aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/omap3isp/isppreview.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/omap3isp/isppreview.c')
-rw-r--r--drivers/media/video/omap3isp/isppreview.c131
1 files changed, 80 insertions, 51 deletions
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