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); | |
548aafcd | 32 | udelay(1000); |
5fd8f738 SN |
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 | ||
548aafcd | 250 | static void fimc_hw_set_prescaler(struct fimc_ctx *ctx) |
5fd8f738 SN |
251 | { |
252 | struct fimc_dev *dev = ctx->fimc_dev; | |
253 | struct fimc_scaler *sc = &ctx->scaler; | |
548aafcd | 254 | u32 cfg, shfactor; |
5fd8f738 SN |
255 | |
256 | shfactor = 10 - (sc->hfactor + sc->vfactor); | |
257 | ||
548aafcd | 258 | cfg = S5P_CISCPRERATIO_SHFACTOR(shfactor); |
5fd8f738 SN |
259 | cfg |= S5P_CISCPRERATIO_HOR(sc->pre_hratio); |
260 | cfg |= S5P_CISCPRERATIO_VER(sc->pre_vratio); | |
261 | writel(cfg, dev->regs + S5P_CISCPRERATIO); | |
262 | ||
548aafcd | 263 | cfg = S5P_CISCPREDST_WIDTH(sc->pre_dst_width); |
5fd8f738 SN |
264 | cfg |= S5P_CISCPREDST_HEIGHT(sc->pre_dst_height); |
265 | writel(cfg, dev->regs + S5P_CISCPREDST); | |
266 | } | |
267 | ||
268 | void fimc_hw_set_scaler(struct fimc_ctx *ctx) | |
269 | { | |
270 | struct fimc_dev *dev = ctx->fimc_dev; | |
271 | struct fimc_scaler *sc = &ctx->scaler; | |
272 | struct fimc_frame *src_frame = &ctx->s_frame; | |
273 | struct fimc_frame *dst_frame = &ctx->d_frame; | |
274 | u32 cfg = 0; | |
275 | ||
548aafcd SN |
276 | fimc_hw_set_prescaler(ctx); |
277 | ||
5fd8f738 SN |
278 | if (!(ctx->flags & FIMC_COLOR_RANGE_NARROW)) |
279 | cfg |= (S5P_CISCCTRL_CSCR2Y_WIDE | S5P_CISCCTRL_CSCY2R_WIDE); | |
280 | ||
281 | if (!sc->enabled) | |
282 | cfg |= S5P_CISCCTRL_SCALERBYPASS; | |
283 | ||
284 | if (sc->scaleup_h) | |
285 | cfg |= S5P_CISCCTRL_SCALEUP_H; | |
286 | ||
287 | if (sc->scaleup_v) | |
288 | cfg |= S5P_CISCCTRL_SCALEUP_V; | |
289 | ||
290 | if (sc->copy_mode) | |
291 | cfg |= S5P_CISCCTRL_ONE2ONE; | |
292 | ||
293 | ||
294 | if (ctx->in_path == FIMC_DMA) { | |
295 | if (src_frame->fmt->color == S5P_FIMC_RGB565) | |
296 | cfg |= S5P_CISCCTRL_INRGB_FMT_RGB565; | |
297 | else if (src_frame->fmt->color == S5P_FIMC_RGB666) | |
298 | cfg |= S5P_CISCCTRL_INRGB_FMT_RGB666; | |
299 | else if (src_frame->fmt->color == S5P_FIMC_RGB888) | |
300 | cfg |= S5P_CISCCTRL_INRGB_FMT_RGB888; | |
301 | } | |
302 | ||
303 | if (ctx->out_path == FIMC_DMA) { | |
304 | if (dst_frame->fmt->color == S5P_FIMC_RGB565) | |
305 | cfg |= S5P_CISCCTRL_OUTRGB_FMT_RGB565; | |
306 | else if (dst_frame->fmt->color == S5P_FIMC_RGB666) | |
307 | cfg |= S5P_CISCCTRL_OUTRGB_FMT_RGB666; | |
308 | else if (dst_frame->fmt->color == S5P_FIMC_RGB888) | |
309 | cfg |= S5P_CISCCTRL_OUTRGB_FMT_RGB888; | |
310 | } else { | |
311 | cfg |= S5P_CISCCTRL_OUTRGB_FMT_RGB888; | |
312 | ||
313 | if (ctx->flags & FIMC_SCAN_MODE_INTERLACED) | |
314 | cfg |= S5P_CISCCTRL_INTERLACE; | |
315 | } | |
316 | ||
317 | dbg("main_hratio= 0x%X main_vratio= 0x%X", | |
318 | sc->main_hratio, sc->main_vratio); | |
319 | ||
320 | cfg |= S5P_CISCCTRL_SC_HORRATIO(sc->main_hratio); | |
321 | cfg |= S5P_CISCCTRL_SC_VERRATIO(sc->main_vratio); | |
322 | ||
323 | writel(cfg, dev->regs + S5P_CISCCTRL); | |
324 | } | |
325 | ||
326 | void fimc_hw_en_capture(struct fimc_ctx *ctx) | |
327 | { | |
328 | struct fimc_dev *dev = ctx->fimc_dev; | |
329 | u32 cfg; | |
330 | ||
331 | cfg = readl(dev->regs + S5P_CIIMGCPT); | |
332 | /* One shot mode for output DMA or freerun for FIFO. */ | |
333 | if (ctx->out_path == FIMC_DMA) | |
334 | cfg |= S5P_CIIMGCPT_CPT_FREN_ENABLE; | |
335 | else | |
336 | cfg &= ~S5P_CIIMGCPT_CPT_FREN_ENABLE; | |
337 | ||
338 | if (ctx->scaler.enabled) | |
339 | cfg |= S5P_CIIMGCPT_IMGCPTEN_SC; | |
340 | ||
341 | writel(cfg | S5P_CIIMGCPT_IMGCPTEN, dev->regs + S5P_CIIMGCPT); | |
342 | } | |
343 | ||
344 | void fimc_hw_set_effect(struct fimc_ctx *ctx) | |
345 | { | |
346 | struct fimc_dev *dev = ctx->fimc_dev; | |
347 | struct fimc_effect *effect = &ctx->effect; | |
348 | u32 cfg = (S5P_CIIMGEFF_IE_ENABLE | S5P_CIIMGEFF_IE_SC_AFTER); | |
349 | ||
350 | cfg |= effect->type; | |
351 | ||
352 | if (effect->type == S5P_FIMC_EFFECT_ARBITRARY) { | |
353 | cfg |= S5P_CIIMGEFF_PAT_CB(effect->pat_cb); | |
354 | cfg |= S5P_CIIMGEFF_PAT_CR(effect->pat_cr); | |
355 | } | |
356 | ||
357 | writel(cfg, dev->regs + S5P_CIIMGEFF); | |
358 | } | |
359 | ||
360 | static void fimc_hw_set_in_dma_size(struct fimc_ctx *ctx) | |
361 | { | |
362 | struct fimc_dev *dev = ctx->fimc_dev; | |
363 | struct fimc_frame *frame = &ctx->s_frame; | |
364 | u32 cfg_o = 0; | |
365 | u32 cfg_r = 0; | |
366 | ||
367 | if (FIMC_LCDFIFO == ctx->out_path) | |
548aafcd | 368 | cfg_r |= S5P_CIREAL_ISIZE_AUTOLOAD_EN; |
5fd8f738 SN |
369 | |
370 | cfg_o |= S5P_ORIG_SIZE_HOR(frame->f_width); | |
371 | cfg_o |= S5P_ORIG_SIZE_VER(frame->f_height); | |
372 | cfg_r |= S5P_CIREAL_ISIZE_WIDTH(frame->width); | |
373 | cfg_r |= S5P_CIREAL_ISIZE_HEIGHT(frame->height); | |
374 | ||
375 | writel(cfg_o, dev->regs + S5P_ORGISIZE); | |
376 | writel(cfg_r, dev->regs + S5P_CIREAL_ISIZE); | |
377 | } | |
378 | ||
379 | void fimc_hw_set_in_dma(struct fimc_ctx *ctx) | |
380 | { | |
381 | struct fimc_dev *dev = ctx->fimc_dev; | |
382 | struct fimc_frame *frame = &ctx->s_frame; | |
383 | struct fimc_dma_offset *offset = &frame->dma_offset; | |
548aafcd | 384 | u32 cfg; |
5fd8f738 SN |
385 | |
386 | /* Set the pixel offsets. */ | |
548aafcd | 387 | cfg = S5P_CIO_OFFS_HOR(offset->y_h); |
5fd8f738 SN |
388 | cfg |= S5P_CIO_OFFS_VER(offset->y_v); |
389 | writel(cfg, dev->regs + S5P_CIIYOFF); | |
390 | ||
548aafcd | 391 | cfg = S5P_CIO_OFFS_HOR(offset->cb_h); |
5fd8f738 SN |
392 | cfg |= S5P_CIO_OFFS_VER(offset->cb_v); |
393 | writel(cfg, dev->regs + S5P_CIICBOFF); | |
394 | ||
548aafcd | 395 | cfg = S5P_CIO_OFFS_HOR(offset->cr_h); |
5fd8f738 SN |
396 | cfg |= S5P_CIO_OFFS_VER(offset->cr_v); |
397 | writel(cfg, dev->regs + S5P_CIICROFF); | |
398 | ||
399 | /* Input original and real size. */ | |
400 | fimc_hw_set_in_dma_size(ctx); | |
401 | ||
548aafcd | 402 | /* Use DMA autoload only in FIFO mode. */ |
5fd8f738 SN |
403 | fimc_hw_en_autoload(dev, ctx->out_path == FIMC_LCDFIFO); |
404 | ||
405 | /* Set the input DMA to process single frame only. */ | |
406 | cfg = readl(dev->regs + S5P_MSCTRL); | |
407 | cfg &= ~(S5P_MSCTRL_FLIP_MASK | |
408 | | S5P_MSCTRL_INFORMAT_MASK | |
409 | | S5P_MSCTRL_IN_BURST_COUNT_MASK | |
410 | | S5P_MSCTRL_INPUT_MASK | |
411 | | S5P_MSCTRL_C_INT_IN_MASK | |
412 | | S5P_MSCTRL_2P_IN_ORDER_MASK); | |
413 | ||
414 | cfg |= (S5P_MSCTRL_FRAME_COUNT(1) | S5P_MSCTRL_INPUT_MEMORY); | |
415 | ||
416 | switch (frame->fmt->color) { | |
417 | case S5P_FIMC_RGB565: | |
418 | case S5P_FIMC_RGB666: | |
419 | case S5P_FIMC_RGB888: | |
420 | cfg |= S5P_MSCTRL_INFORMAT_RGB; | |
421 | break; | |
422 | case S5P_FIMC_YCBCR420: | |
423 | cfg |= S5P_MSCTRL_INFORMAT_YCBCR420; | |
424 | ||
425 | if (frame->fmt->planes_cnt == 2) | |
426 | cfg |= ctx->in_order_2p | S5P_MSCTRL_C_INT_IN_2PLANE; | |
427 | else | |
428 | cfg |= S5P_MSCTRL_C_INT_IN_3PLANE; | |
429 | ||
430 | break; | |
431 | case S5P_FIMC_YCBYCR422: | |
432 | case S5P_FIMC_YCRYCB422: | |
433 | case S5P_FIMC_CBYCRY422: | |
434 | case S5P_FIMC_CRYCBY422: | |
435 | if (frame->fmt->planes_cnt == 1) { | |
436 | cfg |= ctx->in_order_1p | |
437 | | S5P_MSCTRL_INFORMAT_YCBCR422_1P; | |
438 | } else { | |
439 | cfg |= S5P_MSCTRL_INFORMAT_YCBCR422; | |
440 | ||
441 | if (frame->fmt->planes_cnt == 2) | |
442 | cfg |= ctx->in_order_2p | |
443 | | S5P_MSCTRL_C_INT_IN_2PLANE; | |
444 | else | |
445 | cfg |= S5P_MSCTRL_C_INT_IN_3PLANE; | |
446 | } | |
447 | break; | |
448 | default: | |
449 | break; | |
450 | } | |
451 | ||
452 | /* | |
453 | * Input DMA flip mode (and rotation). | |
454 | * Do not allow simultaneous rotation and flipping. | |
455 | */ | |
456 | if (!ctx->rotation && ctx->out_path == FIMC_LCDFIFO) | |
457 | cfg |= fimc_hw_get_in_flip(ctx->flip); | |
458 | ||
459 | writel(cfg, dev->regs + S5P_MSCTRL); | |
460 | ||
461 | /* Input/output DMA linear/tiled mode. */ | |
462 | cfg = readl(dev->regs + S5P_CIDMAPARAM); | |
463 | cfg &= ~S5P_CIDMAPARAM_TILE_MASK; | |
464 | ||
465 | if (tiled_fmt(ctx->s_frame.fmt)) | |
466 | cfg |= S5P_CIDMAPARAM_R_64X32; | |
467 | ||
468 | if (tiled_fmt(ctx->d_frame.fmt)) | |
469 | cfg |= S5P_CIDMAPARAM_W_64X32; | |
470 | ||
471 | writel(cfg, dev->regs + S5P_CIDMAPARAM); | |
472 | } | |
473 | ||
474 | ||
475 | void fimc_hw_set_input_path(struct fimc_ctx *ctx) | |
476 | { | |
477 | struct fimc_dev *dev = ctx->fimc_dev; | |
478 | ||
479 | u32 cfg = readl(dev->regs + S5P_MSCTRL); | |
480 | cfg &= ~S5P_MSCTRL_INPUT_MASK; | |
481 | ||
482 | if (ctx->in_path == FIMC_DMA) | |
483 | cfg |= S5P_MSCTRL_INPUT_MEMORY; | |
484 | else | |
485 | cfg |= S5P_MSCTRL_INPUT_EXTCAM; | |
486 | ||
487 | writel(cfg, dev->regs + S5P_MSCTRL); | |
488 | } | |
489 | ||
490 | void fimc_hw_set_output_path(struct fimc_ctx *ctx) | |
491 | { | |
492 | struct fimc_dev *dev = ctx->fimc_dev; | |
493 | ||
494 | u32 cfg = readl(dev->regs + S5P_CISCCTRL); | |
495 | cfg &= ~S5P_CISCCTRL_LCDPATHEN_FIFO; | |
496 | if (ctx->out_path == FIMC_LCDFIFO) | |
497 | cfg |= S5P_CISCCTRL_LCDPATHEN_FIFO; | |
498 | writel(cfg, dev->regs + S5P_CISCCTRL); | |
499 | } | |
500 | ||
501 | void fimc_hw_set_input_addr(struct fimc_dev *dev, struct fimc_addr *paddr) | |
502 | { | |
548aafcd | 503 | u32 cfg = readl(dev->regs + S5P_CIREAL_ISIZE); |
5fd8f738 SN |
504 | cfg |= S5P_CIREAL_ISIZE_ADDR_CH_DIS; |
505 | writel(cfg, dev->regs + S5P_CIREAL_ISIZE); | |
506 | ||
77e62082 SN |
507 | writel(paddr->y, dev->regs + S5P_CIIYSA(0)); |
508 | writel(paddr->cb, dev->regs + S5P_CIICBSA(0)); | |
509 | writel(paddr->cr, dev->regs + S5P_CIICRSA(0)); | |
5fd8f738 SN |
510 | |
511 | cfg &= ~S5P_CIREAL_ISIZE_ADDR_CH_DIS; | |
512 | writel(cfg, dev->regs + S5P_CIREAL_ISIZE); | |
513 | } | |
514 | ||
548aafcd SN |
515 | void fimc_hw_set_output_addr(struct fimc_dev *dev, |
516 | struct fimc_addr *paddr, int index) | |
5fd8f738 | 517 | { |
548aafcd SN |
518 | int i = (index == -1) ? 0 : index; |
519 | do { | |
5fd8f738 SN |
520 | writel(paddr->y, dev->regs + S5P_CIOYSA(i)); |
521 | writel(paddr->cb, dev->regs + S5P_CIOCBSA(i)); | |
522 | writel(paddr->cr, dev->regs + S5P_CIOCRSA(i)); | |
548aafcd SN |
523 | dbg("dst_buf[%d]: 0x%X, cb: 0x%X, cr: 0x%X", |
524 | i, paddr->y, paddr->cb, paddr->cr); | |
525 | } while (index == -1 && ++i < FIMC_MAX_OUT_BUFS); | |
5fd8f738 | 526 | } |