Merge "jtagmm: Add save-restore support for v7.1 Debug registers"
diff --git a/arch/arm/mach-msm/jtag-mm.c b/arch/arm/mach-msm/jtag-mm.c
index fae2b96..7689b66 100644
--- a/arch/arm/mach-msm/jtag-mm.c
+++ b/arch/arm/mach-msm/jtag-mm.c
@@ -124,6 +124,8 @@
#define DBGBCRn(n) (0x140 + (n * 4))
#define DBGWVRn(n) (0x180 + (n * 4))
#define DBGWCRn(n) (0x1C0 + (n * 4))
+#define DBGOSLAR (0x300)
+#define DBGOSLSR (0x304)
#define DBGPRCR (0x310)
#define DBGITMISCOUT (0xEF8)
#define DBGITMISCIN (0xEFC)
@@ -141,6 +143,7 @@
#define ARCH_V3_5 (0x25)
#define ARM_DEBUG_ARCH_V7B (0x3)
+#define ARM_DEBUG_ARCH_V7p1 (0x5)
#define etm_write(etm, val, off) \
__raw_writel(val, etm->base + off)
@@ -457,22 +460,46 @@
i = 0;
DBG_UNLOCK(dbgdata);
- dbgdata->state[i++] = dbg_read(dbgdata, DBGWFAR);
- dbgdata->state[i++] = dbg_read(dbgdata, DBGVCR);
- for (j = 0; j < dbg.nr_bp; j++) {
- dbgdata->state[i++] = dbg_read(dbgdata, DBGBVRn(j));
- dbgdata->state[i++] = dbg_read(dbgdata, DBGBCRn(j));
+ switch (dbg.arch) {
+ case ARM_DEBUG_ARCH_V7B:
+ dbgdata->state[i++] = dbg_read(dbgdata, DBGWFAR);
+ dbgdata->state[i++] = dbg_read(dbgdata, DBGVCR);
+ for (j = 0; j < dbg.nr_bp; j++) {
+ dbgdata->state[i++] = dbg_read(dbgdata, DBGBVRn(j));
+ dbgdata->state[i++] = dbg_read(dbgdata, DBGBCRn(j));
+ }
+ for (j = 0; j < dbg.nr_wp; j++) {
+ dbgdata->state[i++] = dbg_read(dbgdata, DBGWVRn(j));
+ dbgdata->state[i++] = dbg_read(dbgdata, DBGWCRn(j));
+ }
+ dbgdata->state[i++] = dbg_read(dbgdata, DBGPRCR);
+ dbgdata->state[i++] = dbg_read(dbgdata, DBGDTRTXext);
+ dbgdata->state[i++] = dbg_read(dbgdata, DBGDTRRXext);
+ dbgdata->state[i++] = dbg_read(dbgdata, DBGDSCRext);
+ break;
+ case ARM_DEBUG_ARCH_V7p1:
+ /* Set OS Lock */
+ dbg_write(dbgdata, OSLOCK_MAGIC, DBGOSLAR);
+ /* Ensure OS lock is set before proceeding */
+ mb();
+
+ dbgdata->state[i++] = dbg_read(dbgdata, DBGWFAR);
+ dbgdata->state[i++] = dbg_read(dbgdata, DBGVCR);
+ for (j = 0; j < dbg.nr_bp; j++) {
+ dbgdata->state[i++] = dbg_read(dbgdata, DBGBVRn(j));
+ dbgdata->state[i++] = dbg_read(dbgdata, DBGBCRn(j));
+ }
+ for (j = 0; j < dbg.nr_wp; j++) {
+ dbgdata->state[i++] = dbg_read(dbgdata, DBGWVRn(j));
+ dbgdata->state[i++] = dbg_read(dbgdata, DBGWCRn(j));
+ }
+ dbgdata->state[i++] = dbg_read(dbgdata, DBGPRCR);
+ dbgdata->state[i++] = dbg_read(dbgdata, DBGCLAIMCLR);
+ dbgdata->state[i++] = dbg_read(dbgdata, DBGDTRTXext);
+ dbgdata->state[i++] = dbg_read(dbgdata, DBGDTRRXext);
+ dbgdata->state[i++] = dbg_read(dbgdata, DBGDSCRext);
+ break;
}
- for (j = 0; j < dbg.nr_wp; j++) {
- dbgdata->state[i++] = dbg_read(dbgdata, DBGWVRn(j));
- dbgdata->state[i++] = dbg_read(dbgdata, DBGWCRn(j));
- }
- dbgdata->state[i++] = dbg_read(dbgdata, DBGPRCR);
- dbgdata->state[i++] = dbg_read(dbgdata, DBGCLAIMSET);
- dbgdata->state[i++] = dbg_read(dbgdata, DBGCLAIMCLR);
- dbgdata->state[i++] = dbg_read(dbgdata, DBGDTRTXext);
- dbgdata->state[i++] = dbg_read(dbgdata, DBGDTRRXext);
- dbgdata->state[i++] = dbg_read(dbgdata, DBGDSCRext);
DBG_LOCK(dbgdata);
}
@@ -484,23 +511,55 @@
i = 0;
DBG_UNLOCK(dbgdata);
- dbg_write(dbgdata, dbgdata->state[i++], DBGWFAR);
- dbg_write(dbgdata, dbgdata->state[i++], DBGVCR);
- for (j = 0; j < dbg.nr_bp; j++) {
- dbg_write(dbgdata, dbgdata->state[i++], DBGBVRn(j));
- dbg_write(dbgdata, dbgdata->state[i++], DBGBCRn(j));
- }
- for (j = 0; j < dbg.nr_wp; j++) {
- dbg_write(dbgdata, dbgdata->state[i++], DBGWVRn(j));
- dbg_write(dbgdata, dbgdata->state[i++], DBGWCRn(j));
- }
- dbg_write(dbgdata, dbgdata->state[i++], DBGPRCR);
- dbg_write(dbgdata, dbgdata->state[i++], DBGCLAIMSET);
- dbg_write(dbgdata, dbgdata->state[i++], DBGCLAIMCLR);
- dbg_write(dbgdata, dbgdata->state[i++], DBGDTRTXext);
- dbg_write(dbgdata, dbgdata->state[i++], DBGDTRRXext);
- dbg_write(dbgdata, dbgdata->state[i++] & DBGDSCR_MASK,
+ switch (dbg.arch) {
+ case ARM_DEBUG_ARCH_V7B:
+ dbg_write(dbgdata, dbgdata->state[i++], DBGWFAR);
+ dbg_write(dbgdata, dbgdata->state[i++], DBGVCR);
+ for (j = 0; j < dbg.nr_bp; j++) {
+ dbg_write(dbgdata, dbgdata->state[i++], DBGBVRn(j));
+ dbg_write(dbgdata, dbgdata->state[i++], DBGBCRn(j));
+ }
+ for (j = 0; j < dbg.nr_wp; j++) {
+ dbg_write(dbgdata, dbgdata->state[i++], DBGWVRn(j));
+ dbg_write(dbgdata, dbgdata->state[i++], DBGWCRn(j));
+ }
+ dbg_write(dbgdata, dbgdata->state[i++], DBGPRCR);
+ dbg_write(dbgdata, dbgdata->state[i++], DBGDTRTXext);
+ dbg_write(dbgdata, dbgdata->state[i++], DBGDTRRXext);
+ dbg_write(dbgdata, dbgdata->state[i++] & DBGDSCR_MASK,
DBGDSCRext);
+ break;
+ case ARM_DEBUG_ARCH_V7p1:
+ /* Set OS lock. Lock will already be set after power collapse
+ * but this write is included to ensure it is set.
+ */
+ dbg_write(dbgdata, OSLOCK_MAGIC, DBGOSLAR);
+ /* Ensure OS lock is set before proceeding */
+ mb();
+
+ dbg_write(dbgdata, dbgdata->state[i++], DBGWFAR);
+ dbg_write(dbgdata, dbgdata->state[i++], DBGVCR);
+ for (j = 0; j < dbg.nr_bp; j++) {
+ dbg_write(dbgdata, dbgdata->state[i++], DBGBVRn(j));
+ dbg_write(dbgdata, dbgdata->state[i++], DBGBCRn(j));
+ }
+ for (j = 0; j < dbg.nr_wp; j++) {
+ dbg_write(dbgdata, dbgdata->state[i++], DBGWVRn(j));
+ dbg_write(dbgdata, dbgdata->state[i++], DBGWCRn(j));
+ }
+ dbg_write(dbgdata, dbgdata->state[i++], DBGPRCR);
+ dbg_write(dbgdata, dbgdata->state[i++], DBGCLAIMSET);
+ dbg_write(dbgdata, dbgdata->state[i++], DBGDTRTXext);
+ dbg_write(dbgdata, dbgdata->state[i++], DBGDTRRXext);
+ dbg_write(dbgdata, dbgdata->state[i++] & DBGDSCR_MASK,
+ DBGDSCRext);
+ /* Ensure all writes are completing before clearing OS lock */
+ mb();
+ dbg_write(dbgdata, 0x0, DBGOSLAR);
+ /* Ensure OS lock is cleared before proceeding */
+ mb();
+ break;
+ }
DBG_LOCK(dbgdata);
}
@@ -657,6 +716,7 @@
{
switch (arch) {
case ARM_DEBUG_ARCH_V7B:
+ case ARM_DEBUG_ARCH_V7p1:
break;
default:
return false;