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