[PATCH v7 5/7] drm/hisilicon/hibmc: Add support for VDAC

Sean Paul seanpaul at chromium.org
Wed Nov 16 07:59:16 PST 2016


On Wed, Nov 16, 2016 at 8:43 AM, Rongrong Zou <zourongrong at gmail.com> wrote:
> VDAC(Video Digital-to-Analog converter) converts the RGB diaital data
> stream from DE to VGA analog signals.
>
> Signed-off-by: Rongrong Zou <zourongrong at gmail.com>

Reviewed-by: Sean Paul <seanpaul at chromium.org>

> ---
>  drivers/gpu/drm/hisilicon/hibmc/Makefile         |   2 +-
>  drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c  |   6 +
>  drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h  |   1 +
>  drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 147 +++++++++++++++++++++++
>  4 files changed, 155 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
>
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile b/drivers/gpu/drm/hisilicon/hibmc/Makefile
> index 8e0cf72..f2e04c0 100644
> --- a/drivers/gpu/drm/hisilicon/hibmc/Makefile
> +++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile
> @@ -1,4 +1,4 @@
>  ccflags-y := -Iinclude/drm
> -hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_fbdev.o hibmc_ttm.o
> +hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o hibmc_drm_fbdev.o hibmc_ttm.o
>
>  obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc-drm.o
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
> index 9de3564..c133644 100644
> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
> @@ -123,6 +123,12 @@ static int hibmc_kms_init(struct hibmc_drm_private *priv)
>                 return ret;
>         }
>
> +       ret = hibmc_vdac_init(priv);
> +       if (ret) {
> +               DRM_ERROR("failed to init vdac: %d\n", ret);
> +               return ret;
> +       }
> +
>         return 0;
>  }
>
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
> index 87af1eb..b626caf 100644
> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
> @@ -86,6 +86,7 @@ void hibmc_set_current_gate(struct hibmc_drm_private *priv,
>                             unsigned int gate);
>
>  int hibmc_de_init(struct hibmc_drm_private *priv);
> +int hibmc_vdac_init(struct hibmc_drm_private *priv);
>  int hibmc_fbdev_init(struct hibmc_drm_private *priv);
>  void hibmc_fbdev_fini(struct hibmc_drm_private *priv);
>
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
> new file mode 100644
> index 0000000..d1f67a9
> --- /dev/null
> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
> @@ -0,0 +1,147 @@
> +/* Hisilicon Hibmc SoC drm driver
> + *
> + * Based on the bochs drm driver.
> + *
> + * Copyright (c) 2016 Huawei Limited.
> + *
> + * Author:
> + *     Rongrong Zou <zourongrong at huawei.com>
> + *     Rongrong Zou <zourongrong at gmail.com>
> + *     Jianhua Li <lijianhua at huawei.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + */
> +
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_crtc_helper.h>
> +
> +#include "hibmc_drm_drv.h"
> +#include "hibmc_drm_regs.h"
> +
> +static int hibmc_connector_get_modes(struct drm_connector *connector)
> +{
> +       return drm_add_modes_noedid(connector, 800, 600);
> +}
> +
> +static int hibmc_connector_mode_valid(struct drm_connector *connector,
> +                                     struct drm_display_mode *mode)
> +{
> +       return MODE_OK;
> +}
> +
> +static struct drm_encoder *
> +hibmc_connector_best_encoder(struct drm_connector *connector)
> +{
> +       return drm_encoder_find(connector->dev, connector->encoder_ids[0]);
> +}
> +
> +static enum drm_connector_status hibmc_connector_detect(struct drm_connector
> +                                                *connector, bool force)
> +{
> +       return connector_status_connected;
> +}
> +
> +static const struct drm_connector_helper_funcs
> +       hibmc_connector_helper_funcs = {
> +       .get_modes = hibmc_connector_get_modes,
> +       .mode_valid = hibmc_connector_mode_valid,
> +       .best_encoder = hibmc_connector_best_encoder,
> +};
> +
> +static const struct drm_connector_funcs hibmc_connector_funcs = {
> +       .dpms = drm_atomic_helper_connector_dpms,
> +       .detect = hibmc_connector_detect,
> +       .fill_modes = drm_helper_probe_single_connector_modes,
> +       .destroy = drm_connector_cleanup,
> +       .reset = drm_atomic_helper_connector_reset,
> +       .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
> +       .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
> +};
> +
> +static struct drm_connector *
> +hibmc_connector_init(struct hibmc_drm_private *priv)
> +{
> +       struct drm_device *dev = priv->dev;
> +       struct drm_connector *connector;
> +       int ret;
> +
> +       connector = devm_kzalloc(dev->dev, sizeof(*connector), GFP_KERNEL);
> +       if (!connector) {
> +               DRM_ERROR("failed to alloc memory when init connector\n");
> +               return ERR_PTR(-ENOMEM);
> +       }
> +
> +       ret = drm_connector_init(dev, connector,
> +                                &hibmc_connector_funcs,
> +                                DRM_MODE_CONNECTOR_VGA);
> +       if (ret) {
> +               DRM_ERROR("failed to init connector: %d\n", ret);
> +               return ERR_PTR(ret);
> +       }
> +       drm_connector_helper_add(connector,
> +                                &hibmc_connector_helper_funcs);
> +
> +       return connector;
> +}
> +
> +static void hibmc_encoder_mode_set(struct drm_encoder *encoder,
> +                                  struct drm_display_mode *mode,
> +                                  struct drm_display_mode *adj_mode)
> +{
> +       u32 reg;
> +       struct drm_device *dev = encoder->dev;
> +       struct hibmc_drm_private *priv = dev->dev_private;
> +
> +       reg = readl(priv->mmio + HIBMC_DISPLAY_CONTROL_HISILE);
> +       reg |= HIBMC_DISPLAY_CONTROL_FPVDDEN(1);
> +       reg |= HIBMC_DISPLAY_CONTROL_PANELDATE(1);
> +       reg |= HIBMC_DISPLAY_CONTROL_FPEN(1);
> +       reg |= HIBMC_DISPLAY_CONTROL_VBIASEN(1);
> +       writel(reg, priv->mmio + HIBMC_DISPLAY_CONTROL_HISILE);
> +}
> +
> +static const struct drm_encoder_helper_funcs hibmc_encoder_helper_funcs = {
> +       .mode_set = hibmc_encoder_mode_set,
> +};
> +
> +static const struct drm_encoder_funcs hibmc_encoder_funcs = {
> +       .destroy = drm_encoder_cleanup,
> +};
> +
> +int hibmc_vdac_init(struct hibmc_drm_private *priv)
> +{
> +       struct drm_device *dev = priv->dev;
> +       struct drm_encoder *encoder;
> +       struct drm_connector *connector;
> +       int ret;
> +
> +       connector = hibmc_connector_init(priv);
> +       if (IS_ERR(connector)) {
> +               DRM_ERROR("failed to create connector: %ld\n",
> +                         PTR_ERR(connector));
> +               return PTR_ERR(connector);
> +       }
> +
> +       encoder = devm_kzalloc(dev->dev, sizeof(*encoder), GFP_KERNEL);
> +       if (!encoder) {
> +               DRM_ERROR("failed to alloc memory when init encoder\n");
> +               return -ENOMEM;
> +       }
> +
> +       encoder->possible_crtcs = 0x1;
> +       ret = drm_encoder_init(dev, encoder, &hibmc_encoder_funcs,
> +                              DRM_MODE_ENCODER_DAC, NULL);
> +       if (ret) {
> +               DRM_ERROR("failed to init encoder: %d\n", ret);
> +               return ret;
> +       }
> +
> +       drm_encoder_helper_add(encoder, &hibmc_encoder_helper_funcs);
> +       drm_mode_connector_attach_encoder(connector, encoder);
> +
> +       return 0;
> +}
> --
> 1.9.1
>



More information about the linux-arm-kernel mailing list