Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: dsa: rtl8365mb: set RGMII RX delay in steps of 0.3 ns

A contact at Realtek has clarified what exactly the units of RGMII RX
delay are. The answer is that the unit of RX delay is "about 0.3 ns".
Take this into account when parsing rx-internal-delay-ps by
approximating the closest step value. Delays of more than 2.1 ns are
rejected.

This obviously contradicts the previous assumption in the driver that a
step value of 4 was "about 2 ns", but Realtek also points out that it is
easy to find more than one RX delay step value which makes RGMII work.

Fixes: 4af2950c50c8 ("net: dsa: realtek-smi: add rtl8365mb subdriver for RTL8365MB-VC")
Cc: Arınç ÜNAL <arinc.unal@arinc9.com>
Signed-off-by: Alvin Šipraga <alsi@bang-olufsen.dk>
Acked-by: Arınç ÜNAL <arinc.unal@arinc9.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Alvin Šipraga and committed by
David S. Miller
ef136837 1ecab937

+6 -9
+6 -9
drivers/net/dsa/rtl8365mb.c
··· 760 760 * 0 = no delay, 1 = 2 ns delay 761 761 * RX delay: 762 762 * 0 = no delay, 7 = maximum delay 763 - * No units are specified, but there are a total of 8 steps. 763 + * Each step is approximately 0.3 ns, so the maximum delay is about 764 + * 2.1 ns. 764 765 * 765 766 * The vendor driver also states that this must be configured *before* 766 767 * forcing the external interface into a particular mode, which is done ··· 772 771 * specified. We ignore the detail of the RGMII interface mode 773 772 * (RGMII_{RXID, TXID, etc.}), as this is considered to be a PHY-only 774 773 * property. 775 - * 776 - * For the RX delay, we assume that a register value of 4 corresponds to 777 - * 2 ns. But this is just an educated guess, so ignore all other values 778 - * to avoid too much confusion. 779 774 */ 780 775 if (!of_property_read_u32(dn, "tx-internal-delay-ps", &val)) { 781 776 val = val / 1000; /* convert to ns */ ··· 784 787 } 785 788 786 789 if (!of_property_read_u32(dn, "rx-internal-delay-ps", &val)) { 787 - val = val / 1000; /* convert to ns */ 790 + val = DIV_ROUND_CLOSEST(val, 300); /* convert to 0.3 ns step */ 788 791 789 - if (val == 0 || val == 2) 790 - rx_delay = val * 2; 792 + if (val <= 7) 793 + rx_delay = val; 791 794 else 792 795 dev_warn(smi->dev, 793 - "EXT port RX delay must be 0 to 2 ns\n"); 796 + "EXT port RX delay must be 0 to 2.1 ns\n"); 794 797 } 795 798 796 799 ret = regmap_update_bits(