linux/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2012 Texas Instruments Inc
   3 *
   4 * This program is free software; you can redistribute it and/or
   5 * modify it under the terms of the GNU General Public License as
   6 * published by the Free Software Foundation version 2.
   7 *
   8 * This program is distributed in the hope that it will be useful,
   9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11 * GNU General Public License for more details.
  12 *
  13 * You should have received a copy of the GNU General Public License
  14 * along with this program; if not, write to the Free Software
  15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16 *
  17 * Contributors:
  18 *      Manjunath Hadli <manjunath.hadli@ti.com>
  19 *      Prabhakar Lad <prabhakar.lad@ti.com>
  20 */
  21
  22#include "dm365_ipipe_hw.h"
  23
  24#define IPIPE_MODE_CONTINUOUS           0
  25#define IPIPE_MODE_SINGLE_SHOT          1
  26
  27static void ipipe_clock_enable(void *__iomem base_addr)
  28{
  29        /* enable IPIPE MMR for register write access */
  30        regw_ip(base_addr, IPIPE_GCK_MMR_DEFAULT, IPIPE_GCK_MMR);
  31
  32        /* enable the clock wb,cfa,dfc,d2f,pre modules */
  33        regw_ip(base_addr, IPIPE_GCK_PIX_DEFAULT, IPIPE_GCK_PIX);
  34}
  35
  36static void
  37rsz_set_common_params(void *__iomem rsz_base, struct resizer_params *params)
  38{
  39        struct rsz_common_params *rsz_common = &params->rsz_common;
  40        u32 val;
  41
  42        /* Set mode */
  43        regw_rsz(rsz_base, params->oper_mode, RSZ_SRC_MODE);
  44
  45        /* data source selection  and bypass */
  46        val = (rsz_common->passthrough << RSZ_BYPASS_SHIFT) |
  47              rsz_common->source;
  48        regw_rsz(rsz_base, val, RSZ_SRC_FMT0);
  49
  50        /* src image selection */
  51        val = (rsz_common->raw_flip & 1) |
  52              (rsz_common->src_img_fmt << RSZ_SRC_IMG_FMT_SHIFT) |
  53              ((rsz_common->y_c & 1) << RSZ_SRC_Y_C_SEL_SHIFT);
  54        regw_rsz(rsz_base, val, RSZ_SRC_FMT1);
  55
  56        regw_rsz(rsz_base, rsz_common->vps & IPIPE_RSZ_VPS_MASK, RSZ_SRC_VPS);
  57        regw_rsz(rsz_base, rsz_common->hps & IPIPE_RSZ_HPS_MASK, RSZ_SRC_HPS);
  58        regw_rsz(rsz_base, rsz_common->vsz & IPIPE_RSZ_VSZ_MASK, RSZ_SRC_VSZ);
  59        regw_rsz(rsz_base, rsz_common->hsz & IPIPE_RSZ_HSZ_MASK, RSZ_SRC_HSZ);
  60        regw_rsz(rsz_base, rsz_common->yuv_y_min, RSZ_YUV_Y_MIN);
  61        regw_rsz(rsz_base, rsz_common->yuv_y_max, RSZ_YUV_Y_MAX);
  62        regw_rsz(rsz_base, rsz_common->yuv_c_min, RSZ_YUV_C_MIN);
  63        regw_rsz(rsz_base, rsz_common->yuv_c_max, RSZ_YUV_C_MAX);
  64        /* chromatic position */
  65        regw_rsz(rsz_base, rsz_common->out_chr_pos, RSZ_YUV_PHS);
  66}
  67
  68static void
  69rsz_set_rsz_regs(void *__iomem rsz_base, unsigned int rsz_id,
  70                 struct resizer_params *params)
  71{
  72        struct resizer_scale_param *rsc_params;
  73        struct rsz_ext_mem_param *ext_mem;
  74        struct resizer_rgb *rgb;
  75        u32 reg_base;
  76        u32 val;
  77
  78        rsc_params = &params->rsz_rsc_param[rsz_id];
  79        rgb = &params->rsz2rgb[rsz_id];
  80        ext_mem = &params->ext_mem_param[rsz_id];
  81
  82        if (rsz_id == RSZ_A) {
  83                val = rsc_params->h_flip << RSZA_H_FLIP_SHIFT;
  84                val |= rsc_params->v_flip << RSZA_V_FLIP_SHIFT;
  85                reg_base = RSZ_EN_A;
  86        } else {
  87                val = rsc_params->h_flip << RSZB_H_FLIP_SHIFT;
  88                val |= rsc_params->v_flip << RSZB_V_FLIP_SHIFT;
  89                reg_base = RSZ_EN_B;
  90        }
  91        /* update flip settings */
  92        regw_rsz(rsz_base, val, RSZ_SEQ);
  93
  94        regw_rsz(rsz_base, params->oper_mode, reg_base + RSZ_MODE);
  95
  96        val = (rsc_params->cen << RSZ_CEN_SHIFT) | rsc_params->yen;
  97        regw_rsz(rsz_base, val, reg_base + RSZ_420);
  98
  99        regw_rsz(rsz_base, rsc_params->i_vps & RSZ_VPS_MASK,
 100                 reg_base + RSZ_I_VPS);
 101        regw_rsz(rsz_base, rsc_params->i_hps & RSZ_HPS_MASK,
 102                 reg_base + RSZ_I_HPS);
 103        regw_rsz(rsz_base, rsc_params->o_vsz & RSZ_O_VSZ_MASK,
 104                 reg_base + RSZ_O_VSZ);
 105        regw_rsz(rsz_base, rsc_params->o_hsz & RSZ_O_HSZ_MASK,
 106                 reg_base + RSZ_O_HSZ);
 107        regw_rsz(rsz_base, rsc_params->v_phs_y & RSZ_V_PHS_MASK,
 108                 reg_base + RSZ_V_PHS_Y);
 109        regw_rsz(rsz_base, rsc_params->v_phs_c & RSZ_V_PHS_MASK,
 110                 reg_base + RSZ_V_PHS_C);
 111
 112        /* keep this additional adjustment to zero for now */
 113        regw_rsz(rsz_base, rsc_params->v_dif & RSZ_V_DIF_MASK,
 114                 reg_base + RSZ_V_DIF);
 115
 116        val = (rsc_params->v_typ_y & 1) |
 117              ((rsc_params->v_typ_c & 1) << RSZ_TYP_C_SHIFT);
 118        regw_rsz(rsz_base, val, reg_base + RSZ_V_TYP);
 119
 120        val = (rsc_params->v_lpf_int_y & RSZ_LPF_INT_MASK) |
 121              ((rsc_params->v_lpf_int_c & RSZ_LPF_INT_MASK) <<
 122              RSZ_LPF_INT_C_SHIFT);
 123        regw_rsz(rsz_base, val, reg_base + RSZ_V_LPF);
 124
 125        regw_rsz(rsz_base, rsc_params->h_phs &
 126                RSZ_H_PHS_MASK, reg_base + RSZ_H_PHS);
 127
 128        regw_rsz(rsz_base, 0, reg_base + RSZ_H_PHS_ADJ);
 129        regw_rsz(rsz_base, rsc_params->h_dif &
 130                RSZ_H_DIF_MASK, reg_base + RSZ_H_DIF);
 131
 132        val = (rsc_params->h_typ_y & 1) |
 133              ((rsc_params->h_typ_c & 1) << RSZ_TYP_C_SHIFT);
 134        regw_rsz(rsz_base, val, reg_base + RSZ_H_TYP);
 135
 136        val = (rsc_params->h_lpf_int_y & RSZ_LPF_INT_MASK) |
 137                 ((rsc_params->h_lpf_int_c & RSZ_LPF_INT_MASK) <<
 138                 RSZ_LPF_INT_C_SHIFT);
 139        regw_rsz(rsz_base, val, reg_base + RSZ_H_LPF);
 140
 141        regw_rsz(rsz_base, rsc_params->dscale_en & 1, reg_base + RSZ_DWN_EN);
 142
 143        val = (rsc_params->h_dscale_ave_sz & RSZ_DWN_SCALE_AV_SZ_MASK) |
 144              ((rsc_params->v_dscale_ave_sz & RSZ_DWN_SCALE_AV_SZ_MASK) <<
 145              RSZ_DWN_SCALE_AV_SZ_V_SHIFT);
 146        regw_rsz(rsz_base, val, reg_base + RSZ_DWN_AV);
 147
 148        /* setting rgb conversion parameters */
 149        regw_rsz(rsz_base, rgb->rgb_en, reg_base + RSZ_RGB_EN);
 150
 151        val = (rgb->rgb_typ << RSZ_RGB_TYP_SHIFT) |
 152              (rgb->rgb_msk0 << RSZ_RGB_MSK0_SHIFT) |
 153              (rgb->rgb_msk1 << RSZ_RGB_MSK1_SHIFT);
 154        regw_rsz(rsz_base, val, reg_base + RSZ_RGB_TYP);
 155
 156        regw_rsz(rsz_base, rgb->rgb_alpha_val & RSZ_RGB_ALPHA_MASK,
 157                reg_base + RSZ_RGB_BLD);
 158
 159        /* setting external memory parameters */
 160        regw_rsz(rsz_base, ext_mem->rsz_sdr_oft_y, reg_base + RSZ_SDR_Y_OFT);
 161        regw_rsz(rsz_base, ext_mem->rsz_sdr_ptr_s_y,
 162                 reg_base + RSZ_SDR_Y_PTR_S);
 163        regw_rsz(rsz_base, ext_mem->rsz_sdr_ptr_e_y,
 164                 reg_base + RSZ_SDR_Y_PTR_E);
 165        regw_rsz(rsz_base, ext_mem->rsz_sdr_oft_c, reg_base + RSZ_SDR_C_OFT);
 166        regw_rsz(rsz_base, ext_mem->rsz_sdr_ptr_s_c,
 167                 reg_base + RSZ_SDR_C_PTR_S);
 168        regw_rsz(rsz_base, (ext_mem->rsz_sdr_ptr_e_c >> 1),
 169                 reg_base + RSZ_SDR_C_PTR_E);
 170}
 171
 172/*set the registers of either RSZ0 or RSZ1 */
 173static void
 174ipipe_setup_resizer(void *__iomem rsz_base, struct resizer_params *params)
 175{
 176        /* enable MMR gate to write to Resizer */
 177        regw_rsz(rsz_base, 1, RSZ_GCK_MMR);
 178
 179        /* Enable resizer if it is not in bypass mode */
 180        if (params->rsz_common.passthrough)
 181                regw_rsz(rsz_base, 0, RSZ_GCK_SDR);
 182        else
 183                regw_rsz(rsz_base, 1, RSZ_GCK_SDR);
 184
 185        rsz_set_common_params(rsz_base, params);
 186
 187        regw_rsz(rsz_base, params->rsz_en[RSZ_A], RSZ_EN_A);
 188
 189        if (params->rsz_en[RSZ_A])
 190                /*setting rescale parameters */
 191                rsz_set_rsz_regs(rsz_base, RSZ_A, params);
 192
 193        regw_rsz(rsz_base, params->rsz_en[RSZ_B], RSZ_EN_B);
 194
 195        if (params->rsz_en[RSZ_B])
 196                rsz_set_rsz_regs(rsz_base, RSZ_B, params);
 197}
 198
 199static u32 ipipe_get_color_pat(enum v4l2_mbus_pixelcode pix)
 200{
 201        switch (pix) {
 202        case V4L2_MBUS_FMT_SGRBG10_ALAW8_1X8:
 203        case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8:
 204        case V4L2_MBUS_FMT_SGRBG12_1X12:
 205                return ipipe_sgrbg_pattern;
 206
 207        default:
 208                return ipipe_srggb_pattern;
 209        }
 210}
 211
 212static int ipipe_get_data_path(struct vpfe_ipipe_device *ipipe)
 213{
 214        enum v4l2_mbus_pixelcode temp_pix_fmt;
 215
 216        switch (ipipe->formats[IPIPE_PAD_SINK].code) {
 217        case V4L2_MBUS_FMT_SBGGR8_1X8:
 218        case V4L2_MBUS_FMT_SGRBG10_ALAW8_1X8:
 219        case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8:
 220        case V4L2_MBUS_FMT_SGRBG12_1X12:
 221                temp_pix_fmt = V4L2_MBUS_FMT_SGRBG12_1X12;
 222                break;
 223
 224        default:
 225                temp_pix_fmt = V4L2_MBUS_FMT_UYVY8_2X8;
 226        }
 227
 228        if (temp_pix_fmt == V4L2_MBUS_FMT_SGRBG12_1X12) {
 229                if (ipipe->formats[IPIPE_PAD_SOURCE].code ==
 230                        V4L2_MBUS_FMT_SGRBG12_1X12)
 231                        return IPIPE_RAW2RAW;
 232                return IPIPE_RAW2YUV;
 233        }
 234
 235        return IPIPE_YUV2YUV;
 236}
 237
 238static int get_ipipe_mode(struct vpfe_ipipe_device *ipipe)
 239{
 240        struct vpfe_device *vpfe_dev = to_vpfe_device(ipipe);
 241        u16 ipipeif_sink = vpfe_dev->vpfe_ipipeif.input;
 242
 243        if (ipipeif_sink == IPIPEIF_INPUT_MEMORY)
 244                return IPIPE_MODE_SINGLE_SHOT;
 245        else if (ipipeif_sink == IPIPEIF_INPUT_ISIF)
 246                return IPIPE_MODE_CONTINUOUS;
 247
 248        return -EINVAL;
 249}
 250
 251int config_ipipe_hw(struct vpfe_ipipe_device *ipipe)
 252{
 253        struct vpfe_ipipe_input_config *config = &ipipe->config.input_config;
 254        void __iomem *ipipe_base = ipipe->base_addr;
 255        struct v4l2_mbus_framefmt *outformat;
 256        u32 color_pat;
 257        u32 ipipe_mode;
 258        u32 data_path;
 259
 260        /* enable clock to IPIPE */
 261        vpss_enable_clock(VPSS_IPIPE_CLOCK, 1);
 262        ipipe_clock_enable(ipipe_base);
 263
 264        if (ipipe->input == IPIPE_INPUT_NONE) {
 265                regw_ip(ipipe_base, 0, IPIPE_SRC_EN);
 266                return 0;
 267        }
 268
 269        ipipe_mode = get_ipipe_mode(ipipe);
 270        if (ipipe < 0) {
 271                pr_err("Failed to get ipipe mode");
 272                return -EINVAL;
 273        }
 274        regw_ip(ipipe_base, ipipe_mode, IPIPE_SRC_MODE);
 275
 276        data_path = ipipe_get_data_path(ipipe);
 277        regw_ip(ipipe_base, data_path, IPIPE_SRC_FMT);
 278
 279        regw_ip(ipipe_base, config->vst & IPIPE_RSZ_VPS_MASK, IPIPE_SRC_VPS);
 280        regw_ip(ipipe_base, config->hst & IPIPE_RSZ_HPS_MASK, IPIPE_SRC_HPS);
 281
 282        outformat = &ipipe->formats[IPIPE_PAD_SOURCE];
 283        regw_ip(ipipe_base, (outformat->height + 1) & IPIPE_RSZ_VSZ_MASK,
 284                IPIPE_SRC_VSZ);
 285        regw_ip(ipipe_base, (outformat->width + 1) & IPIPE_RSZ_HSZ_MASK,
 286                IPIPE_SRC_HSZ);
 287
 288        if (data_path == IPIPE_RAW2YUV ||
 289            data_path == IPIPE_RAW2RAW) {
 290                color_pat =
 291                ipipe_get_color_pat(ipipe->formats[IPIPE_PAD_SINK].code);
 292                regw_ip(ipipe_base, color_pat, IPIPE_SRC_COL);
 293        }
 294
 295        return 0;
 296}
 297
 298/*
 299 * config_rsz_hw() - Performs hardware setup of resizer.
 300 */
 301int config_rsz_hw(struct vpfe_resizer_device *resizer,
 302                  struct resizer_params *config)
 303{
 304        struct vpfe_device *vpfe_dev = to_vpfe_device(resizer);
 305        void *__iomem ipipe_base = vpfe_dev->vpfe_ipipe.base_addr;
 306        void *__iomem rsz_base = vpfe_dev->vpfe_resizer.base_addr;
 307
 308        /* enable VPSS clock */
 309        vpss_enable_clock(VPSS_IPIPE_CLOCK, 1);
 310        ipipe_clock_enable(ipipe_base);
 311
 312        ipipe_setup_resizer(rsz_base, config);
 313
 314        return 0;
 315}
 316
 317static void
 318rsz_set_y_address(void *__iomem rsz_base, unsigned int address,
 319                  unsigned int offset)
 320{
 321        u32 val;
 322
 323        val = address & SET_LOW_ADDR;
 324        regw_rsz(rsz_base, val, offset + RSZ_SDR_Y_BAD_L);
 325        regw_rsz(rsz_base, val, offset + RSZ_SDR_Y_SAD_L);
 326
 327        val = (address & SET_HIGH_ADDR) >> 16;
 328        regw_rsz(rsz_base, val, offset + RSZ_SDR_Y_BAD_H);
 329        regw_rsz(rsz_base, val, offset + RSZ_SDR_Y_SAD_H);
 330}
 331
 332static void
 333rsz_set_c_address(void *__iomem rsz_base, unsigned int address,
 334                  unsigned int offset)
 335{
 336        u32 val;
 337
 338        val = address & SET_LOW_ADDR;
 339        regw_rsz(rsz_base, val, offset + RSZ_SDR_C_BAD_L);
 340        regw_rsz(rsz_base, val, offset + RSZ_SDR_C_SAD_L);
 341
 342        val = (address & SET_HIGH_ADDR) >> 16;
 343        regw_rsz(rsz_base, val, offset + RSZ_SDR_C_BAD_H);
 344        regw_rsz(rsz_base, val, offset + RSZ_SDR_C_SAD_H);
 345}
 346
 347/*
 348 * resizer_set_outaddr() - set the address for given resize_no
 349 * @rsz_base: resizer base address
 350 * @params: pointer to ipipe_params structure
 351 * @resize_no: 0 - Resizer-A, 1 - Resizer B
 352 * @address: the address to set
 353 */
 354int
 355resizer_set_outaddr(void *__iomem rsz_base, struct resizer_params *params,
 356                    int resize_no, unsigned int address)
 357{
 358        struct resizer_scale_param *rsc_param;
 359        struct rsz_ext_mem_param *mem_param;
 360        struct rsz_common_params *rsz_common;
 361        unsigned int rsz_start_add;
 362        unsigned int val;
 363
 364        if (resize_no != RSZ_A && resize_no != RSZ_B)
 365                return -EINVAL;
 366
 367        mem_param = &params->ext_mem_param[resize_no];
 368        rsc_param = &params->rsz_rsc_param[resize_no];
 369        rsz_common = &params->rsz_common;
 370
 371        if (resize_no == RSZ_A)
 372                rsz_start_add = RSZ_EN_A;
 373        else
 374                rsz_start_add = RSZ_EN_B;
 375
 376        /* y_c = 0 for y, = 1 for c */
 377        if (rsz_common->src_img_fmt == RSZ_IMG_420) {
 378                if (rsz_common->y_c) {
 379                        /* C channel */
 380                        val = address + mem_param->flip_ofst_c;
 381                        rsz_set_c_address(rsz_base, val, rsz_start_add);
 382                } else {
 383                        val = address + mem_param->flip_ofst_y;
 384                        rsz_set_y_address(rsz_base, val, rsz_start_add);
 385                }
 386        } else {
 387                if (rsc_param->cen && rsc_param->yen) {
 388                        /* 420 */
 389                        val = address + mem_param->c_offset +
 390                              mem_param->flip_ofst_c +
 391                              mem_param->user_y_ofst +
 392                              mem_param->user_c_ofst;
 393                        if (resize_no == RSZ_B)
 394                                val +=
 395                                params->ext_mem_param[RSZ_A].user_y_ofst +
 396                                params->ext_mem_param[RSZ_A].user_c_ofst;
 397                        /* set C address */
 398                        rsz_set_c_address(rsz_base, val, rsz_start_add);
 399                }
 400                val = address + mem_param->flip_ofst_y + mem_param->user_y_ofst;
 401                if (resize_no == RSZ_B)
 402                        val += params->ext_mem_param[RSZ_A].user_y_ofst +
 403                                params->ext_mem_param[RSZ_A].user_c_ofst;
 404                /* set Y address */
 405                rsz_set_y_address(rsz_base, val, rsz_start_add);
 406        }
 407        /* resizer must be enabled */
 408        regw_rsz(rsz_base, params->rsz_en[resize_no], rsz_start_add);
 409
 410        return 0;
 411}
 412
 413void
 414ipipe_set_lutdpc_regs(void *__iomem base_addr, void *__iomem isp5_base_addr,
 415                      struct vpfe_ipipe_lutdpc *dpc)
 416{
 417        u32 max_tbl_size = LUT_DPC_MAX_SIZE >> 1;
 418        u32 lut_start_addr = DPC_TB0_START_ADDR;
 419        u32 val;
 420        u32 count;
 421
 422        ipipe_clock_enable(base_addr);
 423        regw_ip(base_addr, dpc->en, DPC_LUT_EN);
 424
 425        if (dpc->en != 1)
 426                return;
 427
 428        val = LUTDPC_TBL_256_EN | (dpc->repl_white & 1);
 429        regw_ip(base_addr, val, DPC_LUT_SEL);
 430        regw_ip(base_addr, LUT_DPC_START_ADDR, DPC_LUT_ADR);
 431        regw_ip(base_addr, dpc->dpc_size, DPC_LUT_SIZ & LUT_DPC_SIZE_MASK);
 432
 433        if (dpc->table == NULL)
 434                return;
 435
 436        for (count = 0; count < dpc->dpc_size; count++) {
 437                if (count >= max_tbl_size)
 438                        lut_start_addr = DPC_TB1_START_ADDR;
 439                val = (dpc->table[count].horz_pos & LUT_DPC_H_POS_MASK) |
 440                      ((dpc->table[count].vert_pos & LUT_DPC_V_POS_MASK) <<
 441                        LUT_DPC_V_POS_SHIFT) | (dpc->table[count].method <<
 442                        LUT_DPC_CORR_METH_SHIFT);
 443                w_ip_table(isp5_base_addr, val, (lut_start_addr +
 444                ((count % max_tbl_size) << 2)));
 445        }
 446}
 447
 448static void
 449set_dpc_thresholds(void *__iomem base_addr,
 450                   struct vpfe_ipipe_otfdpc_2_0_cfg *dpc_thr)
 451{
 452        regw_ip(base_addr, dpc_thr->corr_thr.r & OTFDPC_DPC2_THR_MASK,
 453                DPC_OTF_2C_THR_R);
 454        regw_ip(base_addr, dpc_thr->corr_thr.gr & OTFDPC_DPC2_THR_MASK,
 455                DPC_OTF_2C_THR_GR);
 456        regw_ip(base_addr, dpc_thr->corr_thr.gb & OTFDPC_DPC2_THR_MASK,
 457                DPC_OTF_2C_THR_GB);
 458        regw_ip(base_addr, dpc_thr->corr_thr.b & OTFDPC_DPC2_THR_MASK,
 459                DPC_OTF_2C_THR_B);
 460        regw_ip(base_addr, dpc_thr->det_thr.r & OTFDPC_DPC2_THR_MASK,
 461                DPC_OTF_2D_THR_R);
 462        regw_ip(base_addr, dpc_thr->det_thr.gr & OTFDPC_DPC2_THR_MASK,
 463                DPC_OTF_2D_THR_GR);
 464        regw_ip(base_addr, dpc_thr->det_thr.gb & OTFDPC_DPC2_THR_MASK,
 465                DPC_OTF_2D_THR_GB);
 466        regw_ip(base_addr, dpc_thr->det_thr.b & OTFDPC_DPC2_THR_MASK,
 467                DPC_OTF_2D_THR_B);
 468}
 469
 470void ipipe_set_otfdpc_regs(void *__iomem base_addr,
 471                           struct vpfe_ipipe_otfdpc *otfdpc)
 472{
 473        struct vpfe_ipipe_otfdpc_2_0_cfg *dpc_2_0 = &otfdpc->alg_cfg.dpc_2_0;
 474        struct vpfe_ipipe_otfdpc_3_0_cfg *dpc_3_0 = &otfdpc->alg_cfg.dpc_3_0;
 475        u32 val;
 476
 477        ipipe_clock_enable(base_addr);
 478
 479        regw_ip(base_addr, (otfdpc->en & 1), DPC_OTF_EN);
 480        if (!otfdpc->en)
 481                return;
 482
 483        /* dpc enabled */
 484        val = (otfdpc->det_method << OTF_DET_METHOD_SHIFT) | otfdpc->alg;
 485        regw_ip(base_addr, val, DPC_OTF_TYP);
 486
 487        if (otfdpc->det_method == VPFE_IPIPE_DPC_OTF_MIN_MAX) {
 488                /* ALG= 0, TYP = 0, DPC_OTF_2D_THR_[x]=0
 489                 * DPC_OTF_2C_THR_[x] = Maximum thresohld
 490                 * MinMax method
 491                 */
 492                dpc_2_0->det_thr.r = dpc_2_0->det_thr.gb =
 493                dpc_2_0->det_thr.gr = dpc_2_0->det_thr.b = 0;
 494                set_dpc_thresholds(base_addr, dpc_2_0);
 495                return;
 496        }
 497        /* MinMax2 */
 498        if (otfdpc->alg == VPFE_IPIPE_OTFDPC_2_0) {
 499                set_dpc_thresholds(base_addr, dpc_2_0);
 500                return;
 501        }
 502        regw_ip(base_addr, dpc_3_0->act_adj_shf &
 503                OTF_DPC3_0_SHF_MASK, DPC_OTF_3_SHF);
 504        /* Detection thresholds */
 505        regw_ip(base_addr, ((dpc_3_0->det_thr & OTF_DPC3_0_THR_MASK) <<
 506                OTF_DPC3_0_THR_SHIFT), DPC_OTF_3D_THR);
 507        regw_ip(base_addr, dpc_3_0->det_slp &
 508                OTF_DPC3_0_SLP_MASK, DPC_OTF_3D_SLP);
 509        regw_ip(base_addr, dpc_3_0->det_thr_min &
 510                OTF_DPC3_0_DET_MASK, DPC_OTF_3D_MIN);
 511        regw_ip(base_addr, dpc_3_0->det_thr_max &
 512                OTF_DPC3_0_DET_MASK, DPC_OTF_3D_MAX);
 513        /* Correction thresholds */
 514        regw_ip(base_addr, ((dpc_3_0->corr_thr & OTF_DPC3_0_THR_MASK) <<
 515                OTF_DPC3_0_THR_SHIFT), DPC_OTF_3C_THR);
 516        regw_ip(base_addr, dpc_3_0->corr_slp &
 517                OTF_DPC3_0_SLP_MASK, DPC_OTF_3C_SLP);
 518        regw_ip(base_addr, dpc_3_0->corr_thr_min &
 519                OTF_DPC3_0_CORR_MASK, DPC_OTF_3C_MIN);
 520        regw_ip(base_addr, dpc_3_0->corr_thr_max &
 521                OTF_DPC3_0_CORR_MASK, DPC_OTF_3C_MAX);
 522}
 523
 524/* 2D Noise filter */
 525void
 526ipipe_set_d2f_regs(void *__iomem base_addr, unsigned int id,
 527                   struct vpfe_ipipe_nf *noise_filter)
 528{
 529
 530        u32 offset = D2F_1ST;
 531        int count;
 532        u32 val;
 533
 534        if (id == IPIPE_D2F_2ND)
 535                offset = D2F_2ND;
 536
 537        ipipe_clock_enable(base_addr);
 538        regw_ip(base_addr, noise_filter->en & 1, offset + D2F_EN);
 539        if (!noise_filter->en)
 540                return;
 541
 542        /*noise filter enabled */
 543        /* Combine all the fields to make D2F_CFG register of IPIPE */
 544        val = ((noise_filter->spread_val & D2F_SPR_VAL_MASK) <<
 545                D2F_SPR_VAL_SHIFT) | ((noise_filter->shft_val &
 546                D2F_SHFT_VAL_MASK) << D2F_SHFT_VAL_SHIFT) |
 547                (noise_filter->gr_sample_meth << D2F_SAMPLE_METH_SHIFT) |
 548                ((noise_filter->apply_lsc_gain & 1) <<
 549                D2F_APPLY_LSC_GAIN_SHIFT) | D2F_USE_SPR_REG_VAL;
 550        regw_ip(base_addr, val, offset + D2F_TYP);
 551
 552        /* edge detection minimum */
 553        regw_ip(base_addr, noise_filter->edge_det_min_thr &
 554                D2F_EDGE_DET_THR_MASK, offset + D2F_EDG_MIN);
 555
 556        /* edge detection maximum */
 557        regw_ip(base_addr, noise_filter->edge_det_max_thr &
 558                D2F_EDGE_DET_THR_MASK, offset + D2F_EDG_MAX);
 559
 560        for (count = 0; count < VPFE_IPIPE_NF_STR_TABLE_SIZE; count++)
 561                regw_ip(base_addr,
 562                        (noise_filter->str[count] & D2F_STR_VAL_MASK),
 563                        offset + D2F_STR + count * 4);
 564
 565        for (count = 0; count < VPFE_IPIPE_NF_THR_TABLE_SIZE; count++)
 566                regw_ip(base_addr, noise_filter->thr[count] & D2F_THR_VAL_MASK,
 567                        offset + D2F_THR + count * 4);
 568}
 569
 570#define IPIPE_U8Q5(decimal, integer) \
 571        (((decimal & 0x1f) | ((integer & 0x7) << 5)))
 572
 573/* Green Imbalance Correction */
 574void ipipe_set_gic_regs(void *__iomem base_addr, struct vpfe_ipipe_gic *gic)
 575{
 576        u32 val;
 577
 578        ipipe_clock_enable(base_addr);
 579        regw_ip(base_addr, gic->en & 1, GIC_EN);
 580
 581        if (!gic->en)
 582                return;
 583
 584        /*gic enabled */
 585        val = (gic->wt_fn_type << GIC_TYP_SHIFT) |
 586              (gic->thr_sel << GIC_THR_SEL_SHIFT) |
 587              ((gic->apply_lsc_gain & 1) << GIC_APPLY_LSC_GAIN_SHIFT);
 588        regw_ip(base_addr, val, GIC_TYP);
 589
 590        regw_ip(base_addr, gic->gain & GIC_GAIN_MASK, GIC_GAN);
 591
 592        if (gic->gic_alg != VPFE_IPIPE_GIC_ALG_ADAPT_GAIN) {
 593                /* Constant Gain. Set threshold to maximum */
 594                regw_ip(base_addr, GIC_THR_MASK, GIC_THR);
 595                return;
 596        }
 597
 598        if (gic->thr_sel == VPFE_IPIPE_GIC_THR_REG) {
 599                regw_ip(base_addr, gic->thr & GIC_THR_MASK, GIC_THR);
 600                regw_ip(base_addr, gic->slope & GIC_SLOPE_MASK, GIC_SLP);
 601        } else {
 602                /* Use NF thresholds */
 603                val = IPIPE_U8Q5(gic->nf2_thr_gain.decimal,
 604                                gic->nf2_thr_gain.integer);
 605                regw_ip(base_addr, val, GIC_NFGAN);
 606        }
 607}
 608
 609#define IPIPE_U13Q9(decimal, integer) \
 610        (((decimal & 0x1ff) | ((integer & 0xf) << 9)))
 611/* White balance */
 612void ipipe_set_wb_regs(void *__iomem base_addr, struct vpfe_ipipe_wb *wb)
 613{
 614        u32 val;
 615
 616        ipipe_clock_enable(base_addr);
 617        /* Ofsets. S12 */
 618        regw_ip(base_addr, wb->ofst_r & WB_OFFSET_MASK, WB2_OFT_R);
 619        regw_ip(base_addr, wb->ofst_gr & WB_OFFSET_MASK, WB2_OFT_GR);
 620        regw_ip(base_addr, wb->ofst_gb & WB_OFFSET_MASK, WB2_OFT_GB);
 621        regw_ip(base_addr, wb->ofst_b & WB_OFFSET_MASK, WB2_OFT_B);
 622
 623        /* Gains. U13Q9 */
 624        val = IPIPE_U13Q9(wb->gain_r.decimal, wb->gain_r.integer);
 625        regw_ip(base_addr, val, WB2_WGN_R);
 626
 627        val = IPIPE_U13Q9(wb->gain_gr.decimal, wb->gain_gr.integer);
 628        regw_ip(base_addr, val, WB2_WGN_GR);
 629
 630        val = IPIPE_U13Q9(wb->gain_gb.decimal, wb->gain_gb.integer);
 631        regw_ip(base_addr, val, WB2_WGN_GB);
 632
 633        val = IPIPE_U13Q9(wb->gain_b.decimal, wb->gain_b.integer);
 634        regw_ip(base_addr, val, WB2_WGN_B);
 635}
 636
 637/* CFA */
 638void ipipe_set_cfa_regs(void *__iomem base_addr, struct vpfe_ipipe_cfa *cfa)
 639{
 640        ipipe_clock_enable(base_addr);
 641
 642        regw_ip(base_addr, cfa->alg, CFA_MODE);
 643        regw_ip(base_addr, cfa->hpf_thr_2dir & CFA_HPF_THR_2DIR_MASK,
 644                CFA_2DIR_HPF_THR);
 645        regw_ip(base_addr, cfa->hpf_slp_2dir & CFA_HPF_SLOPE_2DIR_MASK,
 646                CFA_2DIR_HPF_SLP);
 647        regw_ip(base_addr, cfa->hp_mix_thr_2dir & CFA_HPF_MIX_THR_2DIR_MASK,
 648                CFA_2DIR_MIX_THR);
 649        regw_ip(base_addr, cfa->hp_mix_slope_2dir & CFA_HPF_MIX_SLP_2DIR_MASK,
 650                CFA_2DIR_MIX_SLP);
 651        regw_ip(base_addr, cfa->dir_thr_2dir & CFA_DIR_THR_2DIR_MASK,
 652                CFA_2DIR_DIR_THR);
 653        regw_ip(base_addr, cfa->dir_slope_2dir & CFA_DIR_SLP_2DIR_MASK,
 654                CFA_2DIR_DIR_SLP);
 655        regw_ip(base_addr, cfa->nd_wt_2dir & CFA_ND_WT_2DIR_MASK,
 656                CFA_2DIR_NDWT);
 657        regw_ip(base_addr, cfa->hue_fract_daa & CFA_DAA_HUE_FRA_MASK,
 658                CFA_MONO_HUE_FRA);
 659        regw_ip(base_addr, cfa->edge_thr_daa & CFA_DAA_EDG_THR_MASK,
 660                CFA_MONO_EDG_THR);
 661        regw_ip(base_addr, cfa->thr_min_daa & CFA_DAA_THR_MIN_MASK,
 662                CFA_MONO_THR_MIN);
 663        regw_ip(base_addr, cfa->thr_slope_daa & CFA_DAA_THR_SLP_MASK,
 664                CFA_MONO_THR_SLP);
 665        regw_ip(base_addr, cfa->slope_min_daa & CFA_DAA_SLP_MIN_MASK,
 666                CFA_MONO_SLP_MIN);
 667        regw_ip(base_addr, cfa->slope_slope_daa & CFA_DAA_SLP_SLP_MASK,
 668                CFA_MONO_SLP_SLP);
 669        regw_ip(base_addr, cfa->lp_wt_daa & CFA_DAA_LP_WT_MASK,
 670                CFA_MONO_LPWT);
 671}
 672
 673void
 674ipipe_set_rgb2rgb_regs(void *__iomem base_addr, unsigned int id,
 675                       struct vpfe_ipipe_rgb2rgb *rgb)
 676{
 677        u32 offset_mask = RGB2RGB_1_OFST_MASK;
 678        u32 offset = RGB1_MUL_BASE;
 679        u32 integ_mask = 0xf;
 680        u32 val;
 681
 682        ipipe_clock_enable(base_addr);
 683
 684        if (id == IPIPE_RGB2RGB_2) {
 685                /* For second RGB module, gain integer is 3 bits instead
 686                of 4, offset has 11 bits insread of 13 */
 687                offset = RGB2_MUL_BASE;
 688                integ_mask = 0x7;
 689                offset_mask = RGB2RGB_2_OFST_MASK;
 690        }
 691        /* Gains */
 692        val = (rgb->coef_rr.decimal & 0xff) |
 693                ((rgb->coef_rr.integer & integ_mask) << 8);
 694        regw_ip(base_addr, val, offset + RGB_MUL_RR);
 695        val = (rgb->coef_gr.decimal & 0xff) |
 696                ((rgb->coef_gr.integer & integ_mask) << 8);
 697        regw_ip(base_addr, val, offset + RGB_MUL_GR);
 698        val = (rgb->coef_br.decimal & 0xff) |
 699                ((rgb->coef_br.integer & integ_mask) << 8);
 700        regw_ip(base_addr, val, offset + RGB_MUL_BR);
 701        val = (rgb->coef_rg.decimal & 0xff) |
 702                ((rgb->coef_rg.integer & integ_mask) << 8);
 703        regw_ip(base_addr, val, offset + RGB_MUL_RG);
 704        val = (rgb->coef_gg.decimal & 0xff) |
 705                ((rgb->coef_gg.integer & integ_mask) << 8);
 706        regw_ip(base_addr, val, offset + RGB_MUL_GG);
 707        val = (rgb->coef_bg.decimal & 0xff) |
 708                ((rgb->coef_bg.integer & integ_mask) << 8);
 709        regw_ip(base_addr, val, offset + RGB_MUL_BG);
 710        val = (rgb->coef_rb.decimal & 0xff) |
 711                ((rgb->coef_rb.integer & integ_mask) << 8);
 712        regw_ip(base_addr, val, offset + RGB_MUL_RB);
 713        val = (rgb->coef_gb.decimal & 0xff) |
 714                ((rgb->coef_gb.integer & integ_mask) << 8);
 715        regw_ip(base_addr, val, offset + RGB_MUL_GB);
 716        val = (rgb->coef_bb.decimal & 0xff) |
 717                ((rgb->coef_bb.integer & integ_mask) << 8);
 718        regw_ip(base_addr, val, offset + RGB_MUL_BB);
 719
 720        /* Offsets */
 721        regw_ip(base_addr, rgb->out_ofst_r & offset_mask, offset + RGB_OFT_OR);
 722        regw_ip(base_addr, rgb->out_ofst_g & offset_mask, offset + RGB_OFT_OG);
 723        regw_ip(base_addr, rgb->out_ofst_b & offset_mask, offset + RGB_OFT_OB);
 724}
 725
 726static void
 727ipipe_update_gamma_tbl(void *__iomem isp5_base_addr,
 728        struct vpfe_ipipe_gamma_entry *table, int size, u32 addr)
 729{
 730        int count;
 731        u32 val;
 732
 733        for (count = 0; count < size; count++) {
 734                val = table[count].slope & GAMMA_MASK;
 735                val |= (table[count].offset & GAMMA_MASK) << GAMMA_SHIFT;
 736                w_ip_table(isp5_base_addr, val, (addr + (count * 4)));
 737        }
 738}
 739
 740void
 741ipipe_set_gamma_regs(void *__iomem base_addr, void *__iomem isp5_base_addr,
 742                          struct vpfe_ipipe_gamma *gamma)
 743{
 744        int table_size;
 745        u32 val;
 746
 747        ipipe_clock_enable(base_addr);
 748        val = (gamma->bypass_r << GAMMA_BYPR_SHIFT) |
 749                (gamma->bypass_b << GAMMA_BYPG_SHIFT) |
 750                (gamma->bypass_g << GAMMA_BYPB_SHIFT) |
 751                (gamma->tbl_sel << GAMMA_TBL_SEL_SHIFT) |
 752                (gamma->tbl_size << GAMMA_TBL_SIZE_SHIFT);
 753
 754        regw_ip(base_addr, val, GMM_CFG);
 755
 756        if (gamma->tbl_sel != VPFE_IPIPE_GAMMA_TBL_RAM)
 757                return;
 758
 759        table_size = gamma->tbl_size;
 760
 761        if (!gamma->bypass_r && gamma->table_r != NULL)
 762                ipipe_update_gamma_tbl(isp5_base_addr, gamma->table_r,
 763                        table_size, GAMMA_R_START_ADDR);
 764        if (!gamma->bypass_b && gamma->table_b != NULL)
 765                ipipe_update_gamma_tbl(isp5_base_addr, gamma->table_b,
 766                        table_size, GAMMA_B_START_ADDR);
 767        if (!gamma->bypass_g && gamma->table_g != NULL)
 768                ipipe_update_gamma_tbl(isp5_base_addr, gamma->table_g,
 769                        table_size, GAMMA_G_START_ADDR);
 770}
 771
 772void
 773ipipe_set_3d_lut_regs(void *__iomem base_addr, void *__iomem isp5_base_addr,
 774                           struct vpfe_ipipe_3d_lut *lut_3d)
 775{
 776        struct vpfe_ipipe_3d_lut_entry *tbl;
 777        u32 bnk_index;
 778        u32 tbl_index;
 779        u32 val;
 780        u32 i;
 781
 782        ipipe_clock_enable(base_addr);
 783        regw_ip(base_addr, lut_3d->en, D3LUT_EN);
 784
 785        if (!lut_3d->en)
 786                return;
 787
 788        /* lut_3d enabled */
 789        if (!lut_3d->table)
 790                return;
 791
 792        /* valied table */
 793        tbl = lut_3d->table;
 794        for (i = 0 ; i < VPFE_IPIPE_MAX_SIZE_3D_LUT; i++) {
 795                /* Each entry has 0-9 (B), 10-19 (G) and
 796                20-29 R values */
 797                val = tbl[i].b & D3_LUT_ENTRY_MASK;
 798                val |= (tbl[i].g & D3_LUT_ENTRY_MASK) <<
 799                         D3_LUT_ENTRY_G_SHIFT;
 800                val |= (tbl[i].r & D3_LUT_ENTRY_MASK) <<
 801                         D3_LUT_ENTRY_R_SHIFT;
 802                bnk_index = i % 4;
 803                tbl_index = i >> 2;
 804                tbl_index <<= 2;
 805                if (bnk_index == 0)
 806                        w_ip_table(isp5_base_addr, val,
 807                                   tbl_index + D3L_TB0_START_ADDR);
 808                else if (bnk_index == 1)
 809                        w_ip_table(isp5_base_addr, val,
 810                                   tbl_index + D3L_TB1_START_ADDR);
 811                else if (bnk_index == 2)
 812                        w_ip_table(isp5_base_addr, val,
 813                                   tbl_index + D3L_TB2_START_ADDR);
 814                else
 815                        w_ip_table(isp5_base_addr, val,
 816                                   tbl_index + D3L_TB3_START_ADDR);
 817        }
 818}
 819
 820/* Lumina adjustments */
 821void
 822ipipe_set_lum_adj_regs(void *__iomem base_addr, struct ipipe_lum_adj *lum_adj)
 823{
 824        u32 val;
 825
 826        ipipe_clock_enable(base_addr);
 827
 828        /* combine fields of YUV_ADJ to set brightness and contrast */
 829        val = lum_adj->contrast << LUM_ADJ_CONTR_SHIFT |
 830              lum_adj->brightness << LUM_ADJ_BRIGHT_SHIFT;
 831        regw_ip(base_addr, val, YUV_ADJ);
 832}
 833
 834#define IPIPE_S12Q8(decimal, integer) \
 835        (((decimal & 0xff) | ((integer & 0xf) << 8)))
 836
 837void ipipe_set_rgb2ycbcr_regs(void *__iomem base_addr,
 838                              struct vpfe_ipipe_rgb2yuv *yuv)
 839{
 840        u32 val;
 841
 842        /* S10Q8 */
 843        ipipe_clock_enable(base_addr);
 844        val = IPIPE_S12Q8(yuv->coef_ry.decimal, yuv->coef_ry.integer);
 845        regw_ip(base_addr, val, YUV_MUL_RY);
 846        val = IPIPE_S12Q8(yuv->coef_gy.decimal, yuv->coef_gy.integer);
 847        regw_ip(base_addr, val, YUV_MUL_GY);
 848        val = IPIPE_S12Q8(yuv->coef_by.decimal, yuv->coef_by.integer);
 849        regw_ip(base_addr, val, YUV_MUL_BY);
 850        val = IPIPE_S12Q8(yuv->coef_rcb.decimal, yuv->coef_rcb.integer);
 851        regw_ip(base_addr, val, YUV_MUL_RCB);
 852        val = IPIPE_S12Q8(yuv->coef_gcb.decimal, yuv->coef_gcb.integer);
 853        regw_ip(base_addr, val, YUV_MUL_GCB);
 854        val = IPIPE_S12Q8(yuv->coef_bcb.decimal, yuv->coef_bcb.integer);
 855        regw_ip(base_addr, val, YUV_MUL_BCB);
 856        val = IPIPE_S12Q8(yuv->coef_rcr.decimal, yuv->coef_rcr.integer);
 857        regw_ip(base_addr, val, YUV_MUL_RCR);
 858        val = IPIPE_S12Q8(yuv->coef_gcr.decimal, yuv->coef_gcr.integer);
 859        regw_ip(base_addr, val, YUV_MUL_GCR);
 860        val = IPIPE_S12Q8(yuv->coef_bcr.decimal, yuv->coef_bcr.integer);
 861        regw_ip(base_addr, val, YUV_MUL_BCR);
 862        regw_ip(base_addr, yuv->out_ofst_y & RGB2YCBCR_OFST_MASK, YUV_OFT_Y);
 863        regw_ip(base_addr, yuv->out_ofst_cb & RGB2YCBCR_OFST_MASK, YUV_OFT_CB);
 864        regw_ip(base_addr, yuv->out_ofst_cr & RGB2YCBCR_OFST_MASK, YUV_OFT_CR);
 865}
 866
 867/* YUV 422 conversion */
 868void
 869ipipe_set_yuv422_conv_regs(void *__iomem base_addr,
 870                           struct vpfe_ipipe_yuv422_conv *conv)
 871{
 872        u32 val;
 873
 874        ipipe_clock_enable(base_addr);
 875
 876        /* Combine all the fields to make YUV_PHS register of IPIPE */
 877        val = (conv->chrom_pos << 0) | (conv->en_chrom_lpf << 1);
 878        regw_ip(base_addr, val, YUV_PHS);
 879}
 880
 881void
 882ipipe_set_gbce_regs(void *__iomem base_addr, void *__iomem isp5_base_addr,
 883                    struct vpfe_ipipe_gbce *gbce)
 884{
 885        unsigned int count;
 886        u32 mask = GBCE_Y_VAL_MASK;
 887
 888        if (gbce->type == VPFE_IPIPE_GBCE_GAIN_TBL)
 889                mask = GBCE_GAIN_VAL_MASK;
 890
 891        ipipe_clock_enable(base_addr);
 892        regw_ip(base_addr, gbce->en & 1, GBCE_EN);
 893
 894        if (!gbce->en)
 895                return;
 896
 897        regw_ip(base_addr, gbce->type, GBCE_TYP);
 898
 899        if (!gbce->table)
 900                return;
 901
 902        for (count = 0; count < VPFE_IPIPE_MAX_SIZE_GBCE_LUT ; count += 2)
 903                w_ip_table(isp5_base_addr, ((gbce->table[count + 1] & mask) <<
 904                GBCE_ENTRY_SHIFT) | (gbce->table[count] & mask),
 905                ((count/2) << 2) + GBCE_TB_START_ADDR);
 906}
 907
 908void
 909ipipe_set_ee_regs(void *__iomem base_addr, void *__iomem isp5_base_addr,
 910                  struct vpfe_ipipe_yee *ee)
 911{
 912        unsigned int count;
 913        u32 val;
 914
 915        ipipe_clock_enable(base_addr);
 916        regw_ip(base_addr, ee->en, YEE_EN);
 917
 918        if (!ee->en)
 919                return;
 920
 921        val = ee->en_halo_red & 1;
 922        val |= ee->merge_meth << YEE_HALO_RED_EN_SHIFT;
 923        regw_ip(base_addr, val, YEE_TYP);
 924
 925        regw_ip(base_addr, ee->hpf_shft, YEE_SHF);
 926        regw_ip(base_addr, ee->hpf_coef_00 & YEE_COEF_MASK, YEE_MUL_00);
 927        regw_ip(base_addr, ee->hpf_coef_01 & YEE_COEF_MASK, YEE_MUL_01);
 928        regw_ip(base_addr, ee->hpf_coef_02 & YEE_COEF_MASK, YEE_MUL_02);
 929        regw_ip(base_addr, ee->hpf_coef_10 & YEE_COEF_MASK, YEE_MUL_10);
 930        regw_ip(base_addr, ee->hpf_coef_11 & YEE_COEF_MASK, YEE_MUL_11);
 931        regw_ip(base_addr, ee->hpf_coef_12 & YEE_COEF_MASK, YEE_MUL_12);
 932        regw_ip(base_addr, ee->hpf_coef_20 & YEE_COEF_MASK, YEE_MUL_20);
 933        regw_ip(base_addr, ee->hpf_coef_21 & YEE_COEF_MASK, YEE_MUL_21);
 934        regw_ip(base_addr, ee->hpf_coef_22 & YEE_COEF_MASK, YEE_MUL_22);
 935        regw_ip(base_addr, ee->yee_thr & YEE_THR_MASK, YEE_THR);
 936        regw_ip(base_addr, ee->es_gain & YEE_ES_GAIN_MASK, YEE_E_GAN);
 937        regw_ip(base_addr, ee->es_thr1 & YEE_ES_THR1_MASK, YEE_E_THR1);
 938        regw_ip(base_addr, ee->es_thr2 & YEE_THR_MASK, YEE_E_THR2);
 939        regw_ip(base_addr, ee->es_gain_grad & YEE_THR_MASK, YEE_G_GAN);
 940        regw_ip(base_addr, ee->es_ofst_grad & YEE_THR_MASK, YEE_G_OFT);
 941
 942        if (ee->table == NULL)
 943                return;
 944
 945        for (count = 0; count < VPFE_IPIPE_MAX_SIZE_YEE_LUT; count += 2)
 946                w_ip_table(isp5_base_addr, ((ee->table[count + 1] &
 947                YEE_ENTRY_MASK) << YEE_ENTRY_SHIFT) |
 948                (ee->table[count] & YEE_ENTRY_MASK),
 949                ((count/2) << 2) + YEE_TB_START_ADDR);
 950}
 951
 952/* Chromatic Artifact Correction. CAR */
 953static void ipipe_set_mf(void *__iomem base_addr)
 954{
 955        /* typ to dynamic switch */
 956        regw_ip(base_addr, VPFE_IPIPE_CAR_DYN_SWITCH, CAR_TYP);
 957        /* Set SW0 to maximum */
 958        regw_ip(base_addr, CAR_MF_THR, CAR_SW);
 959}
 960
 961static void
 962ipipe_set_gain_ctrl(void *__iomem base_addr, struct vpfe_ipipe_car *car)
 963{
 964        regw_ip(base_addr, VPFE_IPIPE_CAR_CHR_GAIN_CTRL, CAR_TYP);
 965        regw_ip(base_addr, car->hpf, CAR_HPF_TYP);
 966        regw_ip(base_addr, car->hpf_shft & CAR_HPF_SHIFT_MASK, CAR_HPF_SHF);
 967        regw_ip(base_addr, car->hpf_thr, CAR_HPF_THR);
 968        regw_ip(base_addr, car->gain1.gain, CAR_GN1_GAN);
 969        regw_ip(base_addr, car->gain1.shft & CAR_GAIN1_SHFT_MASK, CAR_GN1_SHF);
 970        regw_ip(base_addr, car->gain1.gain_min & CAR_GAIN_MIN_MASK,
 971                CAR_GN1_MIN);
 972        regw_ip(base_addr, car->gain2.gain, CAR_GN2_GAN);
 973        regw_ip(base_addr, car->gain2.shft & CAR_GAIN2_SHFT_MASK, CAR_GN2_SHF);
 974        regw_ip(base_addr, car->gain2.gain_min & CAR_GAIN_MIN_MASK,
 975                CAR_GN2_MIN);
 976}
 977
 978void ipipe_set_car_regs(void *__iomem base_addr, struct vpfe_ipipe_car *car)
 979{
 980        u32 val;
 981
 982        ipipe_clock_enable(base_addr);
 983        regw_ip(base_addr, car->en, CAR_EN);
 984
 985        if (!car->en)
 986                return;
 987
 988        switch (car->meth) {
 989        case VPFE_IPIPE_CAR_MED_FLTR:
 990                ipipe_set_mf(base_addr);
 991                break;
 992
 993        case VPFE_IPIPE_CAR_CHR_GAIN_CTRL:
 994                ipipe_set_gain_ctrl(base_addr, car);
 995                break;
 996
 997        default:
 998                /* Dynamic switch between MF and Gain Ctrl. */
 999                ipipe_set_mf(base_addr);
1000                ipipe_set_gain_ctrl(base_addr, car);
1001                /* Set the threshold for switching between
1002                  * the two Here we overwrite the MF SW0 value
1003                  */
1004                regw_ip(base_addr, VPFE_IPIPE_CAR_DYN_SWITCH, CAR_TYP);
1005                val = car->sw1;
1006                val <<= CAR_SW1_SHIFT;
1007                val |= car->sw0;
1008                regw_ip(base_addr, val, CAR_SW);
1009        }
1010}
1011
1012/* Chromatic Gain Suppression */
1013void ipipe_set_cgs_regs(void *__iomem base_addr, struct vpfe_ipipe_cgs *cgs)
1014{
1015        ipipe_clock_enable(base_addr);
1016        regw_ip(base_addr, cgs->en, CGS_EN);
1017
1018        if (!cgs->en)
1019                return;
1020
1021        /* Set the bright side parameters */
1022        regw_ip(base_addr, cgs->h_thr, CGS_GN1_H_THR);
1023        regw_ip(base_addr, cgs->h_slope, CGS_GN1_H_GAN);
1024        regw_ip(base_addr, cgs->h_shft & CAR_SHIFT_MASK, CGS_GN1_H_SHF);
1025        regw_ip(base_addr, cgs->h_min, CGS_GN1_H_MIN);
1026}
1027
1028void rsz_src_enable(void *__iomem rsz_base, int enable)
1029{
1030        regw_rsz(rsz_base, enable, RSZ_SRC_EN);
1031}
1032
1033int rsz_enable(void *__iomem rsz_base, int rsz_id, int enable)
1034{
1035        if (rsz_id == RSZ_A) {
1036                regw_rsz(rsz_base, enable, RSZ_EN_A);
1037                /* We always enable RSZ_A. RSZ_B is enable upon request from
1038                 * application. So enable RSZ_SRC_EN along with RSZ_A
1039                 */
1040                regw_rsz(rsz_base, enable, RSZ_SRC_EN);
1041        } else if (rsz_id == RSZ_B) {
1042                regw_rsz(rsz_base, enable, RSZ_EN_B);
1043        } else {
1044                BUG();
1045        }
1046
1047        return 0;
1048}
1049