On Fri, 16 Feb 2024 at 02:22, Caleb Connolly <caleb.conno...@linaro.org> wrote: > > With just a few basic rules, we can generate the $fdtfile environment > variable to match the format used in Linux. This uses the root > compatible property inside u-boot, with specific handling for the > Dragonboard845c which is a special case, and for the qrb robotics > boards. > > This is known to work on supported platforms, and lets us avoid having a > big lookup table. > > Reviewed-by: Neil Armstrong <neil.armstr...@linaro.org> > Signed-off-by: Caleb Connolly <caleb.conno...@linaro.org> > --- > arch/arm/mach-snapdragon/board.c | 101 > +++++++++++++++++++++++++++++++++++++++ > 1 file changed, 101 insertions(+) >
Reviewed-by: Sumit Garg <sumit.g...@linaro.org> -Sumit > diff --git a/arch/arm/mach-snapdragon/board.c > b/arch/arm/mach-snapdragon/board.c > index f445bed3af00..5a859aabd5c4 100644 > --- a/arch/arm/mach-snapdragon/board.c > +++ b/arch/arm/mach-snapdragon/board.c > @@ -160,6 +160,106 @@ int board_init(void) > return 0; > } > > +/* Sets up the "board", and "soc" environment variables as well as > constructing the devicetree > + * path, with a few quirks to handle non-standard dtb filenames. This is not > meant to be a > + * comprehensive solution to automatically picking the DTB, but aims to be > correct for the > + * majority case. For most devices it should be possible to make this > algorithm work by > + * adjusting the root compatible property in the U-Boot DTS. Handling > devices with multiple > + * variants that are all supported by a single U-Boot image will require > implementing device- > + * specific detection. > + */ > +static void configure_env(void) > +{ > + const char *first_compat, *last_compat; > + char *tmp; > + char buf[32] = { 0 }; > + /* > + * Most DTB filenames follow the scheme: > qcom/<soc>-[vendor]-<board>.dtb > + * The vendor is skipped when it's a Qualcomm reference board, or the > + * db845c. > + */ > + char dt_path[64] = { 0 }; > + int compat_count, ret; > + ofnode root; > + > + root = ofnode_root(); > + /* This is almost always 2, but be explicit that we want the first > and last compatibles > + * not the first and second. > + */ > + compat_count = ofnode_read_string_count(root, "compatible"); > + if (compat_count < 2) { > + log_warning("%s: only one root compatible bailing!\n", > __func__); > + return; > + } > + > + /* The most specific device compatible (e.g. "thundercomm,db845c") */ > + ret = ofnode_read_string_index(root, "compatible", 0, &first_compat); > + if (ret < 0) { > + log_warning("Can't read first compatible\n"); > + return; > + } > + > + /* The last compatible is always the SoC compatible */ > + ret = ofnode_read_string_index(root, "compatible", compat_count - 1, > &last_compat); > + if (ret < 0) { > + log_warning("Can't read second compatible\n"); > + return; > + } > + > + /* Copy the second compat (e.g. "qcom,sdm845") into buf */ > + strlcpy(buf, last_compat, sizeof(buf) - 1); > + tmp = buf; > + > + /* strsep() is destructive, it replaces the comma with a \0 */ > + if (!strsep(&tmp, ",")) { > + log_warning("second compatible '%s' has no ','\n", buf); > + return; > + } > + > + /* tmp now points to just the "sdm845" part of the string */ > + env_set("soc", tmp); > + > + /* Now figure out the "board" part from the first compatible */ > + memset(buf, 0, sizeof(buf)); > + strlcpy(buf, first_compat, sizeof(buf) - 1); > + tmp = buf; > + > + /* The Qualcomm reference boards (RBx, HDK, etc) */ > + if (!strncmp("qcom", buf, strlen("qcom"))) { > + /* > + * They all have the first compatible as "qcom,<soc>-<board>" > + * (e.g. "qcom,qrb5165-rb5"). We extract just the part after > + * the dash. > + */ > + if (!strsep(&tmp, "-")) { > + log_warning("compatible '%s' has no '-'\n", buf); > + return; > + } > + /* tmp is now "rb5" */ > + env_set("board", tmp); > + } else { > + if (!strsep(&tmp, ",")) { > + log_warning("compatible '%s' has no ','\n", buf); > + return; > + } > + /* for thundercomm we just want the bit after the comma (e.g. > "db845c"), > + * for all other boards we replace the comma with a '-' and > take both > + * (e.g. "oneplus-enchilada") > + */ > + if (!strncmp("thundercomm", buf, strlen("thundercomm"))) { > + env_set("board", tmp); > + } else { > + *(tmp - 1) = '-'; > + env_set("board", buf); > + } > + } > + > + /* Now build the full path name */ > + snprintf(dt_path, sizeof(dt_path), "qcom/%s-%s.dtb", > + env_get("soc"), env_get("board")); > + env_set("fdtfile", dt_path); > +} > + > void __weak qcom_late_init(void) > { > } > @@ -188,6 +288,7 @@ int board_late_init(void) > if (status) > log_warning("%s: Failed to set run time variables\n", > __func__); > > + configure_env(); > qcom_late_init(); > > return 0; > > -- > 2.43.1 >