xref: /rk3399_rockchip-uboot/drivers/mtd/nand/raw/kmeter1_nand.c (revision cfcc706c901d603707657919484e4f65467be9ff)
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