Blame view
arch/avr32/boards/atstk1000/atstk1002.c
7.72 KB
5f97f7f94
|
1 |
/* |
e150d6e72
|
2 |
* ATSTK1002/ATSTK1006 daughterboard-specific init code |
5f97f7f94
|
3 |
* |
e150d6e72
|
4 |
* Copyright (C) 2005-2007 Atmel Corporation |
5f97f7f94
|
5 6 7 8 9 |
* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ |
c164b9013
|
10 11 |
#include <linux/clk.h> #include <linux/etherdevice.h> |
5f97f7f94
|
12 |
#include <linux/init.h> |
a6f92f3dc
|
13 |
#include <linux/kernel.h> |
c164b9013
|
14 |
#include <linux/platform_device.h> |
a6f92f3dc
|
15 16 |
#include <linux/string.h> #include <linux/types.h> |
3d60ee1b0
|
17 |
#include <linux/spi/spi.h> |
1c2f17379
|
18 |
#include <linux/spi/at73c213.h> |
c42aa775c
|
19 |
#include <linux/atmel-mci.h> |
5f97f7f94
|
20 |
|
d0a2b7af2
|
21 |
#include <video/atmel_lcdc.h> |
c164b9013
|
22 |
#include <asm/io.h> |
a6f92f3dc
|
23 |
#include <asm/setup.h> |
3c26e1703
|
24 |
|
3663b736a
|
25 26 27 28 |
#include <mach/at32ap700x.h> #include <mach/board.h> #include <mach/init.h> #include <mach/portmux.h> |
5f97f7f94
|
29 |
|
d0a2b7af2
|
30 |
#include "atstk1000.h" |
a3d912c8f
|
31 |
|
60ed7951d
|
32 33 34 35 36 37 |
/* Oscillator frequencies. These are board specific */ unsigned long at32_board_osc_rates[3] = { [0] = 32768, /* 32.768 kHz on RTC osc */ [1] = 20000000, /* 20 MHz on osc0 */ [2] = 12000000, /* 12 MHz on osc1 */ }; |
a3d912c8f
|
38 |
|
e150d6e72
|
39 40 41 42 43 44 45 46 47 48 49 50 |
/* * The ATSTK1006 daughterboard is very similar to the ATSTK1002. Both * have the AT32AP7000 chip on board; the difference is that the * STK1006 has 128 MB SDRAM (the STK1002 uses the 8 MB SDRAM chip on * the STK1000 motherboard) and 256 MB NAND flash (the STK1002 has * none.) * * The RAM difference is handled by the boot loader, so the only * difference we end up handling here is the NAND flash. */ #ifdef CONFIG_BOARD_ATSTK1006 #include <linux/mtd/partitions.h> |
3663b736a
|
51 |
#include <mach/smc.h> |
e150d6e72
|
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
static struct smc_timing nand_timing __initdata = { .ncs_read_setup = 0, .nrd_setup = 10, .ncs_write_setup = 0, .nwe_setup = 10, .ncs_read_pulse = 30, .nrd_pulse = 15, .ncs_write_pulse = 30, .nwe_pulse = 15, .read_cycle = 30, .write_cycle = 30, .ncs_read_recover = 0, .nrd_recover = 15, .ncs_write_recover = 0, /* WE# high -> RE# low min 60 ns */ .nwe_recover = 50, }; static struct smc_config nand_config __initdata = { .bus_width = 1, .nrd_controlled = 1, .nwe_controlled = 1, .nwait_mode = 0, .byte_write = 0, .tdf_cycles = 2, .tdf_mode = 0, }; static struct mtd_partition nand_partitions[] = { { .name = "main", .offset = 0x00000000, .size = MTDPART_SIZ_FULL, }, }; |
33f197a60
|
91 |
static struct atmel_nand_data atstk1006_nand_data __initdata = { |
e150d6e72
|
92 93 94 95 |
.cle = 21, .ale = 22, .rdy_pin = GPIO_PIN_PB(30), .enable_pin = GPIO_PIN_PB(29), |
1754aab9b
|
96 97 |
.parts = nand_partitions, .num_parts = ARRAY_SIZE(num_partitions), |
e150d6e72
|
98 99 |
}; #endif |
c164b9013
|
100 101 102 103 104 |
struct eth_addr { u8 addr[6]; }; static struct eth_addr __initdata hw_addr[2]; |
84e0cdb0a
|
105 |
static struct macb_platform_data __initdata eth_data[2] = { |
587ca7619
|
106 107 108 109 110 111 112 113 114 115 116 117 |
{ /* * The MDIO pullups on STK1000 are a bit too weak for * the autodetection to work properly, so we have to * mask out everything but the correct address. */ .phy_mask = ~(1U << 16), }, { .phy_mask = ~(1U << 17), }, }; |
5f97f7f94
|
118 |
|
64d810526
|
119 |
#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC |
1c2f17379
|
120 121 122 123 124 |
static struct at73c213_board_info at73c213_data = { .ssc_id = 0, .shortname = "AVR32 STK1000 external DAC", }; #endif |
1c2f17379
|
125 |
|
78693e47a
|
126 |
#ifndef CONFIG_BOARD_ATSTK100X_SW1_CUSTOM |
41d8ca452
|
127 |
static struct spi_board_info spi0_board_info[] __initdata = { |
64d810526
|
128 |
#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC |
1c2f17379
|
129 130 131 132 133 134 135 136 137 |
{ /* AT73C213 */ .modalias = "at73c213", .max_speed_hz = 200000, .chip_select = 0, .mode = SPI_MODE_1, .platform_data = &at73c213_data, }, #endif |
3d60ee1b0
|
138 |
{ |
41d8ca452
|
139 |
/* QVGA display */ |
3d60ee1b0
|
140 |
.modalias = "ltv350qv", |
3d60ee1b0
|
141 |
.max_speed_hz = 16000000, |
3d60ee1b0
|
142 |
.chip_select = 1, |
2fdfe8d9a
|
143 |
.mode = SPI_MODE_3, |
3d60ee1b0
|
144 145 |
}, }; |
a8e93ed8c
|
146 |
#endif |
78693e47a
|
147 |
#ifdef CONFIG_BOARD_ATSTK100X_SPI1 |
a8e93ed8c
|
148 149 150 151 |
static struct spi_board_info spi1_board_info[] __initdata = { { /* patch in custom entries here */ } }; #endif |
3d60ee1b0
|
152 |
|
c164b9013
|
153 154 155 156 157 158 159 160 |
/* * The next two functions should go away as the boot loader is * supposed to initialize the macb address registers with a valid * ethernet address. But we need to keep it around for a while until * we can be reasonably sure the boot loader does this. * * The phy_id is ignored as the driver will probe for it. */ |
a6f92f3dc
|
161 162 163 164 165 |
static int __init parse_tag_ethernet(struct tag *tag) { int i; i = tag->u.ethernet.mac_index; |
c164b9013
|
166 167 168 |
if (i < ARRAY_SIZE(hw_addr)) memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address, sizeof(hw_addr[i].addr)); |
a6f92f3dc
|
169 170 171 |
return 0; } __tagtable(ATAG_ETHERNET, parse_tag_ethernet); |
c164b9013
|
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
static void __init set_hw_addr(struct platform_device *pdev) { struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); const u8 *addr; void __iomem *regs; struct clk *pclk; if (!res) return; if (pdev->id >= ARRAY_SIZE(hw_addr)) return; addr = hw_addr[pdev->id].addr; if (!is_valid_ether_addr(addr)) return; /* * Since this is board-specific code, we'll cheat and use the * physical address directly as we happen to know that it's * the same as the virtual address. */ regs = (void __iomem __force *)res->start; pclk = clk_get(&pdev->dev, "pclk"); |
36b471e04
|
195 |
if (IS_ERR(pclk)) |
c164b9013
|
196 197 198 199 200 201 202 203 204 |
return; clk_enable(pclk); __raw_writel((addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0], regs + 0x98); __raw_writel((addr[5] << 8) | addr[4], regs + 0x9c); clk_disable(pclk); clk_put(pclk); } |
64d810526
|
205 206 |
#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC static void __init atstk1002_setup_extdac(void) |
1c2f17379
|
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
{ struct clk *gclk; struct clk *pll; gclk = clk_get(NULL, "gclk0"); if (IS_ERR(gclk)) goto err_gclk; pll = clk_get(NULL, "pll0"); if (IS_ERR(pll)) goto err_pll; if (clk_set_parent(gclk, pll)) { pr_debug("STK1000: failed to set pll0 as parent for DAC clock "); goto err_set_clk; } |
caf18f19e
|
223 |
at32_select_periph(GPIO_PIOA_BASE, (1 << 30), GPIO_PERIPH_A, 0); |
64d810526
|
224 |
at73c213_data.dac_clk = gclk; |
1c2f17379
|
225 226 227 228 229 230 231 232 |
err_set_clk: clk_put(pll); err_pll: clk_put(gclk); err_gclk: return; } |
64d810526
|
233 234 235 236 237 238 |
#else static void __init atstk1002_setup_extdac(void) { } #endif /* CONFIG_BOARD_ATSTK1000_EXTDAC */ |
1c2f17379
|
239 |
|
c194588db
|
240 241 |
void __init setup_board(void) { |
78693e47a
|
242 |
#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM |
bf4861cf3
|
243 |
at32_map_usart(0, 1, 0); /* USART 0/B: /dev/ttyS1, IRDA */ |
a8e93ed8c
|
244 |
#else |
bf4861cf3
|
245 |
at32_map_usart(1, 0, 0); /* USART 1/A: /dev/ttyS0, DB9 */ |
a3d912c8f
|
246 247 |
#endif /* USART 2/unused: expansion connector */ |
bf4861cf3
|
248 |
at32_map_usart(3, 2, 0); /* USART 3/C: /dev/ttyS2, DB9 */ |
c194588db
|
249 250 251 |
at32_setup_serial_console(0); } |
3c26e1703
|
252 |
#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM |
6b918657b
|
253 254 255 |
static struct mci_platform_data __initdata mci0_data = { .slot[0] = { .bus_width = 4, |
3c26e1703
|
256 257 |
/* MMC card detect requires MACB0 *NOT* be used */ #ifdef CONFIG_BOARD_ATSTK1002_SW6_CUSTOM |
6b918657b
|
258 259 |
.detect_pin = GPIO_PIN_PC(14), /* gpio30/sdcd */ .wp_pin = GPIO_PIN_PC(15), /* gpio31/sdwp */ |
3c26e1703
|
260 |
#else |
6b918657b
|
261 262 |
.detect_pin = -ENODEV, .wp_pin = -ENODEV, |
3c26e1703
|
263 |
#endif /* SW6 for sd{cd,wp} routing */ |
6b918657b
|
264 265 |
}, }; |
3c26e1703
|
266 267 |
#endif /* SW2 for MMC signal routing */ |
5f97f7f94
|
268 269 |
static int __init atstk1002_init(void) { |
7f9f46786
|
270 271 272 273 |
/* * ATSTK1000 uses 32-bit SDRAM interface. Reserve the * SDRAM-specific pins so that nobody messes with them. */ |
adde42b58
|
274 |
at32_reserve_pin(GPIO_PIOE_BASE, ATMEL_EBI_PE_DATA_ALL); |
7f9f46786
|
275 |
|
e150d6e72
|
276 277 278 279 280 |
#ifdef CONFIG_BOARD_ATSTK1006 smc_set_timing(&nand_config, &nand_timing); smc_set_configuration(3, &nand_config); at32_add_device_nand(0, &atstk1006_nand_data); #endif |
78693e47a
|
281 |
#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM |
c194588db
|
282 |
at32_add_device_usart(1); |
a8e93ed8c
|
283 284 |
#else at32_add_device_usart(0); |
a3d912c8f
|
285 |
#endif |
c194588db
|
286 |
at32_add_device_usart(2); |
5f97f7f94
|
287 |
|
d4003ba0a
|
288 |
#ifndef CONFIG_BOARD_ATSTK1002_SW6_CUSTOM |
c164b9013
|
289 |
set_hw_addr(at32_add_device_eth(0, ð_data[0])); |
d4003ba0a
|
290 |
#endif |
78693e47a
|
291 |
#ifndef CONFIG_BOARD_ATSTK100X_SW1_CUSTOM |
41d8ca452
|
292 |
at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info)); |
a8e93ed8c
|
293 |
#endif |
78693e47a
|
294 |
#ifdef CONFIG_BOARD_ATSTK100X_SPI1 |
a8e93ed8c
|
295 296 |
at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); #endif |
7fb61a7b6
|
297 |
#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM |
6eb3ebe04
|
298 |
at32_add_device_mci(0, &mci0_data); |
7d2be0749
|
299 |
#endif |
a8e93ed8c
|
300 301 302 |
#ifdef CONFIG_BOARD_ATSTK1002_SW5_CUSTOM set_hw_addr(at32_add_device_eth(1, ð_data[1])); #else |
d0a2b7af2
|
303 |
at32_add_device_lcdc(0, &atstk1000_lcdc_data, |
706641248
|
304 305 |
fbmem_start, fbmem_size, ATMEL_LCDC_PRI_24BIT | ATMEL_LCDC_PRI_CONTROL); |
a8e93ed8c
|
306 |
#endif |
6fcf06151
|
307 |
at32_add_device_usba(0, NULL); |
78693e47a
|
308 |
#ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM |
95a42267c
|
309 310 |
at32_add_device_ssc(0, ATMEL_SSC_TX); #endif |
5f97f7f94
|
311 |
|
f4c41b268
|
312 |
atstk1000_setup_j2_leds(); |
64d810526
|
313 |
atstk1002_setup_extdac(); |
1c2f17379
|
314 |
|
5f97f7f94
|
315 316 317 |
return 0; } postcore_initcall(atstk1002_init); |