11// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
22/* Copyright 2019 NXP */
33
4+ #include <linux/fsl/enetc_mdio.h>
45#include <linux/mdio.h>
56#include <linux/of_mdio.h>
67#include <linux/iopoll.h>
78#include <linux/of.h>
89
9- #include "enetc_mdio .h"
10+ #include "enetc_pf .h"
1011
11- #define ENETC_MDIO_REG_OFFSET 0x1c00
1212#define ENETC_MDIO_CFG 0x0 /* MDIO configuration and status */
1313#define ENETC_MDIO_CTL 0x4 /* MDIO control */
1414#define ENETC_MDIO_DATA 0x8 /* MDIO data */
1515#define ENETC_MDIO_ADDR 0xc /* MDIO address */
1616
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)
2233
2334#define ENETC_MDC_DIV 258
2435
3546#define MDIO_DATA (x ) ((x) & 0xffff)
3647
3748#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 )
3950{
4051 u32 val ;
4152
@@ -46,7 +57,6 @@ static int enetc_mdio_wait_complete(struct enetc_hw *hw)
4657int enetc_mdio_write (struct mii_bus * bus , int phy_id , int regnum , u16 value )
4758{
4859 struct enetc_mdio_priv * mdio_priv = bus -> priv ;
49- struct enetc_hw * hw = mdio_priv -> hw ;
5060 u32 mdio_ctl , mdio_cfg ;
5161 u16 dev_addr ;
5262 int ret ;
@@ -61,39 +71,39 @@ int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value)
6171 mdio_cfg &= ~MDIO_CFG_ENC45 ;
6272 }
6373
64- enetc_mdio_wr (hw , MDIO_CFG , mdio_cfg );
74+ enetc_mdio_wr (mdio_priv , MDIO_CFG , mdio_cfg );
6575
66- ret = enetc_mdio_wait_complete (hw );
76+ ret = enetc_mdio_wait_complete (mdio_priv );
6777 if (ret )
6878 return ret ;
6979
7080 /* set port and dev addr */
7181 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 );
7383
7484 /* set the register address */
7585 if (regnum & MII_ADDR_C45 ) {
76- enetc_mdio_wr (hw , MDIO_ADDR , regnum & 0xffff );
86+ enetc_mdio_wr (mdio_priv , MDIO_ADDR , regnum & 0xffff );
7787
78- ret = enetc_mdio_wait_complete (hw );
88+ ret = enetc_mdio_wait_complete (mdio_priv );
7989 if (ret )
8090 return ret ;
8191 }
8292
8393 /* write the value */
84- enetc_mdio_wr (hw , MDIO_DATA , MDIO_DATA (value ));
94+ enetc_mdio_wr (mdio_priv , MDIO_DATA , MDIO_DATA (value ));
8595
86- ret = enetc_mdio_wait_complete (hw );
96+ ret = enetc_mdio_wait_complete (mdio_priv );
8797 if (ret )
8898 return ret ;
8999
90100 return 0 ;
91101}
102+ EXPORT_SYMBOL_GPL (enetc_mdio_write );
92103
93104int enetc_mdio_read (struct mii_bus * bus , int phy_id , int regnum )
94105{
95106 struct enetc_mdio_priv * mdio_priv = bus -> priv ;
96- struct enetc_hw * hw = mdio_priv -> hw ;
97107 u32 mdio_ctl , mdio_cfg ;
98108 u16 dev_addr , value ;
99109 int ret ;
@@ -107,86 +117,56 @@ int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
107117 mdio_cfg &= ~MDIO_CFG_ENC45 ;
108118 }
109119
110- enetc_mdio_wr (hw , MDIO_CFG , mdio_cfg );
120+ enetc_mdio_wr (mdio_priv , MDIO_CFG , mdio_cfg );
111121
112- ret = enetc_mdio_wait_complete (hw );
122+ ret = enetc_mdio_wait_complete (mdio_priv );
113123 if (ret )
114124 return ret ;
115125
116126 /* set port and device addr */
117127 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 );
119129
120130 /* set the register address */
121131 if (regnum & MII_ADDR_C45 ) {
122- enetc_mdio_wr (hw , MDIO_ADDR , regnum & 0xffff );
132+ enetc_mdio_wr (mdio_priv , MDIO_ADDR , regnum & 0xffff );
123133
124- ret = enetc_mdio_wait_complete (hw );
134+ ret = enetc_mdio_wait_complete (mdio_priv );
125135 if (ret )
126136 return ret ;
127137 }
128138
129139 /* 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 );
131141
132- ret = enetc_mdio_wait_complete (hw );
142+ ret = enetc_mdio_wait_complete (mdio_priv );
133143 if (ret )
134144 return ret ;
135145
136146 /* 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 ) {
138148 dev_dbg (& bus -> dev ,
139149 "Error while reading PHY%d reg at %d.%hhu\n" ,
140150 phy_id , dev_addr , regnum );
141151 return 0xffff ;
142152 }
143153
144- value = enetc_mdio_rd (hw , MDIO_DATA ) & 0xffff ;
154+ value = enetc_mdio_rd (mdio_priv , MDIO_DATA ) & 0xffff ;
145155
146156 return value ;
147157}
158+ EXPORT_SYMBOL_GPL (enetc_mdio_read );
148159
149- int enetc_mdio_probe (struct enetc_pf * pf )
160+ struct enetc_hw * enetc_hw_alloc (struct device * dev , void __iomem * port_regs )
150161{
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 ;
181163
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 );
184167
185- return 0 ;
186- }
168+ hw -> port = port_regs ;
187169
188- void enetc_mdio_remove (struct enetc_pf * pf )
189- {
190- if (pf -> mdio )
191- mdiobus_unregister (pf -> mdio );
170+ return hw ;
192171}
172+ EXPORT_SYMBOL_GPL (enetc_hw_alloc );
0 commit comments