Lines Matching full:fw
44 /** @minor: Minor FW version. */
47 /** @major: Major FW version. */
54 /** @version_hash: FW version hash. */
60 /** @size: FW binary size. */
68 /** @CSF_FW_BINARY_ENTRY_TYPE_IFACE: Host <-> FW interface. */
71 /** @CSF_FW_BINARY_ENTRY_TYPE_CONFIG: FW config. */
85 * the FW binary was built.
117 * struct panthor_fw_binary_section_entry_hdr - Describes a section of FW binary
132 /** @data: Data to initialize the FW section with. */
134 /** @start: Start offset in the FW binary. */
137 /** @end: End offset in the FW binary. */
143 /** @meta_start: Offset of the build info data in the FW binary */
145 /** @meta_size: Size of the build info data in the FW binary */
155 /** @data: FW binary data. */
158 /** @size: FW binary size. */
166 * struct panthor_fw_section - FW section
169 /** @node: Used to keep track of FW sections. */
172 /** @flags: Section flags, as encoded in the FW binary. */
186 * @data: Initial data copied to the FW memory.
217 * struct panthor_fw_iface - FW interfaces
237 /** @sections: List of FW sections. */
240 /** @shared_section: The section containing the FW interfaces. */
243 /** @iface: FW interfaces. */
246 /** @watchdog: Collection of fields relating to the FW watchdog. */
248 /** @ping_work: Delayed work used to ping the FW. */
253 * @req_waitqueue: FW request waitqueue.
263 /** @booted: True is the FW is booted */
272 return ptdev->fw->vm; in panthor_fw_vm()
284 return &ptdev->fw->iface.global; in panthor_fw_get_glb_iface()
300 return &ptdev->fw->iface.groups[csg_slot]; in panthor_fw_get_csg_iface()
317 return &ptdev->fw->iface.streams[csg_slot][cs_slot]; in panthor_fw_get_cs_iface()
325 * The FW has two timer sources: the GPU counter or arch-timer. We need
348 * maximum value so the FW still handles the core in panthor_fw_conv_timeout()
430 * @input_fw_va: Pointer holding the input interface FW VA on success.
432 * @output_fw_va: Pointer holding the output interface FW VA on success.
449 mem = panthor_kernel_bo_create(ptdev, ptdev->fw->vm, SZ_8K, in panthor_fw_alloc_queue_iface_mem()
489 const struct firmware *fw, in panthor_fw_load_section_entry() argument
493 ssize_t vm_pgsz = panthor_vm_page_size(ptdev->fw->vm); in panthor_fw_load_section_entry()
516 if (hdr.data.end > fw->size) { in panthor_fw_load_section_entry()
517 drm_err(&ptdev->base, "Firmware corrupted, file truncated? data_end=0x%x > fw size=0x%zx\n", in panthor_fw_load_section_entry()
518 hdr.data.end, fw->size); in panthor_fw_load_section_entry()
553 list_add_tail(§ion->node, &ptdev->fw->sections); in panthor_fw_load_section_entry()
563 memcpy(data, fw->data + hdr.data.start, section->data.size); in panthor_fw_load_section_entry()
629 ptdev->fw->shared_section = section; in panthor_fw_load_section_entry()
635 const struct firmware *fw, in panthor_fw_read_build_info() argument
648 if (hdr.meta_start > fw->size || in panthor_fw_read_build_info()
649 hdr.meta_start + hdr.meta_size > fw->size) { in panthor_fw_read_build_info()
655 if (memcmp(git_sha_header, fw->data + hdr.meta_start, header_len)) { in panthor_fw_read_build_info()
661 if (fw->data[hdr.meta_start + hdr.meta_size - 1] != '\0') { in panthor_fw_read_build_info()
668 fw->data + hdr.meta_start + header_len); in panthor_fw_read_build_info()
678 list_for_each_entry(section, &ptdev->fw->sections, node) { in panthor_reload_fw_sections()
692 const struct firmware *fw, in panthor_fw_load_entry() argument
716 return panthor_fw_load_section_entry(ptdev, fw, &eiter, ehdr); in panthor_fw_load_entry()
718 return panthor_fw_read_build_info(ptdev, fw, &eiter, ehdr); in panthor_fw_load_entry()
741 const struct firmware *fw = NULL; in panthor_fw_load() local
752 ret = request_firmware(&fw, fw_path, ptdev->base.dev); in panthor_fw_load()
759 iter.data = fw->data; in panthor_fw_load()
760 iter.size = fw->size; in panthor_fw_load()
786 ret = panthor_fw_load_entry(ptdev, fw, &iter); in panthor_fw_load()
791 if (!ptdev->fw->shared_section) { in panthor_fw_load()
798 release_firmware(fw); in panthor_fw_load()
811 u64 shared_mem_start = panthor_kernel_bo_gpuva(ptdev->fw->shared_section->mem); in iface_fw_to_cpu_addr()
813 panthor_kernel_bo_size(ptdev->fw->shared_section->mem); in iface_fw_to_cpu_addr()
817 return ptdev->fw->shared_section->mem->kmap + (mcu_va - shared_mem_start); in iface_fw_to_cpu_addr()
825 struct panthor_fw_cs_iface *cs_iface = &ptdev->fw->iface.streams[csg_idx][cs_idx]; in panthor_init_cs_iface()
826 u64 shared_section_sz = panthor_kernel_bo_size(ptdev->fw->shared_section->mem); in panthor_init_cs_iface()
838 cs_iface->control = ptdev->fw->shared_section->mem->kmap + iface_offset; in panthor_init_cs_iface()
880 struct panthor_fw_csg_iface *csg_iface = &ptdev->fw->iface.groups[csg_idx]; in panthor_init_csg_iface()
881 u64 shared_section_sz = panthor_kernel_bo_size(ptdev->fw->shared_section->mem); in panthor_init_csg_iface()
889 csg_iface->control = ptdev->fw->shared_section->mem->kmap + iface_offset; in panthor_init_csg_iface()
934 struct panthor_fw_global_iface *glb_iface = &ptdev->fw->iface.global; in panthor_fw_init_ifaces()
937 if (!ptdev->fw->shared_section->mem->kmap) in panthor_fw_init_ifaces()
941 glb_iface->control = ptdev->fw->shared_section->mem->kmap; in panthor_fw_init_ifaces()
968 …drm_info(&ptdev->base, "CSF FW using interface v%d.%d.%d, Features %#x Instrumentation features %#… in panthor_fw_init_ifaces()
1006 mod_delayed_work(ptdev->reset.wq, &ptdev->fw->watchdog.ping_work, in panthor_fw_init_global_iface()
1012 if (!ptdev->fw->booted && (status & JOB_INT_GLOBAL_IF)) in panthor_job_irq_handler()
1013 ptdev->fw->booted = true; in panthor_job_irq_handler()
1015 wake_up_all(&ptdev->fw->req_waitqueue); in panthor_job_irq_handler()
1017 /* If the FW is not booted, don't process IRQs, just flag the FW as booted. */ in panthor_job_irq_handler()
1018 if (!ptdev->fw->booted) in panthor_job_irq_handler()
1029 ptdev->fw->booted = false; in panthor_fw_start()
1030 panthor_job_irq_resume(&ptdev->fw->irq, ~0); in panthor_fw_start()
1033 if (!wait_event_timeout(ptdev->fw->req_waitqueue, in panthor_fw_start()
1034 ptdev->fw->booted, in panthor_fw_start()
1036 if (!ptdev->fw->booted && in panthor_fw_start()
1079 cancel_delayed_work_sync(&ptdev->fw->watchdog.ping_work); in panthor_fw_pre_reset()
1097 panthor_job_irq_suspend(&ptdev->fw->irq); in panthor_fw_pre_reset()
1104 * Start the FW. If this is not a fast reset, all FW sections are reloaded to
1112 ret = panthor_vm_active(ptdev->fw->vm); in panthor_fw_post_reset()
1123 /* The FW detects 0 -> 1 transitions. Make sure we reset in panthor_fw_post_reset()
1124 * the HALT bit before the FW is rebooted. in panthor_fw_post_reset()
1125 * This is not needed on a slow reset because FW sections are in panthor_fw_post_reset()
1135 drm_err(&ptdev->base, "FW %s reset failed", in panthor_fw_post_reset()
1153 * If there is still FW-related work running after this function returns,
1161 cancel_delayed_work_sync(&ptdev->fw->watchdog.ping_work); in panthor_fw_unplug()
1165 if (ptdev->fw->irq.irq) in panthor_fw_unplug()
1166 panthor_job_irq_suspend(&ptdev->fw->irq); in panthor_fw_unplug()
1171 list_for_each_entry(section, &ptdev->fw->sections, node) in panthor_fw_unplug()
1179 panthor_vm_put(ptdev->fw->vm); in panthor_fw_unplug()
1180 ptdev->fw->vm = NULL; in panthor_fw_unplug()
1187 * panthor_fw_wait_acks() - Wait for requests to be acknowledged by the FW.
1244 /* GLB_HALT doesn't get acked through the FW interface. */ in panthor_fw_glb_wait_acks()
1250 &ptdev->fw->req_waitqueue, in panthor_fw_glb_wait_acks()
1276 &ptdev->fw->req_waitqueue, in panthor_fw_csg_wait_acks()
1310 struct panthor_fw *fw = container_of(work, struct panthor_fw, watchdog.ping_work.work); in panthor_fw_ping_work() local
1311 struct panthor_device *ptdev = fw->irq.ptdev; in panthor_fw_ping_work()
1325 drm_err(&ptdev->base, "FW ping timeout, scheduling a reset"); in panthor_fw_ping_work()
1327 mod_delayed_work(ptdev->reset.wq, &fw->watchdog.ping_work, in panthor_fw_ping_work()
1333 * panthor_fw_init() - Initialize FW related data.
1340 struct panthor_fw *fw; in panthor_fw_init() local
1343 fw = drmm_kzalloc(&ptdev->base, sizeof(*fw), GFP_KERNEL); in panthor_fw_init()
1344 if (!fw) in panthor_fw_init()
1347 ptdev->fw = fw; in panthor_fw_init()
1348 init_waitqueue_head(&fw->req_waitqueue); in panthor_fw_init()
1349 INIT_LIST_HEAD(&fw->sections); in panthor_fw_init()
1350 INIT_DELAYED_WORK(&fw->watchdog.ping_work, panthor_fw_ping_work); in panthor_fw_init()
1356 ret = panthor_request_job_irq(ptdev, &fw->irq, irq, 0); in panthor_fw_init()
1366 fw->vm = panthor_vm_create(ptdev, true, in panthor_fw_init()
1370 if (IS_ERR(fw->vm)) { in panthor_fw_init()
1371 ret = PTR_ERR(fw->vm); in panthor_fw_init()
1372 fw->vm = NULL; in panthor_fw_init()
1380 ret = panthor_vm_active(fw->vm); in panthor_fw_init()