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

Ilya Yanok ilya.yanok at cogentembedded.com
Mon Sep 17 01:14:33 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>
---
Changes in v2:
 - init both musb IPs (conditionally) from arch_init not
   from eth_initialize

 arch/arm/cpu/armv7/am33xx/board.c           |  107 ++++++++++++++++++++++++++-
 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, 126 insertions(+), 4 deletions(-)

diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c
index b387ac2..9007356 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;
 
@@ -227,6 +232,88 @@ void setup_clocks_for_console(void)
 	return;
 }
 
+/* AM33XX has two MUSB controllers which can be host or gadget */
+#if (defined(CONFIG_MUSB_GADGET) || defined(CONFIG_MUSB_HOST)) && \
+	(defined(CONFIG_AM335X_USB0) || defined(CONFIG_AM335X_USB1))
+/* 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 *reg_addr)
+{
+	u32 usb_ctrl_reg;
+
+	usb_ctrl_reg = readl(reg_addr);
+	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, reg_addr);
+}
+
+static struct musb_hdrc_config musb_config = {
+	.multipoint     = 1,
+	.dyn_fifo       = 1,
+	.num_eps        = 16,
+	.ram_bits       = 12,
+};
+
+#ifdef CONFIG_AM335X_USB0
+static void am33xx_otg0_set_phy_power(u8 on)
+{
+	am33xx_usb_set_phy_power(on, &cdev->usb_ctrl0);
+}
+
+struct omap_musb_board_data otg0_board_data = {
+	.set_phy_power = am33xx_otg0_set_phy_power,
+};
+
+static struct musb_hdrc_platform_data otg0_plat = {
+	.mode           = CONFIG_AM335X_USB0_MODE,
+	.config         = &musb_config,
+	.power          = 50,
+	.platform_ops	= &musb_dsps_ops,
+	.board_data	= &otg0_board_data,
+};
+#endif
+
+#ifdef CONFIG_AM335X_USB1
+static void am33xx_otg1_set_phy_power(u8 on)
+{
+	am33xx_usb_set_phy_power(on, &cdev->usb_ctrl1);
+}
+
+struct omap_musb_board_data otg1_board_data = {
+	.set_phy_power = am33xx_otg1_set_phy_power,
+};
+
+static struct musb_hdrc_platform_data otg1_plat = {
+	.mode           = CONFIG_AM335X_USB1_MODE,
+	.config         = &musb_config,
+	.power          = 50,
+	.platform_ops	= &musb_dsps_ops,
+	.board_data	= &otg1_board_data,
+};
+#endif
+#endif
+
+int arch_misc_init(void)
+{
+#ifdef CONFIG_AM335X_USB0
+	musb_register(&otg0_plat, &otg0_board_data,
+		(void *)AM335X_USB0_OTG_BASE);
+#endif
+#ifdef CONFIG_AM335X_USB1
+	musb_register(&otg1_plat, &otg1_board_data,
+		(void *)AM335X_USB1_OTG_BASE);
+#endif
+	return 0;
+}
+
 /*
  * Basic board specific setup.  Pinmux has been handled already.
  */
@@ -279,9 +366,14 @@ static struct cpsw_platform_data cpsw_data = {
 	.host_port_num		= 0,
 	.version		= CPSW_CTRL_VERSION_2,
 };
+#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;
 
@@ -313,6 +405,19 @@ 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 = 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 2b19506..04841e4 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;
@@ -153,6 +154,11 @@ static void enable_per_clocks(void)
 	writel(PRCM_MOD_EN, &cmper->spi0clkctrl);
 	while (readl(&cmper->spi0clkctrl) != PRCM_MOD_EN)
 		;
+
+	/* MUSB */
+	writel(PRCM_MOD_EN, &cmper->usb0clkctrl);
+	while (readl(&cmper->usb0clkctrl) != PRCM_MOD_EN)
+		;
 }
 
 static void mpu_pll_config(void)
@@ -249,6 +255,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 6cfbef7..60e28f9 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 */
@@ -260,12 +261,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 62332f2..39d0717 100644
--- a/arch/arm/include/asm/arch-am33xx/hardware.h
+++ b/arch/arm/include/asm/arch-am33xx/hardware.h
@@ -83,4 +83,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