From 2aa3d61f58aca8dd53cb2c1a598253279a35053a Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Wed, 24 Mar 2021 14:37:42 +0100 Subject: [PATCH] Bring RPM out of reset on initial boot-up Looking closer at the Linux kernel log I notice that all RPM regulators seem to be suddenly broken: adv7511 3-0039: failed to init regulators Poking some registers it looks like RPM is still in reset, because 0x1860000 (GCC_APSS_MISC) still has the reset bit set. Apparently, the HYP firmware is also responsible for bringing RPM out of reset on the initial boot-up. Implementing this isn't that hard, so add some additional assembly to store if this is the initial boot and clear the reset bit if necessary. This makes the RPM regulators work again! :) --- qhypstub.ld | 1 + qhypstub.s | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/qhypstub.ld b/qhypstub.ld index 57dfb07..920abe2 100644 --- a/qhypstub.ld +++ b/qhypstub.ld @@ -8,4 +8,5 @@ SECTIONS { . = 0x86400000; .text : { *(.text) } + .data : { *(.data) } } diff --git a/qhypstub.s b/qhypstub.s index 84a3bd9..b082f67 100644 --- a/qhypstub.s +++ b/qhypstub.s @@ -7,6 +7,7 @@ */ .cpu cortex-a53 +.equ STATE_INITIAL, 0 .equ STATE_AARCH32, 1 .equ STATE_AARCH64, 2 @@ -39,6 +40,7 @@ _start: * Register allocation: * x0 = temporary register * x1 = STATE_AARCH32/STATE_AARCH64 + * x2 = execution_state value * x3 = temporary register * lr = bootloader/kernel entry address */ @@ -50,6 +52,19 @@ _start: mov x3, xzr .endm + /* First, figure out if this is the initial boot-up */ + adr x0, execution_state + ldrb w2, [x0] + cbnz w2, skip_init + strb w1, [x0] /* set initial execution_state based on x1 */ + + /* Bring RPM out of reset */ + mov x0, 0x1860000 /* GCC_APSS_MISC */ + ldr w3, [x0] + and w3, w3, ~0b1 /* RPM_RESET_REMOVAL */ + str w3, [x0] + +skip_init: cmp x1, STATE_AARCH64 bne not_aarch64 @@ -83,3 +98,7 @@ not_aarch64: panic: b panic + +.data +execution_state: + .byte 0