提交 04aa67de 编写于 作者: T Tony Lindgren

Merge branch 'for-tony' of git://gitorious.org/usb/usb into omap-for-linus

Conflicts:
	arch/arm/mach-omap2/omap_hwmod_2430_data.c
	arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
...@@ -218,7 +218,8 @@ obj-$(CONFIG_MACH_OMAP4_PANDA) += board-omap4panda.o \ ...@@ -218,7 +218,8 @@ obj-$(CONFIG_MACH_OMAP4_PANDA) += board-omap4panda.o \
hsmmc.o \ hsmmc.o \
omap_phy_internal.o omap_phy_internal.o
obj-$(CONFIG_MACH_OMAP3517EVM) += board-am3517evm.o obj-$(CONFIG_MACH_OMAP3517EVM) += board-am3517evm.o \
omap_phy_internal.o \
obj-$(CONFIG_MACH_CRANEBOARD) += board-am3517crane.o obj-$(CONFIG_MACH_CRANEBOARD) += board-am3517crane.o
......
...@@ -44,7 +44,6 @@ ...@@ -44,7 +44,6 @@
#define ETH_KS8851_IRQ 34 #define ETH_KS8851_IRQ 34
#define ETH_KS8851_POWER_ON 48 #define ETH_KS8851_POWER_ON 48
#define ETH_KS8851_QUART 138 #define ETH_KS8851_QUART 138
#define OMAP4SDP_MDM_PWR_EN_GPIO 157
#define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO 184 #define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO 184
#define OMAP4_SFH7741_ENABLE_GPIO 188 #define OMAP4_SFH7741_ENABLE_GPIO 188
...@@ -250,16 +249,6 @@ static void __init omap_4430sdp_init_early(void) ...@@ -250,16 +249,6 @@ static void __init omap_4430sdp_init_early(void)
#endif #endif
} }
static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
.port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN,
.port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
.phy_reset = false,
.reset_gpio_port[0] = -EINVAL,
.reset_gpio_port[1] = -EINVAL,
.reset_gpio_port[2] = -EINVAL,
};
static struct omap_musb_board_data musb_board_data = { static struct omap_musb_board_data musb_board_data = {
.interface_type = MUSB_INTERFACE_UTMI, .interface_type = MUSB_INTERFACE_UTMI,
.mode = MUSB_OTG, .mode = MUSB_OTG,
...@@ -575,14 +564,6 @@ static void __init omap_4430sdp_init(void) ...@@ -575,14 +564,6 @@ static void __init omap_4430sdp_init(void)
omap_serial_init(); omap_serial_init();
omap4_twl6030_hsmmc_init(mmc); omap4_twl6030_hsmmc_init(mmc);
/* Power on the ULPI PHY */
status = gpio_request(OMAP4SDP_MDM_PWR_EN_GPIO, "USBB1 PHY VMDM_3V3");
if (status)
pr_err("%s: Could not get USBB1 PHY GPIO\n", __func__);
else
gpio_direction_output(OMAP4SDP_MDM_PWR_EN_GPIO, 1);
usb_ehci_init(&ehci_pdata);
usb_musb_init(&musb_board_data); usb_musb_init(&musb_board_data);
status = omap_ethernet_init(); status = omap_ethernet_init();
......
...@@ -408,6 +408,10 @@ static struct omap_musb_board_data musb_board_data = { ...@@ -408,6 +408,10 @@ static struct omap_musb_board_data musb_board_data = {
.interface_type = MUSB_INTERFACE_ULPI, .interface_type = MUSB_INTERFACE_ULPI,
.mode = MUSB_OTG, .mode = MUSB_OTG,
.power = 500, .power = 500,
.set_phy_power = am35x_musb_phy_power,
.clear_irq = am35x_musb_clear_irq,
.set_mode = am35x_musb_set_mode,
.reset = am35x_musb_reset,
}; };
static __init void am3517_evm_musb_init(void) static __init void am3517_evm_musb_init(void)
......
...@@ -93,6 +93,16 @@ static struct omap_hwmod omap2430_uart3_hwmod; ...@@ -93,6 +93,16 @@ static struct omap_hwmod omap2430_uart3_hwmod;
static struct omap_hwmod omap2430_i2c1_hwmod; static struct omap_hwmod omap2430_i2c1_hwmod;
static struct omap_hwmod omap2430_i2c2_hwmod; static struct omap_hwmod omap2430_i2c2_hwmod;
static struct omap_hwmod omap2430_usbhsotg_hwmod;
/* l3_core -> usbhsotg interface */
static struct omap_hwmod_ocp_if omap2430_usbhsotg__l3 = {
.master = &omap2430_usbhsotg_hwmod,
.slave = &omap2430_l3_main_hwmod,
.clk = "core_l3_ck",
.user = OCP_USER_MPU,
};
/* I2C IP block address space length (in bytes) */ /* I2C IP block address space length (in bytes) */
#define OMAP2_I2C_AS_LEN 128 #define OMAP2_I2C_AS_LEN 128
...@@ -193,6 +203,35 @@ static struct omap_hwmod_ocp_if omap2_l4_core__uart3 = { ...@@ -193,6 +203,35 @@ static struct omap_hwmod_ocp_if omap2_l4_core__uart3 = {
.user = OCP_USER_MPU | OCP_USER_SDMA, .user = OCP_USER_MPU | OCP_USER_SDMA,
}; };
/*
* usbhsotg interface data
*/
static struct omap_hwmod_addr_space omap2430_usbhsotg_addrs[] = {
{
.pa_start = OMAP243X_HS_BASE,
.pa_end = OMAP243X_HS_BASE + SZ_4K - 1,
.flags = ADDR_TYPE_RT
},
};
/* l4_core ->usbhsotg interface */
static struct omap_hwmod_ocp_if omap2430_l4_core__usbhsotg = {
.master = &omap2430_l4_core_hwmod,
.slave = &omap2430_usbhsotg_hwmod,
.clk = "usb_l4_ick",
.addr = omap2430_usbhsotg_addrs,
.addr_cnt = ARRAY_SIZE(omap2430_usbhsotg_addrs),
.user = OCP_USER_MPU,
};
static struct omap_hwmod_ocp_if *omap2430_usbhsotg_masters[] = {
&omap2430_usbhsotg__l3,
};
static struct omap_hwmod_ocp_if *omap2430_usbhsotg_slaves[] = {
&omap2430_l4_core__usbhsotg,
};
/* Slave interfaces on the L4_CORE interconnect */ /* Slave interfaces on the L4_CORE interconnect */
static struct omap_hwmod_ocp_if *omap2430_l4_core_slaves[] = { static struct omap_hwmod_ocp_if *omap2430_l4_core_slaves[] = {
&omap2430_l3_main__l4_core, &omap2430_l3_main__l4_core,
...@@ -1133,6 +1172,64 @@ static struct omap_hwmod omap2430_mcspi3_hwmod = { ...@@ -1133,6 +1172,64 @@ static struct omap_hwmod omap2430_mcspi3_hwmod = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
}; };
/*
* usbhsotg
*/
static struct omap_hwmod_class_sysconfig omap2430_usbhsotg_sysc = {
.rev_offs = 0x0400,
.sysc_offs = 0x0404,
.syss_offs = 0x0408,
.sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE|
SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
SYSC_HAS_AUTOIDLE),
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
.sysc_fields = &omap_hwmod_sysc_type1,
};
static struct omap_hwmod_class usbotg_class = {
.name = "usbotg",
.sysc = &omap2430_usbhsotg_sysc,
};
/* usb_otg_hs */
static struct omap_hwmod_irq_info omap2430_usbhsotg_mpu_irqs[] = {
{ .name = "mc", .irq = 92 },
{ .name = "dma", .irq = 93 },
};
static struct omap_hwmod omap2430_usbhsotg_hwmod = {
.name = "usb_otg_hs",
.mpu_irqs = omap2430_usbhsotg_mpu_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap2430_usbhsotg_mpu_irqs),
.main_clk = "usbhs_ick",
.prcm = {
.omap2 = {
.prcm_reg_id = 1,
.module_bit = OMAP2430_EN_USBHS_MASK,
.module_offs = CORE_MOD,
.idlest_reg_id = 1,
.idlest_idle_bit = OMAP2430_ST_USBHS_SHIFT,
},
},
.masters = omap2430_usbhsotg_masters,
.masters_cnt = ARRAY_SIZE(omap2430_usbhsotg_masters),
.slaves = omap2430_usbhsotg_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_usbhsotg_slaves),
.class = &usbotg_class,
/*
* Erratum ID: i479 idle_req / idle_ack mechanism potentially
* broken when autoidle is enabled
* workaround is to disable the autoidle bit at module level.
*/
.flags = HWMOD_NO_OCP_AUTOIDLE | HWMOD_SWSUP_SIDLE
| HWMOD_SWSUP_MSTANDBY,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
};
static __initdata struct omap_hwmod *omap2430_hwmods[] = { static __initdata struct omap_hwmod *omap2430_hwmods[] = {
&omap2430_l3_main_hwmod, &omap2430_l3_main_hwmod,
&omap2430_l4_core_hwmod, &omap2430_l4_core_hwmod,
...@@ -1160,6 +1257,10 @@ static __initdata struct omap_hwmod *omap2430_hwmods[] = { ...@@ -1160,6 +1257,10 @@ static __initdata struct omap_hwmod *omap2430_hwmods[] = {
&omap2430_mcspi1_hwmod, &omap2430_mcspi1_hwmod,
&omap2430_mcspi2_hwmod, &omap2430_mcspi2_hwmod,
&omap2430_mcspi3_hwmod, &omap2430_mcspi3_hwmod,
/* usbotg class*/
&omap2430_usbhsotg_hwmod,
NULL, NULL,
}; };
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "prm-regbits-34xx.h" #include "prm-regbits-34xx.h"
#include "cm-regbits-34xx.h" #include "cm-regbits-34xx.h"
#include "wd_timer.h" #include "wd_timer.h"
#include <mach/am35xx.h>
/* /*
* OMAP3xxx hardware module integration data * OMAP3xxx hardware module integration data
...@@ -60,6 +61,7 @@ static struct omap_hwmod omap34xx_mcspi1; ...@@ -60,6 +61,7 @@ static struct omap_hwmod omap34xx_mcspi1;
static struct omap_hwmod omap34xx_mcspi2; static struct omap_hwmod omap34xx_mcspi2;
static struct omap_hwmod omap34xx_mcspi3; static struct omap_hwmod omap34xx_mcspi3;
static struct omap_hwmod omap34xx_mcspi4; static struct omap_hwmod omap34xx_mcspi4;
static struct omap_hwmod am35xx_usbhsotg_hwmod;
static struct omap_hwmod omap3xxx_dma_system_hwmod; static struct omap_hwmod omap3xxx_dma_system_hwmod;
...@@ -112,7 +114,23 @@ static struct omap_hwmod omap3xxx_uart1_hwmod; ...@@ -112,7 +114,23 @@ static struct omap_hwmod omap3xxx_uart1_hwmod;
static struct omap_hwmod omap3xxx_uart2_hwmod; static struct omap_hwmod omap3xxx_uart2_hwmod;
static struct omap_hwmod omap3xxx_uart3_hwmod; static struct omap_hwmod omap3xxx_uart3_hwmod;
static struct omap_hwmod omap3xxx_uart4_hwmod; static struct omap_hwmod omap3xxx_uart4_hwmod;
static struct omap_hwmod omap3xxx_usbhsotg_hwmod;
/* l3_core -> usbhsotg interface */
static struct omap_hwmod_ocp_if omap3xxx_usbhsotg__l3 = {
.master = &omap3xxx_usbhsotg_hwmod,
.slave = &omap3xxx_l3_main_hwmod,
.clk = "core_l3_ick",
.user = OCP_USER_MPU,
};
/* l3_core -> am35xx_usbhsotg interface */
static struct omap_hwmod_ocp_if am35xx_usbhsotg__l3 = {
.master = &am35xx_usbhsotg_hwmod,
.slave = &omap3xxx_l3_main_hwmod,
.clk = "core_l3_ick",
.user = OCP_USER_MPU,
};
/* L4_CORE -> L4_WKUP interface */ /* L4_CORE -> L4_WKUP interface */
static struct omap_hwmod_ocp_if omap3xxx_l4_core__l4_wkup = { static struct omap_hwmod_ocp_if omap3xxx_l4_core__l4_wkup = {
.master = &omap3xxx_l4_core_hwmod, .master = &omap3xxx_l4_core_hwmod,
...@@ -306,6 +324,61 @@ static struct omap_hwmod_ocp_if omap3_l4_core__sr2 = { ...@@ -306,6 +324,61 @@ static struct omap_hwmod_ocp_if omap3_l4_core__sr2 = {
.user = OCP_USER_MPU, .user = OCP_USER_MPU,
}; };
/*
* usbhsotg interface data
*/
static struct omap_hwmod_addr_space omap3xxx_usbhsotg_addrs[] = {
{
.pa_start = OMAP34XX_HSUSB_OTG_BASE,
.pa_end = OMAP34XX_HSUSB_OTG_BASE + SZ_4K - 1,
.flags = ADDR_TYPE_RT
},
};
/* l4_core -> usbhsotg */
static struct omap_hwmod_ocp_if omap3xxx_l4_core__usbhsotg = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &omap3xxx_usbhsotg_hwmod,
.clk = "l4_ick",
.addr = omap3xxx_usbhsotg_addrs,
.addr_cnt = ARRAY_SIZE(omap3xxx_usbhsotg_addrs),
.user = OCP_USER_MPU,
};
static struct omap_hwmod_ocp_if *omap3xxx_usbhsotg_masters[] = {
&omap3xxx_usbhsotg__l3,
};
static struct omap_hwmod_ocp_if *omap3xxx_usbhsotg_slaves[] = {
&omap3xxx_l4_core__usbhsotg,
};
static struct omap_hwmod_addr_space am35xx_usbhsotg_addrs[] = {
{
.pa_start = AM35XX_IPSS_USBOTGSS_BASE,
.pa_end = AM35XX_IPSS_USBOTGSS_BASE + SZ_4K - 1,
.flags = ADDR_TYPE_RT
},
};
/* l4_core -> usbhsotg */
static struct omap_hwmod_ocp_if am35xx_l4_core__usbhsotg = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &am35xx_usbhsotg_hwmod,
.clk = "l4_ick",
.addr = am35xx_usbhsotg_addrs,
.addr_cnt = ARRAY_SIZE(am35xx_usbhsotg_addrs),
.user = OCP_USER_MPU,
};
static struct omap_hwmod_ocp_if *am35xx_usbhsotg_masters[] = {
&am35xx_usbhsotg__l3,
};
static struct omap_hwmod_ocp_if *am35xx_usbhsotg_slaves[] = {
&am35xx_l4_core__usbhsotg,
};
/* Slave interfaces on the L4_CORE interconnect */ /* Slave interfaces on the L4_CORE interconnect */
static struct omap_hwmod_ocp_if *omap3xxx_l4_core_slaves[] = { static struct omap_hwmod_ocp_if *omap3xxx_l4_core_slaves[] = {
&omap3xxx_l3_main__l4_core, &omap3xxx_l3_main__l4_core,
...@@ -1630,6 +1703,91 @@ static struct omap_hwmod omap34xx_mcspi4 = { ...@@ -1630,6 +1703,91 @@ static struct omap_hwmod omap34xx_mcspi4 = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
}; };
/*
* usbhsotg
*/
static struct omap_hwmod_class_sysconfig omap3xxx_usbhsotg_sysc = {
.rev_offs = 0x0400,
.sysc_offs = 0x0404,
.syss_offs = 0x0408,
.sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE|
SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
SYSC_HAS_AUTOIDLE),
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
.sysc_fields = &omap_hwmod_sysc_type1,
};
static struct omap_hwmod_class usbotg_class = {
.name = "usbotg",
.sysc = &omap3xxx_usbhsotg_sysc,
};
/* usb_otg_hs */
static struct omap_hwmod_irq_info omap3xxx_usbhsotg_mpu_irqs[] = {
{ .name = "mc", .irq = 92 },
{ .name = "dma", .irq = 93 },
};
static struct omap_hwmod omap3xxx_usbhsotg_hwmod = {
.name = "usb_otg_hs",
.mpu_irqs = omap3xxx_usbhsotg_mpu_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_usbhsotg_mpu_irqs),
.main_clk = "hsotgusb_ick",
.prcm = {
.omap2 = {
.prcm_reg_id = 1,
.module_bit = OMAP3430_EN_HSOTGUSB_SHIFT,
.module_offs = CORE_MOD,
.idlest_reg_id = 1,
.idlest_idle_bit = OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT,
.idlest_stdby_bit = OMAP3430ES2_ST_HSOTGUSB_STDBY_SHIFT
},
},
.masters = omap3xxx_usbhsotg_masters,
.masters_cnt = ARRAY_SIZE(omap3xxx_usbhsotg_masters),
.slaves = omap3xxx_usbhsotg_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_usbhsotg_slaves),
.class = &usbotg_class,
/*
* Erratum ID: i479 idle_req / idle_ack mechanism potentially
* broken when autoidle is enabled
* workaround is to disable the autoidle bit at module level.
*/
.flags = HWMOD_NO_OCP_AUTOIDLE | HWMOD_SWSUP_SIDLE
| HWMOD_SWSUP_MSTANDBY,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
};
/* usb_otg_hs */
static struct omap_hwmod_irq_info am35xx_usbhsotg_mpu_irqs[] = {
{ .name = "mc", .irq = 71 },
};
static struct omap_hwmod_class am35xx_usbotg_class = {
.name = "am35xx_usbotg",
.sysc = NULL,
};
static struct omap_hwmod am35xx_usbhsotg_hwmod = {
.name = "am35x_otg_hs",
.mpu_irqs = am35xx_usbhsotg_mpu_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(am35xx_usbhsotg_mpu_irqs),
.main_clk = NULL,
.prcm = {
.omap2 = {
},
},
.masters = am35xx_usbhsotg_masters,
.masters_cnt = ARRAY_SIZE(am35xx_usbhsotg_masters),
.slaves = am35xx_usbhsotg_slaves,
.slaves_cnt = ARRAY_SIZE(am35xx_usbhsotg_slaves),
.class = &am35xx_usbotg_class,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES3_1)
};
static __initdata struct omap_hwmod *omap3xxx_hwmods[] = { static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
&omap3xxx_l3_main_hwmod, &omap3xxx_l3_main_hwmod,
&omap3xxx_l4_core_hwmod, &omap3xxx_l4_core_hwmod,
...@@ -1667,6 +1825,13 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = { ...@@ -1667,6 +1825,13 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
&omap34xx_mcspi2, &omap34xx_mcspi2,
&omap34xx_mcspi3, &omap34xx_mcspi3,
&omap34xx_mcspi4, &omap34xx_mcspi4,
/* usbotg class */
&omap3xxx_usbhsotg_hwmod,
/* usbotg for am35x */
&am35xx_usbhsotg_hwmod,
NULL, NULL,
}; };
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <linux/usb.h> #include <linux/usb.h>
#include <plat/usb.h> #include <plat/usb.h>
#include "control.h"
/* OMAP control module register for UTMI PHY */ /* OMAP control module register for UTMI PHY */
#define CONTROL_DEV_CONF 0x300 #define CONTROL_DEV_CONF 0x300
...@@ -147,3 +148,95 @@ int omap4430_phy_exit(struct device *dev) ...@@ -147,3 +148,95 @@ int omap4430_phy_exit(struct device *dev)
return 0; return 0;
} }
void am35x_musb_reset(void)
{
u32 regval;
/* Reset the musb interface */
regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
regval |= AM35XX_USBOTGSS_SW_RST;
omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET);
regval &= ~AM35XX_USBOTGSS_SW_RST;
omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET);
regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
}
void am35x_musb_phy_power(u8 on)
{
unsigned long timeout = jiffies + msecs_to_jiffies(100);
u32 devconf2;
if (on) {
/*
* Start the on-chip PHY and its PLL.
*/
devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
devconf2 &= ~(CONF2_RESET | CONF2_PHYPWRDN | CONF2_OTGPWRDN);
devconf2 |= CONF2_PHY_PLLON;
omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
pr_info(KERN_INFO "Waiting for PHY clock good...\n");
while (!(omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2)
& CONF2_PHYCLKGD)) {
cpu_relax();
if (time_after(jiffies, timeout)) {
pr_err(KERN_ERR "musb PHY clock good timed out\n");
break;
}
}
} else {
/*
* Power down the on-chip PHY.
*/
devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
devconf2 &= ~CONF2_PHY_PLLON;
devconf2 |= CONF2_PHYPWRDN | CONF2_OTGPWRDN;
omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
}
}
void am35x_musb_clear_irq(void)
{
u32 regval;
regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
regval |= AM35XX_USBOTGSS_INT_CLR;
omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR);
regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
}
void am35x_musb_set_mode(u8 musb_mode)
{
u32 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
devconf2 &= ~CONF2_OTGMODE;
switch (musb_mode) {
#ifdef CONFIG_USB_MUSB_HDRC_HCD
case MUSB_HOST: /* Force VBUS valid, ID = 0 */
devconf2 |= CONF2_FORCE_HOST;
break;
#endif
#ifdef CONFIG_USB_GADGET_MUSB_HDRC
case MUSB_PERIPHERAL: /* Force VBUS valid, ID = 1 */
devconf2 |= CONF2_FORCE_DEVICE;
break;
#endif
#ifdef CONFIG_USB_MUSB_OTG
case MUSB_OTG: /* Don't override the VBUS/ID comparators */
devconf2 |= CONF2_NO_OVERRIDE;
break;
#endif
default:
pr_info(KERN_INFO "Unsupported mode %u\n", musb_mode);
}
omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
}
...@@ -30,118 +30,11 @@ ...@@ -30,118 +30,11 @@
#include <mach/irqs.h> #include <mach/irqs.h>
#include <mach/am35xx.h> #include <mach/am35xx.h>
#include <plat/usb.h> #include <plat/usb.h>
#include "control.h" #include <plat/omap_device.h>
#include "mux.h"
#if defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined (CONFIG_USB_MUSB_AM35X) #if defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined (CONFIG_USB_MUSB_AM35X)
static void am35x_musb_reset(void)
{
u32 regval;
/* Reset the musb interface */
regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
regval |= AM35XX_USBOTGSS_SW_RST;
omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET);
regval &= ~AM35XX_USBOTGSS_SW_RST;
omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET);
regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
}
static void am35x_musb_phy_power(u8 on)
{
unsigned long timeout = jiffies + msecs_to_jiffies(100);
u32 devconf2;
if (on) {
/*
* Start the on-chip PHY and its PLL.
*/
devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
devconf2 &= ~(CONF2_RESET | CONF2_PHYPWRDN | CONF2_OTGPWRDN);
devconf2 |= CONF2_PHY_PLLON;
omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
pr_info(KERN_INFO "Waiting for PHY clock good...\n");
while (!(omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2)
& CONF2_PHYCLKGD)) {
cpu_relax();
if (time_after(jiffies, timeout)) {
pr_err(KERN_ERR "musb PHY clock good timed out\n");
break;
}
}
} else {
/*
* Power down the on-chip PHY.
*/
devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
devconf2 &= ~CONF2_PHY_PLLON;
devconf2 |= CONF2_PHYPWRDN | CONF2_OTGPWRDN;
omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
}
}
static void am35x_musb_clear_irq(void)
{
u32 regval;
regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
regval |= AM35XX_USBOTGSS_INT_CLR;
omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR);
regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
}
static void am35x_musb_set_mode(u8 musb_mode)
{
u32 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
devconf2 &= ~CONF2_OTGMODE;
switch (musb_mode) {
#ifdef CONFIG_USB_MUSB_HDRC_HCD
case MUSB_HOST: /* Force VBUS valid, ID = 0 */
devconf2 |= CONF2_FORCE_HOST;
break;
#endif
#ifdef CONFIG_USB_GADGET_MUSB_HDRC
case MUSB_PERIPHERAL: /* Force VBUS valid, ID = 1 */
devconf2 |= CONF2_FORCE_DEVICE;
break;
#endif
#ifdef CONFIG_USB_MUSB_OTG
case MUSB_OTG: /* Don't override the VBUS/ID comparators */
devconf2 |= CONF2_NO_OVERRIDE;
break;
#endif
default:
pr_info(KERN_INFO "Unsupported mode %u\n", musb_mode);
}
omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
}
static struct resource musb_resources[] = {
[0] = { /* start and end set dynamically */
.flags = IORESOURCE_MEM,
},
[1] = { /* general IRQ */
.start = INT_243X_HS_USB_MC,
.flags = IORESOURCE_IRQ,
.name = "mc",
},
[2] = { /* DMA IRQ */
.start = INT_243X_HS_USB_DMA,
.flags = IORESOURCE_IRQ,
.name = "dma",
},
};
static struct musb_hdrc_config musb_config = { static struct musb_hdrc_config musb_config = {
.multipoint = 1, .multipoint = 1,
.dyn_fifo = 1, .dyn_fifo = 1,
...@@ -169,38 +62,65 @@ static struct musb_hdrc_platform_data musb_plat = { ...@@ -169,38 +62,65 @@ static struct musb_hdrc_platform_data musb_plat = {
static u64 musb_dmamask = DMA_BIT_MASK(32); static u64 musb_dmamask = DMA_BIT_MASK(32);
static struct platform_device musb_device = { static struct omap_device_pm_latency omap_musb_latency[] = {
.name = "musb-omap2430", {
.id = -1, .deactivate_func = omap_device_idle_hwmods,
.dev = { .activate_func = omap_device_enable_hwmods,
.dma_mask = &musb_dmamask, .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &musb_plat,
}, },
.num_resources = ARRAY_SIZE(musb_resources),
.resource = musb_resources,
}; };
static void usb_musb_mux_init(struct omap_musb_board_data *board_data)
{
switch (board_data->interface_type) {
case MUSB_INTERFACE_UTMI:
omap_mux_init_signal("usba0_otg_dp", OMAP_PIN_INPUT);
omap_mux_init_signal("usba0_otg_dm", OMAP_PIN_INPUT);
break;
case MUSB_INTERFACE_ULPI:
omap_mux_init_signal("usba0_ulpiphy_clk",
OMAP_PIN_INPUT_PULLDOWN);
omap_mux_init_signal("usba0_ulpiphy_stp",
OMAP_PIN_INPUT_PULLDOWN);
omap_mux_init_signal("usba0_ulpiphy_dir",
OMAP_PIN_INPUT_PULLDOWN);
omap_mux_init_signal("usba0_ulpiphy_nxt",
OMAP_PIN_INPUT_PULLDOWN);
omap_mux_init_signal("usba0_ulpiphy_dat0",
OMAP_PIN_INPUT_PULLDOWN);
omap_mux_init_signal("usba0_ulpiphy_dat1",
OMAP_PIN_INPUT_PULLDOWN);
omap_mux_init_signal("usba0_ulpiphy_dat2",
OMAP_PIN_INPUT_PULLDOWN);
omap_mux_init_signal("usba0_ulpiphy_dat3",
OMAP_PIN_INPUT_PULLDOWN);
omap_mux_init_signal("usba0_ulpiphy_dat4",
OMAP_PIN_INPUT_PULLDOWN);
omap_mux_init_signal("usba0_ulpiphy_dat5",
OMAP_PIN_INPUT_PULLDOWN);
omap_mux_init_signal("usba0_ulpiphy_dat6",
OMAP_PIN_INPUT_PULLDOWN);
omap_mux_init_signal("usba0_ulpiphy_dat7",
OMAP_PIN_INPUT_PULLDOWN);
break;
default:
break;
}
}
void __init usb_musb_init(struct omap_musb_board_data *board_data) void __init usb_musb_init(struct omap_musb_board_data *board_data)
{ {
if (cpu_is_omap243x()) { struct omap_hwmod *oh;
musb_resources[0].start = OMAP243X_HS_BASE; struct omap_device *od;
} else if (cpu_is_omap3517() || cpu_is_omap3505()) { struct platform_device *pdev;
musb_device.name = "musb-am35x"; struct device *dev;
musb_resources[0].start = AM35XX_IPSS_USBOTGSS_BASE; int bus_id = -1;
musb_resources[1].start = INT_35XX_USBOTG_IRQ; const char *oh_name, *name;
board_data->set_phy_power = am35x_musb_phy_power;
board_data->clear_irq = am35x_musb_clear_irq; if (cpu_is_omap3517() || cpu_is_omap3505()) {
board_data->set_mode = am35x_musb_set_mode;
board_data->reset = am35x_musb_reset;
} else if (cpu_is_omap34xx()) {
musb_resources[0].start = OMAP34XX_HSUSB_OTG_BASE;
} else if (cpu_is_omap44xx()) { } else if (cpu_is_omap44xx()) {
musb_resources[0].start = OMAP44XX_HSUSB_OTG_BASE; usb_musb_mux_init(board_data);
musb_resources[1].start = OMAP44XX_IRQ_HS_USB_MC_N;
musb_resources[2].start = OMAP44XX_IRQ_HS_USB_DMA_N;
} }
musb_resources[0].end = musb_resources[0].start + SZ_4K - 1;
/* /*
* REVISIT: This line can be removed once all the platforms using * REVISIT: This line can be removed once all the platforms using
...@@ -212,8 +132,35 @@ void __init usb_musb_init(struct omap_musb_board_data *board_data) ...@@ -212,8 +132,35 @@ void __init usb_musb_init(struct omap_musb_board_data *board_data)
musb_plat.mode = board_data->mode; musb_plat.mode = board_data->mode;
musb_plat.extvbus = board_data->extvbus; musb_plat.extvbus = board_data->extvbus;
if (platform_device_register(&musb_device) < 0) if (cpu_is_omap3517() || cpu_is_omap3505()) {
printk(KERN_ERR "Unable to register HS-USB (MUSB) device\n"); oh_name = "am35x_otg_hs";
name = "musb-am35x";
} else {
oh_name = "usb_otg_hs";
name = "musb-omap2430";
}
oh = omap_hwmod_lookup(oh_name);
if (!oh) {
pr_err("Could not look up %s\n", oh_name);
return;
}
od = omap_device_build(name, bus_id, oh, &musb_plat,
sizeof(musb_plat), omap_musb_latency,
ARRAY_SIZE(omap_musb_latency), false);
if (IS_ERR(od)) {
pr_err("Could not build omap_device for %s %s\n",
name, oh_name);
return;
}
pdev = &od->pdev;
dev = &pdev->dev;
get_device(dev);
dev->dma_mask = &musb_dmamask;
dev->coherent_dma_mask = musb_dmamask;
put_device(dev);
} }
#else #else
......
...@@ -91,6 +91,10 @@ extern int omap4430_phy_exit(struct device *dev); ...@@ -91,6 +91,10 @@ extern int omap4430_phy_exit(struct device *dev);
#endif #endif
extern void am35x_musb_reset(void);
extern void am35x_musb_phy_power(u8 on);
extern void am35x_musb_clear_irq(void);
extern void am35x_musb_set_mode(u8 musb_mode);
/* /*
* FIXME correct answer depends on hmc_mode, * FIXME correct answer depends on hmc_mode,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册