Skip to content

Commit 3873d0d

Browse files
author
Paolo Abeni
committed
Merge branch 'series-to-deliver-ethernet-for-stm32mp13'
Christophe Roullier says: ==================== Series to deliver Ethernet for STM32MP13 STM32MP13 is STM32 SOC with 2 GMACs instances GMAC IP version is SNPS 4.20. GMAC IP configure with 1 RX and 1 TX queue. DMA HW capability register supported RX Checksum Offload Engine supported TX Checksum insertion supported Wake-Up On Lan supported TSO supported Rework dwmac glue to simplify management for next stm32 (integrate RFC from Marek) V2: - Remark from Rob Herring (add Krzysztof's ack in patch 02/11, update in yaml) Remark from Serge Semin (upate commits msg) V3: - Remove PHY regulator patch and Ethernet2 DT because need to clarify how to manage PHY regulator (in glue or PHY side) - Integrate RFC from Marek - Remark from Rob Herring in YAML documentation V4: - Remark from Marek (remove max-speed, extra space in DT, update commit msg) - Remark from Rasmus (add sign-off, add base-commit) - Remark from Sai Krishna Gajula V5: - Fix warning during build CHECK_DTBS - Remark from Marek (glue + DT update) - Remark from Krzysztof about YAML (Make it symmetric) V6: - Replace pr_debug by dev_dbg - Split serie driver/DTs separately V7: - Remark from Marek (update sysconfig register mask) ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
2 parents 5f703ce + 50bbc03 commit 3873d0d

File tree

2 files changed

+173
-48
lines changed

2 files changed

+173
-48
lines changed

Documentation/devicetree/bindings/net/stm32-dwmac.yaml

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,17 @@ select:
2222
enum:
2323
- st,stm32-dwmac
2424
- st,stm32mp1-dwmac
25+
- st,stm32mp13-dwmac
2526
required:
2627
- compatible
2728

28-
allOf:
29-
- $ref: snps,dwmac.yaml#
30-
3129
properties:
3230
compatible:
3331
oneOf:
3432
- items:
3533
- enum:
3634
- st,stm32mp1-dwmac
35+
- st,stm32mp13-dwmac
3736
- const: snps,dwmac-4.20a
3837
- items:
3938
- enum:
@@ -75,12 +74,15 @@ properties:
7574
st,syscon:
7675
$ref: /schemas/types.yaml#/definitions/phandle-array
7776
items:
78-
- items:
77+
- minItems: 2
78+
items:
7979
- description: phandle to the syscon node which encompases the glue register
8080
- description: offset of the control register
81+
- description: field to set mask in register
8182
description:
8283
Should be phandle/offset pair. The phandle to the syscon node which
83-
encompases the glue register, and the offset of the control register
84+
encompases the glue register, the offset of the control register and
85+
the mask to set bitfield in control register
8486

8587
st,ext-phyclk:
8688
description:
@@ -112,12 +114,39 @@ required:
112114

113115
unevaluatedProperties: false
114116

117+
allOf:
118+
- $ref: snps,dwmac.yaml#
119+
- if:
120+
properties:
121+
compatible:
122+
contains:
123+
enum:
124+
- st,stm32mp1-dwmac
125+
- st,stm32-dwmac
126+
then:
127+
properties:
128+
st,syscon:
129+
items:
130+
minItems: 2
131+
maxItems: 2
132+
133+
- if:
134+
properties:
135+
compatible:
136+
contains:
137+
enum:
138+
- st,stm32mp13-dwmac
139+
then:
140+
properties:
141+
st,syscon:
142+
items:
143+
minItems: 3
144+
maxItems: 3
145+
115146
examples:
116147
- |
117148
#include <dt-bindings/interrupt-controller/arm-gic.h>
118149
#include <dt-bindings/clock/stm32mp1-clks.h>
119-
#include <dt-bindings/reset/stm32mp1-resets.h>
120-
#include <dt-bindings/mfd/stm32h7-rcc.h>
121150
//Example 1
122151
ethernet0: ethernet@5800a000 {
123152
compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a";

drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c

Lines changed: 137 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
* Below table summarizes the clock requirement and clock sources for
5959
* supported phy interface modes.
6060
* __________________________________________________________________________
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|
6262
*| | | 25MHz | 50MHz | |
6363
* ---------------------------------------------------------------------------
6464
*| MII | - | eth-ck | n/a | n/a |
@@ -90,6 +90,7 @@ struct stm32_dwmac {
9090
int eth_ref_clk_sel_reg;
9191
int irq_pwr_wakeup;
9292
u32 mode_reg; /* MAC glue-logic mode register */
93+
u32 mode_mask;
9394
struct regmap *regmap;
9495
u32 speed;
9596
const struct stm32_ops *ops;
@@ -102,8 +103,9 @@ struct stm32_ops {
102103
void (*resume)(struct stm32_dwmac *dwmac);
103104
int (*parse_data)(struct stm32_dwmac *dwmac,
104105
struct device *dev);
105-
u32 syscfg_eth_mask;
106106
bool clk_rx_enable_in_suspend;
107+
bool is_mp13;
108+
u32 syscfg_clr_off;
107109
};
108110

109111
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)
157159
return stm32_dwmac_clk_enable(dwmac, resume);
158160
}
159161

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)
161163
{
162164
struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
163-
u32 reg = dwmac->mode_reg, clk_rate;
164-
int val;
165165

166-
clk_rate = clk_get_rate(dwmac->clk_eth_ck);
167-
dwmac->enable_eth_ck = false;
168166
switch (plat_dat->mac_interface) {
169167
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;
174240
break;
175241
case PHY_INTERFACE_MODE_GMII:
176242
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)
180244
val |= SYSCFG_PMCR_ETH_CLK_SEL;
181-
}
182-
pr_debug("SYSCFG init : PHY_INTERFACE_MODE_GMII\n");
183245
break;
184246
case PHY_INTERFACE_MODE_RMII:
185247
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)
189249
val |= SYSCFG_PMCR_ETH_REF_CLK_SEL;
190-
}
191-
pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n");
192250
break;
193251
case PHY_INTERFACE_MODE_RGMII:
194252
case PHY_INTERFACE_MODE_RGMII_ID:
195253
case PHY_INTERFACE_MODE_RGMII_RXID:
196254
case PHY_INTERFACE_MODE_RGMII_TXID:
197255
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)
201257
val |= SYSCFG_PMCR_ETH_CLK_SEL;
202-
}
203-
pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RGMII\n");
204258
break;
205259
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));
208262
/* Do not manage others interfaces */
209263
return -EINVAL;
210264
}
211265

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+
212271
/* 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);
215274

216275
/* Update PMCSETR (set register) */
217276
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);
219293
}
220294

221295
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)
227301
switch (plat_dat->mac_interface) {
228302
case PHY_INTERFACE_MODE_MII:
229303
val = SYSCFG_MCU_ETH_SEL_MII;
230-
pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n");
231304
break;
232305
case PHY_INTERFACE_MODE_RMII:
233306
val = SYSCFG_MCU_ETH_SEL_RMII;
234-
pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n");
235307
break;
236308
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));
239311
/* Do not manage others interfaces */
240312
return -EINVAL;
241313
}
242314

315+
dev_dbg(dwmac->dev, "Mode %s", phy_modes(plat_dat->mac_interface));
316+
243317
return regmap_update_bits(dwmac->regmap, reg,
244-
dwmac->ops->syscfg_eth_mask, val << 23);
318+
SYSCFG_MCU_ETH_MASK, val << 23);
245319
}
246320

247321
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,
286360
return PTR_ERR(dwmac->regmap);
287361

288362
err = of_property_read_u32_index(np, "st,syscon", 1, &dwmac->mode_reg);
289-
if (err)
363+
if (err) {
290364
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+
}
291376

292377
return err;
293378
}
@@ -305,7 +390,7 @@ static int stm32mp1_parse_data(struct stm32_dwmac *dwmac,
305390
/* Gigabit Ethernet 125MHz clock selection. */
306391
dwmac->eth_clk_sel_reg = of_property_read_bool(np, "st,eth-clk-sel");
307392

308-
/* Ethernet 50Mhz RMII clock selection */
393+
/* Ethernet 50MHz RMII clock selection */
309394
dwmac->eth_ref_clk_sel_reg =
310395
of_property_read_bool(np, "st,eth-ref-clk-sel");
311396

@@ -478,22 +563,33 @@ static SIMPLE_DEV_PM_OPS(stm32_dwmac_pm_ops,
478563
stm32_dwmac_suspend, stm32_dwmac_resume);
479564

480565
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
483567
};
484568

485569
static struct stm32_ops stm32mp1_dwmac_data = {
486570
.set_mode = stm32mp1_set_mode,
487571
.suspend = stm32mp1_suspend,
488572
.resume = stm32mp1_resume,
489573
.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,
491586
.clk_rx_enable_in_suspend = true
492587
};
493588

494589
static const struct of_device_id stm32_dwmac_match[] = {
495590
{ .compatible = "st,stm32-dwmac", .data = &stm32mcu_dwmac_data},
496591
{ .compatible = "st,stm32mp1-dwmac", .data = &stm32mp1_dwmac_data},
592+
{ .compatible = "st,stm32mp13-dwmac", .data = &stm32mp13_dwmac_data},
497593
{ }
498594
};
499595
MODULE_DEVICE_TABLE(of, stm32_dwmac_match);

0 commit comments

Comments
 (0)