xref: /OK3568_Linux_fs/u-boot/board/socrates/nand.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * (C) Copyright 2008
3*4882a593Smuzhiyun  * Sergei Poselenov, Emcraft Systems, sposelenov@emcraft.com.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <common.h>
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #if defined(CONFIG_SYS_NAND_BASE)
11*4882a593Smuzhiyun #include <nand.h>
12*4882a593Smuzhiyun #include <linux/errno.h>
13*4882a593Smuzhiyun #include <asm/io.h>
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun static int state;
16*4882a593Smuzhiyun static void sc_nand_write_byte(struct mtd_info *mtd, u_char byte);
17*4882a593Smuzhiyun static void sc_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len);
18*4882a593Smuzhiyun static u_char sc_nand_read_byte(struct mtd_info *mtd);
19*4882a593Smuzhiyun static u16 sc_nand_read_word(struct mtd_info *mtd);
20*4882a593Smuzhiyun static void sc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len);
21*4882a593Smuzhiyun static int sc_nand_device_ready(struct mtd_info *mtdinfo);
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #define FPGA_NAND_CMD_MASK		(0x7 << 28)
24*4882a593Smuzhiyun #define FPGA_NAND_CMD_COMMAND		(0x0 << 28)
25*4882a593Smuzhiyun #define FPGA_NAND_CMD_ADDR		(0x1 << 28)
26*4882a593Smuzhiyun #define FPGA_NAND_CMD_READ		(0x2 << 28)
27*4882a593Smuzhiyun #define FPGA_NAND_CMD_WRITE		(0x3 << 28)
28*4882a593Smuzhiyun #define FPGA_NAND_BUSY			(0x1 << 15)
29*4882a593Smuzhiyun #define FPGA_NAND_ENABLE		(0x1 << 31)
30*4882a593Smuzhiyun #define FPGA_NAND_DATA_SHIFT		16
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun /**
33*4882a593Smuzhiyun  * sc_nand_write_byte -  write one byte to the chip
34*4882a593Smuzhiyun  * @mtd:	MTD device structure
35*4882a593Smuzhiyun  * @byte:	pointer to data byte to write
36*4882a593Smuzhiyun  */
sc_nand_write_byte(struct mtd_info * mtd,u_char byte)37*4882a593Smuzhiyun static void sc_nand_write_byte(struct mtd_info *mtd, u_char byte)
38*4882a593Smuzhiyun {
39*4882a593Smuzhiyun 	sc_nand_write_buf(mtd, (const uchar *)&byte, sizeof(byte));
40*4882a593Smuzhiyun }
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun /**
43*4882a593Smuzhiyun  * sc_nand_write_buf -  write buffer to chip
44*4882a593Smuzhiyun  * @mtd:	MTD device structure
45*4882a593Smuzhiyun  * @buf:	data buffer
46*4882a593Smuzhiyun  * @len:	number of bytes to write
47*4882a593Smuzhiyun  */
sc_nand_write_buf(struct mtd_info * mtd,const u_char * buf,int len)48*4882a593Smuzhiyun static void sc_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
49*4882a593Smuzhiyun {
50*4882a593Smuzhiyun 	int i;
51*4882a593Smuzhiyun 	struct nand_chip *this = mtd_to_nand(mtd);
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun 	for (i = 0; i < len; i++) {
54*4882a593Smuzhiyun 		out_be32(this->IO_ADDR_W,
55*4882a593Smuzhiyun 			 state | (buf[i] << FPGA_NAND_DATA_SHIFT));
56*4882a593Smuzhiyun 	}
57*4882a593Smuzhiyun }
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun /**
61*4882a593Smuzhiyun  * sc_nand_read_byte -  read one byte from the chip
62*4882a593Smuzhiyun  * @mtd:	MTD device structure
63*4882a593Smuzhiyun  */
sc_nand_read_byte(struct mtd_info * mtd)64*4882a593Smuzhiyun static u_char sc_nand_read_byte(struct mtd_info *mtd)
65*4882a593Smuzhiyun {
66*4882a593Smuzhiyun 	u8 byte;
67*4882a593Smuzhiyun 	sc_nand_read_buf(mtd, (uchar *)&byte, sizeof(byte));
68*4882a593Smuzhiyun 	return byte;
69*4882a593Smuzhiyun }
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun /**
72*4882a593Smuzhiyun  * sc_nand_read_word -  read one word from the chip
73*4882a593Smuzhiyun  * @mtd:	MTD device structure
74*4882a593Smuzhiyun  */
sc_nand_read_word(struct mtd_info * mtd)75*4882a593Smuzhiyun static u16 sc_nand_read_word(struct mtd_info *mtd)
76*4882a593Smuzhiyun {
77*4882a593Smuzhiyun 	u16 word;
78*4882a593Smuzhiyun 	sc_nand_read_buf(mtd, (uchar *)&word, sizeof(word));
79*4882a593Smuzhiyun 	return word;
80*4882a593Smuzhiyun }
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun /**
83*4882a593Smuzhiyun  * sc_nand_read_buf -  read chip data into buffer
84*4882a593Smuzhiyun  * @mtd:	MTD device structure
85*4882a593Smuzhiyun  * @buf:	buffer to store date
86*4882a593Smuzhiyun  * @len:	number of bytes to read
87*4882a593Smuzhiyun  */
sc_nand_read_buf(struct mtd_info * mtd,u_char * buf,int len)88*4882a593Smuzhiyun static void sc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
89*4882a593Smuzhiyun {
90*4882a593Smuzhiyun 	int i;
91*4882a593Smuzhiyun 	struct nand_chip *this = mtd_to_nand(mtd);
92*4882a593Smuzhiyun 	int val;
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 	val = (state & FPGA_NAND_ENABLE) | FPGA_NAND_CMD_READ;
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun 	out_be32(this->IO_ADDR_W, val);
97*4882a593Smuzhiyun 	for (i = 0; i < len; i++) {
98*4882a593Smuzhiyun 		buf[i] = (in_be32(this->IO_ADDR_R) >> FPGA_NAND_DATA_SHIFT) & 0xff;
99*4882a593Smuzhiyun 	}
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun /**
103*4882a593Smuzhiyun  * sc_nand_device_ready - Check the NAND device is ready for next command.
104*4882a593Smuzhiyun  * @mtd:	MTD device structure
105*4882a593Smuzhiyun  */
sc_nand_device_ready(struct mtd_info * mtdinfo)106*4882a593Smuzhiyun static int sc_nand_device_ready(struct mtd_info *mtdinfo)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun 	struct nand_chip *this = mtd_to_nand(mtdinfo);
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun 	if (in_be32(this->IO_ADDR_W) & FPGA_NAND_BUSY)
111*4882a593Smuzhiyun 		return 0; /* busy */
112*4882a593Smuzhiyun 	return 1;
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun /**
116*4882a593Smuzhiyun  * sc_nand_hwcontrol - NAND control functions wrapper.
117*4882a593Smuzhiyun  * @mtd:	MTD device structure
118*4882a593Smuzhiyun  * @cmd:	Command
119*4882a593Smuzhiyun  */
sc_nand_hwcontrol(struct mtd_info * mtdinfo,int cmd,unsigned int ctrl)120*4882a593Smuzhiyun static void sc_nand_hwcontrol(struct mtd_info *mtdinfo, int cmd, unsigned int ctrl)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun 	if (ctrl & NAND_CTRL_CHANGE) {
123*4882a593Smuzhiyun 		state &= ~(FPGA_NAND_CMD_MASK | FPGA_NAND_ENABLE);
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 		switch (ctrl & (NAND_ALE | NAND_CLE)) {
126*4882a593Smuzhiyun 		case 0:
127*4882a593Smuzhiyun 			state |= FPGA_NAND_CMD_WRITE;
128*4882a593Smuzhiyun 			break;
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 		case NAND_ALE:
131*4882a593Smuzhiyun 			state |= FPGA_NAND_CMD_ADDR;
132*4882a593Smuzhiyun 			break;
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun 		case NAND_CLE:
135*4882a593Smuzhiyun 			state |= FPGA_NAND_CMD_COMMAND;
136*4882a593Smuzhiyun 			break;
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 		default:
139*4882a593Smuzhiyun 			printf("%s: unknown ctrl %#x\n", __FUNCTION__, ctrl);
140*4882a593Smuzhiyun 		}
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 		if (ctrl & NAND_NCE)
143*4882a593Smuzhiyun 			state |= FPGA_NAND_ENABLE;
144*4882a593Smuzhiyun 	}
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun 	if (cmd != NAND_CMD_NONE)
147*4882a593Smuzhiyun 		sc_nand_write_byte(mtdinfo, cmd);
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun 
board_nand_init(struct nand_chip * nand)150*4882a593Smuzhiyun int board_nand_init(struct nand_chip *nand)
151*4882a593Smuzhiyun {
152*4882a593Smuzhiyun 	nand->cmd_ctrl = sc_nand_hwcontrol;
153*4882a593Smuzhiyun 	nand->ecc.mode = NAND_ECC_SOFT;
154*4882a593Smuzhiyun 	nand->dev_ready = sc_nand_device_ready;
155*4882a593Smuzhiyun 	nand->read_byte = sc_nand_read_byte;
156*4882a593Smuzhiyun 	nand->read_word = sc_nand_read_word;
157*4882a593Smuzhiyun 	nand->write_buf = sc_nand_write_buf;
158*4882a593Smuzhiyun 	nand->read_buf = sc_nand_read_buf;
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun 	return 0;
161*4882a593Smuzhiyun }
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun #endif
164