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

Commit 21dc7da5 authored by Akhil P Oommen's avatar Akhil P Oommen
Browse files

msm: kgsl: Mark the scratch buffer as privileged



Mark the scratch buffer as privileged so that it can only be accessed by
GPU through the ringbuffer. To accomplish this, we need to:

1. Move the preemption data out of the scratch buffer.
2. Disable the shadow rptr feature.
3. Trigger RPTR update from GPU using a WHERE_AM_I packet.
4. Add support for the new ucode.

Change-Id: I9b388f55f53b69028b9bbb2306cb43fd1297c52f
Signed-off-by: default avatarAkhil P Oommen <akhilpo@codeaurora.org>
parent 346ce0bb
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -3986,6 +3986,19 @@ static bool adreno_is_hwcg_on(struct kgsl_device *device)
	return test_bit(ADRENO_HWCG_CTRL, &adreno_dev->pwrctrl_flag);
}

u32 adreno_get_ucode_version(const u32 *data)
{
	u32 version;

	version = data[1];

	if ((version & 0xf) != 0xa)
		return version;

	version &= ~0xfff;
	return  version | ((data[3] & 0xfff000) >> 12);
}

static const struct kgsl_functable adreno_functable = {
	/* Mandatory functions */
	.regread = adreno_regread,
+5 −3
Original line number Diff line number Diff line
@@ -265,8 +265,8 @@ enum adreno_preempt_states {
/**
 * struct adreno_preemption
 * @state: The current state of preemption
 * @counters: Memory descriptor for the memory where the GPU writes the
 * preemption counters on switch
 * @scratch: Memory descriptor for the memory where the GPU writes the
 * current ctxt record address and preemption counters on switch
 * @timer: A timer to make sure preemption doesn't stall
 * @work: A work struct for the preemption worker (for 5XX)
 * preempt_level: The level of preemption (for 6XX)
@@ -276,7 +276,7 @@ enum adreno_preempt_states {
 */
struct adreno_preemption {
	atomic_t state;
	struct kgsl_memdesc counters;
	struct kgsl_memdesc scratch;
	struct timer_list timer;
	struct work_struct work;
	unsigned int preempt_level;
@@ -882,6 +882,7 @@ struct adreno_gpudev {

	struct adreno_irq *irq;
	int num_prio_levels;
	int cp_rb_cntl;
	unsigned int vbif_xin_halt_ctrl0_mask;
	unsigned int gbif_client_halt_mask;
	unsigned int gbif_arb_halt_mask;
@@ -1110,6 +1111,7 @@ void adreno_rscc_regread(struct adreno_device *adreno_dev,
		unsigned int offsetwords, unsigned int *value);
void adreno_isense_regread(struct adreno_device *adreno_dev,
		unsigned int offsetwords, unsigned int *value);
u32 adreno_get_ucode_version(const u32 *data);


#define ADRENO_TARGET(_name, _id) \
+8 −5
Original line number Diff line number Diff line
@@ -1724,12 +1724,15 @@ static int a5xx_post_start(struct adreno_device *adreno_dev)
		*cmds++ = 0xF;
	}

	if (adreno_is_preemption_enabled(adreno_dev))
	if (adreno_is_preemption_enabled(adreno_dev)) {
		cmds += _preemption_init(adreno_dev, rb, cmds, NULL);

		rb->_wptr = rb->_wptr - (42 - (cmds - start));

		ret = adreno_ringbuffer_submit_spin_nosync(rb, NULL, 2000);
	} else {
		rb->_wptr = rb->_wptr - (42 - (cmds - start));
		ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000);
	}

	if (ret)
		adreno_spin_idle_debug(adreno_dev,
				"hw initialization failed to idle\n");
@@ -2038,7 +2041,7 @@ static int _load_firmware(struct kgsl_device *device, const char *fwfile,

	memcpy(firmware->memdesc.hostptr, &fw->data[4], fw->size - 4);
	firmware->size = (fw->size - 4) / sizeof(uint32_t);
	firmware->version = *(unsigned int *)&fw->data[4];
	firmware->version = adreno_get_ucode_version((u32 *)fw->data);

done:
	release_firmware(fw);
+2 −2
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2015-2017,2019 The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2017,2019-2020 The Linux Foundation. All rights reserved.
 */

#ifndef _ADRENO_A5XX_H_
@@ -134,7 +134,7 @@ void a5xx_crashdump_init(struct adreno_device *adreno_dev);

void a5xx_hwcg_set(struct adreno_device *adreno_dev, bool on);

#define A5XX_CP_RB_CNTL_DEFAULT (((ilog2(4) << 8) & 0x1F00) | \
#define A5XX_CP_RB_CNTL_DEFAULT ((1 << 27) | ((ilog2(4) << 8) & 0x1F00) | \
		(ilog2(KGSL_RB_DWORDS >> 1) & 0x3F))
/* GPMU interrupt multiplexor */
#define FW_INTR_INFO			(0)
+4 −4
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2014-2017,2019 The Linux Foundation. All rights reserved.
 * Copyright (c) 2014-2017,2019-2020 The Linux Foundation. All rights reserved.
 */

#include "adreno.h"
@@ -570,7 +570,7 @@ static void _preemption_close(struct adreno_device *adreno_dev)
	unsigned int i;

	del_timer(&preempt->timer);
	kgsl_free_global(device, &preempt->counters);
	kgsl_free_global(device, &preempt->scratch);
	a5xx_preemption_iommu_close(adreno_dev);

	FOR_EACH_RINGBUFFER(adreno_dev, rb, i) {
@@ -604,14 +604,14 @@ int a5xx_preemption_init(struct adreno_device *adreno_dev)
	timer_setup(&preempt->timer, _a5xx_preemption_timer, 0);

	/* Allocate mem for storing preemption counters */
	ret = kgsl_allocate_global(device, &preempt->counters,
	ret = kgsl_allocate_global(device, &preempt->scratch,
		adreno_dev->num_ringbuffers *
		A5XX_CP_CTXRECORD_PREEMPTION_COUNTER_SIZE, 0, 0,
		"preemption_counters");
	if (ret)
		goto err;

	addr = preempt->counters.gpuaddr;
	addr = preempt->scratch.gpuaddr;

	/* Allocate mem for storing preemption switch record */
	FOR_EACH_RINGBUFFER(adreno_dev, rb, i) {
Loading