On Wed, Nov 16, 2016 at 8:43 AM, Rongrong Zou <zourongrong@xxxxxxxxx> 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@xxxxxxxxx> Reviewed-by: Sean Paul <seanpaul@xxxxxxxxxxxx> > --- > 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@xxxxxxxxxx> > + * Rongrong Zou <zourongrong@xxxxxxxxx> > + * Jianhua Li <lijianhua@xxxxxxxxxx> > + * > + * 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 > _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel