From nobody Sun Dec 28 00:46:12 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B8B8CC4332F for ; Thu, 14 Dec 2023 06:50:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1443278AbjLNGuu convert rfc822-to-8bit (ORCPT ); Thu, 14 Dec 2023 01:50:50 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32792 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229629AbjLNGug (ORCPT ); Thu, 14 Dec 2023 01:50:36 -0500 Received: from ex01.ufhost.com (ex01.ufhost.com [61.152.239.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1E23FB9; Wed, 13 Dec 2023 22:50:39 -0800 (PST) Received: from EXMBX165.cuchost.com (unknown [175.102.18.54]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "EXMBX165", Issuer "EXMBX165" (not verified)) by ex01.ufhost.com (Postfix) with ESMTP id 5E1BE24E2C6; Thu, 14 Dec 2023 14:50:31 +0800 (CST) Received: from EXMBX062.cuchost.com (172.16.6.62) by EXMBX165.cuchost.com (172.16.6.75) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Thu, 14 Dec 2023 14:50:31 +0800 Received: from ubuntu.mshome.net (113.72.145.168) by EXMBX062.cuchost.com (172.16.6.62) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Thu, 14 Dec 2023 14:50:29 +0800 From: Changhuang Liang To: Mauro Carvalho Chehab , Greg Kroah-Hartman , Hans Verkuil , "Marvin Lin" , Bryan O'Donoghue , "Ming Qian" , Laurent Pinchart , Nicolas Dufresne , Benjamin Gaignard , Tomi Valkeinen , Mingjia Zhang , Geert Uytterhoeven , Sakari Ailus , Dan Carpenter CC: Jack Zhu , Changhuang Liang , , , Subject: [PATCH v1 1/9] media: v4l2-ctrls: Add user controls for StarFive JH7110 ISP Date: Wed, 13 Dec 2023 22:50:19 -0800 Message-ID: <20231214065027.28564-2-changhuang.liang@starfivetech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231214065027.28564-1-changhuang.liang@starfivetech.com> References: <20231214065027.28564-1-changhuang.liang@starfivetech.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" X-Originating-IP: [113.72.145.168] X-ClientProxiedBy: EXCAS061.cuchost.com (172.16.6.21) To EXMBX062.cuchost.com (172.16.6.62) X-YovoleRuleAgent: yovoleflag Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add a control base for StarFive JH7110 ISP driver controls, and reserve 32 controls=EF=BC=8Calso add some controls for StarFive JH7110 ISP. Signed-off-by: Changhuang Liang --- MAINTAINERS | 1 + include/uapi/linux/jh7110-isp.h | 342 +++++++++++++++++++++++++++++ include/uapi/linux/v4l2-controls.h | 6 + 3 files changed, 349 insertions(+) create mode 100644 include/uapi/linux/jh7110-isp.h diff --git a/MAINTAINERS b/MAINTAINERS index af94a3a9be80..e4b6408585d3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -20664,6 +20664,7 @@ S: Maintained F: Documentation/admin-guide/media/starfive_camss.rst F: Documentation/devicetree/bindings/media/starfive,jh7110-camss.yaml F: drivers/staging/media/starfive/camss +F: include/uapi/linux/jh7110-isp.h =20 STARFIVE CRYPTO DRIVER M: Jia Jie Ho diff --git a/include/uapi/linux/jh7110-isp.h b/include/uapi/linux/jh7110-is= p.h new file mode 100644 index 000000000000..df0bb6ab1895 --- /dev/null +++ b/include/uapi/linux/jh7110-isp.h @@ -0,0 +1,342 @@ +/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-C= lause) */ +/* + * jh7110-isp.h + * + * JH7110 ISP driver - user space header file. + * + * Copyright =C2=A9 2023 Starfive Technology Co., Ltd. + * + * Author: Su Zejian (zejian.su@starfivetech.com) + * + */ + +#ifndef __JH7110_ISP_H_ +#define __JH7110_ISP_H_ + +#include + +#define V4L2_CID_USER_JH7110_ISP_WB_SETTING \ + (V4L2_CID_USER_JH7110_ISP_BASE + 0x0001) +#define V4L2_CID_USER_JH7110_ISP_CAR_SETTING \ + (V4L2_CID_USER_JH7110_ISP_BASE + 0x0002) +#define V4L2_CID_USER_JH7110_ISP_CCM_SETTING \ + (V4L2_CID_USER_JH7110_ISP_BASE + 0x0003) +#define V4L2_CID_USER_JH7110_ISP_CFA_SETTING \ + (V4L2_CID_USER_JH7110_ISP_BASE + 0x0004) +#define V4L2_CID_USER_JH7110_ISP_CTC_SETTING \ + (V4L2_CID_USER_JH7110_ISP_BASE + 0x0005) +#define V4L2_CID_USER_JH7110_ISP_DBC_SETTING \ + (V4L2_CID_USER_JH7110_ISP_BASE + 0x0006) +#define V4L2_CID_USER_JH7110_ISP_DNYUV_SETTING \ + (V4L2_CID_USER_JH7110_ISP_BASE + 0x0007) +#define V4L2_CID_USER_JH7110_ISP_GMARGB_SETTING \ + (V4L2_CID_USER_JH7110_ISP_BASE + 0x0008) +#define V4L2_CID_USER_JH7110_ISP_LCCF_SETTING \ + (V4L2_CID_USER_JH7110_ISP_BASE + 0x0009) +#define V4L2_CID_USER_JH7110_ISP_OBC_SETTING \ + (V4L2_CID_USER_JH7110_ISP_BASE + 0x000a) +#define V4L2_CID_USER_JH7110_ISP_OECF_SETTING \ + (V4L2_CID_USER_JH7110_ISP_BASE + 0x000b) +#define V4L2_CID_USER_JH7110_ISP_R2Y_SETTING \ + (V4L2_CID_USER_JH7110_ISP_BASE + 0x000c) +#define V4L2_CID_USER_JH7110_ISP_SAT_SETTING \ + (V4L2_CID_USER_JH7110_ISP_BASE + 0x000d) +#define V4L2_CID_USER_JH7110_ISP_SHRP_SETTING \ + (V4L2_CID_USER_JH7110_ISP_BASE + 0x000e) +#define V4L2_CID_USER_JH7110_ISP_YCRV_SETTING \ + (V4L2_CID_USER_JH7110_ISP_BASE + 0x000f) +#define V4L2_CID_USER_JH7110_ISP_STAT_SETTING \ + (V4L2_CID_USER_JH7110_ISP_BASE + 0x0010) + +struct jh7110_isp_wb_gain { + __u16 gain_r; + __u16 gain_g; + __u16 gain_b; +}; + +struct jh7110_isp_wb_setting { + __u32 enabled; + struct jh7110_isp_wb_gain gains; +}; + +struct jh7110_isp_car_setting { + __u32 enabled; +}; + +struct jh7110_isp_ccm_smlow { + __s32 ccm[3][3]; + __s32 offsets[3]; +}; + +struct jh7110_isp_ccm_setting { + __u32 enabled; + struct jh7110_isp_ccm_smlow ccm_smlow; +}; + +struct jh7110_isp_cfa_params { + __s32 hv_width; + __s32 cross_cov; +}; + +struct jh7110_isp_cfa_setting { + __u32 enabled; + struct jh7110_isp_cfa_params settings; +}; + +struct jh7110_isp_ctc_params { + __u8 saf_mode; + __u8 daf_mode; + __s32 max_gt; + __s32 min_gt; +}; + +struct jh7110_isp_ctc_setting { + __u32 enabled; + struct jh7110_isp_ctc_params settings; +}; + +struct jh7110_isp_dbc_params { + __s32 bad_gt; + __s32 bad_xt; +}; + +struct jh7110_isp_dbc_setting { + __u32 enabled; + struct jh7110_isp_dbc_params settings; +}; + +struct jh7110_isp_dnyuv_params { + __u8 y_sweight[10]; + __u16 y_curve[7]; + __u8 uv_sweight[10]; + __u16 uv_curve[7]; +}; + +struct jh7110_isp_dnyuv_setting { + __u32 enabled; + struct jh7110_isp_dnyuv_params settings; +}; + +struct jh7110_isp_gmargb_point { + __u16 g_val; + __u16 sg_val; +}; + +struct jh7110_isp_gmargb_setting { + __u32 enabled; + struct jh7110_isp_gmargb_point curve[15]; +}; + +struct jh7110_isp_lccf_circle { + __s16 center_x; + __s16 center_y; + __u8 radius; +}; + +struct jh7110_isp_lccf_curve_param { + __s16 f1; + __s16 f2; +}; + +struct jh7110_isp_lccf_setting { + __u32 enabled; + struct jh7110_isp_lccf_circle circle; + struct jh7110_isp_lccf_curve_param r_param; + struct jh7110_isp_lccf_curve_param gr_param; + struct jh7110_isp_lccf_curve_param gb_param; + struct jh7110_isp_lccf_curve_param b_param; +}; + +struct jh7110_isp_blacklevel_win_size { + __u32 width; + __u32 height; +}; + +struct jh7110_isp_blacklevel_gain { + __u8 tl_gain; + __u8 tr_gain; + __u8 bl_gain; + __u8 br_gain; +}; + +struct jh7110_isp_blacklevel_offset { + __u8 tl_offset; + __u8 tr_offset; + __u8 bl_offset; + __u8 br_offset; +}; + +struct jh7110_isp_blacklevel_setting { + __u32 enabled; + struct jh7110_isp_blacklevel_win_size win_size; + struct jh7110_isp_blacklevel_gain gain[4]; + struct jh7110_isp_blacklevel_offset offset[4]; +}; + +struct jh7110_isp_oecf_point { + __u16 x; + __u16 y; + __s16 slope; +}; + +struct jh7110_isp_oecf_setting { + __u32 enabled; + struct jh7110_isp_oecf_point r_curve[16]; + struct jh7110_isp_oecf_point gr_curve[16]; + struct jh7110_isp_oecf_point gb_curve[16]; + struct jh7110_isp_oecf_point b_curve[16]; +}; + +struct jh7110_isp_r2y_matrix { + __s16 m[9]; +}; + +struct jh7110_isp_r2y_setting { + __u32 enabled; + struct jh7110_isp_r2y_matrix matrix; +}; + +struct jh7110_isp_sat_curve { + __s16 yi_min; + __s16 yo_ir; + __s16 yo_min; + __s16 yo_max; +}; + +struct jh7110_isp_sat_hue_info { + __s16 cos; + __s16 sin; +}; + +struct jh7110_isp_sat_info { + __s16 gain_cmab; + __s16 gain_cmmd; + __s16 threshold_cmb; + __s16 threshold_cmd; + __s16 offset_u; + __s16 offset_v; + __s16 cmsf; +}; + +struct jh7110_isp_sat_setting { + __u32 enabled; + struct jh7110_isp_sat_curve curve; + struct jh7110_isp_sat_hue_info hue_info; + struct jh7110_isp_sat_info sat_info; +}; + +struct jh7110_isp_sharp_weight { + __u8 weight[15]; + __u32 recip_wei_sum; +}; + +struct jh7110_isp_sharp_strength { + __s16 diff[4]; + __s16 f[3]; + __s32 s[3]; +}; + +struct jh7110_isp_sharp_setting { + __u32 enabled; + struct jh7110_isp_sharp_weight weight; + struct jh7110_isp_sharp_strength strength; + __s8 pdirf; + __s8 ndirf; +}; + +struct jh7110_isp_ycrv_curve { + __s16 y[64]; +}; + +struct jh7110_isp_ycrv_setting { + __u32 enabled; + 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; + __u8 hor_en; + __u8 ver_en; + __u8 es_ver_thr; + __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; + __u8 awb_ws_grl; + __u8 awb_ws_gru; + __u8 awb_ws_gbl; + __u8 awb_ws_gbu; + __u8 awb_ws_bl; + __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]; +}; + +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; +}; + +#define JH7110_ISP_SC_FALG_INVALID 0x0 +#define JH7110_ISP_SC_FALG_VALID 0xffff + +#pragma pack(1) + +struct jh7110_isp_sc_buffer { + __u32 y_histogram[64]; + __u32 reserv0[33]; + __u32 bright_sc[4096]; + __u32 reserv1[96]; + __u32 ae_hist_y[128]; + __u32 reserv2[511]; + __u16 flag; +}; + +#pragma pack() + +#endif diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-c= ontrols.h index 99c3f5e99da7..8078aa2cc3d4 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -215,6 +215,12 @@ enum v4l2_colorfx { */ #define V4L2_CID_USER_THP7312_BASE (V4L2_CID_USER_BASE + 0x11c0) =20 +/* + * The base for the JH7110 ISP driver controls. + * We reserve 32 controls for this driver. + */ +#define V4L2_CID_USER_JH7110_ISP_BASE (V4L2_CID_USER_BASE + 0x11e0) + /* MPEG-class control IDs */ /* The MPEG controls are applicable to all codec controls * and the 'MPEG' part of the define is historical */ --=20 2.25.1 From nobody Sun Dec 28 00:46:12 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B2769C4332F for ; Thu, 14 Dec 2023 06:51:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1443296AbjLNGuy convert rfc822-to-8bit (ORCPT ); Thu, 14 Dec 2023 01:50:54 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32828 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234327AbjLNGuh (ORCPT ); Thu, 14 Dec 2023 01:50:37 -0500 Received: from fd01.gateway.ufhost.com (fd01.gateway.ufhost.com [61.152.239.71]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6C7D7F5; Wed, 13 Dec 2023 22:50:40 -0800 (PST) Received: from EXMBX166.cuchost.com (unknown [175.102.18.54]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "EXMBX166", Issuer "EXMBX166" (not verified)) by fd01.gateway.ufhost.com (Postfix) with ESMTP id 8AB6F819D; Thu, 14 Dec 2023 14:50:33 +0800 (CST) Received: from EXMBX062.cuchost.com (172.16.6.62) by EXMBX166.cuchost.com (172.16.6.76) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Thu, 14 Dec 2023 14:50:33 +0800 Received: from ubuntu.mshome.net (113.72.145.168) by EXMBX062.cuchost.com (172.16.6.62) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Thu, 14 Dec 2023 14:50:31 +0800 From: Changhuang Liang To: Mauro Carvalho Chehab , Greg Kroah-Hartman , Hans Verkuil , "Marvin Lin" , Bryan O'Donoghue , "Ming Qian" , Laurent Pinchart , Nicolas Dufresne , Benjamin Gaignard , Tomi Valkeinen , Mingjia Zhang , Geert Uytterhoeven , Sakari Ailus , Dan Carpenter CC: Jack Zhu , Changhuang Liang , , , Subject: [PATCH v1 2/9] staging: media: starfive: camss: Add ISP controls Date: Wed, 13 Dec 2023 22:50:20 -0800 Message-ID: <20231214065027.28564-3-changhuang.liang@starfivetech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231214065027.28564-1-changhuang.liang@starfivetech.com> References: <20231214065027.28564-1-changhuang.liang@starfivetech.com> MIME-Version: 1.0 X-Originating-IP: [113.72.145.168] X-ClientProxiedBy: EXCAS061.cuchost.com (172.16.6.21) To EXMBX062.cuchost.com (172.16.6.62) X-YovoleRuleAgent: yovoleflag Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add ISP controls to config ISP parameter for 3A. Signed-off-by: Changhuang Liang --- .../staging/media/starfive/camss/stf-camss.h | 8 + .../media/starfive/camss/stf-isp-hw-ops.c | 527 ++++++++++++++++++ .../staging/media/starfive/camss/stf-isp.c | 299 +++++++++- .../staging/media/starfive/camss/stf-isp.h | 154 +++++ 4 files changed, 987 insertions(+), 1 deletion(-) diff --git a/drivers/staging/media/starfive/camss/stf-camss.h b/drivers/sta= ging/media/starfive/camss/stf-camss.h index e2b0cfb437bd..726aa38424d8 100644 --- a/drivers/staging/media/starfive/camss/stf-camss.h +++ b/drivers/staging/media/starfive/camss/stf-camss.h @@ -103,6 +103,14 @@ static inline void stf_isp_reg_set(struct stfcamss *st= fcamss, u32 reg, u32 mask) stfcamss->isp_base + reg); } =20 +static inline void stf_isp_reg_fill_zero(struct stfcamss *stfcamss, u32 re= g, u32 size) +{ + u32 i; + + for (i =3D 0; i < size; i++, reg +=3D 4) + iowrite32(0, stfcamss->isp_base + reg); +} + static inline u32 stf_syscon_reg_read(struct stfcamss *stfcamss, u32 reg) { return ioread32(stfcamss->syscon_base + reg); diff --git a/drivers/staging/media/starfive/camss/stf-isp-hw-ops.c b/driver= s/staging/media/starfive/camss/stf-isp-hw-ops.c index c34631ff9422..c6295a14d509 100644 --- a/drivers/staging/media/starfive/camss/stf-isp-hw-ops.c +++ b/drivers/staging/media/starfive/camss/stf-isp-hw-ops.c @@ -10,6 +10,25 @@ =20 #include "stf-camss.h" =20 +static const struct stf_isp_module_info mod_info[] =3D { + { ISP_REG_CSI_MODULE_CFG, 2 }, + { ISP_REG_CSI_MODULE_CFG, 4 }, + { ISP_REG_CSI_MODULE_CFG, 6 }, + { ISP_REG_CSI_MODULE_CFG, 7 }, + { ISP_REG_CSI_MODULE_CFG, 17 }, + { ISP_REG_ISP_CTRL_1, 1 }, + { ISP_REG_ISP_CTRL_1, 2 }, + { ISP_REG_ISP_CTRL_1, 3 }, + { ISP_REG_ISP_CTRL_1, 4 }, + { ISP_REG_ISP_CTRL_1, 5 }, + { ISP_REG_ISP_CTRL_1, 7 }, + { ISP_REG_ISP_CTRL_1, 8 }, + { ISP_REG_ISP_CTRL_1, 17 }, + { ISP_REG_ISP_CTRL_1, 19 }, + { ISP_REG_ISP_CTRL_1, 21 }, + { ISP_REG_ISP_CTRL_1, 22 }, +}; + static void stf_isp_config_obc(struct stfcamss *stfcamss) { u32 reg_val, reg_add; @@ -443,3 +462,511 @@ void stf_isp_stream_set(struct stf_isp_dev *isp_dev) stf_isp_reg_write_delay(stfcamss, ISP_REG_CSI_INPUT_EN_AND_STATUS, CSI_EN_S, 10); } + +int isp_set_ctrl_wb(struct stf_isp_dev *isp_dev, const void *value) +{ + const struct stf_isp_module_info *reg_info =3D &mod_info[imi_awb]; + const struct jh7110_isp_wb_setting *setting =3D + (const struct jh7110_isp_wb_setting *)value; + const struct jh7110_isp_wb_gain *gains =3D &setting->gains; + struct stfcamss *stfcamss =3D isp_dev->stfcamss; + + stf_isp_reg_fill_zero(stfcamss, ISP_REG_AWB_X0_CFG_0, 16); + + stf_isp_reg_write(stfcamss, ISP_REG_AWB_S0_CFG_0, + AWB_S_SYMBOL_H(gains->gain_r) | AWB_S_SYMBOL_L(gains->gain_r)); + stf_isp_reg_write(stfcamss, ISP_REG_AWB_S0_CFG_1, + AWB_S_SYMBOL_H(gains->gain_r) | AWB_S_SYMBOL_L(gains->gain_r)); + stf_isp_reg_write(stfcamss, ISP_REG_AWB_S1_CFG_0, + AWB_S_SYMBOL_H(gains->gain_g) | AWB_S_SYMBOL_L(gains->gain_g)); + stf_isp_reg_write(stfcamss, ISP_REG_AWB_S1_CFG_1, + AWB_S_SYMBOL_H(gains->gain_g) | AWB_S_SYMBOL_L(gains->gain_g)); + stf_isp_reg_write(stfcamss, ISP_REG_AWB_S2_CFG_0, + AWB_S_SYMBOL_H(gains->gain_g) | AWB_S_SYMBOL_L(gains->gain_g)); + stf_isp_reg_write(stfcamss, ISP_REG_AWB_S2_CFG_1, + AWB_S_SYMBOL_H(gains->gain_g) | AWB_S_SYMBOL_L(gains->gain_g)); + stf_isp_reg_write(stfcamss, ISP_REG_AWB_S3_CFG_0, + AWB_S_SYMBOL_H(gains->gain_b) | AWB_S_SYMBOL_L(gains->gain_b)); + stf_isp_reg_write(stfcamss, ISP_REG_AWB_S3_CFG_1, + AWB_S_SYMBOL_H(gains->gain_b) | AWB_S_SYMBOL_L(gains->gain_b)); + + stf_isp_reg_set_bit(stfcamss, reg_info->en_reg, 1 << reg_info->en_nbit, + setting->enabled ? 1 << reg_info->en_nbit : 0); + + return 0; +} + +int isp_set_ctrl_car(struct stf_isp_dev *isp_dev, const void *value) +{ + const struct stf_isp_module_info *reg_info =3D &mod_info[imi_car]; + const struct jh7110_isp_car_setting *setting =3D + (const struct jh7110_isp_car_setting *)value; + struct stfcamss *stfcamss =3D isp_dev->stfcamss; + + stf_isp_reg_set_bit(stfcamss, reg_info->en_reg, 1 << reg_info->en_nbit, + setting->enabled ? 1 << reg_info->en_nbit : 0); + + return 0; +} + +int isp_set_ctrl_ccm(struct stf_isp_dev *isp_dev, const void *value) +{ + const struct stf_isp_module_info *reg_info =3D &mod_info[imi_ccm]; + const struct jh7110_isp_ccm_setting *setting =3D + (const struct jh7110_isp_ccm_setting *)value; + const struct jh7110_isp_ccm_smlow *ccm =3D &setting->ccm_smlow; + struct stfcamss *stfcamss =3D isp_dev->stfcamss; + + stf_isp_reg_write(stfcamss, ISP_REG_ICAMD_0, DNRM_F(6)); + stf_isp_reg_fill_zero(stfcamss, ISP_REG_ICAMD_1, 11); + stf_isp_reg_write(stfcamss, ISP_REG_ICAMD_12, ccm->ccm[0][0]); + stf_isp_reg_write(stfcamss, ISP_REG_ICAMD_13, ccm->ccm[0][1]); + stf_isp_reg_write(stfcamss, ISP_REG_ICAMD_14, ccm->ccm[0][2]); + stf_isp_reg_write(stfcamss, ISP_REG_ICAMD_15, ccm->ccm[1][0]); + stf_isp_reg_write(stfcamss, ISP_REG_ICAMD_16, ccm->ccm[1][1]); + stf_isp_reg_write(stfcamss, ISP_REG_ICAMD_17, ccm->ccm[1][2]); + stf_isp_reg_write(stfcamss, ISP_REG_ICAMD_18, ccm->ccm[2][0]); + stf_isp_reg_write(stfcamss, ISP_REG_ICAMD_19, ccm->ccm[2][1]); + stf_isp_reg_write(stfcamss, ISP_REG_ICAMD_20, ccm->ccm[2][2]); + stf_isp_reg_write(stfcamss, ISP_REG_ICAMD_21, ccm->offsets[0]); + stf_isp_reg_write(stfcamss, ISP_REG_ICAMD_22, ccm->offsets[1]); + stf_isp_reg_write(stfcamss, ISP_REG_ICAMD_23, ccm->offsets[2]); + stf_isp_reg_fill_zero(stfcamss, ISP_REG_ICAMD_24, 2); + + stf_isp_reg_set_bit(stfcamss, reg_info->en_reg, 1 << reg_info->en_nbit, + setting->enabled ? 1 << reg_info->en_nbit : 0); + + return 0; +} + +int isp_set_ctrl_cfa(struct stf_isp_dev *isp_dev, const void *value) +{ + const struct stf_isp_module_info *reg_info =3D &mod_info[imi_cfa]; + const struct jh7110_isp_cfa_setting *setting =3D + (const struct jh7110_isp_cfa_setting *)value; + const struct jh7110_isp_cfa_params *cfa =3D &setting->settings; + struct stfcamss *stfcamss =3D isp_dev->stfcamss; + + stf_isp_reg_write(stfcamss, ISP_REG_ICFAM, + HV_W(cfa->hv_width) | CROSS_COV(cfa->cross_cov)); + + stf_isp_reg_set_bit(stfcamss, reg_info->en_reg, 1 << reg_info->en_nbit, + setting->enabled ? 1 << reg_info->en_nbit : 0); + + return 0; +} + +int isp_set_ctrl_ctc(struct stf_isp_dev *isp_dev, const void *value) +{ + const struct stf_isp_module_info *reg_info =3D &mod_info[imi_ctc]; + const struct jh7110_isp_ctc_setting *setting =3D + (const struct jh7110_isp_ctc_setting *)value; + const struct jh7110_isp_ctc_params *ctc =3D &setting->settings; + struct stfcamss *stfcamss =3D isp_dev->stfcamss; + + stf_isp_reg_write(stfcamss, ISP_REG_ICTC, + MINGT(ctc->min_gt) | MAXGT(ctc->max_gt) | + GF_MODE(ctc->saf_mode | ctc->daf_mode)); + + stf_isp_reg_set_bit(stfcamss, reg_info->en_reg, 1 << reg_info->en_nbit, + setting->enabled ? 1 << reg_info->en_nbit : 0); + + return 0; +} + +int isp_set_ctrl_dbc(struct stf_isp_dev *isp_dev, const void *value) +{ + const struct stf_isp_module_info *reg_info =3D &mod_info[imi_dbc]; + const struct jh7110_isp_dbc_setting *setting =3D + (const struct jh7110_isp_dbc_setting *)value; + const struct jh7110_isp_dbc_params *dbc =3D &setting->settings; + struct stfcamss *stfcamss =3D isp_dev->stfcamss; + + stf_isp_reg_write(stfcamss, ISP_REG_IDBC, + BADXT(dbc->bad_xt) | BADGT(dbc->bad_gt)); + + stf_isp_reg_set_bit(stfcamss, reg_info->en_reg, 1 << reg_info->en_nbit, + setting->enabled ? 1 << reg_info->en_nbit : 0); + + return 0; +} + +int isp_set_ctrl_dnyuv(struct stf_isp_dev *isp_dev, const void *value) +{ + const struct stf_isp_module_info *reg_info =3D &mod_info[imi_dnyuv]; + const struct jh7110_isp_dnyuv_setting *setting =3D + (const struct jh7110_isp_dnyuv_setting *)value; + const struct jh7110_isp_dnyuv_params *cfg =3D &setting->settings; + struct stfcamss *stfcamss =3D isp_dev->stfcamss; + + stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_YSWR0, + YUVSW0(cfg->y_sweight[0]) | YUVSW1(cfg->y_sweight[1]) | + YUVSW2(cfg->y_sweight[2]) | YUVSW3(cfg->y_sweight[3]) | + YUVSW4(cfg->y_sweight[4]) | YUVSW5(cfg->y_sweight[5])); + stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_YSWR1, + YUVSW0(cfg->y_sweight[6]) | YUVSW1(cfg->y_sweight[7]) | + YUVSW2(cfg->y_sweight[8]) | YUVSW3(cfg->y_sweight[9])); + stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_CSWR0, + YUVSW0(cfg->uv_sweight[0]) | YUVSW1(cfg->uv_sweight[1]) | + YUVSW2(cfg->uv_sweight[2]) | YUVSW3(cfg->uv_sweight[3]) | + YUVSW4(cfg->uv_sweight[4]) | YUVSW5(cfg->uv_sweight[5])); + stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_CSWR1, + YUVSW0(cfg->uv_sweight[6]) | YUVSW1(cfg->uv_sweight[7]) | + YUVSW2(cfg->uv_sweight[8]) | YUVSW3(cfg->uv_sweight[9])); + stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_YDR0, + CURVE_D_L(cfg->y_curve[0]) | CURVE_D_H(cfg->y_curve[1])); + stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_YDR1, + CURVE_D_L(cfg->y_curve[2]) | CURVE_D_H(cfg->y_curve[3])); + stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_YDR2, + CURVE_D_L(cfg->y_curve[4]) | CURVE_D_H(cfg->y_curve[5])); + stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_CDR0, + CURVE_D_L(cfg->uv_curve[0]) | CURVE_D_H(cfg->uv_curve[1])); + stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_CDR1, + CURVE_D_L(cfg->uv_curve[2]) | CURVE_D_H(cfg->uv_curve[3])); + stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_CDR2, + CURVE_D_L(cfg->uv_curve[4]) | CURVE_D_H(cfg->uv_curve[5])); + + stf_isp_reg_set_bit(stfcamss, reg_info->en_reg, 1 << reg_info->en_nbit, + setting->enabled ? 1 << reg_info->en_nbit : 0); + + return 0; +} + +int isp_set_ctrl_gmargb(struct stf_isp_dev *isp_dev, const void *value) +{ + const struct stf_isp_module_info *reg_info =3D &mod_info[imi_gmargb]; + const struct jh7110_isp_gmargb_setting *setting =3D + (const struct jh7110_isp_gmargb_setting *)value; + const struct jh7110_isp_gmargb_point *curve =3D setting->curve; + struct stfcamss *stfcamss =3D isp_dev->stfcamss; + u32 reg_addr =3D ISP_REG_GAMMA_VAL0; + u32 i; + + for (i =3D 0; i < 15; i++, reg_addr +=3D 4) + stf_isp_reg_write(stfcamss, reg_addr, + GAMMA_S_VAL(curve[i].sg_val) | GAMMA_VAL(curve[i].g_val)); + + stf_isp_reg_set_bit(stfcamss, reg_info->en_reg, 1 << reg_info->en_nbit, + setting->enabled ? 1 << reg_info->en_nbit : 0); + + return 0; +} + +int isp_set_ctrl_lccf(struct stf_isp_dev *isp_dev, const void *value) +{ + const struct stf_isp_module_info *reg_info =3D &mod_info[imi_lccf]; + const struct jh7110_isp_lccf_setting *setting =3D + (const struct jh7110_isp_lccf_setting *)value; + const struct jh7110_isp_lccf_circle *circle =3D &setting->circle; + const struct jh7110_isp_lccf_curve_param *r_param =3D &setting->r_param; + const struct jh7110_isp_lccf_curve_param *gr_param =3D &setting->gr_param; + const struct jh7110_isp_lccf_curve_param *gb_param =3D &setting->gb_param; + const struct jh7110_isp_lccf_curve_param *b_param =3D &setting->b_param; + struct stfcamss *stfcamss =3D isp_dev->stfcamss; + + stf_isp_reg_write(stfcamss, ISP_REG_LCCF_CFG_0, + Y_DISTANCE(circle->center_y) | X_DISTANCE(circle->center_x)); + stf_isp_reg_write(stfcamss, ISP_REG_LCCF_CFG_1, + LCCF_MAX_DIS(circle->radius)); + stf_isp_reg_write(stfcamss, ISP_REG_LCCF_CFG_2, + LCCF_F1_PAR(r_param->f1) | LCCF_F2_PAR(r_param->f2)); + stf_isp_reg_write(stfcamss, ISP_REG_LCCF_CFG_3, + LCCF_F1_PAR(gr_param->f1) | LCCF_F2_PAR(gr_param->f2)); + stf_isp_reg_write(stfcamss, ISP_REG_LCCF_CFG_4, + LCCF_F1_PAR(gb_param->f1) | LCCF_F2_PAR(gb_param->f2)); + stf_isp_reg_write(stfcamss, ISP_REG_LCCF_CFG_5, + LCCF_F1_PAR(b_param->f1) | LCCF_F2_PAR(b_param->f2)); + + stf_isp_reg_set_bit(stfcamss, reg_info->en_reg, 1 << reg_info->en_nbit, + setting->enabled ? 1 << reg_info->en_nbit : 0); + + return 0; +} + +int isp_set_ctrl_obc(struct stf_isp_dev *isp_dev, const void *value) +{ + const struct stf_isp_module_info *reg_info =3D &mod_info[imi_obc]; + const struct jh7110_isp_blacklevel_setting *setting =3D + (const struct jh7110_isp_blacklevel_setting *)value; + const struct jh7110_isp_blacklevel_win_size *win_size =3D &setting->win_s= ize; + const struct jh7110_isp_blacklevel_gain *gain =3D setting->gain; + const struct jh7110_isp_blacklevel_offset *offset =3D setting->offset; + struct stfcamss *stfcamss =3D isp_dev->stfcamss; + + stf_isp_reg_write(stfcamss, ISP_REG_OBC_CFG, + OBC_W_W(win_size->width) | OBC_W_H(win_size->height)); + stf_isp_reg_write(stfcamss, ISP_REG_OBCG_CFG_0, + GAIN_A_POINT(gain[0].tl_gain) | GAIN_B_POINT(gain[0].tr_gain) | + GAIN_C_POINT(gain[0].bl_gain) | GAIN_D_POINT(gain[0].br_gain)); + stf_isp_reg_write(stfcamss, ISP_REG_OBCG_CFG_1, + GAIN_A_POINT(gain[1].tl_gain) | GAIN_B_POINT(gain[1].tr_gain) | + GAIN_C_POINT(gain[1].bl_gain) | GAIN_D_POINT(gain[1].br_gain)); + stf_isp_reg_write(stfcamss, ISP_REG_OBCG_CFG_2, + GAIN_A_POINT(gain[2].tl_gain) | GAIN_B_POINT(gain[2].tr_gain) | + GAIN_C_POINT(gain[2].bl_gain) | GAIN_D_POINT(gain[2].br_gain)); + stf_isp_reg_write(stfcamss, ISP_REG_OBCG_CFG_3, + GAIN_A_POINT(gain[3].tl_gain) | GAIN_B_POINT(gain[3].tr_gain) | + GAIN_C_POINT(gain[3].bl_gain) | GAIN_D_POINT(gain[3].br_gain)); + stf_isp_reg_write(stfcamss, ISP_REG_OBCO_CFG_0, + OFFSET_A_POINT(offset[0].tl_offset) | + OFFSET_B_POINT(offset[0].tr_offset) | + OFFSET_C_POINT(offset[0].bl_offset) | + OFFSET_D_POINT(offset[0].br_offset)); + stf_isp_reg_write(stfcamss, ISP_REG_OBCO_CFG_1, + OFFSET_A_POINT(offset[1].tl_offset) | + OFFSET_B_POINT(offset[1].tr_offset) | + OFFSET_C_POINT(offset[1].bl_offset) | + OFFSET_D_POINT(offset[1].br_offset)); + stf_isp_reg_write(stfcamss, ISP_REG_OBCO_CFG_2, + OFFSET_A_POINT(offset[2].tl_offset) | + OFFSET_B_POINT(offset[2].tr_offset) | + OFFSET_C_POINT(offset[2].bl_offset) | + OFFSET_D_POINT(offset[2].br_offset)); + stf_isp_reg_write(stfcamss, ISP_REG_OBCO_CFG_3, + OFFSET_A_POINT(offset[3].tl_offset) | + OFFSET_B_POINT(offset[3].tr_offset) | + OFFSET_C_POINT(offset[3].bl_offset) | + OFFSET_D_POINT(offset[3].br_offset)); + + stf_isp_reg_set_bit(stfcamss, reg_info->en_reg, 1 << reg_info->en_nbit, + setting->enabled ? 1 << reg_info->en_nbit : 0); + + return 0; +} + +int isp_set_ctrl_oecf(struct stf_isp_dev *isp_dev, const void *value) +{ + const struct stf_isp_module_info *reg_info =3D &mod_info[imi_oecf]; + const struct jh7110_isp_oecf_setting *setting =3D + (const struct jh7110_isp_oecf_setting *)value; + const struct jh7110_isp_oecf_point *oecf =3D setting->r_curve; + struct stfcamss *stfcamss =3D isp_dev->stfcamss; + u32 reg_x_addr =3D ISP_REG_OECF_X0_CFG0; + u32 reg_y_addr =3D ISP_REG_OECF_Y0_CFG0; + u32 reg_s_addr =3D ISP_REG_OECF_S0_CFG0; + u32 i; + + for (i =3D 0; i < 64; i +=3D 2, reg_x_addr +=3D 4, reg_y_addr +=3D 4, reg= _s_addr +=3D 4) { + stf_isp_reg_write(stfcamss, reg_x_addr, + OCEF_PAR_L(oecf[i].x) | OCEF_PAR_H(oecf[i + 1].x)); + stf_isp_reg_write(stfcamss, reg_y_addr, + OCEF_PAR_L(oecf[i].y) | OCEF_PAR_H(oecf[i + 1].y)); + stf_isp_reg_write(stfcamss, reg_s_addr, + OCEF_PAR_L(oecf[i].slope) | OCEF_PAR_H(oecf[i + 1].slope)); + } + + stf_isp_reg_set_bit(stfcamss, reg_info->en_reg, 1 << reg_info->en_nbit, + setting->enabled ? 1 << reg_info->en_nbit : 0); + + return 0; +} + +int isp_set_ctrl_r2y(struct stf_isp_dev *isp_dev, const void *value) +{ + const struct stf_isp_module_info *reg_info =3D &mod_info[imi_r2y]; + const struct jh7110_isp_r2y_setting *setting =3D + (const struct jh7110_isp_r2y_setting *)value; + const struct jh7110_isp_r2y_matrix *matrix =3D &setting->matrix; + struct stfcamss *stfcamss =3D isp_dev->stfcamss; + u32 reg_addr =3D ISP_REG_R2Y_0; + u32 i; + + for (i =3D 0; i < 9; i++, reg_addr +=3D 4) + stf_isp_reg_write(stfcamss, reg_addr, matrix->m[i]); + + stf_isp_reg_set_bit(stfcamss, reg_info->en_reg, 1 << reg_info->en_nbit, + setting->enabled ? 1 << reg_info->en_nbit : 0); + + return 0; +} + +int isp_set_ctrl_sat(struct stf_isp_dev *isp_dev, const void *value) +{ + const struct stf_isp_module_info *reg_info =3D &mod_info[imi_sat]; + const struct jh7110_isp_sat_setting *setting =3D + (const struct jh7110_isp_sat_setting *)value; + const struct jh7110_isp_sat_info *sat =3D &setting->sat_info; + const struct jh7110_isp_sat_hue_info *hue =3D &setting->hue_info; + const struct jh7110_isp_sat_curve *curve =3D &setting->curve; + struct stfcamss *stfcamss =3D isp_dev->stfcamss; + + stf_isp_reg_write(stfcamss, ISP_REG_CS_GAIN, + CMAB(sat->gain_cmab) | CMAD(sat->gain_cmmd)); + stf_isp_reg_write(stfcamss, ISP_REG_CS_THRESHOLD, + CMB(sat->threshold_cmb) | CMD(sat->threshold_cmd)); + stf_isp_reg_write(stfcamss, ISP_REG_CS_OFFSET, + UOFF(sat->offset_u) | VOFF(sat->offset_v)); + stf_isp_reg_write(stfcamss, ISP_REG_CS_SCALE, sat->offset_u); + stf_isp_reg_write(stfcamss, ISP_REG_CS_HUE_F, + COS(hue->cos) | SIN(hue->sin)); + stf_isp_reg_write(stfcamss, ISP_REG_YADJ0, + YIMIN(curve->yi_min) | YOIR(curve->yo_ir)); + stf_isp_reg_write(stfcamss, ISP_REG_YADJ1, + YOMIN(curve->yo_min) | YOMAX(curve->yo_max)); + + stf_isp_reg_set_bit(stfcamss, reg_info->en_reg, 1 << reg_info->en_nbit, + setting->enabled ? 1 << reg_info->en_nbit : 0); + + return 0; +} + +int isp_set_ctrl_shrp(struct stf_isp_dev *isp_dev, const void *value) +{ + const struct stf_isp_module_info *reg_info =3D &mod_info[imi_shrp]; + const struct jh7110_isp_sharp_setting *setting =3D + (const struct jh7110_isp_sharp_setting *)value; + const struct jh7110_isp_sharp_weight *weight =3D &setting->weight; + const struct jh7110_isp_sharp_strength *strength =3D &setting->strength; + struct stfcamss *stfcamss =3D isp_dev->stfcamss; + u32 reg_addr =3D ISP_REG_SHARPEN0; + u32 i; + + for (i =3D 0; i < 4; i++, reg_addr +=3D 4) + stf_isp_reg_write(stfcamss, reg_addr, + S_WEIGHT(weight->weight[i]) | S_DELTA(strength->diff[i])); + + for (; i < 15; i++, reg_addr +=3D 4) + stf_isp_reg_write(stfcamss, reg_addr, S_WEIGHT(weight->weight[i])); + + reg_addr =3D ISP_REG_SHARPEN_FS0; + + for (i =3D 0; i < 3; i++, reg_addr +=3D 4) + stf_isp_reg_write(stfcamss, reg_addr, + S_SLOPE(strength->s[i]) | S_FACTOR(strength->f[i])); + + stf_isp_reg_write(stfcamss, ISP_REG_SHARPEN_WN, + WSUM(weight->recip_wei_sum) | NDIRF(setting->ndirf) | + PDIRF(setting->pdirf)); + + stf_isp_reg_set_bit(stfcamss, reg_info->en_reg, 1 << reg_info->en_nbit, + setting->enabled ? 1 << reg_info->en_nbit : 0); + + return 0; +} + +int isp_set_ctrl_ycrv(struct stf_isp_dev *isp_dev, const void *value) +{ + const struct stf_isp_module_info *reg_info =3D &mod_info[imi_ycrv]; + const struct jh7110_isp_ycrv_setting *setting =3D + (const struct jh7110_isp_ycrv_setting *)value; + const struct jh7110_isp_ycrv_curve *curve =3D &setting->curve; + struct stfcamss *stfcamss =3D isp_dev->stfcamss; + u32 reg_addr =3D ISP_REG_YCURVE_0; + u32 i; + + for (i =3D 0; i < 64; i++, reg_addr +=3D 4) + stf_isp_reg_write(stfcamss, reg_addr, curve->y[i]); + + stf_isp_reg_set_bit(stfcamss, reg_info->en_reg, 1 << reg_info->en_nbit, + setting->enabled ? 1 << reg_info->en_nbit : 0); + + return 0; +} + +int isp_set_ctrl_sc(struct stf_isp_dev *isp_dev, const void *value) +{ + const struct stf_isp_module_info *reg_info =3D &mod_info[imi_sc]; + const struct jh7110_isp_sc_setting *setting =3D + (const struct jh7110_isp_sc_setting *)value; + const struct jh7110_isp_sc_config *crop =3D &setting->crop_config; + const struct jh7110_isp_sc_af_config *af =3D &setting->af_config; + const struct jh7110_isp_sc_awb_config *awb =3D &setting->awb_config; + const struct jh7110_isp_sc_awb_ps *awb_ps =3D &awb->ws_ps_config; + const struct jh7110_isp_sc_awb_ws *awb_ws =3D &awb->ws_config; + const struct jh7110_isp_sc_awb_point *pts =3D awb->pts; + struct stfcamss *stfcamss =3D isp_dev->stfcamss; + u32 reg_addr0, reg_addr1; + u32 i; + + stf_isp_reg_write(stfcamss, ISP_REG_SCD_CFG_1, AXI_ID(1)); + stf_isp_reg_write(stfcamss, ISP_REG_SC_CFG_0, + HSTART(crop->h_start) | VSTART(crop->v_start)); + stf_isp_reg_write(stfcamss, ISP_REG_SC_CFG_1, + SC_WIDTH(crop->sw_width) | SC_HEIGHT(crop->sw_height) | + AWB_PS_GRB_BA(awb->awb_ps_grb_ba) | SEL_TYPE(awb->sel)); + stf_isp_reg_write(stfcamss, ISP_REG_SC_DEC, + SC_DEC_H_PERIOD(crop->hperiod) | SC_DEC_H_KEEP(crop->hkeep) | + SC_DEC_V_PERIOD(crop->vperiod) | SC_DEC_V_KEEP(crop->vkeep)); + + stf_isp_reg_write(stfcamss, ISP_REG_SC_AWB_PS_CFG_0, + AWB_PS_RL(awb_ps->awb_ps_rl) | AWB_PS_RU(awb_ps->awb_ps_ru) | + AWB_PS_GL(awb_ps->awb_ps_gl) | AWB_PS_GU(awb_ps->awb_ps_gu)); + stf_isp_reg_write(stfcamss, ISP_REG_SC_AWB_PS_CFG_1, + AWB_PS_BL(awb_ps->awb_ps_bl) | AWB_PS_BU(awb_ps->awb_ps_bu) | + AWB_PS_YL(awb_ps->awb_ps_yl) | AWB_PS_YU(awb_ps->awb_ps_yu)); + stf_isp_reg_write(stfcamss, ISP_REG_SC_AWB_PS_CFG_2, + AWB_PS_GRL(awb_ps->awb_ps_grl) | AWB_PS_GRU(awb_ps->awb_ps_gru)); + stf_isp_reg_write(stfcamss, ISP_REG_SC_AWB_PS_CFG_3, + AWB_PS_GBL(awb_ps->awb_ps_gbl) | AWB_PS_GBU(awb_ps->awb_ps_gbu)); + stf_isp_reg_write(stfcamss, ISP_REG_SC_AWB_PS_CFG_4, + AWB_PS_GRBL(awb_ps->awb_ps_grbl) | AWB_PS_GRBU(awb_ps->awb_ps_grbu)); + + stf_isp_reg_write(stfcamss, ISP_REG_SCD_CFG_1, + AF_ES_HM(af->es_hor_mode) | AF_ES_SM(af->es_sum_mode) | + AF_ES_HE(af->hor_en) | AF_ES_VE(af->ver_en) | + AF_ES_VTHR(af->es_ver_thr) | AF_ES_HTHR(af->es_hor_thr)); + + stf_isp_reg_write(stfcamss, ISP_REG_SC_AWB_WS_CFG_0, + AWB_WS_RL(awb_ws->awb_ws_rl) | AWB_WS_RU(awb_ws->awb_ws_ru) | + AWB_WS_GRL(awb_ws->awb_ws_grl) | AWB_WS_GRU(awb_ws->awb_ws_gru)); + stf_isp_reg_write(stfcamss, ISP_REG_SC_AWB_WS_CFG_1, + AWB_WS_GBL(awb_ws->awb_ws_gbl) | AWB_WS_GBU(awb_ws->awb_ws_gbu) | + AWB_WS_BL(awb_ws->awb_ws_bl) | AWB_WS_BU(awb_ws->awb_ws_bu)); + + reg_addr0 =3D ISP_REG_SC_AWB_WS_CW0_CFG_0; + reg_addr1 =3D ISP_REG_SC_AWB_WS_CW0_CFG_1; + + for (i =3D 0; i < 13; i++, reg_addr0 +=3D 8, reg_addr1 +=3D 8) { + stf_isp_reg_write(stfcamss, reg_addr0, + AWB_WS_CW_W_0(awb->awb_cw[13 * i]) | + AWB_WS_CW_W_1(awb->awb_cw[13 * i + 1]) | + AWB_WS_CW_W_2(awb->awb_cw[13 * i + 2]) | + AWB_WS_CW_W_3(awb->awb_cw[13 * i + 3]) | + AWB_WS_CW_W_4(awb->awb_cw[13 * i + 4]) | + AWB_WS_CW_W_5(awb->awb_cw[13 * i + 5]) | + AWB_WS_CW_W_6(awb->awb_cw[13 * i + 6]) | + AWB_WS_CW_W_7(awb->awb_cw[13 * i + 7])); + stf_isp_reg_write(stfcamss, reg_addr1, + AWB_WS_CW_W_0(awb->awb_cw[13 * i + 8]) | + AWB_WS_CW_W_1(awb->awb_cw[13 * i + 9]) | + AWB_WS_CW_W_2(awb->awb_cw[13 * i + 10]) | + AWB_WS_CW_W_3(awb->awb_cw[13 * i + 11]) | + AWB_WS_CW_W_4(awb->awb_cw[13 * i + 12])); + } + + stf_isp_reg_write(stfcamss, ISP_REG_SC_AWB_WS_IWV_CFG_0, + AWB_WS_IW_V_0(pts[0].weight) | AWB_WS_IW_V_1(pts[1].weight) | + AWB_WS_IW_V_2(pts[2].weight) | AWB_WS_IW_V_3(pts[3].weight) | + AWB_WS_IW_V_4(pts[4].weight) | AWB_WS_IW_V_5(pts[5].weight) | + AWB_WS_IW_V_6(pts[6].weight) | AWB_WS_IW_V_7(pts[7].weight)); + stf_isp_reg_write(stfcamss, ISP_REG_SC_AWB_WS_IWV_CFG_1, + AWB_WS_IW_V_0(pts[8].weight) | AWB_WS_IW_V_1(pts[9].weight) | + AWB_WS_IW_V_2(pts[10].weight) | AWB_WS_IW_V_3(pts[11].weight) | + AWB_WS_IW_V_4(pts[12].weight) | AWB_WS_IW_V_5(pts[13].weight) | + AWB_WS_IW_V_6(pts[14].weight) | AWB_WS_IW_V_7(pts[15].weight)); + stf_isp_reg_write(stfcamss, ISP_REG_SC_AWB_WS_IWS_CFG_0, + AWB_WS_IW_S_0(2 * (pts[1].weight - pts[0].weight)) | + AWB_WS_IW_S_1(2 * (pts[2].weight - pts[1].weight)) | + AWB_WS_IW_S_2(2 * (pts[3].weight - pts[2].weight)) | + AWB_WS_IW_S_3(2 * (pts[4].weight - pts[3].weight))); + stf_isp_reg_write(stfcamss, ISP_REG_SC_AWB_WS_IWS_CFG_1, + AWB_WS_IW_S_0(2 * (pts[5].weight - pts[4].weight)) | + AWB_WS_IW_S_1(2 * (pts[6].weight - pts[5].weight)) | + AWB_WS_IW_S_2(2 * (pts[7].weight - pts[6].weight)) | + AWB_WS_IW_S_3(2 * (pts[8].weight - pts[7].weight))); + stf_isp_reg_write(stfcamss, ISP_REG_SC_AWB_WS_IWS_CFG_2, + AWB_WS_IW_S_0(2 * (pts[9].weight - pts[8].weight)) | + AWB_WS_IW_S_1(2 * (pts[10].weight - pts[9].weight)) | + AWB_WS_IW_S_2(2 * (pts[11].weight - pts[10].weight)) | + AWB_WS_IW_S_3(2 * (pts[12].weight - pts[11].weight))); + stf_isp_reg_write(stfcamss, ISP_REG_SC_AWB_WS_IWS_CFG_3, + AWB_WS_IW_S_0(2 * (pts[13].weight - pts[12].weight)) | + AWB_WS_IW_S_1(2 * (pts[14].weight - pts[13].weight)) | + AWB_WS_IW_S_2(2 * (pts[15].weight - pts[14].weight)) | + AWB_WS_IW_S_3(2 * (pts[16].weight - pts[15].weight))); + + stf_isp_reg_set_bit(stfcamss, reg_info->en_reg, 1 << reg_info->en_nbit, + setting->enabled ? 1 << reg_info->en_nbit : 0); + + return 0; +} diff --git a/drivers/staging/media/starfive/camss/stf-isp.c b/drivers/stagi= ng/media/starfive/camss/stf-isp.c index d50616ef351e..ac83f23842df 100644 --- a/drivers/staging/media/starfive/camss/stf-isp.c +++ b/drivers/staging/media/starfive/camss/stf-isp.c @@ -6,6 +6,7 @@ * * Copyright (C) 2021-2023 StarFive Technology Co., Ltd. */ +#include #include =20 #include "stf-camss.h" @@ -306,6 +307,11 @@ static int isp_init_formats(struct v4l2_subdev *sd, return isp_set_format(sd, sd_state, &format); } =20 +static const struct v4l2_subdev_core_ops isp_core_ops =3D { + .subscribe_event =3D v4l2_ctrl_subdev_subscribe_event, + .unsubscribe_event =3D v4l2_event_subdev_unsubscribe, +}; + static const struct v4l2_subdev_video_ops isp_video_ops =3D { .s_stream =3D isp_set_stream, }; @@ -319,6 +325,7 @@ static const struct v4l2_subdev_pad_ops isp_pad_ops =3D= { }; =20 static const struct v4l2_subdev_ops isp_v4l2_ops =3D { + .core =3D &isp_core_ops, .video =3D &isp_video_ops, .pad =3D &isp_pad_ops, }; @@ -331,6 +338,292 @@ static const struct media_entity_operations isp_media= _ops =3D { .link_validate =3D v4l2_subdev_link_validate, }; =20 +static int isp_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct stf_isp_dev *isp_dev =3D + container_of(ctrl->handler, struct stf_isp_dev, handler); + int ret =3D 0; + + switch (ctrl->id) { + case V4L2_CID_USER_JH7110_ISP_WB_SETTING: + ret =3D isp_set_ctrl_wb(isp_dev, ctrl->p_new.p_u8); + break; + case V4L2_CID_USER_JH7110_ISP_CAR_SETTING: + ret =3D isp_set_ctrl_car(isp_dev, ctrl->p_new.p_u8); + break; + case V4L2_CID_USER_JH7110_ISP_CCM_SETTING: + ret =3D isp_set_ctrl_ccm(isp_dev, ctrl->p_new.p_u8); + break; + case V4L2_CID_USER_JH7110_ISP_CFA_SETTING: + ret =3D isp_set_ctrl_cfa(isp_dev, ctrl->p_new.p_u8); + break; + case V4L2_CID_USER_JH7110_ISP_CTC_SETTING: + ret =3D isp_set_ctrl_ctc(isp_dev, ctrl->p_new.p_u8); + break; + case V4L2_CID_USER_JH7110_ISP_DBC_SETTING: + ret =3D isp_set_ctrl_dbc(isp_dev, ctrl->p_new.p_u8); + break; + case V4L2_CID_USER_JH7110_ISP_DNYUV_SETTING: + ret =3D isp_set_ctrl_dnyuv(isp_dev, ctrl->p_new.p_u8); + break; + case V4L2_CID_USER_JH7110_ISP_GMARGB_SETTING: + ret =3D isp_set_ctrl_gmargb(isp_dev, ctrl->p_new.p_u8); + break; + case V4L2_CID_USER_JH7110_ISP_LCCF_SETTING: + ret =3D isp_set_ctrl_lccf(isp_dev, ctrl->p_new.p_u8); + break; + case V4L2_CID_USER_JH7110_ISP_OBC_SETTING: + ret =3D isp_set_ctrl_obc(isp_dev, ctrl->p_new.p_u8); + break; + case V4L2_CID_USER_JH7110_ISP_OECF_SETTING: + ret =3D isp_set_ctrl_oecf(isp_dev, ctrl->p_new.p_u8); + break; + case V4L2_CID_USER_JH7110_ISP_R2Y_SETTING: + ret =3D isp_set_ctrl_r2y(isp_dev, ctrl->p_new.p_u8); + break; + case V4L2_CID_USER_JH7110_ISP_SAT_SETTING: + ret =3D isp_set_ctrl_sat(isp_dev, ctrl->p_new.p_u8); + break; + case V4L2_CID_USER_JH7110_ISP_SHRP_SETTING: + ret =3D isp_set_ctrl_shrp(isp_dev, ctrl->p_new.p_u8); + break; + case V4L2_CID_USER_JH7110_ISP_YCRV_SETTING: + ret =3D isp_set_ctrl_ycrv(isp_dev, ctrl->p_new.p_u8); + break; + case V4L2_CID_USER_JH7110_ISP_STAT_SETTING: + ret =3D isp_set_ctrl_sc(isp_dev, ctrl->p_new.p_u8); + break; + default: + ret =3D -EINVAL; + break; + } + + return ret; +} + +static const struct v4l2_ctrl_ops isp_ctrl_ops =3D { + .s_ctrl =3D isp_s_ctrl, +}; + +struct v4l2_ctrl_config isp_ctrl[] =3D { + [0] =3D { + .ops =3D &isp_ctrl_ops, + .type =3D V4L2_CTRL_TYPE_U8, + .def =3D 0, + .min =3D 0x00, + .max =3D 0xff, + .step =3D 1, + .name =3D "WB Setting", + .id =3D V4L2_CID_USER_JH7110_ISP_WB_SETTING, + .dims[0] =3D sizeof(struct jh7110_isp_wb_setting), + .flags =3D 0, + }, + [1] =3D { + .ops =3D &isp_ctrl_ops, + .type =3D V4L2_CTRL_TYPE_U8, + .def =3D 0, + .min =3D 0x00, + .max =3D 0xff, + .step =3D 1, + .name =3D "Car Setting", + .id =3D V4L2_CID_USER_JH7110_ISP_CAR_SETTING, + .dims[0] =3D sizeof(struct jh7110_isp_car_setting), + .flags =3D 0, + }, + [2] =3D { + .ops =3D &isp_ctrl_ops, + .type =3D V4L2_CTRL_TYPE_U8, + .def =3D 0, + .min =3D 0x00, + .max =3D 0xff, + .step =3D 1, + .name =3D "CCM Setting", + .id =3D V4L2_CID_USER_JH7110_ISP_CCM_SETTING, + .dims[0] =3D sizeof(struct jh7110_isp_ccm_setting), + .flags =3D 0, + }, + [3] =3D { + .ops =3D &isp_ctrl_ops, + .type =3D V4L2_CTRL_TYPE_U8, + .def =3D 0, + .min =3D 0x00, + .max =3D 0xff, + .step =3D 1, + .name =3D "CFA Setting", + .id =3D V4L2_CID_USER_JH7110_ISP_CFA_SETTING, + .dims[0] =3D sizeof(struct jh7110_isp_cfa_setting), + .flags =3D 0, + }, + [4] =3D { + .ops =3D &isp_ctrl_ops, + .type =3D V4L2_CTRL_TYPE_U8, + .def =3D 0, + .min =3D 0x00, + .max =3D 0xff, + .step =3D 1, + .name =3D "CTC Setting", + .id =3D V4L2_CID_USER_JH7110_ISP_CTC_SETTING, + .dims[0] =3D sizeof(struct jh7110_isp_ctc_setting), + .flags =3D 0, + }, + [5] =3D { + .ops =3D &isp_ctrl_ops, + .type =3D V4L2_CTRL_TYPE_U8, + .def =3D 0, + .min =3D 0x00, + .max =3D 0xff, + .step =3D 1, + .name =3D "DBC Setting", + .id =3D V4L2_CID_USER_JH7110_ISP_DBC_SETTING, + .dims[0] =3D sizeof(struct jh7110_isp_dbc_setting), + .flags =3D 0, + }, + [6] =3D { + .ops =3D &isp_ctrl_ops, + .type =3D V4L2_CTRL_TYPE_U8, + .def =3D 0, + .min =3D 0x00, + .max =3D 0xff, + .step =3D 1, + .name =3D "DNYUV Setting", + .id =3D V4L2_CID_USER_JH7110_ISP_DNYUV_SETTING, + .dims[0] =3D sizeof(struct jh7110_isp_dnyuv_setting), + .flags =3D 0, + }, + [7] =3D { + .ops =3D &isp_ctrl_ops, + .type =3D V4L2_CTRL_TYPE_U8, + .def =3D 0, + .min =3D 0x00, + .max =3D 0xff, + .step =3D 1, + .name =3D "GMARGB Setting", + .id =3D V4L2_CID_USER_JH7110_ISP_GMARGB_SETTING, + .dims[0] =3D sizeof(struct jh7110_isp_gmargb_setting), + .flags =3D 0, + }, + [8] =3D { + .ops =3D &isp_ctrl_ops, + .type =3D V4L2_CTRL_TYPE_U8, + .def =3D 0, + .min =3D 0x00, + .max =3D 0xff, + .step =3D 1, + .name =3D "LCCF Setting", + .id =3D V4L2_CID_USER_JH7110_ISP_LCCF_SETTING, + .dims[0] =3D sizeof(struct jh7110_isp_lccf_setting), + .flags =3D 0, + }, + [9] =3D { + .ops =3D &isp_ctrl_ops, + .type =3D V4L2_CTRL_TYPE_U8, + .def =3D 0, + .min =3D 0x00, + .max =3D 0xff, + .step =3D 1, + .name =3D "OBC Setting", + .id =3D V4L2_CID_USER_JH7110_ISP_OBC_SETTING, + .dims[0] =3D sizeof(struct jh7110_isp_blacklevel_setting), + .flags =3D 0, + }, + [10] =3D { + .ops =3D &isp_ctrl_ops, + .type =3D V4L2_CTRL_TYPE_U8, + .def =3D 0, + .min =3D 0x00, + .max =3D 0xff, + .step =3D 1, + .name =3D "OECF Setting", + .id =3D V4L2_CID_USER_JH7110_ISP_OECF_SETTING, + .dims[0] =3D sizeof(struct jh7110_isp_oecf_setting), + .flags =3D 0, + }, + [11] =3D { + .ops =3D &isp_ctrl_ops, + .type =3D V4L2_CTRL_TYPE_U8, + .def =3D 0, + .min =3D 0x00, + .max =3D 0xff, + .step =3D 1, + .name =3D "R2Y Setting", + .id =3D V4L2_CID_USER_JH7110_ISP_R2Y_SETTING, + .dims[0] =3D sizeof(struct jh7110_isp_r2y_setting), + .flags =3D 0, + }, + [12] =3D { + .ops =3D &isp_ctrl_ops, + .type =3D V4L2_CTRL_TYPE_U8, + .def =3D 0, + .min =3D 0x00, + .max =3D 0xff, + .step =3D 1, + .name =3D "SAT Setting", + .id =3D V4L2_CID_USER_JH7110_ISP_SAT_SETTING, + .dims[0] =3D sizeof(struct jh7110_isp_sat_setting), + .flags =3D 0, + }, + [13] =3D { + .ops =3D &isp_ctrl_ops, + .type =3D V4L2_CTRL_TYPE_U8, + .def =3D 0, + .min =3D 0x00, + .max =3D 0xff, + .step =3D 1, + .name =3D "SHRP Setting", + .id =3D V4L2_CID_USER_JH7110_ISP_SHRP_SETTING, + .dims[0] =3D sizeof(struct jh7110_isp_sharp_setting), + .flags =3D 0, + }, + [14] =3D { + .ops =3D &isp_ctrl_ops, + .type =3D V4L2_CTRL_TYPE_U8, + .def =3D 0, + .min =3D 0x00, + .max =3D 0xff, + .step =3D 1, + .name =3D "YCRV Setting", + .id =3D V4L2_CID_USER_JH7110_ISP_YCRV_SETTING, + .dims[0] =3D sizeof(struct jh7110_isp_ycrv_setting), + .flags =3D 0, + }, + [15] =3D { + .ops =3D &isp_ctrl_ops, + .type =3D V4L2_CTRL_TYPE_U8, + .def =3D 0, + .min =3D 0x00, + .max =3D 0xff, + .step =3D 1, + .name =3D "SC Setting", + .id =3D V4L2_CID_USER_JH7110_ISP_STAT_SETTING, + .dims[0] =3D sizeof(struct jh7110_isp_sc_setting), + .flags =3D 0, + }, +}; + +static int isp_init_controls(struct stf_isp_dev *isp_dev) +{ + struct v4l2_ctrl_handler *hdl =3D &isp_dev->handler; + int ret; + int i; + + v4l2_ctrl_handler_init(hdl, ARRAY_SIZE(isp_ctrl)); + + for (i =3D 0; i < ARRAY_SIZE(isp_ctrl); i++) + v4l2_ctrl_new_custom(hdl, &isp_ctrl[i], NULL); + + if (hdl->error) { + ret =3D hdl->error; + goto free_ctrls; + } + + isp_dev->subdev.ctrl_handler =3D hdl; + return 0; + +free_ctrls: + v4l2_ctrl_handler_free(hdl); + return ret; +} + int stf_isp_register(struct stf_isp_dev *isp_dev, struct v4l2_device *v4l2= _dev) { struct v4l2_subdev *sd =3D &isp_dev->subdev; @@ -339,7 +632,7 @@ int stf_isp_register(struct stf_isp_dev *isp_dev, struc= t v4l2_device *v4l2_dev) =20 v4l2_subdev_init(sd, &isp_v4l2_ops); sd->internal_ops =3D &isp_internal_ops; - sd->flags |=3D V4L2_SUBDEV_FL_HAS_DEVNODE; + sd->flags |=3D V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; snprintf(sd->name, ARRAY_SIZE(sd->name), "stf_isp"); v4l2_set_subdevdata(sd, isp_dev); =20 @@ -355,6 +648,10 @@ int stf_isp_register(struct stf_isp_dev *isp_dev, stru= ct v4l2_device *v4l2_dev) return ret; } =20 + ret =3D isp_init_controls(isp_dev); + if (ret) + goto err_entity_cleanup; + ret =3D v4l2_subdev_init_finalize(sd); if (ret) goto err_entity_cleanup; diff --git a/drivers/staging/media/starfive/camss/stf-isp.h b/drivers/stagi= ng/media/starfive/camss/stf-isp.h index 955cbb048363..1d98754964ce 100644 --- a/drivers/staging/media/starfive/camss/stf-isp.h +++ b/drivers/staging/media/starfive/camss/stf-isp.h @@ -10,6 +10,8 @@ #ifndef STF_ISP_H #define STF_ISP_H =20 +#include +#include #include =20 #include "stf-video.h" @@ -107,6 +109,60 @@ #define Y_COOR(y) ((y) << 16) #define X_COOR(x) ((x) << 0) =20 +#define ISP_REG_SCD_CFG_0 0x098 + +#define ISP_REG_SCD_CFG_1 0x09c +#define AXI_ID(n) ((n) << 24) + +#define ISP_REG_SC_CFG_0 0x0b8 +#define VSTART(n) ((n) << 16) +#define HSTART(n) ((n) << 0) + +#define ISP_REG_SC_CFG_1 0x0bc +#define ISP_SC_SEL_MASK GENMASK(31, 30) +#define SEL_TYPE(n) ((n) << 30) +#define AWB_PS_GRB_BA(n) ((n) << 16) +#define SC_HEIGHT(n) ((n) << 8) +#define SC_WIDTH(n) ((n) << 0) + +#define ISP_REG_SC_AF 0x0c0 +#define AF_ES_HTHR(n) ((n) << 16) +#define AF_ES_VTHR(n) ((n) << 8) +#define AF_ES_VE(n) ((n) << 3) +#define AF_ES_HE(n) ((n) << 2) +#define AF_ES_SM(n) ((n) << 1) +#define AF_ES_HM(n) ((n) << 0) + +#define ISP_REG_SC_AWB_PS_CFG_0 0x0c4 +#define AWB_PS_GU(n) ((n) << 24) +#define AWB_PS_GL(n) ((n) << 16) +#define AWB_PS_RU(n) ((n) << 8) +#define AWB_PS_RL(n) ((n) << 0) + +#define ISP_REG_SC_AWB_PS_CFG_1 0x0c8 +#define AWB_PS_YU(n) ((n) << 24) +#define AWB_PS_YL(n) ((n) << 16) +#define AWB_PS_BU(n) ((n) << 8) +#define AWB_PS_BL(n) ((n) << 0) + +#define ISP_REG_SC_AWB_PS_CFG_2 0x0cc +#define AWB_PS_GRU(n) ((n) << 16) +#define AWB_PS_GRL(n) ((n) << 0) + +#define ISP_REG_SC_AWB_PS_CFG_3 0x0d0 +#define AWB_PS_GBU(n) ((n) << 16) +#define AWB_PS_GBL(n) ((n) << 0) + +#define ISP_REG_SC_AWB_PS_CFG_4 0x0d4 +#define AWB_PS_GRBU(n) ((n) << 16) +#define AWB_PS_GRBL(n) ((n) << 0) + +#define ISP_REG_SC_DEC 0x0d8 +#define SC_DEC_V_KEEP(n) ((n) << 24) +#define SC_DEC_V_PERIOD(n) ((n) << 16) +#define SC_DEC_H_KEEP(n) ((n) << 8) +#define SC_DEC_H_PERIOD(n) ((n) << 0) + #define ISP_REG_LCCF_CFG_2 0x0e0 #define ISP_REG_LCCF_CFG_3 0x0e4 #define ISP_REG_LCCF_CFG_4 0x0e8 @@ -123,6 +179,8 @@ #define ISP_REG_OECF_X0_CFG6 0x118 #define ISP_REG_OECF_X0_CFG7 0x11c =20 +#define ISP_REG_OECF_Y0_CFG0 0x180 + #define ISP_REG_OECF_Y3_CFG0 0x1e0 #define ISP_REG_OECF_Y3_CFG1 0x1e4 #define ISP_REG_OECF_Y3_CFG2 0x1e8 @@ -187,6 +245,49 @@ #define OFFSET_B_POINT(x) ((x) << 8) #define OFFSET_A_POINT(x) ((x) << 0) =20 +#define ISP_REG_SC_AWB_WS_CW0_CFG_0 0x4d0 +#define ISP_REG_SC_AWB_WS_CW0_CFG_1 0x4d4 +#define AWB_WS_CW_W_7(x) ((x) << 28) +#define AWB_WS_CW_W_6(x) ((x) << 24) +#define AWB_WS_CW_W_5(x) ((x) << 20) +#define AWB_WS_CW_W_4(x) ((x) << 16) +#define AWB_WS_CW_W_3(x) ((x) << 12) +#define AWB_WS_CW_W_2(x) ((x) << 8) +#define AWB_WS_CW_W_1(x) ((x) << 4) +#define AWB_WS_CW_W_0(x) ((x) << 0) + +#define ISP_REG_SC_AWB_WS_IWV_CFG_0 0x538 +#define ISP_REG_SC_AWB_WS_IWV_CFG_1 0x53c +#define AWB_WS_IW_V_7(x) ((x) << 28) +#define AWB_WS_IW_V_6(x) ((x) << 24) +#define AWB_WS_IW_V_5(x) ((x) << 20) +#define AWB_WS_IW_V_4(x) ((x) << 16) +#define AWB_WS_IW_V_3(x) ((x) << 12) +#define AWB_WS_IW_V_2(x) ((x) << 8) +#define AWB_WS_IW_V_1(x) ((x) << 4) +#define AWB_WS_IW_V_0(x) ((x) << 0) + +#define ISP_REG_SC_AWB_WS_IWS_CFG_0 0x540 +#define ISP_REG_SC_AWB_WS_IWS_CFG_1 0x544 +#define ISP_REG_SC_AWB_WS_IWS_CFG_2 0x548 +#define ISP_REG_SC_AWB_WS_IWS_CFG_3 0x54c +#define AWB_WS_IW_S_3(x) ((x) << 24) +#define AWB_WS_IW_S_2(x) ((x) << 16) +#define AWB_WS_IW_S_1(x) ((x) << 8) +#define AWB_WS_IW_S_0(x) ((x) << 0) + +#define ISP_REG_SC_AWB_WS_CFG_0 0x5d0 +#define AWB_WS_GRU(n) ((n) << 24) +#define AWB_WS_GRL(n) ((n) << 16) +#define AWB_WS_RU(n) ((n) << 8) +#define AWB_WS_RL(n) ((n) << 0) + +#define ISP_REG_SC_AWB_WS_CFG_1 0x5d4 +#define AWB_WS_BU(n) ((n) << 24) +#define AWB_WS_BL(n) ((n) << 16) +#define AWB_WS_GBU(n) ((n) << 8) +#define AWB_WS_GBL(n) ((n) << 0) + #define ISP_REG_ISP_CTRL_0 0xa00 #define ISPC_LINE BIT(27) #define ISPC_SC BIT(26) @@ -298,8 +399,19 @@ #define CURVE_D_L(n) ((n) << 0) =20 #define ISP_REG_ICAMD_0 0xc40 +#define ISP_REG_ICAMD_1 0xc44 #define ISP_REG_ICAMD_12 0xc70 +#define ISP_REG_ICAMD_13 0xc74 +#define ISP_REG_ICAMD_14 0xc78 +#define ISP_REG_ICAMD_15 0xc7c +#define ISP_REG_ICAMD_16 0xc80 +#define ISP_REG_ICAMD_17 0xc84 +#define ISP_REG_ICAMD_18 0xc88 +#define ISP_REG_ICAMD_19 0xc8c #define ISP_REG_ICAMD_20 0xc90 +#define ISP_REG_ICAMD_21 0xc94 +#define ISP_REG_ICAMD_22 0xc98 +#define ISP_REG_ICAMD_23 0xc9c #define ISP_REG_ICAMD_24 0xca0 #define ISP_REG_ICAMD_25 0xca4 #define DNRM_F(n) ((n) << 16) @@ -396,6 +508,30 @@ enum stf_isp_pad_id { STF_ISP_PAD_MAX }; =20 +enum stf_isp_modules_index { + imi_obc =3D 0, + imi_oecf, + imi_lccf, + imi_awb, + imi_sc, + imi_cfa, + imi_car, + imi_ccm, + imi_gmargb, + imi_r2y, + imi_shrp, + imi_sat, + imi_dnyuv, + imi_ycrv, + imi_ctc, + imi_dbc, +}; + +struct stf_isp_module_info { + u32 en_reg; + u8 en_nbit; +}; + struct stf_isp_format { u32 code; u8 bpp; @@ -414,6 +550,7 @@ struct stf_isp_dev { unsigned int nformats; struct v4l2_subdev *source_subdev; const struct stf_isp_format *current_fmt; + struct v4l2_ctrl_handler handler; }; =20 int stf_isp_reset(struct stf_isp_dev *isp_dev); @@ -425,4 +562,21 @@ int stf_isp_init(struct stfcamss *stfcamss); int stf_isp_register(struct stf_isp_dev *isp_dev, struct v4l2_device *v4l2= _dev); int stf_isp_unregister(struct stf_isp_dev *isp_dev); =20 +int isp_set_ctrl_wb(struct stf_isp_dev *isp_dev, const void *value); +int isp_set_ctrl_car(struct stf_isp_dev *isp_dev, const void *value); +int isp_set_ctrl_ccm(struct stf_isp_dev *isp_dev, const void *value); +int isp_set_ctrl_cfa(struct stf_isp_dev *isp_dev, const void *value); +int isp_set_ctrl_ctc(struct stf_isp_dev *isp_dev, const void *value); +int isp_set_ctrl_dbc(struct stf_isp_dev *isp_dev, const void *value); +int isp_set_ctrl_dnyuv(struct stf_isp_dev *isp_dev, const void *value); +int isp_set_ctrl_gmargb(struct stf_isp_dev *isp_dev, const void *value); +int isp_set_ctrl_lccf(struct stf_isp_dev *isp_dev, const void *value); +int isp_set_ctrl_obc(struct stf_isp_dev *isp_dev, const void *value); +int isp_set_ctrl_oecf(struct stf_isp_dev *isp_dev, const void *value); +int isp_set_ctrl_r2y(struct stf_isp_dev *isp_dev, const void *value); +int isp_set_ctrl_sat(struct stf_isp_dev *isp_dev, const void *value); +int isp_set_ctrl_shrp(struct stf_isp_dev *isp_dev, const void *value); +int isp_set_ctrl_ycrv(struct stf_isp_dev *isp_dev, const void *value); +int isp_set_ctrl_sc(struct stf_isp_dev *isp_dev, const void *value); + #endif /* STF_ISP_H */ --=20 2.25.1 From nobody Sun Dec 28 00:46:12 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4B276C4332F for ; Thu, 14 Dec 2023 06:51:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1443285AbjLNGuw convert rfc822-to-8bit (ORCPT ); Thu, 14 Dec 2023 01:50:52 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32822 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234318AbjLNGug (ORCPT ); Thu, 14 Dec 2023 01:50:36 -0500 Received: from fd01.gateway.ufhost.com (fd01.gateway.ufhost.com [61.152.239.71]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 07608106; Wed, 13 Dec 2023 22:50:43 -0800 (PST) Received: from EXMBX165.cuchost.com (unknown [175.102.18.54]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "EXMBX165", Issuer "EXMBX165" (not verified)) by fd01.gateway.ufhost.com (Postfix) with ESMTP id 72E308175; Thu, 14 Dec 2023 14:50:36 +0800 (CST) Received: from EXMBX062.cuchost.com (172.16.6.62) by EXMBX165.cuchost.com (172.16.6.75) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Thu, 14 Dec 2023 14:50:36 +0800 Received: from ubuntu.mshome.net (113.72.145.168) by EXMBX062.cuchost.com (172.16.6.62) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Thu, 14 Dec 2023 14:50:33 +0800 From: Changhuang Liang To: Mauro Carvalho Chehab , Greg Kroah-Hartman , Hans Verkuil , "Marvin Lin" , Bryan O'Donoghue , "Ming Qian" , Laurent Pinchart , Nicolas Dufresne , Benjamin Gaignard , Tomi Valkeinen , Mingjia Zhang , Geert Uytterhoeven , Sakari Ailus , Dan Carpenter CC: Jack Zhu , Changhuang Liang , , , Subject: [PATCH v1 3/9] media: videodev2.h, v4l2-ioctl: Add StarFive ISP meta buffer format Date: Wed, 13 Dec 2023 22:50:21 -0800 Message-ID: <20231214065027.28564-4-changhuang.liang@starfivetech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231214065027.28564-1-changhuang.liang@starfivetech.com> References: <20231214065027.28564-1-changhuang.liang@starfivetech.com> MIME-Version: 1.0 X-Originating-IP: [113.72.145.168] X-ClientProxiedBy: EXCAS061.cuchost.com (172.16.6.21) To EXMBX062.cuchost.com (172.16.6.62) X-YovoleRuleAgent: yovoleflag Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add the StarFive ISP specific metadata format V4L2_META_FMT_STF_ISP_STAT_3A for 3A. Signed-off-by: Changhuang Liang --- drivers/media/v4l2-core/v4l2-ioctl.c | 1 + include/uapi/linux/videodev2.h | 3 +++ 2 files changed, 4 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core= /v4l2-ioctl.c index 33076af4dfdb..dfc031e575e9 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1445,6 +1445,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_META_FMT_VIVID: descr =3D "Vivid Metadata"; break; case V4L2_META_FMT_RK_ISP1_PARAMS: descr =3D "Rockchip ISP1 3A Parameters= "; break; case V4L2_META_FMT_RK_ISP1_STAT_3A: descr =3D "Rockchip ISP1 3A Statistic= s"; break; + case V4L2_META_FMT_STF_ISP_STAT_3A: descr =3D "StarFive ISP 3A Statistics= "; break; case V4L2_PIX_FMT_NV12_8L128: descr =3D "NV12 (8x128 Linear)"; break; case V4L2_PIX_FMT_NV12M_8L128: descr =3D "NV12M (8x128 Linear)"; break; case V4L2_PIX_FMT_NV12_10BE_8L128: descr =3D "10-bit NV12 (8x128 Linear, = BE)"; break; diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 68e7ac178cc2..0c3d19a1c8cf 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -839,6 +839,9 @@ struct v4l2_pix_format { #define V4L2_META_FMT_RK_ISP1_PARAMS v4l2_fourcc('R', 'K', '1', 'P') /* Ro= ckchip ISP1 3A Parameters */ #define V4L2_META_FMT_RK_ISP1_STAT_3A v4l2_fourcc('R', 'K', '1', 'S') /* R= ockchip ISP1 3A Statistics */ =20 +/* Vendor specific - used for StarFive JH7110 ISP camera sub-system */ +#define V4L2_META_FMT_STF_ISP_STAT_3A v4l2_fourcc('S', 'T', 'F', 'S') /* S= tarFive ISP 3A Statistics */ + /* priv field value to indicates that subsequent fields are valid. */ #define V4L2_PIX_FMT_PRIV_MAGIC 0xfeedcafe =20 --=20 2.25.1 From nobody Sun Dec 28 00:46:12 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B7775C4332F for ; Thu, 14 Dec 2023 06:50:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1443272AbjLNGur convert rfc822-to-8bit (ORCPT ); Thu, 14 Dec 2023 01:50:47 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32808 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234303AbjLNGug (ORCPT ); Thu, 14 Dec 2023 01:50:36 -0500 Received: from fd01.gateway.ufhost.com (fd01.gateway.ufhost.com [61.152.239.71]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E2596E8; Wed, 13 Dec 2023 22:50:39 -0800 (PST) Received: from EXMBX166.cuchost.com (unknown [175.102.18.54]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "EXMBX166", Issuer "EXMBX166" (not verified)) by fd01.gateway.ufhost.com (Postfix) with ESMTP id 9D252814B; Thu, 14 Dec 2023 14:50:38 +0800 (CST) Received: from EXMBX062.cuchost.com (172.16.6.62) by EXMBX166.cuchost.com (172.16.6.76) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Thu, 14 Dec 2023 14:50:38 +0800 Received: from ubuntu.mshome.net (113.72.145.168) by EXMBX062.cuchost.com (172.16.6.62) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Thu, 14 Dec 2023 14:50:35 +0800 From: Changhuang Liang To: Mauro Carvalho Chehab , Greg Kroah-Hartman , Hans Verkuil , "Marvin Lin" , Bryan O'Donoghue , "Ming Qian" , Laurent Pinchart , Nicolas Dufresne , Benjamin Gaignard , Tomi Valkeinen , Mingjia Zhang , Geert Uytterhoeven , Sakari Ailus , Dan Carpenter CC: Jack Zhu , Changhuang Liang , , , Subject: [PATCH v1 4/9] staging: media: starfive: camss: Replace format index with pad Date: Wed, 13 Dec 2023 22:50:22 -0800 Message-ID: <20231214065027.28564-5-changhuang.liang@starfivetech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231214065027.28564-1-changhuang.liang@starfivetech.com> References: <20231214065027.28564-1-changhuang.liang@starfivetech.com> MIME-Version: 1.0 X-Originating-IP: [113.72.145.168] X-ClientProxiedBy: EXCAS061.cuchost.com (172.16.6.21) To EXMBX062.cuchost.com (172.16.6.62) X-YovoleRuleAgent: yovoleflag Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Replace format index with pad. Signed-off-by: Changhuang Liang --- drivers/staging/media/starfive/camss/stf-isp.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/staging/media/starfive/camss/stf-isp.c b/drivers/stagi= ng/media/starfive/camss/stf-isp.c index ac83f23842df..c3ae02cf6dd8 100644 --- a/drivers/staging/media/starfive/camss/stf-isp.c +++ b/drivers/staging/media/starfive/camss/stf-isp.c @@ -11,9 +11,6 @@ =20 #include "stf-camss.h" =20 -#define SINK_FORMATS_INDEX 0 -#define SOURCE_FORMATS_INDEX 1 - static int isp_set_selection(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, struct v4l2_subdev_selection *sel); @@ -95,11 +92,7 @@ static void isp_try_format(struct stf_isp_dev *isp_dev, return; } =20 - if (pad =3D=3D STF_ISP_PAD_SINK) - formats =3D &isp_dev->formats[SINK_FORMATS_INDEX]; - else if (pad =3D=3D STF_ISP_PAD_SRC) - formats =3D &isp_dev->formats[SOURCE_FORMATS_INDEX]; - + formats =3D &isp_dev->formats[pad]; fmt->width =3D clamp_t(u32, fmt->width, STFCAMSS_FRAME_MIN_WIDTH, STFCAMSS_FRAME_MAX_WIDTH); fmt->height =3D clamp_t(u32, fmt->height, STFCAMSS_FRAME_MIN_HEIGHT, @@ -124,7 +117,7 @@ static int isp_enum_mbus_code(struct v4l2_subdev *sd, if (code->index >=3D ARRAY_SIZE(isp_formats_sink)) return -EINVAL; =20 - formats =3D &isp_dev->formats[SINK_FORMATS_INDEX]; + formats =3D &isp_dev->formats[code->pad]; code->code =3D formats->fmts[code->index].code; } else { struct v4l2_mbus_framefmt *sink_fmt; --=20 2.25.1 From nobody Sun Dec 28 00:46:12 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B3DF3C4332F for ; Thu, 14 Dec 2023 06:51:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1443304AbjLNGu6 convert rfc822-to-8bit (ORCPT ); Thu, 14 Dec 2023 01:50:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32836 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234331AbjLNGui (ORCPT ); Thu, 14 Dec 2023 01:50:38 -0500 Received: from ex01.ufhost.com (ex01.ufhost.com [61.152.239.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 73AB5100; Wed, 13 Dec 2023 22:50:42 -0800 (PST) Received: from EXMBX165.cuchost.com (unknown [175.102.18.54]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "EXMBX165", Issuer "EXMBX165" (not verified)) by ex01.ufhost.com (Postfix) with ESMTP id 43CAE24E2CC; Thu, 14 Dec 2023 14:50:41 +0800 (CST) Received: from EXMBX062.cuchost.com (172.16.6.62) by EXMBX165.cuchost.com (172.16.6.75) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Thu, 14 Dec 2023 14:50:41 +0800 Received: from ubuntu.mshome.net (113.72.145.168) by EXMBX062.cuchost.com (172.16.6.62) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Thu, 14 Dec 2023 14:50:39 +0800 From: Changhuang Liang To: Mauro Carvalho Chehab , Greg Kroah-Hartman , Hans Verkuil , "Marvin Lin" , Bryan O'Donoghue , "Ming Qian" , Laurent Pinchart , Nicolas Dufresne , Benjamin Gaignard , Tomi Valkeinen , Mingjia Zhang , Geert Uytterhoeven , Sakari Ailus , Dan Carpenter CC: Jack Zhu , Changhuang Liang , , , Subject: [PATCH v1 5/9] staging: media: starfive: camss: Add for StarFive ISP 3A Date: Wed, 13 Dec 2023 22:50:23 -0800 Message-ID: <20231214065027.28564-6-changhuang.liang@starfivetech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231214065027.28564-1-changhuang.liang@starfivetech.com> References: <20231214065027.28564-1-changhuang.liang@starfivetech.com> MIME-Version: 1.0 X-Originating-IP: [113.72.145.168] X-ClientProxiedBy: EXCAS061.cuchost.com (172.16.6.21) To EXMBX062.cuchost.com (172.16.6.62) X-YovoleRuleAgent: yovoleflag Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add for StarFive ISP 3A. Signed-off-by: Changhuang Liang --- .../staging/media/starfive/camss/stf-camss.c | 8 + .../media/starfive/camss/stf-capture.c | 89 ++++++++++- .../staging/media/starfive/camss/stf-isp.c | 58 ++++++- .../staging/media/starfive/camss/stf-isp.h | 14 ++ .../staging/media/starfive/camss/stf-video.c | 143 +++++++++++++++++- .../staging/media/starfive/camss/stf-video.h | 2 + 6 files changed, 295 insertions(+), 19 deletions(-) diff --git a/drivers/staging/media/starfive/camss/stf-camss.c b/drivers/sta= ging/media/starfive/camss/stf-camss.c index a587f860101a..3175d0d9a05c 100644 --- a/drivers/staging/media/starfive/camss/stf-camss.c +++ b/drivers/staging/media/starfive/camss/stf-camss.c @@ -126,6 +126,7 @@ static int stfcamss_of_parse_ports(struct stfcamss *stf= camss) static int stfcamss_register_devs(struct stfcamss *stfcamss) { struct stf_capture *cap_yuv =3D &stfcamss->captures[STF_CAPTURE_YUV]; + struct stf_capture *cap_scd =3D &stfcamss->captures[STF_CAPTURE_SCD]; struct stf_isp_dev *isp_dev =3D &stfcamss->isp_dev; int ret; =20 @@ -150,6 +151,13 @@ static int stfcamss_register_devs(struct stfcamss *stf= camss) =20 cap_yuv->video.source_subdev =3D &isp_dev->subdev; =20 + ret =3D media_create_pad_link(&isp_dev->subdev.entity, STF_ISP_PAD_SRC_SC= D, + &cap_scd->video.vdev.entity, 0, 0); + if (ret) + goto err_cap_unregister; + + cap_scd->video.source_subdev =3D &isp_dev->subdev; + return ret; =20 err_cap_unregister: diff --git a/drivers/staging/media/starfive/camss/stf-capture.c b/drivers/s= taging/media/starfive/camss/stf-capture.c index 70c24b050a1b..6a137a273c8a 100644 --- a/drivers/staging/media/starfive/camss/stf-capture.c +++ b/drivers/staging/media/starfive/camss/stf-capture.c @@ -12,6 +12,7 @@ static const char * const stf_cap_names[] =3D { "capture_raw", "capture_yuv", + "capture_scd", }; =20 static const struct stfcamss_format_info stf_wr_fmts[] =3D { @@ -55,6 +56,14 @@ static const struct stfcamss_format_info stf_isp_fmts[] = =3D { }, }; =20 +/* 3A Statistics Collection Data */ +static const struct stfcamss_format_info stf_isp_scd_fmts[] =3D { + { + .code =3D MEDIA_BUS_FMT_METADATA_FIXED, + .pixelformat =3D V4L2_META_FMT_STF_ISP_STAT_3A, + }, +}; + static inline struct stf_capture *to_stf_capture(struct stfcamss_video *vi= deo) { return container_of(video, struct stf_capture, video); @@ -73,6 +82,49 @@ static void stf_set_yuv_addr(struct stfcamss *stfcamss, stf_isp_reg_write(stfcamss, ISP_REG_UV_PLANE_START_ADDR, uv_addr); } =20 +static enum stf_isp_type_scd stf_get_isp_scd_type(struct stfcamss *stfcams= s) +{ + int val; + + val =3D stf_isp_reg_read(stfcamss, ISP_REG_SC_CFG_1); + return (enum stf_isp_type_scd)(val & ISP_SC_SEL_MASK) >> 30; +} + +static void stf_set_scd_addr(struct stfcamss *stfcamss, + dma_addr_t yhist_addr, dma_addr_t scd_addr, + enum stf_isp_type_scd type_scd) +{ + stf_isp_reg_set_bit(stfcamss, ISP_REG_SC_CFG_1, ISP_SC_SEL_MASK, + SEL_TYPE(type_scd)); + stf_isp_reg_write(stfcamss, ISP_REG_SCD_CFG_0, scd_addr); + stf_isp_reg_write(stfcamss, ISP_REG_YHIST_CFG_4, yhist_addr); +} + +static void stf_isp_fill_yhist(struct stfcamss *stfcamss, void *vaddr_sc) +{ + struct jh7110_isp_sc_buffer *sc =3D (struct jh7110_isp_sc_buffer *)vaddr_= sc; + u32 reg_addr =3D ISP_REG_YHIST_ACC_0; + u32 i; + + for (i =3D 0; i < 64; i++, reg_addr +=3D 4) + sc->y_histogram[i] =3D stf_isp_reg_read(stfcamss, reg_addr); +} + +static void stf_isp_fill_flag(struct stfcamss *stfcamss, void *vaddr_sc, + enum stf_isp_type_scd *type_scd) +{ + struct jh7110_isp_sc_buffer *sc =3D (struct jh7110_isp_sc_buffer *)vaddr_= sc; + + *type_scd =3D stf_get_isp_scd_type(stfcamss); + if (*type_scd =3D=3D TYPE_AWB) { + sc->flag =3D JH7110_ISP_SC_FALG_VALID; + *type_scd =3D TYPE_OECF; + } else { + sc->flag =3D JH7110_ISP_SC_FALG_INVALID; + *type_scd =3D TYPE_AWB; + } +} + static void stf_init_addrs(struct stfcamss_video *video) { struct stf_capture *cap =3D to_stf_capture(video); @@ -91,6 +143,8 @@ static void stf_init_addrs(struct stfcamss_video *video) stf_set_raw_addr(video->stfcamss, addr0); else if (cap->type =3D=3D STF_CAPTURE_YUV) stf_set_yuv_addr(video->stfcamss, addr0, addr1); + else + stf_set_scd_addr(video->stfcamss, addr0, addr1, TYPE_AWB); } =20 static struct stfcamss_buffer *stf_buf_get_pending(struct stf_v_buf *outpu= t) @@ -248,18 +302,24 @@ static void stf_capture_init(struct stfcamss *stfcams= s, struct stf_capture *cap) INIT_LIST_HEAD(&cap->buffers.ready_bufs); spin_lock_init(&cap->buffers.lock); =20 - cap->video.type =3D V4L2_BUF_TYPE_VIDEO_CAPTURE; cap->video.stfcamss =3D stfcamss; cap->video.bpl_alignment =3D 16 * 8; =20 if (cap->type =3D=3D STF_CAPTURE_RAW) { + cap->video.type =3D V4L2_BUF_TYPE_VIDEO_CAPTURE; cap->video.formats =3D stf_wr_fmts; cap->video.nformats =3D ARRAY_SIZE(stf_wr_fmts); cap->video.bpl_alignment =3D 8; } else if (cap->type =3D=3D STF_CAPTURE_YUV) { + cap->video.type =3D V4L2_BUF_TYPE_VIDEO_CAPTURE; cap->video.formats =3D stf_isp_fmts; cap->video.nformats =3D ARRAY_SIZE(stf_isp_fmts); cap->video.bpl_alignment =3D 1; + } else { + cap->video.type =3D V4L2_BUF_TYPE_META_CAPTURE; + cap->video.formats =3D stf_isp_scd_fmts; + cap->video.nformats =3D ARRAY_SIZE(stf_isp_scd_fmts); + cap->video.bpl_alignment =3D 16 * 8; } } =20 @@ -371,6 +431,7 @@ static void stf_buf_flush(struct stf_v_buf *output, enu= m vb2_buffer_state state) static void stf_buf_done(struct stf_v_buf *output) { struct stfcamss_buffer *ready_buf; + struct stfcamss *stfcamss =3D cap->video.stfcamss; u64 ts =3D ktime_get_ns(); unsigned long flags; =20 @@ -381,6 +442,9 @@ static void stf_buf_done(struct stf_v_buf *output) spin_lock_irqsave(&output->lock, flags); =20 while ((ready_buf =3D stf_buf_get_ready(output))) { + if (cap->type =3D=3D STF_CAPTURE_SCD) + stf_isp_fill_yhist(stfcamss, ready_buf->vaddr_sc); + ready_buf->vb.vb2_buf.timestamp =3D ts; ready_buf->vb.sequence =3D output->sequence++; =20 @@ -399,6 +463,7 @@ static void stf_change_buffer(struct stf_v_buf *output) dma_addr_t *new_addr; unsigned long flags; u32 active_index; + enum stf_isp_type_scd type_scd; =20 if (output->state =3D=3D STF_OUTPUT_OFF || output->state =3D=3D STF_OUTPUT_STOPPING || @@ -437,10 +502,16 @@ static void stf_change_buffer(struct stf_v_buf *outpu= t) if (output->state =3D=3D STF_OUTPUT_STOPPING) { output->last_buffer =3D ready_buf; } else { - if (cap->type =3D=3D STF_CAPTURE_RAW) + if (cap->type =3D=3D STF_CAPTURE_RAW) { stf_set_raw_addr(stfcamss, new_addr[0]); - else if (cap->type =3D=3D STF_CAPTURE_YUV) + } else if (cap->type =3D=3D STF_CAPTURE_YUV) { stf_set_yuv_addr(stfcamss, new_addr[0], new_addr[1]); + } else { + stf_isp_fill_flag(stfcamss, ready_buf->vaddr_sc, + &type_scd); + stf_set_scd_addr(stfcamss, new_addr[0], + new_addr[1], type_scd); + } =20 stf_buf_add_ready(output, ready_buf); } @@ -469,6 +540,7 @@ irqreturn_t stf_isp_irq_handler(int irq, void *priv) { struct stfcamss *stfcamss =3D priv; struct stf_capture *cap =3D &stfcamss->captures[STF_CAPTURE_YUV]; + struct stf_capture *cap_scd =3D &stfcamss->captures[STF_CAPTURE_SCD]; u32 status; =20 status =3D stf_isp_reg_read(stfcamss, ISP_REG_ISP_CTRL_0); @@ -476,6 +548,9 @@ irqreturn_t stf_isp_irq_handler(int irq, void *priv) if (status & ISPC_ENUO) stf_buf_done(&cap->buffers); =20 + if (status & ISPC_SC) + stf_buf_done(&cap_scd->buffers); + stf_isp_reg_write(stfcamss, ISP_REG_ISP_CTRL_0, (status & ~ISPC_INT_ALL_MASK) | ISPC_ISP | ISPC_CSI | ISPC_SC); @@ -488,13 +563,19 @@ irqreturn_t stf_line_irq_handler(int irq, void *priv) { struct stfcamss *stfcamss =3D priv; struct stf_capture *cap =3D &stfcamss->captures[STF_CAPTURE_YUV]; + struct stf_capture *cap_scd =3D &stfcamss->captures[STF_CAPTURE_SCD]; u32 status; + u32 value; =20 status =3D stf_isp_reg_read(stfcamss, ISP_REG_ISP_CTRL_0); if (status & ISPC_LINE) { if (atomic_dec_if_positive(&cap->buffers.frame_skip) < 0) { if ((status & ISPC_ENUO)) stf_change_buffer(&cap->buffers); + + value =3D stf_isp_reg_read(stfcamss, ISP_REG_CSI_MODULE_CFG); + if (value & CSI_SC_EN) + stf_change_buffer(&cap_scd->buffers); } =20 stf_isp_reg_set_bit(stfcamss, ISP_REG_CSIINTS, @@ -571,9 +652,11 @@ void stf_capture_unregister(struct stfcamss *stfcamss) { struct stf_capture *cap_raw =3D &stfcamss->captures[STF_CAPTURE_RAW]; struct stf_capture *cap_yuv =3D &stfcamss->captures[STF_CAPTURE_YUV]; + struct stf_capture *cap_scd =3D &stfcamss->captures[STF_CAPTURE_SCD]; =20 stf_capture_unregister_one(cap_raw); stf_capture_unregister_one(cap_yuv); + stf_capture_unregister_one(cap_scd); } =20 int stf_capture_register(struct stfcamss *stfcamss, diff --git a/drivers/staging/media/starfive/camss/stf-isp.c b/drivers/stagi= ng/media/starfive/camss/stf-isp.c index c3ae02cf6dd8..aaa17bfc2bb8 100644 --- a/drivers/staging/media/starfive/camss/stf-isp.c +++ b/drivers/staging/media/starfive/camss/stf-isp.c @@ -26,9 +26,14 @@ static const struct stf_isp_format isp_formats_source[] = =3D { { MEDIA_BUS_FMT_YUYV8_1_5X8, 8 }, }; =20 +static const struct stf_isp_format isp_formats_source_scd[] =3D { + { MEDIA_BUS_FMT_METADATA_FIXED }, +}; + static const struct stf_isp_format_table isp_formats_st7110[] =3D { { isp_formats_sink, ARRAY_SIZE(isp_formats_sink) }, { isp_formats_source, ARRAY_SIZE(isp_formats_source) }, + { isp_formats_source_scd, ARRAY_SIZE(isp_formats_source_scd) }, }; =20 static const struct stf_isp_format * @@ -93,13 +98,20 @@ static void isp_try_format(struct stf_isp_dev *isp_dev, } =20 formats =3D &isp_dev->formats[pad]; - fmt->width =3D clamp_t(u32, fmt->width, STFCAMSS_FRAME_MIN_WIDTH, - STFCAMSS_FRAME_MAX_WIDTH); - fmt->height =3D clamp_t(u32, fmt->height, STFCAMSS_FRAME_MIN_HEIGHT, - STFCAMSS_FRAME_MAX_HEIGHT); - fmt->height &=3D ~0x1; + + if (pad !=3D STF_ISP_PAD_SRC_SCD) { + fmt->width =3D clamp_t(u32, fmt->width, STFCAMSS_FRAME_MIN_WIDTH, + STFCAMSS_FRAME_MAX_WIDTH); + fmt->height =3D clamp_t(u32, fmt->height, STFCAMSS_FRAME_MIN_HEIGHT, + STFCAMSS_FRAME_MAX_HEIGHT); + fmt->height &=3D ~0x1; + fmt->colorspace =3D V4L2_COLORSPACE_SRGB; + } else { + fmt->width =3D 1; + fmt->height =3D 1; + } + fmt->field =3D V4L2_FIELD_NONE; - fmt->colorspace =3D V4L2_COLORSPACE_SRGB; fmt->flags =3D 0; =20 if (!stf_g_fmt_by_mcode(formats, fmt->code)) @@ -119,7 +131,7 @@ static int isp_enum_mbus_code(struct v4l2_subdev *sd, =20 formats =3D &isp_dev->formats[code->pad]; code->code =3D formats->fmts[code->index].code; - } else { + } else if (code->pad =3D=3D STF_ISP_PAD_SRC) { struct v4l2_mbus_framefmt *sink_fmt; =20 if (code->index >=3D ARRAY_SIZE(isp_formats_source)) @@ -131,6 +143,10 @@ static int isp_enum_mbus_code(struct v4l2_subdev *sd, code->code =3D sink_fmt->code; if (!code->code) return -EINVAL; + } else { + if (code->index > 0) + return -EINVAL; + code->code =3D MEDIA_BUS_FMT_METADATA_FIXED; } code->flags =3D 0; =20 @@ -151,6 +167,9 @@ static int isp_set_format(struct v4l2_subdev *sd, isp_try_format(isp_dev, state, fmt->pad, &fmt->format); *format =3D fmt->format; =20 + if (fmt->pad =3D=3D STF_ISP_PAD_SRC_SCD) + return 0; + isp_dev->current_fmt =3D stf_g_fmt_by_mcode(&isp_dev->formats[fmt->pad], fmt->format.code); =20 @@ -202,6 +221,9 @@ static int isp_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_format fmt =3D { 0 }; struct v4l2_rect *rect; =20 + if (sel->pad =3D=3D STF_ISP_PAD_SRC_SCD) + return -EINVAL; + switch (sel->target) { case V4L2_SEL_TGT_CROP_BOUNDS: if (sel->pad =3D=3D STF_ISP_PAD_SINK) { @@ -239,6 +261,9 @@ static int isp_set_selection(struct v4l2_subdev *sd, struct stf_isp_dev *isp_dev =3D v4l2_get_subdevdata(sd); struct v4l2_rect *rect; =20 + if (sel->pad =3D=3D STF_ISP_PAD_SRC_SCD) + return -EINVAL; + if (sel->target !=3D V4L2_SEL_TGT_CROP) return -EINVAL; =20 @@ -296,8 +321,24 @@ static int isp_init_formats(struct v4l2_subdev *sd, .height =3D 1080 } }; + struct v4l2_subdev_format format_scd =3D { + .pad =3D STF_ISP_PAD_SRC_SCD, + .which =3D V4L2_SUBDEV_FORMAT_ACTIVE, + .format =3D { + .code =3D MEDIA_BUS_FMT_METADATA_FIXED, + .width =3D 1, + .height =3D 1 + } + }; + int ret; + + /* Init for STF_ISP_PAD_SINK and STF_ISP_PAD_SRC pad */ + ret =3D isp_set_format(sd, sd_state, &format); + if (ret < 0) + return ret; =20 - return isp_set_format(sd, sd_state, &format); + /* Init for STF_ISP_PAD_SRC_SCD pad */ + return isp_set_format(sd, sd_state, &format_scd); } =20 static const struct v4l2_subdev_core_ops isp_core_ops =3D { @@ -631,6 +672,7 @@ int stf_isp_register(struct stf_isp_dev *isp_dev, struc= t v4l2_device *v4l2_dev) =20 pads[STF_ISP_PAD_SINK].flags =3D MEDIA_PAD_FL_SINK; pads[STF_ISP_PAD_SRC].flags =3D MEDIA_PAD_FL_SOURCE; + pads[STF_ISP_PAD_SRC_SCD].flags =3D MEDIA_PAD_FL_SOURCE; =20 sd->entity.function =3D MEDIA_ENT_F_PROC_VIDEO_ISP; sd->entity.ops =3D &isp_media_ops; diff --git a/drivers/staging/media/starfive/camss/stf-isp.h b/drivers/stagi= ng/media/starfive/camss/stf-isp.h index 1d98754964ce..bfb7196cefff 100644 --- a/drivers/staging/media/starfive/camss/stf-isp.h +++ b/drivers/staging/media/starfive/camss/stf-isp.h @@ -417,6 +417,10 @@ #define DNRM_F(n) ((n) << 16) #define CCM_M_DAT(n) ((n) << 0) =20 +#define ISP_REG_YHIST_CFG_4 0xcd8 + +#define ISP_REG_YHIST_ACC_0 0xd00 + #define ISP_REG_GAMMA_VAL0 0xe00 #define ISP_REG_GAMMA_VAL1 0xe04 #define ISP_REG_GAMMA_VAL2 0xe08 @@ -501,10 +505,20 @@ #define IMAGE_MAX_WIDTH 1920 #define IMAGE_MAX_HEIGH 1080 =20 +#define ISP_YHIST_BUFFER_SIZE (64 * sizeof(__u32)) + +enum stf_isp_type_scd { + TYPE_DEC =3D 0, + TYPE_OBC, + TYPE_OECF, + TYPE_AWB, +}; + /* pad id for media framework */ enum stf_isp_pad_id { STF_ISP_PAD_SINK =3D 0, STF_ISP_PAD_SRC, + STF_ISP_PAD_SRC_SCD, STF_ISP_PAD_MAX }; =20 diff --git a/drivers/staging/media/starfive/camss/stf-video.c b/drivers/sta= ging/media/starfive/camss/stf-video.c index 0b305f21eb53..f617b7b00491 100644 --- a/drivers/staging/media/starfive/camss/stf-video.c +++ b/drivers/staging/media/starfive/camss/stf-video.c @@ -125,6 +125,14 @@ static int stf_video_init_format(struct stfcamss_video= *video) return 0; } =20 +static int stf_video_scd_init_format(struct stfcamss_video *video) +{ + video->active_fmt.fmt.meta.dataformat =3D video->formats[0].pixelformat; + video->active_fmt.fmt.meta.buffersize =3D sizeof(struct jh7110_isp_sc_buf= fer); + + return 0; +} + /* -----------------------------------------------------------------------= ------ * Video queue operations */ @@ -330,6 +338,75 @@ static const struct vb2_ops stf_video_vb2_q_ops =3D { .stop_streaming =3D video_stop_streaming, }; =20 +static int video_scd_queue_setup(struct vb2_queue *q, + unsigned int *num_buffers, + unsigned int *num_planes, + unsigned int sizes[], + struct device *alloc_devs[]) +{ + *num_planes =3D 1; + sizes[0] =3D sizeof(struct jh7110_isp_sc_buffer); + + return 0; +} + +static int video_scd_buf_init(struct vb2_buffer *vb) +{ + struct vb2_v4l2_buffer *vbuf =3D to_vb2_v4l2_buffer(vb); + struct stfcamss_buffer *buffer =3D to_stfcamss_buffer(vbuf); + dma_addr_t *paddr; + + paddr =3D vb2_plane_cookie(vb, 0); + buffer->addr[0] =3D *paddr; + buffer->addr[1] =3D buffer->addr[0] + ISP_YHIST_BUFFER_SIZE; + buffer->vaddr_sc =3D vb2_plane_vaddr(vb, 0); + + return 0; +} + +static int video_scd_buf_prepare(struct vb2_buffer *vb) +{ + struct vb2_v4l2_buffer *vbuf =3D to_vb2_v4l2_buffer(vb); + + if (sizeof(struct jh7110_isp_sc_buffer) > vb2_plane_size(vb, 0)) + return -EINVAL; + + vb2_set_plane_payload(vb, 0, sizeof(struct jh7110_isp_sc_buffer)); + + vbuf->field =3D V4L2_FIELD_NONE; + + return 0; +} + +static int video_scd_start_streaming(struct vb2_queue *q, unsigned int cou= nt) +{ + struct stfcamss_video *video =3D vb2_get_drv_priv(q); + + video->ops->start_streaming(video); + + return 0; +} + +static void video_scd_stop_streaming(struct vb2_queue *q) +{ + struct stfcamss_video *video =3D vb2_get_drv_priv(q); + + video->ops->stop_streaming(video); + + video->ops->flush_buffers(video, VB2_BUF_STATE_ERROR); +} + +static const struct vb2_ops stf_video_scd_vb2_q_ops =3D { + .queue_setup =3D video_scd_queue_setup, + .wait_prepare =3D vb2_ops_wait_prepare, + .wait_finish =3D vb2_ops_wait_finish, + .buf_init =3D video_scd_buf_init, + .buf_prepare =3D video_scd_buf_prepare, + .buf_queue =3D video_buf_queue, + .start_streaming =3D video_scd_start_streaming, + .stop_streaming =3D video_scd_stop_streaming, +}; + /* -----------------------------------------------------------------------= ------ * V4L2 ioctls */ @@ -448,6 +525,37 @@ static const struct v4l2_ioctl_ops stf_vid_ioctl_ops = =3D { .vidioc_streamoff =3D vb2_ioctl_streamoff, }; =20 +static int video_scd_g_fmt(struct file *file, void *fh, struct v4l2_format= *f) +{ + struct stfcamss_video *video =3D video_drvdata(file); + struct v4l2_meta_format *meta =3D &f->fmt.meta; + + if (f->type !=3D video->type) + return -EINVAL; + + meta->dataformat =3D video->active_fmt.fmt.meta.dataformat; + meta->buffersize =3D video->active_fmt.fmt.meta.buffersize; + + return 0; +} + +static const struct v4l2_ioctl_ops stf_vid_scd_ioctl_ops =3D { + .vidioc_querycap =3D video_querycap, + .vidioc_enum_fmt_meta_cap =3D video_enum_fmt, + .vidioc_g_fmt_meta_cap =3D video_scd_g_fmt, + .vidioc_s_fmt_meta_cap =3D video_scd_g_fmt, + .vidioc_try_fmt_meta_cap =3D video_scd_g_fmt, + .vidioc_reqbufs =3D vb2_ioctl_reqbufs, + .vidioc_querybuf =3D vb2_ioctl_querybuf, + .vidioc_qbuf =3D vb2_ioctl_qbuf, + .vidioc_expbuf =3D vb2_ioctl_expbuf, + .vidioc_dqbuf =3D vb2_ioctl_dqbuf, + .vidioc_create_bufs =3D vb2_ioctl_create_bufs, + .vidioc_prepare_buf =3D vb2_ioctl_prepare_buf, + .vidioc_streamon =3D vb2_ioctl_streamon, + .vidioc_streamoff =3D vb2_ioctl_streamoff, +}; + /* -----------------------------------------------------------------------= ------ * V4L2 file operations */ @@ -473,6 +581,9 @@ static int stf_link_validate(struct media_link *link) struct stfcamss_video *video =3D video_get_drvdata(vdev); int ret; =20 + if (video->type =3D=3D V4L2_BUF_TYPE_META_CAPTURE) + return 0; + ret =3D stf_video_check_format(video); =20 return ret; @@ -506,7 +617,11 @@ int stf_video_register(struct stfcamss_video *video, q =3D &video->vb2_q; q->drv_priv =3D video; q->mem_ops =3D &vb2_dma_contig_memops; - q->ops =3D &stf_video_vb2_q_ops; + + if (video->type =3D=3D V4L2_BUF_TYPE_VIDEO_CAPTURE) + q->ops =3D &stf_video_vb2_q_ops; + else + q->ops =3D &stf_video_scd_vb2_q_ops; q->type =3D video->type; q->io_modes =3D VB2_DMABUF | VB2_MMAP; q->timestamp_flags =3D V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; @@ -529,16 +644,28 @@ int stf_video_register(struct stfcamss_video *video, goto err_mutex_destroy; } =20 - ret =3D stf_video_init_format(video); - if (ret < 0) { - dev_err(video->stfcamss->dev, - "Failed to init format: %d\n", ret); - goto err_media_cleanup; + if (video->type =3D=3D V4L2_BUF_TYPE_VIDEO_CAPTURE) { + ret =3D stf_video_init_format(video); + if (ret < 0) { + dev_err(video->stfcamss->dev, + "Failed to init format: %d\n", ret); + goto err_media_cleanup; + } + vdev->ioctl_ops =3D &stf_vid_ioctl_ops; + vdev->device_caps =3D V4L2_CAP_VIDEO_CAPTURE; + } else { + ret =3D stf_video_scd_init_format(video); + if (ret < 0) { + dev_err(video->stfcamss->dev, + "Failed to init format: %d\n", ret); + goto err_media_cleanup; + } + vdev->ioctl_ops =3D &stf_vid_scd_ioctl_ops; + vdev->device_caps =3D V4L2_CAP_META_CAPTURE; } =20 vdev->fops =3D &stf_vid_fops; - vdev->ioctl_ops =3D &stf_vid_ioctl_ops; - vdev->device_caps =3D V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + vdev->device_caps |=3D V4L2_CAP_STREAMING; vdev->entity.ops =3D &stf_media_ops; vdev->vfl_dir =3D VFL_DIR_RX; vdev->release =3D stf_video_release; diff --git a/drivers/staging/media/starfive/camss/stf-video.h b/drivers/sta= ging/media/starfive/camss/stf-video.h index 8052b77e3ad8..30d54853777e 100644 --- a/drivers/staging/media/starfive/camss/stf-video.h +++ b/drivers/staging/media/starfive/camss/stf-video.h @@ -37,12 +37,14 @@ enum stf_v_line_id { enum stf_capture_type { STF_CAPTURE_RAW =3D 0, STF_CAPTURE_YUV, + STF_CAPTURE_SCD, STF_CAPTURE_NUM, }; =20 struct stfcamss_buffer { struct vb2_v4l2_buffer vb; dma_addr_t addr[2]; + void *vaddr_sc; /* Use for isp sc data */ struct list_head queue; }; =20 --=20 2.25.1 From nobody Sun Dec 28 00:46:12 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8BCC3C4167B for ; Thu, 14 Dec 2023 06:51:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1443312AbjLNGvB convert rfc822-to-8bit (ORCPT ); Thu, 14 Dec 2023 01:51:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32852 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1443261AbjLNGuj (ORCPT ); Thu, 14 Dec 2023 01:50:39 -0500 Received: from ex01.ufhost.com (ex01.ufhost.com [61.152.239.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0EEAFE8; Wed, 13 Dec 2023 22:50:46 -0800 (PST) Received: from EXMBX166.cuchost.com (unknown [175.102.18.54]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "EXMBX166", Issuer "EXMBX166" (not verified)) by ex01.ufhost.com (Postfix) with ESMTP id B2D1024E2FB; Thu, 14 Dec 2023 14:50:44 +0800 (CST) Received: from EXMBX062.cuchost.com (172.16.6.62) by EXMBX166.cuchost.com (172.16.6.76) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Thu, 14 Dec 2023 14:50:44 +0800 Received: from ubuntu.mshome.net (113.72.145.168) by EXMBX062.cuchost.com (172.16.6.62) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Thu, 14 Dec 2023 14:50:40 +0800 From: Changhuang Liang To: Mauro Carvalho Chehab , Greg Kroah-Hartman , Hans Verkuil , "Marvin Lin" , Bryan O'Donoghue , "Ming Qian" , Laurent Pinchart , Nicolas Dufresne , Benjamin Gaignard , Tomi Valkeinen , Mingjia Zhang , Geert Uytterhoeven , Sakari Ailus , Dan Carpenter CC: Jack Zhu , Changhuang Liang , , , Subject: [PATCH v1 6/9] staging: media: starfive: camss: Update ISP initialise config for 3A Date: Wed, 13 Dec 2023 22:50:24 -0800 Message-ID: <20231214065027.28564-7-changhuang.liang@starfivetech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231214065027.28564-1-changhuang.liang@starfivetech.com> References: <20231214065027.28564-1-changhuang.liang@starfivetech.com> MIME-Version: 1.0 X-Originating-IP: [113.72.145.168] X-ClientProxiedBy: EXCAS061.cuchost.com (172.16.6.21) To EXMBX062.cuchost.com (172.16.6.62) X-YovoleRuleAgent: yovoleflag Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Upadte ISP initialise for 3A statistics collection data. Signed-off-by: Changhuang Liang --- .../media/starfive/camss/stf-isp-hw-ops.c | 23 +++++++++++++++++++ .../staging/media/starfive/camss/stf-isp.h | 11 +++++++++ 2 files changed, 34 insertions(+) diff --git a/drivers/staging/media/starfive/camss/stf-isp-hw-ops.c b/driver= s/staging/media/starfive/camss/stf-isp-hw-ops.c index c6295a14d509..a1ab4f11718e 100644 --- a/drivers/staging/media/starfive/camss/stf-isp-hw-ops.c +++ b/drivers/staging/media/starfive/camss/stf-isp-hw-ops.c @@ -319,6 +319,25 @@ static void stf_isp_config_sat(struct stfcamss *stfcam= ss) stf_isp_reg_write(stfcamss, ISP_REG_YADJ1, YOMAX(0x3ff) | YOMIN(0x1)); } =20 +static void stf_isp_config_sc(struct stfcamss *stfcamss) +{ + stf_isp_reg_write(stfcamss, ISP_REG_SCD_CFG_1, AXI_ID(0)); + stf_isp_reg_write(stfcamss, ISP_REG_SC_CFG_0, HSTART(0) | VSTART(0xc)); + stf_isp_reg_write(stfcamss, ISP_REG_SC_CFG_1, + SC_WIDTH(0x1d) | SC_HEIGHT(0x15) | + AWB_PS_GRB_BA(0x10) | SEL_TYPE(0x3)); +} + +static void stf_isp_config_yhist(struct stfcamss *stfcamss) +{ + stf_isp_reg_write(stfcamss, ISP_REG_YHIST_CFG_0, 0); + stf_isp_reg_write(stfcamss, ISP_REG_YHIST_CFG_1, + YH_WIDTH(0x77f) | YH_HEIGHT(0x437)); + stf_isp_reg_write(stfcamss, ISP_REG_YHIST_CFG_2, + YH_DEC_ETW(2) | YH_DEC_ETH(1)); + stf_isp_reg_write(stfcamss, ISP_REG_YHIST_CFG_3, 0); +} + int stf_isp_reset(struct stf_isp_dev *isp_dev) { stf_isp_reg_set_bit(isp_dev->stfcamss, ISP_REG_ISP_CTRL_0, @@ -351,7 +370,11 @@ void stf_isp_init_cfg(struct stf_isp_dev *isp_dev) stf_isp_config_sharpen(isp_dev->stfcamss); stf_isp_config_dnyuv(isp_dev->stfcamss); stf_isp_config_sat(isp_dev->stfcamss); + stf_isp_config_sc(isp_dev->stfcamss); + stf_isp_config_yhist(isp_dev->stfcamss); =20 + stf_isp_reg_write(isp_dev->stfcamss, ISP_REG_DUMP_CFG_1, + DUMP_BURST_LEN(3) | DUMP_SD(0xb80)); stf_isp_reg_write(isp_dev->stfcamss, ISP_REG_CSI_MODULE_CFG, CSI_DUMP_EN | CSI_SC_EN | CSI_AWB_EN | CSI_LCCF_EN | CSI_OECF_EN | CSI_OBC_EN | CSI_DEC_EN); diff --git a/drivers/staging/media/starfive/camss/stf-isp.h b/drivers/stagi= ng/media/starfive/camss/stf-isp.h index bfb7196cefff..149f06b25416 100644 --- a/drivers/staging/media/starfive/camss/stf-isp.h +++ b/drivers/staging/media/starfive/camss/stf-isp.h @@ -417,6 +417,17 @@ #define DNRM_F(n) ((n) << 16) #define CCM_M_DAT(n) ((n) << 0) =20 +#define ISP_REG_YHIST_CFG_0 0xcc8 + +#define ISP_REG_YHIST_CFG_1 0xccc +#define YH_HEIGHT(n) ((n) << 16) +#define YH_WIDTH(n) ((n) << 0) + +#define ISP_REG_YHIST_CFG_2 0xcd0 +#define YH_DEC_ETH(n) ((n) << 16) +#define YH_DEC_ETW(n) ((n) << 0) + +#define ISP_REG_YHIST_CFG_3 0xcd4 #define ISP_REG_YHIST_CFG_4 0xcd8 =20 #define ISP_REG_YHIST_ACC_0 0xd00 --=20 2.25.1 From nobody Sun Dec 28 00:46:12 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 484DBC4167B for ; Thu, 14 Dec 2023 06:51:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1443321AbjLNGvF convert rfc822-to-8bit (ORCPT ); Thu, 14 Dec 2023 01:51:05 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57386 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1443271AbjLNGum (ORCPT ); Thu, 14 Dec 2023 01:50:42 -0500 Received: from fd01.gateway.ufhost.com (fd01.gateway.ufhost.com [61.152.239.71]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5F754B7; Wed, 13 Dec 2023 22:50:48 -0800 (PST) Received: from EXMBX165.cuchost.com (unknown [175.102.18.54]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "EXMBX165", Issuer "EXMBX165" (not verified)) by fd01.gateway.ufhost.com (Postfix) with ESMTP id 276EC81A5; Thu, 14 Dec 2023 14:50:47 +0800 (CST) Received: from EXMBX062.cuchost.com (172.16.6.62) by EXMBX165.cuchost.com (172.16.6.75) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Thu, 14 Dec 2023 14:50:47 +0800 Received: from ubuntu.mshome.net (113.72.145.168) by EXMBX062.cuchost.com (172.16.6.62) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Thu, 14 Dec 2023 14:50:44 +0800 From: Changhuang Liang To: Mauro Carvalho Chehab , Greg Kroah-Hartman , Hans Verkuil , "Marvin Lin" , Bryan O'Donoghue , "Ming Qian" , Laurent Pinchart , Nicolas Dufresne , Benjamin Gaignard , Tomi Valkeinen , Mingjia Zhang , Geert Uytterhoeven , Sakari Ailus , Dan Carpenter CC: Jack Zhu , Changhuang Liang , , , Subject: [PATCH v1 7/9] staging: media: starfive: camss: Add V4L2_CAP_IO_MC capability Date: Wed, 13 Dec 2023 22:50:25 -0800 Message-ID: <20231214065027.28564-8-changhuang.liang@starfivetech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231214065027.28564-1-changhuang.liang@starfivetech.com> References: <20231214065027.28564-1-changhuang.liang@starfivetech.com> MIME-Version: 1.0 X-Originating-IP: [113.72.145.168] X-ClientProxiedBy: EXCAS061.cuchost.com (172.16.6.21) To EXMBX062.cuchost.com (172.16.6.62) X-YovoleRuleAgent: yovoleflag Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add V4L2_CAP_IO_MC capability for StarFive JH7110 SoC. Signed-off-by: Changhuang Liang --- drivers/staging/media/starfive/camss/stf-video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/starfive/camss/stf-video.c b/drivers/sta= ging/media/starfive/camss/stf-video.c index f617b7b00491..54d855ba0b57 100644 --- a/drivers/staging/media/starfive/camss/stf-video.c +++ b/drivers/staging/media/starfive/camss/stf-video.c @@ -665,7 +665,7 @@ int stf_video_register(struct stfcamss_video *video, } =20 vdev->fops =3D &stf_vid_fops; - vdev->device_caps |=3D V4L2_CAP_STREAMING; + vdev->device_caps |=3D V4L2_CAP_STREAMING | V4L2_CAP_IO_MC; vdev->entity.ops =3D &stf_media_ops; vdev->vfl_dir =3D VFL_DIR_RX; vdev->release =3D stf_video_release; --=20 2.25.1 From nobody Sun Dec 28 00:46:12 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8F920C4332F for ; Thu, 14 Dec 2023 06:51:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1443290AbjLNGvI convert rfc822-to-8bit (ORCPT ); Thu, 14 Dec 2023 01:51:08 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57400 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1443250AbjLNGuo (ORCPT ); Thu, 14 Dec 2023 01:50:44 -0500 Received: from fd01.gateway.ufhost.com (fd01.gateway.ufhost.com [61.152.239.71]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A464EB9; Wed, 13 Dec 2023 22:50:50 -0800 (PST) Received: from EXMBX166.cuchost.com (unknown [175.102.18.54]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "EXMBX166", Issuer "EXMBX166" (not verified)) by fd01.gateway.ufhost.com (Postfix) with ESMTP id 6EE82819B; Thu, 14 Dec 2023 14:50:49 +0800 (CST) Received: from EXMBX062.cuchost.com (172.16.6.62) by EXMBX166.cuchost.com (172.16.6.76) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Thu, 14 Dec 2023 14:50:49 +0800 Received: from ubuntu.mshome.net (113.72.145.168) by EXMBX062.cuchost.com (172.16.6.62) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Thu, 14 Dec 2023 14:50:46 +0800 From: Changhuang Liang To: Mauro Carvalho Chehab , Greg Kroah-Hartman , Hans Verkuil , "Marvin Lin" , Bryan O'Donoghue , "Ming Qian" , Laurent Pinchart , Nicolas Dufresne , Benjamin Gaignard , Tomi Valkeinen , Mingjia Zhang , Geert Uytterhoeven , Sakari Ailus , Dan Carpenter CC: Jack Zhu , Changhuang Liang , , , Subject: [PATCH v1 8/9] staging: media: starfive: Add frame sync event for video capture device Date: Wed, 13 Dec 2023 22:50:26 -0800 Message-ID: <20231214065027.28564-9-changhuang.liang@starfivetech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231214065027.28564-1-changhuang.liang@starfivetech.com> References: <20231214065027.28564-1-changhuang.liang@starfivetech.com> MIME-Version: 1.0 X-Originating-IP: [113.72.145.168] X-ClientProxiedBy: EXCAS061.cuchost.com (172.16.6.21) To EXMBX062.cuchost.com (172.16.6.62) X-YovoleRuleAgent: yovoleflag Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add frame sync event for video capture device. Signed-off-by: Changhuang Liang --- .../staging/media/starfive/camss/stf-capture.c | 9 +++++++++ drivers/staging/media/starfive/camss/stf-video.c | 15 +++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/drivers/staging/media/starfive/camss/stf-capture.c b/drivers/s= taging/media/starfive/camss/stf-capture.c index 6a137a273c8a..d0be769da11b 100644 --- a/drivers/staging/media/starfive/camss/stf-capture.c +++ b/drivers/staging/media/starfive/camss/stf-capture.c @@ -7,6 +7,7 @@ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd. */ =20 +#include #include "stf-camss.h" =20 static const char * const stf_cap_names[] =3D { @@ -430,10 +431,15 @@ static void stf_buf_flush(struct stf_v_buf *output, e= num vb2_buffer_state state) =20 static void stf_buf_done(struct stf_v_buf *output) { + struct stf_capture *cap =3D container_of(output, struct stf_capture, + buffers); struct stfcamss_buffer *ready_buf; struct stfcamss *stfcamss =3D cap->video.stfcamss; u64 ts =3D ktime_get_ns(); unsigned long flags; + struct v4l2_event event =3D { + .type =3D V4L2_EVENT_FRAME_SYNC, + }; =20 if (output->state =3D=3D STF_OUTPUT_OFF || output->state =3D=3D STF_OUTPUT_RESERVED) @@ -445,6 +451,9 @@ static void stf_buf_done(struct stf_v_buf *output) if (cap->type =3D=3D STF_CAPTURE_SCD) stf_isp_fill_yhist(stfcamss, ready_buf->vaddr_sc); =20 + event.u.frame_sync.frame_sequence =3D output->sequence; + v4l2_event_queue(&cap->video.vdev, &event); + ready_buf->vb.vb2_buf.timestamp =3D ts; ready_buf->vb.sequence =3D output->sequence++; =20 diff --git a/drivers/staging/media/starfive/camss/stf-video.c b/drivers/sta= ging/media/starfive/camss/stf-video.c index 54d855ba0b57..32381e9ad049 100644 --- a/drivers/staging/media/starfive/camss/stf-video.c +++ b/drivers/staging/media/starfive/camss/stf-video.c @@ -507,6 +507,17 @@ static int video_try_fmt(struct file *file, void *fh, = struct v4l2_format *f) return __video_try_fmt(video, f); } =20 +static int video_subscribe_event(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub) +{ + switch (sub->type) { + case V4L2_EVENT_FRAME_SYNC: + return v4l2_event_subscribe(fh, sub, 0, NULL); + default: + return -EINVAL; + } +} + static const struct v4l2_ioctl_ops stf_vid_ioctl_ops =3D { .vidioc_querycap =3D video_querycap, .vidioc_enum_fmt_vid_cap =3D video_enum_fmt, @@ -523,6 +534,8 @@ static const struct v4l2_ioctl_ops stf_vid_ioctl_ops = =3D { .vidioc_prepare_buf =3D vb2_ioctl_prepare_buf, .vidioc_streamon =3D vb2_ioctl_streamon, .vidioc_streamoff =3D vb2_ioctl_streamoff, + .vidioc_subscribe_event =3D video_subscribe_event, + .vidioc_unsubscribe_event =3D v4l2_event_unsubscribe, }; =20 static int video_scd_g_fmt(struct file *file, void *fh, struct v4l2_format= *f) @@ -554,6 +567,8 @@ static const struct v4l2_ioctl_ops stf_vid_scd_ioctl_op= s =3D { .vidioc_prepare_buf =3D vb2_ioctl_prepare_buf, .vidioc_streamon =3D vb2_ioctl_streamon, .vidioc_streamoff =3D vb2_ioctl_streamoff, + .vidioc_subscribe_event =3D video_subscribe_event, + .vidioc_unsubscribe_event =3D v4l2_event_unsubscribe, }; =20 /* -----------------------------------------------------------------------= ------ --=20 2.25.1 From nobody Sun Dec 28 00:46:12 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C7A81C4332F for ; Thu, 14 Dec 2023 06:51:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234303AbjLNGvL convert rfc822-to-8bit (ORCPT ); Thu, 14 Dec 2023 01:51:11 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57416 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1443266AbjLNGup (ORCPT ); Thu, 14 Dec 2023 01:50:45 -0500 Received: from ex01.ufhost.com (ex01.ufhost.com [61.152.239.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 28AEDE8; Wed, 13 Dec 2023 22:50:52 -0800 (PST) Received: from EXMBX165.cuchost.com (unknown [175.102.18.54]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "EXMBX165", Issuer "EXMBX165" (not verified)) by ex01.ufhost.com (Postfix) with ESMTP id BE20A24E303; Thu, 14 Dec 2023 14:50:50 +0800 (CST) Received: from EXMBX062.cuchost.com (172.16.6.62) by EXMBX165.cuchost.com (172.16.6.75) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Thu, 14 Dec 2023 14:50:50 +0800 Received: from ubuntu.mshome.net (113.72.145.168) by EXMBX062.cuchost.com (172.16.6.62) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Thu, 14 Dec 2023 14:50:49 +0800 From: Changhuang Liang To: Mauro Carvalho Chehab , Greg Kroah-Hartman , Hans Verkuil , "Marvin Lin" , Bryan O'Donoghue , "Ming Qian" , Laurent Pinchart , Nicolas Dufresne , Benjamin Gaignard , Tomi Valkeinen , Mingjia Zhang , Geert Uytterhoeven , Sakari Ailus , Dan Carpenter CC: Jack Zhu , Changhuang Liang , , , Subject: [PATCH v1 9/9] admin-guide: media: Update documents for StarFive Camera Subsystem Date: Wed, 13 Dec 2023 22:50:27 -0800 Message-ID: <20231214065027.28564-10-changhuang.liang@starfivetech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231214065027.28564-1-changhuang.liang@starfivetech.com> References: <20231214065027.28564-1-changhuang.liang@starfivetech.com> MIME-Version: 1.0 X-Originating-IP: [113.72.145.168] X-ClientProxiedBy: EXCAS061.cuchost.com (172.16.6.21) To EXMBX062.cuchost.com (172.16.6.62) X-YovoleRuleAgent: yovoleflag Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add ISP 3A statistisc collection data video device for documents. Signed-off-by: Changhuang Liang --- .../admin-guide/media/starfive_camss.rst | 9 ++++++--- .../media/starfive_camss_graph.dot | 20 ++++++++++--------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/Documentation/admin-guide/media/starfive_camss.rst b/Documenta= tion/admin-guide/media/starfive_camss.rst index ca42e9447c47..970ae20140d1 100644 --- a/Documentation/admin-guide/media/starfive_camss.rst +++ b/Documentation/admin-guide/media/starfive_camss.rst @@ -58,15 +58,18 @@ The media controller pipeline graph is as follows: :alt: starfive_camss_graph.dot :align: center =20 -The driver has 2 video devices: +The driver has 3 video devices: =20 - capture_raw: The capture device, capturing image data directly from a se= nsor. - capture_yuv: The capture device, capturing YUV frame data processed by t= he - ISP module + ISP module. +- capture_scd: The meta capture device, capturing 3A statistics collection= data + processed by the ISP module. =20 The driver has 3 subdevices: =20 -- stf_isp: is responsible for all the isp operations, outputs YUV frames. +- stf_isp: is responsible for all the isp operations, outputs YUV frames + and 3A statistics collection data. - cdns_csi2rx: a CSI-2 bridge supporting up to 4 CSI lanes in input, and 4 different pixel streams in output. - imx219: an image sensor, image data is sent through MIPI CSI-2. diff --git a/Documentation/admin-guide/media/starfive_camss_graph.dot b/Doc= umentation/admin-guide/media/starfive_camss_graph.dot index 8eff1f161ac7..3fd42e3cc0f6 100644 --- a/Documentation/admin-guide/media/starfive_camss_graph.dot +++ b/Documentation/admin-guide/media/starfive_camss_graph.dot @@ -1,12 +1,14 @@ digraph board { rankdir=3DTB - n00000001 [label=3D"{{ 0} | stf_isp\n/dev/v4l-subdev0 | { 1= }}", shape=3DMrecord, style=3Dfilled, fillcolor=3Dgreen] - n00000001:port1 -> n00000008 [style=3Ddashed] - n00000004 [label=3D"capture_raw\n/dev/video0", shape=3Dbox, style=3Dfille= d, fillcolor=3Dyellow] - n00000008 [label=3D"capture_yuv\n/dev/video1", shape=3Dbox, style=3Dfille= d, fillcolor=3Dyellow] - n0000000e [label=3D"{{ 0} | cdns_csi2rx.19800000.csi-bridge\n | {<= port1> 1 | 2 | 3 | 4}}", shape=3DMrecord, style=3Df= illed, fillcolor=3Dgreen] - n0000000e:port1 -> n00000001:port0 [style=3Ddashed] - n0000000e:port1 -> n00000004 [style=3Ddashed] - n00000018 [label=3D"{{} | imx219 6-0010\n/dev/v4l-subdev1 | { 0}}"= , shape=3DMrecord, style=3Dfilled, fillcolor=3Dgreen] - n00000018:port0 -> n0000000e:port0 [style=3Dbold] + n00000001 [label=3D"{{ 0} | stf_isp\n/dev/v4l-subdev0 | { 1= | 2}}", shape=3DMrecord, style=3Dfilled, fillcolor=3Dgreen] + n00000001:port1 -> n00000009 [style=3Ddashed] + n00000001:port2 -> n0000000d [style=3Ddashed] + n00000005 [label=3D"capture_raw\n/dev/video0", shape=3Dbox, style=3Dfille= d, fillcolor=3Dyellow] + n00000009 [label=3D"capture_yuv\n/dev/video1", shape=3Dbox, style=3Dfille= d, fillcolor=3Dyellow] + n0000000d [label=3D"capture_scd\n/dev/video2", shape=3Dbox, style=3Dfille= d, fillcolor=3Dyellow] + n00000015 [label=3D"{{ 0} | cdns_csi2rx.19800000.csi-bridge\n/dev/= v4l-subdev1 | { 1 | 2 | 3 | 4}}", shape=3DMr= ecord, style=3Dfilled, fillcolor=3Dgreen] + n00000015:port1 -> n00000001:port0 [style=3Ddashed] + n00000015:port1 -> n00000005 [style=3Ddashed] + n0000001f [label=3D"{{} | imx219 6-0010\n/dev/v4l-subdev2 | { 0}}"= , shape=3DMrecord, style=3Dfilled, fillcolor=3Dgreen] + n0000001f:port0 -> n00000015:port0 [style=3Dbold] } --=20 2.25.1