On Mon, 28 Feb 2011 14:57:11 +0800 Xiangfu Liu <xian...@openmobilefree.net> wrote:
> +static int jz_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat, > + u_char *read_ecc, u_char *calc_ecc) > +{ > + int k; > + uint32_t errcnt, index, mask, status; > + volatile u8 *paraddr = (volatile u8 *) &emc->nfpar[0]; > + > + /* Set PAR values */ > + static uint8_t all_ff_ecc[] = > + {0xcd, 0x9d, 0x90, 0x58, 0xf4, 0x8b, 0xff, 0xb7, 0x6f}; const? > + > + if (read_ecc[0] == 0xff && read_ecc[1] == 0xff && > + read_ecc[2] == 0xff && read_ecc[3] == 0xff && > + read_ecc[4] == 0xff && read_ecc[5] == 0xff && > + read_ecc[6] == 0xff && read_ecc[7] == 0xff && > + read_ecc[8] == 0xff) { > + for (k = 0; k < 9; k++) > + writeb(all_ff_ecc[k], (paraddr + k)); > + } else { > + for (k = 0; k < 9; k++) > + writeb(read_ecc[k], (paraddr + k)); > + } Wouldn't it be simpler to do: writeb(..., &emc->nfpar[k]); And don't use volatile. > + /* Set PRDY */ > + writel(readl(&emc->nfecr) | EMC_NFECR_PRDY, &emc->nfecr); > + > + /* Wait for completion */ > + do { > + status = readl(&emc->nfints); > + } while (!(status & EMC_NFINTS_DECF)); > + > + /* disable ecc */ > + writel(readl(&emc->nfecr) & ~EMC_NFECR_ECCE, &emc->nfecr); > + > + /* Check decoding */ > + if (!(status & EMC_NFINTS_ERR)) > + return 0; > + > + if (status & EMC_NFINTS_UNCOR) { > + printf("uncorrectable ecc\n"); > + return -1; > + } > + > + errcnt = (status & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT; > + > +#ifdef CONFIG_NAND_SPL > + return 0; > +#endif Spaces should be a tab. > + switch (errcnt) { > + case 4: > + index = (readl(&emc->nferr[3]) & EMC_NFERR_INDEX_MASK) >> > + EMC_NFERR_INDEX_BIT; > + mask = (readl(&emc->nferr[3]) & EMC_NFERR_MASK_MASK) >> > + EMC_NFERR_MASK_BIT; > + jz_rs_correct(dat, index, mask); > + case 3: > + index = (readl(&emc->nferr[2]) & EMC_NFERR_INDEX_MASK) >> > + EMC_NFERR_INDEX_BIT; > + mask = (readl(&emc->nferr[2]) & EMC_NFERR_MASK_MASK) >> > + EMC_NFERR_MASK_BIT; > + jz_rs_correct(dat, index, mask); > + case 2: > + index = (readl(&emc->nferr[1]) & EMC_NFERR_INDEX_MASK) >> > + EMC_NFERR_INDEX_BIT; > + mask = (readl(&emc->nferr[1]) & EMC_NFERR_MASK_MASK) >> > + EMC_NFERR_MASK_BIT; > + jz_rs_correct(dat, index, mask); > + case 1: > + index = (readl(&emc->nferr[0]) & EMC_NFERR_INDEX_MASK) >> > + EMC_NFERR_INDEX_BIT; > + mask = (readl(&emc->nferr[0]) & EMC_NFERR_MASK_MASK) >> > + EMC_NFERR_MASK_BIT; > + jz_rs_correct(dat, index, mask); > + default: > + break; > + } > + > + return errcnt; You don't do ECC correction in SPL? Can it not fit? > +/* > + * Main initialization routine > + */ > +int board_nand_init(struct nand_chip *nand) > +{ > +#ifdef CONFIG_NAND_SPL > +extern void pll_init(void); > +extern void sdram_init(void); > +extern int serial_init(void); Externs should go in header files. > + __gpio_as_sdram_16bit_4720(); > + __gpio_as_uart0(); > + > + pll_init(); > + serial_init(); > + sdram_init(); > +#if defined(CONFIG_QI_LB60) > +#define KEY_U_OUT (32 * 2 + 16) > +#define KEY_U_IN (32 * 3 + 19) > + __gpio_as_input(KEY_U_IN); > + __gpio_enable_pull(KEY_U_IN); > + __gpio_as_output(KEY_U_OUT); > + __gpio_clear_pin(KEY_U_OUT); > + > + if (__gpio_get_pin(KEY_U_IN) == 0) > + usb_boot(); > +#endif > +#endif This stuff does not belong in the NAND driver; it belongs under your board or cpu directory. > + uint32_t reg; > + > + reg = readl(&emc->nfcsr); > + reg |= EMC_NFCSR_NFE1; /* EMC setup, Set NFE bit */ > + writel(reg, &emc->nfcsr); > + > + writel(EMC_SMCR1_OPT_NAND, &emc->smcr[1]); > + > + nand->IO_ADDR_R = JZ_NAND_DATA_ADDR; > + nand->IO_ADDR_W = JZ_NAND_DATA_ADDR; > + nand->cmd_ctrl = jz_nand_cmd_ctrl; > + nand->dev_ready = jz_nand_device_ready; > +#ifdef CONFIG_NAND_SPL > + nand->read_byte = nand_read_byte; > + nand->read_buf = nand_read_buf; > +#endif > + nand->ecc.hwctl = jz_nand_hwctl; > + nand->ecc.correct = jz_nand_rs_correct_data; > + nand->ecc.calculate = jz_nand_rs_calculate_ecc; > + nand->ecc.mode = NAND_ECC_HW_OOB_FIRST; > + nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE; > + nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES; > + nand->ecc.layout = &qi_lb60_ecclayout_2gb; > + nand->chip_delay = 50; You don't set nand->options... Don't you want a bad block table? -Scott _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot