media: rockchip: isp: add bt601/bt709/bt2020 colorspace

rkisp-isp-subdev pad2 to change colorspace and quantization

Change-Id: I077eb9482cd09119c11f2515e848dca203c42357
Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
Cai YiWei
2021-04-29 14:52:44 +08:00
committed by Tao Huang
parent f0d532ee66
commit 975b743484
5 changed files with 96 additions and 51 deletions

View File

@@ -2214,12 +2214,6 @@ static void rkisp1_params_first_cfg_v1x(struct rkisp_isp_params_vdev *params_vde
hst_params_default_config.mode);
}
/* set the range */
if (params_vdev->quantization == V4L2_QUANTIZATION_FULL_RANGE)
ops->csm_config(params_vdev, true);
else
ops->csm_config(params_vdev, false);
/* disable color related config for grey sensor */
if (params_vdev->in_mbus_code == MEDIA_BUS_FMT_Y8_1X8 ||
params_vdev->in_mbus_code == MEDIA_BUS_FMT_Y10_1X10 ||

View File

@@ -3906,8 +3906,6 @@ static void
rkisp_params_first_cfg_v2x(struct rkisp_isp_params_vdev *params_vdev)
{
struct device *dev = params_vdev->dev->dev;
struct rkisp_isp_params_v21_ops *ops =
(struct rkisp_isp_params_v21_ops *)params_vdev->priv_ops;
struct rkisp_isp_params_val_v21 *priv_val =
(struct rkisp_isp_params_val_v21 *)params_vdev->priv_val;
struct rkisp_hw_dev *hw = params_vdev->dev->hw_dev;
@@ -3922,12 +3920,6 @@ rkisp_params_first_cfg_v2x(struct rkisp_isp_params_vdev *params_vdev)
!params_vdev->isp21_params->module_en_update)
dev_warn(dev, "can not get first iq setting in stream on\n");
/* set the range */
if (params_vdev->quantization == V4L2_QUANTIZATION_FULL_RANGE)
ops->csm_config(params_vdev, true);
else
ops->csm_config(params_vdev, false);
priv_val->dhaz_en = 0;
priv_val->wdr_en = 0;
priv_val->tmo_en = 0;

View File

@@ -4230,8 +4230,6 @@ static void
rkisp_params_first_cfg_v2x(struct rkisp_isp_params_vdev *params_vdev)
{
struct device *dev = params_vdev->dev->dev;
struct rkisp_isp_params_v2x_ops *ops =
(struct rkisp_isp_params_v2x_ops *)params_vdev->priv_ops;
struct rkisp_isp_params_val_v2x *priv_val =
(struct rkisp_isp_params_val_v2x *)params_vdev->priv_val;
@@ -4241,12 +4239,6 @@ rkisp_params_first_cfg_v2x(struct rkisp_isp_params_vdev *params_vdev)
!params_vdev->isp2x_params->module_en_update)
dev_warn(dev, "can not get first iq setting in stream on\n");
/* set the range */
if (params_vdev->quantization == V4L2_QUANTIZATION_FULL_RANGE)
ops->csm_config(params_vdev, true);
else
ops->csm_config(params_vdev, false);
priv_val->dhaz_en = 0;
priv_val->wdr_en = 0;
priv_val->tmo_en = 0;

View File

@@ -1029,6 +1029,67 @@ static void rkisp_monitor_init(struct rkisp_device *dev)
INIT_WORK(&monitor->work, rkisp_restart_monitor);
}
/*
* RGB to YUV color space, default BT601
* BT601:
* Y = 0.299R + 0.587G + 0.114B
* CB = -0.1687R - 0.3313G + 0.5B
* CR = 0.5R - 0.4187G - 0.0813B
* BT709:
* Y = 0.2126R + 0.7152G + 0.0722B
* CB = -0.1146R - 0.3854G + 0.5B
* CR = 0.5R - 0.4542G - 0.0458B
* BT2020:
* Y = 0.2627R + 0.678G + 0.0593B
* CB = -0.1396R - 0.3604G + 0.5B
* CR = 0.5R - 0.4598G - 0.0402B
* 9 bit coeffs are signed integer values with 7 bit fractional
*/
static void rkisp_config_color_space(struct rkisp_device *dev)
{
u16 bt601_coeff[] = {
0x0026, 0x004b, 0x000f,
0x01ea, 0x01d6, 0x0040,
0x0040, 0x01ca, 0x01f6
};
u16 bt709_coeff[] = {
0x001b, 0x005c, 0x0009,
0x01f1, 0x01cf, 0x0040,
0x0040, 0x01c6, 0x01fa
};
u16 bt2020_coeff[] = {
0x0022, 0x0057, 0x0008,
0x01ee, 0x01d2, 0x0040,
0x0040, 0x01c5, 0x01fb
};
u16 i, *coeff;
switch (dev->isp_sdev.colorspace) {
case V4L2_COLORSPACE_REC709:
coeff = bt709_coeff;
break;
case V4L2_COLORSPACE_BT2020:
coeff = bt2020_coeff;
break;
case V4L2_COLORSPACE_SMPTE170M:
default:
coeff = bt601_coeff;
break;
}
for (i = 0; i < 9; i++)
rkisp_write(dev, CIF_ISP_CC_COEFF_0 + i * 4, *(coeff + i), false);
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);
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);
}
/*
* configure isp blocks with input format, size......
*/
@@ -1168,12 +1229,13 @@ static int rkisp_config_isp(struct rkisp_device *dev)
rkisp_write(dev, ISP_ISP3A_IMSC, irq_mask, true);
}
if (out_fmt->fmt_type == FMT_BAYER)
if (out_fmt->fmt_type == FMT_BAYER) {
rkisp_params_disable_isp(&dev->params_vdev);
else
} else {
rkisp_config_color_space(dev);
rkisp_params_first_cfg(&dev->params_vdev, in_fmt,
dev->isp_sdev.quantization);
}
if (!dev->hw_dev->is_single && atomic_read(&dev->hw_dev->refcnt) <= 1) {
rkisp_update_regs(dev, CIF_ISP_ACQ_H_OFFS, CIF_ISP_ACQ_V_SIZE);
rkisp_update_regs(dev, CIF_ISP_OUT_H_SIZE, CIF_ISP_OUT_V_SIZE);
@@ -1903,6 +1965,7 @@ static int rkisp_isp_sd_get_fmt(struct v4l2_subdev *sd,
mf->width = isp_sd->out_crop.width;
mf->height = isp_sd->out_crop.height;
mf->quantization = isp_sd->quantization;
mf->colorspace = isp_sd->colorspace;
}
mf->field = V4L2_FIELD_NONE;
@@ -1955,13 +2018,15 @@ static int rkisp_isp_sd_set_fmt(struct v4l2_subdev *sd,
mf->width = isp_sd->out_crop.width;
mf->height = isp_sd->out_crop.height;
/* full range by default */
if (!mf->quantization)
if (mf->quantization == V4L2_QUANTIZATION_DEFAULT)
mf->quantization = V4L2_QUANTIZATION_FULL_RANGE;
/*
* It is quantization for output,
* isp use bt601 limit-range in internal
*/
/* BT601 default */
if (mf->colorspace != V4L2_COLORSPACE_SMPTE170M &&
mf->colorspace != V4L2_COLORSPACE_REC709 &&
mf->colorspace != V4L2_COLORSPACE_BT2020)
mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
isp_sd->quantization = mf->quantization;
isp_sd->colorspace = mf->colorspace;
}
mf->field = V4L2_FIELD_NONE;
@@ -2488,45 +2553,44 @@ static long rkisp_compat_ioctl32(struct v4l2_subdev *sd,
switch (cmd) {
case RKISP_CMD_TRIGGER_READ_BACK:
ret = copy_from_user(&trigger, up, sizeof(trigger));
if (!ret)
ret = rkisp_ioctl(sd, cmd, &trigger);
if (copy_from_user(&trigger, up, sizeof(trigger)))
return -EFAULT;
ret = rkisp_ioctl(sd, cmd, &trigger);
break;
case RKISP_CMD_CSI_MEMORY_MODE:
ret = copy_from_user(&mode, up, sizeof(int));
if (!ret)
ret = rkisp_ioctl(sd, cmd, &mode);
if (copy_from_user(&mode, up, sizeof(int)))
return -EFAULT;
ret = rkisp_ioctl(sd, cmd, &mode);
break;
case RKISP_CMD_GET_SHARED_BUF:
ret = rkisp_ioctl(sd, cmd, &resmem);
if (!ret)
ret = copy_to_user(up, &resmem, sizeof(resmem));
if (!ret && copy_to_user(up, &resmem, sizeof(resmem)))
ret = -EFAULT;
break;
case RKISP_CMD_FREE_SHARED_BUF:
ret = rkisp_ioctl(sd, cmd, NULL);
break;
case RKISP_CMD_GET_LDCHBUF_INFO:
ret = rkisp_ioctl(sd, cmd, &ldchbuf);
if (!ret)
ret = copy_to_user(up, &ldchbuf, sizeof(ldchbuf));
if (!ret && copy_to_user(up, &ldchbuf, sizeof(ldchbuf)))
ret = -EFAULT;
break;
case RKISP_CMD_SET_LDCHBUF_SIZE:
ret = copy_from_user(&ldchsize, up, sizeof(ldchsize));
if (!ret)
ret = rkisp_ioctl(sd, cmd, &ldchsize);
if (copy_from_user(&ldchsize, up, sizeof(ldchsize)))
return -EFAULT;
ret = rkisp_ioctl(sd, cmd, &ldchsize);
break;
case RKISP_CMD_GET_SHM_BUFFD:
ret = copy_from_user(&shmem, up, sizeof(shmem));
if (!ret) {
ret = rkisp_ioctl(sd, cmd, &shmem);
if (!ret)
ret = copy_to_user(up, &shmem, sizeof(shmem));
}
if (copy_from_user(&shmem, up, sizeof(shmem)))
return -EFAULT;
ret = rkisp_ioctl(sd, cmd, &shmem);
if (!ret && copy_to_user(up, &shmem, sizeof(shmem)))
ret = -EFAULT;
break;
case RKISP_CMD_GET_FBCBUF_FD:
ret = rkisp_ioctl(sd, cmd, &idxfd);
if (!ret)
ret = copy_to_user(up, &idxfd, sizeof(idxfd));
if (!ret && copy_to_user(up, &idxfd, sizeof(idxfd)))
ret = -EFAULT;
break;
default:
ret = -ENOIOCTLCMD;
@@ -2593,6 +2657,8 @@ static void rkisp_isp_sd_init_default_fmt(struct rkisp_isp_subdev *isp_sd)
/* propagate to source */
*out_crop = *in_crop;
*out_fmt = rkisp_isp_output_formats[0];
isp_sd->quantization = V4L2_QUANTIZATION_FULL_RANGE;
isp_sd->colorspace = V4L2_COLORSPACE_SMPTE170M;
}
int rkisp_register_isp_subdev(struct rkisp_device *isp_dev,

View File

@@ -121,6 +121,7 @@ struct rkisp_isp_subdev {
bool dphy_errctrl_disabled;
atomic_t frm_sync_seq;
enum v4l2_quantization quantization;
enum v4l2_colorspace colorspace;
u64 frm_timestamp;
struct frame_debug_info dbg;
};