aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/s5p-fimc/fimc-reg.c
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2010-10-08 04:01:22 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-10-21 05:55:45 -0400
commit47654df8a925ea4f6660b357cbd4ef2ead50c6ad (patch)
tree53e0ded9f86c14c970a84276a3aebd8ea7b504f7 /drivers/media/video/s5p-fimc/fimc-reg.c
parent548aafcd9e73b14fd959ec3689d1551bf7f388d3 (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/media/video/s5p-fimc/fimc-reg.c')
-rw-r--r--drivers/media/video/s5p-fimc/fimc-reg.c101
1 files changed, 50 insertions, 51 deletions
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
40void 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
77static u32 fimc_hw_get_in_flip(u32 ctx_flip) 39static 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
79void 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
117void fimc_hw_set_target_format(struct fimc_ctx *ctx) 119void 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