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 = ðqos->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 = ðqos->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 = ðqos->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 = ðqos->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(ðqos->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, ðqos->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