diff mbox

[RFC,08/13] dwmac-meson8b: add support for phy selection

Message ID 1477060838-14164-9-git-send-email-narmstrong@baylibre.com (mailing list archive)
State New, archived
Headers show

Commit Message

Neil Armstrong Oct. 21, 2016, 2:40 p.m. UTC
The Meson GXL dwmac Glue Layer also provides switching between an external PHY
and an internal RMII 10/100 PHY.
Add a way to setup the correct PHY switching from a device tree attribute.

Currently, the register format is unknown and this is a temporary workaround
until a clarification on the registers fields is received from Amlogic.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c    | 25 ++++++++++++++++++++++
 1 file changed, 25 insertions(+)

Comments

Andrew Lunn Oct. 21, 2016, 3:46 p.m. UTC | #1
On Fri, Oct 21, 2016 at 04:40:33PM +0200, Neil Armstrong wrote:
> The Meson GXL dwmac Glue Layer also provides switching between an external PHY
> and an internal RMII 10/100 PHY.
> Add a way to setup the correct PHY switching from a device tree attribute.

Hi Neil

Can this be made automatic?

The internal PHY appears to be on address 8. Can there also be an
external PHY on address 8? Could you follow the phy-handle link to the
phy node, check the address, and if it is 8, configure for an internal
PHY?

	Andrew
Andrew Lunn Oct. 21, 2016, 3:54 p.m. UTC | #2
On Fri, Oct 21, 2016 at 04:40:33PM +0200, Neil Armstrong wrote:
> The Meson GXL dwmac Glue Layer also provides switching between an external PHY
> and an internal RMII 10/100 PHY.
> Add a way to setup the correct PHY switching from a device tree attribute.

Humm, actually. Maybe PHY_IS_INTERNAL in the phydrv->flags is the
better solution. The MAC can then use phy_is_internal(ndev->phydev) to
decide if this register needs programming.

       Andrew
Neil Armstrong Oct. 21, 2016, 3:59 p.m. UTC | #3
On 10/21/2016 05:54 PM, Andrew Lunn wrote:
> On Fri, Oct 21, 2016 at 04:40:33PM +0200, Neil Armstrong wrote:
>> The Meson GXL dwmac Glue Layer also provides switching between an external PHY
>> and an internal RMII 10/100 PHY.
>> Add a way to setup the correct PHY switching from a device tree attribute.
> 
> Humm, actually. Maybe PHY_IS_INTERNAL in the phydrv->flags is the
> better solution. The MAC can then use phy_is_internal(ndev->phydev) to
> decide if this register needs programming.
> 
>        Andrew
> 

Hi Andrew,

Yes this would be a good idea if we were able to scan the internal and external PHYs at the same time,
but with our limited knowledge the values we write in the register seems to switch a mux for the whole RMII
and MDIO signals to either interface.

Do you have knowledge if this case is already handled upstream ?

Thanks for your help,
Neil
Andrew Lunn Oct. 21, 2016, 4:08 p.m. UTC | #4
Hi Neil

> Yes this would be a good idea if we were able to scan the internal
> and external PHYs at the same time, but with our limited knowledge
> the values we write in the register seems to switch a mux for the
> whole RMII and MDIO signals to either interface.

Ah, O.K. So you need something like:

drivers/net/phy/mdio-mux-mmioreg.c

This seems to be limited to a single byte for the mux register, so you
might need to make some extensions.

      Andrew
Neil Armstrong Oct. 31, 2016, 2:23 p.m. UTC | #5
On 10/21/2016 06:08 PM, Andrew Lunn wrote:
> Hi Neil
> 
>> Yes this would be a good idea if we were able to scan the internal
>> and external PHYs at the same time, but with our limited knowledge
>> the values we write in the register seems to switch a mux for the
>> whole RMII and MDIO signals to either interface.
> 
> Ah, O.K. So you need something like:
> 
> drivers/net/phy/mdio-mux-mmioreg.c
> 
> This seems to be limited to a single byte for the mux register, so you
> might need to make some extensions.
> 
>       Andrew
> 

Thanks for the hint, I will try to make use of this !

Neil
diff mbox

Patch

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index 250e4ce..875cd7c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -53,10 +53,15 @@ 
 
 #define MUX_CLK_NUM_PARENTS		2
 
+#define PHYSEL_REG0			0x0
+#define PHYSEL_REG0_VALUE		0x10110181
+#define PHYSEL_REG1			0x4
+
 struct meson8b_dwmac {
 	struct platform_device	*pdev;
 
 	void __iomem		*regs;
+	void __iomem		*physel_regs;
 
 	phy_interface_t		phy_mode;
 
@@ -244,6 +249,23 @@  static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
 	meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TX_AND_PHY_REF_CLK,
 				PRG_ETH0_TX_AND_PHY_REF_CLK);
 
+	/* Select PHY, either internal or external if specified */
+	if (!IS_ERR(dwmac->physel_regs) &&
+	    of_find_property(dwmac->pdev->dev.of_node,
+			     "amlogic,phy-select", NULL)) {
+		u32 val;
+
+		ret = of_property_read_u32(dwmac->pdev->dev.of_node,
+					   "amlogic,phy-select", &val);
+		if (ret) {
+			dev_err(&dwmac->pdev->dev, "invalid phy-select property\n");
+		} else {
+			writel(PHYSEL_REG0_VALUE,
+			       dwmac->physel_regs + PHYSEL_REG0);
+			writel(val, dwmac->physel_regs + PHYSEL_REG1);
+		}
+	}
+
 	return 0;
 }
 
@@ -272,6 +294,9 @@  static int meson8b_dwmac_probe(struct platform_device *pdev)
 	if (IS_ERR(dwmac->regs))
 		return PTR_ERR(dwmac->regs);
 
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+	dwmac->physel_regs = devm_ioremap_resource(&pdev->dev, res);
+
 	dwmac->pdev = pdev;
 	dwmac->phy_mode = of_get_phy_mode(pdev->dev.of_node);
 	if (dwmac->phy_mode < 0) {