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