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