From: Mehmet Fide <[email protected]>

The driver keeps its own tables of PHY and controller base addresses
and reaches the anatop block through a hardcoded address, although the
device tree describes all three: the controller points at its PHY and
usbmisc nodes, and the PHY at its anatop.

Read them from there and drop the tables. The port number stays only
for the choice between PLL3 and PLL7, which the device tree does not
express, and now comes from the alias of the PHY node.

The usbmisc node already starts at the non-core registers, so the
driver no longer adds an offset to reach them.

Signed-off-by: Mehmet Fide <[email protected]>
---
Changes in v4:
- rebased on next
- dropped two comments that repeated the commit message
- reworded the commit message and took the note on the previous version
  out of it

 drivers/usb/host/ehci-vf.c | 135 ++++++++++++++++++++-----------------
 1 file changed, 72 insertions(+), 63 deletions(-)

diff --git a/drivers/usb/host/ehci-vf.c b/drivers/usb/host/ehci-vf.c
index e5f9ec0fdbb..b1cfad14b09 100644
--- a/drivers/usb/host/ehci-vf.c
+++ b/drivers/usb/host/ehci-vf.c
@@ -22,12 +22,9 @@
 #include <linux/delay.h>
 #include <usb/ehci-ci.h>
 #include <linux/libfdt.h>
-#include <fdtdec.h>
 
 #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 +36,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 +85,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 +118,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,63 +129,76 @@ 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 */
-};
-
-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;
-};
-
-static int vf_usb_of_to_plat(struct udevice *dev)
+static int vf_parse_dt_addrs(struct udevice *dev)
 {
        struct ehci_vf_priv_data *priv = dev_get_priv(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;
+       ofnode phy_node, misc_node, anatop_node;
+       fdt_addr_t addr;
+       int ret;
 
        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))
+       misc_node = ofnode_parse_phandle(dev_ofnode(dev), "fsl,usbmisc", 0);
+       if (!ofnode_valid(misc_node))
+               return -EINVAL;
+
+       anatop_node = ofnode_parse_phandle(phy_node, "fsl,anatop", 0);
+       if (!ofnode_valid(anatop_node))
+               return -EINVAL;
+
+       ret = ofnode_get_alias_seq(phy_node, dev->uclass->uc_drv->name,
+                                  &priv->portnr);
+       if (ret)
+               return ret;
+
+       addr = ofnode_get_addr(phy_node);
+       if (addr == FDT_ADDR_T_NONE)
+               return -EINVAL;
+       priv->phy_addr = (void __iomem *)addr;
+
+       addr = ofnode_get_addr(misc_node);
+       if (addr == FDT_ADDR_T_NONE)
                return -EINVAL;
+       priv->misc_addr = (void __iomem *)addr;
 
-       priv->portnr = i;
+       addr = ofnode_get_addr(anatop_node);
+       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)
+{
+       struct ehci_vf_priv_data *priv = dev_get_priv(dev);
+       const void *dt_blob = gd->fdt_blob;
+       int node = dev_of_offset(dev);
+       const char *mode;
+       int ret;
+
+       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 +250,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 +279,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.55.0

Reply via email to