media: rockchip: isp: isp32 support raw data compression

Change-Id: I62b7a39982ba661034856cce79fb873104f2c4ba
Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
Cai YiWei
2022-02-22 18:46:56 +08:00
committed by Tao Huang
parent c76be98cdc
commit 8a1aeac9b2
7 changed files with 188 additions and 3 deletions

View File

@@ -429,6 +429,108 @@ static int csi_config(struct rkisp_csi_device *csi)
return 0;
}
int rkisp_expander_config(struct rkisp_device *dev,
struct rkmodule_hdr_cfg *cfg, bool on)
{
struct rkmodule_hdr_cfg hdr_cfg;
int ret = -EINVAL;
u32 i, val, num, d0, d1, drop_bit = 0;
if (dev->isp_ver != ISP_V32)
return 0;
if (!on) {
rkisp_write(dev, ISP32_EXPD_CTRL, 0, false);
return 0;
}
if (!cfg) {
struct v4l2_subdev *sd = NULL;
get_remote_mipi_sensor(dev, &sd, MEDIA_ENT_F_PROC_VIDEO_COMPOSER);
if (!sd)
goto err;
ret = v4l2_subdev_call(sd, core, ioctl, RKMODULE_GET_HDR_CFG, &hdr_cfg);
if (ret)
goto err;
cfg = &hdr_cfg;
}
if (cfg->hdr_mode != HDR_COMPR)
return 0;
/* compressed data max 12bit and src data max 20bit */
if (cfg->compr.bit > 20)
drop_bit = cfg->compr.bit - 20;
dev->hdr.compr_bit = cfg->compr.bit - drop_bit;
num = cfg->compr.segment;
for (i = 0; i < num; i++) {
val = cfg->compr.slope_k[i];
rkisp_write(dev, ISP32_EXPD_K0 + i * 4, val, false);
}
d0 = 0;
d1 = cfg->compr.data_compr[0];
val = ISP32_EXPD_DATA(d0, d1 > 0xfff ? 0xfff : d1);
rkisp_write(dev, ISP32_EXPD_X00_01, val, false);
d1 = cfg->compr.data_src_shitf[0];
val = ISP32_EXPD_DATA(d0, drop_bit ? d1 >> drop_bit : d1);
rkisp_write(dev, ISP32_EXPD_Y00_01, val, false);
for (i = 1; i < num - 1; i += 2) {
d0 = cfg->compr.data_compr[i];
d1 = cfg->compr.data_compr[i + 1];
val = ISP32_EXPD_DATA(d0 > 0xfff ? 0xfff : d0,
d1 > 0xfff ? 0xfff : d1);
rkisp_write(dev, ISP32_EXPD_X00_01 + (i + 1) * 2, val, false);
d0 = cfg->compr.data_src_shitf[i];
d1 = cfg->compr.data_src_shitf[i + 1];
if (drop_bit) {
d0 = d0 >> drop_bit;
d1 = d1 >> drop_bit;
}
val = ISP32_EXPD_DATA(d0, d1);
rkisp_write(dev, ISP32_EXPD_Y00_01 + (i + 1) * 2, val, false);
}
/* the last valid point */
val = cfg->compr.data_compr[i];
val = val > 0xfff ? 0xfff : val;
d0 = ISP32_EXPD_DATA(val, val);
val = cfg->compr.data_src_shitf[i];
val = drop_bit ? val >> drop_bit : val;
d1 = ISP32_EXPD_DATA(val, val);
num = HDR_COMPR_SEGMENT_16;
for (; i < num - 1; i += 2) {
rkisp_write(dev, ISP32_EXPD_X00_01 + (i + 1) * 2, d0, false);
rkisp_write(dev, ISP32_EXPD_Y00_01 + (i + 1) * 2, d1, false);
}
rkisp_write(dev, ISP32_EXPD_Y16, val, false);
switch (cfg->compr.segment) {
case HDR_COMPR_SEGMENT_12:
num = 1;
break;
case HDR_COMPR_SEGMENT_16:
num = 2;
break;
default:
num = 0;
}
val = ISP32_EXPD_EN |
ISP32_EXPD_MODE(num) |
ISP32_EXPD_K_SHIFT(cfg->compr.k_shift);
rkisp_write(dev, ISP32_EXPD_CTRL, val, false);
return 0;
err:
return -EINVAL;
}
int rkisp_csi_config_patch(struct rkisp_device *dev)
{
int val = 0, ret = 0;
@@ -458,11 +560,12 @@ int rkisp_csi_config_patch(struct rkisp_device *dev)
if (!ret) {
dev->hdr.op_mode = hdr_cfg.hdr_mode;
dev->hdr.esp_mode = hdr_cfg.esp.mode;
rkisp_expander_config(dev, &hdr_cfg, true);
}
}
/* normal read back mode for V2X */
if (dev->hdr.op_mode == HDR_NORMAL)
/* normal read back mode default */
if (dev->hdr.op_mode == HDR_NORMAL || dev->hdr.op_mode == HDR_COMPR)
dev->hdr.op_mode = HDR_RDBK_FRAME1;
if (dev->isp_inp == INP_CIF && dev->hw_dev->is_single)

View File

@@ -149,6 +149,7 @@ struct rkisp_sensor_info {
struct rkisp_hdr {
u8 op_mode;
u8 esp_mode;
u8 compr_bit;
u8 index[HDR_DMA_MAX];
atomic_t refcnt;
struct v4l2_subdev *sensor;

View File

@@ -966,6 +966,42 @@
#define ISP32_BLS_ISP_OB_PREDGAIN (ISP3X_BLS_BASE + 0x0006c)
#define ISP32_BLS_ISP_OB_MAX (ISP3X_BLS_BASE + 0x00070)
#define ISP32_EXPD_BASE 0x00003200
#define ISP32_EXPD_CTRL (ISP32_EXPD_BASE + 0x00000)
#define ISP32_EXPD_X00_01 (ISP32_EXPD_BASE + 0x00004)
#define ISP32_EXPD_X02_03 (ISP32_EXPD_BASE + 0x00008)
#define ISP32_EXPD_X04_05 (ISP32_EXPD_BASE + 0x0000C)
#define ISP32_EXPD_X06_07 (ISP32_EXPD_BASE + 0x00010)
#define ISP32_EXPD_X08_09 (ISP32_EXPD_BASE + 0x00014)
#define ISP32_EXPD_X10_11 (ISP32_EXPD_BASE + 0x00018)
#define ISP32_EXPD_X12_13 (ISP32_EXPD_BASE + 0x0001C)
#define ISP32_EXPD_X14_15 (ISP32_EXPD_BASE + 0x00020)
#define ISP32_EXPD_Y00_01 (ISP32_EXPD_BASE + 0x00024)
#define ISP32_EXPD_Y02_03 (ISP32_EXPD_BASE + 0x00028)
#define ISP32_EXPD_Y04_05 (ISP32_EXPD_BASE + 0x0002C)
#define ISP32_EXPD_Y06_07 (ISP32_EXPD_BASE + 0x00030)
#define ISP32_EXPD_Y08_09 (ISP32_EXPD_BASE + 0x00034)
#define ISP32_EXPD_Y10_11 (ISP32_EXPD_BASE + 0x00038)
#define ISP32_EXPD_Y12_13 (ISP32_EXPD_BASE + 0x0003C)
#define ISP32_EXPD_Y14_15 (ISP32_EXPD_BASE + 0x00040)
#define ISP32_EXPD_Y16 (ISP32_EXPD_BASE + 0x00044)
#define ISP32_EXPD_K0 (ISP32_EXPD_BASE + 0x00048)
#define ISP32_EXPD_K1 (ISP32_EXPD_BASE + 0x0004c)
#define ISP32_EXPD_K2 (ISP32_EXPD_BASE + 0x00050)
#define ISP32_EXPD_K3 (ISP32_EXPD_BASE + 0x00054)
#define ISP32_EXPD_K4 (ISP32_EXPD_BASE + 0x00058)
#define ISP32_EXPD_K5 (ISP32_EXPD_BASE + 0x0005C)
#define ISP32_EXPD_K6 (ISP32_EXPD_BASE + 0x00060)
#define ISP32_EXPD_K7 (ISP32_EXPD_BASE + 0x00064)
#define ISP32_EXPD_K8 (ISP32_EXPD_BASE + 0x00068)
#define ISP32_EXPD_K9 (ISP32_EXPD_BASE + 0x0006C)
#define ISP32_EXPD_K10 (ISP32_EXPD_BASE + 0x00070)
#define ISP32_EXPD_K11 (ISP32_EXPD_BASE + 0x00074)
#define ISP32_EXPD_K12 (ISP32_EXPD_BASE + 0x00078)
#define ISP32_EXPD_K13 (ISP32_EXPD_BASE + 0x0007C)
#define ISP32_EXPD_K14 (ISP32_EXPD_BASE + 0x00080)
#define ISP32_EXPD_K15 (ISP32_EXPD_BASE + 0x00084)
#define ISP3X_DPCC0_BASE 0x00003400
#define ISP3X_DPCC1_BASE 0x00003500
#define ISP3X_DPCC2_BASE 0x00003600
@@ -2044,6 +2080,13 @@
/* RAWNR */
/* EXPD */
#define ISP32_EXPD_EN BIT(0)
#define ISP32_EXPD_K_SHIFT(a) (((a) & 0xf) << 4)
#define ISP32_EXPD_MODE(a) (((a) & 0x3) << 8)
#define ISP32_EXPD_DATA(a, b) ((a) | (b) << 16)
/* DPCC */
/* CCM */

View File

@@ -517,7 +517,7 @@ void rkisp_trigger_read_back(struct rkisp_device *dev, u8 dma2frm, u32 mode, boo
rkisp_dmarx_get_frame(dev, &cur_frame_id, NULL, NULL, true);
val = 0;
if (mode & T_START_X1) {
if (mode & (T_START_X1 | T_START_C)) {
rd_mode = HDR_RDBK_FRAME1;
} else if (mode & T_START_X2) {
rd_mode = HDR_RDBK_FRAME2;
@@ -530,6 +530,11 @@ void rkisp_trigger_read_back(struct rkisp_device *dev, u8 dma2frm, u32 mode, boo
val = rkisp_read(dev, ISP_HDRMGE_BASE, false) & 0xf;
}
if (mode & T_START_C)
rkisp_expander_config(dev, NULL, true);
else
rkisp_expander_config(dev, NULL, false);
if (is_feature_on) {
if ((ISP2X_MODULE_HDRMGE & ~iq_feature) && (val & SW_HDRMGE_EN)) {
v4l2_err(&dev->v4l2_dev, "hdrmge is not supported\n");

View File

@@ -178,6 +178,9 @@ int rkisp_rdbk_trigger_event(struct rkisp_device *dev, u32 cmd, void *arg);
void rkisp_rx_buf_pool_free(struct rkisp_device *dev);
int rkisp_expander_config(struct rkisp_device *dev,
struct rkmodule_hdr_cfg *cfg, bool on);
static inline
struct ispsd_out_fmt *rkisp_get_ispsd_out_fmt(struct rkisp_isp_subdev *isp_sdev)
{

View File

@@ -352,11 +352,38 @@ struct rkmodule_lsc_cfg {
* NO_HDR: linear mode
* HDR_X2: hdr two frame or line mode
* HDR_X3: hdr three or line mode
* HDR_COMPR: linearised and compressed data for hdr
*/
enum rkmodule_hdr_mode {
NO_HDR = 0,
HDR_X2 = 5,
HDR_X3 = 6,
HDR_COMPR,
};
enum rkmodule_hdr_compr_segment {
HDR_COMPR_SEGMENT_4 = 4,
HDR_COMPR_SEGMENT_12 = 12,
HDR_COMPR_SEGMENT_16 = 16,
};
/* rkmodule_hdr_compr
* linearised and compressed data for hdr: data_src = K * data_compr + XX
*
* bit: bit of src data, max 20 bit.
* segment: linear segment, support 4, 6 or 16.
* k_shift: left shift bit of slop amplification factor, 2^k_shift, [0 15].
* slope_k: K * 2^k_shift.
* data_src_shitf: left shift bit of source data, data_src = 2^data_src_shitf
* data_compr: compressed data.
*/
struct rkmodule_hdr_compr {
enum rkmodule_hdr_compr_segment segment;
__u8 bit;
__u8 k_shift;
__u8 data_src_shitf[HDR_COMPR_SEGMENT_16];
__u16 data_compr[HDR_COMPR_SEGMENT_16];
__u32 slope_k[HDR_COMPR_SEGMENT_16];
};
/**
@@ -395,6 +422,7 @@ struct rkmodule_hdr_esp {
struct rkmodule_hdr_cfg {
__u32 hdr_mode;
struct rkmodule_hdr_esp esp;
struct rkmodule_hdr_compr compr;
} __attribute__ ((packed));
/* sensor lvds sync code

View File

@@ -334,6 +334,7 @@ struct rkisp_mirror_flip {
* T_START_X1: isp read one frame
* T_START_X2: isp read hdr two frame
* T_START_X3: isp read hdr three frame
* T_START_C: isp read hdr linearised and compressed data
*/
enum isp2x_trigger_mode {
T_TRY = BIT(0),
@@ -343,6 +344,7 @@ enum isp2x_trigger_mode {
T_START_X1 = BIT(4),
T_START_X2 = BIT(5),
T_START_X3 = BIT(6),
T_START_C = BIT(7),
};
struct isp2x_csi_trigger {