1 // SPDX-License-Identifier: GPL-2.0 2 /* Renesas Ethernet SERDES device driver 3 * 4 * Copyright (C) 2022 Renesas Electronics Corporation 5 */ 6 7 #include <linux/delay.h> 8 #include <linux/err.h> 9 #include <linux/iopoll.h> 10 #include <linux/kernel.h> 11 #include <linux/phy.h> 12 #include <linux/phy/phy.h> 13 #include <linux/platform_device.h> 14 #include <linux/reset.h> 15 16 #define R8A779F0_ETH_SERDES_NUM 3 17 #define R8A779F0_ETH_SERDES_OFFSET 0x0400 18 #define R8A779F0_ETH_SERDES_BANK_SELECT 0x03fc 19 #define R8A779F0_ETH_SERDES_TIMEOUT_US 100000 20 #define R8A779F0_ETH_SERDES_NUM_RETRY_LINKUP 3 21 #define R8A779F0_ETH_SERDES_NUM_RETRY_INIT 3 22 23 struct r8a779f0_eth_serdes_drv_data; 24 struct r8a779f0_eth_serdes_channel { 25 struct r8a779f0_eth_serdes_drv_data *dd; 26 struct phy *phy; 27 void __iomem *addr; 28 phy_interface_t phy_interface; 29 int speed; 30 int index; 31 }; 32 33 struct r8a779f0_eth_serdes_drv_data { 34 void __iomem *addr; 35 struct platform_device *pdev; 36 struct reset_control *reset; 37 struct r8a779f0_eth_serdes_channel channel[R8A779F0_ETH_SERDES_NUM]; 38 bool initialized; 39 }; 40 41 /* 42 * The datasheet describes initialization procedure without any information 43 * about registers' name/bits. So, this is all black magic to initialize 44 * the hardware. 45 */ 46 static void r8a779f0_eth_serdes_write32(void __iomem *addr, u32 offs, u32 bank, u32 data) 47 { 48 iowrite32(bank, addr + R8A779F0_ETH_SERDES_BANK_SELECT); 49 iowrite32(data, addr + offs); 50 } 51 52 static int 53 r8a779f0_eth_serdes_reg_wait(struct r8a779f0_eth_serdes_channel *channel, 54 u32 offs, u32 bank, u32 mask, u32 expected) 55 { 56 int ret; 57 u32 val; 58 59 iowrite32(bank, channel->addr + R8A779F0_ETH_SERDES_BANK_SELECT); 60 61 ret = readl_poll_timeout_atomic(channel->addr + offs, val, 62 (val & mask) == expected, 63 1, R8A779F0_ETH_SERDES_TIMEOUT_US); 64 if (ret) 65 dev_dbg(&channel->phy->dev, 66 "%s: index %d, offs %x, bank %x, mask %x, expected %x\n", 67 __func__, channel->index, offs, bank, mask, expected); 68 69 return ret; 70 } 71 72 static int 73 r8a779f0_eth_serdes_common_init_ram(struct r8a779f0_eth_serdes_drv_data *dd) 74 { 75 struct r8a779f0_eth_serdes_channel *channel; 76 int i, ret; 77 78 for (i = 0; i < R8A779F0_ETH_SERDES_NUM; i++) { 79 channel = &dd->channel[i]; 80 ret = r8a779f0_eth_serdes_reg_wait(channel, 0x026c, 0x180, BIT(0), 0x01); 81 if (ret) 82 return ret; 83 } 84 85 r8a779f0_eth_serdes_write32(dd->addr, 0x026c, 0x180, 0x03); 86 87 return ret; 88 } 89 90 static int 91 r8a779f0_eth_serdes_common_setting(struct r8a779f0_eth_serdes_channel *channel) 92 { 93 struct r8a779f0_eth_serdes_drv_data *dd = channel->dd; 94 95 switch (channel->phy_interface) { 96 case PHY_INTERFACE_MODE_SGMII: 97 r8a779f0_eth_serdes_write32(dd->addr, 0x0244, 0x180, 0x0097); 98 r8a779f0_eth_serdes_write32(dd->addr, 0x01d0, 0x180, 0x0060); 99 r8a779f0_eth_serdes_write32(dd->addr, 0x01d8, 0x180, 0x2200); 100 r8a779f0_eth_serdes_write32(dd->addr, 0x01d4, 0x180, 0x0000); 101 r8a779f0_eth_serdes_write32(dd->addr, 0x01e0, 0x180, 0x003d); 102 return 0; 103 default: 104 return -EOPNOTSUPP; 105 } 106 } 107 108 static int 109 r8a779f0_eth_serdes_chan_setting(struct r8a779f0_eth_serdes_channel *channel) 110 { 111 int ret; 112 113 switch (channel->phy_interface) { 114 case PHY_INTERFACE_MODE_SGMII: 115 r8a779f0_eth_serdes_write32(channel->addr, 0x0000, 0x380, 0x2000); 116 r8a779f0_eth_serdes_write32(channel->addr, 0x01c0, 0x180, 0x0011); 117 r8a779f0_eth_serdes_write32(channel->addr, 0x0248, 0x180, 0x0540); 118 r8a779f0_eth_serdes_write32(channel->addr, 0x0258, 0x180, 0x0015); 119 r8a779f0_eth_serdes_write32(channel->addr, 0x0144, 0x180, 0x0100); 120 r8a779f0_eth_serdes_write32(channel->addr, 0x01a0, 0x180, 0x0000); 121 r8a779f0_eth_serdes_write32(channel->addr, 0x00d0, 0x180, 0x0002); 122 r8a779f0_eth_serdes_write32(channel->addr, 0x0150, 0x180, 0x0003); 123 r8a779f0_eth_serdes_write32(channel->addr, 0x00c8, 0x180, 0x0100); 124 r8a779f0_eth_serdes_write32(channel->addr, 0x0148, 0x180, 0x0100); 125 r8a779f0_eth_serdes_write32(channel->addr, 0x0174, 0x180, 0x0000); 126 r8a779f0_eth_serdes_write32(channel->addr, 0x0160, 0x180, 0x0007); 127 r8a779f0_eth_serdes_write32(channel->addr, 0x01ac, 0x180, 0x0000); 128 r8a779f0_eth_serdes_write32(channel->addr, 0x00c4, 0x180, 0x0310); 129 r8a779f0_eth_serdes_write32(channel->addr, 0x00c8, 0x180, 0x0101); 130 ret = r8a779f0_eth_serdes_reg_wait(channel, 0x00c8, 0x0180, BIT(0), 0); 131 if (ret) 132 return ret; 133 134 r8a779f0_eth_serdes_write32(channel->addr, 0x0148, 0x180, 0x0101); 135 ret = r8a779f0_eth_serdes_reg_wait(channel, 0x0148, 0x0180, BIT(0), 0); 136 if (ret) 137 return ret; 138 139 r8a779f0_eth_serdes_write32(channel->addr, 0x00c4, 0x180, 0x1310); 140 r8a779f0_eth_serdes_write32(channel->addr, 0x00d8, 0x180, 0x1800); 141 r8a779f0_eth_serdes_write32(channel->addr, 0x00dc, 0x180, 0x0000); 142 r8a779f0_eth_serdes_write32(channel->addr, 0x001c, 0x300, 0x0001); 143 r8a779f0_eth_serdes_write32(channel->addr, 0x0000, 0x380, 0x2100); 144 ret = r8a779f0_eth_serdes_reg_wait(channel, 0x0000, 0x0380, BIT(8), 0); 145 if (ret) 146 return ret; 147 148 if (channel->speed == 1000) 149 r8a779f0_eth_serdes_write32(channel->addr, 0x0000, 0x1f00, 0x0140); 150 else if (channel->speed == 100) 151 r8a779f0_eth_serdes_write32(channel->addr, 0x0000, 0x1f00, 0x2100); 152 153 /* For AN_ON */ 154 r8a779f0_eth_serdes_write32(channel->addr, 0x0004, 0x1f80, 0x0005); 155 r8a779f0_eth_serdes_write32(channel->addr, 0x0028, 0x1f80, 0x07a1); 156 r8a779f0_eth_serdes_write32(channel->addr, 0x0000, 0x1f80, 0x0208); 157 break; 158 default: 159 return -EOPNOTSUPP; 160 } 161 162 return 0; 163 } 164 165 static int 166 r8a779f0_eth_serdes_chan_speed(struct r8a779f0_eth_serdes_channel *channel) 167 { 168 int ret; 169 170 switch (channel->phy_interface) { 171 case PHY_INTERFACE_MODE_SGMII: 172 /* For AN_ON */ 173 if (channel->speed == 1000) 174 r8a779f0_eth_serdes_write32(channel->addr, 0x0000, 0x1f00, 0x1140); 175 else if (channel->speed == 100) 176 r8a779f0_eth_serdes_write32(channel->addr, 0x0000, 0x1f00, 0x3100); 177 ret = r8a779f0_eth_serdes_reg_wait(channel, 0x0008, 0x1f80, BIT(0), 1); 178 if (ret) 179 return ret; 180 r8a779f0_eth_serdes_write32(channel->addr, 0x0008, 0x1f80, 0x0000); 181 break; 182 default: 183 return -EOPNOTSUPP; 184 } 185 186 return 0; 187 } 188 189 190 static int r8a779f0_eth_serdes_monitor_linkup(struct r8a779f0_eth_serdes_channel *channel) 191 { 192 int i, ret; 193 194 for (i = 0; i < R8A779F0_ETH_SERDES_NUM_RETRY_LINKUP; i++) { 195 ret = r8a779f0_eth_serdes_reg_wait(channel, 0x0004, 0x300, 196 BIT(2), BIT(2)); 197 if (!ret) 198 break; 199 200 /* restart */ 201 r8a779f0_eth_serdes_write32(channel->addr, 0x0144, 0x180, 0x0100); 202 udelay(1); 203 r8a779f0_eth_serdes_write32(channel->addr, 0x0144, 0x180, 0x0000); 204 } 205 206 return ret; 207 } 208 209 static int r8a779f0_eth_serdes_hw_init(struct r8a779f0_eth_serdes_channel *channel) 210 { 211 struct r8a779f0_eth_serdes_drv_data *dd = channel->dd; 212 int i, ret; 213 214 if (dd->initialized) 215 return 0; 216 217 ret = r8a779f0_eth_serdes_common_init_ram(dd); 218 if (ret) 219 return ret; 220 221 for (i = 0; i < R8A779F0_ETH_SERDES_NUM; i++) { 222 ret = r8a779f0_eth_serdes_reg_wait(&dd->channel[i], 0x0000, 223 0x300, BIT(15), 0); 224 if (ret) 225 return ret; 226 } 227 228 for (i = 0; i < R8A779F0_ETH_SERDES_NUM; i++) 229 r8a779f0_eth_serdes_write32(dd->channel[i].addr, 0x03d4, 0x380, 0x0443); 230 231 ret = r8a779f0_eth_serdes_common_setting(channel); 232 if (ret) 233 return ret; 234 235 for (i = 0; i < R8A779F0_ETH_SERDES_NUM; i++) 236 r8a779f0_eth_serdes_write32(dd->channel[i].addr, 0x03d0, 0x380, 0x0001); 237 238 239 r8a779f0_eth_serdes_write32(dd->addr, 0x0000, 0x380, 0x8000); 240 241 ret = r8a779f0_eth_serdes_common_init_ram(dd); 242 if (ret) 243 return ret; 244 245 ret = r8a779f0_eth_serdes_reg_wait(&dd->channel[0], 0x0000, 0x380, BIT(15), 0); 246 if (ret) 247 return ret; 248 249 for (i = 0; i < R8A779F0_ETH_SERDES_NUM; i++) { 250 ret = r8a779f0_eth_serdes_chan_setting(&dd->channel[i]); 251 if (ret) 252 return ret; 253 } 254 255 for (i = 0; i < R8A779F0_ETH_SERDES_NUM; i++) { 256 ret = r8a779f0_eth_serdes_chan_speed(&dd->channel[i]); 257 if (ret) 258 return ret; 259 } 260 261 for (i = 0; i < R8A779F0_ETH_SERDES_NUM; i++) 262 r8a779f0_eth_serdes_write32(dd->channel[i].addr, 0x03c0, 0x380, 0x0000); 263 for (i = 0; i < R8A779F0_ETH_SERDES_NUM; i++) 264 r8a779f0_eth_serdes_write32(dd->channel[i].addr, 0x03d0, 0x380, 0x0000); 265 266 for (i = 0; i < R8A779F0_ETH_SERDES_NUM; i++) { 267 ret = r8a779f0_eth_serdes_monitor_linkup(&dd->channel[i]); 268 if (ret) 269 return ret; 270 } 271 272 return 0; 273 } 274 275 static int r8a779f0_eth_serdes_init(struct phy *p) 276 { 277 struct r8a779f0_eth_serdes_channel *channel = phy_get_drvdata(p); 278 int i, ret; 279 280 for (i = 0; i < R8A779F0_ETH_SERDES_NUM_RETRY_INIT; i++) { 281 ret = r8a779f0_eth_serdes_hw_init(channel); 282 if (!ret) { 283 channel->dd->initialized = true; 284 break; 285 } 286 usleep_range(1000, 2000); 287 } 288 289 return ret; 290 } 291 292 static int r8a779f0_eth_serdes_set_mode(struct phy *p, enum phy_mode mode, 293 int submode) 294 { 295 struct r8a779f0_eth_serdes_channel *channel = phy_get_drvdata(p); 296 297 if (mode != PHY_MODE_ETHERNET) 298 return -EOPNOTSUPP; 299 300 switch (submode) { 301 case PHY_INTERFACE_MODE_GMII: 302 case PHY_INTERFACE_MODE_SGMII: 303 case PHY_INTERFACE_MODE_USXGMII: 304 channel->phy_interface = submode; 305 return 0; 306 default: 307 return -EOPNOTSUPP; 308 } 309 } 310 311 static int r8a779f0_eth_serdes_set_speed(struct phy *p, int speed) 312 { 313 struct r8a779f0_eth_serdes_channel *channel = phy_get_drvdata(p); 314 315 channel->speed = speed; 316 317 return 0; 318 } 319 320 static const struct phy_ops r8a779f0_eth_serdes_ops = { 321 .init = r8a779f0_eth_serdes_init, 322 .set_mode = r8a779f0_eth_serdes_set_mode, 323 .set_speed = r8a779f0_eth_serdes_set_speed, 324 }; 325 326 static struct phy *r8a779f0_eth_serdes_xlate(struct device *dev, 327 struct of_phandle_args *args) 328 { 329 struct r8a779f0_eth_serdes_drv_data *dd = dev_get_drvdata(dev); 330 331 if (args->args[0] >= R8A779F0_ETH_SERDES_NUM) 332 return ERR_PTR(-ENODEV); 333 334 return dd->channel[args->args[0]].phy; 335 } 336 337 static const struct of_device_id r8a779f0_eth_serdes_of_table[] = { 338 { .compatible = "renesas,r8a779f0-ether-serdes", }, 339 { } 340 }; 341 MODULE_DEVICE_TABLE(of, r8a779f0_eth_serdes_of_table); 342 343 static int r8a779f0_eth_serdes_probe(struct platform_device *pdev) 344 { 345 struct r8a779f0_eth_serdes_drv_data *dd; 346 struct phy_provider *provider; 347 struct resource *res; 348 int i; 349 350 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 351 if (!res) { 352 dev_err(&pdev->dev, "invalid resource\n"); 353 return -EINVAL; 354 } 355 356 dd = devm_kzalloc(&pdev->dev, sizeof(*dd), GFP_KERNEL); 357 if (!dd) 358 return -ENOMEM; 359 360 platform_set_drvdata(pdev, dd); 361 dd->pdev = pdev; 362 dd->addr = devm_ioremap_resource(&pdev->dev, res); 363 if (IS_ERR(dd->addr)) 364 return PTR_ERR(dd->addr); 365 366 dd->reset = devm_reset_control_get(&pdev->dev, NULL); 367 if (IS_ERR(dd->reset)) 368 return PTR_ERR(dd->reset); 369 370 reset_control_reset(dd->reset); 371 372 for (i = 0; i < R8A779F0_ETH_SERDES_NUM; i++) { 373 struct r8a779f0_eth_serdes_channel *channel = &dd->channel[i]; 374 375 channel->phy = devm_phy_create(&pdev->dev, NULL, 376 &r8a779f0_eth_serdes_ops); 377 if (IS_ERR(channel->phy)) 378 return PTR_ERR(channel->phy); 379 channel->addr = dd->addr + R8A779F0_ETH_SERDES_OFFSET * i; 380 channel->dd = dd; 381 channel->index = i; 382 phy_set_drvdata(channel->phy, channel); 383 } 384 385 provider = devm_of_phy_provider_register(&pdev->dev, 386 r8a779f0_eth_serdes_xlate); 387 if (IS_ERR(provider)) 388 return PTR_ERR(provider); 389 390 pm_runtime_enable(&pdev->dev); 391 pm_runtime_get_sync(&pdev->dev); 392 393 return 0; 394 } 395 396 static int r8a779f0_eth_serdes_remove(struct platform_device *pdev) 397 { 398 pm_runtime_put(&pdev->dev); 399 pm_runtime_disable(&pdev->dev); 400 401 platform_set_drvdata(pdev, NULL); 402 403 return 0; 404 } 405 406 static struct platform_driver r8a779f0_eth_serdes_driver_platform = { 407 .probe = r8a779f0_eth_serdes_probe, 408 .remove = r8a779f0_eth_serdes_remove, 409 .driver = { 410 .name = "r8a779f0_eth_serdes", 411 .of_match_table = r8a779f0_eth_serdes_of_table, 412 } 413 }; 414 module_platform_driver(r8a779f0_eth_serdes_driver_platform); 415 MODULE_AUTHOR("Yoshihiro Shimoda"); 416 MODULE_DESCRIPTION("Renesas Ethernet SERDES device driver"); 417 MODULE_LICENSE("GPL"); 418