diff options
Diffstat (limited to 'drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c')
-rw-r--r-- | drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c | 1038 |
1 files changed, 0 insertions, 1038 deletions
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c deleted file mode 100644 index 110473c30577..000000000000 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c +++ /dev/null @@ -1,1038 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (C) 2012 Texas Instruments Inc - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Contributors: - * Manjunath Hadli <manjunath.hadli@ti.com> - * Prabhakar Lad <prabhakar.lad@ti.com> - */ - -#include "dm365_ipipe_hw.h" - -#define IPIPE_MODE_CONTINUOUS 0 -#define IPIPE_MODE_SINGLE_SHOT 1 - -static void ipipe_clock_enable(void __iomem *base_addr) -{ - /* enable IPIPE MMR for register write access */ - regw_ip(base_addr, IPIPE_GCK_MMR_DEFAULT, IPIPE_GCK_MMR); - - /* enable the clock wb,cfa,dfc,d2f,pre modules */ - regw_ip(base_addr, IPIPE_GCK_PIX_DEFAULT, IPIPE_GCK_PIX); -} - -static void -rsz_set_common_params(void __iomem *rsz_base, struct resizer_params *params) -{ - struct rsz_common_params *rsz_common = ¶ms->rsz_common; - u32 val; - - /* Set mode */ - regw_rsz(rsz_base, params->oper_mode, RSZ_SRC_MODE); - - /* data source selection and bypass */ - val = (rsz_common->passthrough << RSZ_BYPASS_SHIFT) | - rsz_common->source; - regw_rsz(rsz_base, val, RSZ_SRC_FMT0); - - /* src image selection */ - val = (rsz_common->raw_flip & 1) | - (rsz_common->src_img_fmt << RSZ_SRC_IMG_FMT_SHIFT) | - ((rsz_common->y_c & 1) << RSZ_SRC_Y_C_SEL_SHIFT); - regw_rsz(rsz_base, val, RSZ_SRC_FMT1); - - regw_rsz(rsz_base, rsz_common->vps & IPIPE_RSZ_VPS_MASK, RSZ_SRC_VPS); - regw_rsz(rsz_base, rsz_common->hps & IPIPE_RSZ_HPS_MASK, RSZ_SRC_HPS); - regw_rsz(rsz_base, rsz_common->vsz & IPIPE_RSZ_VSZ_MASK, RSZ_SRC_VSZ); - regw_rsz(rsz_base, rsz_common->hsz & IPIPE_RSZ_HSZ_MASK, RSZ_SRC_HSZ); - regw_rsz(rsz_base, rsz_common->yuv_y_min, RSZ_YUV_Y_MIN); - regw_rsz(rsz_base, rsz_common->yuv_y_max, RSZ_YUV_Y_MAX); - regw_rsz(rsz_base, rsz_common->yuv_c_min, RSZ_YUV_C_MIN); - regw_rsz(rsz_base, rsz_common->yuv_c_max, RSZ_YUV_C_MAX); - /* chromatic position */ - regw_rsz(rsz_base, rsz_common->out_chr_pos, RSZ_YUV_PHS); -} - -static void -rsz_set_rsz_regs(void __iomem *rsz_base, unsigned int rsz_id, - struct resizer_params *params) -{ - struct resizer_scale_param *rsc_params; - struct rsz_ext_mem_param *ext_mem; - struct resizer_rgb *rgb; - u32 reg_base; - u32 val; - - rsc_params = ¶ms->rsz_rsc_param[rsz_id]; - rgb = ¶ms->rsz2rgb[rsz_id]; - ext_mem = ¶ms->ext_mem_param[rsz_id]; - - if (rsz_id == RSZ_A) { - val = rsc_params->h_flip << RSZA_H_FLIP_SHIFT; - val |= rsc_params->v_flip << RSZA_V_FLIP_SHIFT; - reg_base = RSZ_EN_A; - } else { - val = rsc_params->h_flip << RSZB_H_FLIP_SHIFT; - val |= rsc_params->v_flip << RSZB_V_FLIP_SHIFT; - reg_base = RSZ_EN_B; - } - /* update flip settings */ - regw_rsz(rsz_base, val, RSZ_SEQ); - - regw_rsz(rsz_base, params->oper_mode, reg_base + RSZ_MODE); - - val = (rsc_params->cen << RSZ_CEN_SHIFT) | rsc_params->yen; - regw_rsz(rsz_base, val, reg_base + RSZ_420); - - regw_rsz(rsz_base, rsc_params->i_vps & RSZ_VPS_MASK, - reg_base + RSZ_I_VPS); - regw_rsz(rsz_base, rsc_params->i_hps & RSZ_HPS_MASK, - reg_base + RSZ_I_HPS); - regw_rsz(rsz_base, rsc_params->o_vsz & RSZ_O_VSZ_MASK, - reg_base + RSZ_O_VSZ); - regw_rsz(rsz_base, rsc_params->o_hsz & RSZ_O_HSZ_MASK, - reg_base + RSZ_O_HSZ); - regw_rsz(rsz_base, rsc_params->v_phs_y & RSZ_V_PHS_MASK, - reg_base + RSZ_V_PHS_Y); - regw_rsz(rsz_base, rsc_params->v_phs_c & RSZ_V_PHS_MASK, - reg_base + RSZ_V_PHS_C); - - /* keep this additional adjustment to zero for now */ - regw_rsz(rsz_base, rsc_params->v_dif & RSZ_V_DIF_MASK, - reg_base + RSZ_V_DIF); - - val = (rsc_params->v_typ_y & 1) | - ((rsc_params->v_typ_c & 1) << RSZ_TYP_C_SHIFT); - regw_rsz(rsz_base, val, reg_base + RSZ_V_TYP); - - val = (rsc_params->v_lpf_int_y & RSZ_LPF_INT_MASK) | - ((rsc_params->v_lpf_int_c & RSZ_LPF_INT_MASK) << - RSZ_LPF_INT_C_SHIFT); - regw_rsz(rsz_base, val, reg_base + RSZ_V_LPF); - - regw_rsz(rsz_base, rsc_params->h_phs & - RSZ_H_PHS_MASK, reg_base + RSZ_H_PHS); - - regw_rsz(rsz_base, 0, reg_base + RSZ_H_PHS_ADJ); - regw_rsz(rsz_base, rsc_params->h_dif & - RSZ_H_DIF_MASK, reg_base + RSZ_H_DIF); - - val = (rsc_params->h_typ_y & 1) | - ((rsc_params->h_typ_c & 1) << RSZ_TYP_C_SHIFT); - regw_rsz(rsz_base, val, reg_base + RSZ_H_TYP); - - val = (rsc_params->h_lpf_int_y & RSZ_LPF_INT_MASK) | - ((rsc_params->h_lpf_int_c & RSZ_LPF_INT_MASK) << - RSZ_LPF_INT_C_SHIFT); - regw_rsz(rsz_base, val, reg_base + RSZ_H_LPF); - - regw_rsz(rsz_base, rsc_params->dscale_en & 1, reg_base + RSZ_DWN_EN); - - val = (rsc_params->h_dscale_ave_sz & RSZ_DWN_SCALE_AV_SZ_MASK) | - ((rsc_params->v_dscale_ave_sz & RSZ_DWN_SCALE_AV_SZ_MASK) << - RSZ_DWN_SCALE_AV_SZ_V_SHIFT); - regw_rsz(rsz_base, val, reg_base + RSZ_DWN_AV); - - /* setting rgb conversion parameters */ - regw_rsz(rsz_base, rgb->rgb_en, reg_base + RSZ_RGB_EN); - - val = (rgb->rgb_typ << RSZ_RGB_TYP_SHIFT) | - (rgb->rgb_msk0 << RSZ_RGB_MSK0_SHIFT) | - (rgb->rgb_msk1 << RSZ_RGB_MSK1_SHIFT); - regw_rsz(rsz_base, val, reg_base + RSZ_RGB_TYP); - - regw_rsz(rsz_base, rgb->rgb_alpha_val & RSZ_RGB_ALPHA_MASK, - reg_base + RSZ_RGB_BLD); - - /* setting external memory parameters */ - regw_rsz(rsz_base, ext_mem->rsz_sdr_oft_y, reg_base + RSZ_SDR_Y_OFT); - regw_rsz(rsz_base, ext_mem->rsz_sdr_ptr_s_y, - reg_base + RSZ_SDR_Y_PTR_S); - regw_rsz(rsz_base, ext_mem->rsz_sdr_ptr_e_y, - reg_base + RSZ_SDR_Y_PTR_E); - regw_rsz(rsz_base, ext_mem->rsz_sdr_oft_c, reg_base + RSZ_SDR_C_OFT); - regw_rsz(rsz_base, ext_mem->rsz_sdr_ptr_s_c, - reg_base + RSZ_SDR_C_PTR_S); - regw_rsz(rsz_base, (ext_mem->rsz_sdr_ptr_e_c >> 1), - reg_base + RSZ_SDR_C_PTR_E); -} - -/*set the registers of either RSZ0 or RSZ1 */ -static void -ipipe_setup_resizer(void __iomem *rsz_base, struct resizer_params *params) -{ - /* enable MMR gate to write to Resizer */ - regw_rsz(rsz_base, 1, RSZ_GCK_MMR); - - /* Enable resizer if it is not in bypass mode */ - if (params->rsz_common.passthrough) - regw_rsz(rsz_base, 0, RSZ_GCK_SDR); - else - regw_rsz(rsz_base, 1, RSZ_GCK_SDR); - - rsz_set_common_params(rsz_base, params); - - regw_rsz(rsz_base, params->rsz_en[RSZ_A], RSZ_EN_A); - - if (params->rsz_en[RSZ_A]) - /*setting rescale parameters */ - rsz_set_rsz_regs(rsz_base, RSZ_A, params); - - regw_rsz(rsz_base, params->rsz_en[RSZ_B], RSZ_EN_B); - - if (params->rsz_en[RSZ_B]) - rsz_set_rsz_regs(rsz_base, RSZ_B, params); -} - -static u32 ipipe_get_color_pat(u32 pix) -{ - switch (pix) { - case MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8: - case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8: - case MEDIA_BUS_FMT_SGRBG12_1X12: - return ipipe_sgrbg_pattern; - - default: - return ipipe_srggb_pattern; - } -} - -static int ipipe_get_data_path(struct vpfe_ipipe_device *ipipe) -{ - u32 temp_pix_fmt; - - switch (ipipe->formats[IPIPE_PAD_SINK].code) { - case MEDIA_BUS_FMT_SBGGR8_1X8: - case MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8: - case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8: - case MEDIA_BUS_FMT_SGRBG12_1X12: - temp_pix_fmt = MEDIA_BUS_FMT_SGRBG12_1X12; - break; - - default: - temp_pix_fmt = MEDIA_BUS_FMT_UYVY8_2X8; - } - - if (temp_pix_fmt == MEDIA_BUS_FMT_SGRBG12_1X12) { - if (ipipe->formats[IPIPE_PAD_SOURCE].code == - MEDIA_BUS_FMT_SGRBG12_1X12) - return IPIPE_RAW2RAW; - return IPIPE_RAW2YUV; - } - - return IPIPE_YUV2YUV; -} - -static int get_ipipe_mode(struct vpfe_ipipe_device *ipipe) -{ - struct vpfe_device *vpfe_dev = to_vpfe_device(ipipe); - u16 ipipeif_sink = vpfe_dev->vpfe_ipipeif.input; - - if (ipipeif_sink == IPIPEIF_INPUT_MEMORY) - return IPIPE_MODE_SINGLE_SHOT; - if (ipipeif_sink == IPIPEIF_INPUT_ISIF) - return IPIPE_MODE_CONTINUOUS; - - return -EINVAL; -} - -int config_ipipe_hw(struct vpfe_ipipe_device *ipipe) -{ - struct vpfe_ipipe_input_config *config = &ipipe->config.input_config; - void __iomem *ipipe_base = ipipe->base_addr; - struct v4l2_mbus_framefmt *outformat; - u32 color_pat; - int ipipe_mode; - u32 data_path; - - /* enable clock to IPIPE */ - vpss_enable_clock(VPSS_IPIPE_CLOCK, 1); - ipipe_clock_enable(ipipe_base); - - if (ipipe->input == IPIPE_INPUT_NONE) { - regw_ip(ipipe_base, 0, IPIPE_SRC_EN); - return 0; - } - - ipipe_mode = get_ipipe_mode(ipipe); - if (ipipe_mode < 0) { - pr_err("Failed to get ipipe mode"); - return -EINVAL; - } - regw_ip(ipipe_base, ipipe_mode, IPIPE_SRC_MODE); - - data_path = ipipe_get_data_path(ipipe); - regw_ip(ipipe_base, data_path, IPIPE_SRC_FMT); - - regw_ip(ipipe_base, config->vst & IPIPE_RSZ_VPS_MASK, IPIPE_SRC_VPS); - regw_ip(ipipe_base, config->hst & IPIPE_RSZ_HPS_MASK, IPIPE_SRC_HPS); - - outformat = &ipipe->formats[IPIPE_PAD_SOURCE]; - regw_ip(ipipe_base, (outformat->height + 1) & IPIPE_RSZ_VSZ_MASK, - IPIPE_SRC_VSZ); - regw_ip(ipipe_base, (outformat->width + 1) & IPIPE_RSZ_HSZ_MASK, - IPIPE_SRC_HSZ); - - if (data_path == IPIPE_RAW2YUV || - data_path == IPIPE_RAW2RAW) { - color_pat = - ipipe_get_color_pat(ipipe->formats[IPIPE_PAD_SINK].code); - regw_ip(ipipe_base, color_pat, IPIPE_SRC_COL); - } - - return 0; -} - -/* - * config_rsz_hw() - Performs hardware setup of resizer. - */ -int config_rsz_hw(struct vpfe_resizer_device *resizer, - struct resizer_params *config) -{ - struct vpfe_device *vpfe_dev = to_vpfe_device(resizer); - void __iomem *ipipe_base = vpfe_dev->vpfe_ipipe.base_addr; - void __iomem *rsz_base = vpfe_dev->vpfe_resizer.base_addr; - - /* enable VPSS clock */ - vpss_enable_clock(VPSS_IPIPE_CLOCK, 1); - ipipe_clock_enable(ipipe_base); - - ipipe_setup_resizer(rsz_base, config); - - return 0; -} - -static void -rsz_set_y_address(void __iomem *rsz_base, unsigned int address, - unsigned int offset) -{ - u32 val; - - val = address & SET_LOW_ADDR; - regw_rsz(rsz_base, val, offset + RSZ_SDR_Y_BAD_L); - regw_rsz(rsz_base, val, offset + RSZ_SDR_Y_SAD_L); - - val = (address & SET_HIGH_ADDR) >> 16; - regw_rsz(rsz_base, val, offset + RSZ_SDR_Y_BAD_H); - regw_rsz(rsz_base, val, offset + RSZ_SDR_Y_SAD_H); -} - -static void -rsz_set_c_address(void __iomem *rsz_base, unsigned int address, - unsigned int offset) -{ - u32 val; - - val = address & SET_LOW_ADDR; - regw_rsz(rsz_base, val, offset + RSZ_SDR_C_BAD_L); - regw_rsz(rsz_base, val, offset + RSZ_SDR_C_SAD_L); - - val = (address & SET_HIGH_ADDR) >> 16; - regw_rsz(rsz_base, val, offset + RSZ_SDR_C_BAD_H); - regw_rsz(rsz_base, val, offset + RSZ_SDR_C_SAD_H); -} - -/* - * resizer_set_outaddr() - set the address for given resize_no - * @rsz_base: resizer base address - * @params: pointer to ipipe_params structure - * @resize_no: 0 - Resizer-A, 1 - Resizer B - * @address: the address to set - */ -int -resizer_set_outaddr(void __iomem *rsz_base, struct resizer_params *params, - int resize_no, unsigned int address) -{ - struct resizer_scale_param *rsc_param; - struct rsz_ext_mem_param *mem_param; - struct rsz_common_params *rsz_common; - unsigned int rsz_start_add; - unsigned int val; - - if (resize_no != RSZ_A && resize_no != RSZ_B) - return -EINVAL; - - mem_param = ¶ms->ext_mem_param[resize_no]; - rsc_param = ¶ms->rsz_rsc_param[resize_no]; - rsz_common = ¶ms->rsz_common; - - if (resize_no == RSZ_A) - rsz_start_add = RSZ_EN_A; - else - rsz_start_add = RSZ_EN_B; - - /* y_c = 0 for y, = 1 for c */ - if (rsz_common->src_img_fmt == RSZ_IMG_420) { - if (rsz_common->y_c) { - /* C channel */ - val = address + mem_param->flip_ofst_c; - rsz_set_c_address(rsz_base, val, rsz_start_add); - } else { - val = address + mem_param->flip_ofst_y; - rsz_set_y_address(rsz_base, val, rsz_start_add); - } - } else { - if (rsc_param->cen && rsc_param->yen) { - /* 420 */ - val = address + mem_param->c_offset + - mem_param->flip_ofst_c + - mem_param->user_y_ofst + - mem_param->user_c_ofst; - if (resize_no == RSZ_B) - val += - params->ext_mem_param[RSZ_A].user_y_ofst + - params->ext_mem_param[RSZ_A].user_c_ofst; - /* set C address */ - rsz_set_c_address(rsz_base, val, rsz_start_add); - } - val = address + mem_param->flip_ofst_y + mem_param->user_y_ofst; - if (resize_no == RSZ_B) - val += params->ext_mem_param[RSZ_A].user_y_ofst + - params->ext_mem_param[RSZ_A].user_c_ofst; - /* set Y address */ - rsz_set_y_address(rsz_base, val, rsz_start_add); - } - /* resizer must be enabled */ - regw_rsz(rsz_base, params->rsz_en[resize_no], rsz_start_add); - - return 0; -} - -void -ipipe_set_lutdpc_regs(void __iomem *base_addr, void __iomem *isp5_base_addr, - struct vpfe_ipipe_lutdpc *dpc) -{ - u32 max_tbl_size = LUT_DPC_MAX_SIZE >> 1; - u32 lut_start_addr = DPC_TB0_START_ADDR; - u32 val; - u32 count; - - ipipe_clock_enable(base_addr); - regw_ip(base_addr, dpc->en, DPC_LUT_EN); - - if (dpc->en != 1) - return; - - val = LUTDPC_TBL_256_EN | (dpc->repl_white & 1); - regw_ip(base_addr, val, DPC_LUT_SEL); - regw_ip(base_addr, LUT_DPC_START_ADDR, DPC_LUT_ADR); - regw_ip(base_addr, dpc->dpc_size, DPC_LUT_SIZ & LUT_DPC_SIZE_MASK); - - for (count = 0; count < dpc->dpc_size; count++) { - if (count >= max_tbl_size) - lut_start_addr = DPC_TB1_START_ADDR; - val = (dpc->table[count].horz_pos & LUT_DPC_H_POS_MASK) | - ((dpc->table[count].vert_pos & LUT_DPC_V_POS_MASK) << - LUT_DPC_V_POS_SHIFT) | (dpc->table[count].method << - LUT_DPC_CORR_METH_SHIFT); - w_ip_table(isp5_base_addr, val, (lut_start_addr + - ((count % max_tbl_size) << 2))); - } -} - -static void -set_dpc_thresholds(void __iomem *base_addr, - struct vpfe_ipipe_otfdpc_2_0_cfg *dpc_thr) -{ - regw_ip(base_addr, dpc_thr->corr_thr.r & OTFDPC_DPC2_THR_MASK, - DPC_OTF_2C_THR_R); - regw_ip(base_addr, dpc_thr->corr_thr.gr & OTFDPC_DPC2_THR_MASK, - DPC_OTF_2C_THR_GR); - regw_ip(base_addr, dpc_thr->corr_thr.gb & OTFDPC_DPC2_THR_MASK, - DPC_OTF_2C_THR_GB); - regw_ip(base_addr, dpc_thr->corr_thr.b & OTFDPC_DPC2_THR_MASK, - DPC_OTF_2C_THR_B); - regw_ip(base_addr, dpc_thr->det_thr.r & OTFDPC_DPC2_THR_MASK, - DPC_OTF_2D_THR_R); - regw_ip(base_addr, dpc_thr->det_thr.gr & OTFDPC_DPC2_THR_MASK, - DPC_OTF_2D_THR_GR); - regw_ip(base_addr, dpc_thr->det_thr.gb & OTFDPC_DPC2_THR_MASK, - DPC_OTF_2D_THR_GB); - regw_ip(base_addr, dpc_thr->det_thr.b & OTFDPC_DPC2_THR_MASK, - DPC_OTF_2D_THR_B); -} - -void ipipe_set_otfdpc_regs(void __iomem *base_addr, - struct vpfe_ipipe_otfdpc *otfdpc) -{ - struct vpfe_ipipe_otfdpc_2_0_cfg *dpc_2_0 = &otfdpc->alg_cfg.dpc_2_0; - struct vpfe_ipipe_otfdpc_3_0_cfg *dpc_3_0 = &otfdpc->alg_cfg.dpc_3_0; - u32 val; - - ipipe_clock_enable(base_addr); - - regw_ip(base_addr, (otfdpc->en & 1), DPC_OTF_EN); - if (!otfdpc->en) - return; - - /* dpc enabled */ - val = (otfdpc->det_method << OTF_DET_METHOD_SHIFT) | otfdpc->alg; - regw_ip(base_addr, val, DPC_OTF_TYP); - - if (otfdpc->det_method == VPFE_IPIPE_DPC_OTF_MIN_MAX) { - /* ALG= 0, TYP = 0, DPC_OTF_2D_THR_[x]=0 - * DPC_OTF_2C_THR_[x] = Maximum thresohld - * MinMax method - */ - dpc_2_0->det_thr.r = dpc_2_0->det_thr.gb = - dpc_2_0->det_thr.gr = dpc_2_0->det_thr.b = 0; - set_dpc_thresholds(base_addr, dpc_2_0); - return; - } - /* MinMax2 */ - if (otfdpc->alg == VPFE_IPIPE_OTFDPC_2_0) { - set_dpc_thresholds(base_addr, dpc_2_0); - return; - } - regw_ip(base_addr, dpc_3_0->act_adj_shf & - OTF_DPC3_0_SHF_MASK, DPC_OTF_3_SHF); - /* Detection thresholds */ - regw_ip(base_addr, ((dpc_3_0->det_thr & OTF_DPC3_0_THR_MASK) << - OTF_DPC3_0_THR_SHIFT), DPC_OTF_3D_THR); - regw_ip(base_addr, dpc_3_0->det_slp & - OTF_DPC3_0_SLP_MASK, DPC_OTF_3D_SLP); - regw_ip(base_addr, dpc_3_0->det_thr_min & - OTF_DPC3_0_DET_MASK, DPC_OTF_3D_MIN); - regw_ip(base_addr, dpc_3_0->det_thr_max & - OTF_DPC3_0_DET_MASK, DPC_OTF_3D_MAX); - /* Correction thresholds */ - regw_ip(base_addr, ((dpc_3_0->corr_thr & OTF_DPC3_0_THR_MASK) << - OTF_DPC3_0_THR_SHIFT), DPC_OTF_3C_THR); - regw_ip(base_addr, dpc_3_0->corr_slp & - OTF_DPC3_0_SLP_MASK, DPC_OTF_3C_SLP); - regw_ip(base_addr, dpc_3_0->corr_thr_min & - OTF_DPC3_0_CORR_MASK, DPC_OTF_3C_MIN); - regw_ip(base_addr, dpc_3_0->corr_thr_max & - OTF_DPC3_0_CORR_MASK, DPC_OTF_3C_MAX); -} - -/* 2D Noise filter */ -void -ipipe_set_d2f_regs(void __iomem *base_addr, unsigned int id, - struct vpfe_ipipe_nf *noise_filter) -{ - - u32 offset = D2F_1ST; - int count; - u32 val; - - if (id == IPIPE_D2F_2ND) - offset = D2F_2ND; - - ipipe_clock_enable(base_addr); - regw_ip(base_addr, noise_filter->en & 1, offset + D2F_EN); - if (!noise_filter->en) - return; - - /*noise filter enabled */ - /* Combine all the fields to make D2F_CFG register of IPIPE */ - val = ((noise_filter->spread_val & D2F_SPR_VAL_MASK) << - D2F_SPR_VAL_SHIFT) | ((noise_filter->shft_val & - D2F_SHFT_VAL_MASK) << D2F_SHFT_VAL_SHIFT) | - (noise_filter->gr_sample_meth << D2F_SAMPLE_METH_SHIFT) | - ((noise_filter->apply_lsc_gain & 1) << - D2F_APPLY_LSC_GAIN_SHIFT) | D2F_USE_SPR_REG_VAL; - regw_ip(base_addr, val, offset + D2F_TYP); - - /* edge detection minimum */ - regw_ip(base_addr, noise_filter->edge_det_min_thr & - D2F_EDGE_DET_THR_MASK, offset + D2F_EDG_MIN); - - /* edge detection maximum */ - regw_ip(base_addr, noise_filter->edge_det_max_thr & - D2F_EDGE_DET_THR_MASK, offset + D2F_EDG_MAX); - - for (count = 0; count < VPFE_IPIPE_NF_STR_TABLE_SIZE; count++) - regw_ip(base_addr, - (noise_filter->str[count] & D2F_STR_VAL_MASK), - offset + D2F_STR + count * 4); - - for (count = 0; count < VPFE_IPIPE_NF_THR_TABLE_SIZE; count++) - regw_ip(base_addr, noise_filter->thr[count] & D2F_THR_VAL_MASK, - offset + D2F_THR + count * 4); -} - -#define IPIPE_U8Q5(decimal, integer) \ - (((decimal & 0x1f) | ((integer & 0x7) << 5))) - -/* Green Imbalance Correction */ -void ipipe_set_gic_regs(void __iomem *base_addr, struct vpfe_ipipe_gic *gic) -{ - u32 val; - - ipipe_clock_enable(base_addr); - regw_ip(base_addr, gic->en & 1, GIC_EN); - - if (!gic->en) - return; - - /*gic enabled */ - val = (gic->wt_fn_type << GIC_TYP_SHIFT) | - (gic->thr_sel << GIC_THR_SEL_SHIFT) | - ((gic->apply_lsc_gain & 1) << GIC_APPLY_LSC_GAIN_SHIFT); - regw_ip(base_addr, val, GIC_TYP); - - regw_ip(base_addr, gic->gain & GIC_GAIN_MASK, GIC_GAN); - - if (gic->gic_alg != VPFE_IPIPE_GIC_ALG_ADAPT_GAIN) { - /* Constant Gain. Set threshold to maximum */ - regw_ip(base_addr, GIC_THR_MASK, GIC_THR); - return; - } - - if (gic->thr_sel == VPFE_IPIPE_GIC_THR_REG) { - regw_ip(base_addr, gic->thr & GIC_THR_MASK, GIC_THR); - regw_ip(base_addr, gic->slope & GIC_SLOPE_MASK, GIC_SLP); - } else { - /* Use NF thresholds */ - val = IPIPE_U8Q5(gic->nf2_thr_gain.decimal, - gic->nf2_thr_gain.integer); - regw_ip(base_addr, val, GIC_NFGAN); - } -} - -#define IPIPE_U13Q9(decimal, integer) \ - (((decimal & 0x1ff) | ((integer & 0xf) << 9))) -/* White balance */ -void ipipe_set_wb_regs(void __iomem *base_addr, struct vpfe_ipipe_wb *wb) -{ - u32 val; - - ipipe_clock_enable(base_addr); - /* Ofsets. S12 */ - regw_ip(base_addr, wb->ofst_r & WB_OFFSET_MASK, WB2_OFT_R); - regw_ip(base_addr, wb->ofst_gr & WB_OFFSET_MASK, WB2_OFT_GR); - regw_ip(base_addr, wb->ofst_gb & WB_OFFSET_MASK, WB2_OFT_GB); - regw_ip(base_addr, wb->ofst_b & WB_OFFSET_MASK, WB2_OFT_B); - - /* Gains. U13Q9 */ - val = IPIPE_U13Q9(wb->gain_r.decimal, wb->gain_r.integer); - regw_ip(base_addr, val, WB2_WGN_R); - - val = IPIPE_U13Q9(wb->gain_gr.decimal, wb->gain_gr.integer); - regw_ip(base_addr, val, WB2_WGN_GR); - - val = IPIPE_U13Q9(wb->gain_gb.decimal, wb->gain_gb.integer); - regw_ip(base_addr, val, WB2_WGN_GB); - - val = IPIPE_U13Q9(wb->gain_b.decimal, wb->gain_b.integer); - regw_ip(base_addr, val, WB2_WGN_B); -} - -/* CFA */ -void ipipe_set_cfa_regs(void __iomem *base_addr, struct vpfe_ipipe_cfa *cfa) -{ - ipipe_clock_enable(base_addr); - - regw_ip(base_addr, cfa->alg, CFA_MODE); - regw_ip(base_addr, cfa->hpf_thr_2dir & CFA_HPF_THR_2DIR_MASK, - CFA_2DIR_HPF_THR); - regw_ip(base_addr, cfa->hpf_slp_2dir & CFA_HPF_SLOPE_2DIR_MASK, - CFA_2DIR_HPF_SLP); - regw_ip(base_addr, cfa->hp_mix_thr_2dir & CFA_HPF_MIX_THR_2DIR_MASK, - CFA_2DIR_MIX_THR); - regw_ip(base_addr, cfa->hp_mix_slope_2dir & CFA_HPF_MIX_SLP_2DIR_MASK, - CFA_2DIR_MIX_SLP); - regw_ip(base_addr, cfa->dir_thr_2dir & CFA_DIR_THR_2DIR_MASK, - CFA_2DIR_DIR_THR); - regw_ip(base_addr, cfa->dir_slope_2dir & CFA_DIR_SLP_2DIR_MASK, - CFA_2DIR_DIR_SLP); - regw_ip(base_addr, cfa->nd_wt_2dir & CFA_ND_WT_2DIR_MASK, - CFA_2DIR_NDWT); - regw_ip(base_addr, cfa->hue_fract_daa & CFA_DAA_HUE_FRA_MASK, - CFA_MONO_HUE_FRA); - regw_ip(base_addr, cfa->edge_thr_daa & CFA_DAA_EDG_THR_MASK, - CFA_MONO_EDG_THR); - regw_ip(base_addr, cfa->thr_min_daa & CFA_DAA_THR_MIN_MASK, - CFA_MONO_THR_MIN); - regw_ip(base_addr, cfa->thr_slope_daa & CFA_DAA_THR_SLP_MASK, - CFA_MONO_THR_SLP); - regw_ip(base_addr, cfa->slope_min_daa & CFA_DAA_SLP_MIN_MASK, - CFA_MONO_SLP_MIN); - regw_ip(base_addr, cfa->slope_slope_daa & CFA_DAA_SLP_SLP_MASK, - CFA_MONO_SLP_SLP); - regw_ip(base_addr, cfa->lp_wt_daa & CFA_DAA_LP_WT_MASK, - CFA_MONO_LPWT); -} - -void -ipipe_set_rgb2rgb_regs(void __iomem *base_addr, unsigned int id, - struct vpfe_ipipe_rgb2rgb *rgb) -{ - u32 offset_mask = RGB2RGB_1_OFST_MASK; - u32 offset = RGB1_MUL_BASE; - u32 integ_mask = 0xf; - u32 val; - - ipipe_clock_enable(base_addr); - - if (id == IPIPE_RGB2RGB_2) { - /* - * For second RGB module, gain integer is 3 bits instead - * of 4, offset has 11 bits insread of 13 - */ - offset = RGB2_MUL_BASE; - integ_mask = 0x7; - offset_mask = RGB2RGB_2_OFST_MASK; - } - /* Gains */ - val = (rgb->coef_rr.decimal & 0xff) | - ((rgb->coef_rr.integer & integ_mask) << 8); - regw_ip(base_addr, val, offset + RGB_MUL_RR); - val = (rgb->coef_gr.decimal & 0xff) | - ((rgb->coef_gr.integer & integ_mask) << 8); - regw_ip(base_addr, val, offset + RGB_MUL_GR); - val = (rgb->coef_br.decimal & 0xff) | - ((rgb->coef_br.integer & integ_mask) << 8); - regw_ip(base_addr, val, offset + RGB_MUL_BR); - val = (rgb->coef_rg.decimal & 0xff) | - ((rgb->coef_rg.integer & integ_mask) << 8); - regw_ip(base_addr, val, offset + RGB_MUL_RG); - val = (rgb->coef_gg.decimal & 0xff) | - ((rgb->coef_gg.integer & integ_mask) << 8); - regw_ip(base_addr, val, offset + RGB_MUL_GG); - val = (rgb->coef_bg.decimal & 0xff) | - ((rgb->coef_bg.integer & integ_mask) << 8); - regw_ip(base_addr, val, offset + RGB_MUL_BG); - val = (rgb->coef_rb.decimal & 0xff) | - ((rgb->coef_rb.integer & integ_mask) << 8); - regw_ip(base_addr, val, offset + RGB_MUL_RB); - val = (rgb->coef_gb.decimal & 0xff) | - ((rgb->coef_gb.integer & integ_mask) << 8); - regw_ip(base_addr, val, offset + RGB_MUL_GB); - val = (rgb->coef_bb.decimal & 0xff) | - ((rgb->coef_bb.integer & integ_mask) << 8); - regw_ip(base_addr, val, offset + RGB_MUL_BB); - - /* Offsets */ - regw_ip(base_addr, rgb->out_ofst_r & offset_mask, offset + RGB_OFT_OR); - regw_ip(base_addr, rgb->out_ofst_g & offset_mask, offset + RGB_OFT_OG); - regw_ip(base_addr, rgb->out_ofst_b & offset_mask, offset + RGB_OFT_OB); -} - -static void -ipipe_update_gamma_tbl(void __iomem *isp5_base_addr, - struct vpfe_ipipe_gamma_entry *table, int size, u32 addr) -{ - int count; - u32 val; - - for (count = 0; count < size; count++) { - val = table[count].slope & GAMMA_MASK; - val |= (table[count].offset & GAMMA_MASK) << GAMMA_SHIFT; - w_ip_table(isp5_base_addr, val, (addr + (count * 4))); - } -} - -void -ipipe_set_gamma_regs(void __iomem *base_addr, void __iomem *isp5_base_addr, - struct vpfe_ipipe_gamma *gamma) -{ - int table_size; - u32 val; - - ipipe_clock_enable(base_addr); - val = (gamma->bypass_r << GAMMA_BYPR_SHIFT) | - (gamma->bypass_b << GAMMA_BYPG_SHIFT) | - (gamma->bypass_g << GAMMA_BYPB_SHIFT) | - (gamma->tbl_sel << GAMMA_TBL_SEL_SHIFT) | - (gamma->tbl_size << GAMMA_TBL_SIZE_SHIFT); - - regw_ip(base_addr, val, GMM_CFG); - - if (gamma->tbl_sel != VPFE_IPIPE_GAMMA_TBL_RAM) - return; - - table_size = gamma->tbl_size; - - if (!gamma->bypass_r) - ipipe_update_gamma_tbl(isp5_base_addr, gamma->table_r, - table_size, GAMMA_R_START_ADDR); - if (!gamma->bypass_b) - ipipe_update_gamma_tbl(isp5_base_addr, gamma->table_b, - table_size, GAMMA_B_START_ADDR); - if (!gamma->bypass_g) - ipipe_update_gamma_tbl(isp5_base_addr, gamma->table_g, - table_size, GAMMA_G_START_ADDR); -} - -void -ipipe_set_3d_lut_regs(void __iomem *base_addr, void __iomem *isp5_base_addr, - struct vpfe_ipipe_3d_lut *lut_3d) -{ - struct vpfe_ipipe_3d_lut_entry *tbl; - u32 bnk_index; - u32 tbl_index; - u32 val; - u32 i; - - ipipe_clock_enable(base_addr); - regw_ip(base_addr, lut_3d->en, D3LUT_EN); - - if (!lut_3d->en) - return; - - /* valid table */ - tbl = lut_3d->table; - for (i = 0; i < VPFE_IPIPE_MAX_SIZE_3D_LUT; i++) { - /* - * Each entry has 0-9 (B), 10-19 (G) and - * 20-29 R values - */ - val = tbl[i].b & D3_LUT_ENTRY_MASK; - val |= (tbl[i].g & D3_LUT_ENTRY_MASK) << - D3_LUT_ENTRY_G_SHIFT; - val |= (tbl[i].r & D3_LUT_ENTRY_MASK) << - D3_LUT_ENTRY_R_SHIFT; - bnk_index = i % 4; - tbl_index = i >> 2; - tbl_index <<= 2; - if (bnk_index == 0) - w_ip_table(isp5_base_addr, val, - tbl_index + D3L_TB0_START_ADDR); - else if (bnk_index == 1) - w_ip_table(isp5_base_addr, val, - tbl_index + D3L_TB1_START_ADDR); - else if (bnk_index == 2) - w_ip_table(isp5_base_addr, val, - tbl_index + D3L_TB2_START_ADDR); - else - w_ip_table(isp5_base_addr, val, - tbl_index + D3L_TB3_START_ADDR); - } -} - -/* Lumina adjustments */ -void -ipipe_set_lum_adj_regs(void __iomem *base_addr, struct ipipe_lum_adj *lum_adj) -{ - u32 val; - - ipipe_clock_enable(base_addr); - - /* combine fields of YUV_ADJ to set brightness and contrast */ - val = lum_adj->contrast << LUM_ADJ_CONTR_SHIFT | - lum_adj->brightness << LUM_ADJ_BRIGHT_SHIFT; - regw_ip(base_addr, val, YUV_ADJ); -} - -inline u32 ipipe_s12q8(unsigned short decimal, short integer) -{ - return (decimal & 0xff) | ((integer & 0xf) << 8); -} - -void ipipe_set_rgb2ycbcr_regs(void __iomem *base_addr, - struct vpfe_ipipe_rgb2yuv *yuv) -{ - u32 val; - - /* S10Q8 */ - ipipe_clock_enable(base_addr); - val = ipipe_s12q8(yuv->coef_ry.decimal, yuv->coef_ry.integer); - regw_ip(base_addr, val, YUV_MUL_RY); - val = ipipe_s12q8(yuv->coef_gy.decimal, yuv->coef_gy.integer); - regw_ip(base_addr, val, YUV_MUL_GY); - val = ipipe_s12q8(yuv->coef_by.decimal, yuv->coef_by.integer); - regw_ip(base_addr, val, YUV_MUL_BY); - val = ipipe_s12q8(yuv->coef_rcb.decimal, yuv->coef_rcb.integer); - regw_ip(base_addr, val, YUV_MUL_RCB); - val = ipipe_s12q8(yuv->coef_gcb.decimal, yuv->coef_gcb.integer); - regw_ip(base_addr, val, YUV_MUL_GCB); - val = ipipe_s12q8(yuv->coef_bcb.decimal, yuv->coef_bcb.integer); - regw_ip(base_addr, val, YUV_MUL_BCB); - val = ipipe_s12q8(yuv->coef_rcr.decimal, yuv->coef_rcr.integer); - regw_ip(base_addr, val, YUV_MUL_RCR); - val = ipipe_s12q8(yuv->coef_gcr.decimal, yuv->coef_gcr.integer); - regw_ip(base_addr, val, YUV_MUL_GCR); - val = ipipe_s12q8(yuv->coef_bcr.decimal, yuv->coef_bcr.integer); - regw_ip(base_addr, val, YUV_MUL_BCR); - regw_ip(base_addr, yuv->out_ofst_y & RGB2YCBCR_OFST_MASK, YUV_OFT_Y); - regw_ip(base_addr, yuv->out_ofst_cb & RGB2YCBCR_OFST_MASK, YUV_OFT_CB); - regw_ip(base_addr, yuv->out_ofst_cr & RGB2YCBCR_OFST_MASK, YUV_OFT_CR); -} - -/* YUV 422 conversion */ -void -ipipe_set_yuv422_conv_regs(void __iomem *base_addr, - struct vpfe_ipipe_yuv422_conv *conv) -{ - u32 val; - - ipipe_clock_enable(base_addr); - - /* Combine all the fields to make YUV_PHS register of IPIPE */ - val = (conv->chrom_pos << 0) | (conv->en_chrom_lpf << 1); - regw_ip(base_addr, val, YUV_PHS); -} - -void -ipipe_set_gbce_regs(void __iomem *base_addr, void __iomem *isp5_base_addr, - struct vpfe_ipipe_gbce *gbce) -{ - unsigned int count; - u32 mask = GBCE_Y_VAL_MASK; - - if (gbce->type == VPFE_IPIPE_GBCE_GAIN_TBL) - mask = GBCE_GAIN_VAL_MASK; - - ipipe_clock_enable(base_addr); - regw_ip(base_addr, gbce->en & 1, GBCE_EN); - - if (!gbce->en) - return; - - regw_ip(base_addr, gbce->type, GBCE_TYP); - - for (count = 0; count < VPFE_IPIPE_MAX_SIZE_GBCE_LUT; count += 2) - w_ip_table(isp5_base_addr, ((gbce->table[count + 1] & mask) << - GBCE_ENTRY_SHIFT) | (gbce->table[count] & mask), - ((count/2) << 2) + GBCE_TB_START_ADDR); -} - -void -ipipe_set_ee_regs(void __iomem *base_addr, void __iomem *isp5_base_addr, - struct vpfe_ipipe_yee *ee) -{ - unsigned int count; - u32 val; - - ipipe_clock_enable(base_addr); - regw_ip(base_addr, ee->en, YEE_EN); - - if (!ee->en) - return; - - val = ee->en_halo_red & 1; - val |= ee->merge_meth << YEE_HALO_RED_EN_SHIFT; - regw_ip(base_addr, val, YEE_TYP); - - regw_ip(base_addr, ee->hpf_shft, YEE_SHF); - regw_ip(base_addr, ee->hpf_coef_00 & YEE_COEF_MASK, YEE_MUL_00); - regw_ip(base_addr, ee->hpf_coef_01 & YEE_COEF_MASK, YEE_MUL_01); - regw_ip(base_addr, ee->hpf_coef_02 & YEE_COEF_MASK, YEE_MUL_02); - regw_ip(base_addr, ee->hpf_coef_10 & YEE_COEF_MASK, YEE_MUL_10); - regw_ip(base_addr, ee->hpf_coef_11 & YEE_COEF_MASK, YEE_MUL_11); - regw_ip(base_addr, ee->hpf_coef_12 & YEE_COEF_MASK, YEE_MUL_12); - regw_ip(base_addr, ee->hpf_coef_20 & YEE_COEF_MASK, YEE_MUL_20); - regw_ip(base_addr, ee->hpf_coef_21 & YEE_COEF_MASK, YEE_MUL_21); - regw_ip(base_addr, ee->hpf_coef_22 & YEE_COEF_MASK, YEE_MUL_22); - regw_ip(base_addr, ee->yee_thr & YEE_THR_MASK, YEE_THR); - regw_ip(base_addr, ee->es_gain & YEE_ES_GAIN_MASK, YEE_E_GAN); - regw_ip(base_addr, ee->es_thr1 & YEE_ES_THR1_MASK, YEE_E_THR1); - regw_ip(base_addr, ee->es_thr2 & YEE_THR_MASK, YEE_E_THR2); - regw_ip(base_addr, ee->es_gain_grad & YEE_THR_MASK, YEE_G_GAN); - regw_ip(base_addr, ee->es_ofst_grad & YEE_THR_MASK, YEE_G_OFT); - - for (count = 0; count < VPFE_IPIPE_MAX_SIZE_YEE_LUT; count += 2) - w_ip_table(isp5_base_addr, ((ee->table[count + 1] & - YEE_ENTRY_MASK) << YEE_ENTRY_SHIFT) | - (ee->table[count] & YEE_ENTRY_MASK), - ((count/2) << 2) + YEE_TB_START_ADDR); -} - -/* Chromatic Artifact Correction. CAR */ -static void ipipe_set_mf(void __iomem *base_addr) -{ - /* typ to dynamic switch */ - regw_ip(base_addr, VPFE_IPIPE_CAR_DYN_SWITCH, CAR_TYP); - /* Set SW0 to maximum */ - regw_ip(base_addr, CAR_MF_THR, CAR_SW); -} - -static void -ipipe_set_gain_ctrl(void __iomem *base_addr, struct vpfe_ipipe_car *car) -{ - regw_ip(base_addr, VPFE_IPIPE_CAR_CHR_GAIN_CTRL, CAR_TYP); - regw_ip(base_addr, car->hpf, CAR_HPF_TYP); - regw_ip(base_addr, car->hpf_shft & CAR_HPF_SHIFT_MASK, CAR_HPF_SHF); - regw_ip(base_addr, car->hpf_thr, CAR_HPF_THR); - regw_ip(base_addr, car->gain1.gain, CAR_GN1_GAN); - regw_ip(base_addr, car->gain1.shft & CAR_GAIN1_SHFT_MASK, CAR_GN1_SHF); - regw_ip(base_addr, car->gain1.gain_min & CAR_GAIN_MIN_MASK, - CAR_GN1_MIN); - regw_ip(base_addr, car->gain2.gain, CAR_GN2_GAN); - regw_ip(base_addr, car->gain2.shft & CAR_GAIN2_SHFT_MASK, CAR_GN2_SHF); - regw_ip(base_addr, car->gain2.gain_min & CAR_GAIN_MIN_MASK, - CAR_GN2_MIN); -} - -void ipipe_set_car_regs(void __iomem *base_addr, struct vpfe_ipipe_car *car) -{ - u32 val; - - ipipe_clock_enable(base_addr); - regw_ip(base_addr, car->en, CAR_EN); - - if (!car->en) - return; - - switch (car->meth) { - case VPFE_IPIPE_CAR_MED_FLTR: - ipipe_set_mf(base_addr); - break; - - case VPFE_IPIPE_CAR_CHR_GAIN_CTRL: - ipipe_set_gain_ctrl(base_addr, car); - break; - - default: - /* Dynamic switch between MF and Gain Ctrl. */ - ipipe_set_mf(base_addr); - ipipe_set_gain_ctrl(base_addr, car); - /* Set the threshold for switching between - * the two Here we overwrite the MF SW0 value - */ - regw_ip(base_addr, VPFE_IPIPE_CAR_DYN_SWITCH, CAR_TYP); - val = car->sw1; - val <<= CAR_SW1_SHIFT; - val |= car->sw0; - regw_ip(base_addr, val, CAR_SW); - } -} - -/* Chromatic Gain Suppression */ -void ipipe_set_cgs_regs(void __iomem *base_addr, struct vpfe_ipipe_cgs *cgs) -{ - ipipe_clock_enable(base_addr); - regw_ip(base_addr, cgs->en, CGS_EN); - - if (!cgs->en) - return; - - /* Set the bright side parameters */ - regw_ip(base_addr, cgs->h_thr, CGS_GN1_H_THR); - regw_ip(base_addr, cgs->h_slope, CGS_GN1_H_GAN); - regw_ip(base_addr, cgs->h_shft & CAR_SHIFT_MASK, CGS_GN1_H_SHF); - regw_ip(base_addr, cgs->h_min, CGS_GN1_H_MIN); -} - -void rsz_src_enable(void __iomem *rsz_base, int enable) -{ - regw_rsz(rsz_base, enable, RSZ_SRC_EN); -} - -int rsz_enable(void __iomem *rsz_base, int rsz_id, int enable) -{ - if (rsz_id == RSZ_A) { - regw_rsz(rsz_base, enable, RSZ_EN_A); - /* We always enable RSZ_A. RSZ_B is enable upon request from - * application. So enable RSZ_SRC_EN along with RSZ_A - */ - regw_rsz(rsz_base, enable, RSZ_SRC_EN); - } else if (rsz_id == RSZ_B) { - regw_rsz(rsz_base, enable, RSZ_EN_B); - } else { - BUG(); - } - - return 0; -} |