diff options
Diffstat (limited to 'arch/avr32/mach-at32ap/at32ap700x.c')
| -rw-r--r-- | arch/avr32/mach-at32ap/at32ap700x.c | 243 |
1 files changed, 224 insertions, 19 deletions
diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c index 7678fee9a885..0f24b4f85c17 100644 --- a/arch/avr32/mach-at32ap/at32ap700x.c +++ b/arch/avr32/mach-at32ap/at32ap700x.c | |||
| @@ -6,11 +6,13 @@ | |||
| 6 | * published by the Free Software Foundation. | 6 | * published by the Free Software Foundation. |
| 7 | */ | 7 | */ |
| 8 | #include <linux/clk.h> | 8 | #include <linux/clk.h> |
| 9 | #include <linux/delay.h> | ||
| 9 | #include <linux/fb.h> | 10 | #include <linux/fb.h> |
| 10 | #include <linux/init.h> | 11 | #include <linux/init.h> |
| 11 | #include <linux/platform_device.h> | 12 | #include <linux/platform_device.h> |
| 12 | #include <linux/dma-mapping.h> | 13 | #include <linux/dma-mapping.h> |
| 13 | #include <linux/spi/spi.h> | 14 | #include <linux/spi/spi.h> |
| 15 | #include <linux/usb/atmel_usba_udc.h> | ||
| 14 | 16 | ||
| 15 | #include <asm/io.h> | 17 | #include <asm/io.h> |
| 16 | #include <asm/irq.h> | 18 | #include <asm/irq.h> |
| @@ -98,6 +100,9 @@ unsigned long at32ap7000_osc_rates[3] = { | |||
| 98 | [2] = 12000000, | 100 | [2] = 12000000, |
| 99 | }; | 101 | }; |
| 100 | 102 | ||
| 103 | static struct clk osc0; | ||
| 104 | static struct clk osc1; | ||
| 105 | |||
| 101 | static unsigned long osc_get_rate(struct clk *clk) | 106 | static unsigned long osc_get_rate(struct clk *clk) |
| 102 | { | 107 | { |
| 103 | return at32ap7000_osc_rates[clk->index]; | 108 | return at32ap7000_osc_rates[clk->index]; |
| @@ -107,9 +112,6 @@ static unsigned long pll_get_rate(struct clk *clk, unsigned long control) | |||
| 107 | { | 112 | { |
| 108 | unsigned long div, mul, rate; | 113 | unsigned long div, mul, rate; |
| 109 | 114 | ||
| 110 | if (!(control & PM_BIT(PLLEN))) | ||
| 111 | return 0; | ||
| 112 | |||
| 113 | div = PM_BFEXT(PLLDIV, control) + 1; | 115 | div = PM_BFEXT(PLLDIV, control) + 1; |
| 114 | mul = PM_BFEXT(PLLMUL, control) + 1; | 116 | mul = PM_BFEXT(PLLMUL, control) + 1; |
| 115 | 117 | ||
| @@ -120,6 +122,71 @@ static unsigned long pll_get_rate(struct clk *clk, unsigned long control) | |||
| 120 | return rate; | 122 | return rate; |
| 121 | } | 123 | } |
| 122 | 124 | ||
| 125 | static long pll_set_rate(struct clk *clk, unsigned long rate, | ||
| 126 | u32 *pll_ctrl) | ||
| 127 | { | ||
| 128 | unsigned long mul; | ||
| 129 | unsigned long mul_best_fit = 0; | ||
| 130 | unsigned long div; | ||
| 131 | unsigned long div_min; | ||
| 132 | unsigned long div_max; | ||
| 133 | unsigned long div_best_fit = 0; | ||
| 134 | unsigned long base; | ||
| 135 | unsigned long pll_in; | ||
| 136 | unsigned long actual = 0; | ||
| 137 | unsigned long rate_error; | ||
| 138 | unsigned long rate_error_prev = ~0UL; | ||
| 139 | u32 ctrl; | ||
| 140 | |||
| 141 | /* Rate must be between 80 MHz and 200 Mhz. */ | ||
| 142 | if (rate < 80000000UL || rate > 200000000UL) | ||
| 143 | return -EINVAL; | ||
| 144 | |||
| 145 | ctrl = PM_BF(PLLOPT, 4); | ||
| 146 | base = clk->parent->get_rate(clk->parent); | ||
| 147 | |||
| 148 | /* PLL input frequency must be between 6 MHz and 32 MHz. */ | ||
| 149 | div_min = DIV_ROUND_UP(base, 32000000UL); | ||
| 150 | div_max = base / 6000000UL; | ||
| 151 | |||
| 152 | if (div_max < div_min) | ||
| 153 | return -EINVAL; | ||
| 154 | |||
| 155 | for (div = div_min; div <= div_max; div++) { | ||
| 156 | pll_in = (base + div / 2) / div; | ||
| 157 | mul = (rate + pll_in / 2) / pll_in; | ||
| 158 | |||
| 159 | if (mul == 0) | ||
| 160 | continue; | ||
| 161 | |||
| 162 | actual = pll_in * mul; | ||
| 163 | rate_error = abs(actual - rate); | ||
| 164 | |||
| 165 | if (rate_error < rate_error_prev) { | ||
| 166 | mul_best_fit = mul; | ||
| 167 | div_best_fit = div; | ||
| 168 | rate_error_prev = rate_error; | ||
| 169 | } | ||
| 170 | |||
| 171 | if (rate_error == 0) | ||
| 172 | break; | ||
| 173 | } | ||
| 174 | |||
| 175 | if (div_best_fit == 0) | ||
| 176 | return -EINVAL; | ||
| 177 | |||
| 178 | ctrl |= PM_BF(PLLMUL, mul_best_fit - 1); | ||
| 179 | ctrl |= PM_BF(PLLDIV, div_best_fit - 1); | ||
| 180 | ctrl |= PM_BF(PLLCOUNT, 16); | ||
| 181 | |||
| 182 | if (clk->parent == &osc1) | ||
| 183 | ctrl |= PM_BIT(PLLOSC); | ||
| 184 | |||
| 185 | *pll_ctrl = ctrl; | ||
| 186 | |||
| 187 | return actual; | ||
| 188 | } | ||
| 189 | |||
| 123 | static unsigned long pll0_get_rate(struct clk *clk) | 190 | static unsigned long pll0_get_rate(struct clk *clk) |
| 124 | { | 191 | { |
| 125 | u32 control; | 192 | u32 control; |
| @@ -129,6 +196,41 @@ static unsigned long pll0_get_rate(struct clk *clk) | |||
| 129 | return pll_get_rate(clk, control); | 196 | return pll_get_rate(clk, control); |
| 130 | } | 197 | } |
| 131 | 198 | ||
| 199 | static void pll1_mode(struct clk *clk, int enabled) | ||
| 200 | { | ||
| 201 | unsigned long timeout; | ||
| 202 | u32 status; | ||
| 203 | u32 ctrl; | ||
| 204 | |||
| 205 | ctrl = pm_readl(PLL1); | ||
| 206 | |||
| 207 | if (enabled) { | ||
| 208 | if (!PM_BFEXT(PLLMUL, ctrl) && !PM_BFEXT(PLLDIV, ctrl)) { | ||
| 209 | pr_debug("clk %s: failed to enable, rate not set\n", | ||
| 210 | clk->name); | ||
| 211 | return; | ||
| 212 | } | ||
| 213 | |||
| 214 | ctrl |= PM_BIT(PLLEN); | ||
| 215 | pm_writel(PLL1, ctrl); | ||
| 216 | |||
| 217 | /* Wait for PLL lock. */ | ||
| 218 | for (timeout = 10000; timeout; timeout--) { | ||
| 219 | status = pm_readl(ISR); | ||
| 220 | if (status & PM_BIT(LOCK1)) | ||
| 221 | break; | ||
| 222 | udelay(10); | ||
| 223 | } | ||
| 224 | |||
| 225 | if (!(status & PM_BIT(LOCK1))) | ||
| 226 | printk(KERN_ERR "clk %s: timeout waiting for lock\n", | ||
| 227 | clk->name); | ||
| 228 | } else { | ||
| 229 | ctrl &= ~PM_BIT(PLLEN); | ||
| 230 | pm_writel(PLL1, ctrl); | ||
| 231 | } | ||
| 232 | } | ||
| 233 | |||
| 132 | static unsigned long pll1_get_rate(struct clk *clk) | 234 | static unsigned long pll1_get_rate(struct clk *clk) |
| 133 | { | 235 | { |
| 134 | u32 control; | 236 | u32 control; |
| @@ -138,6 +240,49 @@ static unsigned long pll1_get_rate(struct clk *clk) | |||
| 138 | return pll_get_rate(clk, control); | 240 | return pll_get_rate(clk, control); |
| 139 | } | 241 | } |
| 140 | 242 | ||
| 243 | static long pll1_set_rate(struct clk *clk, unsigned long rate, int apply) | ||
| 244 | { | ||
| 245 | u32 ctrl = 0; | ||
| 246 | unsigned long actual_rate; | ||
| 247 | |||
| 248 | actual_rate = pll_set_rate(clk, rate, &ctrl); | ||
| 249 | |||
| 250 | if (apply) { | ||
| 251 | if (actual_rate != rate) | ||
| 252 | return -EINVAL; | ||
| 253 | if (clk->users > 0) | ||
| 254 | return -EBUSY; | ||
| 255 | pr_debug(KERN_INFO "clk %s: new rate %lu (actual rate %lu)\n", | ||
| 256 | clk->name, rate, actual_rate); | ||
| 257 | pm_writel(PLL1, ctrl); | ||
| 258 | } | ||
| 259 | |||
| 260 | return actual_rate; | ||
| 261 | } | ||
| 262 | |||
| 263 | static int pll1_set_parent(struct clk *clk, struct clk *parent) | ||
| 264 | { | ||
| 265 | u32 ctrl; | ||
| 266 | |||
| 267 | if (clk->users > 0) | ||
| 268 | return -EBUSY; | ||
| 269 | |||
| 270 | ctrl = pm_readl(PLL1); | ||
| 271 | WARN_ON(ctrl & PM_BIT(PLLEN)); | ||
| 272 | |||
| 273 | if (parent == &osc0) | ||
| 274 | ctrl &= ~PM_BIT(PLLOSC); | ||
| 275 | else if (parent == &osc1) | ||
| 276 | ctrl |= PM_BIT(PLLOSC); | ||
| 277 | else | ||
| 278 | return -EINVAL; | ||
| 279 | |||
| 280 | pm_writel(PLL1, ctrl); | ||
| 281 | clk->parent = parent; | ||
| 282 | |||
| 283 | return 0; | ||
| 284 | } | ||
| 285 | |||
| 141 | /* | 286 | /* |
| 142 | * The AT32AP7000 has five primary clock sources: One 32kHz | 287 | * The AT32AP7000 has five primary clock sources: One 32kHz |
| 143 | * oscillator, two crystal oscillators and two PLLs. | 288 | * oscillator, two crystal oscillators and two PLLs. |
| @@ -166,7 +311,10 @@ static struct clk pll0 = { | |||
| 166 | }; | 311 | }; |
| 167 | static struct clk pll1 = { | 312 | static struct clk pll1 = { |
| 168 | .name = "pll1", | 313 | .name = "pll1", |
| 314 | .mode = pll1_mode, | ||
| 169 | .get_rate = pll1_get_rate, | 315 | .get_rate = pll1_get_rate, |
| 316 | .set_rate = pll1_set_rate, | ||
| 317 | .set_parent = pll1_set_parent, | ||
| 170 | .parent = &osc0, | 318 | .parent = &osc0, |
| 171 | }; | 319 | }; |
| 172 | 320 | ||
| @@ -605,19 +753,32 @@ static inline void set_ebi_sfr_bits(u32 mask) | |||
| 605 | } | 753 | } |
| 606 | 754 | ||
| 607 | /* -------------------------------------------------------------------- | 755 | /* -------------------------------------------------------------------- |
| 608 | * System Timer/Counter (TC) | 756 | * Timer/Counter (TC) |
| 609 | * -------------------------------------------------------------------- */ | 757 | * -------------------------------------------------------------------- */ |
| 610 | static struct resource at32_systc0_resource[] = { | 758 | |
| 759 | static struct resource at32_tcb0_resource[] = { | ||
| 611 | PBMEM(0xfff00c00), | 760 | PBMEM(0xfff00c00), |
| 612 | IRQ(22), | 761 | IRQ(22), |
| 613 | }; | 762 | }; |
| 614 | struct platform_device at32_systc0_device = { | 763 | static struct platform_device at32_tcb0_device = { |
| 615 | .name = "systc", | 764 | .name = "atmel_tcb", |
| 616 | .id = 0, | 765 | .id = 0, |
| 617 | .resource = at32_systc0_resource, | 766 | .resource = at32_tcb0_resource, |
| 618 | .num_resources = ARRAY_SIZE(at32_systc0_resource), | 767 | .num_resources = ARRAY_SIZE(at32_tcb0_resource), |
| 619 | }; | 768 | }; |
| 620 | DEV_CLK(pclk, at32_systc0, pbb, 3); | 769 | DEV_CLK(t0_clk, at32_tcb0, pbb, 3); |
| 770 | |||
| 771 | static struct resource at32_tcb1_resource[] = { | ||
| 772 | PBMEM(0xfff01000), | ||
| 773 | IRQ(23), | ||
| 774 | }; | ||
| 775 | static struct platform_device at32_tcb1_device = { | ||
| 776 | .name = "atmel_tcb", | ||
| 777 | .id = 1, | ||
| 778 | .resource = at32_tcb1_resource, | ||
| 779 | .num_resources = ARRAY_SIZE(at32_tcb1_resource), | ||
| 780 | }; | ||
| 781 | DEV_CLK(t0_clk, at32_tcb1, pbb, 4); | ||
| 621 | 782 | ||
| 622 | /* -------------------------------------------------------------------- | 783 | /* -------------------------------------------------------------------- |
| 623 | * PIO | 784 | * PIO |
| @@ -669,7 +830,8 @@ void __init at32_add_system_devices(void) | |||
| 669 | platform_device_register(&pdc_device); | 830 | platform_device_register(&pdc_device); |
| 670 | platform_device_register(&dmaca0_device); | 831 | platform_device_register(&dmaca0_device); |
| 671 | 832 | ||
| 672 | platform_device_register(&at32_systc0_device); | 833 | platform_device_register(&at32_tcb0_device); |
| 834 | platform_device_register(&at32_tcb1_device); | ||
| 673 | 835 | ||
| 674 | platform_device_register(&pio0_device); | 836 | platform_device_register(&pio0_device); |
| 675 | platform_device_register(&pio1_device); | 837 | platform_device_register(&pio1_device); |
| @@ -989,7 +1151,9 @@ static struct clk atmel_twi0_pclk = { | |||
| 989 | .index = 2, | 1151 | .index = 2, |
| 990 | }; | 1152 | }; |
| 991 | 1153 | ||
| 992 | struct platform_device *__init at32_add_device_twi(unsigned int id) | 1154 | struct platform_device *__init at32_add_device_twi(unsigned int id, |
| 1155 | struct i2c_board_info *b, | ||
| 1156 | unsigned int n) | ||
| 993 | { | 1157 | { |
| 994 | struct platform_device *pdev; | 1158 | struct platform_device *pdev; |
| 995 | 1159 | ||
| @@ -1009,6 +1173,9 @@ struct platform_device *__init at32_add_device_twi(unsigned int id) | |||
| 1009 | 1173 | ||
| 1010 | atmel_twi0_pclk.dev = &pdev->dev; | 1174 | atmel_twi0_pclk.dev = &pdev->dev; |
| 1011 | 1175 | ||
| 1176 | if (b) | ||
| 1177 | i2c_register_board_info(id, b, n); | ||
| 1178 | |||
| 1012 | platform_device_add(pdev); | 1179 | platform_device_add(pdev); |
| 1013 | return pdev; | 1180 | return pdev; |
| 1014 | 1181 | ||
| @@ -1351,9 +1518,39 @@ static struct clk usba0_hclk = { | |||
| 1351 | .index = 6, | 1518 | .index = 6, |
| 1352 | }; | 1519 | }; |
| 1353 | 1520 | ||
| 1521 | #define EP(nam, idx, maxpkt, maxbk, dma, isoc) \ | ||
| 1522 | [idx] = { \ | ||
| 1523 | .name = nam, \ | ||
| 1524 | .index = idx, \ | ||
| 1525 | .fifo_size = maxpkt, \ | ||
| 1526 | .nr_banks = maxbk, \ | ||
| 1527 | .can_dma = dma, \ | ||
| 1528 | .can_isoc = isoc, \ | ||
| 1529 | } | ||
| 1530 | |||
| 1531 | static struct usba_ep_data at32_usba_ep[] __initdata = { | ||
| 1532 | EP("ep0", 0, 64, 1, 0, 0), | ||
| 1533 | EP("ep1", 1, 512, 2, 1, 1), | ||
| 1534 | EP("ep2", 2, 512, 2, 1, 1), | ||
| 1535 | EP("ep3-int", 3, 64, 3, 1, 0), | ||
| 1536 | EP("ep4-int", 4, 64, 3, 1, 0), | ||
| 1537 | EP("ep5", 5, 1024, 3, 1, 1), | ||
| 1538 | EP("ep6", 6, 1024, 3, 1, 1), | ||
| 1539 | }; | ||
| 1540 | |||
| 1541 | #undef EP | ||
| 1542 | |||
| 1354 | struct platform_device *__init | 1543 | struct platform_device *__init |
| 1355 | at32_add_device_usba(unsigned int id, struct usba_platform_data *data) | 1544 | at32_add_device_usba(unsigned int id, struct usba_platform_data *data) |
| 1356 | { | 1545 | { |
| 1546 | /* | ||
| 1547 | * pdata doesn't have room for any endpoints, so we need to | ||
| 1548 | * append room for the ones we need right after it. | ||
| 1549 | */ | ||
| 1550 | struct { | ||
| 1551 | struct usba_platform_data pdata; | ||
| 1552 | struct usba_ep_data ep[7]; | ||
| 1553 | } usba_data; | ||
| 1357 | struct platform_device *pdev; | 1554 | struct platform_device *pdev; |
| 1358 | 1555 | ||
| 1359 | if (id != 0) | 1556 | if (id != 0) |
| @@ -1367,13 +1564,20 @@ at32_add_device_usba(unsigned int id, struct usba_platform_data *data) | |||
| 1367 | ARRAY_SIZE(usba0_resource))) | 1564 | ARRAY_SIZE(usba0_resource))) |
| 1368 | goto out_free_pdev; | 1565 | goto out_free_pdev; |
| 1369 | 1566 | ||
| 1370 | if (data) { | 1567 | if (data) |
| 1371 | if (platform_device_add_data(pdev, data, sizeof(*data))) | 1568 | usba_data.pdata.vbus_pin = data->vbus_pin; |
| 1372 | goto out_free_pdev; | 1569 | else |
| 1570 | usba_data.pdata.vbus_pin = -EINVAL; | ||
| 1571 | |||
| 1572 | data = &usba_data.pdata; | ||
| 1573 | data->num_ep = ARRAY_SIZE(at32_usba_ep); | ||
| 1574 | memcpy(data->ep, at32_usba_ep, sizeof(at32_usba_ep)); | ||
| 1373 | 1575 | ||
| 1374 | if (data->vbus_pin != GPIO_PIN_NONE) | 1576 | if (platform_device_add_data(pdev, data, sizeof(usba_data))) |
| 1375 | at32_select_gpio(data->vbus_pin, 0); | 1577 | goto out_free_pdev; |
| 1376 | } | 1578 | |
| 1579 | if (data->vbus_pin >= 0) | ||
| 1580 | at32_select_gpio(data->vbus_pin, 0); | ||
| 1377 | 1581 | ||
| 1378 | usba0_pclk.dev = &pdev->dev; | 1582 | usba0_pclk.dev = &pdev->dev; |
| 1379 | usba0_hclk.dev = &pdev->dev; | 1583 | usba0_hclk.dev = &pdev->dev; |
| @@ -1694,7 +1898,8 @@ struct clk *at32_clock_list[] = { | |||
| 1694 | &pio2_mck, | 1898 | &pio2_mck, |
| 1695 | &pio3_mck, | 1899 | &pio3_mck, |
| 1696 | &pio4_mck, | 1900 | &pio4_mck, |
| 1697 | &at32_systc0_pclk, | 1901 | &at32_tcb0_t0_clk, |
| 1902 | &at32_tcb1_t0_clk, | ||
| 1698 | &atmel_usart0_usart, | 1903 | &atmel_usart0_usart, |
| 1699 | &atmel_usart1_usart, | 1904 | &atmel_usart1_usart, |
| 1700 | &atmel_usart2_usart, | 1905 | &atmel_usart2_usart, |
