1*a430fa06SMiquel Raynal // SPDX-License-Identifier: GPL-2.0+
2*a430fa06SMiquel Raynal /*
3*a430fa06SMiquel Raynal * FSL UPM NAND driver
4*a430fa06SMiquel Raynal *
5*a430fa06SMiquel Raynal * Copyright (C) 2007 MontaVista Software, Inc.
6*a430fa06SMiquel Raynal * Anton Vorontsov <avorontsov@ru.mvista.com>
7*a430fa06SMiquel Raynal */
8*a430fa06SMiquel Raynal
9*a430fa06SMiquel Raynal #include <config.h>
10*a430fa06SMiquel Raynal #include <common.h>
11*a430fa06SMiquel Raynal #include <asm/io.h>
12*a430fa06SMiquel Raynal #include <linux/errno.h>
13*a430fa06SMiquel Raynal #include <linux/mtd/mtd.h>
14*a430fa06SMiquel Raynal #include <linux/mtd/fsl_upm.h>
15*a430fa06SMiquel Raynal #include <nand.h>
16*a430fa06SMiquel Raynal
fsl_upm_start_pattern(struct fsl_upm * upm,u32 pat_offset)17*a430fa06SMiquel Raynal static void fsl_upm_start_pattern(struct fsl_upm *upm, u32 pat_offset)
18*a430fa06SMiquel Raynal {
19*a430fa06SMiquel Raynal clrsetbits_be32(upm->mxmr, MxMR_MAD_MSK, MxMR_OP_RUNP | pat_offset);
20*a430fa06SMiquel Raynal (void)in_be32(upm->mxmr);
21*a430fa06SMiquel Raynal }
22*a430fa06SMiquel Raynal
fsl_upm_end_pattern(struct fsl_upm * upm)23*a430fa06SMiquel Raynal static void fsl_upm_end_pattern(struct fsl_upm *upm)
24*a430fa06SMiquel Raynal {
25*a430fa06SMiquel Raynal clrbits_be32(upm->mxmr, MxMR_OP_RUNP);
26*a430fa06SMiquel Raynal
27*a430fa06SMiquel Raynal while (in_be32(upm->mxmr) & MxMR_OP_RUNP)
28*a430fa06SMiquel Raynal eieio();
29*a430fa06SMiquel Raynal }
30*a430fa06SMiquel Raynal
fsl_upm_run_pattern(struct fsl_upm * upm,int width,void __iomem * io_addr,u32 mar)31*a430fa06SMiquel Raynal static void fsl_upm_run_pattern(struct fsl_upm *upm, int width,
32*a430fa06SMiquel Raynal void __iomem *io_addr, u32 mar)
33*a430fa06SMiquel Raynal {
34*a430fa06SMiquel Raynal out_be32(upm->mar, mar);
35*a430fa06SMiquel Raynal (void)in_be32(upm->mar);
36*a430fa06SMiquel Raynal switch (width) {
37*a430fa06SMiquel Raynal case 8:
38*a430fa06SMiquel Raynal out_8(io_addr, 0x0);
39*a430fa06SMiquel Raynal break;
40*a430fa06SMiquel Raynal case 16:
41*a430fa06SMiquel Raynal out_be16(io_addr, 0x0);
42*a430fa06SMiquel Raynal break;
43*a430fa06SMiquel Raynal case 32:
44*a430fa06SMiquel Raynal out_be32(io_addr, 0x0);
45*a430fa06SMiquel Raynal break;
46*a430fa06SMiquel Raynal }
47*a430fa06SMiquel Raynal }
48*a430fa06SMiquel Raynal
fun_wait(struct fsl_upm_nand * fun)49*a430fa06SMiquel Raynal static void fun_wait(struct fsl_upm_nand *fun)
50*a430fa06SMiquel Raynal {
51*a430fa06SMiquel Raynal if (fun->dev_ready) {
52*a430fa06SMiquel Raynal while (!fun->dev_ready(fun->chip_nr))
53*a430fa06SMiquel Raynal debug("unexpected busy state\n");
54*a430fa06SMiquel Raynal } else {
55*a430fa06SMiquel Raynal /*
56*a430fa06SMiquel Raynal * If the R/B pin is not connected,
57*a430fa06SMiquel Raynal * a short delay is necessary.
58*a430fa06SMiquel Raynal */
59*a430fa06SMiquel Raynal udelay(1);
60*a430fa06SMiquel Raynal }
61*a430fa06SMiquel Raynal }
62*a430fa06SMiquel Raynal
63*a430fa06SMiquel Raynal #if CONFIG_SYS_NAND_MAX_CHIPS > 1
fun_select_chip(struct mtd_info * mtd,int chip_nr)64*a430fa06SMiquel Raynal static void fun_select_chip(struct mtd_info *mtd, int chip_nr)
65*a430fa06SMiquel Raynal {
66*a430fa06SMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
67*a430fa06SMiquel Raynal struct fsl_upm_nand *fun = nand_get_controller_data(chip);
68*a430fa06SMiquel Raynal
69*a430fa06SMiquel Raynal if (chip_nr >= 0) {
70*a430fa06SMiquel Raynal fun->chip_nr = chip_nr;
71*a430fa06SMiquel Raynal chip->IO_ADDR_R = chip->IO_ADDR_W =
72*a430fa06SMiquel Raynal fun->upm.io_addr + fun->chip_offset * chip_nr;
73*a430fa06SMiquel Raynal } else if (chip_nr == -1) {
74*a430fa06SMiquel Raynal chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
75*a430fa06SMiquel Raynal }
76*a430fa06SMiquel Raynal }
77*a430fa06SMiquel Raynal #endif
78*a430fa06SMiquel Raynal
fun_cmd_ctrl(struct mtd_info * mtd,int cmd,unsigned int ctrl)79*a430fa06SMiquel Raynal static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
80*a430fa06SMiquel Raynal {
81*a430fa06SMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
82*a430fa06SMiquel Raynal struct fsl_upm_nand *fun = nand_get_controller_data(chip);
83*a430fa06SMiquel Raynal void __iomem *io_addr;
84*a430fa06SMiquel Raynal u32 mar;
85*a430fa06SMiquel Raynal
86*a430fa06SMiquel Raynal if (!(ctrl & fun->last_ctrl)) {
87*a430fa06SMiquel Raynal fsl_upm_end_pattern(&fun->upm);
88*a430fa06SMiquel Raynal
89*a430fa06SMiquel Raynal if (cmd == NAND_CMD_NONE)
90*a430fa06SMiquel Raynal return;
91*a430fa06SMiquel Raynal
92*a430fa06SMiquel Raynal fun->last_ctrl = ctrl & (NAND_ALE | NAND_CLE);
93*a430fa06SMiquel Raynal }
94*a430fa06SMiquel Raynal
95*a430fa06SMiquel Raynal if (ctrl & NAND_CTRL_CHANGE) {
96*a430fa06SMiquel Raynal if (ctrl & NAND_ALE)
97*a430fa06SMiquel Raynal fsl_upm_start_pattern(&fun->upm, fun->upm_addr_offset);
98*a430fa06SMiquel Raynal else if (ctrl & NAND_CLE)
99*a430fa06SMiquel Raynal fsl_upm_start_pattern(&fun->upm, fun->upm_cmd_offset);
100*a430fa06SMiquel Raynal }
101*a430fa06SMiquel Raynal
102*a430fa06SMiquel Raynal mar = cmd << (32 - fun->width);
103*a430fa06SMiquel Raynal io_addr = fun->upm.io_addr;
104*a430fa06SMiquel Raynal #if CONFIG_SYS_NAND_MAX_CHIPS > 1
105*a430fa06SMiquel Raynal if (fun->chip_nr > 0) {
106*a430fa06SMiquel Raynal io_addr += fun->chip_offset * fun->chip_nr;
107*a430fa06SMiquel Raynal if (fun->upm_mar_chip_offset)
108*a430fa06SMiquel Raynal mar |= fun->upm_mar_chip_offset * fun->chip_nr;
109*a430fa06SMiquel Raynal }
110*a430fa06SMiquel Raynal #endif
111*a430fa06SMiquel Raynal fsl_upm_run_pattern(&fun->upm, fun->width, io_addr, mar);
112*a430fa06SMiquel Raynal
113*a430fa06SMiquel Raynal /*
114*a430fa06SMiquel Raynal * Some boards/chips needs this. At least the MPC8360E-RDK
115*a430fa06SMiquel Raynal * needs it. Probably weird chip, because I don't see any
116*a430fa06SMiquel Raynal * need for this on MPC8555E + Samsung K9F1G08U0A. Usually
117*a430fa06SMiquel Raynal * here are 0-2 unexpected busy states per block read.
118*a430fa06SMiquel Raynal */
119*a430fa06SMiquel Raynal if (fun->wait_flags & FSL_UPM_WAIT_RUN_PATTERN)
120*a430fa06SMiquel Raynal fun_wait(fun);
121*a430fa06SMiquel Raynal }
122*a430fa06SMiquel Raynal
upm_nand_read_byte(struct mtd_info * mtd)123*a430fa06SMiquel Raynal static u8 upm_nand_read_byte(struct mtd_info *mtd)
124*a430fa06SMiquel Raynal {
125*a430fa06SMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
126*a430fa06SMiquel Raynal
127*a430fa06SMiquel Raynal return in_8(chip->IO_ADDR_R);
128*a430fa06SMiquel Raynal }
129*a430fa06SMiquel Raynal
upm_nand_write_buf(struct mtd_info * mtd,const u_char * buf,int len)130*a430fa06SMiquel Raynal static void upm_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
131*a430fa06SMiquel Raynal {
132*a430fa06SMiquel Raynal int i;
133*a430fa06SMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
134*a430fa06SMiquel Raynal struct fsl_upm_nand *fun = nand_get_controller_data(chip);
135*a430fa06SMiquel Raynal
136*a430fa06SMiquel Raynal for (i = 0; i < len; i++) {
137*a430fa06SMiquel Raynal out_8(chip->IO_ADDR_W, buf[i]);
138*a430fa06SMiquel Raynal if (fun->wait_flags & FSL_UPM_WAIT_WRITE_BYTE)
139*a430fa06SMiquel Raynal fun_wait(fun);
140*a430fa06SMiquel Raynal }
141*a430fa06SMiquel Raynal
142*a430fa06SMiquel Raynal if (fun->wait_flags & FSL_UPM_WAIT_WRITE_BUFFER)
143*a430fa06SMiquel Raynal fun_wait(fun);
144*a430fa06SMiquel Raynal }
145*a430fa06SMiquel Raynal
upm_nand_read_buf(struct mtd_info * mtd,u_char * buf,int len)146*a430fa06SMiquel Raynal static void upm_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
147*a430fa06SMiquel Raynal {
148*a430fa06SMiquel Raynal int i;
149*a430fa06SMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
150*a430fa06SMiquel Raynal
151*a430fa06SMiquel Raynal for (i = 0; i < len; i++)
152*a430fa06SMiquel Raynal buf[i] = in_8(chip->IO_ADDR_R);
153*a430fa06SMiquel Raynal }
154*a430fa06SMiquel Raynal
nand_dev_ready(struct mtd_info * mtd)155*a430fa06SMiquel Raynal static int nand_dev_ready(struct mtd_info *mtd)
156*a430fa06SMiquel Raynal {
157*a430fa06SMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
158*a430fa06SMiquel Raynal struct fsl_upm_nand *fun = nand_get_controller_data(chip);
159*a430fa06SMiquel Raynal
160*a430fa06SMiquel Raynal return fun->dev_ready(fun->chip_nr);
161*a430fa06SMiquel Raynal }
162*a430fa06SMiquel Raynal
fsl_upm_nand_init(struct nand_chip * chip,struct fsl_upm_nand * fun)163*a430fa06SMiquel Raynal int fsl_upm_nand_init(struct nand_chip *chip, struct fsl_upm_nand *fun)
164*a430fa06SMiquel Raynal {
165*a430fa06SMiquel Raynal if (fun->width != 8 && fun->width != 16 && fun->width != 32)
166*a430fa06SMiquel Raynal return -ENOSYS;
167*a430fa06SMiquel Raynal
168*a430fa06SMiquel Raynal fun->last_ctrl = NAND_CLE;
169*a430fa06SMiquel Raynal
170*a430fa06SMiquel Raynal nand_set_controller_data(chip, fun);
171*a430fa06SMiquel Raynal chip->chip_delay = fun->chip_delay;
172*a430fa06SMiquel Raynal chip->ecc.mode = NAND_ECC_SOFT;
173*a430fa06SMiquel Raynal chip->cmd_ctrl = fun_cmd_ctrl;
174*a430fa06SMiquel Raynal #if CONFIG_SYS_NAND_MAX_CHIPS > 1
175*a430fa06SMiquel Raynal chip->select_chip = fun_select_chip;
176*a430fa06SMiquel Raynal #endif
177*a430fa06SMiquel Raynal chip->read_byte = upm_nand_read_byte;
178*a430fa06SMiquel Raynal chip->read_buf = upm_nand_read_buf;
179*a430fa06SMiquel Raynal chip->write_buf = upm_nand_write_buf;
180*a430fa06SMiquel Raynal if (fun->dev_ready)
181*a430fa06SMiquel Raynal chip->dev_ready = nand_dev_ready;
182*a430fa06SMiquel Raynal
183*a430fa06SMiquel Raynal return 0;
184*a430fa06SMiquel Raynal }
185