sh_flctl.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966
  1. /*
  2. * SuperH FLCTL nand controller
  3. *
  4. * Copyright (c) 2008 Renesas Solutions Corp.
  5. * Copyright (c) 2008 Atom Create Engineering Co., Ltd.
  6. *
  7. * Based on fsl_elbc_nand.c, Copyright (c) 2006-2007 Freescale Semiconductor
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; version 2 of the License.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  21. *
  22. */
  23. #include <linux/module.h>
  24. #include <linux/kernel.h>
  25. #include <linux/delay.h>
  26. #include <linux/io.h>
  27. #include <linux/platform_device.h>
  28. #include <linux/pm_runtime.h>
  29. #include <linux/slab.h>
  30. #include <linux/mtd/mtd.h>
  31. #include <linux/mtd/nand.h>
  32. #include <linux/mtd/partitions.h>
  33. #include <linux/mtd/sh_flctl.h>
  34. static struct nand_ecclayout flctl_4secc_oob_16 = {
  35. .eccbytes = 10,
  36. .eccpos = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
  37. .oobfree = {
  38. {.offset = 12,
  39. . length = 4} },
  40. };
  41. static struct nand_ecclayout flctl_4secc_oob_64 = {
  42. .eccbytes = 10,
  43. .eccpos = {48, 49, 50, 51, 52, 53, 54, 55, 56, 57},
  44. .oobfree = {
  45. {.offset = 60,
  46. . length = 4} },
  47. };
  48. static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
  49. static struct nand_bbt_descr flctl_4secc_smallpage = {
  50. .options = NAND_BBT_SCAN2NDPAGE,
  51. .offs = 11,
  52. .len = 1,
  53. .pattern = scan_ff_pattern,
  54. };
  55. static struct nand_bbt_descr flctl_4secc_largepage = {
  56. .options = NAND_BBT_SCAN2NDPAGE,
  57. .offs = 58,
  58. .len = 2,
  59. .pattern = scan_ff_pattern,
  60. };
  61. static void empty_fifo(struct sh_flctl *flctl)
  62. {
  63. writel(0x000c0000, FLINTDMACR(flctl)); /* FIFO Clear */
  64. writel(0x00000000, FLINTDMACR(flctl)); /* Clear Error flags */
  65. }
  66. static void start_translation(struct sh_flctl *flctl)
  67. {
  68. writeb(TRSTRT, FLTRCR(flctl));
  69. }
  70. static void timeout_error(struct sh_flctl *flctl, const char *str)
  71. {
  72. dev_err(&flctl->pdev->dev, "Timeout occurred in %s\n", str);
  73. }
  74. static void wait_completion(struct sh_flctl *flctl)
  75. {
  76. uint32_t timeout = LOOP_TIMEOUT_MAX;
  77. while (timeout--) {
  78. if (readb(FLTRCR(flctl)) & TREND) {
  79. writeb(0x0, FLTRCR(flctl));
  80. return;
  81. }
  82. udelay(1);
  83. }
  84. timeout_error(flctl, __func__);
  85. writeb(0x0, FLTRCR(flctl));
  86. }
  87. static void set_addr(struct mtd_info *mtd, int column, int page_addr)
  88. {
  89. struct sh_flctl *flctl = mtd_to_flctl(mtd);
  90. uint32_t addr = 0;
  91. if (column == -1) {
  92. addr = page_addr; /* ERASE1 */
  93. } else if (page_addr != -1) {
  94. /* SEQIN, READ0, etc.. */
  95. if (flctl->chip.options & NAND_BUSWIDTH_16)
  96. column >>= 1;
  97. if (flctl->page_size) {
  98. addr = column & 0x0FFF;
  99. addr |= (page_addr & 0xff) << 16;
  100. addr |= ((page_addr >> 8) & 0xff) << 24;
  101. /* big than 128MB */
  102. if (flctl->rw_ADRCNT == ADRCNT2_E) {
  103. uint32_t addr2;
  104. addr2 = (page_addr >> 16) & 0xff;
  105. writel(addr2, FLADR2(flctl));
  106. }
  107. } else {
  108. addr = column;
  109. addr |= (page_addr & 0xff) << 8;
  110. addr |= ((page_addr >> 8) & 0xff) << 16;
  111. addr |= ((page_addr >> 16) & 0xff) << 24;
  112. }
  113. }
  114. writel(addr, FLADR(flctl));
  115. }
  116. static void wait_rfifo_ready(struct sh_flctl *flctl)
  117. {
  118. uint32_t timeout = LOOP_TIMEOUT_MAX;
  119. while (timeout--) {
  120. uint32_t val;
  121. /* check FIFO */
  122. val = readl(FLDTCNTR(flctl)) >> 16;
  123. if (val & 0xFF)
  124. return;
  125. udelay(1);
  126. }
  127. timeout_error(flctl, __func__);
  128. }
  129. static void wait_wfifo_ready(struct sh_flctl *flctl)
  130. {
  131. uint32_t len, timeout = LOOP_TIMEOUT_MAX;
  132. while (timeout--) {
  133. /* check FIFO */
  134. len = (readl(FLDTCNTR(flctl)) >> 16) & 0xFF;
  135. if (len >= 4)
  136. return;
  137. udelay(1);
  138. }
  139. timeout_error(flctl, __func__);
  140. }
  141. static int wait_recfifo_ready(struct sh_flctl *flctl, int sector_number)
  142. {
  143. uint32_t timeout = LOOP_TIMEOUT_MAX;
  144. int checked[4];
  145. void __iomem *ecc_reg[4];
  146. int i;
  147. uint32_t data, size;
  148. memset(checked, 0, sizeof(checked));
  149. while (timeout--) {
  150. size = readl(FLDTCNTR(flctl)) >> 24;
  151. if (size & 0xFF)
  152. return 0; /* success */
  153. if (readl(FL4ECCCR(flctl)) & _4ECCFA)
  154. return 1; /* can't correct */
  155. udelay(1);
  156. if (!(readl(FL4ECCCR(flctl)) & _4ECCEND))
  157. continue;
  158. /* start error correction */
  159. ecc_reg[0] = FL4ECCRESULT0(flctl);
  160. ecc_reg[1] = FL4ECCRESULT1(flctl);
  161. ecc_reg[2] = FL4ECCRESULT2(flctl);
  162. ecc_reg[3] = FL4ECCRESULT3(flctl);
  163. for (i = 0; i < 3; i++) {
  164. data = readl(ecc_reg[i]);
  165. if (data != INIT_FL4ECCRESULT_VAL && !checked[i]) {
  166. uint8_t org;
  167. int index;
  168. if (flctl->page_size)
  169. index = (512 * sector_number) +
  170. (data >> 16);
  171. else
  172. index = data >> 16;
  173. org = flctl->done_buff[index];
  174. flctl->done_buff[index] = org ^ (data & 0xFF);
  175. checked[i] = 1;
  176. }
  177. }
  178. writel(0, FL4ECCCR(flctl));
  179. }
  180. timeout_error(flctl, __func__);
  181. return 1; /* timeout */
  182. }
  183. static void wait_wecfifo_ready(struct sh_flctl *flctl)
  184. {
  185. uint32_t timeout = LOOP_TIMEOUT_MAX;
  186. uint32_t len;
  187. while (timeout--) {
  188. /* check FLECFIFO */
  189. len = (readl(FLDTCNTR(flctl)) >> 24) & 0xFF;
  190. if (len >= 4)
  191. return;
  192. udelay(1);
  193. }
  194. timeout_error(flctl, __func__);
  195. }
  196. static void read_datareg(struct sh_flctl *flctl, int offset)
  197. {
  198. unsigned long data;
  199. unsigned long *buf = (unsigned long *)&flctl->done_buff[offset];
  200. wait_completion(flctl);
  201. data = readl(FLDATAR(flctl));
  202. *buf = le32_to_cpu(data);
  203. }
  204. static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
  205. {
  206. int i, len_4align;
  207. unsigned long *buf = (unsigned long *)&flctl->done_buff[offset];
  208. void *fifo_addr = (void *)FLDTFIFO(flctl);
  209. len_4align = (rlen + 3) / 4;
  210. for (i = 0; i < len_4align; i++) {
  211. wait_rfifo_ready(flctl);
  212. buf[i] = readl(fifo_addr);
  213. buf[i] = be32_to_cpu(buf[i]);
  214. }
  215. }
  216. static int read_ecfiforeg(struct sh_flctl *flctl, uint8_t *buff, int sector)
  217. {
  218. int i;
  219. unsigned long *ecc_buf = (unsigned long *)buff;
  220. void *fifo_addr = (void *)FLECFIFO(flctl);
  221. for (i = 0; i < 4; i++) {
  222. if (wait_recfifo_ready(flctl , sector))
  223. return 1;
  224. ecc_buf[i] = readl(fifo_addr);
  225. ecc_buf[i] = be32_to_cpu(ecc_buf[i]);
  226. }
  227. return 0;
  228. }
  229. static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
  230. {
  231. int i, len_4align;
  232. unsigned long *data = (unsigned long *)&flctl->done_buff[offset];
  233. void *fifo_addr = (void *)FLDTFIFO(flctl);
  234. len_4align = (rlen + 3) / 4;
  235. for (i = 0; i < len_4align; i++) {
  236. wait_wfifo_ready(flctl);
  237. writel(cpu_to_be32(data[i]), fifo_addr);
  238. }
  239. }
  240. static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_val)
  241. {
  242. struct sh_flctl *flctl = mtd_to_flctl(mtd);
  243. uint32_t flcmncr_val = flctl->flcmncr_base & ~SEL_16BIT;
  244. uint32_t flcmdcr_val, addr_len_bytes = 0;
  245. /* Set SNAND bit if page size is 2048byte */
  246. if (flctl->page_size)
  247. flcmncr_val |= SNAND_E;
  248. else
  249. flcmncr_val &= ~SNAND_E;
  250. /* default FLCMDCR val */
  251. flcmdcr_val = DOCMD1_E | DOADR_E;
  252. /* Set for FLCMDCR */
  253. switch (cmd) {
  254. case NAND_CMD_ERASE1:
  255. addr_len_bytes = flctl->erase_ADRCNT;
  256. flcmdcr_val |= DOCMD2_E;
  257. break;
  258. case NAND_CMD_READ0:
  259. case NAND_CMD_READOOB:
  260. case NAND_CMD_RNDOUT:
  261. addr_len_bytes = flctl->rw_ADRCNT;
  262. flcmdcr_val |= CDSRC_E;
  263. if (flctl->chip.options & NAND_BUSWIDTH_16)
  264. flcmncr_val |= SEL_16BIT;
  265. break;
  266. case NAND_CMD_SEQIN:
  267. /* This case is that cmd is READ0 or READ1 or READ00 */
  268. flcmdcr_val &= ~DOADR_E; /* ONLY execute 1st cmd */
  269. break;
  270. case NAND_CMD_PAGEPROG:
  271. addr_len_bytes = flctl->rw_ADRCNT;
  272. flcmdcr_val |= DOCMD2_E | CDSRC_E | SELRW;
  273. if (flctl->chip.options & NAND_BUSWIDTH_16)
  274. flcmncr_val |= SEL_16BIT;
  275. break;
  276. case NAND_CMD_READID:
  277. flcmncr_val &= ~SNAND_E;
  278. flcmdcr_val |= CDSRC_E;
  279. addr_len_bytes = ADRCNT_1;
  280. break;
  281. case NAND_CMD_STATUS:
  282. case NAND_CMD_RESET:
  283. flcmncr_val &= ~SNAND_E;
  284. flcmdcr_val &= ~(DOADR_E | DOSR_E);
  285. break;
  286. default:
  287. break;
  288. }
  289. /* Set address bytes parameter */
  290. flcmdcr_val |= addr_len_bytes;
  291. /* Now actually write */
  292. writel(flcmncr_val, FLCMNCR(flctl));
  293. writel(flcmdcr_val, FLCMDCR(flctl));
  294. writel(flcmcdr_val, FLCMCDR(flctl));
  295. }
  296. static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
  297. uint8_t *buf, int page)
  298. {
  299. int i, eccsize = chip->ecc.size;
  300. int eccbytes = chip->ecc.bytes;
  301. int eccsteps = chip->ecc.steps;
  302. uint8_t *p = buf;
  303. struct sh_flctl *flctl = mtd_to_flctl(mtd);
  304. for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
  305. chip->read_buf(mtd, p, eccsize);
  306. for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
  307. if (flctl->hwecc_cant_correct[i])
  308. mtd->ecc_stats.failed++;
  309. else
  310. mtd->ecc_stats.corrected += 0;
  311. }
  312. return 0;
  313. }
  314. static void flctl_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
  315. const uint8_t *buf)
  316. {
  317. int i, eccsize = chip->ecc.size;
  318. int eccbytes = chip->ecc.bytes;
  319. int eccsteps = chip->ecc.steps;
  320. const uint8_t *p = buf;
  321. for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
  322. chip->write_buf(mtd, p, eccsize);
  323. }
  324. static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr)
  325. {
  326. struct sh_flctl *flctl = mtd_to_flctl(mtd);
  327. int sector, page_sectors;
  328. if (flctl->page_size)
  329. page_sectors = 4;
  330. else
  331. page_sectors = 1;
  332. writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE | _4ECCCORRECT,
  333. FLCMNCR(flctl));
  334. set_cmd_regs(mtd, NAND_CMD_READ0,
  335. (NAND_CMD_READSTART << 8) | NAND_CMD_READ0);
  336. for (sector = 0; sector < page_sectors; sector++) {
  337. int ret;
  338. empty_fifo(flctl);
  339. writel(readl(FLCMDCR(flctl)) | 1, FLCMDCR(flctl));
  340. writel(page_addr << 2 | sector, FLADR(flctl));
  341. start_translation(flctl);
  342. read_fiforeg(flctl, 512, 512 * sector);
  343. ret = read_ecfiforeg(flctl,
  344. &flctl->done_buff[mtd->writesize + 16 * sector],
  345. sector);
  346. if (ret)
  347. flctl->hwecc_cant_correct[sector] = 1;
  348. writel(0x0, FL4ECCCR(flctl));
  349. wait_completion(flctl);
  350. }
  351. writel(readl(FLCMNCR(flctl)) & ~(ACM_SACCES_MODE | _4ECCCORRECT),
  352. FLCMNCR(flctl));
  353. }
  354. static void execmd_read_oob(struct mtd_info *mtd, int page_addr)
  355. {
  356. struct sh_flctl *flctl = mtd_to_flctl(mtd);
  357. set_cmd_regs(mtd, NAND_CMD_READ0,
  358. (NAND_CMD_READSTART << 8) | NAND_CMD_READ0);
  359. empty_fifo(flctl);
  360. if (flctl->page_size) {
  361. int i;
  362. /* In case that the page size is 2k */
  363. for (i = 0; i < 16 * 3; i++)
  364. flctl->done_buff[i] = 0xFF;
  365. set_addr(mtd, 3 * 528 + 512, page_addr);
  366. writel(16, FLDTCNTR(flctl));
  367. start_translation(flctl);
  368. read_fiforeg(flctl, 16, 16 * 3);
  369. wait_completion(flctl);
  370. } else {
  371. /* In case that the page size is 512b */
  372. set_addr(mtd, 512, page_addr);
  373. writel(16, FLDTCNTR(flctl));
  374. start_translation(flctl);
  375. read_fiforeg(flctl, 16, 0);
  376. wait_completion(flctl);
  377. }
  378. }
  379. static void execmd_write_page_sector(struct mtd_info *mtd)
  380. {
  381. struct sh_flctl *flctl = mtd_to_flctl(mtd);
  382. int i, page_addr = flctl->seqin_page_addr;
  383. int sector, page_sectors;
  384. if (flctl->page_size)
  385. page_sectors = 4;
  386. else
  387. page_sectors = 1;
  388. writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE, FLCMNCR(flctl));
  389. set_cmd_regs(mtd, NAND_CMD_PAGEPROG,
  390. (NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN);
  391. for (sector = 0; sector < page_sectors; sector++) {
  392. empty_fifo(flctl);
  393. writel(readl(FLCMDCR(flctl)) | 1, FLCMDCR(flctl));
  394. writel(page_addr << 2 | sector, FLADR(flctl));
  395. start_translation(flctl);
  396. write_fiforeg(flctl, 512, 512 * sector);
  397. for (i = 0; i < 4; i++) {
  398. wait_wecfifo_ready(flctl); /* wait for write ready */
  399. writel(0xFFFFFFFF, FLECFIFO(flctl));
  400. }
  401. wait_completion(flctl);
  402. }
  403. writel(readl(FLCMNCR(flctl)) & ~ACM_SACCES_MODE, FLCMNCR(flctl));
  404. }
  405. static void execmd_write_oob(struct mtd_info *mtd)
  406. {
  407. struct sh_flctl *flctl = mtd_to_flctl(mtd);
  408. int page_addr = flctl->seqin_page_addr;
  409. int sector, page_sectors;
  410. if (flctl->page_size) {
  411. sector = 3;
  412. page_sectors = 4;
  413. } else {
  414. sector = 0;
  415. page_sectors = 1;
  416. }
  417. set_cmd_regs(mtd, NAND_CMD_PAGEPROG,
  418. (NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN);
  419. for (; sector < page_sectors; sector++) {
  420. empty_fifo(flctl);
  421. set_addr(mtd, sector * 528 + 512, page_addr);
  422. writel(16, FLDTCNTR(flctl)); /* set read size */
  423. start_translation(flctl);
  424. write_fiforeg(flctl, 16, 16 * sector);
  425. wait_completion(flctl);
  426. }
  427. }
  428. static void flctl_cmdfunc(struct mtd_info *mtd, unsigned int command,
  429. int column, int page_addr)
  430. {
  431. struct sh_flctl *flctl = mtd_to_flctl(mtd);
  432. uint32_t read_cmd = 0;
  433. pm_runtime_get_sync(&flctl->pdev->dev);
  434. flctl->read_bytes = 0;
  435. if (command != NAND_CMD_PAGEPROG)
  436. flctl->index = 0;
  437. switch (command) {
  438. case NAND_CMD_READ1:
  439. case NAND_CMD_READ0:
  440. if (flctl->hwecc) {
  441. /* read page with hwecc */
  442. execmd_read_page_sector(mtd, page_addr);
  443. break;
  444. }
  445. if (flctl->page_size)
  446. set_cmd_regs(mtd, command, (NAND_CMD_READSTART << 8)
  447. | command);
  448. else
  449. set_cmd_regs(mtd, command, command);
  450. set_addr(mtd, 0, page_addr);
  451. flctl->read_bytes = mtd->writesize + mtd->oobsize;
  452. if (flctl->chip.options & NAND_BUSWIDTH_16)
  453. column >>= 1;
  454. flctl->index += column;
  455. goto read_normal_exit;
  456. case NAND_CMD_READOOB:
  457. if (flctl->hwecc) {
  458. /* read page with hwecc */
  459. execmd_read_oob(mtd, page_addr);
  460. break;
  461. }
  462. if (flctl->page_size) {
  463. set_cmd_regs(mtd, command, (NAND_CMD_READSTART << 8)
  464. | NAND_CMD_READ0);
  465. set_addr(mtd, mtd->writesize, page_addr);
  466. } else {
  467. set_cmd_regs(mtd, command, command);
  468. set_addr(mtd, 0, page_addr);
  469. }
  470. flctl->read_bytes = mtd->oobsize;
  471. goto read_normal_exit;
  472. case NAND_CMD_RNDOUT:
  473. if (flctl->hwecc)
  474. break;
  475. if (flctl->page_size)
  476. set_cmd_regs(mtd, command, (NAND_CMD_RNDOUTSTART << 8)
  477. | command);
  478. else
  479. set_cmd_regs(mtd, command, command);
  480. set_addr(mtd, column, 0);
  481. flctl->read_bytes = mtd->writesize + mtd->oobsize - column;
  482. goto read_normal_exit;
  483. case NAND_CMD_READID:
  484. set_cmd_regs(mtd, command, command);
  485. /* READID is always performed using an 8-bit bus */
  486. if (flctl->chip.options & NAND_BUSWIDTH_16)
  487. column <<= 1;
  488. set_addr(mtd, column, 0);
  489. flctl->read_bytes = 8;
  490. writel(flctl->read_bytes, FLDTCNTR(flctl)); /* set read size */
  491. empty_fifo(flctl);
  492. start_translation(flctl);
  493. read_fiforeg(flctl, flctl->read_bytes, 0);
  494. wait_completion(flctl);
  495. break;
  496. case NAND_CMD_ERASE1:
  497. flctl->erase1_page_addr = page_addr;
  498. break;
  499. case NAND_CMD_ERASE2:
  500. set_cmd_regs(mtd, NAND_CMD_ERASE1,
  501. (command << 8) | NAND_CMD_ERASE1);
  502. set_addr(mtd, -1, flctl->erase1_page_addr);
  503. start_translation(flctl);
  504. wait_completion(flctl);
  505. break;
  506. case NAND_CMD_SEQIN:
  507. if (!flctl->page_size) {
  508. /* output read command */
  509. if (column >= mtd->writesize) {
  510. column -= mtd->writesize;
  511. read_cmd = NAND_CMD_READOOB;
  512. } else if (column < 256) {
  513. read_cmd = NAND_CMD_READ0;
  514. } else {
  515. column -= 256;
  516. read_cmd = NAND_CMD_READ1;
  517. }
  518. }
  519. flctl->seqin_column = column;
  520. flctl->seqin_page_addr = page_addr;
  521. flctl->seqin_read_cmd = read_cmd;
  522. break;
  523. case NAND_CMD_PAGEPROG:
  524. empty_fifo(flctl);
  525. if (!flctl->page_size) {
  526. set_cmd_regs(mtd, NAND_CMD_SEQIN,
  527. flctl->seqin_read_cmd);
  528. set_addr(mtd, -1, -1);
  529. writel(0, FLDTCNTR(flctl)); /* set 0 size */
  530. start_translation(flctl);
  531. wait_completion(flctl);
  532. }
  533. if (flctl->hwecc) {
  534. /* write page with hwecc */
  535. if (flctl->seqin_column == mtd->writesize)
  536. execmd_write_oob(mtd);
  537. else if (!flctl->seqin_column)
  538. execmd_write_page_sector(mtd);
  539. else
  540. printk(KERN_ERR "Invalid address !?\n");
  541. break;
  542. }
  543. set_cmd_regs(mtd, command, (command << 8) | NAND_CMD_SEQIN);
  544. set_addr(mtd, flctl->seqin_column, flctl->seqin_page_addr);
  545. writel(flctl->index, FLDTCNTR(flctl)); /* set write size */
  546. start_translation(flctl);
  547. write_fiforeg(flctl, flctl->index, 0);
  548. wait_completion(flctl);
  549. break;
  550. case NAND_CMD_STATUS:
  551. set_cmd_regs(mtd, command, command);
  552. set_addr(mtd, -1, -1);
  553. flctl->read_bytes = 1;
  554. writel(flctl->read_bytes, FLDTCNTR(flctl)); /* set read size */
  555. start_translation(flctl);
  556. read_datareg(flctl, 0); /* read and end */
  557. break;
  558. case NAND_CMD_RESET:
  559. set_cmd_regs(mtd, command, command);
  560. set_addr(mtd, -1, -1);
  561. writel(0, FLDTCNTR(flctl)); /* set 0 size */
  562. start_translation(flctl);
  563. wait_completion(flctl);
  564. break;
  565. default:
  566. break;
  567. }
  568. goto runtime_exit;
  569. read_normal_exit:
  570. writel(flctl->read_bytes, FLDTCNTR(flctl)); /* set read size */
  571. empty_fifo(flctl);
  572. start_translation(flctl);
  573. read_fiforeg(flctl, flctl->read_bytes, 0);
  574. wait_completion(flctl);
  575. runtime_exit:
  576. pm_runtime_put_sync(&flctl->pdev->dev);
  577. return;
  578. }
  579. static void flctl_select_chip(struct mtd_info *mtd, int chipnr)
  580. {
  581. struct sh_flctl *flctl = mtd_to_flctl(mtd);
  582. int ret;
  583. switch (chipnr) {
  584. case -1:
  585. flctl->flcmncr_base &= ~CE0_ENABLE;
  586. pm_runtime_get_sync(&flctl->pdev->dev);
  587. writel(flctl->flcmncr_base, FLCMNCR(flctl));
  588. if (flctl->qos_request) {
  589. dev_pm_qos_remove_request(&flctl->pm_qos);
  590. flctl->qos_request = 0;
  591. }
  592. pm_runtime_put_sync(&flctl->pdev->dev);
  593. break;
  594. case 0:
  595. flctl->flcmncr_base |= CE0_ENABLE;
  596. if (!flctl->qos_request) {
  597. ret = dev_pm_qos_add_request(&flctl->pdev->dev,
  598. &flctl->pm_qos,
  599. DEV_PM_QOS_LATENCY,
  600. 100);
  601. if (ret < 0)
  602. dev_err(&flctl->pdev->dev,
  603. "PM QoS request failed: %d\n", ret);
  604. flctl->qos_request = 1;
  605. }
  606. if (flctl->holden) {
  607. pm_runtime_get_sync(&flctl->pdev->dev);
  608. writel(HOLDEN, FLHOLDCR(flctl));
  609. pm_runtime_put_sync(&flctl->pdev->dev);
  610. }
  611. break;
  612. default:
  613. BUG();
  614. }
  615. }
  616. static void flctl_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
  617. {
  618. struct sh_flctl *flctl = mtd_to_flctl(mtd);
  619. int i, index = flctl->index;
  620. for (i = 0; i < len; i++)
  621. flctl->done_buff[index + i] = buf[i];
  622. flctl->index += len;
  623. }
  624. static uint8_t flctl_read_byte(struct mtd_info *mtd)
  625. {
  626. struct sh_flctl *flctl = mtd_to_flctl(mtd);
  627. int index = flctl->index;
  628. uint8_t data;
  629. data = flctl->done_buff[index];
  630. flctl->index++;
  631. return data;
  632. }
  633. static uint16_t flctl_read_word(struct mtd_info *mtd)
  634. {
  635. struct sh_flctl *flctl = mtd_to_flctl(mtd);
  636. int index = flctl->index;
  637. uint16_t data;
  638. uint16_t *buf = (uint16_t *)&flctl->done_buff[index];
  639. data = *buf;
  640. flctl->index += 2;
  641. return data;
  642. }
  643. static void flctl_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
  644. {
  645. int i;
  646. for (i = 0; i < len; i++)
  647. buf[i] = flctl_read_byte(mtd);
  648. }
  649. static int flctl_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
  650. {
  651. int i;
  652. for (i = 0; i < len; i++)
  653. if (buf[i] != flctl_read_byte(mtd))
  654. return -EFAULT;
  655. return 0;
  656. }
  657. static int flctl_chip_init_tail(struct mtd_info *mtd)
  658. {
  659. struct sh_flctl *flctl = mtd_to_flctl(mtd);
  660. struct nand_chip *chip = &flctl->chip;
  661. if (mtd->writesize == 512) {
  662. flctl->page_size = 0;
  663. if (chip->chipsize > (32 << 20)) {
  664. /* big than 32MB */
  665. flctl->rw_ADRCNT = ADRCNT_4;
  666. flctl->erase_ADRCNT = ADRCNT_3;
  667. } else if (chip->chipsize > (2 << 16)) {
  668. /* big than 128KB */
  669. flctl->rw_ADRCNT = ADRCNT_3;
  670. flctl->erase_ADRCNT = ADRCNT_2;
  671. } else {
  672. flctl->rw_ADRCNT = ADRCNT_2;
  673. flctl->erase_ADRCNT = ADRCNT_1;
  674. }
  675. } else {
  676. flctl->page_size = 1;
  677. if (chip->chipsize > (128 << 20)) {
  678. /* big than 128MB */
  679. flctl->rw_ADRCNT = ADRCNT2_E;
  680. flctl->erase_ADRCNT = ADRCNT_3;
  681. } else if (chip->chipsize > (8 << 16)) {
  682. /* big than 512KB */
  683. flctl->rw_ADRCNT = ADRCNT_4;
  684. flctl->erase_ADRCNT = ADRCNT_2;
  685. } else {
  686. flctl->rw_ADRCNT = ADRCNT_3;
  687. flctl->erase_ADRCNT = ADRCNT_1;
  688. }
  689. }
  690. if (flctl->hwecc) {
  691. if (mtd->writesize == 512) {
  692. chip->ecc.layout = &flctl_4secc_oob_16;
  693. chip->badblock_pattern = &flctl_4secc_smallpage;
  694. } else {
  695. chip->ecc.layout = &flctl_4secc_oob_64;
  696. chip->badblock_pattern = &flctl_4secc_largepage;
  697. }
  698. chip->ecc.size = 512;
  699. chip->ecc.bytes = 10;
  700. chip->ecc.strength = 4;
  701. chip->ecc.read_page = flctl_read_page_hwecc;
  702. chip->ecc.write_page = flctl_write_page_hwecc;
  703. chip->ecc.mode = NAND_ECC_HW;
  704. /* 4 symbols ECC enabled */
  705. flctl->flcmncr_base |= _4ECCEN | ECCPOS2 | ECCPOS_02;
  706. } else {
  707. chip->ecc.mode = NAND_ECC_SOFT;
  708. }
  709. return 0;
  710. }
  711. static int __devinit flctl_probe(struct platform_device *pdev)
  712. {
  713. struct resource *res;
  714. struct sh_flctl *flctl;
  715. struct mtd_info *flctl_mtd;
  716. struct nand_chip *nand;
  717. struct sh_flctl_platform_data *pdata;
  718. int ret = -ENXIO;
  719. pdata = pdev->dev.platform_data;
  720. if (pdata == NULL) {
  721. dev_err(&pdev->dev, "no platform data defined\n");
  722. return -EINVAL;
  723. }
  724. flctl = kzalloc(sizeof(struct sh_flctl), GFP_KERNEL);
  725. if (!flctl) {
  726. dev_err(&pdev->dev, "failed to allocate driver data\n");
  727. return -ENOMEM;
  728. }
  729. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  730. if (!res) {
  731. dev_err(&pdev->dev, "failed to get I/O memory\n");
  732. goto err_iomap;
  733. }
  734. flctl->reg = ioremap(res->start, resource_size(res));
  735. if (flctl->reg == NULL) {
  736. dev_err(&pdev->dev, "failed to remap I/O memory\n");
  737. goto err_iomap;
  738. }
  739. platform_set_drvdata(pdev, flctl);
  740. flctl_mtd = &flctl->mtd;
  741. nand = &flctl->chip;
  742. flctl_mtd->priv = nand;
  743. flctl->pdev = pdev;
  744. flctl->flcmncr_base = pdata->flcmncr_val;
  745. flctl->hwecc = pdata->has_hwecc;
  746. flctl->holden = pdata->use_holden;
  747. nand->options = NAND_NO_AUTOINCR;
  748. /* Set address of hardware control function */
  749. /* 20 us command delay time */
  750. nand->chip_delay = 20;
  751. nand->read_byte = flctl_read_byte;
  752. nand->write_buf = flctl_write_buf;
  753. nand->read_buf = flctl_read_buf;
  754. nand->verify_buf = flctl_verify_buf;
  755. nand->select_chip = flctl_select_chip;
  756. nand->cmdfunc = flctl_cmdfunc;
  757. if (pdata->flcmncr_val & SEL_16BIT) {
  758. nand->options |= NAND_BUSWIDTH_16;
  759. nand->read_word = flctl_read_word;
  760. }
  761. pm_runtime_enable(&pdev->dev);
  762. pm_runtime_resume(&pdev->dev);
  763. ret = nand_scan_ident(flctl_mtd, 1, NULL);
  764. if (ret)
  765. goto err_chip;
  766. ret = flctl_chip_init_tail(flctl_mtd);
  767. if (ret)
  768. goto err_chip;
  769. ret = nand_scan_tail(flctl_mtd);
  770. if (ret)
  771. goto err_chip;
  772. mtd_device_register(flctl_mtd, pdata->parts, pdata->nr_parts);
  773. return 0;
  774. err_chip:
  775. pm_runtime_disable(&pdev->dev);
  776. err_iomap:
  777. kfree(flctl);
  778. return ret;
  779. }
  780. static int __devexit flctl_remove(struct platform_device *pdev)
  781. {
  782. struct sh_flctl *flctl = platform_get_drvdata(pdev);
  783. nand_release(&flctl->mtd);
  784. pm_runtime_disable(&pdev->dev);
  785. kfree(flctl);
  786. return 0;
  787. }
  788. static struct platform_driver flctl_driver = {
  789. .remove = flctl_remove,
  790. .driver = {
  791. .name = "sh_flctl",
  792. .owner = THIS_MODULE,
  793. },
  794. };
  795. static int __init flctl_nand_init(void)
  796. {
  797. return platform_driver_probe(&flctl_driver, flctl_probe);
  798. }
  799. static void __exit flctl_nand_cleanup(void)
  800. {
  801. platform_driver_unregister(&flctl_driver);
  802. }
  803. module_init(flctl_nand_init);
  804. module_exit(flctl_nand_cleanup);
  805. MODULE_LICENSE("GPL");
  806. MODULE_AUTHOR("Yoshihiro Shimoda");
  807. MODULE_DESCRIPTION("SuperH FLCTL driver");
  808. MODULE_ALIAS("platform:sh_flctl");