Lines Matching +full:tx +full:- +full:freq
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2012 Stephane Grosjean <s.grosjean@peak-system.com>
7 * Copyright (C) 2001-2006 PEAK System-Technik GmbH
22 MODULE_AUTHOR("Stephane Grosjean <s.grosjean@peak-system.com>");
23 MODULE_DESCRIPTION("Socket-CAN driver for PEAK PCAN PCIe/M.2 FD family cards");
30 #define PCAN_CPCIEFD_ID 0x0014 /* for Compact-PCI Serial slot cards */
31 #define PCAN_PCIE104FD_ID 0x0017 /* for PCIe-104 Express slot cards */
32 #define PCAN_MINIPCIEFD_ID 0x0018 /* for mini-PCIe slot cards */
59 /* CAN-FD channel addresses */
64 /* CAN-FD channel registers */
67 #define PCIEFD_REG_CAN_CMD_PORT_L 0x0010 /* 64-bits command port */
69 #define PCIEFD_REG_CAN_TX_REQ_ACC 0x0020 /* Tx request accumulator */
70 #define PCIEFD_REG_CAN_TX_CTL_SET 0x0030 /* Tx control set register */
71 #define PCIEFD_REG_CAN_TX_CTL_CLR 0x0038 /* Tx control clear register */
72 #define PCIEFD_REG_CAN_TX_DMA_ADDR_L 0x0040 /* 64-bits addr for Tx DMA */
78 #define PCIEFD_REG_CAN_RX_DMA_ADDR_L 0x0070 /* 64-bits addr for Rx DMA */
81 /* CAN-FD channel misc register bits */
84 /* CAN-FD channel Clock SELector Source & DIVider */
109 /* CAN-FD channel Rx/Tx control register bits */
118 /* Tx anticipation window (link logical address should be aligned on 2K
123 #define CANFD_MSG_LNK_TX 0x1001 /* Tx msgs link */
125 /* 32-bits IRQ status fields, heading Rx DMA area */
149 /* Tx Link record */
157 /* Tx page descriptor */
165 /* CAN-FD channel object */
175 void *rx_dma_vaddr; /* for Rx and Tx areas */
180 u16 tx_pages_free; /* free Tx pages counter */
181 u16 tx_page_index; /* current page used for Tx */
188 /* PEAK-PCIe FD board object */
193 spinlock_t cmd_lock; /* 64-bits cmds must be atomic */
213 return readl(priv->reg_base + reg); in pciefd_sys_readreg()
220 writel(val, priv->reg_base + reg); in pciefd_sys_writereg()
223 /* read a 32 bits value from CAN-FD block register */
226 return readl(priv->reg_base + reg); in pciefd_can_readreg()
229 /* write a 32 bits value into a CAN-FD block register */
233 writel(val, priv->reg_base + reg); in pciefd_can_writereg()
240 const u32 dma_addr_h = (u32)(priv->rx_dma_laddr >> 32); in pciefd_can_setup_rx_dma()
249 pciefd_can_writereg(priv, (u32)priv->rx_dma_laddr, in pciefd_can_setup_rx_dma()
268 /* give a channel logical Tx DMA address to the board */
272 const u32 dma_addr_h = (u32)(priv->tx_dma_laddr >> 32); in pciefd_can_setup_tx_dma()
277 /* (DMA must be reset for Tx) */ in pciefd_can_setup_tx_dma()
280 /* write the logical address of the Tx DMA area for this channel */ in pciefd_can_setup_tx_dma()
281 pciefd_can_writereg(priv, (u32)priv->tx_dma_laddr, in pciefd_can_setup_tx_dma()
285 /* also indicates that Tx DMA is cacheable */ in pciefd_can_setup_tx_dma()
289 /* clear channel logical Tx DMA address from the board */
292 /* DMA must be reset for Tx */ in pciefd_can_clear_tx_dma()
295 /* clear the logical address of the Tx DMA area for this channel */ in pciefd_can_clear_tx_dma()
303 priv->irq_tag = le32_to_cpu(*(__le32 *)priv->rx_dma_vaddr); in pciefd_can_ack_rx_dma()
304 priv->irq_tag++; in pciefd_can_ack_rx_dma()
305 priv->irq_tag &= 0xf; in pciefd_can_ack_rx_dma()
308 pciefd_can_writereg(priv, priv->irq_tag, PCIEFD_REG_CAN_RX_CTL_ACK); in pciefd_can_ack_rx_dma()
315 struct pciefd_rx_dma *rx_dma = priv->rx_dma_vaddr; in pciefd_irq_handler()
318 if (!pci_dev_msi_enabled(priv->board->pci_dev)) in pciefd_irq_handler()
319 (void)pciefd_sys_readreg(priv->board, PCIEFD_REG_SYS_VER1); in pciefd_irq_handler()
321 /* read IRQ status from the first 32-bits of the Rx DMA area */ in pciefd_irq_handler()
322 priv->irq_status = le32_to_cpu(rx_dma->irq_status); in pciefd_irq_handler()
325 if (pciefd_irq_tag(priv->irq_status) != priv->irq_tag) in pciefd_irq_handler()
329 peak_canfd_handle_msgs_list(&priv->ucan, in pciefd_irq_handler()
330 rx_dma->msg, in pciefd_irq_handler()
331 pciefd_irq_rx_cnt(priv->irq_status)); in pciefd_irq_handler()
333 /* handle tx link interrupt (if any) */ in pciefd_irq_handler()
334 if (pciefd_irq_is_lnk(priv->irq_status)) { in pciefd_irq_handler()
337 spin_lock_irqsave(&priv->tx_lock, flags); in pciefd_irq_handler()
338 priv->tx_pages_free++; in pciefd_irq_handler()
339 spin_unlock_irqrestore(&priv->tx_lock, flags); in pciefd_irq_handler()
342 spin_lock_irqsave(&priv->ucan.echo_lock, flags); in pciefd_irq_handler()
343 if (!priv->ucan.can.echo_skb[priv->ucan.echo_idx]) in pciefd_irq_handler()
344 netif_wake_queue(priv->ucan.ndev); in pciefd_irq_handler()
346 spin_unlock_irqrestore(&priv->ucan.echo_lock, flags); in pciefd_irq_handler()
349 /* re-enable Rx DMA transfer for this CAN */ in pciefd_irq_handler()
360 /* initialize the Tx pages descriptors */ in pciefd_enable_tx_path()
361 priv->tx_pages_free = PCIEFD_TX_PAGE_COUNT - 1; in pciefd_enable_tx_path()
362 priv->tx_page_index = 0; in pciefd_enable_tx_path()
364 priv->tx_pages[0].vbase = priv->tx_dma_vaddr; in pciefd_enable_tx_path()
365 priv->tx_pages[0].lbase = priv->tx_dma_laddr; in pciefd_enable_tx_path()
368 priv->tx_pages[i].offset = 0; in pciefd_enable_tx_path()
369 priv->tx_pages[i].size = PCIEFD_TX_PAGE_SIZE - in pciefd_enable_tx_path()
372 priv->tx_pages[i].vbase = in pciefd_enable_tx_path()
373 priv->tx_pages[i - 1].vbase + in pciefd_enable_tx_path()
375 priv->tx_pages[i].lbase = in pciefd_enable_tx_path()
376 priv->tx_pages[i - 1].lbase + in pciefd_enable_tx_path()
381 /* setup Tx DMA addresses into IP core */ in pciefd_enable_tx_path()
384 /* start (TX_RST=0) Tx Path */ in pciefd_enable_tx_path()
390 /* board specific CANFD command pre-processing */
394 u16 cmd = pucan_cmd_get_opcode(&priv->pucan_cmd); in pciefd_pre_cmd()
397 /* pre-process command */ in pciefd_pre_cmd()
402 if (ucan->can.state == CAN_STATE_BUS_OFF) in pciefd_pre_cmd()
406 err = request_irq(priv->ucan.ndev->irq, in pciefd_pre_cmd()
437 /* Tx path will be setup as soon as RX_BARRIER is received */ in pciefd_pre_cmd()
452 /* 64-bits command is atomic */ in pciefd_write_cmd()
453 spin_lock_irqsave(&priv->board->cmd_lock, flags); in pciefd_write_cmd()
455 pciefd_can_writereg(priv, *(u32 *)ucan->cmd_buffer, in pciefd_write_cmd()
457 pciefd_can_writereg(priv, *(u32 *)(ucan->cmd_buffer + 4), in pciefd_write_cmd()
460 spin_unlock_irqrestore(&priv->board->cmd_lock, flags); in pciefd_write_cmd()
465 /* board specific CANFD command post-processing */
469 u16 cmd = pucan_cmd_get_opcode(&priv->pucan_cmd); in pciefd_post_cmd()
474 if (ucan->can.state == CAN_STATE_STOPPED) in pciefd_post_cmd()
483 /* stop and reset DMA addresses in Tx/Rx engines */ in pciefd_post_cmd()
488 (void)pciefd_sys_readreg(priv->board, PCIEFD_REG_SYS_VER1); in pciefd_post_cmd()
490 free_irq(priv->ucan.ndev->irq, priv); in pciefd_post_cmd()
492 ucan->can.state = CAN_STATE_STOPPED; in pciefd_post_cmd()
504 struct pciefd_page *page = priv->tx_pages + priv->tx_page_index; in pciefd_alloc_tx_msg()
508 spin_lock_irqsave(&priv->tx_lock, flags); in pciefd_alloc_tx_msg()
510 if (page->offset + msg_size > page->size) { in pciefd_alloc_tx_msg()
514 if (!priv->tx_pages_free) { in pciefd_alloc_tx_msg()
515 spin_unlock_irqrestore(&priv->tx_lock, flags); in pciefd_alloc_tx_msg()
517 /* Tx overflow */ in pciefd_alloc_tx_msg()
521 priv->tx_pages_free--; in pciefd_alloc_tx_msg()
524 lk = page->vbase + page->offset; in pciefd_alloc_tx_msg()
527 priv->tx_page_index = (priv->tx_page_index + 1) % in pciefd_alloc_tx_msg()
529 page = priv->tx_pages + priv->tx_page_index; in pciefd_alloc_tx_msg()
532 lk->size = cpu_to_le16(sizeof(*lk)); in pciefd_alloc_tx_msg()
533 lk->type = cpu_to_le16(CANFD_MSG_LNK_TX); in pciefd_alloc_tx_msg()
534 lk->laddr_lo = cpu_to_le32(page->lbase); in pciefd_alloc_tx_msg()
537 lk->laddr_hi = cpu_to_le32(page->lbase >> 32); in pciefd_alloc_tx_msg()
539 lk->laddr_hi = 0; in pciefd_alloc_tx_msg()
542 page->offset = 0; in pciefd_alloc_tx_msg()
545 *room_left = priv->tx_pages_free * page->size; in pciefd_alloc_tx_msg()
547 spin_unlock_irqrestore(&priv->tx_lock, flags); in pciefd_alloc_tx_msg()
549 msg = page->vbase + page->offset; in pciefd_alloc_tx_msg()
551 /* give back room left in the tx ring */ in pciefd_alloc_tx_msg()
552 *room_left += page->size - (page->offset + msg_size); in pciefd_alloc_tx_msg()
561 struct pciefd_page *page = priv->tx_pages + priv->tx_page_index; in pciefd_write_tx_msg()
564 page->offset += le16_to_cpu(msg->size); in pciefd_write_tx_msg()
566 /* tell the board a frame has been written in Tx DMA area */ in pciefd_write_tx_msg()
572 /* probe for CAN-FD channel #pciefd_board->can_count */
581 ndev = alloc_peak_canfd_dev(sizeof(*priv), pciefd->can_count, in pciefd_can_probe()
584 dev_err(&pciefd->pci_dev->dev, in pciefd_can_probe()
591 /* fill-in candev private object: */ in pciefd_can_probe()
593 /* setup PCIe-FD own callbacks */ in pciefd_can_probe()
594 priv->ucan.pre_cmd = pciefd_pre_cmd; in pciefd_can_probe()
595 priv->ucan.write_cmd = pciefd_write_cmd; in pciefd_can_probe()
596 priv->ucan.post_cmd = pciefd_post_cmd; in pciefd_can_probe()
597 priv->ucan.enable_tx_path = pciefd_enable_tx_path; in pciefd_can_probe()
598 priv->ucan.alloc_tx_msg = pciefd_alloc_tx_msg; in pciefd_can_probe()
599 priv->ucan.write_tx_msg = pciefd_write_tx_msg; in pciefd_can_probe()
601 /* setup PCIe-FD own command buffer */ in pciefd_can_probe()
602 priv->ucan.cmd_buffer = &priv->pucan_cmd; in pciefd_can_probe()
603 priv->ucan.cmd_maxlen = sizeof(priv->pucan_cmd); in pciefd_can_probe()
605 priv->board = pciefd; in pciefd_can_probe()
608 priv->reg_base = pciefd->reg_base + PCIEFD_CANX_OFF(priv->ucan.index); in pciefd_can_probe()
610 /* allocate non-cacheable DMA'able 4KB memory area for Rx */ in pciefd_can_probe()
611 priv->rx_dma_vaddr = dmam_alloc_coherent(&pciefd->pci_dev->dev, in pciefd_can_probe()
613 &priv->rx_dma_laddr, in pciefd_can_probe()
615 if (!priv->rx_dma_vaddr) { in pciefd_can_probe()
616 dev_err(&pciefd->pci_dev->dev, in pciefd_can_probe()
622 /* allocate non-cacheable DMA'able 4KB memory area for Tx */ in pciefd_can_probe()
623 priv->tx_dma_vaddr = dmam_alloc_coherent(&pciefd->pci_dev->dev, in pciefd_can_probe()
625 &priv->tx_dma_laddr, in pciefd_can_probe()
627 if (!priv->tx_dma_vaddr) { in pciefd_can_probe()
628 dev_err(&pciefd->pci_dev->dev, in pciefd_can_probe()
629 "Tx dmam_alloc_coherent(%u) failure\n", in pciefd_can_probe()
641 priv->ucan.can.clock.freq = 20 * 1000 * 1000; in pciefd_can_probe()
644 priv->ucan.can.clock.freq = 24 * 1000 * 1000; in pciefd_can_probe()
647 priv->ucan.can.clock.freq = 30 * 1000 * 1000; in pciefd_can_probe()
650 priv->ucan.can.clock.freq = 40 * 1000 * 1000; in pciefd_can_probe()
653 priv->ucan.can.clock.freq = 60 * 1000 * 1000; in pciefd_can_probe()
661 priv->ucan.can.clock.freq = 80 * 1000 * 1000; in pciefd_can_probe()
665 ndev->irq = pciefd->pci_dev->irq; in pciefd_can_probe()
667 SET_NETDEV_DEV(ndev, &pciefd->pci_dev->dev); in pciefd_can_probe()
671 dev_err(&pciefd->pci_dev->dev, in pciefd_can_probe()
676 spin_lock_init(&priv->tx_lock); in pciefd_can_probe()
679 pciefd->can[pciefd->can_count] = priv; in pciefd_can_probe()
681 dev_info(&pciefd->pci_dev->dev, "%s at reg_base=0x%p irq=%d\n", in pciefd_can_probe()
682 ndev->name, priv->reg_base, ndev->irq); in pciefd_can_probe()
690 return -ENOMEM; in pciefd_can_probe()
693 /* remove a CAN-FD channel by releasing all of its resources */
697 unregister_candev(priv->ucan.ndev); in pciefd_can_remove()
700 free_candev(priv->ucan.ndev); in pciefd_can_remove()
703 /* remove all CAN-FD channels by releasing their own resources */
706 while (pciefd->can_count > 0) in pciefd_can_remove_all()
707 pciefd_can_remove(pciefd->can[--pciefd->can_count]); in pciefd_can_remove_all()
729 /* the number of channels depends on sub-system id */ in peak_pciefd_probe()
734 dev_dbg(&pdev->dev, "probing device %04x:%04x:%04x\n", in peak_pciefd_probe()
735 pdev->vendor, pdev->device, sub_sys_id); in peak_pciefd_probe()
747 pciefd = devm_kzalloc(&pdev->dev, struct_size(pciefd, can, can_count), in peak_pciefd_probe()
750 err = -ENOMEM; in peak_pciefd_probe()
755 pciefd->pci_dev = pdev; in peak_pciefd_probe()
756 spin_lock_init(&pciefd->cmd_lock); in peak_pciefd_probe()
759 pciefd->reg_base = pci_iomap(pdev, 0, PCIEFD_BAR0_SIZE); in peak_pciefd_probe()
760 if (!pciefd->reg_base) { in peak_pciefd_probe()
761 dev_err(&pdev->dev, "failed to map PCI resource #0\n"); in peak_pciefd_probe()
762 err = -ENOMEM; in peak_pciefd_probe()
773 dev_info(&pdev->dev, in peak_pciefd_probe()
774 "%ux CAN-FD PCAN-PCIe FPGA v%u.%u.%u:\n", can_count, in peak_pciefd_probe()
778 /* FW < v3.3.0 DMA logic doesn't handle correctly the mix of 32-bit and in peak_pciefd_probe()
779 * 64-bit logical addresses: this workaround forces usage of 32-bit in peak_pciefd_probe()
784 err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); in peak_pciefd_probe()
786 dev_warn(&pdev->dev, in peak_pciefd_probe()
799 while (pciefd->can_count < can_count) { in peak_pciefd_probe()
804 pciefd->can_count++; in peak_pciefd_probe()
830 pci_iounmap(pdev, pciefd->reg_base); in peak_pciefd_probe()
850 /* release CAN-FD channels resources */ in peak_pciefd_remove()
853 pci_iounmap(pdev, pciefd->reg_base); in peak_pciefd_remove()