aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/files/0668-drm-amd-dal-Compute-x-y-for-MST-in-dc_link.patch
blob: 29597e7716d997707ba278edf9b35de4b18a9a07 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
From 489af48fca5911be0db30127181a2c11bff9772d Mon Sep 17 00:00:00 2001
From: Harry Wentland <harry.wentland@amd.com>
Date: Thu, 3 Dec 2015 00:18:30 -0500
Subject: [PATCH 0668/1110] drm/amd/dal: Compute x/y for MST in dc_link

Computing x/y for MST more accurately, based on DAL2 code,
rather than doing what radeon driver did.

Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Acked-by: Jordan Lazare <Jordan.Lazare@amd.com>
---
 .../gpu/drm/amd/dal/amdgpu_dm/amdgpu_dc_helpers.c  |  8 ---
 drivers/gpu/drm/amd/dal/dc/core/dc_link.c          | 69 ++++++++++++++++++++--
 .../gpu/drm/amd/dal/include/link_service_types.h   |  3 -
 3 files changed, 63 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dc_helpers.c b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dc_helpers.c
index 3a71159..578517f 100644
--- a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dc_helpers.c
+++ b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dc_helpers.c
@@ -221,14 +221,6 @@ static void get_payload_table(
 							dev,
 							master_port,
 							mst_mgr->payloads[i].vcpi);
-
-			if (mst_mgr->payloads[i].vcpi ==
-					aconnector->port->vcpi.vcpi)
-				table->cur_stream_payload_idx = i;
-
-			/* TODO remove the following and calculate in DC */
-			table->stream_allocations[i].pbn_per_slot = mst_mgr->pbn_div;
-			table->stream_allocations[i].pbn = mst_mgr->proposed_vcpis[i]->pbn;
 		}
 	}
 
diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_link.c b/drivers/gpu/drm/amd/dal/dc/core/dc_link.c
index 94990b9..5e39a41 100644
--- a/drivers/gpu/drm/amd/dal/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/dal/dc/core/dc_link.c
@@ -37,6 +37,7 @@
 #include "stream_encoder.h"
 #include "link_encoder.h"
 #include "hw_sequencer.h"
+#include "fixed31_32.h"
 
 
 #define LINK_INFO(...) \
@@ -52,6 +53,10 @@
  * Private structures
  ******************************************************************************/
 
+enum {
+	LINK_RATE_REF_FREQ_IN_MHZ = 27,
+	PEAK_FACTOR_X1000 = 1006
+};
 
 /*******************************************************************************
  * Private functions
@@ -1275,6 +1280,59 @@ void core_link_resume(struct core_link *link)
 	program_hpd_filter(link);
 }
 
+static struct fixed31_32 get_pbn_per_slot(struct core_stream *stream)
+{
+	struct link_settings *link_settings = &stream->sink->link->cur_link_settings;
+	uint32_t link_rate_in_mbps = link_settings->link_rate * LINK_RATE_REF_FREQ_IN_MHZ;
+	struct fixed31_32 mbps = dal_fixed31_32_from_int(link_rate_in_mbps * link_settings->lane_count);
+
+	return dal_fixed31_32_div_int(mbps, 54);
+}
+
+static int get_color_depth(struct core_stream *stream)
+{
+	switch (stream->pix_clk_params.color_depth) {
+	case COLOR_DEPTH_666: return 6;
+	case COLOR_DEPTH_888: return 8;
+	case COLOR_DEPTH_101010: return 10;
+	case COLOR_DEPTH_121212: return 12;
+	case COLOR_DEPTH_141414: return 14;
+	case COLOR_DEPTH_161616: return 16;
+	default: return 0;
+	}
+}
+
+static struct fixed31_32 get_pbn_from_timing(struct core_stream *stream)
+{
+	uint32_t bpc;
+	uint64_t kbps;
+	struct fixed31_32 peak_kbps;
+	uint32_t numerator;
+	uint32_t denominator;
+
+	bpc = get_color_depth(stream);
+	kbps = stream->pix_clk_params.requested_pix_clk * bpc * 3;
+
+	/*
+	 * margin 5300ppm + 300ppm ~ 0.6% as per spec, factor is 1.006
+	 *
+	 * The unit of 54/64Mbytes/sec is an arbitrary unit chosen based on
+	 * common multiplier to render an integer PBN for all link rate/lane
+	 * counts combinations
+	 * 	 *
+	 * calculate
+	 * 	peak_kbps *= (1006/1000)
+	 * 	peak_kbps *= (64/54)
+	 * 	peak_kbps *= 8    convert to bytes
+	 */
+
+	numerator = 64 * PEAK_FACTOR_X1000;
+	denominator = 54 * 8 * 1000 * 1000;
+	kbps *= numerator;
+	peak_kbps = dal_fixed31_32_from_fraction(kbps, denominator);
+
+	return peak_kbps;
+}
 
 static enum dc_status allocate_mst_payload(struct core_stream *stream)
 {
@@ -1283,8 +1341,9 @@ static enum dc_status allocate_mst_payload(struct core_stream *stream)
 	struct stream_encoder *stream_encoder = stream->stream_enc;
 	struct dp_mst_stream_allocation_table table = {0};
 	struct fixed31_32 avg_time_slots_per_mtp;
-	uint8_t cur_stream_payload_idx;
 	struct dc *dc = stream->ctx->dc;
+	struct fixed31_32 pbn;
+	struct fixed31_32 pbn_per_slot;
 
 	/* enable_link_dp_mst already check link->enabled_stream_count
 	 * and stream is in link->stream[]. This is called during set mode,
@@ -1322,11 +1381,9 @@ static enum dc_status allocate_mst_payload(struct core_stream *stream)
 			&stream->public,
 			true);
 
-	/* slot X.Y for only current stream */
-	cur_stream_payload_idx = table.cur_stream_payload_idx;
-	avg_time_slots_per_mtp = dal_fixed31_32_from_fraction(
-		table.stream_allocations[cur_stream_payload_idx].pbn,
-		table.stream_allocations[cur_stream_payload_idx].pbn_per_slot);
+	pbn_per_slot = get_pbn_per_slot(stream);
+	pbn = get_pbn_from_timing(stream);
+	avg_time_slots_per_mtp = dal_fixed31_32_div(pbn, pbn_per_slot);
 
 	dc->hwss.set_mst_bandwidth(
 		stream_encoder,
diff --git a/drivers/gpu/drm/amd/dal/include/link_service_types.h b/drivers/gpu/drm/amd/dal/include/link_service_types.h
index d91f4b0..429d969 100644
--- a/drivers/gpu/drm/amd/dal/include/link_service_types.h
+++ b/drivers/gpu/drm/amd/dal/include/link_service_types.h
@@ -396,15 +396,12 @@ struct dp_mst_stream_allocation {
 	/* number of slots required for the DP stream in
 	 * transport packet */
 	uint32_t slot_count;
-	uint32_t pbn;
-	uint32_t pbn_per_slot;
 };
 
 /* DP MST stream allocation table */
 struct dp_mst_stream_allocation_table {
 	/* number of DP video streams */
 	uint8_t stream_count;
-	uint8_t cur_stream_payload_idx;
 	/* array of stream allocations */
 	struct dp_mst_stream_allocation stream_allocations[MAX_CONTROLLER_NUM];
 };
-- 
2.7.4