| .. | .. |
|---|
| 160 | 160 | phy_write(phydev, REG_PAGE_SEL, 0x0000); |
|---|
| 161 | 161 | } |
|---|
| 162 | 162 | |
|---|
| 163 | | -static void rk630_phy_set_uaps(struct phy_device *phydev) |
|---|
| 163 | +static void rk630_phy_set_aps(struct phy_device *phydev, bool enable) |
|---|
| 164 | +{ |
|---|
| 165 | + u32 value; |
|---|
| 166 | + |
|---|
| 167 | + /* Switch to page 1 */ |
|---|
| 168 | + phy_write(phydev, REG_PAGE_SEL, 0x0100); |
|---|
| 169 | + value = phy_read(phydev, REG_PAGE1_APS_CTRL); |
|---|
| 170 | + if (enable) |
|---|
| 171 | + value |= BIT(15); |
|---|
| 172 | + else |
|---|
| 173 | + value &= ~BIT(15); |
|---|
| 174 | + phy_write(phydev, REG_PAGE1_APS_CTRL, value); |
|---|
| 175 | + /* Switch to page 0 */ |
|---|
| 176 | + phy_write(phydev, REG_PAGE_SEL, 0x0000); |
|---|
| 177 | +} |
|---|
| 178 | + |
|---|
| 179 | +static void rk630_phy_set_uaps(struct phy_device *phydev, bool enable) |
|---|
| 164 | 180 | { |
|---|
| 165 | 181 | u32 value; |
|---|
| 166 | 182 | |
|---|
| 167 | 183 | /* Switch to page 1 */ |
|---|
| 168 | 184 | phy_write(phydev, REG_PAGE_SEL, 0x0100); |
|---|
| 169 | 185 | value = phy_read(phydev, REG_PAGE1_UAPS_CONFIGURE); |
|---|
| 170 | | - value |= BIT(15); |
|---|
| 186 | + if (enable) |
|---|
| 187 | + value |= BIT(15); |
|---|
| 188 | + else |
|---|
| 189 | + value &= ~BIT(15); |
|---|
| 171 | 190 | phy_write(phydev, REG_PAGE1_UAPS_CONFIGURE, value); |
|---|
| 172 | 191 | /* Switch to page 0 */ |
|---|
| 173 | 192 | phy_write(phydev, REG_PAGE_SEL, 0x0000); |
|---|
| .. | .. |
|---|
| 208 | 227 | |
|---|
| 209 | 228 | /* Switch to page 1 */ |
|---|
| 210 | 229 | phy_write(phydev, REG_PAGE_SEL, 0x0100); |
|---|
| 230 | + /* Enable offset clock */ |
|---|
| 231 | + phy_write(phydev, 0x10, 0xfbfe); |
|---|
| 211 | 232 | /* Disable APS */ |
|---|
| 212 | 233 | phy_write(phydev, REG_PAGE1_APS_CTRL, 0x4824); |
|---|
| 213 | 234 | /* Switch to page 2 */ |
|---|
| .. | .. |
|---|
| 244 | 265 | phy_write(phydev, REG_PAGE_SEL, 0x0800); |
|---|
| 245 | 266 | /* Disable auto-cal */ |
|---|
| 246 | 267 | phy_write(phydev, REG_PAGE8_AUTO_CAL, 0x0844); |
|---|
| 268 | + /* Reatart offset calibration */ |
|---|
| 269 | + phy_write(phydev, 0x13, 0xc096); |
|---|
| 247 | 270 | |
|---|
| 248 | 271 | /* Switch to page 0 */ |
|---|
| 249 | 272 | phy_write(phydev, REG_PAGE_SEL, 0x0000); |
|---|
| .. | .. |
|---|
| 264 | 287 | * Ultra Auto-Power Saving Mode (UAPS) is designed to |
|---|
| 265 | 288 | * save power when cable is not plugged into PHY. |
|---|
| 266 | 289 | */ |
|---|
| 267 | | - rk630_phy_set_uaps(phydev); |
|---|
| 290 | + rk630_phy_set_uaps(phydev, true); |
|---|
| 268 | 291 | break; |
|---|
| 269 | 292 | case PHY_ADDR_T22: |
|---|
| 270 | 293 | rk630_phy_t22_config_init(phydev); |
|---|
| 294 | + rk630_phy_set_aps(phydev, false); |
|---|
| 295 | + rk630_phy_set_uaps(phydev, false); |
|---|
| 271 | 296 | break; |
|---|
| 272 | 297 | default: |
|---|
| 273 | 298 | phydev_err(phydev, "Unsupported address for current phy: %d\n", |
|---|
| .. | .. |
|---|
| 278 | 303 | rk630_phy_ieee_set(phydev, true); |
|---|
| 279 | 304 | |
|---|
| 280 | 305 | return 0; |
|---|
| 306 | +} |
|---|
| 307 | + |
|---|
| 308 | +static void rk630_link_change_notify(struct phy_device *phydev) |
|---|
| 309 | +{ |
|---|
| 310 | + unsigned int val; |
|---|
| 311 | + |
|---|
| 312 | + if (phydev->state == PHY_RUNNING || phydev->state == PHY_NOLINK) { |
|---|
| 313 | + /* Switch to page 6 */ |
|---|
| 314 | + phy_write(phydev, REG_PAGE_SEL, 0x0600); |
|---|
| 315 | + val = phy_read(phydev, REG_PAGE6_AFE_TX_CTRL); |
|---|
| 316 | + val &= ~GENMASK(14, 13); |
|---|
| 317 | + if (phydev->speed == SPEED_10 && phydev->link) |
|---|
| 318 | + val |= BIT(13); |
|---|
| 319 | + phy_write(phydev, REG_PAGE6_AFE_TX_CTRL, val); |
|---|
| 320 | + /* Switch to page 0 */ |
|---|
| 321 | + phy_write(phydev, REG_PAGE_SEL, 0x0000); |
|---|
| 322 | + } |
|---|
| 281 | 323 | } |
|---|
| 282 | 324 | |
|---|
| 283 | 325 | static irqreturn_t rk630_wol_irq_thread(int irq, void *dev_id) |
|---|
| .. | .. |
|---|
| 365 | 407 | .name = "RK630 PHY", |
|---|
| 366 | 408 | .features = PHY_BASIC_FEATURES, |
|---|
| 367 | 409 | .flags = 0, |
|---|
| 410 | + .link_change_notify = rk630_link_change_notify, |
|---|
| 368 | 411 | .probe = rk630_phy_probe, |
|---|
| 369 | 412 | .remove = rk630_phy_remove, |
|---|
| 370 | 413 | .soft_reset = genphy_soft_reset, |
|---|
| .. | .. |
|---|
| 381 | 424 | { } |
|---|
| 382 | 425 | }; |
|---|
| 383 | 426 | |
|---|
| 384 | | -MODULE_DEVICE_TABLE(mdio, rockchip_phy_tbl); |
|---|
| 427 | +MODULE_DEVICE_TABLE(mdio, rk630_phy_tbl); |
|---|
| 385 | 428 | |
|---|
| 386 | 429 | module_phy_driver(rk630_phy_driver); |
|---|
| 387 | 430 | |
|---|