aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJordan Crouse <jcrouse@codeaurora.org>2019-02-12 04:52:38 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-02-19 08:50:12 -0500
commitfcf9d0b7d2f50003efe0ba280be458f27671010d (patch)
tree1736ca86cb99b9f84518b90d7528f32bf5f48c14
parent682a60446b150f3058b77806768977f4dff0fffb (diff)
drm/msm/a6xx: Add support for an interconnect path
Try to get the interconnect path for the GPU and vote for the maximum bandwidth to support all frequencies. This is needed for performance. Later we will want to scale the bandwidth based on the frequency to also optimize for power but that will require some device tree infrastructure that does not yet exist. v6: use icc_set_bw() instead of icc_set() v5: Remove hardcoded interconnect name and just use the default v4: Don't use a port string at all to skip the need for names in the DT v3: Use macros and change port string per Georgi Djakov Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org> Acked-by: Rob Clark <robdclark@gmail.com> Reviewed-by: Evan Green <evgreen@chromium.org> Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/gpu/drm/msm/Kconfig1
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_gmu.c20
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.c9
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.h3
4 files changed, 33 insertions, 0 deletions
diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index cf549f1ed403..78c9e5a5e793 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -5,6 +5,7 @@ config DRM_MSM
5 depends on ARCH_QCOM || SOC_IMX5 || (ARM && COMPILE_TEST) 5 depends on ARCH_QCOM || SOC_IMX5 || (ARM && COMPILE_TEST)
6 depends on OF && COMMON_CLK 6 depends on OF && COMMON_CLK
7 depends on MMU 7 depends on MMU
8 depends on INTERCONNECT || !INTERCONNECT
8 select QCOM_MDT_LOADER if ARCH_QCOM 9 select QCOM_MDT_LOADER if ARCH_QCOM
9 select REGULATOR 10 select REGULATOR
10 select DRM_KMS_HELPER 11 select DRM_KMS_HELPER
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index ce1b3cc4bf6d..d1662a75c7ec 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -2,6 +2,7 @@
2/* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. */ 2/* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. */
3 3
4#include <linux/clk.h> 4#include <linux/clk.h>
5#include <linux/interconnect.h>
5#include <linux/pm_opp.h> 6#include <linux/pm_opp.h>
6#include <soc/qcom/cmd-db.h> 7#include <soc/qcom/cmd-db.h>
7 8
@@ -84,6 +85,9 @@ bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu)
84 85
85static void __a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index) 86static void __a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index)
86{ 87{
88 struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
89 struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
90 struct msm_gpu *gpu = &adreno_gpu->base;
87 int ret; 91 int ret;
88 92
89 gmu_write(gmu, REG_A6XX_GMU_DCVS_ACK_OPTION, 0); 93 gmu_write(gmu, REG_A6XX_GMU_DCVS_ACK_OPTION, 0);
@@ -106,6 +110,12 @@ static void __a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index)
106 dev_err(gmu->dev, "GMU set GPU frequency error: %d\n", ret); 110 dev_err(gmu->dev, "GMU set GPU frequency error: %d\n", ret);
107 111
108 gmu->freq = gmu->gpu_freqs[index]; 112 gmu->freq = gmu->gpu_freqs[index];
113
114 /*
115 * Eventually we will want to scale the path vote with the frequency but
116 * for now leave it at max so that the performance is nominal.
117 */
118 icc_set_bw(gpu->icc_path, 0, MBps_to_icc(7216));
109} 119}
110 120
111void a6xx_gmu_set_freq(struct msm_gpu *gpu, unsigned long freq) 121void a6xx_gmu_set_freq(struct msm_gpu *gpu, unsigned long freq)
@@ -705,6 +715,8 @@ out:
705 715
706int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu) 716int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)
707{ 717{
718 struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
719 struct msm_gpu *gpu = &adreno_gpu->base;
708 struct a6xx_gmu *gmu = &a6xx_gpu->gmu; 720 struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
709 int status, ret; 721 int status, ret;
710 722
@@ -720,6 +732,9 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)
720 if (ret) 732 if (ret)
721 goto out; 733 goto out;
722 734
735 /* Set the bus quota to a reasonable value for boot */
736 icc_set_bw(gpu->icc_path, 0, MBps_to_icc(3072));
737
723 a6xx_gmu_irq_enable(gmu); 738 a6xx_gmu_irq_enable(gmu);
724 739
725 /* Check to see if we are doing a cold or warm boot */ 740 /* Check to see if we are doing a cold or warm boot */
@@ -760,6 +775,8 @@ bool a6xx_gmu_isidle(struct a6xx_gmu *gmu)
760 775
761int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu) 776int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu)
762{ 777{
778 struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
779 struct msm_gpu *gpu = &adreno_gpu->base;
763 struct a6xx_gmu *gmu = &a6xx_gpu->gmu; 780 struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
764 u32 val; 781 u32 val;
765 782
@@ -806,6 +823,9 @@ int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu)
806 /* Tell RPMh to power off the GPU */ 823 /* Tell RPMh to power off the GPU */
807 a6xx_rpmh_stop(gmu); 824 a6xx_rpmh_stop(gmu);
808 825
826 /* Remove the bus vote */
827 icc_set_bw(gpu->icc_path, 0, 0);
828
809 clk_bulk_disable_unprepare(gmu->nr_clocks, gmu->clocks); 829 clk_bulk_disable_unprepare(gmu->nr_clocks, gmu->clocks);
810 830
811 pm_runtime_put_sync(gmu->dev); 831 pm_runtime_put_sync(gmu->dev);
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 2cfee1a4fe0b..27898475cdf4 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -18,6 +18,7 @@
18 */ 18 */
19 19
20#include <linux/ascii85.h> 20#include <linux/ascii85.h>
21#include <linux/interconnect.h>
21#include <linux/kernel.h> 22#include <linux/kernel.h>
22#include <linux/pm_opp.h> 23#include <linux/pm_opp.h>
23#include <linux/slab.h> 24#include <linux/slab.h>
@@ -747,6 +748,11 @@ static int adreno_get_pwrlevels(struct device *dev,
747 748
748 DBG("fast_rate=%u, slow_rate=27000000", gpu->fast_rate); 749 DBG("fast_rate=%u, slow_rate=27000000", gpu->fast_rate);
749 750
751 /* Check for an interconnect path for the bus */
752 gpu->icc_path = of_icc_get(dev, NULL);
753 if (IS_ERR(gpu->icc_path))
754 gpu->icc_path = NULL;
755
750 return 0; 756 return 0;
751} 757}
752 758
@@ -787,10 +793,13 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
787 793
788void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu) 794void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)
789{ 795{
796 struct msm_gpu *gpu = &adreno_gpu->base;
790 unsigned int i; 797 unsigned int i;
791 798
792 for (i = 0; i < ARRAY_SIZE(adreno_gpu->info->fw); i++) 799 for (i = 0; i < ARRAY_SIZE(adreno_gpu->info->fw); i++)
793 release_firmware(adreno_gpu->fw[i]); 800 release_firmware(adreno_gpu->fw[i]);
794 801
802 icc_put(gpu->icc_path);
803
795 msm_gpu_cleanup(&adreno_gpu->base); 804 msm_gpu_cleanup(&adreno_gpu->base);
796} 805}
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index ca17086f72c9..6241986bab51 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -19,6 +19,7 @@
19#define __MSM_GPU_H__ 19#define __MSM_GPU_H__
20 20
21#include <linux/clk.h> 21#include <linux/clk.h>
22#include <linux/interconnect.h>
22#include <linux/regulator/consumer.h> 23#include <linux/regulator/consumer.h>
23 24
24#include "msm_drv.h" 25#include "msm_drv.h"
@@ -118,6 +119,8 @@ struct msm_gpu {
118 struct clk *ebi1_clk, *core_clk, *rbbmtimer_clk; 119 struct clk *ebi1_clk, *core_clk, *rbbmtimer_clk;
119 uint32_t fast_rate; 120 uint32_t fast_rate;
120 121
122 struct icc_path *icc_path;
123
121 /* Hang and Inactivity Detection: 124 /* Hang and Inactivity Detection:
122 */ 125 */
123#define DRM_MSM_INACTIVE_PERIOD 66 /* in ms (roughly four frames) */ 126#define DRM_MSM_INACTIVE_PERIOD 66 /* in ms (roughly four frames) */