[PATCH] rpi: copy the eMMC controller configuration from firmware-supplied DT
Jian-Hong Pan
jhp at endlessos.org
Fri Oct 28 05:51:37 CEST 2022
Ilya K <me at 0upti.me> 於 2022年10月27日 週四 晚上7:48寫道:
>
> FWIW, my vote is for the revised series. Also, we've been shipping both patches downstream in NixOS for a while now, and had no issues with either.
>
> 27.10.2022, 09:27, "Peter Robinson" <pbrobinson at gmail.com>:
>
> Adding Matthias as the RPi maintainer.
>
> There was also this patch series which fixed it and a few other things
> from the firmware DT [1] which is likely a better fix TBH.
>
> Either way Matthias can we get one of these upstream as even the RPi4
> Model B has moved to the newer rev of the SoCs so it's not a nice
> experience for users if they're not aware of the differences/problems.
>
> Peter
>
> [1] https://lists.denx.de/pipermail/u-boot/2022-August/491455.html
Great! This patch series looks nice, too.
Jian-Hong Pan
> On Wed, Oct 26, 2022 at 12:23 PM Jian-Hong Pan <jhp at endlessos.org> wrote:
>
>
> From: Ilya Katsnelson <me at 0upti.me>
>
> The RPi firmware adjusts the onboard eMMC controller's DMA mapping
> ranges of the FDT for each BCM2711 SoC revisions on the Pi 4 and RPi 400
> automatically.
>
> If the following kernel does not boot with the correct eMMC controller's
> DMA mapping ranges, the system on the SD card will boot failed and show
> these error messages:
>
> mmc1: invalid bus width
> mmc1: error -22 whilst initialising SD card
>
> This patch carries the adjustment from RPi firmware to the new loaded
> FDT for the following kernel.
>
> Link: https://lists.denx.de/pipermail/u-boot/2021-September/462006.html
> Fixed: https://bugzilla.kernel.org/show_bug.cgi?id=213753
> Signed-off-by: Ilya Katsnelson <me at 0upti.me>
> Signed-off-by: Jian-Hong Pan <jhp at endlessos.org>
> ---
> The code of this patch comes from "[RFC PATCH] rpi: copy the EMMC
> controller configuration from firmware-supplied DT" [1] basically.
> I only add the message and some modifcation:
>
> * Fix the build failed error:
> board/raspberrypi/rpi/rpi.c: In function 'copy_emmc_config':
> board/raspberrypi/rpi/rpi.c:553:9: warning: dereferencing 'void *' pointer
> 553 | *fw_value = fdt_getprop(fw_fdt, fw_emmc_node, "dma-ranges", &length);
> | ^~~~~~~~~
> board/raspberrypi/rpi/rpi.c:553:19: error: invalid use of void expression
> 553 | *fw_value = fdt_getprop(fw_fdt, fw_emmc_node, "dma-ranges", &length);
> | ^
> make[1]: *** [scripts/Makefile.build:258: board/raspberrypi/rpi/rpi.o] Error 1
>
> * Replace "EMMC" to "eMMC".
>
> * Replace the printf with log_[levels].
>
> So, I keep "Ilya Katsnelson <me at 0upti.me>" as the author.
>
> [1]: https://lists.denx.de/pipermail/u-boot/2021-September/462006.html
>
> board/raspberrypi/rpi/rpi.c | 63 +++++++++++++++++++++++++++++++++++++
> 1 file changed, 63 insertions(+)
>
> diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
> index 00afb352bd..d7ff8e269e 100644
> --- a/board/raspberrypi/rpi/rpi.c
> +++ b/board/raspberrypi/rpi/rpi.c
> @@ -504,6 +504,67 @@ void *board_fdt_blob_setup(int *err)
> return (void *)fw_dtb_pointer;
> }
>
> +void copy_emmc_config(void *our_fdt)
> +{
> + /*
> + * As of 2021-09-28, the Pi 4 has two different revisions, one using a
> + * B0 stepping of the BCM2711 SoC, and one using a C0 stepping.
> + *
> + * The two SoC versions have different, incompatible DMA mappings for
> + * the on-board eMMC controller, which would normally make them require
> + * two different DTs.
> + *
> + * Unfortunately for us, the different revisions don't actually _use_
> + * different DTs - instead, the proprietary stage0 bootloader reads the DT,
> + * patches it in-memory, then passes the corrected DT to the OS.
> + *
> + * In our case, the OS is actually U-Boot, and U-Boot can choose to
> + * completely disregard the firmware-supplied DT and load a custom one
> + * instead, which is used by, e.g., NixOS.
> + *
> + * When that happens, the DT patches applied by the firmware are also
> + * thrown out, which leads to BCM2711C0 boards being unable to boot
> + * due to them trying to use the hardcoded DMA mappings in the DT
> + * (which are for the B0 revision).
> + *
> + * Work around that by manually copying the DMA region setup from the
> + * firmware-provided DT into whatever DT we're actually being asked
> + * to load.
> + */
> + void *fw_fdt = (void *)fw_dtb_pointer;
> + int fw_emmc_node;
> + int our_emmc_node;
> + int length;
> + const void *fw_value;
> + int result;
> +
> + fw_emmc_node = fdt_path_offset(fw_fdt, "emmc2bus");
> + if (fw_emmc_node < 0) {
> + log_info("RPi: Failed to find eMMC config in FW DT: %d\n", fw_emmc_node);
> + return;
> + }
> +
> + our_emmc_node = fdt_path_offset(our_fdt, "emmc2bus");
> + if (our_emmc_node < 0) {
> + log_info("RPi: Failed to find eMMC config in our DT: %d\n", our_emmc_node);
> + return;
> + }
> +
> + fw_value = fdt_getprop(fw_fdt, fw_emmc_node, "dma-ranges", &length);
> + if (!fw_value) {
> + log_info("RPi: Failed to get eMMC DMA ranges property from FW DT: %d\n", length);
> + return;
> + }
> +
> + result = fdt_setprop(our_fdt, our_emmc_node, "dma-ranges", fw_value, length);
> + if (result != 0) {
> + log_warning("RPi: Failed to set eMMC DMA ranges property in our DT: %d\n", result);
> + return;
> + }
> +
> + log_debug("RPi: successfully copied FW DT eMMC configuration to our DT!\n");
> +}
> +
> int ft_board_setup(void *blob, struct bd_info *bd)
> {
> int node;
> @@ -518,5 +579,7 @@ int ft_board_setup(void *blob, struct bd_info *bd)
> EFI_RESERVED_MEMORY_TYPE);
> #endif
>
> + copy_emmc_config(blob);
> +
> return 0;
> }
> --
> 2.38.1
>
More information about the U-Boot
mailing list