drivers/gpu/drm/imagination/pvr_fw_mips.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/imagination/pvr_fw_mips.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/imagination/pvr_fw_mips.c- Extension
.c- Size
- 6911 bytes
- Lines
- 200
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
pvr_device.hpvr_fw.hpvr_fw_mips.hpvr_gem.hpvr_rogue_mips.hpvr_vm_mips.hlinux/err.hlinux/types.h
Detected Declarations
function pvr_mips_initfunction pvr_mips_finifunction pvr_mips_fw_processfunction pvr_mips_wrapper_initfunction pvr_mips_get_fw_addr_with_offsetfunction pvr_mips_irq_pendingfunction pvr_mips_irq_clear
Annotated Snippet
// SPDX-License-Identifier: GPL-2.0-only OR MIT
/* Copyright (c) 2023 Imagination Technologies Ltd. */
#include "pvr_device.h"
#include "pvr_fw.h"
#include "pvr_fw_mips.h"
#include "pvr_gem.h"
#include "pvr_rogue_mips.h"
#include "pvr_vm_mips.h"
#include <linux/err.h>
#include <linux/types.h>
#define ROGUE_FW_HEAP_MIPS_BASE 0xC0000000
#define ROGUE_FW_HEAP_MIPS_SHIFT 24 /* 16 MB */
#define ROGUE_FW_HEAP_MIPS_RESERVED_SIZE SZ_1M
static int
pvr_mips_init(struct pvr_device *pvr_dev)
{
pvr_fw_heap_info_init(pvr_dev, ROGUE_FW_HEAP_MIPS_SHIFT, ROGUE_FW_HEAP_MIPS_RESERVED_SIZE);
return pvr_vm_mips_init(pvr_dev);
}
static void
pvr_mips_fini(struct pvr_device *pvr_dev)
{
pvr_vm_mips_fini(pvr_dev);
}
static int
pvr_mips_fw_process(struct pvr_device *pvr_dev, const u8 *fw,
u8 *fw_code_ptr, u8 *fw_data_ptr, u8 *fw_core_code_ptr, u8 *fw_core_data_ptr,
u32 core_code_alloc_size)
{
struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev;
struct pvr_fw_mips_data *mips_data = fw_dev->processor_data.mips_data;
const struct pvr_fw_layout_entry *boot_code_entry;
const struct pvr_fw_layout_entry *boot_data_entry;
const struct pvr_fw_layout_entry *exception_code_entry;
const struct pvr_fw_layout_entry *stack_entry;
struct rogue_mipsfw_boot_data *boot_data;
dma_addr_t dma_addr;
int err;
err = pvr_fw_process_elf_command_stream(pvr_dev, fw, fw_code_ptr, fw_data_ptr,
fw_core_code_ptr, fw_core_data_ptr);
if (err)
return err;
boot_code_entry = pvr_fw_find_layout_entry(pvr_dev, MIPS_BOOT_CODE);
boot_data_entry = pvr_fw_find_layout_entry(pvr_dev, MIPS_BOOT_DATA);
exception_code_entry = pvr_fw_find_layout_entry(pvr_dev, MIPS_EXCEPTIONS_CODE);
if (!boot_code_entry || !boot_data_entry || !exception_code_entry)
return -EINVAL;
WARN_ON(pvr_gem_get_dma_addr(fw_dev->mem.code_obj->gem, boot_code_entry->alloc_offset,
&mips_data->boot_code_dma_addr));
WARN_ON(pvr_gem_get_dma_addr(fw_dev->mem.data_obj->gem, boot_data_entry->alloc_offset,
&mips_data->boot_data_dma_addr));
WARN_ON(pvr_gem_get_dma_addr(fw_dev->mem.code_obj->gem,
exception_code_entry->alloc_offset,
&mips_data->exception_code_dma_addr));
stack_entry = pvr_fw_find_layout_entry(pvr_dev, MIPS_STACK);
if (!stack_entry)
return -EINVAL;
boot_data = (struct rogue_mipsfw_boot_data *)(fw_data_ptr + boot_data_entry->alloc_offset +
ROGUE_MIPSFW_BOOTLDR_CONF_OFFSET);
WARN_ON(pvr_fw_object_get_dma_addr(fw_dev->mem.data_obj, stack_entry->alloc_offset,
&dma_addr));
boot_data->stack_phys_addr = dma_addr;
boot_data->reg_base = pvr_dev->regs_resource->start;
for (u32 page_nr = 0; page_nr < ARRAY_SIZE(boot_data->pt_phys_addr); page_nr++) {
/* Firmware expects 4k pages, but host page size might be different. */
u32 src_page_nr = (page_nr * ROGUE_MIPSFW_PAGE_SIZE_4K) >> PAGE_SHIFT;
u32 page_offset = (page_nr * ROGUE_MIPSFW_PAGE_SIZE_4K) & ~PAGE_MASK;
boot_data->pt_phys_addr[page_nr] = mips_data->pt_dma_addr[src_page_nr] +
page_offset;
}
boot_data->pt_log2_page_size = ROGUE_MIPSFW_LOG2_PAGE_SIZE_4K;
boot_data->pt_num_pages = ROGUE_MIPSFW_MAX_NUM_PAGETABLE_PAGES;
boot_data->reserved1 = 0;
Annotation
- Immediate include surface: `pvr_device.h`, `pvr_fw.h`, `pvr_fw_mips.h`, `pvr_gem.h`, `pvr_rogue_mips.h`, `pvr_vm_mips.h`, `linux/err.h`, `linux/types.h`.
- Detected declarations: `function pvr_mips_init`, `function pvr_mips_fini`, `function pvr_mips_fw_process`, `function pvr_mips_wrapper_init`, `function pvr_mips_get_fw_addr_with_offset`, `function pvr_mips_irq_pending`, `function pvr_mips_irq_clear`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: source implementation candidate.
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.