xref: /openbmc/linux/arch/arm/mach-ep93xx/ts72xx.c (revision a09d2831)
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/platform_device.h>
16 #include <linux/io.h>
17 #include <linux/m48t86.h>
18 #include <linux/mtd/physmap.h>
19 
20 #include <mach/hardware.h>
21 #include <mach/ts72xx.h>
22 
23 #include <asm/mach-types.h>
24 #include <asm/mach/map.h>
25 #include <asm/mach/arch.h>
26 
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 /*************************************************************************
115  * NOR flash (TS-7200 only)
116  *************************************************************************/
117 static struct physmap_flash_data ts72xx_flash_data = {
118 	.width		= 2,
119 };
120 
121 static struct resource ts72xx_flash_resource = {
122 	.start		= EP93XX_CS6_PHYS_BASE,
123 	.end		= EP93XX_CS6_PHYS_BASE + SZ_16M - 1,
124 	.flags		= IORESOURCE_MEM,
125 };
126 
127 static struct platform_device ts72xx_flash = {
128 	.name		= "physmap-flash",
129 	.id		= 0,
130 	.dev		= {
131 		.platform_data	= &ts72xx_flash_data,
132 	},
133 	.num_resources	= 1,
134 	.resource	= &ts72xx_flash_resource,
135 };
136 
137 static void __init ts72xx_register_flash(void)
138 {
139 	if (board_is_ts7200())
140 		platform_device_register(&ts72xx_flash);
141 }
142 
143 static unsigned char ts72xx_rtc_readbyte(unsigned long addr)
144 {
145 	__raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE);
146 	return __raw_readb(TS72XX_RTC_DATA_VIRT_BASE);
147 }
148 
149 static void ts72xx_rtc_writebyte(unsigned char value, unsigned long addr)
150 {
151 	__raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE);
152 	__raw_writeb(value, TS72XX_RTC_DATA_VIRT_BASE);
153 }
154 
155 static struct m48t86_ops ts72xx_rtc_ops = {
156 	.readbyte	= ts72xx_rtc_readbyte,
157 	.writebyte	= ts72xx_rtc_writebyte,
158 };
159 
160 static struct platform_device ts72xx_rtc_device = {
161 	.name		= "rtc-m48t86",
162 	.id		= -1,
163 	.dev		= {
164 		.platform_data	= &ts72xx_rtc_ops,
165 	},
166 	.num_resources	= 0,
167 };
168 
169 static struct ep93xx_eth_data ts72xx_eth_data = {
170 	.phy_id		= 1,
171 };
172 
173 static void __init ts72xx_init_machine(void)
174 {
175 	ep93xx_init_devices();
176 	ts72xx_register_flash();
177 	platform_device_register(&ts72xx_rtc_device);
178 
179 	ep93xx_register_eth(&ts72xx_eth_data, 1);
180 }
181 
182 MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC")
183 	/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
184 	.phys_io	= EP93XX_APB_PHYS_BASE,
185 	.io_pg_offst	= ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
186 	.boot_params	= EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
187 	.map_io		= ts72xx_map_io,
188 	.init_irq	= ep93xx_init_irq,
189 	.timer		= &ep93xx_timer,
190 	.init_machine	= ts72xx_init_machine,
191 MACHINE_END
192