i2c-nvidia-gpu.c (9732B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Nvidia GPU I2C controller Driver 4 * 5 * Copyright (C) 2018 NVIDIA Corporation. All rights reserved. 6 * Author: Ajay Gupta <ajayg@nvidia.com> 7 */ 8#include <linux/delay.h> 9#include <linux/i2c.h> 10#include <linux/interrupt.h> 11#include <linux/iopoll.h> 12#include <linux/module.h> 13#include <linux/pci.h> 14#include <linux/platform_device.h> 15#include <linux/pm.h> 16#include <linux/pm_runtime.h> 17 18#include <asm/unaligned.h> 19 20#include "i2c-ccgx-ucsi.h" 21 22/* I2C definitions */ 23#define I2C_MST_CNTL 0x00 24#define I2C_MST_CNTL_GEN_START BIT(0) 25#define I2C_MST_CNTL_GEN_STOP BIT(1) 26#define I2C_MST_CNTL_CMD_READ (1 << 2) 27#define I2C_MST_CNTL_CMD_WRITE (2 << 2) 28#define I2C_MST_CNTL_BURST_SIZE_SHIFT 6 29#define I2C_MST_CNTL_GEN_NACK BIT(28) 30#define I2C_MST_CNTL_STATUS GENMASK(30, 29) 31#define I2C_MST_CNTL_STATUS_OKAY (0 << 29) 32#define I2C_MST_CNTL_STATUS_NO_ACK (1 << 29) 33#define I2C_MST_CNTL_STATUS_TIMEOUT (2 << 29) 34#define I2C_MST_CNTL_STATUS_BUS_BUSY (3 << 29) 35#define I2C_MST_CNTL_CYCLE_TRIGGER BIT(31) 36 37#define I2C_MST_ADDR 0x04 38 39#define I2C_MST_I2C0_TIMING 0x08 40#define I2C_MST_I2C0_TIMING_SCL_PERIOD_100KHZ 0x10e 41#define I2C_MST_I2C0_TIMING_TIMEOUT_CLK_CNT 16 42#define I2C_MST_I2C0_TIMING_TIMEOUT_CLK_CNT_MAX 255 43#define I2C_MST_I2C0_TIMING_TIMEOUT_CHECK BIT(24) 44 45#define I2C_MST_DATA 0x0c 46 47#define I2C_MST_HYBRID_PADCTL 0x20 48#define I2C_MST_HYBRID_PADCTL_MODE_I2C BIT(0) 49#define I2C_MST_HYBRID_PADCTL_I2C_SCL_INPUT_RCV BIT(14) 50#define I2C_MST_HYBRID_PADCTL_I2C_SDA_INPUT_RCV BIT(15) 51 52struct gpu_i2c_dev { 53 struct device *dev; 54 void __iomem *regs; 55 struct i2c_adapter adapter; 56 struct i2c_board_info *gpu_ccgx_ucsi; 57 struct i2c_client *ccgx_client; 58}; 59 60static void gpu_enable_i2c_bus(struct gpu_i2c_dev *i2cd) 61{ 62 u32 val; 63 64 /* enable I2C */ 65 val = readl(i2cd->regs + I2C_MST_HYBRID_PADCTL); 66 val |= I2C_MST_HYBRID_PADCTL_MODE_I2C | 67 I2C_MST_HYBRID_PADCTL_I2C_SCL_INPUT_RCV | 68 I2C_MST_HYBRID_PADCTL_I2C_SDA_INPUT_RCV; 69 writel(val, i2cd->regs + I2C_MST_HYBRID_PADCTL); 70 71 /* enable 100KHZ mode */ 72 val = I2C_MST_I2C0_TIMING_SCL_PERIOD_100KHZ; 73 val |= (I2C_MST_I2C0_TIMING_TIMEOUT_CLK_CNT_MAX 74 << I2C_MST_I2C0_TIMING_TIMEOUT_CLK_CNT); 75 val |= I2C_MST_I2C0_TIMING_TIMEOUT_CHECK; 76 writel(val, i2cd->regs + I2C_MST_I2C0_TIMING); 77} 78 79static int gpu_i2c_check_status(struct gpu_i2c_dev *i2cd) 80{ 81 u32 val; 82 int ret; 83 84 ret = readl_poll_timeout(i2cd->regs + I2C_MST_CNTL, val, 85 !(val & I2C_MST_CNTL_CYCLE_TRIGGER) || 86 (val & I2C_MST_CNTL_STATUS) != I2C_MST_CNTL_STATUS_BUS_BUSY, 87 500, 1000 * USEC_PER_MSEC); 88 89 if (ret) { 90 dev_err(i2cd->dev, "i2c timeout error %x\n", val); 91 return -ETIMEDOUT; 92 } 93 94 val = readl(i2cd->regs + I2C_MST_CNTL); 95 switch (val & I2C_MST_CNTL_STATUS) { 96 case I2C_MST_CNTL_STATUS_OKAY: 97 return 0; 98 case I2C_MST_CNTL_STATUS_NO_ACK: 99 return -ENXIO; 100 case I2C_MST_CNTL_STATUS_TIMEOUT: 101 return -ETIMEDOUT; 102 default: 103 return 0; 104 } 105} 106 107static int gpu_i2c_read(struct gpu_i2c_dev *i2cd, u8 *data, u16 len) 108{ 109 int status; 110 u32 val; 111 112 val = I2C_MST_CNTL_GEN_START | I2C_MST_CNTL_CMD_READ | 113 (len << I2C_MST_CNTL_BURST_SIZE_SHIFT) | 114 I2C_MST_CNTL_CYCLE_TRIGGER | I2C_MST_CNTL_GEN_NACK; 115 writel(val, i2cd->regs + I2C_MST_CNTL); 116 117 status = gpu_i2c_check_status(i2cd); 118 if (status < 0) 119 return status; 120 121 val = readl(i2cd->regs + I2C_MST_DATA); 122 switch (len) { 123 case 1: 124 data[0] = val; 125 break; 126 case 2: 127 put_unaligned_be16(val, data); 128 break; 129 case 3: 130 put_unaligned_be24(val, data); 131 break; 132 case 4: 133 put_unaligned_be32(val, data); 134 break; 135 default: 136 break; 137 } 138 return status; 139} 140 141static int gpu_i2c_start(struct gpu_i2c_dev *i2cd) 142{ 143 writel(I2C_MST_CNTL_GEN_START, i2cd->regs + I2C_MST_CNTL); 144 return gpu_i2c_check_status(i2cd); 145} 146 147static int gpu_i2c_stop(struct gpu_i2c_dev *i2cd) 148{ 149 writel(I2C_MST_CNTL_GEN_STOP, i2cd->regs + I2C_MST_CNTL); 150 return gpu_i2c_check_status(i2cd); 151} 152 153static int gpu_i2c_write(struct gpu_i2c_dev *i2cd, u8 data) 154{ 155 u32 val; 156 157 writel(data, i2cd->regs + I2C_MST_DATA); 158 159 val = I2C_MST_CNTL_CMD_WRITE | (1 << I2C_MST_CNTL_BURST_SIZE_SHIFT); 160 writel(val, i2cd->regs + I2C_MST_CNTL); 161 162 return gpu_i2c_check_status(i2cd); 163} 164 165static int gpu_i2c_master_xfer(struct i2c_adapter *adap, 166 struct i2c_msg *msgs, int num) 167{ 168 struct gpu_i2c_dev *i2cd = i2c_get_adapdata(adap); 169 int status, status2; 170 bool send_stop = true; 171 int i, j; 172 173 /* 174 * The controller supports maximum 4 byte read due to known 175 * limitation of sending STOP after every read. 176 */ 177 pm_runtime_get_sync(i2cd->dev); 178 for (i = 0; i < num; i++) { 179 if (msgs[i].flags & I2C_M_RD) { 180 /* program client address before starting read */ 181 writel(msgs[i].addr, i2cd->regs + I2C_MST_ADDR); 182 /* gpu_i2c_read has implicit start */ 183 status = gpu_i2c_read(i2cd, msgs[i].buf, msgs[i].len); 184 if (status < 0) 185 goto exit; 186 } else { 187 u8 addr = i2c_8bit_addr_from_msg(msgs + i); 188 189 status = gpu_i2c_start(i2cd); 190 if (status < 0) { 191 if (i == 0) 192 send_stop = false; 193 goto exit; 194 } 195 196 status = gpu_i2c_write(i2cd, addr); 197 if (status < 0) 198 goto exit; 199 200 for (j = 0; j < msgs[i].len; j++) { 201 status = gpu_i2c_write(i2cd, msgs[i].buf[j]); 202 if (status < 0) 203 goto exit; 204 } 205 } 206 } 207 send_stop = false; 208 status = gpu_i2c_stop(i2cd); 209 if (status < 0) 210 goto exit; 211 212 status = i; 213exit: 214 if (send_stop) { 215 status2 = gpu_i2c_stop(i2cd); 216 if (status2 < 0) 217 dev_err(i2cd->dev, "i2c stop failed %d\n", status2); 218 } 219 pm_runtime_mark_last_busy(i2cd->dev); 220 pm_runtime_put_autosuspend(i2cd->dev); 221 return status; 222} 223 224static const struct i2c_adapter_quirks gpu_i2c_quirks = { 225 .max_read_len = 4, 226 .max_comb_2nd_msg_len = 4, 227 .flags = I2C_AQ_COMB_WRITE_THEN_READ, 228}; 229 230static u32 gpu_i2c_functionality(struct i2c_adapter *adap) 231{ 232 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 233} 234 235static const struct i2c_algorithm gpu_i2c_algorithm = { 236 .master_xfer = gpu_i2c_master_xfer, 237 .functionality = gpu_i2c_functionality, 238}; 239 240/* 241 * This driver is for Nvidia GPU cards with USB Type-C interface. 242 * We want to identify the cards using vendor ID and class code only 243 * to avoid dependency of adding product id for any new card which 244 * requires this driver. 245 * Currently there is no class code defined for UCSI device over PCI 246 * so using UNKNOWN class for now and it will be updated when UCSI 247 * over PCI gets a class code. 248 * There is no other NVIDIA cards with UNKNOWN class code. Even if the 249 * driver gets loaded for an undesired card then eventually i2c_read() 250 * (initiated from UCSI i2c_client) will timeout or UCSI commands will 251 * timeout. 252 */ 253#define PCI_CLASS_SERIAL_UNKNOWN 0x0c80 254static const struct pci_device_id gpu_i2c_ids[] = { 255 { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 256 PCI_CLASS_SERIAL_UNKNOWN << 8, 0xffffff00}, 257 { } 258}; 259MODULE_DEVICE_TABLE(pci, gpu_i2c_ids); 260 261static const struct property_entry ccgx_props[] = { 262 /* Use FW built for NVIDIA (nv) only */ 263 PROPERTY_ENTRY_U16("ccgx,firmware-build", ('n' << 8) | 'v'), 264 { } 265}; 266 267static const struct software_node ccgx_node = { 268 .properties = ccgx_props, 269}; 270 271static int gpu_i2c_probe(struct pci_dev *pdev, const struct pci_device_id *id) 272{ 273 struct device *dev = &pdev->dev; 274 struct gpu_i2c_dev *i2cd; 275 int status; 276 277 i2cd = devm_kzalloc(dev, sizeof(*i2cd), GFP_KERNEL); 278 if (!i2cd) 279 return -ENOMEM; 280 281 i2cd->dev = dev; 282 dev_set_drvdata(dev, i2cd); 283 284 status = pcim_enable_device(pdev); 285 if (status < 0) 286 return dev_err_probe(dev, status, "pcim_enable_device failed\n"); 287 288 pci_set_master(pdev); 289 290 i2cd->regs = pcim_iomap(pdev, 0, 0); 291 if (!i2cd->regs) 292 return dev_err_probe(dev, -ENOMEM, "pcim_iomap failed\n"); 293 294 status = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI); 295 if (status < 0) 296 return dev_err_probe(dev, status, "pci_alloc_irq_vectors err\n"); 297 298 gpu_enable_i2c_bus(i2cd); 299 300 i2c_set_adapdata(&i2cd->adapter, i2cd); 301 i2cd->adapter.owner = THIS_MODULE; 302 strlcpy(i2cd->adapter.name, "NVIDIA GPU I2C adapter", 303 sizeof(i2cd->adapter.name)); 304 i2cd->adapter.algo = &gpu_i2c_algorithm; 305 i2cd->adapter.quirks = &gpu_i2c_quirks; 306 i2cd->adapter.dev.parent = dev; 307 status = i2c_add_adapter(&i2cd->adapter); 308 if (status < 0) 309 goto free_irq_vectors; 310 311 i2cd->ccgx_client = i2c_new_ccgx_ucsi(&i2cd->adapter, pdev->irq, &ccgx_node); 312 if (IS_ERR(i2cd->ccgx_client)) { 313 status = dev_err_probe(dev, PTR_ERR(i2cd->ccgx_client), "register UCSI failed\n"); 314 goto del_adapter; 315 } 316 317 pm_runtime_set_autosuspend_delay(dev, 3000); 318 pm_runtime_use_autosuspend(dev); 319 pm_runtime_put_autosuspend(dev); 320 pm_runtime_allow(dev); 321 322 return 0; 323 324del_adapter: 325 i2c_del_adapter(&i2cd->adapter); 326free_irq_vectors: 327 pci_free_irq_vectors(pdev); 328 return status; 329} 330 331static void gpu_i2c_remove(struct pci_dev *pdev) 332{ 333 struct gpu_i2c_dev *i2cd = pci_get_drvdata(pdev); 334 335 pm_runtime_get_noresume(i2cd->dev); 336 i2c_del_adapter(&i2cd->adapter); 337 pci_free_irq_vectors(pdev); 338} 339 340#define gpu_i2c_suspend NULL 341 342static __maybe_unused int gpu_i2c_resume(struct device *dev) 343{ 344 struct gpu_i2c_dev *i2cd = dev_get_drvdata(dev); 345 346 gpu_enable_i2c_bus(i2cd); 347 /* 348 * Runtime resume ccgx client so that it can see for any 349 * connector change event. Old ccg firmware has known 350 * issue of not triggering interrupt when a device is 351 * connected to runtime resume the controller. 352 */ 353 pm_request_resume(&i2cd->ccgx_client->dev); 354 return 0; 355} 356 357static UNIVERSAL_DEV_PM_OPS(gpu_i2c_driver_pm, gpu_i2c_suspend, gpu_i2c_resume, 358 NULL); 359 360static struct pci_driver gpu_i2c_driver = { 361 .name = "nvidia-gpu", 362 .id_table = gpu_i2c_ids, 363 .probe = gpu_i2c_probe, 364 .remove = gpu_i2c_remove, 365 .driver = { 366 .pm = &gpu_i2c_driver_pm, 367 }, 368}; 369 370module_pci_driver(gpu_i2c_driver); 371 372MODULE_AUTHOR("Ajay Gupta <ajayg@nvidia.com>"); 373MODULE_DESCRIPTION("Nvidia GPU I2C controller Driver"); 374MODULE_LICENSE("GPL v2");