drivers/gpu/drm/etnaviv/etnaviv_flop_reset.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/etnaviv/etnaviv_flop_reset.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/etnaviv/etnaviv_flop_reset.c
Extension
.c
Size
6852 bytes
Lines
224
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 (!(chip_id->features & chipFeatures_PIPE_3D)) {
			pr_warn("Etnaviv: model: 0x%04x, revision: 0x%04x does not support PIPE_3D\n",
				chip_id->model, chip_id->revision);
			pr_warn("Request to force PPU flop reset ignored.\n");
			return false;
		}

		pr_info("Force PPU flop reset for model: 0x%04x, revision: 0x%04x\n",
			chip_id->model, chip_id->revision);
		return true;
	}

	return false;
}

static const u32 image_data_size = PPU_IMAGE_STRIDE * PPU_IMAGE_YSIZE;
static const u32 output_offset = ALIGN(image_data_size, 64);
static const u32 shader_offset = ALIGN(output_offset + image_data_size, 64);
static const u32 shader_size = PPU_FLOP_RESET_INSTR_DWORD_COUNT * sizeof(u32);
static const u32 shader_register_count = 3;
static const u32 buffer_size = shader_offset + shader_size;

int etnaviv_flop_reset_ppu_init(struct etnaviv_drm_private *priv)
{
	/* Get some space from the ring buffer to put the payload
	 * (input and output image, and shader), we keep this buffer
	 * for the whole life time the driver is bound
	 */
	priv->flop_reset_data_ppu = kzalloc_obj(*priv->flop_reset_data_ppu);

	if (!priv->flop_reset_data_ppu)
		return -ENOMEM;

	int ret = etnaviv_cmdbuf_init(priv->cmdbuf_suballoc,
				      priv->flop_reset_data_ppu, buffer_size);
	if (ret) {
		kfree(priv->flop_reset_data_ppu);
		return ret;
	}

	void *buffer_base = priv->flop_reset_data_ppu->vaddr;
	u32 *input_data = (u32 *)buffer_base;
	u8 *shader_data = (u8 *)buffer_base + shader_offset;

	etnaviv_flop_reset_ppu_fill_input(input_data, image_data_size);
	etnaviv_flop_reset_ppu_set_shader(shader_data);

	return 0;
}

void etnaviv_flop_reset_ppu_run(struct etnaviv_gpu *gpu)
{
	struct etnaviv_drm_private *priv = gpu->drm->dev_private;

	if (!priv->flop_reset_data_ppu) {
		dev_err(gpu->dev,
			"Oops: Flop reset data was not initialized, skipping\n");
		return;
	}

	u32 buffer_base = etnaviv_cmdbuf_get_va(priv->flop_reset_data_ppu,
						&gpu->mmu_context->cmdbuf_mapping);

	etnaviv_emit_flop_reset_state_ppu(&gpu->buffer, buffer_base, 0,
					  output_offset, shader_offset,
					  shader_size, shader_register_count);
}

Annotation

Implementation Notes