Commit | Line | Data |
---|---|---|
5fd8f738 SN |
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 | ||
77e62082 SN |
510 | writel(paddr->y, dev->regs + S5P_CIIYSA(0)); |
511 | writel(paddr->cb, dev->regs + S5P_CIICBSA(0)); | |
512 | writel(paddr->cr, dev->regs + S5P_CIICRSA(0)); | |
5fd8f738 SN |
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 | } |