From patchwork Wed Jun 5 16:54:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 13687119 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AAB181CD25 for ; Wed, 5 Jun 2024 16:55:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717606506; cv=none; b=INXDVuOtfAxjNlpPpfw/mOz3iZyKeCI2HZYui3yuMAmq8GVuXXZ9lF/RZdymOU0c3RYGY/4WBNu0SGhC4vHLAupXtMA7EmB6pGvKcnUUh5Q4aIBINkrhWruSmzRX34OtnL47dGvqWqba3WYuZpHWIfRO5aCy1tO0VE3B64E2nmE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717606506; c=relaxed/simple; bh=ZhnGrUGKDXQkVTXg5HRlyrWUPMfF1NMM9zqRJG8uNd4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Sn+ZSU1xeoCCE+RPOfr2pJIg9I4/Zegj8H3TOX/iGvvbLDmTLNfDdSvNJF6RymaBEfep7zHT1+QsBjCBXxY+XkSxkiWJV15jiRsO8m4me2g+fcEuWRkdKpaXMBqTptlTQ9rrOul/STHN5mBO7zXU6DyBV+pjZzKuoTAYbL+KnUc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=T1q9Jxv6; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="T1q9Jxv6" Received: from localhost.localdomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C855E16D4; Wed, 5 Jun 2024 18:54:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1717606489; bh=ZhnGrUGKDXQkVTXg5HRlyrWUPMfF1NMM9zqRJG8uNd4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=T1q9Jxv6DMeHioVji51Ye9lix6+3HvxqTkD2LwkqCzANL9GEliSPgr7JSGqTXF8eG x14Z4IWmr7hqXgQsGP0YJ6e/HDnvC4bOMmjl2kfabqO+7W/Pf9F005qzLGz+282zYT zZAADndrjeJgUOUcWeIpYAWLVKG8SVdMGY2Kbj5Y= From: Jacopo Mondi To: Linux Media Mailing List Cc: Jacopo Mondi , Laurent Pinchart , Sakari Ailus , Hans Verkuil , Stefan Klug , Paul Elder , Daniel Scally , Kieran Bingham , Umang Jain , Dafna Hirschfeld , Mauro Carvalho Chehab , Heiko Stuebner Subject: [PATCH 1/8] uapi: rkisp1-config: Add extensible parameters format Date: Wed, 5 Jun 2024 18:54:20 +0200 Message-ID: <20240605165434.432230-2-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.45.1 In-Reply-To: <20240605165434.432230-1-jacopo.mondi@ideasonboard.com> References: <20240605165434.432230-1-jacopo.mondi@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add to the rkisp1-config.h header data types and documentation of the extensible parameters format. Signed-off-by: Jacopo Mondi Reviewed-by: Daniel Scally --- include/uapi/linux/rkisp1-config.h | 482 +++++++++++++++++++++++++++++ 1 file changed, 482 insertions(+) diff --git a/include/uapi/linux/rkisp1-config.h b/include/uapi/linux/rkisp1-config.h index 6eeaf8bf2362..9c93e536f270 100644 --- a/include/uapi/linux/rkisp1-config.h +++ b/include/uapi/linux/rkisp1-config.h @@ -996,4 +996,486 @@ struct rkisp1_stat_buffer { struct rkisp1_cif_isp_stat params; }; +/*---------- PART3: Extensible Configuration Parameters ------------*/ + +/** + * enum rkisp1_ext_params_block_type - RkISP1 extensible params block type + * + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_BLS: Black level subtraction + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_DPCC: Defect pixel cluster correction + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_SDG: Sensor de-gamma + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_GAINS: Auto white balance gains + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_FLT: ISP filtering + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_BDM: Bayer de-mosaic + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_CTK: Cross-talk correction + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_GOC: Gamma out correction + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF: De-noise pre-filter + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF_STRENGHT: De-noise pre-filter strength + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_CPROC: Color processing + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_IE: Image effects + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_LSC: Lens shading correction + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_MEAS: Auto white balance statistics + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_HST_MEAS: Histogram statistics + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_AEC_MEAS: Auto exposure statistics + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_AFC_MEAS: Auto-focus statistics + */ +enum rkisp1_ext_params_block_type { + RKISP1_EXT_PARAMS_BLOCK_TYPE_BLS, + RKISP1_EXT_PARAMS_BLOCK_TYPE_DPCC, + RKISP1_EXT_PARAMS_BLOCK_TYPE_SDG, + RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_GAINS, + RKISP1_EXT_PARAMS_BLOCK_TYPE_FLT, + RKISP1_EXT_PARAMS_BLOCK_TYPE_BDM, + RKISP1_EXT_PARAMS_BLOCK_TYPE_CTK, + RKISP1_EXT_PARAMS_BLOCK_TYPE_GOC, + RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF, + RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF_STRENGHT, + RKISP1_EXT_PARAMS_BLOCK_TYPE_CPROC, + RKISP1_EXT_PARAMS_BLOCK_TYPE_IE, + RKISP1_EXT_PARAMS_BLOCK_TYPE_LSC, + RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_MEAS, + RKISP1_EXT_PARAMS_BLOCK_TYPE_HST_MEAS, + RKISP1_EXT_PARAMS_BLOCK_TYPE_AEC_MEAS, + RKISP1_EXT_PARAMS_BLOCK_TYPE_AFC_MEAS, + RKISP1_EXT_PARAMS_BLOCK_TYPE_SENTINEL, +}; + +/** + * enum rkisp1_ext_params_block_state - RkISP1 extensible parameter block enable + * state flags + * + * @RKISP1_EXT_PARAMS_BLOCK_NO_CHANGE: Do not change the block power state + * @RKISP1_EXT_PARAMS_BLOCK_DISABLE: Disable the HW block + * @RKISP1_EXT_PARAMS_BLOCK_ENABLE: Enable the HW block + */ +enum rkisp1_ext_params_block_state { + RKISP1_EXT_PARAMS_BLOCK_NO_CHANGE, + RKISP1_EXT_PARAMS_BLOCK_DISABLE, + RKISP1_EXT_PARAMS_BLOCK_ENABLE, +}; + +/** + * struct rkisp1_ext_params_block_header - RkISP1 extensible parameter block + * header + * + * This structure represents the common part of all the ISP configuration + * blocks. Each parameters block shall embed an instance of this structure type + * as its first member, followed by the block-specific configuration data. The + * driver inspects this common header to discern the block type and its size and + * properly handle the block content by casting it to the correct block-specific + * type. + * + * The @type field is one of the values enumerated by + * :c:type:`rkisp1_ext_params_block_type` and specifies how the data should be + * interpreted by the driver. The @size field specifies the size of the + * parameters block and is used by the driver for validation purposes. + * + * The @state field specifies if the ISP block power state should be changed, + * and, if it has to, if it has to be enabled to disabled. The possible + * states are enumerated by :c:type:`rkisp1_ext_params_block_state`. + * When userspace needs to configure and enable an ISP block it shall fully + * populate the block configuration and the @state flag shall be set to + * RKISP1_EXT_PARAMS_BLOCK_ENABLE. When userspace simply wants to disable the + * ISP block the @state flag shall be set to RKISP1_EXT_PARAMS_BLOCK_DISABLE. If + * a new configuration of an ISP block should be applied but the power state + * doesn't need to be changed, userspace shall fully populate the ISP block + * configuration and the @state flag shall be set to + * RKISP1_EXT_PARAMS_BLOCK_NO_CHANGE. + * + * Userspace is responsible for correctly populating the parameters block header + * fields (@type, @state and @size) and correctly populate the block-specific + * parameters. + * + * For example: + * + * .. code-block:: c + * + * void populate_bls(struct rkisp1_ext_params_block_header *block) { + * struct rkisp1_ext_params_bls_config *bls = + * (struct rkisp1_ext_params_bls_config *)block; + * + * block->header.type = RKISP1_EXT_PARAMS_BLOCK_ID_BLS; + * block->header.state = RKISP1_EXT_PARAMS_BLOCK_ENABLE; + * block->header.size = sizeof(struct rkisp1_ext_params_bls_config); + * + * bls->bls_config.enable_auto = 0; + * bls->bls_config.fixed_val.r = blackLevelRed_; + * bls->bls_config.fixed_val.gr = blackLevelGreenR_; + * bls->bls_config.fixed_val.gb = blackLevelGreenB_; + * bls->bls_config.fixed_val.b = blackLevelBlue_; + * } + * + * @type: The parameters block type, see + * :c:type:`rkisp1_ext_params_block_type` + * @state: The block enable state flag, see + * :c:type:`rkisp1_ext_params_block_state` + * @size: Size (in bytes) of the parameters block, including this header + */ +struct rkisp1_ext_params_block_header { + __u32 type; + __u32 state; + __u64 size; +}; + +/** + * struct rkisp1_ext_params_bls_config - RkISP1 extensible params BLS config + * + * RkISP1 extensible parameters Black Level Subtraction configuration block + * + * @header: The RkISP1 extensible parameters header, see + * :c:type:`rkisp1_ext_params_block_header` + * @bls_config: Black Level Subtraction configuration, see + * :c:type:`rkisp1_cif_isp_bls_config` + */ +struct rkisp1_ext_params_bls_config { + struct rkisp1_ext_params_block_header header; + struct rkisp1_cif_isp_bls_config bls_config; +}; + +/** + * struct rkisp1_ext_params_dpcc_config - RkISP1 extensible params DPCC config + * + * RkISP1 extensible parameters Defective Pixel Cluster Correction configuration + * block + * + * @header: The RkISP1 extensible parameters header, see + * :c:type:`rkisp1_ext_params_block_header` + * @dpcc_config: Defective Pixel Cluster Correction configuration, see + * :c:type:`rkisp1_cif_isp_dpcc_config` + */ +struct rkisp1_ext_params_dpcc_config { + struct rkisp1_ext_params_block_header header; + struct rkisp1_cif_isp_dpcc_config dpcc_config; +}; + +/** + * struct rkisp1_ext_params_sdg_config - RkISP1 extensible params SDG config + * + * RkISP1 extensible parameters Sensor Degamma configuration block + * + * @header: The RkISP1 extensible parameters header, see + * :c:type:`rkisp1_ext_params_block_header` + * @sdg_config: Sensor Degamma configuration, see + * :c:type:`rkisp1_cif_isp_sdg_config` + */ +struct rkisp1_ext_params_sdg_config { + struct rkisp1_ext_params_block_header header; + struct rkisp1_cif_isp_sdg_config sdg_config; +}; + +/** + * struct rkisp1_ext_params_lsc_config - RkISP1 extensible params LSC config + * + * RkISP1 extensible parameters Lens Shading Correction configuration block + * + * @header: The RkISP1 extensible parameters header, see + * :c:type:`rkisp1_ext_params_block_header` + * @lsc_config: Lens Shading Correction configuration, see + * :c:type:`rkisp1_cif_isp_lsc_config` + */ +struct rkisp1_ext_params_lsc_config { + struct rkisp1_ext_params_block_header header; + struct rkisp1_cif_isp_lsc_config lsc_config; +}; + +/** + * struct rkisp1_ext_params_awb_gain_config - RkISP1 extensible params AWB + * gain config + * + * RkISP1 extensible parameters Auto-White Balance Gains configuration block + * + * @header: The RkISP1 extensible parameters header, see + * :c:type:`rkisp1_ext_params_block_header` + * @awb_config: Auto-White Balance Gains configuration, see + * :c:type:`rkisp1_cif_isp_awb_gain_config` + */ +struct rkisp1_ext_params_awb_gain_config { + struct rkisp1_ext_params_block_header header; + struct rkisp1_cif_isp_awb_gain_config awb_config; +}; + +/** + * struct rkisp1_ext_params_flt_config - RkISP1 extensible params FLT config + * + * RkISP1 extensible parameters Filter configuration block + * + * @header: The RkISP1 extensible parameters header, see + * :c:type:`rkisp1_ext_params_block_header` + * @flt_config: Filter configuration, see + * :c:type:`rkisp1_cif_isp_flt_config` + */ +struct rkisp1_ext_params_flt_config { + struct rkisp1_ext_params_block_header header; + struct rkisp1_cif_isp_flt_config flt_config; +}; + +/** + * struct rkisp1_ext_params_bdm_config - RkISP1 extensible params BDM config + * + * RkISP1 extensible parameters Demosaicing configuration block + * + * @header: The RkISP1 extensible parameters header, see + * :c:type:`rkisp1_ext_params_block_header` + * @bdm_config: Demosaicing configuration, see + * :c:type:`rkisp1_cif_isp_bdm_config` + */ +struct rkisp1_ext_params_bdm_config { + struct rkisp1_ext_params_block_header header; + struct rkisp1_cif_isp_bdm_config bdm_config; +}; + +/** + * struct rkisp1_ext_params_ctk_config - RkISP1 extensible params CTK config + * + * RkISP1 extensible parameters Cross-Talk configuration block + * + * @header: The RkISP1 extensible parameters header, see + * :c:type:`rkisp1_ext_params_block_header` + * @ctk_config: Cross-Talk configuration, see + * :c:type:`rkisp1_cif_isp_ctk_config` + */ +struct rkisp1_ext_params_ctk_config { + struct rkisp1_ext_params_block_header header; + struct rkisp1_cif_isp_ctk_config ctk_config; +}; + +/** + * struct rkisp1_ext_params_goc_config - RkISP1 extensible params GOC config + * + * RkISP1 extensible parameters Gamma-Out configuration block + * + * @header: The RkISP1 extensible parameters header, see + * :c:type:`rkisp1_ext_params_block_header` + * @goc_config: Gamma-Out configuration, see + * :c:type:`rkisp1_cif_isp_goc_config` + */ +struct rkisp1_ext_params_goc_config { + struct rkisp1_ext_params_block_header header; + struct rkisp1_cif_isp_goc_config goc_config; +}; + +/** + * struct rkisp1_ext_params_dpf_config - RkISP1 extensible params DPF config + * + * RkISP1 extensible parameters De-noise Pre-Filter configuration block + * + * @header: The RkISP1 extensible parameters header, see + * :c:type:`rkisp1_ext_params_block_header` + * @dpf_config: De-noise Pre-Filter configuration, see + * :c:type:`rkisp1_cif_isp_dpf_config` + */ +struct rkisp1_ext_params_dpf_config { + struct rkisp1_ext_params_block_header header; + struct rkisp1_cif_isp_dpf_config dpf_config; +}; + +/** + * struct rkisp1_ext_params_dpf_strength_config - RkISP1 extensible params DPF + * strength config + * + * RkISP1 extensible parameters De-noise Pre-Filter strength configuration block + * + * @header: The RkISP1 extensible parameters header, see + * :c:type:`rkisp1_ext_params_block_header` + * @dpf_strength_config: De-noise Pre-Filter strength configuration, see + * :c:type:`rkisp1_cif_isp_dpf_strength_config` + */ +struct rkisp1_ext_params_dpf_strength_config { + struct rkisp1_ext_params_block_header header; + struct rkisp1_cif_isp_dpf_strength_config dpf_strength_config; +}; + +/** + * struct rkisp1_ext_params_cproc_config - RkISP1 extensible params CPROC config + * + * RkISP1 extensible parameters Color Processing configuration block + * + * @header: The RkISP1 extensible parameters header, see + * :c:type:`rkisp1_ext_params_block_header` + * @cproc_config: Color processing configuration, see + * :c:type:`rkisp1_cif_isp_cproc_config` + */ +struct rkisp1_ext_params_cproc_config { + struct rkisp1_ext_params_block_header header; + struct rkisp1_cif_isp_cproc_config cproc_config; +}; + +/** + * struct rkisp1_ext_params_ie_config - RkISP1 extensible params IE config + * + * RkISP1 extensible parameters Image Effect configuration block + * + * @header: The RkISP1 extensible parameters header, see + * :c:type:`rkisp1_ext_params_block_header` + * @ie_config: Image Effect configuration, see + * :c:type:`rkisp1_cif_isp_ie_config` + */ +struct rkisp1_ext_params_ie_config { + struct rkisp1_ext_params_block_header header; + struct rkisp1_cif_isp_ie_config ie_config; +}; + +/** + * struct rkisp1_ext_params_awb_meas_config - RkISP1 extensible params AWB + * Meas config + * + * RkISP1 extensible parameters Auto-White Balance Measurement configuration + * block + * + * @header: The RkISP1 extensible parameters header, see + * :c:type:`rkisp1_ext_params_block_header` + * @awb_meas_config: Auto-White Balance measure configuration, see + * :c:type:`rkisp1_cif_isp_awb_meas_config` + */ +struct rkisp1_ext_params_awb_meas_config { + struct rkisp1_ext_params_block_header header; + struct rkisp1_cif_isp_awb_meas_config awb_meas_config; +}; + +/** + * struct rkisp1_ext_params_hst_config - RkISP1 extensible params Histogram config + * + * RkISP1 extensible parameters Histogram statistics configuration block + * + * @header: The RkISP1 extensible parameters header, see + * :c:type:`rkisp1_ext_params_block_header` + * @hst_config: Histogram statistics configuration, see + * :c:type:`rkisp1_cif_isp_hst_config` + */ +struct rkisp1_ext_params_hst_config { + struct rkisp1_ext_params_block_header header; + struct rkisp1_cif_isp_hst_config hst_config; +}; + +/** + * struct rkisp1_ext_params_aec_config - RkISP1 extensible params AEC config + * + * RkISP1 extensible parameters Auto-Exposure statistics configuration block + * + * @header: The RkISP1 extensible parameters header, see + * :c:type:`rkisp1_ext_params_block_header` + * @aec_config: Auto-Exposure statistics configuration, see + * :c:type:`rkisp1_cif_isp_aec_config` + */ +struct rkisp1_ext_params_aec_config { + struct rkisp1_ext_params_block_header header; + struct rkisp1_cif_isp_aec_config aec_config; +}; + +/** + * struct rkisp1_ext_params_afc_config - RkISP1 extensible params AFC config + * + * RkISP1 extensible parameters Auto-Focus statistics configuration block + * + * @header: The RkISP1 extensible parameters header, see + * :c:type:`rkisp1_ext_params_block_header` + * @afc_config: Auto-Focus statistics configuration, see + * :c:type:`rkisp1_cif_isp_afc_config` + */ +struct rkisp1_ext_params_afc_config { + struct rkisp1_ext_params_block_header header; + struct rkisp1_cif_isp_afc_config afc_config; +}; + +#define RKISP1_EXT_PARAMS_MAX_SIZE \ + (sizeof(struct rkisp1_ext_params_bls_config) +\ + sizeof(struct rkisp1_ext_params_dpcc_config) +\ + sizeof(struct rkisp1_ext_params_sdg_config) +\ + sizeof(struct rkisp1_ext_params_lsc_config) +\ + sizeof(struct rkisp1_ext_params_awb_gain_config) +\ + sizeof(struct rkisp1_ext_params_flt_config) +\ + sizeof(struct rkisp1_ext_params_bdm_config) +\ + sizeof(struct rkisp1_ext_params_ctk_config) +\ + sizeof(struct rkisp1_ext_params_goc_config) +\ + sizeof(struct rkisp1_ext_params_dpf_config) +\ + sizeof(struct rkisp1_ext_params_dpf_strength_config) +\ + sizeof(struct rkisp1_ext_params_cproc_config) +\ + sizeof(struct rkisp1_ext_params_ie_config) +\ + sizeof(struct rkisp1_ext_params_awb_meas_config) +\ + sizeof(struct rkisp1_ext_params_hst_config) +\ + sizeof(struct rkisp1_ext_params_aec_config) +\ + sizeof(struct rkisp1_ext_params_afc_config)) + +/** + * enum rksip1_ext_param_buffer_version - RkISP1 extensible parameters version + * + * @RKISP1_EXT_PARAM_BUFFER_V1: First version of RkISP1 extensible parameters + */ +enum rksip1_ext_param_buffer_version { + RKISP1_EXT_PARAM_BUFFER_V1 = 1, +}; + +/** + * struct rkisp1_ext_params_cfg - RkISP1 extensible parameters configuration + * + * This struct contains the configuration parameters of the RkISP1 ISP + * algorithms, serialized by userspace into a data buffer. Each configuration + * parameter block is represented by a block-specific structure which contains a + * :c:type:`rkisp1_ext_params_block_header` entry as first member. Userspace + * populates the @data buffer with configuration parameters for the blocks that + * it intends to configure. As a consequence, the data buffer effective size + * changes according to the number of ISP blocks that userspace intends to + * configure and is set by userspace in the @total_size field. + * + * The parameters buffer is versioned by the @version field to allow modifying + * and extending its definition. Userspace shall populate the @version field to + * inform the driver about the version it intends to use. The driver will parse + * and handle the @data buffer according to the data layout specific to the + * indicated version and return an error if the desired version is not + * supported. + * + * For each ISP block that userspace wants to configure, a block-specific + * structure is appended to the @data buffer, one after the other without gaps + * in between nor overlaps. Userspace shall populate the @total_size field with + * the effective size, in bytes, of the @data buffer. + * + * The expected memory layout of the parameters buffer is:: + * + * +-------------------- struct rkisp1_ext_params_cfg -------------------+ + * | version = RKISP_EXT_PARAMS_BUFFER_V1; | + * | total_size = sizeof(struct rkisp1_ext_params_bls_config) | + * | sizeof(struct rkisp1_ext_params_dpcc_config); | + * | +------------------------- data ---------------------------------+ | + * | | +------------- struct rkisp1_ext_params_bls_config -----------+ | | + * | | | +-------- struct rkisp1_ext_params_block_header ---------+ | | | + * | | | | type = RKISP1_EXT_PARAMS_BLOCK_TYPE_BLS; | | | | + * | | | | state = RKISP1_EXT_PARAMS_BLOCK_ENABLE; | | | | + * | | | | size = sizeof(struct rkisp1_ext_params_bls_config); | | | | + * | | | +---------------------------------------------------------+ | | | + * | | | +---------- struct rkisp1_cif_isp_bls_config -------------+ | | | + * | | | | enable_auto = 0; | | | | + * | | | | fixed_val.r = 256; | | | | + * | | | | fixed_val.gr = 256; | | | | + * | | | | fixed_val.gb = 256; | | | | + * | | | | fixed_val.b = 256; | | | | + * | | | +---------------------------------------------------------+ | | | + * | | +------------ struct rkisp1_ext_params_dpcc_config -----------+ | | + * | | | +-------- struct rkisp1_ext_params_block_header ---------+ | | | + * | | | | type = RKISP1_EXT_PARAMS_BLOCK_TYPE_DPCC; | | | | + * | | | | state = RKISP1_EXT_PARAMS_BLOCK_ENABLE; | | | | + * | | | | size = sizeof(struct rkisp1_ext_params_dpcc_config); | | | | + * | | | +---------------------------------------------------------+ | | | + * | | | +---------- struct rkisp1_cif_isp_dpcc_config ------------+ | | | + * | | | | mode = RKISP1_CIF_ISP_DPCC_MODE_STAGE1_ENABLE; | | | | + * | | | | output_mode = | | | | + * | | | | RKISP1_CIF_ISP_DPCC_OUTPUT_MODE_STAGE1_INCL_G_CENTER; | | | | + * | | | | set_use = ... ; | | | | + * | | | | ... = ... ; | | | | + * | | | +---------------------------------------------------------+ | | | + * | | +-------------------------------------------------------------+ | | + * | +-----------------------------------------------------------------+ | + * +---------------------------------------------------------------------+ + * + * @version: The RkISP1 extensible parameters buffer version, see + * :c:type:`rksip1_ext_param_buffer_version` + * @total_size: The RkISP1 configuration data effective size, excluding this + * header + * @data: The RkISP1 extensible configuration data blocks + */ +struct rkisp1_ext_params_cfg { + __u32 version; + __u64 total_size; + __u8 data[RKISP1_EXT_PARAMS_MAX_SIZE]; +}; + #endif /* _UAPI_RKISP1_CONFIG_H */ From patchwork Wed Jun 5 16:54:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 13687120 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E73C2192B68 for ; Wed, 5 Jun 2024 16:55:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717606508; cv=none; b=cJvRWZdw1ioVxgKPryOfDhFJek9hYLaWrDKd/0jfSt+c2iDXKsFQvh+JbXGKcBc25uk+jv4VzrrCYvKb5wKovVfSWPiSUfEeArBx2yPjPw9ZL/X4Vm+tQ2oNjVpbM/tbCJ+blR34RsFcw1en9O2yqjADbpo37TotxpVdx5CNIu4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717606508; c=relaxed/simple; bh=RuzN8OjX2Waq/LlgCWIIv2n+0NRBibjPhhU/72zTnUs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=efg7UVWNz8ActVHwcNdEEHA2MO35kKiwriTaZcsnBpl6TdqOwyIpC1Pvicmlxhbnk3eVt5JAEaQkU8UpC7jv9SwW2H2bJzYrYOMFbY5FXMBhRP7ioxu6IiUGDTDO6eyFxZJKvqu/gCwvf1F5kylJItA/TXqPWz371yssvutolA4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=XlKbyApw; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="XlKbyApw" Received: from localhost.localdomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A17103A11; Wed, 5 Jun 2024 18:54:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1717606490; bh=RuzN8OjX2Waq/LlgCWIIv2n+0NRBibjPhhU/72zTnUs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XlKbyApw3xZ8jnz4NVjZ09v+qksF1sug23GBe5hCWQzfQCK3/TbK0jIQVYGEI+npc v/Z0ZAnJMo//NZfCLkfNAleEfpbNkJH3TQf8TA5t7sod0acoGBZ3ClHhWRBKF2WOlg QlKzJGK5WafKDfzXqWndjBVPo27wj3PGj7c/A4Tk= From: Jacopo Mondi To: Linux Media Mailing List Cc: Jacopo Mondi , Laurent Pinchart , Sakari Ailus , Hans Verkuil , Stefan Klug , Paul Elder , Daniel Scally , Kieran Bingham , Umang Jain , Dafna Hirschfeld , Mauro Carvalho Chehab , Heiko Stuebner Subject: [PATCH 2/8] uapi: videodev2: Add V4L2_META_FMT_RK_ISP1_EXT_PARAMS Date: Wed, 5 Jun 2024 18:54:21 +0200 Message-ID: <20240605165434.432230-3-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.45.1 In-Reply-To: <20240605165434.432230-1-jacopo.mondi@ideasonboard.com> References: <20240605165434.432230-1-jacopo.mondi@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add a new format definition for the RkISP1 extensible parameters format and document it. Document the usage of the new format in the rkisp1 admin guide. Signed-off-by: Jacopo Mondi Reviewed-by: Daniel Scally Reviewed-by: Paul Elder --- Documentation/admin-guide/media/rkisp1.rst | 11 +++- .../media/v4l/metafmt-rkisp1.rst | 62 ++++++++++++++++--- drivers/media/v4l2-core/v4l2-ioctl.c | 1 + include/uapi/linux/videodev2.h | 1 + 4 files changed, 64 insertions(+), 11 deletions(-) diff --git a/Documentation/admin-guide/media/rkisp1.rst b/Documentation/admin-guide/media/rkisp1.rst index 6f14d9561fa5..934c25e191df 100644 --- a/Documentation/admin-guide/media/rkisp1.rst +++ b/Documentation/admin-guide/media/rkisp1.rst @@ -114,11 +114,18 @@ to be applied to the hardware during a video stream, allowing userspace to dynamically modify values such as black level, cross talk corrections and others. -The buffer format is defined by struct :c:type:`rkisp1_params_cfg`, and -userspace should set +The ISP driver supports two different parameters configuration methods, the +`fixed parameters format` or the `extensible parameters format`. + +When using the `fixed parameters` method the buffer format is defined by struct +:c:type:`rkisp1_params_cfg`, and userspace set :ref:`V4L2_META_FMT_RK_ISP1_PARAMS ` as the dataformat. +When using the fixed parameters method the buffer format is defined by struct +:c:type:`rkisp1_ext_params_cfg`, and userspace set +:ref:`V4L2_META_FMT_RK_ISP1_EXT_PARAMS ` as +the dataformat. Capturing Video Frames Example ============================== diff --git a/Documentation/userspace-api/media/v4l/metafmt-rkisp1.rst b/Documentation/userspace-api/media/v4l/metafmt-rkisp1.rst index fa04f00bcd2e..6ff776d071a3 100644 --- a/Documentation/userspace-api/media/v4l/metafmt-rkisp1.rst +++ b/Documentation/userspace-api/media/v4l/metafmt-rkisp1.rst @@ -1,28 +1,72 @@ .. SPDX-License-Identifier: GPL-2.0 -.. _v4l2-meta-fmt-rk-isp1-params: - .. _v4l2-meta-fmt-rk-isp1-stat-3a: -***************************************************************************** -V4L2_META_FMT_RK_ISP1_PARAMS ('rk1p'), V4L2_META_FMT_RK_ISP1_STAT_3A ('rk1s') -***************************************************************************** +************************************************************************************************************************ +V4L2_META_FMT_RK_ISP1_PARAMS ('rk1p'), V4L2_META_FMT_RK_ISP1_STAT_3A ('rk1s'), V4L2_META_FMT_RK_ISP1_EXT_PARAMS ('rk1e') +************************************************************************************************************************ +======================== Configuration parameters ======================== -The configuration parameters are passed to the +The configuration of the RkISP1 ISP is performed by userspace by providing +parameters for the ISP to the driver using the :c:type:`v4l2_meta_format` +interface. + +There are currently two methods that allow to configure the ISP, the `fixed +parameters` configuration format and the `extensible parameters` configuration +format. + +.. _v4l2-meta-fmt-rk-isp1-params: + +Fixed parameters configuration format +===================================== + +When using the fixed configuration format, parameters are passed to the :ref:`rkisp1_params ` metadata output video node, using -the :c:type:`v4l2_meta_format` interface. The buffer contains -a single instance of the C structure :c:type:`rkisp1_params_cfg` defined in -``rkisp1-config.h``. So the structure can be obtained from the buffer by: +the `V4L2_META_FMT_RK_ISP1_PARAMS` meta pixel format. + +The buffer contains a single instance of the C structure +:c:type:`rkisp1_params_cfg` defined in ``rkisp1-config.h``. So the structure can +be obtained from the buffer by: .. code-block:: c struct rkisp1_params_cfg *params = (struct rkisp1_params_cfg*) buffer; +As the members of :c:type:`rkisp1_params_cfg` are defined in the +``rkisp1-config.h`` header, the structure layout is immutable and cannot be +extended further. For this reason the fixed configuration format only allows the +configuration of the ISP blocks supported at the time when the structure had +been defined in the header file, as introducing new parameters or modifying the +existing ones would change the buffer layout and cause breakages in existing +applications. + +.. _v4l2-meta-fmt-rk-isp1-ext-params: + +Extensible parameters configuration format +========================================== + +When using the extensible configuration format, parameters are passed to the +:ref:`rkisp1_params ` metadata output video node, using +the `V4L2_META_FMT_RK_ISP1_EXT_PARAMS` meta pixel format. + +The buffer contains a single instance of the C structure +:c:type:`rkisp1_ext_params_cfg` defined in ``rkisp1-config.h``. The +:c:type:`rkisp1_ext_params_cfg` structure is designed to allow userspace to +populate the data buffer with only the configuration data for the ISP block it +intends to configure. The extensible parameters format design allows to define +new block types and new configuration parameters and defines a versioning scheme +so that it can be extended and versioned without breaking compatibility with +existing applications. + +For these reasons, this configuration method if preferred over the `fixed +parameters` format alternative. + .. rkisp1_stat_buffer +=========================== 3A and histogram statistics =========================== diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 4c76d17b4629..aefdc1efd24b 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1456,6 +1456,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_META_FMT_VIVID: descr = "Vivid Metadata"; break; case V4L2_META_FMT_RK_ISP1_PARAMS: descr = "Rockchip ISP1 3A Parameters"; break; case V4L2_META_FMT_RK_ISP1_STAT_3A: descr = "Rockchip ISP1 3A Statistics"; break; + case V4L2_META_FMT_RK_ISP1_EXT_PARAMS: descr = "Rockchip ISP1 Ext 3A Params"; break; case V4L2_PIX_FMT_NV12_8L128: descr = "NV12 (8x128 Linear)"; break; case V4L2_PIX_FMT_NV12M_8L128: descr = "NV12M (8x128 Linear)"; break; case V4L2_PIX_FMT_NV12_10BE_8L128: descr = "10-bit NV12 (8x128 Linear, BE)"; break; diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index fe6b67e83751..7c2a303c6f59 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -840,6 +840,7 @@ struct v4l2_pix_format { /* Vendor specific - used for RK_ISP1 camera sub-system */ #define V4L2_META_FMT_RK_ISP1_PARAMS v4l2_fourcc('R', 'K', '1', 'P') /* Rockchip ISP1 3A Parameters */ #define V4L2_META_FMT_RK_ISP1_STAT_3A v4l2_fourcc('R', 'K', '1', 'S') /* Rockchip ISP1 3A Statistics */ +#define V4L2_META_FMT_RK_ISP1_EXT_PARAMS v4l2_fourcc('R', 'K', '1', 'E') /* Rockchip ISP1 3a Extensible Parameters */ #ifdef __KERNEL__ /* From patchwork Wed Jun 5 16:54:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 13687121 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 39C0919306A for ; Wed, 5 Jun 2024 16:55:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717606511; cv=none; b=MnicIlA98D9ogGJcK34ZxmKqpdzw4OWnYVrbaPMm1dMyix0okVz36zvEayg31TpKwwyH9ZngyLRLfISwYNVlK0qDjYaqbqYnEd9Ff2SCdBDEzN3CHRkxkydx3wtvuu3Lxh+H+qXtogUBGCpOGPz+RQq2l278WtHYZezdWGml6Nk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717606511; c=relaxed/simple; bh=BvnoWULelIJFp8kdSmdVKMOvEZv0XS1jm2RYXD/HIVs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Y8dErF4gkeZITeRv94NUGkIgEX0fVv9rTRgYHBww2mwonibaU4k/ryjyX1uDkPF/EfxZiY8sWGbS9sYhUGlOVZh+PuOA0oCu2sIVIrP94WjW7SEFbaXC3uE1L+Y3IVDwR89w7NqWk/LY87XCXpqBFrEvbY2DWow+nTSCJV1ofrc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=SHw/coGS; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="SHw/coGS" Received: from localhost.localdomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 7628D6A5D; Wed, 5 Jun 2024 18:54:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1717606491; bh=BvnoWULelIJFp8kdSmdVKMOvEZv0XS1jm2RYXD/HIVs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SHw/coGST7ltyl/XYvcSRxOdz+yUpJso++1hJ95oEdc3bP/GMAEMSPk9dYD/QIHnw JFHxyXWyxTBpJqS7PXAToc58ZoTSMu81Y/DO/GwExal6OxGmCsGiNJLr7/lkcWn65j +Vo/tFcHamejcrIqmd6qpz30XSBoHNBuKX8latjw= From: Jacopo Mondi To: Linux Media Mailing List Cc: Jacopo Mondi , Laurent Pinchart , Sakari Ailus , Hans Verkuil , Stefan Klug , Paul Elder , Daniel Scally , Kieran Bingham , Umang Jain , Dafna Hirschfeld , Mauro Carvalho Chehab , Heiko Stuebner Subject: [PATCH 3/8] media: rkisp1: Remove cached format info Date: Wed, 5 Jun 2024 18:54:22 +0200 Message-ID: <20240605165434.432230-4-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.45.1 In-Reply-To: <20240605165434.432230-1-jacopo.mondi@ideasonboard.com> References: <20240605165434.432230-1-jacopo.mondi@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The struct rkisp1_params type contains a v4l2_format instance which is used to store the buffer format and sizes to be used in enum_fmt and g_fmt operations. To prepare for supporting multiple meta output formats, to introduce support for extensible buffer formats, remove the cached format info and initialize them explicitly in the enum_fmt and g_fmt operations. Signed-off-by: Jacopo Mondi Reviewed-by: Daniel Scally Reviewed-by: Laurent Pinchart Reviewed-by: Paul Elder --- .../platform/rockchip/rkisp1/rkisp1-common.h | 2 -- .../platform/rockchip/rkisp1/rkisp1-params.c | 28 ++++++------------- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h index 26573f6ae575..2a715f964f6e 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h @@ -372,7 +372,6 @@ struct rkisp1_params_ops { * @ops: pointer to the variant-specific operations * @config_lock: locks the buffer list 'params' * @params: queue of rkisp1_buffer - * @vdev_fmt: v4l2_format of the metadata format * @quantization: the quantization configured on the isp's src pad * @raw_type: the bayer pattern on the isp video sink pad */ @@ -383,7 +382,6 @@ struct rkisp1_params { spinlock_t config_lock; /* locks the buffers list 'params' */ struct list_head params; - struct v4l2_format vdev_fmt; enum v4l2_quantization quantization; enum v4l2_ycbcr_encoding ycbcr_encoding; diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c index 173d1ea41874..1f449f29b241 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c @@ -1742,12 +1742,11 @@ static int rkisp1_params_enum_fmt_meta_out(struct file *file, void *priv, struct v4l2_fmtdesc *f) { struct video_device *video = video_devdata(file); - struct rkisp1_params *params = video_get_drvdata(video); if (f->index > 0 || f->type != video->queue->type) return -EINVAL; - f->pixelformat = params->vdev_fmt.fmt.meta.dataformat; + f->pixelformat = V4L2_META_FMT_RK_ISP1_PARAMS; return 0; } @@ -1756,15 +1755,14 @@ static int rkisp1_params_g_fmt_meta_out(struct file *file, void *fh, struct v4l2_format *f) { struct video_device *video = video_devdata(file); - struct rkisp1_params *params = video_get_drvdata(video); struct v4l2_meta_format *meta = &f->fmt.meta; if (f->type != video->queue->type) return -EINVAL; memset(meta, 0, sizeof(*meta)); - meta->dataformat = params->vdev_fmt.fmt.meta.dataformat; - meta->buffersize = params->vdev_fmt.fmt.meta.buffersize; + meta->dataformat = V4L2_META_FMT_RK_ISP1_PARAMS; + meta->buffersize = sizeof(struct rkisp1_params_cfg); return 0; } @@ -1897,19 +1895,6 @@ static int rkisp1_params_init_vb2_queue(struct vb2_queue *q, return vb2_queue_init(q); } -static void rkisp1_init_params(struct rkisp1_params *params) -{ - params->vdev_fmt.fmt.meta.dataformat = - V4L2_META_FMT_RK_ISP1_PARAMS; - params->vdev_fmt.fmt.meta.buffersize = - sizeof(struct rkisp1_params_cfg); - - if (params->rkisp1->info->isp_ver == RKISP1_V12) - params->ops = &rkisp1_v12_params_ops; - else - params->ops = &rkisp1_v10_params_ops; -} - int rkisp1_params_register(struct rkisp1_device *rkisp1) { struct rkisp1_params *params = &rkisp1->params; @@ -1938,7 +1923,12 @@ int rkisp1_params_register(struct rkisp1_device *rkisp1) vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_META_OUTPUT; vdev->vfl_dir = VFL_DIR_TX; rkisp1_params_init_vb2_queue(vdev->queue, params); - rkisp1_init_params(params); + + if (params->rkisp1->info->isp_ver == RKISP1_V12) + params->ops = &rkisp1_v12_params_ops; + else + params->ops = &rkisp1_v10_params_ops; + video_set_drvdata(vdev, params); node->pad.flags = MEDIA_PAD_FL_SOURCE; From patchwork Wed Jun 5 16:54:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 13687122 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 56A1C188CDE for ; Wed, 5 Jun 2024 16:55:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717606514; cv=none; b=b/uB1FH74WwqfTFwsfXsipA1wEzV4/8EecbxiO7wPDV+mRD5boJqRiISYcS7FiotaOscLl7SzQfxZLFVE3sR/0cfq03xi9lTPaCI5kq933ZKekRkz76Lcv8bCyFDFE62n5ZXQYqBUZP+TUcKwqTjJ4F8OfeRz6Spz+HymlNjqA8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717606514; c=relaxed/simple; bh=RgUIfiPz7bkqXqq1Y9QF6MZuo0/8gHQc8ykTzGWFwUU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YFlYvq8PWEEKWbq19nNotfM41vcwhVXk6AU3n0M5iRmVdpcKRKzi3M1LvKEZSqlWjcAA8cz4U33O/pMe1p21mE9kZ5hqMpTWMcESM+6PtWWqV6yIxSrzJ1t23lI6cUVo0yh89/zLuNuGIx17/Cwuqb6xz2nNkV1TcuyLqxabVT0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=gejGb/1P; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="gejGb/1P" Received: from localhost.localdomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4DFB26F48; Wed, 5 Jun 2024 18:54:51 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1717606491; bh=RgUIfiPz7bkqXqq1Y9QF6MZuo0/8gHQc8ykTzGWFwUU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gejGb/1P284cicqgVfQ95iQF3ti4NXBWaua6qcicQB2ylUKeNwZ7Q00aubgTsoj/p sPra1hFW/CglafPQug970rEZmI1cMGl0i7KRHxYnQoXH52iphSK24qNdYf0RXvp7lc DuTHaD1a6N6dnaROgn7TswHjA2+9OJgn68LxERsU= From: Jacopo Mondi To: Linux Media Mailing List Cc: Jacopo Mondi , Laurent Pinchart , Sakari Ailus , Hans Verkuil , Stefan Klug , Paul Elder , Daniel Scally , Kieran Bingham , Umang Jain , Dafna Hirschfeld , Mauro Carvalho Chehab , Heiko Stuebner Subject: [PATCH 4/8] media: rkisp1: Add support for ext format Date: Wed, 5 Jun 2024 18:54:23 +0200 Message-ID: <20240605165434.432230-5-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.45.1 In-Reply-To: <20240605165434.432230-1-jacopo.mondi@ideasonboard.com> References: <20240605165434.432230-1-jacopo.mondi@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add support to the rkisp1 driver for the extensible parameters format. Allow the driver to enumerate the existing and the new format and implement support for the try_fmt and s_fmt operations. Signed-off-by: Jacopo Mondi --- .../platform/rockchip/rkisp1/rkisp1-common.h | 1 + .../platform/rockchip/rkisp1/rkisp1-params.c | 87 +++++++++++++++++-- 2 files changed, 79 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h index 2a715f964f6e..0bddae8dbdb1 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h @@ -383,6 +383,7 @@ struct rkisp1_params { spinlock_t config_lock; /* locks the buffers list 'params' */ struct list_head params; + struct v4l2_meta_format metafmt; enum v4l2_quantization quantization; enum v4l2_ycbcr_encoding ycbcr_encoding; enum rkisp1_fmt_raw_pat_type raw_type; diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c index 1f449f29b241..6f99c7dad758 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c @@ -33,6 +33,34 @@ #define RKISP1_ISP_CC_COEFF(n) \ (RKISP1_CIF_ISP_CC_COEFF_0 + (n) * 4) +enum rkisp1_params_formats { + RKISP1_PARAMS_FIXED, + RKISP1_PARAMS_EXTENSIBLE, + RKISP1_PARAMS_NUM_FMT, +}; + +static const struct v4l2_meta_format rkisp1_params_formats[] = { + [RKISP1_PARAMS_FIXED] = { + .dataformat = V4L2_META_FMT_RK_ISP1_PARAMS, + .buffersize = sizeof(struct rkisp1_params_cfg), + }, + [RKISP1_PARAMS_EXTENSIBLE] = { + .dataformat = V4L2_META_FMT_RK_ISP1_EXT_PARAMS, + .buffersize = sizeof(struct rkisp1_ext_params_cfg), + }, +}; + +static const struct v4l2_meta_format * +rkisp1_params_get_format_info(u32 dataformat) +{ + for (unsigned int i = 0; i < RKISP1_PARAMS_NUM_FMT; i++) { + if (rkisp1_params_formats[i].dataformat == dataformat) + return &rkisp1_params_formats[i]; + } + + return &rkisp1_params_formats[RKISP1_PARAMS_FIXED]; +} + static inline void rkisp1_param_set_bits(struct rkisp1_params *params, u32 reg, u32 bit_mask) { @@ -1742,11 +1770,13 @@ static int rkisp1_params_enum_fmt_meta_out(struct file *file, void *priv, struct v4l2_fmtdesc *f) { struct video_device *video = video_devdata(file); + const struct v4l2_meta_format *metafmt; - if (f->index > 0 || f->type != video->queue->type) + if (f->index >= RKISP1_PARAMS_NUM_FMT || f->type != video->queue->type) return -EINVAL; - f->pixelformat = V4L2_META_FMT_RK_ISP1_PARAMS; + metafmt = &rkisp1_params_formats[f->index]; + f->pixelformat = metafmt->dataformat; return 0; } @@ -1755,14 +1785,44 @@ static int rkisp1_params_g_fmt_meta_out(struct file *file, void *fh, struct v4l2_format *f) { struct video_device *video = video_devdata(file); + struct rkisp1_params *params = video_get_drvdata(video); struct v4l2_meta_format *meta = &f->fmt.meta; if (f->type != video->queue->type) return -EINVAL; memset(meta, 0, sizeof(*meta)); - meta->dataformat = V4L2_META_FMT_RK_ISP1_PARAMS; - meta->buffersize = sizeof(struct rkisp1_params_cfg); + *meta = params->metafmt; + + return 0; +} + +static int rkisp1_params_try_fmt_meta_out(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct video_device *video = video_devdata(file); + struct v4l2_meta_format *meta = &f->fmt.meta; + + if (f->type != video->queue->type) + return -EINVAL; + + *meta = *rkisp1_params_get_format_info(meta->dataformat); + + return 0; +} + +static int rkisp1_params_s_fmt_meta_out(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct video_device *video = video_devdata(file); + struct rkisp1_params *params = video_get_drvdata(video); + struct v4l2_meta_format *meta = &f->fmt.meta; + + if (f->type != video->queue->type) + return -EINVAL; + + *meta = *rkisp1_params_get_format_info(meta->dataformat); + params->metafmt = *meta; return 0; } @@ -1792,8 +1852,8 @@ static const struct v4l2_ioctl_ops rkisp1_params_ioctl = { .vidioc_streamoff = vb2_ioctl_streamoff, .vidioc_enum_fmt_meta_out = rkisp1_params_enum_fmt_meta_out, .vidioc_g_fmt_meta_out = rkisp1_params_g_fmt_meta_out, - .vidioc_s_fmt_meta_out = rkisp1_params_g_fmt_meta_out, - .vidioc_try_fmt_meta_out = rkisp1_params_g_fmt_meta_out, + .vidioc_s_fmt_meta_out = rkisp1_params_s_fmt_meta_out, + .vidioc_try_fmt_meta_out = rkisp1_params_try_fmt_meta_out, .vidioc_querycap = rkisp1_params_querycap, .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, .vidioc_unsubscribe_event = v4l2_event_unsubscribe, @@ -1805,13 +1865,16 @@ static int rkisp1_params_vb2_queue_setup(struct vb2_queue *vq, unsigned int sizes[], struct device *alloc_devs[]) { + struct rkisp1_params *params = vq->drv_priv; + size_t buf_size = params->metafmt.buffersize; + *num_buffers = clamp_t(u32, *num_buffers, RKISP1_ISP_PARAMS_REQ_BUFS_MIN, RKISP1_ISP_PARAMS_REQ_BUFS_MAX); *num_planes = 1; - sizes[0] = sizeof(struct rkisp1_params_cfg); + sizes[0] = buf_size; return 0; } @@ -1831,10 +1894,14 @@ static void rkisp1_params_vb2_buf_queue(struct vb2_buffer *vb) static int rkisp1_params_vb2_buf_prepare(struct vb2_buffer *vb) { - if (vb2_plane_size(vb, 0) < sizeof(struct rkisp1_params_cfg)) + struct vb2_queue *vq = vb->vb2_queue; + struct rkisp1_params *params = vq->drv_priv; + size_t buf_size = params->metafmt.buffersize; + + if (vb2_plane_size(vb, 0) < buf_size) return -EINVAL; - vb2_set_plane_payload(vb, 0, sizeof(struct rkisp1_params_cfg)); + vb2_set_plane_payload(vb, 0, buf_size); return 0; } @@ -1929,6 +1996,8 @@ int rkisp1_params_register(struct rkisp1_device *rkisp1) else params->ops = &rkisp1_v10_params_ops; + params->metafmt = rkisp1_params_formats[RKISP1_PARAMS_FIXED]; + video_set_drvdata(vdev, params); node->pad.flags = MEDIA_PAD_FL_SOURCE; From patchwork Wed Jun 5 16:54:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 13687123 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 48D53188CDE for ; Wed, 5 Jun 2024 16:55:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717606517; cv=none; b=LPNG6gpa7jQ5KsgZJ2gG/KQzWmdXg2QjiWcXiSMPwlvxHrNVfBguYkZsKnCNk4qDlCIaYsN8TQXDOcn4ywci1jzAZvM0TUq0c5xUW7cB/q78ixfn6QX5vwEPIGSKz3o8Rnz3ceYqY4omh3BvfYr00GOBH9+k/HbxubKLRaQTVSg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717606517; c=relaxed/simple; bh=B+gf+ElSQkOiE14sk8bX0B0hGLpIcwUM9s1INqUD/x0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RfU81/fcB2AaREI8/b3nG9XnEu2Cj//VaJR+zGzT5wDgAXxyie0mKeWZYpXpthaaD8yo7Hz5xE3B7o2uoNs0oOLaD2dUVHCDY1stlTk596hLQi5ozwnXR4zLcuZYaU/oltNiUHEBvIfqs/PB4XqVXYnzGgwvmWLnD9fzmv6zwdg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=ebZRhNws; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="ebZRhNws" Received: from localhost.localdomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 224E37036; Wed, 5 Jun 2024 18:54:52 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1717606492; bh=B+gf+ElSQkOiE14sk8bX0B0hGLpIcwUM9s1INqUD/x0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ebZRhNwsm7ScJx603OXQqFIV331ckA8PCGih54ZwzdZWev+EWkLw0BmE7Qd/PYfOd rknvjJQn3FnJQouHjo0pTb6kdX7pzQZJqt2j0rLmm2TfrCupLNSG/6nsBfgWkUWlE7 RHpc4aY+WYyLKydA/0yMqLPc6bqzCY2iqnz2GxFE= From: Jacopo Mondi To: Linux Media Mailing List Cc: Jacopo Mondi , Laurent Pinchart , Sakari Ailus , Hans Verkuil , Stefan Klug , Paul Elder , Daniel Scally , Kieran Bingham , Umang Jain , Dafna Hirschfeld , Mauro Carvalho Chehab , Heiko Stuebner Subject: [PATCH 5/8] media: rkisp1: Implement extensible params support Date: Wed, 5 Jun 2024 18:54:24 +0200 Message-ID: <20240605165434.432230-6-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.45.1 In-Reply-To: <20240605165434.432230-1-jacopo.mondi@ideasonboard.com> References: <20240605165434.432230-1-jacopo.mondi@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Implement support in the rkisp1-params for the extensible configuration parameters format. Create a list of handlers for each ISP block that wraps the existing configuration functions and handles the ISP block enablement state. Parse the configuration parameters buffer in __rkisp1_ext_params_config and filter the enable blocks by group, to allow setting the 'other' and 'meas' groups separately from the 'lsc' group to support the pre/post-configure operations. Signed-off-by: Jacopo Mondi --- .../platform/rockchip/rkisp1/rkisp1-params.c | 565 +++++++++++++++++- 1 file changed, 544 insertions(+), 21 deletions(-) diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c index 6f99c7dad758..3d78e643d0b8 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c @@ -33,6 +33,10 @@ #define RKISP1_ISP_CC_COEFF(n) \ (RKISP1_CIF_ISP_CC_COEFF_0 + (n) * 4) +#define RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS BIT(0) +#define RKISP1_EXT_PARAMS_BLOCK_GROUP_MEAS BIT(1) +#define RKISP1_EXT_PARAMS_BLOCK_GROUP_LSC BIT(2) + enum rkisp1_params_formats { RKISP1_PARAMS_FIXED, RKISP1_PARAMS_EXTENSIBLE, @@ -1529,9 +1533,491 @@ static void rkisp1_isp_isr_meas_config(struct rkisp1_params *params, } } +/*------------------------------------------------------------------------------ + * Extensible parameters format handling + */ + +static void rkisp1_ext_params_bls(struct rkisp1_params *params, + struct rkisp1_ext_params_block_header *hdr) +{ + struct rkisp1_ext_params_bls_config *bls = + (struct rkisp1_ext_params_bls_config *)hdr; + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_DISABLE) { + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_BLS_CTRL, + RKISP1_CIF_ISP_BLS_ENA); + return; + } + + rkisp1_bls_config(params, &bls->bls_config); + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_ENABLE) + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_BLS_CTRL, + RKISP1_CIF_ISP_BLS_ENA); +} + +static void rkisp1_ext_params_dpcc(struct rkisp1_params *params, + struct rkisp1_ext_params_block_header *hdr) +{ + struct rkisp1_ext_params_dpcc_config *dpcc = + (struct rkisp1_ext_params_dpcc_config *)hdr; + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_DISABLE) { + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPCC_MODE, + RKISP1_CIF_ISP_DPCC_MODE_DPCC_ENABLE); + return; + } + + rkisp1_dpcc_config(params, &dpcc->dpcc_config); + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_ENABLE) + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_DPCC_MODE, + RKISP1_CIF_ISP_DPCC_MODE_DPCC_ENABLE); +} + +static void rkisp1_ext_params_sdg(struct rkisp1_params *params, + struct rkisp1_ext_params_block_header *hdr) +{ + struct rkisp1_ext_params_sdg_config *sdg = + (struct rkisp1_ext_params_sdg_config *)hdr; + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_DISABLE) { + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL, + RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA); + return; + } + + rkisp1_sdg_config(params, &sdg->sdg_config); + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_ENABLE) + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, + RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA); +} + +static void rkisp1_ext_params_lsc(struct rkisp1_params *params, + struct rkisp1_ext_params_block_header *hdr) +{ + struct rkisp1_ext_params_lsc_config *lsc = + (struct rkisp1_ext_params_lsc_config *)hdr; + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_DISABLE) { + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL, + RKISP1_CIF_ISP_LSC_CTRL_ENA); + return; + } + + rkisp1_lsc_config(params, &lsc->lsc_config); + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_ENABLE) + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_LSC_CTRL, + RKISP1_CIF_ISP_LSC_CTRL_ENA); +} + +static void rkisp1_ext_params_awbg(struct rkisp1_params *params, + struct rkisp1_ext_params_block_header *hdr) +{ + struct rkisp1_ext_params_awb_gain_config *awbg = + (struct rkisp1_ext_params_awb_gain_config *)hdr; + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_DISABLE) { + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL, + RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA); + return; + } + + params->ops->awb_gain_config(params, &awbg->awb_config); + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_ENABLE) + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, + RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA); +} + +static void rkisp1_ext_params_flt(struct rkisp1_params *params, + struct rkisp1_ext_params_block_header *hdr) +{ + struct rkisp1_ext_params_flt_config *flt = + (struct rkisp1_ext_params_flt_config *)hdr; + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_DISABLE) { + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_FILT_MODE, + RKISP1_CIF_ISP_FLT_ENA); + return; + } + + rkisp1_flt_config(params, &flt->flt_config); + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_ENABLE) + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_FILT_MODE, + RKISP1_CIF_ISP_FLT_ENA); +} + +static void rkisp1_ext_params_bdm(struct rkisp1_params *params, + struct rkisp1_ext_params_block_header *hdr) +{ + struct rkisp1_ext_params_bdm_config *bdm = + (struct rkisp1_ext_params_bdm_config *)hdr; + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_DISABLE) { + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DEMOSAIC, + RKISP1_CIF_ISP_DEMOSAIC_BYPASS); + return; + } + + rkisp1_bdm_config(params, &bdm->bdm_config); + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_ENABLE) + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_DEMOSAIC, + RKISP1_CIF_ISP_DEMOSAIC_BYPASS); +} + +static void rkisp1_ext_params_ctk(struct rkisp1_params *params, + struct rkisp1_ext_params_block_header *hdr) +{ + struct rkisp1_ext_params_ctk_config *ctk = + (struct rkisp1_ext_params_ctk_config *)hdr; + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_DISABLE) { + rkisp1_ctk_enable(params, false); + return; + } + + rkisp1_ctk_config(params, &ctk->ctk_config); + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_ENABLE) + rkisp1_ctk_enable(params, true); +} + +static void rkisp1_ext_params_goc(struct rkisp1_params *params, + struct rkisp1_ext_params_block_header *hdr) +{ + struct rkisp1_ext_params_goc_config *goc = + (struct rkisp1_ext_params_goc_config *)hdr; + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_DISABLE) { + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL, + RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA); + return; + } + + params->ops->goc_config(params, &goc->goc_config); + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_ENABLE) + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, + RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA); +} + +static void rkisp1_ext_params_dpf(struct rkisp1_params *params, + struct rkisp1_ext_params_block_header *hdr) +{ + struct rkisp1_ext_params_dpf_config *dpf = + (struct rkisp1_ext_params_dpf_config *)hdr; + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_DISABLE) { + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPF_MODE, + RKISP1_CIF_ISP_DPF_MODE_EN); + return; + } + + rkisp1_dpf_config(params, &dpf->dpf_config); + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_ENABLE) + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_DPF_MODE, + RKISP1_CIF_ISP_DPF_MODE_EN); +} + +static void rkisp1_ext_params_dpfs(struct rkisp1_params *params, + struct rkisp1_ext_params_block_header *hdr) +{ + struct rkisp1_ext_params_dpf_strength_config *dpfs = + (struct rkisp1_ext_params_dpf_strength_config *)hdr; + + rkisp1_dpf_strength_config(params, &dpfs->dpf_strength_config); +} + +static void rkisp1_ext_params_cproc(struct rkisp1_params *params, + struct rkisp1_ext_params_block_header *hdr) +{ + struct rkisp1_ext_params_cproc_config *cproc = + (struct rkisp1_ext_params_cproc_config *)hdr; + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_DISABLE) { + rkisp1_param_clear_bits(params, RKISP1_CIF_C_PROC_CTRL, + RKISP1_CIF_C_PROC_CTR_ENABLE); + return; + } + + rkisp1_cproc_config(params, &cproc->cproc_config); + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_ENABLE) + rkisp1_param_set_bits(params, RKISP1_CIF_C_PROC_CTRL, + RKISP1_CIF_C_PROC_CTR_ENABLE); +} + +static void rkisp1_ext_params_ie(struct rkisp1_params *params, + struct rkisp1_ext_params_block_header *hdr) +{ + struct rkisp1_ext_params_ie_config *ie = + (struct rkisp1_ext_params_ie_config *)hdr; + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_DISABLE) { + rkisp1_ie_enable(params, false); + return; + } + + rkisp1_ie_config(params, &ie->ie_config); + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_ENABLE) + rkisp1_ie_enable(params, true); +} + +static void rkisp1_ext_params_awbm(struct rkisp1_params *params, + struct rkisp1_ext_params_block_header *hdr) +{ + struct rkisp1_ext_params_awb_meas_config *awbm = + (struct rkisp1_ext_params_awb_meas_config *)hdr; + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_DISABLE) { + params->ops->awb_meas_enable(params, &awbm->awb_meas_config, + false); + return; + } + + params->ops->awb_meas_config(params, &awbm->awb_meas_config); + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_ENABLE) + params->ops->awb_meas_enable(params, &awbm->awb_meas_config, + true); +} + +static void rkisp1_ext_params_hstm(struct rkisp1_params *params, + struct rkisp1_ext_params_block_header *hdr) +{ + struct rkisp1_ext_params_hst_config *hst = + (struct rkisp1_ext_params_hst_config *)hdr; + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_DISABLE) { + params->ops->hst_enable(params, &hst->hst_config, false); + return; + } + + params->ops->hst_config(params, &hst->hst_config); + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_ENABLE) + params->ops->hst_enable(params, &hst->hst_config, true); +} + +static void rkisp1_ext_params_aecm(struct rkisp1_params *params, + struct rkisp1_ext_params_block_header *hdr) +{ + struct rkisp1_ext_params_aec_config *aec = + (struct rkisp1_ext_params_aec_config *)hdr; + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_DISABLE) { + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_EXP_CTRL, + RKISP1_CIF_ISP_EXP_ENA); + return; + } + + params->ops->aec_config(params, &aec->aec_config); + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_ENABLE) + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_EXP_CTRL, + RKISP1_CIF_ISP_EXP_ENA); +} + +static void rkisp1_ext_params_afcm(struct rkisp1_params *params, + struct rkisp1_ext_params_block_header *hdr) +{ + struct rkisp1_ext_params_afc_config *afc = + (struct rkisp1_ext_params_afc_config *)hdr; + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_DISABLE) { + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL, + RKISP1_CIF_ISP_AFM_ENA); + return; + } + + params->ops->afm_config(params, &afc->afc_config); + + if (hdr->state == RKISP1_EXT_PARAMS_BLOCK_ENABLE) + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_AFM_CTRL, + RKISP1_CIF_ISP_AFM_ENA); +} + +typedef void (*rkisp1_block_handler)(struct rkisp1_params *params, + struct rkisp1_ext_params_block_header *hdr); + +static const struct rkisp1_ext_params_handler { + size_t size; + rkisp1_block_handler handler; + unsigned int group; +} rkisp1_ext_params_handlers[] = { + [RKISP1_EXT_PARAMS_BLOCK_TYPE_BLS] = { + .size = sizeof(struct rkisp1_ext_params_bls_config), + .handler = rkisp1_ext_params_bls, + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS + }, + [RKISP1_EXT_PARAMS_BLOCK_TYPE_DPCC] = { + .size = sizeof(struct rkisp1_ext_params_dpcc_config), + .handler = rkisp1_ext_params_dpcc, + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS + }, + [RKISP1_EXT_PARAMS_BLOCK_TYPE_SDG] = { + .size = sizeof(struct rkisp1_ext_params_sdg_config), + .handler = rkisp1_ext_params_sdg, + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS + }, + [RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_GAINS] = { + .size = + sizeof(struct rkisp1_ext_params_awb_gain_config), + .handler = rkisp1_ext_params_awbg, + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS + }, + [RKISP1_EXT_PARAMS_BLOCK_TYPE_FLT] = { + .size = sizeof(struct rkisp1_ext_params_flt_config), + .handler = rkisp1_ext_params_flt, + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS + }, + [RKISP1_EXT_PARAMS_BLOCK_TYPE_BDM] = { + .size = sizeof(struct rkisp1_ext_params_bdm_config), + .handler = rkisp1_ext_params_bdm, + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS + }, + [RKISP1_EXT_PARAMS_BLOCK_TYPE_CTK] = { + .size = sizeof(struct rkisp1_ext_params_ctk_config), + .handler = rkisp1_ext_params_ctk, + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS + }, + [RKISP1_EXT_PARAMS_BLOCK_TYPE_GOC] = { + .size = sizeof(struct rkisp1_ext_params_goc_config), + .handler = rkisp1_ext_params_goc, + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS + }, + [RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF] = { + .size = sizeof(struct rkisp1_ext_params_dpf_config), + .handler = rkisp1_ext_params_dpf, + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS + }, + [RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF_STRENGHT] = { + .size = + sizeof(struct rkisp1_ext_params_dpf_strength_config), + .handler = rkisp1_ext_params_dpfs, + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS + }, + [RKISP1_EXT_PARAMS_BLOCK_TYPE_CPROC] = { + .size = sizeof(struct rkisp1_ext_params_cproc_config), + .handler = rkisp1_ext_params_cproc, + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS + }, + [RKISP1_EXT_PARAMS_BLOCK_TYPE_IE] = { + .size = sizeof(struct rkisp1_ext_params_ie_config), + .handler = rkisp1_ext_params_ie, + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS + }, + [RKISP1_EXT_PARAMS_BLOCK_TYPE_LSC] = { + .size = sizeof(struct rkisp1_ext_params_lsc_config), + .handler = rkisp1_ext_params_lsc, + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_LSC + }, + [RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_MEAS] = { + .size = + sizeof(struct rkisp1_ext_params_awb_meas_config), + .handler = rkisp1_ext_params_awbm, + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_MEAS + }, + [RKISP1_EXT_PARAMS_BLOCK_TYPE_HST_MEAS] = { + .size = sizeof(struct rkisp1_ext_params_hst_config), + .handler = rkisp1_ext_params_hstm, + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_MEAS + }, + [RKISP1_EXT_PARAMS_BLOCK_TYPE_AEC_MEAS] = { + .size = sizeof(struct rkisp1_ext_params_aec_config), + .handler = rkisp1_ext_params_aecm, + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_MEAS + }, + [RKISP1_EXT_PARAMS_BLOCK_TYPE_AFC_MEAS] = { + .size = sizeof(struct rkisp1_ext_params_afc_config), + .handler = rkisp1_ext_params_afcm, + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_MEAS + }, +}; + +static int __rkisp1_ext_params_config(struct rkisp1_params *params, + struct rkisp1_ext_params_cfg *cfg, + u32 block_group_mask) +{ + size_t block_offset = 0; + + if (cfg->total_size > RKISP1_EXT_PARAMS_MAX_SIZE) { + dev_dbg(params->rkisp1->dev, + "Invalid parameters buffer size %llu\n", + cfg->total_size); + return -EINVAL; + } + + /* Walk the list of parameter blocks and process them. */ + while (block_offset < cfg->total_size) { + const struct rkisp1_ext_params_handler *block_handler; + struct rkisp1_ext_params_block_header *block; + + block = (struct rkisp1_ext_params_block_header *) + &cfg->data[block_offset]; + block_offset += block->size; + + /* + * Validate the block id and make sure the block group is in + * the list of groups to configure. + */ + if (block->type >= RKISP1_EXT_PARAMS_BLOCK_TYPE_SENTINEL) { + dev_dbg(params->rkisp1->dev, + "Invalid parameters block type\n"); + return -EINVAL; + } + + block_handler = &rkisp1_ext_params_handlers[block->type]; + if (!(block_handler->group & block_group_mask)) + continue; + + if (block->size != block_handler->size) { + dev_dbg(params->rkisp1->dev, + "Invalid parameters block size\n"); + return -EINVAL; + } + + block_handler->handler(params, block); + } + + return 0; +} + +static int rkisp1_ext_params_config(struct rkisp1_params *params, + struct rkisp1_ext_params_cfg *cfg) +{ + return __rkisp1_ext_params_config(params, cfg, + RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS | + RKISP1_EXT_PARAMS_BLOCK_GROUP_LSC | + RKISP1_EXT_PARAMS_BLOCK_GROUP_MEAS); +} + +static int +rkisp1_ext_params_other_meas_config(struct rkisp1_params *params, + struct rkisp1_ext_params_cfg *cfg) +{ + return __rkisp1_ext_params_config(params, cfg, + RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS | + RKISP1_EXT_PARAMS_BLOCK_GROUP_MEAS); +} + +static int rkisp1_ext_params_lsc_config(struct rkisp1_params *params, + struct rkisp1_ext_params_cfg *cfg) +{ + return __rkisp1_ext_params_config(params, cfg, + RKISP1_EXT_PARAMS_BLOCK_GROUP_LSC); +} + static bool rkisp1_params_get_buffer(struct rkisp1_params *params, struct rkisp1_buffer **buf, - struct rkisp1_params_cfg **cfg) + void **cfg) { if (list_empty(¶ms->params)) return false; @@ -1544,28 +2030,37 @@ static bool rkisp1_params_get_buffer(struct rkisp1_params *params, static void rkisp1_params_complete_buffer(struct rkisp1_params *params, struct rkisp1_buffer *buf, - unsigned int frame_sequence) + unsigned int frame_sequence, + enum vb2_buffer_state state) { list_del(&buf->queue); buf->vb.sequence = frame_sequence; - vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + vb2_buffer_done(&buf->vb.vb2_buf, state); } void rkisp1_params_isr(struct rkisp1_device *rkisp1) { struct rkisp1_params *params = &rkisp1->params; - struct rkisp1_params_cfg *new_params; - struct rkisp1_buffer *cur_buf; + struct rkisp1_buffer *buf; + int ret = 0; + void *cfg; spin_lock(¶ms->config_lock); - if (!rkisp1_params_get_buffer(params, &cur_buf, &new_params)) + if (!rkisp1_params_get_buffer(params, &buf, &cfg)) goto unlock; - rkisp1_isp_isr_other_config(params, new_params); - rkisp1_isp_isr_lsc_config(params, new_params); - rkisp1_isp_isr_meas_config(params, new_params); + if (params->metafmt.dataformat == V4L2_META_FMT_RK_ISP1_PARAMS) { + rkisp1_isp_isr_other_config(params, cfg); + rkisp1_isp_isr_lsc_config(params, cfg); + rkisp1_isp_isr_meas_config(params, cfg); + } else { + ret = rkisp1_ext_params_config(params, cfg); + } + + if (ret) + goto complete_and_unlock; /* update shadow register immediately */ rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, @@ -1579,8 +2074,11 @@ void rkisp1_params_isr(struct rkisp1_device *rkisp1) * indicate to userspace on which frame these parameters are being * applied. */ - rkisp1_params_complete_buffer(params, cur_buf, - rkisp1->isp.frame_sequence + 1); +complete_and_unlock: + rkisp1_params_complete_buffer(params, buf, + rkisp1->isp.frame_sequence + 1, + ret ? VB2_BUF_STATE_ERROR + : VB2_BUF_STATE_DONE); unlock: spin_unlock(¶ms->config_lock); @@ -1631,8 +2129,9 @@ void rkisp1_params_pre_configure(struct rkisp1_params *params, enum v4l2_ycbcr_encoding ycbcr_encoding) { struct rkisp1_cif_isp_hst_config hst = rkisp1_hst_params_default_config; - struct rkisp1_params_cfg *new_params; - struct rkisp1_buffer *cur_buf; + struct rkisp1_buffer *buf; + int ret = 0; + void *cfg; params->quantization = quantization; params->ycbcr_encoding = ycbcr_encoding; @@ -1661,11 +2160,26 @@ void rkisp1_params_pre_configure(struct rkisp1_params *params, /* apply the first buffer if there is one already */ - if (!rkisp1_params_get_buffer(params, &cur_buf, &new_params)) + if (!rkisp1_params_get_buffer(params, &buf, &cfg)) goto unlock; - rkisp1_isp_isr_other_config(params, new_params); - rkisp1_isp_isr_meas_config(params, new_params); + if (params->metafmt.dataformat == V4L2_META_FMT_RK_ISP1_PARAMS) { + rkisp1_isp_isr_other_config(params, cfg); + rkisp1_isp_isr_meas_config(params, cfg); + } else { + ret = rkisp1_ext_params_other_meas_config(params, cfg); + } + + if (ret) { + /* + * Complete the buffer in error state immediately. In case of no + * error, the buffer will be completed in + * rkisp1_params_post_configure(). + */ + rkisp1_params_complete_buffer(params, buf, 0, + VB2_BUF_STATE_ERROR); + goto unlock; + } /* update shadow register immediately */ rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, @@ -1677,8 +2191,9 @@ void rkisp1_params_pre_configure(struct rkisp1_params *params, void rkisp1_params_post_configure(struct rkisp1_params *params) { - struct rkisp1_params_cfg *new_params; - struct rkisp1_buffer *cur_buf; + struct rkisp1_buffer *buf; + int ret = 0; + void *cfg; spin_lock_irq(¶ms->config_lock); @@ -1691,16 +2206,24 @@ void rkisp1_params_post_configure(struct rkisp1_params *params) * unconditionally. */ - if (!rkisp1_params_get_buffer(params, &cur_buf, &new_params)) + if (!rkisp1_params_get_buffer(params, &buf, &cfg)) goto unlock; - rkisp1_isp_isr_lsc_config(params, new_params); + if (params->metafmt.dataformat == V4L2_META_FMT_RK_ISP1_PARAMS) + rkisp1_isp_isr_lsc_config(params, cfg); + else + ret = rkisp1_ext_params_lsc_config(params, cfg); + + if (ret) + goto complete_and_unlock; /* update shadow register immediately */ rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD); - rkisp1_params_complete_buffer(params, cur_buf, 0); +complete_and_unlock: + rkisp1_params_complete_buffer(params, buf, 0, ret ? VB2_BUF_STATE_ERROR + : VB2_BUF_STATE_DONE); unlock: spin_unlock_irq(¶ms->config_lock); From patchwork Wed Jun 5 16:54:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 13687124 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 01732188CA8 for ; Wed, 5 Jun 2024 16:55:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717606518; cv=none; b=QnBcthdChz3VP1LsBrI4q9ecG1yl4c3Y+Kkn472PShfS+O0F4qhB6EndQEIVp/TGfJTYQIeljpy+92Qt6Ml4lCNLur1e102Zc5rTQS3AdGZGTMJ4QgGxOrxMbDf3Vx/vKSoEe5gLifA8yDVTSSWUNRsJQbikRfK72B+9hi/eS5E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717606518; c=relaxed/simple; bh=3UFN83ixbTHSRCJ4lLIcB6Ls9TqzRWiqCGTVYxYyqJo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Qx3Nbc0qyQl2aUWqr+AwhIaUFz4UROirX/7TiMqqYZ72sQGU9L1KF1GnKjJiGaQZi1rGQyHNKR2x9uJKkESi1G2B7GbQzpVPrDj7a2pCVe2OxItwHwgt3/Y+YKoybnERn5HM+epC5cgtI0dfJXLe5zlMx/wiXoNxbDRqtOqWqV8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=huIaSsQS; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="huIaSsQS" Received: from localhost.localdomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 0BA967047; Wed, 5 Jun 2024 18:54:53 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1717606493; bh=3UFN83ixbTHSRCJ4lLIcB6Ls9TqzRWiqCGTVYxYyqJo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=huIaSsQSNFi34Soh1GRIww4HJ2Cw7dWHWpKqUMllOi4GlHwizrvY11Zcc8Z4nGTeo tsNhxcp7BoPYKMLWrUqK1MIJfkEOP6V0xHCgmrLb8a/fQ7uEKCO7xrUV10mrmvxKyc c9XIbTVvPCAhz+d/RUjO78XNj3hOTwxyscOcjd/4= From: Jacopo Mondi To: Linux Media Mailing List Cc: Jacopo Mondi , Laurent Pinchart , Sakari Ailus , Hans Verkuil , Stefan Klug , Paul Elder , Daniel Scally , Kieran Bingham , Umang Jain , Dafna Hirschfeld , Mauro Carvalho Chehab , Heiko Stuebner Subject: [PATCH 6/8] media: rkisp1: Propagate pre/post-config errors Date: Wed, 5 Jun 2024 18:54:25 +0200 Message-ID: <20240605165434.432230-7-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.45.1 In-Reply-To: <20240605165434.432230-1-jacopo.mondi@ideasonboard.com> References: <20240605165434.432230-1-jacopo.mondi@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The support for the extensible parameters format introduces the possibility of failures in handling the parameters buffer. Errors in parsing the configuration parameters are not propagated to the rkisp1_config_isp() and the rkisp1_isp_start() functions. Propagate any possible errors to the callers to report it to userspace. Signed-off-by: Jacopo Mondi --- .../media/platform/rockchip/rkisp1/rkisp1-common.h | 10 +++++----- .../media/platform/rockchip/rkisp1/rkisp1-isp.c | 14 +++++++++----- .../media/platform/rockchip/rkisp1/rkisp1-params.c | 14 +++++++++----- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h index 0bddae8dbdb1..f9df5ed96c98 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h @@ -591,10 +591,10 @@ const struct rkisp1_mbus_info *rkisp1_mbus_info_get_by_code(u32 mbus_code); * It applies the initial ISP parameters from the first params buffer, but * skips LSC as it needs to be configured after the ISP is started. */ -void rkisp1_params_pre_configure(struct rkisp1_params *params, - enum rkisp1_fmt_raw_pat_type bayer_pat, - enum v4l2_quantization quantization, - enum v4l2_ycbcr_encoding ycbcr_encoding); +int rkisp1_params_pre_configure(struct rkisp1_params *params, + enum rkisp1_fmt_raw_pat_type bayer_pat, + enum v4l2_quantization quantization, + enum v4l2_ycbcr_encoding ycbcr_encoding); /* * rkisp1_params_post_configure - Configure the params after stream start @@ -604,7 +604,7 @@ void rkisp1_params_pre_configure(struct rkisp1_params *params, * This function is called by the ISP entity just after the ISP gets started. * It applies the initial ISP LSC parameters from the first params buffer. */ -void rkisp1_params_post_configure(struct rkisp1_params *params); +int rkisp1_params_post_configure(struct rkisp1_params *params); /* rkisp1_params_disable - disable all parameters. * This function is called by the isp entity upon stream start diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c index 91301d17d356..05227c6a16fe 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c @@ -310,12 +310,16 @@ static int rkisp1_config_isp(struct rkisp1_isp *isp, rkisp1_params_disable(&rkisp1->params); } else { const struct v4l2_mbus_framefmt *src_frm; + int ret; src_frm = v4l2_subdev_state_get_format(sd_state, RKISP1_ISP_PAD_SOURCE_VIDEO); - rkisp1_params_pre_configure(&rkisp1->params, sink_fmt->bayer_pat, - src_frm->quantization, - src_frm->ycbcr_enc); + ret = rkisp1_params_pre_configure(&rkisp1->params, + sink_fmt->bayer_pat, + src_frm->quantization, + src_frm->ycbcr_enc); + if (ret) + return ret; } isp->sink_fmt = sink_fmt; @@ -458,9 +462,9 @@ static int rkisp1_isp_start(struct rkisp1_isp *isp, src_info = rkisp1_mbus_info_get_by_code(src_fmt->code); if (src_info->pixel_enc != V4L2_PIXEL_ENC_BAYER) - rkisp1_params_post_configure(&rkisp1->params); + ret = rkisp1_params_post_configure(&rkisp1->params); - return 0; + return ret; } /* ---------------------------------------------------------------------------- diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c index 3d78e643d0b8..c081fd490b2b 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c @@ -2123,10 +2123,10 @@ static const struct rkisp1_cif_isp_afc_config rkisp1_afc_params_default_config = 14 }; -void rkisp1_params_pre_configure(struct rkisp1_params *params, - enum rkisp1_fmt_raw_pat_type bayer_pat, - enum v4l2_quantization quantization, - enum v4l2_ycbcr_encoding ycbcr_encoding) +int rkisp1_params_pre_configure(struct rkisp1_params *params, + enum rkisp1_fmt_raw_pat_type bayer_pat, + enum v4l2_quantization quantization, + enum v4l2_ycbcr_encoding ycbcr_encoding) { struct rkisp1_cif_isp_hst_config hst = rkisp1_hst_params_default_config; struct rkisp1_buffer *buf; @@ -2187,9 +2187,11 @@ void rkisp1_params_pre_configure(struct rkisp1_params *params, unlock: spin_unlock_irq(¶ms->config_lock); + + return ret; } -void rkisp1_params_post_configure(struct rkisp1_params *params) +int rkisp1_params_post_configure(struct rkisp1_params *params) { struct rkisp1_buffer *buf; int ret = 0; @@ -2227,6 +2229,8 @@ void rkisp1_params_post_configure(struct rkisp1_params *params) unlock: spin_unlock_irq(¶ms->config_lock); + + return ret; } /* From patchwork Wed Jun 5 16:54:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 13687125 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 34670188CA8 for ; Wed, 5 Jun 2024 16:55:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717606522; cv=none; b=Dvyo/w7ijfm9kX5aLnqtoISbvPHHe+xXuQwdLoZ2XhY8Pw/Uz6BEpMbBDUcUJKkoYQSZTSGZGfCB/LXMk2VrCXhJPpx+XLWz/HoK6X1KcoPH/CO0ZT2Iz6pyQDWo5ryTUdFHnLdue72ZvwJI4vsPgzi6Texck5+JWJaTliurbDU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717606522; c=relaxed/simple; bh=Gcy9/fXc+lfrnNZrX6Y2uiaLBEDB/nrWRgeaEJCzRYQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pPYu+PYPgAiFHEN9ikx/ew6P12WZoXFxFl8AhhlRo7UhyDlAM9HHD8ZrwzdkeBNbMfONKCdz77GAHmKlWl4NNCGwOiagE25VB9gMqTOta3x46v4ISH/7WEgvmv4qUGfa+EX/leRpkmEO+eWSf4qXo6hYeyO7LeIP2KUhw8q1qos= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=HVuZeGh0; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="HVuZeGh0" Received: from localhost.localdomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D71C7704B; Wed, 5 Jun 2024 18:54:53 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1717606494; bh=Gcy9/fXc+lfrnNZrX6Y2uiaLBEDB/nrWRgeaEJCzRYQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HVuZeGh0bpEpy15wb0CmDT0ND2aRHGnQa0u7otIObqSMvcsVc+MX1qjhmMXBNcYKa ZKbr7nZbRIAYeaC3xaUrgO/MEHI6u0+LRgjNXPO3oO5qta4kaJ81jA9dEVpgzl0SUF +RB3VI3ZFfPp1BDaDNiGGbqhseVjgNK14jDHkJAs= From: Jacopo Mondi To: Linux Media Mailing List Cc: Jacopo Mondi , Laurent Pinchart , Sakari Ailus , Hans Verkuil , Stefan Klug , Paul Elder , Daniel Scally , Kieran Bingham , Umang Jain , Dafna Hirschfeld , Mauro Carvalho Chehab , Heiko Stuebner Subject: [PATCH 7/8] media: rkisp1: Add struct rkisp1_params_buffer Date: Wed, 5 Jun 2024 18:54:26 +0200 Message-ID: <20240605165434.432230-8-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.45.1 In-Reply-To: <20240605165434.432230-1-jacopo.mondi@ideasonboard.com> References: <20240605165434.432230-1-jacopo.mondi@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Create the 'struct rkisp1_params_buffer' type that wraps a vb2_v4l2_buffer and contain a pointer to an optional copy of the parameters buffer that will be used to copy the user-provided configuration buffer in the following patches. Replace usage of 'struct rkisp1_buffer' with 'struct rkisp1_params_buffer' in rkisp1-params.c to prepare for that. Signed-off-by: Jacopo Mondi Reviewed-by: Daniel Scally --- .../platform/rockchip/rkisp1/rkisp1-common.h | 16 +++++++++++++- .../platform/rockchip/rkisp1/rkisp1-params.c | 21 ++++++++++--------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h index f9df5ed96c98..3118f1974246 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h @@ -232,7 +232,7 @@ struct rkisp1_vdev_node { /* * struct rkisp1_buffer - A container for the vb2 buffers used by the video devices: - * params, stats, mainpath, selfpath + * stats, mainpath, selfpath * * @vb: vb2 buffer * @queue: entry of the buffer in the queue @@ -244,6 +244,20 @@ struct rkisp1_buffer { dma_addr_t buff_addr[VIDEO_MAX_PLANES]; }; +/* + * struct rkisp1_params_buffer - A container for the vb2 buffers used by the + * params video device + * + * @vb: vb2 buffer + * @queue: entry of the buffer in the queue + * cfg: scratch buffer used for the extensible parameters format + */ +struct rkisp1_params_buffer { + struct vb2_v4l2_buffer vb; + struct list_head queue; + struct rkisp1_ext_params_cfg *cfg; +}; + /* * struct rkisp1_dummy_buffer - A buffer to write the next frame to in case * there are no vb2 buffers available. diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c index c081fd490b2b..4adaf084ce6e 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c @@ -2016,20 +2016,21 @@ static int rkisp1_ext_params_lsc_config(struct rkisp1_params *params, } static bool rkisp1_params_get_buffer(struct rkisp1_params *params, - struct rkisp1_buffer **buf, + struct rkisp1_params_buffer **buf, void **cfg) { if (list_empty(¶ms->params)) return false; - *buf = list_first_entry(¶ms->params, struct rkisp1_buffer, queue); + *buf = list_first_entry(¶ms->params, struct rkisp1_params_buffer, + queue); *cfg = vb2_plane_vaddr(&(*buf)->vb.vb2_buf, 0); return true; } static void rkisp1_params_complete_buffer(struct rkisp1_params *params, - struct rkisp1_buffer *buf, + struct rkisp1_params_buffer *buf, unsigned int frame_sequence, enum vb2_buffer_state state) { @@ -2042,7 +2043,7 @@ static void rkisp1_params_complete_buffer(struct rkisp1_params *params, void rkisp1_params_isr(struct rkisp1_device *rkisp1) { struct rkisp1_params *params = &rkisp1->params; - struct rkisp1_buffer *buf; + struct rkisp1_params_buffer *buf; int ret = 0; void *cfg; @@ -2129,7 +2130,7 @@ int rkisp1_params_pre_configure(struct rkisp1_params *params, enum v4l2_ycbcr_encoding ycbcr_encoding) { struct rkisp1_cif_isp_hst_config hst = rkisp1_hst_params_default_config; - struct rkisp1_buffer *buf; + struct rkisp1_params_buffer *buf; int ret = 0; void *cfg; @@ -2193,7 +2194,7 @@ int rkisp1_params_pre_configure(struct rkisp1_params *params, int rkisp1_params_post_configure(struct rkisp1_params *params) { - struct rkisp1_buffer *buf; + struct rkisp1_params_buffer *buf; int ret = 0; void *cfg; @@ -2409,8 +2410,8 @@ static int rkisp1_params_vb2_queue_setup(struct vb2_queue *vq, static void rkisp1_params_vb2_buf_queue(struct vb2_buffer *vb) { struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); - struct rkisp1_buffer *params_buf = - container_of(vbuf, struct rkisp1_buffer, vb); + struct rkisp1_params_buffer *params_buf = + container_of(vbuf, struct rkisp1_params_buffer, vb); struct vb2_queue *vq = vb->vb2_queue; struct rkisp1_params *params = vq->drv_priv; @@ -2436,7 +2437,7 @@ static int rkisp1_params_vb2_buf_prepare(struct vb2_buffer *vb) static void rkisp1_params_vb2_stop_streaming(struct vb2_queue *vq) { struct rkisp1_params *params = vq->drv_priv; - struct rkisp1_buffer *buf; + struct rkisp1_params_buffer *buf; LIST_HEAD(tmp_list); /* @@ -2482,7 +2483,7 @@ static int rkisp1_params_init_vb2_queue(struct vb2_queue *q, q->drv_priv = params; q->ops = &rkisp1_params_vb2_ops; q->mem_ops = &vb2_vmalloc_memops; - q->buf_struct_size = sizeof(struct rkisp1_buffer); + q->buf_struct_size = sizeof(struct rkisp1_params_buffer); q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; q->lock = &node->vlock; From patchwork Wed Jun 5 16:54:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 13687126 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C17D518FDD3 for ; Wed, 5 Jun 2024 16:55:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717606523; cv=none; b=g3+39Jti7RTaB1yh3XSy0fwFBdwlw8JD/1xZN+TNYHGhOzUHmzbrVED0AXDLant594Gc+55nMhPoHJqeTV7o6rJClu3o+kUIy3LCwdVJAme2Oolf6YmTT1liJ9kJeCS7MXTcTxTbE4JbpXN4+Ql6c1ZEICXpQ81+pPGsUHVWTPw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717606523; c=relaxed/simple; bh=qPBoCcTqe1iwoQiJLT2/L7KdyVcSdBcZyfE+zy85RiM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Z1B9ZKN9UzBaoVH3IvrL1vQTbxtsMUhPFM6rj/jEpHFbBXq5e1RMhtEOwKIXS0Z+jtJXW9muihYzLkoYFl6CYYIEaEA2NabGptqrIZO0RQDtiPR5X6K+UxS4S6Gj9HS9JwbNneX6qgxp1p1uZ4JklDKoFUlG66vIREdxA7cJtxk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=qmsjWk2P; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="qmsjWk2P" Received: from localhost.localdomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B0B787051; Wed, 5 Jun 2024 18:54:54 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1717606495; bh=qPBoCcTqe1iwoQiJLT2/L7KdyVcSdBcZyfE+zy85RiM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qmsjWk2PWNyCA9HIN+rP3adxGkI+RzBivk1XEI9+wJBx9XNuPBAJlC1XT25WG8Fq/ T3MYV3C0ePydqC5hOdVOCZ9IJ9rF3BV4Febe7ThKOtFEotoEUALe4CrCOJP+XLxW9C yY49MX9ggqfl73OLU0wUNywUm0KpiCQ6TVF8YYFY= From: Jacopo Mondi To: Linux Media Mailing List Cc: Jacopo Mondi , Laurent Pinchart , Sakari Ailus , Hans Verkuil , Stefan Klug , Paul Elder , Daniel Scally , Kieran Bingham , Umang Jain , Dafna Hirschfeld , Mauro Carvalho Chehab , Heiko Stuebner Subject: [PATCH 8/8] media: rkisp1: Copy and validate parameters buffer Date: Wed, 5 Jun 2024 18:54:27 +0200 Message-ID: <20240605165434.432230-9-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.45.1 In-Reply-To: <20240605165434.432230-1-jacopo.mondi@ideasonboard.com> References: <20240605165434.432230-1-jacopo.mondi@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 With the introduction of the extensible parameters format support in the rkisp1-param.c module, the RkISP1 driver now configures the ISP blocks by parsing the content of a data buffer of variable size provided by userspace through the V4L2 meta-output interface using the MMAP memory handling mode. As the parameters buffer is mapped in the userspace process memory, applications have access to the buffer content while the driver parses it. To prevent potential issues during the parameters buffer parsing and processing in the driver, implement three vb2_ops to 1) allocate a scratch buffer in the driver private buffer structure 2) validate the buffer content at VIDIOC_QBUF time 3) copy the content of the user provided configuration parameters in the driver-private scratch buffer Signed-off-by: Jacopo Mondi --- .../platform/rockchip/rkisp1/rkisp1-params.c | 154 ++++++++++++++---- 1 file changed, 124 insertions(+), 30 deletions(-) diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c index 4adaf084ce6e..003239e14511 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c @@ -5,6 +5,8 @@ * Copyright (C) 2017 Rockchip Electronics Co., Ltd. */ +#include + #include #include #include @@ -1943,17 +1945,14 @@ static const struct rkisp1_ext_params_handler { }; static int __rkisp1_ext_params_config(struct rkisp1_params *params, - struct rkisp1_ext_params_cfg *cfg, + struct rkisp1_params_buffer *buffer, u32 block_group_mask) { + struct rkisp1_ext_params_cfg *cfg = buffer->cfg; size_t block_offset = 0; - if (cfg->total_size > RKISP1_EXT_PARAMS_MAX_SIZE) { - dev_dbg(params->rkisp1->dev, - "Invalid parameters buffer size %llu\n", - cfg->total_size); - return -EINVAL; - } + if (WARN_ON(!cfg)) + return -ENOMEM; /* Walk the list of parameter blocks and process them. */ while (block_offset < cfg->total_size) { @@ -1965,25 +1964,13 @@ static int __rkisp1_ext_params_config(struct rkisp1_params *params, block_offset += block->size; /* - * Validate the block id and make sure the block group is in - * the list of groups to configure. + * Make sure the block group is in the list of groups to + * configure. */ - if (block->type >= RKISP1_EXT_PARAMS_BLOCK_TYPE_SENTINEL) { - dev_dbg(params->rkisp1->dev, - "Invalid parameters block type\n"); - return -EINVAL; - } - block_handler = &rkisp1_ext_params_handlers[block->type]; if (!(block_handler->group & block_group_mask)) continue; - if (block->size != block_handler->size) { - dev_dbg(params->rkisp1->dev, - "Invalid parameters block size\n"); - return -EINVAL; - } - block_handler->handler(params, block); } @@ -1991,9 +1978,9 @@ static int __rkisp1_ext_params_config(struct rkisp1_params *params, } static int rkisp1_ext_params_config(struct rkisp1_params *params, - struct rkisp1_ext_params_cfg *cfg) + struct rkisp1_params_buffer *buffer) { - return __rkisp1_ext_params_config(params, cfg, + return __rkisp1_ext_params_config(params, buffer, RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS | RKISP1_EXT_PARAMS_BLOCK_GROUP_LSC | RKISP1_EXT_PARAMS_BLOCK_GROUP_MEAS); @@ -2001,17 +1988,17 @@ static int rkisp1_ext_params_config(struct rkisp1_params *params, static int rkisp1_ext_params_other_meas_config(struct rkisp1_params *params, - struct rkisp1_ext_params_cfg *cfg) + struct rkisp1_params_buffer *buffer) { - return __rkisp1_ext_params_config(params, cfg, + return __rkisp1_ext_params_config(params, buffer, RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS | RKISP1_EXT_PARAMS_BLOCK_GROUP_MEAS); } static int rkisp1_ext_params_lsc_config(struct rkisp1_params *params, - struct rkisp1_ext_params_cfg *cfg) + struct rkisp1_params_buffer *buffer) { - return __rkisp1_ext_params_config(params, cfg, + return __rkisp1_ext_params_config(params, buffer, RKISP1_EXT_PARAMS_BLOCK_GROUP_LSC); } @@ -2057,7 +2044,7 @@ void rkisp1_params_isr(struct rkisp1_device *rkisp1) rkisp1_isp_isr_lsc_config(params, cfg); rkisp1_isp_isr_meas_config(params, cfg); } else { - ret = rkisp1_ext_params_config(params, cfg); + ret = rkisp1_ext_params_config(params, buf); } if (ret) @@ -2168,7 +2155,7 @@ int rkisp1_params_pre_configure(struct rkisp1_params *params, rkisp1_isp_isr_other_config(params, cfg); rkisp1_isp_isr_meas_config(params, cfg); } else { - ret = rkisp1_ext_params_other_meas_config(params, cfg); + ret = rkisp1_ext_params_other_meas_config(params, buf); } if (ret) { @@ -2215,7 +2202,7 @@ int rkisp1_params_post_configure(struct rkisp1_params *params) if (params->metafmt.dataformat == V4L2_META_FMT_RK_ISP1_PARAMS) rkisp1_isp_isr_lsc_config(params, cfg); else - ret = rkisp1_ext_params_lsc_config(params, cfg); + ret = rkisp1_ext_params_lsc_config(params, buf); if (ret) goto complete_and_unlock; @@ -2407,6 +2394,110 @@ static int rkisp1_params_vb2_queue_setup(struct vb2_queue *vq, return 0; } +static int rkisp1_params_vb2_buf_init(struct vb2_buffer *vb) +{ + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct rkisp1_params_buffer *params_buf = + container_of(vbuf, struct rkisp1_params_buffer, vb); + struct rkisp1_params *params = vb->vb2_queue->drv_priv; + size_t buf_size = params->metafmt.buffersize; + + if (params->metafmt.dataformat == V4L2_META_FMT_RK_ISP1_PARAMS) { + params_buf->cfg = NULL; + return 0; + } + + params_buf->cfg = kvmalloc(buf_size, GFP_KERNEL); + if (IS_ERR_OR_NULL(params_buf->cfg)) + return -ENOMEM; + + return 0; +} + +static void rkisp1_params_vb2_buf_cleanup(struct vb2_buffer *vb) +{ + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct rkisp1_params_buffer *params_buf = + container_of(vbuf, struct rkisp1_params_buffer, vb); + + kvfree(params_buf->cfg); +} + +static int rkisp1_params_validate_ext_params(struct rkisp1_params *params, + struct rkisp1_ext_params_cfg *cfg) +{ + size_t block_offset = 0; + + if (cfg->total_size > RKISP1_EXT_PARAMS_MAX_SIZE) { + dev_dbg(params->rkisp1->dev, + "Invalid parameters buffer size %llu\n", + cfg->total_size); + return -EINVAL; + } + + /* Walk the list of parameter blocks and validate them. */ + while (block_offset < cfg->total_size) { + const struct rkisp1_ext_params_handler *hdlr; + struct rkisp1_ext_params_block_header *block; + + block = (struct rkisp1_ext_params_block_header *) + &cfg->data[block_offset]; + block_offset += block->size; + + if (block->type >= RKISP1_EXT_PARAMS_BLOCK_TYPE_SENTINEL) { + dev_dbg(params->rkisp1->dev, + "Invalid parameters block type\n"); + return -EINVAL; + } + + hdlr = &rkisp1_ext_params_handlers[block->type]; + if (hdlr->group != RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS && + hdlr->group != RKISP1_EXT_PARAMS_BLOCK_GROUP_LSC && + hdlr->group != RKISP1_EXT_PARAMS_BLOCK_GROUP_MEAS) { + dev_dbg(params->rkisp1->dev, + "Invalid parameters block group\n"); + return -EINVAL; + } + + if (block->size != hdlr->size) { + dev_dbg(params->rkisp1->dev, + "Invalid parameters block size\n"); + return -EINVAL; + } + } + + return 0; +} + +static int rkisp1_params_vb2_buf_out_validate(struct vb2_buffer *vb) +{ + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct rkisp1_params_buffer *params_buf = + container_of(vbuf, struct rkisp1_params_buffer, vb); + struct vb2_queue *vq = vb->vb2_queue; + struct rkisp1_params *params = vq->drv_priv; + struct rkisp1_ext_params_cfg *cfg = + vb2_plane_vaddr(¶ms_buf->vb.vb2_buf, 0); + int ret; + + /* Fixed parameters format doesn't require validation. */ + if (params->metafmt.dataformat == V4L2_META_FMT_RK_ISP1_PARAMS) + return 0; + + ret = rkisp1_params_validate_ext_params(params, cfg); + if (ret) + return ret; + + /* + * If the parameters buffer is valid, copy it to the internal scratch + * buffer to avoid userspace modifying the buffer content while + * the driver processes it. + */ + memcpy(params_buf->cfg, cfg, sizeof(*cfg)); + + return 0; +} + static void rkisp1_params_vb2_buf_queue(struct vb2_buffer *vb) { struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); @@ -2455,6 +2546,9 @@ static void rkisp1_params_vb2_stop_streaming(struct vb2_queue *vq) static const struct vb2_ops rkisp1_params_vb2_ops = { .queue_setup = rkisp1_params_vb2_queue_setup, + .buf_init = rkisp1_params_vb2_buf_init, + .buf_cleanup = rkisp1_params_vb2_buf_cleanup, + .buf_out_validate = rkisp1_params_vb2_buf_out_validate, .wait_prepare = vb2_ops_wait_prepare, .wait_finish = vb2_ops_wait_finish, .buf_queue = rkisp1_params_vb2_buf_queue,