aboutsummaryrefslogtreecommitdiffstats
path: root/arch/avr32/mach-at32ap/at32ap700x.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/avr32/mach-at32ap/at32ap700x.c')
-rw-r--r--arch/avr32/mach-at32ap/at32ap700x.c282
1 files changed, 224 insertions, 58 deletions
diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c
index 0f24b4f85c17..021d51217184 100644
--- a/arch/avr32/mach-at32ap/at32ap700x.c
+++ b/arch/avr32/mach-at32ap/at32ap700x.c
@@ -14,12 +14,14 @@
14#include <linux/spi/spi.h> 14#include <linux/spi/spi.h>
15#include <linux/usb/atmel_usba_udc.h> 15#include <linux/usb/atmel_usba_udc.h>
16 16
17#include <asm/atmel-mci.h>
17#include <asm/io.h> 18#include <asm/io.h>
18#include <asm/irq.h> 19#include <asm/irq.h>
19 20
20#include <asm/arch/at32ap700x.h> 21#include <asm/arch/at32ap700x.h>
21#include <asm/arch/board.h> 22#include <asm/arch/board.h>
22#include <asm/arch/portmux.h> 23#include <asm/arch/portmux.h>
24#include <asm/arch/sram.h>
23 25
24#include <video/atmel_lcdc.h> 26#include <video/atmel_lcdc.h>
25 27
@@ -93,19 +95,12 @@ static struct clk devname##_##_name = { \
93 95
94static DEFINE_SPINLOCK(pm_lock); 96static DEFINE_SPINLOCK(pm_lock);
95 97
96unsigned long at32ap7000_osc_rates[3] = {
97 [0] = 32768,
98 /* FIXME: these are ATSTK1002-specific */
99 [1] = 20000000,
100 [2] = 12000000,
101};
102
103static struct clk osc0; 98static struct clk osc0;
104static struct clk osc1; 99static struct clk osc1;
105 100
106static unsigned long osc_get_rate(struct clk *clk) 101static unsigned long osc_get_rate(struct clk *clk)
107{ 102{
108 return at32ap7000_osc_rates[clk->index]; 103 return at32_board_osc_rates[clk->index];
109} 104}
110 105
111static unsigned long pll_get_rate(struct clk *clk, unsigned long control) 106static unsigned long pll_get_rate(struct clk *clk, unsigned long control)
@@ -682,6 +677,14 @@ static struct clk hramc_clk = {
682 .users = 1, 677 .users = 1,
683 .index = 3, 678 .index = 3,
684}; 679};
680static struct clk sdramc_clk = {
681 .name = "sdramc_clk",
682 .parent = &pbb_clk,
683 .mode = pbb_clk_mode,
684 .get_rate = pbb_clk_get_rate,
685 .users = 1,
686 .index = 14,
687};
685 688
686static struct resource smc0_resource[] = { 689static struct resource smc0_resource[] = {
687 PBMEM(0xfff03400), 690 PBMEM(0xfff03400),
@@ -841,6 +844,81 @@ void __init at32_add_system_devices(void)
841} 844}
842 845
843/* -------------------------------------------------------------------- 846/* --------------------------------------------------------------------
847 * PSIF
848 * -------------------------------------------------------------------- */
849static struct resource atmel_psif0_resource[] __initdata = {
850 {
851 .start = 0xffe03c00,
852 .end = 0xffe03cff,
853 .flags = IORESOURCE_MEM,
854 },
855 IRQ(18),
856};
857static struct clk atmel_psif0_pclk = {
858 .name = "pclk",
859 .parent = &pba_clk,
860 .mode = pba_clk_mode,
861 .get_rate = pba_clk_get_rate,
862 .index = 15,
863};
864
865static struct resource atmel_psif1_resource[] __initdata = {
866 {
867 .start = 0xffe03d00,
868 .end = 0xffe03dff,
869 .flags = IORESOURCE_MEM,
870 },
871 IRQ(18),
872};
873static struct clk atmel_psif1_pclk = {
874 .name = "pclk",
875 .parent = &pba_clk,
876 .mode = pba_clk_mode,
877 .get_rate = pba_clk_get_rate,
878 .index = 15,
879};
880
881struct platform_device *__init at32_add_device_psif(unsigned int id)
882{
883 struct platform_device *pdev;
884
885 if (!(id == 0 || id == 1))
886 return NULL;
887
888 pdev = platform_device_alloc("atmel_psif", id);
889 if (!pdev)
890 return NULL;
891
892 switch (id) {
893 case 0:
894 if (platform_device_add_resources(pdev, atmel_psif0_resource,
895 ARRAY_SIZE(atmel_psif0_resource)))
896 goto err_add_resources;
897 atmel_psif0_pclk.dev = &pdev->dev;
898 select_peripheral(PA(8), PERIPH_A, 0); /* CLOCK */
899 select_peripheral(PA(9), PERIPH_A, 0); /* DATA */
900 break;
901 case 1:
902 if (platform_device_add_resources(pdev, atmel_psif1_resource,
903 ARRAY_SIZE(atmel_psif1_resource)))
904 goto err_add_resources;
905 atmel_psif1_pclk.dev = &pdev->dev;
906 select_peripheral(PB(11), PERIPH_A, 0); /* CLOCK */
907 select_peripheral(PB(12), PERIPH_A, 0); /* DATA */
908 break;
909 default:
910 return NULL;
911 }
912
913 platform_device_add(pdev);
914 return pdev;
915
916err_add_resources:
917 platform_device_put(pdev);
918 return NULL;
919}
920
921/* --------------------------------------------------------------------
844 * USART 922 * USART
845 * -------------------------------------------------------------------- */ 923 * -------------------------------------------------------------------- */
846 924
@@ -1113,7 +1191,8 @@ at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n)
1113 switch (id) { 1191 switch (id) {
1114 case 0: 1192 case 0:
1115 pdev = &atmel_spi0_device; 1193 pdev = &atmel_spi0_device;
1116 select_peripheral(PA(0), PERIPH_A, 0); /* MISO */ 1194 /* pullup MISO so a level is always defined */
1195 select_peripheral(PA(0), PERIPH_A, AT32_GPIOF_PULLUP);
1117 select_peripheral(PA(1), PERIPH_A, 0); /* MOSI */ 1196 select_peripheral(PA(1), PERIPH_A, 0); /* MOSI */
1118 select_peripheral(PA(2), PERIPH_A, 0); /* SCK */ 1197 select_peripheral(PA(2), PERIPH_A, 0); /* SCK */
1119 at32_spi_setup_slaves(0, b, n, spi0_pins); 1198 at32_spi_setup_slaves(0, b, n, spi0_pins);
@@ -1121,7 +1200,8 @@ at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n)
1121 1200
1122 case 1: 1201 case 1:
1123 pdev = &atmel_spi1_device; 1202 pdev = &atmel_spi1_device;
1124 select_peripheral(PB(0), PERIPH_B, 0); /* MISO */ 1203 /* pullup MISO so a level is always defined */
1204 select_peripheral(PB(0), PERIPH_B, AT32_GPIOF_PULLUP);
1125 select_peripheral(PB(1), PERIPH_B, 0); /* MOSI */ 1205 select_peripheral(PB(1), PERIPH_B, 0); /* MOSI */
1126 select_peripheral(PB(5), PERIPH_B, 0); /* SCK */ 1206 select_peripheral(PB(5), PERIPH_B, 0); /* SCK */
1127 at32_spi_setup_slaves(1, b, n, spi1_pins); 1207 at32_spi_setup_slaves(1, b, n, spi1_pins);
@@ -1199,20 +1279,32 @@ static struct clk atmel_mci0_pclk = {
1199 .index = 9, 1279 .index = 9,
1200}; 1280};
1201 1281
1202struct platform_device *__init at32_add_device_mci(unsigned int id) 1282struct platform_device *__init
1283at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
1203{ 1284{
1204 struct platform_device *pdev; 1285 struct mci_platform_data _data;
1286 struct platform_device *pdev;
1287 struct dw_dma_slave *dws;
1205 1288
1206 if (id != 0) 1289 if (id != 0)
1207 return NULL; 1290 return NULL;
1208 1291
1209 pdev = platform_device_alloc("atmel_mci", id); 1292 pdev = platform_device_alloc("atmel_mci", id);
1210 if (!pdev) 1293 if (!pdev)
1211 return NULL; 1294 goto fail;
1212 1295
1213 if (platform_device_add_resources(pdev, atmel_mci0_resource, 1296 if (platform_device_add_resources(pdev, atmel_mci0_resource,
1214 ARRAY_SIZE(atmel_mci0_resource))) 1297 ARRAY_SIZE(atmel_mci0_resource)))
1215 goto err_add_resources; 1298 goto fail;
1299
1300 if (!data) {
1301 data = &_data;
1302 memset(data, 0, sizeof(struct mci_platform_data));
1303 }
1304
1305 if (platform_device_add_data(pdev, data,
1306 sizeof(struct mci_platform_data)))
1307 goto fail;
1216 1308
1217 select_peripheral(PA(10), PERIPH_A, 0); /* CLK */ 1309 select_peripheral(PA(10), PERIPH_A, 0); /* CLK */
1218 select_peripheral(PA(11), PERIPH_A, 0); /* CMD */ 1310 select_peripheral(PA(11), PERIPH_A, 0); /* CMD */
@@ -1221,12 +1313,19 @@ struct platform_device *__init at32_add_device_mci(unsigned int id)
1221 select_peripheral(PA(14), PERIPH_A, 0); /* DATA2 */ 1313 select_peripheral(PA(14), PERIPH_A, 0); /* DATA2 */
1222 select_peripheral(PA(15), PERIPH_A, 0); /* DATA3 */ 1314 select_peripheral(PA(15), PERIPH_A, 0); /* DATA3 */
1223 1315
1316 if (data) {
1317 if (data->detect_pin != GPIO_PIN_NONE)
1318 at32_select_gpio(data->detect_pin, 0);
1319 if (data->wp_pin != GPIO_PIN_NONE)
1320 at32_select_gpio(data->wp_pin, 0);
1321 }
1322
1224 atmel_mci0_pclk.dev = &pdev->dev; 1323 atmel_mci0_pclk.dev = &pdev->dev;
1225 1324
1226 platform_device_add(pdev); 1325 platform_device_add(pdev);
1227 return pdev; 1326 return pdev;
1228 1327
1229err_add_resources: 1328fail:
1230 platform_device_put(pdev); 1329 platform_device_put(pdev);
1231 return NULL; 1330 return NULL;
1232} 1331}
@@ -1264,7 +1363,8 @@ static struct clk atmel_lcdfb0_pixclk = {
1264 1363
1265struct platform_device *__init 1364struct platform_device *__init
1266at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data, 1365at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,
1267 unsigned long fbmem_start, unsigned long fbmem_len) 1366 unsigned long fbmem_start, unsigned long fbmem_len,
1367 unsigned int pin_config)
1268{ 1368{
1269 struct platform_device *pdev; 1369 struct platform_device *pdev;
1270 struct atmel_lcdfb_info *info; 1370 struct atmel_lcdfb_info *info;
@@ -1291,37 +1391,77 @@ at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,
1291 switch (id) { 1391 switch (id) {
1292 case 0: 1392 case 0:
1293 pdev = &atmel_lcdfb0_device; 1393 pdev = &atmel_lcdfb0_device;
1294 select_peripheral(PC(19), PERIPH_A, 0); /* CC */ 1394
1295 select_peripheral(PC(20), PERIPH_A, 0); /* HSYNC */ 1395 switch (pin_config) {
1296 select_peripheral(PC(21), PERIPH_A, 0); /* PCLK */ 1396 case 0:
1297 select_peripheral(PC(22), PERIPH_A, 0); /* VSYNC */ 1397 select_peripheral(PC(19), PERIPH_A, 0); /* CC */
1298 select_peripheral(PC(23), PERIPH_A, 0); /* DVAL */ 1398 select_peripheral(PC(20), PERIPH_A, 0); /* HSYNC */
1299 select_peripheral(PC(24), PERIPH_A, 0); /* MODE */ 1399 select_peripheral(PC(21), PERIPH_A, 0); /* PCLK */
1300 select_peripheral(PC(25), PERIPH_A, 0); /* PWR */ 1400 select_peripheral(PC(22), PERIPH_A, 0); /* VSYNC */
1301 select_peripheral(PC(26), PERIPH_A, 0); /* DATA0 */ 1401 select_peripheral(PC(23), PERIPH_A, 0); /* DVAL */
1302 select_peripheral(PC(27), PERIPH_A, 0); /* DATA1 */ 1402 select_peripheral(PC(24), PERIPH_A, 0); /* MODE */
1303 select_peripheral(PC(28), PERIPH_A, 0); /* DATA2 */ 1403 select_peripheral(PC(25), PERIPH_A, 0); /* PWR */
1304 select_peripheral(PC(29), PERIPH_A, 0); /* DATA3 */ 1404 select_peripheral(PC(26), PERIPH_A, 0); /* DATA0 */
1305 select_peripheral(PC(30), PERIPH_A, 0); /* DATA4 */ 1405 select_peripheral(PC(27), PERIPH_A, 0); /* DATA1 */
1306 select_peripheral(PC(31), PERIPH_A, 0); /* DATA5 */ 1406 select_peripheral(PC(28), PERIPH_A, 0); /* DATA2 */
1307 select_peripheral(PD(0), PERIPH_A, 0); /* DATA6 */ 1407 select_peripheral(PC(29), PERIPH_A, 0); /* DATA3 */
1308 select_peripheral(PD(1), PERIPH_A, 0); /* DATA7 */ 1408 select_peripheral(PC(30), PERIPH_A, 0); /* DATA4 */
1309 select_peripheral(PD(2), PERIPH_A, 0); /* DATA8 */ 1409 select_peripheral(PC(31), PERIPH_A, 0); /* DATA5 */
1310 select_peripheral(PD(3), PERIPH_A, 0); /* DATA9 */ 1410 select_peripheral(PD(0), PERIPH_A, 0); /* DATA6 */
1311 select_peripheral(PD(4), PERIPH_A, 0); /* DATA10 */ 1411 select_peripheral(PD(1), PERIPH_A, 0); /* DATA7 */
1312 select_peripheral(PD(5), PERIPH_A, 0); /* DATA11 */ 1412 select_peripheral(PD(2), PERIPH_A, 0); /* DATA8 */
1313 select_peripheral(PD(6), PERIPH_A, 0); /* DATA12 */ 1413 select_peripheral(PD(3), PERIPH_A, 0); /* DATA9 */
1314 select_peripheral(PD(7), PERIPH_A, 0); /* DATA13 */ 1414 select_peripheral(PD(4), PERIPH_A, 0); /* DATA10 */
1315 select_peripheral(PD(8), PERIPH_A, 0); /* DATA14 */ 1415 select_peripheral(PD(5), PERIPH_A, 0); /* DATA11 */
1316 select_peripheral(PD(9), PERIPH_A, 0); /* DATA15 */ 1416 select_peripheral(PD(6), PERIPH_A, 0); /* DATA12 */
1317 select_peripheral(PD(10), PERIPH_A, 0); /* DATA16 */ 1417 select_peripheral(PD(7), PERIPH_A, 0); /* DATA13 */
1318 select_peripheral(PD(11), PERIPH_A, 0); /* DATA17 */ 1418 select_peripheral(PD(8), PERIPH_A, 0); /* DATA14 */
1319 select_peripheral(PD(12), PERIPH_A, 0); /* DATA18 */ 1419 select_peripheral(PD(9), PERIPH_A, 0); /* DATA15 */
1320 select_peripheral(PD(13), PERIPH_A, 0); /* DATA19 */ 1420 select_peripheral(PD(10), PERIPH_A, 0); /* DATA16 */
1321 select_peripheral(PD(14), PERIPH_A, 0); /* DATA20 */ 1421 select_peripheral(PD(11), PERIPH_A, 0); /* DATA17 */
1322 select_peripheral(PD(15), PERIPH_A, 0); /* DATA21 */ 1422 select_peripheral(PD(12), PERIPH_A, 0); /* DATA18 */
1323 select_peripheral(PD(16), PERIPH_A, 0); /* DATA22 */ 1423 select_peripheral(PD(13), PERIPH_A, 0); /* DATA19 */
1324 select_peripheral(PD(17), PERIPH_A, 0); /* DATA23 */ 1424 select_peripheral(PD(14), PERIPH_A, 0); /* DATA20 */
1425 select_peripheral(PD(15), PERIPH_A, 0); /* DATA21 */
1426 select_peripheral(PD(16), PERIPH_A, 0); /* DATA22 */
1427 select_peripheral(PD(17), PERIPH_A, 0); /* DATA23 */
1428 break;
1429 case 1:
1430 select_peripheral(PE(0), PERIPH_B, 0); /* CC */
1431 select_peripheral(PC(20), PERIPH_A, 0); /* HSYNC */
1432 select_peripheral(PC(21), PERIPH_A, 0); /* PCLK */
1433 select_peripheral(PC(22), PERIPH_A, 0); /* VSYNC */
1434 select_peripheral(PE(1), PERIPH_B, 0); /* DVAL */
1435 select_peripheral(PE(2), PERIPH_B, 0); /* MODE */
1436 select_peripheral(PC(25), PERIPH_A, 0); /* PWR */
1437 select_peripheral(PE(3), PERIPH_B, 0); /* DATA0 */
1438 select_peripheral(PE(4), PERIPH_B, 0); /* DATA1 */
1439 select_peripheral(PE(5), PERIPH_B, 0); /* DATA2 */
1440 select_peripheral(PE(6), PERIPH_B, 0); /* DATA3 */
1441 select_peripheral(PE(7), PERIPH_B, 0); /* DATA4 */
1442 select_peripheral(PC(31), PERIPH_A, 0); /* DATA5 */
1443 select_peripheral(PD(0), PERIPH_A, 0); /* DATA6 */
1444 select_peripheral(PD(1), PERIPH_A, 0); /* DATA7 */
1445 select_peripheral(PE(8), PERIPH_B, 0); /* DATA8 */
1446 select_peripheral(PE(9), PERIPH_B, 0); /* DATA9 */
1447 select_peripheral(PE(10), PERIPH_B, 0); /* DATA10 */
1448 select_peripheral(PE(11), PERIPH_B, 0); /* DATA11 */
1449 select_peripheral(PE(12), PERIPH_B, 0); /* DATA12 */
1450 select_peripheral(PD(7), PERIPH_A, 0); /* DATA13 */
1451 select_peripheral(PD(8), PERIPH_A, 0); /* DATA14 */
1452 select_peripheral(PD(9), PERIPH_A, 0); /* DATA15 */
1453 select_peripheral(PE(13), PERIPH_B, 0); /* DATA16 */
1454 select_peripheral(PE(14), PERIPH_B, 0); /* DATA17 */
1455 select_peripheral(PE(15), PERIPH_B, 0); /* DATA18 */
1456 select_peripheral(PE(16), PERIPH_B, 0); /* DATA19 */
1457 select_peripheral(PE(17), PERIPH_B, 0); /* DATA20 */
1458 select_peripheral(PE(18), PERIPH_B, 0); /* DATA21 */
1459 select_peripheral(PD(16), PERIPH_A, 0); /* DATA22 */
1460 select_peripheral(PD(17), PERIPH_A, 0); /* DATA23 */
1461 break;
1462 default:
1463 goto err_invalid_id;
1464 }
1325 1465
1326 clk_set_parent(&atmel_lcdfb0_pixclk, &pll0); 1466 clk_set_parent(&atmel_lcdfb0_pixclk, &pll0);
1327 clk_set_rate(&atmel_lcdfb0_pixclk, clk_get_rate(&pll0)); 1467 clk_set_rate(&atmel_lcdfb0_pixclk, clk_get_rate(&pll0));
@@ -1360,7 +1500,7 @@ static struct resource atmel_pwm0_resource[] __initdata = {
1360 IRQ(24), 1500 IRQ(24),
1361}; 1501};
1362static struct clk atmel_pwm0_mck = { 1502static struct clk atmel_pwm0_mck = {
1363 .name = "mck", 1503 .name = "pwm_clk",
1364 .parent = &pbb_clk, 1504 .parent = &pbb_clk,
1365 .mode = pbb_clk_mode, 1505 .mode = pbb_clk_mode,
1366 .get_rate = pbb_clk_get_rate, 1506 .get_rate = pbb_clk_get_rate,
@@ -1887,6 +2027,7 @@ struct clk *at32_clock_list[] = {
1887 &hmatrix_clk, 2027 &hmatrix_clk,
1888 &ebi_clk, 2028 &ebi_clk,
1889 &hramc_clk, 2029 &hramc_clk,
2030 &sdramc_clk,
1890 &smc0_pclk, 2031 &smc0_pclk,
1891 &smc0_mck, 2032 &smc0_mck,
1892 &pdc_hclk, 2033 &pdc_hclk,
@@ -1900,6 +2041,8 @@ struct clk *at32_clock_list[] = {
1900 &pio4_mck, 2041 &pio4_mck,
1901 &at32_tcb0_t0_clk, 2042 &at32_tcb0_t0_clk,
1902 &at32_tcb1_t0_clk, 2043 &at32_tcb1_t0_clk,
2044 &atmel_psif0_pclk,
2045 &atmel_psif1_pclk,
1903 &atmel_usart0_usart, 2046 &atmel_usart0_usart,
1904 &atmel_usart1_usart, 2047 &atmel_usart1_usart,
1905 &atmel_usart2_usart, 2048 &atmel_usart2_usart,
@@ -1935,16 +2078,7 @@ struct clk *at32_clock_list[] = {
1935}; 2078};
1936unsigned int at32_nr_clocks = ARRAY_SIZE(at32_clock_list); 2079unsigned int at32_nr_clocks = ARRAY_SIZE(at32_clock_list);
1937 2080
1938void __init at32_portmux_init(void) 2081void __init setup_platform(void)
1939{
1940 at32_init_pio(&pio0_device);
1941 at32_init_pio(&pio1_device);
1942 at32_init_pio(&pio2_device);
1943 at32_init_pio(&pio3_device);
1944 at32_init_pio(&pio4_device);
1945}
1946
1947void __init at32_clock_init(void)
1948{ 2082{
1949 u32 cpu_mask = 0, hsb_mask = 0, pba_mask = 0, pbb_mask = 0; 2083 u32 cpu_mask = 0, hsb_mask = 0, pba_mask = 0, pbb_mask = 0;
1950 int i; 2084 int i;
@@ -1999,4 +2133,36 @@ void __init at32_clock_init(void)
1999 pm_writel(HSB_MASK, hsb_mask); 2133 pm_writel(HSB_MASK, hsb_mask);
2000 pm_writel(PBA_MASK, pba_mask); 2134 pm_writel(PBA_MASK, pba_mask);
2001 pm_writel(PBB_MASK, pbb_mask); 2135 pm_writel(PBB_MASK, pbb_mask);
2136
2137 /* Initialize the port muxes */
2138 at32_init_pio(&pio0_device);
2139 at32_init_pio(&pio1_device);
2140 at32_init_pio(&pio2_device);
2141 at32_init_pio(&pio3_device);
2142 at32_init_pio(&pio4_device);
2143}
2144
2145struct gen_pool *sram_pool;
2146
2147static int __init sram_init(void)
2148{
2149 struct gen_pool *pool;
2150
2151 /* 1KiB granularity */
2152 pool = gen_pool_create(10, -1);
2153 if (!pool)
2154 goto fail;
2155
2156 if (gen_pool_add(pool, 0x24000000, 0x8000, -1))
2157 goto err_pool_add;
2158
2159 sram_pool = pool;
2160 return 0;
2161
2162err_pool_add:
2163 gen_pool_destroy(pool);
2164fail:
2165 pr_err("Failed to create SRAM pool\n");
2166 return -ENOMEM;
2002} 2167}
2168core_initcall(sram_init);