Re: [v3, net-next, 02/12] net: stmmac: Do not keep rearming the coalesce timer in stmmac_xmit

2018-08-23 Thread Martin Blumenstingl
Hi,

On Fri, Aug 17, 2018 at 9:32 AM Jerome Brunet  wrote:
>
> On Fri, 2018-05-18 at 14:55 +0100, Jose Abreu wrote:
> > This is cutting down performance. Once the timer is armed it should run
> > after the time expires for the first packet sent and not the last one.
> >
> > After this change, running iperf, the performance gain is +/- 24%.
>
> Hi Guys,
>
> Since v4.18, we are getting a serious regression on Amlogic based SoCs.
> I have tested this on amlogic's:
> * gxbb S905 p200 (Micrel KSZ9031 - 1GBps)
> * axg A113 s400 (Realtek RTL8211F - 1GBps)
>
> Both SoCs use the synopsys gmac with stmmac driver.
I can confirm this on Odroid-C1 (Meson8b SoC with RTL8211F RGMII PHY) as well

> I first noticed that running NFS root filesystem became unstable but I could 
> not
> understand why. Then, running a download as simple test with iperf3 (from an
> initramfs) will break the 'network' in matter of seconds.
I didn't run iperf, simply downloading the latest rootfs package
updates (on Arch Linux ARM) caused the network to break

> I don't know exactly what breaks but bisect clearly assign the blame to this
> change. Reverting the change solve this problem.
>
> I'll be happy to make more tests to help understand what is happening here.
if some latency is fine then I can also help testing

here's a bootlog excerpt with the info from the dwmac-meson8b driver
(used on all platforms listed above):
meson8b-dwmac c941.ethernet: PTP uses main clock
meson8b-dwmac c941.ethernet: User ID: 0x10, Synopsys ID: 0x37
meson8b-dwmac c941.ethernet: DWMAC1000
meson8b-dwmac c941.ethernet: DMA HW capability register supported
meson8b-dwmac c941.ethernet: RX Checksum Offload Engine supported
meson8b-dwmac c941.ethernet: COE Type 2
meson8b-dwmac c941.ethernet: TX Checksum insertion supported
meson8b-dwmac c941.ethernet: Wake-Up On Lan supported
meson8b-dwmac c941.ethernet: Normal descriptors
meson8b-dwmac c941.ethernet: Ring mode enabled
meson8b-dwmac c941.ethernet: Enable RX Mitigation via HW Watchdog Timer
...
meson8b-dwmac c941.ethernet eth0: device MAC address [...random
mac address...]
RTL8211F Gigabit Ethernet stmmac-0:00: attached PHY driver [RTL8211F
Gigabit Ethernet] (mii_bus:phy_addr=stmmac-0:00, irq=27)
...
meson8b-dwmac c941.ethernet eth0: No Safety Features support found
meson8b-dwmac c941.ethernet eth0: PTP not supported by HW
IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready


Regards
Martin


Re: [PATCH v2 2/2] net: stmmac: dwmac-meson: extend phy mode setting

2018-05-01 Thread Martin Blumenstingl
Hello Yixun,

On Sat, Apr 28, 2018 at 12:21 PM, Yixun Lan <yixun@amlogic.com> wrote:
>   In the Meson-AXG SoC, the phy mode setting of PRG_ETH0 in the glue layer
> is extended from bit[0] to bit[2:0].
>   There is no problem if we configure it to the RGMII 1000M PHY mode,
> since the register setting is coincidentally compatible with previous one,
> but for the RMII 100M PHY mode, the configuration need to be changed to
> value - b100.
>   This patch was verified with a RTL8201F 100M ethernet PHY.
>
> Signed-off-by: Yixun Lan <yixun@amlogic.com>
> ---
>  .../ethernet/stmicro/stmmac/dwmac-meson8b.c   | 120 +++---
>  1 file changed, 104 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
> b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
> index 7cb794094a70..4ff231df7322 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
> @@ -18,6 +18,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -29,6 +30,10 @@
>
>  #define PRG_ETH0_RGMII_MODEBIT(0)
>
> +#define PRG_ETH0_EXT_PHY_MODE_MASK GENMASK(2, 0)
> +#define PRG_ETH0_EXT_RGMII_MODE1
> +#define PRG_ETH0_EXT_RMII_MODE 4
> +
>  /* mux to choose between fclk_div2 (bit unset) and mpll2 (bit set) */
>  #define PRG_ETH0_CLK_M250_SEL_SHIFT4
>  #define PRG_ETH0_CLK_M250_SEL_MASK GENMASK(4, 4)
> @@ -47,12 +52,20 @@
>
>  #define MUX_CLK_NUM_PARENTS2
>
> +struct meson8b_dwmac;
> +
> +struct meson8b_dwmac_data {
> +   int (*set_phy_mode)(struct meson8b_dwmac *dwmac);
> +};
> +
>  struct meson8b_dwmac {
> -   struct device   *dev;
> -   void __iomem*regs;
> -   phy_interface_t phy_mode;
> -   struct clk  *rgmii_tx_clk;
> -   u32 tx_delay_ns;
> +   struct device   *dev;
> +   void __iomem*regs;
> +
> +   const struct meson8b_dwmac_data *data;
> +   phy_interface_t phy_mode;
> +   struct clk  *rgmii_tx_clk;
> +   u32 tx_delay_ns;
>  };
>
>  struct meson8b_dwmac_clk_configs {
> @@ -171,6 +184,59 @@ static int meson8b_init_rgmii_tx_clk(struct 
> meson8b_dwmac *dwmac)
> return 0;
>  }
>
> +static int meson8b_set_phy_mode(struct meson8b_dwmac *dwmac)
> +{
> +   switch (dwmac->phy_mode) {
> +   case PHY_INTERFACE_MODE_RGMII:
> +   case PHY_INTERFACE_MODE_RGMII_RXID:
> +   case PHY_INTERFACE_MODE_RGMII_ID:
> +   case PHY_INTERFACE_MODE_RGMII_TXID:
> +   /* enable RGMII mode */
> +   meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
> +   PRG_ETH0_RGMII_MODE,
> +   PRG_ETH0_RGMII_MODE);
> +   break;
> +   case PHY_INTERFACE_MODE_RMII:
> +   /* disable RGMII mode -> enables RMII mode */
> +   meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
> +   PRG_ETH0_RGMII_MODE, 0);
> +   break;
> +   default:
> +   dev_err(dwmac->dev, "fail to set phy-mode %s\n",
> +   phy_modes(dwmac->phy_mode));
> +   return -EINVAL;
> +   }
> +
> +   return 0;
> +}
> +
> +static int meson_axg_set_phy_mode(struct meson8b_dwmac *dwmac)
> +{
> +   switch (dwmac->phy_mode) {
> +   case PHY_INTERFACE_MODE_RGMII:
> +   case PHY_INTERFACE_MODE_RGMII_RXID:
> +   case PHY_INTERFACE_MODE_RGMII_ID:
> +   case PHY_INTERFACE_MODE_RGMII_TXID:
> +   /* enable RGMII mode */
> +   meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
> +   PRG_ETH0_EXT_PHY_MODE_MASK,
> +   PRG_ETH0_EXT_RGMII_MODE);
> +   break;
> +   case PHY_INTERFACE_MODE_RMII:
> +   /* disable RGMII mode -> enables RMII mode */
if you have to re-send it for whatever reason:
maybe you could remove the comments from meson_axg_set_phy_mode. the
"older" register layout requires un-setting RGMII mode to enable RMII
mode. however, for AXG there seem to be two dedicated values (1 and 4)
for each mode

apart from that:
Acked-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>

> +   meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
> +   PRG_ETH0_EXT_PHY_MODE_MASK,
> +   

[PATCH net-next v1 1/2] dt-bindings: net: meson-dwmac: add support for the Meson8m2 SoC

2018-03-29 Thread Martin Blumenstingl
The Meson8m2 SoC uses a similar (potentially even identical) register
layout for the dwmac glue as Meson8b and GXBB. Unfortunately there is no
documentation available.
Testing shows that both, RMII and RGMII PHYs are working if they are
configured as on Meson8b. Add a new compatible string to the
documentation so differences (if there are any) between Meson8m2 and the
other SoCs can be taken care of within the driver.

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 Documentation/devicetree/bindings/net/meson-dwmac.txt | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/meson-dwmac.txt 
b/Documentation/devicetree/bindings/net/meson-dwmac.txt
index 354dd9896bb5..61cada22ae6c 100644
--- a/Documentation/devicetree/bindings/net/meson-dwmac.txt
+++ b/Documentation/devicetree/bindings/net/meson-dwmac.txt
@@ -9,6 +9,7 @@ Required properties on all platforms:
 - compatible:  Depending on the platform this should be one of:
- "amlogic,meson6-dwmac"
- "amlogic,meson8b-dwmac"
+   - "amlogic,meson8m2-dwmac"
- "amlogic,meson-gxbb-dwmac"
Additionally "snps,dwmac" and any applicable more
detailed version number described in net/stmmac.txt
@@ -19,13 +20,13 @@ Required properties on all platforms:
configuration (for example the PRG_ETHERNET register range
on Meson8b and newer)
 
-Required properties on Meson8b and newer:
+Required properties on Meson8b, Meson8m2, GXBB and newer:
 - clock-names: Should contain the following:
- "stmmaceth" - see stmmac.txt
- "clkin0" - first parent clock of the internal mux
- "clkin1" - second parent clock of the internal mux
 
-Optional properties on Meson8b and newer:
+Optional properties on Meson8b, Meson8m2, GXBB and newer:
 - amlogic,tx-delay-ns: The internal RGMII TX clock delay (provided
by this driver) in nanoseconds. Allowed values
are: 0ns, 2ns, 4ns, 6ns.
-- 
2.16.3



[PATCH net-next v1 0/2] Meson8m2 support for dwmac-meson8b

2018-03-29 Thread Martin Blumenstingl
The Meson8m2 SoC is an updated version of the Meson8 SoC. Some of the
peripherals are shared with Meson8b (for example the watchdog registers
and the internal temperature sensor calibration procedure).
Meson8m2 also seems to include the same Gigabit MAC register layout as
Meson8b.

The registers in the Amlogic dwmac "glue" seem identical between Meson8b
and Meson8m2. Manual testing seems to confirm this.

To be extra-safe a new compatible string is added because there's no
(public) documentation on the Meson8m2 SoC. This will allow us to
implement any SoC-specific variations later on (if needed).


Martin Blumenstingl (2):
  dt-bindings: net: meson-dwmac: add support for the Meson8m2 SoC
  net: stmmac: dwmac-meson8b: Add support for the Meson8m2 SoC

 Documentation/devicetree/bindings/net/meson-dwmac.txt | 5 +++--
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c   | 5 +++--
 2 files changed, 6 insertions(+), 4 deletions(-)

-- 
2.16.3



[PATCH net-next v1 2/2] net: stmmac: dwmac-meson8b: Add support for the Meson8m2 SoC

2018-03-29 Thread Martin Blumenstingl
The Meson8m2 SoC uses a similar (potentially even identical) register
layout as the Meson8b and GXBB SoCs for the dwmac glue.
Add a new compatible string and update the module description to
indicate support for these SoCs.

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index 2d5d4aea3bcb..7cb794094a70 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -1,5 +1,5 @@
 /*
- * Amlogic Meson8b and GXBB DWMAC glue layer
+ * Amlogic Meson8b, Meson8m2 and GXBB DWMAC glue layer
  *
  * Copyright (C) 2016 Martin Blumenstingl <martin.blumensti...@googlemail.com>
  *
@@ -318,6 +318,7 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
 
 static const struct of_device_id meson8b_dwmac_match[] = {
{ .compatible = "amlogic,meson8b-dwmac" },
+   { .compatible = "amlogic,meson8m2-dwmac" },
{ .compatible = "amlogic,meson-gxbb-dwmac" },
{ }
 };
@@ -335,5 +336,5 @@ static struct platform_driver meson8b_dwmac_driver = {
 module_platform_driver(meson8b_dwmac_driver);
 
 MODULE_AUTHOR("Martin Blumenstingl <martin.blumensti...@googlemail.com>");
-MODULE_DESCRIPTION("Amlogic Meson8b and GXBB DWMAC glue layer");
+MODULE_DESCRIPTION("Amlogic Meson8b, Meson8m2 and GXBB DWMAC glue layer");
 MODULE_LICENSE("GPL v2");
-- 
2.16.3



Re: [net-next PATCH v1 3/3] net: stmmac: dwmac-meson8b: make the clock configurations private

2018-02-17 Thread Martin Blumenstingl
Hi Jerome,

On Sat, Feb 17, 2018 at 5:41 PM, Jerome Brunet <jbru...@baylibre.com> wrote:
> On Sat, 2018-02-17 at 15:08 +0100, Martin Blumenstingl wrote:
>> The common clock framework needs access to the "clock configuration"
>> structs during runtime.
>> However, only the common clock framework should access these. Ensure
>> this by moving the configuration structs out of struct meson8b_dwmac,
>> so only meson8b_init_rgmii_tx_clk() and the common clock framework know
>> about these configurations.
>>
>> Suggested-by: Jerome Brunet <jbru...@baylibre.com>
>> Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
>
> Acked-by: Jerome Brunet <jbru...@baylibre.com>
thank you reviewing this!

>> ---
>>  .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c| 45 
>> --
>>  1 file changed, 24 insertions(+), 21 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
>> b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
>> index 0dfce35c5583..2d5d4aea3bcb 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
>> @@ -49,19 +49,17 @@
>>
>>  struct meson8b_dwmac {
>> struct device   *dev;
>> -
>> void __iomem*regs;
>> -
>> phy_interface_t phy_mode;
>> +   struct clk  *rgmii_tx_clk;
>> +   u32 tx_delay_ns;
>> +};
>>
>> +struct meson8b_dwmac_clk_configs {
>
> Not too sure we needed a struct for this, but it does work and does not matter
> much
I tried it without this struct: this resulted in even more code
because every struct clk_* would have to be devm_kzalloc()'ed, along
with a "if (!result) return -ENOMEM" (which makes it 3 lines per
struct clk_*)
either way: it's still an improvement as per commit message

>> struct clk_mux  m250_mux;
>> struct clk_divider  m250_div;
>> struct clk_fixed_factor fixed_div2;
>> struct clk_gate rgmii_tx_en;
>> -
>> -   struct clk  *rgmii_tx_clk;
>> -
>> -   u32 tx_delay_ns;
>>  };
>

Regards
Martin


[net-next PATCH v1 1/3] net: stmmac: dwmac-meson8b: simplify clock registration

2018-02-17 Thread Martin Blumenstingl
To goal of this patch is to simplify the registration of the RGMII TX
clock (and it's parent clocks). This is achieved by:
- introducing the meson8b_dwmac_register_clk helper-function to remove
  code duplication when registering a single clock (this saves a few
  lines since we have 4 clocks internally)
- using devm_add_action_or_reset to disable the RGMII TX clock
  automatically when needed. This also allows us to re-use the standard
  stmmac_pltfr_remove function.
- devm_kasprintf() and devm_kstrdup() are not used anymore to generate
  the clock name (these are replaced by a variable on the stack) because
  the common clock framework already uses kstrdup() internally.

No functional changes intended.

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c| 156 +
 1 file changed, 65 insertions(+), 91 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index 5270d26f0bc6..84a9a900e74e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -55,17 +55,11 @@ struct meson8b_dwmac {
phy_interface_t phy_mode;
 
struct clk_mux  m250_mux;
-   struct clk  *m250_mux_clk;
-   struct clk  *m250_mux_parent[MUX_CLK_NUM_PARENTS];
-
struct clk_divider  m250_div;
-   struct clk  *m250_div_clk;
-
struct clk_fixed_factor fixed_div2;
-   struct clk  *fixed_div2_clk;
-
struct clk_gate rgmii_tx_en;
-   struct clk  *rgmii_tx_en_clk;
+
+   struct clk  *rgmii_tx_clk;
 
u32 tx_delay_ns;
 };
@@ -82,106 +76,95 @@ static void meson8b_dwmac_mask_bits(struct meson8b_dwmac 
*dwmac, u32 reg,
writel(data, dwmac->regs + reg);
 }
 
-static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac *dwmac)
+static struct clk *meson8b_dwmac_register_clk(struct meson8b_dwmac *dwmac,
+ const char *name_suffix,
+ const char **parent_names,
+ int num_parents,
+ const struct clk_ops *ops,
+ struct clk_hw *hw)
 {
+   struct device *dev = >pdev->dev;
struct clk_init_data init;
+   char clk_name[32];
+
+   snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(dev),
+name_suffix);
+
+   init.name = clk_name;
+   init.ops = ops;
+   init.flags = CLK_SET_RATE_PARENT;
+   init.parent_names = parent_names;
+   init.num_parents = num_parents;
+
+   hw->init = 
+
+   return devm_clk_register(dev, hw);
+}
+
+static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac *dwmac)
+{
int i, ret;
+   struct clk *clk;
struct device *dev = >pdev->dev;
-   char clk_name[32];
-   const char *clk_div_parents[1];
-   const char *mux_parent_names[MUX_CLK_NUM_PARENTS];
+   const char *parent_name, *mux_parent_names[MUX_CLK_NUM_PARENTS];
 
/* get the mux parents from DT */
for (i = 0; i < MUX_CLK_NUM_PARENTS; i++) {
char name[16];
 
snprintf(name, sizeof(name), "clkin%d", i);
-   dwmac->m250_mux_parent[i] = devm_clk_get(dev, name);
-   if (IS_ERR(dwmac->m250_mux_parent[i])) {
-   ret = PTR_ERR(dwmac->m250_mux_parent[i]);
+   clk = devm_clk_get(dev, name);
+   if (IS_ERR(clk)) {
+   ret = PTR_ERR(clk);
if (ret != -EPROBE_DEFER)
dev_err(dev, "Missing clock %s\n", name);
return ret;
}
 
-   mux_parent_names[i] =
-   __clk_get_name(dwmac->m250_mux_parent[i]);
+   mux_parent_names[i] = __clk_get_name(clk);
}
 
-   /* create the m250_mux */
-   snprintf(clk_name, sizeof(clk_name), "%s#m250_sel", dev_name(dev));
-   init.name = clk_name;
-   init.ops = _mux_ops;
-   init.flags = CLK_SET_RATE_PARENT;
-   init.parent_names = mux_parent_names;
-   init.num_parents = MUX_CLK_NUM_PARENTS;
-
dwmac->m250_mux.reg = dwmac->regs + PRG_ETH0;
dwmac->m250_mux.shift = PRG_ETH0_CLK_M250_SEL_SHIFT;
dwmac->m250_mux.mask = PRG_ETH0_CLK_M250_SEL_MASK;
-   dwmac->m250_mux.flags = 0;
-   dwmac->m250_mux.table = NULL;
-   dwmac->m250_mux.hw.init = 
-
-   dwmac->m250_mux_clk = devm_clk_register(dev, >m250_mux.hw);
-   if (WARN_ON(IS_ERR(dwmac->m250_mux_clk)))
-   return PTR_ERR(dwmac-

[net-next PATCH v1 3/3] net: stmmac: dwmac-meson8b: make the clock configurations private

2018-02-17 Thread Martin Blumenstingl
The common clock framework needs access to the "clock configuration"
structs during runtime.
However, only the common clock framework should access these. Ensure
this by moving the configuration structs out of struct meson8b_dwmac,
so only meson8b_init_rgmii_tx_clk() and the common clock framework know
about these configurations.

Suggested-by: Jerome Brunet <jbru...@baylibre.com>
Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c| 45 --
 1 file changed, 24 insertions(+), 21 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index 0dfce35c5583..2d5d4aea3bcb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -49,19 +49,17 @@
 
 struct meson8b_dwmac {
struct device   *dev;
-
void __iomem*regs;
-
phy_interface_t phy_mode;
+   struct clk  *rgmii_tx_clk;
+   u32 tx_delay_ns;
+};
 
+struct meson8b_dwmac_clk_configs {
struct clk_mux  m250_mux;
struct clk_divider  m250_div;
struct clk_fixed_factor fixed_div2;
struct clk_gate rgmii_tx_en;
-
-   struct clk  *rgmii_tx_clk;
-
-   u32 tx_delay_ns;
 };
 
 static void meson8b_dwmac_mask_bits(struct meson8b_dwmac *dwmac, u32 reg,
@@ -106,6 +104,11 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac 
*dwmac)
struct clk *clk;
struct device *dev = dwmac->dev;
const char *parent_name, *mux_parent_names[MUX_CLK_NUM_PARENTS];
+   struct meson8b_dwmac_clk_configs *clk_configs;
+
+   clk_configs = devm_kzalloc(dev, sizeof(*clk_configs), GFP_KERNEL);
+   if (!clk_configs)
+   return -ENOMEM;
 
/* get the mux parents from DT */
for (i = 0; i < MUX_CLK_NUM_PARENTS; i++) {
@@ -123,43 +126,43 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac 
*dwmac)
mux_parent_names[i] = __clk_get_name(clk);
}
 
-   dwmac->m250_mux.reg = dwmac->regs + PRG_ETH0;
-   dwmac->m250_mux.shift = PRG_ETH0_CLK_M250_SEL_SHIFT;
-   dwmac->m250_mux.mask = PRG_ETH0_CLK_M250_SEL_MASK;
+   clk_configs->m250_mux.reg = dwmac->regs + PRG_ETH0;
+   clk_configs->m250_mux.shift = PRG_ETH0_CLK_M250_SEL_SHIFT;
+   clk_configs->m250_mux.mask = PRG_ETH0_CLK_M250_SEL_MASK;
clk = meson8b_dwmac_register_clk(dwmac, "m250_sel", mux_parent_names,
 MUX_CLK_NUM_PARENTS, _mux_ops,
->m250_mux.hw);
+_configs->m250_mux.hw);
if (WARN_ON(IS_ERR(clk)))
return PTR_ERR(clk);
 
parent_name = __clk_get_name(clk);
-   dwmac->m250_div.reg = dwmac->regs + PRG_ETH0;
-   dwmac->m250_div.shift = PRG_ETH0_CLK_M250_DIV_SHIFT;
-   dwmac->m250_div.width = PRG_ETH0_CLK_M250_DIV_WIDTH;
-   dwmac->m250_div.flags = CLK_DIVIDER_ONE_BASED |
+   clk_configs->m250_div.reg = dwmac->regs + PRG_ETH0;
+   clk_configs->m250_div.shift = PRG_ETH0_CLK_M250_DIV_SHIFT;
+   clk_configs->m250_div.width = PRG_ETH0_CLK_M250_DIV_WIDTH;
+   clk_configs->m250_div.flags = CLK_DIVIDER_ONE_BASED |
CLK_DIVIDER_ALLOW_ZERO |
CLK_DIVIDER_ROUND_CLOSEST;
clk = meson8b_dwmac_register_clk(dwmac, "m250_div", _name, 1,
 _divider_ops,
->m250_div.hw);
+_configs->m250_div.hw);
if (WARN_ON(IS_ERR(clk)))
return PTR_ERR(clk);
 
parent_name = __clk_get_name(clk);
-   dwmac->fixed_div2.mult = 1;
-   dwmac->fixed_div2.div = 2;
+   clk_configs->fixed_div2.mult = 1;
+   clk_configs->fixed_div2.div = 2;
clk = meson8b_dwmac_register_clk(dwmac, "fixed_div2", _name, 1,
 _fixed_factor_ops,
->fixed_div2.hw);
+_configs->fixed_div2.hw);
if (WARN_ON(IS_ERR(clk)))
return PTR_ERR(clk);
 
parent_name = __clk_get_name(clk);
-   dwmac->rgmii_tx_en.reg = dwmac->regs + PRG_ETH0;
-   dwmac->rgmii_tx_en.bit_idx = PRG_ETH0_RGMII_TX_CLK_EN;
+   clk_configs->rgmii_tx_en.reg = dwmac->regs + PRG_ETH0;
+   clk_configs->rgmii_tx_en.bit_idx = PRG_ETH0_RGMII_TX_CLK_EN;
clk = meson8b_dwmac_register_clk(dwmac, "rgmii_tx_en", _name, 1,
   

[net-next PATCH v1 2/3] net: stmmac: dwmac-meson8b: only keep struct device around

2018-02-17 Thread Martin Blumenstingl
Nothing in the dwmac-meson8b driver (except .probe itself) requires the
platform_device anymore after .probe has finished. Replace it with a
pointer to struct device since this is what the functions inside the
driver are actually accessing.
No functional changes.

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 19 +--
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index 84a9a900e74e..0dfce35c5583 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -48,7 +48,7 @@
 #define MUX_CLK_NUM_PARENTS2
 
 struct meson8b_dwmac {
-   struct platform_device  *pdev;
+   struct device   *dev;
 
void __iomem*regs;
 
@@ -83,11 +83,10 @@ static struct clk *meson8b_dwmac_register_clk(struct 
meson8b_dwmac *dwmac,
  const struct clk_ops *ops,
  struct clk_hw *hw)
 {
-   struct device *dev = >pdev->dev;
struct clk_init_data init;
char clk_name[32];
 
-   snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(dev),
+   snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(dwmac->dev),
 name_suffix);
 
init.name = clk_name;
@@ -98,14 +97,14 @@ static struct clk *meson8b_dwmac_register_clk(struct 
meson8b_dwmac *dwmac,
 
hw->init = 
 
-   return devm_clk_register(dev, hw);
+   return devm_clk_register(dwmac->dev, hw);
 }
 
 static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac *dwmac)
 {
int i, ret;
struct clk *clk;
-   struct device *dev = >pdev->dev;
+   struct device *dev = dwmac->dev;
const char *parent_name, *mux_parent_names[MUX_CLK_NUM_PARENTS];
 
/* get the mux parents from DT */
@@ -204,19 +203,19 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac 
*dwmac)
 */
ret = clk_set_rate(dwmac->rgmii_tx_clk, 125 * 1000 * 1000);
if (ret) {
-   dev_err(>pdev->dev,
+   dev_err(dwmac->dev,
"failed to set RGMII TX clock\n");
return ret;
}
 
ret = clk_prepare_enable(dwmac->rgmii_tx_clk);
if (ret) {
-   dev_err(>pdev->dev,
+   dev_err(dwmac->dev,
"failed to enable the RGMII TX clock\n");
return ret;
}
 
-   devm_add_action_or_reset(>pdev->dev,
+   devm_add_action_or_reset(dwmac->dev,
(void(*)(void *))clk_disable_unprepare,
dwmac->rgmii_tx_clk);
break;
@@ -238,7 +237,7 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
break;
 
default:
-   dev_err(>pdev->dev, "unsupported phy-mode %s\n",
+   dev_err(dwmac->dev, "unsupported phy-mode %s\n",
phy_modes(dwmac->phy_mode));
return -EINVAL;
}
@@ -279,7 +278,7 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
goto err_remove_config_dt;
}
 
-   dwmac->pdev = pdev;
+   dwmac->dev = >dev;
dwmac->phy_mode = of_get_phy_mode(pdev->dev.of_node);
if (dwmac->phy_mode < 0) {
dev_err(>dev, "missing phy-mode property\n");
-- 
2.16.1



[net-next PATCH v1 0/3] dwmac-meson8b: small cleanup

2018-02-17 Thread Martin Blumenstingl
This is a follow-up to my previous series "dwmac-meson8b: clock fixes for
Meson8b" from [0].
during the review of that series it was found that the clock registration
could be simplified. now that the previous series has landed we can start
cleaning up the clock registration.

the goal of this series is to simplify the code in the dwmac-meson8b
driver. no functional changes are intended.

I have tested this on my Khadas VIM2 (GXM SoC, with RGMII PHY) and my
Endless Mini (EC-100, Meson8b SoC with RMII PHY, .dts support is not part
of mainline yet). no problems were found.


[0] http://lists.infradead.org/pipermail/linux-amlogic/2018-January/006143.html

Martin Blumenstingl (3):
  net: stmmac: dwmac-meson8b: simplify clock registration
  net: stmmac: dwmac-meson8b: only keep struct device around
  net: stmmac: dwmac-meson8b: make the clock configurations private

 .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c| 208 +
 1 file changed, 92 insertions(+), 116 deletions(-)

-- 
2.16.1



Re: [RFT net-next v4 3/5] net: stmmac: dwmac-meson8b: fix internal RGMII clock configuration

2018-01-18 Thread Martin Blumenstingl
On Tue, Jan 16, 2018 at 12:20 PM, Martin Blumenstingl
<martin.blumensti...@googlemail.com> wrote:
> On Sun, Jan 14, 2018 at 10:48 PM, Martin Blumenstingl
> <martin.blumensti...@googlemail.com> wrote:
>> Tests (using an oscilloscope and an Odroid-C1 board with a RTL8211F
>> RGMII PHY) have shown that the PRG_ETH0 register behaves as follows:
>> - bit 4 is a mux to choose between two parent clocks. according to the
>>   public S805 datasheet the only supported parent clock is MPLL2 (this
>>   was not verified using the oscilloscope).
>>   The public S805/S905 datasheet claims that this bit is reserved.
>> - bits 9:7 control a one-based divider (register value 1 means "divide
>>   by 1", etc.) for the input clock. we call this clock the "m250_div"
>>   clock because it's value is always supposed to be (close to) 250MHz
>>   (see below for an explanation).
>>   The description in the public S805/S905 datasheet is a bit cryptic,
>>   but it comes down to "input clock = 250MHz * value" (which could also
>>   be expressed as "250MHz = input clock / value")
>> - there seems to be an internal fixed divide-by-2 clock which takes the
>>   output from the m250_div and divides it by 2. This is not unusual on
>>   Amlogic SoCs, since the SDIO (MMC) driver also uses an internal fixed
>>   divide-by-2 clock.
>>   This is not documented in the public S805/S905 datasheet
>> - bit 10 controls a gate clock which enables or disables the RGMII TX
>>   clock (which is an output on the MAC/SoC and an input in the PHY). we
>>   call this the "rgmii_tx_en" clock. if this bit is set to "0" the RGMII
>>   TX clock output is close to 0
>>   The description for this bit in the public S805/S905 datasheet is
>>   "Generate 25MHz clock for PHY". Based on these tests it's believed
>>   that this is wrong, and should probably read "Generate the 125MHz
>>   RGMII TX clock for the PHY"
>> - the RGMII TX clock has to be set to 125MHz - the IP block adjusts the
>>   output (automatically) depending on the line speed (RGMII specifies
>>   that Gbit connections use a 125MHz clock, 100Mbit/s connections use a
>>   25MHz clock and 10Mbit/s connections use a 2.5MHz clock. only Gbit and
>>   100Mbit/s were tested with an oscilloscope). Due to the requirement
>>   that this clock always has to be set to 125MHz and due to the fixed
>>   divide-by-2 parent clock this means that m250_div will always end up
>>   with a rate of (close to) 250MHz.
>> - bits 6:5 are the TX delay, which is also named "clock phase" in some
>>   of Amlogic's older GPL kernel sources.
>>
>> The PHY also has an XTAL_IN pin where a 25MHz clock has to be provided.
>> Tests with the oscilloscope have shown that this is routed to a crystal
>> right next to the RTL8211F PHY. The same seems to be true on the Khadas
>> VIM2 (which uses a GXM SoC) board - however the 25MHz crystal is on the
>> other side of the PCB there.
>>
>> This updates the clocks in the dwmac-meson8b driver by replacing the
>> "m25_div" with the "rgmii_tx_en" clock and additionally introducing a
>> fixed divide-by-2 clock between "m250_div" and "rgmii_tx_en".
>> Now we also need to set a frequency of 125MHz on the RGMII clock
>> (opposed to the 25MHz we set before, with that non-existing
>> divide-by-5-or-10 divider).
>>
>> Special thanks go to Linus Lüssing for testing the various bits and
>> checking the results with an oscilloscope on his Odroid-C1!
>>
>> Fixes: 566e8251625304 ("net: stmmac: add a glue driver for the Amlogic Meson 
>> 8b / GXBB DWMAC")
>> Reported-by: Emiliano Ingrassia <ingras...@epigenesys.com>
>> Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
> NACK-ed by: Yixun Lan <yixun@amlogic.com>
>
> as it breaks the AXG SoCs (maybe not even directly related to this
> patch, but we're currently not sure if m250_mux is defined correctly)
> see: [0]
for the record (as this series is now merged): it turned out that the
breakage (of this series) on the AXG SoC is a side-effect of at least
two problems in the clock controller driver - these should be fixed
with: [0]

>> ---
>>  .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c| 79 
>> +-
>>  1 file changed, 47 insertions(+), 32 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
>> b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
>> index 670f344f7168..e9fec9e0425c 100644
>> --- a/driv

Re: [PATCH net-next v5 0/4] dwmac-meson8b: clock fixes for Meson8b

2018-01-18 Thread Martin Blumenstingl
Hi Yixun,

On Thu, Jan 18, 2018 at 11:27 AM, Yixun Lan <yixun@amlogic.com> wrote:
> HI Jerome
>
> On 01/17/18 01:19, Jerome Brunet wrote:
>> On Tue, 2018-01-16 at 12:17 +0100, Martin Blumenstingl wrote:
>>>>> Hi Martin
>>>>>
>>>>>   I'm having problem with this series applied.
>>>>> I've tested on the A113D (AXG) platform, if this patch is applied, the
>>>>> driver will choose MPLL2 as clk source, and seems it doesn't work out
>>>>> with this clk (fail to get IP)
>>>>>
>>>>> grep mpll2 /sys/kernel/debug/clk/clk_summary
>>>>> mpll2  11   24449
>>>>>   0 0
>>>>>
>>>>
>>>> This is because the fixed pll is 199200 on the axg instead of 2Ghz.
>>>
>>> is there a chance that we can have a public AXG datasheet, similar to
>>> what Hardkernel and Khadas published for the S805, S905, S905X and
>>> S912?
>>> this would give us community developers a chance to know that we are
>>> going to break something on AXG *before* a patch is published (like in
>>> this case :( )
>>>
>>>> As a consequence fdiv4 is 49800.
>>
>> Quick update
>> I have just been able measure fdiv4 and it is exactly 500Mhz
>> This means the the fixed_pll is actually 2GHz, as we would expect.
>>
> yes, you right here. the output of fixed pll is actually 2GHz (1999.998MHz)
>
>
>> This also means that calculation of the fixed_pll is slightly off on the axg
>> platform.
>>
> the calculation algorithm should be updated because previous one didn't
> take the 'frac' part into account.
>
>
>> Once the clock calculation is done correctly on axg, there should be no 
>> problem.
>>
> there is still a problem, current calculation will still result at
> fixed_pll frequency - 1999,000,000, I would expect it 2000,000,000 (to
> round it to closest? or just 1999,998,000)
if I understand Jerome's "clk: meson: pll fixes" [0] series correctly
then this should result in a fixed_pll frequency of 1999.998MHz as it
addresses the fractional part as well as the issue where all bits
lower than 1MHz were set to 0

>
>>>>
>>>> CCF can reach something closer to 250Mhz with the mpll2.
>>>>
>>>> The easy way to fix this would be to make the inputs of ethernet mux 
>>>> optional
>>>> and not provide the MPLL2 on the axg.
>>>>
>>>> However, this raises a few question on the axg platform :
>>>> 1) Why is the root pll 1992Mhz and not 2GHz ? seems a weird choice just 
>>>> for 4MHz
>>>> This 1992Mhz does not seems to help generate audio freqs anymore than 2GHz
>>>> would. I don't really get this choice. Could you help us understand Yixun ?
>>>>
>>>> 2) Why is ethernet not working with mpll2 on axg ? espcially since we have
>>>> proven the rate be correct on meson8 ... is there any change on this 
>>>> platform we
>>>> don't know about ?
>>>
>>> I tried to force my Khadas VIM2 (GXM) into using MPLL2 by changing
>>> meson-gxl.dtsi:
>>> clocks = < CLKID_ETH>,
>>> -< CLKID_FCLK_DIV2>,
>>> +<>,
>>> < CLKID_MPLL2>;
>>>
>>> the resulting clock tree looks fine:
>>> fixed_pll 440  20
>>> 0 0
>>>   mpll2_div  110   25000
>>>0 0
>>>  mpll2   110   25000
>>>0 0
>>> c941.ethernet#m250_sel   110
>>> 25000  0 0
>>>c941.ethernet#m250_div   110
>>> 25000  0 0
>>>   c941.ethernet#fixed_div2   11
>>> 0   12500  0 0
>>>  c941.ethernet#rgmii_tx_en   11
>>> 0   12500  0 0
>>>
>>> however, Ethernet is broken (I can't ping anything)
>>>
>>> @Yixun: according to all public datasheets bit 4 is reserved
>>> however, Mike and Kevin were told that bit 4 controls a mux between
>>> FCLK_DIV2 and MPLL2
>>> could you please clarify the meaning of this bit 4 on:
>>> - Meson8b
>>> - Meson8m2 (a confirmation that it uses the same Ethernet

Re: [RFT net-next v4 3/5] net: stmmac: dwmac-meson8b: fix internal RGMII clock configuration

2018-01-16 Thread Martin Blumenstingl
On Sun, Jan 14, 2018 at 10:48 PM, Martin Blumenstingl
<martin.blumensti...@googlemail.com> wrote:
> Tests (using an oscilloscope and an Odroid-C1 board with a RTL8211F
> RGMII PHY) have shown that the PRG_ETH0 register behaves as follows:
> - bit 4 is a mux to choose between two parent clocks. according to the
>   public S805 datasheet the only supported parent clock is MPLL2 (this
>   was not verified using the oscilloscope).
>   The public S805/S905 datasheet claims that this bit is reserved.
> - bits 9:7 control a one-based divider (register value 1 means "divide
>   by 1", etc.) for the input clock. we call this clock the "m250_div"
>   clock because it's value is always supposed to be (close to) 250MHz
>   (see below for an explanation).
>   The description in the public S805/S905 datasheet is a bit cryptic,
>   but it comes down to "input clock = 250MHz * value" (which could also
>   be expressed as "250MHz = input clock / value")
> - there seems to be an internal fixed divide-by-2 clock which takes the
>   output from the m250_div and divides it by 2. This is not unusual on
>   Amlogic SoCs, since the SDIO (MMC) driver also uses an internal fixed
>   divide-by-2 clock.
>   This is not documented in the public S805/S905 datasheet
> - bit 10 controls a gate clock which enables or disables the RGMII TX
>   clock (which is an output on the MAC/SoC and an input in the PHY). we
>   call this the "rgmii_tx_en" clock. if this bit is set to "0" the RGMII
>   TX clock output is close to 0
>   The description for this bit in the public S805/S905 datasheet is
>   "Generate 25MHz clock for PHY". Based on these tests it's believed
>   that this is wrong, and should probably read "Generate the 125MHz
>   RGMII TX clock for the PHY"
> - the RGMII TX clock has to be set to 125MHz - the IP block adjusts the
>   output (automatically) depending on the line speed (RGMII specifies
>   that Gbit connections use a 125MHz clock, 100Mbit/s connections use a
>   25MHz clock and 10Mbit/s connections use a 2.5MHz clock. only Gbit and
>   100Mbit/s were tested with an oscilloscope). Due to the requirement
>   that this clock always has to be set to 125MHz and due to the fixed
>   divide-by-2 parent clock this means that m250_div will always end up
>   with a rate of (close to) 250MHz.
> - bits 6:5 are the TX delay, which is also named "clock phase" in some
>   of Amlogic's older GPL kernel sources.
>
> The PHY also has an XTAL_IN pin where a 25MHz clock has to be provided.
> Tests with the oscilloscope have shown that this is routed to a crystal
> right next to the RTL8211F PHY. The same seems to be true on the Khadas
> VIM2 (which uses a GXM SoC) board - however the 25MHz crystal is on the
> other side of the PCB there.
>
> This updates the clocks in the dwmac-meson8b driver by replacing the
> "m25_div" with the "rgmii_tx_en" clock and additionally introducing a
> fixed divide-by-2 clock between "m250_div" and "rgmii_tx_en".
> Now we also need to set a frequency of 125MHz on the RGMII clock
> (opposed to the 25MHz we set before, with that non-existing
> divide-by-5-or-10 divider).
>
> Special thanks go to Linus Lüssing for testing the various bits and
> checking the results with an oscilloscope on his Odroid-C1!
>
> Fixes: 566e8251625304 ("net: stmmac: add a glue driver for the Amlogic Meson 
> 8b / GXBB DWMAC")
> Reported-by: Emiliano Ingrassia <ingras...@epigenesys.com>
> Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
NACK-ed by: Yixun Lan <yixun@amlogic.com>

as it breaks the AXG SoCs (maybe not even directly related to this
patch, but we're currently not sure if m250_mux is defined correctly)
see: [0]

> ---
>  .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c| 79 
> +-
>  1 file changed, 47 insertions(+), 32 deletions(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
> b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
> index 670f344f7168..e9fec9e0425c 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
> @@ -40,9 +40,7 @@
>  #define PRG_ETH0_CLK_M250_DIV_SHIFT7
>  #define PRG_ETH0_CLK_M250_DIV_WIDTH3
>
> -/* divides the result of m25_sel by either 5 (bit unset) or 10 (bit set) */
> -#define PRG_ETH0_CLK_M25_DIV_SHIFT 10
> -#define PRG_ETH0_CLK_M25_DIV_WIDTH 1
> +#define PRG_ETH0_RGMII_TX_CLK_EN   10
>
>  #define PRG_ETH0_INVERTED_RMII_CLK BIT(11)
>  #define PRG_ETH0_TX_AND_PHY_REF_CLKBIT(12)
> @@ -63,8 +61,11 @@ struct meson8b_dwmac {

Re: [PATCH net-next v5 0/4] dwmac-meson8b: clock fixes for Meson8b

2018-01-16 Thread Martin Blumenstingl
Hi Jerome, Hi Yixun,

On Tue, Jan 16, 2018 at 10:37 AM, Jerome Brunet <jbru...@baylibre.com> wrote:
> On Tue, 2018-01-16 at 16:25 +0800, Yixun Lan wrote:
>>
>> On 01/16/18 01:10, Martin Blumenstingl wrote:
>> > Hi Dave,
>> >
>> > this series is now successfully tested, thus we think it's ready to be
>> > applied to your net-next tree.
>> >
>> > Emiliano reported [0] that he couldn't get dwmac-meson8b to work on his
>> > Odroid-C1. This is the (hopefully) final version of this series, which
>> > was successfully tested.
>> >
>> > Due to the fact that the public S805/S905/S912 datasheets all seem to
>> > be outdated regarding the description of the PRG_ETH0 (also called
>> > PRG_ETHERNET_ADDR0) register Linus Lüssing offered to help testing with
>> > an oscilloscope and an Odroid-C1. I would like to say HUGE thanks to him
>> > at this point as he spent hours figuring out the effects of the bits
>> > that are (though to be) relevant to get Ethernet working on the
>> > Odroid-C1.
>> > We tested three scenarios, all based on version 3 of this series:
>> > 1) MPLL2 at ~500MHz, m250_div set to 1, bit 10 enabled
>> > this resulted in a clock rate twice as high as expected at the RGMII TX
>> > clock pin (250MHz instead of 125MHz for Gbit connections and 50MHz
>> > instead of 25MHz for 100Mbit/s connections). it did not change the
>> > rate at the XTAL_IN pin of PHY (which stayed consistenly at 25MHz)
>> > 2) MPLL2 at ~250MHz, m250_div set to 1, bit 10 disabled
>> > the oscilloscope shows "no clock" for the RGMII TX clock pin at it's
>> > highest resolution (and random rates at lower resolutions). XTAL_IN is
>> > still at 25MHz
>> > 3) MPLL2 at ~250MHz, m250_div set to 1, bit 10 enabled
>> > this resulted in a 125MHz signal at the RGMII TX clock pin for Gbit
>> > speeds and 25MHz for 100Mbit/s - both values are as expected. The rate
>> > on the XTAL_IN pin was at 25MHz
>> > -> boot-logs (with the PRG_ETH0 register value) and screenshots from the
>> > readings of the oscilloscope can be found at:
>> > https://metameute.de/~tux/linux/amlogic/odroidc1/ethernet/
>> >
>> > Version 4 of this series is based on the results from Linus Lüssing's
>> > help with the oscilloscope and Odroid-C1.
>> > Unfortunately I don't have any Meson8b boards with RGMII PHY so I could
>> > only partially test this. @Emiliano: Could you please give this version
>> > a try and let me know about the results (preferably with a "Tested-by"
>> > if it works)?
>> > You obviously still need your two "ARM: dts: meson8b" patches which
>> > - add the amlogic,meson8b-dwmac" compatible to meson8b.dtsi
>> > - enable Ethernet on the Odroid-C1 (according to your last thest a TX
>> >   delay of 4ns is required to make it work properly)
>> >
>> > When testing on Meson8b this also needs a fix for the MPLL clock driver:
>> > "clk: meson: mpll: use 64-bit maths in params_from_rate", see:
>> > https://patchwork.kernel.org/patch/10131677/
>> >
>> > I have tested this myself on a Khadas VIM (GXL SoC, internal RMII PHY)
>> > and a Khadas VIM2 (GXM SoC, external RGMII PHY). Both are still working
>> > fine (so let's hope that this also fixes your Meson8b issue :)).
>> >
>> > changes since v4 at [4]:
>> > - dropped "RFT" status since Jerome tested this series successfully!
>> > - dropped PATCH #2 ("simplify generating the clock names"). I will
>> >   improve the whole clock registration in a separate series. since that
>> >   patch didn't really improve anything I dropped it for now
>> > - added Jerome's Acked-/Reviewed-/Tested-by's - many thanks!
>> >
>> > changes since v3 at [3]:
>> > - renamed the function PATCH #1 from meson8b_init_rgmii_clk to
>> >   meson8b_init_rgmii_tx_clk since we now know what the register bits
>> >   mean
>> > - rewrote PATCH #3 because bit 10 is a gate clock and it seems that
>> >   there is an internal fixed divide-by-2 clock. see the patch
>> >   description for a detailed explanation
>> > - updated the description of PATCH #4 and #5 as the clock we're trying
>> >   to fix is the "RGMII TX" clock (old version stated that this is the
>> >   "RGMII clock" or "PHY reference clock"). also updated the numbers in
>> >   the description now that we have the clock hierarchy right (at least
&

[PATCH net-next v5 2/4] net: stmmac: dwmac-meson8b: fix internal RGMII clock configuration

2018-01-15 Thread Martin Blumenstingl
Tests (using an oscilloscope and an Odroid-C1 board with a RTL8211F
RGMII PHY) have shown that the PRG_ETH0 register behaves as follows:
- bit 4 is a mux to choose between two parent clocks. according to the
  public S805 datasheet the only supported parent clock is MPLL2 (this
  was not verified using the oscilloscope).
  The public S805/S905 datasheet claims that this bit is reserved.
- bits 9:7 control a one-based divider (register value 1 means "divide
  by 1", etc.) for the input clock. we call this clock the "m250_div"
  clock because it's value is always supposed to be (close to) 250MHz
  (see below for an explanation).
  The description in the public S805/S905 datasheet is a bit cryptic,
  but it comes down to "input clock = 250MHz * value" (which could also
  be expressed as "250MHz = input clock / value")
- there seems to be an internal fixed divide-by-2 clock which takes the
  output from the m250_div and divides it by 2. This is not unusual on
  Amlogic SoCs, since the SDIO (MMC) driver also uses an internal fixed
  divide-by-2 clock.
  This is not documented in the public S805/S905 datasheet
- bit 10 controls a gate clock which enables or disables the RGMII TX
  clock (which is an output on the MAC/SoC and an input in the PHY). we
  call this the "rgmii_tx_en" clock. if this bit is set to "0" the RGMII
  TX clock output is close to 0
  The description for this bit in the public S805/S905 datasheet is
  "Generate 25MHz clock for PHY". Based on these tests it's believed
  that this is wrong, and should probably read "Generate the 125MHz
  RGMII TX clock for the PHY"
- the RGMII TX clock has to be set to 125MHz - the IP block adjusts the
  output (automatically) depending on the line speed (RGMII specifies
  that Gbit connections use a 125MHz clock, 100Mbit/s connections use a
  25MHz clock and 10Mbit/s connections use a 2.5MHz clock. only Gbit and
  100Mbit/s were tested with an oscilloscope). Due to the requirement
  that this clock always has to be set to 125MHz and due to the fixed
  divide-by-2 parent clock this means that m250_div will always end up
  with a rate of (close to) 250MHz.
- bits 6:5 are the TX delay, which is also named "clock phase" in some
  of Amlogic's older GPL kernel sources.

The PHY also has an XTAL_IN pin where a 25MHz clock has to be provided.
Tests with the oscilloscope have shown that this is routed to a crystal
right next to the RTL8211F PHY. The same seems to be true on the Khadas
VIM2 (which uses a GXM SoC) board - however the 25MHz crystal is on the
other side of the PCB there.

This updates the clocks in the dwmac-meson8b driver by replacing the
"m25_div" with the "rgmii_tx_en" clock and additionally introducing a
fixed divide-by-2 clock between "m250_div" and "rgmii_tx_en".
Now we also need to set a frequency of 125MHz on the RGMII clock
(opposed to the 25MHz we set before, with that non-existing
divide-by-5-or-10 divider).

Special thanks go to Linus Lüssing for testing the various bits and
checking the results with an oscilloscope on his Odroid-C1!

Fixes: 566e8251625304 ("net: stmmac: add a glue driver for the Amlogic Meson 8b 
/ GXBB DWMAC")
Reported-by: Emiliano Ingrassia <ingras...@epigenesys.com>
Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
Acked-by: Jerome Brunet <jbru...@baylibre.com>
Tested-by: Jerome Brunet <jbru...@baylibre.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c| 79 +-
 1 file changed, 47 insertions(+), 32 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index c6f87e9c4ccb..7930a152dd63 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -40,9 +40,7 @@
 #define PRG_ETH0_CLK_M250_DIV_SHIFT7
 #define PRG_ETH0_CLK_M250_DIV_WIDTH3
 
-/* divides the result of m25_sel by either 5 (bit unset) or 10 (bit set) */
-#define PRG_ETH0_CLK_M25_DIV_SHIFT 10
-#define PRG_ETH0_CLK_M25_DIV_WIDTH 1
+#define PRG_ETH0_RGMII_TX_CLK_EN   10
 
 #define PRG_ETH0_INVERTED_RMII_CLK BIT(11)
 #define PRG_ETH0_TX_AND_PHY_REF_CLKBIT(12)
@@ -63,8 +61,11 @@ struct meson8b_dwmac {
struct clk_divider  m250_div;
struct clk  *m250_div_clk;
 
-   struct clk_divider  m25_div;
-   struct clk  *m25_div_clk;
+   struct clk_fixed_factor fixed_div2;
+   struct clk  *fixed_div2_clk;
+
+   struct clk_gate rgmii_tx_en;
+   struct clk  *rgmii_tx_en_clk;
 
u32 tx_delay_ns;
 };
@@ -89,11 +90,6 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac 
*dwmac)
char clk_name[32];
const char *clk_div_parents[1];
const char *mux

[PATCH net-next v5 1/4] net: stmmac: dwmac-meson8b: only configure the clocks in RGMII mode

2018-01-15 Thread Martin Blumenstingl
Neither the m25_div_clk nor the m250_div_clk or m250_mux_clk are used in
RMII mode. The m25_div_clk output is routed to the RGMII PHY's "RGMII
clock".
This means that we don't need to configure the clocks in RMII mode. The
driver however did this - with no effect since the clocks are not routed
to the PHY in RMII mode.

While here also rename meson8b_init_clk to meson8b_init_rgmii_tx_clk to
make it easier to understand the code.

Fixes: 566e8251625304 ("net: stmmac: add a glue driver for the Amlogic Meson 8b 
/ GXBB DWMAC")
Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
Tested-by: Jerome Brunet <jbru...@baylibre.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c| 46 ++
 1 file changed, 21 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index 4404650b32c5..c6f87e9c4ccb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -81,7 +81,7 @@ static void meson8b_dwmac_mask_bits(struct meson8b_dwmac 
*dwmac, u32 reg,
writel(data, dwmac->regs + reg);
 }
 
-static int meson8b_init_clk(struct meson8b_dwmac *dwmac)
+static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac *dwmac)
 {
struct clk_init_data init;
int i, ret;
@@ -176,7 +176,6 @@ static int meson8b_init_clk(struct meson8b_dwmac *dwmac)
 static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
 {
int ret;
-   unsigned long clk_rate;
u8 tx_dly_val = 0;
 
switch (dwmac->phy_mode) {
@@ -191,9 +190,6 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
 
case PHY_INTERFACE_MODE_RGMII_ID:
case PHY_INTERFACE_MODE_RGMII_TXID:
-   /* Generate a 25MHz clock for the PHY */
-   clk_rate = 25 * 1000 * 1000;
-
/* enable RGMII mode */
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_RGMII_MODE,
PRG_ETH0_RGMII_MODE);
@@ -204,12 +200,24 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac 
*dwmac)
 
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TXDLY_MASK,
tx_dly_val << PRG_ETH0_TXDLY_SHIFT);
+
+   ret = clk_prepare_enable(dwmac->m25_div_clk);
+   if (ret) {
+   dev_err(>pdev->dev, "failed to enable the PHY 
clock\n");
+   return ret;
+   }
+
+   /* Generate the 25MHz RGMII clock for the PHY */
+   ret = clk_set_rate(dwmac->m25_div_clk, 25 * 1000 * 1000);
+   if (ret) {
+   clk_disable_unprepare(dwmac->m25_div_clk);
+
+   dev_err(>pdev->dev, "failed to set PHY clock\n");
+   return ret;
+   }
break;
 
case PHY_INTERFACE_MODE_RMII:
-   /* Use the rate of the mux clock for the internal RMII PHY */
-   clk_rate = clk_get_rate(dwmac->m250_mux_clk);
-
/* disable RGMII mode -> enables RMII mode */
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_RGMII_MODE,
0);
@@ -231,20 +239,6 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac 
*dwmac)
return -EINVAL;
}
 
-   ret = clk_prepare_enable(dwmac->m25_div_clk);
-   if (ret) {
-   dev_err(>pdev->dev, "failed to enable the PHY clock\n");
-   return ret;
-   }
-
-   ret = clk_set_rate(dwmac->m25_div_clk, clk_rate);
-   if (ret) {
-   clk_disable_unprepare(dwmac->m25_div_clk);
-
-   dev_err(>pdev->dev, "failed to set PHY clock\n");
-   return ret;
-   }
-
/* enable TX_CLK and PHY_REF_CLK generator */
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TX_AND_PHY_REF_CLK,
PRG_ETH0_TX_AND_PHY_REF_CLK);
@@ -294,7 +288,7 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
 >tx_delay_ns))
dwmac->tx_delay_ns = 2;
 
-   ret = meson8b_init_clk(dwmac);
+   ret = meson8b_init_rgmii_tx_clk(dwmac);
if (ret)
goto err_remove_config_dt;
 
@@ -311,7 +305,8 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
return 0;
 
 err_clk_disable:
-   clk_disable_unprepare(dwmac->m25_div_clk);
+   if (phy_interface_mode_is_rgmii(dwmac->phy_mode))
+   clk_disable_unprepare(dwmac->m25_div_clk);
 err_remove_config_dt:
stmmac_remove_config_dt(pdev, plat_dat);
 
@@ -322,7 +317,8 @@ static int meson8b_dwmac_remove(struct platform_device 
*pdev)
 {
struct m

[PATCH net-next v5 3/4] net: stmmac: dwmac-meson8b: fix setting the RGMII TX clock on Meson8b

2018-01-15 Thread Martin Blumenstingl
Meson8b only supports MPLL2 as clock input. The rate of the MPLL2 clock
set by Odroid-C1's u-boot is close to (but not exactly) 500MHz. The
exact rate is 52394Hz, which is calculated in
drivers/clk/meson/clk-mpll.c using the following formula:
DIV_ROUND_UP_ULL((u64)parent_rate * SDM_DEN, (SDM_DEN * n2) + sdm)
Odroid-C1's u-boot configures MPLL2 with the following values:
- SDM_DEN = 16384
- SDM = 1638
- N2 = 5

The 250MHz clock (m250_div) inside dwmac-meson8b driver is derived from
the MPLL2 clock. Due to MPLL2 running slightly faster than 500MHz the
common clock framework chooses a divider which is too big to generate
the 250MHz clock (a divider of 2 would be needed, but this is rounded up
to a divider of 3). This breaks the RTL8211F RGMII PHY on Odroid-C1
because it requires a (close to) 125MHz RGMII TX clock (on Gbit speeds,
the IP block internally divides that down to 25MHz on 100Mbit/s
connections and 2.5MHz on 10Mbit/s connections - we don't need any
special configuration for that).

Round the divider to the closest value to prevent this issue on Meson8b.
This means we'll now end up with a clock rate for the RGMII TX clock of
125001197Hz (= 125MHz plus 1197Hz), which is close-enough to 125MHz.
This has no effect on the Meson GX SoCs since there fclk_div2 is used as
input clock, which has a rate of 1000MHz (and thus is divisible cleanly
to 250MHz and 125MHz).

Fixes: 566e8251625304 ("net: stmmac: add a glue driver for the Amlogic Meson 8b 
/ GXBB DWMAC")
Reported-by: Emiliano Ingrassia <ingras...@epigenesys.com>
Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
Reviewed-by: Jerome Brunet <jbru...@baylibre.com>
Tested-by: Jerome Brunet <jbru...@baylibre.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index 7930a152dd63..de01ce75a1b1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -140,7 +140,9 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac 
*dwmac)
dwmac->m250_div.shift = PRG_ETH0_CLK_M250_DIV_SHIFT;
dwmac->m250_div.width = PRG_ETH0_CLK_M250_DIV_WIDTH;
dwmac->m250_div.hw.init = 
-   dwmac->m250_div.flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO;
+   dwmac->m250_div.flags = CLK_DIVIDER_ONE_BASED |
+   CLK_DIVIDER_ALLOW_ZERO |
+   CLK_DIVIDER_ROUND_CLOSEST;
 
dwmac->m250_div_clk = devm_clk_register(dev, >m250_div.hw);
if (WARN_ON(IS_ERR(dwmac->m250_div_clk)))
-- 
2.15.1



[PATCH net-next v5 4/4] net: stmmac: dwmac-meson8b: propagate rate changes to the parent clock

2018-01-15 Thread Martin Blumenstingl
On Meson8b the only valid input clock is MPLL2. The bootloader
configures that to run at 52394Hz which cannot be divided evenly
down to 125MHz using the m250_div clock. Currently the common clock
framework chooses a m250_div of 2 - with the internal fixed
"divide by 10" this results in a RGMII TX clock of 125001197Hz (120Hz
above the requested 125MHz).

Letting the common clock framework propagate the rate changes up to the
parent of m250_mux allows us to get the best possible clock rate. With
this patch the common clock framework calculates a rate of
very-close-to-250MHz (24701Hz to be exact) for the MPLL2 clock
(which is the mux input). Dividing that by 2 (which is an internal,
fixed divider for the RGMII TX clock) gives us an RGMII TX clock of
124999850Hz (which is only 150Hz off the requested 125MHz, compared to
1197Hz based on the MPLL2 rate set by u-boot and the Amlogic GPL kernel
sources).

SoCs from the Meson GX series are not affected by this change because
the input clock is FCLK_DIV2 whose rate cannot be changed (which is fine
since it's running at 1GHz, so it's already a multiple of 250MHz and
125MHz).

Fixes: 566e8251625304 ("net: stmmac: add a glue driver for the Amlogic Meson 8b 
/ GXBB DWMAC")
Suggested-by: Jerome Brunet <jbru...@baylibre.com>
Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
Reviewed-by: Jerome Brunet <jbru...@baylibre.com>
Tested-by: Jerome Brunet <jbru...@baylibre.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index de01ce75a1b1..5270d26f0bc6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -112,7 +112,7 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac 
*dwmac)
snprintf(clk_name, sizeof(clk_name), "%s#m250_sel", dev_name(dev));
init.name = clk_name;
init.ops = _mux_ops;
-   init.flags = 0;
+   init.flags = CLK_SET_RATE_PARENT;
init.parent_names = mux_parent_names;
init.num_parents = MUX_CLK_NUM_PARENTS;
 
-- 
2.15.1



[PATCH net-next v5 0/4] dwmac-meson8b: clock fixes for Meson8b

2018-01-15 Thread Martin Blumenstingl
ut the RGMII clock
- added Jerome's Reviewed-by to PATCH #2 (formerly PATCH #1)
- replaced PATCH #3 (formerly PATCH #2) with one that sets
  CLK_SET_RATE_PARENT on the mux and thus re-configures the MPLL2 clock
  on Meson8b correctly


[0] http://lists.infradead.org/pipermail/linux-amlogic/2017-December/005596.html
[1] http://lists.infradead.org/pipermail/linux-amlogic/2017-December/005848.html
[2] http://lists.infradead.org/pipermail/linux-amlogic/2017-December/005861.html
[3] http://lists.infradead.org/pipermail/linux-amlogic/2017-December/005899.html
[4] http://lists.infradead.org/pipermail/linux-amlogic/2018-January/006125.html

Martin Blumenstingl (4):
  net: stmmac: dwmac-meson8b: only configure the clocks in RGMII mode
  net: stmmac: dwmac-meson8b: fix internal RGMII clock configuration
  net: stmmac: dwmac-meson8b: fix setting the RGMII TX clock on Meson8b
  net: stmmac: dwmac-meson8b: propagate rate changes to the parent clock

 .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c| 113 -
 1 file changed, 63 insertions(+), 50 deletions(-)

-- 
2.15.1



Re: [RFT net-next v4 3/5] net: stmmac: dwmac-meson8b: fix internal RGMII clock configuration

2018-01-15 Thread Martin Blumenstingl
Hi Jerome,

On Mon, Jan 15, 2018 at 12:49 PM, Jerome Brunet <jbru...@baylibre.com> wrote:
> On Sun, 2018-01-14 at 22:48 +0100, Martin Blumenstingl wrote:
>> Tests (using an oscilloscope and an Odroid-C1 board with a RTL8211F
>> RGMII PHY) have shown that the PRG_ETH0 register behaves as follows:
>> - bit 4 is a mux to choose between two parent clocks. according to the
>>   public S805 datasheet the only supported parent clock is MPLL2 (this
>>   was not verified using the oscilloscope).
>>   The public S805/S905 datasheet claims that this bit is reserved.
>> - bits 9:7 control a one-based divider (register value 1 means "divide
>>   by 1", etc.) for the input clock. we call this clock the "m250_div"
>>   clock because it's value is always supposed to be (close to) 250MHz
>>   (see below for an explanation).
>>   The description in the public S805/S905 datasheet is a bit cryptic,
>>   but it comes down to "input clock = 250MHz * value" (which could also
>>   be expressed as "250MHz = input clock / value")
>> - there seems to be an internal fixed divide-by-2 clock which takes the
>>   output from the m250_div and divides it by 2. This is not unusual on
>>   Amlogic SoCs, since the SDIO (MMC) driver also uses an internal fixed
>>   divide-by-2 clock.
>>   This is not documented in the public S805/S905 datasheet
>> - bit 10 controls a gate clock which enables or disables the RGMII TX
>>   clock (which is an output on the MAC/SoC and an input in the PHY). we
>>   call this the "rgmii_tx_en" clock. if this bit is set to "0" the RGMII
>>   TX clock output is close to 0
>>   The description for this bit in the public S805/S905 datasheet is
>>   "Generate 25MHz clock for PHY". Based on these tests it's believed
>>   that this is wrong, and should probably read "Generate the 125MHz
>>   RGMII TX clock for the PHY"
>> - the RGMII TX clock has to be set to 125MHz - the IP block adjusts the
>>   output (automatically) depending on the line speed (RGMII specifies
>>   that Gbit connections use a 125MHz clock, 100Mbit/s connections use a
>>   25MHz clock and 10Mbit/s connections use a 2.5MHz clock. only Gbit and
>>   100Mbit/s were tested with an oscilloscope). Due to the requirement
>>   that this clock always has to be set to 125MHz and due to the fixed
>>   divide-by-2 parent clock this means that m250_div will always end up
>>   with a rate of (close to) 250MHz.
>> - bits 6:5 are the TX delay, which is also named "clock phase" in some
>>   of Amlogic's older GPL kernel sources.
>>
>> The PHY also has an XTAL_IN pin where a 25MHz clock has to be provided.
>> Tests with the oscilloscope have shown that this is routed to a crystal
>> right next to the RTL8211F PHY. The same seems to be true on the Khadas
>> VIM2 (which uses a GXM SoC) board - however the 25MHz crystal is on the
>> other side of the PCB there.
>>
>> This updates the clocks in the dwmac-meson8b driver by replacing the
>> "m25_div" with the "rgmii_tx_en" clock and additionally introducing a
>> fixed divide-by-2 clock between "m250_div" and "rgmii_tx_en".
>> Now we also need to set a frequency of 125MHz on the RGMII clock
>> (opposed to the 25MHz we set before, with that non-existing
>> divide-by-5-or-10 divider).
>>
>> Special thanks go to Linus Lüssing for testing the various bits and
>> checking the results with an oscilloscope on his Odroid-C1!
>>
>> Fixes: 566e8251625304 ("net: stmmac: add a glue driver for the Amlogic Meson 
>> 8b / GXBB DWMAC")
>> Reported-by: Emiliano Ingrassia <ingras...@epigenesys.com>
>> Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
>
> Looks Good
> Acked-by: Jerome Brunet <jbru...@baylibre.com>
thank you!

> Not related to this particular change but we still need to re-factor the clock
> registration of this driver. We carry a lot of useless pointers in our private
> data. I guess this is something for another day.
can you share your thoughts how to do this?
I can devm_kzalloc the memory for struct clk_mux, clk_divider and
clk_fixed_factor in the function which registers these clocks. but I
cannot declare them on the stack, because the clk-* implementations
still need it during runtime
this would leave us with only the struct clk instances in meson8_dwmac


Regards
Martin


Re: [RFT net-next v4 1/5] net: stmmac: dwmac-meson8b: only configure the clocks in RGMII mode

2018-01-15 Thread Martin Blumenstingl
Hi Jerome,

On Mon, Jan 15, 2018 at 12:46 PM, Jerome Brunet <jbru...@baylibre.com> wrote:
> On Sun, 2018-01-14 at 22:48 +0100, Martin Blumenstingl wrote:
>>
>
> [...]
>
>> @@ -204,12 +200,24 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac 
>> *dwmac)
>>
>>   meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TXDLY_MASK,
>>   tx_dly_val << PRG_ETH0_TXDLY_SHIFT);
>> +
>> + ret = clk_prepare_enable(dwmac->m25_div_clk);
>> + if (ret) {
>> + dev_err(>pdev->dev, "failed to enable the PHY 
>> clock\n");
>> + return ret;
>> + }
>> +
>> + /* Generate the 25MHz RGMII clock for the PHY */
>> + ret = clk_set_rate(dwmac->m25_div_clk, 25 * 1000 * 1000);
>> + if (ret) {
>> + clk_disable_unprepare(dwmac->m25_div_clk);
>> +
>> + dev_err(>pdev->dev, "failed to set PHY 
>> clock\n");
>> + return ret;
>> + }
>>   break;
>>
>>   case PHY_INTERFACE_MODE_RMII:
>> - /* Use the rate of the mux clock for the internal RMII PHY */
>> - clk_rate = clk_get_rate(dwmac->m250_mux_clk);
>> -
>>   /* disable RGMII mode -> enables RMII mode */
>>   meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_RGMII_MODE,
>>   0);
>> @@ -231,20 +239,6 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac 
>> *dwmac)
>>   return -EINVAL;
>>   }
>>
>> - ret = clk_prepare_enable(dwmac->m25_div_clk);
>> - if (ret) {
>> - dev_err(>pdev->dev, "failed to enable the PHY clock\n");
>> - return ret;
>> - }
>> -
>> - ret = clk_set_rate(dwmac->m25_div_clk, clk_rate);
>> - if (ret) {
>> - clk_disable_unprepare(dwmac->m25_div_clk);
>> -
>> - dev_err(>pdev->dev, "failed to set PHY clock\n");
>> - return ret;
>> - }
>> -
>
> I would set the rate first then enable. Less chances of glitches and no need 
> to
> call clk_disable_unprepare if it fails
I did swap the calls in PATCH #3 of this series
with this patch I wanted to make sure that all of the current logic is
only executed in RGMII mode

>>   /* enable TX_CLK and PHY_REF_CLK generator */
>>   meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TX_AND_PHY_REF_CLK,
>>   PRG_ETH0_TX_AND_PHY_REF_CLK);
>> @@ -294,7 +288,7 @@ static int meson8b_dwmac_probe(struct platform_device 
>> *pdev)
>>>tx_delay_ns))
>>   dwmac->tx_delay_ns = 2;
>>
>> - ret = meson8b_init_clk(dwmac);
>> + ret = meson8b_init_rgmii_tx_clk(dwmac);
>>   if (ret)
>>   goto err_remove_config_dt;
>>
>> @@ -311,7 +305,8 @@ static int meson8b_dwmac_probe(struct platform_device 
>> *pdev)
>>   return 0;
>>
>>  err_clk_disable:
>> - clk_disable_unprepare(dwmac->m25_div_clk);
>> + if (phy_interface_mode_is_rgmii(dwmac->phy_mode))
>> + clk_disable_unprepare(dwmac->m25_div_clk);
>>  err_remove_config_dt:
>>   stmmac_remove_config_dt(pdev, plat_dat);
>>
>> @@ -322,7 +317,8 @@ static int meson8b_dwmac_remove(struct platform_device 
>> *pdev)
>>  {
>>   struct meson8b_dwmac *dwmac = get_stmmac_bsp_priv(>dev);
>>
>> - clk_disable_unprepare(dwmac->m25_div_clk);
>> + if (phy_interface_mode_is_rgmii(dwmac->phy_mode))
>> + clk_disable_unprepare(dwmac->m25_div_clk);
>
> if you use
> devm_add_action_or_reset(dev, (void(*)(void *))clk_disable_unprepare,
> YOUR-CLK)
>
> after enabling the clock, your can discard these conditional hunks.
noted, I'll also make this part of the clock cleanup series

>>
>>   return stmmac_pltfr_remove(pdev);
>>  }
>


Re: [RFT net-next v4 2/5] net: stmmac: dwmac-meson8b: simplify generating the clock names

2018-01-15 Thread Martin Blumenstingl
Hi Jerome,

On Mon, Jan 15, 2018 at 12:46 PM, Jerome Brunet <jbru...@baylibre.com> wrote:
> On Sun, 2018-01-14 at 22:48 +0100, Martin Blumenstingl wrote:
>> Instead of using a custom buffer, snprintf() and devm_kstrdup() we can
>> simplify this by using devm_kasprintf().
>> No functional changes - this just makes the code shorter.
>
> CCF copies the name from the init_data to its own structures, so the init_data
> are useless after the register.
>
> Here you'd allocate memory for each string which will remain until the driver
> unload. It's not much, but still, it is wasted memory.
good catch, thank you!
maybe I should drop this patch for now and clean up the clock
registration in another series - I can try to get rid of the
"unneeded" members in struct meson8b_dwmac in a new patch. what do you
think?

>>
>> Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
>> ---
>>  drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 13 ++---
>>  1 file changed, 6 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
>> b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
>> index c6f87e9c4ccb..670f344f7168 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
>> @@ -86,7 +86,6 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac 
>> *dwmac)
>>   struct clk_init_data init;
>>   int i, ret;
>>   struct device *dev = >pdev->dev;
>> - char clk_name[32];
>>   const char *clk_div_parents[1];
>>   const char *mux_parent_names[MUX_CLK_NUM_PARENTS];
>>   static const struct clk_div_table clk_25m_div_table[] = {
>> @@ -113,8 +112,8 @@ static int meson8b_init_rgmii_tx_clk(struct 
>> meson8b_dwmac *dwmac)
>>   }
>>
>>   /* create the m250_mux */
>> - snprintf(clk_name, sizeof(clk_name), "%s#m250_sel", dev_name(dev));
>> - init.name = clk_name;
>> + init.name = devm_kasprintf(dev, GFP_KERNEL, "%s#m250_sel",
>> +dev_name(dev));
>>   init.ops = _mux_ops;
>>   init.flags = 0;
>>   init.parent_names = mux_parent_names;
>> @@ -132,8 +131,8 @@ static int meson8b_init_rgmii_tx_clk(struct 
>> meson8b_dwmac *dwmac)
>>   return PTR_ERR(dwmac->m250_mux_clk);
>>
>>   /* create the m250_div */
>> - snprintf(clk_name, sizeof(clk_name), "%s#m250_div", dev_name(dev));
>> - init.name = devm_kstrdup(dev, clk_name, GFP_KERNEL);
>> + init.name = devm_kasprintf(dev, GFP_KERNEL, "%s#m250_div",
>> +dev_name(dev));
>>   init.ops = _divider_ops;
>>   init.flags = CLK_SET_RATE_PARENT;
>>   clk_div_parents[0] = __clk_get_name(dwmac->m250_mux_clk);
>> @@ -151,8 +150,8 @@ static int meson8b_init_rgmii_tx_clk(struct 
>> meson8b_dwmac *dwmac)
>>   return PTR_ERR(dwmac->m250_div_clk);
>>
>>   /* create the m25_div */
>> - snprintf(clk_name, sizeof(clk_name), "%s#m25_div", dev_name(dev));
>> - init.name = devm_kstrdup(dev, clk_name, GFP_KERNEL);
>> + init.name = devm_kasprintf(dev, GFP_KERNEL, "%s#m25_div",
>> +dev_name(dev));
>>   init.ops = _divider_ops;
>>   init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT;
>>   clk_div_parents[0] = __clk_get_name(dwmac->m250_div_clk);
>


[RFT net-next v4 1/5] net: stmmac: dwmac-meson8b: only configure the clocks in RGMII mode

2018-01-14 Thread Martin Blumenstingl
Neither the m25_div_clk nor the m250_div_clk or m250_mux_clk are used in
RMII mode. The m25_div_clk output is routed to the RGMII PHY's "RGMII
clock".
This means that we don't need to configure the clocks in RMII mode. The
driver however did this - with no effect since the clocks are not routed
to the PHY in RMII mode.

While here also rename meson8b_init_clk to meson8b_init_rgmii_tx_clk to
make it easier to understand the code.

Fixes: 566e8251625304 ("net: stmmac: add a glue driver for the Amlogic Meson 8b 
/ GXBB DWMAC")
Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c| 46 ++
 1 file changed, 21 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index 4404650b32c5..c6f87e9c4ccb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -81,7 +81,7 @@ static void meson8b_dwmac_mask_bits(struct meson8b_dwmac 
*dwmac, u32 reg,
writel(data, dwmac->regs + reg);
 }
 
-static int meson8b_init_clk(struct meson8b_dwmac *dwmac)
+static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac *dwmac)
 {
struct clk_init_data init;
int i, ret;
@@ -176,7 +176,6 @@ static int meson8b_init_clk(struct meson8b_dwmac *dwmac)
 static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
 {
int ret;
-   unsigned long clk_rate;
u8 tx_dly_val = 0;
 
switch (dwmac->phy_mode) {
@@ -191,9 +190,6 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
 
case PHY_INTERFACE_MODE_RGMII_ID:
case PHY_INTERFACE_MODE_RGMII_TXID:
-   /* Generate a 25MHz clock for the PHY */
-   clk_rate = 25 * 1000 * 1000;
-
/* enable RGMII mode */
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_RGMII_MODE,
PRG_ETH0_RGMII_MODE);
@@ -204,12 +200,24 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac 
*dwmac)
 
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TXDLY_MASK,
tx_dly_val << PRG_ETH0_TXDLY_SHIFT);
+
+   ret = clk_prepare_enable(dwmac->m25_div_clk);
+   if (ret) {
+   dev_err(>pdev->dev, "failed to enable the PHY 
clock\n");
+   return ret;
+   }
+
+   /* Generate the 25MHz RGMII clock for the PHY */
+   ret = clk_set_rate(dwmac->m25_div_clk, 25 * 1000 * 1000);
+   if (ret) {
+   clk_disable_unprepare(dwmac->m25_div_clk);
+
+   dev_err(>pdev->dev, "failed to set PHY clock\n");
+   return ret;
+   }
break;
 
case PHY_INTERFACE_MODE_RMII:
-   /* Use the rate of the mux clock for the internal RMII PHY */
-   clk_rate = clk_get_rate(dwmac->m250_mux_clk);
-
/* disable RGMII mode -> enables RMII mode */
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_RGMII_MODE,
0);
@@ -231,20 +239,6 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac 
*dwmac)
return -EINVAL;
}
 
-   ret = clk_prepare_enable(dwmac->m25_div_clk);
-   if (ret) {
-   dev_err(>pdev->dev, "failed to enable the PHY clock\n");
-   return ret;
-   }
-
-   ret = clk_set_rate(dwmac->m25_div_clk, clk_rate);
-   if (ret) {
-   clk_disable_unprepare(dwmac->m25_div_clk);
-
-   dev_err(>pdev->dev, "failed to set PHY clock\n");
-   return ret;
-   }
-
/* enable TX_CLK and PHY_REF_CLK generator */
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TX_AND_PHY_REF_CLK,
PRG_ETH0_TX_AND_PHY_REF_CLK);
@@ -294,7 +288,7 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
 >tx_delay_ns))
dwmac->tx_delay_ns = 2;
 
-   ret = meson8b_init_clk(dwmac);
+   ret = meson8b_init_rgmii_tx_clk(dwmac);
if (ret)
goto err_remove_config_dt;
 
@@ -311,7 +305,8 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
return 0;
 
 err_clk_disable:
-   clk_disable_unprepare(dwmac->m25_div_clk);
+   if (phy_interface_mode_is_rgmii(dwmac->phy_mode))
+   clk_disable_unprepare(dwmac->m25_div_clk);
 err_remove_config_dt:
stmmac_remove_config_dt(pdev, plat_dat);
 
@@ -322,7 +317,8 @@ static int meson8b_dwmac_remove(struct platform_device 
*pdev)
 {
struct meson8b_dwmac *dwmac = get_stmmac_bsp_priv(>dev);
 
- 

[RFT net-next v4 2/5] net: stmmac: dwmac-meson8b: simplify generating the clock names

2018-01-14 Thread Martin Blumenstingl
Instead of using a custom buffer, snprintf() and devm_kstrdup() we can
simplify this by using devm_kasprintf().
No functional changes - this just makes the code shorter.

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index c6f87e9c4ccb..670f344f7168 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -86,7 +86,6 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac 
*dwmac)
struct clk_init_data init;
int i, ret;
struct device *dev = >pdev->dev;
-   char clk_name[32];
const char *clk_div_parents[1];
const char *mux_parent_names[MUX_CLK_NUM_PARENTS];
static const struct clk_div_table clk_25m_div_table[] = {
@@ -113,8 +112,8 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac 
*dwmac)
}
 
/* create the m250_mux */
-   snprintf(clk_name, sizeof(clk_name), "%s#m250_sel", dev_name(dev));
-   init.name = clk_name;
+   init.name = devm_kasprintf(dev, GFP_KERNEL, "%s#m250_sel",
+  dev_name(dev));
init.ops = _mux_ops;
init.flags = 0;
init.parent_names = mux_parent_names;
@@ -132,8 +131,8 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac 
*dwmac)
return PTR_ERR(dwmac->m250_mux_clk);
 
/* create the m250_div */
-   snprintf(clk_name, sizeof(clk_name), "%s#m250_div", dev_name(dev));
-   init.name = devm_kstrdup(dev, clk_name, GFP_KERNEL);
+   init.name = devm_kasprintf(dev, GFP_KERNEL, "%s#m250_div",
+  dev_name(dev));
init.ops = _divider_ops;
init.flags = CLK_SET_RATE_PARENT;
clk_div_parents[0] = __clk_get_name(dwmac->m250_mux_clk);
@@ -151,8 +150,8 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac 
*dwmac)
return PTR_ERR(dwmac->m250_div_clk);
 
/* create the m25_div */
-   snprintf(clk_name, sizeof(clk_name), "%s#m25_div", dev_name(dev));
-   init.name = devm_kstrdup(dev, clk_name, GFP_KERNEL);
+   init.name = devm_kasprintf(dev, GFP_KERNEL, "%s#m25_div",
+  dev_name(dev));
init.ops = _divider_ops;
init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT;
clk_div_parents[0] = __clk_get_name(dwmac->m250_div_clk);
-- 
2.15.1



[RFT net-next v4 4/5] net: stmmac: dwmac-meson8b: fix setting the RGMII TX clock on Meson8b

2018-01-14 Thread Martin Blumenstingl
Meson8b only supports MPLL2 as clock input. The rate of the MPLL2 clock
set by Odroid-C1's u-boot is close to (but not exactly) 500MHz. The
exact rate is 52394Hz, which is calculated in
drivers/clk/meson/clk-mpll.c using the following formula:
DIV_ROUND_UP_ULL((u64)parent_rate * SDM_DEN, (SDM_DEN * n2) + sdm)
Odroid-C1's u-boot configures MPLL2 with the following values:
- SDM_DEN = 16384
- SDM = 1638
- N2 = 5

The 250MHz clock (m250_div) inside dwmac-meson8b driver is derived from
the MPLL2 clock. Due to MPLL2 running slightly faster than 500MHz the
common clock framework chooses a divider which is too big to generate
the 250MHz clock (a divider of 2 would be needed, but this is rounded up
to a divider of 3). This breaks the RTL8211F RGMII PHY on Odroid-C1
because it requires a (close to) 125MHz RGMII TX clock (on Gbit speeds,
the IP block internally divides that down to 25MHz on 100Mbit/s
connections and 2.5MHz on 10Mbit/s connections - we don't need any
special configuration for that).

Round the divider to the closest value to prevent this issue on Meson8b.
This means we'll now end up with a clock rate for the RGMII TX clock of
125001197Hz (= 125MHz plus 1197Hz), which is close-enough to 125MHz.
This has no effect on the Meson GX SoCs since there fclk_div2 is used as
input clock, which has a rate of 1000MHz (and thus is divisible cleanly
to 250MHz and 125MHz).

Fixes: 566e8251625304 ("net: stmmac: add a glue driver for the Amlogic Meson 8b 
/ GXBB DWMAC")
Reported-by: Emiliano Ingrassia <ingras...@epigenesys.com>
Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
Reviewed-by: Jerome Brunet <jbru...@baylibre.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index e9fec9e0425c..e30ad05d6a6e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -139,7 +139,9 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac 
*dwmac)
dwmac->m250_div.shift = PRG_ETH0_CLK_M250_DIV_SHIFT;
dwmac->m250_div.width = PRG_ETH0_CLK_M250_DIV_WIDTH;
dwmac->m250_div.hw.init = 
-   dwmac->m250_div.flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO;
+   dwmac->m250_div.flags = CLK_DIVIDER_ONE_BASED |
+   CLK_DIVIDER_ALLOW_ZERO |
+   CLK_DIVIDER_ROUND_CLOSEST;
 
dwmac->m250_div_clk = devm_clk_register(dev, >m250_div.hw);
if (WARN_ON(IS_ERR(dwmac->m250_div_clk)))
-- 
2.15.1



[RFT net-next v4 5/5] net: stmmac: dwmac-meson8b: propagate rate changes to the parent clock

2018-01-14 Thread Martin Blumenstingl
On Meson8b the only valid input clock is MPLL2. The bootloader
configures that to run at 52394Hz which cannot be divided evenly
down to 125MHz using the m250_div clock. Currently the common clock
framework chooses a m250_div of 2 - with the internal fixed
"divide by 10" this results in a RGMII TX clock of 125001197Hz (120Hz
above the requested 125MHz).

Letting the common clock framework propagate the rate changes up to the
parent of m250_mux allows us to get the best possible clock rate. With
this patch the common clock framework calculates a rate of
very-close-to-250MHz (24701Hz to be exact) for the MPLL2 clock
(which is the mux input). Dividing that by 2 (which is an internal,
fixed divider for the RGMII TX clock) gives us an RGMII TX clock of
124999850Hz (which is only 150Hz off the requested 125MHz, compared to
1197Hz based on the MPLL2 rate set by u-boot and the Amlogic GPL kernel
sources).

SoCs from the Meson GX series are not affected by this change because
the input clock is FCLK_DIV2 whose rate cannot be changed (which is fine
since it's running at 1GHz, so it's already a multiple of 250MHz and
125MHz).

Fixes: 566e8251625304 ("net: stmmac: add a glue driver for the Amlogic Meson 8b 
/ GXBB DWMAC")
Suggested-by: Jerome Brunet <jbru...@baylibre.com>
Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index e30ad05d6a6e..b64a5351c665 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -111,7 +111,7 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac 
*dwmac)
init.name = devm_kasprintf(dev, GFP_KERNEL, "%s#m250_sel",
   dev_name(dev));
init.ops = _mux_ops;
-   init.flags = 0;
+   init.flags = CLK_SET_RATE_PARENT;
init.parent_names = mux_parent_names;
init.num_parents = MUX_CLK_NUM_PARENTS;
 
-- 
2.15.1



[RFT net-next v4 3/5] net: stmmac: dwmac-meson8b: fix internal RGMII clock configuration

2018-01-14 Thread Martin Blumenstingl
Tests (using an oscilloscope and an Odroid-C1 board with a RTL8211F
RGMII PHY) have shown that the PRG_ETH0 register behaves as follows:
- bit 4 is a mux to choose between two parent clocks. according to the
  public S805 datasheet the only supported parent clock is MPLL2 (this
  was not verified using the oscilloscope).
  The public S805/S905 datasheet claims that this bit is reserved.
- bits 9:7 control a one-based divider (register value 1 means "divide
  by 1", etc.) for the input clock. we call this clock the "m250_div"
  clock because it's value is always supposed to be (close to) 250MHz
  (see below for an explanation).
  The description in the public S805/S905 datasheet is a bit cryptic,
  but it comes down to "input clock = 250MHz * value" (which could also
  be expressed as "250MHz = input clock / value")
- there seems to be an internal fixed divide-by-2 clock which takes the
  output from the m250_div and divides it by 2. This is not unusual on
  Amlogic SoCs, since the SDIO (MMC) driver also uses an internal fixed
  divide-by-2 clock.
  This is not documented in the public S805/S905 datasheet
- bit 10 controls a gate clock which enables or disables the RGMII TX
  clock (which is an output on the MAC/SoC and an input in the PHY). we
  call this the "rgmii_tx_en" clock. if this bit is set to "0" the RGMII
  TX clock output is close to 0
  The description for this bit in the public S805/S905 datasheet is
  "Generate 25MHz clock for PHY". Based on these tests it's believed
  that this is wrong, and should probably read "Generate the 125MHz
  RGMII TX clock for the PHY"
- the RGMII TX clock has to be set to 125MHz - the IP block adjusts the
  output (automatically) depending on the line speed (RGMII specifies
  that Gbit connections use a 125MHz clock, 100Mbit/s connections use a
  25MHz clock and 10Mbit/s connections use a 2.5MHz clock. only Gbit and
  100Mbit/s were tested with an oscilloscope). Due to the requirement
  that this clock always has to be set to 125MHz and due to the fixed
  divide-by-2 parent clock this means that m250_div will always end up
  with a rate of (close to) 250MHz.
- bits 6:5 are the TX delay, which is also named "clock phase" in some
  of Amlogic's older GPL kernel sources.

The PHY also has an XTAL_IN pin where a 25MHz clock has to be provided.
Tests with the oscilloscope have shown that this is routed to a crystal
right next to the RTL8211F PHY. The same seems to be true on the Khadas
VIM2 (which uses a GXM SoC) board - however the 25MHz crystal is on the
other side of the PCB there.

This updates the clocks in the dwmac-meson8b driver by replacing the
"m25_div" with the "rgmii_tx_en" clock and additionally introducing a
fixed divide-by-2 clock between "m250_div" and "rgmii_tx_en".
Now we also need to set a frequency of 125MHz on the RGMII clock
(opposed to the 25MHz we set before, with that non-existing
divide-by-5-or-10 divider).

Special thanks go to Linus Lüssing for testing the various bits and
checking the results with an oscilloscope on his Odroid-C1!

Fixes: 566e8251625304 ("net: stmmac: add a glue driver for the Amlogic Meson 8b 
/ GXBB DWMAC")
Reported-by: Emiliano Ingrassia <ingras...@epigenesys.com>
Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c| 79 +-
 1 file changed, 47 insertions(+), 32 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index 670f344f7168..e9fec9e0425c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -40,9 +40,7 @@
 #define PRG_ETH0_CLK_M250_DIV_SHIFT7
 #define PRG_ETH0_CLK_M250_DIV_WIDTH3
 
-/* divides the result of m25_sel by either 5 (bit unset) or 10 (bit set) */
-#define PRG_ETH0_CLK_M25_DIV_SHIFT 10
-#define PRG_ETH0_CLK_M25_DIV_WIDTH 1
+#define PRG_ETH0_RGMII_TX_CLK_EN   10
 
 #define PRG_ETH0_INVERTED_RMII_CLK BIT(11)
 #define PRG_ETH0_TX_AND_PHY_REF_CLKBIT(12)
@@ -63,8 +61,11 @@ struct meson8b_dwmac {
struct clk_divider  m250_div;
struct clk  *m250_div_clk;
 
-   struct clk_divider  m25_div;
-   struct clk  *m25_div_clk;
+   struct clk_fixed_factor fixed_div2;
+   struct clk  *fixed_div2_clk;
+
+   struct clk_gate rgmii_tx_en;
+   struct clk  *rgmii_tx_en_clk;
 
u32 tx_delay_ns;
 };
@@ -88,11 +89,6 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac 
*dwmac)
struct device *dev = >pdev->dev;
const char *clk_div_parents[1];
const char *mux_parent_names[MUX_CLK_NUM_PARENTS];
-   static const struct clk_div_table clk_25m_di

[RFT net-next v4 0/5] dwmac-meson8b: clock fixes for Meson8b

2018-01-14 Thread Martin Blumenstingl
sts.infradead.org/pipermail/linux-amlogic/2017-December/005848.html
[2] http://lists.infradead.org/pipermail/linux-amlogic/2017-December/005861.html
[3] http://lists.infradead.org/pipermail/linux-amlogic/2017-December/005899.html


Martin Blumenstingl (5):
  net: stmmac: dwmac-meson8b: only configure the clocks in RGMII mode
  net: stmmac: dwmac-meson8b: simplify generating the clock names
  net: stmmac: dwmac-meson8b: fix internal RGMII clock configuration
  net: stmmac: dwmac-meson8b: fix setting the RGMII TX clock on Meson8b
  net: stmmac: dwmac-meson8b: propagate rate changes to the parent clock

 .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c| 124 +++--
 1 file changed, 68 insertions(+), 56 deletions(-)

-- 
2.15.1



Re: [RFT net-next v3 0/5] dwmac-meson8b: RGMII clock fixes for Meson8b

2017-12-30 Thread Martin Blumenstingl
Hi Emiliano,

On Sat, Dec 30, 2017 at 12:00 AM, Emiliano Ingrassia
<ingras...@epigenesys.com> wrote:
> Hi Jerome, Hi Martin,
>
> On Fri, Dec 29, 2017 at 07:04:23PM +0100, Jerome Brunet wrote:
>> On Fri, 2017-12-29 at 02:31 +0100, Emiliano Ingrassia wrote:
>> > Hi Martin, Hi Dave,
>> >
>> > On Thu, Dec 28, 2017 at 11:21:23PM +0100, Martin Blumenstingl wrote:
>> > > Hi Dave,
>> > >
>> > > please do not apply this series until it got a Tested-by from Emiliano.
>> > >
>> > >
>> > > Hi Emiliano,
>> > >
>> > > you reported [0] that you couldn't get dwmac-meson8b to work on your
>> > > Odroid-C1. With your findings (register dumps, clk_summary output, etc.)
>> > > I think I was able to find a fix: it consists of two patches (which you
>> > > find in this series)
>> > >
>> > > Unfortunately I don't have any Meson8b boards with RGMII PHY so I could
>> > > only partially test this (I could only check if the clocks were
>> > > calculated correctly when using a dummy 52394Hz input clock instead
>> > > of MPLL2).
>> > >
>> > > Could you please give this series a try and let me know about the
>> > > results?
>> > > You obviously still need your two "ARM: dts: meson8b" patches which
>> > > - add the amlogic,meson8b-dwmac" compatible to meson8b.dtsi
>> > > - enable Ethernet on the Odroid-C1
>> > >
>> > > When testing on Meson8b this also needs a fix for the MPLL clock driver:
>> > > "clk: meson: mpll: use 64-bit maths in params_from_rate", see:
>> > > https://patchwork.kernel.org/patch/10131677/
>> > >
>> > >
>> > > I have tested this myself on a Khadas VIM (GXL SoC, internal RMII PHY)
>> > > and a Khadas VIM2 (GXM SoC, external RGMII PHY). Both are still working
>> > > fine (so let's hope that this also fixes your Meson8b issue :)).
>> > >
>> > >
>> > > changes since v1 at [1]:
>> > > - changed the subject of the cover-letter to indicate that this is all
>> > >   about the RGMII clock
>> > > - added PATCH #1 which ensures that we don't unnecessarily change the
>> > >   parent clocks in RMII mode (and also makes the code easier to
>> > >   understand)
>> > > - changed subject of PATCH #2 (formerly PATCH #1) to state that this
>> > >   is about the RGMII clock
>> > > - added Jerome's Reviewed-by to PATCH #2 (formerly PATCH #1)
>> > > - replaced PATCH #3 (formerly PATCH #2) with one that sets
>> > >   CLK_SET_RATE_PARENT on the mux and thus re-configures the MPLL2 clock
>> > >   on Meson8b correctly
>> > >
>> > > changes since v2 at [2]:
>> > > - added PATCH #2 to make the following patch easier
>> > > - Emiliano reported that there's currently another bug in the
>> > >   dwmac-meson8b driver which prevents it from working with RGMII PHYs on
>> > >   Meson8b: bit 10 of the PRG_ETH0 register is configures a clock gate
>> > >   (instead of a divide by 5 or divide by 10 clock divider). This has not
>> > >   been visible on GXBB and later due to the input clock which always led
>> > >   to a selection of "divide by 10" (which is done internally in the IP
>> > >   block, but the bit actually means "enable RGMII clock output").
>> > >   PATCH #3 was added to address this issue.
>> > > - the commit message of PATCH #4 and #5 (formerly PATCH #2 and #3) were
>> > >   updated and the patch itself rebased because the m25_div clock was
>> > >   removed with the new PATCH #3 (so some of the statements were not
>> > >   valid anymore)
>> > >
>> >
>> > Here is the clk_summary relative to ethernet on Odroid-C1+
>> > with this new series applied:
>> >
>> > xtal112400 
>> >  0 0
>> >  sys_pll00  12  0 0
>> >   cpu_clk   00  12  0 0
>> >  vid_pll00   73200  0 0
>> >  fixed_pll  22  255000  0 0
>> >   mpll2 11   24701 
>> >  0 0
>> >c941.ethernet#m250_sel   11   24701

Re: [RFT net-next v3 3/5] net: stmmac: dwmac-meson8b: fix internal RGMII clock configuration

2017-12-29 Thread Martin Blumenstingl
Hi Jerome,

On Fri, Dec 29, 2017 at 6:57 PM, Jerome Brunet <jbru...@baylibre.com> wrote:
> On Thu, 2017-12-28 at 23:21 +0100, Martin Blumenstingl wrote:
>> While testing the dwmac-meson8b with an RGMII PHY on Meson8b we
>> discovered that the m25_div is not actually a divider but rather a gate.
>> This matches with the datasheet which describes bit 10 as "Generate
>> 25MHz clock for PHY". Back when the driver was written it was assumed
>> that this was a divider (which could divide by 5 or 10) because other
>> clock bits in the datasheet were documented incorrectly.
>
> Maybe this bit 10 is indeed a 5/10 divider, as amlogic claims it is. Maybe, as
> Emiliano suggested, the output rate of div250 actually needs to be 250Mhz in
> RGMII, before being divided by 10 to produce the 25MHz of div25
>
> IOW, maybe we need this intermediate rate.
I am starting to believe that you (Emiliano and Jerome) are both right
does anyone of you have access to a scope so we can measure the actual
clock output?

> It would not be surprising, 1GBps usually requires a 125MHz clock somewhere.
this could mean that two clocks are derived from m250_div (names are
not final obviously):
- phy_ref_clk (25MHz or 50MHz)
- rgmii_tx_clk (fixed divide by 2, 125MHz)

> This is still doable:
> * Keep the divider
> * drop CLK_SET_RATE_PARENT on div25
> * call set_rate on div250 with 250MHz then on div25 with 25Mhz
yep, I will try this next
this would also be work with the assumption that the rgmii_tx_clk is
derived from m250_div

>
>>
>> Tests have shown that without bit 10 set the RTL8211F RGMII PHY on
>> Odroid-C1 (using a Meson8b SoC) does not work.
>> On GXBB and newer SoCs (where the driver was initially tested with RGMII
>> PHYs) this is not a problem because the input clock is running at 1GHz.
>> The m250_div clock's biggest possible divider is 7 (3-bit divider, with
>> value 0 being reserved). Thus we end up with a m250_div of 4 and a
>> "m25_div" of 10 (= register value 1).
>>
>> Instead it turns out that the Ethernet IP block seems to have a fixed
>> "divide by 10" clock internally. This means that bit 10 is a gate clock
>> which enables the RGMII clock output.
>>
>> This replaces the "m25_div" clock with a clock gate called "m25_en"
>> which ensures that we can set this bit to 1 whenever we enable RGMII
>> mode. This however means that we are now missing a "divide by 10" after
>> the m250_div (and before our new m25_en), otherwise the common clock
>> framework thinks that the rate of the m25_en clock is 10-times higher
>> than it is in the actual hardware. That is solved by adding a
>> fixed-factor clock which divides the m250_div output by 10.
>>
>> Fixes: 566e8251625304 ("net: stmmac: add a glue driver for the Amlogic Meson 
>> 8b / GXBB DWMAC")
>> Reported-by: Emiliano Ingrassia <ingras...@epigenesys.com>
>> Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
>> ---
>>  .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c| 66 
>> +-
>>  1 file changed, 38 insertions(+), 28 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
>> b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
>> index 1c14210df465..7199e8c08536 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
>> @@ -40,9 +40,7 @@
>>  #define PRG_ETH0_CLK_M250_DIV_SHIFT7
>>  #define PRG_ETH0_CLK_M250_DIV_WIDTH3
>>
>> -/* divides the result of m25_sel by either 5 (bit unset) or 10 (bit set) */
>> -#define PRG_ETH0_CLK_M25_DIV_SHIFT 10
>> -#define PRG_ETH0_CLK_M25_DIV_WIDTH 1
>> +#define PRG_ETH0_GENERATE_25M_PHY_CLOCK10
>>
>>  #define PRG_ETH0_INVERTED_RMII_CLK BIT(11)
>>  #define PRG_ETH0_TX_AND_PHY_REF_CLKBIT(12)
>> @@ -63,8 +61,11 @@ struct meson8b_dwmac {
>> struct clk_divider  m250_div;
>> struct clk  *m250_div_clk;
>>
>> -   struct clk_divider  m25_div;
>> -   struct clk  *m25_div_clk;
>> +   struct clk_fixed_factor fixed_div10;
>> +   struct clk  *fixed_div10_clk;
>> +
>> +   struct clk_gate m25_en;
>> +   struct clk  *m25_en_clk;
>
> Maybe it could be the topic of another series but we don't need to keep all
> those structures around, thanks to devm
>
> all clk_divider, fixed_factor, gate and mux can go away
> You only need to keep  the'struct clk*' you are going to use l

Re: [RFT net-next v3 0/5] dwmac-meson8b: RGMII clock fixes for Meson8b

2017-12-28 Thread Martin Blumenstingl
On Fri, Dec 29, 2017 at 8:48 AM, Martin Blumenstingl
<martin.blumensti...@googlemail.com> wrote:
> Hi Emiliano,
>
> On Fri, Dec 29, 2017 at 2:31 AM, Emiliano Ingrassia
> <ingras...@epigenesys.com> wrote:
>> Hi Martin, Hi Dave,
>>
>> On Thu, Dec 28, 2017 at 11:21:23PM +0100, Martin Blumenstingl wrote:
>>> Hi Dave,
>>>
>>> please do not apply this series until it got a Tested-by from Emiliano.
>>>
>>>
>>> Hi Emiliano,
>>>
>>> you reported [0] that you couldn't get dwmac-meson8b to work on your
>>> Odroid-C1. With your findings (register dumps, clk_summary output, etc.)
>>> I think I was able to find a fix: it consists of two patches (which you
>>> find in this series)
>>>
>>> Unfortunately I don't have any Meson8b boards with RGMII PHY so I could
>>> only partially test this (I could only check if the clocks were
>>> calculated correctly when using a dummy 52394Hz input clock instead
>>> of MPLL2).
>>>
>>> Could you please give this series a try and let me know about the
>>> results?
>>> You obviously still need your two "ARM: dts: meson8b" patches which
>>> - add the amlogic,meson8b-dwmac" compatible to meson8b.dtsi
>>> - enable Ethernet on the Odroid-C1
>>>
>>> When testing on Meson8b this also needs a fix for the MPLL clock driver:
>>> "clk: meson: mpll: use 64-bit maths in params_from_rate", see:
>>> https://patchwork.kernel.org/patch/10131677/
>>>
>>>
>>> I have tested this myself on a Khadas VIM (GXL SoC, internal RMII PHY)
>>> and a Khadas VIM2 (GXM SoC, external RGMII PHY). Both are still working
>>> fine (so let's hope that this also fixes your Meson8b issue :)).
>>>
>>>
>>> changes since v1 at [1]:
>>> - changed the subject of the cover-letter to indicate that this is all
>>>   about the RGMII clock
>>> - added PATCH #1 which ensures that we don't unnecessarily change the
>>>   parent clocks in RMII mode (and also makes the code easier to
>>>   understand)
>>> - changed subject of PATCH #2 (formerly PATCH #1) to state that this
>>>   is about the RGMII clock
>>> - added Jerome's Reviewed-by to PATCH #2 (formerly PATCH #1)
>>> - replaced PATCH #3 (formerly PATCH #2) with one that sets
>>>   CLK_SET_RATE_PARENT on the mux and thus re-configures the MPLL2 clock
>>>   on Meson8b correctly
>>>
>>> changes since v2 at [2]:
>>> - added PATCH #2 to make the following patch easier
>>> - Emiliano reported that there's currently another bug in the
>>>   dwmac-meson8b driver which prevents it from working with RGMII PHYs on
>>>   Meson8b: bit 10 of the PRG_ETH0 register is configures a clock gate
>>>   (instead of a divide by 5 or divide by 10 clock divider). This has not
>>>   been visible on GXBB and later due to the input clock which always led
>>>   to a selection of "divide by 10" (which is done internally in the IP
>>>   block, but the bit actually means "enable RGMII clock output").
>>>   PATCH #3 was added to address this issue.
>>> - the commit message of PATCH #4 and #5 (formerly PATCH #2 and #3) were
>>>   updated and the patch itself rebased because the m25_div clock was
>>>   removed with the new PATCH #3 (so some of the statements were not
>>>   valid anymore)
>>>
>>
>> Here is the clk_summary relative to ethernet on Odroid-C1+
>> with this new series applied:
>>
>> xtal112400  0 0
>>  sys_pll00  12  0 0
>>   cpu_clk   00  12  0 0
>>  vid_pll00   73200  0 0
>>  fixed_pll  22  255000  0 0
>>   mpll2 11   24701  0 0
>>c941.ethernet#m250_sel   11   24701  0 0
>> c941.ethernet#m250_div  11   24701  0 0
>>  c941.ethernet#fixed_div10  112470  0 0
>>   c941.ethernet#m25_en  112470  0 0
>>
>> The ethernet prg0 register is set to 0x74A1 which should be correct with
>> respect to the information contained in the S805 SoC manual.
>> Actually, the ethernet is not yet fully functional.
>> Trying to ping the 

Re: [RFT net-next v3 0/5] dwmac-meson8b: RGMII clock fixes for Meson8b

2017-12-28 Thread Martin Blumenstingl
Hi Emiliano,

On Fri, Dec 29, 2017 at 2:31 AM, Emiliano Ingrassia
<ingras...@epigenesys.com> wrote:
> Hi Martin, Hi Dave,
>
> On Thu, Dec 28, 2017 at 11:21:23PM +0100, Martin Blumenstingl wrote:
>> Hi Dave,
>>
>> please do not apply this series until it got a Tested-by from Emiliano.
>>
>>
>> Hi Emiliano,
>>
>> you reported [0] that you couldn't get dwmac-meson8b to work on your
>> Odroid-C1. With your findings (register dumps, clk_summary output, etc.)
>> I think I was able to find a fix: it consists of two patches (which you
>> find in this series)
>>
>> Unfortunately I don't have any Meson8b boards with RGMII PHY so I could
>> only partially test this (I could only check if the clocks were
>> calculated correctly when using a dummy 52394Hz input clock instead
>> of MPLL2).
>>
>> Could you please give this series a try and let me know about the
>> results?
>> You obviously still need your two "ARM: dts: meson8b" patches which
>> - add the amlogic,meson8b-dwmac" compatible to meson8b.dtsi
>> - enable Ethernet on the Odroid-C1
>>
>> When testing on Meson8b this also needs a fix for the MPLL clock driver:
>> "clk: meson: mpll: use 64-bit maths in params_from_rate", see:
>> https://patchwork.kernel.org/patch/10131677/
>>
>>
>> I have tested this myself on a Khadas VIM (GXL SoC, internal RMII PHY)
>> and a Khadas VIM2 (GXM SoC, external RGMII PHY). Both are still working
>> fine (so let's hope that this also fixes your Meson8b issue :)).
>>
>>
>> changes since v1 at [1]:
>> - changed the subject of the cover-letter to indicate that this is all
>>   about the RGMII clock
>> - added PATCH #1 which ensures that we don't unnecessarily change the
>>   parent clocks in RMII mode (and also makes the code easier to
>>   understand)
>> - changed subject of PATCH #2 (formerly PATCH #1) to state that this
>>   is about the RGMII clock
>> - added Jerome's Reviewed-by to PATCH #2 (formerly PATCH #1)
>> - replaced PATCH #3 (formerly PATCH #2) with one that sets
>>   CLK_SET_RATE_PARENT on the mux and thus re-configures the MPLL2 clock
>>   on Meson8b correctly
>>
>> changes since v2 at [2]:
>> - added PATCH #2 to make the following patch easier
>> - Emiliano reported that there's currently another bug in the
>>   dwmac-meson8b driver which prevents it from working with RGMII PHYs on
>>   Meson8b: bit 10 of the PRG_ETH0 register is configures a clock gate
>>   (instead of a divide by 5 or divide by 10 clock divider). This has not
>>   been visible on GXBB and later due to the input clock which always led
>>   to a selection of "divide by 10" (which is done internally in the IP
>>   block, but the bit actually means "enable RGMII clock output").
>>   PATCH #3 was added to address this issue.
>> - the commit message of PATCH #4 and #5 (formerly PATCH #2 and #3) were
>>   updated and the patch itself rebased because the m25_div clock was
>>   removed with the new PATCH #3 (so some of the statements were not
>>   valid anymore)
>>
>
> Here is the clk_summary relative to ethernet on Odroid-C1+
> with this new series applied:
>
> xtal112400  0 0
>  sys_pll00  12  0 0
>   cpu_clk   00  12  0 0
>  vid_pll00   73200  0 0
>  fixed_pll  22  255000  0 0
>   mpll2 11   24701  0 0
>c941.ethernet#m250_sel   11   24701  0 0
> c941.ethernet#m250_div  11   24701  0 0
>  c941.ethernet#fixed_div10  112470  0 0
>   c941.ethernet#m25_en  112470  0 0
>
> The ethernet prg0 register is set to 0x74A1 which should be correct with
> respect to the information contained in the S805 SoC manual.
> Actually, the ethernet is not yet fully functional.
> Trying to ping the board, I can see ARP request from host to board using
> tcpdump. However, the host can't see any response.
great - we're getting closer!

> Following the U-Boot value for prg0 register, which is 0x7d21, I also
> tried to set bit 11. As expected, this did not have any influence.
it *may* be something outside the PRG_ETH0 register than
to confirm that: could you temporarily revert the last patch from this
series ("net: stmmac: dwmac

[RFT net-next v3 2/5] net: stmmac: dwmac-meson8b: simplify generating the clock names

2017-12-28 Thread Martin Blumenstingl
Instead of using a custom buffer, snprintf() and devm_kstrdup() we can
simplify this by using devm_kasprintf().
No functional changes - this just makes the code shorter.

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index e1d5907e481c..1c14210df465 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -86,7 +86,6 @@ static int meson8b_init_rgmii_clk(struct meson8b_dwmac *dwmac)
struct clk_init_data init;
int i, ret;
struct device *dev = >pdev->dev;
-   char clk_name[32];
const char *clk_div_parents[1];
const char *mux_parent_names[MUX_CLK_NUM_PARENTS];
static const struct clk_div_table clk_25m_div_table[] = {
@@ -113,8 +112,8 @@ static int meson8b_init_rgmii_clk(struct meson8b_dwmac 
*dwmac)
}
 
/* create the m250_mux */
-   snprintf(clk_name, sizeof(clk_name), "%s#m250_sel", dev_name(dev));
-   init.name = clk_name;
+   init.name = devm_kasprintf(dev, GFP_KERNEL, "%s#m250_sel",
+  dev_name(dev));
init.ops = _mux_ops;
init.flags = 0;
init.parent_names = mux_parent_names;
@@ -132,8 +131,8 @@ static int meson8b_init_rgmii_clk(struct meson8b_dwmac 
*dwmac)
return PTR_ERR(dwmac->m250_mux_clk);
 
/* create the m250_div */
-   snprintf(clk_name, sizeof(clk_name), "%s#m250_div", dev_name(dev));
-   init.name = devm_kstrdup(dev, clk_name, GFP_KERNEL);
+   init.name = devm_kasprintf(dev, GFP_KERNEL, "%s#m250_div",
+  dev_name(dev));
init.ops = _divider_ops;
init.flags = CLK_SET_RATE_PARENT;
clk_div_parents[0] = __clk_get_name(dwmac->m250_mux_clk);
@@ -151,8 +150,8 @@ static int meson8b_init_rgmii_clk(struct meson8b_dwmac 
*dwmac)
return PTR_ERR(dwmac->m250_div_clk);
 
/* create the m25_div */
-   snprintf(clk_name, sizeof(clk_name), "%s#m25_div", dev_name(dev));
-   init.name = devm_kstrdup(dev, clk_name, GFP_KERNEL);
+   init.name = devm_kasprintf(dev, GFP_KERNEL, "%s#m25_div",
+  dev_name(dev));
init.ops = _divider_ops;
init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT;
clk_div_parents[0] = __clk_get_name(dwmac->m250_div_clk);
-- 
2.15.1



[RFT net-next v3 4/5] net: stmmac: dwmac-meson8b: fix setting the RGMII clock on Meson8b

2017-12-28 Thread Martin Blumenstingl
Meson8b only supports MPLL2 as clock input. The rate of the MPLL2 clock
set by Odroid-C1's u-boot is close to 500MHz. The exact rate is
52394Hz, which is calculated in drivers/clk/meson/clk-mpll.c
using the following formula:
DIV_ROUND_UP_ULL((u64)parent_rate * SDM_DEN, (SDM_DEN * n2) + sdm)
Odroid-C1's u-boot configures MPLL2 with the following values:
- SDM_DEN = 16384
- SDM = 1638
- N2 = 5

The 250MHz clock (m250_div) inside dwmac-meson8b driver is derived from
the MPLL2 clock. Due to MPLL2 running slightly faster than 500MHz the
common clock framework chooses a divider which is too big to generate
the 250MHz clock (a divider of 2 would be needed, but this is rounded up
to a divider of 3). This breaks the RTL8211F RGMII PHY on Odroid-C1
because it requires a (close to) 25MHz clock.

Round the divider to the closest value to prevent this issue on Meson8b.
This means we'll now end up with a clock rate of 25000120Hz (= 25MHz
plus 120Hz).
This has no effect on the Meson GX SoCs since there fclk_div2 is used as
input clock, which has a rate of 1000MHz (and thus is divisible cleanly
to 250MHz and 25MHz).

Fixes: 566e8251625304 ("net: stmmac: add a glue driver for the Amlogic Meson 8b 
/ GXBB DWMAC")
Reported-by: Emiliano Ingrassia <ingras...@epigenesys.com>
Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
Reviewed-by: Jerome Brunet <jbru...@baylibre.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index 7199e8c08536..d06106417063 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -139,7 +139,9 @@ static int meson8b_init_rgmii_clk(struct meson8b_dwmac 
*dwmac)
dwmac->m250_div.shift = PRG_ETH0_CLK_M250_DIV_SHIFT;
dwmac->m250_div.width = PRG_ETH0_CLK_M250_DIV_WIDTH;
dwmac->m250_div.hw.init = 
-   dwmac->m250_div.flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO;
+   dwmac->m250_div.flags = CLK_DIVIDER_ONE_BASED |
+   CLK_DIVIDER_ALLOW_ZERO |
+   CLK_DIVIDER_ROUND_CLOSEST;
 
dwmac->m250_div_clk = devm_clk_register(dev, >m250_div.hw);
if (WARN_ON(IS_ERR(dwmac->m250_div_clk)))
-- 
2.15.1



[RFT net-next v3 3/5] net: stmmac: dwmac-meson8b: fix internal RGMII clock configuration

2017-12-28 Thread Martin Blumenstingl
While testing the dwmac-meson8b with an RGMII PHY on Meson8b we
discovered that the m25_div is not actually a divider but rather a gate.
This matches with the datasheet which describes bit 10 as "Generate
25MHz clock for PHY". Back when the driver was written it was assumed
that this was a divider (which could divide by 5 or 10) because other
clock bits in the datasheet were documented incorrectly.

Tests have shown that without bit 10 set the RTL8211F RGMII PHY on
Odroid-C1 (using a Meson8b SoC) does not work.
On GXBB and newer SoCs (where the driver was initially tested with RGMII
PHYs) this is not a problem because the input clock is running at 1GHz.
The m250_div clock's biggest possible divider is 7 (3-bit divider, with
value 0 being reserved). Thus we end up with a m250_div of 4 and a
"m25_div" of 10 (= register value 1).

Instead it turns out that the Ethernet IP block seems to have a fixed
"divide by 10" clock internally. This means that bit 10 is a gate clock
which enables the RGMII clock output.

This replaces the "m25_div" clock with a clock gate called "m25_en"
which ensures that we can set this bit to 1 whenever we enable RGMII
mode. This however means that we are now missing a "divide by 10" after
the m250_div (and before our new m25_en), otherwise the common clock
framework thinks that the rate of the m25_en clock is 10-times higher
than it is in the actual hardware. That is solved by adding a
fixed-factor clock which divides the m250_div output by 10.

Fixes: 566e8251625304 ("net: stmmac: add a glue driver for the Amlogic Meson 8b 
/ GXBB DWMAC")
Reported-by: Emiliano Ingrassia <ingras...@epigenesys.com>
Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c| 66 +-
 1 file changed, 38 insertions(+), 28 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index 1c14210df465..7199e8c08536 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -40,9 +40,7 @@
 #define PRG_ETH0_CLK_M250_DIV_SHIFT7
 #define PRG_ETH0_CLK_M250_DIV_WIDTH3
 
-/* divides the result of m25_sel by either 5 (bit unset) or 10 (bit set) */
-#define PRG_ETH0_CLK_M25_DIV_SHIFT 10
-#define PRG_ETH0_CLK_M25_DIV_WIDTH 1
+#define PRG_ETH0_GENERATE_25M_PHY_CLOCK10
 
 #define PRG_ETH0_INVERTED_RMII_CLK BIT(11)
 #define PRG_ETH0_TX_AND_PHY_REF_CLKBIT(12)
@@ -63,8 +61,11 @@ struct meson8b_dwmac {
struct clk_divider  m250_div;
struct clk  *m250_div_clk;
 
-   struct clk_divider  m25_div;
-   struct clk  *m25_div_clk;
+   struct clk_fixed_factor fixed_div10;
+   struct clk  *fixed_div10_clk;
+
+   struct clk_gate m25_en;
+   struct clk  *m25_en_clk;
 
u32 tx_delay_ns;
 };
@@ -88,11 +89,6 @@ static int meson8b_init_rgmii_clk(struct meson8b_dwmac 
*dwmac)
struct device *dev = >pdev->dev;
const char *clk_div_parents[1];
const char *mux_parent_names[MUX_CLK_NUM_PARENTS];
-   static const struct clk_div_table clk_25m_div_table[] = {
-   { .val = 0, .div = 5 },
-   { .val = 1, .div = 10 },
-   { /* sentinel */ },
-   };
 
/* get the mux parents from DT */
for (i = 0; i < MUX_CLK_NUM_PARENTS; i++) {
@@ -149,25 +145,39 @@ static int meson8b_init_rgmii_clk(struct meson8b_dwmac 
*dwmac)
if (WARN_ON(IS_ERR(dwmac->m250_div_clk)))
return PTR_ERR(dwmac->m250_div_clk);
 
-   /* create the m25_div */
-   init.name = devm_kasprintf(dev, GFP_KERNEL, "%s#m25_div",
+   /* create the fixed_div10 */
+   init.name = devm_kasprintf(dev, GFP_KERNEL, "%s#fixed_div10",
   dev_name(dev));
-   init.ops = _divider_ops;
-   init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT;
+   init.ops = _fixed_factor_ops;
+   init.flags = CLK_SET_RATE_PARENT;
clk_div_parents[0] = __clk_get_name(dwmac->m250_div_clk);
init.parent_names = clk_div_parents;
init.num_parents = ARRAY_SIZE(clk_div_parents);
 
-   dwmac->m25_div.reg = dwmac->regs + PRG_ETH0;
-   dwmac->m25_div.shift = PRG_ETH0_CLK_M25_DIV_SHIFT;
-   dwmac->m25_div.width = PRG_ETH0_CLK_M25_DIV_WIDTH;
-   dwmac->m25_div.table = clk_25m_div_table;
-   dwmac->m25_div.hw.init = 
-   dwmac->m25_div.flags = CLK_DIVIDER_ALLOW_ZERO;
+   dwmac->fixed_div10.mult = 1;
+   dwmac->fixed_div10.div = 10;
+   dwmac->fixed_div10.hw.init = 
+
+   dwmac->fixed_div10_clk = devm_clk_register(dev, >fixed_div10.hw);
+   if (WARN_ON(IS_ERR(dwmac->fixed

[RFT net-next v3 0/5] dwmac-meson8b: RGMII clock fixes for Meson8b

2017-12-28 Thread Martin Blumenstingl
Hi Dave,

please do not apply this series until it got a Tested-by from Emiliano.


Hi Emiliano,

you reported [0] that you couldn't get dwmac-meson8b to work on your
Odroid-C1. With your findings (register dumps, clk_summary output, etc.)
I think I was able to find a fix: it consists of two patches (which you
find in this series)

Unfortunately I don't have any Meson8b boards with RGMII PHY so I could
only partially test this (I could only check if the clocks were
calculated correctly when using a dummy 52394Hz input clock instead
of MPLL2).

Could you please give this series a try and let me know about the
results?
You obviously still need your two "ARM: dts: meson8b" patches which
- add the amlogic,meson8b-dwmac" compatible to meson8b.dtsi
- enable Ethernet on the Odroid-C1

When testing on Meson8b this also needs a fix for the MPLL clock driver:
"clk: meson: mpll: use 64-bit maths in params_from_rate", see:
https://patchwork.kernel.org/patch/10131677/


I have tested this myself on a Khadas VIM (GXL SoC, internal RMII PHY)
and a Khadas VIM2 (GXM SoC, external RGMII PHY). Both are still working
fine (so let's hope that this also fixes your Meson8b issue :)).


changes since v1 at [1]:
- changed the subject of the cover-letter to indicate that this is all
  about the RGMII clock
- added PATCH #1 which ensures that we don't unnecessarily change the
  parent clocks in RMII mode (and also makes the code easier to
  understand)
- changed subject of PATCH #2 (formerly PATCH #1) to state that this
  is about the RGMII clock
- added Jerome's Reviewed-by to PATCH #2 (formerly PATCH #1)
- replaced PATCH #3 (formerly PATCH #2) with one that sets
  CLK_SET_RATE_PARENT on the mux and thus re-configures the MPLL2 clock
  on Meson8b correctly

changes since v2 at [2]:
- added PATCH #2 to make the following patch easier
- Emiliano reported that there's currently another bug in the
  dwmac-meson8b driver which prevents it from working with RGMII PHYs on
  Meson8b: bit 10 of the PRG_ETH0 register is configures a clock gate
  (instead of a divide by 5 or divide by 10 clock divider). This has not
  been visible on GXBB and later due to the input clock which always led
  to a selection of "divide by 10" (which is done internally in the IP
  block, but the bit actually means "enable RGMII clock output").
  PATCH #3 was added to address this issue.
- the commit message of PATCH #4 and #5 (formerly PATCH #2 and #3) were
  updated and the patch itself rebased because the m25_div clock was
  removed with the new PATCH #3 (so some of the statements were not
  valid anymore)


[0] http://lists.infradead.org/pipermail/linux-amlogic/2017-December/005596.html
[1] http://lists.infradead.org/pipermail/linux-amlogic/2017-December/005848.html
[2] http://lists.infradead.org/pipermail/linux-amlogic/2017-December/005861.html


Martin Blumenstingl (5):
  net: stmmac: dwmac-meson8b: only configure the clocks in RGMII mode
  net: stmmac: dwmac-meson8b: simplify generating the clock names
  net: stmmac: dwmac-meson8b: fix internal RGMII clock configuration
  net: stmmac: dwmac-meson8b: fix setting the RGMII clock on Meson8b
  net: stmmac: dwmac-meson8b: propagate rate changes to the parent clock

 .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c| 119 +++--
 1 file changed, 63 insertions(+), 56 deletions(-)

-- 
2.15.1



[RFT net-next v3 1/5] net: stmmac: dwmac-meson8b: only configure the clocks in RGMII mode

2017-12-28 Thread Martin Blumenstingl
Neither the m25_div_clk nor the m250_div_clk or m250_mux_clk are used in
RMII mode. The m25_div_clk output is routed to the RGMII PHY's "RGMII
clock".
This means that we don't need to configure the clocks in RMII mode. The
driver however did this - with no effect since the clocks are not routed
to the PHY in RMII mode.

While here also rename meson8b_init_clk to meson8b_init_rgmii_clk to
make it easier to understand the code.

Fixes: 566e8251625304 ("net: stmmac: add a glue driver for the Amlogic Meson 8b 
/ GXBB DWMAC")
Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c| 46 ++
 1 file changed, 21 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index 4404650b32c5..e1d5907e481c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -81,7 +81,7 @@ static void meson8b_dwmac_mask_bits(struct meson8b_dwmac 
*dwmac, u32 reg,
writel(data, dwmac->regs + reg);
 }
 
-static int meson8b_init_clk(struct meson8b_dwmac *dwmac)
+static int meson8b_init_rgmii_clk(struct meson8b_dwmac *dwmac)
 {
struct clk_init_data init;
int i, ret;
@@ -176,7 +176,6 @@ static int meson8b_init_clk(struct meson8b_dwmac *dwmac)
 static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
 {
int ret;
-   unsigned long clk_rate;
u8 tx_dly_val = 0;
 
switch (dwmac->phy_mode) {
@@ -191,9 +190,6 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
 
case PHY_INTERFACE_MODE_RGMII_ID:
case PHY_INTERFACE_MODE_RGMII_TXID:
-   /* Generate a 25MHz clock for the PHY */
-   clk_rate = 25 * 1000 * 1000;
-
/* enable RGMII mode */
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_RGMII_MODE,
PRG_ETH0_RGMII_MODE);
@@ -204,12 +200,24 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac 
*dwmac)
 
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TXDLY_MASK,
tx_dly_val << PRG_ETH0_TXDLY_SHIFT);
+
+   ret = clk_prepare_enable(dwmac->m25_div_clk);
+   if (ret) {
+   dev_err(>pdev->dev, "failed to enable the PHY 
clock\n");
+   return ret;
+   }
+
+   /* Generate the 25MHz RGMII clock for the PHY */
+   ret = clk_set_rate(dwmac->m25_div_clk, 25 * 1000 * 1000);
+   if (ret) {
+   clk_disable_unprepare(dwmac->m25_div_clk);
+
+   dev_err(>pdev->dev, "failed to set PHY clock\n");
+   return ret;
+   }
break;
 
case PHY_INTERFACE_MODE_RMII:
-   /* Use the rate of the mux clock for the internal RMII PHY */
-   clk_rate = clk_get_rate(dwmac->m250_mux_clk);
-
/* disable RGMII mode -> enables RMII mode */
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_RGMII_MODE,
0);
@@ -231,20 +239,6 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac 
*dwmac)
return -EINVAL;
}
 
-   ret = clk_prepare_enable(dwmac->m25_div_clk);
-   if (ret) {
-   dev_err(>pdev->dev, "failed to enable the PHY clock\n");
-   return ret;
-   }
-
-   ret = clk_set_rate(dwmac->m25_div_clk, clk_rate);
-   if (ret) {
-   clk_disable_unprepare(dwmac->m25_div_clk);
-
-   dev_err(>pdev->dev, "failed to set PHY clock\n");
-   return ret;
-   }
-
/* enable TX_CLK and PHY_REF_CLK generator */
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TX_AND_PHY_REF_CLK,
PRG_ETH0_TX_AND_PHY_REF_CLK);
@@ -294,7 +288,7 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
 >tx_delay_ns))
dwmac->tx_delay_ns = 2;
 
-   ret = meson8b_init_clk(dwmac);
+   ret = meson8b_init_rgmii_clk(dwmac);
if (ret)
goto err_remove_config_dt;
 
@@ -311,7 +305,8 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
return 0;
 
 err_clk_disable:
-   clk_disable_unprepare(dwmac->m25_div_clk);
+   if (phy_interface_mode_is_rgmii(dwmac->phy_mode))
+   clk_disable_unprepare(dwmac->m25_div_clk);
 err_remove_config_dt:
stmmac_remove_config_dt(pdev, plat_dat);
 
@@ -322,7 +317,8 @@ static int meson8b_dwmac_remove(struct platform_device 
*pdev)
 {
struct meson8b_dwmac *dwmac = get_stmmac_bsp_priv(>dev);
 
-   

[RFT net-next v3 5/5] net: stmmac: dwmac-meson8b: propagate rate changes to the parent clock

2017-12-28 Thread Martin Blumenstingl
On Meson8b the only valid input clock is MPLL2. The bootloader
configures that to run at 52394Hz which cannot be divided evenly
down to 25MHz using the m250_div and m25_div clocks. Currently the
common clock framework chooses a m250_div of 2 - with the internal fixed
"divide by 10" this results in a RGMII clock of 25000120Hz (120Hz above
the requested 25MHz).

Letting the common clock framework propagate the rate changes up to the
parent of m250_mux allows us to get the best possible clock rate. With
this patch the common clock framework calculates a rate of
very-close-to-250MHz (24701Hz to be exact) for the MPLL2 clock
(which is the mux input). Dividing that by 1 (using m250_div) along with
the internal fixed divide-by-10 gives us a RGMII clock of 2470Hz
(which is only 30Hz off the requested 25MHz, compared to 120Hz from
u-boot and the vendor driver).

SoCs from the Meson GX series are not affected by this change because
the input clock is FCLK_DIV2 whose rate cannot be changed (which is fine
since it's running at 1GHz, thus it's a multiple of 250MHz).

Fixes: 566e8251625304 ("net: stmmac: add a glue driver for the Amlogic Meson 8b 
/ GXBB DWMAC")
Suggested-by: Jerome Brunet <jbru...@baylibre.com>
Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index d06106417063..9c3cdfef414a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -111,7 +111,7 @@ static int meson8b_init_rgmii_clk(struct meson8b_dwmac 
*dwmac)
init.name = devm_kasprintf(dev, GFP_KERNEL, "%s#m250_sel",
   dev_name(dev));
init.ops = _mux_ops;
-   init.flags = 0;
+   init.flags = CLK_SET_RATE_PARENT;
init.parent_names = mux_parent_names;
init.num_parents = MUX_CLK_NUM_PARENTS;
 
-- 
2.15.1



Re: [RFT net-next v2 0/3] dwmac-meson8b: RGMII clock fixes for Meson8b

2017-12-28 Thread Martin Blumenstingl
Hi Emiliano,

On Thu, Dec 28, 2017 at 6:51 PM, Emiliano Ingrassia
<ingras...@epigenesys.com> wrote:
> Hi Martin,
>
> thank you for the quick response!
>
> On Thu, Dec 28, 2017 at 05:58:34PM +0100, Martin Blumenstingl wrote:
>> Hi Emiliano,
>>
>> thank you for testing this!
>>
>> On Thu, Dec 28, 2017 at 5:16 PM, Emiliano Ingrassia
>> <ingras...@epigenesys.com> wrote:
>> > Hi Martin, Hi Dave,
>> >
>> > On Sun, Dec 24, 2017 at 12:40:57AM +0100, Martin Blumenstingl wrote:
>> >> Hi Dave,
>> >>
>> >> please do not apply this series until it got a Tested-by from Emiliano.
>> >>
>> >>
>> >> Hi Emiliano,
>> >>
>> >> you reported [0] that you couldn't get dwmac-meson8b to work on your
>> >> Odroid-C1. With your findings (register dumps, clk_summary output, etc.)
>> >> I think I was able to find a fix: it consists of two patches (which you
>> >> find in this series)
>> >>
>> >> Unfortunately I don't have any Meson8b boards with RGMII PHY so I could
>> >> only partially test this (I could only check if the clocks were
>> >> calculated correctly when using a dummy 52394Hz input clock instead
>> >> of MPLL2).
>> >>
>> >> Could you please give this series a try and let me know about the
>> >> results?
>> >> You obviously still need your two "ARM: dts: meson8b" patches which
>> >> - add the amlogic,meson8b-dwmac" compatible to meson8b.dtsi
>> >> - enable Ethernet on the Odroid-C1
>> >>
>> >> I have tested this myself on a Khadas VIM (GXL SoC, internal RMII PHY)
>> >> and a Khadas VIM2 (GXM SoC, external RGMII PHY). Both are still working
>> >> fine (so let's hope that this also fixes your Meson8b issue :)).
>> >>
>> >>
>> >> changes since v1 at [1]:
>> >> - changed the subject of the cover-letter to indicate that this is all
>> >>   about the RGMII clock
>> >> - added PATCH #1 which ensures that we don't unnecessarily change the
>> >>   parent clocks in RMII mode (and also makes the code easier to
>> >>   understand)
>> >> - changed subject of PATCH #2 (formerly PATCH #1) to state that this
>> >>   is about the RGMII clock
>> >> - added Jerome's Reviewed-by to PATCH #2 (formerly PATCH #1)
>> >> - replaced PATCH #3 (formerly PATCH #2) with one that sets
>> >>   CLK_SET_RATE_PARENT on the mux and thus re-configures the MPLL2 clock
>> >>   on Meson8b correctly
>> >>
>> >
>> > Really thank you for your help and effort. I tried your patch but
>> > unfortunately it didn't solve the problem.
>> this is probably my fault: I forgot to mention that it requires a fix
>> for the 32-bit SoCs in the clock driver ("clk: meson: mpll: use 64-bit
>> maths in params_from_rate", see [0]) to work properly
>>
>
> Ok, with that patch applied I got:
>
> xtal   112400  0 0
>  sys_pll   00  12  0 0
>   cpu_clk  00  12  0 0
>  vid_pll   00   73200  0 0
>  fixed_pll 22  255000  0 0
>   mpll211   124999851  0 0
>c941.ethernet#m250_sel  11   124999851  0 0
> c941.ethernet#m250_div 11   124999851  0 0
>  c941.ethernet#m25_div 112471  0 0
in theory this looks good...!

> which is equal to your result. However, the ethernet is still not working.
OK, I'll send an updated version later (or tomorrow, depending on how
much time I have left today) which adds a fixed divider and converts
bit 10 to a gate
on GXBB and newer bit 10 is always true since the m250_div is only
3-bit wide (= max divider of 7, 0 is invalid according to the
datasheet). with a 1000MHz input clock (fclk_div2) m250_div will
divide this by 4 and m25_div divided this by 10.

> The prg0 register is set to 0x70A1.
>
> A problem that I see with this solution is that MPLL2 is set to ~125 MHz.
> The S805 SoC manual reports that bits 9-7 should contain a value x such
> that: MPLL2 = 250 MHz * x (with x >= 1).
> In our case, bits 9-7 are set to 1 which is incorrect.
> I think that MPLL2 should be 250 MHz at least.
when looking at the GXBB clock tree we need a fixed divide by 10.
thi

Re: [RFT net-next v2 0/3] dwmac-meson8b: RGMII clock fixes for Meson8b

2017-12-28 Thread Martin Blumenstingl
Hi Emiliano,

thank you for testing this!

On Thu, Dec 28, 2017 at 5:16 PM, Emiliano Ingrassia
<ingras...@epigenesys.com> wrote:
> Hi Martin, Hi Dave,
>
> On Sun, Dec 24, 2017 at 12:40:57AM +0100, Martin Blumenstingl wrote:
>> Hi Dave,
>>
>> please do not apply this series until it got a Tested-by from Emiliano.
>>
>>
>> Hi Emiliano,
>>
>> you reported [0] that you couldn't get dwmac-meson8b to work on your
>> Odroid-C1. With your findings (register dumps, clk_summary output, etc.)
>> I think I was able to find a fix: it consists of two patches (which you
>> find in this series)
>>
>> Unfortunately I don't have any Meson8b boards with RGMII PHY so I could
>> only partially test this (I could only check if the clocks were
>> calculated correctly when using a dummy 52394Hz input clock instead
>> of MPLL2).
>>
>> Could you please give this series a try and let me know about the
>> results?
>> You obviously still need your two "ARM: dts: meson8b" patches which
>> - add the amlogic,meson8b-dwmac" compatible to meson8b.dtsi
>> - enable Ethernet on the Odroid-C1
>>
>> I have tested this myself on a Khadas VIM (GXL SoC, internal RMII PHY)
>> and a Khadas VIM2 (GXM SoC, external RGMII PHY). Both are still working
>> fine (so let's hope that this also fixes your Meson8b issue :)).
>>
>>
>> changes since v1 at [1]:
>> - changed the subject of the cover-letter to indicate that this is all
>>   about the RGMII clock
>> - added PATCH #1 which ensures that we don't unnecessarily change the
>>   parent clocks in RMII mode (and also makes the code easier to
>>   understand)
>> - changed subject of PATCH #2 (formerly PATCH #1) to state that this
>>   is about the RGMII clock
>> - added Jerome's Reviewed-by to PATCH #2 (formerly PATCH #1)
>> - replaced PATCH #3 (formerly PATCH #2) with one that sets
>>   CLK_SET_RATE_PARENT on the mux and thus re-configures the MPLL2 clock
>>   on Meson8b correctly
>>
>
> Really thank you for your help and effort. I tried your patch but
> unfortunately it didn't solve the problem.
this is probably my fault: I forgot to mention that it requires a fix
for the 32-bit SoCs in the clock driver ("clk: meson: mpll: use 64-bit
maths in params_from_rate", see [0]) to work properly

>
> Here is the new clk_summary:
>
> xtal112400  0 0
>  sys_pll00  12  0 0
>   cpu_clk   00  12  0 0
>  vid_pll00   73200  0 0
>  fixed_pll  22  255000  0 0
>   mpll2 11   10625  0 0
>c941.ethernet#m250_sel   11   10625  0 0
> c941.ethernet#m250_div  11   10625  0 0
>  c941.ethernet#m25_div  112125  0 0
>
> which leads to a value of 0x70a1 in the prg0 ethernet register.
> As you can see, something is changed but the RGMII clock is not at 25 MHz.
> In particular, the bit 10 of prg0, which enables the "generation of 25 MHz
> clock for PHY" (see S805 manual), is 0.
assuming that the description in the datasheet is correct
after Kevin and Mike got updated information from Amlogic about the
PRG_ETHERNET0 register documenation (see [1]) we thought that bit 10
means "0 = divide by 5, 1 = divide by 10" (see [2]). I didn't question
this so far, but I'll test this on a newer SoC later (by forcing
m250_div to 125MHz, then m25_div will have register value 0 = divide
by 5)

if the description from the documentation is correct then we need to
replace m25_div with a fixed-factor clock (mult = 1, div = 5) and make
it a m25_en gate clock instead
the resulting clock path would look like this: mpll2 > m250_sel >
m250_div > fixed_factor > m25_en

> Please, if you have other suggestions let me know.
could you please re-test this with the patch from [0] applied? no
other changes should be needed!

> Best regards,
>
> Emiliano
>
>>
>> [0] 
>> http://lists.infradead.org/pipermail/linux-amlogic/2017-December/005596.html
>> [1] 
>> http://lists.infradead.org/pipermail/linux-amlogic/2017-December/005848.html
>>
>>
>> Martin Blumenstingl (3):
>>   net: stmmac: dwmac-meson8b: only configure the clocks in RGMII mode
>>   net: stmmac: dwmac-meson8b: fix setting the RGMII clock on Meson8b
>>   net: stmmac: dwmac-meson8b: propagate rate changes to the parent clock
>>
>>  .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c| 55 
>> +++---
>>  1 file changed, 27 insertions(+), 28 deletions(-)
>>
>> --
>> 2.15.1
>>

Regards
Martin


[0] https://patchwork.kernel.org/patch/10131677/
[1] https://www.mail-archive.com/netdev@vger.kernel.org/msg119290.html
[2] https://www.mail-archive.com/netdev@vger.kernel.org/msg119293.html


[RFT net-next v2 3/3] net: stmmac: dwmac-meson8b: propagate rate changes to the parent clock

2017-12-23 Thread Martin Blumenstingl
On Meson8b the only valid input clock is MPLL2. The bootloader
configures that to run at 52394Hz which cannot be divided evenly
down to 25MHz using the m250_div and m25_div clocks. Currently the
common clock framework chooses a m250_div of 2 and a m25_div of 10,
which results in a RGMII clock of 25000120Hz (120Hz above the requested
25MHz).

Letting the common clock framework propagate the rate changes from the
m25_div clock to m250_div clock to m250_mux to it's parent allows us to
get the best possible parent clock rate. With this patch the common clock
framework calculates a rate of close-to-125MHz (124999851Hz to be exact)
for the MPLL2 clock (which is the mux input). Dividing that by 5 (using
only the m25_div) gives us a RGMII clock of 2471Hz (which is only
29Hz off the requested 25MHz, compared to 120Hz from u-boot and the
vendor driver).

For now we only want to propagate rate changes to make sure that the mux
parent is not changed automatically by the common clock framework. This
is just to keep the number of side-effects from this patch at a minimum.

SoCs from the Meson GX series are not affected by this change because
the input clock is FCLK_DIV2 whose rate cannot be changed. Additionally
the GX SoCs don't need to use the "closest" divider since the parent
clock is a multiple of 250MHz.

Fixes: 566e8251625304 ("net: stmmac: add a glue driver for the Amlogic Meson 8b 
/ GXBB DWMAC")
Suggested-by: Jerome Brunet <jbru...@baylibre.com>
Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index 0da551c84fe8..e542c8a14f2a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -116,7 +116,7 @@ static int meson8b_init_rgmii_clk(struct meson8b_dwmac 
*dwmac)
snprintf(clk_name, sizeof(clk_name), "%s#m250_sel", dev_name(dev));
init.name = clk_name;
init.ops = _mux_ops;
-   init.flags = 0;
+   init.flags = CLK_SET_RATE_PARENT;
init.parent_names = mux_parent_names;
init.num_parents = MUX_CLK_NUM_PARENTS;
 
-- 
2.15.1



[RFT net-next v2 1/3] net: stmmac: dwmac-meson8b: only configure the clocks in RGMII mode

2017-12-23 Thread Martin Blumenstingl
Neither the m25_div_clk nor the m250_div_clk or m250_mux_clk are used in
RMII mode. The m25_div_clk output is routed to the RGMII PHY's "RGMII
clock".
This means that we don't need to configure the clocks in RMII mode. The
driver however did this - with no effect since the clocks are not routed
to the PHY in RMII mode.

While here also rename meson8b_init_clk to meson8b_init_rgmii_clk to
make it easier to understand the code.

Fixes: 566e8251625304 ("net: stmmac: add a glue driver for the Amlogic Meson 8b 
/ GXBB DWMAC")
Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c| 46 ++
 1 file changed, 21 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index 4404650b32c5..e1d5907e481c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -81,7 +81,7 @@ static void meson8b_dwmac_mask_bits(struct meson8b_dwmac 
*dwmac, u32 reg,
writel(data, dwmac->regs + reg);
 }
 
-static int meson8b_init_clk(struct meson8b_dwmac *dwmac)
+static int meson8b_init_rgmii_clk(struct meson8b_dwmac *dwmac)
 {
struct clk_init_data init;
int i, ret;
@@ -176,7 +176,6 @@ static int meson8b_init_clk(struct meson8b_dwmac *dwmac)
 static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
 {
int ret;
-   unsigned long clk_rate;
u8 tx_dly_val = 0;
 
switch (dwmac->phy_mode) {
@@ -191,9 +190,6 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
 
case PHY_INTERFACE_MODE_RGMII_ID:
case PHY_INTERFACE_MODE_RGMII_TXID:
-   /* Generate a 25MHz clock for the PHY */
-   clk_rate = 25 * 1000 * 1000;
-
/* enable RGMII mode */
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_RGMII_MODE,
PRG_ETH0_RGMII_MODE);
@@ -204,12 +200,24 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac 
*dwmac)
 
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TXDLY_MASK,
tx_dly_val << PRG_ETH0_TXDLY_SHIFT);
+
+   ret = clk_prepare_enable(dwmac->m25_div_clk);
+   if (ret) {
+   dev_err(>pdev->dev, "failed to enable the PHY 
clock\n");
+   return ret;
+   }
+
+   /* Generate the 25MHz RGMII clock for the PHY */
+   ret = clk_set_rate(dwmac->m25_div_clk, 25 * 1000 * 1000);
+   if (ret) {
+   clk_disable_unprepare(dwmac->m25_div_clk);
+
+   dev_err(>pdev->dev, "failed to set PHY clock\n");
+   return ret;
+   }
break;
 
case PHY_INTERFACE_MODE_RMII:
-   /* Use the rate of the mux clock for the internal RMII PHY */
-   clk_rate = clk_get_rate(dwmac->m250_mux_clk);
-
/* disable RGMII mode -> enables RMII mode */
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_RGMII_MODE,
0);
@@ -231,20 +239,6 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac 
*dwmac)
return -EINVAL;
}
 
-   ret = clk_prepare_enable(dwmac->m25_div_clk);
-   if (ret) {
-   dev_err(>pdev->dev, "failed to enable the PHY clock\n");
-   return ret;
-   }
-
-   ret = clk_set_rate(dwmac->m25_div_clk, clk_rate);
-   if (ret) {
-   clk_disable_unprepare(dwmac->m25_div_clk);
-
-   dev_err(>pdev->dev, "failed to set PHY clock\n");
-   return ret;
-   }
-
/* enable TX_CLK and PHY_REF_CLK generator */
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TX_AND_PHY_REF_CLK,
PRG_ETH0_TX_AND_PHY_REF_CLK);
@@ -294,7 +288,7 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
 >tx_delay_ns))
dwmac->tx_delay_ns = 2;
 
-   ret = meson8b_init_clk(dwmac);
+   ret = meson8b_init_rgmii_clk(dwmac);
if (ret)
goto err_remove_config_dt;
 
@@ -311,7 +305,8 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
return 0;
 
 err_clk_disable:
-   clk_disable_unprepare(dwmac->m25_div_clk);
+   if (phy_interface_mode_is_rgmii(dwmac->phy_mode))
+   clk_disable_unprepare(dwmac->m25_div_clk);
 err_remove_config_dt:
stmmac_remove_config_dt(pdev, plat_dat);
 
@@ -322,7 +317,8 @@ static int meson8b_dwmac_remove(struct platform_device 
*pdev)
 {
struct meson8b_dwmac *dwmac = get_stmmac_bsp_priv(>dev);
 
-   

[RFT net-next v2 0/3] dwmac-meson8b: RGMII clock fixes for Meson8b

2017-12-23 Thread Martin Blumenstingl
Hi Dave,

please do not apply this series until it got a Tested-by from Emiliano.


Hi Emiliano,

you reported [0] that you couldn't get dwmac-meson8b to work on your
Odroid-C1. With your findings (register dumps, clk_summary output, etc.)
I think I was able to find a fix: it consists of two patches (which you
find in this series)

Unfortunately I don't have any Meson8b boards with RGMII PHY so I could
only partially test this (I could only check if the clocks were
calculated correctly when using a dummy 52394Hz input clock instead
of MPLL2).

Could you please give this series a try and let me know about the
results?
You obviously still need your two "ARM: dts: meson8b" patches which
- add the amlogic,meson8b-dwmac" compatible to meson8b.dtsi
- enable Ethernet on the Odroid-C1

I have tested this myself on a Khadas VIM (GXL SoC, internal RMII PHY)
and a Khadas VIM2 (GXM SoC, external RGMII PHY). Both are still working
fine (so let's hope that this also fixes your Meson8b issue :)).


changes since v1 at [1]:
- changed the subject of the cover-letter to indicate that this is all
  about the RGMII clock
- added PATCH #1 which ensures that we don't unnecessarily change the
  parent clocks in RMII mode (and also makes the code easier to
  understand)
- changed subject of PATCH #2 (formerly PATCH #1) to state that this
  is about the RGMII clock
- added Jerome's Reviewed-by to PATCH #2 (formerly PATCH #1)
- replaced PATCH #3 (formerly PATCH #2) with one that sets
  CLK_SET_RATE_PARENT on the mux and thus re-configures the MPLL2 clock
  on Meson8b correctly


[0] http://lists.infradead.org/pipermail/linux-amlogic/2017-December/005596.html
[1] http://lists.infradead.org/pipermail/linux-amlogic/2017-December/005848.html


Martin Blumenstingl (3):
  net: stmmac: dwmac-meson8b: only configure the clocks in RGMII mode
  net: stmmac: dwmac-meson8b: fix setting the RGMII clock on Meson8b
  net: stmmac: dwmac-meson8b: propagate rate changes to the parent clock

 .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c| 55 +++---
 1 file changed, 27 insertions(+), 28 deletions(-)

-- 
2.15.1



[RFT net-next v2 2/3] net: stmmac: dwmac-meson8b: fix setting the RGMII clock on Meson8b

2017-12-23 Thread Martin Blumenstingl
Meson8b only supports MPLL2 as clock input. The rate of the MPLL2 clock
set by Odroid-C1's u-boot is close to 500MHz. The exact rate is
52394Hz, which is calculated in drivers/clk/meson/clk-mpll.c
using the following formula:
DIV_ROUND_UP_ULL((u64)parent_rate * SDM_DEN, (SDM_DEN * n2) + sdm)
Odroid-C1's u-boot configures MPLL2 with the following values:
- SDM_DEN = 16384
- SDM = 1638
- N2 = 5

The 250MHz and 25MHz clocks inside dwmac-meson8b driver are derived
from the MPLL2 clock. Due to MPLL2 running slightly faster than 500MHz
the common clock framework chooses dividers which are too big to
generate the 250MHz and 25MHz clocks. Emiliano Ingrassia observed that
the divider for the 250MHz clock was set to 0x5 which results in a clock
rate of close to 100MHz instead of 250MHz. The divider for the 25MHz
clock is set to 0x0 (which means "divide by 5") so the resulting RGMII
clock is running at 20MHz (plus a few additional Hz). The RTL8211F PHY
on Odroid-C1 however fails to operate with a 20MHz RGMII clock.

Round the divider's clock rates to prevent this issue on Meson8b. This
means we'll now end up with a clock rate of 25000120Hz (= 25MHz plus
120Hz).
This has no effect on the Meson GX SoCs since there fclk_div2 is used as
input clock, which has a rate of 1000MHz (and thus is divisible cleanly
to 250MHz and 25MHz).

Fixes: 566e8251625304 ("net: stmmac: add a glue driver for the Amlogic Meson 8b 
/ GXBB DWMAC")
Reported-by: Emiliano Ingrassia <ingras...@epigenesys.com>
Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
Reviewed-by: Jerome Brunet <jbru...@baylibre.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index e1d5907e481c..0da551c84fe8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -144,7 +144,9 @@ static int meson8b_init_rgmii_clk(struct meson8b_dwmac 
*dwmac)
dwmac->m250_div.shift = PRG_ETH0_CLK_M250_DIV_SHIFT;
dwmac->m250_div.width = PRG_ETH0_CLK_M250_DIV_WIDTH;
dwmac->m250_div.hw.init = 
-   dwmac->m250_div.flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO;
+   dwmac->m250_div.flags = CLK_DIVIDER_ONE_BASED |
+   CLK_DIVIDER_ALLOW_ZERO |
+   CLK_DIVIDER_ROUND_CLOSEST;
 
dwmac->m250_div_clk = devm_clk_register(dev, >m250_div.hw);
if (WARN_ON(IS_ERR(dwmac->m250_div_clk)))
@@ -164,7 +166,8 @@ static int meson8b_init_rgmii_clk(struct meson8b_dwmac 
*dwmac)
dwmac->m25_div.width = PRG_ETH0_CLK_M25_DIV_WIDTH;
dwmac->m25_div.table = clk_25m_div_table;
dwmac->m25_div.hw.init = 
-   dwmac->m25_div.flags = CLK_DIVIDER_ALLOW_ZERO;
+   dwmac->m25_div.flags = CLK_DIVIDER_ALLOW_ZERO |
+   CLK_DIVIDER_ROUND_CLOSEST;
 
dwmac->m25_div_clk = devm_clk_register(dev, >m25_div.hw);
if (WARN_ON(IS_ERR(dwmac->m25_div_clk)))
-- 
2.15.1



Re: [RFT net-next 2/2] net: stmmac: dwmac-meson8b: don't try to change m250_div parent's rate

2017-12-23 Thread Martin Blumenstingl
On Sat, Dec 23, 2017 at 11:41 PM, Jerome Brunet <jbru...@baylibre.com> wrote:
> On Sat, 2017-12-23 at 22:49 +0100, Martin Blumenstingl wrote:
>> while calculating this with a target frequency of 500MHz manually
>> again I saw that there's a remainder of 10Mhz after the initial
>> division.
>> remainder * SDM_DEN = 16384000 - this value overflows 32-bit,
>> things will go downhill from here... :)
>> long story short: here's a patch for that issue: [0]
>
> Thanks for the fix !
>
>>
>> the results with "CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT" on the mux:
>
> Actually, I don't think you need the CLK_SET_RATE_NO_REPARENT
as I have to re-test this on the GX SoCs anyways I'll give it a go
without CLK_SET_RATE_NO_REPARENT. stay tuned...

>> fixed_pll 33  255000
>>0 0
>>   mpll2  11   124999851
>>   0 0
>>  c941.ethernet#m250_sel   11
>> 124999851  0 0
>> c941.ethernet#m250_div   11
>> 124999851  0 0
>>c941.ethernet#m25_div   11
>> 2471  0 0
>>
>> this is even closer to 25MHz than the values in the vendor driver
>> (120Hz vs 29Hz)
>> I'll re-spin this series, then Emiliano "just" has to confirm that
>> it's also working for him (despite the dividers in the dwmac-meson8b
>> driver are set up different compared to the vendor driver)
>
> if the rate of the parent clock of mux may change, I think following part 
> should
> be changed as well
>
> case PHY_INTERFACE_MODE_RMII:
> /* Use the rate of the mux clock for the internal RMII PHY */
> clk_rate = clk_get_rate(dwmac->m250_mux_clk);
>
> I think it is a bit weak anyway, as it depends on the initial settings. Do you
> remember why you wrote this way ?
actually this is confusing and a no-op: I'll have to fix it with a
re-spin of this series anyways.

while trying to make sense why Ethernet wouldn't work on Emiliano's
Odroid-C1 I stumbled across this header: [0]
it explains why it doesn't matter which values are set for the
mux/dividers in RMII mode: the clocks are used to generate the "RGMII
clock"
the currrent code is a no-op since the common clock framework sets all
dividers in PRG_ETH0 to 0 - which results in a register value of
0x1800 (which used by the vendor driver for RMII)

I will add a patch which ignores the clocks in RMII mode: this is also
needed because we don't want to configure MPLL2 on Meson8b in RMII
mode

>>
>> > > - according to the datasheet the allowed range of the mpll2 clock is
>> > > 250..637MHz - 127488329Hz is what we get from the common clock
>> > > framework
>> >
>> > Yes, I've seen that but we are able compute out of that range and, so far, 
>> > the
>> > actual rate of clock seems coherent with the calculation. At least, when I
>> > tested with the audio, it was the case.
>>
>> I'm curious: ...on a GX SoCs probably?
>
> Indeed, you got me !
good to know - I'll try to keep the 32-bit overflow issues in mind
when things don't work on Meson8/Meson8b even if they do work on the
GX SoCs


Regards
Martin

[0] 
https://github.com/endlessm/u-boot-meson/blob/345ee7eb02903f5ecb1173ffb2cd3e44ebed/arch/arm/include/asm/arch-m8b/aml_eth_reg.h#L489


Re: [RFT net-next 2/2] net: stmmac: dwmac-meson8b: don't try to change m250_div parent's rate

2017-12-23 Thread Martin Blumenstingl
Hi Jerome,

On Sat, Dec 23, 2017 at 9:40 PM, Jerome Brunet <jbru...@baylibre.com> wrote:
> On Sat, 2017-12-23 at 21:00 +0100, Martin Blumenstingl wrote:
>> Hi Jerome,
>>
>> On Sat, Dec 23, 2017 at 6:40 PM, Jerome Brunet <jbru...@baylibre.com> wrote:
>> > On Sat, 2017-12-23 at 18:04 +0100, Martin Blumenstingl wrote:
>> > > Trying to set the rate of m250_div's parent clock makes no sense since
>> > > it's a mux which has neither CLK_MUX_ROUND_CLOSEST nor
>> > > CLK_SET_RATE_PARENT set.
>> > > It even does harm on Meson8b SoCs where the input clock for the mux
>> > > cannot be divided down to 250MHz evenly (the parent rate is 52394Hz)
>> >
>> > So your problem is more with the mux actually, not the divider. Instead of
>> > removing CLK_SET_RATE_PARENT from the divider, may I suggest to put
>> >
>> > CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT on the parent mux, and keep
>> > CLK_SET_RATE_PARENT (with CLK_DIVIDER_ROUND_CLOSEST)  on the divS.
>>
>> I just gave this a try, here's the result:
>>mpll2  11   127488329
>>0 0
>>  c941.ethernet#m250_sel   11
>> 127488329  0 0
>> c941.ethernet#m250_div   11
>> 127488329  0 0
>>c941.ethernet#m25_div   11
>> 25497666  0 0
>>
>> > I suppose it would a accomplish the same thing with one added benefits for
>> > meson8b :
>> >
>> > If the bootloader did not set the mpll2 to the correct rate, it will now 
>> > be done
>> > thanks to rate propagation.
>>
>> indeed, mpll2 is set to 0 by the bootloader on my board
>> with that change we'll now also set the rate "correctly" (see below)
>>
>> > If I missed anything, feel free to point it out.
>>
>> it seems however that clk-mpll incorrectly calculates the register values
>> with the mpll2 register values from Emiliano we can get to 25000120Hz
>> however, I guess we need to have a look at the clk-mpll
>
> H ! not again ! ;)
>
>>  driver because:
>> - by letting the common clock framework set the rate of mpll2 we get
>> 25497666Hz (which means we're off by by ~500kHz, instead of 120Hz)
>
> Could you dump the SDM and N2 values (devmem) that have been applied by CCF ?
> to compare. If a better solution is available, I'm a bit surprised we don't 
> find
>  it. You may have a found something worth checking ...
while calculating this with a target frequency of 500MHz manually
again I saw that there's a remainder of 10Mhz after the initial
division.
remainder * SDM_DEN = 16384000 - this value overflows 32-bit,
things will go downhill from here... :)
long story short: here's a patch for that issue: [0]

the results with "CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT" on the mux:
fixed_pll 33  255000
   0 0
  mpll2  11   124999851
  0 0
 c941.ethernet#m250_sel   11
124999851  0 0
c941.ethernet#m250_div   11
124999851  0 0
   c941.ethernet#m25_div   11
2471  0 0

this is even closer to 25MHz than the values in the vendor driver
(120Hz vs 29Hz)
I'll re-spin this series, then Emiliano "just" has to confirm that
it's also working for him (despite the dividers in the dwmac-meson8b
driver are set up different compared to the vendor driver)

>> - according to the datasheet the allowed range of the mpll2 clock is
>> 250..637MHz - 127488329Hz is what we get from the common clock
>> framework
>
> Yes, I've seen that but we are able compute out of that range and, so far, the
> actual rate of clock seems coherent with the calculation. At least, when I
> tested with the audio, it was the case.
I'm curious: ...on a GX SoCs probably?

>>
>> Jerome: any idea why that is (more theoretical number games below though :))?
>>
>> just a reminder from the other patch - these are the values used for
>> the mpll2 clock:
>> - parent rate = 2550MHz
>> - SDM_DEN = 16384
>> - SDM = 1638
>> - N2 = 5
>> = (parent rate 255000 * SDM_DEN 16384) / ((SDM_DEN 16384 * N2 5) +
>> 1638) = 52394Hz
>>
>> using an SDM of 1639 gives us a 46410Hz mpll2 clock
>> with all the dividers we get down to a RGMII clock of 24999821Hz which
>> is 179Hz off the desired 25MHz
>> in other words: the mpll2 values set by

Re: [RFT net-next 2/2] net: stmmac: dwmac-meson8b: don't try to change m250_div parent's rate

2017-12-23 Thread Martin Blumenstingl
Hi Jerome,

On Sat, Dec 23, 2017 at 6:40 PM, Jerome Brunet <jbru...@baylibre.com> wrote:
> On Sat, 2017-12-23 at 18:04 +0100, Martin Blumenstingl wrote:
>> Trying to set the rate of m250_div's parent clock makes no sense since
>> it's a mux which has neither CLK_MUX_ROUND_CLOSEST nor
>> CLK_SET_RATE_PARENT set.
>> It even does harm on Meson8b SoCs where the input clock for the mux
>> cannot be divided down to 250MHz evenly (the parent rate is 52394Hz)
>
> So your problem is more with the mux actually, not the divider. Instead of
> removing CLK_SET_RATE_PARENT from the divider, may I suggest to put
>
> CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT on the parent mux, and keep
> CLK_SET_RATE_PARENT (with CLK_DIVIDER_ROUND_CLOSEST)  on the divS.
I just gave this a try, here's the result:
   mpll2  11   127488329
   0 0
 c941.ethernet#m250_sel   11
127488329  0 0
c941.ethernet#m250_div   11
127488329  0 0
   c941.ethernet#m25_div   11
25497666  0 0

> I suppose it would a accomplish the same thing with one added benefits for
> meson8b :
>
> If the bootloader did not set the mpll2 to the correct rate, it will now be 
> done
> thanks to rate propagation.
indeed, mpll2 is set to 0 by the bootloader on my board
with that change we'll now also set the rate "correctly" (see below)

> If I missed anything, feel free to point it out.
it seems however that clk-mpll incorrectly calculates the register values
with the mpll2 register values from Emiliano we can get to 25000120Hz
however, I guess we need to have a look at the clk-mpll driver because:
- by letting the common clock framework set the rate of mpll2 we get
25497666Hz (which means we're off by by ~500kHz, instead of 120Hz)
- according to the datasheet the allowed range of the mpll2 clock is
250..637MHz - 127488329Hz is what we get from the common clock
framework

Jerome: any idea why that is (more theoretical number games below though :))?

just a reminder from the other patch - these are the values used for
the mpll2 clock:
- parent rate = 2550MHz
- SDM_DEN = 16384
- SDM = 1638
- N2 = 5
= (parent rate 255000 * SDM_DEN 16384) / ((SDM_DEN 16384 * N2 5) +
1638) = 52394Hz

using an SDM of 1639 gives us a 46410Hz mpll2 clock
with all the dividers we get down to a RGMII clock of 24999821Hz which
is 179Hz off the desired 25MHz
in other words: the mpll2 values set by Odroid-C1's u-boot are "best",
so if we try to set mpll2's rate through the common clock framework we
should try to get the same results (else we would just make the result
worse)

> Cheers
>
>> which is why we need to use CLK_DIVIDER_ROUND_CLOSEST for the m250_div
>> clock. The clk-divider driver however ignores the
>> CLK_DIVIDER_ROUND_CLOSEST flag if CLK_SET_RATE_PARENT is set (because
>> it simply tries to set the best possible clock rate for the parent,
>> which does nothing in our case since the parent is a mux which doesn't
>> allow rate changes as explained above).
>>
>> This fixes setting the RGMII clock on Meson8 SoCs which ended up with a
>> ~20MHz clock instead of the expected ~25MHz.
>> The dwmac-meson8b driver requests a 25MHz clock rate for the m25_div
>> (which only supports "divide by 5" and "divide by 10") clock which is
>> derived from the m250_div clock. Due to clk-divider ignoring the
>> CLK_DIVIDER_ROUND_CLOSEST flag the resulting m250_div clock was set to
>> ~100MHz (divider = 5) and the m25_div clock was set to ~20MHz (divider =
>> 5) by the common clock framework (as this value is closest to 25MHz if
>> we would not have set CLK_DIVIDER_ROUND_CLOSEST). What we actually need
>> however is a rate of ~250MHz on the m250_div clock (divider = 2) and
>> ~25MHz on the m25_div clock (divider = 10) - these are also the values
>> chosen by the out-of-tree vendor driver.
>> With this we end up with a RGMII clock of 25000120Hz (which is as close
>> to 25MHz we can get with an input clock of 52394Hz).
>>
>> SoCs from the Meson GX series are not affected by this change because
>> the input clock is FCLK_DIV2 whose rate cannot be changed. Additionally
>> the GX SoCs don't need to use the "closest" divider since the parent
>> clock is a multiple of 250MHz.
>>
>> Fixes: 566e8251625304 ("net: stmmac: add a glue driver for the Amlogic Meson 
>> 8b / GXBB DWMAC")
>> Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
>> ---
>>  drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>

[RFT net-next 0/2] dwmac-meson8b: clock rounding fixes for Meson8b

2017-12-23 Thread Martin Blumenstingl
Hi Dave,

please do not apply this series until it got a Tested-by from Emiliano.


Hi Emiliano,

you reported [0] that you couldn't get dwmac-meson8b to work on your
Odroid-C1. With your findings (register dumps, clk_summary output, etc.)
I think I was able to find a fix: it consists of two patches (which you
find in this series)

Unfortunately I don't have any Meson8b boards with RGMII PHY so I could
only partially test this (I could only check if the clocks were
calculated correctly when using a dummy 52394Hz input clock instead
of MPLL2).

Could you please give this series a try and let me know about the
results?
You obviously still need your two "ARM: dts: meson8b" patches which
- add the amlogic,meson8b-dwmac" compatible to meson8b.dtsi
- enable Ethernet on the Odroid-C1

I have tested this myself on a Khadas VIM (GXL SoC, internal RMII PHY)
and a Khadas VIM2 (GXM SoC, external RGMII PHY). Both are still working
fine (so let's hope that this also fixes your Meson8b issue :)).


[0] http://lists.infradead.org/pipermail/linux-amlogic/2017-December/005596.html

Martin Blumenstingl (2):
  net: stmmac: dwmac-meson8b: fix setting the PHY clock on Meson8b
  net: stmmac: dwmac-meson8b: don't try to change m250_div parent's rate

 drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

-- 
2.15.1



[RFT net-next 1/2] net: stmmac: dwmac-meson8b: fix setting the PHY clock on Meson8b

2017-12-23 Thread Martin Blumenstingl
Meson8b only supports MPLL2 as clock input. The rate of the MPLL2 clock
set by Odroid-C1's u-boot is close to 500MHz. The exact rate is
52394Hz, which is calculated in drivers/clk/meson/clk-mpll.c
using the following formula:
DIV_ROUND_UP_ULL((u64)parent_rate * SDM_DEN, (SDM_DEN * n2) + sdm)
Odroid-C1's u-boot configures MPLL2 with the following values:
- SDM_DEN = 16384
- SDM = 1638
- N2 = 5

The 250MHz and 25MHz clocks inside dwmac-meson8b driver are derived
from the MPLL2 clock. Due to MPLL2 running slightly faster than 500MHz
the common clock framework chooses dividers which are too big to
generate the 250MHz and 25MHz clocks. Emiliano Ingrassia observed that
the divider for the 250MHz clock was set to 0x5 which results in a clock
rate of close to 100MHz instead of 250MHz. The divider for the 25MHz
clock is set to 0x0 (which means "divide by 5") so the resulting RGMII
clock is running at 20MHz (plus a few additional Hz). The RTL8211F PHY
on Odroid-C1 however fails to operate with a 20MHz RGMII clock.

Round the divider's clock rates to prevent this issue on Meson8b. This
means we'll now end up with a clock rate of 25000120Hz (= 25MHz plus
120Hz).
This has no effect on the Meson GX SoCs since there fclk_div2 is used as
input clock, which has a rate of 1000MHz (and thus is divisible cleanly
to 250MHz and 25MHz).

Fixes: 566e8251625304 ("net: stmmac: add a glue driver for the Amlogic Meson 8b 
/ GXBB DWMAC")
Reported-by: Emiliano Ingrassia <ingras...@epigenesys.com>
Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index 4404650b32c5..c71966332387 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -144,7 +144,9 @@ static int meson8b_init_clk(struct meson8b_dwmac *dwmac)
dwmac->m250_div.shift = PRG_ETH0_CLK_M250_DIV_SHIFT;
dwmac->m250_div.width = PRG_ETH0_CLK_M250_DIV_WIDTH;
dwmac->m250_div.hw.init = 
-   dwmac->m250_div.flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO;
+   dwmac->m250_div.flags = CLK_DIVIDER_ONE_BASED |
+   CLK_DIVIDER_ALLOW_ZERO |
+   CLK_DIVIDER_ROUND_CLOSEST;
 
dwmac->m250_div_clk = devm_clk_register(dev, >m250_div.hw);
if (WARN_ON(IS_ERR(dwmac->m250_div_clk)))
@@ -164,7 +166,8 @@ static int meson8b_init_clk(struct meson8b_dwmac *dwmac)
dwmac->m25_div.width = PRG_ETH0_CLK_M25_DIV_WIDTH;
dwmac->m25_div.table = clk_25m_div_table;
dwmac->m25_div.hw.init = 
-   dwmac->m25_div.flags = CLK_DIVIDER_ALLOW_ZERO;
+   dwmac->m25_div.flags = CLK_DIVIDER_ALLOW_ZERO |
+   CLK_DIVIDER_ROUND_CLOSEST;
 
dwmac->m25_div_clk = devm_clk_register(dev, >m25_div.hw);
if (WARN_ON(IS_ERR(dwmac->m25_div_clk)))
-- 
2.15.1



[RFT net-next 2/2] net: stmmac: dwmac-meson8b: don't try to change m250_div parent's rate

2017-12-23 Thread Martin Blumenstingl
Trying to set the rate of m250_div's parent clock makes no sense since
it's a mux which has neither CLK_MUX_ROUND_CLOSEST nor
CLK_SET_RATE_PARENT set.
It even does harm on Meson8b SoCs where the input clock for the mux
cannot be divided down to 250MHz evenly (the parent rate is 52394Hz)
which is why we need to use CLK_DIVIDER_ROUND_CLOSEST for the m250_div
clock. The clk-divider driver however ignores the
CLK_DIVIDER_ROUND_CLOSEST flag if CLK_SET_RATE_PARENT is set (because
it simply tries to set the best possible clock rate for the parent,
which does nothing in our case since the parent is a mux which doesn't
allow rate changes as explained above).

This fixes setting the RGMII clock on Meson8 SoCs which ended up with a
~20MHz clock instead of the expected ~25MHz.
The dwmac-meson8b driver requests a 25MHz clock rate for the m25_div
(which only supports "divide by 5" and "divide by 10") clock which is
derived from the m250_div clock. Due to clk-divider ignoring the
CLK_DIVIDER_ROUND_CLOSEST flag the resulting m250_div clock was set to
~100MHz (divider = 5) and the m25_div clock was set to ~20MHz (divider =
5) by the common clock framework (as this value is closest to 25MHz if
we would not have set CLK_DIVIDER_ROUND_CLOSEST). What we actually need
however is a rate of ~250MHz on the m250_div clock (divider = 2) and
~25MHz on the m25_div clock (divider = 10) - these are also the values
chosen by the out-of-tree vendor driver.
With this we end up with a RGMII clock of 25000120Hz (which is as close
to 25MHz we can get with an input clock of 52394Hz).

SoCs from the Meson GX series are not affected by this change because
the input clock is FCLK_DIV2 whose rate cannot be changed. Additionally
the GX SoCs don't need to use the "closest" divider since the parent
clock is a multiple of 250MHz.

Fixes: 566e8251625304 ("net: stmmac: add a glue driver for the Amlogic Meson 8b 
/ GXBB DWMAC")
Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index c71966332387..26f41c117d63 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -135,7 +135,7 @@ static int meson8b_init_clk(struct meson8b_dwmac *dwmac)
snprintf(clk_name, sizeof(clk_name), "%s#m250_div", dev_name(dev));
init.name = devm_kstrdup(dev, clk_name, GFP_KERNEL);
init.ops = _divider_ops;
-   init.flags = CLK_SET_RATE_PARENT;
+   init.flags = 0;
clk_div_parents[0] = __clk_get_name(dwmac->m250_mux_clk);
init.parent_names = clk_div_parents;
init.num_parents = ARRAY_SIZE(clk_div_parents);
-- 
2.15.1



[RfC net-next 3/3] net: phy: realtek: add more interrupt bits for RTL8211E and RTL8211F

2017-12-02 Thread Martin Blumenstingl
This documents a few more bits in the RTL821x_INER register for RTL8211E
and RTL8211F. These are added only to document them (as no public
datasheets are available for these PHYs), they are currently not used.

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 drivers/net/phy/realtek.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 961165d128d6..a793c35cbaae 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -24,7 +24,14 @@
 #define RTL821x_INER   0x12
 #define RTL8211B_INER_INIT 0x6400
 #define RTL8211E_INER_LINK_STATUS  BIT(10)
+#define RTL8211E_INER_ANEG_COMPLETED   BIT(11)
+#define RTL8211E_INER_PAGE_RECEIVEDBIT(12)
+#define RTL8211E_INER_ANEG_ERROR   BIT(15)
 #define RTL8211F_INER_LINK_STATUS  BIT(4)
+#define RTL8211F_INER_PHY_REGISTER_ACCESSIBLE  BIT(5)
+#define RTL8211F_INER_WOL_PME  BIT(7)
+#define RTL8211F_INER_ALDPS_STATE_CHANGE   BIT(9)
+#define RTL8211F_INER_JABBER   BIT(10)
 
 #define RTL821x_INSR   0x13
 
-- 
2.15.1



[RfC net-next 1/3] net: phy: realtek: add support for configuring the RX delay on RTL8211F

2017-12-02 Thread Martin Blumenstingl
On RTL8211F the RX delay can also be enabled/disabled.
The overall behavior of the RX delay is similar to the behavior of the
TX delay, which was already supported by the driver.

The RX delay (similar to the TX delay) may be enabled using hardware pin
strapping. If the MAC already configures the RX delay (if required) then
the RX delay generated by the RTL8211F PHY has to be turned off.

While here, update the comment regarding the TX delay why it has to be
enabled or disabled within the driver.
Also avoid code-duplication by extracting the code to mask/unmask bits
in a paged register into a new rtl8211x_page_mask_bits helper function.

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 drivers/net/phy/realtek.c | 55 ++-
 1 file changed, 45 insertions(+), 10 deletions(-)

diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 5416ec5af042..d4e7f249a4bc 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -32,7 +32,10 @@
 
 #define RTL8211F_INSR  0x1d
 
-#define RTL8211F_TX_DELAY  BIT(8)
+#define RTL8211F_RX_DELAY_REG  0x15
+#define RTL8211F_RX_DELAY_EN   BIT(3)
+#define RTL8211F_TX_DELAY_REG  0x11
+#define RTL8211F_TX_DELAY_EN   BIT(8)
 
 #define RTL8201F_ISR   0x1e
 #define RTL8201F_IER   0x13
@@ -74,6 +77,23 @@ static int rtl8211x_page_write(struct phy_device *phydev, 
u16 page,
return ret;
 }
 
+static int rtl8211x_page_mask_bits(struct phy_device *phydev, u16 page,
+  u16 address, u16 mask, u16 set)
+{
+   int ret;
+   u16 val;
+
+   ret = rtl8211x_page_read(phydev, page, address);
+   if (ret < 0)
+   return ret;
+
+   val = ret & 0x;
+   val &= ~mask;
+   val |= (set & mask);
+
+   return rtl8211x_page_write(phydev, page, address, val);
+}
+
 static int rtl8201_ack_interrupt(struct phy_device *phydev)
 {
int err;
@@ -160,20 +180,35 @@ static int rtl8211f_config_init(struct phy_device *phydev)
if (ret < 0)
return ret;
 
-   ret = rtl8211x_page_read(phydev, 0xd08, 0x11);
-   if (ret < 0)
-   return ret;
+   /*
+* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it.
+* this is needed because it can be enabled by pin strapping and
+* conflict with the TX-delay configured by the MAC.
+*/
+   if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+   phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
+   val = RTL8211F_TX_DELAY_EN;
+   else
+   val = 0;
 
-   val = ret & 0x;
+   ret = rtl8211x_page_mask_bits(phydev, 0xd08, RTL8211F_TX_DELAY_REG,
+ RTL8211F_TX_DELAY_EN, val);
+   if (ret)
+   return ret;
 
-   /* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
+   /*
+* enable RX-delay for rgmii-id and rgmii-rxid, otherwise disable it.
+* this is needed because it can be enabled by pin strapping and
+* conflict with the RX-delay configured by the MAC.
+*/
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
-   phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
-   val |= RTL8211F_TX_DELAY;
+   phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
+   val = RTL8211F_RX_DELAY_EN;
else
-   val &= ~RTL8211F_TX_DELAY;
+   val = 0;
 
-   ret = rtl8211x_page_write(phydev, 0xd08, 0x11, val);
+   ret = rtl8211x_page_mask_bits(phydev, 0xd08, RTL8211F_RX_DELAY_REG,
+ RTL8211F_RX_DELAY_EN, val);
if (ret)
return ret;
 
-- 
2.15.1



[RfC net-next 2/3] net: phy: realtek: configure the INTB pin on RTL8211F

2017-12-02 Thread Martin Blumenstingl
The interrupt pin on the RTL8211F PHY can be used in two different
modes:
INTB
- the default mode of the PHY
- interrupts can be configured through page 0xa42 register RTL821x_INER
- interrupts can be ACK'ed through RTL8211F_INSR
- it acts as a level-interrupt which is active low
- Wake-on-LAN "wakeup" status is available in RTL8211F_INSR bit 7

PMEB:
- special mode for Wake-on-LAN
- interrupts configured through page 0xa42 register RTL821x_INER are
  disabled
- it supports a "pulse low" waveform for the interrupt

For now we simply force the pin into INTB mode since the PHY driver does
not support Wake-on-LAN yet.

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 drivers/net/phy/realtek.c | 27 +--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index d4e7f249a4bc..961165d128d6 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -40,6 +40,9 @@
 #define RTL8201F_ISR   0x1e
 #define RTL8201F_IER   0x13
 
+#define RTL8211F_INTBCR0x16
+#define RTL8211F_INTBCR_INTB_PMEB  BIT(5)
+
 MODULE_DESCRIPTION("Realtek PHY driver");
 MODULE_AUTHOR("Johnson Leung");
 MODULE_LICENSE("GPL");
@@ -161,12 +164,32 @@ static int rtl8211e_config_intr(struct phy_device *phydev)
 
 static int rtl8211f_config_intr(struct phy_device *phydev)
 {
+   int err;
u16 val;
 
-   if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
+   if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
+   /*
+* The interrupt pin has two functions:
+* 0: INTB: it acts as interrupt pin which can be configured
+*through RTL821x_INER and the status can be read through
+*RTL8211F_INSR
+* 1: PMEB: a special "Power Management Event" mode for
+*Wake-on-LAN operation (with support for a "pulse low"
+*wave format). Interrupts configured through RTL821x_INER
+*will not work in this mode
+*
+* select INTB mode in the "INTB pin control" register to
+* ensure that the interrupt pin is in the correct mode.
+*/
+   err = rtl8211x_page_mask_bits(phydev, 0xd40, RTL8211F_INTBCR,
+ RTL8211F_INTBCR_INTB_PMEB, 0);
+   if (err)
+   return err;
+
val = RTL8211F_INER_LINK_STATUS;
-   else
+   } else {
val = 0;
+   }
 
return rtl8211x_page_write(phydev, 0xa42, RTL821x_INER, val);
 }
-- 
2.15.1



[RfC net-next 0/3] RTL8211F Ethernet PHY "documentation"

2017-12-02 Thread Martin Blumenstingl
A recent patch from Heiner made me curious if the RTL8211F part of
the realtek.c PHY driver is correct: [0]
I contacted Realtek and asked if we could get a datasheet for the
RTL8211F PHY. it seems that the full datasheet can only be obtained
with an NDA. however, the contact at Realtek kindly answered all
questions I had regarding the RTL8211F PHY (thank you very much
again!). I am not permitted to share the exact answers I received,
but I am allowed to put them into my own words.

This series is a result of the conversation with Realtek: the main
intention behind this series is to *document* the information I got.
I am not aware of any board which needs the RX delay, has a problem
with the INTB pin configuration or requires any of the additional
interrupts.

I only tested that these patches don't break existing functionality
on Khadas VIM2 board with RTL8211F PHY.

PS: I also received information about the RTL8211E PHY's RX and TX
delay configuration. however, I don't understand that part of the
datasheet so I did not add any #defines in patch #3. the datasheet
says that:
- TX delay is configured through bit 12 and bit 13 in register 0x1c
  in page 0xa4 (value 1 = enabled, 0 = disabled)
- RX delay is configured through bit 11 and bit 13 in register 0x1c
  in page 0xa4 (value 1 = enabled, 0 = disabled)
I don't have any board with a RTL8211E PHY, so I could not test this
part at all. thus I don't know why bit 13 is listed for both, RX and
TX delay.

I do not expect that this series is applied. if someone is interested
in testing this: it applies on top of my other series:
"Realtek Ethernet PHY driver improvements" [1]


[0] https://www.spinics.net/lists/netdev/msg41.html
[1] https://marc.info/?l=linux-netdev=151225151410593=2

Martin Blumenstingl (3):
  net: phy: realtek: add support for configuring the RX delay on
RTL8211F
  net: phy: realtek: configure the INTB pin on RTL8211F
  net: phy: realtek: add more interrupt bits for RTL8211E and RTL8211F

 drivers/net/phy/realtek.c | 89 ---
 1 file changed, 77 insertions(+), 12 deletions(-)

-- 
2.15.1



[PATCH net-next 2/5] net: phy: realtek: rename RTL821x_INER_INIT to RTL8211B_INER_INIT

2017-12-02 Thread Martin Blumenstingl
This macro is only used by the RTL8211B code. RTL8211E and RTL8211F both
use other bits to initialize the RTL821x_INER register.
No functional changes.

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 drivers/net/phy/realtek.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 9708aa9c58dd..59f0688e4d28 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -21,7 +21,7 @@
 #define RTL821x_PHYSR_DUPLEX   BIT(13)
 #define RTL821x_PHYSR_SPEEDGENMASK(15, 14)
 #define RTL821x_INER   0x12
-#define RTL821x_INER_INIT  0x6400
+#define RTL8211B_INER_INIT 0x6400
 #define RTL821x_INSR   0x13
 #define RTL821x_PAGE_SELECT0x1f
 #define RTL8211E_INER_LINK_STATUS  BIT(10)
@@ -92,7 +92,7 @@ static int rtl8211b_config_intr(struct phy_device *phydev)
 
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
err = phy_write(phydev, RTL821x_INER,
-   RTL821x_INER_INIT);
+   RTL8211B_INER_INIT);
else
err = phy_write(phydev, RTL821x_INER, 0);
 
-- 
2.15.1



[PATCH net-next 5/5] net: phy: realtek: add utility functions to read/write page addresses

2017-12-02 Thread Martin Blumenstingl
Realtek PHYs implement the concept of so-called "extension pages". The
reason for this is probably because these PHYs expose more registers
than available in the standard address range.
After all read/write operations on such a page are done the driver
should switch back to page 0 where the standard MII registers (such as
MII_BMCR) are available.

When referring to such a register the datasheets of RTL8211E and
RTL8211F always specify:
- the page / "ext. page" which has to be written to RTL821x_PAGE_SELECT
- an address (sometimes also called reg)

These new utility functions make the existing code easier to read since
it removes some duplication (switching back to page 0 is done within the
new helpers for example).

No functional changes are intended.

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 drivers/net/phy/realtek.c | 83 ++-
 1 file changed, 53 insertions(+), 30 deletions(-)

diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index d6868e8daaab..5416ec5af042 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -41,6 +41,39 @@ MODULE_DESCRIPTION("Realtek PHY driver");
 MODULE_AUTHOR("Johnson Leung");
 MODULE_LICENSE("GPL");
 
+static int rtl8211x_page_read(struct phy_device *phydev, u16 page, u16 address)
+{
+   int ret;
+
+   ret = phy_write(phydev, RTL821x_PAGE_SELECT, page);
+   if (ret)
+   return ret;
+
+   ret = phy_read(phydev, address);
+
+   /* restore to default page 0 */
+   phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
+
+   return ret;
+}
+
+static int rtl8211x_page_write(struct phy_device *phydev, u16 page,
+  u16 address, u16 val)
+{
+   int ret;
+
+   ret = phy_write(phydev, RTL821x_PAGE_SELECT, page);
+   if (ret)
+   return ret;
+
+   ret = phy_write(phydev, address, val);
+
+   /* restore to default page 0 */
+   phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
+
+   return ret;
+}
+
 static int rtl8201_ack_interrupt(struct phy_device *phydev)
 {
int err;
@@ -63,31 +96,21 @@ static int rtl8211f_ack_interrupt(struct phy_device *phydev)
 {
int err;
 
-   phy_write(phydev, RTL821x_PAGE_SELECT, 0xa43);
-   err = phy_read(phydev, RTL8211F_INSR);
-   /* restore to default page 0 */
-   phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
+   err = rtl8211x_page_read(phydev, 0xa43, RTL8211F_INSR);
 
return (err < 0) ? err : 0;
 }
 
 static int rtl8201_config_intr(struct phy_device *phydev)
 {
-   int err;
-
-   /* switch to page 7 */
-   phy_write(phydev, RTL821x_PAGE_SELECT, 0x7);
+   u16 val;
 
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
-   err = phy_write(phydev, RTL8201F_IER,
-   BIT(13) | BIT(12) | BIT(11));
+   val = BIT(13) | BIT(12) | BIT(11);
else
-   err = phy_write(phydev, RTL8201F_IER, 0);
+   val = 0;
 
-   /* restore to default page 0 */
-   phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
-
-   return err;
+   return rtl8211x_page_write(phydev, 0x7, RTL8201F_IER, val);
 }
 
 static int rtl8211b_config_intr(struct phy_device *phydev)
@@ -118,41 +141,41 @@ static int rtl8211e_config_intr(struct phy_device *phydev)
 
 static int rtl8211f_config_intr(struct phy_device *phydev)
 {
-   int err;
+   u16 val;
 
-   phy_write(phydev, RTL821x_PAGE_SELECT, 0xa42);
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
-   err = phy_write(phydev, RTL821x_INER,
-   RTL8211F_INER_LINK_STATUS);
+   val = RTL8211F_INER_LINK_STATUS;
else
-   err = phy_write(phydev, RTL821x_INER, 0);
-   phy_write(phydev, RTL821x_PAGE_SELECT, 0);
+   val = 0;
 
-   return err;
+   return rtl8211x_page_write(phydev, 0xa42, RTL821x_INER, val);
 }
 
 static int rtl8211f_config_init(struct phy_device *phydev)
 {
int ret;
-   u16 reg;
+   u16 val;
 
ret = genphy_config_init(phydev);
if (ret < 0)
return ret;
 
-   phy_write(phydev, RTL821x_PAGE_SELECT, 0xd08);
-   reg = phy_read(phydev, 0x11);
+   ret = rtl8211x_page_read(phydev, 0xd08, 0x11);
+   if (ret < 0)
+   return ret;
+
+   val = ret & 0x;
 
/* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
-   reg |= RTL8211F_TX_DELAY;
+   val |= RTL8211F_TX_DELAY;
else
-   reg &= ~RTL8211F_TX_DELAY;
+   val &= ~RTL8211F_TX_DELAY;
 
-   phy_write(phydev, 0x11, reg);
-   /* restore to default page 0 */
-   

[PATCH net-next 3/5] net: phy: realtek: group all register bit #defines for RTL821x_INER

2017-12-02 Thread Martin Blumenstingl
This simply moves all register bit #defines which describe the (PHY
specific) bits in the RTL821x_INER right below the RTL821x_INER register
definition. This makes it easier to spot which registers and bits belong
together.
No functional changes.

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 drivers/net/phy/realtek.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 59f0688e4d28..da263a92d6b1 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -20,13 +20,16 @@
 #define RTL821x_PHYSR  0x11
 #define RTL821x_PHYSR_DUPLEX   BIT(13)
 #define RTL821x_PHYSR_SPEEDGENMASK(15, 14)
+
 #define RTL821x_INER   0x12
 #define RTL8211B_INER_INIT 0x6400
+#define RTL8211E_INER_LINK_STATUS  BIT(10)
+#define RTL8211F_INER_LINK_STATUS  BIT(4)
+
 #define RTL821x_INSR   0x13
+
 #define RTL821x_PAGE_SELECT0x1f
-#define RTL8211E_INER_LINK_STATUS  BIT(10)
 
-#define RTL8211F_INER_LINK_STATUS  BIT(4)
 #define RTL8211F_INSR  0x1d
 #define RTL8211F_TX_DELAY  BIT(8)
 
-- 
2.15.1



[PATCH net-next 0/5] Realtek Ethernet PHY driver improvements

2017-12-02 Thread Martin Blumenstingl
This series provides some small improvements and cleanups for the
Realtek Ethernet PHY driver.
None of the patches in this series should change any functionality.
The goal is to make the code a bit easier to read by:
- re-using the BIT and GENMASK macros (which makes it easier to compare
  the #defines in the kernel with the values from the datasheets)
- rename a #define from a generic name to a PHY-specific name since it's
  only used for one specific PHY
- logically group the register #defines and their register bit #defines
  together
- indentation cleanups
- removed some code duplicating for reading/writing registers on a
  Realtek specific "page"


Martin Blumenstingl (5):
  net: phy: realtek: use the BIT and GENMASK macros
  net: phy: realtek: rename RTL821x_INER_INIT to RTL8211B_INER_INIT
  net: phy: realtek: group all register bit #defines for RTL821x_INER
  net: phy: realtek: use the same indentation for all #defines
  net: phy: realtek: add utility functions to read/write page addresses

 drivers/net/phy/realtek.c | 116 --
 1 file changed, 72 insertions(+), 44 deletions(-)

-- 
2.15.1



[PATCH net-next 4/5] net: phy: realtek: use the same indentation for all #defines

2017-12-02 Thread Martin Blumenstingl
This simply makes the code easier to read. No functional changes.

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 drivers/net/phy/realtek.c | 27 ++-
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index da263a92d6b1..d6868e8daaab 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -17,24 +17,25 @@
 #include 
 #include 
 
-#define RTL821x_PHYSR  0x11
-#define RTL821x_PHYSR_DUPLEX   BIT(13)
-#define RTL821x_PHYSR_SPEEDGENMASK(15, 14)
+#define RTL821x_PHYSR  0x11
+#define RTL821x_PHYSR_DUPLEX   BIT(13)
+#define RTL821x_PHYSR_SPEEDGENMASK(15, 14)
 
-#define RTL821x_INER   0x12
-#define RTL8211B_INER_INIT 0x6400
-#define RTL8211E_INER_LINK_STATUS  BIT(10)
-#define RTL8211F_INER_LINK_STATUS  BIT(4)
+#define RTL821x_INER   0x12
+#define RTL8211B_INER_INIT 0x6400
+#define RTL8211E_INER_LINK_STATUS  BIT(10)
+#define RTL8211F_INER_LINK_STATUS  BIT(4)
 
-#define RTL821x_INSR   0x13
+#define RTL821x_INSR   0x13
 
-#define RTL821x_PAGE_SELECT0x1f
+#define RTL821x_PAGE_SELECT0x1f
 
-#define RTL8211F_INSR  0x1d
-#define RTL8211F_TX_DELAY  BIT(8)
+#define RTL8211F_INSR  0x1d
 
-#define RTL8201F_ISR   0x1e
-#define RTL8201F_IER   0x13
+#define RTL8211F_TX_DELAY  BIT(8)
+
+#define RTL8201F_ISR   0x1e
+#define RTL8201F_IER   0x13
 
 MODULE_DESCRIPTION("Realtek PHY driver");
 MODULE_AUTHOR("Johnson Leung");
-- 
2.15.1



[PATCH net-next 1/5] net: phy: realtek: use the BIT and GENMASK macros

2017-12-02 Thread Martin Blumenstingl
This makes it easier to compare the #defines with the datasheets.
No functional changes.

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 drivers/net/phy/realtek.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index eda0a6e86918..9708aa9c58dd 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -13,21 +13,22 @@
  * option) any later version.
  *
  */
+#include 
 #include 
 #include 
 
 #define RTL821x_PHYSR  0x11
-#define RTL821x_PHYSR_DUPLEX   0x2000
-#define RTL821x_PHYSR_SPEED0xc000
+#define RTL821x_PHYSR_DUPLEX   BIT(13)
+#define RTL821x_PHYSR_SPEEDGENMASK(15, 14)
 #define RTL821x_INER   0x12
 #define RTL821x_INER_INIT  0x6400
 #define RTL821x_INSR   0x13
 #define RTL821x_PAGE_SELECT0x1f
-#define RTL8211E_INER_LINK_STATUS 0x400
+#define RTL8211E_INER_LINK_STATUS  BIT(10)
 
-#define RTL8211F_INER_LINK_STATUS 0x0010
+#define RTL8211F_INER_LINK_STATUS  BIT(4)
 #define RTL8211F_INSR  0x1d
-#define RTL8211F_TX_DELAY  0x100
+#define RTL8211F_TX_DELAY  BIT(8)
 
 #define RTL8201F_ISR   0x1e
 #define RTL8201F_IER   0x13
-- 
2.15.1



Re: [PATCH] net: phy: realtek: fix RTL8211F interrupt mode

2017-12-02 Thread Martin Blumenstingl
Hi Heiner,

On Sun, Nov 12, 2017 at 4:16 PM, Heiner Kallweit  wrote:
> After commit b94d22d94ad22 "ARM64: dts: meson-gx: add external PHY
> interrupt on some platforms" ethernet stopped working on my Odroid-C2
> which has a RTL8211F phy.
>
> It turned out that no interrupts were triggered. Further analysis
> showed the register INER can't be altered on page 0.
> Because register INSR needs to be accessed via page 0xa43 I assumed
> that register INER needs to be accessed via some page too.
> Some brute force check resulted in page 0xa42 being the right one.
unfortunately there's no public datasheet for the RTL8211F.
I contacted Realtek to see if we could get a datasheet. unfortunately
an NDA is required for that
however, they were kind enough to share some information from the
RTL8211F datasheet with me

RTL821x_INER is called INER (Interrupt Enable Register) in the datasheet.
it is located at page 0xa42, address (the register after selecting the
page) 0x12 (RTL821x_INER is also 0x12)

in other words: your findings were correct!
(I know that my mail is too late to make it into the commit message -
but with this mail it's "documented" online now)

RTL8211E also uses RTL821x_INER (0x12) register, but according to the
information I got from Realtek it is located in page 0x0 (so no
special page has to be selected before changing that register on
RTL8211E)


Regards
Martin


[PATCH net] mdio: mux: fix parsing mux registers outside of the PHY address range

2017-07-10 Thread Martin Blumenstingl
mdio_mux_init parses the child nodes of the MDIO mux. When using
"mdio-mux-mmioreg" the child nodes are describing the register value
that is written to switch between the MDIO busses.

The change which makes the error messages more verbose changed the
parsing of the "reg" property from a simple of_property_read_u32 call
to of_mdio_parse_addr. On a Khadas VIM (based on the Meson GXL SoC,
which uses mdio-mux-mmioreg) this prevents registering the MDIO mux
(because the "reg" values on the MDIO mux child nodes are 0x2009087f
and 0xe40908ff) and leads to the following errors:
  mdio-mux-mmioreg c883455c.eth-phy-mux: 
/soc/periphs@c8834000/eth-phy-mux/mdio@e40908ff PHY address -469169921 is too 
large
  mdio-mux-mmioreg c883455c.eth-phy-mux: Error: Failed to find reg for child 
/soc/periphs@c8834000/eth-phy-mux/mdio@e40908ff
  mdio-mux-mmioreg c883455c.eth-phy-mux: 
/soc/periphs@c8834000/eth-phy-mux/mdio@2009087f PHY address 537462911 is too 
large
  mdio-mux-mmioreg c883455c.eth-phy-mux: Error: Failed to find reg for child 
/soc/periphs@c8834000/eth-phy-mux/mdio@2009087f
  mdio-mux-mmioreg c883455c.eth-phy-mux: Error: No acceptable child buses found
  mdio-mux-mmioreg c883455c.eth-phy-mux: failed to register mdio-mux bus 
/soc/periphs@c8834000/eth-phy-mux
(as a result of that ethernet is not working, because the PHY which is
connected through the mux' child MDIO bus, which is not being
registered).

Fix this by reverting the change from of_mdio_parse_addr to
of_mdio_parse_addr.

Fixes: 342fa1964439 ("mdio: mux: make child bus walking more permissive and 
errors more verbose")
Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 drivers/net/phy/mdio-mux.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/mdio-mux.c b/drivers/net/phy/mdio-mux.c
index 00755b6a42cf..c608e1dfaf09 100644
--- a/drivers/net/phy/mdio-mux.c
+++ b/drivers/net/phy/mdio-mux.c
@@ -135,8 +135,8 @@ int mdio_mux_init(struct device *dev,
for_each_available_child_of_node(dev->of_node, child_bus_node) {
int v;
 
-   v = of_mdio_parse_addr(dev, child_bus_node);
-   if (v < 0) {
+   r = of_property_read_u32(child_bus_node, "reg", );
+   if (r) {
dev_err(dev,
"Error: Failed to find reg for child %s\n",
of_node_full_name(child_bus_node));
-- 
2.13.2



Re: [PATCH 1/1] dt-binding: net: wireless: fix node name in the BCM43xx example

2017-05-16 Thread Martin Blumenstingl
Hi Arend,

On Tue, May 16, 2017 at 12:05 AM, Arend Van Spriel
<arend.vanspr...@broadcom.com> wrote:
> On 15-5-2017 22:13, Martin Blumenstingl wrote:
>> The example in the BCM43xx documentation uses "brcmf" as node name.
>> However, wireless devices should be named "wifi" instead. Fix this to
>
> Hi Martin,
>
> Since when is that a rule. I never got the memo and the DTC did not ever
> complain to me about the naming. That being said I do not really care
> and I suppose it is for the sake of consistency only.
I'm not sure if it's actually a rule or (as you already noted) just
for consistency. back when I added devicetree support to ath9k Rob
pointed out that the node should be named "wifi" (instead of "ath9k"),
see [0]

>> make sure that .dts authors can simply use the documentation as
>> reference (or simply copy the node from the documentation and then
>> adjust only the board specific bits).
>
> Please feel free to add my...
>
> Acked-by: Arend van Spriel <arend.vanspr...@broadcom.com>
thank you!

@Rob: maybe you can ACK this as well if you're fine with this patch?

>> Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
>> ---
>>  Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git 
>> a/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt 
>> b/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt
>> index 5dbf169cd81c..590f622188de 100644
>> --- a/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt
>> +++ b/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt
>> @@ -31,7 +31,7 @@ mmc3: mmc@01c12000 {
>>   non-removable;
>>   status = "okay";
>>
>> - brcmf: bcrmf@1 {
>> + brcmf: wifi@1 {
>>   reg = <1>;
>>   compatible = "brcm,bcm4329-fmac";
>>   interrupt-parent = <>;
>>

[0] http://www.mail-archive.com/ath9k-devel@lists.ath9k.org/msg14678.html


[PATCH 1/1] dt-binding: net: wireless: fix node name in the BCM43xx example

2017-05-15 Thread Martin Blumenstingl
The example in the BCM43xx documentation uses "brcmf" as node name.
However, wireless devices should be named "wifi" instead. Fix this to
make sure that .dts authors can simply use the documentation as
reference (or simply copy the node from the documentation and then
adjust only the board specific bits).

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git 
a/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt 
b/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt
index 5dbf169cd81c..590f622188de 100644
--- a/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt
+++ b/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt
@@ -31,7 +31,7 @@ mmc3: mmc@01c12000 {
non-removable;
status = "okay";
 
-   brcmf: bcrmf@1 {
+   brcmf: wifi@1 {
reg = <1>;
compatible = "brcm,bcm4329-fmac";
interrupt-parent = <>;
-- 
2.13.0



[PATCH 0/1] fix node name in the brcm,bcm43xx-fmac.txt example

2017-05-15 Thread Martin Blumenstingl
recently there were some negative comments about the quality of
code-reviews for new .dts additions. one issue that came up was that the
node for the Broadcom FullMAC wireless SDIO devices was named "brcmf"
instead of "wifi".

This patch tries to fix (one of) the root cause(s), which is that .dts
authors copy the example from the documentation.
unfortunately there are still many .dts files out there which use
"brmcf" as node name - so any new addition of a Broadcom FullMAC SDIO
wireless device should be reviewed carefully regarding the node name
(just in case a .dts author copied from another .dts which still uses
the "wrong" node name).

Martin Blumenstingl (1):
  dt-binding: net: wireless: fix node name in the BCM43xx example

 Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

-- 
2.13.0



Re: [PATCH] net: stmmac: don't set tx delay in RGMII_ID and RGMII_TXID mode

2017-02-03 Thread Martin Blumenstingl
On Wed, Feb 1, 2017 at 8:19 PM, Heiner Kallweit <hkallwe...@gmail.com> wrote:
> As documented in Documentation/devicetree/bindings/net/ethernet.txt,
> in RGMII_ID and RGMII_TXID mode the MAC should not add a tx delay.
>
> Signed-off-by: Heiner Kallweit <hkallwe...@gmail.com>
Acked-by: Martin Blumenstingl <martin.blumensti...@googlemail.com"

> ---
>  drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 16 +---
>  1 file changed, 9 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
> b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
> index 8840a360..9689 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
> @@ -177,12 +177,19 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac 
> *dwmac)
>  {
> int ret;
> unsigned long clk_rate;
> -   u8 tx_dly_val;
> +   u8 tx_dly_val = 0;
>
> switch (dwmac->phy_mode) {
> case PHY_INTERFACE_MODE_RGMII:
> -   case PHY_INTERFACE_MODE_RGMII_ID:
> case PHY_INTERFACE_MODE_RGMII_RXID:
> +   /* TX clock delay in ns = "8ns / 4 * tx_dly_val" (where
> +* 8ns are exactly one cycle of the 125MHz RGMII TX clock):
> +* 0ns = 0x0, 2ns = 0x1, 4ns = 0x2, 6ns = 0x3
> +*/
> +   tx_dly_val = dwmac->tx_delay_ns >> 1;
> +   /* fall through */
> +
> +   case PHY_INTERFACE_MODE_RGMII_ID:
> case PHY_INTERFACE_MODE_RGMII_TXID:
> /* Generate a 25MHz clock for the PHY */
> clk_rate = 25 * 1000 * 1000;
> @@ -195,11 +202,6 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac 
> *dwmac)
> meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
> PRG_ETH0_INVERTED_RMII_CLK, 0);
>
> -   /* TX clock delay in ns = "8ns / 4 * tx_dly_val" (where
> -* 8ns are exactly one cycle of the 125MHz RGMII TX clock):
> -* 0ns = 0x0, 2ns = 0x1, 4ns = 0x2, 6ns = 0x3
> -*/
> -   tx_dly_val = dwmac->tx_delay_ns >> 1;
> meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TXDLY_MASK,
> tx_dly_val << PRG_ETH0_TXDLY_SHIFT);
> break;
> --
> 2.11.0
>
Heiner, many thanks for this and your other patches!


[PATCH net-next v5 2/2] net: stmmac: dwmac-meson8b: make the RGMII TX delay configurable

2017-01-22 Thread Martin Blumenstingl
Prior to this patch we were using a hardcoded RGMII TX clock delay of
2ns (= 1/4 cycle of the 125MHz RGMII TX clock). This value works for
many boards, but unfortunately not for all (due to the way the actual
circuit is designed, sometimes because the TX delay is enabled in the
PHY, etc.). Making the TX delay on the MAC side configurable allows us
to support all possible hardware combinations.

This allows fixing a compatibility issue on some boards, where the
RTL8211F PHY is configured to generate the TX delay. We can now turn
off the TX delay in the MAC, because otherwise we would be applying the
delay twice (which results in non-working TX traffic).

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
Tested-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 20 ++--
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index ffaed1f35efe..8840a360a0b7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -35,10 +35,6 @@
 
 #define PRG_ETH0_TXDLY_SHIFT   5
 #define PRG_ETH0_TXDLY_MASKGENMASK(6, 5)
-#define PRG_ETH0_TXDLY_OFF (0x0 << PRG_ETH0_TXDLY_SHIFT)
-#define PRG_ETH0_TXDLY_QUARTER (0x1 << PRG_ETH0_TXDLY_SHIFT)
-#define PRG_ETH0_TXDLY_HALF(0x2 << PRG_ETH0_TXDLY_SHIFT)
-#define PRG_ETH0_TXDLY_THREE_QUARTERS  (0x3 << PRG_ETH0_TXDLY_SHIFT)
 
 /* divider for the result of m250_sel */
 #define PRG_ETH0_CLK_M250_DIV_SHIFT7
@@ -69,6 +65,8 @@ struct meson8b_dwmac {
 
struct clk_divider  m25_div;
struct clk  *m25_div_clk;
+
+   u32 tx_delay_ns;
 };
 
 static void meson8b_dwmac_mask_bits(struct meson8b_dwmac *dwmac, u32 reg,
@@ -179,6 +177,7 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
 {
int ret;
unsigned long clk_rate;
+   u8 tx_dly_val;
 
switch (dwmac->phy_mode) {
case PHY_INTERFACE_MODE_RGMII:
@@ -196,9 +195,13 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac 
*dwmac)
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
PRG_ETH0_INVERTED_RMII_CLK, 0);
 
-   /* TX clock delay - all known boards use a 1/4 cycle delay */
+   /* TX clock delay in ns = "8ns / 4 * tx_dly_val" (where
+* 8ns are exactly one cycle of the 125MHz RGMII TX clock):
+* 0ns = 0x0, 2ns = 0x1, 4ns = 0x2, 6ns = 0x3
+*/
+   tx_dly_val = dwmac->tx_delay_ns >> 1;
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TXDLY_MASK,
-   PRG_ETH0_TXDLY_QUARTER);
+   tx_dly_val << PRG_ETH0_TXDLY_SHIFT);
break;
 
case PHY_INTERFACE_MODE_RMII:
@@ -284,6 +287,11 @@ static int meson8b_dwmac_probe(struct platform_device 
*pdev)
goto err_remove_config_dt;
}
 
+   /* use 2ns as fallback since this value was previously hardcoded */
+   if (of_property_read_u32(pdev->dev.of_node, "amlogic,tx-delay-ns",
+>tx_delay_ns))
+   dwmac->tx_delay_ns = 2;
+
ret = meson8b_init_clk(dwmac);
if (ret)
goto err_remove_config_dt;
-- 
2.11.0



[PATCH net-next v5 1/2] net: dt-bindings: add RGMII TX delay configuration to meson8b-dwmac

2017-01-22 Thread Martin Blumenstingl
This allows configuring the RGMII TX clock delay. The RGMII clock is
generated by underlying hardware of the the Meson 8b / GXBB DWMAC glue.
The configuration depends on the actual hardware (no delay may be
needed due to the design of the actual circuit, the PHY might add this
delay, etc.).

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
Tested-by: Neil Armstrong <narmstr...@baylibre.com>
Acked-by: Rob Herring <r...@kernel.org>
---
 Documentation/devicetree/bindings/net/meson-dwmac.txt | 16 
 1 file changed, 16 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/meson-dwmac.txt 
b/Documentation/devicetree/bindings/net/meson-dwmac.txt
index 89e62ddc69ca..0703ad3f3c1e 100644
--- a/Documentation/devicetree/bindings/net/meson-dwmac.txt
+++ b/Documentation/devicetree/bindings/net/meson-dwmac.txt
@@ -25,6 +25,22 @@ Required properties on Meson8b and newer:
- "clkin0" - first parent clock of the internal mux
- "clkin1" - second parent clock of the internal mux
 
+Optional properties on Meson8b and newer:
+- amlogic,tx-delay-ns: The internal RGMII TX clock delay (provided
+   by this driver) in nanoseconds. Allowed values
+   are: 0ns, 2ns, 4ns, 6ns.
+   When phy-mode is set to "rgmii" then the TX
+   delay should be explicitly configured. When
+   not configured a fallback of 2ns is used.
+   When the phy-mode is set to either "rgmii-id"
+   or "rgmii-txid" the TX clock delay is already
+   provided by the PHY. In that case this
+   property should be set to 0ns (which disables
+   the TX clock delay in the MAC to prevent the
+   clock from going off because both PHY and MAC
+   are adding a delay).
+   Any configuration is ignored when the phy-mode
+   is set to "rmii".
 
 Example for Meson6:
 
-- 
2.11.0



[PATCH net-next v5 0/2] stmmac: dwmac-meson8b: configurable RGMII TX delay

2017-01-22 Thread Martin Blumenstingl
Currently the dwmac-meson8b stmmac glue driver uses a hardcoded 1/4
cycle (= 2ns) TX clock delay. This seems to work fine for many boards
(for example Odroid-C2 or Amlogic's reference boards) but there are
some others where TX traffic is simply broken.
There are probably multiple reasons why it's working on some boards
while it's broken on others:
- some of Amlogic's reference boards are using a Micrel PHY
- hardware circuit design
- maybe more...

iperf3 results on my Mecool BB2 board (Meson GXM, RTL8211F PHY) with
TX clock delay disabled on the MAC (as it's enabled in the PHY driver).
TX throughput was virtually zero before:
$ iperf3 -c 192.168.1.100 -R
Connecting to host 192.168.1.100, port 5201
Reverse mode, remote host 192.168.1.100 is sending
[  4] local 192.168.1.206 port 52828 connected to 192.168.1.100 port 5201
[ ID] Interval   Transfer Bandwidth
[  4]   0.00-1.00   sec   108 MBytes   901 Mbits/sec
[  4]   1.00-2.00   sec  94.2 MBytes   791 Mbits/sec
[  4]   2.00-3.00   sec  96.5 MBytes   810 Mbits/sec
[  4]   3.00-4.00   sec  96.2 MBytes   808 Mbits/sec
[  4]   4.00-5.00   sec  96.6 MBytes   810 Mbits/sec
[  4]   5.00-6.00   sec  96.5 MBytes   810 Mbits/sec
[  4]   6.00-7.00   sec  96.6 MBytes   810 Mbits/sec
[  4]   7.00-8.00   sec  96.5 MBytes   809 Mbits/sec
[  4]   8.00-9.00   sec   105 MBytes   884 Mbits/sec
[  4]   9.00-10.00  sec   111 MBytes   934 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval   Transfer Bandwidth   Retr
[  4]   0.00-10.00  sec  1000 MBytes   839 Mbits/sec0 sender
[  4]   0.00-10.00  sec   998 MBytes   837 Mbits/sec  receiver

iperf Done.
$ iperf3 -c 192.168.1.100
Connecting to host 192.168.1.100, port 5201
[  4] local 192.168.1.206 port 52832 connected to 192.168.1.100 port 5201
[ ID] Interval   Transfer Bandwidth   Retr  Cwnd
[  4]   0.00-1.01   sec  99.5 MBytes   829 Mbits/sec  117139 KBytes
[  4]   1.01-2.00   sec   105 MBytes   884 Mbits/sec  129   70.7 KBytes
[  4]   2.00-3.01   sec   107 MBytes   889 Mbits/sec  106187 KBytes
[  4]   3.01-4.01   sec   105 MBytes   878 Mbits/sec   92143 KBytes
[  4]   4.01-5.00   sec   105 MBytes   882 Mbits/sec  140129 KBytes
[  4]   5.00-6.01   sec   106 MBytes   883 Mbits/sec  115195 KBytes
[  4]   6.01-7.00   sec   102 MBytes   863 Mbits/sec  133   70.7 KBytes
[  4]   7.00-8.01   sec   106 MBytes   884 Mbits/sec  143   97.6 KBytes
[  4]   8.01-9.01   sec   104 MBytes   875 Mbits/sec  124107 KBytes
[  4]   9.01-10.01  sec   105 MBytes   876 Mbits/sec   90139 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval   Transfer Bandwidth   Retr
[  4]   0.00-10.01  sec  1.02 GBytes   874 Mbits/sec  1189 sender
[  4]   0.00-10.01  sec  1.02 GBytes   873 Mbits/sec  receiver

iperf Done.

I get similar TX throughput on my Meson GXBB "MXQ Pro+" board when I
disable the PHY's TX-delay and configure a 4ms TX-delay on the MAC.
So changes to at least the RTL8211F PHY driver are needed to get it
working properly in all situations.

Changes since v4:
- add a fallback of 2ns (the value which was previously hardcoded) for
  the TX delay so we are backwards-compatible with older .dts'
- update the documentation with the new fallback value and add a small
  note that the "amlogic,tx-delay" property is ignored when the phy-mode
  is "rmii".

Changes since v3:
- rebased to apply against current net-next branch (fixes a conflict
  with d2ed0a7755fe14c7 "net: ethernet: stmmac: fix of-node and
  fixed-link-phydev leaks")

Changes since v2:
- moved all .dts patches (3-7) to a separate series
- removed the default 2ns TX delay when phy-mode RGMII is specified
- (rebased against current net-next)

Changes since v1:
- renamed the devicetree property "amlogic,tx-delay" to
  "amlogic,tx-delay-ns", which makes the .dts easier to read as we can
  simply specify human-readable values instead of having "preprocessor
  defines and calculation in human brain". Thanks to Andrew Lunn for
  the suggestion!
- improved documentation to indicate when the MAC TX-delay should be
  configured and how to use the PHY's TX-delay
- changed the default TX-delay in the dwmac-meson8b driver from 2ns
  to 0ms when any of the rgmii-*id modes are used (the 2ns default
  value still applies for phy-mode "rgmii")
- added patches to properly reset the PHY on Meson GXBB devices and to
  use a similar configuration than the one we use on Meson GXL devices
  (by passing a phy-handle to stmmac and defining the PHY in the mdio0
  bus - patch 3-6)
- add the "amlogic,tx-delay-ns" property to all boards which are using
  the RGMII PHY (patch 7)


Martin Blumenstingl (2):
  net: dt-bindings: add RGMII TX delay configuration to meson8b-dwmac
  net: stmmac: dwmac-meson8b: make the RGMII TX delay configurable

 .../de

[PATCH] Documentation: net: phy: improve explanation when to specify the PHY ID

2017-01-22 Thread Martin Blumenstingl
The old description basically read like "ethernet-phy-id." can
be specified when you know the actual PHY ID. However, specifying this
has a side-effect: it forces Linux to bind to a certain PHY driver (the
one that matches the ID given in the compatible string), ignoring the ID
which is reported by the actual PHY.
Whenever a device is shipped with (multiple) different PHYs during it's
production lifetime then explicitly specifying
"ethernet-phy-id." could break certain revisions of that device.

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
Thanks to Andrew Lunn for pointing the documentation issue out to me in:
http://lists.infradead.org/pipermail/linux-amlogic/2017-January/002141.html


 Documentation/devicetree/bindings/net/phy.txt | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/phy.txt 
b/Documentation/devicetree/bindings/net/phy.txt
index ff1bc4b1bb3b..fb5056b22685 100644
--- a/Documentation/devicetree/bindings/net/phy.txt
+++ b/Documentation/devicetree/bindings/net/phy.txt
@@ -19,8 +19,9 @@ Optional Properties:
   specifications. If neither of these are specified, the default is to
   assume clause 22.
 
-  If the phy's identifier is known then the list may contain an entry
-  of the form: "ethernet-phy-id." where
+  If the PHY reports an incorrect ID (or none at all) then the
+  "compatible" list may contain an entry with the correct PHY ID in the
+  form: "ethernet-phy-id." where
   - The value of the 16 bit Phy Identifier 1 register as
 4 hex digits. This is the chip vendor OUI bits 3:18
   - The value of the 16 bit Phy Identifier 2 register as
-- 
2.11.0



Re: [PATCH net-next v4 2/2] net: stmmac: dwmac-meson8b: make the RGMII TX delay configurable

2017-01-20 Thread Martin Blumenstingl
Hi David,

On Sun, Dec 18, 2016 at 5:13 PM, Martin Blumenstingl
<martin.blumensti...@googlemail.com> wrote:
> On Sun, Dec 18, 2016 at 4:49 PM, David Miller <da...@davemloft.net> wrote:
>> From: Martin Blumenstingl <martin.blumensti...@googlemail.com>
>> Date: Sat, 17 Dec 2016 19:21:19 +0100
>>
>>> Prior to this patch we were using a hardcoded RGMII TX clock delay of
>>> 2ns (= 1/4 cycle of the 125MHz RGMII TX clock). This value works for
>>> many boards, but unfortunately not for all (due to the way the actual
>>> circuit is designed, sometimes because the TX delay is enabled in the
>>> PHY, etc.). Making the TX delay on the MAC side configurable allows us
>>> to support all possible hardware combinations.
>>>
>>> This allows fixing a compatibility issue on some boards, where the
>>> RTL8211F PHY is configured to generate the TX delay. We can now turn
>>> off the TX delay in the MAC, because otherwise we would be applying the
>>> delay twice (which results in non-working TX traffic).
>>>
>>> Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
>>> Tested-by: Neil Armstrong <narmstr...@baylibre.com>
>>
>> Is this really the safest thing to do?
>>
>> If you say the existing hard-coded setting of 1/4 cycle works on most
>> boards, and what you're trying to do is override it with an OF
>> property value for boards where the existing setting does not work,
>> then you _must_ use a default value that corresponds to what the
>> existing code does not when you don't see this new OF property.
> it's a bit more complicated in reality: 1/4 cycle works when the TX
> delay of the RTL8211F PHY is turned off (until recently it was always
> enabled for phy-mode RGMII).
>
>> So please retain the current behavior of the 1/4 cycle TX delay
>> setting when you don't see the amlogic,tx-delay-ns property.
>>
>> I really think you risk breaking existing boards by not doing so,
>> unless you can have this patch tested on every such board that exists
>> and I don't think you really can feasibly and rigorously do that.
> there's a patch in my follow-up series which adds the 2ns to the .dts
> for all RGMII based boards: [0] (and I would keep these even if we had
> a default value, just to make it explicit and thus easier to
> understand for other people).
> however, we can add the 2ns default back (I can do this if you want -
> Rob Herring was unhappy with the missing documentation of this default
> value [1] - so note to myself: take care of that as well). but then we
> have to decide when to apply this default value: only when we're in
> RGMII mode or also in any of the RGMII_*ID modes?
could you please let me know if I should add a a fallback (2ns which
was the old hardcoded value) to the driver or if I should simply leave
it out (that's the way it is right now).
I'm fine with either way, I would just like to avoid duplicate work.
So please let me know how you prefer it.


Regards,
Martin


Re: [PATCH net-next v4 2/2] net: stmmac: dwmac-meson8b: make the RGMII TX delay configurable

2017-01-09 Thread Martin Blumenstingl
Hi David,

On Sun, Dec 18, 2016 at 5:13 PM, Martin Blumenstingl
<martin.blumensti...@googlemail.com> wrote:
> On Sun, Dec 18, 2016 at 4:49 PM, David Miller <da...@davemloft.net> wrote:
>> From: Martin Blumenstingl <martin.blumensti...@googlemail.com>
>> Date: Sat, 17 Dec 2016 19:21:19 +0100
>>
>>> Prior to this patch we were using a hardcoded RGMII TX clock delay of
>>> 2ns (= 1/4 cycle of the 125MHz RGMII TX clock). This value works for
>>> many boards, but unfortunately not for all (due to the way the actual
>>> circuit is designed, sometimes because the TX delay is enabled in the
>>> PHY, etc.). Making the TX delay on the MAC side configurable allows us
>>> to support all possible hardware combinations.
>>>
>>> This allows fixing a compatibility issue on some boards, where the
>>> RTL8211F PHY is configured to generate the TX delay. We can now turn
>>> off the TX delay in the MAC, because otherwise we would be applying the
>>> delay twice (which results in non-working TX traffic).
>>>
>>> Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
>>> Tested-by: Neil Armstrong <narmstr...@baylibre.com>
>>
>> Is this really the safest thing to do?
>>
>> If you say the existing hard-coded setting of 1/4 cycle works on most
>> boards, and what you're trying to do is override it with an OF
>> property value for boards where the existing setting does not work,
>> then you _must_ use a default value that corresponds to what the
>> existing code does not when you don't see this new OF property.
> it's a bit more complicated in reality: 1/4 cycle works when the TX
> delay of the RTL8211F PHY is turned off (until recently it was always
> enabled for phy-mode RGMII).
>
>> So please retain the current behavior of the 1/4 cycle TX delay
>> setting when you don't see the amlogic,tx-delay-ns property.
>>
>> I really think you risk breaking existing boards by not doing so,
>> unless you can have this patch tested on every such board that exists
>> and I don't think you really can feasibly and rigorously do that.
> there's a patch in my follow-up series which adds the 2ns to the .dts
> for all RGMII based boards: [0] (and I would keep these even if we had
> a default value, just to make it explicit and thus easier to
> understand for other people).
> however, we can add the 2ns default back (I can do this if you want -
> Rob Herring was unhappy with the missing documentation of this default
> value [1] - so note to myself: take care of that as well). but then we
> have to decide when to apply this default value: only when we're in
> RGMII mode or also in any of the RGMII_*ID modes?
>
> please let me know how we should proceed
gentle ping - what is your opinion on this?


Regards,
Martin


Re: [PATCH net-next v4 2/2] net: stmmac: dwmac-meson8b: make the RGMII TX delay configurable

2016-12-18 Thread Martin Blumenstingl
On Sun, Dec 18, 2016 at 4:49 PM, David Miller <da...@davemloft.net> wrote:
> From: Martin Blumenstingl <martin.blumensti...@googlemail.com>
> Date: Sat, 17 Dec 2016 19:21:19 +0100
>
>> Prior to this patch we were using a hardcoded RGMII TX clock delay of
>> 2ns (= 1/4 cycle of the 125MHz RGMII TX clock). This value works for
>> many boards, but unfortunately not for all (due to the way the actual
>> circuit is designed, sometimes because the TX delay is enabled in the
>> PHY, etc.). Making the TX delay on the MAC side configurable allows us
>> to support all possible hardware combinations.
>>
>> This allows fixing a compatibility issue on some boards, where the
>> RTL8211F PHY is configured to generate the TX delay. We can now turn
>> off the TX delay in the MAC, because otherwise we would be applying the
>> delay twice (which results in non-working TX traffic).
>>
>> Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
>> Tested-by: Neil Armstrong <narmstr...@baylibre.com>
>
> Is this really the safest thing to do?
>
> If you say the existing hard-coded setting of 1/4 cycle works on most
> boards, and what you're trying to do is override it with an OF
> property value for boards where the existing setting does not work,
> then you _must_ use a default value that corresponds to what the
> existing code does not when you don't see this new OF property.
it's a bit more complicated in reality: 1/4 cycle works when the TX
delay of the RTL8211F PHY is turned off (until recently it was always
enabled for phy-mode RGMII).

> So please retain the current behavior of the 1/4 cycle TX delay
> setting when you don't see the amlogic,tx-delay-ns property.
>
> I really think you risk breaking existing boards by not doing so,
> unless you can have this patch tested on every such board that exists
> and I don't think you really can feasibly and rigorously do that.
there's a patch in my follow-up series which adds the 2ns to the .dts
for all RGMII based boards: [0] (and I would keep these even if we had
a default value, just to make it explicit and thus easier to
understand for other people).
however, we can add the 2ns default back (I can do this if you want -
Rob Herring was unhappy with the missing documentation of this default
value [1] - so note to myself: take care of that as well). but then we
have to decide when to apply this default value: only when we're in
RGMII mode or also in any of the RGMII_*ID modes?

please let me know how we should proceed


Regards,
Martin


[0] http://lists.infradead.org/pipermail/linux-amlogic/2016-December/001838.html
[1] http://lists.infradead.org/pipermail/linux-amlogic/2016-November/001817.html


Re: [PATCH net-next v3 0/4] Fix OdroidC2 Gigabit Tx link issue

2016-12-18 Thread Martin Blumenstingl
Hi Florian, Hi Jerome,

On Wed, Nov 30, 2016 at 2:15 AM, Florian Fainelli  wrote:
> On 11/29/2016 05:13 PM, David Miller wrote:
>> From: Florian Fainelli 
>> Date: Tue, 29 Nov 2016 16:43:20 -0800
>>
>>> On 11/29/2016 04:38 PM, David Miller wrote:
 From: Jerome Brunet 
 Date: Mon, 28 Nov 2016 10:46:45 +0100

> This patchset fixes an issue with the OdroidC2 board (DWMAC + RTL8211F).
> The platform seems to enter LPI on the Rx path too often while performing
> relatively high TX transfer. This eventually break the link (both Tx and
> Rx), and require to bring the interface down and up again to get the Rx
> path working again.
>
> The root cause of this issue is not fully understood yet but disabling EEE
> advertisement on the PHY prevent this feature to be negotiated.
> With this change, the link is stable and reliable, with the expected
> throughput performance.
>
> The patchset adds options in the generic phy driver to disable EEE
> advertisement, through device tree. The way it is done is very similar
> to the handling of the max-speed property.

 Patches 1-3 applied to net-next, thanks.
>>>
>>> Meh, there was a v4 submitted shortly after, and I objected to the whole
>>> idea of using that kind of Device Tree properties to disable EEE, we can
>>> send reverts though..
>>
>> Sorry, I lost this in all the discussion, I can revert.
>
> Yeah, I can understand why, these freaking PHYs tend to generate a lot
> of noise and discussion...
>
>>
>> Just send me a revert of the entire merge commit
>> a152c91889556df17ca6d8ea134fb2cb4ac9f893 with a short
>> description of why and I'll apply it.
>
> OK, I will talk with Jerome first to make sure that we are in agreement
> with the solution to deploy to fix the OdroidC2 problem first.
simply because I'm curious: what was the outcome of your discussion?
can we stay with the current solution or are any changes required?


Regards,
Martin


[PATCH net-next v4 2/2] net: stmmac: dwmac-meson8b: make the RGMII TX delay configurable

2016-12-17 Thread Martin Blumenstingl
Prior to this patch we were using a hardcoded RGMII TX clock delay of
2ns (= 1/4 cycle of the 125MHz RGMII TX clock). This value works for
many boards, but unfortunately not for all (due to the way the actual
circuit is designed, sometimes because the TX delay is enabled in the
PHY, etc.). Making the TX delay on the MAC side configurable allows us
to support all possible hardware combinations.

This allows fixing a compatibility issue on some boards, where the
RTL8211F PHY is configured to generate the TX delay. We can now turn
off the TX delay in the MAC, because otherwise we would be applying the
delay twice (which results in non-working TX traffic).

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
Tested-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 21 +++--
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index ffaed1f35efe..db970cd6600f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -35,10 +35,6 @@
 
 #define PRG_ETH0_TXDLY_SHIFT   5
 #define PRG_ETH0_TXDLY_MASKGENMASK(6, 5)
-#define PRG_ETH0_TXDLY_OFF (0x0 << PRG_ETH0_TXDLY_SHIFT)
-#define PRG_ETH0_TXDLY_QUARTER (0x1 << PRG_ETH0_TXDLY_SHIFT)
-#define PRG_ETH0_TXDLY_HALF(0x2 << PRG_ETH0_TXDLY_SHIFT)
-#define PRG_ETH0_TXDLY_THREE_QUARTERS  (0x3 << PRG_ETH0_TXDLY_SHIFT)
 
 /* divider for the result of m250_sel */
 #define PRG_ETH0_CLK_M250_DIV_SHIFT7
@@ -69,6 +65,8 @@ struct meson8b_dwmac {
 
struct clk_divider  m25_div;
struct clk  *m25_div_clk;
+
+   u32 tx_delay_ns;
 };
 
 static void meson8b_dwmac_mask_bits(struct meson8b_dwmac *dwmac, u32 reg,
@@ -179,6 +177,7 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
 {
int ret;
unsigned long clk_rate;
+   u8 tx_dly_val;
 
switch (dwmac->phy_mode) {
case PHY_INTERFACE_MODE_RGMII:
@@ -196,9 +195,13 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac 
*dwmac)
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
PRG_ETH0_INVERTED_RMII_CLK, 0);
 
-   /* TX clock delay - all known boards use a 1/4 cycle delay */
+   /* TX clock delay in ns = "8ns / 4 * tx_dly_val" (where
+* 8ns are exactly one cycle of the 125MHz RGMII TX clock):
+* 0ns = 0x0, 2ns = 0x1, 4ns = 0x2, 6ns = 0x3
+*/
+   tx_dly_val = dwmac->tx_delay_ns >> 1;
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TXDLY_MASK,
-   PRG_ETH0_TXDLY_QUARTER);
+   tx_dly_val << PRG_ETH0_TXDLY_SHIFT);
break;
 
case PHY_INTERFACE_MODE_RMII:
@@ -282,6 +285,12 @@ static int meson8b_dwmac_probe(struct platform_device 
*pdev)
dev_err(>dev, "missing phy-mode property\n");
ret = -EINVAL;
goto err_remove_config_dt;
+   } else if (dwmac->phy_mode != PHY_INTERFACE_MODE_RMII) {
+   /* ignore errors as this is an optional property - by default
+* we assume a TX delay of 0ns.
+*/
+   of_property_read_u32(pdev->dev.of_node, "amlogic,tx-delay-ns",
+>tx_delay_ns);
}
 
ret = meson8b_init_clk(dwmac);
-- 
2.11.0



[PATCH net-next v4 1/2] net: dt-bindings: add RGMII TX delay configuration to meson8b-dwmac

2016-12-17 Thread Martin Blumenstingl
This allows configuring the RGMII TX clock delay. The RGMII clock is
generated by underlying hardware of the the Meson 8b / GXBB DWMAC glue.
The configuration depends on the actual hardware (no delay may be
needed due to the design of the actual circuit, the PHY might add this
delay, etc.).

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
Tested-by: Neil Armstrong <narmstr...@baylibre.com>
Acked-by: Rob Herring <r...@kernel.org>
---
 Documentation/devicetree/bindings/net/meson-dwmac.txt | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/meson-dwmac.txt 
b/Documentation/devicetree/bindings/net/meson-dwmac.txt
index 89e62ddc69ca..f8bc54094e3c 100644
--- a/Documentation/devicetree/bindings/net/meson-dwmac.txt
+++ b/Documentation/devicetree/bindings/net/meson-dwmac.txt
@@ -25,6 +25,20 @@ Required properties on Meson8b and newer:
- "clkin0" - first parent clock of the internal mux
- "clkin1" - second parent clock of the internal mux
 
+Optional properties on Meson8b and newer:
+- amlogic,tx-delay-ns: The internal RGMII TX clock delay (provided
+   by this driver) in nanoseconds. Allowed values
+   are: 0ns, 2ns, 4ns, 6ns.
+   This must be configured when the phy-mode is
+   "rgmii" (typically a value of 2ns is used in
+   this case).
+   When phy-mode is set to "rgmii-id" or
+   "rgmii-txid" the TX clock delay is already
+   provided by the PHY. In that case this
+   property should be set to 0ns (which disables
+   the TX clock delay in the MAC to prevent the
+   clock from going off because both PHY and MAC
+   are adding a delay).
 
 Example for Meson6:
 
-- 
2.11.0



[PATCH net-next v4 0/2] stmmac: dwmac-meson8b: configurable RGMII TX delay

2016-12-17 Thread Martin Blumenstingl
Currently the dwmac-meson8b stmmac glue driver uses a hardcoded 1/4
cycle (= 2ns) TX clock delay. This seems to work fine for many boards
(for example Odroid-C2 or Amlogic's reference boards) but there are
some others where TX traffic is simply broken.
There are probably multiple reasons why it's working on some boards
while it's broken on others:
- some of Amlogic's reference boards are using a Micrel PHY
- hardware circuit design
- maybe more...

iperf3 results on my Mecool BB2 board (Meson GXM, RTL8211F PHY) with
TX clock delay disabled on the MAC (as it's enabled in the PHY driver).
TX throughput was virtually zero before:
$ iperf3 -c 192.168.1.100 -R
Connecting to host 192.168.1.100, port 5201
Reverse mode, remote host 192.168.1.100 is sending
[  4] local 192.168.1.206 port 52828 connected to 192.168.1.100 port 5201
[ ID] Interval   Transfer Bandwidth
[  4]   0.00-1.00   sec   108 MBytes   901 Mbits/sec
[  4]   1.00-2.00   sec  94.2 MBytes   791 Mbits/sec
[  4]   2.00-3.00   sec  96.5 MBytes   810 Mbits/sec
[  4]   3.00-4.00   sec  96.2 MBytes   808 Mbits/sec
[  4]   4.00-5.00   sec  96.6 MBytes   810 Mbits/sec
[  4]   5.00-6.00   sec  96.5 MBytes   810 Mbits/sec
[  4]   6.00-7.00   sec  96.6 MBytes   810 Mbits/sec
[  4]   7.00-8.00   sec  96.5 MBytes   809 Mbits/sec
[  4]   8.00-9.00   sec   105 MBytes   884 Mbits/sec
[  4]   9.00-10.00  sec   111 MBytes   934 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval   Transfer Bandwidth   Retr
[  4]   0.00-10.00  sec  1000 MBytes   839 Mbits/sec0 sender
[  4]   0.00-10.00  sec   998 MBytes   837 Mbits/sec  receiver

iperf Done.
$ iperf3 -c 192.168.1.100
Connecting to host 192.168.1.100, port 5201
[  4] local 192.168.1.206 port 52832 connected to 192.168.1.100 port 5201
[ ID] Interval   Transfer Bandwidth   Retr  Cwnd
[  4]   0.00-1.01   sec  99.5 MBytes   829 Mbits/sec  117139 KBytes
[  4]   1.01-2.00   sec   105 MBytes   884 Mbits/sec  129   70.7 KBytes
[  4]   2.00-3.01   sec   107 MBytes   889 Mbits/sec  106187 KBytes
[  4]   3.01-4.01   sec   105 MBytes   878 Mbits/sec   92143 KBytes
[  4]   4.01-5.00   sec   105 MBytes   882 Mbits/sec  140129 KBytes
[  4]   5.00-6.01   sec   106 MBytes   883 Mbits/sec  115195 KBytes
[  4]   6.01-7.00   sec   102 MBytes   863 Mbits/sec  133   70.7 KBytes
[  4]   7.00-8.01   sec   106 MBytes   884 Mbits/sec  143   97.6 KBytes
[  4]   8.01-9.01   sec   104 MBytes   875 Mbits/sec  124107 KBytes
[  4]   9.01-10.01  sec   105 MBytes   876 Mbits/sec   90139 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval   Transfer Bandwidth   Retr
[  4]   0.00-10.01  sec  1.02 GBytes   874 Mbits/sec  1189 sender
[  4]   0.00-10.01  sec  1.02 GBytes   873 Mbits/sec  receiver

iperf Done.

I get similar TX throughput on my Meson GXBB "MXQ Pro+" board when I
disable the PHY's TX-delay and configure a 4ms TX-delay on the MAC.
So changes to at least the RTL8211F PHY driver are needed to get it
working properly in all situations.

Changes since v3:
- rebased to apply against current net-next branch (fixes a conflict
  with d2ed0a7755fe14c7 "net: ethernet: stmmac: fix of-node and
  fixed-link-phydev leaks")
- 

Changes since v2:
- moved all .dts patches (3-7) to a separate series
- removed the default 2ns TX delay when phy-mode RGMII is specified
- (rebased against current net-next)

Changes since v1:
- renamed the devicetree property "amlogic,tx-delay" to
  "amlogic,tx-delay-ns", which makes the .dts easier to read as we can
  simply specify human-readable values instead of having "preprocessor
  defines and calculation in human brain". Thanks to Andrew Lunn for
  the suggestion!
- improved documentation to indicate when the MAC TX-delay should be
  configured and how to use the PHY's TX-delay
- changed the default TX-delay in the dwmac-meson8b driver from 2ns
  to 0ms when any of the rgmii-*id modes are used (the 2ns default
  value still applies for phy-mode "rgmii")
- added patches to properly reset the PHY on Meson GXBB devices and to
  use a similar configuration than the one we use on Meson GXL devices
  (by passing a phy-handle to stmmac and defining the PHY in the mdio0
  bus - patch 3-6)
- add the "amlogic,tx-delay-ns" property to all boards which are using
  the RGMII PHY (patch 7)

Martin Blumenstingl (2):
  net: dt-bindings: add RGMII TX delay configuration to meson8b-dwmac
  net: stmmac: dwmac-meson8b: make the RGMII TX delay configurable

 .../devicetree/bindings/net/meson-dwmac.txt | 14 ++
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 21 +++--
 2 files changed, 29 insertions(+), 6 deletions(-)

-- 
2.11.0



Re: [PATCH v2 0/7] stmmac: dwmac-meson8b: configurable RGMII TX delay

2016-12-02 Thread Martin Blumenstingl
On Mon, Nov 28, 2016 at 2:33 AM, David Miller <da...@davemloft.net> wrote:
> From: Martin Blumenstingl <martin.blumensti...@googlemail.com>
> Date: Fri, 25 Nov 2016 14:01:49 +0100
>
>> Currently the dwmac-meson8b stmmac glue driver uses a hardcoded 1/4
>> cycle TX clock delay. This seems to work fine for many boards (for
>> example Odroid-C2 or Amlogic's reference boards) but there are some
>> others where TX traffic is simply broken.
>> There are probably multiple reasons why it's working on some boards
>> while it's broken on others:
>> - some of Amlogic's reference boards are using a Micrel PHY
>> - hardware circuit design
>> - maybe more...
>
> The ARM arch file changes do not apply cleanly to net-next, you probably
> want to merge them via the ARM tree instead of mine, and respin this series
> to be without the .dts file changes.
done, v3 contains only the net-next changes while the dts changes can
be found here: [0]


Regards,
Martin


[0] http://lists.infradead.org/pipermail/linux-amlogic/2016-December/001836.html


[PATCH net-next v3 2/2] net: stmmac: dwmac-meson8b: make the RGMII TX delay configurable

2016-12-02 Thread Martin Blumenstingl
Prior to this patch we were using a hardcoded RGMII TX clock delay of
2ns (= 1/4 cycle of the 125MHz RGMII TX clock). This value works for
many boards, but unfortunately not for all (due to the way the actual
circuit is designed, sometimes because the TX delay is enabled in the
PHY, etc.). Making the TX delay on the MAC side configurable allows us
to support all possible hardware combinations.

This allows fixing a compatibility issue on some boards, where the
RTL8211F PHY is configured to generate the TX delay. We can now turn
off the TX delay in the MAC, because otherwise we would be applying the
delay twice (which results in non-working TX traffic).

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
Tested-by: Neil Armstrong <narmstr...@baylibre.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 21 +++--
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index 250e4ce..dad31b0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -35,10 +35,6 @@
 
 #define PRG_ETH0_TXDLY_SHIFT   5
 #define PRG_ETH0_TXDLY_MASKGENMASK(6, 5)
-#define PRG_ETH0_TXDLY_OFF (0x0 << PRG_ETH0_TXDLY_SHIFT)
-#define PRG_ETH0_TXDLY_QUARTER (0x1 << PRG_ETH0_TXDLY_SHIFT)
-#define PRG_ETH0_TXDLY_HALF(0x2 << PRG_ETH0_TXDLY_SHIFT)
-#define PRG_ETH0_TXDLY_THREE_QUARTERS  (0x3 << PRG_ETH0_TXDLY_SHIFT)
 
 /* divider for the result of m250_sel */
 #define PRG_ETH0_CLK_M250_DIV_SHIFT7
@@ -69,6 +65,8 @@ struct meson8b_dwmac {
 
struct clk_divider  m25_div;
struct clk  *m25_div_clk;
+
+   u32 tx_delay_ns;
 };
 
 static void meson8b_dwmac_mask_bits(struct meson8b_dwmac *dwmac, u32 reg,
@@ -179,6 +177,7 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
 {
int ret;
unsigned long clk_rate;
+   u8 tx_dly_val;
 
switch (dwmac->phy_mode) {
case PHY_INTERFACE_MODE_RGMII:
@@ -196,9 +195,13 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac 
*dwmac)
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
PRG_ETH0_INVERTED_RMII_CLK, 0);
 
-   /* TX clock delay - all known boards use a 1/4 cycle delay */
+   /* TX clock delay in ns = "8ns / 4 * tx_dly_val" (where
+* 8ns are exactly one cycle of the 125MHz RGMII TX clock):
+* 0ns = 0x0, 2ns = 0x1, 4ns = 0x2, 6ns = 0x3
+*/
+   tx_dly_val = dwmac->tx_delay_ns >> 1;
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TXDLY_MASK,
-   PRG_ETH0_TXDLY_QUARTER);
+   tx_dly_val << PRG_ETH0_TXDLY_SHIFT);
break;
 
case PHY_INTERFACE_MODE_RMII:
@@ -277,6 +280,12 @@ static int meson8b_dwmac_probe(struct platform_device 
*pdev)
if (dwmac->phy_mode < 0) {
dev_err(>dev, "missing phy-mode property\n");
return -EINVAL;
+   } else if (dwmac->phy_mode != PHY_INTERFACE_MODE_RMII) {
+   /* ignore errors as this is an optional property - by default
+* we assume a TX delay of 0ns.
+*/
+   of_property_read_u32(pdev->dev.of_node, "amlogic,tx-delay-ns",
+>tx_delay_ns);
}
 
ret = meson8b_init_clk(dwmac);
-- 
2.10.2



[PATCH net-next v3 1/2] net: dt-bindings: add RGMII TX delay configuration to meson8b-dwmac

2016-12-02 Thread Martin Blumenstingl
This allows configuring the RGMII TX clock delay. The RGMII clock is
generated by underlying hardware of the the Meson 8b / GXBB DWMAC glue.
The configuration depends on the actual hardware (no delay may be
needed due to the design of the actual circuit, the PHY might add this
delay, etc.).

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
Tested-by: Neil Armstrong <narmstr...@baylibre.com>
---
 Documentation/devicetree/bindings/net/meson-dwmac.txt | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/meson-dwmac.txt 
b/Documentation/devicetree/bindings/net/meson-dwmac.txt
index 89e62dd..f8bc540 100644
--- a/Documentation/devicetree/bindings/net/meson-dwmac.txt
+++ b/Documentation/devicetree/bindings/net/meson-dwmac.txt
@@ -25,6 +25,20 @@ Required properties on Meson8b and newer:
- "clkin0" - first parent clock of the internal mux
- "clkin1" - second parent clock of the internal mux
 
+Optional properties on Meson8b and newer:
+- amlogic,tx-delay-ns: The internal RGMII TX clock delay (provided
+   by this driver) in nanoseconds. Allowed values
+   are: 0ns, 2ns, 4ns, 6ns.
+   This must be configured when the phy-mode is
+   "rgmii" (typically a value of 2ns is used in
+   this case).
+   When phy-mode is set to "rgmii-id" or
+   "rgmii-txid" the TX clock delay is already
+   provided by the PHY. In that case this
+   property should be set to 0ns (which disables
+   the TX clock delay in the MAC to prevent the
+   clock from going off because both PHY and MAC
+   are adding a delay).
 
 Example for Meson6:
 
-- 
2.10.2



[PATCH net-next v3 0/2] stmmac: dwmac-meson8b: configurable RGMII TX delay

2016-12-02 Thread Martin Blumenstingl
Currently the dwmac-meson8b stmmac glue driver uses a hardcoded 1/4
cycle (= 2ns) TX clock delay. This seems to work fine for many boards
(for example Odroid-C2 or Amlogic's reference boards) but there are
some others where TX traffic is simply broken.
There are probably multiple reasons why it's working on some boards
while it's broken on others:
- some of Amlogic's reference boards are using a Micrel PHY
- hardware circuit design
- maybe more...

iperf3 results on my Mecool BB2 board (Meson GXM, RTL8211F PHY) with
TX clock delay disabled on the MAC (as it's enabled in the PHY driver).
TX throughput was virtually zero before:
$ iperf3 -c 192.168.1.100 -R
Connecting to host 192.168.1.100, port 5201
Reverse mode, remote host 192.168.1.100 is sending
[  4] local 192.168.1.206 port 52828 connected to 192.168.1.100 port 5201
[ ID] Interval   Transfer Bandwidth
[  4]   0.00-1.00   sec   108 MBytes   901 Mbits/sec
[  4]   1.00-2.00   sec  94.2 MBytes   791 Mbits/sec
[  4]   2.00-3.00   sec  96.5 MBytes   810 Mbits/sec
[  4]   3.00-4.00   sec  96.2 MBytes   808 Mbits/sec
[  4]   4.00-5.00   sec  96.6 MBytes   810 Mbits/sec
[  4]   5.00-6.00   sec  96.5 MBytes   810 Mbits/sec
[  4]   6.00-7.00   sec  96.6 MBytes   810 Mbits/sec
[  4]   7.00-8.00   sec  96.5 MBytes   809 Mbits/sec
[  4]   8.00-9.00   sec   105 MBytes   884 Mbits/sec
[  4]   9.00-10.00  sec   111 MBytes   934 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval   Transfer Bandwidth   Retr
[  4]   0.00-10.00  sec  1000 MBytes   839 Mbits/sec0 sender
[  4]   0.00-10.00  sec   998 MBytes   837 Mbits/sec  receiver

iperf Done.
$ iperf3 -c 192.168.1.100
Connecting to host 192.168.1.100, port 5201
[  4] local 192.168.1.206 port 52832 connected to 192.168.1.100 port 5201
[ ID] Interval   Transfer Bandwidth   Retr  Cwnd
[  4]   0.00-1.01   sec  99.5 MBytes   829 Mbits/sec  117139 KBytes
[  4]   1.01-2.00   sec   105 MBytes   884 Mbits/sec  129   70.7 KBytes
[  4]   2.00-3.01   sec   107 MBytes   889 Mbits/sec  106187 KBytes
[  4]   3.01-4.01   sec   105 MBytes   878 Mbits/sec   92143 KBytes
[  4]   4.01-5.00   sec   105 MBytes   882 Mbits/sec  140129 KBytes
[  4]   5.00-6.01   sec   106 MBytes   883 Mbits/sec  115195 KBytes
[  4]   6.01-7.00   sec   102 MBytes   863 Mbits/sec  133   70.7 KBytes
[  4]   7.00-8.01   sec   106 MBytes   884 Mbits/sec  143   97.6 KBytes
[  4]   8.01-9.01   sec   104 MBytes   875 Mbits/sec  124107 KBytes
[  4]   9.01-10.01  sec   105 MBytes   876 Mbits/sec   90139 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval   Transfer Bandwidth   Retr
[  4]   0.00-10.01  sec  1.02 GBytes   874 Mbits/sec  1189 sender
[  4]   0.00-10.01  sec  1.02 GBytes   873 Mbits/sec  receiver

iperf Done.

I get similar TX throughput on my Meson GXBB "MXQ Pro+" board when I
disable the PHY's TX-delay and configure a 4ms TX-delay on the MAC.
So changes to at least the RTL8211F PHY driver are needed to get it
working properly in all situations.

Changes since v2:
- moved all .dts patches (3-7) to a separate series
- removed the default 2ns TX delay when phy-mode RGMII is specified
- (rebased against current net-next)

Changes since v1:
- renamed the devicetree property "amlogic,tx-delay" to
  "amlogic,tx-delay-ns", which makes the .dts easier to read as we can
  simply specify human-readable values instead of having "preprocessor
  defines and calculation in human brain". Thanks to Andrew Lunn for
  the suggestion!
- improved documentation to indicate when the MAC TX-delay should be
  configured and how to use the PHY's TX-delay
- changed the default TX-delay in the dwmac-meson8b driver from 2ns
  to 0ms when any of the rgmii-*id modes are used (the 2ns default
  value still applies for phy-mode "rgmii")
- added patches to properly reset the PHY on Meson GXBB devices and to
  use a similar configuration than the one we use on Meson GXL devices
  (by passing a phy-handle to stmmac and defining the PHY in the mdio0
  bus - patch 3-6)
- add the "amlogic,tx-delay-ns" property to all boards which are using
  the RGMII PHY (patch 7)


Martin Blumenstingl (2):
  net: dt-bindings: add RGMII TX delay configuration to meson8b-dwmac
  net: stmmac: dwmac-meson8b: make the RGMII TX delay configurable

 .../devicetree/bindings/net/meson-dwmac.txt | 14 ++
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 21 +++--
 2 files changed, 29 insertions(+), 6 deletions(-)

-- 
2.10.2



Re: [PATCH v2 1/7] net: dt-bindings: add RGMII TX delay configuration to meson8b-dwmac

2016-11-30 Thread Martin Blumenstingl
On Wed, Nov 30, 2016 at 10:44 PM, Rob Herring <r...@kernel.org> wrote:
> On Fri, Nov 25, 2016 at 02:01:50PM +0100, Martin Blumenstingl wrote:
>> This allows configuring the RGMII TX clock delay. The RGMII clock is
>> generated by underlying hardware of the the Meson 8b / GXBB DWMAC glue.
>> The configuration depends on the actual hardware (no delay may be
>> needed due to the design of the actual circuit, the PHY might add this
>> delay, etc.).
>>
>> Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
>> ---
>>  Documentation/devicetree/bindings/net/meson-dwmac.txt | 14 ++
>>  1 file changed, 14 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/net/meson-dwmac.txt 
>> b/Documentation/devicetree/bindings/net/meson-dwmac.txt
>> index 89e62dd..f8bc540 100644
>> --- a/Documentation/devicetree/bindings/net/meson-dwmac.txt
>> +++ b/Documentation/devicetree/bindings/net/meson-dwmac.txt
>> @@ -25,6 +25,20 @@ Required properties on Meson8b and newer:
>>   - "clkin0" - first parent clock of the internal mux
>>   - "clkin1" - second parent clock of the internal mux
>>
>> +Optional properties on Meson8b and newer:
>> +- amlogic,tx-delay-ns:   The internal RGMII TX clock delay (provided
>> + by this driver) in nanoseconds. Allowed values
>> + are: 0ns, 2ns, 4ns, 6ns.
>> + This must be configured when the phy-mode is
>> + "rgmii" (typically a value of 2ns is used in
>> + this case).
>> + When phy-mode is set to "rgmii-id" or
>> + "rgmii-txid" the TX clock delay is already
>> + provided by the PHY. In that case this
>> + property should be set to 0ns (which disables
>> + the TX clock delay in the MAC to prevent the
>> + clock from going off because both PHY and MAC
>> + are adding a delay).
>
> What's the default? Why can't no property mean 0ns delay?
This value (2ns) was previously hardcoded. Having a default of 0ns
means that patch 7 ("ARM64: dts: amlogic: add the ethernet TX delay
configuration") becomes mandatory (otherwise we'll have broken Gbit
ethernet again because the TX delay is now disabled in the PHY when
phy-mode is "rgmii" and additionally we don't apply the 2ns TX delay
on the MAC side when the property is missing).
I'm fine with either way though - just let me know so I can adjust the
code accordingly.


Re: [PATCH net-next v2 0/4] Documentation: net: phy: Improve documentation

2016-11-27 Thread Martin Blumenstingl
On Sun, Nov 27, 2016 at 7:44 PM, Florian Fainelli <f.faine...@gmail.com> wrote:
> Hi all,
>
> This patch series addresses discussions and feedback that was recently 
> received
> on the mailing-list in the area of: flow control/pause frames, interpretation 
> of
> phy_interface_t and finally add some links to useful standards documents.
>
> Changes in v2:
>
> - clarify a few things in the RGMII section, add a paragraph about common 
> issues
>   with RGMII delay mismatches
Reviewed-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>

Thanks a lot Florian, this will definitely help others in the future!

> Florian Fainelli (4):
>   Documentation: net: phy: remove description of function pointers
>   Documentation: net: phy: Add a paragraph about pause frames/flow
> control
>   Documentation: net: phy: Add blurb about RGMII
>   Documentation: net: phy: Add links to several standards documents
>
>  Documentation/networking/phy.txt | 139 
> +--
>  1 file changed, 104 insertions(+), 35 deletions(-)
>
> --
> 2.9.3
>


Re: net: stmmac: Meson GXBB: attempting to execute userspace memory

2016-11-26 Thread Martin Blumenstingl
Hello Heinrich,

On Sat, Nov 26, 2016 at 8:53 AM, Heinrich Schuchardt
 wrote:
> For Odroid C2 I have compiled kernel
> 4.9.0-rc6-next-20161124-1-gbf7e142
> with one additional patch
> https://github.com/xypron/kernel-odroid-c2/blob/master/patch/0001-stmmac-RTL8211F-Meson-GXBB-TX-throughput-problems.patch
>
> I repeatedly see faults like the one below:
do you see the same errors with the RTL8211F patch *not* applied?

> [ 2557.400796] Unhandled fault: synchronous external abort (0x9210)
> at 0x40001e8ee4b0
> [ 2557.952413] CPU: 0 PID: 22837 Comm: cc1 Tainted: G  D
> 4.9.0-rc6-next-20161124-1-gbf7e142 #1
> [ 2557.962062] Hardware name: Hardkernel ODROID-C2 (DT)
> [ 2557.966980] task: 80006ddb7080 task.stack: 80006dd9c000
> [ 2557.972846] PC is at 0x6a0d98
> [ 2557.975776] LR is at 0x6a0e54
> [ 2557.978709] pc : [<006a0d98>] lr : [<006a0e54>]
> pstate: 8000
> [ 2557.986040] sp : f3ee5f80
> [ 2557.989318] x29: f3ee5f80 x28: 4b3f1240
> [ 2557.994578] x27: 012a7000 x26: 4b3f1288
> [ 2557.999840] x25: 00f58f88 x24: 4b3f1240
> [ 2558.005101] x23:  x22: 0001
> [ 2558.010362] x21: 0001 x20: 4b3f1250
> [ 2558.015623] x19: 0054 x18: 0001
> [ 2558.020885] x17: 48acaa10 x16: 01285050
> [ 2558.026146] x15: 4ad96dc8 x14: 001f
> [ 2558.031407] x13: 4b3f1270 x12: 4b3f1258
> [ 2558.036668] x11: 01347000 x10: 0661
> [ 2558.041930] x9 : 0005 x8 : 0003
> [ 2558.047191] x7 : 4b3f1240 x6 : 20020033
> [ 2558.052452] x5 : 4b402020 x4 : 4b3e1aa0
> [ 2558.057713] x3 : 000c x2 : 0020
> [ 2558.062974] x1 : 00f45000 x0 : 0065
> [ 2558.068235]
> [ 2558.069712] Internal error: Attempting to execute userspace memory:
> 860f [#7] PREEMPT SMP
> [ 2558.078155] Modules linked in: meson_rng rng_core meson_gxbb_wdt
> ip_tables x_tables ipv6 dwmac_generic realtek dwmac_meson8b
> stmmac_platform stmmac
> [ 2558.091267] CPU: 0 PID: 22837 Comm: cc1 Tainted: G  D
> 4.9.0-rc6-next-20161124-1-gbf7e142 #1
> [ 2558.100925] Hardware name: Hardkernel ODROID-C2 (DT)
> [ 2558.105841] task: 80006ddb7080 task.stack: 80006dd9c000
> [ 2558.111706] PC is at 0x6a0e54
> [ 2558.114638] LR is at 0x6a0e54
> [ 2558.117571] pc : [<006a0e54>] lr : [<006a0e54>]
> pstate: 63c5
> [ 2558.124902] sp : 80006dd9fec0
> [ 2558.128179] x29:  x28: 80006ddb7080
> [ 2558.133441] x27: 012a7000 x26: 4b3f1288
> [ 2558.138702] x25: 00f58f88 x24: 4b3f1240
> [ 2558.143963] x23: 8000 x22: 006a0d98
> [ 2558.149225] x21:  x20: 80006e223000
> [ 2558.154486] x19:  x18: 0010
> [ 2558.159747] x17: 48acaa10 x16: 01285050
> [ 2558.165008] x15: 88e91f07 x14: 0006
> [ 2558.170270] x13: 08e91f15 x12: 000f
> [ 2558.175531] x11: 0002 x10: 02ea
> [ 2558.180792] x9 : 80006dd9fb40 x8 : 00010a8b
> [ 2558.186053] x7 :  x6 : 020e
> [ 2558.191315] x5 : 020f020e x4 : 
> [ 2558.196576] x3 :  x2 : 020f
> [ 2558.201837] x1 : 80006ddb7080 x0 : 
> [ 2558.207098]
> [ 2558.208565] Process cc1 (pid: 22837, stack limit = 0x80006dd9c000)
> [ 2558.215035] Stack: (0x80006dd9fec0 to 0x80006dda)
> [ 2558.220728] fec0: 0065 00f45000 0020
> 000c
> [ 2558.228490] fee0: 4b3e1aa0 4b402020 20020033
> 4b3f1240
> [ 2558.236253] ff00: 0003 0005 0661
> 01347000
> [ 2558.244015] ff20: 4b3f1258 4b3f1270 001f
> 4ad96dc8
> [ 2558.251778] ff40: 01285050 48acaa10 0001
> 0054
> [ 2558.259540] ff60: 4b3f1250 0001 0001
> 
> [ 2558.267303] ff80: 4b3f1240 00f58f88 4b3f1288
> 012a7000
> [ 2558.275065] ffa0: 4b3f1240 f3ee5f80 006a0e54
> f3ee5f80
> [ 2558.282828] ffc0: 006a0d98 8000 0003
> 
> [ 2558.290590] ffe0:   
> 
> [ 2558.298351] Call trace:
> [ 2558.300769] Exception stack(0x80006dd9fcf0 to 0x80006dd9fe20)
> [ 2558.307149] fce0:   
> 0001
> [ 2558.314913] fd00: 80006dd9fec0 006a0e54 800073acf500
> 0004
> [ 2558.322675] fd20:  08dbbc18 80006ddb7080
> 6dd9fdd0
> [ 

[PATCH 0/2] net: phy: realtek: fix RTL8211F TX-delay handling

2016-11-25 Thread Martin Blumenstingl
The RTL8211F PHY driver currently enables the TX-delay only when the
phy-mode is PHY_INTERFACE_MODE_RGMII. This is incorrect, because there
are three RGMII variations of the phy-mode which explicitly request the
PHY to enable the RX and/or TX delay, while PHY_INTERFACE_MODE_RGMII
specifies that the PHY should disable the RX and/or TX delays.

Additionally to the RTL8211F PHY driver change this contains a small
update to the phy-mode documentation to clarify the purpose of the
RGMII phy-modes.
While this may not be perfect yet it's at least a start. Please feel
free to drop this patch from this series and send an improved version
yourself.

These patches are the results of recent discussions, see [0]

[0] http://lists.infradead.org/pipermail/linux-amlogic/2016-November/001688.html

Martin Blumenstingl (2):
  Documentation: devicetree: clarify usage of the RGMII phy-modes
  net: phy: realtek: fix enabling of the TX-delay for RTL8211F

 Documentation/devicetree/bindings/net/ethernet.txt | 24 ++
 drivers/net/phy/realtek.c  | 20 ++
 2 files changed, 32 insertions(+), 12 deletions(-)

-- 
2.10.2



[PATCH 1/2] Documentation: devicetree: clarify usage of the RGMII phy-modes

2016-11-25 Thread Martin Blumenstingl
RGMII requires special RX and/or TX delays depending on the actual
hardware circuit/wiring. These delays can be added by the MAC, the PHY
or the designer of the circuit (the latter means that no delay has to
be added by PHY or MAC).
There are 4 RGMII phy-modes used describe where a delay should be
applied:
- rgmii: the RX and TX delays are either added by the MAC (where the
  exact delay is typically configurable, and can be turned off when no
  extra delay is needed) or not needed at all (because the hardware
  wiring adds the delay already). The PHY should neither add the RX nor
  TX delay in this case.
- rgmii-rxid: configures the PHY to enable the RX delay. The MAC should
  not add the RX delay in this case.
- rgmii-txid: configures the PHY to enable the TX delay. The MAC should
  not add the TX delay in this case.
- rgmii-id: combines rgmii-rxid and rgmii-txid and thus configures the
  PHY to enable the RX and TX delays. The MAC should neither add the RX
  nor TX delay in this case.

Document these cases in the ethernet.txt documentation to make it clear
when to use each mode.
If applied incorrectly one might end up with MAC and PHY both enabling
for example the TX delay, which breaks ethernet TX traffic on 1000Mbit/s
links.

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 Documentation/devicetree/bindings/net/ethernet.txt | 24 ++
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/ethernet.txt 
b/Documentation/devicetree/bindings/net/ethernet.txt
index e1d7681..0515095 100644
--- a/Documentation/devicetree/bindings/net/ethernet.txt
+++ b/Documentation/devicetree/bindings/net/ethernet.txt
@@ -9,10 +9,26 @@ The following properties are common to the Ethernet 
controllers:
 - max-speed: number, specifies maximum speed in Mbit/s supported by the device;
 - max-frame-size: number, maximum transfer unit (IEEE defined MTU), rather than
   the maximum frame size (there's contradiction in ePAPR).
-- phy-mode: string, operation mode of the PHY interface; supported values are
-  "mii", "gmii", "sgmii", "qsgmii", "tbi", "rev-mii", "rmii", "rgmii", 
"rgmii-id",
-  "rgmii-rxid", "rgmii-txid", "rtbi", "smii", "xgmii", "trgmii"; this is now a
-  de-facto standard property;
+- phy-mode: string, operation mode of the PHY interface. This is now a de-facto
+  standard property; supported values are:
+  * "mii"
+  * "gmii"
+  * "sgmii"
+  * "qsgmii"
+  * "tbi"
+  * "rev-mii"
+  * "rmii"
+  * "rgmii" (RX and TX delays are added by the MAC when required)
+  * "rgmii-id" (RGMII with internal RX and TX delays provided by the PHY, the
+ MAC should not add the RX or TX delays in this case)
+  * "rgmii-rxid" (RGMII with internal RX delay provided by the PHY, the MAC
+ should not add an RX delay in this case)
+  * "rgmii-txid" (RGMII with internal TX delay provided by the PHY, the MAC
+ should not add an TX delay in this case)
+  * "rtbi"
+  * "smii"
+  * "xgmii"
+  * "trgmii"
 - phy-connection-type: the same as "phy-mode" property but described in ePAPR;
 - phy-handle: phandle, specifies a reference to a node representing a PHY
   device; this property is described in ePAPR and so preferred;
-- 
2.10.2



[PATCH 2/2] net: phy: realtek: fix enabling of the TX-delay for RTL8211F

2016-11-25 Thread Martin Blumenstingl
The old logic always enabled the TX-delay when the phy-mode was set to
PHY_INTERFACE_MODE_RGMII. There are dedicated phy-modes which tell the
PHY driver to enable the RX and/or TX delays:
- PHY_INTERFACE_MODE_RGMII should disable the RX and TX delay in the
  PHY (if required, the MAC should add the delays in this case)
- PHY_INTERFACE_MODE_RGMII_ID should enable RX and TX delay in the PHY
- PHY_INTERFACE_MODE_RGMII_TXID should enable the TX delay in the PHY
- PHY_INTERFACE_MODE_RGMII_RXID should enable the RX delay in the PHY
  (currently not supported by RTL8211F)

With this patch we enable the TX delay for PHY_INTERFACE_MODE_RGMII_ID
and PHY_INTERFACE_MODE_RGMII_TXID.
Additionally we now explicity disable the TX-delay, which seems to be
enabled automatically after a hard-reset of the PHY (by triggering it's
reset pin) to get a consistent state (as defined by the phy-mode).

This fixes a compatibility problem with some SoCs where the TX-delay was
also added by the MAC. With the TX-delay being applied twice the TX
clock was off and TX traffic was broken or very slow (<10Mbit/s) on
1000Mbit/s links.

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 drivers/net/phy/realtek.c | 20 
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index aadd6e9..9cbe645 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -102,15 +102,19 @@ static int rtl8211f_config_init(struct phy_device *phydev)
if (ret < 0)
return ret;
 
-   if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
-   /* enable TXDLY */
-   phy_write(phydev, RTL8211F_PAGE_SELECT, 0xd08);
-   reg = phy_read(phydev, 0x11);
+   phy_write(phydev, RTL8211F_PAGE_SELECT, 0xd08);
+   reg = phy_read(phydev, 0x11);
+
+   /* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
+   if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+   phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
reg |= RTL8211F_TX_DELAY;
-   phy_write(phydev, 0x11, reg);
-   /* restore to default page 0 */
-   phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0);
-   }
+   else
+   reg &= ~RTL8211F_TX_DELAY;
+
+   phy_write(phydev, 0x11, reg);
+   /* restore to default page 0 */
+   phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0);
 
return 0;
 }
-- 
2.10.2



[PATCH v2 7/7] ARM64: dts: amlogic: add the ethernet TX delay configuration

2016-11-25 Thread Martin Blumenstingl
This adds the amlogic,tx-delay-ns with the old (hardcoded) default value
of 2ns to all boards which are using an RGMII ethernet PHY.

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts  | 2 ++
 arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi | 2 ++
 arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi | 2 ++
 arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts | 2 ++
 arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts  | 2 ++
 arch/arm64/boot/dts/amlogic/meson-gxm-s912-q200.dts  | 2 ++
 6 files changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts 
b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
index cbaf024..fdade07 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
@@ -161,6 +161,8 @@
snps,reset-delays-us = <0 1 100>;
snps,reset-active-low;
 
+   amlogic,tx-delay-ns = <2>;
+
phy-mode = "rgmii";
 };
 
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi 
b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
index 2abc553..8172e12 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
@@ -152,6 +152,8 @@
snps,reset-delays-us = <0 1 100>;
snps,reset-active-low;
 
+   amlogic,tx-delay-ns = <2>;
+
phy-mode = "rgmii";
 };
 
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi 
b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
index a0e92e3..ab49712 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
@@ -131,6 +131,8 @@
snps,reset-delays-us = <0 1 100>;
snps,reset-active-low;
 
+   amlogic,tx-delay-ns = <2>;
+
phy-mode = "rgmii";
 };
 
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts 
b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts
index f66939c..7fd11c6 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts
@@ -64,6 +64,8 @@
snps,reset-delays-us = <0 1 100>;
snps,reset-active-low;
 
+   amlogic,tx-delay-ns = <2>;
+
/* External PHY is in RGMII */
phy-mode = "rgmii";
 };
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts 
b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
index d320727..f83d6dc 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
@@ -156,6 +156,8 @@
snps,reset-delays-us = <0 1 100>;
snps,reset-active-low;
 
+   amlogic,tx-delay-ns = <2>;
+
/* External PHY is in RGMII */
phy-mode = "rgmii";
 };
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-s912-q200.dts 
b/arch/arm64/boot/dts/amlogic/meson-gxm-s912-q200.dts
index 5dbc660..e428e29 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxm-s912-q200.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-s912-q200.dts
@@ -64,6 +64,8 @@
snps,reset-delays-us = <0 1 100>;
snps,reset-active-low;
 
+   amlogic,tx-delay-ns = <2>;
+
/* External PHY is in RGMII */
phy-mode = "rgmii";
 };
-- 
2.10.2



[PATCH v2 5/7] ARM64: dts: meson-gxbb-p20x: add reset for the ethernet PHY

2016-11-25 Thread Martin Blumenstingl
This resets the ethernet PHY during boot to get the PHY into a "clean"
state. While here also specify the phy-handle of the ethmac node to
make the PHY configuration similar to the one we have on GXL devices.

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi 
b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
index 203be28..2abc553 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
@@ -134,10 +134,25 @@
pinctrl-names = "default";
 };
 
+ {
+   ethernet_phy0: ethernet-phy@0 {
+   compatible = "ethernet-phy-ieee802.3-c22";
+   reg = <0>;
+   };
+};
+
  {
status = "okay";
pinctrl-0 = <_rgmii_pins>;
pinctrl-names = "default";
+
+   phy-handle = <_phy0>;
+
+   snps,reset-gpio = < GPIOZ_14 0>;
+   snps,reset-delays-us = <0 1 100>;
+   snps,reset-active-low;
+
+   phy-mode = "rgmii";
 };
 
  {
-- 
2.10.2



[PATCH v2 2/7] net: stmmac: dwmac-meson8b: make the RGMII TX delay configurable

2016-11-25 Thread Martin Blumenstingl
Prior to this patch we were using a hardcoded RGMII TX clock delay of
2ns (= 1/4 cycle of the 125MHz RGMII TX clock). This value works for
many boards, but unfortunately not for all (due to the way the actual
circuit is designed, sometimes because the TX delay is enabled in the
PHY, etc.). Making the TX delay on the MAC side configurable allows us
to support all possible hardware combinations.

This allows fixing a compatibility issue on some boards, where the
RTL8211F PHY is configured to generate the TX delay. We can now turn
off the TX delay in the MAC, because otherwise we would be applying the
delay twice (which results in non-working TX traffic).

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c| 26 +-
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index 250e4ce..8ba33be 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -35,10 +35,6 @@
 
 #define PRG_ETH0_TXDLY_SHIFT   5
 #define PRG_ETH0_TXDLY_MASKGENMASK(6, 5)
-#define PRG_ETH0_TXDLY_OFF (0x0 << PRG_ETH0_TXDLY_SHIFT)
-#define PRG_ETH0_TXDLY_QUARTER (0x1 << PRG_ETH0_TXDLY_SHIFT)
-#define PRG_ETH0_TXDLY_HALF(0x2 << PRG_ETH0_TXDLY_SHIFT)
-#define PRG_ETH0_TXDLY_THREE_QUARTERS  (0x3 << PRG_ETH0_TXDLY_SHIFT)
 
 /* divider for the result of m250_sel */
 #define PRG_ETH0_CLK_M250_DIV_SHIFT7
@@ -69,6 +65,8 @@ struct meson8b_dwmac {
 
struct clk_divider  m25_div;
struct clk  *m25_div_clk;
+
+   u32 tx_delay_ns;
 };
 
 static void meson8b_dwmac_mask_bits(struct meson8b_dwmac *dwmac, u32 reg,
@@ -179,6 +177,7 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
 {
int ret;
unsigned long clk_rate;
+   u8 tx_dly_val;
 
switch (dwmac->phy_mode) {
case PHY_INTERFACE_MODE_RGMII:
@@ -196,9 +195,13 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac 
*dwmac)
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
PRG_ETH0_INVERTED_RMII_CLK, 0);
 
-   /* TX clock delay - all known boards use a 1/4 cycle delay */
+   /* TX clock delay in ns = "8ns / 4 * tx_dly_val" (where
+* 8ns are exactly one cycle of the 125MHz RGMII TX clock):
+* 0ns = 0x0, 2ns = 0x1, 4ns = 0x2, 6ns = 0x3
+*/
+   tx_dly_val = dwmac->tx_delay_ns >> 1;
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TXDLY_MASK,
-   PRG_ETH0_TXDLY_QUARTER);
+   tx_dly_val << PRG_ETH0_TXDLY_SHIFT);
break;
 
case PHY_INTERFACE_MODE_RMII:
@@ -277,6 +280,17 @@ static int meson8b_dwmac_probe(struct platform_device 
*pdev)
if (dwmac->phy_mode < 0) {
dev_err(>dev, "missing phy-mode property\n");
return -EINVAL;
+   } else if (dwmac->phy_mode != PHY_INTERFACE_MODE_RMII) {
+   ret = of_property_read_u32(pdev->dev.of_node,
+  "amlogic,tx-delay-ns",
+  >tx_delay_ns);
+   if (ret && dwmac->phy_mode == PHY_INTERFACE_MODE_RGMII)
+   /* default to a TX clock delay of 2ns when the PHY is
+* connected via RGMII (with RGMII_ID and RGMII_TXID
+* the TX clock delay is generated by the PHY and thus
+* we use the default 0ns delay in these case).
+*/
+   dwmac->tx_delay_ns = 2;
}
 
ret = meson8b_init_clk(dwmac);
-- 
2.10.2



[PATCH v2 6/7] ARM64: dts: meson-gxbb-vega-s95: add reset for the ethernet PHY

2016-11-25 Thread Martin Blumenstingl
This resets the ethernet PHY during boot to get the PHY into a "clean"
state. While here also specify the phy-handle of the ethmac node to
make the PHY configuration similar to the one we have on GXL devices.

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi 
b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
index e59ad30..a0e92e3 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
@@ -113,10 +113,25 @@
pinctrl-names = "default";
 };
 
+ {
+   ethernet_phy0: ethernet-phy@0 {
+   compatible = "ethernet-phy-id001c.c916", 
"ethernet-phy-ieee802.3-c22";
+   reg = <0>;
+   };
+};
+
  {
status = "okay";
pinctrl-0 = <_rgmii_pins>;
pinctrl-names = "default";
+
+   phy-handle = <_phy0>;
+
+   snps,reset-gpio = < GPIOZ_14 0>;
+   snps,reset-delays-us = <0 1 100>;
+   snps,reset-active-low;
+
+   phy-mode = "rgmii";
 };
 
 _phy {
-- 
2.10.2



[PATCH v2 3/7] ARM64: dts: meson-gx: move the MDIO node to meson-gx

2016-11-25 Thread Martin Blumenstingl
stmmac's MDIO bus is currently only defined in meson-gxl.dtsi. Move it
up to meson-gx to allow us to keep the stmmac configuration for
meson-gxbb similar to the configuration on meson-gxl.

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 arch/arm64/boot/dts/amlogic/meson-gx.dtsi  | 6 ++
 arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 6 --
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi 
b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
index 47ab306..a2c3ca6 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
@@ -371,6 +371,12 @@
interrupt-names = "macirq";
phy-mode = "rgmii";
status = "disabled";
+
+   mdio0: mdio {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   compatible = "snps,dwmac-mdio";
+   };
};
 
apb: apb@d000 {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi 
b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
index 3af54dc..aa3cd80 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
@@ -57,12 +57,6 @@
 < CLKID_FCLK_DIV2>,
 < CLKID_MPLL2>;
clock-names = "stmmaceth", "clkin0", "clkin1";
-
-   mdio0: mdio {
-   #address-cells = <1>;
-   #size-cells = <0>;
-   compatible = "snps,dwmac-mdio";
-   };
 };
 
  {
-- 
2.10.2



[PATCH v2 4/7] ARM64: dts: meson-gxbb-odroidc2: add reset for the ethernet PHY

2016-11-25 Thread Martin Blumenstingl
This resets the ethernet PHY during boot to get the PHY into a "clean"
state. While here also specify the phy-handle of the ethmac node to
make the PHY configuration similar to the one we have on GXL devices.

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts 
b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
index 238fbea..cbaf024 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
@@ -143,10 +143,25 @@
pinctrl-names = "default";
 };
 
+ {
+   ethernet_phy0: ethernet-phy@0 {
+   compatible = "ethernet-phy-id001c.c916", 
"ethernet-phy-ieee802.3-c22";
+   reg = <0>;
+   };
+};
+
  {
status = "okay";
pinctrl-0 = <_rgmii_pins>;
pinctrl-names = "default";
+
+   phy-handle = <_phy0>;
+
+   snps,reset-gpio = < GPIOZ_14 0>;
+   snps,reset-delays-us = <0 1 100>;
+   snps,reset-active-low;
+
+   phy-mode = "rgmii";
 };
 
  {
-- 
2.10.2



[PATCH v2 1/7] net: dt-bindings: add RGMII TX delay configuration to meson8b-dwmac

2016-11-25 Thread Martin Blumenstingl
This allows configuring the RGMII TX clock delay. The RGMII clock is
generated by underlying hardware of the the Meson 8b / GXBB DWMAC glue.
The configuration depends on the actual hardware (no delay may be
needed due to the design of the actual circuit, the PHY might add this
delay, etc.).

Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
---
 Documentation/devicetree/bindings/net/meson-dwmac.txt | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/meson-dwmac.txt 
b/Documentation/devicetree/bindings/net/meson-dwmac.txt
index 89e62dd..f8bc540 100644
--- a/Documentation/devicetree/bindings/net/meson-dwmac.txt
+++ b/Documentation/devicetree/bindings/net/meson-dwmac.txt
@@ -25,6 +25,20 @@ Required properties on Meson8b and newer:
- "clkin0" - first parent clock of the internal mux
- "clkin1" - second parent clock of the internal mux
 
+Optional properties on Meson8b and newer:
+- amlogic,tx-delay-ns: The internal RGMII TX clock delay (provided
+   by this driver) in nanoseconds. Allowed values
+   are: 0ns, 2ns, 4ns, 6ns.
+   This must be configured when the phy-mode is
+   "rgmii" (typically a value of 2ns is used in
+   this case).
+   When phy-mode is set to "rgmii-id" or
+   "rgmii-txid" the TX clock delay is already
+   provided by the PHY. In that case this
+   property should be set to 0ns (which disables
+   the TX clock delay in the MAC to prevent the
+   clock from going off because both PHY and MAC
+   are adding a delay).
 
 Example for Meson6:
 
-- 
2.10.2



[PATCH v2 0/7] stmmac: dwmac-meson8b: configurable RGMII TX delay

2016-11-25 Thread Martin Blumenstingl
Currently the dwmac-meson8b stmmac glue driver uses a hardcoded 1/4
cycle TX clock delay. This seems to work fine for many boards (for
example Odroid-C2 or Amlogic's reference boards) but there are some
others where TX traffic is simply broken.
There are probably multiple reasons why it's working on some boards
while it's broken on others:
- some of Amlogic's reference boards are using a Micrel PHY
- hardware circuit design
- maybe more...

iperf3 results on my Mecool BB2 board (Meson GXM, RTL8211F PHY) with
TX clock delay disabled on the MAC (as it's enabled in the PHY driver).
TX throughput was virtually zero before:
$ iperf3 -c 192.168.1.100 -R
Connecting to host 192.168.1.100, port 5201
Reverse mode, remote host 192.168.1.100 is sending
[  4] local 192.168.1.206 port 52828 connected to 192.168.1.100 port 5201
[ ID] Interval   Transfer Bandwidth
[  4]   0.00-1.00   sec   108 MBytes   901 Mbits/sec
[  4]   1.00-2.00   sec  94.2 MBytes   791 Mbits/sec
[  4]   2.00-3.00   sec  96.5 MBytes   810 Mbits/sec
[  4]   3.00-4.00   sec  96.2 MBytes   808 Mbits/sec
[  4]   4.00-5.00   sec  96.6 MBytes   810 Mbits/sec
[  4]   5.00-6.00   sec  96.5 MBytes   810 Mbits/sec
[  4]   6.00-7.00   sec  96.6 MBytes   810 Mbits/sec
[  4]   7.00-8.00   sec  96.5 MBytes   809 Mbits/sec
[  4]   8.00-9.00   sec   105 MBytes   884 Mbits/sec
[  4]   9.00-10.00  sec   111 MBytes   934 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval   Transfer Bandwidth   Retr
[  4]   0.00-10.00  sec  1000 MBytes   839 Mbits/sec0 sender
[  4]   0.00-10.00  sec   998 MBytes   837 Mbits/sec  receiver

iperf Done.
$ iperf3 -c 192.168.1.100
Connecting to host 192.168.1.100, port 5201
[  4] local 192.168.1.206 port 52832 connected to 192.168.1.100 port 5201
[ ID] Interval   Transfer Bandwidth   Retr  Cwnd
[  4]   0.00-1.01   sec  99.5 MBytes   829 Mbits/sec  117139 KBytes
[  4]   1.01-2.00   sec   105 MBytes   884 Mbits/sec  129   70.7 KBytes
[  4]   2.00-3.01   sec   107 MBytes   889 Mbits/sec  106187 KBytes
[  4]   3.01-4.01   sec   105 MBytes   878 Mbits/sec   92143 KBytes
[  4]   4.01-5.00   sec   105 MBytes   882 Mbits/sec  140129 KBytes
[  4]   5.00-6.01   sec   106 MBytes   883 Mbits/sec  115195 KBytes
[  4]   6.01-7.00   sec   102 MBytes   863 Mbits/sec  133   70.7 KBytes
[  4]   7.00-8.01   sec   106 MBytes   884 Mbits/sec  143   97.6 KBytes
[  4]   8.01-9.01   sec   104 MBytes   875 Mbits/sec  124107 KBytes
[  4]   9.01-10.01  sec   105 MBytes   876 Mbits/sec   90139 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval   Transfer Bandwidth   Retr
[  4]   0.00-10.01  sec  1.02 GBytes   874 Mbits/sec  1189 sender
[  4]   0.00-10.01  sec  1.02 GBytes   873 Mbits/sec  receiver

iperf Done.

I get similar TX throughput on my Meson GXBB "MXQ Pro+" board when I
disable the PHY's TX-delay and configure a 4ms TX-delay on the MAC.
So changes to at least the RTL8211F PHY driver are needed to get it
working properly in all situations.


NOTE: patches 3-7 should be taken though the Amlogic tree. patches 1
and 2 can be taken through the net-tree or through the Amlogic tree.
There shouldn't be a runtime dependency as long as phy-mode "rgmii"
(or the not-relevant-for-this-case "rmii") is used (which is currently
the case for all ARM64 meson-gx boards) due to the dwmac-meson8b's
default 2ns TX-delay.


Changes since v1:
- renamed the devicetree property "amlogic,tx-delay" to
  "amlogic,tx-delay-ns", which makes the .dts easier to read as we can
  simply specify human-readable values instead of having "preprocessor
  defines and calculation in human brain". Thanks to Andrew Lunn for
  the suggestion!
- improved documentation to indicate when the MAC TX-delay should be
  configured and how to use the PHY's TX-delay
- changed the default TX-delay in the dwmac-meson8b driver from 2ns
  to 0ms when any of the rgmii-*id modes are used (the 2ns default
  value still applies for phy-mode "rgmii")
- added patches to properly reset the PHY on Meson GXBB devices and to
  use a similar configuration than the one we use on Meson GXL devices
  (by passing a phy-handle to stmmac and defining the PHY in the mdio0
  bus - patch 3-6)
- add the "amlogic,tx-delay-ns" property to all boards which are using
  the RGMII PHY (patch 7)


Martin Blumenstingl (7):
  net: dt-bindings: add RGMII TX delay configuration to meson8b-dwmac
  net: stmmac: dwmac-meson8b: make the RGMII TX delay configurable
  ARM64: dts: meson-gx: move the MDIO node to meson-gx
  ARM64: dts: meson-gxbb-odroidc2: add reset for the ethernet PHY
  ARM64: dts: meson-gxbb-p20x: add reset for the ethernet PHY
  ARM64: dts: meson-gxbb-vega-s95: add reset for the ethernet PHY
  ARM64: dts: amlogic: add the ethernet TX delay configuration

 .../devic

Re: [net-next PATCH v1 0/2] stmmac: dwmac-meson8b: configurable RGMII TX delay

2016-11-24 Thread Martin Blumenstingl
On Thu, Nov 24, 2016 at 7:55 PM, Florian Fainelli <f.faine...@gmail.com> wrote:
> Le 24/11/2016 à 09:05, Martin Blumenstingl a écrit :
>> On Thu, Nov 24, 2016 at 4:56 PM, Jerome Brunet <jbru...@baylibre.com> wrote:
>>> On Thu, 2016-11-24 at 15:34 +0100, Martin Blumenstingl wrote:
>>>> Currently the dwmac-meson8b stmmac glue driver uses a hardcoded 1/4
>>>> cycle TX clock delay. This seems to work fine for many boards (for
>>>> example Odroid-C2 or Amlogic's reference boards) but there are some
>>>> others where TX traffic is simply broken.
>>>> There are probably multiple reasons why it's working on some boards
>>>> while it's broken on others:
>>>> - some of Amlogic's reference boards are using a Micrel PHY
>>>> - hardware circuit design
>>>> - maybe more...
>>>>
>>>> This raises a question though:
>>>> Which device is supposed to enable the TX delay when both MAC and PHY
>>>> support it? And should we implement it for each PHY / MAC separately
>>>> or should we think about a more generic solution (currently it's not
>>>> possible to disable the TX delay generated by the RTL8211F PHY via
>>>> devicetree when using phy-mode "rgmii")?
>>>
>>> Actually you can skip the part which activate the Tx-delay on the phy
>>> by setting "phy-mode = "rgmii-id" instead of "rgmii"
>>>
>>> phy->interface will no longer be PHY_INTERFACE_MODE_RGMII
>>> but PHY_INTERFACE_MODE_RGMII_ID.
>> unfortunately this is not true for RTL8211F (I did my previous tests
>> with the same expectation in mind)!
>> the code seems to suggest that TX-delay is disabled whenever mode !=
>> PHY_INTERFACE_MODE_RGMII.
>> BUT: on my device RTL8211F_TX_DELAY is set even before
>> "phy_write(phydev, 0x11, reg);"!
>
> (Adding Sebastian (and Mans, and Andrew) since he raised the same
> question a while ago. I think I now understand a bit better what
> Sebastian was after a couple of weeks ago)
>
>>
>> Based on what I found it seems that rgmii-id, rgmii-txid and
>> rgmii-rxid are supposed to be handled by the PHY.
>
> Correct, the meaning of PHY_INTERFACE_MODE should be from the
> perspective of the PHY device:
>
> - PHY_INTERFACE_MODE_RGMII_TXID means that the PHY is responsible for
> adding a delay when the MAC transmits (TX MAC -> PHY (delay) -> wire)
> - PHY_INTERFACE_MODE_RGMII_RXID means that the PHY is responsible for
> adding a delay when the MAC receives (RX MAC <- (delay) PHY) <- wire)
and PHY_INTERFACE_MODE_RGMII_ID is basically _TXID and _RXID combined
(meaning that the PHY is responsible for the TX and RX delays)

>> That would mean that we have two problems here:
>> 1) drivers/net/phy/realtek.c:rtl8211f_config_init should check for
>> PHY_INTERFACE_MODE_RGMII_ID or PHY_INTERFACE_MODE_RGMII_TXID and
>> enable the TX-delay in that case - otherwise explicitly disable it
>
> Agreed.
(on a side-not: it seems that the RTL8211F's TX-delay setting is
either untouched by a hardware reset via GPIO or enabled automatically
during hardware reset via GPIO)

>> 2) dwmac-meson8b.c should only use the configured TX-delay for
>> PHY_INTERFACE_MODE_RGMII
>> @Florian: could you please share your thoughts on this (who handles
>> the TX delay in which case)?
>
> This also seems reasonable to do, provided that the PHY is also properly
> configured not to add delays in both directions, and therefore assumes
> that the MAC does it.
on Amlogic Meson systems (at least on the ARM64 ones) all customer
devices with Gbit ethernet are using the RTL8211F PHY. The only
exception are some development/reference boards from Amlogic
themselves, which seem to be using a Micrel RGMII PHY.

> We have a fairly large problem with how RGMII delays are done in PHYLIB
> and Ethernet MAC drivers (or just in general), where we can't really
> intersect properly what a PHY is supporting (in terms of internal
> delays), and what the MAC supports either. One possible approach could
> be to update PHY drivers a list of PHY_INTERFACE_MODE_* that they
> support (ideally, even with normalized nanosecond delay values), and
> then intersect that with the requested phy_interface_t during
> phy_{attach,connect} time, and feed this back to the MAC with a special
> error code/callback, so we could gracefully try to choose another
> PHY_INTERFACE_MODE_* value that the MAC supports
>
> A larger problem is that a number of drivers have been deployed, and
> Device Trees, possibly with the meaning of "phy-mode" and
> "phy-connection-type" bein

Re: [RFC PATCH net v2 0/3] Fix OdroidC2 Gigabit Tx link issue

2016-11-24 Thread Martin Blumenstingl
On Thu, Nov 24, 2016 at 5:01 PM, Jerome Brunet <jbru...@baylibre.com> wrote:
> On Thu, 2016-11-24 at 15:40 +0100, Martin Blumenstingl wrote:
>> Hi Jerome,
>>
>> On Mon, Nov 21, 2016 at 4:35 PM, Jerome Brunet <jbru...@baylibre.com>
>> wrote:
>> >
>> > This patchset fixes an issue with the OdroidC2 board (DWMAC +
>> > RTL8211F).
>> > Initially reported as a low Tx throughput issue at gigabit speed,
>> > the
>> > platform enters LPI too often. This eventually break the link (both
>> > Tx
>> > and Rx), and require to bring the interface down and up again to
>> > get the
>> > Rx path working again.
>> >
>> > The root cause of this issue is not fully understood yet but
>> > disabling EEE
>> > advertisement on the PHY prevent this feature to be negotiated.
>> > With this change, the link is stable and reliable, with the
>> > expected
>> > throughput performance.
>> I have just sent a series which allows configuring the TX delay on
>> the
>> MAC (dwmac-meson8b glue) side: [0]
>> Disabling the TX delay generated by the MAC fixes TX throughput for
>> me, even when leaving EEE enabled in the RTL8211F PHY driver!
>>
>> Unfortunately the RTL8211F PHY is a black-box for the community
>> because there is no public datasheeet available.
>> *maybe* (pure speculation!) they're enabling the TX delay based on
>> some internal magic only when EEE is enabled.
>
> Hi already tried acting on the register setting the TX_delay. I also
> tried on the PHY. I never been able to improve situation on the
> Odroic2. Only disabling EEE improved the situation.
OK, thanks for clarifying this!

> To make sure, i tried again with your patch but the result remains
> unchanged. With Tx_delay disabled (either the mac or the phy), the
> situation is even worse, it seems that nothing gets through
This is interesting, because in your case you should have a 4ns TX
delay (2ns from the MAC and presumably 2ns from the PHY).
Maybe that is also the reason why the TX delay is configurable in 2ns
steps in PRG_ETHERNET0 on Amlogic SoCs.

out of curiosity: have you tried setting a 4ns (half clock-cycle) TX
delay for the MAC and disabling it in the PHY?


Regards,
Martin


Re: [net-next PATCH v1 0/2] stmmac: dwmac-meson8b: configurable RGMII TX delay

2016-11-24 Thread Martin Blumenstingl
On Thu, Nov 24, 2016 at 4:56 PM, Jerome Brunet <jbru...@baylibre.com> wrote:
> On Thu, 2016-11-24 at 15:34 +0100, Martin Blumenstingl wrote:
>> Currently the dwmac-meson8b stmmac glue driver uses a hardcoded 1/4
>> cycle TX clock delay. This seems to work fine for many boards (for
>> example Odroid-C2 or Amlogic's reference boards) but there are some
>> others where TX traffic is simply broken.
>> There are probably multiple reasons why it's working on some boards
>> while it's broken on others:
>> - some of Amlogic's reference boards are using a Micrel PHY
>> - hardware circuit design
>> - maybe more...
>>
>> This raises a question though:
>> Which device is supposed to enable the TX delay when both MAC and PHY
>> support it? And should we implement it for each PHY / MAC separately
>> or should we think about a more generic solution (currently it's not
>> possible to disable the TX delay generated by the RTL8211F PHY via
>> devicetree when using phy-mode "rgmii")?
>
> Actually you can skip the part which activate the Tx-delay on the phy
> by setting "phy-mode = "rgmii-id" instead of "rgmii"
>
> phy->interface will no longer be PHY_INTERFACE_MODE_RGMII
> but PHY_INTERFACE_MODE_RGMII_ID.
unfortunately this is not true for RTL8211F (I did my previous tests
with the same expectation in mind)!
the code seems to suggest that TX-delay is disabled whenever mode !=
PHY_INTERFACE_MODE_RGMII.
BUT: on my device RTL8211F_TX_DELAY is set even before
"phy_write(phydev, 0x11, reg);"!

Based on what I found it seems that rgmii-id, rgmii-txid and
rgmii-rxid are supposed to be handled by the PHY.
That would mean that we have two problems here:
1) drivers/net/phy/realtek.c:rtl8211f_config_init should check for
PHY_INTERFACE_MODE_RGMII_ID or PHY_INTERFACE_MODE_RGMII_TXID and
enable the TX-delay in that case - otherwise explicitly disable it
2) dwmac-meson8b.c should only use the configured TX-delay for
PHY_INTERFACE_MODE_RGMII
@Florian: could you please share your thoughts on this (who handles
the TX delay in which case)?


Regards,
Martin


Re: [net-next PATCH v1 1/2] net: dt-bindings: add RGMII TX delay configuration to meson8b-dwmac

2016-11-24 Thread Martin Blumenstingl
Hi Andrew,

On Thu, Nov 24, 2016 at 4:48 PM, Andrew Lunn  wrote:
>> The configuration values are provided as preprocessor macros to make the
>> devicetree files easier to read.
>
> Hi Martin
>
> If i'm reading the code/comments correctly, you can set the delay to
> 0, 2, 4 or 6ns? So calling this property amlogic,tx-delay-ns would be
> even easier to read.
indeed, this sounds like a very nice idea (as it moves the calculation
from the programmer's brain to dwmac-meson8b.c)!

I'll send an updated version once I received enough feedback (in case
something else is wrong with the patches)


Re: [RFC PATCH net v2 0/3] Fix OdroidC2 Gigabit Tx link issue

2016-11-24 Thread Martin Blumenstingl
Hi Jerome,

On Mon, Nov 21, 2016 at 4:35 PM, Jerome Brunet  wrote:
> This patchset fixes an issue with the OdroidC2 board (DWMAC + RTL8211F).
> Initially reported as a low Tx throughput issue at gigabit speed, the
> platform enters LPI too often. This eventually break the link (both Tx
> and Rx), and require to bring the interface down and up again to get the
> Rx path working again.
>
> The root cause of this issue is not fully understood yet but disabling EEE
> advertisement on the PHY prevent this feature to be negotiated.
> With this change, the link is stable and reliable, with the expected
> throughput performance.
I have just sent a series which allows configuring the TX delay on the
MAC (dwmac-meson8b glue) side: [0]
Disabling the TX delay generated by the MAC fixes TX throughput for
me, even when leaving EEE enabled in the RTL8211F PHY driver!

Unfortunately the RTL8211F PHY is a black-box for the community
because there is no public datasheeet available.
*maybe* (pure speculation!) they're enabling the TX delay based on
some internal magic only when EEE is enabled.

Jerome, could you please re-test the behavior on your Odroid-C2 when
you have EEE still enabled but the TX-delay disabled?
In my case throughput is fine, and "$ ethtool -S eth0 | grep lpi" gives:
irq_tx_path_in_lpi_mode_n: 0
irq_tx_path_exit_lpi_mode_n: 0
irq_rx_path_in_lpi_mode_n: 0
irq_rx_path_exit_lpi_mode_n: 0


Regards,
Martin


[0] http://lists.infradead.org/pipermail/linux-amlogic/2016-November/001674.html


  1   2   >