can: kvaser_pciefd: Add support for new Kvaser pciefd devices

Add support for new Kvaser pciefd devices, based on SmartFusion2 SoC.

Signed-off-by: Jimmy Assarsson <extja@kvaser.com>
Link: https://lore.kernel.org/all/20230622151153.294844-3-extja@kvaser.com
[mkl: mark structs as static]
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
This commit is contained in:
Jimmy Assarsson 2023-06-22 17:11:53 +02:00 committed by Marc Kleine-Budde
parent c2ad812956
commit f33ad6776b
2 changed files with 81 additions and 1 deletions

View File

@ -160,8 +160,13 @@ config CAN_KVASER_PCIEFD
Kvaser PCIEcan 4xHS
Kvaser PCIEcan 2xHS v2
Kvaser PCIEcan HS v2
Kvaser PCIEcan 1xCAN v3
Kvaser PCIEcan 2xCAN v3
Kvaser PCIEcan 4xCAN v2
Kvaser Mini PCI Express HS v2
Kvaser Mini PCI Express 2xHS v2
Kvaser Mini PCI Express 1xCAN v3
Kvaser Mini PCI Express 2xCAN v3
config CAN_SLCAN
tristate "Serial / USB serial CAN Adaptors (slcan)"

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
/* Copyright (C) 2018 KVASER AB, Sweden. All rights reserved.
* Parts of this driver are based on the following:
* - Kvaser linux pciefd driver (version 5.25)
* - Kvaser linux pciefd driver (version 5.42)
* - PEAK linux canfd driver
*/
@ -40,9 +40,19 @@ MODULE_DESCRIPTION("CAN driver for Kvaser CAN/PCIe devices");
#define KVASER_PCIEFD_MINIPCIE_HS_V2_DEVICE_ID 0x0010
#define KVASER_PCIEFD_MINIPCIE_2HS_V2_DEVICE_ID 0x0011
/* SmartFusion2 based devices */
#define KVASER_PCIEFD_2CAN_V3_DEVICE_ID 0x0012
#define KVASER_PCIEFD_1CAN_V3_DEVICE_ID 0x0013
#define KVASER_PCIEFD_4CAN_V2_DEVICE_ID 0x0014
#define KVASER_PCIEFD_MINIPCIE_2CAN_V3_DEVICE_ID 0x0015
#define KVASER_PCIEFD_MINIPCIE_1CAN_V3_DEVICE_ID 0x0016
/* Altera SerDes Enable 64-bit DMA address translation */
#define KVASER_PCIEFD_ALTERA_DMA_64BIT BIT(0)
/* SmartFusion2 SerDes LSB address translation mask */
#define KVASER_PCIEFD_SF2_DMA_LSB_MASK GENMASK(31, 12)
/* Kvaser KCAN CAN controller registers */
#define KVASER_PCIEFD_KCAN_FIFO_REG 0x100
#define KVASER_PCIEFD_KCAN_FIFO_LAST_REG 0x180
@ -269,6 +279,8 @@ MODULE_DESCRIPTION("CAN driver for Kvaser CAN/PCIe devices");
struct kvaser_pciefd;
static void kvaser_pciefd_write_dma_map_altera(struct kvaser_pciefd *pcie,
dma_addr_t addr, int index);
static void kvaser_pciefd_write_dma_map_sf2(struct kvaser_pciefd *pcie,
dma_addr_t addr, int index);
struct kvaser_pciefd_address_offset {
u32 serdes;
@ -311,22 +323,50 @@ static const struct kvaser_pciefd_address_offset kvaser_pciefd_altera_address_of
.kcan_ch1 = 0x11000,
};
static const struct kvaser_pciefd_address_offset kvaser_pciefd_sf2_address_offset = {
.serdes = 0x280c8,
.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 = {
.kcan_rx0 = BIT(4),
.kcan_tx = { BIT(0), BIT(1), BIT(2), BIT(3) },
.all = GENMASK(4, 0),
};
static const struct kvaser_pciefd_irq_mask kvaser_pciefd_sf2_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 = {
.kvaser_pciefd_write_dma_map = kvaser_pciefd_write_dma_map_altera,
};
static const struct kvaser_pciefd_dev_ops kvaser_pciefd_sf2_dev_ops = {
.kvaser_pciefd_write_dma_map = kvaser_pciefd_write_dma_map_sf2,
};
static const struct kvaser_pciefd_driver_data kvaser_pciefd_altera_driver_data = {
.address_offset = &kvaser_pciefd_altera_address_offset,
.irq_mask = &kvaser_pciefd_altera_irq_mask,
.ops = &kvaser_pciefd_altera_dev_ops,
};
static const struct kvaser_pciefd_driver_data kvaser_pciefd_sf2_driver_data = {
.address_offset = &kvaser_pciefd_sf2_address_offset,
.irq_mask = &kvaser_pciefd_sf2_irq_mask,
.ops = &kvaser_pciefd_sf2_dev_ops,
};
struct kvaser_pciefd_can {
struct can_priv can;
struct kvaser_pciefd *kv_pcie;
@ -396,6 +436,26 @@ static struct pci_device_id kvaser_pciefd_id_table[] = {
PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_MINIPCIE_2HS_V2_DEVICE_ID),
.driver_data = (kernel_ulong_t)&kvaser_pciefd_altera_driver_data,
},
{
PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_2CAN_V3_DEVICE_ID),
.driver_data = (kernel_ulong_t)&kvaser_pciefd_sf2_driver_data,
},
{
PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_1CAN_V3_DEVICE_ID),
.driver_data = (kernel_ulong_t)&kvaser_pciefd_sf2_driver_data,
},
{
PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_4CAN_V2_DEVICE_ID),
.driver_data = (kernel_ulong_t)&kvaser_pciefd_sf2_driver_data,
},
{
PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_MINIPCIE_2CAN_V3_DEVICE_ID),
.driver_data = (kernel_ulong_t)&kvaser_pciefd_sf2_driver_data,
},
{
PCI_DEVICE(KVASER_PCIEFD_VENDOR, KVASER_PCIEFD_MINIPCIE_1CAN_V3_DEVICE_ID),
.driver_data = (kernel_ulong_t)&kvaser_pciefd_sf2_driver_data,
},
{
0,
},
@ -960,6 +1020,21 @@ static void kvaser_pciefd_write_dma_map_altera(struct kvaser_pciefd *pcie,
iowrite32(word2, serdes_base + 0x4);
}
static void kvaser_pciefd_write_dma_map_sf2(struct kvaser_pciefd *pcie,
dma_addr_t addr, int index)
{
void __iomem *serdes_base;
u32 lsb = addr & KVASER_PCIEFD_SF2_DMA_LSB_MASK;
u32 msb = 0x0;
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
msb = addr >> 32;
#endif
serdes_base = KVASER_PCIEFD_SERDES_ADDR(pcie) + 0x10 * index;
iowrite32(lsb, serdes_base);
iowrite32(msb, serdes_base + 0x4);
}
static int kvaser_pciefd_setup_dma(struct kvaser_pciefd *pcie)
{
int i;