| @@ -111,6 +111,8 @@ · 110 unmodified lines |
| 111 | DPTUN_REG(DP_ALLOCATED_BW) | \ | 111 | DPTUN_REG(DP_ALLOCATED_BW) | \ |
| 112 | DPTUN_REG(DP_TUNNELING_MAX_LINK_RATE) | \ | 112 | DPTUN_REG(DP_TUNNELING_MAX_LINK_RATE) | \ |
| 113 | DPTUN_REG(DP_TUNNELING_MAX_LANE_COUNT) | \ | 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 | DPTUN_REG(DP_DPTX_BW_ALLOCATION_MODE_CONTROL)) | 116 | DPTUN_REG(DP_DPTX_BW_ALLOCATION_MODE_CONTROL)) |
| 115 | | 117 | |
| 116 | static const DECLARE_BITMAP(dptun_info_regs, 64) = { | 118 | static const DECLARE_BITMAP(dptun_info_regs, 64) = { |
| @@ -140,11 +142,14 @@ struct drm_dp_tunnel { · 23 unmodified lines |
| 140 | int estimated_bw; | 142 | int estimated_bw; |
| 141 | int allocated_bw; | 143 | int allocated_bw; |
| 142 | | 144 | |
| | 145 | u8 dprx_128b132b_rates; |
| 143 | int max_dprx_rate; | 146 | int max_dprx_rate; |
| 144 | u8 max_dprx_lane_count; | 147 | u8 max_dprx_lane_count; |
| 145 | | 148 | |
| 146 | u8 adapter_id; | 149 | u8 adapter_id; |
| 147 | | 150 | |
| | 151 | bool dprx_128b132b_support:1; |
| | 152 | bool dprx_128b132b_lane0_mapping_support:1; |
| 148 | bool bw_alloc_supported:1; | 153 | bool bw_alloc_supported:1; |
| 149 | bool bw_alloc_enabled:1; | 154 | bool bw_alloc_enabled:1; |
| 150 | bool has_io_error:1; | 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 | return (250000 << gr) / 8; | 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 | static int tunnel_reg_max_dprx_rate(const struct drm_dp_tunnel_regs *regs) | 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 | return drm_dp_bw_code_to_link_rate(bw_code); | 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 | bool changed = false; | 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 | if (tunnel_reg_max_dprx_rate(regs) != tunnel->max_dprx_rate) { | 768 | if (tunnel_reg_max_dprx_rate(regs) != tunnel->max_dprx_rate) { |
| 710 | tunnel->max_dprx_rate = tunnel_reg_max_dprx_rate(regs); | 769 | tunnel->max_dprx_rate = tunnel_reg_max_dprx_rate(regs); |
| 711 | changed = true; | 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 | EXPORT_SYMBOL(drm_dp_tunnel_handle_irq); | 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 | * drm_dp_tunnel_max_dprx_rate - Query the maximum rate of the tunnel's DPRX | 1449 | * drm_dp_tunnel_max_dprx_rate - Query the maximum rate of the tunnel's DPRX |
| 1336 | * @tunnel: Tunnel object | 1450 | * @tunnel: Tunnel object |