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