Re: [PATCH v2 5/5] drm: zte: add tvenc driver support

2017-01-26 Thread Sean Paul
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

2017-01-26 Thread Shawn Guo
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.

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,
+