1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Synopsys DesignWare I2C adapter driver (master only). |
4 | * |
5 | * Based on the TI DAVINCI I2C adapter driver. |
6 | * |
7 | * Copyright (C) 2006 Texas Instruments. |
8 | * Copyright (C) 2007 MontaVista Software Inc. |
9 | * Copyright (C) 2009 Provigent Ltd. |
10 | * Copyright (C) 2011, 2015, 2016 Intel Corporation. |
11 | */ |
12 | #include <linux/acpi.h> |
13 | #include <linux/delay.h> |
14 | #include <linux/err.h> |
15 | #include <linux/errno.h> |
16 | #include <linux/i2c.h> |
17 | #include <linux/interrupt.h> |
18 | #include <linux/io.h> |
19 | #include <linux/kernel.h> |
20 | #include <linux/module.h> |
21 | #include <linux/pci.h> |
22 | #include <linux/pm_runtime.h> |
23 | #include <linux/power_supply.h> |
24 | #include <linux/sched.h> |
25 | #include <linux/slab.h> |
26 | |
27 | #include "i2c-designware-core.h" |
28 | #include "i2c-ccgx-ucsi.h" |
29 | |
30 | #define DRIVER_NAME "i2c-designware-pci" |
31 | |
32 | enum dw_pci_ctl_id_t { |
33 | medfield, |
34 | merrifield, |
35 | baytrail, |
36 | cherrytrail, |
37 | haswell, |
38 | elkhartlake, |
39 | navi_amd, |
40 | }; |
41 | |
42 | /* |
43 | * This is a legacy structure to describe the hardware counters |
44 | * to configure signal timings on the bus. For Device Tree platforms |
45 | * one should use the respective properties and for ACPI there is |
46 | * a set of ACPI methods that provide these counters. No new |
47 | * platform should use this structure. |
48 | */ |
49 | struct dw_scl_sda_cfg { |
50 | u16 ss_hcnt; |
51 | u16 fs_hcnt; |
52 | u16 ss_lcnt; |
53 | u16 fs_lcnt; |
54 | u32 sda_hold; |
55 | }; |
56 | |
57 | struct dw_pci_controller { |
58 | u32 bus_num; |
59 | u32 flags; |
60 | struct dw_scl_sda_cfg *scl_sda_cfg; |
61 | int (*setup)(struct pci_dev *pdev, struct dw_pci_controller *c); |
62 | u32 (*get_clk_rate_khz)(struct dw_i2c_dev *dev); |
63 | }; |
64 | |
65 | /* Merrifield HCNT/LCNT/SDA hold time */ |
66 | static struct dw_scl_sda_cfg mrfld_config = { |
67 | .ss_hcnt = 0x2f8, |
68 | .fs_hcnt = 0x87, |
69 | .ss_lcnt = 0x37b, |
70 | .fs_lcnt = 0x10a, |
71 | }; |
72 | |
73 | /* BayTrail HCNT/LCNT/SDA hold time */ |
74 | static struct dw_scl_sda_cfg byt_config = { |
75 | .ss_hcnt = 0x200, |
76 | .fs_hcnt = 0x55, |
77 | .ss_lcnt = 0x200, |
78 | .fs_lcnt = 0x99, |
79 | .sda_hold = 0x6, |
80 | }; |
81 | |
82 | /* Haswell HCNT/LCNT/SDA hold time */ |
83 | static struct dw_scl_sda_cfg hsw_config = { |
84 | .ss_hcnt = 0x01b0, |
85 | .fs_hcnt = 0x48, |
86 | .ss_lcnt = 0x01fb, |
87 | .fs_lcnt = 0xa0, |
88 | .sda_hold = 0x9, |
89 | }; |
90 | |
91 | /* NAVI-AMD HCNT/LCNT/SDA hold time */ |
92 | static struct dw_scl_sda_cfg navi_amd_config = { |
93 | .ss_hcnt = 0x1ae, |
94 | .ss_lcnt = 0x23a, |
95 | .sda_hold = 0x9, |
96 | }; |
97 | |
98 | static u32 mfld_get_clk_rate_khz(struct dw_i2c_dev *dev) |
99 | { |
100 | return 25000; |
101 | } |
102 | |
103 | static int mfld_setup(struct pci_dev *pdev, struct dw_pci_controller *c) |
104 | { |
105 | struct dw_i2c_dev *dev = dev_get_drvdata(dev: &pdev->dev); |
106 | |
107 | switch (pdev->device) { |
108 | case 0x0817: |
109 | dev->timings.bus_freq_hz = I2C_MAX_STANDARD_MODE_FREQ; |
110 | fallthrough; |
111 | case 0x0818: |
112 | case 0x0819: |
113 | c->bus_num = pdev->device - 0x817 + 3; |
114 | return 0; |
115 | case 0x082C: |
116 | case 0x082D: |
117 | case 0x082E: |
118 | c->bus_num = pdev->device - 0x82C + 0; |
119 | return 0; |
120 | } |
121 | return -ENODEV; |
122 | } |
123 | |
124 | static int mrfld_setup(struct pci_dev *pdev, struct dw_pci_controller *c) |
125 | { |
126 | /* |
127 | * On Intel Merrifield the user visible i2c buses are enumerated |
128 | * [1..7]. So, we add 1 to shift the default range. Besides that the |
129 | * first PCI slot provides 4 functions, that's why we have to add 0 to |
130 | * the first slot and 4 to the next one. |
131 | */ |
132 | switch (PCI_SLOT(pdev->devfn)) { |
133 | case 8: |
134 | c->bus_num = PCI_FUNC(pdev->devfn) + 0 + 1; |
135 | return 0; |
136 | case 9: |
137 | c->bus_num = PCI_FUNC(pdev->devfn) + 4 + 1; |
138 | return 0; |
139 | } |
140 | return -ENODEV; |
141 | } |
142 | |
143 | static u32 ehl_get_clk_rate_khz(struct dw_i2c_dev *dev) |
144 | { |
145 | return 100000; |
146 | } |
147 | |
148 | static u32 navi_amd_get_clk_rate_khz(struct dw_i2c_dev *dev) |
149 | { |
150 | return 100000; |
151 | } |
152 | |
153 | static int navi_amd_setup(struct pci_dev *pdev, struct dw_pci_controller *c) |
154 | { |
155 | struct dw_i2c_dev *dev = dev_get_drvdata(dev: &pdev->dev); |
156 | |
157 | dev->flags |= MODEL_AMD_NAVI_GPU; |
158 | dev->timings.bus_freq_hz = I2C_MAX_STANDARD_MODE_FREQ; |
159 | return 0; |
160 | } |
161 | |
162 | static struct dw_pci_controller dw_pci_controllers[] = { |
163 | [medfield] = { |
164 | .bus_num = -1, |
165 | .setup = mfld_setup, |
166 | .get_clk_rate_khz = mfld_get_clk_rate_khz, |
167 | }, |
168 | [merrifield] = { |
169 | .bus_num = -1, |
170 | .scl_sda_cfg = &mrfld_config, |
171 | .setup = mrfld_setup, |
172 | }, |
173 | [baytrail] = { |
174 | .bus_num = -1, |
175 | .scl_sda_cfg = &byt_config, |
176 | }, |
177 | [haswell] = { |
178 | .bus_num = -1, |
179 | .scl_sda_cfg = &hsw_config, |
180 | }, |
181 | [cherrytrail] = { |
182 | .bus_num = -1, |
183 | .scl_sda_cfg = &byt_config, |
184 | }, |
185 | [elkhartlake] = { |
186 | .bus_num = -1, |
187 | .get_clk_rate_khz = ehl_get_clk_rate_khz, |
188 | }, |
189 | [navi_amd] = { |
190 | .bus_num = -1, |
191 | .scl_sda_cfg = &navi_amd_config, |
192 | .setup = navi_amd_setup, |
193 | .get_clk_rate_khz = navi_amd_get_clk_rate_khz, |
194 | }, |
195 | }; |
196 | |
197 | static int __maybe_unused i2c_dw_pci_runtime_suspend(struct device *dev) |
198 | { |
199 | struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); |
200 | |
201 | i_dev->disable(i_dev); |
202 | return 0; |
203 | } |
204 | |
205 | static int __maybe_unused i2c_dw_pci_suspend(struct device *dev) |
206 | { |
207 | struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); |
208 | |
209 | i2c_mark_adapter_suspended(adap: &i_dev->adapter); |
210 | |
211 | return i2c_dw_pci_runtime_suspend(dev); |
212 | } |
213 | |
214 | static int __maybe_unused i2c_dw_pci_runtime_resume(struct device *dev) |
215 | { |
216 | struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); |
217 | |
218 | return i_dev->init(i_dev); |
219 | } |
220 | |
221 | static int __maybe_unused i2c_dw_pci_resume(struct device *dev) |
222 | { |
223 | struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); |
224 | int ret; |
225 | |
226 | ret = i2c_dw_pci_runtime_resume(dev); |
227 | |
228 | i2c_mark_adapter_resumed(adap: &i_dev->adapter); |
229 | |
230 | return ret; |
231 | } |
232 | |
233 | static const struct dev_pm_ops i2c_dw_pm_ops = { |
234 | SET_SYSTEM_SLEEP_PM_OPS(i2c_dw_pci_suspend, i2c_dw_pci_resume) |
235 | SET_RUNTIME_PM_OPS(i2c_dw_pci_runtime_suspend, i2c_dw_pci_runtime_resume, NULL) |
236 | }; |
237 | |
238 | static const struct property_entry dgpu_properties[] = { |
239 | /* USB-C doesn't power the system */ |
240 | PROPERTY_ENTRY_U8("scope" , POWER_SUPPLY_SCOPE_DEVICE), |
241 | {} |
242 | }; |
243 | |
244 | static const struct software_node dgpu_node = { |
245 | .properties = dgpu_properties, |
246 | }; |
247 | |
248 | static int i2c_dw_pci_probe(struct pci_dev *pdev, |
249 | const struct pci_device_id *id) |
250 | { |
251 | struct dw_i2c_dev *dev; |
252 | struct i2c_adapter *adap; |
253 | int r; |
254 | struct dw_pci_controller *controller; |
255 | struct dw_scl_sda_cfg *cfg; |
256 | struct i2c_timings *t; |
257 | |
258 | if (id->driver_data >= ARRAY_SIZE(dw_pci_controllers)) |
259 | return dev_err_probe(dev: &pdev->dev, err: -EINVAL, |
260 | fmt: "Invalid driver data %ld\n" , |
261 | id->driver_data); |
262 | |
263 | controller = &dw_pci_controllers[id->driver_data]; |
264 | |
265 | r = pcim_enable_device(pdev); |
266 | if (r) |
267 | return dev_err_probe(dev: &pdev->dev, err: r, |
268 | fmt: "Failed to enable I2C PCI device\n" ); |
269 | |
270 | pci_set_master(dev: pdev); |
271 | |
272 | r = pcim_iomap_regions(pdev, mask: 1 << 0, name: pci_name(pdev)); |
273 | if (r) |
274 | return dev_err_probe(dev: &pdev->dev, err: r, |
275 | fmt: "I/O memory remapping failed\n" ); |
276 | |
277 | dev = devm_kzalloc(dev: &pdev->dev, size: sizeof(*dev), GFP_KERNEL); |
278 | if (!dev) |
279 | return -ENOMEM; |
280 | |
281 | r = pci_alloc_irq_vectors(dev: pdev, min_vecs: 1, max_vecs: 1, PCI_IRQ_ALL_TYPES); |
282 | if (r < 0) |
283 | return r; |
284 | |
285 | dev->get_clk_rate_khz = controller->get_clk_rate_khz; |
286 | dev->base = pcim_iomap_table(pdev)[0]; |
287 | dev->dev = &pdev->dev; |
288 | dev->irq = pci_irq_vector(dev: pdev, nr: 0); |
289 | dev->flags |= controller->flags; |
290 | |
291 | t = &dev->timings; |
292 | i2c_parse_fw_timings(dev: &pdev->dev, t, use_defaults: false); |
293 | |
294 | pci_set_drvdata(pdev, data: dev); |
295 | |
296 | if (controller->setup) { |
297 | r = controller->setup(pdev, controller); |
298 | if (r) { |
299 | pci_free_irq_vectors(dev: pdev); |
300 | return r; |
301 | } |
302 | } |
303 | |
304 | i2c_dw_adjust_bus_speed(dev); |
305 | |
306 | if (has_acpi_companion(dev: &pdev->dev)) |
307 | i2c_dw_acpi_configure(device: &pdev->dev); |
308 | |
309 | r = i2c_dw_validate_speed(dev); |
310 | if (r) { |
311 | pci_free_irq_vectors(dev: pdev); |
312 | return r; |
313 | } |
314 | |
315 | i2c_dw_configure(dev); |
316 | |
317 | if (controller->scl_sda_cfg) { |
318 | cfg = controller->scl_sda_cfg; |
319 | dev->ss_hcnt = cfg->ss_hcnt; |
320 | dev->fs_hcnt = cfg->fs_hcnt; |
321 | dev->ss_lcnt = cfg->ss_lcnt; |
322 | dev->fs_lcnt = cfg->fs_lcnt; |
323 | dev->sda_hold_time = cfg->sda_hold; |
324 | } |
325 | |
326 | adap = &dev->adapter; |
327 | adap->owner = THIS_MODULE; |
328 | adap->class = 0; |
329 | ACPI_COMPANION_SET(&adap->dev, ACPI_COMPANION(&pdev->dev)); |
330 | adap->nr = controller->bus_num; |
331 | |
332 | r = i2c_dw_probe(dev); |
333 | if (r) { |
334 | pci_free_irq_vectors(dev: pdev); |
335 | return r; |
336 | } |
337 | |
338 | if ((dev->flags & MODEL_MASK) == MODEL_AMD_NAVI_GPU) { |
339 | dev->slave = i2c_new_ccgx_ucsi(adapter: &dev->adapter, irq: dev->irq, swnode: &dgpu_node); |
340 | if (IS_ERR(ptr: dev->slave)) |
341 | return dev_err_probe(dev: dev->dev, err: PTR_ERR(ptr: dev->slave), |
342 | fmt: "register UCSI failed\n" ); |
343 | } |
344 | |
345 | pm_runtime_set_autosuspend_delay(dev: &pdev->dev, delay: 1000); |
346 | pm_runtime_use_autosuspend(dev: &pdev->dev); |
347 | pm_runtime_put_autosuspend(dev: &pdev->dev); |
348 | pm_runtime_allow(dev: &pdev->dev); |
349 | |
350 | return 0; |
351 | } |
352 | |
353 | static void i2c_dw_pci_remove(struct pci_dev *pdev) |
354 | { |
355 | struct dw_i2c_dev *dev = pci_get_drvdata(pdev); |
356 | |
357 | dev->disable(dev); |
358 | pm_runtime_forbid(dev: &pdev->dev); |
359 | pm_runtime_get_noresume(dev: &pdev->dev); |
360 | |
361 | i2c_del_adapter(adap: &dev->adapter); |
362 | devm_free_irq(dev: &pdev->dev, irq: dev->irq, dev_id: dev); |
363 | pci_free_irq_vectors(dev: pdev); |
364 | } |
365 | |
366 | static const struct pci_device_id i2_designware_pci_ids[] = { |
367 | /* Medfield */ |
368 | { PCI_VDEVICE(INTEL, 0x0817), medfield }, |
369 | { PCI_VDEVICE(INTEL, 0x0818), medfield }, |
370 | { PCI_VDEVICE(INTEL, 0x0819), medfield }, |
371 | { PCI_VDEVICE(INTEL, 0x082C), medfield }, |
372 | { PCI_VDEVICE(INTEL, 0x082D), medfield }, |
373 | { PCI_VDEVICE(INTEL, 0x082E), medfield }, |
374 | /* Merrifield */ |
375 | { PCI_VDEVICE(INTEL, 0x1195), merrifield }, |
376 | { PCI_VDEVICE(INTEL, 0x1196), merrifield }, |
377 | /* Baytrail */ |
378 | { PCI_VDEVICE(INTEL, 0x0F41), baytrail }, |
379 | { PCI_VDEVICE(INTEL, 0x0F42), baytrail }, |
380 | { PCI_VDEVICE(INTEL, 0x0F43), baytrail }, |
381 | { PCI_VDEVICE(INTEL, 0x0F44), baytrail }, |
382 | { PCI_VDEVICE(INTEL, 0x0F45), baytrail }, |
383 | { PCI_VDEVICE(INTEL, 0x0F46), baytrail }, |
384 | { PCI_VDEVICE(INTEL, 0x0F47), baytrail }, |
385 | /* Haswell */ |
386 | { PCI_VDEVICE(INTEL, 0x9c61), haswell }, |
387 | { PCI_VDEVICE(INTEL, 0x9c62), haswell }, |
388 | /* Braswell / Cherrytrail */ |
389 | { PCI_VDEVICE(INTEL, 0x22C1), cherrytrail }, |
390 | { PCI_VDEVICE(INTEL, 0x22C2), cherrytrail }, |
391 | { PCI_VDEVICE(INTEL, 0x22C3), cherrytrail }, |
392 | { PCI_VDEVICE(INTEL, 0x22C4), cherrytrail }, |
393 | { PCI_VDEVICE(INTEL, 0x22C5), cherrytrail }, |
394 | { PCI_VDEVICE(INTEL, 0x22C6), cherrytrail }, |
395 | { PCI_VDEVICE(INTEL, 0x22C7), cherrytrail }, |
396 | /* Elkhart Lake (PSE I2C) */ |
397 | { PCI_VDEVICE(INTEL, 0x4bb9), elkhartlake }, |
398 | { PCI_VDEVICE(INTEL, 0x4bba), elkhartlake }, |
399 | { PCI_VDEVICE(INTEL, 0x4bbb), elkhartlake }, |
400 | { PCI_VDEVICE(INTEL, 0x4bbc), elkhartlake }, |
401 | { PCI_VDEVICE(INTEL, 0x4bbd), elkhartlake }, |
402 | { PCI_VDEVICE(INTEL, 0x4bbe), elkhartlake }, |
403 | { PCI_VDEVICE(INTEL, 0x4bbf), elkhartlake }, |
404 | { PCI_VDEVICE(INTEL, 0x4bc0), elkhartlake }, |
405 | /* AMD NAVI */ |
406 | { PCI_VDEVICE(ATI, 0x7314), navi_amd }, |
407 | { PCI_VDEVICE(ATI, 0x73a4), navi_amd }, |
408 | { PCI_VDEVICE(ATI, 0x73e4), navi_amd }, |
409 | { PCI_VDEVICE(ATI, 0x73c4), navi_amd }, |
410 | { PCI_VDEVICE(ATI, 0x7444), navi_amd }, |
411 | { PCI_VDEVICE(ATI, 0x7464), navi_amd }, |
412 | { 0,} |
413 | }; |
414 | MODULE_DEVICE_TABLE(pci, i2_designware_pci_ids); |
415 | |
416 | static struct pci_driver dw_i2c_driver = { |
417 | .name = DRIVER_NAME, |
418 | .id_table = i2_designware_pci_ids, |
419 | .probe = i2c_dw_pci_probe, |
420 | .remove = i2c_dw_pci_remove, |
421 | .driver = { |
422 | .pm = &i2c_dw_pm_ops, |
423 | }, |
424 | }; |
425 | module_pci_driver(dw_i2c_driver); |
426 | |
427 | /* Work with hotplug and coldplug */ |
428 | MODULE_ALIAS("i2c_designware-pci" ); |
429 | MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>" ); |
430 | MODULE_DESCRIPTION("Synopsys DesignWare PCI I2C bus adapter" ); |
431 | MODULE_LICENSE("GPL" ); |
432 | |