23
23
24
24
#include "mlxbf_gige.h"
25
25
#include "mlxbf_gige_regs.h"
26
+ #include "mlxbf_gige_mdio_bf2.h"
27
+ #include "mlxbf_gige_mdio_bf3.h"
26
28
27
- #define MLXBF_GIGE_MDIO_GW_OFFSET 0x0
28
- #define MLXBF_GIGE_MDIO_CFG_OFFSET 0x4
29
+ static struct mlxbf_gige_mdio_gw mlxbf_gige_mdio_gw_t [] = {
30
+ [MLXBF_GIGE_VERSION_BF2 ] = {
31
+ .gw_address = MLXBF2_GIGE_MDIO_GW_OFFSET ,
32
+ .read_data_address = MLXBF2_GIGE_MDIO_GW_OFFSET ,
33
+ .busy = {
34
+ .mask = MLXBF2_GIGE_MDIO_GW_BUSY_MASK ,
35
+ .shift = MLXBF2_GIGE_MDIO_GW_BUSY_SHIFT ,
36
+ },
37
+ .read_data = {
38
+ .mask = MLXBF2_GIGE_MDIO_GW_AD_MASK ,
39
+ .shift = MLXBF2_GIGE_MDIO_GW_AD_SHIFT ,
40
+ },
41
+ .write_data = {
42
+ .mask = MLXBF2_GIGE_MDIO_GW_AD_MASK ,
43
+ .shift = MLXBF2_GIGE_MDIO_GW_AD_SHIFT ,
44
+ },
45
+ .devad = {
46
+ .mask = MLXBF2_GIGE_MDIO_GW_DEVAD_MASK ,
47
+ .shift = MLXBF2_GIGE_MDIO_GW_DEVAD_SHIFT ,
48
+ },
49
+ .partad = {
50
+ .mask = MLXBF2_GIGE_MDIO_GW_PARTAD_MASK ,
51
+ .shift = MLXBF2_GIGE_MDIO_GW_PARTAD_SHIFT ,
52
+ },
53
+ .opcode = {
54
+ .mask = MLXBF2_GIGE_MDIO_GW_OPCODE_MASK ,
55
+ .shift = MLXBF2_GIGE_MDIO_GW_OPCODE_SHIFT ,
56
+ },
57
+ .st1 = {
58
+ .mask = MLXBF2_GIGE_MDIO_GW_ST1_MASK ,
59
+ .shift = MLXBF2_GIGE_MDIO_GW_ST1_SHIFT ,
60
+ },
61
+ },
62
+ [MLXBF_GIGE_VERSION_BF3 ] = {
63
+ .gw_address = MLXBF3_GIGE_MDIO_GW_OFFSET ,
64
+ .read_data_address = MLXBF3_GIGE_MDIO_DATA_READ ,
65
+ .busy = {
66
+ .mask = MLXBF3_GIGE_MDIO_GW_BUSY_MASK ,
67
+ .shift = MLXBF3_GIGE_MDIO_GW_BUSY_SHIFT ,
68
+ },
69
+ .read_data = {
70
+ .mask = MLXBF3_GIGE_MDIO_GW_DATA_READ_MASK ,
71
+ .shift = MLXBF3_GIGE_MDIO_GW_DATA_READ_SHIFT ,
72
+ },
73
+ .write_data = {
74
+ .mask = MLXBF3_GIGE_MDIO_GW_DATA_MASK ,
75
+ .shift = MLXBF3_GIGE_MDIO_GW_DATA_SHIFT ,
76
+ },
77
+ .devad = {
78
+ .mask = MLXBF3_GIGE_MDIO_GW_DEVAD_MASK ,
79
+ .shift = MLXBF3_GIGE_MDIO_GW_DEVAD_SHIFT ,
80
+ },
81
+ .partad = {
82
+ .mask = MLXBF3_GIGE_MDIO_GW_PARTAD_MASK ,
83
+ .shift = MLXBF3_GIGE_MDIO_GW_PARTAD_SHIFT ,
84
+ },
85
+ .opcode = {
86
+ .mask = MLXBF3_GIGE_MDIO_GW_OPCODE_MASK ,
87
+ .shift = MLXBF3_GIGE_MDIO_GW_OPCODE_SHIFT ,
88
+ },
89
+ .st1 = {
90
+ .mask = MLXBF3_GIGE_MDIO_GW_ST1_MASK ,
91
+ .shift = MLXBF3_GIGE_MDIO_GW_ST1_SHIFT ,
92
+ },
93
+ },
94
+ };
29
95
30
96
#define MLXBF_GIGE_MDIO_FREQ_REFERENCE 156250000ULL
31
97
#define MLXBF_GIGE_MDIO_COREPLL_CONST 16384ULL
47
113
/* Busy bit is set by software and cleared by hardware */
48
114
#define MLXBF_GIGE_MDIO_SET_BUSY 0x1
49
115
50
- /* MDIO GW register bits */
51
- #define MLXBF_GIGE_MDIO_GW_AD_MASK GENMASK(15, 0)
52
- #define MLXBF_GIGE_MDIO_GW_DEVAD_MASK GENMASK(20, 16)
53
- #define MLXBF_GIGE_MDIO_GW_PARTAD_MASK GENMASK(25, 21)
54
- #define MLXBF_GIGE_MDIO_GW_OPCODE_MASK GENMASK(27, 26)
55
- #define MLXBF_GIGE_MDIO_GW_ST1_MASK GENMASK(28, 28)
56
- #define MLXBF_GIGE_MDIO_GW_BUSY_MASK GENMASK(30, 30)
57
-
58
- /* MDIO config register bits */
59
- #define MLXBF_GIGE_MDIO_CFG_MDIO_MODE_MASK GENMASK(1, 0)
60
- #define MLXBF_GIGE_MDIO_CFG_MDIO3_3_MASK GENMASK(2, 2)
61
- #define MLXBF_GIGE_MDIO_CFG_MDIO_FULL_DRIVE_MASK GENMASK(4, 4)
62
- #define MLXBF_GIGE_MDIO_CFG_MDC_PERIOD_MASK GENMASK(15, 8)
63
- #define MLXBF_GIGE_MDIO_CFG_MDIO_IN_SAMP_MASK GENMASK(23, 16)
64
- #define MLXBF_GIGE_MDIO_CFG_MDIO_OUT_SAMP_MASK GENMASK(31, 24)
65
-
66
- #define MLXBF_GIGE_MDIO_CFG_VAL (FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO_MODE_MASK, 1) | \
67
- FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO3_3_MASK, 1) | \
68
- FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO_FULL_DRIVE_MASK, 1) | \
69
- FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO_IN_SAMP_MASK, 6) | \
70
- FIELD_PREP(MLXBF_GIGE_MDIO_CFG_MDIO_OUT_SAMP_MASK, 13))
71
-
72
116
#define MLXBF_GIGE_BF2_COREPLL_ADDR 0x02800c30
73
117
#define MLXBF_GIGE_BF2_COREPLL_SIZE 0x0000000c
118
+ #define MLXBF_GIGE_BF3_COREPLL_ADDR 0x13409824
119
+ #define MLXBF_GIGE_BF3_COREPLL_SIZE 0x00000010
74
120
75
121
static struct resource corepll_params [] = {
76
122
[MLXBF_GIGE_VERSION_BF2 ] = {
77
123
.start = MLXBF_GIGE_BF2_COREPLL_ADDR ,
78
124
.end = MLXBF_GIGE_BF2_COREPLL_ADDR + MLXBF_GIGE_BF2_COREPLL_SIZE - 1 ,
79
125
.name = "COREPLL_RES"
80
126
},
127
+ [MLXBF_GIGE_VERSION_BF3 ] = {
128
+ .start = MLXBF_GIGE_BF3_COREPLL_ADDR ,
129
+ .end = MLXBF_GIGE_BF3_COREPLL_ADDR + MLXBF_GIGE_BF3_COREPLL_SIZE - 1 ,
130
+ .name = "COREPLL_RES"
131
+ }
81
132
};
82
133
83
134
/* Returns core clock i1clk in Hz */
@@ -134,19 +185,23 @@ static u8 mdio_period_map(struct mlxbf_gige *priv)
134
185
return mdio_period ;
135
186
}
136
187
137
- static u32 mlxbf_gige_mdio_create_cmd (u16 data , int phy_add ,
188
+ static u32 mlxbf_gige_mdio_create_cmd (struct mlxbf_gige_mdio_gw * mdio_gw , u16 data , int phy_add ,
138
189
int phy_reg , u32 opcode )
139
190
{
140
191
u32 gw_reg = 0 ;
141
192
142
- gw_reg |= FIELD_PREP (MLXBF_GIGE_MDIO_GW_AD_MASK , data );
143
- gw_reg |= FIELD_PREP (MLXBF_GIGE_MDIO_GW_DEVAD_MASK , phy_reg );
144
- gw_reg |= FIELD_PREP (MLXBF_GIGE_MDIO_GW_PARTAD_MASK , phy_add );
145
- gw_reg |= FIELD_PREP (MLXBF_GIGE_MDIO_GW_OPCODE_MASK , opcode );
146
- gw_reg |= FIELD_PREP (MLXBF_GIGE_MDIO_GW_ST1_MASK ,
147
- MLXBF_GIGE_MDIO_CL22_ST1 );
148
- gw_reg |= FIELD_PREP (MLXBF_GIGE_MDIO_GW_BUSY_MASK ,
149
- MLXBF_GIGE_MDIO_SET_BUSY );
193
+ gw_reg |= ((data << mdio_gw -> write_data .shift ) &
194
+ mdio_gw -> write_data .mask );
195
+ gw_reg |= ((phy_reg << mdio_gw -> devad .shift ) &
196
+ mdio_gw -> devad .mask );
197
+ gw_reg |= ((phy_add << mdio_gw -> partad .shift ) &
198
+ mdio_gw -> partad .mask );
199
+ gw_reg |= ((opcode << mdio_gw -> opcode .shift ) &
200
+ mdio_gw -> opcode .mask );
201
+ gw_reg |= ((MLXBF_GIGE_MDIO_CL22_ST1 << mdio_gw -> st1 .shift ) &
202
+ mdio_gw -> st1 .mask );
203
+ gw_reg |= ((MLXBF_GIGE_MDIO_SET_BUSY << mdio_gw -> busy .shift ) &
204
+ mdio_gw -> busy .mask );
150
205
151
206
return gw_reg ;
152
207
}
@@ -162,25 +217,26 @@ static int mlxbf_gige_mdio_read(struct mii_bus *bus, int phy_add, int phy_reg)
162
217
return - EOPNOTSUPP ;
163
218
164
219
/* Send mdio read request */
165
- cmd = mlxbf_gige_mdio_create_cmd (0 , phy_add , phy_reg , MLXBF_GIGE_MDIO_CL22_READ );
220
+ cmd = mlxbf_gige_mdio_create_cmd (priv -> mdio_gw , 0 , phy_add , phy_reg ,
221
+ MLXBF_GIGE_MDIO_CL22_READ );
166
222
167
- writel (cmd , priv -> mdio_io + MLXBF_GIGE_MDIO_GW_OFFSET );
223
+ writel (cmd , priv -> mdio_io + priv -> mdio_gw -> gw_address );
168
224
169
- ret = readl_poll_timeout_atomic (priv -> mdio_io + MLXBF_GIGE_MDIO_GW_OFFSET ,
170
- val , !(val & MLXBF_GIGE_MDIO_GW_BUSY_MASK ),
225
+ ret = readl_poll_timeout_atomic (priv -> mdio_io + priv -> mdio_gw -> gw_address ,
226
+ val , !(val & priv -> mdio_gw -> busy . mask ),
171
227
5 , 1000000 );
172
228
173
229
if (ret ) {
174
- writel (0 , priv -> mdio_io + MLXBF_GIGE_MDIO_GW_OFFSET );
230
+ writel (0 , priv -> mdio_io + priv -> mdio_gw -> gw_address );
175
231
return ret ;
176
232
}
177
233
178
- ret = readl (priv -> mdio_io + MLXBF_GIGE_MDIO_GW_OFFSET );
234
+ ret = readl (priv -> mdio_io + priv -> mdio_gw -> read_data_address );
179
235
/* Only return ad bits of the gw register */
180
- ret &= MLXBF_GIGE_MDIO_GW_AD_MASK ;
236
+ ret &= priv -> mdio_gw -> read_data . mask ;
181
237
182
238
/* The MDIO lock is set on read. To release it, clear gw register */
183
- writel (0 , priv -> mdio_io + MLXBF_GIGE_MDIO_GW_OFFSET );
239
+ writel (0 , priv -> mdio_io + priv -> mdio_gw -> gw_address );
184
240
185
241
return ret ;
186
242
}
@@ -197,17 +253,17 @@ static int mlxbf_gige_mdio_write(struct mii_bus *bus, int phy_add,
197
253
return - EOPNOTSUPP ;
198
254
199
255
/* Send mdio write request */
200
- cmd = mlxbf_gige_mdio_create_cmd (val , phy_add , phy_reg ,
256
+ cmd = mlxbf_gige_mdio_create_cmd (priv -> mdio_gw , val , phy_add , phy_reg ,
201
257
MLXBF_GIGE_MDIO_CL22_WRITE );
202
- writel (cmd , priv -> mdio_io + MLXBF_GIGE_MDIO_GW_OFFSET );
258
+ writel (cmd , priv -> mdio_io + priv -> mdio_gw -> gw_address );
203
259
204
260
/* If the poll timed out, drop the request */
205
- ret = readl_poll_timeout_atomic (priv -> mdio_io + MLXBF_GIGE_MDIO_GW_OFFSET ,
206
- temp , !(temp & MLXBF_GIGE_MDIO_GW_BUSY_MASK ),
261
+ ret = readl_poll_timeout_atomic (priv -> mdio_io + priv -> mdio_gw -> gw_address ,
262
+ temp , !(temp & priv -> mdio_gw -> busy . mask ),
207
263
5 , 1000000 );
208
264
209
265
/* The MDIO lock is set on read. To release it, clear gw register */
210
- writel (0 , priv -> mdio_io + MLXBF_GIGE_MDIO_GW_OFFSET );
266
+ writel (0 , priv -> mdio_io + priv -> mdio_gw -> gw_address );
211
267
212
268
return ret ;
213
269
}
@@ -219,9 +275,20 @@ static void mlxbf_gige_mdio_cfg(struct mlxbf_gige *priv)
219
275
220
276
mdio_period = mdio_period_map (priv );
221
277
222
- val = MLXBF_GIGE_MDIO_CFG_VAL ;
223
- val |= FIELD_PREP (MLXBF_GIGE_MDIO_CFG_MDC_PERIOD_MASK , mdio_period );
224
- writel (val , priv -> mdio_io + MLXBF_GIGE_MDIO_CFG_OFFSET );
278
+ if (priv -> hw_version == MLXBF_GIGE_VERSION_BF2 ) {
279
+ val = MLXBF2_GIGE_MDIO_CFG_VAL ;
280
+ val |= FIELD_PREP (MLXBF2_GIGE_MDIO_CFG_MDC_PERIOD_MASK , mdio_period );
281
+ writel (val , priv -> mdio_io + MLXBF2_GIGE_MDIO_CFG_OFFSET );
282
+ } else {
283
+ val = FIELD_PREP (MLXBF3_GIGE_MDIO_CFG_MDIO_MODE_MASK , 1 ) |
284
+ FIELD_PREP (MLXBF3_GIGE_MDIO_CFG_MDIO_FULL_DRIVE_MASK , 1 );
285
+ writel (val , priv -> mdio_io + MLXBF3_GIGE_MDIO_CFG_REG0 );
286
+ val = FIELD_PREP (MLXBF3_GIGE_MDIO_CFG_MDC_PERIOD_MASK , mdio_period );
287
+ writel (val , priv -> mdio_io + MLXBF3_GIGE_MDIO_CFG_REG1 );
288
+ val = FIELD_PREP (MLXBF3_GIGE_MDIO_CFG_MDIO_IN_SAMP_MASK , 6 ) |
289
+ FIELD_PREP (MLXBF3_GIGE_MDIO_CFG_MDIO_OUT_SAMP_MASK , 13 );
290
+ writel (val , priv -> mdio_io + MLXBF3_GIGE_MDIO_CFG_REG2 );
291
+ }
225
292
}
226
293
227
294
int mlxbf_gige_mdio_probe (struct platform_device * pdev , struct mlxbf_gige * priv )
@@ -230,6 +297,9 @@ int mlxbf_gige_mdio_probe(struct platform_device *pdev, struct mlxbf_gige *priv)
230
297
struct resource * res ;
231
298
int ret ;
232
299
300
+ if (priv -> hw_version > MLXBF_GIGE_VERSION_BF3 )
301
+ return - ENODEV ;
302
+
233
303
priv -> mdio_io = devm_platform_ioremap_resource (pdev , MLXBF_GIGE_RES_MDIO9 );
234
304
if (IS_ERR (priv -> mdio_io ))
235
305
return PTR_ERR (priv -> mdio_io );
@@ -242,13 +312,15 @@ int mlxbf_gige_mdio_probe(struct platform_device *pdev, struct mlxbf_gige *priv)
242
312
/* For backward compatibility with older ACPI tables, also keep
243
313
* CLK resource internal to the driver.
244
314
*/
245
- res = & corepll_params [MLXBF_GIGE_VERSION_BF2 ];
315
+ res = & corepll_params [priv -> hw_version ];
246
316
}
247
317
248
318
priv -> clk_io = devm_ioremap (dev , res -> start , resource_size (res ));
249
319
if (!priv -> clk_io )
250
320
return - ENOMEM ;
251
321
322
+ priv -> mdio_gw = & mlxbf_gige_mdio_gw_t [priv -> hw_version ];
323
+
252
324
mlxbf_gige_mdio_cfg (priv );
253
325
254
326
priv -> mdiobus = devm_mdiobus_alloc (dev );
0 commit comments