blob: d7e76deeb7c9783d6efa1f1d36b0945803e7982e [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{
Zhao Qiangffdc8582017-12-14 09:50:46 +080022 phy_write(phydev, MDIO_DEVAD_NONE, 0x00, 0x1200);
Andy Fleming60ca78b2011-04-07 21:56:05 -050023 phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
24 phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x3D47);
25
Zhao Qiang04f2ba42013-12-23 15:51:33 +080026 phydev->supported = phydev->drv->features;
Mugunthan V N3e4537d2016-10-13 19:33:36 +053027 return 0;
28}
29
30static int ar8031_config(struct phy_device *phydev)
31{
32 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
33 phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
34 phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_ADDR_REG,
35 AR803x_DEBUG_REG_5);
36 phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_DATA_REG,
37 AR803x_RGMII_TX_CLK_DLY);
38 }
39
40 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
41 phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
42 phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_ADDR_REG,
43 AR803x_DEBUG_REG_0);
44 phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_DATA_REG,
45 AR803x_RGMII_RX_CLK_DLY);
46 }
47
48 phydev->supported = phydev->drv->features;
49
50 genphy_config_aneg(phydev);
51 genphy_restart_aneg(phydev);
52
Andy Fleming60ca78b2011-04-07 21:56:05 -050053 return 0;
54}
55
Xie Xiaobodcc307e2013-04-10 16:23:39 +080056static int ar8035_config(struct phy_device *phydev)
57{
58 int regval;
59
60 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x0007);
61 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
62 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
63 regval = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
64 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, (regval|0x0018));
65
66 phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
67 regval = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
68 phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, (regval|0x0100));
69
Andrea Merello1e3e19f2016-05-26 18:24:28 +020070 if ((phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||
71 (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) {
72 /* select debug reg 5 */
73 phy_write(phydev, MDIO_DEVAD_NONE, 0x1D, 0x5);
74 /* enable tx delay */
75 phy_write(phydev, MDIO_DEVAD_NONE, 0x1E, 0x0100);
76 }
77
78 if ((phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||
79 (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)) {
80 /* select debug reg 0 */
81 phy_write(phydev, MDIO_DEVAD_NONE, 0x1D, 0x0);
82 /* enable rx delay */
83 phy_write(phydev, MDIO_DEVAD_NONE, 0x1E, 0x8000);
84 }
85
Xiaobo Xieaa09e682014-04-11 16:03:11 +080086 phydev->supported = phydev->drv->features;
Xie Xiaobodcc307e2013-04-10 16:23:39 +080087
Alison Wang5dc3af82016-02-19 15:52:28 +080088 genphy_config_aneg(phydev);
89 genphy_restart_aneg(phydev);
90
Xie Xiaobodcc307e2013-04-10 16:23:39 +080091 return 0;
92}
93
Kim Phillips40c2c032012-10-29 13:34:33 +000094static struct phy_driver AR8021_driver = {
Andy Fleming60ca78b2011-04-07 21:56:05 -050095 .name = "AR8021",
96 .uid = 0x4dd040,
Haijun.Zhang0faa93d2014-03-04 15:56:12 +080097 .mask = 0x4ffff0,
Andy Fleming60ca78b2011-04-07 21:56:05 -050098 .features = PHY_GBIT_FEATURES,
99 .config = ar8021_config,
100 .startup = genphy_startup,
101 .shutdown = genphy_shutdown,
102};
103
Heiko Schocher93ac9b82013-06-04 10:58:00 +0200104static struct phy_driver AR8031_driver = {
Shengzhou Liu76f57c32013-08-08 16:33:35 +0800105 .name = "AR8031/AR8033",
Heiko Schocher93ac9b82013-06-04 10:58:00 +0200106 .uid = 0x4dd074,
Fabio Estevam2edb6062014-01-03 15:55:59 -0200107 .mask = 0xffffffef,
Heiko Schocher93ac9b82013-06-04 10:58:00 +0200108 .features = PHY_GBIT_FEATURES,
Mugunthan V N3e4537d2016-10-13 19:33:36 +0530109 .config = ar8031_config,
Heiko Schocher93ac9b82013-06-04 10:58:00 +0200110 .startup = genphy_startup,
111 .shutdown = genphy_shutdown,
112};
113
114static struct phy_driver AR8035_driver = {
Xie Xiaobodcc307e2013-04-10 16:23:39 +0800115 .name = "AR8035",
116 .uid = 0x4dd072,
Fabio Estevam2edb6062014-01-03 15:55:59 -0200117 .mask = 0xffffffef,
Xie Xiaobodcc307e2013-04-10 16:23:39 +0800118 .features = PHY_GBIT_FEATURES,
119 .config = ar8035_config,
120 .startup = genphy_startup,
121 .shutdown = genphy_shutdown,
122};
123
Andy Fleming60ca78b2011-04-07 21:56:05 -0500124int phy_atheros_init(void)
125{
126 phy_register(&AR8021_driver);
Heiko Schocher93ac9b82013-06-04 10:58:00 +0200127 phy_register(&AR8031_driver);
Xie Xiaobodcc307e2013-04-10 16:23:39 +0800128 phy_register(&AR8035_driver);
Andy Fleming60ca78b2011-04-07 21:56:05 -0500129
130 return 0;
131}