Commit 34b9dcd47872059fdff9552f2c86943b340b906e
Committed by
Larisa Grigore
1 parent
9c10b17cd6
Exists in
smarc_8mq_lf_v2020.04
and in
4 other branches
sja1105: Add port reset functionality
Add a function that resets the RX delay line on all ports on the SJA. Issue: ALB-1755 Signed-off-by: Iustin Dumitrescu <iustin.dumitrescu@nxp.com>
Showing 3 changed files with 127 additions and 2 deletions Side-by-side Diff
drivers/spi/sja1105.c
1 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | 2 | /* |
3 | - * Copyright 2017-2018 NXP | |
3 | + * Copyright 2017-2018,2020 NXP | |
4 | 4 | * |
5 | 5 | */ |
6 | 6 | |
... | ... | @@ -141,6 +141,53 @@ |
141 | 141 | return rc; |
142 | 142 | } |
143 | 143 | |
144 | +static u32 sja1105_write_reg32(struct sja_parms *sjap, u32 reg_addr, u32 val) | |
145 | +{ | |
146 | + u32 cmd[2], resp[2], upper, down; | |
147 | + struct spi_slave *slave; | |
148 | + int bitlen = sizeof(cmd) << 3; | |
149 | + int rc; | |
150 | + | |
151 | + sja_debug("writing 4bytes @0x%08x tlen %d t.bits_per_word %d\n", | |
152 | + reg_addr, 8, 64); | |
153 | + | |
154 | + slave = spi_setup_slave(sjap->bus, sjap->cs, SJA_DSPI_HZ, | |
155 | + SJA_DSPI_MODE); | |
156 | + if (!slave) { | |
157 | + printf("Invalid device %d:%d\n", sjap->bus, sjap->cs); | |
158 | + return -EINVAL; | |
159 | + } | |
160 | + | |
161 | + rc = spi_claim_bus(slave); | |
162 | + if (rc) | |
163 | + goto done; | |
164 | + | |
165 | + cmd[0] = cpu_to_le32 (CMD_ENCODE_RWOP(CMD_WR_OP) | | |
166 | + CMD_ENCODE_ADDR(reg_addr) | CMD_ENCODE_WRD_CNT(1)); | |
167 | + upper = (cmd[0] & 0x0000FFFF) << 16; | |
168 | + down = (cmd[0] & 0xFFFF0000) >> 16; | |
169 | + cmd[0] = upper | down; | |
170 | + | |
171 | + cmd[1] = val; | |
172 | + upper = (cmd[1] & 0x0000FFFF) << 16; | |
173 | + down = (cmd[1] & 0xFFFF0000) >> 16; | |
174 | + cmd[1] = upper | down; | |
175 | + | |
176 | + rc = spi_xfer(slave, bitlen, cmd, resp, SPI_XFER_BEGIN | SPI_XFER_END); | |
177 | + if (rc) | |
178 | + printf("Error %d during SPI transaction\n", rc); | |
179 | + spi_release_bus(slave); | |
180 | + spi_free_slave(slave); | |
181 | + | |
182 | + upper = (resp[1] & 0x0000FFFF) << 16; | |
183 | + down = (resp[1] & 0xFFFF0000) >> 16; | |
184 | + resp[1] = upper | down; | |
185 | + | |
186 | + return le32_to_cpu(resp[1]); | |
187 | +done: | |
188 | + return rc; | |
189 | +} | |
190 | + | |
144 | 191 | static bool sja1105_check_device_status(struct sja_parms *sjap, |
145 | 192 | bool expected_status, |
146 | 193 | bool *pstatus) |
... | ... | @@ -275,6 +322,34 @@ |
275 | 322 | return -ENXIO; |
276 | 323 | } |
277 | 324 | return 0; |
325 | +} | |
326 | + | |
327 | +void sja1105_reset_ports(u32 cs, u32 bus) | |
328 | +{ | |
329 | + struct sja_parms sjap; | |
330 | + int i, val; | |
331 | + | |
332 | + sjap.cs = cs; | |
333 | + sjap.bus = bus; | |
334 | + | |
335 | + for (i = 0; i < SJA1105_PORT_NB; i++) { | |
336 | + val = sja1105_read_reg32(&sjap, | |
337 | + SJA1105_CFG_PAD_MIIX_ID_PORT(i)); | |
338 | + | |
339 | + /* Toggle RX Clock PullDown and Bypass */ | |
340 | + | |
341 | + val |= SJA1105_CFG_PAD_MIIX_ID_RXC_PD; | |
342 | + val |= SJA1105_CFG_PAD_MIIX_ID_RXC_BYPASS; | |
343 | + | |
344 | + sja1105_write_reg32(&sjap, SJA1105_CFG_PAD_MIIX_ID_PORT(i), | |
345 | + val); | |
346 | + | |
347 | + val &= ~SJA1105_CFG_PAD_MIIX_ID_RXC_PD; | |
348 | + val &= ~SJA1105_CFG_PAD_MIIX_ID_RXC_BYPASS; | |
349 | + | |
350 | + sja1105_write_reg32(&sjap, SJA1105_CFG_PAD_MIIX_ID_PORT(i), | |
351 | + val); | |
352 | + } | |
278 | 353 | } |
279 | 354 | |
280 | 355 | int sja1105_probe(u32 cs, u32 bus) |
drivers/spi/sja1105_ll.h
1 | 1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
2 | 2 | /* |
3 | 3 | * AVB switch driver module for SJA1105 |
4 | - * Copyright 2017 NXP | |
4 | + * Copyright 2017,2020 NXP | |
5 | 5 | * |
6 | 6 | * This program is free software; you can redistribute it and/or |
7 | 7 | * modify it under the terms of the GNU General Public License |
... | ... | @@ -177,6 +177,44 @@ |
177 | 177 | #define SJA1105_REG_PORT_MAC_STATUS(_port_) (0x200UL + ((_port_) * 2)) |
178 | 178 | #define SJA1105_REG_PORT_HIGH_STATUS1(_port_) (0x400UL + (_port_) * 16) |
179 | 179 | #define SJA1105_REG_PORT_HIGH_STATUS2(_port_) (0x600UL + (_port_) * 16) |
180 | + | |
181 | +/* CGU Registers */ | |
182 | + | |
183 | +#define SJA1105_CGU_IDIV_ADDR 0x10000B | |
184 | +#define SJA1105_CGU_IDIV_PORT(port) (SJA1105_CGU_IDIV_ADDR + (port)) | |
185 | + | |
186 | +#define SJA1105_CGU_MII_TX_CLK_ADDR 0x100016 | |
187 | +#define SJA1105_CGU_MII_TX_CLK_PORT(port) (SJA1105_CGU_MII_TX_CLK_ADDR + \ | |
188 | + (port) * 6) | |
189 | + | |
190 | +/* Configuration registers */ | |
191 | + | |
192 | +#define SJA1105_CFG_PAD_MIIX_TX_ADDR 0x100800 | |
193 | +#define SJA1105_CFG_PAD_MIIX_TX_PORT(port) (SJA1105_CFG_PAD_MIIX_TX_ADDR \ | |
194 | + + (port) * 2) | |
195 | + | |
196 | +#define SJA1105_CFG_PAD_MIIX_ID_ADDR 0x100810 | |
197 | +#define SJA1105_CFG_PAD_MIIX_ID_PORT(port) (SJA1105_CFG_PAD_MIIX_ID_ADDR \ | |
198 | + + (port)) | |
199 | + | |
200 | +#define SJA1105_PORT_STATUS_MII_ADDR 0x100900 | |
201 | +#define SJA1105_PORT_STATUS_MII_PORT(port) (SJA1105_PORT_STATUS_MII_ADDR \ | |
202 | + + (port)) | |
203 | + | |
204 | +#define SJA1105_CFG_PAD_MIIX_ID_RXC_DELAY(delay) ((delay) << 10) | |
205 | +#define SJA1105_CFG_PAD_MIIX_ID_RXC_BYPASS BIT(9) | |
206 | +#define SJA1105_CFG_PAD_MIIX_ID_RXC_PD BIT(8) | |
207 | + | |
208 | +#define SJA1105_PORT_STATUS_MII_MODE (0x00000003) | |
209 | + | |
210 | +enum sja1105_mii_mode { | |
211 | + e_mii_mode_mii = 0, | |
212 | + e_mii_mode_rmii, | |
213 | + e_mii_mode_rgmii, | |
214 | + e_mii_mode_sgmii, | |
215 | +}; | |
216 | + | |
217 | +#define SJA1105_PORT_NB 5 | |
180 | 218 | |
181 | 219 | int sja1105_get_cfg(u32 devid, u32 cs, u32 *bin_len, u8 **cfg_bin); |
182 | 220 |
include/sja1105.h
... | ... | @@ -20,5 +20,17 @@ |
20 | 20 | */ |
21 | 21 | int sja1105_probe(u32 cs, u32 bus); |
22 | 22 | |
23 | +/** | |
24 | + * sja1105_reset_ports() - Reset ports on SJA1105 in order to allow traffic | |
25 | + * | |
26 | + * Given a bus number and chip select, this resets the ports on the | |
27 | + * corresponding SJA1105 switch. This is done in order to allow traffic in case | |
28 | + * the ports become unresponsive. Should be called upon network operations. | |
29 | + * | |
30 | + * @cs: Chip select to look for | |
31 | + * @bus: SPI bus number | |
32 | + */ | |
33 | +void sja1105_reset_ports(u32 cs, u32 bus); | |
34 | + | |
23 | 35 | #endif |