diff options
author | Marc Kleine-Budde <mkl@pengutronix.de> | 2021-05-21 19:51:32 +0200 |
---|---|---|
committer | Marc Kleine-Budde <mkl@pengutronix.de> | 2022-01-08 20:17:42 +0100 |
commit | 335c818c5a7ace740da837a8bb8591d5896938db (patch) | |
tree | 4b025edfd4aed03291ed2d748888683cd1bf3c52 /drivers/net/can | |
parent | 1e846c7aeb067fefbd53f03db56e69d160781d9d (diff) |
can: mcp251xfd: move chip FIFO init into separate file
This patch moves the chip FIFO initialization from the mcp251xfd core
file into a separate one to make the driver a bit more orderly.
Link: https://lore.kernel.org/all/20220105154300.1258636-12-mkl@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers/net/can')
-rw-r--r-- | drivers/net/can/spi/mcp251xfd/Makefile | 1 | ||||
-rw-r--r-- | drivers/net/can/spi/mcp251xfd/mcp251xfd-chip-fifo.c | 119 | ||||
-rw-r--r-- | drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 102 | ||||
-rw-r--r-- | drivers/net/can/spi/mcp251xfd/mcp251xfd.h | 1 |
4 files changed, 121 insertions, 102 deletions
diff --git a/drivers/net/can/spi/mcp251xfd/Makefile b/drivers/net/can/spi/mcp251xfd/Makefile index 801367e98c54..6de680e7ea50 100644 --- a/drivers/net/can/spi/mcp251xfd/Makefile +++ b/drivers/net/can/spi/mcp251xfd/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_CAN_MCP251XFD) += mcp251xfd.o mcp251xfd-objs := +mcp251xfd-objs += mcp251xfd-chip-fifo.o mcp251xfd-objs += mcp251xfd-core.o mcp251xfd-objs += mcp251xfd-crc16.o mcp251xfd-objs += mcp251xfd-regmap.o diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-chip-fifo.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-chip-fifo.c new file mode 100644 index 000000000000..ce94dd744a93 --- /dev/null +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-chip-fifo.c @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// mcp251xfd - Microchip MCP251xFD Family CAN controller driver +// +// Copyright (c) 2019, 2020, 2021 Pengutronix, +// Marc Kleine-Budde <kernel@pengutronix.de> +// +// Based on: +// +// CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface +// +// Copyright (c) 2019 Martin Sperl <kernel@martin.sperl.org> +// + +#include <linux/bitfield.h> + +#include "mcp251xfd.h" + +static int +mcp251xfd_chip_rx_fifo_init_one(const struct mcp251xfd_priv *priv, + const struct mcp251xfd_rx_ring *ring) +{ + u32 fifo_con; + + /* Enable RXOVIE on _all_ RX FIFOs, not just the last one. + * + * FIFOs hit by a RX MAB overflow and RXOVIE enabled will + * generate a RXOVIF, use this to properly detect RX MAB + * overflows. + */ + fifo_con = FIELD_PREP(MCP251XFD_REG_FIFOCON_FSIZE_MASK, + ring->obj_num - 1) | + MCP251XFD_REG_FIFOCON_RXTSEN | + MCP251XFD_REG_FIFOCON_RXOVIE | + MCP251XFD_REG_FIFOCON_TFNRFNIE; + + if (priv->can.ctrlmode & (CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_FD)) + fifo_con |= FIELD_PREP(MCP251XFD_REG_FIFOCON_PLSIZE_MASK, + MCP251XFD_REG_FIFOCON_PLSIZE_64); + else + fifo_con |= FIELD_PREP(MCP251XFD_REG_FIFOCON_PLSIZE_MASK, + MCP251XFD_REG_FIFOCON_PLSIZE_8); + + return regmap_write(priv->map_reg, + MCP251XFD_REG_FIFOCON(ring->fifo_nr), fifo_con); +} + +static int +mcp251xfd_chip_rx_filter_init_one(const struct mcp251xfd_priv *priv, + const struct mcp251xfd_rx_ring *ring) +{ + u32 fltcon; + + fltcon = MCP251XFD_REG_FLTCON_FLTEN(ring->nr) | + MCP251XFD_REG_FLTCON_FBP(ring->nr, ring->fifo_nr); + + return regmap_update_bits(priv->map_reg, + MCP251XFD_REG_FLTCON(ring->nr >> 2), + MCP251XFD_REG_FLTCON_FLT_MASK(ring->nr), + fltcon); +} + +int mcp251xfd_chip_fifo_init(const struct mcp251xfd_priv *priv) +{ + const struct mcp251xfd_tx_ring *tx_ring = priv->tx; + const struct mcp251xfd_rx_ring *rx_ring; + u32 val; + int err, n; + + /* TEF */ + val = FIELD_PREP(MCP251XFD_REG_TEFCON_FSIZE_MASK, + tx_ring->obj_num - 1) | + MCP251XFD_REG_TEFCON_TEFTSEN | + MCP251XFD_REG_TEFCON_TEFOVIE | + MCP251XFD_REG_TEFCON_TEFNEIE; + + err = regmap_write(priv->map_reg, MCP251XFD_REG_TEFCON, val); + if (err) + return err; + + /* FIFO 1 - TX */ + val = FIELD_PREP(MCP251XFD_REG_FIFOCON_FSIZE_MASK, + tx_ring->obj_num - 1) | + MCP251XFD_REG_FIFOCON_TXEN | + MCP251XFD_REG_FIFOCON_TXATIE; + + if (priv->can.ctrlmode & (CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_FD)) + val |= FIELD_PREP(MCP251XFD_REG_FIFOCON_PLSIZE_MASK, + MCP251XFD_REG_FIFOCON_PLSIZE_64); + else + val |= FIELD_PREP(MCP251XFD_REG_FIFOCON_PLSIZE_MASK, + MCP251XFD_REG_FIFOCON_PLSIZE_8); + + if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT) + val |= FIELD_PREP(MCP251XFD_REG_FIFOCON_TXAT_MASK, + MCP251XFD_REG_FIFOCON_TXAT_ONE_SHOT); + else + val |= FIELD_PREP(MCP251XFD_REG_FIFOCON_TXAT_MASK, + MCP251XFD_REG_FIFOCON_TXAT_UNLIMITED); + + err = regmap_write(priv->map_reg, + MCP251XFD_REG_FIFOCON(MCP251XFD_TX_FIFO), + val); + if (err) + return err; + + /* RX FIFOs */ + mcp251xfd_for_each_rx_ring(priv, rx_ring, n) { + err = mcp251xfd_chip_rx_fifo_init_one(priv, rx_ring); + if (err) + return err; + + err = mcp251xfd_chip_rx_filter_init_one(priv, rx_ring); + if (err) + return err; + } + + return 0; +} diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c index 65803b9fe2a2..f7326c1b1723 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c @@ -767,108 +767,6 @@ static int mcp251xfd_chip_rx_int_disable(const struct mcp251xfd_priv *priv) return regmap_write(priv->map_reg, MCP251XFD_REG_IOCON, val); } -static int -mcp251xfd_chip_rx_fifo_init_one(const struct mcp251xfd_priv *priv, - const struct mcp251xfd_rx_ring *ring) -{ - u32 fifo_con; - - /* Enable RXOVIE on _all_ RX FIFOs, not just the last one. - * - * FIFOs hit by a RX MAB overflow and RXOVIE enabled will - * generate a RXOVIF, use this to properly detect RX MAB - * overflows. - */ - fifo_con = FIELD_PREP(MCP251XFD_REG_FIFOCON_FSIZE_MASK, - ring->obj_num - 1) | - MCP251XFD_REG_FIFOCON_RXTSEN | - MCP251XFD_REG_FIFOCON_RXOVIE | - MCP251XFD_REG_FIFOCON_TFNRFNIE; - - if (priv->can.ctrlmode & (CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_FD)) - fifo_con |= FIELD_PREP(MCP251XFD_REG_FIFOCON_PLSIZE_MASK, - MCP251XFD_REG_FIFOCON_PLSIZE_64); - else - fifo_con |= FIELD_PREP(MCP251XFD_REG_FIFOCON_PLSIZE_MASK, - MCP251XFD_REG_FIFOCON_PLSIZE_8); - - return regmap_write(priv->map_reg, - MCP251XFD_REG_FIFOCON(ring->fifo_nr), fifo_con); -} - -static int -mcp251xfd_chip_rx_filter_init_one(const struct mcp251xfd_priv *priv, - const struct mcp251xfd_rx_ring *ring) -{ - u32 fltcon; - - fltcon = MCP251XFD_REG_FLTCON_FLTEN(ring->nr) | - MCP251XFD_REG_FLTCON_FBP(ring->nr, ring->fifo_nr); - - return regmap_update_bits(priv->map_reg, - MCP251XFD_REG_FLTCON(ring->nr >> 2), - MCP251XFD_REG_FLTCON_FLT_MASK(ring->nr), - fltcon); -} - -static int mcp251xfd_chip_fifo_init(const struct mcp251xfd_priv *priv) -{ - const struct mcp251xfd_tx_ring *tx_ring = priv->tx; - const struct mcp251xfd_rx_ring *rx_ring; - u32 val; - int err, n; - - /* TEF */ - val = FIELD_PREP(MCP251XFD_REG_TEFCON_FSIZE_MASK, - tx_ring->obj_num - 1) | - MCP251XFD_REG_TEFCON_TEFTSEN | - MCP251XFD_REG_TEFCON_TEFOVIE | - MCP251XFD_REG_TEFCON_TEFNEIE; - - err = regmap_write(priv->map_reg, MCP251XFD_REG_TEFCON, val); - if (err) - return err; - - /* FIFO 1 - TX */ - val = FIELD_PREP(MCP251XFD_REG_FIFOCON_FSIZE_MASK, - tx_ring->obj_num - 1) | - MCP251XFD_REG_FIFOCON_TXEN | - MCP251XFD_REG_FIFOCON_TXATIE; - - if (priv->can.ctrlmode & (CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_FD)) - val |= FIELD_PREP(MCP251XFD_REG_FIFOCON_PLSIZE_MASK, - MCP251XFD_REG_FIFOCON_PLSIZE_64); - else - val |= FIELD_PREP(MCP251XFD_REG_FIFOCON_PLSIZE_MASK, - MCP251XFD_REG_FIFOCON_PLSIZE_8); - - if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT) - val |= FIELD_PREP(MCP251XFD_REG_FIFOCON_TXAT_MASK, - MCP251XFD_REG_FIFOCON_TXAT_ONE_SHOT); - else - val |= FIELD_PREP(MCP251XFD_REG_FIFOCON_TXAT_MASK, - MCP251XFD_REG_FIFOCON_TXAT_UNLIMITED); - - err = regmap_write(priv->map_reg, - MCP251XFD_REG_FIFOCON(MCP251XFD_TX_FIFO), - val); - if (err) - return err; - - /* RX FIFOs */ - mcp251xfd_for_each_rx_ring(priv, rx_ring, n) { - err = mcp251xfd_chip_rx_fifo_init_one(priv, rx_ring); - if (err) - return err; - - err = mcp251xfd_chip_rx_filter_init_one(priv, rx_ring); - if (err) - return err; - } - - return 0; -} - static int mcp251xfd_chip_ecc_init(struct mcp251xfd_priv *priv) { struct mcp251xfd_ecc *ecc = &priv->ecc; diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h index 22a18d6fbda4..69220de0e413 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h @@ -868,6 +868,7 @@ mcp251xfd_get_rx_linear_len(const struct mcp251xfd_rx_ring *ring) (n) < (priv)->rx_ring_num; \ (n)++, (ring) = *((priv)->rx + (n))) +int mcp251xfd_chip_fifo_init(const struct mcp251xfd_priv *priv); u16 mcp251xfd_crc16_compute2(const void *cmd, size_t cmd_size, const void *data, size_t data_size); u16 mcp251xfd_crc16_compute(const void *data, size_t data_size); |