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

Commit 7ed8b14e authored by Jordan Crouse's avatar Jordan Crouse
Browse files

msm: kgsl: Set the DDR high bank bit if specified in the device tree



On 5XX targets we need to program the bit of the highest DDR bank
into a number of registers, one of which is protected which would
cause problems if the user mode driver tried to write to it.

Specify the high bank bit in the device tree files, set the
problematic register in the kernel and then pass the value up to
the user mode driver as a property and let them program the
other registers.  This makes the device tree the authoratative
source of the high bit value which is exactly how it should be.

If the value isn't specified by the device tree for whatever reason
return an error for the property request - that will give the UMD
a clue that the value wasn't specified and they should just set a
default.

CRs-Fixed: 970272
Change-Id: Ic0dedbad830321329b74da7fa3e172fdaf765c4d
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
parent c1551685
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -115,6 +115,10 @@ Optional Properties:
				mask   - mask for the relevant bits in the efuse register.
				shift  - number of bits to right shift to get the speed bin
				value.
- qcom,highest-bank-bit:
				Specify the bit of the highest DDR bank. This
				is programmed into protected registers and also
				passed to the user as a property.

- qcom,l2pc-cpu-mask:
				Disables L2PC on masked CPUs when any of Graphics
+4 −1
Original line number Diff line number Diff line
/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -569,6 +569,7 @@

/* RB registers */
#define A5XX_RB_ADDR_MODE_CNTL              0xCC5
#define A5XX_RB_MODE_CNTL                   0xCC6
#define A5XX_RB_PERFCTR_RB_SEL_0            0xCD0
#define A5XX_RB_PERFCTR_RB_SEL_1            0xCD1
#define A5XX_RB_PERFCTR_RB_SEL_2            0xCD2
@@ -656,6 +657,7 @@
#define A5XX_UCHE_GMEM_RANGE_MIN_HI         0xE8C
#define A5XX_UCHE_GMEM_RANGE_MAX_LO         0xE8D
#define A5XX_UCHE_GMEM_RANGE_MAX_HI         0xE8E
#define A5XX_UCHE_DBG_ECO_CNTL_2            0xE8F
#define A5XX_UCHE_INVALIDATE0               0xE95
#define A5XX_UCHE_CACHE_WAYS                0xE96
#define A5XX_UCHE_PERFCTR_UCHE_SEL_0        0xEA0
@@ -697,6 +699,7 @@

/* TP registers */
#define A5XX_TPL1_ADDR_MODE_CNTL            0xF01
#define A5XX_TPL1_MODE_CNTL                 0xF02
#define A5XX_TPL1_PERFCTR_TP_SEL_0          0xF10
#define A5XX_TPL1_PERFCTR_TP_SEL_1          0xF11
#define A5XX_TPL1_PERFCTR_TP_SEL_2          0xF12
+23 −0
Original line number Diff line number Diff line
@@ -1826,6 +1826,29 @@ static int adreno_getproperty(struct kgsl_device *device,
			status = 0;
		}
		break;
	case KGSL_PROP_HIGHEST_BANK_BIT:
		{
			unsigned int bit;

			if (sizebytes < sizeof(unsigned int)) {
				status = -EINVAL;
				break;
			}

			if (of_property_read_u32(device->pdev->dev.of_node,
				"qcom,highest-bank-bit", &bit)) {
					status = -EINVAL;
					break;
			}

			if (copy_to_user(value, &bit, sizeof(bit))) {
				status = -EFAULT;
				break;
			}
		}
		status = 0;
		break;

	default:
		status = -EINVAL;
	}
+24 −1
Original line number Diff line number Diff line
@@ -1878,7 +1878,7 @@ static void a5xx_start(struct adreno_device *adreno_dev)
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device);
	struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
	unsigned int i;
	unsigned int i, bit;
	struct adreno_ringbuffer *rb;
	uint64_t def_ttbr0;
	uint32_t contextidr;
@@ -2055,6 +2055,29 @@ static void a5xx_start(struct adreno_device *adreno_dev)

	kgsl_regwrite(device, A5XX_RBBM_AHB_CNTL2, 0x0000003F);

	if (!of_property_read_u32(device->pdev->dev.of_node,
		"qcom,highest-bank-bit", &bit)) {
		if (bit >= 13 && bit <= 16) {
			bit = (bit - 13) & 0x03;

			/*
			 * Program the highest DDR bank bit that was passed in
			 * from the DT in a handful of registers. Some of these
			 * registers will also be written by the UMD, but we
			 * want to program them in case we happen to use the
			 * UCHE before the UMD does
			 */

			kgsl_regwrite(device, A5XX_TPL1_MODE_CNTL, bit << 7);
			kgsl_regwrite(device, A5XX_RB_MODE_CNTL, bit << 1);

			if (adreno_is_a540(adreno_dev))
				kgsl_regwrite(device, A5XX_UCHE_DBG_ECO_CNTL_2,
					bit);
		}

	}

	if (adreno_is_preemption_enabled(adreno_dev)) {
		struct kgsl_pagetable *pt = device->mmu.defaultpagetable;

+1 −0
Original line number Diff line number Diff line
@@ -302,6 +302,7 @@ enum kgsl_timestamp_type {
#define KGSL_PROP_SP_GENERIC_MEM	0x14
#define KGSL_PROP_UCODE_VERSION		0x15
#define KGSL_PROP_GPMU_VERSION		0x16
#define KGSL_PROP_HIGHEST_BANK_BIT	0x17

struct kgsl_shadowprop {
	unsigned long gpuaddr;