3b5acba46ebb758548055586f7a300cd20a04893
[openwrt/staging/wigyori.git] / target / linux / layerscape / patches-5.4 / 701-net-0089-fsl-fman-backup-and-restore-ICID-registers.patch
1 From ef2b0593c906a85ca59ed5957ae7a7361974349c Mon Sep 17 00:00:00 2001
2 From: Laurentiu Tudor <laurentiu.tudor@nxp.com>
3 Date: Tue, 6 Feb 2018 16:21:17 +0200
4 Subject: [PATCH] fsl/fman: backup and restore ICID registers
5
6 During probing, FMAN is reset thus losing all its register
7 settings. Backup port ICID registers before reset and restore
8 them after, similarly to how it's done on powerpc / PAMU based
9 platforms.
10 This also has the side effect of disabling the old code path
11 (liodn backup/restore handling) that obviously make no sense
12 in the context of SMMU on ARMs.
13
14 Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
15 Acked-by: Madalin Bucur <madalin.bucur@nxp.com>
16 ---
17 drivers/net/ethernet/freescale/fman/fman.c | 35 +++++++++++++++++++++++++++++-
18 drivers/net/ethernet/freescale/fman/fman.h | 4 ++++
19 2 files changed, 38 insertions(+), 1 deletion(-)
20
21 --- a/drivers/net/ethernet/freescale/fman/fman.c
22 +++ b/drivers/net/ethernet/freescale/fman/fman.c
23 @@ -634,6 +634,7 @@ static void set_port_order_restoration(s
24 iowrite32be(tmp, &fpm_rg->fmfp_prc);
25 }
26
27 +#ifdef CONFIG_PPC
28 static void set_port_liodn(struct fman *fman, u8 port_id,
29 u32 liodn_base, u32 liodn_ofst)
30 {
31 @@ -651,6 +652,27 @@ static void set_port_liodn(struct fman *
32 iowrite32be(tmp, &fman->dma_regs->fmdmplr[port_id / 2]);
33 iowrite32be(liodn_ofst, &fman->bmi_regs->fmbm_spliodn[port_id - 1]);
34 }
35 +#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
36 +static void save_restore_port_icids(struct fman *fman, bool save)
37 +{
38 + int port_idxes[] = {
39 + 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc,
40 + 0xd, 0xe, 0xf, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
41 + 0x10, 0x11, 0x30, 0x31
42 + };
43 + int idx, i;
44 +
45 + for (i = 0; i < ARRAY_SIZE(port_idxes); i++) {
46 + idx = port_idxes[i];
47 + if (save)
48 + fman->sp_icids[idx] =
49 + ioread32be(&fman->bmi_regs->fmbm_spliodn[idx]);
50 + else
51 + iowrite32be(fman->sp_icids[idx],
52 + &fman->bmi_regs->fmbm_spliodn[idx]);
53 + }
54 +}
55 +#endif
56
57 static void enable_rams_ecc(struct fman_fpm_regs __iomem *fpm_rg)
58 {
59 @@ -1919,7 +1941,10 @@ _return:
60 static int fman_init(struct fman *fman)
61 {
62 struct fman_cfg *cfg = NULL;
63 - int err = 0, i, count;
64 + int err = 0, count;
65 +#ifdef CONFIG_PPC
66 + int i;
67 +#endif
68
69 if (is_init_done(fman->cfg))
70 return -EINVAL;
71 @@ -1939,6 +1964,7 @@ static int fman_init(struct fman *fman)
72 memset_io((void __iomem *)(fman->base_addr + CGP_OFFSET), 0,
73 fman->state->fm_port_num_of_cg);
74
75 +#ifdef CONFIG_PPC
76 /* Save LIODN info before FMan reset
77 * Skipping non-existent port 0 (i = 1)
78 */
79 @@ -1958,6 +1984,9 @@ static int fman_init(struct fman *fman)
80 }
81 fman->liodn_base[i] = liodn_base;
82 }
83 +#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
84 + save_restore_port_icids(fman, true);
85 +#endif
86
87 err = fman_reset(fman);
88 if (err)
89 @@ -2186,8 +2215,12 @@ int fman_set_port_params(struct fman *fm
90 if (err)
91 goto return_err;
92
93 +#ifdef CONFIG_PPC
94 set_port_liodn(fman, port_id, fman->liodn_base[port_id],
95 fman->liodn_offset[port_id]);
96 +#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
97 + save_restore_port_icids(fman, false);
98 +#endif
99
100 if (fman->state->rev_info.major < 6)
101 set_port_order_restoration(fman->fpm_regs, port_id);
102 --- a/drivers/net/ethernet/freescale/fman/fman.h
103 +++ b/drivers/net/ethernet/freescale/fman/fman.h
104 @@ -347,8 +347,12 @@ struct fman {
105 unsigned long fifo_offset;
106 size_t fifo_size;
107
108 +#ifdef CONFIG_PPC
109 u32 liodn_base[64];
110 u32 liodn_offset[64];
111 +#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
112 + u32 sp_icids[64];
113 +#endif
114
115 struct fman_dts_params dts_params;
116 };