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

Commit 1379f4d5 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Zap performance counters across context switches"

parents c33437e7 72fc4d24
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 */

#ifndef _A6XX_REG_H
@@ -406,6 +407,8 @@
#define A6XX_RBBM_PERFCTR_RBBM_SEL_2             0x509
#define A6XX_RBBM_PERFCTR_RBBM_SEL_3             0x50A
#define A6XX_RBBM_PERFCTR_GPU_BUSY_MASKED        0x50B
#define A6XX_RBBM_PERFCTR_SRAM_INIT_CMD          0x50e
#define A6XX_RBBM_PERFCTR_SRAM_INIT_STATUS       0x50f

#define A6XX_RBBM_ISDB_CNT                       0x533
#define A6XX_RBBM_NC_MODE_CNTL                   0X534
+8 −0
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@
#include "adreno_ringbuffer.h"
#include "kgsl_sharedmem.h"

/* Index to preemption scratch buffer to store KMD postamble */
#define KMD_POSTAMBLE_IDX 100

/* ADRENO_DEVICE - Given a kgsl_device return the adreno device struct */
#define ADRENO_DEVICE(device) \
		container_of(device, struct adreno_device, dev)
@@ -232,6 +235,9 @@ struct adreno_gpudev;
/* Time to allow preemption to complete (in ms) */
#define ADRENO_PREEMPT_TIMEOUT 10000

#define PREEMPT_SCRATCH_ADDR(dev, id) \
	((dev)->preempt.scratch->gpuaddr + (id * sizeof(u64)))

/**
 * enum adreno_preempt_states
 * ADRENO_PREEMPT_NONE: No preemption is scheduled
@@ -261,6 +267,7 @@ enum adreno_preempt_states {
 * skipsaverestore: To skip saverestore during L1 preemption (for 6XX)
 * usesgmem: enable GMEM save/restore across preemption (for 6XX)
 * count: Track the number of preemptions triggered
 * @postamble_len: Number of dwords in KMD postamble pm4 packet
 */
struct adreno_preemption {
	atomic_t state;
@@ -271,6 +278,7 @@ struct adreno_preemption {
	bool skipsaverestore;
	bool usesgmem;
	unsigned int count;
	u32 postamble_len;
};

struct adreno_busy_data {
+40 −4
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 */

#include "adreno.h"
@@ -543,13 +544,24 @@ unsigned int a6xx_preemption_pre_ibsubmit(
	if (context) {
		struct adreno_context *drawctxt = ADRENO_CONTEXT(context);
		struct adreno_ringbuffer *rb = drawctxt->rb;
		uint64_t dest = adreno_dev->preempt.scratch->gpuaddr
			+ (rb->id * sizeof(u64));
		uint64_t dest = PREEMPT_SCRATCH_ADDR(adreno_dev, rb->id);

		*cmds++ = cp_mem_packet(adreno_dev, CP_MEM_WRITE, 2, 2);
		cmds += cp_gpuaddr(adreno_dev, cmds, dest);
		*cmds++ = lower_32_bits(gpuaddr);
		*cmds++ = upper_32_bits(gpuaddr);

		/* Add a KMD post amble to clear the perf counters during preemption */
		if (!adreno_dev->perfcounter) {
			u64 kmd_postamble_addr =
					PREEMPT_SCRATCH_ADDR(adreno_dev, KMD_POSTAMBLE_IDX);

			*cmds++ = cp_type7_packet(CP_SET_AMBLE, 3);
			*cmds++ = lower_32_bits(kmd_postamble_addr);
			*cmds++ = upper_32_bits(kmd_postamble_addr);
			*cmds++ = FIELD_PREP(GENMASK(22, 20), CP_KMD_AMBLE_TYPE)
				| (FIELD_PREP(GENMASK(19, 0), adreno_dev->preempt.postamble_len));
		}
	}

	return (unsigned int) (cmds - cmds_orig);
@@ -562,8 +574,7 @@ unsigned int a6xx_preemption_post_ibsubmit(struct adreno_device *adreno_dev,
	struct adreno_ringbuffer *rb = adreno_dev->cur_rb;

	if (rb) {
		uint64_t dest = adreno_dev->preempt.scratch->gpuaddr
			+ (rb->id * sizeof(u64));
		uint64_t dest = PREEMPT_SCRATCH_ADDR(adreno_dev, adreno_dev->cur_rb->id);

		*cmds++ = cp_mem_packet(adreno_dev, CP_MEM_WRITE, 2, 2);
		cmds += cp_gpuaddr(adreno_dev, cmds, dest);
@@ -721,6 +732,31 @@ int a6xx_preemption_init(struct adreno_device *adreno_dev)
	if (ret)
		return ret;

	/*
	 * First 8 dwords of the preemption scratch buffer is used to store the address for CP
	 * to save/restore VPC data. Reserve 11 dwords in the preemption scratch buffer from
	 * index KMD_POSTAMBLE_IDX for KMD postamble pm4 packets
	 */
	if (!adreno_dev->perfcounter) {
		u32 *postamble = preempt->scratch->hostptr + (KMD_POSTAMBLE_IDX * sizeof(u64));
		u32 count = 0;

		postamble[count++] = cp_type7_packet(CP_REG_RMW, 3);
		postamble[count++] = A6XX_RBBM_PERFCTR_SRAM_INIT_CMD;
		postamble[count++] = 0x0;
		postamble[count++] = 0x1;

		postamble[count++] = cp_type7_packet(CP_WAIT_REG_MEM, 6);
		postamble[count++] = 0x3;
		postamble[count++] = A6XX_RBBM_PERFCTR_SRAM_INIT_STATUS;
		postamble[count++] = 0x0;
		postamble[count++] = 0x1;
		postamble[count++] = 0x1;
		postamble[count++] = 0x0;

		preempt->postamble_len = count;
	}

	set_bit(ADRENO_DEVICE_PREEMPTION, &adreno_dev->priv);
	return 0;
}
+18 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 */

#include <linux/slab.h>
@@ -217,6 +218,12 @@ static unsigned int _adreno_iommu_set_pt_v2_a6xx(struct kgsl_device *device,
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	unsigned int *cmds = cmds_orig;

	/* Clear performance counters during contect switches */
	if (!adreno_dev->perfcounter) {
		*cmds++ = cp_type4_packet(A6XX_RBBM_PERFCTR_SRAM_INIT_CMD, 1);
		*cmds++ = 0x1;
	}

	/* CP switches the pagetable and flushes the Caches */
	*cmds++ = cp_packet(adreno_dev, CP_SMMU_TABLE_UPDATE, 4);
	*cmds++ = lower_32_bits(ttbr0);
@@ -245,6 +252,17 @@ static unsigned int _adreno_iommu_set_pt_v2_a6xx(struct kgsl_device *device,
		*cmds++ = 0;
	}

	/* Wait for performance counter clear to finish */
	if (!adreno_dev->perfcounter) {
		*cmds++ = cp_type7_packet(CP_WAIT_REG_MEM, 6);
		*cmds++ = 0x3;
		*cmds++ = A6XX_RBBM_PERFCTR_SRAM_INIT_STATUS;
		*cmds++ = 0x0;
		*cmds++ = 0x1;
		*cmds++ = 0x1;
		*cmds++ = 0x0;
	}

	return cmds - cmds_orig;
}

+5 −2
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 */

#include <linux/slab.h>
@@ -72,7 +73,8 @@ void adreno_perfcounter_restore(struct adreno_device *adreno_dev)
	const struct adreno_perfcount_group *group;
	unsigned int counter, groupid;

	if (counters == NULL)
	/* Do not save/restore if not requested */
	if (counters == NULL || !adreno_dev->perfcounter)
		return;

	for (groupid = 0; groupid < counters->group_count; groupid++) {
@@ -106,7 +108,8 @@ inline void adreno_perfcounter_save(struct adreno_device *adreno_dev)
	const struct adreno_perfcount_group *group;
	unsigned int counter, groupid;

	if (counters == NULL)
	/* Do not save/restore if not requested */
	if (counters == NULL || !adreno_dev->perfcounter)
		return;

	for (groupid = 0; groupid < counters->group_count; groupid++) {
Loading