[U-Boot] [RFC] usb: musb-new: omap2430: Enable DM_USB and OF support
Adam Ford
aford173 at gmail.com
Sun Jul 22 16:45:09 UTC 2018
With upcoming changes that require CONFIG_BLK, this broke
USB Mass Storage on the OMAP3 boards because if CONFIG_BLK is
enabled, it assumes that DM_USB is enabled, but it wasn't yet
available on omap3 and omap4 boards.
This patch converts the OMAP2430 MUSB glue to support DM_USB and
extracts the necessary information based on the device tree.
It's based on the ti-musb driver, but there are enough significant
differences in both the architecture and device tree entires between
am33xx and OMAP3/OMAP4, that I think it makes sense to continue to
keep the separate.
This RFC has functional USB Host working, but it's hard coded to be
host or peripheral based on the config file. Unfortunately,
USB Peripherals like fastboot, etc don't appear to be
working at all. At least on omap3_logic (DM3730/OMAP35xx).
Any suggestions are appreciated in how to setup the MUSB in OTG mode
and get it to start USB in either host or gadget mode.
Unless an OTG adapter is connected with a USB device, the only message
I get when issing 'usb start' is
USB0: Port not available.
Signed-off-by: Adam Ford <aford173 at gmail.com>
diff --git a/drivers/usb/musb-new/omap2430.c b/drivers/usb/musb-new/omap2430.c
index fd63c07789..8b56e1a42a 100644
--- a/drivers/usb/musb-new/omap2430.c
+++ b/drivers/usb/musb-new/omap2430.c
@@ -9,14 +9,18 @@
* This file is part of the Inventra Controller Driver for Linux.
*/
#include <common.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <linux/usb/otg.h>
#include <asm/omap_common.h>
#include <asm/omap_musb.h>
#include <twl4030.h>
#include <twl6030.h>
#include "linux-compat.h"
-
#include "musb_core.h"
#include "omap2430.h"
+#include "musb_uboot.h"
static inline void omap2430_low_level_exit(struct musb *musb)
{
@@ -43,6 +47,7 @@ static int omap2430_musb_init(struct musb *musb)
u32 l;
int status = 0;
unsigned long int start;
+
struct omap_musb_board_data *data =
(struct omap_musb_board_data *)musb->controller;
@@ -129,3 +134,144 @@ const struct musb_platform_ops omap2430_ops = {
.enable = omap2430_musb_enable,
.disable = omap2430_musb_disable,
};
+
+#if defined(CONFIG_DM_USB)
+
+struct omap2430_musb_platdata {
+ void *base;
+ void *ctrl_mod_base;
+ struct musb_hdrc_platform_data plat;
+ struct musb_hdrc_config musb_config;
+ struct omap_musb_board_data otg_board_data;
+};
+
+static int omap2430_musb_ofdata_to_platdata(struct udevice *dev)
+{
+ struct omap2430_musb_platdata *platdata = dev_get_platdata(dev);
+ const void *fdt = gd->fdt_blob;
+ int node = dev_of_offset(dev);
+
+ platdata->base = (void *)dev_read_addr_ptr(dev);
+
+ platdata->musb_config.multipoint = fdtdec_get_int(fdt, node,
+ "multipoint",
+ -1);
+ if (platdata->musb_config.multipoint < 0) {
+ pr_err("MUSB multipoint DT entry missing\n");
+ return -ENOENT;
+ }
+
+ platdata->musb_config.dyn_fifo = 1;
+ platdata->musb_config.num_eps = fdtdec_get_int(fdt, node,
+ "num-eps", -1);
+ if (platdata->musb_config.num_eps < 0) {
+ pr_err("MUSB num-eps DT entry missing\n");
+ return -ENOENT;
+ }
+
+ platdata->musb_config.ram_bits = fdtdec_get_int(fdt, node,
+ "ram-bits", -1);
+ if (platdata->musb_config.ram_bits < 0) {
+ pr_err("MUSB ram-bits DT entry missing\n");
+ return -ENOENT;
+ }
+
+ platdata->plat.power = fdtdec_get_int(fdt, node,
+ "power", -1);
+ if (platdata->plat.power < 0) {
+ pr_err("MUSB power DT entry missing\n");
+ return -ENOENT;
+ }
+
+ platdata->otg_board_data.interface_type = fdtdec_get_int(fdt, node,
+ "interface-type", -1);
+ if (platdata->otg_board_data.interface_type < 0) {
+ pr_err("MUSB interface-type DT entry missing\n");
+ return -ENOENT;
+ }
+
+#if 0 /* In a perfect world, mode would be set to OTG, mode 3 from DT */
+ platdata->plat.mode = fdtdec_get_int(fdt, node,
+ "mode", -1);
+ if (platdata->plat.mode < 0) {
+ pr_err("MUSB mode DT entry missing\n");
+ return -ENOENT;
+ }
+#else /* MUSB_OTG, it doesn't work */
+#ifdef CONFIG_USB_MUSB_HOST /* Host seems to be the only option that works */
+ platdata->plat.mode = MUSB_HOST;
+#else /* For that matter, MUSB_PERIPHERAL doesn't either */
+ platdata->plat.mode = MUSB_PERIPHERAL;
+#endif
+#endif
+ platdata->otg_board_data.dev = dev;
+ platdata->plat.config = &platdata->musb_config;
+ platdata->plat.platform_ops = &omap2430_ops;
+ platdata->plat.board_data = &platdata->otg_board_data;
+ return 0;
+}
+
+static int omap2430_musb_probe(struct udevice *dev)
+{
+#ifdef CONFIG_USB_MUSB_HOST
+ struct musb_host_data *host = dev_get_priv(dev);
+#endif
+ struct omap2430_musb_platdata *platdata = dev_get_platdata(dev);
+ struct usb_bus_priv *priv = dev_get_uclass_priv(dev);
+ struct omap_musb_board_data *otg_board_data;
+ int ret;
+ void *base = dev_read_addr_ptr(dev);
+
+ priv->desc_before_addr = true;
+
+ otg_board_data = &platdata->otg_board_data;
+
+#ifdef CONFIG_USB_MUSB_HOST
+ host->host = musb_init_controller(&platdata->plat,
+ (struct device *)otg_board_data,
+ platdata->base);
+ if (!host->host) {
+ return -EIO;
+ }
+
+ ret = musb_lowlevel_init(host);
+#else
+ ret = musb_register(&platdata->plat,
+ (struct device *)otg_board_data,
+ platdata->base);
+#endif
+ return ret;
+}
+
+static int omap2430_musb_remove(struct udevice *dev)
+{
+ struct musb_host_data *host = dev_get_priv(dev);
+
+ musb_stop(host->host);
+
+ return 0;
+}
+
+static const struct udevice_id omap2430_musb_ids[] = {
+ { .compatible = "ti,omap3-musb" },
+ { .compatible = "ti,omap4-musb" },
+ { }
+};
+
+U_BOOT_DRIVER(omap2430_musb) = {
+ .name = "omap2430-musb",
+#ifdef CONFIG_USB_MUSB_HOST
+ .id = UCLASS_USB,
+#else
+ .id = UCLASS_USB_DEV_GENERIC,
+#endif
+ .of_match = omap2430_musb_ids,
+ .ofdata_to_platdata = omap2430_musb_ofdata_to_platdata,
+ .probe = omap2430_musb_probe,
+ .remove = omap2430_musb_remove,
+ .ops = &musb_usb_ops,
+ .platdata_auto_alloc_size = sizeof(struct omap2430_musb_platdata),
+ .priv_auto_alloc_size = sizeof(struct musb_host_data),
+};
+
+#endif /* CONFIG_DM_USB */
--
2.17.1
More information about the U-Boot
mailing list