Lines Matching +full:stm32f4 +full:- +full:bxcan

1 // SPDX-License-Identifier: GPL-2.0
3 // bxcan.c - STM32 Basic Extended CAN controller driver
16 #include <linux/can/rx-offload.h>
152 u32 mcr; /* 0x00 - primary control */
153 u32 msr; /* 0x04 - primary status */
154 u32 tsr; /* 0x08 - transmit status */
155 u32 rf0r; /* 0x0c - FIFO 0 */
156 u32 rf1r; /* 0x10 - FIFO 1 */
157 u32 ier; /* 0x14 - interrupt enable */
158 u32 esr; /* 0x18 - error status */
159 u32 btr; /* 0x1c - bit timing*/
161 struct bxcan_mb tx_mb[BXCAN_TX_MB_NUM]; /* 0x180 - tx mailbox */
162 struct bxcan_mb rx_mb[BXCAN_RX_MB_NUM]; /* 0x1b0 - rx mailbox */
177 spinlock_t rmw_lock; /* lock for read-modify-write operations */
201 spin_lock_irqsave(&priv->rmw_lock, flags); in bxcan_rmw()
207 spin_unlock_irqrestore(&priv->rmw_lock, flags); in bxcan_rmw()
215 regmap_update_bits(priv->gcan, BXCAN_FA1R_REG, fmask, 0); in bxcan_disable_filters()
233 regmap_update_bits(priv->gcan, BXCAN_FMR_REG, in bxcan_enable_filters()
239 regmap_update_bits(priv->gcan, BXCAN_FA1R_REG, fmask, 0); in bxcan_enable_filters()
241 /* Two 32-bit registers in identifier mask mode */ in bxcan_enable_filters()
242 regmap_update_bits(priv->gcan, BXCAN_FM1R_REG, fmask, 0); in bxcan_enable_filters()
244 /* Single 32-bit scale configuration */ in bxcan_enable_filters()
245 regmap_update_bits(priv->gcan, BXCAN_FS1R_REG, fmask, fmask); in bxcan_enable_filters()
248 regmap_update_bits(priv->gcan, BXCAN_FFA1R_REG, fmask, 0); in bxcan_enable_filters()
251 regmap_write(priv->gcan, BXCAN_FiR1_REG(fid), 0); in bxcan_enable_filters()
252 regmap_write(priv->gcan, BXCAN_FiR2_REG(fid), 0); in bxcan_enable_filters()
255 regmap_update_bits(priv->gcan, BXCAN_FA1R_REG, fmask, fmask); in bxcan_enable_filters()
258 regmap_update_bits(priv->gcan, BXCAN_FMR_REG, BXCAN_FMR_FINIT, 0); in bxcan_enable_filters()
263 return priv->tx_head % BXCAN_TX_MB_NUM; in bxcan_get_tx_head()
268 return priv->tx_tail % BXCAN_TX_MB_NUM; in bxcan_get_tx_tail()
273 return BXCAN_TX_MB_NUM - (priv->tx_head - priv->tx_tail); in bxcan_get_tx_free()
281 netif_stop_queue(priv->ndev); in bxcan_tx_busy()
287 netdev_dbg(priv->ndev, in bxcan_tx_busy()
288 "Stopping tx-queue (tx_head=0x%08x, tx_tail=0x%08x, len=%d).\n", in bxcan_tx_busy()
289 priv->tx_head, priv->tx_tail, in bxcan_tx_busy()
290 priv->tx_head - priv->tx_tail); in bxcan_tx_busy()
295 netif_start_queue(priv->ndev); in bxcan_tx_busy()
302 struct bxcan_regs __iomem *regs = priv->regs; in bxcan_chip_softreset()
305 bxcan_rmw(priv, &regs->mcr, 0, BXCAN_MCR_RESET); in bxcan_chip_softreset()
306 return readx_poll_timeout(readl, &regs->msr, value, in bxcan_chip_softreset()
313 struct bxcan_regs __iomem *regs = priv->regs; in bxcan_enter_init_mode()
316 bxcan_rmw(priv, &regs->mcr, 0, BXCAN_MCR_INRQ); in bxcan_enter_init_mode()
317 return readx_poll_timeout(readl, &regs->msr, value, in bxcan_enter_init_mode()
324 struct bxcan_regs __iomem *regs = priv->regs; in bxcan_leave_init_mode()
327 bxcan_rmw(priv, &regs->mcr, BXCAN_MCR_INRQ, 0); in bxcan_leave_init_mode()
328 return readx_poll_timeout(readl, &regs->msr, value, in bxcan_leave_init_mode()
335 struct bxcan_regs __iomem *regs = priv->regs; in bxcan_enter_sleep_mode()
338 bxcan_rmw(priv, &regs->mcr, 0, BXCAN_MCR_SLEEP); in bxcan_enter_sleep_mode()
339 return readx_poll_timeout(readl, &regs->msr, value, in bxcan_enter_sleep_mode()
346 struct bxcan_regs __iomem *regs = priv->regs; in bxcan_leave_sleep_mode()
349 bxcan_rmw(priv, &regs->mcr, BXCAN_MCR_SLEEP, 0); in bxcan_leave_sleep_mode()
350 return readx_poll_timeout(readl, &regs->msr, value, in bxcan_leave_sleep_mode()
366 struct bxcan_regs __iomem *regs = priv->regs; in bxcan_mailbox_read()
367 struct bxcan_mb __iomem *mb_regs = &regs->rx_mb[0]; in bxcan_mailbox_read()
372 rf0r = readl(&regs->rf0r); in bxcan_mailbox_read()
374 skb = ERR_PTR(-ENOBUFS); in bxcan_mailbox_read()
381 skb = alloc_can_skb(offload->dev, &cf); in bxcan_mailbox_read()
383 skb = ERR_PTR(-ENOMEM); in bxcan_mailbox_read()
387 id = readl(&mb_regs->id); in bxcan_mailbox_read()
389 cf->can_id = FIELD_GET(BXCAN_RIxR_EXID_MASK, id) | CAN_EFF_FLAG; in bxcan_mailbox_read()
391 cf->can_id = FIELD_GET(BXCAN_RIxR_STID_MASK, id) & CAN_SFF_MASK; in bxcan_mailbox_read()
393 dlc = readl(&mb_regs->dlc); in bxcan_mailbox_read()
394 priv->timestamp = FIELD_GET(BXCAN_RDTxR_TIME_MASK, dlc); in bxcan_mailbox_read()
395 cf->len = can_cc_dlc2len(FIELD_GET(BXCAN_RDTxR_DLC_MASK, dlc)); in bxcan_mailbox_read()
398 cf->can_id |= CAN_RTR_FLAG; in bxcan_mailbox_read()
402 for (i = 0, j = 0; i < cf->len; i += 4, j++) in bxcan_mailbox_read()
403 *(u32 *)(cf->data + i) = readl(&mb_regs->data[j]); in bxcan_mailbox_read()
408 writel(rf0r, &regs->rf0r); in bxcan_mailbox_read()
416 struct bxcan_regs __iomem *regs = priv->regs; in bxcan_rx_isr()
419 rf0r = readl(&regs->rf0r); in bxcan_rx_isr()
423 can_rx_offload_irq_offload_fifo(&priv->offload); in bxcan_rx_isr()
424 can_rx_offload_irq_finish(&priv->offload); in bxcan_rx_isr()
433 struct bxcan_regs __iomem *regs = priv->regs; in bxcan_tx_isr()
434 struct net_device_stats *stats = &ndev->stats; in bxcan_tx_isr()
438 tsr = readl(&regs->tsr); in bxcan_tx_isr()
442 while (priv->tx_head - priv->tx_tail > 0) { in bxcan_tx_isr()
448 stats->tx_packets++; in bxcan_tx_isr()
449 stats->tx_bytes += can_get_echo_skb(ndev, idx, NULL); in bxcan_tx_isr()
450 priv->tx_tail++; in bxcan_tx_isr()
453 writel(tsr, &regs->tsr); in bxcan_tx_isr()
457 * this sees the new tx_ring->tail. in bxcan_tx_isr()
469 enum can_state new_state = priv->can.state; in bxcan_handle_state_change()
490 if (unlikely(new_state == priv->can.state)) in bxcan_handle_state_change()
502 cf->can_id |= CAN_ERR_CNT; in bxcan_handle_state_change()
503 cf->data[6] = bec.txerr; in bxcan_handle_state_change()
504 cf->data[7] = bec.rxerr; in bxcan_handle_state_change()
510 err = can_rx_offload_queue_timestamp(&priv->offload, skb, in bxcan_handle_state_change()
511 priv->timestamp); in bxcan_handle_state_change()
513 ndev->stats.rx_fifo_errors++; in bxcan_handle_state_change()
534 priv->can.can_stats.bus_error++; in bxcan_handle_bus_err()
539 cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; in bxcan_handle_bus_err()
544 ndev->stats.rx_errors++; in bxcan_handle_bus_err()
546 cf->data[2] |= CAN_ERR_PROT_STUFF; in bxcan_handle_bus_err()
551 ndev->stats.rx_errors++; in bxcan_handle_bus_err()
553 cf->data[2] |= CAN_ERR_PROT_FORM; in bxcan_handle_bus_err()
558 ndev->stats.tx_errors++; in bxcan_handle_bus_err()
560 cf->can_id |= CAN_ERR_ACK; in bxcan_handle_bus_err()
561 cf->data[3] = CAN_ERR_PROT_LOC_ACK; in bxcan_handle_bus_err()
567 ndev->stats.tx_errors++; in bxcan_handle_bus_err()
569 cf->data[2] |= CAN_ERR_PROT_BIT1; in bxcan_handle_bus_err()
574 ndev->stats.tx_errors++; in bxcan_handle_bus_err()
576 cf->data[2] |= CAN_ERR_PROT_BIT0; in bxcan_handle_bus_err()
581 ndev->stats.rx_errors++; in bxcan_handle_bus_err()
583 cf->data[2] |= CAN_ERR_PROT_BIT; in bxcan_handle_bus_err()
584 cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; in bxcan_handle_bus_err()
595 err = can_rx_offload_queue_timestamp(&priv->offload, skb, in bxcan_handle_bus_err()
596 priv->timestamp); in bxcan_handle_bus_err()
598 ndev->stats.rx_fifo_errors++; in bxcan_handle_bus_err()
606 struct bxcan_regs __iomem *regs = priv->regs; in bxcan_state_change_isr()
609 msr = readl(&regs->msr); in bxcan_state_change_isr()
613 esr = readl(&regs->esr); in bxcan_state_change_isr()
616 if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) in bxcan_state_change_isr()
620 writel(msr, &regs->msr); in bxcan_state_change_isr()
621 can_rx_offload_irq_finish(&priv->offload); in bxcan_state_change_isr()
629 struct bxcan_regs __iomem *regs = priv->regs; in bxcan_chip_start()
630 struct can_bittiming *bt = &priv->can.bittiming; in bxcan_chip_start()
659 * bus-off state left on sw request in bxcan_chip_start()
664 bxcan_rmw(priv, &regs->mcr, in bxcan_chip_start()
669 set = FIELD_PREP(BXCAN_BTR_BRP_MASK, bt->brp - 1) | in bxcan_chip_start()
670 FIELD_PREP(BXCAN_BTR_TS1_MASK, bt->phase_seg1 + in bxcan_chip_start()
671 bt->prop_seg - 1) | in bxcan_chip_start()
672 FIELD_PREP(BXCAN_BTR_TS2_MASK, bt->phase_seg2 - 1) | in bxcan_chip_start()
673 FIELD_PREP(BXCAN_BTR_SJW_MASK, bt->sjw - 1); in bxcan_chip_start()
676 * useful for hot self-test in bxcan_chip_start()
678 if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) in bxcan_chip_start()
681 if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) in bxcan_chip_start()
684 bxcan_rmw(priv, &regs->btr, BXCAN_BTR_SILM | BXCAN_BTR_LBKM | in bxcan_chip_start()
688 bxcan_enable_filters(priv, priv->cfg); in bxcan_chip_start()
691 priv->tx_head = 0; in bxcan_chip_start()
692 priv->tx_tail = 0; in bxcan_chip_start()
702 bxcan_rmw(priv, &regs->esr, BXCAN_ESR_LEC_MASK, in bxcan_chip_start()
708 * bus-off in bxcan_chip_start()
721 if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) in bxcan_chip_start()
726 bxcan_rmw(priv, &regs->ier, clr, set); in bxcan_chip_start()
728 priv->can.state = CAN_STATE_ERROR_ACTIVE; in bxcan_chip_start()
743 err = clk_prepare_enable(priv->clk); in bxcan_open()
757 can_rx_offload_enable(&priv->offload); in bxcan_open()
758 err = request_irq(ndev->irq, bxcan_rx_isr, IRQF_SHARED, ndev->name, in bxcan_open()
762 ndev->irq, ERR_PTR(err)); in bxcan_open()
766 err = request_irq(priv->tx_irq, bxcan_tx_isr, IRQF_SHARED, ndev->name, in bxcan_open()
770 priv->tx_irq, ERR_PTR(err)); in bxcan_open()
774 err = request_irq(priv->sce_irq, bxcan_state_change_isr, IRQF_SHARED, in bxcan_open()
775 ndev->name, ndev); in bxcan_open()
778 priv->sce_irq, ERR_PTR(err)); in bxcan_open()
790 free_irq(priv->sce_irq, ndev); in bxcan_open()
792 free_irq(priv->tx_irq, ndev); in bxcan_open()
794 free_irq(ndev->irq, ndev); in bxcan_open()
796 can_rx_offload_disable(&priv->offload); in bxcan_open()
799 clk_disable_unprepare(priv->clk); in bxcan_open()
806 struct bxcan_regs __iomem *regs = priv->regs; in bxcan_chip_stop()
809 bxcan_rmw(priv, &regs->ier, BXCAN_IER_SLKIE | BXCAN_IER_WKUIE | in bxcan_chip_stop()
814 bxcan_disable_filters(priv, priv->cfg); in bxcan_chip_stop()
816 priv->can.state = CAN_STATE_STOPPED; in bxcan_chip_stop()
825 free_irq(ndev->irq, ndev); in bxcan_stop()
826 free_irq(priv->tx_irq, ndev); in bxcan_stop()
827 free_irq(priv->sce_irq, ndev); in bxcan_stop()
828 can_rx_offload_disable(&priv->offload); in bxcan_stop()
830 clk_disable_unprepare(priv->clk); in bxcan_stop()
838 struct can_frame *cf = (struct can_frame *)skb->data; in bxcan_start_xmit()
839 struct bxcan_regs __iomem *regs = priv->regs; in bxcan_start_xmit()
852 priv->tx_head++; in bxcan_start_xmit()
856 mb_regs = &regs->tx_mb[idx]; in bxcan_start_xmit()
857 if (cf->can_id & CAN_EFF_FLAG) in bxcan_start_xmit()
858 id = FIELD_PREP(BXCAN_TIxR_EXID_MASK, cf->can_id) | in bxcan_start_xmit()
861 id = FIELD_PREP(BXCAN_TIxR_STID_MASK, cf->can_id); in bxcan_start_xmit()
863 if (cf->can_id & CAN_RTR_FLAG) { /* Remote transmission request */ in bxcan_start_xmit()
866 for (i = 0, j = 0; i < cf->len; i += 4, j++) in bxcan_start_xmit()
867 writel(*(u32 *)(cf->data + i), &mb_regs->data[j]); in bxcan_start_xmit()
870 writel(FIELD_PREP(BXCAN_TDTxR_DLC_MASK, cf->len), &mb_regs->dlc); in bxcan_start_xmit()
875 writel(id | BXCAN_TIxR_TXRQ, &mb_regs->id); in bxcan_start_xmit()
905 return -EOPNOTSUPP; in bxcan_do_set_mode()
915 struct bxcan_regs __iomem *regs = priv->regs; in bxcan_get_berr_counter()
919 err = clk_prepare_enable(priv->clk); in bxcan_get_berr_counter()
923 esr = readl(&regs->esr); in bxcan_get_berr_counter()
924 bec->txerr = FIELD_GET(BXCAN_ESR_TEC_MASK, esr); in bxcan_get_berr_counter()
925 bec->rxerr = FIELD_GET(BXCAN_ESR_REC_MASK, esr); in bxcan_get_berr_counter()
926 clk_disable_unprepare(priv->clk); in bxcan_get_berr_counter()
932 struct device_node *np = pdev->dev.of_node; in bxcan_probe()
933 struct device *dev = &pdev->dev; in bxcan_probe()
954 if (of_property_read_bool(np, "st,can-primary")) in bxcan_probe()
956 else if (of_property_read_bool(np, "st,can-secondary")) in bxcan_probe()
982 return -ENOMEM; in bxcan_probe()
988 ndev->netdev_ops = &bxcan_netdev_ops; in bxcan_probe()
989 ndev->ethtool_ops = &bxcan_ethtool_ops; in bxcan_probe()
990 ndev->irq = rx_irq; in bxcan_probe()
991 ndev->flags |= IFF_ECHO; in bxcan_probe()
993 priv->dev = dev; in bxcan_probe()
994 priv->ndev = ndev; in bxcan_probe()
995 priv->regs = regs; in bxcan_probe()
996 priv->gcan = gcan; in bxcan_probe()
997 priv->clk = clk; in bxcan_probe()
998 priv->tx_irq = tx_irq; in bxcan_probe()
999 priv->sce_irq = sce_irq; in bxcan_probe()
1000 priv->cfg = cfg; in bxcan_probe()
1001 priv->can.clock.freq = clk_get_rate(clk); in bxcan_probe()
1002 spin_lock_init(&priv->rmw_lock); in bxcan_probe()
1003 priv->tx_head = 0; in bxcan_probe()
1004 priv->tx_tail = 0; in bxcan_probe()
1005 priv->can.bittiming_const = &bxcan_bittiming_const; in bxcan_probe()
1006 priv->can.do_set_mode = bxcan_do_set_mode; in bxcan_probe()
1007 priv->can.do_get_berr_counter = bxcan_get_berr_counter; in bxcan_probe()
1008 priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | in bxcan_probe()
1011 priv->offload.mailbox_read = bxcan_mailbox_read; in bxcan_probe()
1012 err = can_rx_offload_add_fifo(ndev, &priv->offload, BXCAN_NAPI_WEIGHT); in bxcan_probe()
1024 dev_info(dev, "clk: %d Hz, IRQs: %d, %d, %d\n", priv->can.clock.freq, in bxcan_probe()
1029 can_rx_offload_del(&priv->offload); in bxcan_probe()
1041 clk_disable_unprepare(priv->clk); in bxcan_remove()
1042 can_rx_offload_del(&priv->offload); in bxcan_remove()
1058 priv->can.state = CAN_STATE_SLEEPING; in bxcan_suspend()
1059 clk_disable_unprepare(priv->clk); in bxcan_suspend()
1071 clk_prepare_enable(priv->clk); in bxcan_resume()
1073 priv->can.state = CAN_STATE_ERROR_ACTIVE; in bxcan_resume()
1083 {.compatible = "st,stm32f4-bxcan"},