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

Commit 75a9117c authored by Harshdeep Dhatt's avatar Harshdeep Dhatt
Browse files

msm: kgsl: Keep a copy of CP INIT cmdstream



This way, we don't have to do checks when composing the CP INIT
cmdstream. This will also be used by eCP.

Change-Id: I91dc54b18aee0443d5a2724daeaadc5224de1a92
Signed-off-by: default avatarHarshdeep Dhatt <hdhatt@codeaurora.org>
parent e9fad773
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -1830,6 +1830,12 @@ static int adreno_init(struct kgsl_device *device)
	if (ret)
		return ret;

	if (gpudev->init != NULL) {
		ret = gpudev->init(adreno_dev);
		if (ret)
			return ret;
	}

	ret = gmu_core_init(device);
	if (ret)
		return ret;
@@ -1853,9 +1859,6 @@ static int adreno_init(struct kgsl_device *device)
	if (ADRENO_GPUREV(adreno_dev) < 600)
		kgsl_pwrctrl_change_state(device, KGSL_STATE_SLUMBER);

	if (gpudev->init != NULL)
		gpudev->init(adreno_dev);

	set_bit(ADRENO_DEVICE_INITIALIZED, &adreno_dev->priv);

	/*
+3 −2
Original line number Diff line number Diff line
@@ -536,7 +536,8 @@ struct adreno_device {
	 * @critpkts: Memory descriptor for 5xx secure critical packets
	 */
	struct kgsl_memdesc *critpkts_secure;

	/** @cp_init_cmds: A copy of the CP INIT commands */
	const void *cp_init_cmds;
};

/**
@@ -776,7 +777,7 @@ struct adreno_gpudev {
	void (*snapshot)(struct adreno_device *adreno_dev,
				struct kgsl_snapshot *snapshot);
	void (*platform_setup)(struct adreno_device *adreno_dev);
	void (*init)(struct adreno_device *adreno_dev);
	int (*init)(struct adreno_device *adreno_dev);
	void (*remove)(struct adreno_device *adreno_dev);
	int (*rb_start)(struct adreno_device *adreno_dev);
	int (*microcode_read)(struct adreno_device *adreno_dev);
+48 −24
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
 */

#include <linux/firmware.h>
@@ -124,6 +124,8 @@ static const unsigned int _a3xx_pwron_fixup_fs_instructions[] = {
	0x00000000, 0x03000000, 0x00000000, 0x00000000,
};

static int a3xx_get_cp_init_cmds(struct adreno_device *adreno_dev);

static void a3xx_efuse_speed_bin(struct adreno_device *adreno_dev)
{
	unsigned int val;
@@ -623,28 +625,7 @@ static int a3xx_send_me_init(struct adreno_device *adreno_dev,
	if (cmds == NULL)
		return -ENOSPC;

	*cmds++ = cp_type3_packet(CP_ME_INIT, 17);

	*cmds++ = 0x000003f7;
	*cmds++ = 0x00000000;
	*cmds++ = 0x00000000;
	*cmds++ = 0x00000000;
	*cmds++ = 0x00000080;
	*cmds++ = 0x00000100;
	*cmds++ = 0x00000180;
	*cmds++ = 0x00006600;
	*cmds++ = 0x00000150;
	*cmds++ = 0x0000014e;
	*cmds++ = 0x00000154;
	*cmds++ = 0x00000001;
	*cmds++ = 0x00000000;
	*cmds++ = 0x00000000;

	/* Enable protected mode registers for A3XX */
	*cmds++ = 0x20000000;

	*cmds++ = 0x00000000;
	*cmds++ = 0x00000000;
	memcpy(cmds, adreno_dev->cp_init_cmds, 18 << 2);

	ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000);
	if (ret) {
@@ -685,13 +666,56 @@ static int a3xx_rb_start(struct adreno_device *adreno_dev)
	return a3xx_send_me_init(adreno_dev, rb);
}

static int a3xx_get_cp_init_cmds(struct adreno_device *adreno_dev)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	u32 *cmds;

	if (adreno_dev->cp_init_cmds)
		return 0;

	adreno_dev->cp_init_cmds = devm_kzalloc(&device->pdev->dev, 18 << 2,
			GFP_KERNEL);
	if (!adreno_dev->cp_init_cmds)
		return -ENOMEM;

	cmds = (u32 *)adreno_dev->cp_init_cmds;

	*cmds++ = cp_type3_packet(CP_ME_INIT, 17);

	*cmds++ = 0x000003f7;
	*cmds++ = 0x00000000;
	*cmds++ = 0x00000000;
	*cmds++ = 0x00000000;
	*cmds++ = 0x00000080;
	*cmds++ = 0x00000100;
	*cmds++ = 0x00000180;
	*cmds++ = 0x00006600;
	*cmds++ = 0x00000150;
	*cmds++ = 0x0000014e;
	*cmds++ = 0x00000154;
	*cmds++ = 0x00000001;
	*cmds++ = 0x00000000;
	*cmds++ = 0x00000000;

	/* Enable protected mode registers for A3XX */
	*cmds++ = 0x20000000;

	*cmds++ = 0x00000000;
	*cmds++ = 0x00000000;

	return 0;
}

/*
 * a3xx_init() - Initialize gpu specific data
 * @adreno_dev: Pointer to adreno device
 */
static void a3xx_init(struct adreno_device *adreno_dev)
static int a3xx_init(struct adreno_device *adreno_dev)
{
	_a3xx_pwron_fixup(adreno_dev);

	return a3xx_get_cp_init_cmds(adreno_dev);
}

/*
+52 −41
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ static int _read_fw2_block_header(struct kgsl_device *device,
		uint32_t id, uint32_t major, uint32_t minor);
static void a5xx_gpmu_reset(struct work_struct *work);
static int a5xx_gpmu_init(struct adreno_device *adreno_dev);
static int a5xx_get_cp_init_cmds(struct adreno_device *adreno_dev);

/**
 * Number of times to check if the regulator enabled before
@@ -185,7 +186,7 @@ static int a5xx_critical_packet_construct(struct adreno_device *adreno_dev)
	return 0;
}

static void a5xx_init(struct adreno_device *adreno_dev)
static int a5xx_init(struct adreno_device *adreno_dev)
{
	const struct adreno_a5xx_core *a5xx_core = to_a5xx_core(adreno_dev);

@@ -199,8 +200,9 @@ static void a5xx_init(struct adreno_device *adreno_dev)
	if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_CRITICAL_PACKETS))
		a5xx_critical_packet_construct(adreno_dev);


	a5xx_crashdump_init(adreno_dev);

	return a5xx_get_cp_init_cmds(adreno_dev);
}

const static struct {
@@ -1739,42 +1741,6 @@ static int _me_init_ucode_workarounds(struct adreno_device *adreno_dev)
		CP_INIT_DEFAULT_RESET_STATE | \
		CP_INIT_UCODE_WORKAROUND_MASK)

static void _set_ordinals(struct adreno_device *adreno_dev,
		unsigned int *cmds, unsigned int count)
{
	unsigned int *start = cmds;

	/* Enabled ordinal mask */
	*cmds++ = CP_INIT_MASK;

	if (CP_INIT_MASK & CP_INIT_MAX_CONTEXT)
		*cmds++ = 0x00000003;

	if (CP_INIT_MASK & CP_INIT_ERROR_DETECTION_CONTROL)
		*cmds++ = 0x20000000;

	if (CP_INIT_MASK & CP_INIT_HEADER_DUMP) {
		/* Header dump address */
		*cmds++ = 0x00000000;
		/* Header dump enable and dump size */
		*cmds++ = 0x00000000;
	}

	if (CP_INIT_MASK & CP_INIT_DRAWCALL_FILTER_RANGE) {
		/* Start range */
		*cmds++ = 0x00000000;
		/* End range (inclusive) */
		*cmds++ = 0x00000000;
	}

	if (CP_INIT_MASK & CP_INIT_UCODE_WORKAROUND_MASK)
		*cmds++ = _me_init_ucode_workarounds(adreno_dev);

	/* Pad rest of the cmds with 0's */
	while ((unsigned int)(cmds - start) < count)
		*cmds++ = 0x0;
}

static int a5xx_critical_packet_submit(struct adreno_device *adreno_dev,
					struct adreno_ringbuffer *rb)
{
@@ -1800,6 +1766,53 @@ static int a5xx_critical_packet_submit(struct adreno_device *adreno_dev,
	return ret;
}

static int a5xx_get_cp_init_cmds(struct adreno_device *adreno_dev)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	u32 *cmds, i = 0;

	if (adreno_dev->cp_init_cmds)
		return 0;

	adreno_dev->cp_init_cmds = devm_kzalloc(&device->pdev->dev, 9 << 2,
				GFP_KERNEL);

	if (!adreno_dev->cp_init_cmds)
		return -ENOMEM;

	cmds = (u32 *)adreno_dev->cp_init_cmds;

	cmds[i++] = cp_type7_packet(CP_ME_INIT, 8);

	/* Enabled ordinal mask */
	cmds[i++] = CP_INIT_MASK;

	if (CP_INIT_MASK & CP_INIT_MAX_CONTEXT)
		cmds[i++] = 0x00000003;

	if (CP_INIT_MASK & CP_INIT_ERROR_DETECTION_CONTROL)
		cmds[i++] = 0x20000000;

	if (CP_INIT_MASK & CP_INIT_HEADER_DUMP) {
		/* Header dump address */
		cmds[i++] = 0x00000000;
		/* Header dump enable and dump size */
		cmds[i++] = 0x00000000;
	}

	if (CP_INIT_MASK & CP_INIT_DRAWCALL_FILTER_RANGE) {
		/* Start range */
		cmds[i++] = 0x00000000;
		/* End range (inclusive) */
		cmds[i++] = 0x00000000;
	}

	if (CP_INIT_MASK & CP_INIT_UCODE_WORKAROUND_MASK)
		cmds[i++] = _me_init_ucode_workarounds(adreno_dev);

	return 0;
}

/*
 * a5xx_send_me_init() - Initialize ringbuffer
 * @adreno_dev: Pointer to adreno device
@@ -1819,9 +1832,7 @@ static int a5xx_send_me_init(struct adreno_device *adreno_dev,
	if (cmds == NULL)
		return -ENOSPC;

	*cmds++ = cp_type7_packet(CP_ME_INIT, 8);

	_set_ordinals(adreno_dev, cmds, 8);
	memcpy(cmds, adreno_dev->cp_init_cmds, 9 << 2);

	ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000);
	if (ret)
+40 −25
Original line number Diff line number Diff line
@@ -99,10 +99,11 @@ static u32 a612_pwrup_reglist[] = {
	A6XX_RBBM_PERFCTR_CNTL,
};

static void a6xx_init(struct adreno_device *adreno_dev)
static int a6xx_get_cp_init_cmds(struct adreno_device *adreno_dev);

static int a6xx_init(struct adreno_device *adreno_dev)
{
	const struct adreno_a6xx_core *a6xx_core = to_a6xx_core(adreno_dev);
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);

	adreno_dev->highest_bank_bit = a6xx_core->highest_bank_bit;

@@ -111,10 +112,16 @@ static void a6xx_init(struct adreno_device *adreno_dev)

	a6xx_crashdump_init(adreno_dev);

	if (IS_ERR_OR_NULL(adreno_dev->pwrup_reglist))
		adreno_dev->pwrup_reglist = kgsl_allocate_global(device,
	if (IS_ERR_OR_NULL(adreno_dev->pwrup_reglist)) {
		adreno_dev->pwrup_reglist =
				kgsl_allocate_global(KGSL_DEVICE(adreno_dev),
					PAGE_SIZE, 0, KGSL_MEMDESC_PRIVILEGED,
					"powerup_register_list");
		if (IS_ERR(adreno_dev->pwrup_reglist))
			return PTR_ERR(adreno_dev->pwrup_reglist);
	}

	return a6xx_get_cp_init_cmds(adreno_dev);
}

static void a6xx_protect_init(struct adreno_device *adreno_dev)
@@ -663,44 +670,54 @@ static int a6xx_microcode_load(struct adreno_device *adreno_dev)
		CP_INIT_OPERATION_MODE_MASK | \
		CP_INIT_REGISTER_INIT_LIST_WITH_SPINLOCK)

static void _set_ordinals(struct adreno_device *adreno_dev,
		unsigned int *cmds, unsigned int count)
static int a6xx_get_cp_init_cmds(struct adreno_device *adreno_dev)
{
	unsigned int *start = cmds;
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	u32 *cmds, i = 0;

	if (adreno_dev->cp_init_cmds)
		return 0;

	adreno_dev->cp_init_cmds = devm_kzalloc(&device->pdev->dev, 12 << 2,
				GFP_KERNEL);
	if (!adreno_dev->cp_init_cmds)
		return -ENOMEM;

	cmds = (u32 *)adreno_dev->cp_init_cmds;

	cmds[i++] = cp_type7_packet(CP_ME_INIT, 11);

	/* Enabled ordinal mask */
	*cmds++ = CP_INIT_MASK;
	cmds[i++] = CP_INIT_MASK;

	if (CP_INIT_MASK & CP_INIT_MAX_CONTEXT)
		*cmds++ = 0x00000003;
		cmds[i++] = 0x00000003;

	if (CP_INIT_MASK & CP_INIT_ERROR_DETECTION_CONTROL)
		*cmds++ = 0x20000000;
		cmds[i++] = 0x20000000;

	if (CP_INIT_MASK & CP_INIT_HEADER_DUMP) {
		/* Header dump address */
		*cmds++ = 0x00000000;
		cmds[i++] = 0x00000000;
		/* Header dump enable and dump size */
		*cmds++ = 0x00000000;
		cmds[i++] = 0x00000000;
	}

	if (CP_INIT_MASK & CP_INIT_UCODE_WORKAROUND_MASK)
		*cmds++ = 0x00000000;
		cmds[i++] = 0x00000000;

	if (CP_INIT_MASK & CP_INIT_OPERATION_MODE_MASK)
		*cmds++ = 0x00000002;
		cmds[i++] = 0x00000002;

	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;
		cmds[i++] = lower_32_bits(gpuaddr);
		cmds[i++] = upper_32_bits(gpuaddr);
		cmds[i++] =  0;
	}

	/* Pad rest of the cmds with 0's */
	while ((unsigned int)(cmds - start) < count)
		*cmds++ = 0x0;
	return 0;
}

/*
@@ -721,9 +738,7 @@ static int a6xx_send_cp_init(struct adreno_device *adreno_dev,
	if (IS_ERR(cmds))
		return PTR_ERR(cmds);

	*cmds++ = cp_type7_packet(CP_ME_INIT, 11);

	_set_ordinals(adreno_dev, cmds, 11);
	memcpy(cmds, adreno_dev->cp_init_cmds, 12 << 2);

	ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000);
	if (ret) {