aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-06-18 10:24:48 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-08-11 14:59:54 -0400
commit6fd206cb6ebd59e42b376b9e2e8f40d90910757e (patch)
tree0700e2a42b84851af5c45dbbca9c6d11cb9bb4c6 /drivers/media/video
parentac9dad93164c603e5efc4e57727e929799861a9f (diff)
[media] omap3isp: preview: Add support for non-GRBG Bayer patterns
Rearrange the CFA interpolation coefficients table based on the Bayer pattern. Support for non-Bayer CFA patterns is dropped as they were not correctly supported, and have never been tested. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Sakari Ailus <sakari.ailus@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/omap3isp/cfa_coef_table.h16
-rw-r--r--drivers/media/video/omap3isp/isppreview.c131
-rw-r--r--drivers/media/video/omap3isp/isppreview.h1
3 files changed, 89 insertions, 59 deletions
diff --git a/drivers/media/video/omap3isp/cfa_coef_table.h b/drivers/media/video/omap3isp/cfa_coef_table.h
index c60df0ed075a..c84df0706f3e 100644
--- a/drivers/media/video/omap3isp/cfa_coef_table.h
+++ b/drivers/media/video/omap3isp/cfa_coef_table.h
@@ -23,7 +23,7 @@
23 * 02110-1301 USA 23 * 02110-1301 USA
24 */ 24 */
25 25
26244, 0, 247, 0, 12, 27, 36, 247, 250, 0, 27, 0, 4, 250, 12, 244, 26{ 244, 0, 247, 0, 12, 27, 36, 247, 250, 0, 27, 0, 4, 250, 12, 244,
27248, 0, 0, 0, 0, 40, 0, 0, 244, 12, 250, 4, 0, 27, 0, 250, 27248, 0, 0, 0, 0, 40, 0, 0, 244, 12, 250, 4, 0, 27, 0, 250,
28247, 36, 27, 12, 0, 247, 0, 244, 0, 0, 40, 0, 0, 0, 0, 248, 28247, 36, 27, 12, 0, 247, 0, 244, 0, 0, 40, 0, 0, 0, 0, 248,
29244, 0, 247, 0, 12, 27, 36, 247, 250, 0, 27, 0, 4, 250, 12, 244, 29244, 0, 247, 0, 12, 27, 36, 247, 250, 0, 27, 0, 4, 250, 12, 244,
@@ -31,8 +31,8 @@
31247, 36, 27, 12, 0, 247, 0, 244, 0, 0, 40, 0, 0, 0, 0, 248, 31247, 36, 27, 12, 0, 247, 0, 244, 0, 0, 40, 0, 0, 0, 0, 248,
32244, 0, 247, 0, 12, 27, 36, 247, 250, 0, 27, 0, 4, 250, 12, 244, 32244, 0, 247, 0, 12, 27, 36, 247, 250, 0, 27, 0, 4, 250, 12, 244,
33248, 0, 0, 0, 0, 40, 0, 0, 244, 12, 250, 4, 0, 27, 0, 250, 33248, 0, 0, 0, 0, 40, 0, 0, 244, 12, 250, 4, 0, 27, 0, 250,
34247, 36, 27, 12, 0, 247, 0, 244, 0, 0, 40, 0, 0, 0, 0, 248, 34247, 36, 27, 12, 0, 247, 0, 244, 0, 0, 40, 0, 0, 0, 0, 248 },
35 0, 247, 0, 244, 247, 36, 27, 12, 0, 27, 0, 250, 244, 12, 250, 4, 35{ 0, 247, 0, 244, 247, 36, 27, 12, 0, 27, 0, 250, 244, 12, 250, 4,
36 0, 0, 0, 248, 0, 0, 40, 0, 4, 250, 12, 244, 250, 0, 27, 0, 36 0, 0, 0, 248, 0, 0, 40, 0, 4, 250, 12, 244, 250, 0, 27, 0,
37 12, 27, 36, 247, 244, 0, 247, 0, 0, 40, 0, 0, 248, 0, 0, 0, 37 12, 27, 36, 247, 244, 0, 247, 0, 0, 40, 0, 0, 248, 0, 0, 0,
38 0, 247, 0, 244, 247, 36, 27, 12, 0, 27, 0, 250, 244, 12, 250, 4, 38 0, 247, 0, 244, 247, 36, 27, 12, 0, 27, 0, 250, 244, 12, 250, 4,
@@ -40,8 +40,8 @@
40 12, 27, 36, 247, 244, 0, 247, 0, 0, 40, 0, 0, 248, 0, 0, 0, 40 12, 27, 36, 247, 244, 0, 247, 0, 0, 40, 0, 0, 248, 0, 0, 0,
41 0, 247, 0, 244, 247, 36, 27, 12, 0, 27, 0, 250, 244, 12, 250, 4, 41 0, 247, 0, 244, 247, 36, 27, 12, 0, 27, 0, 250, 244, 12, 250, 4,
42 0, 0, 0, 248, 0, 0, 40, 0, 4, 250, 12, 244, 250, 0, 27, 0, 42 0, 0, 0, 248, 0, 0, 40, 0, 4, 250, 12, 244, 250, 0, 27, 0,
43 12, 27, 36, 247, 244, 0, 247, 0, 0, 40, 0, 0, 248, 0, 0, 0, 43 12, 27, 36, 247, 244, 0, 247, 0, 0, 40, 0, 0, 248, 0, 0, 0 },
44 4, 250, 12, 244, 250, 0, 27, 0, 12, 27, 36, 247, 244, 0, 247, 0, 44{ 4, 250, 12, 244, 250, 0, 27, 0, 12, 27, 36, 247, 244, 0, 247, 0,
45 0, 0, 0, 248, 0, 0, 40, 0, 0, 247, 0, 244, 247, 36, 27, 12, 45 0, 0, 0, 248, 0, 0, 40, 0, 0, 247, 0, 244, 247, 36, 27, 12,
46 0, 27, 0, 250, 244, 12, 250, 4, 0, 40, 0, 0, 248, 0, 0, 0, 46 0, 27, 0, 250, 244, 12, 250, 4, 0, 40, 0, 0, 248, 0, 0, 0,
47 4, 250, 12, 244, 250, 0, 27, 0, 12, 27, 36, 247, 244, 0, 247, 0, 47 4, 250, 12, 244, 250, 0, 27, 0, 12, 27, 36, 247, 244, 0, 247, 0,
@@ -49,8 +49,8 @@
49 0, 27, 0, 250, 244, 12, 250, 4, 0, 40, 0, 0, 248, 0, 0, 0, 49 0, 27, 0, 250, 244, 12, 250, 4, 0, 40, 0, 0, 248, 0, 0, 0,
50 4, 250, 12, 244, 250, 0, 27, 0, 12, 27, 36, 247, 244, 0, 247, 0, 50 4, 250, 12, 244, 250, 0, 27, 0, 12, 27, 36, 247, 244, 0, 247, 0,
51 0, 0, 0, 248, 0, 0, 40, 0, 0, 247, 0, 244, 247, 36, 27, 12, 51 0, 0, 0, 248, 0, 0, 40, 0, 0, 247, 0, 244, 247, 36, 27, 12,
52 0, 27, 0, 250, 244, 12, 250, 4, 0, 40, 0, 0, 248, 0, 0, 0, 52 0, 27, 0, 250, 244, 12, 250, 4, 0, 40, 0, 0, 248, 0, 0, 0 },
53244, 12, 250, 4, 0, 27, 0, 250, 247, 36, 27, 12, 0, 247, 0, 244, 53{ 244,12, 250, 4, 0, 27, 0, 250, 247, 36, 27, 12, 0, 247, 0, 244,
54248, 0, 0, 0, 0, 40, 0, 0, 244, 0, 247, 0, 12, 27, 36, 247, 54248, 0, 0, 0, 0, 40, 0, 0, 244, 0, 247, 0, 12, 27, 36, 247,
55250, 0, 27, 0, 4, 250, 12, 244, 0, 0, 40, 0, 0, 0, 0, 248, 55250, 0, 27, 0, 4, 250, 12, 244, 0, 0, 40, 0, 0, 0, 0, 248,
56244, 12, 250, 4, 0, 27, 0, 250, 247, 36, 27, 12, 0, 247, 0, 244, 56244, 12, 250, 4, 0, 27, 0, 250, 247, 36, 27, 12, 0, 247, 0, 244,
@@ -58,4 +58,4 @@
58250, 0, 27, 0, 4, 250, 12, 244, 0, 0, 40, 0, 0, 0, 0, 248, 58250, 0, 27, 0, 4, 250, 12, 244, 0, 0, 40, 0, 0, 0, 0, 248,
59244, 12, 250, 4, 0, 27, 0, 250, 247, 36, 27, 12, 0, 247, 0, 244, 59244, 12, 250, 4, 0, 27, 0, 250, 247, 36, 27, 12, 0, 247, 0, 244,
60248, 0, 0, 0, 0, 40, 0, 0, 244, 0, 247, 0, 12, 27, 36, 247, 60248, 0, 0, 0, 0, 40, 0, 0, 244, 0, 247, 0, 12, 27, 36, 247,
61250, 0, 27, 0, 4, 250, 12, 244, 0, 0, 40, 0, 0, 0, 0, 248 61250, 0, 27, 0, 4, 250, 12, 244, 0, 0, 40, 0, 0, 0, 0, 248 },
diff --git a/drivers/media/video/omap3isp/isppreview.c b/drivers/media/video/omap3isp/isppreview.c
index 72d261835ad2..1ae1c0909ed1 100644
--- a/drivers/media/video/omap3isp/isppreview.c
+++ b/drivers/media/video/omap3isp/isppreview.c
@@ -131,7 +131,7 @@ static struct omap3isp_prev_csc flr_prev_csc = {
131 * CFA Filter Coefficient Table 131 * CFA Filter Coefficient Table
132 * 132 *
133 */ 133 */
134static u32 cfa_coef_table[] = { 134static u32 cfa_coef_table[4][OMAP3ISP_PREV_CFA_BLK_SIZE] = {
135#include "cfa_coef_table.h" 135#include "cfa_coef_table.h"
136}; 136};
137 137
@@ -237,19 +237,27 @@ static void preview_enable_hmed(struct isp_prev_device *prev, bool enable)
237} 237}
238 238
239/* 239/*
240 * preview_config_cfa - Configure CFA Interpolation 240 * preview_config_cfa - Configure CFA Interpolation for Bayer formats
241 */ 241 *
242static void 242 * The CFA table is organised in four blocks, one per Bayer component. The
243preview_config_cfa(struct isp_prev_device *prev, 243 * hardware expects blocks to follow the Bayer order of the input data, while
244 const struct prev_params *params) 244 * the driver stores the table in GRBG order in memory. The blocks need to be
245{ 245 * reordered to support non-GRBG Bayer patterns.
246 struct isp_device *isp = to_isp_device(prev); 246 */
247static void preview_config_cfa(struct isp_prev_device *prev,
248 const struct prev_params *params)
249{
250 static const unsigned int cfa_coef_order[4][4] = {
251 { 0, 1, 2, 3 }, /* GRBG */
252 { 1, 0, 3, 2 }, /* RGGB */
253 { 2, 3, 0, 1 }, /* BGGR */
254 { 3, 2, 1, 0 }, /* GBRG */
255 };
256 const unsigned int *order = cfa_coef_order[prev->params.cfa_order];
247 const struct omap3isp_prev_cfa *cfa = &params->cfa; 257 const struct omap3isp_prev_cfa *cfa = &params->cfa;
258 struct isp_device *isp = to_isp_device(prev);
248 unsigned int i; 259 unsigned int i;
249 260 unsigned int j;
250 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
251 ISPPRV_PCR_CFAFMT_MASK,
252 cfa->format << ISPPRV_PCR_CFAFMT_SHIFT);
253 261
254 isp_reg_writel(isp, 262 isp_reg_writel(isp,
255 (cfa->gradthrs_vert << ISPPRV_CFA_GRADTH_VER_SHIFT) | 263 (cfa->gradthrs_vert << ISPPRV_CFA_GRADTH_VER_SHIFT) |
@@ -259,9 +267,12 @@ preview_config_cfa(struct isp_prev_device *prev,
259 isp_reg_writel(isp, ISPPRV_CFA_TABLE_ADDR, 267 isp_reg_writel(isp, ISPPRV_CFA_TABLE_ADDR,
260 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR); 268 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
261 269
262 for (i = 0; i < OMAP3ISP_PREV_CFA_TBL_SIZE; i++) { 270 for (i = 0; i < 4; ++i) {
263 isp_reg_writel(isp, cfa->table[i], 271 const __u32 *block = cfa->table[order[i]];
264 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_DATA); 272
273 for (j = 0; j < OMAP3ISP_PREV_CFA_BLK_SIZE; ++j)
274 isp_reg_writel(isp, block[j], OMAP3_ISP_IOMEM_PREV,
275 ISPPRV_SET_TBL_DATA);
265 } 276 }
266} 277}
267 278
@@ -993,42 +1004,60 @@ preview_config_ycpos(struct isp_prev_device *prev,
993static void preview_config_averager(struct isp_prev_device *prev, u8 average) 1004static void preview_config_averager(struct isp_prev_device *prev, u8 average)
994{ 1005{
995 struct isp_device *isp = to_isp_device(prev); 1006 struct isp_device *isp = to_isp_device(prev);
996 struct prev_params *params;
997 int reg = 0;
998
999 params = (prev->params.active & OMAP3ISP_PREV_CFA)
1000 ? &prev->params.params[0] : &prev->params.params[1];
1001 1007
1002 if (params->cfa.format == OMAP3ISP_CFAFMT_BAYER) 1008 isp_reg_writel(isp, ISPPRV_AVE_EVENDIST_2 << ISPPRV_AVE_EVENDIST_SHIFT |
1003 reg = ISPPRV_AVE_EVENDIST_2 << ISPPRV_AVE_EVENDIST_SHIFT | 1009 ISPPRV_AVE_ODDDIST_2 << ISPPRV_AVE_ODDDIST_SHIFT |
1004 ISPPRV_AVE_ODDDIST_2 << ISPPRV_AVE_ODDDIST_SHIFT | 1010 average, OMAP3_ISP_IOMEM_PREV, ISPPRV_AVE);
1005 average;
1006 else if (params->cfa.format == OMAP3ISP_CFAFMT_RGBFOVEON)
1007 reg = ISPPRV_AVE_EVENDIST_3 << ISPPRV_AVE_EVENDIST_SHIFT |
1008 ISPPRV_AVE_ODDDIST_3 << ISPPRV_AVE_ODDDIST_SHIFT |
1009 average;
1010 isp_reg_writel(isp, reg, OMAP3_ISP_IOMEM_PREV, ISPPRV_AVE);
1011} 1011}
1012 1012
1013
1013/* 1014/*
1014 * preview_config_input_format - Configure the input format 1015 * preview_config_input_format - Configure the input format
1015 * @prev: The preview engine 1016 * @prev: The preview engine
1016 * @format: Format on the preview engine sink pad 1017 * @format: Format on the preview engine sink pad
1017 * 1018 *
1018 * Enable CFA interpolation for Bayer formats and disable it for greyscale 1019 * Enable and configure CFA interpolation for Bayer formats and disable it for
1019 * formats. 1020 * greyscale formats.
1021 *
1022 * The CFA table is organised in four blocks, one per Bayer component. The
1023 * hardware expects blocks to follow the Bayer order of the input data, while
1024 * the driver stores the table in GRBG order in memory. The blocks need to be
1025 * reordered to support non-GRBG Bayer patterns.
1020 */ 1026 */
1021static void preview_config_input_format(struct isp_prev_device *prev, 1027static void preview_config_input_format(struct isp_prev_device *prev,
1022 const struct v4l2_mbus_framefmt *format) 1028 const struct v4l2_mbus_framefmt *format)
1023{ 1029{
1024 struct isp_device *isp = to_isp_device(prev); 1030 struct isp_device *isp = to_isp_device(prev);
1031 struct prev_params *params;
1025 1032
1026 if (format->code != V4L2_MBUS_FMT_Y10_1X10) 1033 switch (format->code) {
1027 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, 1034 case V4L2_MBUS_FMT_SGRBG10_1X10:
1028 ISPPRV_PCR_CFAEN); 1035 prev->params.cfa_order = 0;
1029 else 1036 break;
1037 case V4L2_MBUS_FMT_SRGGB10_1X10:
1038 prev->params.cfa_order = 1;
1039 break;
1040 case V4L2_MBUS_FMT_SBGGR10_1X10:
1041 prev->params.cfa_order = 2;
1042 break;
1043 case V4L2_MBUS_FMT_SGBRG10_1X10:
1044 prev->params.cfa_order = 3;
1045 break;
1046 default:
1047 /* Disable CFA for non-Bayer formats. */
1030 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, 1048 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1031 ISPPRV_PCR_CFAEN); 1049 ISPPRV_PCR_CFAEN);
1050 return;
1051 }
1052
1053 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, ISPPRV_PCR_CFAEN);
1054 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1055 ISPPRV_PCR_CFAFMT_MASK, ISPPRV_PCR_CFAFMT_BAYER);
1056
1057 params = (prev->params.active & OMAP3ISP_PREV_CFA)
1058 ? &prev->params.params[0] : &prev->params.params[1];
1059
1060 preview_config_cfa(prev, params);
1032} 1061}
1033 1062
1034/* 1063/*
@@ -1371,22 +1400,6 @@ static void preview_configure(struct isp_prev_device *prev)
1371 active = prev->params.active; 1400 active = prev->params.active;
1372 spin_unlock_irqrestore(&prev->params.lock, flags); 1401 spin_unlock_irqrestore(&prev->params.lock, flags);
1373 1402
1374 preview_setup_hw(prev, update, active);
1375
1376 if (prev->output & PREVIEW_OUTPUT_MEMORY)
1377 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1378 ISPPRV_PCR_SDRPORT);
1379 else
1380 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1381 ISPPRV_PCR_SDRPORT);
1382
1383 if (prev->output & PREVIEW_OUTPUT_RESIZER)
1384 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1385 ISPPRV_PCR_RSZPORT);
1386 else
1387 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1388 ISPPRV_PCR_RSZPORT);
1389
1390 /* PREV_PAD_SINK */ 1403 /* PREV_PAD_SINK */
1391 format = &prev->formats[PREV_PAD_SINK]; 1404 format = &prev->formats[PREV_PAD_SINK];
1392 1405
@@ -1401,10 +1414,26 @@ static void preview_configure(struct isp_prev_device *prev)
1401 preview_config_inlineoffset(prev, 1414 preview_config_inlineoffset(prev,
1402 ALIGN(format->width, 0x20) * 2); 1415 ALIGN(format->width, 0x20) * 2);
1403 1416
1417 preview_setup_hw(prev, update, active);
1418
1404 /* PREV_PAD_SOURCE */ 1419 /* PREV_PAD_SOURCE */
1405 format = &prev->formats[PREV_PAD_SOURCE]; 1420 format = &prev->formats[PREV_PAD_SOURCE];
1406 1421
1407 if (prev->output & PREVIEW_OUTPUT_MEMORY) 1422 if (prev->output & PREVIEW_OUTPUT_MEMORY)
1423 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1424 ISPPRV_PCR_SDRPORT);
1425 else
1426 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1427 ISPPRV_PCR_SDRPORT);
1428
1429 if (prev->output & PREVIEW_OUTPUT_RESIZER)
1430 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1431 ISPPRV_PCR_RSZPORT);
1432 else
1433 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1434 ISPPRV_PCR_RSZPORT);
1435
1436 if (prev->output & PREVIEW_OUTPUT_MEMORY)
1408 preview_config_outlineoffset(prev, 1437 preview_config_outlineoffset(prev,
1409 ALIGN(format->width, 0x10) * 2); 1438 ALIGN(format->width, 0x10) * 2);
1410 1439
diff --git a/drivers/media/video/omap3isp/isppreview.h b/drivers/media/video/omap3isp/isppreview.h
index 6663ab64e4b1..f66923407f8c 100644
--- a/drivers/media/video/omap3isp/isppreview.h
+++ b/drivers/media/video/omap3isp/isppreview.h
@@ -144,6 +144,7 @@ struct isp_prev_device {
144 struct isp_video video_out; 144 struct isp_video video_out;
145 145
146 struct { 146 struct {
147 unsigned int cfa_order;
147 struct prev_params params[2]; 148 struct prev_params params[2];
148 u32 active; 149 u32 active;
149 spinlock_t lock; 150 spinlock_t lock;