Skip to content

Commit 3ea491c

Browse files
Lukasz Majewskinashif
authored andcommitted
drivers: ethernet: lan865x: Update initial setup guidelines (from AN1760)
This patch brings update of the procedure to initially configure the LAN865x devices. It follows setup guidelines from newest AN1760 [*]. The values from "TABLE1" on the [*] must be written to the device in the indicated order with recommended values. This was not the case previously, as first values from in-flash allocated (const) table were written and only afterwards calculated configuration parameters (cfgparams) were updated. With this patch the lan865x_conf[] table is allocated in-RAM, so placeholder values can be updated and it can be written at once at the end of configuration process. Its single entry has been reduced from 8B to only 4B. Moreover, moving it out of flash saves 512B of flash memory. Note: [*] - AN1760 Revision F (DS60001760G - June 2024) Signed-off-by: Lukasz Majewski <[email protected]>
1 parent 04dee00 commit 3ea491c

File tree

3 files changed

+100
-94
lines changed

3 files changed

+100
-94
lines changed

drivers/ethernet/eth_lan865x.c

Lines changed: 87 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -179,65 +179,109 @@ static uint8_t lan865x_read_indirect_reg(const struct device *dev, uint8_t addr,
179179
return (uint8_t) val & mask;
180180
}
181181

182+
/*
183+
* Values in the below table for LAN865x rev. B0 and B1 (with place
184+
* holders for cfgparamX.
185+
*/
186+
static oa_mem_map_t lan865x_conf[] = {
187+
{ .mms = 0x1, .address = 0x00, .value = 0x0000 },
188+
{ .mms = 0x4, .address = 0xD0, .value = 0x3F31 },
189+
{ .mms = 0x4, .address = 0xE0, .value = 0xC000 },
190+
{ .mms = 0x4, .address = 0x84, .value = 0x0000 }, /* cfgparam1 */
191+
{ .mms = 0x4, .address = 0x8A, .value = 0x0000 }, /* cfgparam2 */
192+
{ .mms = 0x4, .address = 0xE9, .value = 0x9E50 },
193+
{ .mms = 0x4, .address = 0xF5, .value = 0x1CF8 },
194+
{ .mms = 0x4, .address = 0xF4, .value = 0xC020 },
195+
{ .mms = 0x4, .address = 0xF8, .value = 0xB900 },
196+
{ .mms = 0x4, .address = 0xF9, .value = 0x4E53 },
197+
{ .mms = 0x4, .address = 0x91, .value = 0x9660 },
198+
{ .mms = 0x4, .address = 0x77, .value = 0x0028 },
199+
{ .mms = 0x4, .address = 0x43, .value = 0x00FF },
200+
{ .mms = 0x4, .address = 0x44, .value = 0xFFFF },
201+
{ .mms = 0x4, .address = 0x45, .value = 0x0000 },
202+
{ .mms = 0x4, .address = 0x53, .value = 0x00FF },
203+
{ .mms = 0x4, .address = 0x54, .value = 0xFFFF },
204+
{ .mms = 0x4, .address = 0x55, .value = 0x0000 },
205+
{ .mms = 0x4, .address = 0x40, .value = 0x0002 },
206+
{ .mms = 0x4, .address = 0x50, .value = 0x0002 },
207+
{ .mms = 0x4, .address = 0xAD, .value = 0x0000 }, /* cfgparam3 */
208+
{ .mms = 0x4, .address = 0xAE, .value = 0x0000 }, /* cfgparam4 */
209+
{ .mms = 0x4, .address = 0xAF, .value = 0x0000 }, /* cfgparam5 */
210+
{ .mms = 0x4, .address = 0xB0, .value = 0x0103 },
211+
{ .mms = 0x4, .address = 0xB1, .value = 0x0910 },
212+
{ .mms = 0x4, .address = 0xB2, .value = 0x1D26 },
213+
{ .mms = 0x4, .address = 0xB3, .value = 0x002A },
214+
{ .mms = 0x4, .address = 0xB4, .value = 0x0103 },
215+
{ .mms = 0x4, .address = 0xB5, .value = 0x070D },
216+
{ .mms = 0x4, .address = 0xB6, .value = 0x1720 },
217+
{ .mms = 0x4, .address = 0xB7, .value = 0x0027 },
218+
{ .mms = 0x4, .address = 0xB8, .value = 0x0509 },
219+
{ .mms = 0x4, .address = 0xB9, .value = 0x0E13 },
220+
{ .mms = 0x4, .address = 0xBA, .value = 0x1C25 },
221+
{ .mms = 0x4, .address = 0xBB, .value = 0x002B },
222+
{ .mms = 0x4, .address = 0x0C, .value = 0x0100 },
223+
{ .mms = 0x4, .address = 0x81, .value = 0x00E0 },
224+
};
225+
226+
/* Based on AN1760 DS60001760G pseudo code */
182227
static int lan865x_init_chip(const struct device *dev, uint8_t silicon_rev)
183228
{
229+
uint16_t cfgparam1, cfgparam2, cfgparam3, cfgparam4, cfgparam5;
230+
uint8_t i, size = ARRAY_SIZE(lan865x_conf);
184231
struct lan865x_data *ctx = dev->data;
232+
int8_t offset1 = 0, offset2 = 0;
185233
uint8_t value1, value2;
186-
int8_t offset1 = 0, offset2 = 0, ret;
187-
uint16_t value3, value4, value5, value6, value7;
188-
uint16_t cfgparam1, cfgparam2, cfgparam3, cfgparam4, cfgparam5;
189-
uint32_t val;
190234

191-
ret = lan865x_read_indirect_reg(dev, 0x05, 0x40);
192-
if (ret == 0) {
193-
LOG_ERR("LAN865x error! Please contact microchip support for replacement.");
194-
return -EIO;
195-
}
235+
/* Enable protected control RW */
236+
oa_tc6_set_protected_ctrl(ctx->tc6, true);
196237

197238
value1 = lan865x_read_indirect_reg(dev, 0x04, 0x1F);
198239
if ((value1 & 0x10) != 0) { /* Convert uint8_t to int8_t */
199-
offset1 = value1 | 0xE0;
200-
if (offset1 < -5) {
201-
LOG_ERR("LAN865x internal error!");
202-
return -EIO;
203-
}
240+
offset1 = (int8_t)((uint8_t)value1 - 0x20);
204241
} else {
205-
offset1 = value1;
242+
offset1 = (int8_t)value1;
206243
}
207244

208245
value2 = lan865x_read_indirect_reg(dev, 0x08, 0x1F);
209246
if ((value2 & 0x10) != 0) { /* Convert uint8_t to int8_t */
210-
offset2 = value2 | 0xE0;
247+
offset2 = (int8_t)((uint8_t)value2 - 0x20);
211248
} else {
212-
offset2 = value2;
213-
}
214-
215-
oa_tc6_reg_read(ctx->tc6, 0x00040084, &val);
216-
value3 = (uint16_t)val;
217-
218-
oa_tc6_reg_read(ctx->tc6, 0x0004008A, &val);
219-
value4 = (uint16_t)val;
220-
221-
oa_tc6_reg_read(ctx->tc6, 0x000400AD, &val);
222-
value5 = (uint16_t)val;
223-
224-
oa_tc6_reg_read(ctx->tc6, 0x000400AE, &val);
225-
value6 = (uint8_t)val;
226-
227-
oa_tc6_reg_read(ctx->tc6, 0x000400AF, &val);
228-
value7 = (uint8_t)val;
249+
offset2 = (int8_t)value2;
250+
}
251+
252+
cfgparam1 = (uint16_t) (((9 + offset1) & 0x3F) << 10) |
253+
(uint16_t) (((14 + offset1) & 0x3F) << 4) | 0x03;
254+
cfgparam2 = (uint16_t) (((40 + offset2) & 0x3F) << 10);
255+
cfgparam3 = (uint16_t) (((5 + offset1) & 0x3F) << 8) |
256+
(uint16_t) ((9 + offset1) & 0x3F);
257+
cfgparam4 = (uint16_t) (((9 + offset1) & 0x3F) << 8) |
258+
(uint16_t) ((14 + offset1) & 0x3F);
259+
cfgparam5 = (uint16_t) (((17 + offset1) & 0x3F) << 8) |
260+
(uint16_t) ((22 + offset1) & 0x3F);
261+
262+
lan865x_update_dev_cfg_array(lan865x_conf, size,
263+
MMS_REG(0x4, 0x84), cfgparam1);
264+
lan865x_update_dev_cfg_array(lan865x_conf, size,
265+
MMS_REG(0x4, 0x8A), cfgparam2);
266+
lan865x_update_dev_cfg_array(lan865x_conf, size,
267+
MMS_REG(0x4, 0xAD), cfgparam3);
268+
lan865x_update_dev_cfg_array(lan865x_conf, size,
269+
MMS_REG(0x4, 0xAE), cfgparam4);
270+
lan865x_update_dev_cfg_array(lan865x_conf, size,
271+
MMS_REG(0x4, 0xAF), cfgparam5);
229272

230-
cfgparam1 = (value3 & 0xF) | (((9 + offset1) << 10) | ((14 + offset1) << 4));
231-
cfgparam2 = (value4 & 0x3FF) | ((40 + offset2) << 10);
232-
cfgparam3 = (value5 & 0xC0C0) | (((5 + offset1) << 8) | (9 + offset1));
233-
cfgparam4 = (value6 & 0xC0C0) | (((9 + offset1) << 8) | (14 + offset1));
234-
cfgparam5 = (value7 & 0xC0C0) | (((17 + offset1) << 8) | (22 + offset1));
273+
if (silicon_rev == 1) {
274+
/* For silicon rev 1 (B0): (bit [3..0] from 0x0A0084 */
275+
lan865x_update_dev_cfg_array(lan865x_conf, size,
276+
MMS_REG(0x4, 0xD0), 0x5F21);
277+
}
235278

236-
oa_tc6_reg_write(ctx->tc6, 0x00040084, (uint32_t) cfgparam1);
237-
oa_tc6_reg_write(ctx->tc6, 0x0004008A, (uint32_t) cfgparam2);
238-
oa_tc6_reg_write(ctx->tc6, 0x000400AD, (uint32_t) cfgparam3);
239-
oa_tc6_reg_write(ctx->tc6, 0x000400AE, (uint32_t) cfgparam4);
240-
oa_tc6_reg_write(ctx->tc6, 0x000400AF, (uint32_t) cfgparam5);
279+
/* Write LAN865x config with correct order */
280+
for (i = 0; i < size; i++) {
281+
oa_tc6_reg_write(ctx->tc6, MMS_REG(lan865x_conf[i].mms,
282+
lan865x_conf[i].address),
283+
(uint32_t)lan865x_conf[i].value);
284+
}
241285

242286
return 0;
243287
}
@@ -312,58 +356,9 @@ static int lan865x_set_specific_multicast_addr(const struct device *dev)
312356

313357
static int lan865x_default_config(const struct device *dev, uint8_t silicon_rev)
314358
{
315-
/* Values in the below table are the same for LAN865x rev. B0 and B1 */
316-
static const oa_mem_map_t lan865x_conf[] = {
317-
{ .address = 0x00010000, .value = 0x00000000 },
318-
{ .address = 0x00040091, .value = 0x00009660 },
319-
{ .address = 0x00040081, .value = 0x00000080 },
320-
{ .address = 0x00010077, .value = 0x00000028 },
321-
{ .address = 0x00040043, .value = 0x000000FF },
322-
{ .address = 0x00040044, .value = 0x0000FFFF },
323-
{ .address = 0x00040045, .value = 0x00000000 },
324-
{ .address = 0x00040053, .value = 0x000000FF },
325-
{ .address = 0x00040054, .value = 0x0000FFFF },
326-
{ .address = 0x00040055, .value = 0x00000000 },
327-
{ .address = 0x00040040, .value = 0x00000002 },
328-
{ .address = 0x00040050, .value = 0x00000002 },
329-
{ .address = 0x000400E9, .value = 0x00009E50 },
330-
{ .address = 0x000400F5, .value = 0x00001CF8 },
331-
{ .address = 0x000400F4, .value = 0x0000C020 },
332-
{ .address = 0x000400F8, .value = 0x00009B00 },
333-
{ .address = 0x000400F9, .value = 0x00004E53 },
334-
{ .address = 0x000400B0, .value = 0x00000103 },
335-
{ .address = 0x000400B1, .value = 0x00000910 },
336-
{ .address = 0x000400B2, .value = 0x00001D26 },
337-
{ .address = 0x000400B3, .value = 0x0000002A },
338-
{ .address = 0x000400B4, .value = 0x00000103 },
339-
{ .address = 0x000400B5, .value = 0x0000070D },
340-
{ .address = 0x000400B6, .value = 0x00001720 },
341-
{ .address = 0x000400B7, .value = 0x00000027 },
342-
{ .address = 0x000400B8, .value = 0x00000509 },
343-
{ .address = 0x000400B9, .value = 0x00000E13 },
344-
{ .address = 0x000400BA, .value = 0x00001C25 },
345-
{ .address = 0x000400BB, .value = 0x0000002B },
346-
{ .address = 0x0000000C, .value = 0x00000100 },
347-
{ .address = 0x00040081, .value = 0x000000E0 },
348-
};
349359
const struct lan865x_config *cfg = dev->config;
350-
uint8_t i, size = ARRAY_SIZE(lan865x_conf);
351-
struct lan865x_data *ctx = dev->data;
352360
int ret;
353361

354-
/* Enable protected control RW */
355-
oa_tc6_set_protected_ctrl(ctx->tc6, true);
356-
357-
for (i = 0; i < size; i++) {
358-
oa_tc6_reg_write(ctx->tc6, lan865x_conf[i].address,
359-
lan865x_conf[i].value);
360-
}
361-
362-
if (silicon_rev == 1) {
363-
/* For silicon rev 1 (B0): (bit [3..0] from 0x0A0084 */
364-
oa_tc6_reg_write(ctx->tc6, 0x000400D0, 0x5F21);
365-
}
366-
367362
lan865x_write_macaddress(dev);
368363
lan865x_set_specific_multicast_addr(dev);
369364

drivers/ethernet/eth_lan865x_priv.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,14 @@ struct lan865x_data {
8181
k_tid_t tid_int;
8282
};
8383

84+
static inline void lan865x_update_dev_cfg_array(oa_mem_map_t *cfg, uint8_t size,
85+
uint32_t addr, uint16_t val)
86+
{
87+
for (uint8_t i = 0; i < size; i++) {
88+
if (cfg[i].address == addr) {
89+
cfg[i].value = val;
90+
}
91+
}
92+
}
93+
8494
#endif /* ETH_LAN865X_PRIV_H__ */

drivers/ethernet/oa_tc6.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,9 @@ struct oa_tc6 {
113113
};
114114

115115
typedef struct {
116-
uint32_t address;
117-
uint32_t value;
116+
uint8_t mms;
117+
uint8_t address;
118+
uint16_t value;
118119
} oa_mem_map_t;
119120

120121
/**

0 commit comments

Comments
 (0)