Commit 34b9dcd47872059fdff9552f2c86943b340b906e

Authored by Iustin Dumitrescu
Committed by Larisa Grigore
1 parent 9c10b17cd6

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  
... ... @@ -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