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

Commit afa92a79 authored by Shubhraprakash Das's avatar Shubhraprakash Das
Browse files

msm: kgsl: Add CFF capture for IBs



If CFF is enabled, when an IB is submitted to hardware
parse it to find all objects in it and dump them.

Change-Id: I2caecb6a9c912a59be4c0d2acdd3949c96196653
Signed-off-by: default avatarShubhraprakash Das <sadas@codeaurora.org>
parent 4f98552f
Loading
Loading
Loading
Loading
+3 −10
Original line number Diff line number Diff line
@@ -1180,16 +1180,9 @@ int adreno_ringbuffer_submitcmd(struct adreno_device *adreno_dev,
					&link[0], (cmds - link),
					cmdbatch->timestamp);

#ifdef CONFIG_MSM_KGSL_CFF_DUMP
	if (ret)
		goto done;
	/*
	 * insert wait for idle after every IB1
	 * this is conservative but works reliably and is ok
	 * even for performance simulations
	 */
	ret = adreno_idle(device);
#endif
	/* CFF stuff executed only if CFF is enabled */
	kgsl_cffdump_capture_ib_desc(device, context, ibdesc, numibs);
	kgsl_cff_core_idle(device);

done:
	device->pwrctrl.irq_last = 0;
+88 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include "kgsl_sharedmem.h"
#include "adreno_pm4types.h"
#include "adreno.h"
#include "adreno_cp_parser.h"

static struct rchan	*chan;
static struct dentry	*dir;
@@ -647,3 +648,90 @@ int kgsl_cff_dump_enable_get(void *data, u64 *val)
	return 0;
}
EXPORT_SYMBOL(kgsl_cff_dump_enable_get);

/*
 * kgsl_cffdump_capture_adreno_ib_cff() - Capture CFF for an IB
 * @device: Device for which CFF is to be captured
 * @ptbase: The pagetable in which the IB is mapped
 * @gpuaddr: Address of IB
 * @dwords: Size of the IB
 *
 * Dumps the CFF format of the IB including all objects in it like, IB2,
 * shaders, etc.
 *
 * Returns 0 on success else error code
 */
static int kgsl_cffdump_capture_adreno_ib_cff(struct kgsl_device *device,
				phys_addr_t ptbase,
				unsigned int gpuaddr, unsigned int dwords)
{
	int ret;
	struct adreno_ib_object_list *ib_obj_list;
	struct adreno_ib_object *ib_obj;
	int i;

	if (!device->cff_dump_enable)
		return 0;

	ret = adreno_ib_create_object_list(device, ptbase, gpuaddr, dwords,
		&ib_obj_list);

	if (ret) {
		KGSL_DRV_ERR(device,
		"Fail to create object list for IB %x, size(dwords) %x\n",
		gpuaddr, dwords);
		return ret;
	}

	for (i = 0; i < ib_obj_list->num_objs; i++) {
		ib_obj = &(ib_obj_list->obj_list[i]);
		kgsl_cffdump_syncmem(device, &(ib_obj->entry->memdesc),
					ib_obj->gpuaddr, ib_obj->size, false);
	}
	adreno_ib_destroy_obj_list(ib_obj_list);
	return 0;
}

/*
 * kgsl_cffdump_capture_ib_desc() - Capture CFF for a list of IB's
 * @device: Device for which CFF is to be captured
 * @context: The context under which the IB list executes on device
 * @ibdesc: The IB list
 * @numibs: Number of IB's in ibdesc
 *
 * Returns 0 on success else error code
 */
int kgsl_cffdump_capture_ib_desc(struct kgsl_device *device,
				struct kgsl_context *context,
				struct kgsl_ibdesc *ibdesc,
				unsigned int numibs)
{
	int ret = 0;
	unsigned int ptbase;
	int i;

	if (!device->cff_dump_enable)
		return 0;
	/* Dump CFF for IB and all objects in it */
	ptbase = kgsl_mmu_get_pt_base_addr(&device->mmu,
					context->proc_priv->pagetable);
	if (!ptbase) {
		ret = -EINVAL;
		goto done;
	}
	for (i = 0; i < numibs; i++) {
		ret = kgsl_cffdump_capture_adreno_ib_cff(
			device, ptbase, ibdesc[i].gpuaddr,
			ibdesc[i].sizedwords);
		if (ret) {
			KGSL_DRV_ERR(device,
			"Fail cff capture, IB %x, size %x\n",
			ibdesc[i].gpuaddr,
			ibdesc[i].sizedwords << 2);
			break;
		}
	}
done:
	return ret;
}
EXPORT_SYMBOL(kgsl_cffdump_capture_ib_desc);
+24 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#define __KGSL_CFFDUMP_H

#include <linux/types.h>
#include "kgsl_device.h"

extern unsigned int kgsl_cff_dump_enable;

@@ -51,6 +52,10 @@ void kgsl_cffdump_memory_base(struct kgsl_device *device, unsigned int base,
void kgsl_cffdump_hang(struct kgsl_device *device);
int kgsl_cff_dump_enable_set(void *data, u64 val);
int kgsl_cff_dump_enable_get(void *data, u64 *val);
int kgsl_cffdump_capture_ib_desc(struct kgsl_device *device,
				struct kgsl_context *context,
				struct kgsl_ibdesc *ibdesc,
				unsigned int numibs);

#else

@@ -124,6 +129,15 @@ static inline void kgsl_cffdump_user_event(struct kgsl_device *device,
{
	return;
}

static inline int kgsl_cffdump_capture_ib_desc(struct kgsl_device *device,
				struct kgsl_context *context,
				struct kgsl_ibdesc *ibdesc,
				unsigned int numibs)
{
	return 0;
}

static inline int kgsl_cff_dump_enable_set(void *data, u64 val)
{
	return -EINVAL;
@@ -136,4 +150,14 @@ static inline int kgsl_cff_dump_enable_get(void *data, u64 *val)

#endif /* CONFIG_MSM_KGSL_CFF_DUMP */

/*
 * kgsl_cff_core_idle() - Idle the device if CFF is on
 * @device: Device whose idle fuunction is called
 */
static inline void kgsl_cff_core_idle(struct kgsl_device *device)
{
	if (device->cff_dump_enable)
		device->ftbl->idle(device);
}

#endif /* __KGSL_CFFDUMP_H */