From: Jan Kiszka <[email protected]> This is needed for the latest bootloader firmware, or the output will be garbage.
Signed-off-by: Jan Kiszka <[email protected]> --- .../arm-trusted-firmware_2.2.inc | 4 +- ...16550-Prepare-for-skipping-initialisation.patch | 127 +++++++++++++++++++++ .../0002-plat-rpi4-Skip-UART-initialisation.patch | 109 ++++++++++++++++++ ...03-rpi3-4-Add-support-for-offlining-CPUs.patch} | 5 +- 4 files changed, 242 insertions(+), 3 deletions(-) create mode 100644 recipes-bsp/arm-trusted-firmware/files/0001-console-16550-Prepare-for-skipping-initialisation.patch create mode 100644 recipes-bsp/arm-trusted-firmware/files/0002-plat-rpi4-Skip-UART-initialisation.patch rename recipes-bsp/arm-trusted-firmware/files/{0001-rpi3-4-Add-support-for-offlining-CPUs.patch => 0003-rpi3-4-Add-support-for-offlining-CPUs.patch} (89%) diff --git a/recipes-bsp/arm-trusted-firmware/arm-trusted-firmware_2.2.inc b/recipes-bsp/arm-trusted-firmware/arm-trusted-firmware_2.2.inc index 0354ac4..9f75497 100644 --- a/recipes-bsp/arm-trusted-firmware/arm-trusted-firmware_2.2.inc +++ b/recipes-bsp/arm-trusted-firmware/arm-trusted-firmware_2.2.inc @@ -13,6 +13,8 @@ FILESPATH =. "${LAYERDIR_jailhouse}/recipes-bsp/arm-trusted-firmware/files:" SRC_URI += " \ https://github.com/ARM-software/arm-trusted-firmware/archive/v${ATF_PV}.tar.gz;downloadfilename=atf-v${ATF_PV}.tar.gz;name=atf \ - file://0001-rpi3-4-Add-support-for-offlining-CPUs.patch;patchdir=${WORKDIR}/arm-trusted-firmware-${ATF_PV} \ + file://0001-console-16550-Prepare-for-skipping-initialisation.patch;patchdir=${WORKDIR}/arm-trusted-firmware-${ATF_PV} \ + file://0002-plat-rpi4-Skip-UART-initialisation.patch;patchdir=${WORKDIR}/arm-trusted-firmware-${ATF_PV} \ + file://0003-rpi3-4-Add-support-for-offlining-CPUs.patch;patchdir=${WORKDIR}/arm-trusted-firmware-${ATF_PV} \ " SRC_URI[atf.sha256sum] = "07e3c058ae2d95c7d516a46fc93565b797e912c3271ddbf29df523b1ab1ee911" diff --git a/recipes-bsp/arm-trusted-firmware/files/0001-console-16550-Prepare-for-skipping-initialisation.patch b/recipes-bsp/arm-trusted-firmware/files/0001-console-16550-Prepare-for-skipping-initialisation.patch new file mode 100644 index 0000000..10ca776 --- /dev/null +++ b/recipes-bsp/arm-trusted-firmware/files/0001-console-16550-Prepare-for-skipping-initialisation.patch @@ -0,0 +1,127 @@ +From 62b9c075700eedbc6d308b51b17e90c031c1a300 Mon Sep 17 00:00:00 2001 +From: Andre Przywara <[email protected]> +Date: Thu, 12 Dec 2019 12:00:15 +0000 +Subject: [PATCH 1/3] console: 16550: Prepare for skipping initialisation + +On some platforms the UART might have already been initialised, for +instance by firmware running before TF-A or by a separate management +processor. In this case it would not be need to initialise it again +(doing so could create spurious characters). But more importantly this +saves us from knowing the right baudrate and the right base clock rate +for the UART. This can lead to more robust and versatile firmware builds. + +Allow to skip the 16550 UART initialisation and baud rate divisor +programming, by interpreting an input clock rate of "0" to signify this +case. This will just skip the call to console_16550_core_init, but still +will register the console properly. + +Users should just pass 0 as the second parameter, the baudrate (third +parameter) will then be ignored as well. + +Fix copy & paste typos in comments for the console_16550_register() +function on the way. + +Signed-off-by: Andre Przywara <[email protected]> +Change-Id: I9f8fca5b358f878fac0f31dc411358fd160786ee +--- + drivers/ti/uart/aarch32/16550_console.S | 18 +++++++++++++----- + drivers/ti/uart/aarch64/16550_console.S | 9 ++++++++- + include/drivers/ti/uart/uart_16550.h | 5 +++++ + 3 files changed, 26 insertions(+), 6 deletions(-) + +diff --git a/drivers/ti/uart/aarch32/16550_console.S b/drivers/ti/uart/aarch32/16550_console.S +index 692188412..5cd9b30cd 100644 +--- a/drivers/ti/uart/aarch32/16550_console.S ++++ b/drivers/ti/uart/aarch32/16550_console.S +@@ -89,16 +89,19 @@ endfunc console_16550_core_init + .globl console_16550_register + + /* ------------------------------------------------------- +- * int console_stm32_register(uintptr_t baseaddr, ++ * int console_16550_register(uintptr_t baseaddr, + * uint32_t clock, uint32_t baud, +- * struct console_stm32 *console); +- * Function to initialize and register a new STM32 ++ * console_16550_t *console); ++ * Function to initialize and register a new 16550 + * console. Storage passed in for the console struct + * *must* be persistent (i.e. not from the stack). ++ * If r1 (UART clock) is 0, initialisation will be ++ * skipped, relying on previous code to have done ++ * this already. r2 is ignored then as well. + * In: r0 - UART register base address + * r1 - UART clock in Hz +- * r2 - Baud rate +- * r3 - pointer to empty console_stm32 struct ++ * r2 - Baud rate (ignored if r1 is 0) ++ * r3 - pointer to empty console_16550_t struct + * Out: return 1 on success, 0 on error + * Clobber list : r0, r1, r2 + * ------------------------------------------------------- +@@ -110,10 +113,15 @@ func console_16550_register + beq register_fail + str r0, [r4, #CONSOLE_T_16550_BASE] + ++ /* A clock rate of zero means to skip the initialisation. */ ++ cmp r1, #0 ++ beq register_16550 ++ + bl console_16550_core_init + cmp r0, #0 + beq register_fail + ++register_16550: + mov r0, r4 + pop {r4, lr} + finish_console_register 16550 putc=1, getc=1, flush=1 +diff --git a/drivers/ti/uart/aarch64/16550_console.S b/drivers/ti/uart/aarch64/16550_console.S +index dab46e8c5..80c1b8646 100644 +--- a/drivers/ti/uart/aarch64/16550_console.S ++++ b/drivers/ti/uart/aarch64/16550_console.S +@@ -92,9 +92,12 @@ endfunc console_16550_core_init + * Function to initialize and register a new 16550 + * console. Storage passed in for the console struct + * *must* be persistent (i.e. not from the stack). ++ * If w1 (UART clock) is 0, initialisation will be ++ * skipped, relying on previous code to have done ++ * this already. w2 is ignored then as well. + * In: x0 - UART register base address + * w1 - UART clock in Hz +- * w2 - Baud rate ++ * w2 - Baud rate (ignored if w1 is 0) + * x3 - pointer to empty console_16550_t struct + * Out: return 1 on success, 0 on error + * Clobber list : x0, x1, x2, x6, x7, x14 +@@ -106,9 +109,13 @@ func console_16550_register + cbz x6, register_fail + str x0, [x6, #CONSOLE_T_16550_BASE] + ++ /* A clock rate of zero means to skip the initialisation. */ ++ cbz w1, register_16550 ++ + bl console_16550_core_init + cbz x0, register_fail + ++register_16550: + mov x0, x6 + mov x30, x7 + finish_console_register 16550 putc=1, getc=1, flush=1 +diff --git a/include/drivers/ti/uart/uart_16550.h b/include/drivers/ti/uart/uart_16550.h +index 32e38f0ac..2b95fa33a 100644 +--- a/include/drivers/ti/uart/uart_16550.h ++++ b/include/drivers/ti/uart/uart_16550.h +@@ -87,6 +87,11 @@ typedef struct { + * framework. The |console| pointer must point to storage that will be valid + * for the lifetime of the console, such as a global or static local variable. + * Its contents will be reinitialized from scratch. ++ * When |clock| has a value of 0, the UART will *not* be initialised. This ++ * means the UART should already be enabled and the baudrate and clock setup ++ * should have been done already, either by platform specific code or by ++ * previous firmware stages. The |baud| parameter will be ignored in this ++ * case as well. + */ + int console_16550_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud, + console_16550_t *console); +-- +2.16.4 + diff --git a/recipes-bsp/arm-trusted-firmware/files/0002-plat-rpi4-Skip-UART-initialisation.patch b/recipes-bsp/arm-trusted-firmware/files/0002-plat-rpi4-Skip-UART-initialisation.patch new file mode 100644 index 0000000..56cac70 --- /dev/null +++ b/recipes-bsp/arm-trusted-firmware/files/0002-plat-rpi4-Skip-UART-initialisation.patch @@ -0,0 +1,109 @@ +From 0ea846120c1df90cf8cf29ab3f664cf7e3eabc22 Mon Sep 17 00:00:00 2001 +From: Andre Przywara <[email protected]> +Date: Thu, 12 Dec 2019 16:31:11 +0000 +Subject: [PATCH 2/3] plat: rpi4: Skip UART initialisation + +So far we have seen two different clock setups for the Raspberry Pi 4 +board, with the VPU clock divider being different. This was handled by +reading the divider register and adjusting the base clock rate +accordingly. +Recently a new GPU firmware version appeared that changed the clock rate +*again*, though this time at a higher level, so the VPU rate (and the +apparent PLLC parent clock) did not seem to change, judging by reading +the clock registers. +So rather than playing cat and mouse with the GPU firmware or going +further down the rabbit hole of exploring the whole clock tree, let's +just skip the baud rate programming altogether. This works because the +GPU firmware actually sets up and programs the debug UART already, so +we can just use it. + +Pass 0 as the base clock rate to let the console driver skip the setup, +also remove the no longer needed clock code. + +Signed-off-by: Andre Przywara <[email protected]> +Change-Id: Ica88a3f3c9c11059357c1e6dd8f7a4d9b1f98fd7 +--- + plat/rpi/rpi4/aarch64/plat_helpers.S | 4 ++-- + plat/rpi/rpi4/include/rpi_hw.h | 8 -------- + plat/rpi/rpi4/rpi4_bl31_setup.c | 16 +++++----------- + 3 files changed, 7 insertions(+), 21 deletions(-) + +diff --git a/plat/rpi/rpi4/aarch64/plat_helpers.S b/plat/rpi/rpi4/aarch64/plat_helpers.S +index 46073b791..083c30e71 100644 +--- a/plat/rpi/rpi4/aarch64/plat_helpers.S ++++ b/plat/rpi/rpi4/aarch64/plat_helpers.S +@@ -136,8 +136,8 @@ endfunc platform_mem_init + */ + func plat_crash_console_init + mov_imm x0, PLAT_RPI3_UART_BASE +- mov_imm x1, PLAT_RPI4_VPU_CLK_RATE +- mov_imm x2, PLAT_RPI3_UART_BAUDRATE ++ mov x1, xzr ++ mov x2, xzr + b console_16550_core_init + endfunc plat_crash_console_init + +diff --git a/plat/rpi/rpi4/include/rpi_hw.h b/plat/rpi/rpi4/include/rpi_hw.h +index ed367ee20..b1dd4e92e 100644 +--- a/plat/rpi/rpi4/include/rpi_hw.h ++++ b/plat/rpi/rpi4/include/rpi_hw.h +@@ -58,13 +58,6 @@ + */ + #define RPI3_PM_RSTS_WRCFG_HALT U(0x00000555) + +-/* +- * Clock controller +- */ +-#define RPI4_IO_CLOCK_OFFSET ULL(0x00101000) +-#define RPI4_CLOCK_BASE (RPI_IO_BASE + RPI4_IO_CLOCK_OFFSET) +-#define RPI4_VPU_CLOCK_DIVIDER ULL(0x0000000c) +- + /* + * Hardware random number generator. + */ +@@ -88,7 +81,6 @@ + */ + #define RPI3_IO_MINI_UART_OFFSET ULL(0x00215040) + #define RPI3_MINI_UART_BASE (RPI_IO_BASE + RPI3_IO_MINI_UART_OFFSET) +-#define PLAT_RPI4_VPU_CLK_RATE ULL(1000000000) + + /* + * GPIO controller +diff --git a/plat/rpi/rpi4/rpi4_bl31_setup.c b/plat/rpi/rpi4/rpi4_bl31_setup.c +index 53ab0c2e2..9e3b53979 100644 +--- a/plat/rpi/rpi4/rpi4_bl31_setup.c ++++ b/plat/rpi/rpi4/rpi4_bl31_setup.c +@@ -119,8 +119,6 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) + + { +- uint32_t div_reg; +- + /* + * LOCAL_CONTROL: + * Bit 9 clear: Increment by 1 (vs. 2). +@@ -136,16 +134,12 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + + /* + * Initialize the console to provide early debug support. +- * Different GPU firmware revisions set up the VPU divider differently, +- * so read the actual divider register to learn the UART base clock +- * rate. The divider is encoded as a 12.12 fixed point number, but we +- * just care about the integer part of it. ++ * We rely on the GPU firmware to have initialised the UART correctly, ++ * as the baud base clock rate differs across GPU firmware revisions. ++ * Providing a base clock of 0 lets the 16550 UART init routine skip ++ * the initial enablement and baud rate setup. + */ +- div_reg = mmio_read_32(RPI4_CLOCK_BASE + RPI4_VPU_CLOCK_DIVIDER); +- div_reg = (div_reg >> 12) & 0xfff; +- if (div_reg == 0) +- div_reg = 1; +- rpi3_console_init(PLAT_RPI4_VPU_CLK_RATE / div_reg); ++ rpi3_console_init(0); + + bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); + bl33_image_ep_info.spsr = rpi3_get_spsr_for_bl33_entry(); +-- +2.16.4 + diff --git a/recipes-bsp/arm-trusted-firmware/files/0001-rpi3-4-Add-support-for-offlining-CPUs.patch b/recipes-bsp/arm-trusted-firmware/files/0003-rpi3-4-Add-support-for-offlining-CPUs.patch similarity index 89% rename from recipes-bsp/arm-trusted-firmware/files/0001-rpi3-4-Add-support-for-offlining-CPUs.patch rename to recipes-bsp/arm-trusted-firmware/files/0003-rpi3-4-Add-support-for-offlining-CPUs.patch index 33d288b..02d0440 100644 --- a/recipes-bsp/arm-trusted-firmware/files/0001-rpi3-4-Add-support-for-offlining-CPUs.patch +++ b/recipes-bsp/arm-trusted-firmware/files/0003-rpi3-4-Add-support-for-offlining-CPUs.patch @@ -1,7 +1,7 @@ -From 92ff7ed78f8600adc9733663380706a1bdb3e4a9 Mon Sep 17 00:00:00 2001 +From 6368eab6c5129f4ee6679a2daa6f0d5315cfd655 Mon Sep 17 00:00:00 2001 From: Jan Kiszka <[email protected]> Date: Sun, 8 Dec 2019 20:48:46 +0100 -Subject: [PATCH] rpi3/4: Add support for offlining CPUs +Subject: [PATCH 3/3] rpi3/4: Add support for offlining CPUs The hooks were populated but the power down left the CPU in limbo-land. What we need to do - until there is a way to actually power off - is to @@ -9,6 +9,7 @@ turn off the MMU and enter the spinning loop as if we were cold-booted. This allows the on-call to pick up the CPU again. Signed-off-by: Jan Kiszka <[email protected]> +Change-Id: Iefc7a58424e3578ad3dd355a7bd6eaba4b412699 --- plat/rpi/common/rpi3_pm.c | 10 ++++++++++ 1 file changed, 10 insertions(+) -- 2.16.4 -- You received this message because you are subscribed to the Google Groups "Jailhouse" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/jailhouse-dev/aea3ac86dffa3b155ba4654ecc4764101b2cd774.1586760835.git.jan.kiszka%40web.de.
