summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2025-05-02 08:38:27 -0600
committerTom Rini <trini@konsulko.com>2025-05-02 08:38:27 -0600
commit4ca87fd18c1b718be423755939a6e5b1688869f5 (patch)
tree4e233038a1826a39b6ef4c50262943881bdf5527
parentad60d979289650659cc6e158228d2049636215b0 (diff)
parent2803a466a96153ab01c5789321e48397b6bae9c7 (diff)
Merge patch series "Qualcomm: cleanup OF_LIVE fixup and fix RB1/2"
Caleb Connolly <caleb.connolly@linaro.org> says: Introduce a new event to signal that the live tree has been built, allowing boards to perform fixups on the tree before devices are bound. Crucially this allows for devices to be enabled or disabled, but also allows for properties that are parsed during the bind stage to be modified (such as dr_mode for dwc3). With this in place, mach-snapdragon is switched over to use the event and some hacky U-Boot specific DT overrides (which had to be undone prior to booting an image) are removed in favour of fixing up the livetree (which is not passed on to further boot stages). Finally, some minor fixes are made for the QCM2290 RB1 board, the sdcard is enabled and it now uses USB host mode in U-Boot like it's bigger sibling the RB2. Link: https://lore.kernel.org/r/20250411-livetree-fixup-v2-0-1236823377bb@linaro.org
-rw-r--r--arch/arm/dts/qrb4210-rb2-u-boot.dtsi6
-rw-r--r--arch/arm/mach-snapdragon/board.c1
-rw-r--r--arch/arm/mach-snapdragon/of_fixup.c69
-rw-r--r--arch/arm/mach-snapdragon/qcom-priv.h14
-rw-r--r--common/event.c3
-rw-r--r--drivers/clk/qcom/clock-qcm2290.c2
-rw-r--r--drivers/pinctrl/qcom/pinctrl-qcm2290.c2
-rw-r--r--include/event.h18
-rw-r--r--lib/of_live.c11
9 files changed, 73 insertions, 53 deletions
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/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..b398c6b7b9f 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,
@@ -22,6 +21,7 @@
#include <dt-bindings/input/linux-event-codes.h>
#include <dm/of_access.h>
#include <dm/of.h>
+#include <event.h>
#include <fdt_support.h>
#include <linux/errno.h>
#include <stdlib.h>
@@ -32,7 +32,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;
@@ -72,11 +72,12 @@ static int fixup_qcom_dwc3(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);
@@ -98,30 +99,45 @@ static int fixup_qcom_dwc3(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;
}
-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"))) {
- 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);
}
}
/* 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 +149,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,26 +166,19 @@ 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;
}
-int ft_board_setup(void *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;
- }
- }
+EVENT_SPY_FULL(EVT_OF_LIVE_BUILT, qcom_of_fixup_nodes);
+int ft_board_setup(void __maybe_unused *blob, struct bd_info __maybe_unused *bd)
+{
return 0;
}
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__ */
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/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*/
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),
diff --git a/include/event.h b/include/event.h
index 75141a192a4..1d267f1d105 100644
--- a/include/event.h
+++ b/include/event.h
@@ -154,6 +154,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
* looping over all event classes.
@@ -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 <abuf.h>
+#include <event.h>
#include <log.h>
#include <linux/libfdt.h>
#include <of_live.h>
@@ -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;
}