summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzejian.su <zejian.su@starfivetech.com>2023-08-07 05:38:36 +0300
committerAndy Hu <andy.hu@starfivetech.com>2023-11-01 10:04:54 +0300
commit7d7d284f7c210b2b722856a0f9dcf7870a20d4e9 (patch)
treefec50dfb258243a8eddeb833c9b36ac82d450bb9
parent5a0dc091ad05a0ea42cc293a4131c76cd9e86cf7 (diff)
downloadlinux-7d7d284f7c210b2b722856a0f9dcf7870a20d4e9.tar.xz
Expand 2 bytes after the SC buffer for the AE/AWB flag and copy the histogram data to the SC buffer.
-rw-r--r--drivers/media/platform/starfive/v4l2_driver/stf_isp.c37
-rw-r--r--drivers/media/platform/starfive/v4l2_driver/stf_isp.h2
-rw-r--r--drivers/media/platform/starfive/v4l2_driver/stf_video.c5
-rw-r--r--drivers/media/platform/starfive/v4l2_driver/stf_vin.c36
-rw-r--r--include/uapi/linux/jh7110-isp.h33
5 files changed, 87 insertions, 26 deletions
diff --git a/drivers/media/platform/starfive/v4l2_driver/stf_isp.c b/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
index 35e38efa238b..c836ba709788 100644
--- a/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
+++ b/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
@@ -323,6 +323,13 @@ FILL_ISP_REGS_FUNC(u16);
#define FILL_ISP_REGS(type, ispbase, offset, value, size, mask, nbits) \
fill_isp_regs_##type(ispbase, offset, value, size, mask, nbits)
+static void fill_regs_with_zero(void __iomem *ispbase, u32 offset, u32 size)
+{
+ u32 i;
+ for(i = 0; i < size; i++, offset += 4)
+ reg_write(ispbase, offset, 0);
+}
+
static int isp_set_ctrl_wb(struct stf_isp_dev *isp_dev, const void * value)
{
const struct module_register_info * reg_info = &mod_reg_info[imi_awb];
@@ -335,6 +342,8 @@ static int isp_set_ctrl_wb(struct stf_isp_dev *isp_dev, const void * value)
struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
void __iomem *ispbase = vin->isp_base;
+ fill_regs_with_zero(ispbase, reg_info->cfg_reg, 16);
+
reg_write(ispbase, reg_addr, r_g);
reg_write(ispbase, reg_addr + 1 * 4, r_g);
reg_write(ispbase, reg_addr + 2 * 4, g_g);
@@ -370,8 +379,13 @@ static int isp_set_ctrl_ccm(struct stf_isp_dev *isp_dev, const void * value)
void __iomem *ispbase = vin->isp_base;
reg_write(ispbase, reg_info->cfg_reg, 6 << 16);
+ fill_regs_with_zero(ispbase, reg_info->cfg_reg + 4, 11);
+
FILL_ISP_REGS(u32, ispbase, reg_addr, (u32 *)ccm, 12, 0x7ff, 0);
+ reg_addr += 12 * 4;
+ fill_regs_with_zero(ispbase, reg_addr, 2);
+
reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
return 0;
@@ -640,6 +654,27 @@ static int isp_set_ctrl_sc(struct stf_isp_dev *isp_dev, const void * value)
u32 * w_diff = weight_cfg + 2;
s32 i;
+ // SC dumping axi id
+ reg_write(ispbase, 0x9c, 1 << 24);
+
+ // SC frame crop
+ reg_write(ispbase, 0xb8, ((u32)(setting->crop_config.v_start) << 16) | setting->crop_config.h_start);
+
+ // SC config1
+ reg_write(ispbase, 0xbc, ((u32)(setting->awb_config.sel) << 30) | ((u32)(setting->awb_config.awb_ps_grb_ba) << 16) |
+ ((u32)(setting->crop_config.sw_height) << 8) | setting->crop_config.sw_width);
+
+ // SC decimation config
+ reg_write(ispbase, 0xd8, ((u32)(setting->crop_config.vkeep) << 24) | ((u32)(setting->crop_config.vperiod) << 16) |
+ ((u32)(setting->crop_config.hkeep) << 8) | setting->crop_config.hperiod);
+
+ // SC AWB pixel sum config
+ reg_write(ispbase, 0xc4, CREATE_REG_VALUE(u8, &setting->awb_config.ws_ps_config.awb_ps_rl, 4, 0xff, 8));
+ reg_write(ispbase, 0xc8, CREATE_REG_VALUE(u8, &setting->awb_config.ws_ps_config.awb_ps_bl, 4, 0xff, 8));
+ reg_write(ispbase, 0xcc, CREATE_REG_VALUE(u16, &setting->awb_config.ws_ps_config.awb_ps_grl, 2, 0xffff, 16));
+ reg_write(ispbase, 0xd0, CREATE_REG_VALUE(u16, &setting->awb_config.ws_ps_config.awb_ps_gbl, 2, 0xffff, 16));
+ reg_write(ispbase, 0xd4, CREATE_REG_VALUE(u16, &setting->awb_config.ws_ps_config.awb_ps_grbl, 2, 0xffff, 16));
+
// AF register
reg_write(ispbase, 0xc0,
((u32)(setting->af_config.es_hor_thr & 0x1ff) << 16) |
@@ -686,7 +721,7 @@ static int isp_set_ctrl_sc(struct stf_isp_dev *isp_dev, const void * value)
FILL_ISP_REGS(u32, ispbase, reg_addr, weight_cfg, 6, 0xffffffff, 0);
reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
-
+
return 0;
}
diff --git a/drivers/media/platform/starfive/v4l2_driver/stf_isp.h b/drivers/media/platform/starfive/v4l2_driver/stf_isp.h
index 5924503f536e..d740b1fe1aa1 100644
--- a/drivers/media/platform/starfive/v4l2_driver/stf_isp.h
+++ b/drivers/media/platform/starfive/v4l2_driver/stf_isp.h
@@ -18,7 +18,7 @@
#define ISP_SCD_BUFFER_SIZE (19 * 256 * 4) // align 128
#define ISP_YHIST_BUFFER_SIZE (64 * 4)
-#define ISP_SCD_Y_BUFFER_SIZE (ISP_SCD_BUFFER_SIZE + ISP_YHIST_BUFFER_SIZE)
+#define ISP_SCD_Y_BUFFER_SIZE (ISP_SCD_BUFFER_SIZE + ISP_YHIST_BUFFER_SIZE + 2)
#define ISP_RAW_DATA_BITS 12
#define SCALER_RATIO_MAX 1 // no compose function
#define STF_ISP_REG_OFFSET_MAX 0x0FFF
diff --git a/drivers/media/platform/starfive/v4l2_driver/stf_video.c b/drivers/media/platform/starfive/v4l2_driver/stf_video.c
index 53c7a6146b6c..8a5e5a846f96 100644
--- a/drivers/media/platform/starfive/v4l2_driver/stf_video.c
+++ b/drivers/media/platform/starfive/v4l2_driver/stf_video.c
@@ -1286,13 +1286,8 @@ static int stf_video_subscribe_event(struct v4l2_fh *fh,
switch (sub->type) {
case V4L2_EVENT_FRAME_SYNC:
return v4l2_event_subscribe(fh, sub, 2, NULL);
- //int ret = v4l2_event_subscribe(fh, sub, 2, NULL);
- //pr_info("subscribe ret: %d\n", ret);
- //return ret;
default:
return v4l2_ctrl_subscribe_event(fh, sub);
- //st_debug(ST_VIN, "unsupport subscribe_event\n");
- //return -EINVAL;
}
}
diff --git a/drivers/media/platform/starfive/v4l2_driver/stf_vin.c b/drivers/media/platform/starfive/v4l2_driver/stf_vin.c
index 67e69565d179..dc30b018e684 100644
--- a/drivers/media/platform/starfive/v4l2_driver/stf_vin.c
+++ b/drivers/media/platform/starfive/v4l2_driver/stf_vin.c
@@ -1147,6 +1147,17 @@ static void vin_buffer_done(struct vin_line *line, struct vin_params *params)
while ((ready_buf = vin_buf_get_ready(output))) {
//if (line->id >= VIN_LINE_ISP && line->id <= VIN_LINE_ISP_SS1) {
if (line->id == VIN_LINE_ISP_SCD_Y) {
+#define ADDR_REG_YHIST_ACC_0 0x0D00
+ struct stf_vin2_dev *vin_dev = line_to_vin2_dev(line);
+ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
+ void __iomem *ispbase = vin->isp_base;
+ u32 y_hist_reg_addr = ADDR_REG_YHIST_ACC_0;
+ u32 * y_hist_addr = (u32 *)ready_buf->vaddr_sc;
+ s32 i = 0;
+
+ for(i = 0; i < 64; i++, y_hist_reg_addr += 4)
+ y_hist_addr[i] = reg_read(ispbase, y_hist_reg_addr);
+
event.u.frame_sync.frame_sequence = output->sequence;
v4l2_event_queue(&(line->video_out.vdev), &event);
//v4l2_event_queue(line->subdev.devnode, &event);
@@ -1246,9 +1257,14 @@ static void vin_change_buffer(struct vin_line *line)
scd_type = vin_dev->hw_ops->vin_isp_get_scd_type(vin_dev);
ready_buf->vb.flags &= ~(V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME);
if (scd_type == AWB_TYPE)
+ {
ready_buf->vb.flags |= V4L2_BUF_FLAG_PFRAME;
- else
+ *((u16 *)(ready_buf->vaddr_sc + ISP_SCD_BUFFER_SIZE + ISP_YHIST_BUFFER_SIZE)) = 0xffff;
+ }else{
ready_buf->vb.flags |= V4L2_BUF_FLAG_BFRAME;
+ *((u16 *)(ready_buf->vaddr_sc + ISP_SCD_BUFFER_SIZE + ISP_YHIST_BUFFER_SIZE)) = 0;
+ }
+
if (!output->frame_skip) {
output->frame_skip = ISP_AWB_OECF_SKIP_FRAME;
scd_type = scd_type == AWB_TYPE ? OECF_TYPE : AWB_TYPE;
@@ -1343,26 +1359,8 @@ static int vin_link_setup(struct media_entity *entity,
return 0;
}
-static int stf_vin_subscribe_event(struct v4l2_subdev *sd,
- struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub)
-{
- switch (sub->type) {
- case V4L2_EVENT_FRAME_SYNC:
- //return v4l2_event_subscribe(fh, sub, 2, NULL);
- int ret = v4l2_event_subscribe(fh, sub, 2, NULL);
- pr_info("subscribe ret: %d\n", ret);
- return ret;
- default:
- st_debug(ST_VIN, "unsupport subscribe_event\n");
- return -EINVAL;
- }
-}
-
static const struct v4l2_subdev_core_ops vin_core_ops = {
.s_power = vin_set_power,
- //.subscribe_event = stf_vin_subscribe_event,
- //.unsubscribe_event = v4l2_event_subdev_unsubscribe,
};
static const struct v4l2_subdev_video_ops vin_video_ops = {
diff --git a/include/uapi/linux/jh7110-isp.h b/include/uapi/linux/jh7110-isp.h
index e20895bd881a..91254bb509a2 100644
--- a/include/uapi/linux/jh7110-isp.h
+++ b/include/uapi/linux/jh7110-isp.h
@@ -255,6 +255,17 @@ struct jh7110_isp_ycrv_setting {
struct jh7110_isp_ycrv_curve curve;
};
+struct jh7110_isp_sc_config {
+ __u16 h_start;
+ __u16 v_start;
+ __u8 sw_width;
+ __u8 sw_height;
+ __u8 hperiod;
+ __u8 hkeep;
+ __u8 vperiod;
+ __u8 vkeep;
+};
+
struct jh7110_isp_sc_af_config {
__u8 es_hor_mode;
__u8 es_sum_mode;
@@ -264,6 +275,23 @@ struct jh7110_isp_sc_af_config {
__u16 es_hor_thr;
};
+struct jh7110_isp_sc_awb_ps {
+ __u8 awb_ps_rl;
+ __u8 awb_ps_ru;
+ __u8 awb_ps_gl;
+ __u8 awb_ps_gu;
+ __u8 awb_ps_bl;
+ __u8 awb_ps_bu;
+ __u8 awb_ps_yl;
+ __u8 awb_ps_yu;
+ __u16 awb_ps_grl;
+ __u16 awb_ps_gru;
+ __u16 awb_ps_gbl;
+ __u16 awb_ps_gbu;
+ __u16 awb_ps_grbl;
+ __u16 awb_ps_grbu;
+};
+
struct jh7110_isp_sc_awb_ws {
__u8 awb_ws_rl;
__u8 awb_ws_ru;
@@ -275,12 +303,16 @@ struct jh7110_isp_sc_awb_ws {
__u8 awb_ws_bu;
};
+
struct jh7110_isp_sc_awb_point {
__u16 intensity;
__u8 weight;
};
struct jh7110_isp_sc_awb_config {
+ struct jh7110_isp_sc_awb_ps ws_ps_config;
+ __u8 awb_ps_grb_ba;
+ __u8 sel;
struct jh7110_isp_sc_awb_ws ws_config;
__u8 awb_cw[169];
struct jh7110_isp_sc_awb_point pts[17];
@@ -288,6 +320,7 @@ struct jh7110_isp_sc_awb_config {
struct jh7110_isp_sc_setting {
__u32 enabled;
+ struct jh7110_isp_sc_config crop_config;
struct jh7110_isp_sc_af_config af_config;
struct jh7110_isp_sc_awb_config awb_config;
};