aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaud Patard (Rtp) <arnaud.patard@rtp-net.org>2010-12-20 10:48:58 -0500
committerSascha Hauer <s.hauer@pengutronix.de>2011-01-03 04:20:23 -0500
commit711669e5b80b6f2d88f61ed8a9681f83d8cbd201 (patch)
treebfb50f071e2d539e310aeb3767bfbce54267420f
parent8305ed75d1418f02933a48bcabdbb5032d885628 (diff)
mx51: fix usb clock support
Current code doesn't really enable the usb clocks so if they're disabled when booting linux, the kernel/machine will hang as soon as someone is trying to read a usb register Signed-off-by: Arnaud Patard <arnaud.patard@rtp-net.org> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--arch/arm/mach-mx5/clock-mx51-mx53.c45
-rw-r--r--drivers/usb/host/ehci-mxc.c44
2 files changed, 75 insertions, 14 deletions
diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c
index 9fc65bbc9d77..2f9eae213094 100644
--- a/arch/arm/mach-mx5/clock-mx51-mx53.c
+++ b/arch/arm/mach-mx5/clock-mx51-mx53.c
@@ -954,6 +954,41 @@ static struct clk usboh3_clk = {
954 .parent = &pll2_sw_clk, 954 .parent = &pll2_sw_clk,
955 .get_rate = clk_usboh3_get_rate, 955 .get_rate = clk_usboh3_get_rate,
956 .set_parent = clk_usboh3_set_parent, 956 .set_parent = clk_usboh3_set_parent,
957 .enable = _clk_ccgr_enable,
958 .disable = _clk_ccgr_disable,
959 .enable_reg = MXC_CCM_CCGR2,
960 .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
961};
962
963static struct clk usb_ahb_clk = {
964 .parent = &ipg_clk,
965 .enable = _clk_ccgr_enable,
966 .disable = _clk_ccgr_disable,
967 .enable_reg = MXC_CCM_CCGR2,
968 .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
969};
970
971static int clk_usb_phy1_set_parent(struct clk *clk, struct clk *parent)
972{
973 u32 reg;
974
975 reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USB_PHY_CLK_SEL;
976
977 if (parent == &pll3_sw_clk)
978 reg |= 1 << MXC_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET;
979
980 __raw_writel(reg, MXC_CCM_CSCMR1);
981
982 return 0;
983}
984
985static struct clk usb_phy1_clk = {
986 .parent = &pll3_sw_clk,
987 .set_parent = clk_usb_phy1_set_parent,
988 .enable = _clk_ccgr_enable,
989 .enable_reg = MXC_CCM_CCGR2,
990 .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
991 .disable = _clk_ccgr_disable,
957}; 992};
958 993
959/* eCSPI */ 994/* eCSPI */
@@ -1094,9 +1129,12 @@ static struct clk_lookup mx51_lookups[] = {
1094 _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) 1129 _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
1095 _REGISTER_CLOCK("imx-i2c.2", NULL, hsi2c_clk) 1130 _REGISTER_CLOCK("imx-i2c.2", NULL, hsi2c_clk)
1096 _REGISTER_CLOCK("mxc-ehci.0", "usb", usboh3_clk) 1131 _REGISTER_CLOCK("mxc-ehci.0", "usb", usboh3_clk)
1097 _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", ahb_clk) 1132 _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_ahb_clk)
1133 _REGISTER_CLOCK("mxc-ehci.0", "usb_phy1", usb_phy1_clk)
1098 _REGISTER_CLOCK("mxc-ehci.1", "usb", usboh3_clk) 1134 _REGISTER_CLOCK("mxc-ehci.1", "usb", usboh3_clk)
1099 _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", ahb_clk) 1135 _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_ahb_clk)
1136 _REGISTER_CLOCK("mxc-ehci.2", "usb", usboh3_clk)
1137 _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_ahb_clk)
1100 _REGISTER_CLOCK("fsl-usb2-udc", "usb", usboh3_clk) 1138 _REGISTER_CLOCK("fsl-usb2-udc", "usb", usboh3_clk)
1101 _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", ahb_clk) 1139 _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", ahb_clk)
1102 _REGISTER_CLOCK("imx-keypad.0", NULL, kpp_clk) 1140 _REGISTER_CLOCK("imx-keypad.0", NULL, kpp_clk)
@@ -1170,6 +1208,9 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
1170 mx51_revision(); 1208 mx51_revision();
1171 clk_disable(&iim_clk); 1209 clk_disable(&iim_clk);
1172 1210
1211 /* move usb_phy_clk to 24MHz */
1212 clk_set_parent(&usb_phy1_clk, &osc_clk);
1213
1173 /* set the usboh3_clk parent to pll2_sw_clk */ 1214 /* set the usboh3_clk parent to pll2_sw_clk */
1174 clk_set_parent(&usboh3_clk, &pll2_sw_clk); 1215 clk_set_parent(&usboh3_clk, &pll2_sw_clk);
1175 1216
diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c
index bce85055019a..a22d2df769a9 100644
--- a/drivers/usb/host/ehci-mxc.c
+++ b/drivers/usb/host/ehci-mxc.c
@@ -28,7 +28,7 @@
28#define ULPI_VIEWPORT_OFFSET 0x170 28#define ULPI_VIEWPORT_OFFSET 0x170
29 29
30struct ehci_mxc_priv { 30struct ehci_mxc_priv {
31 struct clk *usbclk, *ahbclk; 31 struct clk *usbclk, *ahbclk, *phy1clk;
32 struct usb_hcd *hcd; 32 struct usb_hcd *hcd;
33}; 33};
34 34
@@ -168,17 +168,6 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
168 goto err_ioremap; 168 goto err_ioremap;
169 } 169 }
170 170
171 /* call platform specific init function */
172 if (pdata->init) {
173 ret = pdata->init(pdev);
174 if (ret) {
175 dev_err(dev, "platform init failed\n");
176 goto err_init;
177 }
178 /* platforms need some time to settle changed IO settings */
179 mdelay(10);
180 }
181
182 /* enable clocks */ 171 /* enable clocks */
183 priv->usbclk = clk_get(dev, "usb"); 172 priv->usbclk = clk_get(dev, "usb");
184 if (IS_ERR(priv->usbclk)) { 173 if (IS_ERR(priv->usbclk)) {
@@ -196,6 +185,28 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
196 clk_enable(priv->ahbclk); 185 clk_enable(priv->ahbclk);
197 } 186 }
198 187
188 /* "dr" device has its own clock */
189 if (pdev->id == 0) {
190 priv->phy1clk = clk_get(dev, "usb_phy1");
191 if (IS_ERR(priv->phy1clk)) {
192 ret = PTR_ERR(priv->phy1clk);
193 goto err_clk_phy;
194 }
195 clk_enable(priv->phy1clk);
196 }
197
198
199 /* call platform specific init function */
200 if (pdata->init) {
201 ret = pdata->init(pdev);
202 if (ret) {
203 dev_err(dev, "platform init failed\n");
204 goto err_init;
205 }
206 /* platforms need some time to settle changed IO settings */
207 mdelay(10);
208 }
209
199 /* setup specific usb hw */ 210 /* setup specific usb hw */
200 ret = mxc_initialize_usb_hw(pdev->id, pdata->flags); 211 ret = mxc_initialize_usb_hw(pdev->id, pdata->flags);
201 if (ret < 0) 212 if (ret < 0)
@@ -230,6 +241,11 @@ err_add:
230 if (pdata && pdata->exit) 241 if (pdata && pdata->exit)
231 pdata->exit(pdev); 242 pdata->exit(pdev);
232err_init: 243err_init:
244 if (priv->phy1clk) {
245 clk_disable(priv->phy1clk);
246 clk_put(priv->phy1clk);
247 }
248err_clk_phy:
233 if (priv->ahbclk) { 249 if (priv->ahbclk) {
234 clk_disable(priv->ahbclk); 250 clk_disable(priv->ahbclk);
235 clk_put(priv->ahbclk); 251 clk_put(priv->ahbclk);
@@ -273,6 +289,10 @@ static int __exit ehci_mxc_drv_remove(struct platform_device *pdev)
273 clk_disable(priv->ahbclk); 289 clk_disable(priv->ahbclk);
274 clk_put(priv->ahbclk); 290 clk_put(priv->ahbclk);
275 } 291 }
292 if (priv->phy1clk) {
293 clk_disable(priv->phy1clk);
294 clk_put(priv->phy1clk);
295 }
276 296
277 kfree(priv); 297 kfree(priv);
278 298