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: Jordan Crouse <jcrouse@codeaurora.org>
This commit is contained in:
Jordan Crouse 2016-02-10 09:28:52 -07:00 committed by David Keitel
parent 8cd1ff747d
commit 5c39fe697f
5 changed files with 56 additions and 2 deletions

View file

@ -120,6 +120,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

View file

@ -1,4 +1,4 @@
/* 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

View file

@ -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;
}

View file

@ -1889,7 +1889,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;
@ -2066,6 +2066,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;

View file

@ -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;