#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
#define IPU_ISYS_OVERALLOC_MIN 1024
#define IPU_FW_CODE_REGION_SIZE 0x1000000
#define IPU_FW_CODE_REGION_START 0x4000000
#define IPU_FW_CODE_REGION_END (IPU_FW_CODE_REGION_START + \
IPU_FW_CODE_REGION_SIZE)
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;
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
#define IPU_MMU_ADDR_BITS_NON_SECURE 31
#define IPU7_IS_MMU_NUM 4U
#define IPU7_PS_MMU_NUM 4U
#define IPU7P5_IS_MMU_NUM 4U
#define IPU7P5_PS_MMU_NUM 4U
#define IPU8_IS_MMU_NUM 5U
#define IPU8_PS_MMU_NUM 4U
#define IPU_MMU_MAX_NUM 5U
#define IPU_MMU_MAX_TLB_L1_STREAMS 40U
#define IPU_MMU_MAX_TLB_L2_STREAMS 40U
#define IPU_ZLX_MAX_NUM 32U
#define IPU_ZLX_POOL_NUM 8U
#define IPU_UAO_PLANE_MAX_NUM 64U
#define IPU_MAX_VC_IOSF_PORTS 4
#define IPU_BTRS_ARB_MODE_TYPE_REARB 0
#define IPU_BTRS_ARB_MODE_TYPE_STALL 1
#define IPU_BTRS_ARB_STALL_MODE_VC0 IPU_BTRS_ARB_MODE_TYPE_REARB
#define IPU_BTRS_ARB_STALL_MODE_VC1 IPU_BTRS_ARB_MODE_TYPE_REARB
#define IPU_MMUV2_L2_RANGE (1024 * PAGE_SIZE)
#define IPU_MMUV2_MAX_L2_BLOCKS 2
#define IPU_MMUV2_MAX_L1_BLOCKS 16
#define IPU_MMUV2_TRASH_RANGE (IPU_MMUV2_L2_RANGE * \
IPU_MMUV2_MAX_L2_BLOCKS)
#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 const *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;
};
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