[RESEND PATCH v2 00/11] Add dwc_eth_qos support for rockchip

Rockchip Socs can support two controllers "snps, dwmac-4.20a" and "snps, dwmac-3.50". In order to support two at gmac-rockchip.c, export public interface functions and struct data, it will be more general for others.
Changes in v2: - None - Remove the code is not related (Patrice) - None - Don't change the Rx and Tx clock names. (Patrice, Stephen) - None - None - Add the lost head file. (Patrice) - None - None - None - None
David Wu (11): net: dwc_eth_qos: Use dev_ functions calls to get FDT data net: dwc_eth_qos: Add option "snps,reset-gpio" phy-rst gpio for stm32 net: dwc_eth_qos: Move interface() to eqos_ops structure net: dwc_eth_qos: Make clk_rx and clk_tx optional net: dwc_eth_qos: Split eqos_start() to get link speed net: dwc_eth_qos: make eqos_start_clks and eqos_stop_clks optional net: dwc_eth_qos: Export common struct and interface at head file net: gmac_rockchip: Add dwc_eth_qos support net: dwc_eth_qos: Add eqos_rockchip_ops net: dwc_eth_qos: Add EQOS_MAC_MDIO_ADDRESS_CR_100_150 for Rockchip net: gmac_rockchip: Add RV1126 gmac support
drivers/net/Kconfig | 2 +- drivers/net/dwc_eth_qos.c | 279 ++++++++++++++++++------------------ drivers/net/dwc_eth_qos.h | 89 ++++++++++++ drivers/net/gmac_rockchip.c | 188 ++++++++++++++++++++---- 4 files changed, 393 insertions(+), 165 deletions(-) create mode 100644 drivers/net/dwc_eth_qos.h

It seems dev_ functions are more general than fdt_ functions.
Signed-off-by: David Wu david.wu@rock-chips.com ---
Changes in v2: - None
drivers/net/dwc_eth_qos.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index f67c5f4570..66a02aa80b 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1889,8 +1889,7 @@ static phy_interface_t eqos_get_interface_stm32(struct udevice *dev)
debug("%s(dev=%p):\n", __func__, dev);
- phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode", - NULL); + phy_mode = dev_read_string(dev, "phy-mode"); if (phy_mode) interface = phy_get_interface_by_name(phy_mode);
@@ -1991,9 +1990,9 @@ static int eqos_probe(struct udevice *dev) eqos->dev = dev; eqos->config = (void *)dev_get_driver_data(dev);
- eqos->regs = devfdt_get_addr(dev); + eqos->regs = dev_read_addr(dev); if (eqos->regs == FDT_ADDR_T_NONE) { - pr_err("devfdt_get_addr() failed"); + pr_err("dev_read_addr() failed"); return -ENODEV; } eqos->mac_regs = (void *)(eqos->regs + EQOS_MAC_REGS_BASE);

Hi David
On 5/12/20 11:56 AM, David Wu wrote:
It seems dev_ functions are more general than fdt_ functions.
Signed-off-by: David Wu david.wu@rock-chips.com
Changes in v2:
- None
drivers/net/dwc_eth_qos.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index f67c5f4570..66a02aa80b 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1889,8 +1889,7 @@ static phy_interface_t eqos_get_interface_stm32(struct udevice *dev)
debug("%s(dev=%p):\n", __func__, dev);
- phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
NULL);
- phy_mode = dev_read_string(dev, "phy-mode"); if (phy_mode) interface = phy_get_interface_by_name(phy_mode);
@@ -1991,9 +1990,9 @@ static int eqos_probe(struct udevice *dev) eqos->dev = dev; eqos->config = (void *)dev_get_driver_data(dev);
- eqos->regs = devfdt_get_addr(dev);
- eqos->regs = dev_read_addr(dev); if (eqos->regs == FDT_ADDR_T_NONE) {
pr_err("devfdt_get_addr() failed");
return -ENODEV; } eqos->mac_regs = (void *)(eqos->regs + EQOS_MAC_REGS_BASE);pr_err("dev_read_addr() failed");
Reviewed-by: Patrice Chotard patrice.chotard@st.com
Thanks

Dear David,
From: David Wu david.wu@rock-chips.com Sent: mardi 12 mai 2020 11:56
It seems dev_ functions are more general than fdt_ functions.
Signed-off-by: David Wu david.wu@rock-chips.com
Changes in v2:
- None
drivers/net/dwc_eth_qos.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index f67c5f4570..66a02aa80b 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1889,8 +1889,7 @@ static phy_interface_t eqos_get_interface_stm32(struct udevice *dev)
debug("%s(dev=%p):\n", __func__, dev);
- phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
NULL);
- phy_mode = dev_read_string(dev, "phy-mode"); if (phy_mode) interface = phy_get_interface_by_name(phy_mode);
@@ -1991,9 +1990,9 @@ static int eqos_probe(struct udevice *dev) eqos->dev = dev; eqos->config = (void *)dev_get_driver_data(dev);
- eqos->regs = devfdt_get_addr(dev);
- eqos->regs = dev_read_addr(dev); if (eqos->regs == FDT_ADDR_T_NONE) {
pr_err("devfdt_get_addr() failed");
return -ENODEV; } eqos->mac_regs = (void *)(eqos->regs + EQOS_MAC_REGS_BASE);pr_err("dev_read_addr() failed");
-- 2.19.1
Reviewed-by: Patrick Delaunay patrick.delaunay@st.com
Thanks
Patrick

On 5/13/20 2:58 PM, Patrick DELAUNAY wrote:
Dear David,
From: David Wu david.wu@rock-chips.com Sent: mardi 12 mai 2020 11:56
It seems dev_ functions are more general than fdt_ functions.
Signed-off-by: David Wu david.wu@rock-chips.com
It seems Joe still didn't come back, I have patches open for two+ months now. What do we do ?
[...]

It can be seen that most of the Socs using STM mac, "snps,reset-gpio" gpio is used, adding this option makes reset function more general.
Signed-off-by: David Wu david.wu@rock-chips.com ---
Changes in v2: - Remove the code is not related (Patrice)
drivers/net/dwc_eth_qos.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 66a02aa80b..92dab678c7 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -314,6 +314,7 @@ struct eqos_priv { struct eqos_tegra186_regs *tegra186_regs; struct reset_ctl reset_ctl; struct gpio_desc phy_reset_gpio; + u32 reset_delays[3]; struct clk clk_master_bus; struct clk clk_rx; struct clk clk_ptp_ref; @@ -739,6 +740,15 @@ static int eqos_start_resets_stm32(struct udevice *dev)
debug("%s(dev=%p):\n", __func__, dev); if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) { + ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0); + if (ret < 0) { + pr_err("dm_gpio_set_value(phy_reset, deassert) failed: %d", + ret); + return ret; + } + + udelay(eqos->reset_delays[0]); + ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 1); if (ret < 0) { pr_err("dm_gpio_set_value(phy_reset, assert) failed: %d", @@ -746,7 +756,7 @@ static int eqos_start_resets_stm32(struct udevice *dev) return ret; }
- udelay(2); + udelay(eqos->reset_delays[1]);
ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0); if (ret < 0) { @@ -754,6 +764,8 @@ static int eqos_start_resets_stm32(struct udevice *dev) ret); return ret; } + + udelay(eqos->reset_delays[2]); } debug("%s: OK\n", __func__);
@@ -1864,11 +1876,29 @@ static int eqos_probe_resources_stm32(struct udevice *dev) if (ret) pr_warn("gpio_request_by_name(phy reset) not provided %d", ret); + else + eqos->reset_delays[1] = 2;
eqos->phyaddr = ofnode_read_u32_default(phandle_args.node, "reg", -1); }
+ if (!dm_gpio_is_valid(&eqos->phy_reset_gpio)) { + int reset_flags = GPIOD_IS_OUT; + + if (dev_read_bool(dev, "snps,reset-active-low")) + reset_flags |= GPIOD_ACTIVE_LOW; + + ret = gpio_request_by_name(dev, "snps,reset-gpio", 0, + &eqos->phy_reset_gpio, reset_flags); + if (ret == 0) + ret = dev_read_u32_array(dev, "snps,reset-delays-us", + eqos->reset_delays, 3); + else + pr_warn("gpio_request_by_name(snps,reset-gpio) failed: %d", + ret); + } + debug("%s: OK\n", __func__); return 0;

Hi David
On 5/12/20 11:56 AM, David Wu wrote:
It can be seen that most of the Socs using STM mac, "snps,reset-gpio" gpio is used, adding this option makes reset function more general.
Signed-off-by: David Wu david.wu@rock-chips.com
Changes in v2:
- Remove the code is not related (Patrice)
drivers/net/dwc_eth_qos.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 66a02aa80b..92dab678c7 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -314,6 +314,7 @@ struct eqos_priv { struct eqos_tegra186_regs *tegra186_regs; struct reset_ctl reset_ctl; struct gpio_desc phy_reset_gpio;
- u32 reset_delays[3]; struct clk clk_master_bus; struct clk clk_rx; struct clk clk_ptp_ref;
@@ -739,6 +740,15 @@ static int eqos_start_resets_stm32(struct udevice *dev)
debug("%s(dev=%p):\n", __func__, dev); if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0);
if (ret < 0) {
pr_err("dm_gpio_set_value(phy_reset, deassert) failed: %d",
ret);
return ret;
}
udelay(eqos->reset_delays[0]);
- ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 1); if (ret < 0) { pr_err("dm_gpio_set_value(phy_reset, assert) failed: %d",
@@ -746,7 +756,7 @@ static int eqos_start_resets_stm32(struct udevice *dev) return ret; }
udelay(2);
udelay(eqos->reset_delays[1]);
ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0); if (ret < 0) {
@@ -754,6 +764,8 @@ static int eqos_start_resets_stm32(struct udevice *dev) ret); return ret; }
} debug("%s: OK\n", __func__);udelay(eqos->reset_delays[2]);
@@ -1864,11 +1876,29 @@ static int eqos_probe_resources_stm32(struct udevice *dev) if (ret) pr_warn("gpio_request_by_name(phy reset) not provided %d", ret);
else
eqos->reset_delays[1] = 2;
eqos->phyaddr = ofnode_read_u32_default(phandle_args.node, "reg", -1); }
if (!dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
int reset_flags = GPIOD_IS_OUT;
if (dev_read_bool(dev, "snps,reset-active-low"))
reset_flags |= GPIOD_ACTIVE_LOW;
ret = gpio_request_by_name(dev, "snps,reset-gpio", 0,
&eqos->phy_reset_gpio, reset_flags);
if (ret == 0)
ret = dev_read_u32_array(dev, "snps,reset-delays-us",
eqos->reset_delays, 3);
else
pr_warn("gpio_request_by_name(snps,reset-gpio) failed: %d",
ret);
}
debug("%s: OK\n", __func__); return 0;
Reviewed-by: Patrice Chotard patrice.chotard@st.com
Thanks

Hi David
From: David Wu david.wu@rock-chips.com Sent: mardi 12 mai 2020 11:56
It can be seen that most of the Socs using STM mac, "snps,reset-gpio" gpio is used, adding this option makes reset function more general.
Signed-off-by: David Wu david.wu@rock-chips.com
Changes in v2:
- Remove the code is not related (Patrice)
drivers/net/dwc_eth_qos.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 66a02aa80b..92dab678c7 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -314,6 +314,7 @@ struct eqos_priv { struct eqos_tegra186_regs *tegra186_regs; struct reset_ctl reset_ctl; struct gpio_desc phy_reset_gpio;
- u32 reset_delays[3]; struct clk clk_master_bus; struct clk clk_rx; struct clk clk_ptp_ref;
@@ -739,6 +740,15 @@ static int eqos_start_resets_stm32(struct udevice *dev)
debug("%s(dev=%p):\n", __func__, dev); if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0);
if (ret < 0) {
pr_err("dm_gpio_set_value(phy_reset, deassert) failed:
%d",
ret);
return ret;
}
udelay(eqos->reset_delays[0]);
- ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 1); if (ret < 0) { pr_err("dm_gpio_set_value(phy_reset, assert) failed: %d",
@@ -746,7 +756,7 @@ static int eqos_start_resets_stm32(struct udevice *dev) return ret; }
udelay(2);
udelay(eqos->reset_delays[1]);
ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0); if (ret < 0) {
@@ -754,6 +764,8 @@ static int eqos_start_resets_stm32(struct udevice *dev) ret); return ret; }
} debug("%s: OK\n", __func__);udelay(eqos->reset_delays[2]);
@@ -1864,11 +1876,29 @@ static int eqos_probe_resources_stm32(struct udevice *dev) if (ret) pr_warn("gpio_request_by_name(phy reset) not provided %d", ret);
else
eqos->reset_delays[1] = 2;
eqos->phyaddr = ofnode_read_u32_default(phandle_args.node, "reg", -1); }
if (!dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
int reset_flags = GPIOD_IS_OUT;
if (dev_read_bool(dev, "snps,reset-active-low"))
reset_flags |= GPIOD_ACTIVE_LOW;
ret = gpio_request_by_name(dev, "snps,reset-gpio", 0,
&eqos->phy_reset_gpio, reset_flags);
if (ret == 0)
ret = dev_read_u32_array(dev, "snps,reset-delays-us",
eqos->reset_delays, 3);
else
pr_warn("gpio_request_by_name(snps,reset-gpio) failed:
%d",
ret);
- }
- debug("%s: OK\n", __func__); return 0;
-- 2.19.1
This obsolete binding isn't expected to be supported in stm32 glue for dwmac (and it tis the purpose of eqos_stm32_config)
Reference in linux binding ./Documentation/devicetree/bindings/net/stm32-dwmac.txt (the glue) ./Documentation/devicetree/bindings/net/snps,dwmac.yaml
snps,reset-gpio: deprecated: true
snps,reset-active-low: deprecated: true
snps,reset-delays-us: deprecated: true
I expected that gpio reset in future device tree should be managed by only by PHY generic binding (upstream in progress on Linux side for STM32MP15x), as described in:
Documentation/devicetree/bindings/net/ethernet-phy.yaml
reset-gpios: maxItems: 1 description: The GPIO phandle and specifier for the PHY reset signal.
reset-assert-us: description: Delay after the reset was asserted in microseconds. If this property is missing the delay will be skipped.
reset-deassert-us: description: Delay after the reset was deasserted in microseconds. If this property is missing the delay will be skipped.
See alsoU-Boot: doc/device-tree-bindings/net/phy.txt
Something as
&mac { status = "okay"; pinctrl-0 = <ðernet_mii>; pinctrl-names = "default"; phy-mode = "mii"; phy-handle = <&phy1>; mdio0 { #address-cells = <1>; #size-cells = <0>; compatible = "snps,dwmac-mdio"; phy1: ethernet-phy@1 { reg = <1>; + reset-assert-us = <10000>; + reset-deassert-us = <30000>; + reset-gpios = <&gpioh 15 GPIO_ACTIVE_LOW>; }; }; };
And this binding "reset-gpios" is supported since the commit 5177b31ba6aa ("net: dwc_eth_qos: implement reset-gpios for stm32")
"reset-assert-us" and "reset-deassert-us" can be added if needed.
For witch product / compatible do you want add the support of this obsolete binding ?
Regards
Patrick

Hi Patrick,
Yes, this is the case, it should be add at PHY node, and I also used the original writing "snps,reset*" at MAC node. Anyway, I will try to put the reset gpio in the PHY node.
在 2020/5/13 下午8:55, Patrick DELAUNAY 写道:
Hi David
From: David Wu david.wu@rock-chips.com Sent: mardi 12 mai 2020 11:56
It can be seen that most of the Socs using STM mac, "snps,reset-gpio" gpio is used, adding this option makes reset function more general.
Signed-off-by: David Wu david.wu@rock-chips.com
Changes in v2:
Remove the code is not related (Patrice)
drivers/net/dwc_eth_qos.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 66a02aa80b..92dab678c7 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -314,6 +314,7 @@ struct eqos_priv { struct eqos_tegra186_regs *tegra186_regs; struct reset_ctl reset_ctl; struct gpio_desc phy_reset_gpio;
- u32 reset_delays[3]; struct clk clk_master_bus; struct clk clk_rx; struct clk clk_ptp_ref;
@@ -739,6 +740,15 @@ static int eqos_start_resets_stm32(struct udevice *dev)
debug("%s(dev=%p):\n", __func__, dev); if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0);
if (ret < 0) {
pr_err("dm_gpio_set_value(phy_reset, deassert) failed:
%d",
ret);
return ret;
}
udelay(eqos->reset_delays[0]);
- ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 1); if (ret < 0) { pr_err("dm_gpio_set_value(phy_reset, assert) failed: %d",
@@ -746,7 +756,7 @@ static int eqos_start_resets_stm32(struct udevice *dev) return ret; }
udelay(2);
udelay(eqos->reset_delays[1]);
ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0); if (ret < 0) {
@@ -754,6 +764,8 @@ static int eqos_start_resets_stm32(struct udevice *dev) ret); return ret; }
} debug("%s: OK\n", __func__);udelay(eqos->reset_delays[2]);
@@ -1864,11 +1876,29 @@ static int eqos_probe_resources_stm32(struct udevice *dev) if (ret) pr_warn("gpio_request_by_name(phy reset) not provided %d", ret);
else
eqos->reset_delays[1] = 2;
eqos->phyaddr = ofnode_read_u32_default(phandle_args.node, "reg", -1); }
if (!dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
int reset_flags = GPIOD_IS_OUT;
if (dev_read_bool(dev, "snps,reset-active-low"))
reset_flags |= GPIOD_ACTIVE_LOW;
ret = gpio_request_by_name(dev, "snps,reset-gpio", 0,
&eqos->phy_reset_gpio, reset_flags);
if (ret == 0)
ret = dev_read_u32_array(dev, "snps,reset-delays-us",
eqos->reset_delays, 3);
else
pr_warn("gpio_request_by_name(snps,reset-gpio) failed:
%d",
ret);
- }
- debug("%s: OK\n", __func__); return 0;
-- 2.19.1
This obsolete binding isn't expected to be supported in stm32 glue for dwmac (and it tis the purpose of eqos_stm32_config)
Reference in linux binding ./Documentation/devicetree/bindings/net/stm32-dwmac.txt (the glue) ./Documentation/devicetree/bindings/net/snps,dwmac.yaml
snps,reset-gpio: deprecated: true
snps,reset-active-low: deprecated: true
snps,reset-delays-us: deprecated: true
I expected that gpio reset in future device tree should be managed by only by PHY generic binding (upstream in progress on Linux side for STM32MP15x), as described in:
Documentation/devicetree/bindings/net/ethernet-phy.yaml
reset-gpios: maxItems: 1 description: The GPIO phandle and specifier for the PHY reset signal.
reset-assert-us: description: Delay after the reset was asserted in microseconds. If this property is missing the delay will be skipped.
reset-deassert-us: description: Delay after the reset was deasserted in microseconds. If this property is missing the delay will be skipped.
See alsoU-Boot: doc/device-tree-bindings/net/phy.txt
Something as
&mac { status = "okay"; pinctrl-0 = <ðernet_mii>; pinctrl-names = "default"; phy-mode = "mii"; phy-handle = <&phy1>; mdio0 { #address-cells = <1>; #size-cells = <0>; compatible = "snps,dwmac-mdio"; phy1: ethernet-phy@1 { reg = <1>;
reset-assert-us = <10000>;
reset-deassert-us = <30000>;
}; };reset-gpios = <&gpioh 15 GPIO_ACTIVE_LOW>;
};
And this binding "reset-gpios" is supported since the commit 5177b31ba6aa ("net: dwc_eth_qos: implement reset-gpios for stm32")
"reset-assert-us" and "reset-deassert-us" can be added if needed.
For witch product / compatible do you want add the support of this obsolete binding ?
Regards
Patrick

On Tue, May 12, 2020 at 05:56:01PM +0800, David Wu wrote:
It can be seen that most of the Socs using STM mac, "snps,reset-gpio" gpio is used, adding this option makes reset function more general.
Signed-off-by: David Wu david.wu@rock-chips.com Reviewed-by: Patrice Chotard patrice.chotard@st.com
Changes in v2:
- Remove the code is not related (Patrice)
Please note that based on Patrick's feedback I am expecting a v3 of this patch or further answers about the obsolete binding being used. Thanks!

Hi Tom,
在 2020/6/12 下午10:48, Tom Rini 写道:
On Tue, May 12, 2020 at 05:56:01PM +0800, David Wu wrote:
It can be seen that most of the Socs using STM mac, "snps,reset-gpio" gpio is used, adding this option makes reset function more general.
Signed-off-by: David Wu david.wu@rock-chips.com Reviewed-by: Patrice Chotard patrice.chotard@st.com
Changes in v2:
- Remove the code is not related (Patrice)
Please note that based on Patrick's feedback I am expecting a v3 of this patch or further answers about the obsolete binding being used. Thanks!
I think I will submit v3 after the following two patches, it looks like I need to add a rockchip config.
[1] net: dwc_eth_qos: update the compatible supported for STM32
http://patchwork.ozlabs.org/project/uboot/patch/20200514130023.15030-1-patri...
[2] net: dwc_eth_qos: add Kconfig option to select supported configuration http://patchwork.ozlabs.org/project/uboot/list/?series=181931

After moving to eqos_ops, if eqos_config is defined outside file, can not export interface() definition, only export eqos_ops struct defined in dwc_eth_qos.c.
Signed-off-by: David Wu david.wu@rock-chips.com ---
Changes in v2: - None
drivers/net/dwc_eth_qos.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 92dab678c7..ae2167637f 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -283,7 +283,6 @@ struct eqos_config { int swr_wait; int config_mac; int config_mac_mdio; - phy_interface_t (*interface)(struct udevice *dev); struct eqos_ops *ops; };
@@ -302,6 +301,7 @@ struct eqos_ops { int (*eqos_disable_calibration)(struct udevice *dev); int (*eqos_set_tx_clk_speed)(struct udevice *dev); ulong (*eqos_get_tick_clk_rate)(struct udevice *dev); + phy_interface_t (*eqos_get_interface)(struct udevice *dev); };
struct eqos_priv { @@ -1227,7 +1227,7 @@ static int eqos_start(struct udevice *dev) addr = DWC_NET_PHYADDR; #endif eqos->phy = phy_connect(eqos->mii, addr, dev, - eqos->config->interface(dev)); + eqos->config->ops->eqos_get_interface(dev)); if (!eqos->phy) { pr_err("phy_connect() failed"); goto err_stop_resets; @@ -1827,7 +1827,7 @@ static int eqos_probe_resources_stm32(struct udevice *dev)
debug("%s(dev=%p):\n", __func__, dev);
- interface = eqos->config->interface(dev); + interface = eqos->config->ops->eqos_get_interface(dev);
if (interface == PHY_INTERFACE_MODE_NONE) { pr_err("Invalid PHY interface\n"); @@ -1938,7 +1938,7 @@ static int eqos_probe_resources_imx(struct udevice *dev)
debug("%s(dev=%p):\n", __func__, dev);
- interface = eqos->config->interface(dev); + interface = eqos->config->ops->eqos_get_interface(dev);
if (interface == PHY_INTERFACE_MODE_NONE) { pr_err("Invalid PHY interface\n"); @@ -2122,7 +2122,8 @@ static struct eqos_ops eqos_tegra186_ops = { .eqos_calibrate_pads = eqos_calibrate_pads_tegra186, .eqos_disable_calibration = eqos_disable_calibration_tegra186, .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_tegra186, - .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_tegra186 + .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_tegra186, + .eqos_get_interface = eqos_get_interface_tegra186 };
static const struct eqos_config eqos_tegra186_config = { @@ -2131,7 +2132,6 @@ static const struct eqos_config eqos_tegra186_config = { .swr_wait = 10, .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB, .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_20_35, - .interface = eqos_get_interface_tegra186, .ops = &eqos_tegra186_ops };
@@ -2149,7 +2149,8 @@ static struct eqos_ops eqos_stm32_ops = { .eqos_calibrate_pads = eqos_calibrate_pads_stm32, .eqos_disable_calibration = eqos_disable_calibration_stm32, .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_stm32, - .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_stm32 + .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_stm32, + .eqos_get_interface = eqos_get_interface_stm32 };
static const struct eqos_config eqos_stm32_config = { @@ -2158,7 +2159,6 @@ static const struct eqos_config eqos_stm32_config = { .swr_wait = 50, .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV, .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300, - .interface = eqos_get_interface_stm32, .ops = &eqos_stm32_ops };
@@ -2176,7 +2176,8 @@ static struct eqos_ops eqos_imx_ops = { .eqos_calibrate_pads = eqos_calibrate_pads_imx, .eqos_disable_calibration = eqos_disable_calibration_imx, .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_imx, - .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_imx + .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_imx, + .eqos_get_interface = eqos_get_interface_imx };
struct eqos_config eqos_imx_config = { @@ -2185,7 +2186,6 @@ struct eqos_config eqos_imx_config = { .swr_wait = 50, .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB, .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300, - .interface = eqos_get_interface_imx, .ops = &eqos_imx_ops };

On 5/12/20 11:56 AM, David Wu wrote:
After moving to eqos_ops, if eqos_config is defined outside file, can not export interface() definition, only export eqos_ops struct defined in dwc_eth_qos.c.
Signed-off-by: David Wu david.wu@rock-chips.com
Changes in v2:
- None
drivers/net/dwc_eth_qos.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 92dab678c7..ae2167637f 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -283,7 +283,6 @@ struct eqos_config { int swr_wait; int config_mac; int config_mac_mdio;
- phy_interface_t (*interface)(struct udevice *dev); struct eqos_ops *ops;
};
@@ -302,6 +301,7 @@ struct eqos_ops { int (*eqos_disable_calibration)(struct udevice *dev); int (*eqos_set_tx_clk_speed)(struct udevice *dev); ulong (*eqos_get_tick_clk_rate)(struct udevice *dev);
- phy_interface_t (*eqos_get_interface)(struct udevice *dev);
};
struct eqos_priv { @@ -1227,7 +1227,7 @@ static int eqos_start(struct udevice *dev) addr = DWC_NET_PHYADDR; #endif eqos->phy = phy_connect(eqos->mii, addr, dev,
eqos->config->interface(dev));
if (!eqos->phy) { pr_err("phy_connect() failed"); goto err_stop_resets;eqos->config->ops->eqos_get_interface(dev));
@@ -1827,7 +1827,7 @@ static int eqos_probe_resources_stm32(struct udevice *dev)
debug("%s(dev=%p):\n", __func__, dev);
- interface = eqos->config->interface(dev);
interface = eqos->config->ops->eqos_get_interface(dev);
if (interface == PHY_INTERFACE_MODE_NONE) { pr_err("Invalid PHY interface\n");
@@ -1938,7 +1938,7 @@ static int eqos_probe_resources_imx(struct udevice *dev)
debug("%s(dev=%p):\n", __func__, dev);
- interface = eqos->config->interface(dev);
interface = eqos->config->ops->eqos_get_interface(dev);
if (interface == PHY_INTERFACE_MODE_NONE) { pr_err("Invalid PHY interface\n");
@@ -2122,7 +2122,8 @@ static struct eqos_ops eqos_tegra186_ops = { .eqos_calibrate_pads = eqos_calibrate_pads_tegra186, .eqos_disable_calibration = eqos_disable_calibration_tegra186, .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_tegra186,
- .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_tegra186
- .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_tegra186,
- .eqos_get_interface = eqos_get_interface_tegra186
};
static const struct eqos_config eqos_tegra186_config = { @@ -2131,7 +2132,6 @@ static const struct eqos_config eqos_tegra186_config = { .swr_wait = 10, .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB, .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_20_35,
- .interface = eqos_get_interface_tegra186, .ops = &eqos_tegra186_ops
};
@@ -2149,7 +2149,8 @@ static struct eqos_ops eqos_stm32_ops = { .eqos_calibrate_pads = eqos_calibrate_pads_stm32, .eqos_disable_calibration = eqos_disable_calibration_stm32, .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_stm32,
- .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_stm32
- .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_stm32,
- .eqos_get_interface = eqos_get_interface_stm32
};
static const struct eqos_config eqos_stm32_config = { @@ -2158,7 +2159,6 @@ static const struct eqos_config eqos_stm32_config = { .swr_wait = 50, .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV, .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300,
- .interface = eqos_get_interface_stm32, .ops = &eqos_stm32_ops
};
@@ -2176,7 +2176,8 @@ static struct eqos_ops eqos_imx_ops = { .eqos_calibrate_pads = eqos_calibrate_pads_imx, .eqos_disable_calibration = eqos_disable_calibration_imx, .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_imx,
- .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_imx
- .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_imx,
- .eqos_get_interface = eqos_get_interface_imx
};
struct eqos_config eqos_imx_config = { @@ -2185,7 +2186,6 @@ struct eqos_config eqos_imx_config = { .swr_wait = 50, .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB, .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300,
- .interface = eqos_get_interface_imx, .ops = &eqos_imx_ops
};
Reviewed-by: Patrice Chotard patrice.chotard@st.com
Thanks

For others using, clk_rx and clk_tx may not be necessary, and their clock names are different.
Signed-off-by: David Wu david.wu@rock-chips.com ---
Changes in v2: - Don't change the Rx and Tx clock names. (Patrice, Stephen)
drivers/net/dwc_eth_qos.c | 61 +++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 32 deletions(-)
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index ae2167637f..bec9bf556b 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -613,16 +613,20 @@ static int eqos_start_clks_stm32(struct udevice *dev) goto err; }
- ret = clk_enable(&eqos->clk_rx); - if (ret < 0) { - pr_err("clk_enable(clk_rx) failed: %d", ret); - goto err_disable_clk_master_bus; + if (clk_valid(&eqos->clk_rx)) { + ret = clk_enable(&eqos->clk_rx); + if (ret < 0) { + pr_err("clk_enable(clk_rx) failed: %d", ret); + goto err_disable_clk_master_bus; + } }
- ret = clk_enable(&eqos->clk_tx); - if (ret < 0) { - pr_err("clk_enable(clk_tx) failed: %d", ret); - goto err_disable_clk_rx; + if (clk_valid(&eqos->clk_tx)) { + ret = clk_enable(&eqos->clk_tx); + if (ret < 0) { + pr_err("clk_enable(clk_tx) failed: %d", ret); + goto err_disable_clk_rx; + } }
if (clk_valid(&eqos->clk_ck)) { @@ -639,9 +643,11 @@ static int eqos_start_clks_stm32(struct udevice *dev)
#ifdef CONFIG_CLK err_disable_clk_tx: - clk_disable(&eqos->clk_tx); + if (clk_valid(&eqos->clk_tx)) + clk_disable(&eqos->clk_tx); err_disable_clk_rx: - clk_disable(&eqos->clk_rx); + if (clk_valid(&eqos->clk_rx)) + clk_disable(&eqos->clk_rx); err_disable_clk_master_bus: clk_disable(&eqos->clk_master_bus); err: @@ -679,8 +685,10 @@ static void eqos_stop_clks_stm32(struct udevice *dev)
debug("%s(dev=%p):\n", __func__, dev);
- clk_disable(&eqos->clk_tx); - clk_disable(&eqos->clk_rx); + if (clk_valid(&eqos->clk_tx)) + clk_disable(&eqos->clk_tx); + if (clk_valid(&eqos->clk_rx)) + clk_disable(&eqos->clk_rx); clk_disable(&eqos->clk_master_bus); if (clk_valid(&eqos->clk_ck)) clk_disable(&eqos->clk_ck); @@ -1843,20 +1851,16 @@ static int eqos_probe_resources_stm32(struct udevice *dev) ret = clk_get_by_name(dev, "stmmaceth", &eqos->clk_master_bus); if (ret) { pr_err("clk_get_by_name(master_bus) failed: %d", ret); - goto err_probe; + return ret; }
ret = clk_get_by_name(dev, "mac-clk-rx", &eqos->clk_rx); - if (ret) { - pr_err("clk_get_by_name(rx) failed: %d", ret); - goto err_free_clk_master_bus; - } + if (ret) + pr_warn("clk_get_by_name(rx) failed: %d", ret);
ret = clk_get_by_name(dev, "mac-clk-tx", &eqos->clk_tx); - if (ret) { - pr_err("clk_get_by_name(tx) failed: %d", ret); - goto err_free_clk_rx; - } + if (ret) + pr_warn("clk_get_by_name(tx) failed: %d", ret);
/* Get ETH_CLK clocks (optional) */ ret = clk_get_by_name(dev, "eth-ck", &eqos->clk_ck); @@ -1901,15 +1905,6 @@ static int eqos_probe_resources_stm32(struct udevice *dev)
debug("%s: OK\n", __func__); return 0; - -err_free_clk_rx: - clk_free(&eqos->clk_rx); -err_free_clk_master_bus: - clk_free(&eqos->clk_master_bus); -err_probe: - - debug("%s: returns %d\n", __func__, ret); - return ret; }
static phy_interface_t eqos_get_interface_stm32(struct udevice *dev) @@ -1991,8 +1986,10 @@ static int eqos_remove_resources_stm32(struct udevice *dev)
debug("%s(dev=%p):\n", __func__, dev);
- clk_free(&eqos->clk_tx); - clk_free(&eqos->clk_rx); + if (clk_valid(&eqos->clk_tx)) + clk_free(&eqos->clk_tx); + if (clk_valid(&eqos->clk_rx)) + clk_free(&eqos->clk_rx); clk_free(&eqos->clk_master_bus); if (clk_valid(&eqos->clk_ck)) clk_free(&eqos->clk_ck);

Hi David
On 5/12/20 11:56 AM, David Wu wrote:
For others using, clk_rx and clk_tx may not be necessary, and their clock names are different.
Signed-off-by: David Wu david.wu@rock-chips.com
Changes in v2:
- Don't change the Rx and Tx clock names. (Patrice, Stephen)
drivers/net/dwc_eth_qos.c | 61 +++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 32 deletions(-)
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index ae2167637f..bec9bf556b 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -613,16 +613,20 @@ static int eqos_start_clks_stm32(struct udevice *dev) goto err; }
- ret = clk_enable(&eqos->clk_rx);
- if (ret < 0) {
pr_err("clk_enable(clk_rx) failed: %d", ret);
goto err_disable_clk_master_bus;
- if (clk_valid(&eqos->clk_rx)) {
ret = clk_enable(&eqos->clk_rx);
if (ret < 0) {
pr_err("clk_enable(clk_rx) failed: %d", ret);
goto err_disable_clk_master_bus;
}}
- ret = clk_enable(&eqos->clk_tx);
- if (ret < 0) {
pr_err("clk_enable(clk_tx) failed: %d", ret);
goto err_disable_clk_rx;
if (clk_valid(&eqos->clk_tx)) {
ret = clk_enable(&eqos->clk_tx);
if (ret < 0) {
pr_err("clk_enable(clk_tx) failed: %d", ret);
goto err_disable_clk_rx;
}
}
if (clk_valid(&eqos->clk_ck)) {
@@ -639,9 +643,11 @@ static int eqos_start_clks_stm32(struct udevice *dev)
#ifdef CONFIG_CLK err_disable_clk_tx:
- clk_disable(&eqos->clk_tx);
- if (clk_valid(&eqos->clk_tx))
clk_disable(&eqos->clk_tx);
err_disable_clk_rx:
- clk_disable(&eqos->clk_rx);
- if (clk_valid(&eqos->clk_rx))
clk_disable(&eqos->clk_rx);
err_disable_clk_master_bus: clk_disable(&eqos->clk_master_bus); err: @@ -679,8 +685,10 @@ static void eqos_stop_clks_stm32(struct udevice *dev)
debug("%s(dev=%p):\n", __func__, dev);
- clk_disable(&eqos->clk_tx);
- clk_disable(&eqos->clk_rx);
- if (clk_valid(&eqos->clk_tx))
clk_disable(&eqos->clk_tx);
- if (clk_valid(&eqos->clk_rx))
clk_disable(&eqos->clk_master_bus); if (clk_valid(&eqos->clk_ck)) clk_disable(&eqos->clk_ck);clk_disable(&eqos->clk_rx);
@@ -1843,20 +1851,16 @@ static int eqos_probe_resources_stm32(struct udevice *dev) ret = clk_get_by_name(dev, "stmmaceth", &eqos->clk_master_bus); if (ret) { pr_err("clk_get_by_name(master_bus) failed: %d", ret);
goto err_probe;
return ret;
}
ret = clk_get_by_name(dev, "mac-clk-rx", &eqos->clk_rx);
- if (ret) {
pr_err("clk_get_by_name(rx) failed: %d", ret);
goto err_free_clk_master_bus;
- }
if (ret)
pr_warn("clk_get_by_name(rx) failed: %d", ret);
ret = clk_get_by_name(dev, "mac-clk-tx", &eqos->clk_tx);
- if (ret) {
pr_err("clk_get_by_name(tx) failed: %d", ret);
goto err_free_clk_rx;
- }
if (ret)
pr_warn("clk_get_by_name(tx) failed: %d", ret);
/* Get ETH_CLK clocks (optional) */ ret = clk_get_by_name(dev, "eth-ck", &eqos->clk_ck);
@@ -1901,15 +1905,6 @@ static int eqos_probe_resources_stm32(struct udevice *dev)
debug("%s: OK\n", __func__); return 0;
-err_free_clk_rx:
- clk_free(&eqos->clk_rx);
-err_free_clk_master_bus:
- clk_free(&eqos->clk_master_bus);
-err_probe:
- debug("%s: returns %d\n", __func__, ret);
- return ret;
}
static phy_interface_t eqos_get_interface_stm32(struct udevice *dev) @@ -1991,8 +1986,10 @@ static int eqos_remove_resources_stm32(struct udevice *dev)
debug("%s(dev=%p):\n", __func__, dev);
- clk_free(&eqos->clk_tx);
- clk_free(&eqos->clk_rx);
- if (clk_valid(&eqos->clk_tx))
clk_free(&eqos->clk_tx);
- if (clk_valid(&eqos->clk_rx))
clk_free(&eqos->clk_master_bus); if (clk_valid(&eqos->clk_ck)) clk_free(&eqos->clk_ck);clk_free(&eqos->clk_rx);
Reviewed-by: Patrice Chotard patrice.chotard@st.com
Thanks

Hi David,
From: David Wu david.wu@rock-chips.com Sent: mardi 12 mai 2020 11:56
For others using, clk_rx and clk_tx may not be necessary, and their clock names are different.
Signed-off-by: David Wu david.wu@rock-chips.com
Changes in v2:
- Don't change the Rx and Tx clock names. (Patrice, Stephen)
drivers/net/dwc_eth_qos.c | 61 +++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 32 deletions(-)
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index ae2167637f..bec9bf556b 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -613,16 +613,20 @@ static int eqos_start_clks_stm32(struct udevice *dev) goto err; }
- ret = clk_enable(&eqos->clk_rx);
- if (ret < 0) {
pr_err("clk_enable(clk_rx) failed: %d", ret);
goto err_disable_clk_master_bus;
- if (clk_valid(&eqos->clk_rx)) {
ret = clk_enable(&eqos->clk_rx);
if (ret < 0) {
pr_err("clk_enable(clk_rx) failed: %d", ret);
goto err_disable_clk_master_bus;
}}
- ret = clk_enable(&eqos->clk_tx);
- if (ret < 0) {
pr_err("clk_enable(clk_tx) failed: %d", ret);
goto err_disable_clk_rx;
if (clk_valid(&eqos->clk_tx)) {
ret = clk_enable(&eqos->clk_tx);
if (ret < 0) {
pr_err("clk_enable(clk_tx) failed: %d", ret);
goto err_disable_clk_rx;
}
}
if (clk_valid(&eqos->clk_ck)) {
@@ -639,9 +643,11 @@ static int eqos_start_clks_stm32(struct udevice *dev)
#ifdef CONFIG_CLK err_disable_clk_tx:
- clk_disable(&eqos->clk_tx);
- if (clk_valid(&eqos->clk_tx))
clk_disable(&eqos->clk_tx);
err_disable_clk_rx:
- clk_disable(&eqos->clk_rx);
- if (clk_valid(&eqos->clk_rx))
clk_disable(&eqos->clk_rx);
err_disable_clk_master_bus: clk_disable(&eqos->clk_master_bus); err: @@ -679,8 +685,10 @@ static void eqos_stop_clks_stm32(struct udevice *dev)
debug("%s(dev=%p):\n", __func__, dev);
- clk_disable(&eqos->clk_tx);
- clk_disable(&eqos->clk_rx);
- if (clk_valid(&eqos->clk_tx))
clk_disable(&eqos->clk_tx);
- if (clk_valid(&eqos->clk_rx))
clk_disable(&eqos->clk_master_bus); if (clk_valid(&eqos->clk_ck)) clk_disable(&eqos->clk_ck);clk_disable(&eqos->clk_rx);
@@ -1843,20 +1851,16 @@ static int eqos_probe_resources_stm32(struct udevice *dev) ret = clk_get_by_name(dev, "stmmaceth", &eqos->clk_master_bus); if (ret) { pr_err("clk_get_by_name(master_bus) failed: %d", ret);
goto err_probe;
return ret;
}
ret = clk_get_by_name(dev, "mac-clk-rx", &eqos->clk_rx);
- if (ret) {
pr_err("clk_get_by_name(rx) failed: %d", ret);
goto err_free_clk_master_bus;
- }
if (ret)
pr_warn("clk_get_by_name(rx) failed: %d", ret);
ret = clk_get_by_name(dev, "mac-clk-tx", &eqos->clk_tx);
- if (ret) {
pr_err("clk_get_by_name(tx) failed: %d", ret);
goto err_free_clk_rx;
- }
if (ret)
pr_warn("clk_get_by_name(tx) failed: %d", ret);
/* Get ETH_CLK clocks (optional) */ ret = clk_get_by_name(dev, "eth-ck", &eqos->clk_ck); @@ -1901,15
+1905,6 @@ static int eqos_probe_resources_stm32(struct udevice *dev)
debug("%s: OK\n", __func__); return 0;
-err_free_clk_rx:
- clk_free(&eqos->clk_rx);
-err_free_clk_master_bus:
- clk_free(&eqos->clk_master_bus);
-err_probe:
- debug("%s: returns %d\n", __func__, ret);
- return ret;
}
static phy_interface_t eqos_get_interface_stm32(struct udevice *dev) @@ -1991,8 +1986,10 @@ static int eqos_remove_resources_stm32(struct udevice *dev)
debug("%s(dev=%p):\n", __func__, dev);
- clk_free(&eqos->clk_tx);
- clk_free(&eqos->clk_rx);
- if (clk_valid(&eqos->clk_tx))
clk_free(&eqos->clk_tx);
- if (clk_valid(&eqos->clk_rx))
clk_free(&eqos->clk_master_bus); if (clk_valid(&eqos->clk_ck)) clk_free(&eqos->clk_ck);clk_free(&eqos->clk_rx);
-- 2.19.1
These clock are mandatory for STM32 glue as explain in Linux binding Documentation/devicetree/bindings/net/stm32-dwmac.txt
But I fact when when I check the code, I see perhaps an issue in the current U-Boot glue: we don't select the STM32 glue for the correct compatible, I think I will push
static const struct udevice_id eqos_ids[] = { { .compatible = "nvidia,tegra186-eqos", .data = (ulong)&eqos_tegra186_config }, { - .compatible = "snps,dwmac-4.20a", + .compatible = "st,stm32mp1-dwmac", .data = (ulong)&eqos_stm32_config }, { .compatible = "fsl,imx-eqos", .data = (ulong)&eqos_imx_config },
{ } };
Then you can manage your own glue for rockchip ETH for your compatible.
Regards
Patrick

On 5/13/20 3:17 PM, Patrick DELAUNAY wrote:
Hi David,
From: David Wu david.wu@rock-chips.com Sent: mardi 12 mai 2020 11:56
For others using, clk_rx and clk_tx may not be necessary, and their clock names are different.
Signed-off-by: David Wu david.wu@rock-chips.com
Changes in v2:
- Don't change the Rx and Tx clock names. (Patrice, Stephen)
drivers/net/dwc_eth_qos.c | 61 +++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 32 deletions(-)
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index ae2167637f..bec9bf556b 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -613,16 +613,20 @@ static int eqos_start_clks_stm32(struct udevice *dev) goto err; }
- ret = clk_enable(&eqos->clk_rx);
- if (ret < 0) {
pr_err("clk_enable(clk_rx) failed: %d", ret);
goto err_disable_clk_master_bus;
- if (clk_valid(&eqos->clk_rx)) {
ret = clk_enable(&eqos->clk_rx);
if (ret < 0) {
pr_err("clk_enable(clk_rx) failed: %d", ret);
goto err_disable_clk_master_bus;
}}
- ret = clk_enable(&eqos->clk_tx);
- if (ret < 0) {
pr_err("clk_enable(clk_tx) failed: %d", ret);
goto err_disable_clk_rx;
if (clk_valid(&eqos->clk_tx)) {
ret = clk_enable(&eqos->clk_tx);
if (ret < 0) {
pr_err("clk_enable(clk_tx) failed: %d", ret);
goto err_disable_clk_rx;
}
}
if (clk_valid(&eqos->clk_ck)) {
@@ -639,9 +643,11 @@ static int eqos_start_clks_stm32(struct udevice *dev)
#ifdef CONFIG_CLK err_disable_clk_tx:
- clk_disable(&eqos->clk_tx);
- if (clk_valid(&eqos->clk_tx))
clk_disable(&eqos->clk_tx);
err_disable_clk_rx:
- clk_disable(&eqos->clk_rx);
- if (clk_valid(&eqos->clk_rx))
clk_disable(&eqos->clk_rx);
err_disable_clk_master_bus: clk_disable(&eqos->clk_master_bus); err: @@ -679,8 +685,10 @@ static void eqos_stop_clks_stm32(struct udevice *dev)
debug("%s(dev=%p):\n", __func__, dev);
- clk_disable(&eqos->clk_tx);
- clk_disable(&eqos->clk_rx);
- if (clk_valid(&eqos->clk_tx))
clk_disable(&eqos->clk_tx);
- if (clk_valid(&eqos->clk_rx))
clk_disable(&eqos->clk_master_bus); if (clk_valid(&eqos->clk_ck)) clk_disable(&eqos->clk_ck);clk_disable(&eqos->clk_rx);
@@ -1843,20 +1851,16 @@ static int eqos_probe_resources_stm32(struct udevice *dev) ret = clk_get_by_name(dev, "stmmaceth", &eqos->clk_master_bus); if (ret) { pr_err("clk_get_by_name(master_bus) failed: %d", ret);
goto err_probe;
return ret;
}
ret = clk_get_by_name(dev, "mac-clk-rx", &eqos->clk_rx);
- if (ret) {
pr_err("clk_get_by_name(rx) failed: %d", ret);
goto err_free_clk_master_bus;
- }
if (ret)
pr_warn("clk_get_by_name(rx) failed: %d", ret);
ret = clk_get_by_name(dev, "mac-clk-tx", &eqos->clk_tx);
- if (ret) {
pr_err("clk_get_by_name(tx) failed: %d", ret);
goto err_free_clk_rx;
- }
if (ret)
pr_warn("clk_get_by_name(tx) failed: %d", ret);
/* Get ETH_CLK clocks (optional) */ ret = clk_get_by_name(dev, "eth-ck", &eqos->clk_ck); @@ -1901,15
+1905,6 @@ static int eqos_probe_resources_stm32(struct udevice *dev)
debug("%s: OK\n", __func__); return 0;
-err_free_clk_rx:
- clk_free(&eqos->clk_rx);
-err_free_clk_master_bus:
- clk_free(&eqos->clk_master_bus);
-err_probe:
- debug("%s: returns %d\n", __func__, ret);
- return ret;
}
static phy_interface_t eqos_get_interface_stm32(struct udevice *dev) @@ -1991,8 +1986,10 @@ static int eqos_remove_resources_stm32(struct udevice *dev)
debug("%s(dev=%p):\n", __func__, dev);
- clk_free(&eqos->clk_tx);
- clk_free(&eqos->clk_rx);
- if (clk_valid(&eqos->clk_tx))
clk_free(&eqos->clk_tx);
- if (clk_valid(&eqos->clk_rx))
clk_free(&eqos->clk_master_bus); if (clk_valid(&eqos->clk_ck)) clk_free(&eqos->clk_ck);clk_free(&eqos->clk_rx);
-- 2.19.1
These clock are mandatory for STM32 glue as explain in Linux binding Documentation/devicetree/bindings/net/stm32-dwmac.txt
But I fact when when I check the code, I see perhaps an issue in the current U-Boot glue: we don't select the STM32 glue for the correct compatible, I think I will push
static const struct udevice_id eqos_ids[] = { { .compatible = "nvidia,tegra186-eqos", .data = (ulong)&eqos_tegra186_config }, {
.compatible = "snps,dwmac-4.20a",
.compatible = "st,stm32mp1-dwmac",
.data = (ulong)&eqos_stm32_config }, { .compatible = "fsl,imx-eqos", .data = (ulong)&eqos_imx_config },
{ }
};
Then you can manage your own glue for rockchip ETH for your compatible.
You might even want to drop the tegra support on ARM32 , thus save space by dropping useless code.

Hi Marek,
From: Marek Vasut marex@denx.de Sent: mercredi 13 mai 2020 15:54
On 5/13/20 3:17 PM, Patrick DELAUNAY wrote:
Hi David,
From: David Wu david.wu@rock-chips.com Sent: mardi 12 mai 2020 11:56
For others using, clk_rx and clk_tx may not be necessary, and their clock names are different.
Signed-off-by: David Wu david.wu@rock-chips.com
Changes in v2:
- Don't change the Rx and Tx clock names. (Patrice, Stephen)
drivers/net/dwc_eth_qos.c | 61 +++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 32 deletions(-)
[...]
These clock are mandatory for STM32 glue as explain in Linux binding Documentation/devicetree/bindings/net/stm32-dwmac.txt
But I fact when when I check the code, I see perhaps an issue in the current U-
Boot glue:
we don't select the STM32 glue for the correct compatible, I think I will push
static const struct udevice_id eqos_ids[] = { { .compatible = "nvidia,tegra186-eqos", .data = (ulong)&eqos_tegra186_config }, {
.compatible = "snps,dwmac-4.20a",
.compatible = "st,stm32mp1-dwmac",
.data = (ulong)&eqos_stm32_config }, { .compatible = "fsl,imx-eqos", .data = (ulong)&eqos_imx_config },
{ }
};
Then you can manage your own glue for rockchip ETH for your compatible.
You might even want to drop the tegra support on ARM32 , thus save space by dropping useless code.
For information I push 2 patches after this remark:
[1] net: dwc_eth_qos: update the compatible supported for STM32 http://patchwork.ozlabs.org/project/uboot/patch/20200514130023.15030-1-patri...
[2] net: dwc_eth_qos: add Kconfig option to select supported configuration http://patchwork.ozlabs.org/project/uboot/list/?series=181931

On 6/8/20 11:29 AM, Patrick DELAUNAY wrote: [...]
we don't select the STM32 glue for the correct compatible, I think I will push
static const struct udevice_id eqos_ids[] = { { .compatible = "nvidia,tegra186-eqos", .data = (ulong)&eqos_tegra186_config }, {
.compatible = "snps,dwmac-4.20a",
.compatible = "st,stm32mp1-dwmac",
.data = (ulong)&eqos_stm32_config }, { .compatible = "fsl,imx-eqos", .data = (ulong)&eqos_imx_config },
{ }
};
Then you can manage your own glue for rockchip ETH for your compatible.
You might even want to drop the tegra support on ARM32 , thus save space by dropping useless code.
For information I push 2 patches after this remark:
[1] net: dwc_eth_qos: update the compatible supported for STM32 http://patchwork.ozlabs.org/project/uboot/patch/20200514130023.15030-1-patri...
[2] net: dwc_eth_qos: add Kconfig option to select supported configuration http://patchwork.ozlabs.org/project/uboot/list/?series=181931
That's for -next, right ?

Dear Marek,
From: Marek Vasut marex@denx.de Sent: lundi 8 juin 2020 11:45
On 6/8/20 11:29 AM, Patrick DELAUNAY wrote: [...]
we don't select the STM32 glue for the correct compatible, I think I will push
static const struct udevice_id eqos_ids[] = { { .compatible = "nvidia,tegra186-eqos", .data = (ulong)&eqos_tegra186_config }, {
.compatible = "snps,dwmac-4.20a",
.compatible = "st,stm32mp1-dwmac",
.data = (ulong)&eqos_stm32_config }, { .compatible = "fsl,imx-eqos", .data = (ulong)&eqos_imx_config },
{ }
};
Then you can manage your own glue for rockchip ETH for your compatible.
You might even want to drop the tegra support on ARM32 , thus save space by dropping useless code.
For information I push 2 patches after this remark:
[1] net: dwc_eth_qos: update the compatible supported for STM32
http://patchwork.ozlabs.org/project/uboot/patch/20200514130023.15030-1 -patrick.delaunay@st.com/
[2] net: dwc_eth_qos: add Kconfig option to select supported configuration http://patchwork.ozlabs.org/project/uboot/list/?series=181931
That's for -next, right ?
Yes both are for -next.
It is driver improvement (=code size reduction and cleanup compatible) and no bugfix.
Patrick.

On 6/8/20 7:05 PM, Patrick DELAUNAY wrote:
Dear Marek,
Hi,
From: Marek Vasut marex@denx.de Sent: lundi 8 juin 2020 11:45
On 6/8/20 11:29 AM, Patrick DELAUNAY wrote: [...]
we don't select the STM32 glue for the correct compatible, I think I will push
static const struct udevice_id eqos_ids[] = { { .compatible = "nvidia,tegra186-eqos", .data = (ulong)&eqos_tegra186_config }, {
.compatible = "snps,dwmac-4.20a",
.compatible = "st,stm32mp1-dwmac",
.data = (ulong)&eqos_stm32_config }, { .compatible = "fsl,imx-eqos", .data = (ulong)&eqos_imx_config },
{ }
};
Then you can manage your own glue for rockchip ETH for your compatible.
You might even want to drop the tegra support on ARM32 , thus save space by dropping useless code.
For information I push 2 patches after this remark:
[1] net: dwc_eth_qos: update the compatible supported for STM32
http://patchwork.ozlabs.org/project/uboot/patch/20200514130023.15030-1 -patrick.delaunay@st.com/
[2] net: dwc_eth_qos: add Kconfig option to select supported configuration http://patchwork.ozlabs.org/project/uboot/list/?series=181931
That's for -next, right ?
Yes both are for -next.
It is driver improvement (=code size reduction and cleanup compatible) and no bugfix.
I am still not entirely sure whether the ifdeffery is the way to go. I wonder whether we can't rather somehow use the linker-lists to generate a list of compatible strings at runtime (like we do for commands) and then reduce that list to only the compatible strings present in the DT (that's a bit tricky).

For Rockchip, need to obtain the current link speed to configure the tx clocks, (for example, in rgmii mode, 1000M link: 125M, 100M link: 25M, 10M link is 2.5M rate) and then enable gmac. So after the adjust_link(), before the start gamc, this intermediate stage needs to configure the clock according to the current link speed.
Signed-off-by: David Wu david.wu@rock-chips.com ---
Changes in v2: - None
drivers/net/dwc_eth_qos.c | 56 ++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 18 deletions(-)
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index bec9bf556b..e503be5b4b 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1175,19 +1175,15 @@ static int eqos_read_rom_hwaddr(struct udevice *dev) return !is_valid_ethaddr(pdata->enetaddr); }
-static int eqos_start(struct udevice *dev) +static int eqos_init(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); - int ret, i; + int ret; ulong rate; - u32 val, tx_fifo_sz, rx_fifo_sz, tqs, rqs, pbl; - ulong last_rx_desc; + u32 val;
debug("%s(dev=%p):\n", __func__, dev);
- eqos->tx_desc_idx = 0; - eqos->rx_desc_idx = 0; - ret = eqos->config->ops->eqos_start_clks(dev); if (ret < 0) { pr_err("eqos_start_clks() failed: %d", ret); @@ -1273,6 +1269,30 @@ static int eqos_start(struct udevice *dev) goto err_shutdown_phy; }
+ debug("%s: OK\n", __func__); + return 0; + +err_shutdown_phy: + phy_shutdown(eqos->phy); +err_stop_resets: + eqos->config->ops->eqos_stop_resets(dev); +err_stop_clks: + eqos->config->ops->eqos_stop_clks(dev); +err: + pr_err("FAILED: %d", ret); + return ret; +} + +static void eqos_enable(struct udevice *dev) +{ + struct eqos_priv *eqos = dev_get_priv(dev); + u32 val, tx_fifo_sz, rx_fifo_sz, tqs, rqs, pbl; + ulong last_rx_desc; + int i; + + eqos->tx_desc_idx = 0; + eqos->rx_desc_idx = 0; + /* Configure MTL */ writel(0x60, &eqos->mtl_regs->txq0_quantum_weight - 0x100);
@@ -1492,19 +1512,19 @@ static int eqos_start(struct udevice *dev) writel(last_rx_desc, &eqos->dma_regs->ch0_rxdesc_tail_pointer);
eqos->started = true; +}
- debug("%s: OK\n", __func__); - return 0; +static int eqos_start(struct udevice *dev) +{ + int ret;
-err_shutdown_phy: - phy_shutdown(eqos->phy); -err_stop_resets: - eqos->config->ops->eqos_stop_resets(dev); -err_stop_clks: - eqos->config->ops->eqos_stop_clks(dev); -err: - pr_err("FAILED: %d", ret); - return ret; + ret = eqos_init(dev); + if (ret) + return ret; + + eqos_enable(dev); + + return 0; }
static void eqos_stop(struct udevice *dev)

one typo below
On 5/12/20 11:57 AM, David Wu wrote:
For Rockchip, need to obtain the current link speed to configure the tx clocks, (for example, in rgmii mode, 1000M link: 125M, 100M link: 25M, 10M link is 2.5M rate) and then enable gmac. So after the adjust_link(), before the start gamc, this intermediate stage needs to configure
Typo gamc
the clock according to the current link speed.
Signed-off-by: David Wu david.wu@rock-chips.com
Changes in v2:
- None
drivers/net/dwc_eth_qos.c | 56 ++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 18 deletions(-)
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index bec9bf556b..e503be5b4b 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1175,19 +1175,15 @@ static int eqos_read_rom_hwaddr(struct udevice *dev) return !is_valid_ethaddr(pdata->enetaddr); }
-static int eqos_start(struct udevice *dev) +static int eqos_init(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev);
- int ret, i;
- int ret; ulong rate;
- u32 val, tx_fifo_sz, rx_fifo_sz, tqs, rqs, pbl;
- ulong last_rx_desc;
u32 val;
debug("%s(dev=%p):\n", __func__, dev);
- eqos->tx_desc_idx = 0;
- eqos->rx_desc_idx = 0;
- ret = eqos->config->ops->eqos_start_clks(dev); if (ret < 0) { pr_err("eqos_start_clks() failed: %d", ret);
@@ -1273,6 +1269,30 @@ static int eqos_start(struct udevice *dev) goto err_shutdown_phy; }
- debug("%s: OK\n", __func__);
- return 0;
+err_shutdown_phy:
- phy_shutdown(eqos->phy);
+err_stop_resets:
- eqos->config->ops->eqos_stop_resets(dev);
+err_stop_clks:
- eqos->config->ops->eqos_stop_clks(dev);
+err:
- pr_err("FAILED: %d", ret);
- return ret;
+}
+static void eqos_enable(struct udevice *dev) +{
- struct eqos_priv *eqos = dev_get_priv(dev);
- u32 val, tx_fifo_sz, rx_fifo_sz, tqs, rqs, pbl;
- ulong last_rx_desc;
- int i;
- eqos->tx_desc_idx = 0;
- eqos->rx_desc_idx = 0;
- /* Configure MTL */ writel(0x60, &eqos->mtl_regs->txq0_quantum_weight - 0x100);
@@ -1492,19 +1512,19 @@ static int eqos_start(struct udevice *dev) writel(last_rx_desc, &eqos->dma_regs->ch0_rxdesc_tail_pointer);
eqos->started = true; +}
- debug("%s: OK\n", __func__);
- return 0;
+static int eqos_start(struct udevice *dev) +{
- int ret;
-err_shutdown_phy:
- phy_shutdown(eqos->phy);
-err_stop_resets:
- eqos->config->ops->eqos_stop_resets(dev);
-err_stop_clks:
- eqos->config->ops->eqos_stop_clks(dev);
-err:
- pr_err("FAILED: %d", ret);
- return ret;
- ret = eqos_init(dev);
- if (ret)
return ret;
- eqos_enable(dev);
- return 0;
}
static void eqos_stop(struct udevice *dev)
Reviewed-by: Patrice Chotard patrice.chotard@st.com
Thanks

If there are definitions for eqos_start_clks and eqos_stop_clks, then call these callback function.
Signed-off-by: David Wu david.wu@rock-chips.com ---
Changes in v2: - None
drivers/net/dwc_eth_qos.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index e503be5b4b..295707cbb0 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1184,10 +1184,12 @@ static int eqos_init(struct udevice *dev)
debug("%s(dev=%p):\n", __func__, dev);
- ret = eqos->config->ops->eqos_start_clks(dev); - if (ret < 0) { - pr_err("eqos_start_clks() failed: %d", ret); - goto err; + if (eqos->config->ops->eqos_start_clks) { + ret = eqos->config->ops->eqos_start_clks(dev); + if (ret < 0) { + pr_err("eqos_start_clks() failed: %d", ret); + goto err; + } }
ret = eqos->config->ops->eqos_start_resets(dev); @@ -1277,7 +1279,8 @@ err_shutdown_phy: err_stop_resets: eqos->config->ops->eqos_stop_resets(dev); err_stop_clks: - eqos->config->ops->eqos_stop_clks(dev); + if (eqos->config->ops->eqos_stop_clks) + eqos->config->ops->eqos_stop_clks(dev); err: pr_err("FAILED: %d", ret); return ret; @@ -1576,7 +1579,8 @@ static void eqos_stop(struct udevice *dev) phy_shutdown(eqos->phy); } eqos->config->ops->eqos_stop_resets(dev); - eqos->config->ops->eqos_stop_clks(dev); + if (eqos->config->ops->eqos_stop_clks) + eqos->config->ops->eqos_stop_clks(dev);
debug("%s: OK\n", __func__); }

Hi David On 5/12/20 11:57 AM, David Wu wrote:
If there are definitions for eqos_start_clks and eqos_stop_clks, then call these callback function.
Signed-off-by: David Wu david.wu@rock-chips.com
Changes in v2:
- None
drivers/net/dwc_eth_qos.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index e503be5b4b..295707cbb0 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1184,10 +1184,12 @@ static int eqos_init(struct udevice *dev)
debug("%s(dev=%p):\n", __func__, dev);
- ret = eqos->config->ops->eqos_start_clks(dev);
- if (ret < 0) {
pr_err("eqos_start_clks() failed: %d", ret);
goto err;
if (eqos->config->ops->eqos_start_clks) {
ret = eqos->config->ops->eqos_start_clks(dev);
if (ret < 0) {
pr_err("eqos_start_clks() failed: %d", ret);
goto err;
}
}
ret = eqos->config->ops->eqos_start_resets(dev);
@@ -1277,7 +1279,8 @@ err_shutdown_phy: err_stop_resets: eqos->config->ops->eqos_stop_resets(dev); err_stop_clks:
- eqos->config->ops->eqos_stop_clks(dev);
- if (eqos->config->ops->eqos_stop_clks)
eqos->config->ops->eqos_stop_clks(dev);
err: pr_err("FAILED: %d", ret); return ret; @@ -1576,7 +1579,8 @@ static void eqos_stop(struct udevice *dev) phy_shutdown(eqos->phy); } eqos->config->ops->eqos_stop_resets(dev);
- eqos->config->ops->eqos_stop_clks(dev);
if (eqos->config->ops->eqos_stop_clks)
eqos->config->ops->eqos_stop_clks(dev);
debug("%s: OK\n", __func__);
}
Reviewed-by: Patrice Chotard patrice.chotard@st.com
Thanks

Open structure data and interface, so that Soc using dw_eth_qos controller can reference.
Signed-off-by: David Wu david.wu@rock-chips.com ---
Changes in v2: - Add the lost head file. (Patrice)
drivers/net/dwc_eth_qos.c | 81 ++++-------------------------------- drivers/net/dwc_eth_qos.h | 87 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 72 deletions(-) create mode 100644 drivers/net/dwc_eth_qos.h
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 295707cbb0..b3195d484e 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -46,6 +46,7 @@ #include <asm/arch/clock.h> #include <asm/mach-imx/sys_proto.h> #endif +#include "dwc_eth_qos.h"
/* Core registers */
@@ -100,9 +101,6 @@ struct eqos_mac_regs {
#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT 0 #define EQOS_MAC_RXQ_CTRL0_RXQ0EN_MASK 3 -#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_NOT_ENABLED 0 -#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB 2 -#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV 1
#define EQOS_MAC_RXQ_CTRL2_PSRQ0_SHIFT 0 #define EQOS_MAC_RXQ_CTRL2_PSRQ0_MASK 0xff @@ -123,8 +121,6 @@ struct eqos_mac_regs { #define EQOS_MAC_MDIO_ADDRESS_PA_SHIFT 21 #define EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT 16 #define EQOS_MAC_MDIO_ADDRESS_CR_SHIFT 8 -#define EQOS_MAC_MDIO_ADDRESS_CR_20_35 2 -#define EQOS_MAC_MDIO_ADDRESS_CR_250_300 5 #define EQOS_MAC_MDIO_ADDRESS_SKAP BIT(4) #define EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT 2 #define EQOS_MAC_MDIO_ADDRESS_GOC_READ 3 @@ -277,65 +273,6 @@ struct eqos_desc { #define EQOS_DESC3_LD BIT(28) #define EQOS_DESC3_BUF1V BIT(24)
-struct eqos_config { - bool reg_access_always_ok; - int mdio_wait; - int swr_wait; - int config_mac; - int config_mac_mdio; - struct eqos_ops *ops; -}; - -struct eqos_ops { - void (*eqos_inval_desc)(void *desc); - void (*eqos_flush_desc)(void *desc); - void (*eqos_inval_buffer)(void *buf, size_t size); - void (*eqos_flush_buffer)(void *buf, size_t size); - int (*eqos_probe_resources)(struct udevice *dev); - int (*eqos_remove_resources)(struct udevice *dev); - int (*eqos_stop_resets)(struct udevice *dev); - int (*eqos_start_resets)(struct udevice *dev); - void (*eqos_stop_clks)(struct udevice *dev); - int (*eqos_start_clks)(struct udevice *dev); - int (*eqos_calibrate_pads)(struct udevice *dev); - int (*eqos_disable_calibration)(struct udevice *dev); - int (*eqos_set_tx_clk_speed)(struct udevice *dev); - ulong (*eqos_get_tick_clk_rate)(struct udevice *dev); - phy_interface_t (*eqos_get_interface)(struct udevice *dev); -}; - -struct eqos_priv { - struct udevice *dev; - const struct eqos_config *config; - fdt_addr_t regs; - struct eqos_mac_regs *mac_regs; - struct eqos_mtl_regs *mtl_regs; - struct eqos_dma_regs *dma_regs; - struct eqos_tegra186_regs *tegra186_regs; - struct reset_ctl reset_ctl; - struct gpio_desc phy_reset_gpio; - u32 reset_delays[3]; - struct clk clk_master_bus; - struct clk clk_rx; - struct clk clk_ptp_ref; - struct clk clk_tx; - struct clk clk_ck; - struct clk clk_slave_bus; - struct mii_dev *mii; - struct phy_device *phy; - int phyaddr; - u32 max_speed; - void *descs; - struct eqos_desc *tx_descs; - struct eqos_desc *rx_descs; - int tx_desc_idx, rx_desc_idx; - void *tx_dma_buf; - void *rx_dma_buf; - void *rx_pkt; - bool started; - bool reg_access_ok; -}; - /* * TX and RX descriptors are 16 bytes. This causes problems with the cache * maintenance on CPUs where the cache-line size exceeds the size of these @@ -1121,7 +1058,7 @@ static int eqos_adjust_link(struct udevice *dev) return 0; }
-static int eqos_write_hwaddr(struct udevice *dev) +int eqos_write_hwaddr(struct udevice *dev) { struct eth_pdata *plat = dev_get_platdata(dev); struct eqos_priv *eqos = dev_get_priv(dev); @@ -1175,7 +1112,7 @@ static int eqos_read_rom_hwaddr(struct udevice *dev) return !is_valid_ethaddr(pdata->enetaddr); }
-static int eqos_init(struct udevice *dev) +int eqos_init(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); int ret; @@ -1286,7 +1223,7 @@ err: return ret; }
-static void eqos_enable(struct udevice *dev) +void eqos_enable(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); u32 val, tx_fifo_sz, rx_fifo_sz, tqs, rqs, pbl; @@ -1530,7 +1467,7 @@ static int eqos_start(struct udevice *dev) return 0; }
-static void eqos_stop(struct udevice *dev) +void eqos_stop(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); int i; @@ -1585,7 +1522,7 @@ static void eqos_stop(struct udevice *dev) debug("%s: OK\n", __func__); }
-static int eqos_send(struct udevice *dev, void *packet, int length) +int eqos_send(struct udevice *dev, void *packet, int length) { struct eqos_priv *eqos = dev_get_priv(dev); struct eqos_desc *tx_desc; @@ -1627,7 +1564,7 @@ static int eqos_send(struct udevice *dev, void *packet, int length) return -ETIMEDOUT; }
-static int eqos_recv(struct udevice *dev, int flags, uchar **packetp) +int eqos_recv(struct udevice *dev, int flags, uchar **packetp) { struct eqos_priv *eqos = dev_get_priv(dev); struct eqos_desc *rx_desc; @@ -1652,7 +1589,7 @@ static int eqos_recv(struct udevice *dev, int flags, uchar **packetp) return length; }
-static int eqos_free_pkt(struct udevice *dev, uchar *packet, int length) +int eqos_free_pkt(struct udevice *dev, uchar *packet, int length) { struct eqos_priv *eqos = dev_get_priv(dev); uchar *packet_expected; @@ -2031,7 +1968,7 @@ static int eqos_remove_resources_imx(struct udevice *dev) return 0; }
-static int eqos_probe(struct udevice *dev) +int eqos_probe(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); int ret; diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h new file mode 100644 index 0000000000..3125a301f0 --- /dev/null +++ b/drivers/net/dwc_eth_qos.h @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2020 + */ + +#ifndef _DWC_ETH_QOS_H +#define _DWC_ETH_QOS_H + +#include <reset.h> + +#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_NOT_ENABLED 0 +#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB 2 +#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV 1 + +#define EQOS_MAC_MDIO_ADDRESS_CR_20_35 2 +#define EQOS_MAC_MDIO_ADDRESS_CR_250_300 5 + + +struct eqos_config { + bool reg_access_always_ok; + int mdio_wait; + int swr_wait; + int config_mac; + int config_mac_mdio; + struct eqos_ops *ops; +}; + +struct eqos_ops { + void (*eqos_inval_desc)(void *desc); + void (*eqos_flush_desc)(void *desc); + void (*eqos_inval_buffer)(void *buf, size_t size); + void (*eqos_flush_buffer)(void *buf, size_t size); + int (*eqos_probe_resources)(struct udevice *dev); + int (*eqos_remove_resources)(struct udevice *dev); + int (*eqos_stop_resets)(struct udevice *dev); + int (*eqos_start_resets)(struct udevice *dev); + void (*eqos_stop_clks)(struct udevice *dev); + int (*eqos_start_clks)(struct udevice *dev); + int (*eqos_calibrate_pads)(struct udevice *dev); + int (*eqos_disable_calibration)(struct udevice *dev); + int (*eqos_set_tx_clk_speed)(struct udevice *dev); + ulong (*eqos_get_tick_clk_rate)(struct udevice *dev); + phy_interface_t (*eqos_get_interface)(struct udevice *dev); +}; + +struct eqos_priv { + struct udevice *dev; + const struct eqos_config *config; + fdt_addr_t regs; + struct eqos_mac_regs *mac_regs; + struct eqos_mtl_regs *mtl_regs; + struct eqos_dma_regs *dma_regs; + struct eqos_tegra186_regs *tegra186_regs; + struct reset_ctl reset_ctl; + struct gpio_desc phy_reset_gpio; + u32 reset_delays[3]; + struct clk clk_master_bus; + struct clk clk_rx; + struct clk clk_ptp_ref; + struct clk clk_tx; + struct clk clk_ck; + struct clk clk_slave_bus; + struct mii_dev *mii; + struct phy_device *phy; + int phyaddr; + u32 max_speed; + void *descs; + struct eqos_desc *tx_descs; + struct eqos_desc *rx_descs; + int tx_desc_idx, rx_desc_idx; + void *tx_dma_buf; + void *rx_dma_buf; + void *rx_pkt; + bool started; + bool reg_access_ok; +}; + +int eqos_init(struct udevice *dev); +void eqos_enable(struct udevice *dev); +int eqos_probe(struct udevice *dev); +void eqos_stop(struct udevice *dev); +int eqos_send(struct udevice *dev, void *packet, int length); +int eqos_recv(struct udevice *dev, int flags, uchar **packetp); +int eqos_free_pkt(struct udevice *dev, uchar *packet, int length); +int eqos_write_hwaddr(struct udevice *dev); + +#endif

Hi David
On 5/12/20 11:57 AM, David Wu wrote:
Open structure data and interface, so that Soc using dw_eth_qos controller can reference.
Signed-off-by: David Wu david.wu@rock-chips.com
Changes in v2:
- Add the lost head file. (Patrice)
drivers/net/dwc_eth_qos.c | 81 ++++-------------------------------- drivers/net/dwc_eth_qos.h | 87 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 72 deletions(-) create mode 100644 drivers/net/dwc_eth_qos.h
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 295707cbb0..b3195d484e 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -46,6 +46,7 @@ #include <asm/arch/clock.h> #include <asm/mach-imx/sys_proto.h> #endif +#include "dwc_eth_qos.h"
/* Core registers */
@@ -100,9 +101,6 @@ struct eqos_mac_regs {
#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT 0 #define EQOS_MAC_RXQ_CTRL0_RXQ0EN_MASK 3 -#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_NOT_ENABLED 0 -#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB 2 -#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV 1
#define EQOS_MAC_RXQ_CTRL2_PSRQ0_SHIFT 0 #define EQOS_MAC_RXQ_CTRL2_PSRQ0_MASK 0xff @@ -123,8 +121,6 @@ struct eqos_mac_regs { #define EQOS_MAC_MDIO_ADDRESS_PA_SHIFT 21 #define EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT 16 #define EQOS_MAC_MDIO_ADDRESS_CR_SHIFT 8 -#define EQOS_MAC_MDIO_ADDRESS_CR_20_35 2 -#define EQOS_MAC_MDIO_ADDRESS_CR_250_300 5 #define EQOS_MAC_MDIO_ADDRESS_SKAP BIT(4) #define EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT 2 #define EQOS_MAC_MDIO_ADDRESS_GOC_READ 3 @@ -277,65 +273,6 @@ struct eqos_desc { #define EQOS_DESC3_LD BIT(28) #define EQOS_DESC3_BUF1V BIT(24)
-struct eqos_config {
- bool reg_access_always_ok;
- int mdio_wait;
- int swr_wait;
- int config_mac;
- int config_mac_mdio;
- struct eqos_ops *ops;
-};
-struct eqos_ops {
- void (*eqos_inval_desc)(void *desc);
- void (*eqos_flush_desc)(void *desc);
- void (*eqos_inval_buffer)(void *buf, size_t size);
- void (*eqos_flush_buffer)(void *buf, size_t size);
- int (*eqos_probe_resources)(struct udevice *dev);
- int (*eqos_remove_resources)(struct udevice *dev);
- int (*eqos_stop_resets)(struct udevice *dev);
- int (*eqos_start_resets)(struct udevice *dev);
- void (*eqos_stop_clks)(struct udevice *dev);
- int (*eqos_start_clks)(struct udevice *dev);
- int (*eqos_calibrate_pads)(struct udevice *dev);
- int (*eqos_disable_calibration)(struct udevice *dev);
- int (*eqos_set_tx_clk_speed)(struct udevice *dev);
- ulong (*eqos_get_tick_clk_rate)(struct udevice *dev);
- phy_interface_t (*eqos_get_interface)(struct udevice *dev);
-};
-struct eqos_priv {
- struct udevice *dev;
- const struct eqos_config *config;
- fdt_addr_t regs;
- struct eqos_mac_regs *mac_regs;
- struct eqos_mtl_regs *mtl_regs;
- struct eqos_dma_regs *dma_regs;
- struct eqos_tegra186_regs *tegra186_regs;
- struct reset_ctl reset_ctl;
- struct gpio_desc phy_reset_gpio;
- u32 reset_delays[3];
- struct clk clk_master_bus;
- struct clk clk_rx;
- struct clk clk_ptp_ref;
- struct clk clk_tx;
- struct clk clk_ck;
- struct clk clk_slave_bus;
- struct mii_dev *mii;
- struct phy_device *phy;
- int phyaddr;
- u32 max_speed;
- void *descs;
- struct eqos_desc *tx_descs;
- struct eqos_desc *rx_descs;
- int tx_desc_idx, rx_desc_idx;
- void *tx_dma_buf;
- void *rx_dma_buf;
- void *rx_pkt;
- bool started;
- bool reg_access_ok;
-};
/*
- TX and RX descriptors are 16 bytes. This causes problems with the cache
- maintenance on CPUs where the cache-line size exceeds the size of these
@@ -1121,7 +1058,7 @@ static int eqos_adjust_link(struct udevice *dev) return 0; }
-static int eqos_write_hwaddr(struct udevice *dev) +int eqos_write_hwaddr(struct udevice *dev) { struct eth_pdata *plat = dev_get_platdata(dev); struct eqos_priv *eqos = dev_get_priv(dev); @@ -1175,7 +1112,7 @@ static int eqos_read_rom_hwaddr(struct udevice *dev) return !is_valid_ethaddr(pdata->enetaddr); }
-static int eqos_init(struct udevice *dev) +int eqos_init(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); int ret; @@ -1286,7 +1223,7 @@ err: return ret; }
-static void eqos_enable(struct udevice *dev) +void eqos_enable(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); u32 val, tx_fifo_sz, rx_fifo_sz, tqs, rqs, pbl; @@ -1530,7 +1467,7 @@ static int eqos_start(struct udevice *dev) return 0; }
-static void eqos_stop(struct udevice *dev) +void eqos_stop(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); int i; @@ -1585,7 +1522,7 @@ static void eqos_stop(struct udevice *dev) debug("%s: OK\n", __func__); }
-static int eqos_send(struct udevice *dev, void *packet, int length) +int eqos_send(struct udevice *dev, void *packet, int length) { struct eqos_priv *eqos = dev_get_priv(dev); struct eqos_desc *tx_desc; @@ -1627,7 +1564,7 @@ static int eqos_send(struct udevice *dev, void *packet, int length) return -ETIMEDOUT; }
-static int eqos_recv(struct udevice *dev, int flags, uchar **packetp) +int eqos_recv(struct udevice *dev, int flags, uchar **packetp) { struct eqos_priv *eqos = dev_get_priv(dev); struct eqos_desc *rx_desc; @@ -1652,7 +1589,7 @@ static int eqos_recv(struct udevice *dev, int flags, uchar **packetp) return length; }
-static int eqos_free_pkt(struct udevice *dev, uchar *packet, int length) +int eqos_free_pkt(struct udevice *dev, uchar *packet, int length) { struct eqos_priv *eqos = dev_get_priv(dev); uchar *packet_expected; @@ -2031,7 +1968,7 @@ static int eqos_remove_resources_imx(struct udevice *dev) return 0; }
-static int eqos_probe(struct udevice *dev) +int eqos_probe(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); int ret; diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h new file mode 100644 index 0000000000..3125a301f0 --- /dev/null +++ b/drivers/net/dwc_eth_qos.h @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/*
- Copyright 2020
- */
+#ifndef _DWC_ETH_QOS_H +#define _DWC_ETH_QOS_H
+#include <reset.h>
+#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_NOT_ENABLED 0 +#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB 2 +#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV 1
+#define EQOS_MAC_MDIO_ADDRESS_CR_20_35 2 +#define EQOS_MAC_MDIO_ADDRESS_CR_250_300 5
+struct eqos_config {
- bool reg_access_always_ok;
- int mdio_wait;
- int swr_wait;
- int config_mac;
- int config_mac_mdio;
- struct eqos_ops *ops;
+};
+struct eqos_ops {
- void (*eqos_inval_desc)(void *desc);
- void (*eqos_flush_desc)(void *desc);
- void (*eqos_inval_buffer)(void *buf, size_t size);
- void (*eqos_flush_buffer)(void *buf, size_t size);
- int (*eqos_probe_resources)(struct udevice *dev);
- int (*eqos_remove_resources)(struct udevice *dev);
- int (*eqos_stop_resets)(struct udevice *dev);
- int (*eqos_start_resets)(struct udevice *dev);
- void (*eqos_stop_clks)(struct udevice *dev);
- int (*eqos_start_clks)(struct udevice *dev);
- int (*eqos_calibrate_pads)(struct udevice *dev);
- int (*eqos_disable_calibration)(struct udevice *dev);
- int (*eqos_set_tx_clk_speed)(struct udevice *dev);
- ulong (*eqos_get_tick_clk_rate)(struct udevice *dev);
- phy_interface_t (*eqos_get_interface)(struct udevice *dev);
+};
+struct eqos_priv {
- struct udevice *dev;
- const struct eqos_config *config;
- fdt_addr_t regs;
- struct eqos_mac_regs *mac_regs;
- struct eqos_mtl_regs *mtl_regs;
- struct eqos_dma_regs *dma_regs;
- struct eqos_tegra186_regs *tegra186_regs;
- struct reset_ctl reset_ctl;
- struct gpio_desc phy_reset_gpio;
- u32 reset_delays[3];
- struct clk clk_master_bus;
- struct clk clk_rx;
- struct clk clk_ptp_ref;
- struct clk clk_tx;
- struct clk clk_ck;
- struct clk clk_slave_bus;
- struct mii_dev *mii;
- struct phy_device *phy;
- int phyaddr;
- u32 max_speed;
- void *descs;
- struct eqos_desc *tx_descs;
- struct eqos_desc *rx_descs;
- int tx_desc_idx, rx_desc_idx;
- void *tx_dma_buf;
- void *rx_dma_buf;
- void *rx_pkt;
- bool started;
- bool reg_access_ok;
+};
+int eqos_init(struct udevice *dev); +void eqos_enable(struct udevice *dev); +int eqos_probe(struct udevice *dev); +void eqos_stop(struct udevice *dev); +int eqos_send(struct udevice *dev, void *packet, int length); +int eqos_recv(struct udevice *dev, int flags, uchar **packetp); +int eqos_free_pkt(struct udevice *dev, uchar *packet, int length); +int eqos_write_hwaddr(struct udevice *dev);
+#endif
Reviewed-by: Patrice Chotard patrice.chotard@st.com
Thanks

Change the original data structure so that Rockchip's Soc gmac controller can support the designware.c and dwc_eth_qos.c drivers, a Soc can only support one.
Signed-off-by: David Wu david.wu@rock-chips.com ---
Changes in v2: - None
drivers/net/Kconfig | 2 +- drivers/net/gmac_rockchip.c | 160 ++++++++++++++++++++++++++++++------ 2 files changed, 135 insertions(+), 27 deletions(-)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 38f2bd6637..d29adebee0 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -490,7 +490,7 @@ config PIC32_ETH
config GMAC_ROCKCHIP bool "Rockchip Synopsys Designware Ethernet MAC" - depends on DM_ETH && ETH_DESIGNWARE + depends on DM_ETH && (ETH_DESIGNWARE || DWC_ETH_QOS) help This driver provides Rockchip SoCs network support based on the Synopsys Designware driver. diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c index e152faf083..aa2bab4203 100644 --- a/drivers/net/gmac_rockchip.c +++ b/drivers/net/gmac_rockchip.c @@ -25,26 +25,39 @@ #include <dm/pinctrl.h> #include <dt-bindings/clock/rk3288-cru.h> #include "designware.h" +#include "dwc_eth_qos.h"
DECLARE_GLOBAL_DATA_PTR; #define DELAY_ENABLE(soc, tx, rx) \ (((tx) ? soc##_TXCLK_DLY_ENA_GMAC_ENABLE : soc##_TXCLK_DLY_ENA_GMAC_DISABLE) | \ ((rx) ? soc##_RXCLK_DLY_ENA_GMAC_ENABLE : soc##_RXCLK_DLY_ENA_GMAC_DISABLE))
+struct rockchip_eth_dev { + union { + struct eqos_priv eqos; + struct dw_eth_dev dw; + }; +}; + /* * Platform data for the gmac * * dw_eth_pdata: Required platform data for designware driver (must be first) */ struct gmac_rockchip_platdata { - struct dw_eth_pdata dw_eth_pdata; + union { + struct dw_eth_pdata dw_eth_pdata; + struct eth_pdata eth_pdata; + }; + bool has_gmac4; bool clock_input; int tx_delay; int rx_delay; };
struct rk_gmac_ops { - int (*fix_mac_speed)(struct dw_eth_dev *priv); + const struct eqos_config config; + int (*fix_mac_speed)(struct rockchip_eth_dev *dev); void (*set_to_rmii)(struct gmac_rockchip_platdata *pdata); void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata); }; @@ -55,6 +68,9 @@ static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); const char *string;
+ if (device_is_compatible(dev, "snps,dwmac-4.20a")) + pdata->has_gmac4 = true; + string = dev_read_string(dev, "clock_in_out"); if (!strcmp(string, "input")) pdata->clock_input = true; @@ -71,11 +87,15 @@ static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) if (pdata->rx_delay == -ENOENT) pdata->rx_delay = dev_read_u32_default(dev, "rx-delay", 0x10);
- return designware_eth_ofdata_to_platdata(dev); + if (!pdata->has_gmac4) + return designware_eth_ofdata_to_platdata(dev); + + return 0; }
-static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int px30_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) { + struct dw_eth_dev *priv = &dev->dw; struct px30_grf *grf; struct clk clk_speed; int speed, ret; @@ -115,8 +135,9 @@ static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv) return 0; }
-static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3228_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) { + struct dw_eth_dev *priv = &dev->dw; struct rk322x_grf *grf; int clk; enum { @@ -148,8 +169,9 @@ static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv) return 0; }
-static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3288_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) { + struct dw_eth_dev *priv = &dev->dw; struct rk3288_grf *grf; int clk;
@@ -174,8 +196,9 @@ static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) return 0; }
-static int rk3308_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3308_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) { + struct dw_eth_dev *priv = &dev->dw; struct rk3308_grf *grf; struct clk clk_speed; int speed, ret; @@ -215,8 +238,9 @@ static int rk3308_gmac_fix_mac_speed(struct dw_eth_dev *priv) return 0; }
-static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3328_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) { + struct dw_eth_dev *priv = &dev->dw; struct rk3328_grf_regs *grf; int clk; enum { @@ -248,8 +272,9 @@ static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv) return 0; }
-static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3368_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) { + struct dw_eth_dev *priv = &dev->dw; struct rk3368_grf *grf; int clk; enum { @@ -280,8 +305,9 @@ static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv) return 0; }
-static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3399_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) { + struct dw_eth_dev *priv = &dev->dw; struct rk3399_grf_regs *grf; int clk;
@@ -306,8 +332,9 @@ static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv) return 0; }
-static int rv1108_set_rmii_speed(struct dw_eth_dev *priv) +static int rv1108_set_rmii_speed(struct rockchip_eth_dev *dev) { + struct dw_eth_dev *priv = &dev->dw; struct rv1108_grf *grf; int clk, speed; enum { @@ -555,12 +582,22 @@ static int gmac_rockchip_probe(struct udevice *dev) struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); struct rk_gmac_ops *ops = (struct rk_gmac_ops *)dev_get_driver_data(dev); - struct dw_eth_pdata *dw_pdata = dev_get_platdata(dev); - struct eth_pdata *eth_pdata = &dw_pdata->eth_pdata; + struct dw_eth_pdata *dw_pdata; + struct eth_pdata *eth_pdata; + struct eqos_config *config; struct clk clk; ulong rate; int ret;
+ if (pdata->has_gmac4) { + eth_pdata = &pdata->eth_pdata; + config = (struct eqos_config *)&ops->config; + eth_pdata->phy_interface = config->ops->eqos_get_interface(dev); + } else { + dw_pdata = &pdata->dw_eth_pdata; + eth_pdata = &dw_pdata->eth_pdata; + } + ret = clk_set_defaults(dev, 0); if (ret) debug("%s clk_set_defaults failed %d\n", __func__, ret); @@ -656,37 +693,108 @@ static int gmac_rockchip_probe(struct udevice *dev) return -ENXIO; }
- return designware_eth_probe(dev); + if (pdata->has_gmac4) + return eqos_probe(dev); + else + return designware_eth_probe(dev); +} + +static int gmac_rockchip_eth_write_hwaddr(struct udevice *dev) +{ + struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); + + if (pdata->has_gmac4) + return eqos_write_hwaddr(dev); + else + return designware_eth_write_hwaddr(dev); +} + +static int gmac_rockchip_eth_free_pkt(struct udevice *dev, uchar *packet, + int length) +{ + struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); + + if (pdata->has_gmac4) + return eqos_free_pkt(dev, packet, length); + else + return designware_eth_free_pkt(dev, packet, length); +} + +static int gmac_rockchip_eth_send(struct udevice *dev, void *packet, + int length) +{ + struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); + + if (pdata->has_gmac4) + return eqos_send(dev, packet, length); + else + return designware_eth_send(dev, packet, length); +} + +static int gmac_rockchip_eth_recv(struct udevice *dev, int flags, + uchar **packetp) +{ + struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); + + if (pdata->has_gmac4) + return eqos_recv(dev, flags, packetp); + else + return designware_eth_recv(dev, flags, packetp); }
static int gmac_rockchip_eth_start(struct udevice *dev) { - struct eth_pdata *pdata = dev_get_platdata(dev); - struct dw_eth_dev *priv = dev_get_priv(dev); + struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); + struct rockchip_eth_dev *priv = dev_get_priv(dev); struct rk_gmac_ops *ops = (struct rk_gmac_ops *)dev_get_driver_data(dev); + struct dw_eth_pdata *dw_pdata; + struct eth_pdata *eth_pdata; int ret;
- ret = designware_eth_init(priv, pdata->enetaddr); + if (pdata->has_gmac4) { + ret = eqos_init(dev); + } else { + dw_pdata = &pdata->dw_eth_pdata; + eth_pdata = &dw_pdata->eth_pdata; + ret = designware_eth_init((struct dw_eth_dev *)priv, + eth_pdata->enetaddr); + } if (ret) return ret; + ret = ops->fix_mac_speed(priv); if (ret) return ret; - ret = designware_eth_enable(priv); - if (ret) - return ret; + + if (pdata->has_gmac4) { + eqos_enable(dev); + } else { + ret = designware_eth_enable((struct dw_eth_dev *)priv); + if (ret) + return ret; + }
return 0; }
+static void gmac_rockchip_eth_stop(struct udevice *dev) +{ + struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); + + if (pdata->has_gmac4) + eqos_stop(dev); + else + designware_eth_stop(dev); +} + const struct eth_ops gmac_rockchip_eth_ops = { .start = gmac_rockchip_eth_start, - .send = designware_eth_send, - .recv = designware_eth_recv, - .free_pkt = designware_eth_free_pkt, - .stop = designware_eth_stop, - .write_hwaddr = designware_eth_write_hwaddr, + .send = gmac_rockchip_eth_send, + .recv = gmac_rockchip_eth_recv, + .free_pkt = gmac_rockchip_eth_free_pkt, + .stop = gmac_rockchip_eth_stop, + .write_hwaddr = gmac_rockchip_eth_write_hwaddr, };
const struct rk_gmac_ops px30_gmac_ops = { @@ -756,7 +864,7 @@ U_BOOT_DRIVER(eth_gmac_rockchip) = { .ofdata_to_platdata = gmac_rockchip_ofdata_to_platdata, .probe = gmac_rockchip_probe, .ops = &gmac_rockchip_eth_ops, - .priv_auto_alloc_size = sizeof(struct dw_eth_dev), + .priv_auto_alloc_size = sizeof(struct rockchip_eth_dev), .platdata_auto_alloc_size = sizeof(struct gmac_rockchip_platdata), .flags = DM_FLAG_ALLOC_PRIV_DMA, };

The eqos_rockchip_ops is simillar to eqos_stm32_ops, and export the eqos_rockchip_ops to use.
Signed-off-by: David Wu david.wu@rock-chips.com ---
Changes in v2: - None
drivers/net/dwc_eth_qos.c | 16 ++++++++++++++++ drivers/net/dwc_eth_qos.h | 2 ++ 2 files changed, 18 insertions(+)
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index b3195d484e..f4f6f73849 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -2147,6 +2147,22 @@ struct eqos_config eqos_imx_config = { .ops = &eqos_imx_ops };
+struct eqos_ops eqos_rockchip_ops = { + .eqos_inval_desc = eqos_inval_desc_generic, + .eqos_flush_desc = eqos_flush_desc_generic, + .eqos_inval_buffer = eqos_inval_buffer_generic, + .eqos_flush_buffer = eqos_flush_buffer_generic, + .eqos_probe_resources = eqos_probe_resources_stm32, + .eqos_remove_resources = eqos_remove_resources_stm32, + .eqos_stop_resets = eqos_stop_resets_stm32, + .eqos_start_resets = eqos_start_resets_stm32, + .eqos_calibrate_pads = eqos_calibrate_pads_stm32, + .eqos_disable_calibration = eqos_disable_calibration_stm32, + .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_stm32, + .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_stm32, + .eqos_get_interface = eqos_get_interface_stm32 +}; + static const struct udevice_id eqos_ids[] = { { .compatible = "nvidia,tegra186-eqos", diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h index 3125a301f0..def2706271 100644 --- a/drivers/net/dwc_eth_qos.h +++ b/drivers/net/dwc_eth_qos.h @@ -84,4 +84,6 @@ int eqos_recv(struct udevice *dev, int flags, uchar **packetp); int eqos_free_pkt(struct udevice *dev, uchar *packet, int length); int eqos_write_hwaddr(struct udevice *dev);
+extern struct eqos_ops eqos_rockchip_ops; + #endif

HI David
On 5/12/20 11:58 AM, David Wu wrote:
The eqos_rockchip_ops is simillar to eqos_stm32_ops, and
Typo simillar
export the eqos_rockchip_ops to use.
Signed-off-by: David Wu david.wu@rock-chips.com
Changes in v2:
- None
drivers/net/dwc_eth_qos.c | 16 ++++++++++++++++ drivers/net/dwc_eth_qos.h | 2 ++ 2 files changed, 18 insertions(+)
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index b3195d484e..f4f6f73849 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -2147,6 +2147,22 @@ struct eqos_config eqos_imx_config = { .ops = &eqos_imx_ops };
+struct eqos_ops eqos_rockchip_ops = {
- .eqos_inval_desc = eqos_inval_desc_generic,
- .eqos_flush_desc = eqos_flush_desc_generic,
- .eqos_inval_buffer = eqos_inval_buffer_generic,
- .eqos_flush_buffer = eqos_flush_buffer_generic,
- .eqos_probe_resources = eqos_probe_resources_stm32,
- .eqos_remove_resources = eqos_remove_resources_stm32,
- .eqos_stop_resets = eqos_stop_resets_stm32,
- .eqos_start_resets = eqos_start_resets_stm32,
- .eqos_calibrate_pads = eqos_calibrate_pads_stm32,
- .eqos_disable_calibration = eqos_disable_calibration_stm32,
- .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_stm32,
- .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_stm32,
- .eqos_get_interface = eqos_get_interface_stm32
+};
static const struct udevice_id eqos_ids[] = { { .compatible = "nvidia,tegra186-eqos", diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h index 3125a301f0..def2706271 100644 --- a/drivers/net/dwc_eth_qos.h +++ b/drivers/net/dwc_eth_qos.h @@ -84,4 +84,6 @@ int eqos_recv(struct udevice *dev, int flags, uchar **packetp); int eqos_free_pkt(struct udevice *dev, uchar *packet, int length); int eqos_write_hwaddr(struct udevice *dev);
+extern struct eqos_ops eqos_rockchip_ops;
#endif
Reviewed-by: Patrice Chotard patrice.chotard@st.com
Thanks

The Rockchip CSR clock range is from 100M to 150M, add EQOS_MAC_MDIO_ADDRESS_CR_100_150.
Signed-off-by: David Wu david.wu@rock-chips.com ---
Changes in v2: - None
drivers/net/dwc_eth_qos.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h index def2706271..39f8452c17 100644 --- a/drivers/net/dwc_eth_qos.h +++ b/drivers/net/dwc_eth_qos.h @@ -12,10 +12,10 @@ #define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB 2 #define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV 1
+#define EQOS_MAC_MDIO_ADDRESS_CR_100_150 1 #define EQOS_MAC_MDIO_ADDRESS_CR_20_35 2 #define EQOS_MAC_MDIO_ADDRESS_CR_250_300 5
- struct eqos_config { bool reg_access_always_ok; int mdio_wait;

Hi David
On 5/12/20 11:58 AM, David Wu wrote:
The Rockchip CSR clock range is from 100M to 150M, add EQOS_MAC_MDIO_ADDRESS_CR_100_150.
Signed-off-by: David Wu david.wu@rock-chips.com
Changes in v2:
- None
drivers/net/dwc_eth_qos.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h index def2706271..39f8452c17 100644 --- a/drivers/net/dwc_eth_qos.h +++ b/drivers/net/dwc_eth_qos.h @@ -12,10 +12,10 @@ #define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB 2 #define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV 1
+#define EQOS_MAC_MDIO_ADDRESS_CR_100_150 1 #define EQOS_MAC_MDIO_ADDRESS_CR_20_35 2 #define EQOS_MAC_MDIO_ADDRESS_CR_250_300 5
struct eqos_config { bool reg_access_always_ok; int mdio_wait;
Reviewed-by: Patrice Chotard patrice.chotard@st.com
Thanks

This Soc is different from the previous Socs, need to define eqos_config, and follow the dwc_eth_qos driver process.
Signed-off-by: David Wu david.wu@rock-chips.com ---
Changes in v2: - None
drivers/net/gmac_rockchip.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c index aa2bab4203..d48a0f516b 100644 --- a/drivers/net/gmac_rockchip.c +++ b/drivers/net/gmac_rockchip.c @@ -368,6 +368,13 @@ static int rv1108_set_rmii_speed(struct rockchip_eth_dev *dev) return 0; }
+static int rv1126_set_rgmii_speed(struct rockchip_eth_dev *dev) +{ + /* TO DO... */ + + return 0; +} + static void px30_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata) { struct px30_grf *grf; @@ -577,6 +584,11 @@ static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata) RV1108_GMAC_PHY_INTF_SEL_RMII); }
+static void rv1126_set_to_rgmii(struct gmac_rockchip_platdata *pdata) +{ + /* TO DO... */ +} + static int gmac_rockchip_probe(struct udevice *dev) { struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); @@ -837,6 +849,20 @@ const struct rk_gmac_ops rv1108_gmac_ops = { .set_to_rmii = rv1108_gmac_set_to_rmii, };
+const struct rk_gmac_ops rv1126_gmac_ops = { + .config = { + .reg_access_always_ok = false, + .mdio_wait = 10000, + .swr_wait = 200, + .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_NOT_ENABLED, + .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_100_150, + .ops = &eqos_rockchip_ops + }, + + .fix_mac_speed = rv1126_set_rgmii_speed, + .set_to_rgmii = rv1126_set_to_rgmii, +}; + static const struct udevice_id rockchip_gmac_ids[] = { { .compatible = "rockchip,px30-gmac", .data = (ulong)&px30_gmac_ops }, @@ -854,6 +880,8 @@ static const struct udevice_id rockchip_gmac_ids[] = { .data = (ulong)&rk3399_gmac_ops }, { .compatible = "rockchip,rv1108-gmac", .data = (ulong)&rv1108_gmac_ops }, + { .compatible = "rockchip,rv1126-gmac", + .data = (ulong)&rv1126_gmac_ops }, { } };
participants (5)
-
David Wu
-
Marek Vasut
-
Patrice CHOTARD
-
Patrick DELAUNAY
-
Tom Rini