58
58
* Below table summarizes the clock requirement and clock sources for
59
59
* supported phy interface modes.
60
60
* __________________________________________________________________________
61
- *|PHY_MODE | Normal | PHY wo crystal| PHY wo crystal |No 125Mhz from PHY|
61
+ *|PHY_MODE | Normal | PHY wo crystal| PHY wo crystal |No 125MHz from PHY|
62
62
*| | | 25MHz | 50MHz | |
63
63
* ---------------------------------------------------------------------------
64
64
*| MII | - | eth-ck | n/a | n/a |
@@ -90,6 +90,7 @@ struct stm32_dwmac {
90
90
int eth_ref_clk_sel_reg ;
91
91
int irq_pwr_wakeup ;
92
92
u32 mode_reg ; /* MAC glue-logic mode register */
93
+ u32 mode_mask ;
93
94
struct regmap * regmap ;
94
95
u32 speed ;
95
96
const struct stm32_ops * ops ;
@@ -102,8 +103,9 @@ struct stm32_ops {
102
103
void (* resume )(struct stm32_dwmac * dwmac );
103
104
int (* parse_data )(struct stm32_dwmac * dwmac ,
104
105
struct device * dev );
105
- u32 syscfg_eth_mask ;
106
106
bool clk_rx_enable_in_suspend ;
107
+ bool is_mp13 ;
108
+ u32 syscfg_clr_off ;
107
109
};
108
110
109
111
static int stm32_dwmac_clk_enable (struct stm32_dwmac * dwmac , bool resume )
@@ -157,65 +159,137 @@ static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat, bool resume)
157
159
return stm32_dwmac_clk_enable (dwmac , resume );
158
160
}
159
161
160
- static int stm32mp1_set_mode (struct plat_stmmacenet_data * plat_dat )
162
+ static int stm32mp1_select_ethck_external (struct plat_stmmacenet_data * plat_dat )
161
163
{
162
164
struct stm32_dwmac * dwmac = plat_dat -> bsp_priv ;
163
- u32 reg = dwmac -> mode_reg , clk_rate ;
164
- int val ;
165
165
166
- clk_rate = clk_get_rate (dwmac -> clk_eth_ck );
167
- dwmac -> enable_eth_ck = false;
168
166
switch (plat_dat -> mac_interface ) {
169
167
case PHY_INTERFACE_MODE_MII :
170
- if (clk_rate == ETH_CK_F_25M && dwmac -> ext_phyclk )
171
- dwmac -> enable_eth_ck = true;
172
- val = SYSCFG_PMCR_ETH_SEL_MII ;
173
- pr_debug ("SYSCFG init : PHY_INTERFACE_MODE_MII\n" );
168
+ dwmac -> enable_eth_ck = dwmac -> ext_phyclk ;
169
+ return 0 ;
170
+ case PHY_INTERFACE_MODE_GMII :
171
+ dwmac -> enable_eth_ck = dwmac -> eth_clk_sel_reg ||
172
+ dwmac -> ext_phyclk ;
173
+ return 0 ;
174
+ case PHY_INTERFACE_MODE_RMII :
175
+ dwmac -> enable_eth_ck = dwmac -> eth_ref_clk_sel_reg ||
176
+ dwmac -> ext_phyclk ;
177
+ return 0 ;
178
+ case PHY_INTERFACE_MODE_RGMII :
179
+ case PHY_INTERFACE_MODE_RGMII_ID :
180
+ case PHY_INTERFACE_MODE_RGMII_RXID :
181
+ case PHY_INTERFACE_MODE_RGMII_TXID :
182
+ dwmac -> enable_eth_ck = dwmac -> eth_clk_sel_reg ||
183
+ dwmac -> ext_phyclk ;
184
+ return 0 ;
185
+ default :
186
+ dwmac -> enable_eth_ck = false;
187
+ dev_err (dwmac -> dev , "Mode %s not supported" ,
188
+ phy_modes (plat_dat -> mac_interface ));
189
+ return - EINVAL ;
190
+ }
191
+ }
192
+
193
+ static int stm32mp1_validate_ethck_rate (struct plat_stmmacenet_data * plat_dat )
194
+ {
195
+ struct stm32_dwmac * dwmac = plat_dat -> bsp_priv ;
196
+ const u32 clk_rate = clk_get_rate (dwmac -> clk_eth_ck );
197
+
198
+ switch (plat_dat -> mac_interface ) {
199
+ case PHY_INTERFACE_MODE_MII :
200
+ case PHY_INTERFACE_MODE_GMII :
201
+ if (clk_rate == ETH_CK_F_25M )
202
+ return 0 ;
203
+ break ;
204
+ case PHY_INTERFACE_MODE_RMII :
205
+ if (clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_50M )
206
+ return 0 ;
207
+ break ;
208
+ case PHY_INTERFACE_MODE_RGMII :
209
+ case PHY_INTERFACE_MODE_RGMII_ID :
210
+ case PHY_INTERFACE_MODE_RGMII_RXID :
211
+ case PHY_INTERFACE_MODE_RGMII_TXID :
212
+ if (clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_125M )
213
+ return 0 ;
214
+ break ;
215
+ default :
216
+ break ;
217
+ }
218
+
219
+ dev_err (dwmac -> dev , "Mode %s does not match eth-ck frequency %d Hz" ,
220
+ phy_modes (plat_dat -> mac_interface ), clk_rate );
221
+ return - EINVAL ;
222
+ }
223
+
224
+ static int stm32mp1_configure_pmcr (struct plat_stmmacenet_data * plat_dat )
225
+ {
226
+ struct stm32_dwmac * dwmac = plat_dat -> bsp_priv ;
227
+ u32 reg = dwmac -> mode_reg ;
228
+ int val = 0 ;
229
+
230
+ switch (plat_dat -> mac_interface ) {
231
+ case PHY_INTERFACE_MODE_MII :
232
+ /*
233
+ * STM32MP15xx supports both MII and GMII, STM32MP13xx MII only.
234
+ * SYSCFG_PMCSETR ETH_SELMII is present only on STM32MP15xx and
235
+ * acts as a selector between 0:GMII and 1:MII. As STM32MP13xx
236
+ * supports only MII, ETH_SELMII is not present.
237
+ */
238
+ if (!dwmac -> ops -> is_mp13 ) /* Select MII mode on STM32MP15xx */
239
+ val |= SYSCFG_PMCR_ETH_SEL_MII ;
174
240
break ;
175
241
case PHY_INTERFACE_MODE_GMII :
176
242
val = SYSCFG_PMCR_ETH_SEL_GMII ;
177
- if (clk_rate == ETH_CK_F_25M &&
178
- (dwmac -> eth_clk_sel_reg || dwmac -> ext_phyclk )) {
179
- dwmac -> enable_eth_ck = true;
243
+ if (dwmac -> enable_eth_ck )
180
244
val |= SYSCFG_PMCR_ETH_CLK_SEL ;
181
- }
182
- pr_debug ("SYSCFG init : PHY_INTERFACE_MODE_GMII\n" );
183
245
break ;
184
246
case PHY_INTERFACE_MODE_RMII :
185
247
val = SYSCFG_PMCR_ETH_SEL_RMII ;
186
- if ((clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_50M ) &&
187
- (dwmac -> eth_ref_clk_sel_reg || dwmac -> ext_phyclk )) {
188
- dwmac -> enable_eth_ck = true;
248
+ if (dwmac -> enable_eth_ck )
189
249
val |= SYSCFG_PMCR_ETH_REF_CLK_SEL ;
190
- }
191
- pr_debug ("SYSCFG init : PHY_INTERFACE_MODE_RMII\n" );
192
250
break ;
193
251
case PHY_INTERFACE_MODE_RGMII :
194
252
case PHY_INTERFACE_MODE_RGMII_ID :
195
253
case PHY_INTERFACE_MODE_RGMII_RXID :
196
254
case PHY_INTERFACE_MODE_RGMII_TXID :
197
255
val = SYSCFG_PMCR_ETH_SEL_RGMII ;
198
- if ((clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_125M ) &&
199
- (dwmac -> eth_clk_sel_reg || dwmac -> ext_phyclk )) {
200
- dwmac -> enable_eth_ck = true;
256
+ if (dwmac -> enable_eth_ck )
201
257
val |= SYSCFG_PMCR_ETH_CLK_SEL ;
202
- }
203
- pr_debug ("SYSCFG init : PHY_INTERFACE_MODE_RGMII\n" );
204
258
break ;
205
259
default :
206
- pr_debug ( "SYSCFG init : Do not manage %d interface\n " ,
207
- plat_dat -> mac_interface );
260
+ dev_err ( dwmac -> dev , "Mode %s not supported " ,
261
+ phy_modes ( plat_dat -> mac_interface ) );
208
262
/* Do not manage others interfaces */
209
263
return - EINVAL ;
210
264
}
211
265
266
+ dev_dbg (dwmac -> dev , "Mode %s" , phy_modes (plat_dat -> mac_interface ));
267
+
268
+ /* Shift value at correct ethernet MAC offset in SYSCFG_PMCSETR */
269
+ val <<= ffs (dwmac -> mode_mask ) - ffs (SYSCFG_MP1_ETH_MASK );
270
+
212
271
/* Need to update PMCCLRR (clear register) */
213
- regmap_write (dwmac -> regmap , reg + SYSCFG_PMCCLRR_OFFSET ,
214
- dwmac -> ops -> syscfg_eth_mask );
272
+ regmap_write (dwmac -> regmap , dwmac -> ops -> syscfg_clr_off ,
273
+ dwmac -> mode_mask );
215
274
216
275
/* Update PMCSETR (set register) */
217
276
return regmap_update_bits (dwmac -> regmap , reg ,
218
- dwmac -> ops -> syscfg_eth_mask , val );
277
+ dwmac -> mode_mask , val );
278
+ }
279
+
280
+ static int stm32mp1_set_mode (struct plat_stmmacenet_data * plat_dat )
281
+ {
282
+ int ret ;
283
+
284
+ ret = stm32mp1_select_ethck_external (plat_dat );
285
+ if (ret )
286
+ return ret ;
287
+
288
+ ret = stm32mp1_validate_ethck_rate (plat_dat );
289
+ if (ret )
290
+ return ret ;
291
+
292
+ return stm32mp1_configure_pmcr (plat_dat );
219
293
}
220
294
221
295
static int stm32mcu_set_mode (struct plat_stmmacenet_data * plat_dat )
@@ -227,21 +301,21 @@ static int stm32mcu_set_mode(struct plat_stmmacenet_data *plat_dat)
227
301
switch (plat_dat -> mac_interface ) {
228
302
case PHY_INTERFACE_MODE_MII :
229
303
val = SYSCFG_MCU_ETH_SEL_MII ;
230
- pr_debug ("SYSCFG init : PHY_INTERFACE_MODE_MII\n" );
231
304
break ;
232
305
case PHY_INTERFACE_MODE_RMII :
233
306
val = SYSCFG_MCU_ETH_SEL_RMII ;
234
- pr_debug ("SYSCFG init : PHY_INTERFACE_MODE_RMII\n" );
235
307
break ;
236
308
default :
237
- pr_debug ( "SYSCFG init : Do not manage %d interface\n " ,
238
- plat_dat -> mac_interface );
309
+ dev_err ( dwmac -> dev , "Mode %s not supported " ,
310
+ phy_modes ( plat_dat -> mac_interface ) );
239
311
/* Do not manage others interfaces */
240
312
return - EINVAL ;
241
313
}
242
314
315
+ dev_dbg (dwmac -> dev , "Mode %s" , phy_modes (plat_dat -> mac_interface ));
316
+
243
317
return regmap_update_bits (dwmac -> regmap , reg ,
244
- dwmac -> ops -> syscfg_eth_mask , val << 23 );
318
+ SYSCFG_MCU_ETH_MASK , val << 23 );
245
319
}
246
320
247
321
static void stm32_dwmac_clk_disable (struct stm32_dwmac * dwmac , bool suspend )
@@ -286,8 +360,19 @@ static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac,
286
360
return PTR_ERR (dwmac -> regmap );
287
361
288
362
err = of_property_read_u32_index (np , "st,syscon" , 1 , & dwmac -> mode_reg );
289
- if (err )
363
+ if (err ) {
290
364
dev_err (dev , "Can't get sysconfig mode offset (%d)\n" , err );
365
+ return err ;
366
+ }
367
+
368
+ dwmac -> mode_mask = SYSCFG_MP1_ETH_MASK ;
369
+ err = of_property_read_u32_index (np , "st,syscon" , 2 , & dwmac -> mode_mask );
370
+ if (err ) {
371
+ if (dwmac -> ops -> is_mp13 )
372
+ dev_err (dev , "Sysconfig register mask must be set (%d)\n" , err );
373
+ else
374
+ dev_dbg (dev , "Warning sysconfig register mask not set\n" );
375
+ }
291
376
292
377
return err ;
293
378
}
@@ -305,7 +390,7 @@ static int stm32mp1_parse_data(struct stm32_dwmac *dwmac,
305
390
/* Gigabit Ethernet 125MHz clock selection. */
306
391
dwmac -> eth_clk_sel_reg = of_property_read_bool (np , "st,eth-clk-sel" );
307
392
308
- /* Ethernet 50Mhz RMII clock selection */
393
+ /* Ethernet 50MHz RMII clock selection */
309
394
dwmac -> eth_ref_clk_sel_reg =
310
395
of_property_read_bool (np , "st,eth-ref-clk-sel" );
311
396
@@ -478,22 +563,33 @@ static SIMPLE_DEV_PM_OPS(stm32_dwmac_pm_ops,
478
563
stm32_dwmac_suspend , stm32_dwmac_resume ) ;
479
564
480
565
static struct stm32_ops stm32mcu_dwmac_data = {
481
- .set_mode = stm32mcu_set_mode ,
482
- .syscfg_eth_mask = SYSCFG_MCU_ETH_MASK
566
+ .set_mode = stm32mcu_set_mode
483
567
};
484
568
485
569
static struct stm32_ops stm32mp1_dwmac_data = {
486
570
.set_mode = stm32mp1_set_mode ,
487
571
.suspend = stm32mp1_suspend ,
488
572
.resume = stm32mp1_resume ,
489
573
.parse_data = stm32mp1_parse_data ,
490
- .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK ,
574
+ .syscfg_clr_off = 0x44 ,
575
+ .is_mp13 = false,
576
+ .clk_rx_enable_in_suspend = true
577
+ };
578
+
579
+ static struct stm32_ops stm32mp13_dwmac_data = {
580
+ .set_mode = stm32mp1_set_mode ,
581
+ .suspend = stm32mp1_suspend ,
582
+ .resume = stm32mp1_resume ,
583
+ .parse_data = stm32mp1_parse_data ,
584
+ .syscfg_clr_off = 0x08 ,
585
+ .is_mp13 = true,
491
586
.clk_rx_enable_in_suspend = true
492
587
};
493
588
494
589
static const struct of_device_id stm32_dwmac_match [] = {
495
590
{ .compatible = "st,stm32-dwmac" , .data = & stm32mcu_dwmac_data },
496
591
{ .compatible = "st,stm32mp1-dwmac" , .data = & stm32mp1_dwmac_data },
592
+ { .compatible = "st,stm32mp13-dwmac" , .data = & stm32mp13_dwmac_data },
497
593
{ }
498
594
};
499
595
MODULE_DEVICE_TABLE (of , stm32_dwmac_match );
0 commit comments