| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| /* SPDX-License-Identifier: GPL-2.0 */ | ||
| /* Copyright (C) 2013 - 2020 Intel Corporation */ | ||
|
|
||
| #ifndef IPU_MMU_H | ||
| #define IPU_MMU_H | ||
|
|
||
| #include <linux/dma-mapping.h> | ||
|
|
||
| #include "ipu.h" | ||
| #include "ipu-pdata.h" | ||
|
|
||
| #define ISYS_MMID 1 | ||
| #define PSYS_MMID 0 | ||
|
|
||
| /* | ||
| * @pgtbl: virtual address of the l1 page table (one page) | ||
| */ | ||
| struct ipu_mmu_info { | ||
| u32 __iomem *pgtbl; | ||
| dma_addr_t aperture_start; | ||
| dma_addr_t aperture_end; | ||
| unsigned long pgsize_bitmap; | ||
|
|
||
| spinlock_t lock; /* Serialize access to users */ | ||
| struct ipu_dma_mapping *dmap; | ||
| u32 dummy_l2_tbl; | ||
| u32 dummy_page; | ||
| }; | ||
|
|
||
| /* | ||
| * @pgtbl: physical address of the l1 page table | ||
| */ | ||
| struct ipu_mmu { | ||
| struct list_head node; | ||
|
|
||
| struct ipu_mmu_hw *mmu_hw; | ||
| unsigned int nr_mmus; | ||
| int mmid; | ||
|
|
||
| phys_addr_t pgtbl; | ||
| struct device *dev; | ||
|
|
||
| struct ipu_dma_mapping *dmap; | ||
| struct list_head vma_list; | ||
|
|
||
| struct page *trash_page; | ||
| dma_addr_t iova_addr_trash; | ||
|
|
||
| bool ready; | ||
| spinlock_t ready_lock; /* Serialize access to bool ready */ | ||
|
|
||
| void (*tlb_invalidate)(struct ipu_mmu *mmu); | ||
| }; | ||
|
|
||
| struct ipu_mmu *ipu_mmu_init(struct device *dev, | ||
| void __iomem *base, int mmid, | ||
| const struct ipu_hw_variants *hw); | ||
| void ipu_mmu_cleanup(struct ipu_mmu *mmu); | ||
| int ipu_mmu_hw_init(struct ipu_mmu *mmu); | ||
| int ipu_mmu_hw_cleanup(struct ipu_mmu *mmu); | ||
| int ipu_mmu_map(struct ipu_mmu_info *mmu_info, unsigned long iova, | ||
| phys_addr_t paddr, size_t size); | ||
| size_t ipu_mmu_unmap(struct ipu_mmu_info *mmu_info, unsigned long iova, | ||
| size_t size); | ||
| phys_addr_t ipu_mmu_iova_to_phys(struct ipu_mmu_info *mmu_info, | ||
| dma_addr_t iova); | ||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,251 @@ | ||
| /* SPDX-License-Identifier: GPL-2.0 */ | ||
| /* Copyright (C) 2013 - 2020 Intel Corporation */ | ||
|
|
||
| #ifndef IPU_PDATA_H | ||
| #define IPU_PDATA_H | ||
|
|
||
| #define IPU_MMU_NAME IPU_NAME "-mmu" | ||
| #define IPU_ISYS_CSI2_NAME IPU_NAME "-csi2" | ||
| #define IPU_ISYS_NAME IPU_NAME "-isys" | ||
| #define IPU_PSYS_NAME IPU_NAME "-psys" | ||
| #define IPU_BUTTRESS_NAME IPU_NAME "-buttress" | ||
|
|
||
| #define IPU_MMU_MAX_DEVICES 4 | ||
| #define IPU_MMU_ADDRESS_BITS 32 | ||
| /* The firmware is accessible within the first 2 GiB only in non-secure mode. */ | ||
| #define IPU_MMU_ADDRESS_BITS_NON_SECURE 31 | ||
|
|
||
| #define IPU_MMU_MAX_TLB_L1_STREAMS 32 | ||
| #define IPU_MMU_MAX_TLB_L2_STREAMS 32 | ||
| #define IPU_MAX_LI_BLOCK_ADDR 128 | ||
| #define IPU_MAX_L2_BLOCK_ADDR 64 | ||
|
|
||
| #define IPU_ISYS_MAX_CSI2_LEGACY_PORTS 4 | ||
| #define IPU_ISYS_MAX_CSI2_COMBO_PORTS 2 | ||
|
|
||
| #define IPU_MAX_FRAME_COUNTER 0xff | ||
|
|
||
| /* | ||
| * 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 IPU4 | ||
| */ | ||
| #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 ipu_isys_subdev_pdata; | ||
|
|
||
| /* | ||
| * MMU Invalidation HW bug workaround by ZLW mechanism | ||
| * | ||
| * IPU4 MMUV2 has a bug in the invalidation mechanism which might result in | ||
| * wrong translation or replication of the translation. This will cause data | ||
| * corruption. So we cannot directly use the MMU V2 invalidation registers | ||
| * to invalidate the MMU. Instead, whenever an invalidate is called, we need to | ||
| * clear the TLB by evicting all the valid translations by filling it with trash | ||
| * buffer (which is guaranteed not to be used by any other processes). ZLW is | ||
| * used to fill the L1 and L2 caches with the trash buffer translations. ZLW | ||
| * or Zero length write, is pre-fetch mechanism to pre-fetch the pages in | ||
| * advance to the L1 and L2 caches without triggering any memory operations. | ||
| * | ||
| * In MMU V2, L1 -> 16 streams and 64 blocks, maximum 16 blocks per stream | ||
| * One L1 block has 16 entries, hence points to 16 * 4K pages | ||
| * L2 -> 16 streams and 32 blocks. 2 blocks per streams | ||
| * One L2 block maps to 1024 L1 entries, hence points to 4MB address range | ||
| * 2 blocks per L2 stream means, 1 stream points to 8MB range | ||
| * | ||
| * As we need to clear the caches and 8MB being the biggest cache size, we need | ||
| * to have trash buffer which points to 8MB address range. As these trash | ||
| * buffers are not used for any memory transactions, we need only the least | ||
| * amount of physical memory. So we reserve 8MB IOVA address range but only | ||
| * one page is reserved from physical memory. Each of this 8MB IOVA address | ||
| * range is then mapped to the same physical memory page. | ||
| */ | ||
| /* 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 | ||
|
|
||
| /* | ||
| * In some of the IPU4 MMUs, there is provision to configure L1 and L2 page | ||
| * table caches. Both these L1 and L2 caches are divided into multiple sections | ||
| * called streams. There is maximum 16 streams for both caches. Each of these | ||
| * sections are subdivided into multiple blocks. When nr_l1streams = 0 and | ||
| * nr_l2streams = 0, means the MMU is of type MMU_V1 and do not support | ||
| * L1/L2 page table caches. | ||
| * | ||
| * L1 stream per block sizes are configurable and varies per usecase. | ||
| * L2 has constant block sizes - 2 blocks per stream. | ||
| * | ||
| * MMU1 support pre-fetching of the pages to have less cache lookup misses. To | ||
| * enable the pre-fetching, MMU1 AT (Address Translator) device registers | ||
| * need to be configured. | ||
| * | ||
| * There are four types of memory accesses which requires ZLW configuration. | ||
| * ZLW(Zero Length Write) is a mechanism to enable VT-d pre-fetching on IOMMU. | ||
| * | ||
| * 1. Sequential Access or 1D mode | ||
| * Set ZLW_EN -> 1 | ||
| * set ZLW_PAGE_CROSS_1D -> 1 | ||
| * Set ZLW_N to "N" pages so that ZLW will be inserte N pages ahead where | ||
| * N is pre-defined and hardcoded in the platform data | ||
| * Set ZLW_2D -> 0 | ||
| * | ||
| * 2. ZLW 2D mode | ||
| * Set ZLW_EN -> 1 | ||
| * set ZLW_PAGE_CROSS_1D -> 1, | ||
| * Set ZLW_N -> 0 | ||
| * Set ZLW_2D -> 1 | ||
| * | ||
| * 3. ZLW Enable (no 1D or 2D mode) | ||
| * Set ZLW_EN -> 1 | ||
| * set ZLW_PAGE_CROSS_1D -> 0, | ||
| * Set ZLW_N -> 0 | ||
| * Set ZLW_2D -> 0 | ||
| * | ||
| * 4. ZLW disable | ||
| * Set ZLW_EN -> 0 | ||
| * set ZLW_PAGE_CROSS_1D -> 0, | ||
| * Set ZLW_N -> 0 | ||
| * Set ZLW_2D -> 0 | ||
| * | ||
| * To configure the ZLW for the above memory access, four registers are | ||
| * available. Hence to track these four settings, we have the following entries | ||
| * in the struct ipu_mmu_hw. Each of these entries are per stream and | ||
| * available only for the L1 streams. | ||
| * | ||
| * a. l1_zlw_en -> To track zlw enabled per stream (ZLW_EN) | ||
| * b. l1_zlw_1d_mode -> Track 1D mode per stream. ZLW inserted at page boundary | ||
| * c. l1_ins_zlw_ahead_pages -> to track how advance the ZLW need to be inserted | ||
| * Insert ZLW request N pages ahead address. | ||
| * d. l1_zlw_2d_mode -> To track 2D mode per stream (ZLW_2D) | ||
| * | ||
| * | ||
| * Currently L1/L2 streams, blocks, AT ZLW configurations etc. are pre-defined | ||
| * as per the usecase specific calculations. Any change to this pre-defined | ||
| * table has to happen in sync with IPU4 FW. | ||
| */ | ||
| struct ipu_mmu_hw { | ||
| union { | ||
| unsigned long offset; | ||
| void __iomem *base; | ||
| }; | ||
| unsigned int info_bits; | ||
| u8 nr_l1streams; | ||
| /* | ||
| * L1 has variable blocks per stream - total of 64 blocks and maximum of | ||
| * 16 blocks per stream. Configurable by using the block start address | ||
| * per stream. Block start address is calculated from the block size | ||
| */ | ||
| u8 l1_block_sz[IPU_MMU_MAX_TLB_L1_STREAMS]; | ||
| /* Is ZLW is enabled in each stream */ | ||
| bool l1_zlw_en[IPU_MMU_MAX_TLB_L1_STREAMS]; | ||
| bool l1_zlw_1d_mode[IPU_MMU_MAX_TLB_L1_STREAMS]; | ||
| u8 l1_ins_zlw_ahead_pages[IPU_MMU_MAX_TLB_L1_STREAMS]; | ||
| bool l1_zlw_2d_mode[IPU_MMU_MAX_TLB_L1_STREAMS]; | ||
|
|
||
| u32 l1_stream_id_reg_offset; | ||
| u32 l2_stream_id_reg_offset; | ||
|
|
||
| u8 nr_l2streams; | ||
| /* | ||
| * L2 has fixed 2 blocks per stream. Block address is calculated | ||
| * from the block size | ||
| */ | ||
| u8 l2_block_sz[IPU_MMU_MAX_TLB_L2_STREAMS]; | ||
| /* flag to track if WA is needed for successive invalidate HW bug */ | ||
| bool insert_read_before_invalidate; | ||
| /* flag to track if zlw based mmu invalidation is needed */ | ||
| bool zlw_invalidate; | ||
| }; | ||
|
|
||
| struct ipu_mmu_pdata { | ||
| unsigned int nr_mmus; | ||
| struct ipu_mmu_hw mmu_hw[IPU_MMU_MAX_DEVICES]; | ||
| int mmid; | ||
| }; | ||
|
|
||
| struct ipu_isys_csi2_pdata { | ||
| void __iomem *base; | ||
| }; | ||
|
|
||
| #define IPU_EV_AUTO 0xff | ||
|
|
||
| struct ipu_isys_internal_csi2_pdata { | ||
| unsigned int nports; | ||
| unsigned int *offsets; | ||
| }; | ||
|
|
||
| struct ipu_isys_internal_tpg_pdata { | ||
| unsigned int ntpgs; | ||
| unsigned int *offsets; | ||
| unsigned int *sels; | ||
| }; | ||
|
|
||
| /* | ||
| * One place to handle all the IPU HW variations | ||
| */ | ||
| struct ipu_hw_variants { | ||
| unsigned long offset; | ||
| unsigned int nr_mmus; | ||
| struct ipu_mmu_hw mmu_hw[IPU_MMU_MAX_DEVICES]; | ||
| 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 ipu_isys_internal_csi2_pdata csi2; | ||
| struct ipu_isys_internal_tpg_pdata tpg; | ||
| struct ipu_hw_variants hw_variant; | ||
| u32 num_parallel_streams; | ||
| u32 isys_dma_overshoot; | ||
| }; | ||
|
|
||
| struct ipu_isys_pdata { | ||
| void __iomem *base; | ||
| const struct ipu_isys_internal_pdata *ipdata; | ||
| }; | ||
|
|
||
| struct ipu_psys_internal_pdata { | ||
| struct ipu_hw_variants hw_variant; | ||
| }; | ||
|
|
||
| struct ipu_psys_pdata { | ||
| void __iomem *base; | ||
| const struct ipu_psys_internal_pdata *ipdata; | ||
| }; | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,227 @@ | ||
| // SPDX-License-Identifier: GPL-2.0 | ||
| // Copyright (C) 2013 - 2020 Intel Corporation | ||
|
|
||
| #include <linux/compat.h> | ||
| #include <linux/errno.h> | ||
| #include <linux/uaccess.h> | ||
|
|
||
| #include <uapi/linux/ipu-psys.h> | ||
|
|
||
| #include "ipu-psys.h" | ||
|
|
||
| static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
| { | ||
| long ret = -ENOTTY; | ||
|
|
||
| if (file->f_op->unlocked_ioctl) | ||
| ret = file->f_op->unlocked_ioctl(file, cmd, arg); | ||
|
|
||
| return ret; | ||
| } | ||
|
|
||
| struct ipu_psys_buffer32 { | ||
| u64 len; | ||
| union { | ||
| int fd; | ||
| compat_uptr_t userptr; | ||
| u64 reserved; | ||
| } base; | ||
| u32 data_offset; | ||
| u32 bytes_used; | ||
| u32 flags; | ||
| u32 reserved[2]; | ||
| } __packed; | ||
|
|
||
| struct ipu_psys_command32 { | ||
| u64 issue_id; | ||
| u64 user_token; | ||
| u32 priority; | ||
| compat_uptr_t pg_manifest; | ||
| compat_uptr_t buffers; | ||
| int pg; | ||
| u32 pg_manifest_size; | ||
| u32 bufcount; | ||
| u32 min_psys_freq; | ||
| u32 frame_counter; | ||
| u32 reserved[2]; | ||
| } __packed; | ||
|
|
||
| struct ipu_psys_manifest32 { | ||
| u32 index; | ||
| u32 size; | ||
| compat_uptr_t manifest; | ||
| u32 reserved[5]; | ||
| } __packed; | ||
|
|
||
| static int | ||
| get_ipu_psys_command32(struct ipu_psys_command *kp, | ||
| struct ipu_psys_command32 __user *up) | ||
| { | ||
| compat_uptr_t pgm, bufs; | ||
| bool access_ok; | ||
|
|
||
| access_ok = access_ok(up, sizeof(struct ipu_psys_command32)); | ||
| if (!access_ok || get_user(kp->issue_id, &up->issue_id) || | ||
| get_user(kp->user_token, &up->user_token) || | ||
| get_user(kp->priority, &up->priority) || | ||
| get_user(pgm, &up->pg_manifest) || | ||
| get_user(bufs, &up->buffers) || | ||
| get_user(kp->pg, &up->pg) || | ||
| get_user(kp->pg_manifest_size, &up->pg_manifest_size) || | ||
| get_user(kp->bufcount, &up->bufcount) || | ||
| get_user(kp->min_psys_freq, &up->min_psys_freq) || | ||
| get_user(kp->frame_counter, &up->frame_counter) | ||
| ) | ||
| return -EFAULT; | ||
|
|
||
| kp->pg_manifest = compat_ptr(pgm); | ||
| kp->buffers = compat_ptr(bufs); | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| static int | ||
| get_ipu_psys_buffer32(struct ipu_psys_buffer *kp, | ||
| struct ipu_psys_buffer32 __user *up) | ||
| { | ||
| compat_uptr_t ptr; | ||
| bool access_ok; | ||
|
|
||
| access_ok = access_ok(up, sizeof(struct ipu_psys_buffer32)); | ||
| if (!access_ok || get_user(kp->len, &up->len) || | ||
| get_user(ptr, &up->base.userptr) || | ||
| get_user(kp->data_offset, &up->data_offset) || | ||
| get_user(kp->bytes_used, &up->bytes_used) || | ||
| get_user(kp->flags, &up->flags)) | ||
| return -EFAULT; | ||
|
|
||
| kp->base.userptr = compat_ptr(ptr); | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| static int | ||
| put_ipu_psys_buffer32(struct ipu_psys_buffer *kp, | ||
| struct ipu_psys_buffer32 __user *up) | ||
| { | ||
| bool access_ok; | ||
|
|
||
| access_ok = access_ok(up, sizeof(struct ipu_psys_buffer32)); | ||
| if (!access_ok || put_user(kp->len, &up->len) || | ||
| put_user(kp->base.fd, &up->base.fd) || | ||
| put_user(kp->data_offset, &up->data_offset) || | ||
| put_user(kp->bytes_used, &up->bytes_used) || | ||
| put_user(kp->flags, &up->flags)) | ||
| return -EFAULT; | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| static int | ||
| get_ipu_psys_manifest32(struct ipu_psys_manifest *kp, | ||
| struct ipu_psys_manifest32 __user *up) | ||
| { | ||
| compat_uptr_t ptr; | ||
| bool access_ok; | ||
|
|
||
| access_ok = access_ok(up, sizeof(struct ipu_psys_manifest32)); | ||
| if (!access_ok || get_user(kp->index, &up->index) || | ||
| get_user(kp->size, &up->size) || get_user(ptr, &up->manifest)) | ||
| return -EFAULT; | ||
|
|
||
| kp->manifest = compat_ptr(ptr); | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| static int | ||
| put_ipu_psys_manifest32(struct ipu_psys_manifest *kp, | ||
| struct ipu_psys_manifest32 __user *up) | ||
| { | ||
| compat_uptr_t ptr = (u32)((unsigned long)kp->manifest); | ||
| bool access_ok; | ||
|
|
||
| access_ok = access_ok(up, sizeof(struct ipu_psys_manifest32)); | ||
| if (!access_ok || put_user(kp->index, &up->index) || | ||
| put_user(kp->size, &up->size) || put_user(ptr, &up->manifest)) | ||
| return -EFAULT; | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| #define IPU_IOC_GETBUF32 _IOWR('A', 4, struct ipu_psys_buffer32) | ||
| #define IPU_IOC_PUTBUF32 _IOWR('A', 5, struct ipu_psys_buffer32) | ||
| #define IPU_IOC_QCMD32 _IOWR('A', 6, struct ipu_psys_command32) | ||
| #define IPU_IOC_CMD_CANCEL32 _IOWR('A', 8, struct ipu_psys_command32) | ||
| #define IPU_IOC_GET_MANIFEST32 _IOWR('A', 9, struct ipu_psys_manifest32) | ||
|
|
||
| long ipu_psys_compat_ioctl32(struct file *file, unsigned int cmd, | ||
| unsigned long arg) | ||
| { | ||
| union { | ||
| struct ipu_psys_buffer buf; | ||
| struct ipu_psys_command cmd; | ||
| struct ipu_psys_event ev; | ||
| struct ipu_psys_manifest m; | ||
| } karg; | ||
| int compatible_arg = 1; | ||
| int err = 0; | ||
| void __user *up = compat_ptr(arg); | ||
|
|
||
| switch (cmd) { | ||
| case IPU_IOC_GETBUF32: | ||
| cmd = IPU_IOC_GETBUF; | ||
| break; | ||
| case IPU_IOC_PUTBUF32: | ||
| cmd = IPU_IOC_PUTBUF; | ||
| break; | ||
| case IPU_IOC_QCMD32: | ||
| cmd = IPU_IOC_QCMD; | ||
| break; | ||
| case IPU_IOC_GET_MANIFEST32: | ||
| cmd = IPU_IOC_GET_MANIFEST; | ||
| break; | ||
| } | ||
|
|
||
| switch (cmd) { | ||
| case IPU_IOC_GETBUF: | ||
| case IPU_IOC_PUTBUF: | ||
| err = get_ipu_psys_buffer32(&karg.buf, up); | ||
| compatible_arg = 0; | ||
| break; | ||
| case IPU_IOC_QCMD: | ||
| err = get_ipu_psys_command32(&karg.cmd, up); | ||
| compatible_arg = 0; | ||
| break; | ||
| case IPU_IOC_GET_MANIFEST: | ||
| err = get_ipu_psys_manifest32(&karg.m, up); | ||
| compatible_arg = 0; | ||
| break; | ||
| } | ||
| if (err) | ||
| return err; | ||
|
|
||
| if (compatible_arg) { | ||
| err = native_ioctl(file, cmd, (unsigned long)up); | ||
| } else { | ||
| mm_segment_t old_fs = get_fs(); | ||
|
|
||
| set_fs(KERNEL_DS); | ||
| err = native_ioctl(file, cmd, (unsigned long)&karg); | ||
| set_fs(old_fs); | ||
| } | ||
|
|
||
| if (err) | ||
| return err; | ||
|
|
||
| switch (cmd) { | ||
| case IPU_IOC_GETBUF: | ||
| err = put_ipu_psys_buffer32(&karg.buf, up); | ||
| break; | ||
| case IPU_IOC_GET_MANIFEST: | ||
| err = put_ipu_psys_manifest32(&karg.m, up); | ||
| break; | ||
| } | ||
| return err; | ||
| } | ||
| EXPORT_SYMBOL_GPL(ipu_psys_compat_ioctl32); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,218 @@ | ||
| /* SPDX-License-Identifier: GPL-2.0 */ | ||
| /* Copyright (C) 2013 - 2020 Intel Corporation */ | ||
|
|
||
| #ifndef IPU_PSYS_H | ||
| #define IPU_PSYS_H | ||
|
|
||
| #include <linux/cdev.h> | ||
| #include <linux/workqueue.h> | ||
|
|
||
| #include "ipu.h" | ||
| #include "ipu-pdata.h" | ||
| #include "ipu-fw-psys.h" | ||
| #include "ipu-platform-psys.h" | ||
|
|
||
| #define IPU_PSYS_PG_POOL_SIZE 16 | ||
| #define IPU_PSYS_PG_MAX_SIZE 2048 | ||
| #define IPU_MAX_PSYS_CMD_BUFFERS 32 | ||
| #define IPU_PSYS_EVENT_CMD_COMPLETE IPU_FW_PSYS_EVENT_TYPE_SUCCESS | ||
| #define IPU_PSYS_EVENT_FRAGMENT_COMPLETE IPU_FW_PSYS_EVENT_TYPE_SUCCESS | ||
| #define IPU_PSYS_CLOSE_TIMEOUT_US 50 | ||
| #define IPU_PSYS_CLOSE_TIMEOUT (100000 / IPU_PSYS_CLOSE_TIMEOUT_US) | ||
| #define IPU_PSYS_WORK_QUEUE system_power_efficient_wq | ||
| #define IPU_MAX_RESOURCES 128 | ||
|
|
||
| /* Opaque structure. Do not access fields. */ | ||
| struct ipu_resource { | ||
| u32 id; | ||
| int elements; /* Number of elements available to allocation */ | ||
| unsigned long *bitmap; /* Allocation bitmap, a bit for each element */ | ||
| }; | ||
|
|
||
| enum ipu_resource_type { | ||
| IPU_RESOURCE_DEV_CHN = 0, | ||
| IPU_RESOURCE_EXT_MEM, | ||
| IPU_RESOURCE_DFM | ||
| }; | ||
|
|
||
| /* Allocation of resource(s) */ | ||
| /* Opaque structure. Do not access fields. */ | ||
| struct ipu_resource_alloc { | ||
| enum ipu_resource_type type; | ||
| struct ipu_resource *resource; | ||
| int elements; | ||
| int pos; | ||
| }; | ||
|
|
||
| /* | ||
| * This struct represents all of the currently allocated | ||
| * resources from IPU model. It is used also for allocating | ||
| * resources for the next set of PGs to be run on IPU | ||
| * (ie. those PGs which are not yet being run and which don't | ||
| * yet reserve real IPU resources). | ||
| * Use larger array to cover existing resource quantity | ||
| */ | ||
|
|
||
| /* resource size may need expand for new resource model */ | ||
| struct ipu_psys_resource_pool { | ||
| u32 cells; /* Bitmask of cells allocated */ | ||
| struct ipu_resource dev_channels[16]; | ||
| struct ipu_resource ext_memory[32]; | ||
| struct ipu_resource dfms[16]; | ||
| DECLARE_BITMAP(cmd_queues, 32); | ||
| }; | ||
|
|
||
| /* | ||
| * This struct keeps book of the resources allocated for a specific PG. | ||
| * It is used for freeing up resources from struct ipu_psys_resources | ||
| * when the PG is released from IPU4 (or model of IPU4). | ||
| */ | ||
| struct ipu_psys_resource_alloc { | ||
| u32 cells; /* Bitmask of cells needed */ | ||
| struct ipu_resource_alloc | ||
| resource_alloc[IPU_MAX_RESOURCES]; | ||
| int resources; | ||
| }; | ||
|
|
||
| struct task_struct; | ||
| struct ipu_psys { | ||
| struct ipu_psys_capability caps; | ||
| struct cdev cdev; | ||
| struct device dev; | ||
|
|
||
| struct mutex mutex; /* Psys various */ | ||
| int power; | ||
| bool icache_prefetch_sp; | ||
| bool icache_prefetch_isp; | ||
| spinlock_t power_lock; /* Serialize access to power */ | ||
| spinlock_t pgs_lock; /* Protect pgs list access */ | ||
| struct list_head fhs; | ||
| struct list_head pgs; | ||
| struct list_head started_kcmds_list; | ||
| struct ipu_psys_pdata *pdata; | ||
| struct ipu_bus_device *adev; | ||
| struct ia_css_syscom_context *dev_ctx; | ||
| struct ia_css_syscom_config *syscom_config; | ||
| struct ia_css_psys_server_init *server_init; | ||
| struct task_struct *sched_cmd_thread; | ||
| struct work_struct watchdog_work; | ||
| wait_queue_head_t sched_cmd_wq; | ||
| atomic_t wakeup_count; /* Psys schedule thread wakeup count */ | ||
| #ifdef CONFIG_DEBUG_FS | ||
| struct dentry *debugfsdir; | ||
| #endif | ||
|
|
||
| /* Resources needed to be managed for process groups */ | ||
| struct ipu_psys_resource_pool resource_pool_running; | ||
| struct ipu_psys_resource_pool resource_pool_started; | ||
|
|
||
| const struct firmware *fw; | ||
| struct sg_table fw_sgt; | ||
| u64 *pkg_dir; | ||
| dma_addr_t pkg_dir_dma_addr; | ||
| unsigned int pkg_dir_size; | ||
| unsigned long timeout; | ||
|
|
||
| int active_kcmds, started_kcmds; | ||
| void *fwcom; | ||
|
|
||
| int power_gating; | ||
| }; | ||
|
|
||
| struct ipu_psys_fh { | ||
| struct ipu_psys *psys; | ||
| struct mutex mutex; /* Protects bufmap & kcmds fields */ | ||
| struct list_head list; | ||
| struct list_head bufmap; | ||
| wait_queue_head_t wait; | ||
| struct ipu_psys_scheduler sched; | ||
| }; | ||
|
|
||
| struct ipu_psys_pg { | ||
| struct ipu_fw_psys_process_group *pg; | ||
| size_t size; | ||
| size_t pg_size; | ||
| dma_addr_t pg_dma_addr; | ||
| struct list_head list; | ||
| struct ipu_psys_resource_alloc resource_alloc; | ||
| }; | ||
|
|
||
| struct ipu_psys_kcmd { | ||
| struct ipu_psys_fh *fh; | ||
| struct list_head list; | ||
| struct ipu_psys_buffer_set *kbuf_set; | ||
| enum ipu_psys_cmd_state state; | ||
| void *pg_manifest; | ||
| size_t pg_manifest_size; | ||
| struct ipu_psys_kbuffer **kbufs; | ||
| struct ipu_psys_buffer *buffers; | ||
| size_t nbuffers; | ||
| struct ipu_fw_psys_process_group *pg_user; | ||
| struct ipu_psys_pg *kpg; | ||
| u64 user_token; | ||
| u64 issue_id; | ||
| u32 priority; | ||
| u32 kernel_enable_bitmap[4]; | ||
| u32 terminal_enable_bitmap[4]; | ||
| u32 routing_enable_bitmap[4]; | ||
| u32 rbm[5]; | ||
| struct ipu_buttress_constraint constraint; | ||
| struct ipu_psys_event ev; | ||
| struct timer_list watchdog; | ||
| }; | ||
|
|
||
| struct ipu_dma_buf_attach { | ||
| struct device *dev; | ||
| u64 len; | ||
| void *userptr; | ||
| struct sg_table *sgt; | ||
| bool vma_is_io; | ||
| struct page **pages; | ||
| size_t npages; | ||
| }; | ||
|
|
||
| struct ipu_psys_kbuffer { | ||
| u64 len; | ||
| void *userptr; | ||
| u32 flags; | ||
| int fd; | ||
| void *kaddr; | ||
| struct list_head list; | ||
| dma_addr_t dma_addr; | ||
| struct sg_table *sgt; | ||
| struct dma_buf_attachment *db_attach; | ||
| struct dma_buf *dbuf; | ||
| bool valid; /* True when buffer is usable */ | ||
| }; | ||
|
|
||
| #define inode_to_ipu_psys(inode) \ | ||
| container_of((inode)->i_cdev, struct ipu_psys, cdev) | ||
|
|
||
| #ifdef CONFIG_COMPAT | ||
| long ipu_psys_compat_ioctl32(struct file *file, unsigned int cmd, | ||
| unsigned long arg); | ||
| #endif | ||
|
|
||
| void ipu_psys_setup_hw(struct ipu_psys *psys); | ||
| void ipu_psys_subdomains_power(struct ipu_psys *psys, bool on); | ||
| void ipu_psys_handle_events(struct ipu_psys *psys); | ||
| int ipu_psys_kcmd_new(struct ipu_psys_command *cmd, struct ipu_psys_fh *fh); | ||
| void ipu_psys_run_next(struct ipu_psys *psys); | ||
| void ipu_psys_watchdog_work(struct work_struct *work); | ||
| struct ipu_psys_pg *__get_pg_buf(struct ipu_psys *psys, size_t pg_size); | ||
| struct ipu_psys_kbuffer * | ||
| ipu_psys_lookup_kbuffer(struct ipu_psys_fh *fh, int fd); | ||
| int ipu_psys_mapbuf_with_lock(int fd, struct ipu_psys_fh *fh, | ||
| struct ipu_psys_kbuffer *kbuf); | ||
| struct ipu_psys_kbuffer * | ||
| ipu_psys_lookup_kbuffer_by_kaddr(struct ipu_psys_fh *fh, void *kaddr); | ||
| #ifdef IPU_PSYS_GPC | ||
| int ipu_psys_gpc_init_debugfs(struct ipu_psys *psys); | ||
| #endif | ||
| int ipu_psys_resource_pool_init(struct ipu_psys_resource_pool *pool); | ||
| void ipu_psys_resource_pool_cleanup(struct ipu_psys_resource_pool *pool); | ||
| struct ipu_psys_kcmd *ipu_get_completed_kcmd(struct ipu_psys_fh *fh); | ||
| long ipu_ioctl_dqevent(struct ipu_psys_event *event, | ||
| struct ipu_psys_fh *fh, unsigned int f_flags); | ||
|
|
||
| #endif /* IPU_PSYS_H */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,312 @@ | ||
| /* SPDX-License-Identifier: GPL-2.0 */ | ||
| /* Copyright (C) 2014 - 2020 Intel Corporation */ | ||
|
|
||
| #ifndef IPU_TRACE_H | ||
| #define IPU_TRACE_H | ||
| #include <linux/debugfs.h> | ||
|
|
||
| #define TRACE_REG_MAX_BLOCK_SIZE 0x0fff | ||
|
|
||
| #define TRACE_REG_END_MARK 0xffff | ||
|
|
||
| #define TRACE_REG_CMD_TYPE_D64 0x0 | ||
| #define TRACE_REG_CMD_TYPE_D64M 0x1 | ||
| #define TRACE_REG_CMD_TYPE_D64TS 0x2 | ||
| #define TRACE_REG_CMD_TYPE_D64MTS 0x3 | ||
|
|
||
| /* Trace unit register offsets */ | ||
| #define TRACE_REG_TUN_DDR_ENABLE 0x000 | ||
| #define TRACE_REG_TUN_NPK_ENABLE 0x004 | ||
| #define TRACE_REG_TUN_DDR_INFO_VAL 0x008 | ||
| #define TRACE_REG_TUN_NPK_ADDR 0x00C | ||
| #define TRACE_REG_TUN_DRAM_BASE_ADDR 0x010 | ||
| #define TRACE_REG_TUN_DRAM_END_ADDR 0x014 | ||
| #define TRACE_REG_TUN_LOCAL_TIMER0 0x018 | ||
| #define TRACE_REG_TUN_LOCAL_TIMER1 0x01C | ||
| #define TRACE_REG_TUN_WR_PTR 0x020 | ||
| #define TRACE_REG_TUN_RD_PTR 0x024 | ||
|
|
||
| #define TRACE_REG_CREATE_TUN_REGISTER_LIST { \ | ||
| TRACE_REG_TUN_DDR_ENABLE, \ | ||
| TRACE_REG_TUN_NPK_ENABLE, \ | ||
| TRACE_REG_TUN_DDR_INFO_VAL, \ | ||
| TRACE_REG_TUN_NPK_ADDR, \ | ||
| TRACE_REG_END_MARK \ | ||
| } | ||
|
|
||
| /* | ||
| * Following registers are left out on purpose: | ||
| * TUN_LOCAL_TIMER0, TUN_LOCAL_TIMER1, TUN_DRAM_BASE_ADDR | ||
| * TUN_DRAM_END_ADDR, TUN_WR_PTR, TUN_RD_PTR | ||
| */ | ||
|
|
||
| /* Trace monitor register offsets */ | ||
| #define TRACE_REG_TM_TRACE_ADDR_A 0x0900 | ||
| #define TRACE_REG_TM_TRACE_ADDR_B 0x0904 | ||
| #define TRACE_REG_TM_TRACE_ADDR_C 0x0908 | ||
| #define TRACE_REG_TM_TRACE_ADDR_D 0x090c | ||
| #define TRACE_REG_TM_TRACE_ENABLE_NPK 0x0910 | ||
| #define TRACE_REG_TM_TRACE_ENABLE_DDR 0x0914 | ||
| #define TRACE_REG_TM_TRACE_PER_PC 0x0918 | ||
| #define TRACE_REG_TM_TRACE_PER_BRANCH 0x091c | ||
| #define TRACE_REG_TM_TRACE_HEADER 0x0920 | ||
| #define TRACE_REG_TM_TRACE_CFG 0x0924 | ||
| #define TRACE_REG_TM_TRACE_LOST_PACKETS 0x0928 | ||
| #define TRACE_REG_TM_TRACE_LP_CLEAR 0x092c | ||
| #define TRACE_REG_TM_TRACE_LMRUN_MASK 0x0930 | ||
| #define TRACE_REG_TM_TRACE_LMRUN_PC_LOW 0x0934 | ||
| #define TRACE_REG_TM_TRACE_LMRUN_PC_HIGH 0x0938 | ||
| #define TRACE_REG_TM_TRACE_MMIO_SEL 0x093c | ||
| #define TRACE_REG_TM_TRACE_MMIO_WP0_LOW 0x0940 | ||
| #define TRACE_REG_TM_TRACE_MMIO_WP1_LOW 0x0944 | ||
| #define TRACE_REG_TM_TRACE_MMIO_WP2_LOW 0x0948 | ||
| #define TRACE_REG_TM_TRACE_MMIO_WP3_LOW 0x094c | ||
| #define TRACE_REG_TM_TRACE_MMIO_WP0_HIGH 0x0950 | ||
| #define TRACE_REG_TM_TRACE_MMIO_WP1_HIGH 0x0954 | ||
| #define TRACE_REG_TM_TRACE_MMIO_WP2_HIGH 0x0958 | ||
| #define TRACE_REG_TM_TRACE_MMIO_WP3_HIGH 0x095c | ||
| #define TRACE_REG_TM_FWTRACE_FIRST 0x0A00 | ||
| #define TRACE_REG_TM_FWTRACE_MIDDLE 0x0A04 | ||
| #define TRACE_REG_TM_FWTRACE_LAST 0x0A08 | ||
|
|
||
| #define TRACE_REG_CREATE_TM_REGISTER_LIST { \ | ||
| TRACE_REG_TM_TRACE_ADDR_A, \ | ||
| TRACE_REG_TM_TRACE_ADDR_B, \ | ||
| TRACE_REG_TM_TRACE_ADDR_C, \ | ||
| TRACE_REG_TM_TRACE_ADDR_D, \ | ||
| TRACE_REG_TM_TRACE_ENABLE_NPK, \ | ||
| TRACE_REG_TM_TRACE_ENABLE_DDR, \ | ||
| TRACE_REG_TM_TRACE_PER_PC, \ | ||
| TRACE_REG_TM_TRACE_PER_BRANCH, \ | ||
| TRACE_REG_TM_TRACE_HEADER, \ | ||
| TRACE_REG_TM_TRACE_CFG, \ | ||
| TRACE_REG_TM_TRACE_LOST_PACKETS, \ | ||
| TRACE_REG_TM_TRACE_LP_CLEAR, \ | ||
| TRACE_REG_TM_TRACE_LMRUN_MASK, \ | ||
| TRACE_REG_TM_TRACE_LMRUN_PC_LOW, \ | ||
| TRACE_REG_TM_TRACE_LMRUN_PC_HIGH, \ | ||
| TRACE_REG_TM_TRACE_MMIO_SEL, \ | ||
| TRACE_REG_TM_TRACE_MMIO_WP0_LOW, \ | ||
| TRACE_REG_TM_TRACE_MMIO_WP1_LOW, \ | ||
| TRACE_REG_TM_TRACE_MMIO_WP2_LOW, \ | ||
| TRACE_REG_TM_TRACE_MMIO_WP3_LOW, \ | ||
| TRACE_REG_TM_TRACE_MMIO_WP0_HIGH, \ | ||
| TRACE_REG_TM_TRACE_MMIO_WP1_HIGH, \ | ||
| TRACE_REG_TM_TRACE_MMIO_WP2_HIGH, \ | ||
| TRACE_REG_TM_TRACE_MMIO_WP3_HIGH, \ | ||
| TRACE_REG_END_MARK \ | ||
| } | ||
|
|
||
| /* | ||
| * Following exists only in (I)SP address space: | ||
| * TM_FWTRACE_FIRST, TM_FWTRACE_MIDDLE, TM_FWTRACE_LAST | ||
| */ | ||
|
|
||
| #define TRACE_REG_GPC_RESET 0x000 | ||
| #define TRACE_REG_GPC_OVERALL_ENABLE 0x004 | ||
| #define TRACE_REG_GPC_TRACE_HEADER 0x008 | ||
| #define TRACE_REG_GPC_TRACE_ADDRESS 0x00C | ||
| #define TRACE_REG_GPC_TRACE_NPK_EN 0x010 | ||
| #define TRACE_REG_GPC_TRACE_DDR_EN 0x014 | ||
| #define TRACE_REG_GPC_TRACE_LPKT_CLEAR 0x018 | ||
| #define TRACE_REG_GPC_TRACE_LPKT 0x01C | ||
|
|
||
| #define TRACE_REG_GPC_ENABLE_ID0 0x020 | ||
| #define TRACE_REG_GPC_ENABLE_ID1 0x024 | ||
| #define TRACE_REG_GPC_ENABLE_ID2 0x028 | ||
| #define TRACE_REG_GPC_ENABLE_ID3 0x02c | ||
|
|
||
| #define TRACE_REG_GPC_VALUE_ID0 0x030 | ||
| #define TRACE_REG_GPC_VALUE_ID1 0x034 | ||
| #define TRACE_REG_GPC_VALUE_ID2 0x038 | ||
| #define TRACE_REG_GPC_VALUE_ID3 0x03c | ||
|
|
||
| #define TRACE_REG_GPC_CNT_INPUT_SELECT_ID0 0x040 | ||
| #define TRACE_REG_GPC_CNT_INPUT_SELECT_ID1 0x044 | ||
| #define TRACE_REG_GPC_CNT_INPUT_SELECT_ID2 0x048 | ||
| #define TRACE_REG_GPC_CNT_INPUT_SELECT_ID3 0x04c | ||
|
|
||
| #define TRACE_REG_GPC_CNT_START_SELECT_ID0 0x050 | ||
| #define TRACE_REG_GPC_CNT_START_SELECT_ID1 0x054 | ||
| #define TRACE_REG_GPC_CNT_START_SELECT_ID2 0x058 | ||
| #define TRACE_REG_GPC_CNT_START_SELECT_ID3 0x05c | ||
|
|
||
| #define TRACE_REG_GPC_CNT_STOP_SELECT_ID0 0x060 | ||
| #define TRACE_REG_GPC_CNT_STOP_SELECT_ID1 0x064 | ||
| #define TRACE_REG_GPC_CNT_STOP_SELECT_ID2 0x068 | ||
| #define TRACE_REG_GPC_CNT_STOP_SELECT_ID3 0x06c | ||
|
|
||
| #define TRACE_REG_GPC_CNT_MSG_SELECT_ID0 0x070 | ||
| #define TRACE_REG_GPC_CNT_MSG_SELECT_ID1 0x074 | ||
| #define TRACE_REG_GPC_CNT_MSG_SELECT_ID2 0x078 | ||
| #define TRACE_REG_GPC_CNT_MSG_SELECT_ID3 0x07c | ||
|
|
||
| #define TRACE_REG_GPC_CNT_MSG_PLOAD_SELECT_ID0 0x080 | ||
| #define TRACE_REG_GPC_CNT_MSG_PLOAD_SELECT_ID1 0x084 | ||
| #define TRACE_REG_GPC_CNT_MSG_PLOAD_SELECT_ID2 0x088 | ||
| #define TRACE_REG_GPC_CNT_MSG_PLOAD_SELECT_ID3 0x08c | ||
|
|
||
| #define TRACE_REG_GPC_IRQ_TRIGGER_VALUE_ID0 0x090 | ||
| #define TRACE_REG_GPC_IRQ_TRIGGER_VALUE_ID1 0x094 | ||
| #define TRACE_REG_GPC_IRQ_TRIGGER_VALUE_ID2 0x098 | ||
| #define TRACE_REG_GPC_IRQ_TRIGGER_VALUE_ID3 0x09c | ||
|
|
||
| #define TRACE_REG_GPC_IRQ_TIMER_SELECT_ID0 0x0a0 | ||
| #define TRACE_REG_GPC_IRQ_TIMER_SELECT_ID1 0x0a4 | ||
| #define TRACE_REG_GPC_IRQ_TIMER_SELECT_ID2 0x0a8 | ||
| #define TRACE_REG_GPC_IRQ_TIMER_SELECT_ID3 0x0ac | ||
|
|
||
| #define TRACE_REG_GPC_IRQ_ENABLE_ID0 0x0b0 | ||
| #define TRACE_REG_GPC_IRQ_ENABLE_ID1 0x0b4 | ||
| #define TRACE_REG_GPC_IRQ_ENABLE_ID2 0x0b8 | ||
| #define TRACE_REG_GPC_IRQ_ENABLE_ID3 0x0bc | ||
|
|
||
| #define TRACE_REG_CREATE_GPC_REGISTER_LIST { \ | ||
| TRACE_REG_GPC_RESET, \ | ||
| TRACE_REG_GPC_OVERALL_ENABLE, \ | ||
| TRACE_REG_GPC_TRACE_HEADER, \ | ||
| TRACE_REG_GPC_TRACE_ADDRESS, \ | ||
| TRACE_REG_GPC_TRACE_NPK_EN, \ | ||
| TRACE_REG_GPC_TRACE_DDR_EN, \ | ||
| TRACE_REG_GPC_TRACE_LPKT_CLEAR, \ | ||
| TRACE_REG_GPC_TRACE_LPKT, \ | ||
| TRACE_REG_GPC_ENABLE_ID0, \ | ||
| TRACE_REG_GPC_ENABLE_ID1, \ | ||
| TRACE_REG_GPC_ENABLE_ID2, \ | ||
| TRACE_REG_GPC_ENABLE_ID3, \ | ||
| TRACE_REG_GPC_VALUE_ID0, \ | ||
| TRACE_REG_GPC_VALUE_ID1, \ | ||
| TRACE_REG_GPC_VALUE_ID2, \ | ||
| TRACE_REG_GPC_VALUE_ID3, \ | ||
| TRACE_REG_GPC_CNT_INPUT_SELECT_ID0, \ | ||
| TRACE_REG_GPC_CNT_INPUT_SELECT_ID1, \ | ||
| TRACE_REG_GPC_CNT_INPUT_SELECT_ID2, \ | ||
| TRACE_REG_GPC_CNT_INPUT_SELECT_ID3, \ | ||
| TRACE_REG_GPC_CNT_START_SELECT_ID0, \ | ||
| TRACE_REG_GPC_CNT_START_SELECT_ID1, \ | ||
| TRACE_REG_GPC_CNT_START_SELECT_ID2, \ | ||
| TRACE_REG_GPC_CNT_START_SELECT_ID3, \ | ||
| TRACE_REG_GPC_CNT_STOP_SELECT_ID0, \ | ||
| TRACE_REG_GPC_CNT_STOP_SELECT_ID1, \ | ||
| TRACE_REG_GPC_CNT_STOP_SELECT_ID2, \ | ||
| TRACE_REG_GPC_CNT_STOP_SELECT_ID3, \ | ||
| TRACE_REG_GPC_CNT_MSG_SELECT_ID0, \ | ||
| TRACE_REG_GPC_CNT_MSG_SELECT_ID1, \ | ||
| TRACE_REG_GPC_CNT_MSG_SELECT_ID2, \ | ||
| TRACE_REG_GPC_CNT_MSG_SELECT_ID3, \ | ||
| TRACE_REG_GPC_CNT_MSG_PLOAD_SELECT_ID0, \ | ||
| TRACE_REG_GPC_CNT_MSG_PLOAD_SELECT_ID1, \ | ||
| TRACE_REG_GPC_CNT_MSG_PLOAD_SELECT_ID2, \ | ||
| TRACE_REG_GPC_CNT_MSG_PLOAD_SELECT_ID3, \ | ||
| TRACE_REG_GPC_IRQ_TRIGGER_VALUE_ID0, \ | ||
| TRACE_REG_GPC_IRQ_TRIGGER_VALUE_ID1, \ | ||
| TRACE_REG_GPC_IRQ_TRIGGER_VALUE_ID2, \ | ||
| TRACE_REG_GPC_IRQ_TRIGGER_VALUE_ID3, \ | ||
| TRACE_REG_GPC_IRQ_TIMER_SELECT_ID0, \ | ||
| TRACE_REG_GPC_IRQ_TIMER_SELECT_ID1, \ | ||
| TRACE_REG_GPC_IRQ_TIMER_SELECT_ID2, \ | ||
| TRACE_REG_GPC_IRQ_TIMER_SELECT_ID3, \ | ||
| TRACE_REG_GPC_IRQ_ENABLE_ID0, \ | ||
| TRACE_REG_GPC_IRQ_ENABLE_ID1, \ | ||
| TRACE_REG_GPC_IRQ_ENABLE_ID2, \ | ||
| TRACE_REG_GPC_IRQ_ENABLE_ID3, \ | ||
| TRACE_REG_END_MARK \ | ||
| } | ||
|
|
||
| /* CSI2 legacy receiver trace registers */ | ||
| #define TRACE_REG_CSI2_TM_RESET_REG_IDX 0x0000 | ||
| #define TRACE_REG_CSI2_TM_OVERALL_ENABLE_REG_IDX 0x0004 | ||
| #define TRACE_REG_CSI2_TM_TRACE_HEADER_REG_IDX 0x0008 | ||
| #define TRACE_REG_CSI2_TM_TRACE_ADDRESS_REG_IDX 0x000c | ||
| #define TRACE_REG_CSI2_TM_TRACE_HEADER_VAL 0xf | ||
| #define TRACE_REG_CSI2_TM_TRACE_ADDRESS_VAL 0x100218 | ||
| #define TRACE_REG_CSI2_TM_MONITOR_ID 0x8 | ||
|
|
||
| /* 0 <= n <= 3 */ | ||
| #define TRACE_REG_CSI2_TM_TRACE_NPK_EN_REG_IDX_P(n) (0x0010 + (n) * 4) | ||
| #define TRACE_REG_CSI2_TM_TRACE_DDR_EN_REG_IDX_P(n) (0x0020 + (n) * 4) | ||
| #define TRACE_CSI2_TM_EVENT_FE(vc) (BIT(0) << ((vc) * 6)) | ||
| #define TRACE_CSI2_TM_EVENT_FS(vc) (BIT(1) << ((vc) * 6)) | ||
| #define TRACE_CSI2_TM_EVENT_PE(vc) (BIT(2) << ((vc) * 6)) | ||
| #define TRACE_CSI2_TM_EVENT_PS(vc) (BIT(3) << ((vc) * 6)) | ||
| #define TRACE_CSI2_TM_EVENT_LE(vc) (BIT(4) << ((vc) * 6)) | ||
| #define TRACE_CSI2_TM_EVENT_LS(vc) (BIT(5) << ((vc) * 6)) | ||
|
|
||
| #define TRACE_REG_CSI2_TM_TRACE_LPKT_CLEAR_REG_IDX 0x0030 | ||
| #define TRACE_REG_CSI2_TM_TRACE_LPKT_REG_IDX 0x0034 | ||
|
|
||
| /* 0 <= n <= 7 */ | ||
| #define TRACE_REG_CSI2_TM_ENABLE_REG_ID_N(n) (0x0038 + (n) * 4) | ||
| #define TRACE_REG_CSI2_TM_VALUE_REG_ID_N(n) (0x0058 + (n) * 4) | ||
| #define TRACE_REG_CSI2_TM_CNT_INPUT_SELECT_REG_ID_N(n) (0x0078 + (n) * 4) | ||
| #define TRACE_REG_CSI2_TM_CNT_START_SELECT_REG_ID_N(n) (0x0098 + (n) * 4) | ||
| #define TRACE_REG_CSI2_TM_CNT_STOP_SELECT_REG_ID_N(n) (0x00b8 + (n) * 4) | ||
| #define TRACE_REG_CSI2_TM_IRQ_TRIGGER_VALUE_REG_ID_N(n) (0x00d8 + (n) * 4) | ||
| #define TRACE_REG_CSI2_TM_IRQ_TIMER_SELECT_REG_ID_N(n) (0x00f8 + (n) * 4) | ||
| #define TRACE_REG_CSI2_TM_IRQ_ENABLE_REG_ID_N(n) (0x0118 + (n) * 4) | ||
|
|
||
| /* CSI2_3PH combo receiver trace registers */ | ||
| #define TRACE_REG_CSI2_3PH_TM_RESET_REG_IDX 0x0000 | ||
| #define TRACE_REG_CSI2_3PH_TM_OVERALL_ENABLE_REG_IDX 0x0004 | ||
| #define TRACE_REG_CSI2_3PH_TM_TRACE_HEADER_REG_IDX 0x0008 | ||
| #define TRACE_REG_CSI2_3PH_TM_TRACE_ADDRESS_REG_IDX 0x000c | ||
| #define TRACE_REG_CSI2_3PH_TM_TRACE_ADDRESS_VAL 0x100258 | ||
| #define TRACE_REG_CSI2_3PH_TM_MONITOR_ID 0x9 | ||
|
|
||
| /* 0 <= n <= 5 */ | ||
| #define TRACE_REG_CSI2_3PH_TM_TRACE_NPK_EN_REG_IDX_P(n) (0x0010 + (n) * 4) | ||
| #define TRACE_REG_CSI2_3PH_TM_TRACE_DDR_EN_REG_IDX_P(n) (0x0028 + (n) * 4) | ||
|
|
||
| #define TRACE_REG_CSI2_3PH_TM_TRACE_LPKT_CLEAR_REG_IDX 0x0040 | ||
| #define TRACE_REG_CSI2_3PH_TM_TRACE_LPKT_REG_IDX 0x0044 | ||
|
|
||
| /* 0 <= n <= 7 */ | ||
| #define TRACE_REG_CSI2_3PH_TM_ENABLE_REG_ID_N(n) (0x0048 + (n) * 4) | ||
| #define TRACE_REG_CSI2_3PH_TM_VALUE_REG_ID_N(n) (0x0068 + (n) * 4) | ||
| #define TRACE_REG_CSI2_3PH_TM_CNT_INPUT_SELECT_REG_ID_N(n) (0x0088 + (n) * 4) | ||
| #define TRACE_REG_CSI2_3PH_TM_CNT_START_SELECT_REG_ID_N(n) (0x00a8 + (n) * 4) | ||
| #define TRACE_REG_CSI2_3PH_TM_CNT_STOP_SELECT_REG_ID_N(n) (0x00c8 + (n) * 4) | ||
| #define TRACE_REG_CSI2_3PH_TM_IRQ_TRIGGER_VALUE_REG_ID_N(n) (0x00e8 + (n) * 4) | ||
| #define TRACE_REG_CSI2_3PH_TM_IRQ_TIMER_SELECT_REG_ID_N(n) (0x0108 + (n) * 4) | ||
| #define TRACE_REG_CSI2_3PH_TM_IRQ_ENABLE_REG_ID_N(n) (0x0128 + (n) * 4) | ||
|
|
||
| /* SIG2CIO trace monitors */ | ||
| #define TRACE_REG_SIG2CIO_ADDRESS 0x0000 | ||
| #define TRACE_REG_SIG2CIO_WDATA 0x0004 | ||
| #define TRACE_REG_SIG2CIO_MASK 0x0008 | ||
| #define TRACE_REG_SIG2CIO_GROUP_CFG 0x000c | ||
| #define TRACE_REG_SIG2CIO_STICKY 0x0010 | ||
| #define TRACE_REG_SIG2CIO_RST_STICKY 0x0014 | ||
| #define TRACE_REG_SIG2CIO_MANUAL_RST_STICKY 0x0018 | ||
| #define TRACE_REG_SIG2CIO_STATUS 0x001c | ||
| /* Size of on SIG2CIO block */ | ||
| #define TRACE_REG_SIG2CIO_SIZE_OF 0x0020 | ||
|
|
||
| struct ipu_trace; | ||
| struct ipu_subsystem_trace_config; | ||
|
|
||
| enum ipu_trace_block_type { | ||
| IPU_TRACE_BLOCK_TUN = 0, /* Trace unit */ | ||
| IPU_TRACE_BLOCK_TM, /* Trace monitor */ | ||
| IPU_TRACE_BLOCK_GPC, /* General purpose control */ | ||
| IPU_TRACE_CSI2, /* CSI2 legacy receiver */ | ||
| IPU_TRACE_CSI2_3PH, /* CSI2 combo receiver */ | ||
| IPU_TRACE_SIG2CIOS, | ||
| IPU_TRACE_TIMER_RST, /* Trace reset control timer */ | ||
| IPU_TRACE_BLOCK_END /* End of list */ | ||
| }; | ||
|
|
||
| struct ipu_trace_block { | ||
| u32 offset; /* Offset to block inside subsystem */ | ||
| enum ipu_trace_block_type type; | ||
| }; | ||
|
|
||
| int ipu_trace_add(struct ipu_device *isp); | ||
| int ipu_trace_debugfs_add(struct ipu_device *isp, struct dentry *dir); | ||
| void ipu_trace_release(struct ipu_device *isp); | ||
| int ipu_trace_init(struct ipu_device *isp, void __iomem *base, | ||
| struct device *dev, struct ipu_trace_block *blocks); | ||
| void ipu_trace_restore(struct device *dev); | ||
| void ipu_trace_uninit(struct device *dev); | ||
| void ipu_trace_stop(struct device *dev); | ||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| /* SPDX-License-Identifier: GPL-2.0 */ | ||
| /* Copyright (C) 2013 - 2020 Intel Corporation */ | ||
|
|
||
| #ifndef IPU_H | ||
| #define IPU_H | ||
|
|
||
| #include <linux/ioport.h> | ||
| #include <linux/list.h> | ||
| #include <uapi/linux/media.h> | ||
| #include <linux/version.h> | ||
|
|
||
| #include "ipu-pdata.h" | ||
| #include "ipu-bus.h" | ||
| #include "ipu-buttress.h" | ||
| #include "ipu-trace.h" | ||
|
|
||
| #define IPU6_PCI_ID 0x9a19 | ||
| #define IPU6SE_PCI_ID 0x4e19 | ||
|
|
||
| enum ipu_version { | ||
| IPU_VER_INVALID = 0, | ||
| IPU_VER_6, | ||
| IPU_VER_6SE, | ||
| }; | ||
|
|
||
| /* | ||
| * IPU version definitions to reflect the IPU driver changes. | ||
| * Both ISYS and PSYS share the same version. | ||
| */ | ||
| #define IPU_MAJOR_VERSION 1 | ||
| #define IPU_MINOR_VERSION 0 | ||
| #define IPU_DRIVER_VERSION (IPU_MAJOR_VERSION << 16 | IPU_MINOR_VERSION) | ||
|
|
||
| /* processing system frequency: 25Mhz x ratio, Legal values [8,32] */ | ||
| #define PS_FREQ_CTL_DEFAULT_RATIO 0x12 | ||
|
|
||
| /* input system frequency: 1600Mhz / divisor. Legal values [2,8] */ | ||
| #define IS_FREQ_SOURCE 1600000000 | ||
| #define IS_FREQ_CTL_DIVISOR 0x4 | ||
|
|
||
| /* | ||
| * 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 | ||
|
|
||
| /* | ||
| * Physical pages in GDA is 128, page size is 2K for IPU6, 1K for others. | ||
| */ | ||
| #define IPU_DEVICE_GDA_NR_PAGES 128 | ||
|
|
||
| /* | ||
| * Virtualization factor to calculate the available virtual pages. | ||
| */ | ||
| #define IPU_DEVICE_GDA_VIRT_FACTOR 32 | ||
|
|
||
| struct pci_dev; | ||
| struct list_head; | ||
| struct firmware; | ||
|
|
||
| #define NR_OF_MMU_RESOURCES 2 | ||
|
|
||
| struct ipu_device { | ||
| struct pci_dev *pdev; | ||
| struct list_head devices; | ||
| struct ipu_bus_device *isys; | ||
| struct ipu_bus_device *psys; | ||
| struct ipu_buttress buttress; | ||
|
|
||
| const struct firmware *cpd_fw; | ||
| const char *cpd_fw_name; | ||
| u64 *pkg_dir; | ||
| dma_addr_t pkg_dir_dma_addr; | ||
| unsigned int pkg_dir_size; | ||
| struct sg_table fw_sgt; | ||
|
|
||
| void __iomem *base; | ||
| #ifdef CONFIG_DEBUG_FS | ||
| struct dentry *ipu_dir; | ||
| #endif | ||
| struct ipu_trace *trace; | ||
| bool flr_done; | ||
| bool ipc_reinit; | ||
| bool secure_mode; | ||
|
|
||
| int (*cpd_fw_reload)(struct ipu_device *isp); | ||
| }; | ||
|
|
||
| #define IPU_DMA_MASK 39 | ||
| #define IPU_LIB_CALL_TIMEOUT_MS 2000 | ||
| #define IPU_PSYS_CMD_TIMEOUT_MS 2000 | ||
| #define IPU_PSYS_OPEN_TIMEOUT_US 50 | ||
| #define IPU_PSYS_OPEN_RETRY (10000 / IPU_PSYS_OPEN_TIMEOUT_US) | ||
|
|
||
| int ipu_fw_authenticate(void *data, u64 val); | ||
| void ipu_configure_spc(struct ipu_device *isp, | ||
| const struct ipu_hw_variants *hw_variant, | ||
| int pkg_dir_idx, void __iomem *base, u64 *pkg_dir, | ||
| dma_addr_t pkg_dir_dma_addr); | ||
| int request_cpd_fw(const struct firmware **firmware_p, const char *name, | ||
| struct device *device); | ||
| extern enum ipu_version ipu_ver; | ||
| void ipu_internal_pdata_init(void); | ||
|
|
||
| #endif /* IPU_H */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| # SPDX-License-Identifier: GPL-2.0 | ||
| # Copyright (c) 2017 - 2020 Intel Corporation. | ||
|
|
||
| ifneq ($(EXTERNAL_BUILD), 1) | ||
| srcpath := $(srctree) | ||
| endif | ||
|
|
||
| ccflags-y += -DHAS_DUAL_CMD_CTX_SUPPORT=0 -DIPU_TPG_FRAME_SYNC -DIPU_PSYS_GPC \ | ||
| -DIPU_ISYS_GPC | ||
|
|
||
| intel-ipu6-objs += ../ipu.o \ | ||
| ../ipu-bus.o \ | ||
| ../ipu-dma.o \ | ||
| ../ipu-mmu.o \ | ||
| ../ipu-buttress.o \ | ||
| ../ipu-trace.o \ | ||
| ../ipu-cpd.o \ | ||
| ipu6.o \ | ||
| ../ipu-fw-com.o | ||
|
|
||
| obj-$(CONFIG_VIDEO_INTEL_IPU) += intel-ipu6.o | ||
|
|
||
| intel-ipu6-isys-objs += ../ipu-isys.o \ | ||
| ../ipu-isys-csi2.o \ | ||
| ipu6-isys.o \ | ||
| ipu6-isys-phy.o \ | ||
| ipu6-isys-csi2.o \ | ||
| ipu6-isys-gpc.o \ | ||
| ../ipu-isys-csi2-be-soc.o \ | ||
| ../ipu-isys-csi2-be.o \ | ||
| ../ipu-fw-isys.o \ | ||
| ../ipu-isys-video.o \ | ||
| ../ipu-isys-queue.o \ | ||
| ../ipu-isys-subdev.o \ | ||
| ../ipu-isys-tpg.o | ||
|
|
||
| obj-$(CONFIG_VIDEO_INTEL_IPU) += intel-ipu6-isys.o | ||
|
|
||
| intel-ipu6-psys-objs += ../ipu-psys.o \ | ||
| ipu6-psys.o \ | ||
| ipu-resources.o \ | ||
| ipu6-psys-gpc.o \ | ||
| ipu6-l-scheduler.o \ | ||
| ipu6-ppg.o | ||
|
|
||
| intel-ipu6-psys-objs += ipu-fw-resources.o \ | ||
| ipu6-fw-resources.o \ | ||
| ipu6se-fw-resources.o \ | ||
| ../ipu-fw-psys.o | ||
|
|
||
| ifeq ($(CONFIG_COMPAT),y) | ||
| intel-ipu6-psys-objs += ../ipu-psys-compat32.o | ||
| endif | ||
|
|
||
| obj-$(CONFIG_VIDEO_INTEL_IPU) += intel-ipu6-psys.o | ||
|
|
||
| ccflags-y += -I$(srcpath)/$(src)/../../../../../include/ | ||
| ccflags-y += -I$(srcpath)/$(src)/../ | ||
| ccflags-y += -I$(srcpath)/$(src)/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| // SPDX-License-Identifier: GPL-2.0 | ||
| // Copyright (C) 2015 - 2019 Intel Corporation | ||
|
|
||
| #include <linux/err.h> | ||
| #include <linux/string.h> | ||
|
|
||
| #include "ipu-psys.h" | ||
| #include "ipu-fw-psys.h" | ||
| #include "ipu6-platform-resources.h" | ||
| #include "ipu6se-platform-resources.h" | ||
|
|
||
| /********** Generic resource handling **********/ | ||
|
|
||
| /* | ||
| * Extension library gives byte offsets to its internal structures. | ||
| * use those offsets to update fields. Without extension lib access | ||
| * structures directly. | ||
| */ | ||
| const struct ipu6_psys_hw_res_variant *var = &hw_var; | ||
|
|
||
| int ipu_fw_psys_set_process_cell_id(struct ipu_fw_psys_process *ptr, u8 index, | ||
| u8 value) | ||
| { | ||
| struct ipu_fw_psys_process_group *parent = | ||
| (struct ipu_fw_psys_process_group *)((char *)ptr + | ||
| ptr->parent_offset); | ||
|
|
||
| ptr->cells[index] = value; | ||
| parent->resource_bitmap |= 1 << value; | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| u8 ipu_fw_psys_get_process_cell_id(struct ipu_fw_psys_process *ptr, u8 index) | ||
| { | ||
| return ptr->cells[index]; | ||
| } | ||
|
|
||
| int ipu_fw_psys_clear_process_cell(struct ipu_fw_psys_process *ptr) | ||
| { | ||
| struct ipu_fw_psys_process_group *parent; | ||
| u8 cell_id = ipu_fw_psys_get_process_cell_id(ptr, 0); | ||
| int retval = -1; | ||
| u8 value; | ||
|
|
||
| parent = (struct ipu_fw_psys_process_group *)((char *)ptr + | ||
| ptr->parent_offset); | ||
|
|
||
| value = var->cell_num; | ||
| if ((1 << cell_id) != 0 && | ||
| ((1 << cell_id) & parent->resource_bitmap)) { | ||
| ipu_fw_psys_set_process_cell_id(ptr, 0, value); | ||
| parent->resource_bitmap &= ~(1 << cell_id); | ||
| retval = 0; | ||
| } | ||
|
|
||
| return retval; | ||
| } | ||
|
|
||
| int ipu_fw_psys_set_proc_dev_chn(struct ipu_fw_psys_process *ptr, u16 offset, | ||
| u16 value) | ||
| { | ||
| if (var->set_proc_dev_chn) | ||
| return var->set_proc_dev_chn(ptr, offset, value); | ||
|
|
||
| WARN(1, "ipu6 psys res var is not initialised correctly."); | ||
| return 0; | ||
| } | ||
|
|
||
| int ipu_fw_psys_set_proc_dfm_bitmap(struct ipu_fw_psys_process *ptr, | ||
| u16 id, u32 bitmap, | ||
| u32 active_bitmap) | ||
| { | ||
| if (var->set_proc_dfm_bitmap) | ||
| return var->set_proc_dfm_bitmap(ptr, id, bitmap, | ||
| active_bitmap); | ||
|
|
||
| WARN(1, "ipu6 psys res var is not initialised correctly."); | ||
| return 0; | ||
| } | ||
|
|
||
| int ipu_fw_psys_set_process_ext_mem(struct ipu_fw_psys_process *ptr, | ||
| u16 type_id, u16 mem_id, u16 offset) | ||
| { | ||
| if (var->set_proc_ext_mem) | ||
| return var->set_proc_ext_mem(ptr, type_id, mem_id, offset); | ||
|
|
||
| WARN(1, "ipu6 psys res var is not initialised correctly."); | ||
| return 0; | ||
| } | ||
|
|
||
| int ipu_fw_psys_get_program_manifest_by_process( | ||
| struct ipu_fw_generic_program_manifest *gen_pm, | ||
| const struct ipu_fw_psys_program_group_manifest *pg_manifest, | ||
| struct ipu_fw_psys_process *process) | ||
| { | ||
| if (var->get_pgm_by_proc) | ||
| return var->get_pgm_by_proc(gen_pm, pg_manifest, process); | ||
|
|
||
| WARN(1, "ipu6 psys res var is not initialised correctly."); | ||
| return 0; | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,315 @@ | ||
| /* SPDX-License-Identifier: GPL-2.0 */ | ||
| /* Copyright (C) 2020 Intel Corporation */ | ||
|
|
||
| #ifndef IPU_PLATFORM_BUTTRESS_REGS_H | ||
| #define IPU_PLATFORM_BUTTRESS_REGS_H | ||
|
|
||
| /* IS_WORKPOINT_REQ */ | ||
| #define IPU_BUTTRESS_REG_IS_FREQ_CTL 0x34 | ||
| /* PS_WORKPOINT_REQ */ | ||
| #define IPU_BUTTRESS_REG_PS_FREQ_CTL 0x38 | ||
|
|
||
| #define IPU_BUTTRESS_IS_FREQ_RATIO_MASK 0xff | ||
| #define IPU_BUTTRESS_PS_FREQ_RATIO_MASK 0xff | ||
|
|
||
| #define IPU_IS_FREQ_MAX 533 | ||
| #define IPU_IS_FREQ_MIN 200 | ||
| #define IPU_PS_FREQ_MAX 450 | ||
| #define IPU_IS_FREQ_RATIO_BASE 25 | ||
| #define IPU_PS_FREQ_RATIO_BASE 25 | ||
| #define IPU_BUTTRESS_IS_FREQ_CTL_DIVISOR_MASK 0xff | ||
| #define IPU_BUTTRESS_PS_FREQ_CTL_DIVISOR_MASK 0xff | ||
|
|
||
| /* should be tuned for real silicon */ | ||
| #define IPU_IS_FREQ_CTL_DEFAULT_RATIO 0x08 | ||
| #define IPU_PS_FREQ_CTL_DEFAULT_RATIO 0x10 | ||
|
|
||
| #define IPU_IS_FREQ_CTL_DEFAULT_QOS_FLOOR_RATIO 0x10 | ||
| #define IPU_PS_FREQ_CTL_DEFAULT_QOS_FLOOR_RATIO 0x0708 | ||
|
|
||
| #define IPU_BUTTRESS_PWR_STATE_IS_PWR_SHIFT 3 | ||
| #define IPU_BUTTRESS_PWR_STATE_IS_PWR_MASK \ | ||
| (0x3 << IPU_BUTTRESS_PWR_STATE_IS_PWR_SHIFT) | ||
|
|
||
| #define IPU_BUTTRESS_PWR_STATE_PS_PWR_SHIFT 6 | ||
| #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 IPU_BUTTRESS_REG_FPGA_SUPPORT_0 0x270 | ||
| #define IPU_BUTTRESS_REG_FPGA_SUPPORT_1 0x274 | ||
| #define IPU_BUTTRESS_REG_FPGA_SUPPORT_2 0x278 | ||
| #define IPU_BUTTRESS_REG_FPGA_SUPPORT_3 0x27c | ||
| #define IPU_BUTTRESS_REG_FPGA_SUPPORT_4 0x280 | ||
| #define IPU_BUTTRESS_REG_FPGA_SUPPORT_5 0x284 | ||
| #define IPU_BUTTRESS_REG_FPGA_SUPPORT_6 0x288 | ||
| #define IPU_BUTTRESS_REG_FPGA_SUPPORT_7 0x28c | ||
|
|
||
| #define BUTTRESS_REG_WDT 0x8 | ||
| #define BUTTRESS_REG_BTRS_CTRL 0xc | ||
| #define BUTTRESS_REG_BTRS_CTRL_STALL_MODE_VC0 BIT(0) | ||
| #define BUTTRESS_REG_BTRS_CTRL_STALL_MODE_VC1 BIT(1) | ||
|
|
||
| #define BUTTRESS_REG_FW_RESET_CTL 0x30 | ||
| #define BUTTRESS_FW_RESET_CTL_START BIT(0) | ||
| #define BUTTRESS_FW_RESET_CTL_DONE BIT(1) | ||
|
|
||
| #define BUTTRESS_REG_IS_FREQ_CTL 0x34 | ||
|
|
||
| #define BUTTRESS_IS_FREQ_CTL_DIVISOR_MASK 0xf | ||
|
|
||
| #define BUTTRESS_REG_PS_FREQ_CTL 0x38 | ||
|
|
||
| #define BUTTRESS_PS_FREQ_CTL_RATIO_MASK 0xff | ||
|
|
||
| #define BUTTRESS_FREQ_CTL_START BIT(31) | ||
| #define BUTTRESS_FREQ_CTL_START_SHIFT 31 | ||
| #define BUTTRESS_FREQ_CTL_QOS_FLOOR_SHIFT 8 | ||
| #define BUTTRESS_FREQ_CTL_QOS_FLOOR_MASK (0xff << 8) | ||
|
|
||
| #define BUTTRESS_REG_PWR_STATE 0x5c | ||
|
|
||
| #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 BUTTRESS_PWR_STATE_RESET 0x0 | ||
| #define BUTTRESS_PWR_STATE_PWR_ON_DONE 0x1 | ||
| #define BUTTRESS_PWR_STATE_PWR_RDY 0x3 | ||
| #define BUTTRESS_PWR_STATE_PWR_IDLE 0x4 | ||
|
|
||
| #define BUTTRESS_PWR_STATE_HH_STATUS_SHIFT 11 | ||
| #define BUTTRESS_PWR_STATE_HH_STATUS_MASK (0x3 << 11) | ||
|
|
||
| enum { | ||
| BUTTRESS_PWR_STATE_HH_STATE_IDLE, | ||
| BUTTRESS_PWR_STATE_HH_STATE_IN_PRGS, | ||
| BUTTRESS_PWR_STATE_HH_STATE_DONE, | ||
| BUTTRESS_PWR_STATE_HH_STATE_ERR, | ||
| }; | ||
|
|
||
| #define BUTTRESS_PWR_STATE_IS_PWR_FSM_SHIFT 19 | ||
| #define BUTTRESS_PWR_STATE_IS_PWR_FSM_MASK (0xf << 19) | ||
|
|
||
| #define BUTTRESS_PWR_STATE_IS_PWR_FSM_IDLE 0x0 | ||
| #define BUTTRESS_PWR_STATE_IS_PWR_FSM_WAIT_4_PLL_CMP 0x1 | ||
| #define BUTTRESS_PWR_STATE_IS_PWR_FSM_WAIT_4_CLKACK 0x2 | ||
| #define BUTTRESS_PWR_STATE_IS_PWR_FSM_WAIT_4_PG_ACK 0x3 | ||
| #define BUTTRESS_PWR_STATE_IS_PWR_FSM_RST_ASSRT_CYCLES 0x4 | ||
| #define BUTTRESS_PWR_STATE_IS_PWR_FSM_STOP_CLK_CYCLES1 0x5 | ||
| #define BUTTRESS_PWR_STATE_IS_PWR_FSM_STOP_CLK_CYCLES2 0x6 | ||
| #define BUTTRESS_PWR_STATE_IS_PWR_FSM_RST_DEASSRT_CYCLES 0x7 | ||
| #define BUTTRESS_PWR_STATE_IS_PWR_FSM_WAIT_4_FUSE_WR_CMP 0x8 | ||
| #define BUTTRESS_PWR_STATE_IS_PWR_FSM_BRK_POINT 0x9 | ||
| #define BUTTRESS_PWR_STATE_IS_PWR_FSM_IS_RDY 0xa | ||
| #define BUTTRESS_PWR_STATE_IS_PWR_FSM_HALT_HALTED 0xb | ||
| #define BUTTRESS_PWR_STATE_IS_PWR_FSM_RST_DURATION_CNT3 0xc | ||
| #define BUTTRESS_PWR_STATE_IS_PWR_FSM_WAIT_4_CLKACK_PD 0xd | ||
| #define BUTTRESS_PWR_STATE_IS_PWR_FSM_PD_BRK_POINT 0xe | ||
| #define BUTTRESS_PWR_STATE_IS_PWR_FSM_WAIT_4_PD_PG_ACK0 0xf | ||
|
|
||
| #define BUTTRESS_PWR_STATE_PS_PWR_FSM_SHIFT 24 | ||
| #define BUTTRESS_PWR_STATE_PS_PWR_FSM_MASK (0x1f << 24) | ||
|
|
||
| #define BUTTRESS_PWR_STATE_PS_PWR_FSM_IDLE 0x0 | ||
| #define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_PU_PLL_IP_RDY 0x1 | ||
| #define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_RO_PRE_CNT_EXH 0x2 | ||
| #define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_PU_VGI_PWRGOOD 0x3 | ||
| #define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_RO_POST_CNT_EXH 0x4 | ||
| #define BUTTRESS_PWR_STATE_PS_PWR_FSM_WR_PLL_RATIO 0x5 | ||
| #define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_PU_PLL_CMP 0x6 | ||
| #define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_PU_CLKACK 0x7 | ||
| #define BUTTRESS_PWR_STATE_PS_PWR_FSM_RST_ASSRT_CYCLES 0x8 | ||
| #define BUTTRESS_PWR_STATE_PS_PWR_FSM_STOP_CLK_CYCLES1 0x9 | ||
| #define BUTTRESS_PWR_STATE_PS_PWR_FSM_STOP_CLK_CYCLES2 0xa | ||
| #define BUTTRESS_PWR_STATE_PS_PWR_FSM_RST_DEASSRT_CYCLES 0xb | ||
| #define BUTTRESS_PWR_STATE_PS_PWR_FSM_PU_BRK_PNT 0xc | ||
| #define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_FUSE_ACCPT 0xd | ||
| #define BUTTRESS_PWR_STATE_PS_PWR_FSM_PS_PWR_UP 0xf | ||
| #define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_4_HALTED 0x10 | ||
| #define BUTTRESS_PWR_STATE_PS_PWR_FSM_RESET_CNT3 0x11 | ||
| #define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_PD_CLKACK 0x12 | ||
| #define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_PD_OFF_IND 0x13 | ||
| #define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_DVFS_PH4 0x14 | ||
| #define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_DVFS_PLL_CMP 0x15 | ||
| #define BUTTRESS_PWR_STATE_PS_PWR_FSM_WAIT_DVFS_CLKACK 0x16 | ||
|
|
||
| #define BUTTRESS_REG_SECURITY_CTL 0x300 | ||
|
|
||
| #define BUTTRESS_SECURITY_CTL_FW_SECURE_MODE BIT(16) | ||
| #define BUTTRESS_SECURITY_CTL_FW_SETUP_SHIFT 0 | ||
| #define BUTTRESS_SECURITY_CTL_FW_SETUP_MASK 0x1f | ||
|
|
||
| #define BUTTRESS_SECURITY_CTL_FW_SETUP_DONE 0x1 | ||
| #define BUTTRESS_SECURITY_CTL_AUTH_DONE 0x2 | ||
| #define BUTTRESS_SECURITY_CTL_AUTH_FAILED 0x8 | ||
|
|
||
| #define BUTTRESS_REG_SENSOR_FREQ_CTL 0x16c | ||
|
|
||
| #define BUTTRESS_SENSOR_FREQ_CTL_OSC_OUT_FREQ_DEFAULT(i) \ | ||
| (0x1b << ((i) * 10)) | ||
| #define BUTTRESS_SENSOR_FREQ_CTL_OSC_OUT_FREQ_SHIFT(i) ((i) * 10) | ||
| #define BUTTRESS_SENSOR_FREQ_CTL_OSC_OUT_FREQ_MASK(i) \ | ||
| (0x1ff << ((i) * 10)) | ||
|
|
||
| #define BUTTRESS_SENSOR_CLK_FREQ_6P75MHZ 0x176 | ||
| #define BUTTRESS_SENSOR_CLK_FREQ_8MHZ 0x164 | ||
| #define BUTTRESS_SENSOR_CLK_FREQ_9P6MHZ 0x2 | ||
| #define BUTTRESS_SENSOR_CLK_FREQ_12MHZ 0x1b2 | ||
| #define BUTTRESS_SENSOR_CLK_FREQ_13P6MHZ 0x1ac | ||
| #define BUTTRESS_SENSOR_CLK_FREQ_14P4MHZ 0x1cc | ||
| #define BUTTRESS_SENSOR_CLK_FREQ_15P8MHZ 0x1a6 | ||
| #define BUTTRESS_SENSOR_CLK_FREQ_16P2MHZ 0xca | ||
| #define BUTTRESS_SENSOR_CLK_FREQ_17P3MHZ 0x12e | ||
| #define BUTTRESS_SENSOR_CLK_FREQ_18P6MHZ 0x1c0 | ||
| #define BUTTRESS_SENSOR_CLK_FREQ_19P2MHZ 0x0 | ||
| #define BUTTRESS_SENSOR_CLK_FREQ_24MHZ 0xb2 | ||
| #define BUTTRESS_SENSOR_CLK_FREQ_26MHZ 0xae | ||
| #define BUTTRESS_SENSOR_CLK_FREQ_27MHZ 0x196 | ||
|
|
||
| #define BUTTRESS_SENSOR_FREQ_CTL_LJPLL_FB_RATIO_MASK 0xff | ||
| #define BUTTRESS_SENSOR_FREQ_CTL_SEL_MIPICLK_A_SHIFT 8 | ||
| #define BUTTRESS_SENSOR_FREQ_CTL_SEL_MIPICLK_A_MASK (0x2 << 8) | ||
| #define BUTTRESS_SENSOR_FREQ_CTL_SEL_MIPICLK_C_SHIFT 10 | ||
| #define BUTTRESS_SENSOR_FREQ_CTL_SEL_MIPICLK_C_MASK (0x2 << 10) | ||
| #define BUTTRESS_SENSOR_FREQ_CTL_LJPLL_FORCE_OFF_SHIFT 12 | ||
| #define BUTTRESS_SENSOR_FREQ_CTL_LJPLL_REF_RATIO_SHIFT 14 | ||
| #define BUTTRESS_SENSOR_FREQ_CTL_LJPLL_REF_RATIO_MASK (0x2 << 14) | ||
| #define BUTTRESS_SENSOR_FREQ_CTL_LJPLL_PVD_RATIO_SHIFT 16 | ||
| #define BUTTRESS_SENSOR_FREQ_CTL_LJPLL_PVD_RATIO_MASK (0x2 << 16) | ||
| #define BUTTRESS_SENSOR_FREQ_CTL_LJPLL_OUTPUT_RATIO_SHIFT 18 | ||
| #define BUTTRESS_SENSOR_FREQ_CTL_LJPLL_OUTPUT_RATIO_MASK (0x2 << 18) | ||
| #define BUTTRESS_SENSOR_FREQ_CTL_START_SHIFT 31 | ||
|
|
||
| #define BUTTRESS_REG_SENSOR_CLK_CTL 0x170 | ||
|
|
||
| /* 0 <= i <= 2 */ | ||
| #define BUTTRESS_SENSOR_CLK_CTL_OSC_CLK_OUT_EN_SHIFT(i) ((i) * 2) | ||
| #define BUTTRESS_SENSOR_CLK_CTL_OSC_CLK_OUT_SEL_SHIFT(i) ((i) * 2 + 1) | ||
|
|
||
| #define BUTTRESS_REG_FW_SOURCE_BASE_LO 0x78 | ||
| #define BUTTRESS_REG_FW_SOURCE_BASE_HI 0x7C | ||
| #define BUTTRESS_REG_FW_SOURCE_SIZE 0x80 | ||
|
|
||
| #define BUTTRESS_REG_ISR_STATUS 0x90 | ||
| #define BUTTRESS_REG_ISR_ENABLED_STATUS 0x94 | ||
| #define BUTTRESS_REG_ISR_ENABLE 0x98 | ||
| #define BUTTRESS_REG_ISR_CLEAR 0x9C | ||
|
|
||
| #define BUTTRESS_ISR_IS_IRQ BIT(0) | ||
| #define BUTTRESS_ISR_PS_IRQ BIT(1) | ||
| #define BUTTRESS_ISR_IPC_EXEC_DONE_BY_CSE BIT(2) | ||
| #define BUTTRESS_ISR_IPC_EXEC_DONE_BY_ISH BIT(3) | ||
| #define BUTTRESS_ISR_IPC_FROM_CSE_IS_WAITING BIT(4) | ||
| #define BUTTRESS_ISR_IPC_FROM_ISH_IS_WAITING BIT(5) | ||
| #define BUTTRESS_ISR_CSE_CSR_SET BIT(6) | ||
| #define BUTTRESS_ISR_ISH_CSR_SET BIT(7) | ||
| #define BUTTRESS_ISR_SPURIOUS_CMP BIT(8) | ||
| #define BUTTRESS_ISR_WATCHDOG_EXPIRED BIT(9) | ||
| #define BUTTRESS_ISR_PUNIT_2_IUNIT_IRQ BIT(10) | ||
| #define BUTTRESS_ISR_SAI_VIOLATION BIT(11) | ||
| #define BUTTRESS_ISR_HW_ASSERTION BIT(12) | ||
|
|
||
| #define BUTTRESS_REG_IU2CSEDB0 0x100 | ||
|
|
||
| #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_REG_IU2CSEDATA0 0x104 | ||
|
|
||
| #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 1 | ||
| #define BUTTRESS_CSE2IUDATA0_IPC_AUTH_RUN_DONE 2 | ||
| #define BUTTRESS_CSE2IUDATA0_IPC_AUTH_REPLACE_DONE 4 | ||
| #define BUTTRESS_CSE2IUDATA0_IPC_UPDATE_SECURE_TOUCH_DONE 16 | ||
|
|
||
| #define BUTTRESS_REG_IU2CSECSR 0x108 | ||
|
|
||
| #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) | ||
|
|
||
| #define BUTTRESS_REG_CSE2IUDB0 0x304 | ||
| #define BUTTRESS_REG_CSE2IUCSR 0x30C | ||
| #define BUTTRESS_REG_CSE2IUDATA0 0x308 | ||
|
|
||
| /* 0x20 == NACK, 0xf == unknown command */ | ||
| #define BUTTRESS_CSE2IUDATA0_IPC_NACK 0xf20 | ||
| #define BUTTRESS_CSE2IUDATA0_IPC_NACK_MASK 0xffff | ||
|
|
||
| #define BUTTRESS_REG_ISH2IUCSR 0x50 | ||
| #define BUTTRESS_REG_ISH2IUDB0 0x54 | ||
| #define BUTTRESS_REG_ISH2IUDATA0 0x58 | ||
|
|
||
| #define BUTTRESS_REG_IU2ISHDB0 0x10C | ||
| #define BUTTRESS_REG_IU2ISHDATA0 0x110 | ||
| #define BUTTRESS_REG_IU2ISHDATA1 0x114 | ||
| #define BUTTRESS_REG_IU2ISHCSR 0x118 | ||
|
|
||
| #define BUTTRESS_REG_ISH_START_DETECT 0x198 | ||
| #define BUTTRESS_REG_ISH_START_DETECT_MASK 0x19C | ||
|
|
||
| #define BUTTRESS_REG_FABRIC_CMD 0x88 | ||
|
|
||
| #define BUTTRESS_FABRIC_CMD_START_TSC_SYNC BIT(0) | ||
| #define BUTTRESS_FABRIC_CMD_IS_DRAIN BIT(4) | ||
|
|
||
| #define BUTTRESS_REG_TSW_CTL 0x120 | ||
| #define BUTTRESS_TSW_CTL_SOFT_RESET BIT(8) | ||
|
|
||
| #define BUTTRESS_REG_TSC_LO 0x164 | ||
| #define BUTTRESS_REG_TSC_HI 0x168 | ||
|
|
||
| #define BUTTRESS_REG_CSI2_PORT_CONFIG_AB 0x200 | ||
| #define BUTTRESS_CSI2_PORT_CONFIG_AB_MUX_MASK 0x1f | ||
| #define BUTTRESS_CSI2_PORT_CONFIG_AB_COMBO_SHIFT_B0 16 | ||
|
|
||
| #define BUTTRESS_REG_PS_FREQ_CAPABILITIES 0xf7498 | ||
|
|
||
| #define BUTTRESS_PS_FREQ_CAPABILITIES_LAST_RESOLVED_RATIO_SHIFT 24 | ||
| #define BUTTRESS_PS_FREQ_CAPABILITIES_LAST_RESOLVED_RATIO_MASK (0xff << 24) | ||
| #define BUTTRESS_PS_FREQ_CAPABILITIES_MAX_RATIO_SHIFT 16 | ||
| #define BUTTRESS_PS_FREQ_CAPABILITIES_MAX_RATIO_MASK (0xff << 16) | ||
| #define BUTTRESS_PS_FREQ_CAPABILITIES_EFFICIENT_RATIO_SHIFT 8 | ||
| #define BUTTRESS_PS_FREQ_CAPABILITIES_EFFICIENT_RATIO_MASK (0xff << 8) | ||
| #define BUTTRESS_PS_FREQ_CAPABILITIES_MIN_RATIO_SHIFT 0 | ||
| #define BUTTRESS_PS_FREQ_CAPABILITIES_MIN_RATIO_MASK (0xff) | ||
|
|
||
| #define BUTTRESS_IRQS (BUTTRESS_ISR_IPC_FROM_CSE_IS_WAITING | \ | ||
| BUTTRESS_ISR_IPC_EXEC_DONE_BY_CSE | \ | ||
| BUTTRESS_ISR_IS_IRQ | \ | ||
| BUTTRESS_ISR_PS_IRQ) | ||
|
|
||
| #define IPU6SE_ISYS_PHY_0_BASE 0x10000 | ||
|
|
||
| /* only use BB0, BB2, BB4, and BB6 on PHY0 */ | ||
| #define IPU6SE_ISYS_PHY_BB_NUM 4 | ||
|
|
||
| /* 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)) | ||
|
|
||
| #endif /* IPU_PLATFORM_BUTTRESS_REGS_H */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,277 @@ | ||
| /* SPDX-License-Identifier: GPL-2.0 */ | ||
| /* Copyright (C) 2020 Intel Corporation */ | ||
|
|
||
| #ifndef IPU_PLATFORM_ISYS_CSI2_REG_H | ||
| #define IPU_PLATFORM_ISYS_CSI2_REG_H | ||
|
|
||
| #define CSI_REG_BASE 0x220000 | ||
| #define CSI_REG_BASE_PORT(id) ((id) * 0x1000) | ||
|
|
||
| #define IPU_CSI_PORT_A_ADDR_OFFSET \ | ||
| (CSI_REG_BASE + CSI_REG_BASE_PORT(0)) | ||
| #define IPU_CSI_PORT_B_ADDR_OFFSET \ | ||
| (CSI_REG_BASE + CSI_REG_BASE_PORT(1)) | ||
| #define IPU_CSI_PORT_C_ADDR_OFFSET \ | ||
| (CSI_REG_BASE + CSI_REG_BASE_PORT(2)) | ||
| #define IPU_CSI_PORT_D_ADDR_OFFSET \ | ||
| (CSI_REG_BASE + CSI_REG_BASE_PORT(3)) | ||
| #define IPU_CSI_PORT_E_ADDR_OFFSET \ | ||
| (CSI_REG_BASE + CSI_REG_BASE_PORT(4)) | ||
| #define IPU_CSI_PORT_F_ADDR_OFFSET \ | ||
| (CSI_REG_BASE + CSI_REG_BASE_PORT(5)) | ||
| #define IPU_CSI_PORT_G_ADDR_OFFSET \ | ||
| (CSI_REG_BASE + CSI_REG_BASE_PORT(6)) | ||
| #define IPU_CSI_PORT_H_ADDR_OFFSET \ | ||
| (CSI_REG_BASE + CSI_REG_BASE_PORT(7)) | ||
|
|
||
| /* CSI Port Genral Purpose Registers */ | ||
| #define CSI_REG_PORT_GPREG_SRST 0x0 | ||
| #define CSI_REG_PORT_GPREG_CSI2_SLV_REG_SRST 0x4 | ||
| #define CSI_REG_PORT_GPREG_CSI2_PORT_CONTROL 0x8 | ||
|
|
||
| /* | ||
| * Port IRQs mapping events: | ||
| * IRQ0 - CSI_FE event | ||
| * IRQ1 - CSI_SYNC | ||
| * IRQ2 - S2M_SIDS0TO7 | ||
| * IRQ3 - S2M_SIDS8TO15 | ||
| */ | ||
| #define CSI_PORT_REG_BASE_IRQ_CSI 0x80 | ||
| #define CSI_PORT_REG_BASE_IRQ_CSI_SYNC 0xA0 | ||
| #define CSI_PORT_REG_BASE_IRQ_S2M_SIDS0TOS7 0xC0 | ||
| #define CSI_PORT_REG_BASE_IRQ_S2M_SIDS8TOS15 0xE0 | ||
|
|
||
| #define CSI_PORT_REG_BASE_IRQ_EDGE_OFFSET 0x0 | ||
| #define CSI_PORT_REG_BASE_IRQ_MASK_OFFSET 0x4 | ||
| #define CSI_PORT_REG_BASE_IRQ_STATUS_OFFSET 0x8 | ||
| #define CSI_PORT_REG_BASE_IRQ_CLEAR_OFFSET 0xc | ||
| #define CSI_PORT_REG_BASE_IRQ_ENABLE_OFFSET 0x10 | ||
| #define CSI_PORT_REG_BASE_IRQ_LEVEL_NOT_PULSE_OFFSET 0x14 | ||
|
|
||
| #define IPU6SE_CSI_RX_ERROR_IRQ_MASK 0x7ffff | ||
| #define IPU6_CSI_RX_ERROR_IRQ_MASK 0xfffff | ||
|
|
||
| #define CSI_RX_NUM_ERRORS_IN_IRQ 20 | ||
| #define CSI_RX_NUM_IRQ 32 | ||
|
|
||
| #define IPU_CSI_RX_IRQ_FS_VC 1 | ||
| #define IPU_CSI_RX_IRQ_FE_VC 2 | ||
|
|
||
| /* PPI2CSI */ | ||
| #define CSI_REG_PPI2CSI_ENABLE 0x200 | ||
| #define CSI_REG_PPI2CSI_CONFIG_PPI_INTF 0x204 | ||
| #define PPI_INTF_CONFIG_NOF_ENABLED_DATALANES_SHIFT 3 | ||
| #define PPI_INTF_CONFIG_RX_AUTO_CLKGATING_SHIFT 5 | ||
| #define CSI_REG_PPI2CSI_CONFIG_CSI_FEATURE 0x208 | ||
|
|
||
| enum CSI_PPI2CSI_CTRL { | ||
| CSI_PPI2CSI_DISABLE = 0, | ||
| CSI_PPI2CSI_ENABLE = 1, | ||
| }; | ||
|
|
||
| /* CSI_FE */ | ||
| #define CSI_REG_CSI_FE_ENABLE 0x280 | ||
| #define CSI_REG_CSI_FE_MODE 0x284 | ||
| #define CSI_REG_CSI_FE_MUX_CTRL 0x288 | ||
| #define CSI_REG_CSI_FE_SYNC_CNTR_SEL 0x290 | ||
|
|
||
| enum CSI_FE_ENABLE_TYPE { | ||
| CSI_FE_DISABLE = 0, | ||
| CSI_FE_ENABLE = 1, | ||
| }; | ||
|
|
||
| enum CSI_FE_MODE_TYPE { | ||
| CSI_FE_DPHY_MODE = 0, | ||
| CSI_FE_CPHY_MODE = 1, | ||
| }; | ||
|
|
||
| enum CSI_FE_INPUT_SELECTOR { | ||
| CSI_SENSOR_INPUT = 0, | ||
| CSI_MIPIGEN_INPUT = 1, | ||
| }; | ||
|
|
||
| enum CSI_FE_SYNC_CNTR_SEL_TYPE { | ||
| CSI_CNTR_SENSOR_LINE_ID = (1 << 0), | ||
| CSI_CNTR_INT_LINE_PKT_ID = ~CSI_CNTR_SENSOR_LINE_ID, | ||
| CSI_CNTR_SENSOR_FRAME_ID = (1 << 1), | ||
| CSI_CNTR_INT_FRAME_PKT_ID = ~CSI_CNTR_SENSOR_FRAME_ID, | ||
| }; | ||
|
|
||
| /* MIPI_PKT_GEN */ | ||
| #define CSI_REG_PIXGEN_COM_BASE_OFFSET 0x300 | ||
|
|
||
| #define IPU_CSI_PORT_A_PIXGEN_ADDR_OFFSET \ | ||
| (CSI_REG_BASE + CSI_REG_BASE_PORT(0) + CSI_REG_PIXGEN_COM_BASE_OFFSET) | ||
| #define IPU_CSI_PORT_B_PIXGEN_ADDR_OFFSET \ | ||
| (CSI_REG_BASE + CSI_REG_BASE_PORT(1) + CSI_REG_PIXGEN_COM_BASE_OFFSET) | ||
| #define IPU_CSI_PORT_C_PIXGEN_ADDR_OFFSET \ | ||
| (CSI_REG_BASE + CSI_REG_BASE_PORT(2) + CSI_REG_PIXGEN_COM_BASE_OFFSET) | ||
| #define IPU_CSI_PORT_D_PIXGEN_ADDR_OFFSET \ | ||
| (CSI_REG_BASE + CSI_REG_BASE_PORT(3) + CSI_REG_PIXGEN_COM_BASE_OFFSET) | ||
| #define IPU_CSI_PORT_E_PIXGEN_ADDR_OFFSET \ | ||
| (CSI_REG_BASE + CSI_REG_BASE_PORT(4) + CSI_REG_PIXGEN_COM_BASE_OFFSET) | ||
| #define IPU_CSI_PORT_F_PIXGEN_ADDR_OFFSET \ | ||
| (CSI_REG_BASE + CSI_REG_BASE_PORT(5) + CSI_REG_PIXGEN_COM_BASE_OFFSET) | ||
| #define IPU_CSI_PORT_G_PIXGEN_ADDR_OFFSET \ | ||
| (CSI_REG_BASE + CSI_REG_BASE_PORT(6) + CSI_REG_PIXGEN_COM_BASE_OFFSET) | ||
| #define IPU_CSI_PORT_H_PIXGEN_ADDR_OFFSET \ | ||
| (CSI_REG_BASE + CSI_REG_BASE_PORT(7) + CSI_REG_PIXGEN_COM_BASE_OFFSET) | ||
|
|
||
| #define CSI_REG_PIXGEN_COM_ENABLE_REG_IDX(id) \ | ||
| (CSI_REG_BASE_PORT(id) + 0x300) | ||
| #define CSI_REG_PIXGEN_COM_DTYPE_REG_IDX(id) \ | ||
| (CSI_REG_BASE_PORT(id) + 0x304) | ||
| #define CSI_REG_PIXGEN_COM_VTYPE_REG_IDX(id) \ | ||
| (CSI_REG_BASE_PORT(id) + 0x308) | ||
| #define CSI_REG_PIXGEN_COM_VCHAN_REG_IDX(id) \ | ||
| (CSI_REG_BASE_PORT(id) + 0x30C) | ||
| #define CSI_REG_PIXGEN_COM_WCOUNT_REG_IDX(id) \ | ||
| (CSI_REG_BASE_PORT(id) + 0x310) | ||
| /* PRBS */ | ||
| #define CSI_REG_PIXGEN_PRBS_RSTVAL_REG0_IDX(id) \ | ||
| (CSI_REG_BASE_PORT(id) + 0x314) | ||
| #define CSI_REG_PIXGEN_PRBS_RSTVAL_REG1_IDX(id) \ | ||
| (CSI_REG_BASE_PORT(id) + 0x318) | ||
| /* SYNC_GENERATOR_CONFIG */ | ||
| #define CSI_REG_PIXGEN_SYNG_FREE_RUN_REG_IDX(id) \ | ||
| (CSI_REG_BASE_PORT(id) + 0x31C) | ||
| #define CSI_REG_PIXGEN_SYNG_PAUSE_REG_IDX(id) \ | ||
| (CSI_REG_BASE_PORT(id) + 0x320) | ||
| #define CSI_REG_PIXGEN_SYNG_NOF_FRAME_REG_IDX(id) \ | ||
| (CSI_REG_BASE_PORT(id) + 0x324) | ||
| #define CSI_REG_PIXGEN_SYNG_NOF_PIXEL_REG_IDX(id) \ | ||
| (CSI_REG_BASE_PORT(id) + 0x328) | ||
| #define CSI_REG_PIXGEN_SYNG_NOF_LINE_REG_IDX(id) \ | ||
| (CSI_REG_BASE_PORT(id) + 0x32C) | ||
| #define CSI_REG_PIXGEN_SYNG_HBLANK_CYC_REG_IDX(id) \ | ||
| (CSI_REG_BASE_PORT(id) + 0x330) | ||
| #define CSI_REG_PIXGEN_SYNG_VBLANK_CYC_REG_IDX(id) \ | ||
| (CSI_REG_BASE_PORT(id) + 0x334) | ||
| #define CSI_REG_PIXGEN_SYNG_STAT_HCNT_REG_IDX(id) \ | ||
| (CSI_REG_BASE_PORT(id) + 0x338) | ||
| #define CSI_REG_PIXGEN_SYNG_STAT_VCNT_REG_IDX(id) \ | ||
| (CSI_REG_BASE_PORT(id) + 0x33C) | ||
| #define CSI_REG_PIXGEN_SYNG_STAT_FCNT_REG_IDX(id) \ | ||
| (CSI_REG_BASE_PORT(id) + 0x340) | ||
| #define CSI_REG_PIXGEN_SYNG_STAT_DONE_REG_IDX(id) \ | ||
| (CSI_REG_BASE_PORT(id) + 0x344) | ||
| /* TPG */ | ||
| #define CSI_REG_PIXGEN_TPG_MODE_REG_IDX(id) \ | ||
| (CSI_REG_BASE_PORT(id) + 0x348) | ||
| /* TPG: mask_cfg */ | ||
| #define CSI_REG_PIXGEN_TPG_HCNT_MASK_REG_IDX(id) \ | ||
| (CSI_REG_BASE_PORT(id) + 0x34C) | ||
| #define CSI_REG_PIXGEN_TPG_VCNT_MASK_REG_IDX(id) \ | ||
| (CSI_REG_BASE_PORT(id) + 0x350) | ||
| #define CSI_REG_PIXGEN_TPG_XYCNT_MASK_REG_IDX(id) \ | ||
| (CSI_REG_BASE_PORT(id) + 0x354) | ||
| /* TPG: delta_cfg */ | ||
| #define CSI_REG_PIXGEN_TPG_HCNT_DELTA_REG_IDX(id) \ | ||
| (CSI_REG_BASE_PORT(id) + 0x358) | ||
| #define CSI_REG_PIXGEN_TPG_VCNT_DELTA_REG_IDX(id) \ | ||
| (CSI_REG_BASE_PORT(id) + 0x35C) | ||
| /* TPG: color_cfg */ | ||
| #define CSI_REG_PIXGEN_TPG_R1_REG_IDX(id) (CSI_REG_BASE_PORT(id) + 0x360) | ||
| #define CSI_REG_PIXGEN_TPG_G1_REG_IDX(id) (CSI_REG_BASE_PORT(id) + 0x364) | ||
| #define CSI_REG_PIXGEN_TPG_B1_REG_IDX(id) (CSI_REG_BASE_PORT(id) + 0x368) | ||
| #define CSI_REG_PIXGEN_TPG_R2_REG_IDX(id) (CSI_REG_BASE_PORT(id) + 0x36C) | ||
| #define CSI_REG_PIXGEN_TPG_G2_REG_IDX(id) (CSI_REG_BASE_PORT(id) + 0x370) | ||
| #define CSI_REG_PIXGEN_TPG_B2_REG_IDX(id) (CSI_REG_BASE_PORT(id) + 0x374) | ||
|
|
||
| #define CSI_REG_PIXGEN_PRBS_RSTVAL_REG0 CSI_REG_PIXGEN_PRBS_RSTVAL_REG0_IDX(0) | ||
| #define CSI_REG_PIXGEN_PRBS_RSTVAL_REG1 CSI_REG_PIXGEN_PRBS_RSTVAL_REG1_IDX(0) | ||
| #define CSI_REG_PIXGEN_COM_ENABLE_REG CSI_REG_PIXGEN_COM_ENABLE_REG_IDX(0) | ||
| #define CSI_REG_PIXGEN_TPG_MODE_REG CSI_REG_PIXGEN_TPG_MODE_REG_IDX(0) | ||
| #define CSI_REG_PIXGEN_TPG_R1_REG CSI_REG_PIXGEN_TPG_R1_REG_IDX(0) | ||
| #define CSI_REG_PIXGEN_TPG_G1_REG CSI_REG_PIXGEN_TPG_G1_REG_IDX(0) | ||
| #define CSI_REG_PIXGEN_TPG_B1_REG CSI_REG_PIXGEN_TPG_B1_REG_IDX(0) | ||
| #define CSI_REG_PIXGEN_TPG_R2_REG CSI_REG_PIXGEN_TPG_R2_REG_IDX(0) | ||
| #define CSI_REG_PIXGEN_TPG_G2_REG CSI_REG_PIXGEN_TPG_G2_REG_IDX(0) | ||
| #define CSI_REG_PIXGEN_TPG_B2_REG CSI_REG_PIXGEN_TPG_B2_REG_IDX(0) | ||
| #define CSI_REG_PIXGEN_TPG_HCNT_MASK_REG CSI_REG_PIXGEN_TPG_HCNT_MASK_REG_IDX(0) | ||
| #define CSI_REG_PIXGEN_TPG_VCNT_MASK_REG CSI_REG_PIXGEN_TPG_VCNT_MASK_REG_IDX(0) | ||
| #define CSI_REG_PIXGEN_TPG_XYCNT_MASK_REG \ | ||
| CSI_REG_PIXGEN_TPG_XYCNT_MASK_REG_IDX(0) | ||
|
|
||
| #define CSI_REG_PIXGEN_SYNG_NOF_FRAME_REG \ | ||
| CSI_REG_PIXGEN_SYNG_NOF_FRAME_REG_IDX(0) | ||
| #define CSI_REG_PIXGEN_SYNG_NOF_LINE_REG \ | ||
| CSI_REG_PIXGEN_SYNG_NOF_LINE_REG_IDX(0) | ||
| #define CSI_REG_PIXGEN_SYNG_HBLANK_CYC_REG \ | ||
| CSI_REG_PIXGEN_SYNG_HBLANK_CYC_REG_IDX(0) | ||
| #define CSI_REG_PIXGEN_SYNG_VBLANK_CYC_REG \ | ||
| CSI_REG_PIXGEN_SYNG_VBLANK_CYC_REG_IDX(0) | ||
| #define CSI_REG_PIXGEN_SYNG_NOF_PIXEL_REG \ | ||
| CSI_REG_PIXGEN_SYNG_NOF_PIXEL_REG_IDX(0) | ||
| #define CSI_REG_PIXGEN_COM_WCOUNT_REG CSI_REG_PIXGEN_COM_WCOUNT_REG_IDX(0) | ||
| #define CSI_REG_PIXGEN_COM_DTYPE_REG CSI_REG_PIXGEN_COM_DTYPE_REG_IDX(0) | ||
| #define CSI_REG_PIXGEN_COM_VTYPE_REG CSI_REG_PIXGEN_COM_VTYPE_REG_IDX(0) | ||
| #define CSI_REG_PIXGEN_COM_VCHAN_REG CSI_REG_PIXGEN_COM_VCHAN_REG_IDX(0) | ||
| #define CSI_REG_PIXGEN_TPG_HCNT_DELTA_REG \ | ||
| CSI_REG_PIXGEN_TPG_HCNT_DELTA_REG_IDX(0) | ||
| #define CSI_REG_PIXGEN_TPG_VCNT_DELTA_REG \ | ||
| CSI_REG_PIXGEN_TPG_VCNT_DELTA_REG_IDX(0) | ||
|
|
||
| /* CSI HUB General Purpose Registers */ | ||
| #define CSI_REG_HUB_GPREG_SRST (CSI_REG_BASE + 0x18000) | ||
| #define CSI_REG_HUB_GPREG_SLV_REG_SRST (CSI_REG_BASE + 0x18004) | ||
| #define CSI_REG_HUB_GPREG_PHY_CONTROL(id) \ | ||
| (CSI_REG_BASE + 0x18008 + (id) * 0x8) | ||
| #define CSI_REG_HUB_GPREG_PHY_CONTROL_RESET BIT(4) | ||
| #define CSI_REG_HUB_GPREG_PHY_CONTROL_PWR_EN BIT(0) | ||
| #define CSI_REG_HUB_GPREG_PHY_STATUS(id) \ | ||
| (CSI_REG_BASE + 0x1800c + (id) * 0x8) | ||
| #define CSI_REG_HUB_GPREG_PHY_STATUS_POWER_ACK BIT(0) | ||
| #define CSI_REG_HUB_GPREG_PHY_STATUS_PHY_READY BIT(4) | ||
|
|
||
| #define CSI_REG_HUB_DRV_ACCESS_PORT(id) (CSI_REG_BASE + 0x18018 + (id) * 4) | ||
| #define CSI_REG_HUB_FW_ACCESS_PORT(id) (CSI_REG_BASE + 0x17000 + (id) * 4) | ||
|
|
||
| enum CSI_PORT_CLK_GATING_SWITCH { | ||
| CSI_PORT_CLK_GATING_OFF = 0, | ||
| CSI_PORT_CLK_GATING_ON = 1, | ||
| }; | ||
|
|
||
| #define CSI_REG_BASE_HUB_IRQ 0x18200 | ||
|
|
||
| #define IPU_NUM_OF_DLANE_REG_PORT0 2 | ||
| #define IPU_NUM_OF_DLANE_REG_PORT1 4 | ||
| #define IPU_NUM_OF_DLANE_REG_PORT2 4 | ||
| #define IPU_NUM_OF_DLANE_REG_PORT3 2 | ||
| #define IPU_NUM_OF_DLANE_REG_PORT4 2 | ||
| #define IPU_NUM_OF_DLANE_REG_PORT5 4 | ||
| #define IPU_NUM_OF_DLANE_REG_PORT6 4 | ||
| #define IPU_NUM_OF_DLANE_REG_PORT7 2 | ||
|
|
||
| /* ipu6se support 2 SIPs, 2 port per SIP, 4 ports 0..3 | ||
| * sip0 - 0, 1 | ||
| * sip1 - 2, 3 | ||
| * 0 and 2 support 4 data lanes, 1 and 3 support 2 data lanes | ||
| * all offset are base from isys base address | ||
| */ | ||
|
|
||
| #define CSI2_HUB_GPREG_SIP_SRST(sip) (0x238038 + (sip) * 4) | ||
| #define CSI2_HUB_GPREG_SIP_FB_PORT_CFG(sip) (0x238050 + (sip) * 4) | ||
|
|
||
| #define CSI2_HUB_GPREG_DPHY_TIMER_INCR (0x238040) | ||
| #define CSI2_HUB_GPREG_HPLL_FREQ (0x238044) | ||
| #define CSI2_HUB_GPREG_IS_CLK_RATIO (0x238048) | ||
| #define CSI2_HUB_GPREG_HPLL_FREQ_ISCLK_RATE_OVERRIDE (0x23804c) | ||
| #define CSI2_HUB_GPREG_PORT_CLKGATING_DISABLE (0x238058) | ||
| #define CSI2_HUB_GPREG_SIP0_CSI_RX_A_CONTROL (0x23805c) | ||
| #define CSI2_HUB_GPREG_SIP0_CSI_RX_B_CONTROL (0x238088) | ||
| #define CSI2_HUB_GPREG_SIP1_CSI_RX_A_CONTROL (0x2380a4) | ||
| #define CSI2_HUB_GPREG_SIP1_CSI_RX_B_CONTROL (0x2380d0) | ||
|
|
||
| #define CSI2_SIP_TOP_CSI_RX_BASE(sip) (0x23805c + (sip) * 0x48) | ||
| #define CSI2_SIP_TOP_CSI_RX_PORT_BASE_0(port) (0x23805c + ((port) / 2) * 0x48) | ||
| #define CSI2_SIP_TOP_CSI_RX_PORT_BASE_1(port) (0x238088 + ((port) / 2) * 0x48) | ||
|
|
||
| /* offset from port base */ | ||
| #define CSI2_SIP_TOP_CSI_RX_PORT_CONTROL (0x0) | ||
| #define CSI2_SIP_TOP_CSI_RX_DLY_CNT_TERMEN_CLANE (0x4) | ||
| #define CSI2_SIP_TOP_CSI_RX_DLY_CNT_SETTLE_CLANE (0x8) | ||
| #define CSI2_SIP_TOP_CSI_RX_DLY_CNT_TERMEN_DLANE(lane) (0xc + (lane) * 8) | ||
| #define CSI2_SIP_TOP_CSI_RX_DLY_CNT_SETTLE_DLANE(lane) (0x10 + (lane) * 8) | ||
|
|
||
| #endif /* IPU6_ISYS_CSI2_REG_H */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| /* SPDX-License-Identifier: GPL-2.0 */ | ||
| /* Copyright (C) 2020 Intel Corporation */ | ||
|
|
||
| #ifndef IPU_PLATFORM_ISYS_H | ||
| #define IPU_PLATFORM_ISYS_H | ||
|
|
||
| #define IPU_ISYS_ENTITY_PREFIX "Intel IPU6" | ||
|
|
||
| /* | ||
| * FW support max 16 streams | ||
| */ | ||
| #define IPU_ISYS_MAX_STREAMS 16 | ||
|
|
||
| #define ISYS_UNISPART_IRQS (IPU_ISYS_UNISPART_IRQ_SW | \ | ||
| IPU_ISYS_UNISPART_IRQ_CSI0 | \ | ||
| IPU_ISYS_UNISPART_IRQ_CSI1) | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| /* SPDX-License-Identifier: GPL-2.0 */ | ||
| /* Copyright (C) 2020 Intel Corporation */ | ||
|
|
||
| #ifndef IPU_PLATFORM_PSYS_H | ||
| #define IPU_PLATFORM_PSYS_H | ||
|
|
||
| #include "ipu-psys.h" | ||
| #include <uapi/linux/ipu-psys.h> | ||
|
|
||
| #define IPU_PSYS_BUF_SET_POOL_SIZE 8 | ||
| #define IPU_PSYS_BUF_SET_MAX_SIZE 1024 | ||
|
|
||
| struct ipu_fw_psys_buffer_set; | ||
|
|
||
| enum ipu_psys_cmd_state { | ||
| KCMD_STATE_PPG_NEW, | ||
| KCMD_STATE_PPG_START, | ||
| KCMD_STATE_PPG_ENQUEUE, | ||
| KCMD_STATE_PPG_STOP, | ||
| KCMD_STATE_PPG_COMPLETE | ||
| }; | ||
|
|
||
| struct ipu_psys_scheduler { | ||
| struct list_head ppgs; | ||
| struct mutex bs_mutex; /* Protects buf_set field */ | ||
| struct list_head buf_sets; | ||
| }; | ||
|
|
||
| enum ipu_psys_ppg_state { | ||
| PPG_STATE_START = (1 << 0), | ||
| PPG_STATE_STARTING = (1 << 1), | ||
| PPG_STATE_STARTED = (1 << 2), | ||
| PPG_STATE_RUNNING = (1 << 3), | ||
| PPG_STATE_SUSPEND = (1 << 4), | ||
| PPG_STATE_SUSPENDING = (1 << 5), | ||
| PPG_STATE_SUSPENDED = (1 << 6), | ||
| PPG_STATE_RESUME = (1 << 7), | ||
| PPG_STATE_RESUMING = (1 << 8), | ||
| PPG_STATE_RESUMED = (1 << 9), | ||
| PPG_STATE_STOP = (1 << 10), | ||
| PPG_STATE_STOPPING = (1 << 11), | ||
| PPG_STATE_STOPPED = (1 << 12), | ||
| }; | ||
|
|
||
| struct ipu_psys_ppg { | ||
| struct ipu_psys_pg *kpg; | ||
| struct ipu_psys_fh *fh; | ||
| struct list_head list; | ||
| struct list_head sched_list; | ||
| u64 token; | ||
| void *manifest; | ||
| struct mutex mutex; /* Protects kcmd and ppg state field */ | ||
| struct list_head kcmds_new_list; | ||
| struct list_head kcmds_processing_list; | ||
| struct list_head kcmds_finished_list; | ||
| enum ipu_psys_ppg_state state; | ||
| u32 pri_base; | ||
| int pri_dynamic; | ||
| }; | ||
|
|
||
| struct ipu_psys_buffer_set { | ||
| struct list_head list; | ||
| struct ipu_fw_psys_buffer_set *buf_set; | ||
| size_t size; | ||
| size_t buf_set_size; | ||
| dma_addr_t dma_addr; | ||
| void *kaddr; | ||
| struct ipu_psys_kcmd *kcmd; | ||
| }; | ||
|
|
||
| int ipu_psys_kcmd_start(struct ipu_psys *psys, struct ipu_psys_kcmd *kcmd); | ||
| void ipu_psys_kcmd_complete(struct ipu_psys *psys, struct ipu_psys_kcmd *kcmd, | ||
| int error); | ||
| int ipu_psys_fh_init(struct ipu_psys_fh *fh); | ||
| int ipu_psys_fh_deinit(struct ipu_psys_fh *fh); | ||
|
|
||
| #endif /* IPU_PLATFORM_PSYS_H */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,333 @@ | ||
| /* SPDX-License-Identifier: GPL-2.0 */ | ||
| /* Copyright (C) 2018 - 2020 Intel Corporation */ | ||
|
|
||
| #ifndef IPU_PLATFORM_REGS_H | ||
| #define IPU_PLATFORM_REGS_H | ||
|
|
||
| /* | ||
| * IPU6 uses uniform address within IPU, therefore all subsystem registers | ||
| * locates in one signle space starts from 0 but in different sctions with | ||
| * with different addresses, the subsystem offsets are defined to 0 as the | ||
| * register definition will have the address offset to 0. | ||
| */ | ||
| #define IPU_UNIFIED_OFFSET 0 | ||
|
|
||
| #define IPU_ISYS_IOMMU0_OFFSET 0x2E0000 | ||
| #define IPU_ISYS_IOMMU1_OFFSET 0x2E0500 | ||
| #define IPU_ISYS_IOMMUI_OFFSET 0x2E0A00 | ||
|
|
||
| #define IPU_PSYS_IOMMU0_OFFSET 0x1B0000 | ||
| #define IPU_PSYS_IOMMU1_OFFSET 0x1B0700 | ||
| #define IPU_PSYS_IOMMU1R_OFFSET 0x1B0E00 | ||
| #define IPU_PSYS_IOMMUI_OFFSET 0x1B1500 | ||
|
|
||
| /* the offset from IOMMU base register */ | ||
| #define IPU_MMU_L1_STREAM_ID_REG_OFFSET 0x0c | ||
| #define IPU_MMU_L2_STREAM_ID_REG_OFFSET 0x4c | ||
| #define IPU_PSYS_MMU1W_L2_STREAM_ID_REG_OFFSET 0x8c | ||
|
|
||
| #define IPU_MMU_INFO_OFFSET 0x8 | ||
|
|
||
| #define IPU_ISYS_SPC_OFFSET 0x210000 | ||
|
|
||
| #define IPU6SE_PSYS_SPC_OFFSET 0x110000 | ||
| #define IPU6_PSYS_SPC_OFFSET 0x118000 | ||
|
|
||
| #define IPU_ISYS_DMEM_OFFSET 0x200000 | ||
| #define IPU_PSYS_DMEM_OFFSET 0x100000 | ||
|
|
||
| #define IPU_REG_ISYS_CSI_TOP_CTRL0_IRQ_EDGE 0x238200 | ||
| #define IPU_REG_ISYS_CSI_TOP_CTRL0_IRQ_MASK 0x238204 | ||
| #define IPU_REG_ISYS_CSI_TOP_CTRL0_IRQ_STATUS 0x238208 | ||
| #define IPU_REG_ISYS_CSI_TOP_CTRL0_IRQ_CLEAR 0x23820c | ||
| #define IPU_REG_ISYS_CSI_TOP_CTRL0_IRQ_ENABLE 0x238210 | ||
| #define IPU_REG_ISYS_CSI_TOP_CTRL0_IRQ_LEVEL_NOT_PULSE 0x238214 | ||
|
|
||
| #define IPU_REG_ISYS_CSI_TOP_CTRL1_IRQ_EDGE 0x238220 | ||
| #define IPU_REG_ISYS_CSI_TOP_CTRL1_IRQ_MASK 0x238224 | ||
| #define IPU_REG_ISYS_CSI_TOP_CTRL1_IRQ_STATUS 0x238228 | ||
| #define IPU_REG_ISYS_CSI_TOP_CTRL1_IRQ_CLEAR 0x23822c | ||
| #define IPU_REG_ISYS_CSI_TOP_CTRL1_IRQ_ENABLE 0x238230 | ||
| #define IPU_REG_ISYS_CSI_TOP_CTRL1_IRQ_LEVEL_NOT_PULSE 0x238234 | ||
|
|
||
| #define IPU_REG_ISYS_UNISPART_IRQ_EDGE 0x27c000 | ||
| #define IPU_REG_ISYS_UNISPART_IRQ_MASK 0x27c004 | ||
| #define IPU_REG_ISYS_UNISPART_IRQ_STATUS 0x27c008 | ||
| #define IPU_REG_ISYS_UNISPART_IRQ_CLEAR 0x27c00c | ||
| #define IPU_REG_ISYS_UNISPART_IRQ_ENABLE 0x27c010 | ||
| #define IPU_REG_ISYS_UNISPART_IRQ_LEVEL_NOT_PULSE 0x27c014 | ||
| #define IPU_REG_ISYS_UNISPART_SW_IRQ_REG 0x27c414 | ||
| #define IPU_REG_ISYS_UNISPART_SW_IRQ_MUX_REG 0x27c418 | ||
| #define IPU_ISYS_UNISPART_IRQ_CSI0 BIT(2) | ||
| #define IPU_ISYS_UNISPART_IRQ_CSI1 BIT(3) | ||
| #define IPU_ISYS_UNISPART_IRQ_SW BIT(22) | ||
|
|
||
| #define IPU_REG_ISYS_ISL_TOP_IRQ_EDGE 0x2b0200 | ||
| #define IPU_REG_ISYS_ISL_TOP_IRQ_MASK 0x2b0204 | ||
| #define IPU_REG_ISYS_ISL_TOP_IRQ_STATUS 0x2b0208 | ||
| #define IPU_REG_ISYS_ISL_TOP_IRQ_CLEAR 0x2b020c | ||
| #define IPU_REG_ISYS_ISL_TOP_IRQ_ENABLE 0x2b0210 | ||
| #define IPU_REG_ISYS_ISL_TOP_IRQ_LEVEL_NOT_PULSE 0x2b0214 | ||
|
|
||
| #define IPU_REG_ISYS_CMPR_TOP_IRQ_EDGE 0x2d2100 | ||
| #define IPU_REG_ISYS_CMPR_TOP_IRQ_MASK 0x2d2104 | ||
| #define IPU_REG_ISYS_CMPR_TOP_IRQ_STATUS 0x2d2108 | ||
| #define IPU_REG_ISYS_CMPR_TOP_IRQ_CLEAR 0x2d210c | ||
| #define IPU_REG_ISYS_CMPR_TOP_IRQ_ENABLE 0x2d2110 | ||
| #define IPU_REG_ISYS_CMPR_TOP_IRQ_LEVEL_NOT_PULSE 0x2d2114 | ||
|
|
||
| /* CDC Burst collector thresholds for isys - 3 FIFOs i = 0..2 */ | ||
| #define IPU_REG_ISYS_CDC_THRESHOLD(i) (0x27c400 + ((i) * 4)) | ||
|
|
||
| #define IPU_ISYS_CSI_PHY_NUM 2 | ||
| #define IPU_CSI_IRQ_NUM_PER_PIPE 4 | ||
| #define IPU6SE_ISYS_CSI_PORT_NUM 4 | ||
| #define IPU6_ISYS_CSI_PORT_NUM 8 | ||
|
|
||
| #define IPU_ISYS_CSI_PORT_IRQ(irq_num) (1 << (irq_num)) | ||
|
|
||
| /* PSYS Info bits*/ | ||
| #define IPU_REG_PSYS_INFO_SEG_CMEM_MASTER(a) (0x2C + ((a) * 12)) | ||
| #define IPU_REG_PSYS_INFO_SEG_XMEM_MASTER(a) (0x5C + ((a) * 12)) | ||
|
|
||
| /* PKG DIR OFFSET in IMR in secure mode */ | ||
| #define IPU_PKG_DIR_IMR_OFFSET 0x40 | ||
|
|
||
| #define IPU_ISYS_REG_SPC_STATUS_CTRL 0x0 | ||
|
|
||
| #define IPU_ISYS_SPC_STATUS_START BIT(1) | ||
| #define IPU_ISYS_SPC_STATUS_RUN BIT(3) | ||
| #define IPU_ISYS_SPC_STATUS_READY BIT(5) | ||
| #define IPU_ISYS_SPC_STATUS_CTRL_ICACHE_INVALIDATE BIT(12) | ||
| #define IPU_ISYS_SPC_STATUS_ICACHE_PREFETCH BIT(13) | ||
|
|
||
| #define IPU_PSYS_REG_SPC_STATUS_CTRL 0x0 | ||
| #define IPU_PSYS_REG_SPC_START_PC 0x4 | ||
| #define IPU_PSYS_REG_SPC_ICACHE_BASE 0x10 | ||
| #define IPU_REG_PSYS_INFO_SEG_0_CONFIG_ICACHE_MASTER 0x14 | ||
|
|
||
| #define IPU_PSYS_SPC_STATUS_START BIT(1) | ||
| #define IPU_PSYS_SPC_STATUS_RUN BIT(3) | ||
| #define IPU_PSYS_SPC_STATUS_READY BIT(5) | ||
| #define IPU_PSYS_SPC_STATUS_CTRL_ICACHE_INVALIDATE BIT(12) | ||
| #define IPU_PSYS_SPC_STATUS_ICACHE_PREFETCH BIT(13) | ||
|
|
||
| #define IPU_PSYS_REG_SPP0_STATUS_CTRL 0x20000 | ||
|
|
||
| #define IPU_INFO_ENABLE_SNOOP BIT(0) | ||
| #define IPU_INFO_DEC_FORCE_FLUSH BIT(1) | ||
| #define IPU_INFO_DEC_PASS_THRU BIT(2) | ||
| #define IPU_INFO_ZLW BIT(3) | ||
| #define IPU_INFO_STREAM_ID_SET(id) (((id) & 0x1F) << 4) | ||
| #define IPU_INFO_REQUEST_DESTINATION_IOSF BIT(9) | ||
| #define IPU_INFO_IMR_BASE BIT(10) | ||
| #define IPU_INFO_IMR_DESTINED BIT(11) | ||
|
|
||
| #define IPU_INFO_REQUEST_DESTINATION_PRIMARY IPU_INFO_REQUEST_DESTINATION_IOSF | ||
|
|
||
| /* Trace unit related register definitions */ | ||
| #define TRACE_REG_MAX_ISYS_OFFSET 0xfffff | ||
| #define TRACE_REG_MAX_PSYS_OFFSET 0xfffff | ||
| #define IPU_ISYS_OFFSET IPU_ISYS_DMEM_OFFSET | ||
| #define IPU_PSYS_OFFSET IPU_PSYS_DMEM_OFFSET | ||
| /* ISYS trace unit registers */ | ||
| /* Trace unit base offset */ | ||
| #define IPU_TRACE_REG_IS_TRACE_UNIT_BASE 0x27d000 | ||
| /* Trace monitors */ | ||
| #define IPU_TRACE_REG_IS_SP_EVQ_BASE 0x211000 | ||
| /* GPC blocks */ | ||
| #define IPU_TRACE_REG_IS_SP_GPC_BASE 0x210800 | ||
| #define IPU_TRACE_REG_IS_ISL_GPC_BASE 0x2b0a00 | ||
| #define IPU_TRACE_REG_IS_MMU_GPC_BASE 0x2e0f00 | ||
| /* each CSI2 port has a dedicated trace monitor, index 0..7 */ | ||
| #define IPU_TRACE_REG_CSI2_TM_BASE(port) (0x220400 + 0x1000 * (port)) | ||
|
|
||
| /* Trace timers */ | ||
| #define IPU_TRACE_REG_IS_GPREG_TRACE_TIMER_RST_N 0x27c410 | ||
| #define TRACE_REG_GPREG_TRACE_TIMER_RST_OFF BIT(0) | ||
|
|
||
| /* SIG2CIO */ | ||
| #define IPU_TRACE_REG_CSI2_PORT_SIG2SIO_GR_BASE(port) \ | ||
| (0x220e00 + (port) * 0x1000) | ||
|
|
||
| /* PSYS trace unit registers */ | ||
| /* Trace unit base offset */ | ||
| #define IPU_TRACE_REG_PS_TRACE_UNIT_BASE 0x1b4000 | ||
| /* Trace monitors */ | ||
| #define IPU_TRACE_REG_PS_SPC_EVQ_BASE 0x119000 | ||
| #define IPU_TRACE_REG_PS_SPP0_EVQ_BASE 0x139000 | ||
|
|
||
| /* GPC blocks */ | ||
| #define IPU_TRACE_REG_PS_SPC_GPC_BASE 0x118800 | ||
| #define IPU_TRACE_REG_PS_SPP0_GPC_BASE 0x138800 | ||
| #define IPU_TRACE_REG_PS_MMU_GPC_BASE 0x1b1b00 | ||
|
|
||
| /* Trace timers */ | ||
| #define IPU_TRACE_REG_PS_GPREG_TRACE_TIMER_RST_N 0x1aa714 | ||
|
|
||
| /* | ||
| * s2m_pixel_soc_pixel_remapping is dedicated for the enableing of the | ||
| * pixel s2m remp ability.Remap here means that s2m rearange the order | ||
| * of the pixels in each 4 pixels group. | ||
| * For examle, mirroring remping means that if input's 4 first pixels | ||
| * are 1 2 3 4 then in output we should see 4 3 2 1 in this 4 first pixels. | ||
| * 0xE4 is from s2m MAS document. It means no remaping. | ||
| */ | ||
| #define S2M_PIXEL_SOC_PIXEL_REMAPPING_FLAG_NO_REMAPPING 0xE4 | ||
| /* | ||
| * csi_be_soc_pixel_remapping is for the enabling of the csi\mipi be pixel | ||
| * remapping feature. This remapping is exactly like the stream2mmio remapping. | ||
| */ | ||
| #define CSI_BE_SOC_PIXEL_REMAPPING_FLAG_NO_REMAPPING 0xE4 | ||
|
|
||
| #define IPU_REG_DMA_TOP_AB_GROUP1_BASE_ADDR 0x1AE000 | ||
| #define IPU_REG_DMA_TOP_AB_GROUP2_BASE_ADDR 0x1AF000 | ||
| #define IPU_REG_DMA_TOP_AB_RING_MIN_OFFSET(n) (0x4 + (n) * 0xC) | ||
| #define IPU_REG_DMA_TOP_AB_RING_MAX_OFFSET(n) (0x8 + (n) * 0xC) | ||
| #define IPU_REG_DMA_TOP_AB_RING_ACCESS_OFFSET(n) (0xC + (n) * 0xC) | ||
|
|
||
| enum ipu_device_ab_group1_target_id { | ||
| IPU_DEVICE_AB_GROUP1_TARGET_ID_R0_SPC_DMEM, | ||
| IPU_DEVICE_AB_GROUP1_TARGET_ID_R1_SPC_DMEM, | ||
| IPU_DEVICE_AB_GROUP1_TARGET_ID_R2_SPC_DMEM, | ||
| IPU_DEVICE_AB_GROUP1_TARGET_ID_R3_SPC_STATUS_REG, | ||
| IPU_DEVICE_AB_GROUP1_TARGET_ID_R4_SPC_MASTER_BASE_ADDR, | ||
| IPU_DEVICE_AB_GROUP1_TARGET_ID_R5_SPC_PC_STALL, | ||
| IPU_DEVICE_AB_GROUP1_TARGET_ID_R6_SPC_EQ, | ||
| IPU_DEVICE_AB_GROUP1_TARGET_ID_R7_SPC_RESERVED, | ||
| IPU_DEVICE_AB_GROUP1_TARGET_ID_R8_SPC_RESERVED, | ||
| IPU_DEVICE_AB_GROUP1_TARGET_ID_R9_SPP0, | ||
| IPU_DEVICE_AB_GROUP1_TARGET_ID_R10_SPP1, | ||
| IPU_DEVICE_AB_GROUP1_TARGET_ID_R11_CENTRAL_R1, | ||
| IPU_DEVICE_AB_GROUP1_TARGET_ID_R12_IRQ, | ||
| IPU_DEVICE_AB_GROUP1_TARGET_ID_R13_CENTRAL_R2, | ||
| IPU_DEVICE_AB_GROUP1_TARGET_ID_R14_DMA, | ||
| IPU_DEVICE_AB_GROUP1_TARGET_ID_R15_DMA, | ||
| IPU_DEVICE_AB_GROUP1_TARGET_ID_R16_GP, | ||
| IPU_DEVICE_AB_GROUP1_TARGET_ID_R17_ZLW_INSERTER, | ||
| IPU_DEVICE_AB_GROUP1_TARGET_ID_R18_AB, | ||
| }; | ||
|
|
||
| enum nci_ab_access_mode { | ||
| NCI_AB_ACCESS_MODE_RW, /* read & write */ | ||
| NCI_AB_ACCESS_MODE_RO, /* read only */ | ||
| NCI_AB_ACCESS_MODE_WO, /* write only */ | ||
| NCI_AB_ACCESS_MODE_NA /* No access at all */ | ||
| }; | ||
|
|
||
| /* | ||
| * 3:0 CSI_PORT.irq_out[3:0] CSI_PORT_CTRL0 IRQ outputs (4bits) | ||
| * [0] CSI_PORT.IRQ_CTRL0_csi | ||
| * [1] CSI_PORT.IRQ_CTRL1_csi_sync | ||
| * [2] CSI_PORT.IRQ_CTRL2_s2m_sids0to7 | ||
| * [3] CSI_PORT.IRQ_CTRL3_s2m_sids8to15 | ||
| */ | ||
| #define IPU_ISYS_UNISPART_IRQ_CSI2(port) \ | ||
| (0x3 << ((port) * IPU_CSI_IRQ_NUM_PER_PIPE)) | ||
|
|
||
| /* IRQ-related registers in PSYS */ | ||
| #define IPU_REG_PSYS_GPDEV_IRQ_EDGE 0x1aa200 | ||
| #define IPU_REG_PSYS_GPDEV_IRQ_MASK 0x1aa204 | ||
| #define IPU_REG_PSYS_GPDEV_IRQ_STATUS 0x1aa208 | ||
| #define IPU_REG_PSYS_GPDEV_IRQ_CLEAR 0x1aa20c | ||
| #define IPU_REG_PSYS_GPDEV_IRQ_ENABLE 0x1aa210 | ||
| #define IPU_REG_PSYS_GPDEV_IRQ_LEVEL_NOT_PULSE 0x1aa214 | ||
| /* There are 8 FW interrupts, n = 0..7 */ | ||
| #define IPU_PSYS_GPDEV_FWIRQ0 5 | ||
| #define IPU_PSYS_GPDEV_FWIRQ1 6 | ||
| #define IPU_PSYS_GPDEV_FWIRQ2 7 | ||
| #define IPU_PSYS_GPDEV_FWIRQ3 8 | ||
| #define IPU_PSYS_GPDEV_FWIRQ4 9 | ||
| #define IPU_PSYS_GPDEV_FWIRQ5 10 | ||
| #define IPU_PSYS_GPDEV_FWIRQ6 11 | ||
| #define IPU_PSYS_GPDEV_FWIRQ7 12 | ||
| #define IPU_PSYS_GPDEV_IRQ_FWIRQ(n) (1 << (n)) | ||
| #define IPU_REG_PSYS_GPDEV_FWIRQ(n) (4 * (n) + 0x1aa100) | ||
|
|
||
| /* | ||
| * ISYS GPC (Gerneral Performance Counters) Registers | ||
| */ | ||
| #define IPU_ISYS_GPC_BASE 0x2E0000 | ||
| #define IPU_ISYS_GPREG_TRACE_TIMER_RST 0x27C410 | ||
| enum ipu_isf_cdc_mmu_gpc_registers { | ||
| IPU_ISF_CDC_MMU_GPC_SOFT_RESET = 0x0F00, | ||
| IPU_ISF_CDC_MMU_GPC_OVERALL_ENABLE = 0x0F04, | ||
| IPU_ISF_CDC_MMU_GPC_ENABLE0 = 0x0F20, | ||
| IPU_ISF_CDC_MMU_GPC_VALUE0 = 0x0F60, | ||
| IPU_ISF_CDC_MMU_GPC_CNT_SEL0 = 0x0FA0, | ||
| }; | ||
|
|
||
| /* | ||
| * GPC (Gerneral Performance Counters) Registers | ||
| */ | ||
| #define IPU_GPC_BASE 0x1B0000 | ||
| #define IPU_GPREG_TRACE_TIMER_RST 0x1AA714 | ||
| enum ipu_cdc_mmu_gpc_registers { | ||
| IPU_CDC_MMU_GPC_SOFT_RESET = 0x1B00, | ||
| IPU_CDC_MMU_GPC_OVERALL_ENABLE = 0x1B04, | ||
| IPU_CDC_MMU_GPC_TRACE_HEADER = 0x1B08, | ||
| IPU_CDC_MMU_GPC_TRACE_ADDR = 0x1B0C, | ||
| IPU_CDC_MMU_GPC_TRACE_ENABLE_NPK = 0x1B10, | ||
| IPU_CDC_MMU_GPC_TRACE_ENABLE_DDR = 0x1B14, | ||
| IPU_CDC_MMU_GPC_LP_CLEAR = 0x1B18, | ||
| IPU_CDC_MMU_GPC_LOST_PACKET = 0x1B1C, | ||
| IPU_CDC_MMU_GPC_ENABLE0 = 0x1B20, | ||
| IPU_CDC_MMU_GPC_VALUE0 = 0x1B60, | ||
| IPU_CDC_MMU_GPC_CNT_SEL0 = 0x1BA0, | ||
| IPU_CDC_MMU_GPC_START_SEL0 = 0x1BE0, | ||
| IPU_CDC_MMU_GPC_STOP_SEL0 = 0x1C20, | ||
| IPU_CDC_MMU_GPC_MSG_SEL0 = 0x1C60, | ||
| IPU_CDC_MMU_GPC_PLOAD_SEL0 = 0x1CA0, | ||
| IPU_CDC_MMU_GPC_IRQ_TRIGGER_VALUE0 = 0x1CE0, | ||
| IPU_CDC_MMU_GPC_IRQ_TIMER_SEL0 = 0x1D20, | ||
| IPU_CDC_MMU_GPC_IRQ_ENABLE0 = 0x1D60, | ||
| IPU_CDC_MMU_GPC_END = 0x1D9C | ||
| }; | ||
|
|
||
| #define IPU_GPC_SENSE_OFFSET 7 | ||
| #define IPU_GPC_ROUTE_OFFSET 5 | ||
| #define IPU_GPC_SOURCE_OFFSET 0 | ||
|
|
||
| /* | ||
| * Signals monitored by GPC | ||
| */ | ||
| #define IPU_GPC_TRACE_TLB_MISS_MMU_LB_IDX 0 | ||
| #define IPU_GPC_TRACE_FULL_WRITE_LB_IDX 1 | ||
| #define IPU_GPC_TRACE_NOFULL_WRITE_LB_IDX 2 | ||
| #define IPU_GPC_TRACE_FULL_READ_LB_IDX 3 | ||
| #define IPU_GPC_TRACE_NOFULL_READ_LB_IDX 4 | ||
| #define IPU_GPC_TRACE_STALL_LB_IDX 5 | ||
| #define IPU_GPC_TRACE_ZLW_LB_IDX 6 | ||
| #define IPU_GPC_TRACE_TLB_MISS_MMU_HBTX_IDX 7 | ||
| #define IPU_GPC_TRACE_FULL_WRITE_HBTX_IDX 8 | ||
| #define IPU_GPC_TRACE_NOFULL_WRITE_HBTX_IDX 9 | ||
| #define IPU_GPC_TRACE_FULL_READ_HBTX_IDX 10 | ||
| #define IPU_GPC_TRACE_STALL_HBTX_IDX 11 | ||
| #define IPU_GPC_TRACE_ZLW_HBTX_IDX 12 | ||
| #define IPU_GPC_TRACE_TLB_MISS_MMU_HBFRX_IDX 13 | ||
| #define IPU_GPC_TRACE_FULL_READ_HBFRX_IDX 14 | ||
| #define IPU_GPC_TRACE_NOFULL_READ_HBFRX_IDX 15 | ||
| #define IPU_GPC_TRACE_STALL_HBFRX_IDX 16 | ||
| #define IPU_GPC_TRACE_ZLW_HBFRX_IDX 17 | ||
| #define IPU_GPC_TRACE_TLB_MISS_ICACHE_IDX 18 | ||
| #define IPU_GPC_TRACE_FULL_READ_ICACHE_IDX 19 | ||
| #define IPU_GPC_TRACE_STALL_ICACHE_IDX 20 | ||
| /* | ||
| * psys subdomains power request regs | ||
| */ | ||
| enum ipu_device_buttress_psys_domain_pos { | ||
| IPU_PSYS_SUBDOMAIN_ISA = 0, | ||
| IPU_PSYS_SUBDOMAIN_PSA = 1, | ||
| IPU_PSYS_SUBDOMAIN_BB = 2, | ||
| IPU_PSYS_SUBDOMAIN_IDSP1 = 3, /* only in IPU6M */ | ||
| IPU_PSYS_SUBDOMAIN_IDSP2 = 4, /* only in IPU6M */ | ||
| }; | ||
|
|
||
| #define IPU_PSYS_SUBDOMAINS_POWER_MASK (BIT(IPU_PSYS_SUBDOMAIN_ISA) | \ | ||
| BIT(IPU_PSYS_SUBDOMAIN_PSA) | \ | ||
| BIT(IPU_PSYS_SUBDOMAIN_BB)) | ||
|
|
||
| #define IPU_PSYS_SUBDOMAINS_POWER_REQ 0xa0 | ||
| #define IPU_PSYS_SUBDOMAINS_POWER_STATUS 0xa4 | ||
|
|
||
| #endif /* IPU_PLATFORM_REGS_H */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| /* SPDX-License-Identifier: GPL-2.0 */ | ||
| /* Copyright (C) 2018 - 2020 Intel Corporation */ | ||
|
|
||
| #ifndef IPU_PLATFORM_RESOURCES_COMMON_H | ||
| #define IPU_PLATFORM_RESOURCES_COMMON_H | ||
|
|
||
| #define IPU_FW_PSYS_N_PADDING_UINT8_IN_PROGRAM_MANIFEST 0 | ||
|
|
||
| #define IPU_FW_PSYS_N_PADDING_UINT8_IN_PROCESS_STRUCT 0 | ||
| #define IPU_FW_PSYS_N_PADDING_UINT8_IN_PROCESS_GROUP_STRUCT 2 | ||
| #define IPU_FW_PSYS_N_PADDING_UINT8_IN_PROGRAM_MANIFEST_EXT 2 | ||
|
|
||
| #define IPU_FW_PSYS_N_PADDING_UINT8_IN_TERMINAL_STRUCT 5 | ||
|
|
||
| #define IPU_FW_PSYS_N_PADDING_UINT8_IN_PARAM_TERMINAL_STRUCT 6 | ||
|
|
||
| #define IPU_FW_PSYS_N_PADDING_UINT8_IN_DATA_TERMINAL_STRUCT 3 | ||
|
|
||
| #define IPU_FW_PSYS_N_PADDING_UINT8_IN_FRAME_DESC_STRUCT 3 | ||
| #define IPU_FW_PSYS_N_FRAME_PLANES 6 | ||
| #define IPU_FW_PSYS_N_PADDING_UINT8_IN_FRAME_STRUCT 4 | ||
|
|
||
| #define IPU_FW_PSYS_N_PADDING_UINT8_IN_BUFFER_SET_STRUCT 1 | ||
|
|
||
| #define IPU_FW_PSYS_MAX_INPUT_DEC_RESOURCES 4 | ||
| #define IPU_FW_PSYS_MAX_OUTPUT_DEC_RESOURCES 4 | ||
|
|
||
| #define IPU_FW_PSYS_PROCESS_MAX_CELLS 1 | ||
| #define IPU_FW_PSYS_KERNEL_BITMAP_NOF_ELEMS 4 | ||
| #define IPU_FW_PSYS_RBM_NOF_ELEMS 5 | ||
| #define IPU_FW_PSYS_KBM_NOF_ELEMS 4 | ||
|
|
||
| struct ipu_fw_psys_process { | ||
| s16 parent_offset; | ||
| u8 size; | ||
| u8 cell_dependencies_offset; | ||
| u8 terminal_dependencies_offset; | ||
| u8 process_extension_offset; | ||
| u8 ID; | ||
| u8 program_idx; | ||
| u8 state; | ||
| u8 cells[IPU_FW_PSYS_PROCESS_MAX_CELLS]; | ||
| u8 cell_dependency_count; | ||
| u8 terminal_dependency_count; | ||
| }; | ||
|
|
||
| struct ipu_fw_psys_program_manifest { | ||
| u32 kernel_bitmap[IPU_FW_PSYS_KERNEL_BITMAP_NOF_ELEMS]; | ||
| s16 parent_offset; | ||
| u8 program_dependency_offset; | ||
| u8 terminal_dependency_offset; | ||
| u8 size; | ||
| u8 program_extension_offset; | ||
| u8 program_type; | ||
| u8 ID; | ||
| u8 cells[IPU_FW_PSYS_PROCESS_MAX_CELLS]; | ||
| u8 cell_type_id; | ||
| u8 program_dependency_count; | ||
| u8 terminal_dependency_count; | ||
| }; | ||
|
|
||
| /* platform specific resource interface */ | ||
| struct ipu_psys_resource_pool; | ||
| struct ipu_psys_resource_alloc; | ||
| struct ipu_fw_psys_process_group; | ||
| int ipu_psys_allocate_resources(const struct device *dev, | ||
| struct ipu_fw_psys_process_group *pg, | ||
| void *pg_manifest, | ||
| struct ipu_psys_resource_alloc *alloc, | ||
| struct ipu_psys_resource_pool *pool); | ||
| int ipu_psys_move_resources(const struct device *dev, | ||
| struct ipu_psys_resource_alloc *alloc, | ||
| struct ipu_psys_resource_pool *source_pool, | ||
| struct ipu_psys_resource_pool *target_pool); | ||
|
|
||
| void ipu_psys_resource_copy(struct ipu_psys_resource_pool *src, | ||
| struct ipu_psys_resource_pool *dest); | ||
|
|
||
| int ipu_psys_try_allocate_resources(struct device *dev, | ||
| struct ipu_fw_psys_process_group *pg, | ||
| void *pg_manifest, | ||
| struct ipu_psys_resource_pool *pool); | ||
|
|
||
| void ipu_psys_free_resources(struct ipu_psys_resource_alloc *alloc, | ||
| struct ipu_psys_resource_pool *pool); | ||
|
|
||
| int ipu_fw_psys_set_proc_dfm_bitmap(struct ipu_fw_psys_process *ptr, | ||
| u16 id, u32 bitmap, | ||
| u32 active_bitmap); | ||
|
|
||
| int ipu_psys_allocate_cmd_queue_resource(struct ipu_psys_resource_pool *pool); | ||
| void ipu_psys_free_cmd_queue_resource(struct ipu_psys_resource_pool *pool, | ||
| u8 queue_id); | ||
|
|
||
| extern const struct ipu_fw_resource_definitions *ipu6_res_defs; | ||
| extern const struct ipu_fw_resource_definitions *ipu6se_res_defs; | ||
| extern struct ipu6_psys_hw_res_variant hw_var; | ||
| #endif /* IPU_PLATFORM_RESOURCES_COMMON_H */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| /* SPDX-License-Identifier: GPL-2.0 */ | ||
| /* Copyright (C) 2013 - 2020 Intel Corporation */ | ||
|
|
||
| #ifndef IPU_PLATFORM_H | ||
| #define IPU_PLATFORM_H | ||
|
|
||
| #define IPU_NAME "intel-ipu6" | ||
|
|
||
| #define IPU6SE_FIRMWARE_NAME "intel/ipu6se_fw.bin" | ||
| #define IPU6_FIRMWARE_NAME "intel/ipu6_fw.bin" | ||
|
|
||
| /* | ||
| * The following definitions are encoded to the media_device's model field so | ||
| * that the software components which uses IPU driver can get the hw stepping | ||
| * information. | ||
| */ | ||
| #define IPU_MEDIA_DEV_MODEL_NAME "ipu6" | ||
|
|
||
| #define IPU6SE_ISYS_NUM_STREAMS 8 /* Max 8 */ | ||
| #define IPU6_ISYS_NUM_STREAMS 16 /* Max 16 */ | ||
|
|
||
| /* declearations, definitions in ipu6.c */ | ||
| extern struct ipu_isys_internal_pdata isys_ipdata; | ||
| extern struct ipu_psys_internal_pdata psys_ipdata; | ||
| extern const struct ipu_buttress_ctrl isys_buttress_ctrl; | ||
| extern const struct ipu_buttress_ctrl psys_buttress_ctrl; | ||
|
|
||
| /* definitions in ipu6-isys.c */ | ||
| extern struct ipu_trace_block isys_trace_blocks[]; | ||
| /* definitions in ipu6-psys.c */ | ||
| extern struct ipu_trace_block psys_trace_blocks[]; | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| /* SPDX-License-Identifier: GPL-2.0 */ | ||
| /* Copyright (C) 2020 Intel Corporation */ | ||
|
|
||
| #ifndef IPU6_ISYS_CSI2_H | ||
| #define IPU6_ISYS_CSI2_H | ||
|
|
||
| struct ipu_isys_csi2_timing; | ||
| struct ipu_isys_csi2; | ||
| struct ipu_isys_pipeline; | ||
| struct v4l2_subdev; | ||
|
|
||
| #define IPU_ISYS_SHORT_PACKET_DTYPE_MASK 0x3f | ||
|
|
||
| #endif /* IPU6_ISYS_CSI2_H */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,211 @@ | ||
| // SPDX-License-Identifier: GPL-2.0 | ||
| // Copyright (C) 2020 Intel Corporation | ||
|
|
||
| #ifdef CONFIG_DEBUG_FS | ||
| #include <linux/debugfs.h> | ||
| #include <linux/pm_runtime.h> | ||
|
|
||
| #include "ipu-isys.h" | ||
| #include "ipu-platform-regs.h" | ||
|
|
||
| #define IPU_ISYS_GPC_NUM 16 | ||
|
|
||
| #ifndef CONFIG_PM | ||
| #define pm_runtime_get_sync(d) 0 | ||
| #define pm_runtime_put(d) 0 | ||
| #endif | ||
|
|
||
| struct ipu_isys_gpc { | ||
| bool enable; | ||
| unsigned int route; | ||
| unsigned int source; | ||
| unsigned int sense; | ||
| unsigned int gpcindex; | ||
| void *prit; | ||
| }; | ||
|
|
||
| struct ipu_isys_gpcs { | ||
| bool gpc_enable; | ||
| struct ipu_isys_gpc gpc[IPU_ISYS_GPC_NUM]; | ||
| void *prit; | ||
| }; | ||
|
|
||
| static int ipu6_isys_gpc_global_enable_get(void *data, u64 *val) | ||
| { | ||
| struct ipu_isys_gpcs *isys_gpcs = data; | ||
| struct ipu_isys *isys = isys_gpcs->prit; | ||
|
|
||
| mutex_lock(&isys->mutex); | ||
|
|
||
| *val = isys_gpcs->gpc_enable; | ||
|
|
||
| mutex_unlock(&isys->mutex); | ||
| return 0; | ||
| } | ||
|
|
||
| static int ipu6_isys_gpc_global_enable_set(void *data, u64 val) | ||
| { | ||
| struct ipu_isys_gpcs *isys_gpcs = data; | ||
| struct ipu_isys *isys = isys_gpcs->prit; | ||
| void __iomem *base; | ||
| int i, ret; | ||
|
|
||
| if (val != 0 && val != 1) | ||
| return -EINVAL; | ||
|
|
||
| if (!isys || !isys->pdata || !isys->pdata->base) | ||
| return -EINVAL; | ||
|
|
||
| mutex_lock(&isys->mutex); | ||
|
|
||
| base = isys->pdata->base + IPU_ISYS_GPC_BASE; | ||
|
|
||
| ret = pm_runtime_get_sync(&isys->adev->dev); | ||
| if (ret < 0) { | ||
| pm_runtime_put(&isys->adev->dev); | ||
| mutex_unlock(&isys->mutex); | ||
| return ret; | ||
| } | ||
|
|
||
| if (!val) { | ||
| writel(0x0, base + IPU_ISYS_GPREG_TRACE_TIMER_RST); | ||
| writel(0x0, base + IPU_ISF_CDC_MMU_GPC_OVERALL_ENABLE); | ||
| writel(0xffff, base + IPU_ISF_CDC_MMU_GPC_SOFT_RESET); | ||
| isys_gpcs->gpc_enable = false; | ||
| for (i = 0; i < IPU_ISYS_GPC_NUM; i++) { | ||
| isys_gpcs->gpc[i].enable = 0; | ||
| isys_gpcs->gpc[i].sense = 0; | ||
| isys_gpcs->gpc[i].route = 0; | ||
| isys_gpcs->gpc[i].source = 0; | ||
| } | ||
| pm_runtime_mark_last_busy(&isys->adev->dev); | ||
| pm_runtime_put_autosuspend(&isys->adev->dev); | ||
| } else { | ||
| /* | ||
| * Set gpc reg and start all gpc here. | ||
| * RST free running local timer. | ||
| */ | ||
| writel(0x0, base + IPU_ISYS_GPREG_TRACE_TIMER_RST); | ||
| writel(0x1, base + IPU_ISYS_GPREG_TRACE_TIMER_RST); | ||
|
|
||
| for (i = 0; i < IPU_ISYS_GPC_NUM; i++) { | ||
| /* Enable */ | ||
| writel(isys_gpcs->gpc[i].enable, | ||
| base + IPU_ISF_CDC_MMU_GPC_ENABLE0 + 4 * i); | ||
| /* Setting (route/source/sense) */ | ||
| writel((isys_gpcs->gpc[i].sense | ||
| << IPU_GPC_SENSE_OFFSET) | ||
| + (isys_gpcs->gpc[i].route | ||
| << IPU_GPC_ROUTE_OFFSET) | ||
| + (isys_gpcs->gpc[i].source | ||
| << IPU_GPC_SOURCE_OFFSET), | ||
| base + IPU_ISF_CDC_MMU_GPC_CNT_SEL0 + 4 * i); | ||
| } | ||
|
|
||
| /* Soft reset and Overall Enable. */ | ||
| writel(0x0, base + IPU_ISF_CDC_MMU_GPC_OVERALL_ENABLE); | ||
| writel(0xffff, base + IPU_ISF_CDC_MMU_GPC_SOFT_RESET); | ||
| writel(0x1, base + IPU_ISF_CDC_MMU_GPC_OVERALL_ENABLE); | ||
|
|
||
| isys_gpcs->gpc_enable = true; | ||
| } | ||
|
|
||
| mutex_unlock(&isys->mutex); | ||
| return 0; | ||
| } | ||
|
|
||
| DEFINE_SIMPLE_ATTRIBUTE(isys_gpc_globe_enable_fops, | ||
| ipu6_isys_gpc_global_enable_get, | ||
| ipu6_isys_gpc_global_enable_set, "%llu\n"); | ||
|
|
||
| static int ipu6_isys_gpc_count_get(void *data, u64 *val) | ||
| { | ||
| struct ipu_isys_gpc *isys_gpc = data; | ||
| struct ipu_isys *isys = isys_gpc->prit; | ||
| void __iomem *base; | ||
|
|
||
| if (!isys || !isys->pdata || !isys->pdata->base) | ||
| return -EINVAL; | ||
|
|
||
| spin_lock(&isys->power_lock); | ||
| if (isys->power) { | ||
| base = isys->pdata->base + IPU_ISYS_GPC_BASE; | ||
| *val = readl(base + IPU_ISF_CDC_MMU_GPC_VALUE0 | ||
| + 4 * isys_gpc->gpcindex); | ||
| } else { | ||
| *val = 0; | ||
| } | ||
| spin_unlock(&isys->power_lock); | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| DEFINE_SIMPLE_ATTRIBUTE(isys_gpc_count_fops, ipu6_isys_gpc_count_get, | ||
| NULL, "%llu\n"); | ||
|
|
||
| int ipu_isys_gpc_init_debugfs(struct ipu_isys *isys) | ||
| { | ||
| struct dentry *gpcdir; | ||
| struct dentry *dir; | ||
| struct dentry *file; | ||
| int i; | ||
| char gpcname[10]; | ||
| struct ipu_isys_gpcs *isys_gpcs; | ||
|
|
||
| isys_gpcs = devm_kzalloc(&isys->adev->dev, sizeof(*isys_gpcs), | ||
| GFP_KERNEL); | ||
| if (!isys_gpcs) | ||
| return -ENOMEM; | ||
|
|
||
| gpcdir = debugfs_create_dir("gpcs", isys->debugfsdir); | ||
| if (IS_ERR(gpcdir)) | ||
| return -ENOMEM; | ||
|
|
||
| isys_gpcs->prit = isys; | ||
| file = debugfs_create_file("enable", 0600, gpcdir, isys_gpcs, | ||
| &isys_gpc_globe_enable_fops); | ||
| if (IS_ERR(file)) | ||
| goto err; | ||
|
|
||
| for (i = 0; i < IPU_ISYS_GPC_NUM; i++) { | ||
| sprintf(gpcname, "gpc%d", i); | ||
| dir = debugfs_create_dir(gpcname, gpcdir); | ||
| if (IS_ERR(dir)) | ||
| goto err; | ||
|
|
||
| file = debugfs_create_bool("enable", 0600, dir, | ||
| &isys_gpcs->gpc[i].enable); | ||
| if (IS_ERR(file)) | ||
| goto err; | ||
|
|
||
| file = debugfs_create_u32("source", 0600, dir, | ||
| &isys_gpcs->gpc[i].source); | ||
| if (IS_ERR(file)) | ||
| goto err; | ||
|
|
||
| file = debugfs_create_u32("route", 0600, dir, | ||
| &isys_gpcs->gpc[i].route); | ||
| if (IS_ERR(file)) | ||
| goto err; | ||
|
|
||
| file = debugfs_create_u32("sense", 0600, dir, | ||
| &isys_gpcs->gpc[i].sense); | ||
| if (IS_ERR(file)) | ||
| goto err; | ||
|
|
||
| isys_gpcs->gpc[i].gpcindex = i; | ||
| isys_gpcs->gpc[i].prit = isys; | ||
| file = debugfs_create_file("count", 0400, dir, | ||
| &isys_gpcs->gpc[i], | ||
| &isys_gpc_count_fops); | ||
| if (IS_ERR(file)) | ||
| goto err; | ||
| } | ||
|
|
||
| return 0; | ||
|
|
||
| err: | ||
| debugfs_remove_recursive(gpcdir); | ||
| return -ENOMEM; | ||
| } | ||
| #endif |