xref: /rk3399_ARM-atf/drivers/st/fmc/stm32_fmc2_nand.c (revision 695f7df85299fa4f9cad1b6b1c94a9e4d81049ee)
1*695f7df8SLionel Debieve /*
2*695f7df8SLionel Debieve  * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
3*695f7df8SLionel Debieve  *
4*695f7df8SLionel Debieve  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
5*695f7df8SLionel Debieve  */
6*695f7df8SLionel Debieve 
7*695f7df8SLionel Debieve #include <assert.h>
8*695f7df8SLionel Debieve #include <errno.h>
9*695f7df8SLionel Debieve #include <limits.h>
10*695f7df8SLionel Debieve #include <stdint.h>
11*695f7df8SLionel Debieve 
12*695f7df8SLionel Debieve #include <libfdt.h>
13*695f7df8SLionel Debieve 
14*695f7df8SLionel Debieve #include <platform_def.h>
15*695f7df8SLionel Debieve 
16*695f7df8SLionel Debieve #include <common/debug.h>
17*695f7df8SLionel Debieve #include <drivers/delay_timer.h>
18*695f7df8SLionel Debieve #include <drivers/raw_nand.h>
19*695f7df8SLionel Debieve #include <drivers/st/stm32_fmc2_nand.h>
20*695f7df8SLionel Debieve #include <drivers/st/stm32_gpio.h>
21*695f7df8SLionel Debieve #include <drivers/st/stm32mp_reset.h>
22*695f7df8SLionel Debieve #include <lib/mmio.h>
23*695f7df8SLionel Debieve #include <lib/utils_def.h>
24*695f7df8SLionel Debieve 
25*695f7df8SLionel Debieve /* FMC2 Compatibility */
26*695f7df8SLionel Debieve #define DT_FMC2_COMPAT			"st,stm32mp15-fmc2"
27*695f7df8SLionel Debieve #define MAX_CS				2U
28*695f7df8SLionel Debieve 
29*695f7df8SLionel Debieve /* FMC2 Controller Registers */
30*695f7df8SLionel Debieve #define FMC2_BCR1			0x00U
31*695f7df8SLionel Debieve #define FMC2_PCR			0x80U
32*695f7df8SLionel Debieve #define FMC2_SR				0x84U
33*695f7df8SLionel Debieve #define FMC2_PMEM			0x88U
34*695f7df8SLionel Debieve #define FMC2_PATT			0x8CU
35*695f7df8SLionel Debieve #define FMC2_HECCR			0x94U
36*695f7df8SLionel Debieve #define FMC2_BCHISR			0x254U
37*695f7df8SLionel Debieve #define FMC2_BCHDSR0			0x27CU
38*695f7df8SLionel Debieve #define FMC2_BCHDSR1			0x280U
39*695f7df8SLionel Debieve #define FMC2_BCHDSR2			0x284U
40*695f7df8SLionel Debieve #define FMC2_BCHDSR3			0x288U
41*695f7df8SLionel Debieve #define FMC2_BCHDSR4			0x28CU
42*695f7df8SLionel Debieve 
43*695f7df8SLionel Debieve /* FMC2_BCR1 register */
44*695f7df8SLionel Debieve #define FMC2_BCR1_FMC2EN		BIT(31)
45*695f7df8SLionel Debieve /* FMC2_PCR register */
46*695f7df8SLionel Debieve #define FMC2_PCR_PWAITEN		BIT(1)
47*695f7df8SLionel Debieve #define FMC2_PCR_PBKEN			BIT(2)
48*695f7df8SLionel Debieve #define FMC2_PCR_PWID_MASK		GENMASK_32(5, 4)
49*695f7df8SLionel Debieve #define FMC2_PCR_PWID(x)		(((x) << 4) & FMC2_PCR_PWID_MASK)
50*695f7df8SLionel Debieve #define FMC2_PCR_PWID_8			0x0U
51*695f7df8SLionel Debieve #define FMC2_PCR_PWID_16		0x1U
52*695f7df8SLionel Debieve #define FMC2_PCR_ECCEN			BIT(6)
53*695f7df8SLionel Debieve #define FMC2_PCR_ECCALG			BIT(8)
54*695f7df8SLionel Debieve #define FMC2_PCR_TCLR_MASK		GENMASK_32(12, 9)
55*695f7df8SLionel Debieve #define FMC2_PCR_TCLR(x)		(((x) << 9) & FMC2_PCR_TCLR_MASK)
56*695f7df8SLionel Debieve #define FMC2_PCR_TCLR_DEFAULT		0xFU
57*695f7df8SLionel Debieve #define FMC2_PCR_TAR_MASK		GENMASK_32(16, 13)
58*695f7df8SLionel Debieve #define FMC2_PCR_TAR(x)			(((x) << 13) & FMC2_PCR_TAR_MASK)
59*695f7df8SLionel Debieve #define FMC2_PCR_TAR_DEFAULT		0xFU
60*695f7df8SLionel Debieve #define FMC2_PCR_ECCSS_MASK		GENMASK_32(19, 17)
61*695f7df8SLionel Debieve #define FMC2_PCR_ECCSS(x)		(((x) << 17) & FMC2_PCR_ECCSS_MASK)
62*695f7df8SLionel Debieve #define FMC2_PCR_ECCSS_512		0x1U
63*695f7df8SLionel Debieve #define FMC2_PCR_ECCSS_2048		0x3U
64*695f7df8SLionel Debieve #define FMC2_PCR_BCHECC			BIT(24)
65*695f7df8SLionel Debieve #define FMC2_PCR_WEN			BIT(25)
66*695f7df8SLionel Debieve /* FMC2_SR register */
67*695f7df8SLionel Debieve #define FMC2_SR_NWRF			BIT(6)
68*695f7df8SLionel Debieve /* FMC2_PMEM register*/
69*695f7df8SLionel Debieve #define FMC2_PMEM_MEMSET(x)		(((x) & GENMASK_32(7, 0)) << 0)
70*695f7df8SLionel Debieve #define FMC2_PMEM_MEMWAIT(x)		(((x) & GENMASK_32(7, 0)) << 8)
71*695f7df8SLionel Debieve #define FMC2_PMEM_MEMHOLD(x)		(((x) & GENMASK_32(7, 0)) << 16)
72*695f7df8SLionel Debieve #define FMC2_PMEM_MEMHIZ(x)		(((x) & GENMASK_32(7, 0)) << 24)
73*695f7df8SLionel Debieve #define FMC2_PMEM_DEFAULT		0x0A0A0A0AU
74*695f7df8SLionel Debieve /* FMC2_PATT register */
75*695f7df8SLionel Debieve #define FMC2_PATT_ATTSET(x)		(((x) & GENMASK_32(7, 0)) << 0)
76*695f7df8SLionel Debieve #define FMC2_PATT_ATTWAIT(x)		(((x) & GENMASK_32(7, 0)) << 8)
77*695f7df8SLionel Debieve #define FMC2_PATT_ATTHOLD(x)		(((x) & GENMASK_32(7, 0)) << 16)
78*695f7df8SLionel Debieve #define FMC2_PATT_ATTHIZ(x)		(((x) & GENMASK_32(7, 0)) << 24)
79*695f7df8SLionel Debieve #define FMC2_PATT_DEFAULT		0x0A0A0A0AU
80*695f7df8SLionel Debieve /* FMC2_BCHISR register */
81*695f7df8SLionel Debieve #define FMC2_BCHISR_DERF		BIT(1)
82*695f7df8SLionel Debieve /* FMC2_BCHDSR0 register */
83*695f7df8SLionel Debieve #define FMC2_BCHDSR0_DUE		BIT(0)
84*695f7df8SLionel Debieve #define FMC2_BCHDSR0_DEF		BIT(1)
85*695f7df8SLionel Debieve #define FMC2_BCHDSR0_DEN_MASK		GENMASK_32(7, 4)
86*695f7df8SLionel Debieve #define FMC2_BCHDSR0_DEN_SHIFT		4U
87*695f7df8SLionel Debieve /* FMC2_BCHDSR1 register */
88*695f7df8SLionel Debieve #define FMC2_BCHDSR1_EBP1_MASK		GENMASK_32(12, 0)
89*695f7df8SLionel Debieve #define FMC2_BCHDSR1_EBP2_MASK		GENMASK_32(28, 16)
90*695f7df8SLionel Debieve #define FMC2_BCHDSR1_EBP2_SHIFT		16U
91*695f7df8SLionel Debieve /* FMC2_BCHDSR2 register */
92*695f7df8SLionel Debieve #define FMC2_BCHDSR2_EBP3_MASK		GENMASK_32(12, 0)
93*695f7df8SLionel Debieve #define FMC2_BCHDSR2_EBP4_MASK		GENMASK_32(28, 16)
94*695f7df8SLionel Debieve #define FMC2_BCHDSR2_EBP4_SHIFT		16U
95*695f7df8SLionel Debieve /* FMC2_BCHDSR3 register */
96*695f7df8SLionel Debieve #define FMC2_BCHDSR3_EBP5_MASK		GENMASK_32(12, 0)
97*695f7df8SLionel Debieve #define FMC2_BCHDSR3_EBP6_MASK		GENMASK_32(28, 16)
98*695f7df8SLionel Debieve #define FMC2_BCHDSR3_EBP6_SHIFT		16U
99*695f7df8SLionel Debieve /* FMC2_BCHDSR4 register */
100*695f7df8SLionel Debieve #define FMC2_BCHDSR4_EBP7_MASK		GENMASK_32(12, 0)
101*695f7df8SLionel Debieve #define FMC2_BCHDSR4_EBP8_MASK		GENMASK_32(28, 16)
102*695f7df8SLionel Debieve #define FMC2_BCHDSR4_EBP8_SHIFT		16U
103*695f7df8SLionel Debieve 
104*695f7df8SLionel Debieve /* Timings */
105*695f7df8SLionel Debieve #define FMC2_THIZ			0x01U
106*695f7df8SLionel Debieve #define FMC2_TIO			8000U
107*695f7df8SLionel Debieve #define FMC2_TSYNC			3000U
108*695f7df8SLionel Debieve #define FMC2_PCR_TIMING_MASK		GENMASK_32(3, 0)
109*695f7df8SLionel Debieve #define FMC2_PMEM_PATT_TIMING_MASK	GENMASK_32(7, 0)
110*695f7df8SLionel Debieve 
111*695f7df8SLionel Debieve #define FMC2_BBM_LEN			2U
112*695f7df8SLionel Debieve #define FMC2_MAX_ECC_BYTES		14U
113*695f7df8SLionel Debieve #define TIMEOUT_US_10_MS		10000U
114*695f7df8SLionel Debieve #define FMC2_PSEC_PER_MSEC		(1000UL * 1000UL * 1000UL)
115*695f7df8SLionel Debieve 
116*695f7df8SLionel Debieve enum stm32_fmc2_ecc {
117*695f7df8SLionel Debieve 	FMC2_ECC_HAM = 1U,
118*695f7df8SLionel Debieve 	FMC2_ECC_BCH4 = 4U,
119*695f7df8SLionel Debieve 	FMC2_ECC_BCH8 = 8U
120*695f7df8SLionel Debieve };
121*695f7df8SLionel Debieve 
122*695f7df8SLionel Debieve struct stm32_fmc2_cs_reg {
123*695f7df8SLionel Debieve 	uintptr_t data_base;
124*695f7df8SLionel Debieve 	uintptr_t cmd_base;
125*695f7df8SLionel Debieve 	uintptr_t addr_base;
126*695f7df8SLionel Debieve };
127*695f7df8SLionel Debieve 
128*695f7df8SLionel Debieve struct stm32_fmc2_nand_timings {
129*695f7df8SLionel Debieve 	uint8_t tclr;
130*695f7df8SLionel Debieve 	uint8_t tar;
131*695f7df8SLionel Debieve 	uint8_t thiz;
132*695f7df8SLionel Debieve 	uint8_t twait;
133*695f7df8SLionel Debieve 	uint8_t thold_mem;
134*695f7df8SLionel Debieve 	uint8_t tset_mem;
135*695f7df8SLionel Debieve 	uint8_t thold_att;
136*695f7df8SLionel Debieve 	uint8_t tset_att;
137*695f7df8SLionel Debieve };
138*695f7df8SLionel Debieve 
139*695f7df8SLionel Debieve struct stm32_fmc2_nfc {
140*695f7df8SLionel Debieve 	uintptr_t reg_base;
141*695f7df8SLionel Debieve 	struct stm32_fmc2_cs_reg cs[MAX_CS];
142*695f7df8SLionel Debieve 	unsigned long clock_id;
143*695f7df8SLionel Debieve 	unsigned int reset_id;
144*695f7df8SLionel Debieve 	uint8_t cs_sel;
145*695f7df8SLionel Debieve };
146*695f7df8SLionel Debieve 
147*695f7df8SLionel Debieve static struct stm32_fmc2_nfc stm32_fmc2;
148*695f7df8SLionel Debieve 
149*695f7df8SLionel Debieve static uintptr_t fmc2_base(void)
150*695f7df8SLionel Debieve {
151*695f7df8SLionel Debieve 	return stm32_fmc2.reg_base;
152*695f7df8SLionel Debieve }
153*695f7df8SLionel Debieve 
154*695f7df8SLionel Debieve static void stm32_fmc2_nand_setup_timing(void)
155*695f7df8SLionel Debieve {
156*695f7df8SLionel Debieve 	struct stm32_fmc2_nand_timings tims;
157*695f7df8SLionel Debieve 	unsigned long hclk = stm32mp_clk_get_rate(stm32_fmc2.clock_id);
158*695f7df8SLionel Debieve 	unsigned long hclkp = FMC2_PSEC_PER_MSEC / (hclk / 1000U);
159*695f7df8SLionel Debieve 	unsigned long timing, tar, tclr, thiz, twait;
160*695f7df8SLionel Debieve 	unsigned long tset_mem, tset_att, thold_mem, thold_att;
161*695f7df8SLionel Debieve 	uint32_t pcr, pmem, patt;
162*695f7df8SLionel Debieve 
163*695f7df8SLionel Debieve 	tar = MAX(hclkp, NAND_TAR_MIN);
164*695f7df8SLionel Debieve 	timing = div_round_up(tar, hclkp) - 1U;
165*695f7df8SLionel Debieve 	tims.tar = MIN(timing, (unsigned long)FMC2_PCR_TIMING_MASK);
166*695f7df8SLionel Debieve 
167*695f7df8SLionel Debieve 	tclr = MAX(hclkp, NAND_TCLR_MIN);
168*695f7df8SLionel Debieve 	timing = div_round_up(tclr, hclkp) - 1U;
169*695f7df8SLionel Debieve 	tims.tclr = MIN(timing, (unsigned long)FMC2_PCR_TIMING_MASK);
170*695f7df8SLionel Debieve 
171*695f7df8SLionel Debieve 	tims.thiz = FMC2_THIZ;
172*695f7df8SLionel Debieve 	thiz = (tims.thiz + 1U) * hclkp;
173*695f7df8SLionel Debieve 
174*695f7df8SLionel Debieve 	/*
175*695f7df8SLionel Debieve 	 * tWAIT > tRP
176*695f7df8SLionel Debieve 	 * tWAIT > tWP
177*695f7df8SLionel Debieve 	 * tWAIT > tREA + tIO
178*695f7df8SLionel Debieve 	 */
179*695f7df8SLionel Debieve 	twait = MAX(hclkp, NAND_TRP_MIN);
180*695f7df8SLionel Debieve 	twait = MAX(twait, NAND_TWP_MIN);
181*695f7df8SLionel Debieve 	twait = MAX(twait, NAND_TREA_MAX + FMC2_TIO);
182*695f7df8SLionel Debieve 	timing = div_round_up(twait, hclkp);
183*695f7df8SLionel Debieve 	tims.twait = CLAMP(timing, 1UL,
184*695f7df8SLionel Debieve 			   (unsigned long)FMC2_PMEM_PATT_TIMING_MASK);
185*695f7df8SLionel Debieve 
186*695f7df8SLionel Debieve 	/*
187*695f7df8SLionel Debieve 	 * tSETUP_MEM > tCS - tWAIT
188*695f7df8SLionel Debieve 	 * tSETUP_MEM > tALS - tWAIT
189*695f7df8SLionel Debieve 	 * tSETUP_MEM > tDS - (tWAIT - tHIZ)
190*695f7df8SLionel Debieve 	 */
191*695f7df8SLionel Debieve 	tset_mem = hclkp;
192*695f7df8SLionel Debieve 	if ((twait < NAND_TCS_MIN) && (tset_mem < (NAND_TCS_MIN - twait))) {
193*695f7df8SLionel Debieve 		tset_mem = NAND_TCS_MIN - twait;
194*695f7df8SLionel Debieve 	}
195*695f7df8SLionel Debieve 	if ((twait < NAND_TALS_MIN) && (tset_mem < (NAND_TALS_MIN - twait))) {
196*695f7df8SLionel Debieve 		tset_mem = NAND_TALS_MIN - twait;
197*695f7df8SLionel Debieve 	}
198*695f7df8SLionel Debieve 	if ((twait > thiz) && ((twait - thiz) < NAND_TDS_MIN) &&
199*695f7df8SLionel Debieve 	    (tset_mem < (NAND_TDS_MIN - (twait - thiz)))) {
200*695f7df8SLionel Debieve 		tset_mem = NAND_TDS_MIN - (twait - thiz);
201*695f7df8SLionel Debieve 	}
202*695f7df8SLionel Debieve 	timing = div_round_up(tset_mem, hclkp);
203*695f7df8SLionel Debieve 	tims.tset_mem = CLAMP(timing, 1UL,
204*695f7df8SLionel Debieve 			      (unsigned long)FMC2_PMEM_PATT_TIMING_MASK);
205*695f7df8SLionel Debieve 
206*695f7df8SLionel Debieve 	/*
207*695f7df8SLionel Debieve 	 * tHOLD_MEM > tCH
208*695f7df8SLionel Debieve 	 * tHOLD_MEM > tREH - tSETUP_MEM
209*695f7df8SLionel Debieve 	 * tHOLD_MEM > max(tRC, tWC) - (tSETUP_MEM + tWAIT)
210*695f7df8SLionel Debieve 	 */
211*695f7df8SLionel Debieve 	thold_mem = MAX(hclkp, NAND_TCH_MIN);
212*695f7df8SLionel Debieve 	if ((tset_mem < NAND_TREH_MIN) &&
213*695f7df8SLionel Debieve 	    (thold_mem < (NAND_TREH_MIN - tset_mem))) {
214*695f7df8SLionel Debieve 		thold_mem = NAND_TREH_MIN - tset_mem;
215*695f7df8SLionel Debieve 	}
216*695f7df8SLionel Debieve 	if (((tset_mem + twait) < NAND_TRC_MIN) &&
217*695f7df8SLionel Debieve 	    (thold_mem < (NAND_TRC_MIN - (tset_mem + twait)))) {
218*695f7df8SLionel Debieve 		thold_mem = NAND_TRC_MIN  - (tset_mem + twait);
219*695f7df8SLionel Debieve 	}
220*695f7df8SLionel Debieve 	if (((tset_mem + twait) < NAND_TWC_MIN) &&
221*695f7df8SLionel Debieve 	    (thold_mem < (NAND_TWC_MIN - (tset_mem + twait)))) {
222*695f7df8SLionel Debieve 		thold_mem = NAND_TWC_MIN - (tset_mem + twait);
223*695f7df8SLionel Debieve 	}
224*695f7df8SLionel Debieve 	timing = div_round_up(thold_mem, hclkp);
225*695f7df8SLionel Debieve 	tims.thold_mem = CLAMP(timing, 1UL,
226*695f7df8SLionel Debieve 			       (unsigned long)FMC2_PMEM_PATT_TIMING_MASK);
227*695f7df8SLionel Debieve 
228*695f7df8SLionel Debieve 	/*
229*695f7df8SLionel Debieve 	 * tSETUP_ATT > tCS - tWAIT
230*695f7df8SLionel Debieve 	 * tSETUP_ATT > tCLS - tWAIT
231*695f7df8SLionel Debieve 	 * tSETUP_ATT > tALS - tWAIT
232*695f7df8SLionel Debieve 	 * tSETUP_ATT > tRHW - tHOLD_MEM
233*695f7df8SLionel Debieve 	 * tSETUP_ATT > tDS - (tWAIT - tHIZ)
234*695f7df8SLionel Debieve 	 */
235*695f7df8SLionel Debieve 	tset_att = hclkp;
236*695f7df8SLionel Debieve 	if ((twait < NAND_TCS_MIN) && (tset_att < (NAND_TCS_MIN - twait))) {
237*695f7df8SLionel Debieve 		tset_att = NAND_TCS_MIN - twait;
238*695f7df8SLionel Debieve 	}
239*695f7df8SLionel Debieve 	if ((twait < NAND_TCLS_MIN) && (tset_att < (NAND_TCLS_MIN - twait))) {
240*695f7df8SLionel Debieve 		tset_att = NAND_TCLS_MIN - twait;
241*695f7df8SLionel Debieve 	}
242*695f7df8SLionel Debieve 	if ((twait < NAND_TALS_MIN) && (tset_att < (NAND_TALS_MIN - twait))) {
243*695f7df8SLionel Debieve 		tset_att = NAND_TALS_MIN - twait;
244*695f7df8SLionel Debieve 	}
245*695f7df8SLionel Debieve 	if ((thold_mem < NAND_TRHW_MIN) &&
246*695f7df8SLionel Debieve 	    (tset_att < (NAND_TRHW_MIN - thold_mem))) {
247*695f7df8SLionel Debieve 		tset_att = NAND_TRHW_MIN - thold_mem;
248*695f7df8SLionel Debieve 	}
249*695f7df8SLionel Debieve 	if ((twait > thiz) && ((twait - thiz) < NAND_TDS_MIN) &&
250*695f7df8SLionel Debieve 	    (tset_att < (NAND_TDS_MIN - (twait - thiz)))) {
251*695f7df8SLionel Debieve 		tset_att = NAND_TDS_MIN - (twait - thiz);
252*695f7df8SLionel Debieve 	}
253*695f7df8SLionel Debieve 	timing = div_round_up(tset_att, hclkp);
254*695f7df8SLionel Debieve 	tims.tset_att = CLAMP(timing, 1UL,
255*695f7df8SLionel Debieve 			      (unsigned long)FMC2_PMEM_PATT_TIMING_MASK);
256*695f7df8SLionel Debieve 
257*695f7df8SLionel Debieve 	/*
258*695f7df8SLionel Debieve 	 * tHOLD_ATT > tALH
259*695f7df8SLionel Debieve 	 * tHOLD_ATT > tCH
260*695f7df8SLionel Debieve 	 * tHOLD_ATT > tCLH
261*695f7df8SLionel Debieve 	 * tHOLD_ATT > tCOH
262*695f7df8SLionel Debieve 	 * tHOLD_ATT > tDH
263*695f7df8SLionel Debieve 	 * tHOLD_ATT > tWB + tIO + tSYNC - tSETUP_MEM
264*695f7df8SLionel Debieve 	 * tHOLD_ATT > tADL - tSETUP_MEM
265*695f7df8SLionel Debieve 	 * tHOLD_ATT > tWH - tSETUP_MEM
266*695f7df8SLionel Debieve 	 * tHOLD_ATT > tWHR - tSETUP_MEM
267*695f7df8SLionel Debieve 	 * tHOLD_ATT > tRC - (tSETUP_ATT + tWAIT)
268*695f7df8SLionel Debieve 	 * tHOLD_ATT > tWC - (tSETUP_ATT + tWAIT)
269*695f7df8SLionel Debieve 	 */
270*695f7df8SLionel Debieve 	thold_att = MAX(hclkp, NAND_TALH_MIN);
271*695f7df8SLionel Debieve 	thold_att = MAX(thold_att, NAND_TCH_MIN);
272*695f7df8SLionel Debieve 	thold_att = MAX(thold_att, NAND_TCLH_MIN);
273*695f7df8SLionel Debieve 	thold_att = MAX(thold_att, NAND_TCOH_MIN);
274*695f7df8SLionel Debieve 	thold_att = MAX(thold_att, NAND_TDH_MIN);
275*695f7df8SLionel Debieve 	if (((NAND_TWB_MAX + FMC2_TIO + FMC2_TSYNC) > tset_mem) &&
276*695f7df8SLionel Debieve 	    (thold_att < (NAND_TWB_MAX + FMC2_TIO + FMC2_TSYNC - tset_mem))) {
277*695f7df8SLionel Debieve 		thold_att = NAND_TWB_MAX + FMC2_TIO + FMC2_TSYNC - tset_mem;
278*695f7df8SLionel Debieve 	}
279*695f7df8SLionel Debieve 	if ((tset_mem < NAND_TADL_MIN) &&
280*695f7df8SLionel Debieve 	    (thold_att < (NAND_TADL_MIN - tset_mem))) {
281*695f7df8SLionel Debieve 		thold_att = NAND_TADL_MIN - tset_mem;
282*695f7df8SLionel Debieve 	}
283*695f7df8SLionel Debieve 	if ((tset_mem < NAND_TWH_MIN) &&
284*695f7df8SLionel Debieve 	    (thold_att < (NAND_TWH_MIN - tset_mem))) {
285*695f7df8SLionel Debieve 		thold_att = NAND_TWH_MIN - tset_mem;
286*695f7df8SLionel Debieve 	}
287*695f7df8SLionel Debieve 	if ((tset_mem < NAND_TWHR_MIN) &&
288*695f7df8SLionel Debieve 	    (thold_att < (NAND_TWHR_MIN - tset_mem))) {
289*695f7df8SLionel Debieve 		thold_att = NAND_TWHR_MIN - tset_mem;
290*695f7df8SLionel Debieve 	}
291*695f7df8SLionel Debieve 	if (((tset_att + twait) < NAND_TRC_MIN) &&
292*695f7df8SLionel Debieve 	    (thold_att < (NAND_TRC_MIN - (tset_att + twait)))) {
293*695f7df8SLionel Debieve 		thold_att = NAND_TRC_MIN - (tset_att + twait);
294*695f7df8SLionel Debieve 	}
295*695f7df8SLionel Debieve 	if (((tset_att + twait) < NAND_TWC_MIN) &&
296*695f7df8SLionel Debieve 	    (thold_att < (NAND_TWC_MIN - (tset_att + twait)))) {
297*695f7df8SLionel Debieve 		thold_att = NAND_TWC_MIN - (tset_att + twait);
298*695f7df8SLionel Debieve 	}
299*695f7df8SLionel Debieve 	timing = div_round_up(thold_att, hclkp);
300*695f7df8SLionel Debieve 	tims.thold_att = CLAMP(timing, 1UL,
301*695f7df8SLionel Debieve 			       (unsigned long)FMC2_PMEM_PATT_TIMING_MASK);
302*695f7df8SLionel Debieve 
303*695f7df8SLionel Debieve 	VERBOSE("NAND timings: %u - %u - %u - %u - %u - %u - %u - %u\n",
304*695f7df8SLionel Debieve 		tims.tclr, tims.tar, tims.thiz, tims.twait,
305*695f7df8SLionel Debieve 		tims.thold_mem, tims.tset_mem,
306*695f7df8SLionel Debieve 		tims.thold_att, tims.tset_att);
307*695f7df8SLionel Debieve 
308*695f7df8SLionel Debieve 	/* Set tclr/tar timings */
309*695f7df8SLionel Debieve 	pcr = mmio_read_32(fmc2_base() + FMC2_PCR);
310*695f7df8SLionel Debieve 	pcr &= ~FMC2_PCR_TCLR_MASK;
311*695f7df8SLionel Debieve 	pcr |= FMC2_PCR_TCLR(tims.tclr);
312*695f7df8SLionel Debieve 	pcr &= ~FMC2_PCR_TAR_MASK;
313*695f7df8SLionel Debieve 	pcr |= FMC2_PCR_TAR(tims.tar);
314*695f7df8SLionel Debieve 
315*695f7df8SLionel Debieve 	/* Set tset/twait/thold/thiz timings in common bank */
316*695f7df8SLionel Debieve 	pmem = FMC2_PMEM_MEMSET(tims.tset_mem);
317*695f7df8SLionel Debieve 	pmem |= FMC2_PMEM_MEMWAIT(tims.twait);
318*695f7df8SLionel Debieve 	pmem |=	FMC2_PMEM_MEMHOLD(tims.thold_mem);
319*695f7df8SLionel Debieve 	pmem |= FMC2_PMEM_MEMHIZ(tims.thiz);
320*695f7df8SLionel Debieve 
321*695f7df8SLionel Debieve 	/* Set tset/twait/thold/thiz timings in attribute bank */
322*695f7df8SLionel Debieve 	patt = FMC2_PATT_ATTSET(tims.tset_att);
323*695f7df8SLionel Debieve 	patt |= FMC2_PATT_ATTWAIT(tims.twait);
324*695f7df8SLionel Debieve 	patt |= FMC2_PATT_ATTHOLD(tims.thold_att);
325*695f7df8SLionel Debieve 	patt |= FMC2_PATT_ATTHIZ(tims.thiz);
326*695f7df8SLionel Debieve 
327*695f7df8SLionel Debieve 	mmio_write_32(fmc2_base() + FMC2_PCR, pcr);
328*695f7df8SLionel Debieve 	mmio_write_32(fmc2_base() + FMC2_PMEM, pmem);
329*695f7df8SLionel Debieve 	mmio_write_32(fmc2_base() + FMC2_PATT, patt);
330*695f7df8SLionel Debieve }
331*695f7df8SLionel Debieve 
332*695f7df8SLionel Debieve static void stm32_fmc2_set_buswidth_16(bool set)
333*695f7df8SLionel Debieve {
334*695f7df8SLionel Debieve 	mmio_clrsetbits_32(fmc2_base() + FMC2_PCR, FMC2_PCR_PWID_MASK,
335*695f7df8SLionel Debieve 			   (set ? FMC2_PCR_PWID(FMC2_PCR_PWID_16) : 0U));
336*695f7df8SLionel Debieve }
337*695f7df8SLionel Debieve 
338*695f7df8SLionel Debieve static void stm32_fmc2_set_ecc(bool enable)
339*695f7df8SLionel Debieve {
340*695f7df8SLionel Debieve 	mmio_clrsetbits_32(fmc2_base() + FMC2_PCR, FMC2_PCR_ECCEN,
341*695f7df8SLionel Debieve 			   (enable ? FMC2_PCR_ECCEN : 0U));
342*695f7df8SLionel Debieve }
343*695f7df8SLionel Debieve 
344*695f7df8SLionel Debieve static int stm32_fmc2_ham_correct(uint8_t *buffer, uint8_t *eccbuffer,
345*695f7df8SLionel Debieve 				  uint8_t *ecc)
346*695f7df8SLionel Debieve {
347*695f7df8SLionel Debieve 	uint8_t xor_ecc_ones;
348*695f7df8SLionel Debieve 	uint16_t xor_ecc_1b, xor_ecc_2b, xor_ecc_3b;
349*695f7df8SLionel Debieve 	union {
350*695f7df8SLionel Debieve 		uint32_t val;
351*695f7df8SLionel Debieve 		uint8_t  bytes[4];
352*695f7df8SLionel Debieve 	} xor_ecc;
353*695f7df8SLionel Debieve 
354*695f7df8SLionel Debieve 	/* Page size--------ECC_Code Size
355*695f7df8SLionel Debieve 	 * 256---------------22 bits LSB  (ECC_CODE & 0x003FFFFF)
356*695f7df8SLionel Debieve 	 * 512---------------24 bits      (ECC_CODE & 0x00FFFFFF)
357*695f7df8SLionel Debieve 	 * 1024--------------26 bits      (ECC_CODE & 0x03FFFFFF)
358*695f7df8SLionel Debieve 	 * 2048--------------28 bits      (ECC_CODE & 0x0FFFFFFF)
359*695f7df8SLionel Debieve 	 * 4096--------------30 bits      (ECC_CODE & 0x3FFFFFFF)
360*695f7df8SLionel Debieve 	 * 8192--------------32 bits      (ECC_CODE & 0xFFFFFFFF)
361*695f7df8SLionel Debieve 	 */
362*695f7df8SLionel Debieve 
363*695f7df8SLionel Debieve 	/* For Page size 512, ECC_Code size 24 bits */
364*695f7df8SLionel Debieve 	xor_ecc_1b = ecc[0] ^ eccbuffer[0];
365*695f7df8SLionel Debieve 	xor_ecc_2b = ecc[1] ^ eccbuffer[1];
366*695f7df8SLionel Debieve 	xor_ecc_3b = ecc[2] ^ eccbuffer[2];
367*695f7df8SLionel Debieve 
368*695f7df8SLionel Debieve 	xor_ecc.val = 0L;
369*695f7df8SLionel Debieve 	xor_ecc.bytes[2] = xor_ecc_3b;
370*695f7df8SLionel Debieve 	xor_ecc.bytes[1] = xor_ecc_2b;
371*695f7df8SLionel Debieve 	xor_ecc.bytes[0] = xor_ecc_1b;
372*695f7df8SLionel Debieve 
373*695f7df8SLionel Debieve 	if (xor_ecc.val == 0U) {
374*695f7df8SLionel Debieve 		return 0; /* No Error */
375*695f7df8SLionel Debieve 	}
376*695f7df8SLionel Debieve 
377*695f7df8SLionel Debieve 	xor_ecc_ones = __builtin_popcount(xor_ecc.val);
378*695f7df8SLionel Debieve 	if (xor_ecc_ones < 23U) {
379*695f7df8SLionel Debieve 		if (xor_ecc_ones == 12U) {
380*695f7df8SLionel Debieve 			uint16_t bit_address, byte_address;
381*695f7df8SLionel Debieve 
382*695f7df8SLionel Debieve 			/* Correctable ERROR */
383*695f7df8SLionel Debieve 			bit_address = ((xor_ecc_1b >> 1) & BIT(0)) |
384*695f7df8SLionel Debieve 				      ((xor_ecc_1b >> 2) & BIT(1)) |
385*695f7df8SLionel Debieve 				      ((xor_ecc_1b >> 3) & BIT(2));
386*695f7df8SLionel Debieve 
387*695f7df8SLionel Debieve 			byte_address = ((xor_ecc_1b >> 7) & BIT(0)) |
388*695f7df8SLionel Debieve 				       ((xor_ecc_2b) & BIT(1)) |
389*695f7df8SLionel Debieve 				       ((xor_ecc_2b >> 1) & BIT(2)) |
390*695f7df8SLionel Debieve 				       ((xor_ecc_2b >> 2) & BIT(3)) |
391*695f7df8SLionel Debieve 				       ((xor_ecc_2b >> 3) & BIT(4)) |
392*695f7df8SLionel Debieve 				       ((xor_ecc_3b << 4) & BIT(5)) |
393*695f7df8SLionel Debieve 				       ((xor_ecc_3b << 3) & BIT(6)) |
394*695f7df8SLionel Debieve 				       ((xor_ecc_3b << 2) & BIT(7)) |
395*695f7df8SLionel Debieve 				       ((xor_ecc_3b << 1) & BIT(8));
396*695f7df8SLionel Debieve 
397*695f7df8SLionel Debieve 			/* Correct bit error in the data */
398*695f7df8SLionel Debieve 			buffer[byte_address] =
399*695f7df8SLionel Debieve 				buffer[byte_address] ^ BIT(bit_address);
400*695f7df8SLionel Debieve 			VERBOSE("Hamming: 1 ECC error corrected\n");
401*695f7df8SLionel Debieve 
402*695f7df8SLionel Debieve 			return 0;
403*695f7df8SLionel Debieve 		}
404*695f7df8SLionel Debieve 
405*695f7df8SLionel Debieve 		/* Non Correctable ERROR */
406*695f7df8SLionel Debieve 		ERROR("%s: Uncorrectable ECC Errors\n", __func__);
407*695f7df8SLionel Debieve 		return -1;
408*695f7df8SLionel Debieve 	}
409*695f7df8SLionel Debieve 
410*695f7df8SLionel Debieve 	/* ECC ERROR */
411*695f7df8SLionel Debieve 	ERROR("%s: Hamming correction error\n", __func__);
412*695f7df8SLionel Debieve 	return -1;
413*695f7df8SLionel Debieve }
414*695f7df8SLionel Debieve 
415*695f7df8SLionel Debieve 
416*695f7df8SLionel Debieve static int stm32_fmc2_ham_calculate(uint8_t *buffer, uint8_t *ecc)
417*695f7df8SLionel Debieve {
418*695f7df8SLionel Debieve 	uint32_t heccr;
419*695f7df8SLionel Debieve 	uint64_t timeout = timeout_init_us(TIMEOUT_US_10_MS);
420*695f7df8SLionel Debieve 
421*695f7df8SLionel Debieve 	while ((mmio_read_32(fmc2_base() + FMC2_SR) & FMC2_SR_NWRF) == 0U) {
422*695f7df8SLionel Debieve 		if (timeout_elapsed(timeout)) {
423*695f7df8SLionel Debieve 			return -ETIMEDOUT;
424*695f7df8SLionel Debieve 		}
425*695f7df8SLionel Debieve 	}
426*695f7df8SLionel Debieve 
427*695f7df8SLionel Debieve 	heccr = mmio_read_32(fmc2_base() + FMC2_HECCR);
428*695f7df8SLionel Debieve 
429*695f7df8SLionel Debieve 	ecc[0] = heccr;
430*695f7df8SLionel Debieve 	ecc[1] = heccr >> 8;
431*695f7df8SLionel Debieve 	ecc[2] = heccr >> 16;
432*695f7df8SLionel Debieve 
433*695f7df8SLionel Debieve 	/* Disable ECC */
434*695f7df8SLionel Debieve 	stm32_fmc2_set_ecc(false);
435*695f7df8SLionel Debieve 
436*695f7df8SLionel Debieve 	return 0;
437*695f7df8SLionel Debieve }
438*695f7df8SLionel Debieve 
439*695f7df8SLionel Debieve static int stm32_fmc2_bch_correct(uint8_t *buffer, unsigned int eccsize)
440*695f7df8SLionel Debieve {
441*695f7df8SLionel Debieve 	uint32_t bchdsr0, bchdsr1, bchdsr2, bchdsr3, bchdsr4;
442*695f7df8SLionel Debieve 	uint16_t pos[8];
443*695f7df8SLionel Debieve 	int i, den;
444*695f7df8SLionel Debieve 	uint64_t timeout = timeout_init_us(TIMEOUT_US_10_MS);
445*695f7df8SLionel Debieve 
446*695f7df8SLionel Debieve 	while ((mmio_read_32(fmc2_base() + FMC2_BCHISR) &
447*695f7df8SLionel Debieve 		FMC2_BCHISR_DERF) == 0U) {
448*695f7df8SLionel Debieve 		if (timeout_elapsed(timeout)) {
449*695f7df8SLionel Debieve 			return -ETIMEDOUT;
450*695f7df8SLionel Debieve 		}
451*695f7df8SLionel Debieve 	}
452*695f7df8SLionel Debieve 
453*695f7df8SLionel Debieve 	bchdsr0 = mmio_read_32(fmc2_base() + FMC2_BCHDSR0);
454*695f7df8SLionel Debieve 	bchdsr1 = mmio_read_32(fmc2_base() + FMC2_BCHDSR1);
455*695f7df8SLionel Debieve 	bchdsr2 = mmio_read_32(fmc2_base() + FMC2_BCHDSR2);
456*695f7df8SLionel Debieve 	bchdsr3 = mmio_read_32(fmc2_base() + FMC2_BCHDSR3);
457*695f7df8SLionel Debieve 	bchdsr4 = mmio_read_32(fmc2_base() + FMC2_BCHDSR4);
458*695f7df8SLionel Debieve 
459*695f7df8SLionel Debieve 	/* Disable ECC */
460*695f7df8SLionel Debieve 	stm32_fmc2_set_ecc(false);
461*695f7df8SLionel Debieve 
462*695f7df8SLionel Debieve 	/* No error found */
463*695f7df8SLionel Debieve 	if ((bchdsr0 & FMC2_BCHDSR0_DEF) == 0U) {
464*695f7df8SLionel Debieve 		return 0;
465*695f7df8SLionel Debieve 	}
466*695f7df8SLionel Debieve 
467*695f7df8SLionel Debieve 	/* Too many errors detected */
468*695f7df8SLionel Debieve 	if ((bchdsr0 & FMC2_BCHDSR0_DUE) != 0U) {
469*695f7df8SLionel Debieve 		return -EBADMSG;
470*695f7df8SLionel Debieve 	}
471*695f7df8SLionel Debieve 
472*695f7df8SLionel Debieve 	pos[0] = bchdsr1 & FMC2_BCHDSR1_EBP1_MASK;
473*695f7df8SLionel Debieve 	pos[1] = (bchdsr1 & FMC2_BCHDSR1_EBP2_MASK) >> FMC2_BCHDSR1_EBP2_SHIFT;
474*695f7df8SLionel Debieve 	pos[2] = bchdsr2 & FMC2_BCHDSR2_EBP3_MASK;
475*695f7df8SLionel Debieve 	pos[3] = (bchdsr2 & FMC2_BCHDSR2_EBP4_MASK) >> FMC2_BCHDSR2_EBP4_SHIFT;
476*695f7df8SLionel Debieve 	pos[4] = bchdsr3 & FMC2_BCHDSR3_EBP5_MASK;
477*695f7df8SLionel Debieve 	pos[5] = (bchdsr3 & FMC2_BCHDSR3_EBP6_MASK) >> FMC2_BCHDSR3_EBP6_SHIFT;
478*695f7df8SLionel Debieve 	pos[6] = bchdsr4 & FMC2_BCHDSR4_EBP7_MASK;
479*695f7df8SLionel Debieve 	pos[7] = (bchdsr4 & FMC2_BCHDSR4_EBP8_MASK) >> FMC2_BCHDSR4_EBP8_SHIFT;
480*695f7df8SLionel Debieve 
481*695f7df8SLionel Debieve 	den = (bchdsr0 & FMC2_BCHDSR0_DEN_MASK) >> FMC2_BCHDSR0_DEN_SHIFT;
482*695f7df8SLionel Debieve 	for (i = 0; i < den; i++) {
483*695f7df8SLionel Debieve 		if (pos[i] < (eccsize * 8U)) {
484*695f7df8SLionel Debieve 			uint8_t bitmask = BIT(pos[i] % 8U);
485*695f7df8SLionel Debieve 			uint32_t offset = pos[i] / 8U;
486*695f7df8SLionel Debieve 
487*695f7df8SLionel Debieve 			*(buffer + offset) ^= bitmask;
488*695f7df8SLionel Debieve 		}
489*695f7df8SLionel Debieve 	}
490*695f7df8SLionel Debieve 
491*695f7df8SLionel Debieve 	return 0;
492*695f7df8SLionel Debieve }
493*695f7df8SLionel Debieve 
494*695f7df8SLionel Debieve static void stm32_fmc2_hwctl(struct nand_device *nand)
495*695f7df8SLionel Debieve {
496*695f7df8SLionel Debieve 	stm32_fmc2_set_ecc(false);
497*695f7df8SLionel Debieve 
498*695f7df8SLionel Debieve 	if (nand->ecc.max_bit_corr != FMC2_ECC_HAM) {
499*695f7df8SLionel Debieve 		mmio_clrbits_32(fmc2_base() + FMC2_PCR, FMC2_PCR_WEN);
500*695f7df8SLionel Debieve 	}
501*695f7df8SLionel Debieve 
502*695f7df8SLionel Debieve 	stm32_fmc2_set_ecc(true);
503*695f7df8SLionel Debieve }
504*695f7df8SLionel Debieve 
505*695f7df8SLionel Debieve static int stm32_fmc2_read_page(struct nand_device *nand,
506*695f7df8SLionel Debieve 				unsigned int page, uintptr_t buffer)
507*695f7df8SLionel Debieve {
508*695f7df8SLionel Debieve 	unsigned int eccsize = nand->ecc.size;
509*695f7df8SLionel Debieve 	unsigned int eccbytes = nand->ecc.bytes;
510*695f7df8SLionel Debieve 	unsigned int eccsteps = nand->page_size / eccsize;
511*695f7df8SLionel Debieve 	uint8_t ecc_corr[FMC2_MAX_ECC_BYTES];
512*695f7df8SLionel Debieve 	uint8_t ecc_cal[FMC2_MAX_ECC_BYTES] = {0U};
513*695f7df8SLionel Debieve 	uint8_t *p;
514*695f7df8SLionel Debieve 	unsigned int i;
515*695f7df8SLionel Debieve 	unsigned int s;
516*695f7df8SLionel Debieve 	int ret;
517*695f7df8SLionel Debieve 
518*695f7df8SLionel Debieve 	VERBOSE(">%s page %i buffer %lx\n", __func__, page, buffer);
519*695f7df8SLionel Debieve 
520*695f7df8SLionel Debieve 	ret = nand_read_page_cmd(page, 0U, 0U, 0U);
521*695f7df8SLionel Debieve 	if (ret != 0) {
522*695f7df8SLionel Debieve 		return ret;
523*695f7df8SLionel Debieve 	}
524*695f7df8SLionel Debieve 
525*695f7df8SLionel Debieve 	for (s = 0U, i = nand->page_size + FMC2_BBM_LEN, p = (uint8_t *)buffer;
526*695f7df8SLionel Debieve 	     s < eccsteps;
527*695f7df8SLionel Debieve 	     s++, i += eccbytes, p += eccsize) {
528*695f7df8SLionel Debieve 		stm32_fmc2_hwctl(nand);
529*695f7df8SLionel Debieve 
530*695f7df8SLionel Debieve 		/* Read the NAND page sector (512 bytes) */
531*695f7df8SLionel Debieve 		ret = nand_change_read_column_cmd(s * eccsize, (uintptr_t)p,
532*695f7df8SLionel Debieve 						  eccsize);
533*695f7df8SLionel Debieve 		if (ret != 0) {
534*695f7df8SLionel Debieve 			return ret;
535*695f7df8SLionel Debieve 		}
536*695f7df8SLionel Debieve 
537*695f7df8SLionel Debieve 		if (nand->ecc.max_bit_corr == FMC2_ECC_HAM) {
538*695f7df8SLionel Debieve 			ret = stm32_fmc2_ham_calculate(p, ecc_cal);
539*695f7df8SLionel Debieve 			if (ret != 0) {
540*695f7df8SLionel Debieve 				return ret;
541*695f7df8SLionel Debieve 			}
542*695f7df8SLionel Debieve 		}
543*695f7df8SLionel Debieve 
544*695f7df8SLionel Debieve 		/* Read the corresponding ECC bytes */
545*695f7df8SLionel Debieve 		ret = nand_change_read_column_cmd(i, (uintptr_t)ecc_corr,
546*695f7df8SLionel Debieve 						  eccbytes);
547*695f7df8SLionel Debieve 		if (ret != 0) {
548*695f7df8SLionel Debieve 			return ret;
549*695f7df8SLionel Debieve 		}
550*695f7df8SLionel Debieve 
551*695f7df8SLionel Debieve 		/* Correct the data */
552*695f7df8SLionel Debieve 		if (nand->ecc.max_bit_corr == FMC2_ECC_HAM) {
553*695f7df8SLionel Debieve 			ret = stm32_fmc2_ham_correct(p, ecc_corr, ecc_cal);
554*695f7df8SLionel Debieve 		} else {
555*695f7df8SLionel Debieve 			ret = stm32_fmc2_bch_correct(p, eccsize);
556*695f7df8SLionel Debieve 		}
557*695f7df8SLionel Debieve 
558*695f7df8SLionel Debieve 		if (ret != 0) {
559*695f7df8SLionel Debieve 			return ret;
560*695f7df8SLionel Debieve 		}
561*695f7df8SLionel Debieve 	}
562*695f7df8SLionel Debieve 
563*695f7df8SLionel Debieve 	return 0;
564*695f7df8SLionel Debieve }
565*695f7df8SLionel Debieve 
566*695f7df8SLionel Debieve static void stm32_fmc2_read_data(struct nand_device *nand,
567*695f7df8SLionel Debieve 				 uint8_t *buff, unsigned int length,
568*695f7df8SLionel Debieve 				 bool use_bus8)
569*695f7df8SLionel Debieve {
570*695f7df8SLionel Debieve 	uintptr_t data_base = stm32_fmc2.cs[stm32_fmc2.cs_sel].data_base;
571*695f7df8SLionel Debieve 
572*695f7df8SLionel Debieve 	if (use_bus8 && (nand->buswidth == NAND_BUS_WIDTH_16)) {
573*695f7df8SLionel Debieve 		stm32_fmc2_set_buswidth_16(false);
574*695f7df8SLionel Debieve 	}
575*695f7df8SLionel Debieve 
576*695f7df8SLionel Debieve 	if ((((uintptr_t)buff & BIT(0)) != 0U) && (length != 0U)) {
577*695f7df8SLionel Debieve 		*buff = mmio_read_8(data_base);
578*695f7df8SLionel Debieve 		buff += sizeof(uint8_t);
579*695f7df8SLionel Debieve 		length -= sizeof(uint8_t);
580*695f7df8SLionel Debieve 	}
581*695f7df8SLionel Debieve 
582*695f7df8SLionel Debieve 	if ((((uintptr_t)buff & GENMASK_32(1, 0)) != 0U) &&
583*695f7df8SLionel Debieve 	    (length >= sizeof(uint16_t))) {
584*695f7df8SLionel Debieve 		*(uint16_t *)buff = mmio_read_16(data_base);
585*695f7df8SLionel Debieve 		buff += sizeof(uint16_t);
586*695f7df8SLionel Debieve 		length -= sizeof(uint16_t);
587*695f7df8SLionel Debieve 	}
588*695f7df8SLionel Debieve 
589*695f7df8SLionel Debieve 	/* 32bit aligned */
590*695f7df8SLionel Debieve 	while (length >= sizeof(uint32_t)) {
591*695f7df8SLionel Debieve 		*(uint32_t *)buff = mmio_read_32(data_base);
592*695f7df8SLionel Debieve 		buff += sizeof(uint32_t);
593*695f7df8SLionel Debieve 		length -= sizeof(uint32_t);
594*695f7df8SLionel Debieve 	}
595*695f7df8SLionel Debieve 
596*695f7df8SLionel Debieve 	/* Read remaining bytes */
597*695f7df8SLionel Debieve 	if (length >= sizeof(uint16_t)) {
598*695f7df8SLionel Debieve 		*(uint16_t *)buff = mmio_read_16(data_base);
599*695f7df8SLionel Debieve 		buff += sizeof(uint16_t);
600*695f7df8SLionel Debieve 		length -= sizeof(uint16_t);
601*695f7df8SLionel Debieve 	}
602*695f7df8SLionel Debieve 
603*695f7df8SLionel Debieve 	if (length != 0U) {
604*695f7df8SLionel Debieve 		*buff = mmio_read_8(data_base);
605*695f7df8SLionel Debieve 	}
606*695f7df8SLionel Debieve 
607*695f7df8SLionel Debieve 	if (use_bus8 && (nand->buswidth == NAND_BUS_WIDTH_16)) {
608*695f7df8SLionel Debieve 		/* Reconfigure bus width to 16-bit */
609*695f7df8SLionel Debieve 		stm32_fmc2_set_buswidth_16(true);
610*695f7df8SLionel Debieve 	}
611*695f7df8SLionel Debieve }
612*695f7df8SLionel Debieve 
613*695f7df8SLionel Debieve static void stm32_fmc2_write_data(struct nand_device *nand,
614*695f7df8SLionel Debieve 				  uint8_t *buff, unsigned int length,
615*695f7df8SLionel Debieve 				  bool use_bus8)
616*695f7df8SLionel Debieve {
617*695f7df8SLionel Debieve 	uintptr_t data_base = stm32_fmc2.cs[stm32_fmc2.cs_sel].data_base;
618*695f7df8SLionel Debieve 
619*695f7df8SLionel Debieve 	if (use_bus8 && (nand->buswidth == NAND_BUS_WIDTH_16)) {
620*695f7df8SLionel Debieve 		/* Reconfigure bus width to 8-bit */
621*695f7df8SLionel Debieve 		stm32_fmc2_set_buswidth_16(false);
622*695f7df8SLionel Debieve 	}
623*695f7df8SLionel Debieve 
624*695f7df8SLionel Debieve 	if ((((uintptr_t)buff & BIT(0)) != 0U) && (length != 0U)) {
625*695f7df8SLionel Debieve 		mmio_write_8(data_base, *buff);
626*695f7df8SLionel Debieve 		buff += sizeof(uint8_t);
627*695f7df8SLionel Debieve 		length -= sizeof(uint8_t);
628*695f7df8SLionel Debieve 	}
629*695f7df8SLionel Debieve 
630*695f7df8SLionel Debieve 	if ((((uintptr_t)buff & GENMASK_32(1, 0)) != 0U) &&
631*695f7df8SLionel Debieve 	    (length >= sizeof(uint16_t))) {
632*695f7df8SLionel Debieve 		mmio_write_16(data_base, *(uint16_t *)buff);
633*695f7df8SLionel Debieve 		buff += sizeof(uint16_t);
634*695f7df8SLionel Debieve 		length -= sizeof(uint16_t);
635*695f7df8SLionel Debieve 	}
636*695f7df8SLionel Debieve 
637*695f7df8SLionel Debieve 	/* 32bits aligned */
638*695f7df8SLionel Debieve 	while (length >= sizeof(uint32_t)) {
639*695f7df8SLionel Debieve 		mmio_write_32(data_base, *(uint32_t *)buff);
640*695f7df8SLionel Debieve 		buff += sizeof(uint32_t);
641*695f7df8SLionel Debieve 		length -= sizeof(uint32_t);
642*695f7df8SLionel Debieve 	}
643*695f7df8SLionel Debieve 
644*695f7df8SLionel Debieve 	/* Read remaining bytes */
645*695f7df8SLionel Debieve 	if (length >= sizeof(uint16_t)) {
646*695f7df8SLionel Debieve 		mmio_write_16(data_base, *(uint16_t *)buff);
647*695f7df8SLionel Debieve 		buff += sizeof(uint16_t);
648*695f7df8SLionel Debieve 		length -= sizeof(uint16_t);
649*695f7df8SLionel Debieve 	}
650*695f7df8SLionel Debieve 
651*695f7df8SLionel Debieve 	if (length != 0U) {
652*695f7df8SLionel Debieve 		mmio_write_8(data_base, *buff);
653*695f7df8SLionel Debieve 	}
654*695f7df8SLionel Debieve 
655*695f7df8SLionel Debieve 	if (use_bus8 && (nand->buswidth == NAND_BUS_WIDTH_16)) {
656*695f7df8SLionel Debieve 		/* Reconfigure bus width to 16-bit */
657*695f7df8SLionel Debieve 		stm32_fmc2_set_buswidth_16(true);
658*695f7df8SLionel Debieve 	}
659*695f7df8SLionel Debieve }
660*695f7df8SLionel Debieve 
661*695f7df8SLionel Debieve static void stm32_fmc2_ctrl_init(void)
662*695f7df8SLionel Debieve {
663*695f7df8SLionel Debieve 	uint32_t pcr = mmio_read_32(fmc2_base() + FMC2_PCR);
664*695f7df8SLionel Debieve 	uint32_t bcr1 = mmio_read_32(fmc2_base() + FMC2_BCR1);
665*695f7df8SLionel Debieve 
666*695f7df8SLionel Debieve 	/* Enable wait feature and NAND flash memory bank */
667*695f7df8SLionel Debieve 	pcr |= FMC2_PCR_PWAITEN;
668*695f7df8SLionel Debieve 	pcr |= FMC2_PCR_PBKEN;
669*695f7df8SLionel Debieve 
670*695f7df8SLionel Debieve 	/* Set buswidth to 8 bits mode for identification */
671*695f7df8SLionel Debieve 	pcr &= ~FMC2_PCR_PWID_MASK;
672*695f7df8SLionel Debieve 
673*695f7df8SLionel Debieve 	/* ECC logic is disabled */
674*695f7df8SLionel Debieve 	pcr &= ~FMC2_PCR_ECCEN;
675*695f7df8SLionel Debieve 
676*695f7df8SLionel Debieve 	/* Default mode */
677*695f7df8SLionel Debieve 	pcr &= ~FMC2_PCR_ECCALG;
678*695f7df8SLionel Debieve 	pcr &= ~FMC2_PCR_BCHECC;
679*695f7df8SLionel Debieve 	pcr &= ~FMC2_PCR_WEN;
680*695f7df8SLionel Debieve 
681*695f7df8SLionel Debieve 	/* Set default ECC sector size */
682*695f7df8SLionel Debieve 	pcr &= ~FMC2_PCR_ECCSS_MASK;
683*695f7df8SLionel Debieve 	pcr |= FMC2_PCR_ECCSS(FMC2_PCR_ECCSS_2048);
684*695f7df8SLionel Debieve 
685*695f7df8SLionel Debieve 	/* Set default TCLR/TAR timings */
686*695f7df8SLionel Debieve 	pcr &= ~FMC2_PCR_TCLR_MASK;
687*695f7df8SLionel Debieve 	pcr |= FMC2_PCR_TCLR(FMC2_PCR_TCLR_DEFAULT);
688*695f7df8SLionel Debieve 	pcr &= ~FMC2_PCR_TAR_MASK;
689*695f7df8SLionel Debieve 	pcr |= FMC2_PCR_TAR(FMC2_PCR_TAR_DEFAULT);
690*695f7df8SLionel Debieve 
691*695f7df8SLionel Debieve 	/* Enable FMC2 controller */
692*695f7df8SLionel Debieve 	bcr1 |= FMC2_BCR1_FMC2EN;
693*695f7df8SLionel Debieve 
694*695f7df8SLionel Debieve 	mmio_write_32(fmc2_base() + FMC2_BCR1, bcr1);
695*695f7df8SLionel Debieve 	mmio_write_32(fmc2_base() + FMC2_PCR, pcr);
696*695f7df8SLionel Debieve 	mmio_write_32(fmc2_base() + FMC2_PMEM, FMC2_PMEM_DEFAULT);
697*695f7df8SLionel Debieve 	mmio_write_32(fmc2_base() + FMC2_PATT, FMC2_PATT_DEFAULT);
698*695f7df8SLionel Debieve }
699*695f7df8SLionel Debieve 
700*695f7df8SLionel Debieve static int stm32_fmc2_exec(struct nand_req *req)
701*695f7df8SLionel Debieve {
702*695f7df8SLionel Debieve 	int ret = 0;
703*695f7df8SLionel Debieve 
704*695f7df8SLionel Debieve 	switch (req->type & NAND_REQ_MASK) {
705*695f7df8SLionel Debieve 	case NAND_REQ_CMD:
706*695f7df8SLionel Debieve 		VERBOSE("Write CMD %x\n", (uint8_t)req->type);
707*695f7df8SLionel Debieve 		mmio_write_8(stm32_fmc2.cs[stm32_fmc2.cs_sel].cmd_base,
708*695f7df8SLionel Debieve 			     (uint8_t)req->type);
709*695f7df8SLionel Debieve 		break;
710*695f7df8SLionel Debieve 	case NAND_REQ_ADDR:
711*695f7df8SLionel Debieve 		VERBOSE("Write ADDR %x\n", *(req->addr));
712*695f7df8SLionel Debieve 		mmio_write_8(stm32_fmc2.cs[stm32_fmc2.cs_sel].addr_base,
713*695f7df8SLionel Debieve 			     *(req->addr));
714*695f7df8SLionel Debieve 		break;
715*695f7df8SLionel Debieve 	case NAND_REQ_DATAIN:
716*695f7df8SLionel Debieve 		VERBOSE("Read data\n");
717*695f7df8SLionel Debieve 		stm32_fmc2_read_data(req->nand, req->addr, req->length,
718*695f7df8SLionel Debieve 				     ((req->type & NAND_REQ_BUS_WIDTH_8) !=
719*695f7df8SLionel Debieve 				      0U));
720*695f7df8SLionel Debieve 		break;
721*695f7df8SLionel Debieve 	case NAND_REQ_DATAOUT:
722*695f7df8SLionel Debieve 		VERBOSE("Write data\n");
723*695f7df8SLionel Debieve 		stm32_fmc2_write_data(req->nand, req->addr, req->length,
724*695f7df8SLionel Debieve 				      ((req->type & NAND_REQ_BUS_WIDTH_8) !=
725*695f7df8SLionel Debieve 				      0U));
726*695f7df8SLionel Debieve 		break;
727*695f7df8SLionel Debieve 	case NAND_REQ_WAIT:
728*695f7df8SLionel Debieve 		VERBOSE("WAIT Ready\n");
729*695f7df8SLionel Debieve 		ret = nand_wait_ready(req->delay_ms);
730*695f7df8SLionel Debieve 		break;
731*695f7df8SLionel Debieve 	default:
732*695f7df8SLionel Debieve 		ret = -EINVAL;
733*695f7df8SLionel Debieve 		break;
734*695f7df8SLionel Debieve 	};
735*695f7df8SLionel Debieve 
736*695f7df8SLionel Debieve 	return ret;
737*695f7df8SLionel Debieve }
738*695f7df8SLionel Debieve 
739*695f7df8SLionel Debieve static void stm32_fmc2_setup(struct nand_device *nand)
740*695f7df8SLionel Debieve {
741*695f7df8SLionel Debieve 	uint32_t pcr = mmio_read_32(fmc2_base() + FMC2_PCR);
742*695f7df8SLionel Debieve 
743*695f7df8SLionel Debieve 	/* Set buswidth */
744*695f7df8SLionel Debieve 	pcr &= ~FMC2_PCR_PWID_MASK;
745*695f7df8SLionel Debieve 	if (nand->buswidth == NAND_BUS_WIDTH_16) {
746*695f7df8SLionel Debieve 		pcr |= FMC2_PCR_PWID(FMC2_PCR_PWID_16);
747*695f7df8SLionel Debieve 	}
748*695f7df8SLionel Debieve 
749*695f7df8SLionel Debieve 	if (nand->ecc.mode == NAND_ECC_HW) {
750*695f7df8SLionel Debieve 		nand->mtd_read_page = stm32_fmc2_read_page;
751*695f7df8SLionel Debieve 
752*695f7df8SLionel Debieve 		pcr &= ~FMC2_PCR_ECCALG;
753*695f7df8SLionel Debieve 		pcr &= ~FMC2_PCR_BCHECC;
754*695f7df8SLionel Debieve 
755*695f7df8SLionel Debieve 		pcr &= ~FMC2_PCR_ECCSS_MASK;
756*695f7df8SLionel Debieve 		pcr |= FMC2_PCR_ECCSS(FMC2_PCR_ECCSS_512);
757*695f7df8SLionel Debieve 
758*695f7df8SLionel Debieve 		switch (nand->ecc.max_bit_corr) {
759*695f7df8SLionel Debieve 		case FMC2_ECC_HAM:
760*695f7df8SLionel Debieve 			nand->ecc.bytes = 3;
761*695f7df8SLionel Debieve 			break;
762*695f7df8SLionel Debieve 		case FMC2_ECC_BCH8:
763*695f7df8SLionel Debieve 			pcr |= FMC2_PCR_ECCALG;
764*695f7df8SLionel Debieve 			pcr |= FMC2_PCR_BCHECC;
765*695f7df8SLionel Debieve 			nand->ecc.bytes = 13;
766*695f7df8SLionel Debieve 			break;
767*695f7df8SLionel Debieve 		default:
768*695f7df8SLionel Debieve 			/* Use FMC2 ECC BCH4 */
769*695f7df8SLionel Debieve 			pcr |= FMC2_PCR_ECCALG;
770*695f7df8SLionel Debieve 			nand->ecc.bytes = 7;
771*695f7df8SLionel Debieve 			break;
772*695f7df8SLionel Debieve 		}
773*695f7df8SLionel Debieve 
774*695f7df8SLionel Debieve 		if ((nand->buswidth & NAND_BUS_WIDTH_16) != 0) {
775*695f7df8SLionel Debieve 			nand->ecc.bytes++;
776*695f7df8SLionel Debieve 		}
777*695f7df8SLionel Debieve 	}
778*695f7df8SLionel Debieve 
779*695f7df8SLionel Debieve 	mmio_write_32(stm32_fmc2.reg_base + FMC2_PCR, pcr);
780*695f7df8SLionel Debieve }
781*695f7df8SLionel Debieve 
782*695f7df8SLionel Debieve static const struct nand_ctrl_ops ctrl_ops = {
783*695f7df8SLionel Debieve 	.setup = stm32_fmc2_setup,
784*695f7df8SLionel Debieve 	.exec = stm32_fmc2_exec
785*695f7df8SLionel Debieve };
786*695f7df8SLionel Debieve 
787*695f7df8SLionel Debieve int stm32_fmc2_init(void)
788*695f7df8SLionel Debieve {
789*695f7df8SLionel Debieve 	int fmc_node;
790*695f7df8SLionel Debieve 	int fmc_subnode = 0;
791*695f7df8SLionel Debieve 	int nchips = 0;
792*695f7df8SLionel Debieve 	unsigned int i;
793*695f7df8SLionel Debieve 	void *fdt = NULL;
794*695f7df8SLionel Debieve 	const fdt32_t *cuint;
795*695f7df8SLionel Debieve 	struct dt_node_info info;
796*695f7df8SLionel Debieve 
797*695f7df8SLionel Debieve 	if (fdt_get_address(&fdt) == 0) {
798*695f7df8SLionel Debieve 		return -FDT_ERR_NOTFOUND;
799*695f7df8SLionel Debieve 	}
800*695f7df8SLionel Debieve 
801*695f7df8SLionel Debieve 	fmc_node = dt_get_node(&info, -1, DT_FMC2_COMPAT);
802*695f7df8SLionel Debieve 	if (fmc_node == -FDT_ERR_NOTFOUND) {
803*695f7df8SLionel Debieve 		WARN("No FMC2 node found\n");
804*695f7df8SLionel Debieve 		return fmc_node;
805*695f7df8SLionel Debieve 	}
806*695f7df8SLionel Debieve 
807*695f7df8SLionel Debieve 	if (info.status == DT_DISABLED) {
808*695f7df8SLionel Debieve 		return -FDT_ERR_NOTFOUND;
809*695f7df8SLionel Debieve 	}
810*695f7df8SLionel Debieve 
811*695f7df8SLionel Debieve 	stm32_fmc2.reg_base = info.base;
812*695f7df8SLionel Debieve 
813*695f7df8SLionel Debieve 	if ((info.clock < 0) || (info.reset < 0)) {
814*695f7df8SLionel Debieve 		return -FDT_ERR_BADVALUE;
815*695f7df8SLionel Debieve 	}
816*695f7df8SLionel Debieve 
817*695f7df8SLionel Debieve 	stm32_fmc2.clock_id = (unsigned long)info.clock;
818*695f7df8SLionel Debieve 	stm32_fmc2.reset_id = (unsigned int)info.reset;
819*695f7df8SLionel Debieve 
820*695f7df8SLionel Debieve 	cuint = fdt_getprop(fdt, fmc_node, "reg", NULL);
821*695f7df8SLionel Debieve 	if (cuint == NULL) {
822*695f7df8SLionel Debieve 		return -FDT_ERR_BADVALUE;
823*695f7df8SLionel Debieve 	}
824*695f7df8SLionel Debieve 
825*695f7df8SLionel Debieve 	cuint += 2;
826*695f7df8SLionel Debieve 
827*695f7df8SLionel Debieve 	for (i = 0U; i < MAX_CS; i++) {
828*695f7df8SLionel Debieve 		stm32_fmc2.cs[i].data_base = fdt32_to_cpu(*cuint);
829*695f7df8SLionel Debieve 		stm32_fmc2.cs[i].cmd_base = fdt32_to_cpu(*(cuint + 2));
830*695f7df8SLionel Debieve 		stm32_fmc2.cs[i].addr_base = fdt32_to_cpu(*(cuint + 4));
831*695f7df8SLionel Debieve 		cuint += 6;
832*695f7df8SLionel Debieve 	}
833*695f7df8SLionel Debieve 
834*695f7df8SLionel Debieve 	/* Pinctrl initialization */
835*695f7df8SLionel Debieve 	if (dt_set_pinctrl_config(fmc_node) != 0) {
836*695f7df8SLionel Debieve 		return -FDT_ERR_BADVALUE;
837*695f7df8SLionel Debieve 	}
838*695f7df8SLionel Debieve 
839*695f7df8SLionel Debieve 	/* Parse flash nodes */
840*695f7df8SLionel Debieve 	fdt_for_each_subnode(fmc_subnode, fdt, fmc_node) {
841*695f7df8SLionel Debieve 		nchips++;
842*695f7df8SLionel Debieve 	}
843*695f7df8SLionel Debieve 
844*695f7df8SLionel Debieve 	if (nchips != 1) {
845*695f7df8SLionel Debieve 		WARN("Only one SLC NAND device supported\n");
846*695f7df8SLionel Debieve 		return -FDT_ERR_BADVALUE;
847*695f7df8SLionel Debieve 	}
848*695f7df8SLionel Debieve 
849*695f7df8SLionel Debieve 	fdt_for_each_subnode(fmc_subnode, fdt, fmc_node) {
850*695f7df8SLionel Debieve 		/* Get chip select */
851*695f7df8SLionel Debieve 		cuint = fdt_getprop(fdt, fmc_subnode, "reg", NULL);
852*695f7df8SLionel Debieve 		if (cuint == NULL) {
853*695f7df8SLionel Debieve 			WARN("Chip select not well defined\n");
854*695f7df8SLionel Debieve 			return -FDT_ERR_BADVALUE;
855*695f7df8SLionel Debieve 		}
856*695f7df8SLionel Debieve 		stm32_fmc2.cs_sel = fdt32_to_cpu(*cuint);
857*695f7df8SLionel Debieve 		VERBOSE("NAND CS %i\n", stm32_fmc2.cs_sel);
858*695f7df8SLionel Debieve 	}
859*695f7df8SLionel Debieve 
860*695f7df8SLionel Debieve 	/* Enable Clock */
861*695f7df8SLionel Debieve 	stm32mp_clk_enable(stm32_fmc2.clock_id);
862*695f7df8SLionel Debieve 
863*695f7df8SLionel Debieve 	/* Reset IP */
864*695f7df8SLionel Debieve 	stm32mp_reset_assert(stm32_fmc2.reset_id);
865*695f7df8SLionel Debieve 	stm32mp_reset_deassert(stm32_fmc2.reset_id);
866*695f7df8SLionel Debieve 
867*695f7df8SLionel Debieve 	/* Setup default IP registers */
868*695f7df8SLionel Debieve 	stm32_fmc2_ctrl_init();
869*695f7df8SLionel Debieve 
870*695f7df8SLionel Debieve 	/* Setup default timings */
871*695f7df8SLionel Debieve 	stm32_fmc2_nand_setup_timing();
872*695f7df8SLionel Debieve 
873*695f7df8SLionel Debieve 	/* Init NAND RAW framework */
874*695f7df8SLionel Debieve 	nand_raw_ctrl_init(&ctrl_ops);
875*695f7df8SLionel Debieve 
876*695f7df8SLionel Debieve 	return 0;
877*695f7df8SLionel Debieve }
878