diff options
Diffstat (limited to 'arch/avr32/boards/atngw100/setup.c')
-rw-r--r-- | arch/avr32/boards/atngw100/setup.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/arch/avr32/boards/atngw100/setup.c b/arch/avr32/boards/atngw100/setup.c new file mode 100644 index 000000000000..9bc37d4f6687 --- /dev/null +++ b/arch/avr32/boards/atngw100/setup.c | |||
@@ -0,0 +1,124 @@ | |||
1 | /* | ||
2 | * Board-specific setup code for the ATNGW100 Network Gateway | ||
3 | * | ||
4 | * Copyright (C) 2005-2006 Atmel Corporation | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #include <linux/clk.h> | ||
11 | #include <linux/etherdevice.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/linkage.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <linux/spi/spi.h> | ||
17 | |||
18 | #include <asm/io.h> | ||
19 | #include <asm/setup.h> | ||
20 | |||
21 | #include <asm/arch/at32ap7000.h> | ||
22 | #include <asm/arch/board.h> | ||
23 | #include <asm/arch/init.h> | ||
24 | |||
25 | /* Initialized by bootloader-specific startup code. */ | ||
26 | struct tag *bootloader_tags __initdata; | ||
27 | |||
28 | struct eth_addr { | ||
29 | u8 addr[6]; | ||
30 | }; | ||
31 | static struct eth_addr __initdata hw_addr[2]; | ||
32 | static struct eth_platform_data __initdata eth_data[2]; | ||
33 | |||
34 | static struct spi_board_info spi0_board_info[] __initdata = { | ||
35 | { | ||
36 | .modalias = "mtd_dataflash", | ||
37 | .max_speed_hz = 10000000, | ||
38 | .chip_select = 0, | ||
39 | }, | ||
40 | }; | ||
41 | |||
42 | /* | ||
43 | * The next two functions should go away as the boot loader is | ||
44 | * supposed to initialize the macb address registers with a valid | ||
45 | * ethernet address. But we need to keep it around for a while until | ||
46 | * we can be reasonably sure the boot loader does this. | ||
47 | * | ||
48 | * The phy_id is ignored as the driver will probe for it. | ||
49 | */ | ||
50 | static int __init parse_tag_ethernet(struct tag *tag) | ||
51 | { | ||
52 | int i; | ||
53 | |||
54 | i = tag->u.ethernet.mac_index; | ||
55 | if (i < ARRAY_SIZE(hw_addr)) | ||
56 | memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address, | ||
57 | sizeof(hw_addr[i].addr)); | ||
58 | |||
59 | return 0; | ||
60 | } | ||
61 | __tagtable(ATAG_ETHERNET, parse_tag_ethernet); | ||
62 | |||
63 | static void __init set_hw_addr(struct platform_device *pdev) | ||
64 | { | ||
65 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
66 | const u8 *addr; | ||
67 | void __iomem *regs; | ||
68 | struct clk *pclk; | ||
69 | |||
70 | if (!res) | ||
71 | return; | ||
72 | if (pdev->id >= ARRAY_SIZE(hw_addr)) | ||
73 | return; | ||
74 | |||
75 | addr = hw_addr[pdev->id].addr; | ||
76 | if (!is_valid_ether_addr(addr)) | ||
77 | return; | ||
78 | |||
79 | /* | ||
80 | * Since this is board-specific code, we'll cheat and use the | ||
81 | * physical address directly as we happen to know that it's | ||
82 | * the same as the virtual address. | ||
83 | */ | ||
84 | regs = (void __iomem __force *)res->start; | ||
85 | pclk = clk_get(&pdev->dev, "pclk"); | ||
86 | if (!pclk) | ||
87 | return; | ||
88 | |||
89 | clk_enable(pclk); | ||
90 | __raw_writel((addr[3] << 24) | (addr[2] << 16) | ||
91 | | (addr[1] << 8) | addr[0], regs + 0x98); | ||
92 | __raw_writel((addr[5] << 8) | addr[4], regs + 0x9c); | ||
93 | clk_disable(pclk); | ||
94 | clk_put(pclk); | ||
95 | } | ||
96 | |||
97 | struct platform_device *at32_usart_map[1]; | ||
98 | unsigned int at32_nr_usarts = 1; | ||
99 | |||
100 | void __init setup_board(void) | ||
101 | { | ||
102 | at32_map_usart(1, 0); /* USART 1: /dev/ttyS0, DB9 */ | ||
103 | at32_setup_serial_console(0); | ||
104 | } | ||
105 | |||
106 | static int __init atngw100_init(void) | ||
107 | { | ||
108 | /* | ||
109 | * ATNGW100 uses 16-bit SDRAM interface, so we don't need to | ||
110 | * reserve any pins for it. | ||
111 | */ | ||
112 | |||
113 | at32_add_system_devices(); | ||
114 | |||
115 | at32_add_device_usart(0); | ||
116 | |||
117 | set_hw_addr(at32_add_device_eth(0, ð_data[0])); | ||
118 | set_hw_addr(at32_add_device_eth(1, ð_data[1])); | ||
119 | |||
120 | at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info)); | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | postcore_initcall(atngw100_init); | ||