• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
32 struct 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 
39 enum 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 
54 enum 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 
62 enum 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  */
76 struct 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  */
87 struct 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 
127 int omap4iss_get_external_info(struct iss_pipeline *pipe,
128 			       struct media_link *link);
129 
130 int omap4iss_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait,
131 			      atomic_t *stopping);
132 
133 int omap4iss_module_sync_is_stopping(wait_queue_head_t *wait,
134 				     atomic_t *stopping);
135 
136 int omap4iss_pipeline_set_stream(struct iss_pipeline *pipe,
137 				 enum iss_pipeline_stream_state state);
138 void omap4iss_pipeline_cancel_stream(struct iss_pipeline *pipe);
139 
140 void omap4iss_configure_bridge(struct iss_device *iss,
141 			       enum ipipeif_input_entity input);
142 
143 struct iss_device *omap4iss_get(struct iss_device *iss);
144 void omap4iss_put(struct iss_device *iss);
145 int omap4iss_subclk_enable(struct iss_device *iss,
146 			   enum iss_subclk_resource res);
147 int omap4iss_subclk_disable(struct iss_device *iss,
148 			    enum iss_subclk_resource res);
149 void omap4iss_isp_subclk_enable(struct iss_device *iss,
150 				enum iss_isp_subclk_resource res);
151 void omap4iss_isp_subclk_disable(struct iss_device *iss,
152 				 enum iss_isp_subclk_resource res);
153 
154 int omap4iss_pipeline_pm_use(struct media_entity *entity, int use);
155 
156 int omap4iss_register_entities(struct platform_device *pdev,
157 			       struct v4l2_device *v4l2_dev);
158 void 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  */
168 static inline
iss_reg_read(struct iss_device * iss,enum iss_mem_resources res,u32 offset)169 u32 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  */
182 static inline
iss_reg_write(struct iss_device * iss,enum iss_mem_resources res,u32 offset,u32 value)183 void 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  */
196 static inline
iss_reg_clr(struct iss_device * iss,enum iss_mem_resources res,u32 offset,u32 clr)197 void 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  */
212 static inline
iss_reg_set(struct iss_device * iss,enum iss_mem_resources res,u32 offset,u32 set)213 void 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  */
231 static inline
iss_reg_update(struct iss_device * iss,enum iss_mem_resources res,u32 offset,u32 clr,u32 set)232 void 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