Linux-libre 5.4.48-gnu
[librecmc/linux-libre.git] / drivers / staging / media / omap4iss / iss.h
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 #define v4l2_dev_to_iss_device(dev) \
123         container_of(dev, struct iss_device, v4l2_dev)
124
125 int omap4iss_get_external_info(struct iss_pipeline *pipe,
126                                struct media_link *link);
127
128 int omap4iss_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait,
129                               atomic_t *stopping);
130
131 int omap4iss_module_sync_is_stopping(wait_queue_head_t *wait,
132                                      atomic_t *stopping);
133
134 int omap4iss_pipeline_set_stream(struct iss_pipeline *pipe,
135                                  enum iss_pipeline_stream_state state);
136 void omap4iss_pipeline_cancel_stream(struct iss_pipeline *pipe);
137
138 void omap4iss_configure_bridge(struct iss_device *iss,
139                                enum ipipeif_input_entity input);
140
141 struct iss_device *omap4iss_get(struct iss_device *iss);
142 void omap4iss_put(struct iss_device *iss);
143 int omap4iss_subclk_enable(struct iss_device *iss,
144                            enum iss_subclk_resource res);
145 int omap4iss_subclk_disable(struct iss_device *iss,
146                             enum iss_subclk_resource res);
147 void omap4iss_isp_subclk_enable(struct iss_device *iss,
148                                 enum iss_isp_subclk_resource res);
149 void omap4iss_isp_subclk_disable(struct iss_device *iss,
150                                  enum iss_isp_subclk_resource res);
151
152 int omap4iss_register_entities(struct platform_device *pdev,
153                                struct v4l2_device *v4l2_dev);
154 void omap4iss_unregister_entities(struct platform_device *pdev);
155
156 /*
157  * iss_reg_read - Read the value of an OMAP4 ISS register
158  * @iss: the ISS device
159  * @res: memory resource in which the register is located
160  * @offset: register offset in the memory resource
161  *
162  * Return the register value.
163  */
164 static inline
165 u32 iss_reg_read(struct iss_device *iss, enum iss_mem_resources res,
166                  u32 offset)
167 {
168         return readl(iss->regs[res] + offset);
169 }
170
171 /*
172  * iss_reg_write - Write a value to an OMAP4 ISS register
173  * @iss: the ISS device
174  * @res: memory resource in which the register is located
175  * @offset: register offset in the memory resource
176  * @value: value to be written
177  */
178 static inline
179 void iss_reg_write(struct iss_device *iss, enum iss_mem_resources res,
180                    u32 offset, u32 value)
181 {
182         writel(value, iss->regs[res] + offset);
183 }
184
185 /*
186  * iss_reg_clr - Clear bits in an OMAP4 ISS register
187  * @iss: the ISS device
188  * @res: memory resource in which the register is located
189  * @offset: register offset in the memory resource
190  * @clr: bit mask to be cleared
191  */
192 static inline
193 void iss_reg_clr(struct iss_device *iss, enum iss_mem_resources res,
194                  u32 offset, u32 clr)
195 {
196         u32 v = iss_reg_read(iss, res, offset);
197
198         iss_reg_write(iss, res, offset, v & ~clr);
199 }
200
201 /*
202  * iss_reg_set - Set bits in an OMAP4 ISS register
203  * @iss: the ISS device
204  * @res: memory resource in which the register is located
205  * @offset: register offset in the memory resource
206  * @set: bit mask to be set
207  */
208 static inline
209 void iss_reg_set(struct iss_device *iss, enum iss_mem_resources res,
210                  u32 offset, u32 set)
211 {
212         u32 v = iss_reg_read(iss, res, offset);
213
214         iss_reg_write(iss, res, offset, v | set);
215 }
216
217 /*
218  * iss_reg_update - Clear and set bits in an OMAP4 ISS register
219  * @iss: the ISS device
220  * @res: memory resource in which the register is located
221  * @offset: register offset in the memory resource
222  * @clr: bit mask to be cleared
223  * @set: bit mask to be set
224  *
225  * Clear the clr mask first and then set the set mask.
226  */
227 static inline
228 void iss_reg_update(struct iss_device *iss, enum iss_mem_resources res,
229                     u32 offset, u32 clr, u32 set)
230 {
231         u32 v = iss_reg_read(iss, res, offset);
232
233         iss_reg_write(iss, res, offset, (v & ~clr) | set);
234 }
235
236 #define iss_poll_condition_timeout(cond, timeout, min_ival, max_ival)   \
237 ({                                                                      \
238         unsigned long __timeout = jiffies + usecs_to_jiffies(timeout);  \
239         unsigned int __min_ival = (min_ival);                           \
240         unsigned int __max_ival = (max_ival);                           \
241         bool __cond;                                                    \
242         while (!(__cond = (cond))) {                                    \
243                 if (time_after(jiffies, __timeout))                     \
244                         break;                                          \
245                 usleep_range(__min_ival, __max_ival);                   \
246         }                                                               \
247         !__cond;                                                        \
248 })
249
250 #endif /* _OMAP4_ISS_H_ */