Skip to content

Commit 7beee6e

Browse files
Cruise Hungalexdeucher
authored andcommitted
drm/amd/display: Add new DP tunnel bandwidth validation
[Why & How] Add new function for DP tunnel bandwidth validation. It uses the estimated BW and allocated BW to validate the timings. Reviewed-by: PeiChen Huang <peichen.huang@amd.com> Reviewed-by: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com> Signed-off-by: Cruise Hung <Cruise.Hung@amd.com> Signed-off-by: Fangzhi Zuo <jerry.zuo@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
1 parent 0c5f737 commit 7beee6e

File tree

14 files changed

+302
-52
lines changed

14 files changed

+302
-52
lines changed

drivers/gpu/drm/amd/display/dc/core/dc_debug.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,8 @@ char *dc_status_to_str(enum dc_status status)
268268
return "Insufficient DP link bandwidth";
269269
case DC_FAIL_HW_CURSOR_SUPPORT:
270270
return "HW Cursor not supported";
271+
case DC_FAIL_DP_TUNNEL_BW_VALIDATE:
272+
return "Fail DP Tunnel BW validation";
271273
case DC_ERROR_UNEXPECTED:
272274
return "Unexpected error";
273275
}

drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,3 +519,9 @@ bool dc_link_dp_dpia_validate(struct dc *dc, const struct dc_stream_state *strea
519519
{
520520
return dc->link_srv->validate_dpia_bandwidth(streams, count);
521521
}
522+
523+
enum dc_status dc_link_validate_dp_tunneling_bandwidth(const struct dc *dc, const struct dc_state *new_ctx)
524+
{
525+
return dc->link_srv->validate_dp_tunnel_bandwidth(dc, new_ctx);
526+
}
527+

drivers/gpu/drm/amd/display/dc/dc.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,12 @@ struct dmub_notification;
6868
#define MAX_STREAMS 6
6969
#define MIN_VIEWPORT_SIZE 12
7070
#define MAX_NUM_EDP 2
71-
#define MAX_HOST_ROUTERS_NUM 3
72-
#define MAX_DPIA_PER_HOST_ROUTER 2
7371
#define MAX_SUPPORTED_FORMATS 7
7472

73+
#define MAX_HOST_ROUTERS_NUM 3
74+
#define MAX_DPIA_PER_HOST_ROUTER 3
75+
#define MAX_DPIA_NUM (MAX_HOST_ROUTERS_NUM * MAX_DPIA_PER_HOST_ROUTER)
76+
7577
/* Display Core Interfaces */
7678
struct dc_versions {
7779
const char *dc_ver;
@@ -2427,6 +2429,14 @@ void dc_link_dp_dpia_handle_usb4_bandwidth_allocation_for_link(
24272429
bool dc_link_dp_dpia_validate(struct dc *dc, const struct dc_stream_state *streams,
24282430
const unsigned int count);
24292431

2432+
/*
2433+
* Calculates the DP tunneling bandwidth required for the stream timing
2434+
* and aggregates the stream bandwidth for the respective DP tunneling link
2435+
*
2436+
* return: dc_status
2437+
*/
2438+
enum dc_status dc_link_validate_dp_tunneling_bandwidth(const struct dc *dc, const struct dc_state *new_ctx);
2439+
24302440
/* Sink Interfaces - A sink corresponds to a display output device */
24312441

24322442
struct dc_container_id {

drivers/gpu/drm/amd/display/dc/dc_dp_types.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,11 @@ struct dc_link_settings {
162162
struct dc_tunnel_settings {
163163
bool should_enable_dp_tunneling;
164164
bool should_use_dp_bw_allocation;
165+
uint8_t cm_id;
166+
uint8_t group_id;
167+
uint32_t bw_granularity;
168+
uint32_t estimated_bw;
169+
uint32_t allocated_bw;
165170
};
166171

167172
union dc_dp_ffe_preset {
@@ -957,11 +962,21 @@ union usb4_driver_bw_cap {
957962
uint8_t raw;
958963
};
959964

965+
/* DPCD[0xE0021] DP_IN_ADAPTER_TUNNEL_INFORMATION register. */
966+
union dpia_tunnel_info {
967+
struct {
968+
uint8_t group_id :3;
969+
uint8_t rsvd :5;
970+
} bits;
971+
uint8_t raw;
972+
};
973+
960974
/* DP Tunneling over USB4 */
961975
struct dpcd_usb4_dp_tunneling_info {
962976
union dp_tun_cap_support dp_tun_cap;
963977
union dpia_info dpia_info;
964978
union usb4_driver_bw_cap driver_bw_cap;
979+
union dpia_tunnel_info dpia_tunnel_info;
965980
uint8_t usb4_driver_id;
966981
uint8_t usb4_topology_id[DPCD_USB4_TOPOLOGY_ID_LEN];
967982
};

drivers/gpu/drm/amd/display/dc/dc_types.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1378,4 +1378,11 @@ enum dc_validate_mode {
13781378
/* validate the mode and get the max state (voltage level) */
13791379
DC_VALIDATE_MODE_AND_STATE_INDEX = 2,
13801380
};
1381+
1382+
struct dc_validation_dpia_set {
1383+
const struct dc_link *link;
1384+
const struct dc_tunnel_settings *tunnel_settings;
1385+
uint32_t required_bw;
1386+
};
1387+
13811388
#endif /* DC_TYPES_H_ */

drivers/gpu/drm/amd/display/dc/inc/core_status.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ enum dc_status {
5959
DC_FAIL_DP_PAYLOAD_ALLOCATION = 27,
6060
DC_FAIL_DP_LINK_BANDWIDTH = 28,
6161
DC_FAIL_HW_CURSOR_SUPPORT = 29,
62+
DC_FAIL_DP_TUNNEL_BW_VALIDATE = 30,
6263
DC_ERROR_UNEXPECTED = -1
6364
};
6465

drivers/gpu/drm/amd/display/dc/inc/link.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ struct link_service {
147147
bool (*validate_dpia_bandwidth)(
148148
const struct dc_stream_state *stream,
149149
const unsigned int num_streams);
150+
enum dc_status (*validate_dp_tunnel_bandwidth)(
151+
const struct dc *dc,
152+
const struct dc_state *new_ctx);
150153

151154
uint32_t (*dp_required_hblank_size_bytes)(
152155
const struct dc_link *link,

drivers/gpu/drm/amd/display/dc/link/link_dpms.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2295,12 +2295,10 @@ static bool allocate_usb4_bandwidth_for_stream(struct dc_stream_state *stream, i
22952295
}
22962296

22972297
link->dpia_bw_alloc_config.remote_sink_req_bw[sink_index] = bw;
2298+
link->dpia_bw_alloc_config.dp_overhead = link_dpia_get_dp_mst_overhead(link);
2299+
req_bw += link->dpia_bw_alloc_config.dp_overhead;
22982300
}
22992301

2300-
/* get dp overhead for dp tunneling */
2301-
link->dpia_bw_alloc_config.dp_overhead = link_dp_dpia_get_dp_overhead_in_dp_tunneling(link);
2302-
req_bw += link->dpia_bw_alloc_config.dp_overhead;
2303-
23042302
link_dp_dpia_allocate_usb4_bandwidth_for_stream(link, req_bw);
23052303

23062304
if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {

drivers/gpu/drm/amd/display/dc/link/link_factory.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ static void construct_link_service_validation(struct link_service *link_srv)
101101
link_srv->validate_mode_timing = link_validate_mode_timing;
102102
link_srv->dp_link_bandwidth_kbps = dp_link_bandwidth_kbps;
103103
link_srv->validate_dpia_bandwidth = link_validate_dpia_bandwidth;
104+
link_srv->validate_dp_tunnel_bandwidth = link_validate_dp_tunnel_bandwidth;
104105
link_srv->dp_required_hblank_size_bytes = dp_required_hblank_size_bytes;
105106
}
106107

drivers/gpu/drm/amd/display/dc/link/link_validation.c

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,14 @@ uint32_t dp_link_bandwidth_kbps(
263263
return link_rate_per_lane_kbps * link_settings->lane_count / 10000 * total_data_bw_efficiency_x10000;
264264
}
265265

266+
static uint32_t dp_get_timing_bandwidth_kbps(
267+
const struct dc_crtc_timing *timing,
268+
const struct dc_link *link)
269+
{
270+
return dc_bandwidth_in_kbps_from_timing(timing,
271+
dc_link_get_highest_encoding_format(link));
272+
}
273+
266274
static bool dp_validate_mode_timing(
267275
struct dc_link *link,
268276
const struct dc_crtc_timing *timing)
@@ -411,13 +419,88 @@ bool link_validate_dpia_bandwidth(const struct dc_stream_state *stream, const un
411419
for (uint8_t i = 0; i < num_dpias; ++i) {
412420
int dp_overhead = 0;
413421

414-
dp_overhead = link_dp_dpia_get_dp_overhead_in_dp_tunneling(dpia_link[i]);
422+
dp_overhead = link_dpia_get_dp_mst_overhead(dpia_link[i]);
415423
bw_needed[i] += dp_overhead;
416424
}
417425

418426
return dpia_validate_usb4_bw(dpia_link, bw_needed, num_dpias);
419427
}
420428

429+
static const struct dc_tunnel_settings *get_dp_tunnel_settings(const struct dc_state *context,
430+
const struct dc_stream_state *stream)
431+
{
432+
int i;
433+
const struct dc_tunnel_settings *dp_tunnel_settings = NULL;
434+
435+
for (i = 0; i < MAX_PIPES; i++) {
436+
if (context->res_ctx.pipe_ctx[i].stream && (context->res_ctx.pipe_ctx[i].stream == stream)) {
437+
dp_tunnel_settings = &context->res_ctx.pipe_ctx[i].link_config.dp_tunnel_settings;
438+
break;
439+
}
440+
}
441+
442+
return dp_tunnel_settings;
443+
}
444+
445+
/*
446+
* Calculates the DP tunneling bandwidth required for the stream timing
447+
* and aggregates the stream bandwidth for the respective DP tunneling link
448+
*
449+
* return: dc_status
450+
*/
451+
enum dc_status link_validate_dp_tunnel_bandwidth(const struct dc *dc, const struct dc_state *new_ctx)
452+
{
453+
struct dc_validation_dpia_set dpia_link_sets[MAX_DPIA_NUM] = { 0 };
454+
uint8_t link_count = 0;
455+
enum dc_status result = DC_OK;
456+
457+
for (uint8_t i = 0; (i < MAX_PIPES && i < new_ctx->stream_count); i++) {
458+
const struct dc_stream_state *stream = new_ctx->streams[i];
459+
const struct dc_link *link;
460+
const struct dc_tunnel_settings *dp_tunnel_settings;
461+
uint32_t timing_bw;
462+
463+
if (stream == NULL)
464+
continue;
465+
466+
link = stream->link;
467+
468+
if (!(link && (stream->signal == SIGNAL_TYPE_DISPLAY_PORT
469+
|| stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
470+
&& link->hpd_status))
471+
continue;
472+
473+
dp_tunnel_settings = get_dp_tunnel_settings(new_ctx, stream);
474+
475+
if ((dp_tunnel_settings == NULL) || (dp_tunnel_settings->should_use_dp_bw_allocation == false))
476+
continue;
477+
478+
timing_bw = dp_get_timing_bandwidth_kbps(&stream->timing, link);
479+
480+
for (uint8_t j = 0; j < MAX_DPIA_NUM; j++) {
481+
bool is_new_slot = false;
482+
483+
if (dpia_link_sets[j].link == NULL) {
484+
is_new_slot = true;
485+
link_count++;
486+
dpia_link_sets[j].required_bw = 0;
487+
dpia_link_sets[j].link = link;
488+
}
489+
490+
if (is_new_slot || (dpia_link_sets[j].link == link)) {
491+
dpia_link_sets[j].tunnel_settings = dp_tunnel_settings;
492+
dpia_link_sets[j].required_bw += timing_bw;
493+
break;
494+
}
495+
}
496+
}
497+
498+
if (link_count && link_dpia_validate_dp_tunnel_bandwidth(dpia_link_sets, link_count) == false)
499+
result = DC_FAIL_DP_TUNNEL_BW_VALIDATE;
500+
501+
return result;
502+
}
503+
421504
struct dp_audio_layout_config {
422505
uint8_t layouts_per_sample_denom;
423506
uint8_t symbols_per_layout;

0 commit comments

Comments
 (0)