18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2015 Freescale Semiconductor, Inc.
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci#include <linux/irqchip.h>
68c2ecf20Sopenharmony_ci#include <linux/mfd/syscon.h>
78c2ecf20Sopenharmony_ci#include <linux/mfd/syscon/imx7-iomuxc-gpr.h>
88c2ecf20Sopenharmony_ci#include <linux/of_platform.h>
98c2ecf20Sopenharmony_ci#include <linux/phy.h>
108c2ecf20Sopenharmony_ci#include <linux/regmap.h>
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include <asm/mach/arch.h>
138c2ecf20Sopenharmony_ci#include <asm/mach/map.h>
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#include "common.h"
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_cistatic int ar8031_phy_fixup(struct phy_device *dev)
188c2ecf20Sopenharmony_ci{
198c2ecf20Sopenharmony_ci	u16 val;
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci	/* Set RGMII IO voltage to 1.8V */
228c2ecf20Sopenharmony_ci	phy_write(dev, 0x1d, 0x1f);
238c2ecf20Sopenharmony_ci	phy_write(dev, 0x1e, 0x8);
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci	/* disable phy AR8031 SmartEEE function. */
268c2ecf20Sopenharmony_ci	phy_write(dev, 0xd, 0x3);
278c2ecf20Sopenharmony_ci	phy_write(dev, 0xe, 0x805d);
288c2ecf20Sopenharmony_ci	phy_write(dev, 0xd, 0x4003);
298c2ecf20Sopenharmony_ci	val = phy_read(dev, 0xe);
308c2ecf20Sopenharmony_ci	val &= ~(0x1 << 8);
318c2ecf20Sopenharmony_ci	phy_write(dev, 0xe, val);
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci	return 0;
348c2ecf20Sopenharmony_ci}
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_cistatic int bcm54220_phy_fixup(struct phy_device *dev)
378c2ecf20Sopenharmony_ci{
388c2ecf20Sopenharmony_ci	/* enable RXC skew select RGMII copper mode */
398c2ecf20Sopenharmony_ci	phy_write(dev, 0x1e, 0x21);
408c2ecf20Sopenharmony_ci	phy_write(dev, 0x1f, 0x7ea8);
418c2ecf20Sopenharmony_ci	phy_write(dev, 0x1e, 0x2f);
428c2ecf20Sopenharmony_ci	phy_write(dev, 0x1f, 0x71b7);
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci	return 0;
458c2ecf20Sopenharmony_ci}
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci#define PHY_ID_AR8031	0x004dd074
488c2ecf20Sopenharmony_ci#define PHY_ID_BCM54220	0x600d8589
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_cistatic void __init imx7d_enet_phy_init(void)
518c2ecf20Sopenharmony_ci{
528c2ecf20Sopenharmony_ci	if (IS_BUILTIN(CONFIG_PHYLIB)) {
538c2ecf20Sopenharmony_ci		phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff,
548c2ecf20Sopenharmony_ci					   ar8031_phy_fixup);
558c2ecf20Sopenharmony_ci		phy_register_fixup_for_uid(PHY_ID_BCM54220, 0xffffffff,
568c2ecf20Sopenharmony_ci					   bcm54220_phy_fixup);
578c2ecf20Sopenharmony_ci	}
588c2ecf20Sopenharmony_ci}
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_cistatic void __init imx7d_enet_clk_sel(void)
618c2ecf20Sopenharmony_ci{
628c2ecf20Sopenharmony_ci	struct regmap *gpr;
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci	gpr = syscon_regmap_lookup_by_compatible("fsl,imx7d-iomuxc-gpr");
658c2ecf20Sopenharmony_ci	if (!IS_ERR(gpr)) {
668c2ecf20Sopenharmony_ci		regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_ENET_TX_CLK_SEL_MASK, 0);
678c2ecf20Sopenharmony_ci		regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_ENET_CLK_DIR_MASK, 0);
688c2ecf20Sopenharmony_ci	} else {
698c2ecf20Sopenharmony_ci		pr_err("failed to find fsl,imx7d-iomux-gpr regmap\n");
708c2ecf20Sopenharmony_ci	}
718c2ecf20Sopenharmony_ci}
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_cistatic inline void imx7d_enet_init(void)
748c2ecf20Sopenharmony_ci{
758c2ecf20Sopenharmony_ci	imx7d_enet_phy_init();
768c2ecf20Sopenharmony_ci	imx7d_enet_clk_sel();
778c2ecf20Sopenharmony_ci}
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_cistatic void __init imx7d_init_machine(void)
808c2ecf20Sopenharmony_ci{
818c2ecf20Sopenharmony_ci	imx_anatop_init();
828c2ecf20Sopenharmony_ci	imx7d_enet_init();
838c2ecf20Sopenharmony_ci}
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_cistatic void __init imx7d_init_late(void)
868c2ecf20Sopenharmony_ci{
878c2ecf20Sopenharmony_ci	if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT))
888c2ecf20Sopenharmony_ci		platform_device_register_simple("imx-cpufreq-dt", -1, NULL, 0);
898c2ecf20Sopenharmony_ci}
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_cistatic void __init imx7d_init_irq(void)
928c2ecf20Sopenharmony_ci{
938c2ecf20Sopenharmony_ci	imx_init_revision_from_anatop();
948c2ecf20Sopenharmony_ci	imx_src_init();
958c2ecf20Sopenharmony_ci	irqchip_init();
968c2ecf20Sopenharmony_ci}
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_cistatic const char *const imx7d_dt_compat[] __initconst = {
998c2ecf20Sopenharmony_ci	"fsl,imx7d",
1008c2ecf20Sopenharmony_ci	"fsl,imx7s",
1018c2ecf20Sopenharmony_ci	NULL,
1028c2ecf20Sopenharmony_ci};
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ciDT_MACHINE_START(IMX7D, "Freescale i.MX7 Dual (Device Tree)")
1058c2ecf20Sopenharmony_ci	.init_irq	= imx7d_init_irq,
1068c2ecf20Sopenharmony_ci	.init_machine	= imx7d_init_machine,
1078c2ecf20Sopenharmony_ci	.init_late      = imx7d_init_late,
1088c2ecf20Sopenharmony_ci	.dt_compat	= imx7d_dt_compat,
1098c2ecf20Sopenharmony_ciMACHINE_END
110