[U-Boot] [RFC PATCH 4/5] am33xx: init OTG hardware and new musb gadget driver

Ilya Yanok ilya.yanok at cogentembedded.com
Wed Aug 8 23:13:00 CEST 2012


AM33xx has support for dual port MUSB OTG controller. This patch
adds initialization for the controller using new MUSB gadget
driver and ether gadget.

Signed-off-by: Ilya Yanok <ilya.yanok at cogentembedded.com>
---
 arch/arm/cpu/armv7/am33xx/board.c           |   81 ++++++++++++++++++++++++++-
 arch/arm/cpu/armv7/am33xx/clock.c           |    8 +++
 arch/arm/include/asm/arch-am33xx/cpu.h      |   11 +++-
 arch/arm/include/asm/arch-am33xx/hardware.h |    4 ++
 4 files changed, 100 insertions(+), 4 deletions(-)

diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c
index 2ca4ca7..dafc264 100644
--- a/arch/arm/cpu/armv7/am33xx/board.c
+++ b/arch/arm/cpu/armv7/am33xx/board.c
@@ -33,6 +33,11 @@
 #include <i2c.h>
 #include <miiphy.h>
 #include <cpsw.h>
+#include <asm/errno.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/musb.h>
+#include <asm/omap_musb.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -273,9 +278,65 @@ static struct cpsw_platform_data cpsw_data = {
 	.host_port_num		= 0,
 	.version		= CPSW_CTRL_VERSION_2,
 };
+#endif
+
+#ifdef CONFIG_MUSB_GADGET
+#ifdef CONFIG_MUSB_GADGET_PORT0
+#define USB_CTRL_REG &cdev->usb_ctrl0
+#define OTG_REGS_BASE ((void *)AM335X_USB0_OTG_BASE)
+#elif defined(CONFIG_MUSB_GADGET_PORT1)
+#define USB_CTRL_REG &cdev->usb_ctrl1
+#define OTG_REGS_BASE ((void *)AM335X_USB1_OTG_BASE)
+#else
+#error "Please define CONFIG_MUSB_GADGET_PORT0 or CONFIG_MUSB_GADGET_PORT1"
+#endif
+
+/* USB 2.0 PHY Control */
+#define CM_PHY_PWRDN			(1 << 0)
+#define CM_PHY_OTG_PWRDN		(1 << 1)
+#define OTGVDET_EN			(1 << 19)
+#define OTGSESSENDEN			(1 << 20)
+
+static void am33xx_usb_set_phy_power(u8 on)
+{
+	u32 usb_ctrl_reg;
+
+	usb_ctrl_reg = readl(USB_CTRL_REG);
+	if (on) {
+		usb_ctrl_reg &= ~(CM_PHY_PWRDN | CM_PHY_OTG_PWRDN);
+		usb_ctrl_reg |= (OTGVDET_EN | OTGSESSENDEN);
+	} else {
+		usb_ctrl_reg |= (CM_PHY_PWRDN | CM_PHY_OTG_PWRDN);
+	}
+	writel(usb_ctrl_reg, USB_CTRL_REG);
+}
+
+static struct musb_hdrc_config musb_config = {
+	.multipoint     = 1,
+	.dyn_fifo       = 1,
+	.num_eps        = 16,
+	.ram_bits       = 12,
+};
 
+struct omap_musb_board_data musb_board_data = {
+	.set_phy_power = am33xx_usb_set_phy_power,
+};
+
+static struct musb_hdrc_platform_data musb_plat = {
+	.mode           = MUSB_PERIPHERAL,
+	.config         = &musb_config,
+	.power          = 50,
+	.platform_ops	= &musb_dsps_ops,
+	.board_data	= &musb_board_data,
+};
+#endif
+
+#if defined(CONFIG_DRIVER_TI_CPSW) || \
+	(defined(CONFIG_USB_ETHER) && defined(CONFIG_MUSB_GADGET))
 int board_eth_init(bd_t *bis)
 {
+	int rv, n = 0;
+#ifdef CONFIG_DRIVER_TI_CPSW
 	uint8_t mac_addr[6];
 	uint32_t mac_hi, mac_lo;
 
@@ -307,6 +368,24 @@ int board_eth_init(bd_t *bis)
 				PHY_INTERFACE_MODE_RGMII;
 	}
 
-	return cpsw_register(&cpsw_data);
+	rv = cpsw_register(&cpsw_data);
+	if (rv < 0)
+		printf("Error %d registering CPSW switch\n", rv);
+	else
+		n += rv;
+#endif
+#ifdef CONFIG_USB_ETHER
+	rv = musb_register(&musb_plat, &musb_board_data, OTG_REGS_BASE);
+	if (rv < 0) {
+		printf("Error %d registering MUSB device\n", rv);
+	} else {
+		rv = usb_eth_initialize(bis);
+		if (rv < 0)
+			printf("Error %d registering USB_ETHER\n", rv);
+		else
+			n += rv;
+	}
+#endif
+	return n;
 }
 #endif
diff --git a/arch/arm/cpu/armv7/am33xx/clock.c b/arch/arm/cpu/armv7/am33xx/clock.c
index 1071f92..5ad84ce 100644
--- a/arch/arm/cpu/armv7/am33xx/clock.c
+++ b/arch/arm/cpu/armv7/am33xx/clock.c
@@ -40,6 +40,7 @@
 #define CLK_MODE_MASK		0xfffffff8
 #define CLK_DIV_SEL		0xFFFFFFE0
 #define CPGMAC0_IDLE		0x30000
+#define DPLL_CLKDCOLDO_GATE_CTRL        0x300
 
 const struct cm_perpll *cmper = (struct cm_perpll *)CM_PER;
 const struct cm_wkuppll *cmwkup = (struct cm_wkuppll *)CM_WKUP;
@@ -148,6 +149,11 @@ static void enable_per_clocks(void)
 	writel(PRCM_MOD_EN, &cmper->cpgmac0clkctrl);
 	while ((readl(&cmper->cpgmac0clkctrl) & CPGMAC0_IDLE) != PRCM_FUNCTL)
 		;
+
+	/* MUSB */
+	writel(PRCM_MOD_EN, &cmper->usb0clkctrl);
+	while (readl(&cmper->usb0clkctrl) != PRCM_MOD_EN)
+		;
 }
 
 static void mpu_pll_config(void)
@@ -244,6 +250,8 @@ static void per_pll_config(void)
 
 	while (readl(&cmwkup->idlestdpllper) != ST_DPLL_CLK)
 		;
+
+	writel(DPLL_CLKDCOLDO_GATE_CTRL, &cmwkup->clkdcoldodpllper);
 }
 
 void ddr_pll_config(unsigned int ddrpll_m)
diff --git a/arch/arm/include/asm/arch-am33xx/cpu.h b/arch/arm/include/asm/arch-am33xx/cpu.h
index de9ee91..a98ffa2 100644
--- a/arch/arm/include/asm/arch-am33xx/cpu.h
+++ b/arch/arm/include/asm/arch-am33xx/cpu.h
@@ -82,7 +82,8 @@ struct cm_wkuppll {
 	unsigned int clkseldpllcore;	/* offset 0x68 */
 	unsigned int resv9[1];
 	unsigned int idlestdpllper;	/* offset 0x70 */
-	unsigned int resv10[3];
+	unsigned int resv10[2];
+	unsigned int clkdcoldodpllper;	/* offset 0x7c */
 	unsigned int divm4dpllcore;	/* offset 0x80 */
 	unsigned int divm5dpllcore;	/* offset 0x84 */
 	unsigned int clkmoddpllmpu;	/* offset 0x88 */
@@ -258,12 +259,16 @@ struct ctrl_stat {
 /* Control Device Register */
 struct ctrl_dev {
 	unsigned int deviceid;		/* offset 0x00 */
-	unsigned int resv1[11];
+	unsigned int resv1[7];
+	unsigned int usb_ctrl0;		/* offset 0x20 */
+	unsigned int resv2;
+	unsigned int usb_ctrl1;		/* offset 0x28 */
+	unsigned int resv3;
 	unsigned int macid0l;		/* offset 0x30 */
 	unsigned int macid0h;		/* offset 0x34 */
 	unsigned int macid1l;		/* offset 0x38 */
 	unsigned int macid1h;		/* offset 0x3c */
-	unsigned int resv2[4];
+	unsigned int resv4[4];
 	unsigned int miisel;		/* offset 0x50 */
 };
 #endif /* __ASSEMBLY__ */
diff --git a/arch/arm/include/asm/arch-am33xx/hardware.h b/arch/arm/include/asm/arch-am33xx/hardware.h
index c617331..f98f497 100644
--- a/arch/arm/include/asm/arch-am33xx/hardware.h
+++ b/arch/arm/include/asm/arch-am33xx/hardware.h
@@ -82,4 +82,8 @@
 #define AM335X_CPSW_BASE		0x4A100000
 #define AM335X_CPSW_MDIO_BASE		0x4A101000
 
+/* OTG */
+#define AM335X_USB0_OTG_BASE		0x47401000
+#define AM335X_USB1_OTG_BASE		0x47401800
+
 #endif /* __AM33XX_HARDWARE_H */
-- 
1.7.9.5



More information about the U-Boot mailing list