/* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. */
 
 #include <linux/clk.h>
+#include <linux/interconnect.h>
 #include <linux/pm_opp.h>
 #include <soc/qcom/cmd-db.h>
 
 
 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 = &a6xx_gpu->base;
+       struct msm_gpu *gpu = &adreno_gpu->base;
        int ret;
 
        gmu_write(gmu, REG_A6XX_GMU_DCVS_ACK_OPTION, 0);
                dev_err(gmu->dev, "GMU set GPU frequency error: %d\n", ret);
 
        gmu->freq = gmu->gpu_freqs[index];
+
+       /*
+        * Eventually we will want to scale the path vote with the frequency but
+        * for now leave it at max so that the performance is nominal.
+        */
+       icc_set_bw(gpu->icc_path, 0, MBps_to_icc(7216));
 }
 
 void a6xx_gmu_set_freq(struct msm_gpu *gpu, unsigned long freq)
 
 int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)
 {
+       struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+       struct msm_gpu *gpu = &adreno_gpu->base;
        struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
        int status, ret;
 
        if (ret)
                goto out;
 
+       /* Set the bus quota to a reasonable value for boot */
+       icc_set_bw(gpu->icc_path, 0, MBps_to_icc(3072));
+
        a6xx_gmu_irq_enable(gmu);
 
        /* Check to see if we are doing a cold or warm boot */
 
 int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu)
 {
+       struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+       struct msm_gpu *gpu = &adreno_gpu->base;
        struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
        u32 val;
 
        /* Tell RPMh to power off the GPU */
        a6xx_rpmh_stop(gmu);
 
+       /* Remove the bus vote */
+       icc_set_bw(gpu->icc_path, 0, 0);
+
        clk_bulk_disable_unprepare(gmu->nr_clocks, gmu->clocks);
 
        pm_runtime_put_sync(gmu->dev);
 
  */
 
 #include <linux/ascii85.h>
+#include <linux/interconnect.h>
 #include <linux/kernel.h>
 #include <linux/pm_opp.h>
 #include <linux/slab.h>
 
        DBG("fast_rate=%u, slow_rate=27000000", gpu->fast_rate);
 
+       /* Check for an interconnect path for the bus */
+       gpu->icc_path = of_icc_get(dev, NULL);
+       if (IS_ERR(gpu->icc_path))
+               gpu->icc_path = NULL;
+
        return 0;
 }
 
 
 void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)
 {
+       struct msm_gpu *gpu = &adreno_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(&adreno_gpu->base);
 }