Commit 61a6920b authored by Doug Brown's avatar Doug Brown Committed by Lucas Stach
Browse files

drm/etnaviv: fix power register offset on GC300



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: default avatarDoug Brown <doug@schmorgal.com>
Signed-off-by: default avatarLucas Stach <l.stach@pengutronix.de>
parent cc7d3fb4
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -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);
+10 −10
Original line number Diff line number Diff line
@@ -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)
@@ -1317,9 +1317,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);
@@ -1350,9 +1350,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);
}


+21 −0
Original line number Diff line number Diff line
@@ -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);