698 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * This is the driver for the MGB4 video grabber card by Digiteq Automotive.4 *5 * Copyright (C) 2021-2023 Digiteq Automotive6 * author: Martin Tuma <martin.tuma@digiteqautomotive.com>7 *8 * This is the main driver module. The DMA, I2C and SPI sub-drivers are9 * initialized here and the input/output v4l2 devices are created.10 *11 * The mgb4 card uses different expansion modules for different video sources12 * (GMSL and FPDL3 for now) so in probe() we detect the module type based on13 * what we see on the I2C bus and check if it matches the FPGA bitstream (there14 * are different bitstreams for different expansion modules). When no expansion15 * module is present, we still let the driver initialize to allow flashing of16 * the FPGA firmware using the SPI FLASH device. No v4l2 video devices are17 * created in this case.18 */19 20#include <linux/types.h>21#include <linux/module.h>22#include <linux/pci.h>23#include <linux/platform_device.h>24#include <linux/clk.h>25#include <linux/clk-provider.h>26#include <linux/clkdev.h>27#include <linux/i2c.h>28#include <linux/delay.h>29#include <linux/dma/amd_xdma.h>30#include <linux/platform_data/amd_xdma.h>31#include <linux/spi/xilinx_spi.h>32#include <linux/mtd/mtd.h>33#include <linux/hwmon.h>34#include <linux/debugfs.h>35#include "mgb4_dma.h"36#include "mgb4_i2c.h"37#include "mgb4_sysfs.h"38#include "mgb4_vout.h"39#include "mgb4_vin.h"40#include "mgb4_trigger.h"41#include "mgb4_core.h"42 43#define MGB4_USER_IRQS 1644 45#define DIGITEQ_VID 0x1ed846#define T100_DID 0x010147#define T200_DID 0x020148 49ATTRIBUTE_GROUPS(mgb4_pci);50 51static int flashid;52 53static struct xdma_chan_info h2c_chan_info = {54 .dir = DMA_MEM_TO_DEV,55};56 57static struct xdma_chan_info c2h_chan_info = {58 .dir = DMA_DEV_TO_MEM,59};60 61static struct xspi_platform_data spi_platform_data = {62 .num_chipselect = 1,63 .bits_per_word = 864};65 66static const struct i2c_board_info extender_info = {67 I2C_BOARD_INFO("extender", 0x21)68};69 70#if IS_REACHABLE(CONFIG_HWMON)71static umode_t temp_is_visible(const void *data, enum hwmon_sensor_types type,72 u32 attr, int channel)73{74 if (type == hwmon_temp &&75 (attr == hwmon_temp_input || attr == hwmon_temp_label))76 return 0444;77 else78 return 0;79}80 81static int temp_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,82 int channel, long *val)83{84 struct mgb4_dev *mgbdev = dev_get_drvdata(dev);85 u32 val10, raw;86 87 if (type != hwmon_temp || attr != hwmon_temp_input)88 return -EOPNOTSUPP;89 90 raw = mgb4_read_reg(&mgbdev->video, 0xD0);91 /* register value -> Celsius degrees formula given by Xilinx */92 val10 = ((((raw >> 20) & 0xFFF) * 503975) - 1118822400) / 409600;93 *val = val10 * 100;94 95 return 0;96}97 98static int temp_read_string(struct device *dev, enum hwmon_sensor_types type,99 u32 attr, int channel, const char **str)100{101 if (type != hwmon_temp || attr != hwmon_temp_label)102 return -EOPNOTSUPP;103 104 *str = "FPGA Temperature";105 106 return 0;107}108 109static const struct hwmon_ops temp_ops = {110 .is_visible = temp_is_visible,111 .read = temp_read,112 .read_string = temp_read_string113};114 115static const struct hwmon_channel_info *temp_channel_info[] = {116 HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_LABEL),117 NULL118};119 120static const struct hwmon_chip_info temp_chip_info = {121 .ops = &temp_ops,122 .info = temp_channel_info,123};124#endif125 126static int match_i2c_adap(struct device *dev, void *data)127{128 return i2c_verify_adapter(dev) ? 1 : 0;129}130 131static struct i2c_adapter *get_i2c_adap(struct platform_device *pdev)132{133 struct device *dev;134 135 mutex_lock(&pdev->dev.mutex);136 dev = device_find_child(&pdev->dev, NULL, match_i2c_adap);137 mutex_unlock(&pdev->dev.mutex);138 139 return dev ? to_i2c_adapter(dev) : NULL;140}141 142static int match_spi_adap(struct device *dev, void *data)143{144 return to_spi_device(dev) ? 1 : 0;145}146 147static struct spi_controller *get_spi_adap(struct platform_device *pdev)148{149 struct device *dev;150 151 mutex_lock(&pdev->dev.mutex);152 dev = device_find_child(&pdev->dev, NULL, match_spi_adap);153 mutex_unlock(&pdev->dev.mutex);154 155 return dev ? container_of(dev, struct spi_controller, dev) : NULL;156}157 158static int init_spi(struct mgb4_dev *mgbdev, u32 devid)159{160 struct resource spi_resources[] = {161 {162 .start = 0x400,163 .end = 0x47f,164 .flags = IORESOURCE_MEM,165 .name = "io-memory",166 },167 {168 .start = 14,169 .end = 14,170 .flags = IORESOURCE_IRQ,171 .name = "irq",172 },173 };174 struct spi_board_info spi_info = {175 .max_speed_hz = 10000000,176 .modalias = "m25p80",177 .chip_select = 0,178 .mode = SPI_MODE_3,179 };180 struct pci_dev *pdev = mgbdev->pdev;181 struct device *dev = &pdev->dev;182 struct spi_controller *ctlr;183 struct spi_device *spi_dev;184 u32 irq;185 int rv, id;186 resource_size_t mapbase = pci_resource_start(pdev, MGB4_MGB4_BAR_ID);187 188 request_module("platform:xilinx_spi");189 190 irq = xdma_get_user_irq(mgbdev->xdev, 14);191 xdma_enable_user_irq(mgbdev->xdev, irq);192 193 spi_resources[0].parent = &pdev->resource[MGB4_MGB4_BAR_ID];194 spi_resources[0].start += mapbase;195 spi_resources[0].end += mapbase;196 spi_resources[1].start = irq;197 spi_resources[1].end = irq;198 199 id = pci_dev_id(pdev);200 mgbdev->spi_pdev = platform_device_register_resndata(dev, "xilinx_spi",201 id, spi_resources,202 ARRAY_SIZE(spi_resources),203 &spi_platform_data,204 sizeof(spi_platform_data));205 if (IS_ERR(mgbdev->spi_pdev)) {206 dev_err(dev, "failed to register SPI device\n");207 return PTR_ERR(mgbdev->spi_pdev);208 }209 210 ctlr = get_spi_adap(mgbdev->spi_pdev);211 if (!ctlr) {212 dev_err(dev, "failed to get SPI adapter\n");213 rv = -EINVAL;214 goto err_pdev;215 }216 217 snprintf(mgbdev->fw_part_name, sizeof(mgbdev->fw_part_name),218 "mgb4-fw.%d", flashid);219 mgbdev->partitions[0].name = mgbdev->fw_part_name;220 if (devid == T200_DID) {221 mgbdev->partitions[0].size = 0x950000;222 mgbdev->partitions[0].offset = 0x1000000;223 } else {224 mgbdev->partitions[0].size = 0x400000;225 mgbdev->partitions[0].offset = 0x400000;226 }227 mgbdev->partitions[0].mask_flags = 0;228 229 snprintf(mgbdev->data_part_name, sizeof(mgbdev->data_part_name),230 "mgb4-data.%d", flashid);231 mgbdev->partitions[1].name = mgbdev->data_part_name;232 mgbdev->partitions[1].size = 0x10000;233 mgbdev->partitions[1].offset = 0xFF0000;234 mgbdev->partitions[1].mask_flags = MTD_CAP_NORFLASH;235 236 snprintf(mgbdev->flash_name, sizeof(mgbdev->flash_name),237 "mgb4-flash.%d", flashid);238 mgbdev->flash_data.name = mgbdev->flash_name;239 mgbdev->flash_data.parts = mgbdev->partitions;240 mgbdev->flash_data.nr_parts = ARRAY_SIZE(mgbdev->partitions);241 mgbdev->flash_data.type = "spi-nor";242 243 spi_info.platform_data = &mgbdev->flash_data;244 245 spi_dev = spi_new_device(ctlr, &spi_info);246 put_device(&ctlr->dev);247 if (!spi_dev) {248 dev_err(dev, "failed to create MTD device\n");249 rv = -EINVAL;250 goto err_pdev;251 }252 253 return 0;254 255err_pdev:256 platform_device_unregister(mgbdev->spi_pdev);257 258 return rv;259}260 261static void free_spi(struct mgb4_dev *mgbdev)262{263 platform_device_unregister(mgbdev->spi_pdev);264}265 266static int init_i2c(struct mgb4_dev *mgbdev)267{268 struct resource i2c_resources[] = {269 {270 .start = 0x200,271 .end = 0x3ff,272 .flags = IORESOURCE_MEM,273 .name = "io-memory",274 },275 {276 .start = 15,277 .end = 15,278 .flags = IORESOURCE_IRQ,279 .name = "irq",280 },281 };282 struct pci_dev *pdev = mgbdev->pdev;283 struct device *dev = &pdev->dev;284 char clk_name[16];285 u32 irq;286 int rv, id;287 resource_size_t mapbase = pci_resource_start(pdev, MGB4_MGB4_BAR_ID);288 289 request_module("platform:xiic-i2c");290 291 irq = xdma_get_user_irq(mgbdev->xdev, 15);292 xdma_enable_user_irq(mgbdev->xdev, irq);293 294 i2c_resources[0].parent = &pdev->resource[MGB4_MGB4_BAR_ID];295 i2c_resources[0].start += mapbase;296 i2c_resources[0].end += mapbase;297 i2c_resources[1].start = irq;298 i2c_resources[1].end = irq;299 300 id = pci_dev_id(pdev);301 302 /* create dummy clock required by the xiic-i2c adapter */303 snprintf(clk_name, sizeof(clk_name), "xiic-i2c.%d", id);304 mgbdev->i2c_clk = clk_hw_register_fixed_rate(NULL, clk_name, NULL,305 0, MGB4_HW_FREQ);306 if (IS_ERR(mgbdev->i2c_clk)) {307 dev_err(dev, "failed to register I2C clock\n");308 return PTR_ERR(mgbdev->i2c_clk);309 }310 mgbdev->i2c_cl = clkdev_hw_create(mgbdev->i2c_clk, NULL, "xiic-i2c.%d",311 id);312 if (!mgbdev->i2c_cl) {313 dev_err(dev, "failed to register I2C clockdev\n");314 rv = -ENOMEM;315 goto err_clk;316 }317 318 mgbdev->i2c_pdev = platform_device_register_resndata(dev, "xiic-i2c",319 id, i2c_resources,320 ARRAY_SIZE(i2c_resources),321 NULL, 0);322 if (IS_ERR(mgbdev->i2c_pdev)) {323 dev_err(dev, "failed to register I2C device\n");324 rv = PTR_ERR(mgbdev->i2c_pdev);325 goto err_clkdev;326 }327 328 mgbdev->i2c_adap = get_i2c_adap(mgbdev->i2c_pdev);329 if (!mgbdev->i2c_adap) {330 dev_err(dev, "failed to get I2C adapter\n");331 rv = -EINVAL;332 goto err_pdev;333 }334 335 mutex_init(&mgbdev->i2c_lock);336 337 return 0;338 339err_pdev:340 platform_device_unregister(mgbdev->i2c_pdev);341err_clkdev:342 clkdev_drop(mgbdev->i2c_cl);343err_clk:344 clk_hw_unregister(mgbdev->i2c_clk);345 346 return rv;347}348 349static void free_i2c(struct mgb4_dev *mgbdev)350{351 put_device(&mgbdev->i2c_adap->dev);352 platform_device_unregister(mgbdev->i2c_pdev);353 clkdev_drop(mgbdev->i2c_cl);354 clk_hw_unregister(mgbdev->i2c_clk);355}356 357static int get_serial_number(struct mgb4_dev *mgbdev)358{359 struct device *dev = &mgbdev->pdev->dev;360 struct mtd_info *mtd;361 size_t rs;362 int rv;363 364 mgbdev->serial_number = 0;365 366 mtd = get_mtd_device_nm(mgbdev->data_part_name);367 if (IS_ERR(mtd)) {368 dev_warn(dev, "failed to get data MTD device\n");369 return -ENOENT;370 }371 rv = mtd_read(mtd, 0, sizeof(mgbdev->serial_number), &rs,372 (u_char *)&mgbdev->serial_number);373 put_mtd_device(mtd);374 if (rv < 0 || rs != sizeof(mgbdev->serial_number)) {375 dev_warn(dev, "error reading MTD device\n");376 return -EIO;377 }378 379 return 0;380}381 382static int get_module_version(struct mgb4_dev *mgbdev)383{384 struct device *dev = &mgbdev->pdev->dev;385 struct mgb4_i2c_client extender;386 s32 version;387 u32 fw_version;388 int rv;389 390 rv = mgb4_i2c_init(&extender, mgbdev->i2c_adap, &extender_info, 8);391 if (rv < 0) {392 dev_err(dev, "failed to create extender I2C device\n");393 return rv;394 }395 version = mgb4_i2c_read_byte(&extender, 0x00);396 mgb4_i2c_free(&extender);397 if (version < 0) {398 dev_err(dev, "error reading module version\n");399 return -EIO;400 }401 402 mgbdev->module_version = ~((u32)version) & 0xff;403 if (!(MGB4_IS_FPDL3(mgbdev) || MGB4_IS_GMSL(mgbdev))) {404 dev_err(dev, "unknown module type\n");405 return -EINVAL;406 }407 fw_version = mgb4_read_reg(&mgbdev->video, 0xC4);408 if (fw_version >> 24 != mgbdev->module_version >> 4) {409 dev_err(dev, "module/firmware type mismatch\n");410 return -EINVAL;411 }412 413 dev_info(dev, "%s module detected\n",414 MGB4_IS_FPDL3(mgbdev) ? "FPDL3" : "GMSL");415 416 return 0;417}418 419static int map_regs(struct pci_dev *pdev, struct resource *res,420 struct mgb4_regs *regs)421{422 int rv;423 resource_size_t mapbase = pci_resource_start(pdev, MGB4_MGB4_BAR_ID);424 425 res->start += mapbase;426 res->end += mapbase;427 428 rv = mgb4_regs_map(res, regs);429 if (rv < 0) {430 dev_err(&pdev->dev, "failed to map %s registers\n", res->name);431 return rv;432 }433 434 return 0;435}436 437static int init_xdma(struct mgb4_dev *mgbdev)438{439 struct xdma_platdata data;440 struct resource res[2] = { 0 };441 struct dma_slave_map *map;442 struct pci_dev *pdev = mgbdev->pdev;443 struct device *dev = &pdev->dev;444 int i;445 446 res[0].start = pci_resource_start(pdev, MGB4_XDMA_BAR_ID);447 res[0].end = pci_resource_end(pdev, MGB4_XDMA_BAR_ID);448 res[0].flags = IORESOURCE_MEM;449 res[0].parent = &pdev->resource[MGB4_XDMA_BAR_ID];450 res[1].start = pci_irq_vector(pdev, 0);451 res[1].end = res[1].start + MGB4_VIN_DEVICES + MGB4_VOUT_DEVICES452 + MGB4_USER_IRQS - 1;453 res[1].flags = IORESOURCE_IRQ;454 455 data.max_dma_channels = MGB4_VIN_DEVICES + MGB4_VOUT_DEVICES;456 data.device_map = mgbdev->slave_map;457 data.device_map_cnt = MGB4_VIN_DEVICES + MGB4_VOUT_DEVICES;458 459 for (i = 0; i < MGB4_VIN_DEVICES; i++) {460 sprintf(mgbdev->channel_names[i], "c2h%d", i);461 map = &data.device_map[i];462 map->slave = mgbdev->channel_names[i];463 map->devname = dev_name(dev);464 map->param = XDMA_FILTER_PARAM(&c2h_chan_info);465 }466 for (i = 0; i < MGB4_VOUT_DEVICES; i++) {467 sprintf(mgbdev->channel_names[i + MGB4_VIN_DEVICES], "h2c%d", i);468 map = &data.device_map[i + MGB4_VIN_DEVICES];469 map->slave = mgbdev->channel_names[i + MGB4_VIN_DEVICES];470 map->devname = dev_name(dev);471 map->param = XDMA_FILTER_PARAM(&h2c_chan_info);472 }473 474 mgbdev->xdev = platform_device_register_resndata(dev, "xdma",475 PLATFORM_DEVID_AUTO, res,476 2, &data, sizeof(data));477 if (IS_ERR(mgbdev->xdev)) {478 dev_err(dev, "failed to register XDMA device\n");479 return PTR_ERR(mgbdev->xdev);480 }481 482 return 0;483}484 485static void free_xdma(struct mgb4_dev *mgbdev)486{487 platform_device_unregister(mgbdev->xdev);488}489 490static int mgb4_probe(struct pci_dev *pdev, const struct pci_device_id *id)491{492 int i, rv;493 struct mgb4_dev *mgbdev;494 struct resource video = {495 .start = 0x0,496 .end = 0xff,497 .flags = IORESOURCE_MEM,498 .name = "mgb4-video",499 };500 struct resource cmt = {501 .start = 0x1000,502 .end = 0x17ff,503 .flags = IORESOURCE_MEM,504 .name = "mgb4-cmt",505 };506 int irqs = pci_msix_vec_count(pdev);507 508 mgbdev = kzalloc(sizeof(*mgbdev), GFP_KERNEL);509 if (!mgbdev)510 return -ENOMEM;511 512 mgbdev->pdev = pdev;513 pci_set_drvdata(pdev, mgbdev);514 515 /* PCIe related stuff */516 rv = pci_enable_device(pdev);517 if (rv) {518 dev_err(&pdev->dev, "error enabling PCI device\n");519 goto err_mgbdev;520 }521 522 rv = pcie_capability_set_word(pdev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_RELAX_EN);523 if (rv)524 dev_warn(&pdev->dev, "error enabling PCIe relaxed ordering\n");525 rv = pcie_capability_set_word(pdev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_EXT_TAG);526 if (rv)527 dev_warn(&pdev->dev, "error enabling PCIe extended tag field\n");528 rv = pcie_set_readrq(pdev, 512);529 if (rv)530 dev_warn(&pdev->dev, "error setting PCIe max. memory read size\n");531 pci_set_master(pdev);532 533 rv = pci_alloc_irq_vectors(pdev, irqs, irqs, PCI_IRQ_MSIX);534 if (rv < 0) {535 dev_err(&pdev->dev, "error allocating MSI-X IRQs\n");536 goto err_enable_pci;537 }538 539 rv = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));540 if (rv) {541 dev_err(&pdev->dev, "error setting DMA mask\n");542 goto err_enable_pci;543 }544 545 /* DMA + IRQ engine */546 rv = init_xdma(mgbdev);547 if (rv)548 goto err_alloc_irq;549 rv = mgb4_dma_channel_init(mgbdev);550 if (rv)551 goto err_dma_chan;552 553 /* mgb4 video registers */554 rv = map_regs(pdev, &video, &mgbdev->video);555 if (rv < 0)556 goto err_dma_chan;557 /* mgb4 cmt registers */558 rv = map_regs(pdev, &cmt, &mgbdev->cmt);559 if (rv < 0)560 goto err_video_regs;561 562 /* SPI FLASH */563 rv = init_spi(mgbdev, id->device);564 if (rv < 0)565 goto err_cmt_regs;566 567 /* I2C controller */568 rv = init_i2c(mgbdev);569 if (rv < 0)570 goto err_spi;571 572 /* PCI card related sysfs attributes */573 rv = device_add_groups(&pdev->dev, mgb4_pci_groups);574 if (rv < 0)575 goto err_i2c;576 577#if IS_REACHABLE(CONFIG_HWMON)578 /* HWmon (card temperature) */579 mgbdev->hwmon_dev = hwmon_device_register_with_info(&pdev->dev, "mgb4",580 mgbdev,581 &temp_chip_info,582 NULL);583#endif584 585#ifdef CONFIG_DEBUG_FS586 mgbdev->debugfs = debugfs_create_dir(dev_name(&pdev->dev), NULL);587#endif588 589 /* Get card serial number. On systems without MTD flash support we may590 * get an error thus ignore the return value. An invalid serial number591 * should not break anything...592 */593 if (get_serial_number(mgbdev) < 0)594 dev_warn(&pdev->dev, "error reading card serial number\n");595 596 /* Get module type. If no valid module is found, skip the video device597 * creation part but do not exit with error to allow flashing the card.598 */599 rv = get_module_version(mgbdev);600 if (rv < 0)601 goto exit;602 603 /* Video input v4l2 devices */604 for (i = 0; i < MGB4_VIN_DEVICES; i++)605 mgbdev->vin[i] = mgb4_vin_create(mgbdev, i);606 607 /* Video output v4l2 devices */608 for (i = 0; i < MGB4_VOUT_DEVICES; i++)609 mgbdev->vout[i] = mgb4_vout_create(mgbdev, i);610 611 /* Triggers */612 mgbdev->indio_dev = mgb4_trigger_create(mgbdev);613 614exit:615 flashid++;616 617 return 0;618 619err_i2c:620 free_i2c(mgbdev);621err_spi:622 free_spi(mgbdev);623err_cmt_regs:624 mgb4_regs_free(&mgbdev->cmt);625err_video_regs:626 mgb4_regs_free(&mgbdev->video);627err_dma_chan:628 mgb4_dma_channel_free(mgbdev);629 free_xdma(mgbdev);630err_alloc_irq:631 pci_disable_msix(pdev);632err_enable_pci:633 pci_disable_device(pdev);634err_mgbdev:635 kfree(mgbdev);636 637 return rv;638}639 640static void mgb4_remove(struct pci_dev *pdev)641{642 struct mgb4_dev *mgbdev = pci_get_drvdata(pdev);643 int i;644 645#if IS_REACHABLE(CONFIG_HWMON)646 hwmon_device_unregister(mgbdev->hwmon_dev);647#endif648 649 if (mgbdev->indio_dev)650 mgb4_trigger_free(mgbdev->indio_dev);651 652 for (i = 0; i < MGB4_VOUT_DEVICES; i++)653 if (mgbdev->vout[i])654 mgb4_vout_free(mgbdev->vout[i]);655 for (i = 0; i < MGB4_VIN_DEVICES; i++)656 if (mgbdev->vin[i])657 mgb4_vin_free(mgbdev->vin[i]);658 659#ifdef CONFIG_DEBUG_FS660 debugfs_remove_recursive(mgbdev->debugfs);661#endif662 663 device_remove_groups(&mgbdev->pdev->dev, mgb4_pci_groups);664 free_spi(mgbdev);665 free_i2c(mgbdev);666 mgb4_regs_free(&mgbdev->video);667 mgb4_regs_free(&mgbdev->cmt);668 669 mgb4_dma_channel_free(mgbdev);670 free_xdma(mgbdev);671 672 pci_disable_msix(mgbdev->pdev);673 pci_disable_device(mgbdev->pdev);674 675 kfree(mgbdev);676}677 678static const struct pci_device_id mgb4_pci_ids[] = {679 { PCI_DEVICE(DIGITEQ_VID, T100_DID), },680 { PCI_DEVICE(DIGITEQ_VID, T200_DID), },681 { 0, }682};683MODULE_DEVICE_TABLE(pci, mgb4_pci_ids);684 685static struct pci_driver mgb4_pci_driver = {686 .name = KBUILD_MODNAME,687 .id_table = mgb4_pci_ids,688 .probe = mgb4_probe,689 .remove = mgb4_remove,690};691 692module_pci_driver(mgb4_pci_driver);693 694MODULE_AUTHOR("Digiteq Automotive s.r.o.");695MODULE_DESCRIPTION("Digiteq Automotive MGB4 Driver");696MODULE_LICENSE("GPL");697MODULE_SOFTDEP("pre: platform:xiic-i2c platform:xilinx_spi spi-nor");698