1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * PCI Specific M_CAN Glue 4 * 5 * Copyright (C) 2018-2020 Intel Corporation 6 * Author: Felipe Balbi (Intel) 7 * Author: Jarkko Nikula <jarkko.nikula@linux.intel.com> 8 * Author: Raymond Tan <raymond.tan@intel.com> 9 */ 10 11 #include <linux/kernel.h> 12 #include <linux/module.h> 13 #include <linux/netdevice.h> 14 #include <linux/pci.h> 15 #include <linux/pm_runtime.h> 16 17 #include "m_can.h" 18 19 #define M_CAN_PCI_MMIO_BAR 0 20 21 #define CTL_CSR_INT_CTL_OFFSET 0x508 22 23 struct m_can_pci_config { 24 const struct can_bittiming_const *bit_timing; 25 const struct can_bittiming_const *data_timing; 26 unsigned int clock_freq; 27 }; 28 29 struct m_can_pci_priv { 30 struct m_can_classdev cdev; 31 32 void __iomem *base; 33 }; 34 35 static inline struct m_can_pci_priv *cdev_to_priv(struct m_can_classdev *cdev) 36 { 37 return container_of(cdev, struct m_can_pci_priv, cdev); 38 } 39 40 static u32 iomap_read_reg(struct m_can_classdev *cdev, int reg) 41 { 42 struct m_can_pci_priv *priv = cdev_to_priv(cdev); 43 44 return readl(priv->base + reg); 45 } 46 47 static int iomap_read_fifo(struct m_can_classdev *cdev, int offset, void *val, size_t val_count) 48 { 49 struct m_can_pci_priv *priv = cdev_to_priv(cdev); 50 void __iomem *src = priv->base + offset; 51 52 while (val_count--) { 53 *(unsigned int *)val = ioread32(src); 54 val += 4; 55 src += 4; 56 } 57 58 return 0; 59 } 60 61 static int iomap_write_reg(struct m_can_classdev *cdev, int reg, int val) 62 { 63 struct m_can_pci_priv *priv = cdev_to_priv(cdev); 64 65 writel(val, priv->base + reg); 66 67 return 0; 68 } 69 70 static int iomap_write_fifo(struct m_can_classdev *cdev, int offset, 71 const void *val, size_t val_count) 72 { 73 struct m_can_pci_priv *priv = cdev_to_priv(cdev); 74 void __iomem *dst = priv->base + offset; 75 76 while (val_count--) { 77 iowrite32(*(unsigned int *)val, dst); 78 val += 4; 79 dst += 4; 80 } 81 82 return 0; 83 } 84 85 static struct m_can_ops m_can_pci_ops = { 86 .read_reg = iomap_read_reg, 87 .write_reg = iomap_write_reg, 88 .write_fifo = iomap_write_fifo, 89 .read_fifo = iomap_read_fifo, 90 }; 91 92 static const struct can_bittiming_const m_can_bittiming_const_ehl = { 93 .name = KBUILD_MODNAME, 94 .tseg1_min = 2, /* Time segment 1 = prop_seg + phase_seg1 */ 95 .tseg1_max = 64, 96 .tseg2_min = 1, /* Time segment 2 = phase_seg2 */ 97 .tseg2_max = 128, 98 .sjw_max = 128, 99 .brp_min = 1, 100 .brp_max = 512, 101 .brp_inc = 1, 102 }; 103 104 static const struct can_bittiming_const m_can_data_bittiming_const_ehl = { 105 .name = KBUILD_MODNAME, 106 .tseg1_min = 2, /* Time segment 1 = prop_seg + phase_seg1 */ 107 .tseg1_max = 16, 108 .tseg2_min = 1, /* Time segment 2 = phase_seg2 */ 109 .tseg2_max = 8, 110 .sjw_max = 4, 111 .brp_min = 1, 112 .brp_max = 32, 113 .brp_inc = 1, 114 }; 115 116 static const struct m_can_pci_config m_can_pci_ehl = { 117 .bit_timing = &m_can_bittiming_const_ehl, 118 .data_timing = &m_can_data_bittiming_const_ehl, 119 .clock_freq = 200000000, 120 }; 121 122 static int m_can_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) 123 { 124 struct device *dev = &pci->dev; 125 const struct m_can_pci_config *cfg; 126 struct m_can_classdev *mcan_class; 127 struct m_can_pci_priv *priv; 128 void __iomem *base; 129 int ret; 130 131 ret = pcim_enable_device(pci); 132 if (ret) 133 return ret; 134 135 pci_set_master(pci); 136 137 ret = pcim_iomap_regions(pci, BIT(M_CAN_PCI_MMIO_BAR), pci_name(pci)); 138 if (ret) 139 return ret; 140 141 base = pcim_iomap_table(pci)[M_CAN_PCI_MMIO_BAR]; 142 143 if (!base) { 144 dev_err(dev, "failed to map BARs\n"); 145 return -ENOMEM; 146 } 147 148 mcan_class = m_can_class_allocate_dev(&pci->dev, 149 sizeof(struct m_can_pci_priv)); 150 if (!mcan_class) 151 return -ENOMEM; 152 153 cfg = (const struct m_can_pci_config *)id->driver_data; 154 155 priv = cdev_to_priv(mcan_class); 156 157 priv->base = base; 158 159 ret = pci_alloc_irq_vectors(pci, 1, 1, PCI_IRQ_ALL_TYPES); 160 if (ret < 0) 161 return ret; 162 163 mcan_class->dev = &pci->dev; 164 mcan_class->net->irq = pci_irq_vector(pci, 0); 165 mcan_class->pm_clock_support = 1; 166 mcan_class->bit_timing = cfg->bit_timing; 167 mcan_class->data_timing = cfg->data_timing; 168 mcan_class->can.clock.freq = cfg->clock_freq; 169 mcan_class->ops = &m_can_pci_ops; 170 171 pci_set_drvdata(pci, mcan_class); 172 173 ret = m_can_class_register(mcan_class); 174 if (ret) 175 goto err; 176 177 /* Enable interrupt control at CAN wrapper IP */ 178 writel(0x1, base + CTL_CSR_INT_CTL_OFFSET); 179 180 pm_runtime_set_autosuspend_delay(dev, 1000); 181 pm_runtime_use_autosuspend(dev); 182 pm_runtime_put_noidle(dev); 183 pm_runtime_allow(dev); 184 185 return 0; 186 187 err: 188 pci_free_irq_vectors(pci); 189 return ret; 190 } 191 192 static void m_can_pci_remove(struct pci_dev *pci) 193 { 194 struct m_can_classdev *mcan_class = pci_get_drvdata(pci); 195 struct m_can_pci_priv *priv = cdev_to_priv(mcan_class); 196 197 pm_runtime_forbid(&pci->dev); 198 pm_runtime_get_noresume(&pci->dev); 199 200 /* Disable interrupt control at CAN wrapper IP */ 201 writel(0x0, priv->base + CTL_CSR_INT_CTL_OFFSET); 202 203 m_can_class_unregister(mcan_class); 204 pci_free_irq_vectors(pci); 205 } 206 207 static __maybe_unused int m_can_pci_suspend(struct device *dev) 208 { 209 return m_can_class_suspend(dev); 210 } 211 212 static __maybe_unused int m_can_pci_resume(struct device *dev) 213 { 214 return m_can_class_resume(dev); 215 } 216 217 static SIMPLE_DEV_PM_OPS(m_can_pci_pm_ops, 218 m_can_pci_suspend, m_can_pci_resume); 219 220 static const struct pci_device_id m_can_pci_id_table[] = { 221 { PCI_VDEVICE(INTEL, 0x4bc1), (kernel_ulong_t)&m_can_pci_ehl, }, 222 { PCI_VDEVICE(INTEL, 0x4bc2), (kernel_ulong_t)&m_can_pci_ehl, }, 223 { } /* Terminating Entry */ 224 }; 225 MODULE_DEVICE_TABLE(pci, m_can_pci_id_table); 226 227 static struct pci_driver m_can_pci_driver = { 228 .name = "m_can_pci", 229 .probe = m_can_pci_probe, 230 .remove = m_can_pci_remove, 231 .id_table = m_can_pci_id_table, 232 .driver = { 233 .pm = &m_can_pci_pm_ops, 234 }, 235 }; 236 237 module_pci_driver(m_can_pci_driver); 238 239 MODULE_AUTHOR("Felipe Balbi (Intel)"); 240 MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@linux.intel.com>"); 241 MODULE_AUTHOR("Raymond Tan <raymond.tan@intel.com>"); 242 MODULE_LICENSE("GPL"); 243 MODULE_DESCRIPTION("CAN bus driver for Bosch M_CAN controller on PCI bus"); 244