linux/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
<<
>>
Prefs
   1/* Hisilicon Hibmc SoC drm driver
   2 *
   3 * Based on the bochs drm driver.
   4 *
   5 * Copyright (c) 2016 Huawei Limited.
   6 *
   7 * Author:
   8 *      Rongrong Zou <zourongrong@huawei.com>
   9 *      Rongrong Zou <zourongrong@gmail.com>
  10 *      Jianhua Li <lijianhua@huawei.com>
  11 *
  12 * This program is free software; you can redistribute it and/or modify
  13 * it under the terms of the GNU General Public License as published by
  14 * the Free Software Foundation; either version 2 of the License, or
  15 * (at your option) any later version.
  16 *
  17 */
  18
  19#include <drm/drm_atomic_helper.h>
  20#include <drm/drm_crtc_helper.h>
  21
  22#include "hibmc_drm_drv.h"
  23#include "hibmc_drm_regs.h"
  24
  25static int hibmc_connector_get_modes(struct drm_connector *connector)
  26{
  27        return drm_add_modes_noedid(connector, 800, 600);
  28}
  29
  30static enum drm_mode_status hibmc_connector_mode_valid(struct drm_connector *connector,
  31                                      struct drm_display_mode *mode)
  32{
  33        return MODE_OK;
  34}
  35
  36static struct drm_encoder *
  37hibmc_connector_best_encoder(struct drm_connector *connector)
  38{
  39        return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]);
  40}
  41
  42static const struct drm_connector_helper_funcs
  43        hibmc_connector_helper_funcs = {
  44        .get_modes = hibmc_connector_get_modes,
  45        .mode_valid = hibmc_connector_mode_valid,
  46        .best_encoder = hibmc_connector_best_encoder,
  47};
  48
  49static const struct drm_connector_funcs hibmc_connector_funcs = {
  50        .fill_modes = drm_helper_probe_single_connector_modes,
  51        .destroy = drm_connector_cleanup,
  52        .reset = drm_atomic_helper_connector_reset,
  53        .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
  54        .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
  55};
  56
  57static struct drm_connector *
  58hibmc_connector_init(struct hibmc_drm_private *priv)
  59{
  60        struct drm_device *dev = priv->dev;
  61        struct drm_connector *connector;
  62        int ret;
  63
  64        connector = devm_kzalloc(dev->dev, sizeof(*connector), GFP_KERNEL);
  65        if (!connector) {
  66                DRM_ERROR("failed to alloc memory when init connector\n");
  67                return ERR_PTR(-ENOMEM);
  68        }
  69
  70        ret = drm_connector_init(dev, connector,
  71                                 &hibmc_connector_funcs,
  72                                 DRM_MODE_CONNECTOR_VGA);
  73        if (ret) {
  74                DRM_ERROR("failed to init connector: %d\n", ret);
  75                return ERR_PTR(ret);
  76        }
  77        drm_connector_helper_add(connector,
  78                                 &hibmc_connector_helper_funcs);
  79
  80        return connector;
  81}
  82
  83static void hibmc_encoder_mode_set(struct drm_encoder *encoder,
  84                                   struct drm_display_mode *mode,
  85                                   struct drm_display_mode *adj_mode)
  86{
  87        u32 reg;
  88        struct drm_device *dev = encoder->dev;
  89        struct hibmc_drm_private *priv = dev->dev_private;
  90
  91        reg = readl(priv->mmio + HIBMC_DISPLAY_CONTROL_HISILE);
  92        reg |= HIBMC_DISPLAY_CONTROL_FPVDDEN(1);
  93        reg |= HIBMC_DISPLAY_CONTROL_PANELDATE(1);
  94        reg |= HIBMC_DISPLAY_CONTROL_FPEN(1);
  95        reg |= HIBMC_DISPLAY_CONTROL_VBIASEN(1);
  96        writel(reg, priv->mmio + HIBMC_DISPLAY_CONTROL_HISILE);
  97}
  98
  99static const struct drm_encoder_helper_funcs hibmc_encoder_helper_funcs = {
 100        .mode_set = hibmc_encoder_mode_set,
 101};
 102
 103static const struct drm_encoder_funcs hibmc_encoder_funcs = {
 104        .destroy = drm_encoder_cleanup,
 105};
 106
 107int hibmc_vdac_init(struct hibmc_drm_private *priv)
 108{
 109        struct drm_device *dev = priv->dev;
 110        struct drm_encoder *encoder;
 111        struct drm_connector *connector;
 112        int ret;
 113
 114        connector = hibmc_connector_init(priv);
 115        if (IS_ERR(connector)) {
 116                DRM_ERROR("failed to create connector: %ld\n",
 117                          PTR_ERR(connector));
 118                return PTR_ERR(connector);
 119        }
 120
 121        encoder = devm_kzalloc(dev->dev, sizeof(*encoder), GFP_KERNEL);
 122        if (!encoder) {
 123                DRM_ERROR("failed to alloc memory when init encoder\n");
 124                return -ENOMEM;
 125        }
 126
 127        encoder->possible_crtcs = 0x1;
 128        ret = drm_encoder_init(dev, encoder, &hibmc_encoder_funcs,
 129                               DRM_MODE_ENCODER_DAC, NULL);
 130        if (ret) {
 131                DRM_ERROR("failed to init encoder: %d\n", ret);
 132                return ret;
 133        }
 134
 135        drm_encoder_helper_add(encoder, &hibmc_encoder_helper_funcs);
 136        drm_connector_attach_encoder(connector, encoder);
 137
 138        return 0;
 139}
 140