drm/msm/adreno: Read the speed bins for a5xx targets
authorJordan Crouse <jcrouse@codeaurora.org>
Tue, 21 Nov 2017 19:40:56 +0000 (12:40 -0700)
committerRob Clark <robdclark@gmail.com>
Wed, 10 Jan 2018 13:58:42 +0000 (08:58 -0500)
Some 5xx based chipsets have different bins for GPU clock speeds.
Read the fuses (if applicable) and set the appropriate OPP table.
This will only work with OPP v2 tables - the bin will be ignored
for legacy pwrlevel tables.

Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
Signed-off-by: Rob Clark <robdclark@gmail.com>
drivers/gpu/drm/msm/adreno/a5xx_gpu.c

index a1f4eeeb73e2f4467aaa9ab3f89711a7896b982c..fdbe9e9bb2b1839069b871dda7e504a29278d439 100644 (file)
@@ -17,6 +17,8 @@
 #include <linux/dma-mapping.h>
 #include <linux/of_address.h>
 #include <linux/soc/qcom/mdt_loader.h>
+#include <linux/pm_opp.h>
+#include <linux/nvmem-consumer.h>
 #include "msm_gem.h"
 #include "msm_mmu.h"
 #include "a5xx_gpu.h"
@@ -1184,6 +1186,25 @@ static const struct adreno_gpu_funcs funcs = {
        .get_timestamp = a5xx_get_timestamp,
 };
 
+static void check_speed_bin(struct device *dev)
+{
+       struct nvmem_cell *cell;
+       u32 bin, val;
+
+       cell = nvmem_cell_get(dev, "speed_bin");
+
+       /* If a nvmem cell isn't defined, nothing to do */
+       if (IS_ERR(cell))
+               return;
+
+       bin = *((u32 *) nvmem_cell_read(cell, NULL));
+       nvmem_cell_put(cell);
+
+       val = (1 << bin);
+
+       dev_pm_opp_set_supported_hw(dev, &val, 1);
+}
+
 struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
 {
        struct msm_drm_private *priv = dev->dev_private;
@@ -1210,6 +1231,8 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
 
        a5xx_gpu->lm_leakage = 0x4E001A;
 
+       check_speed_bin(&pdev->dev);
+
        ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 4);
        if (ret) {
                a5xx_destroy(&(a5xx_gpu->base.base));