Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Nvidia GPU I2C controller Driver
0004  *
0005  * Copyright (C) 2018 NVIDIA Corporation. All rights reserved.
0006  * Author: Ajay Gupta <ajayg@nvidia.com>
0007  */
0008 #include <linux/delay.h>
0009 #include <linux/i2c.h>
0010 #include <linux/interrupt.h>
0011 #include <linux/iopoll.h>
0012 #include <linux/module.h>
0013 #include <linux/pci.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/pm.h>
0016 #include <linux/pm_runtime.h>
0017 
0018 #include <asm/unaligned.h>
0019 
0020 #include "i2c-ccgx-ucsi.h"
0021 
0022 /* I2C definitions */
0023 #define I2C_MST_CNTL                0x00
0024 #define I2C_MST_CNTL_GEN_START          BIT(0)
0025 #define I2C_MST_CNTL_GEN_STOP           BIT(1)
0026 #define I2C_MST_CNTL_CMD_READ           (1 << 2)
0027 #define I2C_MST_CNTL_CMD_WRITE          (2 << 2)
0028 #define I2C_MST_CNTL_BURST_SIZE_SHIFT       6
0029 #define I2C_MST_CNTL_GEN_NACK           BIT(28)
0030 #define I2C_MST_CNTL_STATUS         GENMASK(30, 29)
0031 #define I2C_MST_CNTL_STATUS_OKAY        (0 << 29)
0032 #define I2C_MST_CNTL_STATUS_NO_ACK      (1 << 29)
0033 #define I2C_MST_CNTL_STATUS_TIMEOUT     (2 << 29)
0034 #define I2C_MST_CNTL_STATUS_BUS_BUSY        (3 << 29)
0035 #define I2C_MST_CNTL_CYCLE_TRIGGER      BIT(31)
0036 
0037 #define I2C_MST_ADDR                0x04
0038 
0039 #define I2C_MST_I2C0_TIMING             0x08
0040 #define I2C_MST_I2C0_TIMING_SCL_PERIOD_100KHZ       0x10e
0041 #define I2C_MST_I2C0_TIMING_TIMEOUT_CLK_CNT     16
0042 #define I2C_MST_I2C0_TIMING_TIMEOUT_CLK_CNT_MAX     255
0043 #define I2C_MST_I2C0_TIMING_TIMEOUT_CHECK       BIT(24)
0044 
0045 #define I2C_MST_DATA                    0x0c
0046 
0047 #define I2C_MST_HYBRID_PADCTL               0x20
0048 #define I2C_MST_HYBRID_PADCTL_MODE_I2C          BIT(0)
0049 #define I2C_MST_HYBRID_PADCTL_I2C_SCL_INPUT_RCV     BIT(14)
0050 #define I2C_MST_HYBRID_PADCTL_I2C_SDA_INPUT_RCV     BIT(15)
0051 
0052 struct gpu_i2c_dev {
0053     struct device *dev;
0054     void __iomem *regs;
0055     struct i2c_adapter adapter;
0056     struct i2c_board_info *gpu_ccgx_ucsi;
0057     struct i2c_client *ccgx_client;
0058 };
0059 
0060 static void gpu_enable_i2c_bus(struct gpu_i2c_dev *i2cd)
0061 {
0062     u32 val;
0063 
0064     /* enable I2C */
0065     val = readl(i2cd->regs + I2C_MST_HYBRID_PADCTL);
0066     val |= I2C_MST_HYBRID_PADCTL_MODE_I2C |
0067         I2C_MST_HYBRID_PADCTL_I2C_SCL_INPUT_RCV |
0068         I2C_MST_HYBRID_PADCTL_I2C_SDA_INPUT_RCV;
0069     writel(val, i2cd->regs + I2C_MST_HYBRID_PADCTL);
0070 
0071     /* enable 100KHZ mode */
0072     val = I2C_MST_I2C0_TIMING_SCL_PERIOD_100KHZ;
0073     val |= (I2C_MST_I2C0_TIMING_TIMEOUT_CLK_CNT_MAX
0074         << I2C_MST_I2C0_TIMING_TIMEOUT_CLK_CNT);
0075     val |= I2C_MST_I2C0_TIMING_TIMEOUT_CHECK;
0076     writel(val, i2cd->regs + I2C_MST_I2C0_TIMING);
0077 }
0078 
0079 static int gpu_i2c_check_status(struct gpu_i2c_dev *i2cd)
0080 {
0081     u32 val;
0082     int ret;
0083 
0084     ret = readl_poll_timeout(i2cd->regs + I2C_MST_CNTL, val,
0085                  !(val & I2C_MST_CNTL_CYCLE_TRIGGER) ||
0086                  (val & I2C_MST_CNTL_STATUS) != I2C_MST_CNTL_STATUS_BUS_BUSY,
0087                  500, 1000 * USEC_PER_MSEC);
0088 
0089     if (ret) {
0090         dev_err(i2cd->dev, "i2c timeout error %x\n", val);
0091         return -ETIMEDOUT;
0092     }
0093 
0094     val = readl(i2cd->regs + I2C_MST_CNTL);
0095     switch (val & I2C_MST_CNTL_STATUS) {
0096     case I2C_MST_CNTL_STATUS_OKAY:
0097         return 0;
0098     case I2C_MST_CNTL_STATUS_NO_ACK:
0099         return -ENXIO;
0100     case I2C_MST_CNTL_STATUS_TIMEOUT:
0101         return -ETIMEDOUT;
0102     default:
0103         return 0;
0104     }
0105 }
0106 
0107 static int gpu_i2c_read(struct gpu_i2c_dev *i2cd, u8 *data, u16 len)
0108 {
0109     int status;
0110     u32 val;
0111 
0112     val = I2C_MST_CNTL_GEN_START | I2C_MST_CNTL_CMD_READ |
0113         (len << I2C_MST_CNTL_BURST_SIZE_SHIFT) |
0114         I2C_MST_CNTL_CYCLE_TRIGGER | I2C_MST_CNTL_GEN_NACK;
0115     writel(val, i2cd->regs + I2C_MST_CNTL);
0116 
0117     status = gpu_i2c_check_status(i2cd);
0118     if (status < 0)
0119         return status;
0120 
0121     val = readl(i2cd->regs + I2C_MST_DATA);
0122     switch (len) {
0123     case 1:
0124         data[0] = val;
0125         break;
0126     case 2:
0127         put_unaligned_be16(val, data);
0128         break;
0129     case 3:
0130         put_unaligned_be24(val, data);
0131         break;
0132     case 4:
0133         put_unaligned_be32(val, data);
0134         break;
0135     default:
0136         break;
0137     }
0138     return status;
0139 }
0140 
0141 static int gpu_i2c_start(struct gpu_i2c_dev *i2cd)
0142 {
0143     writel(I2C_MST_CNTL_GEN_START, i2cd->regs + I2C_MST_CNTL);
0144     return gpu_i2c_check_status(i2cd);
0145 }
0146 
0147 static int gpu_i2c_stop(struct gpu_i2c_dev *i2cd)
0148 {
0149     writel(I2C_MST_CNTL_GEN_STOP, i2cd->regs + I2C_MST_CNTL);
0150     return gpu_i2c_check_status(i2cd);
0151 }
0152 
0153 static int gpu_i2c_write(struct gpu_i2c_dev *i2cd, u8 data)
0154 {
0155     u32 val;
0156 
0157     writel(data, i2cd->regs + I2C_MST_DATA);
0158 
0159     val = I2C_MST_CNTL_CMD_WRITE | (1 << I2C_MST_CNTL_BURST_SIZE_SHIFT);
0160     writel(val, i2cd->regs + I2C_MST_CNTL);
0161 
0162     return gpu_i2c_check_status(i2cd);
0163 }
0164 
0165 static int gpu_i2c_master_xfer(struct i2c_adapter *adap,
0166                    struct i2c_msg *msgs, int num)
0167 {
0168     struct gpu_i2c_dev *i2cd = i2c_get_adapdata(adap);
0169     int status, status2;
0170     bool send_stop = true;
0171     int i, j;
0172 
0173     /*
0174      * The controller supports maximum 4 byte read due to known
0175      * limitation of sending STOP after every read.
0176      */
0177     pm_runtime_get_sync(i2cd->dev);
0178     for (i = 0; i < num; i++) {
0179         if (msgs[i].flags & I2C_M_RD) {
0180             /* program client address before starting read */
0181             writel(msgs[i].addr, i2cd->regs + I2C_MST_ADDR);
0182             /* gpu_i2c_read has implicit start */
0183             status = gpu_i2c_read(i2cd, msgs[i].buf, msgs[i].len);
0184             if (status < 0)
0185                 goto exit;
0186         } else {
0187             u8 addr = i2c_8bit_addr_from_msg(msgs + i);
0188 
0189             status = gpu_i2c_start(i2cd);
0190             if (status < 0) {
0191                 if (i == 0)
0192                     send_stop = false;
0193                 goto exit;
0194             }
0195 
0196             status = gpu_i2c_write(i2cd, addr);
0197             if (status < 0)
0198                 goto exit;
0199 
0200             for (j = 0; j < msgs[i].len; j++) {
0201                 status = gpu_i2c_write(i2cd, msgs[i].buf[j]);
0202                 if (status < 0)
0203                     goto exit;
0204             }
0205         }
0206     }
0207     send_stop = false;
0208     status = gpu_i2c_stop(i2cd);
0209     if (status < 0)
0210         goto exit;
0211 
0212     status = i;
0213 exit:
0214     if (send_stop) {
0215         status2 = gpu_i2c_stop(i2cd);
0216         if (status2 < 0)
0217             dev_err(i2cd->dev, "i2c stop failed %d\n", status2);
0218     }
0219     pm_runtime_mark_last_busy(i2cd->dev);
0220     pm_runtime_put_autosuspend(i2cd->dev);
0221     return status;
0222 }
0223 
0224 static const struct i2c_adapter_quirks gpu_i2c_quirks = {
0225     .max_read_len = 4,
0226     .max_comb_2nd_msg_len = 4,
0227     .flags = I2C_AQ_COMB_WRITE_THEN_READ,
0228 };
0229 
0230 static u32 gpu_i2c_functionality(struct i2c_adapter *adap)
0231 {
0232     return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
0233 }
0234 
0235 static const struct i2c_algorithm gpu_i2c_algorithm = {
0236     .master_xfer    = gpu_i2c_master_xfer,
0237     .functionality  = gpu_i2c_functionality,
0238 };
0239 
0240 /*
0241  * This driver is for Nvidia GPU cards with USB Type-C interface.
0242  * We want to identify the cards using vendor ID and class code only
0243  * to avoid dependency of adding product id for any new card which
0244  * requires this driver.
0245  * Currently there is no class code defined for UCSI device over PCI
0246  * so using UNKNOWN class for now and it will be updated when UCSI
0247  * over PCI gets a class code.
0248  * There is no other NVIDIA cards with UNKNOWN class code. Even if the
0249  * driver gets loaded for an undesired card then eventually i2c_read()
0250  * (initiated from UCSI i2c_client) will timeout or UCSI commands will
0251  * timeout.
0252  */
0253 #define PCI_CLASS_SERIAL_UNKNOWN    0x0c80
0254 static const struct pci_device_id gpu_i2c_ids[] = {
0255     { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
0256         PCI_CLASS_SERIAL_UNKNOWN << 8, 0xffffff00},
0257     { }
0258 };
0259 MODULE_DEVICE_TABLE(pci, gpu_i2c_ids);
0260 
0261 static const struct property_entry ccgx_props[] = {
0262     /* Use FW built for NVIDIA (nv) only */
0263     PROPERTY_ENTRY_U16("ccgx,firmware-build", ('n' << 8) | 'v'),
0264     { }
0265 };
0266 
0267 static const struct software_node ccgx_node = {
0268     .properties = ccgx_props,
0269 };
0270 
0271 static int gpu_i2c_probe(struct pci_dev *pdev, const struct pci_device_id *id)
0272 {
0273     struct device *dev = &pdev->dev;
0274     struct gpu_i2c_dev *i2cd;
0275     int status;
0276 
0277     i2cd = devm_kzalloc(dev, sizeof(*i2cd), GFP_KERNEL);
0278     if (!i2cd)
0279         return -ENOMEM;
0280 
0281     i2cd->dev = dev;
0282     dev_set_drvdata(dev, i2cd);
0283 
0284     status = pcim_enable_device(pdev);
0285     if (status < 0)
0286         return dev_err_probe(dev, status, "pcim_enable_device failed\n");
0287 
0288     pci_set_master(pdev);
0289 
0290     i2cd->regs = pcim_iomap(pdev, 0, 0);
0291     if (!i2cd->regs)
0292         return dev_err_probe(dev, -ENOMEM, "pcim_iomap failed\n");
0293 
0294     status = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);
0295     if (status < 0)
0296         return dev_err_probe(dev, status, "pci_alloc_irq_vectors err\n");
0297 
0298     gpu_enable_i2c_bus(i2cd);
0299 
0300     i2c_set_adapdata(&i2cd->adapter, i2cd);
0301     i2cd->adapter.owner = THIS_MODULE;
0302     strscpy(i2cd->adapter.name, "NVIDIA GPU I2C adapter",
0303         sizeof(i2cd->adapter.name));
0304     i2cd->adapter.algo = &gpu_i2c_algorithm;
0305     i2cd->adapter.quirks = &gpu_i2c_quirks;
0306     i2cd->adapter.dev.parent = dev;
0307     status = i2c_add_adapter(&i2cd->adapter);
0308     if (status < 0)
0309         goto free_irq_vectors;
0310 
0311     i2cd->ccgx_client = i2c_new_ccgx_ucsi(&i2cd->adapter, pdev->irq, &ccgx_node);
0312     if (IS_ERR(i2cd->ccgx_client)) {
0313         status = dev_err_probe(dev, PTR_ERR(i2cd->ccgx_client), "register UCSI failed\n");
0314         goto del_adapter;
0315     }
0316 
0317     pm_runtime_set_autosuspend_delay(dev, 3000);
0318     pm_runtime_use_autosuspend(dev);
0319     pm_runtime_put_autosuspend(dev);
0320     pm_runtime_allow(dev);
0321 
0322     return 0;
0323 
0324 del_adapter:
0325     i2c_del_adapter(&i2cd->adapter);
0326 free_irq_vectors:
0327     pci_free_irq_vectors(pdev);
0328     return status;
0329 }
0330 
0331 static void gpu_i2c_remove(struct pci_dev *pdev)
0332 {
0333     struct gpu_i2c_dev *i2cd = pci_get_drvdata(pdev);
0334 
0335     pm_runtime_get_noresume(i2cd->dev);
0336     i2c_del_adapter(&i2cd->adapter);
0337     pci_free_irq_vectors(pdev);
0338 }
0339 
0340 #define gpu_i2c_suspend NULL
0341 
0342 static __maybe_unused int gpu_i2c_resume(struct device *dev)
0343 {
0344     struct gpu_i2c_dev *i2cd = dev_get_drvdata(dev);
0345 
0346     gpu_enable_i2c_bus(i2cd);
0347     /*
0348      * Runtime resume ccgx client so that it can see for any
0349      * connector change event. Old ccg firmware has known
0350      * issue of not triggering interrupt when a device is
0351      * connected to runtime resume the controller.
0352      */
0353     pm_request_resume(&i2cd->ccgx_client->dev);
0354     return 0;
0355 }
0356 
0357 static UNIVERSAL_DEV_PM_OPS(gpu_i2c_driver_pm, gpu_i2c_suspend, gpu_i2c_resume,
0358                 NULL);
0359 
0360 static struct pci_driver gpu_i2c_driver = {
0361     .name       = "nvidia-gpu",
0362     .id_table   = gpu_i2c_ids,
0363     .probe      = gpu_i2c_probe,
0364     .remove     = gpu_i2c_remove,
0365     .driver     = {
0366         .pm = &gpu_i2c_driver_pm,
0367     },
0368 };
0369 
0370 module_pci_driver(gpu_i2c_driver);
0371 
0372 MODULE_AUTHOR("Ajay Gupta <ajayg@nvidia.com>");
0373 MODULE_DESCRIPTION("Nvidia GPU I2C controller Driver");
0374 MODULE_LICENSE("GPL v2");