1616#include "xe_late_bind_fw.h"
1717#include "xe_pcode.h"
1818#include "xe_pcode_api.h"
19+ #include "xe_pm.h"
20+
21+ /*
22+ * The component should load quite quickly in most cases, but it could take
23+ * a bit. Using a very big timeout just to cover the worst case scenario
24+ */
25+ #define LB_INIT_TIMEOUT_MS 20000
26+
27+ /*
28+ * Retry interval set to 6 seconds, in steps of 200 ms, to allow time for
29+ * other OS components to release the MEI CL handle
30+ */
31+ #define LB_FW_LOAD_RETRY_MAXCOUNT 30
32+ #define LB_FW_LOAD_RETRY_PAUSE_MS 200
1933
2034static const u32 fw_id_to_type [] = {
2135 [XE_LB_FW_FAN_CONTROL ] = INTEL_LB_TYPE_FAN_CONTROL ,
@@ -31,6 +45,30 @@ late_bind_to_xe(struct xe_late_bind *late_bind)
3145 return container_of (late_bind , struct xe_device , late_bind );
3246}
3347
48+ static const char * xe_late_bind_parse_status (uint32_t status )
49+ {
50+ switch (status ) {
51+ case INTEL_LB_STATUS_SUCCESS :
52+ return "success" ;
53+ case INTEL_LB_STATUS_4ID_MISMATCH :
54+ return "4Id Mismatch" ;
55+ case INTEL_LB_STATUS_ARB_FAILURE :
56+ return "ARB Failure" ;
57+ case INTEL_LB_STATUS_GENERAL_ERROR :
58+ return "General Error" ;
59+ case INTEL_LB_STATUS_INVALID_PARAMS :
60+ return "Invalid Params" ;
61+ case INTEL_LB_STATUS_INVALID_SIGNATURE :
62+ return "Invalid Signature" ;
63+ case INTEL_LB_STATUS_INVALID_PAYLOAD :
64+ return "Invalid Payload" ;
65+ case INTEL_LB_STATUS_TIMEOUT :
66+ return "Timeout" ;
67+ default :
68+ return "Unknown error" ;
69+ }
70+ }
71+
3472static int xe_late_bind_fw_num_fans (struct xe_late_bind * late_bind )
3573{
3674 struct xe_device * xe = late_bind_to_xe (late_bind );
@@ -44,6 +82,101 @@ static int xe_late_bind_fw_num_fans(struct xe_late_bind *late_bind)
4482 return 0 ;
4583}
4684
85+ static void xe_late_bind_wait_for_worker_completion (struct xe_late_bind * late_bind )
86+ {
87+ struct xe_device * xe = late_bind_to_xe (late_bind );
88+ struct xe_late_bind_fw * lbfw ;
89+ int fw_id ;
90+
91+ for (fw_id = 0 ; fw_id < XE_LB_FW_MAX_ID ; fw_id ++ ) {
92+ lbfw = & late_bind -> late_bind_fw [fw_id ];
93+ if (lbfw -> payload && late_bind -> wq ) {
94+ drm_dbg (& xe -> drm , "Flush work: load %s firmware\n" ,
95+ fw_id_to_name [lbfw -> id ]);
96+ flush_work (& lbfw -> work );
97+ }
98+ }
99+ }
100+
101+ static void xe_late_bind_work (struct work_struct * work )
102+ {
103+ struct xe_late_bind_fw * lbfw = container_of (work , struct xe_late_bind_fw , work );
104+ struct xe_late_bind * late_bind = container_of (lbfw , struct xe_late_bind ,
105+ late_bind_fw [lbfw -> id ]);
106+ struct xe_device * xe = late_bind_to_xe (late_bind );
107+ int retry = LB_FW_LOAD_RETRY_MAXCOUNT ;
108+ int ret ;
109+ int slept ;
110+
111+ xe_device_assert_mem_access (xe );
112+
113+ /* we can queue this before the component is bound */
114+ for (slept = 0 ; slept < LB_INIT_TIMEOUT_MS ; slept += 100 ) {
115+ if (late_bind -> component .ops )
116+ break ;
117+ msleep (100 );
118+ }
119+
120+ if (!late_bind -> component .ops ) {
121+ drm_err (& xe -> drm , "Late bind component not bound\n" );
122+ /* Do not re-attempt fw load */
123+ drmm_kfree (& xe -> drm , (void * )lbfw -> payload );
124+ lbfw -> payload = NULL ;
125+ goto out ;
126+ }
127+
128+ drm_dbg (& xe -> drm , "Load %s firmware\n" , fw_id_to_name [lbfw -> id ]);
129+
130+ do {
131+ ret = late_bind -> component .ops -> push_payload (late_bind -> component .mei_dev ,
132+ lbfw -> type ,
133+ lbfw -> flags ,
134+ lbfw -> payload ,
135+ lbfw -> payload_size );
136+ if (!ret )
137+ break ;
138+ msleep (LB_FW_LOAD_RETRY_PAUSE_MS );
139+ } while (-- retry && ret == - EBUSY );
140+
141+ if (!ret ) {
142+ drm_dbg (& xe -> drm , "Load %s firmware successful\n" ,
143+ fw_id_to_name [lbfw -> id ]);
144+ goto out ;
145+ }
146+
147+ if (ret > 0 )
148+ drm_err (& xe -> drm , "Load %s firmware failed with err %d, %s\n" ,
149+ fw_id_to_name [lbfw -> id ], ret , xe_late_bind_parse_status (ret ));
150+ else
151+ drm_err (& xe -> drm , "Load %s firmware failed with err %d" ,
152+ fw_id_to_name [lbfw -> id ], ret );
153+ /* Do not re-attempt fw load */
154+ drmm_kfree (& xe -> drm , (void * )lbfw -> payload );
155+ lbfw -> payload = NULL ;
156+
157+ out :
158+ xe_pm_runtime_put (xe );
159+ }
160+
161+ int xe_late_bind_fw_load (struct xe_late_bind * late_bind )
162+ {
163+ struct xe_device * xe = late_bind_to_xe (late_bind );
164+ struct xe_late_bind_fw * lbfw ;
165+ int fw_id ;
166+
167+ if (!late_bind -> component_added )
168+ return - ENODEV ;
169+
170+ for (fw_id = 0 ; fw_id < XE_LB_FW_MAX_ID ; fw_id ++ ) {
171+ lbfw = & late_bind -> late_bind_fw [fw_id ];
172+ if (lbfw -> payload ) {
173+ xe_pm_runtime_get_noresume (xe );
174+ queue_work (late_bind -> wq , & lbfw -> work );
175+ }
176+ }
177+ return 0 ;
178+ }
179+
47180static int __xe_late_bind_fw_init (struct xe_late_bind * late_bind , u32 fw_id )
48181{
49182 struct xe_device * xe = late_bind_to_xe (late_bind );
@@ -97,6 +230,7 @@ static int __xe_late_bind_fw_init(struct xe_late_bind *late_bind, u32 fw_id)
97230
98231 memcpy ((void * )lb_fw -> payload , fw -> data , lb_fw -> payload_size );
99232 release_firmware (fw );
233+ INIT_WORK (& lb_fw -> work , xe_late_bind_work );
100234
101235 return 0 ;
102236}
@@ -106,11 +240,16 @@ static int xe_late_bind_fw_init(struct xe_late_bind *late_bind)
106240 int ret ;
107241 int fw_id ;
108242
243+ late_bind -> wq = alloc_ordered_workqueue ("late-bind-ordered-wq" , 0 );
244+ if (!late_bind -> wq )
245+ return - ENOMEM ;
246+
109247 for (fw_id = 0 ; fw_id < XE_LB_FW_MAX_ID ; fw_id ++ ) {
110248 ret = __xe_late_bind_fw_init (late_bind , fw_id );
111249 if (ret )
112250 return ret ;
113251 }
252+
114253 return 0 ;
115254}
116255
@@ -132,6 +271,8 @@ static void xe_late_bind_component_unbind(struct device *xe_kdev,
132271 struct xe_device * xe = kdev_to_xe_device (xe_kdev );
133272 struct xe_late_bind * late_bind = & xe -> late_bind ;
134273
274+ xe_late_bind_wait_for_worker_completion (late_bind );
275+
135276 late_bind -> component .ops = NULL ;
136277}
137278
@@ -145,7 +286,15 @@ static void xe_late_bind_remove(void *arg)
145286 struct xe_late_bind * late_bind = arg ;
146287 struct xe_device * xe = late_bind_to_xe (late_bind );
147288
289+ xe_late_bind_wait_for_worker_completion (late_bind );
290+
291+ late_bind -> component_added = false;
292+
148293 component_del (xe -> drm .dev , & xe_late_bind_component_ops );
294+ if (late_bind -> wq ) {
295+ destroy_workqueue (late_bind -> wq );
296+ late_bind -> wq = NULL ;
297+ }
149298}
150299
151300/**
@@ -174,9 +323,15 @@ int xe_late_bind_init(struct xe_late_bind *late_bind)
174323 return err ;
175324 }
176325
326+ late_bind -> component_added = true;
327+
177328 err = devm_add_action_or_reset (xe -> drm .dev , xe_late_bind_remove , late_bind );
178329 if (err )
179330 return err ;
180331
181- return xe_late_bind_fw_init (late_bind );
332+ err = xe_late_bind_fw_init (late_bind );
333+ if (err )
334+ return err ;
335+
336+ return xe_late_bind_fw_load (late_bind );
182337}
0 commit comments