diff options
Diffstat (limited to 'arch/arm/mach-orion5x')
-rw-r--r-- | arch/arm/mach-orion5x/ts78xx-fpga.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-orion5x/ts78xx-setup.c | 132 |
2 files changed, 133 insertions, 0 deletions
diff --git a/arch/arm/mach-orion5x/ts78xx-fpga.h b/arch/arm/mach-orion5x/ts78xx-fpga.h index 0b8e30faff14..e2c503c7807e 100644 --- a/arch/arm/mach-orion5x/ts78xx-fpga.h +++ b/arch/arm/mach-orion5x/ts78xx-fpga.h | |||
@@ -17,6 +17,7 @@ struct fpga_device { | |||
17 | struct fpga_devices { | 17 | struct fpga_devices { |
18 | /* Technologic Systems */ | 18 | /* Technologic Systems */ |
19 | struct fpga_device ts_rtc; | 19 | struct fpga_device ts_rtc; |
20 | struct fpga_device ts_nand; | ||
20 | }; | 21 | }; |
21 | 22 | ||
22 | struct ts78xx_fpga_data { | 23 | struct ts78xx_fpga_data { |
diff --git a/arch/arm/mach-orion5x/ts78xx-setup.c b/arch/arm/mach-orion5x/ts78xx-setup.c index 640b44db5a3f..a6eec4e49424 100644 --- a/arch/arm/mach-orion5x/ts78xx-setup.c +++ b/arch/arm/mach-orion5x/ts78xx-setup.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <linux/mv643xx_eth.h> | 15 | #include <linux/mv643xx_eth.h> |
16 | #include <linux/ata_platform.h> | 16 | #include <linux/ata_platform.h> |
17 | #include <linux/m48t86.h> | 17 | #include <linux/m48t86.h> |
18 | #include <linux/mtd/nand.h> | ||
19 | #include <linux/mtd/partitions.h> | ||
18 | #include <asm/mach-types.h> | 20 | #include <asm/mach-types.h> |
19 | #include <asm/mach/arch.h> | 21 | #include <asm/mach/arch.h> |
20 | #include <asm/mach/map.h> | 22 | #include <asm/mach/map.h> |
@@ -151,11 +153,129 @@ static void ts78xx_ts_rtc_unload(void) | |||
151 | } | 153 | } |
152 | 154 | ||
153 | /***************************************************************************** | 155 | /***************************************************************************** |
156 | * NAND Flash | ||
157 | ****************************************************************************/ | ||
158 | #define TS_NAND_CTRL (TS78XX_FPGA_REGS_VIRT_BASE | 0x800) /* VIRT */ | ||
159 | #define TS_NAND_DATA (TS78XX_FPGA_REGS_PHYS_BASE | 0x804) /* PHYS */ | ||
160 | |||
161 | /* | ||
162 | * hardware specific access to control-lines | ||
163 | * | ||
164 | * ctrl: | ||
165 | * NAND_NCE: bit 0 -> bit 2 | ||
166 | * NAND_CLE: bit 1 -> bit 1 | ||
167 | * NAND_ALE: bit 2 -> bit 0 | ||
168 | */ | ||
169 | static void ts78xx_ts_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, | ||
170 | unsigned int ctrl) | ||
171 | { | ||
172 | struct nand_chip *this = mtd->priv; | ||
173 | |||
174 | if (ctrl & NAND_CTRL_CHANGE) { | ||
175 | unsigned char bits; | ||
176 | |||
177 | bits = (ctrl & NAND_NCE) << 2; | ||
178 | bits |= ctrl & NAND_CLE; | ||
179 | bits |= (ctrl & NAND_ALE) >> 2; | ||
180 | |||
181 | writeb((readb(TS_NAND_CTRL) & ~0x7) | bits, TS_NAND_CTRL); | ||
182 | } | ||
183 | |||
184 | if (cmd != NAND_CMD_NONE) | ||
185 | writeb(cmd, this->IO_ADDR_W); | ||
186 | } | ||
187 | |||
188 | static int ts78xx_ts_nand_dev_ready(struct mtd_info *mtd) | ||
189 | { | ||
190 | return readb(TS_NAND_CTRL) & 0x20; | ||
191 | } | ||
192 | |||
193 | const char *ts_nand_part_probes[] = { "cmdlinepart", NULL }; | ||
194 | |||
195 | static struct mtd_partition ts78xx_ts_nand_parts[] = { | ||
196 | { | ||
197 | .name = "mbr", | ||
198 | .offset = 0, | ||
199 | .size = SZ_128K, | ||
200 | .mask_flags = MTD_WRITEABLE, | ||
201 | }, { | ||
202 | .name = "kernel", | ||
203 | .offset = MTDPART_OFS_APPEND, | ||
204 | .size = SZ_4M, | ||
205 | }, { | ||
206 | .name = "initrd", | ||
207 | .offset = MTDPART_OFS_APPEND, | ||
208 | .size = SZ_4M, | ||
209 | }, { | ||
210 | .name = "rootfs", | ||
211 | .offset = MTDPART_OFS_APPEND, | ||
212 | .size = MTDPART_SIZ_FULL, | ||
213 | } | ||
214 | }; | ||
215 | |||
216 | static struct platform_nand_data ts78xx_ts_nand_data = { | ||
217 | .chip = { | ||
218 | .part_probe_types = ts_nand_part_probes, | ||
219 | .partitions = ts78xx_ts_nand_parts, | ||
220 | .nr_partitions = ARRAY_SIZE(ts78xx_ts_nand_parts), | ||
221 | .chip_delay = 15, | ||
222 | .options = NAND_USE_FLASH_BBT, | ||
223 | }, | ||
224 | .ctrl = { | ||
225 | /* | ||
226 | * The HW ECC offloading functions, used to give about a 9% | ||
227 | * performance increase for 'dd if=/dev/mtdblockX' and 5% for | ||
228 | * nanddump. This all however was changed by git commit | ||
229 | * e6cf5df1838c28bb060ac45b5585e48e71bbc740 so now there is | ||
230 | * no performance advantage to be had so we no longer bother | ||
231 | */ | ||
232 | .cmd_ctrl = ts78xx_ts_nand_cmd_ctrl, | ||
233 | .dev_ready = ts78xx_ts_nand_dev_ready, | ||
234 | }, | ||
235 | }; | ||
236 | |||
237 | static struct resource ts78xx_ts_nand_resources = { | ||
238 | .start = TS_NAND_DATA, | ||
239 | .end = TS_NAND_DATA + 4, | ||
240 | .flags = IORESOURCE_IO, | ||
241 | }; | ||
242 | |||
243 | static struct platform_device ts78xx_ts_nand_device = { | ||
244 | .name = "gen_nand", | ||
245 | .id = -1, | ||
246 | .dev = { | ||
247 | .platform_data = &ts78xx_ts_nand_data, | ||
248 | }, | ||
249 | .resource = &ts78xx_ts_nand_resources, | ||
250 | .num_resources = 1, | ||
251 | }; | ||
252 | |||
253 | static int ts78xx_ts_nand_load(void) | ||
254 | { | ||
255 | int rc; | ||
256 | |||
257 | if (ts78xx_fpga.supports.ts_nand.init == 0) { | ||
258 | rc = platform_device_register(&ts78xx_ts_nand_device); | ||
259 | if (!rc) | ||
260 | ts78xx_fpga.supports.ts_nand.init = 1; | ||
261 | } else | ||
262 | rc = platform_device_add(&ts78xx_ts_nand_device); | ||
263 | |||
264 | return rc; | ||
265 | }; | ||
266 | |||
267 | static void ts78xx_ts_nand_unload(void) | ||
268 | { | ||
269 | platform_device_del(&ts78xx_ts_nand_device); | ||
270 | } | ||
271 | |||
272 | /***************************************************************************** | ||
154 | * FPGA 'hotplug' support code | 273 | * FPGA 'hotplug' support code |
155 | ****************************************************************************/ | 274 | ****************************************************************************/ |
156 | static void ts78xx_fpga_devices_zero_init(void) | 275 | static void ts78xx_fpga_devices_zero_init(void) |
157 | { | 276 | { |
158 | ts78xx_fpga.supports.ts_rtc.init = 0; | 277 | ts78xx_fpga.supports.ts_rtc.init = 0; |
278 | ts78xx_fpga.supports.ts_nand.init = 0; | ||
159 | } | 279 | } |
160 | 280 | ||
161 | static void ts78xx_fpga_supports(void) | 281 | static void ts78xx_fpga_supports(void) |
@@ -164,9 +284,11 @@ static void ts78xx_fpga_supports(void) | |||
164 | switch (ts78xx_fpga.id) { | 284 | switch (ts78xx_fpga.id) { |
165 | case TS7800_REV_B: | 285 | case TS7800_REV_B: |
166 | ts78xx_fpga.supports.ts_rtc.present = 1; | 286 | ts78xx_fpga.supports.ts_rtc.present = 1; |
287 | ts78xx_fpga.supports.ts_nand.present = 1; | ||
167 | break; | 288 | break; |
168 | default: | 289 | default: |
169 | ts78xx_fpga.supports.ts_rtc.present = 0; | 290 | ts78xx_fpga.supports.ts_rtc.present = 0; |
291 | ts78xx_fpga.supports.ts_nand.present = 0; | ||
170 | } | 292 | } |
171 | } | 293 | } |
172 | 294 | ||
@@ -182,6 +304,14 @@ static int ts78xx_fpga_load_devices(void) | |||
182 | } | 304 | } |
183 | ret |= tmp; | 305 | ret |= tmp; |
184 | } | 306 | } |
307 | if (ts78xx_fpga.supports.ts_nand.present == 1) { | ||
308 | tmp = ts78xx_ts_nand_load(); | ||
309 | if (tmp) { | ||
310 | printk(KERN_INFO "TS-78xx: NAND not registered\n"); | ||
311 | ts78xx_fpga.supports.ts_nand.present = 0; | ||
312 | } | ||
313 | ret |= tmp; | ||
314 | } | ||
185 | 315 | ||
186 | return ret; | 316 | return ret; |
187 | } | 317 | } |
@@ -192,6 +322,8 @@ static int ts78xx_fpga_unload_devices(void) | |||
192 | 322 | ||
193 | if (ts78xx_fpga.supports.ts_rtc.present == 1) | 323 | if (ts78xx_fpga.supports.ts_rtc.present == 1) |
194 | ts78xx_ts_rtc_unload(); | 324 | ts78xx_ts_rtc_unload(); |
325 | if (ts78xx_fpga.supports.ts_nand.present == 1) | ||
326 | ts78xx_ts_nand_unload(); | ||
195 | 327 | ||
196 | return ret; | 328 | return ret; |
197 | } | 329 | } |