samsung.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. /*
  2. * S5PC100 OneNAND driver at U-Boot
  3. *
  4. * Copyright (C) 2008-2009 Samsung Electronics
  5. * Kyungmin Park <kyungmin.park@samsung.com>
  6. *
  7. * Implementation:
  8. * Emulate the pseudo BufferRAM
  9. *
  10. * SPDX-License-Identifier: GPL-2.0+
  11. */
  12. #include <common.h>
  13. #include <malloc.h>
  14. #include <linux/compat.h>
  15. #include <linux/mtd/mtd.h>
  16. #include <linux/mtd/onenand.h>
  17. #include <linux/mtd/flashchip.h>
  18. #include <linux/mtd/samsung_onenand.h>
  19. #include <asm/io.h>
  20. #include <linux/errno.h>
  21. #define ONENAND_ERASE_STATUS 0x00
  22. #define ONENAND_MULTI_ERASE_SET 0x01
  23. #define ONENAND_ERASE_START 0x03
  24. #define ONENAND_UNLOCK_START 0x08
  25. #define ONENAND_UNLOCK_END 0x09
  26. #define ONENAND_LOCK_START 0x0A
  27. #define ONENAND_LOCK_END 0x0B
  28. #define ONENAND_LOCK_TIGHT_START 0x0C
  29. #define ONENAND_LOCK_TIGHT_END 0x0D
  30. #define ONENAND_UNLOCK_ALL 0x0E
  31. #define ONENAND_OTP_ACCESS 0x12
  32. #define ONENAND_SPARE_ACCESS_ONLY 0x13
  33. #define ONENAND_MAIN_ACCESS_ONLY 0x14
  34. #define ONENAND_ERASE_VERIFY 0x15
  35. #define ONENAND_MAIN_SPARE_ACCESS 0x16
  36. #define ONENAND_PIPELINE_READ 0x4000
  37. #if defined(CONFIG_S5P)
  38. #define MAP_00 (0x0 << 26)
  39. #define MAP_01 (0x1 << 26)
  40. #define MAP_10 (0x2 << 26)
  41. #define MAP_11 (0x3 << 26)
  42. #endif
  43. /* read/write of XIP buffer */
  44. #define CMD_MAP_00(mem_addr) (MAP_00 | ((mem_addr) << 1))
  45. /* read/write to the memory device */
  46. #define CMD_MAP_01(mem_addr) (MAP_01 | (mem_addr))
  47. /* control special functions of the memory device */
  48. #define CMD_MAP_10(mem_addr) (MAP_10 | (mem_addr))
  49. /* direct interface(direct access) with the memory device */
  50. #define CMD_MAP_11(mem_addr) (MAP_11 | ((mem_addr) << 2))
  51. struct s3c_onenand {
  52. struct mtd_info *mtd;
  53. void __iomem *base;
  54. void __iomem *ahb_addr;
  55. int bootram_command;
  56. void __iomem *page_buf;
  57. void __iomem *oob_buf;
  58. unsigned int (*mem_addr)(int fba, int fpa, int fsa);
  59. struct samsung_onenand *reg;
  60. };
  61. static struct s3c_onenand *onenand;
  62. static int s3c_read_cmd(unsigned int cmd)
  63. {
  64. return readl(onenand->ahb_addr + cmd);
  65. }
  66. static void s3c_write_cmd(int value, unsigned int cmd)
  67. {
  68. writel(value, onenand->ahb_addr + cmd);
  69. }
  70. /*
  71. * MEM_ADDR
  72. *
  73. * fba: flash block address
  74. * fpa: flash page address
  75. * fsa: flash sector address
  76. *
  77. * return the buffer address on the memory device
  78. * It will be combined with CMD_MAP_XX
  79. */
  80. #if defined(CONFIG_S5P)
  81. static unsigned int s3c_mem_addr(int fba, int fpa, int fsa)
  82. {
  83. return (fba << 13) | (fpa << 7) | (fsa << 5);
  84. }
  85. #endif
  86. static void s3c_onenand_reset(void)
  87. {
  88. unsigned long timeout = 0x10000;
  89. int stat;
  90. writel(ONENAND_MEM_RESET_COLD, &onenand->reg->mem_reset);
  91. while (timeout--) {
  92. stat = readl(&onenand->reg->int_err_stat);
  93. if (stat & RST_CMP)
  94. break;
  95. }
  96. stat = readl(&onenand->reg->int_err_stat);
  97. writel(stat, &onenand->reg->int_err_ack);
  98. /* Clear interrupt */
  99. writel(0x0, &onenand->reg->int_err_ack);
  100. /* Clear the ECC status */
  101. writel(0x0, &onenand->reg->ecc_err_stat);
  102. }
  103. static unsigned short s3c_onenand_readw(void __iomem *addr)
  104. {
  105. struct onenand_chip *this = onenand->mtd->priv;
  106. int reg = addr - this->base;
  107. int word_addr = reg >> 1;
  108. int value;
  109. /* It's used for probing time */
  110. switch (reg) {
  111. case ONENAND_REG_MANUFACTURER_ID:
  112. return readl(&onenand->reg->manufact_id);
  113. case ONENAND_REG_DEVICE_ID:
  114. return readl(&onenand->reg->device_id);
  115. case ONENAND_REG_VERSION_ID:
  116. return readl(&onenand->reg->flash_ver_id);
  117. case ONENAND_REG_DATA_BUFFER_SIZE:
  118. return readl(&onenand->reg->data_buf_size);
  119. case ONENAND_REG_TECHNOLOGY:
  120. return readl(&onenand->reg->tech);
  121. case ONENAND_REG_SYS_CFG1:
  122. return readl(&onenand->reg->mem_cfg);
  123. /* Used at unlock all status */
  124. case ONENAND_REG_CTRL_STATUS:
  125. return 0;
  126. case ONENAND_REG_WP_STATUS:
  127. return ONENAND_WP_US;
  128. default:
  129. break;
  130. }
  131. /* BootRAM access control */
  132. if (reg < ONENAND_DATARAM && onenand->bootram_command) {
  133. if (word_addr == 0)
  134. return readl(&onenand->reg->manufact_id);
  135. if (word_addr == 1)
  136. return readl(&onenand->reg->device_id);
  137. if (word_addr == 2)
  138. return readl(&onenand->reg->flash_ver_id);
  139. }
  140. value = s3c_read_cmd(CMD_MAP_11(word_addr)) & 0xffff;
  141. printk(KERN_INFO "s3c_onenand_readw: Illegal access"
  142. " at reg 0x%x, value 0x%x\n", word_addr, value);
  143. return value;
  144. }
  145. static void s3c_onenand_writew(unsigned short value, void __iomem *addr)
  146. {
  147. struct onenand_chip *this = onenand->mtd->priv;
  148. int reg = addr - this->base;
  149. int word_addr = reg >> 1;
  150. /* It's used for probing time */
  151. switch (reg) {
  152. case ONENAND_REG_SYS_CFG1:
  153. writel(value, &onenand->reg->mem_cfg);
  154. return;
  155. case ONENAND_REG_START_ADDRESS1:
  156. case ONENAND_REG_START_ADDRESS2:
  157. return;
  158. /* Lock/lock-tight/unlock/unlock_all */
  159. case ONENAND_REG_START_BLOCK_ADDRESS:
  160. return;
  161. default:
  162. break;
  163. }
  164. /* BootRAM access control */
  165. if (reg < ONENAND_DATARAM) {
  166. if (value == ONENAND_CMD_READID) {
  167. onenand->bootram_command = 1;
  168. return;
  169. }
  170. if (value == ONENAND_CMD_RESET) {
  171. writel(ONENAND_MEM_RESET_COLD,
  172. &onenand->reg->mem_reset);
  173. onenand->bootram_command = 0;
  174. return;
  175. }
  176. }
  177. printk(KERN_INFO "s3c_onenand_writew: Illegal access"
  178. " at reg 0x%x, value 0x%x\n", word_addr, value);
  179. s3c_write_cmd(value, CMD_MAP_11(word_addr));
  180. }
  181. static int s3c_onenand_wait(struct mtd_info *mtd, int state)
  182. {
  183. unsigned int flags = INT_ACT;
  184. unsigned int stat, ecc;
  185. unsigned long timeout = 0x100000;
  186. switch (state) {
  187. case FL_READING:
  188. flags |= BLK_RW_CMP | LOAD_CMP;
  189. break;
  190. case FL_WRITING:
  191. flags |= BLK_RW_CMP | PGM_CMP;
  192. break;
  193. case FL_ERASING:
  194. flags |= BLK_RW_CMP | ERS_CMP;
  195. break;
  196. case FL_LOCKING:
  197. flags |= BLK_RW_CMP;
  198. break;
  199. default:
  200. break;
  201. }
  202. while (timeout--) {
  203. stat = readl(&onenand->reg->int_err_stat);
  204. if (stat & flags)
  205. break;
  206. }
  207. /* To get correct interrupt status in timeout case */
  208. stat = readl(&onenand->reg->int_err_stat);
  209. writel(stat, &onenand->reg->int_err_ack);
  210. /*
  211. * In the Spec. it checks the controller status first
  212. * However if you get the correct information in case of
  213. * power off recovery (POR) test, it should read ECC status first
  214. */
  215. if (stat & LOAD_CMP) {
  216. ecc = readl(&onenand->reg->ecc_err_stat);
  217. if (ecc & ONENAND_ECC_4BIT_UNCORRECTABLE) {
  218. printk(KERN_INFO "%s: ECC error = 0x%04x\n",
  219. __func__, ecc);
  220. mtd->ecc_stats.failed++;
  221. return -EBADMSG;
  222. }
  223. }
  224. if (stat & (LOCKED_BLK | ERS_FAIL | PGM_FAIL | LD_FAIL_ECC_ERR)) {
  225. printk(KERN_INFO "%s: controller error = 0x%04x\n",
  226. __func__, stat);
  227. if (stat & LOCKED_BLK)
  228. printk(KERN_INFO "%s: it's locked error = 0x%04x\n",
  229. __func__, stat);
  230. return -EIO;
  231. }
  232. return 0;
  233. }
  234. static int s3c_onenand_command(struct mtd_info *mtd, int cmd,
  235. loff_t addr, size_t len)
  236. {
  237. struct onenand_chip *this = mtd->priv;
  238. unsigned int *m, *s;
  239. int fba, fpa, fsa = 0;
  240. unsigned int mem_addr;
  241. int i, mcount, scount;
  242. int index;
  243. fba = (int) (addr >> this->erase_shift);
  244. fpa = (int) (addr >> this->page_shift);
  245. fpa &= this->page_mask;
  246. mem_addr = onenand->mem_addr(fba, fpa, fsa);
  247. switch (cmd) {
  248. case ONENAND_CMD_READ:
  249. case ONENAND_CMD_READOOB:
  250. case ONENAND_CMD_BUFFERRAM:
  251. ONENAND_SET_NEXT_BUFFERRAM(this);
  252. default:
  253. break;
  254. }
  255. index = ONENAND_CURRENT_BUFFERRAM(this);
  256. /*
  257. * Emulate Two BufferRAMs and access with 4 bytes pointer
  258. */
  259. m = (unsigned int *) onenand->page_buf;
  260. s = (unsigned int *) onenand->oob_buf;
  261. if (index) {
  262. m += (this->writesize >> 2);
  263. s += (mtd->oobsize >> 2);
  264. }
  265. mcount = mtd->writesize >> 2;
  266. scount = mtd->oobsize >> 2;
  267. switch (cmd) {
  268. case ONENAND_CMD_READ:
  269. /* Main */
  270. for (i = 0; i < mcount; i++)
  271. *m++ = s3c_read_cmd(CMD_MAP_01(mem_addr));
  272. return 0;
  273. case ONENAND_CMD_READOOB:
  274. writel(TSRF, &onenand->reg->trans_spare);
  275. /* Main */
  276. for (i = 0; i < mcount; i++)
  277. *m++ = s3c_read_cmd(CMD_MAP_01(mem_addr));
  278. /* Spare */
  279. for (i = 0; i < scount; i++)
  280. *s++ = s3c_read_cmd(CMD_MAP_01(mem_addr));
  281. writel(0, &onenand->reg->trans_spare);
  282. return 0;
  283. case ONENAND_CMD_PROG:
  284. /* Main */
  285. for (i = 0; i < mcount; i++)
  286. s3c_write_cmd(*m++, CMD_MAP_01(mem_addr));
  287. return 0;
  288. case ONENAND_CMD_PROGOOB:
  289. writel(TSRF, &onenand->reg->trans_spare);
  290. /* Main - dummy write */
  291. for (i = 0; i < mcount; i++)
  292. s3c_write_cmd(0xffffffff, CMD_MAP_01(mem_addr));
  293. /* Spare */
  294. for (i = 0; i < scount; i++)
  295. s3c_write_cmd(*s++, CMD_MAP_01(mem_addr));
  296. writel(0, &onenand->reg->trans_spare);
  297. return 0;
  298. case ONENAND_CMD_UNLOCK_ALL:
  299. s3c_write_cmd(ONENAND_UNLOCK_ALL, CMD_MAP_10(mem_addr));
  300. return 0;
  301. case ONENAND_CMD_ERASE:
  302. s3c_write_cmd(ONENAND_ERASE_START, CMD_MAP_10(mem_addr));
  303. return 0;
  304. case ONENAND_CMD_MULTIBLOCK_ERASE:
  305. s3c_write_cmd(ONENAND_MULTI_ERASE_SET, CMD_MAP_10(mem_addr));
  306. return 0;
  307. case ONENAND_CMD_ERASE_VERIFY:
  308. s3c_write_cmd(ONENAND_ERASE_VERIFY, CMD_MAP_10(mem_addr));
  309. return 0;
  310. default:
  311. break;
  312. }
  313. return 0;
  314. }
  315. static unsigned char *s3c_get_bufferram(struct mtd_info *mtd, int area)
  316. {
  317. struct onenand_chip *this = mtd->priv;
  318. int index = ONENAND_CURRENT_BUFFERRAM(this);
  319. unsigned char *p;
  320. if (area == ONENAND_DATARAM) {
  321. p = (unsigned char *) onenand->page_buf;
  322. if (index == 1)
  323. p += this->writesize;
  324. } else {
  325. p = (unsigned char *) onenand->oob_buf;
  326. if (index == 1)
  327. p += mtd->oobsize;
  328. }
  329. return p;
  330. }
  331. static int onenand_read_bufferram(struct mtd_info *mtd, loff_t addr, int area,
  332. unsigned char *buffer, int offset,
  333. size_t count)
  334. {
  335. unsigned char *p;
  336. p = s3c_get_bufferram(mtd, area);
  337. memcpy(buffer, p + offset, count);
  338. return 0;
  339. }
  340. static int onenand_write_bufferram(struct mtd_info *mtd, loff_t addr, int area,
  341. const unsigned char *buffer, int offset,
  342. size_t count)
  343. {
  344. unsigned char *p;
  345. p = s3c_get_bufferram(mtd, area);
  346. memcpy(p + offset, buffer, count);
  347. return 0;
  348. }
  349. static int s3c_onenand_bbt_wait(struct mtd_info *mtd, int state)
  350. {
  351. struct samsung_onenand *reg = (struct samsung_onenand *)onenand->base;
  352. unsigned int flags = INT_ACT | LOAD_CMP;
  353. unsigned int stat;
  354. unsigned long timeout = 0x10000;
  355. while (timeout--) {
  356. stat = readl(&reg->int_err_stat);
  357. if (stat & flags)
  358. break;
  359. }
  360. /* To get correct interrupt status in timeout case */
  361. stat = readl(&onenand->reg->int_err_stat);
  362. writel(stat, &onenand->reg->int_err_ack);
  363. if (stat & LD_FAIL_ECC_ERR) {
  364. s3c_onenand_reset();
  365. return ONENAND_BBT_READ_ERROR;
  366. }
  367. if (stat & LOAD_CMP) {
  368. int ecc = readl(&onenand->reg->ecc_err_stat);
  369. if (ecc & ONENAND_ECC_4BIT_UNCORRECTABLE) {
  370. s3c_onenand_reset();
  371. return ONENAND_BBT_READ_ERROR;
  372. }
  373. }
  374. return 0;
  375. }
  376. static void s3c_onenand_check_lock_status(struct mtd_info *mtd)
  377. {
  378. struct onenand_chip *this = mtd->priv;
  379. unsigned int block, end;
  380. end = this->chipsize >> this->erase_shift;
  381. for (block = 0; block < end; block++) {
  382. s3c_read_cmd(CMD_MAP_01(onenand->mem_addr(block, 0, 0)));
  383. if (readl(&onenand->reg->int_err_stat) & LOCKED_BLK) {
  384. printf("block %d is write-protected!\n", block);
  385. writel(LOCKED_BLK, &onenand->reg->int_err_ack);
  386. }
  387. }
  388. }
  389. static void s3c_onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs,
  390. size_t len, int cmd)
  391. {
  392. struct onenand_chip *this = mtd->priv;
  393. int start, end, start_mem_addr, end_mem_addr;
  394. start = ofs >> this->erase_shift;
  395. start_mem_addr = onenand->mem_addr(start, 0, 0);
  396. end = start + (len >> this->erase_shift) - 1;
  397. end_mem_addr = onenand->mem_addr(end, 0, 0);
  398. if (cmd == ONENAND_CMD_LOCK) {
  399. s3c_write_cmd(ONENAND_LOCK_START, CMD_MAP_10(start_mem_addr));
  400. s3c_write_cmd(ONENAND_LOCK_END, CMD_MAP_10(end_mem_addr));
  401. } else {
  402. s3c_write_cmd(ONENAND_UNLOCK_START, CMD_MAP_10(start_mem_addr));
  403. s3c_write_cmd(ONENAND_UNLOCK_END, CMD_MAP_10(end_mem_addr));
  404. }
  405. this->wait(mtd, FL_LOCKING);
  406. }
  407. static void s3c_onenand_unlock_all(struct mtd_info *mtd)
  408. {
  409. struct onenand_chip *this = mtd->priv;
  410. loff_t ofs = 0;
  411. size_t len = this->chipsize;
  412. /* FIXME workaround */
  413. this->subpagesize = mtd->writesize;
  414. mtd->subpage_sft = 0;
  415. if (this->options & ONENAND_HAS_UNLOCK_ALL) {
  416. /* Write unlock command */
  417. this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);
  418. /* No need to check return value */
  419. this->wait(mtd, FL_LOCKING);
  420. /* Workaround for all block unlock in DDP */
  421. if (!ONENAND_IS_DDP(this)) {
  422. s3c_onenand_check_lock_status(mtd);
  423. return;
  424. }
  425. /* All blocks on another chip */
  426. ofs = this->chipsize >> 1;
  427. len = this->chipsize >> 1;
  428. }
  429. s3c_onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
  430. s3c_onenand_check_lock_status(mtd);
  431. }
  432. int s5pc110_chip_probe(struct mtd_info *mtd)
  433. {
  434. return 0;
  435. }
  436. int s5pc210_chip_probe(struct mtd_info *mtd)
  437. {
  438. return 0;
  439. }
  440. void s3c_onenand_init(struct mtd_info *mtd)
  441. {
  442. struct onenand_chip *this = mtd->priv;
  443. u32 size = (4 << 10); /* 4 KiB */
  444. onenand = malloc(sizeof(struct s3c_onenand));
  445. if (!onenand)
  446. return;
  447. onenand->page_buf = malloc(size * sizeof(char));
  448. if (!onenand->page_buf)
  449. return;
  450. memset(onenand->page_buf, 0xff, size);
  451. onenand->oob_buf = malloc(128 * sizeof(char));
  452. if (!onenand->oob_buf)
  453. return;
  454. memset(onenand->oob_buf, 0xff, 128);
  455. onenand->mtd = mtd;
  456. #if defined(CONFIG_S5P)
  457. onenand->base = (void *)0xE7100000;
  458. onenand->ahb_addr = (void *)0xB0000000;
  459. #endif
  460. onenand->mem_addr = s3c_mem_addr;
  461. onenand->reg = (struct samsung_onenand *)onenand->base;
  462. this->read_word = s3c_onenand_readw;
  463. this->write_word = s3c_onenand_writew;
  464. this->wait = s3c_onenand_wait;
  465. this->bbt_wait = s3c_onenand_bbt_wait;
  466. this->unlock_all = s3c_onenand_unlock_all;
  467. this->command = s3c_onenand_command;
  468. this->read_bufferram = onenand_read_bufferram;
  469. this->write_bufferram = onenand_write_bufferram;
  470. this->options |= ONENAND_RUNTIME_BADBLOCK_CHECK;
  471. }