aboutsummaryrefslogtreecommitdiffstats
path: root/testing/linux-amlogic/0017-drm-bridge-dw-hdmi-add-support-for-YUV420-output.patch
diff options
context:
space:
mode:
authorHe Yangxuan <yangxuan8282@gmail.com>2018-12-12 04:18:06 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2018-12-20 14:35:09 +0000
commit468ce5d3db5bea1bfc4d0b21ce0460bbc508c0ff (patch)
treeeed21d01ea548aec8278a37ccf3a67357c56ed13 /testing/linux-amlogic/0017-drm-bridge-dw-hdmi-add-support-for-YUV420-output.patch
parent27ddcaeab2051aaf617a81eeddfa34fb6557e64a (diff)
downloadaports-468ce5d3db5bea1bfc4d0b21ce0460bbc508c0ff.tar.bz2
aports-468ce5d3db5bea1bfc4d0b21ce0460bbc508c0ff.tar.xz
testing/linux-amlogic: upgrade to 4.19.8
Diffstat (limited to 'testing/linux-amlogic/0017-drm-bridge-dw-hdmi-add-support-for-YUV420-output.patch')
-rw-r--r--testing/linux-amlogic/0017-drm-bridge-dw-hdmi-add-support-for-YUV420-output.patch198
1 files changed, 198 insertions, 0 deletions
diff --git a/testing/linux-amlogic/0017-drm-bridge-dw-hdmi-add-support-for-YUV420-output.patch b/testing/linux-amlogic/0017-drm-bridge-dw-hdmi-add-support-for-YUV420-output.patch
new file mode 100644
index 0000000000..9c36ea2b48
--- /dev/null
+++ b/testing/linux-amlogic/0017-drm-bridge-dw-hdmi-add-support-for-YUV420-output.patch
@@ -0,0 +1,198 @@
+From 3e7f3ec3de8753faefdeb02ed6d00cc580e6ad52 Mon Sep 17 00:00:00 2001
+From: Neil Armstrong <narmstrong@baylibre.com>
+Date: Wed, 14 Nov 2018 17:19:36 +0100
+Subject: [PATCH] drm/bridge: dw-hdmi: add support for YUV420 output
+
+In order to support the HDMI2.0 YUV420 display modes, this patch
+adds support for the YUV420 TMDS Clock divided by 2 and the controller
+passthrough mode.
+
+This patch is based on work from Zheng Yang <zhengyang@rock-chips.com> in
+the Rockchip Linux 4.4 BSP at [1]
+
+[1] https://github.com/rockchip-linux/kernel/tree/release-4.4
+
+Cc: Zheng Yang <zhengyang@rock-chips.com>
+Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
+
+---
+ drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 63 ++++++++++++++++++++++++-------
+ 1 file changed, 50 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+index 2a30d83..c3e4ed1 100644
+--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+@@ -94,6 +94,7 @@ struct hdmi_vmode {
+ unsigned int mpixelclock;
+ unsigned int mpixelrepetitioninput;
+ unsigned int mpixelrepetitionoutput;
++ unsigned int mtmdsclock;
+ };
+
+ struct hdmi_data_info {
+@@ -549,7 +550,7 @@ static void hdmi_init_clk_regenerator(struct dw_hdmi *hdmi)
+ static void hdmi_clk_regenerator_update_pixel_clock(struct dw_hdmi *hdmi)
+ {
+ mutex_lock(&hdmi->audio_mutex);
+- hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock,
++ hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mtmdsclock,
+ hdmi->sample_rate);
+ mutex_unlock(&hdmi->audio_mutex);
+ }
+@@ -558,7 +559,7 @@ void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate)
+ {
+ mutex_lock(&hdmi->audio_mutex);
+ hdmi->sample_rate = rate;
+- hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock,
++ hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mtmdsclock,
+ hdmi->sample_rate);
+ mutex_unlock(&hdmi->audio_mutex);
+ }
+@@ -659,6 +660,20 @@ static bool hdmi_bus_fmt_is_yuv422(unsigned int bus_format)
+ }
+ }
+
++static bool hdmi_bus_fmt_is_yuv420(unsigned int bus_format)
++{
++ switch (bus_format) {
++ case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
++ case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
++ case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
++ case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
++ return true;
++
++ default:
++ return false;
++ }
++}
++
+ static int hdmi_bus_fmt_color_depth(unsigned int bus_format)
+ {
+ switch (bus_format) {
+@@ -888,7 +903,8 @@ static void hdmi_video_packetize(struct dw_hdmi *hdmi)
+ u8 val, vp_conf;
+
+ if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format) ||
+- hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format)) {
++ hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format) ||
++ hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format)) {
+ switch (hdmi_bus_fmt_color_depth(
+ hdmi->hdmi_data.enc_out_bus_format)) {
+ case 8:
+@@ -1029,7 +1045,7 @@ EXPORT_SYMBOL_GPL(dw_hdmi_phy_i2c_write);
+
+ void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi)
+ {
+- unsigned long mtmdsclock = hdmi->hdmi_data.video_mode.mpixelclock;
++ unsigned long mtmdsclock = hdmi->hdmi_data.video_mode.mtmdsclock;
+
+ /* Control for TMDS Bit Period/TMDS Clock-Period Ratio */
+ if (hdmi->connector.display_info.hdmi.scdc.supported) {
+@@ -1370,6 +1386,9 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
+ struct hdmi_avi_infoframe frame;
+ u8 val;
+
++ if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format))
++ is_hdmi2_sink = true;
++
+ /* Initialise info frame from DRM mode */
+ drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, is_hdmi2_sink);
+
+@@ -1377,6 +1396,8 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
+ frame.colorspace = HDMI_COLORSPACE_YUV444;
+ else if (hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format))
+ frame.colorspace = HDMI_COLORSPACE_YUV422;
++ else if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format))
++ frame.colorspace = HDMI_COLORSPACE_YUV420;
+ else
+ frame.colorspace = HDMI_COLORSPACE_RGB;
+
+@@ -1534,15 +1555,18 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
+ struct drm_hdmi_info *hdmi_info = &hdmi->connector.display_info.hdmi;
+ struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
+ int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len;
+- unsigned int vdisplay;
++ unsigned int vdisplay, hdisplay;
+
+- vmode->mpixelclock = mode->clock * 1000;
++ vmode->mtmdsclock = vmode->mpixelclock = mode->clock * 1000;
+
+ dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock);
+
++ if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format))
++ vmode->mtmdsclock /= 2;
++
+ /* Set up HDMI_FC_INVIDCONF */
+ inv_val = (hdmi->hdmi_data.hdcp_enable ||
+- vmode->mpixelclock > 340000000 ||
++ vmode->mtmdsclock > 340000000 ||
+ hdmi_info->scdc.scrambling.low_rates ?
+ HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE :
+ HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE);
+@@ -1576,6 +1600,22 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
+
+ hdmi_writeb(hdmi, inv_val, HDMI_FC_INVIDCONF);
+
++ hdisplay = mode->hdisplay;
++ hblank = mode->htotal - mode->hdisplay;
++ h_de_hs = mode->hsync_start - mode->hdisplay;
++ hsync_len = mode->hsync_end - mode->hsync_start;
++
++ /*
++ * When we're setting a YCbCr420 mode, we need
++ * to adjust the horizontal timing to suit.
++ */
++ if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format)) {
++ hdisplay /= 2;
++ hblank /= 2;
++ h_de_hs /= 2;
++ hsync_len /= 2;
++ }
++
+ vdisplay = mode->vdisplay;
+ vblank = mode->vtotal - mode->vdisplay;
+ v_de_vs = mode->vsync_start - mode->vdisplay;
+@@ -1594,7 +1634,7 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
+
+ /* Scrambling Control */
+ if (hdmi_info->scdc.supported) {
+- if (vmode->mpixelclock > 340000000 ||
++ if (vmode->mtmdsclock > 340000000 ||
+ hdmi_info->scdc.scrambling.low_rates) {
+ drm_scdc_readb(&hdmi->i2c->adap, SCDC_SINK_VERSION,
+ &bytes);
+@@ -1613,15 +1653,14 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
+ }
+
+ /* Set up horizontal active pixel width */
+- hdmi_writeb(hdmi, mode->hdisplay >> 8, HDMI_FC_INHACTV1);
+- hdmi_writeb(hdmi, mode->hdisplay, HDMI_FC_INHACTV0);
++ hdmi_writeb(hdmi, hdisplay >> 8, HDMI_FC_INHACTV1);
++ hdmi_writeb(hdmi, hdisplay, HDMI_FC_INHACTV0);
+
+ /* Set up vertical active lines */
+ hdmi_writeb(hdmi, vdisplay >> 8, HDMI_FC_INVACTV1);
+ hdmi_writeb(hdmi, vdisplay, HDMI_FC_INVACTV0);
+
+ /* Set up horizontal blanking pixel region width */
+- hblank = mode->htotal - mode->hdisplay;
+ hdmi_writeb(hdmi, hblank >> 8, HDMI_FC_INHBLANK1);
+ hdmi_writeb(hdmi, hblank, HDMI_FC_INHBLANK0);
+
+@@ -1629,7 +1668,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
+ hdmi_writeb(hdmi, vblank, HDMI_FC_INVBLANK);
+
+ /* Set up HSYNC active edge delay width (in pixel clks) */
+- h_de_hs = mode->hsync_start - mode->hdisplay;
+ hdmi_writeb(hdmi, h_de_hs >> 8, HDMI_FC_HSYNCINDELAY1);
+ hdmi_writeb(hdmi, h_de_hs, HDMI_FC_HSYNCINDELAY0);
+
+@@ -1637,7 +1675,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
+ hdmi_writeb(hdmi, v_de_vs, HDMI_FC_VSYNCINDELAY);
+
+ /* Set up HSYNC active pulse width (in pixel clks) */
+- hsync_len = mode->hsync_end - mode->hsync_start;
+ hdmi_writeb(hdmi, hsync_len >> 8, HDMI_FC_HSYNCINWIDTH1);
+ hdmi_writeb(hdmi, hsync_len, HDMI_FC_HSYNCINWIDTH0);
+