14
14
#include <linux/of_mdio.h>
15
15
#include <linux/phy.h>
16
16
#include <linux/platform_device.h>
17
+ #include <linux/regmap.h>
17
18
18
19
#define MSCC_MIIM_REG_STATUS 0x0
19
20
#define MSCC_MIIM_STATUS_STAT_PENDING BIT(2)
35
36
#define MSCC_PHY_REG_PHY_STATUS 0x4
36
37
37
38
struct mscc_miim_dev {
38
- void __iomem * regs ;
39
- void __iomem * phy_regs ;
39
+ struct regmap * regs ;
40
+ struct regmap * phy_regs ;
40
41
};
41
42
42
43
/* When high resolution timers aren't built-in: we can't use usleep_range() as
43
44
* we would sleep way too long. Use udelay() instead.
44
45
*/
45
- #define mscc_readl_poll_timeout ( addr , val , cond , delay_us , timeout_us ) \
46
- ({ \
47
- if (!IS_ENABLED(CONFIG_HIGH_RES_TIMERS)) \
48
- readl_poll_timeout_atomic( addr, val, cond, delay_us, \
49
- timeout_us); \
50
- readl_poll_timeout( addr, val, cond, delay_us, timeout_us); \
46
+ #define mscc_readx_poll_timeout ( op , addr , val , cond , delay_us , timeout_us )\
47
+ ({ \
48
+ if (!IS_ENABLED(CONFIG_HIGH_RES_TIMERS)) \
49
+ readx_poll_timeout_atomic(op, addr, val, cond, delay_us, \
50
+ timeout_us); \
51
+ readx_poll_timeout(op, addr, val, cond, delay_us, timeout_us); \
51
52
})
52
53
53
- static int mscc_miim_wait_ready (struct mii_bus * bus )
54
+ static int mscc_miim_status (struct mii_bus * bus )
54
55
{
55
56
struct mscc_miim_dev * miim = bus -> priv ;
57
+ int val , ret ;
58
+
59
+ ret = regmap_read (miim -> regs , MSCC_MIIM_REG_STATUS , & val );
60
+ if (ret < 0 ) {
61
+ WARN_ONCE (1 , "mscc miim status read error %d\n" , ret );
62
+ return ret ;
63
+ }
64
+
65
+ return val ;
66
+ }
67
+
68
+ static int mscc_miim_wait_ready (struct mii_bus * bus )
69
+ {
56
70
u32 val ;
57
71
58
- return mscc_readl_poll_timeout ( miim -> regs + MSCC_MIIM_REG_STATUS , val ,
72
+ return mscc_readx_poll_timeout ( mscc_miim_status , bus , val ,
59
73
!(val & MSCC_MIIM_STATUS_STAT_BUSY ), 50 ,
60
74
10000 );
61
75
}
62
76
63
77
static int mscc_miim_wait_pending (struct mii_bus * bus )
64
78
{
65
- struct mscc_miim_dev * miim = bus -> priv ;
66
79
u32 val ;
67
80
68
- return mscc_readl_poll_timeout ( miim -> regs + MSCC_MIIM_REG_STATUS , val ,
81
+ return mscc_readx_poll_timeout ( mscc_miim_status , bus , val ,
69
82
!(val & MSCC_MIIM_STATUS_STAT_PENDING ),
70
83
50 , 10000 );
71
84
}
@@ -80,15 +93,27 @@ static int mscc_miim_read(struct mii_bus *bus, int mii_id, int regnum)
80
93
if (ret )
81
94
goto out ;
82
95
83
- writel (MSCC_MIIM_CMD_VLD | (mii_id << MSCC_MIIM_CMD_PHYAD_SHIFT ) |
84
- (regnum << MSCC_MIIM_CMD_REGAD_SHIFT ) | MSCC_MIIM_CMD_OPR_READ ,
85
- miim -> regs + MSCC_MIIM_REG_CMD );
96
+ ret = regmap_write (miim -> regs , MSCC_MIIM_REG_CMD , MSCC_MIIM_CMD_VLD |
97
+ (mii_id << MSCC_MIIM_CMD_PHYAD_SHIFT ) |
98
+ (regnum << MSCC_MIIM_CMD_REGAD_SHIFT ) |
99
+ MSCC_MIIM_CMD_OPR_READ );
100
+
101
+ if (ret < 0 ) {
102
+ WARN_ONCE (1 , "mscc miim write cmd reg error %d\n" , ret );
103
+ goto out ;
104
+ }
86
105
87
106
ret = mscc_miim_wait_ready (bus );
88
107
if (ret )
89
108
goto out ;
90
109
91
- val = readl (miim -> regs + MSCC_MIIM_REG_DATA );
110
+ ret = regmap_read (miim -> regs , MSCC_MIIM_REG_DATA , & val );
111
+
112
+ if (ret < 0 ) {
113
+ WARN_ONCE (1 , "mscc miim read data reg error %d\n" , ret );
114
+ goto out ;
115
+ }
116
+
92
117
if (val & MSCC_MIIM_DATA_ERROR ) {
93
118
ret = - EIO ;
94
119
goto out ;
@@ -109,64 +134,118 @@ static int mscc_miim_write(struct mii_bus *bus, int mii_id,
109
134
if (ret < 0 )
110
135
goto out ;
111
136
112
- writel ( MSCC_MIIM_CMD_VLD | ( mii_id << MSCC_MIIM_CMD_PHYAD_SHIFT ) |
113
- ( regnum << MSCC_MIIM_CMD_REGAD_SHIFT ) |
114
- ( value << MSCC_MIIM_CMD_WRDATA_SHIFT ) |
115
- MSCC_MIIM_CMD_OPR_WRITE ,
116
- miim -> regs + MSCC_MIIM_REG_CMD );
137
+ ret = regmap_write ( miim -> regs , MSCC_MIIM_REG_CMD , MSCC_MIIM_CMD_VLD |
138
+ ( mii_id << MSCC_MIIM_CMD_PHYAD_SHIFT ) |
139
+ ( regnum << MSCC_MIIM_CMD_REGAD_SHIFT ) |
140
+ ( value << MSCC_MIIM_CMD_WRDATA_SHIFT ) |
141
+ MSCC_MIIM_CMD_OPR_WRITE );
117
142
143
+ if (ret < 0 )
144
+ WARN_ONCE (1 , "mscc miim write error %d\n" , ret );
118
145
out :
119
146
return ret ;
120
147
}
121
148
122
149
static int mscc_miim_reset (struct mii_bus * bus )
123
150
{
124
151
struct mscc_miim_dev * miim = bus -> priv ;
152
+ int ret ;
125
153
126
154
if (miim -> phy_regs ) {
127
- writel (0 , miim -> phy_regs + MSCC_PHY_REG_PHY_CFG );
128
- writel (0x1ff , miim -> phy_regs + MSCC_PHY_REG_PHY_CFG );
155
+ ret = regmap_write (miim -> phy_regs , MSCC_PHY_REG_PHY_CFG , 0 );
156
+ if (ret < 0 ) {
157
+ WARN_ONCE (1 , "mscc reset set error %d\n" , ret );
158
+ return ret ;
159
+ }
160
+
161
+ ret = regmap_write (miim -> phy_regs , MSCC_PHY_REG_PHY_CFG , 0x1ff );
162
+ if (ret < 0 ) {
163
+ WARN_ONCE (1 , "mscc reset clear error %d\n" , ret );
164
+ return ret ;
165
+ }
166
+
129
167
mdelay (500 );
130
168
}
131
169
132
170
return 0 ;
133
171
}
134
172
135
- static int mscc_miim_probe (struct platform_device * pdev )
173
+ static const struct regmap_config mscc_miim_regmap_config = {
174
+ .reg_bits = 32 ,
175
+ .val_bits = 32 ,
176
+ .reg_stride = 4 ,
177
+ };
178
+
179
+ static int mscc_miim_setup (struct device * dev , struct mii_bus * * pbus ,
180
+ struct regmap * mii_regmap )
136
181
{
137
- struct mscc_miim_dev * dev ;
138
- struct resource * res ;
182
+ struct mscc_miim_dev * miim ;
139
183
struct mii_bus * bus ;
140
- int ret ;
141
184
142
- bus = devm_mdiobus_alloc_size (& pdev -> dev , sizeof (* dev ));
185
+ bus = devm_mdiobus_alloc_size (dev , sizeof (* miim ));
143
186
if (!bus )
144
187
return - ENOMEM ;
145
188
146
189
bus -> name = "mscc_miim" ;
147
190
bus -> read = mscc_miim_read ;
148
191
bus -> write = mscc_miim_write ;
149
192
bus -> reset = mscc_miim_reset ;
150
- snprintf (bus -> id , MII_BUS_ID_SIZE , "%s-mii" , dev_name (& pdev -> dev ));
151
- bus -> parent = & pdev -> dev ;
193
+ snprintf (bus -> id , MII_BUS_ID_SIZE , "%s-mii" , dev_name (dev ));
194
+ bus -> parent = dev ;
195
+
196
+ miim = bus -> priv ;
197
+
198
+ * pbus = bus ;
199
+
200
+ miim -> regs = mii_regmap ;
201
+
202
+ return 0 ;
203
+ }
204
+
205
+ static int mscc_miim_probe (struct platform_device * pdev )
206
+ {
207
+ struct regmap * mii_regmap , * phy_regmap ;
208
+ void __iomem * regs , * phy_regs ;
209
+ struct mscc_miim_dev * miim ;
210
+ struct mii_bus * bus ;
211
+ int ret ;
152
212
153
- dev = bus -> priv ;
154
- dev -> regs = devm_platform_get_and_ioremap_resource (pdev , 0 , NULL );
155
- if (IS_ERR (dev -> regs )) {
213
+ regs = devm_platform_get_and_ioremap_resource (pdev , 0 , NULL );
214
+ if (IS_ERR (regs )) {
156
215
dev_err (& pdev -> dev , "Unable to map MIIM registers\n" );
157
- return PTR_ERR (dev -> regs );
216
+ return PTR_ERR (regs );
158
217
}
159
218
160
- /* This resource is optional */
161
- res = platform_get_resource (pdev , IORESOURCE_MEM , 1 );
162
- if (res ) {
163
- dev -> phy_regs = devm_ioremap_resource (& pdev -> dev , res );
164
- if (IS_ERR (dev -> phy_regs )) {
165
- dev_err (& pdev -> dev , "Unable to map internal phy registers\n" );
166
- return PTR_ERR (dev -> phy_regs );
167
- }
219
+ mii_regmap = devm_regmap_init_mmio (& pdev -> dev , regs ,
220
+ & mscc_miim_regmap_config );
221
+
222
+ if (IS_ERR (mii_regmap )) {
223
+ dev_err (& pdev -> dev , "Unable to create MIIM regmap\n" );
224
+ return PTR_ERR (mii_regmap );
168
225
}
169
226
227
+ phy_regs = devm_platform_ioremap_resource (pdev , 1 );
228
+ if (IS_ERR (phy_regs )) {
229
+ dev_err (& pdev -> dev , "Unable to map internal phy registers\n" );
230
+ return PTR_ERR (phy_regs );
231
+ }
232
+
233
+ phy_regmap = devm_regmap_init_mmio (& pdev -> dev , phy_regs ,
234
+ & mscc_miim_regmap_config );
235
+ if (IS_ERR (phy_regmap )) {
236
+ dev_err (& pdev -> dev , "Unable to create phy register regmap\n" );
237
+ return PTR_ERR (phy_regmap );
238
+ }
239
+
240
+ ret = mscc_miim_setup (& pdev -> dev , & bus , mii_regmap );
241
+ if (ret < 0 ) {
242
+ dev_err (& pdev -> dev , "Unable to setup the MDIO bus\n" );
243
+ return ret ;
244
+ }
245
+
246
+ miim = bus -> priv ;
247
+ miim -> phy_regs = phy_regmap ;
248
+
170
249
ret = of_mdiobus_register (bus , pdev -> dev .of_node );
171
250
if (ret < 0 ) {
172
251
dev_err (& pdev -> dev , "Cannot register MDIO bus (%d)\n" , ret );
0 commit comments