Lines Matching refs:ptdev
267 struct panthor_vm *panthor_fw_vm(struct panthor_device *ptdev) in panthor_fw_vm() argument
269 return ptdev->fw->vm; in panthor_fw_vm()
279 panthor_fw_get_glb_iface(struct panthor_device *ptdev) in panthor_fw_get_glb_iface() argument
281 return &ptdev->fw->iface.global; in panthor_fw_get_glb_iface()
292 panthor_fw_get_csg_iface(struct panthor_device *ptdev, u32 csg_slot) in panthor_fw_get_csg_iface() argument
294 if (drm_WARN_ON(&ptdev->base, csg_slot >= MAX_CSGS)) in panthor_fw_get_csg_iface()
297 return &ptdev->fw->iface.groups[csg_slot]; in panthor_fw_get_csg_iface()
309 panthor_fw_get_cs_iface(struct panthor_device *ptdev, u32 csg_slot, u32 cs_slot) in panthor_fw_get_cs_iface() argument
311 if (drm_WARN_ON(&ptdev->base, csg_slot >= MAX_CSGS || cs_slot >= MAX_CS_PER_CSG)) in panthor_fw_get_cs_iface()
314 return &ptdev->fw->iface.streams[csg_slot][cs_slot]; in panthor_fw_get_cs_iface()
328 static u32 panthor_fw_conv_timeout(struct panthor_device *ptdev, u32 timeout_us) in panthor_fw_conv_timeout() argument
340 timer_rate = clk_get_rate(ptdev->clks.core); in panthor_fw_conv_timeout()
343 if (drm_WARN_ON(&ptdev->base, !timer_rate)) { in panthor_fw_conv_timeout()
354 if (drm_WARN_ON(&ptdev->base, mod_cycles > GLB_TIMER_VAL(~0))) in panthor_fw_conv_timeout()
361 static int panthor_fw_binary_iter_read(struct panthor_device *ptdev, in panthor_fw_binary_iter_read() argument
368 drm_err(&ptdev->base, "Firmware too small\n"); in panthor_fw_binary_iter_read()
377 static int panthor_fw_binary_sub_iter_init(struct panthor_device *ptdev, in panthor_fw_binary_sub_iter_init() argument
385 drm_err(&ptdev->base, "Firmware entry too long\n"); in panthor_fw_binary_sub_iter_init()
396 static void panthor_fw_init_section_mem(struct panthor_device *ptdev, in panthor_fw_init_section_mem() argument
407 if (drm_WARN_ON(&ptdev->base, ret)) in panthor_fw_init_section_mem()
438 panthor_fw_alloc_queue_iface_mem(struct panthor_device *ptdev, in panthor_fw_alloc_queue_iface_mem() argument
446 mem = panthor_kernel_bo_create(ptdev, ptdev->fw->vm, SZ_8K, in panthor_fw_alloc_queue_iface_mem()
477 panthor_fw_alloc_suspend_buf_mem(struct panthor_device *ptdev, size_t size) in panthor_fw_alloc_suspend_buf_mem() argument
479 return panthor_kernel_bo_create(ptdev, panthor_fw_vm(ptdev), size, in panthor_fw_alloc_suspend_buf_mem()
485 static int panthor_fw_load_section_entry(struct panthor_device *ptdev, in panthor_fw_load_section_entry() argument
490 ssize_t vm_pgsz = panthor_vm_page_size(ptdev->fw->vm); in panthor_fw_load_section_entry()
497 ret = panthor_fw_binary_iter_read(ptdev, iter, &hdr, sizeof(hdr)); in panthor_fw_load_section_entry()
502 drm_err(&ptdev->base, "Firmware corrupted, data.end < data.start (0x%x < 0x%x)\n", in panthor_fw_load_section_entry()
508 drm_err(&ptdev->base, "Firmware corrupted, hdr.va.end < hdr.va.start (0x%x < 0x%x)\n", in panthor_fw_load_section_entry()
514 drm_err(&ptdev->base, "Firmware corrupted, file truncated? data_end=0x%x > fw size=0x%zx\n", in panthor_fw_load_section_entry()
520 drm_err(&ptdev->base, "Firmware corrupted, virtual addresses not page aligned: 0x%x-0x%x\n", in panthor_fw_load_section_entry()
526 drm_err(&ptdev->base, "Firmware contains interface with unsupported flags (0x%x)\n", in panthor_fw_load_section_entry()
532 drm_warn(&ptdev->base, in panthor_fw_load_section_entry()
539 drm_err(&ptdev->base, in panthor_fw_load_section_entry()
546 section = drmm_kzalloc(&ptdev->base, sizeof(*section), GFP_KERNEL); in panthor_fw_load_section_entry()
550 list_add_tail(§ion->node, &ptdev->fw->sections); in panthor_fw_load_section_entry()
555 void *data = drmm_kmalloc(&ptdev->base, section->data.size, GFP_KERNEL); in panthor_fw_load_section_entry()
565 char *name = drmm_kmalloc(&ptdev->base, name_len + 1, GFP_KERNEL); in panthor_fw_load_section_entry()
599 section->mem = panthor_kernel_bo_create(ptdev, panthor_fw_vm(ptdev), in panthor_fw_load_section_entry()
606 if (drm_WARN_ON(&ptdev->base, section->mem->va_node.start != hdr.va.start)) in panthor_fw_load_section_entry()
615 panthor_fw_init_section_mem(ptdev, section); in panthor_fw_load_section_entry()
622 dma_sync_sgtable_for_device(ptdev->base.dev, sgt, DMA_TO_DEVICE); in panthor_fw_load_section_entry()
626 ptdev->fw->shared_section = section; in panthor_fw_load_section_entry()
632 panthor_reload_fw_sections(struct panthor_device *ptdev, bool full_reload) in panthor_reload_fw_sections() argument
636 list_for_each_entry(section, &ptdev->fw->sections, node) { in panthor_reload_fw_sections()
642 panthor_fw_init_section_mem(ptdev, section); in panthor_reload_fw_sections()
644 if (!drm_WARN_ON(&ptdev->base, IS_ERR_OR_NULL(sgt))) in panthor_reload_fw_sections()
645 dma_sync_sgtable_for_device(ptdev->base.dev, sgt, DMA_TO_DEVICE); in panthor_reload_fw_sections()
649 static int panthor_fw_load_entry(struct panthor_device *ptdev, in panthor_fw_load_entry() argument
657 ret = panthor_fw_binary_iter_read(ptdev, iter, &ehdr, sizeof(ehdr)); in panthor_fw_load_entry()
663 drm_err(&ptdev->base, "Firmware entry isn't 32 bit aligned, offset=0x%x size=0x%x\n", in panthor_fw_load_entry()
668 if (panthor_fw_binary_sub_iter_init(ptdev, iter, &eiter, in panthor_fw_load_entry()
674 return panthor_fw_load_section_entry(ptdev, fw, &eiter, ehdr); in panthor_fw_load_entry()
689 drm_err(&ptdev->base, in panthor_fw_load_entry()
695 static int panthor_fw_load(struct panthor_device *ptdev) in panthor_fw_load() argument
704 (u32)GPU_ARCH_MAJOR(ptdev->gpu_info.gpu_id), in panthor_fw_load()
705 (u32)GPU_ARCH_MINOR(ptdev->gpu_info.gpu_id), in panthor_fw_load()
708 ret = request_firmware(&fw, fw_path, ptdev->base.dev); in panthor_fw_load()
710 drm_err(&ptdev->base, "Failed to load firmware image '%s'\n", in panthor_fw_load()
717 ret = panthor_fw_binary_iter_read(ptdev, &iter, &hdr, sizeof(hdr)); in panthor_fw_load()
723 drm_err(&ptdev->base, "Invalid firmware magic\n"); in panthor_fw_load()
729 drm_err(&ptdev->base, "Unsupported firmware binary header version %d.%d (expected %d.x)\n", in panthor_fw_load()
735 drm_err(&ptdev->base, "Firmware image is truncated\n"); in panthor_fw_load()
742 ret = panthor_fw_load_entry(ptdev, fw, &iter); in panthor_fw_load()
747 if (!ptdev->fw->shared_section) { in panthor_fw_load()
748 drm_err(&ptdev->base, "Shared interface region not found\n"); in panthor_fw_load()
765 static void *iface_fw_to_cpu_addr(struct panthor_device *ptdev, u32 mcu_va) in iface_fw_to_cpu_addr() argument
767 u64 shared_mem_start = panthor_kernel_bo_gpuva(ptdev->fw->shared_section->mem); in iface_fw_to_cpu_addr()
769 panthor_kernel_bo_size(ptdev->fw->shared_section->mem); in iface_fw_to_cpu_addr()
773 return ptdev->fw->shared_section->mem->kmap + (mcu_va - shared_mem_start); in iface_fw_to_cpu_addr()
776 static int panthor_init_cs_iface(struct panthor_device *ptdev, in panthor_init_cs_iface() argument
779 struct panthor_fw_global_iface *glb_iface = panthor_fw_get_glb_iface(ptdev); in panthor_init_cs_iface()
780 struct panthor_fw_csg_iface *csg_iface = panthor_fw_get_csg_iface(ptdev, csg_idx); in panthor_init_cs_iface()
781 struct panthor_fw_cs_iface *cs_iface = &ptdev->fw->iface.streams[csg_idx][cs_idx]; in panthor_init_cs_iface()
782 u64 shared_section_sz = panthor_kernel_bo_size(ptdev->fw->shared_section->mem); in panthor_init_cs_iface()
788 panthor_fw_get_cs_iface(ptdev, 0, 0); in panthor_init_cs_iface()
794 cs_iface->control = ptdev->fw->shared_section->mem->kmap + iface_offset; in panthor_init_cs_iface()
795 cs_iface->input = iface_fw_to_cpu_addr(ptdev, cs_iface->control->input_va); in panthor_init_cs_iface()
796 cs_iface->output = iface_fw_to_cpu_addr(ptdev, cs_iface->control->output_va); in panthor_init_cs_iface()
799 drm_err(&ptdev->base, "Invalid stream control interface input/output VA"); in panthor_init_cs_iface()
805 drm_err(&ptdev->base, "Expecting identical CS slots"); in panthor_init_cs_iface()
811 ptdev->csif_info.cs_reg_count = reg_count; in panthor_init_cs_iface()
812 ptdev->csif_info.unpreserved_cs_reg_count = CSF_UNPRESERVED_REG_COUNT; in panthor_init_cs_iface()
832 static int panthor_init_csg_iface(struct panthor_device *ptdev, in panthor_init_csg_iface() argument
835 struct panthor_fw_global_iface *glb_iface = panthor_fw_get_glb_iface(ptdev); in panthor_init_csg_iface()
836 struct panthor_fw_csg_iface *csg_iface = &ptdev->fw->iface.groups[csg_idx]; in panthor_init_csg_iface()
837 u64 shared_section_sz = panthor_kernel_bo_size(ptdev->fw->shared_section->mem); in panthor_init_csg_iface()
845 csg_iface->control = ptdev->fw->shared_section->mem->kmap + iface_offset; in panthor_init_csg_iface()
846 csg_iface->input = iface_fw_to_cpu_addr(ptdev, csg_iface->control->input_va); in panthor_init_csg_iface()
847 csg_iface->output = iface_fw_to_cpu_addr(ptdev, csg_iface->control->output_va); in panthor_init_csg_iface()
854 drm_err(&ptdev->base, "Invalid group control interface input/output VA"); in panthor_init_csg_iface()
860 panthor_fw_get_csg_iface(ptdev, 0); in panthor_init_csg_iface()
863 drm_err(&ptdev->base, "Expecting identical CSG slots"); in panthor_init_csg_iface()
869 int ret = panthor_init_cs_iface(ptdev, csg_idx, i); in panthor_init_csg_iface()
878 static u32 panthor_get_instr_features(struct panthor_device *ptdev) in panthor_get_instr_features() argument
880 struct panthor_fw_global_iface *glb_iface = panthor_fw_get_glb_iface(ptdev); in panthor_get_instr_features()
888 static int panthor_fw_init_ifaces(struct panthor_device *ptdev) in panthor_fw_init_ifaces() argument
890 struct panthor_fw_global_iface *glb_iface = &ptdev->fw->iface.global; in panthor_fw_init_ifaces()
893 if (!ptdev->fw->shared_section->mem->kmap) in panthor_fw_init_ifaces()
897 glb_iface->control = ptdev->fw->shared_section->mem->kmap; in panthor_fw_init_ifaces()
900 drm_err(&ptdev->base, "Firmware version is 0. Firmware may have failed to boot"); in panthor_fw_init_ifaces()
904 glb_iface->input = iface_fw_to_cpu_addr(ptdev, glb_iface->control->input_va); in panthor_fw_init_ifaces()
905 glb_iface->output = iface_fw_to_cpu_addr(ptdev, glb_iface->control->output_va); in panthor_fw_init_ifaces()
907 drm_err(&ptdev->base, "Invalid global control interface input/output VA"); in panthor_fw_init_ifaces()
913 drm_err(&ptdev->base, "Invalid number of control groups"); in panthor_fw_init_ifaces()
918 int ret = panthor_init_csg_iface(ptdev, i); in panthor_fw_init_ifaces()
924 drm_info(&ptdev->base, "CSF FW v%d.%d.%d, Features %#x Instrumentation features %#x", in panthor_fw_init_ifaces()
929 panthor_get_instr_features(ptdev)); in panthor_fw_init_ifaces()
933 static void panthor_fw_init_global_iface(struct panthor_device *ptdev) in panthor_fw_init_global_iface() argument
935 struct panthor_fw_global_iface *glb_iface = panthor_fw_get_glb_iface(ptdev); in panthor_fw_init_global_iface()
938 glb_iface->input->core_en_mask = ptdev->gpu_info.shader_present; in panthor_fw_init_global_iface()
941 glb_iface->input->poweroff_timer = panthor_fw_conv_timeout(ptdev, PWROFF_HYSTERESIS_US); in panthor_fw_init_global_iface()
943 glb_iface->input->idle_timer = panthor_fw_conv_timeout(ptdev, IDLE_HYSTERESIS_US); in panthor_fw_init_global_iface()
959 gpu_write(ptdev, CSF_DOORBELL(CSF_GLB_DOORBELL_ID), 1); in panthor_fw_init_global_iface()
962 mod_delayed_work(ptdev->reset.wq, &ptdev->fw->watchdog.ping_work, in panthor_fw_init_global_iface()
966 static void panthor_job_irq_handler(struct panthor_device *ptdev, u32 status) in panthor_job_irq_handler() argument
968 if (!ptdev->fw->booted && (status & JOB_INT_GLOBAL_IF)) in panthor_job_irq_handler()
969 ptdev->fw->booted = true; in panthor_job_irq_handler()
971 wake_up_all(&ptdev->fw->req_waitqueue); in panthor_job_irq_handler()
974 if (!ptdev->fw->booted) in panthor_job_irq_handler()
977 panthor_sched_report_fw_events(ptdev, status); in panthor_job_irq_handler()
981 static int panthor_fw_start(struct panthor_device *ptdev) in panthor_fw_start() argument
985 ptdev->fw->booted = false; in panthor_fw_start()
986 panthor_job_irq_resume(&ptdev->fw->irq, ~0); in panthor_fw_start()
987 gpu_write(ptdev, MCU_CONTROL, MCU_CONTROL_AUTO); in panthor_fw_start()
989 if (!wait_event_timeout(ptdev->fw->req_waitqueue, in panthor_fw_start()
990 ptdev->fw->booted, in panthor_fw_start()
992 if (!ptdev->fw->booted && in panthor_fw_start()
993 !(gpu_read(ptdev, JOB_INT_STAT) & JOB_INT_GLOBAL_IF)) in panthor_fw_start()
1004 u32 status = gpu_read(ptdev, MCU_STATUS); in panthor_fw_start()
1006 drm_err(&ptdev->base, "Failed to boot MCU (status=%s)", in panthor_fw_start()
1014 static void panthor_fw_stop(struct panthor_device *ptdev) in panthor_fw_stop() argument
1018 gpu_write(ptdev, MCU_CONTROL, MCU_CONTROL_DISABLE); in panthor_fw_stop()
1019 if (readl_poll_timeout(ptdev->iomem + MCU_STATUS, status, in panthor_fw_stop()
1021 drm_err(&ptdev->base, "Failed to stop MCU"); in panthor_fw_stop()
1032 void panthor_fw_pre_reset(struct panthor_device *ptdev, bool on_hang) in panthor_fw_pre_reset() argument
1035 cancel_delayed_work_sync(&ptdev->fw->watchdog.ping_work); in panthor_fw_pre_reset()
1037 ptdev->fw->fast_reset = false; in panthor_fw_pre_reset()
1040 struct panthor_fw_global_iface *glb_iface = panthor_fw_get_glb_iface(ptdev); in panthor_fw_pre_reset()
1044 gpu_write(ptdev, CSF_DOORBELL(CSF_GLB_DOORBELL_ID), 1); in panthor_fw_pre_reset()
1045 if (!readl_poll_timeout(ptdev->iomem + MCU_STATUS, status, in panthor_fw_pre_reset()
1048 ptdev->fw->fast_reset = true; in panthor_fw_pre_reset()
1050 drm_warn(&ptdev->base, "Failed to cleanly suspend MCU"); in panthor_fw_pre_reset()
1059 panthor_job_irq_suspend(&ptdev->fw->irq); in panthor_fw_pre_reset()
1069 int panthor_fw_post_reset(struct panthor_device *ptdev) in panthor_fw_post_reset() argument
1074 ret = panthor_vm_active(ptdev->fw->vm); in panthor_fw_post_reset()
1081 if (ptdev->fw->fast_reset) { in panthor_fw_post_reset()
1082 ret = panthor_fw_start(ptdev); in panthor_fw_post_reset()
1089 panthor_fw_stop(ptdev); in panthor_fw_post_reset()
1090 ptdev->fw->fast_reset = false; in panthor_fw_post_reset()
1091 drm_err(&ptdev->base, "FW fast reset failed, trying a slow reset"); in panthor_fw_post_reset()
1093 ret = panthor_vm_flush_all(ptdev->fw->vm); in panthor_fw_post_reset()
1095 drm_err(&ptdev->base, "FW slow reset failed (couldn't flush FW's AS l2cache)"); in panthor_fw_post_reset()
1104 panthor_reload_fw_sections(ptdev, true); in panthor_fw_post_reset()
1106 ret = panthor_fw_start(ptdev); in panthor_fw_post_reset()
1108 drm_err(&ptdev->base, "FW slow reset failed (couldn't start the FW )"); in panthor_fw_post_reset()
1114 panthor_fw_init_global_iface(ptdev); in panthor_fw_post_reset()
1130 void panthor_fw_unplug(struct panthor_device *ptdev) in panthor_fw_unplug() argument
1134 cancel_delayed_work_sync(&ptdev->fw->watchdog.ping_work); in panthor_fw_unplug()
1137 if (ptdev->fw->irq.irq) in panthor_fw_unplug()
1138 panthor_job_irq_suspend(&ptdev->fw->irq); in panthor_fw_unplug()
1140 panthor_fw_stop(ptdev); in panthor_fw_unplug()
1142 list_for_each_entry(section, &ptdev->fw->sections, node) in panthor_fw_unplug()
1150 panthor_vm_put(ptdev->fw->vm); in panthor_fw_unplug()
1151 ptdev->fw->vm = NULL; in panthor_fw_unplug()
1153 panthor_gpu_power_off(ptdev, L2, ptdev->gpu_info.l2_present, 20000); in panthor_fw_unplug()
1208 int panthor_fw_glb_wait_acks(struct panthor_device *ptdev, in panthor_fw_glb_wait_acks() argument
1212 struct panthor_fw_global_iface *glb_iface = panthor_fw_get_glb_iface(ptdev); in panthor_fw_glb_wait_acks()
1215 if (drm_WARN_ON(&ptdev->base, req_mask & (~GLB_REQ_MASK | GLB_HALT))) in panthor_fw_glb_wait_acks()
1220 &ptdev->fw->req_waitqueue, in panthor_fw_glb_wait_acks()
1235 int panthor_fw_csg_wait_acks(struct panthor_device *ptdev, u32 csg_slot, in panthor_fw_csg_wait_acks() argument
1238 struct panthor_fw_csg_iface *csg_iface = panthor_fw_get_csg_iface(ptdev, csg_slot); in panthor_fw_csg_wait_acks()
1241 if (drm_WARN_ON(&ptdev->base, req_mask & ~CSG_REQ_MASK)) in panthor_fw_csg_wait_acks()
1246 &ptdev->fw->req_waitqueue, in panthor_fw_csg_wait_acks()
1270 void panthor_fw_ring_csg_doorbells(struct panthor_device *ptdev, u32 csg_mask) in panthor_fw_ring_csg_doorbells() argument
1272 struct panthor_fw_global_iface *glb_iface = panthor_fw_get_glb_iface(ptdev); in panthor_fw_ring_csg_doorbells()
1275 gpu_write(ptdev, CSF_DOORBELL(CSF_GLB_DOORBELL_ID), 1); in panthor_fw_ring_csg_doorbells()
1281 struct panthor_device *ptdev = fw->irq.ptdev; in panthor_fw_ping_work() local
1282 struct panthor_fw_global_iface *glb_iface = panthor_fw_get_glb_iface(ptdev); in panthor_fw_ping_work()
1286 if (panthor_device_reset_is_pending(ptdev)) in panthor_fw_ping_work()
1290 gpu_write(ptdev, CSF_DOORBELL(CSF_GLB_DOORBELL_ID), 1); in panthor_fw_ping_work()
1292 ret = panthor_fw_glb_wait_acks(ptdev, GLB_PING, &acked, 100); in panthor_fw_ping_work()
1294 panthor_device_schedule_reset(ptdev); in panthor_fw_ping_work()
1295 drm_err(&ptdev->base, "FW ping timeout, scheduling a reset"); in panthor_fw_ping_work()
1297 mod_delayed_work(ptdev->reset.wq, &fw->watchdog.ping_work, in panthor_fw_ping_work()
1308 int panthor_fw_init(struct panthor_device *ptdev) in panthor_fw_init() argument
1313 fw = drmm_kzalloc(&ptdev->base, sizeof(*fw), GFP_KERNEL); in panthor_fw_init()
1317 ptdev->fw = fw; in panthor_fw_init()
1322 irq = platform_get_irq_byname(to_platform_device(ptdev->base.dev), "job"); in panthor_fw_init()
1326 ret = panthor_request_job_irq(ptdev, &fw->irq, irq, 0); in panthor_fw_init()
1328 drm_err(&ptdev->base, "failed to request job irq"); in panthor_fw_init()
1332 ret = panthor_gpu_l2_power_on(ptdev); in panthor_fw_init()
1336 fw->vm = panthor_vm_create(ptdev, true, in panthor_fw_init()
1346 ret = panthor_fw_load(ptdev); in panthor_fw_init()
1354 ret = panthor_fw_start(ptdev); in panthor_fw_init()
1358 ret = panthor_fw_init_ifaces(ptdev); in panthor_fw_init()
1362 panthor_fw_init_global_iface(ptdev); in panthor_fw_init()
1366 panthor_fw_unplug(ptdev); in panthor_fw_init()