brintos

brintos / linux-shallow public Read only

0
0
Text · 27.8 KiB · 901a3c1 Raw
920 lines · c
1// SPDX-License-Identifier: GPL-2.02// Copyright (c) 2018-19, Linaro Limited3 4#include <linux/module.h>5#include <linux/of.h>6#include <linux/of_net.h>7#include <linux/platform_device.h>8#include <linux/phy.h>9#include <linux/phy/phy.h>10 11#include "stmmac.h"12#include "stmmac_platform.h"13 14#define RGMII_IO_MACRO_CONFIG		0x015#define SDCC_HC_REG_DLL_CONFIG		0x416#define SDCC_TEST_CTL			0x817#define SDCC_HC_REG_DDR_CONFIG		0xC18#define SDCC_HC_REG_DLL_CONFIG2		0x1019#define SDC4_STATUS			0x1420#define SDCC_USR_CTL			0x1821#define RGMII_IO_MACRO_CONFIG2		0x1C22#define RGMII_IO_MACRO_DEBUG1		0x2023#define EMAC_SYSTEM_LOW_POWER_DEBUG	0x2824#define EMAC_WRAPPER_SGMII_PHY_CNTRL1	0xf425 26/* RGMII_IO_MACRO_CONFIG fields */27#define RGMII_CONFIG_FUNC_CLK_EN		BIT(30)28#define RGMII_CONFIG_POS_NEG_DATA_SEL		BIT(23)29#define RGMII_CONFIG_GPIO_CFG_RX_INT		GENMASK(21, 20)30#define RGMII_CONFIG_GPIO_CFG_TX_INT		GENMASK(19, 17)31#define RGMII_CONFIG_MAX_SPD_PRG_9		GENMASK(16, 8)32#define RGMII_CONFIG_MAX_SPD_PRG_2		GENMASK(7, 6)33#define RGMII_CONFIG_INTF_SEL			GENMASK(5, 4)34#define RGMII_CONFIG_BYPASS_TX_ID_EN		BIT(3)35#define RGMII_CONFIG_LOOPBACK_EN		BIT(2)36#define RGMII_CONFIG_PROG_SWAP			BIT(1)37#define RGMII_CONFIG_DDR_MODE			BIT(0)38#define RGMII_CONFIG_SGMII_CLK_DVDR		GENMASK(18, 10)39 40/* SDCC_HC_REG_DLL_CONFIG fields */41#define SDCC_DLL_CONFIG_DLL_RST			BIT(30)42#define SDCC_DLL_CONFIG_PDN			BIT(29)43#define SDCC_DLL_CONFIG_MCLK_FREQ		GENMASK(26, 24)44#define SDCC_DLL_CONFIG_CDR_SELEXT		GENMASK(23, 20)45#define SDCC_DLL_CONFIG_CDR_EXT_EN		BIT(19)46#define SDCC_DLL_CONFIG_CK_OUT_EN		BIT(18)47#define SDCC_DLL_CONFIG_CDR_EN			BIT(17)48#define SDCC_DLL_CONFIG_DLL_EN			BIT(16)49#define SDCC_DLL_MCLK_GATING_EN			BIT(5)50#define SDCC_DLL_CDR_FINE_PHASE			GENMASK(3, 2)51 52/* SDCC_HC_REG_DDR_CONFIG fields */53#define SDCC_DDR_CONFIG_PRG_DLY_EN		BIT(31)54#define SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY	GENMASK(26, 21)55#define SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_CODE	GENMASK(29, 27)56#define SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_EN	BIT(30)57#define SDCC_DDR_CONFIG_TCXO_CYCLES_CNT		GENMASK(11, 9)58#define SDCC_DDR_CONFIG_PRG_RCLK_DLY		GENMASK(8, 0)59 60/* SDCC_HC_REG_DLL_CONFIG2 fields */61#define SDCC_DLL_CONFIG2_DLL_CLOCK_DIS		BIT(21)62#define SDCC_DLL_CONFIG2_MCLK_FREQ_CALC		GENMASK(17, 10)63#define SDCC_DLL_CONFIG2_DDR_TRAFFIC_INIT_SEL	GENMASK(3, 2)64#define SDCC_DLL_CONFIG2_DDR_TRAFFIC_INIT_SW	BIT(1)65#define SDCC_DLL_CONFIG2_DDR_CAL_EN		BIT(0)66 67/* SDC4_STATUS bits */68#define SDC4_STATUS_DLL_LOCK			BIT(7)69 70/* RGMII_IO_MACRO_CONFIG2 fields */71#define RGMII_CONFIG2_RSVD_CONFIG15		GENMASK(31, 17)72#define RGMII_CONFIG2_RGMII_CLK_SEL_CFG		BIT(16)73#define RGMII_CONFIG2_TX_TO_RX_LOOPBACK_EN	BIT(13)74#define RGMII_CONFIG2_CLK_DIVIDE_SEL		BIT(12)75#define RGMII_CONFIG2_RX_PROG_SWAP		BIT(7)76#define RGMII_CONFIG2_DATA_DIVIDE_CLK_SEL	BIT(6)77#define RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN	BIT(5)78 79/* MAC_CTRL_REG bits */80#define ETHQOS_MAC_CTRL_SPEED_MODE		BIT(14)81#define ETHQOS_MAC_CTRL_PORT_SEL		BIT(15)82 83/* EMAC_WRAPPER_SGMII_PHY_CNTRL1 bits */84#define SGMII_PHY_CNTRL1_SGMII_TX_TO_RX_LOOPBACK_EN	BIT(3)85 86#define SGMII_10M_RX_CLK_DVDR			0x3187 88struct ethqos_emac_por {89	unsigned int offset;90	unsigned int value;91};92 93struct ethqos_emac_driver_data {94	const struct ethqos_emac_por *por;95	unsigned int num_por;96	bool rgmii_config_loopback_en;97	bool has_emac_ge_3;98	const char *link_clk_name;99	bool has_integrated_pcs;100	u32 dma_addr_width;101	struct dwmac4_addrs dwmac4_addrs;102	bool needs_sgmii_loopback;103};104 105struct qcom_ethqos {106	struct platform_device *pdev;107	void __iomem *rgmii_base;108	void __iomem *mac_base;109	int (*configure_func)(struct qcom_ethqos *ethqos);110 111	unsigned int link_clk_rate;112	struct clk *link_clk;113	struct phy *serdes_phy;114	unsigned int speed;115	int serdes_speed;116	phy_interface_t phy_mode;117 118	const struct ethqos_emac_por *por;119	unsigned int num_por;120	bool rgmii_config_loopback_en;121	bool has_emac_ge_3;122	bool needs_sgmii_loopback;123};124 125static int rgmii_readl(struct qcom_ethqos *ethqos, unsigned int offset)126{127	return readl(ethqos->rgmii_base + offset);128}129 130static void rgmii_writel(struct qcom_ethqos *ethqos,131			 int value, unsigned int offset)132{133	writel(value, ethqos->rgmii_base + offset);134}135 136static void rgmii_updatel(struct qcom_ethqos *ethqos,137			  int mask, int val, unsigned int offset)138{139	unsigned int temp;140 141	temp = rgmii_readl(ethqos, offset);142	temp = (temp & ~(mask)) | val;143	rgmii_writel(ethqos, temp, offset);144}145 146static void rgmii_dump(void *priv)147{148	struct qcom_ethqos *ethqos = priv;149	struct device *dev = &ethqos->pdev->dev;150 151	dev_dbg(dev, "Rgmii register dump\n");152	dev_dbg(dev, "RGMII_IO_MACRO_CONFIG: %x\n",153		rgmii_readl(ethqos, RGMII_IO_MACRO_CONFIG));154	dev_dbg(dev, "SDCC_HC_REG_DLL_CONFIG: %x\n",155		rgmii_readl(ethqos, SDCC_HC_REG_DLL_CONFIG));156	dev_dbg(dev, "SDCC_HC_REG_DDR_CONFIG: %x\n",157		rgmii_readl(ethqos, SDCC_HC_REG_DDR_CONFIG));158	dev_dbg(dev, "SDCC_HC_REG_DLL_CONFIG2: %x\n",159		rgmii_readl(ethqos, SDCC_HC_REG_DLL_CONFIG2));160	dev_dbg(dev, "SDC4_STATUS: %x\n",161		rgmii_readl(ethqos, SDC4_STATUS));162	dev_dbg(dev, "SDCC_USR_CTL: %x\n",163		rgmii_readl(ethqos, SDCC_USR_CTL));164	dev_dbg(dev, "RGMII_IO_MACRO_CONFIG2: %x\n",165		rgmii_readl(ethqos, RGMII_IO_MACRO_CONFIG2));166	dev_dbg(dev, "RGMII_IO_MACRO_DEBUG1: %x\n",167		rgmii_readl(ethqos, RGMII_IO_MACRO_DEBUG1));168	dev_dbg(dev, "EMAC_SYSTEM_LOW_POWER_DEBUG: %x\n",169		rgmii_readl(ethqos, EMAC_SYSTEM_LOW_POWER_DEBUG));170}171 172/* Clock rates */173#define RGMII_1000_NOM_CLK_FREQ			(250 * 1000 * 1000UL)174#define RGMII_ID_MODE_100_LOW_SVS_CLK_FREQ	 (50 * 1000 * 1000UL)175#define RGMII_ID_MODE_10_LOW_SVS_CLK_FREQ	  (5 * 1000 * 1000UL)176 177static void178ethqos_update_link_clk(struct qcom_ethqos *ethqos, unsigned int speed)179{180	if (!phy_interface_mode_is_rgmii(ethqos->phy_mode))181		return;182 183	switch (speed) {184	case SPEED_1000:185		ethqos->link_clk_rate =  RGMII_1000_NOM_CLK_FREQ;186		break;187 188	case SPEED_100:189		ethqos->link_clk_rate =  RGMII_ID_MODE_100_LOW_SVS_CLK_FREQ;190		break;191 192	case SPEED_10:193		ethqos->link_clk_rate =  RGMII_ID_MODE_10_LOW_SVS_CLK_FREQ;194		break;195	}196 197	clk_set_rate(ethqos->link_clk, ethqos->link_clk_rate);198}199 200static void201qcom_ethqos_set_sgmii_loopback(struct qcom_ethqos *ethqos, bool enable)202{203	if (!ethqos->needs_sgmii_loopback ||204	    ethqos->phy_mode != PHY_INTERFACE_MODE_2500BASEX)205		return;206 207	rgmii_updatel(ethqos,208		      SGMII_PHY_CNTRL1_SGMII_TX_TO_RX_LOOPBACK_EN,209		      enable ? SGMII_PHY_CNTRL1_SGMII_TX_TO_RX_LOOPBACK_EN : 0,210		      EMAC_WRAPPER_SGMII_PHY_CNTRL1);211}212 213static void ethqos_set_func_clk_en(struct qcom_ethqos *ethqos)214{215	qcom_ethqos_set_sgmii_loopback(ethqos, true);216	rgmii_updatel(ethqos, RGMII_CONFIG_FUNC_CLK_EN,217		      RGMII_CONFIG_FUNC_CLK_EN, RGMII_IO_MACRO_CONFIG);218}219 220static const struct ethqos_emac_por emac_v2_3_0_por[] = {221	{ .offset = RGMII_IO_MACRO_CONFIG,	.value = 0x00C01343 },222	{ .offset = SDCC_HC_REG_DLL_CONFIG,	.value = 0x2004642C },223	{ .offset = SDCC_HC_REG_DDR_CONFIG,	.value = 0x00000000 },224	{ .offset = SDCC_HC_REG_DLL_CONFIG2,	.value = 0x00200000 },225	{ .offset = SDCC_USR_CTL,		.value = 0x00010800 },226	{ .offset = RGMII_IO_MACRO_CONFIG2,	.value = 0x00002060 },227};228 229static const struct ethqos_emac_driver_data emac_v2_3_0_data = {230	.por = emac_v2_3_0_por,231	.num_por = ARRAY_SIZE(emac_v2_3_0_por),232	.rgmii_config_loopback_en = true,233	.has_emac_ge_3 = false,234};235 236static const struct ethqos_emac_por emac_v2_1_0_por[] = {237	{ .offset = RGMII_IO_MACRO_CONFIG,	.value = 0x40C01343 },238	{ .offset = SDCC_HC_REG_DLL_CONFIG,	.value = 0x2004642C },239	{ .offset = SDCC_HC_REG_DDR_CONFIG,	.value = 0x00000000 },240	{ .offset = SDCC_HC_REG_DLL_CONFIG2,	.value = 0x00200000 },241	{ .offset = SDCC_USR_CTL,		.value = 0x00010800 },242	{ .offset = RGMII_IO_MACRO_CONFIG2,	.value = 0x00002060 },243};244 245static const struct ethqos_emac_driver_data emac_v2_1_0_data = {246	.por = emac_v2_1_0_por,247	.num_por = ARRAY_SIZE(emac_v2_1_0_por),248	.rgmii_config_loopback_en = false,249	.has_emac_ge_3 = false,250};251 252static const struct ethqos_emac_por emac_v3_0_0_por[] = {253	{ .offset = RGMII_IO_MACRO_CONFIG,	.value = 0x40c01343 },254	{ .offset = SDCC_HC_REG_DLL_CONFIG,	.value = 0x2004642c },255	{ .offset = SDCC_HC_REG_DDR_CONFIG,	.value = 0x80040800 },256	{ .offset = SDCC_HC_REG_DLL_CONFIG2,	.value = 0x00200000 },257	{ .offset = SDCC_USR_CTL,		.value = 0x00010800 },258	{ .offset = RGMII_IO_MACRO_CONFIG2,	.value = 0x00002060 },259};260 261static const struct ethqos_emac_driver_data emac_v3_0_0_data = {262	.por = emac_v3_0_0_por,263	.num_por = ARRAY_SIZE(emac_v3_0_0_por),264	.rgmii_config_loopback_en = false,265	.has_emac_ge_3 = true,266	.dwmac4_addrs = {267		.dma_chan = 0x00008100,268		.dma_chan_offset = 0x1000,269		.mtl_chan = 0x00008000,270		.mtl_chan_offset = 0x1000,271		.mtl_ets_ctrl = 0x00008010,272		.mtl_ets_ctrl_offset = 0x1000,273		.mtl_txq_weight = 0x00008018,274		.mtl_txq_weight_offset = 0x1000,275		.mtl_send_slp_cred = 0x0000801c,276		.mtl_send_slp_cred_offset = 0x1000,277		.mtl_high_cred = 0x00008020,278		.mtl_high_cred_offset = 0x1000,279		.mtl_low_cred = 0x00008024,280		.mtl_low_cred_offset = 0x1000,281	},282};283 284static const struct ethqos_emac_por emac_v4_0_0_por[] = {285	{ .offset = RGMII_IO_MACRO_CONFIG,	.value = 0x40c01343 },286	{ .offset = SDCC_HC_REG_DLL_CONFIG,	.value = 0x2004642c },287	{ .offset = SDCC_HC_REG_DDR_CONFIG,	.value = 0x80040800 },288	{ .offset = SDCC_HC_REG_DLL_CONFIG2,	.value = 0x00200000 },289	{ .offset = SDCC_USR_CTL,		.value = 0x00010800 },290	{ .offset = RGMII_IO_MACRO_CONFIG2,	.value = 0x00002060 },291};292 293static const struct ethqos_emac_driver_data emac_v4_0_0_data = {294	.por = emac_v4_0_0_por,295	.num_por = ARRAY_SIZE(emac_v4_0_0_por),296	.rgmii_config_loopback_en = false,297	.has_emac_ge_3 = true,298	.link_clk_name = "phyaux",299	.has_integrated_pcs = true,300	.needs_sgmii_loopback = true,301	.dma_addr_width = 36,302	.dwmac4_addrs = {303		.dma_chan = 0x00008100,304		.dma_chan_offset = 0x1000,305		.mtl_chan = 0x00008000,306		.mtl_chan_offset = 0x1000,307		.mtl_ets_ctrl = 0x00008010,308		.mtl_ets_ctrl_offset = 0x1000,309		.mtl_txq_weight = 0x00008018,310		.mtl_txq_weight_offset = 0x1000,311		.mtl_send_slp_cred = 0x0000801c,312		.mtl_send_slp_cred_offset = 0x1000,313		.mtl_high_cred = 0x00008020,314		.mtl_high_cred_offset = 0x1000,315		.mtl_low_cred = 0x00008024,316		.mtl_low_cred_offset = 0x1000,317	},318};319 320static int ethqos_dll_configure(struct qcom_ethqos *ethqos)321{322	struct device *dev = &ethqos->pdev->dev;323	unsigned int val;324	int retry = 1000;325 326	/* Set CDR_EN */327	rgmii_updatel(ethqos, SDCC_DLL_CONFIG_CDR_EN,328		      SDCC_DLL_CONFIG_CDR_EN, SDCC_HC_REG_DLL_CONFIG);329 330	/* Set CDR_EXT_EN */331	rgmii_updatel(ethqos, SDCC_DLL_CONFIG_CDR_EXT_EN,332		      SDCC_DLL_CONFIG_CDR_EXT_EN, SDCC_HC_REG_DLL_CONFIG);333 334	/* Clear CK_OUT_EN */335	rgmii_updatel(ethqos, SDCC_DLL_CONFIG_CK_OUT_EN,336		      0, SDCC_HC_REG_DLL_CONFIG);337 338	/* Set DLL_EN */339	rgmii_updatel(ethqos, SDCC_DLL_CONFIG_DLL_EN,340		      SDCC_DLL_CONFIG_DLL_EN, SDCC_HC_REG_DLL_CONFIG);341 342	if (!ethqos->has_emac_ge_3) {343		rgmii_updatel(ethqos, SDCC_DLL_MCLK_GATING_EN,344			      0, SDCC_HC_REG_DLL_CONFIG);345 346		rgmii_updatel(ethqos, SDCC_DLL_CDR_FINE_PHASE,347			      0, SDCC_HC_REG_DLL_CONFIG);348	}349 350	/* Wait for CK_OUT_EN clear */351	do {352		val = rgmii_readl(ethqos, SDCC_HC_REG_DLL_CONFIG);353		val &= SDCC_DLL_CONFIG_CK_OUT_EN;354		if (!val)355			break;356		mdelay(1);357		retry--;358	} while (retry > 0);359	if (!retry)360		dev_err(dev, "Clear CK_OUT_EN timedout\n");361 362	/* Set CK_OUT_EN */363	rgmii_updatel(ethqos, SDCC_DLL_CONFIG_CK_OUT_EN,364		      SDCC_DLL_CONFIG_CK_OUT_EN, SDCC_HC_REG_DLL_CONFIG);365 366	/* Wait for CK_OUT_EN set */367	retry = 1000;368	do {369		val = rgmii_readl(ethqos, SDCC_HC_REG_DLL_CONFIG);370		val &= SDCC_DLL_CONFIG_CK_OUT_EN;371		if (val)372			break;373		mdelay(1);374		retry--;375	} while (retry > 0);376	if (!retry)377		dev_err(dev, "Set CK_OUT_EN timedout\n");378 379	/* Set DDR_CAL_EN */380	rgmii_updatel(ethqos, SDCC_DLL_CONFIG2_DDR_CAL_EN,381		      SDCC_DLL_CONFIG2_DDR_CAL_EN, SDCC_HC_REG_DLL_CONFIG2);382 383	if (!ethqos->has_emac_ge_3) {384		rgmii_updatel(ethqos, SDCC_DLL_CONFIG2_DLL_CLOCK_DIS,385			      0, SDCC_HC_REG_DLL_CONFIG2);386 387		rgmii_updatel(ethqos, SDCC_DLL_CONFIG2_MCLK_FREQ_CALC,388			      0x1A << 10, SDCC_HC_REG_DLL_CONFIG2);389 390		rgmii_updatel(ethqos, SDCC_DLL_CONFIG2_DDR_TRAFFIC_INIT_SEL,391			      BIT(2), SDCC_HC_REG_DLL_CONFIG2);392 393		rgmii_updatel(ethqos, SDCC_DLL_CONFIG2_DDR_TRAFFIC_INIT_SW,394			      SDCC_DLL_CONFIG2_DDR_TRAFFIC_INIT_SW,395			      SDCC_HC_REG_DLL_CONFIG2);396	}397 398	return 0;399}400 401static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos)402{403	struct device *dev = &ethqos->pdev->dev;404	int phase_shift;405	int loopback;406 407	/* Determine if the PHY adds a 2 ns TX delay or the MAC handles it */408	if (ethqos->phy_mode == PHY_INTERFACE_MODE_RGMII_ID ||409	    ethqos->phy_mode == PHY_INTERFACE_MODE_RGMII_TXID)410		phase_shift = 0;411	else412		phase_shift = RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN;413 414	/* Disable loopback mode */415	rgmii_updatel(ethqos, RGMII_CONFIG2_TX_TO_RX_LOOPBACK_EN,416		      0, RGMII_IO_MACRO_CONFIG2);417 418	/* Determine if this platform wants loopback enabled after programming */419	if (ethqos->rgmii_config_loopback_en)420		loopback = RGMII_CONFIG_LOOPBACK_EN;421	else422		loopback = 0;423 424	/* Select RGMII, write 0 to interface select */425	rgmii_updatel(ethqos, RGMII_CONFIG_INTF_SEL,426		      0, RGMII_IO_MACRO_CONFIG);427 428	switch (ethqos->speed) {429	case SPEED_1000:430		rgmii_updatel(ethqos, RGMII_CONFIG_DDR_MODE,431			      RGMII_CONFIG_DDR_MODE, RGMII_IO_MACRO_CONFIG);432		rgmii_updatel(ethqos, RGMII_CONFIG_BYPASS_TX_ID_EN,433			      0, RGMII_IO_MACRO_CONFIG);434		rgmii_updatel(ethqos, RGMII_CONFIG_POS_NEG_DATA_SEL,435			      RGMII_CONFIG_POS_NEG_DATA_SEL,436			      RGMII_IO_MACRO_CONFIG);437		rgmii_updatel(ethqos, RGMII_CONFIG_PROG_SWAP,438			      RGMII_CONFIG_PROG_SWAP, RGMII_IO_MACRO_CONFIG);439		rgmii_updatel(ethqos, RGMII_CONFIG2_DATA_DIVIDE_CLK_SEL,440			      0, RGMII_IO_MACRO_CONFIG2);441 442		rgmii_updatel(ethqos, RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN,443			      phase_shift, RGMII_IO_MACRO_CONFIG2);444		rgmii_updatel(ethqos, RGMII_CONFIG2_RSVD_CONFIG15,445			      0, RGMII_IO_MACRO_CONFIG2);446		rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,447			      RGMII_CONFIG2_RX_PROG_SWAP,448			      RGMII_IO_MACRO_CONFIG2);449 450		/* PRG_RCLK_DLY = TCXO period * TCXO_CYCLES_CNT / 2 * RX delay ns,451		 * in practice this becomes PRG_RCLK_DLY = 52 * 4 / 2 * RX delay ns452		 */453		if (ethqos->has_emac_ge_3) {454			/* 0.9 ns */455			rgmii_updatel(ethqos, SDCC_DDR_CONFIG_PRG_RCLK_DLY,456				      115, SDCC_HC_REG_DDR_CONFIG);457		} else {458			/* 1.8 ns */459			rgmii_updatel(ethqos, SDCC_DDR_CONFIG_PRG_RCLK_DLY,460				      57, SDCC_HC_REG_DDR_CONFIG);461		}462		rgmii_updatel(ethqos, SDCC_DDR_CONFIG_PRG_DLY_EN,463			      SDCC_DDR_CONFIG_PRG_DLY_EN,464			      SDCC_HC_REG_DDR_CONFIG);465		rgmii_updatel(ethqos, RGMII_CONFIG_LOOPBACK_EN,466			      loopback, RGMII_IO_MACRO_CONFIG);467		break;468 469	case SPEED_100:470		rgmii_updatel(ethqos, RGMII_CONFIG_DDR_MODE,471			      RGMII_CONFIG_DDR_MODE, RGMII_IO_MACRO_CONFIG);472		rgmii_updatel(ethqos, RGMII_CONFIG_BYPASS_TX_ID_EN,473			      RGMII_CONFIG_BYPASS_TX_ID_EN,474			      RGMII_IO_MACRO_CONFIG);475		rgmii_updatel(ethqos, RGMII_CONFIG_POS_NEG_DATA_SEL,476			      0, RGMII_IO_MACRO_CONFIG);477		rgmii_updatel(ethqos, RGMII_CONFIG_PROG_SWAP,478			      0, RGMII_IO_MACRO_CONFIG);479		rgmii_updatel(ethqos, RGMII_CONFIG2_DATA_DIVIDE_CLK_SEL,480			      0, RGMII_IO_MACRO_CONFIG2);481		rgmii_updatel(ethqos, RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN,482			      phase_shift, RGMII_IO_MACRO_CONFIG2);483		rgmii_updatel(ethqos, RGMII_CONFIG_MAX_SPD_PRG_2,484			      BIT(6), RGMII_IO_MACRO_CONFIG);485		rgmii_updatel(ethqos, RGMII_CONFIG2_RSVD_CONFIG15,486			      0, RGMII_IO_MACRO_CONFIG2);487 488		if (ethqos->has_emac_ge_3)489			rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,490				      RGMII_CONFIG2_RX_PROG_SWAP,491				      RGMII_IO_MACRO_CONFIG2);492		else493			rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,494				      0, RGMII_IO_MACRO_CONFIG2);495 496		/* Write 0x5 to PRG_RCLK_DLY_CODE */497		rgmii_updatel(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_CODE,498			      (BIT(29) | BIT(27)), SDCC_HC_REG_DDR_CONFIG);499		rgmii_updatel(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY,500			      SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY,501			      SDCC_HC_REG_DDR_CONFIG);502		rgmii_updatel(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_EN,503			      SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_EN,504			      SDCC_HC_REG_DDR_CONFIG);505		rgmii_updatel(ethqos, RGMII_CONFIG_LOOPBACK_EN,506			      loopback, RGMII_IO_MACRO_CONFIG);507		break;508 509	case SPEED_10:510		rgmii_updatel(ethqos, RGMII_CONFIG_DDR_MODE,511			      RGMII_CONFIG_DDR_MODE, RGMII_IO_MACRO_CONFIG);512		rgmii_updatel(ethqos, RGMII_CONFIG_BYPASS_TX_ID_EN,513			      RGMII_CONFIG_BYPASS_TX_ID_EN,514			      RGMII_IO_MACRO_CONFIG);515		rgmii_updatel(ethqos, RGMII_CONFIG_POS_NEG_DATA_SEL,516			      0, RGMII_IO_MACRO_CONFIG);517		rgmii_updatel(ethqos, RGMII_CONFIG_PROG_SWAP,518			      0, RGMII_IO_MACRO_CONFIG);519		rgmii_updatel(ethqos, RGMII_CONFIG2_DATA_DIVIDE_CLK_SEL,520			      0, RGMII_IO_MACRO_CONFIG2);521		rgmii_updatel(ethqos, RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN,522			      phase_shift, RGMII_IO_MACRO_CONFIG2);523		rgmii_updatel(ethqos, RGMII_CONFIG_MAX_SPD_PRG_9,524			      BIT(12) | GENMASK(9, 8),525			      RGMII_IO_MACRO_CONFIG);526		rgmii_updatel(ethqos, RGMII_CONFIG2_RSVD_CONFIG15,527			      0, RGMII_IO_MACRO_CONFIG2);528		if (ethqos->has_emac_ge_3)529			rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,530				      RGMII_CONFIG2_RX_PROG_SWAP,531				      RGMII_IO_MACRO_CONFIG2);532		else533			rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,534				      0, RGMII_IO_MACRO_CONFIG2);535		/* Write 0x5 to PRG_RCLK_DLY_CODE */536		rgmii_updatel(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_CODE,537			      (BIT(29) | BIT(27)), SDCC_HC_REG_DDR_CONFIG);538		rgmii_updatel(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY,539			      SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY,540			      SDCC_HC_REG_DDR_CONFIG);541		rgmii_updatel(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_EN,542			      SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_EN,543			      SDCC_HC_REG_DDR_CONFIG);544		rgmii_updatel(ethqos, RGMII_CONFIG_LOOPBACK_EN,545			      loopback, RGMII_IO_MACRO_CONFIG);546		break;547	default:548		dev_err(dev, "Invalid speed %d\n", ethqos->speed);549		return -EINVAL;550	}551 552	return 0;553}554 555static int ethqos_configure_rgmii(struct qcom_ethqos *ethqos)556{557	struct device *dev = &ethqos->pdev->dev;558	volatile unsigned int dll_lock;559	unsigned int i, retry = 1000;560 561	/* Reset to POR values and enable clk */562	for (i = 0; i < ethqos->num_por; i++)563		rgmii_writel(ethqos, ethqos->por[i].value,564			     ethqos->por[i].offset);565	ethqos_set_func_clk_en(ethqos);566 567	/* Initialize the DLL first */568 569	/* Set DLL_RST */570	rgmii_updatel(ethqos, SDCC_DLL_CONFIG_DLL_RST,571		      SDCC_DLL_CONFIG_DLL_RST, SDCC_HC_REG_DLL_CONFIG);572 573	/* Set PDN */574	rgmii_updatel(ethqos, SDCC_DLL_CONFIG_PDN,575		      SDCC_DLL_CONFIG_PDN, SDCC_HC_REG_DLL_CONFIG);576 577	if (ethqos->has_emac_ge_3) {578		if (ethqos->speed == SPEED_1000) {579			rgmii_writel(ethqos, 0x1800000, SDCC_TEST_CTL);580			rgmii_writel(ethqos, 0x2C010800, SDCC_USR_CTL);581			rgmii_writel(ethqos, 0xA001, SDCC_HC_REG_DLL_CONFIG2);582		} else {583			rgmii_writel(ethqos, 0x40010800, SDCC_USR_CTL);584			rgmii_writel(ethqos, 0xA001, SDCC_HC_REG_DLL_CONFIG2);585		}586	}587 588	/* Clear DLL_RST */589	rgmii_updatel(ethqos, SDCC_DLL_CONFIG_DLL_RST, 0,590		      SDCC_HC_REG_DLL_CONFIG);591 592	/* Clear PDN */593	rgmii_updatel(ethqos, SDCC_DLL_CONFIG_PDN, 0,594		      SDCC_HC_REG_DLL_CONFIG);595 596	if (ethqos->speed != SPEED_100 && ethqos->speed != SPEED_10) {597		/* Set DLL_EN */598		rgmii_updatel(ethqos, SDCC_DLL_CONFIG_DLL_EN,599			      SDCC_DLL_CONFIG_DLL_EN, SDCC_HC_REG_DLL_CONFIG);600 601		/* Set CK_OUT_EN */602		rgmii_updatel(ethqos, SDCC_DLL_CONFIG_CK_OUT_EN,603			      SDCC_DLL_CONFIG_CK_OUT_EN,604			      SDCC_HC_REG_DLL_CONFIG);605 606		/* Set USR_CTL bit 26 with mask of 3 bits */607		if (!ethqos->has_emac_ge_3)608			rgmii_updatel(ethqos, GENMASK(26, 24), BIT(26),609				      SDCC_USR_CTL);610 611		/* wait for DLL LOCK */612		do {613			mdelay(1);614			dll_lock = rgmii_readl(ethqos, SDC4_STATUS);615			if (dll_lock & SDC4_STATUS_DLL_LOCK)616				break;617			retry--;618		} while (retry > 0);619		if (!retry)620			dev_err(dev, "Timeout while waiting for DLL lock\n");621	}622 623	if (ethqos->speed == SPEED_1000)624		ethqos_dll_configure(ethqos);625 626	ethqos_rgmii_macro_init(ethqos);627 628	return 0;629}630 631static void ethqos_set_serdes_speed(struct qcom_ethqos *ethqos, int speed)632{633	if (ethqos->serdes_speed != speed) {634		phy_set_speed(ethqos->serdes_phy, speed);635		ethqos->serdes_speed = speed;636	}637}638 639/* On interface toggle MAC registers gets reset.640 * Configure MAC block for SGMII on ethernet phy link up641 */642static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos)643{644	struct net_device *dev = platform_get_drvdata(ethqos->pdev);645	struct stmmac_priv *priv = netdev_priv(dev);646	int val;647 648	val = readl(ethqos->mac_base + MAC_CTRL_REG);649 650	switch (ethqos->speed) {651	case SPEED_2500:652		val &= ~ETHQOS_MAC_CTRL_PORT_SEL;653		rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG,654			      RGMII_CONFIG2_RGMII_CLK_SEL_CFG,655			      RGMII_IO_MACRO_CONFIG2);656		ethqos_set_serdes_speed(ethqos, SPEED_2500);657		stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 0, 0, 0);658		break;659	case SPEED_1000:660		val &= ~ETHQOS_MAC_CTRL_PORT_SEL;661		rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG,662			      RGMII_CONFIG2_RGMII_CLK_SEL_CFG,663			      RGMII_IO_MACRO_CONFIG2);664		ethqos_set_serdes_speed(ethqos, SPEED_1000);665		stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, 0, 0);666		break;667	case SPEED_100:668		val |= ETHQOS_MAC_CTRL_PORT_SEL | ETHQOS_MAC_CTRL_SPEED_MODE;669		ethqos_set_serdes_speed(ethqos, SPEED_1000);670		stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, 0, 0);671		break;672	case SPEED_10:673		val |= ETHQOS_MAC_CTRL_PORT_SEL;674		val &= ~ETHQOS_MAC_CTRL_SPEED_MODE;675		rgmii_updatel(ethqos, RGMII_CONFIG_SGMII_CLK_DVDR,676			      FIELD_PREP(RGMII_CONFIG_SGMII_CLK_DVDR,677					 SGMII_10M_RX_CLK_DVDR),678			      RGMII_IO_MACRO_CONFIG);679		ethqos_set_serdes_speed(ethqos, SPEED_1000);680		stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, 0, 0);681		break;682	}683 684	writel(val, ethqos->mac_base + MAC_CTRL_REG);685 686	return val;687}688 689static void qcom_ethqos_speed_mode_2500(struct net_device *ndev, void *data)690{691	struct stmmac_priv *priv = netdev_priv(ndev);692 693	priv->plat->max_speed = 2500;694	priv->plat->phy_interface = PHY_INTERFACE_MODE_2500BASEX;695}696 697static int ethqos_configure(struct qcom_ethqos *ethqos)698{699	return ethqos->configure_func(ethqos);700}701 702static void ethqos_fix_mac_speed(void *priv, unsigned int speed, unsigned int mode)703{704	struct qcom_ethqos *ethqos = priv;705 706	qcom_ethqos_set_sgmii_loopback(ethqos, false);707	ethqos->speed = speed;708	ethqos_update_link_clk(ethqos, speed);709	ethqos_configure(ethqos);710}711 712static int qcom_ethqos_serdes_powerup(struct net_device *ndev, void *priv)713{714	struct qcom_ethqos *ethqos = priv;715	int ret;716 717	ret = phy_init(ethqos->serdes_phy);718	if (ret)719		return ret;720 721	ret = phy_power_on(ethqos->serdes_phy);722	if (ret)723		return ret;724 725	return phy_set_speed(ethqos->serdes_phy, ethqos->speed);726}727 728static void qcom_ethqos_serdes_powerdown(struct net_device *ndev, void *priv)729{730	struct qcom_ethqos *ethqos = priv;731 732	phy_power_off(ethqos->serdes_phy);733	phy_exit(ethqos->serdes_phy);734}735 736static int ethqos_clks_config(void *priv, bool enabled)737{738	struct qcom_ethqos *ethqos = priv;739	int ret = 0;740 741	if (enabled) {742		ret = clk_prepare_enable(ethqos->link_clk);743		if (ret) {744			dev_err(&ethqos->pdev->dev, "link_clk enable failed\n");745			return ret;746		}747 748		/* Enable functional clock to prevent DMA reset to timeout due749		 * to lacking PHY clock after the hardware block has been power750		 * cycled. The actual configuration will be adjusted once751		 * ethqos_fix_mac_speed() is invoked.752		 */753		ethqos_set_func_clk_en(ethqos);754	} else {755		clk_disable_unprepare(ethqos->link_clk);756	}757 758	return ret;759}760 761static void ethqos_clks_disable(void *data)762{763	ethqos_clks_config(data, false);764}765 766static void ethqos_ptp_clk_freq_config(struct stmmac_priv *priv)767{768	struct plat_stmmacenet_data *plat_dat = priv->plat;769	int err;770 771	if (!plat_dat->clk_ptp_ref)772		return;773 774	/* Max the PTP ref clock out to get the best resolution possible */775	err = clk_set_rate(plat_dat->clk_ptp_ref, ULONG_MAX);776	if (err)777		netdev_err(priv->dev, "Failed to max out clk_ptp_ref: %d\n", err);778	plat_dat->clk_ptp_rate = clk_get_rate(plat_dat->clk_ptp_ref);779 780	netdev_dbg(priv->dev, "PTP rate %d\n", plat_dat->clk_ptp_rate);781}782 783static int qcom_ethqos_probe(struct platform_device *pdev)784{785	struct device_node *np = pdev->dev.of_node;786	const struct ethqos_emac_driver_data *data;787	struct plat_stmmacenet_data *plat_dat;788	struct stmmac_resources stmmac_res;789	struct device *dev = &pdev->dev;790	struct qcom_ethqos *ethqos;791	int ret, i;792 793	ret = stmmac_get_platform_resources(pdev, &stmmac_res);794	if (ret)795		return dev_err_probe(dev, ret,796				     "Failed to get platform resources\n");797 798	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);799	if (IS_ERR(plat_dat)) {800		return dev_err_probe(dev, PTR_ERR(plat_dat),801				     "dt configuration failed\n");802	}803 804	plat_dat->clks_config = ethqos_clks_config;805 806	ethqos = devm_kzalloc(dev, sizeof(*ethqos), GFP_KERNEL);807	if (!ethqos)808		return -ENOMEM;809 810	ret = of_get_phy_mode(np, &ethqos->phy_mode);811	if (ret)812		return dev_err_probe(dev, ret, "Failed to get phy mode\n");813	switch (ethqos->phy_mode) {814	case PHY_INTERFACE_MODE_RGMII:815	case PHY_INTERFACE_MODE_RGMII_ID:816	case PHY_INTERFACE_MODE_RGMII_RXID:817	case PHY_INTERFACE_MODE_RGMII_TXID:818		ethqos->configure_func = ethqos_configure_rgmii;819		break;820	case PHY_INTERFACE_MODE_2500BASEX:821		plat_dat->speed_mode_2500 = qcom_ethqos_speed_mode_2500;822		fallthrough;823	case PHY_INTERFACE_MODE_SGMII:824		ethqos->configure_func = ethqos_configure_sgmii;825		break;826	default:827		dev_err(dev, "Unsupported phy mode %s\n",828			phy_modes(ethqos->phy_mode));829		return -EINVAL;830	}831 832	ethqos->pdev = pdev;833	ethqos->rgmii_base = devm_platform_ioremap_resource_byname(pdev, "rgmii");834	if (IS_ERR(ethqos->rgmii_base))835		return dev_err_probe(dev, PTR_ERR(ethqos->rgmii_base),836				     "Failed to map rgmii resource\n");837 838	ethqos->mac_base = stmmac_res.addr;839 840	data = of_device_get_match_data(dev);841	ethqos->por = data->por;842	ethqos->num_por = data->num_por;843	ethqos->rgmii_config_loopback_en = data->rgmii_config_loopback_en;844	ethqos->has_emac_ge_3 = data->has_emac_ge_3;845	ethqos->needs_sgmii_loopback = data->needs_sgmii_loopback;846 847	ethqos->link_clk = devm_clk_get(dev, data->link_clk_name ?: "rgmii");848	if (IS_ERR(ethqos->link_clk))849		return dev_err_probe(dev, PTR_ERR(ethqos->link_clk),850				     "Failed to get link_clk\n");851 852	ret = ethqos_clks_config(ethqos, true);853	if (ret)854		return ret;855 856	ret = devm_add_action_or_reset(dev, ethqos_clks_disable, ethqos);857	if (ret)858		return ret;859 860	ethqos->serdes_phy = devm_phy_optional_get(dev, "serdes");861	if (IS_ERR(ethqos->serdes_phy))862		return dev_err_probe(dev, PTR_ERR(ethqos->serdes_phy),863				     "Failed to get serdes phy\n");864 865	ethqos->speed = SPEED_1000;866	ethqos->serdes_speed = SPEED_1000;867	ethqos_update_link_clk(ethqos, SPEED_1000);868	ethqos_set_func_clk_en(ethqos);869 870	plat_dat->bsp_priv = ethqos;871	plat_dat->fix_mac_speed = ethqos_fix_mac_speed;872	plat_dat->dump_debug_regs = rgmii_dump;873	plat_dat->ptp_clk_freq_config = ethqos_ptp_clk_freq_config;874	plat_dat->has_gmac4 = 1;875	if (ethqos->has_emac_ge_3)876		plat_dat->dwmac4_addrs = &data->dwmac4_addrs;877	plat_dat->pmt = 1;878	if (of_property_read_bool(np, "snps,tso"))879		plat_dat->flags |= STMMAC_FLAG_TSO_EN;880	if (of_device_is_compatible(np, "qcom,qcs404-ethqos"))881		plat_dat->flags |= STMMAC_FLAG_RX_CLK_RUNS_IN_LPI;882	if (data->has_integrated_pcs)883		plat_dat->flags |= STMMAC_FLAG_HAS_INTEGRATED_PCS;884	if (data->dma_addr_width)885		plat_dat->host_dma_width = data->dma_addr_width;886 887	if (ethqos->serdes_phy) {888		plat_dat->serdes_powerup = qcom_ethqos_serdes_powerup;889		plat_dat->serdes_powerdown  = qcom_ethqos_serdes_powerdown;890	}891 892	/* Enable TSO on queue0 and enable TBS on rest of the queues */893	for (i = 1; i < plat_dat->tx_queues_to_use; i++)894		plat_dat->tx_queues_cfg[i].tbs_en = 1;895 896	return devm_stmmac_pltfr_probe(pdev, plat_dat, &stmmac_res);897}898 899static const struct of_device_id qcom_ethqos_match[] = {900	{ .compatible = "qcom,qcs404-ethqos", .data = &emac_v2_3_0_data},901	{ .compatible = "qcom,sa8775p-ethqos", .data = &emac_v4_0_0_data},902	{ .compatible = "qcom,sc8280xp-ethqos", .data = &emac_v3_0_0_data},903	{ .compatible = "qcom,sm8150-ethqos", .data = &emac_v2_1_0_data},904	{ }905};906MODULE_DEVICE_TABLE(of, qcom_ethqos_match);907 908static struct platform_driver qcom_ethqos_driver = {909	.probe  = qcom_ethqos_probe,910	.driver = {911		.name           = "qcom-ethqos",912		.pm		= &stmmac_pltfr_pm_ops,913		.of_match_table = qcom_ethqos_match,914	},915};916module_platform_driver(qcom_ethqos_driver);917 918MODULE_DESCRIPTION("Qualcomm ETHQOS driver");919MODULE_LICENSE("GPL v2");920