aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHyunwoong Kim <khw0178.kim@samsung.com>2010-12-28 09:27:13 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-21 19:31:39 -0400
commitb241c6d6f4ceddddfd8097c702dcfdd6b38fbe18 (patch)
tree84ba8792690b4ba2691c3d36ff518b54b4f80844
parent10038bea7a729bcb8c51a2c856f5b58b33646d65 (diff)
[media] s5p-fimc: Configure scaler registers depending on FIMC version
The main scaler has four SFRs for main scaler ratio depending on FIMC version. FIMC 4.x has only two SFRs and FIMC 5.x has four SFRs for main scaler. Those are MainHorRatio, MainHorRatio_ext, MainVerRatio and MainverRatio_ext. The FIMC 5.x has 15 bit resolution for scaling ratio as below. {MainHorRatio,MainHorRatio_ext} = {[14:6],[5:0]}. {MainVerRatio,MainVerRatio_ext} = {[14:6],[5:0]}. MainHorRatio = CISCCTRL[24:16], MainHorRatio_ext = CIEXTEN[15:10] MainVerRatio = CISCCTRL[8:0], MainVerRatio_ext = CIEXTEN[5:0] This patch supports FIMC 4.x and FIMC 5.x using platform_device_id::driver_data. Reviewed-by: Jonghun Han <jonghun.han@samsung.com> Signed-off-by: Hyunwoong Kim <khw0178.kim@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/s5p-fimc/fimc-capture.c7
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.c22
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.h7
-rw-r--r--drivers/media/video/s5p-fimc/fimc-reg.c52
-rw-r--r--drivers/media/video/s5p-fimc/regs-fimc.h12
5 files changed, 87 insertions, 13 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c
index 03ddf5d6164f..91304eef812b 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -237,6 +237,7 @@ static int start_streaming(struct vb2_queue *q)
237 struct fimc_ctx *ctx = q->drv_priv; 237 struct fimc_ctx *ctx = q->drv_priv;
238 struct fimc_dev *fimc = ctx->fimc_dev; 238 struct fimc_dev *fimc = ctx->fimc_dev;
239 struct s5p_fimc_isp_info *isp_info; 239 struct s5p_fimc_isp_info *isp_info;
240 struct samsung_fimc_variant *variant = ctx->fimc_dev->variant;
240 int ret; 241 int ret;
241 242
242 ret = v4l2_subdev_call(fimc->vid_cap.sd, video, s_stream, 1); 243 ret = v4l2_subdev_call(fimc->vid_cap.sd, video, s_stream, 1);
@@ -259,7 +260,11 @@ static int start_streaming(struct vb2_queue *q)
259 return ret; 260 return ret;
260 } 261 }
261 fimc_hw_set_input_path(ctx); 262 fimc_hw_set_input_path(ctx);
262 fimc_hw_set_scaler(ctx); 263 fimc_hw_set_prescaler(ctx);
264 if (variant->has_mainscaler_ext)
265 fimc_hw_set_mainscaler_ext(ctx);
266 else
267 fimc_hw_set_mainscaler(ctx);
263 fimc_hw_set_target_format(ctx); 268 fimc_hw_set_target_format(ctx);
264 fimc_hw_set_rotation(ctx); 269 fimc_hw_set_rotation(ctx);
265 fimc_hw_set_effect(ctx); 270 fimc_hw_set_effect(ctx);
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c
index 70d6b4c9760f..59fa5126fc2d 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.c
+++ b/drivers/media/video/s5p-fimc/fimc-core.c
@@ -248,6 +248,7 @@ int fimc_set_scaler_info(struct fimc_ctx *ctx)
248 struct fimc_scaler *sc = &ctx->scaler; 248 struct fimc_scaler *sc = &ctx->scaler;
249 struct fimc_frame *s_frame = &ctx->s_frame; 249 struct fimc_frame *s_frame = &ctx->s_frame;
250 struct fimc_frame *d_frame = &ctx->d_frame; 250 struct fimc_frame *d_frame = &ctx->d_frame;
251 struct samsung_fimc_variant *variant = ctx->fimc_dev->variant;
251 int tx, ty, sx, sy; 252 int tx, ty, sx, sy;
252 int ret; 253 int ret;
253 254
@@ -286,8 +287,14 @@ int fimc_set_scaler_info(struct fimc_ctx *ctx)
286 sc->pre_dst_width = sx / sc->pre_hratio; 287 sc->pre_dst_width = sx / sc->pre_hratio;
287 sc->pre_dst_height = sy / sc->pre_vratio; 288 sc->pre_dst_height = sy / sc->pre_vratio;
288 289
289 sc->main_hratio = (sx << 8) / (tx << sc->hfactor); 290 if (variant->has_mainscaler_ext) {
290 sc->main_vratio = (sy << 8) / (ty << sc->vfactor); 291 sc->main_hratio = (sx << 14) / (tx << sc->hfactor);
292 sc->main_vratio = (sy << 14) / (ty << sc->vfactor);
293 } else {
294 sc->main_hratio = (sx << 8) / (tx << sc->hfactor);
295 sc->main_vratio = (sy << 8) / (ty << sc->vfactor);
296
297 }
291 298
292 sc->scaleup_h = (tx >= sx) ? 1 : 0; 299 sc->scaleup_h = (tx >= sx) ? 1 : 0;
293 sc->scaleup_v = (ty >= sy) ? 1 : 0; 300 sc->scaleup_v = (ty >= sy) ? 1 : 0;
@@ -571,6 +578,7 @@ static void fimc_dma_run(void *priv)
571{ 578{
572 struct fimc_ctx *ctx = priv; 579 struct fimc_ctx *ctx = priv;
573 struct fimc_dev *fimc; 580 struct fimc_dev *fimc;
581 struct samsung_fimc_variant *variant = ctx->fimc_dev->variant;
574 unsigned long flags; 582 unsigned long flags;
575 u32 ret; 583 u32 ret;
576 584
@@ -603,7 +611,12 @@ static void fimc_dma_run(void *priv)
603 err("Scaler setup error"); 611 err("Scaler setup error");
604 goto dma_unlock; 612 goto dma_unlock;
605 } 613 }
606 fimc_hw_set_scaler(ctx); 614
615 fimc_hw_set_prescaler(ctx);
616 if (variant->has_mainscaler_ext)
617 fimc_hw_set_mainscaler_ext(ctx);
618 else
619 fimc_hw_set_mainscaler(ctx);
607 fimc_hw_set_target_format(ctx); 620 fimc_hw_set_target_format(ctx);
608 fimc_hw_set_rotation(ctx); 621 fimc_hw_set_rotation(ctx);
609 fimc_hw_set_effect(ctx); 622 fimc_hw_set_effect(ctx);
@@ -1730,6 +1743,7 @@ static struct samsung_fimc_variant fimc1_variant_s5pv210 = {
1730 .pix_hoff = 1, 1743 .pix_hoff = 1,
1731 .has_inp_rot = 1, 1744 .has_inp_rot = 1,
1732 .has_out_rot = 1, 1745 .has_out_rot = 1,
1746 .has_mainscaler_ext = 1,
1733 .min_inp_pixsize = 16, 1747 .min_inp_pixsize = 16,
1734 .min_out_pixsize = 16, 1748 .min_out_pixsize = 16,
1735 .hor_offs_align = 1, 1749 .hor_offs_align = 1,
@@ -1751,6 +1765,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = {
1751 .has_inp_rot = 1, 1765 .has_inp_rot = 1,
1752 .has_out_rot = 1, 1766 .has_out_rot = 1,
1753 .has_cistatus2 = 1, 1767 .has_cistatus2 = 1,
1768 .has_mainscaler_ext = 1,
1754 .min_inp_pixsize = 16, 1769 .min_inp_pixsize = 16,
1755 .min_out_pixsize = 16, 1770 .min_out_pixsize = 16,
1756 .hor_offs_align = 1, 1771 .hor_offs_align = 1,
@@ -1761,6 +1776,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = {
1761static struct samsung_fimc_variant fimc2_variant_s5pv310 = { 1776static struct samsung_fimc_variant fimc2_variant_s5pv310 = {
1762 .pix_hoff = 1, 1777 .pix_hoff = 1,
1763 .has_cistatus2 = 1, 1778 .has_cistatus2 = 1,
1779 .has_mainscaler_ext = 1,
1764 .min_inp_pixsize = 16, 1780 .min_inp_pixsize = 16,
1765 .min_out_pixsize = 16, 1781 .min_out_pixsize = 16,
1766 .hor_offs_align = 1, 1782 .hor_offs_align = 1,
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h
index 562d15d7059a..8aee9e3207f9 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.h
+++ b/drivers/media/video/s5p-fimc/fimc-core.h
@@ -361,6 +361,8 @@ struct fimc_pix_limit {
361 * @has_inp_rot: set if has input rotator 361 * @has_inp_rot: set if has input rotator
362 * @has_out_rot: set if has output rotator 362 * @has_out_rot: set if has output rotator
363 * @has_cistatus2: 1 if CISTATUS2 register is present in this IP revision 363 * @has_cistatus2: 1 if CISTATUS2 register is present in this IP revision
364 * @has_mainscaler_ext: 1 if extended mainscaler ratios in CIEXTEN register
365 * are present in this IP revision
364 * @pix_limit: pixel size constraints for the scaler 366 * @pix_limit: pixel size constraints for the scaler
365 * @min_inp_pixsize: minimum input pixel size 367 * @min_inp_pixsize: minimum input pixel size
366 * @min_out_pixsize: minimum output pixel size 368 * @min_out_pixsize: minimum output pixel size
@@ -372,6 +374,7 @@ struct samsung_fimc_variant {
372 unsigned int has_inp_rot:1; 374 unsigned int has_inp_rot:1;
373 unsigned int has_out_rot:1; 375 unsigned int has_out_rot:1;
374 unsigned int has_cistatus2:1; 376 unsigned int has_cistatus2:1;
377 unsigned int has_mainscaler_ext:1;
375 struct fimc_pix_limit *pix_limit; 378 struct fimc_pix_limit *pix_limit;
376 u16 min_inp_pixsize; 379 u16 min_inp_pixsize;
377 u16 min_out_pixsize; 380 u16 min_out_pixsize;
@@ -569,7 +572,9 @@ void fimc_hw_set_target_format(struct fimc_ctx *ctx);
569void fimc_hw_set_out_dma(struct fimc_ctx *ctx); 572void fimc_hw_set_out_dma(struct fimc_ctx *ctx);
570void fimc_hw_en_lastirq(struct fimc_dev *fimc, int enable); 573void fimc_hw_en_lastirq(struct fimc_dev *fimc, int enable);
571void fimc_hw_en_irq(struct fimc_dev *fimc, int enable); 574void fimc_hw_en_irq(struct fimc_dev *fimc, int enable);
572void fimc_hw_set_scaler(struct fimc_ctx *ctx); 575void fimc_hw_set_prescaler(struct fimc_ctx *ctx);
576void fimc_hw_set_mainscaler(struct fimc_ctx *ctx);
577void fimc_hw_set_mainscaler_ext(struct fimc_ctx *ctx);
573void fimc_hw_en_capture(struct fimc_ctx *ctx); 578void fimc_hw_en_capture(struct fimc_ctx *ctx);
574void fimc_hw_set_effect(struct fimc_ctx *ctx); 579void fimc_hw_set_effect(struct fimc_ctx *ctx);
575void fimc_hw_set_in_dma(struct fimc_ctx *ctx); 580void fimc_hw_set_in_dma(struct fimc_ctx *ctx);
diff --git a/drivers/media/video/s5p-fimc/fimc-reg.c b/drivers/media/video/s5p-fimc/fimc-reg.c
index c14c8316ea13..064fa0a8b893 100644
--- a/drivers/media/video/s5p-fimc/fimc-reg.c
+++ b/drivers/media/video/s5p-fimc/fimc-reg.c
@@ -243,7 +243,7 @@ void fimc_hw_en_lastirq(struct fimc_dev *dev, int enable)
243 writel(cfg, dev->regs + S5P_CIOCTRL); 243 writel(cfg, dev->regs + S5P_CIOCTRL);
244} 244}
245 245
246static void fimc_hw_set_prescaler(struct fimc_ctx *ctx) 246void fimc_hw_set_prescaler(struct fimc_ctx *ctx)
247{ 247{
248 struct fimc_dev *dev = ctx->fimc_dev; 248 struct fimc_dev *dev = ctx->fimc_dev;
249 struct fimc_scaler *sc = &ctx->scaler; 249 struct fimc_scaler *sc = &ctx->scaler;
@@ -261,7 +261,7 @@ static void fimc_hw_set_prescaler(struct fimc_ctx *ctx)
261 writel(cfg, dev->regs + S5P_CISCPREDST); 261 writel(cfg, dev->regs + S5P_CISCPREDST);
262} 262}
263 263
264void fimc_hw_set_scaler(struct fimc_ctx *ctx) 264static void fimc_hw_set_scaler(struct fimc_ctx *ctx)
265{ 265{
266 struct fimc_dev *dev = ctx->fimc_dev; 266 struct fimc_dev *dev = ctx->fimc_dev;
267 struct fimc_scaler *sc = &ctx->scaler; 267 struct fimc_scaler *sc = &ctx->scaler;
@@ -269,8 +269,6 @@ void fimc_hw_set_scaler(struct fimc_ctx *ctx)
269 struct fimc_frame *dst_frame = &ctx->d_frame; 269 struct fimc_frame *dst_frame = &ctx->d_frame;
270 u32 cfg = 0; 270 u32 cfg = 0;
271 271
272 fimc_hw_set_prescaler(ctx);
273
274 if (!(ctx->flags & FIMC_COLOR_RANGE_NARROW)) 272 if (!(ctx->flags & FIMC_COLOR_RANGE_NARROW))
275 cfg |= (S5P_CISCCTRL_CSCR2Y_WIDE | S5P_CISCCTRL_CSCY2R_WIDE); 273 cfg |= (S5P_CISCCTRL_CSCR2Y_WIDE | S5P_CISCCTRL_CSCY2R_WIDE);
276 274
@@ -310,13 +308,55 @@ void fimc_hw_set_scaler(struct fimc_ctx *ctx)
310 cfg |= S5P_CISCCTRL_INTERLACE; 308 cfg |= S5P_CISCCTRL_INTERLACE;
311 } 309 }
312 310
311 writel(cfg, dev->regs + S5P_CISCCTRL);
312}
313
314void fimc_hw_set_mainscaler(struct fimc_ctx *ctx)
315{
316 struct fimc_dev *dev = ctx->fimc_dev;
317 struct fimc_scaler *sc = &ctx->scaler;
318 u32 cfg;
319
320 dbg("main_hratio= 0x%X main_vratio= 0x%X",
321 sc->main_hratio, sc->main_vratio);
322
323 fimc_hw_set_scaler(ctx);
324
325 cfg = readl(dev->regs + S5P_CISCCTRL);
326 cfg &= ~S5P_CISCCTRL_MHRATIO_MASK;
327 cfg &= ~S5P_CISCCTRL_MVRATIO_MASK;
328 cfg |= S5P_CISCCTRL_MHRATIO(sc->main_hratio);
329 cfg |= S5P_CISCCTRL_MVRATIO(sc->main_vratio);
330
331 writel(cfg, dev->regs + S5P_CISCCTRL);
332}
333
334void fimc_hw_set_mainscaler_ext(struct fimc_ctx *ctx)
335{
336 struct fimc_dev *dev = ctx->fimc_dev;
337 struct fimc_scaler *sc = &ctx->scaler;
338 u32 cfg, cfg_ext;
339
313 dbg("main_hratio= 0x%X main_vratio= 0x%X", 340 dbg("main_hratio= 0x%X main_vratio= 0x%X",
314 sc->main_hratio, sc->main_vratio); 341 sc->main_hratio, sc->main_vratio);
315 342
316 cfg |= S5P_CISCCTRL_SC_HORRATIO(sc->main_hratio); 343 fimc_hw_set_scaler(ctx);
317 cfg |= S5P_CISCCTRL_SC_VERRATIO(sc->main_vratio); 344
345 cfg = readl(dev->regs + S5P_CISCCTRL);
346 cfg &= ~S5P_CISCCTRL_MHRATIO_MASK;
347 cfg &= ~S5P_CISCCTRL_MVRATIO_MASK;
348 cfg |= S5P_CISCCTRL_MHRATIO_EXT(sc->main_hratio);
349 cfg |= S5P_CISCCTRL_MVRATIO_EXT(sc->main_vratio);
318 350
319 writel(cfg, dev->regs + S5P_CISCCTRL); 351 writel(cfg, dev->regs + S5P_CISCCTRL);
352
353 cfg_ext = readl(dev->regs + S5P_CIEXTEN);
354 cfg_ext &= ~S5P_CIEXTEN_MHRATIO_EXT_MASK;
355 cfg_ext &= ~S5P_CIEXTEN_MVRATIO_EXT_MASK;
356 cfg_ext |= S5P_CIEXTEN_MHRATIO_EXT(sc->main_hratio);
357 cfg_ext |= S5P_CIEXTEN_MVRATIO_EXT(sc->main_vratio);
358
359 writel(cfg_ext, dev->regs + S5P_CIEXTEN);
320} 360}
321 361
322void fimc_hw_en_capture(struct fimc_ctx *ctx) 362void fimc_hw_en_capture(struct fimc_ctx *ctx)
diff --git a/drivers/media/video/s5p-fimc/regs-fimc.h b/drivers/media/video/s5p-fimc/regs-fimc.h
index fe19b4b0fb6a..04669a54a3c2 100644
--- a/drivers/media/video/s5p-fimc/regs-fimc.h
+++ b/drivers/media/video/s5p-fimc/regs-fimc.h
@@ -139,8 +139,12 @@
139#define S5P_CISCCTRL_OUTRGB_FMT_MASK (3 << 11) 139#define S5P_CISCCTRL_OUTRGB_FMT_MASK (3 << 11)
140#define S5P_CISCCTRL_RGB_EXT (1 << 10) 140#define S5P_CISCCTRL_RGB_EXT (1 << 10)
141#define S5P_CISCCTRL_ONE2ONE (1 << 9) 141#define S5P_CISCCTRL_ONE2ONE (1 << 9)
142#define S5P_CISCCTRL_SC_HORRATIO(x) ((x) << 16) 142#define S5P_CISCCTRL_MHRATIO(x) ((x) << 16)
143#define S5P_CISCCTRL_SC_VERRATIO(x) ((x) << 0) 143#define S5P_CISCCTRL_MVRATIO(x) ((x) << 0)
144#define S5P_CISCCTRL_MHRATIO_MASK (0x1ff << 16)
145#define S5P_CISCCTRL_MVRATIO_MASK (0x1ff << 0)
146#define S5P_CISCCTRL_MHRATIO_EXT(x) (((x) >> 6) << 16)
147#define S5P_CISCCTRL_MVRATIO_EXT(x) (((x) >> 6) << 0)
144 148
145/* Target area */ 149/* Target area */
146#define S5P_CITAREA 0x5c 150#define S5P_CITAREA 0x5c
@@ -263,6 +267,10 @@
263 267
264/* Real output DMA image size (extension register) */ 268/* Real output DMA image size (extension register) */
265#define S5P_CIEXTEN 0x188 269#define S5P_CIEXTEN 0x188
270#define S5P_CIEXTEN_MHRATIO_EXT(x) (((x) & 0x3f) << 10)
271#define S5P_CIEXTEN_MVRATIO_EXT(x) ((x) & 0x3f)
272#define S5P_CIEXTEN_MHRATIO_EXT_MASK (0x3f << 10)
273#define S5P_CIEXTEN_MVRATIO_EXT_MASK 0x3f
266 274
267#define S5P_CIDMAPARAM 0x18c 275#define S5P_CIDMAPARAM 0x18c
268#define S5P_CIDMAPARAM_R_LINEAR (0 << 29) 276#define S5P_CIDMAPARAM_R_LINEAR (0 << 29)