| b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame] | 1 | From 1693e5693b77f0d172aac8adcfaa4888d64f8996 Mon Sep 17 00:00:00 2001 |
| 2 | From: Marc Kleine-Budde <mkl@pengutronix.de> |
| 3 | Date: Fri, 1 Mar 2019 13:54:19 +0100 |
| 4 | Subject: [PATCH] can: flexcan: introduce struct flexcan_priv::tx_mask and make |
| 5 | use of it |
| 6 | |
| 7 | The current driver uses FLEXCAN_IFLAG2_MB() to generate the mask to check for |
| 8 | the TX complete interrupt. This works well, as the driver will always use the |
| 9 | last mailbox for TX, which falls into the iflag2 register. |
| 10 | |
| 11 | To support CANFD the payload size has to increase to 64 bytes and the |
| 12 | number of mailboxes will decrease so much that the TX mailbox will be |
| 13 | handled in the iflag1 register. |
| 14 | |
| 15 | This patch introduces a tx_mask in the struct flexcan_priv (similar to rx_mask) |
| 16 | and makes use of it. The actual support to handle the TX mailbox in iflag1 will |
| 17 | be added in the next patches. |
| 18 | |
| 19 | Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> |
| 20 | --- |
| 21 | drivers/net/can/flexcan.c | 14 ++++++++------ |
| 22 | 1 file changed, 8 insertions(+), 6 deletions(-) |
| 23 | |
| 24 | --- a/drivers/net/can/flexcan.c |
| 25 | +++ b/drivers/net/can/flexcan.c |
| 26 | @@ -143,7 +143,6 @@ |
| 27 | #define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP 0 |
| 28 | #define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST (FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP + 1) |
| 29 | #define FLEXCAN_IFLAG_MB(x) BIT_ULL(x) |
| 30 | -#define FLEXCAN_IFLAG2_MB(x) BIT((x) & 0x1f) |
| 31 | #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7) |
| 32 | #define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6) |
| 33 | #define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE BIT(5) |
| 34 | @@ -279,6 +278,7 @@ struct flexcan_priv { |
| 35 | u8 clk_src; /* clock source of CAN Protocol Engine */ |
| 36 | |
| 37 | u64 rx_mask; |
| 38 | + u64 tx_mask; |
| 39 | u32 reg_ctrl_default; |
| 40 | |
| 41 | struct clk *clk_ipg; |
| 42 | @@ -898,7 +898,8 @@ static irqreturn_t flexcan_irq(int irq, |
| 43 | struct flexcan_priv *priv = netdev_priv(dev); |
| 44 | struct flexcan_regs __iomem *regs = priv->regs; |
| 45 | irqreturn_t handled = IRQ_NONE; |
| 46 | - u32 reg_iflag2, reg_esr; |
| 47 | + u64 reg_iflag_tx; |
| 48 | + u32 reg_esr; |
| 49 | enum can_state last_state = priv->can.state; |
| 50 | |
| 51 | /* reception interrupt */ |
| 52 | @@ -932,10 +933,10 @@ static irqreturn_t flexcan_irq(int irq, |
| 53 | } |
| 54 | } |
| 55 | |
| 56 | - reg_iflag2 = priv->read(®s->iflag2); |
| 57 | + reg_iflag_tx = (u64)priv->read(®s->iflag2) << 32; |
| 58 | |
| 59 | /* transmission complete interrupt */ |
| 60 | - if (reg_iflag2 & FLEXCAN_IFLAG2_MB(priv->tx_mb_idx)) { |
| 61 | + if (reg_iflag_tx & priv->tx_mask) { |
| 62 | u32 reg_ctrl = priv->read(&priv->tx_mb->can_ctrl); |
| 63 | |
| 64 | handled = IRQ_HANDLED; |
| 65 | @@ -947,7 +948,7 @@ static irqreturn_t flexcan_irq(int irq, |
| 66 | /* after sending a RTR frame MB is in RX mode */ |
| 67 | priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, |
| 68 | &priv->tx_mb->can_ctrl); |
| 69 | - priv->write(FLEXCAN_IFLAG2_MB(priv->tx_mb_idx), ®s->iflag2); |
| 70 | + priv->write(priv->tx_mask >> 32, ®s->iflag2); |
| 71 | netif_wake_queue(dev); |
| 72 | } |
| 73 | |
| 74 | @@ -1232,7 +1233,7 @@ static int flexcan_chip_start(struct net |
| 75 | /* enable interrupts atomically */ |
| 76 | disable_irq(dev->irq); |
| 77 | priv->write(priv->reg_ctrl_default, ®s->ctrl); |
| 78 | - reg_imask = priv->rx_mask | FLEXCAN_IFLAG_MB(priv->tx_mb_idx); |
| 79 | + reg_imask = priv->rx_mask | priv->tx_mask; |
| 80 | priv->write(upper_32_bits(reg_imask), ®s->imask2); |
| 81 | priv->write(lower_32_bits(reg_imask), ®s->imask1); |
| 82 | enable_irq(dev->irq); |
| 83 | @@ -1327,6 +1328,7 @@ static int flexcan_open(struct net_devic |
| 84 | flexcan_get_mb(priv, FLEXCAN_TX_MB_RESERVED_OFF_FIFO); |
| 85 | priv->tx_mb_idx = priv->mb_count - 1; |
| 86 | priv->tx_mb = flexcan_get_mb(priv, priv->tx_mb_idx); |
| 87 | + priv->tx_mask = FLEXCAN_IFLAG_MB(priv->tx_mb_idx); |
| 88 | |
| 89 | priv->offload.mailbox_read = flexcan_mailbox_read; |
| 90 | |