Rockchip does not publish documentation about the contents of the (PMU)SGRF register block in the RK3399. This document attempts to compile what is known through various documents, code drops and experiments.
Unless otherwise noted, SGRF registers are 16 bits wide and are accessed with 32-bit accesses (and 4-byte alignment), where the upper half is a write mask. Registers are identified by their offset, e. g. :reg:`R0x1C` would refer to the 8th register in the block. Bit ranges such as :reg:`R0x40[10:13]` are inclusive. Bit positions are counted from 0, the least significant bit.
(Mostly taken from TF-A comments and code)
Security state of the DRAM range (0–0xf7ffffff, inclusive) can be controlled in up to 8 regions (+ a 'remainder' region). (n ranges from 0 to 7, inclusive)
:reg:`R0x0+4*n` contains the offset in MiB of region n start. :reg:`R0x20+4*n` contains the offset in MiB of region n end, inclusive.
The range of region n is then :reg:`R0x0+4*n` << 20 to :reg:`R0x20+8*n` << 20 | 0xfffff.
What happens if :reg:`R0x4+8*n` < :reg:`R0x0+8*n` is currently unknown. If two regions overlap, the first seems to take priority (as seen by the reset state).
The security state of region n is set in :reg:`R+40[n]`; 1 means Secure. The security state of the remaining address space is set in :reg:`R+40[8]`. Setting :reg:`R+40[9]`=1 marks all DRAM as Non-Secure.
The reset state is :reg:`R0x0+4*n` = 0, :reg:`R0x20+4*n` = 0xfff, :reg:`R0x40` = 1, so all regions map the entire range and the first one is set secure. Since the latter is what takes effect, it seems earlier regions take priority over later ones.
The meaning (if any) of :reg:`R0x40[10:13]` is unknown. They seem to be reset at system reset.
:reg:`R0x40[14:15]` control something about memory controller clocks and have to be set to make the system not hang. According to TF-A comments, this is due to an 'IC ECO' bug (whatever that means).
The meaning of :reg:`R0x44` to :reg:`R0x88` is unknown. :reg:`R0x44` and :reg:`R0x48` read all-zeroes, the remaining 16 registers read 0xffff at boot. (probably per-region access for each master)
According to U-Boot sources, :reg:`R0x8C` to :reg:`R0x7FFC` are reserved, i. e. meaningless. They read all-zeroes at boot.
According to U-Boot sources, the SOC_CON registers are layed out consecutively … if you only look at the lower 7 bits of address. The upper bits vary for whatever reason (probably different power domains or physical SoC regions). From what can be gathered, an offset x would belong to SOC_CON(x >> 4 & 31) if (x & 0x8f83) == 0x8000.:
SOC_CON0 and SOC_CON1 are :reg:`R+C000` and :reg:`R+C004` respectively. SOC_CON0[3:6] apparently hold flags for Secure World access to the Cortex-A53s (probably one bit per core). SOC_CON0[13] is jtag_rstreqn for the PERILPM0, which "Always be 0" according to the TRM. SOC_CON0[14] is an enable bit for the PERILPM0 SYSRESETREQ. SOC_CON1 holds the upper 16 bits of the reset address for the main cores.
SOC_CON2 does not seem to exist (all spaces where it could be are reserved in the U-Boot struct definition).:
SOC_CON3 to SOC_CON7 are :reg:`R+E00C` to :reg:`R+E01C`. SOC_CON3[7] might be the 0xffffxxxx remap setting (the TRM contradicts itself whether it's this or PMU_CON0[15]). SOC_CON3[8] is a clock gate for the secure watchdog timer bus clock for the Cortex-A53. SOC_CON3[10] is a clock gate for the secure watchdog timer bus clock for the Cortex-M0 (which one is not known). SOC_CON4[0:9] is the amount of (non-PMU) SRAM which is in the Secure World (starting from the 'bottom' according to the TRM, probably they mean the beginning at 0xff8c0000), in 4KiB steps. SOC_CON4[10:15] is the DRAM channel interleaving setting ("stride", TODO values). SOC_CON5 to SOC_CON7 (according to TF-A code) seem to be bitmaps of bus master Security states (1 is Non-Secure), with SOC_CON6[12] being PERILPM0.
SOC_CON8 to SOC_CON15 are :reg:`R+8020` to :reg:`R+803C`.
CON8[4:15]: DMAC0 event/IRQ Security State bits (1 is Non-Secure, reset 0xfff) CON8[3]: DMAC0 manager thread Security state (1 is Non-Secure, reset 1) CON8[2]: DMAC0 manager thread state after reset (1=running, 0=halt, reset 0) CON8[0:1]: unknown but preserved by hardware, reset 0b01 CON9[12:15]: DMAC0 boot_addr[12:15] CON9[0:11]: DMAC0 peripheral Security State bits (1 is Non-Secure, reset 0xfff) CON10: DMAC0 boot_addr[16:31] CON11[3]: DMAC1 manager thread Security state (1 is Non-Secure, reset 1) CON11[2]: DMAC1 manager thread state after reset (1=running, 0=halt, reset 0) CON11[0:1]: unknown but preserved by hardware, reset 0b01 CON12[12:15]: DMAC1 boot_addr[12:15] CON12[0:11]: first 12 DMAC1 peripheral Security State bits (1 is Non-Secure, reset 0xfff) CON13: DMAC1 boot_addr[16:31] CON14[8:15]: unknown but preserved by hardware, reset 0 CON14[0:7]: DMAC1 peripheral Security State bits 12:19 (1 is Non-Secure, reset 0xfff) CON15: DMAC1 event/IRQ Security State bits (1 is Non-Secure, reset 0xfff)
SOC_CON16 to SOC_CON18 are :reg:`R+E040` to :reg:`R+E048`. They read 0 at boot.
SOC_CON19 to SOC_CON22 are :reg:`R+804C` to :reg:`R+8058`.
All slave Security State settings have 1=Secure. and read as 1 at boot, unless mentioned otherwise.
:reg:`R0xC240[0]` seems to be a enable switch for the slave Security configuration and is 0 at boot, meaning all slaves are Non-Secure (is set to 1 by TF-A), :reg:`R0xC240[1]` is crypto1 Security State. The rest of the register is unknown (but is preserved by hardware) and reads 0 at boot.
:reg:`R0xC244` are the Security settings for slaves in the PMU power domain:
[0]: PMU [1]: PMUGRF [2]: interrupt arbiter for the PMUM0 [3]: spi3 [4]: pmutimer [5]: UART4 [6]: WDT2 [7]: mailbox1 [8]: PMUSRAM [9]: i2c0 [10]: i2c4 [11]: i2c8 [12]: pwm [13]: PMUCRU [14]: gpio0 [15]: gpio1
TODO non-PMU R0xE3c0
TODO PMUM0 R0xC100 TODO PERILPM0 R0x8100
TODO eFuse masks R0xC200, R0xC204
TODO fast boot addr R0xC180