2121#define FMC2_BTR (x ) ((x) * 0x8 + FMC2_BTR1)
2222#define FMC2_PCSCNTR 0x20
2323#define FMC2_CFGR 0x20
24+ #define FMC2_SR 0x84
2425#define FMC2_BWTR1 0x104
2526#define FMC2_BWTR (x ) ((x) * 0x8 + FMC2_BWTR1)
27+ #define FMC2_SECCFGR 0x300
28+ #define FMC2_CIDCFGR0 0x30c
29+ #define FMC2_CIDCFGR (x ) ((x) * 0x8 + FMC2_CIDCFGR0)
30+ #define FMC2_SEMCR0 0x310
31+ #define FMC2_SEMCR (x ) ((x) * 0x8 + FMC2_SEMCR0)
2632
2733/* Register: FMC2_BCR1 */
2834#define FMC2_BCR1_CCLKEN BIT(20)
6571#define FMC2_CFGR_CCLKEN BIT(20)
6672#define FMC2_CFGR_FMC2EN BIT(31)
6773
74+ /* Register: FMC2_SR */
75+ #define FMC2_SR_ISOST GENMASK(1, 0)
76+
77+ /* Register: FMC2_CIDCFGR */
78+ #define FMC2_CIDCFGR_CFEN BIT(0)
79+ #define FMC2_CIDCFGR_SEMEN BIT(1)
80+ #define FMC2_CIDCFGR_SCID GENMASK(6, 4)
81+ #define FMC2_CIDCFGR_SEMWLC1 BIT(17)
82+
83+ /* Register: FMC2_SEMCR */
84+ #define FMC2_SEMCR_SEM_MUTEX BIT(0)
85+ #define FMC2_SEMCR_SEMCID GENMASK(6, 4)
86+
6887#define FMC2_MAX_EBI_CE 4
6988#define FMC2_MAX_BANKS 5
89+ #define FMC2_MAX_RESOURCES 6
90+ #define FMC2_CID1 1
7091
7192#define FMC2_BCR_CPSIZE_0 0x0
7293#define FMC2_BCR_CPSIZE_128 0x1
@@ -163,6 +184,9 @@ struct stm32_fmc2_ebi_data {
163184 int (* nwait_used_by_ctrls )(struct stm32_fmc2_ebi * ebi );
164185 void (* set_setup )(struct stm32_fmc2_ebi * ebi );
165186 int (* save_setup )(struct stm32_fmc2_ebi * ebi );
187+ int (* check_rif )(struct stm32_fmc2_ebi * ebi , u32 resource );
188+ void (* put_sems )(struct stm32_fmc2_ebi * ebi );
189+ void (* get_sems )(struct stm32_fmc2_ebi * ebi );
166190};
167191
168192struct stm32_fmc2_ebi {
@@ -171,6 +195,8 @@ struct stm32_fmc2_ebi {
171195 struct regmap * regmap ;
172196 const struct stm32_fmc2_ebi_data * data ;
173197 u8 bank_assigned ;
198+ u8 sem_taken ;
199+ bool access_granted ;
174200
175201 u32 bcr [FMC2_MAX_EBI_CE ];
176202 u32 btr [FMC2_MAX_EBI_CE ];
@@ -262,6 +288,33 @@ static int stm32_fmc2_ebi_check_sync_trans(struct stm32_fmc2_ebi *ebi,
262288 return - EINVAL ;
263289}
264290
291+ static int stm32_fmc2_ebi_mp25_check_cclk (struct stm32_fmc2_ebi * ebi ,
292+ const struct stm32_fmc2_prop * prop ,
293+ int cs )
294+ {
295+ if (!ebi -> access_granted )
296+ return - EACCES ;
297+
298+ return stm32_fmc2_ebi_check_sync_trans (ebi , prop , cs );
299+ }
300+
301+ static int stm32_fmc2_ebi_mp25_check_clk_period (struct stm32_fmc2_ebi * ebi ,
302+ const struct stm32_fmc2_prop * prop ,
303+ int cs )
304+ {
305+ u32 cfgr ;
306+ int ret ;
307+
308+ ret = regmap_read (ebi -> regmap , FMC2_CFGR , & cfgr );
309+ if (ret )
310+ return ret ;
311+
312+ if (cfgr & FMC2_CFGR_CCLKEN && !ebi -> access_granted )
313+ return - EACCES ;
314+
315+ return stm32_fmc2_ebi_check_sync_trans (ebi , prop , cs );
316+ }
317+
265318static int stm32_fmc2_ebi_check_async_trans (struct stm32_fmc2_ebi * ebi ,
266319 const struct stm32_fmc2_prop * prop ,
267320 int cs )
@@ -1043,7 +1096,7 @@ static const struct stm32_fmc2_prop stm32_fmc2_mp25_child_props[] = {
10431096 .bprop = true,
10441097 .reg_type = FMC2_REG_CFGR ,
10451098 .reg_mask = FMC2_CFGR_CCLKEN ,
1046- .check = stm32_fmc2_ebi_check_sync_trans ,
1099+ .check = stm32_fmc2_ebi_mp25_check_cclk ,
10471100 .set = stm32_fmc2_ebi_set_bit_field ,
10481101 },
10491102 {
@@ -1141,7 +1194,7 @@ static const struct stm32_fmc2_prop stm32_fmc2_mp25_child_props[] = {
11411194 {
11421195 .name = "st,fmc2-ebi-cs-clk-period-ns" ,
11431196 .reset_val = FMC2_CFGR_CLKDIV_MAX + 1 ,
1144- .check = stm32_fmc2_ebi_check_sync_trans ,
1197+ .check = stm32_fmc2_ebi_mp25_check_clk_period ,
11451198 .calculate = stm32_fmc2_ebi_ns_to_clock_cycles ,
11461199 .set = stm32_fmc2_ebi_mp25_set_clk_period ,
11471200 },
@@ -1196,6 +1249,110 @@ static const struct stm32_fmc2_prop stm32_fmc2_mp25_child_props[] = {
11961249 },
11971250};
11981251
1252+ static int stm32_fmc2_ebi_mp25_check_rif (struct stm32_fmc2_ebi * ebi , u32 resource )
1253+ {
1254+ u32 seccfgr , cidcfgr , semcr ;
1255+ int cid , ret ;
1256+
1257+ if (resource >= FMC2_MAX_RESOURCES )
1258+ return - EINVAL ;
1259+
1260+ ret = regmap_read (ebi -> regmap , FMC2_SECCFGR , & seccfgr );
1261+ if (ret )
1262+ return ret ;
1263+
1264+ if (seccfgr & BIT (resource )) {
1265+ if (resource )
1266+ dev_err (ebi -> dev , "resource %d is configured as secure\n" ,
1267+ resource );
1268+
1269+ return - EACCES ;
1270+ }
1271+
1272+ ret = regmap_read (ebi -> regmap , FMC2_CIDCFGR (resource ), & cidcfgr );
1273+ if (ret )
1274+ return ret ;
1275+
1276+ if (!(cidcfgr & FMC2_CIDCFGR_CFEN ))
1277+ /* CID filtering is turned off: access granted */
1278+ return 0 ;
1279+
1280+ if (!(cidcfgr & FMC2_CIDCFGR_SEMEN )) {
1281+ /* Static CID mode */
1282+ cid = FIELD_GET (FMC2_CIDCFGR_SCID , cidcfgr );
1283+ if (cid != FMC2_CID1 ) {
1284+ if (resource )
1285+ dev_err (ebi -> dev , "static CID%d set for resource %d\n" ,
1286+ cid , resource );
1287+
1288+ return - EACCES ;
1289+ }
1290+
1291+ return 0 ;
1292+ }
1293+
1294+ /* Pass-list with semaphore mode */
1295+ if (!(cidcfgr & FMC2_CIDCFGR_SEMWLC1 )) {
1296+ if (resource )
1297+ dev_err (ebi -> dev , "CID1 is block-listed for resource %d\n" ,
1298+ resource );
1299+
1300+ return - EACCES ;
1301+ }
1302+
1303+ ret = regmap_read (ebi -> regmap , FMC2_SEMCR (resource ), & semcr );
1304+ if (ret )
1305+ return ret ;
1306+
1307+ if (!(semcr & FMC2_SEMCR_SEM_MUTEX )) {
1308+ regmap_update_bits (ebi -> regmap , FMC2_SEMCR (resource ),
1309+ FMC2_SEMCR_SEM_MUTEX , FMC2_SEMCR_SEM_MUTEX );
1310+
1311+ ret = regmap_read (ebi -> regmap , FMC2_SEMCR (resource ), & semcr );
1312+ if (ret )
1313+ return ret ;
1314+ }
1315+
1316+ cid = FIELD_GET (FMC2_SEMCR_SEMCID , semcr );
1317+ if (cid != FMC2_CID1 ) {
1318+ if (resource )
1319+ dev_err (ebi -> dev , "resource %d is already used by CID%d\n" ,
1320+ resource , cid );
1321+
1322+ return - EACCES ;
1323+ }
1324+
1325+ ebi -> sem_taken |= BIT (resource );
1326+
1327+ return 0 ;
1328+ }
1329+
1330+ static void stm32_fmc2_ebi_mp25_put_sems (struct stm32_fmc2_ebi * ebi )
1331+ {
1332+ unsigned int resource ;
1333+
1334+ for (resource = 0 ; resource < FMC2_MAX_RESOURCES ; resource ++ ) {
1335+ if (!(ebi -> sem_taken & BIT (resource )))
1336+ continue ;
1337+
1338+ regmap_update_bits (ebi -> regmap , FMC2_SEMCR (resource ),
1339+ FMC2_SEMCR_SEM_MUTEX , 0 );
1340+ }
1341+ }
1342+
1343+ static void stm32_fmc2_ebi_mp25_get_sems (struct stm32_fmc2_ebi * ebi )
1344+ {
1345+ unsigned int resource ;
1346+
1347+ for (resource = 0 ; resource < FMC2_MAX_RESOURCES ; resource ++ ) {
1348+ if (!(ebi -> sem_taken & BIT (resource )))
1349+ continue ;
1350+
1351+ regmap_update_bits (ebi -> regmap , FMC2_SEMCR (resource ),
1352+ FMC2_SEMCR_SEM_MUTEX , FMC2_SEMCR_SEM_MUTEX );
1353+ }
1354+ }
1355+
11991356static int stm32_fmc2_ebi_parse_prop (struct stm32_fmc2_ebi * ebi ,
12001357 struct device_node * dev_node ,
12011358 const struct stm32_fmc2_prop * prop ,
@@ -1264,6 +1421,9 @@ static int stm32_fmc2_ebi_save_setup(struct stm32_fmc2_ebi *ebi)
12641421 int ret ;
12651422
12661423 for (cs = 0 ; cs < FMC2_MAX_EBI_CE ; cs ++ ) {
1424+ if (!(ebi -> bank_assigned & BIT (cs )))
1425+ continue ;
1426+
12671427 ret = regmap_read (ebi -> regmap , FMC2_BCR (cs ), & ebi -> bcr [cs ]);
12681428 ret |= regmap_read (ebi -> regmap , FMC2_BTR (cs ), & ebi -> btr [cs ]);
12691429 ret |= regmap_read (ebi -> regmap , FMC2_BWTR (cs ), & ebi -> bwtr [cs ]);
@@ -1293,14 +1453,20 @@ static int stm32_fmc2_ebi_mp25_save_setup(struct stm32_fmc2_ebi *ebi)
12931453 if (ret )
12941454 return ret ;
12951455
1296- return regmap_read (ebi -> regmap , FMC2_CFGR , & ebi -> cfgr );
1456+ if (ebi -> access_granted )
1457+ ret = regmap_read (ebi -> regmap , FMC2_CFGR , & ebi -> cfgr );
1458+
1459+ return ret ;
12971460}
12981461
12991462static void stm32_fmc2_ebi_set_setup (struct stm32_fmc2_ebi * ebi )
13001463{
13011464 unsigned int cs ;
13021465
13031466 for (cs = 0 ; cs < FMC2_MAX_EBI_CE ; cs ++ ) {
1467+ if (!(ebi -> bank_assigned & BIT (cs )))
1468+ continue ;
1469+
13041470 regmap_write (ebi -> regmap , FMC2_BCR (cs ), ebi -> bcr [cs ]);
13051471 regmap_write (ebi -> regmap , FMC2_BTR (cs ), ebi -> btr [cs ]);
13061472 regmap_write (ebi -> regmap , FMC2_BWTR (cs ), ebi -> bwtr [cs ]);
@@ -1316,7 +1482,9 @@ static void stm32_fmc2_ebi_mp1_set_setup(struct stm32_fmc2_ebi *ebi)
13161482static void stm32_fmc2_ebi_mp25_set_setup (struct stm32_fmc2_ebi * ebi )
13171483{
13181484 stm32_fmc2_ebi_set_setup (ebi );
1319- regmap_write (ebi -> regmap , FMC2_CFGR , ebi -> cfgr );
1485+
1486+ if (ebi -> access_granted )
1487+ regmap_write (ebi -> regmap , FMC2_CFGR , ebi -> cfgr );
13201488}
13211489
13221490static void stm32_fmc2_ebi_disable_banks (struct stm32_fmc2_ebi * ebi )
@@ -1359,13 +1527,19 @@ static int stm32_fmc2_ebi_nwait_used_by_ctrls(struct stm32_fmc2_ebi *ebi)
13591527
13601528static void stm32_fmc2_ebi_enable (struct stm32_fmc2_ebi * ebi )
13611529{
1530+ if (!ebi -> access_granted )
1531+ return ;
1532+
13621533 regmap_update_bits (ebi -> regmap , ebi -> data -> fmc2_enable_reg ,
13631534 ebi -> data -> fmc2_enable_bit ,
13641535 ebi -> data -> fmc2_enable_bit );
13651536}
13661537
13671538static void stm32_fmc2_ebi_disable (struct stm32_fmc2_ebi * ebi )
13681539{
1540+ if (!ebi -> access_granted )
1541+ return ;
1542+
13691543 regmap_update_bits (ebi -> regmap , ebi -> data -> fmc2_enable_reg ,
13701544 ebi -> data -> fmc2_enable_bit , 0 );
13711545}
@@ -1424,6 +1598,15 @@ static int stm32_fmc2_ebi_parse_dt(struct stm32_fmc2_ebi *ebi)
14241598 return - EINVAL ;
14251599 }
14261600
1601+ if (ebi -> data -> check_rif ) {
1602+ ret = ebi -> data -> check_rif (ebi , bank + 1 );
1603+ if (ret ) {
1604+ dev_err (dev , "bank access failed: %d\n" , bank );
1605+ of_node_put (child );
1606+ return ret ;
1607+ }
1608+ }
1609+
14271610 if (bank < FMC2_MAX_EBI_CE ) {
14281611 ret = stm32_fmc2_ebi_setup_cs (ebi , child , bank );
14291612 if (ret ) {
@@ -1492,6 +1675,28 @@ static int stm32_fmc2_ebi_probe(struct platform_device *pdev)
14921675 reset_control_deassert (rstc );
14931676 }
14941677
1678+ /* Check if CFGR register can be modified */
1679+ ebi -> access_granted = true;
1680+ if (ebi -> data -> check_rif ) {
1681+ ret = ebi -> data -> check_rif (ebi , 0 );
1682+ if (ret ) {
1683+ u32 sr ;
1684+
1685+ ebi -> access_granted = false;
1686+
1687+ ret = regmap_read (ebi -> regmap , FMC2_SR , & sr );
1688+ if (ret )
1689+ goto err_release ;
1690+
1691+ /* In case of CFGR is secure, just check that the FMC2 is enabled */
1692+ if (sr & FMC2_SR_ISOST ) {
1693+ dev_err (dev , "FMC2 is not ready to be used.\n" );
1694+ ret = - EACCES ;
1695+ goto err_release ;
1696+ }
1697+ }
1698+ }
1699+
14951700 ret = stm32_fmc2_ebi_parse_dt (ebi );
14961701 if (ret )
14971702 goto err_release ;
@@ -1507,6 +1712,8 @@ static int stm32_fmc2_ebi_probe(struct platform_device *pdev)
15071712err_release :
15081713 stm32_fmc2_ebi_disable_banks (ebi );
15091714 stm32_fmc2_ebi_disable (ebi );
1715+ if (ebi -> data -> put_sems )
1716+ ebi -> data -> put_sems (ebi );
15101717 clk_disable_unprepare (ebi -> clk );
15111718
15121719 return ret ;
@@ -1519,6 +1726,8 @@ static void stm32_fmc2_ebi_remove(struct platform_device *pdev)
15191726 of_platform_depopulate (& pdev -> dev );
15201727 stm32_fmc2_ebi_disable_banks (ebi );
15211728 stm32_fmc2_ebi_disable (ebi );
1729+ if (ebi -> data -> put_sems )
1730+ ebi -> data -> put_sems (ebi );
15221731 clk_disable_unprepare (ebi -> clk );
15231732}
15241733
@@ -1527,6 +1736,8 @@ static int __maybe_unused stm32_fmc2_ebi_suspend(struct device *dev)
15271736 struct stm32_fmc2_ebi * ebi = dev_get_drvdata (dev );
15281737
15291738 stm32_fmc2_ebi_disable (ebi );
1739+ if (ebi -> data -> put_sems )
1740+ ebi -> data -> put_sems (ebi );
15301741 clk_disable_unprepare (ebi -> clk );
15311742 pinctrl_pm_select_sleep_state (dev );
15321743
@@ -1544,6 +1755,8 @@ static int __maybe_unused stm32_fmc2_ebi_resume(struct device *dev)
15441755 if (ret )
15451756 return ret ;
15461757
1758+ if (ebi -> data -> get_sems )
1759+ ebi -> data -> get_sems (ebi );
15471760 ebi -> data -> set_setup (ebi );
15481761 stm32_fmc2_ebi_enable (ebi );
15491762
@@ -1570,6 +1783,9 @@ static const struct stm32_fmc2_ebi_data stm32_fmc2_ebi_mp25_data = {
15701783 .fmc2_enable_bit = FMC2_CFGR_FMC2EN ,
15711784 .set_setup = stm32_fmc2_ebi_mp25_set_setup ,
15721785 .save_setup = stm32_fmc2_ebi_mp25_save_setup ,
1786+ .check_rif = stm32_fmc2_ebi_mp25_check_rif ,
1787+ .put_sems = stm32_fmc2_ebi_mp25_put_sems ,
1788+ .get_sems = stm32_fmc2_ebi_mp25_get_sems ,
15731789};
15741790
15751791static const struct of_device_id stm32_fmc2_ebi_match [] = {
0 commit comments