int 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++) { ar7240_spi_write_enable(); // dont move this above 'for' ar7240_spi_bit_banger(AR7240_SPI_CMD_PAGE_PROG); ar7240_spi_send_addr(dst); val = *src & 0xff; ar7240_spi_bit_banger(val); ar7240_spi_go(); ar7240_spi_poll(); } /* * Disable the Function Select * Without this we can't read from the chip again */ ar7240_reg_wr(AR7240_SPI_FS, 0); if (len) { // how to differentiate errors ?? return ERR_PROG_ERROR; } else { return ERR_OK; } }
void ar7240_spi_flash_unblock(void) { ar7240_spi_write_enable(); ar7240_spi_bit_banger(AR7240_SPI_CMD_WRITE_SR); ar7240_spi_bit_banger(0x0); ar7240_spi_go(); ar7240_spi_poll(); }
/* * Returns JEDEC ID from SPI flash */ static ulong read_id(void){ unsigned int flashid = 0; ar7240_reg_wr_nf(AR7240_SPI_FS, 1); ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS); ar7240_spi_bit_banger(0x9F); ar7240_spi_delay_8(); ar7240_spi_delay_8(); ar7240_spi_delay_8(); ar7240_spi_delay_8(); flashid = ar7240_reg_rd(AR7240_SPI_RD_STATUS); /* * We have 3 bytes: * - manufacture ID (1b) * - product ID (2b) */ flashid = flashid >> 8; ar7240_spi_done(); return((ulong)flashid); }
static void ar7240_spi_sector_erase(uint32_t addr){ ar7240_spi_write_enable(); ar7240_spi_bit_banger(AR7240_SPI_CMD_SECTOR_ERASE); ar7240_spi_send_addr(addr); ar7240_spi_go(); ar7240_spi_poll(); }
static void ar7240_spi_write_page(uint32_t addr, uint8_t *data, int len){ int i; uint8_t ch; ar7240_spi_write_enable(); ar7240_spi_bit_banger(AR7240_SPI_CMD_PAGE_PROG); ar7240_spi_send_addr(addr); for(i = 0; i < len; i++){ ch = *(data + i); ar7240_spi_bit_banger(ch); } ar7240_spi_go(); ar7240_spi_poll(); }
static void ar7240_spi_erase_64k(uint32_t addr){ ar7240_spi_write_enable(); ar7240_spi_bit_banger(AR7240_SPI_CMD_BLOCK_ERASE); ar7240_spi_send_addr(addr); ar7240_spi_go(); ar7240_spi_poll(); }
static void ar7240_spi_write_enable() { ar7240_reg_wr_nf(AR7240_SPI_FS, 1); ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS); ar7240_spi_bit_banger(AR7240_SPI_CMD_WREN); ar7240_spi_go(); }
void ar7240_spi_flash_chip_erase(void) { ar7240_spi_write_enable(); ar7240_spi_bit_banger(AR7240_SPI_CMD_CHIP_ERASE); ar7240_spi_go(); ar7240_spi_poll(); }
static void ar7240_spi_poll(){ int rd; do { ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS); ar7240_spi_bit_banger(AR7240_SPI_CMD_RD_STATUS); ar7240_spi_delay_8(); rd = (ar7240_reg_rd(AR7240_SPI_RD_STATUS) & 1); } while(rd); }
static void read_id(void) { u32 rd = 0x777777; ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS); ar7240_spi_bit_banger(0x9f); ar7240_spi_delay_8(); ar7240_spi_delay_8(); ar7240_spi_delay_8(); ar7240_spi_done(); /* rd = ar7240_reg_rd(AR7240_SPI_RD_STATUS); */ rd = ar7240_reg_rd(AR7240_SPI_READ); printf("id read %#x\n", rd); }
static void ath_spi_read_id(void) { u32 rd = 0x777777; ar7240_reg_wr_nf(AR7240_SPI_WRITE, AR7240_SPI_CS_DIS); ar7240_spi_bit_banger(AR7240_SPI_CMD_RDID); ar7240_spi_delay_8(); ar7240_spi_delay_8(); ar7240_spi_delay_8(); ar7240_spi_go(); rd = ar7240_reg_rd(AR7240_SPI_RD_STATUS); printf("Flash Manuf Id 0x%x, DeviceId0 0x%x, DeviceId1 0x%x\n", (rd >> 16) & 0xff, (rd >> 8) & 0xff, (rd >> 0) & 0xff); }