blob: c7db16463e892007c2b3041d315c9d35cdf29673 [file] [log] [blame]
Christophe Kerelloa994a802020-07-31 09:53:40 +02001// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
2/*
3 * Copyright (C) STMicroelectronics 2020
4 */
5
Patrick Delaunay729ecfd2020-11-06 19:01:55 +01006#define LOG_CATEGORY UCLASS_NOP
7
Christophe Kerelloa994a802020-07-31 09:53:40 +02008#include <common.h>
9#include <clk.h>
10#include <dm.h>
11#include <reset.h>
Patrick Delaunay729ecfd2020-11-06 19:01:55 +010012#include <dm/device_compat.h>
Christophe Kerelloa994a802020-07-31 09:53:40 +020013#include <linux/bitfield.h>
14#include <linux/err.h>
15#include <linux/iopoll.h>
16#include <linux/ioport.h>
Igor Prusovc3421ea2023-11-09 20:10:04 +030017#include <linux/time.h>
Christophe Kerelloa994a802020-07-31 09:53:40 +020018
19/* FMC2 Controller Registers */
20#define FMC2_BCR1 0x0
21#define FMC2_BTR1 0x4
22#define FMC2_BCR(x) ((x) * 0x8 + FMC2_BCR1)
23#define FMC2_BTR(x) ((x) * 0x8 + FMC2_BTR1)
24#define FMC2_PCSCNTR 0x20
Christophe Kerello34af8b82024-03-06 10:50:46 +010025#define FMC2_CFGR 0x20
Christophe Kerelloa994a802020-07-31 09:53:40 +020026#define FMC2_BWTR1 0x104
27#define FMC2_BWTR(x) ((x) * 0x8 + FMC2_BWTR1)
28
29/* Register: FMC2_BCR1 */
30#define FMC2_BCR1_CCLKEN BIT(20)
31#define FMC2_BCR1_FMC2EN BIT(31)
32
33/* Register: FMC2_BCRx */
34#define FMC2_BCR_MBKEN BIT(0)
35#define FMC2_BCR_MUXEN BIT(1)
36#define FMC2_BCR_MTYP GENMASK(3, 2)
37#define FMC2_BCR_MWID GENMASK(5, 4)
38#define FMC2_BCR_FACCEN BIT(6)
39#define FMC2_BCR_BURSTEN BIT(8)
40#define FMC2_BCR_WAITPOL BIT(9)
41#define FMC2_BCR_WAITCFG BIT(11)
42#define FMC2_BCR_WREN BIT(12)
43#define FMC2_BCR_WAITEN BIT(13)
44#define FMC2_BCR_EXTMOD BIT(14)
45#define FMC2_BCR_ASYNCWAIT BIT(15)
46#define FMC2_BCR_CPSIZE GENMASK(18, 16)
47#define FMC2_BCR_CBURSTRW BIT(19)
Christophe Kerello34af8b82024-03-06 10:50:46 +010048#define FMC2_BCR_CSCOUNT GENMASK(21, 20)
Christophe Kerelloa994a802020-07-31 09:53:40 +020049#define FMC2_BCR_NBLSET GENMASK(23, 22)
50
51/* Register: FMC2_BTRx/FMC2_BWTRx */
52#define FMC2_BXTR_ADDSET GENMASK(3, 0)
53#define FMC2_BXTR_ADDHLD GENMASK(7, 4)
54#define FMC2_BXTR_DATAST GENMASK(15, 8)
55#define FMC2_BXTR_BUSTURN GENMASK(19, 16)
56#define FMC2_BTR_CLKDIV GENMASK(23, 20)
57#define FMC2_BTR_DATLAT GENMASK(27, 24)
58#define FMC2_BXTR_ACCMOD GENMASK(29, 28)
59#define FMC2_BXTR_DATAHLD GENMASK(31, 30)
60
61/* Register: FMC2_PCSCNTR */
62#define FMC2_PCSCNTR_CSCOUNT GENMASK(15, 0)
63#define FMC2_PCSCNTR_CNTBEN(x) BIT((x) + 16)
64
Christophe Kerello34af8b82024-03-06 10:50:46 +010065/* Register: FMC2_CFGR */
66#define FMC2_CFGR_CLKDIV GENMASK(19, 16)
67#define FMC2_CFGR_CCLKEN BIT(20)
68#define FMC2_CFGR_FMC2EN BIT(31)
69
Christophe Kerelloa994a802020-07-31 09:53:40 +020070#define FMC2_MAX_EBI_CE 4
71#define FMC2_MAX_BANKS 5
72
73#define FMC2_BCR_CPSIZE_0 0x0
74#define FMC2_BCR_CPSIZE_128 0x1
75#define FMC2_BCR_CPSIZE_256 0x2
76#define FMC2_BCR_CPSIZE_512 0x3
77#define FMC2_BCR_CPSIZE_1024 0x4
78
79#define FMC2_BCR_MWID_8 0x0
80#define FMC2_BCR_MWID_16 0x1
81
82#define FMC2_BCR_MTYP_SRAM 0x0
83#define FMC2_BCR_MTYP_PSRAM 0x1
84#define FMC2_BCR_MTYP_NOR 0x2
85
Christophe Kerello34af8b82024-03-06 10:50:46 +010086#define FMC2_BCR_CSCOUNT_0 0x0
87#define FMC2_BCR_CSCOUNT_1 0x1
88#define FMC2_BCR_CSCOUNT_64 0x2
89#define FMC2_BCR_CSCOUNT_256 0x3
90
Christophe Kerelloa994a802020-07-31 09:53:40 +020091#define FMC2_BXTR_EXTMOD_A 0x0
92#define FMC2_BXTR_EXTMOD_B 0x1
93#define FMC2_BXTR_EXTMOD_C 0x2
94#define FMC2_BXTR_EXTMOD_D 0x3
95
96#define FMC2_BCR_NBLSET_MAX 0x3
97#define FMC2_BXTR_ADDSET_MAX 0xf
98#define FMC2_BXTR_ADDHLD_MAX 0xf
99#define FMC2_BXTR_DATAST_MAX 0xff
100#define FMC2_BXTR_BUSTURN_MAX 0xf
101#define FMC2_BXTR_DATAHLD_MAX 0x3
102#define FMC2_BTR_CLKDIV_MAX 0xf
103#define FMC2_BTR_DATLAT_MAX 0xf
104#define FMC2_PCSCNTR_CSCOUNT_MAX 0xff
Christophe Kerello34af8b82024-03-06 10:50:46 +0100105#define FMC2_CFGR_CLKDIV_MAX 0xf
Christophe Kerelloa994a802020-07-31 09:53:40 +0200106
Christophe Kerelloa994a802020-07-31 09:53:40 +0200107enum stm32_fmc2_ebi_bank {
108 FMC2_EBI1 = 0,
109 FMC2_EBI2,
110 FMC2_EBI3,
111 FMC2_EBI4,
112 FMC2_NAND
113};
114
115enum stm32_fmc2_ebi_register_type {
116 FMC2_REG_BCR = 1,
117 FMC2_REG_BTR,
118 FMC2_REG_BWTR,
Christophe Kerello34af8b82024-03-06 10:50:46 +0100119 FMC2_REG_PCSCNTR,
120 FMC2_REG_CFGR
Christophe Kerelloa994a802020-07-31 09:53:40 +0200121};
122
123enum stm32_fmc2_ebi_transaction_type {
124 FMC2_ASYNC_MODE_1_SRAM = 0,
125 FMC2_ASYNC_MODE_1_PSRAM,
126 FMC2_ASYNC_MODE_A_SRAM,
127 FMC2_ASYNC_MODE_A_PSRAM,
128 FMC2_ASYNC_MODE_2_NOR,
129 FMC2_ASYNC_MODE_B_NOR,
130 FMC2_ASYNC_MODE_C_NOR,
131 FMC2_ASYNC_MODE_D_NOR,
132 FMC2_SYNC_READ_SYNC_WRITE_PSRAM,
133 FMC2_SYNC_READ_ASYNC_WRITE_PSRAM,
134 FMC2_SYNC_READ_SYNC_WRITE_NOR,
135 FMC2_SYNC_READ_ASYNC_WRITE_NOR
136};
137
138enum stm32_fmc2_ebi_buswidth {
139 FMC2_BUSWIDTH_8 = 8,
140 FMC2_BUSWIDTH_16 = 16
141};
142
143enum stm32_fmc2_ebi_cpsize {
144 FMC2_CPSIZE_0 = 0,
145 FMC2_CPSIZE_128 = 128,
146 FMC2_CPSIZE_256 = 256,
147 FMC2_CPSIZE_512 = 512,
148 FMC2_CPSIZE_1024 = 1024
149};
150
Christophe Kerello34af8b82024-03-06 10:50:46 +0100151enum stm32_fmc2_ebi_cscount {
152 FMC2_CSCOUNT_0 = 0,
153 FMC2_CSCOUNT_1 = 1,
154 FMC2_CSCOUNT_64 = 64,
155 FMC2_CSCOUNT_256 = 256
156};
157
158struct stm32_fmc2_ebi;
159
160struct stm32_fmc2_ebi_data {
161 const struct stm32_fmc2_prop *child_props;
162 unsigned int nb_child_props;
163 u32 fmc2_enable_reg;
164 u32 fmc2_enable_bit;
165 int (*nwait_used_by_ctrls)(struct stm32_fmc2_ebi *ebi);
166};
167
Christophe Kerelloa994a802020-07-31 09:53:40 +0200168struct stm32_fmc2_ebi {
169 struct clk clk;
170 fdt_addr_t io_base;
Christophe Kerello34af8b82024-03-06 10:50:46 +0100171 const struct stm32_fmc2_ebi_data *data;
Christophe Kerelloa994a802020-07-31 09:53:40 +0200172 u8 bank_assigned;
173};
174
175/*
176 * struct stm32_fmc2_prop - STM32 FMC2 EBI property
177 * @name: the device tree binding name of the property
178 * @bprop: indicate that it is a boolean property
179 * @mprop: indicate that it is a mandatory property
180 * @reg_type: the register that have to be modified
181 * @reg_mask: the bit that have to be modified in the selected register
182 * in case of it is a boolean property
183 * @reset_val: the default value that have to be set in case the property
184 * has not been defined in the device tree
185 * @check: this callback ckecks that the property is compliant with the
186 * transaction type selected
187 * @calculate: this callback is called to calculate for exemple a timing
188 * set in nanoseconds in the device tree in clock cycles or in
189 * clock period
190 * @set: this callback applies the values in the registers
191 */
192struct stm32_fmc2_prop {
193 const char *name;
194 bool bprop;
195 bool mprop;
196 int reg_type;
197 u32 reg_mask;
198 u32 reset_val;
199 int (*check)(struct stm32_fmc2_ebi *ebi,
200 const struct stm32_fmc2_prop *prop, int cs);
201 u32 (*calculate)(struct stm32_fmc2_ebi *ebi, int cs, u32 setup);
202 int (*set)(struct stm32_fmc2_ebi *ebi,
203 const struct stm32_fmc2_prop *prop,
204 int cs, u32 setup);
205};
206
207static int stm32_fmc2_ebi_check_mux(struct stm32_fmc2_ebi *ebi,
208 const struct stm32_fmc2_prop *prop,
209 int cs)
210{
211 u32 bcr = readl(ebi->io_base + FMC2_BCR(cs));
212
213 if (bcr & FMC2_BCR_MTYP)
214 return 0;
215
216 return -EINVAL;
217}
218
219static int stm32_fmc2_ebi_check_waitcfg(struct stm32_fmc2_ebi *ebi,
220 const struct stm32_fmc2_prop *prop,
221 int cs)
222{
223 u32 bcr = readl(ebi->io_base + FMC2_BCR(cs));
224 u32 val = FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);
225
226 if ((bcr & FMC2_BCR_MTYP) == val && bcr & FMC2_BCR_BURSTEN)
227 return 0;
228
229 return -EINVAL;
230}
231
232static int stm32_fmc2_ebi_check_sync_trans(struct stm32_fmc2_ebi *ebi,
233 const struct stm32_fmc2_prop *prop,
234 int cs)
235{
236 u32 bcr = readl(ebi->io_base + FMC2_BCR(cs));
237
238 if (bcr & FMC2_BCR_BURSTEN)
239 return 0;
240
241 return -EINVAL;
242}
243
244static int stm32_fmc2_ebi_check_async_trans(struct stm32_fmc2_ebi *ebi,
245 const struct stm32_fmc2_prop *prop,
246 int cs)
247{
248 u32 bcr = readl(ebi->io_base + FMC2_BCR(cs));
249
250 if (!(bcr & FMC2_BCR_BURSTEN) || !(bcr & FMC2_BCR_CBURSTRW))
251 return 0;
252
253 return -EINVAL;
254}
255
256static int stm32_fmc2_ebi_check_cpsize(struct stm32_fmc2_ebi *ebi,
257 const struct stm32_fmc2_prop *prop,
258 int cs)
259{
260 u32 bcr = readl(ebi->io_base + FMC2_BCR(cs));
261 u32 val = FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM);
262
263 if ((bcr & FMC2_BCR_MTYP) == val && bcr & FMC2_BCR_BURSTEN)
264 return 0;
265
266 return -EINVAL;
267}
268
269static int stm32_fmc2_ebi_check_address_hold(struct stm32_fmc2_ebi *ebi,
270 const struct stm32_fmc2_prop *prop,
271 int cs)
272{
273 u32 bcr = readl(ebi->io_base + FMC2_BCR(cs));
274 u32 bxtr = prop->reg_type == FMC2_REG_BWTR ?
275 readl(ebi->io_base + FMC2_BWTR(cs)) :
276 readl(ebi->io_base + FMC2_BTR(cs));
277 u32 val = FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D);
278
279 if ((!(bcr & FMC2_BCR_BURSTEN) || !(bcr & FMC2_BCR_CBURSTRW)) &&
280 ((bxtr & FMC2_BXTR_ACCMOD) == val || bcr & FMC2_BCR_MUXEN))
281 return 0;
282
283 return -EINVAL;
284}
285
286static int stm32_fmc2_ebi_check_clk_period(struct stm32_fmc2_ebi *ebi,
287 const struct stm32_fmc2_prop *prop,
288 int cs)
289{
290 u32 bcr = readl(ebi->io_base + FMC2_BCR(cs));
291 u32 bcr1 = cs ? readl(ebi->io_base + FMC2_BCR1) : bcr;
292
293 if (bcr & FMC2_BCR_BURSTEN && (!cs || !(bcr1 & FMC2_BCR1_CCLKEN)))
294 return 0;
295
296 return -EINVAL;
297}
298
299static int stm32_fmc2_ebi_check_cclk(struct stm32_fmc2_ebi *ebi,
300 const struct stm32_fmc2_prop *prop,
301 int cs)
302{
303 if (cs)
304 return -EINVAL;
305
306 return stm32_fmc2_ebi_check_sync_trans(ebi, prop, cs);
307}
308
309static u32 stm32_fmc2_ebi_ns_to_clock_cycles(struct stm32_fmc2_ebi *ebi,
310 int cs, u32 setup)
311{
312 unsigned long hclk = clk_get_rate(&ebi->clk);
Igor Prusovc3421ea2023-11-09 20:10:04 +0300313 unsigned long hclkp = NSEC_PER_SEC / (hclk / 1000);
Christophe Kerelloa994a802020-07-31 09:53:40 +0200314
315 return DIV_ROUND_UP(setup * 1000, hclkp);
316}
317
318static u32 stm32_fmc2_ebi_ns_to_clk_period(struct stm32_fmc2_ebi *ebi,
319 int cs, u32 setup)
320{
321 u32 nb_clk_cycles = stm32_fmc2_ebi_ns_to_clock_cycles(ebi, cs, setup);
322 u32 bcr = readl(ebi->io_base + FMC2_BCR1);
323 u32 btr = bcr & FMC2_BCR1_CCLKEN || !cs ?
324 readl(ebi->io_base + FMC2_BTR1) :
325 readl(ebi->io_base + FMC2_BTR(cs));
326 u32 clk_period = FIELD_GET(FMC2_BTR_CLKDIV, btr) + 1;
327
328 return DIV_ROUND_UP(nb_clk_cycles, clk_period);
329}
330
Christophe Kerello34af8b82024-03-06 10:50:46 +0100331static u32 stm32_fmc2_ebi_mp25_ns_to_clk_period(struct stm32_fmc2_ebi *ebi,
332 int cs, u32 setup)
333{
334 u32 nb_clk_cycles = stm32_fmc2_ebi_ns_to_clock_cycles(ebi, cs, setup);
335 u32 cfgr = readl(ebi->io_base + FMC2_CFGR);
336 u32 clk_period;
337
338 if (cfgr & FMC2_CFGR_CCLKEN) {
339 clk_period = FIELD_GET(FMC2_CFGR_CLKDIV, cfgr) + 1;
340 } else {
341 u32 btr = readl(ebi->io_base + FMC2_BTR(cs));
342
343 clk_period = FIELD_GET(FMC2_BTR_CLKDIV, btr) + 1;
344 }
345
346 return DIV_ROUND_UP(nb_clk_cycles, clk_period);
347}
348
Christophe Kerelloa994a802020-07-31 09:53:40 +0200349static int stm32_fmc2_ebi_get_reg(int reg_type, int cs, u32 *reg)
350{
351 switch (reg_type) {
352 case FMC2_REG_BCR:
353 *reg = FMC2_BCR(cs);
354 break;
355 case FMC2_REG_BTR:
356 *reg = FMC2_BTR(cs);
357 break;
358 case FMC2_REG_BWTR:
359 *reg = FMC2_BWTR(cs);
360 break;
361 case FMC2_REG_PCSCNTR:
362 *reg = FMC2_PCSCNTR;
363 break;
Christophe Kerello34af8b82024-03-06 10:50:46 +0100364 case FMC2_REG_CFGR:
365 *reg = FMC2_CFGR;
366 break;
Christophe Kerelloa994a802020-07-31 09:53:40 +0200367 default:
368 return -EINVAL;
369 }
370
371 return 0;
372}
373
374static int stm32_fmc2_ebi_set_bit_field(struct stm32_fmc2_ebi *ebi,
375 const struct stm32_fmc2_prop *prop,
376 int cs, u32 setup)
377{
378 u32 reg;
379 int ret;
380
381 ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, &reg);
382 if (ret)
383 return ret;
384
385 clrsetbits_le32(ebi->io_base + reg, prop->reg_mask,
386 setup ? prop->reg_mask : 0);
387
388 return 0;
389}
390
391static int stm32_fmc2_ebi_set_trans_type(struct stm32_fmc2_ebi *ebi,
392 const struct stm32_fmc2_prop *prop,
393 int cs, u32 setup)
394{
395 u32 bcr_mask, bcr = FMC2_BCR_WREN;
396 u32 btr_mask, btr = 0;
397 u32 bwtr_mask, bwtr = 0;
398
399 bwtr_mask = FMC2_BXTR_ACCMOD;
400 btr_mask = FMC2_BXTR_ACCMOD;
401 bcr_mask = FMC2_BCR_MUXEN | FMC2_BCR_MTYP | FMC2_BCR_FACCEN |
402 FMC2_BCR_WREN | FMC2_BCR_WAITEN | FMC2_BCR_BURSTEN |
403 FMC2_BCR_EXTMOD | FMC2_BCR_CBURSTRW;
404
405 switch (setup) {
406 case FMC2_ASYNC_MODE_1_SRAM:
407 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_SRAM);
408 /*
409 * MUXEN = 0, MTYP = 0, FACCEN = 0, BURSTEN = 0, WAITEN = 0,
410 * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0
411 */
412 break;
413 case FMC2_ASYNC_MODE_1_PSRAM:
414 /*
415 * MUXEN = 0, MTYP = 1, FACCEN = 0, BURSTEN = 0, WAITEN = 0,
416 * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0
417 */
418 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM);
419 break;
420 case FMC2_ASYNC_MODE_A_SRAM:
421 /*
422 * MUXEN = 0, MTYP = 0, FACCEN = 0, BURSTEN = 0, WAITEN = 0,
423 * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 0
424 */
425 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_SRAM);
426 bcr |= FMC2_BCR_EXTMOD;
427 btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_A);
428 bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_A);
429 break;
430 case FMC2_ASYNC_MODE_A_PSRAM:
431 /*
432 * MUXEN = 0, MTYP = 1, FACCEN = 0, BURSTEN = 0, WAITEN = 0,
433 * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 0
434 */
435 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM);
436 bcr |= FMC2_BCR_EXTMOD;
437 btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_A);
438 bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_A);
439 break;
440 case FMC2_ASYNC_MODE_2_NOR:
441 /*
442 * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 0, WAITEN = 0,
443 * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0
444 */
445 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);
446 bcr |= FMC2_BCR_FACCEN;
447 break;
448 case FMC2_ASYNC_MODE_B_NOR:
449 /*
450 * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 0, WAITEN = 0,
451 * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 1
452 */
453 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);
454 bcr |= FMC2_BCR_FACCEN | FMC2_BCR_EXTMOD;
455 btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_B);
456 bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_B);
457 break;
458 case FMC2_ASYNC_MODE_C_NOR:
459 /*
460 * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 0, WAITEN = 0,
461 * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 2
462 */
463 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);
464 bcr |= FMC2_BCR_FACCEN | FMC2_BCR_EXTMOD;
465 btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_C);
466 bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_C);
467 break;
468 case FMC2_ASYNC_MODE_D_NOR:
469 /*
470 * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 0, WAITEN = 0,
471 * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 3
472 */
473 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);
474 bcr |= FMC2_BCR_FACCEN | FMC2_BCR_EXTMOD;
475 btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D);
476 bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D);
477 break;
478 case FMC2_SYNC_READ_SYNC_WRITE_PSRAM:
479 /*
480 * MUXEN = 0, MTYP = 1, FACCEN = 0, BURSTEN = 1, WAITEN = 0,
481 * WREN = 1, EXTMOD = 0, CBURSTRW = 1, ACCMOD = 0
482 */
483 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM);
484 bcr |= FMC2_BCR_BURSTEN | FMC2_BCR_CBURSTRW;
485 break;
486 case FMC2_SYNC_READ_ASYNC_WRITE_PSRAM:
487 /*
488 * MUXEN = 0, MTYP = 1, FACCEN = 0, BURSTEN = 1, WAITEN = 0,
489 * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0
490 */
491 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM);
492 bcr |= FMC2_BCR_BURSTEN;
493 break;
494 case FMC2_SYNC_READ_SYNC_WRITE_NOR:
495 /*
496 * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 1, WAITEN = 0,
497 * WREN = 1, EXTMOD = 0, CBURSTRW = 1, ACCMOD = 0
498 */
499 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);
500 bcr |= FMC2_BCR_FACCEN | FMC2_BCR_BURSTEN | FMC2_BCR_CBURSTRW;
501 break;
502 case FMC2_SYNC_READ_ASYNC_WRITE_NOR:
503 /*
504 * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 1, WAITEN = 0,
505 * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0
506 */
507 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);
508 bcr |= FMC2_BCR_FACCEN | FMC2_BCR_BURSTEN;
509 break;
510 default:
511 /* Type of transaction not supported */
512 return -EINVAL;
513 }
514
515 if (bcr & FMC2_BCR_EXTMOD)
516 clrsetbits_le32(ebi->io_base + FMC2_BWTR(cs),
517 bwtr_mask, bwtr);
518 clrsetbits_le32(ebi->io_base + FMC2_BTR(cs), btr_mask, btr);
519 clrsetbits_le32(ebi->io_base + FMC2_BCR(cs), bcr_mask, bcr);
520
521 return 0;
522}
523
524static int stm32_fmc2_ebi_set_buswidth(struct stm32_fmc2_ebi *ebi,
525 const struct stm32_fmc2_prop *prop,
526 int cs, u32 setup)
527{
528 u32 val;
529
530 switch (setup) {
531 case FMC2_BUSWIDTH_8:
532 val = FIELD_PREP(FMC2_BCR_MWID, FMC2_BCR_MWID_8);
533 break;
534 case FMC2_BUSWIDTH_16:
535 val = FIELD_PREP(FMC2_BCR_MWID, FMC2_BCR_MWID_16);
536 break;
537 default:
538 /* Buswidth not supported */
539 return -EINVAL;
540 }
541
542 clrsetbits_le32(ebi->io_base + FMC2_BCR(cs), FMC2_BCR_MWID, val);
543
544 return 0;
545}
546
547static int stm32_fmc2_ebi_set_cpsize(struct stm32_fmc2_ebi *ebi,
548 const struct stm32_fmc2_prop *prop,
549 int cs, u32 setup)
550{
551 u32 val;
552
553 switch (setup) {
554 case FMC2_CPSIZE_0:
555 val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_0);
556 break;
557 case FMC2_CPSIZE_128:
558 val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_128);
559 break;
560 case FMC2_CPSIZE_256:
561 val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_256);
562 break;
563 case FMC2_CPSIZE_512:
564 val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_512);
565 break;
566 case FMC2_CPSIZE_1024:
567 val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_1024);
568 break;
569 default:
570 /* Cpsize not supported */
571 return -EINVAL;
572 }
573
574 clrsetbits_le32(ebi->io_base + FMC2_BCR(cs), FMC2_BCR_CPSIZE, val);
575
576 return 0;
577}
578
579static int stm32_fmc2_ebi_set_bl_setup(struct stm32_fmc2_ebi *ebi,
580 const struct stm32_fmc2_prop *prop,
581 int cs, u32 setup)
582{
583 u32 val;
584
585 val = min_t(u32, setup, FMC2_BCR_NBLSET_MAX);
586 val = FIELD_PREP(FMC2_BCR_NBLSET, val);
587 clrsetbits_le32(ebi->io_base + FMC2_BCR(cs), FMC2_BCR_NBLSET, val);
588
589 return 0;
590}
591
592static int stm32_fmc2_ebi_set_address_setup(struct stm32_fmc2_ebi *ebi,
593 const struct stm32_fmc2_prop *prop,
594 int cs, u32 setup)
595{
596 u32 bcr = readl(ebi->io_base + FMC2_BCR(cs));
597 u32 bxtr = prop->reg_type == FMC2_REG_BWTR ?
598 readl(ebi->io_base + FMC2_BWTR(cs)) :
599 readl(ebi->io_base + FMC2_BTR(cs));
600 u32 reg, val = FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D);
601 int ret;
602
603 ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, &reg);
604 if (ret)
605 return ret;
606
607 if ((bxtr & FMC2_BXTR_ACCMOD) == val || bcr & FMC2_BCR_MUXEN)
608 val = clamp_val(setup, 1, FMC2_BXTR_ADDSET_MAX);
609 else
610 val = min_t(u32, setup, FMC2_BXTR_ADDSET_MAX);
611 val = FIELD_PREP(FMC2_BXTR_ADDSET, val);
612 clrsetbits_le32(ebi->io_base + reg, FMC2_BXTR_ADDSET, val);
613
614 return 0;
615}
616
617static int stm32_fmc2_ebi_set_address_hold(struct stm32_fmc2_ebi *ebi,
618 const struct stm32_fmc2_prop *prop,
619 int cs, u32 setup)
620{
621 u32 val, reg;
622 int ret;
623
624 ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, &reg);
625 if (ret)
626 return ret;
627
628 val = clamp_val(setup, 1, FMC2_BXTR_ADDHLD_MAX);
629 val = FIELD_PREP(FMC2_BXTR_ADDHLD, val);
630 clrsetbits_le32(ebi->io_base + reg, FMC2_BXTR_ADDHLD, val);
631
632 return 0;
633}
634
635static int stm32_fmc2_ebi_set_data_setup(struct stm32_fmc2_ebi *ebi,
636 const struct stm32_fmc2_prop *prop,
637 int cs, u32 setup)
638{
639 u32 val, reg;
640 int ret;
641
642 ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, &reg);
643 if (ret)
644 return ret;
645
646 val = clamp_val(setup, 1, FMC2_BXTR_DATAST_MAX);
647 val = FIELD_PREP(FMC2_BXTR_DATAST, val);
648 clrsetbits_le32(ebi->io_base + reg, FMC2_BXTR_DATAST, val);
649
650 return 0;
651}
652
653static int stm32_fmc2_ebi_set_bus_turnaround(struct stm32_fmc2_ebi *ebi,
654 const struct stm32_fmc2_prop *prop,
655 int cs, u32 setup)
656{
657 u32 val, reg;
658 int ret;
659
660 ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, &reg);
661 if (ret)
662 return ret;
663
664 val = setup ? min_t(u32, setup - 1, FMC2_BXTR_BUSTURN_MAX) : 0;
665 val = FIELD_PREP(FMC2_BXTR_BUSTURN, val);
666 clrsetbits_le32(ebi->io_base + reg, FMC2_BXTR_BUSTURN, val);
667
668 return 0;
669}
670
671static int stm32_fmc2_ebi_set_data_hold(struct stm32_fmc2_ebi *ebi,
672 const struct stm32_fmc2_prop *prop,
673 int cs, u32 setup)
674{
675 u32 val, reg;
676 int ret;
677
678 ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, &reg);
679 if (ret)
680 return ret;
681
682 if (prop->reg_type == FMC2_REG_BWTR)
683 val = setup ? min_t(u32, setup - 1, FMC2_BXTR_DATAHLD_MAX) : 0;
684 else
685 val = min_t(u32, setup, FMC2_BXTR_DATAHLD_MAX);
686 val = FIELD_PREP(FMC2_BXTR_DATAHLD, val);
687 clrsetbits_le32(ebi->io_base + reg, FMC2_BXTR_DATAHLD, val);
688
689 return 0;
690}
691
692static int stm32_fmc2_ebi_set_clk_period(struct stm32_fmc2_ebi *ebi,
693 const struct stm32_fmc2_prop *prop,
694 int cs, u32 setup)
695{
696 u32 val;
697
698 val = setup ? clamp_val(setup - 1, 1, FMC2_BTR_CLKDIV_MAX) : 1;
699 val = FIELD_PREP(FMC2_BTR_CLKDIV, val);
700 clrsetbits_le32(ebi->io_base + FMC2_BTR(cs), FMC2_BTR_CLKDIV, val);
701
702 return 0;
703}
704
Christophe Kerello34af8b82024-03-06 10:50:46 +0100705static int stm32_fmc2_ebi_mp25_set_clk_period(struct stm32_fmc2_ebi *ebi,
706 const struct stm32_fmc2_prop *prop,
707 int cs, u32 setup)
708{
709 u32 cfgr = readl(ebi->io_base + FMC2_CFGR);
710 u32 val;
711
712 if (cfgr & FMC2_CFGR_CCLKEN) {
713 val = setup ? clamp_val(setup - 1, 1, FMC2_CFGR_CLKDIV_MAX) : 1;
714 val = FIELD_PREP(FMC2_CFGR_CLKDIV, val);
715 clrsetbits_le32(ebi->io_base + FMC2_CFGR, FMC2_CFGR_CLKDIV, val);
716 } else {
717 val = setup ? clamp_val(setup - 1, 1, FMC2_BTR_CLKDIV_MAX) : 1;
718 val = FIELD_PREP(FMC2_BTR_CLKDIV, val);
719 clrsetbits_le32(ebi->io_base + FMC2_BTR(cs), FMC2_BTR_CLKDIV, val);
720 }
721
722 return 0;
723}
724
Christophe Kerelloa994a802020-07-31 09:53:40 +0200725static int stm32_fmc2_ebi_set_data_latency(struct stm32_fmc2_ebi *ebi,
726 const struct stm32_fmc2_prop *prop,
727 int cs, u32 setup)
728{
729 u32 val;
730
731 val = setup > 1 ? min_t(u32, setup - 2, FMC2_BTR_DATLAT_MAX) : 0;
732 val = FIELD_PREP(FMC2_BTR_DATLAT, val);
733 clrsetbits_le32(ebi->io_base + FMC2_BTR(cs), FMC2_BTR_DATLAT, val);
734
735 return 0;
736}
737
738static int stm32_fmc2_ebi_set_max_low_pulse(struct stm32_fmc2_ebi *ebi,
739 const struct stm32_fmc2_prop *prop,
740 int cs, u32 setup)
741{
742 u32 old_val, new_val, pcscntr;
743
744 if (setup < 1)
745 return 0;
746
747 pcscntr = readl(ebi->io_base + FMC2_PCSCNTR);
748
749 /* Enable counter for the bank */
750 setbits_le32(ebi->io_base + FMC2_PCSCNTR, FMC2_PCSCNTR_CNTBEN(cs));
751
752 new_val = min_t(u32, setup - 1, FMC2_PCSCNTR_CSCOUNT_MAX);
753 old_val = FIELD_GET(FMC2_PCSCNTR_CSCOUNT, pcscntr);
754 if (old_val && new_val > old_val)
755 /* Keep current counter value */
756 return 0;
757
758 new_val = FIELD_PREP(FMC2_PCSCNTR_CSCOUNT, new_val);
759 clrsetbits_le32(ebi->io_base + FMC2_PCSCNTR,
760 FMC2_PCSCNTR_CSCOUNT, new_val);
761
762 return 0;
763}
764
Christophe Kerello34af8b82024-03-06 10:50:46 +0100765static int stm32_fmc2_ebi_mp25_set_max_low_pulse(struct stm32_fmc2_ebi *ebi,
766 const struct stm32_fmc2_prop *prop,
767 int cs, u32 setup)
768{
769 u32 val;
770
771 if (setup == FMC2_CSCOUNT_0)
772 val = FIELD_PREP(FMC2_BCR_CSCOUNT, FMC2_BCR_CSCOUNT_0);
773 else if (setup == FMC2_CSCOUNT_1)
774 val = FIELD_PREP(FMC2_BCR_CSCOUNT, FMC2_BCR_CSCOUNT_1);
775 else if (setup <= FMC2_CSCOUNT_64)
776 val = FIELD_PREP(FMC2_BCR_CSCOUNT, FMC2_BCR_CSCOUNT_64);
777 else
778 val = FIELD_PREP(FMC2_BCR_CSCOUNT, FMC2_BCR_CSCOUNT_256);
779
780 clrsetbits_le32(ebi->io_base + FMC2_BCR(cs),
781 FMC2_BCR_CSCOUNT, val);
782
783 return 0;
784}
785
Christophe Kerelloa994a802020-07-31 09:53:40 +0200786static const struct stm32_fmc2_prop stm32_fmc2_child_props[] = {
787 /* st,fmc2-ebi-cs-trans-type must be the first property */
788 {
789 .name = "st,fmc2-ebi-cs-transaction-type",
790 .mprop = true,
791 .set = stm32_fmc2_ebi_set_trans_type,
792 },
793 {
794 .name = "st,fmc2-ebi-cs-cclk-enable",
795 .bprop = true,
796 .reg_type = FMC2_REG_BCR,
797 .reg_mask = FMC2_BCR1_CCLKEN,
798 .check = stm32_fmc2_ebi_check_cclk,
799 .set = stm32_fmc2_ebi_set_bit_field,
800 },
801 {
802 .name = "st,fmc2-ebi-cs-mux-enable",
803 .bprop = true,
804 .reg_type = FMC2_REG_BCR,
805 .reg_mask = FMC2_BCR_MUXEN,
806 .check = stm32_fmc2_ebi_check_mux,
807 .set = stm32_fmc2_ebi_set_bit_field,
808 },
809 {
810 .name = "st,fmc2-ebi-cs-buswidth",
811 .reset_val = FMC2_BUSWIDTH_16,
812 .set = stm32_fmc2_ebi_set_buswidth,
813 },
814 {
815 .name = "st,fmc2-ebi-cs-waitpol-high",
816 .bprop = true,
817 .reg_type = FMC2_REG_BCR,
818 .reg_mask = FMC2_BCR_WAITPOL,
819 .set = stm32_fmc2_ebi_set_bit_field,
820 },
821 {
822 .name = "st,fmc2-ebi-cs-waitcfg-enable",
823 .bprop = true,
824 .reg_type = FMC2_REG_BCR,
825 .reg_mask = FMC2_BCR_WAITCFG,
826 .check = stm32_fmc2_ebi_check_waitcfg,
827 .set = stm32_fmc2_ebi_set_bit_field,
828 },
829 {
830 .name = "st,fmc2-ebi-cs-wait-enable",
831 .bprop = true,
832 .reg_type = FMC2_REG_BCR,
833 .reg_mask = FMC2_BCR_WAITEN,
834 .check = stm32_fmc2_ebi_check_sync_trans,
835 .set = stm32_fmc2_ebi_set_bit_field,
836 },
837 {
838 .name = "st,fmc2-ebi-cs-asyncwait-enable",
839 .bprop = true,
840 .reg_type = FMC2_REG_BCR,
841 .reg_mask = FMC2_BCR_ASYNCWAIT,
842 .check = stm32_fmc2_ebi_check_async_trans,
843 .set = stm32_fmc2_ebi_set_bit_field,
844 },
845 {
846 .name = "st,fmc2-ebi-cs-cpsize",
847 .check = stm32_fmc2_ebi_check_cpsize,
848 .set = stm32_fmc2_ebi_set_cpsize,
849 },
850 {
851 .name = "st,fmc2-ebi-cs-byte-lane-setup-ns",
852 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
853 .set = stm32_fmc2_ebi_set_bl_setup,
854 },
855 {
856 .name = "st,fmc2-ebi-cs-address-setup-ns",
857 .reg_type = FMC2_REG_BTR,
858 .reset_val = FMC2_BXTR_ADDSET_MAX,
859 .check = stm32_fmc2_ebi_check_async_trans,
860 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
861 .set = stm32_fmc2_ebi_set_address_setup,
862 },
863 {
864 .name = "st,fmc2-ebi-cs-address-hold-ns",
865 .reg_type = FMC2_REG_BTR,
866 .reset_val = FMC2_BXTR_ADDHLD_MAX,
867 .check = stm32_fmc2_ebi_check_address_hold,
868 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
869 .set = stm32_fmc2_ebi_set_address_hold,
870 },
871 {
872 .name = "st,fmc2-ebi-cs-data-setup-ns",
873 .reg_type = FMC2_REG_BTR,
874 .reset_val = FMC2_BXTR_DATAST_MAX,
875 .check = stm32_fmc2_ebi_check_async_trans,
876 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
877 .set = stm32_fmc2_ebi_set_data_setup,
878 },
879 {
880 .name = "st,fmc2-ebi-cs-bus-turnaround-ns",
881 .reg_type = FMC2_REG_BTR,
882 .reset_val = FMC2_BXTR_BUSTURN_MAX + 1,
883 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
884 .set = stm32_fmc2_ebi_set_bus_turnaround,
885 },
886 {
887 .name = "st,fmc2-ebi-cs-data-hold-ns",
888 .reg_type = FMC2_REG_BTR,
889 .check = stm32_fmc2_ebi_check_async_trans,
890 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
891 .set = stm32_fmc2_ebi_set_data_hold,
892 },
893 {
894 .name = "st,fmc2-ebi-cs-clk-period-ns",
895 .reset_val = FMC2_BTR_CLKDIV_MAX + 1,
896 .check = stm32_fmc2_ebi_check_clk_period,
897 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
898 .set = stm32_fmc2_ebi_set_clk_period,
899 },
900 {
901 .name = "st,fmc2-ebi-cs-data-latency-ns",
902 .check = stm32_fmc2_ebi_check_sync_trans,
903 .calculate = stm32_fmc2_ebi_ns_to_clk_period,
904 .set = stm32_fmc2_ebi_set_data_latency,
905 },
906 {
907 .name = "st,fmc2-ebi-cs-write-address-setup-ns",
908 .reg_type = FMC2_REG_BWTR,
909 .reset_val = FMC2_BXTR_ADDSET_MAX,
910 .check = stm32_fmc2_ebi_check_async_trans,
911 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
912 .set = stm32_fmc2_ebi_set_address_setup,
913 },
914 {
915 .name = "st,fmc2-ebi-cs-write-address-hold-ns",
916 .reg_type = FMC2_REG_BWTR,
917 .reset_val = FMC2_BXTR_ADDHLD_MAX,
918 .check = stm32_fmc2_ebi_check_address_hold,
919 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
920 .set = stm32_fmc2_ebi_set_address_hold,
921 },
922 {
923 .name = "st,fmc2-ebi-cs-write-data-setup-ns",
924 .reg_type = FMC2_REG_BWTR,
925 .reset_val = FMC2_BXTR_DATAST_MAX,
926 .check = stm32_fmc2_ebi_check_async_trans,
927 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
928 .set = stm32_fmc2_ebi_set_data_setup,
929 },
930 {
931 .name = "st,fmc2-ebi-cs-write-bus-turnaround-ns",
932 .reg_type = FMC2_REG_BWTR,
933 .reset_val = FMC2_BXTR_BUSTURN_MAX + 1,
934 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
935 .set = stm32_fmc2_ebi_set_bus_turnaround,
936 },
937 {
938 .name = "st,fmc2-ebi-cs-write-data-hold-ns",
939 .reg_type = FMC2_REG_BWTR,
940 .check = stm32_fmc2_ebi_check_async_trans,
941 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
942 .set = stm32_fmc2_ebi_set_data_hold,
943 },
944 {
945 .name = "st,fmc2-ebi-cs-max-low-pulse-ns",
946 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
947 .set = stm32_fmc2_ebi_set_max_low_pulse,
948 },
949};
950
Christophe Kerello34af8b82024-03-06 10:50:46 +0100951static const struct stm32_fmc2_prop stm32_fmc2_mp25_child_props[] = {
952 /* st,fmc2-ebi-cs-trans-type must be the first property */
953 {
954 .name = "st,fmc2-ebi-cs-transaction-type",
955 .mprop = true,
956 .set = stm32_fmc2_ebi_set_trans_type,
957 },
958 {
959 .name = "st,fmc2-ebi-cs-cclk-enable",
960 .bprop = true,
961 .reg_type = FMC2_REG_CFGR,
962 .reg_mask = FMC2_CFGR_CCLKEN,
963 .check = stm32_fmc2_ebi_check_sync_trans,
964 .set = stm32_fmc2_ebi_set_bit_field,
965 },
966 {
967 .name = "st,fmc2-ebi-cs-mux-enable",
968 .bprop = true,
969 .reg_type = FMC2_REG_BCR,
970 .reg_mask = FMC2_BCR_MUXEN,
971 .check = stm32_fmc2_ebi_check_mux,
972 .set = stm32_fmc2_ebi_set_bit_field,
973 },
974 {
975 .name = "st,fmc2-ebi-cs-buswidth",
976 .reset_val = FMC2_BUSWIDTH_16,
977 .set = stm32_fmc2_ebi_set_buswidth,
978 },
979 {
980 .name = "st,fmc2-ebi-cs-waitpol-high",
981 .bprop = true,
982 .reg_type = FMC2_REG_BCR,
983 .reg_mask = FMC2_BCR_WAITPOL,
984 .set = stm32_fmc2_ebi_set_bit_field,
985 },
986 {
987 .name = "st,fmc2-ebi-cs-waitcfg-enable",
988 .bprop = true,
989 .reg_type = FMC2_REG_BCR,
990 .reg_mask = FMC2_BCR_WAITCFG,
991 .check = stm32_fmc2_ebi_check_waitcfg,
992 .set = stm32_fmc2_ebi_set_bit_field,
993 },
994 {
995 .name = "st,fmc2-ebi-cs-wait-enable",
996 .bprop = true,
997 .reg_type = FMC2_REG_BCR,
998 .reg_mask = FMC2_BCR_WAITEN,
999 .check = stm32_fmc2_ebi_check_sync_trans,
1000 .set = stm32_fmc2_ebi_set_bit_field,
1001 },
1002 {
1003 .name = "st,fmc2-ebi-cs-asyncwait-enable",
1004 .bprop = true,
1005 .reg_type = FMC2_REG_BCR,
1006 .reg_mask = FMC2_BCR_ASYNCWAIT,
1007 .check = stm32_fmc2_ebi_check_async_trans,
1008 .set = stm32_fmc2_ebi_set_bit_field,
1009 },
1010 {
1011 .name = "st,fmc2-ebi-cs-cpsize",
1012 .check = stm32_fmc2_ebi_check_cpsize,
1013 .set = stm32_fmc2_ebi_set_cpsize,
1014 },
1015 {
1016 .name = "st,fmc2-ebi-cs-byte-lane-setup-ns",
1017 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1018 .set = stm32_fmc2_ebi_set_bl_setup,
1019 },
1020 {
1021 .name = "st,fmc2-ebi-cs-address-setup-ns",
1022 .reg_type = FMC2_REG_BTR,
1023 .reset_val = FMC2_BXTR_ADDSET_MAX,
1024 .check = stm32_fmc2_ebi_check_async_trans,
1025 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1026 .set = stm32_fmc2_ebi_set_address_setup,
1027 },
1028 {
1029 .name = "st,fmc2-ebi-cs-address-hold-ns",
1030 .reg_type = FMC2_REG_BTR,
1031 .reset_val = FMC2_BXTR_ADDHLD_MAX,
1032 .check = stm32_fmc2_ebi_check_address_hold,
1033 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1034 .set = stm32_fmc2_ebi_set_address_hold,
1035 },
1036 {
1037 .name = "st,fmc2-ebi-cs-data-setup-ns",
1038 .reg_type = FMC2_REG_BTR,
1039 .reset_val = FMC2_BXTR_DATAST_MAX,
1040 .check = stm32_fmc2_ebi_check_async_trans,
1041 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1042 .set = stm32_fmc2_ebi_set_data_setup,
1043 },
1044 {
1045 .name = "st,fmc2-ebi-cs-bus-turnaround-ns",
1046 .reg_type = FMC2_REG_BTR,
1047 .reset_val = FMC2_BXTR_BUSTURN_MAX + 1,
1048 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1049 .set = stm32_fmc2_ebi_set_bus_turnaround,
1050 },
1051 {
1052 .name = "st,fmc2-ebi-cs-data-hold-ns",
1053 .reg_type = FMC2_REG_BTR,
1054 .check = stm32_fmc2_ebi_check_async_trans,
1055 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1056 .set = stm32_fmc2_ebi_set_data_hold,
1057 },
1058 {
1059 .name = "st,fmc2-ebi-cs-clk-period-ns",
1060 .reset_val = FMC2_CFGR_CLKDIV_MAX + 1,
1061 .check = stm32_fmc2_ebi_check_sync_trans,
1062 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1063 .set = stm32_fmc2_ebi_mp25_set_clk_period,
1064 },
1065 {
1066 .name = "st,fmc2-ebi-cs-data-latency-ns",
1067 .check = stm32_fmc2_ebi_check_sync_trans,
1068 .calculate = stm32_fmc2_ebi_mp25_ns_to_clk_period,
1069 .set = stm32_fmc2_ebi_set_data_latency,
1070 },
1071 {
1072 .name = "st,fmc2-ebi-cs-write-address-setup-ns",
1073 .reg_type = FMC2_REG_BWTR,
1074 .reset_val = FMC2_BXTR_ADDSET_MAX,
1075 .check = stm32_fmc2_ebi_check_async_trans,
1076 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1077 .set = stm32_fmc2_ebi_set_address_setup,
1078 },
1079 {
1080 .name = "st,fmc2-ebi-cs-write-address-hold-ns",
1081 .reg_type = FMC2_REG_BWTR,
1082 .reset_val = FMC2_BXTR_ADDHLD_MAX,
1083 .check = stm32_fmc2_ebi_check_address_hold,
1084 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1085 .set = stm32_fmc2_ebi_set_address_hold,
1086 },
1087 {
1088 .name = "st,fmc2-ebi-cs-write-data-setup-ns",
1089 .reg_type = FMC2_REG_BWTR,
1090 .reset_val = FMC2_BXTR_DATAST_MAX,
1091 .check = stm32_fmc2_ebi_check_async_trans,
1092 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1093 .set = stm32_fmc2_ebi_set_data_setup,
1094 },
1095 {
1096 .name = "st,fmc2-ebi-cs-write-bus-turnaround-ns",
1097 .reg_type = FMC2_REG_BWTR,
1098 .reset_val = FMC2_BXTR_BUSTURN_MAX + 1,
1099 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1100 .set = stm32_fmc2_ebi_set_bus_turnaround,
1101 },
1102 {
1103 .name = "st,fmc2-ebi-cs-write-data-hold-ns",
1104 .reg_type = FMC2_REG_BWTR,
1105 .check = stm32_fmc2_ebi_check_async_trans,
1106 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1107 .set = stm32_fmc2_ebi_set_data_hold,
1108 },
1109 {
1110 .name = "st,fmc2-ebi-cs-max-low-pulse-ns",
1111 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1112 .set = stm32_fmc2_ebi_mp25_set_max_low_pulse,
1113 },
1114};
1115
Christophe Kerelloa994a802020-07-31 09:53:40 +02001116static int stm32_fmc2_ebi_parse_prop(struct stm32_fmc2_ebi *ebi,
1117 ofnode node,
1118 const struct stm32_fmc2_prop *prop,
1119 int cs)
1120{
1121 u32 setup = 0;
1122
1123 if (!prop->set) {
Patrick Delaunay729ecfd2020-11-06 19:01:55 +01001124 log_err("property %s is not well defined\n", prop->name);
Christophe Kerelloa994a802020-07-31 09:53:40 +02001125 return -EINVAL;
1126 }
1127
1128 if (prop->check && prop->check(ebi, prop, cs))
1129 /* Skip this property */
1130 return 0;
1131
1132 if (prop->bprop) {
1133 bool bprop;
1134
1135 bprop = ofnode_read_bool(node, prop->name);
1136 if (prop->mprop && !bprop) {
Patrick Delaunay729ecfd2020-11-06 19:01:55 +01001137 log_err("mandatory property %s not defined in the device tree\n",
1138 prop->name);
Christophe Kerelloa994a802020-07-31 09:53:40 +02001139 return -EINVAL;
1140 }
1141
1142 if (bprop)
1143 setup = 1;
1144 } else {
1145 u32 val;
1146 int ret;
1147
1148 ret = ofnode_read_u32(node, prop->name, &val);
1149 if (prop->mprop && ret) {
Patrick Delaunay729ecfd2020-11-06 19:01:55 +01001150 log_err("mandatory property %s not defined in the device tree\n",
1151 prop->name);
Christophe Kerelloa994a802020-07-31 09:53:40 +02001152 return ret;
1153 }
1154
1155 if (ret)
1156 setup = prop->reset_val;
1157 else if (prop->calculate)
1158 setup = prop->calculate(ebi, cs, val);
1159 else
1160 setup = val;
1161 }
1162
1163 return prop->set(ebi, prop, cs, setup);
1164}
1165
1166static void stm32_fmc2_ebi_enable_bank(struct stm32_fmc2_ebi *ebi, int cs)
1167{
1168 setbits_le32(ebi->io_base + FMC2_BCR(cs), FMC2_BCR_MBKEN);
1169}
1170
1171static void stm32_fmc2_ebi_disable_bank(struct stm32_fmc2_ebi *ebi, int cs)
1172{
1173 clrbits_le32(ebi->io_base + FMC2_BCR(cs), FMC2_BCR_MBKEN);
1174}
1175
1176/* NWAIT signal can not be connected to EBI controller and NAND controller */
Christophe Kerello34af8b82024-03-06 10:50:46 +01001177static int stm32_fmc2_ebi_nwait_used_by_ctrls(struct stm32_fmc2_ebi *ebi)
Christophe Kerelloa994a802020-07-31 09:53:40 +02001178{
1179 unsigned int cs;
1180 u32 bcr;
1181
1182 for (cs = 0; cs < FMC2_MAX_EBI_CE; cs++) {
1183 if (!(ebi->bank_assigned & BIT(cs)))
1184 continue;
1185
1186 bcr = readl(ebi->io_base + FMC2_BCR(cs));
1187 if ((bcr & FMC2_BCR_WAITEN || bcr & FMC2_BCR_ASYNCWAIT) &&
Christophe Kerello34af8b82024-03-06 10:50:46 +01001188 ebi->bank_assigned & BIT(FMC2_NAND)) {
1189 log_err("NWAIT signal connected to EBI and NAND controllers\n");
1190 return -EINVAL;
1191 }
Christophe Kerelloa994a802020-07-31 09:53:40 +02001192 }
1193
Christophe Kerello34af8b82024-03-06 10:50:46 +01001194 return 0;
Christophe Kerelloa994a802020-07-31 09:53:40 +02001195}
1196
1197static void stm32_fmc2_ebi_enable(struct stm32_fmc2_ebi *ebi)
1198{
Christophe Kerello34af8b82024-03-06 10:50:46 +01001199 setbits_le32(ebi->io_base + ebi->data->fmc2_enable_reg,
1200 ebi->data->fmc2_enable_bit);
Christophe Kerelloa994a802020-07-31 09:53:40 +02001201}
1202
1203static int stm32_fmc2_ebi_setup_cs(struct stm32_fmc2_ebi *ebi,
1204 ofnode node, u32 cs)
1205{
1206 unsigned int i;
1207 int ret;
1208
1209 stm32_fmc2_ebi_disable_bank(ebi, cs);
1210
Christophe Kerello34af8b82024-03-06 10:50:46 +01001211 for (i = 0; i < ebi->data->nb_child_props; i++) {
1212 const struct stm32_fmc2_prop *p = &ebi->data->child_props[i];
Christophe Kerelloa994a802020-07-31 09:53:40 +02001213
1214 ret = stm32_fmc2_ebi_parse_prop(ebi, node, p, cs);
1215 if (ret) {
Patrick Delaunay729ecfd2020-11-06 19:01:55 +01001216 log_err("property %s could not be set: %d\n",
1217 p->name, ret);
Christophe Kerelloa994a802020-07-31 09:53:40 +02001218 return ret;
1219 }
1220 }
1221
1222 stm32_fmc2_ebi_enable_bank(ebi, cs);
1223
1224 return 0;
1225}
1226
1227static int stm32_fmc2_ebi_parse_dt(struct udevice *dev,
1228 struct stm32_fmc2_ebi *ebi)
1229{
1230 ofnode child;
1231 bool child_found = false;
1232 u32 bank;
1233 int ret;
1234
1235 dev_for_each_subnode(child, dev) {
1236 ret = ofnode_read_u32(child, "reg", &bank);
1237 if (ret) {
Patrick Delaunay729ecfd2020-11-06 19:01:55 +01001238 dev_err(dev, "could not retrieve reg property: %d\n", ret);
Christophe Kerelloa994a802020-07-31 09:53:40 +02001239 return ret;
1240 }
1241
1242 if (bank >= FMC2_MAX_BANKS) {
Patrick Delaunay729ecfd2020-11-06 19:01:55 +01001243 dev_err(dev, "invalid reg value: %d\n", bank);
Christophe Kerelloa994a802020-07-31 09:53:40 +02001244 return -EINVAL;
1245 }
1246
1247 if (ebi->bank_assigned & BIT(bank)) {
Patrick Delaunay729ecfd2020-11-06 19:01:55 +01001248 dev_err(dev, "bank already assigned: %d\n", bank);
Christophe Kerelloa994a802020-07-31 09:53:40 +02001249 return -EINVAL;
1250 }
1251
1252 if (bank < FMC2_MAX_EBI_CE) {
1253 ret = stm32_fmc2_ebi_setup_cs(ebi, child, bank);
1254 if (ret) {
Patrick Delaunay729ecfd2020-11-06 19:01:55 +01001255 dev_err(dev, "setup chip select %d failed: %d\n", bank, ret);
Christophe Kerelloa994a802020-07-31 09:53:40 +02001256 return ret;
1257 }
1258 }
1259
1260 ebi->bank_assigned |= BIT(bank);
1261 child_found = true;
1262 }
1263
1264 if (!child_found) {
Patrick Delaunay729ecfd2020-11-06 19:01:55 +01001265 dev_warn(dev, "no subnodes found, disable the driver.\n");
Christophe Kerelloa994a802020-07-31 09:53:40 +02001266 return -ENODEV;
1267 }
1268
Christophe Kerello34af8b82024-03-06 10:50:46 +01001269 if (ebi->data->nwait_used_by_ctrls) {
1270 ret = ebi->data->nwait_used_by_ctrls(ebi);
1271 if (ret)
1272 return ret;
Christophe Kerelloa994a802020-07-31 09:53:40 +02001273 }
1274
1275 stm32_fmc2_ebi_enable(ebi);
1276
1277 return 0;
1278}
1279
1280static int stm32_fmc2_ebi_probe(struct udevice *dev)
1281{
1282 struct stm32_fmc2_ebi *ebi = dev_get_priv(dev);
1283 struct reset_ctl reset;
1284 int ret;
1285
Christophe Kerello34af8b82024-03-06 10:50:46 +01001286 ebi->data = (void *)dev_get_driver_data(dev);
1287 if (!ebi->data)
1288 return -EINVAL;
1289
Christophe Kerelloa994a802020-07-31 09:53:40 +02001290 ebi->io_base = dev_read_addr(dev);
1291 if (ebi->io_base == FDT_ADDR_T_NONE)
1292 return -EINVAL;
1293
1294 ret = clk_get_by_index(dev, 0, &ebi->clk);
1295 if (ret)
1296 return ret;
1297
1298 ret = clk_enable(&ebi->clk);
1299 if (ret)
1300 return ret;
1301
1302 ret = reset_get_by_index(dev, 0, &reset);
1303 if (!ret) {
1304 reset_assert(&reset);
1305 udelay(2);
1306 reset_deassert(&reset);
1307 }
1308
1309 return stm32_fmc2_ebi_parse_dt(dev, ebi);
1310}
1311
Christophe Kerello34af8b82024-03-06 10:50:46 +01001312static const struct stm32_fmc2_ebi_data stm32_fmc2_ebi_mp1_data = {
1313 .child_props = stm32_fmc2_child_props,
1314 .nb_child_props = ARRAY_SIZE(stm32_fmc2_child_props),
1315 .fmc2_enable_reg = FMC2_BCR1,
1316 .fmc2_enable_bit = FMC2_BCR1_FMC2EN,
1317 .nwait_used_by_ctrls = stm32_fmc2_ebi_nwait_used_by_ctrls,
1318};
1319
1320static const struct stm32_fmc2_ebi_data stm32_fmc2_ebi_mp25_data = {
1321 .child_props = stm32_fmc2_mp25_child_props,
1322 .nb_child_props = ARRAY_SIZE(stm32_fmc2_mp25_child_props),
1323 .fmc2_enable_reg = FMC2_CFGR,
1324 .fmc2_enable_bit = FMC2_CFGR_FMC2EN,
1325};
1326
Christophe Kerelloa994a802020-07-31 09:53:40 +02001327static const struct udevice_id stm32_fmc2_ebi_match[] = {
Christophe Kerello34af8b82024-03-06 10:50:46 +01001328 {
1329 .compatible = "st,stm32mp1-fmc2-ebi",
1330 .data = (ulong)&stm32_fmc2_ebi_mp1_data,
1331 },
1332 {
1333 .compatible = "st,stm32mp25-fmc2-ebi",
1334 .data = (ulong)&stm32_fmc2_ebi_mp25_data,
1335 },
Christophe Kerelloa994a802020-07-31 09:53:40 +02001336 { /* Sentinel */ }
1337};
1338
1339U_BOOT_DRIVER(stm32_fmc2_ebi) = {
1340 .name = "stm32_fmc2_ebi",
1341 .id = UCLASS_NOP,
1342 .of_match = stm32_fmc2_ebi_match,
1343 .probe = stm32_fmc2_ebi_probe,
Simon Glass8a2b47f2020-12-03 16:55:17 -07001344 .priv_auto = sizeof(struct stm32_fmc2_ebi),
Christophe Kerelloa994a802020-07-31 09:53:40 +02001345 .bind = dm_scan_fdt_dev,
1346};