1
1
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
2
2
/* Copyright 2019 NXP */
3
3
4
+ #include <linux/fsl/enetc_mdio.h>
4
5
#include <linux/mdio.h>
5
6
#include <linux/of_mdio.h>
6
7
#include <linux/iopoll.h>
7
8
#include <linux/of.h>
8
9
9
- #include "enetc_mdio .h"
10
+ #include "enetc_pf .h"
10
11
11
- #define ENETC_MDIO_REG_OFFSET 0x1c00
12
12
#define ENETC_MDIO_CFG 0x0 /* MDIO configuration and status */
13
13
#define ENETC_MDIO_CTL 0x4 /* MDIO control */
14
14
#define ENETC_MDIO_DATA 0x8 /* MDIO data */
15
15
#define ENETC_MDIO_ADDR 0xc /* MDIO address */
16
16
17
- #define enetc_mdio_rd (hw , off ) \
18
- enetc_port_rd(hw, ENETC_##off + ENETC_MDIO_REG_OFFSET)
19
- #define enetc_mdio_wr (hw , off , val ) \
20
- enetc_port_wr(hw, ENETC_##off + ENETC_MDIO_REG_OFFSET, val)
21
- #define enetc_mdio_rd_reg (off ) enetc_mdio_rd(hw, off)
17
+ static inline u32 _enetc_mdio_rd (struct enetc_mdio_priv * mdio_priv , int off )
18
+ {
19
+ return enetc_port_rd (mdio_priv -> hw , mdio_priv -> mdio_base + off );
20
+ }
21
+
22
+ static inline void _enetc_mdio_wr (struct enetc_mdio_priv * mdio_priv , int off ,
23
+ u32 val )
24
+ {
25
+ enetc_port_wr (mdio_priv -> hw , mdio_priv -> mdio_base + off , val );
26
+ }
27
+
28
+ #define enetc_mdio_rd (mdio_priv , off ) \
29
+ _enetc_mdio_rd(mdio_priv, ENETC_##off)
30
+ #define enetc_mdio_wr (mdio_priv , off , val ) \
31
+ _enetc_mdio_wr(mdio_priv, ENETC_##off, val)
32
+ #define enetc_mdio_rd_reg (off ) enetc_mdio_rd(mdio_priv, off)
22
33
23
34
#define ENETC_MDC_DIV 258
24
35
35
46
#define MDIO_DATA (x ) ((x) & 0xffff)
36
47
37
48
#define TIMEOUT 1000
38
- static int enetc_mdio_wait_complete (struct enetc_hw * hw )
49
+ static int enetc_mdio_wait_complete (struct enetc_mdio_priv * mdio_priv )
39
50
{
40
51
u32 val ;
41
52
@@ -46,7 +57,6 @@ static int enetc_mdio_wait_complete(struct enetc_hw *hw)
46
57
int enetc_mdio_write (struct mii_bus * bus , int phy_id , int regnum , u16 value )
47
58
{
48
59
struct enetc_mdio_priv * mdio_priv = bus -> priv ;
49
- struct enetc_hw * hw = mdio_priv -> hw ;
50
60
u32 mdio_ctl , mdio_cfg ;
51
61
u16 dev_addr ;
52
62
int ret ;
@@ -61,39 +71,39 @@ int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value)
61
71
mdio_cfg &= ~MDIO_CFG_ENC45 ;
62
72
}
63
73
64
- enetc_mdio_wr (hw , MDIO_CFG , mdio_cfg );
74
+ enetc_mdio_wr (mdio_priv , MDIO_CFG , mdio_cfg );
65
75
66
- ret = enetc_mdio_wait_complete (hw );
76
+ ret = enetc_mdio_wait_complete (mdio_priv );
67
77
if (ret )
68
78
return ret ;
69
79
70
80
/* set port and dev addr */
71
81
mdio_ctl = MDIO_CTL_PORT_ADDR (phy_id ) | MDIO_CTL_DEV_ADDR (dev_addr );
72
- enetc_mdio_wr (hw , MDIO_CTL , mdio_ctl );
82
+ enetc_mdio_wr (mdio_priv , MDIO_CTL , mdio_ctl );
73
83
74
84
/* set the register address */
75
85
if (regnum & MII_ADDR_C45 ) {
76
- enetc_mdio_wr (hw , MDIO_ADDR , regnum & 0xffff );
86
+ enetc_mdio_wr (mdio_priv , MDIO_ADDR , regnum & 0xffff );
77
87
78
- ret = enetc_mdio_wait_complete (hw );
88
+ ret = enetc_mdio_wait_complete (mdio_priv );
79
89
if (ret )
80
90
return ret ;
81
91
}
82
92
83
93
/* write the value */
84
- enetc_mdio_wr (hw , MDIO_DATA , MDIO_DATA (value ));
94
+ enetc_mdio_wr (mdio_priv , MDIO_DATA , MDIO_DATA (value ));
85
95
86
- ret = enetc_mdio_wait_complete (hw );
96
+ ret = enetc_mdio_wait_complete (mdio_priv );
87
97
if (ret )
88
98
return ret ;
89
99
90
100
return 0 ;
91
101
}
102
+ EXPORT_SYMBOL_GPL (enetc_mdio_write );
92
103
93
104
int enetc_mdio_read (struct mii_bus * bus , int phy_id , int regnum )
94
105
{
95
106
struct enetc_mdio_priv * mdio_priv = bus -> priv ;
96
- struct enetc_hw * hw = mdio_priv -> hw ;
97
107
u32 mdio_ctl , mdio_cfg ;
98
108
u16 dev_addr , value ;
99
109
int ret ;
@@ -107,86 +117,56 @@ int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
107
117
mdio_cfg &= ~MDIO_CFG_ENC45 ;
108
118
}
109
119
110
- enetc_mdio_wr (hw , MDIO_CFG , mdio_cfg );
120
+ enetc_mdio_wr (mdio_priv , MDIO_CFG , mdio_cfg );
111
121
112
- ret = enetc_mdio_wait_complete (hw );
122
+ ret = enetc_mdio_wait_complete (mdio_priv );
113
123
if (ret )
114
124
return ret ;
115
125
116
126
/* set port and device addr */
117
127
mdio_ctl = MDIO_CTL_PORT_ADDR (phy_id ) | MDIO_CTL_DEV_ADDR (dev_addr );
118
- enetc_mdio_wr (hw , MDIO_CTL , mdio_ctl );
128
+ enetc_mdio_wr (mdio_priv , MDIO_CTL , mdio_ctl );
119
129
120
130
/* set the register address */
121
131
if (regnum & MII_ADDR_C45 ) {
122
- enetc_mdio_wr (hw , MDIO_ADDR , regnum & 0xffff );
132
+ enetc_mdio_wr (mdio_priv , MDIO_ADDR , regnum & 0xffff );
123
133
124
- ret = enetc_mdio_wait_complete (hw );
134
+ ret = enetc_mdio_wait_complete (mdio_priv );
125
135
if (ret )
126
136
return ret ;
127
137
}
128
138
129
139
/* initiate the read */
130
- enetc_mdio_wr (hw , MDIO_CTL , mdio_ctl | MDIO_CTL_READ );
140
+ enetc_mdio_wr (mdio_priv , MDIO_CTL , mdio_ctl | MDIO_CTL_READ );
131
141
132
- ret = enetc_mdio_wait_complete (hw );
142
+ ret = enetc_mdio_wait_complete (mdio_priv );
133
143
if (ret )
134
144
return ret ;
135
145
136
146
/* return all Fs if nothing was there */
137
- if (enetc_mdio_rd (hw , MDIO_CFG ) & MDIO_CFG_RD_ER ) {
147
+ if (enetc_mdio_rd (mdio_priv , MDIO_CFG ) & MDIO_CFG_RD_ER ) {
138
148
dev_dbg (& bus -> dev ,
139
149
"Error while reading PHY%d reg at %d.%hhu\n" ,
140
150
phy_id , dev_addr , regnum );
141
151
return 0xffff ;
142
152
}
143
153
144
- value = enetc_mdio_rd (hw , MDIO_DATA ) & 0xffff ;
154
+ value = enetc_mdio_rd (mdio_priv , MDIO_DATA ) & 0xffff ;
145
155
146
156
return value ;
147
157
}
158
+ EXPORT_SYMBOL_GPL (enetc_mdio_read );
148
159
149
- int enetc_mdio_probe (struct enetc_pf * pf )
160
+ struct enetc_hw * enetc_hw_alloc (struct device * dev , void __iomem * port_regs )
150
161
{
151
- struct device * dev = & pf -> si -> pdev -> dev ;
152
- struct enetc_mdio_priv * mdio_priv ;
153
- struct device_node * np ;
154
- struct mii_bus * bus ;
155
- int err ;
156
-
157
- bus = devm_mdiobus_alloc_size (dev , sizeof (* mdio_priv ));
158
- if (!bus )
159
- return - ENOMEM ;
160
-
161
- bus -> name = "Freescale ENETC MDIO Bus" ;
162
- bus -> read = enetc_mdio_read ;
163
- bus -> write = enetc_mdio_write ;
164
- bus -> parent = dev ;
165
- mdio_priv = bus -> priv ;
166
- mdio_priv -> hw = & pf -> si -> hw ;
167
- snprintf (bus -> id , MII_BUS_ID_SIZE , "%s" , dev_name (dev ));
168
-
169
- np = of_get_child_by_name (dev -> of_node , "mdio" );
170
- if (!np ) {
171
- dev_err (dev , "MDIO node missing\n" );
172
- return - EINVAL ;
173
- }
174
-
175
- err = of_mdiobus_register (bus , np );
176
- if (err ) {
177
- of_node_put (np );
178
- dev_err (dev , "cannot register MDIO bus\n" );
179
- return err ;
180
- }
162
+ struct enetc_hw * hw ;
181
163
182
- of_node_put (np );
183
- pf -> mdio = bus ;
164
+ hw = devm_kzalloc (dev , sizeof (* hw ), GFP_KERNEL );
165
+ if (!hw )
166
+ return ERR_PTR (- ENOMEM );
184
167
185
- return 0 ;
186
- }
168
+ hw -> port = port_regs ;
187
169
188
- void enetc_mdio_remove (struct enetc_pf * pf )
189
- {
190
- if (pf -> mdio )
191
- mdiobus_unregister (pf -> mdio );
170
+ return hw ;
192
171
}
172
+ EXPORT_SYMBOL_GPL (enetc_hw_alloc );
0 commit comments