mirror of
https://github.com/thead-yocto-mirror/vi-kernel
synced 2026-06-21 08:52:26 +02:00
503 lines
17 KiB
C
Executable File
503 lines
17 KiB
C
Executable File
/****************************************************************************
|
|
*
|
|
* The MIT License (MIT)
|
|
*
|
|
* Copyright (c) 2020 VeriSilicon Holdings Co., Ltd.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
* to deal in the Software without restriction, including without limitation
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
* DEALINGS IN THE SOFTWARE.
|
|
*
|
|
*****************************************************************************
|
|
*
|
|
* The GPL License (GPL)
|
|
*
|
|
* Copyright (c) 2020 VeriSilicon Holdings Co., Ltd.
|
|
*
|
|
* 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; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* 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.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program;
|
|
*
|
|
*****************************************************************************
|
|
*
|
|
* Note: This software is released under dual MIT and GPL licenses. A
|
|
* recipient may use this file under the terms of either the MIT license or
|
|
* GPL License. If you wish to use only one license not the other, you can
|
|
* indicate your decision by deleting one of the above license notices in your
|
|
* version of this file.
|
|
*
|
|
*****************************************************************************/
|
|
#ifdef __KERNEL__
|
|
#include <linux/io.h>
|
|
#include <linux/module.h>
|
|
#endif
|
|
#include "mrv_all_bits.h"
|
|
#include "isp_ioctl.h"
|
|
#include "isp_types.h"
|
|
|
|
#define WDR3_WW (32)
|
|
#define WDR3_HH (32)
|
|
#define WDR3_MAX_VALUE (1023)
|
|
#define WDR3_GAIN_SHIFT (2)
|
|
#define WDR3_NORMALIZE (1024)
|
|
#define WDR3_NORMALIZE_SHIFT (10)
|
|
#ifdef ISP_WDR_V3_20BIT
|
|
#define MODULE_INPUT_BIT_DEPTH (20)
|
|
#else
|
|
#define MODULE_INPUT_BIT_DEPTH (12)
|
|
#endif
|
|
#define MODULE_OUTPUT_BIT_DEPTH (12)
|
|
|
|
extern MrvAllRegister_t *all_regs;
|
|
|
|
#ifdef ISP_WDR_V3
|
|
static void wdr3_hw_init(struct isp_ic_dev *dev)
|
|
{
|
|
|
|
struct isp_wdr3_context *wdr3 = &dev->wdr3;
|
|
u32 isp_wdr3_shift_0;
|
|
u32 isp_wdr3_shift_1;
|
|
|
|
u32 width, height;
|
|
u32 slice_block_area_factor;
|
|
u32 slice_value_weight[4];
|
|
u32 slice_pixel_slope_merge;
|
|
u32 slice_pixel_base_merge;
|
|
u32 slice_pixel_slope_adjust;
|
|
u32 slice_pixel_base_adjust;
|
|
u32 slice_pixel_slope_entropy;
|
|
u32 slice_pixel_base_entropy;
|
|
u32 slice_sigma_height;
|
|
u32 slice_sigma_width;
|
|
u32 slice_sigma_value;
|
|
u32 slice_block_width;
|
|
u32 slice_block_height;
|
|
u32 isp_wdr3_block_size;
|
|
u32 isp_wdr3_block_area_factor;
|
|
u32 isp_wdr3_value_weight;
|
|
u32 isp_wdr3_pixel_slope;
|
|
u32 isp_wdr3_entropy_slope;
|
|
u32 isp_wdr3_sigma_width;
|
|
u32 isp_wdr3_sigma_height;
|
|
u32 isp_wdr3_sigma_value;
|
|
u32 isp_wdr3_block_flag_width;
|
|
u32 isp_wdr3_block_flag_height;
|
|
u32 isp_wdr3_strength;
|
|
u32 width_left;
|
|
u32 width_count = 0;
|
|
u32 height_left;
|
|
u32 height_count = 0;
|
|
u32 val;
|
|
bool reg_flag = false;
|
|
int i, pos;
|
|
|
|
pr_info("enter %s\n", __func__);
|
|
|
|
width = isp_read_reg(dev, REG_ADDR(isp_acq_h_size));
|
|
height = isp_read_reg(dev, REG_ADDR(isp_acq_v_size));
|
|
|
|
pr_info("wdr3 res: %d %d \n", width, height);
|
|
/* firware initilization */
|
|
slice_pixel_slope_merge = 128;
|
|
slice_pixel_base_merge = 0;
|
|
slice_pixel_slope_adjust = 128;
|
|
slice_pixel_base_adjust = 0;
|
|
slice_pixel_slope_entropy = 204;
|
|
slice_pixel_base_entropy = 716;
|
|
|
|
slice_value_weight[0] = 6;
|
|
slice_value_weight[1] = 5;
|
|
slice_value_weight[2] = 5;
|
|
slice_value_weight[3] = 16;
|
|
|
|
slice_block_width = width / WDR3_WW;
|
|
slice_block_height = height / WDR3_HH;
|
|
slice_block_area_factor =
|
|
WDR3_NORMALIZE * WDR3_NORMALIZE / (slice_block_width *
|
|
slice_block_height);
|
|
slice_sigma_height =
|
|
WDR3_NORMALIZE * WDR3_NORMALIZE / slice_block_height;
|
|
slice_sigma_width = WDR3_NORMALIZE * WDR3_NORMALIZE / slice_block_width;
|
|
slice_sigma_value = WDR3_NORMALIZE * WDR3_NORMALIZE / WDR3_MAX_VALUE;
|
|
|
|
/* block flag configuration */
|
|
width_left = width - slice_block_width * WDR3_WW;
|
|
height_left = height - slice_block_height * WDR3_HH;
|
|
isp_wdr3_block_flag_width = 0;
|
|
isp_wdr3_block_flag_height = 0;
|
|
|
|
for (i = 0, width_count = 0;
|
|
(i < WDR3_WW) && (width_count < width_left); i++, width_count++) {
|
|
isp_wdr3_block_flag_width |= (1 << i);
|
|
}
|
|
|
|
for (i = 0, height_count = 0;
|
|
(i < WDR3_HH) && (height_count < height_left);
|
|
i++, height_count++) {
|
|
isp_wdr3_block_flag_height |= (1 << i);
|
|
}
|
|
|
|
slice_pixel_base_adjust += 255;
|
|
slice_pixel_base_merge += 255;
|
|
|
|
#ifndef __KERNEL__
|
|
//NOTE: register isp_wdr3_shift is read-only register on fpga, can not write
|
|
//NOTE: it is used by cmodel, So it should be config.
|
|
u32 slice_pixel_shift;
|
|
u32 slice_output_shift;
|
|
u32 isp_wdr3_shift;
|
|
|
|
slice_pixel_shift = MODULE_INPUT_BIT_DEPTH - 5;
|
|
slice_output_shift = MODULE_INPUT_BIT_DEPTH - MODULE_OUTPUT_BIT_DEPTH;
|
|
|
|
isp_wdr3_shift = isp_read_reg(dev, REG_ADDR(isp_wdr3_shift));
|
|
REG_SET_SLICE(isp_wdr3_shift, WDR3_PIXEL_SHIFT_BIT, slice_pixel_shift);
|
|
REG_SET_SLICE(isp_wdr3_shift, WDR3_OUTPUT_SHIFT_BIT,
|
|
slice_output_shift);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_shift), isp_wdr3_shift);
|
|
#endif
|
|
|
|
isp_wdr3_block_size = isp_read_reg(dev, REG_ADDR(isp_wdr3_block_size));
|
|
REG_SET_SLICE(isp_wdr3_block_size, WDR3_BLOCK_WIDTH, slice_block_width);
|
|
REG_SET_SLICE(isp_wdr3_block_size, WDR3_BLOCK_HEIGHT,
|
|
slice_block_height);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_block_size), isp_wdr3_block_size);
|
|
|
|
isp_wdr3_block_area_factor =
|
|
isp_read_reg(dev, REG_ADDR(isp_wdr3_block_area_factor));
|
|
REG_SET_SLICE(isp_wdr3_block_area_factor, WDR3_BLOCK_AREA_INVERSE,
|
|
slice_block_area_factor);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_block_area_factor),
|
|
isp_wdr3_block_area_factor);
|
|
isp_wdr3_value_weight =
|
|
isp_read_reg(dev, REG_ADDR(isp_wdr3_value_weight));
|
|
REG_SET_SLICE(isp_wdr3_value_weight, WDR3_VALUE_WEIGHT_0,
|
|
slice_value_weight[0]);
|
|
REG_SET_SLICE(isp_wdr3_value_weight, WDR3_VALUE_WEIGHT_1,
|
|
slice_value_weight[1]);
|
|
REG_SET_SLICE(isp_wdr3_value_weight, WDR3_VALUE_WEIGHT_2,
|
|
slice_value_weight[2]);
|
|
REG_SET_SLICE(isp_wdr3_value_weight, WDR3_VALUE_WEIGHT_3,
|
|
slice_value_weight[3]);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_value_weight),
|
|
isp_wdr3_value_weight);
|
|
|
|
isp_wdr3_strength = isp_read_reg(dev, REG_ADDR(isp_wdr3_strength));
|
|
REG_SET_SLICE(isp_wdr3_strength, WDR3_MAXIMUM_GAIN, wdr3->max_gain);
|
|
REG_SET_SLICE(isp_wdr3_strength, WDR3_GLOBAL_STRENGTH,
|
|
wdr3->global_strength);
|
|
REG_SET_SLICE(isp_wdr3_strength, WDR3_LOCAL_STRENGTH,
|
|
128);
|
|
REG_SET_SLICE(isp_wdr3_strength, WDR3_TOTAL_STRENGTH, wdr3->strength);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_strength), isp_wdr3_strength);
|
|
|
|
isp_wdr3_pixel_slope =
|
|
isp_read_reg(dev, REG_ADDR(isp_wdr3_pixel_slope));
|
|
REG_SET_SLICE(isp_wdr3_pixel_slope, WDR3_PIXEL_ADJUST_BASE,
|
|
slice_pixel_base_adjust);
|
|
REG_SET_SLICE(isp_wdr3_pixel_slope, WDR3_PIXEL_ADJUST_SLOPE,
|
|
slice_pixel_slope_adjust);
|
|
REG_SET_SLICE(isp_wdr3_pixel_slope, WDR3_PIXEL_MERGE_BASE,
|
|
slice_pixel_base_merge);
|
|
REG_SET_SLICE(isp_wdr3_pixel_slope, WDR3_PIXEL_MERGE_SLOPE,
|
|
slice_pixel_slope_merge);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_pixel_slope),
|
|
isp_wdr3_pixel_slope);
|
|
|
|
isp_wdr3_entropy_slope =
|
|
isp_read_reg(dev, REG_ADDR(isp_wdr3_entropy_slope));
|
|
REG_SET_SLICE(isp_wdr3_entropy_slope, WDR3_ENTROPY_BASE,
|
|
slice_pixel_base_entropy);
|
|
REG_SET_SLICE(isp_wdr3_entropy_slope, WDR3_ENTROPY_SLOPE,
|
|
slice_pixel_slope_entropy);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_entropy_slope),
|
|
isp_wdr3_entropy_slope);
|
|
|
|
isp_wdr3_sigma_width =
|
|
isp_read_reg(dev, REG_ADDR(isp_wdr3_sigma_width));
|
|
REG_SET_SLICE(isp_wdr3_sigma_width, WDR3_BILITERAL_WIDTH_SIGMA,
|
|
slice_sigma_width);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_sigma_width),
|
|
isp_wdr3_sigma_width);
|
|
|
|
isp_wdr3_sigma_height =
|
|
isp_read_reg(dev, REG_ADDR(isp_wdr3_sigma_height));
|
|
REG_SET_SLICE(isp_wdr3_sigma_height, WDR3_BILITERAL_HEIGHT_SIGMA,
|
|
slice_sigma_height);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_sigma_height),
|
|
isp_wdr3_sigma_height);
|
|
|
|
isp_wdr3_sigma_value =
|
|
isp_read_reg(dev, REG_ADDR(isp_wdr3_sigma_value));
|
|
REG_SET_SLICE(isp_wdr3_sigma_value, WDR3_BILITERAL_VALUE_SIGMA,
|
|
slice_sigma_value);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_sigma_value),
|
|
isp_wdr3_sigma_value);
|
|
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_block_flag_width),
|
|
isp_wdr3_block_flag_width);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_block_flag_height),
|
|
isp_wdr3_block_flag_height);
|
|
|
|
for (i = 0; i < 5; i++) {
|
|
reg_flag = i < 4;
|
|
pos = i * 3;
|
|
val =
|
|
wdr3->histogram[pos] << (reg_flag ?
|
|
WDR3_HISTOGRAM_CURVE0_SHIFT :
|
|
WDR3_HISTOGRAM_CURVE1_SHIFT);
|
|
val |=
|
|
wdr3->histogram[pos +
|
|
1] << (reg_flag ?
|
|
WDR3_HISTOGRAM_CURVE1_SHIFT :
|
|
WDR3_HISTOGRAM_CURVE2_SHIFT);
|
|
if (reg_flag)
|
|
REG_SET_SLICE(val, WDR3_HISTOGRAM_CURVE2,
|
|
wdr3->histogram[pos + 2]);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_histogram[i]), val);
|
|
|
|
val =
|
|
wdr3->entropy[pos] << (reg_flag ?
|
|
WDR3_ENTROPY_CONVERT0_SHIFT :
|
|
WDR3_ENTROPY_CONVERT1_SHIFT);
|
|
val |=
|
|
wdr3->entropy[pos +
|
|
1] << (reg_flag ? WDR3_ENTROPY_CONVERT1_SHIFT
|
|
: WDR3_ENTROPY_CONVERT2_SHIFT);
|
|
if (reg_flag)
|
|
REG_SET_SLICE(val, WDR3_ENTROPY_CONVERT2,
|
|
wdr3->entropy[pos + 2]);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_entropy[i]), val);
|
|
|
|
val =
|
|
wdr3->gamma_pre[pos] << (reg_flag ?
|
|
WDR3_GAMMA_PRE_CURVE0_SHIFT :
|
|
WDR3_GAMMA_PRE_CURVE1_SHIFT);
|
|
val |=
|
|
wdr3->gamma_pre[pos +
|
|
1] << (reg_flag ?
|
|
WDR3_GAMMA_PRE_CURVE1_SHIFT :
|
|
WDR3_GAMMA_PRE_CURVE2_SHIFT);
|
|
if (reg_flag)
|
|
REG_SET_SLICE(val, WDR3_GAMMA_PRE_CURVE2,
|
|
wdr3->gamma_pre[pos + 2]);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_gamma_pre[i]), val);
|
|
|
|
val =
|
|
wdr3->gamma_up[pos] << (reg_flag ?
|
|
WDR3_GAMMA_UP_CURVE0_SHIFT :
|
|
WDR3_GAMMA_UP_CURVE1_SHIFT);
|
|
val |=
|
|
wdr3->gamma_up[pos +
|
|
1] << (reg_flag ? WDR3_GAMMA_UP_CURVE1_SHIFT
|
|
: WDR3_GAMMA_UP_CURVE2_SHIFT);
|
|
if (reg_flag)
|
|
REG_SET_SLICE(val, WDR3_GAMMA_UP_CURVE2,
|
|
wdr3->gamma_up[pos + 2]);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_gamma_up[i]), val);
|
|
|
|
val =
|
|
wdr3->gamma_down[pos] << (reg_flag ?
|
|
WDR3_GAMMA_DOWN_CURVE0_SHIFT :
|
|
WDR3_GAMMA_DOWN_CURVE1_SHIFT);
|
|
val |=
|
|
wdr3->gamma_down[pos +
|
|
1] << (reg_flag ?
|
|
WDR3_GAMMA_DOWN_CURVE1_SHIFT :
|
|
WDR3_GAMMA_DOWN_CURVE2_SHIFT);
|
|
if (reg_flag)
|
|
REG_SET_SLICE(val, WDR3_GAMMA_DOWN_CURVE2,
|
|
wdr3->gamma_down[pos + 2]);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_gamma_down[i]), val);
|
|
|
|
val =
|
|
wdr3->distance_weight[pos] << (reg_flag ?
|
|
WDR3_DISTANCE_WEIGHT_CURVE0_SHIFT
|
|
:
|
|
WDR3_DISTANCE_WEIGHT_CURVE1_SHIFT);
|
|
val |=
|
|
wdr3->distance_weight[pos +
|
|
1] << (reg_flag ?
|
|
WDR3_DISTANCE_WEIGHT_CURVE1_SHIFT
|
|
:
|
|
WDR3_DISTANCE_WEIGHT_CURVE2_SHIFT);
|
|
if (reg_flag)
|
|
REG_SET_SLICE(val, WDR3_DISTANCE_WEIGHT_CURVE2,
|
|
wdr3->distance_weight[pos + 2]);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_distance_weight[i]), val);
|
|
|
|
val =
|
|
wdr3->difference_weight[pos] << (reg_flag ?
|
|
WDR3_DIFFERENCE_WEIGHT_CURVE0_SHIFT
|
|
:
|
|
WDR3_DIFFERENCE_WEIGHT_CURVE1_SHIFT);
|
|
val |=
|
|
wdr3->difference_weight[pos +
|
|
1] << (reg_flag ?
|
|
WDR3_DIFFERENCE_WEIGHT_CURVE1_SHIFT
|
|
:
|
|
WDR3_DIFFERENCE_WEIGHT_CURVE2_SHIFT);
|
|
if (reg_flag)
|
|
REG_SET_SLICE(val, WDR3_DIFFERENCE_WEIGHT_CURVE2,
|
|
wdr3->difference_weight[pos + 2]);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_difference_weight[i]),
|
|
val);
|
|
}
|
|
|
|
for (i = 0; i < 7; i++) {
|
|
val = 0;
|
|
REG_SET_SLICE(val, WDR3_GLOBAL_CURVE_INVERT0,
|
|
wdr3->invert_curve[i * 2]);
|
|
REG_SET_SLICE(val, WDR3_GLOBAL_CURVE_INVERT1,
|
|
wdr3->invert_curve[i * 2 + 1]);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_invert_curve[i]), val);
|
|
val = 0;
|
|
REG_SET_SLICE(val, WDR3_LINEAR_CURVE_INVERT0,
|
|
wdr3->invert_linear[i * 2]);
|
|
REG_SET_SLICE(val, WDR3_LINEAR_CURVE_INVERT1,
|
|
wdr3->invert_linear[i * 2 + 1]);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_invert_linear[i]), val);
|
|
}
|
|
|
|
isp_wdr3_shift_0 = 0;
|
|
REG_SET_SLICE(isp_wdr3_shift_0, WDR3_HISTOGRAM_SHIFT0, wdr3->shift[0]);
|
|
REG_SET_SLICE(isp_wdr3_shift_0, WDR3_HISTOGRAM_SHIFT1, wdr3->shift[1]);
|
|
REG_SET_SLICE(isp_wdr3_shift_0, WDR3_HISTOGRAM_SHIFT2, wdr3->shift[2]);
|
|
REG_SET_SLICE(isp_wdr3_shift_0, WDR3_HISTOGRAM_SHIFT3, wdr3->shift[3]);
|
|
REG_SET_SLICE(isp_wdr3_shift_0, WDR3_HISTOGRAM_SHIFT4, wdr3->shift[4]);
|
|
REG_SET_SLICE(isp_wdr3_shift_0, WDR3_HISTOGRAM_SHIFT5, wdr3->shift[5]);
|
|
REG_SET_SLICE(isp_wdr3_shift_0, WDR3_HISTOGRAM_SHIFT6, wdr3->shift[6]);
|
|
REG_SET_SLICE(isp_wdr3_shift_0, WDR3_HISTOGRAM_SHIFT7, wdr3->shift[7]);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_shift_0), isp_wdr3_shift_0);
|
|
|
|
isp_wdr3_shift_1 = 0;
|
|
REG_SET_SLICE(isp_wdr3_shift_1, WDR3_HISTOGRAM_SHIFT8, wdr3->shift[8]);
|
|
REG_SET_SLICE(isp_wdr3_shift_1, WDR3_HISTOGRAM_SHIFT9, wdr3->shift[9]);
|
|
REG_SET_SLICE(isp_wdr3_shift_1, WDR3_HISTOGRAM_SHIFT10,
|
|
wdr3->shift[10]);
|
|
REG_SET_SLICE(isp_wdr3_shift_1, WDR3_HISTOGRAM_SHIFT11,
|
|
wdr3->shift[11]);
|
|
REG_SET_SLICE(isp_wdr3_shift_1, WDR3_HISTOGRAM_SHIFT12,
|
|
wdr3->shift[12]);
|
|
REG_SET_SLICE(isp_wdr3_shift_1, WDR3_HISTOGRAM_SHIFT13,
|
|
wdr3->shift[13]);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_shift_1), isp_wdr3_shift_1);
|
|
|
|
{
|
|
uint32_t isp_wdr3_ctrl = isp_read_reg(dev, REG_ADDR(isp_wdr3_ctrl));
|
|
REG_SET_SLICE(isp_wdr3_ctrl, WDR3_ENABLE, 1);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_ctrl), isp_wdr3_ctrl);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
int isp_enable_wdr3(struct isp_ic_dev *dev)
|
|
{
|
|
#ifndef ISP_WDR_V3
|
|
pr_err("unsupported function: %s", __func__);
|
|
return -EINVAL;
|
|
#else
|
|
struct isp_wdr3_context *wdr3 = &dev->wdr3;
|
|
int32_t isp_wdr3_ctrl = isp_read_reg(dev, REG_ADDR(isp_wdr3_ctrl));
|
|
wdr3->enable = true;
|
|
REG_SET_SLICE(isp_wdr3_ctrl, WDR3_ENABLE, 1);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_ctrl), isp_wdr3_ctrl);
|
|
|
|
{
|
|
uint32_t isp_ctrl = isp_read_reg(dev, REG_ADDR(isp_ctrl));
|
|
REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_GEN_CFG_UPD, 1);
|
|
isp_write_reg(dev, REG_ADDR(isp_ctrl), isp_ctrl);
|
|
}
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
int isp_disable_wdr3(struct isp_ic_dev *dev)
|
|
{
|
|
#ifndef ISP_WDR_V3
|
|
pr_err("unsupported function: %s", __func__);
|
|
return -EINVAL;
|
|
#else
|
|
struct isp_wdr3_context *wdr3 = &dev->wdr3;
|
|
int32_t isp_wdr3_ctrl = isp_read_reg(dev, REG_ADDR(isp_wdr3_ctrl));
|
|
wdr3->enable = false;
|
|
REG_SET_SLICE(isp_wdr3_ctrl, WDR3_ENABLE, 0);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_ctrl), isp_wdr3_ctrl);
|
|
|
|
{
|
|
uint32_t isp_ctrl = isp_read_reg(dev, REG_ADDR(isp_ctrl));
|
|
REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_GEN_CFG_UPD, 1);
|
|
isp_write_reg(dev, REG_ADDR(isp_ctrl), isp_ctrl);
|
|
}
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
int isp_u_wdr3(struct isp_ic_dev *dev)
|
|
{
|
|
#ifndef ISP_WDR_V3
|
|
pr_err("unsupported function: %s", __func__);
|
|
return -EINVAL;
|
|
#else
|
|
wdr3_hw_init(dev);
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
int isp_s_wdr3(struct isp_ic_dev *dev)
|
|
{
|
|
|
|
#ifndef ISP_WDR_V3
|
|
pr_err("unsupported function: %s", __func__);
|
|
return -EINVAL;
|
|
#else
|
|
struct isp_wdr3_context *wdr3 = &dev->wdr3;
|
|
u32 isp_wdr3_strength = isp_read_reg(dev, REG_ADDR(isp_wdr3_strength));
|
|
u32 width = isp_read_reg(dev, REG_ADDR(isp_acq_h_size));
|
|
u32 height = isp_read_reg(dev, REG_ADDR(isp_acq_v_size));
|
|
width /= 32;
|
|
height /= 32;
|
|
|
|
REG_SET_SLICE(isp_wdr3_strength, WDR3_MAXIMUM_GAIN, wdr3->max_gain);
|
|
REG_SET_SLICE(isp_wdr3_strength, WDR3_GLOBAL_STRENGTH,
|
|
wdr3->global_strength);
|
|
REG_SET_SLICE(isp_wdr3_strength, WDR3_LOCAL_STRENGTH, 128);
|
|
REG_SET_SLICE(isp_wdr3_strength, WDR3_TOTAL_STRENGTH, wdr3->strength);
|
|
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_block_size),
|
|
width | (height << 9));
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_strength), isp_wdr3_strength);
|
|
isp_write_reg(dev, REG_ADDR(isp_wdr3_strength_shd), isp_wdr3_strength); /* cmodel use */
|
|
|
|
{
|
|
uint32_t isp_ctrl = isp_read_reg(dev, REG_ADDR(isp_ctrl));
|
|
REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_GEN_CFG_UPD, 1);
|
|
isp_write_reg(dev, REG_ADDR(isp_ctrl), isp_ctrl);
|
|
}
|
|
return 0;
|
|
#endif
|
|
}
|