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

Commit 8931d160 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: fix trace events for 64 bit gpu addresses"

parents ba8a80e6 bd8d189d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1709,7 +1709,7 @@ static int _load_firmware(struct adreno_device *adreno_dev, const char *fwfile,

	memcpy(ucode->hostptr, &fw->data[4], fw->size - 4);
	*ucode_size = (fw->size - 4) / sizeof(uint32_t);
	*ucode_version = fw->data[4];
	*ucode_version = *(unsigned int *)&fw->data[4];

	release_firmware(fw);

+36 −12
Original line number Diff line number Diff line
@@ -474,6 +474,11 @@ static const struct a5xx_hlsq_sp_tp_regs a5xx_hlsq_sp_tp_registers[] = {
	{ 0x37, 0xEF00, 0x128 },
};

/* HLSQ non context registers - can't be read on A530v1 */
static const struct a5xx_hlsq_sp_tp_regs a5xx_hlsq_non_ctx_registers = {
	0x35, 0xE00, 0x1C
};

#define A5XX_NUM_SHADER_BANKS 4
#define A5XX_SHADER_STATETYPE_SHIFT 8

@@ -649,33 +654,52 @@ static void a5xx_snapshot_shader(struct kgsl_device *device,
	}
}

static int get_hlsq_registers(struct kgsl_device *device,
		const struct a5xx_hlsq_sp_tp_regs *regs, unsigned int *data)
{
	int j;
	unsigned int val;

	kgsl_regwrite(device, A5XX_HLSQ_DBG_READ_SEL,
			(regs->statetype << A5XX_SHADER_STATETYPE_SHIFT));

	for (j = 0; j < regs->size; j++) {
		kgsl_regread(device, A5XX_HLSQ_DBG_AHB_READ_APERTURE + j, &val);
		*data++ = regs->ahbaddr + j;
		*data++ = val;
	}

	return regs->size;
}

size_t a5xx_snapshot_dump_hlsq_sp_tp_regs(struct kgsl_device *device, u8 *buf,
	size_t remain, void *priv)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct kgsl_snapshot_regs *header = (struct kgsl_snapshot_regs *)buf;
	unsigned int *data = (unsigned int *)(buf + sizeof(*header));
	int count = 0, i, j, val = 0;
	int count = 0, i;

	/* Figure out how many registers we are going to dump */
	for (i = 0; i < ARRAY_SIZE(a5xx_hlsq_sp_tp_registers); i++)
			count += a5xx_hlsq_sp_tp_registers[i].size;

	/* the HLSQ non context registers cannot be dumped on A530v1 */
	if (!adreno_is_a530v1(adreno_dev))
		count += a5xx_hlsq_non_ctx_registers.size;

	if (remain < (count * 8) + sizeof(*header)) {
		SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
		return 0;
	}

	for (i = 0; i < ARRAY_SIZE(a5xx_hlsq_sp_tp_registers); i++) {
		kgsl_regwrite(device, A5XX_HLSQ_DBG_READ_SEL,
				  (a5xx_hlsq_sp_tp_registers[i].statetype <<
				   A5XX_SHADER_STATETYPE_SHIFT));
		for (j = 0; j < a5xx_hlsq_sp_tp_registers[i].size; j++) {
			kgsl_regread(device,
				A5XX_HLSQ_DBG_AHB_READ_APERTURE + j, &val);
			*data++ = a5xx_hlsq_sp_tp_registers[i].ahbaddr + j;
			*data++ = val;
		}
	}
	for (i = 0; i < ARRAY_SIZE(a5xx_hlsq_sp_tp_registers); i++)
		data += get_hlsq_registers(device,
			&a5xx_hlsq_sp_tp_registers[i], data);

	if (!adreno_is_a530v1(adreno_dev))
		data += get_hlsq_registers(device,
			&a5xx_hlsq_non_ctx_registers, data);

	header->count = count;

+2 −2
Original line number Diff line number Diff line
@@ -1043,9 +1043,9 @@ int adreno_iommu_init(struct adreno_device *adreno_dev)
	if (adreno_is_a5xx(adreno_dev) &&
		!MMU_FEATURE(&device->mmu, KGSL_MMU_GLOBAL_PAGETABLE)) {
		if ((adreno_compare_pfp_version(adreno_dev,
				A5XX_PFP_PER_PROCESS_UCODE_VER) < 0) &&
				A5XX_PFP_PER_PROCESS_UCODE_VER) < 0) ||
		    (adreno_compare_pm4_version(adreno_dev,
				A5XX_PFP_PER_PROCESS_UCODE_VER) < 0)) {
				A5XX_PM4_PER_PROCESS_UCODE_VER) < 0)) {
			KGSL_DRV_ERR(device,
				"Invalid ucode for per process pagetables\n");
			return -ENODEV;
+48 −48
Original line number Diff line number Diff line
@@ -229,7 +229,7 @@ static inline void parse_ib(struct kgsl_device *device,
static size_t snapshot_rb(struct kgsl_device *device, u8 *buf,
	size_t remain, void *priv)
{
	struct kgsl_snapshot_rb *header = (struct kgsl_snapshot_rb *)buf;
	struct kgsl_snapshot_rb_v2 *header = (struct kgsl_snapshot_rb_v2 *)buf;
	unsigned int *data = (unsigned int *)(buf + sizeof(*header));
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct adreno_ringbuffer *rb = ADRENO_CURRENT_RINGBUFFER(adreno_dev);
@@ -326,7 +326,10 @@ static size_t snapshot_rb(struct kgsl_device *device, u8 *buf,
	header->wptr = rb->wptr;
	header->rptr = rptr;
	header->rbsize = KGSL_RB_DWORDS;
	header->gpuaddr = rb->buffer_desc.gpuaddr;
	header->count = KGSL_RB_DWORDS;
	header->id = rb->id;

	adreno_rb_readtimestamp(device, rb, KGSL_TIMESTAMP_QUEUED,
					&header->timestamp_queued);
	adreno_rb_readtimestamp(device, rb, KGSL_TIMESTAMP_RETIRED,
@@ -354,7 +357,7 @@ static size_t snapshot_rb(struct kgsl_device *device, u8 *buf,

		if (parse_ibs && adreno_cmd_is_ib(adreno_dev, rbptr[index])) {
			uint64_t ibaddr;
			unsigned int ibsize;
			uint64_t ibsize;

			if (ADRENO_LEGACY_PM4(adreno_dev)) {
				ibaddr = rbptr[index + 1];
@@ -394,25 +397,29 @@ static int _count_mem_entries(int id, void *ptr, void *data)
	return 0;
}

struct mem_entry {
	uint64_t gpuaddr;
	uint64_t size;
	unsigned int type;
} __packed;

static int _save_mem_entries(int id, void *ptr, void *data)
{
	struct kgsl_mem_entry *entry = ptr;
	unsigned int **p = data;
	unsigned int *local = *p;
	struct mem_entry *m = (struct mem_entry *) data;

	*local++ = (unsigned int) entry->memdesc.gpuaddr;
	*local++ = (unsigned int) entry->memdesc.size;
	*local++ = kgsl_memdesc_get_memtype(&entry->memdesc);
	m->gpuaddr = entry->memdesc.gpuaddr;
	m->size = entry->memdesc.size;
	m->type = kgsl_memdesc_get_memtype(&entry->memdesc);

	*p = local;
	return 0;
}

static size_t snapshot_capture_mem_list(struct kgsl_device *device,
		u8 *buf, size_t remain, void *priv)
{
	struct kgsl_snapshot_replay_mem_list *header =
		(struct kgsl_snapshot_replay_mem_list *)buf;
	struct kgsl_snapshot_mem_list_v2 *header =
		(struct kgsl_snapshot_mem_list_v2 *)buf;
	int num_mem = 0;
	int ret = 0;
	unsigned int *data = (unsigned int *)(buf + sizeof(*header));
@@ -438,13 +445,13 @@ static size_t snapshot_capture_mem_list(struct kgsl_device *device,

	header->num_entries = num_mem;
	header->ptbase =
	 (__u32)kgsl_mmu_pagetable_get_ptbase(process->pagetable);
		kgsl_mmu_pagetable_get_ptbase(process->pagetable);
	/*
	 * Walk throught the memory list and store the
	 * tuples(gpuaddr, size, memtype) in snapshot
	 */

	idr_for_each(&process->mem_idr, _save_mem_entries, &data);
	idr_for_each(&process->mem_idr, _save_mem_entries, data);

	ret = sizeof(*header) + (num_mem * 3 * sizeof(unsigned int));
out:
@@ -455,17 +462,17 @@ out:
struct snapshot_ib_meta {
	struct kgsl_snapshot *snapshot;
	struct kgsl_snapshot_object *obj;
	unsigned int ib1base;
	unsigned int ib1size;
	unsigned int ib2base;
	unsigned int ib2size;
	uint64_t ib1base;
	uint64_t ib1size;
	uint64_t ib2base;
	uint64_t ib2size;
};

/* Snapshot the memory for an indirect buffer */
static size_t snapshot_ib(struct kgsl_device *device, u8 *buf,
	size_t remain, void *priv)
{
	struct kgsl_snapshot_ib *header = (struct kgsl_snapshot_ib *)buf;
	struct kgsl_snapshot_ib_v2 *header = (struct kgsl_snapshot_ib_v2 *)buf;
	struct snapshot_ib_meta *meta = priv;
	unsigned int *src;
	unsigned int *dst = (unsigned int *)(buf + sizeof(*header));
@@ -480,12 +487,6 @@ static size_t snapshot_ib(struct kgsl_device *device, u8 *buf,
	snapshot = meta->snapshot;
	obj = meta->obj;

	if (obj->size > SIZE_MAX) {
		KGSL_CORE_ERR("snapshot: GPU memory object 0x%016llX is too large to snapshot\n",
			obj->gpuaddr);
		return 0;
	}

	if (remain < (obj->size + sizeof(*header))) {
		KGSL_CORE_ERR("snapshot: Not enough memory for the ib\n");
		return 0;
@@ -521,13 +522,9 @@ static size_t snapshot_ib(struct kgsl_device *device, u8 *buf,
	}

	/* Write the sub-header for the section */
	header->gpuaddr = (unsigned int) obj->gpuaddr;
	/*
	 * This loses address bits, but we can't do better until the snapshot
	 * binary format is updated.
	 */
	header->gpuaddr = obj->gpuaddr;
	header->ptbase =
	 (__u32)kgsl_mmu_pagetable_get_ptbase(obj->entry->priv->pagetable);
		kgsl_mmu_pagetable_get_ptbase(obj->entry->priv->pagetable);
	header->size = obj->size >> 2;

	/* Write the contents of the ib */
@@ -540,8 +537,8 @@ static size_t snapshot_ib(struct kgsl_device *device, u8 *buf,
/* Dump another item on the current pending list */
static void dump_object(struct kgsl_device *device, int obj,
		struct kgsl_snapshot *snapshot,
		unsigned int ib1base, unsigned int ib1size,
		unsigned int ib2base, unsigned int ib2size)
		uint64_t ib1base, uint64_t ib1size,
		uint64_t ib2base, uint64_t ib2size)
{
	struct snapshot_ib_meta meta;

@@ -554,7 +551,7 @@ static void dump_object(struct kgsl_device *device, int obj,
		meta.ib2base = ib2base;
		meta.ib2size = ib2size;

		kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_IB,
		kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_IB_V2,
			snapshot, snapshot_ib, &meta);
		if (objbuf[obj].entry) {
			kgsl_memdesc_unmap(&(objbuf[obj].entry->memdesc));
@@ -627,8 +624,8 @@ static size_t snapshot_global(struct kgsl_device *device, u8 *buf,
{
	struct kgsl_memdesc *memdesc = priv;

	struct kgsl_snapshot_gpu_object *header =
		(struct kgsl_snapshot_gpu_object *)buf;
	struct kgsl_snapshot_gpu_object_v2 *header =
		(struct kgsl_snapshot_gpu_object_v2 *)buf;

	u8 *ptr = buf + sizeof(*header);

@@ -649,7 +646,7 @@ static size_t snapshot_global(struct kgsl_device *device, u8 *buf,
	header->size = memdesc->size >> 2;
	header->gpuaddr = memdesc->gpuaddr;
	header->ptbase =
	 (__u32)kgsl_mmu_pagetable_get_ptbase(device->mmu.defaultpagetable);
		kgsl_mmu_pagetable_get_ptbase(device->mmu.defaultpagetable);
	header->type = SNAPSHOT_GPU_OBJECT_GLOBAL;

	memcpy(ptr, memdesc->hostptr, memdesc->size);
@@ -669,8 +666,8 @@ void adreno_snapshot(struct kgsl_device *device, struct kgsl_snapshot *snapshot,
			struct kgsl_context *context)
{
	unsigned int i;
	uint32_t ib1base, ib1size;
	uint32_t ib2base, ib2size;
	uint64_t ib1base, ib2base;
	unsigned int ib1size, ib2size;
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);

@@ -684,26 +681,29 @@ void adreno_snapshot(struct kgsl_device *device, struct kgsl_snapshot *snapshot,
			context ? context->proc_priv : NULL);

	/* Dump the ringbuffer */
	kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_RB, snapshot,
	kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_RB_V2, snapshot,
			snapshot_rb, snapshot);

	adreno_readreg(adreno_dev, ADRENO_REG_CP_IB1_BASE, &ib1base);
	adreno_readreg64(adreno_dev, ADRENO_REG_CP_IB1_BASE,
			ADRENO_REG_CP_IB1_BASE_HI, &ib1base);
	adreno_readreg(adreno_dev, ADRENO_REG_CP_IB1_BUFSZ, &ib1size);
	adreno_readreg(adreno_dev, ADRENO_REG_CP_IB2_BASE, &ib2base);
	adreno_readreg64(adreno_dev, ADRENO_REG_CP_IB2_BASE,
			ADRENO_REG_CP_IB2_BASE_HI, &ib2base);
	adreno_readreg(adreno_dev, ADRENO_REG_CP_IB2_BUFSZ, &ib2size);

	/* Add GPU specific sections - registers mainly, but other stuff too */
	if (gpudev->snapshot)
		gpudev->snapshot(adreno_dev, snapshot);

	/* Dump selected global buffers */
	kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_GPU_OBJECT,
	kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_GPU_OBJECT_V2,
			snapshot, snapshot_global, &adreno_dev->dev.memstore);

	kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_GPU_OBJECT,
	kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_GPU_OBJECT_V2,
			snapshot, snapshot_global,
			&adreno_dev->dev.mmu.setstate_memory);

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

@@ -711,7 +711,7 @@ void adreno_snapshot(struct kgsl_device *device, struct kgsl_snapshot *snapshot,
	 * Add a section that lists (gpuaddr, size, memtype) tuples of the
	 * hanging process
	 */
	kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_MEMLIST,
	kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_MEMLIST_V2,
			snapshot, snapshot_capture_mem_list, snapshot->process);
	/*
	 * Make sure that the last IB1 that was being executed is dumped.
@@ -725,10 +725,10 @@ void adreno_snapshot(struct kgsl_device *device, struct kgsl_snapshot *snapshot,
	 * figure how often this really happens.
	 */

	if (!find_object(SNAPSHOT_OBJ_TYPE_IB, (uint64_t) ib1base,
	if (!find_object(SNAPSHOT_OBJ_TYPE_IB, ib1base,
			snapshot->process) && ib1size) {
		push_object(SNAPSHOT_OBJ_TYPE_IB, snapshot->process,
			(uint64_t) ib1base, ib1size);
			ib1base, ib1size);
		KGSL_CORE_ERR(
		"CP_IB1_BASE not found in the ringbuffer.Dumping %x dwords of the buffer.\n",
		ib1size);
@@ -742,10 +742,10 @@ void adreno_snapshot(struct kgsl_device *device, struct kgsl_snapshot *snapshot,
	 * correct size.
	 */

	if (!find_object(SNAPSHOT_OBJ_TYPE_IB, (uint64_t) ib2base,
	if (!find_object(SNAPSHOT_OBJ_TYPE_IB, ib2base,
		snapshot->process) && ib2size) {
		push_object(SNAPSHOT_OBJ_TYPE_IB, snapshot->process,
			(uint64_t) ib2base, ib2size);
			ib2base, ib2size);
	}

	/*
+17 −5
Original line number Diff line number Diff line
@@ -232,7 +232,8 @@ kgsl_mem_entry_destroy(struct kref *kref)
	kgsl_mem_entry_detach_process(entry);

	if (memtype != KGSL_MEM_ENTRY_KERNEL)
		kgsl_driver.stats.mapped -= entry->memdesc.size;
		atomic_long_sub(entry->memdesc.size,
			&kgsl_driver.stats.mapped);

	/*
	 * Ion takes care of freeing the sg_table for us so
@@ -2214,8 +2215,8 @@ long kgsl_ioctl_gpuobj_import(struct kgsl_device_private *dev_priv,

	param->id = entry->id;

	KGSL_STATS_ADD(entry->memdesc.size, kgsl_driver.stats.mapped,
		kgsl_driver.stats.mapped_max);
	KGSL_STATS_ADD(entry->memdesc.size, &kgsl_driver.stats.mapped,
		&kgsl_driver.stats.mapped_max);

	kgsl_process_add_stats(private,
		kgsl_memdesc_usermem_type(&entry->memdesc),
@@ -2483,8 +2484,8 @@ long kgsl_ioctl_map_user_mem(struct kgsl_device_private *dev_priv,
	param->gpuaddr = (unsigned long)
		entry->memdesc.gpuaddr + (param->offset & PAGE_MASK);

	KGSL_STATS_ADD(param->len, kgsl_driver.stats.mapped,
		kgsl_driver.stats.mapped_max);
	KGSL_STATS_ADD(param->len, &kgsl_driver.stats.mapped,
		&kgsl_driver.stats.mapped_max);

	kgsl_process_add_stats(private,
			kgsl_memdesc_usermem_type(&entry->memdesc), param->len);
@@ -3565,6 +3566,17 @@ struct kgsl_driver kgsl_driver = {
	 * 8064 and 8974 once the region to be flushed is > 16mb.
	 */
	.full_cache_threshold = SZ_16M,

	.stats.vmalloc = ATOMIC_LONG_INIT(0),
	.stats.vmalloc_max = ATOMIC_LONG_INIT(0),
	.stats.page_alloc = ATOMIC_LONG_INIT(0),
	.stats.page_alloc_max = ATOMIC_LONG_INIT(0),
	.stats.coherent = ATOMIC_LONG_INIT(0),
	.stats.coherent_max = ATOMIC_LONG_INIT(0),
	.stats.secure = ATOMIC_LONG_INIT(0),
	.stats.secure_max = ATOMIC_LONG_INIT(0),
	.stats.mapped = ATOMIC_LONG_INIT(0),
	.stats.mapped_max = ATOMIC_LONG_INIT(0),
};
EXPORT_SYMBOL(kgsl_driver);

Loading