1 diff -urN linux.old/drivers/mtd/devices/Kconfig linux.dev/drivers/mtd/devices/Kconfig
2 --- linux.old/drivers/mtd/devices/Kconfig 2006-11-29 22:57:37.000000000 +0100
3 +++ linux.dev/drivers/mtd/devices/Kconfig 2006-12-15 00:03:11.000000000 +0100
5 used for program and data storage. Set up your spi devices
6 with the right board-specific platform data.
9 + tristate "Atheros AR2315/6/7 SPI Flash support"
10 + depends on MTD && AR531X_COBRA
13 tristate "Uncached system RAM"
15 diff -urN linux.old/drivers/mtd/devices/Makefile linux.dev/drivers/mtd/devices/Makefile
16 --- linux.old/drivers/mtd/devices/Makefile 2006-11-29 22:57:37.000000000 +0100
17 +++ linux.dev/drivers/mtd/devices/Makefile 2006-12-15 00:03:11.000000000 +0100
19 obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o
20 obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o
21 obj-$(CONFIG_MTD_M25P80) += m25p80.o
22 +obj-$(CONFIG_MTD_SPIFLASH) += spiflash.o
23 diff -urN linux.old/drivers/mtd/devices/spiflash.c linux.dev/drivers/mtd/devices/spiflash.c
24 --- linux.old/drivers/mtd/devices/spiflash.c 1970-01-01 01:00:00.000000000 +0100
25 +++ linux.dev/drivers/mtd/devices/spiflash.c 2006-12-15 08:26:11.000000000 +0100
29 + * MTD driver for the SPI Flash Memory support.
31 + * Copyright (c) 2005-2006 Atheros Communications Inc.
32 + * Copyright (C) 2006 FON Technology, SL.
33 + * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
34 + * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
36 + * This code is free software; you can redistribute it and/or modify
37 + * it under the terms of the GNU General Public License version 2 as
38 + * published by the Free Software Foundation.
42 +/*===========================================================================
43 +** !!!! VERY IMPORTANT NOTICE !!!! FLASH DATA STORED IN LITTLE ENDIAN FORMAT
45 +** This module contains the Serial Flash access routines for the Atheros SOC.
46 +** The Atheros SOC integrates a SPI flash controller that is used to access
47 +** serial flash parts. The SPI flash controller executes in "Little Endian"
48 +** mode. THEREFORE, all WRITES and READS from the MIPS CPU must be
49 +** BYTESWAPPED! The SPI Flash controller hardware by default performs READ
50 +** ONLY byteswapping when accessed via the SPI Flash Alias memory region
51 +** (Physical Address 0x0800_0000 - 0x0fff_ffff). The data stored in the
52 +** flash sectors is stored in "Little Endian" format.
54 +** The spiflash_write() routine performs byteswapping on all write
56 +**===========================================================================*/
58 +#include <linux/kernel.h>
59 +#include <linux/module.h>
60 +#include <linux/types.h>
61 +#include <linux/version.h>
62 +#include <linux/errno.h>
63 +#include <linux/slab.h>
64 +#include <linux/mtd/mtd.h>
65 +#include <linux/mtd/partitions.h>
66 +#include <linux/squashfs_fs.h>
67 +#include <linux/root_dev.h>
68 +#include <asm/delay.h>
70 +#include "spiflash.h"
73 +/* #define SPIFLASH_DEBUG */
76 +#error This driver currently only works with big endian CPU.
81 +static char module_name[] = "spiflash";
83 +#define MIN(a,b) ((a) < (b) ? (a) : (b))
87 +#define ROOTFS_NAME "rootfs"
89 +static __u32 spiflash_regread32(int reg);
90 +static void spiflash_regwrite32(int reg, __u32 data);
91 +static __u32 spiflash_sendcmd (int op);
93 +static void __init spidata_init(void);
94 +int __init spiflash_init (void);
95 +void __exit spiflash_exit (void);
96 +static int spiflash_probe (void);
97 +static int spiflash_erase (struct mtd_info *mtd,struct erase_info *instr);
98 +static int spiflash_read (struct mtd_info *mtd, loff_t from,size_t len,size_t *retlen,u_char *buf);
99 +static int spiflash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen,const u_char *buf);
101 +/* Flash configuration table */
102 +struct flashconfig {
107 +} flashconfig_tbl[MAX_FLASH] =
110 + { STM_1MB_BYTE_COUNT, STM_1MB_SECTOR_COUNT, STM_1MB_SECTOR_SIZE, 0x0},
111 + { STM_2MB_BYTE_COUNT, STM_2MB_SECTOR_COUNT, STM_2MB_SECTOR_SIZE, 0x0},
112 + { STM_4MB_BYTE_COUNT, STM_4MB_SECTOR_COUNT, STM_4MB_SECTOR_SIZE, 0x0},
113 + { STM_8MB_BYTE_COUNT, STM_8MB_SECTOR_COUNT, STM_8MB_SECTOR_SIZE, 0x0}
116 +/* Mapping of generic opcodes to STM serial flash opcodes */
122 + {STM_OP_WR_ENABLE, 1, 0},
123 + {STM_OP_WR_DISABLE, 1, 0},
124 + {STM_OP_RD_STATUS, 1, 1},
125 + {STM_OP_WR_STATUS, 1, 0},
126 + {STM_OP_RD_DATA, 4, 4},
127 + {STM_OP_FAST_RD_DATA, 1, 0},
128 + {STM_OP_PAGE_PGRM, 8, 0},
129 + {STM_OP_SECTOR_ERASE, 4, 0},
130 + {STM_OP_BULK_ERASE, 1, 0},
131 + {STM_OP_DEEP_PWRDOWN, 1, 0},
132 + {STM_OP_RD_SIG, 4, 1}
135 +/* Driver private data structure */
136 +struct spiflash_data {
137 + struct mtd_info *mtd;
138 + struct mtd_partition *parsed_parts; /* parsed partitions */
139 + void *spiflash_readaddr; /* memory mapped data for read */
140 + void *spiflash_mmraddr; /* memory mapped register space */
144 +static struct spiflash_data *spidata;
146 +extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
148 +/***************************************************************************************************/
151 +spiflash_regread32(int reg)
153 + volatile __u32 *data = (__u32 *)(spidata->spiflash_mmraddr + reg);
159 +spiflash_regwrite32(int reg, __u32 data)
161 + volatile __u32 *addr = (__u32 *)(spidata->spiflash_mmraddr + reg);
168 +spiflash_sendcmd (int op)
172 + struct opcodes *ptr_opcode;
174 + ptr_opcode = &stm_opcodes[op];
177 + reg = spiflash_regread32(SPI_FLASH_CTL);
178 + } while (reg & SPI_CTL_BUSY);
180 + spiflash_regwrite32(SPI_FLASH_OPCODE, ptr_opcode->code);
182 + reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | ptr_opcode->tx_cnt |
183 + (ptr_opcode->rx_cnt << 4) | SPI_CTL_START;
185 + spiflash_regwrite32(SPI_FLASH_CTL, reg);
187 + if (ptr_opcode->rx_cnt > 0) {
189 + reg = spiflash_regread32(SPI_FLASH_CTL);
190 + } while (reg & SPI_CTL_BUSY);
192 + reg = (__u32) spiflash_regread32(SPI_FLASH_DATA);
194 + switch (ptr_opcode->rx_cnt) {
218 +/* Probe SPI flash device
219 + * Function returns 0 for failure.
220 + * and flashconfig_tbl array index for success.
223 +spiflash_probe (void)
231 + if (!spidata) /* init failed */
234 + /* Read the signature on the flash device */
235 + sig = spiflash_sendcmd(SPI_RD_SIG);
238 + case STM_8MBIT_SIGNATURE:
239 + flash_size = FLASH_1MB;
241 + case STM_16MBIT_SIGNATURE:
242 + flash_size = FLASH_2MB;
244 + case STM_32MBIT_SIGNATURE:
245 + flash_size = FLASH_4MB;
247 + case STM_64MBIT_SIGNATURE:
248 + flash_size = FLASH_8MB;
251 + printk (KERN_WARNING "%s: Read of flash device signature failed!\n", module_name);
255 + return (flash_size);
260 +spiflash_erase (struct mtd_info *mtd,struct erase_info *instr)
262 + struct opcodes *ptr_opcode;
264 + int finished = FALSE;
266 +#ifdef SPIFLASH_DEBUG
267 + printk (KERN_DEBUG "%s(addr = 0x%.8x, len = %d)\n",__FUNCTION__,instr->addr,instr->len);
270 + /* sanity checks */
271 + if (instr->addr + instr->len > mtd->size) return (-EINVAL);
273 + ptr_opcode = &stm_opcodes[SPI_SECTOR_ERASE];
275 + temp = ((__u32)instr->addr << 8) | (__u32)(ptr_opcode->code);
276 + spin_lock(&spidata->mutex);
277 + spiflash_sendcmd(SPI_WRITE_ENABLE);
280 + reg = spiflash_regread32(SPI_FLASH_CTL);
281 + } while (reg & SPI_CTL_BUSY);
283 + spiflash_regwrite32(SPI_FLASH_OPCODE, temp);
285 + reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | ptr_opcode->tx_cnt | SPI_CTL_START;
286 + spiflash_regwrite32(SPI_FLASH_CTL, reg);
290 + reg = spiflash_sendcmd(SPI_RD_STATUS);
291 + if (!(reg & SPI_STATUS_WIP)) {
294 + } while (!finished);
295 + spin_unlock(&spidata->mutex);
297 + instr->state = MTD_ERASE_DONE;
298 + if (instr->callback) instr->callback (instr);
300 +#ifdef SPIFLASH_DEBUG
301 + printk (KERN_DEBUG "%s return\n",__FUNCTION__);
307 +spiflash_read (struct mtd_info *mtd, loff_t from,size_t len,size_t *retlen,u_char *buf)
311 +#ifdef SPIFLASH_DEBUG
312 + printk (KERN_DEBUG "%s(from = 0x%.8x, len = %d)\n",__FUNCTION__,(__u32) from,(int)len);
315 + /* sanity checks */
316 + if (!len) return (0);
317 + if (from + len > mtd->size) return (-EINVAL);
320 + /* we always read len bytes */
323 + read_addr = (u_char *)(spidata->spiflash_readaddr + from);
324 + spin_lock(&spidata->mutex);
325 + memcpy(buf, read_addr, len);
326 + spin_unlock(&spidata->mutex);
332 +spiflash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen,const u_char *buf)
334 + int done = FALSE, page_offset, bytes_left, finished;
335 + __u32 xact_len, spi_data = 0, opcode, reg;
337 +#ifdef SPIFLASH_DEBUG
338 + printk (KERN_DEBUG "%s(to = 0x%.8x, len = %d)\n",__FUNCTION__,(__u32) to,len);
343 + /* sanity checks */
344 + if (!len) return (0);
345 + if (to + len > mtd->size) return (-EINVAL);
347 + opcode = stm_opcodes[SPI_PAGE_PROGRAM].code;
350 + while (done == FALSE) {
351 + xact_len = MIN(bytes_left, sizeof(__u32));
353 + /* 32-bit writes cannot span across a page boundary
354 + * (256 bytes). This types of writes require two page
355 + * program operations to handle it correctly. The STM part
356 + * will write the overflow data to the beginning of the
357 + * current page as opposed to the subsequent page.
359 + page_offset = (to & (STM_PAGE_SIZE - 1)) + xact_len;
361 + if (page_offset > STM_PAGE_SIZE) {
362 + xact_len -= (page_offset - STM_PAGE_SIZE);
365 + spin_lock(&spidata->mutex);
366 + spiflash_sendcmd(SPI_WRITE_ENABLE);
370 + reg = spiflash_regread32(SPI_FLASH_CTL);
371 + } while (reg & SPI_CTL_BUSY);
373 + switch (xact_len) {
375 + spi_data = (u32) ((u8) *buf);
378 + spi_data = (buf[1] << 8) | buf[0];
381 + spi_data = (buf[2] << 16) | (buf[1] << 8) | buf[0];
384 + spi_data = (buf[3] << 24) | (buf[2] << 16) |
385 + (buf[1] << 8) | buf[0];
388 + printk("spiflash_write: default case\n");
392 + spiflash_regwrite32(SPI_FLASH_DATA, spi_data);
393 + opcode = (opcode & SPI_OPCODE_MASK) | ((__u32)to << 8);
394 + spiflash_regwrite32(SPI_FLASH_OPCODE, opcode);
396 + reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | (xact_len + 4) | SPI_CTL_START;
397 + spiflash_regwrite32(SPI_FLASH_CTL, reg);
402 + reg = spiflash_sendcmd(SPI_RD_STATUS);
403 + if (!(reg & SPI_STATUS_WIP)) {
406 + } while (!finished);
407 + spin_unlock(&spidata->mutex);
409 + bytes_left -= xact_len;
413 + *retlen += xact_len;
415 + if (bytes_left == 0) {
423 +static void __init spidata_init(void)
428 + spidata = kmalloc(sizeof(struct spiflash_data), GFP_KERNEL);
429 + spin_lock_init(&spidata->mutex);
434 + spidata->spiflash_mmraddr = ioremap_nocache(SPI_FLASH_MMR, SPI_FLASH_MMR_SIZE);
436 + if (!spidata->spiflash_mmraddr) {
437 + printk (KERN_WARNING "%s: Failed to map flash device\n", module_name);
443 +#ifdef CONFIG_MTD_PARTITIONS
444 +static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL };
448 +spiflash_init (void)
450 + int result = -1, i, j;
452 + int index, num_parts;
453 + struct mtd_info *mtd;
454 + struct mtd_partition *mtd_parts;
456 + struct mtd_partition *part;
457 + struct squashfs_super_block *sb;
465 + mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL);
471 + printk ("MTD driver for SPI flash.\n");
472 + printk ("%s: Probing for Serial flash ...\n", module_name);
473 + if (!(index = spiflash_probe ())) {
474 + printk (KERN_WARNING "%s: Found no serial flash device\n", module_name);
480 + printk ("%s: Found SPI serial Flash.\n", module_name);
482 + spidata->spiflash_readaddr = ioremap_nocache(SPI_FLASH_READ, flashconfig_tbl[index].byte_cnt);
483 + if (!spidata->spiflash_readaddr) {
484 + printk (KERN_WARNING "%s: Failed to map flash device\n", module_name);
490 + mtd->name = module_name;
491 + mtd->type = MTD_NORFLASH;
492 + mtd->flags = (MTD_CAP_NORFLASH|MTD_WRITEABLE);
493 + mtd->size = flashconfig_tbl[index].byte_cnt;
494 + mtd->erasesize = flashconfig_tbl[index].sector_size;
495 + mtd->writesize = 1;
496 + mtd->numeraseregions = 0;
497 + mtd->eraseregions = NULL;
498 + mtd->erase = spiflash_erase;
499 + mtd->read = spiflash_read;
500 + mtd->write = spiflash_write;
501 + mtd->owner = THIS_MODULE;
503 +#ifdef SPIFLASH_DEBUG
506 + "mtd->size = 0x%.8x (%uM)\n"
507 + "mtd->erasesize = 0x%.8x (%uK)\n"
508 + "mtd->numeraseregions = %d\n",
510 + mtd->size, mtd->size / (1024*1024),
511 + mtd->erasesize, mtd->erasesize / 1024,
512 + mtd->numeraseregions);
514 + if (mtd->numeraseregions) {
515 + for (result = 0; result < mtd->numeraseregions; result++) {
518 + "mtd->eraseregions[%d].offset = 0x%.8x\n"
519 + "mtd->eraseregions[%d].erasesize = 0x%.8x (%uK)\n"
520 + "mtd->eraseregions[%d].numblocks = %d\n",
521 + result,mtd->eraseregions[result].offset,
522 + result,mtd->eraseregions[result].erasesize,mtd->eraseregions[result].erasesize / 1024,
523 + result,mtd->eraseregions[result].numblocks);
528 + /* parse redboot partitions */
529 + num_parts = parse_mtd_partitions(mtd, part_probe_types, &spidata->parsed_parts, 0);
531 + mtd_parts = kzalloc(sizeof(struct mtd_partition) * MAX_PARTS, GFP_KERNEL);
532 + buf = kmalloc(mtd->erasesize, GFP_KERNEL);
533 + sb = (struct squashfs_super_block *) buf;
534 + for (i = j = 0; i < num_parts; i++, j++) {
535 + part = &mtd_parts[j];
536 + memcpy(part, &spidata->parsed_parts[i], sizeof(struct mtd_partition));
538 + if (!strcmp(part->name, ROOTFS_NAME)) {
539 + /* create the root device */
540 + ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, i);
542 + part->size -= mtd->erasesize;
543 + config_start = part->offset + part->size;
545 + while ((mtd->read(mtd, part->offset, mtd->erasesize, &len, buf) == 0) &&
546 + (len == mtd->erasesize) &&
547 + (*((u32 *) buf) == SQUASHFS_MAGIC) &&
548 + (sb->bytes_used > 0)) {
550 + /* this is squashfs, allocate another partition starting from the end of filesystem data */
551 + memcpy(&mtd_parts[j + 1], part, sizeof(struct mtd_partition));
553 + len = (u32) sb->bytes_used;
554 + len += (part->offset & 0x000fffff);
555 + len += (mtd->erasesize - 1);
556 + len &= ~(mtd->erasesize - 1);
557 + len -= (part->offset & 0x000fffff);
559 + if (len + mtd->erasesize > part->size)
562 + part = &mtd_parts[++j];
564 + part->offset += len;
567 + part->name = kmalloc(10, GFP_KERNEL);
568 + sprintf(part->name, "rootfs%d", j - i);
571 + if (!strcmp(part->name, "RedBoot config")) {
572 + /* add anoterh partition for the board config data */
573 + memcpy(&mtd_parts[j + 1], part, sizeof(struct mtd_partition));
575 + part = &mtd_parts[j];
576 + part->offset += part->size;
577 + part->size = mtd->erasesize;
579 + part->name = kmalloc(16, GFP_KERNEL);
580 + sprintf(part->name, "board_config");
583 + num_parts += j - i;
586 +#ifdef SPIFLASH_DEBUG
587 + printk (KERN_DEBUG "Found %d redboot partitions\n", num_parts);
590 + result = add_mtd_partitions(mtd, mtd_parts, num_parts);
592 +#ifdef SPIFLASH_DEBUG
593 + printk (KERN_DEBUG "Did not find any redboot partitions\n");
600 + spidata->mtd = mtd;
606 +spiflash_exit (void)
608 + if (spidata && spidata->parsed_parts) {
609 + del_mtd_partitions (spidata->mtd);
610 + kfree(spidata->mtd);
615 +module_init (spiflash_init);
616 +module_exit (spiflash_exit);
618 +MODULE_LICENSE("GPL");
619 +MODULE_AUTHOR("Atheros Communications Inc");
620 +MODULE_DESCRIPTION("MTD driver for SPI Flash on Atheros SOC");
622 diff -urN linux.old/drivers/mtd/devices/spiflash.h linux.dev/drivers/mtd/devices/spiflash.h
623 --- linux.old/drivers/mtd/devices/spiflash.h 1970-01-01 01:00:00.000000000 +0100
624 +++ linux.dev/drivers/mtd/devices/spiflash.h 2006-12-15 06:59:43.000000000 +0100
627 + * SPI Flash Memory support header file.
629 + * $Id: //depot/sw/releases/linuxsrc/src/kernels/mips-linux-2.4.25/drivers/mtd/devices/spiflash.h#3 $
632 + * Copyright (c) 2005, Atheros Communications Inc.
633 + * Copyright (C) 2006 FON Technology, SL.
634 + * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
636 + * This code is free software; you can redistribute it and/or modify
637 + * it under the terms of the GNU General Public License version 2 as
638 + * published by the Free Software Foundation.
647 +#define STM_PAGE_SIZE 256
649 +#define SPI_WRITE_ENABLE 0
650 +#define SPI_WRITE_DISABLE 1
651 +#define SPI_RD_STATUS 2
652 +#define SPI_WR_STATUS 3
653 +#define SPI_RD_DATA 4
654 +#define SPI_FAST_RD_DATA 5
655 +#define SPI_PAGE_PROGRAM 6
656 +#define SPI_SECTOR_ERASE 7
657 +#define SPI_BULK_ERASE 8
658 +#define SPI_DEEP_PWRDOWN 9
659 +#define SPI_RD_SIG 10
660 +#define SPI_MAX_OPCODES 11
662 +#define SFI_WRITE_BUFFER_SIZE 4
663 +#define SFI_FLASH_ADDR_MASK 0x00ffffff
665 +#define STM_8MBIT_SIGNATURE 0x13
666 +#define STM_M25P80_BYTE_COUNT 1048576
667 +#define STM_M25P80_SECTOR_COUNT 16
668 +#define STM_M25P80_SECTOR_SIZE 0x10000
670 +#define STM_16MBIT_SIGNATURE 0x14
671 +#define STM_M25P16_BYTE_COUNT 2097152
672 +#define STM_M25P16_SECTOR_COUNT 32
673 +#define STM_M25P16_SECTOR_SIZE 0x10000
675 +#define STM_32MBIT_SIGNATURE 0x15
676 +#define STM_M25P32_BYTE_COUNT 4194304
677 +#define STM_M25P32_SECTOR_COUNT 64
678 +#define STM_M25P32_SECTOR_SIZE 0x10000
680 +#define STM_64MBIT_SIGNATURE 0x16
681 +#define STM_M25P64_BYTE_COUNT 8388608
682 +#define STM_M25P64_SECTOR_COUNT 128
683 +#define STM_M25P64_SECTOR_SIZE 0x10000
685 +#define STM_1MB_BYTE_COUNT STM_M25P80_BYTE_COUNT
686 +#define STM_1MB_SECTOR_COUNT STM_M25P80_SECTOR_COUNT
687 +#define STM_1MB_SECTOR_SIZE STM_M25P80_SECTOR_SIZE
688 +#define STM_2MB_BYTE_COUNT STM_M25P16_BYTE_COUNT
689 +#define STM_2MB_SECTOR_COUNT STM_M25P16_SECTOR_COUNT
690 +#define STM_2MB_SECTOR_SIZE STM_M25P16_SECTOR_SIZE
691 +#define STM_4MB_BYTE_COUNT STM_M25P32_BYTE_COUNT
692 +#define STM_4MB_SECTOR_COUNT STM_M25P32_SECTOR_COUNT
693 +#define STM_4MB_SECTOR_SIZE STM_M25P32_SECTOR_SIZE
694 +#define STM_8MB_BYTE_COUNT STM_M25P64_BYTE_COUNT
695 +#define STM_8MB_SECTOR_COUNT STM_M25P64_SECTOR_COUNT
696 +#define STM_8MB_SECTOR_SIZE STM_M25P64_SECTOR_SIZE
699 + * ST Microelectronics Opcodes for Serial Flash
702 +#define STM_OP_WR_ENABLE 0x06 /* Write Enable */
703 +#define STM_OP_WR_DISABLE 0x04 /* Write Disable */
704 +#define STM_OP_RD_STATUS 0x05 /* Read Status */
705 +#define STM_OP_WR_STATUS 0x01 /* Write Status */
706 +#define STM_OP_RD_DATA 0x03 /* Read Data */
707 +#define STM_OP_FAST_RD_DATA 0x0b /* Fast Read Data */
708 +#define STM_OP_PAGE_PGRM 0x02 /* Page Program */
709 +#define STM_OP_SECTOR_ERASE 0xd8 /* Sector Erase */
710 +#define STM_OP_BULK_ERASE 0xc7 /* Bulk Erase */
711 +#define STM_OP_DEEP_PWRDOWN 0xb9 /* Deep Power-Down Mode */
712 +#define STM_OP_RD_SIG 0xab /* Read Electronic Signature */
714 +#define STM_STATUS_WIP 0x01 /* Write-In-Progress */
715 +#define STM_STATUS_WEL 0x02 /* Write Enable Latch */
716 +#define STM_STATUS_BP0 0x04 /* Block Protect 0 */
717 +#define STM_STATUS_BP1 0x08 /* Block Protect 1 */
718 +#define STM_STATUS_BP2 0x10 /* Block Protect 2 */
719 +#define STM_STATUS_SRWD 0x80 /* Status Register Write Disable */
722 + * SPI Flash Interface Registers
724 +#define AR531XPLUS_SPI_READ 0x08000000
725 +#define AR531XPLUS_SPI_MMR 0x11300000
726 +#define AR531XPLUS_SPI_MMR_SIZE 12
728 +#define AR531XPLUS_SPI_CTL 0x00
729 +#define AR531XPLUS_SPI_OPCODE 0x04
730 +#define AR531XPLUS_SPI_DATA 0x08
732 +#define SPI_FLASH_READ AR531XPLUS_SPI_READ
733 +#define SPI_FLASH_MMR AR531XPLUS_SPI_MMR
734 +#define SPI_FLASH_MMR_SIZE AR531XPLUS_SPI_MMR_SIZE
735 +#define SPI_FLASH_CTL AR531XPLUS_SPI_CTL
736 +#define SPI_FLASH_OPCODE AR531XPLUS_SPI_OPCODE
737 +#define SPI_FLASH_DATA AR531XPLUS_SPI_DATA
739 +#define SPI_CTL_START 0x00000100
740 +#define SPI_CTL_BUSY 0x00010000
741 +#define SPI_CTL_TXCNT_MASK 0x0000000f
742 +#define SPI_CTL_RXCNT_MASK 0x000000f0
743 +#define SPI_CTL_TX_RX_CNT_MASK 0x000000ff
744 +#define SPI_CTL_SIZE_MASK 0x00060000
746 +#define SPI_CTL_CLK_SEL_MASK 0x03000000
747 +#define SPI_OPCODE_MASK 0x000000ff
749 +#define SPI_STATUS_WIP STM_STATUS_WIP