drivers/gpu/drm/panthor/panthor_gpu.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/panthor/panthor_gpu.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/panthor/panthor_gpu.c
Extension
.c
Size
13609 bytes
Lines
483
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

struct panthor_gpu {
	/** @iomem: CPU mapping of GPU_CONTROL iomem region */
	void __iomem *iomem;

	/** @irq: GPU irq. */
	struct panthor_irq irq;

	/** @reqs_lock: Lock protecting access to pending_reqs. */
	spinlock_t reqs_lock;

	/** @pending_reqs: Pending GPU requests. */
	u32 pending_reqs;

	/** @reqs_acked: GPU request wait queue. */
	wait_queue_head_t reqs_acked;

	/** @cache_flush_lock: Lock to serialize cache flushes */
	struct mutex cache_flush_lock;
};

#define GPU_INTERRUPTS_MASK	\
	(GPU_IRQ_FAULT | \
	 GPU_IRQ_PROTM_FAULT | \
	 GPU_IRQ_RESET_COMPLETED | \
	 GPU_IRQ_CLEAN_CACHES_COMPLETED)

#define GPU_POWER_INTERRUPTS_MASK	\
	(GPU_IRQ_POWER_CHANGED | GPU_IRQ_POWER_CHANGED_ALL)

static void panthor_gpu_coherency_set(struct panthor_device *ptdev)
{
	gpu_write(ptdev->gpu->iomem, GPU_COHERENCY_PROTOCOL,
		  ptdev->gpu_info.selected_coherency);
}

static void panthor_gpu_l2_config_set(struct panthor_device *ptdev)
{
	struct panthor_gpu *gpu = ptdev->gpu;
	const struct panthor_soc_data *data = ptdev->soc_data;
	u32 l2_config;
	u32 i;

	if (!data || !data->asn_hash_enable)
		return;

	if (GPU_ARCH_MAJOR(ptdev->gpu_info.gpu_id) < 11) {
		drm_err(&ptdev->base, "Custom ASN hash not supported by the device");
		return;
	}

	for (i = 0; i < ARRAY_SIZE(data->asn_hash); i++)
		gpu_write(gpu->iomem, GPU_ASN_HASH(i), data->asn_hash[i]);

	l2_config = gpu_read(gpu->iomem, GPU_L2_CONFIG);
	l2_config |= GPU_L2_CONFIG_ASN_HASH_ENABLE;
	gpu_write(gpu->iomem, GPU_L2_CONFIG, l2_config);
}

static void panthor_gpu_irq_handler(struct panthor_device *ptdev, u32 status)
{
	struct panthor_gpu *gpu = ptdev->gpu;

	gpu_write(gpu->irq.iomem, INT_CLEAR, status);

	if (tracepoint_enabled(gpu_power_status) && (status & GPU_POWER_INTERRUPTS_MASK))
		trace_gpu_power_status(ptdev->base.dev,
				       gpu_read64(gpu->iomem, SHADER_READY),
				       gpu_read64(gpu->iomem, TILER_READY),
				       gpu_read64(gpu->iomem, L2_READY));

	if (status & GPU_IRQ_FAULT) {
		u32 fault_status = gpu_read(gpu->iomem, GPU_FAULT_STATUS);
		u64 address = gpu_read64(gpu->iomem, GPU_FAULT_ADDR);

		drm_warn(&ptdev->base, "GPU Fault 0x%08x (%s) at 0x%016llx\n",
			 fault_status, panthor_exception_name(ptdev, fault_status & 0xFF),
			 address);
	}
	if (status & GPU_IRQ_PROTM_FAULT)
		drm_warn(&ptdev->base, "GPU Fault in protected mode\n");

	spin_lock(&ptdev->gpu->reqs_lock);
	if (status & ptdev->gpu->pending_reqs) {
		ptdev->gpu->pending_reqs &= ~status;
		wake_up_all(&ptdev->gpu->reqs_acked);
	}
	spin_unlock(&ptdev->gpu->reqs_lock);
}
PANTHOR_IRQ_HANDLER(gpu, panthor_gpu_irq_handler);

Annotation

Implementation Notes