* [PATCH 0/3] usb: ehci-vf: take the register bases from the device tree
@ 2026-08-19 9:37 Mehmet Fide
2026-08-19 9:37 ` [PATCH 1/3] usb: ehci-vf: remove the code path for a build without DM_USB Mehmet Fide
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Mehmet Fide @ 2026-08-19 9:37 UTC (permalink / raw)
To: Marek Vasut; +Cc: Tom Rini, u-boot, Mehmet Fide
From: Mehmet Fide <mehmet.fide@screeningeagle.com>
Marek asked, when he looked at the portnr fix, whether the index based
PHY handling could go away entirely in favour of parsing the addresses
from the device tree:
https://lore.kernel.org/u-boot/1a8642c2-58c8-45fb-a0b6-2ae91076e790@mailbox.org/
This is that follow-up. Patch 3 does it the way ehci-mx6 does: the
controller node points at its PHY and its usbmisc block, the PHY points
at the anatop, and all three addresses come from there, so both base
address tables are gone.
What is left of the index is a port number for the choice between PLL3
and PLL7, which the device tree does not describe. It no longer comes
from the sequence number of the controller but from the alias of the PHY
node, again as ehci-mx6 does.
Patches 1 and 2 remove dead code that stood in the way. The first is a
code path for a build without DM_USB that cannot be selected and does
not compile; the second an empty bind hook whose comment talks about
sequence numbers this driver no longer uses at all.
Tested on a Colibri VF50 V1.2A on an Iris carrier, U-Boot 2026.07 from
NAND.
Mehmet Fide (3):
usb: ehci-vf: remove the code path for a build without DM_USB
usb: ehci-vf: drop the empty bind hook
usb: ehci-vf: take the register bases from the device tree
drivers/usb/host/ehci-vf.c | 184 ++++++++++++++-----------------------
1 file changed, 69 insertions(+), 115 deletions(-)
--
2.54.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/3] usb: ehci-vf: remove the code path for a build without DM_USB
2026-08-19 9:37 [PATCH 0/3] usb: ehci-vf: take the register bases from the device tree Mehmet Fide
@ 2026-08-19 9:37 ` Mehmet Fide
2026-08-19 10:08 ` Marek Vasut
2026-08-19 9:37 ` [PATCH 2/3] usb: ehci-vf: drop the empty bind hook Mehmet Fide
2026-08-19 9:37 ` [PATCH 3/3] usb: ehci-vf: take the register bases from the device tree Mehmet Fide
2 siblings, 1 reply; 7+ messages in thread
From: Mehmet Fide @ 2026-08-19 9:37 UTC (permalink / raw)
To: Marek Vasut; +Cc: Tom Rini, u-boot, Mehmet Fide
From: Mehmet Fide <mehmet.fide@screeningeagle.com>
USB_EHCI_HCD selects DM_USB, so the !CONFIG_IS_ENABLED(DM_USB) branch of
this driver can never be selected. It also cannot compile: ehci_hcd_init()
calls ehci_vf_common_init() with one argument while the function takes
two, so the branch has been dead since the controller was added as a
second parameter.
Remove it, together with the board_usb_phy_mode() hook that no board
implements and nothing else calls.
Signed-off-by: Mehmet Fide <mehmet.fide@screeningeagle.com>
---
drivers/usb/host/ehci-vf.c | 49 --------------------------------------
1 file changed, 49 deletions(-)
diff --git a/drivers/usb/host/ehci-vf.c b/drivers/usb/host/ehci-vf.c
index 32fe05920d0..5d27318de62 100644
--- a/drivers/usb/host/ehci-vf.c
+++ b/drivers/usb/host/ehci-vf.c
@@ -128,11 +128,6 @@ static void usb_oc_config(int index)
setbits_le32(ctrl, UCTRL_OVER_CUR_DIS);
}
-int __weak board_usb_phy_mode(int port)
-{
- return 0;
-}
-
int __weak board_ehci_hcd_init(int port)
{
return 0;
@@ -155,49 +150,6 @@ int ehci_vf_common_init(struct usb_ehci *ehci, int index)
return 0;
}
-#if !CONFIG_IS_ENABLED(DM_USB)
-int ehci_hcd_init(int index, enum usb_init_type init,
- struct ehci_hccr **hccr, struct ehci_hcor **hcor)
-{
- struct usb_ehci *ehci;
- enum usb_init_type type;
- int ret;
-
- if (index >= ARRAY_SIZE(nc_reg_bases))
- return -EINVAL;
-
- ehci = (struct usb_ehci *)nc_reg_bases[index];
-
- ret = ehci_vf_common_init(index);
- if (ret)
- return ret;
-
- *hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
- *hcor = (struct ehci_hcor *)((uint32_t)*hccr +
- HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
-
- type = board_usb_phy_mode(index);
- if (type != init)
- return -ENODEV;
-
- if (init == USB_INIT_DEVICE) {
- setbits_le32(&ehci->usbmode, CM_DEVICE);
- writel((PORT_PTS_UTMI | PORT_PTS_PTW), &ehci->portsc);
- setbits_le32(&ehci->portsc, USB_EN);
- } else if (init == USB_INIT_HOST) {
- setbits_le32(&ehci->usbmode, CM_HOST);
- writel((PORT_PTS_UTMI | PORT_PTS_PTW), &ehci->portsc);
- setbits_le32(&ehci->portsc, USB_EN);
- }
-
- return 0;
-}
-
-int ehci_hcd_stop(int index)
-{
- return 0;
-}
-#else
/* Possible port types (dual role mode) */
enum dr_mode {
DR_MODE_NONE = 0,
@@ -372,4 +324,3 @@ U_BOOT_DRIVER(ehci_vf) = {
.priv_auto = sizeof(struct ehci_vf_priv_data),
.flags = DM_FLAG_ALLOC_PRIV_DMA,
};
-#endif
--
2.54.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/3] usb: ehci-vf: drop the empty bind hook
2026-08-19 9:37 [PATCH 0/3] usb: ehci-vf: take the register bases from the device tree Mehmet Fide
2026-08-19 9:37 ` [PATCH 1/3] usb: ehci-vf: remove the code path for a build without DM_USB Mehmet Fide
@ 2026-08-19 9:37 ` Mehmet Fide
2026-08-19 10:10 ` Marek Vasut
2026-08-19 9:37 ` [PATCH 3/3] usb: ehci-vf: take the register bases from the device tree Mehmet Fide
2 siblings, 1 reply; 7+ messages in thread
From: Mehmet Fide @ 2026-08-19 9:37 UTC (permalink / raw)
To: Marek Vasut; +Cc: Tom Rini, u-boot, Mehmet Fide
From: Mehmet Fide <mehmet.fide@screeningeagle.com>
vf_usb_bind() only returns 0. Its comment describes a hack that keeps
the second controller from taking sequence number 0, but no such code
is there, and an empty .bind cannot influence the numbering the uclass
does. Remove it.
Signed-off-by: Mehmet Fide <mehmet.fide@screeningeagle.com>
---
drivers/usb/host/ehci-vf.c | 15 ---------------
1 file changed, 15 deletions(-)
diff --git a/drivers/usb/host/ehci-vf.c b/drivers/usb/host/ehci-vf.c
index 5d27318de62..e5f9ec0fdbb 100644
--- a/drivers/usb/host/ehci-vf.c
+++ b/drivers/usb/host/ehci-vf.c
@@ -261,20 +261,6 @@ static const struct ehci_ops vf_ehci_ops = {
.init_after_reset = vf_init_after_reset
};
-static int vf_usb_bind(struct udevice *dev)
-{
- /*
- * Without this hack, if we return ENODEV for USB Controller 0, on
- * probe for the next controller, USB Controller 1 will be given a
- * sequence number of 0. This conflicts with our requirement of
- * sequence numbers while initialising the peripherals.
- *
- * FIXME: Check that this still works OK with the new sequence numbers
- */
-
- return 0;
-}
-
static int ehci_usb_probe(struct udevice *dev)
{
struct usb_plat *plat = dev_get_plat(dev);
@@ -315,7 +301,6 @@ U_BOOT_DRIVER(ehci_vf) = {
.name = "ehci_vf",
.id = UCLASS_USB,
.of_match = vf_usb_ids,
- .bind = vf_usb_bind,
.probe = ehci_usb_probe,
.remove = ehci_deregister,
.ops = &ehci_usb_ops,
--
2.54.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/3] usb: ehci-vf: take the register bases from the device tree
2026-08-19 9:37 [PATCH 0/3] usb: ehci-vf: take the register bases from the device tree Mehmet Fide
2026-08-19 9:37 ` [PATCH 1/3] usb: ehci-vf: remove the code path for a build without DM_USB Mehmet Fide
2026-08-19 9:37 ` [PATCH 2/3] usb: ehci-vf: drop the empty bind hook Mehmet Fide
@ 2026-08-19 9:37 ` Mehmet Fide
2026-08-19 19:50 ` Marek Vasut
2 siblings, 1 reply; 7+ messages in thread
From: Mehmet Fide @ 2026-08-19 9:37 UTC (permalink / raw)
To: Marek Vasut; +Cc: Tom Rini, u-boot, Mehmet Fide
From: Mehmet Fide <mehmet.fide@screeningeagle.com>
The driver keeps its own tables of PHY and controller base addresses and
indexes them with a port number, and it reaches the anatop block through
a hardcoded address. The device tree describes all three: the controller
points at its PHY and its usbmisc block, and the PHY points at the
anatop it uses.
Read them from there, as ehci-mx6 does, and drop the tables. The port
number stays for the one thing the device tree does not express, the
choice between PLL3 and PLL7, and it now comes from the alias of the PHY
node instead of the sequence number of the controller.
Note that the usbmisc node already starts at the non-core registers, so
the driver no longer adds an offset of its own to reach them.
Tested on a Colibri VF50 V1.2A on an Iris carrier, U-Boot 2026.07 from
NAND: "usb start" brings the host controller up and enumerates the root
hub, and the port that needs PLL7 is the one that works, so the port
number taken from the PHY alias is the right one.
Signed-off-by: Mehmet Fide <mehmet.fide@screeningeagle.com>
---
drivers/usb/host/ehci-vf.c | 142 +++++++++++++++++++++----------------
1 file changed, 80 insertions(+), 62 deletions(-)
diff --git a/drivers/usb/host/ehci-vf.c b/drivers/usb/host/ehci-vf.c
index e5f9ec0fdbb..fb305569a15 100644
--- a/drivers/usb/host/ehci-vf.c
+++ b/drivers/usb/host/ehci-vf.c
@@ -26,8 +26,6 @@
#include "ehci.h"
-#define USB_NC_REG_OFFSET 0x00000800
-
#define ANADIG_PLL_CTRL_EN_USB_CLKS (1 << 6)
#define UCTRL_OVER_CUR_POL (1 << 8) /* OTG Polarity of Overcurrent */
@@ -39,28 +37,33 @@
DECLARE_GLOBAL_DATA_PTR;
-static const unsigned phy_bases[] = {
- USB_PHY0_BASE_ADDR,
- USB_PHY1_BASE_ADDR,
+/* Possible port types (dual role mode) */
+enum dr_mode {
+ DR_MODE_NONE = 0,
+ DR_MODE_HOST, /* supports host operation */
+ DR_MODE_DEVICE, /* supports device operation */
+ DR_MODE_OTG, /* supports both */
};
-static const unsigned nc_reg_bases[] = {
- USBC0_BASE_ADDR,
- USBC1_BASE_ADDR,
+struct ehci_vf_priv_data {
+ struct ehci_ctrl ctrl;
+ struct usb_ehci *ehci;
+ struct gpio_desc cdet_gpio;
+ enum usb_init_type init_type;
+ enum dr_mode dr_mode;
+ struct anadig_reg __iomem *anatop_addr;
+ void __iomem *phy_addr;
+ void __iomem *misc_addr;
+ int portnr;
};
-static void usb_internal_phy_clock_gate(int index)
+static void usb_internal_phy_clock_gate(void __iomem *phy_reg)
{
- void __iomem *phy_reg;
-
- phy_reg = (void __iomem *)phy_bases[index];
clrbits_le32(phy_reg + USBPHY_CTRL, USBPHY_CTRL_CLKGATE);
}
-static void usb_power_config(int index)
+static void usb_power_config(struct anadig_reg __iomem *anadig, int index)
{
- struct anadig_reg __iomem *anadig =
- (struct anadig_reg __iomem *)ANADIG_BASE_ADDR;
void __iomem *pll_ctrl;
switch (index) {
@@ -83,13 +86,11 @@ static void usb_power_config(int index)
}
}
-static void usb_phy_enable(int index, struct usb_ehci *ehci)
+static void usb_phy_enable(void __iomem *phy_reg, struct usb_ehci *ehci)
{
- void __iomem *phy_reg;
void __iomem *phy_ctrl;
void __iomem *usb_cmd;
- phy_reg = (void __iomem *)phy_bases[index];
phy_ctrl = (void __iomem *)(phy_reg + USBPHY_CTRL);
usb_cmd = (void __iomem *)&ehci->usbcmd;
@@ -118,12 +119,8 @@ static void usb_phy_enable(int index, struct usb_ehci *ehci)
USBPHY_CTRL_ENUTMILEVEL3);
}
-static void usb_oc_config(int index)
+static void usb_oc_config(void __iomem *ctrl)
{
- void __iomem *ctrl;
-
- ctrl = (void __iomem *)(nc_reg_bases[index] + USB_NC_REG_OFFSET);
-
setbits_le32(ctrl, UCTRL_OVER_CUR_POL);
setbits_le32(ctrl, UCTRL_OVER_CUR_DIS);
}
@@ -133,39 +130,72 @@ int __weak board_ehci_hcd_init(int port)
return 0;
}
-int ehci_vf_common_init(struct usb_ehci *ehci, int index)
+static int ehci_vf_common_init(struct ehci_vf_priv_data *priv)
{
int ret;
/* Do board specific initialisation */
- ret = board_ehci_hcd_init(index);
+ ret = board_ehci_hcd_init(priv->portnr);
if (ret)
return ret;
- usb_power_config(index);
- usb_oc_config(index);
- usb_internal_phy_clock_gate(index);
- usb_phy_enable(index, ehci);
+ usb_power_config(priv->anatop_addr, priv->portnr);
+ usb_oc_config(priv->misc_addr);
+ usb_internal_phy_clock_gate(priv->phy_addr);
+ usb_phy_enable(priv->phy_addr, priv->ehci);
return 0;
}
-/* Possible port types (dual role mode) */
-enum dr_mode {
- DR_MODE_NONE = 0,
- DR_MODE_HOST, /* supports host operation */
- DR_MODE_DEVICE, /* supports device operation */
- DR_MODE_OTG, /* supports both */
-};
+static int vf_parse_dt_addrs(struct udevice *dev)
+{
+ struct ehci_vf_priv_data *priv = dev_get_priv(dev);
+ const void *blob = gd->fdt_blob;
+ int offset = dev_of_offset(dev);
+ int phy_off, misc_off, anatop_off;
+ int ret, devnump;
+ fdt_addr_t addr;
+
+ phy_off = fdtdec_lookup_phandle(blob, offset, "fsl,usbphy");
+ if (phy_off < 0)
+ return -EINVAL;
-struct ehci_vf_priv_data {
- struct ehci_ctrl ctrl;
- struct usb_ehci *ehci;
- struct gpio_desc cdet_gpio;
- enum usb_init_type init_type;
- enum dr_mode dr_mode;
- u32 portnr;
-};
+ misc_off = fdtdec_lookup_phandle(blob, offset, "fsl,usbmisc");
+ if (misc_off < 0)
+ return -EINVAL;
+
+ /* Resolve ANATOP offset through USB PHY node */
+ anatop_off = fdtdec_lookup_phandle(blob, phy_off, "fsl,anatop");
+ if (anatop_off < 0)
+ return -EINVAL;
+
+ /*
+ * The PHYs are the only USB nodes the device tree gives an alias, and
+ * their numbering is the port numbering the PLL selection needs.
+ */
+ ret = fdtdec_get_alias_seq(blob, dev->uclass->uc_drv->name, phy_off,
+ &devnump);
+ if (ret < 0)
+ return ret;
+ priv->portnr = devnump;
+
+ addr = fdtdec_get_addr(blob, phy_off, "reg");
+ if (addr == FDT_ADDR_T_NONE)
+ return -EINVAL;
+ priv->phy_addr = (void __iomem *)addr;
+
+ addr = fdtdec_get_addr(blob, misc_off, "reg");
+ if (addr == FDT_ADDR_T_NONE)
+ return -EINVAL;
+ priv->misc_addr = (void __iomem *)addr;
+
+ addr = fdtdec_get_addr(blob, anatop_off, "reg");
+ if (addr == FDT_ADDR_T_NONE)
+ return -EINVAL;
+ priv->anatop_addr = (struct anadig_reg __iomem *)addr;
+
+ return 0;
+}
static int vf_usb_of_to_plat(struct udevice *dev)
{
@@ -173,23 +203,11 @@ static int vf_usb_of_to_plat(struct udevice *dev)
const void *dt_blob = gd->fdt_blob;
int node = dev_of_offset(dev);
const char *mode;
- fdt_addr_t phy_addr;
- ofnode phy_node;
- int i;
-
- phy_node = ofnode_parse_phandle(dev_ofnode(dev), "fsl,usbphy", 0);
- if (!ofnode_valid(phy_node))
- return -EINVAL;
-
- phy_addr = ofnode_get_addr(phy_node);
- for (i = 0; i < ARRAY_SIZE(phy_bases); i++) {
- if (phy_addr == phy_bases[i])
- break;
- }
- if (i == ARRAY_SIZE(phy_bases))
- return -EINVAL;
+ int ret;
- priv->portnr = i;
+ ret = vf_parse_dt_addrs(dev);
+ if (ret)
+ return ret;
priv->ehci = dev_read_addr_ptr(dev);
mode = fdt_getprop(dt_blob, node, "dr_mode", NULL);
@@ -241,7 +259,7 @@ static int vf_init_after_reset(struct ehci_ctrl *dev)
struct usb_ehci *ehci = priv->ehci;
int ret;
- ret = ehci_vf_common_init(priv->ehci, priv->portnr);
+ ret = ehci_vf_common_init(priv);
if (ret)
return ret;
@@ -270,7 +288,7 @@ static int ehci_usb_probe(struct udevice *dev)
struct ehci_hcor *hcor;
int ret;
- ret = ehci_vf_common_init(ehci, priv->portnr);
+ ret = ehci_vf_common_init(priv);
if (ret)
return ret;
--
2.54.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/3] usb: ehci-vf: remove the code path for a build without DM_USB
2026-08-19 9:37 ` [PATCH 1/3] usb: ehci-vf: remove the code path for a build without DM_USB Mehmet Fide
@ 2026-08-19 10:08 ` Marek Vasut
0 siblings, 0 replies; 7+ messages in thread
From: Marek Vasut @ 2026-08-19 10:08 UTC (permalink / raw)
To: Mehmet Fide, Marek Vasut; +Cc: Tom Rini, u-boot, Mehmet Fide
On 8/19/26 11:37 AM, Mehmet Fide wrote:
> From: Mehmet Fide <mehmet.fide@screeningeagle.com>
>
> USB_EHCI_HCD selects DM_USB, so the !CONFIG_IS_ENABLED(DM_USB) branch of
> this driver can never be selected. It also cannot compile: ehci_hcd_init()
> calls ehci_vf_common_init() with one argument while the function takes
> two, so the branch has been dead since the controller was added as a
> second parameter.
>
> Remove it, together with the board_usb_phy_mode() hook that no board
> implements and nothing else calls.
>
> Signed-off-by: Mehmet Fide <mehmet.fide@screeningeagle.com>
Could you please double-check that this is not used in SPL without DM_USB ?
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/3] usb: ehci-vf: drop the empty bind hook
2026-08-19 9:37 ` [PATCH 2/3] usb: ehci-vf: drop the empty bind hook Mehmet Fide
@ 2026-08-19 10:10 ` Marek Vasut
0 siblings, 0 replies; 7+ messages in thread
From: Marek Vasut @ 2026-08-19 10:10 UTC (permalink / raw)
To: Mehmet Fide, Simon Glass; +Cc: Tom Rini, u-boot, Mehmet Fide
On 8/19/26 11:37 AM, Mehmet Fide wrote:
> From: Mehmet Fide <mehmet.fide@screeningeagle.com>
>
> vf_usb_bind() only returns 0. Its comment describes a hack that keeps
> the second controller from taking sequence number 0, but no such code
> is there, and an empty .bind cannot influence the numbering the uclass
> does. Remove it.
This likely fixes these two commits:
0885cdb9d154 ("usb: host: ehci-vf: Migrate Vybrid USB to driver model")
b27347f425f7 ("usb: Update for new sequence numbers")
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 3/3] usb: ehci-vf: take the register bases from the device tree
2026-08-19 9:37 ` [PATCH 3/3] usb: ehci-vf: take the register bases from the device tree Mehmet Fide
@ 2026-08-19 19:50 ` Marek Vasut
0 siblings, 0 replies; 7+ messages in thread
From: Marek Vasut @ 2026-08-19 19:50 UTC (permalink / raw)
To: Mehmet Fide, Marek Vasut; +Cc: Tom Rini, u-boot, Mehmet Fide
On 8/19/26 11:37 AM, Mehmet Fide wrote:
[...]
> + misc_off = fdtdec_lookup_phandle(blob, offset, "fsl,usbmisc");
Please avoid fdtdec_*() functions if at all possible.
Either use dev_read_addr() or a variant thereof, or , a variant of
of_get_address() .
> + if (misc_off < 0)
> + return -EINVAL;
[...]
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-08-20 3:55 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-19 9:37 [PATCH 0/3] usb: ehci-vf: take the register bases from the device tree Mehmet Fide
2026-08-19 9:37 ` [PATCH 1/3] usb: ehci-vf: remove the code path for a build without DM_USB Mehmet Fide
2026-08-19 10:08 ` Marek Vasut
2026-08-19 9:37 ` [PATCH 2/3] usb: ehci-vf: drop the empty bind hook Mehmet Fide
2026-08-19 10:10 ` Marek Vasut
2026-08-19 9:37 ` [PATCH 3/3] usb: ehci-vf: take the register bases from the device tree Mehmet Fide
2026-08-19 19:50 ` Marek Vasut
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.