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

Commit cb769e42 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: Dump the CX debug bus information in A6XX" into msm-4.9

parents 331981b5 ff24c975
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -621,6 +621,48 @@
#define A6XX_VBIF_PERF_PWR_CNT_HIGH1            0x3119
#define A6XX_VBIF_PERF_PWR_CNT_HIGH2            0x311a

/* CX_DBGC_CFG registers */
#define A6XX_CX_DBGC_CFG_DBGBUS_SEL_A                   0x18400
#define A6XX_CX_DBGC_CFG_DBGBUS_SEL_B                   0x18401
#define A6XX_CX_DBGC_CFG_DBGBUS_SEL_C                   0x18402
#define A6XX_CX_DBGC_CFG_DBGBUS_SEL_D                   0x18403
#define A6XX_CX_DBGC_CFG_DBGBUS_CNTLT                   0x18404
#define A6XX_CX_DBGC_CFG_DBGBUS_CNTLT_TRACEEN_SHIFT     0x0
#define A6XX_CX_DBGC_CFG_DBGBUS_CNTLT_GRANU_SHIFT       0xC
#define A6XX_CX_DBGC_CFG_DBGBUS_CNTLT_SEGT_SHIFT        0x1C
#define A6XX_CX_DBGC_CFG_DBGBUS_CNTLM                   0x18405
#define A6XX_CX_DBGC_CFG_DBGBUS_CNTLM_ENABLE_SHIFT      0x18
#define A6XX_CX_DBGC_CFG_DBGBUS_IVTL_0                  0x18408
#define A6XX_CX_DBGC_CFG_DBGBUS_IVTL_1                  0x18409
#define A6XX_CX_DBGC_CFG_DBGBUS_IVTL_2                  0x1840A
#define A6XX_CX_DBGC_CFG_DBGBUS_IVTL_3                  0x1840B
#define A6XX_CX_DBGC_CFG_DBGBUS_MASKL_0                 0x1840C
#define A6XX_CX_DBGC_CFG_DBGBUS_MASKL_1                 0x1840D
#define A6XX_CX_DBGC_CFG_DBGBUS_MASKL_2                 0x1840E
#define A6XX_CX_DBGC_CFG_DBGBUS_MASKL_3                 0x1840F
#define A6XX_CX_DBGC_CFG_DBGBUS_BYTEL_0                 0x18410
#define A6XX_CX_DBGC_CFG_DBGBUS_BYTEL_1                 0x18411
#define A6XX_CX_DBGC_CFG_DBGBUS_BYTEL0_SHIFT            0x0
#define A6XX_CX_DBGC_CFG_DBGBUS_BYTEL1_SHIFT            0x4
#define A6XX_CX_DBGC_CFG_DBGBUS_BYTEL2_SHIFT            0x8
#define A6XX_CX_DBGC_CFG_DBGBUS_BYTEL3_SHIFT            0xC
#define A6XX_CX_DBGC_CFG_DBGBUS_BYTEL4_SHIFT            0x10
#define A6XX_CX_DBGC_CFG_DBGBUS_BYTEL5_SHIFT            0x14
#define A6XX_CX_DBGC_CFG_DBGBUS_BYTEL6_SHIFT            0x18
#define A6XX_CX_DBGC_CFG_DBGBUS_BYTEL7_SHIFT            0x1C
#define A6XX_CX_DBGC_CFG_DBGBUS_BYTEL8_SHIFT            0x0
#define A6XX_CX_DBGC_CFG_DBGBUS_BYTEL9_SHIFT            0x4
#define A6XX_CX_DBGC_CFG_DBGBUS_BYTEL10_SHIFT           0x8
#define A6XX_CX_DBGC_CFG_DBGBUS_BYTEL11_SHIFT           0xC
#define A6XX_CX_DBGC_CFG_DBGBUS_BYTEL12_SHIFT           0x10
#define A6XX_CX_DBGC_CFG_DBGBUS_BYTEL13_SHIFT           0x14
#define A6XX_CX_DBGC_CFG_DBGBUS_BYTEL14_SHIFT           0x18
#define A6XX_CX_DBGC_CFG_DBGBUS_BYTEL15_SHIFT           0x1C
#define A6XX_CX_DBGC_CFG_DBGBUS_TRACE_BUF1              0x1842F
#define A6XX_CX_DBGC_CFG_DBGBUS_TRACE_BUF2              0x18430
#define A6XX_CX_DBGC_CFG_DBGBUS_SEL_PING_INDEX_SHIFT    0x0
#define A6XX_CX_DBGC_CFG_DBGBUS_SEL_PING_BLK_SEL_SHIFT  0x8

/* GMU control registers */
#define A6XX_GMU_GX_SPTPRAC_POWER_CONTROL	0x1A881
#define A6XX_GMU_CM3_ITCM_START			0x1B400
+156 −0
Original line number Diff line number Diff line
@@ -342,6 +342,13 @@ static const struct adreno_debugbus_block a6xx_dbgc_debugbus_blocks[] = {
	{ A6XX_DBGBUS_TPL1_3, 0x100, },
};

static void __iomem *a6xx_cx_dbgc;
static const struct adreno_debugbus_block a6xx_cx_dbgc_debugbus_blocks[] = {
	{ A6XX_DBGBUS_VBIF, 0x100, },
	{ A6XX_DBGBUS_GMU, 0x100, },
	{ A6XX_DBGBUS_CX, 0x100, },
};

#define A6XX_NUM_SHADER_BANKS 3
#define A6XX_SHADER_STATETYPE_SHIFT 8

@@ -904,6 +911,100 @@ static size_t a6xx_snapshot_dbgc_debugbus_block(struct kgsl_device *device,
	return size;
}

static void _cx_dbgc_regread(unsigned int offsetwords, unsigned int *value)
{
	void __iomem *reg;

	if (WARN((offsetwords < A6XX_CX_DBGC_CFG_DBGBUS_SEL_A) ||
		(offsetwords > A6XX_CX_DBGC_CFG_DBGBUS_TRACE_BUF2),
		"Read beyond CX_DBGC block: 0x%x\n", offsetwords))
		return;

	reg = a6xx_cx_dbgc +
		((offsetwords - A6XX_CX_DBGC_CFG_DBGBUS_SEL_A) << 2);
	*value = __raw_readl(reg);

	/*
	 * ensure this read finishes before the next one.
	 * i.e. act like normal readl()
	 */
	rmb();
}

static void _cx_dbgc_regwrite(unsigned int offsetwords, unsigned int value)
{
	void __iomem *reg;

	if (WARN((offsetwords < A6XX_CX_DBGC_CFG_DBGBUS_SEL_A) ||
		(offsetwords > A6XX_CX_DBGC_CFG_DBGBUS_TRACE_BUF2),
		"Write beyond CX_DBGC block: 0x%x\n", offsetwords))
		return;

	reg = a6xx_cx_dbgc +
		((offsetwords - A6XX_CX_DBGC_CFG_DBGBUS_SEL_A) << 2);

	/*
	 * ensure previous writes post before this one,
	 * i.e. act like normal writel()
	 */
	wmb();
	__raw_writel(value, reg);
}

/* a6xx_cx_dbgc_debug_bus_read() - Read data from trace bus */
static void a6xx_cx_debug_bus_read(struct kgsl_device *device,
	unsigned int block_id, unsigned int index, unsigned int *val)
{
	unsigned int reg;

	reg = (block_id << A6XX_CX_DBGC_CFG_DBGBUS_SEL_PING_BLK_SEL_SHIFT) |
			(index << A6XX_CX_DBGC_CFG_DBGBUS_SEL_PING_INDEX_SHIFT);

	_cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_SEL_A, reg);
	_cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_SEL_B, reg);
	_cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_SEL_C, reg);
	_cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_SEL_D, reg);

	_cx_dbgc_regread(A6XX_CX_DBGC_CFG_DBGBUS_TRACE_BUF2, val);
	val++;
	_cx_dbgc_regread(A6XX_CX_DBGC_CFG_DBGBUS_TRACE_BUF1, val);
}

/*
 * a6xx_snapshot_cx_dbgc_debugbus_block() - Capture debug data for a gpu
 * block from the CX DBGC block
 */
static size_t a6xx_snapshot_cx_dbgc_debugbus_block(struct kgsl_device *device,
	u8 *buf, size_t remain, void *priv)
{
	struct kgsl_snapshot_debugbus *header =
		(struct kgsl_snapshot_debugbus *)buf;
	struct adreno_debugbus_block *block = priv;
	int i;
	unsigned int *data = (unsigned int *)(buf + sizeof(*header));
	unsigned int dwords;
	size_t size;

	dwords = block->dwords;

	/* For a6xx each debug bus data unit is 2 DWRODS */
	size = (dwords * sizeof(unsigned int) * 2) + sizeof(*header);

	if (remain < size) {
		SNAPSHOT_ERR_NOMEM(device, "DEBUGBUS");
		return 0;
	}

	header->id = block->block_id;
	header->count = dwords * 2;

	for (i = 0; i < dwords; i++)
		a6xx_cx_debug_bus_read(device, block->block_id, i,
					&data[i*2]);

	return size;
}

/* a6xx_snapshot_debugbus() - Capture debug bus data */
static void a6xx_snapshot_debugbus(struct kgsl_device *device,
		struct kgsl_snapshot *snapshot)
@@ -947,12 +1048,67 @@ static void a6xx_snapshot_debugbus(struct kgsl_device *device,
	kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_MASKL_2, 0);
	kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_MASKL_3, 0);

	a6xx_cx_dbgc = ioremap(device->reg_phys +
			(A6XX_CX_DBGC_CFG_DBGBUS_SEL_A << 2),
			(A6XX_CX_DBGC_CFG_DBGBUS_TRACE_BUF2 -
				A6XX_CX_DBGC_CFG_DBGBUS_SEL_A + 1) << 2);

	if (a6xx_cx_dbgc) {
		_cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_CNTLT,
		(0xf << A6XX_DBGC_CFG_DBGBUS_CNTLT_SEGT_SHIFT) |
		(0x4 << A6XX_DBGC_CFG_DBGBUS_CNTLT_GRANU_SHIFT) |
		(0x20 << A6XX_DBGC_CFG_DBGBUS_CNTLT_TRACEEN_SHIFT));

		_cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_CNTLM,
			0xf << A6XX_CX_DBGC_CFG_DBGBUS_CNTLM_ENABLE_SHIFT);

		_cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_IVTL_0, 0);
		_cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_IVTL_1, 0);
		_cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_IVTL_2, 0);
		_cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_IVTL_3, 0);

		_cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_BYTEL_0,
			(0 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL0_SHIFT) |
			(1 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL1_SHIFT) |
			(2 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL2_SHIFT) |
			(3 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL3_SHIFT) |
			(4 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL4_SHIFT) |
			(5 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL5_SHIFT) |
			(6 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL6_SHIFT) |
			(7 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL7_SHIFT));
		_cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_BYTEL_1,
			(8 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL8_SHIFT) |
			(9 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL9_SHIFT) |
			(10 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL10_SHIFT) |
			(11 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL11_SHIFT) |
			(12 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL12_SHIFT) |
			(13 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL13_SHIFT) |
			(14 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL14_SHIFT) |
			(15 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL15_SHIFT));

		_cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_MASKL_0, 0);
		_cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_MASKL_1, 0);
		_cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_MASKL_2, 0);
		_cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_MASKL_3, 0);
	} else
		KGSL_DRV_ERR(device, "Unable to ioremap CX_DBGC_CFG block\n");

	for (i = 0; i < ARRAY_SIZE(a6xx_dbgc_debugbus_blocks); i++) {
		kgsl_snapshot_add_section(device,
			KGSL_SNAPSHOT_SECTION_DEBUGBUS,
			snapshot, a6xx_snapshot_dbgc_debugbus_block,
			(void *) &a6xx_dbgc_debugbus_blocks[i]);
	}

	if (a6xx_cx_dbgc) {
		for (i = 0; i < ARRAY_SIZE(a6xx_cx_dbgc_debugbus_blocks); i++) {
			kgsl_snapshot_add_section(device,
				KGSL_SNAPSHOT_SECTION_DEBUGBUS,
				snapshot, a6xx_snapshot_cx_dbgc_debugbus_block,
				(void *) &a6xx_cx_dbgc_debugbus_blocks[i]);
		}
		iounmap(a6xx_cx_dbgc);
	}
}

static size_t a6xx_snapshot_dump_gmu_registers(struct kgsl_device *device,