123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433 |
- /****************************************************************************
- *
- * 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"
- #ifdef ISP_3DNR_V2
- extern MrvAllRegister_t *all_regs;
- static void dnr3_hw_init(struct isp_ic_dev *dev)
- {
- struct isp_3dnr_context *dnr3 = &dev->dnr3;
- u32 regVal = 0;
- int i, pos;
- /* spacial */
- u32 update_spacial = 900;
- u32 strength_curve_spacial = 64;
- u32 thr_edge_v_inv = 1024;
- u32 thr_edge_h_inv = 1024;
- u32 thr_range_s_inv = 1024;
- /* temperal */
- u32 update_temperal = 1020;
- u32 strength_curve_temperal = 64;
- u32 range_t_h = 1;
- u32 range_t_v = 1;
- u32 thr_range_t_inv = 1024;
- u32 thr_motion_inv = 1024;
- u32 range_d = 1;
- u32 thr_delta_h_inv = 1023;
- u32 thr_delta_v_inv = 1023;
- u32 thr_delta_t_inv = 1023;
- u32 strength = dnr3->strength;
- strength = MIN(MAX(strength, 0), 128);
- if (dnr3->init) { //for 3dnr init
- u32 isp_denoise3d_ctrl = isp_read_reg(dev, REG_ADDR(isp_denoise3d_ctrl));
- REG_SET_SLICE(isp_denoise3d_ctrl, DENOISE3D_READ_REF_EN, 1);
- REG_SET_SLICE(isp_denoise3d_ctrl, DENOISE3D_WRITE_REF_EN, 1);
- REG_SET_SLICE(isp_denoise3d_ctrl, DENOISE3D_HORIZONTAL_EN,
- dnr3->enable_h);
- REG_SET_SLICE(isp_denoise3d_ctrl, DENOISE3D_VERTICAL_EN,
- dnr3->enable_v);
- REG_SET_SLICE(isp_denoise3d_ctrl, DENOISE3D_TEMPERAL_EN,
- dnr3->enable_temperal);
- REG_SET_SLICE(isp_denoise3d_ctrl, DENOISE3D_DILATE_EN,
- dnr3->enable_dilate);
- REG_SET_SLICE(isp_denoise3d_ctrl, DENOISE3D_ENABLE, dnr3->enable);
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_ctrl), isp_denoise3d_ctrl);
- }
- regVal = 0;
- REG_SET_SLICE(regVal, DENOISE3D_STRENGTH_CURVE_SPACIAL,
- strength_curve_spacial);
- REG_SET_SLICE(regVal, DENOISE3D_THR_EDGE_H_INV, thr_edge_h_inv);
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_edge_h), regVal);
- regVal = 0;
- REG_SET_SLICE(regVal, DENOISE3D_STRENGTH_CURVE_TEMPERAL,
- strength_curve_temperal);
- REG_SET_SLICE(regVal, DENOISE3D_THR_EDGE_V_INV, thr_edge_v_inv);
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_edge_v), regVal);
- regVal = 0;
- REG_SET_SLICE(regVal, DENOISE3D_RANGE_S_INV, thr_range_s_inv);
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_range_s), regVal);
- regVal = 0;
- REG_SET_SLICE(regVal, DENOISE3D_RANGE_T_H, range_t_h);
- REG_SET_SLICE(regVal, DENOISE3D_RANGE_T_V, range_t_v);
- REG_SET_SLICE(regVal, DENOISE3D_RANGE_T_INV, thr_range_t_inv);
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_range_t), regVal);
- regVal = 0;
- REG_SET_SLICE(regVal, DENOISE3D_RANGE_D, range_d);
- REG_SET_SLICE(regVal, DENOISE3D_MOTION_INV, thr_motion_inv);
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_motion), regVal);
- regVal = 0;
- REG_SET_SLICE(regVal, DENOISE3D_DELTA_H_INV, thr_delta_h_inv);
- REG_SET_SLICE(regVal, DENOISE3D_DELTA_V_INV, thr_delta_v_inv);
- REG_SET_SLICE(regVal, DENOISE3D_DELTA_T_INV, thr_delta_t_inv);
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_delta_inv), regVal);
- /* spacial */
- for (i = 0; i < 6; i++) {
- regVal = 0;
- pos = i * 3;
- if (i < 5) {
- REG_SET_SLICE(regVal, DENOISE3D_SPACIAL_CURVE0,
- dnr3->spacial_curve[pos + 0]);
- REG_SET_SLICE(regVal, DENOISE3D_SPACIAL_CURVE1,
- dnr3->spacial_curve[pos + 1]);
- REG_SET_SLICE(regVal, DENOISE3D_SPACIAL_CURVE2,
- dnr3->spacial_curve[pos + 2]);
- } else {
- REG_SET_SLICE(regVal, DENOISE3D_SPACIAL_CURVE1,
- dnr3->spacial_curve[pos + 0]);
- REG_SET_SLICE(regVal, DENOISE3D_SPACIAL_CURVE2,
- dnr3->spacial_curve[pos + 1]);
- }
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_curve_s[i]), regVal);
- regVal = 0;
- if (i < 5) {
- REG_SET_SLICE(regVal, DENOISE3D_TEMPERAL_CURVE0,
- dnr3->temperal_curve[pos + 0]);
- REG_SET_SLICE(regVal, DENOISE3D_TEMPERAL_CURVE1,
- dnr3->temperal_curve[pos + 1]);
- REG_SET_SLICE(regVal, DENOISE3D_TEMPERAL_CURVE2,
- dnr3->temperal_curve[pos + 2]);
- } else {
- REG_SET_SLICE(regVal, DENOISE3D_TEMPERAL_CURVE1,
- dnr3->temperal_curve[pos + 0]);
- REG_SET_SLICE(regVal, DENOISE3D_TEMPERAL_CURVE2,
- dnr3->temperal_curve[pos + 1]);
- }
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_curve_t[i]), regVal);
- }
- regVal = 0;
- REG_SET_SLICE(regVal, DENOISE3D_UPDATE_SPACIAL, update_spacial);
- REG_SET_SLICE(regVal, DENOISE3D_UPDATE_TEMPERAL, update_temperal);
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_strength), regVal);
- }
- int isp_s_3dnr_cmp(struct isp_ic_dev *dev) {
- struct isp_3dnr_compress_context *compress = &dev->dnr3.compress;
- u32 isp_denoise3d_weight1 = 0; // isp_read_reg(dev, REG_ADDR(isp_denoise3d_weight1));
- u32 isp_denoise3d_weight2 = 0; // isp_read_reg(dev, REG_ADDR(isp_denoise3d_weight2));
- int i = 0;
- for (i = 0; i < 4; i++) {
- isp_denoise3d_weight1 |= (compress->weight_down[i] & DENOISE3D_WEIGHT_MASK) << (3 - i) * 4;
- }
- REG_SET_SLICE(isp_denoise3d_weight1, DENOISE3D_WEIGHT_UP_Y0, compress->weight_up_y[0]);
- REG_SET_SLICE(isp_denoise3d_weight1, DENOISE3D_WEIGHT_UP_Y1, compress->weight_up_y[1]);
- for (i = 0; i < 8; i++) {
- isp_denoise3d_weight2 |= (compress->weight_up[i] & DENOISE3D_WEIGHT_MASK) << (7 - i) * 4;
- }
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_weight1), isp_denoise3d_weight1);
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_weight2), isp_denoise3d_weight2);
- return 0;
- }
- int isp_s_3dnr(struct isp_ic_dev *dev)
- {
- struct isp_3dnr_context *dnr3 = &dev->dnr3;
- u32 isp_denoise3d_strength, isp_denoise3d_motion, isp_denoise3d_delta_inv;
- u32 isp_denoise3d_ctrl;
- isp_info("enter %s\n", __func__);
- if (dnr3->update_bin) {
- dnr3_hw_init(dev);
- }
- isp_denoise3d_strength = isp_read_reg(dev, REG_ADDR(isp_denoise3d_strength));
- if (!dnr3->enable) {
- REG_SET_SLICE(isp_denoise3d_strength, DENOISE3D_STRENGTH, 0);
- } else {
- REG_SET_SLICE(isp_denoise3d_strength, DENOISE3D_STRENGTH, dnr3->strength);
- }
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_strength),
- isp_denoise3d_strength);
- isp_denoise3d_motion =
- isp_read_reg(dev, REG_ADDR(isp_denoise3d_motion));
- REG_SET_SLICE(isp_denoise3d_motion, DENOISE3D_MOTION_INV, dnr3->motion_factor);
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_motion),
- isp_denoise3d_motion);
- isp_denoise3d_delta_inv =
- isp_read_reg(dev, REG_ADDR(isp_denoise3d_delta_inv));
- REG_SET_SLICE(isp_denoise3d_delta_inv, DENOISE3D_DELTA_T_INV, dnr3->delta_factor);
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_delta_inv),
- isp_denoise3d_delta_inv);
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_dummy_hblank), 0x80);
- isp_denoise3d_ctrl = isp_read_reg(dev, REG_ADDR(isp_denoise3d_ctrl));
- if (dnr3->enable) {
- isp_s_3dnr_cmp(dev);
- REG_SET_SLICE(isp_denoise3d_ctrl, DENOISE3D_ENABLE, 1);
- }
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_ctrl), isp_denoise3d_ctrl);
- return 0;
- }
- int isp_s_3dnr_motion(struct isp_ic_dev *dev)
- {
- struct isp_3dnr_context *dnr3 = &dev->dnr3;
- u32 isp_denoise3d_motion;
- u32 isp_ctrl;
- isp_denoise3d_motion =
- isp_read_reg(dev, REG_ADDR(isp_denoise3d_motion));
- REG_SET_SLICE(isp_denoise3d_motion, DENOISE3D_MOTION_INV, dnr3->motion_factor);
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_motion),
- isp_denoise3d_motion);
- 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;
- }
- int isp_s_3dnr_delta(struct isp_ic_dev *dev)
- {
- struct isp_3dnr_context *dnr3 = &dev->dnr3;
- u32 isp_denoise3d_delta_inv;
- u32 isp_ctrl;
- isp_denoise3d_delta_inv =
- isp_read_reg(dev, REG_ADDR(isp_denoise3d_delta_inv));
- REG_SET_SLICE(isp_denoise3d_delta_inv, DENOISE3D_DELTA_T_INV, dnr3->delta_factor);
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_delta_inv),
- isp_denoise3d_delta_inv);
- 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;
- }
- int isp_u_3dnr(struct isp_ic_dev *dev, struct isp_3dnr_update *dnr3_update)
- {
- u32 regVal = 0;
- isp_info("enter %s\n", __func__);
- regVal = isp_read_reg(dev, REG_ADDR(isp_denoise3d_strength));
- REG_SET_SLICE(regVal, DENOISE3D_STRENGTH, dev->dnr3.strength);
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_strength), regVal);
- regVal = 0;
- regVal = isp_read_reg(dev, REG_ADDR(isp_denoise3d_edge_h));
- REG_SET_SLICE(regVal, DENOISE3D_THR_EDGE_H_INV,
- dnr3_update->thr_edge_h_inv);
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_edge_h), regVal);
- regVal = 0;
- regVal = isp_read_reg(dev, REG_ADDR(isp_denoise3d_edge_v));
- REG_SET_SLICE(regVal, DENOISE3D_THR_EDGE_V_INV,
- dnr3_update->thr_edge_v_inv);
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_edge_v), regVal);
- regVal = 0;
- regVal = isp_read_reg(dev, REG_ADDR(isp_denoise3d_range_s));
- REG_SET_SLICE(regVal, DENOISE3D_RANGE_S_INV,
- dnr3_update->thr_range_s_inv);
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_range_s), regVal);
- regVal = 0;
- regVal = isp_read_reg(dev, REG_ADDR(isp_denoise3d_range_t));
- REG_SET_SLICE(regVal, DENOISE3D_RANGE_T_H, dnr3_update->range_t_h);
- REG_SET_SLICE(regVal, DENOISE3D_RANGE_T_V, dnr3_update->range_t_v);
- REG_SET_SLICE(regVal, DENOISE3D_RANGE_T_INV,
- dnr3_update->thr_range_t_inv);
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_range_t), regVal);
- regVal = 0;
- regVal = isp_read_reg(dev, REG_ADDR(isp_denoise3d_motion));
- REG_SET_SLICE(regVal, DENOISE3D_RANGE_D, dnr3_update->range_d);
- REG_SET_SLICE(regVal, DENOISE3D_MOTION_INV,
- dnr3_update->thr_motion_inv);
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_motion), regVal);
- regVal = 0;
- regVal = isp_read_reg(dev, REG_ADDR(isp_denoise3d_delta_inv));
- REG_SET_SLICE(regVal, DENOISE3D_DELTA_H_INV,
- dnr3_update->thr_delta_h_inv);
- REG_SET_SLICE(regVal, DENOISE3D_DELTA_V_INV,
- dnr3_update->thr_delta_v_inv);
- REG_SET_SLICE(regVal, DENOISE3D_DELTA_T_INV,
- dnr3_update->thr_delta_t_inv);
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_delta_inv), regVal);
- return 0;
- }
- int isp_g_3dnr(struct isp_ic_dev *dev, u32 * avg)
- {
- if (!dev || !avg) {
- return -EINVAL;
- }
- *avg = isp_read_reg(dev, REG_ADDR(isp_denoise3d_average));
- return 0;
- }
- int isp_u_3dnr_strength(struct isp_ic_dev *dev)
- {
- uint32_t isp_denoise3d_strength;
- isp_denoise3d_strength = isp_read_reg(dev, REG_ADDR(isp_denoise3d_strength));
- REG_SET_SLICE(isp_denoise3d_strength, DENOISE3D_STRENGTH, dev->dnr3.strength);
- isp_write_reg(dev, REG_ADDR(isp_denoise3d_strength), isp_denoise3d_strength);
- return 0;
- }
- int isp_r_3dnr(struct isp_ic_dev *dev)
- {
- #ifndef ISP_3DNR_V2_V1
- return -1;
- #else
- u32 in_width, in_height;
- u32 size, lval;
- u32 miv2_sp2_bus_id;
- u32 miv2_sp2_fmt;
- u32 miv2_ctrl = isp_read_reg(dev, REG_ADDR(miv2_ctrl));
- u32 miv2_imsc = isp_read_reg(dev, REG_ADDR(miv2_imsc));
- u32 miv2_sp2_ctrl = isp_read_reg(dev, REG_ADDR(miv2_sp2_ctrl));
- //SP2_RAW_PATH_ENABLE is shadow bit, need set SP2_MI_CFG_UPD to update to shadow.
- //So here config before set SP2_MI_CFG_UPD
- REG_SET_SLICE(miv2_ctrl, SP2_RAW_RDMA_PATH_ENABLE, 1);
- REG_SET_SLICE(miv2_ctrl, SP2_RAW_PATH_ENABLE, 1);
- isp_write_reg(dev, REG_ADDR(miv2_ctrl), miv2_ctrl);
- in_width = isp_read_reg(dev, REG_ADDR(isp_out_h_size));
- in_height = isp_read_reg(dev, REG_ADDR(isp_out_v_size));
- lval = (in_width * 12 + 127)/ 128;
- lval <<= 4;
- size = in_height * lval; //raw12 unaligned
- //write reference frame config
- isp_write_reg(dev, REG_ADDR(miv2_sp2_raw_base_ad_init), dev->dnr3.pa);
- isp_write_reg(dev, REG_ADDR(miv2_sp2_raw_size_init), size);
- isp_write_reg(dev, REG_ADDR(miv2_sp2_raw_offs_cnt_init), 0);
- isp_write_reg(dev, REG_ADDR(miv2_sp2_raw_llength), lval);
- isp_write_reg(dev, REG_ADDR(miv2_sp2_raw_pic_width), in_width);
- isp_write_reg(dev, REG_ADDR(miv2_sp2_raw_pic_height), in_height);
- isp_write_reg(dev, REG_ADDR(miv2_sp2_raw_pic_size), size);
- miv2_sp2_bus_id = isp_read_reg(dev, REG_ADDR(miv2_sp2_bus_id));
- REG_SET_SLICE(miv2_sp2_bus_id, SP2_WR_ID_EN, 1);
- REG_SET_SLICE(miv2_sp2_bus_id, SP2_RD_ID_EN, 1);
- REG_SET_SLICE(miv2_sp2_bus_id, SP2_RD_BURST_LEN, 2); //sp2 rd burst lenghth 16
- REG_SET_SLICE(miv2_sp2_bus_id, SP2_BUS_SW_EN, 1);
- isp_write_reg(dev, REG_ADDR(miv2_sp2_bus_id), miv2_sp2_bus_id);
- miv2_sp2_fmt = isp_read_reg(dev, REG_ADDR(miv2_sp2_fmt));
- REG_SET_SLICE(miv2_sp2_fmt, SP2_WR_RAW_BIT, 2); //raw12
- REG_SET_SLICE(miv2_sp2_fmt, SP2_WR_RAW_ALIGNED, 0); //unaligned
- REG_SET_SLICE(miv2_sp2_fmt, SP2_RD_RAW_BIT, 2); //raw12
- REG_SET_SLICE(miv2_sp2_fmt, SP2_RD_RAW_ALIGNED, 0); //unaligned
- isp_write_reg(dev, REG_ADDR(miv2_sp2_fmt), miv2_sp2_fmt);
- //read reference frame config
- isp_write_reg(dev, REG_ADDR(miv2_sp2_dma_raw_pic_start_ad), dev->dnr3.pa);
- isp_write_reg(dev, REG_ADDR(miv2_sp2_dma_raw_pic_width), in_width);
- isp_write_reg(dev, REG_ADDR(miv2_sp2_dma_raw_pic_llength), lval);
- isp_write_reg(dev, REG_ADDR(miv2_sp2_dma_raw_pic_lval), lval);
- isp_write_reg(dev, REG_ADDR(miv2_sp2_dma_raw_pic_size), size);
- REG_SET_SLICE(miv2_sp2_ctrl, SP2_RD_RAW_CFG_UPDATE, 1);
- REG_SET_SLICE(miv2_sp2_ctrl, SP2_RD_RAW_AUTO_UPDATE, 1);
- REG_SET_SLICE(miv2_sp2_ctrl, SP2_MI_CFG_UPD, 1);
- /* we successfully programmed a buffer to marvin, so we need
- * to enable updateing of base and offset registers */
- miv2_sp2_ctrl |= (SP2_INIT_BASE_EN_MASK | SP2_INIT_OFFSET_EN_MASK);
- isp_write_reg(dev, REG_ADDR(miv2_sp2_ctrl), miv2_sp2_ctrl);
- miv2_imsc |= SP2_DMA_RAW_READY_MASK;
- isp_write_reg(dev, REG_ADDR(miv2_imsc), miv2_imsc);
- return 0;
- #endif
- }
- #endif
|