Commit 85216f56 authored by Jimmy Assarsson's avatar Jimmy Assarsson Committed by Marc Kleine-Budde

can: kvaser_pciefd: Add support for Kvaser M.2 PCIe 4xCAN

Add support for new Kvaser pciefd device, M.2 PCIe 4xCAN, based on
Xilinx FPGA.
Signed-off-by: default avatarJimmy Assarsson <extja@kvaser.com>
Link: https://lore.kernel.org/all/20231113134717.515037-1-extja@kvaser.comSigned-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent 7d06d15d
...@@ -168,6 +168,7 @@ config CAN_KVASER_PCIEFD ...@@ -168,6 +168,7 @@ config CAN_KVASER_PCIEFD
Kvaser Mini PCI Express 2xHS v2 Kvaser Mini PCI Express 2xHS v2
Kvaser Mini PCI Express 1xCAN v3 Kvaser Mini PCI Express 1xCAN v3
Kvaser Mini PCI Express 2xCAN v3 Kvaser Mini PCI Express 2xCAN v3
Kvaser M.2 PCIe 4xCAN
config CAN_SLCAN config CAN_SLCAN
tristate "Serial / USB serial CAN Adaptors (slcan)" tristate "Serial / USB serial CAN Adaptors (slcan)"
......
...@@ -47,12 +47,18 @@ MODULE_DESCRIPTION("CAN driver for Kvaser CAN/PCIe devices"); ...@@ -47,12 +47,18 @@ MODULE_DESCRIPTION("CAN driver for Kvaser CAN/PCIe devices");
#define KVASER_PCIEFD_MINIPCIE_2CAN_V3_DEVICE_ID 0x0015 #define KVASER_PCIEFD_MINIPCIE_2CAN_V3_DEVICE_ID 0x0015
#define KVASER_PCIEFD_MINIPCIE_1CAN_V3_DEVICE_ID 0x0016 #define KVASER_PCIEFD_MINIPCIE_1CAN_V3_DEVICE_ID 0x0016
/* Xilinx based devices */
#define KVASER_PCIEFD_M2_4CAN_DEVICE_ID 0x0017
/* Altera SerDes Enable 64-bit DMA address translation */ /* Altera SerDes Enable 64-bit DMA address translation */
#define KVASER_PCIEFD_ALTERA_DMA_64BIT BIT(0) #define KVASER_PCIEFD_ALTERA_DMA_64BIT BIT(0)
/* SmartFusion2 SerDes LSB address translation mask */ /* SmartFusion2 SerDes LSB address translation mask */
#define KVASER_PCIEFD_SF2_DMA_LSB_MASK GENMASK(31, 12) #define KVASER_PCIEFD_SF2_DMA_LSB_MASK GENMASK(31, 12)
/* Xilinx SerDes LSB address translation mask */
#define KVASER_PCIEFD_XILINX_DMA_LSB_MASK GENMASK(31, 12)
/* Kvaser KCAN CAN controller registers */ /* Kvaser KCAN CAN controller registers */
#define KVASER_PCIEFD_KCAN_FIFO_REG 0x100 #define KVASER_PCIEFD_KCAN_FIFO_REG 0x100
#define KVASER_PCIEFD_KCAN_FIFO_LAST_REG 0x180 #define KVASER_PCIEFD_KCAN_FIFO_LAST_REG 0x180
...@@ -281,6 +287,8 @@ static void kvaser_pciefd_write_dma_map_altera(struct kvaser_pciefd *pcie, ...@@ -281,6 +287,8 @@ static void kvaser_pciefd_write_dma_map_altera(struct kvaser_pciefd *pcie,
dma_addr_t addr, int index); dma_addr_t addr, int index);
static void kvaser_pciefd_write_dma_map_sf2(struct kvaser_pciefd *pcie, static void kvaser_pciefd_write_dma_map_sf2(struct kvaser_pciefd *pcie,
dma_addr_t addr, int index); dma_addr_t addr, int index);
static void kvaser_pciefd_write_dma_map_xilinx(struct kvaser_pciefd *pcie,
dma_addr_t addr, int index);
struct kvaser_pciefd_address_offset { struct kvaser_pciefd_address_offset {
u32 serdes; u32 serdes;
...@@ -335,6 +343,18 @@ static const struct kvaser_pciefd_address_offset kvaser_pciefd_sf2_address_offse ...@@ -335,6 +343,18 @@ static const struct kvaser_pciefd_address_offset kvaser_pciefd_sf2_address_offse
.kcan_ch1 = 0x142000, .kcan_ch1 = 0x142000,
}; };
static const struct kvaser_pciefd_address_offset kvaser_pciefd_xilinx_address_offset = {
.serdes = 0x00208,
.pci_ien = 0x102004,
.pci_irq = 0x102008,
.sysid = 0x100000,
.loopback = 0x103000,
.kcan_srb_fifo = 0x120000,
.kcan_srb = 0x121000,
.kcan_ch0 = 0x140000,
.kcan_ch1 = 0x142000,
};
static const struct kvaser_pciefd_irq_mask kvaser_pciefd_altera_irq_mask = { static const struct kvaser_pciefd_irq_mask kvaser_pciefd_altera_irq_mask = {
.kcan_rx0 = BIT(4), .kcan_rx0 = BIT(4),
.kcan_tx = { BIT(0), BIT(1), BIT(2), BIT(3) }, .kcan_tx = { BIT(0), BIT(1), BIT(2), BIT(3) },
...@@ -347,6 +367,12 @@ static const struct kvaser_pciefd_irq_mask kvaser_pciefd_sf2_irq_mask = { ...@@ -347,6 +367,12 @@ static const struct kvaser_pciefd_irq_mask kvaser_pciefd_sf2_irq_mask = {
.all = GENMASK(19, 16) | BIT(4), .all = GENMASK(19, 16) | BIT(4),
}; };
static const struct kvaser_pciefd_irq_mask kvaser_pciefd_xilinx_irq_mask = {
.kcan_rx0 = BIT(4),
.kcan_tx = { BIT(16), BIT(17), BIT(18), BIT(19) },
.all = GENMASK(19, 16) | BIT(4),
};
static const struct kvaser_pciefd_dev_ops kvaser_pciefd_altera_dev_ops = { static const struct kvaser_pciefd_dev_ops kvaser_pciefd_altera_dev_ops = {
.kvaser_pciefd_write_dma_map = kvaser_pciefd_write_dma_map_altera, .kvaser_pciefd_write_dma_map = kvaser_pciefd_write_dma_map_altera,
}; };
...@@ -355,6 +381,10 @@ static const struct kvaser_pciefd_dev_ops kvaser_pciefd_sf2_dev_ops = { ...@@ -355,6 +381,10 @@ static const struct kvaser_pciefd_dev_ops kvaser_pciefd_sf2_dev_ops = {
.kvaser_pciefd_write_dma_map = kvaser_pciefd_write_dma_map_sf2, .kvaser_pciefd_write_dma_map = kvaser_pciefd_write_dma_map_sf2,
}; };
static const struct kvaser_pciefd_dev_ops kvaser_pciefd_xilinx_dev_ops = {
.kvaser_pciefd_write_dma_map = kvaser_pciefd_write_dma_map_xilinx,
};
static const struct kvaser_pciefd_driver_data kvaser_pciefd_altera_driver_data = { static const struct kvaser_pciefd_driver_data kvaser_pciefd_altera_driver_data = {
.address_offset = &kvaser_pciefd_altera_address_offset, .address_offset = &kvaser_pciefd_altera_address_offset,
.irq_mask = &kvaser_pciefd_altera_irq_mask, .irq_mask = &kvaser_pciefd_altera_irq_mask,
...@@ -367,6 +397,12 @@ static const struct kvaser_pciefd_driver_data kvaser_pciefd_sf2_driver_data = { ...@@ -367,6 +397,12 @@ static const struct kvaser_pciefd_driver_data kvaser_pciefd_sf2_driver_data = {
.ops = &kvaser_pciefd_sf2_dev_ops, .ops = &kvaser_pciefd_sf2_dev_ops,
}; };
static const struct kvaser_pciefd_driver_data kvaser_pciefd_xilinx_driver_data = {
.address_offset = &kvaser_pciefd_xilinx_address_offset,
.irq_mask = &kvaser_pciefd_xilinx_irq_mask,
.ops = &kvaser_pciefd_xilinx_dev_ops,
};
struct kvaser_pciefd_can { struct kvaser_pciefd_can {
struct can_priv can; struct can_priv can;
struct kvaser_pciefd *kv_pcie; struct kvaser_pciefd *kv_pcie;
...@@ -456,6 +492,10 @@ static struct pci_device_id kvaser_pciefd_id_table[] = { ...@@ -456,6 +492,10 @@ static struct pci_device_id kvaser_pciefd_id_table[] = {
PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_MINIPCIE_1CAN_V3_DEVICE_ID), PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_MINIPCIE_1CAN_V3_DEVICE_ID),
.driver_data = (kernel_ulong_t)&kvaser_pciefd_sf2_driver_data, .driver_data = (kernel_ulong_t)&kvaser_pciefd_sf2_driver_data,
}, },
{
PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_M2_4CAN_DEVICE_ID),
.driver_data = (kernel_ulong_t)&kvaser_pciefd_xilinx_driver_data,
},
{ {
0, 0,
}, },
...@@ -1035,6 +1075,21 @@ static void kvaser_pciefd_write_dma_map_sf2(struct kvaser_pciefd *pcie, ...@@ -1035,6 +1075,21 @@ static void kvaser_pciefd_write_dma_map_sf2(struct kvaser_pciefd *pcie,
iowrite32(msb, serdes_base + 0x4); iowrite32(msb, serdes_base + 0x4);
} }
static void kvaser_pciefd_write_dma_map_xilinx(struct kvaser_pciefd *pcie,
dma_addr_t addr, int index)
{
void __iomem *serdes_base;
u32 lsb = addr & KVASER_PCIEFD_XILINX_DMA_LSB_MASK;
u32 msb = 0x0;
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
msb = addr >> 32;
#endif
serdes_base = KVASER_PCIEFD_SERDES_ADDR(pcie) + 0x8 * index;
iowrite32(msb, serdes_base);
iowrite32(lsb, serdes_base + 0x4);
}
static int kvaser_pciefd_setup_dma(struct kvaser_pciefd *pcie) static int kvaser_pciefd_setup_dma(struct kvaser_pciefd *pcie)
{ {
int i; int i;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment