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+
9099int 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
184197out :
@@ -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}
0 commit comments