aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/media/omap4iss/iss.h
blob: 35df8b4709e6089d44f15d81fa989e9a4a6840cc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
/*
 * TI OMAP4 ISS V4L2 Driver
 *
 * Copyright (C) 2012 Texas Instruments.
 *
 * Author: Sergio Aguirre <sergio.a.aguirre@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#ifndef _OMAP4_ISS_H_
#define _OMAP4_ISS_H_

#include <media/v4l2-device.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/wait.h>

#include <media/omap4iss.h>

#include "iss_regs.h"
#include "iss_csiphy.h"
#include "iss_csi2.h"
#include "iss_ipipeif.h"
#include "iss_ipipe.h"
#include "iss_resizer.h"

struct regmap;

#define to_iss_device(ptr_module)				\
	container_of(ptr_module, struct iss_device, ptr_module)
#define to_device(ptr_module)						\
	(to_iss_device(ptr_module)->dev)

enum iss_mem_resources {
	OMAP4_ISS_MEM_TOP,
	OMAP4_ISS_MEM_CSI2_A_REGS1,
	OMAP4_ISS_MEM_CAMERARX_CORE1,
	OMAP4_ISS_MEM_CSI2_B_REGS1,
	OMAP4_ISS_MEM_CAMERARX_CORE2,
	OMAP4_ISS_MEM_BTE,
	OMAP4_ISS_MEM_ISP_SYS1,
	OMAP4_ISS_MEM_ISP_RESIZER,
	OMAP4_ISS_MEM_ISP_IPIPE,
	OMAP4_ISS_MEM_ISP_ISIF,
	OMAP4_ISS_MEM_ISP_IPIPEIF,
	OMAP4_ISS_MEM_LAST,
};

enum iss_subclk_resource {
	OMAP4_ISS_SUBCLK_SIMCOP		= (1 << 0),
	OMAP4_ISS_SUBCLK_ISP		= (1 << 1),
	OMAP4_ISS_SUBCLK_CSI2_A		= (1 << 2),
	OMAP4_ISS_SUBCLK_CSI2_B		= (1 << 3),
	OMAP4_ISS_SUBCLK_CCP2		= (1 << 4),
};

enum iss_isp_subclk_resource {
	OMAP4_ISS_ISP_SUBCLK_BL		= (1 << 0),
	OMAP4_ISS_ISP_SUBCLK_ISIF	= (1 << 1),
	OMAP4_ISS_ISP_SUBCLK_H3A	= (1 << 2),
	OMAP4_ISS_ISP_SUBCLK_RSZ	= (1 << 3),
	OMAP4_ISS_ISP_SUBCLK_IPIPE	= (1 << 4),
	OMAP4_ISS_ISP_SUBCLK_IPIPEIF	= (1 << 5),
};

/*
 * struct iss_reg - Structure for ISS register values.
 * @reg: 32-bit Register address.
 * @val: 32-bit Register value.
 */
struct iss_reg {
	enum iss_mem_resources mmio_range;
	u32 reg;
	u32 val;
};

/*
 * struct iss_device - ISS device structure.
 * @syscon: Regmap for the syscon register space
 * @crashed: Bitmask of crashed entities (indexed by entity ID)
 */
struct iss_device {
	struct v4l2_device v4l2_dev;
	struct media_device media_dev;
	struct device *dev;
	u32 revision;

	/* platform HW resources */
	struct iss_platform_data *pdata;
	unsigned int irq_num;

	struct resource *res[OMAP4_ISS_MEM_LAST];
	void __iomem *regs[OMAP4_ISS_MEM_LAST];
	struct regmap *syscon;

	u64 raw_dmamask;

	struct mutex iss_mutex;	/* For handling ref_count field */
	unsigned int crashed;
	int has_context;
	int ref_count;

	struct clk *iss_fck;
	struct clk *iss_ctrlclk;

	/* ISS modules */
	struct iss_csi2_device csi2a;
	struct iss_csi2_device csi2b;
	struct iss_csiphy csiphy1;
	struct iss_csiphy csiphy2;
	struct iss_ipipeif_device ipipeif;
	struct iss_ipipe_device ipipe;
	struct iss_resizer_device resizer;

	unsigned int subclk_resources;
	unsigned int isp_subclk_resources;
};

#define v4l2_dev_to_iss_device(dev) \
	container_of(dev, struct iss_device, v4l2_dev)

int omap4iss_get_external_info(struct iss_pipeline *pipe,
			       struct media_link *link);

int omap4iss_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait,
			      atomic_t *stopping);

int omap4iss_module_sync_is_stopping(wait_queue_head_t *wait,
				     atomic_t *stopping);

int omap4iss_pipeline_set_stream(struct iss_pipeline *pipe,
				 enum iss_pipeline_stream_state state);
void omap4iss_pipeline_cancel_stream(struct iss_pipeline *pipe);

void omap4iss_configure_bridge(struct iss_device *iss,
			       enum ipipeif_input_entity input);

struct iss_device *omap4iss_get(struct iss_device *iss);
void omap4iss_put(struct iss_device *iss);
int omap4iss_subclk_enable(struct iss_device *iss,
			   enum iss_subclk_resource res);
int omap4iss_subclk_disable(struct iss_device *iss,
			    enum iss_subclk_resource res);
void omap4iss_isp_subclk_enable(struct iss_device *iss,
				enum iss_isp_subclk_resource res);
void omap4iss_isp_subclk_disable(struct iss_device *iss,
				 enum iss_isp_subclk_resource res);

int omap4iss_pipeline_pm_use(struct media_entity *entity, int use);

int omap4iss_register_entities(struct platform_device *pdev,
			       struct v4l2_device *v4l2_dev);
void omap4iss_unregister_entities(struct platform_device *pdev);

/*
 * iss_reg_read - Read the value of an OMAP4 ISS register
 * @iss: the ISS device
 * @res: memory resource in which the register is located
 * @offset: register offset in the memory resource
 *
 * Return the register value.
 */
static inline
u32 iss_reg_read(struct iss_device *iss, enum iss_mem_resources res,
		 u32 offset)
{
	return readl(iss->regs[res] + offset);
}

/*
 * iss_reg_write - Write a value to an OMAP4 ISS register
 * @iss: the ISS device
 * @res: memory resource in which the register is located
 * @offset: register offset in the memory resource
 * @value: value to be written
 */
static inline
void iss_reg_write(struct iss_device *iss, enum iss_mem_resources res,
		   u32 offset, u32 value)
{
	writel(value, iss->regs[res] + offset);
}

/*
 * iss_reg_clr - Clear bits in an OMAP4 ISS register
 * @iss: the ISS device
 * @res: memory resource in which the register is located
 * @offset: register offset in the memory resource
 * @clr: bit mask to be cleared
 */
static inline
void iss_reg_clr(struct iss_device *iss, enum iss_mem_resources res,
		 u32 offset, u32 clr)
{
	u32 v = iss_reg_read(iss, res, offset);

	iss_reg_write(iss, res, offset, v & ~clr);
}

/*
 * iss_reg_set - Set bits in an OMAP4 ISS register
 * @iss: the ISS device
 * @res: memory resource in which the register is located
 * @offset: register offset in the memory resource
 * @set: bit mask to be set
 */
static inline
void iss_reg_set(struct iss_device *iss, enum iss_mem_resources res,
		 u32 offset, u32 set)
{
	u32 v = iss_reg_read(iss, res, offset);

	iss_reg_write(iss, res, offset, v | set);
}

/*
 * iss_reg_update - Clear and set bits in an OMAP4 ISS register
 * @iss: the ISS device
 * @res: memory resource in which the register is located
 * @offset: register offset in the memory resource
 * @clr: bit mask to be cleared
 * @set: bit mask to be set
 *
 * Clear the clr mask first and then set the set mask.
 */
static inline
void iss_reg_update(struct iss_device *iss, enum iss_mem_resources res,
		    u32 offset, u32 clr, u32 set)
{
	u32 v = iss_reg_read(iss, res, offset);

	iss_reg_write(iss, res, offset, (v & ~clr) | set);
}

#define iss_poll_condition_timeout(cond, timeout, min_ival, max_ival)	\
({									\
	unsigned long __timeout = jiffies + usecs_to_jiffies(timeout);	\
	unsigned int __min_ival = (min_ival);				\
	unsigned int __max_ival = (max_ival);				\
	bool __cond;							\
	while (!(__cond = (cond))) {					\
		if (time_after(jiffies, __timeout))			\
			break;						\
		usleep_range(__min_ival, __max_ival);			\
	}								\
	!__cond;							\
})

#endif /* _OMAP4_ISS_H_ */