コード例 #1
0
ファイル: jz4780_nand.c プロジェクト: 0intro/u-boot-ci20
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;
}
コード例 #2
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;
}