Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/bridge: tc358767: Add configurable default preemphasis

Make the default DP port preemphasis configurable via new DT property
"toshiba,pre-emphasis". This is useful in case the DP link properties
are known and starting link training from preemphasis setting of 0 dB
is not useful. The preemphasis can be set separately for both DP lanes
in range 0=0dB, 1=3.5dB, 2=6dB .

Acked-by: Alexander Stein <alexander.stein@ew.tq-group.com>
Signed-off-by: Marek Vasut <marex@denx.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20240708150130.54484-2-marex@denx.de

+38 -7
+38 -7
drivers/gpu/drm/bridge/tc358767.c
··· 241 241 242 242 /* Link Training */ 243 243 #define DP0_SRCCTRL 0x06a0 244 + #define DP0_SRCCTRL_PRE1 GENMASK(29, 28) 245 + #define DP0_SRCCTRL_SWG1 GENMASK(25, 24) 246 + #define DP0_SRCCTRL_PRE0 GENMASK(21, 20) 247 + #define DP0_SRCCTRL_SWG0 GENMASK(17, 16) 244 248 #define DP0_SRCCTRL_SCRMBLDIS BIT(13) 245 249 #define DP0_SRCCTRL_EN810B BIT(12) 246 250 #define DP0_SRCCTRL_NOTP (0 << 8) ··· 282 278 #define AUDIFDATA6 0x0720 /* DP0 Audio Info Frame Bytes 27 to 24 */ 283 279 284 280 #define DP1_SRCCTRL 0x07a0 /* DP1 Control Register */ 281 + #define DP1_SRCCTRL_PRE GENMASK(21, 20) 282 + #define DP1_SRCCTRL_SWG GENMASK(17, 16) 285 283 286 284 /* PHY */ 287 285 #define DP_PHY_CTRL 0x0800 ··· 375 369 376 370 u32 rev; 377 371 u8 assr; 372 + u8 pre_emphasis[2]; 378 373 379 374 struct gpio_desc *sd_gpio; 380 375 struct gpio_desc *reset_gpio; ··· 1097 1090 return ret; 1098 1091 } 1099 1092 1100 - ret = regmap_write(tc->regmap, DP0_SRCCTRL, tc_srcctrl(tc)); 1093 + ret = regmap_write(tc->regmap, DP0_SRCCTRL, 1094 + tc_srcctrl(tc) | 1095 + FIELD_PREP(DP0_SRCCTRL_PRE0, tc->pre_emphasis[0]) | 1096 + FIELD_PREP(DP0_SRCCTRL_PRE1, tc->pre_emphasis[1])); 1101 1097 if (ret) 1102 1098 return ret; 1103 1099 /* SSCG and BW27 on DP1 must be set to the same as on DP0 */ 1104 1100 ret = regmap_write(tc->regmap, DP1_SRCCTRL, 1105 1101 (tc->link.spread ? DP0_SRCCTRL_SSCG : 0) | 1106 - ((tc->link.rate != 162000) ? DP0_SRCCTRL_BW27 : 0)); 1102 + ((tc->link.rate != 162000) ? DP0_SRCCTRL_BW27 : 0) | 1103 + FIELD_PREP(DP1_SRCCTRL_PRE, tc->pre_emphasis[1])); 1107 1104 if (ret) 1108 1105 return ret; 1109 1106 ··· 1199 1188 goto err_dpcd_write; 1200 1189 1201 1190 /* Reset voltage-swing & pre-emphasis */ 1202 - tmp[0] = tmp[1] = DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | 1203 - DP_TRAIN_PRE_EMPH_LEVEL_0; 1191 + tmp[0] = DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | 1192 + FIELD_PREP(DP_TRAIN_PRE_EMPHASIS_MASK, tc->pre_emphasis[0]); 1193 + tmp[1] = DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | 1194 + FIELD_PREP(DP_TRAIN_PRE_EMPHASIS_MASK, tc->pre_emphasis[1]); 1204 1195 ret = drm_dp_dpcd_write(aux, DP_TRAINING_LANE0_SET, tmp, 2); 1205 1196 if (ret < 0) 1206 1197 goto err_dpcd_write; ··· 1226 1213 ret = regmap_write(tc->regmap, DP0_SRCCTRL, 1227 1214 tc_srcctrl(tc) | DP0_SRCCTRL_SCRMBLDIS | 1228 1215 DP0_SRCCTRL_AUTOCORRECT | 1229 - DP0_SRCCTRL_TP1); 1216 + DP0_SRCCTRL_TP1 | 1217 + FIELD_PREP(DP0_SRCCTRL_PRE0, tc->pre_emphasis[0]) | 1218 + FIELD_PREP(DP0_SRCCTRL_PRE1, tc->pre_emphasis[1])); 1230 1219 if (ret) 1231 1220 return ret; 1232 1221 ··· 1263 1248 ret = regmap_write(tc->regmap, DP0_SRCCTRL, 1264 1249 tc_srcctrl(tc) | DP0_SRCCTRL_SCRMBLDIS | 1265 1250 DP0_SRCCTRL_AUTOCORRECT | 1266 - DP0_SRCCTRL_TP2); 1251 + DP0_SRCCTRL_TP2 | 1252 + FIELD_PREP(DP0_SRCCTRL_PRE0, tc->pre_emphasis[0]) | 1253 + FIELD_PREP(DP0_SRCCTRL_PRE1, tc->pre_emphasis[1])); 1267 1254 if (ret) 1268 1255 return ret; 1269 1256 ··· 1291 1274 1292 1275 /* Clear Training Pattern, set AutoCorrect Mode = 1 */ 1293 1276 ret = regmap_write(tc->regmap, DP0_SRCCTRL, tc_srcctrl(tc) | 1294 - DP0_SRCCTRL_AUTOCORRECT); 1277 + DP0_SRCCTRL_AUTOCORRECT | 1278 + FIELD_PREP(DP0_SRCCTRL_PRE0, tc->pre_emphasis[0]) | 1279 + FIELD_PREP(DP0_SRCCTRL_PRE1, tc->pre_emphasis[1])); 1295 1280 if (ret) 1296 1281 return ret; 1297 1282 ··· 2382 2363 return -EINVAL; 2383 2364 } 2384 2365 mode |= BIT(endpoint.port); 2366 + 2367 + if (endpoint.port == 2) { 2368 + of_property_read_u8_array(node, "toshiba,pre-emphasis", 2369 + tc->pre_emphasis, 2370 + ARRAY_SIZE(tc->pre_emphasis)); 2371 + 2372 + if (tc->pre_emphasis[0] < 0 || tc->pre_emphasis[0] > 2 || 2373 + tc->pre_emphasis[1] < 0 || tc->pre_emphasis[1] > 2) { 2374 + dev_err(dev, "Incorrect Pre-Emphasis setting, use either 0=0dB 1=3.5dB 2=6dB\n"); 2375 + return -EINVAL; 2376 + } 2377 + } 2385 2378 } 2386 2379 2387 2380 if (mode == mode_dpi_to_edp || mode == mode_dpi_to_dp) {