Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: i.MX6: Add OF configuration support for ksz9031

Adds support for ksz9031 PAD skew configuration over devicetree.

Signed-off-by: Hubert Chaumette <hchaumette@adeneo-embedded.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Hubert Chaumette and committed by
David S. Miller
6e4b8273 4b405efb

+105 -1
+105 -1
drivers/net/phy/micrel.c
··· 283 283 return 0; 284 284 } 285 285 286 + #define MII_KSZ9031RN_MMD_CTRL_REG 0x0d 287 + #define MII_KSZ9031RN_MMD_REGDATA_REG 0x0e 288 + #define OP_DATA 1 289 + #define KSZ9031_PS_TO_REG 60 290 + 291 + /* Extended registers */ 292 + #define MII_KSZ9031RN_CONTROL_PAD_SKEW 4 293 + #define MII_KSZ9031RN_RX_DATA_PAD_SKEW 5 294 + #define MII_KSZ9031RN_TX_DATA_PAD_SKEW 6 295 + #define MII_KSZ9031RN_CLK_PAD_SKEW 8 296 + 297 + static int ksz9031_extended_write(struct phy_device *phydev, 298 + u8 mode, u32 dev_addr, u32 regnum, u16 val) 299 + { 300 + phy_write(phydev, MII_KSZ9031RN_MMD_CTRL_REG, dev_addr); 301 + phy_write(phydev, MII_KSZ9031RN_MMD_REGDATA_REG, regnum); 302 + phy_write(phydev, MII_KSZ9031RN_MMD_CTRL_REG, (mode << 14) | dev_addr); 303 + return phy_write(phydev, MII_KSZ9031RN_MMD_REGDATA_REG, val); 304 + } 305 + 306 + static int ksz9031_extended_read(struct phy_device *phydev, 307 + u8 mode, u32 dev_addr, u32 regnum) 308 + { 309 + phy_write(phydev, MII_KSZ9031RN_MMD_CTRL_REG, dev_addr); 310 + phy_write(phydev, MII_KSZ9031RN_MMD_REGDATA_REG, regnum); 311 + phy_write(phydev, MII_KSZ9031RN_MMD_CTRL_REG, (mode << 14) | dev_addr); 312 + return phy_read(phydev, MII_KSZ9031RN_MMD_REGDATA_REG); 313 + } 314 + 315 + static int ksz9031_of_load_skew_values(struct phy_device *phydev, 316 + struct device_node *of_node, 317 + u16 reg, size_t field_sz, 318 + char *field[], u8 numfields) 319 + { 320 + int val[4] = {-1, -2, -3, -4}; 321 + int matches = 0; 322 + u16 mask; 323 + u16 maxval; 324 + u16 newval; 325 + int i; 326 + 327 + for (i = 0; i < numfields; i++) 328 + if (!of_property_read_u32(of_node, field[i], val + i)) 329 + matches++; 330 + 331 + if (!matches) 332 + return 0; 333 + 334 + if (matches < numfields) 335 + newval = ksz9031_extended_read(phydev, OP_DATA, 2, reg); 336 + else 337 + newval = 0; 338 + 339 + maxval = (field_sz == 4) ? 0xf : 0x1f; 340 + for (i = 0; i < numfields; i++) 341 + if (val[i] != -(i + 1)) { 342 + mask = 0xffff; 343 + mask ^= maxval << (field_sz * i); 344 + newval = (newval & mask) | 345 + (((val[i] / KSZ9031_PS_TO_REG) & maxval) 346 + << (field_sz * i)); 347 + } 348 + 349 + return ksz9031_extended_write(phydev, OP_DATA, 2, reg, newval); 350 + } 351 + 352 + static int ksz9031_config_init(struct phy_device *phydev) 353 + { 354 + struct device *dev = &phydev->dev; 355 + struct device_node *of_node = dev->of_node; 356 + char *clk_skews[2] = {"rxc-skew-ps", "txc-skew-ps"}; 357 + char *rx_data_skews[4] = { 358 + "rxd0-skew-ps", "rxd1-skew-ps", 359 + "rxd2-skew-ps", "rxd3-skew-ps" 360 + }; 361 + char *tx_data_skews[4] = { 362 + "txd0-skew-ps", "txd1-skew-ps", 363 + "txd2-skew-ps", "txd3-skew-ps" 364 + }; 365 + char *control_skews[2] = {"txen-skew-ps", "rxdv-skew-ps"}; 366 + 367 + if (!of_node && dev->parent->of_node) 368 + of_node = dev->parent->of_node; 369 + 370 + if (of_node) { 371 + ksz9031_of_load_skew_values(phydev, of_node, 372 + MII_KSZ9031RN_CLK_PAD_SKEW, 5, 373 + clk_skews, 2); 374 + 375 + ksz9031_of_load_skew_values(phydev, of_node, 376 + MII_KSZ9031RN_CONTROL_PAD_SKEW, 4, 377 + control_skews, 2); 378 + 379 + ksz9031_of_load_skew_values(phydev, of_node, 380 + MII_KSZ9031RN_RX_DATA_PAD_SKEW, 4, 381 + rx_data_skews, 4); 382 + 383 + ksz9031_of_load_skew_values(phydev, of_node, 384 + MII_KSZ9031RN_TX_DATA_PAD_SKEW, 4, 385 + tx_data_skews, 4); 386 + } 387 + return 0; 388 + } 389 + 286 390 #define KSZ8873MLL_GLOBAL_CONTROL_4 0x06 287 391 #define KSZ8873MLL_GLOBAL_CONTROL_4_DUPLEX (1 << 6) 288 392 #define KSZ8873MLL_GLOBAL_CONTROL_4_SPEED (1 << 4) ··· 573 469 .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause 574 470 | SUPPORTED_Asym_Pause), 575 471 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, 576 - .config_init = kszphy_config_init, 472 + .config_init = ksz9031_config_init, 577 473 .config_aneg = genphy_config_aneg, 578 474 .read_status = genphy_read_status, 579 475 .ack_interrupt = kszphy_ack_interrupt,