]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - drivers/media/pci/intel/ipu.c
UBUNTU: SAUCE: IPU6 driver release for kernel 5.14 on 2021-11-01
[mirror_ubuntu-jammy-kernel.git] / drivers / media / pci / intel / ipu.c
CommitLineData
f2efa4ee
WY
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (C) 2013 - 2020 Intel Corporation
3
4#include <linux/debugfs.h>
5#include <linux/device.h>
6#include <linux/interrupt.h>
7#include <linux/firmware.h>
8#include <linux/module.h>
9#include <linux/mutex.h>
10#include <linux/pci.h>
11#include <linux/pm_qos.h>
12#include <linux/pm_runtime.h>
13#include <linux/timer.h>
14#include <linux/sched.h>
15
16#include "ipu.h"
17#include "ipu-buttress.h"
18#include "ipu-platform.h"
19#include "ipu-platform-buttress-regs.h"
20#include "ipu-cpd.h"
21#include "ipu-pdata.h"
22#include "ipu-bus.h"
23#include "ipu-mmu.h"
24#include "ipu-platform-regs.h"
25#include "ipu-platform-isys-csi2-reg.h"
26#include "ipu-trace.h"
27
28#define IPU_PCI_BAR 0
29enum ipu_version ipu_ver;
30EXPORT_SYMBOL(ipu_ver);
31
32static struct ipu_bus_device *ipu_isys_init(struct pci_dev *pdev,
33 struct device *parent,
34 struct ipu_buttress_ctrl *ctrl,
35 void __iomem *base,
36 const struct ipu_isys_internal_pdata
37 *ipdata,
38 unsigned int nr)
39{
40 struct ipu_bus_device *isys;
41 struct ipu_isys_pdata *pdata;
42
43 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
44 if (!pdata)
45 return ERR_PTR(-ENOMEM);
46
47 pdata->base = base;
48 pdata->ipdata = ipdata;
49
3ebd4441
WY
50 /* Use 250MHz for ipu6 se */
51 if (ipu_ver == IPU_VER_6SE)
52 ctrl->ratio = IPU6SE_IS_FREQ_CTL_DEFAULT_RATIO;
53
f2efa4ee
WY
54 isys = ipu_bus_add_device(pdev, parent, pdata, ctrl,
55 IPU_ISYS_NAME, nr);
56 if (IS_ERR(isys))
57 return ERR_PTR(-ENOMEM);
58
59 isys->mmu = ipu_mmu_init(&pdev->dev, base, ISYS_MMID,
60 &ipdata->hw_variant);
61 if (IS_ERR(isys->mmu))
62 return ERR_PTR(-ENOMEM);
63
64 isys->mmu->dev = &isys->dev;
65
66 return isys;
67}
68
69static struct ipu_bus_device *ipu_psys_init(struct pci_dev *pdev,
70 struct device *parent,
71 struct ipu_buttress_ctrl *ctrl,
72 void __iomem *base,
73 const struct ipu_psys_internal_pdata
74 *ipdata, unsigned int nr)
75{
76 struct ipu_bus_device *psys;
77 struct ipu_psys_pdata *pdata;
78
79 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
80 if (!pdata)
81 return ERR_PTR(-ENOMEM);
82
83 pdata->base = base;
84 pdata->ipdata = ipdata;
85
86 psys = ipu_bus_add_device(pdev, parent, pdata, ctrl,
87 IPU_PSYS_NAME, nr);
88 if (IS_ERR(psys))
89 return ERR_PTR(-ENOMEM);
90
91 psys->mmu = ipu_mmu_init(&pdev->dev, base, PSYS_MMID,
92 &ipdata->hw_variant);
93 if (IS_ERR(psys->mmu))
94 return ERR_PTR(-ENOMEM);
95
96 psys->mmu->dev = &psys->dev;
97
98 return psys;
99}
100
101int ipu_fw_authenticate(void *data, u64 val)
102{
103 struct ipu_device *isp = data;
104 int ret;
105
106 if (!isp->secure_mode)
107 return -EINVAL;
108
109 ret = ipu_buttress_reset_authentication(isp);
110 if (ret) {
111 dev_err(&isp->pdev->dev, "Failed to reset authentication!\n");
112 return ret;
113 }
114
115 ret = pm_runtime_get_sync(&isp->psys->dev);
116 if (ret < 0) {
117 dev_err(&isp->pdev->dev, "Runtime PM failed (%d)\n", ret);
118 return ret;
119 }
120
121 ret = ipu_buttress_authenticate(isp);
122 if (ret) {
123 dev_err(&isp->pdev->dev, "FW authentication failed\n");
124 return ret;
125 }
126
127 pm_runtime_put(&isp->psys->dev);
128
129 return 0;
130}
131EXPORT_SYMBOL(ipu_fw_authenticate);
132DEFINE_SIMPLE_ATTRIBUTE(authenticate_fops, NULL, ipu_fw_authenticate, "%llu\n");
133
134#ifdef CONFIG_DEBUG_FS
135static int resume_ipu_bus_device(struct ipu_bus_device *adev)
136{
137 struct device *dev = &adev->dev;
138 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
139
140 if (!pm || !pm->resume)
141 return -EIO;
142
143 return pm->resume(dev);
144}
145
146static int suspend_ipu_bus_device(struct ipu_bus_device *adev)
147{
148 struct device *dev = &adev->dev;
149 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
150
151 if (!pm || !pm->suspend)
152 return -EIO;
153
154 return pm->suspend(dev);
155}
156
157static int force_suspend_get(void *data, u64 *val)
158{
159 struct ipu_device *isp = data;
160 struct ipu_buttress *b = &isp->buttress;
161
162 *val = b->force_suspend;
163 return 0;
164}
165
166static int force_suspend_set(void *data, u64 val)
167{
168 struct ipu_device *isp = data;
169 struct ipu_buttress *b = &isp->buttress;
170 int ret = 0;
171
172 if (val == b->force_suspend)
173 return 0;
174
175 if (val) {
176 b->force_suspend = 1;
177 ret = suspend_ipu_bus_device(isp->psys);
178 if (ret) {
179 dev_err(&isp->pdev->dev, "Failed to suspend psys\n");
180 return ret;
181 }
182 ret = suspend_ipu_bus_device(isp->isys);
183 if (ret) {
184 dev_err(&isp->pdev->dev, "Failed to suspend isys\n");
185 return ret;
186 }
187 ret = pci_set_power_state(isp->pdev, PCI_D3hot);
188 if (ret) {
189 dev_err(&isp->pdev->dev,
190 "Failed to suspend IUnit PCI device\n");
191 return ret;
192 }
193 } else {
194 ret = pci_set_power_state(isp->pdev, PCI_D0);
195 if (ret) {
196 dev_err(&isp->pdev->dev,
197 "Failed to suspend IUnit PCI device\n");
198 return ret;
199 }
200 ret = resume_ipu_bus_device(isp->isys);
201 if (ret) {
202 dev_err(&isp->pdev->dev, "Failed to resume isys\n");
203 return ret;
204 }
205 ret = resume_ipu_bus_device(isp->psys);
206 if (ret) {
207 dev_err(&isp->pdev->dev, "Failed to resume psys\n");
208 return ret;
209 }
210 b->force_suspend = 0;
211 }
212
213 return 0;
214}
215
216DEFINE_SIMPLE_ATTRIBUTE(force_suspend_fops, force_suspend_get,
217 force_suspend_set, "%llu\n");
218/*
219 * The sysfs interface for reloading cpd fw is there only for debug purpose,
220 * and it must not be used when either isys or psys is in use.
221 */
222static int cpd_fw_reload(void *data, u64 val)
223{
224 struct ipu_device *isp = data;
225 int rval = -EINVAL;
226
227 if (isp->cpd_fw_reload)
228 rval = isp->cpd_fw_reload(isp);
229
230 return rval;
231}
232
233DEFINE_SIMPLE_ATTRIBUTE(cpd_fw_fops, NULL, cpd_fw_reload, "%llu\n");
234
235static int ipu_init_debugfs(struct ipu_device *isp)
236{
237 struct dentry *file;
238 struct dentry *dir;
239
240 dir = debugfs_create_dir(pci_name(isp->pdev), NULL);
241 if (!dir)
242 return -ENOMEM;
243
244 file = debugfs_create_file("force_suspend", 0700, dir, isp,
245 &force_suspend_fops);
246 if (!file)
247 goto err;
248 file = debugfs_create_file("authenticate", 0700, dir, isp,
249 &authenticate_fops);
250 if (!file)
251 goto err;
252
253 file = debugfs_create_file("cpd_fw_reload", 0700, dir, isp,
254 &cpd_fw_fops);
255 if (!file)
256 goto err;
257
258 if (ipu_trace_debugfs_add(isp, dir))
259 goto err;
260
261 isp->ipu_dir = dir;
262
263 if (ipu_buttress_debugfs_init(isp))
264 goto err;
265
266 return 0;
267err:
268 debugfs_remove_recursive(dir);
269 return -ENOMEM;
270}
271
272static void ipu_remove_debugfs(struct ipu_device *isp)
273{
274 /*
275 * Since isys and psys debugfs dir will be created under ipu root dir,
276 * mark its dentry to NULL to avoid duplicate removal.
277 */
278 debugfs_remove_recursive(isp->ipu_dir);
279 isp->ipu_dir = NULL;
280}
281#endif /* CONFIG_DEBUG_FS */
282
283static int ipu_pci_config_setup(struct pci_dev *dev)
284{
285 u16 pci_command;
eaffc3a7 286 int rval;
f2efa4ee
WY
287
288 pci_read_config_word(dev, PCI_COMMAND, &pci_command);
eaffc3a7 289 pci_command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
f2efa4ee 290 pci_write_config_word(dev, PCI_COMMAND, pci_command);
eaffc3a7
WY
291 if (ipu_ver == IPU_VER_6EP) {
292 /* likely do nothing as msi not enabled by default */
293 pci_disable_msi(dev);
294 return 0;
295 }
f2efa4ee 296
eaffc3a7
WY
297 rval = pci_enable_msi(dev);
298 if (rval)
299 dev_err(&dev->dev, "Failed to enable msi (%d)\n", rval);
300
301 return rval;
f2efa4ee
WY
302}
303
304static void ipu_configure_vc_mechanism(struct ipu_device *isp)
305{
306 u32 val = readl(isp->base + BUTTRESS_REG_BTRS_CTRL);
307
308 if (IPU_BTRS_ARB_STALL_MODE_VC0 == IPU_BTRS_ARB_MODE_TYPE_STALL)
309 val |= BUTTRESS_REG_BTRS_CTRL_STALL_MODE_VC0;
310 else
311 val &= ~BUTTRESS_REG_BTRS_CTRL_STALL_MODE_VC0;
312
313 if (IPU_BTRS_ARB_STALL_MODE_VC1 == IPU_BTRS_ARB_MODE_TYPE_STALL)
314 val |= BUTTRESS_REG_BTRS_CTRL_STALL_MODE_VC1;
315 else
316 val &= ~BUTTRESS_REG_BTRS_CTRL_STALL_MODE_VC1;
317
318 writel(val, isp->base + BUTTRESS_REG_BTRS_CTRL);
319}
320
321int request_cpd_fw(const struct firmware **firmware_p, const char *name,
322 struct device *device)
323{
324 const struct firmware *fw;
325 struct firmware *tmp;
326 int ret;
327
328 ret = request_firmware(&fw, name, device);
329 if (ret)
330 return ret;
331
332 if (is_vmalloc_addr(fw->data)) {
333 *firmware_p = fw;
334 } else {
335 tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
336 if (!tmp) {
337 release_firmware(fw);
338 return -ENOMEM;
339 }
340 tmp->size = fw->size;
341 tmp->data = vmalloc(fw->size);
342 if (!tmp->data) {
343 kfree(tmp);
344 release_firmware(fw);
345 return -ENOMEM;
346 }
347 memcpy((void *)tmp->data, fw->data, fw->size);
348 *firmware_p = tmp;
349 release_firmware(fw);
350 }
351
352 return 0;
353}
354EXPORT_SYMBOL(request_cpd_fw);
355
356static int ipu_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
357{
358 struct ipu_device *isp;
359 phys_addr_t phys;
360 void __iomem *const *iomap;
361 void __iomem *isys_base = NULL;
362 void __iomem *psys_base = NULL;
363 struct ipu_buttress_ctrl *isys_ctrl = NULL, *psys_ctrl = NULL;
364 unsigned int dma_mask = IPU_DMA_MASK;
365 int rval;
366
367 isp = devm_kzalloc(&pdev->dev, sizeof(*isp), GFP_KERNEL);
368 if (!isp)
369 return -ENOMEM;
370
371 dev_set_name(&pdev->dev, "intel-ipu");
372 isp->pdev = pdev;
373 INIT_LIST_HEAD(&isp->devices);
374
375 rval = pcim_enable_device(pdev);
376 if (rval) {
377 dev_err(&pdev->dev, "Failed to enable CI ISP device (%d)\n",
378 rval);
379 return rval;
380 }
381
382 dev_info(&pdev->dev, "Device 0x%x (rev: 0x%x)\n",
383 pdev->device, pdev->revision);
384
385 phys = pci_resource_start(pdev, IPU_PCI_BAR);
386
387 rval = pcim_iomap_regions(pdev,
388 1 << IPU_PCI_BAR,
389 pci_name(pdev));
390 if (rval) {
391 dev_err(&pdev->dev, "Failed to I/O memory remapping (%d)\n",
392 rval);
393 return rval;
394 }
395 dev_info(&pdev->dev, "physical base address 0x%llx\n", phys);
396
397 iomap = pcim_iomap_table(pdev);
398 if (!iomap) {
399 dev_err(&pdev->dev, "Failed to iomap table (%d)\n", rval);
400 return -ENODEV;
401 }
402
403 isp->base = iomap[IPU_PCI_BAR];
404 dev_info(&pdev->dev, "mapped as: 0x%p\n", isp->base);
405
406 pci_set_drvdata(pdev, isp);
407 pci_set_master(pdev);
408
409 switch (id->device) {
410 case IPU6_PCI_ID:
411 ipu_ver = IPU_VER_6;
412 isp->cpd_fw_name = IPU6_FIRMWARE_NAME;
413 break;
414 case IPU6SE_PCI_ID:
415 ipu_ver = IPU_VER_6SE;
416 isp->cpd_fw_name = IPU6SE_FIRMWARE_NAME;
417 break;
5a771b35
HY
418 case IPU6EP_ADL_P_PCI_ID:
419 case IPU6EP_ADL_N_PCI_ID:
eaffc3a7
WY
420 ipu_ver = IPU_VER_6EP;
421 isp->cpd_fw_name = IPU6EP_FIRMWARE_NAME;
422 break;
f2efa4ee
WY
423 default:
424 WARN(1, "Unsupported IPU device");
425 return -ENODEV;
426 }
427
428 ipu_internal_pdata_init();
429
430 isys_base = isp->base + isys_ipdata.hw_variant.offset;
431 psys_base = isp->base + psys_ipdata.hw_variant.offset;
432
433 dev_dbg(&pdev->dev, "isys_base: 0x%lx\n", (unsigned long)isys_base);
434 dev_dbg(&pdev->dev, "psys_base: 0x%lx\n", (unsigned long)psys_base);
435
436 rval = pci_set_dma_mask(pdev, DMA_BIT_MASK(dma_mask));
437 if (!rval)
438 rval = pci_set_consistent_dma_mask(pdev,
439 DMA_BIT_MASK(dma_mask));
440 if (rval) {
441 dev_err(&pdev->dev, "Failed to set DMA mask (%d)\n", rval);
442 return rval;
443 }
444
3ebd4441
WY
445 dma_set_max_seg_size(&pdev->dev, UINT_MAX);
446
f2efa4ee
WY
447 rval = ipu_pci_config_setup(pdev);
448 if (rval)
449 return rval;
450
451 rval = devm_request_threaded_irq(&pdev->dev, pdev->irq,
452 ipu_buttress_isr,
453 ipu_buttress_isr_threaded,
454 IRQF_SHARED, IPU_NAME, isp);
455 if (rval) {
456 dev_err(&pdev->dev, "Requesting irq failed(%d)\n", rval);
457 return rval;
458 }
459
460 rval = ipu_buttress_init(isp);
461 if (rval)
462 return rval;
463
464 dev_info(&pdev->dev, "cpd file name: %s\n", isp->cpd_fw_name);
465
466 rval = request_cpd_fw(&isp->cpd_fw, isp->cpd_fw_name, &pdev->dev);
467 if (rval) {
468 dev_err(&isp->pdev->dev, "Requesting signed firmware failed\n");
469 return rval;
470 }
471
472 rval = ipu_cpd_validate_cpd_file(isp, isp->cpd_fw->data,
473 isp->cpd_fw->size);
474 if (rval) {
475 dev_err(&isp->pdev->dev, "Failed to validate cpd\n");
476 goto out_ipu_bus_del_devices;
477 }
478
479 rval = ipu_trace_add(isp);
480 if (rval)
481 dev_err(&pdev->dev, "Trace support not available\n");
482
483 pm_runtime_put_noidle(&pdev->dev);
484 pm_runtime_allow(&pdev->dev);
485
486 /*
487 * NOTE Device hierarchy below is important to ensure proper
488 * runtime suspend and resume order.
489 * Also registration order is important to ensure proper
490 * suspend and resume order during system
491 * suspend. Registration order is as follows:
492 * isys->psys
493 */
494 isys_ctrl = devm_kzalloc(&pdev->dev, sizeof(*isys_ctrl), GFP_KERNEL);
495 if (!isys_ctrl) {
496 rval = -ENOMEM;
497 goto out_ipu_bus_del_devices;
498 }
499
500 /* Init butress control with default values based on the HW */
501 memcpy(isys_ctrl, &isys_buttress_ctrl, sizeof(*isys_ctrl));
502
503 isp->isys = ipu_isys_init(pdev, &pdev->dev,
504 isys_ctrl, isys_base,
505 &isys_ipdata,
506 0);
507 if (IS_ERR(isp->isys)) {
508 rval = PTR_ERR(isp->isys);
509 goto out_ipu_bus_del_devices;
510 }
511
512 psys_ctrl = devm_kzalloc(&pdev->dev, sizeof(*psys_ctrl), GFP_KERNEL);
513 if (!psys_ctrl) {
514 rval = -ENOMEM;
515 goto out_ipu_bus_del_devices;
516 }
517
518 /* Init butress control with default values based on the HW */
519 memcpy(psys_ctrl, &psys_buttress_ctrl, sizeof(*psys_ctrl));
520
521 isp->psys = ipu_psys_init(pdev, &isp->isys->dev,
522 psys_ctrl, psys_base,
523 &psys_ipdata, 0);
524 if (IS_ERR(isp->psys)) {
525 rval = PTR_ERR(isp->psys);
526 goto out_ipu_bus_del_devices;
527 }
528
529 rval = pm_runtime_get_sync(&isp->psys->dev);
530 if (rval < 0) {
531 dev_err(&isp->psys->dev, "Failed to get runtime PM\n");
532 goto out_ipu_bus_del_devices;
533 }
534
535 rval = ipu_mmu_hw_init(isp->psys->mmu);
536 if (rval) {
537 dev_err(&isp->pdev->dev, "Failed to set mmu hw\n");
538 goto out_ipu_bus_del_devices;
539 }
540
541 rval = ipu_buttress_map_fw_image(isp->psys, isp->cpd_fw,
542 &isp->fw_sgt);
543 if (rval) {
544 dev_err(&isp->pdev->dev, "failed to map fw image\n");
545 goto out_ipu_bus_del_devices;
546 }
547
548 isp->pkg_dir = ipu_cpd_create_pkg_dir(isp->psys,
549 isp->cpd_fw->data,
550 sg_dma_address(isp->fw_sgt.sgl),
551 &isp->pkg_dir_dma_addr,
552 &isp->pkg_dir_size);
553 if (!isp->pkg_dir) {
554 rval = -ENOMEM;
555 dev_err(&isp->pdev->dev, "failed to create pkg dir\n");
556 goto out_ipu_bus_del_devices;
557 }
558
559 rval = ipu_buttress_authenticate(isp);
560 if (rval) {
561 dev_err(&isp->pdev->dev, "FW authentication failed(%d)\n",
562 rval);
563 goto out_ipu_bus_del_devices;
564 }
565
566 ipu_mmu_hw_cleanup(isp->psys->mmu);
567 pm_runtime_put(&isp->psys->dev);
568
569#ifdef CONFIG_DEBUG_FS
570 rval = ipu_init_debugfs(isp);
571 if (rval) {
572 dev_err(&pdev->dev, "Failed to initialize debugfs");
573 goto out_ipu_bus_del_devices;
574 }
575#endif
576
577 /* Configure the arbitration mechanisms for VC requests */
578 ipu_configure_vc_mechanism(isp);
579
580 dev_info(&pdev->dev, "IPU driver version %d.%d\n", IPU_MAJOR_VERSION,
581 IPU_MINOR_VERSION);
582
583 return 0;
584
585out_ipu_bus_del_devices:
586 if (isp->pkg_dir) {
587 ipu_cpd_free_pkg_dir(isp->psys, isp->pkg_dir,
588 isp->pkg_dir_dma_addr,
589 isp->pkg_dir_size);
590 ipu_buttress_unmap_fw_image(isp->psys, &isp->fw_sgt);
591 isp->pkg_dir = NULL;
592 }
593 if (isp->psys && isp->psys->mmu)
594 ipu_mmu_cleanup(isp->psys->mmu);
595 if (isp->isys && isp->isys->mmu)
596 ipu_mmu_cleanup(isp->isys->mmu);
597 if (isp->psys)
598 pm_runtime_put(&isp->psys->dev);
599 ipu_bus_del_devices(pdev);
600 ipu_buttress_exit(isp);
601 release_firmware(isp->cpd_fw);
602
603 return rval;
604}
605
606static void ipu_pci_remove(struct pci_dev *pdev)
607{
608 struct ipu_device *isp = pci_get_drvdata(pdev);
609
610#ifdef CONFIG_DEBUG_FS
611 ipu_remove_debugfs(isp);
612#endif
613 ipu_trace_release(isp);
614
af60d6fc
WY
615 ipu_cpd_free_pkg_dir(isp->psys, isp->pkg_dir, isp->pkg_dir_dma_addr,
616 isp->pkg_dir_size);
617
618 ipu_buttress_unmap_fw_image(isp->psys, &isp->fw_sgt);
619
620 isp->pkg_dir = NULL;
621 isp->pkg_dir_dma_addr = 0;
622 isp->pkg_dir_size = 0;
623
f2efa4ee
WY
624 ipu_bus_del_devices(pdev);
625
626 pm_runtime_forbid(&pdev->dev);
627 pm_runtime_get_noresume(&pdev->dev);
628
629 pci_release_regions(pdev);
630 pci_disable_device(pdev);
631
632 ipu_buttress_exit(isp);
633
634 release_firmware(isp->cpd_fw);
635
636 ipu_mmu_cleanup(isp->psys->mmu);
637 ipu_mmu_cleanup(isp->isys->mmu);
638}
639
640static void ipu_pci_reset_prepare(struct pci_dev *pdev)
641{
642 struct ipu_device *isp = pci_get_drvdata(pdev);
643
644 dev_warn(&pdev->dev, "FLR prepare\n");
645 pm_runtime_forbid(&isp->pdev->dev);
646 isp->flr_done = true;
647}
648
649static void ipu_pci_reset_done(struct pci_dev *pdev)
650{
651 struct ipu_device *isp = pci_get_drvdata(pdev);
652
653 ipu_buttress_restore(isp);
654 if (isp->secure_mode)
655 ipu_buttress_reset_authentication(isp);
656
657 ipu_bus_flr_recovery();
658 isp->ipc_reinit = true;
659 pm_runtime_allow(&isp->pdev->dev);
660
661 dev_warn(&pdev->dev, "FLR completed\n");
662}
663
664#ifdef CONFIG_PM
665
666/*
667 * PCI base driver code requires driver to provide these to enable
668 * PCI device level PM state transitions (D0<->D3)
669 */
670static int ipu_suspend(struct device *dev)
671{
672 struct pci_dev *pdev = to_pci_dev(dev);
673 struct ipu_device *isp = pci_get_drvdata(pdev);
674
675 isp->flr_done = false;
676
677 return 0;
678}
679
680static int ipu_resume(struct device *dev)
681{
682 struct pci_dev *pdev = to_pci_dev(dev);
683 struct ipu_device *isp = pci_get_drvdata(pdev);
684 struct ipu_buttress *b = &isp->buttress;
685 int rval;
686
687 /* Configure the arbitration mechanisms for VC requests */
688 ipu_configure_vc_mechanism(isp);
689
690 ipu_buttress_set_secure_mode(isp);
691 isp->secure_mode = ipu_buttress_get_secure_mode(isp);
692 dev_info(dev, "IPU in %s mode\n",
693 isp->secure_mode ? "secure" : "non-secure");
694
695 ipu_buttress_restore(isp);
696
697 rval = ipu_buttress_ipc_reset(isp, &b->cse);
698 if (rval)
699 dev_err(&isp->pdev->dev, "IPC reset protocol failed!\n");
700
701 rval = pm_runtime_get_sync(&isp->psys->dev);
702 if (rval < 0) {
703 dev_err(&isp->psys->dev, "Failed to get runtime PM\n");
704 return 0;
705 }
706
707 rval = ipu_buttress_authenticate(isp);
708 if (rval)
709 dev_err(&isp->pdev->dev, "FW authentication failed(%d)\n",
710 rval);
711
712 pm_runtime_put(&isp->psys->dev);
713
714 return 0;
715}
716
717static int ipu_runtime_resume(struct device *dev)
718{
719 struct pci_dev *pdev = to_pci_dev(dev);
720 struct ipu_device *isp = pci_get_drvdata(pdev);
721 int rval;
722
723 ipu_configure_vc_mechanism(isp);
724 ipu_buttress_restore(isp);
725
726 if (isp->ipc_reinit) {
727 struct ipu_buttress *b = &isp->buttress;
728
729 isp->ipc_reinit = false;
730 rval = ipu_buttress_ipc_reset(isp, &b->cse);
731 if (rval)
732 dev_err(&isp->pdev->dev,
733 "IPC reset protocol failed!\n");
734 }
735
736 return 0;
737}
738
739static const struct dev_pm_ops ipu_pm_ops = {
740 SET_SYSTEM_SLEEP_PM_OPS(&ipu_suspend, &ipu_resume)
741 SET_RUNTIME_PM_OPS(&ipu_suspend, /* Same as in suspend flow */
742 &ipu_runtime_resume,
743 NULL)
744};
745
746#define IPU_PM (&ipu_pm_ops)
747#else
748#define IPU_PM NULL
749#endif
750
751static const struct pci_device_id ipu_pci_tbl[] = {
752 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, IPU6_PCI_ID)},
753 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, IPU6SE_PCI_ID)},
5a771b35
HY
754 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, IPU6EP_ADL_P_PCI_ID)},
755 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, IPU6EP_ADL_N_PCI_ID)},
f2efa4ee
WY
756 {0,}
757};
758MODULE_DEVICE_TABLE(pci, ipu_pci_tbl);
759
760static const struct pci_error_handlers pci_err_handlers = {
761 .reset_prepare = ipu_pci_reset_prepare,
762 .reset_done = ipu_pci_reset_done,
763};
764
765static struct pci_driver ipu_pci_driver = {
766 .name = IPU_NAME,
767 .id_table = ipu_pci_tbl,
768 .probe = ipu_pci_probe,
769 .remove = ipu_pci_remove,
770 .driver = {
771 .pm = IPU_PM,
772 },
773 .err_handler = &pci_err_handlers,
774};
775
776static int __init ipu_init(void)
777{
778 int rval = ipu_bus_register();
779
780 if (rval) {
781 pr_warn("can't register ipu bus (%d)\n", rval);
782 return rval;
783 }
784
785 rval = pci_register_driver(&ipu_pci_driver);
786 if (rval) {
787 pr_warn("can't register pci driver (%d)\n", rval);
788 goto out_pci_register_driver;
789 }
790
791 return 0;
792
793out_pci_register_driver:
794 ipu_bus_unregister();
795
796 return rval;
797}
798
799static void __exit ipu_exit(void)
800{
801 pci_unregister_driver(&ipu_pci_driver);
802 ipu_bus_unregister();
803}
804
805module_init(ipu_init);
806module_exit(ipu_exit);
807
808MODULE_AUTHOR("Sakari Ailus <sakari.ailus@linux.intel.com>");
809MODULE_AUTHOR("Jouni Högander <jouni.hogander@intel.com>");
810MODULE_AUTHOR("Antti Laakso <antti.laakso@intel.com>");
811MODULE_AUTHOR("Samu Onkalo <samu.onkalo@intel.com>");
812MODULE_AUTHOR("Jianxu Zheng <jian.xu.zheng@intel.com>");
813MODULE_AUTHOR("Tianshu Qiu <tian.shu.qiu@intel.com>");
814MODULE_AUTHOR("Renwei Wu <renwei.wu@intel.com>");
815MODULE_AUTHOR("Bingbu Cao <bingbu.cao@intel.com>");
816MODULE_AUTHOR("Yunliang Ding <yunliang.ding@intel.com>");
817MODULE_AUTHOR("Zaikuo Wang <zaikuo.wang@intel.com>");
818MODULE_AUTHOR("Leifu Zhao <leifu.zhao@intel.com>");
819MODULE_AUTHOR("Xia Wu <xia.wu@intel.com>");
820MODULE_AUTHOR("Kun Jiang <kun.jiang@intel.com>");
821MODULE_AUTHOR("Intel");
822MODULE_LICENSE("GPL");
823MODULE_DESCRIPTION("Intel ipu pci driver");