.. | .. |
---|
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 | |
---|