18bc4ee9eSMinkyu Kang /*
28bc4ee9eSMinkyu Kang * Copyright (C) 2008-2009 Samsung Electronics
38bc4ee9eSMinkyu Kang * Kyungmin Park <kyungmin.park@samsung.com>
48bc4ee9eSMinkyu Kang *
51a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+
68bc4ee9eSMinkyu Kang */
78bc4ee9eSMinkyu Kang
88bc4ee9eSMinkyu Kang #include <common.h>
97b15e2bbSMike Frysinger #include <linux/compat.h>
108bc4ee9eSMinkyu Kang #include <linux/mtd/mtd.h>
118bc4ee9eSMinkyu Kang #include <linux/mtd/onenand.h>
128bc4ee9eSMinkyu Kang #include <linux/mtd/samsung_onenand.h>
138bc4ee9eSMinkyu Kang
148bc4ee9eSMinkyu Kang #include <onenand_uboot.h>
158bc4ee9eSMinkyu Kang
168bc4ee9eSMinkyu Kang #include <asm/io.h>
178bc4ee9eSMinkyu Kang #include <asm/arch/clock.h>
188bc4ee9eSMinkyu Kang
onenand_board_init(struct mtd_info * mtd)19*77b93e5eSLadislav Michl int onenand_board_init(struct mtd_info *mtd)
208bc4ee9eSMinkyu Kang {
218bc4ee9eSMinkyu Kang struct onenand_chip *this = mtd->priv;
22d93d0f0cSMinkyu Kang struct s5pc100_clock *clk =
23d93d0f0cSMinkyu Kang (struct s5pc100_clock *)samsung_get_base_clock();
248bc4ee9eSMinkyu Kang struct samsung_onenand *onenand;
258bc4ee9eSMinkyu Kang int value;
268bc4ee9eSMinkyu Kang
278bc4ee9eSMinkyu Kang this->base = (void *)S5PC100_ONENAND_BASE;
288bc4ee9eSMinkyu Kang onenand = (struct samsung_onenand *)this->base;
298bc4ee9eSMinkyu Kang
308bc4ee9eSMinkyu Kang /* D0 Domain memory clock gating */
318bc4ee9eSMinkyu Kang value = readl(&clk->gate_d01);
328bc4ee9eSMinkyu Kang value &= ~(1 << 2); /* CLK_ONENANDC */
338bc4ee9eSMinkyu Kang value |= (1 << 2);
348bc4ee9eSMinkyu Kang writel(value, &clk->gate_d01);
358bc4ee9eSMinkyu Kang
368bc4ee9eSMinkyu Kang value = readl(&clk->src0);
378bc4ee9eSMinkyu Kang value &= ~(1 << 24); /* MUX_1nand: 0 from HCLKD0 */
388bc4ee9eSMinkyu Kang value &= ~(1 << 20); /* MUX_HREF: 0 from FIN_27M */
398bc4ee9eSMinkyu Kang writel(value, &clk->src0);
408bc4ee9eSMinkyu Kang
418bc4ee9eSMinkyu Kang value = readl(&clk->div1);
428bc4ee9eSMinkyu Kang value &= ~(3 << 16); /* PCLKD1_RATIO */
438bc4ee9eSMinkyu Kang value |= (1 << 16);
448bc4ee9eSMinkyu Kang writel(value, &clk->div1);
458bc4ee9eSMinkyu Kang
468bc4ee9eSMinkyu Kang writel(ONENAND_MEM_RESET_COLD, &onenand->mem_reset);
478bc4ee9eSMinkyu Kang
488bc4ee9eSMinkyu Kang while (!(readl(&onenand->int_err_stat) & RST_CMP))
498bc4ee9eSMinkyu Kang continue;
508bc4ee9eSMinkyu Kang
518bc4ee9eSMinkyu Kang writel(RST_CMP, &onenand->int_err_ack);
528bc4ee9eSMinkyu Kang
538bc4ee9eSMinkyu Kang /*
548bc4ee9eSMinkyu Kang * Access_Clock [2:0]
558bc4ee9eSMinkyu Kang * 166 MHz, 134 Mhz : 3
568bc4ee9eSMinkyu Kang * 100 Mhz, 60 Mhz : 2
578bc4ee9eSMinkyu Kang */
588bc4ee9eSMinkyu Kang writel(0x3, &onenand->acc_clock);
598bc4ee9eSMinkyu Kang
608bc4ee9eSMinkyu Kang writel(INT_ERR_ALL, &onenand->int_err_mask);
618bc4ee9eSMinkyu Kang writel(1 << 0, &onenand->int_pin_en); /* Enable */
628bc4ee9eSMinkyu Kang
638bc4ee9eSMinkyu Kang value = readl(&onenand->int_err_mask);
648bc4ee9eSMinkyu Kang value &= ~RDY_ACT;
658bc4ee9eSMinkyu Kang writel(value, &onenand->int_err_mask);
668bc4ee9eSMinkyu Kang
678bc4ee9eSMinkyu Kang s3c_onenand_init(mtd);
68*77b93e5eSLadislav Michl
69*77b93e5eSLadislav Michl return 0;
708bc4ee9eSMinkyu Kang }
71