aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.c9
-rw-r--r--drivers/media/video/s5p-fimc/fimc-reg.c74
2 files changed, 31 insertions, 52 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c
index 9ebb92530053..b8d59f44a088 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.c
+++ b/drivers/media/video/s5p-fimc/fimc-core.c
@@ -1055,13 +1055,6 @@ int fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_control *ctrl)
1055 struct fimc_dev *fimc = ctx->fimc_dev; 1055 struct fimc_dev *fimc = ctx->fimc_dev;
1056 unsigned long flags; 1056 unsigned long flags;
1057 1057
1058 if (ctx->rotation != 0 &&
1059 (ctrl->id == V4L2_CID_HFLIP || ctrl->id == V4L2_CID_VFLIP)) {
1060 v4l2_err(&fimc->m2m.v4l2_dev,
1061 "Simultaneous flip and rotation is not supported\n");
1062 return -EINVAL;
1063 }
1064
1065 spin_lock_irqsave(&ctx->slock, flags); 1058 spin_lock_irqsave(&ctx->slock, flags);
1066 1059
1067 switch (ctrl->id) { 1060 switch (ctrl->id) {
@@ -1102,7 +1095,7 @@ int fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_control *ctrl)
1102} 1095}
1103 1096
1104static int fimc_m2m_s_ctrl(struct file *file, void *priv, 1097static int fimc_m2m_s_ctrl(struct file *file, void *priv,
1105 struct v4l2_control *ctrl) 1098 struct v4l2_control *ctrl)
1106{ 1099{
1107 struct fimc_ctx *ctx = priv; 1100 struct fimc_ctx *ctx = priv;
1108 int ret = 0; 1101 int ret = 0;
diff --git a/drivers/media/video/s5p-fimc/fimc-reg.c b/drivers/media/video/s5p-fimc/fimc-reg.c
index c4703b5800c4..c14c8316ea13 100644
--- a/drivers/media/video/s5p-fimc/fimc-reg.c
+++ b/drivers/media/video/s5p-fimc/fimc-reg.c
@@ -37,11 +37,11 @@ void fimc_hw_reset(struct fimc_dev *dev)
37 writel(cfg, dev->regs + S5P_CIGCTRL); 37 writel(cfg, dev->regs + S5P_CIGCTRL);
38} 38}
39 39
40static u32 fimc_hw_get_in_flip(u32 ctx_flip) 40static u32 fimc_hw_get_in_flip(struct fimc_ctx *ctx)
41{ 41{
42 u32 flip = S5P_MSCTRL_FLIP_NORMAL; 42 u32 flip = S5P_MSCTRL_FLIP_NORMAL;
43 43
44 switch (ctx_flip) { 44 switch (ctx->flip) {
45 case FLIP_X_AXIS: 45 case FLIP_X_AXIS:
46 flip = S5P_MSCTRL_FLIP_X_MIRROR; 46 flip = S5P_MSCTRL_FLIP_X_MIRROR;
47 break; 47 break;
@@ -51,16 +51,20 @@ static u32 fimc_hw_get_in_flip(u32 ctx_flip)
51 case FLIP_XY_AXIS: 51 case FLIP_XY_AXIS:
52 flip = S5P_MSCTRL_FLIP_180; 52 flip = S5P_MSCTRL_FLIP_180;
53 break; 53 break;
54 default:
55 break;
54 } 56 }
57 if (ctx->rotation <= 90)
58 return flip;
55 59
56 return flip; 60 return (flip ^ S5P_MSCTRL_FLIP_180) & S5P_MSCTRL_FLIP_180;
57} 61}
58 62
59static u32 fimc_hw_get_target_flip(u32 ctx_flip) 63static u32 fimc_hw_get_target_flip(struct fimc_ctx *ctx)
60{ 64{
61 u32 flip = S5P_CITRGFMT_FLIP_NORMAL; 65 u32 flip = S5P_CITRGFMT_FLIP_NORMAL;
62 66
63 switch (ctx_flip) { 67 switch (ctx->flip) {
64 case FLIP_X_AXIS: 68 case FLIP_X_AXIS:
65 flip = S5P_CITRGFMT_FLIP_X_MIRROR; 69 flip = S5P_CITRGFMT_FLIP_X_MIRROR;
66 break; 70 break;
@@ -70,11 +74,13 @@ static u32 fimc_hw_get_target_flip(u32 ctx_flip)
70 case FLIP_XY_AXIS: 74 case FLIP_XY_AXIS:
71 flip = S5P_CITRGFMT_FLIP_180; 75 flip = S5P_CITRGFMT_FLIP_180;
72 break; 76 break;
73 case FLIP_NONE: 77 default:
74 break; 78 break;
75
76 } 79 }
77 return flip; 80 if (ctx->rotation <= 90)
81 return flip;
82
83 return (flip ^ S5P_CITRGFMT_FLIP_180) & S5P_CITRGFMT_FLIP_180;
78} 84}
79 85
80void fimc_hw_set_rotation(struct fimc_ctx *ctx) 86void fimc_hw_set_rotation(struct fimc_ctx *ctx)
@@ -84,10 +90,7 @@ void fimc_hw_set_rotation(struct fimc_ctx *ctx)
84 90
85 cfg = readl(dev->regs + S5P_CITRGFMT); 91 cfg = readl(dev->regs + S5P_CITRGFMT);
86 cfg &= ~(S5P_CITRGFMT_INROT90 | S5P_CITRGFMT_OUTROT90 | 92 cfg &= ~(S5P_CITRGFMT_INROT90 | S5P_CITRGFMT_OUTROT90 |
87 S5P_CITRGFMT_FLIP_180); 93 S5P_CITRGFMT_FLIP_180);
88
89 flip = readl(dev->regs + S5P_MSCTRL);
90 flip &= ~S5P_MSCTRL_FLIP_MASK;
91 94
92 /* 95 /*
93 * The input and output rotator cannot work simultaneously. 96 * The input and output rotator cannot work simultaneously.
@@ -95,26 +98,22 @@ void fimc_hw_set_rotation(struct fimc_ctx *ctx)
95 * in direct fifo output mode. 98 * in direct fifo output mode.
96 */ 99 */
97 if (ctx->rotation == 90 || ctx->rotation == 270) { 100 if (ctx->rotation == 90 || ctx->rotation == 270) {
98 if (ctx->out_path == FIMC_LCDFIFO) {
99 cfg |= S5P_CITRGFMT_INROT90;
100 if (ctx->rotation == 270)
101 flip |= S5P_MSCTRL_FLIP_180;
102 } else {
103 cfg |= S5P_CITRGFMT_OUTROT90;
104 if (ctx->rotation == 270)
105 cfg |= S5P_CITRGFMT_FLIP_180;
106 }
107 } else if (ctx->rotation == 180) {
108 if (ctx->out_path == FIMC_LCDFIFO) 101 if (ctx->out_path == FIMC_LCDFIFO)
109 flip |= S5P_MSCTRL_FLIP_180; 102 cfg |= S5P_CITRGFMT_INROT90;
110 else 103 else
111 cfg |= S5P_CITRGFMT_FLIP_180; 104 cfg |= S5P_CITRGFMT_OUTROT90;
112 } 105 }
113 if (ctx->rotation == 180 || ctx->rotation == 270)
114 writel(flip, dev->regs + S5P_MSCTRL);
115 106
116 cfg |= fimc_hw_get_target_flip(ctx->flip); 107 if (ctx->out_path == FIMC_DMA) {
117 writel(cfg, dev->regs + S5P_CITRGFMT); 108 cfg |= fimc_hw_get_target_flip(ctx);
109 writel(cfg, dev->regs + S5P_CITRGFMT);
110 } else {
111 /* LCD FIFO path */
112 flip = readl(dev->regs + S5P_MSCTRL);
113 flip &= ~S5P_MSCTRL_FLIP_MASK;
114 flip |= fimc_hw_get_in_flip(ctx);
115 writel(flip, dev->regs + S5P_MSCTRL);
116 }
118} 117}
119 118
120void fimc_hw_set_target_format(struct fimc_ctx *ctx) 119void fimc_hw_set_target_format(struct fimc_ctx *ctx)
@@ -131,18 +130,13 @@ void fimc_hw_set_target_format(struct fimc_ctx *ctx)
131 S5P_CITRGFMT_VSIZE_MASK); 130 S5P_CITRGFMT_VSIZE_MASK);
132 131
133 switch (frame->fmt->color) { 132 switch (frame->fmt->color) {
134 case S5P_FIMC_RGB565: 133 case S5P_FIMC_RGB565...S5P_FIMC_RGB888:
135 case S5P_FIMC_RGB666:
136 case S5P_FIMC_RGB888:
137 cfg |= S5P_CITRGFMT_RGB; 134 cfg |= S5P_CITRGFMT_RGB;
138 break; 135 break;
139 case S5P_FIMC_YCBCR420: 136 case S5P_FIMC_YCBCR420:
140 cfg |= S5P_CITRGFMT_YCBCR420; 137 cfg |= S5P_CITRGFMT_YCBCR420;
141 break; 138 break;
142 case S5P_FIMC_YCBYCR422: 139 case S5P_FIMC_YCBYCR422...S5P_FIMC_CRYCBY422:
143 case S5P_FIMC_YCRYCB422:
144 case S5P_FIMC_CBYCRY422:
145 case S5P_FIMC_CRYCBY422:
146 if (frame->fmt->colplanes == 1) 140 if (frame->fmt->colplanes == 1)
147 cfg |= S5P_CITRGFMT_YCBCR422_1P; 141 cfg |= S5P_CITRGFMT_YCBCR422_1P;
148 else 142 else
@@ -410,8 +404,7 @@ void fimc_hw_set_in_dma(struct fimc_ctx *ctx)
410 404
411 /* Set the input DMA to process single frame only. */ 405 /* Set the input DMA to process single frame only. */
412 cfg = readl(dev->regs + S5P_MSCTRL); 406 cfg = readl(dev->regs + S5P_MSCTRL);
413 cfg &= ~(S5P_MSCTRL_FLIP_MASK 407 cfg &= ~(S5P_MSCTRL_INFORMAT_MASK
414 | S5P_MSCTRL_INFORMAT_MASK
415 | S5P_MSCTRL_IN_BURST_COUNT_MASK 408 | S5P_MSCTRL_IN_BURST_COUNT_MASK
416 | S5P_MSCTRL_INPUT_MASK 409 | S5P_MSCTRL_INPUT_MASK
417 | S5P_MSCTRL_C_INT_IN_MASK 410 | S5P_MSCTRL_C_INT_IN_MASK
@@ -450,13 +443,6 @@ void fimc_hw_set_in_dma(struct fimc_ctx *ctx)
450 break; 443 break;
451 } 444 }
452 445
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); 446 writel(cfg, dev->regs + S5P_MSCTRL);
461 447
462 /* Input/output DMA linear/tiled mode. */ 448 /* Input/output DMA linear/tiled mode. */