Re: [Freedreno] [PATCH 8/9] drm/msm/a6xx: Add support for an interconnect path

2018-08-27 Thread kbuild test robot
Hi Jordan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on robclark/msm-next]
[also build test ERROR on v4.19-rc1 next-20180827]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Jordan-Crouse/Add-interconnect-support-bindings-for-A630-GPU/20180828-004407
base:   git://people.freedesktop.org/~robclark/linux msm-next
config: arm-defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=7.2.0 make.cross ARCH=arm 

All errors (new ones prefixed by >>):

   In file included from drivers/gpu/drm/msm/adreno/adreno_gpu.h:25:0,
from drivers/gpu/drm/msm/adreno/adreno_device.c:20:
>> drivers/gpu/drm/msm/msm_gpu.h:23:10: fatal error: linux/interconnect.h: No 
>> such file or directory
#include 
 ^~
   compilation terminated.
--
>> drivers/gpu/drm/msm/adreno/adreno_gpu.c:24:10: fatal error: 
>> linux/interconnect.h: No such file or directory
#include 
 ^~
   compilation terminated.
--
>> drivers/gpu/drm/msm/adreno/a6xx_gmu.c:7:10: fatal error: 
>> linux/interconnect.h: No such file or directory
#include 
 ^~
   compilation terminated.

vim +23 drivers/gpu/drm/msm/msm_gpu.h

20  
21  #include 
22  #include 
  > 23  #include 
24  

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v2 5/5] drm/msm/A6xx: Add devfreq support for A6xx

2018-08-27 Thread Jordan Crouse
On Mon, Aug 27, 2018 at 12:47:20PM +0530, Sharat Masetty wrote:
> Implement routines to estimate GPU busy time and fetching the
> current frequency for the polling interval. This is required by
> the devfreq framework which recommends a frequency change if needed.
> The driver code then tries to set this new frequency on the GPU by
> sending an Out Of Band(OOB) request to the GMU.
> 
> Signed-off-by: Sharat Masetty 
> ---
>  drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 39 
> +++
>  drivers/gpu/drm/msm/adreno/a6xx_gmu.h |  2 ++
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 27 
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.h |  2 ++
>  4 files changed, 66 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
> b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> index f6634c0..3a7b899 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> @@ -67,7 +67,7 @@ static bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu)
>   A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_GX_HM_CLK_OFF));
>  }
>  
> -static int a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index)
> +static int __a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index)
>  {
>   gmu_write(gmu, REG_A6XX_GMU_DCVS_ACK_OPTION, 0);
>  
> @@ -84,7 +84,38 @@ static int a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int 
> index)
>   a6xx_gmu_set_oob(gmu, GMU_OOB_DCVS_SET);
>   a6xx_gmu_clear_oob(gmu, GMU_OOB_DCVS_SET);
>  
> - return gmu_read(gmu, REG_A6XX_GMU_DCVS_RETURN);
> + if (gmu_read(gmu, REG_A6XX_GMU_DCVS_RETURN) != 0)
> + return -EINVAL;
> +
> + gmu->freq = gmu->gpu_freqs[index];
> +
> + return 0;
> +}

While I was working on the interconnect patches it occurred to me that the upper
levels doesn't really care what the value of A6XX_GMU_DCVS_RETURN is so we might
want to just print an error message and return nothing. If the DCVS set didn't
work we might be headed for disaster on the GMU side but its more likely that
we'll just continue along at the current frequency for the next cycle so it
isn't terribly harmful.

Jordan

-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v2 4/5] drm/msm: re-factor devfreq code

2018-08-27 Thread Jordan Crouse
On Mon, Aug 27, 2018 at 12:47:19PM +0530, Sharat Masetty wrote:
> The devfreq framework requires the drivers to provide busy time estimations.
> The GPU driver relies on the hardware performance counteres for the busy time
> estimations, but different hardware revisions have counters which can be
> sourced from different clocks. So the busy time estimation will be target
> dependent.  Additionally on targets where the clocks are completely controlled
> by the on chip microcontroller, fetching and setting the current GPU frequency
> will be different. This patch aims to embrace these differences by 
> re-factoring
> the devfreq code a bit.
> 
> Signed-off-by: Sharat Masetty 
> ---
>  drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 16 +---
>  drivers/gpu/drm/msm/msm_gpu.c | 49 
> ---
>  drivers/gpu/drm/msm/msm_gpu.h |  5 +++-
>  3 files changed, 44 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c 
> b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> index 897f3e2..043e680 100644
> --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> @@ -1369,12 +1369,20 @@ static struct msm_ringbuffer *a5xx_active_ring(struct 
> msm_gpu *gpu)
>   return a5xx_gpu->cur_ring;
>  }
>  
> -static int a5xx_gpu_busy(struct msm_gpu *gpu, uint64_t *value)
> +static unsigned long a5xx_gpu_busy(struct msm_gpu *gpu)
>  {
> - *value = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_RBBM_0_LO,
> - REG_A5XX_RBBM_PERFCTR_RBBM_0_HI);
> + u64 busy_cycles;
> + unsigned long busy_time;
>  
> - return 0;
> + busy_cycles = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_RBBM_0_LO,
> + REG_A5XX_RBBM_PERFCTR_RBBM_0_HI);
> +
> + busy_time = (busy_cycles - gpu->devfreq.busy_cycles) /
> + (clk_get_rate(gpu->core_clk) / 100);
> +
> + gpu->devfreq.busy_cycles = busy_cycles;
> +
> + return busy_time;
>  }
>  
>  static const struct adreno_gpu_funcs funcs = {
> diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
> index 8d6bc0c..26c1c3a 100644
> --- a/drivers/gpu/drm/msm/msm_gpu.c
> +++ b/drivers/gpu/drm/msm/msm_gpu.c
> @@ -36,12 +36,16 @@ static int msm_devfreq_target(struct device *dev, 
> unsigned long *freq,
>   struct msm_gpu *gpu = platform_get_drvdata(to_platform_device(dev));
>   struct dev_pm_opp *opp;
>  
> - opp = dev_pm_opp_find_freq_ceil(dev, freq);
> + opp = devfreq_recommended_opp(dev, freq, flags);
> + if (IS_ERR(opp))
> + return PTR_ERR(opp);
>  
> - if (!IS_ERR(opp)) {
> + if (gpu->funcs->gpu_set_freq)
> + gpu->funcs->gpu_set_freq(gpu, (u64)*freq);

Depending on how the interconnect patches end up looking it might make more
sense for us to send the OPP itself to gpu_set_freq() but we'll put a pin in
that until we know more.

Jordan

-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v2 2/5] drm/msm: unregister devfreq upon clean up

2018-08-27 Thread Jordan Crouse
On Mon, Aug 27, 2018 at 12:47:17PM +0530, Sharat Masetty wrote:
> Call the devfreq_remove_device() API to remove the GPU devfreq instance
> during GPU driver cleanup.
> 
> Signed-off-by: Sharat Masetty 
> ---
>  drivers/gpu/drm/msm/msm_gpu.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
> index 04f9604..8d6bc0c 100644
> --- a/drivers/gpu/drm/msm/msm_gpu.c
> +++ b/drivers/gpu/drm/msm/msm_gpu.c
> @@ -970,6 +970,8 @@ void msm_gpu_cleanup(struct msm_gpu *gpu)
>  
>   WARN_ON(!list_empty(>active_list));
>  
> + devm_devfreq_remove_device(>pdev->dev, gpu->devfreq.devfreq);
> +

Sorry, I don't think I made myself clear. We should use devm_devfreq_add_device
during initialization so that we don't need to do a devfreq_remove_device during
cleanup. This will still be a one line patch but in a different location.

Jordan

>   for (i = 0; i < ARRAY_SIZE(gpu->rb); i++) {
>   msm_ringbuffer_destroy(gpu->rb[i]);
>   gpu->rb[i] = NULL;
> -- 
> 1.9.1
> 

-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 6/9] PM / OPP: dt-bindings: Add opp-interconnect-bw

2018-08-27 Thread Jordan Crouse
Add the "opp-interconnect-bw" property to specify the
average and peak bandwidth for an interconnect path for
a specific operating power point. A separate bandwidth
pair can be specified for each of the interconnects
defined for the device by appending the interconnect
name to the property.

Signed-off-by: Jordan Crouse 
---
 Documentation/devicetree/bindings/opp/opp.txt | 36 +++
 1 file changed, 36 insertions(+)

diff --git a/Documentation/devicetree/bindings/opp/opp.txt 
b/Documentation/devicetree/bindings/opp/opp.txt
index c396c4c0af92..d714c084f36d 100644
--- a/Documentation/devicetree/bindings/opp/opp.txt
+++ b/Documentation/devicetree/bindings/opp/opp.txt
@@ -170,6 +170,11 @@ Optional properties:
   functioning of the current device at the current OPP (where this property is
   present).
 
+- opp-interconnect-bw-: This is an array of pairs specifying the average
+  and peak bandwidth in bytes per second for the interconnect path known by
+  'name'.  This should match the name(s) specified by interconnect-names in the
+  device definition.
+
 Example 1: Single cluster Dual-core ARM cortex A9, switch DVFS states together.
 
 / {
@@ -543,3 +548,34 @@ Example 6: opp-microvolt-, opp-microamp-:
};
};
 };
+
+Example 7: opp-interconnect-bw:
+(example: leaf device with frequency and BW quotas)
+
+/ {
+   soc {
+   gpu@500 {
+   ...
+   interconnects = < 26  512>;
+   interconnect-names = "port0";
+   ...
+   operating-points-v2 = <_opp_table>;
+   };
+   };
+
+   gpu_opp_table: opp_table0 {
+   compatible = "operating-points-v2";
+
+   opp-71000 {
+   op-hz = /bits/ 64 <71000>;
+   /* Set peak bandwidth @ 7216000 KB/s */
+   opp-interconnect-bw-port0 = /bits/ 64 <0 721600>;
+   };
+
+   opp-21000 {
+   op-hz = /bits/ 64 <21000>;
+   /* Set peak bandwidth @ 120 KB/s */
+   opp-interconnect-bw-port0 = /bits/ 64 <0 12>;
+   };
+   };
+};
-- 
2.18.0

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 9/9] arm64: dts: Add interconnect for the GPU on SDM845

2018-08-27 Thread Jordan Crouse
Add the interconnect properties for the GPU on SDM845
and set the corresponding OPP bandwidth values.

Signed-off-by: Jordan Crouse 
---
 arch/arm64/boot/dts/qcom/sdm845.dtsi | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi 
b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 10db0ceb3699..1e67f4fdd7d1 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -198,36 +198,43 @@ gpu_opp_table: adreno-opp-table {
opp-71000 {
opp-hz = /bits/ 64 <71000>;
qcom,level = <416>;
+   opp-interconnect-bw-port0 = /bits/ 64 <0 721600>;
};
 
opp-67500 {
opp-hz = /bits/ 64 <67500>;
qcom,level = <384>;
+   opp-interconnect-bw-port0 = /bits/ 64 <0 721600>;
};
 
opp-59600 {
opp-hz = /bits/ 64 <59600>;
qcom,level = <320>;
+   opp-interconnect-bw-port0 = /bits/ 64 <0 518400>;
};
 
opp-52000 {
opp-hz = /bits/ 64 <52000>;
qcom,level = <256>;
+   opp-interconnect-bw-port0 = /bits/ 64 <0 406800>;
};
 
opp-41400 {
opp-hz = /bits/ 64 <41400>;
qcom,level = <192>;
+   opp-interconnect-bw-port0 = /bits/ 64 <0 307200>;
};
 
opp-34200 {
opp-hz = /bits/ 64 <34200>;
qcom,level = <128>;
+   opp-interconnect-bw-port0 = /bits/ 64 <0 218800>;
};
 
opp-25700 {
opp-hz = /bits/ 64 <25700>;
qcom,level = <64>;
+   opp-interconnect-bw-port0 = /bits/ 64 <0 12>;
};
};
 
@@ -418,6 +425,9 @@ gpu_opp_table: adreno-opp-table {
 
operating-points-v2 = <_opp_table>;
 
+   interconnects = < 26  512>;
+   interconnect-names = "port0";
+
qcom,gmu = <>;
};
 
-- 
2.18.0

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 8/9] drm/msm/a6xx: Add support for an interconnect path

2018-08-27 Thread Jordan Crouse
Add support for setting the OPP defined bandwidth for a given
GPU frequency value for a6xx. On sdm845 even though the GPU
frequency is set by the GMU but the bus bandwidth quota is
set by the CPU.

Signed-off-by: Jordan Crouse 
---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c   | 27 +++--
 drivers/gpu/drm/msm/adreno/adreno_gpu.c |  7 +++
 drivers/gpu/drm/msm/msm_gpu.h   |  3 +++
 3 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index d0dac4c2e3e7..d63eefc7c74d 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -4,6 +4,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "a6xx_gpu.h"
@@ -65,8 +66,15 @@ static bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu)
A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_GX_HM_CLK_OFF));
 }
 
-static int a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index)
+static void a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index)
 {
+   struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
+   struct adreno_gpu *adreno_gpu = _gpu->base;
+   struct msm_gpu *gpu = _gpu->base;
+   struct dev_pm_opp *opp;
+   u64 ab, ib;
+   int ret;
+
gmu_write(gmu, REG_A6XX_GMU_DCVS_ACK_OPTION, 0);
 
gmu_write(gmu, REG_A6XX_GMU_DCVS_PERF_SETTING,
@@ -82,7 +90,22 @@ static int a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index)
a6xx_gmu_set_oob(gmu, GMU_OOB_DCVS_SET);
a6xx_gmu_clear_oob(gmu, GMU_OOB_DCVS_SET);
 
-   return gmu_read(gmu, REG_A6XX_GMU_DCVS_RETURN);
+   ret = gmu_read(gmu, REG_A6XX_GMU_DCVS_RETURN);
+   if (ret)
+   dev_err(gmu->dev, "GMU set GPU frequency error: %d\n", ret);
+
+   /* Set the interconnect bandwidth from the CPU */
+   if (IS_ERR_OR_NULL(gpu->icc_path))
+   return;
+
+   opp = dev_pm_opp_find_freq_exact(>pdev->dev,
+   gmu->gpu_freqs[index], true);
+   if (!IS_ERR_OR_NULL(opp)) {
+   if (!dev_pm_opp_get_interconnect_bw(opp, "port0", , ))
+   icc_set(gpu->icc_path, ab, ib);
+
+   dev_pm_opp_put(opp);
+   }
 }
 
 static bool a6xx_gmu_check_idle_level(struct a6xx_gmu *gmu)
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c 
b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index da1363a0c54d..2eace9bf32c7 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "adreno_gpu.h"
 #include "msm_gem.h"
 #include "msm_mmu.h"
@@ -694,6 +695,9 @@ static int adreno_get_pwrlevels(struct device *dev,
 
DBG("fast_rate=%u, slow_rate=2700", gpu->fast_rate);
 
+   /* Check for an interconnect path for the bus */
+   gpu->icc_path = of_icc_get(dev, "port0");
+
return 0;
 }
 
@@ -732,10 +736,13 @@ int adreno_gpu_init(struct drm_device *drm, struct 
platform_device *pdev,
 
 void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)
 {
+   struct msm_gpu *gpu = _gpu->base;
unsigned int i;
 
for (i = 0; i < ARRAY_SIZE(adreno_gpu->info->fw); i++)
release_firmware(adreno_gpu->fw[i]);
 
+   icc_put(gpu->icc_path);
+
msm_gpu_cleanup(_gpu->base);
 }
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index 9122ee6e55e4..9c851d03f344 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -20,6 +20,7 @@
 
 #include 
 #include 
+#include 
 
 #include "msm_drv.h"
 #include "msm_fence.h"
@@ -117,6 +118,8 @@ struct msm_gpu {
struct clk *ebi1_clk, *core_clk, *rbbmtimer_clk;
uint32_t fast_rate;
 
+   struct icc_path *icc_path;
+
/* Hang and Inactivity Detection:
 */
 #define DRM_MSM_INACTIVE_PERIOD   66 /* in ms (roughly four frames) */
-- 
2.18.0

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 4/9] dt-bindings: Document qcom,adreno-gmu

2018-08-27 Thread Jordan Crouse
Document the device tree bindings for the Adreno GMU device
available on Adreno a6xx targets.

Reviewed-by: Rob Herring 
Signed-off-by: Jordan Crouse 
---
 .../devicetree/bindings/display/msm/gmu.txt   | 54 +++
 .../devicetree/bindings/display/msm/gpu.txt   | 10 +++-
 2 files changed, 62 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/msm/gmu.txt

diff --git a/Documentation/devicetree/bindings/display/msm/gmu.txt 
b/Documentation/devicetree/bindings/display/msm/gmu.txt
new file mode 100644
index ..f65bb49fff36
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/msm/gmu.txt
@@ -0,0 +1,54 @@
+Qualcomm adreno/snapdragon GMU (Graphics management unit)
+
+The GMU is a programmable power controller for the GPU. the CPU controls the
+GMU which in turn handles power controls for the GPU.
+
+Required properties:
+- compatible:
+  * "qcom,adreno-gmu"
+- reg: Physical base address and length of the GMU registers.
+- reg-names: Matching names for the register regions
+  * "gmu"
+  * "gmu_pdc"
+- interrupts: The interrupt signals from the GMU.
+- interrupt-names: Matching names for the interrupts
+  * "hfi"
+  * "gmu"
+- clocks: phandles to the device clocks
+- clock-names: Matching names for the clocks
+   * "gmu"
+   * "cxo"
+   * "axi"
+   * "mnoc"
+- power-domains: should be <_gpucc GPU_CX_GDSC>
+- iommus: phandle to the adreno iommu
+- operating-points-v2: phandle to the OPP operating points
+
+Example:
+
+/ {
+   ...
+
+   gmu: gmu@506a000 {
+   compatible="qcom,adreno-gmu";
+
+   reg = <0x506a000 0x3>,
+   <0xb20 0x30>;
+   reg-names = "gmu", "gmu_pdc";
+
+   interrupts = ,
+   ;
+   interrupt-names = "hfi", "gmu";
+
+   clocks = <_gpucc GPU_CC_CX_GMU_CLK>,
+   <_gpucc GPU_CC_CXO_CLK>,
+   <_gcc GCC_DDRSS_GPU_AXI_CLK>,
+   <_gcc GCC_GPU_MEMNOC_GFX_CLK>;
+   clock-names = "gmu", "cxo", "axi", "memnoc";
+
+   power-domains = <_gpucc GPU_CX_GDSC>;
+   iommus = <_smmu 5>;
+
+   i   operating-points-v2 = <_opp_table>;
+   };
+};
diff --git a/Documentation/devicetree/bindings/display/msm/gpu.txt 
b/Documentation/devicetree/bindings/display/msm/gpu.txt
index 43fac0fe09bb..544a7510166b 100644
--- a/Documentation/devicetree/bindings/display/msm/gpu.txt
+++ b/Documentation/devicetree/bindings/display/msm/gpu.txt
@@ -8,12 +8,18 @@ Required properties:
   with the chip-id.
 - reg: Physical base address and length of the controller's registers.
 - interrupts: The interrupt signal from the gpu.
-- clocks: device clocks
+
+Optional properties.
+- clocks: device clocks. Required for a3xx, a4xx and a5xx targets. a6xx and
+  newer with a GMU attached do not have direct clock control from the CPU and
+  do not need to provide clock properties.
   See ../clocks/clock-bindings.txt for details.
-- clock-names: the following clocks are required:
+- clock-names: the following clocks can be provided:
   * "core"
   * "iface"
   * "mem_iface"
+- qcom,gmu: For a6xx and newer targets a phandle to the GMU device that will
+  control the power for the GPU
 
 Example:
 
-- 
2.18.0

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 3/9] drm/msm/a6xx: Rename gmu phandle to qcom, gmu

2018-08-27 Thread Jordan Crouse
From the review for the DT bindings for the GPU/GMU it
was suggested that the phandle for the GMU be
'qcom,gmu' instead of just 'gmu' but that never actually
got changed in the code.

Signed-off-by: Jordan Crouse 
---
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index c629f742a1d1..9a14cb3d5027 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -799,7 +799,7 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
}
 
/* Check if there is a GMU phandle and set it up */
-   node = of_parse_phandle(pdev->dev.of_node, "gmu", 0);
+   node = of_parse_phandle(pdev->dev.of_node, "qcom,gmu", 0);
 
/* FIXME: How do we gracefully handle this? */
BUG_ON(!node);
-- 
2.18.0

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 1/9] drm/msm/a6xx: rnndb updates for a6xx

2018-08-27 Thread Jordan Crouse
Update the register definitions for a6xx from the rnndb database.
Changes include new enums for upcoming devcoredump support, moving
the PDC and GCC_GX register definitions to their own domain and
various other register updates and additions.

Signed-off-by: Jordan Crouse 
---
 drivers/gpu/drm/msm/adreno/a6xx.xml.h | 642 ++
 drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h |  26 +-
 2 files changed, 416 insertions(+), 252 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx.xml.h 
b/drivers/gpu/drm/msm/adreno/a6xx.xml.h
index 87eab51f7000..7acc57b2c1be 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx.xml.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx.xml.h
@@ -8,17 +8,17 @@ This file was generated by the rules-ng-ng headergen tool in 
this git repository
 git clone https://github.com/freedreno/envytools.git
 
 The rules-ng-ng source files this header was generated from are:
-- /home/robclark/src/envytools/rnndb/adreno.xml   (501 bytes, 
from 2018-07-03 19:37:13)
-- /home/robclark/src/envytools/rnndb/freedreno_copyright.xml  (   1572 bytes, 
from 2018-07-03 19:37:13)
-- /home/robclark/src/envytools/rnndb/adreno/a2xx.xml  (  36805 bytes, 
from 2018-07-03 19:37:13)
-- /home/robclark/src/envytools/rnndb/adreno/adreno_common.xml (  13634 bytes, 
from 2018-07-03 19:37:13)
-- /home/robclark/src/envytools/rnndb/adreno/adreno_pm4.xml(  42393 bytes, 
from 2018-08-06 18:45:45)
-- /home/robclark/src/envytools/rnndb/adreno/a3xx.xml  (  83840 bytes, 
from 2018-07-03 19:37:13)
-- /home/robclark/src/envytools/rnndb/adreno/a4xx.xml  ( 112086 bytes, 
from 2018-07-03 19:37:13)
-- /home/robclark/src/envytools/rnndb/adreno/a5xx.xml  ( 147240 bytes, 
from 2018-08-06 18:45:45)
-- /home/robclark/src/envytools/rnndb/adreno/a6xx.xml  ( 101627 bytes, 
from 2018-08-06 18:45:45)
-- /home/robclark/src/envytools/rnndb/adreno/a6xx_gmu.xml  (  10431 bytes, 
from 2018-07-03 19:37:13)
-- /home/robclark/src/envytools/rnndb/adreno/ocmem.xml (   1773 bytes, 
from 2018-07-03 19:37:13)
+- ./adreno.xml   (501 bytes, from 2018-05-23 16:51:57)
+- ./freedreno_copyright.xml  (   1572 bytes, from 2016-10-24 21:12:27)
+- ./adreno/a2xx.xml  (  36805 bytes, from 2018-05-23 16:51:57)
+- ./adreno/adreno_common.xml (  13634 bytes, from 2018-05-23 16:51:57)
+- ./adreno/adreno_pm4.xml(  42393 bytes, from 2018-08-16 16:56:14)
+- ./adreno/a3xx.xml  (  83840 bytes, from 2017-12-05 18:20:27)
+- ./adreno/a4xx.xml  ( 112086 bytes, from 2018-05-23 16:51:57)
+- ./adreno/a5xx.xml  ( 147240 bytes, from 2018-08-16 16:56:14)
+- ./adreno/a6xx.xml  ( 107521 bytes, from 2018-08-16 17:44:50)
+- ./adreno/a6xx_gmu.xml  (  10431 bytes, from 2018-08-16 17:44:26)
+- ./adreno/ocmem.xml (   1773 bytes, from 2016-10-24 21:12:27)
 
 Copyright (C) 2013-2018 by the following authors:
 - Rob Clark  (robclark)
@@ -272,6 +272,98 @@ enum a6xx_cp_perfcounter_select {
PERF_CP_ALWAYS_COUNT = 0,
 };
 
+enum a6xx_shader_id {
+   A6XX_TP0_TMO_DATA = 9,
+   A6XX_TP0_SMO_DATA = 10,
+   A6XX_TP0_MIPMAP_BASE_DATA = 11,
+   A6XX_TP1_TMO_DATA = 25,
+   A6XX_TP1_SMO_DATA = 26,
+   A6XX_TP1_MIPMAP_BASE_DATA = 27,
+   A6XX_SP_INST_DATA = 41,
+   A6XX_SP_LB_0_DATA = 42,
+   A6XX_SP_LB_1_DATA = 43,
+   A6XX_SP_LB_2_DATA = 44,
+   A6XX_SP_LB_3_DATA = 45,
+   A6XX_SP_LB_4_DATA = 46,
+   A6XX_SP_LB_5_DATA = 47,
+   A6XX_SP_CB_BINDLESS_DATA = 48,
+   A6XX_SP_CB_LEGACY_DATA = 49,
+   A6XX_SP_UAV_DATA = 50,
+   A6XX_SP_INST_TAG = 51,
+   A6XX_SP_CB_BINDLESS_TAG = 52,
+   A6XX_SP_TMO_UMO_TAG = 53,
+   A6XX_SP_SMO_TAG = 54,
+   A6XX_SP_STATE_DATA = 55,
+   A6XX_HLSQ_CHUNK_CVS_RAM = 73,
+   A6XX_HLSQ_CHUNK_CPS_RAM = 74,
+   A6XX_HLSQ_CHUNK_CVS_RAM_TAG = 75,
+   A6XX_HLSQ_CHUNK_CPS_RAM_TAG = 76,
+   A6XX_HLSQ_ICB_CVS_CB_BASE_TAG = 77,
+   A6XX_HLSQ_ICB_CPS_CB_BASE_TAG = 78,
+   A6XX_HLSQ_CVS_MISC_RAM = 80,
+   A6XX_HLSQ_CPS_MISC_RAM = 81,
+   A6XX_HLSQ_INST_RAM = 82,
+   A6XX_HLSQ_GFX_CVS_CONST_RAM = 83,
+   A6XX_HLSQ_GFX_CPS_CONST_RAM = 84,
+   A6XX_HLSQ_CVS_MISC_RAM_TAG = 85,
+   A6XX_HLSQ_CPS_MISC_RAM_TAG = 86,
+   A6XX_HLSQ_INST_RAM_TAG = 87,
+   A6XX_HLSQ_GFX_CVS_CONST_RAM_TAG = 88,
+   A6XX_HLSQ_GFX_CPS_CONST_RAM_TAG = 89,
+   A6XX_HLSQ_PWR_REST_RAM = 90,
+   A6XX_HLSQ_PWR_REST_TAG = 91,
+   A6XX_HLSQ_DATAPATH_META = 96,
+   A6XX_HLSQ_FRONTEND_META = 97,
+   A6XX_HLSQ_INDIRECT_META = 98,
+   A6XX_HLSQ_BACKEND_META = 99,
+};
+
+enum a6xx_debugbus_id {
+   A6XX_DBGBUS_CP = 1,
+   A6XX_DBGBUS_RBBM = 2,
+   A6XX_DBGBUS_VBIF = 3,
+   A6XX_DBGBUS_HLSQ = 4,
+   A6XX_DBGBUS_UCHE = 5,
+   A6XX_DBGBUS_DPM = 6,
+   A6XX_DBGBUS_TESS = 7,
+   A6XX_DBGBUS_PC = 8,
+   A6XX_DBGBUS_VFDP = 9,
+   A6XX_DBGBUS_VPC = 10,
+   A6XX_DBGBUS_TSE = 11,
+   

[Freedreno] [PATCH 0/9] Add interconnect support + bindings for A630 GPU

2018-08-27 Thread Jordan Crouse
This patch series is a first stab at trying to add interconnect support
for the Adreno 630 GPU in the sdm845 SOC. The most interesting thing
for discussion is the OPP binding for specifying bandwidth - once that
is worked out the actual code to implement it is pretty straight forward
thanks to the hard work from Georgi and the PM lists.

The first 5 patches are are just a sync / reminder of the still pending
DT bindings and entries for the GPU itself - the interconnect folks can
refer to them as a reference to see what the GPU nodes will look like
but I suspect they are of more interest for the GPU.

Patch 6 adds a proposed binding to specify the interconnect avg/peak
BW for a given operating point. On devices that can do aggressive
frequency scaling like the GPU we want to be able to set a peak
bandwidth along with the frequency so that we can make sure that
the bus can handle a faster GPU frequency if we scale up but also
to reduce power consumption on the bus when we scale down.

The proposed binding uses the form:

opp-interconnect-bw- = 

Where 'name' is the corresponding interconnect-name of the interested
path and 'avg' and 'peak' are the average and peak bandwidth values
in HZ to program for the operating point. The path name is used to
identify path specific settings for devices that may have multiple
active interconnect paths.

The next patch adds a generic OPP API to read the interconnect values
given a operating point and a name.

The 8th patch adds code support for an interconnect path to the for
the a6xx GPU reading the bandwidth for the operating point from the
OPP API.

And the final patch adds the actual interconnect details the
device tree specifying both the interconnect details as well as
the bandwidth requirements for each of the operating points on the
a630 GPU.

Jordan Crouse (9):
  drm/msm/a6xx: rnndb updates for a6xx
  drm/msm/a6xx: Fix PDC register overlap
  drm/msm/a6xx: Rename gmu phandle to qcom,gmu
  dt-bindings: Document qcom,adreno-gmu
  arm64: dts: sdm845: Add gpu and gmu device nodes
  PM / OPP: dt-bindings: Add opp-interconnect-bw
  OPP: Add dev_pm_opp_get_interconnect_bw()
  drm/msm/a6xx: Add support for an interconnect path
  arm64: dts: Add interconnect for the GPU on SDM845

 .../devicetree/bindings/display/msm/gmu.txt   |  54 ++
 .../devicetree/bindings/display/msm/gpu.txt   |  10 +-
 Documentation/devicetree/bindings/opp/opp.txt |  36 +
 arch/arm64/boot/dts/qcom/sdm845.dtsi  | 131 
 drivers/gpu/drm/msm/adreno/a6xx.xml.h | 642 +++---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 114 ++--
 drivers/gpu/drm/msm/adreno/a6xx_gmu.h |   6 -
 drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h |  26 +-
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c |   2 +-
 drivers/gpu/drm/msm/adreno/adreno_gpu.c   |   7 +
 drivers/gpu/drm/msm/msm_gpu.h |   3 +
 drivers/opp/of.c  |  36 +
 include/linux/pm_opp.h|   7 +
 13 files changed, 775 insertions(+), 299 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/msm/gmu.txt

-- 
2.18.0

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 2/9] drm/msm/a6xx: Fix PDC register overlap

2018-08-27 Thread Jordan Crouse
The current design greedily takes a big chunk of the PDC
register space instead of just the GPU specific sections
which conflicts with other drivers and generally makes
a mess of things.

Furthermore we only need to map the GPU PDC sections
just once during init so map the memory inside the function
that uses it.

Signed-off-by: Jordan Crouse 
---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 87 ---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.h |  6 --
 2 files changed, 51 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index bbb8126ec5c5..d0dac4c2e3e7 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -348,8 +348,23 @@ static void a6xx_rpmh_stop(struct a6xx_gmu *gmu)
gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, 0);
 }
 
+static inline void pdc_write(void __iomem *ptr, u32 offset, u32 value)
+{
+   return msm_writel(value, ptr + (offset << 2));
+}
+
+static void __iomem *a6xx_gmu_get_mmio(struct platform_device *pdev,
+   const char *name);
+
 static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
 {
+   struct platform_device *pdev = to_platform_device(gmu->dev);
+   void __iomem *pdcptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc");
+   void __iomem *seqptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc_seq");
+
+   if (!pdcptr || !seqptr)
+   goto err;
+
/* Disable SDE clock gating */
gmu_write(gmu, REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0, BIT(24));
 
@@ -374,44 +389,48 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
gmu_write(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 4, 0x0020e8a8);
 
/* Load PDC sequencer uCode for power up and power down sequence */
-   pdc_write(gmu, REG_A6XX_PDC_GPU_SEQ_MEM_0, 0xfebea1e1);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_SEQ_MEM_0 + 1, 0xa5a4a3a2);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_SEQ_MEM_0 + 2, 0x8382a6e0);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_SEQ_MEM_0 + 3, 0xbce3e284);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_SEQ_MEM_0 + 4, 0x002081fc);
+   pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0, 0xfebea1e1);
+   pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0 + 1, 0xa5a4a3a2);
+   pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0 + 2, 0x8382a6e0);
+   pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0 + 3, 0xbce3e284);
+   pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0 + 4, 0x002081fc);
 
/* Set TCS commands used by PDC sequence for low power modes */
-   pdc_write(gmu, REG_A6XX_PDC_GPU_TCS1_CMD_ENABLE_BANK, 7);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_TCS1_CMD_WAIT_FOR_CMPL_BANK, 0);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_TCS1_CONTROL, 0);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_TCS1_CMD0_MSGID, 0x10108);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_TCS1_CMD0_ADDR, 0x30010);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_TCS1_CMD0_DATA, 1);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_TCS1_CMD0_MSGID + 4, 0x10108);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_TCS1_CMD0_ADDR + 4, 0x3);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_TCS1_CMD0_DATA + 4, 0x0);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_TCS1_CMD0_MSGID + 8, 0x10108);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_TCS1_CMD0_ADDR + 8, 0x30080);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_TCS1_CMD0_DATA + 8, 0x0);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_TCS3_CMD_ENABLE_BANK, 7);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_TCS3_CMD_WAIT_FOR_CMPL_BANK, 0);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_TCS3_CONTROL, 0);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_TCS3_CMD0_MSGID, 0x10108);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR, 0x30010);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA, 2);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_TCS3_CMD0_MSGID + 4, 0x10108);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR + 4, 0x3);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 4, 0x3);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_TCS3_CMD0_MSGID + 8, 0x10108);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR + 8, 0x30080);
-   pdc_write(gmu, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 8, 0x3);
+   pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD_ENABLE_BANK, 7);
+   pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD_WAIT_FOR_CMPL_BANK, 0);
+   pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CONTROL, 0);
+   pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_MSGID, 0x10108);
+   pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_ADDR, 0x30010);
+   pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_DATA, 1);
+   pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_MSGID + 4, 0x10108);
+   pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_ADDR + 4, 0x3);
+   pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_DATA + 4, 0x0);
+   pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_MSGID + 8, 0x10108);
+   pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_ADDR + 8, 0x30080);
+   pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_DATA + 8, 0x0);
+   

[Freedreno] [Patch v15 5/5] iommu/arm-smmu: Add support for qcom, smmu-v2 variant

2018-08-27 Thread Vivek Gautam
qcom,smmu-v2 is an arm,smmu-v2 implementation with specific
clock and power requirements.
On msm8996, multiple cores, viz. mdss, video, etc. use this
smmu. On sdm845, this smmu is used with gpu.
Add bindings for the same.

Signed-off-by: Vivek Gautam 
Reviewed-by: Rob Herring 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
---

Changes since v14:
 - Moved out dt-bindings change to separate patch.

 drivers/iommu/arm-smmu.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index b5e7f72d418c..c0177ea32678 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -119,6 +119,7 @@ enum arm_smmu_implementation {
GENERIC_SMMU,
ARM_MMU500,
CAVIUM_SMMUV2,
+   QCOM_SMMUV2,
 };
 
 struct arm_smmu_s2cr {
@@ -1970,6 +1971,17 @@ ARM_SMMU_MATCH_DATA(arm_mmu401, ARM_SMMU_V1_64K, 
GENERIC_SMMU);
 ARM_SMMU_MATCH_DATA(arm_mmu500, ARM_SMMU_V2, ARM_MMU500);
 ARM_SMMU_MATCH_DATA(cavium_smmuv2, ARM_SMMU_V2, CAVIUM_SMMUV2);
 
+static const char * const qcom_smmuv2_clks[] = {
+   "bus", "iface",
+};
+
+static const struct arm_smmu_match_data qcom_smmuv2 = {
+   .version = ARM_SMMU_V2,
+   .model = QCOM_SMMUV2,
+   .clks = qcom_smmuv2_clks,
+   .num_clks = ARRAY_SIZE(qcom_smmuv2_clks),
+};
+
 static const struct of_device_id arm_smmu_of_match[] = {
{ .compatible = "arm,smmu-v1", .data = _generic_v1 },
{ .compatible = "arm,smmu-v2", .data = _generic_v2 },
@@ -1977,6 +1989,7 @@ static const struct of_device_id arm_smmu_of_match[] = {
{ .compatible = "arm,mmu-401", .data = _mmu401 },
{ .compatible = "arm,mmu-500", .data = _mmu500 },
{ .compatible = "cavium,smmu-v2", .data = _smmuv2 },
+   { .compatible = "qcom,smmu-v2", .data = _smmuv2 },
{ },
 };
 MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [Patch v15 4/5] dt-bindings: arm-smmu: Add bindings for qcom, smmu-v2

2018-08-27 Thread Vivek Gautam
Add bindings doc for Qcom's smmu-v2 implementation.

Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
---

Changes since v14:
 - This is a new patch added in v15 after noticing the new
   checkpatch warning for separate dt-bindings doc.
 - This patch also addresses comments given by Rob and Robin to add
   a list of valid values of '' in "qcom,-smmu-v2"
   compatible string.

 .../devicetree/bindings/iommu/arm,smmu.txt | 47 ++
 1 file changed, 47 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt 
b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
index 8a6ffce12af5..52198a539606 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
@@ -17,10 +17,24 @@ conditions.
 "arm,mmu-401"
 "arm,mmu-500"
 "cavium,smmu-v2"
+"qcom,-smmu-v2", "qcom,smmu-v2"
 
   depending on the particular implementation and/or the
   version of the architecture implemented.
 
+  A number of Qcom SoCs use qcom,smmu-v2 version of the IP.
+  "qcom,-smmu-v2" represents a soc specific compatible
+  string that should be present along with the "qcom,smmu-v2"
+  to facilitate SoC specific clocks/power connections and to
+  address specific bug fixes.
+  '' string in "qcom,-smmu-v2" should be one of the
+  following:
+  msm8996 - for msm8996 Qcom SoC.
+  sdm845 - for sdm845 Qcom Soc.
+
+  An example string would be -
+  "qcom,msm8996-smmu-v2", "qcom,smmu-v2".
+
 - reg   : Base address and size of the SMMU.
 
 - #global-interrupts : The number of global interrupts exposed by the
@@ -71,6 +85,22 @@ conditions.
   or using stream matching with #iommu-cells = <2>, and
   may be ignored if present in such cases.
 
+- clock-names:List of the names of clocks input to the device. The
+  required list depends on particular implementation and
+  is as follows:
+  - for "qcom,smmu-v2":
+- "bus": clock required for downstream bus access and
+ for the smmu ptw,
+- "iface": clock required to access smmu's registers
+   through the TCU's programming interface.
+  - unspecified for other implementations.
+
+- clocks: Specifiers for all clocks listed in the clock-names property,
+  as per generic clock bindings.
+
+- power-domains:  Specifiers for power domains required to be powered on for
+  the SMMU to operate, as per generic power domain bindings.
+
 ** Deprecated properties:
 
 - mmu-masters (deprecated in favour of the generic "iommus" binding) :
@@ -137,3 +167,20 @@ conditions.
 iommu-map = <0  0 0x400>;
 ...
 };
+
+   /* Qcom's arm,smmu-v2 implementation */
+   smmu4: iommu {
+   compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2";
+   reg = <0xd0 0x1>;
+
+   #global-interrupts = <1>;
+   interrupts = ,
+,
+;
+   #iommu-cells = <1>;
+   power-domains = < MDSS_GDSC>;
+
+   clocks = < SMMU_MDP_AXI_CLK>,
+< SMMU_MDP_AHB_CLK>;
+   clock-names = "bus", "iface";
+   };
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [Patch v15 3/5] iommu/arm-smmu: Add the device_link between masters and smmu

2018-08-27 Thread Vivek Gautam
From: Sricharan R 

Finally add the device link between the master device and
smmu, so that the smmu gets runtime enabled/disabled only when the
master needs it. This is done from add_device callback which gets
called once when the master is added to the smmu.

Signed-off-by: Sricharan R 
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
---

Changes since v14:
 - none.

 drivers/iommu/arm-smmu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 23b4a60149b6..b5e7f72d418c 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1461,6 +1461,9 @@ static int arm_smmu_add_device(struct device *dev)
 
iommu_device_link(>iommu, dev);
 
+   device_link_add(dev, smmu->dev,
+   DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_SUPPLIER);
+
return 0;
 
 out_cfg_free:
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [Patch v15 1/5] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-08-27 Thread Vivek Gautam
From: Sricharan R 

The smmu needs to be functional only when the respective
master's using it are active. The device_link feature
helps to track such functional dependencies, so that the
iommu gets powered when the master device enables itself
using pm_runtime. So by adapting the smmu driver for
runtime pm, above said dependency can be addressed.

This patch adds the pm runtime/sleep callbacks to the
driver and also the functions to parse the smmu clocks
from DT and enable them in resume/suspend.

Also, while we enable the runtime pm add a pm sleep suspend
callback that pushes devices to low power state by turning
the clocks off in a system sleep.
Also add corresponding clock enable path in resume callback.

Signed-off-by: Sricharan R 
Signed-off-by: Archit Taneja 
[vivek: rework for clock and pm ops]
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
---

Changes since v14:
 - none.

 drivers/iommu/arm-smmu.c | 77 ++--
 1 file changed, 74 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index fd1b80ef9490..a81224bc6637 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -48,6 +48,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -205,6 +206,8 @@ struct arm_smmu_device {
u32 num_global_irqs;
u32 num_context_irqs;
unsigned int*irqs;
+   struct clk_bulk_data*clks;
+   int num_clks;
 
u32 cavium_id_base; /* Specific to Cavium */
 
@@ -1896,10 +1899,12 @@ static int arm_smmu_device_cfg_probe(struct 
arm_smmu_device *smmu)
 struct arm_smmu_match_data {
enum arm_smmu_arch_version version;
enum arm_smmu_implementation model;
+   const char * const *clks;
+   int num_clks;
 };
 
 #define ARM_SMMU_MATCH_DATA(name, ver, imp)\
-static struct arm_smmu_match_data name = { .version = ver, .model = imp }
+static const struct arm_smmu_match_data name = { .version = ver, .model = imp }
 
 ARM_SMMU_MATCH_DATA(smmu_generic_v1, ARM_SMMU_V1, GENERIC_SMMU);
 ARM_SMMU_MATCH_DATA(smmu_generic_v2, ARM_SMMU_V2, GENERIC_SMMU);
@@ -1918,6 +1923,23 @@ static const struct of_device_id arm_smmu_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
 
+static void arm_smmu_fill_clk_data(struct arm_smmu_device *smmu,
+  const char * const *clks)
+{
+   int i;
+
+   if (smmu->num_clks < 1)
+   return;
+
+   smmu->clks = devm_kcalloc(smmu->dev, smmu->num_clks,
+ sizeof(*smmu->clks), GFP_KERNEL);
+   if (!smmu->clks)
+   return;
+
+   for (i = 0; i < smmu->num_clks; i++)
+   smmu->clks[i].id = clks[i];
+}
+
 #ifdef CONFIG_ACPI
 static int acpi_smmu_get_data(u32 model, struct arm_smmu_device *smmu)
 {
@@ -2000,6 +2022,9 @@ static int arm_smmu_device_dt_probe(struct 
platform_device *pdev,
data = of_device_get_match_data(dev);
smmu->version = data->version;
smmu->model = data->model;
+   smmu->num_clks = data->num_clks;
+
+   arm_smmu_fill_clk_data(smmu, data->clks);
 
parse_driver_options(smmu);
 
@@ -2098,6 +2123,14 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
smmu->irqs[i] = irq;
}
 
+   err = devm_clk_bulk_get(smmu->dev, smmu->num_clks, smmu->clks);
+   if (err)
+   return err;
+
+   err = clk_bulk_prepare(smmu->num_clks, smmu->clks);
+   if (err)
+   return err;
+
err = arm_smmu_device_cfg_probe(smmu);
if (err)
return err;
@@ -2184,6 +2217,9 @@ static int arm_smmu_device_remove(struct platform_device 
*pdev)
 
/* Turn the thing off */
writel(sCR0_CLIENTPD, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0);
+
+   clk_bulk_unprepare(smmu->num_clks, smmu->clks);
+
return 0;
 }
 
@@ -2192,15 +2228,50 @@ static void arm_smmu_device_shutdown(struct 
platform_device *pdev)
arm_smmu_device_remove(pdev);
 }
 
-static int __maybe_unused arm_smmu_pm_resume(struct device *dev)
+static int __maybe_unused arm_smmu_runtime_resume(struct device *dev)
 {
struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+   int ret;
+
+   ret = clk_bulk_enable(smmu->num_clks, smmu->clks);
+   if (ret)
+   return ret;
 
arm_smmu_device_reset(smmu);
+
return 0;
 }
 
-static SIMPLE_DEV_PM_OPS(arm_smmu_pm_ops, NULL, arm_smmu_pm_resume);
+static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev)
+{
+   struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+
+   clk_bulk_disable(smmu->num_clks, smmu->clks);
+
+   return 0;
+}
+
+static int __maybe_unused arm_smmu_pm_resume(struct device *dev)
+{
+   if 

[Freedreno] [Patch v15 0/5] iommu/arm-smmu: Add runtime pm/sleep support

2018-08-27 Thread Vivek Gautam
This series provides the support for turning on the arm-smmu's
clocks/power domains using runtime pm. This is done using
device links between smmu and client devices. The device link
framework keeps the two devices in correct order for power-cycling
across runtime PM or across system-wide PM.

With addition of a new device link flag DL_FLAG_AUTOREMOVE_SUPPLIER [8],
the device links created between arm-smmu and its clients will be
automatically purged when arm-smmu driver unbinds from its device.

As not all implementations support clock/power gating, we are checking
for a valid 'smmu->dev's pm_domain' to conditionally enable the runtime
power management for such smmu implementations that can support it.
Otherwise, the clocks are turned to be always on in .probe until .remove.
With conditional runtime pm now, we avoid touching dev->power.lock
in fastpaths for smmu implementations that don't need to do anything
useful with pm_runtime.
This lets us to use the much-argued pm_runtime_get_sync/put_sync()
calls in map/unmap callbacks so that the clients do not have to
worry about handling any of the arm-smmu's power.

This series also adds support for Qcom's arm-smmu-v2 variant that
has different clocks and power requirements.

Previous version of this patch series is @ [2].

Build tested the series based on 4.19-rc1.

[v15]
   * Added a list of valid values of '' in "qcom,-smmu-v2"
 compatible string as pointed out by Robin, and Rob in the thread [9]:
   * Added Srini's Tested-by.
   * Separated out the dt-bindings change from driver change into a new
 patch as suggested by new checkpatch warning.

 Rob, I took the liberty of removing your Reviewed-by (for your
 comment on '') for the new dt-bindings patch 4/5.
 Please feel free to review it again. Thanks!

[v14]
   * Moved arm_smmu_device_reset() from arm_smmu_pm_resume() to
 arm_smmu_runtime_resume() so that the pm_resume callback calls
 only runtime_resume to resume the device.
 This should take care of restoring the state of smmu in systems
 in which smmu lose register state on power-domain collapse.

[v13]
   Addressing Rafael's comments:
   * Added .suspend pm callback to disable the clocks in system wide suspend.
   * Added corresponding clock enable in .resume pm callback.
   * Explicitly enabling/disabling the clocks now when runtime PM is disabled.
   * device_link_add() doesn't depend on pm_runtime_enabled() as we can
 use device links across system suspend/resume too.

   Addressing Robin's comments:
   * Making device_link_add failures as non-fatal.

   * Removed IOMMU_OF_DECLARE() declaration as we don't need this after Rob's
 patch that removed all of these declarations.

[v12]
   * Use new device link's flag introduced in [8] -
 DL_FLAG_AUTOREMOVE_SUPPLIER. With this devices links are automatically
 purged when arm-smmu driver unbinds.
   * Using pm_runtime_force_suspend() instead of pm_runtime_disable() to
 avoid following warning from arm_smmu_device_remove()

 [295711.537507] [ cut here ]
 [295711.544226] Unpreparing enabled smmu_mdp_ahb_clk
 [295711.549099] WARNING: CPU: 0 PID: 1 at ../drivers/clk/clk.c:697
 clk_core_unprepare+0xd8/0xe0
 ...
 [295711.674073] Call trace:
 [295711.679454]  clk_core_unprepare+0xd8/0xe0
 [295711.682059]  clk_unprepare+0x28/0x40
 [295711.685964]  clk_bulk_unprepare+0x28/0x40
 [295711.689701]  arm_smmu_device_remove+0x88/0xd8
 [295711.693692]  arm_smmu_device_shutdown+0xc/0x18
 [295711.698120]  platform_drv_shutdown+0x20/0x30

[v11]
   * Some more cleanups for device link. We don't need an explicit
 delete for device link from the driver, but just set the flag
 DL_FLAG_AUTOREMOVE.
 device_link_add() API description says -
 "If the DL_FLAG_AUTOREMOVE is set, the link will be removed
 automatically when the consumer device driver unbinds."
   * Addressed the comments for 'smmu' in arm_smmu_map/unmap().
   * Dropped the patch [7] that introduced device_link_del_dev() API. 

[v10]
   * Introduce device_link_del_dev() API to delete the link between
 given consumer and supplier devices. The users of device link
 do not need to store link pointer to delete the link later.
 They can straightaway use this API by passing consumer and
 supplier devices.
   * Made corresponding changes to arm-smmu driver patch handling the
 device links.
   * Dropped the patch [6] that was adding device_link_find() API to
 device core layer. device_link_del_dev() serves the purpose to
 directly delete the link between two given devices.

[v9]
   * Removed 'rpm_supported' flag, instead checking on pm_domain
 to enable runtime pm.
   * Creating device link only when the runtime pm is enabled, as we
 don't need a device link besides managing the power dependency
 between supplier and consumer devices.
   * Introducing a patch to add 

[Freedreno] [PATCH v2 4/5] drm/msm: re-factor devfreq code

2018-08-27 Thread Sharat Masetty
The devfreq framework requires the drivers to provide busy time estimations.
The GPU driver relies on the hardware performance counteres for the busy time
estimations, but different hardware revisions have counters which can be
sourced from different clocks. So the busy time estimation will be target
dependent.  Additionally on targets where the clocks are completely controlled
by the on chip microcontroller, fetching and setting the current GPU frequency
will be different. This patch aims to embrace these differences by re-factoring
the devfreq code a bit.

Signed-off-by: Sharat Masetty 
---
 drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 16 +---
 drivers/gpu/drm/msm/msm_gpu.c | 49 ---
 drivers/gpu/drm/msm/msm_gpu.h |  5 +++-
 3 files changed, 44 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index 897f3e2..043e680 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -1369,12 +1369,20 @@ static struct msm_ringbuffer *a5xx_active_ring(struct 
msm_gpu *gpu)
return a5xx_gpu->cur_ring;
 }
 
-static int a5xx_gpu_busy(struct msm_gpu *gpu, uint64_t *value)
+static unsigned long a5xx_gpu_busy(struct msm_gpu *gpu)
 {
-   *value = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_RBBM_0_LO,
-   REG_A5XX_RBBM_PERFCTR_RBBM_0_HI);
+   u64 busy_cycles;
+   unsigned long busy_time;
 
-   return 0;
+   busy_cycles = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_RBBM_0_LO,
+   REG_A5XX_RBBM_PERFCTR_RBBM_0_HI);
+
+   busy_time = (busy_cycles - gpu->devfreq.busy_cycles) /
+   (clk_get_rate(gpu->core_clk) / 100);
+
+   gpu->devfreq.busy_cycles = busy_cycles;
+
+   return busy_time;
 }
 
 static const struct adreno_gpu_funcs funcs = {
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 8d6bc0c..26c1c3a 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -36,12 +36,16 @@ static int msm_devfreq_target(struct device *dev, unsigned 
long *freq,
struct msm_gpu *gpu = platform_get_drvdata(to_platform_device(dev));
struct dev_pm_opp *opp;
 
-   opp = dev_pm_opp_find_freq_ceil(dev, freq);
+   opp = devfreq_recommended_opp(dev, freq, flags);
+   if (IS_ERR(opp))
+   return PTR_ERR(opp);
 
-   if (!IS_ERR(opp)) {
+   if (gpu->funcs->gpu_set_freq)
+   gpu->funcs->gpu_set_freq(gpu, (u64)*freq);
+   else
clk_set_rate(gpu->core_clk, *freq);
-   dev_pm_opp_put(opp);
-   }
+
+   dev_pm_opp_put(opp);
 
return 0;
 }
@@ -50,16 +54,14 @@ static int msm_devfreq_get_dev_status(struct device *dev,
struct devfreq_dev_status *status)
 {
struct msm_gpu *gpu = platform_get_drvdata(to_platform_device(dev));
-   u64 cycles;
ktime_t time;
 
-   status->current_frequency = (unsigned long) clk_get_rate(gpu->core_clk);
-   gpu->funcs->gpu_busy(gpu, );
-
-   status->busy_time = (cycles - gpu->devfreq.busy_cycles) /
-   (status->current_frequency / 100);
+   if (gpu->funcs->gpu_get_freq)
+   status->current_frequency = gpu->funcs->gpu_get_freq(gpu);
+   else
+   status->current_frequency = clk_get_rate(gpu->core_clk);
 
-   gpu->devfreq.busy_cycles = cycles;
+   status->busy_time = gpu->funcs->gpu_busy(gpu);
 
time = ktime_get();
status->total_time = ktime_us_delta(time, gpu->devfreq.time);
@@ -72,7 +74,10 @@ static int msm_devfreq_get_cur_freq(struct device *dev, 
unsigned long *freq)
 {
struct msm_gpu *gpu = platform_get_drvdata(to_platform_device(dev));
 
-   *freq = (unsigned long) clk_get_rate(gpu->core_clk);
+   if (gpu->funcs->gpu_get_freq)
+   *freq = gpu->funcs->gpu_get_freq(gpu);
+   else
+   *freq = clk_get_rate(gpu->core_clk);
 
return 0;
 }
@@ -87,7 +92,7 @@ static int msm_devfreq_get_cur_freq(struct device *dev, 
unsigned long *freq)
 static void msm_devfreq_init(struct msm_gpu *gpu)
 {
/* We need target support to do devfreq */
-   if (!gpu->funcs->gpu_busy || !gpu->core_clk)
+   if (!gpu->funcs->gpu_busy)
return;
 
msm_devfreq_profile.initial_freq = gpu->fast_rate;
@@ -185,6 +190,14 @@ static int disable_axi(struct msm_gpu *gpu)
return 0;
 }
 
+void msm_gpu_resume_devfreq(struct msm_gpu *gpu)
+{
+   gpu->devfreq.busy_cycles = 0;
+   gpu->devfreq.time = ktime_get();
+
+   devfreq_resume_device(gpu->devfreq.devfreq);
+}
+
 int msm_gpu_pm_resume(struct msm_gpu *gpu)
 {
int ret;
@@ -203,12 +216,7 @@ int msm_gpu_pm_resume(struct msm_gpu *gpu)
if (ret)
return ret;
 
-   if (gpu->devfreq.devfreq) {
-   gpu->devfreq.busy_cycles = 0;
-   gpu->devfreq.time = 

[Freedreno] [PATCH v2 0/5] msm/drm: A6xx DCVS series

2018-08-27 Thread Sharat Masetty
This patch series starts off with a few bug fixes in devfreq code, followed by
refactoring the devfreq code needed for supporting different chipsets, and
ends with adding devfreq support for A6xx.

Sharat Masetty (5):
  drm/msm: suspend devfreq on init
  drm/msm: unregister devfreq upon clean up
  drm/msm/A6xx: Add gmu_read64() register read op
  drm/msm: re-factor devfreq code
  drm/msm/A6xx: Add devfreq support for A6xx

 drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 16 ---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 39 +++---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 12 
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 27 ++
 drivers/gpu/drm/msm/adreno/a6xx_gpu.h |  2 ++
 drivers/gpu/drm/msm/msm_gpu.c | 53 +--
 drivers/gpu/drm/msm/msm_gpu.h |  5 +++-
 7 files changed, 124 insertions(+), 30 deletions(-)

--
1.9.1

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v2 2/5] drm/msm: unregister devfreq upon clean up

2018-08-27 Thread Sharat Masetty
Call the devfreq_remove_device() API to remove the GPU devfreq instance
during GPU driver cleanup.

Signed-off-by: Sharat Masetty 
---
 drivers/gpu/drm/msm/msm_gpu.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 04f9604..8d6bc0c 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -970,6 +970,8 @@ void msm_gpu_cleanup(struct msm_gpu *gpu)
 
WARN_ON(!list_empty(>active_list));
 
+   devm_devfreq_remove_device(>pdev->dev, gpu->devfreq.devfreq);
+
for (i = 0; i < ARRAY_SIZE(gpu->rb); i++) {
msm_ringbuffer_destroy(gpu->rb[i]);
gpu->rb[i] = NULL;
-- 
1.9.1

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v2 5/5] drm/msm/A6xx: Add devfreq support for A6xx

2018-08-27 Thread Sharat Masetty
Implement routines to estimate GPU busy time and fetching the
current frequency for the polling interval. This is required by
the devfreq framework which recommends a frequency change if needed.
The driver code then tries to set this new frequency on the GPU by
sending an Out Of Band(OOB) request to the GMU.

Signed-off-by: Sharat Masetty 
---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 39 +++
 drivers/gpu/drm/msm/adreno/a6xx_gmu.h |  2 ++
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 27 
 drivers/gpu/drm/msm/adreno/a6xx_gpu.h |  2 ++
 4 files changed, 66 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index f6634c0..3a7b899 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -67,7 +67,7 @@ static bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu)
A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_GX_HM_CLK_OFF));
 }
 
-static int a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index)
+static int __a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index)
 {
gmu_write(gmu, REG_A6XX_GMU_DCVS_ACK_OPTION, 0);
 
@@ -84,7 +84,38 @@ static int a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index)
a6xx_gmu_set_oob(gmu, GMU_OOB_DCVS_SET);
a6xx_gmu_clear_oob(gmu, GMU_OOB_DCVS_SET);
 
-   return gmu_read(gmu, REG_A6XX_GMU_DCVS_RETURN);
+   if (gmu_read(gmu, REG_A6XX_GMU_DCVS_RETURN) != 0)
+   return -EINVAL;
+
+   gmu->freq = gmu->gpu_freqs[index];
+
+   return 0;
+}
+
+int a6xx_gmu_set_freq(struct msm_gpu *gpu, unsigned long freq)
+{
+   struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+   struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+   struct a6xx_gmu *gmu = _gpu->gmu;
+   u32 perf_index = 0;
+
+   if (freq == gmu->freq)
+   return 0;
+
+   for (perf_index = 0; perf_index < gmu->nr_gpu_freqs - 1; perf_index++)
+   if (freq == gmu->gpu_freqs[perf_index])
+   break;
+
+   return  __a6xx_gmu_set_freq(gmu, perf_index);
+}
+
+unsigned long a6xx_gmu_get_freq(struct msm_gpu *gpu)
+{
+   struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+   struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+   struct a6xx_gmu *gmu = _gpu->gmu;
+
+   return  gmu->freq;
 }
 
 static bool a6xx_gmu_check_idle_level(struct a6xx_gmu *gmu)
@@ -630,7 +661,7 @@ int a6xx_gmu_reset(struct a6xx_gpu *a6xx_gpu)
ret = a6xx_hfi_start(gmu, GMU_COLD_BOOT);
 
/* Set the GPU back to the highest power frequency */
-   a6xx_gmu_set_freq(gmu, gmu->nr_gpu_freqs - 1);
+   __a6xx_gmu_set_freq(gmu, gmu->nr_gpu_freqs - 1);
 
 out:
if (ret)
@@ -671,7 +702,7 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)
ret = a6xx_hfi_start(gmu, status);
 
/* Set the GPU to the highest power frequency */
-   a6xx_gmu_set_freq(gmu, gmu->nr_gpu_freqs - 1);
+   __a6xx_gmu_set_freq(gmu, gmu->nr_gpu_freqs - 1);
 
 out:
/* Make sure to turn off the boot OOB request on error */
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
index 09fd3a7..13b064f 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
@@ -77,6 +77,8 @@ struct a6xx_gmu {
unsigned long gmu_freqs[4];
u32 cx_arc_votes[4];
 
+   unsigned long freq;
+
struct a6xx_hfi_queue queues[2];
 
struct tasklet_struct hfi_tasklet;
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index 3429d33a..af90706 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -7,6 +7,8 @@
 #include "a6xx_gpu.h"
 #include "a6xx_gmu.xml.h"
 
+#include 
+
 static inline bool _a6xx_check_idle(struct msm_gpu *gpu)
 {
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
@@ -682,6 +684,8 @@ static int a6xx_pm_resume(struct msm_gpu *gpu)
 
gpu->needs_hw_init = true;
 
+   msm_gpu_resume_devfreq(gpu);
+
return ret;
 }
 
@@ -690,6 +694,8 @@ static int a6xx_pm_suspend(struct msm_gpu *gpu)
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
 
+   devfreq_suspend_device(gpu->devfreq.devfreq);
+
/*
 * Make sure the GMU is idle before continuing (because some transitions
 * may use VBIF
@@ -753,6 +759,24 @@ static void a6xx_destroy(struct msm_gpu *gpu)
kfree(a6xx_gpu);
 }
 
+static unsigned long a6xx_gpu_busy(struct msm_gpu *gpu)
+{
+   struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+   struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+   u64 busy_cycles;
+   unsigned long busy_time;
+
+   busy_cycles = gmu_read64(_gpu->gmu,
+   REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_L,
+   

[Freedreno] [PATCH v2 3/5] drm/msm/A6xx: Add gmu_read64() register read op

2018-08-27 Thread Sharat Masetty
Add a simple function to read 64 registers in the GMU domain

Signed-off-by: Sharat Masetty 
---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
index a08ee8f..09fd3a7 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
@@ -106,6 +106,16 @@ static inline void gmu_rmw(struct a6xx_gmu *gmu, u32 reg, 
u32 mask, u32 or)
gmu_write(gmu, reg, val | or);
 }
 
+static inline u64 gmu_read64(struct a6xx_gmu *gmu, u32 lo, u32 hi)
+{
+   u64 val;
+
+   val = (u64) msm_readl(gmu->mmio + (lo << 2));
+   val |= ((u64) msm_readl(gmu->mmio + (hi << 2)) << 32);
+
+   return val;
+}
+
 #define gmu_poll_timeout(gmu, addr, val, cond, interval, timeout) \
readl_poll_timeout((gmu)->mmio + ((addr) << 2), val, cond, \
interval, timeout)
-- 
1.9.1

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v2 1/5] drm/msm: suspend devfreq on init

2018-08-27 Thread Sharat Masetty
Devfreq turns on and starts recommending power level as soon as it is
initialized. The GPU is still not powered on by the time the devfreq
init happens and this leads to problems on GPU's where register access
is needed to get/set power levels. So we start suspended and only restart
devfreq when GPU is powered on.

Signed-off-by: Sharat Masetty 
---
 drivers/gpu/drm/msm/msm_gpu.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 5281a32..04f9604 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -104,6 +104,8 @@ static void msm_devfreq_init(struct msm_gpu *gpu)
dev_err(>pdev->dev, "Couldn't initialize GPU devfreq\n");
gpu->devfreq.devfreq = NULL;
}
+
+   devfreq_suspend_device(gpu->devfreq.devfreq);
 }
 
 static int enable_pwrrail(struct msm_gpu *gpu)
-- 
1.9.1

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno