Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6f79885a authored by Harshdeep Dhatt's avatar Harshdeep Dhatt
Browse files

msm: kgsl: Capture gpu globals in hwsched snapshot



Capture ringbuffers, smmu info record, scratch memory and
preemption records into hw scheduling snapshot.

Change-Id: I119cc18115f3a74a6a26c976772b7d746e70900e
Signed-off-by: default avatarHarshdeep Dhatt <hdhatt@codeaurora.org>
parent b2f0a442
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -13,6 +13,9 @@
#include "adreno_a6xx_gmu.h"
#include "adreno_a6xx_rgmu.h"

/* Snapshot section size of each CP preemption record for A6XX  */
#define A6XX_SNAPSHOT_CP_CTXRECORD_SIZE_IN_BYTES (64 * 1024)

extern const struct adreno_power_ops a6xx_gmu_power_ops;
extern const struct adreno_power_ops a6xx_rgmu_power_ops;
extern const struct adreno_power_ops a630_gmu_power_ops;
+112 −1
Original line number Diff line number Diff line
@@ -11,16 +11,127 @@
#include "adreno.h"
#include "adreno_a6xx.h"
#include "adreno_a6xx_hwsched.h"
#include "adreno_snapshot.h"
#include "kgsl_device.h"
#include "kgsl_trace.h"
#include "kgsl_util.h"

static size_t adreno_hwsched_snapshot_rb(struct kgsl_device *device, u8 *buf,
	size_t remain, void *priv)
{
	struct kgsl_snapshot_rb_v2 *header = (struct kgsl_snapshot_rb_v2 *)buf;
	u32 *data = (u32 *)(buf + sizeof(*header));
	struct kgsl_memdesc *rb = (struct kgsl_memdesc *)priv;

	if (remain < rb->size + sizeof(*header)) {
		SNAPSHOT_ERR_NOMEM(device, "RB");
		return 0;
	}

	header->start = 0;
	header->end = rb->size >> 2;
	header->rptr = 0;
	header->rbsize = rb->size >> 2;
	header->count = rb->size >> 2;
	header->timestamp_queued = 0;
	header->timestamp_retired = 0;
	header->gpuaddr = rb->gpuaddr;
	header->id = 0;

	memcpy(data, rb->hostptr, rb->size);

	return rb->size + sizeof(*header);
}

static void a6xx_hwsched_snapshot_preemption_record(struct kgsl_device *device,
	struct kgsl_snapshot *snapshot, struct kgsl_memdesc *md, u64 offset)
{
	struct kgsl_snapshot_section_header *section_header =
		(struct kgsl_snapshot_section_header *)snapshot->ptr;
	u8 *dest = snapshot->ptr + sizeof(*section_header);
	struct kgsl_snapshot_gpu_object_v2 *header =
		(struct kgsl_snapshot_gpu_object_v2 *)dest;
	size_t section_size = sizeof(*section_header) + sizeof(*header) +
		A6XX_SNAPSHOT_CP_CTXRECORD_SIZE_IN_BYTES;

	if (snapshot->remain < section_size) {
		SNAPSHOT_ERR_NOMEM(device, "PREEMPTION RECORD");
		return;
	}

	section_header->magic = SNAPSHOT_SECTION_MAGIC;
	section_header->id = KGSL_SNAPSHOT_SECTION_GPU_OBJECT_V2;
	section_header->size = section_size;

	header->size = A6XX_SNAPSHOT_CP_CTXRECORD_SIZE_IN_BYTES >> 2;
	header->gpuaddr = md->gpuaddr + offset;
	header->ptbase =
		kgsl_mmu_pagetable_get_ttbr0(device->mmu.defaultpagetable);
	header->type = SNAPSHOT_GPU_OBJECT_GLOBAL;

	dest += sizeof(*header);

	memcpy(dest, md->hostptr + offset,
		A6XX_SNAPSHOT_CP_CTXRECORD_SIZE_IN_BYTES);

	snapshot->ptr += section_header->size;
	snapshot->remain -= section_header->size;
	snapshot->size += section_header->size;
}

static void snapshot_preemption_records(struct kgsl_device *device,
	struct kgsl_snapshot *snapshot, struct kgsl_memdesc *md)
{
	const struct adreno_a6xx_core *a6xx_core =
		to_a6xx_core(ADRENO_DEVICE(device));
	u64 ctxt_record_size = A6XX_CP_CTXRECORD_SIZE_IN_BYTES;
	u64 offset;

	if (a6xx_core->ctxt_record_size)
		ctxt_record_size = a6xx_core->ctxt_record_size;

	/* All preemption records exist as a single mem alloc entry */
	for (offset = 0; offset < md->size; offset += ctxt_record_size)
		a6xx_hwsched_snapshot_preemption_record(device, snapshot, md,
			offset);
}

void a6xx_hwsched_snapshot(struct adreno_device *adreno_dev,
	struct kgsl_snapshot *snapshot)
{
	adreno_hwsched_parse_fault_cmdobj(adreno_dev, snapshot);
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	struct a6xx_hwsched_hfi *hw_hfi = to_a6xx_hwsched_hfi(adreno_dev);
	u32 i;

	a6xx_gmu_snapshot(adreno_dev, snapshot);

	for (i = 0; i < hw_hfi->mem_alloc_entries; i++) {
		struct mem_alloc_entry *entry = &hw_hfi->mem_alloc_table[i];

		if (entry->desc.mem_kind == MEMKIND_RB)
			kgsl_snapshot_add_section(device,
				KGSL_SNAPSHOT_SECTION_RB_V2,
				snapshot, adreno_hwsched_snapshot_rb,
				entry->gpu_md);

		if (entry->desc.mem_kind == MEMKIND_SCRATCH)
			kgsl_snapshot_add_section(device,
				KGSL_SNAPSHOT_SECTION_GPU_OBJECT_V2,
				snapshot, adreno_snapshot_global,
				entry->gpu_md);

		if (entry->desc.mem_kind == MEMKIND_CSW_SMMU_INFO)
			kgsl_snapshot_add_section(device,
				KGSL_SNAPSHOT_SECTION_GPU_OBJECT_V2,
				snapshot, adreno_snapshot_global,
				entry->gpu_md);

		if (entry->desc.mem_kind == MEMKIND_CSW_PRIV_NON_SECURE)
			snapshot_preemption_records(device, snapshot,
				entry->gpu_md);
	}

	adreno_hwsched_parse_fault_cmdobj(adreno_dev, snapshot);
}

static int a6xx_hwsched_gmu_first_boot(struct adreno_device *adreno_dev)
+0 −3
Original line number Diff line number Diff line
@@ -12,9 +12,6 @@
#define A6XX_NUM_XIN_AXI_BLOCKS 5
#define A6XX_NUM_XIN_CORE_BLOCKS 4

/* Snapshot section size of each CP preemption record for A6XX  */
#define A6XX_SNAPSHOT_CP_CTXRECORD_SIZE_IN_BYTES (64 * 1024)

static const unsigned int a6xx_gras_cluster[] = {
	0x8000, 0x8006, 0x8010, 0x8092, 0x8094, 0x809D, 0x80A0, 0x80A6,
	0x80AF, 0x80F1, 0x8100, 0x8107, 0x8109, 0x8109, 0x8110, 0x8110,
+5 −5
Original line number Diff line number Diff line
@@ -736,7 +736,7 @@ static void setup_fault_process(struct kgsl_device *device,
}

/* Snapshot a global memory buffer */
static size_t snapshot_global(struct kgsl_device *device, u8 *buf,
size_t adreno_snapshot_global(struct kgsl_device *device, u8 *buf,
	size_t remain, void *priv)
{
	struct kgsl_memdesc *memdesc = priv;
@@ -780,12 +780,12 @@ static void adreno_snapshot_iommu(struct kgsl_device *device,
	struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device);

	kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_GPU_OBJECT_V2,
		snapshot, snapshot_global, iommu->setstate);
		snapshot, adreno_snapshot_global, iommu->setstate);

	if (ADRENO_FEATURE(adreno_dev, ADRENO_PREEMPTION))
		kgsl_snapshot_add_section(device,
			KGSL_SNAPSHOT_SECTION_GPU_OBJECT_V2,
			snapshot, snapshot_global, iommu->smmu_info);
			snapshot, adreno_snapshot_global, iommu->smmu_info);
}

static void adreno_snapshot_ringbuffer(struct kgsl_device *device,
@@ -848,10 +848,10 @@ void adreno_snapshot(struct kgsl_device *device, struct kgsl_snapshot *snapshot,

	/* Dump selected global buffers */
	kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_GPU_OBJECT_V2,
			snapshot, snapshot_global, device->memstore);
			snapshot, adreno_snapshot_global, device->memstore);

	kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_GPU_OBJECT_V2,
			snapshot, snapshot_global,
			snapshot, adreno_snapshot_global,
			adreno_dev->pwron_fixup);

	if (kgsl_mmu_get_mmutype(device) == KGSL_MMU_TYPE_IOMMU)
+11 −1
Original line number Diff line number Diff line
@@ -56,5 +56,15 @@ void adreno_parse_ib(struct kgsl_device *device,
	struct kgsl_snapshot *snapshot,
	struct kgsl_process_private *process,
	u64 gpuaddr, u64 dwords);

/**
 * adreno_snapshot_global - Add global buffer to snapshot
 * @device: Pointer to the kgsl device
 * @buf: Where the global buffer section is to be written
 * @remain: Remaining bytes in snapshot buffer
 * @priv: Opaque data
 *
 * Return: Number of bytes written to the snapshot buffer
 */
size_t adreno_snapshot_global(struct kgsl_device *device, u8 *buf,
	size_t remain, void *priv);
#endif /*__ADRENO_SNAPSHOT_H */