| @@ -111,6 +111,8 @@ · 110 unmodified lines |
| 111 | 111 | DPTUN_REG(DP_ALLOCATED_BW) | \ |
| 112 | 112 | DPTUN_REG(DP_TUNNELING_MAX_LINK_RATE) | \ |
| 113 | 113 | DPTUN_REG(DP_TUNNELING_MAX_LANE_COUNT) | \ |
| 114 | + DPTUN_REG(DP_TUNNELING_MAIN_LINK_CHANNEL_CODING) | \ |
| 115 | + DPTUN_REG(DP_TUNNELING_128B132B_LINK_RATE) | \ |
| 114 | 116 | DPTUN_REG(DP_DPTX_BW_ALLOCATION_MODE_CONTROL)) |
| 115 | 117 | |
| 116 | 118 | static const DECLARE_BITMAP(dptun_info_regs, 64) = { |
| @@ -140,11 +142,14 @@ struct drm_dp_tunnel { · 23 unmodified lines |
| 140 | 142 | int estimated_bw; |
| 141 | 143 | int allocated_bw; |
| 142 | 144 | |
| 145 | + u8 dprx_128b132b_rates; |
| 143 | 146 | int max_dprx_rate; |
| 144 | 147 | u8 max_dprx_lane_count; |
| 145 | 148 | |
| 146 | 149 | u8 adapter_id; |
| 147 | 150 | |
| 151 | + bool dprx_128b132b_support:1; |
| 152 | + bool dprx_128b132b_lane0_mapping_support:1; |
| 148 | 153 | bool bw_alloc_supported:1; |
| 149 | 154 | bool bw_alloc_enabled:1; |
| 150 | 155 | bool has_io_error:1; |
| @@ -260,9 +265,46 @@ static int tunnel_reg_bw_granularity(const struct drm_dp_tunnel_regs *regs) · 109 unmodified lines |
| 260 | 265 | return (250000 << gr) / 8; |
| 261 | 266 | } |
| 262 | 267 | |
| 268 | +static bool tunnel_reg_dprx_128b132b_support(const struct drm_dp_tunnel_regs *regs) |
| 269 | +{ |
| 270 | + return tunnel_reg(regs, DP_TUNNELING_MAIN_LINK_CHANNEL_CODING) & DP_128B132B_DP_SUPPORTED; |
| 271 | +} |
| 272 | + |
| 273 | +static bool tunnel_reg_dprx_128b132b_lane0_mapping_support(const struct drm_dp_tunnel_regs *regs) |
| 274 | +{ |
| 275 | + return tunnel_reg(regs, DP_TUNNELING_128B132B_LINK_RATE) & |
| 276 | + DP_TUNNELING_128B132B_LL_LANE0_MAPPING_SUPPORT; |
| 277 | +} |
| 278 | + |
| 279 | +static u8 tunnel_reg_dprx_128b132b_rates(const struct drm_dp_tunnel_regs *regs) |
| 280 | +{ |
| 281 | + if (!tunnel_reg_dprx_128b132b_support(regs)) |
| 282 | + return 0; |
| 283 | + |
| 284 | + return tunnel_reg(regs, DP_TUNNELING_128B132B_LINK_RATE) & |
| 285 | + DP_TUNNELING_128B132B_LINK_RATE_MASK; |
| 286 | +} |
| 287 | + |
| 288 | +static u8 max_128b132b_rate(u8 rates) |
| 289 | +{ |
| 290 | + if (rates & DP_TUNNELING_20GBPS_PER_LANE_SUPPORT) |
| 291 | + return DP_TUNNELING_20GBPS_PER_LANE_SUPPORT; |
| 292 | + else if (rates & DP_TUNNELING_13_5GBPS_PER_LANE_SUPPORT) |
| 293 | + return DP_TUNNELING_13_5GBPS_PER_LANE_SUPPORT; |
| 294 | + else if (rates & DP_TUNNELING_10GBPS_PER_LANE_SUPPORT) |
| 295 | + return DP_TUNNELING_10GBPS_PER_LANE_SUPPORT; |
| 296 | + |
| 297 | + WARN_ON(rates); |
| 298 | + |
| 299 | + return 0; |
| 300 | +} |
| 301 | + |
| 263 | 302 | static int tunnel_reg_max_dprx_rate(const struct drm_dp_tunnel_regs *regs) |
| 264 | 303 | { |
| 265 | | − u8 bw_code = tunnel_reg(regs, DP_TUNNELING_MAX_LINK_RATE); |
| 304 | + u8 bw_code = max_128b132b_rate(tunnel_reg_dprx_128b132b_rates(regs)); |
| 305 | + |
| 306 | + if (!bw_code) |
| 307 | + bw_code = tunnel_reg(regs, DP_TUNNELING_MAX_LINK_RATE); |
| 266 | 308 | |
| 267 | 309 | return drm_dp_bw_code_to_link_rate(bw_code); |
| 268 | 310 | } |
| @@ -706,6 +748,23 @@ static bool update_dprx_caps(struct drm_dp_tunnel *tunnel, const struct drm_dp_t · 437 unmodified lines |
| 706 | 748 | { |
| 707 | 749 | bool changed = false; |
| 708 | 750 | |
| 751 | + if (tunnel_reg_dprx_128b132b_support(regs) != tunnel->dprx_128b132b_support) { |
| 752 | + tunnel->dprx_128b132b_support = tunnel_reg_dprx_128b132b_support(regs); |
| 753 | + changed = true; |
| 754 | + } |
| 755 | + |
| 756 | + if (tunnel_reg_dprx_128b132b_lane0_mapping_support(regs) != |
| 757 | + tunnel->dprx_128b132b_lane0_mapping_support) { |
| 758 | + tunnel->dprx_128b132b_lane0_mapping_support = |
| 759 | + tunnel_reg_dprx_128b132b_lane0_mapping_support(regs); |
| 760 | + changed = true; |
| 761 | + } |
| 762 | + |
| 763 | + if (tunnel_reg_dprx_128b132b_rates(regs) != tunnel->dprx_128b132b_rates) { |
| 764 | + tunnel->dprx_128b132b_rates = tunnel_reg_dprx_128b132b_rates(regs); |
| 765 | + changed = true; |
| 766 | + } |
| 767 | + |
| 709 | 768 | if (tunnel_reg_max_dprx_rate(regs) != tunnel->max_dprx_rate) { |
| 710 | 769 | tunnel->max_dprx_rate = tunnel_reg_max_dprx_rate(regs); |
| 711 | 770 | changed = true; |
| @@ -1331,6 +1390,61 @@ int drm_dp_tunnel_handle_irq(struct drm_dp_tunnel_mgr *mgr, struct drm_dp_aux *a · 619 unmodified lines |
| 1331 | 1390 | } |
| 1332 | 1391 | EXPORT_SYMBOL(drm_dp_tunnel_handle_irq); |
| 1333 | 1392 | |
| 1393 | +/** |
| 1394 | + * drm_dp_tunnel_128b132b_supported - Query if 128b132b is supported by the tunnel's DPRX |
| 1395 | + * @tunnel: Tunnel object |
| 1396 | + * |
| 1397 | + * The function is used to query if 128b132b is supported by the DPRX connected |
| 1398 | + * to @tunnel. |
| 1399 | + * |
| 1400 | + * Returns %true if 128b132b is supported by the DPRX. |
| 1401 | + */ |
| 1402 | +bool drm_dp_tunnel_128b132b_supported(const struct drm_dp_tunnel *tunnel) |
| 1403 | +{ |
| 1404 | + return tunnel->dprx_128b132b_support; |
| 1405 | +} |
| 1406 | +EXPORT_SYMBOL(drm_dp_tunnel_128b132b_supported); |
| 1407 | + |
| 1408 | +/** |
| 1409 | + * drm_dp_tunnel_128b132b_lane0_mapping_supported - Check 128b/132b lane 0 mapping support |
| 1410 | + * @tunnel: Tunnel object |
| 1411 | + * |
| 1412 | + * Check whether the DP-out adapter always maps lane 0 as expected by the |
| 1413 | + * DPRX on a tunneled 128b/132b link. If the function returns %true, one- and |
| 1414 | + * two-lane configurations with UHBR link rates can always be used. If it |
| 1415 | + * returns %false, using one or two lanes with UHBR link rates may cause a |
| 1416 | + * lane-count conversion failure in the DPRX, requiring corrective action by |
| 1417 | + * the source during link training. See DP Standard v2.1b, section |
| 1418 | + * 3.5.2.16.3, 128b/132b DPRX Lane Count Conversion Failure Indication and |
| 1419 | + * Corrective Action. |
| 1420 | + * |
| 1421 | + * A four-lane configuration can always be used, provided that the DPRX |
| 1422 | + * supports it, regardless of the function's return value. |
| 1423 | + * |
| 1424 | + * Returns %true if the DP-out adapter supports the 128b/132b lane 0 mapping. |
| 1425 | + */ |
| 1426 | +bool drm_dp_tunnel_128b132b_lane0_mapping_supported(const struct drm_dp_tunnel *tunnel) |
| 1427 | +{ |
| 1428 | + return tunnel->dprx_128b132b_lane0_mapping_support; |
| 1429 | +} |
| 1430 | +EXPORT_SYMBOL(drm_dp_tunnel_128b132b_lane0_mapping_supported); |
| 1431 | + |
| 1432 | +/** |
| 1433 | + * drm_dp_tunnel_128b132b_dprx_rates - Query the supported 128b132b rates of the tunnel's DPRX |
| 1434 | + * @tunnel: Tunnel object |
| 1435 | + * |
| 1436 | + * The function is used to query the supported 128b132b rates of the DPRX connected |
| 1437 | + * to @tunnel. Note that the related DP_128B132B_SUPPROTED_LINK_RATES DPCD |
| 1438 | + * register will indicate no supported 128B132B rates for a tunneled DPRX. |
| 1439 | + * |
| 1440 | + * Returns the mask of supported 128b132b rates. |
| 1441 | + */ |
| 1442 | +u8 drm_dp_tunnel_128b132b_dprx_rates(const struct drm_dp_tunnel *tunnel) |
| 1443 | +{ |
| 1444 | + return tunnel->dprx_128b132b_rates; |
| 1445 | +} |
| 1446 | +EXPORT_SYMBOL(drm_dp_tunnel_128b132b_dprx_rates); |
| 1447 | + |
| 1334 | 1448 | /** |
| 1335 | 1449 | * drm_dp_tunnel_max_dprx_rate - Query the maximum rate of the tunnel's DPRX |
| 1336 | 1450 | * @tunnel: Tunnel object |