summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2018-07-08 22:19:02 +0100
committerRussell King <rmk+kernel@armlinux.org.uk>2019-06-13 21:55:03 +0100
commit2807ba75970367c528a9c43aef6296c95eade5be (patch)
tree80e9502d6512487d54aedc7da785d419f8038edc
parent125a4f9394c769bc3e4306ff6cc73529bc1fa6dd (diff)
drm/i2c: tda998x: add support for pixel repeated modes
TDA998x has no support for pixel repeated modes, and the code notes this as a "TODO" item. The implementation appears to be relatively simple, so lets add it. We need to calculate the serializer clock divisor based on the TMDS clock rate, set the repeat control, and set the serializer pixel repeat count. Since the audio code needs the actual TMDS clock, record that. 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.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index 384e07696101..d4409aa5ed7a 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -258,6 +258,7 @@ struct tda998x_priv {
# define HVF_CNTRL_1_PAD(x) (((x) & 3) << 4)
# define HVF_CNTRL_1_SEMI_PLANAR (1 << 6)
#define REG_RPT_CNTRL REG(0x00, 0xf0) /* write */
+# define RPT_CNTRL_REPEAT(x) ((x) & 15)
#define REG_I2S_FORMAT REG(0x00, 0xfc) /* read/write */
# define I2S_FORMAT_PHILIPS (0 << 0)
# define I2S_FORMAT_LEFT_J (2 << 0)
@@ -1423,7 +1424,7 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge,
u16 vwin1_line_s, vwin1_line_e;
u16 vwin2_line_s, vwin2_line_e;
u16 de_pix_s, de_pix_e;
- u8 reg, div, rep;
+ u8 reg, div, rep, sel_clk;
/*
* Internally TDA998x is using ITU-R BT.656 style sync but
@@ -1486,7 +1487,16 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge,
(mode->vsync_end - mode->vsync_start)/2;
}
- tmds_clock = mode->clock;
+ /*
+ * Select pixel repeat depending on the double-clock flag
+ * (which means we have to repeat each pixel once.)
+ */
+ rep = mode->flags & DRM_MODE_FLAG_DBLCLK ? 1 : 0;
+ sel_clk = SEL_CLK_ENA_SC_CLK | SEL_CLK_SEL_CLK1 |
+ SEL_CLK_SEL_VRF_CLK(rep ? 2 : 0);
+
+ /* the TMDS clock is scaled up by the pixel repeat */
+ tmds_clock = mode->clock * (1 + rep);
/*
* The divisor is power-of-2. The TDA9983B datasheet gives
@@ -1502,6 +1512,8 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge,
mutex_lock(&priv->audio_mutex);
+ priv->tmds_clock = tmds_clock;
+
/* mute the audio FIFO: */
reg_set(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO);
@@ -1524,12 +1536,8 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge,
reg_write(priv, REG_SERIALIZER, 0);
reg_write(priv, REG_HVF_CNTRL_1, HVF_CNTRL_1_VQR(0));
- /* TODO enable pixel repeat for pixel rates less than 25Msamp/s */
- rep = 0;
- reg_write(priv, REG_RPT_CNTRL, 0);
- reg_write(priv, REG_SEL_CLK, SEL_CLK_SEL_VRF_CLK(0) |
- SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK);
-
+ reg_write(priv, REG_RPT_CNTRL, RPT_CNTRL_REPEAT(rep));
+ reg_write(priv, REG_SEL_CLK, sel_clk);
reg_write(priv, REG_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(div) |
PLL_SERIAL_2_SRL_PR(rep));
@@ -1597,8 +1605,6 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge,
/* must be last register set: */
reg_write(priv, REG_TBG_CNTRL_0, 0);
- priv->tmds_clock = adjusted_mode->clock;
-
/* CEA-861B section 6 says that:
* CEA version 1 (CEA-861) has no support for infoframes.
* CEA version 2 (CEA-861A) supports version 1 AVI infoframes,