flwr.c 4.44 KB
#include "cpusim.h"
#include "bbnand.h"

void
passed(void) {
    message("test flwrite passed\n");
    test_postamble();
}

void
failed(const char* code) {
    message("test flwrite failed (");
    message(code);
    message(")\n");
    test_postamble();
}

static inline int
flash_status(unsigned dev, unsigned offset, unsigned buffer) {
    IO_WRITE(PI_FLASH_ADDR_REG, offset << PI_FLASH_PAGE_ADDR_SHIFT);
    IO_WRITE(PI_FLASH_CTRL_REG, PI_FLASH_CTRL_START |
	    			PI_FLASH_CTRL_RDPH  |
				NAND_CMD_STATUS << PI_FLASH_CTRL_CMD_SHIFT |
				buffer << PI_FLASH_CTRL_BUF_SHIFT |
				dev << PI_FLASH_CTRL_DEV_SHIFT |
				1);
    do {
	if (IO_READ(MI_EINTR_REG)&MI_INTR_MD) return -1;
    } while(IO_READ(PI_FLASH_CTRL_REG)&PI_FLASH_CTRL_BUSY);
    return IO_READ(PI_BUFFER_BASE_REG+buffer*512+offset) >> 24;
}

static inline int
read_page(unsigned dev, unsigned addr, int which_buf) {
    IO_WRITE(PI_FLASH_ADDR_REG, addr << PI_FLASH_PAGE_ADDR_SHIFT);
    IO_WRITE(PI_FLASH_CTRL_REG, PI_FLASH_CTRL_START |
	    			PI_FLASH_CTRL_RDPH  |
				0xf << PI_FLASH_CTRL_ADPH_SHIFT |
				NAND_CMD_READ_0 << PI_FLASH_CTRL_CMD_SHIFT |
				PI_FLASH_CTRL_WRDY |
				which_buf << PI_FLASH_CTRL_BUF_SHIFT |
				dev << PI_FLASH_CTRL_DEV_SHIFT |
				PI_FLASH_CTRL_ECC |
				528);
    do {
	if (IO_READ(MI_EINTR_REG)&MI_INTR_MD) return 1;
    } while(IO_READ(PI_FLASH_CTRL_REG)&PI_FLASH_CTRL_BUSY);
    return (IO_READ(PI_FLASH_CTRL_REG) & PI_FLASH_CTRL_DBERR) ? 1 : 0;
}

static inline int
write_page(unsigned dev, unsigned addr, int which_buf) {
    IO_WRITE(PI_FLASH_ADDR_REG, addr << PI_FLASH_PAGE_ADDR_SHIFT);
    IO_WRITE(PI_FLASH_CTRL_REG, PI_FLASH_CTRL_START |
	    			PI_FLASH_CTRL_WDPH  |
				0xf << PI_FLASH_CTRL_ADPH_SHIFT |
				NAND_CMD_DATA_INPUT << PI_FLASH_CTRL_CMD_SHIFT |
				which_buf << PI_FLASH_CTRL_BUF_SHIFT |
				dev << PI_FLASH_CTRL_DEV_SHIFT |
				PI_FLASH_CTRL_ECC |
				528);
    do {
	if (IO_READ(MI_EINTR_REG)&MI_INTR_MD) return 1;
    } while(IO_READ(PI_FLASH_CTRL_REG)&PI_FLASH_CTRL_BUSY);
    IO_WRITE(PI_FLASH_CTRL_REG, PI_FLASH_CTRL_START |
				NAND_CMD_PROGRAM << PI_FLASH_CTRL_CMD_SHIFT |
				PI_FLASH_CTRL_WRDY |
				dev << PI_FLASH_CTRL_DEV_SHIFT);
    do {
	if (IO_READ(MI_EINTR_REG)&MI_INTR_MD) return 1;
    } while(IO_READ(PI_FLASH_CTRL_REG)&PI_FLASH_CTRL_BUSY);
    return flash_status(dev, 0, which_buf) != (NAND_STATUS_CMD_PASS|NAND_STATUS_WRITE_OK|NAND_STATUS_READY);
}

static inline int
erase_block(unsigned dev, unsigned int addr) {
    IO_WRITE(PI_FLASH_ADDR_REG, addr << PI_FLASH_PAGE_ADDR_SHIFT);
    IO_WRITE(PI_FLASH_CTRL_REG, PI_FLASH_CTRL_START |
				0xe << PI_FLASH_CTRL_ADPH_SHIFT |
				NAND_CMD_ERASE_0 << PI_FLASH_CTRL_CMD_SHIFT |
				dev << PI_FLASH_CTRL_DEV_SHIFT |
				PI_FLASH_CTRL_MCMD);
    do {
	if (IO_READ(MI_EINTR_REG)&MI_INTR_MD) return 1;
    } while(IO_READ(PI_FLASH_CTRL_REG)&PI_FLASH_CTRL_BUSY);
    IO_WRITE(PI_FLASH_CTRL_REG, PI_FLASH_CTRL_START |
				0x0 << PI_FLASH_CTRL_ADPH_SHIFT |
				NAND_CMD_ERASE_1 << PI_FLASH_CTRL_CMD_SHIFT |
				PI_FLASH_CTRL_WRDY |
				dev << PI_FLASH_CTRL_DEV_SHIFT);
    do {
	if (IO_READ(MI_EINTR_REG)&MI_INTR_MD) return 1;
    } while(IO_READ(PI_FLASH_CTRL_REG)&PI_FLASH_CTRL_BUSY);
    return flash_status(dev, 0, 0) != (NAND_STATUS_CMD_PASS|NAND_STATUS_READY|NAND_STATUS_WRITE_OK);
}

void get_err_code(char *s, int data)
{
    char hex[16] = { '0', '1', '2', '3',
                     '4', '5', '6', '7',
                     '8', '9', 'a', 'b',
                     'c', 'd', 'e', 'f'};
    *s++ = hex[((data)>>16) & 0xf];
    *s++ = hex[((data)>>8) & 0xf];
    *s++ = hex[ data & 0xf ];
    *s++ = '\0';
}

int
main() {
    int i;
    char err[4];
    test_preamble();
    /* configure flash */
    IO_WRITE(PI_FLASH_CONFIG_REG, 7 << 28 |  // end of cycle time - 2
	    			  5 << 24 |  // read data sample time - 1
				  0x3e << 16 | // RE active time
				  0x1f << 8 |  // WE active time
				  0x3f << 0);  // CLE/ALE active time

    erase_block(0, 32);
    for (i=0; i<512; i+=4) 
        IO_WRITE(PI_BUFFER_0_START+i, i & (~(i<<16)));

    for (i=i; i<16; i+=4) 
        IO_WRITE(PI_BUFFER_1_OOB_START+i, (i+512) & (~((i+512)<<16))); 

    if (write_page(0, 33, 0)) failed("2");
    if (read_page(0, 33, 1)) failed("4");
    for(i = 0; i < 512; i+=4) {
	unsigned x = IO_READ(PI_BUFFER_1_START+i);
        if (x !=  (i & (~(i<<16)))) {
            get_err_code(err, i);
            DBG_JTAG_FAIL("flash read mismatch 1"); 
            failed(err);
        }
    }

    DBG_JTAG_PASS("flash write/read test passed\n");
    passed();

    return 0;
}