]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm/etnaviv: fix power register offset on GC300
authorDoug Brown <doug@schmorgal.com>
Sat, 10 Sep 2022 20:29:39 +0000 (13:29 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 14 Dec 2024 18:50:56 +0000 (19:50 +0100)
[ Upstream commit 61a6920bb604df3a0e389a2a9479e1e233e4461d ]

Older GC300 revisions have their power registers at an offset of 0x200
rather than 0x100. Add new gpu_read_power and gpu_write_power functions
to encapsulate accesses to the power addresses and fix the addresses.

Signed-off-by: Doug Brown <doug@schmorgal.com>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Stable-dep-of: 37dc4737447a ("drm/etnaviv: hold GPU lock across perfmon sampling")
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/gpu/drm/etnaviv/etnaviv_dump.c
drivers/gpu/drm/etnaviv/etnaviv_gpu.c
drivers/gpu/drm/etnaviv/etnaviv_gpu.h

index 0edcf8ceb4a7881e3bcbe8482f64b260d4cbaf2b..898f84a0fc30cb0ee4197220a4ecadd1af464744 100644 (file)
@@ -83,10 +83,15 @@ static void etnaviv_core_dump_registers(struct core_dump_iterator *iter,
 {
        struct etnaviv_dump_registers *reg = iter->data;
        unsigned int i;
+       u32 read_addr;
 
        for (i = 0; i < ARRAY_SIZE(etnaviv_dump_registers); i++, reg++) {
+               read_addr = etnaviv_dump_registers[i];
+               if (read_addr >= VIVS_PM_POWER_CONTROLS &&
+                   read_addr <= VIVS_PM_PULSE_EATER)
+                       read_addr = gpu_fix_power_address(gpu, read_addr);
                reg->reg = cpu_to_le32(etnaviv_dump_registers[i]);
-               reg->value = cpu_to_le32(gpu_read(gpu, etnaviv_dump_registers[i]));
+               reg->value = cpu_to_le32(gpu_read(gpu, read_addr));
        }
 
        etnaviv_core_dump_header(iter, ETDUMP_BUF_REG, reg);
index 123c8263d27fd050944e8628ea38ea5ae0fe5c6b..9def75f04e5b6d918c3a7fd5a4c91bb01c09c724 100644 (file)
@@ -590,7 +590,7 @@ static void etnaviv_gpu_enable_mlcg(struct etnaviv_gpu *gpu)
        u32 pmc, ppc;
 
        /* enable clock gating */
-       ppc = gpu_read(gpu, VIVS_PM_POWER_CONTROLS);
+       ppc = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
        ppc |= VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
 
        /* Disable stall module clock gating for 4.3.0.1 and 4.3.0.2 revs */
@@ -598,9 +598,9 @@ static void etnaviv_gpu_enable_mlcg(struct etnaviv_gpu *gpu)
            gpu->identity.revision == 0x4302)
                ppc |= VIVS_PM_POWER_CONTROLS_DISABLE_STALL_MODULE_CLOCK_GATING;
 
-       gpu_write(gpu, VIVS_PM_POWER_CONTROLS, ppc);
+       gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, ppc);
 
-       pmc = gpu_read(gpu, VIVS_PM_MODULE_CONTROLS);
+       pmc = gpu_read_power(gpu, VIVS_PM_MODULE_CONTROLS);
 
        /* Disable PA clock gating for GC400+ without bugfix except for GC420 */
        if (gpu->identity.model >= chipModel_GC400 &&
@@ -635,7 +635,7 @@ static void etnaviv_gpu_enable_mlcg(struct etnaviv_gpu *gpu)
        pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_RA_HZ;
        pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_RA_EZ;
 
-       gpu_write(gpu, VIVS_PM_MODULE_CONTROLS, pmc);
+       gpu_write_power(gpu, VIVS_PM_MODULE_CONTROLS, pmc);
 }
 
 void etnaviv_gpu_start_fe(struct etnaviv_gpu *gpu, u32 address, u16 prefetch)
@@ -695,11 +695,11 @@ static void etnaviv_gpu_setup_pulse_eater(struct etnaviv_gpu *gpu)
            (gpu->identity.features & chipFeatures_PIPE_3D))
        {
                /* Performance fix: disable internal DFS */
-               pulse_eater = gpu_read(gpu, VIVS_PM_PULSE_EATER);
+               pulse_eater = gpu_read_power(gpu, VIVS_PM_PULSE_EATER);
                pulse_eater |= BIT(18);
        }
 
-       gpu_write(gpu, VIVS_PM_PULSE_EATER, pulse_eater);
+       gpu_write_power(gpu, VIVS_PM_PULSE_EATER, pulse_eater);
 }
 
 static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu)
@@ -1293,9 +1293,9 @@ static void sync_point_perfmon_sample_pre(struct etnaviv_gpu *gpu,
        u32 val;
 
        /* disable clock gating */
-       val = gpu_read(gpu, VIVS_PM_POWER_CONTROLS);
+       val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
        val &= ~VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
-       gpu_write(gpu, VIVS_PM_POWER_CONTROLS, val);
+       gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, val);
 
        /* enable debug register */
        val = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL);
@@ -1326,9 +1326,9 @@ static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu,
        gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, val);
 
        /* enable clock gating */
-       val = gpu_read(gpu, VIVS_PM_POWER_CONTROLS);
+       val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
        val |= VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
-       gpu_write(gpu, VIVS_PM_POWER_CONTROLS, val);
+       gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, val);
 }
 
 
index 85eddd492774d59c34189f6768e24e3f42dd8766..39f1e83d3cc7d6bd8635bc615cb1ca5deb336636 100644 (file)
@@ -10,6 +10,7 @@
 #include "etnaviv_gem.h"
 #include "etnaviv_mmu.h"
 #include "etnaviv_drv.h"
+#include "common.xml.h"
 
 struct etnaviv_gem_submit;
 struct etnaviv_vram_mapping;
@@ -159,6 +160,26 @@ static inline u32 gpu_read(struct etnaviv_gpu *gpu, u32 reg)
        return readl(gpu->mmio + reg);
 }
 
+static inline u32 gpu_fix_power_address(struct etnaviv_gpu *gpu, u32 reg)
+{
+       /* Power registers in GC300 < 2.0 are offset by 0x100 */
+       if (gpu->identity.model == chipModel_GC300 &&
+           gpu->identity.revision < 0x2000)
+               reg += 0x100;
+
+       return reg;
+}
+
+static inline void gpu_write_power(struct etnaviv_gpu *gpu, u32 reg, u32 data)
+{
+       writel(data, gpu->mmio + gpu_fix_power_address(gpu, reg));
+}
+
+static inline u32 gpu_read_power(struct etnaviv_gpu *gpu, u32 reg)
+{
+       return readl(gpu->mmio + gpu_fix_power_address(gpu, reg));
+}
+
 int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 param, u64 *value);
 
 int etnaviv_gpu_init(struct etnaviv_gpu *gpu);