1*cfcc706cSMiquel Raynal /*
2*cfcc706cSMiquel Raynal * (C) Copyright 2009
3*cfcc706cSMiquel Raynal * Heiko Schocher, DENX Software Engineering, hs@denx.de
4*cfcc706cSMiquel Raynal *
5*cfcc706cSMiquel Raynal * SPDX-License-Identifier: GPL-2.0+
6*cfcc706cSMiquel Raynal */
7*cfcc706cSMiquel Raynal
8*cfcc706cSMiquel Raynal #include <common.h>
9*cfcc706cSMiquel Raynal #include <nand.h>
10*cfcc706cSMiquel Raynal #include <asm/io.h>
11*cfcc706cSMiquel Raynal
12*cfcc706cSMiquel Raynal #define CONFIG_NAND_MODE_REG (void *)(CONFIG_SYS_NAND_BASE + 0x20000)
13*cfcc706cSMiquel Raynal #define CONFIG_NAND_DATA_REG (void *)(CONFIG_SYS_NAND_BASE + 0x30000)
14*cfcc706cSMiquel Raynal
15*cfcc706cSMiquel Raynal #define read_mode() in_8(CONFIG_NAND_MODE_REG)
16*cfcc706cSMiquel Raynal #define write_mode(val) out_8(CONFIG_NAND_MODE_REG, val)
17*cfcc706cSMiquel Raynal #define read_data() in_8(CONFIG_NAND_DATA_REG)
18*cfcc706cSMiquel Raynal #define write_data(val) out_8(CONFIG_NAND_DATA_REG, val)
19*cfcc706cSMiquel Raynal
20*cfcc706cSMiquel Raynal #define KPN_RDY2 (1 << 7)
21*cfcc706cSMiquel Raynal #define KPN_RDY1 (1 << 6)
22*cfcc706cSMiquel Raynal #define KPN_WPN (1 << 4)
23*cfcc706cSMiquel Raynal #define KPN_CE2N (1 << 3)
24*cfcc706cSMiquel Raynal #define KPN_CE1N (1 << 2)
25*cfcc706cSMiquel Raynal #define KPN_ALE (1 << 1)
26*cfcc706cSMiquel Raynal #define KPN_CLE (1 << 0)
27*cfcc706cSMiquel Raynal
28*cfcc706cSMiquel Raynal #define KPN_DEFAULT_CHIP_DELAY 50
29*cfcc706cSMiquel Raynal
kpn_chip_ready(void)30*cfcc706cSMiquel Raynal static int kpn_chip_ready(void)
31*cfcc706cSMiquel Raynal {
32*cfcc706cSMiquel Raynal if (read_mode() & KPN_RDY1)
33*cfcc706cSMiquel Raynal return 1;
34*cfcc706cSMiquel Raynal
35*cfcc706cSMiquel Raynal return 0;
36*cfcc706cSMiquel Raynal }
37*cfcc706cSMiquel Raynal
kpn_wait_rdy(void)38*cfcc706cSMiquel Raynal static void kpn_wait_rdy(void)
39*cfcc706cSMiquel Raynal {
40*cfcc706cSMiquel Raynal int cnt = 1000000;
41*cfcc706cSMiquel Raynal
42*cfcc706cSMiquel Raynal while (--cnt && !kpn_chip_ready())
43*cfcc706cSMiquel Raynal udelay(1);
44*cfcc706cSMiquel Raynal
45*cfcc706cSMiquel Raynal if (!cnt)
46*cfcc706cSMiquel Raynal printf ("timeout while waiting for RDY\n");
47*cfcc706cSMiquel Raynal }
48*cfcc706cSMiquel Raynal
kpn_nand_hwcontrol(struct mtd_info * mtd,int cmd,unsigned int ctrl)49*cfcc706cSMiquel Raynal static void kpn_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
50*cfcc706cSMiquel Raynal {
51*cfcc706cSMiquel Raynal u8 reg_val = read_mode();
52*cfcc706cSMiquel Raynal
53*cfcc706cSMiquel Raynal if (ctrl & NAND_CTRL_CHANGE) {
54*cfcc706cSMiquel Raynal reg_val = reg_val & ~(KPN_ALE + KPN_CLE);
55*cfcc706cSMiquel Raynal
56*cfcc706cSMiquel Raynal if (ctrl & NAND_CLE)
57*cfcc706cSMiquel Raynal reg_val = reg_val | KPN_CLE;
58*cfcc706cSMiquel Raynal if (ctrl & NAND_ALE)
59*cfcc706cSMiquel Raynal reg_val = reg_val | KPN_ALE;
60*cfcc706cSMiquel Raynal if (ctrl & NAND_NCE)
61*cfcc706cSMiquel Raynal reg_val = reg_val & ~KPN_CE1N;
62*cfcc706cSMiquel Raynal else
63*cfcc706cSMiquel Raynal reg_val = reg_val | KPN_CE1N;
64*cfcc706cSMiquel Raynal
65*cfcc706cSMiquel Raynal write_mode(reg_val);
66*cfcc706cSMiquel Raynal }
67*cfcc706cSMiquel Raynal if (cmd != NAND_CMD_NONE)
68*cfcc706cSMiquel Raynal write_data(cmd);
69*cfcc706cSMiquel Raynal
70*cfcc706cSMiquel Raynal /* wait until flash is ready */
71*cfcc706cSMiquel Raynal kpn_wait_rdy();
72*cfcc706cSMiquel Raynal }
73*cfcc706cSMiquel Raynal
kpn_nand_read_byte(struct mtd_info * mtd)74*cfcc706cSMiquel Raynal static u_char kpn_nand_read_byte(struct mtd_info *mtd)
75*cfcc706cSMiquel Raynal {
76*cfcc706cSMiquel Raynal return read_data();
77*cfcc706cSMiquel Raynal }
78*cfcc706cSMiquel Raynal
kpn_nand_write_buf(struct mtd_info * mtd,const u_char * buf,int len)79*cfcc706cSMiquel Raynal static void kpn_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
80*cfcc706cSMiquel Raynal {
81*cfcc706cSMiquel Raynal int i;
82*cfcc706cSMiquel Raynal
83*cfcc706cSMiquel Raynal for (i = 0; i < len; i++) {
84*cfcc706cSMiquel Raynal write_data(buf[i]);
85*cfcc706cSMiquel Raynal kpn_wait_rdy();
86*cfcc706cSMiquel Raynal }
87*cfcc706cSMiquel Raynal }
88*cfcc706cSMiquel Raynal
kpn_nand_read_buf(struct mtd_info * mtd,u_char * buf,int len)89*cfcc706cSMiquel Raynal static void kpn_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
90*cfcc706cSMiquel Raynal {
91*cfcc706cSMiquel Raynal int i;
92*cfcc706cSMiquel Raynal
93*cfcc706cSMiquel Raynal for (i = 0; i < len; i++)
94*cfcc706cSMiquel Raynal buf[i] = read_data();
95*cfcc706cSMiquel Raynal }
96*cfcc706cSMiquel Raynal
kpn_nand_dev_ready(struct mtd_info * mtd)97*cfcc706cSMiquel Raynal static int kpn_nand_dev_ready(struct mtd_info *mtd)
98*cfcc706cSMiquel Raynal {
99*cfcc706cSMiquel Raynal kpn_wait_rdy();
100*cfcc706cSMiquel Raynal
101*cfcc706cSMiquel Raynal return 1;
102*cfcc706cSMiquel Raynal }
103*cfcc706cSMiquel Raynal
board_nand_init(struct nand_chip * nand)104*cfcc706cSMiquel Raynal int board_nand_init(struct nand_chip *nand)
105*cfcc706cSMiquel Raynal {
106*cfcc706cSMiquel Raynal #if defined(CONFIG_NAND_ECC_BCH)
107*cfcc706cSMiquel Raynal nand->ecc.mode = NAND_ECC_SOFT_BCH;
108*cfcc706cSMiquel Raynal #else
109*cfcc706cSMiquel Raynal nand->ecc.mode = NAND_ECC_SOFT;
110*cfcc706cSMiquel Raynal #endif
111*cfcc706cSMiquel Raynal
112*cfcc706cSMiquel Raynal /* Reference hardware control function */
113*cfcc706cSMiquel Raynal nand->cmd_ctrl = kpn_nand_hwcontrol;
114*cfcc706cSMiquel Raynal nand->read_byte = kpn_nand_read_byte;
115*cfcc706cSMiquel Raynal nand->write_buf = kpn_nand_write_buf;
116*cfcc706cSMiquel Raynal nand->read_buf = kpn_nand_read_buf;
117*cfcc706cSMiquel Raynal nand->dev_ready = kpn_nand_dev_ready;
118*cfcc706cSMiquel Raynal nand->chip_delay = KPN_DEFAULT_CHIP_DELAY;
119*cfcc706cSMiquel Raynal
120*cfcc706cSMiquel Raynal /* reset mode register */
121*cfcc706cSMiquel Raynal write_mode(KPN_CE1N + KPN_CE2N + KPN_WPN);
122*cfcc706cSMiquel Raynal return 0;
123*cfcc706cSMiquel Raynal }
124