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.
216 * struct panthor_fw_iface - FW interfaces
236 /** @sections: List of FW sections. */
239 /** @shared_section: The section containing the FW interfaces. */
242 /** @iface: FW interfaces. */
245 /** @watchdog: Collection of fields relating to the FW watchdog. */
247 /** @ping_work: Delayed work used to ping the FW. */
252 * @req_waitqueue: FW request waitqueue.
262 /** @booted: True is the FW is booted */
271 return ptdev->fw->vm; in panthor_fw_vm()
283 return &ptdev->fw->iface.global; in panthor_fw_get_glb_iface()
299 return &ptdev->fw->iface.groups[csg_slot]; in panthor_fw_get_csg_iface()
316 return &ptdev->fw->iface.streams[csg_slot][cs_slot]; in panthor_fw_get_cs_iface()
324 * The FW has two timer sources: the GPU counter or arch-timer. We need
347 * maximum value so the FW still handles the core in panthor_fw_conv_timeout()
429 * @input_fw_va: Pointer holding the input interface FW VA on success.
431 * @output_fw_va: Pointer holding the output interface FW VA on success.
448 mem = panthor_kernel_bo_create(ptdev, ptdev->fw->vm, SZ_8K, in panthor_fw_alloc_queue_iface_mem()
488 const struct firmware *fw, in panthor_fw_load_section_entry() argument
492 ssize_t vm_pgsz = panthor_vm_page_size(ptdev->fw->vm); in panthor_fw_load_section_entry()
515 if (hdr.data.end > fw->size) { in panthor_fw_load_section_entry()
516 drm_err(&ptdev->base, "Firmware corrupted, file truncated? data_end=0x%x > fw size=0x%zx\n", in panthor_fw_load_section_entry()
517 hdr.data.end, fw->size); in panthor_fw_load_section_entry()
552 list_add_tail(&section->node, &ptdev->fw->sections); in panthor_fw_load_section_entry()
562 memcpy(data, fw->data + hdr.data.start, section->data.size); in panthor_fw_load_section_entry()
628 ptdev->fw->shared_section = section; in panthor_fw_load_section_entry()
634 const struct firmware *fw, in panthor_fw_read_build_info() argument
647 if (hdr.meta_start > fw->size || in panthor_fw_read_build_info()
648 hdr.meta_start + hdr.meta_size > fw->size) { in panthor_fw_read_build_info()
654 if (memcmp(git_sha_header, fw->data + hdr.meta_start, header_len)) { in panthor_fw_read_build_info()
660 if (fw->data[hdr.meta_start + hdr.meta_size - 1] != '\0') { in panthor_fw_read_build_info()
667 fw->data + hdr.meta_start + header_len); in panthor_fw_read_build_info()
677 list_for_each_entry(section, &ptdev->fw->sections, node) { in panthor_reload_fw_sections()
691 const struct firmware *fw, in panthor_fw_load_entry() argument
715 return panthor_fw_load_section_entry(ptdev, fw, &eiter, ehdr); in panthor_fw_load_entry()
717 return panthor_fw_read_build_info(ptdev, fw, &eiter, ehdr); in panthor_fw_load_entry()
740 const struct firmware *fw = NULL; in panthor_fw_load() local
751 ret = request_firmware(&fw, fw_path, ptdev->base.dev); in panthor_fw_load()
758 iter.data = fw->data; in panthor_fw_load()
759 iter.size = fw->size; in panthor_fw_load()
785 ret = panthor_fw_load_entry(ptdev, fw, &iter); in panthor_fw_load()
790 if (!ptdev->fw->shared_section) { in panthor_fw_load()
797 release_firmware(fw); in panthor_fw_load()
810 u64 shared_mem_start = panthor_kernel_bo_gpuva(ptdev->fw->shared_section->mem); in iface_fw_to_cpu_addr()
812 panthor_kernel_bo_size(ptdev->fw->shared_section->mem); in iface_fw_to_cpu_addr()
816 return ptdev->fw->shared_section->mem->kmap + (mcu_va - shared_mem_start); in iface_fw_to_cpu_addr()
824 struct panthor_fw_cs_iface *cs_iface = &ptdev->fw->iface.streams[csg_idx][cs_idx]; in panthor_init_cs_iface()
825 u64 shared_section_sz = panthor_kernel_bo_size(ptdev->fw->shared_section->mem); in panthor_init_cs_iface()
837 cs_iface->control = ptdev->fw->shared_section->mem->kmap + iface_offset; in panthor_init_cs_iface()
879 struct panthor_fw_csg_iface *csg_iface = &ptdev->fw->iface.groups[csg_idx]; in panthor_init_csg_iface()
880 u64 shared_section_sz = panthor_kernel_bo_size(ptdev->fw->shared_section->mem); in panthor_init_csg_iface()
888 csg_iface->control = ptdev->fw->shared_section->mem->kmap + iface_offset; in panthor_init_csg_iface()
933 struct panthor_fw_global_iface *glb_iface = &ptdev->fw->iface.global; in panthor_fw_init_ifaces()
936 if (!ptdev->fw->shared_section->mem->kmap) in panthor_fw_init_ifaces()
940 glb_iface->control = ptdev->fw->shared_section->mem->kmap; in panthor_fw_init_ifaces()
967 …drm_info(&ptdev->base, "CSF FW using interface v%d.%d.%d, Features %#x Instrumentation features %#… in panthor_fw_init_ifaces()
1005 mod_delayed_work(ptdev->reset.wq, &ptdev->fw->watchdog.ping_work, in panthor_fw_init_global_iface()
1011 if (!ptdev->fw->booted && (status & JOB_INT_GLOBAL_IF)) in panthor_job_irq_handler()
1012 ptdev->fw->booted = true; in panthor_job_irq_handler()
1014 wake_up_all(&ptdev->fw->req_waitqueue); in panthor_job_irq_handler()
1016 /* If the FW is not booted, don't process IRQs, just flag the FW as booted. */ in panthor_job_irq_handler()
1017 if (!ptdev->fw->booted) in panthor_job_irq_handler()
1028 ptdev->fw->booted = false; in panthor_fw_start()
1029 panthor_job_irq_resume(&ptdev->fw->irq, ~0); in panthor_fw_start()
1032 if (!wait_event_timeout(ptdev->fw->req_waitqueue, in panthor_fw_start()
1033 ptdev->fw->booted, in panthor_fw_start()
1035 if (!ptdev->fw->booted && in panthor_fw_start()
1078 cancel_delayed_work_sync(&ptdev->fw->watchdog.ping_work); in panthor_fw_pre_reset()
1096 panthor_job_irq_suspend(&ptdev->fw->irq); in panthor_fw_pre_reset()
1103 * Start the FW. If this is not a fast reset, all FW sections are reloaded to
1111 ret = panthor_vm_active(ptdev->fw->vm); in panthor_fw_post_reset()
1122 /* The FW detects 0 -> 1 transitions. Make sure we reset in panthor_fw_post_reset()
1123 * the HALT bit before the FW is rebooted. in panthor_fw_post_reset()
1124 * This is not needed on a slow reset because FW sections are in panthor_fw_post_reset()
1134 drm_err(&ptdev->base, "FW %s reset failed", in panthor_fw_post_reset()
1152 * If there is still FW-related work running after this function returns,
1160 cancel_delayed_work_sync(&ptdev->fw->watchdog.ping_work); in panthor_fw_unplug()
1164 if (ptdev->fw->irq.irq) in panthor_fw_unplug()
1165 panthor_job_irq_suspend(&ptdev->fw->irq); in panthor_fw_unplug()
1170 list_for_each_entry(section, &ptdev->fw->sections, node) in panthor_fw_unplug()
1178 panthor_vm_put(ptdev->fw->vm); in panthor_fw_unplug()
1179 ptdev->fw->vm = NULL; in panthor_fw_unplug()
1186 * panthor_fw_wait_acks() - Wait for requests to be acknowledged by the FW.
1243 /* GLB_HALT doesn't get acked through the FW interface. */ in panthor_fw_glb_wait_acks()
1249 &ptdev->fw->req_waitqueue, in panthor_fw_glb_wait_acks()
1275 &ptdev->fw->req_waitqueue, in panthor_fw_csg_wait_acks()
1309 struct panthor_fw *fw = container_of(work, struct panthor_fw, watchdog.ping_work.work); in panthor_fw_ping_work() local
1310 struct panthor_device *ptdev = fw->irq.ptdev; in panthor_fw_ping_work()
1324 drm_err(&ptdev->base, "FW ping timeout, scheduling a reset"); in panthor_fw_ping_work()
1326 mod_delayed_work(ptdev->reset.wq, &fw->watchdog.ping_work, in panthor_fw_ping_work()
1332 * panthor_fw_init() - Initialize FW related data.
1339 struct panthor_fw *fw; in panthor_fw_init() local
1342 fw = drmm_kzalloc(&ptdev->base, sizeof(*fw), GFP_KERNEL); in panthor_fw_init()
1343 if (!fw) in panthor_fw_init()
1346 ptdev->fw = fw; in panthor_fw_init()
1347 init_waitqueue_head(&fw->req_waitqueue); in panthor_fw_init()
1348 INIT_LIST_HEAD(&fw->sections); in panthor_fw_init()
1349 INIT_DELAYED_WORK(&fw->watchdog.ping_work, panthor_fw_ping_work); in panthor_fw_init()
1355 ret = panthor_request_job_irq(ptdev, &fw->irq, irq, 0); in panthor_fw_init()
1365 fw->vm = panthor_vm_create(ptdev, true, in panthor_fw_init()
1369 if (IS_ERR(fw->vm)) { in panthor_fw_init()
1370 ret = PTR_ERR(fw->vm); in panthor_fw_init()
1371 fw->vm = NULL; in panthor_fw_init()
1379 ret = panthor_vm_active(fw->vm); in panthor_fw_init()