Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 308b9245 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Add support for GBIF for A615 GPU"

parents 856db920 77b82ed8
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -764,6 +764,29 @@
#define A6XX_VBIF_PERF_PWR_CNT_HIGH1            0x3119
#define A6XX_VBIF_PERF_PWR_CNT_HIGH2            0x311a

/* GBIF registers */
#define A6XX_GBIF_HALT                    0x3c45
#define A6XX_GBIF_HALT_ACK                0x3c46
#define A6XX_GBIF_HALT_MASK               0x1

#define A6XX_GBIF_PERF_PWR_CNT_EN         0x3cc0
#define A6XX_GBIF_PERF_CNT_SEL            0x3cc2
#define A6XX_GBIF_PERF_CNT_LOW0           0x3cc4
#define A6XX_GBIF_PERF_CNT_LOW1           0x3cc5
#define A6XX_GBIF_PERF_CNT_LOW2           0x3cc6
#define A6XX_GBIF_PERF_CNT_LOW3           0x3cc7
#define A6XX_GBIF_PERF_CNT_HIGH0          0x3cc8
#define A6XX_GBIF_PERF_CNT_HIGH1          0x3cc9
#define A6XX_GBIF_PERF_CNT_HIGH2          0x3cca
#define A6XX_GBIF_PERF_CNT_HIGH3          0x3ccb
#define A6XX_GBIF_PWR_CNT_LOW0            0x3ccc
#define A6XX_GBIF_PWR_CNT_LOW1            0x3ccd
#define A6XX_GBIF_PWR_CNT_LOW2            0x3cce
#define A6XX_GBIF_PWR_CNT_HIGH0           0x3ccf
#define A6XX_GBIF_PWR_CNT_HIGH1           0x3cd0
#define A6XX_GBIF_PWR_CNT_HIGH2           0x3cd1


/* CX_DBGC_CFG registers */
#define A6XX_CX_DBGC_CFG_DBGBUS_SEL_A                   0x18400
#define A6XX_CX_DBGC_CFG_DBGBUS_SEL_B                   0x18401
+46 −9
Original line number Diff line number Diff line
@@ -636,6 +636,8 @@ enum adreno_regs {
	ADRENO_REG_VBIF_XIN_HALT_CTRL0,
	ADRENO_REG_VBIF_XIN_HALT_CTRL1,
	ADRENO_REG_VBIF_VERSION,
	ADRENO_REG_GBIF_HALT,
	ADRENO_REG_GBIF_HALT_ACK,
	ADRENO_REG_GMU_AO_INTERRUPT_EN,
	ADRENO_REG_GMU_AO_HOST_INTERRUPT_CLR,
	ADRENO_REG_GMU_AO_HOST_INTERRUPT_STATUS,
@@ -1801,26 +1803,34 @@ static inline void adreno_perfcntr_active_oob_put(
	kgsl_active_count_put(KGSL_DEVICE(adreno_dev));
}

static inline bool adreno_has_gbif(struct adreno_device *adreno_dev)
{
	if (adreno_is_a615(adreno_dev))
		return true;
	else
		return false;
}

/**
 * adreno_vbif_clear_pending_transactions() - Clear transactions in VBIF pipe
 * @device: Pointer to the device whose VBIF pipe is to be cleared
 * adreno_wait_for_vbif_halt_ack() - wait for VBIF acknowledgment
 * for given HALT request.
 * @ack_reg: register offset to wait for acknowledge
 */
static inline int adreno_vbif_clear_pending_transactions(
	struct kgsl_device *device)
static inline int adreno_wait_for_vbif_halt_ack(struct kgsl_device *device,
	int ack_reg)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
	unsigned long wait_for_vbif;
	unsigned int mask = gpudev->vbif_xin_halt_ctrl0_mask;
	unsigned int val;
	unsigned long wait_for_vbif;
	int ret = 0;

	adreno_writereg(adreno_dev, ADRENO_REG_VBIF_XIN_HALT_CTRL0, mask);
	/* wait for the transactions to clear */
	wait_for_vbif = jiffies + msecs_to_jiffies(100);
	while (1) {
		adreno_readreg(adreno_dev,
			ADRENO_REG_VBIF_XIN_HALT_CTRL1, &val);
		adreno_readreg(adreno_dev, ack_reg,
			&val);
		if ((val & mask) == mask)
			break;
		if (time_after(jiffies, wait_for_vbif)) {
@@ -1830,7 +1840,34 @@ static inline int adreno_vbif_clear_pending_transactions(
			break;
		}
	}

	return ret;
}

/**
 * adreno_vbif_clear_pending_transactions() - Clear transactions in VBIF pipe
 * @device: Pointer to the device whose VBIF pipe is to be cleared
 */
static inline int adreno_vbif_clear_pending_transactions(
	struct kgsl_device *device)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
	unsigned int mask = gpudev->vbif_xin_halt_ctrl0_mask;
	int ret = 0;

	if (adreno_has_gbif(adreno_dev)) {
		adreno_writereg(adreno_dev, ADRENO_REG_GBIF_HALT, mask);
		ret = adreno_wait_for_vbif_halt_ack(device,
				ADRENO_REG_GBIF_HALT_ACK);
		adreno_writereg(adreno_dev, ADRENO_REG_GBIF_HALT, 0);
	} else {
		adreno_writereg(adreno_dev, ADRENO_REG_VBIF_XIN_HALT_CTRL0,
			mask);
		ret = adreno_wait_for_vbif_halt_ack(device,
				ADRENO_REG_VBIF_XIN_HALT_CTRL1);
		adreno_writereg(adreno_dev, ADRENO_REG_VBIF_XIN_HALT_CTRL0, 0);
	}
	return ret;
}

+58 −13
Original line number Diff line number Diff line
@@ -50,11 +50,16 @@ static const struct adreno_vbif_data a630_vbif[] = {
	{0, 0},
};

static const struct adreno_vbif_data a615_gbif[] = {
	{A6XX_RBBM_VBIF_CLIENT_QOS_CNTL, 0x3},
	{0, 0},
};

static const struct adreno_vbif_platform a6xx_vbif_platforms[] = {
	{ adreno_is_a630, a630_vbif },
	{ adreno_is_a615, a615_gbif },
};


struct kgsl_hwcg_reg {
	unsigned int off;
	unsigned int val;
@@ -244,18 +249,6 @@ static struct reg_list_pair {
	{ A6XX_RB_CONTEXT_SWITCH_GMEM_SAVE_RESTORE, 0x0 },
};

static void a6xx_platform_setup(struct adreno_device *adreno_dev)
{
	uint64_t addr;
	struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);

	/* Calculate SP local and private mem addresses */
	addr = ALIGN(ADRENO_UCHE_GMEM_BASE + adreno_dev->gmem_size, SZ_64K);
	adreno_dev->sp_local_gpuaddr = addr;
	adreno_dev->sp_pvt_gpuaddr = addr + SZ_64K;
	gpudev->vbif_xin_halt_ctrl0_mask = A6XX_VBIF_XIN_HALT_CTRL0_MASK;
}

static void _update_always_on_regs(struct adreno_device *adreno_dev)
{
	struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
@@ -2721,6 +2714,27 @@ static struct adreno_perfcount_register a6xx_perfcounters_vbif_pwr[] = {
		A6XX_VBIF_PERF_PWR_CNT_HIGH2, -1, A6XX_VBIF_PERF_PWR_CNT_EN2 },
};


static struct adreno_perfcount_register a6xx_perfcounters_gbif[] = {
	{ KGSL_PERFCOUNTER_NOT_USED, 0, 0, A6XX_GBIF_PERF_CNT_LOW0,
		A6XX_GBIF_PERF_CNT_HIGH0, -1, A6XX_GBIF_PERF_CNT_SEL },
	{ KGSL_PERFCOUNTER_NOT_USED, 0, 0, A6XX_GBIF_PERF_CNT_LOW1,
		A6XX_GBIF_PERF_CNT_HIGH1, -1, A6XX_GBIF_PERF_CNT_SEL },
	{ KGSL_PERFCOUNTER_NOT_USED, 0, 0, A6XX_GBIF_PERF_CNT_LOW2,
		A6XX_GBIF_PERF_CNT_HIGH2, -1, A6XX_GBIF_PERF_CNT_SEL },
	{ KGSL_PERFCOUNTER_NOT_USED, 0, 0, A6XX_GBIF_PERF_CNT_LOW3,
		A6XX_GBIF_PERF_CNT_HIGH3, -1, A6XX_GBIF_PERF_CNT_SEL },
};

static struct adreno_perfcount_register a6xx_perfcounters_gbif_pwr[] = {
	{ KGSL_PERFCOUNTER_NOT_USED, 0, 0, A6XX_GBIF_PWR_CNT_LOW0,
		A6XX_GBIF_PWR_CNT_HIGH0, -1, A6XX_GBIF_PERF_PWR_CNT_EN },
	{ KGSL_PERFCOUNTER_NOT_USED, 0, 0, A6XX_GBIF_PWR_CNT_LOW1,
		A6XX_GBIF_PWR_CNT_HIGH1, -1, A6XX_GBIF_PERF_PWR_CNT_EN },
	{ KGSL_PERFCOUNTER_NOT_USED, 0, 0, A6XX_GBIF_PWR_CNT_LOW2,
		A6XX_GBIF_PWR_CNT_HIGH2, -1, A6XX_GBIF_PERF_PWR_CNT_EN },
};

static struct adreno_perfcount_register a6xx_perfcounters_pwr[] = {
	{ KGSL_PERFCOUNTER_BROKEN, 0, 0, 0, 0, -1, 0 },
	{ KGSL_PERFCOUNTER_NOT_USED, 0, 0,
@@ -2831,6 +2845,35 @@ static int a6xx_enable_pwr_counters(struct adreno_device *adreno_dev,
	return 0;
}

static void a6xx_platform_setup(struct adreno_device *adreno_dev)
{
	uint64_t addr;
	struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);

	/* Calculate SP local and private mem addresses */
	addr = ALIGN(ADRENO_UCHE_GMEM_BASE + adreno_dev->gmem_size, SZ_64K);
	adreno_dev->sp_local_gpuaddr = addr;
	adreno_dev->sp_pvt_gpuaddr = addr + SZ_64K;

	if (adreno_has_gbif(adreno_dev)) {
		a6xx_perfcounter_groups[KGSL_PERFCOUNTER_GROUP_VBIF].regs =
				a6xx_perfcounters_gbif;
		a6xx_perfcounter_groups[KGSL_PERFCOUNTER_GROUP_VBIF].reg_count
				= ARRAY_SIZE(a6xx_perfcounters_gbif);

		a6xx_perfcounter_groups[KGSL_PERFCOUNTER_GROUP_VBIF_PWR].regs =
				a6xx_perfcounters_gbif_pwr;
		a6xx_perfcounter_groups[KGSL_PERFCOUNTER_GROUP_VBIF].reg_count
				= ARRAY_SIZE(a6xx_perfcounters_gbif_pwr);

		gpudev->vbif_xin_halt_ctrl0_mask =
				A6XX_GBIF_HALT_MASK;
	} else
		gpudev->vbif_xin_halt_ctrl0_mask =
				A6XX_VBIF_XIN_HALT_CTRL0_MASK;
}


/* Register offset defines for A6XX, in order of enum adreno_regs */
static unsigned int a6xx_register_offsets[ADRENO_REG_REGISTER_MAX] = {

@@ -2890,6 +2933,8 @@ static unsigned int a6xx_register_offsets[ADRENO_REG_REGISTER_MAX] = {
				A6XX_VBIF_XIN_HALT_CTRL0),
	ADRENO_REG_DEFINE(ADRENO_REG_VBIF_XIN_HALT_CTRL1,
				A6XX_VBIF_XIN_HALT_CTRL1),
	ADRENO_REG_DEFINE(ADRENO_REG_GBIF_HALT, A6XX_GBIF_HALT),
	ADRENO_REG_DEFINE(ADRENO_REG_GBIF_HALT_ACK, A6XX_GBIF_HALT_ACK),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_ALWAYSON_COUNTER_LO,
				A6XX_GMU_ALWAYS_ON_COUNTER_L),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_ALWAYSON_COUNTER_HI,
+11 −6
Original line number Diff line number Diff line
@@ -1357,6 +1357,7 @@ static void a6xx_snapshot_debugbus(struct kgsl_device *device,
		struct kgsl_snapshot *snapshot)
{
	int i;
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);

	kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_CNTLT,
		(0xf << A6XX_DBGC_CFG_DBGBUS_CNTLT_SEGT_SHIFT) |
@@ -1447,7 +1448,10 @@ static void a6xx_snapshot_debugbus(struct kgsl_device *device,
			(void *) &a6xx_dbgc_debugbus_blocks[i]);
	}

	kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUGBUS,
	/* Skip if GPU has GBIF */
	if (!adreno_has_gbif(adreno_dev))
		kgsl_snapshot_add_section(device,
				KGSL_SNAPSHOT_SECTION_DEBUGBUS,
				snapshot, a6xx_snapshot_vbif_debugbus_block,
				(void *) &a6xx_vbif_debugbus_blocks);

@@ -1584,6 +1588,7 @@ void a6xx_snapshot(struct adreno_device *adreno_dev,
		snapshot, a6xx_snapshot_pre_crashdump_regs, NULL);

	/* Dump vbif registers as well which get affected by crash dumper */
	if (!adreno_has_gbif(adreno_dev))
		adreno_snapshot_vbif_registers(device, snapshot,
			a6xx_vbif_snapshot_registers,
			ARRAY_SIZE(a6xx_vbif_snapshot_registers));
+71 −10
Original line number Diff line number Diff line
@@ -28,6 +28,20 @@
/* offset of enable register from select register */
#define VBIF2_PERF_EN_REG_SEL_OFF 16

/* offset of clear register from select register for GBIF */
#define GBIF_PERF_CLR_REG_SEL_OFF 1

/* offset of enable register from select register for GBIF*/
#define GBIF_PERF_EN_REG_SEL_OFF  2

/* offset of clear register from the power enable register for GBIF*/
#define GBIF_PWR_CLR_REG_EN_OFF    1

/* */
#define GBIF_PERF_RMW_MASK   0xFF
/* */
#define GBIF_PWR_RMW_MASK    0x10000

/* offset of clear register from the enable register */
#define VBIF2_PERF_PWR_CLR_REG_EN_OFF 8

@@ -612,14 +626,41 @@ static void _perfcounter_enable_vbif(struct adreno_device *adreno_dev,
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	struct adreno_perfcount_register *reg;
	unsigned int shift = counter << 3;

	reg = &counters->groups[KGSL_PERFCOUNTER_GROUP_VBIF].regs[counter];
	/* Write 1, followed by 0 to CLR register for clearing the counter */
	kgsl_regwrite(device, reg->select - VBIF2_PERF_CLR_REG_SEL_OFF, 1);
	kgsl_regwrite(device, reg->select - VBIF2_PERF_CLR_REG_SEL_OFF, 0);
	kgsl_regwrite(device, reg->select, countable & VBIF2_PERF_CNT_SEL_MASK);

	if (adreno_has_gbif(adreno_dev)) {
		/*
		 * Write 1, followed by 0 to CLR register for
		 * clearing the counter
		 */
		kgsl_regrmw(device, reg->select - GBIF_PERF_CLR_REG_SEL_OFF,
			1 << counter, 1);
		kgsl_regrmw(device, reg->select - GBIF_PERF_CLR_REG_SEL_OFF,
			1 << counter, 0);
		/* select the desired countable */
		kgsl_regrmw(device, reg->select,
			GBIF_PERF_RMW_MASK << shift, countable << shift);
		/* enable counter */
		kgsl_regrmw(device, reg->select - GBIF_PERF_EN_REG_SEL_OFF,
			1 << counter, 1);

	} else {
		/*
		 * Write 1, followed by 0 to CLR register for
		 * clearing the counter
		 */
		kgsl_regwrite(device,
			reg->select - VBIF2_PERF_CLR_REG_SEL_OFF, 1);
		kgsl_regwrite(device,
			reg->select - VBIF2_PERF_CLR_REG_SEL_OFF, 0);
		kgsl_regwrite(device,
			reg->select, countable & VBIF2_PERF_CNT_SEL_MASK);
		/* enable reg is 8 DWORDS before select reg */
	kgsl_regwrite(device, reg->select - VBIF2_PERF_EN_REG_SEL_OFF, 1);
		kgsl_regwrite(device,
			reg->select - VBIF2_PERF_EN_REG_SEL_OFF, 1);
	}
	reg->value = 0;
}

@@ -630,10 +671,30 @@ static void _perfcounter_enable_vbif_pwr(struct adreno_device *adreno_dev,
	struct adreno_perfcount_register *reg;

	reg = &counters->groups[KGSL_PERFCOUNTER_GROUP_VBIF_PWR].regs[counter];
	/* Write 1, followed by 0 to CLR register for clearing the counter */
	kgsl_regwrite(device, reg->select + VBIF2_PERF_PWR_CLR_REG_EN_OFF, 1);
	kgsl_regwrite(device, reg->select + VBIF2_PERF_PWR_CLR_REG_EN_OFF, 0);

	if (adreno_has_gbif(adreno_dev)) {
		/*
		 * Write 1, followed by 0 to CLR register for
		 * clearing the counter
		 */
		kgsl_regrmw(device, reg->select + GBIF_PWR_CLR_REG_EN_OFF,
			GBIF_PWR_RMW_MASK << counter, 1);
		kgsl_regrmw(device, reg->select + GBIF_PWR_CLR_REG_EN_OFF,
			GBIF_PWR_RMW_MASK << counter, 0);
		/* Enable the counter */
		kgsl_regrmw(device, reg->select,
			GBIF_PWR_RMW_MASK << counter, 1);
	} else {
		/*
		 * Write 1, followed by 0 to CLR register for
		 * clearing the counter
		 */
		kgsl_regwrite(device, reg->select +
			VBIF2_PERF_PWR_CLR_REG_EN_OFF, 1);
		kgsl_regwrite(device, reg->select +
			VBIF2_PERF_PWR_CLR_REG_EN_OFF, 0);
		kgsl_regwrite(device, reg->select, 1);
	}
	reg->value = 0;
}