diff options
Diffstat (limited to 'drivers/media/video/s5p-fimc/fimc-reg.c')
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-reg.c | 527 |
1 files changed, 527 insertions, 0 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-reg.c b/drivers/media/video/s5p-fimc/fimc-reg.c new file mode 100644 index 000000000000..5570f1ce0c9c --- /dev/null +++ b/drivers/media/video/s5p-fimc/fimc-reg.c | |||
@@ -0,0 +1,527 @@ | |||
1 | /* | ||
2 | * Register interface file for Samsung Camera Interface (FIMC) driver | ||
3 | * | ||
4 | * Copyright (c) 2010 Samsung Electronics | ||
5 | * | ||
6 | * Sylwester Nawrocki, s.nawrocki@samsung.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 version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/io.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <mach/map.h> | ||
16 | |||
17 | #include "fimc-core.h" | ||
18 | |||
19 | |||
20 | void fimc_hw_reset(struct fimc_dev *dev) | ||
21 | { | ||
22 | u32 cfg; | ||
23 | |||
24 | cfg = readl(dev->regs + S5P_CISRCFMT); | ||
25 | cfg |= S5P_CISRCFMT_ITU601_8BIT; | ||
26 | writel(cfg, dev->regs + S5P_CISRCFMT); | ||
27 | |||
28 | /* Software reset. */ | ||
29 | cfg = readl(dev->regs + S5P_CIGCTRL); | ||
30 | cfg |= (S5P_CIGCTRL_SWRST | S5P_CIGCTRL_IRQ_LEVEL); | ||
31 | writel(cfg, dev->regs + S5P_CIGCTRL); | ||
32 | msleep(1); | ||
33 | |||
34 | cfg = readl(dev->regs + S5P_CIGCTRL); | ||
35 | cfg &= ~S5P_CIGCTRL_SWRST; | ||
36 | writel(cfg, dev->regs + S5P_CIGCTRL); | ||
37 | |||
38 | } | ||
39 | |||
40 | void fimc_hw_set_rotation(struct fimc_ctx *ctx) | ||
41 | { | ||
42 | u32 cfg, flip; | ||
43 | struct fimc_dev *dev = ctx->fimc_dev; | ||
44 | |||
45 | cfg = readl(dev->regs + S5P_CITRGFMT); | ||
46 | cfg &= ~(S5P_CITRGFMT_INROT90 | S5P_CITRGFMT_OUTROT90); | ||
47 | |||
48 | flip = readl(dev->regs + S5P_MSCTRL); | ||
49 | flip &= ~S5P_MSCTRL_FLIP_MASK; | ||
50 | |||
51 | /* | ||
52 | * The input and output rotator cannot work simultaneously. | ||
53 | * Use the output rotator in output DMA mode or the input rotator | ||
54 | * in direct fifo output mode. | ||
55 | */ | ||
56 | if (ctx->rotation == 90 || ctx->rotation == 270) { | ||
57 | if (ctx->out_path == FIMC_LCDFIFO) { | ||
58 | cfg |= S5P_CITRGFMT_INROT90; | ||
59 | if (ctx->rotation == 270) | ||
60 | flip |= S5P_MSCTRL_FLIP_180; | ||
61 | } else { | ||
62 | cfg |= S5P_CITRGFMT_OUTROT90; | ||
63 | if (ctx->rotation == 270) | ||
64 | cfg |= S5P_CITRGFMT_FLIP_180; | ||
65 | } | ||
66 | } else if (ctx->rotation == 180) { | ||
67 | if (ctx->out_path == FIMC_LCDFIFO) | ||
68 | flip |= S5P_MSCTRL_FLIP_180; | ||
69 | else | ||
70 | cfg |= S5P_CITRGFMT_FLIP_180; | ||
71 | } | ||
72 | if (ctx->rotation == 180 || ctx->rotation == 270) | ||
73 | writel(flip, dev->regs + S5P_MSCTRL); | ||
74 | writel(cfg, dev->regs + S5P_CITRGFMT); | ||
75 | } | ||
76 | |||
77 | static u32 fimc_hw_get_in_flip(u32 ctx_flip) | ||
78 | { | ||
79 | u32 flip = S5P_MSCTRL_FLIP_NORMAL; | ||
80 | |||
81 | switch (ctx_flip) { | ||
82 | case FLIP_X_AXIS: | ||
83 | flip = S5P_MSCTRL_FLIP_X_MIRROR; | ||
84 | break; | ||
85 | case FLIP_Y_AXIS: | ||
86 | flip = S5P_MSCTRL_FLIP_Y_MIRROR; | ||
87 | break; | ||
88 | case FLIP_XY_AXIS: | ||
89 | flip = S5P_MSCTRL_FLIP_180; | ||
90 | break; | ||
91 | } | ||
92 | |||
93 | return flip; | ||
94 | } | ||
95 | |||
96 | static u32 fimc_hw_get_target_flip(u32 ctx_flip) | ||
97 | { | ||
98 | u32 flip = S5P_CITRGFMT_FLIP_NORMAL; | ||
99 | |||
100 | switch (ctx_flip) { | ||
101 | case FLIP_X_AXIS: | ||
102 | flip = S5P_CITRGFMT_FLIP_X_MIRROR; | ||
103 | break; | ||
104 | case FLIP_Y_AXIS: | ||
105 | flip = S5P_CITRGFMT_FLIP_Y_MIRROR; | ||
106 | break; | ||
107 | case FLIP_XY_AXIS: | ||
108 | flip = S5P_CITRGFMT_FLIP_180; | ||
109 | break; | ||
110 | case FLIP_NONE: | ||
111 | break; | ||
112 | |||
113 | } | ||
114 | return flip; | ||
115 | } | ||
116 | |||
117 | void fimc_hw_set_target_format(struct fimc_ctx *ctx) | ||
118 | { | ||
119 | u32 cfg; | ||
120 | struct fimc_dev *dev = ctx->fimc_dev; | ||
121 | struct fimc_frame *frame = &ctx->d_frame; | ||
122 | |||
123 | dbg("w= %d, h= %d color: %d", frame->width, | ||
124 | frame->height, frame->fmt->color); | ||
125 | |||
126 | cfg = readl(dev->regs + S5P_CITRGFMT); | ||
127 | cfg &= ~(S5P_CITRGFMT_FMT_MASK | S5P_CITRGFMT_HSIZE_MASK | | ||
128 | S5P_CITRGFMT_VSIZE_MASK); | ||
129 | |||
130 | switch (frame->fmt->color) { | ||
131 | case S5P_FIMC_RGB565: | ||
132 | case S5P_FIMC_RGB666: | ||
133 | case S5P_FIMC_RGB888: | ||
134 | cfg |= S5P_CITRGFMT_RGB; | ||
135 | break; | ||
136 | case S5P_FIMC_YCBCR420: | ||
137 | cfg |= S5P_CITRGFMT_YCBCR420; | ||
138 | break; | ||
139 | case S5P_FIMC_YCBYCR422: | ||
140 | case S5P_FIMC_YCRYCB422: | ||
141 | case S5P_FIMC_CBYCRY422: | ||
142 | case S5P_FIMC_CRYCBY422: | ||
143 | if (frame->fmt->planes_cnt == 1) | ||
144 | cfg |= S5P_CITRGFMT_YCBCR422_1P; | ||
145 | else | ||
146 | cfg |= S5P_CITRGFMT_YCBCR422; | ||
147 | break; | ||
148 | default: | ||
149 | break; | ||
150 | } | ||
151 | |||
152 | cfg |= S5P_CITRGFMT_HSIZE(frame->width); | ||
153 | cfg |= S5P_CITRGFMT_VSIZE(frame->height); | ||
154 | |||
155 | if (ctx->rotation == 0) { | ||
156 | cfg &= ~S5P_CITRGFMT_FLIP_MASK; | ||
157 | cfg |= fimc_hw_get_target_flip(ctx->flip); | ||
158 | } | ||
159 | writel(cfg, dev->regs + S5P_CITRGFMT); | ||
160 | |||
161 | cfg = readl(dev->regs + S5P_CITAREA) & ~S5P_CITAREA_MASK; | ||
162 | cfg |= (frame->width * frame->height); | ||
163 | writel(cfg, dev->regs + S5P_CITAREA); | ||
164 | } | ||
165 | |||
166 | static void fimc_hw_set_out_dma_size(struct fimc_ctx *ctx) | ||
167 | { | ||
168 | struct fimc_dev *dev = ctx->fimc_dev; | ||
169 | struct fimc_frame *frame = &ctx->d_frame; | ||
170 | u32 cfg = 0; | ||
171 | |||
172 | if (ctx->rotation == 90 || ctx->rotation == 270) { | ||
173 | cfg |= S5P_ORIG_SIZE_HOR(frame->f_height); | ||
174 | cfg |= S5P_ORIG_SIZE_VER(frame->f_width); | ||
175 | } else { | ||
176 | cfg |= S5P_ORIG_SIZE_HOR(frame->f_width); | ||
177 | cfg |= S5P_ORIG_SIZE_VER(frame->f_height); | ||
178 | } | ||
179 | writel(cfg, dev->regs + S5P_ORGOSIZE); | ||
180 | } | ||
181 | |||
182 | void fimc_hw_set_out_dma(struct fimc_ctx *ctx) | ||
183 | { | ||
184 | u32 cfg; | ||
185 | struct fimc_dev *dev = ctx->fimc_dev; | ||
186 | struct fimc_frame *frame = &ctx->d_frame; | ||
187 | struct fimc_dma_offset *offset = &frame->dma_offset; | ||
188 | |||
189 | /* Set the input dma offsets. */ | ||
190 | cfg = 0; | ||
191 | cfg |= S5P_CIO_OFFS_HOR(offset->y_h); | ||
192 | cfg |= S5P_CIO_OFFS_VER(offset->y_v); | ||
193 | writel(cfg, dev->regs + S5P_CIOYOFF); | ||
194 | |||
195 | cfg = 0; | ||
196 | cfg |= S5P_CIO_OFFS_HOR(offset->cb_h); | ||
197 | cfg |= S5P_CIO_OFFS_VER(offset->cb_v); | ||
198 | writel(cfg, dev->regs + S5P_CIOCBOFF); | ||
199 | |||
200 | cfg = 0; | ||
201 | cfg |= S5P_CIO_OFFS_HOR(offset->cr_h); | ||
202 | cfg |= S5P_CIO_OFFS_VER(offset->cr_v); | ||
203 | writel(cfg, dev->regs + S5P_CIOCROFF); | ||
204 | |||
205 | fimc_hw_set_out_dma_size(ctx); | ||
206 | |||
207 | /* Configure chroma components order. */ | ||
208 | cfg = readl(dev->regs + S5P_CIOCTRL); | ||
209 | |||
210 | cfg &= ~(S5P_CIOCTRL_ORDER2P_MASK | S5P_CIOCTRL_ORDER422_MASK | | ||
211 | S5P_CIOCTRL_YCBCR_PLANE_MASK); | ||
212 | |||
213 | if (frame->fmt->planes_cnt == 1) | ||
214 | cfg |= ctx->out_order_1p; | ||
215 | else if (frame->fmt->planes_cnt == 2) | ||
216 | cfg |= ctx->out_order_2p | S5P_CIOCTRL_YCBCR_2PLANE; | ||
217 | else if (frame->fmt->planes_cnt == 3) | ||
218 | cfg |= S5P_CIOCTRL_YCBCR_3PLANE; | ||
219 | |||
220 | writel(cfg, dev->regs + S5P_CIOCTRL); | ||
221 | } | ||
222 | |||
223 | static void fimc_hw_en_autoload(struct fimc_dev *dev, int enable) | ||
224 | { | ||
225 | u32 cfg = readl(dev->regs + S5P_ORGISIZE); | ||
226 | if (enable) | ||
227 | cfg |= S5P_CIREAL_ISIZE_AUTOLOAD_EN; | ||
228 | else | ||
229 | cfg &= ~S5P_CIREAL_ISIZE_AUTOLOAD_EN; | ||
230 | writel(cfg, dev->regs + S5P_ORGISIZE); | ||
231 | } | ||
232 | |||
233 | void fimc_hw_en_lastirq(struct fimc_dev *dev, int enable) | ||
234 | { | ||
235 | unsigned long flags; | ||
236 | u32 cfg; | ||
237 | |||
238 | spin_lock_irqsave(&dev->slock, flags); | ||
239 | |||
240 | cfg = readl(dev->regs + S5P_CIOCTRL); | ||
241 | if (enable) | ||
242 | cfg |= S5P_CIOCTRL_LASTIRQ_ENABLE; | ||
243 | else | ||
244 | cfg &= ~S5P_CIOCTRL_LASTIRQ_ENABLE; | ||
245 | writel(cfg, dev->regs + S5P_CIOCTRL); | ||
246 | |||
247 | spin_unlock_irqrestore(&dev->slock, flags); | ||
248 | } | ||
249 | |||
250 | void fimc_hw_set_prescaler(struct fimc_ctx *ctx) | ||
251 | { | ||
252 | struct fimc_dev *dev = ctx->fimc_dev; | ||
253 | struct fimc_scaler *sc = &ctx->scaler; | ||
254 | u32 cfg = 0, shfactor; | ||
255 | |||
256 | shfactor = 10 - (sc->hfactor + sc->vfactor); | ||
257 | |||
258 | cfg |= S5P_CISCPRERATIO_SHFACTOR(shfactor); | ||
259 | cfg |= S5P_CISCPRERATIO_HOR(sc->pre_hratio); | ||
260 | cfg |= S5P_CISCPRERATIO_VER(sc->pre_vratio); | ||
261 | writel(cfg, dev->regs + S5P_CISCPRERATIO); | ||
262 | |||
263 | cfg = 0; | ||
264 | cfg |= S5P_CISCPREDST_WIDTH(sc->pre_dst_width); | ||
265 | cfg |= S5P_CISCPREDST_HEIGHT(sc->pre_dst_height); | ||
266 | writel(cfg, dev->regs + S5P_CISCPREDST); | ||
267 | } | ||
268 | |||
269 | void fimc_hw_set_scaler(struct fimc_ctx *ctx) | ||
270 | { | ||
271 | struct fimc_dev *dev = ctx->fimc_dev; | ||
272 | struct fimc_scaler *sc = &ctx->scaler; | ||
273 | struct fimc_frame *src_frame = &ctx->s_frame; | ||
274 | struct fimc_frame *dst_frame = &ctx->d_frame; | ||
275 | u32 cfg = 0; | ||
276 | |||
277 | if (!(ctx->flags & FIMC_COLOR_RANGE_NARROW)) | ||
278 | cfg |= (S5P_CISCCTRL_CSCR2Y_WIDE | S5P_CISCCTRL_CSCY2R_WIDE); | ||
279 | |||
280 | if (!sc->enabled) | ||
281 | cfg |= S5P_CISCCTRL_SCALERBYPASS; | ||
282 | |||
283 | if (sc->scaleup_h) | ||
284 | cfg |= S5P_CISCCTRL_SCALEUP_H; | ||
285 | |||
286 | if (sc->scaleup_v) | ||
287 | cfg |= S5P_CISCCTRL_SCALEUP_V; | ||
288 | |||
289 | if (sc->copy_mode) | ||
290 | cfg |= S5P_CISCCTRL_ONE2ONE; | ||
291 | |||
292 | |||
293 | if (ctx->in_path == FIMC_DMA) { | ||
294 | if (src_frame->fmt->color == S5P_FIMC_RGB565) | ||
295 | cfg |= S5P_CISCCTRL_INRGB_FMT_RGB565; | ||
296 | else if (src_frame->fmt->color == S5P_FIMC_RGB666) | ||
297 | cfg |= S5P_CISCCTRL_INRGB_FMT_RGB666; | ||
298 | else if (src_frame->fmt->color == S5P_FIMC_RGB888) | ||
299 | cfg |= S5P_CISCCTRL_INRGB_FMT_RGB888; | ||
300 | } | ||
301 | |||
302 | if (ctx->out_path == FIMC_DMA) { | ||
303 | if (dst_frame->fmt->color == S5P_FIMC_RGB565) | ||
304 | cfg |= S5P_CISCCTRL_OUTRGB_FMT_RGB565; | ||
305 | else if (dst_frame->fmt->color == S5P_FIMC_RGB666) | ||
306 | cfg |= S5P_CISCCTRL_OUTRGB_FMT_RGB666; | ||
307 | else if (dst_frame->fmt->color == S5P_FIMC_RGB888) | ||
308 | cfg |= S5P_CISCCTRL_OUTRGB_FMT_RGB888; | ||
309 | } else { | ||
310 | cfg |= S5P_CISCCTRL_OUTRGB_FMT_RGB888; | ||
311 | |||
312 | if (ctx->flags & FIMC_SCAN_MODE_INTERLACED) | ||
313 | cfg |= S5P_CISCCTRL_INTERLACE; | ||
314 | } | ||
315 | |||
316 | dbg("main_hratio= 0x%X main_vratio= 0x%X", | ||
317 | sc->main_hratio, sc->main_vratio); | ||
318 | |||
319 | cfg |= S5P_CISCCTRL_SC_HORRATIO(sc->main_hratio); | ||
320 | cfg |= S5P_CISCCTRL_SC_VERRATIO(sc->main_vratio); | ||
321 | |||
322 | writel(cfg, dev->regs + S5P_CISCCTRL); | ||
323 | } | ||
324 | |||
325 | void fimc_hw_en_capture(struct fimc_ctx *ctx) | ||
326 | { | ||
327 | struct fimc_dev *dev = ctx->fimc_dev; | ||
328 | u32 cfg; | ||
329 | |||
330 | cfg = readl(dev->regs + S5P_CIIMGCPT); | ||
331 | /* One shot mode for output DMA or freerun for FIFO. */ | ||
332 | if (ctx->out_path == FIMC_DMA) | ||
333 | cfg |= S5P_CIIMGCPT_CPT_FREN_ENABLE; | ||
334 | else | ||
335 | cfg &= ~S5P_CIIMGCPT_CPT_FREN_ENABLE; | ||
336 | |||
337 | if (ctx->scaler.enabled) | ||
338 | cfg |= S5P_CIIMGCPT_IMGCPTEN_SC; | ||
339 | |||
340 | writel(cfg | S5P_CIIMGCPT_IMGCPTEN, dev->regs + S5P_CIIMGCPT); | ||
341 | } | ||
342 | |||
343 | void fimc_hw_set_effect(struct fimc_ctx *ctx) | ||
344 | { | ||
345 | struct fimc_dev *dev = ctx->fimc_dev; | ||
346 | struct fimc_effect *effect = &ctx->effect; | ||
347 | u32 cfg = (S5P_CIIMGEFF_IE_ENABLE | S5P_CIIMGEFF_IE_SC_AFTER); | ||
348 | |||
349 | cfg |= effect->type; | ||
350 | |||
351 | if (effect->type == S5P_FIMC_EFFECT_ARBITRARY) { | ||
352 | cfg |= S5P_CIIMGEFF_PAT_CB(effect->pat_cb); | ||
353 | cfg |= S5P_CIIMGEFF_PAT_CR(effect->pat_cr); | ||
354 | } | ||
355 | |||
356 | writel(cfg, dev->regs + S5P_CIIMGEFF); | ||
357 | } | ||
358 | |||
359 | static void fimc_hw_set_in_dma_size(struct fimc_ctx *ctx) | ||
360 | { | ||
361 | struct fimc_dev *dev = ctx->fimc_dev; | ||
362 | struct fimc_frame *frame = &ctx->s_frame; | ||
363 | u32 cfg_o = 0; | ||
364 | u32 cfg_r = 0; | ||
365 | |||
366 | if (FIMC_LCDFIFO == ctx->out_path) | ||
367 | cfg_r |= S5P_CIREAL_ISIZE_AUTOLOAD_EN; | ||
368 | |||
369 | cfg_o |= S5P_ORIG_SIZE_HOR(frame->f_width); | ||
370 | cfg_o |= S5P_ORIG_SIZE_VER(frame->f_height); | ||
371 | cfg_r |= S5P_CIREAL_ISIZE_WIDTH(frame->width); | ||
372 | cfg_r |= S5P_CIREAL_ISIZE_HEIGHT(frame->height); | ||
373 | |||
374 | writel(cfg_o, dev->regs + S5P_ORGISIZE); | ||
375 | writel(cfg_r, dev->regs + S5P_CIREAL_ISIZE); | ||
376 | } | ||
377 | |||
378 | void fimc_hw_set_in_dma(struct fimc_ctx *ctx) | ||
379 | { | ||
380 | struct fimc_dev *dev = ctx->fimc_dev; | ||
381 | struct fimc_frame *frame = &ctx->s_frame; | ||
382 | struct fimc_dma_offset *offset = &frame->dma_offset; | ||
383 | u32 cfg = 0; | ||
384 | |||
385 | /* Set the pixel offsets. */ | ||
386 | cfg |= S5P_CIO_OFFS_HOR(offset->y_h); | ||
387 | cfg |= S5P_CIO_OFFS_VER(offset->y_v); | ||
388 | writel(cfg, dev->regs + S5P_CIIYOFF); | ||
389 | |||
390 | cfg = 0; | ||
391 | cfg |= S5P_CIO_OFFS_HOR(offset->cb_h); | ||
392 | cfg |= S5P_CIO_OFFS_VER(offset->cb_v); | ||
393 | writel(cfg, dev->regs + S5P_CIICBOFF); | ||
394 | |||
395 | cfg = 0; | ||
396 | cfg |= S5P_CIO_OFFS_HOR(offset->cr_h); | ||
397 | cfg |= S5P_CIO_OFFS_VER(offset->cr_v); | ||
398 | writel(cfg, dev->regs + S5P_CIICROFF); | ||
399 | |||
400 | /* Input original and real size. */ | ||
401 | fimc_hw_set_in_dma_size(ctx); | ||
402 | |||
403 | /* Autoload is used currently only in FIFO mode. */ | ||
404 | fimc_hw_en_autoload(dev, ctx->out_path == FIMC_LCDFIFO); | ||
405 | |||
406 | /* Set the input DMA to process single frame only. */ | ||
407 | cfg = readl(dev->regs + S5P_MSCTRL); | ||
408 | cfg &= ~(S5P_MSCTRL_FLIP_MASK | ||
409 | | S5P_MSCTRL_INFORMAT_MASK | ||
410 | | S5P_MSCTRL_IN_BURST_COUNT_MASK | ||
411 | | S5P_MSCTRL_INPUT_MASK | ||
412 | | S5P_MSCTRL_C_INT_IN_MASK | ||
413 | | S5P_MSCTRL_2P_IN_ORDER_MASK); | ||
414 | |||
415 | cfg |= (S5P_MSCTRL_FRAME_COUNT(1) | S5P_MSCTRL_INPUT_MEMORY); | ||
416 | |||
417 | switch (frame->fmt->color) { | ||
418 | case S5P_FIMC_RGB565: | ||
419 | case S5P_FIMC_RGB666: | ||
420 | case S5P_FIMC_RGB888: | ||
421 | cfg |= S5P_MSCTRL_INFORMAT_RGB; | ||
422 | break; | ||
423 | case S5P_FIMC_YCBCR420: | ||
424 | cfg |= S5P_MSCTRL_INFORMAT_YCBCR420; | ||
425 | |||
426 | if (frame->fmt->planes_cnt == 2) | ||
427 | cfg |= ctx->in_order_2p | S5P_MSCTRL_C_INT_IN_2PLANE; | ||
428 | else | ||
429 | cfg |= S5P_MSCTRL_C_INT_IN_3PLANE; | ||
430 | |||
431 | break; | ||
432 | case S5P_FIMC_YCBYCR422: | ||
433 | case S5P_FIMC_YCRYCB422: | ||
434 | case S5P_FIMC_CBYCRY422: | ||
435 | case S5P_FIMC_CRYCBY422: | ||
436 | if (frame->fmt->planes_cnt == 1) { | ||
437 | cfg |= ctx->in_order_1p | ||
438 | | S5P_MSCTRL_INFORMAT_YCBCR422_1P; | ||
439 | } else { | ||
440 | cfg |= S5P_MSCTRL_INFORMAT_YCBCR422; | ||
441 | |||
442 | if (frame->fmt->planes_cnt == 2) | ||
443 | cfg |= ctx->in_order_2p | ||
444 | | S5P_MSCTRL_C_INT_IN_2PLANE; | ||
445 | else | ||
446 | cfg |= S5P_MSCTRL_C_INT_IN_3PLANE; | ||
447 | } | ||
448 | break; | ||
449 | default: | ||
450 | break; | ||
451 | } | ||
452 | |||
453 | /* | ||
454 | * Input DMA flip mode (and rotation). | ||
455 | * Do not allow simultaneous rotation and flipping. | ||
456 | */ | ||
457 | if (!ctx->rotation && ctx->out_path == FIMC_LCDFIFO) | ||
458 | cfg |= fimc_hw_get_in_flip(ctx->flip); | ||
459 | |||
460 | writel(cfg, dev->regs + S5P_MSCTRL); | ||
461 | |||
462 | /* Input/output DMA linear/tiled mode. */ | ||
463 | cfg = readl(dev->regs + S5P_CIDMAPARAM); | ||
464 | cfg &= ~S5P_CIDMAPARAM_TILE_MASK; | ||
465 | |||
466 | if (tiled_fmt(ctx->s_frame.fmt)) | ||
467 | cfg |= S5P_CIDMAPARAM_R_64X32; | ||
468 | |||
469 | if (tiled_fmt(ctx->d_frame.fmt)) | ||
470 | cfg |= S5P_CIDMAPARAM_W_64X32; | ||
471 | |||
472 | writel(cfg, dev->regs + S5P_CIDMAPARAM); | ||
473 | } | ||
474 | |||
475 | |||
476 | void fimc_hw_set_input_path(struct fimc_ctx *ctx) | ||
477 | { | ||
478 | struct fimc_dev *dev = ctx->fimc_dev; | ||
479 | |||
480 | u32 cfg = readl(dev->regs + S5P_MSCTRL); | ||
481 | cfg &= ~S5P_MSCTRL_INPUT_MASK; | ||
482 | |||
483 | if (ctx->in_path == FIMC_DMA) | ||
484 | cfg |= S5P_MSCTRL_INPUT_MEMORY; | ||
485 | else | ||
486 | cfg |= S5P_MSCTRL_INPUT_EXTCAM; | ||
487 | |||
488 | writel(cfg, dev->regs + S5P_MSCTRL); | ||
489 | } | ||
490 | |||
491 | void fimc_hw_set_output_path(struct fimc_ctx *ctx) | ||
492 | { | ||
493 | struct fimc_dev *dev = ctx->fimc_dev; | ||
494 | |||
495 | u32 cfg = readl(dev->regs + S5P_CISCCTRL); | ||
496 | cfg &= ~S5P_CISCCTRL_LCDPATHEN_FIFO; | ||
497 | if (ctx->out_path == FIMC_LCDFIFO) | ||
498 | cfg |= S5P_CISCCTRL_LCDPATHEN_FIFO; | ||
499 | writel(cfg, dev->regs + S5P_CISCCTRL); | ||
500 | } | ||
501 | |||
502 | void fimc_hw_set_input_addr(struct fimc_dev *dev, struct fimc_addr *paddr) | ||
503 | { | ||
504 | u32 cfg = 0; | ||
505 | |||
506 | cfg = readl(dev->regs + S5P_CIREAL_ISIZE); | ||
507 | cfg |= S5P_CIREAL_ISIZE_ADDR_CH_DIS; | ||
508 | writel(cfg, dev->regs + S5P_CIREAL_ISIZE); | ||
509 | |||
510 | writel(paddr->y, dev->regs + S5P_CIIYSA0); | ||
511 | writel(paddr->cb, dev->regs + S5P_CIICBSA0); | ||
512 | writel(paddr->cr, dev->regs + S5P_CIICRSA0); | ||
513 | |||
514 | cfg &= ~S5P_CIREAL_ISIZE_ADDR_CH_DIS; | ||
515 | writel(cfg, dev->regs + S5P_CIREAL_ISIZE); | ||
516 | } | ||
517 | |||
518 | void fimc_hw_set_output_addr(struct fimc_dev *dev, struct fimc_addr *paddr) | ||
519 | { | ||
520 | int i; | ||
521 | /* Set all the output register sets to point to single video buffer. */ | ||
522 | for (i = 0; i < FIMC_MAX_OUT_BUFS; i++) { | ||
523 | writel(paddr->y, dev->regs + S5P_CIOYSA(i)); | ||
524 | writel(paddr->cb, dev->regs + S5P_CIOCBSA(i)); | ||
525 | writel(paddr->cr, dev->regs + S5P_CIOCRSA(i)); | ||
526 | } | ||
527 | } | ||