X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Fdataflash.c;h=91903c8c8f739abd7c2310d3220483af6982f42f;hb=4a8527ef086ec7c89f40674ef024ae6f988a614a;hp=a0a4b62a4f7685964a7993a5e9346f4485bccd0d;hpb=2abbe0754759f94c79125a2534fbc4be74f416bc;p=oweals%2Fu-boot.git diff --git a/drivers/dataflash.c b/drivers/dataflash.c index a0a4b62a4f..91903c8c8f 100644 --- a/drivers/dataflash.c +++ b/drivers/dataflash.c @@ -26,30 +26,96 @@ AT91S_DATAFLASH_INFO dataflash_info[CFG_MAX_DATAFLASH_BANKS]; static AT91S_DataFlash DataFlashInst; +#ifdef CONFIG_AT91SAM9260EK +int cs[][CFG_MAX_DATAFLASH_BANKS] = { + {CFG_DATAFLASH_LOGIC_ADDR_CS0, 0}, /* Logical adress, CS */ + {CFG_DATAFLASH_LOGIC_ADDR_CS1, 1} +}; +#elif defined(CONFIG_AT91SAM9263EK) +int cs[][CFG_MAX_DATAFLASH_BANKS] = { + {CFG_DATAFLASH_LOGIC_ADDR_CS0, 0} /* Logical adress, CS */ +}; +#else int cs[][CFG_MAX_DATAFLASH_BANKS] = { {CFG_DATAFLASH_LOGIC_ADDR_CS0, 0}, /* Logical adress, CS */ {CFG_DATAFLASH_LOGIC_ADDR_CS3, 3} }; +#endif + +/*define the area offsets*/ +#if defined(CONFIG_AT91SAM9261EK) || defined(CONFIG_AT91SAM9260EK) || defined(CONFIG_AT91SAM9263EK) +#if defined(CONFIG_NEW_PARTITION) +dataflash_protect_t area_list[NB_DATAFLASH_AREA] = { + {0x00000000, 0x00003FFF, FLAG_PROTECT_SET, 0, "Bootstrap"}, /* ROM code */ + {0x00004200, 0x000083FF, FLAG_PROTECT_CLEAR, 0, "Environment"}, /* u-boot environment */ + {0x00008400, 0x0003DDFF, FLAG_PROTECT_SET, 0, "U-Boot"}, /* u-boot code */ + {0x0003DE00, 0x00041FFF, FLAG_PROTECT_CLEAR, FLAG_SETENV, "MON"}, /* Room for alternative boot monitor */ + {0x00042000, 0x0018BFFF, FLAG_PROTECT_CLEAR, FLAG_SETENV, "OS"}, /* data area size to tune */ + {0x0018C000, 0xFFFFFFFF, FLAG_PROTECT_CLEAR, FLAG_SETENV, "FS"}, /* data area size to tune */ +}; +#else +dataflash_protect_t area_list[NB_DATAFLASH_AREA] = { + {0, 0x3fff, FLAG_PROTECT_SET}, /* ROM code */ + {0x4000, 0x7fff, FLAG_PROTECT_CLEAR}, /* u-boot environment */ + {0x8000, 0x37fff, FLAG_PROTECT_SET}, /* u-boot code */ + {0x38000, 0x1fffff, FLAG_PROTECT_CLEAR}, /* data area size to tune */ +}; +#endif +#elif defined(CONFIG_NEW_PARTITION) +/*define the area offsets*/ +/* Invalid partitions should be defined with start > end */ +dataflash_protect_t area_list[NB_DATAFLASH_AREA*CFG_MAX_DATAFLASH_BANKS] = { + {0x00000000, 0x000083ff, FLAG_PROTECT_SET, 0, "Bootstrap"}, /* ROM code */ + {0x00008400, 0x00020fff, FLAG_PROTECT_SET, 0, "U-Boot"}, /* u-boot code */ + {0x00021000, 0x000293ff, FLAG_PROTECT_CLEAR, 0, "Environment"}, /* u-boot environment 8Kb */ + {0x00029400, 0x00041fff, FLAG_PROTECT_INVALID, 0, ""}, /* Rest of Sector 1 */ + {0x00042000, 0x0018Bfff, FLAG_PROTECT_CLEAR, FLAG_SETENV, "OS"}, /* data area size to tune */ + {0x0018C000, 0xffffffff, FLAG_PROTECT_CLEAR, FLAG_SETENV, "FS"}, /* data area size to tune */ + + {0x00000000, 0xffffffff, FLAG_PROTECT_CLEAR, FLAG_SETENV, "Data"}, /* data area */ + {0xffffffff, 0x00000000, FLAG_PROTECT_INVALID, 0, ""}, /* Invalid */ + {0xffffffff, 0x00000000, FLAG_PROTECT_INVALID, 0, ""}, /* Invalid */ + {0xffffffff, 0x00000000, FLAG_PROTECT_INVALID, 0, ""}, /* Invalid */ + {0xffffffff, 0x00000000, FLAG_PROTECT_INVALID, 0, ""}, /* Invalid */ + {0xffffffff, 0x00000000, FLAG_PROTECT_INVALID, 0, ""}, /* Invalid */ +}; +#else +dataflash_protect_t area_list[NB_DATAFLASH_AREA] = { + {0, 0x7fff, FLAG_PROTECT_SET}, /* ROM code */ + {0x8000, 0x1ffff, FLAG_PROTECT_SET}, /* u-boot code */ + {0x20000, 0x27fff, FLAG_PROTECT_CLEAR}, /* u-boot environment */ + {0x28000, 0x1fffff, FLAG_PROTECT_CLEAR}, /* data area size to tune */ +}; +#endif extern void AT91F_SpiInit (void); extern int AT91F_DataflashProbe (int i, AT91PS_DataflashDesc pDesc); extern int AT91F_DataFlashRead (AT91PS_DataFlash pDataFlash, unsigned long addr, unsigned long size, char *buffer); - +extern int AT91F_DataFlashWrite( AT91PS_DataFlash pDataFlash, + unsigned char *src, + int dest, + int size ); int AT91F_DataflashInit (void) { int i, j; int dfcode; + int part = 0; + int last_part; + int found[CFG_MAX_DATAFLASH_BANKS]; + unsigned char protected; AT91F_SpiInit (); for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) { - + found[i] = 0; + dataflash_info[i].Desc.state = IDLE; dataflash_info[i].id = 0; dataflash_info[i].Device.pages_number = 0; - dfcode = AT91F_DataflashProbe (cs[i][1], &dataflash_info[i].Desc); + dfcode = AT91F_DataflashProbe (cs[i][1], + &dataflash_info[i].Desc); switch (dfcode) { case AT45DB161: @@ -61,6 +127,7 @@ int AT91F_DataflashInit (void) dataflash_info[i].Desc.DataFlash_state = IDLE; dataflash_info[i].logical_address = cs[i][0]; dataflash_info[i].id = dfcode; + found[i] += dfcode;; break; case AT45DB321: @@ -72,6 +139,7 @@ int AT91F_DataflashInit (void) dataflash_info[i].Desc.DataFlash_state = IDLE; dataflash_info[i].logical_address = cs[i][0]; dataflash_info[i].id = dfcode; + found[i] += dfcode;; break; case AT45DB642: @@ -83,43 +151,114 @@ int AT91F_DataflashInit (void) dataflash_info[i].Desc.DataFlash_state = IDLE; dataflash_info[i].logical_address = cs[i][0]; dataflash_info[i].id = dfcode; + found[i] += dfcode;; + break; + + case AT45DB128: + dataflash_info[i].Device.pages_number = 16384; + dataflash_info[i].Device.pages_size = 1056; + dataflash_info[i].Device.page_offset = 11; + dataflash_info[i].Device.byte_mask = 0x700; + dataflash_info[i].Device.cs = cs[i][1]; + dataflash_info[i].Desc.DataFlash_state = IDLE; + dataflash_info[i].logical_address = cs[i][0]; + dataflash_info[i].id = dfcode; + found[i] += dfcode;; break; default: + dfcode = 0; break; } - - for (j = 0; j < dataflash_info[i].Device.pages_number; j++) - dataflash_info[i].protect[j] = FLAG_PROTECT_SET; - + /* set the last area end to the dataflash size*/ + area_list[NB_DATAFLASH_AREA -1].end = + (dataflash_info[i].Device.pages_number * + dataflash_info[i].Device.pages_size)-1; + + last_part=0; + /* set the area addresses */ + for(j = 0; j (pdataFlash->pDevice->pages_size * + pdataFlash->pDevice->pages_number)) return 0; + /* is too large for the dataflash */ + if (size > ((pdataFlash->pDevice->pages_size * + pdataFlash->pDevice->pages_number) - + ((int)addr & 0x0FFFFFFF))) return 0; + + return 1; +} +/*---------------------------------------------------------------------------*/ +/* Function Name : prot_dataflash */ +/* Object : Test if destination area is protected */ +/*---------------------------------------------------------------------------*/ +int prot_dataflash (AT91PS_DataFlash pdataFlash, unsigned long addr) +{ +int area; + /* find area */ + for (area=0; area < NB_DATAFLASH_AREA; area++) { + if ((addr >= pdataFlash->pDevice->area_list[area].start) && + (addr < pdataFlash->pDevice->area_list[area].end)) + break; + } + if (area == NB_DATAFLASH_AREA) + return -1; + + /*test protection value*/ + if (pdataFlash->pDevice->area_list[area].protected == FLAG_PROTECT_SET) + return 0; + if (pdataFlash->pDevice->area_list[area].protected == FLAG_PROTECT_INVALID) + return 0; -/*------------------------------------------------------------------------------*/ -/* Function Name : read_dataflash */ -/* Object : dataflash memory read */ -/*------------------------------------------------------------------------------*/ + return 1; +} +/*--------------------------------------------------------------------------*/ +/* Function Name : dataflash_real_protect */ +/* Object : protect/unprotect area */ +/*--------------------------------------------------------------------------*/ +int dataflash_real_protect (int flag, unsigned long start_addr, + unsigned long end_addr) +{ +int i,j, area1, area2, addr_valid = 0; + /* find dataflash */ + for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) { + if ((((int) start_addr) & 0xF0000000) == + dataflash_info[i].logical_address) { + addr_valid = 1; + break; + } + } + if (!addr_valid) { + return -1; + } + /* find start area */ + for (area1=0; area1 < NB_DATAFLASH_AREA; area1++) { + if (start_addr == dataflash_info[i].Device.area_list[area1].start) + break; + } + if (area1 == NB_DATAFLASH_AREA) return -1; + /* find end area */ + for (area2=0; area2 < NB_DATAFLASH_AREA; area2++) { + if (end_addr == dataflash_info[i].Device.area_list[area2].end) + break; + } + if (area2 == NB_DATAFLASH_AREA) + return -1; + + /*set protection value*/ + for(j = area1; j < area2+1 ; j++) + if(dataflash_info[i].Device.area_list[j].protected + != FLAG_PROTECT_INVALID) { + if (flag == 0) { + dataflash_info[i].Device.area_list[j].protected + = FLAG_PROTECT_CLEAR; + } else { + dataflash_info[i].Device.area_list[j].protected + = FLAG_PROTECT_SET; + } + } + + return (area2-area1+1); +} + +/*---------------------------------------------------------------------------*/ +/* Function Name : read_dataflash */ +/* Object : dataflash memory read */ +/*---------------------------------------------------------------------------*/ int read_dataflash (unsigned long addr, unsigned long size, char *result) { - int AddrToRead = addr; + unsigned long AddrToRead = addr; AT91PS_DataFlash pFlash = &DataFlashInst; pFlash = AT91F_DataflashSelect (pFlash, &AddrToRead); + if (pFlash == 0) - return -1; + return ERR_UNKNOWN_FLASH_TYPE; + + if (size_dataflash(pFlash,addr,size) == 0) + return ERR_INVAL; return (AT91F_DataFlashRead (pFlash, AddrToRead, size, result)); } -/*-----------------------------------------------------------------------------*/ -/* Function Name : write_dataflash */ -/* Object : write a block in dataflash */ -/*-----------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/* Function Name : write_dataflash */ +/* Object : write a block in dataflash */ +/*---------------------------------------------------------------------------*/ int write_dataflash (unsigned long addr_dest, unsigned long addr_src, - unsigned long size) + unsigned long size) { - extern AT91S_DataFlashStatus AT91F_DataFlashWrite( - AT91PS_DataFlash, uchar *, int, int); - int AddrToWrite = addr_dest; + unsigned long AddrToWrite = addr_dest; AT91PS_DataFlash pFlash = &DataFlashInst; pFlash = AT91F_DataflashSelect (pFlash, &AddrToWrite); + + if (pFlash == 0) + return ERR_UNKNOWN_FLASH_TYPE; + + if (size_dataflash(pFlash,addr_dest,size) == 0) + return ERR_INVAL; + + if (prot_dataflash(pFlash,addr_dest) == 0) + return ERR_PROTECTED; + if (AddrToWrite == -1) return -1; - return AT91F_DataFlashWrite (pFlash, (char *) addr_src, AddrToWrite, - size); + return AT91F_DataFlashWrite (pFlash, (uchar *)addr_src, + AddrToWrite, size); } @@ -222,22 +484,22 @@ void dataflash_perror (int err) case ERR_OK: break; case ERR_TIMOUT: - printf ("Timeout writing to DataFlash\n"); + printf("Timeout writing to DataFlash\n"); break; case ERR_PROTECTED: - printf ("Can't write to protected DataFlash sectors\n"); + printf("Can't write to protected/invalid DataFlash sectors\n"); break; case ERR_INVAL: - printf ("Outside available DataFlash\n"); + printf("Outside available DataFlash\n"); break; case ERR_UNKNOWN_FLASH_TYPE: - printf ("Unknown Type of DataFlash\n"); + printf("Unknown Type of DataFlash\n"); break; case ERR_PROG_ERROR: - printf ("General DataFlash Programming Error\n"); + printf("General DataFlash Programming Error\n"); break; default: - printf ("%s[%d] FIXME: rc=%d\n", __FILE__, __LINE__, err); + printf("%s[%d] FIXME: rc=%d\n", __FILE__, __LINE__, err); break; } }