* [RFC] pinctrl: renesas: rzg2l: Add support to select MII/RGMII mode
@ 2021-11-18 14:55 Biju Das
2021-11-23 15:35 ` Geert Uytterhoeven
0 siblings, 1 reply; 2+ messages in thread
From: Biju Das @ 2021-11-18 14:55 UTC (permalink / raw)
To: Linus Walleij
Cc: Biju Das, Geert Uytterhoeven, linux-renesas-soc, linux-gpio,
Chris Paterson, Biju Das, Prabhakar Mahadev Lad
RZ/G2L supports Ether MII/RGMII mode control which select
the direction of the pins based on PHY mode.
This patch adds support to select MII/RGMII mode based on
the phy-mode property present in the ether node, as the
register for configuring the same is located in pinctrl block
rather than GbEthernet block.
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
Current names on HW manual is based on pins which is going to
change in next version like below.
P20_0->ETH0_mode
P29_0->ETH1_mode
---
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 70 +++++++++++++++++++++++++
1 file changed, 70 insertions(+)
diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index ccee9c9e2e22..bc86119be01e 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -92,6 +92,7 @@
#define PWPR (0x3014)
#define SD_CH(n) (0x3000 + (n) * 4)
#define QSPI (0x3008)
+#define ETHER_MODE (0x3018)
#define PVDD_1800 1 /* I/O domain voltage <= 1.8V */
#define PVDD_3300 0 /* I/O domain voltage >= 3.3V */
@@ -104,6 +105,10 @@
#define PFC_MASK 0x07
#define IEN_MASK 0x01
#define IOLH_MASK 0x03
+#define ETHER_MODE_ETH0_MASK BIT(0)
+#define ETHER_MODE_ETH1_MASK BIT(1)
+#define ETHER_MODE_ETH0_ADDR 0x11c20000
+#define ETHER_MODE_ETH1_ADDR 0x11c30000
#define PM_INPUT 0x1
#define PM_OUTPUT 0x2
@@ -1197,6 +1202,69 @@ static void rzg2l_pinctrl_clk_disable(void *data)
clk_disable_unprepare(data);
}
+static bool rzg2l_pinctrl_is_rgmii_mode(struct rzg2l_pinctrl *pctrl,
+ struct device_node *node)
+{
+ const char *mode = of_get_property(node, "phy-mode", NULL);
+ bool ret = false;
+
+ if (!mode) {
+ dev_err(pctrl->dev, "phy-mode missing, setting to mii mode");
+ return ret;
+ }
+
+ if ((!strcmp("rgmii", mode)) || (!strcmp("rgmii-id", mode)) ||
+ (!strcmp("rgmii-rxid", mode)) || (!strcmp("rgmii-txid", mode)))
+ ret = true;
+
+ return ret;
+}
+
+static void rzg2l_pinctrl_set_eth_mode(struct rzg2l_pinctrl *pctrl,
+ struct device_node *np)
+{
+ u8 reg = readb(pctrl->base + ETHER_MODE);
+ u8 mask = ETHER_MODE_ETH0_MASK;
+ const __be32 *prop;
+ u64 addr;
+
+ prop = of_get_property(np, "reg", NULL);
+ if (!prop)
+ return;
+
+ addr = of_read_number(prop, of_n_addr_cells(np));
+ if (addr == ETHER_MODE_ETH1_ADDR)
+ mask = ETHER_MODE_ETH1_MASK;
+
+ if (rzg2l_pinctrl_is_rgmii_mode(pctrl, np))
+ reg &= ~mask;
+ else
+ reg |= mask;
+
+ writeb(reg, pctrl->base + ETHER_MODE);
+}
+
+static void rzg2l_pinctrl_set_ether_modes(struct rzg2l_pinctrl *pctrl)
+{
+ struct device_node *np, *np1 = NULL;
+
+ np = of_find_compatible_node(NULL, NULL, "renesas,rzg2l-gbeth");
+ if (np) {
+ np1 = of_find_compatible_node(np, NULL, "renesas,rzg2l-gbeth");
+ if (of_device_is_available(np))
+ rzg2l_pinctrl_set_eth_mode(pctrl, np);
+
+ of_node_put(np);
+ }
+
+ if (np1) {
+ if (of_device_is_available(np1))
+ rzg2l_pinctrl_set_eth_mode(pctrl, np1);
+
+ of_node_put(np1);
+ }
+}
+
static int rzg2l_pinctrl_probe(struct platform_device *pdev)
{
struct rzg2l_pinctrl *pctrl;
@@ -1246,6 +1314,8 @@ static int rzg2l_pinctrl_probe(struct platform_device *pdev)
if (ret)
return ret;
+ rzg2l_pinctrl_set_ether_modes(pctrl);
+
dev_info(pctrl->dev, "%s support registered\n", DRV_NAME);
return 0;
}
--
2.17.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [RFC] pinctrl: renesas: rzg2l: Add support to select MII/RGMII mode
2021-11-18 14:55 [RFC] pinctrl: renesas: rzg2l: Add support to select MII/RGMII mode Biju Das
@ 2021-11-23 15:35 ` Geert Uytterhoeven
0 siblings, 0 replies; 2+ messages in thread
From: Geert Uytterhoeven @ 2021-11-23 15:35 UTC (permalink / raw)
To: Biju Das
Cc: Linus Walleij, Linux-Renesas, open list:GPIO SUBSYSTEM,
Chris Paterson, Biju Das, Prabhakar Mahadev Lad, Sergey Shtylyov
Hi Biju,
CC Sergey
On Thu, Nov 18, 2021 at 3:56 PM Biju Das <biju.das.jz@bp.renesas.com> wrote:
> RZ/G2L supports Ether MII/RGMII mode control which select
> the direction of the pins based on PHY mode.
>
> This patch adds support to select MII/RGMII mode based on
> the phy-mode property present in the ether node, as the
> register for configuring the same is located in pinctrl block
> rather than GbEthernet block.
>
> Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Thanks for your patch!
I can't really say I'm very enthusiastic about this. Looking up
Ethernet nodes like this is fragile, and doesn't work with dynamic
DT overlays (which are not supported upstream anyway, doh).
I think it would be better to configure this explicitly in DT,
especially since in RGMII mode, the user is supposed to configure
the TX_COL, TX_CRS, and RX_ERR in some specific way, too.
Documentation/devicetree/bindings/pinctrl/pincfg-node.yaml does
not define anything like this, but perhaps we can do something
direction-based?
The documentation for the related bits in the ETHER_MODE register says:
B'0 = RGMII: The Direction of the IO buffer is Output.
B’1 = MII(Initial value): The Direction of the IO buffer is Input.
Below a few general coding comments (which hopefully become
irrelevant soon...).
> ---
> Current names on HW manual is based on pins which is going to
> change in next version like below.
>
> P20_0->ETH0_mode
> P29_0->ETH1_mode
> ---
> drivers/pinctrl/renesas/pinctrl-rzg2l.c | 70 +++++++++++++++++++++++++
> 1 file changed, 70 insertions(+)
>
> diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> index ccee9c9e2e22..bc86119be01e 100644
> --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
> @@ -92,6 +92,7 @@
> #define PWPR (0x3014)
> #define SD_CH(n) (0x3000 + (n) * 4)
> #define QSPI (0x3008)
> +#define ETHER_MODE (0x3018)
>
> #define PVDD_1800 1 /* I/O domain voltage <= 1.8V */
> #define PVDD_3300 0 /* I/O domain voltage >= 3.3V */
> @@ -104,6 +105,10 @@
> #define PFC_MASK 0x07
> #define IEN_MASK 0x01
> #define IOLH_MASK 0x03
> +#define ETHER_MODE_ETH0_MASK BIT(0)
> +#define ETHER_MODE_ETH1_MASK BIT(1)
> +#define ETHER_MODE_ETH0_ADDR 0x11c20000
> +#define ETHER_MODE_ETH1_ADDR 0x11c30000
>
> #define PM_INPUT 0x1
> #define PM_OUTPUT 0x2
> @@ -1197,6 +1202,69 @@ static void rzg2l_pinctrl_clk_disable(void *data)
> clk_disable_unprepare(data);
> }
>
> +static bool rzg2l_pinctrl_is_rgmii_mode(struct rzg2l_pinctrl *pctrl,
> + struct device_node *node)
> +{
> + const char *mode = of_get_property(node, "phy-mode", NULL);
> + bool ret = false;
> +
> + if (!mode) {
> + dev_err(pctrl->dev, "phy-mode missing, setting to mii mode");
> + return ret;
> + }
> +
> + if ((!strcmp("rgmii", mode)) || (!strcmp("rgmii-id", mode)) ||
> + (!strcmp("rgmii-rxid", mode)) || (!strcmp("rgmii-txid", mode)))
return !strncmp(mode, "rgmii", strlen("rgmii"));?
> + ret = true;
> +
> + return ret;
> +}
> +
> +static void rzg2l_pinctrl_set_eth_mode(struct rzg2l_pinctrl *pctrl,
> + struct device_node *np)
> +{
> + u8 reg = readb(pctrl->base + ETHER_MODE);
> + u8 mask = ETHER_MODE_ETH0_MASK;
> + const __be32 *prop;
> + u64 addr;
> +
> + prop = of_get_property(np, "reg", NULL);
> + if (!prop)
> + return;
> +
> + addr = of_read_number(prop, of_n_addr_cells(np));
of_address_to_resource()
> + if (addr == ETHER_MODE_ETH1_ADDR)
> + mask = ETHER_MODE_ETH1_MASK;
> +
> + if (rzg2l_pinctrl_is_rgmii_mode(pctrl, np))
> + reg &= ~mask;
> + else
> + reg |= mask;
> +
> + writeb(reg, pctrl->base + ETHER_MODE);
> +}
> +
> +static void rzg2l_pinctrl_set_ether_modes(struct rzg2l_pinctrl *pctrl)
> +{
> + struct device_node *np, *np1 = NULL;
> +
> + np = of_find_compatible_node(NULL, NULL, "renesas,rzg2l-gbeth");
> + if (np) {
> + np1 = of_find_compatible_node(np, NULL, "renesas,rzg2l-gbeth");
> + if (of_device_is_available(np))
> + rzg2l_pinctrl_set_eth_mode(pctrl, np);
> +
> + of_node_put(np);
> + }
> +
> + if (np1) {
> + if (of_device_is_available(np1))
> + rzg2l_pinctrl_set_eth_mode(pctrl, np1);
> +
> + of_node_put(np1);
> + }
for_each_compatible_node(...) { ... }
> +}
> +
> static int rzg2l_pinctrl_probe(struct platform_device *pdev)
> {
> struct rzg2l_pinctrl *pctrl;
> @@ -1246,6 +1314,8 @@ static int rzg2l_pinctrl_probe(struct platform_device *pdev)
> if (ret)
> return ret;
>
> + rzg2l_pinctrl_set_ether_modes(pctrl);
> +
> dev_info(pctrl->dev, "%s support registered\n", DRV_NAME);
> return 0;
> }
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2021-11-23 15:35 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-18 14:55 [RFC] pinctrl: renesas: rzg2l: Add support to select MII/RGMII mode Biju Das
2021-11-23 15:35 ` Geert Uytterhoeven
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).