[U-Boot] [PATCH V2 1/3] usb: ehci-mx6: implement ofdata_to_platdata

Implement ofdata_to_platdata to set the type to host or device. - Check "dr-mode" property. - If there is no "dr-mode", check phy_ctrl for i.MX6 and phy_status for i.MX7
Signed-off-by: Peng Fan peng.fan@nxp.com Cc: Marek Vasut marex@denx.de Cc: Simon Glass sjg@chromium.org Cc: Stefano Babic sbabic@denx.de ---
V2: Add a ehci_usb_phy_mode function to check phy mode when dr-mode is otg, or no mode property provided.
drivers/usb/host/ehci-mx6.c | 75 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+)
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c index 48889c1..18b7fc3 100644 --- a/drivers/usb/host/ehci-mx6.c +++ b/drivers/usb/host/ehci-mx6.c @@ -15,10 +15,13 @@ #include <asm/arch/imx-regs.h> #include <asm/arch/clock.h> #include <asm/imx-common/iomux-v3.h> +#include <asm/imx-common/sys_proto.h> #include <dm.h>
#include "ehci.h"
+DECLARE_GLOBAL_DATA_PTR; + #define USB_OTGREGS_OFFSET 0x000 #define USB_H1REGS_OFFSET 0x200 #define USB_H2REGS_OFFSET 0x400 @@ -48,6 +51,7 @@ #define ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS 0x00000040
#define USBNC_OFFSET 0x200 +#define USBNC_PHY_STATUS_OFFSET 0x23C #define USBNC_PHYSTATUS_ID_DIG (1 << 4) /* otg_id status */ #define USBNC_PHYCFG2_ACAENB (1 << 4) /* otg_id detection enable */ #define UCTRL_PWR_POL (1 << 9) /* OTG Polarity of Power Pin */ @@ -417,6 +421,76 @@ static const struct ehci_ops mx6_ehci_ops = { .init_after_reset = mx6_init_after_reset };
+static int ehci_usb_phy_mode(struct udevice *dev) +{ + struct usb_platdata *plat = dev_get_platdata(dev); + void *__iomem addr = (void *__iomem)dev_get_addr(dev); + void *__iomem phy_ctrl, *__iomem phy_status; + const void *blob = gd->fdt_blob; + int offset = dev->of_offset, phy_off; + u32 val; + + /* + * About fsl,usbphy, Refer to + * Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt. + */ + if (is_mx6()) { + phy_off = fdtdec_lookup_phandle(blob, + offset, + "fsl,usbphy"); + if (phy_off < 0) + return -EINVAL; + + addr = (void __iomem *)fdtdec_get_addr(blob, phy_off, + "reg"); + if ((fdt_addr_t)addr == FDT_ADDR_T_NONE) + return -EINVAL; + + phy_ctrl = (void __iomem *)(addr + USBPHY_CTRL); + val = readl(phy_ctrl); + + if (val & USBPHY_CTRL_OTG_ID) + plat->init_type = USB_INIT_DEVICE; + else + plat->init_type = USB_INIT_HOST; + } else if (is_mx7()) { + phy_status = (void __iomem *)(addr + + USBNC_PHY_STATUS_OFFSET); + val = readl(phy_status); + + if (val & USBNC_PHYSTATUS_ID_DIG) + plat->init_type = USB_INIT_DEVICE; + else + plat->init_type = USB_INIT_HOST; + } else { + return -EINVAL; + } + + return 0; +} + +static int ehci_usb_ofdata_to_platdata(struct udevice *dev) +{ + struct usb_platdata *plat = dev_get_platdata(dev); + const char *mode; + + mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "dr_mode", NULL); + if (mode) { + if (strcmp(mode, "peripheral") == 0) + plat->init_type = USB_INIT_DEVICE; + else if (strcmp(mode, "host") == 0) + plat->init_type = USB_INIT_HOST; + else if (strcmp(mode, "otg") == 0) + return ehci_usb_phy_mode(dev); + else + return -EINVAL; + + return 0; + } + + return ehci_usb_phy_mode(dev); +} + static int ehci_usb_probe(struct udevice *dev) { struct usb_platdata *plat = dev_get_platdata(dev); @@ -460,6 +534,7 @@ U_BOOT_DRIVER(usb_mx6) = { .name = "ehci_mx6", .id = UCLASS_USB, .of_match = mx6_usb_ids, + .ofdata_to_platdata = ehci_usb_ofdata_to_platdata, .probe = ehci_usb_probe, .remove = ehci_deregister, .ops = &ehci_usb_ops,

Drop board_ehci_power when dm usb used and switch to use regulator api to handle vbus.
Signed-off-by: Peng Fan peng.fan@nxp.com Cc: Marek Vasut marex@denx.de Cc: Simon Glass sjg@chromium.org Cc: Stefano Babic sbabic@denx.de ---
V2: None
drivers/usb/host/ehci-mx6.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c index 18b7fc3..7b309b7 100644 --- a/drivers/usb/host/ehci-mx6.c +++ b/drivers/usb/host/ehci-mx6.c @@ -17,6 +17,7 @@ #include <asm/imx-common/iomux-v3.h> #include <asm/imx-common/sys_proto.h> #include <dm.h> +#include <power/regulator.h>
#include "ehci.h"
@@ -388,6 +389,7 @@ int ehci_hcd_stop(int index) struct ehci_mx6_priv_data { struct ehci_ctrl ctrl; struct usb_ehci *ehci; + struct udevice *vbus_supply; enum usb_init_type init_type; int portnr; }; @@ -403,7 +405,15 @@ static int mx6_init_after_reset(struct ehci_ctrl *dev) if (ret) return ret;
- board_ehci_power(priv->portnr, (type == USB_INIT_DEVICE) ? 0 : 1); + if (priv->vbus_supply) { + ret = regulator_set_enable(priv->vbus_supply, + (type == USB_INIT_DEVICE) ? + false : true); + if (ret) { + puts("Error enabling VBUS supply\n"); + return ret; + } + }
if (type == USB_INIT_DEVICE) return 0; @@ -496,19 +506,33 @@ static int ehci_usb_probe(struct udevice *dev) struct usb_platdata *plat = dev_get_platdata(dev); struct usb_ehci *ehci = (struct usb_ehci *)dev_get_addr(dev); struct ehci_mx6_priv_data *priv = dev_get_priv(dev); + enum usb_init_type type = plat->init_type; struct ehci_hccr *hccr; struct ehci_hcor *hcor; int ret;
priv->ehci = ehci; priv->portnr = dev->seq; - priv->init_type = plat->init_type; + priv->init_type = type; + + ret = device_get_supply_regulator(dev, "vbus-supply", + &priv->vbus_supply); + if (ret) + debug("%s: No vbus supply\n", dev->name);
ret = ehci_mx6_common_init(ehci, priv->portnr); if (ret) return ret;
- board_ehci_power(priv->portnr, (priv->init_type == USB_INIT_DEVICE) ? 0 : 1); + if (priv->vbus_supply) { + ret = regulator_set_enable(priv->vbus_supply, + (type == USB_INIT_DEVICE) ? + false : true); + if (ret) { + puts("Error enabling VBUS supply\n"); + return ret; + } + }
if (priv->init_type == USB_INIT_HOST) { setbits_le32(&ehci->usbmode, CM_HOST);

On 12/22/2016 10:06 AM, Peng Fan wrote:
Drop board_ehci_power when dm usb used and switch to use regulator api to handle vbus.
Signed-off-by: Peng Fan peng.fan@nxp.com Cc: Marek Vasut marex@denx.de Cc: Simon Glass sjg@chromium.org Cc: Stefano Babic sbabic@denx.de
Acked-by: Marek Vasut marex@denx.de
I'd like a R-B from Simon on this one.

On 22 December 2016 at 22:19, Marek Vasut marex@denx.de wrote:
On 12/22/2016 10:06 AM, Peng Fan wrote:
Drop board_ehci_power when dm usb used and switch to use regulator api to handle vbus.
Signed-off-by: Peng Fan peng.fan@nxp.com Cc: Marek Vasut marex@denx.de Cc: Simon Glass sjg@chromium.org Cc: Stefano Babic sbabic@denx.de
Acked-by: Marek Vasut marex@denx.de
I'd like a R-B from Simon on this one.
-- Best regards, Marek Vasut
Reviewed-by: Simon Glass sjg@chromium.org
But I think we are supposed to use printf() instead of puts(), and you might include the error number too.
Regards, Simon

Add usb support for mx6sllevk board.
Signed-off-by: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de ---
V2: Drop the polarity setting and CONFIG_USB_MAX_CONTROLLER_COUNT
configs/mx6sllevk_defconfig | 5 +++++ configs/mx6sllevk_plugin_defconfig | 5 +++++ include/configs/mx6sllevk.h | 8 ++++++++ 3 files changed, 18 insertions(+)
diff --git a/configs/mx6sllevk_defconfig b/configs/mx6sllevk_defconfig index 8ae049e..267cdc6 100644 --- a/configs/mx6sllevk_defconfig +++ b/configs/mx6sllevk_defconfig @@ -10,6 +10,7 @@ CONFIG_CMD_BOOTZ=y CONFIG_CMD_MEMTEST=y CONFIG_CMD_MMC=y CONFIG_CMD_I2C=y +CONFIG_CMD_USB=y CONFIG_CMD_GPIO=y CONFIG_CMD_DHCP=y CONFIG_CMD_PING=y @@ -34,3 +35,7 @@ CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_PFUZE100=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_GPIO=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_STORAGE=y diff --git a/configs/mx6sllevk_plugin_defconfig b/configs/mx6sllevk_plugin_defconfig index e6be979..63d5bbc 100644 --- a/configs/mx6sllevk_plugin_defconfig +++ b/configs/mx6sllevk_plugin_defconfig @@ -11,6 +11,7 @@ CONFIG_CMD_BOOTZ=y CONFIG_CMD_MEMTEST=y CONFIG_CMD_MMC=y CONFIG_CMD_I2C=y +CONFIG_CMD_USB=y CONFIG_CMD_GPIO=y CONFIG_CMD_DHCP=y CONFIG_CMD_PING=y @@ -35,3 +36,7 @@ CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_PFUZE100=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_GPIO=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_STORAGE=y diff --git a/include/configs/mx6sllevk.h b/include/configs/mx6sllevk.h index b9f25cf..be4d147 100644 --- a/include/configs/mx6sllevk.h +++ b/include/configs/mx6sllevk.h @@ -149,4 +149,12 @@
#define CONFIG_IOMUX_LPSR
+/* USB Configs */ +#ifdef CONFIG_CMD_USB +#define CONFIG_USB_HOST_ETHER +#define CONFIG_USB_ETHER_ASIX +#define CONFIG_USB_ETHER_RTL8152 +#define CONFIG_MXC_USB_PORTSC (PORT_PTS_UTMI | PORT_PTS_PTW) +#endif + #endif /* __CONFIG_H */

On 12/22/2016 10:06 AM, Peng Fan wrote:
Implement ofdata_to_platdata to set the type to host or device.
- Check "dr-mode" property.
- If there is no "dr-mode", check phy_ctrl for i.MX6 and phy_status for i.MX7
Signed-off-by: Peng Fan peng.fan@nxp.com Cc: Marek Vasut marex@denx.de Cc: Simon Glass sjg@chromium.org Cc: Stefano Babic sbabic@denx.de
V2: Add a ehci_usb_phy_mode function to check phy mode when dr-mode is otg, or no mode property provided.
drivers/usb/host/ehci-mx6.c | 75 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+)
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c index 48889c1..18b7fc3 100644 --- a/drivers/usb/host/ehci-mx6.c +++ b/drivers/usb/host/ehci-mx6.c @@ -15,10 +15,13 @@ #include <asm/arch/imx-regs.h> #include <asm/arch/clock.h> #include <asm/imx-common/iomux-v3.h> +#include <asm/imx-common/sys_proto.h> #include <dm.h>
#include "ehci.h"
+DECLARE_GLOBAL_DATA_PTR;
#define USB_OTGREGS_OFFSET 0x000 #define USB_H1REGS_OFFSET 0x200 #define USB_H2REGS_OFFSET 0x400 @@ -48,6 +51,7 @@ #define ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS 0x00000040
#define USBNC_OFFSET 0x200 +#define USBNC_PHY_STATUS_OFFSET 0x23C #define USBNC_PHYSTATUS_ID_DIG (1 << 4) /* otg_id status */ #define USBNC_PHYCFG2_ACAENB (1 << 4) /* otg_id detection enable */ #define UCTRL_PWR_POL (1 << 9) /* OTG Polarity of Power Pin */ @@ -417,6 +421,76 @@ static const struct ehci_ops mx6_ehci_ops = { .init_after_reset = mx6_init_after_reset };
+static int ehci_usb_phy_mode(struct udevice *dev) +{
- struct usb_platdata *plat = dev_get_platdata(dev);
- void *__iomem addr = (void *__iomem)dev_get_addr(dev);
- void *__iomem phy_ctrl, *__iomem phy_status;
- const void *blob = gd->fdt_blob;
- int offset = dev->of_offset, phy_off;
- u32 val;
- /*
* About fsl,usbphy, Refer to
* Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt.
*/
- if (is_mx6()) {
phy_off = fdtdec_lookup_phandle(blob,
offset,
"fsl,usbphy");
This could be on a single line IMO.
if (phy_off < 0)
return -EINVAL;
addr = (void __iomem *)fdtdec_get_addr(blob, phy_off,
"reg");
Same here, shouldn't be over 80.
Otherwise: Acked-by: Marek Vasut marex@denx.de
if ((fdt_addr_t)addr == FDT_ADDR_T_NONE)
return -EINVAL;
phy_ctrl = (void __iomem *)(addr + USBPHY_CTRL);
val = readl(phy_ctrl);
if (val & USBPHY_CTRL_OTG_ID)
plat->init_type = USB_INIT_DEVICE;
else
plat->init_type = USB_INIT_HOST;
- } else if (is_mx7()) {
phy_status = (void __iomem *)(addr +
USBNC_PHY_STATUS_OFFSET);
val = readl(phy_status);
if (val & USBNC_PHYSTATUS_ID_DIG)
plat->init_type = USB_INIT_DEVICE;
else
plat->init_type = USB_INIT_HOST;
- } else {
return -EINVAL;
- }
- return 0;
+}
+static int ehci_usb_ofdata_to_platdata(struct udevice *dev) +{
- struct usb_platdata *plat = dev_get_platdata(dev);
- const char *mode;
- mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "dr_mode", NULL);
- if (mode) {
if (strcmp(mode, "peripheral") == 0)
plat->init_type = USB_INIT_DEVICE;
else if (strcmp(mode, "host") == 0)
plat->init_type = USB_INIT_HOST;
else if (strcmp(mode, "otg") == 0)
return ehci_usb_phy_mode(dev);
else
return -EINVAL;
return 0;
- }
- return ehci_usb_phy_mode(dev);
+}
static int ehci_usb_probe(struct udevice *dev) { struct usb_platdata *plat = dev_get_platdata(dev); @@ -460,6 +534,7 @@ U_BOOT_DRIVER(usb_mx6) = { .name = "ehci_mx6", .id = UCLASS_USB, .of_match = mx6_usb_ids,
- .ofdata_to_platdata = ehci_usb_ofdata_to_platdata, .probe = ehci_usb_probe, .remove = ehci_deregister, .ops = &ehci_usb_ops,

On 22 December 2016 at 22:06, Peng Fan peng.fan@nxp.com wrote:
Implement ofdata_to_platdata to set the type to host or device.
- Check "dr-mode" property.
- If there is no "dr-mode", check phy_ctrl for i.MX6 and phy_status for i.MX7
Signed-off-by: Peng Fan peng.fan@nxp.com Cc: Marek Vasut marex@denx.de Cc: Simon Glass sjg@chromium.org Cc: Stefano Babic sbabic@denx.de
V2: Add a ehci_usb_phy_mode function to check phy mode when dr-mode is otg, or no mode property provided.
drivers/usb/host/ehci-mx6.c | 75 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org

On 12/26/2016 06:24 AM, Simon Glass wrote:
On 22 December 2016 at 22:06, Peng Fan peng.fan@nxp.com wrote:
Implement ofdata_to_platdata to set the type to host or device.
- Check "dr-mode" property.
- If there is no "dr-mode", check phy_ctrl for i.MX6 and phy_status for i.MX7
Signed-off-by: Peng Fan peng.fan@nxp.com Cc: Marek Vasut marex@denx.de Cc: Simon Glass sjg@chromium.org Cc: Stefano Babic sbabic@denx.de
V2: Add a ehci_usb_phy_mode function to check phy mode when dr-mode is otg, or no mode property provided.
drivers/usb/host/ehci-mx6.c | 75 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org
Applied all to u-boot-usb/next , thanks.
participants (3)
-
Marek Vasut
-
Peng Fan
-
Simon Glass