aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorH Hartley Sweeten <hartleys@visionengravers.com>2010-01-05 16:59:56 -0500
committerDavid Woodhouse <David.Woodhouse@intel.com>2010-01-06 08:21:13 -0500
commit030d2dd450a628b7a8e31e980af3d05854f68edb (patch)
treefd1b6bec2f28cfd038dd6c888d865823246d2991 /arch
parentde58288d1dc4ec73d36395a3c4a7708f01311d20 (diff)
mtd: Update ep93xx/ts72xx to use generic platform nand driver
Update the ts72xx platform's nand driver support. This changes the ts72xx platform from using a custom nand driver (ts7250.c) to the generic platform nand driver (plat_nand.c). Tested on TS-7250 with 32MiB NAND. Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com> Tested-by: Matthieu Crapet <mcrapet@gmail.com> Cc: Jesse Off <joff@embeddedARM.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-ep93xx/ts72xx.c188
1 files changed, 131 insertions, 57 deletions
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
index 259f7822ba52..47a86f07831d 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);