forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-11 04dd17822334871b23ea2862f7798fb0e0007777
kernel/drivers/gpu/drm/msm/adreno/a6xx_hfi.c
....@@ -7,6 +7,7 @@
77
88 #include "a6xx_gmu.h"
99 #include "a6xx_gmu.xml.h"
10
+#include "a6xx_gpu.h"
1011
1112 #define HFI_MSG_ID(val) [val] = #val
1213
....@@ -16,10 +17,14 @@
1617 HFI_MSG_ID(HFI_H2F_MSG_BW_TABLE),
1718 HFI_MSG_ID(HFI_H2F_MSG_PERF_TABLE),
1819 HFI_MSG_ID(HFI_H2F_MSG_TEST),
20
+ HFI_MSG_ID(HFI_H2F_MSG_START),
21
+ HFI_MSG_ID(HFI_H2F_MSG_CORE_FW_START),
22
+ HFI_MSG_ID(HFI_H2F_MSG_GX_BW_PERF_VOTE),
23
+ HFI_MSG_ID(HFI_H2F_MSG_PREPARE_SLUMBER),
1924 };
2025
21
-static int a6xx_hfi_queue_read(struct a6xx_hfi_queue *queue, u32 *data,
22
- u32 dwords)
26
+static int a6xx_hfi_queue_read(struct a6xx_gmu *gmu,
27
+ struct a6xx_hfi_queue *queue, u32 *data, u32 dwords)
2328 {
2429 struct a6xx_hfi_queue_header *header = queue->header;
2530 u32 i, hdr, index = header->read_index;
....@@ -47,6 +52,9 @@
4752 index = (index + 1) % header->size;
4853 }
4954
55
+ if (!gmu->legacy)
56
+ index = ALIGN(index, 4) % header->size;
57
+
5058 header->read_index = index;
5159 return HFI_HEADER_SIZE(hdr);
5260 }
....@@ -72,6 +80,12 @@
7280 index = (index + 1) % header->size;
7381 }
7482
83
+ /* Cookify any non used data at the end of the write buffer */
84
+ if (!gmu->legacy) {
85
+ for (; index % 4; index = (index + 1) % header->size)
86
+ queue->data[index] = 0xfafafafa;
87
+ }
88
+
7589 header->write_index = index;
7690 spin_unlock(&queue->lock);
7791
....@@ -79,83 +93,72 @@
7993 return 0;
8094 }
8195
82
-struct a6xx_hfi_response {
83
- u32 id;
84
- u32 seqnum;
85
- struct list_head node;
86
- struct completion complete;
87
-
88
- u32 error;
89
- u32 payload[16];
90
-};
91
-
92
-/*
93
- * Incoming HFI ack messages can come in out of order so we need to store all
94
- * the pending messages on a list until they are handled.
95
- */
96
-static spinlock_t hfi_ack_lock = __SPIN_LOCK_UNLOCKED(message_lock);
97
-static LIST_HEAD(hfi_ack_list);
98
-
99
-static void a6xx_hfi_handle_ack(struct a6xx_gmu *gmu,
100
- struct a6xx_hfi_msg_response *msg)
96
+static int a6xx_hfi_wait_for_ack(struct a6xx_gmu *gmu, u32 id, u32 seqnum,
97
+ u32 *payload, u32 payload_size)
10198 {
102
- struct a6xx_hfi_response *resp;
103
- u32 id, seqnum;
104
-
105
- /* msg->ret_header contains the header of the message being acked */
106
- id = HFI_HEADER_ID(msg->ret_header);
107
- seqnum = HFI_HEADER_SEQNUM(msg->ret_header);
108
-
109
- spin_lock(&hfi_ack_lock);
110
- list_for_each_entry(resp, &hfi_ack_list, node) {
111
- if (resp->id == id && resp->seqnum == seqnum) {
112
- resp->error = msg->error;
113
- memcpy(resp->payload, msg->payload,
114
- sizeof(resp->payload));
115
-
116
- complete(&resp->complete);
117
- spin_unlock(&hfi_ack_lock);
118
- return;
119
- }
120
- }
121
- spin_unlock(&hfi_ack_lock);
122
-
123
- dev_err(gmu->dev, "Nobody was waiting for HFI message %d\n", seqnum);
124
-}
125
-
126
-static void a6xx_hfi_handle_error(struct a6xx_gmu *gmu,
127
- struct a6xx_hfi_msg_response *msg)
128
-{
129
- struct a6xx_hfi_msg_error *error = (struct a6xx_hfi_msg_error *) msg;
130
-
131
- dev_err(gmu->dev, "GMU firmware error %d\n", error->code);
132
-}
133
-
134
-void a6xx_hfi_task(unsigned long data)
135
-{
136
- struct a6xx_gmu *gmu = (struct a6xx_gmu *) data;
13799 struct a6xx_hfi_queue *queue = &gmu->queues[HFI_RESPONSE_QUEUE];
138
- struct a6xx_hfi_msg_response resp;
100
+ u32 val;
101
+ int ret;
102
+
103
+ /* Wait for a response */
104
+ ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_GMU2HOST_INTR_INFO, val,
105
+ val & A6XX_GMU_GMU2HOST_INTR_INFO_MSGQ, 100, 5000);
106
+
107
+ if (ret) {
108
+ DRM_DEV_ERROR(gmu->dev,
109
+ "Message %s id %d timed out waiting for response\n",
110
+ a6xx_hfi_msg_id[id], seqnum);
111
+ return -ETIMEDOUT;
112
+ }
113
+
114
+ /* Clear the interrupt */
115
+ gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_CLR,
116
+ A6XX_GMU_GMU2HOST_INTR_INFO_MSGQ);
139117
140118 for (;;) {
141
- u32 id;
142
- int ret = a6xx_hfi_queue_read(queue, (u32 *) &resp,
119
+ struct a6xx_hfi_msg_response resp;
120
+
121
+ /* Get the next packet */
122
+ ret = a6xx_hfi_queue_read(gmu, queue, (u32 *) &resp,
143123 sizeof(resp) >> 2);
144124
145
- /* Returns the number of bytes copied or negative on error */
146
- if (ret <= 0) {
147
- if (ret < 0)
148
- dev_err(gmu->dev,
149
- "Unable to read the HFI message queue\n");
150
- break;
125
+ /* If the queue is empty our response never made it */
126
+ if (!ret) {
127
+ DRM_DEV_ERROR(gmu->dev,
128
+ "The HFI response queue is unexpectedly empty\n");
129
+
130
+ return -ENOENT;
151131 }
152132
153
- id = HFI_HEADER_ID(resp.header);
133
+ if (HFI_HEADER_ID(resp.header) == HFI_F2H_MSG_ERROR) {
134
+ struct a6xx_hfi_msg_error *error =
135
+ (struct a6xx_hfi_msg_error *) &resp;
154136
155
- if (id == HFI_F2H_MSG_ACK)
156
- a6xx_hfi_handle_ack(gmu, &resp);
157
- else if (id == HFI_F2H_MSG_ERROR)
158
- a6xx_hfi_handle_error(gmu, &resp);
137
+ DRM_DEV_ERROR(gmu->dev, "GMU firmware error %d\n",
138
+ error->code);
139
+ continue;
140
+ }
141
+
142
+ if (seqnum != HFI_HEADER_SEQNUM(resp.ret_header)) {
143
+ DRM_DEV_ERROR(gmu->dev,
144
+ "Unexpected message id %d on the response queue\n",
145
+ HFI_HEADER_SEQNUM(resp.ret_header));
146
+ continue;
147
+ }
148
+
149
+ if (resp.error) {
150
+ DRM_DEV_ERROR(gmu->dev,
151
+ "Message %s id %d returned error %d\n",
152
+ a6xx_hfi_msg_id[id], seqnum, resp.error);
153
+ return -EINVAL;
154
+ }
155
+
156
+ /* All is well, copy over the buffer */
157
+ if (payload && payload_size)
158
+ memcpy(payload, resp.payload,
159
+ min_t(u32, payload_size, sizeof(resp.payload)));
160
+
161
+ return 0;
159162 }
160163 }
161164
....@@ -163,7 +166,6 @@
163166 void *data, u32 size, u32 *payload, u32 payload_size)
164167 {
165168 struct a6xx_hfi_queue *queue = &gmu->queues[HFI_COMMAND_QUEUE];
166
- struct a6xx_hfi_response resp = { 0 };
167169 int ret, dwords = size >> 2;
168170 u32 seqnum;
169171
....@@ -173,61 +175,22 @@
173175 *((u32 *) data) = (seqnum << 20) | (HFI_MSG_CMD << 16) |
174176 (dwords << 8) | id;
175177
176
- init_completion(&resp.complete);
177
- resp.id = id;
178
- resp.seqnum = seqnum;
179
-
180
- spin_lock_bh(&hfi_ack_lock);
181
- list_add_tail(&resp.node, &hfi_ack_list);
182
- spin_unlock_bh(&hfi_ack_lock);
183
-
184178 ret = a6xx_hfi_queue_write(gmu, queue, data, dwords);
185179 if (ret) {
186
- dev_err(gmu->dev, "Unable to send message %s id %d\n",
180
+ DRM_DEV_ERROR(gmu->dev, "Unable to send message %s id %d\n",
187181 a6xx_hfi_msg_id[id], seqnum);
188
- goto out;
189
- }
190
-
191
- /* Wait up to 5 seconds for the response */
192
- ret = wait_for_completion_timeout(&resp.complete,
193
- msecs_to_jiffies(5000));
194
- if (!ret) {
195
- dev_err(gmu->dev,
196
- "Message %s id %d timed out waiting for response\n",
197
- a6xx_hfi_msg_id[id], seqnum);
198
- ret = -ETIMEDOUT;
199
- } else
200
- ret = 0;
201
-
202
-out:
203
- spin_lock_bh(&hfi_ack_lock);
204
- list_del(&resp.node);
205
- spin_unlock_bh(&hfi_ack_lock);
206
-
207
- if (ret)
208182 return ret;
209
-
210
- if (resp.error) {
211
- dev_err(gmu->dev, "Message %s id %d returned error %d\n",
212
- a6xx_hfi_msg_id[id], seqnum, resp.error);
213
- return -EINVAL;
214183 }
215184
216
- if (payload && payload_size) {
217
- int copy = min_t(u32, payload_size, sizeof(resp.payload));
218
-
219
- memcpy(payload, resp.payload, copy);
220
- }
221
-
222
- return 0;
185
+ return a6xx_hfi_wait_for_ack(gmu, id, seqnum, payload, payload_size);
223186 }
224187
225188 static int a6xx_hfi_send_gmu_init(struct a6xx_gmu *gmu, int boot_state)
226189 {
227190 struct a6xx_hfi_msg_gmu_init_cmd msg = { 0 };
228191
229
- msg.dbg_buffer_addr = (u32) gmu->debug->iova;
230
- msg.dbg_buffer_size = (u32) gmu->debug->size;
192
+ msg.dbg_buffer_addr = (u32) gmu->debug.iova;
193
+ msg.dbg_buffer_size = (u32) gmu->debug.size;
231194 msg.boot_state = boot_state;
232195
233196 return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_INIT, &msg, sizeof(msg),
....@@ -245,9 +208,9 @@
245208 version, sizeof(*version));
246209 }
247210
248
-static int a6xx_hfi_send_perf_table(struct a6xx_gmu *gmu)
211
+static int a6xx_hfi_send_perf_table_v1(struct a6xx_gmu *gmu)
249212 {
250
- struct a6xx_hfi_msg_perf_table msg = { 0 };
213
+ struct a6xx_hfi_msg_perf_table_v1 msg = { 0 };
251214 int i;
252215
253216 msg.num_gpu_levels = gmu->nr_gpu_freqs;
....@@ -267,48 +230,179 @@
267230 NULL, 0);
268231 }
269232
270
-static int a6xx_hfi_send_bw_table(struct a6xx_gmu *gmu)
233
+static int a6xx_hfi_send_perf_table(struct a6xx_gmu *gmu)
271234 {
272
- struct a6xx_hfi_msg_bw_table msg = { 0 };
235
+ struct a6xx_hfi_msg_perf_table msg = { 0 };
236
+ int i;
237
+
238
+ msg.num_gpu_levels = gmu->nr_gpu_freqs;
239
+ msg.num_gmu_levels = gmu->nr_gmu_freqs;
240
+
241
+ for (i = 0; i < gmu->nr_gpu_freqs; i++) {
242
+ msg.gx_votes[i].vote = gmu->gx_arc_votes[i];
243
+ msg.gx_votes[i].acd = 0xffffffff;
244
+ msg.gx_votes[i].freq = gmu->gpu_freqs[i] / 1000;
245
+ }
246
+
247
+ for (i = 0; i < gmu->nr_gmu_freqs; i++) {
248
+ msg.cx_votes[i].vote = gmu->cx_arc_votes[i];
249
+ msg.cx_votes[i].freq = gmu->gmu_freqs[i] / 1000;
250
+ }
251
+
252
+ return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_PERF_TABLE, &msg, sizeof(msg),
253
+ NULL, 0);
254
+}
255
+
256
+static void a618_build_bw_table(struct a6xx_hfi_msg_bw_table *msg)
257
+{
258
+ /* Send a single "off" entry since the 618 GMU doesn't do bus scaling */
259
+ msg->bw_level_num = 1;
260
+
261
+ msg->ddr_cmds_num = 3;
262
+ msg->ddr_wait_bitmask = 0x01;
263
+
264
+ msg->ddr_cmds_addrs[0] = 0x50000;
265
+ msg->ddr_cmds_addrs[1] = 0x5003c;
266
+ msg->ddr_cmds_addrs[2] = 0x5000c;
267
+
268
+ msg->ddr_cmds_data[0][0] = 0x40000000;
269
+ msg->ddr_cmds_data[0][1] = 0x40000000;
270
+ msg->ddr_cmds_data[0][2] = 0x40000000;
273271
274272 /*
275
- * The sdm845 GMU doesn't do bus frequency scaling on its own but it
276
- * does need at least one entry in the list because it might be accessed
277
- * when the GMU is shutting down. Send a single "off" entry.
273
+ * These are the CX (CNOC) votes - these are used by the GMU but the
274
+ * votes are known and fixed for the target
278275 */
276
+ msg->cnoc_cmds_num = 1;
277
+ msg->cnoc_wait_bitmask = 0x01;
279278
280
- msg.bw_level_num = 1;
279
+ msg->cnoc_cmds_addrs[0] = 0x5007c;
280
+ msg->cnoc_cmds_data[0][0] = 0x40000000;
281
+ msg->cnoc_cmds_data[1][0] = 0x60000001;
282
+}
281283
282
- msg.ddr_cmds_num = 3;
283
- msg.ddr_wait_bitmask = 0x07;
284
+static void a640_build_bw_table(struct a6xx_hfi_msg_bw_table *msg)
285
+{
286
+ /*
287
+ * Send a single "off" entry just to get things running
288
+ * TODO: bus scaling
289
+ */
290
+ msg->bw_level_num = 1;
284291
285
- msg.ddr_cmds_addrs[0] = 0x50000;
286
- msg.ddr_cmds_addrs[1] = 0x5005c;
287
- msg.ddr_cmds_addrs[2] = 0x5000c;
292
+ msg->ddr_cmds_num = 3;
293
+ msg->ddr_wait_bitmask = 0x01;
288294
289
- msg.ddr_cmds_data[0][0] = 0x40000000;
290
- msg.ddr_cmds_data[0][1] = 0x40000000;
291
- msg.ddr_cmds_data[0][2] = 0x40000000;
295
+ msg->ddr_cmds_addrs[0] = 0x50000;
296
+ msg->ddr_cmds_addrs[1] = 0x5003c;
297
+ msg->ddr_cmds_addrs[2] = 0x5000c;
298
+
299
+ msg->ddr_cmds_data[0][0] = 0x40000000;
300
+ msg->ddr_cmds_data[0][1] = 0x40000000;
301
+ msg->ddr_cmds_data[0][2] = 0x40000000;
302
+
303
+ /*
304
+ * These are the CX (CNOC) votes - these are used by the GMU but the
305
+ * votes are known and fixed for the target
306
+ */
307
+ msg->cnoc_cmds_num = 3;
308
+ msg->cnoc_wait_bitmask = 0x01;
309
+
310
+ msg->cnoc_cmds_addrs[0] = 0x50034;
311
+ msg->cnoc_cmds_addrs[1] = 0x5007c;
312
+ msg->cnoc_cmds_addrs[2] = 0x5004c;
313
+
314
+ msg->cnoc_cmds_data[0][0] = 0x40000000;
315
+ msg->cnoc_cmds_data[0][1] = 0x00000000;
316
+ msg->cnoc_cmds_data[0][2] = 0x40000000;
317
+
318
+ msg->cnoc_cmds_data[1][0] = 0x60000001;
319
+ msg->cnoc_cmds_data[1][1] = 0x20000001;
320
+ msg->cnoc_cmds_data[1][2] = 0x60000001;
321
+}
322
+
323
+static void a650_build_bw_table(struct a6xx_hfi_msg_bw_table *msg)
324
+{
325
+ /*
326
+ * Send a single "off" entry just to get things running
327
+ * TODO: bus scaling
328
+ */
329
+ msg->bw_level_num = 1;
330
+
331
+ msg->ddr_cmds_num = 3;
332
+ msg->ddr_wait_bitmask = 0x01;
333
+
334
+ msg->ddr_cmds_addrs[0] = 0x50000;
335
+ msg->ddr_cmds_addrs[1] = 0x50004;
336
+ msg->ddr_cmds_addrs[2] = 0x5007c;
337
+
338
+ msg->ddr_cmds_data[0][0] = 0x40000000;
339
+ msg->ddr_cmds_data[0][1] = 0x40000000;
340
+ msg->ddr_cmds_data[0][2] = 0x40000000;
341
+
342
+ /*
343
+ * These are the CX (CNOC) votes - these are used by the GMU but the
344
+ * votes are known and fixed for the target
345
+ */
346
+ msg->cnoc_cmds_num = 1;
347
+ msg->cnoc_wait_bitmask = 0x01;
348
+
349
+ msg->cnoc_cmds_addrs[0] = 0x500a4;
350
+ msg->cnoc_cmds_data[0][0] = 0x40000000;
351
+ msg->cnoc_cmds_data[1][0] = 0x60000001;
352
+}
353
+
354
+static void a6xx_build_bw_table(struct a6xx_hfi_msg_bw_table *msg)
355
+{
356
+ /* Send a single "off" entry since the 630 GMU doesn't do bus scaling */
357
+ msg->bw_level_num = 1;
358
+
359
+ msg->ddr_cmds_num = 3;
360
+ msg->ddr_wait_bitmask = 0x07;
361
+
362
+ msg->ddr_cmds_addrs[0] = 0x50000;
363
+ msg->ddr_cmds_addrs[1] = 0x5005c;
364
+ msg->ddr_cmds_addrs[2] = 0x5000c;
365
+
366
+ msg->ddr_cmds_data[0][0] = 0x40000000;
367
+ msg->ddr_cmds_data[0][1] = 0x40000000;
368
+ msg->ddr_cmds_data[0][2] = 0x40000000;
292369
293370 /*
294371 * These are the CX (CNOC) votes. This is used but the values for the
295372 * sdm845 GMU are known and fixed so we can hard code them.
296373 */
297374
298
- msg.cnoc_cmds_num = 3;
299
- msg.cnoc_wait_bitmask = 0x05;
375
+ msg->cnoc_cmds_num = 3;
376
+ msg->cnoc_wait_bitmask = 0x05;
300377
301
- msg.cnoc_cmds_addrs[0] = 0x50034;
302
- msg.cnoc_cmds_addrs[1] = 0x5007c;
303
- msg.cnoc_cmds_addrs[2] = 0x5004c;
378
+ msg->cnoc_cmds_addrs[0] = 0x50034;
379
+ msg->cnoc_cmds_addrs[1] = 0x5007c;
380
+ msg->cnoc_cmds_addrs[2] = 0x5004c;
304381
305
- msg.cnoc_cmds_data[0][0] = 0x40000000;
306
- msg.cnoc_cmds_data[0][1] = 0x00000000;
307
- msg.cnoc_cmds_data[0][2] = 0x40000000;
382
+ msg->cnoc_cmds_data[0][0] = 0x40000000;
383
+ msg->cnoc_cmds_data[0][1] = 0x00000000;
384
+ msg->cnoc_cmds_data[0][2] = 0x40000000;
308385
309
- msg.cnoc_cmds_data[1][0] = 0x60000001;
310
- msg.cnoc_cmds_data[1][1] = 0x20000001;
311
- msg.cnoc_cmds_data[1][2] = 0x60000001;
386
+ msg->cnoc_cmds_data[1][0] = 0x60000001;
387
+ msg->cnoc_cmds_data[1][1] = 0x20000001;
388
+ msg->cnoc_cmds_data[1][2] = 0x60000001;
389
+}
390
+
391
+
392
+static int a6xx_hfi_send_bw_table(struct a6xx_gmu *gmu)
393
+{
394
+ struct a6xx_hfi_msg_bw_table msg = { 0 };
395
+ struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
396
+ struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
397
+
398
+ if (adreno_is_a618(adreno_gpu))
399
+ a618_build_bw_table(&msg);
400
+ else if (adreno_is_a640(adreno_gpu))
401
+ a640_build_bw_table(&msg);
402
+ else if (adreno_is_a650(adreno_gpu))
403
+ a650_build_bw_table(&msg);
404
+ else
405
+ a6xx_build_bw_table(&msg);
312406
313407 return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_BW_TABLE, &msg, sizeof(msg),
314408 NULL, 0);
....@@ -322,7 +416,45 @@
322416 NULL, 0);
323417 }
324418
325
-int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state)
419
+static int a6xx_hfi_send_start(struct a6xx_gmu *gmu)
420
+{
421
+ struct a6xx_hfi_msg_start msg = { 0 };
422
+
423
+ return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_START, &msg, sizeof(msg),
424
+ NULL, 0);
425
+}
426
+
427
+static int a6xx_hfi_send_core_fw_start(struct a6xx_gmu *gmu)
428
+{
429
+ struct a6xx_hfi_msg_core_fw_start msg = { 0 };
430
+
431
+ return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_CORE_FW_START, &msg,
432
+ sizeof(msg), NULL, 0);
433
+}
434
+
435
+int a6xx_hfi_set_freq(struct a6xx_gmu *gmu, int index)
436
+{
437
+ struct a6xx_hfi_gx_bw_perf_vote_cmd msg = { 0 };
438
+
439
+ msg.ack_type = 1; /* blocking */
440
+ msg.freq = index;
441
+ msg.bw = 0; /* TODO: bus scaling */
442
+
443
+ return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_GX_BW_PERF_VOTE, &msg,
444
+ sizeof(msg), NULL, 0);
445
+}
446
+
447
+int a6xx_hfi_send_prep_slumber(struct a6xx_gmu *gmu)
448
+{
449
+ struct a6xx_hfi_prep_slumber_cmd msg = { 0 };
450
+
451
+ /* TODO: should freq and bw fields be non-zero ? */
452
+
453
+ return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_PREPARE_SLUMBER, &msg,
454
+ sizeof(msg), NULL, 0);
455
+}
456
+
457
+static int a6xx_hfi_start_v1(struct a6xx_gmu *gmu, int boot_state)
326458 {
327459 int ret;
328460
....@@ -340,7 +472,7 @@
340472 * the GMU firmware
341473 */
342474
343
- ret = a6xx_hfi_send_perf_table(gmu);
475
+ ret = a6xx_hfi_send_perf_table_v1(gmu);
344476 if (ret)
345477 return ret;
346478
....@@ -357,6 +489,37 @@
357489 return 0;
358490 }
359491
492
+int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state)
493
+{
494
+ int ret;
495
+
496
+ if (gmu->legacy)
497
+ return a6xx_hfi_start_v1(gmu, boot_state);
498
+
499
+
500
+ ret = a6xx_hfi_send_perf_table(gmu);
501
+ if (ret)
502
+ return ret;
503
+
504
+ ret = a6xx_hfi_send_bw_table(gmu);
505
+ if (ret)
506
+ return ret;
507
+
508
+ ret = a6xx_hfi_send_core_fw_start(gmu);
509
+ if (ret)
510
+ return ret;
511
+
512
+ /*
513
+ * Downstream driver sends this in its "a6xx_hw_init" equivalent,
514
+ * but seems to be no harm in sending it here
515
+ */
516
+ ret = a6xx_hfi_send_start(gmu);
517
+ if (ret)
518
+ return ret;
519
+
520
+ return 0;
521
+}
522
+
360523 void a6xx_hfi_stop(struct a6xx_gmu *gmu)
361524 {
362525 int i;
....@@ -368,7 +531,7 @@
368531 continue;
369532
370533 if (queue->header->read_index != queue->header->write_index)
371
- dev_err(gmu->dev, "HFI queue %d is not empty\n", i);
534
+ DRM_DEV_ERROR(gmu->dev, "HFI queue %d is not empty\n", i);
372535
373536 queue->header->read_index = 0;
374537 queue->header->write_index = 0;
....@@ -401,7 +564,7 @@
401564
402565 void a6xx_hfi_init(struct a6xx_gmu *gmu)
403566 {
404
- struct a6xx_gmu_bo *hfi = gmu->hfi;
567
+ struct a6xx_gmu_bo *hfi = &gmu->hfi;
405568 struct a6xx_hfi_queue_table_header *table = hfi->virt;
406569 struct a6xx_hfi_queue_header *headers = hfi->virt + sizeof(*table);
407570 u64 offset;
....@@ -431,5 +594,5 @@
431594 /* GMU response queue */
432595 offset += SZ_4K;
433596 a6xx_hfi_queue_init(&gmu->queues[1], &headers[1], hfi->virt + offset,
434
- hfi->iova + offset, 4);
597
+ hfi->iova + offset, gmu->legacy ? 4 : 1);
435598 }