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
30struct 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
37enum 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
52enum 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
60enum 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 */
74struct 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 */
85struct 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
122int omap4iss_get_external_info(struct iss_pipeline *pipe,
123			       struct media_link *link);
124
125int omap4iss_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait,
126			      atomic_t *stopping);
127
128int omap4iss_module_sync_is_stopping(wait_queue_head_t *wait,
129				     atomic_t *stopping);
130
131int omap4iss_pipeline_set_stream(struct iss_pipeline *pipe,
132				 enum iss_pipeline_stream_state state);
133void omap4iss_pipeline_cancel_stream(struct iss_pipeline *pipe);
134
135void omap4iss_configure_bridge(struct iss_device *iss,
136			       enum ipipeif_input_entity input);
137
138struct iss_device *omap4iss_get(struct iss_device *iss);
139void omap4iss_put(struct iss_device *iss);
140int omap4iss_subclk_enable(struct iss_device *iss,
141			   enum iss_subclk_resource res);
142int omap4iss_subclk_disable(struct iss_device *iss,
143			    enum iss_subclk_resource res);
144void omap4iss_isp_subclk_enable(struct iss_device *iss,
145				enum iss_isp_subclk_resource res);
146void omap4iss_isp_subclk_disable(struct iss_device *iss,
147				 enum iss_isp_subclk_resource res);
148
149int omap4iss_register_entities(struct platform_device *pdev,
150			       struct v4l2_device *v4l2_dev);
151void 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 */
161static inline
162u32 iss_reg_read(struct iss_device *iss, enum iss_mem_resources res,
163		 u32 offset)
164{
165	return readl(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 */
175static inline
176void iss_reg_write(struct iss_device *iss, enum iss_mem_resources res,
177		   u32 offset, u32 value)
178{
179	writel(value, 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 */
189static inline
190void 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, 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 */
205static inline
206void 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, 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 */
224static inline
225void 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, (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