1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2018 MediaTek Inc. 4 */ 5 #include <linux/bitfield.h> 6 #include <linux/io.h> 7 #include <linux/mfd/syscon.h> 8 #include <linux/module.h> 9 #include <linux/of.h> 10 #include <linux/of_device.h> 11 #include <linux/of_net.h> 12 #include <linux/pm_runtime.h> 13 #include <linux/regmap.h> 14 #include <linux/stmmac.h> 15 16 #include "stmmac.h" 17 #include "stmmac_platform.h" 18 19 /* Peri Configuration register for mt2712 */ 20 #define PERI_ETH_PHY_INTF_SEL 0x418 21 #define PHY_INTF_MII 0 22 #define PHY_INTF_RGMII 1 23 #define PHY_INTF_RMII 4 24 #define RMII_CLK_SRC_RXC BIT(4) 25 #define RMII_CLK_SRC_INTERNAL BIT(5) 26 27 #define PERI_ETH_DLY 0x428 28 #define ETH_DLY_GTXC_INV BIT(6) 29 #define ETH_DLY_GTXC_ENABLE BIT(5) 30 #define ETH_DLY_GTXC_STAGES GENMASK(4, 0) 31 #define ETH_DLY_TXC_INV BIT(20) 32 #define ETH_DLY_TXC_ENABLE BIT(19) 33 #define ETH_DLY_TXC_STAGES GENMASK(18, 14) 34 #define ETH_DLY_RXC_INV BIT(13) 35 #define ETH_DLY_RXC_ENABLE BIT(12) 36 #define ETH_DLY_RXC_STAGES GENMASK(11, 7) 37 38 #define PERI_ETH_DLY_FINE 0x800 39 #define ETH_RMII_DLY_TX_INV BIT(2) 40 #define ETH_FINE_DLY_GTXC BIT(1) 41 #define ETH_FINE_DLY_RXC BIT(0) 42 43 struct mac_delay_struct { 44 u32 tx_delay; 45 u32 rx_delay; 46 bool tx_inv; 47 bool rx_inv; 48 }; 49 50 struct mediatek_dwmac_plat_data { 51 const struct mediatek_dwmac_variant *variant; 52 struct mac_delay_struct mac_delay; 53 struct clk_bulk_data *clks; 54 struct device_node *np; 55 struct regmap *peri_regmap; 56 struct device *dev; 57 phy_interface_t phy_mode; 58 int num_clks_to_config; 59 bool rmii_clk_from_mac; 60 bool rmii_rxc; 61 }; 62 63 struct mediatek_dwmac_variant { 64 int (*dwmac_set_phy_interface)(struct mediatek_dwmac_plat_data *plat); 65 int (*dwmac_set_delay)(struct mediatek_dwmac_plat_data *plat); 66 67 /* clock ids to be requested */ 68 const char * const *clk_list; 69 int num_clks; 70 71 u32 dma_bit_mask; 72 u32 rx_delay_max; 73 u32 tx_delay_max; 74 }; 75 76 /* list of clocks required for mac */ 77 static const char * const mt2712_dwmac_clk_l[] = { 78 "axi", "apb", "mac_main", "ptp_ref", "rmii_internal" 79 }; 80 81 static int mt2712_set_interface(struct mediatek_dwmac_plat_data *plat) 82 { 83 int rmii_clk_from_mac = plat->rmii_clk_from_mac ? RMII_CLK_SRC_INTERNAL : 0; 84 int rmii_rxc = plat->rmii_rxc ? RMII_CLK_SRC_RXC : 0; 85 u32 intf_val = 0; 86 87 /* The clock labeled as "rmii_internal" in mt2712_dwmac_clk_l is needed 88 * only in RMII(when MAC provides the reference clock), and useless for 89 * RGMII/MII/RMII(when PHY provides the reference clock). 90 * num_clks_to_config indicates the real number of clocks should be 91 * configured, equals to (plat->variant->num_clks - 1) in default for all the case, 92 * then +1 for rmii_clk_from_mac case. 93 */ 94 plat->num_clks_to_config = plat->variant->num_clks - 1; 95 96 /* select phy interface in top control domain */ 97 switch (plat->phy_mode) { 98 case PHY_INTERFACE_MODE_MII: 99 intf_val |= PHY_INTF_MII; 100 break; 101 case PHY_INTERFACE_MODE_RMII: 102 if (plat->rmii_clk_from_mac) 103 plat->num_clks_to_config++; 104 intf_val |= (PHY_INTF_RMII | rmii_rxc | rmii_clk_from_mac); 105 break; 106 case PHY_INTERFACE_MODE_RGMII: 107 case PHY_INTERFACE_MODE_RGMII_TXID: 108 case PHY_INTERFACE_MODE_RGMII_RXID: 109 case PHY_INTERFACE_MODE_RGMII_ID: 110 intf_val |= PHY_INTF_RGMII; 111 break; 112 default: 113 dev_err(plat->dev, "phy interface not supported\n"); 114 return -EINVAL; 115 } 116 117 regmap_write(plat->peri_regmap, PERI_ETH_PHY_INTF_SEL, intf_val); 118 119 return 0; 120 } 121 122 static void mt2712_delay_ps2stage(struct mediatek_dwmac_plat_data *plat) 123 { 124 struct mac_delay_struct *mac_delay = &plat->mac_delay; 125 126 switch (plat->phy_mode) { 127 case PHY_INTERFACE_MODE_MII: 128 case PHY_INTERFACE_MODE_RMII: 129 /* 550ps per stage for MII/RMII */ 130 mac_delay->tx_delay /= 550; 131 mac_delay->rx_delay /= 550; 132 break; 133 case PHY_INTERFACE_MODE_RGMII: 134 case PHY_INTERFACE_MODE_RGMII_TXID: 135 case PHY_INTERFACE_MODE_RGMII_RXID: 136 case PHY_INTERFACE_MODE_RGMII_ID: 137 /* 170ps per stage for RGMII */ 138 mac_delay->tx_delay /= 170; 139 mac_delay->rx_delay /= 170; 140 break; 141 default: 142 dev_err(plat->dev, "phy interface not supported\n"); 143 break; 144 } 145 } 146 147 static void mt2712_delay_stage2ps(struct mediatek_dwmac_plat_data *plat) 148 { 149 struct mac_delay_struct *mac_delay = &plat->mac_delay; 150 151 switch (plat->phy_mode) { 152 case PHY_INTERFACE_MODE_MII: 153 case PHY_INTERFACE_MODE_RMII: 154 /* 550ps per stage for MII/RMII */ 155 mac_delay->tx_delay *= 550; 156 mac_delay->rx_delay *= 550; 157 break; 158 case PHY_INTERFACE_MODE_RGMII: 159 case PHY_INTERFACE_MODE_RGMII_TXID: 160 case PHY_INTERFACE_MODE_RGMII_RXID: 161 case PHY_INTERFACE_MODE_RGMII_ID: 162 /* 170ps per stage for RGMII */ 163 mac_delay->tx_delay *= 170; 164 mac_delay->rx_delay *= 170; 165 break; 166 default: 167 dev_err(plat->dev, "phy interface not supported\n"); 168 break; 169 } 170 } 171 172 static int mt2712_set_delay(struct mediatek_dwmac_plat_data *plat) 173 { 174 struct mac_delay_struct *mac_delay = &plat->mac_delay; 175 u32 delay_val = 0, fine_val = 0; 176 177 mt2712_delay_ps2stage(plat); 178 179 switch (plat->phy_mode) { 180 case PHY_INTERFACE_MODE_MII: 181 delay_val |= FIELD_PREP(ETH_DLY_TXC_ENABLE, !!mac_delay->tx_delay); 182 delay_val |= FIELD_PREP(ETH_DLY_TXC_STAGES, mac_delay->tx_delay); 183 delay_val |= FIELD_PREP(ETH_DLY_TXC_INV, mac_delay->tx_inv); 184 185 delay_val |= FIELD_PREP(ETH_DLY_RXC_ENABLE, !!mac_delay->rx_delay); 186 delay_val |= FIELD_PREP(ETH_DLY_RXC_STAGES, mac_delay->rx_delay); 187 delay_val |= FIELD_PREP(ETH_DLY_RXC_INV, mac_delay->rx_inv); 188 break; 189 case PHY_INTERFACE_MODE_RMII: 190 if (plat->rmii_clk_from_mac) { 191 /* case 1: mac provides the rmii reference clock, 192 * and the clock output to TXC pin. 193 * The egress timing can be adjusted by GTXC delay macro circuit. 194 * The ingress timing can be adjusted by TXC delay macro circuit. 195 */ 196 delay_val |= FIELD_PREP(ETH_DLY_TXC_ENABLE, !!mac_delay->rx_delay); 197 delay_val |= FIELD_PREP(ETH_DLY_TXC_STAGES, mac_delay->rx_delay); 198 delay_val |= FIELD_PREP(ETH_DLY_TXC_INV, mac_delay->rx_inv); 199 200 delay_val |= FIELD_PREP(ETH_DLY_GTXC_ENABLE, !!mac_delay->tx_delay); 201 delay_val |= FIELD_PREP(ETH_DLY_GTXC_STAGES, mac_delay->tx_delay); 202 delay_val |= FIELD_PREP(ETH_DLY_GTXC_INV, mac_delay->tx_inv); 203 } else { 204 /* case 2: the rmii reference clock is from external phy, 205 * and the property "rmii_rxc" indicates which pin(TXC/RXC) 206 * the reference clk is connected to. The reference clock is a 207 * received signal, so rx_delay/rx_inv are used to indicate 208 * the reference clock timing adjustment 209 */ 210 if (plat->rmii_rxc) { 211 /* the rmii reference clock from outside is connected 212 * to RXC pin, the reference clock will be adjusted 213 * by RXC delay macro circuit. 214 */ 215 delay_val |= FIELD_PREP(ETH_DLY_RXC_ENABLE, !!mac_delay->rx_delay); 216 delay_val |= FIELD_PREP(ETH_DLY_RXC_STAGES, mac_delay->rx_delay); 217 delay_val |= FIELD_PREP(ETH_DLY_RXC_INV, mac_delay->rx_inv); 218 } else { 219 /* the rmii reference clock from outside is connected 220 * to TXC pin, the reference clock will be adjusted 221 * by TXC delay macro circuit. 222 */ 223 delay_val |= FIELD_PREP(ETH_DLY_TXC_ENABLE, !!mac_delay->rx_delay); 224 delay_val |= FIELD_PREP(ETH_DLY_TXC_STAGES, mac_delay->rx_delay); 225 delay_val |= FIELD_PREP(ETH_DLY_TXC_INV, mac_delay->rx_inv); 226 } 227 /* tx_inv will inverse the tx clock inside mac relateive to 228 * reference clock from external phy, 229 * and this bit is located in the same register with fine-tune 230 */ 231 if (mac_delay->tx_inv) 232 fine_val = ETH_RMII_DLY_TX_INV; 233 } 234 break; 235 case PHY_INTERFACE_MODE_RGMII: 236 case PHY_INTERFACE_MODE_RGMII_TXID: 237 case PHY_INTERFACE_MODE_RGMII_RXID: 238 case PHY_INTERFACE_MODE_RGMII_ID: 239 fine_val = ETH_FINE_DLY_GTXC | ETH_FINE_DLY_RXC; 240 241 delay_val |= FIELD_PREP(ETH_DLY_GTXC_ENABLE, !!mac_delay->tx_delay); 242 delay_val |= FIELD_PREP(ETH_DLY_GTXC_STAGES, mac_delay->tx_delay); 243 delay_val |= FIELD_PREP(ETH_DLY_GTXC_INV, mac_delay->tx_inv); 244 245 delay_val |= FIELD_PREP(ETH_DLY_RXC_ENABLE, !!mac_delay->rx_delay); 246 delay_val |= FIELD_PREP(ETH_DLY_RXC_STAGES, mac_delay->rx_delay); 247 delay_val |= FIELD_PREP(ETH_DLY_RXC_INV, mac_delay->rx_inv); 248 break; 249 default: 250 dev_err(plat->dev, "phy interface not supported\n"); 251 return -EINVAL; 252 } 253 regmap_write(plat->peri_regmap, PERI_ETH_DLY, delay_val); 254 regmap_write(plat->peri_regmap, PERI_ETH_DLY_FINE, fine_val); 255 256 mt2712_delay_stage2ps(plat); 257 258 return 0; 259 } 260 261 static const struct mediatek_dwmac_variant mt2712_gmac_variant = { 262 .dwmac_set_phy_interface = mt2712_set_interface, 263 .dwmac_set_delay = mt2712_set_delay, 264 .clk_list = mt2712_dwmac_clk_l, 265 .num_clks = ARRAY_SIZE(mt2712_dwmac_clk_l), 266 .dma_bit_mask = 33, 267 .rx_delay_max = 17600, 268 .tx_delay_max = 17600, 269 }; 270 271 static int mediatek_dwmac_config_dt(struct mediatek_dwmac_plat_data *plat) 272 { 273 struct mac_delay_struct *mac_delay = &plat->mac_delay; 274 u32 tx_delay_ps, rx_delay_ps; 275 int err; 276 277 plat->peri_regmap = syscon_regmap_lookup_by_phandle(plat->np, "mediatek,pericfg"); 278 if (IS_ERR(plat->peri_regmap)) { 279 dev_err(plat->dev, "Failed to get pericfg syscon\n"); 280 return PTR_ERR(plat->peri_regmap); 281 } 282 283 err = of_get_phy_mode(plat->np, &plat->phy_mode); 284 if (err) { 285 dev_err(plat->dev, "not find phy-mode\n"); 286 return err; 287 } 288 289 if (!of_property_read_u32(plat->np, "mediatek,tx-delay-ps", &tx_delay_ps)) { 290 if (tx_delay_ps < plat->variant->tx_delay_max) { 291 mac_delay->tx_delay = tx_delay_ps; 292 } else { 293 dev_err(plat->dev, "Invalid TX clock delay: %dps\n", tx_delay_ps); 294 return -EINVAL; 295 } 296 } 297 298 if (!of_property_read_u32(plat->np, "mediatek,rx-delay-ps", &rx_delay_ps)) { 299 if (rx_delay_ps < plat->variant->rx_delay_max) { 300 mac_delay->rx_delay = rx_delay_ps; 301 } else { 302 dev_err(plat->dev, "Invalid RX clock delay: %dps\n", rx_delay_ps); 303 return -EINVAL; 304 } 305 } 306 307 mac_delay->tx_inv = of_property_read_bool(plat->np, "mediatek,txc-inverse"); 308 mac_delay->rx_inv = of_property_read_bool(plat->np, "mediatek,rxc-inverse"); 309 plat->rmii_rxc = of_property_read_bool(plat->np, "mediatek,rmii-rxc"); 310 plat->rmii_clk_from_mac = of_property_read_bool(plat->np, "mediatek,rmii-clk-from-mac"); 311 312 return 0; 313 } 314 315 static int mediatek_dwmac_clk_init(struct mediatek_dwmac_plat_data *plat) 316 { 317 const struct mediatek_dwmac_variant *variant = plat->variant; 318 int i, num = variant->num_clks; 319 320 plat->clks = devm_kcalloc(plat->dev, num, sizeof(*plat->clks), GFP_KERNEL); 321 if (!plat->clks) 322 return -ENOMEM; 323 324 for (i = 0; i < num; i++) 325 plat->clks[i].id = variant->clk_list[i]; 326 327 plat->num_clks_to_config = variant->num_clks; 328 329 return devm_clk_bulk_get(plat->dev, num, plat->clks); 330 } 331 332 static int mediatek_dwmac_init(struct platform_device *pdev, void *priv) 333 { 334 struct mediatek_dwmac_plat_data *plat = priv; 335 const struct mediatek_dwmac_variant *variant = plat->variant; 336 int ret; 337 338 ret = dma_set_mask_and_coherent(plat->dev, DMA_BIT_MASK(variant->dma_bit_mask)); 339 if (ret) { 340 dev_err(plat->dev, "No suitable DMA available, err = %d\n", ret); 341 return ret; 342 } 343 344 ret = variant->dwmac_set_phy_interface(plat); 345 if (ret) { 346 dev_err(plat->dev, "failed to set phy interface, err = %d\n", ret); 347 return ret; 348 } 349 350 ret = variant->dwmac_set_delay(plat); 351 if (ret) { 352 dev_err(plat->dev, "failed to set delay value, err = %d\n", ret); 353 return ret; 354 } 355 356 ret = clk_bulk_prepare_enable(plat->num_clks_to_config, plat->clks); 357 if (ret) { 358 dev_err(plat->dev, "failed to enable clks, err = %d\n", ret); 359 return ret; 360 } 361 362 pm_runtime_enable(&pdev->dev); 363 pm_runtime_get_sync(&pdev->dev); 364 365 return 0; 366 } 367 368 static void mediatek_dwmac_exit(struct platform_device *pdev, void *priv) 369 { 370 struct mediatek_dwmac_plat_data *plat = priv; 371 372 clk_bulk_disable_unprepare(plat->num_clks_to_config, plat->clks); 373 374 pm_runtime_put_sync(&pdev->dev); 375 pm_runtime_disable(&pdev->dev); 376 } 377 378 static int mediatek_dwmac_probe(struct platform_device *pdev) 379 { 380 struct mediatek_dwmac_plat_data *priv_plat; 381 struct plat_stmmacenet_data *plat_dat; 382 struct stmmac_resources stmmac_res; 383 int ret; 384 385 priv_plat = devm_kzalloc(&pdev->dev, sizeof(*priv_plat), GFP_KERNEL); 386 if (!priv_plat) 387 return -ENOMEM; 388 389 priv_plat->variant = of_device_get_match_data(&pdev->dev); 390 if (!priv_plat->variant) { 391 dev_err(&pdev->dev, "Missing dwmac-mediatek variant\n"); 392 return -EINVAL; 393 } 394 395 priv_plat->dev = &pdev->dev; 396 priv_plat->np = pdev->dev.of_node; 397 398 ret = mediatek_dwmac_config_dt(priv_plat); 399 if (ret) 400 return ret; 401 402 ret = mediatek_dwmac_clk_init(priv_plat); 403 if (ret) 404 return ret; 405 406 ret = stmmac_get_platform_resources(pdev, &stmmac_res); 407 if (ret) 408 return ret; 409 410 plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac); 411 if (IS_ERR(plat_dat)) 412 return PTR_ERR(plat_dat); 413 414 plat_dat->interface = priv_plat->phy_mode; 415 plat_dat->has_gmac4 = 1; 416 plat_dat->has_gmac = 0; 417 plat_dat->pmt = 0; 418 plat_dat->riwt_off = 1; 419 plat_dat->maxmtu = ETH_DATA_LEN; 420 plat_dat->bsp_priv = priv_plat; 421 plat_dat->init = mediatek_dwmac_init; 422 plat_dat->exit = mediatek_dwmac_exit; 423 mediatek_dwmac_init(pdev, priv_plat); 424 425 ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); 426 if (ret) { 427 stmmac_remove_config_dt(pdev, plat_dat); 428 return ret; 429 } 430 431 return 0; 432 } 433 434 static const struct of_device_id mediatek_dwmac_match[] = { 435 { .compatible = "mediatek,mt2712-gmac", 436 .data = &mt2712_gmac_variant }, 437 { } 438 }; 439 440 MODULE_DEVICE_TABLE(of, mediatek_dwmac_match); 441 442 static struct platform_driver mediatek_dwmac_driver = { 443 .probe = mediatek_dwmac_probe, 444 .remove = stmmac_pltfr_remove, 445 .driver = { 446 .name = "dwmac-mediatek", 447 .pm = &stmmac_pltfr_pm_ops, 448 .of_match_table = mediatek_dwmac_match, 449 }, 450 }; 451 module_platform_driver(mediatek_dwmac_driver); 452 453 MODULE_AUTHOR("Biao Huang <biao.huang@mediatek.com>"); 454 MODULE_DESCRIPTION("MediaTek DWMAC specific glue layer"); 455 MODULE_LICENSE("GPL v2"); 456