drivers/gpu/drm/imagination/pvr_fw.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/imagination/pvr_fw.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/imagination/pvr_fw.c- Extension
.c- Size
- 44023 bytes
- Lines
- 1516
- Domain
- Driver Families
- Bucket
- drivers/gpu
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
pvr_ccb.hpvr_device.hpvr_device_info.hpvr_fw.hpvr_fw_info.hpvr_fw_startstop.hpvr_fw_trace.hpvr_gem.hpvr_power.hpvr_rogue_fwif_dev_info.hpvr_rogue_heap_config.hpvr_vm.hdrm/drm_drv.hdrm/drm_managed.hdrm/drm_mm.hdrm/drm_print.hlinux/clk.hlinux/firmware.hlinux/math.hlinux/minmax.hlinux/sizes.h
Detected Declarations
function pvr_fw_find_layout_entryfunction pvr_fw_find_private_datafunction pvr_fw_validatefunction pvr_fw_get_device_infofunction layout_get_sizesfunction pvr_fw_find_mmu_segmentfunction pvr_fw_create_fwif_connection_ctlfunction pvr_fw_fini_fwif_connection_ctlfunction fw_osinit_initfunction fw_osdata_initfunction fw_fault_page_initfunction fw_sysinit_initfunction fw_sysdata_initfunction fw_runtime_cfg_initfunction fw_gpu_util_fwcb_initfunction pvr_fw_create_structuresfunction pvr_fw_destroy_structuresfunction pvr_fw_processfunction pvr_copy_to_fwfunction pvr_fw_reinit_code_datafunction pvr_fw_cleanupfunction pvr_wait_for_fw_bootfunction pvr_fw_heap_info_initfunction pvr_fw_validate_init_device_infofunction pvr_fw_initfunction pvr_fw_finifunction pvr_fw_mts_schedulefunction pvr_fw_structure_cleanupfunction pvr_fw_object_fw_mapfunction pvr_fw_object_fw_unmapfunction pvr_fw_object_create_and_map_commonfunction pvr_fw_object_createfunction pvr_fw_object_create_and_mapfunction pvr_fw_object_create_and_map_offsetfunction pvr_fw_object_destroyfunction pvr_fw_object_get_fw_addr_offsetfunction pvr_fw_obj_get_gpu_addrfunction pvr_fw_hard_resetfunction list_for_each
Annotated Snippet
switch (layout_entries[entry].type) {
case FW_CODE:
fw_mem->code_alloc_size += layout_entries[entry].alloc_size;
break;
case FW_DATA:
fw_mem->data_alloc_size += layout_entries[entry].alloc_size;
break;
case FW_COREMEM_CODE:
fw_mem->core_code_alloc_size +=
layout_entries[entry].alloc_size;
break;
case FW_COREMEM_DATA:
fw_mem->core_data_alloc_size +=
layout_entries[entry].alloc_size;
break;
case NONE:
break;
}
}
}
int
pvr_fw_find_mmu_segment(struct pvr_device *pvr_dev, u32 addr, u32 size, void *fw_code_ptr,
void *fw_data_ptr, void *fw_core_code_ptr, void *fw_core_data_ptr,
void **host_addr_out)
{
const struct pvr_fw_layout_entry *layout_entries = pvr_dev->fw_dev.layout_entries;
u32 num_layout_entries = pvr_dev->fw_dev.header->layout_entry_num;
u32 end_addr = addr + size;
/* Ensure requested range is not zero, and size is not causing addr to overflow. */
if (end_addr <= addr)
return -EINVAL;
for (int entry = 0; entry < num_layout_entries; entry++) {
u32 entry_start_addr = layout_entries[entry].base_addr;
u32 entry_end_addr = entry_start_addr + layout_entries[entry].alloc_size;
if (addr >= entry_start_addr && addr < entry_end_addr &&
end_addr > entry_start_addr && end_addr <= entry_end_addr) {
switch (layout_entries[entry].type) {
case FW_CODE:
*host_addr_out = fw_code_ptr;
break;
case FW_DATA:
*host_addr_out = fw_data_ptr;
break;
case FW_COREMEM_CODE:
*host_addr_out = fw_core_code_ptr;
break;
case FW_COREMEM_DATA:
*host_addr_out = fw_core_data_ptr;
break;
default:
return -EINVAL;
}
/* Direct Mem write to mapped memory */
addr -= layout_entries[entry].base_addr;
addr += layout_entries[entry].alloc_offset;
/*
* Add offset to pointer to FW allocation only if that
* allocation is available
*/
*(u8 **)host_addr_out += addr;
return 0;
}
}
return -EINVAL;
}
static int
pvr_fw_create_fwif_connection_ctl(struct pvr_device *pvr_dev)
{
struct drm_device *drm_dev = from_pvr_device(pvr_dev);
struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev;
fw_dev->fwif_connection_ctl =
pvr_fw_object_create_and_map_offset(pvr_dev,
fw_dev->fw_heap_info.config_offset +
PVR_ROGUE_FWIF_CONNECTION_CTL_OFFSET,
sizeof(*fw_dev->fwif_connection_ctl),
PVR_BO_FW_FLAGS_DEVICE_UNCACHED,
NULL, NULL,
&fw_dev->mem.fwif_connection_ctl_obj);
Annotation
- Immediate include surface: `pvr_ccb.h`, `pvr_device.h`, `pvr_device_info.h`, `pvr_fw.h`, `pvr_fw_info.h`, `pvr_fw_startstop.h`, `pvr_fw_trace.h`, `pvr_gem.h`.
- Detected declarations: `function pvr_fw_find_layout_entry`, `function pvr_fw_find_private_data`, `function pvr_fw_validate`, `function pvr_fw_get_device_info`, `function layout_get_sizes`, `function pvr_fw_find_mmu_segment`, `function pvr_fw_create_fwif_connection_ctl`, `function pvr_fw_fini_fwif_connection_ctl`, `function fw_osinit_init`, `function fw_osdata_init`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.