msm: kgsl: Add snapshot and postmortem support for A3XX
Modify postmortem and GPU snapshot to dump A3XX debug sections
and registers.
Change-Id: Ic0dedbadb28be76d5ad2dcf214bc88b15dd7342e
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
diff --git a/drivers/gpu/msm/Makefile b/drivers/gpu/msm/Makefile
index 04d53c0..5189388 100644
--- a/drivers/gpu/msm/Makefile
+++ b/drivers/gpu/msm/Makefile
@@ -26,6 +26,7 @@
adreno_a2xx_trace.o \
adreno_a2xx_snapshot.o \
adreno_a3xx.o \
+ adreno_a3xx_snapshot.o \
adreno.o
msm_adreno-$(CONFIG_DEBUG_FS) += adreno_debugfs.o
diff --git a/drivers/gpu/msm/a2xx_reg.h b/drivers/gpu/msm/a2xx_reg.h
index 50b2745..4c0bd19 100644
--- a/drivers/gpu/msm/a2xx_reg.h
+++ b/drivers/gpu/msm/a2xx_reg.h
@@ -278,6 +278,7 @@
#define REG_CP_ME_CNTL 0x01F6
#define REG_CP_ME_RAM_DATA 0x01FA
#define REG_CP_ME_RAM_WADDR 0x01F8
+#define REG_CP_ME_RAM_RADDR 0x01F9
#define REG_CP_ME_STATUS 0x01F7
#define REG_CP_PFP_UCODE_ADDR 0x00C0
#define REG_CP_PFP_UCODE_DATA 0x00C1
diff --git a/drivers/gpu/msm/a3xx_reg.h b/drivers/gpu/msm/a3xx_reg.h
index 84c83b8..1806886 100644
--- a/drivers/gpu/msm/a3xx_reg.h
+++ b/drivers/gpu/msm/a3xx_reg.h
@@ -67,9 +67,15 @@
#define A3XX_RBBM_RBBM_CTL 0x100
#define A3XX_RBBM_PERFCTR_PWR_1_LO 0x0EC
#define A3XX_RBBM_PERFCTR_PWR_1_HI 0x0ED
+#define A3XX_RBBM_DEBUG_BUS_CTL 0x111
+#define A3XX_RBBM_DEBUG_BUS_DATA_STATUS 0x112
/* Following two are same as on A2XX, just in a different place */
#define A3XX_CP_PFP_UCODE_ADDR 0x1C9
#define A3XX_CP_PFP_UCODE_DATA 0x1CA
+#define A3XX_CP_ROQ_ADDR 0x1CC
+#define A3XX_CP_ROQ_DATA 0x1CD
+#define A3XX_CP_MEQ_ADDR 0x1DA
+#define A3XX_CP_MEQ_DATA 0x1DB
#define A3XX_CP_HW_FAULT 0x45C
#define A3XX_CP_AHB_FAULT 0x54D
#define A3XX_CP_PROTECT_CTRL 0x45E
@@ -142,6 +148,8 @@
#define A3XX_GRAS_CL_USER_PLANE_Y5 0xCB5
#define A3XX_GRAS_CL_USER_PLANE_Z5 0xCB6
#define A3XX_GRAS_CL_USER_PLANE_W5 0xCB7
+#define A3XX_VPC_VPC_DEBUG_RAM_SEL 0xE61
+#define A3XX_VPC_VPC_DEBUG_RAM_READ 0xE62
#define A3XX_UCHE_CACHE_INVALIDATE0_REG 0xEA0
#define A3XX_GRAS_CL_CLIP_CNTL 0x2040
#define A3XX_GRAS_CL_GB_CLIP_ADJ 0x2044
@@ -450,4 +458,34 @@
#define VPC_VPCVARPSREPLMODE_COMPONENT16 28
#define VPC_VPCVARPSREPLMODE_COMPONENT17 30
+/* RBBM Debug bus block IDs */
+#define RBBM_BLOCK_ID_NONE 0x0
+#define RBBM_BLOCK_ID_CP 0x1
+#define RBBM_BLOCK_ID_RBBM 0x2
+#define RBBM_BLOCK_ID_VBIF 0x3
+#define RBBM_BLOCK_ID_HLSQ 0x4
+#define RBBM_BLOCK_ID_UCHE 0x5
+#define RBBM_BLOCK_ID_PC 0x8
+#define RBBM_BLOCK_ID_VFD 0x9
+#define RBBM_BLOCK_ID_VPC 0xa
+#define RBBM_BLOCK_ID_TSE 0xb
+#define RBBM_BLOCK_ID_RAS 0xc
+#define RBBM_BLOCK_ID_VSC 0xd
+#define RBBM_BLOCK_ID_SP_0 0x10
+#define RBBM_BLOCK_ID_SP_1 0x11
+#define RBBM_BLOCK_ID_SP_2 0x12
+#define RBBM_BLOCK_ID_SP_3 0x13
+#define RBBM_BLOCK_ID_TPL1_0 0x18
+#define RBBM_BLOCK_ID_TPL1_1 0x19
+#define RBBM_BLOCK_ID_TPL1_2 0x1a
+#define RBBM_BLOCK_ID_TPL1_3 0x1b
+#define RBBM_BLOCK_ID_RB_0 0x20
+#define RBBM_BLOCK_ID_RB_1 0x21
+#define RBBM_BLOCK_ID_RB_2 0x22
+#define RBBM_BLOCK_ID_RB_3 0x23
+#define RBBM_BLOCK_ID_MARB_0 0x28
+#define RBBM_BLOCK_ID_MARB_1 0x29
+#define RBBM_BLOCK_ID_MARB_2 0x2a
+#define RBBM_BLOCK_ID_MARB_3 0x2b
+
#endif
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 95b6253..9c2d704 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -107,6 +107,10 @@
extern const unsigned int a200_registers_count;
extern const unsigned int a220_registers_count;
+/* A3XX register set defined in adreno_a3xx.c */
+extern const unsigned int a3xx_registers[];
+extern const unsigned int a3xx_registers_count;
+
int adreno_idle(struct kgsl_device *device, unsigned int timeout);
void adreno_regread(struct kgsl_device *device, unsigned int offsetwords,
unsigned int *value);
diff --git a/drivers/gpu/msm/adreno_a2xx_snapshot.c b/drivers/gpu/msm/adreno_a2xx_snapshot.c
index 30d692b..091db22 100644
--- a/drivers/gpu/msm/adreno_a2xx_snapshot.c
+++ b/drivers/gpu/msm/adreno_a2xx_snapshot.c
@@ -224,24 +224,6 @@
return DEBUG_SECTION_SZ(MIUDEBUG_COUNT);
}
-/* Helper function to snapshot a section of indexed registers */
-
-static void *a2xx_snapshot_indexed_registers(struct kgsl_device *device,
- void *snapshot, int *remain,
- unsigned int index, unsigned int data, unsigned int start,
- unsigned int count)
-{
- struct kgsl_snapshot_indexed_registers iregs;
- iregs.index = index;
- iregs.data = data;
- iregs.start = start;
- iregs.count = count;
-
- return kgsl_snapshot_add_section(device,
- KGSL_SNAPSHOT_SECTION_INDEXED_REGS, snapshot,
- remain, kgsl_snapshot_dump_indexed_regs, &iregs);
-}
-
/* A2XX GPU snapshot function - this is where all of the A2XX specific
* bits and pieces are grabbed into the snapshot memory
*/
@@ -269,12 +251,12 @@
kgsl_snapshot_dump_regs, ®s);
/* CP_STATE_DEBUG indexed registers */
- snapshot = a2xx_snapshot_indexed_registers(device, snapshot,
+ snapshot = kgsl_snapshot_indexed_registers(device, snapshot,
remain, REG_CP_STATE_DEBUG_INDEX,
REG_CP_STATE_DEBUG_DATA, 0x0, 0x14);
/* CP_ME indexed registers */
- snapshot = a2xx_snapshot_indexed_registers(device, snapshot,
+ snapshot = kgsl_snapshot_indexed_registers(device, snapshot,
remain, REG_CP_ME_CNTL, REG_CP_ME_STATUS,
64, 44);
@@ -293,7 +275,7 @@
/* SU debug indexed registers (only for < 470) */
if (!adreno_is_a22x(adreno_dev))
- snapshot = a2xx_snapshot_indexed_registers(device, snapshot,
+ snapshot = kgsl_snapshot_indexed_registers(device, snapshot,
remain, REG_PA_SU_DEBUG_CNTL,
REG_PA_SU_DEBUG_DATA,
0, 0x1B);
@@ -304,26 +286,26 @@
a2xx_snapshot_cpdebug, NULL);
/* MH debug indexed registers */
- snapshot = a2xx_snapshot_indexed_registers(device, snapshot,
+ snapshot = kgsl_snapshot_indexed_registers(device, snapshot,
remain, MH_DEBUG_CTRL, MH_DEBUG_DATA, 0x0, 0x40);
/* Leia only register sets */
if (adreno_is_a22x(adreno_dev)) {
/* RB DEBUG indexed regisers */
- snapshot = a2xx_snapshot_indexed_registers(device, snapshot,
+ snapshot = kgsl_snapshot_indexed_registers(device, snapshot,
remain, REG_RB_DEBUG_CNTL, REG_RB_DEBUG_DATA, 0, 8);
/* RB DEBUG indexed registers bank 2 */
- snapshot = a2xx_snapshot_indexed_registers(device, snapshot,
+ snapshot = kgsl_snapshot_indexed_registers(device, snapshot,
remain, REG_RB_DEBUG_CNTL, REG_RB_DEBUG_DATA + 0x1000,
0, 8);
/* PC_DEBUG indexed registers */
- snapshot = a2xx_snapshot_indexed_registers(device, snapshot,
+ snapshot = kgsl_snapshot_indexed_registers(device, snapshot,
remain, REG_PC_DEBUG_CNTL, REG_PC_DEBUG_DATA, 0, 8);
/* GRAS_DEBUG indexed registers */
- snapshot = a2xx_snapshot_indexed_registers(device, snapshot,
+ snapshot = kgsl_snapshot_indexed_registers(device, snapshot,
remain, REG_GRAS_DEBUG_CNTL, REG_GRAS_DEBUG_DATA, 0, 4);
/* MIU debug registers */
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index cbc7bed..1bad811 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -19,6 +19,51 @@
#include "kgsl_cffdump.h"
#include "a3xx_reg.h"
+/*
+ * Set of registers to dump for A3XX on postmortem and snapshot.
+ * Registers in pairs - first value is the start offset, second
+ * is the stop offset (inclusive)
+ */
+
+const unsigned int a3xx_registers[] = {
+ 0x0000, 0x0002, 0x0010, 0x0012, 0x0018, 0x0018, 0x0020, 0x0027,
+ 0x0029, 0x002b, 0x002e, 0x0033, 0x0040, 0x0042, 0x0050, 0x005c,
+ 0x0060, 0x006c, 0x0080, 0x0082, 0x0084, 0x0088, 0x0090, 0x00e5,
+ 0x00ea, 0x00ed, 0x0100, 0x0100, 0x0110, 0x0123, 0x01c0, 0x01c1,
+ 0x01c3, 0x01c5, 0x01c7, 0x01c7, 0x01d5, 0x01d9, 0x01dc, 0x01dd,
+ 0x01ea, 0x01ea, 0x01ee, 0x01f1, 0x01f5, 0x01f5, 0x01fc, 0x01ff,
+ 0x0440, 0x0440, 0x0443, 0x0443, 0x0445, 0x0445, 0x044d, 0x044f,
+ 0x0452, 0x0452, 0x0454, 0x046f, 0x047c, 0x047c, 0x047f, 0x047f,
+ 0x0579, 0x057f, 0x0600, 0x0602, 0x0605, 0x0607, 0x060a, 0x060e,
+ 0x0612, 0x0614, 0x0c01, 0x0c02, 0x0c06, 0x0c1d, 0x0c3d, 0x0c3f,
+ 0x0c48, 0x0c4b, 0x0c80, 0x0c80, 0x0c88, 0x0c8b, 0x0ca0, 0x0cb7,
+ 0x0cc0, 0x0cc1, 0x0cc6, 0x0cc7, 0x0ce4, 0x0ce5, 0x0e00, 0x0e05,
+ 0x0e0c, 0x0e0c, 0x0e22, 0x0e23, 0x0e41, 0x0e45, 0x0e64, 0x0e65,
+ 0x0e80, 0x0e82, 0x0e84, 0x0e89, 0x0ea0, 0x0ea1, 0x0ea4, 0x0ea7,
+ 0x0ec4, 0x0ecb, 0x0ee0, 0x0ee0, 0x0f00, 0x0f01, 0x0f03, 0x0f09,
+ 0x2040, 0x2040, 0x2044, 0x2044, 0x2048, 0x204d, 0x2068, 0x2069,
+ 0x206c, 0x206d, 0x2070, 0x2070, 0x2072, 0x2072, 0x2074, 0x2075,
+ 0x2079, 0x207a, 0x20c0, 0x20d3, 0x20e4, 0x20ef, 0x2100, 0x2109,
+ 0x210c, 0x210c, 0x210e, 0x210e, 0x2110, 0x2111, 0x2114, 0x2115,
+ 0x21e4, 0x21e4, 0x21ea, 0x21ea, 0x21ec, 0x21ed, 0x21f0, 0x21f0,
+ 0x2200, 0x2212, 0x2214, 0x2217, 0x221a, 0x221a, 0x2240, 0x227e,
+ 0x2280, 0x228b, 0x22c0, 0x22c0, 0x22c4, 0x22ce, 0x22d0, 0x22d8,
+ 0x22df, 0x22e6, 0x22e8, 0x22e9, 0x22ec, 0x22ec, 0x22f0, 0x22f7,
+ 0x22ff, 0x22ff, 0x2340, 0x2343, 0x2348, 0x2349, 0x2350, 0x2356,
+ 0x2360, 0x2360, 0x2440, 0x2440, 0x2444, 0x2444, 0x2448, 0x244d,
+ 0x2468, 0x2469, 0x246c, 0x246d, 0x2470, 0x2470, 0x2472, 0x2472,
+ 0x2474, 0x2475, 0x2479, 0x247a, 0x24c0, 0x24d3, 0x24e4, 0x24ef,
+ 0x2500, 0x2509, 0x250c, 0x250c, 0x250e, 0x250e, 0x2510, 0x2511,
+ 0x2514, 0x2515, 0x25e4, 0x25e4, 0x25ea, 0x25ea, 0x25ec, 0x25ed,
+ 0x25f0, 0x25f0, 0x2600, 0x2612, 0x2614, 0x2617, 0x261a, 0x261a,
+ 0x2640, 0x267e, 0x2680, 0x268b, 0x26c0, 0x26c0, 0x26c4, 0x26ce,
+ 0x26d0, 0x26d8, 0x26df, 0x26e6, 0x26e8, 0x26e9, 0x26ec, 0x26ec,
+ 0x26f0, 0x26f7, 0x26ff, 0x26ff, 0x2740, 0x2743, 0x2748, 0x2749,
+ 0x2750, 0x2756, 0x2760, 0x2760,
+};
+
+const unsigned int a3xx_registers_count = ARRAY_SIZE(a3xx_registers) / 2;
+
/* Simple macro to facilitate bit setting in the gmem2sys and sys2gmem
* functions.
*/
@@ -2531,6 +2576,10 @@
adreno_regwrite(device, A3XX_RBBM_RBBM_CTL, 0x00003000);
}
+/* Defined in adreno_a3xx_snapshot.c */
+void *a3xx_snapshot(struct adreno_device *adreno_dev, void *snapshot,
+ int *remain, int hang);
+
struct adreno_gpudev adreno_a3xx_gpudev = {
.reg_rbbm_status = A3XX_RBBM_STATUS,
.reg_cp_pfp_ucode_addr = A3XX_CP_PFP_UCODE_ADDR,
@@ -2544,4 +2593,5 @@
.irq_handler = a3xx_irq_handler,
.busy_cycles = a3xx_busy_cycles,
.start = a3xx_start,
+ .snapshot = a3xx_snapshot,
};
diff --git a/drivers/gpu/msm/adreno_a3xx_snapshot.c b/drivers/gpu/msm/adreno_a3xx_snapshot.c
new file mode 100644
index 0000000..aade50c
--- /dev/null
+++ b/drivers/gpu/msm/adreno_a3xx_snapshot.c
@@ -0,0 +1,296 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "kgsl.h"
+#include "adreno.h"
+#include "kgsl_snapshot.h"
+#include "a3xx_reg.h"
+
+#define DEBUG_SECTION_SZ(_dwords) (((_dwords) * sizeof(unsigned int)) \
+ + sizeof(struct kgsl_snapshot_debug))
+
+#define VPC_MEMORY_BANKS 4
+#define VPC_MEMORY_SIZE 512
+
+static int a3xx_snapshot_vpc_memory(struct kgsl_device *device, void *snapshot,
+ int remain, void *priv)
+{
+ struct kgsl_snapshot_debug *header = snapshot;
+ unsigned int *data = snapshot + sizeof(*header);
+ int size = VPC_MEMORY_BANKS * VPC_MEMORY_SIZE;
+ int bank, addr, i = 0;
+
+ if (remain < DEBUG_SECTION_SZ(size)) {
+ SNAPSHOT_ERR_NOMEM(device, "VPC MEMORY");
+ return 0;
+ }
+
+ header->type = SNAPSHOT_DEBUG_VPC_MEMORY;
+ header->size = size;
+
+ for (bank = 0; bank < VPC_MEMORY_BANKS; bank++) {
+ for (addr = 0; addr < VPC_MEMORY_SIZE; addr++) {
+ unsigned int val = bank | (addr << 4);
+ adreno_regwrite(device,
+ A3XX_VPC_VPC_DEBUG_RAM_SEL, val);
+ adreno_regread(device,
+ A3XX_VPC_VPC_DEBUG_RAM_READ, &data[i++]);
+ }
+ }
+
+ return DEBUG_SECTION_SZ(size);
+}
+
+#define CP_MEQ_SIZE 16
+static int a3xx_snapshot_cp_meq(struct kgsl_device *device, void *snapshot,
+ int remain, void *priv)
+{
+ struct kgsl_snapshot_debug *header = snapshot;
+ unsigned int *data = snapshot + sizeof(*header);
+ int i;
+
+ if (remain < DEBUG_SECTION_SZ(CP_MEQ_SIZE)) {
+ SNAPSHOT_ERR_NOMEM(device, "CP MEQ DEBUG");
+ return 0;
+ }
+
+ header->type = SNAPSHOT_DEBUG_CP_MEQ;
+ header->size = CP_MEQ_SIZE;
+
+ adreno_regwrite(device, A3XX_CP_MEQ_ADDR, 0x0);
+ for (i = 0; i < CP_MEQ_SIZE; i++)
+ adreno_regread(device, A3XX_CP_MEQ_DATA, &data[i]);
+
+ return DEBUG_SECTION_SZ(CP_MEQ_SIZE);
+}
+
+static int a3xx_snapshot_cp_pm4_ram(struct kgsl_device *device, void *snapshot,
+ int remain, void *priv)
+{
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+ struct kgsl_snapshot_debug *header = snapshot;
+ unsigned int *data = snapshot + sizeof(*header);
+ int i, size = adreno_dev->pm4_fw_size >> 2;
+
+ if (remain < DEBUG_SECTION_SZ(size)) {
+ SNAPSHOT_ERR_NOMEM(device, "CP PM4 RAM DEBUG");
+ return 0;
+ }
+
+ header->type = SNAPSHOT_DEBUG_CP_PM4_RAM;
+ header->size = size;
+
+ /*
+ * Read the firmware from the GPU rather than use our cache in order to
+ * try to catch mis-programming or corruption in the hardware. We do
+ * use the cached version of the size, however, instead of trying to
+ * maintain always changing hardcoded constants
+ */
+
+ adreno_regwrite(device, REG_CP_ME_RAM_RADDR, 0x0);
+ for (i = 0; i < adreno_dev->pm4_fw_size >> 2; i++)
+ adreno_regread(device, REG_CP_ME_RAM_DATA, &data[i]);
+
+ return DEBUG_SECTION_SZ(size);
+}
+
+static int a3xx_snapshot_cp_pfp_ram(struct kgsl_device *device, void *snapshot,
+ int remain, void *priv)
+{
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+ struct kgsl_snapshot_debug *header = snapshot;
+ unsigned int *data = snapshot + sizeof(*header);
+ int i, size = adreno_dev->pfp_fw_size >> 2;
+
+ if (remain < DEBUG_SECTION_SZ(size)) {
+ SNAPSHOT_ERR_NOMEM(device, "CP PFP RAM DEBUG");
+ return 0;
+ }
+
+ header->type = SNAPSHOT_DEBUG_CP_PFP_RAM;
+ header->size = size;
+
+ /*
+ * Read the firmware from the GPU rather than use our cache in order to
+ * try to catch mis-programming or corruption in the hardware. We do
+ * use the cached version of the size, however, instead of trying to
+ * maintain always changing hardcoded constants
+ */
+ kgsl_regwrite(device, A3XX_CP_PFP_UCODE_ADDR, 0x0);
+ for (i = 0; i < adreno_dev->pfp_fw_size >> 2; i++)
+ adreno_regread(device, A3XX_CP_PFP_UCODE_DATA, &data[i]);
+
+ return DEBUG_SECTION_SZ(size);
+}
+
+#define CP_ROQ_SIZE 128
+
+static int a3xx_snapshot_cp_roq(struct kgsl_device *device, void *snapshot,
+ int remain, void *priv)
+{
+ struct kgsl_snapshot_debug *header = snapshot;
+ unsigned int *data = snapshot + sizeof(*header);
+ int i;
+
+ if (remain < DEBUG_SECTION_SZ(CP_ROQ_SIZE)) {
+ SNAPSHOT_ERR_NOMEM(device, "CP ROQ DEBUG");
+ return 0;
+ }
+
+ header->type = SNAPSHOT_DEBUG_CP_ROQ;
+ header->size = CP_ROQ_SIZE;
+
+ adreno_regwrite(device, A3XX_CP_ROQ_ADDR, 0x0);
+ for (i = 0; i < CP_ROQ_SIZE; i++)
+ adreno_regread(device, A3XX_CP_ROQ_DATA, &data[i]);
+
+ return DEBUG_SECTION_SZ(CP_ROQ_SIZE);
+}
+
+#define DEBUGFS_BLOCK_SIZE 0x40
+
+static int a3xx_snapshot_debugbus_block(struct kgsl_device *device,
+ void *snapshot, int remain, void *priv)
+{
+ struct kgsl_snapshot_debugbus *header = snapshot;
+ unsigned int id = (unsigned int) priv;
+ unsigned int val;
+ int i;
+ unsigned int *data = snapshot + sizeof(*header);
+ int size =
+ (DEBUGFS_BLOCK_SIZE * sizeof(unsigned int)) + sizeof(*header);
+
+ if (remain < size) {
+ SNAPSHOT_ERR_NOMEM(device, "DEBUGBUS");
+ return 0;
+ }
+
+ val = (id << 0x06) | (1 << 0x10);
+
+ header->id = id;
+ header->count = DEBUGFS_BLOCK_SIZE;
+
+ for (i = 0; i < DEBUGFS_BLOCK_SIZE; i++) {
+ adreno_regwrite(device, A3XX_RBBM_DEBUG_BUS_CTL, val | i);
+ adreno_regread(device, A3XX_RBBM_DEBUG_BUS_DATA_STATUS,
+ &data[i]);
+ }
+
+ return size;
+}
+
+static unsigned int debugbus_blocks[] = {
+ RBBM_BLOCK_ID_CP,
+ RBBM_BLOCK_ID_RBBM,
+ RBBM_BLOCK_ID_VBIF,
+ RBBM_BLOCK_ID_HLSQ,
+ RBBM_BLOCK_ID_UCHE,
+ RBBM_BLOCK_ID_PC,
+ RBBM_BLOCK_ID_VFD,
+ RBBM_BLOCK_ID_VPC,
+ RBBM_BLOCK_ID_TSE,
+ RBBM_BLOCK_ID_RAS,
+ RBBM_BLOCK_ID_VSC,
+ RBBM_BLOCK_ID_SP_0,
+ RBBM_BLOCK_ID_SP_1,
+ RBBM_BLOCK_ID_SP_2,
+ RBBM_BLOCK_ID_SP_3,
+ RBBM_BLOCK_ID_TPL1_0,
+ RBBM_BLOCK_ID_TPL1_1,
+ RBBM_BLOCK_ID_TPL1_2,
+ RBBM_BLOCK_ID_TPL1_3,
+ RBBM_BLOCK_ID_RB_0,
+ RBBM_BLOCK_ID_RB_1,
+ RBBM_BLOCK_ID_RB_2,
+ RBBM_BLOCK_ID_RB_3,
+ RBBM_BLOCK_ID_MARB_0,
+ RBBM_BLOCK_ID_MARB_1,
+ RBBM_BLOCK_ID_MARB_2,
+ RBBM_BLOCK_ID_MARB_3,
+};
+
+static void *a3xx_snapshot_debugbus(struct kgsl_device *device,
+ void *snapshot, int *remain)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(debugbus_blocks); i++) {
+ snapshot = kgsl_snapshot_add_section(device,
+ KGSL_SNAPSHOT_SECTION_DEBUGBUS, snapshot, remain,
+ a3xx_snapshot_debugbus_block,
+ (void *) debugbus_blocks[i]);
+ }
+
+ return snapshot;
+}
+
+/* A3XX GPU snapshot function - this is where all of the A3XX specific
+ * bits and pieces are grabbed into the snapshot memory
+ */
+
+void *a3xx_snapshot(struct adreno_device *adreno_dev, void *snapshot,
+ int *remain, int hang)
+{
+ struct kgsl_device *device = &adreno_dev->dev;
+ struct kgsl_snapshot_registers regs;
+
+ regs.regs = (unsigned int *) a3xx_registers;
+ regs.count = a3xx_registers_count;
+
+ /* Master set of (non debug) registers */
+ snapshot = kgsl_snapshot_add_section(device,
+ KGSL_SNAPSHOT_SECTION_REGS, snapshot, remain,
+ kgsl_snapshot_dump_regs, ®s);
+
+ /* CP_STATE_DEBUG indexed registers */
+ snapshot = kgsl_snapshot_indexed_registers(device, snapshot,
+ remain, REG_CP_STATE_DEBUG_INDEX,
+ REG_CP_STATE_DEBUG_DATA, 0x0, 0x14);
+
+ /* CP_ME indexed registers */
+ snapshot = kgsl_snapshot_indexed_registers(device, snapshot,
+ remain, REG_CP_ME_CNTL, REG_CP_ME_STATUS,
+ 64, 44);
+
+ /* VPC memory */
+ snapshot = kgsl_snapshot_add_section(device,
+ KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain,
+ a3xx_snapshot_vpc_memory, NULL);
+
+ /* CP MEQ */
+ snapshot = kgsl_snapshot_add_section(device,
+ KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain,
+ a3xx_snapshot_cp_meq, NULL);
+
+ /* CP PFP and PM4 */
+ /* Reading these will hang the GPU if it isn't already hung */
+
+ if (hang) {
+ snapshot = kgsl_snapshot_add_section(device,
+ KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain,
+ a3xx_snapshot_cp_pfp_ram, NULL);
+
+ snapshot = kgsl_snapshot_add_section(device,
+ KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain,
+ a3xx_snapshot_cp_pm4_ram, NULL);
+ }
+
+ /* CP ROQ */
+ snapshot = kgsl_snapshot_add_section(device,
+ KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain,
+ a3xx_snapshot_cp_roq, NULL);
+
+ snapshot = a3xx_snapshot_debugbus(device, snapshot, remain);
+
+ return snapshot;
+}
diff --git a/drivers/gpu/msm/adreno_postmortem.c b/drivers/gpu/msm/adreno_postmortem.c
index 7f054b1..98e3810 100644
--- a/drivers/gpu/msm/adreno_postmortem.c
+++ b/drivers/gpu/msm/adreno_postmortem.c
@@ -24,6 +24,7 @@
#include "kgsl_pwrctrl.h"
#include "a2xx_reg.h"
+#include "a3xx_reg.h"
#define INVALID_RB_CMD 0xaaaaaaaa
#define NUM_DWORDS_OF_RINGBUFFER_HISTORY 100
@@ -362,29 +363,160 @@
}
}
-static int adreno_dump(struct kgsl_device *device)
+static void adreno_dump_a3xx(struct kgsl_device *device)
{
unsigned int r1, r2, r3, rbbm_status;
- unsigned int cp_ib1_base, cp_ib1_bufsz, cp_stat;
- unsigned int cp_ib2_base, cp_ib2_bufsz;
- unsigned int pt_base, cur_pt_base;
- unsigned int cp_rb_base, rb_count;
- unsigned int cp_rb_wptr, cp_rb_rptr;
- unsigned int i;
- int result = 0;
- uint32_t *rb_copy;
- const uint32_t *rb_vaddr;
- int num_item = 0;
- int read_idx, write_idx;
- unsigned int ts_processed;
-
- static struct ib_list ib_list;
-
+ unsigned int cp_stat, rb_count;
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
- mb();
+ kgsl_regread(device, adreno_dev->gpudev->reg_rbbm_status, &rbbm_status);
+ KGSL_LOG_DUMP(device, "RBBM: STATUS = %08X\n", rbbm_status);
- kgsl_regread(device, REG_RBBM_STATUS, &rbbm_status);
+ {
+ struct log_field lines[] = {
+ {rbbm_status & BIT(0), "HI busy "},
+ {rbbm_status & BIT(1), "CP ME busy "},
+ {rbbm_status & BIT(2), "CP PFP busy "},
+ {rbbm_status & BIT(14), "CP NRT busy "},
+ {rbbm_status & BIT(15), "VBIF busy "},
+ {rbbm_status & BIT(16), "TSE busy "},
+ {rbbm_status & BIT(17), "RAS busy "},
+ {rbbm_status & BIT(18), "RB busy "},
+ {rbbm_status & BIT(19), "PC DCALL bsy"},
+ {rbbm_status & BIT(20), "PC VSD busy "},
+ {rbbm_status & BIT(21), "VFD busy "},
+ {rbbm_status & BIT(22), "VPC busy "},
+ {rbbm_status & BIT(23), "UCHE busy "},
+ {rbbm_status & BIT(24), "SP busy "},
+ {rbbm_status & BIT(25), "TPL1 busy "},
+ {rbbm_status & BIT(26), "MARB busy "},
+ {rbbm_status & BIT(27), "VSC busy "},
+ {rbbm_status & BIT(28), "ARB busy "},
+ {rbbm_status & BIT(29), "HLSQ busy "},
+ {rbbm_status & BIT(30), "GPU bsy noHC"},
+ {rbbm_status & BIT(31), "GPU busy "},
+ };
+ adreno_dump_fields(device, " STATUS=", lines,
+ ARRAY_SIZE(lines));
+ }
+
+ kgsl_regread(device, REG_CP_RB_BASE, &r1);
+ kgsl_regread(device, REG_CP_RB_CNTL, &r2);
+ rb_count = 2 << (r2 & (BIT(6) - 1));
+ kgsl_regread(device, REG_CP_RB_RPTR_ADDR, &r3);
+ KGSL_LOG_DUMP(device,
+ "CP_RB: BASE = %08X | CNTL = %08X | RPTR_ADDR = %08X"
+ "| rb_count = %08X\n", r1, r2, r3, rb_count);
+
+ kgsl_regread(device, REG_CP_RB_RPTR, &r1);
+ kgsl_regread(device, REG_CP_RB_WPTR, &r2);
+ kgsl_regread(device, REG_CP_RB_RPTR_WR, &r3);
+ KGSL_LOG_DUMP(device,
+ " RPTR = %08X | WPTR = %08X | RPTR_WR = %08X"
+ "\n", r1, r2, r3);
+
+ kgsl_regread(device, REG_CP_IB1_BASE, &r1);
+ kgsl_regread(device, REG_CP_IB1_BUFSZ, &r2);
+ KGSL_LOG_DUMP(device, "CP_IB1: BASE = %08X | BUFSZ = %d\n", r1, r2);
+
+ kgsl_regread(device, REG_CP_ME_CNTL, &r1);
+ kgsl_regread(device, REG_CP_ME_STATUS, &r2);
+ KGSL_LOG_DUMP(device, "CP_ME: CNTL = %08X | STATUS = %08X\n", r1, r2);
+
+ kgsl_regread(device, REG_CP_STAT, &cp_stat);
+ KGSL_LOG_DUMP(device, "CP_STAT = %08X\n", cp_stat);
+#ifndef CONFIG_MSM_KGSL_PSTMRTMDMP_CP_STAT_NO_DETAIL
+ {
+ struct log_field lns[] = {
+ {cp_stat & BIT(0), "WR_BSY 0"},
+ {cp_stat & BIT(1), "RD_RQ_BSY 1"},
+ {cp_stat & BIT(2), "RD_RTN_BSY 2"},
+ };
+ adreno_dump_fields(device, " MIU=", lns, ARRAY_SIZE(lns));
+ }
+ {
+ struct log_field lns[] = {
+ {cp_stat & BIT(5), "RING_BUSY 5"},
+ {cp_stat & BIT(6), "NDRCTS_BSY 6"},
+ {cp_stat & BIT(7), "NDRCT2_BSY 7"},
+ {cp_stat & BIT(9), "ST_BUSY 9"},
+ {cp_stat & BIT(10), "BUSY 10"},
+ };
+ adreno_dump_fields(device, " CSF=", lns, ARRAY_SIZE(lns));
+ }
+ {
+ struct log_field lns[] = {
+ {cp_stat & BIT(11), "RNG_Q_BSY 11"},
+ {cp_stat & BIT(12), "NDRCTS_Q_B12"},
+ {cp_stat & BIT(13), "NDRCT2_Q_B13"},
+ {cp_stat & BIT(16), "ST_QUEUE_B16"},
+ {cp_stat & BIT(17), "PFP_BUSY 17"},
+ };
+ adreno_dump_fields(device, " RING=", lns, ARRAY_SIZE(lns));
+ }
+ {
+ struct log_field lns[] = {
+ {cp_stat & BIT(3), "RBIU_BUSY 3"},
+ {cp_stat & BIT(4), "RCIU_BUSY 4"},
+ {cp_stat & BIT(8), "EVENT_BUSY 8"},
+ {cp_stat & BIT(18), "MQ_RG_BSY 18"},
+ {cp_stat & BIT(19), "MQ_NDRS_BS19"},
+ {cp_stat & BIT(20), "MQ_NDR2_BS20"},
+ {cp_stat & BIT(21), "MIU_WC_STL21"},
+ {cp_stat & BIT(22), "CP_NRT_BSY22"},
+ {cp_stat & BIT(23), "3D_BUSY 23"},
+ {cp_stat & BIT(26), "ME_BUSY 26"},
+ {cp_stat & BIT(27), "RB_FFO_BSY27"},
+ {cp_stat & BIT(28), "CF_FFO_BSY28"},
+ {cp_stat & BIT(29), "PS_FFO_BSY29"},
+ {cp_stat & BIT(30), "VS_FFO_BSY30"},
+ {cp_stat & BIT(31), "CP_BUSY 31"},
+ };
+ adreno_dump_fields(device, " CP_STT=", lns, ARRAY_SIZE(lns));
+ }
+#endif
+
+ kgsl_regread(device, A3XX_RBBM_INT_0_STATUS, &r1);
+ KGSL_LOG_DUMP(device, "MSTR_INT_SGNL = %08X\n", r1);
+ {
+ struct log_field ints[] = {
+ {r1 & BIT(0), "RBBM_GPU_IDLE 0"},
+ {r1 & BIT(1), "RBBM_AHB_ERROR 1"},
+ {r1 & BIT(2), "RBBM_REG_TIMEOUT 2"},
+ {r1 & BIT(3), "RBBM_ME_MS_TIMEOUT 3"},
+ {r1 & BIT(4), "RBBM_PFP_MS_TIMEOUT 4"},
+ {r1 & BIT(5), "RBBM_ATB_BUS_OVERFLOW 5"},
+ {r1 & BIT(6), "VFD_ERROR 6"},
+ {r1 & BIT(7), "CP_SW_INT 7"},
+ {r1 & BIT(8), "CP_T0_PACKET_IN_IB 8"},
+ {r1 & BIT(9), "CP_OPCODE_ERROR 9"},
+ {r1 & BIT(10), "CP_RESERVED_BIT_ERROR 10"},
+ {r1 & BIT(11), "CP_HW_FAULT 11"},
+ {r1 & BIT(12), "CP_DMA 12"},
+ {r1 & BIT(13), "CP_IB2_INT 13"},
+ {r1 & BIT(14), "CP_IB1_INT 14"},
+ {r1 & BIT(15), "CP_RB_INT 15"},
+ {r1 & BIT(16), "CP_REG_PROTECT_FAULT 16"},
+ {r1 & BIT(17), "CP_RB_DONE_TS 17"},
+ {r1 & BIT(18), "CP_VS_DONE_TS 18"},
+ {r1 & BIT(19), "CP_PS_DONE_TS 19"},
+ {r1 & BIT(20), "CACHE_FLUSH_TS 20"},
+ {r1 & BIT(21), "CP_AHB_ERROR_HALT 21"},
+ {r1 & BIT(24), "MISC_HANG_DETECT 24"},
+ {r1 & BIT(25), "UCHE_OOB_ACCESS 25"},
+ };
+ adreno_dump_fields(device, "INT_SGNL=", ints, ARRAY_SIZE(ints));
+ }
+}
+
+static void adreno_dump_a2xx(struct kgsl_device *device)
+{
+ unsigned int r1, r2, r3, rbbm_status;
+ unsigned int cp_stat, rb_count;
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+
+ kgsl_regread(device, adreno_dev->gpudev->reg_rbbm_status, &rbbm_status);
+
kgsl_regread(device, REG_RBBM_PM_OVERRIDE1, &r2);
kgsl_regread(device, REG_RBBM_PM_OVERRIDE2, &r3);
KGSL_LOG_DUMP(device, "RBBM: STATUS = %08X | PM_OVERRIDE1 = %08X | "
@@ -426,37 +558,33 @@
ARRAY_SIZE(lines));
}
- kgsl_regread(device, REG_CP_RB_BASE, &cp_rb_base);
+ kgsl_regread(device, REG_CP_RB_BASE, &r1);
kgsl_regread(device, REG_CP_RB_CNTL, &r2);
rb_count = 2 << (r2 & (BIT(6)-1));
kgsl_regread(device, REG_CP_RB_RPTR_ADDR, &r3);
KGSL_LOG_DUMP(device,
"CP_RB: BASE = %08X | CNTL = %08X | RPTR_ADDR = %08X"
- " | rb_count = %08X\n", cp_rb_base, r2, r3, rb_count);
+ "| rb_count = %08X\n", r1, r2, r3, rb_count);
{
struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
if (rb->sizedwords != rb_count)
rb_count = rb->sizedwords;
}
- kgsl_regread(device, REG_CP_RB_RPTR, &cp_rb_rptr);
- kgsl_regread(device, REG_CP_RB_WPTR, &cp_rb_wptr);
+ kgsl_regread(device, REG_CP_RB_RPTR, &r1);
+ kgsl_regread(device, REG_CP_RB_WPTR, &r2);
kgsl_regread(device, REG_CP_RB_RPTR_WR, &r3);
KGSL_LOG_DUMP(device,
" RPTR = %08X | WPTR = %08X | RPTR_WR = %08X"
- "\n", cp_rb_rptr, cp_rb_wptr, r3);
+ "\n", r1, r2, r3);
- kgsl_regread(device, REG_CP_IB1_BASE, &cp_ib1_base);
- kgsl_regread(device, REG_CP_IB1_BUFSZ, &cp_ib1_bufsz);
- KGSL_LOG_DUMP(device,
- "CP_IB1: BASE = %08X | BUFSZ = %d\n", cp_ib1_base,
- cp_ib1_bufsz);
+ kgsl_regread(device, REG_CP_IB1_BASE, &r1);
+ kgsl_regread(device, REG_CP_IB1_BUFSZ, &r2);
+ KGSL_LOG_DUMP(device, "CP_IB1: BASE = %08X | BUFSZ = %d\n", r1, r2);
- kgsl_regread(device, REG_CP_IB2_BASE, &cp_ib2_base);
- kgsl_regread(device, REG_CP_IB2_BUFSZ, &cp_ib2_bufsz);
- KGSL_LOG_DUMP(device,
- "CP_IB2: BASE = %08X | BUFSZ = %d\n", cp_ib2_base,
- cp_ib2_bufsz);
+ kgsl_regread(device, REG_CP_IB2_BASE, &r1);
+ kgsl_regread(device, REG_CP_IB2_BUFSZ, &r2);
+ KGSL_LOG_DUMP(device, "CP_IB2: BASE = %08X | BUFSZ = %d\n", r1, r2);
kgsl_regread(device, REG_CP_INT_CNTL, &r1);
kgsl_regread(device, REG_CP_INT_STATUS, &r2);
@@ -541,11 +669,10 @@
kgsl_regread(device, MH_MMU_MPU_END, &r1);
kgsl_regread(device, MH_MMU_VA_RANGE, &r2);
- pt_base = kgsl_mmu_get_current_ptbase(device);
+ r3 = kgsl_mmu_get_current_ptbase(device);
KGSL_LOG_DUMP(device,
" MPU_END = %08X | VA_RANGE = %08X | PT_BASE ="
- " %08X\n", r1, r2, pt_base);
- cur_pt_base = pt_base;
+ " %08X\n", r1, r2, r3);
KGSL_LOG_DUMP(device, "PAGETABLE SIZE: %08X ", KGSL_PAGETABLE_SIZE);
@@ -556,6 +683,46 @@
kgsl_regread(device, MH_INTERRUPT_STATUS, &r2);
KGSL_LOG_DUMP(device,
"MH_INTERRUPT: MASK = %08X | STATUS = %08X\n", r1, r2);
+}
+
+static int adreno_dump(struct kgsl_device *device)
+{
+ unsigned int cp_ib1_base, cp_ib1_bufsz;
+ unsigned int cp_ib2_base, cp_ib2_bufsz;
+ unsigned int pt_base, cur_pt_base;
+ unsigned int cp_rb_base, cp_rb_ctrl, rb_count;
+ unsigned int cp_rb_wptr, cp_rb_rptr;
+ unsigned int i;
+ int result = 0;
+ uint32_t *rb_copy;
+ const uint32_t *rb_vaddr;
+ int num_item = 0;
+ int read_idx, write_idx;
+ unsigned int ts_processed;
+
+ static struct ib_list ib_list;
+
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+
+ mb();
+
+ if (adreno_is_a2xx(adreno_dev))
+ adreno_dump_a2xx(device);
+ else if (adreno_is_a3xx(adreno_dev))
+ adreno_dump_a3xx(device);
+
+ pt_base = kgsl_mmu_get_current_ptbase(device);
+ cur_pt_base = pt_base;
+
+ kgsl_regread(device, REG_CP_RB_BASE, &cp_rb_base);
+ kgsl_regread(device, REG_CP_RB_CNTL, &cp_rb_ctrl);
+ rb_count = 2 << (cp_rb_ctrl & (BIT(6) - 1));
+ kgsl_regread(device, REG_CP_RB_RPTR, &cp_rb_rptr);
+ kgsl_regread(device, REG_CP_RB_WPTR, &cp_rb_wptr);
+ kgsl_regread(device, REG_CP_IB1_BASE, &cp_ib1_base);
+ kgsl_regread(device, REG_CP_IB1_BUFSZ, &cp_ib1_bufsz);
+ kgsl_regread(device, REG_CP_IB2_BASE, &cp_ib2_base);
+ kgsl_regread(device, REG_CP_IB2_BUFSZ, &cp_ib2_bufsz);
ts_processed = device->ftbl->readtimestamp(device,
KGSL_TIMESTAMP_RETIRED);
@@ -689,6 +856,9 @@
else if (adreno_is_a22x(adreno_dev))
adreno_dump_regs(device, a220_registers,
a220_registers_count);
+ else if (adreno_is_a3xx(adreno_dev))
+ adreno_dump_regs(device, a3xx_registers,
+ a3xx_registers_count);
error_vfree:
vfree(rb_copy);
diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c
index 72df148b..de39ee4 100644
--- a/drivers/gpu/msm/kgsl_snapshot.c
+++ b/drivers/gpu/msm/kgsl_snapshot.c
@@ -139,7 +139,7 @@
* register
*/
-int kgsl_snapshot_dump_indexed_regs(struct kgsl_device *device,
+static int kgsl_snapshot_dump_indexed_regs(struct kgsl_device *device,
void *snapshot, int remain, void *priv)
{
struct kgsl_snapshot_indexed_registers *iregs = priv;
@@ -164,7 +164,6 @@
return (iregs->count * 4) + sizeof(*header);
}
-EXPORT_SYMBOL(kgsl_snapshot_dump_indexed_regs);
/*
* kgsl_snapshot_dump_regs - helper function to dump device registers
@@ -220,6 +219,23 @@
}
EXPORT_SYMBOL(kgsl_snapshot_dump_regs);
+void *kgsl_snapshot_indexed_registers(struct kgsl_device *device,
+ void *snapshot, int *remain,
+ unsigned int index, unsigned int data, unsigned int start,
+ unsigned int count)
+{
+ struct kgsl_snapshot_indexed_registers iregs;
+ iregs.index = index;
+ iregs.data = data;
+ iregs.start = start;
+ iregs.count = count;
+
+ return kgsl_snapshot_add_section(device,
+ KGSL_SNAPSHOT_SECTION_INDEXED_REGS, snapshot,
+ remain, kgsl_snapshot_dump_indexed_regs, &iregs);
+}
+EXPORT_SYMBOL(kgsl_snapshot_indexed_registers);
+
/*
* kgsl_snapshot - construct a device snapshot
* @device - device to snapshot
diff --git a/drivers/gpu/msm/kgsl_snapshot.h b/drivers/gpu/msm/kgsl_snapshot.h
index 4fdc8a1..3b72b0f 100644
--- a/drivers/gpu/msm/kgsl_snapshot.h
+++ b/drivers/gpu/msm/kgsl_snapshot.h
@@ -47,6 +47,7 @@
#define KGSL_SNAPSHOT_SECTION_INDEXED_REGS 0x0501
#define KGSL_SNAPSHOT_SECTION_ISTORE 0x0801
#define KGSL_SNAPSHOT_SECTION_DEBUG 0x0901
+#define KGSL_SNAPSHOT_SECTION_DEBUGBUS 0x0A01
#define KGSL_SNAPSHOT_SECTION_END 0xFFFF
/* OS sub-section header */
@@ -124,15 +125,28 @@
/* Debug data sub-section header */
+/* A2XX debug sections */
#define SNAPSHOT_DEBUG_SX 1
#define SNAPSHOT_DEBUG_CP 2
#define SNAPSHOT_DEBUG_SQ 3
#define SNAPSHOT_DEBUG_SQTHREAD 4
#define SNAPSHOT_DEBUG_MIU 5
+/* A3XX debug sections */
+#define SNAPSHOT_DEBUG_VPC_MEMORY 6
+#define SNAPSHOT_DEBUG_CP_MEQ 7
+#define SNAPSHOT_DEBUG_CP_PM4_RAM 8
+#define SNAPSHOT_DEBUG_CP_PFP_RAM 9
+#define SNAPSHOT_DEBUG_CP_ROQ 10
+
struct kgsl_snapshot_debug {
int type; /* Type identifier for the attached tata */
- int size; /* Size of the section in bytes */
+ int size; /* Size of the section in dwords */
+} __packed;
+
+struct kgsl_snapshot_debugbus {
+ int id; /* Debug bus ID */
+ int count; /* Number of dwords in the dump */
} __packed;
#ifdef __KERNEL__
@@ -252,8 +266,12 @@
unsigned int count; /* Number of values to read from the pair */
};
-int kgsl_snapshot_dump_indexed_regs(struct kgsl_device *device,
- void *snapshot, int remain, void *priv);
+/* Helper function to snapshot a section of indexed registers */
+
+void *kgsl_snapshot_indexed_registers(struct kgsl_device *device,
+ void *snapshot, int *remain, unsigned int index,
+ unsigned int data, unsigned int start, unsigned int count);
+
#endif
#endif