denali_spl.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2014 Panasonic Corporation
  4. * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
  5. */
  6. #include <common.h>
  7. #include <asm/io.h>
  8. #include <asm/unaligned.h>
  9. #include <linux/mtd/rawnand.h>
  10. #include "denali.h"
  11. #define DENALI_MAP01 (1 << 26) /* read/write pages in PIO */
  12. #define DENALI_MAP10 (2 << 26) /* high-level control plane */
  13. #define INDEX_CTRL_REG 0x0
  14. #define INDEX_DATA_REG 0x10
  15. #define SPARE_ACCESS 0x41
  16. #define MAIN_ACCESS 0x42
  17. #define PIPELINE_ACCESS 0x2000
  18. #define BANK(x) ((x) << 24)
  19. static void __iomem *denali_flash_mem =
  20. (void __iomem *)CONFIG_SYS_NAND_DATA_BASE;
  21. static void __iomem *denali_flash_reg =
  22. (void __iomem *)CONFIG_SYS_NAND_REGS_BASE;
  23. static const int flash_bank;
  24. static int page_size, oob_size, pages_per_block;
  25. static void index_addr(uint32_t address, uint32_t data)
  26. {
  27. writel(address, denali_flash_mem + INDEX_CTRL_REG);
  28. writel(data, denali_flash_mem + INDEX_DATA_REG);
  29. }
  30. static int wait_for_irq(uint32_t irq_mask)
  31. {
  32. unsigned long timeout = 1000000;
  33. uint32_t intr_status;
  34. do {
  35. intr_status = readl(denali_flash_reg + INTR_STATUS(flash_bank));
  36. if (intr_status & INTR__ECC_UNCOR_ERR) {
  37. debug("Uncorrected ECC detected\n");
  38. return -EBADMSG;
  39. }
  40. if (intr_status & irq_mask)
  41. break;
  42. udelay(1);
  43. timeout--;
  44. } while (timeout);
  45. if (!timeout) {
  46. debug("Timeout with interrupt status %08x\n", intr_status);
  47. return -EIO;
  48. }
  49. return 0;
  50. }
  51. static void read_data_from_flash_mem(uint8_t *buf, int len)
  52. {
  53. int i;
  54. uint32_t *buf32;
  55. /* transfer the data from the flash */
  56. buf32 = (uint32_t *)buf;
  57. /*
  58. * Let's take care of unaligned access although it rarely happens.
  59. * Avoid put_unaligned() for the normal use cases since it leads to
  60. * a bit performance regression.
  61. */
  62. if ((unsigned long)buf32 % 4) {
  63. for (i = 0; i < len / 4; i++)
  64. put_unaligned(readl(denali_flash_mem + INDEX_DATA_REG),
  65. buf32++);
  66. } else {
  67. for (i = 0; i < len / 4; i++)
  68. *buf32++ = readl(denali_flash_mem + INDEX_DATA_REG);
  69. }
  70. if (len % 4) {
  71. u32 tmp;
  72. tmp = cpu_to_le32(readl(denali_flash_mem + INDEX_DATA_REG));
  73. buf = (uint8_t *)buf32;
  74. for (i = 0; i < len % 4; i++) {
  75. *buf++ = tmp;
  76. tmp >>= 8;
  77. }
  78. }
  79. }
  80. int denali_send_pipeline_cmd(int page, int ecc_en, int access_type)
  81. {
  82. uint32_t addr, cmd;
  83. static uint32_t page_count = 1;
  84. writel(ecc_en, denali_flash_reg + ECC_ENABLE);
  85. /* clear all bits of intr_status. */
  86. writel(0xffff, denali_flash_reg + INTR_STATUS(flash_bank));
  87. addr = BANK(flash_bank) | page;
  88. /* setup the acccess type */
  89. cmd = DENALI_MAP10 | addr;
  90. index_addr(cmd, access_type);
  91. /* setup the pipeline command */
  92. index_addr(cmd, PIPELINE_ACCESS | page_count);
  93. cmd = DENALI_MAP01 | addr;
  94. writel(cmd, denali_flash_mem + INDEX_CTRL_REG);
  95. return wait_for_irq(INTR__LOAD_COMP);
  96. }
  97. static int nand_read_oob(void *buf, int page)
  98. {
  99. int ret;
  100. ret = denali_send_pipeline_cmd(page, 0, SPARE_ACCESS);
  101. if (ret < 0)
  102. return ret;
  103. read_data_from_flash_mem(buf, oob_size);
  104. return 0;
  105. }
  106. static int nand_read_page(void *buf, int page)
  107. {
  108. int ret;
  109. ret = denali_send_pipeline_cmd(page, 1, MAIN_ACCESS);
  110. if (ret < 0)
  111. return ret;
  112. read_data_from_flash_mem(buf, page_size);
  113. return 0;
  114. }
  115. static int nand_block_isbad(void *buf, int block)
  116. {
  117. int ret;
  118. ret = nand_read_oob(buf, block * pages_per_block);
  119. if (ret < 0)
  120. return ret;
  121. return *((uint8_t *)buf + CONFIG_SYS_NAND_BAD_BLOCK_POS) != 0xff;
  122. }
  123. /* nand_init() - initialize data to make nand usable by SPL */
  124. void nand_init(void)
  125. {
  126. /* access to main area */
  127. writel(0, denali_flash_reg + TRANSFER_SPARE_REG);
  128. /*
  129. * These registers are expected to be already set by the hardware
  130. * or earlier boot code. So we read these values out.
  131. */
  132. page_size = readl(denali_flash_reg + DEVICE_MAIN_AREA_SIZE);
  133. oob_size = readl(denali_flash_reg + DEVICE_SPARE_AREA_SIZE);
  134. pages_per_block = readl(denali_flash_reg + PAGES_PER_BLOCK);
  135. }
  136. int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
  137. {
  138. int block, page, column, readlen;
  139. int ret;
  140. int force_bad_block_check = 1;
  141. page = offs / page_size;
  142. column = offs % page_size;
  143. block = page / pages_per_block;
  144. page = page % pages_per_block;
  145. while (size) {
  146. if (force_bad_block_check || page == 0) {
  147. ret = nand_block_isbad(dst, block);
  148. if (ret < 0)
  149. return ret;
  150. if (ret) {
  151. block++;
  152. continue;
  153. }
  154. }
  155. force_bad_block_check = 0;
  156. ret = nand_read_page(dst, block * pages_per_block + page);
  157. if (ret < 0)
  158. return ret;
  159. readlen = min(page_size - column, (int)size);
  160. if (unlikely(column)) {
  161. /* Partial page read */
  162. memmove(dst, dst + column, readlen);
  163. column = 0;
  164. }
  165. size -= readlen;
  166. dst += readlen;
  167. page++;
  168. if (page == pages_per_block) {
  169. block++;
  170. page = 0;
  171. }
  172. }
  173. return 0;
  174. }
  175. void nand_deselect(void) {}