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

Commit aea8799b 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: Add IFPC static registers to powerup register list"

parents 41b31e3f 4ea68128
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@
#define A6XX_CP_MEM_POOL_SIZE            0x8C3
#define A6XX_CP_CHICKEN_DBG              0x841
#define A6XX_CP_ADDR_MODE_CNTL           0x842
#define A6XX_CP_DBG_ECO_CNTL             0x843
#define A6XX_CP_PROTECT_CNTL             0x84F
#define A6XX_CP_PROTECT_REG              0x850
#define A6XX_CP_CONTEXT_SWITCH_CNTL      0x8A0
+92 −9
Original line number Diff line number Diff line
@@ -281,6 +281,7 @@ static struct a6xx_protected_regs {
	{ 0xA630, 0x0, 1 },
};

/* IFPC & Preemption static powerup restore list */
static struct reg_list_pair {
	uint32_t offset;
	uint32_t val;
@@ -315,6 +316,48 @@ static struct reg_list_pair {
	{ A6XX_RB_CONTEXT_SWITCH_GMEM_SAVE_RESTORE, 0x0 },
};

/* IFPC only static powerup restore list */
static struct reg_list_pair a6xx_ifpc_pwrup_reglist[] = {
	{ A6XX_RBBM_VBIF_CLIENT_QOS_CNTL, 0x0 },
	{ A6XX_CP_CHICKEN_DBG, 0x0 },
	{ A6XX_CP_ADDR_MODE_CNTL, 0x0 },
	{ A6XX_CP_DBG_ECO_CNTL, 0x0 },
	{ A6XX_CP_PROTECT_CNTL, 0x0 },
	{ A6XX_CP_PROTECT_REG, 0x0 },
	{ A6XX_CP_PROTECT_REG+1, 0x0 },
	{ A6XX_CP_PROTECT_REG+2, 0x0 },
	{ A6XX_CP_PROTECT_REG+3, 0x0 },
	{ A6XX_CP_PROTECT_REG+4, 0x0 },
	{ A6XX_CP_PROTECT_REG+5, 0x0 },
	{ A6XX_CP_PROTECT_REG+6, 0x0 },
	{ A6XX_CP_PROTECT_REG+7, 0x0 },
	{ A6XX_CP_PROTECT_REG+8, 0x0 },
	{ A6XX_CP_PROTECT_REG+9, 0x0 },
	{ A6XX_CP_PROTECT_REG+10, 0x0 },
	{ A6XX_CP_PROTECT_REG+11, 0x0 },
	{ A6XX_CP_PROTECT_REG+12, 0x0 },
	{ A6XX_CP_PROTECT_REG+13, 0x0 },
	{ A6XX_CP_PROTECT_REG+14, 0x0 },
	{ A6XX_CP_PROTECT_REG+15, 0x0 },
	{ A6XX_CP_PROTECT_REG+16, 0x0 },
	{ A6XX_CP_PROTECT_REG+17, 0x0 },
	{ A6XX_CP_PROTECT_REG+18, 0x0 },
	{ A6XX_CP_PROTECT_REG+19, 0x0 },
	{ A6XX_CP_PROTECT_REG+20, 0x0 },
	{ A6XX_CP_PROTECT_REG+21, 0x0 },
	{ A6XX_CP_PROTECT_REG+22, 0x0 },
	{ A6XX_CP_PROTECT_REG+23, 0x0 },
	{ A6XX_CP_PROTECT_REG+24, 0x0 },
	{ A6XX_CP_PROTECT_REG+25, 0x0 },
	{ A6XX_CP_PROTECT_REG+26, 0x0 },
	{ A6XX_CP_PROTECT_REG+27, 0x0 },
	{ A6XX_CP_PROTECT_REG+28, 0x0 },
	{ A6XX_CP_PROTECT_REG+29, 0x0 },
	{ A6XX_CP_PROTECT_REG+30, 0x0 },
	{ A6XX_CP_PROTECT_REG+31, 0x0 },
	{ A6XX_CP_AHB_CNTL, 0x0 },
};

static void _update_always_on_regs(struct adreno_device *adreno_dev)
{
	struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
@@ -331,7 +374,7 @@ static void a6xx_pwrup_reglist_init(struct adreno_device *adreno_dev)
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);

	if (kgsl_allocate_global(device, &adreno_dev->pwrup_reglist,
		PAGE_SIZE, KGSL_MEMFLAGS_GPUREADONLY, 0,
		PAGE_SIZE, 0, KGSL_MEMDESC_CONTIG | KGSL_MEMDESC_PRIVILEGED,
		"powerup_register_list")) {
		adreno_dev->pwrup_reglist.gpuaddr = 0;
		return;
@@ -500,17 +543,46 @@ static uint32_t lm_limit(struct adreno_device *adreno_dev)
static void a6xx_patch_pwrup_reglist(struct adreno_device *adreno_dev)
{
	uint32_t i;
	struct cpu_gpu_lock *lock;
	struct reg_list_pair *r;

	/* Set up the register values */
	for (i = 0; i < ARRAY_SIZE(a6xx_pwrup_reglist); i++) {
		struct reg_list_pair *r = &a6xx_pwrup_reglist[i];
	for (i = 0; i < ARRAY_SIZE(a6xx_ifpc_pwrup_reglist); i++) {
		r = &a6xx_ifpc_pwrup_reglist[i];
		kgsl_regread(KGSL_DEVICE(adreno_dev), r->offset, &r->val);
	}

	for (i = 0; i < ARRAY_SIZE(a6xx_pwrup_reglist); i++) {
		r = &a6xx_pwrup_reglist[i];
		kgsl_regread(KGSL_DEVICE(adreno_dev), r->offset, &r->val);
	}

	/* Copy Preemption register/data pairs */
	memcpy(adreno_dev->pwrup_reglist.hostptr, &a6xx_pwrup_reglist,
		sizeof(a6xx_pwrup_reglist));
	lock = (struct cpu_gpu_lock *) adreno_dev->pwrup_reglist.hostptr;
	lock->flag_ucode = 0;
	lock->flag_kmd = 0;
	lock->turn = 0;

	/*
	 * The overall register list is composed of
	 * 1. Static IFPC-only registers
	 * 2. Static IFPC + preemption registers
	 * 2. Dynamic IFPC + preemption registers (ex: perfcounter selects)
	 *
	 * The CP views the second and third entries as one dynamic list
	 * starting from list_offset. Thus, list_length should be the sum
	 * of all three lists above (of which the third list will start off
	 * empty). And list_offset should be specified as the size in dwords
	 * of the static IFPC-only register list.
	 */
	lock->list_length = (sizeof(a6xx_ifpc_pwrup_reglist) +
			sizeof(a6xx_pwrup_reglist)) >> 2;
	lock->list_offset = sizeof(a6xx_ifpc_pwrup_reglist) >> 2;

	memcpy(adreno_dev->pwrup_reglist.hostptr + sizeof(*lock),
		a6xx_ifpc_pwrup_reglist, sizeof(a6xx_ifpc_pwrup_reglist));
	memcpy(adreno_dev->pwrup_reglist.hostptr + sizeof(*lock)
		+ sizeof(a6xx_ifpc_pwrup_reglist),
		a6xx_pwrup_reglist, sizeof(a6xx_pwrup_reglist));
}

/*
@@ -717,13 +789,16 @@ static int a6xx_microcode_load(struct adreno_device *adreno_dev)
/* Register initialization list */
#define CP_INIT_REGISTER_INIT_LIST BIT(7)

/* Register initialization list with spinlock */
#define CP_INIT_REGISTER_INIT_LIST_WITH_SPINLOCK BIT(8)

#define CP_INIT_MASK (CP_INIT_MAX_CONTEXT | \
		CP_INIT_ERROR_DETECTION_CONTROL | \
		CP_INIT_HEADER_DUMP | \
		CP_INIT_DEFAULT_RESET_STATE | \
		CP_INIT_UCODE_WORKAROUND_MASK | \
		CP_INIT_OPERATION_MODE_MASK | \
		CP_INIT_REGISTER_INIT_LIST)
		CP_INIT_REGISTER_INIT_LIST_WITH_SPINLOCK)

static void _set_ordinals(struct adreno_device *adreno_dev,
		unsigned int *cmds, unsigned int count)
@@ -759,13 +834,21 @@ static void _set_ordinals(struct adreno_device *adreno_dev,
	if (CP_INIT_MASK & CP_INIT_OPERATION_MODE_MASK)
		*cmds++ = 0x00000002;

	if (CP_INIT_MASK & CP_INIT_REGISTER_INIT_LIST) {
	if (CP_INIT_MASK & CP_INIT_REGISTER_INIT_LIST_WITH_SPINLOCK) {
		uint64_t gpuaddr = adreno_dev->pwrup_reglist.gpuaddr;

		*cmds++ = lower_32_bits(gpuaddr);
		*cmds++ = upper_32_bits(gpuaddr);
		*cmds++ =  0;

	} else if (CP_INIT_MASK & CP_INIT_REGISTER_INIT_LIST) {
		uint64_t gpuaddr = adreno_dev->pwrup_reglist.gpuaddr;

		*cmds++ = lower_32_bits(gpuaddr);
		*cmds++ = upper_32_bits(gpuaddr);
		/* Size is in dwords */
		*cmds++ = sizeof(a6xx_pwrup_reglist) >> 2;
		*cmds++ = (sizeof(a6xx_ifpc_pwrup_reglist) +
			sizeof(a6xx_pwrup_reglist)) >> 2;
	}

	/* Pad rest of the cmds with 0's */
+18 −0
Original line number Diff line number Diff line
@@ -75,6 +75,24 @@ struct a6xx_cp_smmu_info {

#define A6XX_CP_SMMU_INFO_MAGIC_REF     0x241350D5UL

/**
 * struct cpu_gpu_spinlock - CP spinlock structure for power up list
 * @flag_ucode: flag value set by CP
 * @flag_kmd: flag value set by KMD
 * @turn: turn variable set by both CP and KMD
 * @list_length: this tells CP the last dword in the list:
 * 16 + (4 * (List_Length - 1))
 * @list_offset: this tells CP the start of preemption only list:
 * 16 + (4 * List_Offset)
 */
struct cpu_gpu_lock {
	uint32_t flag_ucode;
	uint32_t flag_kmd;
	uint32_t turn;
	uint16_t list_length;
	uint16_t list_offset;
};

#define A6XX_CP_CTXRECORD_MAGIC_REF     0xAE399D6EUL
/* Size of each CP preemption record */
#define A6XX_CP_CTXRECORD_SIZE_IN_BYTES     (2112 * 1024)