1*15f504adSChristophe Kerello // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
2*15f504adSChristophe Kerello /*
3*15f504adSChristophe Kerello * Copyright (C) STMicroelectronics 2019
4*15f504adSChristophe Kerello * Author: Christophe Kerello <christophe.kerello@st.com>
5*15f504adSChristophe Kerello */
6*15f504adSChristophe Kerello
7*15f504adSChristophe Kerello #include <common.h>
8*15f504adSChristophe Kerello #include <clk.h>
9*15f504adSChristophe Kerello #include <dm.h>
10*15f504adSChristophe Kerello #include <nand.h>
11*15f504adSChristophe Kerello #include <reset.h>
12*15f504adSChristophe Kerello #include <linux/iopoll.h>
13*15f504adSChristophe Kerello #include <linux/ioport.h>
14*15f504adSChristophe Kerello
15*15f504adSChristophe Kerello /* Bad block marker length */
16*15f504adSChristophe Kerello #define FMC2_BBM_LEN 2
17*15f504adSChristophe Kerello
18*15f504adSChristophe Kerello /* ECC step size */
19*15f504adSChristophe Kerello #define FMC2_ECC_STEP_SIZE 512
20*15f504adSChristophe Kerello
21*15f504adSChristophe Kerello /* Command delay */
22*15f504adSChristophe Kerello #define FMC2_RB_DELAY_US 30
23*15f504adSChristophe Kerello
24*15f504adSChristophe Kerello /* Max chip enable */
25*15f504adSChristophe Kerello #define FMC2_MAX_CE 2
26*15f504adSChristophe Kerello
27*15f504adSChristophe Kerello /* Timings */
28*15f504adSChristophe Kerello #define FMC2_THIZ 1
29*15f504adSChristophe Kerello #define FMC2_TIO 8000
30*15f504adSChristophe Kerello #define FMC2_TSYNC 3000
31*15f504adSChristophe Kerello #define FMC2_PCR_TIMING_MASK 0xf
32*15f504adSChristophe Kerello #define FMC2_PMEM_PATT_TIMING_MASK 0xff
33*15f504adSChristophe Kerello
34*15f504adSChristophe Kerello /* FMC2 Controller Registers */
35*15f504adSChristophe Kerello #define FMC2_BCR1 0x0
36*15f504adSChristophe Kerello #define FMC2_PCR 0x80
37*15f504adSChristophe Kerello #define FMC2_SR 0x84
38*15f504adSChristophe Kerello #define FMC2_PMEM 0x88
39*15f504adSChristophe Kerello #define FMC2_PATT 0x8c
40*15f504adSChristophe Kerello #define FMC2_HECCR 0x94
41*15f504adSChristophe Kerello #define FMC2_BCHISR 0x254
42*15f504adSChristophe Kerello #define FMC2_BCHICR 0x258
43*15f504adSChristophe Kerello #define FMC2_BCHPBR1 0x260
44*15f504adSChristophe Kerello #define FMC2_BCHPBR2 0x264
45*15f504adSChristophe Kerello #define FMC2_BCHPBR3 0x268
46*15f504adSChristophe Kerello #define FMC2_BCHPBR4 0x26c
47*15f504adSChristophe Kerello #define FMC2_BCHDSR0 0x27c
48*15f504adSChristophe Kerello #define FMC2_BCHDSR1 0x280
49*15f504adSChristophe Kerello #define FMC2_BCHDSR2 0x284
50*15f504adSChristophe Kerello #define FMC2_BCHDSR3 0x288
51*15f504adSChristophe Kerello #define FMC2_BCHDSR4 0x28c
52*15f504adSChristophe Kerello
53*15f504adSChristophe Kerello /* Register: FMC2_BCR1 */
54*15f504adSChristophe Kerello #define FMC2_BCR1_FMC2EN BIT(31)
55*15f504adSChristophe Kerello
56*15f504adSChristophe Kerello /* Register: FMC2_PCR */
57*15f504adSChristophe Kerello #define FMC2_PCR_PWAITEN BIT(1)
58*15f504adSChristophe Kerello #define FMC2_PCR_PBKEN BIT(2)
59*15f504adSChristophe Kerello #define FMC2_PCR_PWID_MASK GENMASK(5, 4)
60*15f504adSChristophe Kerello #define FMC2_PCR_PWID(x) (((x) & 0x3) << 4)
61*15f504adSChristophe Kerello #define FMC2_PCR_PWID_BUSWIDTH_8 0
62*15f504adSChristophe Kerello #define FMC2_PCR_PWID_BUSWIDTH_16 1
63*15f504adSChristophe Kerello #define FMC2_PCR_ECCEN BIT(6)
64*15f504adSChristophe Kerello #define FMC2_PCR_ECCALG BIT(8)
65*15f504adSChristophe Kerello #define FMC2_PCR_TCLR_MASK GENMASK(12, 9)
66*15f504adSChristophe Kerello #define FMC2_PCR_TCLR(x) (((x) & 0xf) << 9)
67*15f504adSChristophe Kerello #define FMC2_PCR_TCLR_DEFAULT 0xf
68*15f504adSChristophe Kerello #define FMC2_PCR_TAR_MASK GENMASK(16, 13)
69*15f504adSChristophe Kerello #define FMC2_PCR_TAR(x) (((x) & 0xf) << 13)
70*15f504adSChristophe Kerello #define FMC2_PCR_TAR_DEFAULT 0xf
71*15f504adSChristophe Kerello #define FMC2_PCR_ECCSS_MASK GENMASK(19, 17)
72*15f504adSChristophe Kerello #define FMC2_PCR_ECCSS(x) (((x) & 0x7) << 17)
73*15f504adSChristophe Kerello #define FMC2_PCR_ECCSS_512 1
74*15f504adSChristophe Kerello #define FMC2_PCR_ECCSS_2048 3
75*15f504adSChristophe Kerello #define FMC2_PCR_BCHECC BIT(24)
76*15f504adSChristophe Kerello #define FMC2_PCR_WEN BIT(25)
77*15f504adSChristophe Kerello
78*15f504adSChristophe Kerello /* Register: FMC2_SR */
79*15f504adSChristophe Kerello #define FMC2_SR_NWRF BIT(6)
80*15f504adSChristophe Kerello
81*15f504adSChristophe Kerello /* Register: FMC2_PMEM */
82*15f504adSChristophe Kerello #define FMC2_PMEM_MEMSET(x) (((x) & 0xff) << 0)
83*15f504adSChristophe Kerello #define FMC2_PMEM_MEMWAIT(x) (((x) & 0xff) << 8)
84*15f504adSChristophe Kerello #define FMC2_PMEM_MEMHOLD(x) (((x) & 0xff) << 16)
85*15f504adSChristophe Kerello #define FMC2_PMEM_MEMHIZ(x) (((x) & 0xff) << 24)
86*15f504adSChristophe Kerello #define FMC2_PMEM_DEFAULT 0x0a0a0a0a
87*15f504adSChristophe Kerello
88*15f504adSChristophe Kerello /* Register: FMC2_PATT */
89*15f504adSChristophe Kerello #define FMC2_PATT_ATTSET(x) (((x) & 0xff) << 0)
90*15f504adSChristophe Kerello #define FMC2_PATT_ATTWAIT(x) (((x) & 0xff) << 8)
91*15f504adSChristophe Kerello #define FMC2_PATT_ATTHOLD(x) (((x) & 0xff) << 16)
92*15f504adSChristophe Kerello #define FMC2_PATT_ATTHIZ(x) (((x) & 0xff) << 24)
93*15f504adSChristophe Kerello #define FMC2_PATT_DEFAULT 0x0a0a0a0a
94*15f504adSChristophe Kerello
95*15f504adSChristophe Kerello /* Register: FMC2_BCHISR */
96*15f504adSChristophe Kerello #define FMC2_BCHISR_DERF BIT(1)
97*15f504adSChristophe Kerello #define FMC2_BCHISR_EPBRF BIT(4)
98*15f504adSChristophe Kerello
99*15f504adSChristophe Kerello /* Register: FMC2_BCHICR */
100*15f504adSChristophe Kerello #define FMC2_BCHICR_CLEAR_IRQ GENMASK(4, 0)
101*15f504adSChristophe Kerello
102*15f504adSChristophe Kerello /* Register: FMC2_BCHDSR0 */
103*15f504adSChristophe Kerello #define FMC2_BCHDSR0_DUE BIT(0)
104*15f504adSChristophe Kerello #define FMC2_BCHDSR0_DEF BIT(1)
105*15f504adSChristophe Kerello #define FMC2_BCHDSR0_DEN_MASK GENMASK(7, 4)
106*15f504adSChristophe Kerello #define FMC2_BCHDSR0_DEN_SHIFT 4
107*15f504adSChristophe Kerello
108*15f504adSChristophe Kerello /* Register: FMC2_BCHDSR1 */
109*15f504adSChristophe Kerello #define FMC2_BCHDSR1_EBP1_MASK GENMASK(12, 0)
110*15f504adSChristophe Kerello #define FMC2_BCHDSR1_EBP2_MASK GENMASK(28, 16)
111*15f504adSChristophe Kerello #define FMC2_BCHDSR1_EBP2_SHIFT 16
112*15f504adSChristophe Kerello
113*15f504adSChristophe Kerello /* Register: FMC2_BCHDSR2 */
114*15f504adSChristophe Kerello #define FMC2_BCHDSR2_EBP3_MASK GENMASK(12, 0)
115*15f504adSChristophe Kerello #define FMC2_BCHDSR2_EBP4_MASK GENMASK(28, 16)
116*15f504adSChristophe Kerello #define FMC2_BCHDSR2_EBP4_SHIFT 16
117*15f504adSChristophe Kerello
118*15f504adSChristophe Kerello /* Register: FMC2_BCHDSR3 */
119*15f504adSChristophe Kerello #define FMC2_BCHDSR3_EBP5_MASK GENMASK(12, 0)
120*15f504adSChristophe Kerello #define FMC2_BCHDSR3_EBP6_MASK GENMASK(28, 16)
121*15f504adSChristophe Kerello #define FMC2_BCHDSR3_EBP6_SHIFT 16
122*15f504adSChristophe Kerello
123*15f504adSChristophe Kerello /* Register: FMC2_BCHDSR4 */
124*15f504adSChristophe Kerello #define FMC2_BCHDSR4_EBP7_MASK GENMASK(12, 0)
125*15f504adSChristophe Kerello #define FMC2_BCHDSR4_EBP8_MASK GENMASK(28, 16)
126*15f504adSChristophe Kerello #define FMC2_BCHDSR4_EBP8_SHIFT 16
127*15f504adSChristophe Kerello
128*15f504adSChristophe Kerello #define FMC2_NSEC_PER_SEC 1000000000L
129*15f504adSChristophe Kerello
130*15f504adSChristophe Kerello enum stm32_fmc2_ecc {
131*15f504adSChristophe Kerello FMC2_ECC_HAM = 1,
132*15f504adSChristophe Kerello FMC2_ECC_BCH4 = 4,
133*15f504adSChristophe Kerello FMC2_ECC_BCH8 = 8
134*15f504adSChristophe Kerello };
135*15f504adSChristophe Kerello
136*15f504adSChristophe Kerello struct stm32_fmc2_timings {
137*15f504adSChristophe Kerello u8 tclr;
138*15f504adSChristophe Kerello u8 tar;
139*15f504adSChristophe Kerello u8 thiz;
140*15f504adSChristophe Kerello u8 twait;
141*15f504adSChristophe Kerello u8 thold_mem;
142*15f504adSChristophe Kerello u8 tset_mem;
143*15f504adSChristophe Kerello u8 thold_att;
144*15f504adSChristophe Kerello u8 tset_att;
145*15f504adSChristophe Kerello };
146*15f504adSChristophe Kerello
147*15f504adSChristophe Kerello struct stm32_fmc2_nand {
148*15f504adSChristophe Kerello struct nand_chip chip;
149*15f504adSChristophe Kerello struct stm32_fmc2_timings timings;
150*15f504adSChristophe Kerello int ncs;
151*15f504adSChristophe Kerello int cs_used[FMC2_MAX_CE];
152*15f504adSChristophe Kerello };
153*15f504adSChristophe Kerello
to_fmc2_nand(struct nand_chip * chip)154*15f504adSChristophe Kerello static inline struct stm32_fmc2_nand *to_fmc2_nand(struct nand_chip *chip)
155*15f504adSChristophe Kerello {
156*15f504adSChristophe Kerello return container_of(chip, struct stm32_fmc2_nand, chip);
157*15f504adSChristophe Kerello }
158*15f504adSChristophe Kerello
159*15f504adSChristophe Kerello struct stm32_fmc2_nfc {
160*15f504adSChristophe Kerello struct nand_hw_control base;
161*15f504adSChristophe Kerello struct stm32_fmc2_nand nand;
162*15f504adSChristophe Kerello struct nand_ecclayout ecclayout;
163*15f504adSChristophe Kerello void __iomem *io_base;
164*15f504adSChristophe Kerello void __iomem *data_base[FMC2_MAX_CE];
165*15f504adSChristophe Kerello void __iomem *cmd_base[FMC2_MAX_CE];
166*15f504adSChristophe Kerello void __iomem *addr_base[FMC2_MAX_CE];
167*15f504adSChristophe Kerello struct clk clk;
168*15f504adSChristophe Kerello
169*15f504adSChristophe Kerello u8 cs_assigned;
170*15f504adSChristophe Kerello int cs_sel;
171*15f504adSChristophe Kerello };
172*15f504adSChristophe Kerello
to_stm32_nfc(struct nand_hw_control * base)173*15f504adSChristophe Kerello static inline struct stm32_fmc2_nfc *to_stm32_nfc(struct nand_hw_control *base)
174*15f504adSChristophe Kerello {
175*15f504adSChristophe Kerello return container_of(base, struct stm32_fmc2_nfc, base);
176*15f504adSChristophe Kerello }
177*15f504adSChristophe Kerello
178*15f504adSChristophe Kerello /* Timings configuration */
stm32_fmc2_timings_init(struct nand_chip * chip)179*15f504adSChristophe Kerello static void stm32_fmc2_timings_init(struct nand_chip *chip)
180*15f504adSChristophe Kerello {
181*15f504adSChristophe Kerello struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
182*15f504adSChristophe Kerello struct stm32_fmc2_nand *nand = to_fmc2_nand(chip);
183*15f504adSChristophe Kerello struct stm32_fmc2_timings *timings = &nand->timings;
184*15f504adSChristophe Kerello u32 pcr = readl(fmc2->io_base + FMC2_PCR);
185*15f504adSChristophe Kerello u32 pmem, patt;
186*15f504adSChristophe Kerello
187*15f504adSChristophe Kerello /* Set tclr/tar timings */
188*15f504adSChristophe Kerello pcr &= ~FMC2_PCR_TCLR_MASK;
189*15f504adSChristophe Kerello pcr |= FMC2_PCR_TCLR(timings->tclr);
190*15f504adSChristophe Kerello pcr &= ~FMC2_PCR_TAR_MASK;
191*15f504adSChristophe Kerello pcr |= FMC2_PCR_TAR(timings->tar);
192*15f504adSChristophe Kerello
193*15f504adSChristophe Kerello /* Set tset/twait/thold/thiz timings in common bank */
194*15f504adSChristophe Kerello pmem = FMC2_PMEM_MEMSET(timings->tset_mem);
195*15f504adSChristophe Kerello pmem |= FMC2_PMEM_MEMWAIT(timings->twait);
196*15f504adSChristophe Kerello pmem |= FMC2_PMEM_MEMHOLD(timings->thold_mem);
197*15f504adSChristophe Kerello pmem |= FMC2_PMEM_MEMHIZ(timings->thiz);
198*15f504adSChristophe Kerello
199*15f504adSChristophe Kerello /* Set tset/twait/thold/thiz timings in attribut bank */
200*15f504adSChristophe Kerello patt = FMC2_PATT_ATTSET(timings->tset_att);
201*15f504adSChristophe Kerello patt |= FMC2_PATT_ATTWAIT(timings->twait);
202*15f504adSChristophe Kerello patt |= FMC2_PATT_ATTHOLD(timings->thold_att);
203*15f504adSChristophe Kerello patt |= FMC2_PATT_ATTHIZ(timings->thiz);
204*15f504adSChristophe Kerello
205*15f504adSChristophe Kerello writel(pcr, fmc2->io_base + FMC2_PCR);
206*15f504adSChristophe Kerello writel(pmem, fmc2->io_base + FMC2_PMEM);
207*15f504adSChristophe Kerello writel(patt, fmc2->io_base + FMC2_PATT);
208*15f504adSChristophe Kerello }
209*15f504adSChristophe Kerello
210*15f504adSChristophe Kerello /* Controller configuration */
stm32_fmc2_setup(struct nand_chip * chip)211*15f504adSChristophe Kerello static void stm32_fmc2_setup(struct nand_chip *chip)
212*15f504adSChristophe Kerello {
213*15f504adSChristophe Kerello struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
214*15f504adSChristophe Kerello u32 pcr = readl(fmc2->io_base + FMC2_PCR);
215*15f504adSChristophe Kerello
216*15f504adSChristophe Kerello /* Configure ECC algorithm (default configuration is Hamming) */
217*15f504adSChristophe Kerello pcr &= ~FMC2_PCR_ECCALG;
218*15f504adSChristophe Kerello pcr &= ~FMC2_PCR_BCHECC;
219*15f504adSChristophe Kerello if (chip->ecc.strength == FMC2_ECC_BCH8) {
220*15f504adSChristophe Kerello pcr |= FMC2_PCR_ECCALG;
221*15f504adSChristophe Kerello pcr |= FMC2_PCR_BCHECC;
222*15f504adSChristophe Kerello } else if (chip->ecc.strength == FMC2_ECC_BCH4) {
223*15f504adSChristophe Kerello pcr |= FMC2_PCR_ECCALG;
224*15f504adSChristophe Kerello }
225*15f504adSChristophe Kerello
226*15f504adSChristophe Kerello /* Set buswidth */
227*15f504adSChristophe Kerello pcr &= ~FMC2_PCR_PWID_MASK;
228*15f504adSChristophe Kerello if (chip->options & NAND_BUSWIDTH_16)
229*15f504adSChristophe Kerello pcr |= FMC2_PCR_PWID(FMC2_PCR_PWID_BUSWIDTH_16);
230*15f504adSChristophe Kerello
231*15f504adSChristophe Kerello /* Set ECC sector size */
232*15f504adSChristophe Kerello pcr &= ~FMC2_PCR_ECCSS_MASK;
233*15f504adSChristophe Kerello pcr |= FMC2_PCR_ECCSS(FMC2_PCR_ECCSS_512);
234*15f504adSChristophe Kerello
235*15f504adSChristophe Kerello writel(pcr, fmc2->io_base + FMC2_PCR);
236*15f504adSChristophe Kerello }
237*15f504adSChristophe Kerello
238*15f504adSChristophe Kerello /* Select target */
stm32_fmc2_select_chip(struct mtd_info * mtd,int chipnr)239*15f504adSChristophe Kerello static void stm32_fmc2_select_chip(struct mtd_info *mtd, int chipnr)
240*15f504adSChristophe Kerello {
241*15f504adSChristophe Kerello struct nand_chip *chip = mtd_to_nand(mtd);
242*15f504adSChristophe Kerello struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
243*15f504adSChristophe Kerello struct stm32_fmc2_nand *nand = to_fmc2_nand(chip);
244*15f504adSChristophe Kerello
245*15f504adSChristophe Kerello if (chipnr < 0 || chipnr >= nand->ncs)
246*15f504adSChristophe Kerello return;
247*15f504adSChristophe Kerello
248*15f504adSChristophe Kerello if (nand->cs_used[chipnr] == fmc2->cs_sel)
249*15f504adSChristophe Kerello return;
250*15f504adSChristophe Kerello
251*15f504adSChristophe Kerello fmc2->cs_sel = nand->cs_used[chipnr];
252*15f504adSChristophe Kerello chip->IO_ADDR_R = fmc2->data_base[fmc2->cs_sel];
253*15f504adSChristophe Kerello chip->IO_ADDR_W = fmc2->data_base[fmc2->cs_sel];
254*15f504adSChristophe Kerello
255*15f504adSChristophe Kerello /* FMC2 setup routine */
256*15f504adSChristophe Kerello stm32_fmc2_setup(chip);
257*15f504adSChristophe Kerello
258*15f504adSChristophe Kerello /* Apply timings */
259*15f504adSChristophe Kerello stm32_fmc2_timings_init(chip);
260*15f504adSChristophe Kerello }
261*15f504adSChristophe Kerello
262*15f504adSChristophe Kerello /* Set bus width to 16-bit or 8-bit */
stm32_fmc2_set_buswidth_16(struct stm32_fmc2_nfc * fmc2,bool set)263*15f504adSChristophe Kerello static void stm32_fmc2_set_buswidth_16(struct stm32_fmc2_nfc *fmc2, bool set)
264*15f504adSChristophe Kerello {
265*15f504adSChristophe Kerello u32 pcr = readl(fmc2->io_base + FMC2_PCR);
266*15f504adSChristophe Kerello
267*15f504adSChristophe Kerello pcr &= ~FMC2_PCR_PWID_MASK;
268*15f504adSChristophe Kerello if (set)
269*15f504adSChristophe Kerello pcr |= FMC2_PCR_PWID(FMC2_PCR_PWID_BUSWIDTH_16);
270*15f504adSChristophe Kerello writel(pcr, fmc2->io_base + FMC2_PCR);
271*15f504adSChristophe Kerello }
272*15f504adSChristophe Kerello
273*15f504adSChristophe Kerello /* Enable/disable ECC */
stm32_fmc2_set_ecc(struct stm32_fmc2_nfc * fmc2,bool enable)274*15f504adSChristophe Kerello static void stm32_fmc2_set_ecc(struct stm32_fmc2_nfc *fmc2, bool enable)
275*15f504adSChristophe Kerello {
276*15f504adSChristophe Kerello u32 pcr = readl(fmc2->io_base + FMC2_PCR);
277*15f504adSChristophe Kerello
278*15f504adSChristophe Kerello pcr &= ~FMC2_PCR_ECCEN;
279*15f504adSChristophe Kerello if (enable)
280*15f504adSChristophe Kerello pcr |= FMC2_PCR_ECCEN;
281*15f504adSChristophe Kerello writel(pcr, fmc2->io_base + FMC2_PCR);
282*15f504adSChristophe Kerello }
283*15f504adSChristophe Kerello
284*15f504adSChristophe Kerello /* Clear irq sources in case of bch is used */
stm32_fmc2_clear_bch_irq(struct stm32_fmc2_nfc * fmc2)285*15f504adSChristophe Kerello static inline void stm32_fmc2_clear_bch_irq(struct stm32_fmc2_nfc *fmc2)
286*15f504adSChristophe Kerello {
287*15f504adSChristophe Kerello writel(FMC2_BCHICR_CLEAR_IRQ, fmc2->io_base + FMC2_BCHICR);
288*15f504adSChristophe Kerello }
289*15f504adSChristophe Kerello
290*15f504adSChristophe Kerello /* Send command and address cycles */
stm32_fmc2_cmd_ctrl(struct mtd_info * mtd,int cmd,unsigned int ctrl)291*15f504adSChristophe Kerello static void stm32_fmc2_cmd_ctrl(struct mtd_info *mtd, int cmd,
292*15f504adSChristophe Kerello unsigned int ctrl)
293*15f504adSChristophe Kerello {
294*15f504adSChristophe Kerello struct nand_chip *chip = mtd_to_nand(mtd);
295*15f504adSChristophe Kerello struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
296*15f504adSChristophe Kerello
297*15f504adSChristophe Kerello if (cmd == NAND_CMD_NONE)
298*15f504adSChristophe Kerello return;
299*15f504adSChristophe Kerello
300*15f504adSChristophe Kerello if (ctrl & NAND_CLE) {
301*15f504adSChristophe Kerello writeb(cmd, fmc2->cmd_base[fmc2->cs_sel]);
302*15f504adSChristophe Kerello return;
303*15f504adSChristophe Kerello }
304*15f504adSChristophe Kerello
305*15f504adSChristophe Kerello writeb(cmd, fmc2->addr_base[fmc2->cs_sel]);
306*15f504adSChristophe Kerello }
307*15f504adSChristophe Kerello
308*15f504adSChristophe Kerello /*
309*15f504adSChristophe Kerello * Enable ECC logic and reset syndrome/parity bits previously calculated
310*15f504adSChristophe Kerello * Syndrome/parity bits is cleared by setting the ECCEN bit to 0
311*15f504adSChristophe Kerello */
stm32_fmc2_hwctl(struct mtd_info * mtd,int mode)312*15f504adSChristophe Kerello static void stm32_fmc2_hwctl(struct mtd_info *mtd, int mode)
313*15f504adSChristophe Kerello {
314*15f504adSChristophe Kerello struct nand_chip *chip = mtd_to_nand(mtd);
315*15f504adSChristophe Kerello struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
316*15f504adSChristophe Kerello
317*15f504adSChristophe Kerello stm32_fmc2_set_ecc(fmc2, false);
318*15f504adSChristophe Kerello
319*15f504adSChristophe Kerello if (chip->ecc.strength != FMC2_ECC_HAM) {
320*15f504adSChristophe Kerello u32 pcr = readl(fmc2->io_base + FMC2_PCR);
321*15f504adSChristophe Kerello
322*15f504adSChristophe Kerello if (mode == NAND_ECC_WRITE)
323*15f504adSChristophe Kerello pcr |= FMC2_PCR_WEN;
324*15f504adSChristophe Kerello else
325*15f504adSChristophe Kerello pcr &= ~FMC2_PCR_WEN;
326*15f504adSChristophe Kerello writel(pcr, fmc2->io_base + FMC2_PCR);
327*15f504adSChristophe Kerello
328*15f504adSChristophe Kerello stm32_fmc2_clear_bch_irq(fmc2);
329*15f504adSChristophe Kerello }
330*15f504adSChristophe Kerello
331*15f504adSChristophe Kerello stm32_fmc2_set_ecc(fmc2, true);
332*15f504adSChristophe Kerello }
333*15f504adSChristophe Kerello
334*15f504adSChristophe Kerello /*
335*15f504adSChristophe Kerello * ECC Hamming calculation
336*15f504adSChristophe Kerello * ECC is 3 bytes for 512 bytes of data (supports error correction up to
337*15f504adSChristophe Kerello * max of 1-bit)
338*15f504adSChristophe Kerello */
stm32_fmc2_ham_calculate(struct mtd_info * mtd,const u8 * data,u8 * ecc)339*15f504adSChristophe Kerello static int stm32_fmc2_ham_calculate(struct mtd_info *mtd, const u8 *data,
340*15f504adSChristophe Kerello u8 *ecc)
341*15f504adSChristophe Kerello {
342*15f504adSChristophe Kerello struct nand_chip *chip = mtd_to_nand(mtd);
343*15f504adSChristophe Kerello struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
344*15f504adSChristophe Kerello u32 heccr, sr;
345*15f504adSChristophe Kerello int ret;
346*15f504adSChristophe Kerello
347*15f504adSChristophe Kerello ret = readl_poll_timeout(fmc2->io_base + FMC2_SR, sr,
348*15f504adSChristophe Kerello sr & FMC2_SR_NWRF, 10000);
349*15f504adSChristophe Kerello if (ret < 0) {
350*15f504adSChristophe Kerello pr_err("Ham timeout\n");
351*15f504adSChristophe Kerello return ret;
352*15f504adSChristophe Kerello }
353*15f504adSChristophe Kerello
354*15f504adSChristophe Kerello heccr = readl(fmc2->io_base + FMC2_HECCR);
355*15f504adSChristophe Kerello
356*15f504adSChristophe Kerello ecc[0] = heccr;
357*15f504adSChristophe Kerello ecc[1] = heccr >> 8;
358*15f504adSChristophe Kerello ecc[2] = heccr >> 16;
359*15f504adSChristophe Kerello
360*15f504adSChristophe Kerello /* Disable ecc */
361*15f504adSChristophe Kerello stm32_fmc2_set_ecc(fmc2, false);
362*15f504adSChristophe Kerello
363*15f504adSChristophe Kerello return 0;
364*15f504adSChristophe Kerello }
365*15f504adSChristophe Kerello
stm32_fmc2_ham_correct(struct mtd_info * mtd,u8 * dat,u8 * read_ecc,u8 * calc_ecc)366*15f504adSChristophe Kerello static int stm32_fmc2_ham_correct(struct mtd_info *mtd, u8 *dat,
367*15f504adSChristophe Kerello u8 *read_ecc, u8 *calc_ecc)
368*15f504adSChristophe Kerello {
369*15f504adSChristophe Kerello u8 bit_position = 0, b0, b1, b2;
370*15f504adSChristophe Kerello u32 byte_addr = 0, b;
371*15f504adSChristophe Kerello u32 i, shifting = 1;
372*15f504adSChristophe Kerello
373*15f504adSChristophe Kerello /* Indicate which bit and byte is faulty (if any) */
374*15f504adSChristophe Kerello b0 = read_ecc[0] ^ calc_ecc[0];
375*15f504adSChristophe Kerello b1 = read_ecc[1] ^ calc_ecc[1];
376*15f504adSChristophe Kerello b2 = read_ecc[2] ^ calc_ecc[2];
377*15f504adSChristophe Kerello b = b0 | (b1 << 8) | (b2 << 16);
378*15f504adSChristophe Kerello
379*15f504adSChristophe Kerello /* No errors */
380*15f504adSChristophe Kerello if (likely(!b))
381*15f504adSChristophe Kerello return 0;
382*15f504adSChristophe Kerello
383*15f504adSChristophe Kerello /* Calculate bit position */
384*15f504adSChristophe Kerello for (i = 0; i < 3; i++) {
385*15f504adSChristophe Kerello switch (b % 4) {
386*15f504adSChristophe Kerello case 2:
387*15f504adSChristophe Kerello bit_position += shifting;
388*15f504adSChristophe Kerello case 1:
389*15f504adSChristophe Kerello break;
390*15f504adSChristophe Kerello default:
391*15f504adSChristophe Kerello return -EBADMSG;
392*15f504adSChristophe Kerello }
393*15f504adSChristophe Kerello shifting <<= 1;
394*15f504adSChristophe Kerello b >>= 2;
395*15f504adSChristophe Kerello }
396*15f504adSChristophe Kerello
397*15f504adSChristophe Kerello /* Calculate byte position */
398*15f504adSChristophe Kerello shifting = 1;
399*15f504adSChristophe Kerello for (i = 0; i < 9; i++) {
400*15f504adSChristophe Kerello switch (b % 4) {
401*15f504adSChristophe Kerello case 2:
402*15f504adSChristophe Kerello byte_addr += shifting;
403*15f504adSChristophe Kerello case 1:
404*15f504adSChristophe Kerello break;
405*15f504adSChristophe Kerello default:
406*15f504adSChristophe Kerello return -EBADMSG;
407*15f504adSChristophe Kerello }
408*15f504adSChristophe Kerello shifting <<= 1;
409*15f504adSChristophe Kerello b >>= 2;
410*15f504adSChristophe Kerello }
411*15f504adSChristophe Kerello
412*15f504adSChristophe Kerello /* Flip the bit */
413*15f504adSChristophe Kerello dat[byte_addr] ^= (1 << bit_position);
414*15f504adSChristophe Kerello
415*15f504adSChristophe Kerello return 1;
416*15f504adSChristophe Kerello }
417*15f504adSChristophe Kerello
418*15f504adSChristophe Kerello /*
419*15f504adSChristophe Kerello * ECC BCH calculation and correction
420*15f504adSChristophe Kerello * ECC is 7/13 bytes for 512 bytes of data (supports error correction up to
421*15f504adSChristophe Kerello * max of 4-bit/8-bit)
422*15f504adSChristophe Kerello */
423*15f504adSChristophe Kerello
stm32_fmc2_bch_calculate(struct mtd_info * mtd,const u8 * data,u8 * ecc)424*15f504adSChristophe Kerello static int stm32_fmc2_bch_calculate(struct mtd_info *mtd, const u8 *data,
425*15f504adSChristophe Kerello u8 *ecc)
426*15f504adSChristophe Kerello {
427*15f504adSChristophe Kerello struct nand_chip *chip = mtd_to_nand(mtd);
428*15f504adSChristophe Kerello struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
429*15f504adSChristophe Kerello u32 bchpbr, bchisr;
430*15f504adSChristophe Kerello int ret;
431*15f504adSChristophe Kerello
432*15f504adSChristophe Kerello /* Wait until the BCH code is ready */
433*15f504adSChristophe Kerello ret = readl_poll_timeout(fmc2->io_base + FMC2_BCHISR, bchisr,
434*15f504adSChristophe Kerello bchisr & FMC2_BCHISR_EPBRF, 10000);
435*15f504adSChristophe Kerello if (ret < 0) {
436*15f504adSChristophe Kerello pr_err("Bch timeout\n");
437*15f504adSChristophe Kerello return ret;
438*15f504adSChristophe Kerello }
439*15f504adSChristophe Kerello
440*15f504adSChristophe Kerello /* Read parity bits */
441*15f504adSChristophe Kerello bchpbr = readl(fmc2->io_base + FMC2_BCHPBR1);
442*15f504adSChristophe Kerello ecc[0] = bchpbr;
443*15f504adSChristophe Kerello ecc[1] = bchpbr >> 8;
444*15f504adSChristophe Kerello ecc[2] = bchpbr >> 16;
445*15f504adSChristophe Kerello ecc[3] = bchpbr >> 24;
446*15f504adSChristophe Kerello
447*15f504adSChristophe Kerello bchpbr = readl(fmc2->io_base + FMC2_BCHPBR2);
448*15f504adSChristophe Kerello ecc[4] = bchpbr;
449*15f504adSChristophe Kerello ecc[5] = bchpbr >> 8;
450*15f504adSChristophe Kerello ecc[6] = bchpbr >> 16;
451*15f504adSChristophe Kerello
452*15f504adSChristophe Kerello if (chip->ecc.strength == FMC2_ECC_BCH8) {
453*15f504adSChristophe Kerello ecc[7] = bchpbr >> 24;
454*15f504adSChristophe Kerello
455*15f504adSChristophe Kerello bchpbr = readl(fmc2->io_base + FMC2_BCHPBR3);
456*15f504adSChristophe Kerello ecc[8] = bchpbr;
457*15f504adSChristophe Kerello ecc[9] = bchpbr >> 8;
458*15f504adSChristophe Kerello ecc[10] = bchpbr >> 16;
459*15f504adSChristophe Kerello ecc[11] = bchpbr >> 24;
460*15f504adSChristophe Kerello
461*15f504adSChristophe Kerello bchpbr = readl(fmc2->io_base + FMC2_BCHPBR4);
462*15f504adSChristophe Kerello ecc[12] = bchpbr;
463*15f504adSChristophe Kerello }
464*15f504adSChristophe Kerello
465*15f504adSChristophe Kerello /* Disable ecc */
466*15f504adSChristophe Kerello stm32_fmc2_set_ecc(fmc2, false);
467*15f504adSChristophe Kerello
468*15f504adSChristophe Kerello return 0;
469*15f504adSChristophe Kerello }
470*15f504adSChristophe Kerello
471*15f504adSChristophe Kerello /* BCH algorithm correction */
stm32_fmc2_bch_correct(struct mtd_info * mtd,u8 * dat,u8 * read_ecc,u8 * calc_ecc)472*15f504adSChristophe Kerello static int stm32_fmc2_bch_correct(struct mtd_info *mtd, u8 *dat,
473*15f504adSChristophe Kerello u8 *read_ecc, u8 *calc_ecc)
474*15f504adSChristophe Kerello {
475*15f504adSChristophe Kerello struct nand_chip *chip = mtd_to_nand(mtd);
476*15f504adSChristophe Kerello struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
477*15f504adSChristophe Kerello u32 bchdsr0, bchdsr1, bchdsr2, bchdsr3, bchdsr4, bchisr;
478*15f504adSChristophe Kerello u16 pos[8];
479*15f504adSChristophe Kerello int i, ret, den, eccsize = chip->ecc.size;
480*15f504adSChristophe Kerello unsigned int nb_errs = 0;
481*15f504adSChristophe Kerello
482*15f504adSChristophe Kerello /* Wait until the decoding error is ready */
483*15f504adSChristophe Kerello ret = readl_poll_timeout(fmc2->io_base + FMC2_BCHISR, bchisr,
484*15f504adSChristophe Kerello bchisr & FMC2_BCHISR_DERF, 10000);
485*15f504adSChristophe Kerello if (ret < 0) {
486*15f504adSChristophe Kerello pr_err("Bch timeout\n");
487*15f504adSChristophe Kerello return ret;
488*15f504adSChristophe Kerello }
489*15f504adSChristophe Kerello
490*15f504adSChristophe Kerello bchdsr0 = readl(fmc2->io_base + FMC2_BCHDSR0);
491*15f504adSChristophe Kerello bchdsr1 = readl(fmc2->io_base + FMC2_BCHDSR1);
492*15f504adSChristophe Kerello bchdsr2 = readl(fmc2->io_base + FMC2_BCHDSR2);
493*15f504adSChristophe Kerello bchdsr3 = readl(fmc2->io_base + FMC2_BCHDSR3);
494*15f504adSChristophe Kerello bchdsr4 = readl(fmc2->io_base + FMC2_BCHDSR4);
495*15f504adSChristophe Kerello
496*15f504adSChristophe Kerello /* Disable ECC */
497*15f504adSChristophe Kerello stm32_fmc2_set_ecc(fmc2, false);
498*15f504adSChristophe Kerello
499*15f504adSChristophe Kerello /* No errors found */
500*15f504adSChristophe Kerello if (likely(!(bchdsr0 & FMC2_BCHDSR0_DEF)))
501*15f504adSChristophe Kerello return 0;
502*15f504adSChristophe Kerello
503*15f504adSChristophe Kerello /* Too many errors detected */
504*15f504adSChristophe Kerello if (unlikely(bchdsr0 & FMC2_BCHDSR0_DUE))
505*15f504adSChristophe Kerello return -EBADMSG;
506*15f504adSChristophe Kerello
507*15f504adSChristophe Kerello pos[0] = bchdsr1 & FMC2_BCHDSR1_EBP1_MASK;
508*15f504adSChristophe Kerello pos[1] = (bchdsr1 & FMC2_BCHDSR1_EBP2_MASK) >> FMC2_BCHDSR1_EBP2_SHIFT;
509*15f504adSChristophe Kerello pos[2] = bchdsr2 & FMC2_BCHDSR2_EBP3_MASK;
510*15f504adSChristophe Kerello pos[3] = (bchdsr2 & FMC2_BCHDSR2_EBP4_MASK) >> FMC2_BCHDSR2_EBP4_SHIFT;
511*15f504adSChristophe Kerello pos[4] = bchdsr3 & FMC2_BCHDSR3_EBP5_MASK;
512*15f504adSChristophe Kerello pos[5] = (bchdsr3 & FMC2_BCHDSR3_EBP6_MASK) >> FMC2_BCHDSR3_EBP6_SHIFT;
513*15f504adSChristophe Kerello pos[6] = bchdsr4 & FMC2_BCHDSR4_EBP7_MASK;
514*15f504adSChristophe Kerello pos[7] = (bchdsr4 & FMC2_BCHDSR4_EBP8_MASK) >> FMC2_BCHDSR4_EBP8_SHIFT;
515*15f504adSChristophe Kerello
516*15f504adSChristophe Kerello den = (bchdsr0 & FMC2_BCHDSR0_DEN_MASK) >> FMC2_BCHDSR0_DEN_SHIFT;
517*15f504adSChristophe Kerello for (i = 0; i < den; i++) {
518*15f504adSChristophe Kerello if (pos[i] < eccsize * 8) {
519*15f504adSChristophe Kerello __change_bit(pos[i], (unsigned long *)dat);
520*15f504adSChristophe Kerello nb_errs++;
521*15f504adSChristophe Kerello }
522*15f504adSChristophe Kerello }
523*15f504adSChristophe Kerello
524*15f504adSChristophe Kerello return nb_errs;
525*15f504adSChristophe Kerello }
526*15f504adSChristophe Kerello
stm32_fmc2_read_page(struct mtd_info * mtd,struct nand_chip * chip,u8 * buf,int oob_required,int page)527*15f504adSChristophe Kerello static int stm32_fmc2_read_page(struct mtd_info *mtd,
528*15f504adSChristophe Kerello struct nand_chip *chip, u8 *buf,
529*15f504adSChristophe Kerello int oob_required, int page)
530*15f504adSChristophe Kerello {
531*15f504adSChristophe Kerello int i, s, stat, eccsize = chip->ecc.size;
532*15f504adSChristophe Kerello int eccbytes = chip->ecc.bytes;
533*15f504adSChristophe Kerello int eccsteps = chip->ecc.steps;
534*15f504adSChristophe Kerello int eccstrength = chip->ecc.strength;
535*15f504adSChristophe Kerello u8 *p = buf;
536*15f504adSChristophe Kerello u8 *ecc_calc = chip->buffers->ecccalc;
537*15f504adSChristophe Kerello u8 *ecc_code = chip->buffers->ecccode;
538*15f504adSChristophe Kerello unsigned int max_bitflips = 0;
539*15f504adSChristophe Kerello
540*15f504adSChristophe Kerello for (i = mtd->writesize + FMC2_BBM_LEN, s = 0; s < eccsteps;
541*15f504adSChristophe Kerello s++, i += eccbytes, p += eccsize) {
542*15f504adSChristophe Kerello chip->ecc.hwctl(mtd, NAND_ECC_READ);
543*15f504adSChristophe Kerello
544*15f504adSChristophe Kerello /* Read the nand page sector (512 bytes) */
545*15f504adSChristophe Kerello chip->cmdfunc(mtd, NAND_CMD_RNDOUT, s * eccsize, -1);
546*15f504adSChristophe Kerello chip->read_buf(mtd, p, eccsize);
547*15f504adSChristophe Kerello
548*15f504adSChristophe Kerello /* Read the corresponding ECC bytes */
549*15f504adSChristophe Kerello chip->cmdfunc(mtd, NAND_CMD_RNDOUT, i, -1);
550*15f504adSChristophe Kerello chip->read_buf(mtd, ecc_code, eccbytes);
551*15f504adSChristophe Kerello
552*15f504adSChristophe Kerello /* Correct the data */
553*15f504adSChristophe Kerello stat = chip->ecc.correct(mtd, p, ecc_code, ecc_calc);
554*15f504adSChristophe Kerello if (stat == -EBADMSG)
555*15f504adSChristophe Kerello /* Check for empty pages with bitflips */
556*15f504adSChristophe Kerello stat = nand_check_erased_ecc_chunk(p, eccsize,
557*15f504adSChristophe Kerello ecc_code, eccbytes,
558*15f504adSChristophe Kerello NULL, 0,
559*15f504adSChristophe Kerello eccstrength);
560*15f504adSChristophe Kerello
561*15f504adSChristophe Kerello if (stat < 0) {
562*15f504adSChristophe Kerello mtd->ecc_stats.failed++;
563*15f504adSChristophe Kerello } else {
564*15f504adSChristophe Kerello mtd->ecc_stats.corrected += stat;
565*15f504adSChristophe Kerello max_bitflips = max_t(unsigned int, max_bitflips, stat);
566*15f504adSChristophe Kerello }
567*15f504adSChristophe Kerello }
568*15f504adSChristophe Kerello
569*15f504adSChristophe Kerello /* Read oob */
570*15f504adSChristophe Kerello if (oob_required) {
571*15f504adSChristophe Kerello chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1);
572*15f504adSChristophe Kerello chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
573*15f504adSChristophe Kerello }
574*15f504adSChristophe Kerello
575*15f504adSChristophe Kerello return max_bitflips;
576*15f504adSChristophe Kerello }
577*15f504adSChristophe Kerello
578*15f504adSChristophe Kerello /* Controller initialization */
stm32_fmc2_init(struct stm32_fmc2_nfc * fmc2)579*15f504adSChristophe Kerello static void stm32_fmc2_init(struct stm32_fmc2_nfc *fmc2)
580*15f504adSChristophe Kerello {
581*15f504adSChristophe Kerello u32 pcr = readl(fmc2->io_base + FMC2_PCR);
582*15f504adSChristophe Kerello u32 bcr1 = readl(fmc2->io_base + FMC2_BCR1);
583*15f504adSChristophe Kerello
584*15f504adSChristophe Kerello /* Set CS used to undefined */
585*15f504adSChristophe Kerello fmc2->cs_sel = -1;
586*15f504adSChristophe Kerello
587*15f504adSChristophe Kerello /* Enable wait feature and nand flash memory bank */
588*15f504adSChristophe Kerello pcr |= FMC2_PCR_PWAITEN;
589*15f504adSChristophe Kerello pcr |= FMC2_PCR_PBKEN;
590*15f504adSChristophe Kerello
591*15f504adSChristophe Kerello /* Set buswidth to 8 bits mode for identification */
592*15f504adSChristophe Kerello pcr &= ~FMC2_PCR_PWID_MASK;
593*15f504adSChristophe Kerello
594*15f504adSChristophe Kerello /* ECC logic is disabled */
595*15f504adSChristophe Kerello pcr &= ~FMC2_PCR_ECCEN;
596*15f504adSChristophe Kerello
597*15f504adSChristophe Kerello /* Default mode */
598*15f504adSChristophe Kerello pcr &= ~FMC2_PCR_ECCALG;
599*15f504adSChristophe Kerello pcr &= ~FMC2_PCR_BCHECC;
600*15f504adSChristophe Kerello pcr &= ~FMC2_PCR_WEN;
601*15f504adSChristophe Kerello
602*15f504adSChristophe Kerello /* Set default ECC sector size */
603*15f504adSChristophe Kerello pcr &= ~FMC2_PCR_ECCSS_MASK;
604*15f504adSChristophe Kerello pcr |= FMC2_PCR_ECCSS(FMC2_PCR_ECCSS_2048);
605*15f504adSChristophe Kerello
606*15f504adSChristophe Kerello /* Set default tclr/tar timings */
607*15f504adSChristophe Kerello pcr &= ~FMC2_PCR_TCLR_MASK;
608*15f504adSChristophe Kerello pcr |= FMC2_PCR_TCLR(FMC2_PCR_TCLR_DEFAULT);
609*15f504adSChristophe Kerello pcr &= ~FMC2_PCR_TAR_MASK;
610*15f504adSChristophe Kerello pcr |= FMC2_PCR_TAR(FMC2_PCR_TAR_DEFAULT);
611*15f504adSChristophe Kerello
612*15f504adSChristophe Kerello /* Enable FMC2 controller */
613*15f504adSChristophe Kerello bcr1 |= FMC2_BCR1_FMC2EN;
614*15f504adSChristophe Kerello
615*15f504adSChristophe Kerello writel(bcr1, fmc2->io_base + FMC2_BCR1);
616*15f504adSChristophe Kerello writel(pcr, fmc2->io_base + FMC2_PCR);
617*15f504adSChristophe Kerello writel(FMC2_PMEM_DEFAULT, fmc2->io_base + FMC2_PMEM);
618*15f504adSChristophe Kerello writel(FMC2_PATT_DEFAULT, fmc2->io_base + FMC2_PATT);
619*15f504adSChristophe Kerello }
620*15f504adSChristophe Kerello
621*15f504adSChristophe Kerello /* Controller timings */
stm32_fmc2_calc_timings(struct nand_chip * chip,const struct nand_sdr_timings * sdrt)622*15f504adSChristophe Kerello static void stm32_fmc2_calc_timings(struct nand_chip *chip,
623*15f504adSChristophe Kerello const struct nand_sdr_timings *sdrt)
624*15f504adSChristophe Kerello {
625*15f504adSChristophe Kerello struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
626*15f504adSChristophe Kerello struct stm32_fmc2_nand *nand = to_fmc2_nand(chip);
627*15f504adSChristophe Kerello struct stm32_fmc2_timings *tims = &nand->timings;
628*15f504adSChristophe Kerello unsigned long hclk = clk_get_rate(&fmc2->clk);
629*15f504adSChristophe Kerello unsigned long hclkp = FMC2_NSEC_PER_SEC / (hclk / 1000);
630*15f504adSChristophe Kerello int tar, tclr, thiz, twait, tset_mem, tset_att, thold_mem, thold_att;
631*15f504adSChristophe Kerello
632*15f504adSChristophe Kerello tar = hclkp;
633*15f504adSChristophe Kerello if (tar < sdrt->tAR_min)
634*15f504adSChristophe Kerello tar = sdrt->tAR_min;
635*15f504adSChristophe Kerello tims->tar = DIV_ROUND_UP(tar, hclkp) - 1;
636*15f504adSChristophe Kerello if (tims->tar > FMC2_PCR_TIMING_MASK)
637*15f504adSChristophe Kerello tims->tar = FMC2_PCR_TIMING_MASK;
638*15f504adSChristophe Kerello
639*15f504adSChristophe Kerello tclr = hclkp;
640*15f504adSChristophe Kerello if (tclr < sdrt->tCLR_min)
641*15f504adSChristophe Kerello tclr = sdrt->tCLR_min;
642*15f504adSChristophe Kerello tims->tclr = DIV_ROUND_UP(tclr, hclkp) - 1;
643*15f504adSChristophe Kerello if (tims->tclr > FMC2_PCR_TIMING_MASK)
644*15f504adSChristophe Kerello tims->tclr = FMC2_PCR_TIMING_MASK;
645*15f504adSChristophe Kerello
646*15f504adSChristophe Kerello tims->thiz = FMC2_THIZ;
647*15f504adSChristophe Kerello thiz = (tims->thiz + 1) * hclkp;
648*15f504adSChristophe Kerello
649*15f504adSChristophe Kerello /*
650*15f504adSChristophe Kerello * tWAIT > tRP
651*15f504adSChristophe Kerello * tWAIT > tWP
652*15f504adSChristophe Kerello * tWAIT > tREA + tIO
653*15f504adSChristophe Kerello */
654*15f504adSChristophe Kerello twait = hclkp;
655*15f504adSChristophe Kerello if (twait < sdrt->tRP_min)
656*15f504adSChristophe Kerello twait = sdrt->tRP_min;
657*15f504adSChristophe Kerello if (twait < sdrt->tWP_min)
658*15f504adSChristophe Kerello twait = sdrt->tWP_min;
659*15f504adSChristophe Kerello if (twait < sdrt->tREA_max + FMC2_TIO)
660*15f504adSChristophe Kerello twait = sdrt->tREA_max + FMC2_TIO;
661*15f504adSChristophe Kerello tims->twait = DIV_ROUND_UP(twait, hclkp);
662*15f504adSChristophe Kerello if (tims->twait == 0)
663*15f504adSChristophe Kerello tims->twait = 1;
664*15f504adSChristophe Kerello else if (tims->twait > FMC2_PMEM_PATT_TIMING_MASK)
665*15f504adSChristophe Kerello tims->twait = FMC2_PMEM_PATT_TIMING_MASK;
666*15f504adSChristophe Kerello
667*15f504adSChristophe Kerello /*
668*15f504adSChristophe Kerello * tSETUP_MEM > tCS - tWAIT
669*15f504adSChristophe Kerello * tSETUP_MEM > tALS - tWAIT
670*15f504adSChristophe Kerello * tSETUP_MEM > tDS - (tWAIT - tHIZ)
671*15f504adSChristophe Kerello */
672*15f504adSChristophe Kerello tset_mem = hclkp;
673*15f504adSChristophe Kerello if (sdrt->tCS_min > twait && (tset_mem < sdrt->tCS_min - twait))
674*15f504adSChristophe Kerello tset_mem = sdrt->tCS_min - twait;
675*15f504adSChristophe Kerello if (sdrt->tALS_min > twait && (tset_mem < sdrt->tALS_min - twait))
676*15f504adSChristophe Kerello tset_mem = sdrt->tALS_min - twait;
677*15f504adSChristophe Kerello if (twait > thiz && (sdrt->tDS_min > twait - thiz) &&
678*15f504adSChristophe Kerello (tset_mem < sdrt->tDS_min - (twait - thiz)))
679*15f504adSChristophe Kerello tset_mem = sdrt->tDS_min - (twait - thiz);
680*15f504adSChristophe Kerello tims->tset_mem = DIV_ROUND_UP(tset_mem, hclkp);
681*15f504adSChristophe Kerello if (tims->tset_mem == 0)
682*15f504adSChristophe Kerello tims->tset_mem = 1;
683*15f504adSChristophe Kerello else if (tims->tset_mem > FMC2_PMEM_PATT_TIMING_MASK)
684*15f504adSChristophe Kerello tims->tset_mem = FMC2_PMEM_PATT_TIMING_MASK;
685*15f504adSChristophe Kerello
686*15f504adSChristophe Kerello /*
687*15f504adSChristophe Kerello * tHOLD_MEM > tCH
688*15f504adSChristophe Kerello * tHOLD_MEM > tREH - tSETUP_MEM
689*15f504adSChristophe Kerello * tHOLD_MEM > max(tRC, tWC) - (tSETUP_MEM + tWAIT)
690*15f504adSChristophe Kerello */
691*15f504adSChristophe Kerello thold_mem = hclkp;
692*15f504adSChristophe Kerello if (thold_mem < sdrt->tCH_min)
693*15f504adSChristophe Kerello thold_mem = sdrt->tCH_min;
694*15f504adSChristophe Kerello if (sdrt->tREH_min > tset_mem &&
695*15f504adSChristophe Kerello (thold_mem < sdrt->tREH_min - tset_mem))
696*15f504adSChristophe Kerello thold_mem = sdrt->tREH_min - tset_mem;
697*15f504adSChristophe Kerello if ((sdrt->tRC_min > tset_mem + twait) &&
698*15f504adSChristophe Kerello (thold_mem < sdrt->tRC_min - (tset_mem + twait)))
699*15f504adSChristophe Kerello thold_mem = sdrt->tRC_min - (tset_mem + twait);
700*15f504adSChristophe Kerello if ((sdrt->tWC_min > tset_mem + twait) &&
701*15f504adSChristophe Kerello (thold_mem < sdrt->tWC_min - (tset_mem + twait)))
702*15f504adSChristophe Kerello thold_mem = sdrt->tWC_min - (tset_mem + twait);
703*15f504adSChristophe Kerello tims->thold_mem = DIV_ROUND_UP(thold_mem, hclkp);
704*15f504adSChristophe Kerello if (tims->thold_mem == 0)
705*15f504adSChristophe Kerello tims->thold_mem = 1;
706*15f504adSChristophe Kerello else if (tims->thold_mem > FMC2_PMEM_PATT_TIMING_MASK)
707*15f504adSChristophe Kerello tims->thold_mem = FMC2_PMEM_PATT_TIMING_MASK;
708*15f504adSChristophe Kerello
709*15f504adSChristophe Kerello /*
710*15f504adSChristophe Kerello * tSETUP_ATT > tCS - tWAIT
711*15f504adSChristophe Kerello * tSETUP_ATT > tCLS - tWAIT
712*15f504adSChristophe Kerello * tSETUP_ATT > tALS - tWAIT
713*15f504adSChristophe Kerello * tSETUP_ATT > tRHW - tHOLD_MEM
714*15f504adSChristophe Kerello * tSETUP_ATT > tDS - (tWAIT - tHIZ)
715*15f504adSChristophe Kerello */
716*15f504adSChristophe Kerello tset_att = hclkp;
717*15f504adSChristophe Kerello if (sdrt->tCS_min > twait && (tset_att < sdrt->tCS_min - twait))
718*15f504adSChristophe Kerello tset_att = sdrt->tCS_min - twait;
719*15f504adSChristophe Kerello if (sdrt->tCLS_min > twait && (tset_att < sdrt->tCLS_min - twait))
720*15f504adSChristophe Kerello tset_att = sdrt->tCLS_min - twait;
721*15f504adSChristophe Kerello if (sdrt->tALS_min > twait && (tset_att < sdrt->tALS_min - twait))
722*15f504adSChristophe Kerello tset_att = sdrt->tALS_min - twait;
723*15f504adSChristophe Kerello if (sdrt->tRHW_min > thold_mem &&
724*15f504adSChristophe Kerello (tset_att < sdrt->tRHW_min - thold_mem))
725*15f504adSChristophe Kerello tset_att = sdrt->tRHW_min - thold_mem;
726*15f504adSChristophe Kerello if (twait > thiz && (sdrt->tDS_min > twait - thiz) &&
727*15f504adSChristophe Kerello (tset_att < sdrt->tDS_min - (twait - thiz)))
728*15f504adSChristophe Kerello tset_att = sdrt->tDS_min - (twait - thiz);
729*15f504adSChristophe Kerello tims->tset_att = DIV_ROUND_UP(tset_att, hclkp);
730*15f504adSChristophe Kerello if (tims->tset_att == 0)
731*15f504adSChristophe Kerello tims->tset_att = 1;
732*15f504adSChristophe Kerello else if (tims->tset_att > FMC2_PMEM_PATT_TIMING_MASK)
733*15f504adSChristophe Kerello tims->tset_att = FMC2_PMEM_PATT_TIMING_MASK;
734*15f504adSChristophe Kerello
735*15f504adSChristophe Kerello /*
736*15f504adSChristophe Kerello * tHOLD_ATT > tALH
737*15f504adSChristophe Kerello * tHOLD_ATT > tCH
738*15f504adSChristophe Kerello * tHOLD_ATT > tCLH
739*15f504adSChristophe Kerello * tHOLD_ATT > tCOH
740*15f504adSChristophe Kerello * tHOLD_ATT > tDH
741*15f504adSChristophe Kerello * tHOLD_ATT > tWB + tIO + tSYNC - tSETUP_MEM
742*15f504adSChristophe Kerello * tHOLD_ATT > tADL - tSETUP_MEM
743*15f504adSChristophe Kerello * tHOLD_ATT > tWH - tSETUP_MEM
744*15f504adSChristophe Kerello * tHOLD_ATT > tWHR - tSETUP_MEM
745*15f504adSChristophe Kerello * tHOLD_ATT > tRC - (tSETUP_ATT + tWAIT)
746*15f504adSChristophe Kerello * tHOLD_ATT > tWC - (tSETUP_ATT + tWAIT)
747*15f504adSChristophe Kerello */
748*15f504adSChristophe Kerello thold_att = hclkp;
749*15f504adSChristophe Kerello if (thold_att < sdrt->tALH_min)
750*15f504adSChristophe Kerello thold_att = sdrt->tALH_min;
751*15f504adSChristophe Kerello if (thold_att < sdrt->tCH_min)
752*15f504adSChristophe Kerello thold_att = sdrt->tCH_min;
753*15f504adSChristophe Kerello if (thold_att < sdrt->tCLH_min)
754*15f504adSChristophe Kerello thold_att = sdrt->tCLH_min;
755*15f504adSChristophe Kerello if (thold_att < sdrt->tCOH_min)
756*15f504adSChristophe Kerello thold_att = sdrt->tCOH_min;
757*15f504adSChristophe Kerello if (thold_att < sdrt->tDH_min)
758*15f504adSChristophe Kerello thold_att = sdrt->tDH_min;
759*15f504adSChristophe Kerello if ((sdrt->tWB_max + FMC2_TIO + FMC2_TSYNC > tset_mem) &&
760*15f504adSChristophe Kerello (thold_att < sdrt->tWB_max + FMC2_TIO + FMC2_TSYNC - tset_mem))
761*15f504adSChristophe Kerello thold_att = sdrt->tWB_max + FMC2_TIO + FMC2_TSYNC - tset_mem;
762*15f504adSChristophe Kerello if (sdrt->tADL_min > tset_mem &&
763*15f504adSChristophe Kerello (thold_att < sdrt->tADL_min - tset_mem))
764*15f504adSChristophe Kerello thold_att = sdrt->tADL_min - tset_mem;
765*15f504adSChristophe Kerello if (sdrt->tWH_min > tset_mem &&
766*15f504adSChristophe Kerello (thold_att < sdrt->tWH_min - tset_mem))
767*15f504adSChristophe Kerello thold_att = sdrt->tWH_min - tset_mem;
768*15f504adSChristophe Kerello if (sdrt->tWHR_min > tset_mem &&
769*15f504adSChristophe Kerello (thold_att < sdrt->tWHR_min - tset_mem))
770*15f504adSChristophe Kerello thold_att = sdrt->tWHR_min - tset_mem;
771*15f504adSChristophe Kerello if ((sdrt->tRC_min > tset_att + twait) &&
772*15f504adSChristophe Kerello (thold_att < sdrt->tRC_min - (tset_att + twait)))
773*15f504adSChristophe Kerello thold_att = sdrt->tRC_min - (tset_att + twait);
774*15f504adSChristophe Kerello if ((sdrt->tWC_min > tset_att + twait) &&
775*15f504adSChristophe Kerello (thold_att < sdrt->tWC_min - (tset_att + twait)))
776*15f504adSChristophe Kerello thold_att = sdrt->tWC_min - (tset_att + twait);
777*15f504adSChristophe Kerello tims->thold_att = DIV_ROUND_UP(thold_att, hclkp);
778*15f504adSChristophe Kerello if (tims->thold_att == 0)
779*15f504adSChristophe Kerello tims->thold_att = 1;
780*15f504adSChristophe Kerello else if (tims->thold_att > FMC2_PMEM_PATT_TIMING_MASK)
781*15f504adSChristophe Kerello tims->thold_att = FMC2_PMEM_PATT_TIMING_MASK;
782*15f504adSChristophe Kerello }
783*15f504adSChristophe Kerello
stm32_fmc2_setup_interface(struct mtd_info * mtd,int chipnr,const struct nand_data_interface * conf)784*15f504adSChristophe Kerello static int stm32_fmc2_setup_interface(struct mtd_info *mtd, int chipnr,
785*15f504adSChristophe Kerello const struct nand_data_interface *conf)
786*15f504adSChristophe Kerello {
787*15f504adSChristophe Kerello struct nand_chip *chip = mtd_to_nand(mtd);
788*15f504adSChristophe Kerello const struct nand_sdr_timings *sdrt;
789*15f504adSChristophe Kerello
790*15f504adSChristophe Kerello sdrt = nand_get_sdr_timings(conf);
791*15f504adSChristophe Kerello if (IS_ERR(sdrt))
792*15f504adSChristophe Kerello return PTR_ERR(sdrt);
793*15f504adSChristophe Kerello
794*15f504adSChristophe Kerello if (chipnr == NAND_DATA_IFACE_CHECK_ONLY)
795*15f504adSChristophe Kerello return 0;
796*15f504adSChristophe Kerello
797*15f504adSChristophe Kerello stm32_fmc2_calc_timings(chip, sdrt);
798*15f504adSChristophe Kerello
799*15f504adSChristophe Kerello /* Apply timings */
800*15f504adSChristophe Kerello stm32_fmc2_timings_init(chip);
801*15f504adSChristophe Kerello
802*15f504adSChristophe Kerello return 0;
803*15f504adSChristophe Kerello }
804*15f504adSChristophe Kerello
805*15f504adSChristophe Kerello /* NAND callbacks setup */
stm32_fmc2_nand_callbacks_setup(struct nand_chip * chip)806*15f504adSChristophe Kerello static void stm32_fmc2_nand_callbacks_setup(struct nand_chip *chip)
807*15f504adSChristophe Kerello {
808*15f504adSChristophe Kerello chip->ecc.hwctl = stm32_fmc2_hwctl;
809*15f504adSChristophe Kerello
810*15f504adSChristophe Kerello /*
811*15f504adSChristophe Kerello * Specific callbacks to read/write a page depending on
812*15f504adSChristophe Kerello * the algo used (Hamming, BCH).
813*15f504adSChristophe Kerello */
814*15f504adSChristophe Kerello if (chip->ecc.strength == FMC2_ECC_HAM) {
815*15f504adSChristophe Kerello /* Hamming is used */
816*15f504adSChristophe Kerello chip->ecc.calculate = stm32_fmc2_ham_calculate;
817*15f504adSChristophe Kerello chip->ecc.correct = stm32_fmc2_ham_correct;
818*15f504adSChristophe Kerello chip->ecc.bytes = chip->options & NAND_BUSWIDTH_16 ? 4 : 3;
819*15f504adSChristophe Kerello chip->ecc.options |= NAND_ECC_GENERIC_ERASED_CHECK;
820*15f504adSChristophe Kerello return;
821*15f504adSChristophe Kerello }
822*15f504adSChristophe Kerello
823*15f504adSChristophe Kerello /* BCH is used */
824*15f504adSChristophe Kerello chip->ecc.read_page = stm32_fmc2_read_page;
825*15f504adSChristophe Kerello chip->ecc.calculate = stm32_fmc2_bch_calculate;
826*15f504adSChristophe Kerello chip->ecc.correct = stm32_fmc2_bch_correct;
827*15f504adSChristophe Kerello
828*15f504adSChristophe Kerello if (chip->ecc.strength == FMC2_ECC_BCH8)
829*15f504adSChristophe Kerello chip->ecc.bytes = chip->options & NAND_BUSWIDTH_16 ? 14 : 13;
830*15f504adSChristophe Kerello else
831*15f504adSChristophe Kerello chip->ecc.bytes = chip->options & NAND_BUSWIDTH_16 ? 8 : 7;
832*15f504adSChristophe Kerello }
833*15f504adSChristophe Kerello
834*15f504adSChristophe Kerello /* FMC2 caps */
stm32_fmc2_calc_ecc_bytes(int step_size,int strength)835*15f504adSChristophe Kerello static int stm32_fmc2_calc_ecc_bytes(int step_size, int strength)
836*15f504adSChristophe Kerello {
837*15f504adSChristophe Kerello /* Hamming */
838*15f504adSChristophe Kerello if (strength == FMC2_ECC_HAM)
839*15f504adSChristophe Kerello return 4;
840*15f504adSChristophe Kerello
841*15f504adSChristophe Kerello /* BCH8 */
842*15f504adSChristophe Kerello if (strength == FMC2_ECC_BCH8)
843*15f504adSChristophe Kerello return 14;
844*15f504adSChristophe Kerello
845*15f504adSChristophe Kerello /* BCH4 */
846*15f504adSChristophe Kerello return 8;
847*15f504adSChristophe Kerello }
848*15f504adSChristophe Kerello
849*15f504adSChristophe Kerello NAND_ECC_CAPS_SINGLE(stm32_fmc2_ecc_caps, stm32_fmc2_calc_ecc_bytes,
850*15f504adSChristophe Kerello FMC2_ECC_STEP_SIZE,
851*15f504adSChristophe Kerello FMC2_ECC_HAM, FMC2_ECC_BCH4, FMC2_ECC_BCH8);
852*15f504adSChristophe Kerello
853*15f504adSChristophe Kerello /* FMC2 probe */
stm32_fmc2_parse_child(struct stm32_fmc2_nfc * fmc2,ofnode node)854*15f504adSChristophe Kerello static int stm32_fmc2_parse_child(struct stm32_fmc2_nfc *fmc2,
855*15f504adSChristophe Kerello ofnode node)
856*15f504adSChristophe Kerello {
857*15f504adSChristophe Kerello struct stm32_fmc2_nand *nand = &fmc2->nand;
858*15f504adSChristophe Kerello u32 cs[FMC2_MAX_CE];
859*15f504adSChristophe Kerello int ret, i;
860*15f504adSChristophe Kerello
861*15f504adSChristophe Kerello if (!ofnode_get_property(node, "reg", &nand->ncs))
862*15f504adSChristophe Kerello return -EINVAL;
863*15f504adSChristophe Kerello
864*15f504adSChristophe Kerello nand->ncs /= sizeof(u32);
865*15f504adSChristophe Kerello if (!nand->ncs) {
866*15f504adSChristophe Kerello pr_err("Invalid reg property size\n");
867*15f504adSChristophe Kerello return -EINVAL;
868*15f504adSChristophe Kerello }
869*15f504adSChristophe Kerello
870*15f504adSChristophe Kerello ret = ofnode_read_u32_array(node, "reg", cs, nand->ncs);
871*15f504adSChristophe Kerello if (ret < 0) {
872*15f504adSChristophe Kerello pr_err("Could not retrieve reg property\n");
873*15f504adSChristophe Kerello return -EINVAL;
874*15f504adSChristophe Kerello }
875*15f504adSChristophe Kerello
876*15f504adSChristophe Kerello for (i = 0; i < nand->ncs; i++) {
877*15f504adSChristophe Kerello if (cs[i] > FMC2_MAX_CE) {
878*15f504adSChristophe Kerello pr_err("Invalid reg value: %d\n",
879*15f504adSChristophe Kerello nand->cs_used[i]);
880*15f504adSChristophe Kerello return -EINVAL;
881*15f504adSChristophe Kerello }
882*15f504adSChristophe Kerello
883*15f504adSChristophe Kerello if (fmc2->cs_assigned & BIT(cs[i])) {
884*15f504adSChristophe Kerello pr_err("Cs already assigned: %d\n",
885*15f504adSChristophe Kerello nand->cs_used[i]);
886*15f504adSChristophe Kerello return -EINVAL;
887*15f504adSChristophe Kerello }
888*15f504adSChristophe Kerello
889*15f504adSChristophe Kerello fmc2->cs_assigned |= BIT(cs[i]);
890*15f504adSChristophe Kerello nand->cs_used[i] = cs[i];
891*15f504adSChristophe Kerello }
892*15f504adSChristophe Kerello
893*15f504adSChristophe Kerello nand->chip.flash_node = ofnode_to_offset(node);
894*15f504adSChristophe Kerello
895*15f504adSChristophe Kerello return 0;
896*15f504adSChristophe Kerello }
897*15f504adSChristophe Kerello
stm32_fmc2_parse_dt(struct udevice * dev,struct stm32_fmc2_nfc * fmc2)898*15f504adSChristophe Kerello static int stm32_fmc2_parse_dt(struct udevice *dev,
899*15f504adSChristophe Kerello struct stm32_fmc2_nfc *fmc2)
900*15f504adSChristophe Kerello {
901*15f504adSChristophe Kerello ofnode child;
902*15f504adSChristophe Kerello int ret, nchips = 0;
903*15f504adSChristophe Kerello
904*15f504adSChristophe Kerello dev_for_each_subnode(child, dev)
905*15f504adSChristophe Kerello nchips++;
906*15f504adSChristophe Kerello
907*15f504adSChristophe Kerello if (!nchips) {
908*15f504adSChristophe Kerello pr_err("NAND chip not defined\n");
909*15f504adSChristophe Kerello return -EINVAL;
910*15f504adSChristophe Kerello }
911*15f504adSChristophe Kerello
912*15f504adSChristophe Kerello if (nchips > 1) {
913*15f504adSChristophe Kerello pr_err("Too many NAND chips defined\n");
914*15f504adSChristophe Kerello return -EINVAL;
915*15f504adSChristophe Kerello }
916*15f504adSChristophe Kerello
917*15f504adSChristophe Kerello dev_for_each_subnode(child, dev) {
918*15f504adSChristophe Kerello ret = stm32_fmc2_parse_child(fmc2, child);
919*15f504adSChristophe Kerello if (ret)
920*15f504adSChristophe Kerello return ret;
921*15f504adSChristophe Kerello }
922*15f504adSChristophe Kerello
923*15f504adSChristophe Kerello return 0;
924*15f504adSChristophe Kerello }
925*15f504adSChristophe Kerello
stm32_fmc2_probe(struct udevice * dev)926*15f504adSChristophe Kerello static int stm32_fmc2_probe(struct udevice *dev)
927*15f504adSChristophe Kerello {
928*15f504adSChristophe Kerello struct stm32_fmc2_nfc *fmc2 = dev_get_priv(dev);
929*15f504adSChristophe Kerello struct stm32_fmc2_nand *nand = &fmc2->nand;
930*15f504adSChristophe Kerello struct nand_chip *chip = &nand->chip;
931*15f504adSChristophe Kerello struct mtd_info *mtd = &chip->mtd;
932*15f504adSChristophe Kerello struct nand_ecclayout *ecclayout;
933*15f504adSChristophe Kerello struct resource resource;
934*15f504adSChristophe Kerello struct reset_ctl reset;
935*15f504adSChristophe Kerello int oob_index, chip_cs, mem_region, ret, i;
936*15f504adSChristophe Kerello
937*15f504adSChristophe Kerello spin_lock_init(&fmc2->controller.lock);
938*15f504adSChristophe Kerello init_waitqueue_head(&fmc2->controller.wq);
939*15f504adSChristophe Kerello
940*15f504adSChristophe Kerello ret = stm32_fmc2_parse_dt(dev, fmc2);
941*15f504adSChristophe Kerello if (ret)
942*15f504adSChristophe Kerello return ret;
943*15f504adSChristophe Kerello
944*15f504adSChristophe Kerello /* Get resources */
945*15f504adSChristophe Kerello ret = dev_read_resource(dev, 0, &resource);
946*15f504adSChristophe Kerello if (ret) {
947*15f504adSChristophe Kerello pr_err("Resource io_base not found");
948*15f504adSChristophe Kerello return ret;
949*15f504adSChristophe Kerello }
950*15f504adSChristophe Kerello fmc2->io_base = (void __iomem *)resource.start;
951*15f504adSChristophe Kerello
952*15f504adSChristophe Kerello for (chip_cs = 0, mem_region = 1; chip_cs < FMC2_MAX_CE;
953*15f504adSChristophe Kerello chip_cs++, mem_region += 3) {
954*15f504adSChristophe Kerello if (!(fmc2->cs_assigned & BIT(chip_cs)))
955*15f504adSChristophe Kerello continue;
956*15f504adSChristophe Kerello
957*15f504adSChristophe Kerello ret = dev_read_resource(dev, mem_region, &resource);
958*15f504adSChristophe Kerello if (ret) {
959*15f504adSChristophe Kerello pr_err("Resource data_base not found for cs%d",
960*15f504adSChristophe Kerello chip_cs);
961*15f504adSChristophe Kerello return ret;
962*15f504adSChristophe Kerello }
963*15f504adSChristophe Kerello fmc2->data_base[chip_cs] = (void __iomem *)resource.start;
964*15f504adSChristophe Kerello
965*15f504adSChristophe Kerello ret = dev_read_resource(dev, mem_region + 1, &resource);
966*15f504adSChristophe Kerello if (ret) {
967*15f504adSChristophe Kerello pr_err("Resource cmd_base not found for cs%d",
968*15f504adSChristophe Kerello chip_cs);
969*15f504adSChristophe Kerello return ret;
970*15f504adSChristophe Kerello }
971*15f504adSChristophe Kerello fmc2->cmd_base[chip_cs] = (void __iomem *)resource.start;
972*15f504adSChristophe Kerello
973*15f504adSChristophe Kerello ret = dev_read_resource(dev, mem_region + 2, &resource);
974*15f504adSChristophe Kerello if (ret) {
975*15f504adSChristophe Kerello pr_err("Resource addr_base not found for cs%d",
976*15f504adSChristophe Kerello chip_cs);
977*15f504adSChristophe Kerello return ret;
978*15f504adSChristophe Kerello }
979*15f504adSChristophe Kerello fmc2->addr_base[chip_cs] = (void __iomem *)resource.start;
980*15f504adSChristophe Kerello }
981*15f504adSChristophe Kerello
982*15f504adSChristophe Kerello /* Enable the clock */
983*15f504adSChristophe Kerello ret = clk_get_by_index(dev, 0, &fmc2->clk);
984*15f504adSChristophe Kerello if (ret)
985*15f504adSChristophe Kerello return ret;
986*15f504adSChristophe Kerello
987*15f504adSChristophe Kerello ret = clk_enable(&fmc2->clk);
988*15f504adSChristophe Kerello if (ret)
989*15f504adSChristophe Kerello return ret;
990*15f504adSChristophe Kerello
991*15f504adSChristophe Kerello /* Reset */
992*15f504adSChristophe Kerello ret = reset_get_by_index(dev, 0, &reset);
993*15f504adSChristophe Kerello if (!ret) {
994*15f504adSChristophe Kerello reset_assert(&reset);
995*15f504adSChristophe Kerello udelay(2);
996*15f504adSChristophe Kerello reset_deassert(&reset);
997*15f504adSChristophe Kerello }
998*15f504adSChristophe Kerello
999*15f504adSChristophe Kerello /* FMC2 init routine */
1000*15f504adSChristophe Kerello stm32_fmc2_init(fmc2);
1001*15f504adSChristophe Kerello
1002*15f504adSChristophe Kerello chip->controller = &fmc2->base;
1003*15f504adSChristophe Kerello chip->select_chip = stm32_fmc2_select_chip;
1004*15f504adSChristophe Kerello chip->setup_data_interface = stm32_fmc2_setup_interface;
1005*15f504adSChristophe Kerello chip->cmd_ctrl = stm32_fmc2_cmd_ctrl;
1006*15f504adSChristophe Kerello chip->chip_delay = FMC2_RB_DELAY_US;
1007*15f504adSChristophe Kerello chip->options |= NAND_BUSWIDTH_AUTO | NAND_NO_SUBPAGE_WRITE |
1008*15f504adSChristophe Kerello NAND_USE_BOUNCE_BUFFER;
1009*15f504adSChristophe Kerello
1010*15f504adSChristophe Kerello /* Default ECC settings */
1011*15f504adSChristophe Kerello chip->ecc.mode = NAND_ECC_HW;
1012*15f504adSChristophe Kerello chip->ecc.size = FMC2_ECC_STEP_SIZE;
1013*15f504adSChristophe Kerello chip->ecc.strength = FMC2_ECC_BCH8;
1014*15f504adSChristophe Kerello
1015*15f504adSChristophe Kerello /* Scan to find existence of the device */
1016*15f504adSChristophe Kerello ret = nand_scan_ident(mtd, nand->ncs, NULL);
1017*15f504adSChristophe Kerello if (ret)
1018*15f504adSChristophe Kerello return ret;
1019*15f504adSChristophe Kerello
1020*15f504adSChristophe Kerello /*
1021*15f504adSChristophe Kerello * Only NAND_ECC_HW mode is actually supported
1022*15f504adSChristophe Kerello * Hamming => ecc.strength = 1
1023*15f504adSChristophe Kerello * BCH4 => ecc.strength = 4
1024*15f504adSChristophe Kerello * BCH8 => ecc.strength = 8
1025*15f504adSChristophe Kerello * ECC sector size = 512
1026*15f504adSChristophe Kerello */
1027*15f504adSChristophe Kerello if (chip->ecc.mode != NAND_ECC_HW) {
1028*15f504adSChristophe Kerello pr_err("Nand_ecc_mode is not well defined in the DT\n");
1029*15f504adSChristophe Kerello return -EINVAL;
1030*15f504adSChristophe Kerello }
1031*15f504adSChristophe Kerello
1032*15f504adSChristophe Kerello ret = nand_check_ecc_caps(chip, &stm32_fmc2_ecc_caps,
1033*15f504adSChristophe Kerello mtd->oobsize - FMC2_BBM_LEN);
1034*15f504adSChristophe Kerello if (ret) {
1035*15f504adSChristophe Kerello pr_err("No valid ECC settings set\n");
1036*15f504adSChristophe Kerello return ret;
1037*15f504adSChristophe Kerello }
1038*15f504adSChristophe Kerello
1039*15f504adSChristophe Kerello if (chip->bbt_options & NAND_BBT_USE_FLASH)
1040*15f504adSChristophe Kerello chip->bbt_options |= NAND_BBT_NO_OOB;
1041*15f504adSChristophe Kerello
1042*15f504adSChristophe Kerello /* NAND callbacks setup */
1043*15f504adSChristophe Kerello stm32_fmc2_nand_callbacks_setup(chip);
1044*15f504adSChristophe Kerello
1045*15f504adSChristophe Kerello /* Define ECC layout */
1046*15f504adSChristophe Kerello ecclayout = &fmc2->ecclayout;
1047*15f504adSChristophe Kerello ecclayout->eccbytes = chip->ecc.bytes *
1048*15f504adSChristophe Kerello (mtd->writesize / chip->ecc.size);
1049*15f504adSChristophe Kerello oob_index = FMC2_BBM_LEN;
1050*15f504adSChristophe Kerello for (i = 0; i < ecclayout->eccbytes; i++, oob_index++)
1051*15f504adSChristophe Kerello ecclayout->eccpos[i] = oob_index;
1052*15f504adSChristophe Kerello ecclayout->oobfree->offset = oob_index;
1053*15f504adSChristophe Kerello ecclayout->oobfree->length = mtd->oobsize - ecclayout->oobfree->offset;
1054*15f504adSChristophe Kerello chip->ecc.layout = ecclayout;
1055*15f504adSChristophe Kerello
1056*15f504adSChristophe Kerello /* Configure bus width to 16-bit */
1057*15f504adSChristophe Kerello if (chip->options & NAND_BUSWIDTH_16)
1058*15f504adSChristophe Kerello stm32_fmc2_set_buswidth_16(fmc2, true);
1059*15f504adSChristophe Kerello
1060*15f504adSChristophe Kerello /* Scan the device to fill MTD data-structures */
1061*15f504adSChristophe Kerello ret = nand_scan_tail(mtd);
1062*15f504adSChristophe Kerello if (ret)
1063*15f504adSChristophe Kerello return ret;
1064*15f504adSChristophe Kerello
1065*15f504adSChristophe Kerello return nand_register(0, mtd);
1066*15f504adSChristophe Kerello }
1067*15f504adSChristophe Kerello
1068*15f504adSChristophe Kerello static const struct udevice_id stm32_fmc2_match[] = {
1069*15f504adSChristophe Kerello { .compatible = "st,stm32mp15-fmc2" },
1070*15f504adSChristophe Kerello { /* Sentinel */ }
1071*15f504adSChristophe Kerello };
1072*15f504adSChristophe Kerello
1073*15f504adSChristophe Kerello U_BOOT_DRIVER(stm32_fmc2_nand) = {
1074*15f504adSChristophe Kerello .name = "stm32_fmc2_nand",
1075*15f504adSChristophe Kerello .id = UCLASS_MTD,
1076*15f504adSChristophe Kerello .of_match = stm32_fmc2_match,
1077*15f504adSChristophe Kerello .probe = stm32_fmc2_probe,
1078*15f504adSChristophe Kerello .priv_auto_alloc_size = sizeof(struct stm32_fmc2_nfc),
1079*15f504adSChristophe Kerello };
1080*15f504adSChristophe Kerello
board_nand_init(void)1081*15f504adSChristophe Kerello void board_nand_init(void)
1082*15f504adSChristophe Kerello {
1083*15f504adSChristophe Kerello struct udevice *dev;
1084*15f504adSChristophe Kerello int ret;
1085*15f504adSChristophe Kerello
1086*15f504adSChristophe Kerello ret = uclass_get_device_by_driver(UCLASS_MTD,
1087*15f504adSChristophe Kerello DM_GET_DRIVER(stm32_fmc2_nand),
1088*15f504adSChristophe Kerello &dev);
1089*15f504adSChristophe Kerello if (ret && ret != -ENODEV)
1090*15f504adSChristophe Kerello pr_err("Failed to initialize STM32 FMC2 NAND controller. (error %d)\n",
1091*15f504adSChristophe Kerello ret);
1092*15f504adSChristophe Kerello }
1093