powerpc/mm: Avoid calling arch_enter/leave_lazy_mmu() in set_ptes
[platform/kernel/linux-starfive.git] / drivers / net / ethernet / ti / icssg / icssg_config.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* ICSSG Ethernet driver
3  *
4  * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com
5  */
6
7 #include <linux/iopoll.h>
8 #include <linux/regmap.h>
9 #include <uapi/linux/if_ether.h>
10 #include "icssg_config.h"
11 #include "icssg_prueth.h"
12 #include "icssg_switch_map.h"
13 #include "icssg_mii_rt.h"
14
15 /* TX IPG Values to be set for 100M link speed. These values are
16  * in ocp_clk cycles. So need change if ocp_clk is changed for a specific
17  * h/w design.
18  */
19
20 /* IPG is in core_clk cycles */
21 #define MII_RT_TX_IPG_100M      0x17
22 #define MII_RT_TX_IPG_1G        0xb
23
24 #define ICSSG_QUEUES_MAX                64
25 #define ICSSG_QUEUE_OFFSET              0xd00
26 #define ICSSG_QUEUE_PEEK_OFFSET         0xe00
27 #define ICSSG_QUEUE_CNT_OFFSET          0xe40
28 #define ICSSG_QUEUE_RESET_OFFSET        0xf40
29
30 #define ICSSG_NUM_TX_QUEUES     8
31
32 #define RECYCLE_Q_SLICE0        16
33 #define RECYCLE_Q_SLICE1        17
34
35 #define ICSSG_NUM_OTHER_QUEUES  5       /* port, host and special queues */
36
37 #define PORT_HI_Q_SLICE0        32
38 #define PORT_LO_Q_SLICE0        33
39 #define HOST_HI_Q_SLICE0        34
40 #define HOST_LO_Q_SLICE0        35
41 #define HOST_SPL_Q_SLICE0       40      /* Special Queue */
42
43 #define PORT_HI_Q_SLICE1        36
44 #define PORT_LO_Q_SLICE1        37
45 #define HOST_HI_Q_SLICE1        38
46 #define HOST_LO_Q_SLICE1        39
47 #define HOST_SPL_Q_SLICE1       41      /* Special Queue */
48
49 #define MII_RXCFG_DEFAULT       (PRUSS_MII_RT_RXCFG_RX_ENABLE | \
50                                  PRUSS_MII_RT_RXCFG_RX_DATA_RDY_MODE_DIS | \
51                                  PRUSS_MII_RT_RXCFG_RX_L2_EN | \
52                                  PRUSS_MII_RT_RXCFG_RX_L2_EOF_SCLR_DIS)
53
54 #define MII_TXCFG_DEFAULT       (PRUSS_MII_RT_TXCFG_TX_ENABLE | \
55                                  PRUSS_MII_RT_TXCFG_TX_AUTO_PREAMBLE | \
56                                  PRUSS_MII_RT_TXCFG_TX_32_MODE_EN | \
57                                  PRUSS_MII_RT_TXCFG_TX_IPG_WIRE_CLK_EN)
58
59 #define ICSSG_CFG_DEFAULT       (ICSSG_CFG_TX_L1_EN | \
60                                  ICSSG_CFG_TX_L2_EN | ICSSG_CFG_RX_L2_G_EN | \
61                                  ICSSG_CFG_TX_PRU_EN | \
62                                  ICSSG_CFG_SGMII_MODE)
63
64 #define FDB_GEN_CFG1            0x60
65 #define SMEM_VLAN_OFFSET        8
66 #define SMEM_VLAN_OFFSET_MASK   GENMASK(25, 8)
67
68 #define FDB_GEN_CFG2            0x64
69 #define FDB_VLAN_EN             BIT(6)
70 #define FDB_HOST_EN             BIT(2)
71 #define FDB_PRU1_EN             BIT(1)
72 #define FDB_PRU0_EN             BIT(0)
73 #define FDB_EN_ALL              (FDB_PRU0_EN | FDB_PRU1_EN | \
74                                  FDB_HOST_EN | FDB_VLAN_EN)
75
76 /**
77  * struct map - ICSSG Queue Map
78  * @queue: Queue number
79  * @pd_addr_start: Packet descriptor queue reserved memory
80  * @flags: Flags
81  * @special: Indicates whether this queue is a special queue or not
82  */
83 struct map {
84         int queue;
85         u32 pd_addr_start;
86         u32 flags;
87         bool special;
88 };
89
90 /* Hardware queue map for ICSSG */
91 static const struct map hwq_map[2][ICSSG_NUM_OTHER_QUEUES] = {
92         {
93                 { PORT_HI_Q_SLICE0, PORT_DESC0_HI, 0x200000, 0 },
94                 { PORT_LO_Q_SLICE0, PORT_DESC0_LO, 0, 0 },
95                 { HOST_HI_Q_SLICE0, HOST_DESC0_HI, 0x200000, 0 },
96                 { HOST_LO_Q_SLICE0, HOST_DESC0_LO, 0, 0 },
97                 { HOST_SPL_Q_SLICE0, HOST_SPPD0, 0x400000, 1 },
98         },
99         {
100                 { PORT_HI_Q_SLICE1, PORT_DESC1_HI, 0xa00000, 0 },
101                 { PORT_LO_Q_SLICE1, PORT_DESC1_LO, 0x800000, 0 },
102                 { HOST_HI_Q_SLICE1, HOST_DESC1_HI, 0xa00000, 0 },
103                 { HOST_LO_Q_SLICE1, HOST_DESC1_LO, 0x800000, 0 },
104                 { HOST_SPL_Q_SLICE1, HOST_SPPD1, 0xc00000, 1 },
105         },
106 };
107
108 static void icssg_config_mii_init(struct prueth_emac *emac)
109 {
110         u32 rxcfg, txcfg, rxcfg_reg, txcfg_reg, pcnt_reg;
111         struct prueth *prueth = emac->prueth;
112         int slice = prueth_emac_slice(emac);
113         struct regmap *mii_rt;
114
115         mii_rt = prueth->mii_rt;
116
117         rxcfg_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_RXCFG0 :
118                                        PRUSS_MII_RT_RXCFG1;
119         txcfg_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_TXCFG0 :
120                                        PRUSS_MII_RT_TXCFG1;
121         pcnt_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_RX_PCNT0 :
122                                        PRUSS_MII_RT_RX_PCNT1;
123
124         rxcfg = MII_RXCFG_DEFAULT;
125         txcfg = MII_TXCFG_DEFAULT;
126
127         if (slice == ICSS_MII1)
128                 rxcfg |= PRUSS_MII_RT_RXCFG_RX_MUX_SEL;
129
130         /* In MII mode TX lines swapped inside ICSSG, so TX_MUX_SEL cfg need
131          * to be swapped also comparing to RGMII mode.
132          */
133         if (emac->phy_if == PHY_INTERFACE_MODE_MII && slice == ICSS_MII0)
134                 txcfg |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL;
135         else if (emac->phy_if != PHY_INTERFACE_MODE_MII && slice == ICSS_MII1)
136                 txcfg |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL;
137
138         regmap_write(mii_rt, rxcfg_reg, rxcfg);
139         regmap_write(mii_rt, txcfg_reg, txcfg);
140         regmap_write(mii_rt, pcnt_reg, 0x1);
141 }
142
143 static void icssg_miig_queues_init(struct prueth *prueth, int slice)
144 {
145         struct regmap *miig_rt = prueth->miig_rt;
146         void __iomem *smem = prueth->shram.va;
147         u8 pd[ICSSG_SPECIAL_PD_SIZE];
148         int queue = 0, i, j;
149         u32 *pdword;
150
151         /* reset hwqueues */
152         if (slice)
153                 queue = ICSSG_NUM_TX_QUEUES;
154
155         for (i = 0; i < ICSSG_NUM_TX_QUEUES; i++) {
156                 regmap_write(miig_rt, ICSSG_QUEUE_RESET_OFFSET, queue);
157                 queue++;
158         }
159
160         queue = slice ? RECYCLE_Q_SLICE1 : RECYCLE_Q_SLICE0;
161         regmap_write(miig_rt, ICSSG_QUEUE_RESET_OFFSET, queue);
162
163         for (i = 0; i < ICSSG_NUM_OTHER_QUEUES; i++) {
164                 regmap_write(miig_rt, ICSSG_QUEUE_RESET_OFFSET,
165                              hwq_map[slice][i].queue);
166         }
167
168         /* initialize packet descriptors in SMEM */
169         /* push pakcet descriptors to hwqueues */
170
171         pdword = (u32 *)pd;
172         for (j = 0; j < ICSSG_NUM_OTHER_QUEUES; j++) {
173                 const struct map *mp;
174                 int pd_size, num_pds;
175                 u32 pdaddr;
176
177                 mp = &hwq_map[slice][j];
178                 if (mp->special) {
179                         pd_size = ICSSG_SPECIAL_PD_SIZE;
180                         num_pds = ICSSG_NUM_SPECIAL_PDS;
181                 } else  {
182                         pd_size = ICSSG_NORMAL_PD_SIZE;
183                         num_pds = ICSSG_NUM_NORMAL_PDS;
184                 }
185
186                 for (i = 0; i < num_pds; i++) {
187                         memset(pd, 0, pd_size);
188
189                         pdword[0] &= ICSSG_FLAG_MASK;
190                         pdword[0] |= mp->flags;
191                         pdaddr = mp->pd_addr_start + i * pd_size;
192
193                         memcpy_toio(smem + pdaddr, pd, pd_size);
194                         queue = mp->queue;
195                         regmap_write(miig_rt, ICSSG_QUEUE_OFFSET + 4 * queue,
196                                      pdaddr);
197                 }
198         }
199 }
200
201 void icssg_config_ipg(struct prueth_emac *emac)
202 {
203         struct prueth *prueth = emac->prueth;
204         int slice = prueth_emac_slice(emac);
205
206         switch (emac->speed) {
207         case SPEED_1000:
208                 icssg_mii_update_ipg(prueth->mii_rt, slice, MII_RT_TX_IPG_1G);
209                 break;
210         case SPEED_100:
211                 icssg_mii_update_ipg(prueth->mii_rt, slice, MII_RT_TX_IPG_100M);
212                 break;
213         case SPEED_10:
214                 /* IPG for 10M is same as 100M */
215                 icssg_mii_update_ipg(prueth->mii_rt, slice, MII_RT_TX_IPG_100M);
216                 break;
217         default:
218                 /* Other links speeds not supported */
219                 netdev_err(emac->ndev, "Unsupported link speed\n");
220                 return;
221         }
222 }
223
224 static void emac_r30_cmd_init(struct prueth_emac *emac)
225 {
226         struct icssg_r30_cmd __iomem *p;
227         int i;
228
229         p = emac->dram.va + MGR_R30_CMD_OFFSET;
230
231         for (i = 0; i < 4; i++)
232                 writel(EMAC_NONE, &p->cmd[i]);
233 }
234
235 static int emac_r30_is_done(struct prueth_emac *emac)
236 {
237         const struct icssg_r30_cmd __iomem *p;
238         u32 cmd;
239         int i;
240
241         p = emac->dram.va + MGR_R30_CMD_OFFSET;
242
243         for (i = 0; i < 4; i++) {
244                 cmd = readl(&p->cmd[i]);
245                 if (cmd != EMAC_NONE)
246                         return 0;
247         }
248
249         return 1;
250 }
251
252 static int prueth_emac_buffer_setup(struct prueth_emac *emac)
253 {
254         struct icssg_buffer_pool_cfg __iomem *bpool_cfg;
255         struct icssg_rxq_ctx __iomem *rxq_ctx;
256         struct prueth *prueth = emac->prueth;
257         int slice = prueth_emac_slice(emac);
258         u32 addr;
259         int i;
260
261         /* Layout to have 64KB aligned buffer pool
262          * |BPOOL0|BPOOL1|RX_CTX0|RX_CTX1|
263          */
264
265         addr = lower_32_bits(prueth->msmcram.pa);
266         if (slice)
267                 addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE;
268
269         if (addr % SZ_64K) {
270                 dev_warn(prueth->dev, "buffer pool needs to be 64KB aligned\n");
271                 return -EINVAL;
272         }
273
274         bpool_cfg = emac->dram.va + BUFFER_POOL_0_ADDR_OFFSET;
275         /* workaround for f/w bug. bpool 0 needs to be initilalized */
276         writel(addr, &bpool_cfg[0].addr);
277         writel(0, &bpool_cfg[0].len);
278
279         for (i = PRUETH_EMAC_BUF_POOL_START;
280              i < PRUETH_EMAC_BUF_POOL_START + PRUETH_NUM_BUF_POOLS;
281              i++) {
282                 writel(addr, &bpool_cfg[i].addr);
283                 writel(PRUETH_EMAC_BUF_POOL_SIZE, &bpool_cfg[i].len);
284                 addr += PRUETH_EMAC_BUF_POOL_SIZE;
285         }
286
287         if (!slice)
288                 addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE;
289         else
290                 addr += PRUETH_EMAC_RX_CTX_BUF_SIZE * 2;
291
292         /* Pre-emptible RX buffer queue */
293         rxq_ctx = emac->dram.va + HOST_RX_Q_PRE_CONTEXT_OFFSET;
294         for (i = 0; i < 3; i++)
295                 writel(addr, &rxq_ctx->start[i]);
296
297         addr += PRUETH_EMAC_RX_CTX_BUF_SIZE;
298         writel(addr, &rxq_ctx->end);
299
300         /* Express RX buffer queue */
301         rxq_ctx = emac->dram.va + HOST_RX_Q_EXP_CONTEXT_OFFSET;
302         for (i = 0; i < 3; i++)
303                 writel(addr, &rxq_ctx->start[i]);
304
305         addr += PRUETH_EMAC_RX_CTX_BUF_SIZE;
306         writel(addr, &rxq_ctx->end);
307
308         return 0;
309 }
310
311 static void icssg_init_emac_mode(struct prueth *prueth)
312 {
313         /* When the device is configured as a bridge and it is being brought
314          * back to the emac mode, the host mac address has to be set as 0.
315          */
316         u8 mac[ETH_ALEN] = { 0 };
317
318         if (prueth->emacs_initialized)
319                 return;
320
321         regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1,
322                            SMEM_VLAN_OFFSET_MASK, 0);
323         regmap_write(prueth->miig_rt, FDB_GEN_CFG2, 0);
324         /* Clear host MAC address */
325         icssg_class_set_host_mac_addr(prueth->miig_rt, mac);
326 }
327
328 int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice)
329 {
330         void __iomem *config = emac->dram.va + ICSSG_CONFIG_OFFSET;
331         struct icssg_flow_cfg __iomem *flow_cfg;
332         int ret;
333
334         icssg_init_emac_mode(prueth);
335
336         memset_io(config, 0, TAS_GATE_MASK_LIST0);
337         icssg_miig_queues_init(prueth, slice);
338
339         emac->speed = SPEED_1000;
340         emac->duplex = DUPLEX_FULL;
341         if (!phy_interface_mode_is_rgmii(emac->phy_if)) {
342                 emac->speed = SPEED_100;
343                 emac->duplex = DUPLEX_FULL;
344         }
345         regmap_update_bits(prueth->miig_rt, ICSSG_CFG_OFFSET,
346                            ICSSG_CFG_DEFAULT, ICSSG_CFG_DEFAULT);
347         icssg_miig_set_interface_mode(prueth->miig_rt, slice, emac->phy_if);
348         icssg_config_mii_init(emac);
349         icssg_config_ipg(emac);
350         icssg_update_rgmii_cfg(prueth->miig_rt, emac);
351
352         /* set GPI mode */
353         pruss_cfg_gpimode(prueth->pruss, prueth->pru_id[slice],
354                           PRUSS_GPI_MODE_MII);
355
356         /* enable XFR shift for PRU and RTU */
357         pruss_cfg_xfr_enable(prueth->pruss, PRU_TYPE_PRU, true);
358         pruss_cfg_xfr_enable(prueth->pruss, PRU_TYPE_RTU, true);
359
360         /* set C28 to 0x100 */
361         pru_rproc_set_ctable(prueth->pru[slice], PRU_C28, 0x100 << 8);
362         pru_rproc_set_ctable(prueth->rtu[slice], PRU_C28, 0x100 << 8);
363         pru_rproc_set_ctable(prueth->txpru[slice], PRU_C28, 0x100 << 8);
364
365         flow_cfg = config + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET;
366         writew(emac->rx_flow_id_base, &flow_cfg->rx_base_flow);
367         writew(0, &flow_cfg->mgm_base_flow);
368         writeb(0, config + SPL_PKT_DEFAULT_PRIORITY);
369         writeb(0, config + QUEUE_NUM_UNTAGGED);
370
371         ret = prueth_emac_buffer_setup(emac);
372         if (ret)
373                 return ret;
374
375         emac_r30_cmd_init(emac);
376
377         return 0;
378 }
379
380 /* Bitmask for ICSSG r30 commands */
381 static const struct icssg_r30_cmd emac_r32_bitmask[] = {
382         {{0xffff0004, 0xffff0100, 0xffff0100, EMAC_NONE}},      /* EMAC_PORT_DISABLE */
383         {{0xfffb0040, 0xfeff0200, 0xfeff0200, EMAC_NONE}},      /* EMAC_PORT_BLOCK */
384         {{0xffbb0000, 0xfcff0000, 0xdcff0000, EMAC_NONE}},      /* EMAC_PORT_FORWARD */
385         {{0xffbb0000, 0xfcff0000, 0xfcff2000, EMAC_NONE}},      /* EMAC_PORT_FORWARD_WO_LEARNING */
386         {{0xffff0001, EMAC_NONE,  EMAC_NONE, EMAC_NONE}},       /* ACCEPT ALL */
387         {{0xfffe0002, EMAC_NONE,  EMAC_NONE, EMAC_NONE}},       /* ACCEPT TAGGED */
388         {{0xfffc0000, EMAC_NONE,  EMAC_NONE, EMAC_NONE}},       /* ACCEPT UNTAGGED and PRIO */
389         {{EMAC_NONE,  0xffff0020, EMAC_NONE, EMAC_NONE}},       /* TAS Trigger List change */
390         {{EMAC_NONE,  0xdfff1000, EMAC_NONE, EMAC_NONE}},       /* TAS set state ENABLE*/
391         {{EMAC_NONE,  0xefff2000, EMAC_NONE, EMAC_NONE}},       /* TAS set state RESET*/
392         {{EMAC_NONE,  0xcfff0000, EMAC_NONE, EMAC_NONE}},       /* TAS set state DISABLE*/
393         {{EMAC_NONE,  EMAC_NONE,  0xffff0400, EMAC_NONE}},      /* UC flooding ENABLE*/
394         {{EMAC_NONE,  EMAC_NONE,  0xfbff0000, EMAC_NONE}},      /* UC flooding DISABLE*/
395         {{EMAC_NONE,  EMAC_NONE,  0xffff0800, EMAC_NONE}},      /* MC flooding ENABLE*/
396         {{EMAC_NONE,  EMAC_NONE,  0xf7ff0000, EMAC_NONE}},      /* MC flooding DISABLE*/
397         {{EMAC_NONE,  0xffff4000, EMAC_NONE, EMAC_NONE}},       /* Preemption on Tx ENABLE*/
398         {{EMAC_NONE,  0xbfff0000, EMAC_NONE, EMAC_NONE}},       /* Preemption on Tx DISABLE*/
399         {{0xffff0010,  EMAC_NONE, 0xffff0010, EMAC_NONE}},      /* VLAN AWARE*/
400         {{0xffef0000,  EMAC_NONE, 0xffef0000, EMAC_NONE}}       /* VLAN UNWARE*/
401 };
402
403 int emac_set_port_state(struct prueth_emac *emac,
404                         enum icssg_port_state_cmd cmd)
405 {
406         struct icssg_r30_cmd __iomem *p;
407         int ret = -ETIMEDOUT;
408         int done = 0;
409         int i;
410
411         p = emac->dram.va + MGR_R30_CMD_OFFSET;
412
413         if (cmd >= ICSSG_EMAC_PORT_MAX_COMMANDS) {
414                 netdev_err(emac->ndev, "invalid port command\n");
415                 return -EINVAL;
416         }
417
418         /* only one command at a time allowed to firmware */
419         mutex_lock(&emac->cmd_lock);
420
421         for (i = 0; i < 4; i++)
422                 writel(emac_r32_bitmask[cmd].cmd[i], &p->cmd[i]);
423
424         /* wait for done */
425         ret = read_poll_timeout(emac_r30_is_done, done, done == 1,
426                                 1000, 10000, false, emac);
427
428         if (ret == -ETIMEDOUT)
429                 netdev_err(emac->ndev, "timeout waiting for command done\n");
430
431         mutex_unlock(&emac->cmd_lock);
432
433         return ret;
434 }
435
436 void icssg_config_set_speed(struct prueth_emac *emac)
437 {
438         u8 fw_speed;
439
440         switch (emac->speed) {
441         case SPEED_1000:
442                 fw_speed = FW_LINK_SPEED_1G;
443                 break;
444         case SPEED_100:
445                 fw_speed = FW_LINK_SPEED_100M;
446                 break;
447         case SPEED_10:
448                 fw_speed = FW_LINK_SPEED_10M;
449                 break;
450         default:
451                 /* Other links speeds not supported */
452                 netdev_err(emac->ndev, "Unsupported link speed\n");
453                 return;
454         }
455
456         writeb(fw_speed, emac->dram.va + PORT_LINK_SPEED_OFFSET);
457 }