123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626 |
- /****************************************************************************
- *
- * 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.
- *
- *****************************************************************************/
- #include "mrv_all_bits.h"
- #include "isp_ioctl.h"
- #include "isp_types.h"
- #ifdef ISP_MIV1
- extern MrvAllRegister_t *all_regs;
- static int getRawBit(u32 type, u32 *bit, u32 *len)
- {
- *len = 16;
- switch (type) {
- case ISP_PICBUF_TYPE_RAW8:
- *bit = 0;
- *len = 8;
- break;
- #if 0 /* normal process, need pass type from engine. */
- case ISP_PICBUF_TYPE_RAW10:
- *bit = 1;
- break;
- case ISP_PICBUF_TYPE_RAW12:
- *bit = 2;
- break;
- case ISP_PICBUF_TYPE_RAW14:
- *bit = 3;
- break;
- case ISP_PICBUF_TYPE_RAW16:
- *bit = 4;
- break;
- #else /* WA */
- case ISP_PICBUF_TYPE_RAW10:
- case ISP_PICBUF_TYPE_RAW12:
- case ISP_PICBUF_TYPE_RAW14:
- case ISP_PICBUF_TYPE_RAW16:
- *bit = 4;
- break;
- #endif
- default:
- isp_err("unsupport raw formt: %d\n", type);
- return -1;
- }
- return 0;
- }
- int isp_ioc_cfg_dma(struct isp_ic_dev *dev, void __user *args)
- {
- return 0;
- }
- int isp_ioc_start_dma_read(struct isp_ic_dev *dev, void __user *args)
- {
- struct isp_dma_context dma;
- u32 mi_dma_ctrl = isp_read_reg(dev, REG_ADDR(mi_dma_ctrl));
- u32 llength = 0, mcm_rd_fmt_bit = 0;
- u32 mi_imsc = 0, mcm_fmt = 0;
- isp_info("enter %s\n", __func__);
- viv_check_retval(copy_from_user(&dma, args, sizeof(dma)));
- REG_SET_SLICE(mi_dma_ctrl, MRV_MI_DMA_BURST_LEN_LUM, dma.burst_y);
- REG_SET_SLICE(mi_dma_ctrl, MRV_MI_DMA_BURST_LEN_CHROM, dma.burst_c);
- isp_write_reg(dev, REG_ADDR(mi_dma_y_pic_start_ad),
- (MRV_MI_DMA_Y_PIC_START_AD_MASK & dma.base));
- getRawBit(dma.type, &mcm_rd_fmt_bit, &llength);
- llength = dma.width * llength / 8;
- REG_SET_SLICE(mcm_fmt, MCM_RD_RAW_BIT, mcm_rd_fmt_bit);
- isp_write_reg(dev, REG_ADDR(mi_dma_y_pic_width),
- (MRV_MI_DMA_Y_PIC_WIDTH_MASK & dma.width));
- isp_write_reg(dev, REG_ADDR(mi_dma_y_llength),
- (MRV_MI_DMA_Y_LLENGTH_MASK & llength));
- isp_write_reg(dev, REG_ADDR(mi_dma_y_pic_size),
- (MRV_MI_DMA_Y_PIC_SIZE_MASK & (llength * dma.height)));
- isp_write_reg(dev, REG_ADDR(mi_dma_cb_pic_start_ad), 0);
- isp_write_reg(dev, REG_ADDR(mi_dma_cr_pic_start_ad), 0);
- isp_write_reg(dev, REG_ADDR(mi_dma_ctrl), mi_dma_ctrl);
- isp_write_reg(dev, REG_ADDR(mi_dma_status), 0);
- isp_write_reg(dev, REG_ADDR(mi_dma_y_raw_fmt), mcm_fmt);
- isp_write_reg(dev, REG_ADDR(mi_dma_y_raw_lval),
- (MRV_MI_DMA_Y_LLENGTH_MASK & llength));
- mi_imsc = isp_read_reg(dev, REG_ADDR(mi_imsc));
- mi_imsc |= MRV_MI_DMA_READY_MASK;
- isp_write_reg(dev, REG_ADDR(mi_imsc), mi_imsc);
- isp_write_reg(dev, REG_ADDR(mi_dma_start), MRV_MI_DMA_START_MASK);
- return 0;
- }
- u32 getScaleFactor(u32 src, u32 dst)
- {
- if (dst > src) {
- return ((65536 * (src - 1)) / (dst - 1));
- } else if (dst < src) {
- return ((65536 * (dst - 1)) / (src - 1)) + 1;
- }
- return 65536;
- }
- int set_scaling(int id, struct isp_ic_dev *dev, bool stabilization)
- {
- u32 addr, ctrl;
- u32 iw, ih, ow, oh;
- u32 inputWidth, inputHeight, outputWidth, outputHeight;
- u32 scale_hy, scale_hcb, scale_hcr, scale_vy, scale_vc;
- struct isp_mi_data_path_context *path = &dev->mi.path[id];
- if (id == IC_MI_PATH_MAIN) { /* mp */
- addr = REG_ADDR(mrsz_ctrl);
- } else if (id == IC_MI_PATH_SELF) { /* sp */
- addr = REG_ADDR(srsz_ctrl);
- } else {
- return -EINVAL;
- }
- inputWidth = path->in_width;
- inputHeight = path->in_height;
- outputWidth = path->out_width;
- outputHeight = path->out_height;
- if (stabilization) { /* enabled image stabilization. */
- inputWidth = isp_read_reg(dev, REG_ADDR(isp_is_h_size));
- inputHeight = isp_read_reg(dev, REG_ADDR(isp_is_v_size));
- }
- ctrl = isp_read_reg(dev, addr);
- iw = inputWidth / 2;
- ih = inputHeight;
- ow = outputWidth / 2;
- oh = outputHeight;
- switch (path->in_mode) {
- case IC_MI_DATAMODE_YUV422:
- oh = outputHeight;
- break;
- case IC_MI_DATAMODE_YUV420:
- oh = outputHeight / 2; /* scale cbcr */
- break;
- default:
- return -EFAULT;
- }
- REG_SET_SLICE(ctrl, MRV_MRSZ_SCALE_HY_ENABLE,
- inputWidth != outputWidth);
- REG_SET_SLICE(ctrl, MRV_MRSZ_SCALE_VY_ENABLE,
- inputHeight != outputHeight);
- REG_SET_SLICE(ctrl, MRV_MRSZ_SCALE_HY_UP, inputWidth < outputWidth);
- REG_SET_SLICE(ctrl, MRV_MRSZ_SCALE_VY_UP, inputHeight < outputHeight);
- scale_hy = getScaleFactor(inputWidth, outputWidth);
- scale_vy = getScaleFactor(inputHeight, outputHeight);
- REG_SET_SLICE(ctrl, MRV_MRSZ_SCALE_HC_ENABLE, iw != ow);
- REG_SET_SLICE(ctrl, MRV_MRSZ_SCALE_VC_ENABLE, ih != oh);
- REG_SET_SLICE(ctrl, MRV_MRSZ_SCALE_HC_UP, iw < ow);
- REG_SET_SLICE(ctrl, MRV_MRSZ_SCALE_VC_UP, ih < oh);
- scale_hcr = getScaleFactor(iw, ow);
- scale_hcb = getScaleFactor(iw, ow);
- scale_vc = getScaleFactor(ih, oh);
- REG_SET_SLICE(ctrl, MRV_MRSZ_AUTO_UPD, 1);
- if (id == IC_MI_PATH_MAIN) {
- isp_write_reg(dev, REG_ADDR(mrsz_scale_vc), scale_vc);
- isp_write_reg(dev, REG_ADDR(mrsz_scale_vy), scale_vy);
- isp_write_reg(dev, REG_ADDR(mrsz_scale_hcr), scale_hcr);
- isp_write_reg(dev, REG_ADDR(mrsz_scale_hcb), scale_hcb);
- isp_write_reg(dev, REG_ADDR(mrsz_scale_hy), scale_hy);
- isp_write_reg(dev, REG_ADDR(mrsz_ctrl),
- ctrl | MRV_MRSZ_CFG_UPD_MASK);
- } else if (id == IC_MI_PATH_SELF) {
- isp_write_reg(dev, REG_ADDR(srsz_scale_vc), scale_vc);
- isp_write_reg(dev, REG_ADDR(srsz_scale_vy), scale_vy);
- isp_write_reg(dev, REG_ADDR(srsz_scale_hcr), scale_hcr);
- isp_write_reg(dev, REG_ADDR(srsz_scale_hcb), scale_hcb);
- isp_write_reg(dev, REG_ADDR(srsz_scale_hy), scale_hy);
- isp_write_reg(dev, REG_ADDR(srsz_ctrl),
- ctrl | MRV_MRSZ_CFG_UPD_MASK);
- }
- return 0;
- }
- #ifdef ISP_MI_BP
- int isp_bppath_start(struct isp_ic_dev *dev)
- {
- struct isp_mi_context mi = *(&dev->mi);
- u32 bp_ctrl = 0, lval = 0;
- struct isp_mi_data_path_context *path = &mi.path[2];
- u32 mi_imsc = isp_read_reg(dev, REG_ADDR(mi_imsc));
- int i;
- isp_info("enter %s\n", __func__);
- bp_ctrl = 0;
- lval = path->out_width;
- if (mi.path[2].enable) {
- bp_ctrl &= ~MRV_MI_BP_WRITE_RAWBIT_MASK;
- if (path->data_alignMode == ISP_MI_DATA_ALIGN_16BIT_MODE) {
- if ((path->out_mode == IC_MI_DATAMODE_RAW10) ||
- (path->out_mode == IC_MI_DATAMODE_RAW12) ||
- (path->out_mode == IC_MI_DATAMODE_RAW14)) {
- lval = (path->out_width + 3) / 4;
- }
- } else if (path->data_alignMode ==
- ISP_MI_DATA_ALIGN_128BIT_MODE) {
- if ((path->out_mode == IC_MI_DATAMODE_RAW10)
- || (path->out_mode == IC_MI_DATAMODE_RAW12)
- || (path->out_mode == IC_MI_DATAMODE_RAW14)) {
- lval = (path->out_width * 2 + 126) / 128;
- }
- } else {
- if (path->out_mode == IC_MI_DATAMODE_RAW10) {
- lval = (path->out_width * 10 + 63) / 64;
- } else if (path->out_mode == IC_MI_DATAMODE_RAW12) {
- lval = (path->out_width * 12 + 63) / 64;
- } else if (path->out_mode == IC_MI_DATAMODE_RAW14) {
- lval = (path->out_width * 14 + 63) / 64;
- } else if (path->out_mode == IC_MI_DATAMODE_RAW16) {
- lval = (path->out_width * 16 + 63) / 64;
- } else {
- lval = (path->out_width * 8 + 63) / 64;
- }
- }
- lval <<= 3;
- REG_SET_SLICE(bp_ctrl, BP_WR_RAW_ALIGNED, path->data_alignMode);
- switch (mi.path[2].out_mode) {
- case (IC_MI_DATAMODE_RAW8):
- REG_SET_SLICE(bp_ctrl, MRV_MI_BP_WRITE_RAWBIT,
- MRV_MI_BP_WRITE_RAWBIT_RAW_8);
- REG_SET_SLICE(bp_ctrl, MRV_MI_BP_WRITE_FORMAT,
- MRV_MI_BP_WRITE_INTERLEAVE_FORMAT);
- break;
- case (IC_MI_DATAMODE_RAW12):
- REG_SET_SLICE(bp_ctrl, BP_WR_BYTE_SWAP, 1);
- REG_SET_SLICE(bp_ctrl, MRV_MI_BP_WRITE_RAWBIT,
- MRV_MI_BP_WRITE_RAWBIT_RAW_12);
- REG_SET_SLICE(bp_ctrl, MRV_MI_BP_WRITE_FORMAT,
- MRV_MI_BP_WRITE_INTERLEAVE_FORMAT);
- break;
- case (IC_MI_DATAMODE_RAW10):
- REG_SET_SLICE(bp_ctrl, BP_WR_BYTE_SWAP, 1);
- REG_SET_SLICE(bp_ctrl, MRV_MI_BP_WRITE_RAWBIT,
- MRV_MI_BP_WRITE_RAWBIT_RAW_10);
- REG_SET_SLICE(bp_ctrl, MRV_MI_BP_WRITE_FORMAT,
- MRV_MI_BP_WRITE_INTERLEAVE_FORMAT);
- break;
- default:
- break;
- }
- isp_write_reg(dev, REG_ADDR(mi_bp_wr_size_init),
- lval * mi.path[2].out_height);
- isp_write_reg(dev, REG_ADDR(mi_bp_pic_width),
- mi.path[2].out_width);
- isp_write_reg(dev, REG_ADDR(mi_bp_wr_llength), lval);
- isp_write_reg(dev, REG_ADDR(mi_bp_pic_height),
- mi.path[2].out_height);
- isp_write_reg(dev, REG_ADDR(mi_bp_pic_size),
- lval * mi.path[2].out_height);
- /* enable frame end irq for bp path */
- mi_imsc |=
- MRV_MI_BP_FRAME_END_MASK | MRV_MI_BP_WRAP_R_MASK |
- MRV_MI_BP_WRAP_GR_MASK | MRV_MI_BP_WRAP_GB_MASK |
- MRV_MI_BP_WRAP_B_MASK;
- }
- if (!dev->rawis.enable) {
- isp_write_reg(dev, REG_ADDR(isp_raw_is_h_size),
- mi.path[2].out_width);
- isp_write_reg(dev, REG_ADDR(isp_raw_is_v_size),
- mi.path[2].out_height);
- isp_write_reg(dev, REG_ADDR(isp_raw_is_ctrl), 0);
- }
- bp_ctrl |= MRV_MI_BP_PATH_ENABLE_MASK;
- isp_write_reg(dev, REG_ADDR(mi_bp_ctrl), bp_ctrl);
- isp_write_reg(dev, REG_ADDR(mi_imsc), mi_imsc);
- return 0;
- }
- #endif
- int isp_mi_start(struct isp_ic_dev *dev)
- {
- struct isp_mi_context mi = *(&dev->mi);
- u32 mi_init, mi_ctrl, mi_imsc;
- u32 out_stride;
- int i;
- u8 retry = 3;
- isp_info("enter %s\n", __func__);
- isp_write_reg(dev, REG_ADDR(mrsz_ctrl), 0);
- isp_write_reg(dev, REG_ADDR(mrsz_ctrl_shd), 0);
- for (i = 0; i < 2; i++) {
- if (mi.path[i].hscale || mi.path[i].vscale) {
- set_scaling(i, dev, dev->is.enable);
- }
- }
- mi_init = 0;
- mi_ctrl = 0;
- mi_imsc = 0;
- if (mi.path[0].enable) {
- /* remove update enable bits for offset and base registers */
- mi_init &= ~MRV_MI_MP_OUTPUT_FORMAT_MASK;
- mi_ctrl &= ~MRV_MI_MP_WRITE_FORMAT_MASK;
- /* config mi_init output format for yuv format */
- if (mi.path[0].out_mode <= IC_MI_DATAMODE_YUV400)
- REG_SET_SLICE(mi_init, MRV_MI_MP_OUTPUT_FORMAT,
- IC_MI_DATAMODE_YUV400 -
- mi.path[0].out_mode);
- switch (mi.path[0].out_mode) {
- case (IC_MI_DATAMODE_RAW8):
- REG_SET_SLICE(mi_ctrl, MRV_MI_MP_WRITE_FORMAT,
- MRV_MI_MP_WRITE_FORMAT_RAW_8);
- REG_SET_SLICE(mi_ctrl, MRV_MI_RAW_ENABLE, 1);
- REG_SET_SLICE(mi_init, MRV_MI_MP_OUTPUT_FORMAT,
- MRV_MI_MP_OUTPUT_FORMAT_RAW8);
- break;
- case (IC_MI_DATAMODE_RAW12):
- REG_SET_SLICE(mi_ctrl, MRV_MI_MP_WRITE_FORMAT,
- MRV_MI_MP_WRITE_FORMAT_RAW_12);
- REG_SET_SLICE(mi_ctrl, MRV_MI_RAW_ENABLE, 1);
- REG_SET_SLICE(mi_init, MRV_MI_MP_OUTPUT_FORMAT,
- MRV_MI_MP_OUTPUT_FORMAT_RAW12);
- isp_write_reg(dev, REG_ADDR(mi_output_align_format), 1);
- break;
- case (IC_MI_DATAMODE_RAW10):
- REG_SET_SLICE(mi_ctrl, MRV_MI_MP_WRITE_FORMAT,
- MRV_MI_MP_WRITE_FORMAT_RAW_12);
- REG_SET_SLICE(mi_ctrl, MRV_MI_RAW_ENABLE, 1);
- REG_SET_SLICE(mi_init, MRV_MI_MP_OUTPUT_FORMAT,
- MRV_MI_MP_OUTPUT_FORMAT_RAW10);
- isp_write_reg(dev, REG_ADDR(mi_output_align_format), 1);
- break;
- case (IC_MI_DATAMODE_JPEG):
- REG_SET_SLICE(mi_ctrl, MRV_MI_MP_WRITE_FORMAT,
- MRV_MI_MP_WRITE_FORMAT_PLANAR);
- REG_SET_SLICE(mi_ctrl, MRV_MI_JPEG_ENABLE, 1);
- break;
- case (IC_MI_DATAMODE_YUV444):
- case (IC_MI_DATAMODE_YUV422):
- case (IC_MI_DATAMODE_YUV420):
- case (IC_MI_DATAMODE_YUV400):
- if (mi.path[0].data_layout == IC_MI_DATASTORAGE_PLANAR) {
- REG_SET_SLICE(mi_ctrl, MRV_MI_MP_WRITE_FORMAT,
- MRV_MI_MP_WRITE_FORMAT_PLANAR);
- } else if (mi.path[0].data_layout ==
- IC_MI_DATASTORAGE_SEMIPLANAR) {
- REG_SET_SLICE(mi_ctrl, MRV_MI_MP_WRITE_FORMAT,
- MRV_MI_MP_WRITE_FORMAT_SEMIPLANAR);
- } else if (mi.path[0].data_layout ==
- IC_MI_DATASTORAGE_INTERLEAVED) {
- REG_SET_SLICE(mi_ctrl, MRV_MI_MP_WRITE_FORMAT,
- MRV_MI_MP_WRITE_FORMAT_INTERLEAVED);
- } else {
- break;
- }
- REG_SET_SLICE(mi_ctrl, MRV_MI_MP_ENABLE, 1);
- break;
- default:
- break;
- }
- out_stride = mi.path[0].data_layout ==
- IC_MI_DATASTORAGE_INTERLEAVED ?
- (mi.path[0].out_width * 2) : (mi.path[0].out_width);
- isp_write_reg(dev, REG_ADDR(mi_mp_y_pic_width), out_stride);
- isp_write_reg(dev, REG_ADDR(mi_mp_y_llength), out_stride);
- isp_write_reg(dev, REG_ADDR(mi_mp_y_pic_height),
- mi.path[0].out_height);
- isp_write_reg(dev, REG_ADDR(mi_mp_y_pic_size),
- out_stride * mi.path[0].out_height);
- /* workaround to resolve the problem that the mi_mp_y_pic_width can't be written */
- for(i = 0; i < retry; i++) {
- if(isp_read_reg(dev, REG_ADDR(mi_mp_y_pic_width)) != out_stride) {
- isp_write_reg(dev, REG_ADDR(mi_mp_y_pic_width), out_stride);
- } else {
- break;
- }
- }
- if(retry == i) {
- isp_info("%s: update mi_mp_y_pic_width error!\n", __func__);
- }
- /* enable frame end irq for main path */
- mi_imsc |=
- (MRV_MI_MP_FRAME_END_MASK | MRV_MI_WRAP_MP_Y_MASK |
- MRV_MI_WRAP_MP_CB_MASK | MRV_MI_WRAP_MP_CR_MASK);
- }
- if (mi.path[1].enable) {
- /* setup mi for self-path */
- mi_ctrl &= ~(MRV_MI_SP_WRITE_FORMAT_MASK);
- REG_SET_SLICE(mi_ctrl, MRV_MI_SP_INPUT_FORMAT,
- mi.path[1].in_mode - 1);
- REG_SET_SLICE(mi_ctrl, MRV_MI_SP_OUTPUT_FORMAT,
- mi.path[1].out_mode - 1);
- switch (mi.path[1].out_mode) {
- case (IC_MI_DATAMODE_RGB888):
- case (IC_MI_DATAMODE_RGB666):
- case (IC_MI_DATAMODE_RGB565):
- REG_SET_SLICE(mi_ctrl, MRV_MI_SP_WRITE_FORMAT,
- MRV_MI_SP_WRITE_FORMAT_RGB_INTERLEAVED);
- break;
- case (IC_MI_DATAMODE_YUV444):
- case (IC_MI_DATAMODE_YUV400):
- if (mi.path[1].data_layout == IC_MI_DATASTORAGE_PLANAR) {
- REG_SET_SLICE(mi_ctrl, MRV_MI_SP_WRITE_FORMAT,
- MRV_MI_SP_WRITE_FORMAT_PLANAR);
- }
- break;
- case (IC_MI_DATAMODE_YUV422):
- switch (mi.path[1].data_layout) {
- case (IC_MI_DATASTORAGE_PLANAR):
- REG_SET_SLICE(mi_ctrl, MRV_MI_SP_WRITE_FORMAT,
- MRV_MI_SP_WRITE_FORMAT_PLANAR);
- break;
- case (IC_MI_DATASTORAGE_SEMIPLANAR):
- REG_SET_SLICE(mi_ctrl, MRV_MI_SP_WRITE_FORMAT,
- MRV_MI_SP_WRITE_FORMAT_SEMIPLANAR);
- break;
- case (IC_MI_DATASTORAGE_INTERLEAVED):
- REG_SET_SLICE(mi_ctrl, MRV_MI_SP_WRITE_FORMAT,
- MRV_MI_SP_WRITE_FORMAT_INTERLEAVED);
- break;
- default:
- break;
- }
- break;
- case (IC_MI_DATAMODE_YUV420):
- switch (mi.path[1].data_layout) {
- case (IC_MI_DATASTORAGE_PLANAR):
- REG_SET_SLICE(mi_ctrl, MRV_MI_SP_WRITE_FORMAT,
- MRV_MI_SP_WRITE_FORMAT_PLANAR);
- break;
- case (IC_MI_DATASTORAGE_SEMIPLANAR):
- REG_SET_SLICE(mi_ctrl, MRV_MI_SP_WRITE_FORMAT,
- MRV_MI_SP_WRITE_FORMAT_SEMIPLANAR);
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- out_stride = mi.path[1].data_layout ==
- IC_MI_DATASTORAGE_INTERLEAVED ?
- mi.path[1].out_width * 2 : mi.path[1].out_width;
- REG_SET_SLICE(mi_ctrl, MRV_MI_SP_ENABLE, 1);
- isp_write_reg(dev, REG_ADDR(mi_sp_y_pic_width), out_stride);
- isp_write_reg(dev, REG_ADDR(mi_sp_y_llength), out_stride);
- isp_write_reg(dev, REG_ADDR(mi_sp_y_pic_height),
- mi.path[1].out_height);
- isp_write_reg(dev, REG_ADDR(mi_sp_y_pic_size),
- out_stride * mi.path[1].out_height);
- /* enable frame end interrupt on self path */
- mi_imsc |=
- (MRV_MI_SP_FRAME_END_MASK | MRV_MI_WRAP_SP_Y_MASK |
- MRV_MI_WRAP_SP_CB_MASK | MRV_MI_WRAP_SP_CR_MASK);
- }
- #if defined(__KERNEL__) && defined(ENABLE_IRQ)
- for (i = 0; i < MI_PATH_NUM; ++i) {
- dev->mi_buf[i] = NULL;
- dev->mi_buf_shd[i] = NULL;
- }
- if (dev->state)
- *dev->state |= STATE_DRIVER_STARTED;
- #endif
- mi_ctrl |= (MRV_MI_INIT_BASE_EN_MASK | MRV_MI_INIT_OFFSET_EN_MASK);
- REG_SET_SLICE(mi_ctrl, MRV_MI_BURST_LEN_CHROM, mi.burst_len);
- REG_SET_SLICE(mi_ctrl, MRV_MI_BURST_LEN_LUM, mi.burst_len);
- isp_write_reg(dev, REG_ADDR(mi_ctrl), mi_ctrl | 0x2000);
- REG_SET_SLICE(mi_init, MRV_MI_MI_CFG_UPD, 1);
- isp_write_reg(dev, REG_ADDR(mi_imsc), mi_imsc);
- #ifdef ISP_MI_BP
- isp_bppath_start(dev);
- #endif
- isp_write_reg(dev, REG_ADDR(mi_init), mi_init);
- return 0;
- }
- int isp_mi_stop(struct isp_ic_dev *dev)
- {
- u32 mi_ctrl = 0, mi_init = 0;
- isp_info("enter %s\n", __func__);
- isp_write_reg(dev, REG_ADDR(mi_imsc), 0);
- /* disable mi path */
- mi_ctrl = isp_read_reg(dev, REG_ADDR(mi_ctrl));
- REG_SET_SLICE(mi_ctrl, MRV_MI_MP_ENABLE, 0);
- REG_SET_SLICE(mi_ctrl, MRV_MI_SP_ENABLE, 0);
- REG_SET_SLICE(mi_ctrl, MRV_MI_JPEG_ENABLE, 0);
- REG_SET_SLICE(mi_ctrl, MRV_MI_RAW_ENABLE, 0);
- isp_write_reg(dev, REG_ADDR(mi_ctrl), mi_ctrl);
- mi_init = isp_read_reg(dev, REG_ADDR(mi_init));
- REG_SET_SLICE(mi_init, MRV_MI_MI_CFG_UPD, 1);
- isp_write_reg(dev, REG_ADDR(mi_init), mi_init);
- #if defined(__KERNEL__) && defined(ENABLE_IRQ)
- if (dev->state)
- *dev->state &= ~STATE_DRIVER_STARTED;
- clean_dma_buffer(dev);
- #endif
- return 0;
- }
- int isp_set_buffer(struct isp_ic_dev *dev, struct isp_buffer_context *buf)
- {
- u32 addr;
- if (!dev || !buf) {
- isp_err("NULL pointer %s\n", __func__);
- return -EINVAL;
- }
- addr = buf->path == 0 ?
- REG_ADDR(mi_mp_y_base_ad_init) : REG_ADDR(mi_sp_y_base_ad_init);
- isp_write_reg(dev, addr, (buf->addr_y & MRV_MI_MP_Y_BASE_AD_INIT_MASK));
- isp_write_reg(dev, addr + 1 * 4,
- (buf->size_y & MRV_MI_MP_Y_SIZE_INIT_MASK));
- isp_write_reg(dev, addr + 2 * 4, 0);
- isp_write_reg(dev, addr + 5 * 4,
- (buf->addr_cb & MRV_MI_MP_CB_BASE_AD_INIT_MASK));
- isp_write_reg(dev, addr + 6 * 4,
- (buf->size_cb & MRV_MI_MP_CB_SIZE_INIT_MASK));
- isp_write_reg(dev, addr + 7 * 4, 0);
- isp_write_reg(dev, addr + 9 * 4,
- (buf->addr_cr & MRV_MI_MP_CR_BASE_AD_INIT_MASK));
- isp_write_reg(dev, addr + 10 * 4,
- (buf->size_cr & MRV_MI_MP_CR_SIZE_INIT_MASK));
- isp_write_reg(dev, addr + 11 * 4, 0);
- return 0;
- }
- int isp_set_bp_buffer(struct isp_ic_dev *dev, struct isp_bp_buffer_context *buf)
- {
- #ifndef ISP_MI_BP
- isp_err("unsupported function: %s", __func__);
- return -EINVAL;
- #else
- isp_write_reg(dev, REG_ADDR(mi_bp_r_base_ad_init),
- (buf->addr_r & BP_R_BASE_AD_INIT_MASK));
- isp_write_reg(dev, REG_ADDR(mi_bp_gr_base_ad_init),
- (buf->addr_gr & BP_GR_BASE_AD_INIT_MASK));
- isp_write_reg(dev, REG_ADDR(mi_bp_gb_base_ad_init),
- (buf->addr_gb & BP_GB_BASE_AD_INIT_MASK));
- isp_write_reg(dev, REG_ADDR(mi_bp_b_base_ad_init),
- (buf->addr_b & BP_B_BASE_AD_INIT_MASK));
- return 0;
- #endif
- }
- u32 isp_read_mi_irq(struct isp_ic_dev * dev)
- {
- return isp_read_reg(dev, REG_ADDR(mi_mis));
- }
- void isp_reset_mi_irq(struct isp_ic_dev *dev, u32 icr)
- {
- isp_write_reg(dev, REG_ADDR(mi_icr), icr);
- }
- #endif
|