drm/bridge: analogix_dp: Add support for SSC (Spread-Spectrum Clock)

DPTX implements the programmable SSC down-spreading with up to
0.5% modulation amplitude and 30k/33k modulation frequency.

Change-Id: I2c3eae8f27c84eb1b22eac8973691e0276c1588e
Signed-off-by: Wyon Bi <bivvy.bi@rock-chips.com>
This commit is contained in:
Wyon Bi
2019-01-09 10:05:25 +08:00
committed by Tao Huang
parent 1ba631eb8a
commit 31bc0dca0d
4 changed files with 54 additions and 1 deletions

View File

@@ -161,7 +161,7 @@ analogix_dp_set_lane_lane_pre_emphasis(struct analogix_dp_device *dp,
static int analogix_dp_link_start(struct analogix_dp_device *dp)
{
u8 buf[4];
u8 buf[4], dpcd = 0;
int lane, lane_count, pll_tries, retval;
lane_count = dp->link_train.lane_count;
@@ -183,6 +183,30 @@ static int analogix_dp_link_start(struct analogix_dp_device *dp)
if (retval < 0)
return retval;
/* possibly enable downspread on the sink */
retval = drm_dp_dpcd_readb(&dp->aux, DP_MAX_DOWNSPREAD, &dpcd);
if (retval < 0)
return retval;
if (dpcd & DP_MAX_DOWNSPREAD_0_5) {
DRM_DEV_INFO(dp->dev, "Enable downspread on the sink\n");
analogix_dp_ssc_enable(dp);
retval = drm_dp_dpcd_writeb(&dp->aux, DP_DOWNSPREAD_CTRL,
DP_SPREAD_AMP_0_5);
if (retval < 0)
return retval;
} else {
DRM_DEV_INFO(dp->dev, "Disable downspread on the sink\n");
analogix_dp_ssc_disable(dp);
retval = drm_dp_dpcd_writeb(&dp->aux, DP_DOWNSPREAD_CTRL, 0);
if (retval < 0)
return retval;
}
/* Set TX pre-emphasis to minimum */
for (lane = 0; lane < lane_count; lane++)
analogix_dp_set_lane_lane_pre_emphasis(dp,

View File

@@ -251,4 +251,6 @@ void analogix_dp_set_video_format(struct analogix_dp_device *dp);
void analogix_dp_video_bist_enable(struct analogix_dp_device *dp);
ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
struct drm_dp_aux_msg *msg);
void analogix_dp_ssc_enable(struct analogix_dp_device *dp);
void analogix_dp_ssc_disable(struct analogix_dp_device *dp);
#endif /* _ANALOGIX_DP_CORE_H */

View File

@@ -1076,3 +1076,29 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
return num_transferred;
}
void analogix_dp_ssc_enable(struct analogix_dp_device *dp)
{
u8 reg;
/* 4500ppm */
writel(0x19, dp->reg_base + ANALOIGX_DP_SSC_REG);
/*
* To apply updated SSC parameters into SSC operation,
* firmware must disable and enable this bit.
*/
reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
reg |= SSC_FUNC_EN_N;
writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
reg &= ~SSC_FUNC_EN_N;
writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
}
void analogix_dp_ssc_disable(struct analogix_dp_device *dp)
{
u8 reg;
reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
reg |= SSC_FUNC_EN_N;
writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
}

View File

@@ -46,6 +46,7 @@
#define ANALOGIX_DP_PLL_REG_4 0x9ec
#define ANALOGIX_DP_PLL_REG_5 0xa00
#define ANALOIGX_DP_SSC_REG 0x104
#define ANALOGIX_DP_PD 0x12c
#define ANALOGIX_DP_LANE_MAP 0x35C