コード例 #1
0
/*
 * Board-specific NAND initialization. The following members of the
 * argument are board-specific (per include/linux/mtd/nand.h):
 * - base : address that OneNAND is located at.
 * - scan_bbt: board specific bad block scan function.
 * Members with a "?" were not set in the merged testing-NAND branch,
 * so they are not set here either.
 */
int board_onenand_init (struct onenand_chip *onenand)
{
	int value;

	onenand->base = (void __iomem *)CFG_ONENAND_BASE;
	onenand->options |= (ONENAND_READ_BURST | ONENAND_CHECK_BAD | ONENAND_PIPELINE_AHEAD);
	onenand->scan_bbt = s3c_scan_bbt;

	/*** Initialize Controller ***/

	/* D0 Domain OneNAND Clock Gating */
	value = readl(ELFIN_CLOCK_POWER_BASE + CLK_GATE_SCLK_0_OFFSET);
	value = (value & ~(1 << 2)) | (1<< 2);
	writel(value, ELFIN_CLOCK_POWER_BASE + CLK_GATE_SCLK_0_OFFSET);

	/* ONENAND Select */
	value = readl(ELFIN_CLOCK_POWER_BASE + CLK_SRC0_OFFSET);
	value = value & ~(1 << 24); 
	value = value & ~(1 << 20);
//	value = (value & ~(1 << 12)) | (1<<12);

	writel(value, ELFIN_CLOCK_POWER_BASE + CLK_SRC0_OFFSET);

	/* SYSCON */
	value = readl(ELFIN_CLOCK_POWER_BASE + CLK_DIV1_OFFSET);
	value = (value & ~(3 << 16)) | (1 << 16);
	writel(value, ELFIN_CLOCK_POWER_BASE + CLK_DIV1_OFFSET);

	/* Cold Reset */
	writel(ONENAND_MEM_RESET_COLD, onenand->base + ONENAND_REG_MEM_RESET);

	/* Access Clock Register */
	writel(ONENAND_ACC_CLOCK_134_67, onenand->base + ONENAND_REG_ACC_CLOCK);

	/* FBA, FPA, FSA, DBS_DFS Width Register */
	set_addr_width_regs(onenand);

	/* Enable Interrupts */
	writel(0x3ff, onenand->base + ONENAND_REG_INT_ERR_MASK);
	writel(ONENAND_INT_PIN_ENABLE, onenand->base + ONENAND_REG_INT_PIN_ENABLE);
	writel(readl(onenand->base + ONENAND_REG_INT_ERR_MASK) & ~(ONENAND_INT_ERR_RDY_ACT), onenand->base + ONENAND_REG_INT_ERR_MASK);

	/* Memory Device Configuration Register */
	value = (ONENAND_MEM_CFG_SYNC_READ | ONENAND_MEM_CFG_BRL_4 | \
			ONENAND_MEM_CFG_BL_16 | ONENAND_MEM_CFG_IOBE | \
			ONENAND_MEM_CFG_INT_HIGH | ONENAND_MEM_CFG_RDY_HIGH);
	writel(value, onenand->base + ONENAND_REG_MEM_CFG);

	/* Burst Length Register */
	writel(ONENAND_BURST_LEN_16, onenand->base + ONENAND_REG_BURST_LEN);

	return 0;
}
コード例 #2
0
/*
 * Board-specific NAND initialization. The following members of the
 * argument are board-specific (per include/linux/mtd/nand.h):
 * - base : address that OneNAND is located at.
 * - scan_bbt: board specific bad block scan function.
 * Members with a "?" were not set in the merged testing-NAND branch,
 * so they are not set here either.
 */
int board_onenand_init (struct onenand_chip *onenand)
{
	int value;

	onenand->base = (void __iomem *)CFG_ONENAND_BASE;
	onenand->options |= (ONENAND_READ_BURST | ONENAND_CHECK_BAD | ONENAND_PIPELINE_AHEAD);
	onenand->scan_bbt = s3c_scan_bbt;

	/*** Initialize Controller ***/

	/* SYSCON */
	value = readl(ELFIN_CLOCK_POWER_BASE + CLK_DIV0_OFFSET);
	value = (value & ~(3 << 16)) | (1 << 16);
	writel(value, ELFIN_CLOCK_POWER_BASE + CLK_DIV0_OFFSET);

#if defined(CONFIG_S3C6410) || defined(CONFIG_S3C6430)
	writel(ONENAND_FLASH_AUX_WD_DISABLE, ONENAND_REG_FLASH_AUX_CNTRL);
#endif

	/* Cold Reset */
	writel(ONENAND_MEM_RESET_COLD, onenand->base + ONENAND_REG_MEM_RESET);

	/* Access Clock Register */
	writel(ONENAND_ACC_CLOCK_134_67, onenand->base + ONENAND_REG_ACC_CLOCK);

	/* FBA, FPA, FSA, DBS_DFS Width Register */
	set_addr_width_regs(onenand);

	/* Enable Interrupts */
	writel(0x3ff, onenand->base + ONENAND_REG_INT_ERR_MASK);
	writel(ONENAND_INT_PIN_ENABLE, onenand->base + ONENAND_REG_INT_PIN_ENABLE);
	writel(readl(onenand->base + ONENAND_REG_INT_ERR_MASK) & ~(ONENAND_INT_ERR_RDY_ACT), onenand->base + ONENAND_REG_INT_ERR_MASK);

	/* Memory Device Configuration Register */
	value = (ONENAND_MEM_CFG_SYNC_READ | ONENAND_MEM_CFG_BRL_4 | \
			ONENAND_MEM_CFG_BL_16 | ONENAND_MEM_CFG_IOBE | \
			ONENAND_MEM_CFG_INT_HIGH | ONENAND_MEM_CFG_RDY_HIGH);
	writel(value, onenand->base + ONENAND_REG_MEM_CFG);

	/* Burst Length Register */
	writel(ONENAND_BURST_LEN_16, onenand->base + ONENAND_REG_BURST_LEN);

	return 0;
}