aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-lpc32xx/clock.c87
-rw-r--r--arch/arm/mach-lpc32xx/common.c26
-rw-r--r--arch/arm/mach-lpc32xx/common.h1
-rw-r--r--arch/arm/mach-lpc32xx/phy3250.c1
4 files changed, 91 insertions, 24 deletions
diff --git a/arch/arm/mach-lpc32xx/clock.c b/arch/arm/mach-lpc32xx/clock.c
index ab8c21647422..370a5471798e 100644
--- a/arch/arm/mach-lpc32xx/clock.c
+++ b/arch/arm/mach-lpc32xx/clock.c
@@ -87,6 +87,7 @@
87#include <linux/list.h> 87#include <linux/list.h>
88#include <linux/errno.h> 88#include <linux/errno.h>
89#include <linux/device.h> 89#include <linux/device.h>
90#include <linux/delay.h>
90#include <linux/err.h> 91#include <linux/err.h>
91#include <linux/clk.h> 92#include <linux/clk.h>
92#include <linux/amba/bus.h> 93#include <linux/amba/bus.h>
@@ -100,6 +101,8 @@
100 101
101static DEFINE_SPINLOCK(global_clkregs_lock); 102static DEFINE_SPINLOCK(global_clkregs_lock);
102 103
104static int usb_pll_enable, usb_pll_valid;
105
103static struct clk clk_armpll; 106static struct clk clk_armpll;
104static struct clk clk_usbpll; 107static struct clk clk_usbpll;
105 108
@@ -384,30 +387,62 @@ static u32 local_clk_usbpll_setup(struct clk_pll_setup *pHCLKPllSetup)
384static int local_usbpll_enable(struct clk *clk, int enable) 387static int local_usbpll_enable(struct clk *clk, int enable)
385{ 388{
386 u32 reg; 389 u32 reg;
387 int ret = -ENODEV; 390 int ret = 0;
388 unsigned long timeout = jiffies + msecs_to_jiffies(10); 391 unsigned long timeout = jiffies + msecs_to_jiffies(20);
389 392
390 reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL); 393 reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
391 394
392 if (enable == 0) { 395 __raw_writel(reg & ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN2 |
393 reg &= ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN1 | 396 LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP),
394 LPC32XX_CLKPWR_USBCTRL_CLK_EN2); 397 LPC32XX_CLKPWR_USB_CTRL);
395 __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); 398 __raw_writel(reg & ~LPC32XX_CLKPWR_USBCTRL_CLK_EN1,
396 } else if (reg & LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP) { 399 LPC32XX_CLKPWR_USB_CTRL);
400
401 if (enable && usb_pll_valid && usb_pll_enable) {
402 ret = -ENODEV;
403 /*
404 * If the PLL rate has been previously set, then the rate
405 * in the PLL register is valid and can be enabled here.
406 * Otherwise, it needs to be enabled as part of setrate.
407 */
408
409 /*
410 * Gate clock into PLL
411 */
397 reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN1; 412 reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN1;
398 __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); 413 __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
399 414
400 /* Wait for PLL lock */ 415 /*
416 * Enable PLL
417 */
418 reg |= LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP;
419 __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
420
421 /*
422 * Wait for PLL to lock
423 */
401 while (time_before(jiffies, timeout) && (ret == -ENODEV)) { 424 while (time_before(jiffies, timeout) && (ret == -ENODEV)) {
402 reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL); 425 reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
403 if (reg & LPC32XX_CLKPWR_USBCTRL_PLL_STS) 426 if (reg & LPC32XX_CLKPWR_USBCTRL_PLL_STS)
404 ret = 0; 427 ret = 0;
428 else
429 udelay(10);
405 } 430 }
406 431
432 /*
433 * Gate clock from PLL if PLL is locked
434 */
407 if (ret == 0) { 435 if (ret == 0) {
408 reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN2; 436 __raw_writel(reg | LPC32XX_CLKPWR_USBCTRL_CLK_EN2,
409 __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); 437 LPC32XX_CLKPWR_USB_CTRL);
438 } else {
439 __raw_writel(reg & ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN1 |
440 LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP),
441 LPC32XX_CLKPWR_USB_CTRL);
410 } 442 }
443 } else if ((enable == 0) && usb_pll_valid && usb_pll_enable) {
444 usb_pll_valid = 0;
445 usb_pll_enable = 0;
411 } 446 }
412 447
413 return ret; 448 return ret;
@@ -425,7 +460,7 @@ static unsigned long local_usbpll_round_rate(struct clk *clk,
425 */ 460 */
426 rate = rate * 1000; 461 rate = rate * 1000;
427 462
428 clkin = clk->parent->rate; 463 clkin = clk->get_rate(clk);
429 usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) & 464 usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) &
430 LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1; 465 LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1;
431 clkin = clkin / usbdiv; 466 clkin = clkin / usbdiv;
@@ -439,7 +474,8 @@ static unsigned long local_usbpll_round_rate(struct clk *clk,
439 474
440static int local_usbpll_set_rate(struct clk *clk, unsigned long rate) 475static int local_usbpll_set_rate(struct clk *clk, unsigned long rate)
441{ 476{
442 u32 clkin, reg, usbdiv; 477 int ret = -ENODEV;
478 u32 clkin, usbdiv;
443 struct clk_pll_setup pllsetup; 479 struct clk_pll_setup pllsetup;
444 480
445 /* 481 /*
@@ -448,7 +484,7 @@ static int local_usbpll_set_rate(struct clk *clk, unsigned long rate)
448 */ 484 */
449 rate = rate * 1000; 485 rate = rate * 1000;
450 486
451 clkin = clk->get_rate(clk); 487 clkin = clk->get_rate(clk->parent);
452 usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) & 488 usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) &
453 LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1; 489 LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1;
454 clkin = clkin / usbdiv; 490 clkin = clkin / usbdiv;
@@ -457,22 +493,25 @@ static int local_usbpll_set_rate(struct clk *clk, unsigned long rate)
457 if (local_clk_find_pll_cfg(clkin, rate, &pllsetup) == 0) 493 if (local_clk_find_pll_cfg(clkin, rate, &pllsetup) == 0)
458 return -EINVAL; 494 return -EINVAL;
459 495
496 /*
497 * Disable PLL clocks during PLL change
498 */
460 local_usbpll_enable(clk, 0); 499 local_usbpll_enable(clk, 0);
461 500 pllsetup.analog_on = 0;
462 reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
463 reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN1;
464 __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
465
466 pllsetup.analog_on = 1;
467 local_clk_usbpll_setup(&pllsetup); 501 local_clk_usbpll_setup(&pllsetup);
468 502
469 clk->rate = clk_check_pll_setup(clkin, &pllsetup); 503 /*
504 * Start USB PLL and check PLL status
505 */
506
507 usb_pll_valid = 1;
508 usb_pll_enable = 1;
470 509
471 reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL); 510 ret = local_usbpll_enable(clk, 1);
472 reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN2; 511 if (ret >= 0)
473 __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); 512 clk->rate = clk_check_pll_setup(clkin, &pllsetup);
474 513
475 return 0; 514 return ret;
476} 515}
477 516
478static struct clk clk_usbpll = { 517static struct clk clk_usbpll = {
diff --git a/arch/arm/mach-lpc32xx/common.c b/arch/arm/mach-lpc32xx/common.c
index 6c76bb36559b..11c900857b1b 100644
--- a/arch/arm/mach-lpc32xx/common.c
+++ b/arch/arm/mach-lpc32xx/common.c
@@ -160,6 +160,32 @@ struct platform_device lpc32xx_adc_device = {
160}; 160};
161 161
162/* 162/*
163 * USB support
164 */
165/* The dmamask must be set for OHCI to work */
166static u64 ohci_dmamask = ~(u32) 0;
167static struct resource ohci_resources[] = {
168 {
169 .start = IO_ADDRESS(LPC32XX_USB_BASE),
170 .end = IO_ADDRESS(LPC32XX_USB_BASE + 0x100 - 1),
171 .flags = IORESOURCE_MEM,
172 }, {
173 .start = IRQ_LPC32XX_USB_HOST,
174 .flags = IORESOURCE_IRQ,
175 },
176};
177struct platform_device lpc32xx_ohci_device = {
178 .name = "usb-ohci",
179 .id = -1,
180 .dev = {
181 .dma_mask = &ohci_dmamask,
182 .coherent_dma_mask = 0xFFFFFFFF,
183 },
184 .num_resources = ARRAY_SIZE(ohci_resources),
185 .resource = ohci_resources,
186};
187
188/*
163 * Returns the unique ID for the device 189 * Returns the unique ID for the device
164 */ 190 */
165void lpc32xx_get_uid(u32 devid[4]) 191void lpc32xx_get_uid(u32 devid[4])
diff --git a/arch/arm/mach-lpc32xx/common.h b/arch/arm/mach-lpc32xx/common.h
index 68f2e46d98ad..e1880b02b76b 100644
--- a/arch/arm/mach-lpc32xx/common.h
+++ b/arch/arm/mach-lpc32xx/common.h
@@ -31,6 +31,7 @@ extern struct platform_device lpc32xx_i2c2_device;
31extern struct platform_device lpc32xx_tsc_device; 31extern struct platform_device lpc32xx_tsc_device;
32extern struct platform_device lpc32xx_adc_device; 32extern struct platform_device lpc32xx_adc_device;
33extern struct platform_device lpc32xx_rtc_device; 33extern struct platform_device lpc32xx_rtc_device;
34extern struct platform_device lpc32xx_ohci_device;
34 35
35/* 36/*
36 * Other arch specific structures and functions 37 * Other arch specific structures and functions
diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c
index 4590a8b52e72..53f12301be8a 100644
--- a/arch/arm/mach-lpc32xx/phy3250.c
+++ b/arch/arm/mach-lpc32xx/phy3250.c
@@ -279,6 +279,7 @@ static struct platform_device *phy3250_devs[] __initdata = {
279 &lpc32xx_watchdog_device, 279 &lpc32xx_watchdog_device,
280 &lpc32xx_gpio_led_device, 280 &lpc32xx_gpio_led_device,
281 &lpc32xx_adc_device, 281 &lpc32xx_adc_device,
282 &lpc32xx_ohci_device,
282}; 283};
283 284
284static struct amba_device *amba_devs[] __initdata = { 285static struct amba_device *amba_devs[] __initdata = {