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