aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/onenand/onenand_sim.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/onenand/onenand_sim.c')
-rw-r--r--drivers/mtd/onenand/onenand_sim.c81
1 files changed, 74 insertions, 7 deletions
diff --git a/drivers/mtd/onenand/onenand_sim.c b/drivers/mtd/onenand/onenand_sim.c
index d64200b7c94b..f6e3c8aebd3a 100644
--- a/drivers/mtd/onenand/onenand_sim.c
+++ b/drivers/mtd/onenand/onenand_sim.c
@@ -6,6 +6,10 @@
6 * Copyright © 2005-2007 Samsung Electronics 6 * Copyright © 2005-2007 Samsung Electronics
7 * Kyungmin Park <kyungmin.park@samsung.com> 7 * Kyungmin Park <kyungmin.park@samsung.com>
8 * 8 *
9 * Vishak G <vishak.g at samsung.com>, Rohit Hagargundgi <h.rohit at samsung.com>
10 * Flex-OneNAND simulator support
11 * Copyright (C) Samsung Electronics, 2008
12 *
9 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 14 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. 15 * published by the Free Software Foundation.
@@ -24,16 +28,38 @@
24#ifndef CONFIG_ONENAND_SIM_MANUFACTURER 28#ifndef CONFIG_ONENAND_SIM_MANUFACTURER
25#define CONFIG_ONENAND_SIM_MANUFACTURER 0xec 29#define CONFIG_ONENAND_SIM_MANUFACTURER 0xec
26#endif 30#endif
31
27#ifndef CONFIG_ONENAND_SIM_DEVICE_ID 32#ifndef CONFIG_ONENAND_SIM_DEVICE_ID
28#define CONFIG_ONENAND_SIM_DEVICE_ID 0x04 33#define CONFIG_ONENAND_SIM_DEVICE_ID 0x04
29#endif 34#endif
35
36#define CONFIG_FLEXONENAND ((CONFIG_ONENAND_SIM_DEVICE_ID >> 9) & 1)
37
30#ifndef CONFIG_ONENAND_SIM_VERSION_ID 38#ifndef CONFIG_ONENAND_SIM_VERSION_ID
31#define CONFIG_ONENAND_SIM_VERSION_ID 0x1e 39#define CONFIG_ONENAND_SIM_VERSION_ID 0x1e
32#endif 40#endif
33 41
42#ifndef CONFIG_ONENAND_SIM_TECHNOLOGY_ID
43#define CONFIG_ONENAND_SIM_TECHNOLOGY_ID CONFIG_FLEXONENAND
44#endif
45
46/* Initial boundary values for Flex-OneNAND Simulator */
47#ifndef CONFIG_FLEXONENAND_SIM_DIE0_BOUNDARY
48#define CONFIG_FLEXONENAND_SIM_DIE0_BOUNDARY 0x01
49#endif
50
51#ifndef CONFIG_FLEXONENAND_SIM_DIE1_BOUNDARY
52#define CONFIG_FLEXONENAND_SIM_DIE1_BOUNDARY 0x01
53#endif
54
34static int manuf_id = CONFIG_ONENAND_SIM_MANUFACTURER; 55static int manuf_id = CONFIG_ONENAND_SIM_MANUFACTURER;
35static int device_id = CONFIG_ONENAND_SIM_DEVICE_ID; 56static int device_id = CONFIG_ONENAND_SIM_DEVICE_ID;
36static int version_id = CONFIG_ONENAND_SIM_VERSION_ID; 57static int version_id = CONFIG_ONENAND_SIM_VERSION_ID;
58static int technology_id = CONFIG_ONENAND_SIM_TECHNOLOGY_ID;
59static int boundary[] = {
60 CONFIG_FLEXONENAND_SIM_DIE0_BOUNDARY,
61 CONFIG_FLEXONENAND_SIM_DIE1_BOUNDARY,
62};
37 63
38struct onenand_flash { 64struct onenand_flash {
39 void __iomem *base; 65 void __iomem *base;
@@ -57,12 +83,18 @@ struct onenand_flash {
57 (writew(v, this->base + ONENAND_REG_WP_STATUS)) 83 (writew(v, this->base + ONENAND_REG_WP_STATUS))
58 84
59/* It has all 0xff chars */ 85/* It has all 0xff chars */
60#define MAX_ONENAND_PAGESIZE (2048 + 64) 86#define MAX_ONENAND_PAGESIZE (4096 + 128)
61static unsigned char *ffchars; 87static unsigned char *ffchars;
62 88
89#if CONFIG_FLEXONENAND
90#define PARTITION_NAME "Flex-OneNAND simulator partition"
91#else
92#define PARTITION_NAME "OneNAND simulator partition"
93#endif
94
63static struct mtd_partition os_partitions[] = { 95static struct mtd_partition os_partitions[] = {
64 { 96 {
65 .name = "OneNAND simulator partition", 97 .name = PARTITION_NAME,
66 .offset = 0, 98 .offset = 0,
67 .size = MTDPART_SIZ_FULL, 99 .size = MTDPART_SIZ_FULL,
68 }, 100 },
@@ -104,6 +136,7 @@ static void onenand_lock_handle(struct onenand_chip *this, int cmd)
104 136
105 switch (cmd) { 137 switch (cmd) {
106 case ONENAND_CMD_UNLOCK: 138 case ONENAND_CMD_UNLOCK:
139 case ONENAND_CMD_UNLOCK_ALL:
107 if (block_lock_scheme) 140 if (block_lock_scheme)
108 ONENAND_SET_WP_STATUS(ONENAND_WP_US, this); 141 ONENAND_SET_WP_STATUS(ONENAND_WP_US, this);
109 else 142 else
@@ -228,10 +261,12 @@ static void onenand_data_handle(struct onenand_chip *this, int cmd,
228{ 261{
229 struct mtd_info *mtd = &info->mtd; 262 struct mtd_info *mtd = &info->mtd;
230 struct onenand_flash *flash = this->priv; 263 struct onenand_flash *flash = this->priv;
231 int main_offset, spare_offset; 264 int main_offset, spare_offset, die = 0;
232 void __iomem *src; 265 void __iomem *src;
233 void __iomem *dest; 266 void __iomem *dest;
234 unsigned int i; 267 unsigned int i;
268 static int pi_operation;
269 int erasesize, rgn;
235 270
236 if (dataram) { 271 if (dataram) {
237 main_offset = mtd->writesize; 272 main_offset = mtd->writesize;
@@ -241,10 +276,27 @@ static void onenand_data_handle(struct onenand_chip *this, int cmd,
241 spare_offset = 0; 276 spare_offset = 0;
242 } 277 }
243 278
279 if (pi_operation) {
280 die = readw(this->base + ONENAND_REG_START_ADDRESS2);
281 die >>= ONENAND_DDP_SHIFT;
282 }
283
244 switch (cmd) { 284 switch (cmd) {
285 case FLEXONENAND_CMD_PI_ACCESS:
286 pi_operation = 1;
287 break;
288
289 case ONENAND_CMD_RESET:
290 pi_operation = 0;
291 break;
292
245 case ONENAND_CMD_READ: 293 case ONENAND_CMD_READ:
246 src = ONENAND_CORE(flash) + offset; 294 src = ONENAND_CORE(flash) + offset;
247 dest = ONENAND_MAIN_AREA(this, main_offset); 295 dest = ONENAND_MAIN_AREA(this, main_offset);
296 if (pi_operation) {
297 writew(boundary[die], this->base + ONENAND_DATARAM);
298 break;
299 }
248 memcpy(dest, src, mtd->writesize); 300 memcpy(dest, src, mtd->writesize);
249 /* Fall through */ 301 /* Fall through */
250 302
@@ -257,6 +309,10 @@ static void onenand_data_handle(struct onenand_chip *this, int cmd,
257 case ONENAND_CMD_PROG: 309 case ONENAND_CMD_PROG:
258 src = ONENAND_MAIN_AREA(this, main_offset); 310 src = ONENAND_MAIN_AREA(this, main_offset);
259 dest = ONENAND_CORE(flash) + offset; 311 dest = ONENAND_CORE(flash) + offset;
312 if (pi_operation) {
313 boundary[die] = readw(this->base + ONENAND_DATARAM);
314 break;
315 }
260 /* To handle partial write */ 316 /* To handle partial write */
261 for (i = 0; i < (1 << mtd->subpage_sft); i++) { 317 for (i = 0; i < (1 << mtd->subpage_sft); i++) {
262 int off = i * this->subpagesize; 318 int off = i * this->subpagesize;
@@ -284,9 +340,18 @@ static void onenand_data_handle(struct onenand_chip *this, int cmd,
284 break; 340 break;
285 341
286 case ONENAND_CMD_ERASE: 342 case ONENAND_CMD_ERASE:
287 memset(ONENAND_CORE(flash) + offset, 0xff, mtd->erasesize); 343 if (pi_operation)
344 break;
345
346 if (FLEXONENAND(this)) {
347 rgn = flexonenand_region(mtd, offset);
348 erasesize = mtd->eraseregions[rgn].erasesize;
349 } else
350 erasesize = mtd->erasesize;
351
352 memset(ONENAND_CORE(flash) + offset, 0xff, erasesize);
288 memset(ONENAND_CORE_SPARE(flash, this, offset), 0xff, 353 memset(ONENAND_CORE_SPARE(flash, this, offset), 0xff,
289 (mtd->erasesize >> 5)); 354 (erasesize >> 5));
290 break; 355 break;
291 356
292 default: 357 default:
@@ -339,7 +404,7 @@ static void onenand_command_handle(struct onenand_chip *this, int cmd)
339 } 404 }
340 405
341 if (block != -1) 406 if (block != -1)
342 offset += block << this->erase_shift; 407 offset = onenand_addr(this, block);
343 408
344 if (page != -1) 409 if (page != -1)
345 offset += page << this->page_shift; 410 offset += page << this->page_shift;
@@ -390,6 +455,7 @@ static int __init flash_init(struct onenand_flash *flash)
390 } 455 }
391 456
392 density = device_id >> ONENAND_DEVICE_DENSITY_SHIFT; 457 density = device_id >> ONENAND_DEVICE_DENSITY_SHIFT;
458 density &= ONENAND_DEVICE_DENSITY_MASK;
393 size = ((16 << 20) << density); 459 size = ((16 << 20) << density);
394 460
395 ONENAND_CORE(flash) = vmalloc(size + (size >> 5)); 461 ONENAND_CORE(flash) = vmalloc(size + (size >> 5));
@@ -405,8 +471,9 @@ static int __init flash_init(struct onenand_flash *flash)
405 writew(manuf_id, flash->base + ONENAND_REG_MANUFACTURER_ID); 471 writew(manuf_id, flash->base + ONENAND_REG_MANUFACTURER_ID);
406 writew(device_id, flash->base + ONENAND_REG_DEVICE_ID); 472 writew(device_id, flash->base + ONENAND_REG_DEVICE_ID);
407 writew(version_id, flash->base + ONENAND_REG_VERSION_ID); 473 writew(version_id, flash->base + ONENAND_REG_VERSION_ID);
474 writew(technology_id, flash->base + ONENAND_REG_TECHNOLOGY);
408 475
409 if (density < 2) 476 if (density < 2 && (!CONFIG_FLEXONENAND))
410 buffer_size = 0x0400; /* 1KiB page */ 477 buffer_size = 0x0400; /* 1KiB page */
411 else 478 else
412 buffer_size = 0x0800; /* 2KiB page */ 479 buffer_size = 0x0800; /* 2KiB page */