mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
media: rockchip: isp: dual isp unite process image
Change-Id: Ia85adab95cce029ea0967c00bd7d0d51863d7d76 Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
@@ -890,8 +890,8 @@ static void restrict_rsz_resolution(struct rkisp_device *dev,
|
||||
struct v4l2_rect *input_win;
|
||||
|
||||
input_win = rkisp_get_isp_sd_win(&dev->isp_sdev);
|
||||
max_rsz->width = min_t(int, input_win->width, config->max_rsz_width);
|
||||
max_rsz->height = min_t(int, input_win->height, config->max_rsz_height);
|
||||
max_rsz->width = max_t(int, input_win->width, config->max_rsz_width);
|
||||
max_rsz->height = max_t(int, input_win->height, config->max_rsz_height);
|
||||
}
|
||||
|
||||
static int rkisp_set_fmt(struct rkisp_stream *stream,
|
||||
|
||||
@@ -200,7 +200,7 @@ struct streams_ops {
|
||||
void (*stop_mi)(struct rkisp_stream *stream);
|
||||
void (*enable_mi)(struct rkisp_stream *stream);
|
||||
void (*disable_mi)(struct rkisp_stream *stream);
|
||||
void (*set_data_path)(void __iomem *base);
|
||||
void (*set_data_path)(struct rkisp_stream *stream);
|
||||
bool (*is_stream_stopped)(void __iomem *base);
|
||||
void (*update_mi)(struct rkisp_stream *stream);
|
||||
int (*frame_end)(struct rkisp_stream *stream);
|
||||
|
||||
@@ -380,7 +380,7 @@ static struct streams_ops rkisp_mp_streams_ops = {
|
||||
.enable_mi = mp_enable_mi,
|
||||
.disable_mi = mp_disable_mi,
|
||||
.stop_mi = mp_stop_mi,
|
||||
.set_data_path = mp_set_data_path,
|
||||
.set_data_path = stream_data_path,
|
||||
.is_stream_stopped = mp_is_stream_stopped,
|
||||
.update_mi = update_mi,
|
||||
.frame_end = mi_frame_end,
|
||||
@@ -391,7 +391,7 @@ static struct streams_ops rkisp_sp_streams_ops = {
|
||||
.enable_mi = sp_enable_mi,
|
||||
.disable_mi = sp_disable_mi,
|
||||
.stop_mi = sp_stop_mi,
|
||||
.set_data_path = sp_set_data_path,
|
||||
.set_data_path = stream_data_path,
|
||||
.is_stream_stopped = sp_is_stream_stopped,
|
||||
.update_mi = update_mi,
|
||||
.frame_end = mi_frame_end,
|
||||
@@ -517,11 +517,10 @@ static void rkisp_stream_stop(struct rkisp_stream *stream)
|
||||
*/
|
||||
static int rkisp_start(struct rkisp_stream *stream)
|
||||
{
|
||||
void __iomem *base = stream->ispdev->base_addr;
|
||||
int ret;
|
||||
|
||||
if (stream->ops->set_data_path)
|
||||
stream->ops->set_data_path(base);
|
||||
stream->ops->set_data_path(stream);
|
||||
ret = stream->ops->config_mi(stream);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -836,7 +836,7 @@ static struct streams_ops rkisp_mp_streams_ops = {
|
||||
.enable_mi = mp_enable_mi,
|
||||
.disable_mi = mp_disable_mi,
|
||||
.stop_mi = mp_stop_mi,
|
||||
.set_data_path = mp_set_data_path,
|
||||
.set_data_path = stream_data_path,
|
||||
.is_stream_stopped = mp_is_stream_stopped,
|
||||
.update_mi = update_mi,
|
||||
.frame_end = mi_frame_end,
|
||||
@@ -847,7 +847,7 @@ static struct streams_ops rkisp_sp_streams_ops = {
|
||||
.enable_mi = sp_enable_mi,
|
||||
.disable_mi = sp_disable_mi,
|
||||
.stop_mi = sp_stop_mi,
|
||||
.set_data_path = sp_set_data_path,
|
||||
.set_data_path = stream_data_path,
|
||||
.is_stream_stopped = sp_is_stream_stopped,
|
||||
.update_mi = update_mi,
|
||||
.frame_end = mi_frame_end,
|
||||
@@ -1215,7 +1215,6 @@ static void rkisp_stream_stop(struct rkisp_stream *stream)
|
||||
*/
|
||||
static int rkisp_start(struct rkisp_stream *stream)
|
||||
{
|
||||
void __iomem *base = stream->ispdev->base_addr;
|
||||
struct rkisp_device *dev = stream->ispdev;
|
||||
int ret;
|
||||
|
||||
@@ -1226,7 +1225,7 @@ static int rkisp_start(struct rkisp_stream *stream)
|
||||
hdr_config_dmatx(dev);
|
||||
|
||||
if (stream->ops->set_data_path)
|
||||
stream->ops->set_data_path(base);
|
||||
stream->ops->set_data_path(stream);
|
||||
ret = stream->ops->config_mi(stream);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -733,7 +733,7 @@ static struct streams_ops rkisp_mp_streams_ops = {
|
||||
.enable_mi = mp_enable_mi,
|
||||
.disable_mi = mp_disable_mi,
|
||||
.stop_mi = mp_stop_mi,
|
||||
.set_data_path = mp_set_data_path,
|
||||
.set_data_path = stream_data_path,
|
||||
.is_stream_stopped = mp_is_stream_stopped,
|
||||
.update_mi = update_mi,
|
||||
.frame_end = mi_frame_end,
|
||||
@@ -744,7 +744,7 @@ static struct streams_ops rkisp_sp_streams_ops = {
|
||||
.enable_mi = sp_enable_mi,
|
||||
.disable_mi = sp_disable_mi,
|
||||
.stop_mi = sp_stop_mi,
|
||||
.set_data_path = sp_set_data_path,
|
||||
.set_data_path = stream_data_path,
|
||||
.is_stream_stopped = sp_is_stream_stopped,
|
||||
.update_mi = update_mi,
|
||||
.frame_end = mi_frame_end,
|
||||
@@ -1038,7 +1038,6 @@ static void rkisp_stream_stop(struct rkisp_stream *stream)
|
||||
*/
|
||||
static int rkisp_start(struct rkisp_stream *stream)
|
||||
{
|
||||
void __iomem *base = stream->ispdev->base_addr;
|
||||
struct rkisp_device *dev = stream->ispdev;
|
||||
bool is_update = false;
|
||||
int ret;
|
||||
@@ -1050,7 +1049,7 @@ static int rkisp_start(struct rkisp_stream *stream)
|
||||
}
|
||||
|
||||
if (stream->ops->set_data_path)
|
||||
stream->ops->set_data_path(base);
|
||||
stream->ops->set_data_path(stream);
|
||||
ret = stream->ops->config_mi(stream);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -134,7 +134,8 @@ static int rkisp_stream_config_dcrop(struct rkisp_stream *stream, bool async)
|
||||
|
||||
if (dcrop->width == input_win->width &&
|
||||
dcrop->height == input_win->height &&
|
||||
dcrop->left == 0 && dcrop->top == 0) {
|
||||
dcrop->left == 0 && dcrop->top == 0 &&
|
||||
!dev->hw_dev->is_unite) {
|
||||
rkisp_disable_dcrop(stream, async);
|
||||
v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev,
|
||||
"stream %d crop disabled\n", stream->id);
|
||||
@@ -274,6 +275,7 @@ static int mp_config_mi(struct rkisp_stream *stream)
|
||||
{
|
||||
struct rkisp_device *dev = stream->ispdev;
|
||||
struct v4l2_pix_format_mplane *out_fmt = &stream->out_fmt;
|
||||
bool is_unite = dev->hw_dev->is_unite;
|
||||
u32 val, mask;
|
||||
|
||||
/*
|
||||
@@ -281,26 +283,26 @@ static int mp_config_mi(struct rkisp_stream *stream)
|
||||
* memory plane formats, so calculate the size explicitly.
|
||||
*/
|
||||
val = out_fmt->plane_fmt[0].bytesperline * out_fmt->height;
|
||||
rkisp_write(dev, stream->config->mi.y_size_init, val, false);
|
||||
rkisp_unite_write(dev, stream->config->mi.y_size_init, val, false, is_unite);
|
||||
|
||||
val = out_fmt->plane_fmt[1].sizeimage;
|
||||
rkisp_write(dev, stream->config->mi.cb_size_init, val, false);
|
||||
rkisp_unite_write(dev, stream->config->mi.cb_size_init, val, false, is_unite);
|
||||
|
||||
val = out_fmt->plane_fmt[2].sizeimage;
|
||||
rkisp_write(dev, stream->config->mi.cr_size_init, val, false);
|
||||
rkisp_unite_write(dev, stream->config->mi.cr_size_init, val, false, is_unite);
|
||||
|
||||
val = out_fmt->width;
|
||||
rkisp_write(dev, ISP3X_MI_MP_WR_Y_PIC_WIDTH, val, false);
|
||||
val = is_unite ? out_fmt->width / 2 : out_fmt->width;
|
||||
rkisp_unite_write(dev, ISP3X_MI_MP_WR_Y_PIC_WIDTH, val, false, is_unite);
|
||||
|
||||
val = out_fmt->height;
|
||||
rkisp_write(dev, ISP3X_MI_MP_WR_Y_PIC_HEIGHT, val, false);
|
||||
rkisp_unite_write(dev, ISP3X_MI_MP_WR_Y_PIC_HEIGHT, val, false, is_unite);
|
||||
|
||||
val = ALIGN(out_fmt->plane_fmt[0].bytesperline, 16);
|
||||
rkisp_write(dev, ISP3X_MI_MP_WR_Y_LLENGTH, val, false);
|
||||
rkisp_unite_write(dev, ISP3X_MI_MP_WR_Y_LLENGTH, val, false, is_unite);
|
||||
|
||||
val = stream->out_isp_fmt.uv_swap ? ISP3X_MI_XTD_FORMAT_MP_UV_SWAP : 0;
|
||||
mask = ISP3X_MI_XTD_FORMAT_MP_UV_SWAP;
|
||||
rkisp_set_bits(dev, ISP3X_MI_WR_XTD_FORMAT_CTRL, mask, val, false);
|
||||
rkisp_unite_set_bits(dev, ISP3X_MI_WR_XTD_FORMAT_CTRL, mask, val, false, is_unite);
|
||||
|
||||
if (stream->out_fmt.pixelformat == V4L2_PIX_FMT_NV21 ||
|
||||
stream->out_fmt.pixelformat == V4L2_PIX_FMT_NV12 ||
|
||||
@@ -311,13 +313,13 @@ static int mp_config_mi(struct rkisp_stream *stream)
|
||||
else
|
||||
val = ISP3X_SEPERATE_YUV_CFG | ISP3X_MP_YUV_MODE;
|
||||
mask = ISP3X_MPFBC_FORCE_UPD | ISP3X_MP_YUV_MODE;
|
||||
rkisp_set_bits(dev, ISP3X_MPFBC_CTRL, mask, val, false);
|
||||
rkisp_unite_set_bits(dev, ISP3X_MPFBC_CTRL, mask, val, false, is_unite);
|
||||
|
||||
val = calc_burst_len(stream) | CIF_MI_CTRL_INIT_BASE_EN |
|
||||
CIF_MI_CTRL_INIT_OFFSET_EN | CIF_MI_MP_AUTOUPDATE_ENABLE |
|
||||
stream->out_isp_fmt.write_format;
|
||||
mask = GENMASK(19, 16) | MI_CTRL_MP_FMT_MASK;
|
||||
rkisp_set_bits(dev, ISP3X_MI_WR_CTRL, mask, val, false);
|
||||
rkisp_unite_set_bits(dev, ISP3X_MI_WR_CTRL, mask, val, false, is_unite);
|
||||
|
||||
mi_frame_end_int_enable(stream);
|
||||
/* set up first buffer */
|
||||
@@ -358,6 +360,7 @@ static int sp_config_mi(struct rkisp_stream *stream)
|
||||
struct v4l2_pix_format_mplane *out_fmt = &stream->out_fmt;
|
||||
struct ispsd_out_fmt *input_isp_fmt =
|
||||
rkisp_get_ispsd_out_fmt(&dev->isp_sdev);
|
||||
bool is_unite = dev->hw_dev->is_unite;
|
||||
u32 sp_in_fmt, val, mask;
|
||||
|
||||
if (mbus_code_sp_in_fmt(input_isp_fmt->mbus_code,
|
||||
@@ -371,26 +374,26 @@ static int sp_config_mi(struct rkisp_stream *stream)
|
||||
* memory plane formats, so calculate the size explicitly.
|
||||
*/
|
||||
val = out_fmt->plane_fmt[0].bytesperline * out_fmt->height;
|
||||
rkisp_write(dev, stream->config->mi.y_size_init, val, false);
|
||||
rkisp_unite_write(dev, stream->config->mi.y_size_init, val, false, is_unite);
|
||||
|
||||
val = out_fmt->plane_fmt[1].sizeimage;
|
||||
rkisp_write(dev, stream->config->mi.cb_size_init, val, false);
|
||||
rkisp_unite_write(dev, stream->config->mi.cb_size_init, val, false, is_unite);
|
||||
|
||||
val = out_fmt->plane_fmt[2].sizeimage;
|
||||
rkisp_write(dev, stream->config->mi.cr_size_init, val, false);
|
||||
rkisp_unite_write(dev, stream->config->mi.cr_size_init, val, false, is_unite);
|
||||
|
||||
val = out_fmt->width;
|
||||
rkisp_write(dev, ISP3X_MI_SP_WR_Y_PIC_WIDTH, val, false);
|
||||
val = is_unite ? out_fmt->width / 2 : out_fmt->width;
|
||||
rkisp_unite_write(dev, ISP3X_MI_SP_WR_Y_PIC_WIDTH, val, false, is_unite);
|
||||
|
||||
val = out_fmt->height;
|
||||
rkisp_write(dev, ISP3X_MI_SP_WR_Y_PIC_HEIGHT, val, false);
|
||||
rkisp_unite_write(dev, ISP3X_MI_SP_WR_Y_PIC_HEIGHT, val, false, is_unite);
|
||||
|
||||
val = ALIGN(out_fmt->plane_fmt[0].bytesperline, 16);
|
||||
rkisp_write(dev, ISP3X_MI_SP_WR_Y_LLENGTH, val, false);
|
||||
rkisp_unite_write(dev, ISP3X_MI_SP_WR_Y_LLENGTH, val, false, is_unite);
|
||||
|
||||
val = stream->out_isp_fmt.uv_swap ? ISP3X_MI_XTD_FORMAT_SP_UV_SWAP : 0;
|
||||
mask = ISP3X_MI_XTD_FORMAT_SP_UV_SWAP;
|
||||
rkisp_set_bits(dev, ISP3X_MI_WR_XTD_FORMAT_CTRL, mask, val, false);
|
||||
rkisp_unite_set_bits(dev, ISP3X_MI_WR_XTD_FORMAT_CTRL, mask, val, false, is_unite);
|
||||
|
||||
if (stream->out_fmt.pixelformat == V4L2_PIX_FMT_NV21 ||
|
||||
stream->out_fmt.pixelformat == V4L2_PIX_FMT_NV12 ||
|
||||
@@ -401,14 +404,14 @@ static int sp_config_mi(struct rkisp_stream *stream)
|
||||
else
|
||||
val = ISP3X_SEPERATE_YUV_CFG | ISP3X_SP_YUV_MODE;
|
||||
mask = ISP3X_MPFBC_FORCE_UPD | ISP3X_SP_YUV_MODE;
|
||||
rkisp_set_bits(dev, ISP3X_MPFBC_CTRL, mask, val, false);
|
||||
rkisp_unite_set_bits(dev, ISP3X_MPFBC_CTRL, mask, val, false, is_unite);
|
||||
|
||||
val = calc_burst_len(stream) | CIF_MI_CTRL_INIT_BASE_EN |
|
||||
CIF_MI_CTRL_INIT_OFFSET_EN | stream->out_isp_fmt.write_format |
|
||||
sp_in_fmt | stream->out_isp_fmt.output_format |
|
||||
CIF_MI_SP_AUTOUPDATE_ENABLE;
|
||||
mask = GENMASK(19, 16) | MI_CTRL_SP_FMT_MASK;
|
||||
rkisp_set_bits(dev, ISP3X_MI_WR_CTRL, mask, val, false);
|
||||
rkisp_unite_set_bits(dev, ISP3X_MI_WR_CTRL, mask, val, false, is_unite);
|
||||
|
||||
mi_frame_end_int_enable(stream);
|
||||
/* set up first buffer */
|
||||
@@ -418,10 +421,20 @@ static int sp_config_mi(struct rkisp_stream *stream)
|
||||
|
||||
static int fbc_config_mi(struct rkisp_stream *stream)
|
||||
{
|
||||
u32 h = stream->out_fmt.height;
|
||||
u32 h = ALIGN(stream->out_fmt.height, 16);
|
||||
u32 w = ALIGN(stream->out_fmt.width, 16);
|
||||
u32 offs = w * h / 16;
|
||||
bool is_unite = stream->ispdev->hw_dev->is_unite;
|
||||
|
||||
rkisp_write(stream->ispdev, ISP3X_MPFBC_VIR_WIDTH, 0, false);
|
||||
rkisp_write(stream->ispdev, ISP3X_MPFBC_VIR_HEIGHT, ALIGN(h, 16), false);
|
||||
rkisp_write(stream->ispdev, ISP3X_MPFBC_HEAD_OFFSET, offs, false);
|
||||
rkisp_unite_write(stream->ispdev, ISP3X_MPFBC_VIR_WIDTH, w, false, is_unite);
|
||||
rkisp_unite_write(stream->ispdev, ISP3X_MPFBC_VIR_HEIGHT, h, false, is_unite);
|
||||
if (is_unite) {
|
||||
u32 left_w = (stream->out_fmt.width / 2) & ~0xf;
|
||||
|
||||
offs += left_w * 32;
|
||||
rkisp_next_write(stream->ispdev, ISP3X_MPFBC_HEAD_OFFSET, offs, false);
|
||||
}
|
||||
mi_frame_end_int_enable(stream);
|
||||
/* set up first buffer */
|
||||
mi_frame_end(stream);
|
||||
@@ -432,6 +445,7 @@ static int bp_config_mi(struct rkisp_stream *stream)
|
||||
{
|
||||
struct v4l2_pix_format_mplane *out_fmt = &stream->out_fmt;
|
||||
struct rkisp_device *dev = stream->ispdev;
|
||||
bool is_unite = dev->hw_dev->is_unite;
|
||||
u32 val, mask;
|
||||
|
||||
/*
|
||||
@@ -439,19 +453,19 @@ static int bp_config_mi(struct rkisp_stream *stream)
|
||||
* memory plane formats, so calculate the size explicitly.
|
||||
*/
|
||||
val = out_fmt->plane_fmt[0].bytesperline * out_fmt->height;
|
||||
rkisp_write(dev, stream->config->mi.y_size_init, val, false);
|
||||
rkisp_unite_write(dev, stream->config->mi.y_size_init, val, false, is_unite);
|
||||
|
||||
val = out_fmt->plane_fmt[1].sizeimage;
|
||||
rkisp_write(dev, stream->config->mi.cb_size_init, val, false);
|
||||
rkisp_unite_write(dev, stream->config->mi.cb_size_init, val, false, is_unite);
|
||||
|
||||
val = out_fmt->width;
|
||||
rkisp_write(dev, ISP3X_MI_BP_WR_Y_PIC_WIDTH, val, false);
|
||||
val = is_unite ? out_fmt->width / 2 : out_fmt->width;
|
||||
rkisp_unite_write(dev, ISP3X_MI_BP_WR_Y_PIC_WIDTH, val, false, is_unite);
|
||||
|
||||
val = out_fmt->height;
|
||||
rkisp_write(dev, ISP3X_MI_BP_WR_Y_PIC_HEIGHT, val, false);
|
||||
rkisp_unite_write(dev, ISP3X_MI_BP_WR_Y_PIC_HEIGHT, val, false, is_unite);
|
||||
|
||||
val = ALIGN(out_fmt->plane_fmt[0].bytesperline, 16);
|
||||
rkisp_write(dev, ISP3X_MI_BP_WR_Y_LLENGTH, val, false);
|
||||
rkisp_unite_write(dev, ISP3X_MI_BP_WR_Y_LLENGTH, val, false, is_unite);
|
||||
|
||||
if (out_fmt->pixelformat == V4L2_PIX_FMT_NV12 ||
|
||||
out_fmt->pixelformat == V4L2_PIX_FMT_NV12M)
|
||||
@@ -459,7 +473,7 @@ static int bp_config_mi(struct rkisp_stream *stream)
|
||||
else
|
||||
val = ISP3X_SEPERATE_YUV_CFG | ISP3X_BP_YUV_MODE;
|
||||
mask = ISP3X_MPFBC_FORCE_UPD | ISP3X_BP_YUV_MODE;
|
||||
rkisp_set_bits(dev, ISP3X_MPFBC_CTRL, mask, val, false);
|
||||
rkisp_unite_set_bits(dev, ISP3X_MPFBC_CTRL, mask, val, false, is_unite);
|
||||
|
||||
mi_frame_end_int_enable(stream);
|
||||
/* set up first buffer */
|
||||
@@ -475,21 +489,25 @@ static void mp_enable_mi(struct rkisp_stream *stream)
|
||||
|
||||
if (isp_fmt->fmt_type == FMT_BAYER)
|
||||
val = CIF_MI_CTRL_RAW_ENABLE;
|
||||
rkisp_set_bits(stream->ispdev, ISP3X_MI_WR_CTRL, mask, val, false);
|
||||
rkisp_unite_set_bits(stream->ispdev, ISP3X_MI_WR_CTRL, mask, val,
|
||||
false, stream->ispdev->hw_dev->is_unite);
|
||||
}
|
||||
|
||||
static void sp_enable_mi(struct rkisp_stream *stream)
|
||||
{
|
||||
rkisp_set_bits(stream->ispdev, ISP3X_MI_WR_CTRL,
|
||||
0, CIF_MI_CTRL_SP_ENABLE, false);
|
||||
rkisp_unite_set_bits(stream->ispdev, ISP3X_MI_WR_CTRL, 0,
|
||||
CIF_MI_CTRL_SP_ENABLE, false,
|
||||
stream->ispdev->hw_dev->is_unite);
|
||||
}
|
||||
|
||||
static void fbc_enable_mi(struct rkisp_stream *stream)
|
||||
{
|
||||
u32 mask = ISP3X_MPFBC_FORCE_UPD | ISP3X_MPFBC_YUV_MASK;
|
||||
u32 val = stream->out_isp_fmt.write_format | ISP3X_MPFBC_EN;
|
||||
u32 val = stream->out_isp_fmt.write_format |
|
||||
ISP3X_HEAD_OFFSET_EN | ISP3X_MPFBC_EN;
|
||||
bool is_unite = stream->ispdev->hw_dev->is_unite;
|
||||
|
||||
rkisp_set_bits(stream->ispdev, ISP3X_MPFBC_CTRL, mask, val, false);
|
||||
rkisp_unite_set_bits(stream->ispdev, ISP3X_MPFBC_CTRL, mask, val, false, is_unite);
|
||||
}
|
||||
|
||||
static void bp_enable_mi(struct rkisp_stream *stream)
|
||||
@@ -497,48 +515,80 @@ static void bp_enable_mi(struct rkisp_stream *stream)
|
||||
u32 val = stream->out_isp_fmt.write_format |
|
||||
ISP3X_BP_ENABLE | ISP3X_BP_AUTO_UPD;
|
||||
|
||||
rkisp_write(stream->ispdev, ISP3X_MI_BP_WR_CTRL, val, false);
|
||||
rkisp_unite_write(stream->ispdev, ISP3X_MI_BP_WR_CTRL, val, false,
|
||||
stream->ispdev->hw_dev->is_unite);
|
||||
}
|
||||
|
||||
static void mp_disable_mi(struct rkisp_stream *stream)
|
||||
{
|
||||
u32 mask = CIF_MI_CTRL_MP_ENABLE | CIF_MI_CTRL_RAW_ENABLE;
|
||||
|
||||
rkisp_clear_bits(stream->ispdev, ISP3X_MI_WR_CTRL, mask, false);
|
||||
rkisp_unite_clear_bits(stream->ispdev, ISP3X_MI_WR_CTRL, mask, false,
|
||||
stream->ispdev->hw_dev->is_unite);
|
||||
}
|
||||
|
||||
static void sp_disable_mi(struct rkisp_stream *stream)
|
||||
{
|
||||
rkisp_clear_bits(stream->ispdev, ISP3X_MI_WR_CTRL, CIF_MI_CTRL_SP_ENABLE, false);
|
||||
rkisp_unite_clear_bits(stream->ispdev, ISP3X_MI_WR_CTRL, CIF_MI_CTRL_SP_ENABLE,
|
||||
false, stream->ispdev->hw_dev->is_unite);
|
||||
}
|
||||
|
||||
static void fbc_disable_mi(struct rkisp_stream *stream)
|
||||
{
|
||||
u32 mask = ISP3X_MPFBC_FORCE_UPD | ISP3X_MPFBC_EN;
|
||||
|
||||
rkisp_clear_bits(stream->ispdev, ISP3X_MPFBC_CTRL, mask, false);
|
||||
rkisp_unite_clear_bits(stream->ispdev, ISP3X_MPFBC_CTRL, mask,
|
||||
false, stream->ispdev->hw_dev->is_unite);
|
||||
}
|
||||
|
||||
static void bp_disable_mi(struct rkisp_stream *stream)
|
||||
{
|
||||
rkisp_clear_bits(stream->ispdev, ISP3X_MI_BP_WR_CTRL, ISP3X_BP_ENABLE, false);
|
||||
rkisp_unite_clear_bits(stream->ispdev, ISP3X_MI_BP_WR_CTRL, ISP3X_BP_ENABLE,
|
||||
false, stream->ispdev->hw_dev->is_unite);
|
||||
}
|
||||
|
||||
static void update_mi(struct rkisp_stream *stream)
|
||||
{
|
||||
struct rkisp_dummy_buffer *dummy_buf = &stream->ispdev->hw_dev->dummy_buf;
|
||||
struct rkisp_device *dev = stream->ispdev;
|
||||
u32 val;
|
||||
struct rkisp_dummy_buffer *dummy_buf = &dev->hw_dev->dummy_buf;
|
||||
u32 val, reg;
|
||||
|
||||
if (stream->next_buf) {
|
||||
reg = stream->config->mi.y_base_ad_init;
|
||||
val = stream->next_buf->buff_addr[RKISP_PLANE_Y];
|
||||
rkisp_write(dev, stream->config->mi.y_base_ad_init, val, false);
|
||||
rkisp_write(dev, reg, val, false);
|
||||
|
||||
reg = stream->config->mi.cb_base_ad_init;
|
||||
val = stream->next_buf->buff_addr[RKISP_PLANE_CB];
|
||||
rkisp_write(dev, stream->config->mi.cb_base_ad_init, val, false);
|
||||
rkisp_write(dev, reg, val, false);
|
||||
|
||||
if (stream->id != RKISP_STREAM_FBC && stream->id != RKISP_STREAM_BP) {
|
||||
reg = stream->config->mi.cr_base_ad_init;
|
||||
val = stream->next_buf->buff_addr[RKISP_PLANE_CR];
|
||||
rkisp_write(dev, stream->config->mi.cr_base_ad_init, val, false);
|
||||
rkisp_write(dev, reg, val, false);
|
||||
}
|
||||
|
||||
if (dev->hw_dev->is_unite) {
|
||||
u32 mult = stream->id != RKISP_STREAM_FBC ? 1 : 32;
|
||||
|
||||
reg = stream->config->mi.y_base_ad_init;
|
||||
val = stream->next_buf->buff_addr[RKISP_PLANE_Y];
|
||||
val += ((stream->out_fmt.width / 2) & ~0xf);
|
||||
rkisp_next_write(dev, reg, val, false);
|
||||
|
||||
reg = stream->config->mi.cb_base_ad_init;
|
||||
val = stream->next_buf->buff_addr[RKISP_PLANE_CB];
|
||||
val += ((stream->out_fmt.width / 2) & ~0xf) * mult;
|
||||
rkisp_next_write(dev, reg, val, false);
|
||||
|
||||
if (stream->id != RKISP_STREAM_FBC && stream->id != RKISP_STREAM_BP) {
|
||||
reg = stream->config->mi.cr_base_ad_init;
|
||||
val = stream->next_buf->buff_addr[RKISP_PLANE_CR];
|
||||
val += ((stream->out_fmt.width / 2) & ~0xf);
|
||||
rkisp_next_write(dev, reg, val, false);
|
||||
}
|
||||
}
|
||||
|
||||
/* single buf updated at readback for multidevice */
|
||||
if (!dev->hw_dev->is_single) {
|
||||
stream->curr_buf = stream->next_buf;
|
||||
@@ -547,31 +597,45 @@ static void update_mi(struct rkisp_stream *stream)
|
||||
} else if (dummy_buf->mem_priv) {
|
||||
stream->dbg.frameloss++;
|
||||
val = dummy_buf->dma_addr;
|
||||
rkisp_write(dev, stream->config->mi.y_base_ad_init, val, false);
|
||||
rkisp_write(dev, stream->config->mi.cb_base_ad_init, val, false);
|
||||
reg = stream->config->mi.y_base_ad_init;
|
||||
rkisp_unite_write(dev, reg, val, false, dev->hw_dev->is_unite);
|
||||
reg = stream->config->mi.cb_base_ad_init;
|
||||
rkisp_unite_write(dev, reg, val, false, dev->hw_dev->is_unite);
|
||||
reg = stream->config->mi.cr_base_ad_init;
|
||||
if (stream->id != RKISP_STREAM_FBC && stream->id != RKISP_STREAM_BP)
|
||||
rkisp_write(dev, stream->config->mi.cr_base_ad_init, val, false);
|
||||
rkisp_unite_write(dev, reg, val, false, dev->hw_dev->is_unite);
|
||||
}
|
||||
|
||||
if (stream->id != RKISP_STREAM_FBC) {
|
||||
mi_set_y_offset(stream, 0);
|
||||
mi_set_cb_offset(stream, 0);
|
||||
reg = stream->config->mi.y_offs_cnt_init;
|
||||
rkisp_unite_write(dev, reg, 0, false, dev->hw_dev->is_unite);
|
||||
reg = stream->config->mi.cb_offs_cnt_init;
|
||||
rkisp_unite_write(dev, reg, 0, false, dev->hw_dev->is_unite);
|
||||
reg = stream->config->mi.cr_offs_cnt_init;
|
||||
if (stream->id != RKISP_STREAM_BP)
|
||||
mi_set_cr_offset(stream, 0);
|
||||
rkisp_unite_write(dev, reg, 0, false, dev->hw_dev->is_unite);
|
||||
}
|
||||
|
||||
v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev,
|
||||
"%s stream:%d Y:0x%x CB:0x%x | Y_SHD:0x%x\n",
|
||||
__func__, stream->id,
|
||||
rkisp_read(dev, stream->config->mi.y_base_ad_init, false),
|
||||
rkisp_read(dev, stream->config->mi.cb_base_ad_init, false),
|
||||
rkisp_read(dev, stream->config->mi.y_base_ad_shd, true));
|
||||
if (dev->hw_dev->is_unite)
|
||||
v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev,
|
||||
"%s stream:%d Y:0x%x CB:0x%x | Y_SHD:0x%x, right\n",
|
||||
__func__, stream->id,
|
||||
rkisp_next_read(dev, stream->config->mi.y_base_ad_init, false),
|
||||
rkisp_next_read(dev, stream->config->mi.cb_base_ad_init, false),
|
||||
rkisp_next_read(dev, stream->config->mi.y_base_ad_shd, true));
|
||||
}
|
||||
|
||||
static struct streams_ops rkisp_mp_streams_ops = {
|
||||
.config_mi = mp_config_mi,
|
||||
.enable_mi = mp_enable_mi,
|
||||
.disable_mi = mp_disable_mi,
|
||||
.set_data_path = mp_set_data_path,
|
||||
.set_data_path = stream_data_path,
|
||||
.is_stream_stopped = mp_is_stream_stopped,
|
||||
.update_mi = update_mi,
|
||||
.frame_end = mi_frame_end,
|
||||
@@ -581,7 +645,7 @@ static struct streams_ops rkisp_sp_streams_ops = {
|
||||
.config_mi = sp_config_mi,
|
||||
.enable_mi = sp_enable_mi,
|
||||
.disable_mi = sp_disable_mi,
|
||||
.set_data_path = sp_set_data_path,
|
||||
.set_data_path = stream_data_path,
|
||||
.is_stream_stopped = sp_is_stream_stopped,
|
||||
.update_mi = update_mi,
|
||||
.frame_end = mi_frame_end,
|
||||
@@ -708,13 +772,12 @@ static void rkisp_stream_stop(struct rkisp_stream *stream)
|
||||
*/
|
||||
static int rkisp_start(struct rkisp_stream *stream)
|
||||
{
|
||||
void __iomem *base = stream->ispdev->base_addr;
|
||||
struct rkisp_device *dev = stream->ispdev;
|
||||
bool is_update = atomic_read(&dev->cap_dev.refcnt) > 1 ? false : true;
|
||||
int ret;
|
||||
|
||||
if (stream->ops->set_data_path)
|
||||
stream->ops->set_data_path(base);
|
||||
stream->ops->set_data_path(stream);
|
||||
ret = stream->ops->config_mi(stream);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -907,12 +970,6 @@ static int rkisp_stream_start(struct rkisp_stream *stream)
|
||||
dev->cap_dev.stream[RKISP_STREAM_SP].streaming :
|
||||
dev->cap_dev.stream[RKISP_STREAM_MP].streaming;
|
||||
|
||||
ret = rkisp_stream_config_rsz(stream, async);
|
||||
if (ret < 0) {
|
||||
v4l2_err(v4l2_dev, "config rsz failed with error %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* can't be async now, otherwise the latter started stream fails to
|
||||
* produce mi interrupt.
|
||||
@@ -923,6 +980,11 @@ static int rkisp_stream_start(struct rkisp_stream *stream)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = rkisp_stream_config_rsz(stream, async);
|
||||
if (ret < 0) {
|
||||
v4l2_err(v4l2_dev, "config rsz failed with error %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
end:
|
||||
return rkisp_start(stream);
|
||||
}
|
||||
@@ -1156,6 +1218,15 @@ void rkisp_mi_v30_isr(u32 mis_val, struct rkisp_device *dev)
|
||||
struct rkisp_stream *stream;
|
||||
unsigned int i;
|
||||
|
||||
if (dev->hw_dev->is_unite) {
|
||||
u32 val = rkisp_read(dev, ISP3X_MI_RIS, true);
|
||||
|
||||
if (val) {
|
||||
rkisp_write(dev, ISP3X_MI_ICR, val, true);
|
||||
v4l2_dbg(3, rkisp_debug, &dev->v4l2_dev,
|
||||
"left mi isr:0x%x\n", val);
|
||||
}
|
||||
}
|
||||
v4l2_dbg(3, rkisp_debug, &dev->v4l2_dev,
|
||||
"mi isr:0x%x\n", mis_val);
|
||||
|
||||
|
||||
@@ -22,6 +22,20 @@ void rkisp_write(struct rkisp_device *dev, u32 reg, u32 val, bool is_direct)
|
||||
}
|
||||
}
|
||||
|
||||
void rkisp_next_write(struct rkisp_device *dev, u32 reg, u32 val, bool is_direct)
|
||||
{
|
||||
u32 offset = RKISP_ISP_SW_MAX_SIZE + reg;
|
||||
u32 *mem = dev->sw_base_addr + offset;
|
||||
u32 *flag = dev->sw_base_addr + offset + RKISP_ISP_SW_REG_SIZE;
|
||||
|
||||
*mem = val;
|
||||
*flag = SW_REG_CACHE;
|
||||
if (dev->hw_dev->is_single || is_direct) {
|
||||
*flag = SW_REG_CACHE_SYNC;
|
||||
writel(val, dev->hw_dev->base_next_addr + reg);
|
||||
}
|
||||
}
|
||||
|
||||
u32 rkisp_read(struct rkisp_device *dev, u32 reg, bool is_direct)
|
||||
{
|
||||
u32 val;
|
||||
@@ -33,11 +47,27 @@ u32 rkisp_read(struct rkisp_device *dev, u32 reg, bool is_direct)
|
||||
return val;
|
||||
}
|
||||
|
||||
u32 rkisp_next_read(struct rkisp_device *dev, u32 reg, bool is_direct)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
if (dev->hw_dev->is_single || is_direct)
|
||||
val = readl(dev->hw_dev->base_next_addr + reg);
|
||||
else
|
||||
val = *(u32 *)(dev->sw_base_addr + RKISP_ISP_SW_MAX_SIZE + reg);
|
||||
return val;
|
||||
}
|
||||
|
||||
u32 rkisp_read_reg_cache(struct rkisp_device *dev, u32 reg)
|
||||
{
|
||||
return *(u32 *)(dev->sw_base_addr + reg);
|
||||
}
|
||||
|
||||
u32 rkisp_next_read_reg_cache(struct rkisp_device *dev, u32 reg)
|
||||
{
|
||||
return *(u32 *)(dev->sw_base_addr + RKISP_ISP_SW_MAX_SIZE + reg);
|
||||
}
|
||||
|
||||
void rkisp_set_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val, bool is_direct)
|
||||
{
|
||||
u32 tmp = rkisp_read(dev, reg, is_direct) & ~mask;
|
||||
@@ -45,6 +75,13 @@ void rkisp_set_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val, bool i
|
||||
rkisp_write(dev, reg, val | tmp, is_direct);
|
||||
}
|
||||
|
||||
void rkisp_next_set_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val, bool is_direct)
|
||||
{
|
||||
u32 tmp = rkisp_next_read(dev, reg, is_direct) & ~mask;
|
||||
|
||||
rkisp_next_write(dev, reg, val | tmp, is_direct);
|
||||
}
|
||||
|
||||
void rkisp_clear_bits(struct rkisp_device *dev, u32 reg, u32 mask, bool is_direct)
|
||||
{
|
||||
u32 tmp = rkisp_read(dev, reg, is_direct);
|
||||
@@ -52,6 +89,13 @@ void rkisp_clear_bits(struct rkisp_device *dev, u32 reg, u32 mask, bool is_direc
|
||||
rkisp_write(dev, reg, tmp & ~mask, is_direct);
|
||||
}
|
||||
|
||||
void rkisp_next_clear_bits(struct rkisp_device *dev, u32 reg, u32 mask, bool is_direct)
|
||||
{
|
||||
u32 tmp = rkisp_next_read(dev, reg, is_direct);
|
||||
|
||||
rkisp_next_write(dev, reg, tmp & ~mask, is_direct);
|
||||
}
|
||||
|
||||
void rkisp_update_regs(struct rkisp_device *dev, u32 start, u32 end)
|
||||
{
|
||||
void __iomem *base = dev->hw_dev->base_addr;
|
||||
|
||||
@@ -164,6 +164,39 @@ u32 rkisp_read(struct rkisp_device *dev, u32 reg, bool is_direct);
|
||||
u32 rkisp_read_reg_cache(struct rkisp_device *dev, u32 reg);
|
||||
void rkisp_set_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val, bool is_direct);
|
||||
void rkisp_clear_bits(struct rkisp_device *dev, u32 reg, u32 mask, bool is_direct);
|
||||
/* for dual isp, config for next isp reg */
|
||||
void rkisp_next_write(struct rkisp_device *dev, u32 reg, u32 val, bool is_direct);
|
||||
u32 rkisp_next_read(struct rkisp_device *dev, u32 reg, bool is_direct);
|
||||
u32 rkisp_next_read_reg_cache(struct rkisp_device *dev, u32 reg);
|
||||
void rkisp_next_set_bits(struct rkisp_device *dev, u32 reg, u32 mask, u32 val, bool is_direct);
|
||||
void rkisp_next_clear_bits(struct rkisp_device *dev, u32 reg, u32 mask, bool is_direct);
|
||||
|
||||
static inline void
|
||||
rkisp_unite_write(struct rkisp_device *dev, u32 reg, u32 val, bool is_direct, bool is_unite)
|
||||
{
|
||||
rkisp_write(dev, reg, val, is_direct);
|
||||
if (is_unite)
|
||||
rkisp_next_write(dev, reg, val, is_direct);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rkisp_unite_set_bits(struct rkisp_device *dev, u32 reg, u32 mask,
|
||||
u32 val, bool is_direct, bool is_unite)
|
||||
{
|
||||
rkisp_set_bits(dev, reg, mask, val, is_direct);
|
||||
if (is_unite)
|
||||
rkisp_next_set_bits(dev, reg, mask, val, is_direct);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rkisp_unite_clear_bits(struct rkisp_device *dev, u32 reg, u32 mask,
|
||||
bool is_direct, bool is_unite)
|
||||
{
|
||||
rkisp_clear_bits(dev, reg, mask, is_direct);
|
||||
if (is_unite)
|
||||
rkisp_next_clear_bits(dev, reg, mask, is_direct);
|
||||
}
|
||||
|
||||
void rkisp_update_regs(struct rkisp_device *dev, u32 start, u32 end);
|
||||
|
||||
int rkisp_alloc_buffer(struct rkisp_device *dev, struct rkisp_dummy_buffer *buf);
|
||||
|
||||
@@ -497,8 +497,9 @@ int rkisp_csi_config_patch(struct rkisp_device *dev)
|
||||
}
|
||||
|
||||
if (!dev->hw_dev->is_mi_update)
|
||||
rkisp_write(dev, CSI2RX_CTRL0,
|
||||
SW_IBUF_OP_MODE(dev->hdr.op_mode), true);
|
||||
rkisp_unite_write(dev, CSI2RX_CTRL0,
|
||||
SW_IBUF_OP_MODE(dev->hdr.op_mode),
|
||||
true, dev->hw_dev->is_unite);
|
||||
|
||||
/* hdr merge */
|
||||
switch (dev->hdr.op_mode) {
|
||||
@@ -522,16 +523,19 @@ int rkisp_csi_config_patch(struct rkisp_device *dev)
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
rkisp_write(dev, ISP_HDRMGE_BASE, val, false);
|
||||
rkisp_unite_write(dev, ISP_HDRMGE_BASE, val, false, dev->hw_dev->is_unite);
|
||||
|
||||
rkisp_set_bits(dev, CSI2RX_MASK_STAT, 0, RAW_RD_SIZE_ERR, true);
|
||||
rkisp_unite_set_bits(dev, CSI2RX_MASK_STAT, 0, RAW_RD_SIZE_ERR,
|
||||
true, dev->hw_dev->is_unite);
|
||||
}
|
||||
|
||||
if (IS_HDR_RDBK(dev->hdr.op_mode))
|
||||
rkisp_set_bits(dev, CTRL_SWS_CFG, 0, SW_MPIP_DROP_FRM_DIS, true);
|
||||
rkisp_unite_set_bits(dev, CTRL_SWS_CFG, 0, SW_MPIP_DROP_FRM_DIS,
|
||||
true, dev->hw_dev->is_unite);
|
||||
|
||||
if (dev->isp_ver == ISP_V30)
|
||||
rkisp_set_bits(dev, CTRL_SWS_CFG, 0, ISP3X_SW_ACK_FRM_PRO_DIS, true);
|
||||
rkisp_unite_set_bits(dev, CTRL_SWS_CFG, 0, ISP3X_SW_ACK_FRM_PRO_DIS,
|
||||
true, dev->hw_dev->is_unite);
|
||||
|
||||
memset(dev->filt_state, 0, sizeof(dev->filt_state));
|
||||
dev->rdbk_cnt = -1;
|
||||
|
||||
@@ -224,6 +224,8 @@ static int __isp_pipeline_s_isp_clk(struct rkisp_pipeline *p)
|
||||
end:
|
||||
/* set isp clock rate */
|
||||
rkisp_set_clk_rate(hw_dev->clks[0], hw_dev->clk_rate_tbl[i].clk_rate * 1000000UL);
|
||||
if (hw_dev->is_unite)
|
||||
rkisp_set_clk_rate(hw_dev->clks[5], hw_dev->clk_rate_tbl[i].clk_rate * 1000000UL);
|
||||
dev_dbg(hw_dev->dev, "set isp clk = %luHz\n", clk_get_rate(hw_dev->clks[0]));
|
||||
|
||||
return 0;
|
||||
@@ -722,7 +724,7 @@ static int rkisp_plat_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
struct v4l2_device *v4l2_dev;
|
||||
struct rkisp_device *isp_dev;
|
||||
int i, ret;
|
||||
int i, ret, mult = 1;
|
||||
|
||||
sprintf(rkisp_version, "v%02x.%02x.%02x",
|
||||
RKISP_DRIVER_VERSION >> 16,
|
||||
@@ -734,24 +736,29 @@ static int rkisp_plat_probe(struct platform_device *pdev)
|
||||
isp_dev = devm_kzalloc(dev, sizeof(*isp_dev), GFP_KERNEL);
|
||||
if (!isp_dev)
|
||||
return -ENOMEM;
|
||||
isp_dev->sw_base_addr = devm_kzalloc(dev, RKISP_ISP_SW_MAX_SIZE, GFP_KERNEL);
|
||||
if (!isp_dev->sw_base_addr)
|
||||
return -ENOMEM;
|
||||
|
||||
dev_set_drvdata(dev, isp_dev);
|
||||
isp_dev->dev = dev;
|
||||
ret = rkisp_attach_hw(isp_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (isp_dev->hw_dev->is_unite)
|
||||
mult = 2;
|
||||
isp_dev->sw_base_addr = devm_kzalloc(dev, RKISP_ISP_SW_MAX_SIZE * mult, GFP_KERNEL);
|
||||
if (!isp_dev->sw_base_addr)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = rkisp_vs_irq_parse(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = rkisp_attach_hw(isp_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
sprintf(isp_dev->media_dev.model, "%s%d",
|
||||
DRIVER_NAME, isp_dev->dev_id);
|
||||
strscpy(isp_dev->name, dev_name(dev), sizeof(isp_dev->name));
|
||||
if (!isp_dev->hw_dev->is_unite)
|
||||
strscpy(isp_dev->name, dev_name(dev), sizeof(isp_dev->name));
|
||||
else
|
||||
strscpy(isp_dev->name, "rkisp-unite", sizeof(isp_dev->name));
|
||||
strscpy(isp_dev->media_dev.driver_name, isp_dev->name,
|
||||
sizeof(isp_dev->media_dev.driver_name));
|
||||
|
||||
|
||||
@@ -318,6 +318,7 @@ static struct streams_ops rkisp_dmarx_streams_ops = {
|
||||
static int rawrd_config_mi(struct rkisp_stream *stream)
|
||||
{
|
||||
struct rkisp_device *dev = stream->ispdev;
|
||||
bool is_unite = dev->hw_dev->is_unite;
|
||||
u32 val;
|
||||
|
||||
val = rkisp_read(dev, CSI2RX_DATA_IDS_1, true);
|
||||
@@ -346,9 +347,9 @@ static int rawrd_config_mi(struct rkisp_stream *stream)
|
||||
default:
|
||||
val |= CIF_CSI2_DT_RAW12;
|
||||
}
|
||||
rkisp_write(dev, CSI2RX_RAW_RD_CTRL,
|
||||
stream->memory << 2, false);
|
||||
rkisp_write(dev, CSI2RX_DATA_IDS_1, val, false);
|
||||
rkisp_unite_write(dev, CSI2RX_RAW_RD_CTRL,
|
||||
stream->memory << 2, false, is_unite);
|
||||
rkisp_unite_write(dev, CSI2RX_DATA_IDS_1, val, false, is_unite);
|
||||
rkisp_rawrd_set_pic_size(dev, stream->out_fmt.width,
|
||||
stream->out_fmt.height);
|
||||
mi_raw_length(stream);
|
||||
@@ -364,11 +365,17 @@ static void update_rawrd(struct rkisp_stream *stream)
|
||||
{
|
||||
struct rkisp_device *dev = stream->ispdev;
|
||||
void __iomem *base = dev->base_addr;
|
||||
struct capture_fmt *fmt = &stream->out_isp_fmt;
|
||||
u32 val;
|
||||
|
||||
if (stream->curr_buf) {
|
||||
rkisp_write(dev, stream->config->mi.y_base_ad_init,
|
||||
stream->curr_buf->buff_addr[RKISP_PLANE_Y],
|
||||
false);
|
||||
val = stream->curr_buf->buff_addr[RKISP_PLANE_Y];
|
||||
rkisp_write(dev, stream->config->mi.y_base_ad_init, val, false);
|
||||
if (dev->hw_dev->is_unite) {
|
||||
val += (stream->out_fmt.width / 2 - RKMOUDLE_UNITE_EXTEND_PIXEL) *
|
||||
fmt->bpp[0] / 8;
|
||||
rkisp_next_write(dev, stream->config->mi.y_base_ad_init, val, false);
|
||||
}
|
||||
stream->frame_end = false;
|
||||
if (stream->id == RKISP_STREAM_RAWRD2 &&
|
||||
stream->out_isp_fmt.fmt_type == FMT_YUV) {
|
||||
@@ -1059,6 +1066,8 @@ void rkisp_rawrd_set_pic_size(struct rkisp_device *dev,
|
||||
{
|
||||
struct rkisp_isp_subdev *sdev = &dev->isp_sdev;
|
||||
u8 mult = sdev->in_fmt.fmt_type == FMT_YUV ? 2 : 1;
|
||||
bool is_unite = dev->hw_dev->is_unite;
|
||||
u32 w = !is_unite ? width : width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL;
|
||||
|
||||
/* rx height should equal to isp height + offset for read back mode */
|
||||
height = sdev->in_crop.top + sdev->in_crop.height;
|
||||
@@ -1070,7 +1079,8 @@ void rkisp_rawrd_set_pic_size(struct rkisp_device *dev,
|
||||
dev->rd_mode == HDR_RDBK_FRAME1)
|
||||
height += RKMODULE_EXTEND_LINE;
|
||||
|
||||
rkisp_write(dev, CSI2RX_RAW_RD_PIC_SIZE, height << 16 | width * mult, false);
|
||||
w *= mult;
|
||||
rkisp_unite_write(dev, CSI2RX_RAW_RD_PIC_SIZE, height << 16 | w, false, is_unite);
|
||||
}
|
||||
|
||||
void rkisp_dmarx_get_frame(struct rkisp_device *dev, u32 *id,
|
||||
|
||||
@@ -109,6 +109,10 @@ static void default_sw_reg_flag(struct rkisp_device *dev)
|
||||
for (i = 0; i < size; i++) {
|
||||
flag = dev->sw_base_addr + reg[i] + RKISP_ISP_SW_REG_SIZE;
|
||||
*flag = SW_REG_CACHE;
|
||||
if (dev->hw_dev->is_unite) {
|
||||
flag += RKISP_ISP_SW_MAX_SIZE / 4;
|
||||
*flag = SW_REG_CACHE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,6 +121,8 @@ static irqreturn_t mipi_irq_hdl(int irq, void *ctx)
|
||||
struct device *dev = ctx;
|
||||
struct rkisp_hw_dev *hw_dev = dev_get_drvdata(dev);
|
||||
struct rkisp_device *isp = hw_dev->isp[hw_dev->mipi_dev_id];
|
||||
void __iomem *base = !hw_dev->is_unite ?
|
||||
hw_dev->base_addr : hw_dev->base_next_addr;
|
||||
|
||||
if (hw_dev->is_thunderboot)
|
||||
return IRQ_HANDLED;
|
||||
@@ -124,9 +130,9 @@ static irqreturn_t mipi_irq_hdl(int irq, void *ctx)
|
||||
if (hw_dev->isp_ver == ISP_V13 || hw_dev->isp_ver == ISP_V12) {
|
||||
u32 err1, err2, err3;
|
||||
|
||||
err1 = readl(hw_dev->base_addr + CIF_ISP_CSI0_ERR1);
|
||||
err2 = readl(hw_dev->base_addr + CIF_ISP_CSI0_ERR2);
|
||||
err3 = readl(hw_dev->base_addr + CIF_ISP_CSI0_ERR3);
|
||||
err1 = readl(base + CIF_ISP_CSI0_ERR1);
|
||||
err2 = readl(base + CIF_ISP_CSI0_ERR2);
|
||||
err3 = readl(base + CIF_ISP_CSI0_ERR3);
|
||||
|
||||
if (err1 || err2 || err3)
|
||||
rkisp_mipi_v13_isr(err1, err2, err3, isp);
|
||||
@@ -135,10 +141,10 @@ static irqreturn_t mipi_irq_hdl(int irq, void *ctx)
|
||||
hw_dev->isp_ver == ISP_V30) {
|
||||
u32 phy, packet, overflow, state;
|
||||
|
||||
state = readl(hw_dev->base_addr + CSI2RX_ERR_STAT);
|
||||
phy = readl(hw_dev->base_addr + CSI2RX_ERR_PHY);
|
||||
packet = readl(hw_dev->base_addr + CSI2RX_ERR_PACKET);
|
||||
overflow = readl(hw_dev->base_addr + CSI2RX_ERR_OVERFLOW);
|
||||
state = readl(base + CSI2RX_ERR_STAT);
|
||||
phy = readl(base + CSI2RX_ERR_PHY);
|
||||
packet = readl(base + CSI2RX_ERR_PACKET);
|
||||
overflow = readl(base + CSI2RX_ERR_OVERFLOW);
|
||||
if (phy | packet | overflow | state) {
|
||||
if (hw_dev->isp_ver == ISP_V20)
|
||||
rkisp_mipi_v20_isr(phy, packet, overflow, state, isp);
|
||||
@@ -148,7 +154,7 @@ static irqreturn_t mipi_irq_hdl(int irq, void *ctx)
|
||||
rkisp_mipi_v30_isr(phy, packet, overflow, state, isp);
|
||||
}
|
||||
} else {
|
||||
u32 mis_val = readl(hw_dev->base_addr + CIF_MIPI_MIS);
|
||||
u32 mis_val = readl(base + CIF_MIPI_MIS);
|
||||
|
||||
if (mis_val)
|
||||
rkisp_mipi_isr(mis_val, isp);
|
||||
@@ -162,13 +168,15 @@ static irqreturn_t mi_irq_hdl(int irq, void *ctx)
|
||||
struct device *dev = ctx;
|
||||
struct rkisp_hw_dev *hw_dev = dev_get_drvdata(dev);
|
||||
struct rkisp_device *isp = hw_dev->isp[hw_dev->cur_dev_id];
|
||||
void __iomem *base = !hw_dev->is_unite ?
|
||||
hw_dev->base_addr : hw_dev->base_next_addr;
|
||||
u32 mis_val, tx_isr = MI_RAW0_WR_FRAME | MI_RAW1_WR_FRAME |
|
||||
MI_RAW2_WR_FRAME | MI_RAW3_WR_FRAME;
|
||||
|
||||
if (hw_dev->is_thunderboot)
|
||||
return IRQ_HANDLED;
|
||||
|
||||
mis_val = readl(hw_dev->base_addr + CIF_MI_MIS);
|
||||
mis_val = readl(base + CIF_MI_MIS);
|
||||
if (mis_val) {
|
||||
if (mis_val & ~tx_isr)
|
||||
rkisp_mi_isr(mis_val & ~tx_isr, isp);
|
||||
@@ -185,16 +193,18 @@ static irqreturn_t isp_irq_hdl(int irq, void *ctx)
|
||||
struct device *dev = ctx;
|
||||
struct rkisp_hw_dev *hw_dev = dev_get_drvdata(dev);
|
||||
struct rkisp_device *isp = hw_dev->isp[hw_dev->cur_dev_id];
|
||||
void __iomem *base = !hw_dev->is_unite ?
|
||||
hw_dev->base_addr : hw_dev->base_next_addr;
|
||||
unsigned int mis_val, mis_3a = 0;
|
||||
|
||||
if (hw_dev->is_thunderboot)
|
||||
return IRQ_HANDLED;
|
||||
|
||||
mis_val = readl(hw_dev->base_addr + CIF_ISP_MIS);
|
||||
mis_val = readl(base + CIF_ISP_MIS);
|
||||
if (hw_dev->isp_ver == ISP_V20 ||
|
||||
hw_dev->isp_ver == ISP_V21 ||
|
||||
hw_dev->isp_ver == ISP_V30)
|
||||
mis_3a = readl(hw_dev->base_addr + ISP_ISP3A_MIS);
|
||||
mis_3a = readl(base + ISP_ISP3A_MIS);
|
||||
if (mis_val || mis_3a)
|
||||
rkisp_isp_isr(mis_val, mis_3a, isp);
|
||||
|
||||
@@ -474,7 +484,8 @@ static const struct isp_match_data rv1126_isp_match_data = {
|
||||
.clk_rate_tbl = rv1126_isp_clk_rate,
|
||||
.num_clk_rate_tbl = ARRAY_SIZE(rv1126_isp_clk_rate),
|
||||
.irqs = rv1126_isp_irqs,
|
||||
.num_irqs = ARRAY_SIZE(rv1126_isp_irqs)
|
||||
.num_irqs = ARRAY_SIZE(rv1126_isp_irqs),
|
||||
.unite = false,
|
||||
};
|
||||
|
||||
static const struct isp_match_data rk1808_isp_match_data = {
|
||||
@@ -484,7 +495,8 @@ static const struct isp_match_data rk1808_isp_match_data = {
|
||||
.clk_rate_tbl = rk1808_isp_clk_rate,
|
||||
.num_clk_rate_tbl = ARRAY_SIZE(rk1808_isp_clk_rate),
|
||||
.irqs = rk1808_isp_irqs,
|
||||
.num_irqs = ARRAY_SIZE(rk1808_isp_irqs)
|
||||
.num_irqs = ARRAY_SIZE(rk1808_isp_irqs),
|
||||
.unite = false,
|
||||
};
|
||||
|
||||
static const struct isp_match_data rk3288_isp_match_data = {
|
||||
@@ -494,7 +506,8 @@ static const struct isp_match_data rk3288_isp_match_data = {
|
||||
.clk_rate_tbl = rk3288_isp_clk_rate,
|
||||
.num_clk_rate_tbl = ARRAY_SIZE(rk3288_isp_clk_rate),
|
||||
.irqs = rk3288_isp_irqs,
|
||||
.num_irqs = ARRAY_SIZE(rk3288_isp_irqs)
|
||||
.num_irqs = ARRAY_SIZE(rk3288_isp_irqs),
|
||||
.unite = false,
|
||||
};
|
||||
|
||||
static const struct isp_match_data rk3326_isp_match_data = {
|
||||
@@ -504,7 +517,8 @@ static const struct isp_match_data rk3326_isp_match_data = {
|
||||
.clk_rate_tbl = rk3326_isp_clk_rate,
|
||||
.num_clk_rate_tbl = ARRAY_SIZE(rk3326_isp_clk_rate),
|
||||
.irqs = rk3326_isp_irqs,
|
||||
.num_irqs = ARRAY_SIZE(rk3326_isp_irqs)
|
||||
.num_irqs = ARRAY_SIZE(rk3326_isp_irqs),
|
||||
.unite = false,
|
||||
};
|
||||
|
||||
static const struct isp_match_data rk3368_isp_match_data = {
|
||||
@@ -514,7 +528,8 @@ static const struct isp_match_data rk3368_isp_match_data = {
|
||||
.clk_rate_tbl = rk3368_isp_clk_rate,
|
||||
.num_clk_rate_tbl = ARRAY_SIZE(rk3368_isp_clk_rate),
|
||||
.irqs = rk3368_isp_irqs,
|
||||
.num_irqs = ARRAY_SIZE(rk3368_isp_irqs)
|
||||
.num_irqs = ARRAY_SIZE(rk3368_isp_irqs),
|
||||
.unite = false,
|
||||
};
|
||||
|
||||
static const struct isp_match_data rk3399_isp_match_data = {
|
||||
@@ -524,7 +539,8 @@ static const struct isp_match_data rk3399_isp_match_data = {
|
||||
.clk_rate_tbl = rk3399_isp_clk_rate,
|
||||
.num_clk_rate_tbl = ARRAY_SIZE(rk3399_isp_clk_rate),
|
||||
.irqs = rk3399_isp_irqs,
|
||||
.num_irqs = ARRAY_SIZE(rk3399_isp_irqs)
|
||||
.num_irqs = ARRAY_SIZE(rk3399_isp_irqs),
|
||||
.unite = false,
|
||||
};
|
||||
|
||||
static const struct isp_match_data rk3568_isp_match_data = {
|
||||
@@ -534,7 +550,8 @@ static const struct isp_match_data rk3568_isp_match_data = {
|
||||
.clk_rate_tbl = rk3568_isp_clk_rate,
|
||||
.num_clk_rate_tbl = ARRAY_SIZE(rk3568_isp_clk_rate),
|
||||
.irqs = rk3568_isp_irqs,
|
||||
.num_irqs = ARRAY_SIZE(rk3568_isp_irqs)
|
||||
.num_irqs = ARRAY_SIZE(rk3568_isp_irqs),
|
||||
.unite = false,
|
||||
};
|
||||
|
||||
static const struct isp_match_data rk3588_isp_match_data = {
|
||||
@@ -545,6 +562,7 @@ static const struct isp_match_data rk3588_isp_match_data = {
|
||||
.num_clk_rate_tbl = ARRAY_SIZE(rk3588_isp_clk_rate),
|
||||
.irqs = rk3588_isp_irqs,
|
||||
.num_irqs = ARRAY_SIZE(rk3588_isp_irqs),
|
||||
.unite = false,
|
||||
};
|
||||
|
||||
static const struct of_device_id rkisp_hw_of_match[] = {
|
||||
@@ -603,6 +621,8 @@ void rkisp_soft_reset(struct rkisp_hw_dev *dev, bool is_secure)
|
||||
* isp soft reset first to protect isp reset.
|
||||
*/
|
||||
writel(0xffff, base + CIF_IRCL);
|
||||
if (dev->is_unite)
|
||||
writel(0xffff, dev->base_next_addr + CIF_IRCL);
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
@@ -617,6 +637,8 @@ void rkisp_soft_reset(struct rkisp_hw_dev *dev, bool is_secure)
|
||||
if (dev->isp_ver == ISP_V20)
|
||||
writel(CIF_ISP_CTRL_ISP_MODE_BAYER_ITU601, base + CIF_ISP_CTRL);
|
||||
writel(0xffff, base + CIF_IRCL);
|
||||
if (dev->is_unite)
|
||||
writel(0xffff, dev->base_next_addr + CIF_IRCL);
|
||||
udelay(10);
|
||||
|
||||
/* refresh iommu after reset */
|
||||
@@ -637,6 +659,8 @@ static void isp_config_clk(struct rkisp_hw_dev *dev, int on)
|
||||
val |= ICCL_MPFBC_CLK;
|
||||
|
||||
writel(val, dev->base_addr + CIF_ICCL);
|
||||
if (dev->is_unite)
|
||||
writel(val, dev->base_next_addr + CIF_ICCL);
|
||||
|
||||
if (dev->isp_ver == ISP_V12 || dev->isp_ver == ISP_V13) {
|
||||
val = !on ? 0 :
|
||||
@@ -660,6 +684,8 @@ static void isp_config_clk(struct rkisp_hw_dev *dev, int on)
|
||||
if (dev->isp_ver == ISP_V20 && on)
|
||||
val |= CLK_CTRL_ISP_3A;
|
||||
writel(val, dev->base_addr + CTRL_VI_ISP_CLK_CTRL);
|
||||
if (dev->is_unite)
|
||||
writel(val, dev->base_next_addr + CTRL_VI_ISP_CLK_CTRL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -682,6 +708,7 @@ static void disable_sys_clk(struct rkisp_hw_dev *dev)
|
||||
static int enable_sys_clk(struct rkisp_hw_dev *dev)
|
||||
{
|
||||
int i, ret = -EINVAL;
|
||||
unsigned long rate;
|
||||
|
||||
for (i = 0; i < dev->num_clks; i++) {
|
||||
if (!IS_ERR(dev->clks[i])) {
|
||||
@@ -691,8 +718,10 @@ static int enable_sys_clk(struct rkisp_hw_dev *dev)
|
||||
}
|
||||
}
|
||||
|
||||
rkisp_set_clk_rate(dev->clks[0],
|
||||
dev->clk_rate_tbl[0].clk_rate * 1000000UL);
|
||||
rate = dev->clk_rate_tbl[0].clk_rate * 1000000UL;
|
||||
rkisp_set_clk_rate(dev->clks[0], rate);
|
||||
if (dev->is_unite)
|
||||
rkisp_set_clk_rate(dev->clks[5], rate);
|
||||
rkisp_soft_reset(dev, false);
|
||||
isp_config_clk(dev, true);
|
||||
|
||||
@@ -764,9 +793,31 @@ static int rkisp_hw_probe(struct platform_device *pdev)
|
||||
goto err;
|
||||
}
|
||||
|
||||
rkisp_monitor = device_property_read_bool(dev, "rockchip,restart-monitor-en");
|
||||
|
||||
match_data = match->data;
|
||||
hw_dev->base_next_addr = NULL;
|
||||
if (match_data->unite) {
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
if (!res) {
|
||||
dev_err(dev, "get next resource failed\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
hw_dev->base_next_addr = devm_ioremap_resource(dev, res);
|
||||
if (PTR_ERR(hw_dev->base_next_addr) == -EBUSY) {
|
||||
resource_size_t offset = res->start;
|
||||
resource_size_t size = resource_size(res);
|
||||
|
||||
hw_dev->base_next_addr = devm_ioremap(dev, offset, size);
|
||||
}
|
||||
|
||||
if (IS_ERR(hw_dev->base_next_addr)) {
|
||||
dev_err(dev, "ioremap next failed\n");
|
||||
ret = PTR_ERR(hw_dev->base_next_addr);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
rkisp_monitor = device_property_read_bool(dev, "rockchip,restart-monitor-en");
|
||||
hw_dev->mipi_irq = -1;
|
||||
|
||||
hw_dev->pdev = pdev;
|
||||
@@ -804,6 +855,7 @@ static int rkisp_hw_probe(struct platform_device *pdev)
|
||||
hw_dev->cur_dev_id = 0;
|
||||
hw_dev->mipi_dev_id = 0;
|
||||
hw_dev->isp_ver = match_data->isp_ver;
|
||||
hw_dev->is_unite = match_data->unite;
|
||||
mutex_init(&hw_dev->dev_lock);
|
||||
spin_lock_init(&hw_dev->rdbk_lock);
|
||||
atomic_set(&hw_dev->refcnt, 0);
|
||||
@@ -860,8 +912,11 @@ static void rkisp_hw_shutdown(struct platform_device *pdev)
|
||||
struct rkisp_hw_dev *hw_dev = platform_get_drvdata(pdev);
|
||||
|
||||
hw_dev->is_shutdown = true;
|
||||
if (pm_runtime_active(&pdev->dev))
|
||||
if (pm_runtime_active(&pdev->dev)) {
|
||||
writel(0xffff, hw_dev->base_addr + CIF_IRCL);
|
||||
if (hw_dev->is_unite)
|
||||
writel(0xffff, hw_dev->base_next_addr + CIF_IRCL);
|
||||
}
|
||||
dev_info(&pdev->dev, "%s\n", __func__);
|
||||
}
|
||||
|
||||
@@ -877,6 +932,7 @@ static int __maybe_unused rkisp_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct rkisp_hw_dev *hw_dev = dev_get_drvdata(dev);
|
||||
void __iomem *base = hw_dev->base_addr;
|
||||
int mult = hw_dev->is_unite ? 2 : 1;
|
||||
int ret, i;
|
||||
|
||||
ret = pinctrl_pm_select_default_state(dev);
|
||||
@@ -888,8 +944,13 @@ static int __maybe_unused rkisp_runtime_resume(struct device *dev)
|
||||
for (i = 0; i < hw_dev->dev_num; i++) {
|
||||
void *buf = hw_dev->isp[i]->sw_base_addr;
|
||||
|
||||
memset(buf, 0, RKISP_ISP_SW_MAX_SIZE);
|
||||
memset(buf, 0, RKISP_ISP_SW_MAX_SIZE * mult);
|
||||
memcpy_fromio(buf, base, RKISP_ISP_SW_REG_SIZE);
|
||||
if (hw_dev->is_unite) {
|
||||
buf += RKISP_ISP_SW_MAX_SIZE;
|
||||
base = hw_dev->base_next_addr;
|
||||
memcpy_fromio(buf, base, RKISP_ISP_SW_REG_SIZE);
|
||||
}
|
||||
default_sw_reg_flag(hw_dev->isp[i]);
|
||||
}
|
||||
hw_dev->monitor.is_en = rkisp_monitor;
|
||||
|
||||
@@ -22,6 +22,7 @@ struct isp_match_data {
|
||||
int num_clk_rate_tbl;
|
||||
struct isp_irqs_data *irqs;
|
||||
int num_irqs;
|
||||
bool unite;
|
||||
};
|
||||
|
||||
struct rkisp_monitor {
|
||||
@@ -40,6 +41,7 @@ struct rkisp_hw_dev {
|
||||
struct device *dev;
|
||||
struct regmap *grf;
|
||||
void __iomem *base_addr;
|
||||
void __iomem *base_next_addr;
|
||||
struct clk *clks[RKISP_MAX_BUS_CLK];
|
||||
int num_clks;
|
||||
const struct isp_clk_info *clk_rate_tbl;
|
||||
@@ -79,6 +81,7 @@ struct rkisp_hw_dev {
|
||||
bool is_thunderboot;
|
||||
bool is_buf_init;
|
||||
bool is_shutdown;
|
||||
bool is_unite;
|
||||
};
|
||||
|
||||
int rkisp_register_irq(struct rkisp_hw_dev *dev);
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
*/
|
||||
|
||||
#include <media/v4l2-common.h>
|
||||
#include <linux/rk-camera-module.h>
|
||||
#include "regs.h"
|
||||
|
||||
void rkisp_disable_dcrop(struct rkisp_stream *stream, bool async)
|
||||
@@ -44,7 +45,8 @@ void rkisp_disable_dcrop(struct rkisp_stream *stream, bool async)
|
||||
|
||||
if (async && dev->hw_dev->is_single)
|
||||
val = CIF_DUAL_CROP_GEN_CFG_UPD;
|
||||
rkisp_set_bits(dev, stream->config->dual_crop.ctrl, mask, val, false);
|
||||
rkisp_unite_set_bits(dev, stream->config->dual_crop.ctrl,
|
||||
mask, val, false, dev->hw_dev->is_unite);
|
||||
}
|
||||
|
||||
void rkisp_config_dcrop(struct rkisp_stream *stream,
|
||||
@@ -52,16 +54,49 @@ void rkisp_config_dcrop(struct rkisp_stream *stream,
|
||||
{
|
||||
struct rkisp_device *dev = stream->ispdev;
|
||||
u32 val = stream->config->dual_crop.yuvmode_mask;
|
||||
bool is_unite = dev->hw_dev->is_unite;
|
||||
struct v4l2_rect tmp = *rect;
|
||||
u32 reg;
|
||||
|
||||
if (is_unite)
|
||||
tmp.width /= 2;
|
||||
reg = stream->config->dual_crop.h_offset;
|
||||
rkisp_write(dev, reg, tmp.left, false);
|
||||
reg = stream->config->dual_crop.h_size;
|
||||
rkisp_write(dev, reg, tmp.width, false);
|
||||
|
||||
reg = stream->config->dual_crop.v_offset;
|
||||
rkisp_unite_write(dev, reg, tmp.top, false, is_unite);
|
||||
reg = stream->config->dual_crop.v_size;
|
||||
rkisp_unite_write(dev, reg, tmp.height, false, is_unite);
|
||||
|
||||
rkisp_write(dev, stream->config->dual_crop.h_offset, rect->left, false);
|
||||
rkisp_write(dev, stream->config->dual_crop.v_offset, rect->top, false);
|
||||
rkisp_write(dev, stream->config->dual_crop.h_size, rect->width, false);
|
||||
rkisp_write(dev, stream->config->dual_crop.v_size, rect->height, false);
|
||||
if (async && dev->hw_dev->is_single)
|
||||
val |= CIF_DUAL_CROP_GEN_CFG_UPD;
|
||||
else
|
||||
val |= CIF_DUAL_CROP_CFG_UPD;
|
||||
rkisp_set_bits(dev, stream->config->dual_crop.ctrl, 0, val, false);
|
||||
if (is_unite) {
|
||||
reg = stream->config->dual_crop.h_offset;
|
||||
rkisp_next_write(dev, reg, RKMOUDLE_UNITE_EXTEND_PIXEL, false);
|
||||
reg = stream->config->dual_crop.h_size;
|
||||
rkisp_next_write(dev, reg, tmp.width, false);
|
||||
|
||||
reg = stream->config->dual_crop.ctrl;
|
||||
rkisp_next_set_bits(dev, reg, 0, val, false);
|
||||
/* output with scale, crop by scl output */
|
||||
if (stream->out_fmt.width < rect->width)
|
||||
val = 0;
|
||||
else
|
||||
v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev,
|
||||
"left dcrop (%d, %d) %dx%d\n",
|
||||
tmp.top, tmp.left, tmp.width, tmp.height);
|
||||
v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev,
|
||||
"right dcrop (%d, %d) %dx%d\n",
|
||||
RKMOUDLE_UNITE_EXTEND_PIXEL, tmp.top, tmp.width, tmp.height);
|
||||
}
|
||||
if (val) {
|
||||
reg = stream->config->dual_crop.ctrl;
|
||||
rkisp_set_bits(dev, reg, 0, val, false);
|
||||
}
|
||||
}
|
||||
|
||||
void rkisp_dump_rsz_regs(struct rkisp_stream *stream)
|
||||
@@ -107,7 +142,8 @@ static void update_rsz_shadow(struct rkisp_stream *stream, bool async)
|
||||
|
||||
if (async && dev->hw_dev->is_single)
|
||||
val = CIF_RSZ_CTRL_CFG_UPD_AUTO;
|
||||
rkisp_set_bits(dev, stream->config->rsz.ctrl, 0, val, false);
|
||||
rkisp_unite_set_bits(dev, stream->config->rsz.ctrl, 0,
|
||||
val, false, dev->hw_dev->is_unite);
|
||||
}
|
||||
|
||||
static void set_scale(struct rkisp_stream *stream, struct v4l2_rect *in_y,
|
||||
@@ -121,7 +157,8 @@ static void set_scale(struct rkisp_stream *stream, struct v4l2_rect *in_y,
|
||||
u32 scale_vy_addr = stream->config->rsz.scale_vy;
|
||||
u32 scale_vc_addr = stream->config->rsz.scale_vc;
|
||||
u32 rsz_ctrl_addr = stream->config->rsz.ctrl;
|
||||
u32 scale_hy, scale_hc, scale_vy, scale_vc, rsz_ctrl = 0;
|
||||
u32 scale_hy = 1, scale_hc = 1, scale_vy = 1, scale_vc = 1;
|
||||
u32 rsz_ctrl = 0;
|
||||
|
||||
if (in_y->width < out_y->width) {
|
||||
rsz_ctrl |= CIF_RSZ_CTRL_SCALE_HY_ENABLE |
|
||||
@@ -176,6 +213,75 @@ static void set_scale(struct rkisp_stream *stream, struct v4l2_rect *in_y,
|
||||
rkisp_write(dev, scale_vc_addr, scale_vc, false);
|
||||
}
|
||||
|
||||
if (dev->hw_dev->is_unite) {
|
||||
u32 hy_size_reg = stream->id == RKISP_STREAM_MP ?
|
||||
ISP3X_MAIN_RESIZE_HY_SIZE : ISP3X_SELF_RESIZE_HY_SIZE;
|
||||
u32 hc_size_reg = stream->id == RKISP_STREAM_MP ?
|
||||
ISP3X_MAIN_RESIZE_HC_SIZE : ISP3X_SELF_RESIZE_HC_SIZE;
|
||||
u32 hy_offs_mi_reg = stream->id == RKISP_STREAM_MP ?
|
||||
ISP3X_MAIN_RESIZE_HY_OFFS_MI : ISP3X_SELF_RESIZE_HY_OFFS_MI;
|
||||
u32 hc_offs_mi_reg = stream->id == RKISP_STREAM_MP ?
|
||||
ISP3X_MAIN_RESIZE_HC_OFFS_MI : ISP3X_SELF_RESIZE_HC_OFFS_MI;
|
||||
u32 in_crop_offs_reg = stream->id == RKISP_STREAM_MP ?
|
||||
ISP3X_MAIN_RESIZE_IN_CROP_OFFSET : ISP3X_SELF_RESIZE_IN_CROP_OFFSET;
|
||||
u32 isp_in_w = in_y->width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL;
|
||||
u32 scl_w = out_y->width / 2;
|
||||
u32 left_y = DIV_ROUND_UP(scl_w * 65536, scale_hy);
|
||||
u32 left_c = DIV_ROUND_UP(scl_w * 65536 / 2, scale_hc);
|
||||
u32 phase_src_y = left_y * scale_hy;
|
||||
u32 phase_dst_y = scl_w * 65536;
|
||||
u32 phase_left_y = scale_hy - (phase_src_y - phase_dst_y);
|
||||
u32 phase_src_c = left_c * scale_hc;
|
||||
u32 phase_dst_c = scl_w * 65536 / 2;
|
||||
u32 phase_left_c = scale_hc - (phase_src_c - phase_dst_c);
|
||||
u32 right_y = phase_left_y ?
|
||||
in_y->width - (left_y - 1) :
|
||||
in_y->width - left_y;
|
||||
u32 right_c = phase_left_c ?
|
||||
in_y->width - (left_c - 1) * 2 :
|
||||
in_y->width - left_c * 2;
|
||||
u32 right_crop_y = isp_in_w - right_y;
|
||||
u32 right_crop_c = isp_in_w - right_c;
|
||||
u32 right_scl_in_y = right_crop_y - RKMOUDLE_UNITE_EXTEND_PIXEL;
|
||||
u32 right_scl_in_c = right_crop_c - RKMOUDLE_UNITE_EXTEND_PIXEL;
|
||||
|
||||
/* left isp */
|
||||
rkisp_write(dev, hy_size_reg, scl_w, false);
|
||||
rkisp_write(dev, hc_size_reg, scl_w, false);
|
||||
rkisp_write(dev, hy_offs_mi_reg, 0, false);
|
||||
rkisp_write(dev, hc_offs_mi_reg, 0, false);
|
||||
rkisp_write(dev, in_crop_offs_reg, 0, false);
|
||||
|
||||
/* right isp */
|
||||
rkisp_next_write(dev, hy_size_reg, scl_w, false);
|
||||
rkisp_next_write(dev, hc_size_reg, scl_w, false);
|
||||
rkisp_next_write(dev, scale_hy_addr, scale_hy, false);
|
||||
rkisp_next_write(dev, scale_hcb_addr, scale_hc, false);
|
||||
rkisp_next_write(dev, scale_hcr_addr, scale_hc, false);
|
||||
rkisp_next_write(dev, scale_vy_addr, scale_vy, false);
|
||||
rkisp_next_write(dev, scale_vc_addr, scale_vc, false);
|
||||
rkisp_next_write(dev, stream->config->rsz.phase_hy, phase_left_y, false);
|
||||
rkisp_next_write(dev, stream->config->rsz.phase_hc, phase_left_c, false);
|
||||
rkisp_next_write(dev, stream->config->rsz.phase_vy, 0, false);
|
||||
rkisp_next_write(dev, stream->config->rsz.phase_vc, 0, false);
|
||||
rkisp_next_write(dev, hy_offs_mi_reg, scl_w & 15, false);
|
||||
rkisp_next_write(dev, hc_offs_mi_reg, scl_w & 15, false);
|
||||
rkisp_next_write(dev, in_crop_offs_reg,
|
||||
right_scl_in_c << 4 | right_scl_in_y, false);
|
||||
|
||||
rsz_ctrl |= ISP3X_SCL_CLIP_EN;
|
||||
rkisp_next_write(dev, rsz_ctrl_addr,
|
||||
rsz_ctrl | ISP3X_SCL_HPHASE_EN | ISP3X_SCL_IN_CLIP_EN, false);
|
||||
v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev,
|
||||
"scl:%dx%d, scl factor[hy:%d hc:%d vy:%d vc:%d]\n",
|
||||
scl_w, out_y->height, scale_hy, scale_hc, scale_vy, scale_vc);
|
||||
v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev,
|
||||
"scl_left size[y:%d c:%d] phase[y:%d c:%d]\n",
|
||||
left_y, left_c, phase_left_y, phase_left_c);
|
||||
v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev,
|
||||
"scl_right size[y:%d c:%d] offs_mi[y:%d c:%d] in_crop[y:%d c:%d]\n",
|
||||
right_y, right_c, scl_w & 15, scl_w & 15, right_scl_in_y, right_scl_in_c);
|
||||
}
|
||||
rkisp_write(dev, rsz_ctrl_addr, rsz_ctrl, false);
|
||||
}
|
||||
|
||||
@@ -185,6 +291,7 @@ void rkisp_config_rsz(struct rkisp_stream *stream, struct v4l2_rect *in_y,
|
||||
{
|
||||
struct rkisp_device *dev = stream->ispdev;
|
||||
int i = 0;
|
||||
bool is_unite = dev->hw_dev->is_unite;
|
||||
|
||||
/* No phase offset */
|
||||
rkisp_write(dev, stream->config->rsz.phase_hy, 0, true);
|
||||
@@ -194,8 +301,8 @@ void rkisp_config_rsz(struct rkisp_stream *stream, struct v4l2_rect *in_y,
|
||||
|
||||
/* Linear interpolation */
|
||||
for (i = 0; i < 64; i++) {
|
||||
rkisp_write(dev, stream->config->rsz.scale_lut_addr, i, true);
|
||||
rkisp_write(dev, stream->config->rsz.scale_lut, i, true);
|
||||
rkisp_unite_write(dev, stream->config->rsz.scale_lut_addr, i, true, is_unite);
|
||||
rkisp_unite_write(dev, stream->config->rsz.scale_lut, i, true, is_unite);
|
||||
}
|
||||
|
||||
set_scale(stream, in_y, in_c, out_y, out_c);
|
||||
@@ -205,7 +312,9 @@ void rkisp_config_rsz(struct rkisp_stream *stream, struct v4l2_rect *in_y,
|
||||
|
||||
void rkisp_disable_rsz(struct rkisp_stream *stream, bool async)
|
||||
{
|
||||
rkisp_write(stream->ispdev, stream->config->rsz.ctrl, 0, false);
|
||||
bool is_unite = stream->ispdev->hw_dev->is_unite;
|
||||
|
||||
rkisp_unite_write(stream->ispdev, stream->config->rsz.ctrl, 0, false, is_unite);
|
||||
|
||||
if (!async)
|
||||
update_rsz_shadow(stream, async);
|
||||
|
||||
@@ -1735,7 +1735,9 @@ static inline void mi_set_cr_offset(struct rkisp_stream *stream, int val)
|
||||
|
||||
static inline void mi_frame_end_int_enable(struct rkisp_stream *stream)
|
||||
{
|
||||
void __iomem *base = stream->ispdev->base_addr;
|
||||
struct rkisp_hw_dev *hw = stream->ispdev->hw_dev;
|
||||
void __iomem *base = !hw->is_unite ?
|
||||
hw->base_addr : hw->base_next_addr;
|
||||
void __iomem *addr = base + CIF_MI_IMSC;
|
||||
|
||||
writel(CIF_MI_FRAME(stream) | readl(addr), addr);
|
||||
@@ -1743,7 +1745,9 @@ static inline void mi_frame_end_int_enable(struct rkisp_stream *stream)
|
||||
|
||||
static inline void mi_frame_end_int_disable(struct rkisp_stream *stream)
|
||||
{
|
||||
void __iomem *base = stream->ispdev->base_addr;
|
||||
struct rkisp_hw_dev *hw = stream->ispdev->hw_dev;
|
||||
void __iomem *base = !hw->is_unite ?
|
||||
hw->base_addr : hw->base_next_addr;
|
||||
void __iomem *addr = base + CIF_MI_IMSC;
|
||||
|
||||
writel(~CIF_MI_FRAME(stream) & readl(addr), addr);
|
||||
@@ -1751,42 +1755,27 @@ static inline void mi_frame_end_int_disable(struct rkisp_stream *stream)
|
||||
|
||||
static inline void mi_frame_end_int_clear(struct rkisp_stream *stream)
|
||||
{
|
||||
void __iomem *base = stream->ispdev->base_addr;
|
||||
struct rkisp_hw_dev *hw = stream->ispdev->hw_dev;
|
||||
void __iomem *base = !hw->is_unite ?
|
||||
hw->base_addr : hw->base_next_addr;
|
||||
void __iomem *addr = base + CIF_MI_ICR;
|
||||
|
||||
writel(CIF_MI_FRAME(stream), addr);
|
||||
}
|
||||
|
||||
static inline void mp_set_chain_mode(void __iomem *base)
|
||||
static inline void stream_data_path(struct rkisp_stream *stream)
|
||||
{
|
||||
u32 dpcl = readl(base + CIF_VI_DPCL);
|
||||
struct rkisp_device *dev = stream->ispdev;
|
||||
bool is_unite = dev->hw_dev->is_unite;
|
||||
u32 dpcl = 0;
|
||||
|
||||
dpcl |= CIF_VI_DPCL_CHAN_MODE_MP;
|
||||
writel(dpcl, base + CIF_VI_DPCL);
|
||||
}
|
||||
if (stream->id == RKISP_STREAM_MP)
|
||||
dpcl |= CIF_VI_DPCL_CHAN_MODE_MP | CIF_VI_DPCL_MP_MUX_MRSZ_MI;
|
||||
else if (stream->id == RKISP_STREAM_SP)
|
||||
dpcl |= CIF_VI_DPCL_CHAN_MODE_SP;
|
||||
|
||||
static inline void sp_set_chain_mode(void __iomem *base)
|
||||
{
|
||||
u32 dpcl = readl(base + CIF_VI_DPCL);
|
||||
|
||||
dpcl |= CIF_VI_DPCL_CHAN_MODE_SP;
|
||||
writel(dpcl, base + CIF_VI_DPCL);
|
||||
}
|
||||
|
||||
static inline void mp_set_data_path(void __iomem *base)
|
||||
{
|
||||
u32 dpcl = readl(base + CIF_VI_DPCL);
|
||||
|
||||
dpcl = dpcl | CIF_VI_DPCL_CHAN_MODE_MP | CIF_VI_DPCL_MP_MUX_MRSZ_MI;
|
||||
writel(dpcl, base + CIF_VI_DPCL);
|
||||
}
|
||||
|
||||
static inline void sp_set_data_path(void __iomem *base)
|
||||
{
|
||||
u32 dpcl = readl(base + CIF_VI_DPCL);
|
||||
|
||||
dpcl |= CIF_VI_DPCL_CHAN_MODE_SP;
|
||||
writel(dpcl, base + CIF_VI_DPCL);
|
||||
if (dpcl)
|
||||
rkisp_unite_set_bits(dev, CIF_VI_DPCL, 0, dpcl, true, is_unite);
|
||||
}
|
||||
|
||||
static inline void mp_set_uv_swap(void __iomem *base)
|
||||
@@ -1907,13 +1896,13 @@ static inline void sp_mi_ctrl_autoupdate_en(void __iomem *base)
|
||||
|
||||
static inline void force_cfg_update(struct rkisp_device *dev)
|
||||
{
|
||||
void __iomem *base = dev->base_addr;
|
||||
u32 val = readl(base + CIF_MI_CTRL);
|
||||
u32 val = CIF_MI_CTRL_INIT_OFFSET_EN | CIF_MI_CTRL_INIT_BASE_EN;
|
||||
bool is_unite = dev->hw_dev->is_unite;
|
||||
|
||||
dev->hw_dev->is_mi_update = true;
|
||||
val |= CIF_MI_CTRL_INIT_OFFSET_EN | CIF_MI_CTRL_INIT_BASE_EN;
|
||||
writel(val, base + CIF_MI_CTRL);
|
||||
writel(CIF_MI_INIT_SOFT_UPD, base + CIF_MI_INIT);
|
||||
rkisp_unite_set_bits(dev, CIF_MI_CTRL, 0, val, true, is_unite);
|
||||
val = CIF_MI_INIT_SOFT_UPD;
|
||||
rkisp_unite_write(dev, CIF_MI_INIT, val, true, is_unite);
|
||||
}
|
||||
|
||||
static inline void dmatx0_ctrl(void __iomem *base, u32 val)
|
||||
|
||||
@@ -2699,6 +2699,11 @@ static inline void mi_raw_length(struct rkisp_stream *stream)
|
||||
stream->out_fmt.plane_fmt[0].bytesperline, is_direct);
|
||||
if (stream->ispdev->isp_ver == ISP_V21 || stream->ispdev->isp_ver == ISP_V30)
|
||||
rkisp_set_bits(stream->ispdev, MI_RD_CTRL2, 0, BIT(30), false);
|
||||
if (stream->ispdev->hw_dev->is_unite) {
|
||||
rkisp_next_write(stream->ispdev, stream->config->mi.length,
|
||||
stream->out_fmt.plane_fmt[0].bytesperline, is_direct);
|
||||
rkisp_next_set_bits(stream->ispdev, MI_RD_CTRL2, 0, BIT(30), false);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void rx_force_upd(void __iomem *base)
|
||||
|
||||
@@ -1625,6 +1625,11 @@
|
||||
#define ISP3X_GAMMA_OUT_EQU_SEGM BIT(1)
|
||||
#define ISP3X_GAMMA_OUT_FINALX4_DENSE BIT(2)
|
||||
|
||||
/* RESIZE */
|
||||
#define ISP3X_SCL_HPHASE_EN BIT(10)
|
||||
#define ISP3X_SCL_CLIP_EN BIT(11)
|
||||
#define ISP3X_SCL_IN_CLIP_EN BIT(12)
|
||||
|
||||
/* mi interrupt */
|
||||
#define ISP3X_MI_MP_FRAME BIT(0)
|
||||
#define ISP3X_MI_SP_FRAME BIT(1)
|
||||
|
||||
@@ -222,12 +222,12 @@ int rkisp_align_sensor_resolution(struct rkisp_device *dev,
|
||||
CIF_ISP_INPUT_H_MAX_V21);
|
||||
break;
|
||||
case ISP_V30:
|
||||
w = clamp_t(u32, src_w,
|
||||
CIF_ISP_INPUT_W_MIN,
|
||||
CIF_ISP_INPUT_W_MAX_V30);
|
||||
h = clamp_t(u32, src_h,
|
||||
CIF_ISP_INPUT_H_MIN,
|
||||
CIF_ISP_INPUT_H_MAX_V30);
|
||||
w = dev->hw_dev->is_unite ?
|
||||
CIF_ISP_INPUT_W_MAX_V30_UNITE : CIF_ISP_INPUT_W_MAX_V30;
|
||||
w = clamp_t(u32, src_w, CIF_ISP_INPUT_W_MIN, w);
|
||||
h = dev->hw_dev->is_unite ?
|
||||
CIF_ISP_INPUT_H_MAX_V30_UNITE : CIF_ISP_INPUT_H_MAX_V30;
|
||||
h = clamp_t(u32, src_h, CIF_ISP_INPUT_H_MIN, h);
|
||||
break;
|
||||
default:
|
||||
w = clamp_t(u32, src_w,
|
||||
@@ -529,7 +529,7 @@ void rkisp_trigger_read_back(struct rkisp_device *dev, u8 dma2frm, u32 mode, boo
|
||||
|
||||
tmp = rkisp_read(dev, ISP_HDRMGE_BASE, false) & 0xf;
|
||||
if (val != tmp) {
|
||||
rkisp_write(dev, ISP_HDRMGE_BASE, val, false);
|
||||
rkisp_unite_write(dev, ISP_HDRMGE_BASE, val, false, hw->is_unite);
|
||||
dev->skip_frame = 2;
|
||||
is_upd = true;
|
||||
}
|
||||
@@ -645,7 +645,7 @@ void rkisp_trigger_read_back(struct rkisp_device *dev, u8 dma2frm, u32 mode, boo
|
||||
if (!dma2frm)
|
||||
rkisp_bridge_update_mi(dev, 0);
|
||||
if (!hw->is_shutdown)
|
||||
rkisp_write(dev, CSI2RX_CTRL0, val, true);
|
||||
rkisp_unite_write(dev, CSI2RX_CTRL0, val, true, hw->is_unite);
|
||||
}
|
||||
|
||||
static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd)
|
||||
@@ -806,22 +806,26 @@ static void rkisp_set_state(u32 *state, u32 val)
|
||||
static void rkisp_config_ism(struct rkisp_device *dev)
|
||||
{
|
||||
struct v4l2_rect *out_crop = &dev->isp_sdev.out_crop;
|
||||
u32 width = out_crop->width, mult = 1;
|
||||
bool is_unite = dev->hw_dev->is_unite;
|
||||
|
||||
/* isp2.0 no ism */
|
||||
if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21)
|
||||
return;
|
||||
|
||||
rkisp_write(dev, CIF_ISP_IS_RECENTER, 0, false);
|
||||
rkisp_write(dev, CIF_ISP_IS_MAX_DX, 0, false);
|
||||
rkisp_write(dev, CIF_ISP_IS_MAX_DY, 0, false);
|
||||
rkisp_write(dev, CIF_ISP_IS_DISPLACE, 0, false);
|
||||
rkisp_write(dev, CIF_ISP_IS_H_OFFS, out_crop->left, false);
|
||||
rkisp_write(dev, CIF_ISP_IS_V_OFFS, out_crop->top, false);
|
||||
rkisp_write(dev, CIF_ISP_IS_H_SIZE, out_crop->width, false);
|
||||
if (is_unite)
|
||||
width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL;
|
||||
rkisp_unite_write(dev, CIF_ISP_IS_RECENTER, 0, false, is_unite);
|
||||
rkisp_unite_write(dev, CIF_ISP_IS_MAX_DX, 0, false, is_unite);
|
||||
rkisp_unite_write(dev, CIF_ISP_IS_MAX_DY, 0, false, is_unite);
|
||||
rkisp_unite_write(dev, CIF_ISP_IS_DISPLACE, 0, false, is_unite);
|
||||
rkisp_unite_write(dev, CIF_ISP_IS_H_OFFS, out_crop->left, false, is_unite);
|
||||
rkisp_unite_write(dev, CIF_ISP_IS_V_OFFS, out_crop->top, false, is_unite);
|
||||
rkisp_unite_write(dev, CIF_ISP_IS_H_SIZE, width, false, is_unite);
|
||||
if (dev->cap_dev.stream[RKISP_STREAM_SP].interlaced)
|
||||
rkisp_write(dev, CIF_ISP_IS_V_SIZE, out_crop->height / 2, false);
|
||||
else
|
||||
rkisp_write(dev, CIF_ISP_IS_V_SIZE, out_crop->height, false);
|
||||
mult = 2;
|
||||
rkisp_unite_write(dev, CIF_ISP_IS_V_SIZE, out_crop->height / mult,
|
||||
false, is_unite);
|
||||
|
||||
if (dev->isp_ver == ISP_V30)
|
||||
return;
|
||||
@@ -1116,22 +1120,188 @@ static void rkisp_config_color_space(struct rkisp_device *dev)
|
||||
}
|
||||
|
||||
for (i = 0; i < 9; i++)
|
||||
rkisp_write(dev, CIF_ISP_CC_COEFF_0 + i * 4, *(coeff + i), false);
|
||||
rkisp_unite_write(dev, CIF_ISP_CC_COEFF_0 + i * 4,
|
||||
*(coeff + i), false, dev->hw_dev->is_unite);
|
||||
|
||||
if (dev->isp_sdev.quantization == V4L2_QUANTIZATION_FULL_RANGE)
|
||||
rkisp_set_bits(dev, CIF_ISP_CTRL, 0,
|
||||
CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA |
|
||||
CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA, false);
|
||||
rkisp_unite_set_bits(dev, CIF_ISP_CTRL, 0,
|
||||
CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA |
|
||||
CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA,
|
||||
false, dev->hw_dev->is_unite);
|
||||
else
|
||||
rkisp_clear_bits(dev, CIF_ISP_CTRL,
|
||||
CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA |
|
||||
CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA, false);
|
||||
rkisp_unite_clear_bits(dev, CIF_ISP_CTRL,
|
||||
CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA |
|
||||
CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA,
|
||||
false, dev->hw_dev->is_unite);
|
||||
}
|
||||
|
||||
static void rkisp_config_cmsk_single(struct rkisp_device *dev,
|
||||
struct rkisp_cmsk_cfg *cfg)
|
||||
{
|
||||
u32 i, val, ctrl = 0;
|
||||
u32 mp_en = cfg->win[0].win_en;
|
||||
u32 sp_en = cfg->win[1].win_en;
|
||||
u32 bp_en = cfg->win[2].win_en;
|
||||
|
||||
if (mp_en) {
|
||||
ctrl |= ISP3X_SW_CMSK_EN_MP;
|
||||
rkisp_write(dev, ISP3X_CMSK_CTRL1, mp_en, false);
|
||||
val = cfg->win[0].mode;
|
||||
rkisp_write(dev, ISP3X_CMSK_CTRL4, val, false);
|
||||
}
|
||||
|
||||
if (sp_en) {
|
||||
ctrl |= ISP3X_SW_CMSK_EN_SP;
|
||||
rkisp_write(dev, ISP3X_CMSK_CTRL2, sp_en, false);
|
||||
val = cfg->win[1].mode;
|
||||
rkisp_write(dev, ISP3X_CMSK_CTRL5, val, false);
|
||||
}
|
||||
|
||||
if (bp_en) {
|
||||
ctrl |= ISP3X_SW_CMSK_EN_BP;
|
||||
rkisp_write(dev, ISP3X_CMSK_CTRL3, bp_en, false);
|
||||
val = cfg->win[2].mode;
|
||||
rkisp_write(dev, ISP3X_CMSK_CTRL6, val, false);
|
||||
}
|
||||
|
||||
for (i = 0; i < RKISP_CMSK_WIN_MAX; i++) {
|
||||
if (!(mp_en & BIT(i)) && !(sp_en & BIT(i)) && !(bp_en & BIT(i)))
|
||||
continue;
|
||||
|
||||
val = ISP3X_SW_CMSK_YUV(cfg->win[i].cover_color_y,
|
||||
cfg->win[i].cover_color_u,
|
||||
cfg->win[i].cover_color_v);
|
||||
rkisp_write(dev, ISP3X_CMSK_YUV0 + i * 4, val, false);
|
||||
|
||||
val = ISP_PACK_2SHORT(cfg->win[i].h_offs, cfg->win[i].v_offs);
|
||||
rkisp_write(dev, ISP3X_CMSK_OFFS0 + i * 8, val, false);
|
||||
|
||||
val = ISP_PACK_2SHORT(cfg->win[i].h_size, cfg->win[i].v_size);
|
||||
rkisp_write(dev, ISP3X_CMSK_SIZE0 + i * 8, val, false);
|
||||
}
|
||||
|
||||
if (ctrl) {
|
||||
val = ISP_PACK_2SHORT(dev->isp_sdev.out_crop.width,
|
||||
dev->isp_sdev.out_crop.height);
|
||||
rkisp_write(dev, ISP3X_CMSK_PIC_SIZE, val, false);
|
||||
ctrl |= ISP3X_SW_CMSK_EN | ISP3X_SW_CMSK_ORDER_MODE;
|
||||
}
|
||||
rkisp_write(dev, ISP3X_CMSK_CTRL0, ctrl, false);
|
||||
}
|
||||
|
||||
static void rkisp_config_cmsk_dual(struct rkisp_device *dev,
|
||||
struct rkisp_cmsk_cfg *cfg)
|
||||
{
|
||||
struct rkisp_cmsk_cfg left = *cfg;
|
||||
struct rkisp_cmsk_cfg right = *cfg;
|
||||
u32 width = dev->isp_sdev.out_crop.width;
|
||||
u32 height = dev->isp_sdev.out_crop.height;
|
||||
u32 w = width / 2;
|
||||
u32 i, val, h_offs, h_size, ctrl;
|
||||
u8 mp_en = cfg->win[0].win_en;
|
||||
u8 sp_en = cfg->win[1].win_en;
|
||||
u8 bp_en = cfg->win[2].win_en;
|
||||
|
||||
for (i = 0; i < RKISP_CMSK_WIN_MAX; i++) {
|
||||
if (!(mp_en & BIT(i)) && !(sp_en & BIT(i)) && !(bp_en & BIT(i)))
|
||||
continue;
|
||||
|
||||
h_offs = cfg->win[i].h_offs;
|
||||
h_size = cfg->win[i].h_size;
|
||||
if (h_offs + h_size <= w) {
|
||||
/* cmsk window at left isp */
|
||||
right.win[0].win_en &= ~BIT(i);
|
||||
right.win[1].win_en &= ~BIT(i);
|
||||
right.win[2].win_en &= ~BIT(i);
|
||||
} else if (h_offs >= w) {
|
||||
/* cmsk window at right isp */
|
||||
left.win[0].win_en &= ~BIT(i);
|
||||
left.win[1].win_en &= ~BIT(i);
|
||||
left.win[2].win_en &= ~BIT(i);
|
||||
} else {
|
||||
/* cmsk window at dual isp */
|
||||
left.win[i].h_size = ALIGN(w - h_offs, 8);
|
||||
|
||||
right.win[i].h_offs = RKMOUDLE_UNITE_EXTEND_PIXEL;
|
||||
val = h_offs + h_size - w;
|
||||
right.win[i].h_size = ALIGN(val, 8);
|
||||
right.win[i].h_offs -= right.win[i].h_size - val;
|
||||
}
|
||||
|
||||
val = ISP3X_SW_CMSK_YUV(left.win[i].cover_color_y,
|
||||
left.win[i].cover_color_u,
|
||||
left.win[i].cover_color_v);
|
||||
rkisp_write(dev, ISP3X_CMSK_YUV0 + i * 4, val, false);
|
||||
rkisp_next_write(dev, ISP3X_CMSK_YUV0 + i * 4, val, false);
|
||||
|
||||
val = ISP_PACK_2SHORT(left.win[i].h_offs, left.win[i].v_offs);
|
||||
rkisp_write(dev, ISP3X_CMSK_OFFS0 + i * 8, val, false);
|
||||
val = ISP_PACK_2SHORT(left.win[i].h_size, left.win[i].v_size);
|
||||
rkisp_write(dev, ISP3X_CMSK_SIZE0 + i * 8, val, false);
|
||||
|
||||
val = ISP_PACK_2SHORT(right.win[i].h_offs, right.win[i].v_offs);
|
||||
rkisp_next_write(dev, ISP3X_CMSK_OFFS0 + i * 8, val, false);
|
||||
val = ISP_PACK_2SHORT(right.win[i].h_size, right.win[i].v_size);
|
||||
rkisp_next_write(dev, ISP3X_CMSK_SIZE0 + i * 8, val, false);
|
||||
}
|
||||
|
||||
w += RKMOUDLE_UNITE_EXTEND_PIXEL;
|
||||
ctrl = 0;
|
||||
if (left.win[0].win_en) {
|
||||
ctrl |= ISP3X_SW_CMSK_EN_MP;
|
||||
rkisp_write(dev, ISP3X_CMSK_CTRL1, left.win[0].win_en, false);
|
||||
val = left.win[0].mode;
|
||||
rkisp_write(dev, ISP3X_CMSK_CTRL4, val, false);
|
||||
}
|
||||
if (left.win[1].win_en) {
|
||||
ctrl |= ISP3X_SW_CMSK_EN_SP;
|
||||
rkisp_write(dev, ISP3X_CMSK_CTRL2, left.win[1].win_en, false);
|
||||
val = left.win[1].mode;
|
||||
rkisp_write(dev, ISP3X_CMSK_CTRL5, val, false);
|
||||
}
|
||||
if (left.win[2].win_en) {
|
||||
ctrl |= ISP3X_SW_CMSK_EN_BP;
|
||||
rkisp_write(dev, ISP3X_CMSK_CTRL3, left.win[2].win_en, false);
|
||||
val = left.win[2].mode;
|
||||
rkisp_write(dev, ISP3X_CMSK_CTRL6, val, false);
|
||||
}
|
||||
if (ctrl) {
|
||||
val = ISP_PACK_2SHORT(w, height);
|
||||
rkisp_write(dev, ISP3X_CMSK_PIC_SIZE, val, false);
|
||||
ctrl |= ISP3X_SW_CMSK_EN | ISP3X_SW_CMSK_ORDER_MODE;
|
||||
}
|
||||
rkisp_write(dev, ISP3X_CMSK_CTRL0, ctrl, false);
|
||||
|
||||
ctrl = 0;
|
||||
if (right.win[0].win_en) {
|
||||
ctrl |= ISP3X_SW_CMSK_EN_MP;
|
||||
rkisp_next_write(dev, ISP3X_CMSK_CTRL1, right.win[0].win_en, false);
|
||||
val = right.win[0].mode;
|
||||
rkisp_next_write(dev, ISP3X_CMSK_CTRL4, val, false);
|
||||
}
|
||||
if (right.win[1].win_en) {
|
||||
ctrl |= ISP3X_SW_CMSK_EN_SP;
|
||||
rkisp_next_write(dev, ISP3X_CMSK_CTRL2, right.win[1].win_en, false);
|
||||
val = right.win[1].mode;
|
||||
rkisp_next_write(dev, ISP3X_CMSK_CTRL5, val, false);
|
||||
}
|
||||
if (right.win[2].win_en) {
|
||||
ctrl |= ISP3X_SW_CMSK_EN_BP;
|
||||
rkisp_next_write(dev, ISP3X_CMSK_CTRL3, right.win[2].win_en, false);
|
||||
val = right.win[2].mode;
|
||||
rkisp_next_write(dev, ISP3X_CMSK_CTRL6, val, false);
|
||||
}
|
||||
if (ctrl) {
|
||||
val = ISP_PACK_2SHORT(w, height);
|
||||
rkisp_next_write(dev, ISP3X_CMSK_PIC_SIZE, val, false);
|
||||
ctrl |= ISP3X_SW_CMSK_EN | ISP3X_SW_CMSK_ORDER_MODE;
|
||||
}
|
||||
rkisp_next_write(dev, ISP3X_CMSK_CTRL0, ctrl, false);
|
||||
}
|
||||
|
||||
static void rkisp_config_cmsk(struct rkisp_device *dev)
|
||||
{
|
||||
unsigned long lock_flags = 0;
|
||||
u32 i, val, mp_en, sp_en, bp_en, ctrl = 0;
|
||||
struct rkisp_cmsk_cfg cfg;
|
||||
|
||||
if (dev->isp_ver != ISP_V30)
|
||||
@@ -1146,53 +1316,10 @@ static void rkisp_config_cmsk(struct rkisp_device *dev)
|
||||
cfg = dev->cmsk_cfg;
|
||||
spin_unlock_irqrestore(&dev->cmsk_lock, lock_flags);
|
||||
|
||||
mp_en = cfg.win[0].win_en;
|
||||
if (mp_en) {
|
||||
ctrl |= ISP3X_SW_CMSK_EN_MP;
|
||||
rkisp_write(dev, ISP3X_CMSK_CTRL1, mp_en, false);
|
||||
val = cfg.win[0].mode;
|
||||
rkisp_write(dev, ISP3X_CMSK_CTRL4, val, false);
|
||||
}
|
||||
|
||||
sp_en = cfg.win[1].win_en;
|
||||
if (sp_en) {
|
||||
ctrl |= ISP3X_SW_CMSK_EN_SP;
|
||||
rkisp_write(dev, ISP3X_CMSK_CTRL2, sp_en, false);
|
||||
val = cfg.win[1].mode;
|
||||
rkisp_write(dev, ISP3X_CMSK_CTRL5, val, false);
|
||||
}
|
||||
|
||||
bp_en = cfg.win[2].win_en;
|
||||
if (bp_en) {
|
||||
ctrl |= ISP3X_SW_CMSK_EN_BP;
|
||||
rkisp_write(dev, ISP3X_CMSK_CTRL3, bp_en, false);
|
||||
val = cfg.win[2].mode;
|
||||
rkisp_write(dev, ISP3X_CMSK_CTRL6, val, false);
|
||||
}
|
||||
|
||||
for (i = 0; i < RKISP_CMSK_WIN_MAX; i++) {
|
||||
if (!(mp_en & BIT(i)) && !(sp_en & BIT(i)) && !(bp_en & BIT(i)))
|
||||
continue;
|
||||
|
||||
val = ISP3X_SW_CMSK_YUV(cfg.win[i].cover_color_y,
|
||||
cfg.win[i].cover_color_u,
|
||||
cfg.win[i].cover_color_v);
|
||||
rkisp_write(dev, ISP3X_CMSK_YUV0 + i * 4, val, false);
|
||||
|
||||
val = ISP_PACK_2SHORT(cfg.win[i].h_offs, cfg.win[i].v_offs);
|
||||
rkisp_write(dev, ISP3X_CMSK_OFFS0 + i * 8, val, false);
|
||||
|
||||
val = ISP_PACK_2SHORT(cfg.win[i].h_size, cfg.win[i].v_size);
|
||||
rkisp_write(dev, ISP3X_CMSK_SIZE0 + i * 8, val, false);
|
||||
}
|
||||
|
||||
if (ctrl) {
|
||||
val = ISP_PACK_2SHORT(dev->isp_sdev.out_crop.width,
|
||||
dev->isp_sdev.out_crop.height);
|
||||
rkisp_write(dev, ISP3X_CMSK_PIC_SIZE, val, false);
|
||||
ctrl |= ISP3X_SW_CMSK_EN | ISP3X_SW_CMSK_ORDER_MODE;
|
||||
}
|
||||
rkisp_write(dev, ISP3X_CMSK_CTRL0, ctrl, false);
|
||||
if (!dev->hw_dev->is_unite)
|
||||
rkisp_config_cmsk_single(dev, &cfg);
|
||||
else
|
||||
rkisp_config_cmsk_dual(dev, &cfg);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1204,17 +1331,20 @@ static int rkisp_config_isp(struct rkisp_device *dev)
|
||||
struct ispsd_out_fmt *out_fmt;
|
||||
struct v4l2_rect *in_crop;
|
||||
struct rkisp_sensor_info *sensor;
|
||||
bool is_unite = dev->hw_dev->is_unite;
|
||||
u32 isp_ctrl = 0;
|
||||
u32 irq_mask = 0;
|
||||
u32 signal = 0;
|
||||
u32 acq_mult = 0;
|
||||
u32 acq_prop = 0;
|
||||
u32 extend_line = 0;
|
||||
u32 width;
|
||||
|
||||
sensor = dev->active_sensor;
|
||||
in_fmt = &dev->isp_sdev.in_fmt;
|
||||
out_fmt = &dev->isp_sdev.out_fmt;
|
||||
in_crop = &dev->isp_sdev.in_crop;
|
||||
width = in_crop->width;
|
||||
|
||||
if (in_fmt->fmt_type == FMT_BAYER) {
|
||||
acq_mult = 1;
|
||||
@@ -1233,7 +1363,8 @@ static int rkisp_config_isp(struct rkisp_device *dev)
|
||||
if (dev->isp_ver == ISP_V20 ||
|
||||
dev->isp_ver == ISP_V21 ||
|
||||
dev->isp_ver == ISP_V30)
|
||||
rkisp_write(dev, ISP_DEBAYER_CONTROL, 0, false);
|
||||
rkisp_unite_write(dev, ISP_DEBAYER_CONTROL,
|
||||
0, false, is_unite);
|
||||
else
|
||||
rkisp_write(dev, CIF_ISP_DEMOSAIC,
|
||||
CIF_ISP_DEMOSAIC_BYPASS |
|
||||
@@ -1242,10 +1373,11 @@ static int rkisp_config_isp(struct rkisp_device *dev)
|
||||
if (dev->isp_ver == ISP_V20 ||
|
||||
dev->isp_ver == ISP_V21 ||
|
||||
dev->isp_ver == ISP_V30)
|
||||
rkisp_write(dev, ISP_DEBAYER_CONTROL,
|
||||
SW_DEBAYER_EN |
|
||||
SW_DEBAYER_FILTER_G_EN |
|
||||
SW_DEBAYER_FILTER_C_EN, false);
|
||||
rkisp_unite_write(dev, ISP_DEBAYER_CONTROL,
|
||||
SW_DEBAYER_EN |
|
||||
SW_DEBAYER_FILTER_G_EN |
|
||||
SW_DEBAYER_FILTER_C_EN,
|
||||
false, is_unite);
|
||||
else
|
||||
rkisp_write(dev, CIF_ISP_DEMOSAIC,
|
||||
CIF_ISP_DEMOSAIC_TH(0xc), false);
|
||||
@@ -1298,29 +1430,38 @@ static int rkisp_config_isp(struct rkisp_device *dev)
|
||||
signal |= CIF_ISP_ACQ_PROP_HSYNC_LOW;
|
||||
}
|
||||
|
||||
rkisp_write(dev, CIF_ISP_CTRL, isp_ctrl, false);
|
||||
rkisp_unite_write(dev, CIF_ISP_CTRL, isp_ctrl, false, is_unite);
|
||||
acq_prop |= signal | in_fmt->yuv_seq |
|
||||
CIF_ISP_ACQ_PROP_BAYER_PAT(in_fmt->bayer_pat) |
|
||||
CIF_ISP_ACQ_PROP_FIELD_SEL_ALL;
|
||||
rkisp_write(dev, CIF_ISP_ACQ_PROP, acq_prop, false);
|
||||
rkisp_write(dev, CIF_ISP_ACQ_NR_FRAMES, 0, true);
|
||||
rkisp_unite_write(dev, CIF_ISP_ACQ_PROP, acq_prop, false, is_unite);
|
||||
rkisp_unite_write(dev, CIF_ISP_ACQ_NR_FRAMES, 0, true, is_unite);
|
||||
|
||||
if (is_unite)
|
||||
width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL;
|
||||
/* Acquisition Size */
|
||||
rkisp_write(dev, CIF_ISP_ACQ_H_OFFS, acq_mult * in_crop->left, false);
|
||||
rkisp_write(dev, CIF_ISP_ACQ_V_OFFS, in_crop->top, false);
|
||||
rkisp_write(dev, CIF_ISP_ACQ_H_SIZE, acq_mult * in_crop->width, false);
|
||||
rkisp_unite_write(dev, CIF_ISP_ACQ_H_OFFS, acq_mult * in_crop->left,
|
||||
false, is_unite);
|
||||
rkisp_unite_write(dev, CIF_ISP_ACQ_V_OFFS, in_crop->top,
|
||||
false, is_unite);
|
||||
rkisp_unite_write(dev, CIF_ISP_ACQ_H_SIZE, acq_mult * width,
|
||||
false, is_unite);
|
||||
|
||||
/* ISP Out Area differ with ACQ is only FIFO, so don't crop in this */
|
||||
rkisp_write(dev, CIF_ISP_OUT_H_OFFS, 0, true);
|
||||
rkisp_write(dev, CIF_ISP_OUT_V_OFFS, 0, true);
|
||||
rkisp_write(dev, CIF_ISP_OUT_H_SIZE, in_crop->width, false);
|
||||
rkisp_unite_write(dev, CIF_ISP_OUT_H_OFFS, 0, true, is_unite);
|
||||
rkisp_unite_write(dev, CIF_ISP_OUT_V_OFFS, 0, true, is_unite);
|
||||
rkisp_unite_write(dev, CIF_ISP_OUT_H_SIZE, width, false, is_unite);
|
||||
|
||||
if (dev->cap_dev.stream[RKISP_STREAM_SP].interlaced) {
|
||||
rkisp_write(dev, CIF_ISP_ACQ_V_SIZE, in_crop->height / 2, false);
|
||||
rkisp_write(dev, CIF_ISP_OUT_V_SIZE, in_crop->height / 2, false);
|
||||
rkisp_unite_write(dev, CIF_ISP_ACQ_V_SIZE, in_crop->height / 2,
|
||||
false, is_unite);
|
||||
rkisp_unite_write(dev, CIF_ISP_OUT_V_SIZE, in_crop->height / 2,
|
||||
false, is_unite);
|
||||
} else {
|
||||
rkisp_write(dev, CIF_ISP_ACQ_V_SIZE, in_crop->height + extend_line, false);
|
||||
rkisp_write(dev, CIF_ISP_OUT_V_SIZE, in_crop->height + extend_line, false);
|
||||
rkisp_unite_write(dev, CIF_ISP_ACQ_V_SIZE, in_crop->height + extend_line,
|
||||
false, is_unite);
|
||||
rkisp_unite_write(dev, CIF_ISP_OUT_V_SIZE, in_crop->height + extend_line,
|
||||
false, is_unite);
|
||||
}
|
||||
|
||||
/* interrupt mask */
|
||||
@@ -1330,7 +1471,10 @@ static int rkisp_config_isp(struct rkisp_device *dev)
|
||||
dev->isp_ver == ISP_V21 ||
|
||||
dev->isp_ver == ISP_V30)
|
||||
irq_mask |= ISP2X_LSC_LUT_ERR;
|
||||
rkisp_write(dev, CIF_ISP_IMSC, irq_mask, true);
|
||||
if (is_unite)
|
||||
rkisp_next_write(dev, CIF_ISP_IMSC, irq_mask, true);
|
||||
else
|
||||
rkisp_write(dev, CIF_ISP_IMSC, irq_mask, true);
|
||||
|
||||
if ((dev->isp_ver == ISP_V20 ||
|
||||
dev->isp_ver == ISP_V21) &&
|
||||
@@ -1455,9 +1599,9 @@ err:
|
||||
/* Configure MUX */
|
||||
static int rkisp_config_path(struct rkisp_device *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
struct rkisp_sensor_info *sensor = dev->active_sensor;
|
||||
u32 dpcl = readl(dev->base_addr + CIF_VI_DPCL);
|
||||
int ret = 0;
|
||||
u32 dpcl = 0;
|
||||
|
||||
/* isp input interface selects */
|
||||
if ((sensor && sensor->mbus.type == V4L2_MBUS_CSI2_DPHY) ||
|
||||
@@ -1482,8 +1626,8 @@ static int rkisp_config_path(struct rkisp_device *dev)
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
writel(dpcl, dev->base_addr + CIF_VI_DPCL);
|
||||
|
||||
rkisp_unite_set_bits(dev, CIF_VI_DPCL, 0, dpcl, true,
|
||||
dev->hw_dev->is_unite);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1572,6 +1716,7 @@ static void rkisp_stop_3a_run(struct rkisp_device *dev)
|
||||
/* Mess register operations to stop isp */
|
||||
static int rkisp_isp_stop(struct rkisp_device *dev)
|
||||
{
|
||||
struct rkisp_hw_dev *hw = dev->hw_dev;
|
||||
void __iomem *base = dev->base_addr;
|
||||
unsigned long old_rate, safe_rate;
|
||||
u32 val;
|
||||
@@ -1650,6 +1795,9 @@ static int rkisp_isp_stop(struct rkisp_device *dev)
|
||||
|
||||
val = readl(base + CIF_ISP_CTRL);
|
||||
writel(val | CIF_ISP_CTRL_ISP_CFG_UPD, base + CIF_ISP_CTRL);
|
||||
if (hw->is_unite)
|
||||
rkisp_next_write(dev, CIF_ISP_CTRL,
|
||||
val | CIF_ISP_CTRL_ISP_CFG_UPD, true);
|
||||
|
||||
readx_poll_timeout_atomic(readl, base + CIF_ISP_RIS,
|
||||
val, val & CIF_ISP_OFF, 20, 100);
|
||||
@@ -1661,10 +1809,12 @@ static int rkisp_isp_stop(struct rkisp_device *dev)
|
||||
if (!in_interrupt()) {
|
||||
/* normal case */
|
||||
/* check the isp_clk before isp reset operation */
|
||||
old_rate = clk_get_rate(dev->hw_dev->clks[0]);
|
||||
safe_rate = dev->hw_dev->clk_rate_tbl[0].clk_rate * 1000000UL;
|
||||
old_rate = clk_get_rate(hw->clks[0]);
|
||||
safe_rate = hw->clk_rate_tbl[0].clk_rate * 1000000UL;
|
||||
if (old_rate > safe_rate) {
|
||||
rkisp_set_clk_rate(dev->hw_dev->clks[0], safe_rate);
|
||||
rkisp_set_clk_rate(hw->clks[0], safe_rate);
|
||||
if (hw->is_unite)
|
||||
rkisp_set_clk_rate(hw->clks[5], safe_rate);
|
||||
udelay(100);
|
||||
}
|
||||
rkisp_soft_reset(dev->hw_dev, false);
|
||||
@@ -1681,6 +1831,8 @@ static int rkisp_isp_stop(struct rkisp_device *dev)
|
||||
dev->isp_ver == ISP_V21 ||
|
||||
dev->isp_ver == ISP_V30) {
|
||||
writel(0, base + CSI2RX_CSI2_RESETN);
|
||||
if (hw->is_unite)
|
||||
rkisp_next_write(dev, CSI2RX_CSI2_RESETN, 0, true);
|
||||
}
|
||||
|
||||
dev->hw_dev->is_idle = true;
|
||||
@@ -1713,8 +1865,8 @@ static int rkisp_isp_start(struct rkisp_device *dev)
|
||||
{
|
||||
struct rkisp_sensor_info *sensor = dev->active_sensor;
|
||||
void __iomem *base = dev->base_addr;
|
||||
u32 val;
|
||||
bool is_direct = true;
|
||||
u32 val;
|
||||
|
||||
v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev,
|
||||
"%s refcnt:%d\n", __func__,
|
||||
@@ -1743,7 +1895,7 @@ static int rkisp_isp_start(struct rkisp_device *dev)
|
||||
val |= NOC_HURRY_PRIORITY(2) | NOC_HURRY_W_MODE(2) | NOC_HURRY_R_MODE(1);
|
||||
if (atomic_read(&dev->hw_dev->refcnt) > 1)
|
||||
is_direct = false;
|
||||
rkisp_write(dev, CIF_ISP_CTRL, val, is_direct);
|
||||
rkisp_unite_write(dev, CIF_ISP_CTRL, val, is_direct, dev->hw_dev->is_unite);
|
||||
|
||||
dev->isp_err_cnt = 0;
|
||||
dev->isp_isr_cnt = 0;
|
||||
@@ -2223,8 +2375,10 @@ static int rkisp_isp_sd_get_selection(struct v4l2_subdev *sd,
|
||||
max_h = CIF_ISP_INPUT_H_MAX_V21;
|
||||
break;
|
||||
case ISP_V30:
|
||||
max_w = CIF_ISP_INPUT_W_MAX_V30;
|
||||
max_h = CIF_ISP_INPUT_H_MAX_V30;
|
||||
max_w = dev->hw_dev->is_unite ?
|
||||
CIF_ISP_INPUT_W_MAX_V30_UNITE : CIF_ISP_INPUT_W_MAX_V30;
|
||||
max_h = dev->hw_dev->is_unite ?
|
||||
CIF_ISP_INPUT_H_MAX_V30_UNITE : CIF_ISP_INPUT_H_MAX_V30;
|
||||
break;
|
||||
default:
|
||||
max_w = CIF_ISP_INPUT_W_MAX;
|
||||
@@ -2427,6 +2581,7 @@ static int rkisp_rx_buf_pool_init(struct rkisp_device *dev,
|
||||
struct sg_table *sg_tbl;
|
||||
int i, ret;
|
||||
void *mem;
|
||||
u32 val;
|
||||
|
||||
for (i = 0; i < RKISP_RX_BUF_POOL_MAX; i++) {
|
||||
pool = &dev->pv_pool[i];
|
||||
@@ -2471,7 +2626,13 @@ static int rkisp_rx_buf_pool_init(struct rkisp_device *dev,
|
||||
|
||||
}
|
||||
stream->ops->config_mi(stream);
|
||||
rkisp_write(dev, stream->config->mi.y_base_ad_init, pool->dma, false);
|
||||
val = pool->dma;
|
||||
rkisp_write(dev, stream->config->mi.y_base_ad_init, val, false);
|
||||
if (dev->hw_dev->is_unite) {
|
||||
val += (stream->out_fmt.width / 2 - RKMOUDLE_UNITE_EXTEND_PIXEL) *
|
||||
stream->out_isp_fmt.bpp[0] / 8;
|
||||
rkisp_next_write(dev, stream->config->mi.y_base_ad_init, val, false);
|
||||
}
|
||||
v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev,
|
||||
"%s dma:0x%x vaddr:%p", __func__, (u32)pool->dma, pool->vaddr);
|
||||
return 0;
|
||||
@@ -3198,7 +3359,9 @@ void rkisp_isp_isr(unsigned int isp_mis,
|
||||
unsigned int isp3a_mis,
|
||||
struct rkisp_device *dev)
|
||||
{
|
||||
void __iomem *base = dev->base_addr;
|
||||
struct rkisp_hw_dev *hw = dev->hw_dev;
|
||||
void __iomem *base = !hw->is_unite ?
|
||||
hw->base_addr : hw->base_next_addr;
|
||||
unsigned int isp_mis_tmp = 0;
|
||||
unsigned int isp_err = 0;
|
||||
u32 si3a_isr_mask = ISP2X_SIAWB_DONE | ISP2X_SIAF_FIN |
|
||||
@@ -3218,6 +3381,15 @@ void rkisp_isp_isr(unsigned int isp_mis,
|
||||
if (isp3a_mis & ISP2X_3A_RAWAE_BIG && dev->params_vdev.rdbk_times > 0)
|
||||
writel(BIT(31), base + RAWAE_BIG1_BASE + RAWAE_BIG_CTRL);
|
||||
|
||||
if (hw->is_unite) {
|
||||
u32 val = rkisp_read(dev, ISP3X_ISP_RIS, true);
|
||||
|
||||
if (val) {
|
||||
rkisp_write(dev, ISP3X_ISP_ICR, val, true);
|
||||
v4l2_dbg(3, rkisp_debug, &dev->v4l2_dev,
|
||||
"left isp isr:0x%x\n", val);
|
||||
}
|
||||
}
|
||||
v4l2_dbg(3, rkisp_debug, &dev->v4l2_dev,
|
||||
"isp isr:0x%x, 0x%x\n", isp_mis, isp3a_mis);
|
||||
dev->isp_isr_cnt++;
|
||||
|
||||
@@ -53,6 +53,8 @@
|
||||
#define CIF_ISP_INPUT_H_MAX_V21 3072
|
||||
#define CIF_ISP_INPUT_W_MAX_V30 4672
|
||||
#define CIF_ISP_INPUT_H_MAX_V30 3504
|
||||
#define CIF_ISP_INPUT_W_MAX_V30_UNITE 8192
|
||||
#define CIF_ISP_INPUT_H_MAX_V30_UNITE 6144
|
||||
#define CIF_ISP_INPUT_W_MIN 208
|
||||
#define CIF_ISP_INPUT_H_MIN 128
|
||||
#define CIF_ISP_OUTPUT_W_MAX CIF_ISP_INPUT_W_MAX
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
|
||||
#define RKMODULE_API_VERSION KERNEL_VERSION(0, 1, 0x2)
|
||||
|
||||
/* using for rk3588 dual isp unite */
|
||||
#define RKMOUDLE_UNITE_EXTEND_PIXEL 128
|
||||
/* using for rv1109 and rv1126 */
|
||||
#define RKMODULE_EXTEND_LINE 24
|
||||
|
||||
|
||||
Reference in New Issue
Block a user