hc
2024-05-10 61598093bbdd283a7edc367d900f223070ead8d2
kernel/drivers/gpu/drm/msm/adreno/a5xx_power.c
....@@ -1,14 +1,5 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /* Copyright (c) 2016 The Linux Foundation. All rights reserved.
2
- *
3
- * This program is free software; you can redistribute it and/or modify
4
- * it under the terms of the GNU General Public License version 2 and
5
- * only version 2 as published by the Free Software Foundation.
6
- *
7
- * This program is distributed in the hope that it will be useful,
8
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
- * GNU General Public License for more details.
11
- *
123 */
134
145 #include <linux/pm_opp.h>
....@@ -31,6 +22,18 @@
3122
3223 #define AGC_POWER_CONFIG_PRODUCTION_ID 1
3324 #define AGC_INIT_MSG_VALUE 0xBABEFACE
25
+
26
+/* AGC_LM_CONFIG (A540+) */
27
+#define AGC_LM_CONFIG (136/4)
28
+#define AGC_LM_CONFIG_GPU_VERSION_SHIFT 17
29
+#define AGC_LM_CONFIG_ENABLE_GPMU_ADAPTIVE 1
30
+#define AGC_LM_CONFIG_THROTTLE_DISABLE (2 << 8)
31
+#define AGC_LM_CONFIG_ISENSE_ENABLE (1 << 4)
32
+#define AGC_LM_CONFIG_ENABLE_ERROR (3 << 4)
33
+#define AGC_LM_CONFIG_LLM_ENABLED (1 << 16)
34
+#define AGC_LM_CONFIG_BCL_DISABLED (1 << 24)
35
+
36
+#define AGC_LEVEL_CONFIG (140/4)
3437
3538 static struct {
3639 uint32_t reg;
....@@ -116,7 +119,7 @@
116119 }
117120
118121 /* Setup thermal limit management */
119
-static void a5xx_lm_setup(struct msm_gpu *gpu)
122
+static void a530_lm_setup(struct msm_gpu *gpu)
120123 {
121124 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
122125 struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
....@@ -165,6 +168,45 @@
165168 gpu_write(gpu, AGC_INIT_MSG_MAGIC, AGC_INIT_MSG_VALUE);
166169 }
167170
171
+#define PAYLOAD_SIZE(_size) ((_size) * sizeof(u32))
172
+#define LM_DCVS_LIMIT 1
173
+#define LEVEL_CONFIG ~(0x303)
174
+
175
+static void a540_lm_setup(struct msm_gpu *gpu)
176
+{
177
+ struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
178
+ u32 config;
179
+
180
+ /* The battery current limiter isn't enabled for A540 */
181
+ config = AGC_LM_CONFIG_BCL_DISABLED;
182
+ config |= adreno_gpu->rev.patchid << AGC_LM_CONFIG_GPU_VERSION_SHIFT;
183
+
184
+ /* For now disable GPMU side throttling */
185
+ config |= AGC_LM_CONFIG_THROTTLE_DISABLE;
186
+
187
+ /* Until we get clock scaling 0 is always the active power level */
188
+ gpu_write(gpu, REG_A5XX_GPMU_GPMU_VOLTAGE, 0x80000000 | 0);
189
+
190
+ /* Fixed at 6000 for now */
191
+ gpu_write(gpu, REG_A5XX_GPMU_GPMU_PWR_THRESHOLD, 0x80000000 | 6000);
192
+
193
+ gpu_write(gpu, AGC_MSG_STATE, 0x80000001);
194
+ gpu_write(gpu, AGC_MSG_COMMAND, AGC_POWER_CONFIG_PRODUCTION_ID);
195
+
196
+ gpu_write(gpu, AGC_MSG_PAYLOAD(0), 5448);
197
+ gpu_write(gpu, AGC_MSG_PAYLOAD(1), 1);
198
+
199
+ gpu_write(gpu, AGC_MSG_PAYLOAD(2), _get_mvolts(gpu, gpu->fast_rate));
200
+ gpu_write(gpu, AGC_MSG_PAYLOAD(3), gpu->fast_rate / 1000000);
201
+
202
+ gpu_write(gpu, AGC_MSG_PAYLOAD(AGC_LM_CONFIG), config);
203
+ gpu_write(gpu, AGC_MSG_PAYLOAD(AGC_LEVEL_CONFIG), LEVEL_CONFIG);
204
+ gpu_write(gpu, AGC_MSG_PAYLOAD_SIZE,
205
+ PAYLOAD_SIZE(AGC_LEVEL_CONFIG + 1));
206
+
207
+ gpu_write(gpu, AGC_INIT_MSG_MAGIC, AGC_INIT_MSG_VALUE);
208
+}
209
+
168210 /* Enable SP/TP cpower collapse */
169211 static void a5xx_pc_init(struct msm_gpu *gpu)
170212 {
....@@ -198,7 +240,7 @@
198240 OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1);
199241 OUT_RING(ring, 1);
200242
201
- gpu->funcs->flush(gpu, ring);
243
+ a5xx_flush(gpu, ring, true);
202244
203245 if (!a5xx_idle(gpu, ring)) {
204246 DRM_ERROR("%s: Unable to load GPMU firmware. GPMU will not be active\n",
....@@ -206,7 +248,8 @@
206248 return -EINVAL;
207249 }
208250
209
- gpu_write(gpu, REG_A5XX_GPMU_WFI_CONFIG, 0x4014);
251
+ if (adreno_is_a530(adreno_gpu))
252
+ gpu_write(gpu, REG_A5XX_GPMU_WFI_CONFIG, 0x4014);
210253
211254 /* Kick off the GPMU */
212255 gpu_write(gpu, REG_A5XX_GPMU_CM3_SYSRESET, 0x0);
....@@ -220,12 +263,26 @@
220263 DRM_ERROR("%s: GPMU firmware initialization timed out\n",
221264 gpu->name);
222265
266
+ if (!adreno_is_a530(adreno_gpu)) {
267
+ u32 val = gpu_read(gpu, REG_A5XX_GPMU_GENERAL_1);
268
+
269
+ if (val)
270
+ DRM_ERROR("%s: GPMU firmware initialization failed: %d\n",
271
+ gpu->name, val);
272
+ }
273
+
223274 return 0;
224275 }
225276
226277 /* Enable limits management */
227278 static void a5xx_lm_enable(struct msm_gpu *gpu)
228279 {
280
+ struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
281
+
282
+ /* This init sequence only applies to A530 */
283
+ if (!adreno_is_a530(adreno_gpu))
284
+ return;
285
+
229286 gpu_write(gpu, REG_A5XX_GDPM_INT_MASK, 0x0);
230287 gpu_write(gpu, REG_A5XX_GDPM_INT_EN, 0x0A);
231288 gpu_write(gpu, REG_A5XX_GPMU_GPMU_VOLTAGE_INTR_EN_MASK, 0x01);
....@@ -237,10 +294,18 @@
237294
238295 int a5xx_power_init(struct msm_gpu *gpu)
239296 {
297
+ struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
240298 int ret;
241299
300
+ /* Not all A5xx chips have a GPMU */
301
+ if (adreno_is_a510(adreno_gpu))
302
+ return 0;
303
+
242304 /* Set up the limits management */
243
- a5xx_lm_setup(gpu);
305
+ if (adreno_is_a530(adreno_gpu))
306
+ a530_lm_setup(gpu);
307
+ else if (adreno_is_a540(adreno_gpu))
308
+ a540_lm_setup(gpu);
244309
245310 /* Set up SP/TP power collpase */
246311 a5xx_pc_init(gpu);
....@@ -264,6 +329,9 @@
264329 uint32_t dwords = 0, offset = 0, bosize;
265330 unsigned int *data, *ptr, *cmds;
266331 unsigned int cmds_size;
332
+
333
+ if (adreno_is_a510(adreno_gpu))
334
+ return;
267335
268336 if (a5xx_gpu->gpmu_bo)
269337 return;
....@@ -298,7 +366,9 @@
298366 MSM_BO_UNCACHED | MSM_BO_GPU_READONLY, gpu->aspace,
299367 &a5xx_gpu->gpmu_bo, &a5xx_gpu->gpmu_iova);
300368 if (IS_ERR(ptr))
301
- goto err;
369
+ return;
370
+
371
+ msm_gem_object_set_name(a5xx_gpu->gpmu_bo, "gpmufw");
302372
303373 while (cmds_size > 0) {
304374 int i;
....@@ -317,15 +387,4 @@
317387
318388 msm_gem_put_vaddr(a5xx_gpu->gpmu_bo);
319389 a5xx_gpu->gpmu_dwords = dwords;
320
-
321
- return;
322
-err:
323
- if (a5xx_gpu->gpmu_iova)
324
- msm_gem_put_iova(a5xx_gpu->gpmu_bo, gpu->aspace);
325
- if (a5xx_gpu->gpmu_bo)
326
- drm_gem_object_unreference(a5xx_gpu->gpmu_bo);
327
-
328
- a5xx_gpu->gpmu_bo = NULL;
329
- a5xx_gpu->gpmu_iova = 0;
330
- a5xx_gpu->gpmu_dwords = 0;
331390 }