/*----------------------------------------------------------------------- * Copy memory to flash, returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased */ int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt) { FPW data = 0; /* 16 or 32 bit word, matches flash bus width on MPC8XX */ int bytes; /* number of bytes to program in current word */ int left; /* number of bytes left to program */ int i, res; for (left = cnt, res = 0; left > 0 && res == 0; addr += sizeof(data), left -= sizeof(data) - bytes) { bytes = addr & (sizeof(data) - 1); addr &= ~(sizeof(data) - 1); /* combine source and destination data so can program * an entire word of 16 or 32 bits */ for (i = 0; i < sizeof(data); i++) { if (i < bytes || i - bytes >= left ) *((uchar *)&data + i) = *((uchar *)addr + i); else *((uchar *)&data + i)= *src++; } if(get_timer(rt2880_flash_start_t) > CFG_FLASH_STATE_DISPLAY_TOUT) { printf("\n addr = 0x%08X ,cnt=%d ",addr,left); rt2880_flash_start_t = get_timer(0); } /* write one word to the flash */ switch (info->flash_id & FLASH_VENDMASK) { case FLASH_MAN_AMD: res = write_word_amd(info, (FPWV *)addr, data); break; case FLASH_MAN_INTEL: res = write_word_intel(info, (FPWV *)addr, data); break; case FLASH_MAN_MX: res = write_word_amd(info, (FPWV *)addr, data); break; default: /* unknown flash type, error! */ printf("missing or unknown FLASH type\n"); res = 1; /* not really a timeout, but gives error */ break; } } return (res); }
/* broken for 2x16: TODO */ static int write_word (flash_info_t *info, ulong dest, ulong data) { volatile unsigned char *addr = (uchar *)(info->start[0]); ulong start; int flag, i; if(info->portwidth==4) return 1; if((info->flash_id & FLASH_TYPEMASK) == FLASH_ROM) return 1; if((info->flash_id & FLASH_TYPEMASK) == FLASH_RAM) { *(unsigned long *)dest=data; return 0; } if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) { unsigned short low = data & 0xffff; unsigned short hi = (data >> 16) & 0xffff; int ret = write_word_intel((bank_addr_t)dest, hi); if (!ret) ret = write_word_intel((bank_addr_t)(dest+2), low); return ret; }