From 89f50d3b0de85f31182ff74eba97db1d9164b04c Mon Sep 17 00:00:00 2001 From: Sunmi Lee Date: Fri, 6 Jul 2018 11:10:12 +0900 Subject: [PATCH] [COMMON] fimc-is2: Implementation of uvsp UVSP function is controlled by noise_index (this value from ISP). So it is needed to calculate the proper value with using linear interpolation by noise_index. New functions were added to support uvsp. PR JIRA ID: CPR-39 Change-Id: Id9b27ace9a2e663091f0901258b95b20a304bfbe Signed-off-by: Sunmi Lee --- .../hardware/api/fimc-is-hw-api-mcscaler-v2.h | 9 + .../api/fimc-is-hw-api-mcscaler-v5_0.c | 316 ++++++++++++++++ .../hardware/fimc-is-hw-mcscaler-v2.c | 5 + .../hardware/fimc-is-hw-mcscaler-v2.h | 5 + .../fimc-is2/hardware/fimc-is-hw-uvsp-cac.c | 340 ++++++++++++++++++ .../fimc-is2/hardware/fimc-is-hw-uvsp-cac.h | 13 +- 6 files changed, 687 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/exynos/fimc-is2/hardware/api/fimc-is-hw-api-mcscaler-v2.h b/drivers/media/platform/exynos/fimc-is2/hardware/api/fimc-is-hw-api-mcscaler-v2.h index 85fabb4dee06..7fa92731bbb8 100644 --- a/drivers/media/platform/exynos/fimc-is2/hardware/api/fimc-is-hw-api-mcscaler-v2.h +++ b/drivers/media/platform/exynos/fimc-is2/hardware/api/fimc-is-hw-api-mcscaler-v2.h @@ -233,6 +233,15 @@ void fimc_is_scaler_set_cac_enable(void __iomem *base_addr, u32 en); void fimc_is_scaler_set_cac_input_source(void __iomem *base_addr, u32 in); void fimc_is_scaler_set_cac_map_crt_thr(void __iomem *base_addr, struct cac_cfg_by_ni *cfg); +/* uvsp */ +void fimc_is_scaler_set_uvsp_enable(void __iomem *base_addr, u32 hw_id, u32 en); +void fimc_is_scaler_set_uvsp_radial_ctrl(void __iomem *base_addr, u32 hw_id, struct uvsp_ctrl *cfg); +void fimc_is_scaler_set_uvsp_radial_cfg(void __iomem *base_addr, u32 hw_id, struct uvsp_radial_cfg *cfg); +void fimc_is_scaler_set_uvsp_pedestal_cfg(void __iomem *base_addr, u32 hw_id, struct uvsp_pedestal_cfg *cfg); +void fimc_is_scaler_set_uvsp_offset_cfg(void __iomem *base_addr, u32 hw_id, struct uvsp_offset_cfg *cfg); +void fimc_is_scaler_set_uvsp_desat_cfg(void __iomem *base_addr, u32 hw_id, struct uvsp_desat_cfg *cfg); +void fimc_is_scaler_set_uvsp_r2y_coef_cfg(void __iomem *base_addr, u32 hw_id, struct uvsp_r2y_coef_cfg *cfg); + /* ysum */ void fimc_is_scaler_set_ysum_input_sourece_enable(void __iomem *base_addr, u32 output_id, bool ysum_enable); void fimc_is_scaler_set_ysum_enable(void __iomem *base_addr, bool ysum_enable); diff --git a/drivers/media/platform/exynos/fimc-is2/hardware/api/fimc-is-hw-api-mcscaler-v5_0.c b/drivers/media/platform/exynos/fimc-is2/hardware/api/fimc-is-hw-api-mcscaler-v5_0.c index ff93458de149..e83e81ece8da 100644 --- a/drivers/media/platform/exynos/fimc-is2/hardware/api/fimc-is-hw-api-mcscaler-v5_0.c +++ b/drivers/media/platform/exynos/fimc-is2/hardware/api/fimc-is-hw-api-mcscaler-v5_0.c @@ -3548,6 +3548,322 @@ void fimc_is_scaler_set_cac_map_crt_thr(void __iomem *base_addr, struct cac_cfg_ fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_CAC_CRT_THR], reg_val); } +/* for UVSP */ +void fimc_is_scaler_set_uvsp_enable(void __iomem *base_addr, u32 hw_id, u32 en) +{ + u32 reg_val = 0; + + switch (hw_id) { + case DEV_HW_MCSC0: + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_CTRL]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_ENABLE], en); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_CTRL], reg_val); + break; + case DEV_HW_MCSC1: + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_CTRL]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_ENABLE], en); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_CTRL], reg_val); + break; + default: + warn_hw("invalid hw_id(%d) for MCSC api\n", hw_id); + break; + } +} + +void fimc_is_scaler_set_uvsp_radial_ctrl(void __iomem *base_addr, u32 hw_id, struct uvsp_ctrl *cfg) +{ + u32 reg_val = 0; + + switch (hw_id) { + case DEV_HW_MCSC0: + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_BINNING]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_BINNING_X], + cfg->binning_x); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_BINNING_Y], + cfg->binning_y); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_BINNING], reg_val); + + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_RADIAL_CTRL]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_RADIAL_EN], 1); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_RADIAL_CENTER_X], + cfg->radial_center_x); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_RADIAL_CENTER_Y], + cfg->radial_center_y); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_RADIAL_CTRL], reg_val); + + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_RADIAL_BIQUAD_A]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_RADIAL_BIQUAD_A], + cfg->biquad_a); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_RADIAL_BIQUAD_B], + cfg->biquad_b); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_RADIAL_BIQUAD_B], reg_val); + break; + case DEV_HW_MCSC1: + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_BINNING]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_BINNING_X], + cfg->binning_x); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_BINNING_Y], + cfg->binning_y); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_BINNING], reg_val); + + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_RADIAL_CTRL]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_RADIAL_EN], 1); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_RADIAL_CENTER_X], + cfg->radial_center_x); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_RADIAL_CENTER_Y], + cfg->radial_center_y); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_RADIAL_CTRL], reg_val); + + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_RADIAL_BIQUAD_A]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_RADIAL_BIQUAD_A], + cfg->biquad_a); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_RADIAL_BIQUAD_B], + cfg->biquad_b); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_RADIAL_BIQUAD_B], reg_val); + break; + default: + warn_hw("invalid hw_id(%d) for MCSC api\n", hw_id); + break; + } +} + +void fimc_is_scaler_set_uvsp_radial_cfg(void __iomem *base_addr, u32 hw_id, struct uvsp_radial_cfg *cfg) +{ + u32 reg_val = 0; + + switch (hw_id) { + case DEV_HW_MCSC0: + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_RADIAL_BIQUAD_SHIFT], + cfg->biquad_shift); + + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_RADIAL_RANDOM]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_RADIAL_RANDOM_EN], + cfg->random_en); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_RADIAL_RANDOM_POWER], + cfg->random_power); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_RADIAL_RANDOM], reg_val); + + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_RADIAL_REFINE]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_RADIAL_REFINE_EN], + cfg->refine_en); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_RADIAL_REFINE_LUMA_MIN], + cfg->refine_luma_min); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_RADIAL_REFINE_DENOM], + cfg->refine_denom); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_RADIAL_REFINE], reg_val); + + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_RADIAL_ALPHA]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_RADIAL_ALPHA_GAIN_ADD_EN], + cfg->alpha_gain_add_en); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_RADIAL_ALPHA_GREEN_EN], + cfg->alpha_green_en); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_RADIAL_ALPHA_R], + cfg->alpha_r); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_RADIAL_ALPHA_G], + cfg->alpha_g); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_RADIAL_ALPHA_B], + cfg->alpha_b); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_RADIAL_ALPHA], reg_val); + break; + case DEV_HW_MCSC1: + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_RADIAL_BIQUAD_SHIFT], + cfg->biquad_shift); + + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_RADIAL_RANDOM]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_RADIAL_RANDOM_EN], + cfg->random_en); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_RADIAL_RANDOM_POWER], + cfg->random_power); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_RADIAL_RANDOM], reg_val); + + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_RADIAL_REFINE]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_RADIAL_REFINE_EN], + cfg->refine_en); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_RADIAL_REFINE_LUMA_MIN], + cfg->refine_luma_min); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_RADIAL_REFINE_DENOM], + cfg->refine_denom); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_RADIAL_REFINE], reg_val); + + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_RADIAL_ALPHA]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_RADIAL_ALPHA_GAIN_ADD_EN], + cfg->alpha_gain_add_en); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_RADIAL_ALPHA_GREEN_EN], + cfg->alpha_green_en); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_RADIAL_ALPHA_R], + cfg->alpha_r); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_RADIAL_ALPHA_G], + cfg->alpha_g); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_RADIAL_ALPHA_B], + cfg->alpha_b); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_RADIAL_ALPHA], reg_val); + break; + default: + warn_hw("invalid hw_id(%d) for MCSC api\n", hw_id); + break; + } +} + +void fimc_is_scaler_set_uvsp_pedestal_cfg(void __iomem *base_addr, u32 hw_id, struct uvsp_pedestal_cfg *cfg) +{ + u32 reg_val = 0; + + switch (hw_id) { + case DEV_HW_MCSC0: + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_PEDESTAL]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_PEDESTAL_R], cfg->r); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_PEDESTAL_G], cfg->g); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_PEDESTAL_B], cfg->b); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_PEDESTAL], reg_val); + break; + case DEV_HW_MCSC1: + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_PEDESTAL]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_PEDESTAL_R], cfg->r); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_PEDESTAL_G], cfg->g); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_PEDESTAL_B], cfg->b); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_PEDESTAL], reg_val); + break; + default: + warn_hw("invalid hw_id(%d) for MCSC api\n", hw_id); + break; + } +} + +void fimc_is_scaler_set_uvsp_offset_cfg(void __iomem *base_addr, u32 hw_id, struct uvsp_offset_cfg *cfg) +{ + u32 reg_val = 0; + + switch (hw_id) { + case DEV_HW_MCSC0: + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_OFFSET]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_OFFSET_R], cfg->r); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_OFFSET_G], cfg->g); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_OFFSET_B], cfg->b); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_OFFSET], reg_val); + break; + case DEV_HW_MCSC1: + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_OFFSET]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_OFFSET_R], cfg->r); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_OFFSET_G], cfg->g); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_OFFSET_B], cfg->b); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_OFFSET], reg_val); + break; + default: + warn_hw("invalid hw_id(%d) for MCSC api\n", hw_id); + break; + } +} + +void fimc_is_scaler_set_uvsp_desat_cfg(void __iomem *base_addr, u32 hw_id, struct uvsp_desat_cfg *cfg) +{ + u32 reg_val = 0; + + switch (hw_id) { + case DEV_HW_MCSC0: + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_DESAT_CTRL]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_DESAT_CTRL_EN], + cfg->ctrl_en); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_DESAT_CTRL_SINGLESIDE], + cfg->ctrl_singleSide); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_DESAT_CTRL_LUMA_OFFSET], + cfg->ctrl_luma_offset); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_DESAT_CTRL_GAIN_OFFSET], + cfg->ctrl_gain_offset); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_DESAT_CTRL], reg_val); + + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_DESAT_Y]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_DESAT_Y_SHIFT], + cfg->y_shift); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_DESAT_Y_LUMA_MAX], + cfg->y_luma_max); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_DESAT_Y], reg_val); + + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_DESAT_U]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_DESAT_U_LOW], + cfg->u_low); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_DESAT_U_HIGH], + cfg->u_high); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_DESAT_U], reg_val); + + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_DESAT_V]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_DESAT_V_LOW], + cfg->v_low); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP0_DESAT_V_HIGH], + cfg->v_high); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_DESAT_V], reg_val); + break; + case DEV_HW_MCSC1: + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_DESAT_CTRL]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_DESAT_CTRL_EN], + cfg->ctrl_en); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_DESAT_CTRL_SINGLESIDE], + cfg->ctrl_singleSide); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_DESAT_CTRL_LUMA_OFFSET], + cfg->ctrl_luma_offset); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_DESAT_CTRL_GAIN_OFFSET], + cfg->ctrl_gain_offset); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_DESAT_CTRL], reg_val); + + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_DESAT_Y]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_DESAT_Y_SHIFT], + cfg->y_shift); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_DESAT_Y_LUMA_MAX], + cfg->y_luma_max); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_DESAT_Y], reg_val); + + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_DESAT_U]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_DESAT_U_LOW], + cfg->u_low); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_DESAT_U_HIGH], + cfg->u_high); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_DESAT_U], reg_val); + + reg_val = fimc_is_hw_get_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_DESAT_V]); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_DESAT_V_LOW], + cfg->v_low); + reg_val = fimc_is_hw_set_field_value(reg_val, &mcsc_fields[MCSC_F_UVSP1_DESAT_V_HIGH], + cfg->v_high); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_DESAT_V], reg_val); + break; + default: + warn_hw("invalid hw_id(%d) for MCSC api\n", hw_id); + break; + } +} + +void fimc_is_scaler_set_uvsp_r2y_coef_cfg(void __iomem *base_addr, u32 hw_id, struct uvsp_r2y_coef_cfg *cfg) +{ + switch (hw_id) { + case DEV_HW_MCSC0: + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_RGB2YUV_COEF_00], cfg->r2y_coef_00); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_RGB2YUV_COEF_01], cfg->r2y_coef_01); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_RGB2YUV_COEF_02], cfg->r2y_coef_02); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_RGB2YUV_COEF_10], cfg->r2y_coef_10); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_RGB2YUV_COEF_11], cfg->r2y_coef_11); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_RGB2YUV_COEF_12], cfg->r2y_coef_12); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_RGB2YUV_COEF_20], cfg->r2y_coef_20); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_RGB2YUV_COEF_21], cfg->r2y_coef_21); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_RGB2YUV_COEF_22], cfg->r2y_coef_22); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP0_RGB2YUV_COEF_SHIFT], cfg->r2y_coef_shift); + break; + case DEV_HW_MCSC1: + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_RGB2YUV_COEF_00], cfg->r2y_coef_00); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_RGB2YUV_COEF_01], cfg->r2y_coef_01); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_RGB2YUV_COEF_02], cfg->r2y_coef_02); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_RGB2YUV_COEF_10], cfg->r2y_coef_10); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_RGB2YUV_COEF_11], cfg->r2y_coef_11); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_RGB2YUV_COEF_12], cfg->r2y_coef_12); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_RGB2YUV_COEF_20], cfg->r2y_coef_20); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_RGB2YUV_COEF_21], cfg->r2y_coef_21); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_RGB2YUV_COEF_22], cfg->r2y_coef_22); + fimc_is_hw_set_reg(base_addr, &mcsc_regs[MCSC_R_UVSP1_RGB2YUV_COEF_SHIFT], cfg->r2y_coef_shift); + break; + default: + warn_hw("invalid hw_id(%d) for MCSC api\n", hw_id); + break; + } +} + /* DS */ void fimc_is_scaler_set_ds_enable(void __iomem *base_addr, u32 ds_enable) { diff --git a/drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-mcscaler-v2.c b/drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-mcscaler-v2.c index 33c577db429b..59c4954b3eb1 100644 --- a/drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-mcscaler-v2.c +++ b/drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-mcscaler-v2.c @@ -833,6 +833,7 @@ config: ret_internal = fimc_is_hw_mcsc_update_dsvra_register(hw_ip, head, mcs_param, instance, frame->shot); ret_internal = fimc_is_hw_mcsc_update_tdnr_register(hw_ip, frame, param, start_flag); ret_internal = fimc_is_hw_mcsc_update_cac_register(hw_ip, frame, instance); + ret_internal = fimc_is_hw_mcsc_update_uvsp_register(hw_ip, frame, instance); ret_internal = fimc_is_hw_mcsc_update_ysum_register(hw_ip, head, mcs_param, instance, frame->shot); if (ret_internal) { msdbg_hw(2, "ysum cfg is failed\n", instance, hw_ip); @@ -1146,6 +1147,10 @@ static int fimc_is_hw_mcsc_load_setfile(struct fimc_is_hw_ip *hw_ip, u32 instanc return -EINVAL; } } +#if defined(USE_UVSP_CAC) + hw_mcsc->uvsp_ctrl.biquad_a = hw_ip->hardware->cal_info[sensor_position].data[2]; + hw_mcsc->uvsp_ctrl.biquad_b = hw_ip->hardware->cal_info[sensor_position].data[3]; +#endif set_bit(HW_TUNESET, &hw_ip->state); diff --git a/drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-mcscaler-v2.h b/drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-mcscaler-v2.h index 93ab9636f25c..a4484c104bd0 100644 --- a/drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-mcscaler-v2.h +++ b/drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-mcscaler-v2.h @@ -152,6 +152,7 @@ struct fimc_is_hw_mcsc_cap { enum mcsc_cap_enum tdnr; enum mcsc_cap_enum djag; enum mcsc_cap_enum cac; + enum mcsc_cap_enum uvsp; enum mcsc_cap_enum ysum; enum mcsc_cap_enum ds_vra; }; @@ -180,6 +181,8 @@ struct fimc_is_hw_mcsc { enum tdnr_mode cur_tdnr_mode; enum yic_mode yic_en; struct tdnr_configs tdnr_cfgs; + /* for uvsp */ + struct uvsp_ctrl uvsp_ctrl; /* for CAC*/ u32 cac_in; @@ -250,6 +253,8 @@ int fimc_is_hw_mcsc_update_djag_register(struct fimc_is_hw_ip *hw_ip, u32 instance); int fimc_is_hw_mcsc_update_cac_register(struct fimc_is_hw_ip *hw_ip, struct fimc_is_frame *frame, u32 instance); +int fimc_is_hw_mcsc_update_uvsp_register(struct fimc_is_hw_ip *hw_ip, + struct fimc_is_frame *frame, u32 instance); int fimc_is_hw_mcsc_update_ysum_register(struct fimc_is_hw_ip *hw_ip, struct fimc_is_group *head, struct mcs_param *mcs_param, u32 instance, struct camera2_shot *shot); diff --git a/drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-uvsp-cac.c b/drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-uvsp-cac.c index 4c57602f0b8a..85e3a25aa602 100644 --- a/drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-uvsp-cac.c +++ b/drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-uvsp-cac.c @@ -211,3 +211,343 @@ int fimc_is_hw_mcsc_recovery_cac_register(struct fimc_is_hw_ip *hw_ip, return ret; } + +struct ref_ni hw_mcsc_find_ni_idx_for_uvsp(struct fimc_is_hw_ip *hw_ip, + struct uvsp_setfile_contents *uvsp, u32 cur_ni) +{ + struct ref_ni ret_idx = {0, 0}; + struct ref_ni ni_idx_range; + u32 ni_idx; + + for (ni_idx = 0; ni_idx < uvsp->ni_max - 1; ni_idx++) { + ni_idx_range.min = MULTIPLIED_10(uvsp->ni_vals[ni_idx]); + ni_idx_range.max = MULTIPLIED_10(uvsp->ni_vals[ni_idx + 1]); + + if (ni_idx_range.min < cur_ni && cur_ni < ni_idx_range.max) { + ret_idx.min = ni_idx; + ret_idx.max = ni_idx + 1; + break; + } else if (cur_ni == ni_idx_range.min) { + ret_idx.min = ni_idx; + ret_idx.max = ni_idx; + break; + } else if (cur_ni == ni_idx_range.max) { + ret_idx.min = ni_idx + 1; + ret_idx.max = ni_idx + 1; + break; + } + } + + sdbg_hw(2, "[UVSP] find_ni_idx: cur_ni(%d), ni[%d, %d], idx[%d, %d]\n", hw_ip, + uvsp->ni_vals[ret_idx.min], uvsp->ni_vals[ret_idx.max], + ret_idx.min, ret_idx.max); + + return ret_idx; +} + +void hw_mcsc_calc_uvsp_r2y_coef_cfg(struct uvsp_cfg_by_ni *uvsp_cfg, + struct uvsp_cfg_by_ni *cfg_min, struct uvsp_cfg_by_ni *cfg_max, + struct ref_ni *ni_idx, u32 cur_ni) +{ + struct uvsp_r2y_coef_cfg *min, *max, *cfg; + + min = &cfg_min->r2y_coef_cfg; + max = &cfg_max->r2y_coef_cfg; + cfg = &uvsp_cfg->r2y_coef_cfg; + + cfg->r2y_coef_00 = GET_LNR_INTRPL( + min->r2y_coef_00, max->r2y_coef_00, + ni_idx->min, ni_idx->max, cur_ni); + cfg->r2y_coef_01 = GET_LNR_INTRPL( + min->r2y_coef_01, max->r2y_coef_01, + ni_idx->min, ni_idx->max, cur_ni); + cfg->r2y_coef_02 = GET_LNR_INTRPL( + min->r2y_coef_02, max->r2y_coef_02, + ni_idx->min, ni_idx->max, cur_ni); + cfg->r2y_coef_10 = GET_LNR_INTRPL( + min->r2y_coef_10, max->r2y_coef_10, + ni_idx->min, ni_idx->max, cur_ni); + cfg->r2y_coef_11 = GET_LNR_INTRPL( + min->r2y_coef_11, max->r2y_coef_11, + ni_idx->min, ni_idx->max, cur_ni); + cfg->r2y_coef_12 = GET_LNR_INTRPL( + min->r2y_coef_12, max->r2y_coef_12, + ni_idx->min, ni_idx->max, cur_ni); + cfg->r2y_coef_20 = GET_LNR_INTRPL( + min->r2y_coef_20, max->r2y_coef_20, + ni_idx->min, ni_idx->max, cur_ni); + cfg->r2y_coef_21 = GET_LNR_INTRPL( + min->r2y_coef_21, max->r2y_coef_21, + ni_idx->min, ni_idx->max, cur_ni); + cfg->r2y_coef_22 = GET_LNR_INTRPL( + min->r2y_coef_22, max->r2y_coef_22, + ni_idx->min, ni_idx->max, cur_ni); + cfg->r2y_coef_shift = GET_LNR_INTRPL( + min->r2y_coef_shift, max->r2y_coef_shift, + ni_idx->min, ni_idx->max, cur_ni); +} + +void hw_mcsc_calc_uvsp_desat_cfg(struct uvsp_cfg_by_ni *uvsp_cfg, + struct uvsp_cfg_by_ni *cfg_min, struct uvsp_cfg_by_ni *cfg_max, + struct ref_ni *ni_idx, u32 cur_ni) +{ + struct uvsp_desat_cfg *min, *max, *cfg; + + min = &cfg_min->desat_cfg; + max = &cfg_max->desat_cfg; + cfg = &uvsp_cfg->desat_cfg; + + cfg->ctrl_en = GET_LNR_INTRPL( + min->ctrl_en, max->ctrl_en, + ni_idx->min, ni_idx->max, cur_ni); + cfg->ctrl_singleSide = GET_LNR_INTRPL( + min->ctrl_singleSide, max->ctrl_singleSide, + ni_idx->min, ni_idx->max, cur_ni); + cfg->ctrl_luma_offset = GET_LNR_INTRPL( + min->ctrl_luma_offset, max->ctrl_luma_offset, + ni_idx->min, ni_idx->max, cur_ni); + cfg->ctrl_gain_offset = GET_LNR_INTRPL( + min->ctrl_gain_offset, max->ctrl_gain_offset, + ni_idx->min, ni_idx->max, cur_ni); + + cfg->y_shift = GET_LNR_INTRPL( + min->y_shift, max->y_shift, + ni_idx->min, ni_idx->max, cur_ni); + cfg->y_luma_max = GET_LNR_INTRPL( + min->y_luma_max, max->y_luma_max, + ni_idx->min, ni_idx->max, cur_ni); + cfg->u_low = GET_LNR_INTRPL( + min->u_low, max->u_low, + ni_idx->min, ni_idx->max, cur_ni); + cfg->u_high = GET_LNR_INTRPL( + min->u_high, max->u_high, + ni_idx->min, ni_idx->max, cur_ni); + cfg->v_low = GET_LNR_INTRPL( + min->v_low, max->v_low, + ni_idx->min, ni_idx->max, cur_ni); + cfg->v_high = GET_LNR_INTRPL( + min->v_high, max->v_high, + ni_idx->min, ni_idx->max, cur_ni); +} + +void hw_mcsc_calc_uvsp_offset_cfg(struct uvsp_cfg_by_ni *uvsp_cfg, + struct uvsp_cfg_by_ni *cfg_min, struct uvsp_cfg_by_ni *cfg_max, + struct ref_ni *ni_idx, u32 cur_ni) +{ + struct uvsp_offset_cfg *min, *max, *cfg; + + min = &cfg_min->offset_cfg; + max = &cfg_max->offset_cfg; + cfg = &uvsp_cfg->offset_cfg; + + cfg->r = GET_LNR_INTRPL( + min->r, max->r, + ni_idx->min, ni_idx->max, cur_ni); + cfg->g = GET_LNR_INTRPL( + min->g, max->g, + ni_idx->min, ni_idx->max, cur_ni); + cfg->b = GET_LNR_INTRPL( + min->b, max->b, + ni_idx->min, ni_idx->max, cur_ni); +} + +void hw_mcsc_calc_uvsp_pedestal_cfg(struct uvsp_cfg_by_ni *uvsp_cfg, + struct uvsp_cfg_by_ni *cfg_min, struct uvsp_cfg_by_ni *cfg_max, + struct ref_ni *ni_idx, u32 cur_ni) +{ + struct uvsp_pedestal_cfg *min, *max, *cfg; + + min = &cfg_min->pedestal_cfg; + max = &cfg_max->pedestal_cfg; + cfg = &uvsp_cfg->pedestal_cfg; + + cfg->r = GET_LNR_INTRPL( + min->r, max->r, + ni_idx->min, ni_idx->max, cur_ni); + cfg->g = GET_LNR_INTRPL( + min->g, max->g, + ni_idx->min, ni_idx->max, cur_ni); + cfg->b = GET_LNR_INTRPL( + min->b, max->b, + ni_idx->min, ni_idx->max, cur_ni); +} + +void hw_mcsc_calc_uvsp_radial_cfg(struct uvsp_cfg_by_ni *uvsp_cfg, + struct uvsp_cfg_by_ni *cfg_min, struct uvsp_cfg_by_ni *cfg_max, + struct ref_ni *ni_idx, u32 cur_ni) +{ + struct uvsp_radial_cfg *min, *max, *cfg; + + min = &cfg_min->radial_cfg; + max = &cfg_max->radial_cfg; + cfg = &uvsp_cfg->radial_cfg; + + cfg->biquad_shift = GET_LNR_INTRPL( + min->biquad_shift, max->biquad_shift, + ni_idx->min, ni_idx->max, cur_ni); + + cfg->random_en = GET_LNR_INTRPL( + min->random_en, max->random_en, + ni_idx->min, ni_idx->max, cur_ni); + cfg->random_power = GET_LNR_INTRPL( + min->random_power, max->random_power, + ni_idx->min, ni_idx->max, cur_ni); + cfg->refine_en = GET_LNR_INTRPL( + min->refine_en, max->refine_en, + ni_idx->min, ni_idx->max, cur_ni); + cfg->refine_luma_min = GET_LNR_INTRPL( + min->refine_luma_min, max->refine_luma_min, + ni_idx->min, ni_idx->max, cur_ni); + cfg->refine_denom = GET_LNR_INTRPL( + min->refine_denom, max->refine_denom, + ni_idx->min, ni_idx->max, cur_ni); + + cfg->alpha_gain_add_en = GET_LNR_INTRPL( + min->alpha_gain_add_en, max->alpha_gain_add_en, + ni_idx->min, ni_idx->max, cur_ni); + cfg->alpha_green_en = GET_LNR_INTRPL( + min->alpha_green_en, max->alpha_green_en, + ni_idx->min, ni_idx->max, cur_ni); + cfg->alpha_r = GET_LNR_INTRPL( + min->alpha_r, max->alpha_r, + ni_idx->min, ni_idx->max, cur_ni); + cfg->alpha_g = GET_LNR_INTRPL( + min->alpha_g, max->alpha_g, + ni_idx->min, ni_idx->max, cur_ni); + cfg->alpha_b = GET_LNR_INTRPL( + min->alpha_b, max->alpha_b, + ni_idx->min, ni_idx->max, cur_ni); +} + +void hw_mcsc_calc_uvsp_param_by_ni(struct fimc_is_hw_ip *hw_ip, + struct uvsp_setfile_contents *uvsp, u32 cur_ni) +{ + struct ref_ni ni_range, ni_idx; + struct uvsp_cfg_by_ni uvsp_cfg, cfg_max, cfg_min; + + ni_range.min = MULTIPLIED_10(uvsp->ni_vals[0]); + ni_range.max = MULTIPLIED_10(uvsp->ni_vals[uvsp->ni_max - 1]); + + if (cur_ni <= ni_range.min) { + sdbg_hw(2, "[UVSP] cur_ni(%d) <= ni_range.min(%d)\n", hw_ip, cur_ni, ni_range.min); + ni_idx.min = 0; + ni_idx.max = 0; + } else if (cur_ni >= ni_range.max) { + sdbg_hw(2, "[UVSP] cur_ni(%d) >= ni_range.max(%d)\n", hw_ip, cur_ni, ni_range.max); + ni_idx.min = uvsp->ni_max - 1; + ni_idx.max = uvsp->ni_max - 1; + } else { + ni_idx = hw_mcsc_find_ni_idx_for_uvsp(hw_ip, uvsp, cur_ni); + } + + cfg_min = uvsp->cfgs[ni_idx.min]; + cfg_max = uvsp->cfgs[ni_idx.max]; + hw_mcsc_calc_uvsp_radial_cfg(&uvsp_cfg, &cfg_min, &cfg_max, &ni_idx, cur_ni); + hw_mcsc_calc_uvsp_pedestal_cfg(&uvsp_cfg, &cfg_min, &cfg_max, &ni_idx, cur_ni); + hw_mcsc_calc_uvsp_offset_cfg(&uvsp_cfg, &cfg_min, &cfg_max, &ni_idx, cur_ni); + hw_mcsc_calc_uvsp_desat_cfg(&uvsp_cfg, &cfg_min, &cfg_max, &ni_idx, cur_ni); + hw_mcsc_calc_uvsp_r2y_coef_cfg(&uvsp_cfg, &cfg_min, &cfg_max, &ni_idx, cur_ni); + + fimc_is_scaler_set_uvsp_radial_cfg(hw_ip->regs, hw_ip->id, &uvsp_cfg.radial_cfg); + fimc_is_scaler_set_uvsp_pedestal_cfg(hw_ip->regs, hw_ip->id, &uvsp_cfg.pedestal_cfg); + fimc_is_scaler_set_uvsp_offset_cfg(hw_ip->regs, hw_ip->id, &uvsp_cfg.offset_cfg); + fimc_is_scaler_set_uvsp_r2y_coef_cfg(hw_ip->regs, hw_ip->id, &uvsp_cfg.r2y_coef_cfg); + fimc_is_scaler_set_uvsp_enable(hw_ip->regs, hw_ip->id, 1); +} + +void hw_mcsc_calc_uvsp_radial_ctrl(struct fimc_is_hw_ip *hw_ip, + struct fimc_is_hw_mcsc *hw_mcsc, struct fimc_is_frame *frame, + struct cal_info *cal_info, u32 instance) +{ + struct uvsp_ctrl *uvsp_ctrl; + struct camera2_shot_ext *shot_ext; + u32 lsc_center_x, lsc_center_y; + + lsc_center_x = cal_info->data[0]; + lsc_center_y = cal_info->data[1]; + uvsp_ctrl->biquad_a = cal_info->data[2]; + uvsp_ctrl->biquad_b = cal_info->data[3]; + sdbg_hw(2, "[UVSP][F:%d]: lsc_center_x,y(%d,%d), uvsp_ctrl->biquad_a,b(%d,%d)\n", + hw_ip, __func__, frame->fcount, lsc_center_x, lsc_center_y, + uvsp_ctrl->biquad_a, uvsp_ctrl->biquad_b); + + shot_ext = frame->shot_ext; + if (!frame->shot_ext) { + sdbg_hw(2, "___carrotsm:[F:%d] shot_ext(NULL)\n", hw_ip, __func__); + fimc_is_scaler_set_uvsp_enable(hw_ip->regs, hw_ip->id, 0); + return; + } + + sdbg_hw(2, "[UVSP][F:%d]: shot >> binning_r(%d,%d), crop_taa(%d,%d), bds(%d,%d)\n", + hw_ip, __func__, frame->fcount, + shot_ext->binning_ratio_x, shot_ext->binning_ratio_y, + shot_ext->crop_taa_x, shot_ext->crop_taa_y, + shot_ext->bds_ratio_x, shot_ext->bds_ratio_y); + + uvsp_ctrl = &hw_mcsc->uvsp_ctrl; + uvsp_ctrl->binning_x = shot_ext->binning_ratio_x * shot_ext->bds_ratio_x * 1024; + uvsp_ctrl->binning_y = shot_ext->binning_ratio_y * shot_ext->bds_ratio_y * 1024; + if (shot_ext->bds_ratio_x && shot_ext->bds_ratio_y) { + shot_ext->bds_ratio_x = 1; + shot_ext->bds_ratio_y = 1; + } + uvsp_ctrl->radial_center_x = (u32)((lsc_center_x - shot_ext->crop_taa_x) / shot_ext->bds_ratio_x); + uvsp_ctrl->radial_center_y = (u32)((lsc_center_y - shot_ext->crop_taa_y) / shot_ext->bds_ratio_y); + + fimc_is_scaler_set_uvsp_radial_ctrl(hw_ip->regs, hw_ip->id, uvsp_ctrl); + sdbg_hw(2, "[UVSP][F:%d]: uvsp_ctrl >> binning(%d,%d), r_center(%d,%d), biquad(%d,%d)\n", + hw_ip, __func__, frame->fcount, uvsp_ctrl->binning_x, uvsp_ctrl->binning_y, + uvsp_ctrl->radial_center_x, uvsp_ctrl->radial_center_y, + uvsp_ctrl->biquad_a, uvsp_ctrl->biquad_b); +} + +int fimc_is_hw_mcsc_update_uvsp_register(struct fimc_is_hw_ip *hw_ip, + struct fimc_is_frame *frame, u32 instance) +{ + int ret = 0; + struct fimc_is_hw_mcsc *hw_mcsc; + struct fimc_is_hw_mcsc_cap *cap; + struct hw_mcsc_setfile *setfile; + struct uvsp_setfile_contents *uvsp; + struct cal_info *cal_info; + enum exynos_sensor_position sensor_position; + u32 ni; + + hw_mcsc = (struct fimc_is_hw_mcsc *)hw_ip->priv_info; + cap = GET_MCSC_HW_CAP(hw_ip); + + if (cap->uvsp != MCSC_CAP_SUPPORT) + return ret; + + sensor_position = hw_ip->hardware->sensor_position[instance]; + setfile = hw_mcsc->cur_setfile[sensor_position]; + cal_info = &hw_ip->hardware->cal_info[sensor_position]; + + sdbg_hw(10, "TEST: get_lnr_intprl(11, 20, 1, 1, 3) = %d\n", + hw_ip, GET_LNR_INTRPL(11, 20, 1, 1, 3)); + +#ifdef LHM_ENABLE_EVT0 + return ret; +#endif + /* calculate cac parameters */ +#ifdef FIXED_TDNR_NOISE_INDEX + ni = FIXED_TDNR_NOISE_INDEX_VALUE; +#else + ni = frame->noise_idx; +#endif + if (hw_mcsc->cur_ni == ni) + goto exit; + + hw_mcsc_calc_uvsp_radial_ctrl(hw_ip, hw_mcsc, frame, cal_info, instance); +#if defined(USE_UVSP_CAC) + uvsp = &setfile->uvsp; + hw_mcsc_calc_uvsp_param_by_ni(hw_ip, uvsp, ni); +#endif + sdbg_hw(2, "[UVSP][F:%d]: ni(%d)\n", + hw_ip, __func__, frame->fcount, ni); + +exit: + hw_mcsc->cur_ni = ni; + + return 0; +} diff --git a/drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-uvsp-cac.h b/drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-uvsp-cac.h index 3a465c719c2b..4f54e5a20bfc 100644 --- a/drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-uvsp-cac.h +++ b/drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-uvsp-cac.h @@ -36,7 +36,18 @@ struct cac_setfile_contents { struct cac_cfg_by_ni cfgs[CAC_MAX_NI_DEPENDED_CFG]; }; -#define UVSP_MAX_NI_DEPENDED_CONFIGS (6) +#define UVSP_MAX_NI_DEPENDED_CONFIGS (9) +struct uvsp_ctrl { + u32 binning_x; + u32 binning_y; + + u32 radial_center_x; + u32 radial_center_y; + + u32 biquad_a; + u32 biquad_b; +}; + struct uvsp_radial_cfg { u32 biquad_shift; -- 2.20.1