History

media: rkisp1: Add support for CAC

The CAC block implements chromatic aberration correction. Expose it to userspace using the extensible parameters format. This was tested on the i.MX8MP platform, but based on available documentation it is also present in the RK3399 variant (V10). Thus presumably also in later versions, so no feature flag is introduced.

Barnabás Pőcze committed 6 months ago

Commit 27caa941 parent c4c01c43 files · +187 −3Browse files

Unified · Split

3 files
  1. drivers/media/platform/rockchip/rkisp1/rkisp1-params.c +68 −0
  2. drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h +13 −2
  3. include/uapi/linux/rkisp1-config.h +106 −1
drivers/media/platform/rockchip/rkisp1/rkisp1-params.c+68−0
@@ -64,6 +64,7 @@ union rkisp1_ext_params_config { · 63 unmodified lines
64 struct rkisp1_ext_params_compand_bls_config compand_bls;64 struct rkisp1_ext_params_compand_bls_config compand_bls;
65 struct rkisp1_ext_params_compand_curve_config compand_curve;65 struct rkisp1_ext_params_compand_curve_config compand_curve;
66 struct rkisp1_ext_params_wdr_config wdr;66 struct rkisp1_ext_params_wdr_config wdr;
67 struct rkisp1_ext_params_cac_config cac;
67};68};
68 69
69enum rkisp1_params_formats {70enum rkisp1_params_formats {
@@ -1413,6 +1414,47 @@ static void rkisp1_wdr_config(struct rkisp1_params *params, · 1343 unmodified lines
1413 RKISP1_CIF_ISP_WDR_TONE_CURVE_YM_MASK);1414 RKISP1_CIF_ISP_WDR_TONE_CURVE_YM_MASK);
1414}1415}
1415 1416
1417static void rkisp1_cac_config(struct rkisp1_params *params,
1418 const struct rkisp1_cif_isp_cac_config *arg)
1419{
1420 u32 val;
1421
1422 /*
1423 * The enable bit is in the same register (RKISP1_CIF_ISP_CAC_CTRL),
1424 * so only set the clipping mode, and do not modify the other bits.
1425 */
1426 val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_CAC_CTRL);
1427 val &= ~(RKISP1_CIF_ISP_CAC_CTRL_H_CLIP_MODE |
1428 RKISP1_CIF_ISP_CAC_CTRL_V_CLIP_MODE);
1429 val |= FIELD_PREP(RKISP1_CIF_ISP_CAC_CTRL_H_CLIP_MODE, arg->h_clip_mode) |
1430 FIELD_PREP(RKISP1_CIF_ISP_CAC_CTRL_V_CLIP_MODE, arg->v_clip_mode);
1431 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_CTRL, val);
1432
1433 val = FIELD_PREP(RKISP1_CIF_ISP_CAC_COUNT_START_H_MASK, arg->h_count_start) |
1434 FIELD_PREP(RKISP1_CIF_ISP_CAC_COUNT_START_V_MASK, arg->v_count_start);
1435 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_COUNT_START, val);
1436
1437 val = FIELD_PREP(RKISP1_CIF_ISP_CAC_RED_MASK, arg->red[0]) |
1438 FIELD_PREP(RKISP1_CIF_ISP_CAC_BLUE_MASK, arg->blue[0]);
1439 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_A, val);
1440
1441 val = FIELD_PREP(RKISP1_CIF_ISP_CAC_RED_MASK, arg->red[1]) |
1442 FIELD_PREP(RKISP1_CIF_ISP_CAC_BLUE_MASK, arg->blue[1]);
1443 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_B, val);
1444
1445 val = FIELD_PREP(RKISP1_CIF_ISP_CAC_RED_MASK, arg->red[2]) |
1446 FIELD_PREP(RKISP1_CIF_ISP_CAC_BLUE_MASK, arg->blue[2]);
1447 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_C, val);
1448
1449 val = FIELD_PREP(RKISP1_CIF_ISP_CAC_NF_MASK, arg->x_nf) |
1450 FIELD_PREP(RKISP1_CIF_ISP_CAC_NS_MASK, arg->x_ns);
1451 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_X_NORM, val);
1452
1453 val = FIELD_PREP(RKISP1_CIF_ISP_CAC_NF_MASK, arg->y_nf) |
1454 FIELD_PREP(RKISP1_CIF_ISP_CAC_NS_MASK, arg->y_ns);
1455 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_Y_NORM, val);
1456}
1457
1416static void1458static void
1417rkisp1_isp_isr_other_config(struct rkisp1_params *params,1459rkisp1_isp_isr_other_config(struct rkisp1_params *params,
1418 const struct rkisp1_params_cfg *new_params)1460 const struct rkisp1_params_cfg *new_params)
@@ -2089,6 +2131,25 @@ static void rkisp1_ext_params_wdr(struct rkisp1_params *params, · 670 unmodified lines
2089 RKISP1_CIF_ISP_WDR_CTRL_ENABLE);2131 RKISP1_CIF_ISP_WDR_CTRL_ENABLE);
2090}2132}
2091 2133
2134static void rkisp1_ext_params_cac(struct rkisp1_params *params,
2135 const union rkisp1_ext_params_config *block)
2136{
2137 const struct rkisp1_ext_params_cac_config *cac = &block->cac;
2138
2139 if (cac->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {
2140 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CAC_CTRL,
2141 RKISP1_CIF_ISP_CAC_CTRL_ENABLE);
2142 return;
2143 }
2144
2145 rkisp1_cac_config(params, &cac->config);
2146
2147 if ((cac->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&
2148 !(params->enabled_blocks & BIT(cac->header.type)))
2149 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CAC_CTRL,
2150 RKISP1_CIF_ISP_CAC_CTRL_ENABLE);
2151}
2152
2092typedef void (*rkisp1_block_handler)(struct rkisp1_params *params,2153typedef void (*rkisp1_block_handler)(struct rkisp1_params *params,
2093 const union rkisp1_ext_params_config *config);2154 const union rkisp1_ext_params_config *config);
2094 2155
@@ -2185,6 +2246,10 @@ static const struct rkisp1_ext_params_handler { · 90 unmodified lines
2185 .handler = rkisp1_ext_params_wdr,2246 .handler = rkisp1_ext_params_wdr,
2186 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,2247 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
2187 },2248 },
2249 [RKISP1_EXT_PARAMS_BLOCK_TYPE_CAC] = {
2250 .handler = rkisp1_ext_params_cac,
2251 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
2252 },
2188};2253};
2189 2254
2190#define RKISP1_PARAMS_BLOCK_INFO(block, data) \2255#define RKISP1_PARAMS_BLOCK_INFO(block, data) \
@@ -2215,6 +2280,7 @@ rkisp1_ext_params_block_types_info[] = { · 24 unmodified lines
2215 RKISP1_PARAMS_BLOCK_INFO(COMPAND_EXPAND, compand_curve),2280 RKISP1_PARAMS_BLOCK_INFO(COMPAND_EXPAND, compand_curve),
2216 RKISP1_PARAMS_BLOCK_INFO(COMPAND_COMPRESS, compand_curve),2281 RKISP1_PARAMS_BLOCK_INFO(COMPAND_COMPRESS, compand_curve),
2217 RKISP1_PARAMS_BLOCK_INFO(WDR, wdr),2282 RKISP1_PARAMS_BLOCK_INFO(WDR, wdr),
2283 RKISP1_PARAMS_BLOCK_INFO(CAC, cac),
2218};2284};
2219 2285
2220static_assert(ARRAY_SIZE(rkisp1_ext_params_handlers) ==2286static_assert(ARRAY_SIZE(rkisp1_ext_params_handlers) ==
@@ -2474,6 +2540,8 @@ void rkisp1_params_disable(struct rkisp1_params *params) · 253 unmodified lines
2474 rkisp1_ie_enable(params, false);2540 rkisp1_ie_enable(params, false);
2475 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPF_MODE,2541 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPF_MODE,
2476 RKISP1_CIF_ISP_DPF_MODE_EN);2542 RKISP1_CIF_ISP_DPF_MODE_EN);
2543 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CAC_CTRL,
2544 RKISP1_CIF_ISP_CAC_CTRL_ENABLE);
2477}2545}
2478 2546
2479static const struct rkisp1_params_ops rkisp1_v10_params_ops = {2547static const struct rkisp1_params_ops rkisp1_v10_params_ops = {
drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h+13−2
@@ -724,6 +724,17 @@ · 723 unmodified lines
724#define RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_MASK GENMASK(20, 16)724#define RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_MASK GENMASK(20, 16)
725#define RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_MAX 16U725#define RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_MAX 16U
726 726
727/* CAC */
728#define RKISP1_CIF_ISP_CAC_CTRL_ENABLE BIT(0)
729#define RKISP1_CIF_ISP_CAC_CTRL_V_CLIP_MODE GENMASK(2, 1)
730#define RKISP1_CIF_ISP_CAC_CTRL_H_CLIP_MODE BIT(3)
731#define RKISP1_CIF_ISP_CAC_COUNT_START_H_MASK GENMASK(12, 0)
732#define RKISP1_CIF_ISP_CAC_COUNT_START_V_MASK GENMASK(28, 16)
733#define RKISP1_CIF_ISP_CAC_RED_MASK GENMASK(8, 0)
734#define RKISP1_CIF_ISP_CAC_BLUE_MASK GENMASK(24, 16)
735#define RKISP1_CIF_ISP_CAC_NF_MASK GENMASK(4, 0)
736#define RKISP1_CIF_ISP_CAC_NS_MASK GENMASK(19, 16)
737
727/* =================================================================== */738/* =================================================================== */
728/* CIF Registers */739/* CIF Registers */
729/* =================================================================== */740/* =================================================================== */
@@ -1196,8 +1207,8 @@ · 466 unmodified lines
1196#define RKISP1_CIF_ISP_CAC_A (RKISP1_CIF_ISP_CAC_BASE + 0x00000008)1207#define RKISP1_CIF_ISP_CAC_A (RKISP1_CIF_ISP_CAC_BASE + 0x00000008)
1197#define RKISP1_CIF_ISP_CAC_B (RKISP1_CIF_ISP_CAC_BASE + 0x0000000c)1208#define RKISP1_CIF_ISP_CAC_B (RKISP1_CIF_ISP_CAC_BASE + 0x0000000c)
1198#define RKISP1_CIF_ISP_CAC_C (RKISP1_CIF_ISP_CAC_BASE + 0x00000010)1209#define RKISP1_CIF_ISP_CAC_C (RKISP1_CIF_ISP_CAC_BASE + 0x00000010)
1199#define RKISP1_CIF_ISP_X_NORM (RKISP1_CIF_ISP_CAC_BASE + 0x00000014)1210#define RKISP1_CIF_ISP_CAC_X_NORM (RKISP1_CIF_ISP_CAC_BASE + 0x00000014)
1200#define RKISP1_CIF_ISP_Y_NORM (RKISP1_CIF_ISP_CAC_BASE + 0x00000018)1211#define RKISP1_CIF_ISP_CAC_Y_NORM (RKISP1_CIF_ISP_CAC_BASE + 0x00000018)
1201 1212
1202#define RKISP1_CIF_ISP_EXP_BASE 0x000026001213#define RKISP1_CIF_ISP_EXP_BASE 0x00002600
1203#define RKISP1_CIF_ISP_EXP_CTRL (RKISP1_CIF_ISP_EXP_BASE + 0x00000000)1214#define RKISP1_CIF_ISP_EXP_CTRL (RKISP1_CIF_ISP_EXP_BASE + 0x00000000)
include/uapi/linux/rkisp1-config.h+106−1
@@ -967,6 +967,92 @@ struct rkisp1_cif_isp_wdr_config { · 966 unmodified lines
967 __u8 use_iref;967 __u8 use_iref;
968};968};
969 969
970/*
971 * enum rkisp1_cif_isp_cac_h_clip_mode - horizontal clipping mode
972 *
973 * @RKISP1_CIF_ISP_CAC_H_CLIP_MODE_4PX: +/- 4 pixels
974 * @RKISP1_CIF_ISP_CAC_H_CLIP_MODE_4_5PX: +/- 4/5 pixels depending on bayer position
975 */
976enum rkisp1_cif_isp_cac_h_clip_mode {
977 RKISP1_CIF_ISP_CAC_H_CLIP_MODE_4PX = 0,
978 RKISP1_CIF_ISP_CAC_H_CLIP_MODE_4_5PX = 1,
979};
980
981/**
982 * enum rkisp1_cif_isp_cac_v_clip_mode - vertical clipping mode
983 *
984 * @RKISP1_CIF_ISP_CAC_V_CLIP_MODE_2PX: +/- 2 pixels
985 * @RKISP1_CIF_ISP_CAC_V_CLIP_MODE_3PX: +/- 3 pixels
986 * @RKISP1_CIF_ISP_CAC_V_CLIP_MODE_3_4PX: +/- 3/4 pixels depending on bayer position
987 */
988enum rkisp1_cif_isp_cac_v_clip_mode {
989 RKISP1_CIF_ISP_CAC_V_CLIP_MODE_2PX = 0,
990 RKISP1_CIF_ISP_CAC_V_CLIP_MODE_3PX = 1,
991 RKISP1_CIF_ISP_CAC_V_CLIP_MODE_3_4PX = 2,
992};
993
994/**
995 * struct rkisp1_cif_isp_cac_config - chromatic aberration correction configuration
996 *
997 * The correction is carried out by shifting the red and blue pixels relative
998 * to the green ones, depending on the distance from the optical center:
999 *
1000 * @h_count_start: horizontal coordinate of the optical center (13-bit unsigned integer; [1,8191])
1001 * @v_count_start: vertical coordinate of the optical center (13-bit unsigned integer; [1,8191])
1002 *
1003 * For each pixel, the x/y distances from the optical center are calculated and
1004 * then transformed into the [0,255] range based on the following formula:
1005 *
1006 * (((d << 4) >> ns) * nf) >> 5
1007 *
1008 * where `d` is the distance, `ns` and `nf` are the normalization parameters:
1009 *
1010 * @x_nf: horizontal normalization scale parameter (5-bit unsigned integer; [0,31])
1011 * @x_ns: horizontal normalization shift parameter (4-bit unsigned integer; [0,15])
1012 *
1013 * @y_nf: vertical normalization scale parameter (5-bit unsigned integer; [0,31])
1014 * @y_ns: vertical normalization shift parameter (4-bit unsigned integer; [0,15])
1015 *
1016 * These parameters should be chosen based on the image resolution, the position
1017 * of the optical center, and the shape of pixels, so that no normalized distance
1018 * is larger than 255. If the pixels have square shape, the two sets of parameters
1019 * should be equal.
1020 *
1021 * The actual amount of correction is calculated with a third degree polynomial:
1022 *
1023 * c[0] * r + c[1] * r^2 + c[2] * r^3
1024 *
1025 * where `c` is the set of coefficients for the given color, and `r` is distance:
1026 *
1027 * @red: red coefficients (5.4 two's complement; [-16,15.9375])
1028 * @blue: blue coefficients (5.4 two's complement; [-16,15.9375])
1029 *
1030 * Finally, the amount is clipped as requested:
1031 *
1032 * @h_clip_mode: maximum horizontal shift (from enum rkisp1_cif_isp_cac_h_clip_mode)
1033 * @v_clip_mode: maximum vertical shift (from enum rkisp1_cif_isp_cac_v_clip_mode)
1034 *
1035 * A positive result will shift away from the optical center, while a negative
1036 * one will shift towards the optical center. In the latter case, the pixel
1037 * values at the edges are duplicated.
1038 */
1039struct rkisp1_cif_isp_cac_config {
1040 __u8 h_clip_mode;
1041 __u8 v_clip_mode;
1042
1043 __u16 h_count_start;
1044 __u16 v_count_start;
1045
1046 __u16 red[3];
1047 __u16 blue[3];
1048
1049 __u8 x_nf;
1050 __u8 x_ns;
1051
1052 __u8 y_nf;
1053 __u8 y_ns;
1054};
1055
970/*---------- PART2: Measurement Statistics ------------*/1056/*---------- PART2: Measurement Statistics ------------*/
971 1057
972/**1058/**
@@ -1138,6 +1224,7 @@ struct rkisp1_stat_buffer { · 165 unmodified lines
1138 * @RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND: Companding expand curve1224 * @RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND: Companding expand curve
1139 * @RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS: Companding compress curve1225 * @RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS: Companding compress curve
1140 * @RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR: Wide dynamic range1226 * @RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR: Wide dynamic range
1227 * @RKISP1_EXT_PARAMS_BLOCK_TYPE_CAC: Chromatic aberration correction
1141 */1228 */
1142enum rkisp1_ext_params_block_type {1229enum rkisp1_ext_params_block_type {
1143 RKISP1_EXT_PARAMS_BLOCK_TYPE_BLS,1230 RKISP1_EXT_PARAMS_BLOCK_TYPE_BLS,
@@ -1161,6 +1248,7 @@ enum rkisp1_ext_params_block_type { · 17 unmodified lines
1161 RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND,1248 RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND,
1162 RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS,1249 RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS,
1163 RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR,1250 RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR,
1251 RKISP1_EXT_PARAMS_BLOCK_TYPE_CAC,
1164};1252};
1165 1253
1166/* For backward compatibility */1254/* For backward compatibility */
@@ -1507,6 +1595,22 @@ struct rkisp1_ext_params_wdr_config { · 340 unmodified lines
1507 struct rkisp1_cif_isp_wdr_config config;1595 struct rkisp1_cif_isp_wdr_config config;
1508} __attribute__((aligned(8)));1596} __attribute__((aligned(8)));
1509 1597
1598/**
1599 * struct rkisp1_ext_params_cac_config - RkISP1 extensible params CAC config
1600 *
1601 * RkISP1 extensible parameters CAC block.
1602 * Identified by :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_CAC`.
1603 *
1604 * @header: The RkISP1 extensible parameters header, see
1605 * :c:type:`rkisp1_ext_params_block_header`
1606 * @config: CAC configuration, see
1607 * :c:type:`rkisp1_cif_isp_cac_config`
1608 */
1609struct rkisp1_ext_params_cac_config {
1610 struct rkisp1_ext_params_block_header header;
1611 struct rkisp1_cif_isp_cac_config config;
1612} __attribute__((aligned(8)));
1613
1510/*1614/*
1511 * The rkisp1_ext_params_compand_curve_config structure is counted twice as it1615 * The rkisp1_ext_params_compand_curve_config structure is counted twice as it
1512 * is used for both the COMPAND_EXPAND and COMPAND_COMPRESS block types.1616 * is used for both the COMPAND_EXPAND and COMPAND_COMPRESS block types.
@@ -1532,7 +1636,8 @@ struct rkisp1_ext_params_wdr_config { · 19 unmodified lines
1532 sizeof(struct rkisp1_ext_params_compand_bls_config) +\1636 sizeof(struct rkisp1_ext_params_compand_bls_config) +\
1533 sizeof(struct rkisp1_ext_params_compand_curve_config) +\1637 sizeof(struct rkisp1_ext_params_compand_curve_config) +\
1534 sizeof(struct rkisp1_ext_params_compand_curve_config) +\1638 sizeof(struct rkisp1_ext_params_compand_curve_config) +\
1535 sizeof(struct rkisp1_ext_params_wdr_config))1639 sizeof(struct rkisp1_ext_params_wdr_config) +\
1640 sizeof(struct rkisp1_ext_params_cac_config))
1536 1641
1537/**1642/**
1538 * enum rkisp1_ext_param_buffer_version - RkISP1 extensible parameters version1643 * enum rkisp1_ext_param_buffer_version - RkISP1 extensible parameters version

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t