Lines Matching +full:timing +full:- +full:adjustment

1 // SPDX-License-Identifier: GPL-2.0-or-later
6 * Copyright (C) 2015-2018 Ondrej Ille <ondrej.ille@gmail.com> FEE CTU
7 * Copyright (C) 2018-2021 Ondrej Ille <ondrej.ille@gmail.com> self-funded
8 * Copyright (C) 2018-2019 Martin Jerabek <martin.jerabek01@gmail.com> FEE CTU
9 * Copyright (C) 2018-2022 Pavel Pisa <pisa@cmp.felk.cvut.cz> FEE CTU/self-funded
49 * - when a buffer transitions to empty state, rotate order and priorities
50 * - if more buffers seem to transition at the same time, rotate by the number of buffers
51 * - it may be assumed that buffers transition to empty state in FIFO order (because we manage
53 * - at frame filling, do not rotate anything, just increment buffer modulo counter
114 iowrite32(val, priv->mem_base + reg); in ctucan_write32_le()
120 iowrite32be(val, priv->mem_base + reg); in ctucan_write32_be()
126 return ioread32(priv->mem_base + reg); in ctucan_read32_le()
132 return ioread32be(priv->mem_base + reg); in ctucan_read32_be()
137 priv->write_reg(priv, reg, val); in ctucan_write32()
142 return priv->read_reg(priv, reg); in ctucan_read32()
148 priv->write_reg(priv, buf_base + offset, val); in ctucan_write_txt_buf()
155 * ctucan_state_to_str() - Converts CAN controller state code to corresponding text
170 * ctucan_reset() - Issues software reset request to CTU CAN FD
173 * Return: 0 for success, -%ETIMEDOUT if CAN controller does not leave reset
181 clear_bit(CTUCANFD_FLAG_RX_FFW_BUFFERED, &priv->drv_flags); in ctucan_reset()
189 if (!i--) { in ctucan_reset()
191 return -ETIMEDOUT; in ctucan_reset()
198 * ctucan_set_btr() - Sets CAN bus bit timing in CTU CAN FD
200 * @bt: Pointer to Bit timing structure
201 * @nominal: True - Nominal bit timing, False - Data bit timing
203 * Return: 0 - OK, -%EPERM if controller is enabled
210 u32 prop_seg = bt->prop_seg; in ctucan_set_btr()
211 u32 phase_seg1 = bt->phase_seg1; in ctucan_set_btr()
214 netdev_err(ndev, "BUG! Cannot set bittiming - CAN is enabled\n"); in ctucan_set_btr()
215 return -EPERM; in ctucan_set_btr()
221 /* The timing calculation functions have only constraints on tseg1, which is prop_seg + in ctucan_set_btr()
223 * In CTU CAN FD, PROP is 6/7 bits wide but PH1 only 6/5, so we must re-distribute the in ctucan_set_btr()
227 prop_seg += phase_seg1 - max_ph1_len; in ctucan_set_btr()
229 bt->prop_seg = prop_seg; in ctucan_set_btr()
230 bt->phase_seg1 = phase_seg1; in ctucan_set_btr()
236 btr |= FIELD_PREP(REG_BTR_PH2, bt->phase_seg2); in ctucan_set_btr()
237 btr |= FIELD_PREP(REG_BTR_BRP, bt->brp); in ctucan_set_btr()
238 btr |= FIELD_PREP(REG_BTR_SJW, bt->sjw); in ctucan_set_btr()
244 btr |= FIELD_PREP(REG_BTR_FD_PH2_FD, bt->phase_seg2); in ctucan_set_btr()
245 btr |= FIELD_PREP(REG_BTR_FD_BRP_FD, bt->brp); in ctucan_set_btr()
246 btr |= FIELD_PREP(REG_BTR_FD_SJW_FD, bt->sjw); in ctucan_set_btr()
255 * ctucan_set_bittiming() - CAN set nominal bit timing routine
258 * Return: 0 on success, -%EPERM on error
263 struct can_bittiming *bt = &priv->can.bittiming; in ctucan_set_bittiming()
270 * ctucan_set_data_bittiming() - CAN set data bit timing routine
273 * Return: 0 on success, -%EPERM on error
278 struct can_bittiming *dbt = &priv->can.fd.data_bittiming; in ctucan_set_data_bittiming()
285 * ctucan_set_secondary_sample_point() - Sets secondary sample point in CTU CAN FD
288 * Return: 0 on success, -%EPERM if controller is enabled
293 struct can_bittiming *dbt = &priv->can.fd.data_bittiming; in ctucan_set_secondary_sample_point()
298 netdev_err(ndev, "BUG! Cannot set SSP - CAN is enabled\n"); in ctucan_set_secondary_sample_point()
299 return -EPERM; in ctucan_set_secondary_sample_point()
302 /* Use SSP for bit-rates above 1 Mbits/s */ in ctucan_set_secondary_sample_point()
303 if (dbt->bitrate > 1000000) { in ctucan_set_secondary_sample_point()
305 ssp_offset = (priv->can.clock.freq / 1000) * dbt->sample_point / dbt->bitrate; in ctucan_set_secondary_sample_point()
322 * ctucan_set_mode() - Sets CTU CAN FDs mode
330 mode_reg = (mode->flags & CAN_CTRLMODE_LOOPBACK) ? in ctucan_set_mode()
334 mode_reg = (mode->flags & CAN_CTRLMODE_LISTENONLY) ? in ctucan_set_mode()
338 mode_reg = (mode->flags & CAN_CTRLMODE_FD) ? in ctucan_set_mode()
342 mode_reg = (mode->flags & CAN_CTRLMODE_PRESUME_ACK) ? in ctucan_set_mode()
346 mode_reg = (mode->flags & CAN_CTRLMODE_FD_NON_ISO) ? in ctucan_set_mode()
352 mode_reg = (mode->flags & CAN_CTRLMODE_ONE_SHOT) ? in ctucan_set_mode()
357 * TSTM - Off, User shall not be able to change REC/TEC by hand during operation in ctucan_set_mode()
365 * ctucan_chip_start() - This routine starts the driver
383 priv->txb_prio = 0x01234567; in ctucan_chip_start()
384 priv->txb_head = 0; in ctucan_chip_start()
385 priv->txb_tail = 0; in ctucan_chip_start()
386 ctucan_write32(priv, CTUCANFD_TX_PRIORITY, priv->txb_prio); in ctucan_chip_start()
388 /* Configure bit-rates and ssp */ in ctucan_chip_start()
402 mode.flags = priv->can.ctrlmode; in ctucan_chip_start()
412 /* Bus error reporting -> Allow Error/Arb.lost interrupts */ in ctucan_chip_start()
413 if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) { in ctucan_chip_start()
425 priv->can.state = CAN_STATE_STOPPED; in ctucan_chip_start()
436 * ctucan_do_set_mode() - Sets mode of the driver
461 ret = -EOPNOTSUPP; in ctucan_do_set_mode()
469 * ctucan_get_tx_status() - Gets status of TXT buffer
471 * @buf: Buffer index (0-based)
484 * ctucan_is_txt_buf_writable() - Checks if frame can be inserted to TXT Buffer
486 * @buf: Buffer index (0-based)
488 * Return: True - Frame can be inserted to TXT Buffer, False - If attempted, frame will not be
503 * ctucan_insert_frame() - Inserts frame to TXT buffer
506 * @buf: TXT Buffer index to which frame is inserted (0-based)
507 * @isfdf: True - CAN FD Frame, False - CAN 2.0 Frame
510 * * True - Frame inserted successfully
511 * * False - Frame was not inserted due to one of:
524 if (buf >= priv->ntxbufs) in ctucan_insert_frame()
530 if (cf->len > CANFD_MAX_DLEN) in ctucan_insert_frame()
534 if (cf->can_id & CAN_RTR_FLAG) in ctucan_insert_frame()
537 if (cf->can_id & CAN_EFF_FLAG) in ctucan_insert_frame()
542 if (cf->flags & CANFD_BRS) in ctucan_insert_frame()
546 ffw |= FIELD_PREP(REG_FRAME_FORMAT_W_DLC, can_fd_len2dlc(cf->len)); in ctucan_insert_frame()
549 if (cf->can_id & CAN_EFF_FLAG) in ctucan_insert_frame()
550 idw = cf->can_id & CAN_EFF_MASK; in ctucan_insert_frame()
552 idw = FIELD_PREP(REG_IDENTIFIER_W_IDENTIFIER_BASE, cf->can_id & CAN_SFF_MASK); in ctucan_insert_frame()
554 /* Write ID, Frame format, Don't write timestamp -> Time triggered transmission disabled */ in ctucan_insert_frame()
560 if (!(cf->can_id & CAN_RTR_FLAG)) { in ctucan_insert_frame()
561 for (i = 0; i < cf->len; i += 4) { in ctucan_insert_frame()
562 u32 data = le32_to_cpu(*(__le32 *)(cf->data + i)); in ctucan_insert_frame()
572 * ctucan_give_txtb_cmd() - Applies command on TXT buffer
575 * @buf: Buffer index (0-based)
586 * ctucan_start_xmit() - Starts the transmission
599 struct canfd_frame *cf = (struct canfd_frame *)skb->data; in ctucan_start_xmit()
613 txtb_id = priv->txb_head % priv->ntxbufs; in ctucan_start_xmit()
620 ndev->stats.tx_dropped++; in ctucan_start_xmit()
626 spin_lock_irqsave(&priv->tx_lock, flags); in ctucan_start_xmit()
628 priv->txb_head++; in ctucan_start_xmit()
634 spin_unlock_irqrestore(&priv->tx_lock, flags); in ctucan_start_xmit()
640 * ctucan_read_rx_frame() - Reads frame from RX FIFO
656 cf->can_id = (idw & CAN_EFF_MASK) | CAN_EFF_FLAG; in ctucan_read_rx_frame()
658 cf->can_id = (idw >> 18) & CAN_SFF_MASK; in ctucan_read_rx_frame()
663 cf->flags |= CANFD_BRS; in ctucan_read_rx_frame()
665 cf->flags |= CANFD_ESI; in ctucan_read_rx_frame()
667 cf->can_id |= CAN_RTR_FLAG; in ctucan_read_rx_frame()
670 wc = FIELD_GET(REG_FRAME_FORMAT_W_RWCNT, ffw) - 3; in ctucan_read_rx_frame()
681 cf->len = len; in ctucan_read_rx_frame()
685 /* Timestamp - Read and throw away */ in ctucan_read_rx_frame()
692 *(__le32 *)(cf->data + i) = cpu_to_le32(data); in ctucan_read_rx_frame()
701 * ctucan_rx() - Called from CAN ISR to complete the received frame processing
708 * -%EAGAIN in a case of empty Rx FIFO.
713 struct net_device_stats *stats = &ndev->stats; in ctucan_rx()
718 if (test_bit(CTUCANFD_FLAG_RX_FFW_BUFFERED, &priv->drv_flags)) { in ctucan_rx()
719 ffw = priv->rxfrm_first_word; in ctucan_rx()
720 clear_bit(CTUCANFD_FLAG_RX_FFW_BUFFERED, &priv->drv_flags); in ctucan_rx()
726 return -EAGAIN; in ctucan_rx()
734 priv->rxfrm_first_word = ffw; in ctucan_rx()
735 set_bit(CTUCANFD_FLAG_RX_FFW_BUFFERED, &priv->drv_flags); in ctucan_rx()
741 stats->rx_bytes += cf->len; in ctucan_rx()
742 stats->rx_packets++; in ctucan_rx()
749 * ctucan_read_fault_state() - Reads CTU CAN FDs fault confinement state.
781 * ctucan_get_rec_tec() - Reads REC/TEC counter values from controller
789 bec->rxerr = FIELD_GET(REG_REC_REC_VAL, err_ctrs); in ctucan_get_rec_tec()
790 bec->txerr = FIELD_GET(REG_REC_TEC_VAL, err_ctrs); in ctucan_get_rec_tec()
794 * ctucan_err_interrupt() - Error frame ISR
804 struct net_device_stats *stats = &ndev->stats; in ctucan_err_interrupt()
833 ctucan_state_to_str(priv->can.state), in ctucan_err_interrupt()
836 if (priv->can.state == state) in ctucan_err_interrupt()
840 priv->can.state = state; in ctucan_err_interrupt()
843 priv->can.can_stats.bus_off++; in ctucan_err_interrupt()
846 cf->can_id |= CAN_ERR_BUSOFF; in ctucan_err_interrupt()
849 priv->can.can_stats.error_passive++; in ctucan_err_interrupt()
851 cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT; in ctucan_err_interrupt()
852 cf->data[1] = (bec.rxerr > 127) ? in ctucan_err_interrupt()
855 cf->data[6] = bec.txerr; in ctucan_err_interrupt()
856 cf->data[7] = bec.rxerr; in ctucan_err_interrupt()
860 priv->can.can_stats.error_warning++; in ctucan_err_interrupt()
862 cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT; in ctucan_err_interrupt()
863 cf->data[1] |= (bec.txerr > bec.rxerr) ? in ctucan_err_interrupt()
866 cf->data[6] = bec.txerr; in ctucan_err_interrupt()
867 cf->data[7] = bec.rxerr; in ctucan_err_interrupt()
872 cf->can_id |= CAN_ERR_CNT; in ctucan_err_interrupt()
873 cf->data[1] = CAN_ERR_CRTL_ACTIVE; in ctucan_err_interrupt()
874 cf->data[6] = bec.txerr; in ctucan_err_interrupt()
875 cf->data[7] = bec.rxerr; in ctucan_err_interrupt()
889 priv->can.can_stats.arbitration_lost++; in ctucan_err_interrupt()
891 cf->can_id |= CAN_ERR_LOSTARB; in ctucan_err_interrupt()
892 cf->data[0] = CAN_ERR_LOSTARB_UNSPEC; in ctucan_err_interrupt()
899 priv->can.can_stats.bus_error++; in ctucan_err_interrupt()
900 stats->rx_errors++; in ctucan_err_interrupt()
902 cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; in ctucan_err_interrupt()
903 cf->data[2] = CAN_ERR_PROT_UNSPEC; in ctucan_err_interrupt()
904 cf->data[3] = CAN_ERR_PROT_LOC_UNSPEC; in ctucan_err_interrupt()
909 stats->rx_packets++; in ctucan_err_interrupt()
910 stats->rx_bytes += cf->can_dlc; in ctucan_err_interrupt()
916 * ctucan_rx_poll() - Poll routine for rx packets (NAPI)
926 struct net_device *ndev = napi->dev; in ctucan_rx_poll()
943 struct net_device_stats *stats = &ndev->stats; in ctucan_rx_poll()
948 stats->rx_over_errors++; in ctucan_rx_poll()
949 stats->rx_errors++; in ctucan_rx_poll()
952 cf->can_id |= CAN_ERR_CRTL; in ctucan_rx_poll()
953 cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW; in ctucan_rx_poll()
954 stats->rx_packets++; in ctucan_rx_poll()
955 stats->rx_bytes += cf->can_dlc; in ctucan_rx_poll()
965 /* Clear and enable RBNEI. It is level-triggered, so in ctucan_rx_poll()
977 * ctucan_rotate_txb_prio() - Rotates priorities of TXT Buffers
983 u32 prio = priv->txb_prio; in ctucan_rotate_txb_prio()
985 prio = (prio << 4) | ((prio >> ((priv->ntxbufs - 1) * 4)) & 0xF); in ctucan_rotate_txb_prio()
986 ctucan_netdev_dbg(ndev, "%s: from 0x%08x to 0x%08x\n", __func__, priv->txb_prio, prio); in ctucan_rotate_txb_prio()
987 priv->txb_prio = prio; in ctucan_rotate_txb_prio()
992 * ctucan_tx_interrupt() - Tx done Isr
998 struct net_device_stats *stats = &ndev->stats; in ctucan_tx_interrupt()
1007 * if ok -> echo in ctucan_tx_interrupt()
1008 * if error / aborted -> ?? (find how to handle oneshot mode) in ctucan_tx_interrupt()
1012 spin_lock_irqsave(&priv->tx_lock, flags); in ctucan_tx_interrupt()
1015 while ((int)(priv->txb_head - priv->txb_tail) > 0) { in ctucan_tx_interrupt()
1016 txtb_id = priv->txb_tail % priv->ntxbufs; in ctucan_tx_interrupt()
1024 stats->tx_bytes += can_get_echo_skb(ndev, txtb_id, NULL); in ctucan_tx_interrupt()
1025 stats->tx_packets++; in ctucan_tx_interrupt()
1035 stats->tx_dropped++; in ctucan_tx_interrupt()
1039 * re-queue the frame, but multiqueue/abort is not supported yet in ctucan_tx_interrupt()
1044 stats->tx_dropped++; in ctucan_tx_interrupt()
1054 spin_unlock_irqrestore(&priv->tx_lock, flags); in ctucan_tx_interrupt()
1060 priv->txb_tail++; in ctucan_tx_interrupt()
1068 spin_unlock_irqrestore(&priv->tx_lock, flags); in ctucan_tx_interrupt()
1070 /* If no buffers were processed this time, we cannot clear - that would introduce in ctucan_tx_interrupt()
1082 spin_lock_irqsave(&priv->tx_lock, flags); in ctucan_tx_interrupt()
1088 spin_unlock_irqrestore(&priv->tx_lock, flags); in ctucan_tx_interrupt()
1092 * ctucan_interrupt() - CAN Isr
1100 * IRQ_NONE - If CAN device is in sleep mode, IRQ_HANDLED otherwise
1126 napi_schedule(&priv->napi); in ctucan_interrupt()
1155 priv->txb_head, priv->txb_tail); in ctucan_interrupt()
1156 for (i = 0; i < priv->ntxbufs; i++) { in ctucan_interrupt()
1171 * ctucan_chip_stop() - Driver stop routine
1190 priv->can.state = CAN_STATE_STOPPED; in ctucan_chip_stop()
1194 * ctucan_open() - Driver open routine
1205 ret = pm_runtime_get_sync(priv->dev); in ctucan_open()
1209 pm_runtime_put_noidle(priv->dev); in ctucan_open()
1224 ret = request_irq(ndev->irq, ctucan_interrupt, priv->irq_flags, ndev->name, ndev); in ctucan_open()
1237 napi_enable(&priv->napi); in ctucan_open()
1243 free_irq(ndev->irq, ndev); in ctucan_open()
1248 pm_runtime_put(priv->dev); in ctucan_open()
1254 * ctucan_close() - Driver close routine
1264 napi_disable(&priv->napi); in ctucan_close()
1266 free_irq(ndev->irq, ndev); in ctucan_close()
1269 pm_runtime_put(priv->dev); in ctucan_close()
1275 * ctucan_get_berr_counter() - error counter routine
1287 ret = pm_runtime_get_sync(priv->dev); in ctucan_get_berr_counter()
1290 pm_runtime_put_noidle(priv->dev); in ctucan_get_berr_counter()
1295 pm_runtime_put(priv->dev); in ctucan_get_berr_counter()
1321 priv->can.state = CAN_STATE_SLEEPING; in ctucan_suspend()
1332 priv->can.state = CAN_STATE_ERROR_ACTIVE; in ctucan_resume()
1354 return -ENOMEM; in ctucan_probe_common()
1357 spin_lock_init(&priv->tx_lock); in ctucan_probe_common()
1358 INIT_LIST_HEAD(&priv->peers_on_pdev); in ctucan_probe_common()
1359 priv->ntxbufs = ntxbufs; in ctucan_probe_common()
1360 priv->dev = dev; in ctucan_probe_common()
1361 priv->can.bittiming_const = &ctu_can_fd_bit_timing_max; in ctucan_probe_common()
1362 priv->can.fd.data_bittiming_const = &ctu_can_fd_bit_timing_data_max; in ctucan_probe_common()
1363 priv->can.do_set_mode = ctucan_do_set_mode; in ctucan_probe_common()
1365 /* Needed for timing adjustment to be performed as soon as possible */ in ctucan_probe_common()
1366 priv->can.do_set_bittiming = ctucan_set_bittiming; in ctucan_probe_common()
1367 priv->can.fd.do_set_data_bittiming = ctucan_set_data_bittiming; in ctucan_probe_common()
1369 priv->can.do_get_berr_counter = ctucan_get_berr_counter; in ctucan_probe_common()
1370 priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK in ctucan_probe_common()
1377 priv->mem_base = addr; in ctucan_probe_common()
1380 ndev->irq = irq; in ctucan_probe_common()
1381 ndev->flags |= IFF_ECHO; /* We support local echo */ in ctucan_probe_common()
1386 ndev->netdev_ops = &ctucan_netdev_ops; in ctucan_probe_common()
1387 ndev->ethtool_ops = &ctucan_ethtool_ops; in ctucan_probe_common()
1391 priv->can_clk = devm_clk_get(dev, NULL); in ctucan_probe_common()
1392 if (IS_ERR(priv->can_clk)) { in ctucan_probe_common()
1394 ret = PTR_ERR(priv->can_clk); in ctucan_probe_common()
1397 can_clk_rate = clk_get_rate(priv->can_clk); in ctucan_probe_common()
1400 priv->write_reg = ctucan_write32_le; in ctucan_probe_common()
1401 priv->read_reg = ctucan_read32_le; in ctucan_probe_common()
1409 pm_runtime_put_noidle(priv->dev); in ctucan_probe_common()
1413 /* Check for big-endianity and set according IO-accessors */ in ctucan_probe_common()
1415 priv->write_reg = ctucan_write32_be; in ctucan_probe_common()
1416 priv->read_reg = ctucan_read32_be; in ctucan_probe_common()
1419 ret = -ENODEV; in ctucan_probe_common()
1428 priv->can.clock.freq = can_clk_rate; in ctucan_probe_common()
1430 netif_napi_add(ndev, &priv->napi, ctucan_rx_poll); in ctucan_probe_common()
1441 priv->mem_base, ndev->irq, priv->can.clock.freq, priv->ntxbufs); in ctucan_probe_common()
1446 pm_runtime_put(priv->dev); in ctucan_probe_common()
1451 list_del_init(&priv->peers_on_pdev); in ctucan_probe_common()