blob: 713dead5c572feb35805fefe97ca943c1fde6874 [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 <clk.h>
9#include <dm.h>
10#include <reset.h>
Patrick Delaunay729ecfd2020-11-06 19:01:55 +010011#include <dm/device_compat.h>
Christophe Kerelloa994a802020-07-31 09:53:40 +020012#include <linux/bitfield.h>
13#include <linux/err.h>
14#include <linux/iopoll.h>
15#include <linux/ioport.h>
Igor Prusovc3421ea2023-11-09 20:10:04 +030016#include <linux/time.h>
Christophe Kerelloa994a802020-07-31 09:53:40 +020017
18/* FMC2 Controller Registers */
19#define FMC2_BCR1 0x0
20#define FMC2_BTR1 0x4
21#define FMC2_BCR(x) ((x) * 0x8 + FMC2_BCR1)
22#define FMC2_BTR(x) ((x) * 0x8 + FMC2_BTR1)
23#define FMC2_PCSCNTR 0x20
Christophe Kerello34af8b82024-03-06 10:50:46 +010024#define FMC2_CFGR 0x20
Christophe Kerello90c38b52024-03-06 10:50:47 +010025#define FMC2_SR 0x84
Christophe Kerelloa994a802020-07-31 09:53:40 +020026#define FMC2_BWTR1 0x104
27#define FMC2_BWTR(x) ((x) * 0x8 + FMC2_BWTR1)
Christophe Kerello90c38b52024-03-06 10:50:47 +010028#define FMC2_SECCFGR 0x300
29#define FMC2_CIDCFGR0 0x30c
30#define FMC2_CIDCFGR(x) ((x) * 0x8 + FMC2_CIDCFGR0)
31#define FMC2_SEMCR0 0x310
32#define FMC2_SEMCR(x) ((x) * 0x8 + FMC2_SEMCR0)
Christophe Kerelloa994a802020-07-31 09:53:40 +020033
34/* Register: FMC2_BCR1 */
35#define FMC2_BCR1_CCLKEN BIT(20)
36#define FMC2_BCR1_FMC2EN BIT(31)
37
38/* Register: FMC2_BCRx */
39#define FMC2_BCR_MBKEN BIT(0)
40#define FMC2_BCR_MUXEN BIT(1)
41#define FMC2_BCR_MTYP GENMASK(3, 2)
42#define FMC2_BCR_MWID GENMASK(5, 4)
43#define FMC2_BCR_FACCEN BIT(6)
44#define FMC2_BCR_BURSTEN BIT(8)
45#define FMC2_BCR_WAITPOL BIT(9)
46#define FMC2_BCR_WAITCFG BIT(11)
47#define FMC2_BCR_WREN BIT(12)
48#define FMC2_BCR_WAITEN BIT(13)
49#define FMC2_BCR_EXTMOD BIT(14)
50#define FMC2_BCR_ASYNCWAIT BIT(15)
51#define FMC2_BCR_CPSIZE GENMASK(18, 16)
52#define FMC2_BCR_CBURSTRW BIT(19)
Christophe Kerello34af8b82024-03-06 10:50:46 +010053#define FMC2_BCR_CSCOUNT GENMASK(21, 20)
Christophe Kerelloa994a802020-07-31 09:53:40 +020054#define FMC2_BCR_NBLSET GENMASK(23, 22)
55
56/* Register: FMC2_BTRx/FMC2_BWTRx */
57#define FMC2_BXTR_ADDSET GENMASK(3, 0)
58#define FMC2_BXTR_ADDHLD GENMASK(7, 4)
59#define FMC2_BXTR_DATAST GENMASK(15, 8)
60#define FMC2_BXTR_BUSTURN GENMASK(19, 16)
61#define FMC2_BTR_CLKDIV GENMASK(23, 20)
62#define FMC2_BTR_DATLAT GENMASK(27, 24)
63#define FMC2_BXTR_ACCMOD GENMASK(29, 28)
64#define FMC2_BXTR_DATAHLD GENMASK(31, 30)
65
66/* Register: FMC2_PCSCNTR */
67#define FMC2_PCSCNTR_CSCOUNT GENMASK(15, 0)
68#define FMC2_PCSCNTR_CNTBEN(x) BIT((x) + 16)
69
Christophe Kerello34af8b82024-03-06 10:50:46 +010070/* Register: FMC2_CFGR */
71#define FMC2_CFGR_CLKDIV GENMASK(19, 16)
72#define FMC2_CFGR_CCLKEN BIT(20)
73#define FMC2_CFGR_FMC2EN BIT(31)
74
Christophe Kerello90c38b52024-03-06 10:50:47 +010075/* Register: FMC2_SR */
76#define FMC2_SR_ISOST GENMASK(1, 0)
77
78/* Register: FMC2_CIDCFGR */
79#define FMC2_CIDCFGR_CFEN BIT(0)
80#define FMC2_CIDCFGR_SEMEN BIT(1)
81#define FMC2_CIDCFGR_SCID GENMASK(6, 4)
82#define FMC2_CIDCFGR_SEMWLC1 BIT(17)
83
84/* Register: FMC2_SEMCR */
85#define FMC2_SEMCR_SEM_MUTEX BIT(0)
86#define FMC2_SEMCR_SEMCID GENMASK(6, 4)
87
Christophe Kerelloa994a802020-07-31 09:53:40 +020088#define FMC2_MAX_EBI_CE 4
89#define FMC2_MAX_BANKS 5
Christophe Kerello90c38b52024-03-06 10:50:47 +010090#define FMC2_MAX_RESOURCES 6
91#define FMC2_CID1 1
Christophe Kerelloa994a802020-07-31 09:53:40 +020092
93#define FMC2_BCR_CPSIZE_0 0x0
94#define FMC2_BCR_CPSIZE_128 0x1
95#define FMC2_BCR_CPSIZE_256 0x2
96#define FMC2_BCR_CPSIZE_512 0x3
97#define FMC2_BCR_CPSIZE_1024 0x4
98
99#define FMC2_BCR_MWID_8 0x0
100#define FMC2_BCR_MWID_16 0x1
101
102#define FMC2_BCR_MTYP_SRAM 0x0
103#define FMC2_BCR_MTYP_PSRAM 0x1
104#define FMC2_BCR_MTYP_NOR 0x2
105
Christophe Kerello34af8b82024-03-06 10:50:46 +0100106#define FMC2_BCR_CSCOUNT_0 0x0
107#define FMC2_BCR_CSCOUNT_1 0x1
108#define FMC2_BCR_CSCOUNT_64 0x2
109#define FMC2_BCR_CSCOUNT_256 0x3
110
Christophe Kerelloa994a802020-07-31 09:53:40 +0200111#define FMC2_BXTR_EXTMOD_A 0x0
112#define FMC2_BXTR_EXTMOD_B 0x1
113#define FMC2_BXTR_EXTMOD_C 0x2
114#define FMC2_BXTR_EXTMOD_D 0x3
115
116#define FMC2_BCR_NBLSET_MAX 0x3
117#define FMC2_BXTR_ADDSET_MAX 0xf
118#define FMC2_BXTR_ADDHLD_MAX 0xf
119#define FMC2_BXTR_DATAST_MAX 0xff
120#define FMC2_BXTR_BUSTURN_MAX 0xf
121#define FMC2_BXTR_DATAHLD_MAX 0x3
122#define FMC2_BTR_CLKDIV_MAX 0xf
123#define FMC2_BTR_DATLAT_MAX 0xf
124#define FMC2_PCSCNTR_CSCOUNT_MAX 0xff
Christophe Kerello34af8b82024-03-06 10:50:46 +0100125#define FMC2_CFGR_CLKDIV_MAX 0xf
Christophe Kerelloa994a802020-07-31 09:53:40 +0200126
Christophe Kerelloa994a802020-07-31 09:53:40 +0200127enum stm32_fmc2_ebi_bank {
128 FMC2_EBI1 = 0,
129 FMC2_EBI2,
130 FMC2_EBI3,
131 FMC2_EBI4,
132 FMC2_NAND
133};
134
135enum stm32_fmc2_ebi_register_type {
136 FMC2_REG_BCR = 1,
137 FMC2_REG_BTR,
138 FMC2_REG_BWTR,
Christophe Kerello34af8b82024-03-06 10:50:46 +0100139 FMC2_REG_PCSCNTR,
140 FMC2_REG_CFGR
Christophe Kerelloa994a802020-07-31 09:53:40 +0200141};
142
143enum stm32_fmc2_ebi_transaction_type {
144 FMC2_ASYNC_MODE_1_SRAM = 0,
145 FMC2_ASYNC_MODE_1_PSRAM,
146 FMC2_ASYNC_MODE_A_SRAM,
147 FMC2_ASYNC_MODE_A_PSRAM,
148 FMC2_ASYNC_MODE_2_NOR,
149 FMC2_ASYNC_MODE_B_NOR,
150 FMC2_ASYNC_MODE_C_NOR,
151 FMC2_ASYNC_MODE_D_NOR,
152 FMC2_SYNC_READ_SYNC_WRITE_PSRAM,
153 FMC2_SYNC_READ_ASYNC_WRITE_PSRAM,
154 FMC2_SYNC_READ_SYNC_WRITE_NOR,
155 FMC2_SYNC_READ_ASYNC_WRITE_NOR
156};
157
158enum stm32_fmc2_ebi_buswidth {
159 FMC2_BUSWIDTH_8 = 8,
160 FMC2_BUSWIDTH_16 = 16
161};
162
163enum stm32_fmc2_ebi_cpsize {
164 FMC2_CPSIZE_0 = 0,
165 FMC2_CPSIZE_128 = 128,
166 FMC2_CPSIZE_256 = 256,
167 FMC2_CPSIZE_512 = 512,
168 FMC2_CPSIZE_1024 = 1024
169};
170
Christophe Kerello34af8b82024-03-06 10:50:46 +0100171enum stm32_fmc2_ebi_cscount {
172 FMC2_CSCOUNT_0 = 0,
173 FMC2_CSCOUNT_1 = 1,
174 FMC2_CSCOUNT_64 = 64,
175 FMC2_CSCOUNT_256 = 256
176};
177
178struct stm32_fmc2_ebi;
179
180struct stm32_fmc2_ebi_data {
181 const struct stm32_fmc2_prop *child_props;
182 unsigned int nb_child_props;
183 u32 fmc2_enable_reg;
184 u32 fmc2_enable_bit;
185 int (*nwait_used_by_ctrls)(struct stm32_fmc2_ebi *ebi);
Christophe Kerello90c38b52024-03-06 10:50:47 +0100186 int (*check_rif)(struct stm32_fmc2_ebi *ebi, u32 resource);
Christophe Kerello34af8b82024-03-06 10:50:46 +0100187};
188
Christophe Kerelloa994a802020-07-31 09:53:40 +0200189struct stm32_fmc2_ebi {
190 struct clk clk;
191 fdt_addr_t io_base;
Christophe Kerello34af8b82024-03-06 10:50:46 +0100192 const struct stm32_fmc2_ebi_data *data;
Christophe Kerelloa994a802020-07-31 09:53:40 +0200193 u8 bank_assigned;
Christophe Kerello90c38b52024-03-06 10:50:47 +0100194 bool access_granted;
Christophe Kerelloa994a802020-07-31 09:53:40 +0200195};
196
197/*
198 * struct stm32_fmc2_prop - STM32 FMC2 EBI property
199 * @name: the device tree binding name of the property
200 * @bprop: indicate that it is a boolean property
201 * @mprop: indicate that it is a mandatory property
202 * @reg_type: the register that have to be modified
203 * @reg_mask: the bit that have to be modified in the selected register
204 * in case of it is a boolean property
205 * @reset_val: the default value that have to be set in case the property
206 * has not been defined in the device tree
207 * @check: this callback ckecks that the property is compliant with the
208 * transaction type selected
209 * @calculate: this callback is called to calculate for exemple a timing
210 * set in nanoseconds in the device tree in clock cycles or in
211 * clock period
212 * @set: this callback applies the values in the registers
213 */
214struct stm32_fmc2_prop {
215 const char *name;
216 bool bprop;
217 bool mprop;
218 int reg_type;
219 u32 reg_mask;
220 u32 reset_val;
221 int (*check)(struct stm32_fmc2_ebi *ebi,
222 const struct stm32_fmc2_prop *prop, int cs);
223 u32 (*calculate)(struct stm32_fmc2_ebi *ebi, int cs, u32 setup);
224 int (*set)(struct stm32_fmc2_ebi *ebi,
225 const struct stm32_fmc2_prop *prop,
226 int cs, u32 setup);
227};
228
229static int stm32_fmc2_ebi_check_mux(struct stm32_fmc2_ebi *ebi,
230 const struct stm32_fmc2_prop *prop,
231 int cs)
232{
233 u32 bcr = readl(ebi->io_base + FMC2_BCR(cs));
234
235 if (bcr & FMC2_BCR_MTYP)
236 return 0;
237
238 return -EINVAL;
239}
240
241static int stm32_fmc2_ebi_check_waitcfg(struct stm32_fmc2_ebi *ebi,
242 const struct stm32_fmc2_prop *prop,
243 int cs)
244{
245 u32 bcr = readl(ebi->io_base + FMC2_BCR(cs));
246 u32 val = FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);
247
248 if ((bcr & FMC2_BCR_MTYP) == val && bcr & FMC2_BCR_BURSTEN)
249 return 0;
250
251 return -EINVAL;
252}
253
254static int stm32_fmc2_ebi_check_sync_trans(struct stm32_fmc2_ebi *ebi,
255 const struct stm32_fmc2_prop *prop,
256 int cs)
257{
258 u32 bcr = readl(ebi->io_base + FMC2_BCR(cs));
259
260 if (bcr & FMC2_BCR_BURSTEN)
261 return 0;
262
263 return -EINVAL;
264}
265
Christophe Kerello90c38b52024-03-06 10:50:47 +0100266static int stm32_fmc2_ebi_mp25_check_cclk(struct stm32_fmc2_ebi *ebi,
267 const struct stm32_fmc2_prop *prop,
268 int cs)
269{
270 if (!ebi->access_granted)
271 return -EACCES;
272
273 return stm32_fmc2_ebi_check_sync_trans(ebi, prop, cs);
274}
275
276static int stm32_fmc2_ebi_mp25_check_clk_period(struct stm32_fmc2_ebi *ebi,
277 const struct stm32_fmc2_prop *prop,
278 int cs)
279{
280 u32 cfgr = readl(ebi->io_base + FMC2_CFGR);
281
282 if (cfgr & FMC2_CFGR_CCLKEN && !ebi->access_granted)
283 return -EACCES;
284
285 return stm32_fmc2_ebi_check_sync_trans(ebi, prop, cs);
286}
287
Christophe Kerelloa994a802020-07-31 09:53:40 +0200288static int stm32_fmc2_ebi_check_async_trans(struct stm32_fmc2_ebi *ebi,
289 const struct stm32_fmc2_prop *prop,
290 int cs)
291{
292 u32 bcr = readl(ebi->io_base + FMC2_BCR(cs));
293
294 if (!(bcr & FMC2_BCR_BURSTEN) || !(bcr & FMC2_BCR_CBURSTRW))
295 return 0;
296
297 return -EINVAL;
298}
299
300static int stm32_fmc2_ebi_check_cpsize(struct stm32_fmc2_ebi *ebi,
301 const struct stm32_fmc2_prop *prop,
302 int cs)
303{
304 u32 bcr = readl(ebi->io_base + FMC2_BCR(cs));
305 u32 val = FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM);
306
307 if ((bcr & FMC2_BCR_MTYP) == val && bcr & FMC2_BCR_BURSTEN)
308 return 0;
309
310 return -EINVAL;
311}
312
313static int stm32_fmc2_ebi_check_address_hold(struct stm32_fmc2_ebi *ebi,
314 const struct stm32_fmc2_prop *prop,
315 int cs)
316{
317 u32 bcr = readl(ebi->io_base + FMC2_BCR(cs));
318 u32 bxtr = prop->reg_type == FMC2_REG_BWTR ?
319 readl(ebi->io_base + FMC2_BWTR(cs)) :
320 readl(ebi->io_base + FMC2_BTR(cs));
321 u32 val = FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D);
322
323 if ((!(bcr & FMC2_BCR_BURSTEN) || !(bcr & FMC2_BCR_CBURSTRW)) &&
324 ((bxtr & FMC2_BXTR_ACCMOD) == val || bcr & FMC2_BCR_MUXEN))
325 return 0;
326
327 return -EINVAL;
328}
329
330static int stm32_fmc2_ebi_check_clk_period(struct stm32_fmc2_ebi *ebi,
331 const struct stm32_fmc2_prop *prop,
332 int cs)
333{
334 u32 bcr = readl(ebi->io_base + FMC2_BCR(cs));
335 u32 bcr1 = cs ? readl(ebi->io_base + FMC2_BCR1) : bcr;
336
337 if (bcr & FMC2_BCR_BURSTEN && (!cs || !(bcr1 & FMC2_BCR1_CCLKEN)))
338 return 0;
339
340 return -EINVAL;
341}
342
343static int stm32_fmc2_ebi_check_cclk(struct stm32_fmc2_ebi *ebi,
344 const struct stm32_fmc2_prop *prop,
345 int cs)
346{
347 if (cs)
348 return -EINVAL;
349
350 return stm32_fmc2_ebi_check_sync_trans(ebi, prop, cs);
351}
352
353static u32 stm32_fmc2_ebi_ns_to_clock_cycles(struct stm32_fmc2_ebi *ebi,
354 int cs, u32 setup)
355{
356 unsigned long hclk = clk_get_rate(&ebi->clk);
Igor Prusovc3421ea2023-11-09 20:10:04 +0300357 unsigned long hclkp = NSEC_PER_SEC / (hclk / 1000);
Christophe Kerelloa994a802020-07-31 09:53:40 +0200358
359 return DIV_ROUND_UP(setup * 1000, hclkp);
360}
361
362static u32 stm32_fmc2_ebi_ns_to_clk_period(struct stm32_fmc2_ebi *ebi,
363 int cs, u32 setup)
364{
365 u32 nb_clk_cycles = stm32_fmc2_ebi_ns_to_clock_cycles(ebi, cs, setup);
366 u32 bcr = readl(ebi->io_base + FMC2_BCR1);
367 u32 btr = bcr & FMC2_BCR1_CCLKEN || !cs ?
368 readl(ebi->io_base + FMC2_BTR1) :
369 readl(ebi->io_base + FMC2_BTR(cs));
370 u32 clk_period = FIELD_GET(FMC2_BTR_CLKDIV, btr) + 1;
371
372 return DIV_ROUND_UP(nb_clk_cycles, clk_period);
373}
374
Christophe Kerello34af8b82024-03-06 10:50:46 +0100375static u32 stm32_fmc2_ebi_mp25_ns_to_clk_period(struct stm32_fmc2_ebi *ebi,
376 int cs, u32 setup)
377{
378 u32 nb_clk_cycles = stm32_fmc2_ebi_ns_to_clock_cycles(ebi, cs, setup);
379 u32 cfgr = readl(ebi->io_base + FMC2_CFGR);
380 u32 clk_period;
381
382 if (cfgr & FMC2_CFGR_CCLKEN) {
383 clk_period = FIELD_GET(FMC2_CFGR_CLKDIV, cfgr) + 1;
384 } else {
385 u32 btr = readl(ebi->io_base + FMC2_BTR(cs));
386
387 clk_period = FIELD_GET(FMC2_BTR_CLKDIV, btr) + 1;
388 }
389
390 return DIV_ROUND_UP(nb_clk_cycles, clk_period);
391}
392
Christophe Kerelloa994a802020-07-31 09:53:40 +0200393static int stm32_fmc2_ebi_get_reg(int reg_type, int cs, u32 *reg)
394{
395 switch (reg_type) {
396 case FMC2_REG_BCR:
397 *reg = FMC2_BCR(cs);
398 break;
399 case FMC2_REG_BTR:
400 *reg = FMC2_BTR(cs);
401 break;
402 case FMC2_REG_BWTR:
403 *reg = FMC2_BWTR(cs);
404 break;
405 case FMC2_REG_PCSCNTR:
406 *reg = FMC2_PCSCNTR;
407 break;
Christophe Kerello34af8b82024-03-06 10:50:46 +0100408 case FMC2_REG_CFGR:
409 *reg = FMC2_CFGR;
410 break;
Christophe Kerelloa994a802020-07-31 09:53:40 +0200411 default:
412 return -EINVAL;
413 }
414
415 return 0;
416}
417
418static int stm32_fmc2_ebi_set_bit_field(struct stm32_fmc2_ebi *ebi,
419 const struct stm32_fmc2_prop *prop,
420 int cs, u32 setup)
421{
422 u32 reg;
423 int ret;
424
425 ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, &reg);
426 if (ret)
427 return ret;
428
429 clrsetbits_le32(ebi->io_base + reg, prop->reg_mask,
430 setup ? prop->reg_mask : 0);
431
432 return 0;
433}
434
435static int stm32_fmc2_ebi_set_trans_type(struct stm32_fmc2_ebi *ebi,
436 const struct stm32_fmc2_prop *prop,
437 int cs, u32 setup)
438{
439 u32 bcr_mask, bcr = FMC2_BCR_WREN;
440 u32 btr_mask, btr = 0;
441 u32 bwtr_mask, bwtr = 0;
442
443 bwtr_mask = FMC2_BXTR_ACCMOD;
444 btr_mask = FMC2_BXTR_ACCMOD;
445 bcr_mask = FMC2_BCR_MUXEN | FMC2_BCR_MTYP | FMC2_BCR_FACCEN |
446 FMC2_BCR_WREN | FMC2_BCR_WAITEN | FMC2_BCR_BURSTEN |
447 FMC2_BCR_EXTMOD | FMC2_BCR_CBURSTRW;
448
449 switch (setup) {
450 case FMC2_ASYNC_MODE_1_SRAM:
451 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_SRAM);
452 /*
453 * MUXEN = 0, MTYP = 0, FACCEN = 0, BURSTEN = 0, WAITEN = 0,
454 * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0
455 */
456 break;
457 case FMC2_ASYNC_MODE_1_PSRAM:
458 /*
459 * MUXEN = 0, MTYP = 1, FACCEN = 0, BURSTEN = 0, WAITEN = 0,
460 * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0
461 */
462 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM);
463 break;
464 case FMC2_ASYNC_MODE_A_SRAM:
465 /*
466 * MUXEN = 0, MTYP = 0, FACCEN = 0, BURSTEN = 0, WAITEN = 0,
467 * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 0
468 */
469 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_SRAM);
470 bcr |= FMC2_BCR_EXTMOD;
471 btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_A);
472 bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_A);
473 break;
474 case FMC2_ASYNC_MODE_A_PSRAM:
475 /*
476 * MUXEN = 0, MTYP = 1, FACCEN = 0, BURSTEN = 0, WAITEN = 0,
477 * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 0
478 */
479 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM);
480 bcr |= FMC2_BCR_EXTMOD;
481 btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_A);
482 bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_A);
483 break;
484 case FMC2_ASYNC_MODE_2_NOR:
485 /*
486 * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 0, WAITEN = 0,
487 * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0
488 */
489 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);
490 bcr |= FMC2_BCR_FACCEN;
491 break;
492 case FMC2_ASYNC_MODE_B_NOR:
493 /*
494 * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 0, WAITEN = 0,
495 * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 1
496 */
497 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);
498 bcr |= FMC2_BCR_FACCEN | FMC2_BCR_EXTMOD;
499 btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_B);
500 bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_B);
501 break;
502 case FMC2_ASYNC_MODE_C_NOR:
503 /*
504 * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 0, WAITEN = 0,
505 * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 2
506 */
507 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);
508 bcr |= FMC2_BCR_FACCEN | FMC2_BCR_EXTMOD;
509 btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_C);
510 bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_C);
511 break;
512 case FMC2_ASYNC_MODE_D_NOR:
513 /*
514 * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 0, WAITEN = 0,
515 * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 3
516 */
517 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);
518 bcr |= FMC2_BCR_FACCEN | FMC2_BCR_EXTMOD;
519 btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D);
520 bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D);
521 break;
522 case FMC2_SYNC_READ_SYNC_WRITE_PSRAM:
523 /*
524 * MUXEN = 0, MTYP = 1, FACCEN = 0, BURSTEN = 1, WAITEN = 0,
525 * WREN = 1, EXTMOD = 0, CBURSTRW = 1, ACCMOD = 0
526 */
527 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM);
528 bcr |= FMC2_BCR_BURSTEN | FMC2_BCR_CBURSTRW;
529 break;
530 case FMC2_SYNC_READ_ASYNC_WRITE_PSRAM:
531 /*
532 * MUXEN = 0, MTYP = 1, FACCEN = 0, BURSTEN = 1, WAITEN = 0,
533 * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0
534 */
535 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM);
536 bcr |= FMC2_BCR_BURSTEN;
537 break;
538 case FMC2_SYNC_READ_SYNC_WRITE_NOR:
539 /*
540 * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 1, WAITEN = 0,
541 * WREN = 1, EXTMOD = 0, CBURSTRW = 1, ACCMOD = 0
542 */
543 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);
544 bcr |= FMC2_BCR_FACCEN | FMC2_BCR_BURSTEN | FMC2_BCR_CBURSTRW;
545 break;
546 case FMC2_SYNC_READ_ASYNC_WRITE_NOR:
547 /*
548 * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 1, WAITEN = 0,
549 * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0
550 */
551 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);
552 bcr |= FMC2_BCR_FACCEN | FMC2_BCR_BURSTEN;
553 break;
554 default:
555 /* Type of transaction not supported */
556 return -EINVAL;
557 }
558
559 if (bcr & FMC2_BCR_EXTMOD)
560 clrsetbits_le32(ebi->io_base + FMC2_BWTR(cs),
561 bwtr_mask, bwtr);
562 clrsetbits_le32(ebi->io_base + FMC2_BTR(cs), btr_mask, btr);
563 clrsetbits_le32(ebi->io_base + FMC2_BCR(cs), bcr_mask, bcr);
564
565 return 0;
566}
567
568static int stm32_fmc2_ebi_set_buswidth(struct stm32_fmc2_ebi *ebi,
569 const struct stm32_fmc2_prop *prop,
570 int cs, u32 setup)
571{
572 u32 val;
573
574 switch (setup) {
575 case FMC2_BUSWIDTH_8:
576 val = FIELD_PREP(FMC2_BCR_MWID, FMC2_BCR_MWID_8);
577 break;
578 case FMC2_BUSWIDTH_16:
579 val = FIELD_PREP(FMC2_BCR_MWID, FMC2_BCR_MWID_16);
580 break;
581 default:
582 /* Buswidth not supported */
583 return -EINVAL;
584 }
585
586 clrsetbits_le32(ebi->io_base + FMC2_BCR(cs), FMC2_BCR_MWID, val);
587
588 return 0;
589}
590
591static int stm32_fmc2_ebi_set_cpsize(struct stm32_fmc2_ebi *ebi,
592 const struct stm32_fmc2_prop *prop,
593 int cs, u32 setup)
594{
595 u32 val;
596
597 switch (setup) {
598 case FMC2_CPSIZE_0:
599 val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_0);
600 break;
601 case FMC2_CPSIZE_128:
602 val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_128);
603 break;
604 case FMC2_CPSIZE_256:
605 val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_256);
606 break;
607 case FMC2_CPSIZE_512:
608 val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_512);
609 break;
610 case FMC2_CPSIZE_1024:
611 val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_1024);
612 break;
613 default:
614 /* Cpsize not supported */
615 return -EINVAL;
616 }
617
618 clrsetbits_le32(ebi->io_base + FMC2_BCR(cs), FMC2_BCR_CPSIZE, val);
619
620 return 0;
621}
622
623static int stm32_fmc2_ebi_set_bl_setup(struct stm32_fmc2_ebi *ebi,
624 const struct stm32_fmc2_prop *prop,
625 int cs, u32 setup)
626{
627 u32 val;
628
629 val = min_t(u32, setup, FMC2_BCR_NBLSET_MAX);
630 val = FIELD_PREP(FMC2_BCR_NBLSET, val);
631 clrsetbits_le32(ebi->io_base + FMC2_BCR(cs), FMC2_BCR_NBLSET, val);
632
633 return 0;
634}
635
636static int stm32_fmc2_ebi_set_address_setup(struct stm32_fmc2_ebi *ebi,
637 const struct stm32_fmc2_prop *prop,
638 int cs, u32 setup)
639{
640 u32 bcr = readl(ebi->io_base + FMC2_BCR(cs));
641 u32 bxtr = prop->reg_type == FMC2_REG_BWTR ?
642 readl(ebi->io_base + FMC2_BWTR(cs)) :
643 readl(ebi->io_base + FMC2_BTR(cs));
644 u32 reg, val = FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D);
645 int ret;
646
647 ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, &reg);
648 if (ret)
649 return ret;
650
651 if ((bxtr & FMC2_BXTR_ACCMOD) == val || bcr & FMC2_BCR_MUXEN)
652 val = clamp_val(setup, 1, FMC2_BXTR_ADDSET_MAX);
653 else
654 val = min_t(u32, setup, FMC2_BXTR_ADDSET_MAX);
655 val = FIELD_PREP(FMC2_BXTR_ADDSET, val);
656 clrsetbits_le32(ebi->io_base + reg, FMC2_BXTR_ADDSET, val);
657
658 return 0;
659}
660
661static int stm32_fmc2_ebi_set_address_hold(struct stm32_fmc2_ebi *ebi,
662 const struct stm32_fmc2_prop *prop,
663 int cs, u32 setup)
664{
665 u32 val, reg;
666 int ret;
667
668 ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, &reg);
669 if (ret)
670 return ret;
671
672 val = clamp_val(setup, 1, FMC2_BXTR_ADDHLD_MAX);
673 val = FIELD_PREP(FMC2_BXTR_ADDHLD, val);
674 clrsetbits_le32(ebi->io_base + reg, FMC2_BXTR_ADDHLD, val);
675
676 return 0;
677}
678
679static int stm32_fmc2_ebi_set_data_setup(struct stm32_fmc2_ebi *ebi,
680 const struct stm32_fmc2_prop *prop,
681 int cs, u32 setup)
682{
683 u32 val, reg;
684 int ret;
685
686 ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, &reg);
687 if (ret)
688 return ret;
689
690 val = clamp_val(setup, 1, FMC2_BXTR_DATAST_MAX);
691 val = FIELD_PREP(FMC2_BXTR_DATAST, val);
692 clrsetbits_le32(ebi->io_base + reg, FMC2_BXTR_DATAST, val);
693
694 return 0;
695}
696
697static int stm32_fmc2_ebi_set_bus_turnaround(struct stm32_fmc2_ebi *ebi,
698 const struct stm32_fmc2_prop *prop,
699 int cs, u32 setup)
700{
701 u32 val, reg;
702 int ret;
703
704 ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, &reg);
705 if (ret)
706 return ret;
707
708 val = setup ? min_t(u32, setup - 1, FMC2_BXTR_BUSTURN_MAX) : 0;
709 val = FIELD_PREP(FMC2_BXTR_BUSTURN, val);
710 clrsetbits_le32(ebi->io_base + reg, FMC2_BXTR_BUSTURN, val);
711
712 return 0;
713}
714
715static int stm32_fmc2_ebi_set_data_hold(struct stm32_fmc2_ebi *ebi,
716 const struct stm32_fmc2_prop *prop,
717 int cs, u32 setup)
718{
719 u32 val, reg;
720 int ret;
721
722 ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, &reg);
723 if (ret)
724 return ret;
725
726 if (prop->reg_type == FMC2_REG_BWTR)
727 val = setup ? min_t(u32, setup - 1, FMC2_BXTR_DATAHLD_MAX) : 0;
728 else
729 val = min_t(u32, setup, FMC2_BXTR_DATAHLD_MAX);
730 val = FIELD_PREP(FMC2_BXTR_DATAHLD, val);
731 clrsetbits_le32(ebi->io_base + reg, FMC2_BXTR_DATAHLD, val);
732
733 return 0;
734}
735
736static int stm32_fmc2_ebi_set_clk_period(struct stm32_fmc2_ebi *ebi,
737 const struct stm32_fmc2_prop *prop,
738 int cs, u32 setup)
739{
740 u32 val;
741
742 val = setup ? clamp_val(setup - 1, 1, FMC2_BTR_CLKDIV_MAX) : 1;
743 val = FIELD_PREP(FMC2_BTR_CLKDIV, val);
744 clrsetbits_le32(ebi->io_base + FMC2_BTR(cs), FMC2_BTR_CLKDIV, val);
745
746 return 0;
747}
748
Christophe Kerello34af8b82024-03-06 10:50:46 +0100749static int stm32_fmc2_ebi_mp25_set_clk_period(struct stm32_fmc2_ebi *ebi,
750 const struct stm32_fmc2_prop *prop,
751 int cs, u32 setup)
752{
753 u32 cfgr = readl(ebi->io_base + FMC2_CFGR);
754 u32 val;
755
756 if (cfgr & FMC2_CFGR_CCLKEN) {
757 val = setup ? clamp_val(setup - 1, 1, FMC2_CFGR_CLKDIV_MAX) : 1;
758 val = FIELD_PREP(FMC2_CFGR_CLKDIV, val);
759 clrsetbits_le32(ebi->io_base + FMC2_CFGR, FMC2_CFGR_CLKDIV, val);
760 } else {
761 val = setup ? clamp_val(setup - 1, 1, FMC2_BTR_CLKDIV_MAX) : 1;
762 val = FIELD_PREP(FMC2_BTR_CLKDIV, val);
763 clrsetbits_le32(ebi->io_base + FMC2_BTR(cs), FMC2_BTR_CLKDIV, val);
764 }
765
766 return 0;
767}
768
Christophe Kerelloa994a802020-07-31 09:53:40 +0200769static int stm32_fmc2_ebi_set_data_latency(struct stm32_fmc2_ebi *ebi,
770 const struct stm32_fmc2_prop *prop,
771 int cs, u32 setup)
772{
773 u32 val;
774
775 val = setup > 1 ? min_t(u32, setup - 2, FMC2_BTR_DATLAT_MAX) : 0;
776 val = FIELD_PREP(FMC2_BTR_DATLAT, val);
777 clrsetbits_le32(ebi->io_base + FMC2_BTR(cs), FMC2_BTR_DATLAT, val);
778
779 return 0;
780}
781
782static int stm32_fmc2_ebi_set_max_low_pulse(struct stm32_fmc2_ebi *ebi,
783 const struct stm32_fmc2_prop *prop,
784 int cs, u32 setup)
785{
786 u32 old_val, new_val, pcscntr;
787
788 if (setup < 1)
789 return 0;
790
791 pcscntr = readl(ebi->io_base + FMC2_PCSCNTR);
792
793 /* Enable counter for the bank */
794 setbits_le32(ebi->io_base + FMC2_PCSCNTR, FMC2_PCSCNTR_CNTBEN(cs));
795
796 new_val = min_t(u32, setup - 1, FMC2_PCSCNTR_CSCOUNT_MAX);
797 old_val = FIELD_GET(FMC2_PCSCNTR_CSCOUNT, pcscntr);
798 if (old_val && new_val > old_val)
799 /* Keep current counter value */
800 return 0;
801
802 new_val = FIELD_PREP(FMC2_PCSCNTR_CSCOUNT, new_val);
803 clrsetbits_le32(ebi->io_base + FMC2_PCSCNTR,
804 FMC2_PCSCNTR_CSCOUNT, new_val);
805
806 return 0;
807}
808
Christophe Kerello34af8b82024-03-06 10:50:46 +0100809static int stm32_fmc2_ebi_mp25_set_max_low_pulse(struct stm32_fmc2_ebi *ebi,
810 const struct stm32_fmc2_prop *prop,
811 int cs, u32 setup)
812{
813 u32 val;
814
815 if (setup == FMC2_CSCOUNT_0)
816 val = FIELD_PREP(FMC2_BCR_CSCOUNT, FMC2_BCR_CSCOUNT_0);
817 else if (setup == FMC2_CSCOUNT_1)
818 val = FIELD_PREP(FMC2_BCR_CSCOUNT, FMC2_BCR_CSCOUNT_1);
819 else if (setup <= FMC2_CSCOUNT_64)
820 val = FIELD_PREP(FMC2_BCR_CSCOUNT, FMC2_BCR_CSCOUNT_64);
821 else
822 val = FIELD_PREP(FMC2_BCR_CSCOUNT, FMC2_BCR_CSCOUNT_256);
823
824 clrsetbits_le32(ebi->io_base + FMC2_BCR(cs),
825 FMC2_BCR_CSCOUNT, val);
826
827 return 0;
828}
829
Christophe Kerelloa994a802020-07-31 09:53:40 +0200830static const struct stm32_fmc2_prop stm32_fmc2_child_props[] = {
831 /* st,fmc2-ebi-cs-trans-type must be the first property */
832 {
833 .name = "st,fmc2-ebi-cs-transaction-type",
834 .mprop = true,
835 .set = stm32_fmc2_ebi_set_trans_type,
836 },
837 {
838 .name = "st,fmc2-ebi-cs-cclk-enable",
839 .bprop = true,
840 .reg_type = FMC2_REG_BCR,
841 .reg_mask = FMC2_BCR1_CCLKEN,
842 .check = stm32_fmc2_ebi_check_cclk,
843 .set = stm32_fmc2_ebi_set_bit_field,
844 },
845 {
846 .name = "st,fmc2-ebi-cs-mux-enable",
847 .bprop = true,
848 .reg_type = FMC2_REG_BCR,
849 .reg_mask = FMC2_BCR_MUXEN,
850 .check = stm32_fmc2_ebi_check_mux,
851 .set = stm32_fmc2_ebi_set_bit_field,
852 },
853 {
854 .name = "st,fmc2-ebi-cs-buswidth",
855 .reset_val = FMC2_BUSWIDTH_16,
856 .set = stm32_fmc2_ebi_set_buswidth,
857 },
858 {
859 .name = "st,fmc2-ebi-cs-waitpol-high",
860 .bprop = true,
861 .reg_type = FMC2_REG_BCR,
862 .reg_mask = FMC2_BCR_WAITPOL,
863 .set = stm32_fmc2_ebi_set_bit_field,
864 },
865 {
866 .name = "st,fmc2-ebi-cs-waitcfg-enable",
867 .bprop = true,
868 .reg_type = FMC2_REG_BCR,
869 .reg_mask = FMC2_BCR_WAITCFG,
870 .check = stm32_fmc2_ebi_check_waitcfg,
871 .set = stm32_fmc2_ebi_set_bit_field,
872 },
873 {
874 .name = "st,fmc2-ebi-cs-wait-enable",
875 .bprop = true,
876 .reg_type = FMC2_REG_BCR,
877 .reg_mask = FMC2_BCR_WAITEN,
878 .check = stm32_fmc2_ebi_check_sync_trans,
879 .set = stm32_fmc2_ebi_set_bit_field,
880 },
881 {
882 .name = "st,fmc2-ebi-cs-asyncwait-enable",
883 .bprop = true,
884 .reg_type = FMC2_REG_BCR,
885 .reg_mask = FMC2_BCR_ASYNCWAIT,
886 .check = stm32_fmc2_ebi_check_async_trans,
887 .set = stm32_fmc2_ebi_set_bit_field,
888 },
889 {
890 .name = "st,fmc2-ebi-cs-cpsize",
891 .check = stm32_fmc2_ebi_check_cpsize,
892 .set = stm32_fmc2_ebi_set_cpsize,
893 },
894 {
895 .name = "st,fmc2-ebi-cs-byte-lane-setup-ns",
896 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
897 .set = stm32_fmc2_ebi_set_bl_setup,
898 },
899 {
900 .name = "st,fmc2-ebi-cs-address-setup-ns",
901 .reg_type = FMC2_REG_BTR,
902 .reset_val = FMC2_BXTR_ADDSET_MAX,
903 .check = stm32_fmc2_ebi_check_async_trans,
904 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
905 .set = stm32_fmc2_ebi_set_address_setup,
906 },
907 {
908 .name = "st,fmc2-ebi-cs-address-hold-ns",
909 .reg_type = FMC2_REG_BTR,
910 .reset_val = FMC2_BXTR_ADDHLD_MAX,
911 .check = stm32_fmc2_ebi_check_address_hold,
912 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
913 .set = stm32_fmc2_ebi_set_address_hold,
914 },
915 {
916 .name = "st,fmc2-ebi-cs-data-setup-ns",
917 .reg_type = FMC2_REG_BTR,
918 .reset_val = FMC2_BXTR_DATAST_MAX,
919 .check = stm32_fmc2_ebi_check_async_trans,
920 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
921 .set = stm32_fmc2_ebi_set_data_setup,
922 },
923 {
924 .name = "st,fmc2-ebi-cs-bus-turnaround-ns",
925 .reg_type = FMC2_REG_BTR,
926 .reset_val = FMC2_BXTR_BUSTURN_MAX + 1,
927 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
928 .set = stm32_fmc2_ebi_set_bus_turnaround,
929 },
930 {
931 .name = "st,fmc2-ebi-cs-data-hold-ns",
932 .reg_type = FMC2_REG_BTR,
933 .check = stm32_fmc2_ebi_check_async_trans,
934 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
935 .set = stm32_fmc2_ebi_set_data_hold,
936 },
937 {
938 .name = "st,fmc2-ebi-cs-clk-period-ns",
939 .reset_val = FMC2_BTR_CLKDIV_MAX + 1,
940 .check = stm32_fmc2_ebi_check_clk_period,
941 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
942 .set = stm32_fmc2_ebi_set_clk_period,
943 },
944 {
945 .name = "st,fmc2-ebi-cs-data-latency-ns",
946 .check = stm32_fmc2_ebi_check_sync_trans,
947 .calculate = stm32_fmc2_ebi_ns_to_clk_period,
948 .set = stm32_fmc2_ebi_set_data_latency,
949 },
950 {
951 .name = "st,fmc2-ebi-cs-write-address-setup-ns",
952 .reg_type = FMC2_REG_BWTR,
953 .reset_val = FMC2_BXTR_ADDSET_MAX,
954 .check = stm32_fmc2_ebi_check_async_trans,
955 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
956 .set = stm32_fmc2_ebi_set_address_setup,
957 },
958 {
959 .name = "st,fmc2-ebi-cs-write-address-hold-ns",
960 .reg_type = FMC2_REG_BWTR,
961 .reset_val = FMC2_BXTR_ADDHLD_MAX,
962 .check = stm32_fmc2_ebi_check_address_hold,
963 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
964 .set = stm32_fmc2_ebi_set_address_hold,
965 },
966 {
967 .name = "st,fmc2-ebi-cs-write-data-setup-ns",
968 .reg_type = FMC2_REG_BWTR,
969 .reset_val = FMC2_BXTR_DATAST_MAX,
970 .check = stm32_fmc2_ebi_check_async_trans,
971 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
972 .set = stm32_fmc2_ebi_set_data_setup,
973 },
974 {
975 .name = "st,fmc2-ebi-cs-write-bus-turnaround-ns",
976 .reg_type = FMC2_REG_BWTR,
977 .reset_val = FMC2_BXTR_BUSTURN_MAX + 1,
978 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
979 .set = stm32_fmc2_ebi_set_bus_turnaround,
980 },
981 {
982 .name = "st,fmc2-ebi-cs-write-data-hold-ns",
983 .reg_type = FMC2_REG_BWTR,
984 .check = stm32_fmc2_ebi_check_async_trans,
985 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
986 .set = stm32_fmc2_ebi_set_data_hold,
987 },
988 {
989 .name = "st,fmc2-ebi-cs-max-low-pulse-ns",
990 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
991 .set = stm32_fmc2_ebi_set_max_low_pulse,
992 },
993};
994
Christophe Kerello34af8b82024-03-06 10:50:46 +0100995static const struct stm32_fmc2_prop stm32_fmc2_mp25_child_props[] = {
996 /* st,fmc2-ebi-cs-trans-type must be the first property */
997 {
998 .name = "st,fmc2-ebi-cs-transaction-type",
999 .mprop = true,
1000 .set = stm32_fmc2_ebi_set_trans_type,
1001 },
1002 {
1003 .name = "st,fmc2-ebi-cs-cclk-enable",
1004 .bprop = true,
1005 .reg_type = FMC2_REG_CFGR,
1006 .reg_mask = FMC2_CFGR_CCLKEN,
Christophe Kerello90c38b52024-03-06 10:50:47 +01001007 .check = stm32_fmc2_ebi_mp25_check_cclk,
Christophe Kerello34af8b82024-03-06 10:50:46 +01001008 .set = stm32_fmc2_ebi_set_bit_field,
1009 },
1010 {
1011 .name = "st,fmc2-ebi-cs-mux-enable",
1012 .bprop = true,
1013 .reg_type = FMC2_REG_BCR,
1014 .reg_mask = FMC2_BCR_MUXEN,
1015 .check = stm32_fmc2_ebi_check_mux,
1016 .set = stm32_fmc2_ebi_set_bit_field,
1017 },
1018 {
1019 .name = "st,fmc2-ebi-cs-buswidth",
1020 .reset_val = FMC2_BUSWIDTH_16,
1021 .set = stm32_fmc2_ebi_set_buswidth,
1022 },
1023 {
1024 .name = "st,fmc2-ebi-cs-waitpol-high",
1025 .bprop = true,
1026 .reg_type = FMC2_REG_BCR,
1027 .reg_mask = FMC2_BCR_WAITPOL,
1028 .set = stm32_fmc2_ebi_set_bit_field,
1029 },
1030 {
1031 .name = "st,fmc2-ebi-cs-waitcfg-enable",
1032 .bprop = true,
1033 .reg_type = FMC2_REG_BCR,
1034 .reg_mask = FMC2_BCR_WAITCFG,
1035 .check = stm32_fmc2_ebi_check_waitcfg,
1036 .set = stm32_fmc2_ebi_set_bit_field,
1037 },
1038 {
1039 .name = "st,fmc2-ebi-cs-wait-enable",
1040 .bprop = true,
1041 .reg_type = FMC2_REG_BCR,
1042 .reg_mask = FMC2_BCR_WAITEN,
1043 .check = stm32_fmc2_ebi_check_sync_trans,
1044 .set = stm32_fmc2_ebi_set_bit_field,
1045 },
1046 {
1047 .name = "st,fmc2-ebi-cs-asyncwait-enable",
1048 .bprop = true,
1049 .reg_type = FMC2_REG_BCR,
1050 .reg_mask = FMC2_BCR_ASYNCWAIT,
1051 .check = stm32_fmc2_ebi_check_async_trans,
1052 .set = stm32_fmc2_ebi_set_bit_field,
1053 },
1054 {
1055 .name = "st,fmc2-ebi-cs-cpsize",
1056 .check = stm32_fmc2_ebi_check_cpsize,
1057 .set = stm32_fmc2_ebi_set_cpsize,
1058 },
1059 {
1060 .name = "st,fmc2-ebi-cs-byte-lane-setup-ns",
1061 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1062 .set = stm32_fmc2_ebi_set_bl_setup,
1063 },
1064 {
1065 .name = "st,fmc2-ebi-cs-address-setup-ns",
1066 .reg_type = FMC2_REG_BTR,
1067 .reset_val = FMC2_BXTR_ADDSET_MAX,
1068 .check = stm32_fmc2_ebi_check_async_trans,
1069 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1070 .set = stm32_fmc2_ebi_set_address_setup,
1071 },
1072 {
1073 .name = "st,fmc2-ebi-cs-address-hold-ns",
1074 .reg_type = FMC2_REG_BTR,
1075 .reset_val = FMC2_BXTR_ADDHLD_MAX,
1076 .check = stm32_fmc2_ebi_check_address_hold,
1077 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1078 .set = stm32_fmc2_ebi_set_address_hold,
1079 },
1080 {
1081 .name = "st,fmc2-ebi-cs-data-setup-ns",
1082 .reg_type = FMC2_REG_BTR,
1083 .reset_val = FMC2_BXTR_DATAST_MAX,
1084 .check = stm32_fmc2_ebi_check_async_trans,
1085 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1086 .set = stm32_fmc2_ebi_set_data_setup,
1087 },
1088 {
1089 .name = "st,fmc2-ebi-cs-bus-turnaround-ns",
1090 .reg_type = FMC2_REG_BTR,
1091 .reset_val = FMC2_BXTR_BUSTURN_MAX + 1,
1092 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1093 .set = stm32_fmc2_ebi_set_bus_turnaround,
1094 },
1095 {
1096 .name = "st,fmc2-ebi-cs-data-hold-ns",
1097 .reg_type = FMC2_REG_BTR,
1098 .check = stm32_fmc2_ebi_check_async_trans,
1099 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1100 .set = stm32_fmc2_ebi_set_data_hold,
1101 },
1102 {
1103 .name = "st,fmc2-ebi-cs-clk-period-ns",
1104 .reset_val = FMC2_CFGR_CLKDIV_MAX + 1,
Christophe Kerello90c38b52024-03-06 10:50:47 +01001105 .check = stm32_fmc2_ebi_mp25_check_clk_period,
Christophe Kerello34af8b82024-03-06 10:50:46 +01001106 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1107 .set = stm32_fmc2_ebi_mp25_set_clk_period,
1108 },
1109 {
1110 .name = "st,fmc2-ebi-cs-data-latency-ns",
1111 .check = stm32_fmc2_ebi_check_sync_trans,
1112 .calculate = stm32_fmc2_ebi_mp25_ns_to_clk_period,
1113 .set = stm32_fmc2_ebi_set_data_latency,
1114 },
1115 {
1116 .name = "st,fmc2-ebi-cs-write-address-setup-ns",
1117 .reg_type = FMC2_REG_BWTR,
1118 .reset_val = FMC2_BXTR_ADDSET_MAX,
1119 .check = stm32_fmc2_ebi_check_async_trans,
1120 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1121 .set = stm32_fmc2_ebi_set_address_setup,
1122 },
1123 {
1124 .name = "st,fmc2-ebi-cs-write-address-hold-ns",
1125 .reg_type = FMC2_REG_BWTR,
1126 .reset_val = FMC2_BXTR_ADDHLD_MAX,
1127 .check = stm32_fmc2_ebi_check_address_hold,
1128 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1129 .set = stm32_fmc2_ebi_set_address_hold,
1130 },
1131 {
1132 .name = "st,fmc2-ebi-cs-write-data-setup-ns",
1133 .reg_type = FMC2_REG_BWTR,
1134 .reset_val = FMC2_BXTR_DATAST_MAX,
1135 .check = stm32_fmc2_ebi_check_async_trans,
1136 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1137 .set = stm32_fmc2_ebi_set_data_setup,
1138 },
1139 {
1140 .name = "st,fmc2-ebi-cs-write-bus-turnaround-ns",
1141 .reg_type = FMC2_REG_BWTR,
1142 .reset_val = FMC2_BXTR_BUSTURN_MAX + 1,
1143 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1144 .set = stm32_fmc2_ebi_set_bus_turnaround,
1145 },
1146 {
1147 .name = "st,fmc2-ebi-cs-write-data-hold-ns",
1148 .reg_type = FMC2_REG_BWTR,
1149 .check = stm32_fmc2_ebi_check_async_trans,
1150 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1151 .set = stm32_fmc2_ebi_set_data_hold,
1152 },
1153 {
1154 .name = "st,fmc2-ebi-cs-max-low-pulse-ns",
1155 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
1156 .set = stm32_fmc2_ebi_mp25_set_max_low_pulse,
1157 },
1158};
1159
Christophe Kerello90c38b52024-03-06 10:50:47 +01001160static int stm32_fmc2_ebi_mp25_check_rif(struct stm32_fmc2_ebi *ebi, u32 resource)
1161{
1162 u32 seccfgr, cidcfgr, semcr;
1163 int cid;
1164
1165 if (resource >= FMC2_MAX_RESOURCES)
1166 return -EINVAL;
1167
1168 seccfgr = readl(ebi->io_base + FMC2_SECCFGR);
1169 if (seccfgr & BIT(resource)) {
1170 if (resource)
1171 log_err("resource %d is configured as secure\n",
1172 resource);
1173
1174 return -EACCES;
1175 }
1176
1177 cidcfgr = readl(ebi->io_base + FMC2_CIDCFGR(resource));
1178 if (!(cidcfgr & FMC2_CIDCFGR_CFEN))
1179 /* CID filtering is turned off: access granted */
1180 return 0;
1181
1182 if (!(cidcfgr & FMC2_CIDCFGR_SEMEN)) {
1183 /* Static CID mode */
1184 cid = FIELD_GET(FMC2_CIDCFGR_SCID, cidcfgr);
1185 if (cid != FMC2_CID1) {
1186 if (resource)
1187 log_err("static CID%d set for resource %d\n",
1188 cid, resource);
1189
1190 return -EACCES;
1191 }
1192
1193 return 0;
1194 }
1195
1196 /* Pass-list with semaphore mode */
1197 if (!(cidcfgr & FMC2_CIDCFGR_SEMWLC1)) {
1198 if (resource)
1199 log_err("CID1 is block-listed for resource %d\n",
1200 resource);
1201
1202 return -EACCES;
1203 }
1204
1205 semcr = readl(ebi->io_base + FMC2_SEMCR(resource));
1206 if (!(semcr & FMC2_SEMCR_SEM_MUTEX)) {
1207 setbits_le32(ebi->io_base + FMC2_SEMCR(resource),
1208 FMC2_SEMCR_SEM_MUTEX);
1209 semcr = readl(ebi->io_base + FMC2_SEMCR(resource));
1210 }
1211
1212 cid = FIELD_GET(FMC2_SEMCR_SEMCID, semcr);
1213 if (cid != FMC2_CID1) {
1214 if (resource)
1215 log_err("resource %d is already used by CID%d\n",
1216 resource, cid);
1217
1218 return -EACCES;
1219 }
1220
1221 return 0;
1222}
1223
Christophe Kerelloa994a802020-07-31 09:53:40 +02001224static int stm32_fmc2_ebi_parse_prop(struct stm32_fmc2_ebi *ebi,
1225 ofnode node,
1226 const struct stm32_fmc2_prop *prop,
1227 int cs)
1228{
1229 u32 setup = 0;
1230
1231 if (!prop->set) {
Patrick Delaunay729ecfd2020-11-06 19:01:55 +01001232 log_err("property %s is not well defined\n", prop->name);
Christophe Kerelloa994a802020-07-31 09:53:40 +02001233 return -EINVAL;
1234 }
1235
1236 if (prop->check && prop->check(ebi, prop, cs))
1237 /* Skip this property */
1238 return 0;
1239
1240 if (prop->bprop) {
1241 bool bprop;
1242
1243 bprop = ofnode_read_bool(node, prop->name);
1244 if (prop->mprop && !bprop) {
Patrick Delaunay729ecfd2020-11-06 19:01:55 +01001245 log_err("mandatory property %s not defined in the device tree\n",
1246 prop->name);
Christophe Kerelloa994a802020-07-31 09:53:40 +02001247 return -EINVAL;
1248 }
1249
1250 if (bprop)
1251 setup = 1;
1252 } else {
1253 u32 val;
1254 int ret;
1255
1256 ret = ofnode_read_u32(node, prop->name, &val);
1257 if (prop->mprop && ret) {
Patrick Delaunay729ecfd2020-11-06 19:01:55 +01001258 log_err("mandatory property %s not defined in the device tree\n",
1259 prop->name);
Christophe Kerelloa994a802020-07-31 09:53:40 +02001260 return ret;
1261 }
1262
1263 if (ret)
1264 setup = prop->reset_val;
1265 else if (prop->calculate)
1266 setup = prop->calculate(ebi, cs, val);
1267 else
1268 setup = val;
1269 }
1270
1271 return prop->set(ebi, prop, cs, setup);
1272}
1273
1274static void stm32_fmc2_ebi_enable_bank(struct stm32_fmc2_ebi *ebi, int cs)
1275{
1276 setbits_le32(ebi->io_base + FMC2_BCR(cs), FMC2_BCR_MBKEN);
1277}
1278
1279static void stm32_fmc2_ebi_disable_bank(struct stm32_fmc2_ebi *ebi, int cs)
1280{
1281 clrbits_le32(ebi->io_base + FMC2_BCR(cs), FMC2_BCR_MBKEN);
1282}
1283
1284/* NWAIT signal can not be connected to EBI controller and NAND controller */
Christophe Kerello34af8b82024-03-06 10:50:46 +01001285static int stm32_fmc2_ebi_nwait_used_by_ctrls(struct stm32_fmc2_ebi *ebi)
Christophe Kerelloa994a802020-07-31 09:53:40 +02001286{
1287 unsigned int cs;
1288 u32 bcr;
1289
1290 for (cs = 0; cs < FMC2_MAX_EBI_CE; cs++) {
1291 if (!(ebi->bank_assigned & BIT(cs)))
1292 continue;
1293
1294 bcr = readl(ebi->io_base + FMC2_BCR(cs));
1295 if ((bcr & FMC2_BCR_WAITEN || bcr & FMC2_BCR_ASYNCWAIT) &&
Christophe Kerello34af8b82024-03-06 10:50:46 +01001296 ebi->bank_assigned & BIT(FMC2_NAND)) {
1297 log_err("NWAIT signal connected to EBI and NAND controllers\n");
1298 return -EINVAL;
1299 }
Christophe Kerelloa994a802020-07-31 09:53:40 +02001300 }
1301
Christophe Kerello34af8b82024-03-06 10:50:46 +01001302 return 0;
Christophe Kerelloa994a802020-07-31 09:53:40 +02001303}
1304
1305static void stm32_fmc2_ebi_enable(struct stm32_fmc2_ebi *ebi)
1306{
Christophe Kerello90c38b52024-03-06 10:50:47 +01001307 if (!ebi->access_granted)
1308 return;
1309
Christophe Kerello34af8b82024-03-06 10:50:46 +01001310 setbits_le32(ebi->io_base + ebi->data->fmc2_enable_reg,
1311 ebi->data->fmc2_enable_bit);
Christophe Kerelloa994a802020-07-31 09:53:40 +02001312}
1313
1314static int stm32_fmc2_ebi_setup_cs(struct stm32_fmc2_ebi *ebi,
1315 ofnode node, u32 cs)
1316{
1317 unsigned int i;
1318 int ret;
1319
1320 stm32_fmc2_ebi_disable_bank(ebi, cs);
1321
Christophe Kerello34af8b82024-03-06 10:50:46 +01001322 for (i = 0; i < ebi->data->nb_child_props; i++) {
1323 const struct stm32_fmc2_prop *p = &ebi->data->child_props[i];
Christophe Kerelloa994a802020-07-31 09:53:40 +02001324
1325 ret = stm32_fmc2_ebi_parse_prop(ebi, node, p, cs);
1326 if (ret) {
Patrick Delaunay729ecfd2020-11-06 19:01:55 +01001327 log_err("property %s could not be set: %d\n",
1328 p->name, ret);
Christophe Kerelloa994a802020-07-31 09:53:40 +02001329 return ret;
1330 }
1331 }
1332
1333 stm32_fmc2_ebi_enable_bank(ebi, cs);
1334
1335 return 0;
1336}
1337
1338static int stm32_fmc2_ebi_parse_dt(struct udevice *dev,
1339 struct stm32_fmc2_ebi *ebi)
1340{
1341 ofnode child;
1342 bool child_found = false;
1343 u32 bank;
1344 int ret;
1345
1346 dev_for_each_subnode(child, dev) {
1347 ret = ofnode_read_u32(child, "reg", &bank);
1348 if (ret) {
Patrick Delaunay729ecfd2020-11-06 19:01:55 +01001349 dev_err(dev, "could not retrieve reg property: %d\n", ret);
Christophe Kerelloa994a802020-07-31 09:53:40 +02001350 return ret;
1351 }
1352
1353 if (bank >= FMC2_MAX_BANKS) {
Patrick Delaunay729ecfd2020-11-06 19:01:55 +01001354 dev_err(dev, "invalid reg value: %d\n", bank);
Christophe Kerelloa994a802020-07-31 09:53:40 +02001355 return -EINVAL;
1356 }
1357
1358 if (ebi->bank_assigned & BIT(bank)) {
Patrick Delaunay729ecfd2020-11-06 19:01:55 +01001359 dev_err(dev, "bank already assigned: %d\n", bank);
Christophe Kerelloa994a802020-07-31 09:53:40 +02001360 return -EINVAL;
1361 }
1362
Christophe Kerello90c38b52024-03-06 10:50:47 +01001363 if (ebi->data->check_rif) {
1364 ret = ebi->data->check_rif(ebi, bank + 1);
1365 if (ret) {
1366 dev_err(dev, "bank access failed: %d\n", bank);
1367 return ret;
1368 }
1369 }
1370
Christophe Kerelloa994a802020-07-31 09:53:40 +02001371 if (bank < FMC2_MAX_EBI_CE) {
1372 ret = stm32_fmc2_ebi_setup_cs(ebi, child, bank);
1373 if (ret) {
Patrick Delaunay729ecfd2020-11-06 19:01:55 +01001374 dev_err(dev, "setup chip select %d failed: %d\n", bank, ret);
Christophe Kerelloa994a802020-07-31 09:53:40 +02001375 return ret;
1376 }
1377 }
1378
1379 ebi->bank_assigned |= BIT(bank);
1380 child_found = true;
1381 }
1382
1383 if (!child_found) {
Patrick Delaunay729ecfd2020-11-06 19:01:55 +01001384 dev_warn(dev, "no subnodes found, disable the driver.\n");
Christophe Kerelloa994a802020-07-31 09:53:40 +02001385 return -ENODEV;
1386 }
1387
Christophe Kerello34af8b82024-03-06 10:50:46 +01001388 if (ebi->data->nwait_used_by_ctrls) {
1389 ret = ebi->data->nwait_used_by_ctrls(ebi);
1390 if (ret)
1391 return ret;
Christophe Kerelloa994a802020-07-31 09:53:40 +02001392 }
1393
1394 stm32_fmc2_ebi_enable(ebi);
1395
1396 return 0;
1397}
1398
1399static int stm32_fmc2_ebi_probe(struct udevice *dev)
1400{
1401 struct stm32_fmc2_ebi *ebi = dev_get_priv(dev);
1402 struct reset_ctl reset;
1403 int ret;
1404
Christophe Kerello34af8b82024-03-06 10:50:46 +01001405 ebi->data = (void *)dev_get_driver_data(dev);
1406 if (!ebi->data)
1407 return -EINVAL;
1408
Christophe Kerelloa994a802020-07-31 09:53:40 +02001409 ebi->io_base = dev_read_addr(dev);
1410 if (ebi->io_base == FDT_ADDR_T_NONE)
1411 return -EINVAL;
1412
1413 ret = clk_get_by_index(dev, 0, &ebi->clk);
1414 if (ret)
1415 return ret;
1416
1417 ret = clk_enable(&ebi->clk);
1418 if (ret)
1419 return ret;
1420
1421 ret = reset_get_by_index(dev, 0, &reset);
1422 if (!ret) {
1423 reset_assert(&reset);
1424 udelay(2);
1425 reset_deassert(&reset);
1426 }
1427
Christophe Kerello90c38b52024-03-06 10:50:47 +01001428 /* Check if CFGR register can be modified */
1429 ebi->access_granted = true;
1430 if (ebi->data->check_rif) {
1431 ret = ebi->data->check_rif(ebi, 0);
1432 if (ret) {
1433 ebi->access_granted = false;
1434
1435 /* In case of CFGR is secure, just check that the FMC2 is enabled */
1436 if (readl(ebi->io_base + FMC2_SR) & FMC2_SR_ISOST) {
1437 dev_err(dev, "FMC2 is not ready to be used.\n");
1438 return -EACCES;
1439 }
1440 }
1441 }
1442
Christophe Kerelloa994a802020-07-31 09:53:40 +02001443 return stm32_fmc2_ebi_parse_dt(dev, ebi);
1444}
1445
Christophe Kerello34af8b82024-03-06 10:50:46 +01001446static const struct stm32_fmc2_ebi_data stm32_fmc2_ebi_mp1_data = {
1447 .child_props = stm32_fmc2_child_props,
1448 .nb_child_props = ARRAY_SIZE(stm32_fmc2_child_props),
1449 .fmc2_enable_reg = FMC2_BCR1,
1450 .fmc2_enable_bit = FMC2_BCR1_FMC2EN,
1451 .nwait_used_by_ctrls = stm32_fmc2_ebi_nwait_used_by_ctrls,
1452};
1453
1454static const struct stm32_fmc2_ebi_data stm32_fmc2_ebi_mp25_data = {
1455 .child_props = stm32_fmc2_mp25_child_props,
1456 .nb_child_props = ARRAY_SIZE(stm32_fmc2_mp25_child_props),
1457 .fmc2_enable_reg = FMC2_CFGR,
1458 .fmc2_enable_bit = FMC2_CFGR_FMC2EN,
Christophe Kerello90c38b52024-03-06 10:50:47 +01001459 .check_rif = stm32_fmc2_ebi_mp25_check_rif,
Christophe Kerello34af8b82024-03-06 10:50:46 +01001460};
1461
Christophe Kerelloa994a802020-07-31 09:53:40 +02001462static const struct udevice_id stm32_fmc2_ebi_match[] = {
Christophe Kerello34af8b82024-03-06 10:50:46 +01001463 {
1464 .compatible = "st,stm32mp1-fmc2-ebi",
1465 .data = (ulong)&stm32_fmc2_ebi_mp1_data,
1466 },
1467 {
1468 .compatible = "st,stm32mp25-fmc2-ebi",
1469 .data = (ulong)&stm32_fmc2_ebi_mp25_data,
1470 },
Christophe Kerelloa994a802020-07-31 09:53:40 +02001471 { /* Sentinel */ }
1472};
1473
1474U_BOOT_DRIVER(stm32_fmc2_ebi) = {
1475 .name = "stm32_fmc2_ebi",
1476 .id = UCLASS_NOP,
1477 .of_match = stm32_fmc2_ebi_match,
1478 .probe = stm32_fmc2_ebi_probe,
Simon Glass8a2b47f2020-12-03 16:55:17 -07001479 .priv_auto = sizeof(struct stm32_fmc2_ebi),
Christophe Kerelloa994a802020-07-31 09:53:40 +02001480 .bind = dm_scan_fdt_dev,
1481};