1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2013--2024 Intel Corporation
6 #include <linux/bitfield.h>
7 #include <linux/bits.h>
8 #include <linux/dma-mapping.h>
10 #include <linux/firmware.h>
11 #include <linux/kernel.h>
12 #include <linux/interrupt.h>
14 #include <linux/list.h>
15 #include <linux/module.h>
16 #include <linux/pci-ats.h>
17 #include <linux/pm_runtime.h>
18 #include <linux/property.h>
19 #include <linux/scatterlist.h>
20 #include <linux/slab.h>
21 #include <linux/types.h>
23 #include <media/ipu-bridge.h>
24 #include <media/ipu6-pci-table.h>
28 #include "ipu6-buttress.h"
30 #include "ipu6-isys.h"
32 #include "ipu6-platform-buttress-regs.h"
33 #include "ipu6-platform-isys-csi2-reg.h"
34 #include "ipu6-platform-regs.h"
36 #define IPU6_PCI_BAR 0
38 struct ipu6_cell_program {
64 u32 cell_pmem_data_bus_address;
65 u32 cell_dmem_data_bus_address;
66 u32 cell_pmem_control_bus_address;
67 u32 cell_dmem_control_bus_address;
73 static struct ipu6_isys_internal_pdata isys_ipdata = {
75 .offset = IPU6_UNIFIED_OFFSET,
79 .offset = IPU6_ISYS_IOMMU0_OFFSET,
80 .info_bits = IPU6_INFO_REQUEST_DESTINATION_IOSF,
83 3, 8, 2, 2, 2, 2, 2, 2, 1, 1,
88 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
91 .insert_read_before_invalidate = false,
92 .l1_stream_id_reg_offset =
93 IPU6_MMU_L1_STREAM_ID_REG_OFFSET,
94 .l2_stream_id_reg_offset =
95 IPU6_MMU_L2_STREAM_ID_REG_OFFSET,
98 .offset = IPU6_ISYS_IOMMU1_OFFSET,
102 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
107 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
110 .insert_read_before_invalidate = false,
111 .l1_stream_id_reg_offset =
112 IPU6_MMU_L1_STREAM_ID_REG_OFFSET,
113 .l2_stream_id_reg_offset =
114 IPU6_MMU_L2_STREAM_ID_REG_OFFSET,
117 .offset = IPU6_ISYS_IOMMUI_OFFSET,
121 .insert_read_before_invalidate = false,
125 .cdc_fifo_threshold = {6, 8, 2},
126 .dmem_offset = IPU6_ISYS_DMEM_OFFSET,
127 .spc_offset = IPU6_ISYS_SPC_OFFSET,
129 .isys_dma_overshoot = IPU6_ISYS_OVERALLOC_MIN,
132 static struct ipu6_psys_internal_pdata psys_ipdata = {
134 .offset = IPU6_UNIFIED_OFFSET,
138 .offset = IPU6_PSYS_IOMMU0_OFFSET,
140 IPU6_INFO_REQUEST_DESTINATION_IOSF,
143 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
148 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
151 .insert_read_before_invalidate = false,
152 .l1_stream_id_reg_offset =
153 IPU6_MMU_L1_STREAM_ID_REG_OFFSET,
154 .l2_stream_id_reg_offset =
155 IPU6_MMU_L2_STREAM_ID_REG_OFFSET,
158 .offset = IPU6_PSYS_IOMMU1_OFFSET,
162 1, 2, 2, 2, 2, 2, 2, 2, 2, 2,
164 5, 4, 14, 6, 4, 14, 6, 4, 8,
169 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
171 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
174 .insert_read_before_invalidate = false,
175 .l1_stream_id_reg_offset =
176 IPU6_MMU_L1_STREAM_ID_REG_OFFSET,
177 .l2_stream_id_reg_offset =
178 IPU6_PSYS_MMU1W_L2_STREAM_ID_REG_OFFSET,
181 .offset = IPU6_PSYS_IOMMU1R_OFFSET,
185 1, 4, 4, 4, 4, 16, 8, 4, 32,
186 16, 16, 2, 2, 2, 1, 12
190 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
193 .insert_read_before_invalidate = false,
194 .l1_stream_id_reg_offset =
195 IPU6_MMU_L1_STREAM_ID_REG_OFFSET,
196 .l2_stream_id_reg_offset =
197 IPU6_MMU_L2_STREAM_ID_REG_OFFSET,
200 .offset = IPU6_PSYS_IOMMUI_OFFSET,
204 .insert_read_before_invalidate = false,
207 .dmem_offset = IPU6_PSYS_DMEM_OFFSET,
211 static const struct ipu6_buttress_ctrl isys_buttress_ctrl = {
212 .ratio = IPU6_IS_FREQ_CTL_DEFAULT_RATIO,
213 .qos_floor = IPU6_IS_FREQ_CTL_DEFAULT_QOS_FLOOR_RATIO,
214 .freq_ctl = IPU6_BUTTRESS_REG_IS_FREQ_CTL,
215 .pwr_sts_shift = IPU6_BUTTRESS_PWR_STATE_IS_PWR_SHIFT,
216 .pwr_sts_mask = IPU6_BUTTRESS_PWR_STATE_IS_PWR_MASK,
217 .pwr_sts_on = IPU6_BUTTRESS_PWR_STATE_UP_DONE,
218 .pwr_sts_off = IPU6_BUTTRESS_PWR_STATE_DN_DONE,
221 static const struct ipu6_buttress_ctrl psys_buttress_ctrl = {
222 .ratio = IPU6_PS_FREQ_CTL_DEFAULT_RATIO,
223 .qos_floor = IPU6_PS_FREQ_CTL_DEFAULT_QOS_FLOOR_RATIO,
224 .freq_ctl = IPU6_BUTTRESS_REG_PS_FREQ_CTL,
225 .pwr_sts_shift = IPU6_BUTTRESS_PWR_STATE_PS_PWR_SHIFT,
226 .pwr_sts_mask = IPU6_BUTTRESS_PWR_STATE_PS_PWR_MASK,
227 .pwr_sts_on = IPU6_BUTTRESS_PWR_STATE_UP_DONE,
228 .pwr_sts_off = IPU6_BUTTRESS_PWR_STATE_DN_DONE,
232 ipu6_pkg_dir_configure_spc(struct ipu6_device *isp,
233 const struct ipu6_hw_variants *hw_variant,
234 int pkg_dir_idx, void __iomem *base,
235 u64 *pkg_dir, dma_addr_t pkg_dir_vied_address)
237 struct ipu6_cell_program *prog;
238 void __iomem *spc_base;
243 server_fw_addr = lower_32_bits(*(pkg_dir + (pkg_dir_idx + 1) * 2));
244 if (pkg_dir_idx == IPU6_CPD_PKG_DIR_ISYS_SERVER_IDX)
245 dma_addr = sg_dma_address(isp->isys->fw_sgt.sgl);
247 dma_addr = sg_dma_address(isp->psys->fw_sgt.sgl);
249 pg_offset = server_fw_addr - dma_addr;
250 prog = (struct ipu6_cell_program *)((u64)isp->cpd_fw->data + pg_offset);
251 spc_base = base + prog->regs_addr;
252 if (spc_base != (base + hw_variant->spc_offset))
253 dev_warn(&isp->pdev->dev,
254 "SPC reg addr %p not matching value from CPD %p\n",
255 base + hw_variant->spc_offset, spc_base);
256 writel(server_fw_addr + prog->blob_offset +
257 prog->icache_source, spc_base + IPU6_PSYS_REG_SPC_ICACHE_BASE);
258 writel(IPU6_INFO_REQUEST_DESTINATION_IOSF,
259 spc_base + IPU6_REG_PSYS_INFO_SEG_0_CONFIG_ICACHE_MASTER);
260 writel(prog->start[1], spc_base + IPU6_PSYS_REG_SPC_START_PC);
261 writel(pkg_dir_vied_address, base + hw_variant->dmem_offset);
264 void ipu6_configure_spc(struct ipu6_device *isp,
265 const struct ipu6_hw_variants *hw_variant,
266 int pkg_dir_idx, void __iomem *base, u64 *pkg_dir,
267 dma_addr_t pkg_dir_dma_addr)
269 void __iomem *dmem_base = base + hw_variant->dmem_offset;
270 void __iomem *spc_regs_base = base + hw_variant->spc_offset;
273 val = readl(spc_regs_base + IPU6_PSYS_REG_SPC_STATUS_CTRL);
274 val |= IPU6_PSYS_SPC_STATUS_CTRL_ICACHE_INVALIDATE;
275 writel(val, spc_regs_base + IPU6_PSYS_REG_SPC_STATUS_CTRL);
277 if (isp->secure_mode)
278 writel(IPU6_PKG_DIR_IMR_OFFSET, dmem_base);
280 ipu6_pkg_dir_configure_spc(isp, hw_variant, pkg_dir_idx, base,
281 pkg_dir, pkg_dir_dma_addr);
283 EXPORT_SYMBOL_NS_GPL(ipu6_configure_spc, INTEL_IPU6);
285 #define IPU6_ISYS_CSI2_NPORTS 4
286 #define IPU6SE_ISYS_CSI2_NPORTS 4
287 #define IPU6_TGL_ISYS_CSI2_NPORTS 8
288 #define IPU6EP_MTL_ISYS_CSI2_NPORTS 4
290 static void ipu6_internal_pdata_init(struct ipu6_device *isp)
292 u8 hw_ver = isp->hw_ver;
294 isys_ipdata.num_parallel_streams = IPU6_ISYS_NUM_STREAMS;
295 isys_ipdata.sram_gran_shift = IPU6_SRAM_GRANULARITY_SHIFT;
296 isys_ipdata.sram_gran_size = IPU6_SRAM_GRANULARITY_SIZE;
297 isys_ipdata.max_sram_size = IPU6_MAX_SRAM_SIZE;
298 isys_ipdata.sensor_type_start = IPU6_FW_ISYS_SENSOR_TYPE_START;
299 isys_ipdata.sensor_type_end = IPU6_FW_ISYS_SENSOR_TYPE_END;
300 isys_ipdata.max_streams = IPU6_ISYS_NUM_STREAMS;
301 isys_ipdata.max_send_queues = IPU6_N_MAX_SEND_QUEUES;
302 isys_ipdata.max_sram_blocks = IPU6_NOF_SRAM_BLOCKS_MAX;
303 isys_ipdata.max_devq_size = IPU6_DEV_SEND_QUEUE_SIZE;
304 isys_ipdata.csi2.nports = IPU6_ISYS_CSI2_NPORTS;
305 isys_ipdata.csi2.irq_mask = IPU6_CSI_RX_ERROR_IRQ_MASK;
306 isys_ipdata.csi2.ctrl0_irq_edge = IPU6_REG_ISYS_CSI_TOP_CTRL0_IRQ_EDGE;
307 isys_ipdata.csi2.ctrl0_irq_clear =
308 IPU6_REG_ISYS_CSI_TOP_CTRL0_IRQ_CLEAR;
309 isys_ipdata.csi2.ctrl0_irq_mask = IPU6_REG_ISYS_CSI_TOP_CTRL0_IRQ_MASK;
310 isys_ipdata.csi2.ctrl0_irq_enable =
311 IPU6_REG_ISYS_CSI_TOP_CTRL0_IRQ_ENABLE;
312 isys_ipdata.csi2.ctrl0_irq_status =
313 IPU6_REG_ISYS_CSI_TOP_CTRL0_IRQ_STATUS;
314 isys_ipdata.csi2.ctrl0_irq_lnp =
315 IPU6_REG_ISYS_CSI_TOP_CTRL0_IRQ_LEVEL_NOT_PULSE;
316 isys_ipdata.enhanced_iwake = is_ipu6ep_mtl(hw_ver) || is_ipu6ep(hw_ver);
317 psys_ipdata.hw_variant.spc_offset = IPU6_PSYS_SPC_OFFSET;
318 isys_ipdata.csi2.fw_access_port_ofs = CSI_REG_HUB_FW_ACCESS_PORT_OFS;
320 if (is_ipu6ep(hw_ver)) {
321 isys_ipdata.ltr = IPU6EP_LTR_VALUE;
322 isys_ipdata.memopen_threshold = IPU6EP_MIN_MEMOPEN_TH;
325 if (is_ipu6_tgl(hw_ver))
326 isys_ipdata.csi2.nports = IPU6_TGL_ISYS_CSI2_NPORTS;
328 if (is_ipu6ep_mtl(hw_ver)) {
329 isys_ipdata.csi2.nports = IPU6EP_MTL_ISYS_CSI2_NPORTS;
331 isys_ipdata.csi2.ctrl0_irq_edge =
332 IPU6V6_REG_ISYS_CSI_TOP_CTRL0_IRQ_EDGE;
333 isys_ipdata.csi2.ctrl0_irq_clear =
334 IPU6V6_REG_ISYS_CSI_TOP_CTRL0_IRQ_CLEAR;
335 isys_ipdata.csi2.ctrl0_irq_mask =
336 IPU6V6_REG_ISYS_CSI_TOP_CTRL0_IRQ_MASK;
337 isys_ipdata.csi2.ctrl0_irq_enable =
338 IPU6V6_REG_ISYS_CSI_TOP_CTRL0_IRQ_ENABLE;
339 isys_ipdata.csi2.ctrl0_irq_lnp =
340 IPU6V6_REG_ISYS_CSI_TOP_CTRL0_IRQ_LEVEL_NOT_PULSE;
341 isys_ipdata.csi2.ctrl0_irq_status =
342 IPU6V6_REG_ISYS_CSI_TOP_CTRL0_IRQ_STATUS;
343 isys_ipdata.csi2.fw_access_port_ofs =
344 CSI_REG_HUB_FW_ACCESS_PORT_V6OFS;
345 isys_ipdata.ltr = IPU6EP_MTL_LTR_VALUE;
346 isys_ipdata.memopen_threshold = IPU6EP_MTL_MIN_MEMOPEN_TH;
349 if (is_ipu6se(hw_ver)) {
350 isys_ipdata.csi2.nports = IPU6SE_ISYS_CSI2_NPORTS;
351 isys_ipdata.csi2.irq_mask = IPU6SE_CSI_RX_ERROR_IRQ_MASK;
352 isys_ipdata.num_parallel_streams = IPU6SE_ISYS_NUM_STREAMS;
353 isys_ipdata.sram_gran_shift = IPU6SE_SRAM_GRANULARITY_SHIFT;
354 isys_ipdata.sram_gran_size = IPU6SE_SRAM_GRANULARITY_SIZE;
355 isys_ipdata.max_sram_size = IPU6SE_MAX_SRAM_SIZE;
356 isys_ipdata.sensor_type_start =
357 IPU6SE_FW_ISYS_SENSOR_TYPE_START;
358 isys_ipdata.sensor_type_end = IPU6SE_FW_ISYS_SENSOR_TYPE_END;
359 isys_ipdata.max_streams = IPU6SE_ISYS_NUM_STREAMS;
360 isys_ipdata.max_send_queues = IPU6SE_N_MAX_SEND_QUEUES;
361 isys_ipdata.max_sram_blocks = IPU6SE_NOF_SRAM_BLOCKS_MAX;
362 isys_ipdata.max_devq_size = IPU6SE_DEV_SEND_QUEUE_SIZE;
363 psys_ipdata.hw_variant.spc_offset = IPU6SE_PSYS_SPC_OFFSET;
367 static struct ipu6_bus_device *
368 ipu6_isys_init(struct pci_dev *pdev, struct device *parent,
369 struct ipu6_buttress_ctrl *ctrl, void __iomem *base,
370 const struct ipu6_isys_internal_pdata *ipdata)
372 struct device *dev = &pdev->dev;
373 struct ipu6_bus_device *isys_adev;
374 struct ipu6_isys_pdata *pdata;
377 ret = ipu_bridge_init(dev, ipu_bridge_parse_ssdb);
379 dev_err_probe(dev, ret, "IPU6 bridge init failed\n");
383 pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
385 return ERR_PTR(-ENOMEM);
388 pdata->ipdata = ipdata;
390 isys_adev = ipu6_bus_initialize_device(pdev, parent, pdata, ctrl,
392 if (IS_ERR(isys_adev)) {
393 dev_err_probe(dev, PTR_ERR(isys_adev),
394 "ipu6_bus_initialize_device isys failed\n");
396 return ERR_CAST(isys_adev);
399 isys_adev->mmu = ipu6_mmu_init(dev, base, ISYS_MMID,
400 &ipdata->hw_variant);
401 if (IS_ERR(isys_adev->mmu)) {
402 dev_err_probe(dev, PTR_ERR(isys_adev->mmu),
403 "ipu6_mmu_init(isys_adev->mmu) failed\n");
404 put_device(&isys_adev->auxdev.dev);
406 return ERR_CAST(isys_adev->mmu);
409 isys_adev->mmu->dev = &isys_adev->auxdev.dev;
411 ret = ipu6_bus_add_device(isys_adev);
420 static struct ipu6_bus_device *
421 ipu6_psys_init(struct pci_dev *pdev, struct device *parent,
422 struct ipu6_buttress_ctrl *ctrl, void __iomem *base,
423 const struct ipu6_psys_internal_pdata *ipdata)
425 struct ipu6_bus_device *psys_adev;
426 struct ipu6_psys_pdata *pdata;
429 pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
431 return ERR_PTR(-ENOMEM);
434 pdata->ipdata = ipdata;
436 psys_adev = ipu6_bus_initialize_device(pdev, parent, pdata, ctrl,
438 if (IS_ERR(psys_adev)) {
439 dev_err_probe(&pdev->dev, PTR_ERR(psys_adev),
440 "ipu6_bus_initialize_device psys failed\n");
442 return ERR_CAST(psys_adev);
445 psys_adev->mmu = ipu6_mmu_init(&pdev->dev, base, PSYS_MMID,
446 &ipdata->hw_variant);
447 if (IS_ERR(psys_adev->mmu)) {
448 dev_err_probe(&pdev->dev, PTR_ERR(psys_adev->mmu),
449 "ipu6_mmu_init(psys_adev->mmu) failed\n");
450 put_device(&psys_adev->auxdev.dev);
452 return ERR_CAST(psys_adev->mmu);
455 psys_adev->mmu->dev = &psys_adev->auxdev.dev;
457 ret = ipu6_bus_add_device(psys_adev);
466 static int ipu6_pci_config_setup(struct pci_dev *dev, u8 hw_ver)
470 /* disable IPU6 PCI ATS on mtl ES2 */
471 if (is_ipu6ep_mtl(hw_ver) && boot_cpu_data.x86_stepping == 0x2 &&
472 pci_ats_supported(dev))
473 pci_disable_ats(dev);
475 /* No PCI msi capability for IPU6EP */
476 if (is_ipu6ep(hw_ver) || is_ipu6ep_mtl(hw_ver)) {
477 /* likely do nothing as msi not enabled by default */
478 pci_disable_msi(dev);
482 ret = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_MSI);
484 return dev_err_probe(&dev->dev, ret, "Request msi failed");
489 static void ipu6_configure_vc_mechanism(struct ipu6_device *isp)
491 u32 val = readl(isp->base + BUTTRESS_REG_BTRS_CTRL);
493 if (IPU6_BTRS_ARB_STALL_MODE_VC0 == IPU6_BTRS_ARB_MODE_TYPE_STALL)
494 val |= BUTTRESS_REG_BTRS_CTRL_STALL_MODE_VC0;
496 val &= ~BUTTRESS_REG_BTRS_CTRL_STALL_MODE_VC0;
498 if (IPU6_BTRS_ARB_STALL_MODE_VC1 == IPU6_BTRS_ARB_MODE_TYPE_STALL)
499 val |= BUTTRESS_REG_BTRS_CTRL_STALL_MODE_VC1;
501 val &= ~BUTTRESS_REG_BTRS_CTRL_STALL_MODE_VC1;
503 writel(val, isp->base + BUTTRESS_REG_BTRS_CTRL);
506 static int ipu6_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
508 struct ipu6_buttress_ctrl *isys_ctrl = NULL, *psys_ctrl = NULL;
509 struct device *dev = &pdev->dev;
510 void __iomem *isys_base = NULL;
511 void __iomem *psys_base = NULL;
512 struct ipu6_device *isp;
514 u32 val, version, sku_id;
517 isp = devm_kzalloc(dev, sizeof(*isp), GFP_KERNEL);
522 INIT_LIST_HEAD(&isp->devices);
524 ret = pcim_enable_device(pdev);
526 return dev_err_probe(dev, ret, "Enable PCI device failed\n");
528 phys = pci_resource_start(pdev, IPU6_PCI_BAR);
529 dev_dbg(dev, "IPU6 PCI bar[%u] = %pa\n", IPU6_PCI_BAR, &phys);
531 ret = pcim_iomap_regions(pdev, 1 << IPU6_PCI_BAR, pci_name(pdev));
533 return dev_err_probe(dev, ret, "Failed to I/O mem remapping\n");
535 isp->base = pcim_iomap_table(pdev)[IPU6_PCI_BAR];
536 pci_set_drvdata(pdev, isp);
537 pci_set_master(pdev);
539 isp->cpd_metadata_cmpnt_size = sizeof(struct ipu6_cpd_metadata_cmpnt);
540 switch (id->device) {
541 case PCI_DEVICE_ID_INTEL_IPU6:
542 isp->hw_ver = IPU6_VER_6;
543 isp->cpd_fw_name = IPU6_FIRMWARE_NAME;
545 case PCI_DEVICE_ID_INTEL_IPU6SE:
546 isp->hw_ver = IPU6_VER_6SE;
547 isp->cpd_fw_name = IPU6SE_FIRMWARE_NAME;
548 isp->cpd_metadata_cmpnt_size =
549 sizeof(struct ipu6se_cpd_metadata_cmpnt);
551 case PCI_DEVICE_ID_INTEL_IPU6EP_ADLP:
552 case PCI_DEVICE_ID_INTEL_IPU6EP_RPLP:
553 isp->hw_ver = IPU6_VER_6EP;
554 isp->cpd_fw_name = IPU6EP_FIRMWARE_NAME;
556 case PCI_DEVICE_ID_INTEL_IPU6EP_ADLN:
557 isp->hw_ver = IPU6_VER_6EP;
558 isp->cpd_fw_name = IPU6EPADLN_FIRMWARE_NAME;
560 case PCI_DEVICE_ID_INTEL_IPU6EP_MTL:
561 isp->hw_ver = IPU6_VER_6EP_MTL;
562 isp->cpd_fw_name = IPU6EPMTL_FIRMWARE_NAME;
565 return dev_err_probe(dev, -ENODEV,
566 "Unsupported IPU6 device %x\n",
570 ipu6_internal_pdata_init(isp);
572 isys_base = isp->base + isys_ipdata.hw_variant.offset;
573 psys_base = isp->base + psys_ipdata.hw_variant.offset;
575 ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(39));
577 return dev_err_probe(dev, ret, "Failed to set DMA mask\n");
579 ret = dma_set_max_seg_size(dev, UINT_MAX);
581 return dev_err_probe(dev, ret, "Failed to set max_seg_size\n");
583 ret = ipu6_pci_config_setup(pdev, isp->hw_ver);
587 ret = ipu6_buttress_init(isp);
591 ret = request_firmware(&isp->cpd_fw, isp->cpd_fw_name, dev);
593 dev_err_probe(&isp->pdev->dev, ret,
594 "Requesting signed firmware %s failed\n",
599 ret = ipu6_cpd_validate_cpd_file(isp, isp->cpd_fw->data,
602 dev_err_probe(&isp->pdev->dev, ret,
603 "Failed to validate cpd\n");
604 goto out_ipu6_bus_del_devices;
607 isys_ctrl = devm_kmemdup(dev, &isys_buttress_ctrl,
608 sizeof(isys_buttress_ctrl), GFP_KERNEL);
611 goto out_ipu6_bus_del_devices;
614 isp->isys = ipu6_isys_init(pdev, dev, isys_ctrl, isys_base,
616 if (IS_ERR(isp->isys)) {
617 ret = PTR_ERR(isp->isys);
618 goto out_ipu6_bus_del_devices;
621 psys_ctrl = devm_kmemdup(dev, &psys_buttress_ctrl,
622 sizeof(psys_buttress_ctrl), GFP_KERNEL);
625 goto out_ipu6_bus_del_devices;
628 isp->psys = ipu6_psys_init(pdev, &isp->isys->auxdev.dev, psys_ctrl,
629 psys_base, &psys_ipdata);
630 if (IS_ERR(isp->psys)) {
631 ret = PTR_ERR(isp->psys);
632 goto out_ipu6_bus_del_devices;
635 ret = pm_runtime_resume_and_get(&isp->psys->auxdev.dev);
637 goto out_ipu6_bus_del_devices;
639 ret = ipu6_mmu_hw_init(isp->psys->mmu);
641 dev_err_probe(&isp->pdev->dev, ret,
642 "Failed to set MMU hardware\n");
643 goto out_ipu6_bus_del_devices;
646 ret = ipu6_buttress_map_fw_image(isp->psys, isp->cpd_fw,
649 dev_err_probe(&isp->pdev->dev, ret, "failed to map fw image\n");
650 goto out_ipu6_bus_del_devices;
653 ret = ipu6_cpd_create_pkg_dir(isp->psys, isp->cpd_fw->data);
655 dev_err_probe(&isp->pdev->dev, ret,
656 "failed to create pkg dir\n");
657 goto out_ipu6_bus_del_devices;
660 ret = devm_request_threaded_irq(dev, pdev->irq, ipu6_buttress_isr,
661 ipu6_buttress_isr_threaded,
662 IRQF_SHARED, IPU6_NAME, isp);
664 dev_err_probe(dev, ret, "Requesting irq failed\n");
665 goto out_ipu6_bus_del_devices;
668 ret = ipu6_buttress_authenticate(isp);
670 dev_err_probe(&isp->pdev->dev, ret,
671 "FW authentication failed\n");
675 ipu6_mmu_hw_cleanup(isp->psys->mmu);
676 pm_runtime_put(&isp->psys->auxdev.dev);
678 /* Configure the arbitration mechanisms for VC requests */
679 ipu6_configure_vc_mechanism(isp);
681 val = readl(isp->base + BUTTRESS_REG_SKU);
682 sku_id = FIELD_GET(GENMASK(6, 4), val);
683 version = FIELD_GET(GENMASK(3, 0), val);
684 dev_info(dev, "IPU%u-v%u[%x] hardware version %d\n", version, sku_id,
685 pdev->device, isp->hw_ver);
687 pm_runtime_put_noidle(dev);
688 pm_runtime_allow(dev);
690 isp->bus_ready_to_probe = true;
695 devm_free_irq(dev, pdev->irq, isp);
696 out_ipu6_bus_del_devices:
698 ipu6_cpd_free_pkg_dir(isp->psys);
699 ipu6_buttress_unmap_fw_image(isp->psys, &isp->psys->fw_sgt);
701 if (!IS_ERR_OR_NULL(isp->psys) && !IS_ERR_OR_NULL(isp->psys->mmu))
702 ipu6_mmu_cleanup(isp->psys->mmu);
703 if (!IS_ERR_OR_NULL(isp->isys) && !IS_ERR_OR_NULL(isp->isys->mmu))
704 ipu6_mmu_cleanup(isp->isys->mmu);
705 ipu6_bus_del_devices(pdev);
706 release_firmware(isp->cpd_fw);
708 ipu6_buttress_exit(isp);
713 static void ipu6_pci_remove(struct pci_dev *pdev)
715 struct ipu6_device *isp = pci_get_drvdata(pdev);
716 struct ipu6_mmu *isys_mmu = isp->isys->mmu;
717 struct ipu6_mmu *psys_mmu = isp->psys->mmu;
719 devm_free_irq(&pdev->dev, pdev->irq, isp);
720 ipu6_cpd_free_pkg_dir(isp->psys);
722 ipu6_buttress_unmap_fw_image(isp->psys, &isp->psys->fw_sgt);
723 ipu6_buttress_exit(isp);
725 ipu6_bus_del_devices(pdev);
727 pm_runtime_forbid(&pdev->dev);
728 pm_runtime_get_noresume(&pdev->dev);
730 release_firmware(isp->cpd_fw);
732 ipu6_mmu_cleanup(psys_mmu);
733 ipu6_mmu_cleanup(isys_mmu);
736 static void ipu6_pci_reset_prepare(struct pci_dev *pdev)
738 struct ipu6_device *isp = pci_get_drvdata(pdev);
740 pm_runtime_forbid(&isp->pdev->dev);
743 static void ipu6_pci_reset_done(struct pci_dev *pdev)
745 struct ipu6_device *isp = pci_get_drvdata(pdev);
747 ipu6_buttress_restore(isp);
748 if (isp->secure_mode)
749 ipu6_buttress_reset_authentication(isp);
751 isp->need_ipc_reset = true;
752 pm_runtime_allow(&isp->pdev->dev);
756 * PCI base driver code requires driver to provide these to enable
757 * PCI device level PM state transitions (D0<->D3)
759 static int ipu6_suspend(struct device *dev)
764 static int ipu6_resume(struct device *dev)
766 struct pci_dev *pdev = to_pci_dev(dev);
767 struct ipu6_device *isp = pci_get_drvdata(pdev);
768 struct ipu6_buttress *b = &isp->buttress;
771 /* Configure the arbitration mechanisms for VC requests */
772 ipu6_configure_vc_mechanism(isp);
774 isp->secure_mode = ipu6_buttress_get_secure_mode(isp);
775 dev_info(dev, "IPU6 in %s mode\n",
776 isp->secure_mode ? "secure" : "non-secure");
778 ipu6_buttress_restore(isp);
780 ret = ipu6_buttress_ipc_reset(isp, &b->cse);
782 dev_err(&isp->pdev->dev, "IPC reset protocol failed!\n");
784 ret = pm_runtime_resume_and_get(&isp->psys->auxdev.dev);
786 dev_err(&isp->psys->auxdev.dev, "Failed to get runtime PM\n");
790 ret = ipu6_buttress_authenticate(isp);
792 dev_err(&isp->pdev->dev, "FW authentication failed(%d)\n", ret);
794 pm_runtime_put(&isp->psys->auxdev.dev);
799 static int ipu6_runtime_resume(struct device *dev)
801 struct pci_dev *pdev = to_pci_dev(dev);
802 struct ipu6_device *isp = pci_get_drvdata(pdev);
805 ipu6_configure_vc_mechanism(isp);
806 ipu6_buttress_restore(isp);
808 if (isp->need_ipc_reset) {
809 struct ipu6_buttress *b = &isp->buttress;
811 isp->need_ipc_reset = false;
812 ret = ipu6_buttress_ipc_reset(isp, &b->cse);
814 dev_err(&isp->pdev->dev, "IPC reset protocol failed\n");
820 static const struct dev_pm_ops ipu6_pm_ops = {
821 SYSTEM_SLEEP_PM_OPS(&ipu6_suspend, &ipu6_resume)
822 RUNTIME_PM_OPS(&ipu6_suspend, &ipu6_runtime_resume, NULL)
825 MODULE_DEVICE_TABLE(pci, ipu6_pci_tbl);
827 static const struct pci_error_handlers pci_err_handlers = {
828 .reset_prepare = ipu6_pci_reset_prepare,
829 .reset_done = ipu6_pci_reset_done,
832 static struct pci_driver ipu6_pci_driver = {
834 .id_table = ipu6_pci_tbl,
835 .probe = ipu6_pci_probe,
836 .remove = ipu6_pci_remove,
838 .pm = pm_ptr(&ipu6_pm_ops),
840 .err_handler = &pci_err_handlers,
843 module_pci_driver(ipu6_pci_driver);
845 MODULE_IMPORT_NS(INTEL_IPU_BRIDGE);
846 MODULE_AUTHOR("Sakari Ailus <sakari.ailus@linux.intel.com>");
847 MODULE_AUTHOR("Tianshu Qiu <tian.shu.qiu@intel.com>");
848 MODULE_AUTHOR("Bingbu Cao <bingbu.cao@intel.com>");
849 MODULE_AUTHOR("Qingwu Zhang <qingwu.zhang@intel.com>");
850 MODULE_AUTHOR("Yunliang Ding <yunliang.ding@intel.com>");
851 MODULE_AUTHOR("Hongju Wang <hongju.wang@intel.com>");
852 MODULE_LICENSE("GPL");
853 MODULE_DESCRIPTION("Intel IPU6 PCI driver");