0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0011
0012 #include <linux/types.h>
0013 #include <linux/delay.h>
0014 #include <linux/clk.h>
0015 #include <linux/io.h>
0016 #include <linux/err.h>
0017 #include <linux/usb.h>
0018 #include <linux/usb/musb.h>
0019
0020 #include "soc.h"
0021 #include "control.h"
0022 #include "usb.h"
0023
0024 #define CONTROL_DEV_CONF 0x300
0025 #define PHY_PD 0x1
0026
0027
0028
0029
0030
0031
0032
0033
0034 static int __init omap4430_phy_power_down(void)
0035 {
0036 void __iomem *ctrl_base;
0037
0038 if (!cpu_is_omap44xx())
0039 return 0;
0040
0041 ctrl_base = ioremap(OMAP443X_SCM_BASE, SZ_1K);
0042 if (!ctrl_base) {
0043 pr_err("control module ioremap failed\n");
0044 return -ENOMEM;
0045 }
0046
0047
0048 writel_relaxed(PHY_PD, ctrl_base + CONTROL_DEV_CONF);
0049
0050 iounmap(ctrl_base);
0051
0052 return 0;
0053 }
0054 omap_early_initcall(omap4430_phy_power_down);
0055
0056 void am35x_musb_reset(void)
0057 {
0058 u32 regval;
0059
0060
0061 regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
0062
0063 regval |= AM35XX_USBOTGSS_SW_RST;
0064 omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET);
0065
0066 regval &= ~AM35XX_USBOTGSS_SW_RST;
0067 omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET);
0068
0069 regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
0070 }
0071
0072 void am35x_musb_phy_power(u8 on)
0073 {
0074 unsigned long timeout = jiffies + msecs_to_jiffies(100);
0075 u32 devconf2;
0076
0077 if (on) {
0078
0079
0080
0081 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
0082
0083 devconf2 &= ~(CONF2_RESET | CONF2_PHYPWRDN | CONF2_OTGPWRDN);
0084 devconf2 |= CONF2_PHY_PLLON;
0085
0086 omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
0087
0088 pr_info("Waiting for PHY clock good...\n");
0089 while (!(omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2)
0090 & CONF2_PHYCLKGD)) {
0091 cpu_relax();
0092
0093 if (time_after(jiffies, timeout)) {
0094 pr_err("musb PHY clock good timed out\n");
0095 break;
0096 }
0097 }
0098 } else {
0099
0100
0101
0102 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
0103
0104 devconf2 &= ~CONF2_PHY_PLLON;
0105 devconf2 |= CONF2_PHYPWRDN | CONF2_OTGPWRDN;
0106 omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
0107 }
0108 }
0109
0110 void am35x_musb_clear_irq(void)
0111 {
0112 u32 regval;
0113
0114 regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
0115 regval |= AM35XX_USBOTGSS_INT_CLR;
0116 omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR);
0117 regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
0118 }
0119
0120 void am35x_set_mode(u8 musb_mode)
0121 {
0122 u32 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
0123
0124 devconf2 &= ~CONF2_OTGMODE;
0125 switch (musb_mode) {
0126 case MUSB_HOST:
0127 devconf2 |= CONF2_FORCE_HOST;
0128 break;
0129 case MUSB_PERIPHERAL:
0130 devconf2 |= CONF2_FORCE_DEVICE;
0131 break;
0132 case MUSB_OTG:
0133 devconf2 |= CONF2_NO_OVERRIDE;
0134 break;
0135 default:
0136 pr_info("Unsupported mode %u\n", musb_mode);
0137 }
0138
0139 omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
0140 }