aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-ep93xx
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-05-21 10:25:43 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-21 10:25:43 -0400
commit05ec7dd8dd5aa42c22a49682e4a51cadd4166b7e (patch)
tree6370b43c0d8f324aa7421bbb5a647aa04ab5d747 /arch/arm/mach-ep93xx
parentc316ba3b518bc35ce5aef5421135220389f4eb98 (diff)
parent8046112818b70329e930b1d4557ef0876c1ad2bb (diff)
Merge git://git.infradead.org/mtd-2.6
* git://git.infradead.org/mtd-2.6: (154 commits) mtd: cfi_cmdset_0002: use AMD standard command-set with Winbond flash chips mtd: cfi_cmdset_0002: Fix MODULE_ALIAS and linkage for new 0701 commandset ID mtd: mxc_nand: Remove duplicate NAND_CMD_RESET case value mtd: update gfp/slab.h includes jffs2: Stop triggering block erases from jffs2_write_super() jffs2: Rename jffs2_erase_pending_trigger() to jffs2_dirty_trigger() jffs2: Use jffs2_garbage_collect_trigger() to trigger pending erases jffs2: Require jffs2_garbage_collect_trigger() to be called with lock held jffs2: Wake GC thread when there are blocks to be erased jffs2: Erase pending blocks in GC pass, avoid invalid -EIO return jffs2: Add 'work_done' return value from jffs2_erase_pending_blocks() mtd: mtdchar: Do not corrupt backing device of device node inode mtd/maps/pcmciamtd: Fix printk format for ssize_t in debug messages drivers/mtd: Use kmemdup mtd: cfi_cmdset_0002: Fix argument order in bootloc warning mtd: nand: add Toshiba TC58NVG0 device ID pcmciamtd: add another ID pcmciamtd: coding style cleanups pcmciamtd: fixing obvious errors mtd: chips: add SST39WF160x NOR-flashes ... Trivial conflicts due to dev_node removal in drivers/mtd/maps/pcmciamtd.c
Diffstat (limited to 'arch/arm/mach-ep93xx')
-rw-r--r--arch/arm/mach-ep93xx/include/mach/ts72xx.h19
-rw-r--r--arch/arm/mach-ep93xx/ts72xx.c188
2 files changed, 131 insertions, 76 deletions
diff --git a/arch/arm/mach-ep93xx/include/mach/ts72xx.h b/arch/arm/mach-ep93xx/include/mach/ts72xx.h
index 93107d88ff3a..0eabec62cd9d 100644
--- a/arch/arm/mach-ep93xx/include/mach/ts72xx.h
+++ b/arch/arm/mach-ep93xx/include/mach/ts72xx.h
@@ -9,9 +9,6 @@
9 * febff000 22000000 4K model number register 9 * febff000 22000000 4K model number register
10 * febfe000 22400000 4K options register 10 * febfe000 22400000 4K options register
11 * febfd000 22800000 4K options register #2 11 * febfd000 22800000 4K options register #2
12 * febfc000 [67]0000000 4K NAND data register
13 * febfb000 [67]0400000 4K NAND control register
14 * febfa000 [67]0800000 4K NAND busy register
15 * febf9000 10800000 4K TS-5620 RTC index register 12 * febf9000 10800000 4K TS-5620 RTC index register
16 * febf8000 11700000 4K TS-5620 RTC data register 13 * febf8000 11700000 4K TS-5620 RTC data register
17 */ 14 */
@@ -41,22 +38,6 @@
41#define TS72XX_OPTIONS2_TS9420_BOOT 0x02 38#define TS72XX_OPTIONS2_TS9420_BOOT 0x02
42 39
43 40
44#define TS72XX_NAND1_DATA_PHYS_BASE 0x60000000
45#define TS72XX_NAND2_DATA_PHYS_BASE 0x70000000
46#define TS72XX_NAND_DATA_VIRT_BASE 0xfebfc000
47#define TS72XX_NAND_DATA_SIZE 0x00001000
48
49#define TS72XX_NAND1_CONTROL_PHYS_BASE 0x60400000
50#define TS72XX_NAND2_CONTROL_PHYS_BASE 0x70400000
51#define TS72XX_NAND_CONTROL_VIRT_BASE 0xfebfb000
52#define TS72XX_NAND_CONTROL_SIZE 0x00001000
53
54#define TS72XX_NAND1_BUSY_PHYS_BASE 0x60800000
55#define TS72XX_NAND2_BUSY_PHYS_BASE 0x70800000
56#define TS72XX_NAND_BUSY_VIRT_BASE 0xfebfa000
57#define TS72XX_NAND_BUSY_SIZE 0x00001000
58
59
60#define TS72XX_RTC_INDEX_VIRT_BASE 0xfebf9000 41#define TS72XX_RTC_INDEX_VIRT_BASE 0xfebf9000
61#define TS72XX_RTC_INDEX_PHYS_BASE 0x10800000 42#define TS72XX_RTC_INDEX_PHYS_BASE 0x10800000
62#define TS72XX_RTC_INDEX_SIZE 0x00001000 43#define TS72XX_RTC_INDEX_SIZE 0x00001000
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
index 9553031900b0..ae7319e588c7 100644
--- a/arch/arm/mach-ep93xx/ts72xx.c
+++ b/arch/arm/mach-ep93xx/ts72xx.c
@@ -10,12 +10,16 @@
10 * your option) any later version. 10 * your option) any later version.
11 */ 11 */
12 12
13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14
13#include <linux/kernel.h> 15#include <linux/kernel.h>
14#include <linux/init.h> 16#include <linux/init.h>
15#include <linux/platform_device.h> 17#include <linux/platform_device.h>
16#include <linux/io.h> 18#include <linux/io.h>
17#include <linux/m48t86.h> 19#include <linux/m48t86.h>
18#include <linux/mtd/physmap.h> 20#include <linux/mtd/physmap.h>
21#include <linux/mtd/nand.h>
22#include <linux/mtd/partitions.h>
19 23
20#include <mach/hardware.h> 24#include <mach/hardware.h>
21#include <mach/ts72xx.h> 25#include <mach/ts72xx.h>
@@ -54,92 +58,162 @@ static struct map_desc ts72xx_io_desc[] __initdata = {
54 } 58 }
55}; 59};
56 60
57static struct map_desc ts72xx_nand_io_desc[] __initdata = { 61static void __init ts72xx_map_io(void)
58 { 62{
59 .virtual = TS72XX_NAND_DATA_VIRT_BASE, 63 ep93xx_map_io();
60 .pfn = __phys_to_pfn(TS72XX_NAND1_DATA_PHYS_BASE), 64 iotable_init(ts72xx_io_desc, ARRAY_SIZE(ts72xx_io_desc));
61 .length = TS72XX_NAND_DATA_SIZE, 65}
62 .type = MT_DEVICE, 66
63 }, { 67
64 .virtual = TS72XX_NAND_CONTROL_VIRT_BASE, 68/*************************************************************************
65 .pfn = __phys_to_pfn(TS72XX_NAND1_CONTROL_PHYS_BASE), 69 * NAND flash
66 .length = TS72XX_NAND_CONTROL_SIZE, 70 *************************************************************************/
67 .type = MT_DEVICE, 71#define TS72XX_NAND_CONTROL_ADDR_LINE 22 /* 0xN0400000 */
68 }, { 72#define TS72XX_NAND_BUSY_ADDR_LINE 23 /* 0xN0800000 */
69 .virtual = TS72XX_NAND_BUSY_VIRT_BASE, 73
70 .pfn = __phys_to_pfn(TS72XX_NAND1_BUSY_PHYS_BASE), 74static void ts72xx_nand_hwcontrol(struct mtd_info *mtd,
71 .length = TS72XX_NAND_BUSY_SIZE, 75 int cmd, unsigned int ctrl)
72 .type = MT_DEVICE, 76{
77 struct nand_chip *chip = mtd->priv;
78
79 if (ctrl & NAND_CTRL_CHANGE) {
80 void __iomem *addr = chip->IO_ADDR_R;
81 unsigned char bits;
82
83 addr += (1 << TS72XX_NAND_CONTROL_ADDR_LINE);
84
85 bits = __raw_readb(addr) & ~0x07;
86 bits |= (ctrl & NAND_NCE) << 2; /* bit 0 -> bit 2 */
87 bits |= (ctrl & NAND_CLE); /* bit 1 -> bit 1 */
88 bits |= (ctrl & NAND_ALE) >> 2; /* bit 2 -> bit 0 */
89
90 __raw_writeb(bits, addr);
73 } 91 }
74};
75 92
76static struct map_desc ts72xx_alternate_nand_io_desc[] __initdata = { 93 if (cmd != NAND_CMD_NONE)
94 __raw_writeb(cmd, chip->IO_ADDR_W);
95}
96
97static int ts72xx_nand_device_ready(struct mtd_info *mtd)
98{
99 struct nand_chip *chip = mtd->priv;
100 void __iomem *addr = chip->IO_ADDR_R;
101
102 addr += (1 << TS72XX_NAND_BUSY_ADDR_LINE);
103
104 return !!(__raw_readb(addr) & 0x20);
105}
106
107static const char *ts72xx_nand_part_probes[] = { "cmdlinepart", NULL };
108
109#define TS72XX_BOOTROM_PART_SIZE (SZ_16K)
110#define TS72XX_REDBOOT_PART_SIZE (SZ_2M + SZ_1M)
111
112static struct mtd_partition ts72xx_nand_parts[] = {
77 { 113 {
78 .virtual = TS72XX_NAND_DATA_VIRT_BASE, 114 .name = "TS-BOOTROM",
79 .pfn = __phys_to_pfn(TS72XX_NAND2_DATA_PHYS_BASE), 115 .offset = 0,
80 .length = TS72XX_NAND_DATA_SIZE, 116 .size = TS72XX_BOOTROM_PART_SIZE,
81 .type = MT_DEVICE, 117 .mask_flags = MTD_WRITEABLE, /* force read-only */
82 }, { 118 }, {
83 .virtual = TS72XX_NAND_CONTROL_VIRT_BASE, 119 .name = "Linux",
84 .pfn = __phys_to_pfn(TS72XX_NAND2_CONTROL_PHYS_BASE), 120 .offset = MTDPART_OFS_APPEND,
85 .length = TS72XX_NAND_CONTROL_SIZE, 121 .size = 0, /* filled in later */
86 .type = MT_DEVICE,
87 }, { 122 }, {
88 .virtual = TS72XX_NAND_BUSY_VIRT_BASE, 123 .name = "RedBoot",
89 .pfn = __phys_to_pfn(TS72XX_NAND2_BUSY_PHYS_BASE), 124 .offset = MTDPART_OFS_APPEND,
90 .length = TS72XX_NAND_BUSY_SIZE, 125 .size = MTDPART_SIZ_FULL,
91 .type = MT_DEVICE, 126 .mask_flags = MTD_WRITEABLE, /* force read-only */
92 } 127 },
93}; 128};
94 129
95static void __init ts72xx_map_io(void) 130static void ts72xx_nand_set_parts(uint64_t size,
131 struct platform_nand_chip *chip)
96{ 132{
97 ep93xx_map_io(); 133 /* Factory TS-72xx boards only come with 32MiB or 128MiB NAND options */
98 iotable_init(ts72xx_io_desc, ARRAY_SIZE(ts72xx_io_desc)); 134 if (size == SZ_32M || size == SZ_128M) {
135 /* Set the "Linux" partition size */
136 ts72xx_nand_parts[1].size = size - TS72XX_REDBOOT_PART_SIZE;
99 137
100 /* 138 chip->partitions = ts72xx_nand_parts;
101 * The TS-7200 has NOR flash, the other models have NAND flash. 139 chip->nr_partitions = ARRAY_SIZE(ts72xx_nand_parts);
102 */ 140 } else {
103 if (!board_is_ts7200()) { 141 pr_warning("Unknown nand disk size:%lluMiB\n", size >> 20);
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 } 142 }
112} 143}
113 144
145static struct platform_nand_data ts72xx_nand_data = {
146 .chip = {
147 .nr_chips = 1,
148 .chip_offset = 0,
149 .chip_delay = 15,
150 .part_probe_types = ts72xx_nand_part_probes,
151 .set_parts = ts72xx_nand_set_parts,
152 },
153 .ctrl = {
154 .cmd_ctrl = ts72xx_nand_hwcontrol,
155 .dev_ready = ts72xx_nand_device_ready,
156 },
157};
158
159static struct resource ts72xx_nand_resource[] = {
160 {
161 .start = 0, /* filled in later */
162 .end = 0, /* filled in later */
163 .flags = IORESOURCE_MEM,
164 },
165};
166
167static struct platform_device ts72xx_nand_flash = {
168 .name = "gen_nand",
169 .id = -1,
170 .dev.platform_data = &ts72xx_nand_data,
171 .resource = ts72xx_nand_resource,
172 .num_resources = ARRAY_SIZE(ts72xx_nand_resource),
173};
174
175
114/************************************************************************* 176/*************************************************************************
115 * NOR flash (TS-7200 only) 177 * NOR flash (TS-7200 only)
116 *************************************************************************/ 178 *************************************************************************/
117static struct physmap_flash_data ts72xx_flash_data = { 179static struct physmap_flash_data ts72xx_nor_data = {
118 .width = 2, 180 .width = 2,
119}; 181};
120 182
121static struct resource ts72xx_flash_resource = { 183static struct resource ts72xx_nor_resource = {
122 .start = EP93XX_CS6_PHYS_BASE, 184 .start = EP93XX_CS6_PHYS_BASE,
123 .end = EP93XX_CS6_PHYS_BASE + SZ_16M - 1, 185 .end = EP93XX_CS6_PHYS_BASE + SZ_16M - 1,
124 .flags = IORESOURCE_MEM, 186 .flags = IORESOURCE_MEM,
125}; 187};
126 188
127static struct platform_device ts72xx_flash = { 189static struct platform_device ts72xx_nor_flash = {
128 .name = "physmap-flash", 190 .name = "physmap-flash",
129 .id = 0, 191 .id = 0,
130 .dev = { 192 .dev.platform_data = &ts72xx_nor_data,
131 .platform_data = &ts72xx_flash_data, 193 .resource = &ts72xx_nor_resource,
132 }, 194 .num_resources = 1,
133 .num_resources = 1,
134 .resource = &ts72xx_flash_resource,
135}; 195};
136 196
137static void __init ts72xx_register_flash(void) 197static void __init ts72xx_register_flash(void)
138{ 198{
139 if (board_is_ts7200()) 199 if (board_is_ts7200()) {
140 platform_device_register(&ts72xx_flash); 200 platform_device_register(&ts72xx_nor_flash);
201 } else {
202 resource_size_t start;
203
204 if (is_ts9420_installed())
205 start = EP93XX_CS7_PHYS_BASE;
206 else
207 start = EP93XX_CS6_PHYS_BASE;
208
209 ts72xx_nand_resource[0].start = start;
210 ts72xx_nand_resource[0].end = start + SZ_16M - 1;
211
212 platform_device_register(&ts72xx_nand_flash);
213 }
141} 214}
142 215
216
143static unsigned char ts72xx_rtc_readbyte(unsigned long addr) 217static unsigned char ts72xx_rtc_readbyte(unsigned long addr)
144{ 218{
145 __raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE); 219 __raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE);