diff options
Diffstat (limited to 'arch/arm/plat-omap/clock.c')
-rw-r--r-- | arch/arm/plat-omap/clock.c | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index 59d91b3262ba..52a58b2da288 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <asm/arch/usb.h> | 21 | #include <asm/arch/usb.h> |
22 | 22 | ||
23 | #include "clock.h" | 23 | #include "clock.h" |
24 | #include "sram.h" | ||
24 | 25 | ||
25 | static LIST_HEAD(clocks); | 26 | static LIST_HEAD(clocks); |
26 | static DECLARE_MUTEX(clocks_sem); | 27 | static DECLARE_MUTEX(clocks_sem); |
@@ -141,7 +142,7 @@ static struct clk arm_ck = { | |||
141 | static struct clk armper_ck = { | 142 | static struct clk armper_ck = { |
142 | .name = "armper_ck", | 143 | .name = "armper_ck", |
143 | .parent = &ck_dpll1, | 144 | .parent = &ck_dpll1, |
144 | .flags = CLOCK_IN_OMAP730 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | 145 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | |
145 | RATE_CKCTL, | 146 | RATE_CKCTL, |
146 | .enable_reg = ARM_IDLECT2, | 147 | .enable_reg = ARM_IDLECT2, |
147 | .enable_bit = EN_PERCK, | 148 | .enable_bit = EN_PERCK, |
@@ -385,7 +386,8 @@ static struct clk uart2_ck = { | |||
385 | .name = "uart2_ck", | 386 | .name = "uart2_ck", |
386 | /* Direct from ULPD, no parent */ | 387 | /* Direct from ULPD, no parent */ |
387 | .rate = 12000000, | 388 | .rate = 12000000, |
388 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | ENABLE_REG_32BIT, | 389 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | ENABLE_REG_32BIT | |
390 | ALWAYS_ENABLED, | ||
389 | .enable_reg = MOD_CONF_CTRL_0, | 391 | .enable_reg = MOD_CONF_CTRL_0, |
390 | .enable_bit = 30, /* Chooses between 12MHz and 48MHz */ | 392 | .enable_bit = 30, /* Chooses between 12MHz and 48MHz */ |
391 | .set_rate = &set_uart_rate, | 393 | .set_rate = &set_uart_rate, |
@@ -443,6 +445,15 @@ static struct clk usb_hhc_ck16xx = { | |||
443 | .enable_bit = 8 /* UHOST_EN */, | 445 | .enable_bit = 8 /* UHOST_EN */, |
444 | }; | 446 | }; |
445 | 447 | ||
448 | static struct clk usb_dc_ck = { | ||
449 | .name = "usb_dc_ck", | ||
450 | /* Direct from ULPD, no parent */ | ||
451 | .rate = 48000000, | ||
452 | .flags = CLOCK_IN_OMAP16XX | RATE_FIXED, | ||
453 | .enable_reg = SOFT_REQ_REG, | ||
454 | .enable_bit = 4, | ||
455 | }; | ||
456 | |||
446 | static struct clk mclk_1510 = { | 457 | static struct clk mclk_1510 = { |
447 | .name = "mclk", | 458 | .name = "mclk", |
448 | /* Direct from ULPD, no parent. May be enabled by ext hardware. */ | 459 | /* Direct from ULPD, no parent. May be enabled by ext hardware. */ |
@@ -552,6 +563,7 @@ static struct clk * onchip_clks[] = { | |||
552 | &uart3_16xx, | 563 | &uart3_16xx, |
553 | &usb_clko, | 564 | &usb_clko, |
554 | &usb_hhc_ck1510, &usb_hhc_ck16xx, | 565 | &usb_hhc_ck1510, &usb_hhc_ck16xx, |
566 | &usb_dc_ck, | ||
555 | &mclk_1510, &mclk_16xx, | 567 | &mclk_1510, &mclk_16xx, |
556 | &bclk_1510, &bclk_16xx, | 568 | &bclk_1510, &bclk_16xx, |
557 | &mmc1_ck, | 569 | &mmc1_ck, |
@@ -946,14 +958,13 @@ static int select_table_rate(struct clk * clk, unsigned long rate) | |||
946 | if (!ptr->rate) | 958 | if (!ptr->rate) |
947 | return -EINVAL; | 959 | return -EINVAL; |
948 | 960 | ||
949 | if (!ptr->rate) | 961 | /* |
950 | return -EINVAL; | 962 | * In most cases we should not need to reprogram DPLL. |
963 | * Reprogramming the DPLL is tricky, it must be done from SRAM. | ||
964 | */ | ||
965 | omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val); | ||
951 | 966 | ||
952 | if (unlikely(ck_dpll1.rate == 0)) { | 967 | ck_dpll1.rate = ptr->pll_rate; |
953 | omap_writew(ptr->dpllctl_val, DPLL_CTL); | ||
954 | ck_dpll1.rate = ptr->pll_rate; | ||
955 | } | ||
956 | omap_writew(ptr->ckctl_val, ARM_CKCTL); | ||
957 | propagate_rate(&ck_dpll1); | 968 | propagate_rate(&ck_dpll1); |
958 | return 0; | 969 | return 0; |
959 | } | 970 | } |
@@ -1224,9 +1235,11 @@ int __init clk_init(void) | |||
1224 | #endif | 1235 | #endif |
1225 | /* Cache rates for clocks connected to ck_ref (not dpll1) */ | 1236 | /* Cache rates for clocks connected to ck_ref (not dpll1) */ |
1226 | propagate_rate(&ck_ref); | 1237 | propagate_rate(&ck_ref); |
1227 | printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): %ld.%01ld/%ld/%ld MHz\n", | 1238 | printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): " |
1239 | "%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n", | ||
1228 | ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10, | 1240 | ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10, |
1229 | ck_dpll1.rate, arm_ck.rate); | 1241 | ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10, |
1242 | arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10); | ||
1230 | 1243 | ||
1231 | #ifdef CONFIG_MACH_OMAP_PERSEUS2 | 1244 | #ifdef CONFIG_MACH_OMAP_PERSEUS2 |
1232 | /* Select slicer output as OMAP input clock */ | 1245 | /* Select slicer output as OMAP input clock */ |
@@ -1271,7 +1284,9 @@ static int __init omap_late_clk_reset(void) | |||
1271 | struct clk *p; | 1284 | struct clk *p; |
1272 | __u32 regval32; | 1285 | __u32 regval32; |
1273 | 1286 | ||
1274 | omap_writew(0, SOFT_REQ_REG); | 1287 | /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */ |
1288 | regval32 = omap_readw(SOFT_REQ_REG) & (1 << 4); | ||
1289 | omap_writew(regval32, SOFT_REQ_REG); | ||
1275 | omap_writew(0, SOFT_REQ_REG2); | 1290 | omap_writew(0, SOFT_REQ_REG2); |
1276 | 1291 | ||
1277 | list_for_each_entry(p, &clocks, node) { | 1292 | list_for_each_entry(p, &clocks, node) { |