From: Bingbu Cao <bingbu.cao@linux.intel.com>
To: phasta@kernel.org, bingbu.cao@intel.com,
linux-media@vger.kernel.org, sakari.ailus@linux.intel.com,
hdegoede@redhat.com
Cc: hans@hansg.org, stanislaw.gruszka@linux.intel.com,
jerry.w.hu@intel.com, tian.shu.qiu@intel.com,
daxing.li@intel.com, hao.yao@intel.com
Subject: Re: [RFC PATCH 2/7] media: ipu7: add Intel IPU7 PCI device driver
Date: Tue, 25 Feb 2025 17:39:24 +0800 [thread overview]
Message-ID: <83c9c01e-8025-5d19-1750-5cb68dd4de83@linux.intel.com> (raw)
In-Reply-To: <873cbddbc43638c2564ce27e373c25fe2f3dc2e9.camel@mailbox.org>
On 2/24/25 10:38 PM, Philipp Stanner wrote:
> Hi,
>
> see below
>
> On Fri, 2025-02-21 at 15:52 +0800, bingbu.cao@intel.com wrote:
>> From: Bingbu Cao <bingbu.cao@intel.com>
>>
>> Intel Image Processing Unit 7th Gen includes input and processing
>> systems
>> and the hardware presents itself as a single PCI device in system
>> same
>> as IPU6.
>>
>> The IPU7 PCI device driver basically does PCI configurations, basic
>> hardware configuration by its buttress interfaces, loads the
>> firmware binary, register the auxiliary device which serve for the
>> ISYS
>> device driver.
>>
>> Signed-off-by: Bingbu Cao <bingbu.cao@intel.com>
>> ---
>> drivers/media/pci/intel/ipu7/ipu7-bus.c | 158 +
>> drivers/media/pci/intel/ipu7/ipu7-bus.h | 69 +
>> .../media/pci/intel/ipu7/ipu7-buttress-regs.h | 465 +++
>> drivers/media/pci/intel/ipu7/ipu7-buttress.c | 1187 +++++++
>> drivers/media/pci/intel/ipu7/ipu7-buttress.h | 84 +
>> .../media/pci/intel/ipu7/ipu7-platform-regs.h | 146 +
>> drivers/media/pci/intel/ipu7/ipu7.c | 2791
>> +++++++++++++++++
>> drivers/media/pci/intel/ipu7/ipu7.h | 244 ++
>> 8 files changed, 5144 insertions(+)
>> create mode 100644 drivers/media/pci/intel/ipu7/ipu7-bus.c
>> create mode 100644 drivers/media/pci/intel/ipu7/ipu7-bus.h
>> create mode 100644 drivers/media/pci/intel/ipu7/ipu7-buttress-regs.h
>> create mode 100644 drivers/media/pci/intel/ipu7/ipu7-buttress.c
>> create mode 100644 drivers/media/pci/intel/ipu7/ipu7-buttress.h
>> create mode 100644 drivers/media/pci/intel/ipu7/ipu7-platform-regs.h
>> create mode 100644 drivers/media/pci/intel/ipu7/ipu7.c
>> create mode 100644 drivers/media/pci/intel/ipu7/ipu7.h
>>
>> diff --git a/drivers/media/pci/intel/ipu7/ipu7-bus.c
>> b/drivers/media/pci/intel/ipu7/ipu7-bus.c
>> new file mode 100644
>> index 000000000000..6c2825afaca7
>> --- /dev/null
>> +++ b/drivers/media/pci/intel/ipu7/ipu7-bus.c
>> @@ -0,0 +1,158 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Copyright (C) 2013 - 2024 Intel Corporation
>> + */
>> +
>> +#include <linux/auxiliary_bus.h>
>> +#include <linux/device.h>
>> +#include <linux/dma-mapping.h>
>> +#include <linux/err.h>
>> +#include <linux/list.h>
>> +#include <linux/mutex.h>
>> +#include <linux/pci.h>
>> +#include <linux/pm_domain.h>
>> +#include <linux/pm_runtime.h>
>> +#include <linux/slab.h>
>> +
>> +#include "ipu7.h"
>> +#include "ipu7-bus.h"
>> +#include "ipu7-boot.h"
>> +#include "ipu7-dma.h"
>> +
>> +static int bus_pm_runtime_suspend(struct device *dev)
>> +{
>> + struct ipu7_bus_device *adev = to_ipu7_bus_device(dev);
>> + int ret;
>> +
>> + ret = pm_generic_runtime_suspend(dev);
>> + if (ret)
>> + return ret;
>> +
>> + ret = ipu_buttress_powerdown(dev, adev->ctrl);
>> + if (!ret)
>> + return 0;
>> +
>> + dev_err(dev, "power down failed!\n");
>> +
>> + /* Powering down failed, attempt to resume device now */
>> + ret = pm_generic_runtime_resume(dev);
>> + if (!ret)
>> + return -EBUSY;
>> +
>> + return -EIO;
>> +}
>> +
>> +static int bus_pm_runtime_resume(struct device *dev)
>> +{
>> + struct ipu7_bus_device *adev = to_ipu7_bus_device(dev);
>> + int ret;
>> +
>> + ret = ipu_buttress_powerup(dev, adev->ctrl);
>> + if (ret)
>> + return ret;
>> +
>> + ret = pm_generic_runtime_resume(dev);
>> + if (ret)
>> + goto out_err;
>> +
>> + return 0;
>> +
>> +out_err:
>> + ipu_buttress_powerdown(dev, adev->ctrl);
>> +
>> + return -EBUSY;
>> +}
>> +
>> +static struct dev_pm_domain ipu7_bus_pm_domain = {
>> + .ops = {
>> + .runtime_suspend = bus_pm_runtime_suspend,
>> + .runtime_resume = bus_pm_runtime_resume,
>> + },
>> +};
>> +
>> +static DEFINE_MUTEX(ipu7_bus_mutex);
>> +static void ipu7_bus_release(struct device *dev)
>> +{
>> + struct ipu7_bus_device *adev = to_ipu7_bus_device(dev);
>> +
>> + kfree(adev->pdata);
>> + kfree(adev);
>> +}
>> +
>> +struct ipu7_bus_device *
>> +ipu7_bus_initialize_device(struct pci_dev *pdev, struct device
>> *parent,
>> + void *pdata, const struct
>> ipu_buttress_ctrl *ctrl,
>> + char *name)
>> +{
>> + struct auxiliary_device *auxdev;
>> + struct ipu7_bus_device *adev;
>> + struct ipu7_device *isp = pci_get_drvdata(pdev);
>> + int ret;
>> +
>> + adev = kzalloc(sizeof(*adev), GFP_KERNEL);
>> + if (!adev)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + adev->isp = isp;
>> + adev->ctrl = ctrl;
>> + adev->pdata = pdata;
>> + auxdev = &adev->auxdev;
>> + auxdev->name = name;
>> + auxdev->id = (pci_domain_nr(pdev->bus) << 16) |
>> + PCI_DEVID(pdev->bus->number, pdev->devfn);
>> +
>> + auxdev->dev.parent = parent;
>> + auxdev->dev.release = ipu7_bus_release;
>> +
>> + ret = auxiliary_device_init(auxdev);
>> + if (ret < 0) {
>> + dev_err(&isp->pdev->dev, "auxiliary device init
>> failed (%d)\n",
>> + ret);
>> + kfree(adev);
>> + return ERR_PTR(ret);
>> + }
>> +
>> + dev_pm_domain_set(&auxdev->dev, &ipu7_bus_pm_domain);
>> +
>> + pm_runtime_forbid(&adev->auxdev.dev);
>> + pm_runtime_enable(&adev->auxdev.dev);
>> +
>> + return adev;
>> +}
>> +
>> +int ipu7_bus_add_device(struct ipu7_bus_device *adev)
>> +{
>> + struct auxiliary_device *auxdev = &adev->auxdev;
>> + int ret;
>> +
>> + ret = auxiliary_device_add(auxdev);
>> + if (ret) {
>> + auxiliary_device_uninit(auxdev);
>> + return ret;
>> + }
>> +
>> + mutex_lock(&ipu7_bus_mutex);
>> + list_add(&adev->list, &adev->isp->devices);
>> + mutex_unlock(&ipu7_bus_mutex);
>> +
>> + pm_runtime_allow(&auxdev->dev);
>> +
>> + return 0;
>> +}
>> +
>> +void ipu7_bus_del_devices(struct pci_dev *pdev)
>> +{
>> + struct ipu7_device *isp = pci_get_drvdata(pdev);
>> + struct ipu7_bus_device *adev, *save;
>> +
>> + mutex_lock(&ipu7_bus_mutex);
>> +
>> + list_for_each_entry_safe(adev, save, &isp->devices, list) {
>> + pm_runtime_disable(&adev->auxdev.dev);
>> + list_del(&adev->list);
>> + auxiliary_device_delete(&adev->auxdev);
>> + auxiliary_device_uninit(&adev->auxdev);
>> + }
>> +
>> + mutex_unlock(&ipu7_bus_mutex);
>> +}
>> diff --git a/drivers/media/pci/intel/ipu7/ipu7-bus.h
>> b/drivers/media/pci/intel/ipu7/ipu7-bus.h
>> new file mode 100644
>> index 000000000000..b180b332cf2a
>> --- /dev/null
>> +++ b/drivers/media/pci/intel/ipu7/ipu7-bus.h
>> @@ -0,0 +1,69 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +/*
>> + * Copyright (C) 2013 - 2024 Intel Corporation
>> + */
>> +
>> +#ifndef IPU7_BUS_H
>> +#define IPU7_BUS_H
>> +
>> +#include <linux/auxiliary_bus.h>
>> +#include <linux/container_of.h>
>> +#include <linux/device.h>
>> +#include <linux/irqreturn.h>
>> +#include <linux/list.h>
>> +#include <linux/scatterlist.h>
>> +#include <linux/types.h>
>> +
>> +#include "abi/ipu7_fw_boot_abi.h"
>> +
>> +#include "ipu7-syscom.h"
>> +
>> +struct pci_dev;
>> +struct ipu_buttress_ctrl;
>> +struct ipu7_mmu;
>> +struct ipu7_device;
>> +
>> +enum ipu7_subsys {
>> + IPU_IS = 0,
>> + IPU_PS = 1,
>> + IPU_SUBSYS_NUM = 2,
>> +};
>> +
>> +struct ipu7_bus_device {
>> + struct auxiliary_device auxdev;
>> + const struct auxiliary_driver *auxdrv;
>> + const struct ipu7_auxdrv_data *auxdrv_data;
>> + struct list_head list;
>> + enum ipu7_subsys subsys;
>> + void *pdata;
>> + struct ipu7_mmu *mmu;
>> + struct ipu7_device *isp;
>> + const struct ipu_buttress_ctrl *ctrl;
>> + u64 dma_mask;
>> + struct sg_table fw_sgt;
>> + u32 fw_entry;
>> + struct ipu7_syscom_context *syscom;
>> + struct ia_gofo_boot_config *boot_config;
>> + dma_addr_t boot_config_dma_addr;
>> + u32 boot_config_size;
>> +};
>> +
>> +struct ipu7_auxdrv_data {
>> + irqreturn_t (*isr)(struct ipu7_bus_device *adev);
>> + irqreturn_t (*isr_threaded)(struct ipu7_bus_device *adev);
>> + bool wake_isr_thread;
>> +};
>> +
>> +#define
>> to_ipu7_bus_device(_dev) \
>> + container_of(to_auxiliary_dev(_dev), struct ipu7_bus_device,
>> auxdev)
>> +#define
>> auxdev_to_adev(_auxdev) \
>> + container_of(_auxdev, struct ipu7_bus_device, auxdev)
>> +#define ipu7_bus_get_drvdata(adev) dev_get_drvdata(&(adev)-
>>> auxdev.dev)
>> +
>> +struct ipu7_bus_device *
>> +ipu7_bus_initialize_device(struct pci_dev *pdev, struct device
>> *parent,
>> + void *pdata, const struct
>> ipu_buttress_ctrl *ctrl,
>> + char *name);
>> +int ipu7_bus_add_device(struct ipu7_bus_device *adev);
>> +void ipu7_bus_del_devices(struct pci_dev *pdev);
>> +#endif
>> diff --git a/drivers/media/pci/intel/ipu7/ipu7-buttress-regs.h
>> b/drivers/media/pci/intel/ipu7/ipu7-buttress-regs.h
>> new file mode 100644
>> index 000000000000..fdf6148fb95c
>> --- /dev/null
>> +++ b/drivers/media/pci/intel/ipu7/ipu7-buttress-regs.h
>> @@ -0,0 +1,465 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +/*
>> + * Copyright (C) 2020 - 2024 Intel Corporation
>> + */
>> +
>> +#ifndef IPU7_BUTTRESS_REGS_H
>> +#define IPU7_BUTTRESS_REGS_H
>> +
>> +#define
>> BUTTRESS_REG_IRQ_STATUS 0x2000
>> +#define
>> BUTTRESS_REG_IRQ_STATUS_UNMASKED 0x2004
>> +#define
>> BUTTRESS_REG_IRQ_ENABLE 0x2008
>> +#define
>> BUTTRESS_REG_IRQ_CLEAR 0x200c
>> +#define
>> BUTTRESS_REG_IRQ_MASK 0x2010
>> +#define
>> BUTTRESS_REG_TSC_CMD 0x2014
>> +#define
>> BUTTRESS_REG_TSC_CTL 0x2018
>> +#define
>> BUTTRESS_REG_TSC_LO 0x201c
>> +#define
>> BUTTRESS_REG_TSC_HI 0x2020
>> +
>> +/* valid for PTL */
>> +#define
>> BUTTRESS_REG_PB_TIMESTAMP_LO 0x2030
>> +#define
>> BUTTRESS_REG_PB_TIMESTAMP_HI 0x2034
>> +#define
>> BUTTRESS_REG_PB_TIMESTAMP_VALID 0x2038
>> +
>> +#define
>> BUTTRESS_REG_PS_WORKPOINT_REQ 0x2100
>> +#define
>> BUTTRESS_REG_IS_WORKPOINT_REQ 0x2104
>> +#define
>> BUTTRESS_REG_PS_WORKPOINT_DOMAIN_REQ 0x2108
>> +#define
>> BUTTRESS_REG_PS_DOMAINS_STATUS 0x2110
>> +#define
>> BUTTRESS_REG_PWR_STATUS 0x2114
>> +#define
>> BUTTRESS_REG_PS_WORKPOINT_REQ_SHADOW 0x2120
>> +#define
>> BUTTRESS_REG_IS_WORKPOINT_REQ_SHADOW 0x2124
>> +#define
>> BUTTRESS_REG_PS_WORKPOINT_DOMAIN_REQ_SHADOW 0x2128
>> +#define
>> BUTTRESS_REG_ISPS_WORKPOINT_DOWNLOAD 0x212c
>> +#define
>> BUTTRESS_REG_PG_FLOW_OVERRIDE 0x2180
>> +#define
>> BUTTRESS_REG_GLOBAL_OVERRIDE_UNGATE_CTL 0x2184
>> +#define
>> BUTTRESS_REG_PWR_FSM_CTL 0x2188
>> +#define
>> BUTTRESS_REG_IDLE_WDT 0x218c
>> +#define
>> BUTTRESS_REG_PS_PWR_DOMAIN_EVENTQ_EN 0x2190
>> +#define
>> BUTTRESS_REG_PS_PWR_DOMAIN_EVENTQ_ADDR 0x2194
>> +#define
>> BUTTRESS_REG_PS_PWR_DOMAIN_EVENTQ_DATA 0x2198
>> +#define
>> BUTTRESS_REG_POWER_EN_DELAY 0x219c
>> +#define
>> IPU7_BUTTRESS_REG_LTR_CONTROL 0x21a0
>> +#define
>> IPU7_BUTTRESS_REG_NDE_CONTROL 0x21a4
>> +#define
>> IPU7_BUTTRESS_REG_INT_FRM_PUNIT 0x21a8
>> +#define
>> IPU8_BUTTRESS_REG_LTR_CONTROL 0x21a4
>> +#define
>> IPU8_BUTTRESS_REG_NDE_CONTROL 0x21a8
>> +#define
>> IPU8_BUTTRESS_REG_INT_FRM_PUNIT 0x21ac
>> +#define
>> BUTTRESS_REG_SLEEP_LEVEL_CFG 0x21b0
>> +#define
>> BUTTRESS_REG_SLEEP_LEVEL_STS 0x21b4
>> +#define
>> BUTTRESS_REG_DVFS_FSM_STATUS 0x21b8
>> +#define
>> BUTTRESS_REG_PS_PLL_ENABLE 0x21bc
>> +#define
>> BUTTRESS_REG_D2D_CTL 0x21d4
>> +#define
>> BUTTRESS_REG_IB_CLK_CTL 0x21d8
>> +#define
>> BUTTRESS_REG_IB_CRO_CLK_CTL 0x21dc
>> +#define
>> BUTTRESS_REG_FUNC_FUSES 0x21e0
>> +#define
>> BUTTRESS_REG_ISOCH_CTL 0x21e4
>> +#define
>> BUTTRESS_REG_WORKPOINT_CTL 0x21f0
>> +#define
>> BUTTRESS_REG_DRV_IS_UCX_CONTROL_STATUS 0x2200
>> +#define
>> BUTTRESS_REG_DRV_IS_UCX_START_ADDR 0x2204
>> +#define
>> BUTTRESS_REG_DRV_PS_UCX_CONTROL_STATUS 0x2208
>> +#define
>> BUTTRESS_REG_DRV_PS_UCX_START_ADDR 0x220c
>> +#define
>> BUTTRESS_REG_DRV_UCX_RESET_CFG 0x2210
>> +
>> +/* configured by CSE */
>> +#define
>> BUTTRESS_REG_CSE_IS_UCX_CONTROL_STATUS 0x2300
>> +#define
>> BUTTRESS_REG_CSE_IS_UCX_START_ADDR 0x2304
>> +#define
>> BUTTRESS_REG_CSE_PS_UCX_CONTROL_STATUS 0x2308
>> +#define
>> BUTTRESS_REG_CSE_PS_UCX_START_ADDR 0x230c
>> +
>> +#define
>> BUTTRESS_REG_CAMERA_MASK 0x2310
>> +#define
>> BUTTRESS_REG_FW_CTL 0x2314
>> +#define
>> BUTTRESS_REG_SECURITY_CTL 0x2318
>> +#define
>> BUTTRESS_REG_FUNCTIONAL_FW_SETUP 0x231c
>> +#define
>> BUTTRESS_REG_FW_BASE 0x2320
>> +#define
>> BUTTRESS_REG_FW_BASE_LIMIT 0x2324
>> +#define
>> BUTTRESS_REG_FW_SCRATCH_BASE 0x2328
>> +#define
>> BUTTRESS_REG_FW_SCRATCH_LIMIT 0x232c
>> +#define
>> BUTTRESS_REG_CSE_ACTION 0x2330
>> +
>> +/* configured by SW */
>> +#define
>> BUTTRESS_REG_FW_RESET_CTL 0x2334
>> +#define
>> BUTTRESS_REG_FW_SOURCE_SIZE 0x2338
>> +#define
>> BUTTRESS_REG_FW_SOURCE_BASE 0x233c
>> +
>> +#define
>> BUTTRESS_REG_IPU_SEC_CP_LSB 0x2400
>> +#define
>> BUTTRESS_REG_IPU_SEC_CP_MSB 0x2404
>> +#define
>> BUTTRESS_REG_IPU_SEC_WAC_LSB 0x2408
>> +#define
>> BUTTRESS_REG_IPU_SEC_WAC_MSB 0x240c
>> +#define
>> BUTTRESS_REG_IPU_SEC_RAC_LSB 0x2410
>> +#define
>> BUTTRESS_REG_IPU_SEC_RAC_MSB 0x2414
>> +#define
>> BUTTRESS_REG_IPU_DRV_CP_LSB 0x2418
>> +#define
>> BUTTRESS_REG_IPU_DRV_CP_MSB 0x241c
>> +#define
>> BUTTRESS_REG_IPU_DRV_WAC_LSB 0x2420
>> +#define
>> BUTTRESS_REG_IPU_DRV_WAC_MSB 0x2424
>> +#define
>> BUTTRESS_REG_IPU_DRV_RAC_LSB 0x2428
>> +#define
>> BUTTRESS_REG_IPU_DRV_RAC_MSB 0x242c
>> +#define
>> BUTTRESS_REG_IPU_FW_CP_LSB 0x2430
>> +#define
>> BUTTRESS_REG_IPU_FW_CP_MSB 0x2434
>> +#define
>> BUTTRESS_REG_IPU_FW_WAC_LSB 0x2438
>> +#define
>> BUTTRESS_REG_IPU_FW_WAC_MSB 0x243c
>> +#define
>> BUTTRESS_REG_IPU_FW_RAC_LSB 0x2440
>> +#define
>> BUTTRESS_REG_IPU_FW_RAC_MSB 0x2444
>> +#define
>> BUTTRESS_REG_IPU_BIOS_SEC_CP_LSB 0x2448
>> +#define
>> BUTTRESS_REG_IPU_BIOS_SEC_CP_MSB 0x244c
>> +#define
>> BUTTRESS_REG_IPU_BIOS_SEC_WAC_LSB 0x2450
>> +#define
>> BUTTRESS_REG_IPU_BIOS_SEC_WAC_MSB 0x2454
>> +#define
>> BUTTRESS_REG_IPU_BIOS_SEC_RAC_LSB 0x2458
>> +#define
>> BUTTRESS_REG_IPU_BIOS_SEC_RAC_MSB 0x245c
>> +#define
>> BUTTRESS_REG_IPU_DFD_CP_LSB 0x2460
>> +#define
>> BUTTRESS_REG_IPU_DFD_CP_MSB 0x2464
>> +#define
>> BUTTRESS_REG_IPU_DFD_WAC_LSB 0x2468
>> +#define
>> BUTTRESS_REG_IPU_DFD_WAC_MSB 0x246c
>> +#define
>> BUTTRESS_REG_IPU_DFD_RAC_LSB 0x2470
>> +#define
>> BUTTRESS_REG_IPU_DFD_RAC_MSB 0x2474
>> +#define
>> BUTTRESS_REG_CSE2IUDB0 0x2500
>> +#define
>> BUTTRESS_REG_CSE2IUDATA0 0x2504
>> +#define
>> BUTTRESS_REG_CSE2IUCSR 0x2508
>> +#define
>> BUTTRESS_REG_IU2CSEDB0 0x250c
>> +#define
>> BUTTRESS_REG_IU2CSEDATA0 0x2510
>> +#define
>> BUTTRESS_REG_IU2CSECSR 0x2514
>> +#define
>> BUTTRESS_REG_CSE2IUDB0_CR_SHADOW 0x2520
>> +#define
>> BUTTRESS_REG_CSE2IUDATA0_CR_SHADOW 0x2524
>> +#define
>> BUTTRESS_REG_CSE2IUCSR_CR_SHADOW 0x2528
>> +#define
>> BUTTRESS_REG_IU2CSEDB0_CR_SHADOW 0x252c
>> +#define
>> BUTTRESS_REG_DVFS_FSM_SURVIVABILITY 0x2900
>> +#define
>> BUTTRESS_REG_FLOWS_FSM_SURVIVABILITY 0x2904
>> +#define
>> BUTTRESS_REG_FABRICS_FSM_SURVIVABILITY 0x2908
>> +#define
>> BUTTRESS_REG_PS_SUB1_PM_FSM_SURVIVABILITY 0x290c
>> +#define
>> BUTTRESS_REG_PS_SUB0_PM_FSM_SURVIVABILITY 0x2910
>> +#define
>> BUTTRESS_REG_PS_PM_FSM_SURVIVABILITY 0x2914
>> +#define
>> BUTTRESS_REG_IS_PM_FSM_SURVIVABILITY 0x2918
>> +#define
>> BUTTRESS_REG_FLR_RST_FSM_SURVIVABILITY 0x291c
>> +#define
>> BUTTRESS_REG_FW_RST_FSM_SURVIVABILITY 0x2920
>> +#define
>> BUTTRESS_REG_RESETPREP_FSM_SURVIVABILITY 0x2924
>> +#define
>> BUTTRESS_REG_POWER_FSM_DOMAIN_STATUS 0x3000
>> +#define
>> BUTTRESS_REG_IDLEREQ_STATUS1 0x3004
>> +#define
>> BUTTRESS_REG_POWER_FSM_STATUS_IS_PS 0x3008
>> +#define
>> BUTTRESS_REG_POWER_ACK_B_STATUS 0x300c
>> +#define
>> BUTTRESS_REG_DOMAIN_RETENTION_CTL 0x3010
>> +#define
>> BUTTRESS_REG_CG_CTRL_BITS 0x3014
>> +#define
>> BUTTRESS_REG_IS_IFC_STATUS0 0x3018
>> +#define
>> BUTTRESS_REG_IS_IFC_STATUS1 0x301c
>> +#define
>> BUTTRESS_REG_PS_IFC_STATUS0 0x3020
>> +#define
>> BUTTRESS_REG_PS_IFC_STATUS1 0x3024
>> +#define
>> BUTTRESS_REG_BTRS_IFC_STATUS0 0x3028
>> +#define
>> BUTTRESS_REG_BTRS_IFC_STATUS1 0x302c
>> +#define
>> BUTTRESS_REG_IPU_SKU 0x3030
>> +#define
>> BUTTRESS_REG_PS_IDLEACK 0x3034
>> +#define
>> BUTTRESS_REG_IS_IDLEACK 0x3038
>> +#define
>> BUTTRESS_REG_SPARE_REGS_0 0x303c
>> +#define
>> BUTTRESS_REG_SPARE_REGS_1 0x3040
>> +#define
>> BUTTRESS_REG_SPARE_REGS_2 0x3044
>> +#define
>> BUTTRESS_REG_SPARE_REGS_3 0x3048
>> +#define
>> BUTTRESS_REG_IUNIT_ACV 0x304c
>> +#define
>> BUTTRESS_REG_CHICKEN_BITS 0x3050
>> +#define
>> BUTTRESS_REG_SBENDPOINT_CFG 0x3054
>> +#define
>> BUTTRESS_REG_ECC_ERR_LOG 0x3058
>> +#define
>> BUTTRESS_REG_POWER_FSM_STATUS 0x3070
>> +#define
>> BUTTRESS_REG_RESET_FSM_STATUS 0x3074
>> +#define
>> BUTTRESS_REG_IDLE_STATUS 0x3078
>> +#define
>> BUTTRESS_REG_IDLEACK_STATUS 0x307c
>> +#define
>> BUTTRESS_REG_IPU_DEBUG 0x3080
>> +
>> +#define
>> BUTTRESS_REG_FW_BOOT_PARAMS0 0x4000
>> +#define
>> BUTTRESS_REG_FW_BOOT_PARAMS1 0x4004
>> +#define
>> BUTTRESS_REG_FW_BOOT_PARAMS2 0x4008
>> +#define
>> BUTTRESS_REG_FW_BOOT_PARAMS3 0x400c
>> +#define
>> BUTTRESS_REG_FW_BOOT_PARAMS4 0x4010
>> +#define
>> BUTTRESS_REG_FW_BOOT_PARAMS5 0x4014
>> +#define
>> BUTTRESS_REG_FW_BOOT_PARAMS6 0x4018
>> +#define
>> BUTTRESS_REG_FW_BOOT_PARAMS7 0x401c
>> +#define
>> BUTTRESS_REG_FW_BOOT_PARAMS8 0x4020
>> +#define
>> BUTTRESS_REG_FW_BOOT_PARAMS9 0x4024
>> +#define
>> BUTTRESS_REG_FW_BOOT_PARAMS10 0x4028
>> +#define
>> BUTTRESS_REG_FW_BOOT_PARAMS11 0x402c
>> +#define
>> BUTTRESS_REG_FW_BOOT_PARAMS12 0x4030
>> +#define
>> BUTTRESS_REG_FW_BOOT_PARAMS13 0x4034
>> +#define
>> BUTTRESS_REG_FW_BOOT_PARAMS14 0x4038
>> +#define
>> BUTTRESS_REG_FW_BOOT_PARAMS15 0x403c
>> +
>> +#define BUTTRESS_FW_BOOT_PARAMS_ENTRY(i) \
>> + (BUTTRESS_REG_FW_BOOT_PARAMS0 + ((i) * 4U))
>> +#define BUTTRESS_REG_FW_GP(i) (0x4040 +
>> 0x4 * (i))
>> +#define BUTTRESS_REG_FPGA_SUPPORT(i) (0x40c0 +
>> 0x4 * (i))
>> +
>> +#define
>> BUTTRESS_REG_FW_GP8 0x4060
>> +#define
>> BUTTRESS_REG_FW_GP24 0x40a0
>> +
>> +#define
>> BUTTRESS_REG_GPIO_0_PADCFG_ADDR_CR 0x4100
>> +#define
>> BUTTRESS_REG_GPIO_1_PADCFG_ADDR_CR 0x4104
>> +#define
>> BUTTRESS_REG_GPIO_2_PADCFG_ADDR_CR 0x4108
>> +#define
>> BUTTRESS_REG_GPIO_3_PADCFG_ADDR_CR 0x410c
>> +#define
>> BUTTRESS_REG_GPIO_4_PADCFG_ADDR_CR 0x4110
>> +#define
>> BUTTRESS_REG_GPIO_5_PADCFG_ADDR_CR 0x4114
>> +#define
>> BUTTRESS_REG_GPIO_6_PADCFG_ADDR_CR 0x4118
>> +#define
>> BUTTRESS_REG_GPIO_7_PADCFG_ADDR_CR 0x411c
>> +#define
>> BUTTRESS_REG_GPIO_ENABLE 0x4140
>> +#define
>> BUTTRESS_REG_GPIO_VALUE_CR 0x4144
>> +
>> +#define
>> BUTTRESS_REG_IS_MEM_CORRECTABLE_ERROR_STATUS 0x5000
>> +#define
>> BUTTRESS_REG_IS_MEM_FATAL_ERROR_STATUS 0x5004
>> +#define
>> BUTTRESS_REG_IS_MEM_NON_FATAL_ERROR_STATUS 0x5008
>> +#define
>> BUTTRESS_REG_IS_MEM_CHECK_PASSED 0x500c
>> +#define
>> BUTTRESS_REG_IS_MEM_ERROR_INJECT 0x5010
>> +#define
>> BUTTRESS_REG_IS_MEM_ERROR_CLEAR 0x5014
>> +#define
>> BUTTRESS_REG_PS_MEM_CORRECTABLE_ERROR_STATUS 0x5040
>> +#define
>> BUTTRESS_REG_PS_MEM_FATAL_ERROR_STATUS 0x5044
>> +#define
>> BUTTRESS_REG_PS_MEM_NON_FATAL_ERROR_STATUS 0x5048
>> +#define
>> BUTTRESS_REG_PS_MEM_CHECK_PASSED 0x504c
>> +#define
>> BUTTRESS_REG_PS_MEM_ERROR_INJECT 0x5050
>> +#define
>> BUTTRESS_REG_PS_MEM_ERROR_CLEAR 0x5054
>> +
>> +#define BUTTRESS_REG_IS_AB_REGION_MIN_ADDRESS(i) (0x6000 +
>> 0x8 * (i))
>> +#define BUTTRESS_REG_IS_AB_REGION_MAX_ADDRESS(i) (0x6004 +
>> 0x8 * (i))
>> +#define
>> BUTTRESS_REG_IS_AB_VIOLATION_LOG0 0x6080
>> +#define
>> BUTTRESS_REG_IS_AB_VIOLATION_LOG1 0x6084
>> +#define BUTTRESS_REG_PS_AB_REGION_MIN_ADDRESS(i) (0x6100 +
>> 0x8 * (i))
>> +#define BUTTRESS_REG_PS_AB_REGION_MAX_ADDRESS0 (0x6104 +
>> 0x8 * (i))
>> +#define
>> BUTTRESS_REG_PS_AB_VIOLATION_LOG0 0x6180
>> +#define
>> BUTTRESS_REG_PS_AB_VIOLATION_LOG1 0x6184
>> +#define
>> BUTTRESS_REG_PS_DEBUG_AB_VIOLATION_LOG0 0x6200
>> +#define
>> BUTTRESS_REG_PS_DEBUG_AB_VIOLATION_LOG1 0x6204
>> +#define
>> BUTTRESS_REG_IS_DEBUG_AB_VIOLATION_LOG0 0x6208
>> +#define
>> BUTTRESS_REG_IS_DEBUG_AB_VIOLATION_LOG1 0x620c
>> +#define
>> BUTTRESS_REG_IB_DVP_AB_VIOLATION_LOG0 0x6210
>> +#define
>> BUTTRESS_REG_IB_DVP_AB_VIOLATION_LOG1 0x6214
>> +#define
>> BUTTRESS_REG_IB_ATB2DTF_AB_VIOLATION_LOG0 0x6218
>> +#define
>> BUTTRESS_REG_IB_ATB2DTF_AB_VIOLATION_LOG1 0x621c
>> +#define
>> BUTTRESS_REG_AB_ENABLE 0x6220
>> +#define
>> BUTTRESS_REG_AB_DEFAULT_ACCESS 0x6230
>> +
>> +/* Indicates CSE has received an IPU driver IPC transaction */
>> +#define BUTTRESS_IRQ_IPC_EXEC_DONE_BY_CSE BIT(0)
>> +/* Indicates an IPC transaction from CSE has arrived */
>> +#define BUTTRESS_IRQ_IPC_FROM_CSE_IS_WAITING BIT(1)
>> +/* Indicates a CSR update from CSE has arrived */
>> +#define BUTTRESS_IRQ_CSE_CSR_SET BIT(2)
>> +/* Indicates an interrupt set by Punit (not in use at this time) */
>> +#define BUTTRESS_IRQ_PUNIT_2_IUNIT_IRQ BIT(3)
>> +/* Indicates an SAI violation was detected on access to IB registers
>> */
>> +#define BUTTRESS_IRQ_SAI_VIOLATION BIT(4)
>> +/* Indicates a transaction to IS was not able to pass the access
>> blocker */
>> +#define BUTTRESS_IRQ_IS_AB_VIOLATION BIT(5)
>> +/* Indicates a transaction to PS was not able to pass the access
>> blocker */
>> +#define BUTTRESS_IRQ_PS_AB_VIOLATION BIT(6)
>> +/* Indicates an error response was detected by the IB config NoC */
>> +#define
>> BUTTRESS_IRQ_IB_CFG_NOC_ERR_IRQ BIT(7)
>> +/* Indicates an error response was detected by the IB data NoC */
>> +#define BUTTRESS_IRQ_IB_DATA_NOC_ERR_IRQ BIT(8)
>> +/* Transaction to DVP regs was not able to pass the access blocker
>> */
>> +#define BUTTRESS_IRQ_IB_DVP_AB_VIOLATION BIT(9)
>> +/* Transaction to ATB2DTF regs was not able to pass the access
>> blocker */
>> +#define BUTTRESS_IRQ_ATB2DTF_AB_VIOLATION BIT(10)
>> +/* Transaction to IS debug regs was not able to pass the access
>> blocker */
>> +#define BUTTRESS_IRQ_IS_DEBUG_AB_VIOLATION BIT(11)
>> +/* Transaction to PS debug regs was not able to pass the access
>> blocker */
>> +#define BUTTRESS_IRQ_PS_DEBUG_AB_VIOLATION BIT(12)
>> +/* Indicates timeout occurred waiting for a response from a target
>> */
>> +#define BUTTRESS_IRQ_IB_CFG_NOC_TIMEOUT_IRQ BIT(13)
>> +/* Set when any correctable ECC error input wire to buttress is set
>> */
>> +#define BUTTRESS_IRQ_ECC_CORRECTABLE BIT(14)
>> +/* Any noncorrectable-nonfatal ECC error input wire to buttress is
>> set */
>> +#define BUTTRESS_IRQ_ECC_NONCORRECTABLE_NONFATAL BIT(15)
>> +/* Set when any noncorrectable-fatal ECC error input wire to
>> buttress is set */
>> +#define BUTTRESS_IRQ_ECC_NONCORRECTABLE_FATAL BIT(16)
>> +/* Set when timeout occurred waiting for a response from a target */
>> +#define BUTTRESS_IRQ_IS_CFG_NOC_TIMEOUT_IRQ BIT(17)
>> +#define BUTTRESS_IRQ_PS_CFG_NOC_TIMEOUT_IRQ BIT(18)
>> +#define BUTTRESS_IRQ_LB_CFG_NOC_TIMEOUT_IRQ BIT(19)
>> +/* IS FW double exception event */
>> +#define
>> BUTTRESS_IRQ_IS_UC_PFATAL_ERROR BIT(26)
>> +/* PS FW double exception event */
>> +#define
>> BUTTRESS_IRQ_PS_UC_PFATAL_ERROR BIT(27)
>> +/* IS FW watchdog event */
>> +#define BUTTRESS_IRQ_IS_WATCHDOG BIT(28)
>> +/* PS FW watchdog event */
>> +#define BUTTRESS_IRQ_PS_WATCHDOG BIT(29)
>> +/* IS IRC irq out */
>> +#define BUTTRESS_IRQ_IS_IRQ BIT(30)
>> +/* PS IRC irq out */
>> +#define BUTTRESS_IRQ_PS_IRQ BIT(31)
>> +
>> +/* buttress irq */
>> +enum {
>> + BUTTRESS_PWR_STATUS_HH_STATE_IDLE,
>> + BUTTRESS_PWR_STATUS_HH_STATE_IN_PRGS,
>> + BUTTRESS_PWR_STATUS_HH_STATE_DONE,
>> + BUTTRESS_PWR_STATUS_HH_STATE_ERR,
>> +};
>> +
>> +#define BUTTRESS_TSC_CMD_START_TSC_SYNC BIT(0)
>> +#define BUTTRESS_PWR_STATUS_HH_STATUS_SHIFT 11
>> +#define BUTTRESS_PWR_STATUS_HH_STATUS_MASK (0x3 << 11)
>> +#define BUTTRESS_TSW_WA_SOFT_RESET BIT(8)
>> +/* new for PTL */
>> +#define BUTTRESS_SEL_PB_TIMESTAMP BIT(9)
>> +#define BUTTRESS_IRQS (BUTTRESS_IRQ_IS_IRQ | \
>> + BUTTRESS_IRQ_PS_IRQ | \
>> +
>> BUTTRESS_IRQ_IPC_FROM_CSE_IS_WAITING | \
>> + BUTTRESS_IRQ_CSE_CSR_SET | \
>> + BUTTRESS_IRQ_IPC_EXEC_DONE_BY_CSE |
>> \
>> + BUTTRESS_IRQ_PUNIT_2_IUNIT_IRQ)
>> +
>> +/* Iunit to CSE regs */
>> +#define BUTTRESS_IU2CSEDB0_BUSY BIT(31)
>> +#define BUTTRESS_IU2CSEDB0_SHORT_FORMAT_SHIFT 27
>> +#define BUTTRESS_IU2CSEDB0_CLIENT_ID_SHIFT 10
>> +#define BUTTRESS_IU2CSEDB0_IPC_CLIENT_ID_VAL 2
>> +
>> +#define BUTTRESS_IU2CSEDATA0_IPC_BOOT_LOAD 1
>> +#define BUTTRESS_IU2CSEDATA0_IPC_AUTH_RUN 2
>> +#define BUTTRESS_IU2CSEDATA0_IPC_AUTH_REPLACE 3
>> +#define BUTTRESS_IU2CSEDATA0_IPC_UPDATE_SECURE_TOUCH 16
>> +
>> +#define
>> BUTTRESS_CSE2IUDATA0_IPC_BOOT_LOAD_DONE BIT(0)
>> +#define
>> BUTTRESS_CSE2IUDATA0_IPC_AUTH_RUN_DONE BIT(1)
>> +#define
>> BUTTRESS_CSE2IUDATA0_IPC_AUTH_REPLACE_DONE BIT(2)
>> +#define
>> BUTTRESS_CSE2IUDATA0_IPC_UPDATE_SECURE_TOUCH_DONE BIT(4)
>> +
>> +#define
>> BUTTRESS_IU2CSECSR_IPC_PEER_COMP_ACTIONS_RST_PHASE1 BIT(0)
>> +#define
>> BUTTRESS_IU2CSECSR_IPC_PEER_COMP_ACTIONS_RST_PHASE2 BIT(1)
>> +#define
>> BUTTRESS_IU2CSECSR_IPC_PEER_QUERIED_IP_COMP_ACTIONS_RST_PHASE BIT(
>> 2)
>> +#define
>> BUTTRESS_IU2CSECSR_IPC_PEER_ASSERTED_REG_VALID_REQ BIT(3)
>> +#define
>> BUTTRESS_IU2CSECSR_IPC_PEER_ACKED_REG_VALID BIT(4)
>> +#define
>> BUTTRESS_IU2CSECSR_IPC_PEER_DEASSERTED_REG_VALID_REQ BIT(5)
>> +
>> +/* 0x20 == NACK, 0xf == unknown command */
>> +#define BUTTRESS_CSE2IUDATA0_IPC_NACK 0xf20
>> +#define BUTTRESS_CSE2IUDATA0_IPC_NACK_MASK 0xffff
>> +
>> +/* IS/PS freq control */
>> +#define BUTTRESS_IS_FREQ_CTL_RATIO_MASK 0xff
>> +#define BUTTRESS_PS_FREQ_CTL_RATIO_MASK 0xff
>> +#define BUTTRESS_IS_FREQ_CTL_CDYN_MASK 0xff
>> +#define BUTTRESS_PS_FREQ_CTL_CDYN_MASK 0xff
>> +
>> +#define IPU7_IS_FREQ_MAX 450
>> +#define IPU7_IS_FREQ_MIN 50
>> +#define IPU7_PS_FREQ_MAX 750
>> +#define BUTTRESS_PS_FREQ_RATIO_STEP 25U
>> +/* valid for IPU8 */
>> +#define BUTTRESS_IS_FREQ_RATIO_STEP 25U
>> +
>> +/* IS: 400mhz, PS: 500mhz */
>> +#define IPU7_IS_FREQ_CTL_DEFAULT_RATIO 0x1b
>> +#define IPU7_PS_FREQ_CTL_DEFAULT_RATIO 0x14
>> +/* IS: 400mhz, PS: 400mhz */
>> +#define IPU8_IS_FREQ_CTL_DEFAULT_RATIO 0x10
>> +#define IPU8_PS_FREQ_CTL_DEFAULT_RATIO 0x10
>> +
>> +#define IPU_FREQ_CTL_CDYN 0x80
>> +#define IPU_FREQ_CTL_RATIO_SHIFT 0x0
>> +#define IPU_FREQ_CTL_CDYN_SHIFT 0x8
>> +
>> +/* buttree power status */
>> +#define IPU_BUTTRESS_PWR_STATE_IS_PWR_SHIFT 0
>> +#define IPU_BUTTRESS_PWR_STATE_IS_PWR_MASK \
>> + (0x3 << IPU_BUTTRESS_PWR_STATE_IS_PWR_SHIFT)
>> +
>> +#define IPU_BUTTRESS_PWR_STATE_PS_PWR_SHIFT 4
>> +#define IPU_BUTTRESS_PWR_STATE_PS_PWR_MASK \
>> + (0x3 << IPU_BUTTRESS_PWR_STATE_PS_PWR_SHIFT)
>> +
>> +#define IPU_BUTTRESS_PWR_STATE_DN_DONE 0x0
>> +#define IPU_BUTTRESS_PWR_STATE_UP_PROCESS 0x1
>> +#define IPU_BUTTRESS_PWR_STATE_DN_PROCESS 0x2
>> +#define IPU_BUTTRESS_PWR_STATE_UP_DONE 0x3
>> +
>> +#define BUTTRESS_PWR_STATE_IS_PWR_SHIFT 3
>> +#define BUTTRESS_PWR_STATE_IS_PWR_MASK (0x3 << 3)
>> +
>> +#define BUTTRESS_PWR_STATE_PS_PWR_SHIFT 6
>> +#define BUTTRESS_PWR_STATE_PS_PWR_MASK (0x3 << 6)
>> +
>> +#define PS_FSM_CG BIT(3)
>> +
>> +#define BUTTRESS_OVERRIDE_IS_CLK BIT(1)
>> +#define BUTTRESS_OVERRIDE_PS_CLK BIT(2)
>> +/* ps_pll only valid for ipu8 */
>> +#define BUTTRESS_OWN_ACK_PS_PLL BIT(8)
>> +#define BUTTRESS_OWN_ACK_IS_CLK BIT(9)
>> +#define BUTTRESS_OWN_ACK_PS_CLK BIT(10)
>> +
>> +/* FW reset ctrl */
>> +#define BUTTRESS_FW_RESET_CTL_START BIT(0)
>> +#define BUTTRESS_FW_RESET_CTL_DONE BIT(1)
>> +
>> +/* security */
>> +#define BUTTRESS_SECURITY_CTL_FW_SECURE_MODE BIT(16)
>> +#define BUTTRESS_SECURITY_CTL_FW_SETUP_MASK GENMASK(4,
>> 0)
>> +
>> +#define BUTTRESS_SECURITY_CTL_FW_SETUP_DONE BIT(0)
>> +#define
>> BUTTRESS_SECURITY_CTL_AUTH_DONE BIT(1)
>> +#define BUTTRESS_SECURITY_CTL_AUTH_FAILED BIT(3)
>> +
>> +/* D2D */
>> +#define BUTTRESS_D2D_PWR_EN BIT(0)
>> +#define BUTTRESS_D2D_PWR_ACK BIT(4)
>> +
>> +/* NDE */
>> +#define NDE_VAL_MASK GENMASK(9, 0)
>> +#define NDE_SCALE_MASK GENMASK(12, 10)
>> +#define NDE_VALID_MASK BIT(13)
>> +#define NDE_RESVEC_MASK GENMASK(19,
>> 16)
>> +#define NDE_IN_VBLANK_DIS_MASK BIT(31)
>> +
>> +#define BUTTRESS_NDE_VAL_ACTIVE 48
>> +#define BUTTRESS_NDE_SCALE_ACTIVE 2
>> +#define BUTTRESS_NDE_VALID_ACTIVE 1
>> +
>> +#define BUTTRESS_NDE_VAL_DEFAULT 1023
>> +#define BUTTRESS_NDE_SCALE_DEFAULT 2
>> +#define BUTTRESS_NDE_VALID_DEFAULT 0
>> +
>> +/* IS and PS UCX control */
>> +#define UCX_CTL_RESET BIT(0)
>> +#define UCX_CTL_RUN BIT(1)
>> +#define UCX_CTL_WAKEUP BIT(2)
>> +#define UCX_CTL_SPARE GENMASK(7, 3)
>> +#define UCX_STS_PWR GENMASK(17, 16)
>> +#define UCX_STS_SLEEPING BIT(18)
>> +
>> +/* offset from PHY base */
>> +#define PHY_CSI_CFG 0xc0
>> +#define PHY_CSI_RCOMP_CONTROL 0xc8
>> +#define PHY_CSI_BSCAN_EXCLUDE 0xd8
>> +
>> +#define PHY_CPHY_DLL_OVRD(x) (0x100 + 0x100 * (x))
>> +#define PHY_DPHY_DLL_OVRD(x) (0x14c + 0x100 * (x))
>> +#define PHY_CPHY_RX_CONTROL1(x) (0x110 + 0x100 *
>> (x))
>> +#define PHY_CPHY_RX_CONTROL2(x) (0x114 + 0x100 *
>> (x))
>> +#define PHY_DPHY_CFG(x) (0x148 + 0x100 *
>> (x))
>> +#define PHY_BB_AFE_CONFIG(x) (0x174 + 0x100 * (x))
>> +
>> +/* PB registers */
>> +#define INTERRUPT_STATUS 0x0
>> +#define BTRS_LOCAL_INTERRUPT_MASK 0x4
>> +#define GLOBAL_INTERRUPT_MASK 0x8
>> +#define HM_ATS 0xc
>> +#define ATS_ERROR_LOG1 0x10
>> +#define ATS_ERROR_LOG2 0x14
>> +#define ATS_ERROR_CLEAR 0x18
>> +#define CFI_0_ERROR_LOG 0x1c
>> +#define CFI_0_ERROR_CLEAR 0x20
>> +#define HASH_CONFIG 0x2c
>> +#define TLBID_HASH_ENABLE_31_0 0x30
>> +#define TLBID_HASH_ENABLE_63_32 0x34
>> +#define TLBID_HASH_ENABLE_95_64 0x38
>> +#define TLBID_HASH_ENABLE_127_96 0x3c
>> +#define CFI_1_ERROR_LOGGING 0x40
>> +#define CFI_1_ERROR_CLEAR 0x44
>> +#define IMR_ERROR_LOGGING_LOW 0x48
>> +#define IMR_ERROR_LOGGING_HIGH 0x4c
>> +#define IMR_ERROR_CLEAR 0x50
>> +#define PORT_ARBITRATION_WEIGHTS 0x54
>> +#define IMR_ERROR_LOGGING_CFI_1_LOW 0x58
>> +#define IMR_ERROR_LOGGING_CFI_1_HIGH 0x5c
>> +#define IMR_ERROR_CLEAR_CFI_1 0x60
>> +#define BAR2_MISC_CONFIG 0x64
>> +#define RSP_ID_CONFIG_AXI2CFI_0 0x68
>> +#define RSP_ID_CONFIG_AXI2CFI_1 0x6c
>> +#define PB_DRIVER_PCODE_MAILBOX_STATUS 0x70
>> +#define PB_DRIVER_PCODE_MAILBOX_INTERFACE 0x74
>> +#define PORT_ARBITRATION_WEIGHTS_ATS 0x78
>> +
>> +#endif /* IPU7_BUTTRESS_REGS_H */
>> diff --git a/drivers/media/pci/intel/ipu7/ipu7-buttress.c
>> b/drivers/media/pci/intel/ipu7/ipu7-buttress.c
>> new file mode 100644
>> index 000000000000..4b488f834b1a
>> --- /dev/null
>> +++ b/drivers/media/pci/intel/ipu7/ipu7-buttress.c
>> @@ -0,0 +1,1187 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Copyright (C) 2013 - 2024 Intel Corporation
>> + */
>> +
>> +#include <asm/cpu_device_id.h>
>> +#include <linux/bitfield.h>
>> +#include <linux/bits.h>
>> +#include <linux/completion.h>
>> +#include <linux/device.h>
>> +#include <linux/dma-mapping.h>
>> +#include <linux/firmware.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/iopoll.h>
>> +#include <linux/math64.h>
>> +#include <linux/mm.h>
>> +#include <linux/mutex.h>
>> +#include <linux/module.h>
>> +#include <linux/pci.h>
>> +#include <linux/pm_runtime.h>
>> +#include <linux/scatterlist.h>
>> +#include <linux/types.h>
>> +
>> +#include "ipu7.h"
>> +#include "ipu7-bus.h"
>> +#include "ipu7-buttress.h"
>> +#include "ipu7-buttress-regs.h"
>> +
>> +#define BOOTLOADER_STATUS_OFFSET BUTTRESS_REG_FW_BOOT_PARAMS7
>> +
>> +#define BOOTLOADER_MAGIC_KEY 0xb00710ad
>> +
>> +#define ENTRY BUTTRESS_IU2CSECSR_IPC_PEER_COMP_ACTIONS_RST_PHASE1
>> +#define EXIT BUTTRESS_IU2CSECSR_IPC_PEER_COMP_ACTIONS_RST_PHASE2
>> +#define
>> QUERY BUTTRESS_IU2CSECSR_IPC_PEER_QUERIED_IP_COMP_ACTIONS_RST_PHASE
>> +
>> +#define BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX 10
>> +
>> +#define BUTTRESS_POWER_TIMEOUT_US (200 *
>> USEC_PER_MSEC)
>> +
>> +#define BUTTRESS_CSE_BOOTLOAD_TIMEOUT_US (5 * USEC_PER_SEC)
>> +#define BUTTRESS_CSE_AUTHENTICATE_TIMEOUT_US (10 * USEC_PER_SEC)
>> +#define BUTTRESS_CSE_FWRESET_TIMEOUT_US (100 *
>> USEC_PER_MSEC)
>> +
>> +#define BUTTRESS_IPC_TX_TIMEOUT_MS MSEC_PER_SEC
>> +#define BUTTRESS_IPC_RX_TIMEOUT_MS MSEC_PER_SEC
>> +#define BUTTRESS_IPC_VALIDITY_TIMEOUT_US (1 * USEC_PER_SEC)
>> +#define BUTTRESS_TSC_SYNC_TIMEOUT_US (5 * USEC_PER_MSEC)
>> +
>> +#define BUTTRESS_IPC_RESET_RETRY 2000
>> +#define BUTTRESS_CSE_IPC_RESET_RETRY 4
>> +#define BUTTRESS_IPC_CMD_SEND_RETRY 1
>> +
>> +static const u32 ipu7_adev_irq_mask[2] = {
>> + BUTTRESS_IRQ_IS_IRQ,
>> + BUTTRESS_IRQ_PS_IRQ
>> +};
>> +
>> +int ipu_buttress_ipc_reset(struct ipu7_device *isp,
>> + struct ipu_buttress_ipc *ipc)
>> +{
>> + unsigned int retries = BUTTRESS_IPC_RESET_RETRY;
>> + struct ipu_buttress *b = &isp->buttress;
>> + struct device *dev = &isp->pdev->dev;
>> + u32 val = 0, csr_in_clr;
>> +
>> + if (!isp->secure_mode) {
>> + dev_dbg(dev, "Skip IPC reset for non-secure
>> mode\n");
>> + return 0;
>> + }
>> +
>> + mutex_lock(&b->ipc_mutex);
>> +
>> + /* Clear-by-1 CSR (all bits), corresponding internal states.
>> */
>> + val = readl(isp->base + ipc->csr_in);
>> + writel(val, isp->base + ipc->csr_in);
>> +
>> + /* Set peer CSR bit IPC_PEER_COMP_ACTIONS_RST_PHASE1 */
>> + writel(ENTRY, isp->base + ipc->csr_out);
>> + /*
>> + * Clear-by-1 all CSR bits EXCEPT following
>> + * bits:
>> + * A. IPC_PEER_COMP_ACTIONS_RST_PHASE1.
>> + * B. IPC_PEER_COMP_ACTIONS_RST_PHASE2.
>> + * C. Possibly custom bits, depending on
>> + * their role.
>> + */
>> + csr_in_clr =
>> BUTTRESS_IU2CSECSR_IPC_PEER_DEASSERTED_REG_VALID_REQ |
>> + BUTTRESS_IU2CSECSR_IPC_PEER_ACKED_REG_VALID |
>> + BUTTRESS_IU2CSECSR_IPC_PEER_ASSERTED_REG_VALID_REQ |
>> QUERY;
>> +
>> + do {
>> + usleep_range(400, 500);
>> + val = readl(isp->base + ipc->csr_in);
>> + switch (val) {
>> + case ENTRY | EXIT:
>> + case ENTRY | EXIT | QUERY:
>> + /*
>> + * 1) Clear-by-1 CSR bits
>> + * (IPC_PEER_COMP_ACTIONS_RST_PHASE1,
>> + * IPC_PEER_COMP_ACTIONS_RST_PHASE2).
>> + * 2) Set peer CSR bit
>> + *
>> IPC_PEER_QUERIED_IP_COMP_ACTIONS_RST_PHASE.
>> + */
>> + writel(ENTRY | EXIT, isp->base + ipc-
>>> csr_in);
>> + writel(QUERY, isp->base + ipc->csr_out);
>> + break;
>> + case ENTRY:
>> + case ENTRY | QUERY:
>> + /*
>> + * 1) Clear-by-1 CSR bits
>> + * (IPC_PEER_COMP_ACTIONS_RST_PHASE1,
>> + *
>> IPC_PEER_QUERIED_IP_COMP_ACTIONS_RST_PHASE).
>> + * 2) Set peer CSR bit
>> + * IPC_PEER_COMP_ACTIONS_RST_PHASE1.
>> + */
>> + writel(ENTRY | QUERY, isp->base + ipc-
>>> csr_in);
>> + writel(ENTRY, isp->base + ipc->csr_out);
>> + break;
>> + case EXIT:
>> + case EXIT | QUERY:
>> + /*
>> + * Clear-by-1 CSR bit
>> + * IPC_PEER_COMP_ACTIONS_RST_PHASE2.
>> + * 1) Clear incoming doorbell.
>> + * 2) Clear-by-1 all CSR bits EXCEPT
>> following
>> + * bits:
>> + * A. IPC_PEER_COMP_ACTIONS_RST_PHASE1.
>> + * B. IPC_PEER_COMP_ACTIONS_RST_PHASE2.
>> + * C. Possibly custom bits, depending on
>> + * their role.
>> + * 3) Set peer CSR bit
>> + * IPC_PEER_COMP_ACTIONS_RST_PHASE2.
>> + */
>> + writel(EXIT, isp->base + ipc->csr_in);
>> + writel(0, isp->base + ipc->db0_in);
>> + writel(csr_in_clr, isp->base + ipc->csr_in);
>> + writel(EXIT, isp->base + ipc->csr_out);
>> +
>> + /*
>> + * Read csr_in again to make sure if
>> RST_PHASE2 is done.
>> + * If csr_in is QUERY, it should be handled
>> again.
>> + */
>> + usleep_range(200, 300);
>> + val = readl(isp->base + ipc->csr_in);
>> + if (val & QUERY) {
>> + dev_dbg(dev,
>> + "RST_PHASE2 retry csr_in =
>> %x\n", val);
>> + break;
>> + }
>> + mutex_unlock(&b->ipc_mutex);
>> + return 0;
>> + case QUERY:
>> + /*
>> + * 1) Clear-by-1 CSR bit
>> + *
>> IPC_PEER_QUERIED_IP_COMP_ACTIONS_RST_PHASE.
>> + * 2) Set peer CSR bit
>> + * IPC_PEER_COMP_ACTIONS_RST_PHASE1
>> + */
>> + writel(QUERY, isp->base + ipc->csr_in);
>> + writel(ENTRY, isp->base + ipc->csr_out);
>> + break;
>> + default:
>> + dev_dbg_ratelimited(dev, "Unexpected CSR
>> 0x%x\n", val);
>> + break;
>> + }
>> + } while (retries--);
>> +
>> + mutex_unlock(&b->ipc_mutex);
>> + dev_err(dev, "Timed out while waiting for CSE\n");
>> +
>> + return -ETIMEDOUT;
>> +}
>> +
>> +static void ipu_buttress_ipc_validity_close(struct ipu7_device *isp,
>> + struct ipu_buttress_ipc
>> *ipc)
>> +{
>> + writel(BUTTRESS_IU2CSECSR_IPC_PEER_DEASSERTED_REG_VALID_REQ,
>> + isp->base + ipc->csr_out);
>> +}
>> +
>> +static int
>> +ipu_buttress_ipc_validity_open(struct ipu7_device *isp,
>> + struct ipu_buttress_ipc *ipc)
>> +{
>> + unsigned int mask =
>> BUTTRESS_IU2CSECSR_IPC_PEER_ACKED_REG_VALID;
>> + void __iomem *addr;
>> + int ret;
>> + u32 val;
>> +
>> + writel(BUTTRESS_IU2CSECSR_IPC_PEER_ASSERTED_REG_VALID_REQ,
>> + isp->base + ipc->csr_out);
>> +
>> + addr = isp->base + ipc->csr_in;
>> + ret = readl_poll_timeout(addr, val, val & mask, 200,
>> + BUTTRESS_IPC_VALIDITY_TIMEOUT_US);
>> + if (ret) {
>> + dev_err(&isp->pdev->dev, "CSE validity timeout
>> 0x%x\n", val);
>> + ipu_buttress_ipc_validity_close(isp, ipc);
>> + }
>> +
>> + return ret;
>> +}
>> +
>> +static void ipu_buttress_ipc_recv(struct ipu7_device *isp,
>> + struct ipu_buttress_ipc *ipc, u32
>> *ipc_msg)
>> +{
>> + if (ipc_msg)
>> + *ipc_msg = readl(isp->base + ipc->data0_in);
>> + writel(0, isp->base + ipc->db0_in);
>> +}
>> +
>> +static int ipu_buttress_ipc_send_bulk(struct ipu7_device *isp,
>> + struct
>> ipu7_ipc_buttress_bulk_msg *msgs,
>> + u32 size)
>> +{
>> + unsigned long tx_timeout_jiffies, rx_timeout_jiffies;
>> + unsigned int i, retry = BUTTRESS_IPC_CMD_SEND_RETRY;
>> + struct ipu_buttress *b = &isp->buttress;
>> + struct ipu_buttress_ipc *ipc = &b->cse;
>> + struct device *dev = &isp->pdev->dev;
>> + int tout;
>> + u32 val;
>> + int ret;
>> +
>> + mutex_lock(&b->ipc_mutex);
>> +
>> + ret = ipu_buttress_ipc_validity_open(isp, ipc);
>> + if (ret) {
>> + dev_err(dev, "IPC validity open failed\n");
>> + goto out;
>> + }
>> +
>> + tx_timeout_jiffies =
>> msecs_to_jiffies(BUTTRESS_IPC_TX_TIMEOUT_MS);
>> + rx_timeout_jiffies =
>> msecs_to_jiffies(BUTTRESS_IPC_RX_TIMEOUT_MS);
>> +
>> + for (i = 0; i < size; i++) {
>> + reinit_completion(&ipc->send_complete);
>> + if (msgs[i].require_resp)
>> + reinit_completion(&ipc->recv_complete);
>> +
>> + dev_dbg(dev, "bulk IPC command: 0x%x\n",
>> msgs[i].cmd);
>> + writel(msgs[i].cmd, isp->base + ipc->data0_out);
>> + val = BUTTRESS_IU2CSEDB0_BUSY | msgs[i].cmd_size;
>> + writel(val, isp->base + ipc->db0_out);
>> +
>> + tout = wait_for_completion_timeout(&ipc-
>>> send_complete,
>> +
>> tx_timeout_jiffies);
>> + if (!tout) {
>> + dev_err(dev, "send IPC response timeout\n");
>> + if (!retry--) {
>> + ret = -ETIMEDOUT;
>> + goto out;
>> + }
>> +
>> + /* Try again if CSE is not responding on
>> first try */
>> + writel(0, isp->base + ipc->db0_out);
>> + i--;
>> + continue;
>> + }
>> +
>> + retry = BUTTRESS_IPC_CMD_SEND_RETRY;
>> +
>> + if (!msgs[i].require_resp)
>> + continue;
>> +
>> + tout = wait_for_completion_timeout(&ipc-
>>> recv_complete,
>> +
>> rx_timeout_jiffies);
>> + if (!tout) {
>> + dev_err(dev, "recv IPC response timeout\n");
>> + ret = -ETIMEDOUT;
>> + goto out;
>> + }
>> +
>> + if (ipc->nack_mask &&
>> + (ipc->recv_data & ipc->nack_mask) == ipc->nack)
>> {
>> + dev_err(dev, "IPC NACK for cmd 0x%x\n",
>> msgs[i].cmd);
>> + ret = -EIO;
>> + goto out;
>> + }
>> +
>> + if (ipc->recv_data != msgs[i].expected_resp) {
>> + dev_err(dev,
>> + "expected resp: 0x%x, IPC response:
>> 0x%x\n",
>> + msgs[i].expected_resp, ipc-
>>> recv_data);
>> + ret = -EIO;
>> + goto out;
>> + }
>> + }
>> +
>> + dev_dbg(dev, "bulk IPC commands done\n");
>> +
>> +out:
>> + ipu_buttress_ipc_validity_close(isp, ipc);
>> + mutex_unlock(&b->ipc_mutex);
>> +
>> + return ret;
>> +}
>> +
>> +static int ipu_buttress_ipc_send(struct ipu7_device *isp,
>> + u32 ipc_msg, u32 size, bool
>> require_resp,
>> + u32 expected_resp)
>> +{
>> + struct ipu7_ipc_buttress_bulk_msg msg = {
>> + .cmd = ipc_msg,
>> + .cmd_size = size,
>> + .require_resp = require_resp,
>> + .expected_resp = expected_resp,
>> + };
>> +
>> + return ipu_buttress_ipc_send_bulk(isp, &msg, 1);
>> +}
>> +
>> +static irqreturn_t ipu_buttress_call_isr(struct ipu7_bus_device
>> *adev)
>> +{
>> + irqreturn_t ret = IRQ_WAKE_THREAD;
>> +
>> + if (!adev || !adev->auxdrv || !adev->auxdrv_data)
>> + return IRQ_NONE;
>> +
>> + if (adev->auxdrv_data->isr)
>> + ret = adev->auxdrv_data->isr(adev);
>> +
>> + if (ret == IRQ_WAKE_THREAD && !adev->auxdrv_data-
>>> isr_threaded)
>> + ret = IRQ_NONE;
>> +
>> + return ret;
>> +}
>> +
>> +irqreturn_t ipu_buttress_isr(int irq, void *isp_ptr)
>> +{
>> + struct ipu7_device *isp = isp_ptr;
>> + struct ipu7_bus_device *adev[] = { isp->isys, isp->psys };
>> + struct ipu_buttress *b = &isp->buttress;
>> + struct device *dev = &isp->pdev->dev;
>> + irqreturn_t ret = IRQ_NONE;
>> + u32 pb_irq, pb_local_irq;
>> + u32 disable_irqs = 0;
>> + u32 irq_status;
>> + unsigned int i;
>> +
>> + pm_runtime_get_noresume(dev);
>> +
>> + pb_irq = readl(isp->pb_base + INTERRUPT_STATUS);
>> + writel(pb_irq, isp->pb_base + INTERRUPT_STATUS);
>> +
>> + /* check btrs ATS, CFI and IMR errors, BIT(0) is unused for
>> IPU */
>> + pb_local_irq = readl(isp->pb_base +
>> BTRS_LOCAL_INTERRUPT_MASK);
>> + if (pb_local_irq & ~BIT(0)) {
>> + dev_warn(dev, "PB interrupt status 0x%x local
>> 0x%x\n", pb_irq,
>> + pb_local_irq);
>> + dev_warn(dev, "Details: %x %x %x %x %x %x %x %x\n",
>> + readl(isp->pb_base + ATS_ERROR_LOG1),
>> + readl(isp->pb_base + ATS_ERROR_LOG2),
>> + readl(isp->pb_base + CFI_0_ERROR_LOG),
>> + readl(isp->pb_base + CFI_1_ERROR_LOGGING),
>> + readl(isp->pb_base +
>> IMR_ERROR_LOGGING_LOW),
>> + readl(isp->pb_base +
>> IMR_ERROR_LOGGING_HIGH),
>> + readl(isp->pb_base +
>> IMR_ERROR_LOGGING_CFI_1_LOW),
>> + readl(isp->pb_base +
>> IMR_ERROR_LOGGING_CFI_1_HIGH));
>> + }
>> +
>> + irq_status = readl(isp->base + BUTTRESS_REG_IRQ_STATUS);
>> + if (!irq_status) {
>> + pm_runtime_put_noidle(dev);
>> + return IRQ_NONE;
>> + }
>> +
>> + do {
>> + writel(irq_status, isp->base +
>> BUTTRESS_REG_IRQ_CLEAR);
>> +
>> + for (i = 0; i < ARRAY_SIZE(ipu7_adev_irq_mask); i++)
>> {
>> + irqreturn_t r =
>> ipu_buttress_call_isr(adev[i]);
>> +
>> + if (!(irq_status & ipu7_adev_irq_mask[i]))
>> + continue;
>> +
>> + if (r == IRQ_WAKE_THREAD) {
>> + ret = IRQ_WAKE_THREAD;
>> + disable_irqs |=
>> ipu7_adev_irq_mask[i];
>> + } else if (ret == IRQ_NONE && r ==
>> IRQ_HANDLED) {
>> + ret = IRQ_HANDLED;
>> + }
>> + }
>> +
>> + if (irq_status & (BUTTRESS_IRQS |
>> BUTTRESS_IRQ_SAI_VIOLATION) &&
>> + ret == IRQ_NONE)
>> + ret = IRQ_HANDLED;
>> +
>> + if (irq_status &
>> BUTTRESS_IRQ_IPC_FROM_CSE_IS_WAITING) {
>> + dev_dbg(dev,
>> "BUTTRESS_IRQ_IPC_FROM_CSE_IS_WAITING\n");
>> + ipu_buttress_ipc_recv(isp, &b->cse, &b-
>>> cse.recv_data);
>> + complete(&b->cse.recv_complete);
>> + }
>> +
>> + if (irq_status & BUTTRESS_IRQ_CSE_CSR_SET)
>> + dev_dbg(dev, "BUTTRESS_IRQ_CSE_CSR_SET\n");
>> +
>> + if (irq_status & BUTTRESS_IRQ_IPC_EXEC_DONE_BY_CSE)
>> {
>> + dev_dbg(dev,
>> "BUTTRESS_IRQ_IPC_EXEC_DONE_BY_CSE\n");
>> + complete(&b->cse.send_complete);
>> + }
>> +
>> + if (irq_status & BUTTRESS_IRQ_PUNIT_2_IUNIT_IRQ)
>> + dev_dbg(dev,
>> "BUTTRESS_IRQ_PUNIT_2_IUNIT_IRQ\n");
>> +
>> + if (irq_status & BUTTRESS_IRQ_SAI_VIOLATION &&
>> + ipu_buttress_get_secure_mode(isp))
>> + dev_err(dev,
>> "BUTTRESS_IRQ_SAI_VIOLATION\n");
>> +
>> + irq_status = readl(isp->base +
>> BUTTRESS_REG_IRQ_STATUS);
>> + } while (irq_status);
>> +
>> + if (disable_irqs)
>> + writel(BUTTRESS_IRQS & ~disable_irqs,
>> + isp->base + BUTTRESS_REG_IRQ_ENABLE);
>> +
>> + pm_runtime_put(dev);
>> +
>> + return ret;
>> +}
>> +
>> +irqreturn_t ipu_buttress_isr_threaded(int irq, void *isp_ptr)
>> +{
>> + struct ipu7_device *isp = isp_ptr;
>> + struct ipu7_bus_device *adev[] = { isp->isys, isp->psys };
>> + const struct ipu7_auxdrv_data *drv_data = NULL;
>> + irqreturn_t ret = IRQ_NONE;
>> + unsigned int i;
>> +
>> + for (i = 0; i < ARRAY_SIZE(ipu7_adev_irq_mask) && adev[i];
>> i++) {
>> + drv_data = adev[i]->auxdrv_data;
>> + if (!drv_data)
>> + continue;
>> +
>> + if (drv_data->wake_isr_thread &&
>> + drv_data->isr_threaded(adev[i]) == IRQ_HANDLED)
>> + ret = IRQ_HANDLED;
>> + }
>> +
>> + writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_IRQ_ENABLE);
>> +
>> + return ret;
>> +}
>> +
>> +static int isys_d2d_power(struct device *dev, bool on)
>> +{
>> + struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp;
>> + int ret = 0;
>> + u32 val;
>> +
>> + dev_dbg(dev, "power %s isys d2d.\n", on ? "UP" : "DOWN");
>> + val = readl(isp->base + BUTTRESS_REG_D2D_CTL);
>> + if (!(val & BUTTRESS_D2D_PWR_ACK) ^ on) {
>> + dev_info(dev, "d2d already in %s state.\n",
>> + on ? "UP" : "DOWN");
>> + return 0;
>> + }
>> +
>> + val = on ? val | BUTTRESS_D2D_PWR_EN : val &
>> (~BUTTRESS_D2D_PWR_EN);
>> + writel(val, isp->base + BUTTRESS_REG_D2D_CTL);
>> + ret = readl_poll_timeout(isp->base + BUTTRESS_REG_D2D_CTL,
>> + val, (!(val & BUTTRESS_D2D_PWR_ACK)
>> ^ on),
>> + 100, BUTTRESS_POWER_TIMEOUT_US);
>> + if (ret)
>> + dev_err(dev, "power %s d2d timeout. status: 0x%x\n",
>> + on ? "UP" : "DOWN", val);
>> +
>> + return ret;
>> +}
>> +
>> +static void isys_nde_control(struct device *dev, bool on)
>> +{
>> + struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp;
>> + u32 val, value, scale, valid, resvec;
>> + u32 nde_reg;
>> +
>> + if (on) {
>> + value = BUTTRESS_NDE_VAL_ACTIVE;
>> + scale = BUTTRESS_NDE_SCALE_ACTIVE;
>> + valid = BUTTRESS_NDE_VALID_ACTIVE;
>> + } else {
>> + value = BUTTRESS_NDE_VAL_DEFAULT;
>> + scale = BUTTRESS_NDE_SCALE_DEFAULT;
>> + valid = BUTTRESS_NDE_VALID_DEFAULT;
>> + }
>> +
>> + /* only set the fabrics resource ownership for ipu8 */
>> + nde_reg = is_ipu8(isp->hw_ver) ?
>> IPU8_BUTTRESS_REG_NDE_CONTROL :
>> + IPU7_BUTTRESS_REG_NDE_CONTROL;
>> + resvec = is_ipu8(isp->hw_ver) ? 0x2 : 0xe;
>> + val = FIELD_PREP(NDE_VAL_MASK, value) |
>> + FIELD_PREP(NDE_SCALE_MASK, scale) |
>> + FIELD_PREP(NDE_VALID_MASK, valid) |
>> + FIELD_PREP(NDE_RESVEC_MASK, resvec);
>> +
>> + writel(val, isp->base + nde_reg);
>> +}
>> +
>> +static int ipu7_buttress_powerup(struct device *dev,
>> + const struct ipu_buttress_ctrl
>> *ctrl)
>> +{
>> + struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp;
>> + u32 val, exp_sts;
>> + int ret = 0;
>> +
>> + if (!ctrl)
>> + return 0;
>> +
>> + mutex_lock(&isp->buttress.power_mutex);
>> +
>> + exp_sts = ctrl->pwr_sts_on << ctrl->pwr_sts_shift;
>> + if (ctrl->subsys_id == IPU_IS) {
>> + ret = isys_d2d_power(dev, true);
>> + if (ret)
>> + goto out_power;
>> + isys_nde_control(dev, true);
>> + }
>> +
>> + /* request clock resource ownership */
>> + val = readl(isp->base + BUTTRESS_REG_SLEEP_LEVEL_CFG);
>> + val |= ctrl->ovrd_clk;
>> + writel(val, isp->base + BUTTRESS_REG_SLEEP_LEVEL_CFG);
>> + ret = readl_poll_timeout(isp->base +
>> BUTTRESS_REG_SLEEP_LEVEL_STS,
>> + val, (val & ctrl->own_clk_ack),
>> + 100, BUTTRESS_POWER_TIMEOUT_US);
>> + if (ret)
>> + dev_warn(dev, "request clk ownership timeout. status
>> 0x%x\n",
>> + val);
>> +
>> + val = ctrl->ratio << ctrl->ratio_shift | ctrl->cdyn << ctrl-
>>> cdyn_shift;
>> +
>> + dev_dbg(dev, "set 0x%x to %s_WORKPOINT_REQ.\n", val,
>> + ctrl->subsys_id == IPU_IS ? "IS" : "PS");
>> + writel(val, isp->base + ctrl->freq_ctl);
>> +
>> + ret = readl_poll_timeout(isp->base +
>> BUTTRESS_REG_PWR_STATUS,
>> + val, ((val & ctrl->pwr_sts_mask) ==
>> exp_sts),
>> + 100, BUTTRESS_POWER_TIMEOUT_US);
>> + if (ret) {
>> + dev_err(dev, "%s power up timeout with status:
>> 0x%x\n",
>> + ctrl->subsys_id == IPU_IS ? "IS" : "PS",
>> val);
>> + goto out_power;
>> + }
>> +
>> + dev_dbg(dev, "%s power up successfully. status: 0x%x\n",
>> + ctrl->subsys_id == IPU_IS ? "IS" : "PS", val);
>> +
>> + /* release clock resource ownership */
>> + val = readl(isp->base + BUTTRESS_REG_SLEEP_LEVEL_CFG);
>> + val &= ~ctrl->ovrd_clk;
>> + writel(val, isp->base + BUTTRESS_REG_SLEEP_LEVEL_CFG);
>> +
>> +out_power:
>> + mutex_unlock(&isp->buttress.power_mutex);
>> +
>> + return ret;
>> +}
>> +
>> +static int ipu7_buttress_powerdown(struct device *dev,
>> + const struct ipu_buttress_ctrl
>> *ctrl)
>> +{
>> + struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp;
>> + u32 val, exp_sts;
>> + int ret = 0;
>> +
>> + if (!ctrl)
>> + return 0;
>> +
>> + mutex_lock(&isp->buttress.power_mutex);
>> +
>> + exp_sts = ctrl->pwr_sts_off << ctrl->pwr_sts_shift;
>> + val = 0x8 << ctrl->ratio_shift;
>> +
>> + dev_dbg(dev, "set 0x%x to %s_WORKPOINT_REQ.\n", val,
>> + ctrl->subsys_id == IPU_IS ? "IS" : "PS");
>> + writel(val, isp->base + ctrl->freq_ctl);
>> + ret = readl_poll_timeout(isp->base +
>> BUTTRESS_REG_PWR_STATUS,
>> + val, ((val & ctrl->pwr_sts_mask) ==
>> exp_sts),
>> + 100, BUTTRESS_POWER_TIMEOUT_US);
>> + if (ret) {
>> + dev_err(dev, "%s power down timeout with status:
>> 0x%x\n",
>> + ctrl->subsys_id == IPU_IS ? "IS" : "PS",
>> val);
>> + goto out_power;
>> + }
>> +
>> + dev_dbg(dev, "%s power down successfully. status: 0x%x\n",
>> + ctrl->subsys_id == IPU_IS ? "IS" : "PS", val);
>> +out_power:
>> + if (ctrl->subsys_id == IPU_IS && !ret) {
>> + isys_d2d_power(dev, false);
>> + isys_nde_control(dev, false);
>> + }
>> +
>> + mutex_unlock(&isp->buttress.power_mutex);
>> +
>> + return ret;
>> +}
>> +
>> +static int ipu8_buttress_powerup(struct device *dev,
>> + const struct ipu_buttress_ctrl
>> *ctrl)
>> +{
>> + struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp;
>> + u32 sleep_level_reg = BUTTRESS_REG_SLEEP_LEVEL_STS;
>> + u32 val, exp_sts;
>> + int ret = 0;
>> +
>> + if (!ctrl)
>> + return 0;
>> +
>> + mutex_lock(&isp->buttress.power_mutex);
>> + exp_sts = ctrl->pwr_sts_on << ctrl->pwr_sts_shift;
>> + if (ctrl->subsys_id == IPU_IS) {
>> + ret = isys_d2d_power(dev, true);
>> + if (ret)
>> + goto out_power;
>> + isys_nde_control(dev, true);
>> + }
>> +
>> + /* request ps_pll when psys freq > 400Mhz */
>> + if (ctrl->subsys_id == IPU_PS && ctrl->ratio > 0x10) {
>> + writel(1, isp->base + BUTTRESS_REG_PS_PLL_ENABLE);
>> + ret = readl_poll_timeout(isp->base +
>> sleep_level_reg,
>> + val, (val & ctrl-
>>> own_clk_ack),
>> + 100,
>> BUTTRESS_POWER_TIMEOUT_US);
>> + if (ret)
>> + dev_warn(dev, "ps_pll req ack timeout.
>> status 0x%x\n",
>> + val);
>> + }
>> +
>> + val = ctrl->ratio << ctrl->ratio_shift | ctrl->cdyn << ctrl-
>>> cdyn_shift;
>> + dev_dbg(dev, "set 0x%x to %s_WORKPOINT_REQ.\n", val,
>> + ctrl->subsys_id == IPU_IS ? "IS" : "PS");
>> + writel(val, isp->base + ctrl->freq_ctl);
>> + ret = readl_poll_timeout(isp->base +
>> BUTTRESS_REG_PWR_STATUS,
>> + val, ((val & ctrl->pwr_sts_mask) ==
>> exp_sts),
>> + 100, BUTTRESS_POWER_TIMEOUT_US);
>> + if (ret) {
>> + dev_err(dev, "%s power up timeout with status:
>> 0x%x\n",
>> + ctrl->subsys_id == IPU_IS ? "IS" : "PS",
>> val);
>> + goto out_power;
>> + }
>> +
>> + dev_dbg(dev, "%s power up successfully. status: 0x%x\n",
>> + ctrl->subsys_id == IPU_IS ? "IS" : "PS", val);
>> +out_power:
>> + mutex_unlock(&isp->buttress.power_mutex);
>> +
>> + return ret;
>> +}
>> +
>> +static int ipu8_buttress_powerdown(struct device *dev,
>> + const struct ipu_buttress_ctrl
>> *ctrl)
>> +{
>> + struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp;
>> + u32 val, exp_sts;
>> + int ret = 0;
>> +
>> + if (!ctrl)
>> + return 0;
>> +
>> + mutex_lock(&isp->buttress.power_mutex);
>> + exp_sts = ctrl->pwr_sts_off << ctrl->pwr_sts_shift;
>> +
>> + if (ctrl->subsys_id == IPU_PS)
>> + val = 0x10 << ctrl->ratio_shift;
>> + else
>> + val = 0x8 << ctrl->ratio_shift;
>> +
>> + dev_dbg(dev, "set 0x%x to %s_WORKPOINT_REQ.\n", val,
>> + ctrl->subsys_id == IPU_IS ? "IS" : "PS");
>> + writel(val, isp->base + ctrl->freq_ctl);
>> + ret = readl_poll_timeout(isp->base +
>> BUTTRESS_REG_PWR_STATUS,
>> + val, ((val & ctrl->pwr_sts_mask) ==
>> exp_sts),
>> + 100, BUTTRESS_POWER_TIMEOUT_US);
>> + if (ret) {
>> + dev_err(dev, "%s power down timeout with status:
>> 0x%x\n",
>> + ctrl->subsys_id == IPU_IS ? "IS" : "PS",
>> val);
>> + goto out_power;
>> + }
>> +
>> + dev_dbg(dev, "%s power down successfully. status: 0x%x\n",
>> + ctrl->subsys_id == IPU_IS ? "IS" : "PS", val);
>> +out_power:
>> + if (ctrl->subsys_id == IPU_IS && !ret) {
>> + isys_d2d_power(dev, false);
>> + isys_nde_control(dev, false);
>> + }
>> +
>> + if (ctrl->subsys_id == IPU_PS) {
>> + val = readl(isp->base +
>> BUTTRESS_REG_SLEEP_LEVEL_STS);
>> + if (val & ctrl->own_clk_ack)
>> + writel(0, isp->base +
>> BUTTRESS_REG_PS_PLL_ENABLE);
>> + }
>> + mutex_unlock(&isp->buttress.power_mutex);
>> +
>> + return ret;
>> +}
>> +
>> +int ipu_buttress_powerup(struct device *dev,
>> + const struct ipu_buttress_ctrl *ctrl)
>> +{
>> + struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp;
>> +
>> + if (is_ipu8(isp->hw_ver))
>> + return ipu8_buttress_powerup(dev, ctrl);
>> +
>> + return ipu7_buttress_powerup(dev, ctrl);
>> +}
>> +
>> +int ipu_buttress_powerdown(struct device *dev,
>> + const struct ipu_buttress_ctrl *ctrl)
>> +{
>> + struct ipu7_device *isp = to_ipu7_bus_device(dev)->isp;
>> +
>> + if (is_ipu8(isp->hw_ver))
>> + return ipu8_buttress_powerdown(dev, ctrl);
>> +
>> + return ipu7_buttress_powerdown(dev, ctrl);
>> +}
>> +
>> +bool ipu_buttress_get_secure_mode(struct ipu7_device *isp)
>> +{
>> + u32 val;
>> +
>> + val = readl(isp->base + BUTTRESS_REG_SECURITY_CTL);
>> +
>> + return val & BUTTRESS_SECURITY_CTL_FW_SECURE_MODE;
>> +}
>> +
>> +bool ipu_buttress_auth_done(struct ipu7_device *isp)
>> +{
>> + u32 val;
>> +
>> + if (!isp->secure_mode)
>> + return true;
>> +
>> + val = readl(isp->base + BUTTRESS_REG_SECURITY_CTL);
>> + val = FIELD_GET(BUTTRESS_SECURITY_CTL_FW_SETUP_MASK, val);
>> +
>> + return val == BUTTRESS_SECURITY_CTL_AUTH_DONE;
>> +}
>> +EXPORT_SYMBOL_NS_GPL(ipu_buttress_auth_done, "INTEL_IPU7");
>> +
>> +int ipu_buttress_get_isys_freq(struct ipu7_device *isp, u32 *freq)
>> +{
>> + u32 reg_val;
>> + int ret;
>> +
>> + ret = pm_runtime_get_sync(&isp->isys->auxdev.dev);
>> + if (ret < 0) {
>> + pm_runtime_put(&isp->isys->auxdev.dev);
>> + dev_err(&isp->pdev->dev, "Runtime PM failed (%d)\n",
>> ret);
>> + return ret;
>> + }
>> +
>> + reg_val = readl(isp->base + BUTTRESS_REG_IS_WORKPOINT_REQ);
>> +
>> + pm_runtime_put(&isp->isys->auxdev.dev);
>> +
>> + if (is_ipu8(isp->hw_ver))
>> + *freq = (reg_val & BUTTRESS_IS_FREQ_CTL_RATIO_MASK)
>> * 25;
>> + else
>> + *freq = (reg_val & BUTTRESS_IS_FREQ_CTL_RATIO_MASK)
>> * 50 / 3;
>> +
>> + return 0;
>> +}
>> +EXPORT_SYMBOL_NS_GPL(ipu_buttress_get_isys_freq, "INTEL_IPU7");
>> +
>> +int ipu_buttress_get_psys_freq(struct ipu7_device *isp, u32 *freq)
>> +{
>> + u32 reg_val;
>> + int ret;
>> +
>> + ret = pm_runtime_get_sync(&isp->psys->auxdev.dev);
>> + if (ret < 0) {
>> + pm_runtime_put(&isp->psys->auxdev.dev);
>> + dev_err(&isp->pdev->dev, "Runtime PM failed (%d)\n",
>> ret);
>> + return ret;
>> + }
>> +
>> + reg_val = readl(isp->base + BUTTRESS_REG_PS_WORKPOINT_REQ);
>> +
>> + pm_runtime_put(&isp->psys->auxdev.dev);
>> +
>> + reg_val &= BUTTRESS_PS_FREQ_CTL_RATIO_MASK;
>> + *freq = BUTTRESS_PS_FREQ_RATIO_STEP * reg_val;
>> +
>> + return 0;
>> +}
>> +EXPORT_SYMBOL_NS_GPL(ipu_buttress_get_psys_freq, "INTEL_IPU7");
>> +
>> +int ipu_buttress_reset_authentication(struct ipu7_device *isp)
>> +{
>> + struct device *dev = &isp->pdev->dev;
>> + int ret;
>> + u32 val;
>> +
>> + if (!isp->secure_mode) {
>> + dev_dbg(dev, "Skip auth for non-secure mode\n");
>> + return 0;
>> + }
>> +
>> + writel(BUTTRESS_FW_RESET_CTL_START, isp->base +
>> + BUTTRESS_REG_FW_RESET_CTL);
>> +
>> + ret = readl_poll_timeout(isp->base +
>> BUTTRESS_REG_FW_RESET_CTL, val,
>> + val & BUTTRESS_FW_RESET_CTL_DONE,
>> 500,
>> + BUTTRESS_CSE_FWRESET_TIMEOUT_US);
>> + if (ret) {
>> + dev_err(dev, "Time out while resetting
>> authentication state\n");
>> + return ret;
>> + }
>> +
>> + dev_dbg(dev, "FW reset for authentication done\n");
>> + writel(0, isp->base + BUTTRESS_REG_FW_RESET_CTL);
>> + /* leave some time for HW restore */
>> + usleep_range(800, 1000);
>> +
>> + return 0;
>> +}
>> +
>> +int ipu_buttress_authenticate(struct ipu7_device *isp)
>> +{
>> + struct ipu_buttress *b = &isp->buttress;
>> + struct device *dev = &isp->pdev->dev;
>> + u32 data, mask, done, fail;
>> + int ret;
>> +
>> + if (!isp->secure_mode) {
>> + dev_dbg(dev, "Skip auth for non-secure mode\n");
>> + return 0;
>> + }
>> +
>> + mutex_lock(&b->auth_mutex);
>> +
>> + if (ipu_buttress_auth_done(isp)) {
>> + ret = 0;
>> + goto out_unlock;
>> + }
>> +
>> + /*
>> + * BUTTRESS_REG_FW_SOURCE_BASE needs to be set with FW CPD
>> + * package address for secure mode.
>> + */
>> +
>> + writel(isp->cpd_fw->size, isp->base +
>> BUTTRESS_REG_FW_SOURCE_SIZE);
>> + writel(sg_dma_address(isp->psys->fw_sgt.sgl),
>> + isp->base + BUTTRESS_REG_FW_SOURCE_BASE);
>> +
>> + /*
>> + * Write boot_load into IU2CSEDATA0
>> + * Write sizeof(boot_load) | 0x2 << CLIENT_ID to
>> + * IU2CSEDB.IU2CSECMD and set IU2CSEDB.IU2CSEBUSY as
>> + */
>> + dev_info(dev, "Sending BOOT_LOAD to CSE\n");
>> + ret = ipu_buttress_ipc_send(isp,
>> BUTTRESS_IU2CSEDATA0_IPC_BOOT_LOAD,
>> + 1, true,
>> +
>> BUTTRESS_CSE2IUDATA0_IPC_BOOT_LOAD_DONE);
>> + if (ret) {
>> + dev_err(dev, "CSE boot_load failed\n");
>> + goto out_unlock;
>> + }
>> +
>> + mask = BUTTRESS_SECURITY_CTL_FW_SETUP_MASK;
>> + done = BUTTRESS_SECURITY_CTL_FW_SETUP_DONE;
>> + fail = BUTTRESS_SECURITY_CTL_AUTH_FAILED;
>> + ret = readl_poll_timeout(isp->base +
>> BUTTRESS_REG_SECURITY_CTL, data,
>> + ((data & mask) == done ||
>> + (data & mask) == fail), 500,
>> + BUTTRESS_CSE_BOOTLOAD_TIMEOUT_US);
>> + if (ret) {
>> + dev_err(dev, "CSE boot_load timeout\n");
>> + goto out_unlock;
>> + }
>> +
>> + if ((data & mask) == fail) {
>> + dev_err(dev, "CSE auth failed\n");
>> + ret = -EINVAL;
>> + goto out_unlock;
>> + }
>> +
>> + ret = readl_poll_timeout(isp->base +
>> BOOTLOADER_STATUS_OFFSET,
>> + data, data == BOOTLOADER_MAGIC_KEY,
>> 500,
>> + BUTTRESS_CSE_BOOTLOAD_TIMEOUT_US);
>> + if (ret) {
>> + dev_err(dev, "Unexpected magic number 0x%x\n",
>> data);
>> + goto out_unlock;
>> + }
>> +
>> + /*
>> + * Write authenticate_run into IU2CSEDATA0
>> + * Write sizeof(boot_load) | 0x2 << CLIENT_ID to
>> + * IU2CSEDB.IU2CSECMD and set IU2CSEDB.IU2CSEBUSY as
>> + */
>> + dev_info(dev, "Sending AUTHENTICATE_RUN to CSE\n");
>> + ret = ipu_buttress_ipc_send(isp,
>> BUTTRESS_IU2CSEDATA0_IPC_AUTH_RUN,
>> + 1, true,
>> +
>> BUTTRESS_CSE2IUDATA0_IPC_AUTH_RUN_DONE);
>> + if (ret) {
>> + dev_err(dev, "CSE authenticate_run failed\n");
>> + goto out_unlock;
>> + }
>> +
>> + done = BUTTRESS_SECURITY_CTL_AUTH_DONE;
>> + ret = readl_poll_timeout(isp->base +
>> BUTTRESS_REG_SECURITY_CTL, data,
>> + ((data & mask) == done ||
>> + (data & mask) == fail), 500,
>> +
>> BUTTRESS_CSE_AUTHENTICATE_TIMEOUT_US);
>> + if (ret) {
>> + dev_err(dev, "CSE authenticate timeout\n");
>> + goto out_unlock;
>> + }
>> +
>> + if ((data & mask) == fail) {
>> + dev_err(dev, "CSE boot_load failed\n");
>> + ret = -EINVAL;
>> + goto out_unlock;
>> + }
>> +
>> + dev_info(dev, "CSE authenticate_run done\n");
>> +
>> +out_unlock:
>> + mutex_unlock(&b->auth_mutex);
>> +
>> + return ret;
>> +}
>> +
>> +static int ipu_buttress_send_tsc_request(struct ipu7_device *isp)
>> +{
>> + u32 val, mask, done;
>> + int ret;
>> +
>> + mask = BUTTRESS_PWR_STATUS_HH_STATUS_MASK;
>> +
>> + writel(BUTTRESS_TSC_CMD_START_TSC_SYNC,
>> + isp->base + BUTTRESS_REG_TSC_CMD);
>> +
>> + val = readl(isp->base + BUTTRESS_REG_PWR_STATUS);
>> + val = FIELD_GET(mask, val);
>> + if (val == BUTTRESS_PWR_STATUS_HH_STATE_ERR) {
>> + dev_err(&isp->pdev->dev, "Start tsc sync failed\n");
>> + return -EINVAL;
>> + }
>> +
>> + done = BUTTRESS_PWR_STATUS_HH_STATE_DONE;
>> + ret = readl_poll_timeout(isp->base +
>> BUTTRESS_REG_PWR_STATUS, val,
>> + FIELD_GET(mask, val) == done, 500,
>> + BUTTRESS_TSC_SYNC_TIMEOUT_US);
>> + if (ret)
>> + dev_err(&isp->pdev->dev, "Start tsc sync
>> timeout\n");
>> +
>> + return ret;
>> +}
>> +
>> +int ipu_buttress_start_tsc_sync(struct ipu7_device *isp)
>> +{
>> + void __iomem *base = isp->base;
>> + unsigned int i;
>> + u32 val;
>> +
>> + if (is_ipu8(isp->hw_ver)) {
>> + for (i = 0; i < BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX;
>> i++) {
>> + val = readl(base +
>> BUTTRESS_REG_PB_TIMESTAMP_VALID);
>> + if (val == 1)
>> + return 0;
>> + usleep_range(40, 50);
>> + }
>> +
>> + dev_err(&isp->pdev->dev, "PB HH sync failed (valid
>> %u)\n", val);
>> + return -ETIMEDOUT;
>> + }
>> +
>> + if (is_ipu7p5(isp->hw_ver)) {
>> + val = readl(base + BUTTRESS_REG_TSC_CTL);
>> + val |= BUTTRESS_SEL_PB_TIMESTAMP;
>> + writel(val, base + BUTTRESS_REG_TSC_CTL);
>> +
>> + for (i = 0; i < BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX;
>> i++) {
>> + val = readl(base +
>> BUTTRESS_REG_PB_TIMESTAMP_VALID);
>> + if (val == 1)
>> + return 0;
>> + usleep_range(40, 50);
>> + }
>> +
>> + dev_err(&isp->pdev->dev, "PB HH sync failed (valid
>> %u)\n", val);
>> +
>> + return -ETIMEDOUT;
>> + }
>> +
>> + for (i = 0; i < BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX; i++) {
>> + int ret;
>> +
>> + ret = ipu_buttress_send_tsc_request(isp);
>> + if (ret != -ETIMEDOUT)
>> + return ret;
>> +
>> + val = readl(base + BUTTRESS_REG_TSC_CTL);
>> + val = val | BUTTRESS_TSW_WA_SOFT_RESET;
>> + writel(val, base + BUTTRESS_REG_TSC_CTL);
>> + val = val & (~BUTTRESS_TSW_WA_SOFT_RESET);
>> + writel(val, base + BUTTRESS_REG_TSC_CTL);
>> + }
>> +
>> + dev_err(&isp->pdev->dev, "TSC sync failed (timeout)\n");
>> +
>> + return -ETIMEDOUT;
>> +}
>> +EXPORT_SYMBOL_NS_GPL(ipu_buttress_start_tsc_sync, "INTEL_IPU7");
>> +
>> +void ipu_buttress_tsc_read(struct ipu7_device *isp, u64 *val)
>> +{
>> + unsigned long flags;
>> + u32 tsc_hi, tsc_lo;
>> +
>> + local_irq_save(flags);
>> + if (is_ipu7(isp->hw_ver)) {
>> + tsc_lo = readl(isp->base + BUTTRESS_REG_TSC_LO);
>> + tsc_hi = readl(isp->base + BUTTRESS_REG_TSC_HI);
>> + } else {
>> + tsc_lo = readl(isp->base +
>> BUTTRESS_REG_PB_TIMESTAMP_LO);
>> + tsc_hi = readl(isp->base +
>> BUTTRESS_REG_PB_TIMESTAMP_HI);
>> + }
>> + *val = (u64)tsc_hi << 32 | tsc_lo;
>> + local_irq_restore(flags);
>> +}
>> +EXPORT_SYMBOL_NS_GPL(ipu_buttress_tsc_read, "INTEL_IPU7");
>> +
>> +u64 ipu_buttress_tsc_ticks_to_ns(u64 ticks, const struct ipu7_device
>> *isp)
>> +{
>> + u64 ns = ticks * 10000;
>> +
>> + /*
>> + * converting TSC tick count to ns is calculated by:
>> + * Example (TSC clock frequency is 19.2MHz):
>> + * ns = ticks * 1000 000 000 / 19.2Mhz
>> + * = ticks * 1000 000 000 / 19200000Hz
>> + * = ticks * 10000 / 192 ns
>> + */
>> + return div_u64(ns, isp->buttress.ref_clk);
>> +}
>> +EXPORT_SYMBOL_NS_GPL(ipu_buttress_tsc_ticks_to_ns, "INTEL_IPU7");
>> +
>> +/* trigger uc control to wakeup fw */
>> +void ipu_buttress_wakeup_is_uc(const struct ipu7_device *isp)
>> +{
>> + u32 val;
>> +
>> + val = readl(isp->base +
>> BUTTRESS_REG_DRV_IS_UCX_CONTROL_STATUS);
>> + val |= UCX_CTL_WAKEUP;
>> + writel(val, isp->base +
>> BUTTRESS_REG_DRV_IS_UCX_CONTROL_STATUS);
>> +}
>> +EXPORT_SYMBOL_NS_GPL(ipu_buttress_wakeup_is_uc, "INTEL_IPU7");
>> +
>> +void ipu_buttress_wakeup_ps_uc(const struct ipu7_device *isp)
>> +{
>> + u32 val;
>> +
>> + val = readl(isp->base +
>> BUTTRESS_REG_DRV_PS_UCX_CONTROL_STATUS);
>> + val |= UCX_CTL_WAKEUP;
>> + writel(val, isp->base +
>> BUTTRESS_REG_DRV_PS_UCX_CONTROL_STATUS);
>> +}
>> +EXPORT_SYMBOL_NS_GPL(ipu_buttress_wakeup_ps_uc, "INTEL_IPU7");
>> +
>> +static const struct x86_cpu_id ipu_misc_cfg_exclusion[] = {
>> + X86_MATCH_VFM_STEPS(INTEL_PANTHERLAKE_L, 0x1, 0x1, 0),
>> + {},
>> +};
>> +
>> +static void ipu_buttress_setup(struct ipu7_device *isp)
>> +{
>> + struct device *dev = &isp->pdev->dev;
>> + u32 val;
>> +
>> + /* program PB BAR */
>> +#define WRXREQOP_OVRD_VAL_MASK GENMASK(22, 19)
>> + writel(0, isp->pb_base + GLOBAL_INTERRUPT_MASK);
>> + val = readl(isp->pb_base + BAR2_MISC_CONFIG);
>> + if (is_ipu7(isp->hw_ver) ||
>> x86_match_cpu(ipu_misc_cfg_exclusion))
>> + val |= 0x100U;
>> + else
>> + val |= FIELD_PREP(WRXREQOP_OVRD_VAL_MASK, 0xf) |
>> + BIT(18) | 0x100U;
>> +
>> + writel(val, isp->pb_base + BAR2_MISC_CONFIG);
>> + val = readl(isp->pb_base + BAR2_MISC_CONFIG);
>> +
>> + if (is_ipu8(isp->hw_ver)) {
>> + writel(BIT(13), isp->pb_base +
>> TLBID_HASH_ENABLE_63_32);
>> + writel(BIT(9), isp->pb_base +
>> TLBID_HASH_ENABLE_95_64);
>> + dev_dbg(dev, "IPU8 TLBID_HASH %x %x\n",
>> + readl(isp->pb_base +
>> TLBID_HASH_ENABLE_63_32),
>> + readl(isp->pb_base +
>> TLBID_HASH_ENABLE_95_64));
>> + } else if (is_ipu7p5(isp->hw_ver)) {
>> + writel(BIT(14), isp->pb_base +
>> TLBID_HASH_ENABLE_63_32);
>> + writel(BIT(9), isp->pb_base +
>> TLBID_HASH_ENABLE_95_64);
>> + dev_dbg(dev, "IPU7P5 TLBID_HASH %x %x\n",
>> + readl(isp->pb_base +
>> TLBID_HASH_ENABLE_63_32),
>> + readl(isp->pb_base +
>> TLBID_HASH_ENABLE_95_64));
>> + } else {
>> + writel(BIT(22), isp->pb_base +
>> TLBID_HASH_ENABLE_63_32);
>> + writel(BIT(1), isp->pb_base +
>> TLBID_HASH_ENABLE_127_96);
>> + dev_dbg(dev, "TLBID_HASH %x %x\n",
>> + readl(isp->pb_base +
>> TLBID_HASH_ENABLE_63_32),
>> + readl(isp->pb_base +
>> TLBID_HASH_ENABLE_127_96));
>> + }
>> +
>> + writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_IRQ_CLEAR);
>> + writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_IRQ_MASK);
>> + writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_IRQ_ENABLE);
>> + /* LNL SW workaround for PS PD hang when PS sub-domain
>> during PD */
>> + writel(PS_FSM_CG, isp->base + BUTTRESS_REG_CG_CTRL_BITS);
>> +}
>> +
>> +void ipu_buttress_restore(struct ipu7_device *isp)
>> +{
>> + struct ipu_buttress *b = &isp->buttress;
>> +
>> + ipu_buttress_setup(isp);
>> +
>> + writel(b->wdt_cached_value, isp->base +
>> BUTTRESS_REG_IDLE_WDT);
>> +}
>> +
>> +int ipu_buttress_init(struct ipu7_device *isp)
>> +{
>> + int ret, ipc_reset_retry = BUTTRESS_CSE_IPC_RESET_RETRY;
>> + struct ipu_buttress *b = &isp->buttress;
>> + struct device *dev = &isp->pdev->dev;
>> + u32 val;
>> +
>> + mutex_init(&b->power_mutex);
>> + mutex_init(&b->auth_mutex);
>> + mutex_init(&b->cons_mutex);
>> + mutex_init(&b->ipc_mutex);
>> + init_completion(&b->cse.send_complete);
>> + init_completion(&b->cse.recv_complete);
>> +
>> + b->cse.nack = BUTTRESS_CSE2IUDATA0_IPC_NACK;
>> + b->cse.nack_mask = BUTTRESS_CSE2IUDATA0_IPC_NACK_MASK;
>> + b->cse.csr_in = BUTTRESS_REG_CSE2IUCSR;
>> + b->cse.csr_out = BUTTRESS_REG_IU2CSECSR;
>> + b->cse.db0_in = BUTTRESS_REG_CSE2IUDB0;
>> + b->cse.db0_out = BUTTRESS_REG_IU2CSEDB0;
>> + b->cse.data0_in = BUTTRESS_REG_CSE2IUDATA0;
>> + b->cse.data0_out = BUTTRESS_REG_IU2CSEDATA0;
>> +
>> + isp->secure_mode = ipu_buttress_get_secure_mode(isp);
>> + val = readl(isp->base + BUTTRESS_REG_IPU_SKU);
>> + dev_info(dev, "IPU%u SKU %u in %s mode mask 0x%x\n", val &
>> 0xf,
>> + (val >> 4) & 0x7, isp->secure_mode ? "secure" :
>> "non-secure",
>> + readl(isp->base + BUTTRESS_REG_CAMERA_MASK));
>> + b->wdt_cached_value = readl(isp->base +
>> BUTTRESS_REG_IDLE_WDT);
>> + b->ref_clk = 384;
>> +
>> + ipu_buttress_setup(isp);
>> +
>> + /* Retry couple of times in case of CSE initialization is
>> delayed */
>> + do {
>> + ret = ipu_buttress_ipc_reset(isp, &b->cse);
>> + if (ret) {
>> + dev_warn(dev, "IPC reset protocol failed,
>> retrying\n");
>> + } else {
>> + dev_dbg(dev, "IPC reset done\n");
>> + return 0;
>> + }
>> + } while (ipc_reset_retry--);
>> +
>> + dev_err(dev, "IPC reset protocol failed\n");
>> +
>> + mutex_destroy(&b->power_mutex);
>> + mutex_destroy(&b->auth_mutex);
>> + mutex_destroy(&b->cons_mutex);
>> + mutex_destroy(&b->ipc_mutex);
>> +
>> + return ret;
>> +}
>> +
>> +void ipu_buttress_exit(struct ipu7_device *isp)
>> +{
>> + struct ipu_buttress *b = &isp->buttress;
>> +
>> + writel(0, isp->base + BUTTRESS_REG_IRQ_ENABLE);
>> + mutex_destroy(&b->power_mutex);
>> + mutex_destroy(&b->auth_mutex);
>> + mutex_destroy(&b->cons_mutex);
>> + mutex_destroy(&b->ipc_mutex);
>> +}
>> diff --git a/drivers/media/pci/intel/ipu7/ipu7-buttress.h
>> b/drivers/media/pci/intel/ipu7/ipu7-buttress.h
>> new file mode 100644
>> index 000000000000..045b11992331
>> --- /dev/null
>> +++ b/drivers/media/pci/intel/ipu7/ipu7-buttress.h
>> @@ -0,0 +1,84 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +/*
>> + * Copyright (C) 2013 - 2024 Intel Corporation
>> + */
>> +
>> +#ifndef IPU7_BUTTRESS_H
>> +#define IPU7_BUTTRESS_H
>> +
>> +#include <linux/completion.h>
>> +#include <linux/irqreturn.h>
>> +#include <linux/list.h>
>> +#include <linux/mutex.h>
>> +
>> +struct device;
>> +struct ipu7_device;
>> +
>> +struct ipu_buttress_ctrl {
>> + u32 subsys_id;
>> + u32 freq_ctl, pwr_sts_shift, pwr_sts_mask, pwr_sts_on,
>> pwr_sts_off;
>> + u32 ratio;
>> + u32 ratio_shift;
>> + u32 cdyn;
>> + u32 cdyn_shift;
>> + u32 ovrd_clk;
>> + u32 own_clk_ack;
>> +};
>> +
>> +struct ipu_buttress_ipc {
>> + struct completion send_complete;
>> + struct completion recv_complete;
>> + u32 nack;
>> + u32 nack_mask;
>> + u32 recv_data;
>> + u32 csr_out;
>> + u32 csr_in;
>> + u32 db0_in;
>> + u32 db0_out;
>> + u32 data0_out;
>> + u32 data0_in;
>> +};
>> +
>> +struct ipu_buttress {
>> + struct mutex power_mutex, auth_mutex, cons_mutex, ipc_mutex;
>> + struct ipu_buttress_ipc cse;
>> + u32 psys_min_freq;
>> + u32 wdt_cached_value;
>> + u8 psys_force_ratio;
>> + bool force_suspend;
>> + u32 ref_clk;
>> +};
>> +
>> +struct ipu7_ipc_buttress_bulk_msg {
>> + u32 cmd;
>> + u32 expected_resp;
>> + bool require_resp;
>> + u8 cmd_size;
>> +};
>> +
>> +int ipu_buttress_ipc_reset(struct ipu7_device *isp,
>> + struct ipu_buttress_ipc *ipc);
>> +int ipu_buttress_powerup(struct device *dev,
>> + const struct ipu_buttress_ctrl *ctrl);
>> +int ipu_buttress_powerdown(struct device *dev,
>> + const struct ipu_buttress_ctrl *ctrl);
>> +bool ipu_buttress_get_secure_mode(struct ipu7_device *isp);
>> +int ipu_buttress_authenticate(struct ipu7_device *isp);
>> +int ipu_buttress_reset_authentication(struct ipu7_device *isp);
>> +bool ipu_buttress_auth_done(struct ipu7_device *isp);
>> +int ipu_buttress_get_isys_freq(struct ipu7_device *isp, u32 *freq);
>> +int ipu_buttress_get_psys_freq(struct ipu7_device *isp, u32 *freq);
>> +int ipu_buttress_start_tsc_sync(struct ipu7_device *isp);
>> +void ipu_buttress_tsc_read(struct ipu7_device *isp, u64 *val);
>> +u64 ipu_buttress_tsc_ticks_to_ns(u64 ticks, const struct ipu7_device
>> *isp);
>> +
>> +irqreturn_t ipu_buttress_isr(int irq, void *isp_ptr);
>> +irqreturn_t ipu_buttress_isr_threaded(int irq, void *isp_ptr);
>> +int ipu_buttress_init(struct ipu7_device *isp);
>> +void ipu_buttress_exit(struct ipu7_device *isp);
>> +void ipu_buttress_csi_port_config(struct ipu7_device *isp,
>> + u32 legacy, u32 combo);
>> +void ipu_buttress_restore(struct ipu7_device *isp);
>> +void ipu_buttress_wakeup_is_uc(const struct ipu7_device *isp);
>> +void ipu_buttress_wakeup_ps_uc(const struct ipu7_device *isp);
>> +#endif /* IPU7_BUTTRESS_H */
>> diff --git a/drivers/media/pci/intel/ipu7/ipu7-platform-regs.h
>> b/drivers/media/pci/intel/ipu7/ipu7-platform-regs.h
>> new file mode 100644
>> index 000000000000..377acca35ab0
>> --- /dev/null
>> +++ b/drivers/media/pci/intel/ipu7/ipu7-platform-regs.h
>> @@ -0,0 +1,146 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +/*
>> + * Copyright (C) 2018 - 2024 Intel Corporation
>> + */
>> +
>> +#ifndef IPU7_PLATFORM_REGS_H
>> +#define IPU7_PLATFORM_REGS_H
>> +
>> +#define IS_BASE 0x230000
>> +#define IS_UC_CTRL_BASE (IS_BASE +
>> 0x0)
>> +
>> +#define PS_BASE 0x130000
>> +#define PS_UC_CTRL_BASE (PS_BASE +
>> 0x0)
>> +
>> +/*
>> + * bit 0: IRQ from FW,
>> + * bit 1, 2 and 3: IRQ from HW
>> + */
>> +#define TO_SW_IRQ_MASK 0xf
>> +#define TO_SW_IRQ_FW BIT(0)
>> +
>> +#define FW_CODE_BASE 0x0
>> +#define FW_DATA_BASE 0x4
>> +#define CPU_AXI_CNTL 0x8
>> +#define CPU_QOS_CNTL 0xc
>> +#define IDMA_AXI_CNTL 0x10
>> +#define IDMA_QOS_CNTL 0x14
>> +#define MEF_SPLIT_SIZE 0x18
>> +#define FW_MSG_CONTROL 0x1c
>> +#define FW_MSG_CREDITS_STATUS 0x20
>> +#define FW_MSG_CREDIT_TAKEN 0x24
>> +#define FW_MSG_CREDIT_RETURNED 0x28
>> +#define TRIG_IDMA_IN 0x2c
>> +#define IDMA_DONE 0x30
>> +#define IDMA_DONE_CLEAR 0x34
>> +#define DMEM_CAPACITY 0x38
>> +#define NON_SECURE_CODE_OFFSET 0x3c
>> +#define UC_CG_CTRL_BITS 0x40
>> +#define ALT_RESET_VEC 0x44
>> +#define WDT_NMI_DURATION 0x104
>> +#define WDT_RST_REQ_DURATION 0x108
>> +#define WDT_CNTL 0x10c
>> +#define WDT_NMI_CURRENT_COUNT 0x110
>> +#define WDT_RST_CURRENT_COUNT 0x114
>> +#define WDT_HALT 0x118
>> +#define WDT_STATUS 0x11c
>> +#define SPARE_REG_RW 0x120
>> +#define SPARE_REG_RO 0x124
>> +#define FW_TO_FW_IRQ_CNTL_EDGE 0x200
>> +#define FW_TO_FW_IRQ_CNTL_MASK_N 0x204
>> +#define FW_TO_FW_IRQ_CNTL_STATUS 0x208
>> +#define FW_TO_FW_IRQ_CNTL_CLEAR 0x20c
>> +#define FW_TO_FW_IRQ_CNTL_ENABLE 0x210
>> +#define FW_TO_FW_IRQ_CNTL_LEVEL_NOT_PULSE 0x214
>> +#define CLK_GATE_DIS 0x218
>> +#define DEBUG_STATUS 0x1000
>> +#define DEBUG_EXCPETION 0x1004
>> +#define TIE_GENERAL_INPUT 0x1008
>> +#define ERR_STATUS 0x100c
>> +#define UC_ERR_INFO 0x1010
>> +#define SPARE_CNTL 0x1014
>> +#define MEF_TRC_CNTL 0x1100
>> +#define DBG_MEF_LAST_PUSH 0x1104
>> +#define DBG_MEF_LAST_POP 0x1108
>> +#define DBG_MEF_COUNT_CNTL 0x110c
>> +#define DBG_MEF_COUNT1 0x1110
>> +#define DBG_MEF_COUNT2 0x1114
>> +#define DBG_MEF_ACC_OCCUPANCY 0x1118
>> +#define DBG_MEF_MAX_IRQ_TO_POP 0x111c
>> +#define DBG_IRQ_CNTL 0x1120
>> +#define DBG_IRQ_COUNT 0x1124
>> +#define DBG_CYC_COUNT 0x1128
>> +#define DBG_CNTL 0x1130
>> +#define DBG_RST_REG 0x1134
>> +#define DBG_MEF_STATUS0 0x1138
>> +#define DBG_MEF_STATUS1 0x113c
>> +#define PDEBUG_CTL 0x1140
>> +#define PDEBUG_DATA 0x1144
>> +#define PDEBUG_INST 0x1148
>> +#define PDEBUG_LS0ADDR 0x114c
>> +#define PDEBUG_LS0DATA 0x1150
>> +#define PDEBUG_LS0STAT 0x1154
>> +#define PDEBUG_PC 0x1158
>> +#define PDEBUG_MISC 0x115c
>> +#define PDEBUG_PREF_STS 0x1160
>> +#define MEF0_ADDR 0x2000
>> +#define MEF1_ADDR 0x2020
>> +#define PRINTF_EN_THROUGH_TRACE 0x3004
>> +#define PRINTF_EN_DIRECTLY_TO_DDR 0x3008
>> +#define PRINTF_DDR_BASE_ADDR 0x300c
>> +#define PRINTF_DDR_SIZE 0x3010
>> +#define PRINTF_DDR_NEXT_ADDR 0x3014
>> +#define PRINTF_STATUS 0x3018
>> +#define PRINTF_AXI_CNTL 0x301c
>> +#define PRINTF_MSG_LENGTH 0x3020
>> +#define TO_SW_IRQ_CNTL_EDGE 0x4000
>> +#define TO_SW_IRQ_CNTL_MASK_N 0x4004
>> +#define TO_SW_IRQ_CNTL_STATUS 0x4008
>> +#define TO_SW_IRQ_CNTL_CLEAR 0x400c
>> +#define TO_SW_IRQ_CNTL_ENABLE 0x4010
>> +#define TO_SW_IRQ_CNTL_LEVEL_NOT_PULSE 0x4014
>> +#define ERR_IRQ_CNTL_EDGE 0x4018
>> +#define ERR_IRQ_CNTL_MASK_N 0x401c
>> +#define ERR_IRQ_CNTL_STATUS 0x4020
>> +#define ERR_IRQ_CNTL_CLEAR 0x4024
>> +#define ERR_IRQ_CNTL_ENABLE 0x4028
>> +#define ERR_IRQ_CNTL_LEVEL_NOT_PULSE 0x402c
>> +#define LOCAL_DMEM_BASE_ADDR 0x1300000
>> +
>> +/*
>> + * IS_UC_TO_SW irqs
>> + * bit 0: IRQ from local FW
>> + * bit 1~3: IRQ from HW
>> + */
>> +#define IS_UC_TO_SW_IRQ_MASK 0xf
>> +
>> +#define IPU_ISYS_SPC_OFFSET 0x210000
>> +#define IPU7_PSYS_SPC_OFFSET 0x118000
>> +#define IPU_ISYS_DMEM_OFFSET 0x200000
>> +#define IPU_PSYS_DMEM_OFFSET 0x100000
>> +
>> +#define IPU7_ISYS_CSI_PORT_NUM 4
>> +
>> +/* IRQ-related registers in PSYS */
>> +#define IPU_REG_PSYS_TO_SW_IRQ_CNTL_EDGE 0x134000
>> +#define IPU_REG_PSYS_TO_SW_IRQ_CNTL_MASK 0x134004
>> +#define IPU_REG_PSYS_TO_SW_IRQ_CNTL_STATUS 0x134008
>> +#define IPU_REG_PSYS_TO_SW_IRQ_CNTL_CLEAR 0x13400c
>> +#define IPU_REG_PSYS_TO_SW_IRQ_CNTL_ENABLE 0x134010
>> +#define IPU_REG_PSYS_TO_SW_IRQ_CNTL_LEVEL_NOT_PULSE 0x134014
>> +#define IRQ_FROM_LOCAL_FW BIT(0)
>> +
>> +/*
>> + * psys subdomains power request regs
>> + */
>> +enum ipu7_device_buttress_psys_domain_pos {
>> + IPU_PSYS_SUBDOMAIN_LB = 0,
>> + IPU_PSYS_SUBDOMAIN_BB = 1,
>> +};
>> +
>> +#define
>> IPU7_PSYS_DOMAIN_POWER_MASK (BIT(IPU_PSYS_SUBDOMAIN_LB) | \
>> +
>> BIT(IPU_PSYS_SUBDOMAIN_BB))
>> +#define
>> IPU8_PSYS_DOMAIN_POWER_MASK BIT(IPU_PSYS_SUBDOMAIN_LB)
>> +#define IPU_PSYS_DOMAIN_POWER_IN_PROGRESS BIT(31)
>> +
>> +#endif /* IPU7_PLATFORM_REGS_H */
>> diff --git a/drivers/media/pci/intel/ipu7/ipu7.c
>> b/drivers/media/pci/intel/ipu7/ipu7.c
>> new file mode 100644
>> index 000000000000..a0eec938fbea
>> --- /dev/null
>> +++ b/drivers/media/pci/intel/ipu7/ipu7.c
>> @@ -0,0 +1,2791 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Copyright (C) 2013 - 2024 Intel Corporation
>> + */
>> +
>> +#include <linux/acpi.h>
>> +#include <linux/bitfield.h>
>> +#include <linux/bits.h>
>> +#include <linux/bug.h>
>> +#include <linux/dma-mapping.h>
>> +#include <linux/err.h>
>> +#include <linux/firmware.h>
>> +#include <linux/kernel.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/io.h>
>> +#include <linux/list.h>
>> +#include <linux/module.h>
>> +#include <linux/pm_runtime.h>
>> +#include <linux/property.h>
>> +#include <linux/scatterlist.h>
>> +#include <linux/slab.h>
>> +#include <linux/types.h>
>> +#include <linux/vmalloc.h>
>> +#include <linux/version.h>
>> +
>> +#include <media/ipu-bridge.h>
>> +
>> +#include "abi/ipu7_fw_common_abi.h"
>> +
>> +#include "ipu7.h"
>> +#include "ipu7-bus.h"
>> +#include "ipu7-buttress.h"
>> +#include "ipu7-buttress-regs.h"
>> +#include "ipu7-cpd.h"
>> +#include "ipu7-dma.h"
>> +#include "ipu7-isys-csi2-regs.h"
>> +#include "ipu7-mmu.h"
>> +#include "ipu7-platform-regs.h"
>> +
>> +#define IPU_PCI_BAR 0
>> +#define IPU_PCI_PBBAR 4
>> +
>> +static unsigned int ipu7_csi_offsets[] = {
>> + IPU_CSI_PORT_A_ADDR_OFFSET,
>> + IPU_CSI_PORT_B_ADDR_OFFSET,
>> + IPU_CSI_PORT_C_ADDR_OFFSET,
>> + IPU_CSI_PORT_D_ADDR_OFFSET,
>> +};
>> +
>> +static struct ipu_isys_internal_pdata ipu7p5_isys_ipdata = {
>> + .csi2 = {
>> + .gpreg = IS_IO_CSI2_GPREGS_BASE,
>> + },
>> + .hw_variant = {
>> + .offset = IPU_UNIFIED_OFFSET,
>> + .nr_mmus = IPU7P5_IS_MMU_NUM,
>> + .mmu_hw = {
>> + {
>> + .name = "IS_FW_RD",
>> + .offset =
>> IPU7P5_IS_MMU_FW_RD_OFFSET,
>> + .zlx_offset =
>> IPU7P5_IS_ZLX_UC_RD_OFFSET,
>> + .uao_offset =
>> IPU7P5_IS_UAO_UC_RD_OFFSET,
>> + .info_bits = 0x20005101,
>> + .refill = 0x00002726,
>> + .collapse_en_bitmap = 0x1,
>> + .at_sp_arb_cfg = 0x1,
>> + .l1_block =
>> IPU7P5_IS_MMU_FW_RD_L1_BLOCKNR_REG,
>> + .l2_block =
>> IPU7P5_IS_MMU_FW_RD_L2_BLOCKNR_REG,
>> + .nr_l1streams =
>> IPU7P5_IS_MMU_FW_RD_STREAM_NUM,
>> + .nr_l2streams =
>> IPU7P5_IS_MMU_FW_RD_STREAM_NUM,
>> + .l1_block_sz = {
>> + 0x0, 0x8, 0xa,
>> + },
>> + .l2_block_sz = {
>> + 0x0, 0x2, 0x4,
>> + },
>> + .zlx_nr = IPU7P5_IS_ZLX_UC_RD_NUM,
>> + .zlx_axi_pool = {
>> + 0x00000f30,
>> + },
>> + .zlx_en = {
>> + 0, 1, 0, 0
>> + },
>> + .zlx_conf = {
>> + 0x0,
>> + },
>> + .uao_p_num =
>> IPU7P5_IS_UAO_UC_RD_PLANENUM,
>> + .uao_p2tlb = {
>> + 0x00000049,
>> + 0x0000004c,
>> + 0x0000004d,
>> + 0x00000000,
>> + },
>> + },
>> + {
>> + .name = "IS_FW_WR",
>> + .offset =
>> IPU7P5_IS_MMU_FW_WR_OFFSET,
>> + .zlx_offset =
>> IPU7P5_IS_ZLX_UC_WR_OFFSET,
>> + .uao_offset =
>> IPU7P5_IS_UAO_UC_WR_OFFSET,
>> + .info_bits = 0x20005001,
>> + .refill = 0x00002524,
>> + .collapse_en_bitmap = 0x1,
>> + .at_sp_arb_cfg = 0x1,
>> + .l1_block =
>> IPU7P5_IS_MMU_FW_WR_L1_BLOCKNR_REG,
>> + .l2_block =
>> IPU7P5_IS_MMU_FW_WR_L2_BLOCKNR_REG,
>> + .nr_l1streams =
>> IPU7P5_IS_MMU_FW_WR_STREAM_NUM,
>> + .nr_l2streams =
>> IPU7P5_IS_MMU_FW_WR_STREAM_NUM,
>> + .l1_block_sz = {
>> + 0x0, 0x8, 0xa,
>> + },
>> + .l2_block_sz = {
>> + 0x0, 0x2, 0x4,
>> + },
>> + .zlx_nr = IPU7P5_IS_ZLX_UC_WR_NUM,
>> + .zlx_axi_pool = {
>> + 0x00000f20,
>> + },
>> + .zlx_en = {
>> + 0, 1, 1, 0,
>> + },
>> + .zlx_conf = {
>> + 0x0,
>> + 0x00010101,
>> + 0x00010101,
>> + 0x0,
>> + },
>> + .uao_p_num =
>> IPU7P5_IS_UAO_UC_WR_PLANENUM,
>> + .uao_p2tlb = {
>> + 0x00000049,
>> + 0x0000004a,
>> + 0x0000004b,
>> + 0x00000000,
>> + },
>> + },
>> + {
>> + .name = "IS_DATA_WR_ISOC",
>> + .offset = IPU7P5_IS_MMU_M0_OFFSET,
>> + .zlx_offset =
>> IPU7P5_IS_ZLX_M0_OFFSET,
>> + .uao_offset =
>> IPU7P5_IS_UAO_M0_WR_OFFSET,
>> + .info_bits = 0x20004e01,
>> + .refill = 0x00002120,
>> + .collapse_en_bitmap = 0x1,
>> + .at_sp_arb_cfg = 0x1,
>> + .l1_block =
>> IPU7P5_IS_MMU_M0_L1_BLOCKNR_REG,
>> + .l2_block =
>> IPU7P5_IS_MMU_M0_L2_BLOCKNR_REG,
>> + .nr_l1streams =
>> IPU7P5_IS_MMU_M0_STREAM_NUM,
>> + .nr_l2streams =
>> IPU7P5_IS_MMU_M0_STREAM_NUM,
>> + .l1_block_sz = {
>> + 0x00000000,
>> + 0x00000002,
>> + 0x00000004,
>> + 0x00000006,
>> + 0x00000008,
>> + 0x0000000a,
>> + 0x0000000c,
>> + 0x0000000e,
>> + 0x00000010,
>> + 0x00000012,
>> + 0x00000014,
>> + 0x00000016,
>> + 0x00000018,
>> + 0x0000001a,
>> + 0x0000001c,
>> + 0x0000001e,
>> + },
>> + .l2_block_sz = {
>> + 0x00000000,
>> + 0x00000002,
>> + 0x00000004,
>> + 0x00000006,
>> + 0x00000008,
>> + 0x0000000a,
>> + 0x0000000c,
>> + 0x0000000e,
>> + 0x00000010,
>> + 0x00000012,
>> + 0x00000014,
>> + 0x00000016,
>> + 0x00000018,
>> + 0x0000001a,
>> + 0x0000001c,
>> + 0x0000001e,
>> + },
>> + .zlx_nr = IPU7P5_IS_ZLX_M0_NUM,
>> + .zlx_axi_pool = {
>> + 0x00000f10,
>> + },
>> + .zlx_en = {
>> + 1, 1, 1, 1, 1, 1, 1, 1,
>> + 1, 1, 1, 1, 1, 1, 1, 1,
>> + },
>> + .zlx_conf = {
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + },
>> + .uao_p_num =
>> IPU7P5_IS_UAO_M0_WR_PLANENUM,
>> + .uao_p2tlb = {
>> + 0x00000041,
>> + 0x00000042,
>> + 0x00000043,
>> + 0x00000044,
>> + 0x00000041,
>> + 0x00000042,
>> + 0x00000043,
>> + 0x00000044,
>> + 0x00000041,
>> + 0x00000042,
>> + 0x00000043,
>> + 0x00000044,
>> + 0x00000041,
>> + 0x00000042,
>> + 0x00000043,
>> + 0x00000044,
>> + },
>> + },
>> + {
>> + .name = "IS_DATA_WR_SNOOP",
>> + .offset = IPU7P5_IS_MMU_M1_OFFSET,
>> + .zlx_offset =
>> IPU7P5_IS_ZLX_M1_OFFSET,
>> + .uao_offset =
>> IPU7P5_IS_UAO_M1_WR_OFFSET,
>> + .info_bits = 0x20004f01,
>> + .refill = 0x00002322,
>> + .collapse_en_bitmap = 0x1,
>> + .at_sp_arb_cfg = 0x1,
>> + .l1_block =
>> IPU7P5_IS_MMU_M1_L1_BLOCKNR_REG,
>> + .l2_block =
>> IPU7P5_IS_MMU_M1_L2_BLOCKNR_REG,
>> + .nr_l1streams =
>> IPU7P5_IS_MMU_M1_STREAM_NUM,
>> + .nr_l2streams =
>> IPU7P5_IS_MMU_M1_STREAM_NUM,
>> + .l1_block_sz = {
>> + 0x00000000,
>> + 0x00000002,
>> + 0x00000004,
>> + 0x00000006,
>> + 0x00000008,
>> + 0x0000000a,
>> + 0x0000000c,
>> + 0x0000000e,
>> + 0x00000010,
>> + 0x00000012,
>> + 0x00000014,
>> + 0x00000016,
>> + 0x00000018,
>> + 0x0000001a,
>> + 0x0000001c,
>> + 0x0000001e,
>> + },
>> + .l2_block_sz = {
>> + 0x00000000,
>> + 0x00000002,
>> + 0x00000004,
>> + 0x00000006,
>> + 0x00000008,
>> + 0x0000000a,
>> + 0x0000000c,
>> + 0x0000000e,
>> + 0x00000010,
>> + 0x00000012,
>> + 0x00000014,
>> + 0x00000016,
>> + 0x00000018,
>> + 0x0000001a,
>> + 0x0000001c,
>> + 0x0000001e,
>> + },
>> + .zlx_nr = IPU7P5_IS_ZLX_M1_NUM,
>> + .zlx_axi_pool = {
>> + 0x00000f20,
>> + },
>> + .zlx_en = {
>> + 1, 1, 1, 1, 1, 1, 1, 1,
>> + 1, 1, 1, 1, 1, 1, 1, 1,
>> + },
>> + .zlx_conf = {
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + },
>> + .uao_p_num =
>> IPU7P5_IS_UAO_M1_WR_PLANENUM,
>> + .uao_p2tlb = {
>> + 0x00000045,
>> + 0x00000046,
>> + 0x00000047,
>> + 0x00000048,
>> + 0x00000045,
>> + 0x00000046,
>> + 0x00000047,
>> + 0x00000048,
>> + 0x00000045,
>> + 0x00000046,
>> + 0x00000047,
>> + 0x00000048,
>> + 0x00000045,
>> + 0x00000046,
>> + 0x00000047,
>> + 0x00000048,
>> + },
>> + },
>> + },
>> + .cdc_fifos = 3,
>> + .cdc_fifo_threshold = {6, 8, 2},
>> + .dmem_offset = IPU_ISYS_DMEM_OFFSET,
>> + .spc_offset = IPU_ISYS_SPC_OFFSET,
>> + },
>> + .isys_dma_overshoot = IPU_ISYS_OVERALLOC_MIN,
>> +};
>> +
>> +static struct ipu_psys_internal_pdata ipu7p5_psys_ipdata = {
>> + .hw_variant = {
>> + .offset = IPU_UNIFIED_OFFSET,
>> + .nr_mmus = IPU7P5_PS_MMU_NUM,
>> + .mmu_hw = {
>> + {
>> + .name = "PS_FW_RD",
>> + .offset =
>> IPU7P5_PS_MMU_FW_RD_OFFSET,
>> + .zlx_offset =
>> IPU7P5_PS_ZLX_FW_RD_OFFSET,
>> + .uao_offset =
>> IPU7P5_PS_UAO_FW_RD_OFFSET,
>> + .info_bits = 0x20004001,
>> + .refill = 0x00002726,
>> + .collapse_en_bitmap = 0x1,
>> + .at_sp_arb_cfg = 0x1,
>> + .l1_block =
>> IPU7P5_PS_MMU_FW_RD_L1_BLOCKNR_REG,
>> + .l2_block =
>> IPU7P5_PS_MMU_FW_RD_L2_BLOCKNR_REG,
>> + .nr_l1streams =
>> IPU7P5_PS_MMU_FW_RD_STREAM_NUM,
>> + .nr_l2streams =
>> IPU7P5_PS_MMU_FW_RD_STREAM_NUM,
>> + .l1_block_sz = {
>> + 0x00000000,
>> + 0x00000008,
>> + 0x0000000a,
>> + 0x0000000c,
>> + 0x0000000d,
>> + 0x0000000f,
>> + 0x00000011,
>> + 0x00000012,
>> + 0x00000013,
>> + 0x00000014,
>> + 0x00000016,
>> + 0x00000018,
>> + 0x00000019,
>> + 0x0000001a,
>> + 0x0000001a,
>> + 0x0000001a,
>> + },
>> + .l2_block_sz = {
>> + 0x00000000,
>> + 0x00000002,
>> + 0x00000004,
>> + 0x00000006,
>> + 0x00000008,
>> + 0x0000000a,
>> + 0x0000000c,
>> + 0x0000000e,
>> + 0x00000010,
>> + 0x00000012,
>> + 0x00000014,
>> + 0x00000016,
>> + 0x00000018,
>> + 0x0000001a,
>> + 0x0000001c,
>> + 0x0000001e,
>> + },
>> + .zlx_nr = IPU7P5_PS_ZLX_FW_RD_NUM,
>> + .zlx_axi_pool = {
>> + 0x00000f30,
>> + },
>> + .zlx_en = {
>> + 0, 1, 0, 0, 1, 1, 0, 0,
>> + 0, 1, 1, 0, 0, 0, 0, 0,
>> + },
>> + .zlx_conf = {
>> + 0x00000000,
>> + 0x00010101,
>> + 0x00000000,
>> + 0x00000000,
>> + 0x00010101,
>> + 0x00010101,
>> + 0x00000000,
>> + 0x00000000,
>> + 0x00000000,
>> + 0x00010101,
>> + 0x00010101,
>> + 0x00000000,
>> + 0x00000000,
>> + 0x00000000,
>> + 0x00000000,
>> + 0x00000000,
>> + },
>> + .uao_p_num =
>> IPU7P5_PS_UAO_FW_RD_PLANENUM,
>> + .uao_p2tlb = {
>> + 0x0000002e,
>> + 0x00000035,
>> + 0x00000036,
>> + 0x00000031,
>> + 0x00000037,
>> + 0x00000038,
>> + 0x00000039,
>> + 0x00000032,
>> + 0x00000033,
>> + 0x0000003a,
>> + 0x0000003b,
>> + 0x0000003c,
>> + 0x00000034,
>> + 0x0,
>> + 0x0,
>> + 0x0,
>> + },
>> + },
>> + {
>> + .name = "PS_FW_WR",
>> + .offset =
>> IPU7P5_PS_MMU_FW_WR_OFFSET,
>> + .zlx_offset =
>> IPU7P5_PS_ZLX_FW_WR_OFFSET,
>> + .uao_offset =
>> IPU7P5_PS_UAO_FW_WR_OFFSET,
>> + .info_bits = 0x20003e01,
>> + .refill = 0x00002322,
>> + .collapse_en_bitmap = 0x1,
>> + .at_sp_arb_cfg = 0x1,
>> + .l1_block =
>> IPU7P5_PS_MMU_FW_WR_L1_BLOCKNR_REG,
>> + .l2_block =
>> IPU7P5_PS_MMU_FW_WR_L2_BLOCKNR_REG,
>> + .nr_l1streams =
>> IPU7P5_PS_MMU_FW_WR_STREAM_NUM,
>> + .nr_l2streams =
>> IPU7P5_PS_MMU_FW_WR_STREAM_NUM,
>> + .l1_block_sz = {
>> + 0x00000000,
>> + 0x00000008,
>> + 0x0000000a,
>> + 0x0000000c,
>> + 0x0000000d,
>> + 0x0000000e,
>> + 0x0000000f,
>> + 0x00000010,
>> + 0x00000010,
>> + 0x00000010,
>> + },
>> + .l2_block_sz = {
>> + 0x00000000,
>> + 0x00000002,
>> + 0x00000004,
>> + 0x00000006,
>> + 0x00000008,
>> + 0x0000000a,
>> + 0x0000000c,
>> + 0x0000000e,
>> + 0x00000010,
>> + 0x00000012,
>> + },
>> + .zlx_nr = IPU7P5_PS_ZLX_FW_WR_NUM,
>> + .zlx_axi_pool = {
>> + 0x00000f20,
>> + },
>> + .zlx_en = {
>> + 0, 1, 1, 0, 0, 0, 0, 0, 0,
>> 0,
>> + },
>> + .zlx_conf = {
>> + 0x00000000,
>> + 0x00010101,
>> + 0x00010101,
>> + 0x00000000,
>> + 0x00000000,
>> + 0x00000000,
>> + 0x00000000,
>> + 0x00000000,
>> + 0x00000000,
>> + 0x00000000,
>> + },
>> + .uao_p_num =
>> IPU7P5_PS_UAO_FW_WR_PLANENUM,
>> + .uao_p2tlb = {
>> + 0x0000002e,
>> + 0x0000002f,
>> + 0x00000030,
>> + 0x00000031,
>> + 0x00000032,
>> + 0x00000033,
>> + 0x00000034,
>> + 0x0,
>> + 0x0,
>> + 0x0,
>> + },
>> + },
>> + {
>> + .name = "PS_DATA_RD",
>> + .offset =
>> IPU7P5_PS_MMU_SRT_RD_OFFSET,
>> + .zlx_offset =
>> IPU7P5_PS_ZLX_DATA_RD_OFFSET,
>> + .uao_offset =
>> IPU7P5_PS_UAO_SRT_RD_OFFSET,
>> + .info_bits = 0x20003f01,
>> + .refill = 0x00002524,
>> + .collapse_en_bitmap = 0x1,
>> + .at_sp_arb_cfg = 0x1,
>> + .l1_block =
>> IPU7P5_PS_MMU_SRT_RD_L1_BLOCKNR_REG,
>> + .l2_block =
>> IPU7P5_PS_MMU_SRT_RD_L2_BLOCKNR_REG,
>> + .nr_l1streams =
>> IPU7P5_PS_MMU_SRT_RD_STREAM_NUM,
>> + .nr_l2streams =
>> IPU7P5_PS_MMU_SRT_RD_STREAM_NUM,
>> + .l1_block_sz = {
>> + 0x00000000,
>> + 0x00000004,
>> + 0x00000006,
>> + 0x00000008,
>> + 0x0000000b,
>> + 0x0000000d,
>> + 0x0000000f,
>> + 0x00000013,
>> + 0x00000017,
>> + 0x00000019,
>> + 0x0000001b,
>> + 0x0000001d,
>> + 0x0000001f,
>> + 0x0000002b,
>> + 0x00000033,
>> + 0x0000003f,
>> + 0x00000047,
>> + 0x00000049,
>> + 0x0000004b,
>> + 0x0000004c,
>> + 0x0000004d,
>> + 0x0000004e,
>> + },
>> + .l2_block_sz = {
>> + 0x00000000,
>> + 0x00000002,
>> + 0x00000004,
>> + 0x00000006,
>> + 0x00000008,
>> + 0x0000000a,
>> + 0x0000000c,
>> + 0x0000000e,
>> + 0x00000010,
>> + 0x00000012,
>> + 0x00000014,
>> + 0x00000016,
>> + 0x00000018,
>> + 0x0000001a,
>> + 0x0000001c,
>> + 0x0000001e,
>> + 0x00000020,
>> + 0x00000022,
>> + 0x00000024,
>> + 0x00000026,
>> + 0x00000028,
>> + 0x0000002a,
>> + },
>> + .zlx_nr = IPU7P5_PS_ZLX_DATA_RD_NUM,
>> + .zlx_axi_pool = {
>> + 0x00000f30,
>> + },
>> + .zlx_en = {
>> + 1, 1, 1, 1, 1, 1, 1, 1,
>> + 1, 1, 1, 1, 1, 1, 1, 1,
>> + 1, 1, 0, 0, 0, 0,
>> + },
>> + .zlx_conf = {
>> + 0x00030303,
>> + 0x00010101,
>> + 0x00010101,
>> + 0x00030202,
>> + 0x00010101,
>> + 0x00010101,
>> + 0x00030303,
>> + 0x00030303,
>> + 0x00010101,
>> + 0x00030800,
>> + 0x00030500,
>> + 0x00020101,
>> + 0x00042000,
>> + 0x00031000,
>> + 0x00042000,
>> + 0x00031000,
>> + 0x00020400,
>> + 0x00010101,
>> + 0x00000000,
>> + 0x00000000,
>> + 0x00000000,
>> + 0x00000000,
>> + },
>> + .uao_p_num =
>> IPU7P5_PS_UAO_SRT_RD_PLANENUM,
>> + .uao_p2tlb = {
>> + 0x0000001c,
>> + 0x0000001d,
>> + 0x0000001e,
>> + 0x0000001f,
>> + 0x00000020,
>> + 0x00000021,
>> + 0x00000022,
>> + 0x00000023,
>> + 0x00000024,
>> + 0x00000025,
>> + 0x00000026,
>> + 0x00000027,
>> + 0x00000028,
>> + 0x00000029,
>> + 0x0000002a,
>> + 0x0000002b,
>> + 0x0000002c,
>> + 0x0000002d,
>> + 0x00000000,
>> + 0x00000000,
>> + 0x00000000,
>> + 0x00000000,
>> + },
>> + },
>> + {
>> + .name = "PS_DATA_WR",
>> + .offset =
>> IPU7P5_PS_MMU_SRT_WR_OFFSET,
>> + .zlx_offset =
>> IPU7P5_PS_ZLX_DATA_WR_OFFSET,
>> + .uao_offset =
>> IPU7P5_PS_UAO_SRT_WR_OFFSET,
>> + .info_bits = 0x20003d01,
>> + .refill = 0x00002120,
>> + .collapse_en_bitmap = 0x1,
>> + .at_sp_arb_cfg = 0x1,
>> + .l1_block =
>> IPU7P5_PS_MMU_SRT_WR_L1_BLOCKNR_REG,
>> + .l2_block =
>> IPU7P5_PS_MMU_SRT_WR_L2_BLOCKNR_REG,
>> + .nr_l1streams =
>> IPU7P5_PS_MMU_SRT_WR_STREAM_NUM,
>> + .nr_l2streams =
>> IPU7P5_PS_MMU_SRT_WR_STREAM_NUM,
>> + .l1_block_sz = {
>> + 0x00000000,
>> + 0x00000002,
>> + 0x00000006,
>> + 0x0000000a,
>> + 0x0000000c,
>> + 0x0000000e,
>> + 0x00000010,
>> + 0x00000012,
>> + 0x00000014,
>> + 0x00000016,
>> + 0x00000018,
>> + 0x0000001a,
>> + 0x0000001c,
>> + 0x0000001e,
>> + 0x00000020,
>> + 0x00000022,
>> + 0x00000024,
>> + 0x00000028,
>> + 0x0000002a,
>> + 0x00000036,
>> + 0x0000003e,
>> + 0x00000040,
>> + 0x00000042,
>> + 0x0000004e,
>> + 0x00000056,
>> + 0x0000005c,
>> + 0x00000068,
>> + 0x00000070,
>> + 0x00000076,
>> + 0x00000077,
>> + 0x00000078,
>> + 0x00000079,
>> + },
>> + .l2_block_sz = {
>> + 0x00000000,
>> + 0x00000002,
>> + 0x00000006,
>> + 0x0000000a,
>> + 0x0000000c,
>> + 0x0000000e,
>> + 0x00000010,
>> + 0x00000012,
>> + 0x00000014,
>> + 0x00000016,
>> + 0x00000018,
>> + 0x0000001a,
>> + 0x0000001c,
>> + 0x0000001e,
>> + 0x00000020,
>> + 0x00000022,
>> + 0x00000024,
>> + 0x00000028,
>> + 0x0000002a,
>> + 0x00000036,
>> + 0x0000003e,
>> + 0x00000040,
>> + 0x00000042,
>> + 0x0000004e,
>> + 0x00000056,
>> + 0x0000005c,
>> + 0x00000068,
>> + 0x00000070,
>> + 0x00000076,
>> + 0x00000077,
>> + 0x00000078,
>> + 0x00000079,
>> + },
>> + .zlx_nr = IPU7P5_PS_ZLX_DATA_WR_NUM,
>> + .zlx_axi_pool = {
>> + 0x00000f50,
>> + },
>> + .zlx_en = {
>> + 1, 1, 1, 1, 1, 1, 1, 1,
>> + 0, 0, 1, 1, 1, 1, 1, 1,
>> + 1, 1, 1, 1, 1, 1, 1, 1,
>> + 1, 1, 1, 1, 0, 0, 0, 0,
>> + },
>> + .zlx_conf = {
>> + 0x00010102,
>> + 0x00030103,
>> + 0x00030103,
>> + 0x00010101,
>> + 0x00010101,
>> + 0x00030101,
>> + 0x00010101,
>> + 0x38010101,
>> + 0x00000000,
>> + 0x00000000,
>> + 0x38010101,
>> + 0x38010101,
>> + 0x38010101,
>> + 0x38010101,
>> + 0x38010101,
>> + 0x38010101,
>> + 0x00030303,
>> + 0x00010101,
>> + 0x00042000,
>> + 0x00031000,
>> + 0x00010101,
>> + 0x00010101,
>> + 0x00042000,
>> + 0x00031000,
>> + 0x00031000,
>> + 0x00042000,
>> + 0x00031000,
>> + 0x00031000,
>> + 0x00000000,
>> + 0x00000000,
>> + 0x00000000,
>> + 0x00000000,
>> + },
>> + .uao_p_num =
>> IPU7P5_PS_UAO_SRT_WR_PLANENUM,
>> + .uao_p2tlb = {
>> + 0x00000000,
>> + 0x00000001,
>> + 0x00000002,
>> + 0x00000003,
>> + 0x00000004,
>> + 0x00000005,
>> + 0x00000006,
>> + 0x00000007,
>> + 0x00000008,
>> + 0x00000009,
>> + 0x0000000a,
>> + 0x0000000b,
>> + 0x0000000c,
>> + 0x0000000d,
>> + 0x0000000e,
>> + 0x0000000f,
>> + 0x00000010,
>> + 0x00000011,
>> + 0x00000012,
>> + 0x00000013,
>> + 0x00000014,
>> + 0x00000015,
>> + 0x00000016,
>> + 0x00000017,
>> + 0x00000018,
>> + 0x00000019,
>> + 0x0000001a,
>> + 0x0000001b,
>> + 0x00000000,
>> + 0x00000000,
>> + 0x00000000,
>> + 0x00000000,
>> + },
>> + },
>> + },
>> + .dmem_offset = IPU_PSYS_DMEM_OFFSET,
>> + },
>> +};
>> +
>> +static struct ipu_isys_internal_pdata ipu7_isys_ipdata = {
>> + .csi2 = {
>> + .gpreg = IS_IO_CSI2_GPREGS_BASE,
>> + },
>> + .hw_variant = {
>> + .offset = IPU_UNIFIED_OFFSET,
>> + .nr_mmus = IPU7_IS_MMU_NUM,
>> + .mmu_hw = {
>> + {
>> + .name = "IS_FW_RD",
>> + .offset = IPU7_IS_MMU_FW_RD_OFFSET,
>> + .zlx_offset =
>> IPU7_IS_ZLX_UC_RD_OFFSET,
>> + .uao_offset =
>> IPU7_IS_UAO_UC_RD_OFFSET,
>> + .info_bits = 0x20006701,
>> + .refill = 0x00002726,
>> + .collapse_en_bitmap = 0x0,
>> + .l1_block =
>> IPU7_IS_MMU_FW_RD_L1_BLOCKNR_REG,
>> + .l2_block =
>> IPU7_IS_MMU_FW_RD_L2_BLOCKNR_REG,
>> + .nr_l1streams =
>> IPU7_IS_MMU_FW_RD_STREAM_NUM,
>> + .nr_l2streams =
>> IPU7_IS_MMU_FW_RD_STREAM_NUM,
>> + .l1_block_sz = {
>> + 0x0, 0x8, 0xa,
>> + },
>> + .l2_block_sz = {
>> + 0x0, 0x2, 0x4,
>> + },
>> + .zlx_nr = IPU7_IS_ZLX_UC_RD_NUM,
>> + .zlx_axi_pool = {
>> + 0x00000f30,
>> + },
>> + .zlx_en = {
>> + 0, 0, 0, 0
>> + },
>> + .zlx_conf = {
>> + 0x0, 0x0, 0x0, 0x0,
>> + },
>> + .uao_p_num =
>> IPU7_IS_UAO_UC_RD_PLANENUM,
>> + .uao_p2tlb = {
>> + 0x00000061,
>> + 0x00000064,
>> + 0x00000065,
>> + },
>> + },
>> + {
>> + .name = "IS_FW_WR",
>> + .offset = IPU7_IS_MMU_FW_WR_OFFSET,
>> + .zlx_offset =
>> IPU7_IS_ZLX_UC_WR_OFFSET,
>> + .uao_offset =
>> IPU7_IS_UAO_UC_WR_OFFSET,
>> + .info_bits = 0x20006801,
>> + .refill = 0x00002524,
>> + .collapse_en_bitmap = 0x0,
>> + .l1_block =
>> IPU7_IS_MMU_FW_WR_L1_BLOCKNR_REG,
>> + .l2_block =
>> IPU7_IS_MMU_FW_WR_L2_BLOCKNR_REG,
>> + .nr_l1streams =
>> IPU7_IS_MMU_FW_WR_STREAM_NUM,
>> + .nr_l2streams =
>> IPU7_IS_MMU_FW_WR_STREAM_NUM,
>> + .l1_block_sz = {
>> + 0x0, 0x8, 0xa,
>> + },
>> + .l2_block_sz = {
>> + 0x0, 0x2, 0x4,
>> + },
>> + .zlx_nr = IPU7_IS_ZLX_UC_WR_NUM,
>> + .zlx_axi_pool = {
>> + 0x00000f20,
>> + },
>> + .zlx_en = {
>> + 0, 1, 1, 0,
>> + },
>> + .zlx_conf = {
>> + 0x0,
>> + 0x00010101,
>> + 0x00010101,
>> + },
>> + .uao_p_num =
>> IPU7_IS_UAO_UC_WR_PLANENUM,
>> + .uao_p2tlb = {
>> + 0x00000061,
>> + 0x00000062,
>> + 0x00000063,
>> + },
>> + },
>> + {
>> + .name = "IS_DATA_WR_ISOC",
>> + .offset = IPU7_IS_MMU_M0_OFFSET,
>> + .zlx_offset = IPU7_IS_ZLX_M0_OFFSET,
>> + .uao_offset =
>> IPU7_IS_UAO_M0_WR_OFFSET,
>> + .info_bits = 0x20006601,
>> + .refill = 0x00002120,
>> + .collapse_en_bitmap = 0x0,
>> + .l1_block =
>> IPU7_IS_MMU_M0_L1_BLOCKNR_REG,
>> + .l2_block =
>> IPU7_IS_MMU_M0_L2_BLOCKNR_REG,
>> + .nr_l1streams =
>> IPU7_IS_MMU_M0_STREAM_NUM,
>> + .nr_l2streams =
>> IPU7_IS_MMU_M0_STREAM_NUM,
>> + .l1_block_sz = {
>> + 0x0, 0x3, 0x6, 0x8, 0xa,
>> 0xc, 0xe, 0x10,
>> + },
>> + .l2_block_sz = {
>> + 0x0, 0x2, 0x4, 0x6, 0x8,
>> 0xa, 0xc, 0xe,
>> + },
>> + .zlx_nr = IPU7_IS_ZLX_M0_NUM,
>> + .zlx_axi_pool = {
>> + 0x00000f10,
>> + },
>> + .zlx_en = {
>> + 1, 1, 1, 1, 1, 1, 1, 1,
>> + },
>> + .zlx_conf = {
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010101,
>> + 0x00010101,
>> + 0x00010101,
>> + 0x00010101,
>> + 0x00010101,
>> + 0x00010101,
>> + },
>> + .uao_p_num =
>> IPU7_IS_UAO_M0_WR_PLANENUM,
>> + .uao_p2tlb = {
>> + 0x00000049,
>> + 0x0000004a,
>> + 0x0000004b,
>> + 0x0000004c,
>> + 0x0000004d,
>> + 0x0000004e,
>> + 0x0000004f,
>> + 0x00000050,
>> + },
>> + },
>> + {
>> + .name = "IS_DATA_WR_SNOOP",
>> + .offset = IPU7_IS_MMU_M1_OFFSET,
>> + .zlx_offset = IPU7_IS_ZLX_M1_OFFSET,
>> + .uao_offset =
>> IPU7_IS_UAO_M1_WR_OFFSET,
>> + .info_bits = 0x20006901,
>> + .refill = 0x00002322,
>> + .collapse_en_bitmap = 0x0,
>> + .l1_block =
>> IPU7_IS_MMU_M1_L1_BLOCKNR_REG,
>> + .l2_block =
>> IPU7_IS_MMU_M1_L2_BLOCKNR_REG,
>> + .nr_l1streams =
>> IPU7_IS_MMU_M1_STREAM_NUM,
>> + .nr_l2streams =
>> IPU7_IS_MMU_M1_STREAM_NUM,
>> + .l1_block_sz = {
>> + 0x0, 0x3, 0x6, 0x9, 0xc,
>> + 0xe, 0x10, 0x12, 0x14, 0x16,
>> + 0x18, 0x1a, 0x1c, 0x1e,
>> 0x20,
>> + 0x22,
>> + },
>> + .l2_block_sz = {
>> + 0x0, 0x2, 0x4, 0x6, 0x8,
>> + 0xa, 0xc, 0xe, 0x10, 0x12,
>> + 0x14, 0x16, 0x18, 0x1a,
>> 0x1c,
>> + 0x1e,
>> + },
>> + .zlx_nr = IPU7_IS_ZLX_M1_NUM,
>> + .zlx_axi_pool = {
>> + 0x00000f20,
>> + },
>> + .zlx_en = {
>> + 1, 1, 1, 1, 1, 1, 1, 1,
>> + 1, 1, 1, 1, 1, 1, 1, 1,
>> + },
>> + .zlx_conf = {
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010103,
>> + 0x00010101,
>> + 0x00010101,
>> + 0x00010101,
>> + 0x00010101,
>> + 0x00010101,
>> + 0x00010101,
>> + 0x00010101,
>> + 0x00010101,
>> + },
>> + .uao_p_num =
>> IPU7_IS_UAO_M1_WR_PLANENUM,
>> + .uao_p2tlb = {
>> + 0x00000051,
>> + 0x00000052,
>> + 0x00000053,
>> + 0x00000054,
>> + 0x00000055,
>> + 0x00000056,
>> + 0x00000057,
>> + 0x00000058,
>> + 0x00000059,
>> + 0x0000005a,
>> + 0x0000005b,
>> + 0x0000005c,
>> + 0x0000005d,
>> + 0x0000005e,
>> + 0x0000005f,
>> + 0x00000060,
>> + },
>> + },
>> + },
>> + .cdc_fifos = 3,
>> + .cdc_fifo_threshold = {6, 8, 2},
>> + .dmem_offset = IPU_ISYS_DMEM_OFFSET,
>> + .spc_offset = IPU_ISYS_SPC_OFFSET,
>> + },
>> + .isys_dma_overshoot = IPU_ISYS_OVERALLOC_MIN,
>> +};
>> +
>> +static struct ipu_psys_internal_pdata ipu7_psys_ipdata = {
>> + .hw_variant = {
>> + .offset = IPU_UNIFIED_OFFSET,
>> + .nr_mmus = IPU7_PS_MMU_NUM,
>> + .mmu_hw = {
>> + {
>> + .name = "PS_FW_RD",
>> + .offset = IPU7_PS_MMU_FW_RD_OFFSET,
>> + .zlx_offset =
>> IPU7_PS_ZLX_FW_RD_OFFSET,
>> + .uao_offset =
>> IPU7_PS_UAO_FW_RD_OFFSET,
>> + .info_bits = 0x20004801,
>> + .refill = 0x00002726,
>> + .collapse_en_bitmap = 0x0,
>> + .l1_block =
>> IPU7_PS_MMU_FW_RD_L1_BLOCKNR_REG,
>> + .l2_block =
>> IPU7_PS_MMU_FW_RD_L2_BLOCKNR_REG,
>> + .nr_l1streams =
>> IPU7_PS_MMU_FW_RD_STREAM_NUM,
>> + .nr_l2streams =
>> IPU7_PS_MMU_FW_RD_STREAM_NUM,
>> + .l1_block_sz = {
>> + 0, 0x8, 0xa, 0xc, 0xd,
>> + 0xf, 0x11, 0x12, 0x13, 0x14,
>> + 0x16, 0x18, 0x19, 0x1a,
>> 0x1a,
>> + 0x1a, 0x1a, 0x1a, 0x1a,
>> 0x1a,
>> + },
>> + .l2_block_sz = {
>> + 0x0, 0x2, 0x4, 0x6, 0x8,
>> + 0xa, 0xc, 0xe, 0x10, 0x12,
>> + 0x14, 0x16, 0x18, 0x1a,
>> 0x1c,
>> + 0x1e, 0x20, 0x22, 0x24,
>> 0x26,
>> + },
>> + .zlx_nr = IPU7_PS_ZLX_FW_RD_NUM,
>> + .zlx_axi_pool = {
>> + 0x00000f30,
>> + },
>> + .zlx_en = {
>> + 0, 0, 0, 0, 0, 0, 0, 0,
>> + 0, 0, 0, 0, 0, 0, 0, 0,
>> + },
>> + .zlx_conf = {
>> + 0x0,
>> + },
>> + .uao_p_num =
>> IPU7_PS_UAO_FW_RD_PLANENUM,
>> + .uao_p2tlb = {
>> + 0x00000036,
>> + 0x0000003d,
>> + 0x0000003e,
>> + 0x00000039,
>> + 0x0000003f,
>> + 0x00000040,
>> + 0x00000041,
>> + 0x0000003a,
>> + 0x0000003b,
>> + 0x00000042,
>> + 0x00000043,
>> + 0x00000044,
>> + 0x0000003c,
>> + },
>> + },
>> + {
>> + .name = "PS_FW_WR",
>> + .offset = IPU7_PS_MMU_FW_WR_OFFSET,
>> + .zlx_offset =
>> IPU7_PS_ZLX_FW_WR_OFFSET,
>> + .uao_offset =
>> IPU7_PS_UAO_FW_WR_OFFSET,
>> + .info_bits = 0x20004601,
>> + .refill = 0x00002322,
>> + .collapse_en_bitmap = 0x0,
>> + .l1_block =
>> IPU7_PS_MMU_FW_WR_L1_BLOCKNR_REG,
>> + .l2_block =
>> IPU7_PS_MMU_FW_WR_L2_BLOCKNR_REG,
>> + .nr_l1streams =
>> IPU7_PS_MMU_FW_WR_STREAM_NUM,
>> + .nr_l2streams =
>> IPU7_PS_MMU_FW_WR_STREAM_NUM,
>> + .l1_block_sz = {
>> + 0, 0x8, 0xa, 0xc, 0xd,
>> + 0xe, 0xf, 0x10, 0x10, 0x10,
>> + },
>> + .l2_block_sz = {
>> + 0x0, 0x2, 0x4, 0x6, 0x8,
>> + 0xa, 0xc, 0xe, 0x10, 0x12,
>> + },
>> + .zlx_nr = IPU7_PS_ZLX_FW_WR_NUM,
>> + .zlx_axi_pool = {
>> + 0x00000f20,
>> + },
>> + .zlx_en = {
>> + 0, 1, 1, 0, 0, 0, 0, 0,
>> + 0, 0,
>> + },
>> + .zlx_conf = {
>> + 0x0,
>> + 0x00010101,
>> + 0x00010101,
>> + },
>> + .uao_p_num =
>> IPU7_PS_UAO_FW_WR_PLANENUM,
>> + .uao_p2tlb = {
>> + 0x00000036,
>> + 0x00000037,
>> + 0x00000038,
>> + 0x00000039,
>> + 0x0000003a,
>> + 0x0000003b,
>> + 0x0000003c,
>> + },
>> + },
>> + {
>> + .name = "PS_DATA_RD",
>> + .offset = IPU7_PS_MMU_SRT_RD_OFFSET,
>> + .zlx_offset =
>> IPU7_PS_ZLX_DATA_RD_OFFSET,
>> + .uao_offset =
>> IPU7_PS_UAO_SRT_RD_OFFSET,
>> + .info_bits = 0x20004701,
>> + .refill = 0x00002120,
>> + .collapse_en_bitmap = 0x0,
>> + .l1_block =
>> IPU7_PS_MMU_SRT_RD_L1_BLOCKNR_REG,
>> + .l2_block =
>> IPU7_PS_MMU_SRT_RD_L2_BLOCKNR_REG,
>> + .nr_l1streams =
>> IPU7_PS_MMU_SRT_RD_STREAM_NUM,
>> + .nr_l2streams =
>> IPU7_PS_MMU_SRT_RD_STREAM_NUM,
>> + .l1_block_sz = {
>> + 0x0, 0x4, 0x6, 0x8, 0xb,
>> + 0xd, 0xf, 0x11, 0x13, 0x15,
>> + 0x17, 0x23, 0x2b, 0x37,
>> 0x3f,
>> + 0x41, 0x43, 0x44, 0x45,
>> 0x46,
>> + 0x47, 0x48, 0x49, 0x4a,
>> 0x4b,
>> + 0x4c, 0x4d, 0x4e, 0x4f,
>> 0x50,
>> + 0x51, 0x52, 0x53, 0x55,
>> 0x57,
>> + 0x59, 0x5b, 0x5d, 0x5f,
>> 0x61,
>> + },
>> + .l2_block_sz = {
>> + 0x0, 0x2, 0x4, 0x6, 0x8,
>> + 0xa, 0xc, 0xe, 0x10, 0x12,
>> + 0x14, 0x16, 0x18, 0x1a,
>> 0x1c,
>> + 0x1e, 0x20, 0x22, 0x24,
>> 0x26,
>> + 0x28, 0x2a, 0x2c, 0x2e,
>> 0x30,
>> + 0x32, 0x34, 0x36, 0x38,
>> 0x3a,
>> + 0x3c, 0x3e, 0x40, 0x42,
>> 0x44,
>> + 0x46, 0x48, 0x4a, 0x4c,
>> 0x4e,
>> + },
>> + .zlx_nr = IPU7_PS_ZLX_DATA_RD_NUM,
>> + .zlx_axi_pool = {
>> + 0x00000f30,
>> + },
>> + .zlx_en = {
>> + 1, 1, 1, 1, 1, 1, 1, 1,
>> + 1, 1, 1, 1, 1, 1, 1, 1,
>> + 0, 0, 0, 0, 0, 0, 0, 0,
>> + 0, 0, 0, 0, 0, 0, 0, 0,
>> + },
>> + .zlx_conf = {
>> + 0x00030303,
>> + 0x00010101,
>> + 0x00010101,
>> + 0x00030202,
>> + 0x00010101,
>> + 0x00010101,
>> + 0x00010101,
>> + 0x00030800,
>> + 0x00030500,
>> + 0x00020101,
>> + 0x00042000,
>> + 0x00031000,
>> + 0x00042000,
>> + 0x00031000,
>> + 0x00020400,
>> + 0x00010101,
>> + },
>> + .uao_p_num =
>> IPU7_PS_UAO_SRT_RD_PLANENUM,
>> + .uao_p2tlb = {
>> + 0x00000022,
>> + 0x00000023,
>> + 0x00000024,
>> + 0x00000025,
>> + 0x00000026,
>> + 0x00000027,
>> + 0x00000028,
>> + 0x00000029,
>> + 0x0000002a,
>> + 0x0000002b,
>> + 0x0000002c,
>> + 0x0000002d,
>> + 0x0000002e,
>> + 0x0000002f,
>> + 0x00000030,
>> + 0x00000031,
>> + 0x0, 0x0, 0x0, 0x0, 0x0,
>> 0x0, 0x0, 0x0,
>> + 0x0, 0x0, 0x0, 0x0, 0x0,
>> 0x0, 0x0, 0x0,
>> + 0x0000001e,
>> + 0x0000001f,
>> + 0x00000020,
>> + 0x00000021,
>> + 0x00000032,
>> + 0x00000033,
>> + 0x00000034,
>> + 0x00000035,
>> + },
>> + },
>> + {
>> + .name = "PS_DATA_WR",
>> + .offset = IPU7_PS_MMU_SRT_WR_OFFSET,
>> + .zlx_offset =
>> IPU7_PS_ZLX_DATA_WR_OFFSET,
>> + .uao_offset =
>> IPU7_PS_UAO_SRT_WR_OFFSET,
>> + .info_bits = 0x20004501,
>> + .refill = 0x00002120,
>> + .collapse_en_bitmap = 0x0,
>> + .l1_block =
>> IPU7_PS_MMU_SRT_WR_L1_BLOCKNR_REG,
>> + .l2_block =
>> IPU7_PS_MMU_SRT_WR_L2_BLOCKNR_REG,
>> + .nr_l1streams =
>> IPU7_PS_MMU_SRT_WR_STREAM_NUM,
>> + .nr_l2streams =
>> IPU7_PS_MMU_SRT_WR_STREAM_NUM,
>> + .l1_block_sz = {
>> + 0x0, 0x2, 0x6, 0xa, 0xc,
>> + 0xe, 0x10, 0x12, 0x14, 0x16,
>> + 0x18, 0x1a, 0x1c, 0x1e,
>> 0x20,
>> + 0x22, 0x24, 0x26, 0x32,
>> 0x3a,
>> + 0x3c, 0x3e, 0x4a, 0x52,
>> 0x58,
>> + 0x64, 0x6c, 0x72, 0x7e,
>> 0x86,
>> + 0x8c, 0x8d, 0x8e, 0x8f,
>> 0x90,
>> + 0x91, 0x92, 0x94, 0x96,
>> 0x98,
>> + },
>> + .l2_block_sz = {
>> + 0x0, 0x2, 0x4, 0x6, 0x8,
>> + 0xa, 0xc, 0xe, 0x10, 0x12,
>> + 0x14, 0x16, 0x18, 0x1a,
>> 0x1c,
>> + 0x1e, 0x20, 0x22, 0x24,
>> 0x26,
>> + 0x28, 0x2a, 0x2c, 0x2e,
>> 0x30,
>> + 0x32, 0x34, 0x36, 0x38,
>> 0x3a,
>> + 0x3c, 0x3e, 0x40, 0x42,
>> 0x44,
>> + 0x46, 0x48, 0x4a, 0x4c,
>> 0x4e,
>> + },
>> + .zlx_nr = IPU7_PS_ZLX_DATA_WR_NUM,
>> + .zlx_axi_pool = {
>> + 0x00000f50,
>> + },
>> + .zlx_en = {
>> + 1, 1, 1, 1, 1, 1, 1, 1,
>> + 0, 0, 1, 1, 1, 1, 1, 1,
>> + 1, 1, 1, 1, 1, 1, 1, 1,
>> + 1, 1, 1, 1, 1, 1, 0, 0,
>> + },
>> + .zlx_conf = {
>> + 0x00010102,
>> + 0x00030103,
>> + 0x00030103,
>> + 0x00010101,
>> + 0x00010101,
>> + 0x00030101,
>> + 0x00010101,
>> + 0x38010101,
>> + 0x0,
>> + 0x0,
>> + 0x38010101,
>> + 0x38010101,
>> + 0x38010101,
>> + 0x38010101,
>> + 0x38010101,
>> + 0x38010101,
>> + 0x00010101,
>> + 0x00042000,
>> + 0x00031000,
>> + 0x00010101,
>> + 0x00010101,
>> + 0x00042000,
>> + 0x00031000,
>> + 0x00031000,
>> + 0x00042000,
>> + 0x00031000,
>> + 0x00031000,
>> + 0x00042000,
>> + 0x00031000,
>> + 0x00031000,
>> + 0x0,
>> + 0x0,
>> + },
>> + .uao_p_num =
>> IPU7_PS_UAO_SRT_WR_PLANENUM,
>> + .uao_p2tlb = {
>> + 0x00000000,
>> + 0x00000001,
>> + 0x00000002,
>> + 0x00000003,
>> + 0x00000004,
>> + 0x00000005,
>> + 0x00000006,
>> + 0x00000007,
>> + 0x00000008,
>> + 0x00000009,
>> + 0x0000000a,
>> + 0x0000000b,
>> + 0x0000000c,
>> + 0x0000000d,
>> + 0x0000000e,
>> + 0x0000000f,
>> + 0x00000010,
>> + 0x00000011,
>> + 0x00000012,
>> + 0x00000013,
>> + 0x00000014,
>> + 0x00000015,
>> + 0x00000016,
>> + 0x00000017,
>> + 0x00000018,
>> + 0x00000019,
>> + 0x0000001a,
>> + 0x0000001b,
>> + 0x0000001c,
>> + 0x0000001d,
>> + 0x0, 0x0, 0x0, 0x0, 0x0,
>> 0x0,
>> + 0x0000001e,
>> + 0x0000001f,
>> + 0x00000020,
>> + 0x00000021,
>> + },
>> + },
>> + },
>> + .dmem_offset = IPU_PSYS_DMEM_OFFSET,
>> + },
>> +};
>> +
>> +static struct ipu_isys_internal_pdata ipu8_isys_ipdata = {
>> + .csi2 = {
>> + .gpreg = IPU8_IS_IO_CSI2_GPREGS_BASE,
>> + },
>> + .hw_variant = {
>> + .offset = IPU_UNIFIED_OFFSET,
>> + .nr_mmus = IPU8_IS_MMU_NUM,
>> + .mmu_hw = {
>> + {
>> + .name = "IS_FW_RD",
>> + .offset = IPU8_IS_MMU_FW_RD_OFFSET,
>> + .zlx_offset =
>> IPU8_IS_ZLX_UC_RD_OFFSET,
>> + .uao_offset =
>> IPU8_IS_UAO_UC_RD_OFFSET,
>> + .info_bits = 0x20005101,
>> + .refill = 0x00002726,
>> + .collapse_en_bitmap = 0x1,
>> + .at_sp_arb_cfg = 0x1,
>> + .l1_block =
>> IPU8_IS_MMU_FW_RD_L1_BLOCKNR_REG,
>> + .l2_block =
>> IPU8_IS_MMU_FW_RD_L2_BLOCKNR_REG,
>> + .nr_l1streams =
>> IPU8_IS_MMU_FW_RD_STREAM_NUM,
>> + .nr_l2streams =
>> IPU8_IS_MMU_FW_RD_STREAM_NUM,
>> + .l1_block_sz = {
>> + 0x0, 0x8, 0xa,
>> + },
>> + .l2_block_sz = {
>> + 0x0, 0x2, 0x4,
>> + },
>> + .zlx_nr = IPU8_IS_ZLX_UC_RD_NUM,
>> + .zlx_axi_pool = {
>> + 0x00000f30,
>> + },
>> + .zlx_en = {
>> + 0, 1, 0, 0
>> + },
>> + .zlx_conf = {
>> + 0, 2, 0, 0
>> + },
>> + .uao_p_num =
>> IPU8_IS_UAO_UC_RD_PLANENUM,
>> + .uao_p2tlb = {
>> + 0x00000049,
>> + 0x0000004c,
>> + 0x0000004d,
>> + 0x00000000,
>> + },
>> + },
>> + {
>> + .name = "IS_FW_WR",
>> + .offset = IPU8_IS_MMU_FW_WR_OFFSET,
>> + .zlx_offset =
>> IPU8_IS_ZLX_UC_WR_OFFSET,
>> + .uao_offset =
>> IPU8_IS_UAO_UC_WR_OFFSET,
>> + .info_bits = 0x20005001,
>> + .refill = 0x00002524,
>> + .collapse_en_bitmap = 0x1,
>> + .at_sp_arb_cfg = 0x1,
>> + .l1_block =
>> IPU8_IS_MMU_FW_WR_L1_BLOCKNR_REG,
>> + .l2_block =
>> IPU8_IS_MMU_FW_WR_L2_BLOCKNR_REG,
>> + .nr_l1streams =
>> IPU8_IS_MMU_FW_WR_STREAM_NUM,
>> + .nr_l2streams =
>> IPU8_IS_MMU_FW_WR_STREAM_NUM,
>> + .l1_block_sz = {
>> + 0x0, 0x8, 0xa,
>> + },
>> + .l2_block_sz = {
>> + 0x0, 0x2, 0x4,
>> + },
>> + .zlx_nr = IPU8_IS_ZLX_UC_WR_NUM,
>> + .zlx_axi_pool = {
>> + 0x00000f20,
>> + },
>> + .zlx_en = {
>> + 0, 1, 1, 0,
>> + },
>> + .zlx_conf = {
>> + 0x0,
>> + 0x2,
>> + 0x2,
>> + 0x0,
>> + },
>> + .uao_p_num =
>> IPU8_IS_UAO_UC_WR_PLANENUM,
>> + .uao_p2tlb = {
>> + 0x00000049,
>> + 0x0000004a,
>> + 0x0000004b,
>> + 0x00000000,
>> + },
>> + },
>> + {
>> + .name = "IS_DATA_WR_ISOC",
>> + .offset = IPU8_IS_MMU_M0_OFFSET,
>> + .zlx_offset = IPU8_IS_ZLX_M0_OFFSET,
>> + .uao_offset =
>> IPU8_IS_UAO_M0_WR_OFFSET,
>> + .info_bits = 0x20004e01,
>> + .refill = 0x00002120,
>> + .collapse_en_bitmap = 0x1,
>> + .at_sp_arb_cfg = 0x1,
>> + .l1_block =
>> IPU8_IS_MMU_M0_L1_BLOCKNR_REG,
>> + .l2_block =
>> IPU8_IS_MMU_M0_L2_BLOCKNR_REG,
>> + .nr_l1streams =
>> IPU8_IS_MMU_M0_STREAM_NUM,
>> + .nr_l2streams =
>> IPU8_IS_MMU_M0_STREAM_NUM,
>> + .l1_block_sz = {
>> + 0x00000000,
>> + 0x00000002,
>> + 0x00000004,
>> + 0x00000006,
>> + 0x00000008,
>> + 0x0000000a,
>> + 0x0000000c,
>> + 0x0000000e,
>> + 0x00000010,
>> + 0x00000012,
>> + 0x00000014,
>> + 0x00000016,
>> + 0x00000018,
>> + 0x0000001a,
>> + 0x0000001c,
>> + 0x0000001e,
>> + },
>> + .l2_block_sz = {
>> + 0x00000000,
>> + 0x00000002,
>> + 0x00000004,
>> + 0x00000006,
>> + 0x00000008,
>> + 0x0000000a,
>> + 0x0000000c,
>> + 0x0000000e,
>> + 0x00000010,
>> + 0x00000012,
>> + 0x00000014,
>> + 0x00000016,
>> + 0x00000018,
>> + 0x0000001a,
>> + 0x0000001c,
>> + 0x0000001e,
>> + },
>> + .zlx_nr = IPU8_IS_ZLX_M0_NUM,
>> + .zlx_axi_pool = {
>> + 0x00000f10,
>> + },
>> + .zlx_en = {
>> + 1, 1, 1, 1, 1, 1, 1, 1,
>> + 1, 1, 1, 1, 1, 1, 1, 1,
>> + },
>> + .zlx_conf = {
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + },
>> + .uao_p_num =
>> IPU8_IS_UAO_M0_WR_PLANENUM,
>> + .uao_p2tlb = {
>> + 0x0000003b,
>> + 0x0000003c,
>> + 0x0000003d,
>> + 0x0000003e,
>> + 0x0000003b,
>> + 0x0000003c,
>> + 0x0000003d,
>> + 0x0000003e,
>> + 0x0000003b,
>> + 0x0000003c,
>> + 0x0000003d,
>> + 0x0000003e,
>> + 0x0000003b,
>> + 0x0000003c,
>> + 0x0000003d,
>> + 0x0000003e,
>> + },
>> + },
>> + {
>> + .name = "IS_DATA_WR_SNOOP",
>> + .offset = IPU8_IS_MMU_M1_OFFSET,
>> + .zlx_offset = IPU8_IS_ZLX_M1_OFFSET,
>> + .uao_offset =
>> IPU8_IS_UAO_M1_WR_OFFSET,
>> + .info_bits = 0x20004f01,
>> + .refill = 0x00002322,
>> + .collapse_en_bitmap = 0x1,
>> + .at_sp_arb_cfg = 0x1,
>> + .l1_block =
>> IPU8_IS_MMU_M1_L1_BLOCKNR_REG,
>> + .l2_block =
>> IPU8_IS_MMU_M1_L2_BLOCKNR_REG,
>> + .nr_l1streams =
>> IPU8_IS_MMU_M1_STREAM_NUM,
>> + .nr_l2streams =
>> IPU8_IS_MMU_M1_STREAM_NUM,
>> + .l1_block_sz = {
>> + 0x00000000,
>> + 0x00000002,
>> + 0x00000004,
>> + 0x00000006,
>> + 0x00000008,
>> + 0x0000000a,
>> + 0x0000000c,
>> + 0x0000000e,
>> + 0x00000010,
>> + 0x00000012,
>> + 0x00000014,
>> + 0x00000016,
>> + 0x00000018,
>> + 0x0000001a,
>> + 0x0000001c,
>> + 0x0000001e,
>> + },
>> + .l2_block_sz = {
>> + 0x00000000,
>> + 0x00000002,
>> + 0x00000004,
>> + 0x00000006,
>> + 0x00000008,
>> + 0x0000000a,
>> + 0x0000000c,
>> + 0x0000000e,
>> + 0x00000010,
>> + 0x00000012,
>> + 0x00000014,
>> + 0x00000016,
>> + 0x00000018,
>> + 0x0000001a,
>> + 0x0000001c,
>> + 0x0000001e,
>> + },
>> + .zlx_nr = IPU8_IS_ZLX_M1_NUM,
>> + .zlx_axi_pool = {
>> + 0x00000f20,
>> + },
>> + .zlx_en = {
>> + 1, 1, 1, 1, 1, 1, 1, 1,
>> + 1, 1, 1, 1, 1, 1, 1, 1,
>> + },
>> + .zlx_conf = {
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + },
>> + .uao_p_num =
>> IPU8_IS_UAO_M1_WR_PLANENUM,
>> + .uao_p2tlb = {
>> + 0x0000003f,
>> + 0x00000040,
>> + 0x00000041,
>> + 0x00000042,
>> + 0x0000003f,
>> + 0x00000040,
>> + 0x00000041,
>> + 0x00000042,
>> + 0x0000003f,
>> + 0x00000040,
>> + 0x00000041,
>> + 0x00000042,
>> + 0x0000003f,
>> + 0x00000040,
>> + 0x00000041,
>> + 0x00000042,
>> + },
>> + },
>> + {
>> + .name = "IS_UPIPE",
>> + .offset = IPU8_IS_MMU_UPIPE_OFFSET,
>> + .zlx_offset =
>> IPU8_IS_ZLX_UPIPE_OFFSET,
>> + .uao_offset =
>> IPU8_IS_UAO_UPIPE_OFFSET,
>> + .info_bits = 0x20005201,
>> + .refill = 0x00002928,
>> + .collapse_en_bitmap = 0x1,
>> + .at_sp_arb_cfg = 0x1,
>> + .l1_block =
>> IPU8_IS_MMU_UPIPE_L1_BLOCKNR_REG,
>> + .l2_block =
>> IPU8_IS_MMU_UPIPE_L2_BLOCKNR_REG,
>> + .nr_l1streams =
>> IPU8_IS_MMU_UPIPE_STREAM_NUM,
>> + .nr_l2streams =
>> IPU8_IS_MMU_UPIPE_STREAM_NUM,
>> + .l1_block_sz = {
>> + 0x00000000,
>> + 0x00000002,
>> + 0x00000004,
>> + 0x00000006,
>> + 0x00000008,
>> + 0x0000000a,
>> + },
>> + .l2_block_sz = {
>> + 0x00000000,
>> + 0x00000002,
>> + 0x00000004,
>> + 0x00000006,
>> + 0x00000008,
>> + 0x0000000a,
>> + },
>> + .zlx_nr = IPU8_IS_ZLX_UPIPE_NUM,
>> + .zlx_axi_pool = {
>> + 0x00000f20,
>> + },
>> + .zlx_en = {
>> + 1, 1, 1, 1, 1, 1,
>> + },
>> + .zlx_conf = {
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + 0x3,
>> + },
>> + .uao_p_num =
>> IPU8_IS_UAO_UPIPE_PLANENUM,
>> + .uao_p2tlb = {
>> + 0x00000043,
>> + 0x00000044,
>> + 0x00000045,
>> + 0x00000046,
>> + 0x00000047,
>> + 0x00000048,
>> + },
>> + },
>> + },
>> + .cdc_fifos = 3,
>> + .cdc_fifo_threshold = {6, 8, 2},
>> + .dmem_offset = IPU_ISYS_DMEM_OFFSET,
>> + .spc_offset = IPU_ISYS_SPC_OFFSET,
>> + },
>> + .isys_dma_overshoot = IPU_ISYS_OVERALLOC_MIN,
>> +};
>> +
>> +static struct ipu_psys_internal_pdata ipu8_psys_ipdata = {
>> + .hw_variant = {
>> + .offset = IPU_UNIFIED_OFFSET,
>> + .nr_mmus = IPU8_PS_MMU_NUM,
>> + .mmu_hw = {
>> + {
>> + .name = "PS_FW_RD",
>> + .offset = IPU8_PS_MMU_FW_RD_OFFSET,
>> + .zlx_offset =
>> IPU8_PS_ZLX_FW_RD_OFFSET,
>> + .uao_offset =
>> IPU8_PS_UAO_FW_RD_OFFSET,
>> + .info_bits = 0x20003a01,
>> + .refill = 0x00002726,
>> + .collapse_en_bitmap = 0x1,
>> + .at_sp_arb_cfg = 0x1,
>> + .l1_block =
>> IPU8_PS_MMU_FW_RD_L1_BLOCKNR_REG,
>> + .l2_block =
>> IPU8_PS_MMU_FW_RD_L2_BLOCKNR_REG,
>> + .nr_l1streams =
>> IPU8_PS_MMU_FW_RD_STREAM_NUM,
>> + .nr_l2streams =
>> IPU8_PS_MMU_FW_RD_STREAM_NUM,
>> + .l1_block_sz = {
>> + 0x00000000,
>> + 0x00000008,
>> + 0x0000000a,
>> + 0x0000000e,
>> + 0x00000010,
>> + 0x00000012,
>> + 0x00000014,
>> + 0x00000016,
>> + 0x00000018,
>> + 0x00000018,
>> + 0x00000018,
>> + 0x00000018,
>> + },
>> + .l2_block_sz = {
>> + 0x00000000,
>> + 0x00000002,
>> + 0x00000004,
>> + 0x00000006,
>> + 0x00000008,
>> + 0x0000000a,
>> + 0x0000000c,
>> + 0x0000000e,
>> + 0x00000010,
>> + 0x00000012,
>> + 0x00000014,
>> + 0x00000016,
>> + },
>> + .zlx_nr = IPU8_PS_ZLX_FW_RD_NUM,
>> + .zlx_axi_pool = {
>> + 0x00000f30,
>> + },
>> + .zlx_en = {
>> + 0, 1, 0, 0, 1, 1, 0, 0,
>> + 0, 0, 0, 0,
>> + },
>> + .zlx_conf = {
>> + 0x0,
>> + 0x2,
>> + 0x0,
>> + 0x0,
>> + 0x2,
>> + 0x2,
>> + 0x0,
>> + 0x0,
>> + 0x0,
>> + 0x0,
>> + 0x0,
>> + 0x0,
>> + },
>> + .uao_p_num =
>> IPU8_PS_UAO_FW_RD_PLANENUM,
>> + .uao_p2tlb = {
>> + 0x0000002d,
>> + 0x00000032,
>> + 0x00000033,
>> + 0x00000030,
>> + 0x00000034,
>> + 0x00000035,
>> + 0x00000036,
>> + 0x00000031,
>> + 0x0,
>> + 0x0,
>> + 0x0,
>> + 0x0,
>> + },
>> + },
>> + {
>> + .name = "PS_FW_WR",
>> + .offset = IPU8_PS_MMU_FW_WR_OFFSET,
>> + .zlx_offset =
>> IPU8_PS_ZLX_FW_WR_OFFSET,
>> + .uao_offset =
>> IPU8_PS_UAO_FW_WR_OFFSET,
>> + .info_bits = 0x20003901,
>> + .refill = 0x00002524,
>> + .collapse_en_bitmap = 0x1,
>> + .at_sp_arb_cfg = 0x1,
>> + .l1_block =
>> IPU8_PS_MMU_FW_WR_L1_BLOCKNR_REG,
>> + .l2_block =
>> IPU8_PS_MMU_FW_WR_L2_BLOCKNR_REG,
>> + .nr_l1streams =
>> IPU8_PS_MMU_FW_WR_STREAM_NUM,
>> + .nr_l2streams =
>> IPU8_PS_MMU_FW_WR_STREAM_NUM,
>> + .l1_block_sz = {
>> + 0x00000000,
>> + 0x00000008,
>> + 0x0000000a,
>> + 0x0000000c,
>> + 0x0000000e,
>> + 0x00000010,
>> + 0x00000010,
>> + 0x00000010,
>> + },
>> + .l2_block_sz = {
>> + 0x00000000,
>> + 0x00000002,
>> + 0x00000004,
>> + 0x00000006,
>> + 0x00000008,
>> + 0x0000000a,
>> + 0x0000000c,
>> + 0x0000000e,
>> + },
>> + .zlx_nr = IPU8_PS_ZLX_FW_WR_NUM,
>> + .zlx_axi_pool = {
>> + 0x00000f20,
>> + },
>> + .zlx_en = {
>> + 0, 1, 1, 0, 0, 0, 0, 0,
>> + },
>> + .zlx_conf = {
>> + 0x0, 0x2, 0x2, 0x0,
>> + 0x0, 0x0, 0x0, 0x0,
>> + },
>> + .uao_p_num =
>> IPU8_PS_UAO_FW_WR_PLANENUM,
>> + .uao_p2tlb = {
>> + 0x0000002d,
>> + 0x0000002e,
>> + 0x0000002f,
>> + 0x00000030,
>> + 0x00000031,
>> + 0x0,
>> + 0x0,
>> + 0x0,
>> + },
>> + },
>> + {
>> + .name = "PS_DATA_RD",
>> + .offset = IPU8_PS_MMU_SRT_RD_OFFSET,
>> + .zlx_offset =
>> IPU8_PS_ZLX_DATA_RD_OFFSET,
>> + .uao_offset =
>> IPU8_PS_UAO_SRT_RD_OFFSET,
>> + .info_bits = 0x20003801,
>> + .refill = 0x00002322,
>> + .collapse_en_bitmap = 0x1,
>> + .at_sp_arb_cfg = 0x1,
>> + .l1_block =
>> IPU8_PS_MMU_SRT_RD_L1_BLOCKNR_REG,
>> + .l2_block =
>> IPU8_PS_MMU_SRT_RD_L2_BLOCKNR_REG,
>> + .nr_l1streams =
>> IPU8_PS_MMU_SRT_RD_STREAM_NUM,
>> + .nr_l2streams =
>> IPU8_PS_MMU_SRT_RD_STREAM_NUM,
>> + .l1_block_sz = {
>> + 0x00000000,
>> + 0x00000004,
>> + 0x00000006,
>> + 0x00000008,
>> + 0x0000000c,
>> + 0x0000000e,
>> + 0x00000010,
>> + 0x00000014,
>> + 0x00000018,
>> + 0x0000001c,
>> + 0x0000001e,
>> + 0x00000022,
>> + 0x00000024,
>> + 0x00000026,
>> + 0x00000028,
>> + 0x0000002a,
>> + 0x0000002c,
>> + 0x0000002e,
>> + 0x00000030,
>> + 0x00000032,
>> + 0x00000036,
>> + 0x0000003a,
>> + 0x0000003c,
>> + 0x0000003c,
>> + 0x0000003c,
>> + 0x0000003c,
>> + },
>> + .l2_block_sz = {
>> + 0x00000000,
>> + 0x00000002,
>> + 0x00000004,
>> + 0x00000006,
>> + 0x00000008,
>> + 0x0000000a,
>> + 0x0000000c,
>> + 0x0000000e,
>> + 0x00000010,
>> + 0x00000012,
>> + 0x00000014,
>> + 0x00000016,
>> + 0x00000018,
>> + 0x0000001a,
>> + 0x0000001c,
>> + 0x0000001e,
>> + 0x00000020,
>> + 0x00000022,
>> + 0x00000024,
>> + 0x00000026,
>> + 0x00000028,
>> + 0x0000002a,
>> + 0x0000002c,
>> + 0x0000002e,
>> + 0x00000030,
>> + 0x00000032,
>> + },
>> + .zlx_nr = IPU8_PS_ZLX_DATA_RD_NUM,
>> + .zlx_axi_pool = {
>> + 0x00000f30,
>> + },
>> + .zlx_en = {
>> + 1, 1, 1, 1, 1, 1, 1, 1,
>> + 1, 1, 1, 1, 1, 1, 1, 1,
>> + 1, 1, 1, 1, 1, 1, 0, 0,
>> + 0, 0,
>> + },
>> + .zlx_conf = {
>> + 0x6, 0x3, 0x3, 0x6,
>> + 0x2, 0x2, 0x6, 0x6,
>> + 0x6, 0x3, 0x6, 0x3,
>> + 0x3, 0x2, 0x2, 0x2,
>> + 0x2, 0x2, 0x2, 0x6,
>> + 0x6, 0x3, 0x0, 0x0,
>> + 0x0, 0x0,
>> + },
>> + .uao_p_num =
>> IPU8_PS_UAO_SRT_RD_PLANENUM,
>> + .uao_p2tlb = {
>> + 0x00000017,
>> + 0x00000018,
>> + 0x00000019,
>> + 0x0000001a,
>> + 0x0000001b,
>> + 0x0000001c,
>> + 0x0000001d,
>> + 0x0000001e,
>> + 0x0000001f,
>> + 0x00000020,
>> + 0x00000021,
>> + 0x00000022,
>> + 0x00000023,
>> + 0x00000024,
>> + 0x00000025,
>> + 0x00000026,
>> + 0x00000027,
>> + 0x00000028,
>> + 0x00000029,
>> + 0x0000002a,
>> + 0x0000002b,
>> + 0x0000002c,
>> + 0x0,
>> + 0x0,
>> + 0x0,
>> + 0x0,
>> + },
>> + },
>> + {
>> + .name = "PS_DATA_WR",
>> + .offset = IPU8_PS_MMU_SRT_WR_OFFSET,
>> + .zlx_offset =
>> IPU8_PS_ZLX_DATA_WR_OFFSET,
>> + .uao_offset =
>> IPU8_PS_UAO_SRT_WR_OFFSET,
>> + .info_bits = 0x20003701,
>> + .refill = 0x00002120,
>> + .collapse_en_bitmap = 0x1,
>> + .at_sp_arb_cfg = 0x1,
>> + .l1_block =
>> IPU8_PS_MMU_SRT_WR_L1_BLOCKNR_REG,
>> + .l2_block =
>> IPU8_PS_MMU_SRT_WR_L2_BLOCKNR_REG,
>> + .nr_l1streams =
>> IPU8_PS_MMU_SRT_WR_STREAM_NUM,
>> + .nr_l2streams =
>> IPU8_PS_MMU_SRT_WR_STREAM_NUM,
>> + .l1_block_sz = {
>> + 0x00000000,
>> + 0x00000002,
>> + 0x00000006,
>> + 0x00000008,
>> + 0x0000000a,
>> + 0x0000000c,
>> + 0x0000000e,
>> + 0x00000010,
>> + 0x00000012,
>> + 0x00000014,
>> + 0x00000016,
>> + 0x00000018,
>> + 0x0000001c,
>> + 0x0000001e,
>> + 0x00000022,
>> + 0x00000024,
>> + 0x00000028,
>> + 0x0000002a,
>> + 0x0000002e,
>> + 0x00000030,
>> + 0x00000032,
>> + 0x00000036,
>> + 0x00000038,
>> + 0x0000003a,
>> + 0x0000003a,
>> + 0x0000003a,
>> + },
>> + .l2_block_sz = {
>> + 0x00000000,
>> + 0x00000002,
>> + 0x00000004,
>> + 0x00000006,
>> + 0x00000008,
>> + 0x0000000a,
>> + 0x0000000c,
>> + 0x0000000e,
>> + 0x00000010,
>> + 0x00000012,
>> + 0x00000014,
>> + 0x00000016,
>> + 0x00000018,
>> + 0x0000001a,
>> + 0x0000001c,
>> + 0x0000001e,
>> + 0x00000020,
>> + 0x00000022,
>> + 0x00000024,
>> + 0x00000026,
>> + 0x00000028,
>> + 0x0000002a,
>> + 0x0000002c,
>> + 0x0000002e,
>> + 0x00000030,
>> + 0x00000032,
>> + },
>> + .zlx_nr = IPU8_PS_ZLX_DATA_WR_NUM,
>> + .zlx_axi_pool = {
>> + 0x00000f50,
>> + },
>> + .zlx_en = {
>> + 1, 1, 1, 0, 1, 1, 1, 1,
>> + 1, 1, 1, 1, 1, 1, 1, 1,
>> + 1, 1, 1, 1, 1, 1, 1, 0,
>> + 0, 0,
>> + },
>> + .zlx_conf = {
>> + 0x3,
>> + 0x6,
>> + 0x38000002,
>> + 0x38000000,
>> + 0x3,
>> + 0x38000002,
>> + 0x38000002,
>> + 0x38000002,
>> + 0x38000002,
>> + 0x38000002,
>> + 0x38000002,
>> + 0x6,
>> + 0x3,
>> + 0x6,
>> + 0x3,
>> + 0x6,
>> + 0x3,
>> + 0x6,
>> + 0x3,
>> + 0x3,
>> + 0x6,
>> + 0x3,
>> + 0x3,
>> + 0x0,
>> + 0x0,
>> + 0x0,
>> + },
>> + .uao_p_num =
>> IPU8_PS_UAO_SRT_WR_PLANENUM,
>> + .uao_p2tlb = {
>> + 0x00000000,
>> + 0x00000001,
>> + 0x00000002,
>> + 0x00000003,
>> + 0x00000004,
>> + 0x00000005,
>> + 0x00000006,
>> + 0x00000007,
>> + 0x00000008,
>> + 0x00000009,
>> + 0x0000000a,
>> + 0x0000000b,
>> + 0x0000000c,
>> + 0x0000000d,
>> + 0x0000000e,
>> + 0x0000000f,
>> + 0x00000010,
>> + 0x00000011,
>> + 0x00000012,
>> + 0x00000013,
>> + 0x00000014,
>> + 0x00000015,
>> + 0x00000016,
>> + 0x00000000,
>> + 0x00000000,
>> + 0x00000000,
>> + },
>> + },
>> + },
>> + .dmem_offset = IPU_PSYS_DMEM_OFFSET,
>> + },
>> +};
>> +
>> +static const struct ipu_buttress_ctrl ipu7_isys_buttress_ctrl = {
>> + .subsys_id = IPU_IS,
>> + .ratio = IPU7_IS_FREQ_CTL_DEFAULT_RATIO,
>> + .ratio_shift = IPU_FREQ_CTL_RATIO_SHIFT,
>> + .cdyn = IPU_FREQ_CTL_CDYN,
>> + .cdyn_shift = IPU_FREQ_CTL_CDYN_SHIFT,
>> + .freq_ctl = BUTTRESS_REG_IS_WORKPOINT_REQ,
>> + .pwr_sts_shift = IPU_BUTTRESS_PWR_STATE_IS_PWR_SHIFT,
>> + .pwr_sts_mask = IPU_BUTTRESS_PWR_STATE_IS_PWR_MASK,
>> + .pwr_sts_on = IPU_BUTTRESS_PWR_STATE_UP_DONE,
>> + .pwr_sts_off = IPU_BUTTRESS_PWR_STATE_DN_DONE,
>> + .ovrd_clk = BUTTRESS_OVERRIDE_IS_CLK,
>> + .own_clk_ack = BUTTRESS_OWN_ACK_IS_CLK,
>> +};
>> +
>> +static const struct ipu_buttress_ctrl ipu7_psys_buttress_ctrl = {
>> + .subsys_id = IPU_PS,
>> + .ratio = IPU7_PS_FREQ_CTL_DEFAULT_RATIO,
>> + .ratio_shift = IPU_FREQ_CTL_RATIO_SHIFT,
>> + .cdyn = IPU_FREQ_CTL_CDYN,
>> + .cdyn_shift = IPU_FREQ_CTL_CDYN_SHIFT,
>> + .freq_ctl = BUTTRESS_REG_PS_WORKPOINT_REQ,
>> + .pwr_sts_shift = IPU_BUTTRESS_PWR_STATE_PS_PWR_SHIFT,
>> + .pwr_sts_mask = IPU_BUTTRESS_PWR_STATE_PS_PWR_MASK,
>> + .pwr_sts_on = IPU_BUTTRESS_PWR_STATE_UP_DONE,
>> + .pwr_sts_off = IPU_BUTTRESS_PWR_STATE_DN_DONE,
>> + .ovrd_clk = BUTTRESS_OVERRIDE_PS_CLK,
>> + .own_clk_ack = BUTTRESS_OWN_ACK_PS_CLK,
>> +};
>> +
>> +static const struct ipu_buttress_ctrl ipu8_isys_buttress_ctrl = {
>> + .subsys_id = IPU_IS,
>> + .ratio = IPU8_IS_FREQ_CTL_DEFAULT_RATIO,
>> + .ratio_shift = IPU_FREQ_CTL_RATIO_SHIFT,
>> + .cdyn = IPU_FREQ_CTL_CDYN,
>> + .cdyn_shift = IPU_FREQ_CTL_CDYN_SHIFT,
>> + .freq_ctl = BUTTRESS_REG_IS_WORKPOINT_REQ,
>> + .pwr_sts_shift = IPU_BUTTRESS_PWR_STATE_IS_PWR_SHIFT,
>> + .pwr_sts_mask = IPU_BUTTRESS_PWR_STATE_IS_PWR_MASK,
>> + .pwr_sts_on = IPU_BUTTRESS_PWR_STATE_UP_DONE,
>> + .pwr_sts_off = IPU_BUTTRESS_PWR_STATE_DN_DONE,
>> +};
>> +
>> +static const struct ipu_buttress_ctrl ipu8_psys_buttress_ctrl = {
>> + .subsys_id = IPU_PS,
>> + .ratio = IPU8_PS_FREQ_CTL_DEFAULT_RATIO,
>> + .ratio_shift = IPU_FREQ_CTL_RATIO_SHIFT,
>> + .cdyn = IPU_FREQ_CTL_CDYN,
>> + .cdyn_shift = IPU_FREQ_CTL_CDYN_SHIFT,
>> + .freq_ctl = BUTTRESS_REG_PS_WORKPOINT_REQ,
>> + .pwr_sts_shift = IPU_BUTTRESS_PWR_STATE_PS_PWR_SHIFT,
>> + .pwr_sts_mask = IPU_BUTTRESS_PWR_STATE_PS_PWR_MASK,
>> + .pwr_sts_on = IPU_BUTTRESS_PWR_STATE_UP_DONE,
>> + .pwr_sts_off = IPU_BUTTRESS_PWR_STATE_DN_DONE,
>> + .own_clk_ack = BUTTRESS_OWN_ACK_PS_PLL,
>> +};
>> +
>> +void ipu_internal_pdata_init(struct ipu_isys_internal_pdata
>> *isys_ipdata,
>> + struct ipu_psys_internal_pdata
>> *psys_ipdata)
>> +{
>> + isys_ipdata->csi2.nports = ARRAY_SIZE(ipu7_csi_offsets);
>> + isys_ipdata->csi2.offsets = ipu7_csi_offsets;
>> + isys_ipdata->num_parallel_streams = IPU7_ISYS_NUM_STREAMS;
>> + psys_ipdata->hw_variant.spc_offset = IPU7_PSYS_SPC_OFFSET;
>> +}
>> +
>> +static int ipu7_isys_check_fwnode_graph(struct fwnode_handle
>> *fwnode)
>> +{
>> + struct fwnode_handle *endpoint;
>> +
>> + if (IS_ERR_OR_NULL(fwnode))
>> + return -EINVAL;
>> +
>> + endpoint = fwnode_graph_get_next_endpoint(fwnode, NULL);
>> + if (endpoint) {
>> + fwnode_handle_put(endpoint);
>> + return 0;
>> + }
>> +
>> + return ipu7_isys_check_fwnode_graph(fwnode->secondary);
>> +}
>> +
>> +static struct ipu7_bus_device *
>> +ipu7_isys_init(struct pci_dev *pdev, struct device *parent,
>> + const struct ipu_buttress_ctrl *ctrl, void __iomem
>> *base,
>> + const struct ipu_isys_internal_pdata *ipdata,
>> + unsigned int nr)
>> +{
>> + struct fwnode_handle *fwnode = dev_fwnode(&pdev->dev);
>> + struct ipu7_bus_device *isys_adev;
>> + struct device *dev = &pdev->dev;
>> + struct ipu7_isys_pdata *pdata;
>> + int ret;
>> +
>> + ret = ipu7_isys_check_fwnode_graph(fwnode);
>> + if (ret) {
>> + if (fwnode && !IS_ERR_OR_NULL(fwnode->secondary)) {
>> + dev_err(dev,
>> + "fwnode graph has no endpoints
>> connection\n");
>> + return ERR_PTR(-EINVAL);
>> + }
>> +
>> + ret = ipu_bridge_init(dev, ipu_bridge_parse_ssdb);
>> + if (ret) {
>> + dev_err_probe(dev, ret, "IPU bridge init
>> failed\n");
>> + return ERR_PTR(ret);
>> + }
>> + }
>> +
>> + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
>> + if (!pdata)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + pdata->base = base;
>> + pdata->ipdata = ipdata;
>> +
>> + isys_adev = ipu7_bus_initialize_device(pdev, parent, pdata,
>> ctrl,
>> + IPU_ISYS_NAME);
>> + if (IS_ERR(isys_adev)) {
>> + dev_err_probe(dev, PTR_ERR(isys_adev),
>> + "ipu7_bus_initialize_device isys
>> failed\n");
>> + kfree(pdata);
>> + return ERR_CAST(isys_adev);
>> + }
>> +
>> + isys_adev->mmu = ipu7_mmu_init(dev, base, ISYS_MMID,
>> + &ipdata->hw_variant);
>> + if (IS_ERR(isys_adev->mmu)) {
>> + dev_err_probe(dev, PTR_ERR(isys_adev),
>> + "ipu7_mmu_init(isys_adev->mmu)
>> failed\n");
>> + put_device(&isys_adev->auxdev.dev);
>> + kfree(pdata);
>> + return ERR_CAST(isys_adev->mmu);
>> + }
>> +
>> + isys_adev->mmu->dev = &isys_adev->auxdev.dev;
>> + isys_adev->subsys = IPU_IS;
>> +
>> + ret = ipu7_bus_add_device(isys_adev);
>> + if (ret) {
>> + kfree(pdata);
>> + return ERR_PTR(ret);
>> + }
>> +
>> + return isys_adev;
>> +}
>> +
>> +static struct ipu7_bus_device *
>> +ipu7_psys_init(struct pci_dev *pdev, struct device *parent,
>> + const struct ipu_buttress_ctrl *ctrl, void __iomem
>> *base,
>> + const struct ipu_psys_internal_pdata *ipdata,
>> unsigned int nr)
>> +{
>> + struct ipu7_bus_device *psys_adev;
>> + struct ipu7_psys_pdata *pdata;
>> + int ret;
>> +
>> + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
>> + if (!pdata)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + pdata->base = base;
>> + pdata->ipdata = ipdata;
>> +
>> + psys_adev = ipu7_bus_initialize_device(pdev, parent, pdata,
>> ctrl,
>> + IPU_PSYS_NAME);
>> + if (IS_ERR(psys_adev)) {
>> + dev_err_probe(&pdev->dev, PTR_ERR(psys_adev),
>> + "ipu7_bus_initialize_device psys
>> failed\n");
>> + kfree(pdata);
>> + return ERR_CAST(psys_adev);
>> + }
>> +
>> + psys_adev->mmu = ipu7_mmu_init(&pdev->dev, base, PSYS_MMID,
>> + &ipdata->hw_variant);
>> + if (IS_ERR(psys_adev->mmu)) {
>> + dev_err_probe(&pdev->dev, PTR_ERR(psys_adev),
>> + "ipu7_mmu_init(psys_adev->mmu)
>> failed\n");
>> + put_device(&psys_adev->auxdev.dev);
>> + kfree(pdata);
>> + return ERR_CAST(psys_adev->mmu);
>> + }
>> +
>> + psys_adev->mmu->dev = &psys_adev->auxdev.dev;
>> + psys_adev->subsys = IPU_PS;
>> +
>> + ret = ipu7_bus_add_device(psys_adev);
>> + if (ret) {
>> + kfree(pdata);
>> + return ERR_PTR(ret);
>> + }
>> +
>> + return psys_adev;
>> +}
>> +
>> +static struct ia_gofo_msg_log_info_ts fw_error_log[IPU_SUBSYS_NUM];
>> +void ipu7_dump_fw_error_log(const struct ipu7_bus_device *adev)
>> +{
>> + void __iomem *reg = adev->isp->base + ((adev->subsys ==
>> IPU_IS) ?
>> + BUTTRESS_REG_FW_GP24
>> :
>> + BUTTRESS_REG_FW_GP8);
>> +
>> + memcpy_fromio(&fw_error_log[adev->subsys], reg,
>> + sizeof(fw_error_log[adev->subsys]));
>> +}
>> +EXPORT_SYMBOL_NS_GPL(ipu7_dump_fw_error_log, "INTEL_IPU7");
>> +
>> +static int ipu7_pci_config_setup(struct pci_dev *dev)
>> +{
>> + u16 pci_command;
>> + int ret;
>> +
>> + pci_read_config_word(dev, PCI_COMMAND, &pci_command);
>> + pci_command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
>> + pci_write_config_word(dev, PCI_COMMAND, pci_command);
>> +
>> + ret = pci_enable_msi(dev);
>> + if (ret)
>> + dev_err(&dev->dev, "Failed to enable msi (%d)\n",
>> ret);
>> +
>> + return ret;
>> +}
>> +
>> +static int ipu7_map_fw_code_region(struct ipu7_bus_device *sys,
>> + void *data, size_t size)
>> +{
>> + struct device *dev = &sys->auxdev.dev;
>> + struct ipu7_bus_device *adev = to_ipu7_bus_device(dev);
>> + struct sg_table *sgt = &sys->fw_sgt;
>> + struct ipu7_device *isp = adev->isp;
>> + struct pci_dev *pdev = isp->pdev;
>> + unsigned long n_pages, i;
>> + unsigned long attr = 0;
>> + struct page **pages;
>> + int ret;
>> +
>> + n_pages = PFN_UP(size);
>> +
>> + pages = kmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL);
>> + if (!pages)
>> + return -ENOMEM;
>> +
>> + for (i = 0; i < n_pages; i++) {
>> + struct page *p = vmalloc_to_page(data);
>> +
>> + if (!p) {
>> + ret = -ENODEV;
>> + goto out;
>> + }
>> +
>> + pages[i] = p;
>> + data += PAGE_SIZE;
>> + }
>> +
>> + ret = sg_alloc_table_from_pages(sgt, pages, n_pages, 0,
>> size,
>> + GFP_KERNEL);
>> + if (ret) {
>> + ret = -ENOMEM;
>> + goto out;
>> + }
>> +
>> + if (!isp->secure_mode)
>> + attr |= DMA_ATTR_RESERVE_REGION;
>> +
>> + ret = dma_map_sgtable(&pdev->dev, sgt, DMA_BIDIRECTIONAL,
>> 0);
>> + if (ret < 0) {
>> + dev_err(dev, "map fw code[%lu pages %u nents]
>> failed\n",
>> + n_pages, sgt->nents);
>> + ret = -ENOMEM;
>> + sg_free_table(sgt);
>> + goto out;
>> + }
>> +
>> + ret = ipu7_dma_map_sgtable(sys, sgt, DMA_BIDIRECTIONAL,
>> attr);
>> + if (ret) {
>> + dma_unmap_sgtable(&pdev->dev, sgt,
>> DMA_BIDIRECTIONAL, 0);
>> + sg_free_table(sgt);
>> + goto out;
>> + }
>> +
>> + ipu7_dma_sync_sgtable(sys, sgt);
>> +
>> + dev_dbg(dev, "fw code region mapped at 0x%llx entries %d\n",
>> + sgt->sgl->dma_address, sgt->nents);
>> +
>> +out:
>> + kfree(pages);
>> +
>> + return ret;
>> +}
>> +
>> +static void ipu7_unmap_fw_code_region(struct ipu7_bus_device *sys)
>> +{
>> + struct pci_dev *pdev = sys->isp->pdev;
>> + struct sg_table *sgt = &sys->fw_sgt;
>> +
>> + ipu7_dma_unmap_sgtable(sys, sgt, DMA_BIDIRECTIONAL, 0);
>> + dma_unmap_sgtable(&pdev->dev, sgt, DMA_BIDIRECTIONAL, 0);
>> + sg_free_table(sgt);
>> +}
>> +
>> +static int ipu7_init_fw_code_region_by_sys(struct ipu7_bus_device
>> *sys,
>> + char *sys_name)
>> +{
>> + struct device *dev = &sys->auxdev.dev;
>> + struct ipu7_device *isp = sys->isp;
>> + int ret;
>> +
>> + /* Copy FW binaries to specific location. */
>> + ret = ipu7_cpd_copy_binary(isp->cpd_fw->data, sys_name,
>> + isp->fw_code_region, &sys-
>>> fw_entry);
>> + if (ret) {
>> + dev_err(dev, "%s binary not found.\n", sys_name);
>> + return ret;
>> + }
>> +
>> + ret = pm_runtime_get_sync(dev);
>> + if (ret < 0) {
>> + dev_err(dev, "Failed to get runtime PM\n");
>> + return ret;
>> + }
>> +
>> + ret = ipu7_mmu_hw_init(sys->mmu);
>> + if (ret) {
>> + dev_err(dev, "Failed to set mmu hw\n");
>> + pm_runtime_put(dev);
>> + return ret;
>> + }
>> +
>> + /* Map code region. */
>> + ret = ipu7_map_fw_code_region(sys, isp->fw_code_region,
>> + IPU_FW_CODE_REGION_SIZE);
>> + if (ret)
>> + dev_err(dev, "Failed to map fw code region for
>> %s.\n",
>> + sys_name);
>> +
>> + ipu7_mmu_hw_cleanup(sys->mmu);
>> + pm_runtime_put(dev);
>> +
>> + return ret;
>> +}
>> +
>> +static int ipu7_init_fw_code_region(struct ipu7_device *isp)
>> +{
>> + int ret;
>> +
>> + /*
>> + * Allocate and map memory for FW execution.
>> + * Not required in secure mode, in which FW runs in IMR.
>> + */
>> + isp->fw_code_region = vmalloc(IPU_FW_CODE_REGION_SIZE);
>> + if (!isp->fw_code_region)
>> + return -ENOMEM;
>> +
>> + ret = ipu7_init_fw_code_region_by_sys(isp->isys, "isys");
>> + if (ret)
>> + goto fail_init;
>> +
>> + ret = ipu7_init_fw_code_region_by_sys(isp->psys, "psys");
>> + if (ret)
>> + goto fail_init;
>> +
>> + return 0;
>> +
>> +fail_init:
>> + vfree(isp->fw_code_region);
>> +
>> + return ret;
>> +}
>> +
>> +static int ipu7_pci_probe(struct pci_dev *pdev, const struct
>> pci_device_id *id)
>> +{
>> + struct ipu_buttress_ctrl *isys_ctrl = NULL, *psys_ctrl =
>> NULL;
>> + struct fwnode_handle *fwnode = dev_fwnode(&pdev->dev);
>> + const struct ipu_buttress_ctrl *isys_buttress_ctrl;
>> + const struct ipu_buttress_ctrl *psys_buttress_ctrl;
>> + struct ipu_isys_internal_pdata *isys_ipdata;
>> + struct ipu_psys_internal_pdata *psys_ipdata;
>> + unsigned int dma_mask = IPU_DMA_MASK;
>> + struct device *dev = &pdev->dev;
>> + void __iomem *isys_base = NULL;
>> + void __iomem *psys_base = NULL;
>> + void __iomem *const *iomap;
>> + phys_addr_t phys, pb_phys;
>> + struct ipu7_device *isp;
>> + u32 is_es;
>> + int ret;
>> +
>> + if (!fwnode || fwnode_property_read_u32(fwnode, "is_es",
>> &is_es))
>> + is_es = 0;
>> +
>> + isp = devm_kzalloc(dev, sizeof(*isp), GFP_KERNEL);
>> + if (!isp)
>> + return -ENOMEM;
>> +
>> + dev_set_name(dev, "intel-ipu7");
>> + isp->pdev = pdev;
>> + INIT_LIST_HEAD(&isp->devices);
>> +
>> + ret = pcim_enable_device(pdev);
>> + if (ret)
>> + return dev_err_probe(dev, ret, "Enable PCI device
>> failed\n");
>> +
>> + dev_info(dev, "Device 0x%x (rev: 0x%x)\n",
>> + pdev->device, pdev->revision);
>> +
>> + phys = pci_resource_start(pdev, IPU_PCI_BAR);
>> + pb_phys = pci_resource_start(pdev, IPU_PCI_PBBAR);
>> + dev_info(dev, "IPU7 PCI BAR0 base %llx BAR2 base %llx\n",
>> + phys, pb_phys);
>> +
>> + ret = pcim_iomap_regions(pdev, BIT(IPU_PCI_BAR) |
>> BIT(IPU_PCI_PBBAR),
>> + pci_name(pdev));
>> + if (ret)
>> + return dev_err_probe(dev, ret,
>> + "Failed to I/O memory remapping
>> (%d)\n",
>> + ret);
>> +
>> + iomap = pcim_iomap_table(pdev);
>
> pcim_iomap_table() and pcim_iomap_regions() have been deprecated last
> year. That's also documented in those functions' docstrings. Please
> don't use them anymore.
>
> You can achieve all you need with the simpler pcim_iomap_region()
>
>
>> + if (!iomap)
>> + return dev_err_probe(dev, -ENODEV, "Failed to iomap
>> table\n");
>> +
>> + isp->base = iomap[IPU_PCI_BAR];
>> + isp->pb_base = iomap[IPU_PCI_PBBAR];
>> + dev_info(dev, "IPU7 PCI BAR0 mapped at %p\n BAR2 mapped at
>> %p\n",
>> + isp->base, isp->pb_base);
>> +
>> + pci_set_drvdata(pdev, isp);
>> + pci_set_master(pdev);
>> +
>> + switch (id->device) {
>> + case IPU7_PCI_ID:
>> + isp->hw_ver = IPU_VER_7;
>> + isp->cpd_fw_name = IPU7_FIRMWARE_NAME;
>> + isys_ipdata = &ipu7_isys_ipdata;
>> + psys_ipdata = &ipu7_psys_ipdata;
>> + isys_buttress_ctrl = &ipu7_isys_buttress_ctrl;
>> + psys_buttress_ctrl = &ipu7_psys_buttress_ctrl;
>> + break;
>> + case IPU7P5_PCI_ID:
>> + isp->hw_ver = IPU_VER_7P5;
>> + isp->cpd_fw_name = IPU7P5_FIRMWARE_NAME;
>> + isys_ipdata = &ipu7p5_isys_ipdata;
>> + psys_ipdata = &ipu7p5_psys_ipdata;
>> + isys_buttress_ctrl = &ipu7_isys_buttress_ctrl;
>> + psys_buttress_ctrl = &ipu7_psys_buttress_ctrl;
>> + break;
>> + case IPU8_PCI_ID:
>> + isp->hw_ver = IPU_VER_8;
>> + isp->cpd_fw_name = IPU8_FIRMWARE_NAME;
>> + isys_ipdata = &ipu8_isys_ipdata;
>> + psys_ipdata = &ipu8_psys_ipdata;
>> + isys_buttress_ctrl = &ipu8_isys_buttress_ctrl;
>> + psys_buttress_ctrl = &ipu8_psys_buttress_ctrl;
>> + break;
>> + default:
>> + WARN(1, "Unsupported IPU device");
>> + return -ENODEV;
>> + }
>> +
>> + ipu_internal_pdata_init(isys_ipdata, psys_ipdata);
>> +
>> + isys_base = isp->base + isys_ipdata->hw_variant.offset;
>> + psys_base = isp->base + psys_ipdata->hw_variant.offset;
>> +
>> + ret = dma_set_mask_and_coherent(dev,
>> DMA_BIT_MASK(dma_mask));
>> + if (ret)
>> + return dev_err_probe(dev, ret, "Failed to set DMA
>> mask\n");
>> +
>> + dma_set_max_seg_size(dev, UINT_MAX);
>> +
>> + ret = ipu7_pci_config_setup(pdev);
>> + if (ret)
>> + return ret;
>> +
>> + ret = ipu_buttress_init(isp);
>> + if (ret)
>> + return ret;
>> +
>> + dev_info(dev, "firmware cpd file: %s\n", isp->cpd_fw_name);
>> +
>> + ret = request_firmware(&isp->cpd_fw, isp->cpd_fw_name, dev);
>> + if (ret) {
>> + dev_err_probe(dev, ret,
>> + "Requesting signed firmware %s
>> failed\n",
>> + isp->cpd_fw_name);
>> + goto buttress_exit;
>> + }
>> +
>> + ret = ipu7_cpd_validate_cpd_file(isp, isp->cpd_fw->data,
>> + isp->cpd_fw->size);
>> + if (ret) {
>> + dev_err_probe(dev, ret, "Failed to validate cpd\n");
>> + goto out_ipu_bus_del_devices;
>> + }
>> +
>> + isys_ctrl = devm_kmemdup(dev, isys_buttress_ctrl,
>> + sizeof(*isys_buttress_ctrl),
>> GFP_KERNEL);
>> + if (!isys_ctrl) {
>> + ret = -ENOMEM;
>> + goto out_ipu_bus_del_devices;
>> + }
>> +
>> + isp->isys = ipu7_isys_init(pdev, dev, isys_ctrl, isys_base,
>> + isys_ipdata, 0);
>> + if (IS_ERR(isp->isys)) {
>> + ret = PTR_ERR(isp->isys);
>> + goto out_ipu_bus_del_devices;
>> + }
>> +
>> + psys_ctrl = devm_kmemdup(dev, psys_buttress_ctrl,
>> + sizeof(*psys_buttress_ctrl),
>> GFP_KERNEL);
>> + if (!psys_ctrl) {
>> + ret = -ENOMEM;
>> + goto out_ipu_bus_del_devices;
>> + }
>> +
>> + isp->psys = ipu7_psys_init(pdev, &isp->isys->auxdev.dev,
>> + psys_ctrl, psys_base,
>> + psys_ipdata, 0);
>> + if (IS_ERR(isp->psys)) {
>> + ret = PTR_ERR(isp->psys);
>> + goto out_ipu_bus_del_devices;
>> + }
>> +
>> + ret = devm_request_threaded_irq(dev, pdev->irq,
>> + ipu_buttress_isr,
>> + ipu_buttress_isr_threaded,
>> + IRQF_SHARED, IPU_NAME, isp);
>> + if (ret)
>> + goto out_ipu_bus_del_devices;
>> +
>> + if (!isp->secure_mode) {
>> + ret = ipu7_init_fw_code_region(isp);
>> + if (ret)
>> + goto out_ipu_bus_del_devices;
>> + } else {
>> + ret = pm_runtime_get_sync(&isp->psys->auxdev.dev);
>> + if (ret < 0) {
>> + dev_err(&isp->psys->auxdev.dev,
>> + "Failed to get runtime PM\n");
>> + goto out_ipu_bus_del_devices;
>> + }
>> +
>> + ret = ipu7_mmu_hw_init(isp->psys->mmu);
>> + if (ret) {
>> + dev_err_probe(&isp->pdev->dev, ret,
>> + "Failed to init MMU
>> hardware\n");
>> + goto out_ipu_bus_del_devices;
>> + }
>> +
>> + ret = ipu7_map_fw_code_region(isp->psys,
>> + (void *)isp->cpd_fw-
>>> data,
>> + isp->cpd_fw->size);
>> + if (ret) {
>> + dev_err_probe(&isp->pdev->dev, ret,
>> + "failed to map fw image\n");
>> + goto out_ipu_bus_del_devices;
>> + }
>> +
>> + ret = ipu_buttress_authenticate(isp);
>> + if (ret) {
>> + dev_err_probe(&isp->pdev->dev, ret,
>> + "FW authentication failed\n");
>> + goto out_ipu_bus_del_devices;
>> + }
>> +
>> + ipu7_mmu_hw_cleanup(isp->psys->mmu);
>> + pm_runtime_put(&isp->psys->auxdev.dev);
>> + }
>> +
>> + pm_runtime_put_noidle(dev);
>> + pm_runtime_allow(dev);
>> +
>> + isp->ipu7_bus_ready_to_probe = true;
>> +
>> + return 0;
>> +
>> +out_ipu_bus_del_devices:
>> + if (!IS_ERR_OR_NULL(isp->isys) && isp->isys->fw_sgt.nents)
>> + ipu7_unmap_fw_code_region(isp->isys);
>> + if (!IS_ERR_OR_NULL(isp->psys) && isp->psys->fw_sgt.nents)
>> + ipu7_unmap_fw_code_region(isp->psys);
>> + if (!IS_ERR_OR_NULL(isp->psys) && !IS_ERR_OR_NULL(isp->psys-
>>> mmu))
>> + ipu7_mmu_cleanup(isp->psys->mmu);
>> + if (!IS_ERR_OR_NULL(isp->isys) && !IS_ERR_OR_NULL(isp->isys-
>>> mmu))
>> + ipu7_mmu_cleanup(isp->isys->mmu);
>> + if (!IS_ERR_OR_NULL(isp->psys))
>> + pm_runtime_put(&isp->psys->auxdev.dev);
>> + ipu7_bus_del_devices(pdev);
>> + release_firmware(isp->cpd_fw);
>> +buttress_exit:
>> + ipu_buttress_exit(isp);
>> +
>> + return ret;
>> +}
>> +
>> +static void ipu7_pci_remove(struct pci_dev *pdev)
>> +{
>> + struct ipu7_device *isp = pci_get_drvdata(pdev);
>> +
>> + if (!IS_ERR_OR_NULL(isp->isys) && isp->isys->fw_sgt.nents)
>> + ipu7_unmap_fw_code_region(isp->isys);
>> + if (!IS_ERR_OR_NULL(isp->psys) && isp->psys->fw_sgt.nents)
>> + ipu7_unmap_fw_code_region(isp->psys);
>> +
>> + if (!IS_ERR_OR_NULL(isp->fw_code_region))
>> + vfree(isp->fw_code_region);
>> +
>> + ipu7_bus_del_devices(pdev);
>> +
>> + pm_runtime_forbid(&pdev->dev);
>> + pm_runtime_get_noresume(&pdev->dev);
>> +
>> + pci_release_regions(pdev);
>
> You don't need this if you request with a pcim_ function. The 'm'
> stands for "managed". Those are devres functions that will clean up
> automatically if probe() fails or once remove() is invoked.
>
> Furthermore, you should not mix pcim_ and pci_ functions; at least not
> those.
>
> And even if the pcim_ functions wouldn't do a cleanup, you would leak
> the IO mappings above, since pci_release_regions() just removes the
> region requests, but not the mapping cookies.
>
> I recommend taking a look to the PCI subystem's documentation.
>
>> + pci_disable_device(pdev);
>
> You also don't need this since you used pcim_enable_device(), which
> will disable the device automatically on driver-detach.
Philipp,
Thanks for the review, I also found your talk at FOSDEM, I will
cleanup these APIs.
>
>
> P.
>
>> +
>> + ipu_buttress_exit(isp);
>> +
>> + release_firmware(isp->cpd_fw);
>> +
>> + ipu7_mmu_cleanup(isp->psys->mmu);
>> + ipu7_mmu_cleanup(isp->isys->mmu);
>> +}
>> +
>> +static void ipu7_pci_reset_prepare(struct pci_dev *pdev)
>> +{
>> + struct ipu7_device *isp = pci_get_drvdata(pdev);
>> +
>> + dev_warn(&pdev->dev, "FLR prepare\n");
>> + pm_runtime_forbid(&isp->pdev->dev);
>> +}
>> +
>> +static void ipu7_pci_reset_done(struct pci_dev *pdev)
>> +{
>> + struct ipu7_device *isp = pci_get_drvdata(pdev);
>> +
>> + ipu_buttress_restore(isp);
>> + if (isp->secure_mode)
>> + ipu_buttress_reset_authentication(isp);
>> +
>> + isp->ipc_reinit = true;
>> + pm_runtime_allow(&isp->pdev->dev);
>> +
>> + dev_warn(&pdev->dev, "FLR completed\n");
>> +}
>> +
>> +/*
>> + * PCI base driver code requires driver to provide these to enable
>> + * PCI device level PM state transitions (D0<->D3)
>> + */
>> +static int ipu7_suspend(struct device *dev)
>> +{
>> + return 0;
>> +}
>> +
>> +static int ipu7_resume(struct device *dev)
>> +{
>> + struct pci_dev *pdev = to_pci_dev(dev);
>> + struct ipu7_device *isp = pci_get_drvdata(pdev);
>> + struct ipu_buttress *b = &isp->buttress;
>> + int ret;
>> +
>> + isp->secure_mode = ipu_buttress_get_secure_mode(isp);
>> + dev_info(dev, "IPU7 in %s mode\n",
>> + isp->secure_mode ? "secure" : "non-secure");
>> +
>> + ipu_buttress_restore(isp);
>> +
>> + ret = ipu_buttress_ipc_reset(isp, &b->cse);
>> + if (ret)
>> + dev_err(dev, "IPC reset protocol failed!\n");
>> +
>> + ret = pm_runtime_get_sync(&isp->psys->auxdev.dev);
>> + if (ret < 0) {
>> + dev_err(dev, "Failed to get runtime PM\n");
>> + return 0;
>> + }
>> +
>> + ret = ipu_buttress_authenticate(isp);
>> + if (ret)
>> + dev_err(dev, "FW authentication failed(%d)\n", ret);
>> +
>> + pm_runtime_put(&isp->psys->auxdev.dev);
>> +
>> + return 0;
>> +}
>> +
>> +static int ipu7_runtime_resume(struct device *dev)
>> +{
>> + struct pci_dev *pdev = to_pci_dev(dev);
>> + struct ipu7_device *isp = pci_get_drvdata(pdev);
>> + int ret;
>> +
>> + ipu_buttress_restore(isp);
>> +
>> + if (isp->ipc_reinit) {
>> + struct ipu_buttress *b = &isp->buttress;
>> +
>> + isp->ipc_reinit = false;
>> + ret = ipu_buttress_ipc_reset(isp, &b->cse);
>> + if (ret)
>> + dev_err(dev, "IPC reset protocol
>> failed!\n");
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static const struct dev_pm_ops ipu7_pm_ops = {
>> + SET_SYSTEM_SLEEP_PM_OPS(&ipu7_suspend, &ipu7_resume)
>> + SET_RUNTIME_PM_OPS(&ipu7_suspend, /* Same as in
>> suspend flow */
>> + &ipu7_runtime_resume,
>> + NULL)
>> +};
>> +
>> +static const struct pci_device_id ipu7_pci_tbl[] = {
>> + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, IPU7_PCI_ID)},
>> + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, IPU7P5_PCI_ID)},
>> + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, IPU8_PCI_ID)},
>> + {0,}
>> +};
>> +MODULE_DEVICE_TABLE(pci, ipu7_pci_tbl);
>> +
>> +static const struct pci_error_handlers pci_err_handlers = {
>> + .reset_prepare = ipu7_pci_reset_prepare,
>> + .reset_done = ipu7_pci_reset_done,
>> +};
>> +
>> +static struct pci_driver ipu7_pci_driver = {
>> + .name = IPU_NAME,
>> + .id_table = ipu7_pci_tbl,
>> + .probe = ipu7_pci_probe,
>> + .remove = ipu7_pci_remove,
>> + .driver = {
>> + .pm = &ipu7_pm_ops,
>> + },
>> + .err_handler = &pci_err_handlers,
>> +};
>> +
>> +module_pci_driver(ipu7_pci_driver);
>> +
>> +MODULE_IMPORT_NS("INTEL_IPU_BRIDGE");
>> +MODULE_AUTHOR("Bingbu Cao <bingbu.cao@intel.com>");
>> +MODULE_AUTHOR("Tianshu Qiu <tian.shu.qiu@intel.com>");
>> +MODULE_AUTHOR("Qingwu Zhang <qingwu.zhang@intel.com>");
>> +MODULE_AUTHOR("Intel");
>> +MODULE_LICENSE("GPL");
>> +MODULE_DESCRIPTION("Intel ipu7 pci driver");
>> diff --git a/drivers/media/pci/intel/ipu7/ipu7.h
>> b/drivers/media/pci/intel/ipu7/ipu7.h
>> new file mode 100644
>> index 000000000000..6f5705f403b7
>> --- /dev/null
>> +++ b/drivers/media/pci/intel/ipu7/ipu7.h
>> @@ -0,0 +1,244 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +/*
>> + * Copyright (C) 2013 - 2024 Intel Corporation
>> + */
>> +
>> +#ifndef IPU7_H
>> +#define IPU7_H
>> +
>> +#include <linux/list.h>
>> +#include <linux/pci.h>
>> +#include <linux/types.h>
>> +
>> +#include "ipu7-buttress.h"
>> +
>> +struct ipu7_bus_device;
>> +struct pci_dev;
>> +struct firmware;
>> +
>> +#define IPU_NAME "intel-ipu7"
>> +#define IPU_MEDIA_DEV_MODEL_NAME "ipu7"
>> +
>> +#define IPU7_FIRMWARE_NAME "intel/ipu/ipu7_fw.bin"
>> +#define IPU7P5_FIRMWARE_NAME "intel/ipu/ipu7ptl_fw.bin"
>> +#define IPU8_FIRMWARE_NAME "intel/ipu/ipu8_fw.bin"
>> +
>> +#define IPU7_ISYS_NUM_STREAMS 12
>> +
>> +#define IPU7_PCI_ID 0x645d
>> +#define IPU7P5_PCI_ID 0xb05d
>> +#define IPU8_PCI_ID 0xd719
>> +
>> +#define FW_LOG_BUF_SIZE (2 * 1024 * 1024)
>> +
>> +enum ipu_version {
>> + IPU_VER_INVALID = 0,
>> + IPU_VER_7 = 1,
>> + IPU_VER_7P5 = 2,
>> + IPU_VER_8 = 3,
>> +};
>> +
>> +static inline bool is_ipu7p5(u8 hw_ver)
>> +{
>> + return hw_ver == IPU_VER_7P5;
>> +}
>> +
>> +static inline bool is_ipu7(u8 hw_ver)
>> +{
>> + return hw_ver == IPU_VER_7;
>> +}
>> +
>> +static inline bool is_ipu8(u8 hw_ver)
>> +{
>> + return hw_ver == IPU_VER_8;
>> +}
>> +
>> +#define IPU_UNIFIED_OFFSET 0
>> +
>> +/*
>> + * ISYS DMA can overshoot. For higher resolutions over allocation is
>> one line
>> + * but it must be at minimum 1024 bytes. Value could be different in
>> + * different versions / generations thus provide it via platform
>> data.
>> + */
>> +#define IPU_ISYS_OVERALLOC_MIN 1024
>> +
>> +#define IPU_FW_CODE_REGION_SIZE 0x1000000 /* 16MB */
>> +#define IPU_FW_CODE_REGION_START 0x4000000 /* 64MB */
>> +#define IPU_FW_CODE_REGION_END (IPU_FW_CODE_REGION_START
>> + \
>> + IPU_FW_CODE_REGION_SIZE) /*
>> 80MB */
>> +
>> +struct ipu7_device {
>> + struct pci_dev *pdev;
>> + struct list_head devices;
>> + struct ipu7_bus_device *isys;
>> + struct ipu7_bus_device *psys;
>> + struct ipu_buttress buttress;
>> +
>> + const struct firmware *cpd_fw;
>> + const char *cpd_fw_name;
>> + /* Only for non-secure mode. */
>> + void *fw_code_region;
>> +
>> + void __iomem *base;
>> + void __iomem *pb_base;
>> + u8 hw_ver;
>> + bool ipc_reinit;
>> + bool secure_mode;
>> + bool ipu7_bus_ready_to_probe;
>> +};
>> +
>> +#define IPU_DMA_MASK 39
>> +#define IPU_LIB_CALL_TIMEOUT_MS 2000
>> +#define IPU_PSYS_CMD_TIMEOUT_MS 2000
>> +#define IPU_PSYS_OPEN_CLOSE_TIMEOUT_US 50
>> +#define IPU_PSYS_OPEN_CLOSE_RETRY (10000 /
>> IPU_PSYS_OPEN_CLOSE_TIMEOUT_US)
>> +
>> +#define IPU_ISYS_NAME "isys"
>> +#define IPU_PSYS_NAME "psys"
>> +
>> +#define IPU_MMU_ADDR_BITS 32
>> +/* FW is accessible within the first 2 GiB only in non-secure mode.
>> */
>> +#define IPU_MMU_ADDR_BITS_NON_SECURE 31
>> +
>> +#define IPU7_IS_MMU_NUM 4
>> +#define IPU7_PS_MMU_NUM 4
>> +#define IPU7P5_IS_MMU_NUM 4
>> +#define IPU7P5_PS_MMU_NUM 4
>> +#define IPU8_IS_MMU_NUM 5
>> +#define IPU8_PS_MMU_NUM 4
>> +#define IPU_MMU_MAX_NUM 5 /* max(IS, PS) */
>> +#define IPU_MMU_MAX_TLB_L1_STREAMS 40
>> +#define IPU_MMU_MAX_TLB_L2_STREAMS 40
>> +#define IPU_ZLX_MAX_NUM 32
>> +#define IPU_ZLX_POOL_NUM 8
>> +#define IPU_UAO_PLANE_MAX_NUM 64
>> +
>> +/*
>> + * To maximize the IOSF utlization, IPU need to send requests in
>> bursts.
>> + * At the DMA interface with the buttress, there are CDC FIFOs with
>> burst
>> + * collection capability. CDC FIFO burst collectors have a
>> configurable
>> + * threshold and is configured based on the outcome of performance
>> measurements.
>> + *
>> + * isys has 3 ports with IOSF interface for VC0, VC1 and VC2
>> + * psys has 4 ports with IOSF interface for VC0, VC1w, VC1r and VC2
>> + *
>> + * Threshold values are pre-defined and are arrived at after
>> performance
>> + * evaluations on a type of IPU
>> + */
>> +#define IPU_MAX_VC_IOSF_PORTS 4
>> +
>> +/*
>> + * IPU must configure correct arbitration mechanism related to the
>> IOSF VC
>> + * requests. There are two options per VC0 and VC1 - > 0 means
>> rearbitrate on
>> + * stall and 1 means stall until the request is completed.
>> + */
>> +#define IPU_BTRS_ARB_MODE_TYPE_REARB 0
>> +#define IPU_BTRS_ARB_MODE_TYPE_STALL 1
>> +
>> +/* Currently chosen arbitration mechanism for VC0 */
>> +#define IPU_BTRS_ARB_STALL_MODE_VC0 IPU_BTRS_ARB_MODE_TYPE_REARB
>> +
>> +/* Currently chosen arbitration mechanism for VC1 */
>> +#define IPU_BTRS_ARB_STALL_MODE_VC1 IPU_BTRS_ARB_MODE_TYPE_REARB
>> +
>> +struct ipu7_isys_subdev_pdata;
>> +
>> +/* One L2 entry maps 1024 L1 entries and one L1 entry per page */
>> +#define IPU_MMUV2_L2_RANGE (1024 * PAGE_SIZE)
>> +/* Max L2 blocks per stream */
>> +#define IPU_MMUV2_MAX_L2_BLOCKS 2
>> +/* Max L1 blocks per stream */
>> +#define IPU_MMUV2_MAX_L1_BLOCKS 16
>> +#define IPU_MMUV2_TRASH_RANGE (IPU_MMUV2_L2_RANGE * \
>> + IPU_MMUV2_MAX_L2_BLOCKS)
>> +/* Entries per L1 block */
>> +#define MMUV2_ENTRIES_PER_L1_BLOCK 16
>> +#define MMUV2_TRASH_L1_BLOCK_OFFSET (MMUV2_ENTRIES_PER_L1_BLOCK
>> * PAGE_SIZE)
>> +#define MMUV2_TRASH_L2_BLOCK_OFFSET IPU_MMUV2_L2_RANGE
>> +
>> +struct ipu7_mmu_hw {
>> + char name[32];
>> +
>> + void __iomem *base;
>> + void __iomem *zlx_base;
>> + void __iomem *uao_base;
>> +
>> + u32 offset;
>> + u32 zlx_offset;
>> + u32 uao_offset;
>> +
>> + u32 info_bits;
>> + u32 refill;
>> + u32 collapse_en_bitmap;
>> + u32 at_sp_arb_cfg;
>> +
>> + u32 l1_block;
>> + u32 l2_block;
>> +
>> + u8 nr_l1streams;
>> + u8 nr_l2streams;
>> + u32 l1_block_sz[IPU_MMU_MAX_TLB_L1_STREAMS];
>> + u32 l2_block_sz[IPU_MMU_MAX_TLB_L2_STREAMS];
>> +
>> + u8 zlx_nr;
>> + u32 zlx_axi_pool[IPU_ZLX_POOL_NUM];
>> + u32 zlx_en[IPU_ZLX_MAX_NUM];
>> + u32 zlx_conf[IPU_ZLX_MAX_NUM];
>> +
>> + u32 uao_p_num;
>> + u32 uao_p2tlb[IPU_UAO_PLANE_MAX_NUM];
>> +};
>> +
>> +struct ipu7_mmu_pdata {
>> + u32 nr_mmus;
>> + struct ipu7_mmu_hw mmu_hw[IPU_MMU_MAX_NUM];
>> + int mmid;
>> +};
>> +
>> +struct ipu7_isys_csi2_pdata {
>> + void __iomem *base;
>> +};
>> +
>> +struct ipu7_isys_internal_csi2_pdata {
>> + u32 nports;
>> + u32 *offsets;
>> + u32 gpreg;
>> +};
>> +
>> +struct ipu7_hw_variants {
>> + unsigned long offset;
>> + u32 nr_mmus;
>> + struct ipu7_mmu_hw mmu_hw[IPU_MMU_MAX_NUM];
>> + u8 cdc_fifos;
>> + u8 cdc_fifo_threshold[IPU_MAX_VC_IOSF_PORTS];
>> + u32 dmem_offset;
>> + u32 spc_offset; /* SPC offset from psys base */
>> +};
>> +
>> +struct ipu_isys_internal_pdata {
>> + struct ipu7_isys_internal_csi2_pdata csi2;
>> + struct ipu7_hw_variants hw_variant;
>> + u32 num_parallel_streams;
>> + u32 isys_dma_overshoot;
>> +};
>> +
>> +struct ipu7_isys_pdata {
>> + void __iomem *base;
>> + const struct ipu_isys_internal_pdata *ipdata;
>> +};
>> +
>> +struct ipu_psys_internal_pdata {
>> + struct ipu7_hw_variants hw_variant;
>> +};
>> +
>> +struct ipu7_psys_pdata {
>> + void __iomem *base;
>> + const struct ipu_psys_internal_pdata *ipdata;
>> +};
>> +
>> +int request_cpd_fw(const struct firmware **firmware_p, const char
>> *name,
>> + struct device *device);
>> +void ipu_internal_pdata_init(struct ipu_isys_internal_pdata
>> *isys_ipdata,
>> + struct ipu_psys_internal_pdata
>> *psys_ipdata);
>> +void ipu7_dump_fw_error_log(const struct ipu7_bus_device *adev);
>> +#endif /* IPU7_H */
>
>
--
Best regards,
Bingbu Cao
next prev parent reply other threads:[~2025-02-25 9:44 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-21 7:52 [RFC PATCH 0/7] Intel IPU7 PCI and input system device drivers bingbu.cao
2025-02-21 7:52 ` [RFC PATCH 1/7] media: Rename the IPU PCI device table header and add IPU7 PCI IDs bingbu.cao
2025-02-21 7:52 ` [RFC PATCH 2/7] media: ipu7: add Intel IPU7 PCI device driver bingbu.cao
2025-02-24 14:38 ` Philipp Stanner
2025-02-25 9:39 ` Bingbu Cao [this message]
2025-02-27 4:06 ` Bingbu Cao
2025-03-03 15:01 ` Philipp Stanner
2025-03-03 15:18 ` Philipp Stanner
2025-02-26 10:00 ` Philipp Stanner
2025-02-27 3:47 ` Bingbu Cao
2025-02-21 7:52 ` [RFC PATCH 3/7] media: ipu7: add IPU7 DMA APIs and MMU mapping bingbu.cao
2025-03-03 16:13 ` Bjorn Helgaas
2025-02-21 7:52 ` [RFC PATCH 4/7] media: ipu7: add firmware parse, syscom interface and boot sequence bingbu.cao
2025-02-21 7:52 ` [RFC PATCH 5/7] media: ipu7: add IPU7 firmware ABI headers bingbu.cao
2025-02-21 7:52 ` [RFC PATCH 6/7] media: ipu7: add IPU7 input system device driver bingbu.cao
2025-02-21 7:52 ` [RFC PATCH 7/7] media: ipu7: add Makefile and Kconfig for IPU7 bingbu.cao
2025-02-25 5:55 ` Bingbu Cao
2025-02-21 12:55 ` [RFC PATCH 0/7] Intel IPU7 PCI and input system device drivers Sakari Ailus
2025-04-09 20:23 ` Laurent Pinchart
2025-03-03 16:23 ` Bjorn Helgaas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=83c9c01e-8025-5d19-1750-5cb68dd4de83@linux.intel.com \
--to=bingbu.cao@linux.intel.com \
--cc=bingbu.cao@intel.com \
--cc=daxing.li@intel.com \
--cc=hans@hansg.org \
--cc=hao.yao@intel.com \
--cc=hdegoede@redhat.com \
--cc=jerry.w.hu@intel.com \
--cc=linux-media@vger.kernel.org \
--cc=phasta@kernel.org \
--cc=sakari.ailus@linux.intel.com \
--cc=stanislaw.gruszka@linux.intel.com \
--cc=tian.shu.qiu@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox