blob: 3e59c3f39150f912bda27f848298308d32ec0df3 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Andy Fleming9082eea2011-04-07 21:56:05 -05002/*
3 * Atheros PHY drivers
4 *
Xie Xiaobo60273842013-04-10 16:23:39 +08005 * Copyright 2011, 2013 Freescale Semiconductor, Inc.
Andy Fleming9082eea2011-04-07 21:56:05 -05006 * author Andy Fleming
Andy Fleming9082eea2011-04-07 21:56:05 -05007 */
Joe Hershberger05b60ac2018-07-25 12:59:22 -05008#include <common.h>
Andy Fleming9082eea2011-04-07 21:56:05 -05009#include <phy.h>
10
Mugunthan V Nce412b72016-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
Vladimir Oltean29602f92020-05-07 00:11:49 +020015#define AR803x_RGMII_TX_CLK_DLY BIT(8)
Mugunthan V Nce412b72016-10-13 19:33:36 +053016
17#define AR803x_DEBUG_REG_0 0x0
Vladimir Oltean29602f92020-05-07 00:11:49 +020018#define AR803x_RGMII_RX_CLK_DLY BIT(15)
19
Vladimir Olteana234ae82020-05-07 00:11:50 +020020/* CLK_25M register is at MMD 7, address 0x8016 */
21#define AR803x_CLK_25M_SEL_REG 0x8016
22/* AR8035: Select frequency on CLK_25M pin through bits 4:3 */
23#define AR8035_CLK_25M_FREQ_25M (0 | 0)
24#define AR8035_CLK_25M_FREQ_50M (0 | BIT(3))
25#define AR8035_CLK_25M_FREQ_62M (BIT(4) | 0)
26#define AR8035_CLK_25M_FREQ_125M (BIT(4) | BIT(3))
27#define AR8035_CLK_25M_MASK GENMASK(4, 3)
28
Vladimir Oltean29602f92020-05-07 00:11:49 +020029static void ar803x_enable_rx_delay(struct phy_device *phydev, bool on)
30{
31 int regval;
32
33 phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_ADDR_REG,
34 AR803x_DEBUG_REG_0);
35 regval = phy_read(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_DATA_REG);
36 if (on)
37 regval |= AR803x_RGMII_RX_CLK_DLY;
38 else
39 regval &= ~AR803x_RGMII_RX_CLK_DLY;
40 phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_DATA_REG, regval);
41}
42
43static void ar803x_enable_tx_delay(struct phy_device *phydev, bool on)
44{
45 int regval;
46
47 phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_ADDR_REG,
48 AR803x_DEBUG_REG_5);
49 regval = phy_read(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_DATA_REG);
50 if (on)
51 regval |= AR803x_RGMII_TX_CLK_DLY;
52 else
53 regval &= ~AR803x_RGMII_TX_CLK_DLY;
54 phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_DATA_REG, regval);
55}
Mugunthan V Nce412b72016-10-13 19:33:36 +053056
Andy Fleming9082eea2011-04-07 21:56:05 -050057static int ar8021_config(struct phy_device *phydev)
58{
Zhao Qiang1e2d2592017-12-14 09:50:46 +080059 phy_write(phydev, MDIO_DEVAD_NONE, 0x00, 0x1200);
Vladimir Oltean29602f92020-05-07 00:11:49 +020060 phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_ADDR_REG,
61 AR803x_DEBUG_REG_5);
62 phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_DATA_REG, 0x3D47);
Andy Fleming9082eea2011-04-07 21:56:05 -050063
Zhao Qiange0d80962013-12-23 15:51:33 +080064 phydev->supported = phydev->drv->features;
Andy Fleming9082eea2011-04-07 21:56:05 -050065 return 0;
66}
67
Mugunthan V Nce412b72016-10-13 19:33:36 +053068static int ar8031_config(struct phy_device *phydev)
69{
70 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
Vladimir Oltean29602f92020-05-07 00:11:49 +020071 phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
72 ar803x_enable_tx_delay(phydev, true);
Vladimir Oltean13114f32020-05-07 00:11:51 +020073 else
74 ar803x_enable_tx_delay(phydev, false);
Mugunthan V Nce412b72016-10-13 19:33:36 +053075
76 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
Vladimir Oltean29602f92020-05-07 00:11:49 +020077 phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
78 ar803x_enable_rx_delay(phydev, true);
Vladimir Oltean13114f32020-05-07 00:11:51 +020079 else
80 ar803x_enable_rx_delay(phydev, false);
Mugunthan V Nce412b72016-10-13 19:33:36 +053081
82 phydev->supported = phydev->drv->features;
83
84 genphy_config_aneg(phydev);
85 genphy_restart_aneg(phydev);
86
87 return 0;
88}
89
Xie Xiaobo60273842013-04-10 16:23:39 +080090static int ar8035_config(struct phy_device *phydev)
91{
92 int regval;
93
Vladimir Olteana234ae82020-05-07 00:11:50 +020094 /* Configure CLK_25M output clock at 125 MHz */
95 regval = phy_read_mmd(phydev, MDIO_MMD_AN, AR803x_CLK_25M_SEL_REG);
96 regval &= ~AR8035_CLK_25M_MASK; /* No surprises */
97 regval |= AR8035_CLK_25M_FREQ_125M;
98 phy_write_mmd(phydev, MDIO_MMD_AN, AR803x_CLK_25M_SEL_REG, regval);
Xie Xiaobo60273842013-04-10 16:23:39 +080099
Andrea Merello2ec4d102016-05-26 18:24:28 +0200100 if ((phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||
Vladimir Oltean29602f92020-05-07 00:11:49 +0200101 (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID))
102 ar803x_enable_tx_delay(phydev, true);
Vladimir Oltean13114f32020-05-07 00:11:51 +0200103 else
104 ar803x_enable_tx_delay(phydev, false);
Andrea Merello2ec4d102016-05-26 18:24:28 +0200105
106 if ((phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||
Vladimir Oltean29602f92020-05-07 00:11:49 +0200107 (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID))
108 ar803x_enable_rx_delay(phydev, true);
Vladimir Oltean13114f32020-05-07 00:11:51 +0200109 else
110 ar803x_enable_rx_delay(phydev, false);
Andrea Merello2ec4d102016-05-26 18:24:28 +0200111
Xiaobo Xie02aa4c52014-04-11 16:03:11 +0800112 phydev->supported = phydev->drv->features;
Xie Xiaobo60273842013-04-10 16:23:39 +0800113
Alison Wang903d3842016-02-19 15:52:28 +0800114 genphy_config_aneg(phydev);
115 genphy_restart_aneg(phydev);
116
Xie Xiaobo60273842013-04-10 16:23:39 +0800117 return 0;
118}
119
Kim Phillips06370592012-10-29 13:34:33 +0000120static struct phy_driver AR8021_driver = {
Andy Fleming9082eea2011-04-07 21:56:05 -0500121 .name = "AR8021",
122 .uid = 0x4dd040,
Haijun.Zhangdc116bd2014-03-04 15:56:12 +0800123 .mask = 0x4ffff0,
Andy Fleming9082eea2011-04-07 21:56:05 -0500124 .features = PHY_GBIT_FEATURES,
125 .config = ar8021_config,
126 .startup = genphy_startup,
127 .shutdown = genphy_shutdown,
128};
129
Heiko Schocher433a2c52013-06-04 10:58:00 +0200130static struct phy_driver AR8031_driver = {
Shengzhou Liu626ee1e2013-08-08 16:33:35 +0800131 .name = "AR8031/AR8033",
Heiko Schocher433a2c52013-06-04 10:58:00 +0200132 .uid = 0x4dd074,
Fabio Estevamf66e3de2014-01-03 15:55:59 -0200133 .mask = 0xffffffef,
Heiko Schocher433a2c52013-06-04 10:58:00 +0200134 .features = PHY_GBIT_FEATURES,
Mugunthan V Nce412b72016-10-13 19:33:36 +0530135 .config = ar8031_config,
Heiko Schocher433a2c52013-06-04 10:58:00 +0200136 .startup = genphy_startup,
137 .shutdown = genphy_shutdown,
138};
139
140static struct phy_driver AR8035_driver = {
Xie Xiaobo60273842013-04-10 16:23:39 +0800141 .name = "AR8035",
142 .uid = 0x4dd072,
Fabio Estevamf66e3de2014-01-03 15:55:59 -0200143 .mask = 0xffffffef,
Xie Xiaobo60273842013-04-10 16:23:39 +0800144 .features = PHY_GBIT_FEATURES,
145 .config = ar8035_config,
146 .startup = genphy_startup,
147 .shutdown = genphy_shutdown,
148};
149
Andy Fleming9082eea2011-04-07 21:56:05 -0500150int phy_atheros_init(void)
151{
152 phy_register(&AR8021_driver);
Heiko Schocher433a2c52013-06-04 10:58:00 +0200153 phy_register(&AR8031_driver);
Xie Xiaobo60273842013-04-10 16:23:39 +0800154 phy_register(&AR8035_driver);
Andy Fleming9082eea2011-04-07 21:56:05 -0500155
156 return 0;
157}