Lines Matching +full:powervr +full:- +full:gpu

1 // SPDX-License-Identifier: GPL-2.0-only OR MIT
51 const struct pvr_fw_layout_entry *layout_entries = pvr_dev->fw_dev.layout_entries; in pvr_fw_find_layout_entry()
52 u32 num_layout_entries = pvr_dev->fw_dev.header->layout_entry_num; in pvr_fw_find_layout_entry()
66 const struct pvr_fw_layout_entry *layout_entries = pvr_dev->fw_dev.layout_entries; in pvr_fw_find_private_data()
67 u32 num_layout_entries = pvr_dev->fw_dev.header->layout_entry_num; in pvr_fw_find_private_data()
83 * pvr_fw_validate() - Parse firmware header and check compatibility
88 * * -EINVAL if firmware is incompatible.
94 const struct firmware *firmware = pvr_dev->fw_dev.firmware; in pvr_fw_validate()
97 const u8 *fw = firmware->data; in pvr_fw_validate()
98 u32 fw_offset = firmware->size - SZ_4K; in pvr_fw_validate()
102 if (firmware->size < SZ_4K || (firmware->size % FW_BLOCK_SIZE)) in pvr_fw_validate()
103 return -EINVAL; in pvr_fw_validate()
107 if (header->info_version != PVR_FW_INFO_VERSION) { in pvr_fw_validate()
109 header->info_version); in pvr_fw_validate()
110 return -EINVAL; in pvr_fw_validate()
113 if (header->header_len != sizeof(struct pvr_fw_info_header) || in pvr_fw_validate()
114 header->layout_entry_size != sizeof(struct pvr_fw_layout_entry) || in pvr_fw_validate()
115 header->layout_entry_num > PVR_FW_INFO_MAX_NUM_ENTRIES) { in pvr_fw_validate()
117 return -EINVAL; in pvr_fw_validate()
120 if (!(header->flags & PVR_FW_FLAGS_OPEN_SOURCE) || in pvr_fw_validate()
121 header->fw_version_major > FW_MAX_SUPPORTED_MAJOR_VERSION || in pvr_fw_validate()
122 header->fw_version_major == 0) { in pvr_fw_validate()
124 header->fw_version_major, header->fw_version_minor, in pvr_fw_validate()
125 header->fw_version_build, in pvr_fw_validate()
126 (header->flags & PVR_FW_FLAGS_OPEN_SOURCE) ? " OS" : ""); in pvr_fw_validate()
127 return -EINVAL; in pvr_fw_validate()
130 if (pvr_gpu_id_to_packed_bvnc(&pvr_dev->gpu_id) != header->bvnc) { in pvr_fw_validate()
133 packed_bvnc_to_pvr_gpu_id(header->bvnc, &fw_gpu_id); in pvr_fw_validate()
134 drm_err(drm_dev, "FW built for incorrect GPU ID %i.%i.%i.%i (expected %i.%i.%i.%i)\n", in pvr_fw_validate()
136 pvr_dev->gpu_id.b, pvr_dev->gpu_id.v, pvr_dev->gpu_id.n, pvr_dev->gpu_id.c); in pvr_fw_validate()
137 return -EINVAL; in pvr_fw_validate()
140 fw_offset += header->header_len; in pvr_fw_validate()
142 header->layout_entry_size * header->layout_entry_num; in pvr_fw_validate()
143 if ((fw_offset + layout_table_size) > firmware->size) in pvr_fw_validate()
144 return -EINVAL; in pvr_fw_validate()
147 for (entry = 0; entry < header->layout_entry_num; entry++) { in pvr_fw_validate()
152 return -EINVAL; in pvr_fw_validate()
155 fw_offset = (firmware->size - SZ_4K) - header->device_info_size; in pvr_fw_validate()
157 drm_info(drm_dev, "FW version v%u.%u (build %u OS)\n", header->fw_version_major, in pvr_fw_validate()
158 header->fw_version_minor, header->fw_version_build); in pvr_fw_validate()
160 pvr_dev->fw_version.major = header->fw_version_major; in pvr_fw_validate()
161 pvr_dev->fw_version.minor = header->fw_version_minor; in pvr_fw_validate()
163 pvr_dev->fw_dev.header = header; in pvr_fw_validate()
164 pvr_dev->fw_dev.layout_entries = layout_entries; in pvr_fw_validate()
172 const struct firmware *firmware = pvr_dev->fw_dev.firmware; in pvr_fw_get_device_info()
174 const u8 *fw = firmware->data; in pvr_fw_get_device_info()
178 fw_offset = (firmware->size - SZ_4K) - pvr_dev->fw_dev.header->device_info_size; in pvr_fw_get_device_info()
183 pvr_device_info_set_quirks(pvr_dev, dev_info, header->brn_mask_size); in pvr_fw_get_device_info()
184 dev_info += header->brn_mask_size; in pvr_fw_get_device_info()
186 pvr_device_info_set_enhancements(pvr_dev, dev_info, header->ern_mask_size); in pvr_fw_get_device_info()
187 dev_info += header->ern_mask_size; in pvr_fw_get_device_info()
189 return pvr_device_info_set_features(pvr_dev, dev_info, header->feature_mask_size, in pvr_fw_get_device_info()
190 header->feature_param_size); in pvr_fw_get_device_info()
196 const struct pvr_fw_layout_entry *layout_entries = pvr_dev->fw_dev.layout_entries; in layout_get_sizes()
197 u32 num_layout_entries = pvr_dev->fw_dev.header->layout_entry_num; in layout_get_sizes()
198 struct pvr_fw_mem *fw_mem = &pvr_dev->fw_dev.mem; in layout_get_sizes()
200 fw_mem->code_alloc_size = 0; in layout_get_sizes()
201 fw_mem->data_alloc_size = 0; in layout_get_sizes()
202 fw_mem->core_code_alloc_size = 0; in layout_get_sizes()
203 fw_mem->core_data_alloc_size = 0; in layout_get_sizes()
209 fw_mem->code_alloc_size += layout_entries[entry].alloc_size; in layout_get_sizes()
212 fw_mem->data_alloc_size += layout_entries[entry].alloc_size; in layout_get_sizes()
215 fw_mem->core_code_alloc_size += in layout_get_sizes()
219 fw_mem->core_data_alloc_size += in layout_get_sizes()
233 const struct pvr_fw_layout_entry *layout_entries = pvr_dev->fw_dev.layout_entries; in pvr_fw_find_mmu_segment()
234 u32 num_layout_entries = pvr_dev->fw_dev.header->layout_entry_num; in pvr_fw_find_mmu_segment()
240 return -EINVAL; in pvr_fw_find_mmu_segment()
266 return -EINVAL; in pvr_fw_find_mmu_segment()
269 addr -= layout_entries[entry].base_addr; in pvr_fw_find_mmu_segment()
281 return -EINVAL; in pvr_fw_find_mmu_segment()
288 struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; in pvr_fw_create_fwif_connection_ctl()
290 fw_dev->fwif_connection_ctl = in pvr_fw_create_fwif_connection_ctl()
292 fw_dev->fw_heap_info.config_offset + in pvr_fw_create_fwif_connection_ctl()
294 sizeof(*fw_dev->fwif_connection_ctl), in pvr_fw_create_fwif_connection_ctl()
297 &fw_dev->mem.fwif_connection_ctl_obj); in pvr_fw_create_fwif_connection_ctl()
298 if (IS_ERR(fw_dev->fwif_connection_ctl)) { in pvr_fw_create_fwif_connection_ctl()
301 return PTR_ERR(fw_dev->fwif_connection_ctl); in pvr_fw_create_fwif_connection_ctl()
310 struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; in pvr_fw_fini_fwif_connection_ctl()
312 pvr_fw_object_unmap_and_destroy(fw_dev->mem.fwif_connection_ctl_obj); in pvr_fw_fini_fwif_connection_ctl()
320 struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; in fw_osinit_init()
321 struct pvr_fw_mem *fw_mem = &fw_dev->mem; in fw_osinit_init()
323 fwif_osinit->kernel_ccbctl_fw_addr = pvr_dev->kccb.ccb.ctrl_fw_addr; in fw_osinit_init()
324 fwif_osinit->kernel_ccb_fw_addr = pvr_dev->kccb.ccb.ccb_fw_addr; in fw_osinit_init()
325 pvr_fw_object_get_fw_addr(pvr_dev->kccb.rtn_obj, in fw_osinit_init()
326 &fwif_osinit->kernel_ccb_rtn_slots_fw_addr); in fw_osinit_init()
328 fwif_osinit->firmware_ccbctl_fw_addr = pvr_dev->fwccb.ctrl_fw_addr; in fw_osinit_init()
329 fwif_osinit->firmware_ccb_fw_addr = pvr_dev->fwccb.ccb_fw_addr; in fw_osinit_init()
331 fwif_osinit->work_est_firmware_ccbctl_fw_addr = 0; in fw_osinit_init()
332 fwif_osinit->work_est_firmware_ccb_fw_addr = 0; in fw_osinit_init()
334 pvr_fw_object_get_fw_addr(fw_mem->hwrinfobuf_obj, in fw_osinit_init()
335 &fwif_osinit->rogue_fwif_hwr_info_buf_ctl_fw_addr); in fw_osinit_init()
336 pvr_fw_object_get_fw_addr(fw_mem->osdata_obj, &fwif_osinit->fw_os_data_fw_addr); in fw_osinit_init()
338 fwif_osinit->hwr_debug_dump_limit = 0; in fw_osinit_init()
340 rogue_fwif_compchecks_bvnc_init(&fwif_osinit->rogue_comp_checks.hw_bvnc); in fw_osinit_init()
341 rogue_fwif_compchecks_bvnc_init(&fwif_osinit->rogue_comp_checks.fw_bvnc); in fw_osinit_init()
349 struct pvr_fw_mem *fw_mem = &pvr_dev->fw_dev.mem; in fw_osdata_init()
351 pvr_fw_object_get_fw_addr(fw_mem->power_sync_obj, &fwif_osdata->power_sync_fw_addr); in fw_osdata_init()
368 struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; in fw_sysinit_init()
369 struct pvr_fw_mem *fw_mem = &fw_dev->mem; in fw_sysinit_init()
371 u32 clock_speed_hz = clk_get_rate(pvr_dev->core_clk); in fw_sysinit_init()
375 WARN_ON(pvr_fw_object_get_dma_addr(fw_mem->fault_page_obj, 0, &fault_dma_addr)); in fw_sysinit_init()
376 fwif_sysinit->fault_phys_addr = (u64)fault_dma_addr; in fw_sysinit_init()
378 fwif_sysinit->pds_exec_base = ROGUE_PDSCODEDATA_HEAP_BASE; in fw_sysinit_init()
379 fwif_sysinit->usc_exec_base = ROGUE_USCCODE_HEAP_BASE; in fw_sysinit_init()
381 pvr_fw_object_get_fw_addr(fw_mem->runtime_cfg_obj, &fwif_sysinit->runtime_cfg_fw_addr); in fw_sysinit_init()
382 pvr_fw_object_get_fw_addr(fw_dev->fw_trace.tracebuf_ctrl_obj, in fw_sysinit_init()
383 &fwif_sysinit->trace_buf_ctl_fw_addr); in fw_sysinit_init()
384 pvr_fw_object_get_fw_addr(fw_mem->sysdata_obj, &fwif_sysinit->fw_sys_data_fw_addr); in fw_sysinit_init()
385 pvr_fw_object_get_fw_addr(fw_mem->gpu_util_fwcb_obj, in fw_sysinit_init()
386 &fwif_sysinit->gpu_util_fw_cb_ctl_fw_addr); in fw_sysinit_init()
387 if (fw_mem->core_data_obj) { in fw_sysinit_init()
388 pvr_fw_object_get_fw_addr(fw_mem->core_data_obj, in fw_sysinit_init()
389 &fwif_sysinit->coremem_data_store.fw_addr); in fw_sysinit_init()
393 fwif_sysinit->counter_dump_ctl.buffer_fw_addr = 0; in fw_sysinit_init()
394 fwif_sysinit->counter_dump_ctl.size_in_dwords = 0; in fw_sysinit_init()
397 fwif_sysinit->align_checks = 0; in fw_sysinit_init()
399 fwif_sysinit->filter_flags = 0; in fw_sysinit_init()
400 fwif_sysinit->hw_perf_filter = 0; in fw_sysinit_init()
401 fwif_sysinit->firmware_perf = FW_PERF_CONF_NONE; in fw_sysinit_init()
402 fwif_sysinit->initial_core_clock_speed = clock_speed_hz; in fw_sysinit_init()
403 fwif_sysinit->active_pm_latency_ms = 0; in fw_sysinit_init()
404 fwif_sysinit->gpio_validation_mode = ROGUE_FWIF_GPIO_VAL_OFF; in fw_sysinit_init()
405 fwif_sysinit->firmware_started = false; in fw_sysinit_init()
406 fwif_sysinit->marker_val = 1; in fw_sysinit_init()
408 memset(&fwif_sysinit->bvnc_km_feature_flags, 0, in fw_sysinit_init()
409 sizeof(fwif_sysinit->bvnc_km_feature_flags)); in fw_sysinit_init()
427 fwif_sysdata->config_flags = config_flags; in fw_sysdata_init()
435 u32 clock_speed_hz = clk_get_rate(pvr_dev->core_clk); in fw_runtime_cfg_init()
439 runtime_cfg->core_clock_speed = clock_speed_hz; in fw_runtime_cfg_init()
440 runtime_cfg->active_pm_latency_ms = 0; in fw_runtime_cfg_init()
441 runtime_cfg->active_pm_latency_persistant = true; in fw_runtime_cfg_init()
443 &runtime_cfg->default_dusts_num_init) != 0); in fw_runtime_cfg_init()
451 gpu_util_fwcb->last_word = PVR_FWIF_GPU_UTIL_STATE_IDLE; in fw_gpu_util_fwcb_init()
458 struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; in pvr_fw_create_structures()
459 struct pvr_fw_mem *fw_mem = &fw_dev->mem; in pvr_fw_create_structures()
462 fw_dev->power_sync = pvr_fw_object_create_and_map(pvr_dev, sizeof(*fw_dev->power_sync), in pvr_fw_create_structures()
464 NULL, NULL, &fw_mem->power_sync_obj); in pvr_fw_create_structures()
465 if (IS_ERR(fw_dev->power_sync)) { in pvr_fw_create_structures()
467 return PTR_ERR(fw_dev->power_sync); in pvr_fw_create_structures()
470 fw_dev->hwrinfobuf = pvr_fw_object_create_and_map(pvr_dev, sizeof(*fw_dev->hwrinfobuf), in pvr_fw_create_structures()
472 NULL, NULL, &fw_mem->hwrinfobuf_obj); in pvr_fw_create_structures()
473 if (IS_ERR(fw_dev->hwrinfobuf)) { in pvr_fw_create_structures()
476 err = PTR_ERR(fw_dev->hwrinfobuf); in pvr_fw_create_structures()
482 NULL, NULL, &fw_mem->mmucache_sync_obj); in pvr_fw_create_structures()
489 fw_dev->fwif_sysdata = pvr_fw_object_create_and_map(pvr_dev, in pvr_fw_create_structures()
490 sizeof(*fw_dev->fwif_sysdata), in pvr_fw_create_structures()
493 &fw_mem->sysdata_obj); in pvr_fw_create_structures()
494 if (IS_ERR(fw_dev->fwif_sysdata)) { in pvr_fw_create_structures()
496 err = PTR_ERR(fw_dev->fwif_sysdata); in pvr_fw_create_structures()
502 fw_fault_page_init, NULL, &fw_mem->fault_page_obj); in pvr_fw_create_structures()
510 fw_gpu_util_fwcb_init, pvr_dev, &fw_mem->gpu_util_fwcb_obj); in pvr_fw_create_structures()
512 drm_err(drm_dev, "Unable to allocate GPU util FWCB\n"); in pvr_fw_create_structures()
518 fw_runtime_cfg_init, pvr_dev, &fw_mem->runtime_cfg_obj); in pvr_fw_create_structures()
528 fw_dev->fwif_osdata = pvr_fw_object_create_and_map(pvr_dev, in pvr_fw_create_structures()
529 sizeof(*fw_dev->fwif_osdata), in pvr_fw_create_structures()
532 &fw_mem->osdata_obj); in pvr_fw_create_structures()
533 if (IS_ERR(fw_dev->fwif_osdata)) { in pvr_fw_create_structures()
535 err = PTR_ERR(fw_dev->fwif_osdata); in pvr_fw_create_structures()
539 fw_dev->fwif_osinit = in pvr_fw_create_structures()
541 fw_dev->fw_heap_info.config_offset + in pvr_fw_create_structures()
543 sizeof(*fw_dev->fwif_osinit), in pvr_fw_create_structures()
545 fw_osinit_init, pvr_dev, &fw_mem->osinit_obj); in pvr_fw_create_structures()
546 if (IS_ERR(fw_dev->fwif_osinit)) { in pvr_fw_create_structures()
548 err = PTR_ERR(fw_dev->fwif_osinit); in pvr_fw_create_structures()
552 fw_dev->fwif_sysinit = in pvr_fw_create_structures()
554 fw_dev->fw_heap_info.config_offset + in pvr_fw_create_structures()
556 sizeof(*fw_dev->fwif_sysinit), in pvr_fw_create_structures()
558 fw_sysinit_init, pvr_dev, &fw_mem->sysinit_obj); in pvr_fw_create_structures()
559 if (IS_ERR(fw_dev->fwif_sysinit)) { in pvr_fw_create_structures()
561 err = PTR_ERR(fw_dev->fwif_sysinit); in pvr_fw_create_structures()
568 pvr_fw_object_unmap_and_destroy(fw_mem->osinit_obj); in pvr_fw_create_structures()
571 pvr_fw_object_unmap_and_destroy(fw_mem->osdata_obj); in pvr_fw_create_structures()
577 pvr_fw_object_destroy(fw_mem->runtime_cfg_obj); in pvr_fw_create_structures()
580 pvr_fw_object_destroy(fw_mem->gpu_util_fwcb_obj); in pvr_fw_create_structures()
583 pvr_fw_object_destroy(fw_mem->fault_page_obj); in pvr_fw_create_structures()
586 pvr_fw_object_unmap_and_destroy(fw_mem->sysdata_obj); in pvr_fw_create_structures()
589 pvr_fw_object_destroy(fw_mem->mmucache_sync_obj); in pvr_fw_create_structures()
592 pvr_fw_object_unmap_and_destroy(fw_mem->hwrinfobuf_obj); in pvr_fw_create_structures()
595 pvr_fw_object_unmap_and_destroy(fw_mem->power_sync_obj); in pvr_fw_create_structures()
603 struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; in pvr_fw_destroy_structures()
604 struct pvr_fw_mem *fw_mem = &fw_dev->mem; in pvr_fw_destroy_structures()
607 pvr_fw_object_destroy(fw_mem->runtime_cfg_obj); in pvr_fw_destroy_structures()
608 pvr_fw_object_destroy(fw_mem->gpu_util_fwcb_obj); in pvr_fw_destroy_structures()
609 pvr_fw_object_destroy(fw_mem->fault_page_obj); in pvr_fw_destroy_structures()
610 pvr_fw_object_unmap_and_destroy(fw_mem->sysdata_obj); in pvr_fw_destroy_structures()
611 pvr_fw_object_unmap_and_destroy(fw_mem->sysinit_obj); in pvr_fw_destroy_structures()
613 pvr_fw_object_destroy(fw_mem->mmucache_sync_obj); in pvr_fw_destroy_structures()
614 pvr_fw_object_unmap_and_destroy(fw_mem->hwrinfobuf_obj); in pvr_fw_destroy_structures()
615 pvr_fw_object_unmap_and_destroy(fw_mem->power_sync_obj); in pvr_fw_destroy_structures()
616 pvr_fw_object_unmap_and_destroy(fw_mem->osdata_obj); in pvr_fw_destroy_structures()
617 pvr_fw_object_unmap_and_destroy(fw_mem->osinit_obj); in pvr_fw_destroy_structures()
621 * pvr_fw_process() - Process firmware image, allocate FW memory and create boot
634 struct pvr_fw_mem *fw_mem = &pvr_dev->fw_dev.mem; in pvr_fw_process()
635 const u8 *fw = pvr_dev->fw_dev.firmware->data; in pvr_fw_process()
647 return -EINVAL; in pvr_fw_process()
655 * This has the useful side-effect that for every other object in the in pvr_fw_process()
658 fw_code_ptr = pvr_fw_object_create_and_map_offset(pvr_dev, 0, fw_mem->code_alloc_size, in pvr_fw_process()
660 NULL, NULL, &fw_mem->code_obj); in pvr_fw_process()
666 if (pvr_dev->fw_dev.defs->has_fixed_data_addr()) { in pvr_fw_process()
667 u32 base_addr = private_data->base_addr & pvr_dev->fw_dev.fw_heap_info.offset_mask; in pvr_fw_process()
671 fw_mem->data_alloc_size, in pvr_fw_process()
673 NULL, NULL, &fw_mem->data_obj); in pvr_fw_process()
675 fw_data_ptr = pvr_fw_object_create_and_map(pvr_dev, fw_mem->data_alloc_size, in pvr_fw_process()
677 NULL, NULL, &fw_mem->data_obj); in pvr_fw_process()
686 if (fw_mem->core_code_alloc_size) { in pvr_fw_process()
688 pvr_fw_object_create_and_map(pvr_dev, fw_mem->core_code_alloc_size, in pvr_fw_process()
690 NULL, NULL, &fw_mem->core_code_obj); in pvr_fw_process()
701 if (fw_mem->core_data_alloc_size) { in pvr_fw_process()
703 pvr_fw_object_create_and_map(pvr_dev, fw_mem->core_data_alloc_size, in pvr_fw_process()
705 NULL, NULL, &fw_mem->core_data_obj); in pvr_fw_process()
716 fw_mem->code = kzalloc(fw_mem->code_alloc_size, GFP_KERNEL); in pvr_fw_process()
717 fw_mem->data = kzalloc(fw_mem->data_alloc_size, GFP_KERNEL); in pvr_fw_process()
718 if (fw_mem->core_code_alloc_size) in pvr_fw_process()
719 fw_mem->core_code = kzalloc(fw_mem->core_code_alloc_size, GFP_KERNEL); in pvr_fw_process()
720 if (fw_mem->core_data_alloc_size) in pvr_fw_process()
721 fw_mem->core_data = kzalloc(fw_mem->core_data_alloc_size, GFP_KERNEL); in pvr_fw_process()
723 if (!fw_mem->code || !fw_mem->data || in pvr_fw_process()
724 (!fw_mem->core_code && fw_mem->core_code_alloc_size) || in pvr_fw_process()
725 (!fw_mem->core_data && fw_mem->core_data_alloc_size)) { in pvr_fw_process()
726 err = -ENOMEM; in pvr_fw_process()
730 err = pvr_dev->fw_dev.defs->fw_process(pvr_dev, fw, in pvr_fw_process()
731 fw_mem->code, fw_mem->data, fw_mem->core_code, in pvr_fw_process()
732 fw_mem->core_data, fw_mem->core_code_alloc_size); in pvr_fw_process()
737 memcpy(fw_code_ptr, fw_mem->code, fw_mem->code_alloc_size); in pvr_fw_process()
738 memcpy(fw_data_ptr, fw_mem->data, fw_mem->data_alloc_size); in pvr_fw_process()
739 if (fw_mem->core_code) in pvr_fw_process()
740 memcpy(fw_core_code_ptr, fw_mem->core_code, fw_mem->core_code_alloc_size); in pvr_fw_process()
741 if (fw_mem->core_data) in pvr_fw_process()
742 memcpy(fw_core_data_ptr, fw_mem->core_data, fw_mem->core_data_alloc_size); in pvr_fw_process()
746 pvr_fw_object_vunmap(fw_mem->core_data_obj); in pvr_fw_process()
748 pvr_fw_object_vunmap(fw_mem->core_code_obj); in pvr_fw_process()
749 pvr_fw_object_vunmap(fw_mem->data_obj); in pvr_fw_process()
751 pvr_fw_object_vunmap(fw_mem->code_obj); in pvr_fw_process()
761 kfree(fw_mem->core_data); in pvr_fw_process()
762 kfree(fw_mem->core_code); in pvr_fw_process()
763 kfree(fw_mem->data); in pvr_fw_process()
764 kfree(fw_mem->code); in pvr_fw_process()
768 pvr_fw_object_unmap_and_destroy(fw_mem->core_data_obj); in pvr_fw_process()
772 pvr_fw_object_unmap_and_destroy(fw_mem->core_code_obj); in pvr_fw_process()
776 pvr_fw_object_vunmap(fw_mem->data_obj); in pvr_fw_process()
777 pvr_fw_object_destroy(fw_mem->data_obj); in pvr_fw_process()
781 pvr_fw_object_vunmap(fw_mem->code_obj); in pvr_fw_process()
782 pvr_fw_object_destroy(fw_mem->code_obj); in pvr_fw_process()
805 struct pvr_fw_mem *fw_mem = &pvr_dev->fw_dev.mem; in pvr_fw_reinit_code_data()
808 err = pvr_copy_to_fw(fw_mem->code_obj, fw_mem->code, fw_mem->code_alloc_size); in pvr_fw_reinit_code_data()
812 err = pvr_copy_to_fw(fw_mem->data_obj, fw_mem->data, fw_mem->data_alloc_size); in pvr_fw_reinit_code_data()
816 if (fw_mem->core_code) { in pvr_fw_reinit_code_data()
817 err = pvr_copy_to_fw(fw_mem->core_code_obj, fw_mem->core_code, in pvr_fw_reinit_code_data()
818 fw_mem->core_code_alloc_size); in pvr_fw_reinit_code_data()
823 if (fw_mem->core_data) { in pvr_fw_reinit_code_data()
824 err = pvr_copy_to_fw(fw_mem->core_data_obj, fw_mem->core_data, in pvr_fw_reinit_code_data()
825 fw_mem->core_data_alloc_size); in pvr_fw_reinit_code_data()
836 struct pvr_fw_mem *fw_mem = &pvr_dev->fw_dev.mem; in pvr_fw_cleanup()
839 if (fw_mem->core_code_obj) in pvr_fw_cleanup()
840 pvr_fw_object_destroy(fw_mem->core_code_obj); in pvr_fw_cleanup()
841 if (fw_mem->core_data_obj) in pvr_fw_cleanup()
842 pvr_fw_object_destroy(fw_mem->core_data_obj); in pvr_fw_cleanup()
843 pvr_fw_object_destroy(fw_mem->code_obj); in pvr_fw_cleanup()
844 pvr_fw_object_destroy(fw_mem->data_obj); in pvr_fw_cleanup()
848 * pvr_wait_for_fw_boot() - Wait for firmware to finish booting
849 * @pvr_dev: Target PowerVR device.
853 * * -%ETIMEDOUT if firmware fails to boot within timeout.
859 struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; in pvr_wait_for_fw_boot()
862 if (READ_ONCE(fw_dev->fwif_sysinit->firmware_started)) in pvr_wait_for_fw_boot()
866 return -ETIMEDOUT; in pvr_wait_for_fw_boot()
870 * pvr_fw_heap_info_init() - Calculate size and masks for FW heap
871 * @pvr_dev: Target PowerVR device.
878 struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; in pvr_fw_heap_info_init()
880 fw_dev->fw_heap_info.gpu_addr = PVR_ROGUE_FW_MAIN_HEAP_BASE; in pvr_fw_heap_info_init()
881 fw_dev->fw_heap_info.log2_size = log2_size; in pvr_fw_heap_info_init()
882 fw_dev->fw_heap_info.reserved_size = reserved_size; in pvr_fw_heap_info_init()
883 fw_dev->fw_heap_info.raw_size = 1 << fw_dev->fw_heap_info.log2_size; in pvr_fw_heap_info_init()
884 fw_dev->fw_heap_info.offset_mask = fw_dev->fw_heap_info.raw_size - 1; in pvr_fw_heap_info_init()
885 fw_dev->fw_heap_info.config_offset = fw_dev->fw_heap_info.raw_size - in pvr_fw_heap_info_init()
887 fw_dev->fw_heap_info.size = fw_dev->fw_heap_info.raw_size - in pvr_fw_heap_info_init()
892 * pvr_fw_validate_init_device_info() - Validate firmware and initialise device information
893 * @pvr_dev: Target PowerVR device.
899 * * -%EINVAL if firmware validation fails.
914 * pvr_fw_init() - Initialise and boot firmware
915 * @pvr_dev: Target PowerVR device
917 * On successful completion of the function the PowerVR device will be
922 * * -%EINVAL on invalid firmware image,
923 * * -%ENOMEM on out of memory, or
924 * * -%ETIMEDOUT if firmware processor fails to boot or on register poll timeout.
930 u32 kccb_rtn_size = (1 << kccb_size_log2) * sizeof(*pvr_dev->kccb.rtn); in pvr_fw_init()
931 struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; in pvr_fw_init()
934 if (fw_dev->processor_type == PVR_FW_PROCESSOR_TYPE_META) in pvr_fw_init()
935 fw_dev->defs = &pvr_fw_defs_meta; in pvr_fw_init()
936 else if (fw_dev->processor_type == PVR_FW_PROCESSOR_TYPE_MIPS) in pvr_fw_init()
937 fw_dev->defs = &pvr_fw_defs_mips; in pvr_fw_init()
939 return -EINVAL; in pvr_fw_init()
941 err = fw_dev->defs->init(pvr_dev); in pvr_fw_init()
945 drm_mm_init(&fw_dev->fw_mm, ROGUE_FW_HEAP_BASE, fw_dev->fw_heap_info.raw_size); in pvr_fw_init()
946 fw_dev->fw_mm_base = ROGUE_FW_HEAP_BASE; in pvr_fw_init()
947 spin_lock_init(&fw_dev->fw_mm_lock); in pvr_fw_init()
949 INIT_LIST_HEAD(&fw_dev->fw_objs.list); in pvr_fw_init()
950 err = drmm_mutex_init(from_pvr_device(pvr_dev), &fw_dev->fw_objs.lock); in pvr_fw_init()
968 pvr_dev->kccb.rtn = pvr_fw_object_create_and_map(pvr_dev, kccb_rtn_size, in pvr_fw_init()
970 NULL, NULL, &pvr_dev->kccb.rtn_obj); in pvr_fw_init()
971 if (IS_ERR(pvr_dev->kccb.rtn)) { in pvr_fw_init()
972 err = PTR_ERR(pvr_dev->kccb.rtn); in pvr_fw_init()
990 fw_dev->booted = true; in pvr_fw_init()
1001 pvr_fw_object_unmap_and_destroy(pvr_dev->kccb.rtn_obj); in pvr_fw_init()
1004 pvr_ccb_fini(&pvr_dev->fwccb); in pvr_fw_init()
1013 drm_mm_takedown(&fw_dev->fw_mm); in pvr_fw_init()
1015 if (fw_dev->defs->fini) in pvr_fw_init()
1016 fw_dev->defs->fini(pvr_dev); in pvr_fw_init()
1022 * pvr_fw_fini() - Shutdown firmware processor and free associated memory
1023 * @pvr_dev: Target PowerVR device
1028 struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; in pvr_fw_fini()
1030 fw_dev->booted = false; in pvr_fw_fini()
1033 pvr_fw_object_unmap_and_destroy(pvr_dev->kccb.rtn_obj); in pvr_fw_fini()
1039 pvr_ccb_fini(&pvr_dev->fwccb); in pvr_fw_fini()
1043 mutex_lock(&pvr_dev->fw_dev.fw_objs.lock); in pvr_fw_fini()
1044 WARN_ON(!list_empty(&pvr_dev->fw_dev.fw_objs.list)); in pvr_fw_fini()
1045 mutex_unlock(&pvr_dev->fw_dev.fw_objs.lock); in pvr_fw_fini()
1047 drm_mm_takedown(&fw_dev->fw_mm); in pvr_fw_fini()
1049 if (fw_dev->defs->fini) in pvr_fw_fini()
1050 fw_dev->defs->fini(pvr_dev); in pvr_fw_fini()
1054 * pvr_fw_mts_schedule() - Schedule work via an MTS kick
1055 * @pvr_dev: Target PowerVR device
1071 * pvr_fw_structure_cleanup() - Send FW cleanup request for an object
1072 * @pvr_dev: Target PowerVR device.
1079 * * -EBUSY if object is busy,
1080 * * -ETIMEDOUT on timeout, or
1081 * * -EIO if device is lost.
1095 down_read(&pvr_dev->reset_sem); in pvr_fw_structure_cleanup()
1098 err = -EIO; in pvr_fw_structure_cleanup()
1104 cleanup_req->cleanup_type = type; in pvr_fw_structure_cleanup()
1109 &cleanup_req->cleanup_data.context_fw_addr); in pvr_fw_structure_cleanup()
1113 &cleanup_req->cleanup_data.hwrt_data_fw_addr); in pvr_fw_structure_cleanup()
1117 &cleanup_req->cleanup_data.freelist_fw_addr); in pvr_fw_structure_cleanup()
1120 err = -EINVAL; in pvr_fw_structure_cleanup()
1133 err = -EBUSY; in pvr_fw_structure_cleanup()
1139 up_read(&pvr_dev->reset_sem); in pvr_fw_structure_cleanup()
1145 * pvr_fw_object_fw_map() - Map a FW object in firmware address space
1153 * * -%EINVAL if @fw_obj is already mapped but has no references, or
1159 struct pvr_gem_object *pvr_obj = fw_obj->gem; in pvr_fw_object_fw_map()
1161 struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; in pvr_fw_object_fw_map()
1165 spin_lock(&fw_dev->fw_mm_lock); in pvr_fw_object_fw_map()
1167 if (drm_mm_node_allocated(&fw_obj->fw_mm_node)) { in pvr_fw_object_fw_map()
1168 err = -EINVAL; in pvr_fw_object_fw_map()
1177 err = drm_mm_insert_node_in_range(&fw_dev->fw_mm, &fw_obj->fw_mm_node, in pvr_fw_object_fw_map()
1178 gem_obj->size, 0, 0, in pvr_fw_object_fw_map()
1179 fw_dev->fw_heap_info.gpu_addr, in pvr_fw_object_fw_map()
1180 fw_dev->fw_heap_info.gpu_addr + in pvr_fw_object_fw_map()
1181 fw_dev->fw_heap_info.size, 0); in pvr_fw_object_fw_map()
1185 fw_obj->fw_mm_node.start = dev_addr; in pvr_fw_object_fw_map()
1186 fw_obj->fw_mm_node.size = gem_obj->size; in pvr_fw_object_fw_map()
1187 err = drm_mm_reserve_node(&fw_dev->fw_mm, &fw_obj->fw_mm_node); in pvr_fw_object_fw_map()
1192 spin_unlock(&fw_dev->fw_mm_lock); in pvr_fw_object_fw_map()
1194 /* Map object on GPU. */ in pvr_fw_object_fw_map()
1195 err = fw_dev->defs->vm_map(pvr_dev, fw_obj); in pvr_fw_object_fw_map()
1199 fw_obj->fw_addr_offset = (u32)(fw_obj->fw_mm_node.start - fw_dev->fw_mm_base); in pvr_fw_object_fw_map()
1204 spin_lock(&fw_dev->fw_mm_lock); in pvr_fw_object_fw_map()
1205 drm_mm_remove_node(&fw_obj->fw_mm_node); in pvr_fw_object_fw_map()
1208 spin_unlock(&fw_dev->fw_mm_lock); in pvr_fw_object_fw_map()
1214 * pvr_fw_object_fw_unmap() - Unmap a previously mapped FW object
1219 * * -%EINVAL if object is not currently mapped.
1224 struct pvr_gem_object *pvr_obj = fw_obj->gem; in pvr_fw_object_fw_unmap()
1226 struct pvr_device *pvr_dev = to_pvr_device(gem_obj->dev); in pvr_fw_object_fw_unmap()
1227 struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; in pvr_fw_object_fw_unmap()
1229 fw_dev->defs->vm_unmap(pvr_dev, fw_obj); in pvr_fw_object_fw_unmap()
1231 spin_lock(&fw_dev->fw_mm_lock); in pvr_fw_object_fw_unmap()
1233 if (!drm_mm_node_allocated(&fw_obj->fw_mm_node)) { in pvr_fw_object_fw_unmap()
1234 spin_unlock(&fw_dev->fw_mm_lock); in pvr_fw_object_fw_unmap()
1235 return -EINVAL; in pvr_fw_object_fw_unmap()
1238 drm_mm_remove_node(&fw_obj->fw_mm_node); in pvr_fw_object_fw_unmap()
1240 spin_unlock(&fw_dev->fw_mm_lock); in pvr_fw_object_fw_unmap()
1260 return ERR_PTR(-ENOMEM); in pvr_fw_object_create_and_map_common()
1262 INIT_LIST_HEAD(&fw_obj->node); in pvr_fw_object_create_and_map_common()
1263 fw_obj->init = init; in pvr_fw_object_create_and_map_common()
1264 fw_obj->init_priv = init_priv; in pvr_fw_object_create_and_map_common()
1266 fw_obj->gem = pvr_gem_object_create(pvr_dev, size, flags); in pvr_fw_object_create_and_map_common()
1267 if (IS_ERR(fw_obj->gem)) { in pvr_fw_object_create_and_map_common()
1268 err = PTR_ERR(fw_obj->gem); in pvr_fw_object_create_and_map_common()
1269 fw_obj->gem = NULL; in pvr_fw_object_create_and_map_common()
1285 if (fw_obj->init) in pvr_fw_object_create_and_map_common()
1286 fw_obj->init(cpu_ptr, fw_obj->init_priv); in pvr_fw_object_create_and_map_common()
1288 mutex_lock(&pvr_dev->fw_dev.fw_objs.lock); in pvr_fw_object_create_and_map_common()
1289 list_add_tail(&fw_obj->node, &pvr_dev->fw_dev.fw_objs.list); in pvr_fw_object_create_and_map_common()
1290 mutex_unlock(&pvr_dev->fw_dev.fw_objs.lock); in pvr_fw_object_create_and_map_common()
1301 * pvr_fw_object_create() - Create a FW object and map to firmware
1302 * @pvr_dev: PowerVR device pointer.
1337 * pvr_fw_object_create_and_map() - Create a FW object and map to firmware and CPU
1338 * @pvr_dev: PowerVR device pointer.
1369 * pvr_fw_object_create_and_map_offset() - Create a FW object and map to
1371 * @pvr_dev: PowerVR device pointer.
1399 u64 dev_addr = pvr_dev->fw_dev.fw_mm_base + dev_offset; in pvr_fw_object_create_and_map_offset()
1406 * pvr_fw_object_destroy() - Destroy a pvr_fw_object
1411 struct pvr_gem_object *pvr_obj = fw_obj->gem; in pvr_fw_object_destroy()
1413 struct pvr_device *pvr_dev = to_pvr_device(gem_obj->dev); in pvr_fw_object_destroy()
1415 mutex_lock(&pvr_dev->fw_dev.fw_objs.lock); in pvr_fw_object_destroy()
1416 list_del(&fw_obj->node); in pvr_fw_object_destroy()
1417 mutex_unlock(&pvr_dev->fw_dev.fw_objs.lock); in pvr_fw_object_destroy()
1419 if (drm_mm_node_allocated(&fw_obj->fw_mm_node)) { in pvr_fw_object_destroy()
1425 if (fw_obj->gem) in pvr_fw_object_destroy()
1426 pvr_gem_object_put(fw_obj->gem); in pvr_fw_object_destroy()
1432 * pvr_fw_object_get_fw_addr_offset() - Return address of object in firmware address space, with
1440 struct pvr_gem_object *pvr_obj = fw_obj->gem; in pvr_fw_object_get_fw_addr_offset()
1441 struct pvr_device *pvr_dev = to_pvr_device(gem_from_pvr_gem(pvr_obj)->dev); in pvr_fw_object_get_fw_addr_offset()
1443 *fw_addr_out = pvr_dev->fw_dev.defs->get_fw_addr_with_offset(fw_obj, offset); in pvr_fw_object_get_fw_addr_offset()
1447 * pvr_fw_hard_reset() - Re-initialise the FW code and data segments, and reset all global FW
1464 mutex_lock(&pvr_dev->fw_dev.fw_objs.lock); in pvr_fw_hard_reset()
1466 list_for_each(pos, &pvr_dev->fw_dev.fw_objs.list) { in pvr_fw_hard_reset()
1472 if (!(fw_obj->gem->flags & PVR_BO_FW_NO_CLEAR_ON_RESET)) { in pvr_fw_hard_reset()
1473 memset(cpu_ptr, 0, pvr_gem_object_size(fw_obj->gem)); in pvr_fw_hard_reset()
1475 if (fw_obj->init) in pvr_fw_hard_reset()
1476 fw_obj->init(cpu_ptr, fw_obj->init_priv); in pvr_fw_hard_reset()
1482 mutex_unlock(&pvr_dev->fw_dev.fw_objs.lock); in pvr_fw_hard_reset()