drivers/gpu/drm/imagination/pvr_fw_meta.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/imagination/pvr_fw_meta.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/imagination/pvr_fw_meta.c
Extension
.c
Size
16356 bytes
Lines
562
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (boot_conf) {
			u32 register_offset = config_command->block_data[0];
			u32 register_value = config_command->block_data[1];

			/* Do register write */
			add_boot_arg(&boot_conf, register_offset,
				     register_value);
		}

		curr_block_size = 12;
		l2_block_size -= curr_block_size;
		config_command = (struct rogue_meta_ldr_cfg_blk
					  *)((uintptr_t)config_command +
					     curr_block_size);
	}

	if (boot_conf_ptr)
		*boot_conf_ptr = boot_conf;

	return 0;
}

/**
 * process_ldr_command_stream() - Process LDR firmware image and populate
 *                                firmware sections
 * @pvr_dev: Device pointer.
 * @fw: Pointer to firmware image.
 * @fw_code_ptr: Pointer to FW code section.
 * @fw_data_ptr: Pointer to FW data section.
 * @fw_core_code_ptr: Pointer to FW coremem code section.
 * @fw_core_data_ptr: Pointer to FW coremem data section.
 * @boot_conf_ptr: Pointer to boot config argument pointer.
 *
 * Returns :
 *  * 0 on success, or
 *  * -EINVAL on any error in LDR command stream.
 */
static int
process_ldr_command_stream(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 **boot_conf_ptr)
{
	struct drm_device *drm_dev = from_pvr_device(pvr_dev);
	struct rogue_meta_ldr_block_hdr *ldr_header =
		(struct rogue_meta_ldr_block_hdr *)fw;
	struct rogue_meta_ldr_l1_data_blk *l1_data =
		(struct rogue_meta_ldr_l1_data_blk *)(fw + ldr_header->sl_data);
	const u32 fw_size = pvr_dev->fw_dev.firmware->size;
	int err;

	u32 *boot_conf = boot_conf_ptr ? *boot_conf_ptr : NULL;
	u32 coremem_size;

	err = PVR_FEATURE_VALUE(pvr_dev, meta_coremem_size, &coremem_size);
	if (err)
		return err;

	coremem_size *= SZ_1K;

	while (l1_data) {
		/* Verify block header is within bounds. */
		if (((u8 *)l1_data - fw) >= fw_size || ((u8 *)(l1_data + 1) - fw) >= fw_size)
			return -EINVAL;

		if (ROGUE_META_LDR_BLK_IS_COMMENT(l1_data->cmd)) {
			/* Don't process comment blocks */
			goto next_block;
		}

		switch (l1_data->cmd & ROGUE_META_LDR_CMD_MASK)
		case ROGUE_META_LDR_CMD_LOADMEM: {
			err = meta_ldr_cmd_loadmem(drm_dev, fw, l1_data,
						   coremem_size,
						   fw_code_ptr, fw_data_ptr,
						   fw_core_code_ptr,
						   fw_core_data_ptr, fw_size);
			if (err)
				return err;
			break;

		case ROGUE_META_LDR_CMD_START_THREADS:
			/* Don't process this block */
			break;

		case ROGUE_META_LDR_CMD_ZEROMEM:
			err = meta_ldr_cmd_zeromem(drm_dev, l1_data,
						   coremem_size,
						   fw_code_ptr, fw_data_ptr,
						   fw_core_code_ptr,
						   fw_core_data_ptr);

Annotation

Implementation Notes