From 2807ba75970367c528a9c43aef6296c95eade5be Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 8 Jul 2018 22:19:02 +0100 Subject: 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 Signed-off-by: Russell King --- drivers/gpu/drm/i2c/tda998x_drv.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'drivers') 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, -- cgit v1.2.3