[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