aboutsummaryrefslogtreecommitdiff
path: root/board/keymile/common
diff options
context:
space:
mode:
authorAleksandar Gerasimovski2021-11-16 12:53:28 +0000
committerPriyanka Jain2022-02-01 15:08:07 +0530
commitde144d5ffe0c15c56e3bbd64832bc4b265bd663f (patch)
tree8794afa83661dcc408457fad6e2d6171d3b8dd03 /board/keymile/common
parent70003e52f4ed9b22a75ac4d084ceee65d9b14ea1 (diff)
km: qrio: add access functions for ebootcount
The EBOOTCNT is a reserved persistent static memory area in QRIO, and similar to BOOTCNT is intended to be used as boot counter location. Comparable to BOOTCNT that is reserved for u-boot main bootcount infrastructure, EBOOTCNT is intended to be used for pg-wcom board specific purposes (e.g implementing early boot counter for fail-safe u-boot update). Signed-off-by: Aleksandar Gerasimovski <aleksandar.gerasimovski@hitachienergy.com> Reviewed-by: Priyanka Jain <priyanka.jain@nxp.com>
Diffstat (limited to 'board/keymile/common')
-rw-r--r--board/keymile/common/common.h3
-rw-r--r--board/keymile/common/qrio.c38
2 files changed, 41 insertions, 0 deletions
diff --git a/board/keymile/common/common.h b/board/keymile/common/common.h
index 15a3c3797d1..fc14728f9b5 100644
--- a/board/keymile/common/common.h
+++ b/board/keymile/common/common.h
@@ -133,6 +133,9 @@ int get_testpin(void);
int set_km_env(void);
+ulong early_bootcount_load(void);
+void early_bootcount_store(ulong ebootcount);
+
#define DELAY_ABORT_SEQ 62 /* @200kHz 9 clocks = 44us, 62us is ok */
#define DELAY_HALF_PERIOD (500 / (CONFIG_SYS_I2C_SPEED / 1000))
diff --git a/board/keymile/common/qrio.c b/board/keymile/common/qrio.c
index 89a9726a1fc..5401bddf06a 100644
--- a/board/keymile/common/qrio.c
+++ b/board/keymile/common/qrio.c
@@ -270,6 +270,44 @@ void qrio_uprstreq(u8 mode)
out_8(qrio_base + RSTCFG_OFF, rstcfg);
}
+/* Early bootcount memory area is avilable starting from QRIO3 Rev.2 */
+#define QRIO3_ID 0x71
+#define QRIO3_REV 0x02
+#define EBOOTCNT_OFF 0x28
+
+ulong early_bootcount_load(void)
+{
+ void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
+ u16 id_rev = in_be16(qrio_base + ID_REV_OFF);
+ u8 id = (id_rev >> 8) & 0xff;
+ u8 rev = id_rev & 0xff;
+ u32 ebootcount = 0;
+
+ if (id == QRIO3_ID && rev >= QRIO3_REV) {
+ ebootcount = in_be32(qrio_base + EBOOTCNT_OFF);
+ } else {
+ printf("QRIO: warning: early bootcount not supported, ");
+ printf("id = %u, rev = %u\n", id, rev);
+ }
+
+ return ebootcount;
+}
+
+void early_bootcount_store(ulong ebootcount)
+{
+ void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
+ u16 id_rev = in_be16(qrio_base + ID_REV_OFF);
+ u8 id = (id_rev >> 8) & 0xff;
+ u8 rev = id_rev & 0xff;
+
+ if (id == QRIO3_ID && rev >= QRIO3_REV) {
+ out_be32(qrio_base + EBOOTCNT_OFF, ebootcount);
+ } else {
+ printf("QRIO: warning: early bootcount not supported, ");
+ printf("id = %u, rev = %u\n", id, rev);
+ }
+}
+
/* I2C deblocking uses the algorithm defined in board/keymile/common/common.c
* 2 dedicated QRIO GPIOs externally pull the SCL and SDA lines
* For I2C only the low state is activly driven and high state is pulled-up