Skip to content

Commit 993913c

Browse files
committed
Add support for TI AM625 and AM62A arm64 SoCs
- TI AM625: https://www.ti.com/lit/pdf/spruiv7 - TI AM62a: https://www.ti.com/lit/pdf/spruj16 - fixes #12
1 parent d499e95 commit 993913c

File tree

4 files changed

+114
-2
lines changed

4 files changed

+114
-2
lines changed

src/Makefile.am

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
AM_CFLAGS = -std=c99 -pedantic -W -Wall -Wextra -Wno-unused-parameter -Wshadow
22

33
sbin_PROGRAMS = bootcount
4-
bootcount_SOURCES = bootcount.c am33xx.c stm32mp1.c i2c_eeprom.c memory.c \
5-
dt.c imx8m.c imx93.c
4+
bootcount_SOURCES = bootcount.c dt.c memory.c \
5+
am33xx.c am62x.c \
6+
stm32mp1.c \
7+
i2c_eeprom.c\
8+
imx8m.c imx93.c
69

src/am62x.c

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/**
2+
* Access and reset u-boot's "bootcount" counter for the TI AM625 and AM62A SoCs
3+
* which is stored in the RTC_SCRATCH2_REG.
4+
*
5+
* see:
6+
* - AM625 TRM: https://www.ti.com/lit/pdf/spruiv7
7+
* Section 12.7.3.3.4 Scratch Registers
8+
* Section 14.8.7.3.12.1 RTC_RTC_SCRATCH0_N Register
9+
*
10+
* - AM62ax TRM: https://www.ti.com/lit/pdf/spruj16
11+
* Section 12.8.3.3.4 Scratch Registers
12+
* Section 14.9.7.3.12.1 RTC_RTC_SCRATCH0_N Register
13+
*/
14+
15+
#include <stdlib.h>
16+
#include <stdint.h>
17+
#include <stdio.h>
18+
#include <string.h>
19+
20+
#include "./constants.h"
21+
#include "./memory.h"
22+
#include "./dt.h"
23+
#include "./am62x.h"
24+
25+
// spruiv7.pdf Section 14.8.7.3.12 RTC_RTC_RTC_SCRATCH0_N Register
26+
// spruj16.pdf Section 14.9.7.3.12 RTC_RTC_RTC_SCRATCH0_N Register
27+
#define AM62_RTCSS 0x2B1F0000ul
28+
#define AM62_SCRATCH2_REG_OFFSET (0x30ul * 2)
29+
#define AM62_REG_SIZE 4ul // registers are 4 bytes/ 32bit
30+
31+
// spruiv7.pdf Section 14.8.7.3.19 RTC_RTC_RTC_KICK0 Registers
32+
// spruj16.pdf Section 14.9.7.3.19 RTC_RTC_RTC_KICK0 Registers
33+
#define AM62_KICK0R_REG_OFFSET 0x70ul
34+
#define AM62_KICK1R_REG_OFFSET 0x74ul
35+
#define AM62_KICK0_MAGIC 0x83e70b13ul
36+
#define AM62_KICK1_MAGIC 0x95a4f1e0ul
37+
38+
#define AM62_MEM_OFFSET (AM62_RTCSS + AM62_SCRATCH2_REG_OFFSET)
39+
// We need to map the RTCSS block from SCRATCH2 up to the end of KICK1R:
40+
#define AM62_MEM_LEN (AM62_KICK1R_REG_OFFSET + AM62_REG_SIZE - AM62_SCRATCH2_REG_OFFSET)
41+
42+
bool is_am62() {
43+
return is_compatible_soc("ti,am625") || is_compatible_soc("ti,am62a7");
44+
}
45+
46+
int am62_read_bootcount(uint16_t* val) {
47+
48+
uint32_t *scratch2_addr = memory_open(AM62_MEM_OFFSET, AM62_MEM_LEN);
49+
if ( scratch2_addr == (void *)E_DEVICE ) {
50+
return E_DEVICE;
51+
}
52+
53+
uint32_t scratch2_val = memory_read(scratch2_addr);
54+
// low two bytes are the value, high two bytes are magic
55+
if ((scratch2_val & 0xffff0000) != (BOOTCOUNT_MAGIC & 0xffff0000)) {
56+
return E_BADMAGIC;
57+
}
58+
59+
*val = (uint16_t)(scratch2_val & 0x0000ffff);
60+
return 0;
61+
}
62+
63+
64+
int am62_write_bootcount(uint16_t val) {
65+
// NOTE: These must be volatile.
66+
// See https://github.com/brgl/busybox/blob/master/miscutils/devmem.c
67+
volatile uint32_t *scratch2_addr =
68+
(volatile uint32_t *)memory_open(AM62_MEM_OFFSET, AM62_MEM_LEN);
69+
if ( scratch2_addr == (void *)E_DEVICE ) {
70+
return E_DEVICE;
71+
}
72+
73+
volatile uint32_t *kick0r = scratch2_addr + (AM62_KICK0R_REG_OFFSET - AM62_SCRATCH2_REG_OFFSET) / 4;
74+
volatile uint32_t *kick1r = kick0r + 1; // (AM62_KICK1R_REG_OFFSET - AM62_SCRATCH2_REG_OFFSET) / 4;
75+
76+
// Disable write protection, then write to SCRATCH2
77+
*kick0r = AM62_KICK0_MAGIC;
78+
*kick1r = AM62_KICK1_MAGIC;
79+
uint32_t scratch2_val = (BOOTCOUNT_MAGIC & 0xffff0000) | (val & 0xffff);
80+
memory_write(scratch2_addr, scratch2_val);
81+
82+
// re-lock the write protection register
83+
*kick1r = 0;
84+
85+
// read back to verify:
86+
uint16_t read_val = 0;
87+
am33_read_bootcount(&read_val);
88+
if ( read_val != val ) {
89+
return E_WRITE_FAILED;
90+
}
91+
92+
93+
return 0;
94+
}

src/am62x.h

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# pragma once
2+
3+
#include <stdbool.h>
4+
5+
#define AM62_PLAT_NAME "TI AM62x"
6+
7+
bool is_am62();
8+
int am62_read_bootcount(uint16_t* val);
9+
int am62_write_bootcount(uint16_t val);

src/bootcount.c

+6
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "constants.h"
3131
#include "dt.h"
3232
#include "am33xx.h"
33+
#include "am62x.h"
3334
#include "imx8m.h"
3435
#include "imx93.h"
3536
#include "stm32mp1.h"
@@ -50,6 +51,11 @@ static const struct platform platforms[] = {
5051
.read_bootcount = am33_read_bootcount,
5152
.write_bootcount = am33_write_bootcount
5253
},
54+
{.name = AM62_PLAT_NAME,
55+
.detect = is_am62,
56+
.read_bootcount = am62_read_bootcount,
57+
.write_bootcount = am62_write_bootcount
58+
},
5359
{.name = IMX8M_PLAT_NAME,
5460
.detect = is_imx8m,
5561
.read_bootcount = imx8m_read_bootcount,

0 commit comments

Comments
 (0)