[PATCH v7 5/7] drm/hisilicon/hibmc: Add support for VDAC
Sean Paul
seanpaul at chromium.org
Wed Nov 16 15:59:16 UTC 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 dri-devel
mailing list