blob: b34cdd3d87dc02f8a01db2f10e895287790679fb [file] [log] [blame]
Andy Fleming60ca78b2011-04-07 21:56:05 -05001/*
2 * Atheros PHY drivers
3 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02004 * SPDX-License-Identifier: GPL-2.0+
Andy Fleming60ca78b2011-04-07 21:56:05 -05005 *
Xie Xiaobodcc307e2013-04-10 16:23:39 +08006 * Copyright 2011, 2013 Freescale Semiconductor, Inc.
Andy Fleming60ca78b2011-04-07 21:56:05 -05007 * author Andy Fleming
Andy Fleming60ca78b2011-04-07 21:56:05 -05008 */
9#include <phy.h>
10
Mugunthan V N3e4537d2016-10-13 19:33:36 +053011#define AR803x_PHY_DEBUG_ADDR_REG 0x1d
12#define AR803x_PHY_DEBUG_DATA_REG 0x1e
13
14#define AR803x_DEBUG_REG_5 0x5
15#define AR803x_RGMII_TX_CLK_DLY 0x100
16
17#define AR803x_DEBUG_REG_0 0x0
18#define AR803x_RGMII_RX_CLK_DLY 0x8000
19
Andy Fleming60ca78b2011-04-07 21:56:05 -050020static int ar8021_config(struct phy_device *phydev)
21{
22 phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
23 phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x3D47);
24
Zhao Qiang04f2ba42013-12-23 15:51:33 +080025 phydev->supported = phydev->drv->features;
Mugunthan V N3e4537d2016-10-13 19:33:36 +053026 return 0;
27}
28
29static int ar8031_config(struct phy_device *phydev)
30{
31 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
32 phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
33 phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_ADDR_REG,
34 AR803x_DEBUG_REG_5);
35 phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_DATA_REG,
36 AR803x_RGMII_TX_CLK_DLY);
37 }
38
39 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
40 phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
41 phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_ADDR_REG,
42 AR803x_DEBUG_REG_0);
43 phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_DATA_REG,
44 AR803x_RGMII_RX_CLK_DLY);
45 }
46
47 phydev->supported = phydev->drv->features;
48
49 genphy_config_aneg(phydev);
50 genphy_restart_aneg(phydev);
51
Andy Fleming60ca78b2011-04-07 21:56:05 -050052 return 0;
53}
54
Xie Xiaobodcc307e2013-04-10 16:23:39 +080055static int ar8035_config(struct phy_device *phydev)
56{
57 int regval;
58
59 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x0007);
60 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
61 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
62 regval = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
63 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, (regval|0x0018));
64
65 phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
66 regval = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
67 phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, (regval|0x0100));
68
Andrea Merello1e3e19f2016-05-26 18:24:28 +020069 if ((phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||
70 (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) {
71 /* select debug reg 5 */
72 phy_write(phydev, MDIO_DEVAD_NONE, 0x1D, 0x5);
73 /* enable tx delay */
74 phy_write(phydev, MDIO_DEVAD_NONE, 0x1E, 0x0100);
75 }
76
77 if ((phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||
78 (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)) {
79 /* select debug reg 0 */
80 phy_write(phydev, MDIO_DEVAD_NONE, 0x1D, 0x0);
81 /* enable rx delay */
82 phy_write(phydev, MDIO_DEVAD_NONE, 0x1E, 0x8000);
83 }
84
Xiaobo Xieaa09e682014-04-11 16:03:11 +080085 phydev->supported = phydev->drv->features;
Xie Xiaobodcc307e2013-04-10 16:23:39 +080086
Alison Wang5dc3af82016-02-19 15:52:28 +080087 genphy_config_aneg(phydev);
88 genphy_restart_aneg(phydev);
89
Xie Xiaobodcc307e2013-04-10 16:23:39 +080090 return 0;
91}
92
Kim Phillips40c2c032012-10-29 13:34:33 +000093static struct phy_driver AR8021_driver = {
Andy Fleming60ca78b2011-04-07 21:56:05 -050094 .name = "AR8021",
95 .uid = 0x4dd040,
Haijun.Zhang0faa93d2014-03-04 15:56:12 +080096 .mask = 0x4ffff0,
Andy Fleming60ca78b2011-04-07 21:56:05 -050097 .features = PHY_GBIT_FEATURES,
98 .config = ar8021_config,
99 .startup = genphy_startup,
100 .shutdown = genphy_shutdown,
101};
102
Heiko Schocher93ac9b82013-06-04 10:58:00 +0200103static struct phy_driver AR8031_driver = {
Shengzhou Liu76f57c32013-08-08 16:33:35 +0800104 .name = "AR8031/AR8033",
Heiko Schocher93ac9b82013-06-04 10:58:00 +0200105 .uid = 0x4dd074,
Fabio Estevam2edb6062014-01-03 15:55:59 -0200106 .mask = 0xffffffef,
Heiko Schocher93ac9b82013-06-04 10:58:00 +0200107 .features = PHY_GBIT_FEATURES,
Mugunthan V N3e4537d2016-10-13 19:33:36 +0530108 .config = ar8031_config,
Heiko Schocher93ac9b82013-06-04 10:58:00 +0200109 .startup = genphy_startup,
110 .shutdown = genphy_shutdown,
111};
112
113static struct phy_driver AR8035_driver = {
Xie Xiaobodcc307e2013-04-10 16:23:39 +0800114 .name = "AR8035",
115 .uid = 0x4dd072,
Fabio Estevam2edb6062014-01-03 15:55:59 -0200116 .mask = 0xffffffef,
Xie Xiaobodcc307e2013-04-10 16:23:39 +0800117 .features = PHY_GBIT_FEATURES,
118 .config = ar8035_config,
119 .startup = genphy_startup,
120 .shutdown = genphy_shutdown,
121};
122
Andy Fleming60ca78b2011-04-07 21:56:05 -0500123int phy_atheros_init(void)
124{
125 phy_register(&AR8021_driver);
Heiko Schocher93ac9b82013-06-04 10:58:00 +0200126 phy_register(&AR8031_driver);
Xie Xiaobodcc307e2013-04-10 16:23:39 +0800127 phy_register(&AR8035_driver);
Andy Fleming60ca78b2011-04-07 21:56:05 -0500128
129 return 0;
130}