xref: /openbmc/linux/arch/arm/mach-ep93xx/ts72xx.c (revision 643d1f7f)
1 /*
2  * arch/arm/mach-ep93xx/ts72xx.c
3  * Technologic Systems TS72xx SBC support.
4  *
5  * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or (at
10  * your option) any later version.
11  */
12 
13 #include <linux/kernel.h>
14 #include <linux/init.h>
15 #include <linux/mm.h>
16 #include <linux/sched.h>
17 #include <linux/interrupt.h>
18 #include <linux/ioport.h>
19 #include <linux/mtd/physmap.h>
20 #include <linux/platform_device.h>
21 #include <linux/m48t86.h>
22 #include <asm/io.h>
23 #include <asm/hardware.h>
24 #include <asm/mach-types.h>
25 #include <asm/mach/arch.h>
26 #include <asm/mach/map.h>
27 
28 static struct map_desc ts72xx_io_desc[] __initdata = {
29 	{
30 		.virtual	= TS72XX_MODEL_VIRT_BASE,
31 		.pfn		= __phys_to_pfn(TS72XX_MODEL_PHYS_BASE),
32 		.length		= TS72XX_MODEL_SIZE,
33 		.type		= MT_DEVICE,
34 	}, {
35 		.virtual	= TS72XX_OPTIONS_VIRT_BASE,
36 		.pfn		= __phys_to_pfn(TS72XX_OPTIONS_PHYS_BASE),
37 		.length		= TS72XX_OPTIONS_SIZE,
38 		.type		= MT_DEVICE,
39 	}, {
40 		.virtual	= TS72XX_OPTIONS2_VIRT_BASE,
41 		.pfn		= __phys_to_pfn(TS72XX_OPTIONS2_PHYS_BASE),
42 		.length		= TS72XX_OPTIONS2_SIZE,
43 		.type		= MT_DEVICE,
44 	}, {
45 		.virtual	= TS72XX_RTC_INDEX_VIRT_BASE,
46 		.pfn		= __phys_to_pfn(TS72XX_RTC_INDEX_PHYS_BASE),
47 		.length		= TS72XX_RTC_INDEX_SIZE,
48 		.type		= MT_DEVICE,
49 	}, {
50 		.virtual	= TS72XX_RTC_DATA_VIRT_BASE,
51 		.pfn		= __phys_to_pfn(TS72XX_RTC_DATA_PHYS_BASE),
52 		.length		= TS72XX_RTC_DATA_SIZE,
53 		.type		= MT_DEVICE,
54 	}
55 };
56 
57 static struct map_desc ts72xx_nand_io_desc[] __initdata = {
58 	{
59 		.virtual	= TS72XX_NAND_DATA_VIRT_BASE,
60 		.pfn		= __phys_to_pfn(TS72XX_NAND1_DATA_PHYS_BASE),
61 		.length		= TS72XX_NAND_DATA_SIZE,
62 		.type		= MT_DEVICE,
63 	}, {
64 		.virtual	= TS72XX_NAND_CONTROL_VIRT_BASE,
65 		.pfn		= __phys_to_pfn(TS72XX_NAND1_CONTROL_PHYS_BASE),
66 		.length		= TS72XX_NAND_CONTROL_SIZE,
67 		.type		= MT_DEVICE,
68 	}, {
69 		.virtual	= TS72XX_NAND_BUSY_VIRT_BASE,
70 		.pfn		= __phys_to_pfn(TS72XX_NAND1_BUSY_PHYS_BASE),
71 		.length		= TS72XX_NAND_BUSY_SIZE,
72 		.type		= MT_DEVICE,
73 	}
74 };
75 
76 static struct map_desc ts72xx_alternate_nand_io_desc[] __initdata = {
77 	{
78 		.virtual	= TS72XX_NAND_DATA_VIRT_BASE,
79 		.pfn		= __phys_to_pfn(TS72XX_NAND2_DATA_PHYS_BASE),
80 		.length		= TS72XX_NAND_DATA_SIZE,
81 		.type		= MT_DEVICE,
82 	}, {
83 		.virtual	= TS72XX_NAND_CONTROL_VIRT_BASE,
84 		.pfn		= __phys_to_pfn(TS72XX_NAND2_CONTROL_PHYS_BASE),
85 		.length		= TS72XX_NAND_CONTROL_SIZE,
86 		.type		= MT_DEVICE,
87 	}, {
88 		.virtual	= TS72XX_NAND_BUSY_VIRT_BASE,
89 		.pfn		= __phys_to_pfn(TS72XX_NAND2_BUSY_PHYS_BASE),
90 		.length		= TS72XX_NAND_BUSY_SIZE,
91 		.type		= MT_DEVICE,
92 	}
93 };
94 
95 static void __init ts72xx_map_io(void)
96 {
97 	ep93xx_map_io();
98 	iotable_init(ts72xx_io_desc, ARRAY_SIZE(ts72xx_io_desc));
99 
100 	/*
101 	 * The TS-7200 has NOR flash, the other models have NAND flash.
102 	 */
103 	if (!board_is_ts7200()) {
104 		if (is_ts9420_installed()) {
105 			iotable_init(ts72xx_alternate_nand_io_desc,
106 				ARRAY_SIZE(ts72xx_alternate_nand_io_desc));
107 		} else {
108 			iotable_init(ts72xx_nand_io_desc,
109 				ARRAY_SIZE(ts72xx_nand_io_desc));
110 		}
111 	}
112 }
113 
114 static struct physmap_flash_data ts72xx_flash_data = {
115 	.width		= 1,
116 };
117 
118 static struct resource ts72xx_flash_resource = {
119 	.start		= TS72XX_NOR_PHYS_BASE,
120 	.end		= TS72XX_NOR_PHYS_BASE + 0x00ffffff,
121 	.flags		= IORESOURCE_MEM,
122 };
123 
124 static struct platform_device ts72xx_flash = {
125 	.name		= "physmap-flash",
126 	.id		= 0,
127 	.dev		= {
128 		.platform_data	= &ts72xx_flash_data,
129 	},
130 	.num_resources	= 1,
131 	.resource	= &ts72xx_flash_resource,
132 };
133 
134 static unsigned char ts72xx_rtc_readbyte(unsigned long addr)
135 {
136 	__raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE);
137 	return __raw_readb(TS72XX_RTC_DATA_VIRT_BASE);
138 }
139 
140 static void ts72xx_rtc_writebyte(unsigned char value, unsigned long addr)
141 {
142 	__raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE);
143 	__raw_writeb(value, TS72XX_RTC_DATA_VIRT_BASE);
144 }
145 
146 static struct m48t86_ops ts72xx_rtc_ops = {
147 	.readbyte		= ts72xx_rtc_readbyte,
148 	.writebyte		= ts72xx_rtc_writebyte,
149 };
150 
151 static struct platform_device ts72xx_rtc_device = {
152 	.name			= "rtc-m48t86",
153 	.id			= -1,
154 	.dev			= {
155 		.platform_data		= &ts72xx_rtc_ops,
156 	},
157 	.num_resources		= 0,
158 };
159 
160 static struct ep93xx_eth_data ts72xx_eth_data = {
161 	.phy_id			= 1,
162 };
163 
164 static struct resource ts72xx_eth_resource[] = {
165 	{
166 		.start	= EP93XX_ETHERNET_PHYS_BASE,
167 		.end	= EP93XX_ETHERNET_PHYS_BASE + 0xffff,
168 		.flags	= IORESOURCE_MEM,
169 	}, {
170 		.start	= IRQ_EP93XX_ETHERNET,
171 		.end	= IRQ_EP93XX_ETHERNET,
172 		.flags	= IORESOURCE_IRQ,
173 	}
174 };
175 
176 static struct platform_device ts72xx_eth_device = {
177 	.name		= "ep93xx-eth",
178 	.id		= -1,
179 	.dev		= {
180 		.platform_data	= &ts72xx_eth_data,
181 	},
182 	.num_resources	= 2,
183 	.resource	= ts72xx_eth_resource,
184 };
185 
186 static void __init ts72xx_init_machine(void)
187 {
188 	ep93xx_init_devices();
189 	if (board_is_ts7200())
190 		platform_device_register(&ts72xx_flash);
191 	platform_device_register(&ts72xx_rtc_device);
192 
193 	memcpy(ts72xx_eth_data.dev_addr,
194 		(void *)(EP93XX_ETHERNET_BASE + 0x50), 6);
195 	platform_device_register(&ts72xx_eth_device);
196 }
197 
198 MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC")
199 	/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
200 	.phys_io	= EP93XX_APB_PHYS_BASE,
201 	.io_pg_offst	= ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
202 	.boot_params	= 0x00000100,
203 	.map_io		= ts72xx_map_io,
204 	.init_irq	= ep93xx_init_irq,
205 	.timer		= &ep93xx_timer,
206 	.init_machine	= ts72xx_init_machine,
207 MACHINE_END
208