14
14
#include <drm/drm_ioctl.h>
15
15
#include <drm/drm_prime.h>
16
16
17
+ #include "vpu_boot_api.h"
17
18
#include "ivpu_drv.h"
19
+ #include "ivpu_fw.h"
18
20
#include "ivpu_gem.h"
19
21
#include "ivpu_hw.h"
20
22
#include "ivpu_ipc.h"
23
+ #include "ivpu_jsm_msg.h"
21
24
#include "ivpu_mmu.h"
22
25
#include "ivpu_mmu_context.h"
23
26
@@ -32,6 +35,10 @@ int ivpu_dbg_mask;
32
35
module_param_named (dbg_mask , ivpu_dbg_mask , int , 0644 );
33
36
MODULE_PARM_DESC (dbg_mask , "Driver debug mask. See IVPU_DBG_* macros." );
34
37
38
+ int ivpu_test_mode ;
39
+ module_param_named_unsafe (test_mode , ivpu_test_mode , int , 0644 );
40
+ MODULE_PARM_DESC (test_mode , "Test mode: 0 - normal operation, 1 - fw unit test, 2 - null hw" );
41
+
35
42
u8 ivpu_pll_min_ratio ;
36
43
module_param_named (pll_min_ratio , ivpu_pll_min_ratio , byte , 0644 );
37
44
MODULE_PARM_DESC (pll_min_ratio , "Minimum PLL ratio used to set VPU frequency" );
@@ -129,6 +136,28 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f
129
136
case DRM_IVPU_PARAM_CONTEXT_ID :
130
137
args -> value = file_priv -> ctx .id ;
131
138
break ;
139
+ case DRM_IVPU_PARAM_FW_API_VERSION :
140
+ if (args -> index < VPU_FW_API_VER_NUM ) {
141
+ struct vpu_firmware_header * fw_hdr ;
142
+
143
+ fw_hdr = (struct vpu_firmware_header * )vdev -> fw -> file -> data ;
144
+ args -> value = fw_hdr -> api_version [args -> index ];
145
+ } else {
146
+ ret = - EINVAL ;
147
+ }
148
+ break ;
149
+ case DRM_IVPU_PARAM_ENGINE_HEARTBEAT :
150
+ ret = ivpu_jsm_get_heartbeat (vdev , args -> index , & args -> value );
151
+ break ;
152
+ case DRM_IVPU_PARAM_UNIQUE_INFERENCE_ID :
153
+ args -> value = (u64 )atomic64_inc_return (& vdev -> unique_id_counter );
154
+ break ;
155
+ case DRM_IVPU_PARAM_TILE_CONFIG :
156
+ args -> value = vdev -> hw -> tile_fuse ;
157
+ break ;
158
+ case DRM_IVPU_PARAM_SKU :
159
+ args -> value = vdev -> hw -> sku ;
160
+ break ;
132
161
default :
133
162
ret = - EINVAL ;
134
163
break ;
@@ -225,11 +254,85 @@ static const struct drm_ioctl_desc ivpu_drm_ioctls[] = {
225
254
DRM_IOCTL_DEF_DRV (IVPU_BO_INFO , ivpu_bo_info_ioctl , 0 ),
226
255
};
227
256
257
+ static int ivpu_wait_for_ready (struct ivpu_device * vdev )
258
+ {
259
+ struct ivpu_ipc_consumer cons ;
260
+ struct ivpu_ipc_hdr ipc_hdr ;
261
+ unsigned long timeout ;
262
+ int ret ;
263
+
264
+ if (ivpu_test_mode == IVPU_TEST_MODE_FW_TEST )
265
+ return 0 ;
266
+
267
+ ivpu_ipc_consumer_add (vdev , & cons , IVPU_IPC_CHAN_BOOT_MSG );
268
+
269
+ timeout = jiffies + msecs_to_jiffies (vdev -> timeout .boot );
270
+ while (1 ) {
271
+ ret = ivpu_ipc_irq_handler (vdev );
272
+ if (ret )
273
+ break ;
274
+ ret = ivpu_ipc_receive (vdev , & cons , & ipc_hdr , NULL , 0 );
275
+ if (ret != - ETIMEDOUT || time_after_eq (jiffies , timeout ))
276
+ break ;
277
+
278
+ cond_resched ();
279
+ }
280
+
281
+ ivpu_ipc_consumer_del (vdev , & cons );
282
+
283
+ if (!ret && ipc_hdr .data_addr != IVPU_IPC_BOOT_MSG_DATA_ADDR ) {
284
+ ivpu_err (vdev , "Invalid VPU ready message: 0x%x\n" ,
285
+ ipc_hdr .data_addr );
286
+ return - EIO ;
287
+ }
288
+
289
+ if (!ret )
290
+ ivpu_info (vdev , "VPU ready message received successfully\n" );
291
+ else
292
+ ivpu_hw_diagnose_failure (vdev );
293
+
294
+ return ret ;
295
+ }
296
+
297
+ /**
298
+ * ivpu_boot() - Start VPU firmware
299
+ * @vdev: VPU device
300
+ *
301
+ * This function is paired with ivpu_shutdown() but it doesn't power up the
302
+ * VPU because power up has to be called very early in ivpu_probe().
303
+ */
304
+ int ivpu_boot (struct ivpu_device * vdev )
305
+ {
306
+ int ret ;
307
+
308
+ /* Update boot params located at first 4KB of FW memory */
309
+ ivpu_fw_boot_params_setup (vdev , vdev -> fw -> mem -> kvaddr );
310
+
311
+ ret = ivpu_hw_boot_fw (vdev );
312
+ if (ret ) {
313
+ ivpu_err (vdev , "Failed to start the firmware: %d\n" , ret );
314
+ return ret ;
315
+ }
316
+
317
+ ret = ivpu_wait_for_ready (vdev );
318
+ if (ret ) {
319
+ ivpu_err (vdev , "Failed to boot the firmware: %d\n" , ret );
320
+ return ret ;
321
+ }
322
+
323
+ ivpu_hw_irq_clear (vdev );
324
+ enable_irq (vdev -> irq );
325
+ ivpu_hw_irq_enable (vdev );
326
+ ivpu_ipc_enable (vdev );
327
+ return 0 ;
328
+ }
329
+
228
330
int ivpu_shutdown (struct ivpu_device * vdev )
229
331
{
230
332
int ret ;
231
333
232
334
ivpu_hw_irq_disable (vdev );
335
+ disable_irq (vdev -> irq );
233
336
ivpu_ipc_disable (vdev );
234
337
ivpu_mmu_disable (vdev );
235
338
@@ -341,6 +444,10 @@ static int ivpu_dev_init(struct ivpu_device *vdev)
341
444
if (!vdev -> mmu )
342
445
return - ENOMEM ;
343
446
447
+ vdev -> fw = drmm_kzalloc (& vdev -> drm , sizeof (* vdev -> fw ), GFP_KERNEL );
448
+ if (!vdev -> fw )
449
+ return - ENOMEM ;
450
+
344
451
vdev -> ipc = drmm_kzalloc (& vdev -> drm , sizeof (* vdev -> ipc ), GFP_KERNEL );
345
452
if (!vdev -> ipc )
346
453
return - ENOMEM ;
@@ -349,6 +456,7 @@ static int ivpu_dev_init(struct ivpu_device *vdev)
349
456
vdev -> platform = IVPU_PLATFORM_INVALID ;
350
457
vdev -> context_xa_limit .min = IVPU_GLOBAL_CONTEXT_MMU_SSID + 1 ;
351
458
vdev -> context_xa_limit .max = IVPU_CONTEXT_LIMIT ;
459
+ atomic64_set (& vdev -> unique_id_counter , 0 );
352
460
xa_init_flags (& vdev -> context_xa , XA_FLAGS_ALLOC );
353
461
354
462
ret = ivpu_pci_init (vdev );
@@ -389,14 +497,34 @@ static int ivpu_dev_init(struct ivpu_device *vdev)
389
497
goto err_mmu_gctx_fini ;
390
498
}
391
499
500
+ ret = ivpu_fw_init (vdev );
501
+ if (ret ) {
502
+ ivpu_err (vdev , "Failed to initialize firmware: %d\n" , ret );
503
+ goto err_mmu_gctx_fini ;
504
+ }
505
+
392
506
ret = ivpu_ipc_init (vdev );
393
507
if (ret ) {
394
508
ivpu_err (vdev , "Failed to initialize IPC: %d\n" , ret );
395
- goto err_mmu_gctx_fini ;
509
+ goto err_fw_fini ;
510
+ }
511
+
512
+ ret = ivpu_fw_load (vdev );
513
+ if (ret ) {
514
+ ivpu_err (vdev , "Failed to load firmware: %d\n" , ret );
515
+ goto err_fw_fini ;
516
+ }
517
+
518
+ ret = ivpu_boot (vdev );
519
+ if (ret ) {
520
+ ivpu_err (vdev , "Failed to boot: %d\n" , ret );
521
+ goto err_fw_fini ;
396
522
}
397
523
398
524
return 0 ;
399
525
526
+ err_fw_fini :
527
+ ivpu_fw_fini (vdev );
400
528
err_mmu_gctx_fini :
401
529
ivpu_mmu_global_context_fini (vdev );
402
530
err_power_down :
@@ -410,6 +538,7 @@ static void ivpu_dev_fini(struct ivpu_device *vdev)
410
538
{
411
539
ivpu_shutdown (vdev );
412
540
ivpu_ipc_fini (vdev );
541
+ ivpu_fw_fini (vdev );
413
542
ivpu_mmu_global_context_fini (vdev );
414
543
415
544
drm_WARN_ON (& vdev -> drm , !xa_empty (& vdev -> context_xa ));
0 commit comments