linux/drivers/staging/kpc2000/kpc2000/core.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2#include <linux/kernel.h>
   3#include <linux/idr.h>
   4#include <linux/init.h>
   5#include <linux/module.h>
   6#include <linux/pci.h>
   7#include <linux/types.h>
   8#include <linux/export.h>
   9#include <linux/slab.h>
  10#include <linux/fs.h>
  11#include <linux/errno.h>
  12#include <linux/cdev.h>
  13#include <linux/rwsem.h>
  14#include <linux/uaccess.h>
  15#include <linux/io.h>
  16#include <linux/mfd/core.h>
  17#include <linux/platform_device.h>
  18#include <linux/ioport.h>
  19#include <linux/io-64-nonatomic-lo-hi.h>
  20#include <linux/interrupt.h>
  21#include <linux/workqueue.h>
  22#include <linux/device.h>
  23#include <linux/sched.h>
  24#include <linux/jiffies.h>
  25#include "pcie.h"
  26#include "uapi.h"
  27
  28static DEFINE_IDA(card_num_ida);
  29
  30/*******************************************************
  31 * SysFS Attributes
  32 ******************************************************/
  33
  34static ssize_t ssid_show(struct device *dev, struct device_attribute *attr,
  35                         char *buf)
  36{
  37        struct kp2000_device *pcard = dev_get_drvdata(dev);
  38
  39        return sprintf(buf, "%016llx\n", pcard->ssid);
  40}
  41static DEVICE_ATTR_RO(ssid);
  42
  43static ssize_t ddna_show(struct device *dev, struct device_attribute *attr,
  44                         char *buf)
  45{
  46        struct kp2000_device *pcard = dev_get_drvdata(dev);
  47
  48        return sprintf(buf, "%016llx\n", pcard->ddna);
  49}
  50static DEVICE_ATTR_RO(ddna);
  51
  52static ssize_t card_id_show(struct device *dev, struct device_attribute *attr,
  53                            char *buf)
  54{
  55        struct kp2000_device *pcard = dev_get_drvdata(dev);
  56
  57        return sprintf(buf, "%08x\n", pcard->card_id);
  58}
  59static DEVICE_ATTR_RO(card_id);
  60
  61static ssize_t hw_rev_show(struct device *dev, struct device_attribute *attr,
  62                           char *buf)
  63{
  64        struct kp2000_device *pcard = dev_get_drvdata(dev);
  65
  66        return sprintf(buf, "%08x\n", pcard->hardware_revision);
  67}
  68static DEVICE_ATTR_RO(hw_rev);
  69
  70static ssize_t build_show(struct device *dev, struct device_attribute *attr,
  71                          char *buf)
  72{
  73        struct kp2000_device *pcard = dev_get_drvdata(dev);
  74
  75        return sprintf(buf, "%08x\n", pcard->build_version);
  76}
  77static DEVICE_ATTR_RO(build);
  78
  79static ssize_t build_date_show(struct device *dev,
  80                               struct device_attribute *attr, char *buf)
  81{
  82        struct kp2000_device *pcard = dev_get_drvdata(dev);
  83
  84        return sprintf(buf, "%08x\n", pcard->build_datestamp);
  85}
  86static DEVICE_ATTR_RO(build_date);
  87
  88static ssize_t build_time_show(struct device *dev,
  89                               struct device_attribute *attr, char *buf)
  90{
  91        struct kp2000_device *pcard = dev_get_drvdata(dev);
  92
  93        return sprintf(buf, "%08x\n", pcard->build_timestamp);
  94}
  95static DEVICE_ATTR_RO(build_time);
  96
  97static ssize_t cpld_reg_show(struct device *dev, struct device_attribute *attr,
  98                             char *buf)
  99{
 100        struct kp2000_device *pcard = dev_get_drvdata(dev);
 101        u64 val;
 102
 103        val = readq(pcard->sysinfo_regs_base + REG_CPLD_CONFIG);
 104        return sprintf(buf, "%016llx\n", val);
 105}
 106static DEVICE_ATTR_RO(cpld_reg);
 107
 108static ssize_t cpld_reconfigure(struct device *dev,
 109                                struct device_attribute *attr,
 110                                const char *buf, size_t count)
 111{
 112        struct kp2000_device *pcard = dev_get_drvdata(dev);
 113        unsigned long wr_val;
 114        int rv;
 115
 116        rv = kstrtoul(buf, 0, &wr_val);
 117        if (rv < 0)
 118                return rv;
 119        if (wr_val > 7)
 120                return -EINVAL;
 121
 122        wr_val = wr_val << 8;
 123        wr_val |= 0x1; // Set the "Configure Go" bit
 124        writeq(wr_val, pcard->sysinfo_regs_base + REG_CPLD_CONFIG);
 125        return count;
 126}
 127static DEVICE_ATTR(cpld_reconfigure, 0220, NULL, cpld_reconfigure);
 128
 129static ssize_t irq_mask_reg_show(struct device *dev,
 130                                 struct device_attribute *attr, char *buf)
 131{
 132        struct kp2000_device *pcard = dev_get_drvdata(dev);
 133        u64 val;
 134
 135        val = readq(pcard->sysinfo_regs_base + REG_INTERRUPT_MASK);
 136        return sprintf(buf, "%016llx\n", val);
 137}
 138static DEVICE_ATTR_RO(irq_mask_reg);
 139
 140static ssize_t irq_active_reg_show(struct device *dev,
 141                                   struct device_attribute *attr, char *buf)
 142{
 143        struct kp2000_device *pcard = dev_get_drvdata(dev);
 144        u64 val;
 145
 146        val = readq(pcard->sysinfo_regs_base + REG_INTERRUPT_ACTIVE);
 147        return sprintf(buf, "%016llx\n", val);
 148}
 149static DEVICE_ATTR_RO(irq_active_reg);
 150
 151static ssize_t pcie_error_count_reg_show(struct device *dev,
 152                                         struct device_attribute *attr,
 153                                         char *buf)
 154{
 155        struct kp2000_device *pcard = dev_get_drvdata(dev);
 156        u64 val;
 157
 158        val = readq(pcard->sysinfo_regs_base + REG_PCIE_ERROR_COUNT);
 159        return sprintf(buf, "%016llx\n", val);
 160}
 161static DEVICE_ATTR_RO(pcie_error_count_reg);
 162
 163static ssize_t core_table_offset_show(struct device *dev,
 164                                      struct device_attribute *attr, char *buf)
 165{
 166        struct kp2000_device *pcard = dev_get_drvdata(dev);
 167
 168        return sprintf(buf, "%08x\n", pcard->core_table_offset);
 169}
 170static DEVICE_ATTR_RO(core_table_offset);
 171
 172static ssize_t core_table_length_show(struct device *dev,
 173                                      struct device_attribute *attr, char *buf)
 174{
 175        struct kp2000_device *pcard = dev_get_drvdata(dev);
 176
 177        return sprintf(buf, "%08x\n", pcard->core_table_length);
 178}
 179static DEVICE_ATTR_RO(core_table_length);
 180
 181static const struct attribute *kp_attr_list[] = {
 182        &dev_attr_ssid.attr,
 183        &dev_attr_ddna.attr,
 184        &dev_attr_card_id.attr,
 185        &dev_attr_hw_rev.attr,
 186        &dev_attr_build.attr,
 187        &dev_attr_build_date.attr,
 188        &dev_attr_build_time.attr,
 189        &dev_attr_cpld_reg.attr,
 190        &dev_attr_cpld_reconfigure.attr,
 191        &dev_attr_irq_mask_reg.attr,
 192        &dev_attr_irq_active_reg.attr,
 193        &dev_attr_pcie_error_count_reg.attr,
 194        &dev_attr_core_table_offset.attr,
 195        &dev_attr_core_table_length.attr,
 196        NULL,
 197};
 198
 199/*******************************************************
 200 * Functions
 201 ******************************************************/
 202
 203static void wait_and_read_ssid(struct kp2000_device *pcard)
 204{
 205        u64 read_val = readq(pcard->sysinfo_regs_base + REG_FPGA_SSID);
 206        unsigned long timeout;
 207
 208        if (read_val & 0x8000000000000000UL) {
 209                pcard->ssid = read_val;
 210                return;
 211        }
 212
 213        timeout = jiffies + (HZ * 2);
 214        do {
 215                read_val = readq(pcard->sysinfo_regs_base + REG_FPGA_SSID);
 216                if (read_val & 0x8000000000000000UL) {
 217                        pcard->ssid = read_val;
 218                        return;
 219                }
 220                cpu_relax();
 221                //schedule();
 222        } while (time_before(jiffies, timeout));
 223
 224        dev_notice(&pcard->pdev->dev, "SSID didn't show up!\n");
 225
 226        // Timed out waiting for the SSID to show up, stick all zeros in the
 227        // value
 228        pcard->ssid = 0;
 229}
 230
 231static int  read_system_regs(struct kp2000_device *pcard)
 232{
 233        u64 read_val;
 234
 235        read_val = readq(pcard->sysinfo_regs_base + REG_MAGIC_NUMBER);
 236        if (read_val != KP2000_MAGIC_VALUE) {
 237                dev_err(&pcard->pdev->dev,
 238                        "Invalid magic!  Got: 0x%016llx  Want: 0x%016llx\n",
 239                        read_val, KP2000_MAGIC_VALUE);
 240                return -EILSEQ;
 241        }
 242
 243        read_val = readq(pcard->sysinfo_regs_base + REG_CARD_ID_AND_BUILD);
 244        pcard->card_id = (read_val & 0xFFFFFFFF00000000UL) >> 32;
 245        pcard->build_version = (read_val & 0x00000000FFFFFFFFUL) >> 0;
 246
 247        read_val = readq(pcard->sysinfo_regs_base + REG_DATE_AND_TIME_STAMPS);
 248        pcard->build_datestamp = (read_val & 0xFFFFFFFF00000000UL) >> 32;
 249        pcard->build_timestamp = (read_val & 0x00000000FFFFFFFFUL) >> 0;
 250
 251        read_val = readq(pcard->sysinfo_regs_base + REG_CORE_TABLE_OFFSET);
 252        pcard->core_table_length = (read_val & 0xFFFFFFFF00000000UL) >> 32;
 253        pcard->core_table_offset = (read_val & 0x00000000FFFFFFFFUL) >> 0;
 254
 255        wait_and_read_ssid(pcard);
 256
 257        read_val = readq(pcard->sysinfo_regs_base + REG_FPGA_HW_ID);
 258        pcard->core_table_rev    = (read_val & 0x0000000000000F00) >> 8;
 259        pcard->hardware_revision = (read_val & 0x000000000000001F);
 260
 261        read_val = readq(pcard->sysinfo_regs_base + REG_FPGA_DDNA);
 262        pcard->ddna = read_val;
 263
 264        dev_info(&pcard->pdev->dev,
 265                 "system_regs: %08x %08x %08x %08x  %02x  %d %d  %016llx  %016llx\n",
 266                 pcard->card_id,
 267                 pcard->build_version,
 268                 pcard->build_datestamp,
 269                 pcard->build_timestamp,
 270                 pcard->hardware_revision,
 271                 pcard->core_table_rev,
 272                 pcard->core_table_length,
 273                 pcard->ssid,
 274                 pcard->ddna);
 275
 276        if (pcard->core_table_rev > 1) {
 277                dev_err(&pcard->pdev->dev,
 278                        "core table entry revision is higher than we can deal with, cannot continue with this card!\n");
 279                return 1;
 280        }
 281
 282        return 0;
 283}
 284
 285static irqreturn_t kp2000_irq_handler(int irq, void *dev_id)
 286{
 287        struct kp2000_device *pcard = dev_id;
 288
 289        writel(KPC_DMA_CARD_IRQ_ENABLE |
 290               KPC_DMA_CARD_USER_INTERRUPT_MODE |
 291               KPC_DMA_CARD_USER_INTERRUPT_ACTIVE,
 292               pcard->dma_common_regs);
 293        return IRQ_HANDLED;
 294}
 295
 296static int kp2000_pcie_probe(struct pci_dev *pdev,
 297                             const struct pci_device_id *id)
 298{
 299        int err = 0;
 300        struct kp2000_device *pcard;
 301        unsigned long reg_bar_phys_addr;
 302        unsigned long reg_bar_phys_len;
 303        unsigned long dma_bar_phys_addr;
 304        unsigned long dma_bar_phys_len;
 305        u16 regval;
 306
 307        pcard = kzalloc(sizeof(*pcard), GFP_KERNEL);
 308        if (!pcard)
 309                return -ENOMEM;
 310        dev_dbg(&pdev->dev, "probe: allocated struct kp2000_device @ %p\n",
 311                pcard);
 312
 313        err = ida_simple_get(&card_num_ida, 1, INT_MAX, GFP_KERNEL);
 314        if (err < 0) {
 315                dev_err(&pdev->dev, "probe: failed to get card number (%d)\n",
 316                        err);
 317                goto err_free_pcard;
 318        }
 319        pcard->card_num = err;
 320        scnprintf(pcard->name, 16, "kpcard%u", pcard->card_num);
 321
 322        mutex_init(&pcard->sem);
 323        mutex_lock(&pcard->sem);
 324
 325        pcard->pdev = pdev;
 326        pci_set_drvdata(pdev, pcard);
 327
 328        err = pci_enable_device(pcard->pdev);
 329        if (err) {
 330                dev_err(&pcard->pdev->dev,
 331                        "probe: failed to enable PCIE2000 PCIe device (%d)\n",
 332                        err);
 333                goto err_remove_ida;
 334        }
 335
 336        /* Setup the Register BAR */
 337        reg_bar_phys_addr = pci_resource_start(pcard->pdev, REG_BAR);
 338        reg_bar_phys_len = pci_resource_len(pcard->pdev, REG_BAR);
 339
 340        pcard->regs_bar_base = ioremap(reg_bar_phys_addr, PAGE_SIZE);
 341        if (!pcard->regs_bar_base) {
 342                dev_err(&pcard->pdev->dev,
 343                        "probe: REG_BAR could not remap memory to virtual space\n");
 344                err = -ENODEV;
 345                goto err_disable_device;
 346        }
 347        dev_dbg(&pcard->pdev->dev,
 348                "probe: REG_BAR virt hardware address start [%p]\n",
 349                pcard->regs_bar_base);
 350
 351        err = pci_request_region(pcard->pdev, REG_BAR, KP_DRIVER_NAME_KP2000);
 352        if (err) {
 353                dev_err(&pcard->pdev->dev,
 354                        "probe: failed to acquire PCI region (%d)\n",
 355                        err);
 356                err = -ENODEV;
 357                goto err_unmap_regs;
 358        }
 359
 360        pcard->regs_base_resource.start = reg_bar_phys_addr;
 361        pcard->regs_base_resource.end   = reg_bar_phys_addr +
 362                                          reg_bar_phys_len - 1;
 363        pcard->regs_base_resource.flags = IORESOURCE_MEM;
 364
 365        /* Setup the DMA BAR */
 366        dma_bar_phys_addr = pci_resource_start(pcard->pdev, DMA_BAR);
 367        dma_bar_phys_len = pci_resource_len(pcard->pdev, DMA_BAR);
 368
 369        pcard->dma_bar_base = ioremap(dma_bar_phys_addr,
 370                                              dma_bar_phys_len);
 371        if (!pcard->dma_bar_base) {
 372                dev_err(&pcard->pdev->dev,
 373                        "probe: DMA_BAR could not remap memory to virtual space\n");
 374                err = -ENODEV;
 375                goto err_release_regs;
 376        }
 377        dev_dbg(&pcard->pdev->dev,
 378                "probe: DMA_BAR virt hardware address start [%p]\n",
 379                pcard->dma_bar_base);
 380
 381        pcard->dma_common_regs = pcard->dma_bar_base + KPC_DMA_COMMON_OFFSET;
 382
 383        err = pci_request_region(pcard->pdev, DMA_BAR, "kp2000_pcie");
 384        if (err) {
 385                dev_err(&pcard->pdev->dev,
 386                        "probe: failed to acquire PCI region (%d)\n", err);
 387                err = -ENODEV;
 388                goto err_unmap_dma;
 389        }
 390
 391        pcard->dma_base_resource.start = dma_bar_phys_addr;
 392        pcard->dma_base_resource.end   = dma_bar_phys_addr +
 393                                         dma_bar_phys_len - 1;
 394        pcard->dma_base_resource.flags = IORESOURCE_MEM;
 395
 396        /* Read System Regs */
 397        pcard->sysinfo_regs_base = pcard->regs_bar_base;
 398        err = read_system_regs(pcard);
 399        if (err)
 400                goto err_release_dma;
 401
 402        // Disable all "user" interrupts because they're not used yet.
 403        writeq(0xFFFFFFFFFFFFFFFFUL,
 404               pcard->sysinfo_regs_base + REG_INTERRUPT_MASK);
 405
 406        // let the card master PCIe
 407        pci_set_master(pcard->pdev);
 408
 409        // enable IO and mem if not already done
 410        pci_read_config_word(pcard->pdev, PCI_COMMAND, &regval);
 411        regval |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
 412        pci_write_config_word(pcard->pdev, PCI_COMMAND, regval);
 413
 414        // Clear relaxed ordering bit
 415        pcie_capability_clear_and_set_word(pcard->pdev, PCI_EXP_DEVCTL,
 416                                           PCI_EXP_DEVCTL_RELAX_EN, 0);
 417
 418        // Set Max_Payload_Size and Max_Read_Request_Size
 419        regval = (0x0) << 5; // Max_Payload_Size = 128 B
 420        pcie_capability_clear_and_set_word(pcard->pdev, PCI_EXP_DEVCTL,
 421                                           PCI_EXP_DEVCTL_PAYLOAD, regval);
 422        regval = (0x0) << 12; // Max_Read_Request_Size = 128 B
 423        pcie_capability_clear_and_set_word(pcard->pdev, PCI_EXP_DEVCTL,
 424                                           PCI_EXP_DEVCTL_READRQ, regval);
 425
 426        // Enable error reporting for: Correctable Errors, Non-Fatal Errors,
 427        // Fatal Errors, Unsupported Requests
 428        pcie_capability_clear_and_set_word(pcard->pdev, PCI_EXP_DEVCTL, 0,
 429                                           PCI_EXP_DEVCTL_CERE |
 430                                           PCI_EXP_DEVCTL_NFERE |
 431                                           PCI_EXP_DEVCTL_FERE |
 432                                           PCI_EXP_DEVCTL_URRE);
 433
 434        err = dma_set_mask(PCARD_TO_DEV(pcard), DMA_BIT_MASK(64));
 435        if (err) {
 436                dev_err(&pcard->pdev->dev,
 437                        "CANNOT use DMA mask %0llx\n", DMA_BIT_MASK(64));
 438                goto err_release_dma;
 439        }
 440        dev_dbg(&pcard->pdev->dev,
 441                "Using DMA mask %0llx\n", dma_get_mask(PCARD_TO_DEV(pcard)));
 442
 443        err = pci_enable_msi(pcard->pdev);
 444        if (err < 0)
 445                goto err_release_dma;
 446
 447        err = request_irq(pcard->pdev->irq, kp2000_irq_handler, IRQF_SHARED,
 448                          pcard->name, pcard);
 449        if (err) {
 450                dev_err(&pcard->pdev->dev,
 451                        "%s: failed to request_irq: %d\n", __func__, err);
 452                goto err_disable_msi;
 453        }
 454
 455        err = sysfs_create_files(&pdev->dev.kobj, kp_attr_list);
 456        if (err) {
 457                dev_err(&pdev->dev, "Failed to add sysfs files: %d\n", err);
 458                goto err_free_irq;
 459        }
 460
 461        err = kp2000_probe_cores(pcard);
 462        if (err)
 463                goto err_remove_sysfs;
 464
 465        /* Enable IRQs in HW */
 466        writel(KPC_DMA_CARD_IRQ_ENABLE | KPC_DMA_CARD_USER_INTERRUPT_MODE,
 467               pcard->dma_common_regs);
 468
 469        mutex_unlock(&pcard->sem);
 470        return 0;
 471
 472err_remove_sysfs:
 473        sysfs_remove_files(&pdev->dev.kobj, kp_attr_list);
 474err_free_irq:
 475        free_irq(pcard->pdev->irq, pcard);
 476err_disable_msi:
 477        pci_disable_msi(pcard->pdev);
 478err_release_dma:
 479        pci_release_region(pdev, DMA_BAR);
 480err_unmap_dma:
 481        iounmap(pcard->dma_bar_base);
 482err_release_regs:
 483        pci_release_region(pdev, REG_BAR);
 484err_unmap_regs:
 485        iounmap(pcard->regs_bar_base);
 486err_disable_device:
 487        pci_disable_device(pcard->pdev);
 488err_remove_ida:
 489        mutex_unlock(&pcard->sem);
 490        ida_simple_remove(&card_num_ida, pcard->card_num);
 491err_free_pcard:
 492        kfree(pcard);
 493        return err;
 494}
 495
 496static void kp2000_pcie_remove(struct pci_dev *pdev)
 497{
 498        struct kp2000_device *pcard = pci_get_drvdata(pdev);
 499
 500        if (!pcard)
 501                return;
 502
 503        mutex_lock(&pcard->sem);
 504        kp2000_remove_cores(pcard);
 505        mfd_remove_devices(PCARD_TO_DEV(pcard));
 506        sysfs_remove_files(&pdev->dev.kobj, kp_attr_list);
 507        free_irq(pcard->pdev->irq, pcard);
 508        pci_disable_msi(pcard->pdev);
 509        if (pcard->dma_bar_base) {
 510                iounmap(pcard->dma_bar_base);
 511                pci_release_region(pdev, DMA_BAR);
 512                pcard->dma_bar_base = NULL;
 513        }
 514        if (pcard->regs_bar_base) {
 515                iounmap(pcard->regs_bar_base);
 516                pci_release_region(pdev, REG_BAR);
 517                pcard->regs_bar_base = NULL;
 518        }
 519        pci_disable_device(pcard->pdev);
 520        pci_set_drvdata(pdev, NULL);
 521        mutex_unlock(&pcard->sem);
 522        ida_simple_remove(&card_num_ida, pcard->card_num);
 523        kfree(pcard);
 524}
 525
 526struct class *kpc_uio_class;
 527ATTRIBUTE_GROUPS(kpc_uio_class);
 528
 529static const struct pci_device_id kp2000_pci_device_ids[] = {
 530        { PCI_DEVICE(PCI_VENDOR_ID_DAKTRONICS, PCI_DEVICE_ID_DAKTRONICS) },
 531        { PCI_DEVICE(PCI_VENDOR_ID_DAKTRONICS, PCI_DEVICE_ID_DAKTRONICS_KADOKA_P2KR0) },
 532        { 0, }
 533};
 534MODULE_DEVICE_TABLE(pci, kp2000_pci_device_ids);
 535
 536static struct pci_driver kp2000_driver_inst = {
 537        .name =         "kp2000_pcie",
 538        .id_table =     kp2000_pci_device_ids,
 539        .probe =        kp2000_pcie_probe,
 540        .remove =       kp2000_pcie_remove,
 541};
 542
 543static int __init kp2000_pcie_init(void)
 544{
 545        kpc_uio_class = class_create(THIS_MODULE, "kpc_uio");
 546        if (IS_ERR(kpc_uio_class))
 547                return PTR_ERR(kpc_uio_class);
 548
 549        kpc_uio_class->dev_groups = kpc_uio_class_groups;
 550        return pci_register_driver(&kp2000_driver_inst);
 551}
 552module_init(kp2000_pcie_init);
 553
 554static void __exit kp2000_pcie_exit(void)
 555{
 556        pci_unregister_driver(&kp2000_driver_inst);
 557        class_destroy(kpc_uio_class);
 558        ida_destroy(&card_num_ida);
 559}
 560module_exit(kp2000_pcie_exit);
 561
 562MODULE_LICENSE("GPL");
 563MODULE_AUTHOR("Lee.Brooke@Daktronics.com, Matt.Sickler@Daktronics.com");
 564MODULE_SOFTDEP("pre: uio post: kpc_nwl_dma kpc_i2c kpc_spi");
 565