diff --git a/Documentation/devicetree/bindings/gpu/adreno.txt b/Documentation/devicetree/bindings/gpu/adreno.txt index cb7189b6e954..202335a3207f 100644 --- a/Documentation/devicetree/bindings/gpu/adreno.txt +++ b/Documentation/devicetree/bindings/gpu/adreno.txt @@ -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 diff --git a/drivers/gpu/msm/a5xx_reg.h b/drivers/gpu/msm/a5xx_reg.h index 8e33c3e8b455..45aabeb3c4a2 100644 --- a/drivers/gpu/msm/a5xx_reg.h +++ b/drivers/gpu/msm/a5xx_reg.h @@ -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 diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index b800ce54964e..ba2533bd4c4c 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -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; } diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c index 299eb96295a2..d25218ad7e96 100644 --- a/drivers/gpu/msm/adreno_a5xx.c +++ b/drivers/gpu/msm/adreno_a5xx.c @@ -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; diff --git a/include/uapi/linux/msm_kgsl.h b/include/uapi/linux/msm_kgsl.h index fb944467f75b..f7c8ac15f21b 100644 --- a/include/uapi/linux/msm_kgsl.h +++ b/include/uapi/linux/msm_kgsl.h @@ -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;