1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
|
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2013 - 2025 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 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 /* max(IS, PS) */
#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
/*
* 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
/* 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 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; /* 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 */
|