Lines Matching full:fw
43 /** @minor: Minor FW version. */
46 /** @major: Major FW version. */
53 /** @version_hash: FW version hash. */
59 /** @size: FW binary size. */
67 /** @CSF_FW_BINARY_ENTRY_TYPE_IFACE: Host <-> FW interface. */
70 /** @CSF_FW_BINARY_ENTRY_TYPE_CONFIG: FW config. */
110 * struct panthor_fw_binary_section_entry_hdr - Describes a section of FW binary
125 /** @data: Data to initialize the FW section with. */
127 /** @start: Start offset in the FW binary. */
130 /** @end: End offset in the FW binary. */
141 /** @data: FW binary data. */
144 /** @size: FW binary size. */
152 * struct panthor_fw_section - FW section
155 /** @node: Used to keep track of FW sections. */
158 /** @flags: Section flags, as encoded in the FW binary. */
172 * @data: Initial data copied to the FW memory.
203 * struct panthor_fw_iface - FW interfaces
223 /** @sections: List of FW sections. */
226 /** @shared_section: The section containing the FW interfaces. */
229 /** @iface: FW interfaces. */
232 /** @watchdog: Collection of fields relating to the FW watchdog. */
234 /** @ping_work: Delayed work used to ping the FW. */
239 * @req_waitqueue: FW request waitqueue.
249 /** @booted: True is the FW is booted */
255 * A fast reset is just a reset where the driver doesn't reload the FW sections.
269 return ptdev->fw->vm; in panthor_fw_vm()
281 return &ptdev->fw->iface.global; in panthor_fw_get_glb_iface()
297 return &ptdev->fw->iface.groups[csg_slot]; in panthor_fw_get_csg_iface()
314 return &ptdev->fw->iface.streams[csg_slot][cs_slot]; in panthor_fw_get_cs_iface()
322 * The FW has two timer sources: the GPU counter or arch-timer. We need
345 * maximum value so the FW still handles the core in panthor_fw_conv_timeout()
427 * @input_fw_va: Pointer holding the input interface FW VA on success.
429 * @output_fw_va: Pointer holding the output interface FW VA on success.
446 mem = panthor_kernel_bo_create(ptdev, ptdev->fw->vm, SZ_8K, in panthor_fw_alloc_queue_iface_mem()
486 const struct firmware *fw, 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()
513 if (hdr.data.end > fw->size) { 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()
515 hdr.data.end, fw->size); in panthor_fw_load_section_entry()
550 list_add_tail(§ion->node, &ptdev->fw->sections); in panthor_fw_load_section_entry()
560 memcpy(data, fw->data + hdr.data.start, section->data.size); in panthor_fw_load_section_entry()
626 ptdev->fw->shared_section = section; in panthor_fw_load_section_entry()
636 list_for_each_entry(section, &ptdev->fw->sections, node) { in panthor_reload_fw_sections()
650 const struct firmware *fw, in panthor_fw_load_entry() argument
674 return panthor_fw_load_section_entry(ptdev, fw, &eiter, ehdr); in panthor_fw_load_entry()
697 const struct firmware *fw = NULL; in panthor_fw_load() local
708 ret = request_firmware(&fw, fw_path, ptdev->base.dev); in panthor_fw_load()
715 iter.data = fw->data; in panthor_fw_load()
716 iter.size = fw->size; 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()
754 release_firmware(fw); in panthor_fw_load()
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()
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()
794 cs_iface->control = ptdev->fw->shared_section->mem->kmap + iface_offset; in panthor_init_cs_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()
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()
924 drm_info(&ptdev->base, "CSF FW v%d.%d.%d, Features %#x Instrumentation features %#x", in panthor_fw_init_ifaces()
962 mod_delayed_work(ptdev->reset.wq, &ptdev->fw->watchdog.ping_work, in panthor_fw_init_global_iface()
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()
973 /* If the FW is not booted, don't process IRQs, just flag the FW as booted. */ in panthor_job_irq_handler()
974 if (!ptdev->fw->booted) in panthor_job_irq_handler()
985 ptdev->fw->booted = false; in panthor_fw_start()
986 panthor_job_irq_resume(&ptdev->fw->irq, ~0); 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()
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()
1048 ptdev->fw->fast_reset = true; in panthor_fw_pre_reset()
1053 /* The FW detects 0 -> 1 transitions. Make sure we reset in panthor_fw_pre_reset()
1054 * the HALT bit before the FW is rebooted. in panthor_fw_pre_reset()
1059 panthor_job_irq_suspend(&ptdev->fw->irq); in panthor_fw_pre_reset()
1066 * Start the FW. If this is not a fast reset, all FW sections are reloaded to
1074 ret = panthor_vm_active(ptdev->fw->vm); in panthor_fw_post_reset()
1079 * the FW sections. If it fails, go for a full reset. in panthor_fw_post_reset()
1081 if (ptdev->fw->fast_reset) { 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()
1108 drm_err(&ptdev->base, "FW slow reset failed (couldn't start the FW )"); in panthor_fw_post_reset()
1126 * If there is still FW-related work running after this function returns,
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()
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()
1157 * panthor_fw_wait_acks() - Wait for requests to be acknowledged by the FW.
1214 /* GLB_HALT doesn't get acked through the FW interface. */ in panthor_fw_glb_wait_acks()
1220 &ptdev->fw->req_waitqueue, in panthor_fw_glb_wait_acks()
1246 &ptdev->fw->req_waitqueue, in panthor_fw_csg_wait_acks()
1280 struct panthor_fw *fw = container_of(work, struct panthor_fw, watchdog.ping_work.work); in panthor_fw_ping_work() local
1281 struct panthor_device *ptdev = fw->irq.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()
1303 * panthor_fw_init() - Initialize FW related data.
1310 struct panthor_fw *fw; in panthor_fw_init() local
1313 fw = drmm_kzalloc(&ptdev->base, sizeof(*fw), GFP_KERNEL); in panthor_fw_init()
1314 if (!fw) in panthor_fw_init()
1317 ptdev->fw = fw; in panthor_fw_init()
1318 init_waitqueue_head(&fw->req_waitqueue); in panthor_fw_init()
1319 INIT_LIST_HEAD(&fw->sections); in panthor_fw_init()
1320 INIT_DELAYED_WORK(&fw->watchdog.ping_work, panthor_fw_ping_work); in panthor_fw_init()
1326 ret = panthor_request_job_irq(ptdev, &fw->irq, irq, 0); in panthor_fw_init()
1336 fw->vm = panthor_vm_create(ptdev, true, in panthor_fw_init()
1340 if (IS_ERR(fw->vm)) { in panthor_fw_init()
1341 ret = PTR_ERR(fw->vm); in panthor_fw_init()
1342 fw->vm = NULL; in panthor_fw_init()
1350 ret = panthor_vm_active(fw->vm); in panthor_fw_init()