]>
Commit | Line | Data |
---|---|---|
f42c302d WY |
1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* Copyright (C) 2013 - 2020 Intel Corporation */ | |
3 | ||
4 | #ifndef IPU_PSYS_H | |
5 | #define IPU_PSYS_H | |
6 | ||
7 | #include <linux/cdev.h> | |
8 | #include <linux/workqueue.h> | |
9 | ||
10 | #include "ipu.h" | |
11 | #include "ipu-pdata.h" | |
12 | #include "ipu-fw-psys.h" | |
13 | #include "ipu-platform-psys.h" | |
14 | ||
15 | #define IPU_PSYS_PG_POOL_SIZE 16 | |
22dedf60 | 16 | #define IPU_PSYS_PG_MAX_SIZE 8192 |
f42c302d WY |
17 | #define IPU_MAX_PSYS_CMD_BUFFERS 32 |
18 | #define IPU_PSYS_EVENT_CMD_COMPLETE IPU_FW_PSYS_EVENT_TYPE_SUCCESS | |
19 | #define IPU_PSYS_EVENT_FRAGMENT_COMPLETE IPU_FW_PSYS_EVENT_TYPE_SUCCESS | |
20 | #define IPU_PSYS_CLOSE_TIMEOUT_US 50 | |
21 | #define IPU_PSYS_CLOSE_TIMEOUT (100000 / IPU_PSYS_CLOSE_TIMEOUT_US) | |
22 | #define IPU_PSYS_WORK_QUEUE system_power_efficient_wq | |
23 | #define IPU_MAX_RESOURCES 128 | |
24 | ||
25 | /* Opaque structure. Do not access fields. */ | |
26 | struct ipu_resource { | |
27 | u32 id; | |
28 | int elements; /* Number of elements available to allocation */ | |
29 | unsigned long *bitmap; /* Allocation bitmap, a bit for each element */ | |
30 | }; | |
31 | ||
32 | enum ipu_resource_type { | |
33 | IPU_RESOURCE_DEV_CHN = 0, | |
34 | IPU_RESOURCE_EXT_MEM, | |
35 | IPU_RESOURCE_DFM | |
36 | }; | |
37 | ||
38 | /* Allocation of resource(s) */ | |
39 | /* Opaque structure. Do not access fields. */ | |
40 | struct ipu_resource_alloc { | |
41 | enum ipu_resource_type type; | |
42 | struct ipu_resource *resource; | |
43 | int elements; | |
44 | int pos; | |
45 | }; | |
46 | ||
47 | /* | |
48 | * This struct represents all of the currently allocated | |
49 | * resources from IPU model. It is used also for allocating | |
50 | * resources for the next set of PGs to be run on IPU | |
51 | * (ie. those PGs which are not yet being run and which don't | |
52 | * yet reserve real IPU resources). | |
53 | * Use larger array to cover existing resource quantity | |
54 | */ | |
55 | ||
56 | /* resource size may need expand for new resource model */ | |
57 | struct ipu_psys_resource_pool { | |
58 | u32 cells; /* Bitmask of cells allocated */ | |
59 | struct ipu_resource dev_channels[16]; | |
60 | struct ipu_resource ext_memory[32]; | |
61 | struct ipu_resource dfms[16]; | |
62 | DECLARE_BITMAP(cmd_queues, 32); | |
63 | }; | |
64 | ||
65 | /* | |
66 | * This struct keeps book of the resources allocated for a specific PG. | |
67 | * It is used for freeing up resources from struct ipu_psys_resources | |
144e3aca | 68 | * when the PG is released from IPU (or model of IPU). |
f42c302d WY |
69 | */ |
70 | struct ipu_psys_resource_alloc { | |
71 | u32 cells; /* Bitmask of cells needed */ | |
72 | struct ipu_resource_alloc | |
73 | resource_alloc[IPU_MAX_RESOURCES]; | |
74 | int resources; | |
75 | }; | |
76 | ||
77 | struct task_struct; | |
78 | struct ipu_psys { | |
79 | struct ipu_psys_capability caps; | |
80 | struct cdev cdev; | |
81 | struct device dev; | |
82 | ||
83 | struct mutex mutex; /* Psys various */ | |
144e3aca | 84 | int ready; /* psys fw status */ |
f42c302d WY |
85 | bool icache_prefetch_sp; |
86 | bool icache_prefetch_isp; | |
144e3aca | 87 | spinlock_t ready_lock; /* protect psys firmware state */ |
f42c302d WY |
88 | spinlock_t pgs_lock; /* Protect pgs list access */ |
89 | struct list_head fhs; | |
90 | struct list_head pgs; | |
91 | struct list_head started_kcmds_list; | |
92 | struct ipu_psys_pdata *pdata; | |
93 | struct ipu_bus_device *adev; | |
94 | struct ia_css_syscom_context *dev_ctx; | |
95 | struct ia_css_syscom_config *syscom_config; | |
96 | struct ia_css_psys_server_init *server_init; | |
97 | struct task_struct *sched_cmd_thread; | |
ddeb731c | 98 | struct work_struct watchdog_work; |
f42c302d WY |
99 | wait_queue_head_t sched_cmd_wq; |
100 | atomic_t wakeup_count; /* Psys schedule thread wakeup count */ | |
101 | #ifdef CONFIG_DEBUG_FS | |
102 | struct dentry *debugfsdir; | |
103 | #endif | |
104 | ||
105 | /* Resources needed to be managed for process groups */ | |
106 | struct ipu_psys_resource_pool resource_pool_running; | |
ddeb731c | 107 | struct ipu_psys_resource_pool resource_pool_started; |
f42c302d WY |
108 | |
109 | const struct firmware *fw; | |
110 | struct sg_table fw_sgt; | |
111 | u64 *pkg_dir; | |
112 | dma_addr_t pkg_dir_dma_addr; | |
113 | unsigned int pkg_dir_size; | |
114 | unsigned long timeout; | |
115 | ||
116 | int active_kcmds, started_kcmds; | |
117 | void *fwcom; | |
118 | ||
119 | int power_gating; | |
120 | }; | |
121 | ||
122 | struct ipu_psys_fh { | |
123 | struct ipu_psys *psys; | |
124 | struct mutex mutex; /* Protects bufmap & kcmds fields */ | |
125 | struct list_head list; | |
126 | struct list_head bufmap; | |
127 | wait_queue_head_t wait; | |
128 | struct ipu_psys_scheduler sched; | |
129 | }; | |
130 | ||
131 | struct ipu_psys_pg { | |
132 | struct ipu_fw_psys_process_group *pg; | |
133 | size_t size; | |
134 | size_t pg_size; | |
135 | dma_addr_t pg_dma_addr; | |
136 | struct list_head list; | |
137 | struct ipu_psys_resource_alloc resource_alloc; | |
138 | }; | |
139 | ||
140 | struct ipu_psys_kcmd { | |
141 | struct ipu_psys_fh *fh; | |
142 | struct list_head list; | |
143 | struct ipu_psys_buffer_set *kbuf_set; | |
144 | enum ipu_psys_cmd_state state; | |
145 | void *pg_manifest; | |
146 | size_t pg_manifest_size; | |
147 | struct ipu_psys_kbuffer **kbufs; | |
148 | struct ipu_psys_buffer *buffers; | |
149 | size_t nbuffers; | |
150 | struct ipu_fw_psys_process_group *pg_user; | |
151 | struct ipu_psys_pg *kpg; | |
152 | u64 user_token; | |
153 | u64 issue_id; | |
154 | u32 priority; | |
155 | u32 kernel_enable_bitmap[4]; | |
156 | u32 terminal_enable_bitmap[4]; | |
157 | u32 routing_enable_bitmap[4]; | |
158 | u32 rbm[5]; | |
159 | struct ipu_buttress_constraint constraint; | |
160 | struct ipu_psys_event ev; | |
161 | struct timer_list watchdog; | |
162 | }; | |
163 | ||
164 | struct ipu_dma_buf_attach { | |
165 | struct device *dev; | |
166 | u64 len; | |
167 | void *userptr; | |
168 | struct sg_table *sgt; | |
169 | bool vma_is_io; | |
170 | struct page **pages; | |
171 | size_t npages; | |
172 | }; | |
173 | ||
174 | struct ipu_psys_kbuffer { | |
175 | u64 len; | |
176 | void *userptr; | |
177 | u32 flags; | |
178 | int fd; | |
179 | void *kaddr; | |
180 | struct list_head list; | |
181 | dma_addr_t dma_addr; | |
182 | struct sg_table *sgt; | |
183 | struct dma_buf_attachment *db_attach; | |
184 | struct dma_buf *dbuf; | |
185 | bool valid; /* True when buffer is usable */ | |
186 | }; | |
187 | ||
188 | #define inode_to_ipu_psys(inode) \ | |
189 | container_of((inode)->i_cdev, struct ipu_psys, cdev) | |
190 | ||
191 | #ifdef CONFIG_COMPAT | |
192 | long ipu_psys_compat_ioctl32(struct file *file, unsigned int cmd, | |
193 | unsigned long arg); | |
194 | #endif | |
195 | ||
196 | void ipu_psys_setup_hw(struct ipu_psys *psys); | |
197 | void ipu_psys_subdomains_power(struct ipu_psys *psys, bool on); | |
198 | void ipu_psys_handle_events(struct ipu_psys *psys); | |
199 | int ipu_psys_kcmd_new(struct ipu_psys_command *cmd, struct ipu_psys_fh *fh); | |
200 | void ipu_psys_run_next(struct ipu_psys *psys); | |
ddeb731c | 201 | void ipu_psys_watchdog_work(struct work_struct *work); |
f42c302d WY |
202 | struct ipu_psys_pg *__get_pg_buf(struct ipu_psys *psys, size_t pg_size); |
203 | struct ipu_psys_kbuffer * | |
204 | ipu_psys_lookup_kbuffer(struct ipu_psys_fh *fh, int fd); | |
603641ea WY |
205 | int ipu_psys_mapbuf_locked(int fd, struct ipu_psys_fh *fh, |
206 | struct ipu_psys_kbuffer *kbuf); | |
f42c302d WY |
207 | struct ipu_psys_kbuffer * |
208 | ipu_psys_lookup_kbuffer_by_kaddr(struct ipu_psys_fh *fh, void *kaddr); | |
209 | #ifdef IPU_PSYS_GPC | |
210 | int ipu_psys_gpc_init_debugfs(struct ipu_psys *psys); | |
211 | #endif | |
212 | int ipu_psys_resource_pool_init(struct ipu_psys_resource_pool *pool); | |
213 | void ipu_psys_resource_pool_cleanup(struct ipu_psys_resource_pool *pool); | |
214 | struct ipu_psys_kcmd *ipu_get_completed_kcmd(struct ipu_psys_fh *fh); | |
215 | long ipu_ioctl_dqevent(struct ipu_psys_event *event, | |
216 | struct ipu_psys_fh *fh, unsigned int f_flags); | |
217 | ||
218 | #endif /* IPU_PSYS_H */ |