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:
parent
8cd1ff747d
commit
5c39fe697f
5 changed files with 56 additions and 2 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue