Lines Matching refs:ptdev

269 struct panthor_vm *panthor_fw_vm(struct panthor_device *ptdev)  in panthor_fw_vm()  argument
271 return ptdev->fw->vm; in panthor_fw_vm()
281 panthor_fw_get_glb_iface(struct panthor_device *ptdev) in panthor_fw_get_glb_iface() argument
283 return &ptdev->fw->iface.global; in panthor_fw_get_glb_iface()
294 panthor_fw_get_csg_iface(struct panthor_device *ptdev, u32 csg_slot) in panthor_fw_get_csg_iface() argument
296 if (drm_WARN_ON(&ptdev->base, csg_slot >= MAX_CSGS)) in panthor_fw_get_csg_iface()
299 return &ptdev->fw->iface.groups[csg_slot]; in panthor_fw_get_csg_iface()
311 panthor_fw_get_cs_iface(struct panthor_device *ptdev, u32 csg_slot, u32 cs_slot) in panthor_fw_get_cs_iface() argument
313 if (drm_WARN_ON(&ptdev->base, csg_slot >= MAX_CSGS || cs_slot >= MAX_CS_PER_CSG)) in panthor_fw_get_cs_iface()
316 return &ptdev->fw->iface.streams[csg_slot][cs_slot]; in panthor_fw_get_cs_iface()
330 static u32 panthor_fw_conv_timeout(struct panthor_device *ptdev, u32 timeout_us) in panthor_fw_conv_timeout() argument
342 timer_rate = clk_get_rate(ptdev->clks.core); in panthor_fw_conv_timeout()
345 if (drm_WARN_ON(&ptdev->base, !timer_rate)) { in panthor_fw_conv_timeout()
356 if (drm_WARN_ON(&ptdev->base, mod_cycles > GLB_TIMER_VAL(~0))) in panthor_fw_conv_timeout()
363 static int panthor_fw_binary_iter_read(struct panthor_device *ptdev, in panthor_fw_binary_iter_read() argument
370 drm_err(&ptdev->base, "Firmware too small\n"); in panthor_fw_binary_iter_read()
379 static int panthor_fw_binary_sub_iter_init(struct panthor_device *ptdev, in panthor_fw_binary_sub_iter_init() argument
387 drm_err(&ptdev->base, "Firmware entry too long\n"); in panthor_fw_binary_sub_iter_init()
398 static void panthor_fw_init_section_mem(struct panthor_device *ptdev, in panthor_fw_init_section_mem() argument
409 if (drm_WARN_ON(&ptdev->base, ret)) in panthor_fw_init_section_mem()
440 panthor_fw_alloc_queue_iface_mem(struct panthor_device *ptdev, in panthor_fw_alloc_queue_iface_mem() argument
448 mem = panthor_kernel_bo_create(ptdev, ptdev->fw->vm, SZ_8K, in panthor_fw_alloc_queue_iface_mem()
480 panthor_fw_alloc_suspend_buf_mem(struct panthor_device *ptdev, size_t size) in panthor_fw_alloc_suspend_buf_mem() argument
482 return panthor_kernel_bo_create(ptdev, panthor_fw_vm(ptdev), size, in panthor_fw_alloc_suspend_buf_mem()
489 static int panthor_fw_load_section_entry(struct panthor_device *ptdev, in panthor_fw_load_section_entry() argument
494 ssize_t vm_pgsz = panthor_vm_page_size(ptdev->fw->vm); in panthor_fw_load_section_entry()
501 ret = panthor_fw_binary_iter_read(ptdev, iter, &hdr, sizeof(hdr)); in panthor_fw_load_section_entry()
506 drm_err(&ptdev->base, "Firmware corrupted, data.end < data.start (0x%x < 0x%x)\n", in panthor_fw_load_section_entry()
512 drm_err(&ptdev->base, "Firmware corrupted, hdr.va.end < hdr.va.start (0x%x < 0x%x)\n", in panthor_fw_load_section_entry()
518 drm_err(&ptdev->base, "Firmware corrupted, file truncated? data_end=0x%x > fw size=0x%zx\n", in panthor_fw_load_section_entry()
524 drm_err(&ptdev->base, "Firmware corrupted, virtual addresses not page aligned: 0x%x-0x%x\n", in panthor_fw_load_section_entry()
530 drm_err(&ptdev->base, "Firmware contains interface with unsupported flags (0x%x)\n", in panthor_fw_load_section_entry()
536 drm_warn(&ptdev->base, in panthor_fw_load_section_entry()
543 drm_err(&ptdev->base, in panthor_fw_load_section_entry()
550 section = drmm_kzalloc(&ptdev->base, sizeof(*section), GFP_KERNEL); in panthor_fw_load_section_entry()
554 list_add_tail(&section->node, &ptdev->fw->sections); in panthor_fw_load_section_entry()
559 void *data = drmm_kmalloc(&ptdev->base, section->data.size, GFP_KERNEL); in panthor_fw_load_section_entry()
569 char *name = drmm_kmalloc(&ptdev->base, name_len + 1, GFP_KERNEL); in panthor_fw_load_section_entry()
603 section->mem = panthor_kernel_bo_create(ptdev, panthor_fw_vm(ptdev), in panthor_fw_load_section_entry()
610 if (drm_WARN_ON(&ptdev->base, section->mem->va_node.start != hdr.va.start)) in panthor_fw_load_section_entry()
619 panthor_fw_init_section_mem(ptdev, section); in panthor_fw_load_section_entry()
626 dma_sync_sgtable_for_device(ptdev->base.dev, sgt, DMA_TO_DEVICE); in panthor_fw_load_section_entry()
630 ptdev->fw->shared_section = section; in panthor_fw_load_section_entry()
635 static int panthor_fw_read_build_info(struct panthor_device *ptdev, in panthor_fw_read_build_info() argument
645 ret = panthor_fw_binary_iter_read(ptdev, iter, &hdr, sizeof(hdr)); in panthor_fw_read_build_info()
651 drm_err(&ptdev->base, "Firmware build info corrupt\n"); in panthor_fw_read_build_info()
663 drm_warn(&ptdev->base, "Firmware's git sha is not NULL terminated\n"); in panthor_fw_read_build_info()
668 drm_info(&ptdev->base, "Firmware git sha: %s\n", in panthor_fw_read_build_info()
675 panthor_reload_fw_sections(struct panthor_device *ptdev, bool full_reload) in panthor_reload_fw_sections() argument
679 list_for_each_entry(section, &ptdev->fw->sections, node) { in panthor_reload_fw_sections()
685 panthor_fw_init_section_mem(ptdev, section); in panthor_reload_fw_sections()
687 if (!drm_WARN_ON(&ptdev->base, IS_ERR_OR_NULL(sgt))) in panthor_reload_fw_sections()
688 dma_sync_sgtable_for_device(ptdev->base.dev, sgt, DMA_TO_DEVICE); in panthor_reload_fw_sections()
692 static int panthor_fw_load_entry(struct panthor_device *ptdev, in panthor_fw_load_entry() argument
700 ret = panthor_fw_binary_iter_read(ptdev, iter, &ehdr, sizeof(ehdr)); in panthor_fw_load_entry()
706 drm_err(&ptdev->base, "Firmware entry isn't 32 bit aligned, offset=0x%x size=0x%x\n", in panthor_fw_load_entry()
711 if (panthor_fw_binary_sub_iter_init(ptdev, iter, &eiter, in panthor_fw_load_entry()
717 return panthor_fw_load_section_entry(ptdev, fw, &eiter, ehdr); in panthor_fw_load_entry()
719 return panthor_fw_read_build_info(ptdev, fw, &eiter, ehdr); in panthor_fw_load_entry()
734 drm_err(&ptdev->base, in panthor_fw_load_entry()
740 static int panthor_fw_load(struct panthor_device *ptdev) in panthor_fw_load() argument
749 (u32)GPU_ARCH_MAJOR(ptdev->gpu_info.gpu_id), in panthor_fw_load()
750 (u32)GPU_ARCH_MINOR(ptdev->gpu_info.gpu_id), in panthor_fw_load()
753 ret = request_firmware(&fw, fw_path, ptdev->base.dev); in panthor_fw_load()
755 drm_err(&ptdev->base, "Failed to load firmware image '%s'\n", in panthor_fw_load()
762 ret = panthor_fw_binary_iter_read(ptdev, &iter, &hdr, sizeof(hdr)); in panthor_fw_load()
768 drm_err(&ptdev->base, "Invalid firmware magic\n"); in panthor_fw_load()
774 drm_err(&ptdev->base, "Unsupported firmware binary header version %d.%d (expected %d.x)\n", in panthor_fw_load()
780 drm_err(&ptdev->base, "Firmware image is truncated\n"); in panthor_fw_load()
787 ret = panthor_fw_load_entry(ptdev, fw, &iter); in panthor_fw_load()
792 if (!ptdev->fw->shared_section) { in panthor_fw_load()
793 drm_err(&ptdev->base, "Shared interface region not found\n"); in panthor_fw_load()
810 static void *iface_fw_to_cpu_addr(struct panthor_device *ptdev, u32 mcu_va) in iface_fw_to_cpu_addr() argument
812 u64 shared_mem_start = panthor_kernel_bo_gpuva(ptdev->fw->shared_section->mem); in iface_fw_to_cpu_addr()
814 panthor_kernel_bo_size(ptdev->fw->shared_section->mem); in iface_fw_to_cpu_addr()
818 return ptdev->fw->shared_section->mem->kmap + (mcu_va - shared_mem_start); in iface_fw_to_cpu_addr()
821 static int panthor_init_cs_iface(struct panthor_device *ptdev, in panthor_init_cs_iface() argument
824 struct panthor_fw_global_iface *glb_iface = panthor_fw_get_glb_iface(ptdev); in panthor_init_cs_iface()
825 struct panthor_fw_csg_iface *csg_iface = panthor_fw_get_csg_iface(ptdev, csg_idx); in panthor_init_cs_iface()
826 struct panthor_fw_cs_iface *cs_iface = &ptdev->fw->iface.streams[csg_idx][cs_idx]; in panthor_init_cs_iface()
827 u64 shared_section_sz = panthor_kernel_bo_size(ptdev->fw->shared_section->mem); in panthor_init_cs_iface()
833 panthor_fw_get_cs_iface(ptdev, 0, 0); in panthor_init_cs_iface()
839 cs_iface->control = ptdev->fw->shared_section->mem->kmap + iface_offset; in panthor_init_cs_iface()
840 cs_iface->input = iface_fw_to_cpu_addr(ptdev, cs_iface->control->input_va); in panthor_init_cs_iface()
841 cs_iface->output = iface_fw_to_cpu_addr(ptdev, cs_iface->control->output_va); in panthor_init_cs_iface()
844 drm_err(&ptdev->base, "Invalid stream control interface input/output VA"); in panthor_init_cs_iface()
850 drm_err(&ptdev->base, "Expecting identical CS slots"); in panthor_init_cs_iface()
856 ptdev->csif_info.cs_reg_count = reg_count; in panthor_init_cs_iface()
857 ptdev->csif_info.unpreserved_cs_reg_count = CSF_UNPRESERVED_REG_COUNT; in panthor_init_cs_iface()
877 static int panthor_init_csg_iface(struct panthor_device *ptdev, in panthor_init_csg_iface() argument
880 struct panthor_fw_global_iface *glb_iface = panthor_fw_get_glb_iface(ptdev); in panthor_init_csg_iface()
881 struct panthor_fw_csg_iface *csg_iface = &ptdev->fw->iface.groups[csg_idx]; in panthor_init_csg_iface()
882 u64 shared_section_sz = panthor_kernel_bo_size(ptdev->fw->shared_section->mem); in panthor_init_csg_iface()
890 csg_iface->control = ptdev->fw->shared_section->mem->kmap + iface_offset; in panthor_init_csg_iface()
891 csg_iface->input = iface_fw_to_cpu_addr(ptdev, csg_iface->control->input_va); in panthor_init_csg_iface()
892 csg_iface->output = iface_fw_to_cpu_addr(ptdev, csg_iface->control->output_va); in panthor_init_csg_iface()
899 drm_err(&ptdev->base, "Invalid group control interface input/output VA"); in panthor_init_csg_iface()
905 panthor_fw_get_csg_iface(ptdev, 0); in panthor_init_csg_iface()
908 drm_err(&ptdev->base, "Expecting identical CSG slots"); in panthor_init_csg_iface()
914 int ret = panthor_init_cs_iface(ptdev, csg_idx, i); in panthor_init_csg_iface()
923 static u32 panthor_get_instr_features(struct panthor_device *ptdev) in panthor_get_instr_features() argument
925 struct panthor_fw_global_iface *glb_iface = panthor_fw_get_glb_iface(ptdev); in panthor_get_instr_features()
933 static int panthor_fw_init_ifaces(struct panthor_device *ptdev) in panthor_fw_init_ifaces() argument
935 struct panthor_fw_global_iface *glb_iface = &ptdev->fw->iface.global; in panthor_fw_init_ifaces()
938 if (!ptdev->fw->shared_section->mem->kmap) in panthor_fw_init_ifaces()
942 glb_iface->control = ptdev->fw->shared_section->mem->kmap; in panthor_fw_init_ifaces()
945 drm_err(&ptdev->base, "Firmware version is 0. Firmware may have failed to boot"); in panthor_fw_init_ifaces()
949 glb_iface->input = iface_fw_to_cpu_addr(ptdev, glb_iface->control->input_va); in panthor_fw_init_ifaces()
950 glb_iface->output = iface_fw_to_cpu_addr(ptdev, glb_iface->control->output_va); in panthor_fw_init_ifaces()
952 drm_err(&ptdev->base, "Invalid global control interface input/output VA"); in panthor_fw_init_ifaces()
958 drm_err(&ptdev->base, "Invalid number of control groups"); in panthor_fw_init_ifaces()
963 int ret = panthor_init_csg_iface(ptdev, i); in panthor_fw_init_ifaces()
969 …drm_info(&ptdev->base, "CSF FW using interface v%d.%d.%d, Features %#x Instrumentation features %#… in panthor_fw_init_ifaces()
974 panthor_get_instr_features(ptdev)); in panthor_fw_init_ifaces()
978 static void panthor_fw_init_global_iface(struct panthor_device *ptdev) in panthor_fw_init_global_iface() argument
980 struct panthor_fw_global_iface *glb_iface = panthor_fw_get_glb_iface(ptdev); in panthor_fw_init_global_iface()
983 glb_iface->input->core_en_mask = ptdev->gpu_info.shader_present; in panthor_fw_init_global_iface()
986 glb_iface->input->poweroff_timer = panthor_fw_conv_timeout(ptdev, PWROFF_HYSTERESIS_US); in panthor_fw_init_global_iface()
988 glb_iface->input->idle_timer = panthor_fw_conv_timeout(ptdev, IDLE_HYSTERESIS_US); in panthor_fw_init_global_iface()
1004 gpu_write(ptdev, CSF_DOORBELL(CSF_GLB_DOORBELL_ID), 1); in panthor_fw_init_global_iface()
1007 mod_delayed_work(ptdev->reset.wq, &ptdev->fw->watchdog.ping_work, in panthor_fw_init_global_iface()
1011 static void panthor_job_irq_handler(struct panthor_device *ptdev, u32 status) in panthor_job_irq_handler() argument
1013 gpu_write(ptdev, JOB_INT_CLEAR, status); in panthor_job_irq_handler()
1015 if (!ptdev->fw->booted && (status & JOB_INT_GLOBAL_IF)) in panthor_job_irq_handler()
1016 ptdev->fw->booted = true; in panthor_job_irq_handler()
1018 wake_up_all(&ptdev->fw->req_waitqueue); in panthor_job_irq_handler()
1021 if (!ptdev->fw->booted) in panthor_job_irq_handler()
1024 panthor_sched_report_fw_events(ptdev, status); in panthor_job_irq_handler()
1028 static int panthor_fw_start(struct panthor_device *ptdev) in panthor_fw_start() argument
1032 ptdev->fw->booted = false; in panthor_fw_start()
1033 panthor_job_irq_resume(&ptdev->fw->irq, ~0); in panthor_fw_start()
1034 gpu_write(ptdev, MCU_CONTROL, MCU_CONTROL_AUTO); in panthor_fw_start()
1036 if (!wait_event_timeout(ptdev->fw->req_waitqueue, in panthor_fw_start()
1037 ptdev->fw->booted, in panthor_fw_start()
1039 if (!ptdev->fw->booted && in panthor_fw_start()
1040 !(gpu_read(ptdev, JOB_INT_STAT) & JOB_INT_GLOBAL_IF)) in panthor_fw_start()
1051 u32 status = gpu_read(ptdev, MCU_STATUS); in panthor_fw_start()
1053 drm_err(&ptdev->base, "Failed to boot MCU (status=%s)", in panthor_fw_start()
1061 static void panthor_fw_stop(struct panthor_device *ptdev) in panthor_fw_stop() argument
1065 gpu_write(ptdev, MCU_CONTROL, MCU_CONTROL_DISABLE); in panthor_fw_stop()
1066 if (gpu_read_poll_timeout(ptdev, MCU_STATUS, status, in panthor_fw_stop()
1068 drm_err(&ptdev->base, "Failed to stop MCU"); in panthor_fw_stop()
1079 void panthor_fw_pre_reset(struct panthor_device *ptdev, bool on_hang) in panthor_fw_pre_reset() argument
1082 cancel_delayed_work_sync(&ptdev->fw->watchdog.ping_work); in panthor_fw_pre_reset()
1084 ptdev->reset.fast = false; in panthor_fw_pre_reset()
1087 struct panthor_fw_global_iface *glb_iface = panthor_fw_get_glb_iface(ptdev); in panthor_fw_pre_reset()
1091 gpu_write(ptdev, CSF_DOORBELL(CSF_GLB_DOORBELL_ID), 1); in panthor_fw_pre_reset()
1092 if (!gpu_read_poll_timeout(ptdev, MCU_STATUS, status, in panthor_fw_pre_reset()
1095 ptdev->reset.fast = true; in panthor_fw_pre_reset()
1097 drm_warn(&ptdev->base, "Failed to cleanly suspend MCU"); in panthor_fw_pre_reset()
1101 panthor_job_irq_suspend(&ptdev->fw->irq); in panthor_fw_pre_reset()
1111 int panthor_fw_post_reset(struct panthor_device *ptdev) in panthor_fw_post_reset() argument
1116 ret = panthor_vm_active(ptdev->fw->vm); in panthor_fw_post_reset()
1120 if (!ptdev->reset.fast) { in panthor_fw_post_reset()
1125 panthor_reload_fw_sections(ptdev, true); in panthor_fw_post_reset()
1132 struct panthor_fw_global_iface *glb_iface = panthor_fw_get_glb_iface(ptdev); in panthor_fw_post_reset()
1137 ret = panthor_fw_start(ptdev); in panthor_fw_post_reset()
1139 drm_err(&ptdev->base, "FW %s reset failed", in panthor_fw_post_reset()
1140 ptdev->reset.fast ? "fast" : "slow"); in panthor_fw_post_reset()
1145 panthor_fw_init_global_iface(ptdev); in panthor_fw_post_reset()
1161 void panthor_fw_unplug(struct panthor_device *ptdev) in panthor_fw_unplug() argument
1165 cancel_delayed_work_sync(&ptdev->fw->watchdog.ping_work); in panthor_fw_unplug()
1167 if (!IS_ENABLED(CONFIG_PM) || pm_runtime_active(ptdev->base.dev)) { in panthor_fw_unplug()
1169 if (ptdev->fw->irq.irq) in panthor_fw_unplug()
1170 panthor_job_irq_suspend(&ptdev->fw->irq); in panthor_fw_unplug()
1172 panthor_fw_stop(ptdev); in panthor_fw_unplug()
1175 list_for_each_entry(section, &ptdev->fw->sections, node) in panthor_fw_unplug()
1183 panthor_vm_put(ptdev->fw->vm); in panthor_fw_unplug()
1184 ptdev->fw->vm = NULL; in panthor_fw_unplug()
1186 if (!IS_ENABLED(CONFIG_PM) || pm_runtime_active(ptdev->base.dev)) in panthor_fw_unplug()
1187 panthor_gpu_power_off(ptdev, L2, ptdev->gpu_info.l2_present, 20000); in panthor_fw_unplug()
1242 int panthor_fw_glb_wait_acks(struct panthor_device *ptdev, in panthor_fw_glb_wait_acks() argument
1246 struct panthor_fw_global_iface *glb_iface = panthor_fw_get_glb_iface(ptdev); in panthor_fw_glb_wait_acks()
1249 if (drm_WARN_ON(&ptdev->base, req_mask & (~GLB_REQ_MASK | GLB_HALT))) in panthor_fw_glb_wait_acks()
1254 &ptdev->fw->req_waitqueue, in panthor_fw_glb_wait_acks()
1269 int panthor_fw_csg_wait_acks(struct panthor_device *ptdev, u32 csg_slot, in panthor_fw_csg_wait_acks() argument
1272 struct panthor_fw_csg_iface *csg_iface = panthor_fw_get_csg_iface(ptdev, csg_slot); in panthor_fw_csg_wait_acks()
1275 if (drm_WARN_ON(&ptdev->base, req_mask & ~CSG_REQ_MASK)) in panthor_fw_csg_wait_acks()
1280 &ptdev->fw->req_waitqueue, in panthor_fw_csg_wait_acks()
1304 void panthor_fw_ring_csg_doorbells(struct panthor_device *ptdev, u32 csg_mask) in panthor_fw_ring_csg_doorbells() argument
1306 struct panthor_fw_global_iface *glb_iface = panthor_fw_get_glb_iface(ptdev); in panthor_fw_ring_csg_doorbells()
1309 gpu_write(ptdev, CSF_DOORBELL(CSF_GLB_DOORBELL_ID), 1); in panthor_fw_ring_csg_doorbells()
1315 struct panthor_device *ptdev = fw->irq.ptdev; in panthor_fw_ping_work() local
1316 struct panthor_fw_global_iface *glb_iface = panthor_fw_get_glb_iface(ptdev); in panthor_fw_ping_work()
1320 if (panthor_device_reset_is_pending(ptdev)) in panthor_fw_ping_work()
1324 gpu_write(ptdev, CSF_DOORBELL(CSF_GLB_DOORBELL_ID), 1); in panthor_fw_ping_work()
1326 ret = panthor_fw_glb_wait_acks(ptdev, GLB_PING, &acked, 100); in panthor_fw_ping_work()
1328 panthor_device_schedule_reset(ptdev); in panthor_fw_ping_work()
1329 drm_err(&ptdev->base, "FW ping timeout, scheduling a reset"); in panthor_fw_ping_work()
1331 mod_delayed_work(ptdev->reset.wq, &fw->watchdog.ping_work, in panthor_fw_ping_work()
1342 int panthor_fw_init(struct panthor_device *ptdev) in panthor_fw_init() argument
1347 fw = drmm_kzalloc(&ptdev->base, sizeof(*fw), GFP_KERNEL); in panthor_fw_init()
1351 ptdev->fw = fw; in panthor_fw_init()
1356 irq = platform_get_irq_byname(to_platform_device(ptdev->base.dev), "job"); in panthor_fw_init()
1360 ret = panthor_request_job_irq(ptdev, &fw->irq, irq, 0); in panthor_fw_init()
1362 drm_err(&ptdev->base, "failed to request job irq"); in panthor_fw_init()
1366 ret = panthor_gpu_l2_power_on(ptdev); in panthor_fw_init()
1370 fw->vm = panthor_vm_create(ptdev, true, in panthor_fw_init()
1380 ret = panthor_fw_load(ptdev); in panthor_fw_init()
1388 ret = panthor_fw_start(ptdev); in panthor_fw_init()
1392 ret = panthor_fw_init_ifaces(ptdev); in panthor_fw_init()
1396 panthor_fw_init_global_iface(ptdev); in panthor_fw_init()
1400 panthor_fw_unplug(ptdev); in panthor_fw_init()