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

Commit dc9688db authored by Carter Cooper's avatar Carter Cooper Committed by Stephen Boyd
Browse files

msm: kgsl: Add per-context performance counter sampling feature



Add global monitoring ability for GPU performance counters on every command
buffer submission.  This feature is used by user-space via debugfs files.

Change-Id: I428276e5d991ba8bb8b7bdf1fe59432086f05e5b
Signed-off-by: default avatarCarter Cooper <ccooper@codeaurora.org>
parent 1aa09a7a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ msm_adreno-y += \
	adreno_a3xx_snapshot.o \
	adreno.o

msm_adreno-$(CONFIG_DEBUG_FS) += adreno_debugfs.o
msm_adreno-$(CONFIG_DEBUG_FS) += adreno_debugfs.o adreno_profile.o

msm_z180-y += \
	z180.o \
+71 −1
Original line number Diff line number Diff line
@@ -274,7 +274,7 @@ static void adreno_perfcounter_start(struct adreno_device *adreno_dev)
}

/**
 * adreno_perfcounter_read_group: Determine which countables are in counters
 * adreno_perfcounter_read_group() - Determine which countables are in counters
 * @adreno_dev: Adreno device to configure
 * @reads: List of kgsl_perfcounter_read_groups
 * @count: Length of list
@@ -350,6 +350,61 @@ done:
	return ret;
}

/**
 * adreno_perfcounter_get_groupid() - Get the performance counter ID
 * @adreno_dev: Adreno device
 * @name: Performance counter group name string
 *
 * Get the groupid based on the name and return this ID
 */

int adreno_perfcounter_get_groupid(struct adreno_device *adreno_dev,
					const char *name)
{

	struct adreno_perfcounters *counters = adreno_dev->gpudev->perfcounters;
	struct adreno_perfcount_group *group;
	int i;

	if (name == NULL)
		return -EINVAL;

	/* perfcounter get/put/query not allowed on a2xx */
	if (adreno_is_a2xx(adreno_dev))
		return -EINVAL;

	for (i = 0; i < counters->group_count; ++i) {
		group = &(counters->groups[i]);
		if (!strcmp(group->name, name))
			return i;
	}

	return -EINVAL;
}

/**
 * adreno_perfcounter_get_name() - Get the group name
 * @adreno_dev: Adreno device
 * @groupid: Desired performance counter groupid
 *
 * Get the name based on the groupid and return it
 */

const char *adreno_perfcounter_get_name(struct adreno_device *adreno_dev,
		unsigned int groupid)
{
	struct adreno_perfcounters *counters = adreno_dev->gpudev->perfcounters;

	/* perfcounter get/put/query not allowed on a2xx */
	if (adreno_is_a2xx(adreno_dev))
		return NULL;

	if (groupid >= counters->group_count)
		return NULL;

	return counters->groups[groupid].name;
}

/**
 * adreno_perfcounter_query_group: Determine which countables are in counters
 * @adreno_dev: Adreno device to configure
@@ -574,6 +629,8 @@ static void adreno_cleanup_pt(struct kgsl_device *device,

	kgsl_mmu_unmap(pagetable, &device->memstore);

	kgsl_mmu_unmap(pagetable, &adreno_dev->profile.shared_buffer);

	kgsl_mmu_unmap(pagetable, &device->mmu.setstate_memory);
}

@@ -596,6 +653,11 @@ static int adreno_setup_pt(struct kgsl_device *device,
	if (result)
		goto unmap_memptrs_desc;

	result = kgsl_mmu_map_global(pagetable,
					&adreno_dev->profile.shared_buffer);
	if (result)
		goto unmap_profile_shared;

	result = kgsl_mmu_map_global(pagetable, &device->mmu.setstate_memory);
	if (result)
		goto unmap_memstore_desc;
@@ -609,6 +671,9 @@ static int adreno_setup_pt(struct kgsl_device *device,
				device->mmu.setstate_memory.size;
	return result;

unmap_profile_shared:
	kgsl_mmu_unmap(pagetable, &adreno_dev->profile.shared_buffer);

unmap_memstore_desc:
	kgsl_mmu_unmap(pagetable, &device->memstore);

@@ -1522,6 +1587,7 @@ adreno_probe(struct platform_device *pdev)
		goto error_close_rb;

	adreno_debugfs_init(device);
	adreno_profile_init(device);

	adreno_ft_init_sysfs(device);

@@ -1552,6 +1618,7 @@ static int adreno_remove(struct platform_device *pdev)
	adreno_dev = ADRENO_DEVICE(device);

	adreno_coresight_remove(pdev);
	adreno_profile_close(device);

	kgsl_pwrscale_detach_policy(device);
	kgsl_pwrscale_close(device);
@@ -3194,6 +3261,9 @@ static int adreno_suspend_context(struct kgsl_device *device)
	int status = 0;
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);

	/* process any profiling results that are available */
	adreno_profile_process_results(device);

	/* switch to NULL ctxt */
	if (adreno_dev->drawctxt_active != NULL) {
		adreno_drawctxt_switch(adreno_dev, NULL, 0);
+13 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include "kgsl_device.h"
#include "adreno_drawctxt.h"
#include "adreno_ringbuffer.h"
#include "adreno_profile.h"
#include "kgsl_iommu.h"
#include <mach/ocmem.h>

@@ -38,6 +39,7 @@
#define KGSL_CMD_FLAGS_PMODE		0x00000001
#define KGSL_CMD_FLAGS_INTERNAL_ISSUE	0x00000002
#define KGSL_CMD_FLAGS_GET_INT		0x00000004
#define KGSL_CMD_FLAGS_PROFILE		0x00000008
#define KGSL_CMD_FLAGS_EOF	        0x00000100

/* Command identifiers */
@@ -48,6 +50,8 @@
#define KGSL_END_OF_IB_IDENTIFIER	0x2ABEDEAD
#define KGSL_END_OF_FRAME_IDENTIFIER	0x2E0F2E0F
#define KGSL_NOP_IB_IDENTIFIER	        0x20F20F20
#define KGSL_START_OF_PROFILE_IDENTIFIER	0x2DEFADE1
#define KGSL_END_OF_PROFILE_IDENTIFIER	0x2DEFADE2

#ifdef CONFIG_MSM_SCM
#define ADRENO_DEFAULT_PWRSCALE_POLICY  (&kgsl_pwrscale_policy_tz)
@@ -131,6 +135,7 @@ struct adreno_device {
	struct ocmem_buf *ocmem_hdl;
	unsigned int ocmem_base;
	unsigned int gpu_cycles;
	struct adreno_profile profile;
};

#define PERFCOUNTER_FLAG_NONE 0x0
@@ -156,10 +161,12 @@ struct adreno_perfcount_register {
 * struct adreno_perfcount_group: registers for a hardware group
 * @regs: available registers for this group
 * @reg_count: total registers for this group
 * @name: group name for this group
 */
struct adreno_perfcount_group {
	struct adreno_perfcount_register *regs;
	unsigned int reg_count;
	const char *name;
};

/**
@@ -414,6 +421,12 @@ unsigned int adreno_ft_detect(struct kgsl_device *device,
int adreno_ft_init_sysfs(struct kgsl_device *device);
void adreno_ft_uninit_sysfs(struct kgsl_device *device);

int adreno_perfcounter_get_groupid(struct adreno_device *adreno_dev,
					const char *name);

const char *adreno_perfcounter_get_name(struct adreno_device
					*adreno_dev, unsigned int groupid);

int adreno_perfcounter_get(struct adreno_device *adreno_dev,
	unsigned int groupid, unsigned int countable, unsigned int *offset,
	unsigned int flags);
+21 −15
Original line number Diff line number Diff line
@@ -3245,22 +3245,25 @@ static struct adreno_perfcount_register a3xx_perfcounters_vbif_pwr[] = {
	{ KGSL_PERFCOUNTER_NOT_USED, 0, 0, A3XX_VBIF_PERF_PWR_CNT2_LO },
};

#define A3XX_PERFCOUNTER_GROUP(name) { a3xx_perfcounters_##name, \
	ARRAY_SIZE(a3xx_perfcounters_##name), __stringify(name) }

static struct adreno_perfcount_group a3xx_perfcounter_groups[] = {
	{ a3xx_perfcounters_cp, ARRAY_SIZE(a3xx_perfcounters_cp) },
	{ a3xx_perfcounters_rbbm, ARRAY_SIZE(a3xx_perfcounters_rbbm) },
	{ a3xx_perfcounters_pc, ARRAY_SIZE(a3xx_perfcounters_pc) },
	{ a3xx_perfcounters_vfd, ARRAY_SIZE(a3xx_perfcounters_vfd) },
	{ a3xx_perfcounters_hlsq, ARRAY_SIZE(a3xx_perfcounters_hlsq) },
	{ a3xx_perfcounters_vpc, ARRAY_SIZE(a3xx_perfcounters_vpc) },
	{ a3xx_perfcounters_tse, ARRAY_SIZE(a3xx_perfcounters_tse) },
	{ a3xx_perfcounters_ras, ARRAY_SIZE(a3xx_perfcounters_ras) },
	{ a3xx_perfcounters_uche, ARRAY_SIZE(a3xx_perfcounters_uche) },
	{ a3xx_perfcounters_tp, ARRAY_SIZE(a3xx_perfcounters_tp) },
	{ a3xx_perfcounters_sp, ARRAY_SIZE(a3xx_perfcounters_sp) },
	{ a3xx_perfcounters_rb, ARRAY_SIZE(a3xx_perfcounters_rb) },
	{ a3xx_perfcounters_pwr, ARRAY_SIZE(a3xx_perfcounters_pwr) },
	{ a3xx_perfcounters_vbif, ARRAY_SIZE(a3xx_perfcounters_vbif) },
	{ a3xx_perfcounters_vbif_pwr, ARRAY_SIZE(a3xx_perfcounters_vbif_pwr) },
	A3XX_PERFCOUNTER_GROUP(cp),
	A3XX_PERFCOUNTER_GROUP(rbbm),
	A3XX_PERFCOUNTER_GROUP(pc),
	A3XX_PERFCOUNTER_GROUP(vfd),
	A3XX_PERFCOUNTER_GROUP(hlsq),
	A3XX_PERFCOUNTER_GROUP(vpc),
	A3XX_PERFCOUNTER_GROUP(tse),
	A3XX_PERFCOUNTER_GROUP(ras),
	A3XX_PERFCOUNTER_GROUP(uche),
	A3XX_PERFCOUNTER_GROUP(tp),
	A3XX_PERFCOUNTER_GROUP(sp),
	A3XX_PERFCOUNTER_GROUP(rb),
	A3XX_PERFCOUNTER_GROUP(pwr),
	A3XX_PERFCOUNTER_GROUP(vbif),
	A3XX_PERFCOUNTER_GROUP(vbif_pwr),
};

static struct adreno_perfcounters a3xx_perfcounters = {
@@ -3304,6 +3307,9 @@ static void a3xx_perfcounter_init(struct adreno_device *adreno_dev)
	/* Reserve and start countable 1 in the PWR perfcounter group */
	adreno_perfcounter_get(adreno_dev, KGSL_PERFCOUNTER_GROUP_PWR, 1,
			NULL, PERFCOUNTER_FLAG_KERNEL);

	/* Default performance counter profiling to false */
	adreno_dev->profile.enabled = false;
}

/**
+2 −0
Original line number Diff line number Diff line
@@ -249,6 +249,8 @@ void adreno_drawctxt_detach(struct kgsl_context *context)
	if (device->state != KGSL_STATE_HUNG)
		adreno_idle(device);

	adreno_profile_process_results(device);

	kgsl_sharedmem_free(&drawctxt->gpustate);
	kgsl_sharedmem_free(&drawctxt->context_gmem_shadow.gmemshadow);
}
Loading