brintos

brintos / linux-shallow public Read only

0
0
Text · 45.6 KiB · 566c225 Raw
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, &reg);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, &reg);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, &reg);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, &reg);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, &reg);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, &reg);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