1831 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (C) STMicroelectronics 20204 */5 6#include <linux/bitfield.h>7#include <linux/clk.h>8#include <linux/mfd/syscon.h>9#include <linux/module.h>10#include <linux/of.h>11#include <linux/of_platform.h>12#include <linux/pinctrl/consumer.h>13#include <linux/platform_device.h>14#include <linux/pm_runtime.h>15#include <linux/regmap.h>16#include <linux/reset.h>17 18/* FMC2 Controller Registers */19#define FMC2_BCR1 0x020#define FMC2_BTR1 0x421#define FMC2_BCR(x) ((x) * 0x8 + FMC2_BCR1)22#define FMC2_BTR(x) ((x) * 0x8 + FMC2_BTR1)23#define FMC2_PCSCNTR 0x2024#define FMC2_CFGR 0x2025#define FMC2_SR 0x8426#define FMC2_BWTR1 0x10427#define FMC2_BWTR(x) ((x) * 0x8 + FMC2_BWTR1)28#define FMC2_SECCFGR 0x30029#define FMC2_CIDCFGR0 0x30c30#define FMC2_CIDCFGR(x) ((x) * 0x8 + FMC2_CIDCFGR0)31#define FMC2_SEMCR0 0x31032#define FMC2_SEMCR(x) ((x) * 0x8 + FMC2_SEMCR0)33 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)53#define FMC2_BCR_CSCOUNT GENMASK(21, 20)54#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 70/* 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 75/* 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 88#define FMC2_MAX_EBI_CE 489#define FMC2_MAX_BANKS 590#define FMC2_MAX_RESOURCES 691#define FMC2_CID1 192 93#define FMC2_BCR_CPSIZE_0 0x094#define FMC2_BCR_CPSIZE_128 0x195#define FMC2_BCR_CPSIZE_256 0x296#define FMC2_BCR_CPSIZE_512 0x397#define FMC2_BCR_CPSIZE_1024 0x498 99#define FMC2_BCR_MWID_8 0x0100#define FMC2_BCR_MWID_16 0x1101 102#define FMC2_BCR_MTYP_SRAM 0x0103#define FMC2_BCR_MTYP_PSRAM 0x1104#define FMC2_BCR_MTYP_NOR 0x2105 106#define FMC2_BCR_CSCOUNT_0 0x0107#define FMC2_BCR_CSCOUNT_1 0x1108#define FMC2_BCR_CSCOUNT_64 0x2109#define FMC2_BCR_CSCOUNT_256 0x3110 111#define FMC2_BXTR_EXTMOD_A 0x0112#define FMC2_BXTR_EXTMOD_B 0x1113#define FMC2_BXTR_EXTMOD_C 0x2114#define FMC2_BXTR_EXTMOD_D 0x3115 116#define FMC2_BCR_NBLSET_MAX 0x3117#define FMC2_BXTR_ADDSET_MAX 0xf118#define FMC2_BXTR_ADDHLD_MAX 0xf119#define FMC2_BXTR_DATAST_MAX 0xff120#define FMC2_BXTR_BUSTURN_MAX 0xf121#define FMC2_BXTR_DATAHLD_MAX 0x3122#define FMC2_BTR_CLKDIV_MAX 0xf123#define FMC2_BTR_DATLAT_MAX 0xf124#define FMC2_PCSCNTR_CSCOUNT_MAX 0xff125#define FMC2_CFGR_CLKDIV_MAX 0xf126 127enum stm32_fmc2_ebi_bank {128 FMC2_EBI1 = 0,129 FMC2_EBI2,130 FMC2_EBI3,131 FMC2_EBI4,132 FMC2_NAND133};134 135enum stm32_fmc2_ebi_register_type {136 FMC2_REG_BCR = 1,137 FMC2_REG_BTR,138 FMC2_REG_BWTR,139 FMC2_REG_PCSCNTR,140 FMC2_REG_CFGR141};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_NOR156};157 158enum stm32_fmc2_ebi_buswidth {159 FMC2_BUSWIDTH_8 = 8,160 FMC2_BUSWIDTH_16 = 16161};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 = 1024169};170 171enum stm32_fmc2_ebi_cscount {172 FMC2_CSCOUNT_0 = 0,173 FMC2_CSCOUNT_1 = 1,174 FMC2_CSCOUNT_64 = 64,175 FMC2_CSCOUNT_256 = 256176};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);186 void (*set_setup)(struct stm32_fmc2_ebi *ebi);187 int (*save_setup)(struct stm32_fmc2_ebi *ebi);188 int (*check_rif)(struct stm32_fmc2_ebi *ebi, u32 resource);189 void (*put_sems)(struct stm32_fmc2_ebi *ebi);190 void (*get_sems)(struct stm32_fmc2_ebi *ebi);191};192 193struct stm32_fmc2_ebi {194 struct device *dev;195 struct clk *clk;196 struct regmap *regmap;197 const struct stm32_fmc2_ebi_data *data;198 u8 bank_assigned;199 u8 sem_taken;200 bool access_granted;201 202 u32 bcr[FMC2_MAX_EBI_CE];203 u32 btr[FMC2_MAX_EBI_CE];204 u32 bwtr[FMC2_MAX_EBI_CE];205 u32 pcscntr;206 u32 cfgr;207};208 209/*210 * struct stm32_fmc2_prop - STM32 FMC2 EBI property211 * @name: the device tree binding name of the property212 * @bprop: indicate that it is a boolean property213 * @mprop: indicate that it is a mandatory property214 * @reg_type: the register that have to be modified215 * @reg_mask: the bit that have to be modified in the selected register216 * in case of it is a boolean property217 * @reset_val: the default value that have to be set in case the property218 * has not been defined in the device tree219 * @check: this callback ckecks that the property is compliant with the220 * transaction type selected221 * @calculate: this callback is called to calculate for exemple a timing222 * set in nanoseconds in the device tree in clock cycles or in223 * clock period224 * @set: this callback applies the values in the registers225 */226struct stm32_fmc2_prop {227 const char *name;228 bool bprop;229 bool mprop;230 int reg_type;231 u32 reg_mask;232 u32 reset_val;233 int (*check)(struct stm32_fmc2_ebi *ebi,234 const struct stm32_fmc2_prop *prop, int cs);235 u32 (*calculate)(struct stm32_fmc2_ebi *ebi, int cs, u32 setup);236 int (*set)(struct stm32_fmc2_ebi *ebi,237 const struct stm32_fmc2_prop *prop,238 int cs, u32 setup);239};240 241static int stm32_fmc2_ebi_check_mux(struct stm32_fmc2_ebi *ebi,242 const struct stm32_fmc2_prop *prop,243 int cs)244{245 u32 bcr;246 int ret;247 248 ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);249 if (ret)250 return ret;251 252 if (bcr & FMC2_BCR_MTYP)253 return 0;254 255 return -EINVAL;256}257 258static int stm32_fmc2_ebi_check_waitcfg(struct stm32_fmc2_ebi *ebi,259 const struct stm32_fmc2_prop *prop,260 int cs)261{262 u32 bcr, val = FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);263 int ret;264 265 ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);266 if (ret)267 return ret;268 269 if ((bcr & FMC2_BCR_MTYP) == val && bcr & FMC2_BCR_BURSTEN)270 return 0;271 272 return -EINVAL;273}274 275static int stm32_fmc2_ebi_check_sync_trans(struct stm32_fmc2_ebi *ebi,276 const struct stm32_fmc2_prop *prop,277 int cs)278{279 u32 bcr;280 int ret;281 282 ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);283 if (ret)284 return ret;285 286 if (bcr & FMC2_BCR_BURSTEN)287 return 0;288 289 return -EINVAL;290}291 292static int stm32_fmc2_ebi_mp25_check_cclk(struct stm32_fmc2_ebi *ebi,293 const struct stm32_fmc2_prop *prop,294 int cs)295{296 if (!ebi->access_granted)297 return -EACCES;298 299 return stm32_fmc2_ebi_check_sync_trans(ebi, prop, cs);300}301 302static int stm32_fmc2_ebi_mp25_check_clk_period(struct stm32_fmc2_ebi *ebi,303 const struct stm32_fmc2_prop *prop,304 int cs)305{306 u32 cfgr;307 int ret;308 309 ret = regmap_read(ebi->regmap, FMC2_CFGR, &cfgr);310 if (ret)311 return ret;312 313 if (cfgr & FMC2_CFGR_CCLKEN && !ebi->access_granted)314 return -EACCES;315 316 return stm32_fmc2_ebi_check_sync_trans(ebi, prop, cs);317}318 319static int stm32_fmc2_ebi_check_async_trans(struct stm32_fmc2_ebi *ebi,320 const struct stm32_fmc2_prop *prop,321 int cs)322{323 u32 bcr;324 int ret;325 326 ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);327 if (ret)328 return ret;329 330 if (!(bcr & FMC2_BCR_BURSTEN) || !(bcr & FMC2_BCR_CBURSTRW))331 return 0;332 333 return -EINVAL;334}335 336static int stm32_fmc2_ebi_check_cpsize(struct stm32_fmc2_ebi *ebi,337 const struct stm32_fmc2_prop *prop,338 int cs)339{340 u32 bcr, val = FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM);341 int ret;342 343 ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);344 if (ret)345 return ret;346 347 if ((bcr & FMC2_BCR_MTYP) == val && bcr & FMC2_BCR_BURSTEN)348 return 0;349 350 return -EINVAL;351}352 353static int stm32_fmc2_ebi_check_address_hold(struct stm32_fmc2_ebi *ebi,354 const struct stm32_fmc2_prop *prop,355 int cs)356{357 u32 bcr, bxtr, val = FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D);358 int ret;359 360 ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);361 if (ret)362 return ret;363 364 if (prop->reg_type == FMC2_REG_BWTR)365 ret = regmap_read(ebi->regmap, FMC2_BWTR(cs), &bxtr);366 else367 ret = regmap_read(ebi->regmap, FMC2_BTR(cs), &bxtr);368 if (ret)369 return ret;370 371 if ((!(bcr & FMC2_BCR_BURSTEN) || !(bcr & FMC2_BCR_CBURSTRW)) &&372 ((bxtr & FMC2_BXTR_ACCMOD) == val || bcr & FMC2_BCR_MUXEN))373 return 0;374 375 return -EINVAL;376}377 378static int stm32_fmc2_ebi_check_clk_period(struct stm32_fmc2_ebi *ebi,379 const struct stm32_fmc2_prop *prop,380 int cs)381{382 u32 bcr, bcr1;383 int ret;384 385 ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);386 if (ret)387 return ret;388 389 if (cs) {390 ret = regmap_read(ebi->regmap, FMC2_BCR1, &bcr1);391 if (ret)392 return ret;393 } else {394 bcr1 = bcr;395 }396 397 if (bcr & FMC2_BCR_BURSTEN && (!cs || !(bcr1 & FMC2_BCR1_CCLKEN)))398 return 0;399 400 return -EINVAL;401}402 403static int stm32_fmc2_ebi_check_cclk(struct stm32_fmc2_ebi *ebi,404 const struct stm32_fmc2_prop *prop,405 int cs)406{407 if (cs)408 return -EINVAL;409 410 return stm32_fmc2_ebi_check_sync_trans(ebi, prop, cs);411}412 413static u32 stm32_fmc2_ebi_ns_to_clock_cycles(struct stm32_fmc2_ebi *ebi,414 int cs, u32 setup)415{416 unsigned long hclk = clk_get_rate(ebi->clk);417 unsigned long hclkp = NSEC_PER_SEC / (hclk / 1000);418 419 return DIV_ROUND_UP(setup * 1000, hclkp);420}421 422static u32 stm32_fmc2_ebi_ns_to_clk_period(struct stm32_fmc2_ebi *ebi,423 int cs, u32 setup)424{425 u32 nb_clk_cycles = stm32_fmc2_ebi_ns_to_clock_cycles(ebi, cs, setup);426 u32 bcr, btr, clk_period;427 int ret;428 429 ret = regmap_read(ebi->regmap, FMC2_BCR1, &bcr);430 if (ret)431 return ret;432 433 if (bcr & FMC2_BCR1_CCLKEN || !cs)434 ret = regmap_read(ebi->regmap, FMC2_BTR1, &btr);435 else436 ret = regmap_read(ebi->regmap, FMC2_BTR(cs), &btr);437 if (ret)438 return ret;439 440 clk_period = FIELD_GET(FMC2_BTR_CLKDIV, btr) + 1;441 442 return DIV_ROUND_UP(nb_clk_cycles, clk_period);443}444 445static u32 stm32_fmc2_ebi_mp25_ns_to_clk_period(struct stm32_fmc2_ebi *ebi,446 int cs, u32 setup)447{448 u32 nb_clk_cycles = stm32_fmc2_ebi_ns_to_clock_cycles(ebi, cs, setup);449 u32 cfgr, btr, clk_period;450 int ret;451 452 ret = regmap_read(ebi->regmap, FMC2_CFGR, &cfgr);453 if (ret)454 return ret;455 456 if (cfgr & FMC2_CFGR_CCLKEN) {457 clk_period = FIELD_GET(FMC2_CFGR_CLKDIV, cfgr) + 1;458 } else {459 ret = regmap_read(ebi->regmap, FMC2_BTR(cs), &btr);460 if (ret)461 return ret;462 463 clk_period = FIELD_GET(FMC2_BTR_CLKDIV, btr) + 1;464 }465 466 return DIV_ROUND_UP(nb_clk_cycles, clk_period);467}468 469static int stm32_fmc2_ebi_get_reg(int reg_type, int cs, u32 *reg)470{471 switch (reg_type) {472 case FMC2_REG_BCR:473 *reg = FMC2_BCR(cs);474 break;475 case FMC2_REG_BTR:476 *reg = FMC2_BTR(cs);477 break;478 case FMC2_REG_BWTR:479 *reg = FMC2_BWTR(cs);480 break;481 case FMC2_REG_PCSCNTR:482 *reg = FMC2_PCSCNTR;483 break;484 case FMC2_REG_CFGR:485 *reg = FMC2_CFGR;486 break;487 default:488 return -EINVAL;489 }490 491 return 0;492}493 494static int stm32_fmc2_ebi_set_bit_field(struct stm32_fmc2_ebi *ebi,495 const struct stm32_fmc2_prop *prop,496 int cs, u32 setup)497{498 u32 reg;499 int ret;500 501 ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, ®);502 if (ret)503 return ret;504 505 regmap_update_bits(ebi->regmap, reg, prop->reg_mask,506 setup ? prop->reg_mask : 0);507 508 return 0;509}510 511static int stm32_fmc2_ebi_set_trans_type(struct stm32_fmc2_ebi *ebi,512 const struct stm32_fmc2_prop *prop,513 int cs, u32 setup)514{515 u32 bcr_mask, bcr = FMC2_BCR_WREN;516 u32 btr_mask, btr = 0;517 u32 bwtr_mask, bwtr = 0;518 519 bwtr_mask = FMC2_BXTR_ACCMOD;520 btr_mask = FMC2_BXTR_ACCMOD;521 bcr_mask = FMC2_BCR_MUXEN | FMC2_BCR_MTYP | FMC2_BCR_FACCEN |522 FMC2_BCR_WREN | FMC2_BCR_WAITEN | FMC2_BCR_BURSTEN |523 FMC2_BCR_EXTMOD | FMC2_BCR_CBURSTRW;524 525 switch (setup) {526 case FMC2_ASYNC_MODE_1_SRAM:527 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_SRAM);528 /*529 * MUXEN = 0, MTYP = 0, FACCEN = 0, BURSTEN = 0, WAITEN = 0,530 * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0531 */532 break;533 case FMC2_ASYNC_MODE_1_PSRAM:534 /*535 * MUXEN = 0, MTYP = 1, FACCEN = 0, BURSTEN = 0, WAITEN = 0,536 * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0537 */538 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM);539 break;540 case FMC2_ASYNC_MODE_A_SRAM:541 /*542 * MUXEN = 0, MTYP = 0, FACCEN = 0, BURSTEN = 0, WAITEN = 0,543 * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 0544 */545 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_SRAM);546 bcr |= FMC2_BCR_EXTMOD;547 btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_A);548 bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_A);549 break;550 case FMC2_ASYNC_MODE_A_PSRAM:551 /*552 * MUXEN = 0, MTYP = 1, FACCEN = 0, BURSTEN = 0, WAITEN = 0,553 * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 0554 */555 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM);556 bcr |= FMC2_BCR_EXTMOD;557 btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_A);558 bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_A);559 break;560 case FMC2_ASYNC_MODE_2_NOR:561 /*562 * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 0, WAITEN = 0,563 * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0564 */565 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);566 bcr |= FMC2_BCR_FACCEN;567 break;568 case FMC2_ASYNC_MODE_B_NOR:569 /*570 * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 0, WAITEN = 0,571 * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 1572 */573 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);574 bcr |= FMC2_BCR_FACCEN | FMC2_BCR_EXTMOD;575 btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_B);576 bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_B);577 break;578 case FMC2_ASYNC_MODE_C_NOR:579 /*580 * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 0, WAITEN = 0,581 * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 2582 */583 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);584 bcr |= FMC2_BCR_FACCEN | FMC2_BCR_EXTMOD;585 btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_C);586 bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_C);587 break;588 case FMC2_ASYNC_MODE_D_NOR:589 /*590 * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 0, WAITEN = 0,591 * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 3592 */593 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);594 bcr |= FMC2_BCR_FACCEN | FMC2_BCR_EXTMOD;595 btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D);596 bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D);597 break;598 case FMC2_SYNC_READ_SYNC_WRITE_PSRAM:599 /*600 * MUXEN = 0, MTYP = 1, FACCEN = 0, BURSTEN = 1, WAITEN = 0,601 * WREN = 1, EXTMOD = 0, CBURSTRW = 1, ACCMOD = 0602 */603 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM);604 bcr |= FMC2_BCR_BURSTEN | FMC2_BCR_CBURSTRW;605 break;606 case FMC2_SYNC_READ_ASYNC_WRITE_PSRAM:607 /*608 * MUXEN = 0, MTYP = 1, FACCEN = 0, BURSTEN = 1, WAITEN = 0,609 * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0610 */611 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM);612 bcr |= FMC2_BCR_BURSTEN;613 break;614 case FMC2_SYNC_READ_SYNC_WRITE_NOR:615 /*616 * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 1, WAITEN = 0,617 * WREN = 1, EXTMOD = 0, CBURSTRW = 1, ACCMOD = 0618 */619 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);620 bcr |= FMC2_BCR_FACCEN | FMC2_BCR_BURSTEN | FMC2_BCR_CBURSTRW;621 break;622 case FMC2_SYNC_READ_ASYNC_WRITE_NOR:623 /*624 * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 1, WAITEN = 0,625 * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0626 */627 bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);628 bcr |= FMC2_BCR_FACCEN | FMC2_BCR_BURSTEN;629 break;630 default:631 /* Type of transaction not supported */632 return -EINVAL;633 }634 635 if (bcr & FMC2_BCR_EXTMOD)636 regmap_update_bits(ebi->regmap, FMC2_BWTR(cs),637 bwtr_mask, bwtr);638 regmap_update_bits(ebi->regmap, FMC2_BTR(cs), btr_mask, btr);639 regmap_update_bits(ebi->regmap, FMC2_BCR(cs), bcr_mask, bcr);640 641 return 0;642}643 644static int stm32_fmc2_ebi_set_buswidth(struct stm32_fmc2_ebi *ebi,645 const struct stm32_fmc2_prop *prop,646 int cs, u32 setup)647{648 u32 val;649 650 switch (setup) {651 case FMC2_BUSWIDTH_8:652 val = FIELD_PREP(FMC2_BCR_MWID, FMC2_BCR_MWID_8);653 break;654 case FMC2_BUSWIDTH_16:655 val = FIELD_PREP(FMC2_BCR_MWID, FMC2_BCR_MWID_16);656 break;657 default:658 /* Buswidth not supported */659 return -EINVAL;660 }661 662 regmap_update_bits(ebi->regmap, FMC2_BCR(cs), FMC2_BCR_MWID, val);663 664 return 0;665}666 667static int stm32_fmc2_ebi_set_cpsize(struct stm32_fmc2_ebi *ebi,668 const struct stm32_fmc2_prop *prop,669 int cs, u32 setup)670{671 u32 val;672 673 switch (setup) {674 case FMC2_CPSIZE_0:675 val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_0);676 break;677 case FMC2_CPSIZE_128:678 val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_128);679 break;680 case FMC2_CPSIZE_256:681 val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_256);682 break;683 case FMC2_CPSIZE_512:684 val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_512);685 break;686 case FMC2_CPSIZE_1024:687 val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_1024);688 break;689 default:690 /* Cpsize not supported */691 return -EINVAL;692 }693 694 regmap_update_bits(ebi->regmap, FMC2_BCR(cs), FMC2_BCR_CPSIZE, val);695 696 return 0;697}698 699static int stm32_fmc2_ebi_set_bl_setup(struct stm32_fmc2_ebi *ebi,700 const struct stm32_fmc2_prop *prop,701 int cs, u32 setup)702{703 u32 val;704 705 val = min_t(u32, setup, FMC2_BCR_NBLSET_MAX);706 val = FIELD_PREP(FMC2_BCR_NBLSET, val);707 regmap_update_bits(ebi->regmap, FMC2_BCR(cs), FMC2_BCR_NBLSET, val);708 709 return 0;710}711 712static int stm32_fmc2_ebi_set_address_setup(struct stm32_fmc2_ebi *ebi,713 const struct stm32_fmc2_prop *prop,714 int cs, u32 setup)715{716 u32 bcr, bxtr, reg;717 u32 val = FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D);718 int ret;719 720 ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, ®);721 if (ret)722 return ret;723 724 ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);725 if (ret)726 return ret;727 728 if (prop->reg_type == FMC2_REG_BWTR)729 ret = regmap_read(ebi->regmap, FMC2_BWTR(cs), &bxtr);730 else731 ret = regmap_read(ebi->regmap, FMC2_BTR(cs), &bxtr);732 if (ret)733 return ret;734 735 if ((bxtr & FMC2_BXTR_ACCMOD) == val || bcr & FMC2_BCR_MUXEN)736 val = clamp_val(setup, 1, FMC2_BXTR_ADDSET_MAX);737 else738 val = min_t(u32, setup, FMC2_BXTR_ADDSET_MAX);739 val = FIELD_PREP(FMC2_BXTR_ADDSET, val);740 regmap_update_bits(ebi->regmap, reg, FMC2_BXTR_ADDSET, val);741 742 return 0;743}744 745static int stm32_fmc2_ebi_set_address_hold(struct stm32_fmc2_ebi *ebi,746 const struct stm32_fmc2_prop *prop,747 int cs, u32 setup)748{749 u32 val, reg;750 int ret;751 752 ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, ®);753 if (ret)754 return ret;755 756 val = clamp_val(setup, 1, FMC2_BXTR_ADDHLD_MAX);757 val = FIELD_PREP(FMC2_BXTR_ADDHLD, val);758 regmap_update_bits(ebi->regmap, reg, FMC2_BXTR_ADDHLD, val);759 760 return 0;761}762 763static int stm32_fmc2_ebi_set_data_setup(struct stm32_fmc2_ebi *ebi,764 const struct stm32_fmc2_prop *prop,765 int cs, u32 setup)766{767 u32 val, reg;768 int ret;769 770 ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, ®);771 if (ret)772 return ret;773 774 val = clamp_val(setup, 1, FMC2_BXTR_DATAST_MAX);775 val = FIELD_PREP(FMC2_BXTR_DATAST, val);776 regmap_update_bits(ebi->regmap, reg, FMC2_BXTR_DATAST, val);777 778 return 0;779}780 781static int stm32_fmc2_ebi_set_bus_turnaround(struct stm32_fmc2_ebi *ebi,782 const struct stm32_fmc2_prop *prop,783 int cs, u32 setup)784{785 u32 val, reg;786 int ret;787 788 ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, ®);789 if (ret)790 return ret;791 792 val = setup ? min_t(u32, setup - 1, FMC2_BXTR_BUSTURN_MAX) : 0;793 val = FIELD_PREP(FMC2_BXTR_BUSTURN, val);794 regmap_update_bits(ebi->regmap, reg, FMC2_BXTR_BUSTURN, val);795 796 return 0;797}798 799static int stm32_fmc2_ebi_set_data_hold(struct stm32_fmc2_ebi *ebi,800 const struct stm32_fmc2_prop *prop,801 int cs, u32 setup)802{803 u32 val, reg;804 int ret;805 806 ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, ®);807 if (ret)808 return ret;809 810 if (prop->reg_type == FMC2_REG_BWTR)811 val = setup ? min_t(u32, setup - 1, FMC2_BXTR_DATAHLD_MAX) : 0;812 else813 val = min_t(u32, setup, FMC2_BXTR_DATAHLD_MAX);814 val = FIELD_PREP(FMC2_BXTR_DATAHLD, val);815 regmap_update_bits(ebi->regmap, reg, FMC2_BXTR_DATAHLD, val);816 817 return 0;818}819 820static int stm32_fmc2_ebi_set_clk_period(struct stm32_fmc2_ebi *ebi,821 const struct stm32_fmc2_prop *prop,822 int cs, u32 setup)823{824 u32 val;825 826 val = setup ? clamp_val(setup - 1, 1, FMC2_BTR_CLKDIV_MAX) : 1;827 val = FIELD_PREP(FMC2_BTR_CLKDIV, val);828 regmap_update_bits(ebi->regmap, FMC2_BTR(cs), FMC2_BTR_CLKDIV, val);829 830 return 0;831}832 833static int stm32_fmc2_ebi_mp25_set_clk_period(struct stm32_fmc2_ebi *ebi,834 const struct stm32_fmc2_prop *prop,835 int cs, u32 setup)836{837 u32 val, cfgr;838 int ret;839 840 ret = regmap_read(ebi->regmap, FMC2_CFGR, &cfgr);841 if (ret)842 return ret;843 844 if (cfgr & FMC2_CFGR_CCLKEN) {845 val = setup ? clamp_val(setup - 1, 1, FMC2_CFGR_CLKDIV_MAX) : 1;846 val = FIELD_PREP(FMC2_CFGR_CLKDIV, val);847 regmap_update_bits(ebi->regmap, FMC2_CFGR, FMC2_CFGR_CLKDIV, val);848 } else {849 val = setup ? clamp_val(setup - 1, 1, FMC2_BTR_CLKDIV_MAX) : 1;850 val = FIELD_PREP(FMC2_BTR_CLKDIV, val);851 regmap_update_bits(ebi->regmap, FMC2_BTR(cs), FMC2_BTR_CLKDIV, val);852 }853 854 return 0;855}856 857static int stm32_fmc2_ebi_set_data_latency(struct stm32_fmc2_ebi *ebi,858 const struct stm32_fmc2_prop *prop,859 int cs, u32 setup)860{861 u32 val;862 863 val = setup > 1 ? min_t(u32, setup - 2, FMC2_BTR_DATLAT_MAX) : 0;864 val = FIELD_PREP(FMC2_BTR_DATLAT, val);865 regmap_update_bits(ebi->regmap, FMC2_BTR(cs), FMC2_BTR_DATLAT, val);866 867 return 0;868}869 870static int stm32_fmc2_ebi_set_max_low_pulse(struct stm32_fmc2_ebi *ebi,871 const struct stm32_fmc2_prop *prop,872 int cs, u32 setup)873{874 u32 old_val, new_val, pcscntr;875 int ret;876 877 if (setup < 1)878 return 0;879 880 ret = regmap_read(ebi->regmap, FMC2_PCSCNTR, &pcscntr);881 if (ret)882 return ret;883 884 /* Enable counter for the bank */885 regmap_update_bits(ebi->regmap, FMC2_PCSCNTR,886 FMC2_PCSCNTR_CNTBEN(cs),887 FMC2_PCSCNTR_CNTBEN(cs));888 889 new_val = min_t(u32, setup - 1, FMC2_PCSCNTR_CSCOUNT_MAX);890 old_val = FIELD_GET(FMC2_PCSCNTR_CSCOUNT, pcscntr);891 if (old_val && new_val > old_val)892 /* Keep current counter value */893 return 0;894 895 new_val = FIELD_PREP(FMC2_PCSCNTR_CSCOUNT, new_val);896 regmap_update_bits(ebi->regmap, FMC2_PCSCNTR,897 FMC2_PCSCNTR_CSCOUNT, new_val);898 899 return 0;900}901 902static int stm32_fmc2_ebi_mp25_set_max_low_pulse(struct stm32_fmc2_ebi *ebi,903 const struct stm32_fmc2_prop *prop,904 int cs, u32 setup)905{906 u32 val;907 908 if (setup == FMC2_CSCOUNT_0)909 val = FIELD_PREP(FMC2_BCR_CSCOUNT, FMC2_BCR_CSCOUNT_0);910 else if (setup == FMC2_CSCOUNT_1)911 val = FIELD_PREP(FMC2_BCR_CSCOUNT, FMC2_BCR_CSCOUNT_1);912 else if (setup <= FMC2_CSCOUNT_64)913 val = FIELD_PREP(FMC2_BCR_CSCOUNT, FMC2_BCR_CSCOUNT_64);914 else915 val = FIELD_PREP(FMC2_BCR_CSCOUNT, FMC2_BCR_CSCOUNT_256);916 917 regmap_update_bits(ebi->regmap, FMC2_BCR(cs),918 FMC2_BCR_CSCOUNT, val);919 920 return 0;921}922 923static const struct stm32_fmc2_prop stm32_fmc2_child_props[] = {924 /* st,fmc2-ebi-cs-trans-type must be the first property */925 {926 .name = "st,fmc2-ebi-cs-transaction-type",927 .mprop = true,928 .set = stm32_fmc2_ebi_set_trans_type,929 },930 {931 .name = "st,fmc2-ebi-cs-cclk-enable",932 .bprop = true,933 .reg_type = FMC2_REG_BCR,934 .reg_mask = FMC2_BCR1_CCLKEN,935 .check = stm32_fmc2_ebi_check_cclk,936 .set = stm32_fmc2_ebi_set_bit_field,937 },938 {939 .name = "st,fmc2-ebi-cs-mux-enable",940 .bprop = true,941 .reg_type = FMC2_REG_BCR,942 .reg_mask = FMC2_BCR_MUXEN,943 .check = stm32_fmc2_ebi_check_mux,944 .set = stm32_fmc2_ebi_set_bit_field,945 },946 {947 .name = "st,fmc2-ebi-cs-buswidth",948 .reset_val = FMC2_BUSWIDTH_16,949 .set = stm32_fmc2_ebi_set_buswidth,950 },951 {952 .name = "st,fmc2-ebi-cs-waitpol-high",953 .bprop = true,954 .reg_type = FMC2_REG_BCR,955 .reg_mask = FMC2_BCR_WAITPOL,956 .set = stm32_fmc2_ebi_set_bit_field,957 },958 {959 .name = "st,fmc2-ebi-cs-waitcfg-enable",960 .bprop = true,961 .reg_type = FMC2_REG_BCR,962 .reg_mask = FMC2_BCR_WAITCFG,963 .check = stm32_fmc2_ebi_check_waitcfg,964 .set = stm32_fmc2_ebi_set_bit_field,965 },966 {967 .name = "st,fmc2-ebi-cs-wait-enable",968 .bprop = true,969 .reg_type = FMC2_REG_BCR,970 .reg_mask = FMC2_BCR_WAITEN,971 .check = stm32_fmc2_ebi_check_sync_trans,972 .set = stm32_fmc2_ebi_set_bit_field,973 },974 {975 .name = "st,fmc2-ebi-cs-asyncwait-enable",976 .bprop = true,977 .reg_type = FMC2_REG_BCR,978 .reg_mask = FMC2_BCR_ASYNCWAIT,979 .check = stm32_fmc2_ebi_check_async_trans,980 .set = stm32_fmc2_ebi_set_bit_field,981 },982 {983 .name = "st,fmc2-ebi-cs-cpsize",984 .check = stm32_fmc2_ebi_check_cpsize,985 .set = stm32_fmc2_ebi_set_cpsize,986 },987 {988 .name = "st,fmc2-ebi-cs-byte-lane-setup-ns",989 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,990 .set = stm32_fmc2_ebi_set_bl_setup,991 },992 {993 .name = "st,fmc2-ebi-cs-address-setup-ns",994 .reg_type = FMC2_REG_BTR,995 .reset_val = FMC2_BXTR_ADDSET_MAX,996 .check = stm32_fmc2_ebi_check_async_trans,997 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,998 .set = stm32_fmc2_ebi_set_address_setup,999 },1000 {1001 .name = "st,fmc2-ebi-cs-address-hold-ns",1002 .reg_type = FMC2_REG_BTR,1003 .reset_val = FMC2_BXTR_ADDHLD_MAX,1004 .check = stm32_fmc2_ebi_check_address_hold,1005 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,1006 .set = stm32_fmc2_ebi_set_address_hold,1007 },1008 {1009 .name = "st,fmc2-ebi-cs-data-setup-ns",1010 .reg_type = FMC2_REG_BTR,1011 .reset_val = FMC2_BXTR_DATAST_MAX,1012 .check = stm32_fmc2_ebi_check_async_trans,1013 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,1014 .set = stm32_fmc2_ebi_set_data_setup,1015 },1016 {1017 .name = "st,fmc2-ebi-cs-bus-turnaround-ns",1018 .reg_type = FMC2_REG_BTR,1019 .reset_val = FMC2_BXTR_BUSTURN_MAX + 1,1020 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,1021 .set = stm32_fmc2_ebi_set_bus_turnaround,1022 },1023 {1024 .name = "st,fmc2-ebi-cs-data-hold-ns",1025 .reg_type = FMC2_REG_BTR,1026 .check = stm32_fmc2_ebi_check_async_trans,1027 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,1028 .set = stm32_fmc2_ebi_set_data_hold,1029 },1030 {1031 .name = "st,fmc2-ebi-cs-clk-period-ns",1032 .reset_val = FMC2_BTR_CLKDIV_MAX + 1,1033 .check = stm32_fmc2_ebi_check_clk_period,1034 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,1035 .set = stm32_fmc2_ebi_set_clk_period,1036 },1037 {1038 .name = "st,fmc2-ebi-cs-data-latency-ns",1039 .check = stm32_fmc2_ebi_check_sync_trans,1040 .calculate = stm32_fmc2_ebi_ns_to_clk_period,1041 .set = stm32_fmc2_ebi_set_data_latency,1042 },1043 {1044 .name = "st,fmc2-ebi-cs-write-address-setup-ns",1045 .reg_type = FMC2_REG_BWTR,1046 .reset_val = FMC2_BXTR_ADDSET_MAX,1047 .check = stm32_fmc2_ebi_check_async_trans,1048 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,1049 .set = stm32_fmc2_ebi_set_address_setup,1050 },1051 {1052 .name = "st,fmc2-ebi-cs-write-address-hold-ns",1053 .reg_type = FMC2_REG_BWTR,1054 .reset_val = FMC2_BXTR_ADDHLD_MAX,1055 .check = stm32_fmc2_ebi_check_address_hold,1056 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,1057 .set = stm32_fmc2_ebi_set_address_hold,1058 },1059 {1060 .name = "st,fmc2-ebi-cs-write-data-setup-ns",1061 .reg_type = FMC2_REG_BWTR,1062 .reset_val = FMC2_BXTR_DATAST_MAX,1063 .check = stm32_fmc2_ebi_check_async_trans,1064 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,1065 .set = stm32_fmc2_ebi_set_data_setup,1066 },1067 {1068 .name = "st,fmc2-ebi-cs-write-bus-turnaround-ns",1069 .reg_type = FMC2_REG_BWTR,1070 .reset_val = FMC2_BXTR_BUSTURN_MAX + 1,1071 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,1072 .set = stm32_fmc2_ebi_set_bus_turnaround,1073 },1074 {1075 .name = "st,fmc2-ebi-cs-write-data-hold-ns",1076 .reg_type = FMC2_REG_BWTR,1077 .check = stm32_fmc2_ebi_check_async_trans,1078 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,1079 .set = stm32_fmc2_ebi_set_data_hold,1080 },1081 {1082 .name = "st,fmc2-ebi-cs-max-low-pulse-ns",1083 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,1084 .set = stm32_fmc2_ebi_set_max_low_pulse,1085 },1086};1087 1088static const struct stm32_fmc2_prop stm32_fmc2_mp25_child_props[] = {1089 /* st,fmc2-ebi-cs-trans-type must be the first property */1090 {1091 .name = "st,fmc2-ebi-cs-transaction-type",1092 .mprop = true,1093 .set = stm32_fmc2_ebi_set_trans_type,1094 },1095 {1096 .name = "st,fmc2-ebi-cs-cclk-enable",1097 .bprop = true,1098 .reg_type = FMC2_REG_CFGR,1099 .reg_mask = FMC2_CFGR_CCLKEN,1100 .check = stm32_fmc2_ebi_mp25_check_cclk,1101 .set = stm32_fmc2_ebi_set_bit_field,1102 },1103 {1104 .name = "st,fmc2-ebi-cs-mux-enable",1105 .bprop = true,1106 .reg_type = FMC2_REG_BCR,1107 .reg_mask = FMC2_BCR_MUXEN,1108 .check = stm32_fmc2_ebi_check_mux,1109 .set = stm32_fmc2_ebi_set_bit_field,1110 },1111 {1112 .name = "st,fmc2-ebi-cs-buswidth",1113 .reset_val = FMC2_BUSWIDTH_16,1114 .set = stm32_fmc2_ebi_set_buswidth,1115 },1116 {1117 .name = "st,fmc2-ebi-cs-waitpol-high",1118 .bprop = true,1119 .reg_type = FMC2_REG_BCR,1120 .reg_mask = FMC2_BCR_WAITPOL,1121 .set = stm32_fmc2_ebi_set_bit_field,1122 },1123 {1124 .name = "st,fmc2-ebi-cs-waitcfg-enable",1125 .bprop = true,1126 .reg_type = FMC2_REG_BCR,1127 .reg_mask = FMC2_BCR_WAITCFG,1128 .check = stm32_fmc2_ebi_check_waitcfg,1129 .set = stm32_fmc2_ebi_set_bit_field,1130 },1131 {1132 .name = "st,fmc2-ebi-cs-wait-enable",1133 .bprop = true,1134 .reg_type = FMC2_REG_BCR,1135 .reg_mask = FMC2_BCR_WAITEN,1136 .check = stm32_fmc2_ebi_check_sync_trans,1137 .set = stm32_fmc2_ebi_set_bit_field,1138 },1139 {1140 .name = "st,fmc2-ebi-cs-asyncwait-enable",1141 .bprop = true,1142 .reg_type = FMC2_REG_BCR,1143 .reg_mask = FMC2_BCR_ASYNCWAIT,1144 .check = stm32_fmc2_ebi_check_async_trans,1145 .set = stm32_fmc2_ebi_set_bit_field,1146 },1147 {1148 .name = "st,fmc2-ebi-cs-cpsize",1149 .check = stm32_fmc2_ebi_check_cpsize,1150 .set = stm32_fmc2_ebi_set_cpsize,1151 },1152 {1153 .name = "st,fmc2-ebi-cs-byte-lane-setup-ns",1154 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,1155 .set = stm32_fmc2_ebi_set_bl_setup,1156 },1157 {1158 .name = "st,fmc2-ebi-cs-address-setup-ns",1159 .reg_type = FMC2_REG_BTR,1160 .reset_val = FMC2_BXTR_ADDSET_MAX,1161 .check = stm32_fmc2_ebi_check_async_trans,1162 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,1163 .set = stm32_fmc2_ebi_set_address_setup,1164 },1165 {1166 .name = "st,fmc2-ebi-cs-address-hold-ns",1167 .reg_type = FMC2_REG_BTR,1168 .reset_val = FMC2_BXTR_ADDHLD_MAX,1169 .check = stm32_fmc2_ebi_check_address_hold,1170 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,1171 .set = stm32_fmc2_ebi_set_address_hold,1172 },1173 {1174 .name = "st,fmc2-ebi-cs-data-setup-ns",1175 .reg_type = FMC2_REG_BTR,1176 .reset_val = FMC2_BXTR_DATAST_MAX,1177 .check = stm32_fmc2_ebi_check_async_trans,1178 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,1179 .set = stm32_fmc2_ebi_set_data_setup,1180 },1181 {1182 .name = "st,fmc2-ebi-cs-bus-turnaround-ns",1183 .reg_type = FMC2_REG_BTR,1184 .reset_val = FMC2_BXTR_BUSTURN_MAX + 1,1185 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,1186 .set = stm32_fmc2_ebi_set_bus_turnaround,1187 },1188 {1189 .name = "st,fmc2-ebi-cs-data-hold-ns",1190 .reg_type = FMC2_REG_BTR,1191 .check = stm32_fmc2_ebi_check_async_trans,1192 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,1193 .set = stm32_fmc2_ebi_set_data_hold,1194 },1195 {1196 .name = "st,fmc2-ebi-cs-clk-period-ns",1197 .reset_val = FMC2_CFGR_CLKDIV_MAX + 1,1198 .check = stm32_fmc2_ebi_mp25_check_clk_period,1199 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,1200 .set = stm32_fmc2_ebi_mp25_set_clk_period,1201 },1202 {1203 .name = "st,fmc2-ebi-cs-data-latency-ns",1204 .check = stm32_fmc2_ebi_check_sync_trans,1205 .calculate = stm32_fmc2_ebi_mp25_ns_to_clk_period,1206 .set = stm32_fmc2_ebi_set_data_latency,1207 },1208 {1209 .name = "st,fmc2-ebi-cs-write-address-setup-ns",1210 .reg_type = FMC2_REG_BWTR,1211 .reset_val = FMC2_BXTR_ADDSET_MAX,1212 .check = stm32_fmc2_ebi_check_async_trans,1213 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,1214 .set = stm32_fmc2_ebi_set_address_setup,1215 },1216 {1217 .name = "st,fmc2-ebi-cs-write-address-hold-ns",1218 .reg_type = FMC2_REG_BWTR,1219 .reset_val = FMC2_BXTR_ADDHLD_MAX,1220 .check = stm32_fmc2_ebi_check_address_hold,1221 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,1222 .set = stm32_fmc2_ebi_set_address_hold,1223 },1224 {1225 .name = "st,fmc2-ebi-cs-write-data-setup-ns",1226 .reg_type = FMC2_REG_BWTR,1227 .reset_val = FMC2_BXTR_DATAST_MAX,1228 .check = stm32_fmc2_ebi_check_async_trans,1229 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,1230 .set = stm32_fmc2_ebi_set_data_setup,1231 },1232 {1233 .name = "st,fmc2-ebi-cs-write-bus-turnaround-ns",1234 .reg_type = FMC2_REG_BWTR,1235 .reset_val = FMC2_BXTR_BUSTURN_MAX + 1,1236 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,1237 .set = stm32_fmc2_ebi_set_bus_turnaround,1238 },1239 {1240 .name = "st,fmc2-ebi-cs-write-data-hold-ns",1241 .reg_type = FMC2_REG_BWTR,1242 .check = stm32_fmc2_ebi_check_async_trans,1243 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,1244 .set = stm32_fmc2_ebi_set_data_hold,1245 },1246 {1247 .name = "st,fmc2-ebi-cs-max-low-pulse-ns",1248 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles,1249 .set = stm32_fmc2_ebi_mp25_set_max_low_pulse,1250 },1251};1252 1253static int stm32_fmc2_ebi_mp25_check_rif(struct stm32_fmc2_ebi *ebi, u32 resource)1254{1255 u32 seccfgr, cidcfgr, semcr;1256 int cid, ret;1257 1258 if (resource >= FMC2_MAX_RESOURCES)1259 return -EINVAL;1260 1261 ret = regmap_read(ebi->regmap, FMC2_SECCFGR, &seccfgr);1262 if (ret)1263 return ret;1264 1265 if (seccfgr & BIT(resource)) {1266 if (resource)1267 dev_err(ebi->dev, "resource %d is configured as secure\n",1268 resource);1269 1270 return -EACCES;1271 }1272 1273 ret = regmap_read(ebi->regmap, FMC2_CIDCFGR(resource), &cidcfgr);1274 if (ret)1275 return ret;1276 1277 if (!(cidcfgr & FMC2_CIDCFGR_CFEN))1278 /* CID filtering is turned off: access granted */1279 return 0;1280 1281 if (!(cidcfgr & FMC2_CIDCFGR_SEMEN)) {1282 /* Static CID mode */1283 cid = FIELD_GET(FMC2_CIDCFGR_SCID, cidcfgr);1284 if (cid != FMC2_CID1) {1285 if (resource)1286 dev_err(ebi->dev, "static CID%d set for resource %d\n",1287 cid, resource);1288 1289 return -EACCES;1290 }1291 1292 return 0;1293 }1294 1295 /* Pass-list with semaphore mode */1296 if (!(cidcfgr & FMC2_CIDCFGR_SEMWLC1)) {1297 if (resource)1298 dev_err(ebi->dev, "CID1 is block-listed for resource %d\n",1299 resource);1300 1301 return -EACCES;1302 }1303 1304 ret = regmap_read(ebi->regmap, FMC2_SEMCR(resource), &semcr);1305 if (ret)1306 return ret;1307 1308 if (!(semcr & FMC2_SEMCR_SEM_MUTEX)) {1309 regmap_update_bits(ebi->regmap, FMC2_SEMCR(resource),1310 FMC2_SEMCR_SEM_MUTEX, FMC2_SEMCR_SEM_MUTEX);1311 1312 ret = regmap_read(ebi->regmap, FMC2_SEMCR(resource), &semcr);1313 if (ret)1314 return ret;1315 }1316 1317 cid = FIELD_GET(FMC2_SEMCR_SEMCID, semcr);1318 if (cid != FMC2_CID1) {1319 if (resource)1320 dev_err(ebi->dev, "resource %d is already used by CID%d\n",1321 resource, cid);1322 1323 return -EACCES;1324 }1325 1326 ebi->sem_taken |= BIT(resource);1327 1328 return 0;1329}1330 1331static void stm32_fmc2_ebi_mp25_put_sems(struct stm32_fmc2_ebi *ebi)1332{1333 unsigned int resource;1334 1335 for (resource = 0; resource < FMC2_MAX_RESOURCES; resource++) {1336 if (!(ebi->sem_taken & BIT(resource)))1337 continue;1338 1339 regmap_update_bits(ebi->regmap, FMC2_SEMCR(resource),1340 FMC2_SEMCR_SEM_MUTEX, 0);1341 }1342}1343 1344static void stm32_fmc2_ebi_mp25_get_sems(struct stm32_fmc2_ebi *ebi)1345{1346 unsigned int resource;1347 1348 for (resource = 0; resource < FMC2_MAX_RESOURCES; resource++) {1349 if (!(ebi->sem_taken & BIT(resource)))1350 continue;1351 1352 regmap_update_bits(ebi->regmap, FMC2_SEMCR(resource),1353 FMC2_SEMCR_SEM_MUTEX, FMC2_SEMCR_SEM_MUTEX);1354 }1355}1356 1357static int stm32_fmc2_ebi_parse_prop(struct stm32_fmc2_ebi *ebi,1358 struct device_node *dev_node,1359 const struct stm32_fmc2_prop *prop,1360 int cs)1361{1362 struct device *dev = ebi->dev;1363 u32 setup = 0;1364 1365 if (!prop->set) {1366 dev_err(dev, "property %s is not well defined\n", prop->name);1367 return -EINVAL;1368 }1369 1370 if (prop->check && prop->check(ebi, prop, cs))1371 /* Skeep this property */1372 return 0;1373 1374 if (prop->bprop) {1375 bool bprop;1376 1377 bprop = of_property_read_bool(dev_node, prop->name);1378 if (prop->mprop && !bprop) {1379 dev_err(dev, "mandatory property %s not defined in the device tree\n",1380 prop->name);1381 return -EINVAL;1382 }1383 1384 if (bprop)1385 setup = 1;1386 } else {1387 u32 val;1388 int ret;1389 1390 ret = of_property_read_u32(dev_node, prop->name, &val);1391 if (prop->mprop && ret) {1392 dev_err(dev, "mandatory property %s not defined in the device tree\n",1393 prop->name);1394 return ret;1395 }1396 1397 if (ret)1398 setup = prop->reset_val;1399 else if (prop->calculate)1400 setup = prop->calculate(ebi, cs, val);1401 else1402 setup = val;1403 }1404 1405 return prop->set(ebi, prop, cs, setup);1406}1407 1408static void stm32_fmc2_ebi_enable_bank(struct stm32_fmc2_ebi *ebi, int cs)1409{1410 regmap_update_bits(ebi->regmap, FMC2_BCR(cs),1411 FMC2_BCR_MBKEN, FMC2_BCR_MBKEN);1412}1413 1414static void stm32_fmc2_ebi_disable_bank(struct stm32_fmc2_ebi *ebi, int cs)1415{1416 regmap_update_bits(ebi->regmap, FMC2_BCR(cs), FMC2_BCR_MBKEN, 0);1417}1418 1419static int stm32_fmc2_ebi_save_setup(struct stm32_fmc2_ebi *ebi)1420{1421 unsigned int cs;1422 int ret;1423 1424 for (cs = 0; cs < FMC2_MAX_EBI_CE; cs++) {1425 if (!(ebi->bank_assigned & BIT(cs)))1426 continue;1427 1428 ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &ebi->bcr[cs]);1429 ret |= regmap_read(ebi->regmap, FMC2_BTR(cs), &ebi->btr[cs]);1430 ret |= regmap_read(ebi->regmap, FMC2_BWTR(cs), &ebi->bwtr[cs]);1431 if (ret)1432 return ret;1433 }1434 1435 return 0;1436}1437 1438static int stm32_fmc2_ebi_mp1_save_setup(struct stm32_fmc2_ebi *ebi)1439{1440 int ret;1441 1442 ret = stm32_fmc2_ebi_save_setup(ebi);1443 if (ret)1444 return ret;1445 1446 return regmap_read(ebi->regmap, FMC2_PCSCNTR, &ebi->pcscntr);1447}1448 1449static int stm32_fmc2_ebi_mp25_save_setup(struct stm32_fmc2_ebi *ebi)1450{1451 int ret;1452 1453 ret = stm32_fmc2_ebi_save_setup(ebi);1454 if (ret)1455 return ret;1456 1457 if (ebi->access_granted)1458 ret = regmap_read(ebi->regmap, FMC2_CFGR, &ebi->cfgr);1459 1460 return ret;1461}1462 1463static void stm32_fmc2_ebi_set_setup(struct stm32_fmc2_ebi *ebi)1464{1465 unsigned int cs;1466 1467 for (cs = 0; cs < FMC2_MAX_EBI_CE; cs++) {1468 if (!(ebi->bank_assigned & BIT(cs)))1469 continue;1470 1471 regmap_write(ebi->regmap, FMC2_BCR(cs), ebi->bcr[cs]);1472 regmap_write(ebi->regmap, FMC2_BTR(cs), ebi->btr[cs]);1473 regmap_write(ebi->regmap, FMC2_BWTR(cs), ebi->bwtr[cs]);1474 }1475}1476 1477static void stm32_fmc2_ebi_mp1_set_setup(struct stm32_fmc2_ebi *ebi)1478{1479 stm32_fmc2_ebi_set_setup(ebi);1480 regmap_write(ebi->regmap, FMC2_PCSCNTR, ebi->pcscntr);1481}1482 1483static void stm32_fmc2_ebi_mp25_set_setup(struct stm32_fmc2_ebi *ebi)1484{1485 stm32_fmc2_ebi_set_setup(ebi);1486 1487 if (ebi->access_granted)1488 regmap_write(ebi->regmap, FMC2_CFGR, ebi->cfgr);1489}1490 1491static void stm32_fmc2_ebi_disable_banks(struct stm32_fmc2_ebi *ebi)1492{1493 unsigned int cs;1494 1495 for (cs = 0; cs < FMC2_MAX_EBI_CE; cs++) {1496 if (!(ebi->bank_assigned & BIT(cs)))1497 continue;1498 1499 stm32_fmc2_ebi_disable_bank(ebi, cs);1500 }1501}1502 1503/* NWAIT signal can not be connected to EBI controller and NAND controller */1504static int stm32_fmc2_ebi_nwait_used_by_ctrls(struct stm32_fmc2_ebi *ebi)1505{1506 struct device *dev = ebi->dev;1507 unsigned int cs;1508 u32 bcr;1509 int ret;1510 1511 for (cs = 0; cs < FMC2_MAX_EBI_CE; cs++) {1512 if (!(ebi->bank_assigned & BIT(cs)))1513 continue;1514 1515 ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);1516 if (ret)1517 return ret;1518 1519 if ((bcr & FMC2_BCR_WAITEN || bcr & FMC2_BCR_ASYNCWAIT) &&1520 ebi->bank_assigned & BIT(FMC2_NAND)) {1521 dev_err(dev, "NWAIT signal connected to EBI and NAND controllers\n");1522 return -EINVAL;1523 }1524 }1525 1526 return 0;1527}1528 1529static void stm32_fmc2_ebi_enable(struct stm32_fmc2_ebi *ebi)1530{1531 if (!ebi->access_granted)1532 return;1533 1534 regmap_update_bits(ebi->regmap, ebi->data->fmc2_enable_reg,1535 ebi->data->fmc2_enable_bit,1536 ebi->data->fmc2_enable_bit);1537}1538 1539static void stm32_fmc2_ebi_disable(struct stm32_fmc2_ebi *ebi)1540{1541 if (!ebi->access_granted)1542 return;1543 1544 regmap_update_bits(ebi->regmap, ebi->data->fmc2_enable_reg,1545 ebi->data->fmc2_enable_bit, 0);1546}1547 1548static int stm32_fmc2_ebi_setup_cs(struct stm32_fmc2_ebi *ebi,1549 struct device_node *dev_node,1550 u32 cs)1551{1552 unsigned int i;1553 int ret;1554 1555 stm32_fmc2_ebi_disable_bank(ebi, cs);1556 1557 for (i = 0; i < ebi->data->nb_child_props; i++) {1558 const struct stm32_fmc2_prop *p = &ebi->data->child_props[i];1559 1560 ret = stm32_fmc2_ebi_parse_prop(ebi, dev_node, p, cs);1561 if (ret) {1562 dev_err(ebi->dev, "property %s could not be set: %d\n",1563 p->name, ret);1564 return ret;1565 }1566 }1567 1568 stm32_fmc2_ebi_enable_bank(ebi, cs);1569 1570 return 0;1571}1572 1573static int stm32_fmc2_ebi_parse_dt(struct stm32_fmc2_ebi *ebi)1574{1575 struct device *dev = ebi->dev;1576 bool child_found = false;1577 u32 bank;1578 int ret;1579 1580 for_each_available_child_of_node_scoped(dev->of_node, child) {1581 ret = of_property_read_u32(child, "reg", &bank);1582 if (ret)1583 return dev_err_probe(dev, ret, "could not retrieve reg property\n");1584 1585 if (bank >= FMC2_MAX_BANKS) {1586 dev_err(dev, "invalid reg value: %d\n", bank);1587 return -EINVAL;1588 }1589 1590 if (ebi->bank_assigned & BIT(bank)) {1591 dev_err(dev, "bank already assigned: %d\n", bank);1592 return -EINVAL;1593 }1594 1595 if (ebi->data->check_rif) {1596 ret = ebi->data->check_rif(ebi, bank + 1);1597 if (ret) {1598 dev_err(dev, "bank access failed: %d\n", bank);1599 return ret;1600 }1601 }1602 1603 if (bank < FMC2_MAX_EBI_CE) {1604 ret = stm32_fmc2_ebi_setup_cs(ebi, child, bank);1605 if (ret)1606 return dev_err_probe(dev, ret,1607 "setup chip select %d failed\n", bank);1608 }1609 1610 ebi->bank_assigned |= BIT(bank);1611 child_found = true;1612 }1613 1614 if (!child_found) {1615 dev_warn(dev, "no subnodes found, disable the driver.\n");1616 return -ENODEV;1617 }1618 1619 if (ebi->data->nwait_used_by_ctrls) {1620 ret = ebi->data->nwait_used_by_ctrls(ebi);1621 if (ret)1622 return ret;1623 }1624 1625 stm32_fmc2_ebi_enable(ebi);1626 1627 return of_platform_populate(dev->of_node, NULL, NULL, dev);1628}1629 1630static int stm32_fmc2_ebi_probe(struct platform_device *pdev)1631{1632 struct device *dev = &pdev->dev;1633 struct stm32_fmc2_ebi *ebi;1634 struct reset_control *rstc;1635 int ret;1636 1637 ebi = devm_kzalloc(&pdev->dev, sizeof(*ebi), GFP_KERNEL);1638 if (!ebi)1639 return -ENOMEM;1640 1641 ebi->dev = dev;1642 platform_set_drvdata(pdev, ebi);1643 1644 ebi->data = of_device_get_match_data(dev);1645 if (!ebi->data)1646 return -EINVAL;1647 1648 ebi->regmap = device_node_to_regmap(dev->of_node);1649 if (IS_ERR(ebi->regmap))1650 return PTR_ERR(ebi->regmap);1651 1652 ebi->clk = devm_clk_get(dev, NULL);1653 if (IS_ERR(ebi->clk))1654 return PTR_ERR(ebi->clk);1655 1656 rstc = devm_reset_control_get(dev, NULL);1657 if (PTR_ERR(rstc) == -EPROBE_DEFER)1658 return -EPROBE_DEFER;1659 1660 ret = devm_pm_runtime_enable(dev);1661 if (ret)1662 return ret;1663 1664 ret = pm_runtime_resume_and_get(dev);1665 if (ret < 0)1666 return ret;1667 1668 if (!IS_ERR(rstc)) {1669 reset_control_assert(rstc);1670 reset_control_deassert(rstc);1671 }1672 1673 /* Check if CFGR register can be modified */1674 ebi->access_granted = true;1675 if (ebi->data->check_rif) {1676 ret = ebi->data->check_rif(ebi, 0);1677 if (ret) {1678 u32 sr;1679 1680 ebi->access_granted = false;1681 1682 ret = regmap_read(ebi->regmap, FMC2_SR, &sr);1683 if (ret)1684 goto err_release;1685 1686 /* In case of CFGR is secure, just check that the FMC2 is enabled */1687 if (sr & FMC2_SR_ISOST) {1688 dev_err(dev, "FMC2 is not ready to be used.\n");1689 ret = -EACCES;1690 goto err_release;1691 }1692 }1693 }1694 1695 ret = stm32_fmc2_ebi_parse_dt(ebi);1696 if (ret)1697 goto err_release;1698 1699 ret = ebi->data->save_setup(ebi);1700 if (ret)1701 goto err_release;1702 1703 return 0;1704 1705err_release:1706 stm32_fmc2_ebi_disable_banks(ebi);1707 stm32_fmc2_ebi_disable(ebi);1708 if (ebi->data->put_sems)1709 ebi->data->put_sems(ebi);1710 pm_runtime_put_sync_suspend(dev);1711 1712 return ret;1713}1714 1715static void stm32_fmc2_ebi_remove(struct platform_device *pdev)1716{1717 struct stm32_fmc2_ebi *ebi = platform_get_drvdata(pdev);1718 1719 of_platform_depopulate(&pdev->dev);1720 stm32_fmc2_ebi_disable_banks(ebi);1721 stm32_fmc2_ebi_disable(ebi);1722 if (ebi->data->put_sems)1723 ebi->data->put_sems(ebi);1724 pm_runtime_put_sync_suspend(&pdev->dev);1725}1726 1727static int __maybe_unused stm32_fmc2_ebi_runtime_suspend(struct device *dev)1728{1729 struct stm32_fmc2_ebi *ebi = dev_get_drvdata(dev);1730 1731 clk_disable_unprepare(ebi->clk);1732 1733 return 0;1734}1735 1736static int __maybe_unused stm32_fmc2_ebi_runtime_resume(struct device *dev)1737{1738 struct stm32_fmc2_ebi *ebi = dev_get_drvdata(dev);1739 1740 return clk_prepare_enable(ebi->clk);1741}1742 1743static int __maybe_unused stm32_fmc2_ebi_suspend(struct device *dev)1744{1745 struct stm32_fmc2_ebi *ebi = dev_get_drvdata(dev);1746 1747 stm32_fmc2_ebi_disable(ebi);1748 if (ebi->data->put_sems)1749 ebi->data->put_sems(ebi);1750 pm_runtime_put_sync_suspend(dev);1751 pinctrl_pm_select_sleep_state(dev);1752 1753 return 0;1754}1755 1756static int __maybe_unused stm32_fmc2_ebi_resume(struct device *dev)1757{1758 struct stm32_fmc2_ebi *ebi = dev_get_drvdata(dev);1759 int ret;1760 1761 pinctrl_pm_select_default_state(dev);1762 1763 ret = pm_runtime_resume_and_get(dev);1764 if (ret < 0)1765 return ret;1766 1767 if (ebi->data->get_sems)1768 ebi->data->get_sems(ebi);1769 ebi->data->set_setup(ebi);1770 stm32_fmc2_ebi_enable(ebi);1771 1772 return 0;1773}1774 1775static const struct dev_pm_ops stm32_fmc2_ebi_pm_ops = {1776 SET_RUNTIME_PM_OPS(stm32_fmc2_ebi_runtime_suspend,1777 stm32_fmc2_ebi_runtime_resume, NULL)1778 SET_SYSTEM_SLEEP_PM_OPS(stm32_fmc2_ebi_suspend, stm32_fmc2_ebi_resume)1779};1780 1781static const struct stm32_fmc2_ebi_data stm32_fmc2_ebi_mp1_data = {1782 .child_props = stm32_fmc2_child_props,1783 .nb_child_props = ARRAY_SIZE(stm32_fmc2_child_props),1784 .fmc2_enable_reg = FMC2_BCR1,1785 .fmc2_enable_bit = FMC2_BCR1_FMC2EN,1786 .nwait_used_by_ctrls = stm32_fmc2_ebi_nwait_used_by_ctrls,1787 .set_setup = stm32_fmc2_ebi_mp1_set_setup,1788 .save_setup = stm32_fmc2_ebi_mp1_save_setup,1789};1790 1791static const struct stm32_fmc2_ebi_data stm32_fmc2_ebi_mp25_data = {1792 .child_props = stm32_fmc2_mp25_child_props,1793 .nb_child_props = ARRAY_SIZE(stm32_fmc2_mp25_child_props),1794 .fmc2_enable_reg = FMC2_CFGR,1795 .fmc2_enable_bit = FMC2_CFGR_FMC2EN,1796 .set_setup = stm32_fmc2_ebi_mp25_set_setup,1797 .save_setup = stm32_fmc2_ebi_mp25_save_setup,1798 .check_rif = stm32_fmc2_ebi_mp25_check_rif,1799 .put_sems = stm32_fmc2_ebi_mp25_put_sems,1800 .get_sems = stm32_fmc2_ebi_mp25_get_sems,1801};1802 1803static const struct of_device_id stm32_fmc2_ebi_match[] = {1804 {1805 .compatible = "st,stm32mp1-fmc2-ebi",1806 .data = &stm32_fmc2_ebi_mp1_data,1807 },1808 {1809 .compatible = "st,stm32mp25-fmc2-ebi",1810 .data = &stm32_fmc2_ebi_mp25_data,1811 },1812 {}1813};1814MODULE_DEVICE_TABLE(of, stm32_fmc2_ebi_match);1815 1816static struct platform_driver stm32_fmc2_ebi_driver = {1817 .probe = stm32_fmc2_ebi_probe,1818 .remove_new = stm32_fmc2_ebi_remove,1819 .driver = {1820 .name = "stm32_fmc2_ebi",1821 .of_match_table = stm32_fmc2_ebi_match,1822 .pm = &stm32_fmc2_ebi_pm_ops,1823 },1824};1825module_platform_driver(stm32_fmc2_ebi_driver);1826 1827MODULE_ALIAS("platform:stm32_fmc2_ebi");1828MODULE_AUTHOR("Christophe Kerello <christophe.kerello@st.com>");1829MODULE_DESCRIPTION("STMicroelectronics STM32 FMC2 ebi driver");1830MODULE_LICENSE("GPL v2");1831