From 993a9db918af451c68851522c8770e582b717629 Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Fri, 11 Apr 2025 14:47:38 +0200 Subject: event: signal when livetree has been built OF_LIVE offers a variety of benefits, one of them being that the live tree can be modified without caring about the underlying FDT. This is particularly valuable for working around U-Boot limitations like lacking USB superspeed support on Qualcomm platforms, no runtime OTG, or peripherals like the sdcard being broken (and displaying potentially worrying error messages). Add an event to signal when the live tree has been built so that we can apply fixups to it directly before devices are bound. Signed-off-by: Caleb Connolly --- common/event.c | 3 +++ include/event.h | 18 ++++++++++++++++++ lib/of_live.c | 11 +++++++++++ 3 files changed, 32 insertions(+) diff --git a/common/event.c b/common/event.c index dda569d4478..8d7513eb10b 100644 --- a/common/event.c +++ b/common/event.c @@ -48,6 +48,9 @@ const char *const type_name[] = { /* main loop events */ "main_loop", + + /* livetree has been built */ + "of_live_init", }; _Static_assert(ARRAY_SIZE(type_name) == EVT_COUNT, "event type_name size"); diff --git a/include/event.h b/include/event.h index 75141a192a4..1d267f1d105 100644 --- a/include/event.h +++ b/include/event.h @@ -153,6 +153,15 @@ enum event_t { */ EVT_MAIN_LOOP, + /** + * @EVT_OF_LIVE_BUILT: + * This event is triggered immediately after the live device tree has been + * built. This allows for machine specific fixups to be done to the live tree + * (like disabling known-unsupported devices) before it is used. This + * event is only available if OF_LIVE is enabled and is only used after relocation. + */ + EVT_OF_LIVE_BUILT, + /** * @EVT_COUNT: * This constants holds the maximum event number + 1 and is used when @@ -203,6 +212,15 @@ union event_data { oftree tree; struct bootm_headers *images; } ft_fixup; + + /** + * struct event_of_live_built - livetree has been built + * + * @root: The root node of the live device tree + */ + struct event_of_live_built { + struct device_node *root; + } of_live_built; }; /** diff --git a/lib/of_live.c b/lib/of_live.c index 90b9459ede3..c1620616513 100644 --- a/lib/of_live.c +++ b/lib/of_live.c @@ -11,6 +11,7 @@ #define LOG_CATEGORY LOGC_DT #include +#include #include #include #include @@ -321,6 +322,7 @@ int unflatten_device_tree(const void *blob, struct device_node **mynodes) int of_live_build(const void *fdt_blob, struct device_node **rootp) { int ret; + union event_data evt; debug("%s: start\n", __func__); ret = unflatten_device_tree(fdt_blob, rootp); @@ -335,6 +337,15 @@ int of_live_build(const void *fdt_blob, struct device_node **rootp) } debug("%s: stop\n", __func__); + if (CONFIG_IS_ENABLED(EVENT)) { + evt.of_live_built.root = *rootp; + ret = event_notify(EVT_OF_LIVE_BUILT, &evt, sizeof(evt)); + if (ret) { + log_debug("Failed to notify livetree build event: err=%d\n", ret); + return ret; + } + } + return ret; } -- cgit v1.2.3 From 5a1dfb27f9170d35a475ea8be46b5d7c037ee837 Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Fri, 11 Apr 2025 14:47:39 +0200 Subject: mach-snapdragon: use EVT_OF_LIVE_INIT to apply DT fixups This will now apply fixups prior to devices being bound, which makes it possible to enable/disable devices and adjust more properties that might be read before devices probe. Signed-off-by: Caleb Connolly --- arch/arm/mach-snapdragon/board.c | 1 - arch/arm/mach-snapdragon/of_fixup.c | 25 ++++++++++++++++--------- arch/arm/mach-snapdragon/qcom-priv.h | 14 -------------- 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c index deae4d32378..3ab75f0fce0 100644 --- a/arch/arm/mach-snapdragon/board.c +++ b/arch/arm/mach-snapdragon/board.c @@ -306,7 +306,6 @@ void __weak qcom_board_init(void) int board_init(void) { show_psci_version(); - qcom_of_fixup_nodes(); qcom_board_init(); return 0; } diff --git a/arch/arm/mach-snapdragon/of_fixup.c b/arch/arm/mach-snapdragon/of_fixup.c index 1ea0c18c2f2..70399307bcb 100644 --- a/arch/arm/mach-snapdragon/of_fixup.c +++ b/arch/arm/mach-snapdragon/of_fixup.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -32,7 +33,7 @@ * DT here. This improves compatibility with upstream DT and simplifies the * porting process for new devices. */ -static int fixup_qcom_dwc3(struct device_node *glue_np) +static int fixup_qcom_dwc3(struct device_node *root, struct device_node *glue_np) { struct device_node *dwc3; int ret, len, hsphy_idx = 1; @@ -101,9 +102,9 @@ static int fixup_qcom_dwc3(struct device_node *glue_np) return 0; } -static void fixup_usb_nodes(void) +static void fixup_usb_nodes(struct device_node *root) { - struct device_node *glue_np = NULL; + struct device_node *glue_np = root; int ret; while ((glue_np = of_find_compatible_node(glue_np, NULL, "qcom,dwc3"))) { @@ -114,14 +115,14 @@ static void fixup_usb_nodes(void) } /* Remove all references to the rpmhpd device */ -static void fixup_power_domains(void) +static void fixup_power_domains(struct device_node *root) { struct device_node *pd = NULL, *np = NULL; struct property *prop; const __be32 *val; /* All Qualcomm platforms name the rpm(h)pd "power-controller" */ - for_each_of_allnodes(pd) { + for_each_of_allnodes_from(root, pd) { if (pd->name && !strcmp("power-controller", pd->name)) break; } @@ -133,7 +134,7 @@ static void fixup_power_domains(void) } /* Remove all references to the power domain controller */ - for_each_of_allnodes(np) { + for_each_of_allnodes_from(root, np) { if (!(prop = of_find_property(np, "power-domains", NULL))) continue; @@ -150,12 +151,18 @@ static void fixup_power_domains(void) debug(#func " took %lluus\n", timer_get_us() - start); \ } while (0) -void qcom_of_fixup_nodes(void) +static int qcom_of_fixup_nodes(void * __maybe_unused ctx, struct event *event) { - time_call(fixup_usb_nodes); - time_call(fixup_power_domains); + struct device_node *root = event->data.of_live_built.root; + + time_call(fixup_usb_nodes, root); + time_call(fixup_power_domains, root); + + return 0; } +EVENT_SPY_FULL(EVT_OF_LIVE_BUILT, qcom_of_fixup_nodes); + int ft_board_setup(void *blob, struct bd_info __maybe_unused *bd) { struct fdt_header *fdt = blob; diff --git a/arch/arm/mach-snapdragon/qcom-priv.h b/arch/arm/mach-snapdragon/qcom-priv.h index 74d39197b89..4f398e2ba37 100644 --- a/arch/arm/mach-snapdragon/qcom-priv.h +++ b/arch/arm/mach-snapdragon/qcom-priv.h @@ -9,18 +9,4 @@ void qcom_configure_capsule_updates(void); void qcom_configure_capsule_updates(void) {} #endif /* EFI_HAVE_CAPSULE_SUPPORT */ -#if CONFIG_IS_ENABLED(OF_LIVE) -/** - * qcom_of_fixup_nodes() - Fixup Qualcomm DT nodes - * - * Adjusts nodes in the live tree to improve compatibility with U-Boot. - */ -void qcom_of_fixup_nodes(void); -#else -static inline void qcom_of_fixup_nodes(void) -{ - log_debug("Unable to dynamically fixup USB nodes, please enable CONFIG_OF_LIVE\n"); -} -#endif /* OF_LIVE */ - #endif /* __QCOM_PRIV_H__ */ -- cgit v1.2.3 From 0ec337d03410a4a0b7402ae72968470cf63f0c55 Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Fri, 11 Apr 2025 14:47:40 +0200 Subject: mach-snapdragon: of_fixup: skip disabled USB nodes There's no need to waste time fixing up nodes that aren't used on this device. Skip them. Reviewed-by: Sumit Garg Reviewed-by: Neil Armstrong Tested-by: Sumit Garg Signed-off-by: Caleb Connolly --- arch/arm/mach-snapdragon/of_fixup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-snapdragon/of_fixup.c b/arch/arm/mach-snapdragon/of_fixup.c index 70399307bcb..dcd09ee7cac 100644 --- a/arch/arm/mach-snapdragon/of_fixup.c +++ b/arch/arm/mach-snapdragon/of_fixup.c @@ -108,7 +108,9 @@ static void fixup_usb_nodes(struct device_node *root) int ret; while ((glue_np = of_find_compatible_node(glue_np, NULL, "qcom,dwc3"))) { - ret = fixup_qcom_dwc3(glue_np); + if (!of_device_is_available(glue_np)) + continue; + ret = fixup_qcom_dwc3(root, glue_np); if (ret) log_warning("Failed to fixup node %s: %d\n", glue_np->name, ret); } -- cgit v1.2.3 From a6cc4ef343dc39c17fd5b833d983aff2f26c94b7 Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Fri, 11 Apr 2025 14:47:41 +0200 Subject: mach-snapdragon: of_fixup: remove confusing log message The debug log here had the logic completely backwards, even though the code is actually correct. Remove it since it's extraneous anyway. Signed-off-by: Caleb Connolly Reviewed-by: Neil Armstrong --- arch/arm/mach-snapdragon/of_fixup.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-snapdragon/of_fixup.c b/arch/arm/mach-snapdragon/of_fixup.c index dcd09ee7cac..a5515c02d3d 100644 --- a/arch/arm/mach-snapdragon/of_fixup.c +++ b/arch/arm/mach-snapdragon/of_fixup.c @@ -73,11 +73,12 @@ static int fixup_qcom_dwc3(struct device_node *root, struct device_node *glue_np return ret; } - if (!strncmp("usb3-phy", second_phy_name, strlen("usb3-phy"))) { - log_debug("Second phy isn't superspeed (is '%s') assuming first phy is SS\n", - second_phy_name); + /* + * Determine which phy is the superspeed phy by checking the name of the second phy + * since it is typically the superspeed one. + */ + if (!strncmp("usb3-phy", second_phy_name, strlen("usb3-phy"))) hsphy_idx = 0; - } /* Overwrite the "phys" property to only contain the high-speed phy */ ret = of_write_prop(dwc3, "phys", sizeof(*phandles), phandles + hsphy_idx); -- cgit v1.2.3 From 9bc7eef9bf58c4c1d453cba81060dc61375f5354 Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Fri, 11 Apr 2025 14:47:42 +0200 Subject: mach-snapdragon: of_fixup: update comment we don't rewrite the volume buttons any more. Signed-off-by: Caleb Connolly Reviewed-by: Neil Armstrong --- arch/arm/mach-snapdragon/of_fixup.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm/mach-snapdragon/of_fixup.c b/arch/arm/mach-snapdragon/of_fixup.c index a5515c02d3d..10053e48d88 100644 --- a/arch/arm/mach-snapdragon/of_fixup.c +++ b/arch/arm/mach-snapdragon/of_fixup.c @@ -4,8 +4,7 @@ * * This file implements runtime fixups for Qualcomm DT to improve * compatibility with U-Boot. This includes adjusting the USB nodes - * to only use USB high-speed, as well as remapping volume buttons - * to behave as up/down for navigating U-Boot. + * to only use USB high-speed. * * We use OF_LIVE for this rather than early FDT fixup for a couple * of reasons: it has a much nicer API, is most likely more efficient, -- cgit v1.2.3 From 3b983cf48e70ecb6aadca788d0d91a021340c802 Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Fri, 11 Apr 2025 14:47:43 +0200 Subject: mach-snapdragon: of_fixup: set dr_mode for RB1/2 boards The RB1 and RB2 have a single USB controller which is manually muxed between a type-c port and an internal USB hub via a DIP switch. OTG is supported in Linux, but the DWC3 driver in U-Boot can only handle a single mode, and defaults to peripheral mode. We did hack around this on the RB2, but the RB1 got left out. Now that we can fix up the live tree before devices are bound, drop the DTS hacks and do the fixup at runtime instead. Reviewed-by: Sumit Garg Reviewed-by: Neil Armstrong Tested-by: Sumit Garg Signed-off-by: Caleb Connolly --- arch/arm/dts/qrb4210-rb2-u-boot.dtsi | 6 ------ arch/arm/mach-snapdragon/of_fixup.c | 28 ++++++++++++++-------------- 2 files changed, 14 insertions(+), 20 deletions(-) delete mode 100644 arch/arm/dts/qrb4210-rb2-u-boot.dtsi diff --git a/arch/arm/dts/qrb4210-rb2-u-boot.dtsi b/arch/arm/dts/qrb4210-rb2-u-boot.dtsi deleted file mode 100644 index 7d1375f38c4..00000000000 --- a/arch/arm/dts/qrb4210-rb2-u-boot.dtsi +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -/* This is usually OTG but U-Boot doesn't support that properly */ -&usb_dwc3 { - dr_mode = "host"; -}; diff --git a/arch/arm/mach-snapdragon/of_fixup.c b/arch/arm/mach-snapdragon/of_fixup.c index 10053e48d88..b398c6b7b9f 100644 --- a/arch/arm/mach-snapdragon/of_fixup.c +++ b/arch/arm/mach-snapdragon/of_fixup.c @@ -99,6 +99,19 @@ static int fixup_qcom_dwc3(struct device_node *root, struct device_node *glue_np return ret; } + /* + * The RB1/2 boards only have a single USB controller and it's muxed between the type-C port + * and a USB hub. Since we can't do OTG in U-Boot properly we prefer to put it into host mode. + */ + if (of_device_is_compatible(root, "qcom,qrb4210-rb2", NULL, NULL) || + of_device_is_compatible(root, "qcom,qrb2210-rb1", NULL, NULL)) { + ret = of_write_prop(dwc3, "dr_mode", sizeof("host"), "host"); + if (ret) { + log_err("Failed to set 'dr_mode' property: %d\n", ret); + return ret; + } + } + return 0; } @@ -165,20 +178,7 @@ static int qcom_of_fixup_nodes(void * __maybe_unused ctx, struct event *event) EVENT_SPY_FULL(EVT_OF_LIVE_BUILT, qcom_of_fixup_nodes); -int ft_board_setup(void *blob, struct bd_info __maybe_unused *bd) +int ft_board_setup(void __maybe_unused *blob, struct bd_info __maybe_unused *bd) { - struct fdt_header *fdt = blob; - int node; - - /* On RB1/2 we need to fix-up the dr_mode */ - if (!fdt_node_check_compatible(fdt, 0, "qcom,qrb4210-rb2") || - !fdt_node_check_compatible(fdt, 0, "qcom,qrb2210-rb1")) { - fdt_for_each_node_by_compatible(node, blob, 0, "snps,dwc3") { - log_debug("%s: Setting 'dr_mode' to OTG\n", fdt_get_name(blob, node, NULL)); - fdt_setprop_string(fdt, node, "dr_mode", "otg"); - break; - } - } - return 0; } -- cgit v1.2.3 From 229fd3f9a8d4dbaad7c9a2e9c1b62d14d0753b0b Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Fri, 11 Apr 2025 14:47:44 +0200 Subject: clk/qcom: qcm2290: show clock name in set_rate() The device name is always clk_qcom... Not very useful. Reviewed-by: Sumit Garg Reviewed-by: Neil Armstrong Tested-by: Sumit Garg Signed-off-by: Caleb Connolly --- drivers/clk/qcom/clock-qcm2290.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/clock-qcm2290.c b/drivers/clk/qcom/clock-qcm2290.c index 1326b770c3e..fad104fb91a 100644 --- a/drivers/clk/qcom/clock-qcm2290.c +++ b/drivers/clk/qcom/clock-qcm2290.c @@ -88,7 +88,7 @@ static ulong qcm2290_set_rate(struct clk *clk, ulong rate) struct msm_clk_priv *priv = dev_get_priv(clk->dev); const struct freq_tbl *freq; - debug("%s: clk %s rate %lu\n", __func__, clk->dev->name, rate); + debug("%s: clk %s rate %lu\n", __func__, qcm2290_clks[clk->id].name, rate); switch (clk->id) { case GCC_QUPV3_WRAP0_S4_CLK: /*UART2*/ -- cgit v1.2.3 From 2803a466a96153ab01c5789321e48397b6bae9c7 Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Fri, 11 Apr 2025 14:47:45 +0200 Subject: pinctrl: qcom: qcm2290: fix off by 1 in pin_count There are 134 pins not 133, oops! This fixes the sdcard on the RB1 as the pins now all get configured correctly. Fixes: 0ecb8cfcb930 ("pinctrl: qcom: add qcm2290 pinctrl driver") Reviewed-by: Sumit Garg Reviewed-by: Neil Armstrong Tested-by: Sumit Garg Signed-off-by: Caleb Connolly --- drivers/pinctrl/qcom/pinctrl-qcm2290.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/qcom/pinctrl-qcm2290.c b/drivers/pinctrl/qcom/pinctrl-qcm2290.c index 0c2222ce663..84f76b63b93 100644 --- a/drivers/pinctrl/qcom/pinctrl-qcm2290.c +++ b/drivers/pinctrl/qcom/pinctrl-qcm2290.c @@ -45,7 +45,7 @@ static int qcm2290_get_function_mux(__maybe_unused unsigned int pin, unsigned in struct msm_pinctrl_data qcm2290_data = { .pin_data = { - .pin_count = 133, + .pin_count = 134, .special_pins_start = 127, }, .functions_count = ARRAY_SIZE(msm_pinctrl_functions), -- cgit v1.2.3