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