mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 10:31:46 +09:00
drm/bridge: analogix_dp: add support for ASSR mode
According to the eDP v1.3 chapter 3.6 Table 3-15, Alternative Scramble Seed Reset(ASSR) is a recommended way for eDP Sink devices to support Display Authentication and Content Protection as Method 3a, while Method 1 HDCP is normally not expected in an eDP Sink device. In addition, the ASSR support capability should be the bit 0 of DPCD register 0000Dh according to the eDP v1.4 'Revision History' table 2: ...... Table 3-4: Corrected reference to DPCD Address 0000Dh, bit 0 (was bit 4) ...... Change-Id: Iafad97755fd4c9e688c47164d099b290af905036 Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
This commit is contained in:
@@ -341,6 +341,43 @@ static bool analogix_dp_get_vrr_capable(struct analogix_dp_device *dp)
|
||||
return true;
|
||||
}
|
||||
|
||||
static int analogix_dp_enable_sink_to_assr_mode(struct analogix_dp_device *dp, bool enable)
|
||||
{
|
||||
u8 data;
|
||||
int ret;
|
||||
|
||||
ret = drm_dp_dpcd_readb(&dp->aux, DP_EDP_CONFIGURATION_SET, &data);
|
||||
if (ret != 1)
|
||||
return ret;
|
||||
|
||||
if (enable)
|
||||
ret = drm_dp_dpcd_writeb(&dp->aux, DP_EDP_CONFIGURATION_SET,
|
||||
data | DP_ALTERNATE_SCRAMBLER_RESET_ENABLE);
|
||||
else
|
||||
ret = drm_dp_dpcd_writeb(&dp->aux, DP_LANE_COUNT_SET,
|
||||
data & ~DP_ALTERNATE_SCRAMBLER_RESET_ENABLE);
|
||||
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
static int analogix_dp_set_assr_mode(struct analogix_dp_device *dp)
|
||||
{
|
||||
bool assr_en;
|
||||
int ret;
|
||||
|
||||
assr_en = drm_dp_alternate_scrambler_reset_cap(dp->dpcd);
|
||||
|
||||
ret = analogix_dp_enable_sink_to_assr_mode(dp, assr_en);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
analogix_dp_enable_assr_mode(dp, assr_en);
|
||||
|
||||
dp->link_train.assr = assr_en;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int analogix_dp_link_start(struct analogix_dp_device *dp)
|
||||
{
|
||||
u8 buf[4];
|
||||
@@ -380,6 +417,13 @@ static int analogix_dp_link_start(struct analogix_dp_device *dp)
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
|
||||
/* set ASSR if available */
|
||||
retval = analogix_dp_set_assr_mode(dp);
|
||||
if (retval < 0) {
|
||||
dev_err(dp->dev, "failed to set assr mode\n");
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* set enhanced mode if available */
|
||||
retval = analogix_dp_set_enhanced_mode(dp);
|
||||
if (retval < 0) {
|
||||
@@ -908,6 +952,7 @@ static int analogix_dp_fast_link_train(struct analogix_dp_device *dp)
|
||||
analogix_dp_set_link_bandwidth(dp, dp->link_train.link_rate);
|
||||
analogix_dp_set_lane_count(dp, dp->link_train.lane_count);
|
||||
analogix_dp_set_lane_link_training(dp);
|
||||
analogix_dp_enable_assr_mode(dp, dp->link_train.assr);
|
||||
analogix_dp_enable_enhanced_mode(dp, dp->link_train.enhanced_framing);
|
||||
|
||||
/* source Set training pattern 1 */
|
||||
@@ -2392,6 +2437,7 @@ static void analogix_dp_link_train_restore(struct analogix_dp_device *dp)
|
||||
|
||||
dp->link_train.link_rate = link_rate;
|
||||
dp->link_train.lane_count = lane_count;
|
||||
dp->link_train.assr = analogix_dp_get_assr_mode(dp);
|
||||
dp->link_train.enhanced_framing = analogix_dp_get_enhanced_mode(dp);
|
||||
dp->link_train.ssc = !!(spread & DP_MAX_DOWNSPREAD_0_5);
|
||||
|
||||
|
||||
@@ -160,6 +160,7 @@ struct link_train {
|
||||
u8 training_lane[4];
|
||||
bool ssc;
|
||||
bool enhanced_framing;
|
||||
bool assr;
|
||||
|
||||
enum link_training_state lt_state;
|
||||
};
|
||||
@@ -279,5 +280,7 @@ void analogix_dp_init(struct analogix_dp_device *dp);
|
||||
void analogix_dp_irq_handler(struct analogix_dp_device *dp);
|
||||
void analogix_dp_phy_test(struct analogix_dp_device *dp);
|
||||
void analogix_dp_check_device_service_irq(struct analogix_dp_device *dp);
|
||||
void analogix_dp_enable_assr_mode(struct analogix_dp_device *dp, bool enable);
|
||||
bool analogix_dp_get_assr_mode(struct analogix_dp_device *dp);
|
||||
|
||||
#endif /* _ANALOGIX_DP_CORE_H */
|
||||
|
||||
@@ -1390,3 +1390,27 @@ void analogix_dp_init(struct analogix_dp_device *dp)
|
||||
analogix_dp_init_hpd(dp);
|
||||
analogix_dp_init_aux(dp);
|
||||
}
|
||||
|
||||
void analogix_dp_enable_assr_mode(struct analogix_dp_device *dp, bool enable)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
if (enable) {
|
||||
reg = analogix_dp_read(dp, ANALOGIX_DP_LINK_POLICY);
|
||||
reg |= ALTERNATE_SR_ENABLE;
|
||||
analogix_dp_write(dp, ANALOGIX_DP_LINK_POLICY, reg);
|
||||
} else {
|
||||
reg = analogix_dp_read(dp, ANALOGIX_DP_LINK_POLICY);
|
||||
reg &= ~ALTERNATE_SR_ENABLE;
|
||||
analogix_dp_write(dp, ANALOGIX_DP_LINK_POLICY, reg);
|
||||
}
|
||||
}
|
||||
|
||||
bool analogix_dp_get_assr_mode(struct analogix_dp_device *dp)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = analogix_dp_read(dp, ANALOGIX_DP_LINK_POLICY);
|
||||
|
||||
return !!(reg & ALTERNATE_SR_ENABLE);
|
||||
}
|
||||
|
||||
@@ -146,6 +146,8 @@
|
||||
#define ANALOGIX_DP_CRC_CON 0x890
|
||||
#define ANALOGIX_DP_I2S_CTRL 0x9C8
|
||||
|
||||
#define ANALOGIX_DP_LINK_POLICY 0x9D8
|
||||
|
||||
/* ANALOGIX_DP_TX_SW_RESET */
|
||||
#define RESET_DP_TX (0x1 << 0)
|
||||
|
||||
@@ -515,4 +517,7 @@
|
||||
/* ANALOGIX_DP_I2S_CTRL */
|
||||
#define I2S_EN (0x1 << 4)
|
||||
|
||||
/* ANALOGIX_DP_LINK_POLICY */
|
||||
#define ALTERNATE_SR_ENABLE (0x1 << 7)
|
||||
|
||||
#endif /* _ANALOGIX_DP_REG_H */
|
||||
|
||||
Reference in New Issue
Block a user