[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