void flash_wren(void) { uint8_t tx[8] = { FLASH_CMD_WREN, FLASH_CMD_WRDI }; struct spi_transfer td[] = { {NULL, &tx[0], 1 }, {NULL, &tx[1], 1} }; // spi_exchange(&td[1], 1); spi_exchange(&td[0], 1); flash_poll(FLASH_MOD_POLLWREN); }
static int flash_eraseblk(unsigned long addr) { unsigned long a; uint16 st; a = (unsigned long)addr; if (a >= flashutl_desc->size) return 1; a = block(a, BLOCK_BASE); /* Ensure blocks are unlocked (for intel chips) */ if (flashutl_cmd->type == BSC) { scmd((unsigned char)INTEL_UNLOCK1, a); scmd((unsigned char)INTEL_UNLOCK2, a); } if (flashutl_cmd->pre_erase) cmd(flashutl_cmd->pre_erase, CMD_ADDR); if (flashutl_cmd->erase_block) cmd(flashutl_cmd->erase_block, a); if (flashutl_cmd->confirm) scmd(flashutl_cmd->confirm, a); if (flashutl_wsz == sizeof(uint8)) st = flash_poll(a, 0xff); else st = flash_poll(a, 0xffff); flash_reset(); if (st) { DPRINT(("Erase of block 0x%08lx-0x%08lx failed\n", a, block((unsigned long)addr, BLOCK_LIM))); return st; } DPRINT(("Erase of block 0x%08lx-0x%08lx done\n", a, block((unsigned long)addr, BLOCK_LIM))); return 0; }
static int flash_write(unsigned long off, uint8 *src, uint nbytes) { uint8 *dest; uint16 st, data; uint i, len; ASSERT(flashutl_desc != NULL); if (off >= flashutl_desc->size) return 1; ASSERT(!(off & (flashutl_wsz - 1))); dest = (uint8*)FLASH_ADDR(off); st = 0; while (nbytes) { if ((flashutl_desc->type == SCS) && flashutl_cmd->write_buf && ((off & (WBUFSIZE - 1)) == 0)) { /* issue write command */ if (flashutl_cmd->write_buf) cmd(flashutl_cmd->write_buf, off); if ((st = flash_poll(off, DONE))) continue; len = MIN(nbytes, WBUFSIZE); #ifndef MIPSEB /* write (length - 1) */ cmd(len / sizeof(uint16) - 1, off); /* write data */ for (i = 0; i < len; i += sizeof(uint16), dest += sizeof(uint16), src += sizeof(uint16)) *(uint16 *)dest = *(uint16 *)src; #else /* * BCM4710 endianness is word consistent but * byte/short scrambled. This write buffer * mechanism appears to be sensitive to the * order of the addresses hence we need to * unscramble them. We may also need to pad * the source with two bytes of 0xffff in case * an odd number of shorts are presented. */ /* write (padded length - 1) */ cmd((ROUNDUP(len, sizeof(uint32)) / sizeof(uint16)) - 1, off); /* write data (plus pad if necessary) */ for (i = 0; i < ROUNDUP(len, sizeof(uint32)); i += sizeof(uint32), dest += sizeof(uint32), src += sizeof(uint32)) { *((uint16 *)dest + 1) = ((i + sizeof(uint16)) < len) ? *((uint16 *)src + 1) : 0xffff; *(uint16 *)dest = *(uint16 *)src; } #endif /* MIPSEB */ /* write confirm */ if (flashutl_cmd->confirm) cmd(flashutl_cmd->confirm, off); if ((st = flash_poll(off, DONE))) break; } else { /* issue write command */ if (flashutl_cmd->write_word) cmd(flashutl_cmd->write_word, CMD_ADDR); /* write data */ data = flash_readword((unsigned long)src); flash_writeword((unsigned long)dest, data); /* poll for done */ if ((st = flash_poll(off, data))) break; len = MIN(nbytes, flashutl_wsz); dest += len; src += len; } nbytes -= len; off += len; } flash_reset(); return st; }