1 /* 2 * Copyright (c) 2014-2015 Hisilicon Limited. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 */ 9 10 #include <linux/errno.h> 11 #include <linux/etherdevice.h> 12 #include <linux/init.h> 13 #include <linux/kernel.h> 14 #include <linux/module.h> 15 #include <linux/mutex.h> 16 #include <linux/netdevice.h> 17 #include <linux/of_address.h> 18 #include <linux/of.h> 19 #include <linux/of_mdio.h> 20 #include <linux/of_platform.h> 21 #include <linux/phy.h> 22 #include <linux/platform_device.h> 23 #include <linux/spinlock_types.h> 24 25 #define MDIO_DRV_NAME "Hi-HNS_MDIO" 26 #define MDIO_BUS_NAME "Hisilicon MII Bus" 27 #define MDIO_DRV_VERSION "1.3.0" 28 #define MDIO_COPYRIGHT "Copyright(c) 2015 Huawei Corporation." 29 #define MDIO_DRV_STRING MDIO_BUS_NAME 30 #define MDIO_DEFAULT_DEVICE_DESCR MDIO_BUS_NAME 31 32 #define MDIO_CTL_DEV_ADDR(x) (x & 0x1f) 33 #define MDIO_CTL_PORT_ADDR(x) ((x & 0x1f) << 5) 34 35 #define MDIO_TIMEOUT 1000000 36 37 struct hns_mdio_device { 38 void *vbase; /* mdio reg base address */ 39 void *sys_vbase; 40 }; 41 42 /* mdio reg */ 43 #define MDIO_COMMAND_REG 0x0 44 #define MDIO_ADDR_REG 0x4 45 #define MDIO_WDATA_REG 0x8 46 #define MDIO_RDATA_REG 0xc 47 #define MDIO_STA_REG 0x10 48 49 /* cfg phy bit map */ 50 #define MDIO_CMD_DEVAD_M 0x1f 51 #define MDIO_CMD_DEVAD_S 0 52 #define MDIO_CMD_PRTAD_M 0x1f 53 #define MDIO_CMD_PRTAD_S 5 54 #define MDIO_CMD_OP_M 0x3 55 #define MDIO_CMD_OP_S 10 56 #define MDIO_CMD_ST_M 0x3 57 #define MDIO_CMD_ST_S 12 58 #define MDIO_CMD_START_B 14 59 60 #define MDIO_ADDR_DATA_M 0xffff 61 #define MDIO_ADDR_DATA_S 0 62 63 #define MDIO_WDATA_DATA_M 0xffff 64 #define MDIO_WDATA_DATA_S 0 65 66 #define MDIO_RDATA_DATA_M 0xffff 67 #define MDIO_RDATA_DATA_S 0 68 69 #define MDIO_STATE_STA_B 0 70 71 enum mdio_st_clause { 72 MDIO_ST_CLAUSE_45 = 0, 73 MDIO_ST_CLAUSE_22 74 }; 75 76 enum mdio_c22_op_seq { 77 MDIO_C22_WRITE = 1, 78 MDIO_C22_READ = 2 79 }; 80 81 enum mdio_c45_op_seq { 82 MDIO_C45_WRITE_ADDR = 0, 83 MDIO_C45_WRITE_DATA, 84 MDIO_C45_READ_INCREMENT, 85 MDIO_C45_READ 86 }; 87 88 /* peri subctrl reg */ 89 #define MDIO_SC_CLK_EN 0x338 90 #define MDIO_SC_CLK_DIS 0x33C 91 #define MDIO_SC_RESET_REQ 0xA38 92 #define MDIO_SC_RESET_DREQ 0xA3C 93 #define MDIO_SC_CTRL 0x2010 94 #define MDIO_SC_CLK_ST 0x531C 95 #define MDIO_SC_RESET_ST 0x5A1C 96 97 static void mdio_write_reg(void *base, u32 reg, u32 value) 98 { 99 u8 __iomem *reg_addr = (u8 __iomem *)base; 100 101 writel_relaxed(value, reg_addr + reg); 102 } 103 104 #define MDIO_WRITE_REG(a, reg, value) \ 105 mdio_write_reg((a)->vbase, (reg), (value)) 106 107 static u32 mdio_read_reg(void *base, u32 reg) 108 { 109 u8 __iomem *reg_addr = (u8 __iomem *)base; 110 111 return readl_relaxed(reg_addr + reg); 112 } 113 114 #define mdio_set_field(origin, mask, shift, val) \ 115 do { \ 116 (origin) &= (~((mask) << (shift))); \ 117 (origin) |= (((val) & (mask)) << (shift)); \ 118 } while (0) 119 120 #define mdio_get_field(origin, mask, shift) (((origin) >> (shift)) & (mask)) 121 122 static void mdio_set_reg_field(void *base, u32 reg, u32 mask, u32 shift, 123 u32 val) 124 { 125 u32 origin = mdio_read_reg(base, reg); 126 127 mdio_set_field(origin, mask, shift, val); 128 mdio_write_reg(base, reg, origin); 129 } 130 131 #define MDIO_SET_REG_FIELD(dev, reg, mask, shift, val) \ 132 mdio_set_reg_field((dev)->vbase, (reg), (mask), (shift), (val)) 133 134 static u32 mdio_get_reg_field(void *base, u32 reg, u32 mask, u32 shift) 135 { 136 u32 origin; 137 138 origin = mdio_read_reg(base, reg); 139 return mdio_get_field(origin, mask, shift); 140 } 141 142 #define MDIO_GET_REG_FIELD(dev, reg, mask, shift) \ 143 mdio_get_reg_field((dev)->vbase, (reg), (mask), (shift)) 144 145 #define MDIO_GET_REG_BIT(dev, reg, bit) \ 146 mdio_get_reg_field((dev)->vbase, (reg), 0x1ull, (bit)) 147 148 #define MDIO_CHECK_SET_ST 1 149 #define MDIO_CHECK_CLR_ST 0 150 151 static int mdio_sc_cfg_reg_write(struct hns_mdio_device *mdio_dev, 152 u32 cfg_reg, u32 set_val, 153 u32 st_reg, u32 st_msk, u8 check_st) 154 { 155 u32 time_cnt; 156 u32 reg_value; 157 158 mdio_write_reg((void *)mdio_dev->sys_vbase, cfg_reg, set_val); 159 160 for (time_cnt = MDIO_TIMEOUT; time_cnt; time_cnt--) { 161 reg_value = mdio_read_reg((void *)mdio_dev->sys_vbase, st_reg); 162 reg_value &= st_msk; 163 if ((!!check_st) == (!!reg_value)) 164 break; 165 } 166 167 if ((!!check_st) != (!!reg_value)) 168 return -EBUSY; 169 170 return 0; 171 } 172 173 static int hns_mdio_wait_ready(struct mii_bus *bus) 174 { 175 struct hns_mdio_device *mdio_dev = bus->priv; 176 int i; 177 u32 cmd_reg_value = 1; 178 179 /* waitting for MDIO_COMMAND_REG 's mdio_start==0 */ 180 /* after that can do read or write*/ 181 for (i = 0; cmd_reg_value; i++) { 182 cmd_reg_value = MDIO_GET_REG_BIT(mdio_dev, 183 MDIO_COMMAND_REG, 184 MDIO_CMD_START_B); 185 if (i == MDIO_TIMEOUT) 186 return -ETIMEDOUT; 187 } 188 189 return 0; 190 } 191 192 static void hns_mdio_cmd_write(struct hns_mdio_device *mdio_dev, 193 u8 is_c45, u8 op, u8 phy_id, u16 cmd) 194 { 195 u32 cmd_reg_value; 196 u8 st = is_c45 ? MDIO_ST_CLAUSE_45 : MDIO_ST_CLAUSE_22; 197 198 cmd_reg_value = st << MDIO_CMD_ST_S; 199 cmd_reg_value |= op << MDIO_CMD_OP_S; 200 cmd_reg_value |= 201 (phy_id & MDIO_CMD_PRTAD_M) << MDIO_CMD_PRTAD_S; 202 cmd_reg_value |= (cmd & MDIO_CMD_DEVAD_M) << MDIO_CMD_DEVAD_S; 203 cmd_reg_value |= 1 << MDIO_CMD_START_B; 204 205 MDIO_WRITE_REG(mdio_dev, MDIO_COMMAND_REG, cmd_reg_value); 206 } 207 208 /** 209 * hns_mdio_write - access phy register 210 * @bus: mdio bus 211 * @phy_id: phy id 212 * @regnum: register num 213 * @value: register value 214 * 215 * Return 0 on success, negative on failure 216 */ 217 static int hns_mdio_write(struct mii_bus *bus, 218 int phy_id, int regnum, u16 data) 219 { 220 int ret; 221 struct hns_mdio_device *mdio_dev = (struct hns_mdio_device *)bus->priv; 222 u8 devad = ((regnum >> 16) & 0x1f); 223 u8 is_c45 = !!(regnum & MII_ADDR_C45); 224 u16 reg = (u16)(regnum & 0xffff); 225 u8 op; 226 u16 cmd_reg_cfg; 227 228 dev_dbg(&bus->dev, "mdio write %s,base is %p\n", 229 bus->id, mdio_dev->vbase); 230 dev_dbg(&bus->dev, "phy id=%d, is_c45=%d, devad=%d, reg=%#x, write data=%d\n", 231 phy_id, is_c45, devad, reg, data); 232 233 /* wait for ready */ 234 ret = hns_mdio_wait_ready(bus); 235 if (ret) { 236 dev_err(&bus->dev, "MDIO bus is busy\n"); 237 return ret; 238 } 239 240 if (!is_c45) { 241 cmd_reg_cfg = reg; 242 op = MDIO_C22_WRITE; 243 } else { 244 /* config the cmd-reg to write addr*/ 245 MDIO_SET_REG_FIELD(mdio_dev, MDIO_ADDR_REG, MDIO_ADDR_DATA_M, 246 MDIO_ADDR_DATA_S, reg); 247 248 hns_mdio_cmd_write(mdio_dev, is_c45, 249 MDIO_C45_WRITE_ADDR, phy_id, devad); 250 251 /* check for read or write opt is finished */ 252 ret = hns_mdio_wait_ready(bus); 253 if (ret) { 254 dev_err(&bus->dev, "MDIO bus is busy\n"); 255 return ret; 256 } 257 258 /* config the data needed writing */ 259 cmd_reg_cfg = devad; 260 op = MDIO_C45_WRITE_ADDR; 261 } 262 263 MDIO_SET_REG_FIELD(mdio_dev, MDIO_WDATA_REG, MDIO_WDATA_DATA_M, 264 MDIO_WDATA_DATA_S, data); 265 266 hns_mdio_cmd_write(mdio_dev, is_c45, op, phy_id, cmd_reg_cfg); 267 268 return 0; 269 } 270 271 /** 272 * hns_mdio_read - access phy register 273 * @bus: mdio bus 274 * @phy_id: phy id 275 * @regnum: register num 276 * @value: register value 277 * 278 * Return phy register value 279 */ 280 static int hns_mdio_read(struct mii_bus *bus, int phy_id, int regnum) 281 { 282 int ret; 283 u16 reg_val = 0; 284 u8 devad = ((regnum >> 16) & 0x1f); 285 u8 is_c45 = !!(regnum & MII_ADDR_C45); 286 u16 reg = (u16)(regnum & 0xffff); 287 struct hns_mdio_device *mdio_dev = (struct hns_mdio_device *)bus->priv; 288 289 dev_dbg(&bus->dev, "mdio read %s,base is %p\n", 290 bus->id, mdio_dev->vbase); 291 dev_dbg(&bus->dev, "phy id=%d, is_c45=%d, devad=%d, reg=%#x!\n", 292 phy_id, is_c45, devad, reg); 293 294 /* Step 1: wait for ready */ 295 ret = hns_mdio_wait_ready(bus); 296 if (ret) { 297 dev_err(&bus->dev, "MDIO bus is busy\n"); 298 return ret; 299 } 300 301 if (!is_c45) { 302 hns_mdio_cmd_write(mdio_dev, is_c45, 303 MDIO_C22_READ, phy_id, reg); 304 } else { 305 MDIO_SET_REG_FIELD(mdio_dev, MDIO_ADDR_REG, MDIO_ADDR_DATA_M, 306 MDIO_ADDR_DATA_S, reg); 307 308 /* Step 2; config the cmd-reg to write addr*/ 309 hns_mdio_cmd_write(mdio_dev, is_c45, 310 MDIO_C45_WRITE_ADDR, phy_id, devad); 311 312 /* Step 3: check for read or write opt is finished */ 313 ret = hns_mdio_wait_ready(bus); 314 if (ret) { 315 dev_err(&bus->dev, "MDIO bus is busy\n"); 316 return ret; 317 } 318 319 hns_mdio_cmd_write(mdio_dev, is_c45, 320 MDIO_C45_WRITE_ADDR, phy_id, devad); 321 } 322 323 /* Step 5: waitting for MDIO_COMMAND_REG 's mdio_start==0,*/ 324 /* check for read or write opt is finished */ 325 ret = hns_mdio_wait_ready(bus); 326 if (ret) { 327 dev_err(&bus->dev, "MDIO bus is busy\n"); 328 return ret; 329 } 330 331 reg_val = MDIO_GET_REG_BIT(mdio_dev, MDIO_STA_REG, MDIO_STATE_STA_B); 332 if (reg_val) { 333 dev_err(&bus->dev, " ERROR! MDIO Read failed!\n"); 334 return -EBUSY; 335 } 336 337 /* Step 6; get out data*/ 338 reg_val = (u16)MDIO_GET_REG_FIELD(mdio_dev, MDIO_RDATA_REG, 339 MDIO_RDATA_DATA_M, MDIO_RDATA_DATA_S); 340 341 return reg_val; 342 } 343 344 /** 345 * hns_mdio_reset - reset mdio bus 346 * @bus: mdio bus 347 * 348 * Return 0 on success, negative on failure 349 */ 350 static int hns_mdio_reset(struct mii_bus *bus) 351 { 352 struct hns_mdio_device *mdio_dev = (struct hns_mdio_device *)bus->priv; 353 int ret; 354 355 if (!mdio_dev->sys_vbase) { 356 dev_err(&bus->dev, "mdio sys ctl reg has not maped\n"); 357 return -ENODEV; 358 } 359 360 /*1. reset req, and read reset st check*/ 361 ret = mdio_sc_cfg_reg_write(mdio_dev, MDIO_SC_RESET_REQ, 0x1, 362 MDIO_SC_RESET_ST, 0x1, 363 MDIO_CHECK_SET_ST); 364 if (ret) { 365 dev_err(&bus->dev, "MDIO reset fail\n"); 366 return ret; 367 } 368 369 /*2. dis clk, and read clk st check*/ 370 ret = mdio_sc_cfg_reg_write(mdio_dev, MDIO_SC_CLK_DIS, 371 0x1, MDIO_SC_CLK_ST, 0x1, 372 MDIO_CHECK_CLR_ST); 373 if (ret) { 374 dev_err(&bus->dev, "MDIO dis clk fail\n"); 375 return ret; 376 } 377 378 /*3. reset dreq, and read reset st check*/ 379 ret = mdio_sc_cfg_reg_write(mdio_dev, MDIO_SC_RESET_DREQ, 0x1, 380 MDIO_SC_RESET_ST, 0x1, 381 MDIO_CHECK_CLR_ST); 382 if (ret) { 383 dev_err(&bus->dev, "MDIO dis clk fail\n"); 384 return ret; 385 } 386 387 /*4. en clk, and read clk st check*/ 388 ret = mdio_sc_cfg_reg_write(mdio_dev, MDIO_SC_CLK_EN, 389 0x1, MDIO_SC_CLK_ST, 0x1, 390 MDIO_CHECK_SET_ST); 391 if (ret) 392 dev_err(&bus->dev, "MDIO en clk fail\n"); 393 394 return ret; 395 } 396 397 /** 398 * hns_mdio_bus_name - get mdio bus name 399 * @name: mdio bus name 400 * @np: mdio device node pointer 401 */ 402 static void hns_mdio_bus_name(char *name, struct device_node *np) 403 { 404 const u32 *addr; 405 u64 taddr = OF_BAD_ADDR; 406 407 addr = of_get_address(np, 0, NULL, NULL); 408 if (addr) 409 taddr = of_translate_address(np, addr); 410 411 snprintf(name, MII_BUS_ID_SIZE, "%s@%llx", np->name, 412 (unsigned long long)taddr); 413 } 414 415 /** 416 * hns_mdio_probe - probe mdio device 417 * @pdev: mdio platform device 418 * 419 * Return 0 on success, negative on failure 420 */ 421 static int hns_mdio_probe(struct platform_device *pdev) 422 { 423 struct device_node *np; 424 struct hns_mdio_device *mdio_dev; 425 struct mii_bus *new_bus; 426 struct resource *res; 427 int ret; 428 429 if (!pdev) { 430 dev_err(NULL, "pdev is NULL!\r\n"); 431 return -ENODEV; 432 } 433 np = pdev->dev.of_node; 434 mdio_dev = devm_kzalloc(&pdev->dev, sizeof(*mdio_dev), GFP_KERNEL); 435 if (!mdio_dev) 436 return -ENOMEM; 437 438 new_bus = devm_mdiobus_alloc(&pdev->dev); 439 if (!new_bus) { 440 dev_err(&pdev->dev, "mdiobus_alloc fail!\n"); 441 return -ENOMEM; 442 } 443 444 new_bus->name = MDIO_BUS_NAME; 445 new_bus->read = hns_mdio_read; 446 new_bus->write = hns_mdio_write; 447 new_bus->reset = hns_mdio_reset; 448 new_bus->priv = mdio_dev; 449 hns_mdio_bus_name(new_bus->id, np); 450 451 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 452 mdio_dev->vbase = devm_ioremap_resource(&pdev->dev, res); 453 if (IS_ERR(mdio_dev->vbase)) { 454 ret = PTR_ERR(mdio_dev->vbase); 455 return ret; 456 } 457 458 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 459 mdio_dev->sys_vbase = devm_ioremap_resource(&pdev->dev, res); 460 if (IS_ERR(mdio_dev->sys_vbase)) { 461 ret = PTR_ERR(mdio_dev->sys_vbase); 462 return ret; 463 } 464 465 new_bus->irq = devm_kcalloc(&pdev->dev, PHY_MAX_ADDR, 466 sizeof(int), GFP_KERNEL); 467 if (!new_bus->irq) 468 return -ENOMEM; 469 470 new_bus->parent = &pdev->dev; 471 platform_set_drvdata(pdev, new_bus); 472 473 ret = of_mdiobus_register(new_bus, np); 474 if (ret) { 475 dev_err(&pdev->dev, "Cannot register as MDIO bus!\n"); 476 platform_set_drvdata(pdev, NULL); 477 return ret; 478 } 479 480 return 0; 481 } 482 483 /** 484 * hns_mdio_remove - remove mdio device 485 * @pdev: mdio platform device 486 * 487 * Return 0 on success, negative on failure 488 */ 489 static int hns_mdio_remove(struct platform_device *pdev) 490 { 491 struct mii_bus *bus; 492 493 bus = platform_get_drvdata(pdev); 494 495 mdiobus_unregister(bus); 496 platform_set_drvdata(pdev, NULL); 497 return 0; 498 } 499 500 static const struct of_device_id hns_mdio_match[] = { 501 {.compatible = "hisilicon,mdio"}, 502 {.compatible = "hisilicon,hns-mdio"}, 503 {} 504 }; 505 506 static struct platform_driver hns_mdio_driver = { 507 .probe = hns_mdio_probe, 508 .remove = hns_mdio_remove, 509 .driver = { 510 .name = MDIO_DRV_NAME, 511 .of_match_table = hns_mdio_match, 512 }, 513 }; 514 515 module_platform_driver(hns_mdio_driver); 516 517 MODULE_LICENSE("GPL"); 518 MODULE_AUTHOR("Huawei Tech. Co., Ltd."); 519 MODULE_DESCRIPTION("Hisilicon HNS MDIO driver"); 520 MODULE_ALIAS("platform:" MDIO_DRV_NAME); 521