blob: 48f044c647210fb644763f76d0a356f126c474d7 [file] [log] [blame]
Vladimir Olteanf24b6662021-09-29 18:04:41 +03001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright 2016-2018 NXP
4 * Copyright 2018, Sensor-Technik Wiedemann GmbH
5 * Copyright 2018-2019, Vladimir Oltean <olteanv@gmail.com>
6 * Copyright 2020-2021 NXP
7 *
8 * Ported from Linux (drivers/net/dsa/sja1105/).
9 */
10
11#include <common.h>
12#include <dm/device_compat.h>
13#include <linux/bitops.h>
14#include <linux/bitrev.h>
15#include <linux/errno.h>
16#include <linux/delay.h>
17#include <linux/if_ether.h>
18#include <linux/if_vlan.h>
19#include <linux/types.h>
20#include <net/dsa.h>
21#include <stdlib.h>
22#include <spi.h>
23#include <miiphy.h>
24#include <dm/of_extra.h>
25
26enum packing_op {
27 PACK,
28 UNPACK,
29};
30
31#define ETHER_CRC32_POLY 0x04C11DB7
32#define ETH_P_SJA1105 0xdadb
33#define SJA1105_NUM_PORTS 5
34#define SJA1110_NUM_PORTS 11
35#define SJA1105_MAX_NUM_PORTS SJA1110_NUM_PORTS
36#define SJA1105_NUM_TC 8
37#define SJA1105ET_FDB_BIN_SIZE 4
38#define SJA1105_SIZE_CGU_CMD 4
39#define SJA1105_SIZE_RESET_CMD 4
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +030040#define SJA1105_SIZE_MDIO_CMD 4
Vladimir Olteanf24b6662021-09-29 18:04:41 +030041#define SJA1105_SIZE_SPI_MSG_HEADER 4
42#define SJA1105_SIZE_SPI_MSG_MAXLEN (64 * 4)
43#define SJA1105_SIZE_DEVICE_ID 4
44#define SJA1105_SIZE_TABLE_HEADER 12
45#define SJA1105_SIZE_L2_POLICING_ENTRY 8
46#define SJA1105_SIZE_VLAN_LOOKUP_ENTRY 8
47#define SJA1110_SIZE_VLAN_LOOKUP_ENTRY 12
48#define SJA1105_SIZE_L2_FORWARDING_ENTRY 8
49#define SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY 12
50#define SJA1105_SIZE_XMII_PARAMS_ENTRY 4
51#define SJA1110_SIZE_XMII_PARAMS_ENTRY 8
52#define SJA1105ET_SIZE_MAC_CONFIG_ENTRY 28
53#define SJA1105ET_SIZE_GENERAL_PARAMS_ENTRY 40
54#define SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY 32
55#define SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY 44
56#define SJA1110_SIZE_GENERAL_PARAMS_ENTRY 56
57
58#define SJA1105_MAX_L2_LOOKUP_COUNT 1024
59#define SJA1105_MAX_L2_POLICING_COUNT 45
60#define SJA1110_MAX_L2_POLICING_COUNT 110
61#define SJA1105_MAX_VLAN_LOOKUP_COUNT 4096
62#define SJA1105_MAX_L2_FORWARDING_COUNT 13
63#define SJA1110_MAX_L2_FORWARDING_COUNT 19
64#define SJA1105_MAX_MAC_CONFIG_COUNT 5
65#define SJA1110_MAX_MAC_CONFIG_COUNT 11
66#define SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT 1
67#define SJA1105_MAX_GENERAL_PARAMS_COUNT 1
68#define SJA1105_MAX_XMII_PARAMS_COUNT 1
69
70#define SJA1105_MAX_FRAME_MEMORY 929
71
72#define SJA1105E_DEVICE_ID 0x9C00000Cull
73#define SJA1105T_DEVICE_ID 0x9E00030Eull
74#define SJA1105PR_DEVICE_ID 0xAF00030Eull
75#define SJA1105QS_DEVICE_ID 0xAE00030Eull
76#define SJA1110_DEVICE_ID 0xB700030Full
77
78#define SJA1105ET_PART_NO 0x9A83
79#define SJA1105P_PART_NO 0x9A84
80#define SJA1105Q_PART_NO 0x9A85
81#define SJA1105R_PART_NO 0x9A86
82#define SJA1105S_PART_NO 0x9A87
83#define SJA1110A_PART_NO 0x1110
84#define SJA1110B_PART_NO 0x1111
85#define SJA1110C_PART_NO 0x1112
86#define SJA1110D_PART_NO 0x1113
87
88#define SJA1110_ACU 0x1c4400
89#define SJA1110_RGU 0x1c6000
90#define SJA1110_CGU 0x1c6400
91
92#define SJA1110_SPI_ADDR(x) ((x) / 4)
93#define SJA1110_ACU_ADDR(x) (SJA1110_ACU + SJA1110_SPI_ADDR(x))
94#define SJA1110_CGU_ADDR(x) (SJA1110_CGU + SJA1110_SPI_ADDR(x))
95#define SJA1110_RGU_ADDR(x) (SJA1110_RGU + SJA1110_SPI_ADDR(x))
96
97#define SJA1105_RSV_ADDR 0xffffffffffffffffull
98
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +030099#define SJA1110_PCS_BANK_REG SJA1110_SPI_ADDR(0x3fc)
100
Vladimir Olteanf24b6662021-09-29 18:04:41 +0300101#define DSA_8021Q_DIR_TX BIT(11)
102#define DSA_8021Q_PORT_SHIFT 0
103#define DSA_8021Q_PORT_MASK GENMASK(3, 0)
104#define DSA_8021Q_PORT(x) (((x) << DSA_8021Q_PORT_SHIFT) & \
105 DSA_8021Q_PORT_MASK)
106
107#define SJA1105_RATE_MBPS(speed) (((speed) * 64000) / 1000)
108
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +0300109/* XPCS registers */
110
111/* VR MII MMD registers offsets */
112#define DW_VR_MII_DIG_CTRL1 0x8000
113#define DW_VR_MII_AN_CTRL 0x8001
114#define DW_VR_MII_DIG_CTRL2 0x80e1
115
116/* VR_MII_DIG_CTRL1 */
117#define DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW BIT(9)
118
119/* VR_MII_DIG_CTRL2 */
120#define DW_VR_MII_DIG_CTRL2_TX_POL_INV BIT(4)
121
122/* VR_MII_AN_CTRL */
123#define DW_VR_MII_AN_CTRL_TX_CONFIG_SHIFT 3
124#define DW_VR_MII_TX_CONFIG_MASK BIT(3)
125#define DW_VR_MII_TX_CONFIG_MAC_SIDE_SGMII 0x0
126#define DW_VR_MII_AN_CTRL_PCS_MODE_SHIFT 1
127#define DW_VR_MII_PCS_MODE_MASK GENMASK(2, 1)
128#define DW_VR_MII_PCS_MODE_C37_SGMII 0x2
129
130/* PMA registers */
131
132/* LANE_DRIVER1_0 register */
133#define SJA1110_LANE_DRIVER1_0 0x8038
134#define SJA1110_TXDRV(x) (((x) << 12) & GENMASK(14, 12))
135
136/* LANE_DRIVER2_0 register */
137#define SJA1110_LANE_DRIVER2_0 0x803a
138#define SJA1110_TXDRVTRIM_LSB(x) ((x) & GENMASK_ULL(15, 0))
139
140/* LANE_DRIVER2_1 register */
141#define SJA1110_LANE_DRIVER2_1 0x803b
142#define SJA1110_LANE_DRIVER2_1_RSV BIT(9)
143#define SJA1110_TXDRVTRIM_MSB(x) (((x) & GENMASK_ULL(23, 16)) >> 16)
144
145/* LANE_TRIM register */
146#define SJA1110_LANE_TRIM 0x8040
147#define SJA1110_TXTEN BIT(11)
148#define SJA1110_TXRTRIM(x) (((x) << 8) & GENMASK(10, 8))
149#define SJA1110_TXPLL_BWSEL BIT(7)
150#define SJA1110_RXTEN BIT(6)
151#define SJA1110_RXRTRIM(x) (((x) << 3) & GENMASK(5, 3))
152#define SJA1110_CDR_GAIN BIT(2)
153#define SJA1110_ACCOUPLE_RXVCM_EN BIT(0)
154
155/* LANE_DATAPATH_1 register */
156#define SJA1110_LANE_DATAPATH_1 0x8037
157
158/* POWERDOWN_ENABLE register */
159#define SJA1110_POWERDOWN_ENABLE 0x8041
160#define SJA1110_TXPLL_PD BIT(12)
161#define SJA1110_TXPD BIT(11)
162#define SJA1110_RXPKDETEN BIT(10)
163#define SJA1110_RXCH_PD BIT(9)
164#define SJA1110_RXBIAS_PD BIT(8)
165#define SJA1110_RESET_SER_EN BIT(7)
166#define SJA1110_RESET_SER BIT(6)
167#define SJA1110_RESET_DES BIT(5)
168#define SJA1110_RCVEN BIT(4)
169
170/* RXPLL_CTRL0 register */
171#define SJA1110_RXPLL_CTRL0 0x8065
172#define SJA1110_RXPLL_FBDIV(x) (((x) << 2) & GENMASK(9, 2))
173
174/* RXPLL_CTRL1 register */
175#define SJA1110_RXPLL_CTRL1 0x8066
176#define SJA1110_RXPLL_REFDIV(x) ((x) & GENMASK(4, 0))
177
178/* TXPLL_CTRL0 register */
179#define SJA1110_TXPLL_CTRL0 0x806d
180#define SJA1110_TXPLL_FBDIV(x) ((x) & GENMASK(11, 0))
181
182/* TXPLL_CTRL1 register */
183#define SJA1110_TXPLL_CTRL1 0x806e
184#define SJA1110_TXPLL_REFDIV(x) ((x) & GENMASK(5, 0))
185
186/* RX_DATA_DETECT register */
187#define SJA1110_RX_DATA_DETECT 0x8045
188
189/* RX_CDR_CTLE register */
190#define SJA1110_RX_CDR_CTLE 0x8042
191
Vladimir Olteanf24b6662021-09-29 18:04:41 +0300192/* UM10944.pdf Page 11, Table 2. Configuration Blocks */
193enum {
194 BLKID_L2_POLICING = 0x06,
195 BLKID_VLAN_LOOKUP = 0x07,
196 BLKID_L2_FORWARDING = 0x08,
197 BLKID_MAC_CONFIG = 0x09,
198 BLKID_L2_FORWARDING_PARAMS = 0x0E,
199 BLKID_GENERAL_PARAMS = 0x11,
200 BLKID_XMII_PARAMS = 0x4E,
201};
202
203enum sja1105_blk_idx {
204 BLK_IDX_L2_POLICING = 0,
205 BLK_IDX_VLAN_LOOKUP,
206 BLK_IDX_L2_FORWARDING,
207 BLK_IDX_MAC_CONFIG,
208 BLK_IDX_L2_FORWARDING_PARAMS,
209 BLK_IDX_GENERAL_PARAMS,
210 BLK_IDX_XMII_PARAMS,
211 BLK_IDX_MAX,
212};
213
214struct sja1105_general_params_entry {
215 u64 mac_fltres1;
216 u64 mac_fltres0;
217 u64 mac_flt1;
218 u64 mac_flt0;
219 u64 casc_port;
220 u64 host_port;
221 u64 mirr_port;
222 u64 tpid;
223 u64 tpid2;
224};
225
226struct sja1105_vlan_lookup_entry {
227 u64 vmemb_port;
228 u64 vlan_bc;
229 u64 tag_port;
230 u64 vlanid;
231 u64 type_entry; /* SJA1110 only */
232};
233
234struct sja1105_l2_forwarding_entry {
235 u64 bc_domain;
236 u64 reach_port;
237 u64 fl_domain;
238};
239
240struct sja1105_l2_forwarding_params_entry {
241 u64 part_spc[SJA1105_NUM_TC];
242};
243
244struct sja1105_l2_policing_entry {
245 u64 sharindx;
246 u64 smax;
247 u64 rate;
248 u64 maxlen;
249 u64 partition;
250};
251
252struct sja1105_mac_config_entry {
253 u64 top[SJA1105_NUM_TC];
254 u64 base[SJA1105_NUM_TC];
255 u64 enabled[SJA1105_NUM_TC];
256 u64 speed;
257 u64 vlanid;
258 u64 egress;
259 u64 ingress;
260};
261
262struct sja1105_xmii_params_entry {
263 u64 phy_mac[SJA1105_MAX_NUM_PORTS];
264 u64 xmii_mode[SJA1105_MAX_NUM_PORTS];
265 u64 special[SJA1105_MAX_NUM_PORTS];
266};
267
268struct sja1105_table_header {
269 u64 block_id;
270 u64 len;
271 u64 crc;
272};
273
274struct sja1105_table_ops {
275 size_t (*packing)(void *buf, void *entry_ptr, enum packing_op op);
276 size_t unpacked_entry_size;
277 size_t packed_entry_size;
278 size_t max_entry_count;
279};
280
281struct sja1105_table {
282 const struct sja1105_table_ops *ops;
283 size_t entry_count;
284 void *entries;
285};
286
287struct sja1105_static_config {
288 u64 device_id;
289 struct sja1105_table tables[BLK_IDX_MAX];
290};
291
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +0300292struct sja1105_xpcs_cfg {
293 bool inband_an;
294 int speed;
295};
296
Vladimir Olteanf24b6662021-09-29 18:04:41 +0300297struct sja1105_private {
298 struct sja1105_static_config static_config;
299 bool rgmii_rx_delay[SJA1105_MAX_NUM_PORTS];
300 bool rgmii_tx_delay[SJA1105_MAX_NUM_PORTS];
301 u16 pvid[SJA1105_MAX_NUM_PORTS];
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +0300302 struct sja1105_xpcs_cfg xpcs_cfg[SJA1105_MAX_NUM_PORTS];
303 struct mii_dev *mdio_pcs;
Vladimir Olteanf24b6662021-09-29 18:04:41 +0300304 const struct sja1105_info *info;
305 struct udevice *dev;
306};
307
308typedef enum {
309 SPI_READ = 0,
310 SPI_WRITE = 1,
311} sja1105_spi_rw_mode_t;
312
313typedef enum {
314 XMII_MAC = 0,
315 XMII_PHY = 1,
316} sja1105_mii_role_t;
317
318typedef enum {
319 XMII_MODE_MII = 0,
320 XMII_MODE_RMII = 1,
321 XMII_MODE_RGMII = 2,
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +0300322 XMII_MODE_SGMII = 3,
Vladimir Olteanf24b6662021-09-29 18:04:41 +0300323} sja1105_phy_interface_t;
324
325enum {
326 SJA1105_SPEED_AUTO,
327 SJA1105_SPEED_10MBPS,
328 SJA1105_SPEED_100MBPS,
329 SJA1105_SPEED_1000MBPS,
330 SJA1105_SPEED_MAX,
331};
332
333enum sja1110_vlan_type {
334 SJA1110_VLAN_INVALID = 0,
335 SJA1110_VLAN_C_TAG = 1, /* Single inner VLAN tag */
336 SJA1110_VLAN_S_TAG = 2, /* Single outer VLAN tag */
337 SJA1110_VLAN_D_TAG = 3, /* Double tagged, use outer tag for lookup */
338};
339
340/* Keeps the different addresses between E/T and P/Q/R/S */
341struct sja1105_regs {
342 u64 device_id;
343 u64 prod_id;
344 u64 status;
345 u64 port_control;
346 u64 rgu;
347 u64 config;
348 u64 rmii_pll1;
349 u64 pad_mii_tx[SJA1105_MAX_NUM_PORTS];
350 u64 pad_mii_rx[SJA1105_MAX_NUM_PORTS];
351 u64 pad_mii_id[SJA1105_MAX_NUM_PORTS];
352 u64 cgu_idiv[SJA1105_MAX_NUM_PORTS];
353 u64 mii_tx_clk[SJA1105_MAX_NUM_PORTS];
354 u64 mii_rx_clk[SJA1105_MAX_NUM_PORTS];
355 u64 mii_ext_tx_clk[SJA1105_MAX_NUM_PORTS];
356 u64 mii_ext_rx_clk[SJA1105_MAX_NUM_PORTS];
357 u64 rgmii_tx_clk[SJA1105_MAX_NUM_PORTS];
358 u64 rmii_ref_clk[SJA1105_MAX_NUM_PORTS];
359 u64 rmii_ext_tx_clk[SJA1105_MAX_NUM_PORTS];
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +0300360 u64 pcs_base[SJA1105_MAX_NUM_PORTS];
Vladimir Olteanf24b6662021-09-29 18:04:41 +0300361};
362
363struct sja1105_info {
364 u64 device_id;
365 u64 part_no;
366 const struct sja1105_table_ops *static_ops;
367 const struct sja1105_regs *regs;
368 int (*reset_cmd)(struct sja1105_private *priv);
369 int (*setup_rgmii_delay)(struct sja1105_private *priv, int port);
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +0300370 int (*pcs_mdio_read)(struct mii_dev *bus, int phy, int mmd, int reg);
371 int (*pcs_mdio_write)(struct mii_dev *bus, int phy, int mmd, int reg,
372 u16 val);
373 int (*pma_config)(struct sja1105_private *priv, int port);
Vladimir Olteanf24b6662021-09-29 18:04:41 +0300374 const char *name;
375 bool supports_mii[SJA1105_MAX_NUM_PORTS];
376 bool supports_rmii[SJA1105_MAX_NUM_PORTS];
377 bool supports_rgmii[SJA1105_MAX_NUM_PORTS];
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +0300378 bool supports_sgmii[SJA1105_MAX_NUM_PORTS];
Vladimir Olteanf24b6662021-09-29 18:04:41 +0300379 const u64 port_speed[SJA1105_SPEED_MAX];
380};
381
382struct sja1105_chunk {
383 u8 *buf;
384 size_t len;
385 u64 reg_addr;
386};
387
388struct sja1105_spi_message {
389 u64 access;
390 u64 read_count;
391 u64 address;
392};
393
394/* Common structure for CFG_PAD_MIIx_RX and CFG_PAD_MIIx_TX */
395struct sja1105_cfg_pad_mii {
396 u64 d32_os;
397 u64 d32_ih;
398 u64 d32_ipud;
399 u64 d10_ih;
400 u64 d10_os;
401 u64 d10_ipud;
402 u64 ctrl_os;
403 u64 ctrl_ih;
404 u64 ctrl_ipud;
405 u64 clk_os;
406 u64 clk_ih;
407 u64 clk_ipud;
408};
409
410struct sja1105_cfg_pad_mii_id {
411 u64 rxc_stable_ovr;
412 u64 rxc_delay;
413 u64 rxc_bypass;
414 u64 rxc_pd;
415 u64 txc_stable_ovr;
416 u64 txc_delay;
417 u64 txc_bypass;
418 u64 txc_pd;
419};
420
421struct sja1105_cgu_idiv {
422 u64 clksrc;
423 u64 autoblock;
424 u64 idiv;
425 u64 pd;
426};
427
428struct sja1105_cgu_pll_ctrl {
429 u64 pllclksrc;
430 u64 msel;
431 u64 autoblock;
432 u64 psel;
433 u64 direct;
434 u64 fbsel;
435 u64 bypass;
436 u64 pd;
437};
438
439enum {
440 CLKSRC_MII0_TX_CLK = 0x00,
441 CLKSRC_MII0_RX_CLK = 0x01,
442 CLKSRC_MII1_TX_CLK = 0x02,
443 CLKSRC_MII1_RX_CLK = 0x03,
444 CLKSRC_MII2_TX_CLK = 0x04,
445 CLKSRC_MII2_RX_CLK = 0x05,
446 CLKSRC_MII3_TX_CLK = 0x06,
447 CLKSRC_MII3_RX_CLK = 0x07,
448 CLKSRC_MII4_TX_CLK = 0x08,
449 CLKSRC_MII4_RX_CLK = 0x09,
450 CLKSRC_PLL0 = 0x0B,
451 CLKSRC_PLL1 = 0x0E,
452 CLKSRC_IDIV0 = 0x11,
453 CLKSRC_IDIV1 = 0x12,
454 CLKSRC_IDIV2 = 0x13,
455 CLKSRC_IDIV3 = 0x14,
456 CLKSRC_IDIV4 = 0x15,
457};
458
459struct sja1105_cgu_mii_ctrl {
460 u64 clksrc;
461 u64 autoblock;
462 u64 pd;
463};
464
465static int get_reverse_lsw32_offset(int offset, size_t len)
466{
467 int closest_multiple_of_4;
468 int word_index;
469
470 word_index = offset / 4;
471 closest_multiple_of_4 = word_index * 4;
472 offset -= closest_multiple_of_4;
473 word_index = (len / 4) - word_index - 1;
474 return word_index * 4 + offset;
475}
476
477/* Simplified version of the "packing" function from Linux, adapted
478 * to support only sja1105's quirk: QUIRK_LSW32_IS_FIRST
479 */
480static void sja1105_packing(void *pbuf, u64 *uval, int startbit, int endbit,
481 size_t pbuflen, enum packing_op op)
482{
483 int plogical_first_u8, plogical_last_u8, box;
484
485 if (op == UNPACK)
486 *uval = 0;
487
488 plogical_first_u8 = startbit / 8;
489 plogical_last_u8 = endbit / 8;
490
491 for (box = plogical_first_u8; box >= plogical_last_u8; box--) {
492 int box_start_bit, box_end_bit, box_addr;
493 int proj_start_bit, proj_end_bit;
494 u64 proj_mask;
495 u8 box_mask;
496
497 if (box == plogical_first_u8)
498 box_start_bit = startbit % 8;
499 else
500 box_start_bit = 7;
501 if (box == plogical_last_u8)
502 box_end_bit = endbit % 8;
503 else
504 box_end_bit = 0;
505
506 proj_start_bit = ((box * 8) + box_start_bit) - endbit;
507 proj_end_bit = ((box * 8) + box_end_bit) - endbit;
508 proj_mask = GENMASK_ULL(proj_start_bit, proj_end_bit);
509 box_mask = GENMASK_ULL(box_start_bit, box_end_bit);
510
511 box_addr = pbuflen - box - 1;
512 box_addr = get_reverse_lsw32_offset(box_addr, pbuflen);
513
514 if (op == UNPACK) {
515 u64 pval;
516
517 /* Read from pbuf, write to uval */
518 pval = ((u8 *)pbuf)[box_addr] & box_mask;
519
520 pval >>= box_end_bit;
521 pval <<= proj_end_bit;
522 *uval &= ~proj_mask;
523 *uval |= pval;
524 } else {
525 u64 pval;
526
527 /* Write to pbuf, read from uval */
528 pval = (*uval) & proj_mask;
529 pval >>= proj_end_bit;
530
531 pval <<= box_end_bit;
532 ((u8 *)pbuf)[box_addr] &= ~box_mask;
533 ((u8 *)pbuf)[box_addr] |= pval;
534 }
535 }
536}
537
538static u32 crc32_add(u32 crc, u8 byte)
539{
540 u32 byte32 = bitrev32(byte);
541 int i;
542
543 for (i = 0; i < 8; i++) {
544 if ((crc ^ byte32) & BIT(31)) {
545 crc <<= 1;
546 crc ^= ETHER_CRC32_POLY;
547 } else {
548 crc <<= 1;
549 }
550 byte32 <<= 1;
551 }
552 return crc;
553}
554
555/* Little-endian Ethernet CRC32 of data packed as big-endian u32 words */
556static uint32_t sja1105_crc32(void *buf, size_t len)
557{
558 unsigned int i;
559 u64 chunk;
560 u32 crc;
561
562 /* seed */
563 crc = 0xFFFFFFFF;
564 for (i = 0; i < len; i += 4) {
565 sja1105_packing(buf + i, &chunk, 31, 0, 4, UNPACK);
566 crc = crc32_add(crc, chunk & 0xFF);
567 crc = crc32_add(crc, (chunk >> 8) & 0xFF);
568 crc = crc32_add(crc, (chunk >> 16) & 0xFF);
569 crc = crc32_add(crc, (chunk >> 24) & 0xFF);
570 }
571 return bitrev32(~crc);
572}
573
574static void sja1105_spi_message_pack(void *buf, struct sja1105_spi_message *msg)
575{
576 const int size = SJA1105_SIZE_SPI_MSG_HEADER;
577
578 memset(buf, 0, size);
579
580 sja1105_packing(buf, &msg->access, 31, 31, size, PACK);
581 sja1105_packing(buf, &msg->read_count, 30, 25, size, PACK);
582 sja1105_packing(buf, &msg->address, 24, 4, size, PACK);
583}
584
585static int sja1105_xfer_buf(const struct sja1105_private *priv,
586 sja1105_spi_rw_mode_t rw, u64 reg_addr,
587 u8 *buf, size_t len)
588{
589 struct udevice *dev = priv->dev;
590 struct sja1105_chunk chunk = {
591 .len = min_t(size_t, len, SJA1105_SIZE_SPI_MSG_MAXLEN),
592 .reg_addr = reg_addr,
593 .buf = buf,
594 };
595 int num_chunks;
596 int rc, i;
597
598 rc = dm_spi_claim_bus(dev);
599 if (rc)
600 return rc;
601
602 num_chunks = DIV_ROUND_UP(len, SJA1105_SIZE_SPI_MSG_MAXLEN);
603
604 for (i = 0; i < num_chunks; i++) {
605 u8 hdr_buf[SJA1105_SIZE_SPI_MSG_HEADER];
606 struct sja1105_spi_message msg;
607 u8 *rx_buf = NULL;
608 u8 *tx_buf = NULL;
609
610 /* Populate the transfer's header buffer */
611 msg.address = chunk.reg_addr;
612 msg.access = rw;
613 if (rw == SPI_READ)
614 msg.read_count = chunk.len / 4;
615 else
616 /* Ignored */
617 msg.read_count = 0;
618 sja1105_spi_message_pack(hdr_buf, &msg);
619 rc = dm_spi_xfer(dev, SJA1105_SIZE_SPI_MSG_HEADER * 8, hdr_buf,
620 NULL, SPI_XFER_BEGIN);
621 if (rc)
622 goto out;
623
624 /* Populate the transfer's data buffer */
625 if (rw == SPI_READ)
626 rx_buf = chunk.buf;
627 else
628 tx_buf = chunk.buf;
629 rc = dm_spi_xfer(dev, chunk.len * 8, tx_buf, rx_buf,
630 SPI_XFER_END);
631 if (rc)
632 goto out;
633
634 /* Calculate next chunk */
635 chunk.buf += chunk.len;
636 chunk.reg_addr += chunk.len / 4;
637 chunk.len = min_t(size_t, (ptrdiff_t)(buf + len - chunk.buf),
638 SJA1105_SIZE_SPI_MSG_MAXLEN);
639 }
640
641out:
642 dm_spi_release_bus(dev);
643
644 return rc;
645}
646
647static int sja1105et_reset_cmd(struct sja1105_private *priv)
648{
649 const struct sja1105_regs *regs = priv->info->regs;
650 u8 packed_buf[SJA1105_SIZE_RESET_CMD] = {0};
651 const int size = SJA1105_SIZE_RESET_CMD;
652 u64 cold_rst = 1;
653
654 sja1105_packing(packed_buf, &cold_rst, 3, 3, size, PACK);
655
656 return sja1105_xfer_buf(priv, SPI_WRITE, regs->rgu, packed_buf,
657 SJA1105_SIZE_RESET_CMD);
658}
659
660static int sja1105pqrs_reset_cmd(struct sja1105_private *priv)
661{
662 const struct sja1105_regs *regs = priv->info->regs;
663 u8 packed_buf[SJA1105_SIZE_RESET_CMD] = {0};
664 const int size = SJA1105_SIZE_RESET_CMD;
665 u64 cold_rst = 1;
666
667 sja1105_packing(packed_buf, &cold_rst, 2, 2, size, PACK);
668
669 return sja1105_xfer_buf(priv, SPI_WRITE, regs->rgu, packed_buf,
670 SJA1105_SIZE_RESET_CMD);
671}
672
673static int sja1110_reset_cmd(struct sja1105_private *priv)
674{
675 const struct sja1105_regs *regs = priv->info->regs;
676 u8 packed_buf[SJA1105_SIZE_RESET_CMD] = {0};
677 const int size = SJA1105_SIZE_RESET_CMD;
678 u64 switch_rst = 1;
679
680 /* Only reset the switch core.
681 * A full cold reset would re-enable the BASE_MCSS_CLOCK PLL which
682 * would turn on the microcontroller, potentially letting it execute
683 * code which could interfere with our configuration.
684 */
685 sja1105_packing(packed_buf, &switch_rst, 20, 20, size, PACK);
686
687 return sja1105_xfer_buf(priv, SPI_WRITE, regs->rgu, packed_buf,
688 SJA1105_SIZE_RESET_CMD);
689}
690
691static size_t sja1105et_general_params_entry_packing(void *buf, void *entry_ptr,
692 enum packing_op op)
693{
694 const size_t size = SJA1105ET_SIZE_GENERAL_PARAMS_ENTRY;
695 struct sja1105_general_params_entry *entry = entry_ptr;
696
697 sja1105_packing(buf, &entry->mac_fltres1, 311, 264, size, op);
698 sja1105_packing(buf, &entry->mac_fltres0, 263, 216, size, op);
699 sja1105_packing(buf, &entry->mac_flt1, 215, 168, size, op);
700 sja1105_packing(buf, &entry->mac_flt0, 167, 120, size, op);
701 sja1105_packing(buf, &entry->casc_port, 115, 113, size, op);
702 sja1105_packing(buf, &entry->host_port, 112, 110, size, op);
703 sja1105_packing(buf, &entry->mirr_port, 109, 107, size, op);
704 sja1105_packing(buf, &entry->tpid, 42, 27, size, op);
705 sja1105_packing(buf, &entry->tpid2, 25, 10, size, op);
706 return size;
707}
708
709static size_t sja1110_general_params_entry_packing(void *buf, void *entry_ptr,
710 enum packing_op op)
711{
712 struct sja1105_general_params_entry *entry = entry_ptr;
713 const size_t size = SJA1110_SIZE_GENERAL_PARAMS_ENTRY;
714
715 sja1105_packing(buf, &entry->mac_fltres1, 438, 391, size, op);
716 sja1105_packing(buf, &entry->mac_fltres0, 390, 343, size, op);
717 sja1105_packing(buf, &entry->mac_flt1, 342, 295, size, op);
718 sja1105_packing(buf, &entry->mac_flt0, 294, 247, size, op);
719 sja1105_packing(buf, &entry->casc_port, 242, 232, size, op);
720 sja1105_packing(buf, &entry->host_port, 231, 228, size, op);
721 sja1105_packing(buf, &entry->mirr_port, 227, 224, size, op);
722 sja1105_packing(buf, &entry->tpid2, 159, 144, size, op);
723 sja1105_packing(buf, &entry->tpid, 142, 127, size, op);
724 return size;
725}
726
727static size_t
728sja1105pqrs_general_params_entry_packing(void *buf, void *entry_ptr,
729 enum packing_op op)
730{
731 const size_t size = SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY;
732 struct sja1105_general_params_entry *entry = entry_ptr;
733
734 sja1105_packing(buf, &entry->mac_fltres1, 343, 296, size, op);
735 sja1105_packing(buf, &entry->mac_fltres0, 295, 248, size, op);
736 sja1105_packing(buf, &entry->mac_flt1, 247, 200, size, op);
737 sja1105_packing(buf, &entry->mac_flt0, 199, 152, size, op);
738 sja1105_packing(buf, &entry->casc_port, 147, 145, size, op);
739 sja1105_packing(buf, &entry->host_port, 144, 142, size, op);
740 sja1105_packing(buf, &entry->mirr_port, 141, 139, size, op);
741 sja1105_packing(buf, &entry->tpid, 74, 59, size, op);
742 sja1105_packing(buf, &entry->tpid2, 57, 42, size, op);
743 return size;
744}
745
746static size_t
747sja1105_l2_forwarding_params_entry_packing(void *buf, void *entry_ptr,
748 enum packing_op op)
749{
750 const size_t size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY;
751 struct sja1105_l2_forwarding_params_entry *entry = entry_ptr;
752 int offset, i;
753
754 for (i = 0, offset = 13; i < SJA1105_NUM_TC; i++, offset += 10)
755 sja1105_packing(buf, &entry->part_spc[i],
756 offset + 9, offset + 0, size, op);
757 return size;
758}
759
760static size_t
761sja1110_l2_forwarding_params_entry_packing(void *buf, void *entry_ptr,
762 enum packing_op op)
763{
764 struct sja1105_l2_forwarding_params_entry *entry = entry_ptr;
765 const size_t size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY;
766 int offset, i;
767
768 for (i = 0, offset = 5; i < 8; i++, offset += 11)
769 sja1105_packing(buf, &entry->part_spc[i],
770 offset + 10, offset + 0, size, op);
771 return size;
772}
773
774static size_t sja1105_l2_forwarding_entry_packing(void *buf, void *entry_ptr,
775 enum packing_op op)
776{
777 const size_t size = SJA1105_SIZE_L2_FORWARDING_ENTRY;
778 struct sja1105_l2_forwarding_entry *entry = entry_ptr;
779
780 sja1105_packing(buf, &entry->bc_domain, 63, 59, size, op);
781 sja1105_packing(buf, &entry->reach_port, 58, 54, size, op);
782 sja1105_packing(buf, &entry->fl_domain, 53, 49, size, op);
783 return size;
784}
785
786static size_t sja1110_l2_forwarding_entry_packing(void *buf, void *entry_ptr,
787 enum packing_op op)
788{
789 struct sja1105_l2_forwarding_entry *entry = entry_ptr;
790 const size_t size = SJA1105_SIZE_L2_FORWARDING_ENTRY;
791
792 sja1105_packing(buf, &entry->bc_domain, 63, 53, size, op);
793 sja1105_packing(buf, &entry->reach_port, 52, 42, size, op);
794 sja1105_packing(buf, &entry->fl_domain, 41, 31, size, op);
795 return size;
796}
797
798static size_t sja1105_l2_policing_entry_packing(void *buf, void *entry_ptr,
799 enum packing_op op)
800{
801 struct sja1105_l2_policing_entry *entry = entry_ptr;
802 const size_t size = SJA1105_SIZE_L2_POLICING_ENTRY;
803
804 sja1105_packing(buf, &entry->sharindx, 63, 58, size, op);
805 sja1105_packing(buf, &entry->smax, 57, 42, size, op);
806 sja1105_packing(buf, &entry->rate, 41, 26, size, op);
807 sja1105_packing(buf, &entry->maxlen, 25, 15, size, op);
808 sja1105_packing(buf, &entry->partition, 14, 12, size, op);
809 return size;
810}
811
812static size_t sja1110_l2_policing_entry_packing(void *buf, void *entry_ptr,
813 enum packing_op op)
814{
815 struct sja1105_l2_policing_entry *entry = entry_ptr;
816 const size_t size = SJA1105_SIZE_L2_POLICING_ENTRY;
817
818 sja1105_packing(buf, &entry->sharindx, 63, 57, size, op);
819 sja1105_packing(buf, &entry->smax, 56, 39, size, op);
820 sja1105_packing(buf, &entry->rate, 38, 21, size, op);
821 sja1105_packing(buf, &entry->maxlen, 20, 10, size, op);
822 sja1105_packing(buf, &entry->partition, 9, 7, size, op);
823 return size;
824}
825
826static size_t sja1105et_mac_config_entry_packing(void *buf, void *entry_ptr,
827 enum packing_op op)
828{
829 const size_t size = SJA1105ET_SIZE_MAC_CONFIG_ENTRY;
830 struct sja1105_mac_config_entry *entry = entry_ptr;
831 int offset, i;
832
833 for (i = 0, offset = 72; i < SJA1105_NUM_TC; i++, offset += 19) {
834 sja1105_packing(buf, &entry->enabled[i],
835 offset + 0, offset + 0, size, op);
836 sja1105_packing(buf, &entry->base[i],
837 offset + 9, offset + 1, size, op);
838 sja1105_packing(buf, &entry->top[i],
839 offset + 18, offset + 10, size, op);
840 }
841 sja1105_packing(buf, &entry->speed, 66, 65, size, op);
842 sja1105_packing(buf, &entry->vlanid, 21, 10, size, op);
843 sja1105_packing(buf, &entry->egress, 2, 2, size, op);
844 sja1105_packing(buf, &entry->ingress, 1, 1, size, op);
845 return size;
846}
847
848static size_t sja1105pqrs_mac_config_entry_packing(void *buf, void *entry_ptr,
849 enum packing_op op)
850{
851 const size_t size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY;
852 struct sja1105_mac_config_entry *entry = entry_ptr;
853 int offset, i;
854
855 for (i = 0, offset = 104; i < SJA1105_NUM_TC; i++, offset += 19) {
856 sja1105_packing(buf, &entry->enabled[i],
857 offset + 0, offset + 0, size, op);
858 sja1105_packing(buf, &entry->base[i],
859 offset + 9, offset + 1, size, op);
860 sja1105_packing(buf, &entry->top[i],
861 offset + 18, offset + 10, size, op);
862 }
863 sja1105_packing(buf, &entry->speed, 98, 97, size, op);
864 sja1105_packing(buf, &entry->vlanid, 53, 42, size, op);
865 sja1105_packing(buf, &entry->egress, 32, 32, size, op);
866 sja1105_packing(buf, &entry->ingress, 31, 31, size, op);
867 return size;
868}
869
870static size_t sja1110_mac_config_entry_packing(void *buf, void *entry_ptr,
871 enum packing_op op)
872{
873 const size_t size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY;
874 struct sja1105_mac_config_entry *entry = entry_ptr;
875 int offset, i;
876
877 for (i = 0, offset = 104; i < 8; i++, offset += 19) {
878 sja1105_packing(buf, &entry->enabled[i],
879 offset + 0, offset + 0, size, op);
880 sja1105_packing(buf, &entry->base[i],
881 offset + 9, offset + 1, size, op);
882 sja1105_packing(buf, &entry->top[i],
883 offset + 18, offset + 10, size, op);
884 }
885 sja1105_packing(buf, &entry->speed, 98, 96, size, op);
886 sja1105_packing(buf, &entry->vlanid, 52, 41, size, op);
887 sja1105_packing(buf, &entry->egress, 31, 31, size, op);
888 sja1105_packing(buf, &entry->ingress, 30, 30, size, op);
889 return size;
890}
891
892static size_t sja1105_vlan_lookup_entry_packing(void *buf, void *entry_ptr,
893 enum packing_op op)
894{
895 const size_t size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY;
896 struct sja1105_vlan_lookup_entry *entry = entry_ptr;
897
898 sja1105_packing(buf, &entry->vmemb_port, 53, 49, size, op);
899 sja1105_packing(buf, &entry->vlan_bc, 48, 44, size, op);
900 sja1105_packing(buf, &entry->tag_port, 43, 39, size, op);
901 sja1105_packing(buf, &entry->vlanid, 38, 27, size, op);
902 return size;
903}
904
905static size_t sja1110_vlan_lookup_entry_packing(void *buf, void *entry_ptr,
906 enum packing_op op)
907{
908 struct sja1105_vlan_lookup_entry *entry = entry_ptr;
909 const size_t size = SJA1110_SIZE_VLAN_LOOKUP_ENTRY;
910
911 sja1105_packing(buf, &entry->vmemb_port, 73, 63, size, op);
912 sja1105_packing(buf, &entry->vlan_bc, 62, 52, size, op);
913 sja1105_packing(buf, &entry->tag_port, 51, 41, size, op);
914 sja1105_packing(buf, &entry->type_entry, 40, 39, size, op);
915 sja1105_packing(buf, &entry->vlanid, 38, 27, size, op);
916 return size;
917}
918
919static size_t sja1105_xmii_params_entry_packing(void *buf, void *entry_ptr,
920 enum packing_op op)
921{
922 const size_t size = SJA1105_SIZE_XMII_PARAMS_ENTRY;
923 struct sja1105_xmii_params_entry *entry = entry_ptr;
924 int offset, i;
925
926 for (i = 0, offset = 17; i < SJA1105_NUM_PORTS; i++, offset += 3) {
927 sja1105_packing(buf, &entry->xmii_mode[i],
928 offset + 1, offset + 0, size, op);
929 sja1105_packing(buf, &entry->phy_mac[i],
930 offset + 2, offset + 2, size, op);
931 }
932 return size;
933}
934
935static size_t sja1110_xmii_params_entry_packing(void *buf, void *entry_ptr,
936 enum packing_op op)
937{
938 const size_t size = SJA1110_SIZE_XMII_PARAMS_ENTRY;
939 struct sja1105_xmii_params_entry *entry = entry_ptr;
940 int offset, i;
941
942 for (i = 0, offset = 20; i < SJA1110_NUM_PORTS; i++, offset += 4) {
943 sja1105_packing(buf, &entry->xmii_mode[i],
944 offset + 1, offset + 0, size, op);
945 sja1105_packing(buf, &entry->phy_mac[i],
946 offset + 2, offset + 2, size, op);
947 sja1105_packing(buf, &entry->special[i],
948 offset + 3, offset + 3, size, op);
949 }
950 return size;
951}
952
953static size_t sja1105_table_header_packing(void *buf, void *entry_ptr,
954 enum packing_op op)
955{
956 const size_t size = SJA1105_SIZE_TABLE_HEADER;
957 struct sja1105_table_header *entry = entry_ptr;
958
959 sja1105_packing(buf, &entry->block_id, 31, 24, size, op);
960 sja1105_packing(buf, &entry->len, 55, 32, size, op);
961 sja1105_packing(buf, &entry->crc, 95, 64, size, op);
962 return size;
963}
964
965static void
966sja1105_table_header_pack_with_crc(void *buf, struct sja1105_table_header *hdr)
967{
968 /* First pack the table as-is, then calculate the CRC, and
969 * finally put the proper CRC into the packed buffer
970 */
971 memset(buf, 0, SJA1105_SIZE_TABLE_HEADER);
972 sja1105_table_header_packing(buf, hdr, PACK);
973 hdr->crc = sja1105_crc32(buf, SJA1105_SIZE_TABLE_HEADER - 4);
974 sja1105_packing(buf + SJA1105_SIZE_TABLE_HEADER - 4, &hdr->crc,
975 31, 0, 4, PACK);
976}
977
978static void sja1105_table_write_crc(u8 *table_start, u8 *crc_ptr)
979{
980 u64 computed_crc;
981 int len_bytes;
982
983 len_bytes = (uintptr_t)(crc_ptr - table_start);
984 computed_crc = sja1105_crc32(table_start, len_bytes);
985 sja1105_packing(crc_ptr, &computed_crc, 31, 0, 4, PACK);
986}
987
988/* The block IDs that the switches support are unfortunately sparse, so keep a
989 * mapping table to "block indices" and translate back and forth.
990 */
991static const u64 blk_id_map[BLK_IDX_MAX] = {
992 [BLK_IDX_L2_POLICING] = BLKID_L2_POLICING,
993 [BLK_IDX_VLAN_LOOKUP] = BLKID_VLAN_LOOKUP,
994 [BLK_IDX_L2_FORWARDING] = BLKID_L2_FORWARDING,
995 [BLK_IDX_MAC_CONFIG] = BLKID_MAC_CONFIG,
996 [BLK_IDX_L2_FORWARDING_PARAMS] = BLKID_L2_FORWARDING_PARAMS,
997 [BLK_IDX_GENERAL_PARAMS] = BLKID_GENERAL_PARAMS,
998 [BLK_IDX_XMII_PARAMS] = BLKID_XMII_PARAMS,
999};
1000
1001static void
1002sja1105_static_config_pack(void *buf, struct sja1105_static_config *config)
1003{
1004 struct sja1105_table_header header = {0};
1005 enum sja1105_blk_idx i;
1006 u8 *p = buf;
1007 int j;
1008
1009 sja1105_packing(p, &config->device_id, 31, 0, 4, PACK);
1010 p += SJA1105_SIZE_DEVICE_ID;
1011
1012 for (i = 0; i < BLK_IDX_MAX; i++) {
1013 const struct sja1105_table *table;
1014 u8 *table_start;
1015
1016 table = &config->tables[i];
1017 if (!table->entry_count)
1018 continue;
1019
1020 header.block_id = blk_id_map[i];
1021 header.len = table->entry_count *
1022 table->ops->packed_entry_size / 4;
1023 sja1105_table_header_pack_with_crc(p, &header);
1024 p += SJA1105_SIZE_TABLE_HEADER;
1025 table_start = p;
1026 for (j = 0; j < table->entry_count; j++) {
1027 u8 *entry_ptr = table->entries;
1028
1029 entry_ptr += j * table->ops->unpacked_entry_size;
1030 memset(p, 0, table->ops->packed_entry_size);
1031 table->ops->packing(p, entry_ptr, PACK);
1032 p += table->ops->packed_entry_size;
1033 }
1034 sja1105_table_write_crc(table_start, p);
1035 p += 4;
1036 }
1037 /* Final header:
1038 * Block ID does not matter
1039 * Length of 0 marks that header is final
1040 * CRC will be replaced on-the-fly
1041 */
1042 header.block_id = 0;
1043 header.len = 0;
1044 header.crc = 0xDEADBEEF;
1045 memset(p, 0, SJA1105_SIZE_TABLE_HEADER);
1046 sja1105_table_header_packing(p, &header, PACK);
1047}
1048
1049static size_t
1050sja1105_static_config_get_length(const struct sja1105_static_config *config)
1051{
1052 unsigned int header_count;
1053 enum sja1105_blk_idx i;
1054 unsigned int sum;
1055
1056 /* Ending header */
1057 header_count = 1;
1058 sum = SJA1105_SIZE_DEVICE_ID;
1059
1060 /* Tables (headers and entries) */
1061 for (i = 0; i < BLK_IDX_MAX; i++) {
1062 const struct sja1105_table *table;
1063
1064 table = &config->tables[i];
1065 if (table->entry_count)
1066 header_count++;
1067
1068 sum += table->ops->packed_entry_size * table->entry_count;
1069 }
1070 /* Headers have an additional CRC at the end */
1071 sum += header_count * (SJA1105_SIZE_TABLE_HEADER + 4);
1072 /* Last header does not have an extra CRC because there is no data */
1073 sum -= 4;
1074
1075 return sum;
1076}
1077
1078/* Compatibility matrices */
1079static const struct sja1105_table_ops sja1105et_table_ops[BLK_IDX_MAX] = {
1080 [BLK_IDX_L2_POLICING] = {
1081 .packing = sja1105_l2_policing_entry_packing,
1082 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry),
1083 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY,
1084 .max_entry_count = SJA1105_MAX_L2_POLICING_COUNT,
1085 },
1086 [BLK_IDX_VLAN_LOOKUP] = {
1087 .packing = sja1105_vlan_lookup_entry_packing,
1088 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry),
1089 .packed_entry_size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY,
1090 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT,
1091 },
1092 [BLK_IDX_L2_FORWARDING] = {
1093 .packing = sja1105_l2_forwarding_entry_packing,
1094 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry),
1095 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY,
1096 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT,
1097 },
1098 [BLK_IDX_MAC_CONFIG] = {
1099 .packing = sja1105et_mac_config_entry_packing,
1100 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry),
1101 .packed_entry_size = SJA1105ET_SIZE_MAC_CONFIG_ENTRY,
1102 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT,
1103 },
1104 [BLK_IDX_L2_FORWARDING_PARAMS] = {
1105 .packing = sja1105_l2_forwarding_params_entry_packing,
1106 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry),
1107 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY,
1108 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT,
1109 },
1110 [BLK_IDX_GENERAL_PARAMS] = {
1111 .packing = sja1105et_general_params_entry_packing,
1112 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry),
1113 .packed_entry_size = SJA1105ET_SIZE_GENERAL_PARAMS_ENTRY,
1114 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT,
1115 },
1116 [BLK_IDX_XMII_PARAMS] = {
1117 .packing = sja1105_xmii_params_entry_packing,
1118 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry),
1119 .packed_entry_size = SJA1105_SIZE_XMII_PARAMS_ENTRY,
1120 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT,
1121 },
1122};
1123
1124static const struct sja1105_table_ops sja1105pqrs_table_ops[BLK_IDX_MAX] = {
1125 [BLK_IDX_L2_POLICING] = {
1126 .packing = sja1105_l2_policing_entry_packing,
1127 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry),
1128 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY,
1129 .max_entry_count = SJA1105_MAX_L2_POLICING_COUNT,
1130 },
1131 [BLK_IDX_VLAN_LOOKUP] = {
1132 .packing = sja1105_vlan_lookup_entry_packing,
1133 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry),
1134 .packed_entry_size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY,
1135 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT,
1136 },
1137 [BLK_IDX_L2_FORWARDING] = {
1138 .packing = sja1105_l2_forwarding_entry_packing,
1139 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry),
1140 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY,
1141 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT,
1142 },
1143 [BLK_IDX_MAC_CONFIG] = {
1144 .packing = sja1105pqrs_mac_config_entry_packing,
1145 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry),
1146 .packed_entry_size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY,
1147 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT,
1148 },
1149 [BLK_IDX_L2_FORWARDING_PARAMS] = {
1150 .packing = sja1105_l2_forwarding_params_entry_packing,
1151 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry),
1152 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY,
1153 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT,
1154 },
1155 [BLK_IDX_GENERAL_PARAMS] = {
1156 .packing = sja1105pqrs_general_params_entry_packing,
1157 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry),
1158 .packed_entry_size = SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY,
1159 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT,
1160 },
1161 [BLK_IDX_XMII_PARAMS] = {
1162 .packing = sja1105_xmii_params_entry_packing,
1163 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry),
1164 .packed_entry_size = SJA1105_SIZE_XMII_PARAMS_ENTRY,
1165 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT,
1166 },
1167};
1168
1169static const struct sja1105_table_ops sja1110_table_ops[BLK_IDX_MAX] = {
1170 [BLK_IDX_L2_POLICING] = {
1171 .packing = sja1110_l2_policing_entry_packing,
1172 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry),
1173 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY,
1174 .max_entry_count = SJA1110_MAX_L2_POLICING_COUNT,
1175 },
1176 [BLK_IDX_VLAN_LOOKUP] = {
1177 .packing = sja1110_vlan_lookup_entry_packing,
1178 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry),
1179 .packed_entry_size = SJA1110_SIZE_VLAN_LOOKUP_ENTRY,
1180 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT,
1181 },
1182 [BLK_IDX_L2_FORWARDING] = {
1183 .packing = sja1110_l2_forwarding_entry_packing,
1184 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry),
1185 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY,
1186 .max_entry_count = SJA1110_MAX_L2_FORWARDING_COUNT,
1187 },
1188 [BLK_IDX_MAC_CONFIG] = {
1189 .packing = sja1110_mac_config_entry_packing,
1190 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry),
1191 .packed_entry_size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY,
1192 .max_entry_count = SJA1110_MAX_MAC_CONFIG_COUNT,
1193 },
1194 [BLK_IDX_L2_FORWARDING_PARAMS] = {
1195 .packing = sja1110_l2_forwarding_params_entry_packing,
1196 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry),
1197 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY,
1198 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT,
1199 },
1200 [BLK_IDX_GENERAL_PARAMS] = {
1201 .packing = sja1110_general_params_entry_packing,
1202 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry),
1203 .packed_entry_size = SJA1110_SIZE_GENERAL_PARAMS_ENTRY,
1204 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT,
1205 },
1206 [BLK_IDX_XMII_PARAMS] = {
1207 .packing = sja1110_xmii_params_entry_packing,
1208 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry),
1209 .packed_entry_size = SJA1110_SIZE_XMII_PARAMS_ENTRY,
1210 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT,
1211 },
1212};
1213
1214static int sja1105_init_mii_settings(struct sja1105_private *priv)
1215{
1216 struct sja1105_table *table;
1217
1218 table = &priv->static_config.tables[BLK_IDX_XMII_PARAMS];
1219
1220 table->entries = calloc(SJA1105_MAX_XMII_PARAMS_COUNT,
1221 table->ops->unpacked_entry_size);
1222 if (!table->entries)
1223 return -ENOMEM;
1224
1225 /* Table will be populated at runtime */
1226 table->entry_count = SJA1105_MAX_XMII_PARAMS_COUNT;
1227
1228 return 0;
1229}
1230
1231static void sja1105_setup_tagging(struct sja1105_private *priv, int port)
1232{
1233 struct dsa_pdata *pdata = dev_get_uclass_plat(priv->dev);
1234 struct sja1105_vlan_lookup_entry *vlan;
1235 int cpu = pdata->cpu_port;
1236
1237 /* The CPU port is implicitly configured by
1238 * configuring the front-panel ports
1239 */
1240 if (port == cpu)
1241 return;
1242
1243 vlan = priv->static_config.tables[BLK_IDX_VLAN_LOOKUP].entries;
1244
1245 priv->pvid[port] = DSA_8021Q_DIR_TX | DSA_8021Q_PORT(port);
1246
1247 vlan[port].vmemb_port = BIT(port) | BIT(cpu);
1248 vlan[port].vlan_bc = BIT(port) | BIT(cpu);
1249 vlan[port].tag_port = BIT(cpu);
1250 vlan[port].vlanid = priv->pvid[port];
1251 vlan[port].type_entry = SJA1110_VLAN_D_TAG;
1252}
1253
1254static int sja1105_init_vlan(struct sja1105_private *priv)
1255{
1256 struct dsa_pdata *pdata = dev_get_uclass_plat(priv->dev);
1257 struct sja1105_table *table;
1258 int port;
1259
1260 table = &priv->static_config.tables[BLK_IDX_VLAN_LOOKUP];
1261
1262 table->entries = calloc(pdata->num_ports,
1263 table->ops->unpacked_entry_size);
1264 if (!table->entries)
1265 return -ENOMEM;
1266
1267 table->entry_count = pdata->num_ports;
1268
1269 for (port = 0; port < pdata->num_ports; port++)
1270 sja1105_setup_tagging(priv, port);
1271
1272 return 0;
1273}
1274
1275static void
1276sja1105_port_allow_traffic(struct sja1105_l2_forwarding_entry *l2_fwd,
1277 int from, int to)
1278{
1279 l2_fwd[from].bc_domain |= BIT(to);
1280 l2_fwd[from].reach_port |= BIT(to);
1281 l2_fwd[from].fl_domain |= BIT(to);
1282}
1283
1284static int sja1105_init_l2_forwarding(struct sja1105_private *priv)
1285{
1286 struct dsa_pdata *pdata = dev_get_uclass_plat(priv->dev);
1287 struct sja1105_l2_forwarding_entry *l2fwd;
1288 struct sja1105_table *table;
1289 int cpu = pdata->cpu_port;
1290 int i;
1291
1292 table = &priv->static_config.tables[BLK_IDX_L2_FORWARDING];
1293
1294 table->entries = calloc(SJA1105_MAX_L2_FORWARDING_COUNT,
1295 table->ops->unpacked_entry_size);
1296 if (!table->entries)
1297 return -ENOMEM;
1298
1299 table->entry_count = SJA1105_MAX_L2_FORWARDING_COUNT;
1300
1301 l2fwd = table->entries;
1302
1303 /* First 5 entries define the forwarding rules */
1304 for (i = 0; i < pdata->num_ports; i++) {
1305 if (i == cpu)
1306 continue;
1307
1308 sja1105_port_allow_traffic(l2fwd, i, cpu);
1309 sja1105_port_allow_traffic(l2fwd, cpu, i);
1310 }
1311 /* Next 8 entries define VLAN PCP mapping from ingress to egress.
1312 * Leave them unpopulated (implicitly 0) but present.
1313 */
1314 return 0;
1315}
1316
1317static int sja1105_init_l2_forwarding_params(struct sja1105_private *priv)
1318{
1319 struct sja1105_l2_forwarding_params_entry default_l2fwd_params = {
1320 /* Use a single memory partition for all ingress queues */
1321 .part_spc = { SJA1105_MAX_FRAME_MEMORY, 0, 0, 0, 0, 0, 0, 0 },
1322 };
1323 struct sja1105_table *table;
1324
1325 table = &priv->static_config.tables[BLK_IDX_L2_FORWARDING_PARAMS];
1326
1327 table->entries = calloc(SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT,
1328 table->ops->unpacked_entry_size);
1329 if (!table->entries)
1330 return -ENOMEM;
1331
1332 table->entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT;
1333
1334 /* This table only has a single entry */
1335 ((struct sja1105_l2_forwarding_params_entry *)table->entries)[0] =
1336 default_l2fwd_params;
1337
1338 return 0;
1339}
1340
1341static int sja1105_init_general_params(struct sja1105_private *priv)
1342{
1343 struct dsa_pdata *pdata = dev_get_uclass_plat(priv->dev);
1344 struct sja1105_general_params_entry default_general_params = {
1345 /* No frame trapping */
1346 .mac_fltres1 = 0x0,
1347 .mac_flt1 = 0xffffffffffff,
1348 .mac_fltres0 = 0x0,
1349 .mac_flt0 = 0xffffffffffff,
1350 .host_port = pdata->num_ports,
1351 /* No mirroring => specify an out-of-range port value */
1352 .mirr_port = pdata->num_ports,
1353 /* No link-local trapping => specify an out-of-range port value
1354 */
1355 .casc_port = pdata->num_ports,
1356 /* Force the switch to see all traffic as untagged. */
1357 .tpid = ETH_P_SJA1105,
1358 .tpid2 = ETH_P_SJA1105,
1359 };
1360 struct sja1105_table *table;
1361
1362 table = &priv->static_config.tables[BLK_IDX_GENERAL_PARAMS];
1363
1364 table->entries = calloc(SJA1105_MAX_GENERAL_PARAMS_COUNT,
1365 table->ops->unpacked_entry_size);
1366 if (!table->entries)
1367 return -ENOMEM;
1368
1369 table->entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT;
1370
1371 /* This table only has a single entry */
1372 ((struct sja1105_general_params_entry *)table->entries)[0] =
1373 default_general_params;
1374
1375 return 0;
1376}
1377
1378static void sja1105_setup_policer(struct sja1105_l2_policing_entry *policing,
1379 int index, int mtu)
1380{
1381 policing[index].sharindx = index;
1382 policing[index].smax = 65535; /* Burst size in bytes */
1383 policing[index].rate = SJA1105_RATE_MBPS(1000);
1384 policing[index].maxlen = mtu;
1385 policing[index].partition = 0;
1386}
1387
1388static int sja1105_init_l2_policing(struct sja1105_private *priv)
1389{
1390 struct dsa_pdata *pdata = dev_get_uclass_plat(priv->dev);
1391 struct sja1105_l2_policing_entry *policing;
1392 struct sja1105_table *table;
1393 int cpu = pdata->cpu_port;
1394 int i, j, k;
1395
1396 table = &priv->static_config.tables[BLK_IDX_L2_POLICING];
1397
1398 table->entries = calloc(SJA1105_MAX_L2_POLICING_COUNT,
1399 table->ops->unpacked_entry_size);
1400 if (!table->entries)
1401 return -ENOMEM;
1402
1403 table->entry_count = SJA1105_MAX_L2_POLICING_COUNT;
1404
1405 policing = table->entries;
1406
1407 /* k sweeps through all unicast policers (0-39).
1408 * bcast sweeps through policers 40-44.
1409 */
1410 for (i = 0, k = 0; i < pdata->num_ports; i++) {
1411 int bcast = (pdata->num_ports * SJA1105_NUM_TC) + i;
1412 int mtu = VLAN_ETH_FRAME_LEN + ETH_FCS_LEN;
1413
1414 if (i == cpu)
1415 mtu += VLAN_HLEN;
1416
1417 for (j = 0; j < SJA1105_NUM_TC; j++, k++)
1418 sja1105_setup_policer(policing, k, mtu);
1419
1420 /* Set up this port's policer for broadcast traffic */
1421 sja1105_setup_policer(policing, bcast, mtu);
1422 }
1423 return 0;
1424}
1425
1426static int sja1105_init_mac_settings(struct sja1105_private *priv)
1427{
1428 struct sja1105_mac_config_entry default_mac = {
1429 /* Enable 1 priority queue on egress. */
1430 .top = {0x1FF, 0, 0, 0, 0, 0, 0},
1431 .base = {0x0, 0, 0, 0, 0, 0, 0, 0},
1432 .enabled = {1, 0, 0, 0, 0, 0, 0, 0},
1433 /* Will be overridden in sja1105_port_enable. */
1434 .speed = priv->info->port_speed[SJA1105_SPEED_AUTO],
1435 .egress = true,
1436 .ingress = true,
1437 };
1438 struct dsa_pdata *pdata = dev_get_uclass_plat(priv->dev);
1439 struct sja1105_mac_config_entry *mac;
1440 struct sja1105_table *table;
1441 int port;
1442
1443 table = &priv->static_config.tables[BLK_IDX_MAC_CONFIG];
1444
1445 table->entries = calloc(pdata->num_ports,
1446 table->ops->unpacked_entry_size);
1447 if (!table->entries)
1448 return -ENOMEM;
1449
1450 table->entry_count = pdata->num_ports;
1451
1452 mac = table->entries;
1453
1454 for (port = 0; port < pdata->num_ports; port++) {
1455 mac[port] = default_mac;
1456 /* Internal VLAN (pvid) to apply to untagged ingress */
1457 mac[port].vlanid = priv->pvid[port];
1458 }
1459
1460 return 0;
1461}
1462
1463static int sja1105_static_config_init(struct sja1105_private *priv)
1464{
1465 struct sja1105_static_config *config = &priv->static_config;
1466 const struct sja1105_table_ops *static_ops = priv->info->static_ops;
1467 u64 device_id = priv->info->device_id;
1468 enum sja1105_blk_idx i;
1469 int rc;
1470
1471 *config = (struct sja1105_static_config) {0};
1472
1473 /* Transfer static_ops array from priv into per-table ops
1474 * for handier access
1475 */
1476 for (i = 0; i < BLK_IDX_MAX; i++)
1477 config->tables[i].ops = &static_ops[i];
1478
1479 config->device_id = device_id;
1480
1481 /* Build initial static configuration, to be fixed up during runtime */
1482 rc = sja1105_init_vlan(priv);
1483 if (rc < 0)
1484 return rc;
1485 rc = sja1105_init_mac_settings(priv);
1486 if (rc < 0)
1487 return rc;
1488 rc = sja1105_init_mii_settings(priv);
1489 if (rc < 0)
1490 return rc;
1491 rc = sja1105_init_l2_forwarding(priv);
1492 if (rc < 0)
1493 return rc;
1494 rc = sja1105_init_l2_forwarding_params(priv);
1495 if (rc < 0)
1496 return rc;
1497 rc = sja1105_init_l2_policing(priv);
1498 if (rc < 0)
1499 return rc;
1500 rc = sja1105_init_general_params(priv);
1501 if (rc < 0)
1502 return rc;
1503
1504 return 0;
1505}
1506
1507static void sja1105_static_config_free(struct sja1105_static_config *config)
1508{
1509 enum sja1105_blk_idx i;
1510
1511 for (i = 0; i < BLK_IDX_MAX; i++) {
1512 if (config->tables[i].entry_count) {
1513 free(config->tables[i].entries);
1514 config->tables[i].entry_count = 0;
1515 }
1516 }
1517}
1518
1519static void sja1105_cgu_idiv_packing(void *buf, struct sja1105_cgu_idiv *idiv,
1520 enum packing_op op)
1521{
1522 const int size = 4;
1523
1524 sja1105_packing(buf, &idiv->clksrc, 28, 24, size, op);
1525 sja1105_packing(buf, &idiv->autoblock, 11, 11, size, op);
1526 sja1105_packing(buf, &idiv->idiv, 5, 2, size, op);
1527 sja1105_packing(buf, &idiv->pd, 0, 0, size, op);
1528}
1529
1530static int sja1105_cgu_idiv_config(struct sja1105_private *priv, int port,
1531 bool enabled, int factor)
1532{
1533 const struct sja1105_regs *regs = priv->info->regs;
1534 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
1535 struct sja1105_cgu_idiv idiv;
1536
1537 if (regs->cgu_idiv[port] == SJA1105_RSV_ADDR)
1538 return 0;
1539
1540 if (enabled && factor != 1 && factor != 10)
1541 return -ERANGE;
1542
1543 /* Payload for packed_buf */
1544 idiv.clksrc = 0x0A; /* 25MHz */
1545 idiv.autoblock = 1; /* Block clk automatically */
1546 idiv.idiv = factor - 1; /* Divide by 1 or 10 */
1547 idiv.pd = enabled ? 0 : 1; /* Power down? */
1548 sja1105_cgu_idiv_packing(packed_buf, &idiv, PACK);
1549
1550 return sja1105_xfer_buf(priv, SPI_WRITE, regs->cgu_idiv[port],
1551 packed_buf, SJA1105_SIZE_CGU_CMD);
1552}
1553
1554static void
1555sja1105_cgu_mii_control_packing(void *buf, struct sja1105_cgu_mii_ctrl *cmd,
1556 enum packing_op op)
1557{
1558 const int size = 4;
1559
1560 sja1105_packing(buf, &cmd->clksrc, 28, 24, size, op);
1561 sja1105_packing(buf, &cmd->autoblock, 11, 11, size, op);
1562 sja1105_packing(buf, &cmd->pd, 0, 0, size, op);
1563}
1564
1565static int sja1105_cgu_mii_tx_clk_config(struct sja1105_private *priv,
1566 int port, sja1105_mii_role_t role)
1567{
1568 const struct sja1105_regs *regs = priv->info->regs;
1569 struct sja1105_cgu_mii_ctrl mii_tx_clk;
1570 const int mac_clk_sources[] = {
1571 CLKSRC_MII0_TX_CLK,
1572 CLKSRC_MII1_TX_CLK,
1573 CLKSRC_MII2_TX_CLK,
1574 CLKSRC_MII3_TX_CLK,
1575 CLKSRC_MII4_TX_CLK,
1576 };
1577 const int phy_clk_sources[] = {
1578 CLKSRC_IDIV0,
1579 CLKSRC_IDIV1,
1580 CLKSRC_IDIV2,
1581 CLKSRC_IDIV3,
1582 CLKSRC_IDIV4,
1583 };
1584 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
1585 int clksrc;
1586
1587 if (regs->mii_tx_clk[port] == SJA1105_RSV_ADDR)
1588 return 0;
1589
1590 if (role == XMII_MAC)
1591 clksrc = mac_clk_sources[port];
1592 else
1593 clksrc = phy_clk_sources[port];
1594
1595 /* Payload for packed_buf */
1596 mii_tx_clk.clksrc = clksrc;
1597 mii_tx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
1598 mii_tx_clk.pd = 0; /* Power Down off => enabled */
1599 sja1105_cgu_mii_control_packing(packed_buf, &mii_tx_clk, PACK);
1600
1601 return sja1105_xfer_buf(priv, SPI_WRITE, regs->mii_tx_clk[port],
1602 packed_buf, SJA1105_SIZE_CGU_CMD);
1603}
1604
1605static int
1606sja1105_cgu_mii_rx_clk_config(struct sja1105_private *priv, int port)
1607{
1608 const struct sja1105_regs *regs = priv->info->regs;
1609 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
1610 struct sja1105_cgu_mii_ctrl mii_rx_clk;
1611 const int clk_sources[] = {
1612 CLKSRC_MII0_RX_CLK,
1613 CLKSRC_MII1_RX_CLK,
1614 CLKSRC_MII2_RX_CLK,
1615 CLKSRC_MII3_RX_CLK,
1616 CLKSRC_MII4_RX_CLK,
1617 };
1618
1619 if (regs->mii_rx_clk[port] == SJA1105_RSV_ADDR)
1620 return 0;
1621
1622 /* Payload for packed_buf */
1623 mii_rx_clk.clksrc = clk_sources[port];
1624 mii_rx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
1625 mii_rx_clk.pd = 0; /* Power Down off => enabled */
1626 sja1105_cgu_mii_control_packing(packed_buf, &mii_rx_clk, PACK);
1627
1628 return sja1105_xfer_buf(priv, SPI_WRITE, regs->mii_rx_clk[port],
1629 packed_buf, SJA1105_SIZE_CGU_CMD);
1630}
1631
1632static int
1633sja1105_cgu_mii_ext_tx_clk_config(struct sja1105_private *priv, int port)
1634{
1635 const struct sja1105_regs *regs = priv->info->regs;
1636 struct sja1105_cgu_mii_ctrl mii_ext_tx_clk;
1637 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
1638 const int clk_sources[] = {
1639 CLKSRC_IDIV0,
1640 CLKSRC_IDIV1,
1641 CLKSRC_IDIV2,
1642 CLKSRC_IDIV3,
1643 CLKSRC_IDIV4,
1644 };
1645
1646 if (regs->mii_ext_tx_clk[port] == SJA1105_RSV_ADDR)
1647 return 0;
1648
1649 /* Payload for packed_buf */
1650 mii_ext_tx_clk.clksrc = clk_sources[port];
1651 mii_ext_tx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
1652 mii_ext_tx_clk.pd = 0; /* Power Down off => enabled */
1653 sja1105_cgu_mii_control_packing(packed_buf, &mii_ext_tx_clk, PACK);
1654
1655 return sja1105_xfer_buf(priv, SPI_WRITE, regs->mii_ext_tx_clk[port],
1656 packed_buf, SJA1105_SIZE_CGU_CMD);
1657}
1658
1659static int
1660sja1105_cgu_mii_ext_rx_clk_config(struct sja1105_private *priv, int port)
1661{
1662 const struct sja1105_regs *regs = priv->info->regs;
1663 struct sja1105_cgu_mii_ctrl mii_ext_rx_clk;
1664 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
1665 const int clk_sources[] = {
1666 CLKSRC_IDIV0,
1667 CLKSRC_IDIV1,
1668 CLKSRC_IDIV2,
1669 CLKSRC_IDIV3,
1670 CLKSRC_IDIV4,
1671 };
1672
1673 if (regs->mii_ext_rx_clk[port] == SJA1105_RSV_ADDR)
1674 return 0;
1675
1676 /* Payload for packed_buf */
1677 mii_ext_rx_clk.clksrc = clk_sources[port];
1678 mii_ext_rx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
1679 mii_ext_rx_clk.pd = 0; /* Power Down off => enabled */
1680 sja1105_cgu_mii_control_packing(packed_buf, &mii_ext_rx_clk, PACK);
1681
1682 return sja1105_xfer_buf(priv, SPI_WRITE, regs->mii_ext_rx_clk[port],
1683 packed_buf, SJA1105_SIZE_CGU_CMD);
1684}
1685
1686static int sja1105_mii_clocking_setup(struct sja1105_private *priv, int port,
1687 sja1105_mii_role_t role)
1688{
1689 int rc;
1690
1691 rc = sja1105_cgu_idiv_config(priv, port, (role == XMII_PHY), 1);
1692 if (rc < 0)
1693 return rc;
1694
1695 rc = sja1105_cgu_mii_tx_clk_config(priv, port, role);
1696 if (rc < 0)
1697 return rc;
1698
1699 rc = sja1105_cgu_mii_rx_clk_config(priv, port);
1700 if (rc < 0)
1701 return rc;
1702
1703 if (role == XMII_PHY) {
1704 rc = sja1105_cgu_mii_ext_tx_clk_config(priv, port);
1705 if (rc < 0)
1706 return rc;
1707
1708 rc = sja1105_cgu_mii_ext_rx_clk_config(priv, port);
1709 if (rc < 0)
1710 return rc;
1711 }
1712 return 0;
1713}
1714
1715static void
1716sja1105_cgu_pll_control_packing(void *buf, struct sja1105_cgu_pll_ctrl *cmd,
1717 enum packing_op op)
1718{
1719 const int size = 4;
1720
1721 sja1105_packing(buf, &cmd->pllclksrc, 28, 24, size, op);
1722 sja1105_packing(buf, &cmd->msel, 23, 16, size, op);
1723 sja1105_packing(buf, &cmd->autoblock, 11, 11, size, op);
1724 sja1105_packing(buf, &cmd->psel, 9, 8, size, op);
1725 sja1105_packing(buf, &cmd->direct, 7, 7, size, op);
1726 sja1105_packing(buf, &cmd->fbsel, 6, 6, size, op);
1727 sja1105_packing(buf, &cmd->bypass, 1, 1, size, op);
1728 sja1105_packing(buf, &cmd->pd, 0, 0, size, op);
1729}
1730
1731static int sja1105_cgu_rgmii_tx_clk_config(struct sja1105_private *priv,
1732 int port, u64 speed)
1733{
1734 const struct sja1105_regs *regs = priv->info->regs;
1735 struct sja1105_cgu_mii_ctrl txc;
1736 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
1737 int clksrc;
1738
1739 if (regs->rgmii_tx_clk[port] == SJA1105_RSV_ADDR)
1740 return 0;
1741
1742 if (speed == priv->info->port_speed[SJA1105_SPEED_1000MBPS]) {
1743 clksrc = CLKSRC_PLL0;
1744 } else {
1745 int clk_sources[] = {CLKSRC_IDIV0, CLKSRC_IDIV1, CLKSRC_IDIV2,
1746 CLKSRC_IDIV3, CLKSRC_IDIV4};
1747 clksrc = clk_sources[port];
1748 }
1749
1750 /* RGMII: 125MHz for 1000, 25MHz for 100, 2.5MHz for 10 */
1751 txc.clksrc = clksrc;
1752 /* Autoblock clk while changing clksrc */
1753 txc.autoblock = 1;
1754 /* Power Down off => enabled */
1755 txc.pd = 0;
1756 sja1105_cgu_mii_control_packing(packed_buf, &txc, PACK);
1757
1758 return sja1105_xfer_buf(priv, SPI_WRITE, regs->rgmii_tx_clk[port],
1759 packed_buf, SJA1105_SIZE_CGU_CMD);
1760}
1761
1762/* AGU */
1763static void
1764sja1105_cfg_pad_mii_packing(void *buf, struct sja1105_cfg_pad_mii *cmd,
1765 enum packing_op op)
1766{
1767 const int size = 4;
1768
1769 sja1105_packing(buf, &cmd->d32_os, 28, 27, size, op);
1770 sja1105_packing(buf, &cmd->d32_ih, 26, 26, size, op);
1771 sja1105_packing(buf, &cmd->d32_ipud, 25, 24, size, op);
1772 sja1105_packing(buf, &cmd->d10_os, 20, 19, size, op);
1773 sja1105_packing(buf, &cmd->d10_ih, 18, 18, size, op);
1774 sja1105_packing(buf, &cmd->d10_ipud, 17, 16, size, op);
1775 sja1105_packing(buf, &cmd->ctrl_os, 12, 11, size, op);
1776 sja1105_packing(buf, &cmd->ctrl_ih, 10, 10, size, op);
1777 sja1105_packing(buf, &cmd->ctrl_ipud, 9, 8, size, op);
1778 sja1105_packing(buf, &cmd->clk_os, 4, 3, size, op);
1779 sja1105_packing(buf, &cmd->clk_ih, 2, 2, size, op);
1780 sja1105_packing(buf, &cmd->clk_ipud, 1, 0, size, op);
1781}
1782
1783static void
1784sja1110_cfg_pad_mii_id_packing(void *buf, struct sja1105_cfg_pad_mii_id *cmd,
1785 enum packing_op op)
1786{
1787 const int size = SJA1105_SIZE_CGU_CMD;
1788 u64 range = 4;
1789
1790 /* Fields RXC_RANGE and TXC_RANGE select the input frequency range:
1791 * 0 = 2.5MHz
1792 * 1 = 25MHz
1793 * 2 = 50MHz
1794 * 3 = 125MHz
1795 * 4 = Automatically determined by port speed.
1796 * There's no point in defining a structure different than the one for
1797 * SJA1105, so just hardcode the frequency range to automatic, just as
1798 * before.
1799 */
1800 sja1105_packing(buf, &cmd->rxc_stable_ovr, 26, 26, size, op);
1801 sja1105_packing(buf, &cmd->rxc_delay, 25, 21, size, op);
1802 sja1105_packing(buf, &range, 20, 18, size, op);
1803 sja1105_packing(buf, &cmd->rxc_bypass, 17, 17, size, op);
1804 sja1105_packing(buf, &cmd->rxc_pd, 16, 16, size, op);
1805 sja1105_packing(buf, &cmd->txc_stable_ovr, 10, 10, size, op);
1806 sja1105_packing(buf, &cmd->txc_delay, 9, 5, size, op);
1807 sja1105_packing(buf, &range, 4, 2, size, op);
1808 sja1105_packing(buf, &cmd->txc_bypass, 1, 1, size, op);
1809 sja1105_packing(buf, &cmd->txc_pd, 0, 0, size, op);
1810}
1811
1812static int sja1105_rgmii_cfg_pad_tx_config(struct sja1105_private *priv,
1813 int port)
1814{
1815 const struct sja1105_regs *regs = priv->info->regs;
1816 struct sja1105_cfg_pad_mii pad_mii_tx = {0};
1817 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
1818
1819 if (regs->pad_mii_tx[port] == SJA1105_RSV_ADDR)
1820 return 0;
1821
1822 /* Payload */
1823 pad_mii_tx.d32_os = 3; /* TXD[3:2] output stage: */
1824 /* high noise/high speed */
1825 pad_mii_tx.d10_os = 3; /* TXD[1:0] output stage: */
1826 /* high noise/high speed */
1827 pad_mii_tx.d32_ipud = 2; /* TXD[3:2] input stage: */
1828 /* plain input (default) */
1829 pad_mii_tx.d10_ipud = 2; /* TXD[1:0] input stage: */
1830 /* plain input (default) */
1831 pad_mii_tx.ctrl_os = 3; /* TX_CTL / TX_ER output stage */
1832 pad_mii_tx.ctrl_ipud = 2; /* TX_CTL / TX_ER input stage (default) */
1833 pad_mii_tx.clk_os = 3; /* TX_CLK output stage */
1834 pad_mii_tx.clk_ih = 0; /* TX_CLK input hysteresis (default) */
1835 pad_mii_tx.clk_ipud = 2; /* TX_CLK input stage (default) */
1836 sja1105_cfg_pad_mii_packing(packed_buf, &pad_mii_tx, PACK);
1837
1838 return sja1105_xfer_buf(priv, SPI_WRITE, regs->pad_mii_tx[port],
1839 packed_buf, SJA1105_SIZE_CGU_CMD);
1840}
1841
1842static int sja1105_cfg_pad_rx_config(struct sja1105_private *priv, int port)
1843{
1844 const struct sja1105_regs *regs = priv->info->regs;
1845 struct sja1105_cfg_pad_mii pad_mii_rx = {0};
1846 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
1847
1848 if (regs->pad_mii_rx[port] == SJA1105_RSV_ADDR)
1849 return 0;
1850
1851 /* Payload */
1852 pad_mii_rx.d32_ih = 0; /* RXD[3:2] input stage hysteresis: */
1853 /* non-Schmitt (default) */
1854 pad_mii_rx.d32_ipud = 2; /* RXD[3:2] input weak pull-up/down */
1855 /* plain input (default) */
1856 pad_mii_rx.d10_ih = 0; /* RXD[1:0] input stage hysteresis: */
1857 /* non-Schmitt (default) */
1858 pad_mii_rx.d10_ipud = 2; /* RXD[1:0] input weak pull-up/down */
1859 /* plain input (default) */
1860 pad_mii_rx.ctrl_ih = 0; /* RX_DV/CRS_DV/RX_CTL and RX_ER */
1861 /* input stage hysteresis: */
1862 /* non-Schmitt (default) */
1863 pad_mii_rx.ctrl_ipud = 3; /* RX_DV/CRS_DV/RX_CTL and RX_ER */
1864 /* input stage weak pull-up/down: */
1865 /* pull-down */
1866 pad_mii_rx.clk_os = 2; /* RX_CLK/RXC output stage: */
1867 /* medium noise/fast speed (default) */
1868 pad_mii_rx.clk_ih = 0; /* RX_CLK/RXC input hysteresis: */
1869 /* non-Schmitt (default) */
1870 pad_mii_rx.clk_ipud = 2; /* RX_CLK/RXC input pull-up/down: */
1871 /* plain input (default) */
1872 sja1105_cfg_pad_mii_packing(packed_buf, &pad_mii_rx, PACK);
1873
1874 return sja1105_xfer_buf(priv, SPI_WRITE, regs->pad_mii_rx[port],
1875 packed_buf, SJA1105_SIZE_CGU_CMD);
1876}
1877
1878static void
1879sja1105_cfg_pad_mii_id_packing(void *buf, struct sja1105_cfg_pad_mii_id *cmd,
1880 enum packing_op op)
1881{
1882 const int size = SJA1105_SIZE_CGU_CMD;
1883
1884 sja1105_packing(buf, &cmd->rxc_stable_ovr, 15, 15, size, op);
1885 sja1105_packing(buf, &cmd->rxc_delay, 14, 10, size, op);
1886 sja1105_packing(buf, &cmd->rxc_bypass, 9, 9, size, op);
1887 sja1105_packing(buf, &cmd->rxc_pd, 8, 8, size, op);
1888 sja1105_packing(buf, &cmd->txc_stable_ovr, 7, 7, size, op);
1889 sja1105_packing(buf, &cmd->txc_delay, 6, 2, size, op);
1890 sja1105_packing(buf, &cmd->txc_bypass, 1, 1, size, op);
1891 sja1105_packing(buf, &cmd->txc_pd, 0, 0, size, op);
1892}
1893
1894/* Valid range in degrees is an integer between 73.8 and 101.7 */
1895static u64 sja1105_rgmii_delay(u64 phase)
1896{
1897 /* UM11040.pdf: The delay in degree phase is 73.8 + delay_tune * 0.9.
1898 * To avoid floating point operations we'll multiply by 10
1899 * and get 1 decimal point precision.
1900 */
1901 phase *= 10;
1902 return (phase - 738) / 9;
1903}
1904
1905static int sja1105pqrs_setup_rgmii_delay(struct sja1105_private *priv, int port)
1906{
1907 const struct sja1105_regs *regs = priv->info->regs;
1908 struct sja1105_cfg_pad_mii_id pad_mii_id = {0};
1909 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
1910 int rc;
1911
1912 if (priv->rgmii_rx_delay[port])
1913 pad_mii_id.rxc_delay = sja1105_rgmii_delay(90);
1914 if (priv->rgmii_tx_delay[port])
1915 pad_mii_id.txc_delay = sja1105_rgmii_delay(90);
1916
1917 /* Stage 1: Turn the RGMII delay lines off. */
1918 pad_mii_id.rxc_bypass = 1;
1919 pad_mii_id.rxc_pd = 1;
1920 pad_mii_id.txc_bypass = 1;
1921 pad_mii_id.txc_pd = 1;
1922 sja1105_cfg_pad_mii_id_packing(packed_buf, &pad_mii_id, PACK);
1923
1924 rc = sja1105_xfer_buf(priv, SPI_WRITE, regs->pad_mii_id[port],
1925 packed_buf, SJA1105_SIZE_CGU_CMD);
1926 if (rc < 0)
1927 return rc;
1928
1929 /* Stage 2: Turn the RGMII delay lines on. */
1930 if (priv->rgmii_rx_delay[port]) {
1931 pad_mii_id.rxc_bypass = 0;
1932 pad_mii_id.rxc_pd = 0;
1933 }
1934 if (priv->rgmii_tx_delay[port]) {
1935 pad_mii_id.txc_bypass = 0;
1936 pad_mii_id.txc_pd = 0;
1937 }
1938 sja1105_cfg_pad_mii_id_packing(packed_buf, &pad_mii_id, PACK);
1939
1940 return sja1105_xfer_buf(priv, SPI_WRITE, regs->pad_mii_id[port],
1941 packed_buf, SJA1105_SIZE_CGU_CMD);
1942}
1943
1944static int sja1110_setup_rgmii_delay(struct sja1105_private *priv, int port)
1945{
1946 const struct sja1105_regs *regs = priv->info->regs;
1947 struct sja1105_cfg_pad_mii_id pad_mii_id = {0};
1948 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
1949
1950 pad_mii_id.rxc_pd = 1;
1951 pad_mii_id.txc_pd = 1;
1952
1953 if (priv->rgmii_rx_delay[port]) {
1954 pad_mii_id.rxc_delay = sja1105_rgmii_delay(90);
1955 /* The "BYPASS" bit in SJA1110 is actually a "don't bypass" */
1956 pad_mii_id.rxc_bypass = 1;
1957 pad_mii_id.rxc_pd = 0;
1958 }
1959
1960 if (priv->rgmii_tx_delay[port]) {
1961 pad_mii_id.txc_delay = sja1105_rgmii_delay(90);
1962 pad_mii_id.txc_bypass = 1;
1963 pad_mii_id.txc_pd = 0;
1964 }
1965
1966 sja1110_cfg_pad_mii_id_packing(packed_buf, &pad_mii_id, PACK);
1967
1968 return sja1105_xfer_buf(priv, SPI_WRITE, regs->pad_mii_id[port],
1969 packed_buf, SJA1105_SIZE_CGU_CMD);
1970}
1971
1972static int sja1105_rgmii_clocking_setup(struct sja1105_private *priv, int port,
1973 sja1105_mii_role_t role)
1974{
1975 struct sja1105_mac_config_entry *mac;
1976 struct udevice *dev = priv->dev;
1977 u64 speed;
1978 int rc;
1979
1980 mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries;
1981 speed = mac[port].speed;
1982
1983 if (speed == priv->info->port_speed[SJA1105_SPEED_1000MBPS]) {
1984 /* 1000Mbps, IDIV disabled (125 MHz) */
1985 rc = sja1105_cgu_idiv_config(priv, port, false, 1);
1986 } else if (speed == priv->info->port_speed[SJA1105_SPEED_100MBPS]) {
1987 /* 100Mbps, IDIV enabled, divide by 1 (25 MHz) */
1988 rc = sja1105_cgu_idiv_config(priv, port, true, 1);
1989 } else if (speed == priv->info->port_speed[SJA1105_SPEED_10MBPS]) {
1990 /* 10Mbps, IDIV enabled, divide by 10 (2.5 MHz) */
1991 rc = sja1105_cgu_idiv_config(priv, port, true, 10);
1992 } else if (speed == priv->info->port_speed[SJA1105_SPEED_AUTO]) {
1993 /* Skip CGU configuration if there is no speed available
1994 * (e.g. link is not established yet)
1995 */
1996 dev_dbg(dev, "Speed not available, skipping CGU config\n");
1997 return 0;
1998 } else {
1999 rc = -EINVAL;
2000 }
2001
2002 if (rc < 0) {
2003 dev_err(dev, "Failed to configure idiv\n");
2004 return rc;
2005 }
2006 rc = sja1105_cgu_rgmii_tx_clk_config(priv, port, speed);
2007 if (rc < 0) {
2008 dev_err(dev, "Failed to configure RGMII Tx clock\n");
2009 return rc;
2010 }
2011 rc = sja1105_rgmii_cfg_pad_tx_config(priv, port);
2012 if (rc < 0) {
2013 dev_err(dev, "Failed to configure Tx pad registers\n");
2014 return rc;
2015 }
2016
2017 if (!priv->info->setup_rgmii_delay)
2018 return 0;
2019
2020 return priv->info->setup_rgmii_delay(priv, port);
2021}
2022
2023static int sja1105_cgu_rmii_ref_clk_config(struct sja1105_private *priv,
2024 int port)
2025{
2026 const struct sja1105_regs *regs = priv->info->regs;
2027 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
2028 struct sja1105_cgu_mii_ctrl ref_clk;
2029 const int clk_sources[] = {
2030 CLKSRC_MII0_TX_CLK,
2031 CLKSRC_MII1_TX_CLK,
2032 CLKSRC_MII2_TX_CLK,
2033 CLKSRC_MII3_TX_CLK,
2034 CLKSRC_MII4_TX_CLK,
2035 };
2036
2037 if (regs->rmii_ref_clk[port] == SJA1105_RSV_ADDR)
2038 return 0;
2039
2040 /* Payload for packed_buf */
2041 ref_clk.clksrc = clk_sources[port];
2042 ref_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
2043 ref_clk.pd = 0; /* Power Down off => enabled */
2044 sja1105_cgu_mii_control_packing(packed_buf, &ref_clk, PACK);
2045
2046 return sja1105_xfer_buf(priv, SPI_WRITE, regs->rmii_ref_clk[port],
2047 packed_buf, SJA1105_SIZE_CGU_CMD);
2048}
2049
2050static int
2051sja1105_cgu_rmii_ext_tx_clk_config(struct sja1105_private *priv, int port)
2052{
2053 const struct sja1105_regs *regs = priv->info->regs;
2054 struct sja1105_cgu_mii_ctrl ext_tx_clk;
2055 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
2056
2057 if (regs->rmii_ext_tx_clk[port] == SJA1105_RSV_ADDR)
2058 return 0;
2059
2060 /* Payload for packed_buf */
2061 ext_tx_clk.clksrc = CLKSRC_PLL1;
2062 ext_tx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
2063 ext_tx_clk.pd = 0; /* Power Down off => enabled */
2064 sja1105_cgu_mii_control_packing(packed_buf, &ext_tx_clk, PACK);
2065
2066 return sja1105_xfer_buf(priv, SPI_WRITE, regs->rmii_ext_tx_clk[port],
2067 packed_buf, SJA1105_SIZE_CGU_CMD);
2068}
2069
2070static int sja1105_cgu_rmii_pll_config(struct sja1105_private *priv)
2071{
2072 const struct sja1105_regs *regs = priv->info->regs;
2073 u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
2074 struct sja1105_cgu_pll_ctrl pll = {0};
2075 int rc;
2076
2077 if (regs->rmii_pll1 == SJA1105_RSV_ADDR)
2078 return 0;
2079
2080 /* Step 1: PLL1 setup for 50Mhz */
2081 pll.pllclksrc = 0xA;
2082 pll.msel = 0x1;
2083 pll.autoblock = 0x1;
2084 pll.psel = 0x1;
2085 pll.direct = 0x0;
2086 pll.fbsel = 0x1;
2087 pll.bypass = 0x0;
2088 pll.pd = 0x1;
2089
2090 sja1105_cgu_pll_control_packing(packed_buf, &pll, PACK);
2091 rc = sja1105_xfer_buf(priv, SPI_WRITE, regs->rmii_pll1, packed_buf,
2092 SJA1105_SIZE_CGU_CMD);
2093 if (rc < 0)
2094 return rc;
2095
2096 /* Step 2: Enable PLL1 */
2097 pll.pd = 0x0;
2098
2099 sja1105_cgu_pll_control_packing(packed_buf, &pll, PACK);
2100 rc = sja1105_xfer_buf(priv, SPI_WRITE, regs->rmii_pll1, packed_buf,
2101 SJA1105_SIZE_CGU_CMD);
2102 return rc;
2103}
2104
2105static int sja1105_rmii_clocking_setup(struct sja1105_private *priv, int port,
2106 sja1105_mii_role_t role)
2107{
2108 int rc;
2109
2110 /* AH1601.pdf chapter 2.5.1. Sources */
2111 if (role == XMII_MAC) {
2112 /* Configure and enable PLL1 for 50Mhz output */
2113 rc = sja1105_cgu_rmii_pll_config(priv);
2114 if (rc < 0)
2115 return rc;
2116 }
2117 /* Disable IDIV for this port */
2118 rc = sja1105_cgu_idiv_config(priv, port, false, 1);
2119 if (rc < 0)
2120 return rc;
2121 /* Source to sink mappings */
2122 rc = sja1105_cgu_rmii_ref_clk_config(priv, port);
2123 if (rc < 0)
2124 return rc;
2125 if (role == XMII_MAC) {
2126 rc = sja1105_cgu_rmii_ext_tx_clk_config(priv, port);
2127 if (rc < 0)
2128 return rc;
2129 }
2130 return 0;
2131}
2132
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +03002133static int sja1105_pcs_read(struct sja1105_private *priv, int addr,
2134 int devad, int regnum)
2135{
2136 return priv->mdio_pcs->read(priv->mdio_pcs, addr, devad, regnum);
2137}
2138
2139static int sja1105_pcs_write(struct sja1105_private *priv, int addr,
2140 int devad, int regnum, u16 val)
2141{
2142 return priv->mdio_pcs->write(priv->mdio_pcs, addr, devad, regnum, val);
2143}
2144
2145/* In NXP SJA1105, the PCS is integrated with a PMA that has the TX lane
2146 * polarity inverted by default (PLUS is MINUS, MINUS is PLUS). To obtain
2147 * normal non-inverted behavior, the TX lane polarity must be inverted in the
2148 * PCS, via the DIGITAL_CONTROL_2 register.
2149 */
2150static int sja1105_pma_config(struct sja1105_private *priv, int port)
2151{
2152 return sja1105_pcs_write(priv, port, MDIO_MMD_VEND2,
2153 DW_VR_MII_DIG_CTRL2,
2154 DW_VR_MII_DIG_CTRL2_TX_POL_INV);
2155}
2156
2157static int sja1110_pma_config(struct sja1105_private *priv, int port)
2158{
2159 u16 txpll_fbdiv = 0x19, txpll_refdiv = 0x1;
2160 u16 rxpll_fbdiv = 0x19, rxpll_refdiv = 0x1;
2161 u16 rx_cdr_ctle = 0x212a;
2162 u16 val;
2163 int rc;
2164
2165 /* Program TX PLL feedback divider and reference divider settings for
2166 * correct oscillation frequency.
2167 */
2168 rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, SJA1110_TXPLL_CTRL0,
2169 SJA1110_TXPLL_FBDIV(txpll_fbdiv));
2170 if (rc < 0)
2171 return rc;
2172
2173 rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, SJA1110_TXPLL_CTRL1,
2174 SJA1110_TXPLL_REFDIV(txpll_refdiv));
2175 if (rc < 0)
2176 return rc;
2177
2178 /* Program transmitter amplitude and disable amplitude trimming */
2179 rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2,
2180 SJA1110_LANE_DRIVER1_0, SJA1110_TXDRV(0x5));
2181 if (rc < 0)
2182 return rc;
2183
2184 val = SJA1110_TXDRVTRIM_LSB(0xffffffull);
2185
2186 rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2,
2187 SJA1110_LANE_DRIVER2_0, val);
2188 if (rc < 0)
2189 return rc;
2190
2191 val = SJA1110_TXDRVTRIM_MSB(0xffffffull) | SJA1110_LANE_DRIVER2_1_RSV;
2192
2193 rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2,
2194 SJA1110_LANE_DRIVER2_1, val);
2195 if (rc < 0)
2196 return rc;
2197
2198 /* Enable input and output resistor terminations for low BER. */
2199 val = SJA1110_ACCOUPLE_RXVCM_EN | SJA1110_CDR_GAIN |
2200 SJA1110_RXRTRIM(4) | SJA1110_RXTEN | SJA1110_TXPLL_BWSEL |
2201 SJA1110_TXRTRIM(3) | SJA1110_TXTEN;
2202
2203 rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, SJA1110_LANE_TRIM,
2204 val);
2205 if (rc < 0)
2206 return rc;
2207
2208 /* Select PCS as transmitter data source. */
2209 rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2,
2210 SJA1110_LANE_DATAPATH_1, 0);
2211 if (rc < 0)
2212 return rc;
2213
2214 /* Program RX PLL feedback divider and reference divider for correct
2215 * oscillation frequency.
2216 */
2217 rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, SJA1110_RXPLL_CTRL0,
2218 SJA1110_RXPLL_FBDIV(rxpll_fbdiv));
2219 if (rc < 0)
2220 return rc;
2221
2222 rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, SJA1110_RXPLL_CTRL1,
2223 SJA1110_RXPLL_REFDIV(rxpll_refdiv));
2224 if (rc < 0)
2225 return rc;
2226
2227 /* Program threshold for receiver signal detector.
2228 * Enable control of RXPLL by receiver signal detector to disable RXPLL
2229 * when an input signal is not present.
2230 */
2231 rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2,
2232 SJA1110_RX_DATA_DETECT, 0x0005);
2233 if (rc < 0)
2234 return rc;
2235
2236 /* Enable TX and RX PLLs and circuits.
2237 * Release reset of PMA to enable data flow to/from PCS.
2238 */
2239 rc = sja1105_pcs_read(priv, port, MDIO_MMD_VEND2,
2240 SJA1110_POWERDOWN_ENABLE);
2241 if (rc < 0)
2242 return rc;
2243
2244 val = rc & ~(SJA1110_TXPLL_PD | SJA1110_TXPD | SJA1110_RXCH_PD |
2245 SJA1110_RXBIAS_PD | SJA1110_RESET_SER_EN |
2246 SJA1110_RESET_SER | SJA1110_RESET_DES);
2247 val |= SJA1110_RXPKDETEN | SJA1110_RCVEN;
2248
2249 rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2,
2250 SJA1110_POWERDOWN_ENABLE, val);
2251 if (rc < 0)
2252 return rc;
2253
2254 /* Program continuous-time linear equalizer (CTLE) settings. */
2255 rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, SJA1110_RX_CDR_CTLE,
2256 rx_cdr_ctle);
2257 if (rc < 0)
2258 return rc;
2259
2260 return 0;
2261}
2262
2263static int sja1105_xpcs_config_aneg_c37_sgmii(struct sja1105_private *priv,
2264 int port)
2265{
2266 int rc;
2267
2268 rc = sja1105_pcs_read(priv, port, MDIO_MMD_VEND2, MDIO_CTRL1);
2269 if (rc < 0)
2270 return rc;
2271 rc &= ~MDIO_AN_CTRL1_ENABLE;
2272 rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, MDIO_CTRL1,
2273 rc);
2274 if (rc < 0)
2275 return rc;
2276
2277 rc = sja1105_pcs_read(priv, port, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL);
2278 if (rc < 0)
2279 return rc;
2280
2281 rc &= ~(DW_VR_MII_PCS_MODE_MASK | DW_VR_MII_TX_CONFIG_MASK);
2282 rc |= (DW_VR_MII_PCS_MODE_C37_SGMII <<
2283 DW_VR_MII_AN_CTRL_PCS_MODE_SHIFT &
2284 DW_VR_MII_PCS_MODE_MASK);
2285 rc |= (DW_VR_MII_TX_CONFIG_MAC_SIDE_SGMII <<
2286 DW_VR_MII_AN_CTRL_TX_CONFIG_SHIFT &
2287 DW_VR_MII_TX_CONFIG_MASK);
2288 rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL,
2289 rc);
2290 if (rc < 0)
2291 return rc;
2292
2293 rc = sja1105_pcs_read(priv, port, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1);
2294 if (rc < 0)
2295 return rc;
2296
2297 if (priv->xpcs_cfg[port].inband_an)
2298 rc |= DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
2299 else
2300 rc &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
2301
2302 rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1,
2303 rc);
2304 if (rc < 0)
2305 return rc;
2306
2307 rc = sja1105_pcs_read(priv, port, MDIO_MMD_VEND2, MDIO_CTRL1);
2308 if (rc < 0)
2309 return rc;
2310
2311 if (priv->xpcs_cfg[port].inband_an)
2312 rc |= MDIO_AN_CTRL1_ENABLE;
2313 else
2314 rc &= ~MDIO_AN_CTRL1_ENABLE;
2315
2316 return sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, MDIO_CTRL1, rc);
2317}
2318
2319static int sja1105_xpcs_link_up_sgmii(struct sja1105_private *priv, int port)
2320{
2321 int val = BMCR_FULLDPLX;
2322
2323 if (priv->xpcs_cfg[port].inband_an)
2324 return 0;
2325
2326 switch (priv->xpcs_cfg[port].speed) {
2327 case SPEED_1000:
2328 val = BMCR_SPEED1000;
2329 break;
2330 case SPEED_100:
2331 val = BMCR_SPEED100;
2332 break;
2333 case SPEED_10:
2334 val = BMCR_SPEED10;
2335 break;
2336 default:
2337 dev_err(priv->dev, "Invalid PCS speed %d\n",
2338 priv->xpcs_cfg[port].speed);
2339 return -EINVAL;
2340 }
2341
2342 return sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, MDIO_CTRL1, val);
2343}
2344
2345static int sja1105_sgmii_setup(struct sja1105_private *priv, int port)
2346{
2347 int rc;
2348
2349 rc = sja1105_xpcs_config_aneg_c37_sgmii(priv, port);
2350 if (rc)
2351 return rc;
2352
2353 rc = sja1105_xpcs_link_up_sgmii(priv, port);
2354 if (rc)
2355 return rc;
2356
2357 return priv->info->pma_config(priv, port);
2358}
2359
Vladimir Olteanf24b6662021-09-29 18:04:41 +03002360static int sja1105_clocking_setup_port(struct sja1105_private *priv, int port)
2361{
2362 struct sja1105_xmii_params_entry *mii;
2363 sja1105_phy_interface_t phy_mode;
2364 sja1105_mii_role_t role;
2365 int rc;
2366
2367 mii = priv->static_config.tables[BLK_IDX_XMII_PARAMS].entries;
2368
2369 /* RGMII etc */
2370 phy_mode = mii->xmii_mode[port];
2371 /* MAC or PHY, for applicable types (not RGMII) */
2372 role = mii->phy_mac[port];
2373
2374 switch (phy_mode) {
2375 case XMII_MODE_MII:
2376 rc = sja1105_mii_clocking_setup(priv, port, role);
2377 break;
2378 case XMII_MODE_RMII:
2379 rc = sja1105_rmii_clocking_setup(priv, port, role);
2380 break;
2381 case XMII_MODE_RGMII:
2382 rc = sja1105_rgmii_clocking_setup(priv, port, role);
2383 break;
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +03002384 case XMII_MODE_SGMII:
2385 rc = sja1105_sgmii_setup(priv, port);
2386 break;
Vladimir Olteanf24b6662021-09-29 18:04:41 +03002387 default:
2388 return -EINVAL;
2389 }
2390 if (rc)
2391 return rc;
2392
2393 /* Internally pull down the RX_DV/CRS_DV/RX_CTL and RX_ER inputs */
2394 return sja1105_cfg_pad_rx_config(priv, port);
2395}
2396
2397static int sja1105_clocking_setup(struct sja1105_private *priv)
2398{
2399 struct dsa_pdata *pdata = dev_get_uclass_plat(priv->dev);
2400 int port, rc;
2401
2402 for (port = 0; port < pdata->num_ports; port++) {
2403 rc = sja1105_clocking_setup_port(priv, port);
2404 if (rc < 0)
2405 return rc;
2406 }
2407 return 0;
2408}
2409
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +03002410static int sja1105_pcs_mdio_read(struct mii_dev *bus, int phy, int mmd, int reg)
2411{
2412 u8 packed_buf[SJA1105_SIZE_MDIO_CMD] = {0};
2413 struct sja1105_private *priv = bus->priv;
2414 const int size = SJA1105_SIZE_MDIO_CMD;
2415 u64 addr, tmp;
2416 int rc;
2417
2418 if (mmd == MDIO_DEVAD_NONE)
2419 return -ENODEV;
2420
2421 if (!priv->info->supports_sgmii[phy])
2422 return -ENODEV;
2423
2424 addr = (mmd << 16) | (reg & GENMASK(15, 0));
2425
2426 if (mmd != MDIO_MMD_VEND1 && mmd != MDIO_MMD_VEND2)
2427 return 0xffff;
2428
2429 rc = sja1105_xfer_buf(priv, SPI_READ, addr, packed_buf, size);
2430 if (rc < 0)
2431 return rc;
2432
2433 sja1105_packing(packed_buf, &tmp, 31, 0, size, UNPACK);
2434
2435 return tmp & 0xffff;
2436}
2437
2438static int sja1105_pcs_mdio_write(struct mii_dev *bus, int phy, int mmd,
2439 int reg, u16 val)
2440{
2441 u8 packed_buf[SJA1105_SIZE_MDIO_CMD] = {0};
2442 struct sja1105_private *priv = bus->priv;
2443 const int size = SJA1105_SIZE_MDIO_CMD;
2444 u64 addr, tmp;
2445
2446 if (mmd == MDIO_DEVAD_NONE)
2447 return -ENODEV;
2448
2449 if (!priv->info->supports_sgmii[phy])
2450 return -ENODEV;
2451
2452 addr = (mmd << 16) | (reg & GENMASK(15, 0));
2453 tmp = val;
2454
2455 if (mmd != MDIO_MMD_VEND1 && mmd != MDIO_MMD_VEND2)
2456 return -ENODEV;
2457
2458 sja1105_packing(packed_buf, &tmp, 31, 0, size, PACK);
2459
2460 return sja1105_xfer_buf(priv, SPI_WRITE, addr, packed_buf, size);
2461}
2462
2463static int sja1110_pcs_mdio_read(struct mii_dev *bus, int phy, int mmd, int reg)
2464{
2465 struct sja1105_private *priv = bus->priv;
2466 const struct sja1105_regs *regs = priv->info->regs;
2467 u8 packed_buf[SJA1105_SIZE_MDIO_CMD] = {0};
2468 const int size = SJA1105_SIZE_MDIO_CMD;
2469 int offset, bank;
2470 u64 addr, tmp;
2471 int rc;
2472
2473 if (mmd == MDIO_DEVAD_NONE)
2474 return -ENODEV;
2475
2476 if (regs->pcs_base[phy] == SJA1105_RSV_ADDR)
2477 return -ENODEV;
2478
2479 addr = (mmd << 16) | (reg & GENMASK(15, 0));
2480
2481 bank = addr >> 8;
2482 offset = addr & GENMASK(7, 0);
2483
2484 /* This addressing scheme reserves register 0xff for the bank address
2485 * register, so that can never be addressed.
2486 */
2487 if (offset == 0xff)
2488 return -ENODEV;
2489
2490 tmp = bank;
2491
2492 sja1105_packing(packed_buf, &tmp, 31, 0, size, PACK);
2493
2494 rc = sja1105_xfer_buf(priv, SPI_WRITE,
2495 regs->pcs_base[phy] + SJA1110_PCS_BANK_REG,
2496 packed_buf, size);
2497 if (rc < 0)
2498 return rc;
2499
2500 rc = sja1105_xfer_buf(priv, SPI_READ, regs->pcs_base[phy] + offset,
2501 packed_buf, size);
2502 if (rc < 0)
2503 return rc;
2504
2505 sja1105_packing(packed_buf, &tmp, 31, 0, size, UNPACK);
2506
2507 return tmp & 0xffff;
2508}
2509
2510static int sja1110_pcs_mdio_write(struct mii_dev *bus, int phy, int mmd,
2511 int reg, u16 val)
2512{
2513 struct sja1105_private *priv = bus->priv;
2514 const struct sja1105_regs *regs = priv->info->regs;
2515 u8 packed_buf[SJA1105_SIZE_MDIO_CMD] = {0};
2516 const int size = SJA1105_SIZE_MDIO_CMD;
2517 int offset, bank;
2518 u64 addr, tmp;
2519 int rc;
2520
2521 if (mmd == MDIO_DEVAD_NONE)
2522 return -ENODEV;
2523
2524 if (regs->pcs_base[phy] == SJA1105_RSV_ADDR)
2525 return -ENODEV;
2526
2527 addr = (mmd << 16) | (reg & GENMASK(15, 0));
2528
2529 bank = addr >> 8;
2530 offset = addr & GENMASK(7, 0);
2531
2532 /* This addressing scheme reserves register 0xff for the bank address
2533 * register, so that can never be addressed.
2534 */
2535 if (offset == 0xff)
2536 return -ENODEV;
2537
2538 tmp = bank;
2539 sja1105_packing(packed_buf, &tmp, 31, 0, size, PACK);
2540
2541 rc = sja1105_xfer_buf(priv, SPI_WRITE,
2542 regs->pcs_base[phy] + SJA1110_PCS_BANK_REG,
2543 packed_buf, size);
2544 if (rc < 0)
2545 return rc;
2546
2547 tmp = val;
2548 sja1105_packing(packed_buf, &tmp, 31, 0, size, PACK);
2549
2550 return sja1105_xfer_buf(priv, SPI_WRITE, regs->pcs_base[phy] + offset,
2551 packed_buf, size);
2552}
2553
2554static int sja1105_mdiobus_register(struct sja1105_private *priv)
2555{
2556 struct udevice *dev = priv->dev;
2557 struct mii_dev *bus;
2558 int rc;
2559
2560 if (!priv->info->pcs_mdio_read || !priv->info->pcs_mdio_write)
2561 return 0;
2562
2563 bus = mdio_alloc();
2564 if (!bus)
2565 return -ENOMEM;
2566
2567 snprintf(bus->name, MDIO_NAME_LEN, "%s-pcs", dev->name);
2568 bus->read = priv->info->pcs_mdio_read;
2569 bus->write = priv->info->pcs_mdio_write;
2570 bus->priv = priv;
2571
2572 rc = mdio_register(bus);
2573 if (rc) {
2574 mdio_free(bus);
2575 return rc;
2576 }
2577
2578 priv->mdio_pcs = bus;
2579
2580 return 0;
2581}
2582
2583static void sja1105_mdiobus_unregister(struct sja1105_private *priv)
2584{
2585 if (!priv->mdio_pcs)
2586 return;
2587
2588 mdio_unregister(priv->mdio_pcs);
2589 mdio_free(priv->mdio_pcs);
2590}
2591
Vladimir Olteanf24b6662021-09-29 18:04:41 +03002592static const struct sja1105_regs sja1105et_regs = {
2593 .device_id = 0x0,
2594 .prod_id = 0x100BC3,
2595 .status = 0x1,
2596 .port_control = 0x11,
2597 .config = 0x020000,
2598 .rgu = 0x100440,
2599 /* UM10944.pdf, Table 86, ACU Register overview */
2600 .pad_mii_tx = {0x100800, 0x100802, 0x100804, 0x100806, 0x100808},
2601 .pad_mii_rx = {0x100801, 0x100803, 0x100805, 0x100807, 0x100809},
2602 .rmii_pll1 = 0x10000A,
2603 .cgu_idiv = {0x10000B, 0x10000C, 0x10000D, 0x10000E, 0x10000F},
2604 /* UM10944.pdf, Table 78, CGU Register overview */
2605 .mii_tx_clk = {0x100013, 0x10001A, 0x100021, 0x100028, 0x10002F},
2606 .mii_rx_clk = {0x100014, 0x10001B, 0x100022, 0x100029, 0x100030},
2607 .mii_ext_tx_clk = {0x100018, 0x10001F, 0x100026, 0x10002D, 0x100034},
2608 .mii_ext_rx_clk = {0x100019, 0x100020, 0x100027, 0x10002E, 0x100035},
2609 .rgmii_tx_clk = {0x100016, 0x10001D, 0x100024, 0x10002B, 0x100032},
2610 .rmii_ref_clk = {0x100015, 0x10001C, 0x100023, 0x10002A, 0x100031},
2611 .rmii_ext_tx_clk = {0x100018, 0x10001F, 0x100026, 0x10002D, 0x100034},
2612};
2613
2614static const struct sja1105_regs sja1105pqrs_regs = {
2615 .device_id = 0x0,
2616 .prod_id = 0x100BC3,
2617 .status = 0x1,
2618 .port_control = 0x12,
2619 .config = 0x020000,
2620 .rgu = 0x100440,
2621 /* UM10944.pdf, Table 86, ACU Register overview */
2622 .pad_mii_tx = {0x100800, 0x100802, 0x100804, 0x100806, 0x100808},
2623 .pad_mii_rx = {0x100801, 0x100803, 0x100805, 0x100807, 0x100809},
2624 .pad_mii_id = {0x100810, 0x100811, 0x100812, 0x100813, 0x100814},
2625 .rmii_pll1 = 0x10000A,
2626 .cgu_idiv = {0x10000B, 0x10000C, 0x10000D, 0x10000E, 0x10000F},
2627 /* UM11040.pdf, Table 114 */
2628 .mii_tx_clk = {0x100013, 0x100019, 0x10001F, 0x100025, 0x10002B},
2629 .mii_rx_clk = {0x100014, 0x10001A, 0x100020, 0x100026, 0x10002C},
2630 .mii_ext_tx_clk = {0x100017, 0x10001D, 0x100023, 0x100029, 0x10002F},
2631 .mii_ext_rx_clk = {0x100018, 0x10001E, 0x100024, 0x10002A, 0x100030},
2632 .rgmii_tx_clk = {0x100016, 0x10001C, 0x100022, 0x100028, 0x10002E},
2633 .rmii_ref_clk = {0x100015, 0x10001B, 0x100021, 0x100027, 0x10002D},
2634 .rmii_ext_tx_clk = {0x100017, 0x10001D, 0x100023, 0x100029, 0x10002F},
2635};
2636
2637static const struct sja1105_regs sja1110_regs = {
2638 .device_id = SJA1110_SPI_ADDR(0x0),
2639 .prod_id = SJA1110_ACU_ADDR(0xf00),
2640 .status = SJA1110_SPI_ADDR(0x4),
2641 .port_control = SJA1110_SPI_ADDR(0x50), /* actually INHIB_TX */
2642 .config = 0x020000,
2643 .rgu = SJA1110_RGU_ADDR(0x100), /* Reset Control Register 0 */
2644 /* Ports 2 and 3 are capable of xMII, but there isn't anything to
2645 * configure in the CGU/ACU for them.
2646 */
2647 .pad_mii_tx = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2648 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2649 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2650 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2651 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2652 SJA1105_RSV_ADDR},
2653 .pad_mii_rx = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2654 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2655 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2656 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2657 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2658 SJA1105_RSV_ADDR},
2659 .pad_mii_id = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2660 SJA1110_ACU_ADDR(0x18), SJA1110_ACU_ADDR(0x28),
2661 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2662 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2663 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2664 SJA1105_RSV_ADDR},
2665 .rmii_pll1 = SJA1105_RSV_ADDR,
2666 .cgu_idiv = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2667 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2668 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2669 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
2670 .mii_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2671 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2672 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2673 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
2674 .mii_rx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2675 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2676 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2677 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
2678 .mii_ext_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2679 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2680 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2681 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
2682 .mii_ext_rx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2683 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2684 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2685 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
2686 .rgmii_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2687 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2688 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2689 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
2690 .rmii_ref_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2691 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2692 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2693 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
2694 .rmii_ext_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2695 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2696 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2697 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2698 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2699 SJA1105_RSV_ADDR},
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +03002700 .pcs_base = {SJA1105_RSV_ADDR, 0x1c1400, 0x1c1800, 0x1c1c00, 0x1c2000,
2701 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
2702 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
Vladimir Olteanf24b6662021-09-29 18:04:41 +03002703};
2704
2705enum sja1105_switch_id {
2706 SJA1105E = 0,
2707 SJA1105T,
2708 SJA1105P,
2709 SJA1105Q,
2710 SJA1105R,
2711 SJA1105S,
2712 SJA1110A,
2713 SJA1110B,
2714 SJA1110C,
2715 SJA1110D,
2716 SJA1105_MAX_SWITCH_ID,
2717};
2718
2719static const struct sja1105_info sja1105_info[] = {
2720 [SJA1105E] = {
2721 .device_id = SJA1105E_DEVICE_ID,
2722 .part_no = SJA1105ET_PART_NO,
2723 .static_ops = sja1105et_table_ops,
2724 .reset_cmd = sja1105et_reset_cmd,
2725 .regs = &sja1105et_regs,
2726 .port_speed = {
2727 [SJA1105_SPEED_AUTO] = 0,
2728 [SJA1105_SPEED_10MBPS] = 3,
2729 [SJA1105_SPEED_100MBPS] = 2,
2730 [SJA1105_SPEED_1000MBPS] = 1,
2731 },
2732 .supports_mii = {true, true, true, true, true},
2733 .supports_rmii = {true, true, true, true, true},
2734 .supports_rgmii = {true, true, true, true, true},
2735 .name = "SJA1105E",
2736 },
2737 [SJA1105T] = {
2738 .device_id = SJA1105T_DEVICE_ID,
2739 .part_no = SJA1105ET_PART_NO,
2740 .static_ops = sja1105et_table_ops,
2741 .reset_cmd = sja1105et_reset_cmd,
2742 .regs = &sja1105et_regs,
2743 .port_speed = {
2744 [SJA1105_SPEED_AUTO] = 0,
2745 [SJA1105_SPEED_10MBPS] = 3,
2746 [SJA1105_SPEED_100MBPS] = 2,
2747 [SJA1105_SPEED_1000MBPS] = 1,
2748 },
2749 .supports_mii = {true, true, true, true, true},
2750 .supports_rmii = {true, true, true, true, true},
2751 .supports_rgmii = {true, true, true, true, true},
2752 .name = "SJA1105T",
2753 },
2754 [SJA1105P] = {
2755 .device_id = SJA1105PR_DEVICE_ID,
2756 .part_no = SJA1105P_PART_NO,
2757 .static_ops = sja1105pqrs_table_ops,
2758 .setup_rgmii_delay = sja1105pqrs_setup_rgmii_delay,
2759 .reset_cmd = sja1105pqrs_reset_cmd,
2760 .regs = &sja1105pqrs_regs,
2761 .port_speed = {
2762 [SJA1105_SPEED_AUTO] = 0,
2763 [SJA1105_SPEED_10MBPS] = 3,
2764 [SJA1105_SPEED_100MBPS] = 2,
2765 [SJA1105_SPEED_1000MBPS] = 1,
2766 },
2767 .supports_mii = {true, true, true, true, true},
2768 .supports_rmii = {true, true, true, true, true},
2769 .supports_rgmii = {true, true, true, true, true},
2770 .name = "SJA1105P",
2771 },
2772 [SJA1105Q] = {
2773 .device_id = SJA1105QS_DEVICE_ID,
2774 .part_no = SJA1105Q_PART_NO,
2775 .static_ops = sja1105pqrs_table_ops,
2776 .setup_rgmii_delay = sja1105pqrs_setup_rgmii_delay,
2777 .reset_cmd = sja1105pqrs_reset_cmd,
2778 .regs = &sja1105pqrs_regs,
2779 .port_speed = {
2780 [SJA1105_SPEED_AUTO] = 0,
2781 [SJA1105_SPEED_10MBPS] = 3,
2782 [SJA1105_SPEED_100MBPS] = 2,
2783 [SJA1105_SPEED_1000MBPS] = 1,
2784 },
2785 .supports_mii = {true, true, true, true, true},
2786 .supports_rmii = {true, true, true, true, true},
2787 .supports_rgmii = {true, true, true, true, true},
2788 .name = "SJA1105Q",
2789 },
2790 [SJA1105R] = {
2791 .device_id = SJA1105PR_DEVICE_ID,
2792 .part_no = SJA1105R_PART_NO,
2793 .static_ops = sja1105pqrs_table_ops,
2794 .setup_rgmii_delay = sja1105pqrs_setup_rgmii_delay,
2795 .reset_cmd = sja1105pqrs_reset_cmd,
2796 .regs = &sja1105pqrs_regs,
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +03002797 .pcs_mdio_read = sja1105_pcs_mdio_read,
2798 .pcs_mdio_write = sja1105_pcs_mdio_write,
2799 .pma_config = sja1105_pma_config,
Vladimir Olteanf24b6662021-09-29 18:04:41 +03002800 .port_speed = {
2801 [SJA1105_SPEED_AUTO] = 0,
2802 [SJA1105_SPEED_10MBPS] = 3,
2803 [SJA1105_SPEED_100MBPS] = 2,
2804 [SJA1105_SPEED_1000MBPS] = 1,
2805 },
2806 .supports_mii = {true, true, true, true, true},
2807 .supports_rmii = {true, true, true, true, true},
2808 .supports_rgmii = {true, true, true, true, true},
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +03002809 .supports_sgmii = {false, false, false, false, true},
Vladimir Olteanf24b6662021-09-29 18:04:41 +03002810 .name = "SJA1105R",
2811 },
2812 [SJA1105S] = {
2813 .device_id = SJA1105QS_DEVICE_ID,
2814 .part_no = SJA1105S_PART_NO,
2815 .static_ops = sja1105pqrs_table_ops,
2816 .setup_rgmii_delay = sja1105pqrs_setup_rgmii_delay,
2817 .reset_cmd = sja1105pqrs_reset_cmd,
2818 .regs = &sja1105pqrs_regs,
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +03002819 .pcs_mdio_read = sja1105_pcs_mdio_read,
2820 .pcs_mdio_write = sja1105_pcs_mdio_write,
2821 .pma_config = sja1105_pma_config,
Vladimir Olteanf24b6662021-09-29 18:04:41 +03002822 .port_speed = {
2823 [SJA1105_SPEED_AUTO] = 0,
2824 [SJA1105_SPEED_10MBPS] = 3,
2825 [SJA1105_SPEED_100MBPS] = 2,
2826 [SJA1105_SPEED_1000MBPS] = 1,
2827 },
2828 .supports_mii = {true, true, true, true, true},
2829 .supports_rmii = {true, true, true, true, true},
2830 .supports_rgmii = {true, true, true, true, true},
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +03002831 .supports_sgmii = {false, false, false, false, true},
Vladimir Olteanf24b6662021-09-29 18:04:41 +03002832 .name = "SJA1105S",
2833 },
2834 [SJA1110A] = {
2835 .device_id = SJA1110_DEVICE_ID,
2836 .part_no = SJA1110A_PART_NO,
2837 .static_ops = sja1110_table_ops,
2838 .setup_rgmii_delay = sja1110_setup_rgmii_delay,
2839 .reset_cmd = sja1110_reset_cmd,
2840 .regs = &sja1110_regs,
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +03002841 .pcs_mdio_read = sja1110_pcs_mdio_read,
2842 .pcs_mdio_write = sja1110_pcs_mdio_write,
2843 .pma_config = sja1110_pma_config,
Vladimir Olteanf24b6662021-09-29 18:04:41 +03002844 .port_speed = {
2845 [SJA1105_SPEED_AUTO] = 0,
2846 [SJA1105_SPEED_10MBPS] = 4,
2847 [SJA1105_SPEED_100MBPS] = 3,
2848 [SJA1105_SPEED_1000MBPS] = 2,
2849 },
2850 .supports_mii = {true, true, true, true, false,
2851 true, true, true, true, true, true},
2852 .supports_rmii = {false, false, true, true, false,
2853 false, false, false, false, false, false},
2854 .supports_rgmii = {false, false, true, true, false,
2855 false, false, false, false, false, false},
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +03002856 .supports_sgmii = {false, true, true, true, true,
2857 false, false, false, false, false, false},
Vladimir Olteanf24b6662021-09-29 18:04:41 +03002858 .name = "SJA1110A",
2859 },
2860 [SJA1110B] = {
2861 .device_id = SJA1110_DEVICE_ID,
2862 .part_no = SJA1110B_PART_NO,
2863 .static_ops = sja1110_table_ops,
2864 .setup_rgmii_delay = sja1110_setup_rgmii_delay,
2865 .reset_cmd = sja1110_reset_cmd,
2866 .regs = &sja1110_regs,
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +03002867 .pcs_mdio_read = sja1110_pcs_mdio_read,
2868 .pcs_mdio_write = sja1110_pcs_mdio_write,
2869 .pma_config = sja1110_pma_config,
Vladimir Olteanf24b6662021-09-29 18:04:41 +03002870 .port_speed = {
2871 [SJA1105_SPEED_AUTO] = 0,
2872 [SJA1105_SPEED_10MBPS] = 4,
2873 [SJA1105_SPEED_100MBPS] = 3,
2874 [SJA1105_SPEED_1000MBPS] = 2,
2875 },
2876 .supports_mii = {true, true, true, true, false,
2877 true, true, true, true, true, false},
2878 .supports_rmii = {false, false, true, true, false,
2879 false, false, false, false, false, false},
2880 .supports_rgmii = {false, false, true, true, false,
2881 false, false, false, false, false, false},
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +03002882 .supports_sgmii = {false, false, false, true, true,
2883 false, false, false, false, false, false},
Vladimir Olteanf24b6662021-09-29 18:04:41 +03002884 .name = "SJA1110B",
2885 },
2886 [SJA1110C] = {
2887 .device_id = SJA1110_DEVICE_ID,
2888 .part_no = SJA1110C_PART_NO,
2889 .static_ops = sja1110_table_ops,
2890 .setup_rgmii_delay = sja1110_setup_rgmii_delay,
2891 .reset_cmd = sja1110_reset_cmd,
2892 .regs = &sja1110_regs,
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +03002893 .pcs_mdio_read = sja1110_pcs_mdio_read,
2894 .pcs_mdio_write = sja1110_pcs_mdio_write,
2895 .pma_config = sja1110_pma_config,
Vladimir Olteanf24b6662021-09-29 18:04:41 +03002896 .port_speed = {
2897 [SJA1105_SPEED_AUTO] = 0,
2898 [SJA1105_SPEED_10MBPS] = 4,
2899 [SJA1105_SPEED_100MBPS] = 3,
2900 [SJA1105_SPEED_1000MBPS] = 2,
2901 },
2902 .supports_mii = {true, true, true, true, false,
2903 true, true, true, false, false, false},
2904 .supports_rmii = {false, false, true, true, false,
2905 false, false, false, false, false, false},
2906 .supports_rgmii = {false, false, true, true, false,
2907 false, false, false, false, false, false},
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +03002908 .supports_sgmii = {false, false, false, false, true,
2909 false, false, false, false, false, false},
Vladimir Olteanf24b6662021-09-29 18:04:41 +03002910 .name = "SJA1110C",
2911 },
2912 [SJA1110D] = {
2913 .device_id = SJA1110_DEVICE_ID,
2914 .part_no = SJA1110D_PART_NO,
2915 .static_ops = sja1110_table_ops,
2916 .setup_rgmii_delay = sja1110_setup_rgmii_delay,
2917 .reset_cmd = sja1110_reset_cmd,
2918 .regs = &sja1110_regs,
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +03002919 .pcs_mdio_read = sja1110_pcs_mdio_read,
2920 .pcs_mdio_write = sja1110_pcs_mdio_write,
2921 .pma_config = sja1110_pma_config,
Vladimir Olteanf24b6662021-09-29 18:04:41 +03002922 .port_speed = {
2923 [SJA1105_SPEED_AUTO] = 0,
2924 [SJA1105_SPEED_10MBPS] = 4,
2925 [SJA1105_SPEED_100MBPS] = 3,
2926 [SJA1105_SPEED_1000MBPS] = 2,
2927 },
2928 .supports_mii = {true, false, true, false, false,
2929 true, true, true, false, false, false},
2930 .supports_rmii = {false, false, true, false, false,
2931 false, false, false, false, false, false},
2932 .supports_rgmii = {false, false, true, false, false,
2933 false, false, false, false, false, false},
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +03002934 .supports_sgmii = {false, true, true, true, true,
2935 false, false, false, false, false, false},
Vladimir Olteanf24b6662021-09-29 18:04:41 +03002936 .name = "SJA1110D",
2937 },
2938};
2939
2940struct sja1105_status {
2941 u64 configs;
2942 u64 crcchkl;
2943 u64 ids;
2944 u64 crcchkg;
2945};
2946
2947static void sja1105_status_unpack(void *buf, struct sja1105_status *status)
2948{
2949 sja1105_packing(buf, &status->configs, 31, 31, 4, UNPACK);
2950 sja1105_packing(buf, &status->crcchkl, 30, 30, 4, UNPACK);
2951 sja1105_packing(buf, &status->ids, 29, 29, 4, UNPACK);
2952 sja1105_packing(buf, &status->crcchkg, 28, 28, 4, UNPACK);
2953}
2954
2955static int sja1105_status_get(struct sja1105_private *priv,
2956 struct sja1105_status *status)
2957{
2958 const struct sja1105_regs *regs = priv->info->regs;
2959 u8 packed_buf[4];
2960 int rc;
2961
2962 rc = sja1105_xfer_buf(priv, SPI_READ, regs->status, packed_buf, 4);
2963 if (rc < 0)
2964 return rc;
2965
2966 sja1105_status_unpack(packed_buf, status);
2967
2968 return 0;
2969}
2970
2971/* Not const because unpacking priv->static_config into buffers and preparing
2972 * for upload requires the recalculation of table CRCs and updating the
2973 * structures with these.
2974 */
2975static int
2976static_config_buf_prepare_for_upload(struct sja1105_private *priv,
2977 void *config_buf, int buf_len)
2978{
2979 struct sja1105_static_config *config = &priv->static_config;
2980 struct sja1105_table_header final_header;
2981 char *final_header_ptr;
2982 int crc_len;
2983
2984 /* Write Device ID and config tables to config_buf */
2985 sja1105_static_config_pack(config_buf, config);
2986 /* Recalculate CRC of the last header (right now 0xDEADBEEF).
2987 * Don't include the CRC field itself.
2988 */
2989 crc_len = buf_len - 4;
2990 /* Read the whole table header */
2991 final_header_ptr = config_buf + buf_len - SJA1105_SIZE_TABLE_HEADER;
2992 sja1105_table_header_packing(final_header_ptr, &final_header, UNPACK);
2993 /* Modify */
2994 final_header.crc = sja1105_crc32(config_buf, crc_len);
2995 /* Rewrite */
2996 sja1105_table_header_packing(final_header_ptr, &final_header, PACK);
2997
2998 return 0;
2999}
3000
3001static int sja1105_static_config_upload(struct sja1105_private *priv)
3002{
3003 struct sja1105_static_config *config = &priv->static_config;
3004 const struct sja1105_regs *regs = priv->info->regs;
3005 struct sja1105_status status;
3006 u8 *config_buf;
3007 int buf_len;
3008 int rc;
3009
3010 buf_len = sja1105_static_config_get_length(config);
3011 config_buf = calloc(buf_len, sizeof(char));
3012 if (!config_buf)
3013 return -ENOMEM;
3014
3015 rc = static_config_buf_prepare_for_upload(priv, config_buf, buf_len);
3016 if (rc < 0) {
3017 printf("Invalid config, cannot upload\n");
3018 rc = -EINVAL;
3019 goto out;
3020 }
3021 /* Put the SJA1105 in programming mode */
3022 rc = priv->info->reset_cmd(priv);
3023 if (rc < 0) {
3024 printf("Failed to reset switch\n");
3025 goto out;
3026 }
3027 /* Wait for the switch to come out of reset */
3028 udelay(1000);
3029 /* Upload the static config to the device */
3030 rc = sja1105_xfer_buf(priv, SPI_WRITE, regs->config,
3031 config_buf, buf_len);
3032 if (rc < 0) {
3033 printf("Failed to upload config\n");
3034 goto out;
3035 }
3036 /* Check that SJA1105 responded well to the config upload */
3037 rc = sja1105_status_get(priv, &status);
3038 if (rc < 0)
3039 goto out;
3040
3041 if (status.ids == 1) {
3042 printf("Mismatch between hardware and static config device id. "
3043 "Wrote 0x%llx, wants 0x%llx\n",
3044 config->device_id, priv->info->device_id);
3045 rc = -EIO;
3046 goto out;
3047 }
3048 if (status.crcchkl == 1 || status.crcchkg == 1) {
3049 printf("Switch reported invalid CRC on static config\n");
3050 rc = -EIO;
3051 goto out;
3052 }
3053 if (status.configs == 0) {
3054 printf("Switch reported that config is invalid\n");
3055 rc = -EIO;
3056 goto out;
3057 }
3058
3059out:
3060 free(config_buf);
3061 return rc;
3062}
3063
3064static int sja1105_static_config_reload(struct sja1105_private *priv)
3065{
3066 int rc;
3067
3068 rc = sja1105_static_config_upload(priv);
3069 if (rc < 0) {
3070 printf("Failed to load static config: %d\n", rc);
3071 return rc;
3072 }
3073
3074 /* Configure the CGU (PHY link modes and speeds) */
3075 rc = sja1105_clocking_setup(priv);
3076 if (rc < 0) {
3077 printf("Failed to configure MII clocking: %d\n", rc);
3078 return rc;
3079 }
3080
3081 return 0;
3082}
3083
3084static int sja1105_port_probe(struct udevice *dev, int port,
3085 struct phy_device *phy)
3086{
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +03003087 struct sja1105_private *priv = dev_get_priv(dev);
3088 ofnode node = dsa_port_get_ofnode(dev, port);
Vladimir Olteanf24b6662021-09-29 18:04:41 +03003089 phy_interface_t phy_mode = phy->interface;
3090
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +03003091 priv->xpcs_cfg[port].inband_an = ofnode_eth_uses_inband_aneg(node);
3092
Vladimir Olteanf24b6662021-09-29 18:04:41 +03003093 if (phy_mode == PHY_INTERFACE_MODE_MII ||
3094 phy_mode == PHY_INTERFACE_MODE_RMII) {
3095 phy->supported &= PHY_BASIC_FEATURES;
3096 phy->advertising &= PHY_BASIC_FEATURES;
3097 } else {
3098 phy->supported &= PHY_GBIT_FEATURES;
3099 phy->advertising &= PHY_GBIT_FEATURES;
3100 }
3101
3102 return phy_config(phy);
3103}
3104
3105static int sja1105_port_enable(struct udevice *dev, int port,
3106 struct phy_device *phy)
3107{
3108 struct sja1105_private *priv = dev_get_priv(dev);
3109 phy_interface_t phy_mode = phy->interface;
3110 struct sja1105_xmii_params_entry *mii;
3111 struct sja1105_mac_config_entry *mac;
3112 int rc;
3113
3114 rc = phy_startup(phy);
3115 if (rc)
3116 return rc;
3117
3118 mii = priv->static_config.tables[BLK_IDX_XMII_PARAMS].entries;
3119 mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries;
3120
3121 switch (phy_mode) {
3122 case PHY_INTERFACE_MODE_MII:
3123 if (!priv->info->supports_mii[port])
3124 goto unsupported;
3125
3126 mii->xmii_mode[port] = XMII_MODE_MII;
3127 break;
3128 case PHY_INTERFACE_MODE_RMII:
3129 if (!priv->info->supports_rmii[port])
3130 goto unsupported;
3131
3132 mii->xmii_mode[port] = XMII_MODE_RMII;
3133 break;
3134 case PHY_INTERFACE_MODE_RGMII:
3135 case PHY_INTERFACE_MODE_RGMII_ID:
3136 case PHY_INTERFACE_MODE_RGMII_RXID:
3137 case PHY_INTERFACE_MODE_RGMII_TXID:
3138 if (!priv->info->supports_rgmii[port])
3139 goto unsupported;
3140
3141 mii->xmii_mode[port] = XMII_MODE_RGMII;
3142 break;
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +03003143 case PHY_INTERFACE_MODE_SGMII:
3144 if (!priv->info->supports_sgmii[port])
3145 goto unsupported;
3146
3147 mii->xmii_mode[port] = XMII_MODE_SGMII;
3148 mii->special[port] = true;
3149 break;
Vladimir Olteanf24b6662021-09-29 18:04:41 +03003150unsupported:
3151 default:
3152 dev_err(dev, "Unsupported PHY mode %d on port %d!\n",
3153 phy_mode, port);
3154 return -EINVAL;
3155 }
3156
3157 /* RevMII, RevRMII not supported */
3158 mii->phy_mac[port] = XMII_MAC;
3159
3160 /* Let the PHY handle the RGMII delays, if present. */
3161 if (phy->phy_id == PHY_FIXED_ID) {
3162 if (phy_mode == PHY_INTERFACE_MODE_RGMII_RXID ||
3163 phy_mode == PHY_INTERFACE_MODE_RGMII_ID)
3164 priv->rgmii_rx_delay[port] = true;
3165
3166 if (phy_mode == PHY_INTERFACE_MODE_RGMII_TXID ||
3167 phy_mode == PHY_INTERFACE_MODE_RGMII_ID)
3168 priv->rgmii_tx_delay[port] = true;
3169
3170 if ((priv->rgmii_rx_delay[port] ||
3171 priv->rgmii_tx_delay[port]) &&
3172 !priv->info->setup_rgmii_delay) {
3173 printf("Chip does not support internal RGMII delays\n");
3174 return -EINVAL;
3175 }
3176 }
3177
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +03003178 if (mii->xmii_mode[port] == XMII_MODE_SGMII) {
3179 mac[port].speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS];
3180 priv->xpcs_cfg[port].speed = phy->speed;
3181 } else if (phy->speed == SPEED_1000) {
Vladimir Olteanf24b6662021-09-29 18:04:41 +03003182 mac[port].speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS];
3183 } else if (phy->speed == SPEED_100) {
3184 mac[port].speed = priv->info->port_speed[SJA1105_SPEED_100MBPS];
3185 } else if (phy->speed == SPEED_10) {
3186 mac[port].speed = priv->info->port_speed[SJA1105_SPEED_10MBPS];
3187 } else {
3188 printf("Invalid PHY speed %d on port %d\n", phy->speed, port);
3189 return -EINVAL;
3190 }
3191
3192 return sja1105_static_config_reload(priv);
3193}
3194
3195static void sja1105_port_disable(struct udevice *dev, int port,
3196 struct phy_device *phy)
3197{
3198 phy_shutdown(phy);
3199}
3200
3201static int sja1105_xmit(struct udevice *dev, int port, void *packet, int length)
3202{
3203 struct sja1105_private *priv = dev_get_priv(dev);
3204 u8 *from = (u8 *)packet + VLAN_HLEN;
3205 struct vlan_ethhdr *hdr = packet;
3206 u8 *dest = (u8 *)packet;
3207
3208 memmove(dest, from, 2 * ETH_ALEN);
3209 hdr->h_vlan_proto = htons(ETH_P_SJA1105);
3210 hdr->h_vlan_TCI = htons(priv->pvid[port]);
3211
3212 return 0;
3213}
3214
3215static int sja1105_rcv(struct udevice *dev, int *port, void *packet, int length)
3216{
3217 struct vlan_ethhdr *hdr = packet;
3218 u8 *dest = packet + VLAN_HLEN;
3219 u8 *from = packet;
3220
3221 if (ntohs(hdr->h_vlan_proto) != ETH_P_SJA1105)
3222 return -EINVAL;
3223
3224 *port = ntohs(hdr->h_vlan_TCI) & DSA_8021Q_PORT_MASK;
3225 memmove(dest, from, 2 * ETH_ALEN);
3226
3227 return 0;
3228}
3229
3230static const struct dsa_ops sja1105_dsa_ops = {
3231 .port_probe = sja1105_port_probe,
3232 .port_enable = sja1105_port_enable,
3233 .port_disable = sja1105_port_disable,
3234 .xmit = sja1105_xmit,
3235 .rcv = sja1105_rcv,
3236};
3237
3238static int sja1105_init(struct sja1105_private *priv)
3239{
3240 int rc;
3241
3242 rc = sja1105_static_config_init(priv);
3243 if (rc) {
3244 printf("Failed to initialize static config: %d\n", rc);
3245 return rc;
3246 }
3247
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +03003248 rc = sja1105_mdiobus_register(priv);
3249 if (rc) {
3250 printf("Failed to register MDIO bus: %d\n", rc);
3251 goto err_mdiobus_register;
3252 }
3253
Vladimir Olteanf24b6662021-09-29 18:04:41 +03003254 return 0;
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +03003255
3256err_mdiobus_register:
3257 sja1105_static_config_free(&priv->static_config);
3258
3259 return rc;
Vladimir Olteanf24b6662021-09-29 18:04:41 +03003260}
3261
3262static int sja1105_check_device_id(struct sja1105_private *priv)
3263{
3264 const struct sja1105_regs *regs = priv->info->regs;
3265 u8 packed_buf[SJA1105_SIZE_DEVICE_ID] = {0};
3266 enum sja1105_switch_id id;
3267 u64 device_id;
3268 u64 part_no;
3269 int rc;
3270
3271 rc = sja1105_xfer_buf(priv, SPI_READ, regs->device_id, packed_buf,
3272 SJA1105_SIZE_DEVICE_ID);
3273 if (rc < 0)
3274 return rc;
3275
3276 sja1105_packing(packed_buf, &device_id, 31, 0, SJA1105_SIZE_DEVICE_ID,
3277 UNPACK);
3278
Vladimir Olteanf24b6662021-09-29 18:04:41 +03003279 rc = sja1105_xfer_buf(priv, SPI_READ, regs->prod_id, packed_buf,
3280 SJA1105_SIZE_DEVICE_ID);
3281 if (rc < 0)
3282 return rc;
3283
3284 sja1105_packing(packed_buf, &part_no, 19, 4, SJA1105_SIZE_DEVICE_ID,
3285 UNPACK);
3286
3287 for (id = 0; id < SJA1105_MAX_SWITCH_ID; id++) {
3288 const struct sja1105_info *info = &sja1105_info[id];
3289
3290 /* Is what's been probed in our match table at all? */
3291 if (info->device_id != device_id || info->part_no != part_no)
3292 continue;
3293
3294 /* But is it what's in the device tree? */
3295 if (priv->info->device_id != device_id ||
3296 priv->info->part_no != part_no) {
3297 printf("Device tree specifies chip %s but found %s, please fix it!\n",
3298 priv->info->name, info->name);
3299 /* It isn't. No problem, pick that up. */
3300 priv->info = info;
3301 }
3302
3303 return 0;
3304 }
3305
3306 printf("Unexpected {device ID, part number}: 0x%llx 0x%llx\n",
3307 device_id, part_no);
3308
3309 return -ENODEV;
3310}
3311
3312static int sja1105_probe(struct udevice *dev)
3313{
3314 enum sja1105_switch_id id = dev_get_driver_data(dev);
3315 struct sja1105_private *priv = dev_get_priv(dev);
3316 int rc;
3317
3318 if (ofnode_valid(dev_ofnode(dev)) &&
Simon Glass89090662022-09-06 20:27:17 -06003319 !ofnode_is_enabled(dev_ofnode(dev))) {
Vladimir Olteanf24b6662021-09-29 18:04:41 +03003320 dev_dbg(dev, "switch disabled\n");
3321 return -ENODEV;
3322 }
3323
3324 priv->info = &sja1105_info[id];
3325 priv->dev = dev;
3326
3327 rc = sja1105_check_device_id(priv);
3328 if (rc < 0) {
3329 dev_err(dev, "Device ID check failed: %d\n", rc);
3330 return rc;
3331 }
3332
3333 dsa_set_tagging(dev, VLAN_HLEN, 0);
3334
3335 return sja1105_init(priv);
3336}
3337
3338static int sja1105_remove(struct udevice *dev)
3339{
3340 struct sja1105_private *priv = dev_get_priv(dev);
3341
Vladimir Oltean7f7e73e2021-09-29 18:04:42 +03003342 sja1105_mdiobus_unregister(priv);
Vladimir Olteanf24b6662021-09-29 18:04:41 +03003343 sja1105_static_config_free(&priv->static_config);
3344
3345 return 0;
3346}
3347
3348static const struct udevice_id sja1105_ids[] = {
3349 { .compatible = "nxp,sja1105e", .data = SJA1105E },
3350 { .compatible = "nxp,sja1105t", .data = SJA1105T },
3351 { .compatible = "nxp,sja1105p", .data = SJA1105P },
3352 { .compatible = "nxp,sja1105q", .data = SJA1105Q },
3353 { .compatible = "nxp,sja1105r", .data = SJA1105R },
3354 { .compatible = "nxp,sja1105s", .data = SJA1105S },
3355 { .compatible = "nxp,sja1110a", .data = SJA1110A },
3356 { .compatible = "nxp,sja1110b", .data = SJA1110B },
3357 { .compatible = "nxp,sja1110c", .data = SJA1110C },
3358 { .compatible = "nxp,sja1110d", .data = SJA1110D },
3359 { }
3360};
3361
3362U_BOOT_DRIVER(sja1105) = {
3363 .name = "sja1105",
3364 .id = UCLASS_DSA,
3365 .of_match = sja1105_ids,
3366 .probe = sja1105_probe,
3367 .remove = sja1105_remove,
3368 .ops = &sja1105_dsa_ops,
3369 .priv_auto = sizeof(struct sja1105_private),
3370};