Skip to content

Commit 933fd5f

Browse files
rtauro1895rodrigovivi
authored andcommitted
drm/xe: check pcode init status only on root gt of root tile
The root tile indicates the pcode initialization is complete when all tiles have completed their initialization. So the mailbox can be polled only on the root tile. Check pcode init status only on root tile and move it to device probe early as root tile is initialized there. Also make similar changes in resume paths. v2: add lock/unlocked version of pcode_mailbox_rw to allow pcode init to be called in device early probe (Rodrigo) v3: add code description about using root tile change function names to xe_pcode_probe_early and xe_pcode_init (Rodrigo) Signed-off-by: Riana Tauro <riana.tauro@intel.com> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Reviewed-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240410085005.1126343-2-riana.tauro@intel.com Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
1 parent 3df49b2 commit 933fd5f

File tree

4 files changed

+94
-64
lines changed

4 files changed

+94
-64
lines changed

drivers/gpu/drm/xe/xe_device.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -422,8 +422,14 @@ static int xe_set_dma_info(struct xe_device *xe)
422422
return err;
423423
}
424424

425-
/*
426-
* Initialize MMIO resources that don't require any knowledge about tile count.
425+
/**
426+
* xe_device_probe_early: Device early probe
427+
* @xe: xe device instance
428+
*
429+
* Initialize MMIO resources that don't require any
430+
* knowledge about tile count. Also initialize pcode
431+
*
432+
* Return: 0 on success, error code on failure
427433
*/
428434
int xe_device_probe_early(struct xe_device *xe)
429435
{
@@ -439,6 +445,10 @@ int xe_device_probe_early(struct xe_device *xe)
439445
if (err)
440446
return err;
441447

448+
err = xe_pcode_probe_early(xe);
449+
if (err)
450+
return err;
451+
442452
return 0;
443453
}
444454

@@ -517,11 +527,8 @@ int xe_device_probe(struct xe_device *xe)
517527
if (err)
518528
return err;
519529

520-
for_each_gt(gt, xe, id) {
521-
err = xe_pcode_probe(gt);
522-
if (err)
523-
return err;
524-
}
530+
for_each_gt(gt, xe, id)
531+
xe_pcode_init(gt);
525532

526533
err = xe_display_init_noirq(xe);
527534
if (err)

drivers/gpu/drm/xe/xe_pcode.c

Lines changed: 70 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <drm/drm_managed.h>
1212

13+
#include "xe_device.h"
1314
#include "xe_gt.h"
1415
#include "xe_mmio.h"
1516
#include "xe_pcode_api.h"
@@ -43,8 +44,6 @@ static int pcode_mailbox_status(struct xe_gt *gt)
4344
[PCODE_ERROR_MASK] = {-EPROTO, "Unknown"},
4445
};
4546

46-
lockdep_assert_held(&gt->pcode.lock);
47-
4847
err = xe_mmio_read32(gt, PCODE_MAILBOX) & PCODE_ERROR_MASK;
4948
if (err) {
5049
drm_err(&gt_to_xe(gt)->drm, "PCODE Mailbox failed: %d %s", err,
@@ -55,17 +54,15 @@ static int pcode_mailbox_status(struct xe_gt *gt)
5554
return 0;
5655
}
5756

58-
static int pcode_mailbox_rw(struct xe_gt *gt, u32 mbox, u32 *data0, u32 *data1,
59-
unsigned int timeout_ms, bool return_data,
60-
bool atomic)
57+
static int __pcode_mailbox_rw(struct xe_gt *gt, u32 mbox, u32 *data0, u32 *data1,
58+
unsigned int timeout_ms, bool return_data,
59+
bool atomic)
6160
{
6261
int err;
6362

6463
if (gt_to_xe(gt)->info.skip_pcode)
6564
return 0;
6665

67-
lockdep_assert_held(&gt->pcode.lock);
68-
6966
if ((xe_mmio_read32(gt, PCODE_MAILBOX) & PCODE_READY) != 0)
7067
return -EAGAIN;
7168

@@ -87,6 +84,18 @@ static int pcode_mailbox_rw(struct xe_gt *gt, u32 mbox, u32 *data0, u32 *data1,
8784
return pcode_mailbox_status(gt);
8885
}
8986

87+
static int pcode_mailbox_rw(struct xe_gt *gt, u32 mbox, u32 *data0, u32 *data1,
88+
unsigned int timeout_ms, bool return_data,
89+
bool atomic)
90+
{
91+
if (gt_to_xe(gt)->info.skip_pcode)
92+
return 0;
93+
94+
lockdep_assert_held(&gt->pcode.lock);
95+
96+
return __pcode_mailbox_rw(gt, mbox, data0, data1, timeout_ms, return_data, atomic);
97+
}
98+
9099
int xe_pcode_write_timeout(struct xe_gt *gt, u32 mbox, u32 data, int timeout)
91100
{
92101
int err;
@@ -109,15 +118,19 @@ int xe_pcode_read(struct xe_gt *gt, u32 mbox, u32 *val, u32 *val1)
109118
return err;
110119
}
111120

112-
static int xe_pcode_try_request(struct xe_gt *gt, u32 mbox,
113-
u32 request, u32 reply_mask, u32 reply,
114-
u32 *status, bool atomic, int timeout_us)
121+
static int pcode_try_request(struct xe_gt *gt, u32 mbox,
122+
u32 request, u32 reply_mask, u32 reply,
123+
u32 *status, bool atomic, int timeout_us, bool locked)
115124
{
116125
int slept, wait = 10;
117126

118127
for (slept = 0; slept < timeout_us; slept += wait) {
119-
*status = pcode_mailbox_rw(gt, mbox, &request, NULL, 1, true,
120-
atomic);
128+
if (locked)
129+
*status = pcode_mailbox_rw(gt, mbox, &request, NULL, 1, true,
130+
atomic);
131+
else
132+
*status = __pcode_mailbox_rw(gt, mbox, &request, NULL, 1, true,
133+
atomic);
121134
if ((*status == 0) && ((request & reply_mask) == reply))
122135
return 0;
123136

@@ -158,8 +171,8 @@ int xe_pcode_request(struct xe_gt *gt, u32 mbox, u32 request,
158171

159172
mutex_lock(&gt->pcode.lock);
160173

161-
ret = xe_pcode_try_request(gt, mbox, request, reply_mask, reply, &status,
162-
false, timeout_base_ms * 1000);
174+
ret = pcode_try_request(gt, mbox, request, reply_mask, reply, &status,
175+
false, timeout_base_ms * 1000, true);
163176
if (!ret)
164177
goto out;
165178

@@ -177,8 +190,8 @@ int xe_pcode_request(struct xe_gt *gt, u32 mbox, u32 request,
177190
"PCODE timeout, retrying with preemption disabled\n");
178191
drm_WARN_ON_ONCE(&gt_to_xe(gt)->drm, timeout_base_ms > 1);
179192
preempt_disable();
180-
ret = xe_pcode_try_request(gt, mbox, request, reply_mask, reply, &status,
181-
true, timeout_base_ms * 1000);
193+
ret = pcode_try_request(gt, mbox, request, reply_mask, reply, &status,
194+
true, timeout_base_ms * 1000, true);
182195
preempt_enable();
183196

184197
out:
@@ -238,59 +251,71 @@ int xe_pcode_init_min_freq_table(struct xe_gt *gt, u32 min_gt_freq,
238251
}
239252

240253
/**
241-
* xe_pcode_init - Ensure PCODE is initialized
242-
* @gt: gt instance
254+
* xe_pcode_ready - Ensure PCODE is initialized
255+
* @xe: xe instance
256+
* @locked: true if lock held, false otherwise
243257
*
244-
* This function ensures that PCODE is properly initialized. To be called during
245-
* probe and resume paths.
258+
* PCODE init mailbox is polled only on root gt of root tile
259+
* as the root tile provides the initialization is complete only
260+
* after all the tiles have completed the initialization.
261+
* Called only on early probe without locks and with locks in
262+
* resume path.
246263
*
247-
* It returns 0 on success, and -error number on failure.
264+
* Returns 0 on success, and -error number on failure.
248265
*/
249-
int xe_pcode_init(struct xe_gt *gt)
266+
int xe_pcode_ready(struct xe_device *xe, bool locked)
250267
{
251268
u32 status, request = DGFX_GET_INIT_STATUS;
269+
struct xe_gt *gt = xe_root_mmio_gt(xe);
252270
int timeout_us = 180000000; /* 3 min */
253271
int ret;
254272

255-
if (gt_to_xe(gt)->info.skip_pcode)
273+
if (xe->info.skip_pcode)
256274
return 0;
257275

258-
if (!IS_DGFX(gt_to_xe(gt)))
276+
if (!IS_DGFX(xe))
259277
return 0;
260278

261-
mutex_lock(&gt->pcode.lock);
262-
ret = xe_pcode_try_request(gt, DGFX_PCODE_STATUS, request,
263-
DGFX_INIT_STATUS_COMPLETE,
264-
DGFX_INIT_STATUS_COMPLETE,
265-
&status, false, timeout_us);
266-
mutex_unlock(&gt->pcode.lock);
279+
if (locked)
280+
mutex_lock(&gt->pcode.lock);
281+
282+
ret = pcode_try_request(gt, DGFX_PCODE_STATUS, request,
283+
DGFX_INIT_STATUS_COMPLETE,
284+
DGFX_INIT_STATUS_COMPLETE,
285+
&status, false, timeout_us, locked);
286+
287+
if (locked)
288+
mutex_unlock(&gt->pcode.lock);
267289

268290
if (ret)
269-
drm_err(&gt_to_xe(gt)->drm,
291+
drm_err(&xe->drm,
270292
"PCODE initialization timedout after: 3 min\n");
271293

272294
return ret;
273295
}
274296

275297
/**
276-
* xe_pcode_probe - Prepare xe_pcode and also ensure PCODE is initialized.
298+
* xe_pcode_init: initialize components of PCODE
277299
* @gt: gt instance
278300
*
279-
* This function initializes the xe_pcode component, and when needed, it ensures
280-
* that PCODE has properly performed its initialization and it is really ready
281-
* to go. To be called once only during probe.
282-
*
283-
* It returns 0 on success, and -error number on failure.
301+
* This function initializes the xe_pcode component.
302+
* To be called once only during probe.
284303
*/
285-
int xe_pcode_probe(struct xe_gt *gt)
304+
void xe_pcode_init(struct xe_gt *gt)
286305
{
287306
drmm_mutex_init(&gt_to_xe(gt)->drm, &gt->pcode.lock);
307+
}
288308

289-
if (gt_to_xe(gt)->info.skip_pcode)
290-
return 0;
291-
292-
if (!IS_DGFX(gt_to_xe(gt)))
293-
return 0;
294-
295-
return xe_pcode_init(gt);
309+
/**
310+
* xe_pcode_probe_early: initializes PCODE
311+
* @xe: xe instance
312+
*
313+
* This function checks the initialization status of PCODE
314+
* To be called once only during early probe without locks.
315+
*
316+
* Returns 0 on success, error code otherwise
317+
*/
318+
int xe_pcode_probe_early(struct xe_device *xe)
319+
{
320+
return xe_pcode_ready(xe, false);
296321
}

drivers/gpu/drm/xe/xe_pcode.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88

99
#include <linux/types.h>
1010
struct xe_gt;
11+
struct xe_device;
1112

12-
int xe_pcode_probe(struct xe_gt *gt);
13-
int xe_pcode_init(struct xe_gt *gt);
13+
void xe_pcode_init(struct xe_gt *gt);
14+
int xe_pcode_probe_early(struct xe_device *xe);
15+
int xe_pcode_ready(struct xe_device *xe, bool locked);
1416
int xe_pcode_init_min_freq_table(struct xe_gt *gt, u32 min_gt_freq,
1517
u32 max_gt_freq);
1618
int xe_pcode_read(struct xe_gt *gt, u32 mbox, u32 *val, u32 *val1);

drivers/gpu/drm/xe/xe_pm.c

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,9 @@ int xe_pm_resume(struct xe_device *xe)
129129
for_each_tile(tile, xe, id)
130130
xe_wa_apply_tile_workarounds(tile);
131131

132-
for_each_gt(gt, xe, id) {
133-
err = xe_pcode_init(gt);
134-
if (err)
135-
goto err;
136-
}
132+
err = xe_pcode_ready(xe, true);
133+
if (err)
134+
return err;
137135

138136
xe_display_pm_resume_early(xe);
139137

@@ -386,11 +384,9 @@ int xe_pm_runtime_resume(struct xe_device *xe)
386384
xe->d3cold.power_lost = xe_guc_in_reset(&gt->uc.guc);
387385

388386
if (xe->d3cold.allowed && xe->d3cold.power_lost) {
389-
for_each_gt(gt, xe, id) {
390-
err = xe_pcode_init(gt);
391-
if (err)
392-
goto out;
393-
}
387+
err = xe_pcode_ready(xe, true);
388+
if (err)
389+
goto out;
394390

395391
/*
396392
* This only restores pinned memory which is the memory

0 commit comments

Comments
 (0)