120-spiflash.patch 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. --- a/drivers/mtd/devices/Kconfig
  2. +++ b/drivers/mtd/devices/Kconfig
  3. @@ -104,6 +104,10 @@ config M25PXX_USE_FAST_READ
  4. help
  5. This option enables FAST_READ access supported by ST M25Pxx.
  6. +config MTD_AR2315
  7. + tristate "Atheros AR2315+ SPI Flash support"
  8. + depends on ATHEROS_AR2315
  9. +
  10. config MTD_SLRAM
  11. tristate "Uncached system RAM"
  12. help
  13. --- a/drivers/mtd/devices/Makefile
  14. +++ b/drivers/mtd/devices/Makefile
  15. @@ -16,3 +16,4 @@ obj-$(CONFIG_MTD_LART) += lart.o
  16. obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o
  17. obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o
  18. obj-$(CONFIG_MTD_M25P80) += m25p80.o
  19. +obj-$(CONFIG_MTD_AR2315) += ar2315.o
  20. --- /dev/null
  21. +++ b/drivers/mtd/devices/ar2315.c
  22. @@ -0,0 +1,519 @@
  23. +
  24. +/*
  25. + * MTD driver for the SPI Flash Memory support on Atheros AR2315
  26. + *
  27. + * Copyright (c) 2005-2006 Atheros Communications Inc.
  28. + * Copyright (C) 2006-2007 FON Technology, SL.
  29. + * Copyright (C) 2006-2007 Imre Kaloz <[email protected]>
  30. + * Copyright (C) 2006-2009 Felix Fietkau <[email protected]>
  31. + *
  32. + * This code is free software; you can redistribute it and/or modify
  33. + * it under the terms of the GNU General Public License version 2 as
  34. + * published by the Free Software Foundation.
  35. + *
  36. + */
  37. +
  38. +#include <linux/kernel.h>
  39. +#include <linux/module.h>
  40. +#include <linux/types.h>
  41. +#include <linux/version.h>
  42. +#include <linux/errno.h>
  43. +#include <linux/slab.h>
  44. +#include <linux/mtd/mtd.h>
  45. +#include <linux/mtd/partitions.h>
  46. +#include <linux/platform_device.h>
  47. +#include <linux/sched.h>
  48. +#include <linux/squashfs_fs.h>
  49. +#include <linux/root_dev.h>
  50. +#include <linux/delay.h>
  51. +#include <asm/delay.h>
  52. +#include <asm/io.h>
  53. +
  54. +#include <ar2315_spiflash.h>
  55. +#include <ar231x_platform.h>
  56. +#include <ar231x.h>
  57. +
  58. +
  59. +#define SPIFLASH "spiflash: "
  60. +#define busy_wait(_priv, _condition, _wait) do { \
  61. + while (_condition) { \
  62. + spin_unlock_bh(&_priv->lock); \
  63. + if (_wait > 1) \
  64. + msleep(_wait); \
  65. + else if ((_wait == 1) && need_resched()) \
  66. + schedule(); \
  67. + else \
  68. + udelay(1); \
  69. + spin_lock_bh(&_priv->lock); \
  70. + } \
  71. +} while (0)
  72. +
  73. +enum {
  74. + FLASH_NONE,
  75. + FLASH_1MB,
  76. + FLASH_2MB,
  77. + FLASH_4MB,
  78. + FLASH_8MB,
  79. + FLASH_16MB,
  80. +};
  81. +
  82. +/* Flash configuration table */
  83. +struct flashconfig {
  84. + u32 byte_cnt;
  85. + u32 sector_cnt;
  86. + u32 sector_size;
  87. +};
  88. +
  89. +const struct flashconfig flashconfig_tbl[] = {
  90. + [FLASH_NONE] = { 0, 0, 0},
  91. + [FLASH_1MB] = { STM_1MB_BYTE_COUNT, STM_1MB_SECTOR_COUNT, STM_1MB_SECTOR_SIZE},
  92. + [FLASH_2MB] = { STM_2MB_BYTE_COUNT, STM_2MB_SECTOR_COUNT, STM_2MB_SECTOR_SIZE},
  93. + [FLASH_4MB] = { STM_4MB_BYTE_COUNT, STM_4MB_SECTOR_COUNT, STM_4MB_SECTOR_SIZE},
  94. + [FLASH_8MB] = { STM_8MB_BYTE_COUNT, STM_8MB_SECTOR_COUNT, STM_8MB_SECTOR_SIZE},
  95. + [FLASH_16MB] = { STM_16MB_BYTE_COUNT, STM_16MB_SECTOR_COUNT, STM_16MB_SECTOR_SIZE}
  96. +};
  97. +
  98. +/* Mapping of generic opcodes to STM serial flash opcodes */
  99. +enum {
  100. + SPI_WRITE_ENABLE,
  101. + SPI_WRITE_DISABLE,
  102. + SPI_RD_STATUS,
  103. + SPI_WR_STATUS,
  104. + SPI_RD_DATA,
  105. + SPI_FAST_RD_DATA,
  106. + SPI_PAGE_PROGRAM,
  107. + SPI_SECTOR_ERASE,
  108. + SPI_BULK_ERASE,
  109. + SPI_DEEP_PWRDOWN,
  110. + SPI_RD_SIG,
  111. +};
  112. +
  113. +struct opcodes {
  114. + __u16 code;
  115. + __s8 tx_cnt;
  116. + __s8 rx_cnt;
  117. +};
  118. +const struct opcodes stm_opcodes[] = {
  119. + [SPI_WRITE_ENABLE] = {STM_OP_WR_ENABLE, 1, 0},
  120. + [SPI_WRITE_DISABLE] = {STM_OP_WR_DISABLE, 1, 0},
  121. + [SPI_RD_STATUS] = {STM_OP_RD_STATUS, 1, 1},
  122. + [SPI_WR_STATUS] = {STM_OP_WR_STATUS, 1, 0},
  123. + [SPI_RD_DATA] = {STM_OP_RD_DATA, 4, 4},
  124. + [SPI_FAST_RD_DATA] = {STM_OP_FAST_RD_DATA, 5, 0},
  125. + [SPI_PAGE_PROGRAM] = {STM_OP_PAGE_PGRM, 8, 0},
  126. + [SPI_SECTOR_ERASE] = {STM_OP_SECTOR_ERASE, 4, 0},
  127. + [SPI_BULK_ERASE] = {STM_OP_BULK_ERASE, 1, 0},
  128. + [SPI_DEEP_PWRDOWN] = {STM_OP_DEEP_PWRDOWN, 1, 0},
  129. + [SPI_RD_SIG] = {STM_OP_RD_SIG, 4, 1},
  130. +};
  131. +
  132. +/* Driver private data structure */
  133. +struct spiflash_priv {
  134. + struct mtd_info mtd;
  135. + void *readaddr; /* memory mapped data for read */
  136. + void *mmraddr; /* memory mapped register space */
  137. + wait_queue_head_t wq;
  138. + spinlock_t lock;
  139. + int state;
  140. +};
  141. +
  142. +#define to_spiflash(_mtd) container_of(_mtd, struct spiflash_priv, mtd)
  143. +
  144. +enum {
  145. + FL_READY,
  146. + FL_READING,
  147. + FL_ERASING,
  148. + FL_WRITING
  149. +};
  150. +
  151. +/***************************************************************************************************/
  152. +
  153. +static u32
  154. +spiflash_read_reg(struct spiflash_priv *priv, int reg)
  155. +{
  156. + return ar231x_read_reg((u32) priv->mmraddr + reg);
  157. +}
  158. +
  159. +static void
  160. +spiflash_write_reg(struct spiflash_priv *priv, int reg, u32 data)
  161. +{
  162. + ar231x_write_reg((u32) priv->mmraddr + reg, data);
  163. +}
  164. +
  165. +static u32
  166. +spiflash_wait_busy(struct spiflash_priv *priv)
  167. +{
  168. + u32 reg;
  169. +
  170. + busy_wait(priv, (reg = spiflash_read_reg(priv, SPI_FLASH_CTL)) &
  171. + SPI_CTL_BUSY, 0);
  172. + return reg;
  173. +}
  174. +
  175. +static u32
  176. +spiflash_sendcmd (struct spiflash_priv *priv, int opcode, u32 addr)
  177. +{
  178. + const struct opcodes *op;
  179. + u32 reg, mask;
  180. +
  181. + op = &stm_opcodes[opcode];
  182. + reg = spiflash_wait_busy(priv);
  183. + spiflash_write_reg(priv, SPI_FLASH_OPCODE,
  184. + ((u32) op->code) | (addr << 8));
  185. +
  186. + reg &= ~SPI_CTL_TX_RX_CNT_MASK;
  187. + reg |= SPI_CTL_START | op->tx_cnt | (op->rx_cnt << 4);
  188. +
  189. + spiflash_write_reg(priv, SPI_FLASH_CTL, reg);
  190. + spiflash_wait_busy(priv);
  191. +
  192. + if (!op->rx_cnt)
  193. + return 0;
  194. +
  195. + reg = spiflash_read_reg(priv, SPI_FLASH_DATA);
  196. +
  197. + switch (op->rx_cnt) {
  198. + case 1:
  199. + mask = 0x000000ff;
  200. + break;
  201. + case 2:
  202. + mask = 0x0000ffff;
  203. + break;
  204. + case 3:
  205. + mask = 0x00ffffff;
  206. + break;
  207. + default:
  208. + mask = 0xffffffff;
  209. + break;
  210. + }
  211. + reg &= mask;
  212. +
  213. + return reg;
  214. +}
  215. +
  216. +
  217. +/*
  218. + * Probe SPI flash device
  219. + * Function returns 0 for failure.
  220. + * and flashconfig_tbl array index for success.
  221. + */
  222. +static int
  223. +spiflash_probe_chip (struct spiflash_priv *priv)
  224. +{
  225. + u32 sig;
  226. + int flash_size;
  227. +
  228. + /* Read the signature on the flash device */
  229. + spin_lock_bh(&priv->lock);
  230. + sig = spiflash_sendcmd(priv, SPI_RD_SIG, 0);
  231. + spin_unlock_bh(&priv->lock);
  232. +
  233. + switch (sig) {
  234. + case STM_8MBIT_SIGNATURE:
  235. + flash_size = FLASH_1MB;
  236. + break;
  237. + case STM_16MBIT_SIGNATURE:
  238. + flash_size = FLASH_2MB;
  239. + break;
  240. + case STM_32MBIT_SIGNATURE:
  241. + flash_size = FLASH_4MB;
  242. + break;
  243. + case STM_64MBIT_SIGNATURE:
  244. + flash_size = FLASH_8MB;
  245. + break;
  246. + case STM_128MBIT_SIGNATURE:
  247. + flash_size = FLASH_16MB;
  248. + break;
  249. + default:
  250. + printk (KERN_WARNING SPIFLASH "Read of flash device signature failed!\n");
  251. + return 0;
  252. + }
  253. +
  254. + return flash_size;
  255. +}
  256. +
  257. +
  258. +/* wait until the flash chip is ready and grab a lock */
  259. +static int spiflash_wait_ready(struct spiflash_priv *priv, int state)
  260. +{
  261. + DECLARE_WAITQUEUE(wait, current);
  262. +
  263. +retry:
  264. + spin_lock_bh(&priv->lock);
  265. + if (priv->state != FL_READY) {
  266. + set_current_state(TASK_UNINTERRUPTIBLE);
  267. + add_wait_queue(&priv->wq, &wait);
  268. + spin_unlock_bh(&priv->lock);
  269. + schedule();
  270. + remove_wait_queue(&priv->wq, &wait);
  271. +
  272. + if(signal_pending(current))
  273. + return 0;
  274. +
  275. + goto retry;
  276. + }
  277. + priv->state = state;
  278. +
  279. + return 1;
  280. +}
  281. +
  282. +static inline void spiflash_done(struct spiflash_priv *priv)
  283. +{
  284. + priv->state = FL_READY;
  285. + spin_unlock_bh(&priv->lock);
  286. + wake_up(&priv->wq);
  287. +}
  288. +
  289. +static void
  290. +spiflash_wait_complete(struct spiflash_priv *priv)
  291. +{
  292. + busy_wait(priv, spiflash_sendcmd(priv, SPI_RD_STATUS, 0) &
  293. + SPI_STATUS_WIP, 20);
  294. + spiflash_done(priv);
  295. +}
  296. +
  297. +
  298. +
  299. +static int
  300. +spiflash_erase (struct mtd_info *mtd, struct erase_info *instr)
  301. +{
  302. + struct spiflash_priv *priv = to_spiflash(mtd);
  303. + const struct opcodes *op;
  304. + u32 temp, reg;
  305. +
  306. + if (instr->addr + instr->len > mtd->size)
  307. + return -EINVAL;
  308. +
  309. + if (!spiflash_wait_ready(priv, FL_ERASING))
  310. + return -EINTR;
  311. +
  312. + spiflash_sendcmd(priv, SPI_WRITE_ENABLE, 0);
  313. + reg = spiflash_wait_busy(priv);
  314. +
  315. + op = &stm_opcodes[SPI_SECTOR_ERASE];
  316. + temp = ((u32)instr->addr << 8) | (u32)(op->code);
  317. + spiflash_write_reg(priv, SPI_FLASH_OPCODE, temp);
  318. +
  319. + reg &= ~SPI_CTL_TX_RX_CNT_MASK;
  320. + reg |= op->tx_cnt | SPI_CTL_START;
  321. + spiflash_write_reg(priv, SPI_FLASH_CTL, reg);
  322. +
  323. + spiflash_wait_complete(priv);
  324. +
  325. + instr->state = MTD_ERASE_DONE;
  326. + if (instr->callback)
  327. + instr->callback(instr);
  328. +
  329. + return 0;
  330. +}
  331. +
  332. +static int
  333. +spiflash_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
  334. +{
  335. + struct spiflash_priv *priv = to_spiflash(mtd);
  336. + u8 *read_addr;
  337. +
  338. + if (!len)
  339. + return 0;
  340. +
  341. + if (from + len > mtd->size)
  342. + return -EINVAL;
  343. +
  344. + *retlen = len;
  345. +
  346. + if (!spiflash_wait_ready(priv, FL_READING))
  347. + return -EINTR;
  348. +
  349. + read_addr = (u8 *)(priv->readaddr + from);
  350. + memcpy_fromio(buf, read_addr, len);
  351. + spiflash_done(priv);
  352. +
  353. + return 0;
  354. +}
  355. +
  356. +static int
  357. +spiflash_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u8 *buf)
  358. +{
  359. + struct spiflash_priv *priv = to_spiflash(mtd);
  360. + u32 opcode, bytes_left;
  361. +
  362. + *retlen = 0;
  363. +
  364. + if (!len)
  365. + return 0;
  366. +
  367. + if (to + len > mtd->size)
  368. + return -EINVAL;
  369. +
  370. + bytes_left = len;
  371. +
  372. + do {
  373. + u32 read_len, reg, page_offset, spi_data = 0;
  374. +
  375. + read_len = min(bytes_left, sizeof(u32));
  376. +
  377. + /* 32-bit writes cannot span across a page boundary
  378. + * (256 bytes). This types of writes require two page
  379. + * program operations to handle it correctly. The STM part
  380. + * will write the overflow data to the beginning of the
  381. + * current page as opposed to the subsequent page.
  382. + */
  383. + page_offset = (to & (STM_PAGE_SIZE - 1)) + read_len;
  384. +
  385. + if (page_offset > STM_PAGE_SIZE)
  386. + read_len -= (page_offset - STM_PAGE_SIZE);
  387. +
  388. + if (!spiflash_wait_ready(priv, FL_WRITING))
  389. + return -EINTR;
  390. +
  391. + spiflash_sendcmd(priv, SPI_WRITE_ENABLE, 0);
  392. + spi_data = 0;
  393. + switch (read_len) {
  394. + case 4:
  395. + spi_data |= buf[3] << 24;
  396. + /* fall through */
  397. + case 3:
  398. + spi_data |= buf[2] << 16;
  399. + /* fall through */
  400. + case 2:
  401. + spi_data |= buf[1] << 8;
  402. + /* fall through */
  403. + case 1:
  404. + spi_data |= buf[0] & 0xff;
  405. + break;
  406. + default:
  407. + break;
  408. + }
  409. +
  410. + spiflash_write_reg(priv, SPI_FLASH_DATA, spi_data);
  411. + opcode = stm_opcodes[SPI_PAGE_PROGRAM].code |
  412. + (to & 0x00ffffff) << 8;
  413. + spiflash_write_reg(priv, SPI_FLASH_OPCODE, opcode);
  414. +
  415. + reg = spiflash_read_reg(priv, SPI_FLASH_CTL);
  416. + reg &= ~SPI_CTL_TX_RX_CNT_MASK;
  417. + reg |= (read_len + 4) | SPI_CTL_START;
  418. + spiflash_write_reg(priv, SPI_FLASH_CTL, reg);
  419. +
  420. + spiflash_wait_complete(priv);
  421. +
  422. + bytes_left -= read_len;
  423. + to += read_len;
  424. + buf += read_len;
  425. +
  426. + *retlen += read_len;
  427. + } while (bytes_left != 0);
  428. +
  429. + return 0;
  430. +}
  431. +
  432. +
  433. +#ifdef CONFIG_MTD_PARTITIONS
  434. +static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", "MyLoader", NULL };
  435. +#endif
  436. +
  437. +
  438. +static int
  439. +spiflash_probe(struct platform_device *pdev)
  440. +{
  441. + struct spiflash_priv *priv;
  442. + struct mtd_partition *parts;
  443. + struct mtd_info *mtd;
  444. + int index, num_parts;
  445. + int result = 0;
  446. +
  447. + priv = kzalloc(sizeof(struct spiflash_priv), GFP_KERNEL);
  448. + spin_lock_init(&priv->lock);
  449. + init_waitqueue_head(&priv->wq);
  450. + priv->state = FL_READY;
  451. + mtd = &priv->mtd;
  452. +
  453. + priv->mmraddr = ioremap_nocache(SPI_FLASH_MMR, SPI_FLASH_MMR_SIZE);
  454. + if (!priv->mmraddr) {
  455. + printk(KERN_WARNING SPIFLASH "Failed to map flash device\n");
  456. + goto error;
  457. + }
  458. +
  459. + index = spiflash_probe_chip(priv);
  460. + if (!index) {
  461. + printk (KERN_WARNING SPIFLASH "Found no serial flash device\n");
  462. + goto error;
  463. + }
  464. +
  465. + priv->readaddr = ioremap_nocache(SPI_FLASH_READ, flashconfig_tbl[index].byte_cnt);
  466. + if (!priv->readaddr) {
  467. + printk (KERN_WARNING SPIFLASH "Failed to map flash device\n");
  468. + goto error;
  469. + }
  470. +
  471. + platform_set_drvdata(pdev, priv);
  472. + mtd->name = "spiflash";
  473. + mtd->type = MTD_NORFLASH;
  474. + mtd->flags = (MTD_CAP_NORFLASH|MTD_WRITEABLE);
  475. + mtd->size = flashconfig_tbl[index].byte_cnt;
  476. + mtd->erasesize = flashconfig_tbl[index].sector_size;
  477. + mtd->writesize = 1;
  478. + mtd->numeraseregions = 0;
  479. + mtd->eraseregions = NULL;
  480. + mtd->erase = spiflash_erase;
  481. + mtd->read = spiflash_read;
  482. + mtd->write = spiflash_write;
  483. + mtd->owner = THIS_MODULE;
  484. +
  485. +#ifdef CONFIG_MTD_PARTITIONS
  486. + /* parse redboot partitions */
  487. + num_parts = parse_mtd_partitions(mtd, part_probe_types, &parts, 0);
  488. + if (!num_parts)
  489. + goto error;
  490. +
  491. + result = add_mtd_partitions(mtd, parts, num_parts);
  492. +#endif
  493. +
  494. + return result;
  495. +
  496. +error:
  497. + if (priv->mmraddr)
  498. + iounmap(priv->mmraddr);
  499. + kfree(priv);
  500. + return -ENXIO;
  501. +}
  502. +
  503. +static int
  504. +spiflash_remove (struct platform_device *pdev)
  505. +{
  506. + struct spiflash_priv *priv = platform_get_drvdata(pdev);
  507. + struct mtd_info *mtd = &priv->mtd;
  508. +
  509. + del_mtd_partitions(mtd);
  510. + iounmap(priv->mmraddr);
  511. + iounmap(priv->readaddr);
  512. + kfree(priv);
  513. +
  514. + return 0;
  515. +}
  516. +
  517. +struct platform_driver spiflash_driver = {
  518. + .driver.name = "spiflash",
  519. + .probe = spiflash_probe,
  520. + .remove = spiflash_remove,
  521. +};
  522. +
  523. +int __init
  524. +spiflash_init (void)
  525. +{
  526. + return platform_driver_register(&spiflash_driver);
  527. +}
  528. +
  529. +void __exit
  530. +spiflash_exit (void)
  531. +{
  532. + return platform_driver_unregister(&spiflash_driver);
  533. +}
  534. +
  535. +module_init (spiflash_init);
  536. +module_exit (spiflash_exit);
  537. +
  538. +MODULE_LICENSE("GPL");
  539. +MODULE_AUTHOR("OpenWrt.org, Atheros Communications Inc");
  540. +MODULE_DESCRIPTION("MTD driver for SPI Flash on Atheros SOC");
  541. +
  542. --- /dev/null
  543. +++ b/arch/mips/include/asm/mach-ar231x/ar2315_spiflash.h
  544. @@ -0,0 +1,116 @@
  545. +/*
  546. + * SPI Flash Memory support header file.
  547. + *
  548. + * Copyright (c) 2005, Atheros Communications Inc.
  549. + * Copyright (C) 2006 FON Technology, SL.
  550. + * Copyright (C) 2006 Imre Kaloz <[email protected]>
  551. + * Copyright (C) 2006-2009 Felix Fietkau <[email protected]>
  552. + *
  553. + * This code is free software; you can redistribute it and/or modify
  554. + * it under the terms of the GNU General Public License version 2 as
  555. + * published by the Free Software Foundation.
  556. + *
  557. + */
  558. +#ifndef __AR2315_SPIFLASH_H
  559. +#define __AR2315_SPIFLASH_H
  560. +
  561. +#define STM_PAGE_SIZE 256
  562. +
  563. +#define SFI_WRITE_BUFFER_SIZE 4
  564. +#define SFI_FLASH_ADDR_MASK 0x00ffffff
  565. +
  566. +#define STM_8MBIT_SIGNATURE 0x13
  567. +#define STM_M25P80_BYTE_COUNT 1048576
  568. +#define STM_M25P80_SECTOR_COUNT 16
  569. +#define STM_M25P80_SECTOR_SIZE 0x10000
  570. +
  571. +#define STM_16MBIT_SIGNATURE 0x14
  572. +#define STM_M25P16_BYTE_COUNT 2097152
  573. +#define STM_M25P16_SECTOR_COUNT 32
  574. +#define STM_M25P16_SECTOR_SIZE 0x10000
  575. +
  576. +#define STM_32MBIT_SIGNATURE 0x15
  577. +#define STM_M25P32_BYTE_COUNT 4194304
  578. +#define STM_M25P32_SECTOR_COUNT 64
  579. +#define STM_M25P32_SECTOR_SIZE 0x10000
  580. +
  581. +#define STM_64MBIT_SIGNATURE 0x16
  582. +#define STM_M25P64_BYTE_COUNT 8388608
  583. +#define STM_M25P64_SECTOR_COUNT 128
  584. +#define STM_M25P64_SECTOR_SIZE 0x10000
  585. +
  586. +#define STM_128MBIT_SIGNATURE 0x17
  587. +#define STM_M25P128_BYTE_COUNT 16777216
  588. +#define STM_M25P128_SECTOR_COUNT 256
  589. +#define STM_M25P128_SECTOR_SIZE 0x10000
  590. +
  591. +#define STM_1MB_BYTE_COUNT STM_M25P80_BYTE_COUNT
  592. +#define STM_1MB_SECTOR_COUNT STM_M25P80_SECTOR_COUNT
  593. +#define STM_1MB_SECTOR_SIZE STM_M25P80_SECTOR_SIZE
  594. +#define STM_2MB_BYTE_COUNT STM_M25P16_BYTE_COUNT
  595. +#define STM_2MB_SECTOR_COUNT STM_M25P16_SECTOR_COUNT
  596. +#define STM_2MB_SECTOR_SIZE STM_M25P16_SECTOR_SIZE
  597. +#define STM_4MB_BYTE_COUNT STM_M25P32_BYTE_COUNT
  598. +#define STM_4MB_SECTOR_COUNT STM_M25P32_SECTOR_COUNT
  599. +#define STM_4MB_SECTOR_SIZE STM_M25P32_SECTOR_SIZE
  600. +#define STM_8MB_BYTE_COUNT STM_M25P64_BYTE_COUNT
  601. +#define STM_8MB_SECTOR_COUNT STM_M25P64_SECTOR_COUNT
  602. +#define STM_8MB_SECTOR_SIZE STM_M25P64_SECTOR_SIZE
  603. +#define STM_16MB_BYTE_COUNT STM_M25P128_BYTE_COUNT
  604. +#define STM_16MB_SECTOR_COUNT STM_M25P128_SECTOR_COUNT
  605. +#define STM_16MB_SECTOR_SIZE STM_M25P128_SECTOR_SIZE
  606. +
  607. +/*
  608. + * ST Microelectronics Opcodes for Serial Flash
  609. + */
  610. +
  611. +#define STM_OP_WR_ENABLE 0x06 /* Write Enable */
  612. +#define STM_OP_WR_DISABLE 0x04 /* Write Disable */
  613. +#define STM_OP_RD_STATUS 0x05 /* Read Status */
  614. +#define STM_OP_WR_STATUS 0x01 /* Write Status */
  615. +#define STM_OP_RD_DATA 0x03 /* Read Data */
  616. +#define STM_OP_FAST_RD_DATA 0x0b /* Fast Read Data */
  617. +#define STM_OP_PAGE_PGRM 0x02 /* Page Program */
  618. +#define STM_OP_SECTOR_ERASE 0xd8 /* Sector Erase */
  619. +#define STM_OP_BULK_ERASE 0xc7 /* Bulk Erase */
  620. +#define STM_OP_DEEP_PWRDOWN 0xb9 /* Deep Power-Down Mode */
  621. +#define STM_OP_RD_SIG 0xab /* Read Electronic Signature */
  622. +
  623. +#define STM_STATUS_WIP 0x01 /* Write-In-Progress */
  624. +#define STM_STATUS_WEL 0x02 /* Write Enable Latch */
  625. +#define STM_STATUS_BP0 0x04 /* Block Protect 0 */
  626. +#define STM_STATUS_BP1 0x08 /* Block Protect 1 */
  627. +#define STM_STATUS_BP2 0x10 /* Block Protect 2 */
  628. +#define STM_STATUS_SRWD 0x80 /* Status Register Write Disable */
  629. +
  630. +/*
  631. + * SPI Flash Interface Registers
  632. + */
  633. +#define AR531XPLUS_SPI_READ 0x08000000
  634. +#define AR531XPLUS_SPI_MMR 0x11300000
  635. +#define AR531XPLUS_SPI_MMR_SIZE 12
  636. +
  637. +#define AR531XPLUS_SPI_CTL 0x00
  638. +#define AR531XPLUS_SPI_OPCODE 0x04
  639. +#define AR531XPLUS_SPI_DATA 0x08
  640. +
  641. +#define SPI_FLASH_READ AR531XPLUS_SPI_READ
  642. +#define SPI_FLASH_MMR AR531XPLUS_SPI_MMR
  643. +#define SPI_FLASH_MMR_SIZE AR531XPLUS_SPI_MMR_SIZE
  644. +#define SPI_FLASH_CTL AR531XPLUS_SPI_CTL
  645. +#define SPI_FLASH_OPCODE AR531XPLUS_SPI_OPCODE
  646. +#define SPI_FLASH_DATA AR531XPLUS_SPI_DATA
  647. +
  648. +#define SPI_CTL_START 0x00000100
  649. +#define SPI_CTL_BUSY 0x00010000
  650. +#define SPI_CTL_TXCNT_MASK 0x0000000f
  651. +#define SPI_CTL_RXCNT_MASK 0x000000f0
  652. +#define SPI_CTL_TX_RX_CNT_MASK 0x000000ff
  653. +#define SPI_CTL_SIZE_MASK 0x00060000
  654. +
  655. +#define SPI_CTL_CLK_SEL_MASK 0x03000000
  656. +#define SPI_OPCODE_MASK 0x000000ff
  657. +
  658. +#define SPI_STATUS_WIP STM_STATUS_WIP
  659. +
  660. +#endif