1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
2 | /* |
3 | * TI OMAP4 ISS V4L2 Driver |
4 | * |
5 | * Copyright (C) 2012 Texas Instruments. |
6 | * |
7 | * Author: Sergio Aguirre <sergio.a.aguirre@gmail.com> |
8 | */ |
9 | |
10 | #ifndef _OMAP4_ISS_H_ |
11 | #define _OMAP4_ISS_H_ |
12 | |
13 | #include <media/v4l2-device.h> |
14 | #include <media/v4l2-mc.h> |
15 | |
16 | #include <linux/device.h> |
17 | #include <linux/io.h> |
18 | #include <linux/platform_device.h> |
19 | #include <linux/wait.h> |
20 | |
21 | #include <linux/platform_data/media/omap4iss.h> |
22 | |
23 | #include "iss_regs.h" |
24 | #include "iss_csiphy.h" |
25 | #include "iss_csi2.h" |
26 | #include "iss_ipipeif.h" |
27 | #include "iss_ipipe.h" |
28 | #include "iss_resizer.h" |
29 | |
30 | struct regmap; |
31 | |
32 | #define to_iss_device(ptr_module) \ |
33 | container_of(ptr_module, struct iss_device, ptr_module) |
34 | #define to_device(ptr_module) \ |
35 | (to_iss_device(ptr_module)->dev) |
36 | |
37 | enum iss_mem_resources { |
38 | OMAP4_ISS_MEM_TOP, |
39 | OMAP4_ISS_MEM_CSI2_A_REGS1, |
40 | OMAP4_ISS_MEM_CAMERARX_CORE1, |
41 | OMAP4_ISS_MEM_CSI2_B_REGS1, |
42 | OMAP4_ISS_MEM_CAMERARX_CORE2, |
43 | OMAP4_ISS_MEM_BTE, |
44 | OMAP4_ISS_MEM_ISP_SYS1, |
45 | OMAP4_ISS_MEM_ISP_RESIZER, |
46 | OMAP4_ISS_MEM_ISP_IPIPE, |
47 | OMAP4_ISS_MEM_ISP_ISIF, |
48 | OMAP4_ISS_MEM_ISP_IPIPEIF, |
49 | OMAP4_ISS_MEM_LAST, |
50 | }; |
51 | |
52 | enum iss_subclk_resource { |
53 | OMAP4_ISS_SUBCLK_SIMCOP = (1 << 0), |
54 | OMAP4_ISS_SUBCLK_ISP = (1 << 1), |
55 | OMAP4_ISS_SUBCLK_CSI2_A = (1 << 2), |
56 | OMAP4_ISS_SUBCLK_CSI2_B = (1 << 3), |
57 | OMAP4_ISS_SUBCLK_CCP2 = (1 << 4), |
58 | }; |
59 | |
60 | enum iss_isp_subclk_resource { |
61 | OMAP4_ISS_ISP_SUBCLK_BL = (1 << 0), |
62 | OMAP4_ISS_ISP_SUBCLK_ISIF = (1 << 1), |
63 | OMAP4_ISS_ISP_SUBCLK_H3A = (1 << 2), |
64 | OMAP4_ISS_ISP_SUBCLK_RSZ = (1 << 3), |
65 | OMAP4_ISS_ISP_SUBCLK_IPIPE = (1 << 4), |
66 | OMAP4_ISS_ISP_SUBCLK_IPIPEIF = (1 << 5), |
67 | }; |
68 | |
69 | /* |
70 | * struct iss_reg - Structure for ISS register values. |
71 | * @reg: 32-bit Register address. |
72 | * @val: 32-bit Register value. |
73 | */ |
74 | struct iss_reg { |
75 | enum iss_mem_resources mmio_range; |
76 | u32 reg; |
77 | u32 val; |
78 | }; |
79 | |
80 | /* |
81 | * struct iss_device - ISS device structure. |
82 | * @syscon: Regmap for the syscon register space |
83 | * @crashed: Crashed entities |
84 | */ |
85 | struct iss_device { |
86 | struct v4l2_device v4l2_dev; |
87 | struct media_device media_dev; |
88 | struct device *dev; |
89 | u32 revision; |
90 | |
91 | /* platform HW resources */ |
92 | struct iss_platform_data *pdata; |
93 | unsigned int irq_num; |
94 | |
95 | struct resource *res[OMAP4_ISS_MEM_LAST]; |
96 | void __iomem *regs[OMAP4_ISS_MEM_LAST]; |
97 | struct regmap *syscon; |
98 | |
99 | u64 raw_dmamask; |
100 | |
101 | struct mutex iss_mutex; /* For handling ref_count field */ |
102 | struct media_entity_enum crashed; |
103 | int has_context; |
104 | int ref_count; |
105 | |
106 | struct clk *iss_fck; |
107 | struct clk *iss_ctrlclk; |
108 | |
109 | /* ISS modules */ |
110 | struct iss_csi2_device csi2a; |
111 | struct iss_csi2_device csi2b; |
112 | struct iss_csiphy csiphy1; |
113 | struct iss_csiphy csiphy2; |
114 | struct iss_ipipeif_device ipipeif; |
115 | struct iss_ipipe_device ipipe; |
116 | struct iss_resizer_device resizer; |
117 | |
118 | unsigned int subclk_resources; |
119 | unsigned int isp_subclk_resources; |
120 | }; |
121 | |
122 | int omap4iss_get_external_info(struct iss_pipeline *pipe, |
123 | struct media_link *link); |
124 | |
125 | int omap4iss_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait, |
126 | atomic_t *stopping); |
127 | |
128 | int omap4iss_module_sync_is_stopping(wait_queue_head_t *wait, |
129 | atomic_t *stopping); |
130 | |
131 | int omap4iss_pipeline_set_stream(struct iss_pipeline *pipe, |
132 | enum iss_pipeline_stream_state state); |
133 | void omap4iss_pipeline_cancel_stream(struct iss_pipeline *pipe); |
134 | |
135 | void omap4iss_configure_bridge(struct iss_device *iss, |
136 | enum ipipeif_input_entity input); |
137 | |
138 | struct iss_device *omap4iss_get(struct iss_device *iss); |
139 | void omap4iss_put(struct iss_device *iss); |
140 | int omap4iss_subclk_enable(struct iss_device *iss, |
141 | enum iss_subclk_resource res); |
142 | int omap4iss_subclk_disable(struct iss_device *iss, |
143 | enum iss_subclk_resource res); |
144 | void omap4iss_isp_subclk_enable(struct iss_device *iss, |
145 | enum iss_isp_subclk_resource res); |
146 | void omap4iss_isp_subclk_disable(struct iss_device *iss, |
147 | enum iss_isp_subclk_resource res); |
148 | |
149 | int omap4iss_register_entities(struct platform_device *pdev, |
150 | struct v4l2_device *v4l2_dev); |
151 | void omap4iss_unregister_entities(struct platform_device *pdev); |
152 | |
153 | /* |
154 | * iss_reg_read - Read the value of an OMAP4 ISS register |
155 | * @iss: the ISS device |
156 | * @res: memory resource in which the register is located |
157 | * @offset: register offset in the memory resource |
158 | * |
159 | * Return the register value. |
160 | */ |
161 | static inline |
162 | u32 iss_reg_read(struct iss_device *iss, enum iss_mem_resources res, |
163 | u32 offset) |
164 | { |
165 | return readl(addr: iss->regs[res] + offset); |
166 | } |
167 | |
168 | /* |
169 | * iss_reg_write - Write a value to an OMAP4 ISS register |
170 | * @iss: the ISS device |
171 | * @res: memory resource in which the register is located |
172 | * @offset: register offset in the memory resource |
173 | * @value: value to be written |
174 | */ |
175 | static inline |
176 | void iss_reg_write(struct iss_device *iss, enum iss_mem_resources res, |
177 | u32 offset, u32 value) |
178 | { |
179 | writel(val: value, addr: iss->regs[res] + offset); |
180 | } |
181 | |
182 | /* |
183 | * iss_reg_clr - Clear bits in an OMAP4 ISS register |
184 | * @iss: the ISS device |
185 | * @res: memory resource in which the register is located |
186 | * @offset: register offset in the memory resource |
187 | * @clr: bit mask to be cleared |
188 | */ |
189 | static inline |
190 | void iss_reg_clr(struct iss_device *iss, enum iss_mem_resources res, |
191 | u32 offset, u32 clr) |
192 | { |
193 | u32 v = iss_reg_read(iss, res, offset); |
194 | |
195 | iss_reg_write(iss, res, offset, value: v & ~clr); |
196 | } |
197 | |
198 | /* |
199 | * iss_reg_set - Set bits in an OMAP4 ISS register |
200 | * @iss: the ISS device |
201 | * @res: memory resource in which the register is located |
202 | * @offset: register offset in the memory resource |
203 | * @set: bit mask to be set |
204 | */ |
205 | static inline |
206 | void iss_reg_set(struct iss_device *iss, enum iss_mem_resources res, |
207 | u32 offset, u32 set) |
208 | { |
209 | u32 v = iss_reg_read(iss, res, offset); |
210 | |
211 | iss_reg_write(iss, res, offset, value: v | set); |
212 | } |
213 | |
214 | /* |
215 | * iss_reg_update - Clear and set bits in an OMAP4 ISS register |
216 | * @iss: the ISS device |
217 | * @res: memory resource in which the register is located |
218 | * @offset: register offset in the memory resource |
219 | * @clr: bit mask to be cleared |
220 | * @set: bit mask to be set |
221 | * |
222 | * Clear the clr mask first and then set the set mask. |
223 | */ |
224 | static inline |
225 | void iss_reg_update(struct iss_device *iss, enum iss_mem_resources res, |
226 | u32 offset, u32 clr, u32 set) |
227 | { |
228 | u32 v = iss_reg_read(iss, res, offset); |
229 | |
230 | iss_reg_write(iss, res, offset, value: (v & ~clr) | set); |
231 | } |
232 | |
233 | #define iss_poll_condition_timeout(cond, timeout, min_ival, max_ival) \ |
234 | ({ \ |
235 | unsigned long __timeout = jiffies + usecs_to_jiffies(timeout); \ |
236 | unsigned int __min_ival = (min_ival); \ |
237 | unsigned int __max_ival = (max_ival); \ |
238 | bool __cond; \ |
239 | while (!(__cond = (cond))) { \ |
240 | if (time_after(jiffies, __timeout)) \ |
241 | break; \ |
242 | usleep_range(__min_ival, __max_ival); \ |
243 | } \ |
244 | !__cond; \ |
245 | }) |
246 | |
247 | #endif /* _OMAP4_ISS_H_ */ |
248 | |