aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2018-07-31 06:12:27 -0400
committerRussell King <rmk+kernel@armlinux.org.uk>2019-06-13 16:55:07 -0400
commitfcc22c5f9ddaa8d1bb051878cc7e5f928b9973d8 (patch)
treeebcf1113072ecfc261957e6c96ae08e19b81585f
parent2807ba75970367c528a9c43aef6296c95eade5be (diff)
drm/i2c: tda998x: improve correctness of quantisation range
CEA-861 says: "A Source shall not send a non-zero Q value that does not correspond to the default RGB Quantization Range for the transmitted Picture unless the Sink indicates support for the Q bit in a Video Capabilities Data Block." Make TDA998x compliant by using the helper to set the quantisation range in the infoframe, and using the TDA998x's colour scaling to appropriately adjust the RGB values sent to the monitor. This ensures that monitors that do not support the Q bit are sent RGB values that are within the expected range. Monitors with support for the Q bit will be sent full-range RGB. Reviewed-by: Brian Starkey <brian.starkey@arm.com> Tested-by: Sven Van Asbroeck <TheSven73@gmail.com> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
-rw-r--r--drivers/gpu/drm/i2c/tda998x_drv.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index d4409aa5ed7a..2d69aef556a5 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -67,6 +67,7 @@ struct tda998x_priv {
67 bool is_on; 67 bool is_on;
68 bool supports_infoframes; 68 bool supports_infoframes;
69 bool sink_has_audio; 69 bool sink_has_audio;
70 enum hdmi_quantization_range rgb_quant_range;
70 u8 vip_cntrl_0; 71 u8 vip_cntrl_0;
71 u8 vip_cntrl_1; 72 u8 vip_cntrl_1;
72 u8 vip_cntrl_2; 73 u8 vip_cntrl_2;
@@ -870,6 +871,8 @@ tda998x_write_avi(struct tda998x_priv *priv, const struct drm_display_mode *mode
870 drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, 871 drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
871 &priv->connector, mode); 872 &priv->connector, mode);
872 frame.avi.quantization_range = HDMI_QUANTIZATION_RANGE_FULL; 873 frame.avi.quantization_range = HDMI_QUANTIZATION_RANGE_FULL;
874 drm_hdmi_avi_infoframe_quant_range(&frame.avi, &priv->connector, mode,
875 priv->rgb_quant_range);
873 876
874 tda998x_write_if(priv, DIP_IF_FLAGS_IF2, REG_IF2_HB0, &frame); 877 tda998x_write_if(priv, DIP_IF_FLAGS_IF2, REG_IF2_HB0, &frame);
875} 878}
@@ -1427,6 +1430,16 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge,
1427 u8 reg, div, rep, sel_clk; 1430 u8 reg, div, rep, sel_clk;
1428 1431
1429 /* 1432 /*
1433 * Since we are "computer" like, our source invariably produces
1434 * full-range RGB. If the monitor supports full-range, then use
1435 * it, otherwise reduce to limited-range.
1436 */
1437 priv->rgb_quant_range =
1438 priv->connector.display_info.rgb_quant_range_selectable ?
1439 HDMI_QUANTIZATION_RANGE_FULL :
1440 drm_default_rgb_quant_range(adjusted_mode);
1441
1442 /*
1430 * Internally TDA998x is using ITU-R BT.656 style sync but 1443 * Internally TDA998x is using ITU-R BT.656 style sync but
1431 * we get VESA style sync. TDA998x is using a reference pixel 1444 * we get VESA style sync. TDA998x is using a reference pixel
1432 * relative to ITU to sync to the input frame and for output 1445 * relative to ITU to sync to the input frame and for output
@@ -1541,10 +1554,25 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge,
1541 reg_write(priv, REG_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(div) | 1554 reg_write(priv, REG_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(div) |
1542 PLL_SERIAL_2_SRL_PR(rep)); 1555 PLL_SERIAL_2_SRL_PR(rep));
1543 1556
1544 /* set color matrix bypass flag: */ 1557 /* set color matrix according to output rgb quant range */
1545 reg_write(priv, REG_MAT_CONTRL, MAT_CONTRL_MAT_BP | 1558 if (priv->rgb_quant_range == HDMI_QUANTIZATION_RANGE_LIMITED) {
1546 MAT_CONTRL_MAT_SC(1)); 1559 static u8 tda998x_full_to_limited_range[] = {
1547 reg_set(priv, REG_FEAT_POWERDOWN, FEAT_POWERDOWN_CSC); 1560 MAT_CONTRL_MAT_SC(2),
1561 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1562 0x03, 0x6f, 0x00, 0x00, 0x00, 0x00,
1563 0x00, 0x00, 0x03, 0x6f, 0x00, 0x00,
1564 0x00, 0x00, 0x00, 0x00, 0x03, 0x6f,
1565 0x00, 0x40, 0x00, 0x40, 0x00, 0x40
1566 };
1567 reg_clear(priv, REG_FEAT_POWERDOWN, FEAT_POWERDOWN_CSC);
1568 reg_write_range(priv, REG_MAT_CONTRL,
1569 tda998x_full_to_limited_range,
1570 sizeof(tda998x_full_to_limited_range));
1571 } else {
1572 reg_write(priv, REG_MAT_CONTRL, MAT_CONTRL_MAT_BP |
1573 MAT_CONTRL_MAT_SC(1));
1574 reg_set(priv, REG_FEAT_POWERDOWN, FEAT_POWERDOWN_CSC);
1575 }
1548 1576
1549 /* set BIAS tmds value: */ 1577 /* set BIAS tmds value: */
1550 reg_write(priv, REG_ANA_GENERAL, 0x09); 1578 reg_write(priv, REG_ANA_GENERAL, 0x09);