QCA provided 32M support for board956x.
This is raw version QCA patched for board956x to support 32M.
Keep it untouchd in the CL.
Change-Id: I0097c3683133f8f438ad2d8fdbd8ab2f1c458011
diff --git a/board/atheros/common/ath_flash.c b/board/atheros/common/ath_flash.c
index ee4bf1d..e89c89b 100755
--- a/board/atheros/common/ath_flash.c
+++ b/board/atheros/common/ath_flash.c
@@ -25,6 +25,10 @@
# define ath_spi_flash_print_info flash_print_info
#endif
+#if ENABLE_EXT_ADDR_SUPPORT
+/* for legacy flash only support 16M */
+#define LEGACY_SPI_ADDR_BOUNDARY 0x1000000
+#endif
/*
* globals
*/
@@ -40,6 +44,11 @@
#endif
static void ath_spi_sector_erase(uint32_t addr);
+#if ENABLE_EXT_ADDR_SUPPORT
+static void ath_spi_wrear(uint32_t data);
+static uchar ath_spi_rdear(void);
+#endif
+
static void
ath_spi_read_id(void)
{
@@ -141,11 +150,10 @@
}
int
-write_buff(flash_info_t *info, uchar *src, ulong dst, ulong len)
+ath_write_buff(flash_info_t *info, uchar *src, ulong dst, ulong len)
{
uint32_t val;
- dst = dst - CFG_FLASH_BASE;
printf("write len: %lu dst: 0x%x src: %p\n", len, dst, src);
for (; len; len--, dst++, src++) {
@@ -174,14 +182,13 @@
}
#else
int
-write_buff(flash_info_t *info, uchar *source, ulong addr, ulong len)
+ath_write_buff(flash_info_t *info, uchar *source, ulong addr, ulong len)
{
int total = 0, len_this_lp, bytes_this_page;
ulong dst;
uchar *src;
printf("write addr: %x\n", addr);
- addr = addr - CFG_FLASH_BASE;
while (total < len) {
src = source + total;
@@ -201,6 +208,75 @@
}
#endif
+int
+write_buff(flash_info_t *info, uchar *source, ulong addr, ulong len)
+{
+ return(ath_write_buff(info, source, addr - CFG_FLASH_BASE, len));
+}
+
+#if ENABLE_EXT_ADDR_SUPPORT
+int
+read_buff_ext(flash_info_t *info, uchar *buf, ulong offset, ulong len)
+{
+ ulong i = 0;
+ uint32_t curr_addr = offset;
+ uint32_t ori_ear = (uint32_t)ath_spi_rdear();
+ uint32_t new_ear;
+
+ while (i < len) {
+ new_ear = curr_addr >> 24;
+ ath_spi_wrear(new_ear);
+ ath_spi_write_enable();
+ ath_spi_bit_banger(ATH_SPI_CMD_READ);
+ ath_spi_send_addr(curr_addr);
+ do {
+ ath_spi_delay_8();
+ *(buf + i++) = (uchar) (ath_reg_rd(ATH_SPI_RD_STATUS));
+ /* Update the extended adress update if it's a multiple of 16M */
+ if (!((++ curr_addr) & (LEGACY_SPI_ADDR_BOUNDARY - 1))) {
+ break;
+ }
+ } while (i < len);
+ ath_spi_go();
+ }
+ if (new_ear != ori_ear) {
+ ath_spi_wrear(ori_ear);
+ }
+ ath_spi_done();
+ return 0;
+}
+
+int
+write_buff_ext(flash_info_t *info, uchar *source, ulong offset, ulong len)
+{
+ int status;
+ uint32_t ori_ear = (uint32_t)ath_spi_rdear();
+ uint32_t new_ear = 0;
+ uint32_t curr_addr = offset;
+ uint32_t bytes_this_16M, total = 0;
+
+ while (len) {
+ new_ear = curr_addr >> 24;
+ ath_spi_wrear(new_ear);
+ bytes_this_16M = LEGACY_SPI_ADDR_BOUNDARY - curr_addr % LEGACY_SPI_ADDR_BOUNDARY;
+ bytes_this_16M = (bytes_this_16M < len) ? bytes_this_16M : len;
+ if((status = ath_write_buff(info, source + total, curr_addr, bytes_this_16M)) != ERR_OK) {
+ printf("failed to write 0x%x bytes to 0x%x\n", bytes_this_16M, curr_addr);
+ break;
+ }
+ curr_addr += bytes_this_16M;
+ total += bytes_this_16M;
+ len -= bytes_this_16M;
+ }
+ if (new_ear != ori_ear) {
+ ath_spi_wrear(ori_ear);
+ }
+ ath_spi_done();
+
+ return(status);
+}
+#endif /* #if ENABLE_EXT_ADDR_SUPPORT */
+
static void
ath_spi_write_enable()
{
@@ -219,10 +295,40 @@
ath_reg_wr_nf(ATH_SPI_WRITE, ATH_SPI_CS_DIS);
ath_spi_bit_banger(ATH_SPI_CMD_RD_STATUS);
ath_spi_delay_8();
+ // Back ported bug fix, always write CE_LOW, CS_DIS before poll.
+ ath_spi_go();
rd = (ath_reg_rd(ATH_SPI_RD_STATUS) & 1);
} while (rd);
}
+#if ENABLE_EXT_ADDR_SUPPORT
+static void
+ath_spi_wrear(uint32_t data)
+{
+ ath_spi_write_enable();
+ ath_spi_bit_banger(ATH_SPI_CMD_WREAR);
+ ath_spi_bit_banger((uchar)data);
+ ath_spi_go();
+
+ ath_spi_poll();
+}
+
+static uchar
+ath_spi_rdear(void)
+{
+ uchar data;
+
+ ath_spi_write_enable();
+ ath_spi_bit_banger(ATH_SPI_CMD_RDEAR);
+ ath_spi_delay_8();
+ ath_spi_go();
+ data = (uchar)(ath_reg_rd(ATH_SPI_RD_STATUS));
+ ath_spi_poll();
+ return(data);
+}
+
+#endif /* #if ENABLE_EXT_ADDR_SUPPORT */
+
#if !defined(ATH_SST_FLASH)
static void
ath_spi_write_page(uint32_t addr, uint8_t *data, int len)
@@ -250,12 +356,24 @@
static void
ath_spi_sector_erase(uint32_t addr)
{
+#if ENABLE_EXT_ADDR_SUPPORT
+ uint32_t ori_ear = (uint32_t)ath_spi_rdear();
+ uint32_t new_ear = addr >> 24;
+
+ if(new_ear != ori_ear)
+ ath_spi_wrear(new_ear);
+#endif
ath_spi_write_enable();
ath_spi_bit_banger(ATH_SPI_CMD_SECTOR_ERASE);
ath_spi_send_addr(addr);
ath_spi_go();
display(0x7d);
ath_spi_poll();
+#if ENABLE_EXT_ADDR_SUPPORT
+ /* recover extended address register */
+ if(new_ear != ori_ear)
+ ath_spi_wrear(ori_ear);
+#endif
}
#ifdef ATH_DUAL_FLASH
diff --git a/common/cmd_flash.c b/common/cmd_flash.c
index ecc10b5..6a5263c 100755
--- a/common/cmd_flash.c
+++ b/common/cmd_flash.c
@@ -307,6 +307,106 @@
}
#endif /* #ifndef COMPRESSED_UBOOT */
+#if ENABLE_EXT_ADDR_SUPPORT
+int do_flread_ext (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ flash_info_t *info;
+ ulong buf, offset, len;
+ int bank = 1;
+
+ if (argc < 4) {
+ printf ("Usage:\n%s\n%s\n", cmdtp->usage, cmdtp->help);
+ return 1;
+ }
+ buf = simple_strtoul(argv[1], NULL, 16);
+ offset = simple_strtoul(argv[2], NULL, 16);
+ len = simple_strtoul(argv[3], NULL, 16);
+ if (argc > 4) {
+ bank = simple_strtoul(argv[4], NULL, 16);
+ if ((bank < 1) || (bank > CFG_MAX_FLASH_BANKS)) {
+ printf ("Only FLASH Banks # 1 ... # %d supported\n",
+ CFG_MAX_FLASH_BANKS);
+ return 1;
+ }
+ }
+ info = &flash_info[bank - 1];
+
+ if ((offset + len) > info->size){
+ printf ("Bad parameters, 'offset' + 'len' should < 0x%x\n", info->size);
+ return 1;
+ }
+ return(read_buff_ext(info, (uchar *)buf, offset, len));
+}
+
+int do_flwrite_ext (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ flash_info_t *info;
+ ulong source, offset, len;
+ int bank = 1;
+
+ if (argc < 4) {
+ printf ("Usage:\n%s\n%s\n", cmdtp->usage, cmdtp->help);
+ return 1;
+ }
+ source = simple_strtoul(argv[1], NULL, 16);
+ offset = simple_strtoul(argv[2], NULL, 16);
+ len = simple_strtoul(argv[3], NULL, 16);
+ if (argc > 4) {
+ bank = simple_strtoul(argv[4], NULL, 16);
+ if ((bank < 1) || (bank > CFG_MAX_FLASH_BANKS)) {
+ printf ("Only FLASH Banks # 1 ... # %d supported\n",
+ CFG_MAX_FLASH_BANKS);
+ return 1;
+ }
+ }
+
+ info = &flash_info[bank - 1];
+ if ((offset + len) > info->size){
+ printf ("Bad parameters, 'offset' + 'len' should < 0x%x\n", info->size);
+ return 1;
+ }
+
+ return(write_buff_ext(info, (uchar *)source, offset, len));
+}
+
+int do_flerase_ext (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ flash_info_t *info;
+ ulong offset, len;
+ int sect_first, sect_last, sect_size;
+ int bank = 1;
+
+ if (argc < 3) {
+ printf ("Usage:\n%s\n%s\n", cmdtp->usage, cmdtp->help);
+ return 1;
+ }
+ offset = simple_strtoul(argv[1], NULL, 16);
+ len = simple_strtoul(argv[2], NULL, 16);
+
+ if (argc > 4) {
+ bank = simple_strtoul(argv[4], NULL, 16);
+ if ((bank < 1) || (bank > CFG_MAX_FLASH_BANKS)) {
+ printf ("Only FLASH Banks # 1 ... # %d supported\n",
+ CFG_MAX_FLASH_BANKS);
+ return 1;
+ }
+ }
+
+ info = &flash_info[bank - 1];
+ if ((offset + len) > info->size){
+ printf ("Bad parameters, 'offset' + 'len' should < 0x%x\n", info->size);
+ return 1;
+ }
+ sect_size = info->size / info->sector_count;
+ sect_first = offset / sect_size;
+ sect_last = (offset + len - 1) / sect_size;
+ printf("flash size:0x%x offset:0x%x len:0x%x sect_size:0x%x first:0x%x last:0x%x\n",
+ info->size, offset, len, sect_size, sect_first, sect_last);
+
+ return(flash_erase(info, sect_first, sect_last));
+}
+#endif /* #if ENABLE_EXT_ADDR_SUPPORT */
+
int do_flerase (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
flash_info_t *info;
@@ -744,7 +844,31 @@
"erase all\n - erase all FLASH banks\n"
);
+#if ENABLE_EXT_ADDR_SUPPORT
+U_BOOT_CMD(
+ read_ext, 5, 1, do_flread_ext,
+ "read_ext - read SPI NOR FLASH memory(0-32M space)\n",
+ "read_ext dst offset(offset of the flash) len [N]\n"
+ " - read 'len' bytes from FLASH bank #N addr 'start' to memory addr 'dst'\n"
+ " - 'N' is optional, default the first bank\n"
+ );
+U_BOOT_CMD(
+ erase_ext, 4, 1, do_flerase_ext,
+ "erase_ext - erase SPI NOR FLASH memory(0-32M space)\n",
+ "erase_ext start(offset of the flash) len [N]\n"
+ " - erase FLASH bank #N from addr 'start' to the end of sect addr 'start'+'len'-1\n"
+ " - 'N' is optional, default the first bank\n"
+ );
+
+U_BOOT_CMD(
+ write_ext, 5, 1, do_flwrite_ext,
+ "write_ext - write SPI NOR FLASH memory(0-32M space)\n",
+ "write_ext src dst(offset of the flash) len [N]\n"
+ " - copy 'len' bytes from memory addr 'src' to FLASH bank #N addr 'start'\n"
+ " - 'N' is optional, default the first bank\n"
+ );
+#endif /* #if ENABLE_EXT_ADDR_SUPPORT */
#undef TMP_ERASE
#undef TMP_PROT_ON
diff --git a/include/956x.h b/include/956x.h
index 5788cb2..161fb40 100755
--- a/include/956x.h
+++ b/include/956x.h
@@ -3511,6 +3511,8 @@
#define ATH_SPI_CS_DIS 0x70000
#define ATH_SPI_CE_LOW 0x60000
#define ATH_SPI_CE_HIGH 0x60100
+#define ATH_SPI_CD_LOW 0x70000
+#define ATH_SPI_CD_HIGH 0x70100
#define ATH_SPI_SECTOR_SIZE (1024*64)
#define ATH_SPI_PAGE_SIZE 256
@@ -3533,6 +3535,15 @@
#define ATH_SPI_CMD_SECTOR_ERASE 0xd8
#define ATH_SPI_CMD_CHIP_ERASE 0xc7
#define ATH_SPI_CMD_RDID 0x9f
+/* commands for 32MB and above */
+#define ATH_SPI_CMD_WREAR 0xC5
+#define ATH_SPI_CMD_RDEAR 0xC8
+#define ATH_SPI_CMD_READ 0x03
+#define ATH_SPI_CMD_EN4B 0xB7
+#define ATH_SPI_CMD_EX4B 0xE9
+#define ATH_SPI_CMD_WRDIS 0x04
+#define ATH_SPI_CMD_RD_STATUS_2 0x35
+#define ATH_SPI_CMD_RD_STATUS_3 0x15
#if defined(CFG_ATH_EMULATION)
diff --git a/include/configs/board956x.h b/include/configs/board956x.h
index 3e0e58e..a8ce12d 100755
--- a/include/configs/board956x.h
+++ b/include/configs/board956x.h
@@ -38,7 +38,10 @@
* FLASH and environment organization
*/
#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
-#if (FLASH_SIZE == 16)
+#if (FLASH_SIZE == 32)
+#define CFG_MAX_FLASH_SECT 512 /* max number of sectors on one chip */
+#define ATH_MTDPARTS_MIB0 "64k(mib0)"
+#elif (FLASH_SIZE == 16)
#define CFG_MAX_FLASH_SECT 256 /* max number of sectors on one chip */
#define ATH_MTDPARTS_MIB0 "64k(mib0)"
#elif (FLASH_SIZE == 8)
@@ -50,7 +53,9 @@
#endif
#define CFG_FLASH_SECTOR_SIZE (64*1024)
-#if (FLASH_SIZE == 16)
+#if (FLASH_SIZE == 32)
+#define CFG_FLASH_SIZE 0x02000000 /* Total flash size */
+#elif (FLASH_SIZE == 16)
#define CFG_FLASH_SIZE 0x01000000 /* Total flash size */
#elif (FLASH_SIZE == 8)
#define CFG_FLASH_SIZE 0x00800000 /* max number of sectors on one chip */
@@ -190,7 +195,14 @@
*/
# define MTDPARTS_DEFAULT "mtdparts=ath-nor0:32k(u-boot1),32k(u-boot2),3008k(rootfs),896k(uImage),64k(mib0),64k(ART)"
# else
-#if (FLASH_SIZE == 16) /*FLASH SIZE */
+#if (FLASH_SIZE == 32) /*FLASH SIZE */
+# define ATH_F_FILE fs_name(${bc}-jffs2)
+# define ATH_F_LEN $filesize
+# define ATH_F_ADDR 0x9f050000
+# define ATH_K_FILE vmlinux${bc}.lzma.uImage
+# define ATH_K_ADDR 0x9fe80000
+# define MTDPARTS_DEFAULT "mtdparts=ath-nor0:256k(u-boot),64k(u-boot-env),14528k(rootfs),1408k(uImage),64k(mib0),64k(ART),16m(test)"
+#elif (FLASH_SIZE == 16) /*FLASH SIZE */
# define ATH_F_FILE fs_name(${bc}-jffs2)
# define ATH_F_LEN 0xE30000
# define ATH_F_ADDR 0x9f050000
diff --git a/include/flash.h b/include/flash.h
index d9955e0..4978f7d 100755
--- a/include/flash.h
+++ b/include/flash.h
@@ -89,6 +89,10 @@
extern int flash_write (char *, ulong, ulong);
extern flash_info_t *addr2info (ulong);
extern int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt);
+#if ENABLE_EXT_ADDR_SUPPORT
+extern int write_buff_ext (flash_info_t *info, uchar *src, ulong offset, ulong cnt);
+extern int read_buff_ext (flash_info_t *info, uchar *buf, ulong offset, ulong cnt);
+#endif
/* board/?/flash.c */
#if defined(CFG_FLASH_PROTECTION)