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:
Cai YiWei
2021-07-05 09:10:36 +08:00
committed by Tao Huang
parent 7faaa53254
commit da2794bb29
20 changed files with 788 additions and 274 deletions

View File

@@ -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,

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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));

View File

@@ -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,

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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++;

View File

@@ -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

View File

@@ -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