/* * 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; }
/* * 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; }