diff options
author | Sylwester Nawrocki <s.nawrocki@samsung.com> | 2010-10-08 04:01:22 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-10-21 05:55:45 -0400 |
commit | 47654df8a925ea4f6660b357cbd4ef2ead50c6ad (patch) | |
tree | 53e0ded9f86c14c970a84276a3aebd8ea7b504f7 /drivers | |
parent | 548aafcd9e73b14fd959ec3689d1551bf7f388d3 (diff) |
[media] s5p-fimc: Fix 90/270 deg rotation errors
Due to errorneous swapping of image dimensions the rotation
control was not handled properly in subsequent calls.
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-core.c | 15 | ||||
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-reg.c | 101 |
2 files changed, 57 insertions, 59 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index fccab1398425..27379a6c503c 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c | |||
@@ -207,8 +207,13 @@ static int fimc_set_scaler_info(struct fimc_ctx *ctx) | |||
207 | int tx, ty, sx, sy; | 207 | int tx, ty, sx, sy; |
208 | int ret; | 208 | int ret; |
209 | 209 | ||
210 | tx = d_frame->width; | 210 | if (ctx->rotation == 90 || ctx->rotation == 270) { |
211 | ty = d_frame->height; | 211 | ty = d_frame->width; |
212 | tx = d_frame->height; | ||
213 | } else { | ||
214 | tx = d_frame->width; | ||
215 | ty = d_frame->height; | ||
216 | } | ||
212 | if (tx <= 0 || ty <= 0) { | 217 | if (tx <= 0 || ty <= 0) { |
213 | v4l2_err(&ctx->fimc_dev->m2m.v4l2_dev, | 218 | v4l2_err(&ctx->fimc_dev->m2m.v4l2_dev, |
214 | "invalid target size: %d x %d", tx, ty); | 219 | "invalid target size: %d x %d", tx, ty); |
@@ -429,12 +434,6 @@ static int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags) | |||
429 | d_frame = &ctx->d_frame; | 434 | d_frame = &ctx->d_frame; |
430 | 435 | ||
431 | if (flags & FIMC_PARAMS) { | 436 | if (flags & FIMC_PARAMS) { |
432 | if ((ctx->out_path == FIMC_DMA) && | ||
433 | (ctx->rotation == 90 || ctx->rotation == 270)) { | ||
434 | swap(d_frame->f_width, d_frame->f_height); | ||
435 | swap(d_frame->width, d_frame->height); | ||
436 | } | ||
437 | |||
438 | /* Prepare the DMA offset ratios for scaler. */ | 437 | /* Prepare the DMA offset ratios for scaler. */ |
439 | fimc_prepare_dma_offset(ctx, &ctx->s_frame); | 438 | fimc_prepare_dma_offset(ctx, &ctx->s_frame); |
440 | fimc_prepare_dma_offset(ctx, &ctx->d_frame); | 439 | fimc_prepare_dma_offset(ctx, &ctx->d_frame); |
diff --git a/drivers/media/video/s5p-fimc/fimc-reg.c b/drivers/media/video/s5p-fimc/fimc-reg.c index 94e98d47a7d0..95adc8464693 100644 --- a/drivers/media/video/s5p-fimc/fimc-reg.c +++ b/drivers/media/video/s5p-fimc/fimc-reg.c | |||
@@ -34,44 +34,6 @@ void fimc_hw_reset(struct fimc_dev *dev) | |||
34 | cfg = readl(dev->regs + S5P_CIGCTRL); | 34 | cfg = readl(dev->regs + S5P_CIGCTRL); |
35 | cfg &= ~S5P_CIGCTRL_SWRST; | 35 | cfg &= ~S5P_CIGCTRL_SWRST; |
36 | writel(cfg, dev->regs + S5P_CIGCTRL); | 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 | } | 37 | } |
76 | 38 | ||
77 | static u32 fimc_hw_get_in_flip(u32 ctx_flip) | 39 | static u32 fimc_hw_get_in_flip(u32 ctx_flip) |
@@ -114,6 +76,46 @@ static u32 fimc_hw_get_target_flip(u32 ctx_flip) | |||
114 | return flip; | 76 | return flip; |
115 | } | 77 | } |
116 | 78 | ||
79 | void fimc_hw_set_rotation(struct fimc_ctx *ctx) | ||
80 | { | ||
81 | u32 cfg, flip; | ||
82 | struct fimc_dev *dev = ctx->fimc_dev; | ||
83 | |||
84 | cfg = readl(dev->regs + S5P_CITRGFMT); | ||
85 | cfg &= ~(S5P_CITRGFMT_INROT90 | S5P_CITRGFMT_OUTROT90 | | ||
86 | S5P_CITRGFMT_FLIP_180); | ||
87 | |||
88 | flip = readl(dev->regs + S5P_MSCTRL); | ||
89 | flip &= ~S5P_MSCTRL_FLIP_MASK; | ||
90 | |||
91 | /* | ||
92 | * The input and output rotator cannot work simultaneously. | ||
93 | * Use the output rotator in output DMA mode or the input rotator | ||
94 | * in direct fifo output mode. | ||
95 | */ | ||
96 | if (ctx->rotation == 90 || ctx->rotation == 270) { | ||
97 | if (ctx->out_path == FIMC_LCDFIFO) { | ||
98 | cfg |= S5P_CITRGFMT_INROT90; | ||
99 | if (ctx->rotation == 270) | ||
100 | flip |= S5P_MSCTRL_FLIP_180; | ||
101 | } else { | ||
102 | cfg |= S5P_CITRGFMT_OUTROT90; | ||
103 | if (ctx->rotation == 270) | ||
104 | cfg |= S5P_CITRGFMT_FLIP_180; | ||
105 | } | ||
106 | } else if (ctx->rotation == 180) { | ||
107 | if (ctx->out_path == FIMC_LCDFIFO) | ||
108 | flip |= S5P_MSCTRL_FLIP_180; | ||
109 | else | ||
110 | cfg |= S5P_CITRGFMT_FLIP_180; | ||
111 | } | ||
112 | if (ctx->rotation == 180 || ctx->rotation == 270) | ||
113 | writel(flip, dev->regs + S5P_MSCTRL); | ||
114 | |||
115 | cfg |= fimc_hw_get_target_flip(ctx->flip); | ||
116 | writel(cfg, dev->regs + S5P_CITRGFMT); | ||
117 | } | ||
118 | |||
117 | void fimc_hw_set_target_format(struct fimc_ctx *ctx) | 119 | void fimc_hw_set_target_format(struct fimc_ctx *ctx) |
118 | { | 120 | { |
119 | u32 cfg; | 121 | u32 cfg; |
@@ -149,13 +151,15 @@ void fimc_hw_set_target_format(struct fimc_ctx *ctx) | |||
149 | break; | 151 | break; |
150 | } | 152 | } |
151 | 153 | ||
152 | cfg |= S5P_CITRGFMT_HSIZE(frame->width); | 154 | if (ctx->rotation == 90 || ctx->rotation == 270) { |
153 | cfg |= S5P_CITRGFMT_VSIZE(frame->height); | 155 | cfg |= S5P_CITRGFMT_HSIZE(frame->height); |
156 | cfg |= S5P_CITRGFMT_VSIZE(frame->width); | ||
157 | } else { | ||
154 | 158 | ||
155 | if (ctx->rotation == 0) { | 159 | cfg |= S5P_CITRGFMT_HSIZE(frame->width); |
156 | cfg &= ~S5P_CITRGFMT_FLIP_MASK; | 160 | cfg |= S5P_CITRGFMT_VSIZE(frame->height); |
157 | cfg |= fimc_hw_get_target_flip(ctx->flip); | ||
158 | } | 161 | } |
162 | |||
159 | writel(cfg, dev->regs + S5P_CITRGFMT); | 163 | writel(cfg, dev->regs + S5P_CITRGFMT); |
160 | 164 | ||
161 | cfg = readl(dev->regs + S5P_CITAREA) & ~S5P_CITAREA_MASK; | 165 | cfg = readl(dev->regs + S5P_CITAREA) & ~S5P_CITAREA_MASK; |
@@ -167,15 +171,10 @@ static void fimc_hw_set_out_dma_size(struct fimc_ctx *ctx) | |||
167 | { | 171 | { |
168 | struct fimc_dev *dev = ctx->fimc_dev; | 172 | struct fimc_dev *dev = ctx->fimc_dev; |
169 | struct fimc_frame *frame = &ctx->d_frame; | 173 | struct fimc_frame *frame = &ctx->d_frame; |
170 | u32 cfg = 0; | 174 | u32 cfg; |
171 | 175 | ||
172 | if (ctx->rotation == 90 || ctx->rotation == 270) { | 176 | cfg = S5P_ORIG_SIZE_HOR(frame->f_width); |
173 | cfg |= S5P_ORIG_SIZE_HOR(frame->f_height); | 177 | cfg |= S5P_ORIG_SIZE_VER(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); | 178 | writel(cfg, dev->regs + S5P_ORGOSIZE); |
180 | } | 179 | } |
181 | 180 | ||