]> Git Repo - J-u-boot.git/blame - drivers/net/phy/atheros.c
phy: atheros: introduce debug read and write functions
[J-u-boot.git] / drivers / net / phy / atheros.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
9082eeac
AF
2/*
3 * Atheros PHY drivers
4 *
6027384a 5 * Copyright 2011, 2013 Freescale Semiconductor, Inc.
9082eeac 6 * author Andy Fleming
9082eeac 7 */
05b60ac5 8#include <common.h>
9082eeac
AF
9#include <phy.h>
10
ce412b79
M
11#define AR803x_PHY_DEBUG_ADDR_REG 0x1d
12#define AR803x_PHY_DEBUG_DATA_REG 0x1e
13
14#define AR803x_DEBUG_REG_5 0x5
29602f9c 15#define AR803x_RGMII_TX_CLK_DLY BIT(8)
ce412b79
M
16
17#define AR803x_DEBUG_REG_0 0x0
29602f9c
VO
18#define AR803x_RGMII_RX_CLK_DLY BIT(15)
19
a234ae86
VO
20/* 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
30e31931
MW
29#define AR8021_PHY_ID 0x004dd040
30#define AR8031_PHY_ID 0x004dd074
31#define AR8035_PHY_ID 0x004dd072
32
f6ae47be 33static int ar803x_debug_reg_read(struct phy_device *phydev, u16 reg)
29602f9c 34{
f6ae47be
MW
35 int ret;
36
37 ret = phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_ADDR_REG,
38 reg);
39 if (ret < 0)
40 return ret;
41
42 return phy_read(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_DATA_REG);
43}
44
45static int ar803x_debug_reg_mask(struct phy_device *phydev, u16 reg,
46 u16 clear, u16 set)
47{
48 int val;
49
50 val = ar803x_debug_reg_read(phydev, reg);
51 if (val < 0)
52 return val;
53
54 val &= 0xffff;
55 val &= ~clear;
56 val |= set;
57
58 return phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_DATA_REG,
59 val);
60}
61
62static int ar803x_enable_rx_delay(struct phy_device *phydev, bool on)
63{
64 u16 clear = 0, set = 0;
29602f9c 65
29602f9c 66 if (on)
f6ae47be 67 set = AR803x_RGMII_RX_CLK_DLY;
29602f9c 68 else
f6ae47be
MW
69 clear = AR803x_RGMII_RX_CLK_DLY;
70
71 return ar803x_debug_reg_mask(phydev, AR803x_DEBUG_REG_0, clear, set);
29602f9c
VO
72}
73
f6ae47be 74static int ar803x_enable_tx_delay(struct phy_device *phydev, bool on)
29602f9c 75{
f6ae47be 76 u16 clear = 0, set = 0;
29602f9c 77
29602f9c 78 if (on)
f6ae47be 79 set = AR803x_RGMII_TX_CLK_DLY;
29602f9c 80 else
f6ae47be
MW
81 clear = AR803x_RGMII_TX_CLK_DLY;
82
83 return ar803x_debug_reg_mask(phydev, AR803x_DEBUG_REG_5, clear, set);
29602f9c 84}
ce412b79 85
9082eeac
AF
86static int ar8021_config(struct phy_device *phydev)
87{
4d4e4cf7
VO
88 phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR,
89 BMCR_ANENABLE | BMCR_ANRESTART);
90
91 ar803x_enable_tx_delay(phydev, true);
9082eeac 92
e0d80964 93 phydev->supported = phydev->drv->features;
9082eeac
AF
94 return 0;
95}
96
ce412b79
M
97static int ar8031_config(struct phy_device *phydev)
98{
99 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
29602f9c
VO
100 phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
101 ar803x_enable_tx_delay(phydev, true);
13114f38
VO
102 else
103 ar803x_enable_tx_delay(phydev, false);
ce412b79
M
104
105 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
29602f9c
VO
106 phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
107 ar803x_enable_rx_delay(phydev, true);
13114f38
VO
108 else
109 ar803x_enable_rx_delay(phydev, false);
ce412b79
M
110
111 phydev->supported = phydev->drv->features;
112
113 genphy_config_aneg(phydev);
114 genphy_restart_aneg(phydev);
115
116 return 0;
117}
118
6027384a
XX
119static int ar8035_config(struct phy_device *phydev)
120{
121 int regval;
122
a234ae86
VO
123 /* Configure CLK_25M output clock at 125 MHz */
124 regval = phy_read_mmd(phydev, MDIO_MMD_AN, AR803x_CLK_25M_SEL_REG);
125 regval &= ~AR8035_CLK_25M_MASK; /* No surprises */
126 regval |= AR8035_CLK_25M_FREQ_125M;
127 phy_write_mmd(phydev, MDIO_MMD_AN, AR803x_CLK_25M_SEL_REG, regval);
6027384a 128
2ec4d10b 129 if ((phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||
29602f9c
VO
130 (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID))
131 ar803x_enable_tx_delay(phydev, true);
13114f38
VO
132 else
133 ar803x_enable_tx_delay(phydev, false);
2ec4d10b
AM
134
135 if ((phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||
29602f9c
VO
136 (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID))
137 ar803x_enable_rx_delay(phydev, true);
13114f38
VO
138 else
139 ar803x_enable_rx_delay(phydev, false);
2ec4d10b 140
02aa4c53 141 phydev->supported = phydev->drv->features;
6027384a 142
903d384d
AW
143 genphy_config_aneg(phydev);
144 genphy_restart_aneg(phydev);
145
6027384a
XX
146 return 0;
147}
148
06370590 149static struct phy_driver AR8021_driver = {
9082eeac 150 .name = "AR8021",
30e31931 151 .uid = AR8021_PHY_ID,
f4d48f43 152 .mask = 0xfffffff0,
9082eeac
AF
153 .features = PHY_GBIT_FEATURES,
154 .config = ar8021_config,
155 .startup = genphy_startup,
156 .shutdown = genphy_shutdown,
157};
158
433a2c53 159static struct phy_driver AR8031_driver = {
626ee1e3 160 .name = "AR8031/AR8033",
30e31931 161 .uid = AR8031_PHY_ID,
f66e3ded 162 .mask = 0xffffffef,
433a2c53 163 .features = PHY_GBIT_FEATURES,
ce412b79 164 .config = ar8031_config,
433a2c53
HS
165 .startup = genphy_startup,
166 .shutdown = genphy_shutdown,
167};
168
169static struct phy_driver AR8035_driver = {
6027384a 170 .name = "AR8035",
30e31931 171 .uid = AR8035_PHY_ID,
f66e3ded 172 .mask = 0xffffffef,
6027384a
XX
173 .features = PHY_GBIT_FEATURES,
174 .config = ar8035_config,
175 .startup = genphy_startup,
176 .shutdown = genphy_shutdown,
177};
178
9082eeac
AF
179int phy_atheros_init(void)
180{
181 phy_register(&AR8021_driver);
433a2c53 182 phy_register(&AR8031_driver);
6027384a 183 phy_register(&AR8035_driver);
9082eeac
AF
184
185 return 0;
186}
This page took 0.489477 seconds and 4 git commands to generate.