int jz4780_nand_init(struct nand_chip *nand) { struct jz_nand_priv *priv; uint32_t reg; /* set BCH clock divide */ reg = readl(CPM_BCHCDR) & ~(CPM_BCHCDR_BCHCDR_MASK | CPM_BCHCDR_BPCS_MASK); reg |= ((CONFIG_SYS_CPU_SPEED / 200000000) - 1) & CPM_BCHCDR_BCHCDR_MASK; reg |= CPM_BCHCDR_BPCS_MPLL; writel(reg | CPM_BCHCDR_CE_BCH, CPM_BCHCDR); writel(reg | CPM_BCHCDR_CE_BCH, CPM_BCHCDR); while (readl(CPM_BCHCDR) & CPM_BCHCDR_BCH_BUSY); writel(reg, CPM_BCHCDR); /* ungate NEMC & BCH clocks */ writel(readl(CPM_CLKGR0) & ~(CPM_CLKGR0_NEMC | CPM_CLKGR0_BCH), CPM_CLKGR0); nand->cmd_ctrl = jz_nand_cmd_ctrl; nand->dev_ready = jz_nand_device_ready; nand->read_buf = jz_nand_read_buf; nand->write_buf = jz_nand_write_buf; nand->ecc.mode = NAND_ECC_HW_OOB_FIRST; nand->ecc.hwctl = jz_nand_hwctl; nand->ecc.correct = jz_nand_correct_data; nand->ecc.calculate = jz_nand_calculate_ecc; nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE; nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES; nand->ecc.strength = CONFIG_SYS_NAND_ECCSTRENGTH; nand->ecc.layout = &jz4780_nand_ecclayout; nand->chip_delay = 50; nand->options = NAND_NO_SUBPAGE_WRITE; nand->bbt_options = NAND_BBT_USE_FLASH; nand->priv = priv = &nand_privs[0]; priv->reading = 0; priv->pn_bytes = priv->pn_size = priv->pn_skip = 0; /* optimise timing */ writel(0x18664400, NEMC_BASE + NEMC_SMCR1); /* enable flash chip */ writel(readl(NEMC_BASE + NEMC_NFCSR) | NEMC_NFCSR_NFEn(1), NEMC_BASE + NEMC_NFCSR); /* begin without pseudo-random noise */ jz_nand_set_pn(0, false); return 0; }
int jz_nand_chip_init(struct jz_nemc *nemc, struct jz_nand_params *param) { struct clk *clk = devm_clk_get(&nemc->pdev->dev, "h2clk"); int valume, smcr, cycle, nfcsr; unsigned long h2clk; if (IS_ERR_OR_NULL(clk)) return -EIO; h2clk = clk_get_rate(clk); cycle = 1000000000/(h2clk/1000); /* NEMC.TAS */ valume = (param->tALS * 1000 + cycle - 1) / cycle; valume -= (valume > 1) ? 1 : 0; smcr = (valume & NEMC_SMCR_TAS_MASK) << NEMC_SMCR_TAS_BIT; /* NEMC.TAH */ valume = (param->tALH * 1000 + cycle -1) / cycle; valume -= (valume > 1) ? 1 : 0; smcr |= (valume & NEMC_SMCR_TAH_MASK) << NEMC_SMCR_TAH_BIT; /* NEMC.TBP */ valume = (param->tWP * 1000 + cycle - 1) / cycle; smcr |= (valume & NEMC_SMCR_TBP_MASK) << NEMC_SMCR_TBP_BIT; /* NEMC.TAW */ valume = (param->tRP * 1000 + cycle -1) / cycle; smcr |= (valume & NEMC_SMCR_TAW_MASK) << NEMC_SMCR_TAW_BIT; /* NEMC.STRV */ valume = (param->tRHW * 1000 + cycle - 1) / cycle; writel(smcr, nemc->base+NEMC_SMCRn(1)); nfcsr = readl(nemc->base + NEMC_NFCSR); nfcsr |= NEMC_NFCSR_NFEn(1); writel(nfcsr, nemc->base + NEMC_NFCSR); nemc->clk = devm_clk_get(&nemc->pdev->dev, "nemc"); clk_enable(nemc->clk); return 0; }