diff options
author | Felix Fietkau <nbd@openwrt.org> | 2010-06-26 20:41:59 +0000 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2010-06-26 20:41:59 +0000 |
commit | d3ec4c6f75195bf79f15804024036a5eb6c0b94d (patch) | |
tree | 1c3c36fd5f358bb19c2b181de417425f68444d82 /target/linux/brcm-2.4/files/arch/mips/bcm947xx/sflash.c | |
parent | 19a9284b9a6fd60ac78a129052cc677a39abf3cb (diff) | |
download | master-187ad058-d3ec4c6f75195bf79f15804024036a5eb6c0b94d.tar.gz master-187ad058-d3ec4c6f75195bf79f15804024036a5eb6c0b94d.tar.bz2 master-187ad058-d3ec4c6f75195bf79f15804024036a5eb6c0b94d.zip |
remove the brcm-2.4 target, it will no longer be supported in future releases. please use brcm47xx with broadcom-wl instead
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@21946 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/brcm-2.4/files/arch/mips/bcm947xx/sflash.c')
-rw-r--r-- | target/linux/brcm-2.4/files/arch/mips/bcm947xx/sflash.c | 508 |
1 files changed, 0 insertions, 508 deletions
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/sflash.c b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/sflash.c deleted file mode 100644 index 9bfb8b42a2..0000000000 --- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/sflash.c +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Broadcom SiliconBackplane chipcommon serial flash interface - * - * Copyright 2007, Broadcom Corporation - * All Rights Reserved. - * - * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY - * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM - * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. - * - * $Id$ - */ - -#include <typedefs.h> -#include <osl.h> -#include "include/bcmutils.h" -#include <sbutils.h> -#include <sbconfig.h> -#include <sbchipc.h> -#include <bcmdevs.h> -#include <sflash.h> - -/* Private global state */ -static struct sflash sflash; - -/* Issue a serial flash command */ -static INLINE void -sflash_cmd(osl_t *osh, chipcregs_t *cc, uint opcode) -{ - W_REG(osh, &cc->flashcontrol, SFLASH_START | opcode); - while (R_REG(osh, &cc->flashcontrol) & SFLASH_BUSY); -} - -/* Initialize serial flash access */ -struct sflash * -sflash_init(sb_t *sbh, chipcregs_t *cc) -{ - uint32 id, id2; - osl_t *osh; - - ASSERT(sbh); - - osh = sb_osh(sbh); - - bzero(&sflash, sizeof(sflash)); - - sflash.type = sbh->cccaps & CC_CAP_FLASH_MASK; - - switch (sflash.type) { - case SFLASH_ST: - /* Probe for ST chips */ - sflash_cmd(osh, cc, SFLASH_ST_DP); - sflash_cmd(osh, cc, SFLASH_ST_RES); - id = R_REG(osh, &cc->flashdata); - switch (id) { - case 0x11: - /* ST M25P20 2 Mbit Serial Flash */ - sflash.blocksize = 64 * 1024; - sflash.numblocks = 4; - break; - case 0x12: - /* ST M25P40 4 Mbit Serial Flash */ - sflash.blocksize = 64 * 1024; - sflash.numblocks = 8; - break; - case 0x13: - /* ST M25P80 8 Mbit Serial Flash */ - sflash.blocksize = 64 * 1024; - sflash.numblocks = 16; - break; - case 0x14: - /* ST M25P16 16 Mbit Serial Flash */ - sflash.blocksize = 64 * 1024; - sflash.numblocks = 32; - break; - case 0x15: - /* ST M25P32 32 Mbit Serial Flash */ - sflash.blocksize = 64 * 1024; - sflash.numblocks = 64; - break; - case 0x16: - /* ST M25P64 64 Mbit Serial Flash */ - sflash.blocksize = 64 * 1024; - sflash.numblocks = 128; - break; - case 0xbf: - W_REG(osh, &cc->flashaddress, 1); - sflash_cmd(osh, cc, SFLASH_ST_RES); - id2 = R_REG(osh, &cc->flashdata); - if (id2 == 0x44) { - /* SST M25VF80 4 Mbit Serial Flash */ - sflash.blocksize = 64 * 1024; - sflash.numblocks = 8; - } - break; - } - break; - - case SFLASH_AT: - /* Probe for Atmel chips */ - sflash_cmd(osh, cc, SFLASH_AT_STATUS); - id = R_REG(osh, &cc->flashdata) & 0x3c; - switch (id) { - case 0xc: - /* Atmel AT45DB011 1Mbit Serial Flash */ - sflash.blocksize = 256; - sflash.numblocks = 512; - break; - case 0x14: - /* Atmel AT45DB021 2Mbit Serial Flash */ - sflash.blocksize = 256; - sflash.numblocks = 1024; - break; - case 0x1c: - /* Atmel AT45DB041 4Mbit Serial Flash */ - sflash.blocksize = 256; - sflash.numblocks = 2048; - break; - case 0x24: - /* Atmel AT45DB081 8Mbit Serial Flash */ - sflash.blocksize = 256; - sflash.numblocks = 4096; - break; - case 0x2c: - /* Atmel AT45DB161 16Mbit Serial Flash */ - sflash.blocksize = 512; - sflash.numblocks = 4096; - break; - case 0x34: - /* Atmel AT45DB321 32Mbit Serial Flash */ - sflash.blocksize = 512; - sflash.numblocks = 8192; - break; - case 0x3c: - /* Atmel AT45DB642 64Mbit Serial Flash */ - sflash.blocksize = 1024; - sflash.numblocks = 8192; - break; - } - break; - } - - sflash.size = sflash.blocksize * sflash.numblocks; - return sflash.size ? &sflash : NULL; -} - -/* Read len bytes starting at offset into buf. Returns number of bytes read. */ -int -sflash_read(sb_t *sbh, chipcregs_t *cc, uint offset, uint len, uchar *buf) -{ - uint8 *from, *to; - int cnt, i; - osl_t *osh; - - ASSERT(sbh); - - if (!len) - return 0; - - if ((offset + len) > sflash.size) - return -22; - - if ((len >= 4) && (offset & 3)) - cnt = 4 - (offset & 3); - else if ((len >= 4) && ((uintptr)buf & 3)) - cnt = 4 - ((uintptr)buf & 3); - else - cnt = len; - - osh = sb_osh(sbh); - - from = (uint8 *)(uintptr)OSL_UNCACHED(SB_FLASH2 + offset); - to = (uint8 *)buf; - - if (cnt < 4) { - for (i = 0; i < cnt; i ++) { - *to = R_REG(osh, from); - from ++; - to ++; - } - return cnt; - } - - while (cnt >= 4) { - *(uint32 *)to = R_REG(osh, (uint32 *)from); - from += 4; - to += 4; - cnt -= 4; - } - - return (len - cnt); -} - -/* Poll for command completion. Returns zero when complete. */ -int -sflash_poll(sb_t *sbh, chipcregs_t *cc, uint offset) -{ - osl_t *osh; - - ASSERT(sbh); - - osh = sb_osh(sbh); - - if (offset >= sflash.size) - return -22; - - switch (sflash.type) { - case SFLASH_ST: - /* Check for ST Write In Progress bit */ - sflash_cmd(osh, cc, SFLASH_ST_RDSR); - return R_REG(osh, &cc->flashdata) & SFLASH_ST_WIP; - case SFLASH_AT: - /* Check for Atmel Ready bit */ - sflash_cmd(osh, cc, SFLASH_AT_STATUS); - return !(R_REG(osh, &cc->flashdata) & SFLASH_AT_READY); - } - - return 0; -} - -/* Write len bytes starting at offset into buf. Returns number of bytes - * written. Caller should poll for completion. - */ -int -sflash_write(sb_t *sbh, chipcregs_t *cc, uint offset, uint len, const uchar *buf) -{ - struct sflash *sfl; - int ret = 0; - bool is4712b0; - uint32 page, byte, mask; - osl_t *osh; - - ASSERT(sbh); - - osh = sb_osh(sbh); - - if (!len) - return 0; - - if ((offset + len) > sflash.size) - return -22; - - sfl = &sflash; - switch (sfl->type) { - case SFLASH_ST: - is4712b0 = (sbh->chip == BCM4712_CHIP_ID) && (sbh->chiprev == 3); - /* Enable writes */ - sflash_cmd(osh, cc, SFLASH_ST_WREN); - if (is4712b0) { - mask = 1 << 14; - W_REG(osh, &cc->flashaddress, offset); - W_REG(osh, &cc->flashdata, *buf++); - /* Set chip select */ - OR_REG(osh, &cc->gpioout, mask); - /* Issue a page program with the first byte */ - sflash_cmd(osh, cc, SFLASH_ST_PP); - ret = 1; - offset++; - len--; - while (len > 0) { - if ((offset & 255) == 0) { - /* Page boundary, drop cs and return */ - AND_REG(osh, &cc->gpioout, ~mask); - if (!sflash_poll(sbh, cc, offset)) { - /* Flash rejected command */ - return -11; - } - return ret; - } else { - /* Write single byte */ - sflash_cmd(osh, cc, *buf++); - } - ret++; - offset++; - len--; - } - /* All done, drop cs if needed */ - if ((offset & 255) != 1) { - /* Drop cs */ - AND_REG(osh, &cc->gpioout, ~mask); - if (!sflash_poll(sbh, cc, offset)) { - /* Flash rejected command */ - return -12; - } - } - } else if ( (sbh->ccrev >= 20) && (len != 1) ) { - //} else if ( sbh->ccrev >= 20 ) { /* foxconn modified by EricHuang, 05/24/2007 */ - W_REG(NULL, &cc->flashaddress, offset); - W_REG(NULL, &cc->flashdata, *buf++); - /* Issue a page program with CSA bit set */ - sflash_cmd(osh, cc, SFLASH_ST_CSA | SFLASH_ST_PP); - ret = 1; - offset++; - len--; - while (len > 0) { - if ((offset & 255) == 0) { - /* Page boundary, poll droping cs and return */ - W_REG(NULL, &cc->flashcontrol, 0); - /* wklin added start, 06/08/2007 */ - W_REG(NULL, &cc->flashcontrol, 0); - OSL_DELAY(1); - /* wklin added end, 06/08/2007 */ - /* wklin rmeoved start, 06/08/2007 */ -#if 0 - if (!sflash_poll(sbh, cc, offset)) { - /* Flash rejected command */ - return -11; - } -#endif - /* wklin removed end, 06/08/2007 */ - return ret; - } else { - /* Write single byte */ - sflash_cmd(osh, cc, SFLASH_ST_CSA | *buf++); - } - ret++; - offset++; - len--; - } - /* All done, drop cs if needed */ - if ((offset & 255) != 1) { - /* Drop cs, poll */ - W_REG(NULL, &cc->flashcontrol, 0); - /* wklin added start, 06/08/2007 */ - W_REG(NULL, &cc->flashcontrol, 0); - OSL_DELAY(1); - /* wklin added end, 06/08/2007 */ - /* wklin removed start, 06/08/2007 */ -#if 0 - if (!sflash_poll(sbh, cc, offset)) { - /* Flash rejected command */ - return -12; - } -#endif - /* wklin removed end, 06/08/2007 */ - } - } else { - ret = 1; - W_REG(osh, &cc->flashaddress, offset); - W_REG(osh, &cc->flashdata, *buf); - /* Page program */ - sflash_cmd(osh, cc, SFLASH_ST_PP); - } - break; - case SFLASH_AT: - mask = sfl->blocksize - 1; - page = (offset & ~mask) << 1; - byte = offset & mask; - /* Read main memory page into buffer 1 */ - if (byte || (len < sfl->blocksize)) { - W_REG(osh, &cc->flashaddress, page); - sflash_cmd(osh, cc, SFLASH_AT_BUF1_LOAD); - /* 250 us for AT45DB321B */ - SPINWAIT(sflash_poll(sbh, cc, offset), 1000); - ASSERT(!sflash_poll(sbh, cc, offset)); - } - /* Write into buffer 1 */ - for (ret = 0; (ret < (int)len) && (byte < sfl->blocksize); ret++) { - W_REG(osh, &cc->flashaddress, byte++); - W_REG(osh, &cc->flashdata, *buf++); - sflash_cmd(osh, cc, SFLASH_AT_BUF1_WRITE); - } - /* Write buffer 1 into main memory page */ - W_REG(osh, &cc->flashaddress, page); - sflash_cmd(osh, cc, SFLASH_AT_BUF1_PROGRAM); - break; - } - - return ret; -} - -/* Erase a region. Returns number of bytes scheduled for erasure. - * Caller should poll for completion. - */ -int -sflash_erase(sb_t *sbh, chipcregs_t *cc, uint offset) -{ - struct sflash *sfl; - osl_t *osh; - - ASSERT(sbh); - - osh = sb_osh(sbh); - - if (offset >= sflash.size) - return -22; - - sfl = &sflash; - switch (sfl->type) { - case SFLASH_ST: - sflash_cmd(osh, cc, SFLASH_ST_WREN); - W_REG(osh, &cc->flashaddress, offset); - sflash_cmd(osh, cc, SFLASH_ST_SE); - return sfl->blocksize; - case SFLASH_AT: - W_REG(osh, &cc->flashaddress, offset << 1); - sflash_cmd(osh, cc, SFLASH_AT_PAGE_ERASE); - return sfl->blocksize; - } - - return 0; -} - -/* - * writes the appropriate range of flash, a NULL buf simply erases - * the region of flash - */ -int -sflash_commit(sb_t *sbh, chipcregs_t *cc, uint offset, uint len, const uchar *buf) -{ - struct sflash *sfl; - uchar *block = NULL, *cur_ptr, *blk_ptr; - uint blocksize = 0, mask, cur_offset, cur_length, cur_retlen, remainder; - uint blk_offset, blk_len, copied; - int bytes, ret = 0; - osl_t *osh; - - ASSERT(sbh); - - osh = sb_osh(sbh); - - /* Check address range */ - if (len <= 0) - return 0; - - sfl = &sflash; - if ((offset + len) > sfl->size) - return -1; - - blocksize = sfl->blocksize; - mask = blocksize - 1; - - /* Allocate a block of mem */ - if (!(block = MALLOC(osh, blocksize))) - return -1; - - while (len) { - /* Align offset */ - cur_offset = offset & ~mask; - cur_length = blocksize; - cur_ptr = block; - - remainder = blocksize - (offset & mask); - if (len < remainder) - cur_retlen = len; - else - cur_retlen = remainder; - - /* buf == NULL means erase only */ - if (buf) { - /* Copy existing data into holding block if necessary */ - if ((offset & mask) || (len < blocksize)) { - blk_offset = cur_offset; - blk_len = cur_length; - blk_ptr = cur_ptr; - - /* Copy entire block */ - while (blk_len) { - copied = sflash_read(sbh, cc, blk_offset, blk_len, blk_ptr); - blk_offset += copied; - blk_len -= copied; - blk_ptr += copied; - } - } - - /* Copy input data into holding block */ - memcpy(cur_ptr + (offset & mask), buf, cur_retlen); - } - - /* Erase block */ - if ((ret = sflash_erase(sbh, cc, (uint) cur_offset)) < 0) - goto done; - while (sflash_poll(sbh, cc, (uint) cur_offset)); - - /* buf == NULL means erase only */ - if (!buf) { - offset += cur_retlen; - len -= cur_retlen; - continue; - } - - /* Write holding block */ - while (cur_length > 0) { - if ((bytes = sflash_write(sbh, cc, - (uint) cur_offset, - (uint) cur_length, - (uchar *) cur_ptr)) < 0) { - ret = bytes; - goto done; - } - while (sflash_poll(sbh, cc, (uint) cur_offset)); - cur_offset += bytes; - cur_length -= bytes; - cur_ptr += bytes; - } - - offset += cur_retlen; - len -= cur_retlen; - buf += cur_retlen; - } - - ret = len; -done: - if (block) - MFREE(osh, block, blocksize); - return ret; -} |