Re: [PATCH v2 5/5] drm: zte: add tvenc driver support
On Thu, Jan 26, 2017 at 11:20:53PM +0800, Shawn Guo wrote: > From: Shawn Guo> > It adds the TV Encoder driver to support video output in PAL and NTSC > format. The driver uses syscon/regmap interface to configure register > bit sitting in SYSCTRL module for DAC power control. > Reviewed-by: Sean Paul > Signed-off-by: Shawn Guo > --- > Changes for v2: > - Embed struct drm_display_mode in zx_tvenc_mode to save function >zx_tvenc_mode_to_drm_mode(). > - Use drm_mode_equal() to find the matching mode. > - Use drm_mode_set_name() to name mode. > - Fix typos in clock multiplier comment. > - Add a sanity check in .mode_valid hook to ensure the given mode is >valid. > - Remove destroy() calls from .unbind hook, as those are already taken >care of by drm_mode_config_cleanup(). > > drivers/gpu/drm/zte/Makefile| 1 + > drivers/gpu/drm/zte/zx_drm_drv.c| 1 + > drivers/gpu/drm/zte/zx_drm_drv.h| 1 + > drivers/gpu/drm/zte/zx_tvenc.c | 407 > > drivers/gpu/drm/zte/zx_tvenc_regs.h | 31 +++ > drivers/gpu/drm/zte/zx_vou.c| 5 + > 6 files changed, 446 insertions(+) > create mode 100644 drivers/gpu/drm/zte/zx_tvenc.c > create mode 100644 drivers/gpu/drm/zte/zx_tvenc_regs.h > > diff --git a/drivers/gpu/drm/zte/Makefile b/drivers/gpu/drm/zte/Makefile > index 699180bfd57c..01352b56c418 100644 > --- a/drivers/gpu/drm/zte/Makefile > +++ b/drivers/gpu/drm/zte/Makefile > @@ -2,6 +2,7 @@ zxdrm-y := \ > zx_drm_drv.o \ > zx_hdmi.o \ > zx_plane.o \ > + zx_tvenc.o \ > zx_vou.o > > obj-$(CONFIG_DRM_ZTE) += zxdrm.o > diff --git a/drivers/gpu/drm/zte/zx_drm_drv.c > b/drivers/gpu/drm/zte/zx_drm_drv.c > index 3e76f72c92ff..13081fed902d 100644 > --- a/drivers/gpu/drm/zte/zx_drm_drv.c > +++ b/drivers/gpu/drm/zte/zx_drm_drv.c > @@ -247,6 +247,7 @@ static int zx_drm_remove(struct platform_device *pdev) > static struct platform_driver *drivers[] = { > _crtc_driver, > _hdmi_driver, > + _tvenc_driver, > _drm_platform_driver, > }; > > diff --git a/drivers/gpu/drm/zte/zx_drm_drv.h > b/drivers/gpu/drm/zte/zx_drm_drv.h > index e65cd18a6cba..5ca035b079c7 100644 > --- a/drivers/gpu/drm/zte/zx_drm_drv.h > +++ b/drivers/gpu/drm/zte/zx_drm_drv.h > @@ -13,6 +13,7 @@ > > extern struct platform_driver zx_crtc_driver; > extern struct platform_driver zx_hdmi_driver; > +extern struct platform_driver zx_tvenc_driver; > > static inline u32 zx_readl(void __iomem *reg) > { > diff --git a/drivers/gpu/drm/zte/zx_tvenc.c b/drivers/gpu/drm/zte/zx_tvenc.c > new file mode 100644 > index ..b56dc69843fc > --- /dev/null > +++ b/drivers/gpu/drm/zte/zx_tvenc.c > @@ -0,0 +1,407 @@ > +/* > + * Copyright 2017 Linaro Ltd. > + * Copyright 2017 ZTE Corporation. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + * > + */ > + > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > + > +#include "zx_drm_drv.h" > +#include "zx_tvenc_regs.h" > +#include "zx_vou.h" > + > +struct zx_tvenc_pwrctrl { > + struct regmap *regmap; > + u32 reg; > + u32 mask; > +}; > + > +struct zx_tvenc { > + struct drm_connector connector; > + struct drm_encoder encoder; > + struct device *dev; > + void __iomem *mmio; > + const struct vou_inf *inf; > + struct zx_tvenc_pwrctrl pwrctrl; > +}; > + > +#define to_zx_tvenc(x) container_of(x, struct zx_tvenc, x) > + > +struct zx_tvenc_mode { > + struct drm_display_mode mode; > + u32 video_info; > + u32 video_res; > + u32 field1_param; > + u32 field2_param; > + u32 burst_line_odd1; > + u32 burst_line_even1; > + u32 burst_line_odd2; > + u32 burst_line_even2; > + u32 line_timing_param; > + u32 weight_value; > + u32 blank_black_level; > + u32 burst_level; > + u32 control_param; > + u32 sub_carrier_phase1; > + u32 phase_line_incr_cvbs; > +}; > + > +/* > + * The CRM cannot directly provide a suitable frequency, and we have to > + * ask a multiplied rate from CRM and use the divider in VOU to get the > + * desired one. > + */ > +#define TVENC_CLOCK_MULTIPLIER 4 > + > +static const struct zx_tvenc_mode tvenc_mode_pal = { > + .mode = { > + .clock = 13500 * TVENC_CLOCK_MULTIPLIER, > + .hdisplay = 720, > + .hsync_start = 720 + 12, > + .hsync_end = 720 + 12 + 2, > + .htotal = 720 + 12 + 2 + 130, > + .vdisplay = 576, > + .vsync_start = 576 + 2, > + .vsync_end = 576 + 2 + 2, > + .vtotal = 576 + 2 + 2 + 20, > + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | > + DRM_MODE_FLAG_INTERLACE, >
[PATCH v2 5/5] drm: zte: add tvenc driver support
From: Shawn GuoIt adds the TV Encoder driver to support video output in PAL and NTSC format. The driver uses syscon/regmap interface to configure register bit sitting in SYSCTRL module for DAC power control. Signed-off-by: Shawn Guo --- Changes for v2: - Embed struct drm_display_mode in zx_tvenc_mode to save function zx_tvenc_mode_to_drm_mode(). - Use drm_mode_equal() to find the matching mode. - Use drm_mode_set_name() to name mode. - Fix typos in clock multiplier comment. - Add a sanity check in .mode_valid hook to ensure the given mode is valid. - Remove destroy() calls from .unbind hook, as those are already taken care of by drm_mode_config_cleanup(). drivers/gpu/drm/zte/Makefile| 1 + drivers/gpu/drm/zte/zx_drm_drv.c| 1 + drivers/gpu/drm/zte/zx_drm_drv.h| 1 + drivers/gpu/drm/zte/zx_tvenc.c | 407 drivers/gpu/drm/zte/zx_tvenc_regs.h | 31 +++ drivers/gpu/drm/zte/zx_vou.c| 5 + 6 files changed, 446 insertions(+) create mode 100644 drivers/gpu/drm/zte/zx_tvenc.c create mode 100644 drivers/gpu/drm/zte/zx_tvenc_regs.h diff --git a/drivers/gpu/drm/zte/Makefile b/drivers/gpu/drm/zte/Makefile index 699180bfd57c..01352b56c418 100644 --- a/drivers/gpu/drm/zte/Makefile +++ b/drivers/gpu/drm/zte/Makefile @@ -2,6 +2,7 @@ zxdrm-y := \ zx_drm_drv.o \ zx_hdmi.o \ zx_plane.o \ + zx_tvenc.o \ zx_vou.o obj-$(CONFIG_DRM_ZTE) += zxdrm.o diff --git a/drivers/gpu/drm/zte/zx_drm_drv.c b/drivers/gpu/drm/zte/zx_drm_drv.c index 3e76f72c92ff..13081fed902d 100644 --- a/drivers/gpu/drm/zte/zx_drm_drv.c +++ b/drivers/gpu/drm/zte/zx_drm_drv.c @@ -247,6 +247,7 @@ static int zx_drm_remove(struct platform_device *pdev) static struct platform_driver *drivers[] = { _crtc_driver, _hdmi_driver, + _tvenc_driver, _drm_platform_driver, }; diff --git a/drivers/gpu/drm/zte/zx_drm_drv.h b/drivers/gpu/drm/zte/zx_drm_drv.h index e65cd18a6cba..5ca035b079c7 100644 --- a/drivers/gpu/drm/zte/zx_drm_drv.h +++ b/drivers/gpu/drm/zte/zx_drm_drv.h @@ -13,6 +13,7 @@ extern struct platform_driver zx_crtc_driver; extern struct platform_driver zx_hdmi_driver; +extern struct platform_driver zx_tvenc_driver; static inline u32 zx_readl(void __iomem *reg) { diff --git a/drivers/gpu/drm/zte/zx_tvenc.c b/drivers/gpu/drm/zte/zx_tvenc.c new file mode 100644 index ..b56dc69843fc --- /dev/null +++ b/drivers/gpu/drm/zte/zx_tvenc.c @@ -0,0 +1,407 @@ +/* + * Copyright 2017 Linaro Ltd. + * Copyright 2017 ZTE Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "zx_drm_drv.h" +#include "zx_tvenc_regs.h" +#include "zx_vou.h" + +struct zx_tvenc_pwrctrl { + struct regmap *regmap; + u32 reg; + u32 mask; +}; + +struct zx_tvenc { + struct drm_connector connector; + struct drm_encoder encoder; + struct device *dev; + void __iomem *mmio; + const struct vou_inf *inf; + struct zx_tvenc_pwrctrl pwrctrl; +}; + +#define to_zx_tvenc(x) container_of(x, struct zx_tvenc, x) + +struct zx_tvenc_mode { + struct drm_display_mode mode; + u32 video_info; + u32 video_res; + u32 field1_param; + u32 field2_param; + u32 burst_line_odd1; + u32 burst_line_even1; + u32 burst_line_odd2; + u32 burst_line_even2; + u32 line_timing_param; + u32 weight_value; + u32 blank_black_level; + u32 burst_level; + u32 control_param; + u32 sub_carrier_phase1; + u32 phase_line_incr_cvbs; +}; + +/* + * The CRM cannot directly provide a suitable frequency, and we have to + * ask a multiplied rate from CRM and use the divider in VOU to get the + * desired one. + */ +#define TVENC_CLOCK_MULTIPLIER 4 + +static const struct zx_tvenc_mode tvenc_mode_pal = { + .mode = { + .clock = 13500 * TVENC_CLOCK_MULTIPLIER, + .hdisplay = 720, + .hsync_start = 720 + 12, + .hsync_end = 720 + 12 + 2, + .htotal = 720 + 12 + 2 + 130, + .vdisplay = 576, + .vsync_start = 576 + 2, + .vsync_end = 576 + 2 + 2, + .vtotal = 576 + 2 + 2 + 20, + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | +DRM_MODE_FLAG_INTERLACE, + }, + .video_info = 0x00040040, + .video_res = 0x05a9c760, + .field1_param = 0x0004d416, + .field2_param = 0x0009b94f, + .burst_line_odd1 = 0x0004d406, + .burst_line_even1 = 0x0009b53e, + .burst_line_odd2 = 0x0004d805, + .burst_line_even2 = 0x0009b93f, +