aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/files/0575-drm-amd-dal-amd-dc-Implement-get-memory-and-engine-c.patch
blob: a3f305bad9747975457d412332c697cb3f1178ae (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
168
169
170
171
172
173
174
175
176
177
178
179
From a5e65a3bdc11c64a135c4312bf79c6b7baf879c2 Mon Sep 17 00:00:00 2001
From: Vitaly Prosyak <vitaly.prosyak@amd.com>
Date: Thu, 3 Dec 2015 13:48:04 -0500
Subject: [PATCH 0575/1110] drm/amd/dal: amd/dc Implement get memory and engine
 clocks from PPLib

Added comments for clocks: PPLib uses tens of kHz, DM uses kHz,
but DC does in fixed point MHz

Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Acked-by: Harry Wentland <harry.wentland@amd.com>
---
 .../drm/amd/dal/amdgpu_dm/amdgpu_dal_services.c    | 53 ++++++++++++++--------
 drivers/gpu/drm/amd/dal/dc/core/dc.c               | 45 +++++++++++++++---
 drivers/gpu/drm/amd/dal/dc/dc_services.h           |  2 +-
 3 files changed, 73 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dal_services.c b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dal_services.c
index fd54703..2c02d18 100644
--- a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dal_services.c
+++ b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dal_services.c
@@ -234,43 +234,58 @@ bool dc_service_pp_get_clock_levels_by_type(
 		enum dc_pp_clock_type clk_type,
 		struct dc_pp_clock_levels *clks)
 {
-#ifdef CONFIG_DRM_AMD_POWERPLAY
-/* TODO: get clks from pplib.
+
+/*
+ #ifdef CONFIG_DRM_AMD_POWERPLAY
+	if(amd_powerplay_get_clocks_by_type(adev->powerplay.pp_handle,
+		(int)clk_type, (void *)clks) == fail
+		PPlib return clocks in tens of kHz
+		divide by 10 & push to the clks which kHz
+#endif
+*/
+
 	struct amdgpu_device *adev = ctx->driver_context;
 
-	return (amd_powerplay_get_clocks_by_type(adev->powerplay.pp_handle,
-			(int)clk_type, (void *)clks) == 0);
-			*/
-	uint32_t disp_clks_in_hz[8] = {
-			30000, 41143, 48000, 53334, 62609, 62609, 62609, 62609 };
-	uint32_t sclks_in_hz[8] = {
-			20000, 26667, 34286, 41143, 45000, 51429, 57600, 62609 };
-	uint32_t mclks_in_hz[8] = { 33300, 80000, 0, 0, 0, 0, 0, 0 };
+	uint32_t disp_clks_in_khz[8] = {
+	300000, 411430, 480000, 533340, 626090, 626090, 626090, 626090 };
+	uint32_t sclks_in_khz[8] = {
+	200000, 266670, 342860, 411430, 450000, 514290, 576000, 626090 };
+	uint32_t mclks_in_khz[8] = { 333000, 800000 };
+
+	struct amd_pp_dal_clock_info info = {0};
 
 	switch (clk_type) {
 	case DC_PP_CLOCK_TYPE_DISPLAY_CLK:
 		clks->num_levels = 8;
-		dc_service_memmove(clks->clocks_in_hz, disp_clks_in_hz, 8);
+		dc_service_memmove(clks->clocks_in_khz, disp_clks_in_khz,
+				sizeof(disp_clks_in_khz));
 		break;
 	case DC_PP_CLOCK_TYPE_ENGINE_CLK:
 		clks->num_levels = 8;
-		dc_service_memmove(clks->clocks_in_hz, sclks_in_hz, 8);
+		dc_service_memmove(clks->clocks_in_khz, sclks_in_khz,
+				sizeof(sclks_in_khz));
 		break;
 	case DC_PP_CLOCK_TYPE_MEMORY_CLK:
 		clks->num_levels = 2;
-		dc_service_memmove(clks->clocks_in_hz, mclks_in_hz, 8);
+		dc_service_memmove(clks->clocks_in_khz, mclks_in_khz,
+				sizeof(mclks_in_khz));
 		break;
 	default:
 		return false;
 	}
-
-	return true;
-#else
-	DRM_INFO("%s - not implemented\n", __func__);
-	return false;
+#ifdef CONFIG_DRM_AMD_POWERPLAY
+	if (clk_type ==  DC_PP_CLOCK_TYPE_ENGINE_CLK ||
+		clk_type ==  DC_PP_CLOCK_TYPE_DISPLAY_CLK) {
+		if (0 == amd_powerplay_get_display_power_level(
+				adev->powerplay.pp_handle, &info) &&
+				info.level < clks->num_levels) {
+		/*if the max possible power level less then use smaller*/
+			clks->num_levels = info.level;
+		}
+	}
 #endif
+	return true;
 }
-
 /**** end of power component interfaces ****/
 
 
diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc.c b/drivers/gpu/drm/amd/dal/dc/core/dc.c
index 57277ed..599bf2f 100644
--- a/drivers/gpu/drm/amd/dal/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/dal/dc/core/dc.c
@@ -226,9 +226,45 @@ static struct adapter_service *create_as(
 
 static void bw_calcs_data_update_from_pplib(struct dc *dc)
 {
-	struct dal_system_clock_range clk_range = { 0 };
+	struct dc_pp_clock_levels clks = {0};
 
-	dc_service_get_system_clocks_range(dc->ctx, &clk_range);
+	/*do system clock*/
+	dc_service_pp_get_clock_levels_by_type(
+			dc->ctx,
+			DC_PP_CLOCK_TYPE_ENGINE_CLK,
+			&clks);
+	/* convert all the clock fro kHz to fix point mHz */
+	dc->bw_vbios.high_sclk = frc_to_fixed(
+			clks.clocks_in_khz[clks.num_levels-1], 1000);
+	dc->bw_vbios.mid_sclk  = frc_to_fixed(
+			clks.clocks_in_khz[clks.num_levels>>1], 1000);
+	dc->bw_vbios.low_sclk  = frc_to_fixed(
+			clks.clocks_in_khz[0], 1000);
+
+	/*do display clock*/
+	dc_service_pp_get_clock_levels_by_type(
+			dc->ctx,
+			DC_PP_CLOCK_TYPE_DISPLAY_CLK,
+			&clks);
+
+	dc->bw_vbios.high_voltage_max_dispclk = frc_to_fixed(
+			clks.clocks_in_khz[clks.num_levels-1], 1000);
+	dc->bw_vbios.mid_voltage_max_dispclk  = frc_to_fixed(
+			clks.clocks_in_khz[clks.num_levels>>1], 1000);
+	dc->bw_vbios.low_voltage_max_dispclk  = frc_to_fixed(
+			clks.clocks_in_khz[0], 1000);
+
+	/*do memory clock*/
+	dc_service_pp_get_clock_levels_by_type(
+			dc->ctx,
+			DC_PP_CLOCK_TYPE_MEMORY_CLK,
+			&clks);
+
+	dc->bw_vbios.low_yclk = frc_to_fixed(
+			clks.clocks_in_khz[0], 1000);
+	dc->bw_vbios.high_yclk = frc_to_fixed(
+			clks.clocks_in_khz[clks.num_levels-1], 1000);
+	return;
 
 	/* on CZ Gardenia from PPLib we get:
 	 * clk_range.max_mclk:80000
@@ -238,11 +274,6 @@ static void bw_calcs_data_update_from_pplib(struct dc *dc)
 
 	/* The values for calcs are stored in units of MHz, so for example
 	 * 80000 will be stored as 800. */
-	dc->bw_vbios.high_sclk = frc_to_fixed(clk_range.max_sclk, 100);
-	dc->bw_vbios.low_sclk = frc_to_fixed(clk_range.min_sclk, 100);
-
-	dc->bw_vbios.high_yclk = frc_to_fixed(clk_range.max_mclk, 100);
-	dc->bw_vbios.low_yclk = frc_to_fixed(clk_range.min_mclk, 100);
 }
 
 static bool construct(struct dc *dc, const struct dal_init_data *init_params)
diff --git a/drivers/gpu/drm/amd/dal/dc/dc_services.h b/drivers/gpu/drm/amd/dal/dc/dc_services.h
index c2172ea..a584b6a 100644
--- a/drivers/gpu/drm/amd/dal/dc/dc_services.h
+++ b/drivers/gpu/drm/amd/dal/dc/dc_services.h
@@ -176,7 +176,7 @@ enum dc_pp_clock_type {
 
 struct dc_pp_clock_levels {
 	uint32_t num_levels;
-	uint32_t clocks_in_hz[DC_PP_MAX_CLOCK_LEVELS];
+	uint32_t clocks_in_khz[DC_PP_MAX_CLOCK_LEVELS];
 
 	/* TODO: add latency
 	 * do we need to know invalid (unsustainable boost) level for watermark
-- 
2.7.4