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