int nand_write(unsigned int nand_start, unsigned char * buf, unsigned int len) { unsigned long count = 0; unsigned long addr = nand_start; int i = nand_start % 2048; nand_select(); while (count < len) { nand_cmd(0x80); nand_send_addr(addr); for (; i < 2048 && count < len; i++) { nand_send_data(buf[count++]); addr++; } nand_cmd(0x10); wait_ready(); i = 0; } nand_deselect(); }
static void nand_reset(){ int i; nand_select(); NFCMD=NAND_CMD_RESET; for(i=0;i<10;i++); nand_wait(); nand_deselect(); }
int spl_nand_load_image(void) { nand_init(); nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, CONFIG_SYS_NAND_U_BOOT_SIZE, (void *)CONFIG_SYS_NAND_U_BOOT_DST); spl_set_header_raw_uboot(); nand_deselect(); return 0; }
int spl_nand_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { nand_init(); nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, CONFIG_SYS_NAND_U_BOOT_SIZE, (void *)CONFIG_SYS_NAND_U_BOOT_DST); spl_set_header_raw_uboot(spl_image); nand_deselect(); return 0; }
static void nand_reset(void) { /* 选中 */ nand_select(); /* 发出0xff命令 */ nand_cmd(0xff); /* 等待就绪 */ wait_ready(); /* 取消选中 */ nand_deselect(); }
int nand_erase_block(unsigned long addr) { int page = addr / 2048; nand_select(); nand_cmd(0x60); nand_addr(page & 0xff); nand_addr((page >> 8) & 0xff); nand_addr((page >> 16) & 0xff); nand_cmd(0xd0); wait_ready(); nand_deselect(); }
void spl_nand_load_image(void) { struct image_header *header; switch (omap_boot_mode()) { case NAND_MODE_HW_ECC: debug("spl: nand - using hw ecc\n"); gpmc_init(); nand_init(); break; default: puts("spl: ERROR: This bootmode is not implemented - hanging"); hang(); } /*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); #ifdef CONFIG_NAND_ENV_DST nand_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); spl_parse_image_header(header); nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, (void *)image_load_addr); #ifdef CONFIG_ENV_OFFSET_REDUND nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); spl_parse_image_header(header); nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, (void *)image_load_addr); #endif #endif /* Load u-boot */ nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); spl_parse_image_header(header); nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, spl_image.size, (void *)spl_image.load_addr); nand_deselect(); }
int nand_read(unsigned int nand_start, unsigned int ddr_start, unsigned int len) { unsigned int addr = nand_start; int i, count = 0; unsigned char *dest = (unsigned char *)ddr_start; /* 选中芯片 */ nand_select(); while (count < len) { /* 发出命令0x00 */ nand_cmd(0x00); /* 发出地址 */ nand_send_addr(addr); /* 发出命令0x30 */ nand_cmd(0x30); /* 等待就绪 */ wait_ready(); /* 读数据 */ for (i = 0; i < 2048 && count < len; i++) { dest[count++] = nand_get_data(); } addr += 2048; } /* 取消片选 */ nand_deselect(); return 0; }
int spl_nand_load_image(void) { int err; struct image_header *header; int *src __attribute__((unused)); int *dst __attribute__((unused)); #ifdef CONFIG_SPL_NAND_SOFTECC debug("spl: nand - using sw ecc\n"); #else debug("spl: nand - using hw ecc\n"); #endif nand_init(); /*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); #ifdef CONFIG_SPL_OS_BOOT if (!spl_start_uboot()) { /* * load parameter image * load to temp position since nand_spl_load_image reads * a whole block which is typically larger than * CONFIG_CMD_SPL_WRITE_SIZE therefore may overwrite * following sections like BSS */ nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS, CONFIG_CMD_SPL_WRITE_SIZE, (void *)CONFIG_SYS_TEXT_BASE); /* copy to destintion */ for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR, src = (int *)CONFIG_SYS_TEXT_BASE; src < (int *)(CONFIG_SYS_TEXT_BASE + CONFIG_CMD_SPL_WRITE_SIZE); src++, dst++) { writel(readl(src), dst); } /* load linux */ nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, sizeof(*header), (void *)header); err = spl_parse_image_header(header); if (err) return err; if (header->ih_os == IH_OS_LINUX) { /* happy - was a linux */ err = nand_spl_load_image( CONFIG_SYS_NAND_SPL_KERNEL_OFFS, spl_image.size, (void *)spl_image.load_addr); nand_deselect(); return err; } else { puts("The Expected Linux image was not " "found. Please check your NAND " "configuration.\n"); puts("Trying to start u-boot now...\n"); } } #endif #ifdef CONFIG_NAND_ENV_DST spl_nand_load_element(CONFIG_ENV_OFFSET, header); #ifdef CONFIG_ENV_OFFSET_REDUND spl_nand_load_element(CONFIG_ENV_OFFSET_REDUND, header); #endif #endif /* Load u-boot */ err = spl_nand_load_element(CONFIG_SYS_NAND_U_BOOT_OFFS, header); nand_deselect(); return err; }
int spl_ubi_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { struct image_header *header; struct ubispl_info info; struct ubispl_load volumes[2]; int ret = 1; switch (bootdev->boot_device) { #ifdef CONFIG_SPL_NAND_SUPPORT case BOOT_DEVICE_NAND: nand_init(); info.read = nand_spl_read_block; info.peb_size = CONFIG_SYS_NAND_BLOCK_SIZE; break; #endif #ifdef CONFIG_SPL_ONENAND_SUPPORT case BOOT_DEVICE_ONENAND: info.read = onenand_spl_read_block; info.peb_size = CONFIG_SYS_ONENAND_BLOCK_SIZE; break; #endif default: goto out; } info.ubi = (struct ubi_scan_info *)CONFIG_SPL_UBI_INFO_ADDR; info.fastmap = 1; info.peb_offset = CONFIG_SPL_UBI_PEB_OFFSET; info.vid_offset = CONFIG_SPL_UBI_VID_OFFSET; info.leb_start = CONFIG_SPL_UBI_LEB_START; info.peb_count = CONFIG_SPL_UBI_MAX_PEBS - info.peb_offset; #ifdef CONFIG_SPL_OS_BOOT if (!spl_start_uboot()) { volumes[0].vol_id = CONFIG_SPL_UBI_LOAD_KERNEL_ID; volumes[0].load_addr = (void *)CONFIG_SYS_LOAD_ADDR; volumes[1].vol_id = CONFIG_SPL_UBI_LOAD_ARGS_ID; volumes[1].load_addr = (void *)CONFIG_SYS_SPL_ARGS_ADDR; ret = ubispl_load_volumes(&info, volumes, 2); if (!ret) { header = (struct image_header *)volumes[0].load_addr; spl_parse_image_header(spl_image, header); puts("Linux loaded.\n"); goto out; } puts("Loading Linux failed, falling back to U-Boot.\n"); } #endif header = (struct image_header *) (CONFIG_SYS_TEXT_BASE - sizeof(struct image_header)); volumes[0].vol_id = CONFIG_SPL_UBI_LOAD_MONITOR_ID; volumes[0].load_addr = (void *)header; ret = ubispl_load_volumes(&info, volumes, 1); if (!ret) spl_parse_image_header(spl_image, header); out: #ifdef CONFIG_SPL_NAND_SUPPORT if (bootdev->boot_device == BOOT_DEVICE_NAND) nand_deselect(); #endif return ret; }