acf993a0f2
Recent changes to the Atheros at803x driver cause the approach taken here to stop working because commit6d4cd041f0
("net: phy: at803x: disable delay only for RGMII mode") and commitcd28d1d6e5
("net: phy: at803x: Disable phy delay for RGMII mode") fix the AR8031 driver to configure the phy's (RX/TX) delays as per the 'phy-mode' in the device tree. In particular, the phy tx (and rx) delays are updated again as per the 'phy-mode' *after* the code in here runs. Things worked before above commits, because the AR8031 comes out of reset with RX delay enabled, and the at803x driver didn't touch the delay configuration at all when "rgmii" mode was selected. It appears the code in here tries to make device trees work that incorrectly specify "rgmii", but that can't work any more and it is imperative since above commits to have the phy-mode configured correctly in the device tree. I suspect there are a few imx7d based boards using the ar8031 phy and phy-mode = "rgmii", but given I don't know which ones exactly, I am not in a position to update the respective device trees. Hence this patch is simply removing the superfluous code from the imx7d initialisation. An alternative could be to add a warning instead, but that would penalize all boards that have been updated already. Signed-off-by: André Draszik <git@andred.net> CC: Russell King <linux@armlinux.org.uk> CC: Shawn Guo <shawnguo@kernel.org> CC: Sascha Hauer <s.hauer@pengutronix.de> CC: Pengutronix Kernel Team <kernel@pengutronix.de> CC: Fabio Estevam <festevam@gmail.com> CC: NXP Linux Team <linux-imx@nxp.com> CC: Kate Stewart <kstewart@linuxfoundation.org> CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org> CC: Thomas Gleixner <tglx@linutronix.de> CC: Leonard Crestez <leonard.crestez@nxp.com> CC: linux-arm-kernel@lists.infradead.org Signed-off-by: Shawn Guo <shawnguo@kernel.org>
116 lines
2.5 KiB
C
116 lines
2.5 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* Copyright (C) 2015 Freescale Semiconductor, Inc.
|
|
*/
|
|
#include <linux/irqchip.h>
|
|
#include <linux/mfd/syscon.h>
|
|
#include <linux/mfd/syscon/imx7-iomuxc-gpr.h>
|
|
#include <linux/of_platform.h>
|
|
#include <linux/phy.h>
|
|
#include <linux/regmap.h>
|
|
|
|
#include <asm/mach/arch.h>
|
|
#include <asm/mach/map.h>
|
|
|
|
#include "common.h"
|
|
|
|
static int ar8031_phy_fixup(struct phy_device *dev)
|
|
{
|
|
u16 val;
|
|
|
|
/* Set RGMII IO voltage to 1.8V */
|
|
phy_write(dev, 0x1d, 0x1f);
|
|
phy_write(dev, 0x1e, 0x8);
|
|
|
|
/* disable phy AR8031 SmartEEE function. */
|
|
phy_write(dev, 0xd, 0x3);
|
|
phy_write(dev, 0xe, 0x805d);
|
|
phy_write(dev, 0xd, 0x4003);
|
|
val = phy_read(dev, 0xe);
|
|
val &= ~(0x1 << 8);
|
|
phy_write(dev, 0xe, val);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int bcm54220_phy_fixup(struct phy_device *dev)
|
|
{
|
|
/* enable RXC skew select RGMII copper mode */
|
|
phy_write(dev, 0x1e, 0x21);
|
|
phy_write(dev, 0x1f, 0x7ea8);
|
|
phy_write(dev, 0x1e, 0x2f);
|
|
phy_write(dev, 0x1f, 0x71b7);
|
|
|
|
return 0;
|
|
}
|
|
|
|
#define PHY_ID_AR8031 0x004dd074
|
|
#define PHY_ID_BCM54220 0x600d8589
|
|
|
|
static void __init imx7d_enet_phy_init(void)
|
|
{
|
|
if (IS_BUILTIN(CONFIG_PHYLIB)) {
|
|
phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff,
|
|
ar8031_phy_fixup);
|
|
phy_register_fixup_for_uid(PHY_ID_BCM54220, 0xffffffff,
|
|
bcm54220_phy_fixup);
|
|
}
|
|
}
|
|
|
|
static void __init imx7d_enet_clk_sel(void)
|
|
{
|
|
struct regmap *gpr;
|
|
|
|
gpr = syscon_regmap_lookup_by_compatible("fsl,imx7d-iomuxc-gpr");
|
|
if (!IS_ERR(gpr)) {
|
|
regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_ENET_TX_CLK_SEL_MASK, 0);
|
|
regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_ENET_CLK_DIR_MASK, 0);
|
|
} else {
|
|
pr_err("failed to find fsl,imx7d-iomux-gpr regmap\n");
|
|
}
|
|
}
|
|
|
|
static inline void imx7d_enet_init(void)
|
|
{
|
|
imx7d_enet_phy_init();
|
|
imx7d_enet_clk_sel();
|
|
}
|
|
|
|
static void __init imx7d_init_machine(void)
|
|
{
|
|
struct device *parent;
|
|
|
|
parent = imx_soc_device_init();
|
|
if (parent == NULL)
|
|
pr_warn("failed to initialize soc device\n");
|
|
|
|
imx_anatop_init();
|
|
imx7d_enet_init();
|
|
}
|
|
|
|
static void __init imx7d_init_late(void)
|
|
{
|
|
if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT))
|
|
platform_device_register_simple("imx-cpufreq-dt", -1, NULL, 0);
|
|
}
|
|
|
|
static void __init imx7d_init_irq(void)
|
|
{
|
|
imx_init_revision_from_anatop();
|
|
imx_src_init();
|
|
irqchip_init();
|
|
}
|
|
|
|
static const char *const imx7d_dt_compat[] __initconst = {
|
|
"fsl,imx7d",
|
|
"fsl,imx7s",
|
|
NULL,
|
|
};
|
|
|
|
DT_MACHINE_START(IMX7D, "Freescale i.MX7 Dual (Device Tree)")
|
|
.init_irq = imx7d_init_irq,
|
|
.init_machine = imx7d_init_machine,
|
|
.init_late = imx7d_init_late,
|
|
.dt_compat = imx7d_dt_compat,
|
|
MACHINE_END
|