spimem.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  1. /*
  2. * Copyright (c) 2017 Actions Semiconductor Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file
  8. * @brief common code for SPI Flash (NOR & NAND & PSRAM)
  9. */
  10. #include "spi_internal.h"
  11. #include "spimem.h"
  12. #define SPIMEM_CMD_READ_CHIPID 0x9f /* JEDEC ID */
  13. #define SPIMEM_CMD_FAST_READ 0x0b /* fast read */
  14. #define SPIMEM_CMD_FAST_READ_X2 0x3b /* data x2 */
  15. #define SPIMEM_CMD_FAST_READ_X4 0x6b /* data x4 */
  16. #define SPIMEM_CMD_FAST_READ_X2IO 0xbb /* addr & data x2 */
  17. #define SPIMEM_CMD_FAST_READ_X4IO 0xeb /* addr & data x4 */
  18. #define SPIMEM_CMD_ENABLE_WRITE 0x06 /* enable write */
  19. #define SPIMEM_CMD_DISABLE_WRITE 0x04 /* disable write */
  20. #define SPIMEM_CMD_WRITE_PAGE 0x02 /* write one page */
  21. #define SPIMEM_CMD_ERASE_BLOCK 0xd8 /* 64KB erase */
  22. #define SPIMEM_CMD_CONTINUOUS_READ_RESET 0xff /* exit quad continuous_read mode */
  23. _nor_fun void spi_delay(void)
  24. {
  25. volatile int i = SPI_DELAY_LOOPS;
  26. while (i--)
  27. ;
  28. }
  29. _nor_fun static int spi_controller_num(struct spi_info *si)
  30. {
  31. if (si->base == (SPI0_REG_BASE)) {
  32. return 0;
  33. } else if (si->base == (SPI1_REGISTER_BASE)) {
  34. return 1;
  35. } else if (si->base == (SPI2_REG_BASE)) {
  36. return 2;
  37. }else {
  38. return 3;
  39. }
  40. }
  41. _nor_fun static void spi_set_bits(struct spi_info *si, unsigned int reg,
  42. unsigned int mask, unsigned int value)
  43. {
  44. spi_write(si, reg, (spi_read(si, reg) & ~mask) | value);
  45. }
  46. _nor_fun static void spi_reset(struct spi_info *si)
  47. {
  48. if (spi_controller_num(si) == 0) {
  49. /* SPI0 */
  50. sys_write32(sys_read32(RMU_MRCR0) & ~(1 << MRCR0_SPI0RESET), RMU_MRCR0);
  51. spi_delay();
  52. sys_write32(sys_read32(RMU_MRCR0) | (1 << MRCR0_SPI0RESET), RMU_MRCR0);
  53. } else if (spi_controller_num(si) == 1) {
  54. /* SPI1 */
  55. sys_write32(sys_read32(RMU_MRCR0) & ~(1 << MRCR0_SPI1RESET), RMU_MRCR0);
  56. spi_delay();
  57. sys_write32(sys_read32(RMU_MRCR0) | (1 << MRCR0_SPI1RESET), RMU_MRCR0);
  58. } else if (spi_controller_num(si) == 2) {
  59. /* SPI2 */
  60. sys_write32(sys_read32(RMU_MRCR0) & ~(1 << MRCR0_SPI2RESET), RMU_MRCR0);
  61. spi_delay();
  62. sys_write32(sys_read32(RMU_MRCR0) | (1 << MRCR0_SPI2RESET), RMU_MRCR0);
  63. }else {
  64. /* SPI3 */
  65. sys_write32(sys_read32(RMU_MRCR0) & ~(1 << MRCR0_SPI3RESET), RMU_MRCR0);
  66. spi_delay();
  67. sys_write32(sys_read32(RMU_MRCR0) | (1 << MRCR0_SPI3RESET), RMU_MRCR0);
  68. }
  69. }
  70. #if 0
  71. _nor_fun static void spi_init_clk(struct spi_info *si)
  72. {
  73. if (spi_controller_num(si) == 0) {
  74. /* SPI0 clock source: 32M HOSC, div 2*/
  75. sys_write32(0x01, CMU_SPI0CLK);
  76. /* enable SPI0 module clock */
  77. sys_write32(sys_read32(CMU_DEVCLKEN0) | (1 << CMU_DEVCLKEN0_SPI0CLKEN), CMU_DEVCLKEN0);
  78. } else if (spi_controller_num(si) == 1) {
  79. /* SPI1 clock source: 32M HOSC div 2*/
  80. sys_write32(0x01, CMU_SPI1CLK);
  81. /* enable SPI1 module clock */
  82. sys_write32(sys_read32(CMU_DEVCLKEN0) | (1 << CMU_DEVCLKEN0_SPI1CLKEN), CMU_DEVCLKEN0);
  83. } else if (spi_controller_num(si) == 2) {
  84. /* SPI2 clock source: 32M HOSC div 2*/
  85. sys_write32(0x01, CMU_SPI2CLK);
  86. /* enable SPI0 module clock */
  87. sys_write32(sys_read32(CMU_DEVCLKEN0) | (1 << CMU_DEVCLKEN0_SPI2CLKEN), CMU_DEVCLKEN0);
  88. }else {
  89. /* SPI3 clock source: 32M HOSC div 2*/
  90. sys_write32(0x01, CMU_SPI3CLK);
  91. /* enable SPI0 module clock */
  92. sys_write32(sys_read32(CMU_DEVCLKEN0) | (1 << CMU_DEVCLKEN0_SPI3CLKEN), CMU_DEVCLKEN0);
  93. }
  94. }
  95. #endif
  96. _nor_fun static void spi_set_cs(struct spi_info *si, int value)
  97. {
  98. if (si->set_cs)
  99. si->set_cs(si, value);
  100. else
  101. spi_set_bits(si, SSPI_CTL, SSPI_CTL_SS, value ? SSPI_CTL_SS : 0);
  102. }
  103. _nor_fun static void spi_setup_bus_width(struct spi_info *si, unsigned char bus_width)
  104. {
  105. spi_set_bits(si, SSPI_CTL, SSPI_CTL_IO_MODE_MASK,
  106. ((bus_width & 0x7) / 2 + 1) << SSPI_CTL_IO_MODE_SHIFT);
  107. spi_delay();
  108. }
  109. _nor_fun static void spi_setup_randmomize(struct spi_info *si, int is_tx, int enable)
  110. {
  111. if (enable)
  112. spi_set_bits(si, SSPI_CTL, SSPI_CTL_RAND_TXEN | SSPI_CTL_RAND_RXEN,
  113. is_tx ? SSPI_CTL_RAND_TXEN : SSPI_CTL_RAND_RXEN);
  114. else
  115. spi_set_bits(si, SSPI_CTL, SSPI_CTL_RAND_TXEN | SSPI_CTL_RAND_RXEN, 0);
  116. }
  117. _nor_fun static void spi_pause_resume_randmomize(struct spi_info *si, int is_pause)
  118. {
  119. spi_set_bits(si, SSPI_CTL, SSPI_CTL_RAND_PAUSE, is_pause ? SSPI_CTL_RAND_PAUSE : 0);
  120. }
  121. _nor_fun static int spi_is_randmomize_pause(struct spi_info *si)
  122. {
  123. return !!(spi_read(si, SSPI_CTL) & SSPI_CTL_RAND_PAUSE);
  124. }
  125. _nor_fun static void spi_wait_tx_complete(struct spi_info *si)
  126. {
  127. if (spi_controller_num(si) == 0) {
  128. /* SPI0 */
  129. while (!(spi_read(si, SSPI_STATUS) & SSPI_STATUS_TX_EMPTY))
  130. ;
  131. /* wait until tx fifo is empty */
  132. while ((spi_read(si, SSPI_STATUS) & SSPI_STATUS_BUSY))
  133. ;
  134. } else {
  135. /* SPI1 & SPI2 & SPI3 */
  136. while (!(spi_read(si, SSPI_STATUS) & SSPI1_STATUS_TX_EMPTY))
  137. ;
  138. /* wait until tx fifo is empty */
  139. while ((spi_read(si, SSPI_STATUS) & SSPI1_STATUS_BUSY))
  140. ;
  141. }
  142. }
  143. _nor_fun static void spi_read_data(struct spi_info *si, unsigned char *buf,
  144. int len)
  145. {
  146. spi_write(si, SSPI_BC, len);
  147. /* switch to read mode */
  148. spi_set_bits(si, SSPI_CTL, SSPI_CTL_WR_MODE_MASK, SSPI_CTL_WR_MODE_READ);
  149. /* read data */
  150. while (len--) {
  151. if (spi_controller_num(si) == 0) {
  152. /* SPI0 */
  153. while (spi_read(si, SSPI_STATUS) & SSPI_STATUS_RX_EMPTY)
  154. ;
  155. } else {
  156. /* SPI1 & SPI2 & SPI3 */
  157. while (spi_read(si, SSPI_STATUS) & SSPI1_STATUS_RX_EMPTY)
  158. ;
  159. }
  160. *buf++ = spi_read(si, SSPI_RXDAT);
  161. }
  162. /* disable read mode */
  163. spi_set_bits(si, SSPI_CTL, SSPI_CTL_WR_MODE_MASK, SSPI_CTL_WR_MODE_DISABLE);
  164. }
  165. _nor_fun static void spi_write_data(struct spi_info *si,
  166. const unsigned char *buf, int len)
  167. {
  168. /* switch to write mode */
  169. spi_set_bits(si, SSPI_CTL, SSPI_CTL_WR_MODE_MASK, SSPI_CTL_WR_MODE_WRITE);
  170. /* write data */
  171. while (len--) {
  172. if (spi_controller_num(si) == 0) {
  173. /* SPI0 */
  174. while (spi_read(si, SSPI_STATUS) & SSPI_STATUS_TX_FULL)
  175. ;
  176. } else {
  177. /* SPI1 & SPI2 & SPI3 */
  178. while (spi_read(si, SSPI_STATUS) & SSPI1_STATUS_TX_FULL)
  179. ;
  180. }
  181. spi_write(si, SSPI_TXDAT, *buf++);
  182. }
  183. spi_delay();
  184. spi_wait_tx_complete(si);
  185. /* disable write mode */
  186. spi_set_bits(si, SSPI_CTL, SSPI_CTL_WR_MODE_MASK, SSPI_CTL_WR_MODE_DISABLE);
  187. }
  188. #define DMA_CTL (0x00)
  189. #define DMA_START (0x04)
  190. #define DMA_SADDR (0x08)
  191. #define DMA_DADDR (0x10)
  192. #define DMA_BC (0x18)
  193. #define DMA_RC (0x1c)
  194. //#define DMA_PD (0x04)
  195. _nor_fun static void spi_read_data_by_dma(struct spi_info *si,
  196. const unsigned char *buf, int len)
  197. {
  198. spi_write(si, SSPI_BC, len);
  199. /* switch to dma read mode */
  200. spi_set_bits(si, SSPI_CTL, SSPI_CTL_CLK_SEL_MASK | SSPI_CTL_RX_DRQ_EN | SSPI_CTL_WR_MODE_MASK,
  201. SSPI_CTL_CLK_SEL_DMA | SSPI_CTL_RX_DRQ_EN | SSPI_CTL_WR_MODE_READ);
  202. if (spi_controller_num(si) == 0) {
  203. /* SPI0 */
  204. sys_write32(0x200087, si->dma_base + DMA_CTL);
  205. } else if (spi_controller_num(si) == 1) {
  206. /* SPI1 */
  207. sys_write32(0x200088, si->dma_base + DMA_CTL);
  208. } else if (spi_controller_num(si) == 2) {
  209. /* SPI2 */
  210. sys_write32(0x200089, si->dma_base + DMA_CTL);
  211. } else {
  212. /* SPI3 */
  213. sys_write32(0x20008a, si->dma_base + DMA_CTL);
  214. }
  215. sys_write32(si->base + SSPI_RXDAT, si->dma_base + DMA_SADDR);
  216. sys_write32((unsigned int)buf, si->dma_base + DMA_DADDR);
  217. sys_write32(len, si->dma_base + DMA_BC);
  218. /* start dma */
  219. sys_write32(1, si->dma_base + DMA_START);
  220. while (sys_read32(si->dma_base + DMA_START) & 0x1) {
  221. /* wait */
  222. }
  223. spi_delay();
  224. spi_wait_tx_complete(si);
  225. spi_set_bits(si, SSPI_CTL, SSPI_CTL_CLK_SEL_MASK | SSPI_CTL_RX_DRQ_EN | SSPI_CTL_WR_MODE_MASK,
  226. SSPI_CTL_CLK_SEL_CPU | SSPI_CTL_WR_MODE_DISABLE);
  227. }
  228. _nor_fun static void spi_write_data_by_dma(struct spi_info *si,
  229. const unsigned char *buf, int len)
  230. {
  231. /* switch to dma write mode */
  232. spi_set_bits(si, SSPI_CTL, SSPI_CTL_CLK_SEL_MASK | SSPI_CTL_TX_DRQ_EN | SSPI_CTL_WR_MODE_MASK,
  233. SSPI_CTL_CLK_SEL_DMA | SSPI_CTL_TX_DRQ_EN | SSPI_CTL_WR_MODE_WRITE);
  234. if (spi_controller_num(si) == 0) {
  235. /* SPI0 */
  236. sys_write32(0x208700, si->dma_base + DMA_CTL);
  237. } else if (spi_controller_num(si) == 1) {
  238. /* SPI1 */
  239. sys_write32(0x208800, si->dma_base + DMA_CTL);
  240. } else if (spi_controller_num(si) == 2) {
  241. /* SPI2 */
  242. sys_write32(0x208900, si->dma_base + DMA_CTL);
  243. } else {
  244. /* SPI3 */
  245. sys_write32(0x208a00, si->dma_base + DMA_CTL);
  246. }
  247. sys_write32((unsigned int)buf, si->dma_base + DMA_SADDR);
  248. sys_write32(si->base + SSPI_TXDAT, si->dma_base + DMA_DADDR);
  249. sys_write32(len, si->dma_base + DMA_BC);
  250. /* start dma */
  251. sys_write32(1, si->dma_base + DMA_START);
  252. while (sys_read32(si->dma_base + DMA_START) & 0x1) {
  253. /* wait */
  254. }
  255. spi_delay();
  256. spi_wait_tx_complete(si);
  257. spi_set_bits(si, SSPI_CTL, SSPI_CTL_CLK_SEL_MASK | SSPI_CTL_TX_DRQ_EN | SSPI_CTL_WR_MODE_MASK,
  258. SSPI_CTL_CLK_SEL_CPU | SSPI_CTL_WR_MODE_DISABLE);
  259. }
  260. _nor_fun static void sys_memcpy_swap(void *dst, const void *src, int length)
  261. {
  262. unsigned char *tmp_src = (unsigned char *)((unsigned int)src + (length - 1));
  263. unsigned char *tmp_dst = (unsigned char *)dst;
  264. for (; length > 0; length--) {
  265. *tmp_dst++ = *tmp_src--;
  266. }
  267. }
  268. _nor_fun static void _spimem_read_data(struct spi_info *si, void *buf, int len)
  269. {
  270. if ((len > 16) && si->dma_base) {
  271. spi_read_data_by_dma(si, (unsigned char *)buf, len);
  272. } else {
  273. spi_read_data(si, (unsigned char *)buf, len);
  274. }
  275. }
  276. _nor_fun static void _spimem_write_data(struct spi_info *si, const void *buf, int len)
  277. {
  278. if ((len > 16) && si->dma_base) {
  279. spi_write_data_by_dma(si, (const unsigned char *)buf, len);
  280. } else {
  281. spi_write_data(si, (const unsigned char *)buf, len);
  282. }
  283. }
  284. _nor_fun static void _spimem_write_byte(struct spi_info *si, unsigned char byte)
  285. {
  286. _spimem_write_data(si, &byte, 1);
  287. }
  288. _nor_fun void spimem_set_cs(struct spi_info *si, int value)
  289. {
  290. spi_set_cs(si, value);
  291. }
  292. _nor_fun void spimem_continuous_read_reset(struct spi_info *si)
  293. {
  294. spimem_set_cs(si, 0);
  295. _spimem_write_byte(si, SPIMEM_CMD_CONTINUOUS_READ_RESET);
  296. _spimem_write_byte(si, SPIMEM_CMD_CONTINUOUS_READ_RESET);
  297. spimem_set_cs(si, 1);
  298. }
  299. _nor_fun unsigned int spimem_prepare_op(struct spi_info *si)
  300. {
  301. unsigned int orig_spi_ctl;
  302. unsigned int use_3wire = 0;
  303. /* backup old SPI_CTL */
  304. orig_spi_ctl = spi_read(si, SSPI_CTL);
  305. if (!spi_is_randmomize_pause(si))
  306. spi_reset(si);
  307. if (spi_controller_num(si) == 0) {
  308. spi_write(si, SSPI_CTL, (orig_spi_ctl & SSPI_CTL_RAND_MASK) |
  309. SSPI_CTL_AHB_REQ | SSPI_CTL_IO_MODE_1X | SSPI_CTL_WR_MODE_DISABLE |
  310. SSPI_CTL_RX_FIFO_EN | SSPI_CTL_TX_FIFO_EN | SSPI_CTL_SS |
  311. 8 << SSPI_CTL_DELAYCHAIN_SHIFT);
  312. use_3wire = orig_spi_ctl & SSPI_CTL_SPI_3WIRE;
  313. } else {
  314. spi_write(si, SSPI_CTL,
  315. SSPI1_CTL_AHB_REQ | SSPI_CTL_IO_MODE_1X | SSPI_CTL_WR_MODE_DISABLE |
  316. SSPI_CTL_RX_FIFO_EN | SSPI_CTL_TX_FIFO_EN | SSPI_CTL_SS |
  317. 8 << SSPI_CTL_DELAYCHAIN_SHIFT);
  318. }
  319. if (use_3wire)
  320. spi_set_bits(si, SSPI_CTL, SSPI_CTL_SPI_3WIRE, SSPI_CTL_SPI_3WIRE);
  321. if (si->delay_chain != 0xff)
  322. spi_set_bits(si, SSPI_CTL, SSPI_CTL_DELAYCHAIN_MASK,
  323. si->delay_chain << SSPI_CTL_DELAYCHAIN_SHIFT);
  324. if (si->flag & SPI_FLAG_SPI_MODE0) {
  325. if (spi_controller_num(si) == 0) {
  326. spi_set_bits(si, SSPI_CTL, SSPI_CTL_MODE_MASK,
  327. SSPI_CTL_MODE_MODE0);
  328. } else {
  329. spi_set_bits(si, SSPI_CTL, SSPI1_CTL_MODE_MASK,
  330. SSPI1_CTL_MODE_MODE0);
  331. }
  332. }
  333. if (si->set_clk && si->freq_khz)
  334. si->set_clk(si, si->freq_khz);
  335. if (si->prepare_hook)
  336. si->prepare_hook(si);
  337. return orig_spi_ctl;
  338. }
  339. _nor_fun void spimem_complete_op(struct spi_info *si, unsigned int orig_spi_ctl)
  340. {
  341. /* restore old SPI_CTL */
  342. spi_write(si, SSPI_CTL, orig_spi_ctl);
  343. spi_delay();
  344. }
  345. _nor_fun int spimem_transfer(struct spi_info *si, unsigned char cmd, unsigned int addr,
  346. int addr_len, void *buf, int length,
  347. unsigned char dummy_len, unsigned int flag)
  348. {
  349. unsigned int orig_spi_ctl, i, addr_be;
  350. unsigned int key = 0;
  351. /* address to big endian */
  352. if (addr_len > 0)
  353. sys_memcpy_swap(&addr_be, &addr, addr_len);
  354. if (!(si->flag & SPI_FLAG_NO_IRQ_LOCK)) {
  355. key = irq_lock();
  356. }
  357. orig_spi_ctl = spimem_prepare_op(si);
  358. if (!spi_is_randmomize_pause(si))
  359. spi_setup_randmomize(si, 0, 0);
  360. #ifdef NORDEBUG
  361. // SPI_SEED configuration, nor reset
  362. sys_write32(0x12345678, SPI0_SEED);
  363. #endif
  364. spimem_set_cs(si, 0);
  365. /* cmd & address & data all use multi io mode */
  366. if (flag & SPIMEM_TFLAG_MIO_CMD_ADDR_DATA)
  367. spi_setup_bus_width(si, si->bus_width);
  368. /* write command */
  369. _spimem_write_byte(si, cmd);
  370. /* address & data use multi io mode */
  371. if (flag & SPIMEM_TFLAG_MIO_ADDR_DATA)
  372. spi_setup_bus_width(si, si->bus_width);
  373. if (addr_len > 0)
  374. _spimem_write_data(si, &addr_be, addr_len);
  375. /* send dummy bytes */
  376. for (i = 0; i < dummy_len; i++)
  377. _spimem_write_byte(si, 0);
  378. /* only data use multi io mode */
  379. if (flag & SPIMEM_TFLAG_MIO_DATA)
  380. spi_setup_bus_width(si, si->bus_width);
  381. /* send or get data */
  382. if (length > 0) {
  383. if (flag & SPIMEM_TFLAG_WRITE_DATA) {
  384. if (flag & SPIMEM_TFLAG_RESUME_RANDOMIZE)
  385. spi_pause_resume_randmomize(si, 0);
  386. if (flag & SPIMEM_TFLAG_ENABLE_RANDOMIZE)
  387. spi_setup_randmomize(si, 1, 1);
  388. _spimem_write_data(si, buf, length);
  389. } else {
  390. if (flag & SPIMEM_TFLAG_RESUME_RANDOMIZE)
  391. spi_pause_resume_randmomize(si, 0);
  392. if (flag & SPIMEM_TFLAG_ENABLE_RANDOMIZE)
  393. spi_setup_randmomize(si, 0, 1);
  394. _spimem_read_data(si, buf, length);
  395. }
  396. }
  397. /* restore spi bus width to 1-bit */
  398. if (flag & SPIMEM_TFLAG_MIO_MASK)
  399. spi_setup_bus_width(si, 1);
  400. if (flag & SPIMEM_TFLAG_PAUSE_RANDOMIZE)
  401. spi_pause_resume_randmomize(si, 1);
  402. else if (flag & SPIMEM_TFLAG_ENABLE_RANDOMIZE)
  403. spi_setup_randmomize(si, 0, 0);
  404. spimem_set_cs(si, 1);
  405. if (!spi_is_randmomize_pause(si))
  406. spimem_complete_op(si, orig_spi_ctl);
  407. if (!(si->flag & SPI_FLAG_NO_IRQ_LOCK)) {
  408. irq_unlock(key);
  409. }
  410. return 0;
  411. }
  412. _nor_fun int spimem_write_cmd_addr(struct spi_info *si, unsigned char cmd,
  413. unsigned int addr, int addr_len)
  414. {
  415. return spimem_transfer(si, cmd, addr, addr_len, 0, 0, 0, 0);
  416. }
  417. _nor_fun int spimem_write_cmd(struct spi_info *si, unsigned char cmd)
  418. {
  419. return spimem_write_cmd_addr(si, cmd, 0, 0);
  420. }
  421. _nor_fun void spimem_read_chipid(struct spi_info *si, void *chipid, int len)
  422. {
  423. spimem_transfer(si, SPIMEM_CMD_READ_CHIPID, 0, 0, chipid, len, 0, 0);
  424. }
  425. _nor_fun unsigned char spimem_read_status(struct spi_info *si, unsigned char cmd)
  426. {
  427. unsigned int status;
  428. spimem_transfer(si, cmd, 0, 0, &status, 1, 0, 0);
  429. return status;
  430. }
  431. _nor_fun void spimem_set_write_protect(struct spi_info *si, int protect)
  432. {
  433. if (protect)
  434. spimem_write_cmd(si, SPIMEM_CMD_DISABLE_WRITE);
  435. else
  436. spimem_write_cmd(si, SPIMEM_CMD_ENABLE_WRITE);
  437. }
  438. _nor_fun void spimem_read_page(struct spi_info *si,
  439. unsigned int addr, int addr_len,
  440. void *buf, int len)
  441. {
  442. unsigned char cmd;
  443. unsigned int flag, dlen =1;
  444. if (si->bus_width == 4) {
  445. if(si->flag & SPI_FLAG_SPI_NXIO) {
  446. cmd = SPIMEM_CMD_FAST_READ_X4IO;
  447. flag = SPIMEM_TFLAG_MIO_ADDR_DATA;
  448. dlen = 3;/*1byte mode & 2byte dummy*/
  449. }else{
  450. cmd = SPIMEM_CMD_FAST_READ_X4;
  451. flag = SPIMEM_TFLAG_MIO_DATA;
  452. }
  453. } else if (si->bus_width == 2) {
  454. if(si->flag & SPI_FLAG_SPI_NXIO){
  455. cmd = SPIMEM_CMD_FAST_READ_X2IO;
  456. flag = SPIMEM_TFLAG_MIO_ADDR_DATA;
  457. }else {
  458. cmd = SPIMEM_CMD_FAST_READ_X2;
  459. flag = SPIMEM_TFLAG_MIO_DATA;
  460. }
  461. } else {
  462. cmd = SPIMEM_CMD_FAST_READ;
  463. flag = 0;
  464. }
  465. /* change to 4 bytes address commands*/
  466. if (addr_len == 4)
  467. cmd++;
  468. spimem_transfer(si, cmd, addr, addr_len, buf, len, dlen, flag);
  469. }
  470. _nor_fun int spimem_erase_block(struct spi_info *si, unsigned int addr)
  471. {
  472. spimem_set_write_protect(si, 0);
  473. spimem_write_cmd_addr(si, SPIMEM_CMD_ERASE_BLOCK, addr, 3);
  474. return 0;
  475. }