From nobody Sat Jun 13 02:07:57 2026 Received: from AS8PR04CU009.outbound.protection.outlook.com (mail-westeuropeazon11011050.outbound.protection.outlook.com [52.101.70.50]) (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 82CAE3ED3BA; Fri, 12 Jun 2026 13:20:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.70.50 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781270454; cv=fail; b=reCbO3iOAS53sOqFm4S4neMnb0sXdl/y37sJEhd0zAKNUVp5Ku1JGf8erCJalya5TbXjLfN6gkvBUlq1OVFs+T9x/zAF0jp7ChM/s0+R4tDLHfEdJz8aLAMaPx38pn7OgmwID9V9BoOlr5rlW+0NNlvjUziGI4PGIbpZ0Lk/XKk= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781270454; c=relaxed/simple; bh=eYNfLurK286fJvZyKW3NZxKIvsueugnvR3kUNaHz3yE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=qDuVkSkqML7aH2xyp3HRrItssFWl1nXldY/CjdkkNW3Xmx80y3T1BNLz2vkNzZCCdLIE81LfQvOCG0Rr1VEi734yen0X5fBW2ehSg0sxS4foNzi1xgL0Hhgx+B5jAX3lDGyH3ImMfcY69G4xDU6xVV69kDRnzq9HvZHuBl1hYbE= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com; spf=pass smtp.mailfrom=nxp.com; dkim=pass (2048-bit key) header.d=nxp.com header.i=@nxp.com header.b=JdE9btX7; arc=fail smtp.client-ip=52.101.70.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nxp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nxp.com header.i=@nxp.com header.b="JdE9btX7" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=ayiadlRQ17plxylF4fr5uBgMEpKktrlSzZ4NJhsYN/VO3MFxNc8KGEtB+8cH2HkVvX2nOUORwZ7ieSNAcl4PjaMmXB51tA0/IpOuQt6SoXvM+xA51f6qcThRxwF9AXxvSTBUHQPApuZMNS2k2FrGMQg9bgWpfXdM9/KHUTgBkwiBnLvMFWVgTsGBqyLAemlitFKtbTYTVVo2KabtJgXRpFa78BOASdfRSUovVhWWHhzbN09unEvnngJydirddAW5QS6hcDLMWpPEDBiS50eba4QN3T2dsSPF8Ef8wRCZqXHrRIqL2bG3c3mol6bQ1/VJJxjb+b1w5Tpn4jiP+g672Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=U7+/PrI/CHd1t5lfruSMnN7Tk17vorCA4fbH59otp24=; b=YuGO0yS31UhVOQYavEIx0hkEPSegZ8030FwOVcyt9nEmZXpTNsz5P6jwqwmdww2sXxIJN0dBy9GCklaMR9TBIEcJHFj0DL5fB+LuBLiNq1dYQm38qAecvp4vG2Vpo5OirFc2Qz1Odt7MmUNiUwjenc0vGqNAXgHMg10AkaF6//91W3SyGOMpD6yjPNZWiN7GHscqTxYjcq+g8B0l2wTDkJf0OePWo4lp4V1S6NyOYrla42pOcf1vcdwPTGtETi0kZ6mmHLvEvfmtMKCoTo2LU67G9h6wl3czwVhtQRgwdD/Df4Uj4MvLQdw9hpas/AOwjM3dGgyTRn1kAysrYxI0xA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nxp.com; dmarc=pass action=none header.from=nxp.com; dkim=pass header.d=nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=U7+/PrI/CHd1t5lfruSMnN7Tk17vorCA4fbH59otp24=; b=JdE9btX74lOq6DztiDeJwjTBkUvhfFaAAdDcHBu7iHOu08eOF41JFwEnhdfjZbIGnu9ED2lYDePyPkneY0PMLdbWm0DeK3g6JgtNnrjwJRDQv4HITILGq6xCoE8vXmbJh5uD+z7ApIAEvAXe9qQHYqXhaHgTAIcscrxm4EsUIyIFMprVOh4hgDwIhlwO/I1ArboDTzj/BZTDRcuIKOe6WPExbwScfdVlX+qVpEg+98u1fGAKMdmjSwXYVtqF16Ylec3y6/cyflKVS8AweaRX1dEOVraf8FLvz15gbETPah7+cUx8Ckx8QXWZ09HBXClHOcKeLtXFmD2hngbFB3NZFQ== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from PA6PR04MB11910.eurprd04.prod.outlook.com (2603:10a6:102:516::16) by DB9PR04MB8203.eurprd04.prod.outlook.com (2603:10a6:10:242::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.113.14; Fri, 12 Jun 2026 13:20:48 +0000 Received: from PA6PR04MB11910.eurprd04.prod.outlook.com ([fe80::d3f0:3c24:f717:4989]) by PA6PR04MB11910.eurprd04.prod.outlook.com ([fe80::d3f0:3c24:f717:4989%4]) with mapi id 15.21.0113.013; Fri, 12 Jun 2026 13:20:48 +0000 From: Antoine Bouyer To: julien.vuillaumier@nxp.com, alexi.birlinger@nxp.com, daniel.baluta@nxp.com, peng.fan@nxp.com, frank.li@nxp.com, jacopo.mondi@ideasonboard.com, laurent.pinchart@ideasonboard.com, mchehab@kernel.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, michael.riesch@collabora.com, anthony.mcgivern@arm.com Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, imx@lists.linux.dev, ai.luthra@ideasonboard.com, paul.elder@ideasonboard.com, geert@linux-m68k.org, sakari.ailus@linux.intel.com, hverkuil+cisco@kernel.org, Antoine Bouyer Subject: [PATCH v3 1/8] dt-bindings: media: Add nxp neoisp support Date: Fri, 12 Jun 2026 15:20:32 +0200 Message-ID: <20260612132039.2089051-2-antoine.bouyer@nxp.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260612132039.2089051-1-antoine.bouyer@nxp.com> References: <20260612132039.2089051-1-antoine.bouyer@nxp.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: FR4P281CA0017.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:c9::13) To PA6PR04MB11910.eurprd04.prod.outlook.com (2603:10a6:102:516::16) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PA6PR04MB11910:EE_|DB9PR04MB8203:EE_ X-MS-Office365-Filtering-Correlation-Id: 415c3150-a828-4625-748e-08dec8856af0 X-LD-Processed: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635,ExtAddr X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|19092799006|376014|7416014|366016|23010399003|921020|6133799003|18002099003|22082099003|3023799007|11063799006|56012099006; X-Microsoft-Antispam-Message-Info: KUEh+5K0dUsBZUZ1iPMFaZKSIw3TsAwIEIrRoM/HPQIGD0pFC7//nZtDvEypD5jL/ji7Pf56jsF0PGB+bd8ez52PiZT7UTwdbuvEcfPXleMIiwSOjfK08YNwRpMOiyEU6Yz8ca1fAt4C2RNcPKylN/JoxQ5CyDBZkY6/wGYZdrzS/AAVL+0s1PZyvrzjNDuHYR1CsTRyqKQmLLkWfA2WZbZzVN6Hj7XFRM7Mh2dXXwhIDlnC3fOrDFajkr8/kTnvKMuxPzpEw4xGlj1LBUX1xgDMHpFIGdlydDaasezS5uOsNv/VQ6fwmJFJ36N7hG30qnTUIzlWx5gX2eJ6M/0yiKMBIsY5G4Jazz6rWTB7Rppvh5yOhnf/w4JawJ+Gora0QXIHoUW4mfwt19vo7g3nPd/u5SgghMlVc4HgOQkQqxm2fD4I1loiTc/QzCSRTE0lLFnmF0Q1E46tzXZrMaEQTua1Ur3B2eQclDZbfsEPgQw+Y6686npH/7k4dVz/kx4k1EaRTYzCHNiA1ih08dWYsAtW/cDKhd881ZZZVHlYXkWVaW+aWts3IFsMq9Ms5yvlvTIwZ1+KdUhqkUa/ew4DV5MJC29mX2ar9S4Ui8C5eJxtM/n1mEd5SyJPqytOt8EJ7JWwUlMJUTxLE+zgPr1GbNpc4YQNG9ul0pp9pzlhLVkXE6ep6XKii3Oib6hhXLNl X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PA6PR04MB11910.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(1800799024)(19092799006)(376014)(7416014)(366016)(23010399003)(921020)(6133799003)(18002099003)(22082099003)(3023799007)(11063799006)(56012099006);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?uUn4yDWQ0MNiMYuvzECrm6wb/O5J2aQmF9+hvsLnp5/v2cSl1edzIMahDV0z?= =?us-ascii?Q?ejszwSnlMsabpKDHuwZH7EwQLOwaIJNWODrMAhPTVhrM9DfH86mFqnJyiB6z?= =?us-ascii?Q?WE5gURxUiM96t8WMoKKW7YGbCGaJKBV/jQZF/9Tb1B6PUiGSH6f/1wcO75iH?= =?us-ascii?Q?+XzCUP/+pr7IXbcQAmGRCfwXXNVryARODrsjwMCktCxMNUDFqOmJA2hjcFr0?= =?us-ascii?Q?4S6fLIKt5DPw1FKqzb9g0O1H4lpt+2M+BWmhKEzuSBEaBvOioqFkypm1PGYN?= =?us-ascii?Q?OwK+eDYMD2CRXXa846ojrJjOBx0Lwyh8S8UpHnysOxZoSFUh2qyI6ST49+xq?= =?us-ascii?Q?AjYdwRIuqY0NTamusN6yKrvjwMonFiMmbQq7jPe66MuJBgB0qOV/txaTgQQj?= =?us-ascii?Q?Nb7VQSqYGmEKcL2HLg9EYbU7bJO4PbyT6+SJajQ0RCVsEFRPNhhyZM81naNT?= =?us-ascii?Q?tlLxqauQ5Cs9ln3zmfnJSWIux4JOknkM7YiPSzh+tfXQiyyC++xlz4TlTv67?= =?us-ascii?Q?5d7BiLT1tTV9n2Ek47AbnfBrnnztKxTmU/SYomVA4D4/xqV5qGadn8MKu/vy?= =?us-ascii?Q?Oc8+740wBoJJn7U4H1O6E5m1YJeHNHFstYxzIf+Zz6CmBiDmuZxzNtUdKnCD?= =?us-ascii?Q?jXSI2Y7j0zm6a4H5PxoNvAbJPpX5eEy+UE0lZeJnMb34lMG63ylZT7I3w+mC?= =?us-ascii?Q?wGF74VmWHIPnQuwaN72Fmffh99Kv7YQr+AzQAgOpEKLnlSoZsjzVHYGhVid8?= =?us-ascii?Q?74ZxITFVpfy134pmASMdKy5DJQJwcv9qhXVKmoFU6QUSRkXjwlh+d1vJxKc/?= =?us-ascii?Q?KJm9vgp4kFnTFI6/7cXHDRlMtGINrCobcfyYoODKc3TYeyTnJ9BvZ3KrsACj?= =?us-ascii?Q?Z7/g7Rl/myHphTV9SRULndpUd4zxu0d4qaL8DFtENq7NoFKr+fOPAjhEY9jW?= =?us-ascii?Q?IDO40tMKU2qsvTN5ksRy3lTH9fQH0mbjgl2es1RrBruxKsKGmnCbBrnRcZOI?= =?us-ascii?Q?GwsYnjb9BDY9ulkeQ43c1G4+TCa9CJJpQZy2YQU3w5VQYsau13UbdQ9/cmUM?= =?us-ascii?Q?kfFlwfLQN0TxamlnFyUcrMi7aUlI3Mp6mC36DwdABSE3rRpkuaZt1Ul3pfZ0?= =?us-ascii?Q?KEZqXcQPEN1F4OiONKnSjDmKL85pU2JyWZMU5Lndq8obgrKG8+rWZ0SXIElR?= =?us-ascii?Q?i+uvFTbJD7XhQuJ7kL5sXqldD4jUyVn2rdr52vkjbvbrIkBBgjz4LWwmBtNd?= =?us-ascii?Q?48abePGY08piGB+v5rx7in3GsGJCq+cIA0Bl2lCgAAhJqemyvX4Yb295aT2N?= =?us-ascii?Q?KmKPFYzp2aaYdG4qRJdvomZyoC6V1CNKG88s4GSgibaV4ejiowWUOAS3lnp/?= =?us-ascii?Q?ueDBkb6Rdeze9mJ4UQ+HEdkBH5aC2Jt7orz3Z6qfqEh1hBK7h014+qQ0eQYD?= =?us-ascii?Q?N8qwVW+R28YHGP/zsGHipJhyFXVkHnMc0mNOqzjH37jFfiZEvs2VzC5KvYMm?= =?us-ascii?Q?bDptA+k7eqGVOVbDgV/hcQZK3EGW9ZVkkkgVBJCxqkmDfsl7LjH+aM6b7lpl?= =?us-ascii?Q?6a56MGNVfuWOUDezJapnHB2+p4wcQSjliwHAxneWolN89IRrollbyPy2GMsP?= =?us-ascii?Q?gkizqS5w+wdMoGpwhpNu/g6f60jvNsGsNuiuFI55SnL73jn7BSRDRHBm6qkh?= =?us-ascii?Q?u0AxjHqua65dj12+bwrd+ZAuuFnYksEBFHnMXzDioQESjKzRcZkRu0IJnFNI?= =?us-ascii?Q?YRpjADagiQ=3D=3D?= X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 415c3150-a828-4625-748e-08dec8856af0 X-MS-Exchange-CrossTenant-AuthSource: PA6PR04MB11910.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Jun 2026 13:20:48.5330 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: RBluzfoJ4Yw3lip6NZPwYSzCYBPiXF1P42hacw2tmDP1MDzCb9nfUIKWPU5esxCfTjQnqhvaLAyqkUZ87Lagsw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB9PR04MB8203 Content-Type: text/plain; charset="utf-8" Add the yaml binding for NXP's Neo Image Signal Processor (ISP). Signed-off-by: Antoine Bouyer Reviewed-by: Rob Herring (Arm) Reviewed-by: Frank Li --- .../bindings/media/nxp,imx95-neoisp.yaml | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/nxp,imx95-neois= p.yaml diff --git a/Documentation/devicetree/bindings/media/nxp,imx95-neoisp.yaml = b/Documentation/devicetree/bindings/media/nxp,imx95-neoisp.yaml new file mode 100644 index 000000000000..458c4e4d640d --- /dev/null +++ b/Documentation/devicetree/bindings/media/nxp,imx95-neoisp.yaml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/nxp,imx95-neoisp.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP NEOISP Image Signal Processing Pipeline + +maintainers: + - Antoine Bouyer + +description: + The NXP NEOISP performs a set of image processing tasks on the RAW camera + stream and provides RGB or YUV enhanced image. + +properties: + compatible: + enum: + - nxp,imx95-neoisp + + reg: + items: + - description: The configuration registers + - description: ISP local memories + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + items: + - const: camcm0 + + power-domains: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - power-domains + +additionalProperties: false + +examples: + - | + #include + + isp@4ae00000 { + compatible =3D "nxp,imx95-neoisp"; + reg =3D <0x4ae00000 0x8000>, + <0x4afe0000 0x10000>; + interrupts =3D ; + interrupt-parent =3D <&gic>; + clocks =3D <&scmi_clk 64>; /* IMX95_CLK_CAMCM0 */ + clock-names =3D "camcm0"; + power-domains =3D <&scmi_devpd 3>; /* IMX95_PD_CAMERA */ + }; --=20 2.53.0 From nobody Sat Jun 13 02:07:57 2026 Received: from AS8PR04CU009.outbound.protection.outlook.com (mail-westeuropeazon11011050.outbound.protection.outlook.com [52.101.70.50]) (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 42E933EC2E1; Fri, 12 Jun 2026 13:20:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.70.50 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781270459; cv=fail; b=ptgSlSqhinCHhT4TpXZMHGx7wmEon+mD8fBD/lJT2GcP8jybRHPDFS2E8jsDbikFRBRSzhAePK2by7A3HKUWHFbclF0HGHiak+RfU3AIBNp3nUSOOj0vZd1Q+xkenYQiMtJ+gwY3kH/xbG4Ayim7cW0CYllDjOxmvd+Ipt1vq/Y= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781270459; c=relaxed/simple; bh=BQqxafIMtTkKAMwC+xdESHTLeXpYxaXYvjlaQBvYEcc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=f/2fPtZlYW0bXVcFvByuKH65qm2nocsp4623JWxYmNyAhNzqkDv2/5e0raDQKPv7EQFLSGq2LhE/+oXmBobNgr2PE0RpEUuvXOdPxlQCKjx+rfKqXf3DeOUQoGdtVZRrKE4HkLh6N5I5aN7f4yX71Ea1PevZFzQT69M7KicMSyA= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com; spf=pass smtp.mailfrom=nxp.com; dkim=pass (2048-bit key) header.d=nxp.com header.i=@nxp.com header.b=V8XkLAP2; arc=fail smtp.client-ip=52.101.70.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nxp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nxp.com header.i=@nxp.com header.b="V8XkLAP2" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=NAY1ved88caHYSwy0DiCr0kbqjbv2jGFNGStGiJyEvhS8YH54gzLNcV1VytKrNUWGYqMWnW53Vzb6VS0aJXmr8falMtHBaOhjV77wR0z64/ckrvqirgRRav+x3LovHAqirsliBXTUhDrVAmFIba4O3SPlLnkF5SNMY9MtiBF46saTZ0dU2mZKb8VGhvE2X0uhmAKXj80lYbODbB/Z7nSGzKi44EOXRn64XUvp18JJLtpEnLquLGl9r4Zjl+G1df731feO4FQmOejzbMldL1Y2iGJfz8FPvMHR2NMSbb4rvXO5c9WXLNcJgwC7Hug5QuITRbVFICMNfLlmKYjrRvF2w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=auZ1sWQO+u/Ug16/3GkGDmclPngY0qQnRvzgdh4nQek=; b=wqjnWTOougVWu1Qq+QnC/+ome22IjP57PK43C9xRZh8lPQYcmgmDJVe8ghyBG2wzzb/bSyK5wG08wDjwN3q8FMy8W3EIa5Xm+tzJCSl5VTzlzUX/p7ibEByPSS1J7u63YyHrGzV0FJTGqi3o9wXuXMamAjmJPQNwL77SI5+bP9H5qAZO/5phs0WOouJkij/0n2FtSztNC8YW2TCBmMEurhJlInIAqQ+Z1lyyVq+LO/l/p/MycUgm6JWWpi4B8o676cmYinneDsnlWvbYmYdOTHQ5U4+kvy+kOK2V9l67OB3j49S/UcLL15iir81akG1nPdVe/bdZVLD/xMN4OimEkg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nxp.com; dmarc=pass action=none header.from=nxp.com; dkim=pass header.d=nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=auZ1sWQO+u/Ug16/3GkGDmclPngY0qQnRvzgdh4nQek=; b=V8XkLAP2lNMykNWhew+QEy6+JAEKVUKehfO4yr0i9/dvx1xLowyERyAjF+en9KRcjtzecLVdwoYqq/4JilJuplzDjbp4f+V6Cvje1uEzcyF8bT7QWzJYZDYbyQrE8m8v1Nlr4fTeMJsn3W61IEGJm6TyIAWAUC+NXMzonbmnNySwfuawLzSL+d0PrVpNwy77DuOi0zRsM9va70p4b121UCrDeQz7jL7tu5zKQuciN6d7pM33y9iYeEC1ZPtAL/SdLb5JtG0SVlmBPeYoU2HfViGVw0jm39eR8XHHPISGnSV1XK+KxH/UFvjzPvbiY7x7TMUaPMQbXdLsUY49vpglQw== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from PA6PR04MB11910.eurprd04.prod.outlook.com (2603:10a6:102:516::16) by DB9PR04MB8203.eurprd04.prod.outlook.com (2603:10a6:10:242::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.113.14; Fri, 12 Jun 2026 13:20:50 +0000 Received: from PA6PR04MB11910.eurprd04.prod.outlook.com ([fe80::d3f0:3c24:f717:4989]) by PA6PR04MB11910.eurprd04.prod.outlook.com ([fe80::d3f0:3c24:f717:4989%4]) with mapi id 15.21.0113.013; Fri, 12 Jun 2026 13:20:50 +0000 From: Antoine Bouyer To: julien.vuillaumier@nxp.com, alexi.birlinger@nxp.com, daniel.baluta@nxp.com, peng.fan@nxp.com, frank.li@nxp.com, jacopo.mondi@ideasonboard.com, laurent.pinchart@ideasonboard.com, mchehab@kernel.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, michael.riesch@collabora.com, anthony.mcgivern@arm.com Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, imx@lists.linux.dev, ai.luthra@ideasonboard.com, paul.elder@ideasonboard.com, geert@linux-m68k.org, sakari.ailus@linux.intel.com, hverkuil+cisco@kernel.org, Antoine Bouyer Subject: [PATCH v3 2/8] media: v4l2-ctrls: Add user control base for NXP neoisp controls Date: Fri, 12 Jun 2026 15:20:33 +0200 Message-ID: <20260612132039.2089051-3-antoine.bouyer@nxp.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260612132039.2089051-1-antoine.bouyer@nxp.com> References: <20260612132039.2089051-1-antoine.bouyer@nxp.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: FR2P281CA0101.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:9c::7) To PA6PR04MB11910.eurprd04.prod.outlook.com (2603:10a6:102:516::16) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PA6PR04MB11910:EE_|DB9PR04MB8203:EE_ X-MS-Office365-Filtering-Correlation-Id: 983065ac-23a6-46ad-4758-08dec8856c13 X-LD-Processed: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635,ExtAddr X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|19092799006|376014|7416014|366016|23010399003|921020|18002099003|22082099003|11063799006|56012099006; X-Microsoft-Antispam-Message-Info: l0FLMv3XwBb4Ldr2ipU/yg42Scwb/TH/939AV1lYC6V/Rxsuf/jnmZqklFlguErBbF0cGHGzMS3/+M3d3tu7f5h7rjMcxlxOFgjwxHIFxmWZS8gTx+zwZry2w8JXMdZUqpdE9y6j+5yMWHJ3WGUS1JK58Aj6K+b085kafngvzgXqyagF9mrcVP4vAdrTnlFlOx4ihLCsJmckvULJNguBlUStS18GTX0gTyUKGrNdKgq2pfKK/bGDiwT1RARfBpjcJqFFdTmUabkHuTNCBlVYXtV6rG1UVGRtrkmrPigAJ1R2MuWiYsGVY6eNOVnaXDC/oXuQfYrvxBWoo3CMyvXsevK6mkQ9wFru5+CJHLYV4T3QOWGTrBQxksZ2T/gf/oFh631oN4ROaNDS0hhHge0PHnyG15P5fQINzLmpVRVsTLNdwbTYCjh92bA2rePr+A0VPQO4j8tMylh9wJIuJ4Xg1YgWD2FQZOOQ2pHQIcJozNP7rtZPjppka/Dabws6vdRdB81kUYQ59e4lv1clQFZWiLKK046sPOWhUQweII3V0qn4/iRQuEW4YV7cYDTVgB27KiFym242V2lid+CUVGvVN9GOXI/73wpx2pALs7jsNgxUERidb7jagO9q6WrmzaCiXYwrw7kJLVP6gpujO2VMGIPCChUEmiEw4xEx/+Hg2WK174nImrNiIoo/36FV+/dyqZ4tAs5pTW5Cx7ErTwr17FvgoyOLCe0AqxkATXkZS4o= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PA6PR04MB11910.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(1800799024)(19092799006)(376014)(7416014)(366016)(23010399003)(921020)(18002099003)(22082099003)(11063799006)(56012099006);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?otrEBOoG9XSRtoxq7lEDuuKcFLxol6PUCM+NUcEgZ2GTrIlP4NqaKD1WzwWD?= =?us-ascii?Q?uMa+E1Z4gvjuQg8L8Q7Dp+DyoPTz6tSFnRPXl+Qst31ZWTL77Q1C9522EfVu?= =?us-ascii?Q?lOKmUmkiNNKGUkebl78SuIm818VDZxh70PsO4hlXQbDKOlom7bcdrjNd03rN?= =?us-ascii?Q?1ogvbT9d22E3dr5vRW12XfLFuKj2RA1EOuUI8rxjYZuXKu6xRxq/zzefVd7F?= =?us-ascii?Q?oNcaJofW3AeLLeuIeC6ONdk/OuCxhgEw6O0ue9Sd9QU7/9hhbCJStpMPjzvf?= =?us-ascii?Q?FLprITEWAyqOL3QTtsIcu1xPdKpFX9AWeRHJawcLEkFAxsSK5kqWwv7m3Ux6?= =?us-ascii?Q?KY8+5OlTkjyeycugTtc9zJqfLpgTDD1AHouO/m1KcXaa3vBhnk5H2+wG9G0Q?= =?us-ascii?Q?R+xpknazls8ZWSEccuVygy9blJHSfF0h+Fbc1i7CctayBUp5lR+A/U/cTfgp?= =?us-ascii?Q?H2qj6IlK9kV5pd3/29lqcsLS4mWNZvf3hhBa5s/KIrQHzuC5EH0+rPmmAM7c?= =?us-ascii?Q?3YFMVWXZPIKzoVbtfIwyF/+MlluaMA/kDeFB4lEYGX0dA4zrKCqhbggpIEMz?= =?us-ascii?Q?m9w7G2RRhTFaBYvm7i1RHaEKbbzhFerxx9SLT0ZEuhrI/mw2YS5hmq9BcYty?= =?us-ascii?Q?7+41Qs4Ygm+YYk7kMS7t7FFIsmVfKL9RKJZlXvU7UWVuCwIFcex54eKKgdgF?= =?us-ascii?Q?wk1zkJdQs3sUkwqcl0WztXXDvVj8W7wcJ71dMEHEnpV/k5FhPr65N4Bf5uS7?= =?us-ascii?Q?9Iy+7Kq8sC1VciP08NDXgUBwIKKYfsqPV13I0DSNgT38mcAiZpIMpEI59zhI?= =?us-ascii?Q?5VHHYMPxFX67MRdRs0uSrUTj9FpA7iHJwRrP6ih+ov4gPPuzPoKxSFY52P3n?= =?us-ascii?Q?H+hulPJEHAvmiQTcNRXrbAvr3CxPPtajesVJ8OJL3+M0oFKko2sRs9GiCszL?= =?us-ascii?Q?3qRvH4JbL/M48B73Q/xvlIb8/jEV7mix5LlQIorepzAaXtxIzLRJRsWmFmao?= =?us-ascii?Q?kZmEdppRw4kII3WOOh6vwNDWr9r+WsJdPV4WHBV3WLjF0OCC9GWQbWqv/Mmz?= =?us-ascii?Q?3U6cmdOB8eSRB+T/xChyXeR98LjEfp4sIqQ0JPlSwB+HWqwmu7v33Yh9tDTW?= =?us-ascii?Q?CgTCCiNQnvIyAjlEVJ5sXcd/5EAM+K969htmTq1H6OmAwPx6n6rxlaj4Ku0A?= =?us-ascii?Q?7L75Oznf1tAT6xXGlbX3DMzRSuUihpi9DJj6VBoWHfprFj7RnJw81rgTrLOJ?= =?us-ascii?Q?XHicOQMNtQlzmEyZhc8o3oAFV3++L99NZsJGRfrSjBsYhclLl/kcWRnDWpdw?= =?us-ascii?Q?ufgpgXDiPj2nTpbdOSzUAeNbgAhW2jOVSi2Zx7F1d6/F3HfPHmrww0xVTxw9?= =?us-ascii?Q?o+6lPJD/BcTS0jM4u+BXGlKZXQnfUnkug6V3qNjReGyTc4vSzZamrZDJSIOf?= =?us-ascii?Q?+QCZFj+5aTI7P0lCh7dIZ+7ptv7Itdq51lfQ4QfmZzS2vvsJ1MlxC0L67SK+?= =?us-ascii?Q?9Mn0Mw8mvVYtmjC2FCn6vibnzHcNUYufK1lFCqMJYPqiAkCDWy9Zx28819Np?= =?us-ascii?Q?X7IbkKyznphIVGvTx/hYZRPmltC/2//fTUBELGtjm4FjIMkFFfA4SCL70m+7?= =?us-ascii?Q?GHA8euJBAavqbEj+y7cr6YlKyl8A8sZOMoLcEOADEVLIm7MNYGb/q1diGbmN?= =?us-ascii?Q?K1KDgMJggyfnksgBbjEoi2IW2W9Zf4Lk5pGsFgLwXdpy3IU6zWZgmrWA9vNK?= =?us-ascii?Q?ihSFUvnn5g=3D=3D?= X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 983065ac-23a6-46ad-4758-08dec8856c13 X-MS-Exchange-CrossTenant-AuthSource: PA6PR04MB11910.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Jun 2026 13:20:50.3881 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: CFg0org8WwQKV9ZL8X9DRtSiJccuvfRz4eblVGSg8+y92sbP6Q+VYmrVp/7yuxOJ0eAVba55ZlpbN3byhkVbkA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB9PR04MB8203 Content-Type: text/plain; charset="utf-8" Add a control base for the NXP neoisp driver controls, and reserve up to 16 controls. Signed-off-by: Antoine Bouyer --- include/uapi/linux/v4l2-controls.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-c= ontrols.h index affec0ab4781..1c44229d349d 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -234,6 +234,12 @@ enum v4l2_colorfx { */ #define V4L2_CID_USER_MALI_C55_BASE (V4L2_CID_USER_BASE + 0x1230) =20 +/* + * The base for NEOISP driver controls. + * We reserve 16 controls for this driver. + */ +#define V4L2_CID_USER_NEOISP_BASE (V4L2_CID_USER_BASE + 0x1240) + /* MPEG-class control IDs */ /* The MPEG controls are applicable to all codec controls * and the 'MPEG' part of the define is historical */ --=20 2.53.0 From nobody Sat Jun 13 02:07:57 2026 Received: from AS8PR04CU009.outbound.protection.outlook.com (mail-westeuropeazon11011050.outbound.protection.outlook.com [52.101.70.50]) (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 C639C3ED5BE; Fri, 12 Jun 2026 13:20:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.70.50 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781270461; cv=fail; b=PrzXYXsK1feZapNRjtLjIosukAKZoU6ktyqsciXdm34ilauJ2SYWtMy/za5Oz57ojEGtLhAEuculdeLb74d9wBWZDxWYtYZwPxGByD/aH5ZnY+Yh2S/dbn3+9TxoZA8JDfU4ocAVtZNWxibTUzr0cPKMcMwFPe1d4PgJe0I3WiA= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781270461; c=relaxed/simple; bh=Eb+ROArPlZwaikX7ZHwvVK6KPrJti5o1939Jt6zokBY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=c4gbGbtORdxgHMmNvFA2GikgPnf3cwzf/pgPT5YYHWa71KpdttIcGUh7Q8kek5v8OeIW+uI/oGioRqdaDztH7kltos2z/jeNFayD5jxqD6y2uscYI1mJd+NJBBRIHJmpw3rAxmYEpkgN7P/Me7+c6Qn+m0v3TM5i6NYMTJvU9C8= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com; spf=pass smtp.mailfrom=nxp.com; dkim=pass (2048-bit key) header.d=nxp.com header.i=@nxp.com header.b=R3BsGuRP; arc=fail smtp.client-ip=52.101.70.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nxp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nxp.com header.i=@nxp.com header.b="R3BsGuRP" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=cLRbia45zQS36ywfQUDx5uM5fu5ym0/HKR7Dv/tPjZEVv8I1PD64csWMecUzpNgWSzPDymi3PbGlfTnqFjigpSjmN7Irt9vJo/Xy+lM5SEyxhnMiwagPghskpgx3GYBsjtXah6gUaEHL16JwJimusUI+nRexrYUSEJE21EdgbTBh2lH5okrPZu2Vwb8xP0xGJyQTDHgEyigRqhtNTBANm64o26AWQaWGcYYzVT/ejoxFkwg5MLt9n/XT8ydUD9L9pX6amfkO1uGILV5QRLkTGaoJap1xk5ujbkT5aJrWXmXfP9juOx0KZorOXmVa5xbYvR2DajXtuFhOmiZE8emKHQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=PHWV3gRupX+AHVICQwWzT/H+/0hT8aV0cZ6MT8xnZZw=; b=fdWQel22Uyw690SM2mEiUJU9zmNfSVZmJcma7gnIoITcaFFJs0sl5x2HU43esEy4l3KJL2LOMs3OR68pCuaAabeHc+fh+oIz6RA+j/yl8M2vjDaAYhGCk8sZoroJvH3nMcv8OSvlQzWLCn7QRoOV3/tcc6wTyzfrJsPirq8rT02J1xUqOio9cLHH6hIyz59BRE7HrABrUeq3j4maNXszTxgA/pNcap0hfAHwLMtt23YjUAoTt01g76rRkJP9KzZYNduc9ewSxmdLSzm3BtJJYJezFMICSAOmEpzDKr76t7EB4R4SxNrH+hh6BjiHIj3cZSng1oxqLT41Q5aaLgGorw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nxp.com; dmarc=pass action=none header.from=nxp.com; dkim=pass header.d=nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=PHWV3gRupX+AHVICQwWzT/H+/0hT8aV0cZ6MT8xnZZw=; b=R3BsGuRP68znml6Kur8CBkRE47vNOeEEcBJPCP55d73M2PhYnyhiy0W+s5WQklcaloyxBols2nYIe71eAFDrICuENwtVQCtJjOLxAX5g2tK1yxJ3hFz+9xuaHP0jCg0hT0LF8hxE3bAPIgpvT1UYnXZi5kRKODdjhyP/inUqzTahAgB7MSgD4c4NQki+V0A07E5svxMEQzPMIXj0ivrYRR7N9LcwdX2x0Wk/LlkRLS4qH5BMw+HQnz3oUy/BTA5tg5OO51B5BjGNgOcLPmMkZpi4iBrqx9gdQRC0dqaDfywoj3Bjb5vqlkZjqc1EUqhzNxPeXFi2xCTKhjxSLDtIkw== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from PA6PR04MB11910.eurprd04.prod.outlook.com (2603:10a6:102:516::16) by DB9PR04MB8203.eurprd04.prod.outlook.com (2603:10a6:10:242::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.113.14; Fri, 12 Jun 2026 13:20:52 +0000 Received: from PA6PR04MB11910.eurprd04.prod.outlook.com ([fe80::d3f0:3c24:f717:4989]) by PA6PR04MB11910.eurprd04.prod.outlook.com ([fe80::d3f0:3c24:f717:4989%4]) with mapi id 15.21.0113.013; Fri, 12 Jun 2026 13:20:52 +0000 From: Antoine Bouyer To: julien.vuillaumier@nxp.com, alexi.birlinger@nxp.com, daniel.baluta@nxp.com, peng.fan@nxp.com, frank.li@nxp.com, jacopo.mondi@ideasonboard.com, laurent.pinchart@ideasonboard.com, mchehab@kernel.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, michael.riesch@collabora.com, anthony.mcgivern@arm.com Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, imx@lists.linux.dev, ai.luthra@ideasonboard.com, paul.elder@ideasonboard.com, geert@linux-m68k.org, sakari.ailus@linux.intel.com, hverkuil+cisco@kernel.org, Antoine Bouyer Subject: [PATCH v3 3/8] media: Add meta formats supported by NXP neoisp driver Date: Fri, 12 Jun 2026 15:20:34 +0200 Message-ID: <20260612132039.2089051-4-antoine.bouyer@nxp.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260612132039.2089051-1-antoine.bouyer@nxp.com> References: <20260612132039.2089051-1-antoine.bouyer@nxp.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: FR4P281CA0165.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:ba::20) To PA6PR04MB11910.eurprd04.prod.outlook.com (2603:10a6:102:516::16) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PA6PR04MB11910:EE_|DB9PR04MB8203:EE_ X-MS-Office365-Filtering-Correlation-Id: 9d788f4c-2031-43df-07c3-08dec8856d1e X-LD-Processed: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635,ExtAddr X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|19092799006|376014|7416014|366016|23010399003|921020|6133799003|18002099003|22082099003|3023799007|11063799006|56012099006; X-Microsoft-Antispam-Message-Info: RsYtq5QYbyOG4SedJkhUE2uOK4hmtQt91uTH3L1R17DM1lBb4CWsMUYQczchN+rKbiIVx1n6mOA3tpGJHu6pFxuWFNUYGkkopMZ9/xKUIuxM9g2JXEef8Lqy77kRygNcZvNzxNgssr6TShlgu44Ri3m/vc6QBy+caFCTAJBs4UpWVEOJCWJoWoTe1+tejMwXC+BxDe6Eae9JZDXcMykKiuqEFXG2ChSRKjrL2FeBmDlnONoIWoeyEyDMEaNy0/eQ5u8DG0xaOOjjYUdhHZ+spWRhidzs/OGnQ6zSTMaPxgD/zdvNkzlPJM06289JhoEv6hPzem7sI3HG9AyxFB2rHIPEIToeikKF3Aj8ANvq9Np0UQXiENuza/RZEuNshAZONCG60eAZIbtL8Zz2m7TtgEKlZDV0xn3mSktaqJ8PaR01uT2IRQbXgqFcpa6axKPKV+4JEzZ9mwcVHCGLjT3nEbVe0bHAjvFMHMTOYCcB6TnZXrSScv9rAqHJWVxo+PIBWtlPkdcpWHCUDB/ie9C0P82iC/r0Xs2mybioRU6CfXQ59YH8roNqIQGDZsvUC3eljDFPLF6qal521DK3z74BowWAK87yajt7/jWziYh+mzEi9lBcVFKqdrcx200PPSlZR0VUSIwXvY8ga2mb9SEvd6HQyQ7RGd/7ncg8ppYTcVBfGvp5rHZTy8M6WZsj0eVYNCrB3ACHQ5XJMo/T2K2n6lOQKKJmet8AhM5kHyeutUE= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PA6PR04MB11910.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(1800799024)(19092799006)(376014)(7416014)(366016)(23010399003)(921020)(6133799003)(18002099003)(22082099003)(3023799007)(11063799006)(56012099006);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?r01lxVQM/V+dWgXH60q5jyIfkLYX04Gzf4FBfKR7hOFdt/MRrX+XEEO8b+QN?= =?us-ascii?Q?BDkA35DidfRSJ+eDJZ8mDKffxapPqhS9NcfK2VfTrgx2c5pMy29ZMdjxcrDf?= =?us-ascii?Q?3RhK6bVx2LEGuxzANSdAcPHf4p8blpJ9FNX8fSvyGRtm+QWtQHmky5eIXgVI?= =?us-ascii?Q?IH4Py2xV0PnRebANvoTw5o+ojqrb2ayC4GlgtuSQqvdhQBtyXEGmNore+sOe?= =?us-ascii?Q?I7zFAhoNQEzZ2Bky16PkIY91AqJhFe6Z3Lj2bTbgua980LjNQ+DQRcMKWlXJ?= =?us-ascii?Q?9BjbHepOmojoD3ZbGavHexaFIpCmLOIrY5RMKPGecB7C5ISX2GaNVFZCVwTj?= =?us-ascii?Q?WL/Q4iVGzeXxcLqh6wM3Gtnx4vI/vCPrTHdJvP7ujRaSx8ZZNxbICiF1HYWN?= =?us-ascii?Q?CsSBo1YuXNDJipSHDeulkU/rwUQfnd5Zj8iWrZolIIIW5oK1+/JFVScKkpiL?= =?us-ascii?Q?7yjL0mgoAm/EQDulzM95o/GBZzrlHPWGHN0jArmzv/s8HC1BIMR6W+b1KB7q?= =?us-ascii?Q?jUCutSkg5Kfp2dkmpHd4yf+PoWbT3pYkA8/o8X8er9GoxhwcA6iDc4FY9Ak1?= =?us-ascii?Q?WDmIsv9/qrjQlqIoeoXfpSXmAwFxuim8HMExpv+TV1LF9He81hmftzP2jllo?= =?us-ascii?Q?kuAuA0KsimzJPj7Pjea2ARCrbzMaF+dNcR+jO1vQExhpDW5mEPcelA1n6q9k?= =?us-ascii?Q?dVCQAS5sK+9BJm3zW0oopCgbqhjffhWxp8/p0MgYQlcq6gLFxe1aTgoagds1?= =?us-ascii?Q?AbbXUZLCtfc65eIBtPCKaJ45yVFF3jIzxdjr5qIjCfsa1m1ykkKra/3PpXgA?= =?us-ascii?Q?4kzaHDf5xCdcPzR1KclGMLrwtv3S23WH+xH3+fuCKAQalL+NRRq4PSilbYhg?= =?us-ascii?Q?jym4X2fGf8ABcTL6l4Es/T05rMJffq/h+8UZoEbdWNijL5sxEIjlx5w3QQ6E?= =?us-ascii?Q?pQ8/+4pNCFgmRVoYXrFJmVf+Xec0830QOewUBzqDB8ri87hBM6MwOi4j0JhA?= =?us-ascii?Q?yC9xx4t2k4PnyhgPb3L0gKBJBhTiQiYm0TePrxjXi7hUYZwbTRKxYiscYgup?= =?us-ascii?Q?K7fotLS2cpXWyPCMOBv9NlJX+OLbA8HRJcaCoggGR3ndxkSjrJQIjYDZhhDS?= =?us-ascii?Q?k7lJm/3uRZg2oUb535GgkYnzX+sfwxz8CwrGERRcIWrvq6l76lLQwtfvgrs1?= =?us-ascii?Q?Rk4u6trlFMOIxf1TstWoOw45aDXzcjisXNPm8rpAYHyfa3EfMyQCeL07OWt0?= =?us-ascii?Q?oPtMW+BOd7yqAvhaGP5taa+8R/49gmj+nNG754BQknFdfnfJ6z8FX0E+eWP8?= =?us-ascii?Q?CM9/HaJS87y9WfLw2g3oOkrr4MIPl566bu7mQ0yrKKF3/5gFTjqwHZFMcd+s?= =?us-ascii?Q?2qH/BI2EVAqkumaaY+bH2YckOEUrTmXHknxUw7QDlD/M8r1zAQQ0vSG8S+7t?= =?us-ascii?Q?RRiLVKRccEXJkk34X+9BWHi4OCJ+L4MBs3DoE+gXXNpowxJcvfEZEvuRCHCP?= =?us-ascii?Q?FtQRHI8Jrot8MeKQxNRZN80wuDYM/LhzyTz0WhXjXMnS/D5eZ2NIu2RooCNx?= =?us-ascii?Q?QOnxWIstyd6Uzvue2zL0iehM2qtnemUqsy64iqaLs1Z6d2KR1suY2c7MjOI7?= =?us-ascii?Q?cetC9kXVDcQBB5NhbpG6ZCnNVkjPImY9EYr+HGJdONlwlplst9/ZweugDDJU?= =?us-ascii?Q?rCcwX78S3+N+q/27jDX1SxP/RE90wUOEpFP2bze8l2Iv5cvI95O1NP5dVhh6?= =?us-ascii?Q?KcM3FilGwA=3D=3D?= X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 9d788f4c-2031-43df-07c3-08dec8856d1e X-MS-Exchange-CrossTenant-AuthSource: PA6PR04MB11910.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Jun 2026 13:20:52.1747 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: KOlLG/HJUEF/OisjG0xOeLXK5BRbSCOtl9+Y+ulOtin4FwtD/+iFUYY0weW3nHe5/phSntYar4gDTmR35pDb7w== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB9PR04MB8203 Content-Type: text/plain; charset="utf-8" This patch adds new v4l2 meta formats definitions and descriptions used by neoisp driver for the parameters and statistics buffers: - `V4L2_META_FMT_NEO_ISP_EXT_PARAMS` used for the generic v4l2-isp extensible parameters structure, supporting a non-fixed-size buffer and changeable ISP configuration blocks. - `V4L2_META_FMT_NEO_ISP_EXT_STATS` used for the generic v4l2-isp extensible statistics structure, supporting a non-fixed-size buffer and changeable ISP statistics blocks. Signed-off-by: Antoine Bouyer --- drivers/media/v4l2-core/v4l2-ioctl.c | 2 ++ include/uapi/linux/videodev2.h | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core= /v4l2-ioctl.c index a2b650f4ec3c..acc60dc69d31 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1471,6 +1471,8 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_META_FMT_C3ISP_STATS: descr =3D "Amlogic C3 ISP Statistics"; b= reak; case V4L2_META_FMT_MALI_C55_PARAMS: descr =3D "ARM Mali-C55 ISP Parameter= s"; break; case V4L2_META_FMT_MALI_C55_STATS: descr =3D "ARM Mali-C55 ISP 3A Statist= ics"; break; + case V4L2_META_FMT_NEO_ISP_EXT_PARAMS: descr =3D "NXP Neo ISP ext 3A Para= meters"; break; + case V4L2_META_FMT_NEO_ISP_EXT_STATS: descr =3D "NXP Neo ISP ext 3A Stati= stics"; break; case V4L2_PIX_FMT_NV12_8L128: descr =3D "NV12 (8x128 Linear)"; break; case V4L2_PIX_FMT_NV12M_8L128: descr =3D "NV12M (8x128 Linear)"; break; case V4L2_PIX_FMT_NV12_10BE_8L128: descr =3D "10-bit NV12 (8x128 Linear, = BE)"; break; diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index eda4492e40dc..e1656520b312 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -889,6 +889,10 @@ struct v4l2_pix_format { #define V4L2_META_FMT_MALI_C55_PARAMS v4l2_fourcc('C', '5', '5', 'P') /* A= RM Mali-C55 Parameters */ #define V4L2_META_FMT_MALI_C55_STATS v4l2_fourcc('C', '5', '5', 'S') /* AR= M Mali-C55 3A Statistics */ =20 +/* Vendor specific - used for NXP NEOISP sub-system */ +#define V4L2_META_FMT_NEO_ISP_EXT_PARAMS v4l2_fourcc('N', 'N', 'E', 'P') /= * NXP NEOISP Extensible Parameters */ +#define V4L2_META_FMT_NEO_ISP_EXT_STATS v4l2_fourcc('N', 'N', 'E', 'S') /= * NXP NEOISP Extensible Statistics */ + #ifdef __KERNEL__ /* * Line-based metadata formats. Remember to update v4l_fill_fmtdesc() when --=20 2.53.0 From nobody Sat Jun 13 02:07:57 2026 Received: from AM0PR02CU008.outbound.protection.outlook.com (mail-westeuropeazon11013052.outbound.protection.outlook.com [52.101.72.52]) (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 5EB833E5EF1; Fri, 12 Jun 2026 13:20:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.72.52 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781270463; cv=fail; b=b3SSWL/EtQzMvv0byAoW0XcS2dBuDYJdVvlI4BxEyESxia3t6oO8E4jZ6HDjnR1uPf5NsrZReRVCHtnJCTUACWZa5DlXzua5gTyWs522l3wzcZqm/gQXNacOCrYcyVnQyx+8FtyQ1Fp2bSG9sDL6NToDh0L0N2gv67GxZBR6uRY= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781270463; c=relaxed/simple; bh=s1a+PJSYAuOeza1pRzCFb9lUBE4cKaDoVifed60zhtQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=ZRxrvJzW8ABqKqLBaQdULDrc7IZoEXZRm4G7IfwxwbxAq3kNP/ai0Q8TtSs5tByzZ6dVcByRLt0CpX84lH0LC7wI0qi3FJ2Xv/cdammFlTEb+E/FDLN4d8G8SYAVmfQ7+6Th/OQK6X0S3aApao+TY9ettPXrIptZVxh6VZedGu4= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com; spf=pass smtp.mailfrom=nxp.com; dkim=pass (2048-bit key) header.d=nxp.com header.i=@nxp.com header.b=dIwef7kw; arc=fail smtp.client-ip=52.101.72.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nxp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nxp.com header.i=@nxp.com header.b="dIwef7kw" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=xsuGnGJMXv8MFd9ah3uqKFhzzOzQqbu4OmcGrqwnlRjMbMMMs6q7Y368ozAaq6TKjJUVRJnC6wHyFrgO6J0qfkipUdp2j0bJYA2sC+kEwZsZEMrKS5o+cbEjq2oTT9lPEjEWfFcPvNoV3OOxWHYx0h9GcYddYkfou/dX7V+xdFe6L5KkSR5yFS+/k9sH2t79GorZAIJO3NFgC6S+365l0lKi7vE+tU7RxPGBBSKe4BXBc5gbrc8S+6nIDoBz//2DzzsYBquZhXMhgYdQSeChpmy2ae/ZglumRR5QVyXazkWTOP/NyK0ksCqyDUyyNYjeTtr2XPCX60g/wGuCGKhTrg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=RwehiwJ7HEEHFDB35aXkYj77L6pfOZ7NwurtOXiBnA0=; b=Xtl1Yl+RZ2W/7qk+R2PvHNtEnmvvA6eDfwopQm7voJ2cjYbO/UjJIoSTSLKrkPdYk5bh38sTCD1fPJlDyoibGD1carF+FHubLhYOKTTKmMgjj17IzAlyEqpxJ/hZ8t4qMFGgi8jgXbml+0IizddqMstHJW5cTNb7+M7fI47N+ax9RkRSD1Zi5K45EV2h2rVSfDIKkP1fDz2ZJWgtO84gBt+18d9fZDQ25GyfziezDuf5MyhNrOyOm1EQrs4qTR7mNC0rF4JwMpi50EbOwCpDdZKBcqk5c/TmZ3Z4AlFN9IcrL8n1Xvv0QRen79NqrQCru+hyAxlX29VvmHkcF8yszw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nxp.com; dmarc=pass action=none header.from=nxp.com; dkim=pass header.d=nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=RwehiwJ7HEEHFDB35aXkYj77L6pfOZ7NwurtOXiBnA0=; b=dIwef7kwpyZCmr70C97ToSQzdZ+yvf/BzZrEsLxHITZYC7SFWYjCH0GK/lfxY2b6EN925Iq7BJuNknCO0wULdvrLMupIMH8IfBudecoD8oZD5RwrPQR2mQ2cEJsKGY/W2J3yU0enyVZccL3iIm0PXFNygUibq8XEWABcVjylZCQyR4261K1WXWXbfLUP+3oTm39Nkzgq0GuI88ZHqNXclOpsKuvMQeION+Pr9XhXN5Qm5HURTgFTgrtiSoNBdqa4Beb31Qio/WKSwGyYML3de23vvI3dPgz5BpbDmlQNFIJ5HUrKInIN9E3wWIiQ2I+N5hTGqLAEFNLfqyco/DCoPA== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from PA6PR04MB11910.eurprd04.prod.outlook.com (2603:10a6:102:516::16) by PAWPR04MB9957.eurprd04.prod.outlook.com (2603:10a6:102:385::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.113.14; Fri, 12 Jun 2026 13:20:54 +0000 Received: from PA6PR04MB11910.eurprd04.prod.outlook.com ([fe80::d3f0:3c24:f717:4989]) by PA6PR04MB11910.eurprd04.prod.outlook.com ([fe80::d3f0:3c24:f717:4989%4]) with mapi id 15.21.0113.013; Fri, 12 Jun 2026 13:20:54 +0000 From: Antoine Bouyer To: julien.vuillaumier@nxp.com, alexi.birlinger@nxp.com, daniel.baluta@nxp.com, peng.fan@nxp.com, frank.li@nxp.com, jacopo.mondi@ideasonboard.com, laurent.pinchart@ideasonboard.com, mchehab@kernel.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, michael.riesch@collabora.com, anthony.mcgivern@arm.com Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, imx@lists.linux.dev, ai.luthra@ideasonboard.com, paul.elder@ideasonboard.com, geert@linux-m68k.org, sakari.ailus@linux.intel.com, hverkuil+cisco@kernel.org, Antoine Bouyer Subject: [PATCH v3 4/8] media: uapi: Add NXP NEOISP user interface header file Date: Fri, 12 Jun 2026 15:20:35 +0200 Message-ID: <20260612132039.2089051-5-antoine.bouyer@nxp.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260612132039.2089051-1-antoine.bouyer@nxp.com> References: <20260612132039.2089051-1-antoine.bouyer@nxp.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: FR4P281CA0095.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:cb::6) To PA6PR04MB11910.eurprd04.prod.outlook.com (2603:10a6:102:516::16) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PA6PR04MB11910:EE_|PAWPR04MB9957:EE_ X-MS-Office365-Filtering-Correlation-Id: 994bbd3e-b81e-474d-3584-08dec8856e32 X-LD-Processed: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635,ExtAddr X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|7416014|376014|23010399003|366016|19092799006|1800799024|921020|11063799006|3023799007|6133799003|56012099006|22082099003|18002099003; X-Microsoft-Antispam-Message-Info: 0ZzGnXan70qPv+y0VIMeYlGu5wExkpve20vED4O0IJs5OPutTpxORypqSlr/6meiaLeILhk3zKzNAoTYWCSdR0Vn7gojcHO7ivQ/UTobdHSWsUcj2aKIv+NWs7RCYJQxTT6UoDuwcTBC+AtrHdY+8WhaE4o+wIosbT2kUYQtThdQDf8XEcadKoJJo64niPjRukLcvf8skxO3ueIen8ku+ro4J9OTHu150aJUX46GNu2k5lR+d9BsGxuGYTalXs+4GkVyTEsR9SKBC7yA/0zgZ9dvrOoQ7X6gzkI2R9Zh2CyO1Um451yg+3MdStLW03L5F0FVO/jlopNsyI/hHYofm6uYlcB93mjtX6fNSWTTGT2Vp3uBj6nysluowlWfe1abq6HokGY4m4Ll0hL+i8m5OopIYjYK04A+To49EXznN7Ex7SeN9cqbKvZal9EO9rcKhNEIpZjLmZG3zJinpeQz/yFbelS+sOCP44U05y9KehVUlu4VFMin/H4Sd3EJTFnzbn1F8UXrF24dGRBkvLCwBACczes8ljWMKOWsAwrsmw4LzlaOy4Q9OFWPRHB18kS6CIe3woat838mLYClMCPQI7vIwntB7d9gWvo1rdK8NIyG9agBpuLcqLN0WS4pobEWEHyfx+FzEnrbvE/0bRN0EChMhKFp1YymZltan8neLd8CZ+MaEu1zio0DFfO/e/nObYL5fD6gpFXNinC+r11z29CPHo+RgEJzxCwiKhhi1j0= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PA6PR04MB11910.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(7416014)(376014)(23010399003)(366016)(19092799006)(1800799024)(921020)(11063799006)(3023799007)(6133799003)(56012099006)(22082099003)(18002099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?+GknMxGHsAYPAiE4OxI8G8jXUvKxjnuUT7IYhewZydoP+HmHBMmFKTtY7vr7?= =?us-ascii?Q?Tve6C1Q2PZ5YuGEsa6vHRj8X5IhM5gengLmeY9VanLAg6nQHzp/uV1QYrnMU?= =?us-ascii?Q?g9wIKPT3gPgqRANL5PhgSp3qDVkxoGptuosjENaTgejEh0LqOALj8tMPyKsd?= =?us-ascii?Q?LkkOLYFVbGDE+wb8sPpAgx7cOlkUO8+TlxkUUSpLPXgBURgpzMObq7/ttBHa?= =?us-ascii?Q?UV4asSxAJExavOa7L+FelH2VI4avKMIrh4vltipYzzAptLIAttGa99PD+606?= =?us-ascii?Q?RMTc0OnaZciqBDHvRz2TIV3KgTqgsB9CUH5OeMwpyT8StoADtk8y0wSAWYRK?= =?us-ascii?Q?vWikBW6+3IwMvBp3EF0UDz0h/P91IbME+ovlsPGXfIMt+Mc3DMGcP6iz845h?= =?us-ascii?Q?eeZNco0/GNFxgMK6mZi/yCAzaYu+13DUSeYj78WhqO2e65UOf6XsogcUfbsQ?= =?us-ascii?Q?GK5lfUukOgX10fZx0wxaIX4AZdOS37n5L9b494y1DVCpg0yd77js8LHaDq71?= =?us-ascii?Q?ClEMNqTlkiqtuyMyKZdE7LZQd5UC7T98ZC/q/tdihBBGOuy2UZRP22P1+QkD?= =?us-ascii?Q?McGO1aUadZuxOgt22+pKQdFmjmCj1/igCMHDYH4VmDgLLV0pNkrg+1p0ie6e?= =?us-ascii?Q?g1xUxnHUNcQxP8HKmpCDH29F4m8hVoG4mWMwbQ2YE15EOuojXkseOizOrn55?= =?us-ascii?Q?po8AJD86Z4ax3eNcmqzClJgzPbbVvxRF1/fKIsnK0TWlNMSvUkYTvzeIW8kb?= =?us-ascii?Q?d/z52l+2Woo6jfYQ4xSzb3p0Ll5elF4hnMa1dT4A6VKRDckaqA6G41rWTPlQ?= =?us-ascii?Q?ruWbuBUuda9GrFw3XDwaS2SdCw4OoeS3f8ybnMgzqBlV56HdDGzr4X2ukBdz?= =?us-ascii?Q?PscnsazKX7/czL3jG+skKcIab1zS3gf7JP+gKrc45qNKDOnNBQ9d4yq7HIDU?= =?us-ascii?Q?h9gXmnAN/oCI75CCsH8K6pu7UtrqqFL9ljrIp+8jOegQgpZlG0RCGyzjFLHa?= =?us-ascii?Q?yUFmTZJQwhwy0aWAnp011ZjE5BZlWcghe23Gz7d/HMX4FA0V7uhZvFxsA3gD?= =?us-ascii?Q?oCtbQywXc2IFAoIzsb7IsH2KxweC02o4g71srr/YE2E1Cijf6vFoqzG7F4A1?= =?us-ascii?Q?uKJmZsCVWb7y3SYTcQ2PqBB4T/mAyk3Ah8VS4AqDOsNKZQjPepU4hdUjfmZL?= =?us-ascii?Q?LxUYeTYBiJ/+cmCXZYGSa26db50EkdQbtaxvMD7txrbGj+CXLoIyY1qfpuse?= =?us-ascii?Q?zKIKuYWDI7C5CXTnhSD49QbierIaSuf1FAUZjEO3/2zRVE3gFKyPWCgst6jF?= =?us-ascii?Q?hY0ZWofGcQqRS6icy9jBrw78wJ2ngvxljbcY+5oLUer/zMb+t+o9rRhs9n3C?= =?us-ascii?Q?otfJbbMrUBM1Z4p9AKll/w+dCzRdWLyvihr1bpyoS5CIE2/WT/dTDDJQUYqu?= =?us-ascii?Q?c3BlWzS20/oSvZnCvOy/fsvapQraXJjhrHQ2zYdAjMM6pYLlMtNEODLpG88/?= =?us-ascii?Q?AA38HiXmGOjisptEEGs7SCvahFMX2tneetH7C2xuqjowTQNIrCdDsHRiGxNq?= =?us-ascii?Q?YUpnAQrzpcUDdprK04jzAjuLCulNJJRt9NI1+tB6KKzAC6x8kYV5Enj+EJKJ?= =?us-ascii?Q?MCtutAZAvu75MYITelKdkya/0yZou/hnsuSSPAlVA8X1YqbbtVQpMn01VMXt?= =?us-ascii?Q?D/AtQXtl57G2lQV3euqyDK3d+pBam/sua9ed1o+GDtgbMxe8IpheLTbAqReD?= =?us-ascii?Q?xK/Q8i+EIw=3D=3D?= X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 994bbd3e-b81e-474d-3584-08dec8856e32 X-MS-Exchange-CrossTenant-AuthSource: PA6PR04MB11910.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Jun 2026 13:20:54.1681 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 7KKCMo7U5L83Mztf5VOrJHOgkyLNa80Vv1uqLf1GN4x4xDk6Xkr7FstWs+SWeT0Pe6o+Lcv5VY0JB+h0IlLvzg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAWPR04MB9957 Content-Type: text/plain; charset="utf-8" Add user space api header file for meta data structures definitions. This header describes `parameters` buffer for the ISP blocks control by userspace, and `statistics` buffer for userspace and IPA handling. Both buffers use the newly introduced generic `v4l2_isp_buffer` definition, which behaves the same as the generic `v4l2_isp_params_buffer` already used by other ISP devices (rkisp1, mali-c55). Signed-off-by: Antoine Bouyer --- include/uapi/linux/media/nxp/nxp_neoisp.h | 1694 +++++++++++++++++++++ 1 file changed, 1694 insertions(+) create mode 100644 include/uapi/linux/media/nxp/nxp_neoisp.h diff --git a/include/uapi/linux/media/nxp/nxp_neoisp.h b/include/uapi/linux= /media/nxp/nxp_neoisp.h new file mode 100644 index 000000000000..2dafa19df324 --- /dev/null +++ b/include/uapi/linux/media/nxp/nxp_neoisp.h @@ -0,0 +1,1694 @@ +/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR MIT) */ +/* + * NXP NEOISP userspace API + * + * Copyright 2023-2026 NXP + */ + +#ifndef __UAPI_NXP_NEOISP_H +#define __UAPI_NXP_NEOISP_H + +#include +#include +#include + +/* + * Check Documentation/admin-guide/media/nxp-neoisp.rst for control detail= s. + */ +#define V4L2_CID_NEOISP_SUPPORTED_PARAMS_BLOCKS (V4L2_CID_USER_NEOISP_BASE= + 0) + +/* Local memories sizes (words size) */ + +/* CTemp statistics - 256 bytes - 64 x 32bits words */ +#define NEO_CTEMP_R_SUM_CNT 64 +#define NEO_CTEMP_G_SUM_CNT 64 +#define NEO_CTEMP_B_SUM_CNT 64 +/* CTemp statistics pixel count - 128 bytes - 64 x 16bits words */ +#define NEO_CTEMP_PIX_CNT_CNT 64 +/* RGBIR histogram - 1024 bytes - 256 x 32bits words */ +#define NEO_RGBIR_HIST_CNT 256 +/* Histograms/Statistics - 2048 bytes - 512 x 32bits words */ +#define NEO_HIST_STAT_CNT 512 +/* DRC Global histograms - 1664 bytes - 416 x 32bits words */ +#define NEO_DRC_GLOBAL_HIST_ROI_CNT 416 +/* DRC local sum - 4096 - 1024 x 32bits words */ +#define NEO_DRC_LOCAL_SUM_CNT 1024 +/* Vignetting look up table - 6144 bytes - 3072 x 16bits words */ +#define NEO_VIGNETTING_TABLE_SIZE 3072 +/* DRC Global Tonemap - 832 bytes - 416 x 16bits words */ +#define NEO_DRC_GLOBAL_TONEMAP_SIZE 416 +/* DRC Local Tonemap - 1024 bytes - 1024 x 8bits words */ +#define NEO_DRC_LOCAL_TONEMAP_SIZE 1024 + +/** + * struct neoisp_pipe_conf_cfg_s - Pipeline Configuration + * @img_conf_inalign0: Input image 0 pixel alignment (0: LSB; 1: MSB) + * @img_conf_lpalign0: Linepath 0 pixel alignment (0: LSB; 1: MSB) + * @img_conf_inalign1: Input image 1 pixel alignment (0: LSB; 1: MSB) + * @img_conf_lpalign1: Linepath 1 pixel alignment (0: LSB; 1: MSB) + * + * These fields configure how the images are fetched into the NEO pipeline. + * + * INALIGN0/1 configures if the image is fetched MSB or LSB-aligned from t= he + * 16-bit aligned words in the DDR buffer. + * + * LPALIGN0/1 configures how the N-bit pixel data is fetched from the DDR + * buffer will be stored into the ISP internal pipeline. + */ +struct neoisp_pipe_conf_cfg_s { + __u8 img_conf_inalign0; + __u8 img_conf_lpalign0; + __u8 img_conf_inalign1; + __u8 img_conf_lpalign1; +}; + +/** + * struct neoisp_head_color_cfg_s - Head color configuration + * @ctrl_hoffset: Horizontal Head Pixel offset + * @ctrl_voffset: Vertical Head Pixel offset + */ +struct neoisp_head_color_cfg_s { + __u8 ctrl_hoffset; + __u8 ctrl_voffset; +}; + +/** + * struct neoisp_hdr_decompress0_cfg_s - HDR Decompression for line path 0= configuration + * @knee_point1: Knee point 1 value for interpolation step of the decompre= ssion + * @knee_point2: Knee point 2 value for interpolation step of the decompre= ssion + * @knee_point3: Knee point 3 value for interpolation step of the decompre= ssion + * @knee_point4: Knee point 4 value for interpolation step of the decompre= ssion + * @knee_offset0: Knee point offset 0 value for interpolation step of the = decompression + * @knee_offset1: Knee point offset 1 value for interpolation step of the = decompression + * @knee_offset2: Knee point offset 2 value for interpolation step of the = decompression + * @knee_offset3: Knee point offset 3 value for interpolation step of the = decompression + * @knee_offset4: Knee point offset 4 value for interpolation step of the = decompression + * @knee_ratio0: Knee point ratio 0 value for interpolation step of the de= compression + * @knee_ratio1: Knee point ratio 1 value for interpolation step of the de= compression + * @knee_ratio2: Knee point ratio 2 value for interpolation step of the de= compression + * @knee_ratio3: Knee point ratio 3 value for interpolation step of the de= compression + * @knee_ratio4: Knee point ratio 4 value for interpolation step of the de= compression + * @knee_npoint0: New knee point 0 value for the output + * @knee_npoint1: New knee point 1 value for the output + * @knee_npoint2: New knee point 2 value for the output + * @knee_npoint3: New knee point 3 value for the output + * @knee_npoint4: New knee point 4 value for the output + */ +struct neoisp_hdr_decompress0_cfg_s { + __u16 knee_point1; + __u16 knee_point2; + __u16 knee_point3; + __u16 knee_point4; + __u16 knee_offset0; + __u16 knee_offset1; + __u16 knee_offset2; + __u16 knee_offset3; + __u16 knee_offset4; + __u16 knee_ratio0; + __u16 knee_ratio1; + __u16 knee_ratio2; + __u16 knee_ratio3; + __u16 knee_ratio4; + __u32 knee_npoint0; + __u32 knee_npoint1; + __u32 knee_npoint2; + __u32 knee_npoint3; + __u32 knee_npoint4; +}; + +/** + * struct neoisp_hdr_decompress1_cfg_s - HDR Decompression for line path 1= configuration + * @knee_point1: Knee point 1 value for interpolation step of the decompre= ssion + * @knee_point2: Knee point 2 value for interpolation step of the decompre= ssion + * @knee_point3: Knee point 3 value for interpolation step of the decompre= ssion + * @knee_point4: Knee point 4 value for interpolation step of the decompre= ssion + * @knee_offset0: Knee point offset 0 value for interpolation step of the = decompression + * @knee_offset1: Knee point offset 1 value for interpolation step of the = decompression + * @knee_offset2: Knee point offset 2 value for interpolation step of the = decompression + * @knee_offset3: Knee point offset 3 value for interpolation step of the = decompression + * @knee_offset4: Knee point offset 4 value for interpolation step of the = decompression + * @knee_ratio0: Knee point ratio 0 value for interpolation step of the de= compression + * @knee_ratio1: Knee point ratio 1 value for interpolation step of the de= compression + * @knee_ratio2: Knee point ratio 2 value for interpolation step of the de= compression + * @knee_ratio3: Knee point ratio 3 value for interpolation step of the de= compression + * @knee_ratio4: Knee point ratio 4 value for interpolation step of the de= compression + * @knee_npoint0: New knee point 0 value for the output + * @knee_npoint1: New knee point 1 value for the output + * @knee_npoint2: New knee point 2 value for the output + * @knee_npoint3: New knee point 3 value for the output + * @knee_npoint4: New knee point 4 value for the output + */ +struct neoisp_hdr_decompress1_cfg_s { + __u16 knee_point1; + __u16 knee_point2; + __u16 knee_point3; + __u16 knee_point4; + __u16 knee_offset0; + __u16 knee_offset1; + __u16 knee_offset2; + __u16 knee_offset3; + __u16 knee_offset4; + __u16 knee_ratio0; + __u16 knee_ratio1; + __u16 knee_ratio2; + __u16 knee_ratio3; + __u16 knee_ratio4; + __u16 knee_npoint0; + __u16 knee_npoint1; + __u16 knee_npoint2; + __u16 knee_npoint3; + __u16 knee_npoint4; +}; + +#define NEO_OBWB_CNT (3) + +/** + * struct neoisp_obwb_cfg_s - Optical Black correction and White Balance c= onfiguration + * @ctrl_obpp: Indicates the size of pixel components output + * (0: 12bpp; 1: 14bpp; 2: 16bpp; 3: 20bpp) + * @r_ctrl_gain: Provides gain for red channel + * @r_ctrl_offset: Provides offset for red channel + * @gr_ctrl_gain: Provides gain for green red channel + * @gr_ctrl_offset: Provides offset for green red channel + * @gb_ctrl_gain: Provides gain for green blue channel + * @gb_ctrl_offset: Provides offset for green blue channel + * @b_ctrl_gain: Provides gain for blue channel + * @b_ctrl_offset: Provides offset for blue channel + */ +struct neoisp_obwb_cfg_s { + __u8 ctrl_obpp; + __u16 r_ctrl_gain; + __u16 r_ctrl_offset; + __u16 gr_ctrl_gain; + __u16 gr_ctrl_offset; + __u16 gb_ctrl_gain; + __u16 gb_ctrl_offset; + __u16 b_ctrl_gain; + __u16 b_ctrl_offset; +}; + +/** + * struct neoisp_hdr_merge_cfg_s - HDR merge of 2 incoming images in a lin= e-by-line manner + * @ctrl_motion_fix_en: Set 1 to enable fixing of HDR artifacts due to mo= tion + * @ctrl_blend_3x3: Selects the HDR blending mode (0: 1x1; 1:3x3) + * @ctrl_gain1bpp: Size of pixel components after gain on line path 1 + * @ctrl_gain0bpp: Size of pixel components after gain on line path 0 + * @ctrl_obpp: Size of pixel components for the HDR Merge output + * @gain_offset_offset1: Offset parameter for input image 1 + * @gain_offset_offset0: Offset parameter for input image 0 + * @gain_scale_scale1: Scale factor of input pixel components of image 1 + * @gain_scale_scale0: Scale factor of input pixel components of image 0 + * @gain_shift_shift1: Shift factor (right shift) for gained image 1 + * @gain_shift_shift0: Shift factor (right shift) for gained image 0 + * @luma_th_th0: Provides luminance threshold 0 + * @luma_scale_scale: Scaling value which multiplies the threshold-condit= ioned luminance + * @luma_scale_shift: Right shift value the scaling factor + * @luma_scale_thshift: Right shift value for binomial output before thre= shold function + * @downscale_imgscale1: Down scaling (right shift) value corresponding to= image 1 + * @downscale_imgscale0: Down scaling (right shift) value corresponding to= image 0 + * @upscale_imgscale1: Up scaling (left shift) value corresponding to ima= ge 1 + * @upscale_imgscale0: Up scaling (left shift) value corresponding to ima= ge 0 + * @post_scale_scale: Down scaling (right shift) of the final blended out= put + */ +struct neoisp_hdr_merge_cfg_s { + __u8 ctrl_motion_fix_en; + __u8 ctrl_blend_3x3; + __u8 ctrl_gain1bpp; + __u8 ctrl_gain0bpp; + __u8 ctrl_obpp; + __u16 gain_offset_offset1; + __u16 gain_offset_offset0; + __u16 gain_scale_scale1; + __u16 gain_scale_scale0; + __u8 gain_shift_shift1; + __u8 gain_shift_shift0; + __u16 luma_th_th0; + __u16 luma_scale_scale; + __u8 luma_scale_shift; + __u8 luma_scale_thshift; + __u8 downscale_imgscale1; + __u8 downscale_imgscale0; + __u8 upscale_imgscale1; + __u8 upscale_imgscale0; + __u8 post_scale_scale; +}; + +/** + * struct neoisp_roi_cfg_s - common ROI structure + * @xpos: Provides the horizontal start position (pixel number) of the ROI + * @ypos: Provides the vertical start position (line number) of the ROI + * @width: Provides the horizontal width of the ROI + * @height: Provides the vertical height of the ROI + */ +struct neoisp_roi_cfg_s { + __u16 xpos; + __u16 ypos; + __u16 width; + __u16 height; +}; + +/** + * struct neoisp_stat_hist_cfg_s - common stat histograms structure + * @hist_ctrl_offset: Black level correction offset for each pixel + * @hist_ctrl_channel: Binary value of channel for binning on respective = histogram + * @hist_ctrl_pattern: Defines neighbouring pixel 1x1 (0) vs 2x2 (1) + * @hist_ctrl_dir_input1_dif: Defines Direct (0) vs Difference (1) + * @hist_ctrl_lin_input1_log: Defines Linear (0) vs Logarithmic (1) + * @hist_scale_scale: Scaling factor on the input pixel for bin determina= tion + */ +struct neoisp_stat_hist_cfg_s { + __u16 hist_ctrl_offset; + __u8 hist_ctrl_channel; + __u8 hist_ctrl_pattern; + __u8 hist_ctrl_dir_input1_dif; + __u8 hist_ctrl_lin_input1_log; + __u32 hist_scale_scale; +}; + +#define NEO_RGBIR_ROI_CNT (2) +#define NEO_RGBIR_STAT_HIST_CNT (2) + +/** + * struct neoisp_rgbir_cfg_s - RGBIR to RGGB and IR unit configuration + * @ccm0_ccm: Color correction parameter for component 0 (crosstalk 0) re= d if RGGB + * @ccm1_ccm: Color correction parameter for component 1 (crosstalk 1) bo= th green if RGGB + * @ccm2_ccm: Color correction parameter for component 2 (crosstalk 2) bl= ue if RGGB + * @ccm0_th_threshold: Crosstalk removal threshold from channel 3 (IR) to = channel 0 (red) + * @ccm1_th_threshold: Crosstalk removal threshold from channel 3 (IR) to = channel 1 (green) + * @ccm2_th_threshold: Crosstalk removal threshold from channel 3 (IR) to = channel 2 (blue) + * @roi: Array of region of interests + * @hists: Array of histograms parameters + */ +struct neoisp_rgbir_cfg_s { + __u16 ccm0_ccm; + __u16 ccm1_ccm; + __u16 ccm2_ccm; + __u32 ccm0_th_threshold; + __u32 ccm1_th_threshold; + __u32 ccm2_th_threshold; + struct neoisp_roi_cfg_s roi[NEO_RGBIR_ROI_CNT]; + struct neoisp_stat_hist_cfg_s hists[NEO_RGBIR_STAT_HIST_CNT]; +}; + +#define NEO_STAT_HIST_CNT (4) + +/** + * struct neoisp_stat_cfg_s - Statistics and Histogram unit configuration + * @roi0: Region of interest 0 + * @roi1: Region of interest 1 + * @hists: Control parameters for building the histogram + */ +struct neoisp_stat_cfg_s { + struct neoisp_roi_cfg_s roi0; + struct neoisp_roi_cfg_s roi1; + struct neoisp_stat_hist_cfg_s hists[NEO_STAT_HIST_CNT]; +}; + +/** + * struct neoisp_ir_compress_cfg_s - Infra-red Compression unit configurat= ion + * @ctrl_obpp: bpp of compressed output IR (0: 8bpp; 1: 16bpp) + * @knee_point1_kneepoint: Knee point 1 value for interpolation step of ir= compression + * @knee_point2_kneepoint: Knee point 2 value for interpolation step of ir= compression + * @knee_point3_kneepoint: Knee point 3 value for interpolation step of ir= compression + * @knee_point4_kneepoint: Knee point 4 value for interpolation step of ir= compression + * @knee_offset0_offset: Offset 0 value for interpolation step of ir compr= ession + * @knee_offset1_offset: Offset 1 value for interpolation step of ir compr= ession + * @knee_offset2_offset: Offset 2 value for interpolation step of ir compr= ession + * @knee_offset3_offset: Offset 3 value for interpolation step of ir compr= ession + * @knee_offset4_offset: Offset 4 value for interpolation step of ir compr= ession + * @knee_ratio01_ratio0: Ratio 0 value for interpolation step of ir compre= ssion (u1.15) + * @knee_ratio01_ratio1: Ratio 1 value for interpolation step of ir compre= ssion (u1.15) + * @knee_ratio23_ratio2: Ratio 2 value for interpolation step of ir compre= ssion (u1.15) + * @knee_ratio23_ratio3: Ratio 3 value for interpolation step of ir compre= ssion (u1.15) + * @knee_ratio4_ratio4: Ratio 4 value for interpolation step of ir compre= ssion (u1.15) + * @knee_npoint0_kneepoint: New 0 knee point value for the output + * @knee_npoint1_kneepoint: New 1 knee point value for the output + * @knee_npoint2_kneepoint: New 2 knee point value for the output + * @knee_npoint3_kneepoint: New 3 knee point value for the output + * @knee_npoint4_kneepoint: New 4 knee point value for the output + */ +struct neoisp_ir_compress_cfg_s { + __u8 ctrl_obpp; + __u32 knee_point1_kneepoint; + __u32 knee_point2_kneepoint; + __u32 knee_point3_kneepoint; + __u32 knee_point4_kneepoint; + __u32 knee_offset0_offset; + __u32 knee_offset1_offset; + __u32 knee_offset2_offset; + __u32 knee_offset3_offset; + __u32 knee_offset4_offset; + __u16 knee_ratio01_ratio0; + __u16 knee_ratio01_ratio1; + __u16 knee_ratio23_ratio2; + __u16 knee_ratio23_ratio3; + __u16 knee_ratio4_ratio4; + __u16 knee_npoint0_kneepoint; + __u16 knee_npoint1_kneepoint; + __u16 knee_npoint2_kneepoint; + __u16 knee_npoint3_kneepoint; + __u16 knee_npoint4_kneepoint; +}; + +/** + * struct neoisp_bnr_cfg_s - Bayer Noise Reduction unit configuration + * @ctrl_debug: Debug view for on-target tuning (0:off) + * @ctrl_obpp: Output bpp (0: 12bpp; 1: 14bpp; 2: 16bpp; 3: 20bpp) + * @ctrl_nhood: Neighbourhood Pattern (0: 2x2; 1: 1x1) + * @ypeak_peak_outsel: Output scaling (0: no scaling; 1: enable scaling) + * @ypeak_peak_sel: Selecting the boundary pixel among the sorted list (0.= .3: 1..4 positions) + * @ypeak_peak_low: Lower scale value of the clipping function (u4.8) + * @ypeak_peak_high: Higher scale value of the clipping function (u4.8) + * @yedge_th0_edge_th0: Lower edge threshold for long alpha blending coeff= icient calculation + * @yedge_scale_scale: Scaling factor for long alpha blending factor deter= mination + * @yedge_scale_shift: Right shift factor for blending factor determination + * For example, a shift value of 10, implements u6.10 scaling factor + * @yedges_th0_edge_th0: Lower threshold for short alpha blending function= in the BNR + * @yedges_scale_scale: Scale factor for determining the short alpha blend= ing threshold value + * @yedges_scale_shift: Right shift factor for blending factor determinati= on + * For example, a shift value of 10, implements u6.10 scaling factor + * @yedgea_th0_edge_th0: Lower threshold for final alpha blending function= in the BNR + * @yedgea_scale_scale: Scale factor for determining the final alpha blend= ing threshold value + * @yedgea_scale_shift: Right shift factor for blending factor determinati= on + * For example, a shift value of 10, implements u6.10 scaling factor + * @yluma_x_th0_th: X threshold 0 for blending coefficient calculation + * @yluma_y_th_luma_y_th0: 10-bit value for Y threshold 0 + * @yluma_y_th_luma_y_th1: 10-bit value for Y threshold 1 + * @yluma_scale_scale: Scale for the threshold-conditioned luma factor det= ermination + * @yluma_scale_shift: Right shift factor for blending factor determination + * For example, a shift value of 10, implements u6.10 scaling factor + * @yalpha_gain_gain: Gain value (multiplication factor) for the alpha coe= fficient + * @yalpha_gain_offset: Offset value (addition factor) for the gain'd alph= a coefficient + * @cpeak_peak_outsel: Set 1 to enable scaling of the output, 0 no scaling + * @cpeak_peak_sel: Provides selection for selecting the boundary pixel am= ong the sorted list + * @cpeak_peak_low: ower scale value of the clipping function (u4.8) + * @cpeak_peak_high: Higher scale value of the clipping function (u4.8) + * @cedge_th0_edge_th0: Lower threshold for blending function in the BNR u= nit + * @cedge_scale_scale: Scale for the threshold-conditioned blending factor= determination + * @cedge_scale_shift: Right shift factor for blending factor determination + * For example, a shift value of 10, implements u6.10 scaling factor + * @cedges_th0_edge_th0: Lower threshold for short alpha blending function= in the BNR unit + * @cedges_scale_scale: Scale for the threshold-conditioned short alpha bl= ending factor + * @cedges_scale_shift: Right shift factor for blending factor determinati= on + * For example, a shift value of 10, implements u6.10 scaling factor + * @cedgea_th0_edge_th0: Lower threshold for final alpha blending function + * @cedgea_scale_scale: Scale for the threshold-conditioned final alpha bl= ending factor + * @cedgea_scale_shift: Right shift factor for blending factor determinati= on + * For example, a shift value of 10, implements u6.10 scaling factor + * @cluma_x_th0_th: Provides the X threshold 0 for blending coefficient ca= lculation + * @cluma_y_th_luma_y_th0: 10-bit value for Y threshold 0 + * @cluma_y_th_luma_y_th1: 10-bit value for Y threshold 1 + * @cluma_scale_scale: Scale for the threshold-conditioned luma factor det= ermination + * @cluma_scale_shift: Right shift factor for blending factor determination + * For example, a shift value of 10, implements u6.10 scaling factor + * @calpha_gain_gain: Provides the gain value (multiplication factor) for = the alpha coefficient + * @calpha_gain_offset: Provides the offset value (addition factor) for th= e gain'd alpha coefficient + * @stretch_gain: Provides the gain factor for all the pixels at the outpu= t of BNR (u8.8) + * This gain is applied even when BNR is disabled + */ +struct neoisp_bnr_cfg_s { + __u8 ctrl_debug; + __u8 ctrl_obpp; + __u8 ctrl_nhood; + __u8 ypeak_peak_outsel; + __u8 ypeak_peak_sel; + __u16 ypeak_peak_low; + __u16 ypeak_peak_high; + __u32 yedge_th0_edge_th0; + __u16 yedge_scale_scale; + __u8 yedge_scale_shift; + __u32 yedges_th0_edge_th0; + __u16 yedges_scale_scale; + __u8 yedges_scale_shift; + __u32 yedgea_th0_edge_th0; + __u16 yedgea_scale_scale; + __u8 yedgea_scale_shift; + __u32 yluma_x_th0_th; + __u16 yluma_y_th_luma_y_th0; + __u16 yluma_y_th_luma_y_th1; + __u16 yluma_scale_scale; + __u8 yluma_scale_shift; + __u16 yalpha_gain_gain; + __u16 yalpha_gain_offset; + __u8 cpeak_peak_outsel; + __u8 cpeak_peak_sel; + __u16 cpeak_peak_low; + __u16 cpeak_peak_high; + __u32 cedge_th0_edge_th0; + __u16 cedge_scale_scale; + __u8 cedge_scale_shift; + __u32 cedges_th0_edge_th0; + __u16 cedges_scale_scale; + __u8 cedges_scale_shift; + __u32 cedgea_th0_edge_th0; + __u16 cedgea_scale_scale; + __u8 cedgea_scale_shift; + __u32 cluma_x_th0_th; + __u16 cluma_y_th_luma_y_th0; + __u16 cluma_y_th_luma_y_th1; + __u16 cluma_scale_scale; + __u8 cluma_scale_shift; + __u16 calpha_gain_gain; + __u16 calpha_gain_offset; + __u16 stretch_gain; +}; + +/** + * struct neoisp_vignetting_ctrl_cfg_s - Vignetting controlling configurat= ion + * @blk_conf_rows: Provides number of rows into which the input image is p= artitioned + * @blk_conf_cols: Provides number of columns into which the input image i= s partitioned + * @blk_size_ysize: Number of rows per block + * @blk_size_xsize: Number of pixels per block + * @blk_stepy_step: Vertical scaling factor (u0.16) + * @blk_stepx_step: Horizontal scaling factor (u0.16) + */ +struct neoisp_vignetting_ctrl_cfg_s { + __u8 blk_conf_rows; + __u8 blk_conf_cols; + __u16 blk_size_ysize; + __u16 blk_size_xsize; + __u16 blk_stepy_step; + __u16 blk_stepx_step; +}; + +#define NEO_CTEMP_COLOR_ROIS_CNT (10) +#define NEO_CTEMP_CSC_MATRIX_SIZE (3) +#define NEO_CTEMP_CSC_OFFSET_VECTOR_SIZE (4) + +/** + * struct neoisp_ctemp_roi_desc_s - common color ROI Position Register + * @pos_roverg_low: Low value of red over green (u1.7) + * @pos_roverg_high: High value of red over green (u1.7) + * @pos_boverg_low: Low value of blue over green (u1.7) + * @pos_boverg_high: High value of blue over green (u1.7) + */ +struct neoisp_ctemp_roi_desc_s { + __u8 pos_roverg_low; + __u8 pos_roverg_high; + __u8 pos_boverg_low; + __u8 pos_boverg_high; +}; + +/** + * struct neoisp_ctemp_cfg_s - Color temperature unit configuration + * @ctrl_cscon: Color Space Correction ON (1), (0) disabled + * @ctrl_ibpp: Size of pixel components on input (0: 12bpp; 1: 14bpp; 2: = 16bpp; 3: 20bpp) + * @luma_th_thl: Provides the low threshold for luminance range check + * @luma_th_thh: Provides the high threshold for luminance range check + * @roi: Array of regions of interest + * @redgain_min: Minimum gain for the red channel (u1.7) + * @redgain_max: Maximum gain for the red channel (u1.7) + * @bluegain_min: Minimum gain for the blue channel (u1.7) + * @bluegain_max: Maximum gain for the blue channel (u1.7) + * @point1_blue: Point 1 value for blue over green curve (u1.7) + * @point1_red: Point 1 value for red over green curve (u1.7) + * @point2_blue: Point 2 value for blue over green curve (u1.7) + * @point2_red: Point 2 value for red over green curve (u1.7) + * @hoffset_right: Offset in increasing horizontal indices (u1.7) + * @hoffset_left: Offset in decreasing horizontal indices (u1.7) + * @voffset_up: Offset in increasing vertical indices (u1.7) + * @voffset_down: Offset in decreasing vertical indices (u1.7) + * @point1_slope_slope_l: Left slope for point 1 (s8.8) + * @point1_slope_slope_r: Right slope for point 1 (s8.8) + * @point2_slope_slope_l: Left slope for point 2 (s8.8) + * @point2_slope_slope_r: Right slope for point 2 (s8.8) + * @csc_matrix: A 3x3 color space correction matrix for respective camera= context (s8.8) + * @offsets: Correction offsets values of input filter array pixel + * @stat_blk_size0_xsize: Number of pixels per block. Should always be mul= tiple of 2 + * @stat_blk_size0_ysize: Number of image lines per block. Should always b= e multiple of 2 + * @color_rois: Array of color regions of interest + * @gr_avg_in_gr_agv: Subtracted from the GR values before accumulation in= to the GR vs GB sums + * @gb_avg_in_gb_agv: Subtracted from the GB values before accumulation in= to the GR vs GB sums + */ +struct neoisp_ctemp_cfg_s { + __u8 ctrl_cscon; + __u8 ctrl_ibpp; + __u16 luma_th_thl; + __u16 luma_th_thh; + struct neoisp_roi_cfg_s roi; + __u8 redgain_min; + __u8 redgain_max; + __u8 bluegain_min; + __u8 bluegain_max; + __u8 point1_blue; + __u8 point1_red; + __u8 point2_blue; + __u8 point2_red; + __u8 hoffset_right; + __u8 hoffset_left; + __u8 voffset_up; + __u8 voffset_down; + __s16 point1_slope_slope_l; + __s16 point1_slope_slope_r; + __s16 point2_slope_slope_l; + __s16 point2_slope_slope_r; + __s16 csc_matrix[NEO_CTEMP_CSC_MATRIX_SIZE][NEO_CTEMP_CSC_MATRIX_SIZE]; + __s16 offsets[NEO_CTEMP_CSC_OFFSET_VECTOR_SIZE]; + __u16 stat_blk_size0_xsize; + __u16 stat_blk_size0_ysize; + struct neoisp_ctemp_roi_desc_s color_rois[NEO_CTEMP_COLOR_ROIS_CNT]; + __u32 gr_avg_in_gr_agv; + __u32 gb_avg_in_gb_agv; +}; + +/** + * struct neoisp_demosaic_cfg_s - Demosaic function on the input bayer ima= ge configuration + * @ctrl_fmt: Format of the input image (0: rggb; 1: rccc; 2: monochrome) + * @activity_ctl_alpha: Alpha Blending Factor (u1.8) + * @activity_ctl_act_ratio: Activity Ratio (u8.8) + * @dynamics_ctl0_strengthg: Feedback strength for green pixel interpolati= on (u8.8) + * @dynamics_ctl0_strengthc: Feedback strength for color (red or blue) pix= el interpolation (u8.8) + * @dynamics_ctl2_max_impact: Maximum impact of the dynamics on the interp= olated values (u8.8) + */ +struct neoisp_demosaic_cfg_s { + __u8 ctrl_fmt; + __u16 activity_ctl_alpha; + __u16 activity_ctl_act_ratio; + __u16 dynamics_ctl0_strengthg; + __u16 dynamics_ctl0_strengthc; + __u16 dynamics_ctl2_max_impact; +}; + +#define NEO_RGB2YUV_MATRIX_SIZE (3) + +/** + * struct neoisp_rgb2yuv_cfg_s - Color space conversion RGB to YUV data co= nfiguration + * @gain_ctrl_rgain: Provides the gain factor corresponding to red compone= nt + * @gain_ctrl_bgain: Provides the gain factor corresponding to blue compon= ent + * @mat_rxcy: Provides the values of elements of the 3x3 color space conv= ersion matrix + * @csc_offsets: Provides the offsets of the color space conversion matrix= (s21) + */ +struct neoisp_rgb2yuv_cfg_s { + __u16 gain_ctrl_rgain; + __u16 gain_ctrl_bgain; + __s16 mat_rxcy[NEO_RGB2YUV_MATRIX_SIZE][NEO_RGB2YUV_MATRIX_SIZE]; + __s32 csc_offsets[NEO_RGB2YUV_MATRIX_SIZE]; +}; + +/** + * struct neoisp_dr_comp_cfg_s - Dynamic Range Compression unit configurat= ion + * @roi0: Region of interest 0 + * @roi1: Region of interest 1 + * @groi_sum_shift_shift0: Global ROI 0 sum shift value (u5) + * @groi_sum_shift_shift1: Global ROI 1 sum shift value (u5) + * @gbl_gain_gain: Provides a gain for the global DRC (u8.8) + * @lcl_blk_size_xsize: Provides number of pixels per block + * @lcl_blk_size_ysize: Provides number of rows per block + * @lcl_stretch_offset: Black level value before applying gamma + * @lcl_stretch_stretch: Provides local DRC stretch value of the input (u8= .8) + * @lcl_blk_stepx_step: Horizontal scaling factor (u0.16) + * @lcl_blk_stepy_step: Vertical scaling factor (u0.16) + * @lcl_sum_shift_shift: Provides shift value for building the local DRC (= u5) + * @alpha_alpha: Alpha value for blending step between global and local D= RC (u9) + */ +struct neoisp_dr_comp_cfg_s { + struct neoisp_roi_cfg_s roi0; + struct neoisp_roi_cfg_s roi1; + __u8 groi_sum_shift_shift0; + __u8 groi_sum_shift_shift1; + __u16 gbl_gain_gain; + __u16 lcl_blk_size_xsize; + __u16 lcl_blk_size_ysize; + __u16 lcl_stretch_offset; + __u16 lcl_stretch_stretch; + __u16 lcl_blk_stepx_step; + __u16 lcl_blk_stepy_step; + __u8 lcl_sum_shift_shift; + __u16 alpha_alpha; +}; + +/** + * struct neoisp_nr_cfg_s - Noise Reduction unit configuration + * @ctrl_debug: This field controls if tuning/debug information + * @blend_scale_gain: Gain value for the blending factor determination (u4= .4) + * @blend_scale_shift: Shift value for the blending factor determination + * @blend_scale_scale: Scale factor for the blending factor determination + * @blend_th0_th: Provides threshold 0 value for determining the blending = factor (u20) + */ +struct neoisp_nr_cfg_s { + __u8 ctrl_debug; + __u8 blend_scale_gain; + __u8 blend_scale_shift; + __u16 blend_scale_scale; + __u32 blend_th0_th; +}; + +#define NEO_AF_ROIS_CNT (9) +#define NEO_AF_FILTERS_CNT (9) + +/** + * struct neoisp_af_cfg_s - AutoFocus unit configuration + * @af_roi: Array of regions of interest + * @fil0_coeffs: Array of Autofocus Filter 0 Coefficients + * @fil0_shift_shift: Provides the shift (scale down) factor at the output= of filter 0 (u5) + * @fil1_coeffs: Array of Autofocus Filter 1 Coefficients + * @fil1_shift_shift: Provides the shift (scale down) factor at the output= of filter 1 (u5) + */ +struct neoisp_af_cfg_s { + struct neoisp_roi_cfg_s af_roi[NEO_AF_ROIS_CNT]; + __s8 fil0_coeffs[NEO_AF_FILTERS_CNT]; + __u8 fil0_shift_shift; + __s8 fil1_coeffs[NEO_AF_FILTERS_CNT]; + __u8 fil1_shift_shift; +}; + +/** + * struct neoisp_ee_cfg_s - Edge Enhancement unit configuration + * @ctrl_debug: This field controls if tuning/debug information is shown = in the + * output image (0: Off; 1: edge pixels shown as white; 2: edge + * pixels shown as white and all others) + * @maskgain_gain: Gain value for the HPF factor determination (u4.4) + * @coring_coring: Coring value for the mask factor determination (u20) + * @clip_clip: Clip value for the mask factor determination (u20) + */ +struct neoisp_ee_cfg_s { + __u8 ctrl_debug; + __u8 maskgain_gain; + __u32 coring_coring; + __u32 clip_clip; +}; + +/** + * struct neoisp_df_cfg_s - Direction Filter unit configuration + * @ctrl_debug: This field controls if tuning/debug information + * @blend_shift_shift: Shift factor for the blending factor determination = (u6) + * @th_scale_scale: Scale factor for the blending factor determination (u2= 0) + * @blend_th0_th: Provides threshold 0 value for determining the blending = factor (u20) + */ +struct neoisp_df_cfg_s { + __u8 ctrl_debug; + __u8 blend_shift_shift; + __u32 th_scale_scale; + __u32 blend_th0_th; +}; + +/** + * struct neoisp_convmed_cfg_s - Color Convolution and Median Filter unit = configuration + * @ctrl_flt: This field controls the type of filtering to be executed: + * (0: bypassed; 1: convolution (5x5 binomial); 2: median (5x5)) + */ +struct neoisp_convmed_cfg_s { + __u8 ctrl_flt; +}; + +/** + * struct neoisp_cas_cfg_s - Color Adaptive Saturation unit configuration + * @gain_shift: Shift value for the suppression factor determination + * @gain_scale: Scale factor for the suppression factor + * @corr_corr: Minimum correction factor for dark pixels (u8.8) + * @offset_offset: Offset value for the suppression factor determination + */ +struct neoisp_cas_cfg_s { + __u8 gain_shift; + __u16 gain_scale; + __u16 corr_corr; + __u16 offset_offset; +}; + +#define NEO_GAMMA_MATRIX_SIZE (3) +#define NEO_GAMMA_OFFSETS_SIZE (3) + +/** + * struct neoisp_gcm_cfg_s - Gamma Correction Matrix unit configuration + * @imat_rxcy: 3x3 input gamma correction matrix (s8.8) + * @ioffsets: Offset values for input channels + * @omat_rxcy: 3x3 output gamma correction matrix + * @ooffsets: Offset values of 3x3 output matrix (s12) + * @gamma0_gamma0: Provides the gamma value of channel 0 (u1.8) + * @gamma0_offset0: Provides the offset value of channel 0 (u12) + * @gamma1_gamma1: Provides the gamma value of channel 1 (u1.8) + * @gamma1_offset1: Provides the offset value of channel 1 (u12) + * @gamma2_gamma2: Provides the gamma value of channel 2 (u1.8) + * @gamma2_offset2: Provides the offset value of channel 2 (u12) + * @blklvl0_ctrl_gain0: Gain value for the linear part of the channel 0 g= amma curve (u8.8) + * @blklvl0_ctrl_offset0: Blacklevel value to be subtracted on channel 0 + * @blklvl1_ctrl_gain1: Gain value for the linear part of the channel 1 g= amma curve (u8.8) + * @blklvl1_ctrl_offset1: Blacklevel value to be subtracted on channel 1 + * @blklvl2_ctrl_gain2: Gain value for the linear part of the channel 2 g= amma curve (u8.8) + * @blklvl2_ctrl_offset2: Blacklevel value to be subtracted on channel 2 + * @lowth_ctrl01_threshold0: Threshold for low area of the dynamic range o= f channel 0 (u12.4) + * @lowth_ctrl01_threshold1: Threshold for low area of the dynamic range o= f channel 1 (u12.4) + * @lowth_ctrl2_threshold2: Threshold for low area of the dynamic range of= channel 2 (u12.4) + * @mat_confg_sign_confg: Set 0 for signe gcm, 1 Unsigned + */ +struct neoisp_gcm_cfg_s { + __s16 imat_rxcy[NEO_GAMMA_MATRIX_SIZE][NEO_GAMMA_MATRIX_SIZE]; + __s16 ioffsets[NEO_GAMMA_OFFSETS_SIZE]; + __s16 omat_rxcy[NEO_GAMMA_MATRIX_SIZE][NEO_GAMMA_MATRIX_SIZE]; + __s16 ooffsets[NEO_GAMMA_OFFSETS_SIZE]; + __u16 gamma0_gamma0; + __u16 gamma0_offset0; + __u16 gamma1_gamma1; + __u16 gamma1_offset1; + __u16 gamma2_gamma2; + __u16 gamma2_offset2; + __u16 blklvl0_ctrl_gain0; + __s16 blklvl0_ctrl_offset0; + __u16 blklvl1_ctrl_gain1; + __s16 blklvl1_ctrl_offset1; + __u16 blklvl2_ctrl_gain2; + __s16 blklvl2_ctrl_offset2; + __u16 lowth_ctrl01_threshold0; + __u16 lowth_ctrl01_threshold1; + __u16 lowth_ctrl2_threshold2; + __u8 mat_confg_sign_confg; +}; + +/** + * struct neoisp_vignetting_table_mem_params_s - Vignetting table values + * @vignetting_table: Array of vignetting lookup table + */ +struct neoisp_vignetting_table_mem_params_s { + __u16 vignetting_table[NEO_VIGNETTING_TABLE_SIZE]; +}; + +/** + * struct neoisp_drc_global_tonemap_mem_params_s - DRC Global Tonemap + * @drc_global_tonemap: Global DRC tonemap lookup table + */ +struct neoisp_drc_global_tonemap_mem_params_s { + __u16 drc_global_tonemap[NEO_DRC_GLOBAL_TONEMAP_SIZE]; +}; + +/** + * struct neoisp_drc_local_tonemap_mem_params_s - DRC Local Tonemap + * @drc_local_tonemap: Local DRC tonemap lookup table + */ +struct neoisp_drc_local_tonemap_mem_params_s { + __u8 drc_local_tonemap[NEO_DRC_LOCAL_TONEMAP_SIZE]; +}; + +/** + * enum neoisp_param_block_type_e - Enumeration of Neoisp parameter blocks + * + * This enumeration defines the types of Neoisp parameters block. Each ent= ry + * configures a specific processing block of the Neoisp. The block type + * allows the driver to correctly interpret the parameters block data. + * + * It is the responsibility of userspace to correctly set the type of each + * parameters block. + * + * @NEOISP_PARAM_BLK_PIPE_CONF: Pipe configuration block + * @NEOISP_PARAM_BLK_HEAD_COLOR: Head Color block + * @NEOISP_PARAM_BLK_HDR_DECOMPRESS0: HDR decompression of line path 0 + * @NEOISP_PARAM_BLK_HDR_DECOMPRESS1: HDR decompression of line path 1 + * @NEOISP_PARAM_BLK_OBWB0: Optical Black Correction and White Balance of = line path 0 + * @NEOISP_PARAM_BLK_OBWB1: Optical Black Correction and White Balance of = line path 1 + * @NEOISP_PARAM_BLK_OBWB2: Optical Black Correction and White Balance of = merged path + * @NEOISP_PARAM_BLK_HDR_MERGE: HDR merge block + * @NEOISP_PARAM_BLK_RGBIR: RGB-IR block + * @NEOISP_PARAM_BLK_STAT: Statistics block + * @NEOISP_PARAM_BLK_IR_COMPRESS: Infrared compression block + * @NEOISP_PARAM_BLK_BNR: Bayer noise reduction block + * @NEOISP_PARAM_BLK_VIGNETTING_CTRL: Vignetting control block + * @NEOISP_PARAM_BLK_CTEMP: Color temperature block + * @NEOISP_PARAM_BLK_DEMOSAIC: Demosaicing block + * @NEOISP_PARAM_BLK_RGB2YUV: RGB to YUV block + * @NEOISP_PARAM_BLK_DR_COMP: Dynamic range compression + * @NEOISP_PARAM_BLK_NR: Noise reduction block + * @NEOISP_PARAM_BLK_AF: Auto focus block + * @NEOISP_PARAM_BLK_EE: Edge enhancement block + * @NEOISP_PARAM_BLK_DF: Direction filter block + * @NEOISP_PARAM_BLK_CONVMED: Convolution and median filter block + * @NEOISP_PARAM_BLK_CAS: Color adaptive saturation block + * @NEOISP_PARAM_BLK_GCM: Gamma correction matrix block + * @NEOISP_PARAM_BLK_VIGNETTING_TABLE: Vignetting lookup table + * @NEOISP_PARAM_BLK_DRC_GLOBAL_TONEMAP: Global tonemap table + * @NEOISP_PARAM_BLK_DRC_LOCAL_TONEMAP: Local tonemap table + */ +enum neoisp_param_block_type_e { + NEOISP_PARAM_BLK_PIPE_CONF, + NEOISP_PARAM_BLK_HEAD_COLOR, + NEOISP_PARAM_BLK_HDR_DECOMPRESS0, + NEOISP_PARAM_BLK_HDR_DECOMPRESS1, + NEOISP_PARAM_BLK_OBWB0, + NEOISP_PARAM_BLK_OBWB1, + NEOISP_PARAM_BLK_OBWB2, + NEOISP_PARAM_BLK_HDR_MERGE, + NEOISP_PARAM_BLK_RGBIR, + NEOISP_PARAM_BLK_STAT, + NEOISP_PARAM_BLK_CTEMP, + NEOISP_PARAM_BLK_IR_COMPRESS, + NEOISP_PARAM_BLK_BNR, + NEOISP_PARAM_BLK_VIGNETTING_CTRL, + NEOISP_PARAM_BLK_DEMOSAIC, + NEOISP_PARAM_BLK_RGB2YUV, + NEOISP_PARAM_BLK_DR_COMP, + NEOISP_PARAM_BLK_NR, + NEOISP_PARAM_BLK_AF, + NEOISP_PARAM_BLK_EE, + NEOISP_PARAM_BLK_DF, + NEOISP_PARAM_BLK_CONVMED, + NEOISP_PARAM_BLK_CAS, + NEOISP_PARAM_BLK_GCM, + NEOISP_PARAM_BLK_VIGNETTING_TABLE, + NEOISP_PARAM_BLK_DRC_GLOBAL_TONEMAP, + NEOISP_PARAM_BLK_DRC_LOCAL_TONEMAP, +}; + +/** + * struct neoisp_pipe_conf_cfg_es - Neoisp extensible params pipeline conf= iguration + * + * Neoisp extensible params block for pipelines alignment configuration. + * Identified by :c:type:`NEOISP_PARAM_BLK_PIPE_CONF`. + * + * @header: The Neoisp extensible parameters header, see + * :c:type:`v4l2_isp_block_header` + * @cfg: Pipeline configuration, see + * :c:type:`neoisp_pipe_conf_cfg_s` + */ +struct neoisp_pipe_conf_cfg_es { + struct v4l2_isp_block_header header; + struct neoisp_pipe_conf_cfg_s cfg; +} __attribute__((aligned(8))); + +/** + * struct neoisp_head_color_cfg_es - Neoisp extensible Head color configur= ation + * + * Neoisp extensible params block for head color configuration. + * Identified by :c:type:`NEOISP_PARAM_BLK_HEAD_COLOR`. + * + * @header: The Neoisp extensible parameters header, see + * :c:type:`v4l2_isp_block_header` + * @cfg: Head color configuration, see + * :c:type:`neoisp_head_color_cfg_s` + */ +struct neoisp_head_color_cfg_es { + struct v4l2_isp_block_header header; + struct neoisp_head_color_cfg_s cfg; +} __attribute__((aligned(8))); + +/** + * struct neoisp_hdr_decompress0_cfg_es - Neoisp extensible HDR Decompress= 0 configuration + * + * Neoisp extensible params block for HDR Decompression configuration of l= ine path 0. + * Identified by :c:type:`NEOISP_PARAM_BLK_HDR_DECOMPRESS0`. + * + * @header: The Neoisp extensible parameters header, see + * :c:type:`v4l2_isp_block_header` + * @cfg: HDR Decompression configuration for line path 0, see + * :c:type:`neoisp_hdr_decompress0_cfg_s` + */ +struct neoisp_hdr_decompress0_cfg_es { + struct v4l2_isp_block_header header; + struct neoisp_hdr_decompress0_cfg_s cfg; +} __attribute__((aligned(8))); + +/** + * struct neoisp_hdr_decompress1_cfg_es - Neoisp extensible HDR Decompress= 1 configuration + * + * Neoisp extensible params block for HDR Decompression configuration of l= ine path 1. + * Identified by :c:type:`NEOISP_PARAM_BLK_HDR_DECOMPRESS1`. + * + * @header: The Neoisp extensible parameters header, see + * :c:type:`v4l2_isp_block_header` + * @cfg: HDR Decompression configuration for line path 1, see + * :c:type:`neoisp_hdr_decompress1_cfg_s` + */ +struct neoisp_hdr_decompress1_cfg_es { + struct v4l2_isp_block_header header; + struct neoisp_hdr_decompress1_cfg_s cfg; +} __attribute__((aligned(8))); + +/** + * struct neoisp_obwb_cfg_es - Neoisp extensible OBWB configuration + * + * Neoisp extensible params block for Optical Black correction and White B= alance + * configuration of the different OBWB instances. + * Identified by :c:type:`NEOISP_PARAM_BLK_OBWB0`, :c:type:`NEOISP_PARAM_B= LK_OBWB1` + * or :c:type:`NEOISP_PARAM_BLK_OBWB2` + * + * @header: The Neoisp extensible parameters header, see + * :c:type:`v4l2_isp_block_header` + * @cfg: Optical Black correction and White Balance configuration, see + * :c:type:`neoisp_obwb_cfg_s` + */ +struct neoisp_obwb_cfg_es { + struct v4l2_isp_block_header header; + struct neoisp_obwb_cfg_s cfg; +} __attribute__((aligned(8))); + +/** + * struct neoisp_hdr_merge_cfg_es - Neoisp extensible HDR merge configurat= ion + * + * Neoisp extensible params block for the HDR merge unit configuration. + * Identified by :c:type:`NEOISP_PARAM_HDR_MERGE`. + * + * @header: The Neoisp extensible parameters header, see + * :c:type:`v4l2_isp_block_header` + * @cfg: HDR merge configuration, see + * :c:type:`neoisp_hdr_merge_cfg_s` + */ +struct neoisp_hdr_merge_cfg_es { + struct v4l2_isp_block_header header; + struct neoisp_hdr_merge_cfg_s cfg; +} __attribute__((aligned(8))); + +/** + * struct neoisp_rgbir_cfg_es - Neoisp extensible RGBIR to RGGB and IR con= figuration + * + * Neoisp extensible params block for the RGBIR to RGGB and IR conversion = unit configuration. + * Identified by :c:type:`NEOISP_PARAM_RGBIR`. + * + * @header: The Neoisp extensible parameters header, see + * :c:type:`v4l2_isp_block_header` + * @cfg: RGBIR to RGGB and IR unit configuration, see + * :c:type:`neoisp_rgbir_cfg_s` + */ +struct neoisp_rgbir_cfg_es { + struct v4l2_isp_block_header header; + struct neoisp_rgbir_cfg_s cfg; +} __attribute__((aligned(8))); + +/** + * struct neoisp_stat_cfg_es - Neoisp extensible Statistics and Histogram = configuration + * + * Neoisp extensible params block for the Statistics and Histogram unit co= nfiguration. + * Identified by :c:type:`NEOISP_PARAM_BLK_STAT`. + * + * @header: The Neoisp extensible parameters header, see + * :c:type:`v4l2_isp_block_header` + * @cfg: Statistics and Histogram unit configuration, see + * :c:type:`neoisp_stat_cfg_s` + */ +struct neoisp_stat_cfg_es { + struct v4l2_isp_block_header header; + struct neoisp_stat_cfg_s cfg; +} __attribute__((aligned(8))); + +/** + * struct neoisp_ir_compress_cfg_es - Neoisp extensible IR Compression con= figuration + * + * Neoisp extensible params block for the Infra-red Compression unit confi= guration. + * Identified by :c:type:`NEOISP_PARAM_BLK_IR_COMP`. + * + * @header: The Neoisp extensible parameters header, see + * :c:type:`v4l2_isp_block_header` + * @cfg: Infra-red Compression configuration, see + * :c:type:`neoisp_ir_compress_cfg_s` + */ +struct neoisp_ir_compress_cfg_es { + struct v4l2_isp_block_header header; + struct neoisp_ir_compress_cfg_s cfg; +} __attribute__((aligned(8))); + +/** + * struct neoisp_bnr_cfg_es - Neoisp extensible BNR configuration + * + * Neoisp extensible params block for the Bayer Noise Reduction unit confi= guration. + * Identified by :c:type:`NEOISP_PARAM_BLK_BNR`. + * + * @header: The Neoisp extensible parameters header, see + * :c:type:`v4l2_isp_block_header` + * @cfg: Bayer Noise Reduction configuration, see + * :c:type:`neoisp_bnr_cfg_s` + */ +struct neoisp_bnr_cfg_es { + struct v4l2_isp_block_header header; + struct neoisp_bnr_cfg_s cfg; +} __attribute__((aligned(8))); + +/** + * struct neoisp_vignetting_ctrl_cfg_es - Neoisp extensible Vignetting con= figuration + * + * Neoisp extensible params block for the Vignetting unit configuration. + * Identified by :c:type:`NEOISP_PARAM_BLK_VIGNETTING_CTRL`. + * + * @header: The Neoisp extensible parameters header, see + * :c:type:`v4l2_isp_block_header` + * @cfg: Vignetting unit configuration, see + * :c:type:`neoisp_vignetting_ctrl_cfg_s` + */ +struct neoisp_vignetting_ctrl_cfg_es { + struct v4l2_isp_block_header header; + struct neoisp_vignetting_ctrl_cfg_s cfg; +} __attribute__((aligned(8))); + +/** + * struct neoisp_ctemp_cfg_es - Neoisp extensible Color Temperature config= uration + * + * Neoisp extensible params block for the Color Temperature unit configura= tion. + * Identified by :c:type:`NEOISP_PARAM_BLK_CTEMP`. + * + * @header: The Neoisp extensible parameters header, see + * :c:type:`v4l2_isp_block_header` + * @cfg: Color Temperature unit configuration, see + * :c:type:`neoisp_ctemp_cfg_s` + */ +struct neoisp_ctemp_cfg_es { + struct v4l2_isp_block_header header; + struct neoisp_ctemp_cfg_s cfg; +} __attribute__((aligned(8))); + +/** + * struct neoisp_demosaic_cfg_es - Neoisp extensible Demosaic configuration + * + * Neoisp extensible params block for the Demosaic unit configuration. + * Identified by :c:type:`NEOISP_PARAM_BLK_DEMOSAIC`. + * + * @header: The Neoisp extensible parameters header, see + * :c:type:`v4l2_isp_block_header` + * @cfg: Demosaic unit configuration, see + * :c:type:`neoisp_demosaic_cfg_s` + */ +struct neoisp_demosaic_cfg_es { + struct v4l2_isp_block_header header; + struct neoisp_demosaic_cfg_s cfg; +} __attribute__((aligned(8))); + +/** + * struct neoisp_rgb2yuv_cfg_es - Neoisp extensible RGB to YUV configurati= on + * + * Neoisp extensible params block for the RGB to YUV color space conversion + * unit configuration. + * Identified by :c:type:`NEOISP_PARAM_BLK_RGB2YUV`. + * + * @header: The Neoisp extensible parameters header, see + * :c:type:`v4l2_isp_block_header` + * @cfg: Color space conversion unit configuration, see + * :c:type:`neoisp_rgb2yuv_cfg_s` + */ +struct neoisp_rgb2yuv_cfg_es { + struct v4l2_isp_block_header header; + struct neoisp_rgb2yuv_cfg_s cfg; +} __attribute__((aligned(8))); + +/** + * struct neoisp_dr_comp_cfg_es - Neoisp extensible DRC unit configuration + * + * Neoisp extensible params block for the Dynamic Range Compression unit c= onfiguration. + * Identified by :c:type:`NEOISP_PARAM_BLK_DR_COMP`. + * + * @header: The Neoisp extensible parameters header, see + * :c:type:`v4l2_isp_block_header` + * @cfg: Dynamic Range Compression unit configuration, see + * :c:type:`neoisp_dr_comp_cfg_s` + */ +struct neoisp_dr_comp_cfg_es { + struct v4l2_isp_block_header header; + struct neoisp_dr_comp_cfg_s cfg; +} __attribute__((aligned(8))); + +/** + * struct neoisp_nr_cfg_es - Neoisp extensible NR unit configuration + * + * Neoisp extensible params block for the Noise Reduction unit configurati= on. + * Identified by :c:type:`NEOISP_PARAM_BLK_NR`. + * + * @header: The Neoisp extensible parameters header, see + * :c:type:`v4l2_isp_block_header` + * @cfg: Noise Reduction unit configuration, see + * :c:type:`neoisp_nr_cfg_s` + */ +struct neoisp_nr_cfg_es { + struct v4l2_isp_block_header header; + struct neoisp_nr_cfg_s cfg; +} __attribute__((aligned(8))); + +/** + * struct neoisp_af_cfg_es - Neoisp extensible AutoFocus unit configuration + * + * Neoisp extensible params block for the AutoFocus unit configuration. + * Identified by :c:type:`NEOISP_PARAM_BLK_AF`. + * + * @header: The Neoisp extensible parameters header, see + * :c:type:`v4l2_isp_block_header` + * @cfg: AutoFocus unit configuration, see + * :c:type:`neoisp_af_cfg_s` + */ +struct neoisp_af_cfg_es { + struct v4l2_isp_block_header header; + struct neoisp_af_cfg_s cfg; +} __attribute__((aligned(8))); + +/** + * struct neoisp_ee_cfg_es - Neoisp extensible Edge Enhancement unit confi= guration + * + * Neoisp extensible params block for the Edge Enhancement unit configurat= ion. + * Identified by :c:type:`NEOISP_PARAM_BLK_EE`. + * + * @header: The Neoisp extensible parameters header, see + * :c:type:`v4l2_isp_block_header` + * @cfg: Edge Enhancement unit configuration, see + * :c:type:`neoisp_ee_cfg_s` + */ +struct neoisp_ee_cfg_es { + struct v4l2_isp_block_header header; + struct neoisp_ee_cfg_s cfg; +} __attribute__((aligned(8))); + +/** + * struct neoisp_df_cfg_es - Neoisp extensible Direction Filter configurat= ion + * + * Neoisp extensible params block for the Direction Filter unit configurat= ion. + * Identified by :c:type:`NEOISP_PARAM_BLK_DF`. + * + * @header: The Neoisp extensible parameters header, see + * :c:type:`v4l2_isp_block_header` + * @cfg: Direction Filter configuration, see + * :c:type:`neoisp_df_cfg_s` + */ +struct neoisp_df_cfg_es { + struct v4l2_isp_block_header header; + struct neoisp_df_cfg_s cfg; +} __attribute__((aligned(8))); + +/** + * struct neoisp_convmed_cfg_es - Neoisp extensible Convmed configuration + * + * Neoisp extensible params block for the Color Convolution and Median Fil= ter + * unit configuration. + * Identified by :c:type:`NEOISP_PARAM_BLK_CONVMED`. + * + * @header: The Neoisp extensible parameters header, see + * :c:type:`v4l2_isp_block_header` + * @cfg: Color Convolution and Median Filter unit configuration, see + * :c:type:`neoisp_convmed_cfg_s` + */ +struct neoisp_convmed_cfg_es { + struct v4l2_isp_block_header header; + struct neoisp_convmed_cfg_s cfg; +} __attribute__((aligned(8))); + +/** + * struct neoisp_cas_cfg_es - Neoisp extensible CAS configuration + * + * Neoisp extensible params block for the Color Adaptive Saturation unit c= onfiguration. + * Identified by :c:type:`NEOISP_PARAM_BLK_CAS`. + * + * @header: The Neoisp extensible parameters header, see + * :c:type:`v4l2_isp_block_header` + * @cfg: Color Adaptive Saturation unit configuration, see + * :c:type:`neoisp_cas_cfg_s` + */ +struct neoisp_cas_cfg_es { + struct v4l2_isp_block_header header; + struct neoisp_cas_cfg_s cfg; +} __attribute__((aligned(8))); + +/** + * struct neoisp_gcm_cfg_es - Neoisp extensible GCM configuration + * + * Neoisp extensible params block for the Gamma Correction matrix unit con= figuration. + * Identified by :c:type:`NEOISP_PARAM_BLK_GCM`. + * + * @header: The Neoisp extensible parameters header, see + * :c:type:`v4l2_isp_block_header` + * @cfg: Gamma Correction Matrix configuration, see + * :c:type:`neoisp_gcm_cfg_s` + */ +struct neoisp_gcm_cfg_es { + struct v4l2_isp_block_header header; + struct neoisp_gcm_cfg_s cfg; +} __attribute__((aligned(8))); + +/** + * struct neoisp_vignetting_table_mem_params_es - Neoisp extensible Vignet= ting LUT configuration + * + * Neoisp extensible params block for the Vignetting look up table configu= ration. + * Identified by :c:type:`NEOISP_PARAM_BLK_VIGNETTING_TABLE`. + * + * @header: The Neoisp extensible parameters header, see + * :c:type:`v4l2_isp_block_header` + * @cfg: Vignetting LUT configuration, see + * :c:type:`neoisp_vignetting_table_mem_params_s` + */ +struct neoisp_vignetting_table_mem_params_es { + struct v4l2_isp_block_header header; + struct neoisp_vignetting_table_mem_params_s cfg; +} __attribute__((aligned(8))); + +/** + * struct neoisp_drc_global_tonemap_mem_params_es - Neoisp extensible DRC = Global Tonemap LUT + * configuration + * + * Neoisp extensible params block for the DRC Global Tonemap look up table= configuration. + * Identified by :c:type:`NEOISP_PARAM_BLK_DRC_GLOBAL_TONEMAP`. + * + * @header: The Neoisp extensible parameters header, see + * :c:type:`v4l2_isp_block_header` + * @cfg: DRC Global Tonemap LUT configuration, see + * :c:type:`neoisp_drc_global_tonemap_mem_params_s` + */ +struct neoisp_drc_global_tonemap_mem_params_es { + struct v4l2_isp_block_header header; + struct neoisp_drc_global_tonemap_mem_params_s cfg; +} __attribute__((aligned(8))); + +/** + * struct neoisp_drc_local_tonemap_mem_params_es - Neoisp extensible DRC L= ocal Tonemap LUT + * configuration + * + * Neoisp extensible params block for the DRC Local Tonemap look up table = configuration. + * Identified by :c:type:`NEOISP_PARAM_BLK_DRC_LOCAL_TONEMAP`. + * + * @header: The Neoisp extensible parameters header, see + * :c:type:`v4l2_isp_block_header` + * @cfg: DRC Local tonemap LUT configuration, see + * :c:type:`neoisp_drc_local_tonemap_mem_params_s` + */ +struct neoisp_drc_local_tonemap_mem_params_es { + struct v4l2_isp_block_header header; + struct neoisp_drc_local_tonemap_mem_params_s cfg; +} __attribute__((aligned(8))); + +/** + * define NEOISP_EXT_PARAMS_MAX_SIZE - Maximum size of all Neoisp Paramete= rs + * + * Though the parameters for the Neoisp are passed as optional blocks, the + * driver still needs to know the absolute maximum size so that it can all= ocate + * a buffer sized appropriately to accommodate userspace attempting to set= all + * possible parameters in a single frame. + * + * Some structs are in this list multiple times. Where that's the case, it= just + * reflects the fact that the same struct can be used with multiple differ= ent + * header types from :c:type:`neoisp_param_block_type_e`. + */ +#define NEOISP_EXT_PARAMS_MAX_SIZE \ + (sizeof(struct neoisp_pipe_conf_cfg_es) + \ + sizeof(struct neoisp_head_color_cfg_es) + \ + sizeof(struct neoisp_hdr_decompress0_cfg_es) + \ + sizeof(struct neoisp_hdr_decompress1_cfg_es) + \ + (sizeof(struct neoisp_obwb_cfg_es) * NEO_OBWB_CNT) + \ + sizeof(struct neoisp_hdr_merge_cfg_es) + \ + sizeof(struct neoisp_rgbir_cfg_es) + \ + sizeof(struct neoisp_ctemp_cfg_es) + \ + sizeof(struct neoisp_stat_cfg_es) + \ + sizeof(struct neoisp_ir_compress_cfg_es) + \ + sizeof(struct neoisp_bnr_cfg_es) + \ + sizeof(struct neoisp_vignetting_ctrl_cfg_es) + \ + sizeof(struct neoisp_demosaic_cfg_es) + \ + sizeof(struct neoisp_rgb2yuv_cfg_es) + \ + sizeof(struct neoisp_dr_comp_cfg_es) + \ + sizeof(struct neoisp_nr_cfg_es) + \ + sizeof(struct neoisp_af_cfg_es) + \ + sizeof(struct neoisp_ee_cfg_es) + \ + sizeof(struct neoisp_df_cfg_es) + \ + sizeof(struct neoisp_convmed_cfg_es) + \ + sizeof(struct neoisp_cas_cfg_es) + \ + sizeof(struct neoisp_gcm_cfg_es) + \ + sizeof(struct neoisp_vignetting_table_mem_params_es) + \ + sizeof(struct neoisp_drc_global_tonemap_mem_params_es) + \ + sizeof(struct neoisp_drc_local_tonemap_mem_params_es)) + +/* + * Statistics + */ +#define NEO_CTEMP_REG_STATS_CROIS_CNT (10) +#define NEO_AF_REG_STATS_ROIS_CNT (9) + +/** + * struct neoisp_reg_stats_crois_s - Color region of interest + * @pixcnt_pixcnt: Pixel count saturates once it reaches all 1s + * @sumred_sum: Accumulated red value of total number + * @sumgreen_sum: Accumulated green value of total number + * @sumblue_sum: Accumulated blue value of total number + */ +struct neoisp_reg_stats_crois_s { + __u32 pixcnt_pixcnt; + __u32 sumred_sum; + __u32 sumgreen_sum; + __u32 sumblue_sum; +}; + +/** + * struct neoisp_ctemp_reg_stats_s - Color Temperature statistics located = in registers + * @cnt_white_white: Number of white pixels + * @sumr_sum_l: Lower 32-bits of accumulated value of the red channel + * @sumr_sum_h: Higher 32-bits of accumulated value of the red channel + * @sumg_sum_l: Lower 32-bits of accumulated value of the green channel + * @sumg_sum_h: Higher 32-bits of accumulated value of the green channel + * @sumb_sum_l: Lower 32-bits of accumulated value of the blue channel + * @sumb_sum_h: Higher 32-bits of accumulated value of the blue channel + * @sumrg_sum_l: Lower 32-bits of accumulated red over green gain + * @sumrg_sum_h: Higher 32-bits of accumulated red over green gain + * @sumbg_sum_l: Lower 32-bits of accumulated blue over green gain + * @sumbg_sum_h: Higher 32-bits of accumulated blue over green gain + * @crois: Color regions of interest + * @gr_gb_cnt_cnt: Number of counted pixels in the gr vs gb sums + * @gr_sum_sum: Sum of counted GR values (msb: 27 bits mantissa, lsb: 5 b= its exponent) + * @gb_sum_sum: Sum of counted GB values (msb: 27 bits mantissa, lsb: 5 b= its exponent) + * @gr2_sum_sum: Sum of squared GR values (msb: 27 bits mantissa, lsb: 5 b= its exponent) + * @gb2_sum_sum: Sum of squared GB values (msb: 27 bits mantissa, lsb: 5 b= its exponent) + * @pad: Pad two word for alignment + * @grgb_sum_sum: Sum of GR*GB values (msb: 27 bits mantissa, lsb: 5 bits = exponent) + */ +struct neoisp_ctemp_reg_stats_s { + __u32 cnt_white_white; + __u32 sumr_sum_l; /* split low and high to avoid padding and keep aligned= with hw */ + __u32 sumr_sum_h; + __u32 sumg_sum_l; + __u32 sumg_sum_h; + __u32 sumb_sum_l; + __u32 sumb_sum_h; + __u32 sumrg_sum_l; + __u32 sumrg_sum_h; + __u32 sumbg_sum_l; + __u32 sumbg_sum_h; + struct neoisp_reg_stats_crois_s crois[NEO_CTEMP_REG_STATS_CROIS_CNT]; + __u32 gr_gb_cnt_cnt; + __u32 gr_sum_sum; + __u32 gb_sum_sum; + __u32 gr2_sum_sum; + __u32 gb2_sum_sum; + __u32 pad[2]; + __u32 grgb_sum_sum; +}; + +/** + * struct neoisp_drc_reg_stats_s - Dynamic Range Compression statistics + * @groi0_sum_val: Sum of pixels within the global region of interest 0 + * @groi1_sum_val: Sum of pixels within the global region of interest 1 + */ +struct neoisp_drc_reg_stats_s { + __u32 groi0_sum_val; + __u32 groi1_sum_val; +}; + +/** + * struct neoisp_af_reg_stats_sums_s - common Auto Focus sum registers pair + * @sum0: Provides the 32-bit accumulated value for filter 0 for a ROI + * @sum1: Provides the 32-bit accumulated value for filter 1 for a ROI + */ +struct neoisp_af_reg_stats_sums_s { + __u32 sum0; + __u32 sum1; +}; + +/** + * struct neoisp_af_reg_stats_s - Auto Focus statistics + * @rois: Array of filters 0 and 1 sums for each ROI + */ +struct neoisp_af_reg_stats_s { + struct neoisp_af_reg_stats_sums_s rois[NEO_AF_REG_STATS_ROIS_CNT]; +}; + +/** + * struct neoisp_bnr_reg_stats_s - Bayer Noise Reduction statistics + * @edge_stat_edge_pixels: Number of edge pixels that are above the L thre= shold (u24) + * @edges_stat_edge_pixels: Number of edge pixels that are above the S thr= eshold (u24) + */ +struct neoisp_bnr_reg_stats_s { + __u32 edge_stat_edge_pixels; + __u32 edges_stat_edge_pixels; +}; + +/** + * struct neoisp_nr_reg_stats_s - Noise Reduction statistics + * @edgecnt_val: Number of filtered pixels for respective camera context (= u24) + */ +struct neoisp_nr_reg_stats_s { + __u32 edgecnt_val; +}; + +/** + * struct neoisp_ee_reg_stats_s - Edge enhancement statistics + * @edgecnt_val: Number of filtered pixels for respective camera context (= u24) + */ +struct neoisp_ee_reg_stats_s { + __u32 edgecnt_val; +}; + +/** + * struct neoisp_df_reg_stats_s - Direction Filter statistics + * @edgecnt_val: Number of filtered pixels for respective camera context (= u24) + */ +struct neoisp_df_reg_stats_s { + __u32 edgecnt_val; +}; + +/** + * struct neoisp_ctemp_mem_stats_s - Color Temperature statistics located = in memory + * @ctemp_r_sum: Array of red sums + * @ctemp_g_sum: Array of green sums + * @ctemp_b_sum: Array of blue sums + * @ctemp_pix_cnt: Array of pixel counts + */ +struct neoisp_ctemp_mem_stats_s { + __u32 ctemp_r_sum[NEO_CTEMP_R_SUM_CNT]; + __u32 ctemp_g_sum[NEO_CTEMP_G_SUM_CNT]; + __u32 ctemp_b_sum[NEO_CTEMP_B_SUM_CNT]; + __u16 ctemp_pix_cnt[NEO_CTEMP_PIX_CNT_CNT]; +}; + +/** + * struct neoisp_rgbir_mem_stats_s - RGBIR statistics located in memory + * @rgbir_hist: Rgbir histograms + */ +struct neoisp_rgbir_mem_stats_s { + __u32 rgbir_hist[NEO_RGBIR_HIST_CNT]; +}; + +/** + * struct neoisp_hist_mem_stats_s - Histograms located in memory + * @hist_stat: Array of histograms and statistics + */ +struct neoisp_hist_mem_stats_s { + __u32 hist_stat[NEO_HIST_STAT_CNT]; +}; + +/** + * struct neoisp_drc_mem_stats_s - DRC statistics located in memory + * @drc_local_sum: DRC local sums array + * @drc_global_hist_roi0: DRC global histogram fir region of interest 0 + * @drc_global_hist_roi1: DRC global histogram fir region of interest 1 + */ +struct neoisp_drc_mem_stats_s { + __u32 drc_local_sum[NEO_DRC_LOCAL_SUM_CNT]; + __u32 drc_global_hist_roi0[NEO_DRC_GLOBAL_HIST_ROI_CNT]; + __u32 drc_global_hist_roi1[NEO_DRC_GLOBAL_HIST_ROI_CNT]; +}; + +/** + * enum neoisp_stats_block_type_e - Enumeration of Neoisp statistics blocks + * + * This enumeration defines the types of Neoisp statistics block. Each ent= ry + * contains statistics specific to a processing block of the Neoisp. The b= lock + * type allows the driver to correctly interpret the statistics block data. + * + * It is driver responsability to correctly set the type of each statistic= s block. + * + * @NEOISP_STATS_BLK_RCTEMP: Color Temperature statistics registers + * @NEOISP_STATS_BLK_RDRC: Dynamic Range Compression statistics registers + * @NEOISP_STATS_BLK_RAF: Auto Focus statistics registers + * @NEOISP_STATS_BLK_RBNR: Bayer Noise Reduction statistics registers + * @NEOISP_STATS_BLK_RNR: Noise Reduction statistics registers + * @NEOISP_STATS_BLK_REE: Edge enhancement statistics + * @NEOISP_STATS_BLK_RDF: Direction Filter statistics registers + * @NEOISP_STATS_BLK_MCTEMP: Color Temperature statistics memories + * @NEOISP_STATS_BLK_MRGBIR: RGBIR statistics memories + * @NEOISP_STATS_BLK_MHIST: Histograms statistics memories + * @NEOISP_STATS_BLK_MDRC: DRC statistics memories + */ +enum neoisp_stats_block_type_e { + NEOISP_STATS_BLK_RCTEMP, + NEOISP_STATS_BLK_RDRC, + NEOISP_STATS_BLK_RAF, + NEOISP_STATS_BLK_RBNR, + NEOISP_STATS_BLK_RNR, + NEOISP_STATS_BLK_REE, + NEOISP_STATS_BLK_RDF, + NEOISP_STATS_BLK_MCTEMP, + NEOISP_STATS_BLK_MRGBIR, + NEOISP_STATS_BLK_MHIST, + NEOISP_STATS_BLK_MDRC, +}; + +/** + * struct neoisp_ctemp_reg_stats_es - Neoisp extensible pipeline configura= tion + * + * Neoisp extensible pipelines alignment configuration block. + * Identified by :c:type:`NEOISP_STATS_BLK_RCTEMP`. + * + * @header: The Neoisp extensible statistics header, see + * :c:type:`v4l2_isp_block_header` + * @stat: Pipeline configuration, see + * :c:type:`neoisp_ctemp_reg_stats_s` + */ +struct neoisp_ctemp_reg_stats_es { + struct v4l2_isp_block_header header; + struct neoisp_ctemp_reg_stats_s stat; +} __attribute__((aligned(8))); + +/** + * struct neoisp_drc_reg_stats_es - Neoisp extensible pipeline configurati= on + * + * Neoisp extensible pipelines alignment configuration block. + * Identified by :c:type:`NEOISP_STATS_BLK_RDRC`. + * + * @header: The Neoisp extensible statistics header, see + * :c:type:`v4l2_isp_block_header` + * @stat: Pipeline configuration, see + * :c:type:`neoisp_drc_reg_stats_s` + */ +struct neoisp_drc_reg_stats_es { + struct v4l2_isp_block_header header; + struct neoisp_drc_reg_stats_s stat; +} __attribute__((aligned(8))); + +/** + * struct neoisp_af_reg_stats_es - Neoisp extensible pipeline configuration + * + * Neoisp extensible pipelines alignment configuration block. + * Identified by :c:type:`NEOISP_STATS_BLK_RAF`. + * + * @header: The Neoisp extensible statistics header, see + * :c:type:`v4l2_isp_block_header` + * @stat: Pipeline configuration, see + * :c:type:`neoisp_af_reg_stats_s` + */ +struct neoisp_af_reg_stats_es { + struct v4l2_isp_block_header header; + struct neoisp_af_reg_stats_s stat; +} __attribute__((aligned(8))); + +/** + * struct neoisp_bnr_reg_stats_es - Neoisp extensible pipeline configurati= on + * + * Neoisp extensible pipelines alignment configuration block. + * Identified by :c:type:`NEOISP_STATS_BLK_RBNR`. + * + * @header: The Neoisp extensible statistics header, see + * :c:type:`v4l2_isp_block_header` + * @stat: Pipeline configuration, see + * :c:type:`neoisp_bnr_reg_stats_s` + */ +struct neoisp_bnr_reg_stats_es { + struct v4l2_isp_block_header header; + struct neoisp_bnr_reg_stats_s stat; +} __attribute__((aligned(8))); + +/** + * struct neoisp_nr_reg_stats_es - Neoisp extensible pipeline configuration + * + * Neoisp extensible pipelines alignment configuration block. + * Identified by :c:type:`NEOISP_STATS_BLK_RNR`. + * + * @header: The Neoisp extensible statistics header, see + * :c:type:`v4l2_isp_block_header` + * @stat: Pipeline configuration, see + * :c:type:`neoisp_nr_reg_stats_s` + */ +struct neoisp_nr_reg_stats_es { + struct v4l2_isp_block_header header; + struct neoisp_nr_reg_stats_s stat; +} __attribute__((aligned(8))); + +/** + * struct neoisp_ee_reg_stats_es - Neoisp extensible pipeline configuration + * + * Neoisp extensible pipelines alignment configuration block. + * Identified by :c:type:`NEOISP_STATS_BLK_REE`. + * + * @header: The Neoisp extensible statistics header, see + * :c:type:`v4l2_isp_block_header` + * @stat: Pipeline configuration, see + * :c:type:`neoisp_ee_reg_stats_s` + */ +struct neoisp_ee_reg_stats_es { + struct v4l2_isp_block_header header; + struct neoisp_ee_reg_stats_s stat; +} __attribute__((aligned(8))); + +/** + * struct neoisp_df_reg_stats_es - Neoisp extensible pipeline configuration + * + * Neoisp extensible pipelines alignment configuration block. + * Identified by :c:type:`NEOISP_STATS_BLK_RDF`. + * + * @header: The Neoisp extensible statistics header, see + * :c:type:`v4l2_isp_block_header` + * @stat: Pipeline configuration, see + * :c:type:`neoisp_df_reg_stats_s` + */ +struct neoisp_df_reg_stats_es { + struct v4l2_isp_block_header header; + struct neoisp_df_reg_stats_s stat; +} __attribute__((aligned(8))); + +/** + * struct neoisp_ctemp_mem_stats_es - Neoisp extensible pipeline configura= tion + * + * Neoisp extensible pipelines alignment configuration block. + * Identified by :c:type:`NEOISP_STATS_BLK_MCTEMP`. + * + * @header: The Neoisp extensible statistics header, see + * :c:type:`v4l2_isp_block_header` + * @stat: Pipeline configuration, see + * :c:type:`neoisp_ctemp_mem_stats_s` + */ +struct neoisp_ctemp_mem_stats_es { + struct v4l2_isp_block_header header; + struct neoisp_ctemp_mem_stats_s stat; +} __attribute__((aligned(8))); + +/** + * struct neoisp_rgbir_mem_stats_es - Neoisp extensible pipeline configura= tion + * + * Neoisp extensible pipelines alignment configuration block. + * Identified by :c:type:`NEOISP_STATS_BLK_MRGBIR`. + * + * @header: The Neoisp extensible statistics header, see + * :c:type:`v4l2_isp_block_header` + * @stat: Pipeline configuration, see + * :c:type:`neoisp_rgbir_mem_stats_s` + */ +struct neoisp_rgbir_mem_stats_es { + struct v4l2_isp_block_header header; + struct neoisp_rgbir_mem_stats_s stat; +} __attribute__((aligned(8))); + +/** + * struct neoisp_hist_mem_stats_es - Neoisp extensible pipeline configurat= ion + * + * Neoisp extensible pipelines alignment configuration block. + * Identified by :c:type:`NEOISP_STATS_BLK_MHIST`. + * + * @header: The Neoisp extensible statistics header, see + * :c:type:`v4l2_isp_block_header` + * @stat: Pipeline configuration, see + * :c:type:`neoisp_hist_mem_stats_s` + */ +struct neoisp_hist_mem_stats_es { + struct v4l2_isp_block_header header; + struct neoisp_hist_mem_stats_s stat; +} __attribute__((aligned(8))); + +/** + * struct neoisp_drc_mem_stats_es - Neoisp extensible pipeline configurati= on + * + * Neoisp extensible pipelines alignment configuration block. + * Identified by :c:type:`NEOISP_STATS_BLK_MDRC`. + * + * @header: The Neoisp extensible statistics header, see + * :c:type:`v4l2_isp_block_header` + * @stat: Pipeline configuration, see + * :c:type:`neoisp_drc_mem_stats_s` + */ +struct neoisp_drc_mem_stats_es { + struct v4l2_isp_block_header header; + struct neoisp_drc_mem_stats_s stat; +} __attribute__((aligned(8))); + +/** + * define NEOISP_EXT_STATS_MAX_SIZE - Maximum size of all Neoisp Statistics + * + * Though the statistics of the Neoisp are passed as optional blocks, the + * userspace still needs to know the absolute maximum size so that it can + * allocate a buffer sized appropriately to accommodate driver attempting = to + * set all possible statistics in a single frame. + */ +#define NEOISP_EXT_STATS_MAX_SIZE \ + (sizeof(struct neoisp_ctemp_reg_stats_es) + \ + sizeof(struct neoisp_drc_reg_stats_es) + \ + sizeof(struct neoisp_af_reg_stats_es) + \ + sizeof(struct neoisp_bnr_reg_stats_es) + \ + sizeof(struct neoisp_nr_reg_stats_es) + \ + sizeof(struct neoisp_ee_reg_stats_es) + \ + sizeof(struct neoisp_df_reg_stats_es) + \ + sizeof(struct neoisp_ctemp_mem_stats_es) + \ + sizeof(struct neoisp_rgbir_mem_stats_es) + \ + sizeof(struct neoisp_hist_mem_stats_es) + \ + sizeof(struct neoisp_drc_mem_stats_es)) + +#endif /* __UAPI_NXP_NEOISP_H */ --=20 2.53.0 From nobody Sat Jun 13 02:07:57 2026 Received: from AS8PR04CU009.outbound.protection.outlook.com (mail-westeuropeazon11011050.outbound.protection.outlook.com [52.101.70.50]) (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 A60193EDAD5; Fri, 12 Jun 2026 13:21:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.70.50 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781270464; cv=fail; b=pEz46CRMvnF5R/RqJtHfSCYUthBrI7nYBKg84X6mk9sfQnfuflXpklytThRGyqi7469mob4/wqrPnXQuZFwBX8YCpkW1cdp8zWpIXF4w5/WUe61VHv6fexrzX0TUMEg03nSRZBSqcHJT+5Tp+wt6MZGnCiZuDrPkEKWQ61yty5Y= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781270464; c=relaxed/simple; bh=jxJ2Urjr1Gqy5nBVn+PubBSEb1SeEuU5gxubmvePbbA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=oO8iIILilvYC8rx2tP+yGaWixRFWGBawZjJhvl2jH7/52PTXWX6rC4fiB60HDmUIAf9R7ELeOwOLhVXCnljyqPx9Ilz9s9BkJgVsZW/x0nnfFtTKy0szOH8AEPEsdqGBmEKKQ+QkDPAGypXtl54tSKuqkRSm+UU0wAuwknmLDPQ= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com; spf=pass smtp.mailfrom=nxp.com; dkim=pass (2048-bit key) header.d=nxp.com header.i=@nxp.com header.b=YGXrvbyh; arc=fail smtp.client-ip=52.101.70.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nxp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nxp.com header.i=@nxp.com header.b="YGXrvbyh" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=nDFrrh0SfCS1HHdXlajlVheNp9ntYS/BiFPmIAaJPzx8/+S32cTOI7MzAdrLHlnSom4OhT4EpIoF3r96pskGSJXBs5SpZWPKiZsF0tpXWpHIUJiqRQy8L5qwqE9banyYFw5yaqloXCY9GOI+Fy0qDzrt3tkfI0oiQ/B9+V/VqJPNAaloiU6hKmEnhjTDAbTOvlaU97VEVkVzRz5OMjIMkhwrBTePTYmFj85SPItx2AbzXJf7trfliO2pc81p9Xbm+k4C2w5Bg55CgznGXJu0yQA/6VM+hGCjN/Dy847LHeiZBG32v5h92mSViQQyWpHGb1qUC9KXhzMqLtG3iiOL0g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=UdPWwS328qxBWsvVz5I1WqQPinMJqRJVHV18w5JPFug=; b=je/2p/N5Gi/Ru/jx+q796VGZWGWdHeHwYvQeJbSklUOd7DmCAcJ6gN9M7HL4qb5OZz/eY+jCNm4h3FmUGZlbeULf+jdNyR/d5l1BRwlujSo4/coZBK2A3qtRdTxIIjyQPS6z1+X/wQg5NOvJBTtLpADbsblO96sWZjhu2VNpeYQoTf4BsfTHD7GIYv6xuaEXLHZlS12kIyV+rCqPAMnpkwWFOrbWEcT3+k+DKfj6v3jqk/m0h6rWYXa6aN4I4+8IRyOp7WmNV4oRFvwROMX9fPezZlIKM992Ptc3QLW2+hecqdx6/B3+VflCbyQLTOJpoXDvR6KocsYZHNSQrG3NmA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nxp.com; dmarc=pass action=none header.from=nxp.com; dkim=pass header.d=nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=UdPWwS328qxBWsvVz5I1WqQPinMJqRJVHV18w5JPFug=; b=YGXrvbyhpBOwEICuV7/AbNjKq+P6FR4uy9AhHgURSN+k0C+aVd+gAZVX3tKaylBBw9dLRgb2fY/avSjzOPAUG/BE/z6RWXxfoEx8CMjpRgHh4WrBTge5rH9QTqTMmbzGdFuuo4exGhasCzefP8ISm1Iqc1/JX7w18wLuEA7Esvn1COJxaMQE9y5haU7SgBIL6QwS5aAguwv8chSsI2WWSnmNTJvp2aSUDOrOGB518POzmkiAaP5pTlRSEGmdhYPvDXtkocyDUql3QAdb6bDf5Jvo4QByL5uKrU39xKhM8/8XG382r3xCRwZSrMT6NKpHkKhwVZCyJZ4FXe87T5jPuQ== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from PA6PR04MB11910.eurprd04.prod.outlook.com (2603:10a6:102:516::16) by DB9PR04MB8203.eurprd04.prod.outlook.com (2603:10a6:10:242::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.113.14; Fri, 12 Jun 2026 13:20:56 +0000 Received: from PA6PR04MB11910.eurprd04.prod.outlook.com ([fe80::d3f0:3c24:f717:4989]) by PA6PR04MB11910.eurprd04.prod.outlook.com ([fe80::d3f0:3c24:f717:4989%4]) with mapi id 15.21.0113.013; Fri, 12 Jun 2026 13:20:56 +0000 From: Antoine Bouyer To: julien.vuillaumier@nxp.com, alexi.birlinger@nxp.com, daniel.baluta@nxp.com, peng.fan@nxp.com, frank.li@nxp.com, jacopo.mondi@ideasonboard.com, laurent.pinchart@ideasonboard.com, mchehab@kernel.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, michael.riesch@collabora.com, anthony.mcgivern@arm.com Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, imx@lists.linux.dev, ai.luthra@ideasonboard.com, paul.elder@ideasonboard.com, geert@linux-m68k.org, sakari.ailus@linux.intel.com, hverkuil+cisco@kernel.org, Antoine Bouyer Subject: [PATCH v3 5/8] media: Documentation: Add NXP neoisp driver documentation Date: Fri, 12 Jun 2026 15:20:36 +0200 Message-ID: <20260612132039.2089051-6-antoine.bouyer@nxp.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260612132039.2089051-1-antoine.bouyer@nxp.com> References: <20260612132039.2089051-1-antoine.bouyer@nxp.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: FR4P281CA0117.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:bb::6) To PA6PR04MB11910.eurprd04.prod.outlook.com (2603:10a6:102:516::16) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PA6PR04MB11910:EE_|DB9PR04MB8203:EE_ X-MS-Office365-Filtering-Correlation-Id: 0f0139ad-c107-4424-462f-08dec8856f62 X-LD-Processed: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635,ExtAddr X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|19092799006|376014|7416014|366016|23010399003|8126099003|921020|6133799003|18002099003|22082099003|3023799007|11063799006|56012099006; X-Microsoft-Antispam-Message-Info: 3TaeGK3rPD/pya+R4Oxyxpihmqhu5zALEQwUSTxE2d7pEzbThQIKgSPzSZfGgKrmoS5xFa9s4VsqxDF13CE0Gw2TU2OVTgMNw2Brx0Oxgr7zBl9LXZnKmbDwHKdoHrScH/2duZgqIocNi297ImALi5p1/nnkdRFXlzzWGicswpTCUNkAj64VfleAyELUaxs7LMZiGG51v33cYdJCK9m2VPUllzo5rPbwQVYpmKx8Cw9WXKJ7UduEhm7INLYtMlpZBZ8uPDlWD2jwaWbgaaXVtzyg+ZCosCaRtSPRiVpm4v8wRBi52jHJzclI5Szs2Q19wtgnbdQZ8x8V8TUD1yGEEuoqcBkuYIrJtiHqmpJw7xoEfJzr9VwcEB+/aKKU8aKjMKLVB+86VBntAhY6JbutOvtx/S7bMYCmUtvCir488sgJU8YUS0MhfLJiDrkKohm4uPhrP6Qy5e2X71iKmv3WPeNWs0lkEZi41D+Ki5BDizkt5MhQ9MmRrDvihF89riUGRQQVtjb2+R6L5rSebwpU2eFD5Nirx/eWxhQDv/LTzd/x53z45FFMYCncyY885SvGHaf+Bd035ktTFhujcL5DCLqBzOzbU6Apj3sCjRPAtrzkgiLF96ZYoo012+6cZL/zaayoAT2fVhE2PeNTOp4wxLvkKyOf7qkd0fer1DJ21bIcQJE4RW4E+SiUQYY12unWw7JHYGWojtHwuFzTGtm5rsdD2cPTS2QN7rkqbWfIIDc= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PA6PR04MB11910.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(1800799024)(19092799006)(376014)(7416014)(366016)(23010399003)(8126099003)(921020)(6133799003)(18002099003)(22082099003)(3023799007)(11063799006)(56012099006);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?WA2MnUS+Ut4whM0uUtTkAnOPF2gHTyHvNu/Sr+xFMNJpJpVFddhMTdYq/ykA?= =?us-ascii?Q?xl40Vcv3HucuqlVaUfG8ELIn/ogFu9HXZNC3x/iqc+GEUkd+41yGSnG6z3hV?= =?us-ascii?Q?KpQ3W1c1YLTbZkfkGMBG1R4PqA5i/34V/8Uwy+T474xFKci2duM6SguTd+J/?= =?us-ascii?Q?bo477pEkIPwLmSl7nFyEgaSHm4UTXQDzokBnvbadKB0rSRZ/YF0VZ36OUuta?= =?us-ascii?Q?mWTT1sZFszM1RQMBZTHTnW95ODhHIm2ovUe7uitFCy+eQJonLGnGmhRXLCAB?= =?us-ascii?Q?ORgMfVR/C+YlcwuNfEEQJl51iGituPycS3uPbGxcR39bPtu0XO8irI2p+3Cf?= =?us-ascii?Q?4XoR4Srql6PTX4XC7zr8I/5gNRAZ94Pq40Eg1aNXiG1RBoC9Dy6j9ofkeEkK?= =?us-ascii?Q?gO+h/dkDgehb4M18NqBVsQt/0Nls1ronnKM/tJTSA1RWi/fynQJVbMUCdYJB?= =?us-ascii?Q?4A+gTE6G5Pjcow3oodSE5C0WUyLLV/29Xzm0veHDzhBoHeU92cngNXbIQEWl?= =?us-ascii?Q?mYtx56i3dzsJ5af7KZoxst+DhLC7FcQHDMRMhjWo5GYP7DJyWv7MWPcsSS0G?= =?us-ascii?Q?/npkxuJyxsaa3oZzKpI8DXlreR6+42lZ28CCuJpMM7cortime3BU7610S799?= =?us-ascii?Q?0yn6B0IxBlAvtnuYvG+vWYPQFaM5lYkd0qLBLnJCw0jcxfpQ894C0YdwIzis?= =?us-ascii?Q?IGA/x7VHfQVMe2LA9GZm3CPdONLCuUhBHwWG1Atfo7nusUIWlyH5fsFkQqK/?= =?us-ascii?Q?MRhjwEFoLcluYiqEEMHrPomgwStgxKussRDUINpS2NQHhPaWZMjIr8zxgbVv?= =?us-ascii?Q?I3VlHwvdYVleqIGoufy0jg0hPnfoCf02aSHe/FdLA6Jt7w8RQ8EkqzawZn04?= =?us-ascii?Q?8elw0zmJG9IIYUBAMHNsraCl5OfKiTrb2UWqS/ZKMOsrvofX9OyDj2907xu+?= =?us-ascii?Q?s9JgFcu8/9RRmz6f3oD+t4RSA7r9Z29rvEElOyGB6yluvLJSM3wlStKfgD3g?= =?us-ascii?Q?CELUmTrYwYpY9WUBqjHV75Cgfa2/O/mvhPPiO4G5ft1XvAZ1ZTCg4dt1dtfB?= =?us-ascii?Q?nqiHE48uI2KTGaS9IP9IDrNiHEOETPgpDSh+PHNwRD2hA83Rbn3sX6knrHo2?= =?us-ascii?Q?2ZkmyPjNyZxI7uqCMi1ECrssXONOfsw1J+jfJn93uf5iBHGc7Dwfsl5aKTz1?= =?us-ascii?Q?QlB1spoI80PVLJ3h6dMmwx1mSukUjTXZiuCQnIVQNd8r/lAnsoPQKkmd6ylC?= =?us-ascii?Q?dibVwsB39zmkVNnMekRmTwQAvRN5f4n7YWqZWI9MoXkQlGaL7YTRWwZglsMB?= =?us-ascii?Q?q8JRnCtQEscMzwtra5ZezlC5JKZV2ZpWJx+tNtYkFpzV+acjhL9e9uVlPD1S?= =?us-ascii?Q?gVO5TeogpuXFZ7evctG8qzRui9optfk/GmrzPZY4mXvyNKbmBB1d4rNDspa2?= =?us-ascii?Q?Qr78plUmcDsGwz00EJENGXTLzG5mRF2OU1VHQlWKEJVFoIxrkm0IKyiqRR0t?= =?us-ascii?Q?xBbFGIMdOY11PaKZ3oYwuT3iVw77Eel3d7hqMEPzQO0PeFDV55tsvh9aeFKP?= =?us-ascii?Q?Ib3gz4FJ0X3PUKLdN+RPhfg3SSzw6hBcytuG7B3x5Kx052lNMoKVmEmmWDPF?= =?us-ascii?Q?vRGgzGy3CUOLEGnEkF4JWp0ig3qrhJ7B26jDYMhCGCm7Mx/8q+cmid9s6bOk?= =?us-ascii?Q?W57BHLr2h0mHJImXwBi/UUyHe/+BGieduHwHns68uQEGpul1kJK99sAqYksn?= =?us-ascii?Q?XVA+lMWgJQ=3D=3D?= X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 0f0139ad-c107-4424-462f-08dec8856f62 X-MS-Exchange-CrossTenant-AuthSource: PA6PR04MB11910.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Jun 2026 13:20:55.9671 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: tEKV+LoiE3wJTW5DhbMyZVqzUKJW2/PaWJthv9+oI2Qme+tCH2j2ezrU/IWExB0yREOy0ERdcaFfm1OvthGu4A== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB9PR04MB8203 Content-Type: text/plain; charset="utf-8" Document the NXP neoisp driver both in the admin-guide for neoisp IP description, and in the userspace-api for neoisp interface description. Signed-off-by: Antoine Bouyer --- .../admin-guide/media/nxp-neoisp-diagram.dot | 24 +++ .../admin-guide/media/nxp-neoisp.dot | 18 ++ .../admin-guide/media/nxp-neoisp.rst | 179 ++++++++++++++++++ .../admin-guide/media/v4l-drivers.rst | 1 + .../userspace-api/media/v4l/meta-formats.rst | 1 + .../media/v4l/metafmt-nxp-neoisp.rst | 70 +++++++ 6 files changed, 293 insertions(+) create mode 100644 Documentation/admin-guide/media/nxp-neoisp-diagram.dot create mode 100644 Documentation/admin-guide/media/nxp-neoisp.dot create mode 100644 Documentation/admin-guide/media/nxp-neoisp.rst create mode 100644 Documentation/userspace-api/media/v4l/metafmt-nxp-neois= p.rst diff --git a/Documentation/admin-guide/media/nxp-neoisp-diagram.dot b/Docum= entation/admin-guide/media/nxp-neoisp-diagram.dot new file mode 100644 index 000000000000..362723d66bc9 --- /dev/null +++ b/Documentation/admin-guide/media/nxp-neoisp-diagram.dot @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: GPL-2.0 + +digraph G { + rankdir =3D "LR"; + node [shape=3Drect]; + splines =3D ortho; + label =3D "Neoisp pipeline diagram"; + {In0, In1 } -> HC -> {HDR_decomp0, HDR_decomp1}; + HDR_decomp0 -> OBWB0 -> HDR_merge; + HDR_decomp1 -> OBWB1 -> HDR_merge; + HDR_merge -> RGBIR -> IR_compression; + RGBIR -> Statistics; + RGBIR -> OBWB2 ->BNR -> Vignetting -> ColorTemp; + Vignetting -> Demosaic -> RGB2YUV -> DRC -> AF; + DRC-> NR -> EE -> DF -> Gamma -> Packetizer; + DRC -> DMAP -> DF[weight=3D2]; + DRC -> CCONV -> CAS -> Gamma; + {rank =3D "same"; RGBIR, DRC} + {rank =3D "same"; AF, NR, DMAP} + {rank =3D "same"; IR_compression, Vignetting} + IR_compression -> AXIOutDMA; + Packetizer -> AXIOutDMA [weight=3D3]; + AXIOutDMA -> {"Out0", "Out1"} +} diff --git a/Documentation/admin-guide/media/nxp-neoisp.dot b/Documentation= /admin-guide/media/nxp-neoisp.dot new file mode 100644 index 000000000000..79d9090dc1f9 --- /dev/null +++ b/Documentation/admin-guide/media/nxp-neoisp.dot @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: GPL-2.0 + +digraph board { + rankdir=3DTB + n00000001 [label=3D"{{ 0 | 1 | 2} | neoisp\n | { 3 | 4 | 5}}", shape=3DMrecord, style=3Dfilled, fillco= lor=3Dgreen] + n00000001:port3 -> n00000020 [style=3Ddashed] + n00000001:port4 -> n00000022 [style=3Ddashed] + n00000001:port5 -> n00000024 [style=3Ddashed] + n0000000a [label=3D"neoisp-input0\n/dev/video0", shape=3Dbox, style=3Dfil= led, fillcolor=3Dyellow] + n0000000a -> n00000001:port0 [style=3Dbold] + n00000010 [label=3D"neoisp-input1\n/dev/video1", shape=3Dbox, style=3Dfil= led, fillcolor=3Dyellow] + n00000010 -> n00000001:port1 [style=3Ddashed] + n00000016 [label=3D"neoisp-params\n/dev/video2", shape=3Dbox, style=3Dfil= led, fillcolor=3Dyellow] + n00000016 -> n00000001:port2 [style=3Ddashed] + n00000020 [label=3D"neoisp-frame\n/dev/video3", shape=3Dbox, style=3Dfill= ed, fillcolor=3Dyellow] + n00000022 [label=3D"neoisp-ir\n/dev/video4", shape=3Dbox, style=3Dfilled,= fillcolor=3Dyellow] + n00000024 [label=3D"neoisp-stats\n/dev/video5", shape=3Dbox, style=3Dfill= ed, fillcolor=3Dyellow] +} diff --git a/Documentation/admin-guide/media/nxp-neoisp.rst b/Documentation= /admin-guide/media/nxp-neoisp.rst new file mode 100644 index 000000000000..c8e3a2699140 --- /dev/null +++ b/Documentation/admin-guide/media/nxp-neoisp.rst @@ -0,0 +1,179 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +NXP Neo Image Signal Processor (neoisp) +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Introduction +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Neoisp performs a set of image processing tasks on the RAW camera stream, = where +the input camera stream and Neoisp processed output image are stored in DD= R or +any system memory fast enough to keep up with Neoisp processing. +The overall Neoisp operation is frame based, that is 1 complete image fram= e is +read and output pixel by pixel, line by line wise. + +Revisions +=3D=3D=3D=3D=3D=3D=3D=3D=3D + +NXP Neoisp driver supports the Neoisp V2 hw revision, used in i.MX95 Soc f= amily. + +Neoisp hardware +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +The Neoisp registers and pipeline processing are documented in the NXP Ima= ge +Signal Processor Specification document (under NDA). + +The NEO pipeline block diagram is shown below: + +.. kernel-figure:: nxp-neoisp-diagram.dot + :alt: Diagram of neoisp pipeline + :align: center + +It is composed of the following HW blocks: + +- a Head Color (HC) selection block, +- two HDR decompression blocks, one for each input, +- three Optical Black correction and White Balance (OBWB) blocks at differ= ent + stages in the pipeline, +- a HDR merge block for HDR image capture from the 2 input lines, +- a RGB-IR to RGGB converter, +- a Bayer Noise Reduction (BNR) block, +- a Vignetting block, aka Lens Shading Correction (LSC), +- a Demosaic block for RAW image conversion to RGB, +- a RGB Color Correction Matrix (CCM) and Color Space Converter aka CSC or + RGB2YUV, +- a Dynamic Range Compression (DRC) block, +- the Denoising pipeline (composed by multiple blocks for Noise Reduction,= Edge + Enhancement, Gamma Compensation, etc), +- a Packetizer used for UV sub-sampling or RGB packing. + +All these blocks are controlled by SW through registers. Some of these +registers are accessible by the uAPI, so that userspace application and Im= age +Processing Algorithms (IPA) can configure them through the parameters buff= ers. + +Neoisp driver +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Neoisp driver is located under drivers/media/platform/nxp/neoisp. +It uses the `V4L2 API` and the `V4L2 subdev API` to register capture and o= utput +video devices in addition to a subdevice for neoisp that connects the video +devices into a media graph realized using the `Media Controller (MC) API`. + +Driver provides a core registration API that allows registering the neoisp= core +media devices into an external media graph. In this case, the neoisp is fu= lly +integrated into a main media graph which could include other subdevices su= ch as +camera sensors, crossbar routing, etc. It also provides a module parameter= to +allow running in standalone mode. In such case, the neoisp registers its m= edia +devices into its own media graph. + +The media topology registered by Neoisp driver is represented below: + +.. kernel-figure:: nxp-neoisp.dot + :alt: Diagram of neoisp media device topology + :align: center + + +The neoisp registers the following video device nodes: + +- neoisp-input0: output device for RAW frames to be submitted to the ISP f= or processing. +- neoisp-input1: output device for RAW frames short capture in HDR merge m= ode. +- neoisp-params: output meta device for parameters provided by user space = 3A algorithms. +- neoisp-frame: capture device for RGB/YUV pixels of the processed images. +- neoisp-ir: capture device for the infra-red pixels of the processed imag= es. +- neoisp-stats: capture meta device for generated image statistics for use= r space 3A algorithms. + +neoisp-input0, neoisp-input1 +---------------------------- + +Images to be processed by Neoisp are queued to the neoisp-input0 (and +neoisp-input1 when in HDR mode) output device nodes. Supported image forma= ts +as input to the ISP are: + +- Raw bayer formats: + + - 8 bits raw (V4L2_PIX_FMT_SRGGB8, V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SGB= RG8, + V4L2_PIX_FMT_SGRBG8) + - 10 bits raw (V4L2_PIX_FMT_SRGGB10, V4L2_PIX_FMT_SBGGR10, + V4L2_PIX_FMT_SGBRG10, V4L2_PIX_FMT_SGRBG10) + - 12 bits raw (V4L2_PIX_FMT_SRGGB12, V4L2_PIX_FMT_SBGGR12, + V4L2_PIX_FMT_SGBRG12, V4L2_PIX_FMT_SGRBG12) + - 14 bits raw (V4L2_PIX_FMT_SRGGB14, V4L2_PIX_FMT_SBGGR14, + V4L2_PIX_FMT_SGBRG14, V4L2_PIX_FMT_SGRBG14) + - 16 bits raw (V4L2_PIX_FMT_SRGGB16, V4L2_PIX_FMT_SBGGR16, + V4L2_PIX_FMT_SGBRG16, V4L2_PIX_FMT_SGRBG16) + +- Monochrome formats: + + - 8 bits Monochrome (V4L2_PIX_FMT_GREY) + - 10 bits Monochrome (V4L2_PIX_FMT_Y10) + - 12 bits Monochrome (V4L2_PIX_FMT_Y12) + - 14 bits Monochrome (V4L2_PIX_FMT_Y14) + - 16 bits Monochrome (V4L2_PIX_FMT_Y16) + +.. note:: + RGBIr camera sensors are supported as well, and can be used through user + space activation of the IR block. + +.. note:: + neoisp-input1 link is mutable and should be enabled in case a short cap= ture + image buffer is provided to the ISP for HDR merge. + +.. _neoisp_params: + +neoisp-params +------------- + +The neoisp-params output meta device receives configuration data to be wri= tten +to Neoisp registers and internal memory for desired input image processing. +This v4l2 device accepts the generic `extensible parameters` format. + +In this format, the parameters buffer is defined by the generic +:c:type:`v4l2_isp_buffer`, and userspace should set +:ref:`V4L2_META_FMT_NEO_ISP_EXT_PARAMS ` +as dataformat. + +When the related media link is disabled, the image decoding will be done b= ased +on the default parameters of the ISP. + +neoisp-frame +------------ + +The capture device writes to memory the RGB or YUV pixels of the image pro= cessed +by Neoisp when the media link is enabled. If the related media link is dis= abled, +the processed image will be written to dummy buffer and not delivered to t= he +neoisp-frame video device node. + +neoisp-ir +--------- + +The capture device writes to memory the RGBIr pixels of the image processe= d by +Neoisp when the media link is enabled. If the related media link is disabl= ed, +the processed image will not be delivered to the neoisp-ir video device no= de. + +.. _neoisp_stats: + +neoisp-stats +------------ + +The neoisp-stats capture meta device provides statistics data generated by +Neoisp hardware while processing the input image. This v4l2 device accepts= the +`extensible statistics` format. + +In this format, the statistics buffer is defined by the generic +:c:type:`v4l2_isp_buffer`, and userspace should set +:ref:`V4L2_META_FMT_NEO_ISP_EXT_STATS ` as +dataformat. + +When the related media link is disabled, the decoding statistics will not = be +delivered to the neoisp-stats meta device node. + +Control +=3D=3D=3D=3D=3D=3D=3D + +To support additional neoisp hardware revisions, the read-only bitmask con= trol +``V4L2_CID_NEOISP_SUPPORTED_PARAMS_BLOCKS`` can be used to query the list = of +supported blocks. Each bit represents the availability of the corresponding +entry from the :c:type:`neoisp_param_block_type_e` enum. In current driver +version, default and max values represent the blocks supported by the i.MX= 95 +SoC. diff --git a/Documentation/admin-guide/media/v4l-drivers.rst b/Documentatio= n/admin-guide/media/v4l-drivers.rst index 4621eae9fa1e..4ae312b6135a 100644 --- a/Documentation/admin-guide/media/v4l-drivers.rst +++ b/Documentation/admin-guide/media/v4l-drivers.rst @@ -22,6 +22,7 @@ Video4Linux (V4L) driver-specific documentation ivtv mali-c55 mgb4 + nxp-neoisp omap3isp philips qcom_camss diff --git a/Documentation/userspace-api/media/v4l/meta-formats.rst b/Docum= entation/userspace-api/media/v4l/meta-formats.rst index 3e0cab153f0a..46268d955d3a 100644 --- a/Documentation/userspace-api/media/v4l/meta-formats.rst +++ b/Documentation/userspace-api/media/v4l/meta-formats.rst @@ -18,6 +18,7 @@ These formats are used for the :ref:`metadata` interface = only. metafmt-d4xx metafmt-generic metafmt-intel-ipu3 + metafmt-nxp-neoisp metafmt-pisp-be metafmt-pisp-fe metafmt-rkisp1 diff --git a/Documentation/userspace-api/media/v4l/metafmt-nxp-neoisp.rst b= /Documentation/userspace-api/media/v4l/metafmt-nxp-neoisp.rst new file mode 100644 index 000000000000..c631fd50972a --- /dev/null +++ b/Documentation/userspace-api/media/v4l/metafmt-nxp-neoisp.rst @@ -0,0 +1,70 @@ +.. SPDX-License-Identifier: GPL-2.0 + +***************************************** +V4L2_META_FMT_NEO_ISP_EXT_PARAMS ('nnep') +***************************************** + +The Neoisp image signal processor is configured by userspace through a buf= fer +of parameters to :ref:`neoisp-params ` output device node u= sing +the :c:type:`v4l2_meta_format` interface. + +The parameters buffer uses the generic `extensible parameters` configurati= on +format. + +.. _v4l2-meta-fmt-neo-isp-ext-params: + +Extensible parameters configuration format +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +When using the `extensible parameters` configuration format, parameters are +passed to the :ref:`neoisp-params ` metadata output video n= ode +using the `V4L2_META_FMT_NEO_ISP_EXT_PARAMS` meta format. + +The buffer contains a single instance of the C structure +:c:type:`v4l2_isp_buffer` defined in `v4l2-isp.h`. The +:c:type:`v4l2_isp_buffer` structure is designed to allow userspace to +populate the data buffer with only the configuration data for the Neoisp b= locks +it intends to configure. The extensible parameters format design allows +developers to define new block types to support new configuration paramete= rs, +and defines a versioning scheme so that it can be extended and versioned +without breaking compatibility with existing applications. + +**************************************** +V4L2_META_FMT_NEO_ISP_EXT_STATS ('nnes') +**************************************** + +The Neoisp image signal processor generates statistics data while processi= ng an +input image. These statistics are captured in a buffer and provided to +userspace through the :ref:`neoisp-stats ` capture video node +using the :c:type:`v4l2_meta_format` interface. The statistics data are +processed by userspace application to produce the next Neoisp parameters. + +The statistics buffer uses the generic `extensible statistics` format. + +.. _v4l2-meta-fmt-neo-isp-ext-stats: + +Extensible statistics format +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D + +When using the `extensible statistics` format, the statistics buffer is pa= ssed +from the :ref:`neoisp-stats ` metadata capture video node us= ing +the `V4L2_META_FMT_NEO_ISP_EXT_STATS` meta format. + +The buffer contains a single instance of the C structure +:c:type:`v4l2_isp_buffer` defined in `v4l2-isp.h`. The +:c:type:`v4l2_isp_buffer` structure is designed to allow future Neoisp +driver versions to populate the statistics buffer with future blocks +statistics, and defines a versioning scheme so that it can be extended and +versioned without breaking compatibility with existing applications. + +********************** +Neoisp uAPI data types +********************** + +This chapter describes the data types exposed to userspace by Neoisp drive= r. + +Some structure members are in a fixed-point format, in this case the relat= ed +description will be ended by a fixed-point definition between parenthesis. + +.. kernel-doc:: include/uapi/linux/media/nxp/nxp_neoisp.h + --=20 2.53.0 From nobody Sat Jun 13 02:07:57 2026 Received: from AS8PR04CU009.outbound.protection.outlook.com (mail-westeuropeazon11011050.outbound.protection.outlook.com [52.101.70.50]) (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 3B6B13F0A8C; Fri, 12 Jun 2026 13:21:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.70.50 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781270483; cv=fail; b=OfWyvpUMgM4khqs3pIVTSJHRvVCR54+ISdN7s11MylYZ2Nng6LHl6pDl2eESGzKWpJxVwVwS4WvwgCPDbmeLV+a9f6fWwQkUO9urNG2KikvdW4W61O9RnVMs7Smy+PZfqoLmHS40mt/B0GXlwzMh7T+MLYuFdwkTkzF7AtsSsLs= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781270483; c=relaxed/simple; bh=NKFZBh5eEqMdFSPzfdiwZboC/iv6NJIhgpLAK6HVA6k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=k7saqej1UjaENLqgIsEMZIDGhSgJKriKfrYH0OIg4UcgMwFubQRpdJc190+43vJUavb6sR6wZ6xkpqV1zTJWeZdPYz0/kSelJ152aKPcxplAul/bqcOYdzdSDt4Po9+ZQhdWAfNe12neJKG/OFAGIsaoXjeh7/NdICFsIrvtL24= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com; spf=pass smtp.mailfrom=nxp.com; dkim=pass (2048-bit key) header.d=nxp.com header.i=@nxp.com header.b=As1MnKbl; arc=fail smtp.client-ip=52.101.70.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nxp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nxp.com header.i=@nxp.com header.b="As1MnKbl" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=jdV31MU09u0oimTGcPh+GnjZuYoes8qdjAUlbQpse9tPL9Ie7AaCbCTPU4qOZr24jIcQe1O8nbqYIgVIcq0Rqyix5K4wNbMWVdQTtpVewKZP9fyrdCBuvpTvQ9joyk/urGN6O2swJ5sCZdgSqJZ9sNBOr3zfQ6zVGP6imtXVxuizlM65H+iIrggc3iUtJy+E8ftJwWmDMKKi7yOkmPKIB3Dbg5EFqUsChPoAUcE5nemHVc3DeagACAsVOfGxcFI9zL0cQbW95irbmRKLSjdTINMyd1T0RWzW/3FuDByHgi3OUR2D/nPUozjbHoNSz5Rnd4fAstdyFVJTXesKjwEbKg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=2HSGMdhFrDuRwOFoVKQmfsLq1sKPYFdWYuS2UWJhgY0=; b=ThNOExQqh2yuPOwJMujcMaLdOFaQeNWovOt4J9rQ5lMVy8w5AQWOQUueDknqDU9cvQL7snSU7TGUURgIcebI/moTFHDZ93AExxdSewjbXK4v39LrRapTnldXI3ZTG1SFSPukaW2U57/SW9q83h5mUju+/AGWTHcxvCCX3bu54NfEo87JCnO7HCwrd30rUfH6SbmGDqkvh8jOopq1PagrW+wvtcgR488F2lTce6mqkUVuNp130u23IwUDya8xlXvzBq45x5xRE8E9WrGmXyzjE5z58L39OlB7rVsQz4IHXzI0GX3KuA3WbWfXYV8No/rpAuTvG+p0UzGmt9qq1qw2oQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nxp.com; dmarc=pass action=none header.from=nxp.com; dkim=pass header.d=nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=2HSGMdhFrDuRwOFoVKQmfsLq1sKPYFdWYuS2UWJhgY0=; b=As1MnKblQ43VQA8xu48nNhMWxg17vZxxDjTcFYWc2OXX1RbMlTSoRL9gBvQGaizPN/w5pG2Eqs5jyk1v+trSy5+KxBocwnRTfryWs6RPmXu2Ta6U+UxrEsm32y5JwSoRjajBorp6Wpt3edyAoneeFJMlb0332+QN++75ktlQP/ihswsjFZSalDZF5A6l2d6z9WOcmzq5xeicrj1CdTN+pgz9CqGHLdSQT2gQ9ZjIyET7ZOa8WIf3uZLhXbPGtcxmK2kArKHa7nBVEleT08t8gRctH/dI73gk6/HhvY49NH/yZAG7Qg57VgeIKqSTTNJ5dfs5QcovgNvnfDMLWfkHow== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from PA6PR04MB11910.eurprd04.prod.outlook.com (2603:10a6:102:516::16) by DB9PR04MB8203.eurprd04.prod.outlook.com (2603:10a6:10:242::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.113.14; Fri, 12 Jun 2026 13:20:58 +0000 Received: from PA6PR04MB11910.eurprd04.prod.outlook.com ([fe80::d3f0:3c24:f717:4989]) by PA6PR04MB11910.eurprd04.prod.outlook.com ([fe80::d3f0:3c24:f717:4989%4]) with mapi id 15.21.0113.013; Fri, 12 Jun 2026 13:20:58 +0000 From: Antoine Bouyer To: julien.vuillaumier@nxp.com, alexi.birlinger@nxp.com, daniel.baluta@nxp.com, peng.fan@nxp.com, frank.li@nxp.com, jacopo.mondi@ideasonboard.com, laurent.pinchart@ideasonboard.com, mchehab@kernel.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, michael.riesch@collabora.com, anthony.mcgivern@arm.com Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, imx@lists.linux.dev, ai.luthra@ideasonboard.com, paul.elder@ideasonboard.com, geert@linux-m68k.org, sakari.ailus@linux.intel.com, hverkuil+cisco@kernel.org, Antoine Bouyer Subject: [PATCH v3 6/8] media: platform: Add NXP Neoisp Image Signal Processor Date: Fri, 12 Jun 2026 15:20:37 +0200 Message-ID: <20260612132039.2089051-7-antoine.bouyer@nxp.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260612132039.2089051-1-antoine.bouyer@nxp.com> References: <20260612132039.2089051-1-antoine.bouyer@nxp.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: FR4P281CA0059.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:cc::7) To PA6PR04MB11910.eurprd04.prod.outlook.com (2603:10a6:102:516::16) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PA6PR04MB11910:EE_|DB9PR04MB8203:EE_ X-MS-Office365-Filtering-Correlation-Id: d69b85c0-800b-496e-fb17-08dec8857076 X-LD-Processed: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635,ExtAddr X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|19092799006|4022899009|376014|7416014|366016|23010399003|13003099007|921020|6133799003|18002099003|22082099003|3023799007|5023799004|11063799006|56012099006; X-Microsoft-Antispam-Message-Info: iGcnruIvxb/oGDgjfGWHs9iOzmSM8bC2GdAAf3cTfR4rFQknvTzYLygpoNNpFJtXzqfQ68EIPFd2RwARz+lg67KvGiY07KVzIX7BUVHomReKxIE6inIzDfplPOBk2FS8MMA4YdGjm91Ls+eYj6kPVeGE/bUUgTDnpMoGqjOnsYrs39L5P7nMfEzE4P3HS3PMbtR17Qwx9lLnlYwcm9ifEhzwztxhbCvHKSqR/bhdbZbjJJvCGwOuIKIKnMRjnMOoPmaxw/9lYlOtqQQGhYihnnJQdlikhGSw+yw8zS13QFLL18TJmMzqbDNIo+korWO1UNtDlPmkRAPTNle9f1V5/KbZsBoNoG4YTF6fAOVUNikQGz9+x4sjJlqVlC6NSSZ2ZlUfdx8l0VScJ5/x/jfrVtqJGlYGljEWHBCuzqna0eQ4pF59QhO0H1O16Q6QxsOpiu3cCWO4VKf0QZb9Q/Xei8WNH2gsXzpm4eh5UH/eJA38d2V+8YD/F+9edBUe4tI2WvtENKoGcKA0dJFxPpbqmr6Nl8g5GlysB2+fSIrDJQXPBirPda5SeuFwdME5HHOBVKqXyiJXU4gRYTURncY2SFOF6GUD5g8k7DSOhoz/Rj3D06axs2cjnsgp//rTcHiwf3rOVkeMReIHS9BDi28qFXkq/TH+6g+ZupHmDl8eFqK9ZEbgNMcxAKlK4ZHsb2fD X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PA6PR04MB11910.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(1800799024)(19092799006)(4022899009)(376014)(7416014)(366016)(23010399003)(13003099007)(921020)(6133799003)(18002099003)(22082099003)(3023799007)(5023799004)(11063799006)(56012099006);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?+xOqv/LXXWcwFWsRdHI9yQ0VgCwHI7iopodylyova8yBO8jzgxSZK7mF3BzS?= =?us-ascii?Q?8bwXFzC+Lw/mVQyUd7/oSqkPzFr74WPwtR1/2E0yxXD16LbLTQdagjjm5aph?= =?us-ascii?Q?sNDgDHJaMhLcgnGcKqC6jjDnYk4bmLPJOVKdFC0OobTahbg5r2MpOVzENRfz?= =?us-ascii?Q?Z5KW7DAsN2APqVhHFh5gGIAtVFPYniAkxT/XsxUa0/bKZOT/JPZPPN7/YYM1?= =?us-ascii?Q?BLKwn1VuqOLelmeQ7/M7suYlD7gtNaPAvTeYuCv49BwYoSes2jIYqhBqqLzV?= =?us-ascii?Q?+fU2hKYO37LnvsNXLj67BT9UXSP4jkUP7REqAx1UdY5hGp6+IWai/5ylCldF?= =?us-ascii?Q?ouKnCajl9zf36acxv9yBBXA6Vwjv9kfvT/pfjzLQZ0sTvPyS3ysx+855ka7q?= =?us-ascii?Q?TZS4fLrBYsDxxxkgL/owF5IZDnEguTy2oW+gYe2uY3EotAyGoY0lE4MdsCRb?= =?us-ascii?Q?GMkQMWrQL0sc9KW+vr64eIctwrDZhjKRd9c9n78I+nAAbH2Mfaiy7e3J68gf?= =?us-ascii?Q?Q3Fu9pkBYBmIvcsVUaHm1H6IcSgnNa1xg7Jh7x22q4bg5JsOah+focSmHrGI?= =?us-ascii?Q?Z9DReySnM0KPI7Cb3RUqgIfkDo54TaYcOEvJRo4qfCPuHyYrtfbrd2meI8xf?= =?us-ascii?Q?bx4vw1RenW7npA9thA/pH6HEccC3yNeCBYsFgrFHFhKk9ILkQHqxjs9pH2Sb?= =?us-ascii?Q?X0p8DfI4U/jamHKvx3a58i8DwagqEq0Ba+BZZ23d6Y8913BWJ8sO2EE+KWQZ?= =?us-ascii?Q?hB2Ob5Q/z3yL8hfqvqFmfPNzbq9TI9kQb38jlM+ZannwGgHXMSoVTsWOiVVp?= =?us-ascii?Q?z6H10u6p56XviFF32v8GH+PFtLWD0lioOa0GH3J4xDD2RZ2uSj1EAx9EIkPZ?= =?us-ascii?Q?W0ikzoNeLij8UhHXfvoNmktGFIJb9VWg/IDyUlY860Gx8tX03ih7V0YlgpDd?= =?us-ascii?Q?6eap68NDaEmE9xIzpbZiNUK5Li1Sg3uQrn5W99b+pqvswP82dJZfF8h5j4+g?= =?us-ascii?Q?MWcl68rf+WR/y9PIZeTj29PL5n9kyfD3YgHBAMdjjhHz2dVR6xSQnsOYYYIB?= =?us-ascii?Q?gz1U0SQ4A+eeojOsqHrIqGDI9XGywE7XFqqvbw8RH4rJbfl58qRrGcOUbw2a?= =?us-ascii?Q?fIvq+Fulg54zNitYb7CglrJ0nxzvwP+ieMGRHnl7dRy192sjbGxSbaRUHaur?= =?us-ascii?Q?bgcca5uhcGKvIJsP5xydAIB7icKZy71/n7F4ZSeIxevJk44cMtqADEg6XrgD?= =?us-ascii?Q?UnfDcifYW0/J5SrKJVCH7RntqevJ9qw4nreO1FcPZRXwgAFBQLDYUD9U02IX?= =?us-ascii?Q?CrD9zf1OHpNAWa0WW4anYHoRa+QHTD8guod8vNs44l0NpG2M8HEbNHoDGPay?= =?us-ascii?Q?eGjn1WQaUH/Gp9m0KaS3VdAP2ezRN5jvQbZ8opE/2LmhjDunXAlMcZOOAV2h?= =?us-ascii?Q?CYQvCuAsRtrrrWHdPo2y/rk/2Fbl3zvYpPaoXba/phvenWT0LnVmzuJ7/zTr?= =?us-ascii?Q?KRnj+GPHNpV4O46zbiJCHoQ2lzvSM9oa3zSv+T2m28efVniU71Ixg6qt5yN2?= =?us-ascii?Q?ZFl6qKSYZS7rbpYV4JjTgHrnARCrTfsJT0gHlIU/H4oS2vC/ajB7gyMmTK7T?= =?us-ascii?Q?X5OmtDkSHrT4l0GtL7PeGNsDUb4Jevx9CXjNWh0FtpQHLu+xTf0APa/lugKJ?= =?us-ascii?Q?/zigPVRSSBaWygHKfNab/266IQjSW1ms2mXgjeGxvdGKZHp4sVHJYGuA9DQR?= =?us-ascii?Q?Yk6H7lh4zQ=3D=3D?= X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: d69b85c0-800b-496e-fb17-08dec8857076 X-MS-Exchange-CrossTenant-AuthSource: PA6PR04MB11910.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Jun 2026 13:20:58.0274 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: G3KaVOjz09A7a3OzBibVEQx3AA28rMqPPDgmK9+yTu1506m4S6fFZ9NLL/i4+YeMyVDwHOzo2FtG8qntSVr4dw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB9PR04MB8203 Content-Type: text/plain; charset="utf-8" First NXP neoisp driver version with the following contents: This driver was initially inspired from raspberrypi pisp_be driver. It reuses same approach for ISP job scheduling. The Neoisp driver supports: * 8, 10, 12, 14 and 16-bits RAW Bayer images input. * Monochrome sensors input. * RGB/YUV, IR and Greyscale output formats. The neoisp features are: * Provides single context to limit amount of v4l2 devices. * Supports M2M operations. * Support SDR and HDR modes. * Supports generic v4l2-isp framework for extensible Parameters and Statistics buffers. * Provides a `core_media_register` API to register neoisp's media entities into another media graph. * A module parameter to run in standalone mode with its own media device. Co-developed-by: Alexi Birlinger Signed-off-by: Alexi Birlinger Signed-off-by: Antoine Bouyer --- MAINTAINERS | 9 + drivers/media/platform/nxp/Kconfig | 1 + drivers/media/platform/nxp/Makefile | 1 + drivers/media/platform/nxp/neoisp/Kconfig | 17 + drivers/media/platform/nxp/neoisp/Makefile | 6 + drivers/media/platform/nxp/neoisp/neoisp.h | 249 ++ .../media/platform/nxp/neoisp/neoisp_core.h | 30 + .../media/platform/nxp/neoisp/neoisp_ctx.c | 2635 +++++++++++++++++ .../media/platform/nxp/neoisp/neoisp_ctx.h | 77 + .../media/platform/nxp/neoisp/neoisp_fmt.h | 495 ++++ drivers/media/platform/nxp/neoisp/neoisp_hw.h | 557 ++++ .../media/platform/nxp/neoisp/neoisp_main.c | 1907 ++++++++++++ .../media/platform/nxp/neoisp/neoisp_nodes.h | 54 + .../media/platform/nxp/neoisp/neoisp_regs.h | 1465 +++++++++ 14 files changed, 7503 insertions(+) create mode 100644 drivers/media/platform/nxp/neoisp/Kconfig create mode 100644 drivers/media/platform/nxp/neoisp/Makefile create mode 100644 drivers/media/platform/nxp/neoisp/neoisp.h create mode 100644 drivers/media/platform/nxp/neoisp/neoisp_core.h create mode 100644 drivers/media/platform/nxp/neoisp/neoisp_ctx.c create mode 100644 drivers/media/platform/nxp/neoisp/neoisp_ctx.h create mode 100644 drivers/media/platform/nxp/neoisp/neoisp_fmt.h create mode 100644 drivers/media/platform/nxp/neoisp/neoisp_hw.h create mode 100644 drivers/media/platform/nxp/neoisp/neoisp_main.c create mode 100644 drivers/media/platform/nxp/neoisp/neoisp_nodes.h create mode 100644 drivers/media/platform/nxp/neoisp/neoisp_regs.h diff --git a/MAINTAINERS b/MAINTAINERS index a727d4920fae..85a5a73e0e1b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16274,6 +16274,15 @@ W: https://linuxtv.org T: git git://linuxtv.org/media.git F: drivers/media/dvb-frontends/mxl5xx* =20 +MEDIA DRIVERS FOR NXP NEOISP +M: Antoine Bouyer +S: Maintained +F: Documentation/admin-guide/media/nxp-neoisp* +F: Documentation/devicetree/bindings/media/nxp,imx95-neoisp.yaml +F: Documentation/userspace-api/media/v4l/metafmt-nxp-neoisp.rst +F: drivers/media/platform/nxp/neoisp/* +F: include/uapi/linux/media/nxp/nxp_neoisp.h + MEDIA DRIVERS FOR NETUP PCI UNIVERSAL DVB devices M: Abylay Ospan L: linux-media@vger.kernel.org diff --git a/drivers/media/platform/nxp/Kconfig b/drivers/media/platform/nx= p/Kconfig index 40e3436669e2..924307e6660b 100644 --- a/drivers/media/platform/nxp/Kconfig +++ b/drivers/media/platform/nxp/Kconfig @@ -67,3 +67,4 @@ config VIDEO_MX2_EMMAPRP =20 source "drivers/media/platform/nxp/dw100/Kconfig" source "drivers/media/platform/nxp/imx-jpeg/Kconfig" +source "drivers/media/platform/nxp/neoisp/Kconfig" diff --git a/drivers/media/platform/nxp/Makefile b/drivers/media/platform/n= xp/Makefile index 4d90eb713652..f5d91598fc8b 100644 --- a/drivers/media/platform/nxp/Makefile +++ b/drivers/media/platform/nxp/Makefile @@ -3,6 +3,7 @@ obj-y +=3D dw100/ obj-y +=3D imx-jpeg/ obj-y +=3D imx8-isi/ +obj-y +=3D neoisp/ =20 obj-$(CONFIG_VIDEO_IMX7_CSI) +=3D imx7-media-csi.o obj-$(CONFIG_VIDEO_IMX8MQ_MIPI_CSI2) +=3D imx8mq-mipi-csi2.o diff --git a/drivers/media/platform/nxp/neoisp/Kconfig b/drivers/media/plat= form/nxp/neoisp/Kconfig new file mode 100644 index 000000000000..643b03f18d88 --- /dev/null +++ b/drivers/media/platform/nxp/neoisp/Kconfig @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config VIDEO_NXP_NEOISP + tristate "NXP NEO Image Signal Processor (ISP) driver" + depends on ARCH_MXC || COMPILE_TEST + depends on HAS_DMA && PM + depends on VIDEO_DEV + select MEDIA_CONTROLLER + select VIDEOBUF2_DMA_CONTIG + select V4L2_ISP + help + Enable this to support the NXP NEO Image Signal Processing (ISP) + module present in various NXP SoCs. This module offers multiple + functions for processing RAW images and generating RGB or YUV images. + + To compile this driver as a module, choose M here: the module + will be called neoisp. diff --git a/drivers/media/platform/nxp/neoisp/Makefile b/drivers/media/pla= tform/nxp/neoisp/Makefile new file mode 100644 index 000000000000..7652df785e98 --- /dev/null +++ b/drivers/media/platform/nxp/neoisp/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ + +obj-$(CONFIG_VIDEO_NXP_NEOISP) +=3D neoisp.o + +neoisp-objs :=3D neoisp_ctx.o \ + neoisp_main.o diff --git a/drivers/media/platform/nxp/neoisp/neoisp.h b/drivers/media/pla= tform/nxp/neoisp/neoisp.h new file mode 100644 index 000000000000..a777625974fe --- /dev/null +++ b/drivers/media/platform/nxp/neoisp/neoisp.h @@ -0,0 +1,249 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * NEOISP main header file + * + * Copyright 2023-2026 NXP + */ + +#ifndef __NXP_NEOISP_H +#define __NXP_NEOISP_H + +#include +#include +#include +#include +#include +#include + +#include "neoisp_hw.h" + +#define NEOISP_NAME "neoisp" + +#define NEOISP_MIN_W 64U +#define NEOISP_MIN_H 64U +#define NEOISP_MAX_W 4096U +#define NEOISP_MAX_H 4096U +#define NEOISP_MAX_BPP 4U +#define NEOISP_ALIGN_W 3 +#define NEOISP_ALIGN_H 3 +#define NEOISP_DEF_W 640U +#define NEOISP_DEF_H 480U + +#define NEOISP_SUSPEND_TIMEOUT_MS 500 + +/* + * 16 controls have been reserved for this driver for future extension, but + * let's limit the related driver allocation to the effective number of co= ntrols + * in use. + */ +enum neoisp_ctrls_e { + NEOISP_CTRLS_SUPPORTED_PARAMS_BLOCKS, + NEOISP_CTRLS_COUNT, +}; + +static inline bool format_is_monochrome(u32 format) +{ + return format =3D=3D V4L2_PIX_FMT_GREY || format =3D=3D V4L2_PIX_FMT_Y10 = || + format =3D=3D V4L2_PIX_FMT_Y12 || format =3D=3D V4L2_PIX_FMT_Y14 || + format =3D=3D V4L2_PIX_FMT_Y16 || format =3D=3D V4L2_PIX_FMT_Y16_BE; +} + +#define NEOISP_COLORSPACE_MASK(colorspace) BIT((colorspace) & 0x1f) + +#define NEOISP_COLORSPACE_MASK_JPEG \ + NEOISP_COLORSPACE_MASK(V4L2_COLORSPACE_JPEG) +#define NEOISP_COLORSPACE_MASK_SMPTE170M \ + NEOISP_COLORSPACE_MASK(V4L2_COLORSPACE_SMPTE170M) +#define NEOISP_COLORSPACE_MASK_REC709 \ + NEOISP_COLORSPACE_MASK(V4L2_COLORSPACE_REC709) +#define NEOISP_COLORSPACE_MASK_SRGB \ + NEOISP_COLORSPACE_MASK(V4L2_COLORSPACE_SRGB) +#define NEOISP_COLORSPACE_MASK_RAW \ + NEOISP_COLORSPACE_MASK(V4L2_COLORSPACE_RAW) + +/* + * JPEG, SMPTE170M and REC709 colorspaces are fundamentally sRGB underneath + * with different YCbCr encodings. All these colorspaces are defined for + * every YUV/RGB video capture formats. + */ +#define NEOISP_COLORSPACE_MASK_ALL_SRGB (NEOISP_COLORSPACE_MASK_JPEG | \ + NEOISP_COLORSPACE_MASK_SRGB | \ + NEOISP_COLORSPACE_MASK_SMPTE170M | \ + NEOISP_COLORSPACE_MASK_REC709) + +enum neoisp_fmt_type_e { + NEOISP_FMT_VIDEO_CAPTURE =3D BIT(0), + NEOISP_FMT_VIDEO_OUTPUT =3D BIT(1), + NEOISP_FMT_META_CAPTURE =3D BIT(2), + NEOISP_FMT_META_OUTPUT =3D BIT(3), +}; + +enum neoisp_node_e { + NEOISP_INPUT0_NODE, + NEOISP_INPUT1_NODE, + NEOISP_PARAMS_NODE, + NEOISP_FRAME_NODE, + NEOISP_IR_NODE, + NEOISP_STATS_NODE, + NEOISP_NODES_COUNT, +}; + +struct neoisp_fmt_s { + u32 fourcc; + u32 align; + u32 bit_depth; + u32 num_planes; + u8 pl_divisors[VB2_MAX_PLANES]; + u8 bpp_enc; + u8 is_rgb; + u32 colorspace_mask; + enum v4l2_colorspace colorspace_default; + enum neoisp_fmt_type_e type; +}; + +struct neoisp_dev_s; + +struct neoisp_context_s { + struct neoisp_hw_s hw; + struct neoisp_vignetting_table_mem_params_s vig; + struct neoisp_drc_global_tonemap_mem_params_s gtm; + struct neoisp_drc_local_tonemap_mem_params_s ltm; +}; + +/* + * struct neoisp_context_ops_s - Context related operations across HW revi= sions + * + * @get_irq_status: Read irq status register + * @set_irq_enable: Set irq enable register + * @clear_irq: Clear irq status register + * @adjust_gain: Callback to adjust gain for data alignment + */ +struct neoisp_context_ops_s { + u32 (*get_irq_status)(struct neoisp_dev_s *neoispd); + void (*set_irq_enable)(struct neoisp_dev_s *neoispd, u32 val); + void (*clear_irq)(struct neoisp_dev_s *neoispd, u32 val); + void (*adjust_gain)(struct neoisp_context_s *ctx, u32 ibpp); +}; + +struct isp_block_map_s { + u32 vignetting_table; + u32 drc_global_tonemap; + u32 drc_global_hist_roi0; + u32 drc_global_hist_roi1; + u32 drc_local_tonemap; + u32 drc_local_sum; +}; + +/* + * struct neoisp_info_s - ISP Hardware various information + * + * @blocks_list: The list of ISP units supported by an ISP version + * + * This structure contains information about the ISP specific model, + * like parameters block list. + */ +struct neoisp_info_s { + const unsigned int *blocks_list; +}; + +struct neoisp_node_desc_s { + const char *ent_name; + enum v4l2_buf_type buf_type; + u32 caps; + u32 link_flags; +}; + +/* + * Structure to describe a single node /dev/video which represents a si= ngle + * input or output queue to the neoisp device. + */ +struct neoisp_node_s { + u32 id; + s32 vfl_dir; + enum v4l2_buf_type buf_type; + struct video_device vfd; + struct media_pad pad; + struct media_intf_devnode *intf_devnode; + struct media_link *intf_link; + struct neoisp_dev_s *neoisp; + struct list_head ready_queue; + struct vb2_queue queue; + struct v4l2_format format; + const struct neoisp_fmt_s *neoisp_format; + struct v4l2_rect crop; +}; + +struct neoisp_buffer_s { + struct vb2_v4l2_buffer vb; + struct list_head ready_list; +}; + +static inline struct neoisp_buffer_s *to_neoisp_buffer(struct vb2_v4l2_buf= fer *vbuf) +{ + return container_of(vbuf, struct neoisp_buffer_s, vb); +} + +/* Catch currently running or queued jobs on the neoisp hw */ +struct neoisp_job_s { + struct neoisp_buffer_s *buf[NEOISP_NODES_COUNT]; +}; + +/* Records a job configuration */ +struct neoisp_job_desc_s { + struct list_head queue; + struct neoisp_buffer_s *buffers[NEOISP_NODES_COUNT]; +}; + +struct neoisp_dev_s { + struct device *dev; + struct neoisp_info_s *info; + void __iomem *mmio; + void *local_mem; + struct clk_bulk_data *clks; + s32 num_clks; + struct neoisp_job_s queued_job; + bool hw_busy; /* Non-zero if a job is queued or is being started */ + u8 media_registered; + struct list_head job_queue; + /* Protects "hw_busy" flag, streaming_map and job_queue */ + spinlock_t hw_lock; + u32 frame_sequence; + struct v4l2_device v4l2_dev; + struct v4l2_subdev sd; + struct v4l2_ctrl_handler hdl; + struct v4l2_ctrl *ctrls[NEOISP_CTRLS_COUNT]; + struct media_device mdev; + struct neoisp_node_s node[NEOISP_NODES_COUNT]; + /* Global lock for the node queues */ + struct mutex queue_lock; + u32 streaming_map; /* Bitmap of which nodes are streaming */ + struct media_pad pad[NEOISP_NODES_COUNT]; /* Output pads first */ + dma_addr_t params_dma_addr; + u32 *dummy_buf; + dma_addr_t dummy_dma; + u32 dummy_size; + struct neoisp_context_s *context; +}; + +static inline int neoisp_node_link_is_enabled(struct neoisp_node_s *node) +{ + return (node->intf_link->flags & MEDIA_LNK_FL_ENABLED); +} + +/* + * From the Reference Manual, we must always access the NEO registers using + * 32-bit operations. + */ +static inline u32 neoisp_rd(struct neoisp_dev_s *neoispd, u32 offset) +{ + return readl(neoispd->mmio + offset); +} + +static inline void neoisp_wr(struct neoisp_dev_s *neoispd, u32 offset, u32= val) +{ + writel(val, neoispd->mmio + offset); +} + +const struct neoisp_fmt_s *neoisp_find_video_capture_format(u32 pixel_form= at); + +#endif /* __NXP_NEOISP_H */ diff --git a/drivers/media/platform/nxp/neoisp/neoisp_core.h b/drivers/medi= a/platform/nxp/neoisp/neoisp_core.h new file mode 100644 index 000000000000..5f035e14f34b --- /dev/null +++ b/drivers/media/platform/nxp/neoisp/neoisp_core.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * NEOISP context definition + * + * Copyright 2026 NXP + */ + +#ifndef __NXP_NEOISP_CORE_H +#define __NXP_NEOISP_CORE_H + +/** + * neoisp_core_media_register - Register neoisp subdevice into another med= ia device + * @dev: the neoisp device pointer + * @sd: The V4L2 subdevice which shares the media device to neoisp core + * + * This function allows a V4L2 subdevice sharing the media device it belon= gs to + * with neo isp core devices. Thus, the neoisp graph can be registered in = that media + * device, even thought it is independent without any media link connectio= ns to the + * other devices. + */ +#if IS_ENABLED(CONFIG_VIDEO_NXP_NEOISP) +int neoisp_core_media_register(struct device *dev, struct v4l2_subdev *sd); +#else +static inline int neoisp_core_media_register(struct device *dev, struct v4= l2_subdev *sd) +{ + return 0; +} +#endif + +#endif /* __NXP_NEOISP_CORE_H */ diff --git a/drivers/media/platform/nxp/neoisp/neoisp_ctx.c b/drivers/media= /platform/nxp/neoisp/neoisp_ctx.c new file mode 100644 index 000000000000..9d13eb7b732d --- /dev/null +++ b/drivers/media/platform/nxp/neoisp/neoisp_ctx.c @@ -0,0 +1,2635 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * NEOISP context registers/memory setting helpers + * + * Copyright 2023-2026 NXP + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "neoisp.h" +#include "neoisp_ctx.h" + +#define FIELD_PREP_S16_CONST(_mask, _val) \ + FIELD_PREP_CONST(_mask, (_val) & GENMASK(15, 0)) +/* + * This is the initial set of parameters setup by driver upon a streamon i= octl for INPUT0 node. + * It could be updated later by the driver depending on input/output forma= ts setup by userspace + * and also if fine tuned parameters are provided by the camera stack. + */ +static const struct neoisp_context_s def_context =3D { + .hw =3D { + .pipe_conf =3D { + .img_conf =3D + FIELD_PREP_CONST(NEO_PIPE_CONF_IMG_CONF_CAM0_INALIGN0, 1) | + FIELD_PREP_CONST(NEO_PIPE_CONF_IMG_CONF_CAM0_LPALIGN0, 1) | + FIELD_PREP_CONST(NEO_PIPE_CONF_IMG_CONF_CAM0_INALIGN1, 1) | + FIELD_PREP_CONST(NEO_PIPE_CONF_IMG_CONF_CAM0_LPALIGN1, 1), + }, + .hdr_decompress0 =3D { + .ctrl =3D + FIELD_PREP_CONST(NEO_HDR_DECOMPRESS0_CTRL_CAM0_ENABLE, 1), + .knee_ratio4 =3D + FIELD_PREP_CONST(NEO_HDR_DECOMPRESS0_KNEE_RATIO4_CAM0_RATIO4, + 1 << 5), + }, + .hdr_decompress1 =3D { + .ctrl =3D + FIELD_PREP_CONST(NEO_HDR_DECOMPRESS1_CTRL_CAM0_ENABLE, 0), + .knee_ratio4 =3D + FIELD_PREP_CONST(NEO_HDR_DECOMPRESS1_KNEE_RATIO4_CAM0_RATIO4, + 1 << 5), + }, + .obwb0 =3D { + .ctrl =3D + FIELD_PREP_CONST(NEO_OB_WB0_CTRL_CAM0_OBPP, 3), + .r_ctrl =3D + FIELD_PREP_CONST(NEO_OB_WB0_R_CTRL_CAM0_GAIN, 1 << 8) | + FIELD_PREP_CONST(NEO_OB_WB0_R_CTRL_CAM0_OFFSET, 0), + .gr_ctrl =3D + FIELD_PREP_CONST(NEO_OB_WB0_GR_CTRL_CAM0_GAIN, 1 << 8) | + FIELD_PREP_CONST(NEO_OB_WB0_GR_CTRL_CAM0_OFFSET, 0), + .gb_ctrl =3D + FIELD_PREP_CONST(NEO_OB_WB0_GB_CTRL_CAM0_GAIN, 1 << 8) | + FIELD_PREP_CONST(NEO_OB_WB0_GB_CTRL_CAM0_OFFSET, 0), + .b_ctrl =3D + FIELD_PREP_CONST(NEO_OB_WB0_B_CTRL_CAM0_GAIN, 1 << 8) | + FIELD_PREP_CONST(NEO_OB_WB0_B_CTRL_CAM0_OFFSET, 0), + }, + .obwb1 =3D { + .ctrl =3D + FIELD_PREP_CONST(NEO_OB_WB1_CTRL_CAM0_OBPP, 2), + .r_ctrl =3D + FIELD_PREP_CONST(NEO_OB_WB1_R_CTRL_CAM0_GAIN, 1 << 8) | + FIELD_PREP_CONST(NEO_OB_WB1_R_CTRL_CAM0_OFFSET, 0), + .gr_ctrl =3D + FIELD_PREP_CONST(NEO_OB_WB1_GR_CTRL_CAM0_GAIN, 1 << 8) | + FIELD_PREP_CONST(NEO_OB_WB1_GR_CTRL_CAM0_OFFSET, 0), + .gb_ctrl =3D + FIELD_PREP_CONST(NEO_OB_WB1_GB_CTRL_CAM0_GAIN, 1 << 8) | + FIELD_PREP_CONST(NEO_OB_WB1_GB_CTRL_CAM0_OFFSET, 0), + .b_ctrl =3D + FIELD_PREP_CONST(NEO_OB_WB1_B_CTRL_CAM0_GAIN, 1 << 8) | + FIELD_PREP_CONST(NEO_OB_WB1_B_CTRL_CAM0_OFFSET, 0), + }, + .obwb2 =3D { + .ctrl =3D + FIELD_PREP_CONST(NEO_OB_WB2_CTRL_CAM0_OBPP, 3), + .r_ctrl =3D + FIELD_PREP_CONST(NEO_OB_WB2_R_CTRL_CAM0_GAIN, 1 << 8) | + FIELD_PREP_CONST(NEO_OB_WB2_R_CTRL_CAM0_OFFSET, 0), + .gr_ctrl =3D + FIELD_PREP_CONST(NEO_OB_WB2_GR_CTRL_CAM0_GAIN, 1 << 8) | + FIELD_PREP_CONST(NEO_OB_WB2_GR_CTRL_CAM0_OFFSET, 0), + .gb_ctrl =3D + FIELD_PREP_CONST(NEO_OB_WB2_GB_CTRL_CAM0_GAIN, 1 << 8) | + FIELD_PREP_CONST(NEO_OB_WB2_GB_CTRL_CAM0_OFFSET, 0), + .b_ctrl =3D + FIELD_PREP_CONST(NEO_OB_WB2_B_CTRL_CAM0_GAIN, 1 << 8) | + FIELD_PREP_CONST(NEO_OB_WB2_B_CTRL_CAM0_OFFSET, 0), + }, + .hdr_merge =3D { + .ctrl =3D + FIELD_PREP_CONST(NEO_HDR_MERGE_CTRL_CAM0_ENABLE, 0) | + FIELD_PREP_CONST(NEO_HDR_MERGE_CTRL_CAM0_GAIN1BPP, 3) | + FIELD_PREP_CONST(NEO_HDR_MERGE_CTRL_CAM0_GAIN0BPP, 3) | + FIELD_PREP_CONST(NEO_HDR_MERGE_CTRL_CAM0_OBPP, 3), + .gain_scale =3D + FIELD_PREP_CONST(NEO_HDR_MERGE_GAIN_SCALE_CAM0_SCALE1, 8) | + FIELD_PREP_CONST(NEO_HDR_MERGE_GAIN_SCALE_CAM0_SCALE0, 1 << 12), + .gain_shift =3D + FIELD_PREP_CONST(NEO_HDR_MERGE_GAIN_SHIFT_CAM0_SHIFT1, 12) | + FIELD_PREP_CONST(NEO_HDR_MERGE_GAIN_SHIFT_CAM0_SHIFT0, 4), + .luma_th =3D + FIELD_PREP_CONST(NEO_HDR_MERGE_LUMA_TH_CAM0_TH0, 4), + .luma_scale =3D + FIELD_PREP_CONST(NEO_HDR_MERGE_LUMA_SCALE_CAM0_SCALE, 1 << 8) | + FIELD_PREP_CONST(NEO_HDR_MERGE_LUMA_SCALE_CAM0_SHIFT, 8) | + FIELD_PREP_CONST(NEO_HDR_MERGE_LUMA_SCALE_CAM0_THSHIFT, 8), + .downscale =3D + FIELD_PREP_CONST(NEO_HDR_MERGE_DOWNSCALE_CAM0_IMGSCALE0, 8), + .upscale =3D + FIELD_PREP_CONST(NEO_HDR_MERGE_UPSCALE_CAM0_IMGSCALE1, 8), + }, + .ctemp =3D {}, + .rgbir =3D { + .ctrl =3D + FIELD_PREP_CONST(NEO_RGBIR_CTRL_CAM0_ENABLE, 0), + .ccm0 =3D + FIELD_PREP_CONST(NEO_RGBIR_CCM0_CAM0_CCM, 1 << 8), + .ccm1 =3D + FIELD_PREP_CONST(NEO_RGBIR_CCM1_CAM0_CCM, 1 << 8), + .ccm2 =3D + FIELD_PREP_CONST(NEO_RGBIR_CCM2_CAM0_CCM, 1 << 8), + .ccm0_th =3D + FIELD_PREP_CONST(NEO_RGBIR_CCM0_TH_CAM0_THRESHOLD, 0xff000), + .ccm1_th =3D + FIELD_PREP_CONST(NEO_RGBIR_CCM1_TH_CAM0_THRESHOLD, 0xff000), + .ccm2_th =3D + FIELD_PREP_CONST(NEO_RGBIR_CCM2_TH_CAM0_THRESHOLD, 0xff000), + }, + .stat =3D {}, + .ir_compress =3D { + .ctrl =3D + FIELD_PREP_CONST(NEO_IR_COMPRESS_CTRL_CAM0_ENABLE, 0) | + FIELD_PREP_CONST(NEO_IR_COMPRESS_CTRL_CAM0_OBPP, 0), + .knee_point1 =3D + FIELD_PREP_CONST(NEO_IR_COMPRESS_KNEE_POINT1_CAM0_KNEEPOINT, + (1 << 20) - 1), + .knee_ratio01 =3D + FIELD_PREP_CONST(NEO_IR_COMPRESS_KNEE_RATIO01_CAM0_RATIO0, 8), + .knee_ratio4 =3D + FIELD_PREP_CONST(NEO_IR_COMPRESS_KNEE_RATIO4_CAM0_RATIO4, 8), + }, + .bnr =3D { + .ctrl =3D + FIELD_PREP_CONST(NEO_BNR_CTRL_CAM0_ENABLE, 1) | + FIELD_PREP_CONST(NEO_BNR_CTRL_CAM0_NHOOD, 0) | + FIELD_PREP_CONST(NEO_BNR_CTRL_CAM0_DEBUG, 0) | + FIELD_PREP_CONST(NEO_BNR_CTRL_CAM0_OBPP, 3), + .ypeak =3D + FIELD_PREP_CONST(NEO_BNR_YPEAK_CAM0_PEAK_OUTSEL, 0) | + FIELD_PREP_CONST(NEO_BNR_YPEAK_CAM0_PEAK_HIGH, 1 << 8) | + FIELD_PREP_CONST(NEO_BNR_YPEAK_CAM0_PEAK_SEL, 0) | + FIELD_PREP_CONST(NEO_BNR_YPEAK_CAM0_PEAK_LOW, 1 << 7), + .yedge_th0 =3D + FIELD_PREP_CONST(NEO_BNR_YEDGE_TH0_CAM0_EDGE_TH0, 20), + .yedge_scale =3D + FIELD_PREP_CONST(NEO_BNR_YEDGE_SCALE_CAM0_SHIFT, 10) | + FIELD_PREP_CONST(NEO_BNR_YEDGE_SCALE_CAM0_SCALE, 1 << 10), + .yedges_th0 =3D + FIELD_PREP_CONST(NEO_BNR_YEDGES_TH0_CAM0_EDGE_TH0, 20), + .yedges_scale =3D + FIELD_PREP_CONST(NEO_BNR_YEDGES_SCALE_CAM0_SHIFT, 10) | + FIELD_PREP_CONST(NEO_BNR_YEDGES_SCALE_CAM0_SCALE, 1 << 10), + .yedgea_th0 =3D + FIELD_PREP_CONST(NEO_BNR_YEDGEA_TH0_CAM0_EDGE_TH0, 20), + .yedgea_scale =3D + FIELD_PREP_CONST(NEO_BNR_YEDGEA_SCALE_CAM0_SHIFT, 10) | + FIELD_PREP_CONST(NEO_BNR_YEDGEA_SCALE_CAM0_SCALE, 10), + .yluma_x_th0 =3D + FIELD_PREP_CONST(NEO_BNR_YLUMA_X_TH0_CAM0_TH, 20), + .yluma_y_th =3D + FIELD_PREP_CONST(NEO_BNR_YLUMA_Y_TH_CAM0_LUMA_Y_TH1, 1 << 8) | + FIELD_PREP_CONST(NEO_BNR_YLUMA_Y_TH_CAM0_LUMA_Y_TH0, 10), + .yluma_scale =3D + FIELD_PREP_CONST(NEO_BNR_YLUMA_SCALE_CAM0_SHIFT, 10) | + FIELD_PREP_CONST(NEO_BNR_YLUMA_SCALE_CAM0_SCALE, 1 << 10), + .yalpha_gain =3D + FIELD_PREP_CONST(NEO_BNR_YALPHA_GAIN_CAM0_OFFSET, 0) | + FIELD_PREP_CONST(NEO_BNR_YALPHA_GAIN_CAM0_GAIN, 1 << 8), + .cpeak =3D + FIELD_PREP_CONST(NEO_BNR_CPEAK_CAM0_PEAK_OUTSEL, 0) | + FIELD_PREP_CONST(NEO_BNR_CPEAK_CAM0_PEAK_HIGH, 1 << 8) | + FIELD_PREP_CONST(NEO_BNR_CPEAK_CAM0_PEAK_SEL, 0) | + FIELD_PREP_CONST(NEO_BNR_CPEAK_CAM0_PEAK_LOW, 1 << 7), + .cedge_th0 =3D + FIELD_PREP_CONST(NEO_BNR_CEDGE_TH0_CAM0_EDGE_TH0, 20), + .cedge_scale =3D + FIELD_PREP_CONST(NEO_BNR_CEDGE_SCALE_CAM0_SHIFT, 10) | + FIELD_PREP_CONST(NEO_BNR_CEDGE_SCALE_CAM0_SCALE, 1 << 10), + .cedges_th0 =3D + FIELD_PREP_CONST(NEO_BNR_CEDGES_TH0_CAM0_EDGE_TH0, 20), + .cedges_scale =3D + FIELD_PREP_CONST(NEO_BNR_CEDGES_SCALE_CAM0_SHIFT, 10) | + FIELD_PREP_CONST(NEO_BNR_CEDGES_SCALE_CAM0_SCALE, 1 << 10), + .cedgea_th0 =3D + FIELD_PREP_CONST(NEO_BNR_CEDGEA_TH0_CAM0_EDGE_TH0, 20), + .cedgea_scale =3D + FIELD_PREP_CONST(NEO_BNR_CEDGEA_SCALE_CAM0_SHIFT, 10) | + FIELD_PREP_CONST(NEO_BNR_CEDGEA_SCALE_CAM0_SCALE, 1 << 10), + .cluma_x_th0 =3D + FIELD_PREP_CONST(NEO_BNR_CLUMA_X_TH0_CAM0_TH, 20), + .cluma_y_th =3D + FIELD_PREP_CONST(NEO_BNR_CLUMA_Y_TH_CAM0_LUMA_Y_TH1, 1 << 8) | + FIELD_PREP_CONST(NEO_BNR_CLUMA_Y_TH_CAM0_LUMA_Y_TH0, 10), + .cluma_scale =3D + FIELD_PREP_CONST(NEO_BNR_CLUMA_SCALE_CAM0_SHIFT, 10) | + FIELD_PREP_CONST(NEO_BNR_CLUMA_SCALE_CAM0_SCALE, 1 << 10), + .calpha_gain =3D + FIELD_PREP_CONST(NEO_BNR_CALPHA_GAIN_CAM0_OFFSET, 0) | + FIELD_PREP_CONST(NEO_BNR_CALPHA_GAIN_CAM0_GAIN, 1 << 8), + .stretch =3D + FIELD_PREP_CONST(NEO_BNR_STRETCH_CAM0_GAIN, 1 << 8), + }, + .idbg1 =3D { + .line_num_t =3D + NEO_IDBG1_LINE_NUM_LINE_NUM, + }, + .demosaic =3D { + .ctrl =3D + FIELD_PREP_CONST(NEO_DEMOSAIC_CTRL_CAM0_FMT, 0), + .activity_ctl =3D + FIELD_PREP_CONST(NEO_DEMOSAIC_ACTIVITY_CTL_CAM0_ACT_RATIO, 1 << 8) | + FIELD_PREP_CONST(NEO_DEMOSAIC_ACTIVITY_CTL_CAM0_ALPHA, 1 << 8), + .dynamics_ctl0 =3D + FIELD_PREP_CONST(NEO_DEMOSAIC_DYNAMICS_CTL0_CAM0_STRENGTHC, + 1 << 8) | + FIELD_PREP_CONST(NEO_DEMOSAIC_DYNAMICS_CTL0_CAM0_STRENGTHG, + 1 << 8), + .dynamics_ctl2 =3D + FIELD_PREP_CONST(NEO_DEMOSAIC_DYNAMICS_CTL2_CAM0_MAX_IMPACT, + 1 << 7), + }, + .rgb2yuv =3D { + .gain_ctrl =3D + FIELD_PREP_CONST(NEO_RGB_TO_YUV_GAIN_CTRL_CAM0_BGAIN, 1 << 8) | + FIELD_PREP_CONST(NEO_RGB_TO_YUV_GAIN_CTRL_CAM0_RGAIN, 1 << 8), + /* Constants defined by V4L2_YCBCR_ENC_601, full range and + * formatted in s8.8. This matrix will define the gcm.imat_rxcy + * as its inverse. + * https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/color= spaces-details.html + * {77, 150, 29}, + * {-43, -85, 128}, + * {128, -107, -21}, + */ + .mat0 =3D + FIELD_PREP_CONST(NEO_RGB_TO_YUV_MAT0_CAM0_R0C0, 77) | + FIELD_PREP_CONST(NEO_RGB_TO_YUV_MAT0_CAM0_R0C1, 150), + .mat1 =3D + FIELD_PREP_CONST(NEO_RGB_TO_YUV_MAT1_CAM0_R0C2, 29), + .mat2 =3D + FIELD_PREP_S16_CONST(NEO_RGB_TO_YUV_MAT2_CAM0_R1C0, -43) | + FIELD_PREP_S16_CONST(NEO_RGB_TO_YUV_MAT2_CAM0_R1C1, -85), + .mat3 =3D + FIELD_PREP_CONST(NEO_RGB_TO_YUV_MAT3_CAM0_R1C2, 128), + .mat4 =3D + FIELD_PREP_CONST(NEO_RGB_TO_YUV_MAT4_CAM0_R2C0, 128) | + FIELD_PREP_S16_CONST(NEO_RGB_TO_YUV_MAT4_CAM0_R2C1, -107), + .mat5 =3D + FIELD_PREP_S16_CONST(NEO_RGB_TO_YUV_MAT5_CAM0_R2C2, -21), + }, + .drc =3D { + .gbl_gain =3D + FIELD_PREP_CONST(NEO_DRC_GBL_GAIN_CAM0_GAIN, 1 << 8), + .lcl_stretch =3D + FIELD_PREP_CONST(NEO_DRC_LCL_STRETCH_CAM0_STRETCH, 1 << 8), + .alpha =3D + FIELD_PREP_CONST(NEO_DRC_ALPHA_CAM0_ALPHA, 1 << 8), + }, + .cas =3D { + .gain =3D + FIELD_PREP_CONST(NEO_CAS_GAIN_CAM0_SCALE, 1), + }, + .packetizer =3D { + .ch0_ctrl =3D + FIELD_PREP_CONST(NEO_PACKETIZER_CH0_CTRL_CAM0_OBPP, 6) | + FIELD_PREP_CONST(NEO_PACKETIZER_CH0_CTRL_CAM0_RSA, 4) | + FIELD_PREP_CONST(NEO_PACKETIZER_CH0_CTRL_CAM0_LSA, 0), + .ch12_ctrl =3D + FIELD_PREP_CONST(NEO_PACKETIZER_CH12_CTRL_CAM0_OBPP, 6) | + FIELD_PREP_CONST(NEO_PACKETIZER_CH12_CTRL_CAM0_RSA, 4) | + FIELD_PREP_CONST(NEO_PACKETIZER_CH12_CTRL_CAM0_LSA, 0) | + FIELD_PREP_CONST(NEO_PACKETIZER_CH12_CTRL_CAM0_SUBSAMPLE, 0), + .pack_ctrl =3D + FIELD_PREP_CONST(NEO_PACKETIZER_PACK_CTRL_CAM0_TYPE, 1) | + FIELD_PREP_CONST(NEO_PACKETIZER_PACK_CTRL_CAM0_ORDER0, 0) | + FIELD_PREP_CONST(NEO_PACKETIZER_PACK_CTRL_CAM0_ORDER1, 1) | + FIELD_PREP_CONST(NEO_PACKETIZER_PACK_CTRL_CAM0_ORDER2, 2) | + FIELD_PREP_CONST(NEO_PACKETIZER_PACK_CTRL_CAM0_A0S, 0), + }, + .gcm =3D { + .imat0 =3D + FIELD_PREP_CONST(NEO_GCM_IMAT0_CAM0_R0C0, 256) | + FIELD_PREP_CONST(NEO_GCM_IMAT0_CAM0_R0C1, 0), + .imat1 =3D + FIELD_PREP_CONST(NEO_GCM_IMAT1_CAM0_R0C2, 359), + .imat2 =3D + FIELD_PREP_CONST(NEO_GCM_IMAT2_CAM0_R1C0, 256) | + FIELD_PREP_S16_CONST(NEO_GCM_IMAT2_CAM0_R1C1, -88), + .imat3 =3D + FIELD_PREP_S16_CONST(NEO_GCM_IMAT3_CAM0_R1C2, -183), + .imat4 =3D + FIELD_PREP_CONST(NEO_GCM_IMAT4_CAM0_R2C0, 256) | + FIELD_PREP_CONST(NEO_GCM_IMAT4_CAM0_R2C1, 454), + .imat5 =3D + FIELD_PREP_CONST(NEO_GCM_IMAT5_CAM0_R2C2, 0), + .omat0 =3D + FIELD_PREP_CONST(NEO_GCM_OMAT0_CAM0_R0C0, 256), + .omat2 =3D + FIELD_PREP_CONST(NEO_GCM_OMAT2_CAM0_R1C1, 256), + .omat5 =3D + FIELD_PREP_CONST(NEO_GCM_OMAT5_CAM0_R2C2, 256), + .mat_confg =3D + FIELD_PREP_CONST(NEO_GCM_MAT_CONFG_CAM0_SIGN_CONFG, 1), + }, + }, + .gtm =3D { + /* Fill default global tonemap lut with 1.0 value (256) */ + .drc_global_tonemap =3D { [0 ... NEO_DRC_GLOBAL_TONEMAP_SIZE - 1] =3D (1= << 8) }, + }, +}; + +union neoisp_params_block_u { + struct v4l2_isp_block_header header; + struct neoisp_pipe_conf_cfg_es pipe_conf; + struct neoisp_head_color_cfg_es head_color; + struct neoisp_hdr_decompress0_cfg_es hdr_decompress0; + struct neoisp_hdr_decompress1_cfg_es hdr_decompress1; + struct neoisp_obwb_cfg_es obwb; + struct neoisp_hdr_merge_cfg_es hdr_merge; + struct neoisp_rgbir_cfg_es rgbir; + struct neoisp_stat_cfg_es stat; + struct neoisp_ir_compress_cfg_es ir_compress; + struct neoisp_bnr_cfg_es bnr; + struct neoisp_vignetting_ctrl_cfg_es vignetting_ctrl; + struct neoisp_ctemp_cfg_es ctemp; + struct neoisp_demosaic_cfg_es demosaic; + struct neoisp_rgb2yuv_cfg_es rgb2yuv; + struct neoisp_dr_comp_cfg_es dr_comp; + struct neoisp_nr_cfg_es nr; + struct neoisp_af_cfg_es af; + struct neoisp_ee_cfg_es ee; + struct neoisp_df_cfg_es df; + struct neoisp_convmed_cfg_es convmed; + struct neoisp_cas_cfg_es cas; + struct neoisp_gcm_cfg_es gcm; + struct neoisp_vignetting_table_mem_params_es vignetting_table; + struct neoisp_drc_global_tonemap_mem_params_es drc_global_tonemap; + struct neoisp_drc_local_tonemap_mem_params_es drc_local_tonemap; +}; + +union neoisp_stats_block_u { + struct v4l2_isp_block_header header; + struct neoisp_ctemp_reg_stats_es rctemp; + struct neoisp_drc_reg_stats_es rdrc; + struct neoisp_af_reg_stats_es raf; + struct neoisp_bnr_reg_stats_es rbnr; + struct neoisp_nr_reg_stats_es rnr; + struct neoisp_ee_reg_stats_es ree; + struct neoisp_df_reg_stats_es rdf; + struct neoisp_ctemp_mem_stats_es mctemp; + struct neoisp_rgbir_mem_stats_es mrgbir; + struct neoisp_hist_mem_stats_es mhist; + struct neoisp_drc_mem_stats_es mdrc; +}; + +static dma_addr_t get_addr(struct neoisp_buffer_s *buf, u32 num_plane) +{ + if (buf) + return vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, num_plane); + return 0; +} + +static u32 *get_vaddr(struct neoisp_buffer_s *buf) +{ + if (buf) + return vb2_plane_vaddr(&buf->vb.vb2_buf, 0); + return NULL; +} + +/* + * Extract offset and size in bytes from memory region map + */ +static inline void get_offsize(enum isp_block_map_e map, u32 *offset, u32 = *size) +{ + *offset =3D ISP_GET_OFF(map); + *size =3D ISP_GET_SZ(map); +} + +static inline void +local_mem_blk_write(struct neoisp_dev_s *neoispd, enum isp_block_map_e map= , void *src) +{ + u32 offset, count; + + get_offsize(map, &offset, &count); + memcpy(neoispd->local_mem + offset, src, count); +} + +static inline void +local_mem_blk_read(struct neoisp_dev_s *neoispd, enum isp_block_map_e map,= void *dst) +{ + u32 offset, count; + + get_offsize(map, &offset, &count); + memcpy(dst, neoispd->local_mem + offset, count); +} + +static inline void +reg_blk_write(struct neoisp_dev_s *neoispd, u32 offset, u32 *src, size_t c= ount) +{ + size_t size =3D 0; + + while (size < count) { + neoisp_wr(neoispd, offset + size, *src++); + size +=3D sizeof(u32); + } +} + +static inline void +reg_blk_read(struct neoisp_dev_s *neoispd, u32 offset, u32 *dst, size_t co= unt) +{ + size_t size =3D 0; + + while (size < count) { + *dst++ =3D neoisp_rd(neoispd, offset + size); + size +=3D sizeof(u32); + } +} + +/*------------------------------------------------------------------------= ------ + * Extensible parameters format handling + */ +static void +neoisp_params_handler_pipe_conf(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + struct neoisp_pipe_conf_s *pc =3D &ctx->hw.pipe_conf; + const struct neoisp_pipe_conf_cfg_s *cfg; + + if (block->header.size =3D=3D sizeof(struct v4l2_isp_block_header)) + /* nothing to do */ + return; + + cfg =3D &block->pipe_conf.cfg; + + FIELD_MODIFY(NEO_PIPE_CONF_IMG_CONF_CAM0_INALIGN0, + &pc->img_conf, cfg->img_conf_inalign0); + FIELD_MODIFY(NEO_PIPE_CONF_IMG_CONF_CAM0_LPALIGN0, + &pc->img_conf, cfg->img_conf_lpalign0); + FIELD_MODIFY(NEO_PIPE_CONF_IMG_CONF_CAM0_INALIGN1, + &pc->img_conf, cfg->img_conf_inalign1); + FIELD_MODIFY(NEO_PIPE_CONF_IMG_CONF_CAM0_LPALIGN1, + &pc->img_conf, cfg->img_conf_lpalign1); +} + +static void +neoisp_params_handler_head_color(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + struct neoisp_hc_s *hc =3D &ctx->hw.hc; + const struct neoisp_head_color_cfg_s *cfg; + + if (block->header.size =3D=3D sizeof(struct v4l2_isp_block_header)) + /* nothing to do */ + return; + + cfg =3D &block->head_color.cfg; + + hc->ctrl =3D + FIELD_PREP(NEO_HC_CTRL_CAM0_HOFFSET, cfg->ctrl_hoffset) | + FIELD_PREP(NEO_HC_CTRL_CAM0_VOFFSET, cfg->ctrl_voffset); +} + +static void +neoisp_params_handler_hdr_decompress0(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + struct neoisp_hdr_decompress0_s *hd0 =3D &ctx->hw.hdr_decompress0; + const struct neoisp_hdr_decompress0_cfg_s *cfg; + + if (block->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_DISABLE) + FIELD_MODIFY(NEO_HDR_DECOMPRESS0_CTRL_CAM0_ENABLE, &hd0->ctrl, 0); + else if (block->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_ENABLE) + FIELD_MODIFY(NEO_HDR_DECOMPRESS0_CTRL_CAM0_ENABLE, &hd0->ctrl, 1); + + if (block->header.size =3D=3D sizeof(struct v4l2_isp_block_header)) + /* nothing else to do */ + return; + + cfg =3D &block->hdr_decompress0.cfg; + + hd0->knee_point1 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS0_KNEE_POINT1_CAM0_KNEEPOINT, cfg->knee_poi= nt1); + hd0->knee_point2 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS0_KNEE_POINT2_CAM0_KNEEPOINT, cfg->knee_poi= nt2); + hd0->knee_point3 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS0_KNEE_POINT3_CAM0_KNEEPOINT, cfg->knee_poi= nt3); + hd0->knee_point4 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS0_KNEE_POINT4_CAM0_KNEEPOINT, cfg->knee_poi= nt4); + hd0->knee_offset0 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS0_KNEE_OFFSET0_CAM0_OFFSET, cfg->knee_offse= t0); + hd0->knee_offset1 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS0_KNEE_OFFSET1_CAM0_OFFSET, cfg->knee_offse= t1); + hd0->knee_offset2 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS0_KNEE_OFFSET2_CAM0_OFFSET, cfg->knee_offse= t2); + hd0->knee_offset3 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS0_KNEE_OFFSET3_CAM0_OFFSET, cfg->knee_offse= t3); + hd0->knee_offset4 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS0_KNEE_OFFSET4_CAM0_OFFSET, cfg->knee_offse= t4); + hd0->knee_ratio01 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS0_KNEE_RATIO01_CAM0_RATIO0, cfg->knee_ratio= 0) | + FIELD_PREP(NEO_HDR_DECOMPRESS0_KNEE_RATIO01_CAM0_RATIO1, cfg->knee_ratio= 1); + hd0->knee_ratio23 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS0_KNEE_RATIO23_CAM0_RATIO2, cfg->knee_ratio= 2) | + FIELD_PREP(NEO_HDR_DECOMPRESS0_KNEE_RATIO23_CAM0_RATIO3, cfg->knee_ratio= 3); + hd0->knee_ratio4 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS0_KNEE_RATIO4_CAM0_RATIO4, cfg->knee_ratio4= ); + hd0->knee_npoint0 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS0_KNEE_NPOINT0_CAM0_KNEEPOINT, cfg->knee_np= oint0); + hd0->knee_npoint1 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS0_KNEE_NPOINT1_CAM0_KNEEPOINT, cfg->knee_np= oint1); + hd0->knee_npoint2 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS0_KNEE_NPOINT2_CAM0_KNEEPOINT, cfg->knee_np= oint2); + hd0->knee_npoint3 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS0_KNEE_NPOINT3_CAM0_KNEEPOINT, cfg->knee_np= oint3); + hd0->knee_npoint4 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS0_KNEE_NPOINT4_CAM0_KNEEPOINT, cfg->knee_np= oint4); +} + +static void +neoisp_params_handler_hdr_decompress1(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + struct neoisp_hdr_decompress1_s *hd1 =3D &ctx->hw.hdr_decompress1; + const struct neoisp_hdr_decompress1_cfg_s *cfg; + + if (block->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_DISABLE) + FIELD_MODIFY(NEO_HDR_DECOMPRESS1_CTRL_CAM0_ENABLE, &hd1->ctrl, 0); + else if (block->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_ENABLE) + FIELD_MODIFY(NEO_HDR_DECOMPRESS1_CTRL_CAM0_ENABLE, &hd1->ctrl, 1); + + if (block->header.size =3D=3D sizeof(struct v4l2_isp_block_header)) + /* nothing else to do */ + return; + + cfg =3D &block->hdr_decompress1.cfg; + + hd1->knee_point1 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS1_KNEE_POINT1_CAM0_KNEEPOINT, cfg->knee_poi= nt1); + hd1->knee_point2 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS1_KNEE_POINT2_CAM0_KNEEPOINT, cfg->knee_poi= nt2); + hd1->knee_point3 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS1_KNEE_POINT3_CAM0_KNEEPOINT, cfg->knee_poi= nt3); + hd1->knee_point4 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS1_KNEE_POINT4_CAM0_KNEEPOINT, cfg->knee_poi= nt4); + hd1->knee_offset0 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS1_KNEE_OFFSET0_CAM0_OFFSET, cfg->knee_offse= t0); + hd1->knee_offset1 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS1_KNEE_OFFSET1_CAM0_OFFSET, cfg->knee_offse= t1); + hd1->knee_offset2 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS1_KNEE_OFFSET2_CAM0_OFFSET, cfg->knee_offse= t2); + hd1->knee_offset3 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS1_KNEE_OFFSET3_CAM0_OFFSET, cfg->knee_offse= t3); + hd1->knee_offset4 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS1_KNEE_OFFSET4_CAM0_OFFSET, cfg->knee_offse= t4); + hd1->knee_ratio01 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS1_KNEE_RATIO01_CAM0_RATIO0, cfg->knee_ratio= 0) | + FIELD_PREP(NEO_HDR_DECOMPRESS1_KNEE_RATIO01_CAM0_RATIO1, cfg->knee_ratio= 1); + hd1->knee_ratio23 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS1_KNEE_RATIO23_CAM0_RATIO2, cfg->knee_ratio= 2) | + FIELD_PREP(NEO_HDR_DECOMPRESS1_KNEE_RATIO23_CAM0_RATIO3, cfg->knee_ratio= 3); + hd1->knee_ratio4 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS1_KNEE_RATIO4_CAM0_RATIO4, cfg->knee_ratio4= ); + hd1->knee_npoint0 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS1_KNEE_NPOINT0_CAM0_KNEEPOINT, cfg->knee_np= oint0); + hd1->knee_npoint1 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS1_KNEE_NPOINT1_CAM0_KNEEPOINT, cfg->knee_np= oint1); + hd1->knee_npoint2 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS1_KNEE_NPOINT2_CAM0_KNEEPOINT, cfg->knee_np= oint2); + hd1->knee_npoint3 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS1_KNEE_NPOINT3_CAM0_KNEEPOINT, cfg->knee_np= oint3); + hd1->knee_npoint4 =3D + FIELD_PREP(NEO_HDR_DECOMPRESS1_KNEE_NPOINT4_CAM0_KNEEPOINT, cfg->knee_np= oint4); +} + +static void +__neoisp_params_handler_obwb(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block, + u8 id) +{ + struct neoisp_obwb_s *obwb; + const struct neoisp_obwb_cfg_s *cfg; + + if (block->header.size =3D=3D sizeof(struct v4l2_isp_block_header)) + /* nothing to do */ + return; + + switch (id) { + case 0: + obwb =3D &ctx->hw.obwb0; + break; + case 1: + obwb =3D &ctx->hw.obwb1; + break; + case 2: + obwb =3D &ctx->hw.obwb2; + break; + default: + return; + } + + cfg =3D &block->obwb.cfg; + + obwb->ctrl =3D + FIELD_PREP(NEO_OB_WB0_CTRL_CAM0_OBPP, cfg->ctrl_obpp); + obwb->r_ctrl =3D + FIELD_PREP(NEO_OB_WB0_R_CTRL_CAM0_OFFSET, cfg->r_ctrl_offset) | + FIELD_PREP(NEO_OB_WB0_R_CTRL_CAM0_GAIN, cfg->r_ctrl_gain); + obwb->gr_ctrl =3D + FIELD_PREP(NEO_OB_WB0_GR_CTRL_CAM0_OFFSET, cfg->gr_ctrl_offset) | + FIELD_PREP(NEO_OB_WB0_GR_CTRL_CAM0_GAIN, cfg->gr_ctrl_gain); + obwb->gb_ctrl =3D + FIELD_PREP(NEO_OB_WB0_GB_CTRL_CAM0_OFFSET, cfg->gb_ctrl_offset) | + FIELD_PREP(NEO_OB_WB0_GB_CTRL_CAM0_GAIN, cfg->gb_ctrl_gain); + obwb->b_ctrl =3D + FIELD_PREP(NEO_OB_WB0_B_CTRL_CAM0_OFFSET, cfg->b_ctrl_offset) | + FIELD_PREP(NEO_OB_WB0_B_CTRL_CAM0_GAIN, cfg->b_ctrl_gain); +} + +static void neoisp_params_handler_obwb0(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + __neoisp_params_handler_obwb(ctx, block, 0); +} + +static void neoisp_params_handler_obwb1(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + __neoisp_params_handler_obwb(ctx, block, 1); +} + +static void neoisp_params_handler_obwb2(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + __neoisp_params_handler_obwb(ctx, block, 2); +} + +static void +neoisp_params_handler_hdr_merge(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + struct neoisp_hdr_merge_s *hmg =3D &ctx->hw.hdr_merge; + const struct neoisp_hdr_merge_cfg_s *cfg; + + if (block->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_DISABLE) + FIELD_MODIFY(NEO_HDR_MERGE_CTRL_CAM0_ENABLE, &hmg->ctrl, 0); + else if (block->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_ENABLE) + FIELD_MODIFY(NEO_HDR_MERGE_CTRL_CAM0_ENABLE, &hmg->ctrl, 1); + + if (block->header.size =3D=3D sizeof(struct v4l2_isp_block_header)) + /* nothing else to do */ + return; + + cfg =3D &block->hdr_merge.cfg; + + FIELD_MODIFY(NEO_HDR_MERGE_CTRL_CAM0_OBPP, &hmg->ctrl, cfg->ctrl_obpp); + FIELD_MODIFY(NEO_HDR_MERGE_CTRL_CAM0_MOTION_FIX_EN, &hmg->ctrl, cfg->ctrl= _motion_fix_en); + FIELD_MODIFY(NEO_HDR_MERGE_CTRL_CAM0_BLEND_3X3, &hmg->ctrl, cfg->ctrl_ble= nd_3x3); + FIELD_MODIFY(NEO_HDR_MERGE_CTRL_CAM0_GAIN0BPP, &hmg->ctrl, cfg->ctrl_gain= 0bpp); + FIELD_MODIFY(NEO_HDR_MERGE_CTRL_CAM0_GAIN1BPP, &hmg->ctrl, cfg->ctrl_gain= 1bpp); + + hmg->gain_offset =3D + FIELD_PREP(NEO_HDR_MERGE_GAIN_OFFSET_CAM0_OFFSET0, cfg->gain_offset_offs= et0) | + FIELD_PREP(NEO_HDR_MERGE_GAIN_OFFSET_CAM0_OFFSET1, cfg->gain_offset_offs= et1); + hmg->gain_scale =3D + FIELD_PREP(NEO_HDR_MERGE_GAIN_SCALE_CAM0_SCALE0, cfg->gain_scale_scale0)= | + FIELD_PREP(NEO_HDR_MERGE_GAIN_SCALE_CAM0_SCALE1, cfg->gain_scale_scale1); + hmg->gain_shift =3D + FIELD_PREP(NEO_HDR_MERGE_GAIN_SHIFT_CAM0_SHIFT0, cfg->gain_shift_shift0)= | + FIELD_PREP(NEO_HDR_MERGE_GAIN_SHIFT_CAM0_SHIFT1, cfg->gain_shift_shift1); + hmg->luma_th =3D + FIELD_PREP(NEO_HDR_MERGE_LUMA_TH_CAM0_TH0, cfg->luma_th_th0); + hmg->luma_scale =3D + FIELD_PREP(NEO_HDR_MERGE_LUMA_SCALE_CAM0_SCALE, cfg->luma_scale_scale) | + FIELD_PREP(NEO_HDR_MERGE_LUMA_SCALE_CAM0_SHIFT, cfg->luma_scale_shift) | + FIELD_PREP(NEO_HDR_MERGE_LUMA_SCALE_CAM0_THSHIFT, cfg->luma_scale_thshif= t); + hmg->downscale =3D + FIELD_PREP(NEO_HDR_MERGE_DOWNSCALE_CAM0_IMGSCALE0, cfg->downscale_imgsca= le0) | + FIELD_PREP(NEO_HDR_MERGE_DOWNSCALE_CAM0_IMGSCALE1, cfg->downscale_imgsca= le1); + hmg->upscale =3D + FIELD_PREP(NEO_HDR_MERGE_UPSCALE_CAM0_IMGSCALE0, cfg->upscale_imgscale0)= | + FIELD_PREP(NEO_HDR_MERGE_UPSCALE_CAM0_IMGSCALE1, cfg->upscale_imgscale1); + hmg->post_scale =3D + FIELD_PREP(NEO_HDR_MERGE_POST_SCALE_CAM0_SCALE, cfg->post_scale_scale); +} + +static void +neoisp_params_handler_rgbir(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + struct neoisp_rgbir_s *rgbir =3D &ctx->hw.rgbir; + const struct neoisp_rgbir_cfg_s *cfg; + const struct neoisp_stat_hist_cfg_s *hist; + + if (block->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_DISABLE) + FIELD_MODIFY(NEO_RGBIR_CTRL_CAM0_ENABLE, &rgbir->ctrl, 0); + else if (block->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_ENABLE) + FIELD_MODIFY(NEO_RGBIR_CTRL_CAM0_ENABLE, &rgbir->ctrl, 1); + + if (block->header.size =3D=3D sizeof(struct v4l2_isp_block_header)) + /* nothing else to do */ + return; + + cfg =3D &block->rgbir.cfg; + + rgbir->ccm0 =3D + FIELD_PREP(NEO_RGBIR_CCM0_CAM0_CCM, cfg->ccm0_ccm); + rgbir->ccm1 =3D + FIELD_PREP(NEO_RGBIR_CCM1_CAM0_CCM, cfg->ccm1_ccm); + rgbir->ccm2 =3D + FIELD_PREP(NEO_RGBIR_CCM2_CAM0_CCM, cfg->ccm2_ccm); + rgbir->ccm0_th =3D + FIELD_PREP(NEO_RGBIR_CCM0_TH_CAM0_THRESHOLD, cfg->ccm0_th_threshold); + rgbir->ccm1_th =3D + FIELD_PREP(NEO_RGBIR_CCM1_TH_CAM0_THRESHOLD, cfg->ccm1_th_threshold); + rgbir->ccm2_th =3D + FIELD_PREP(NEO_RGBIR_CCM2_TH_CAM0_THRESHOLD, cfg->ccm2_th_threshold); + rgbir->roi0_pos =3D + FIELD_PREP(NEO_RGBIR_ROI0_POS_CAM0_XPOS, cfg->roi[0].xpos) | + FIELD_PREP(NEO_RGBIR_ROI0_POS_CAM0_YPOS, cfg->roi[0].ypos); + rgbir->roi0_size =3D + FIELD_PREP(NEO_RGBIR_ROI0_SIZE_CAM0_WIDTH, cfg->roi[0].width) | + FIELD_PREP(NEO_RGBIR_ROI0_SIZE_CAM0_HEIGHT, cfg->roi[0].height); + rgbir->roi1_pos =3D + FIELD_PREP(NEO_RGBIR_ROI1_POS_CAM0_XPOS, cfg->roi[1].xpos) | + FIELD_PREP(NEO_RGBIR_ROI1_POS_CAM0_YPOS, cfg->roi[1].ypos); + rgbir->roi1_size =3D + FIELD_PREP(NEO_RGBIR_ROI1_SIZE_CAM0_WIDTH, cfg->roi[1].width) | + FIELD_PREP(NEO_RGBIR_ROI1_SIZE_CAM0_HEIGHT, cfg->roi[1].height); + + hist =3D &cfg->hists[0]; + rgbir->hist0_ctrl =3D + FIELD_PREP(NEO_RGBIR_HIST0_CTRL_CAM0_LIN_INPUT1_LOG, + hist->hist_ctrl_lin_input1_log) | + FIELD_PREP(NEO_RGBIR_HIST0_CTRL_CAM0_DIR_INPUT1_DIF, + hist->hist_ctrl_dir_input1_dif) | + FIELD_PREP(NEO_RGBIR_HIST0_CTRL_CAM0_PATTERN, hist->hist_ctrl_pattern) | + FIELD_PREP(NEO_RGBIR_HIST0_CTRL_CAM0_CHANNEL, hist->hist_ctrl_channel) | + FIELD_PREP(NEO_RGBIR_HIST0_CTRL_CAM0_OFFSET, hist->hist_ctrl_offset); + rgbir->hist0_scale =3D + FIELD_PREP(NEO_RGBIR_HIST0_SCALE_CAM0_SCALE, hist->hist_scale_scale); + + hist =3D &cfg->hists[1]; + rgbir->hist1_ctrl =3D + FIELD_PREP(NEO_RGBIR_HIST1_CTRL_CAM0_LIN_INPUT1_LOG, + hist->hist_ctrl_lin_input1_log) | + FIELD_PREP(NEO_RGBIR_HIST1_CTRL_CAM0_DIR_INPUT1_DIF, + hist->hist_ctrl_dir_input1_dif) | + FIELD_PREP(NEO_RGBIR_HIST1_CTRL_CAM0_PATTERN, hist->hist_ctrl_pattern) | + FIELD_PREP(NEO_RGBIR_HIST1_CTRL_CAM0_CHANNEL, hist->hist_ctrl_channel) | + FIELD_PREP(NEO_RGBIR_HIST1_CTRL_CAM0_OFFSET, hist->hist_ctrl_offset); + rgbir->hist1_scale =3D + FIELD_PREP(NEO_RGBIR_HIST1_SCALE_CAM0_SCALE, hist->hist_scale_scale); +} + +static void +neoisp_params_handler_stat(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + struct neoisp_stat_s *stat =3D &ctx->hw.stat; + const struct neoisp_stat_cfg_s *cfg; + const struct neoisp_stat_hist_cfg_s *hist; + + if (block->header.size =3D=3D sizeof(struct v4l2_isp_block_header)) + /* nothing to do */ + return; + + cfg =3D &block->stat.cfg; + + stat->roi0_pos =3D + FIELD_PREP(NEO_STAT_ROI0_POS_CAM0_XPOS, cfg->roi0.xpos) | + FIELD_PREP(NEO_STAT_ROI0_POS_CAM0_YPOS, cfg->roi0.ypos); + stat->roi0_size =3D + FIELD_PREP(NEO_STAT_ROI0_SIZE_CAM0_WIDTH, cfg->roi0.width) | + FIELD_PREP(NEO_STAT_ROI0_SIZE_CAM0_HEIGHT, cfg->roi0.height); + stat->roi1_pos =3D + FIELD_PREP(NEO_STAT_ROI1_POS_CAM0_XPOS, cfg->roi1.xpos) | + FIELD_PREP(NEO_STAT_ROI1_POS_CAM0_YPOS, cfg->roi1.ypos); + stat->roi1_size =3D + FIELD_PREP(NEO_STAT_ROI1_SIZE_CAM0_WIDTH, cfg->roi1.width) | + FIELD_PREP(NEO_STAT_ROI1_SIZE_CAM0_HEIGHT, cfg->roi1.height); + + hist =3D &cfg->hists[0]; + stat->hist0_ctrl =3D + FIELD_PREP(NEO_STAT_HIST0_CTRL_CAM0_LIN_INPUT1_LOG, + hist->hist_ctrl_lin_input1_log) | + FIELD_PREP(NEO_STAT_HIST0_CTRL_CAM0_DIR_INPUT1_DIF, + hist->hist_ctrl_dir_input1_dif) | + FIELD_PREP(NEO_STAT_HIST0_CTRL_CAM0_PATTERN, hist->hist_ctrl_pattern) | + FIELD_PREP(NEO_STAT_HIST0_CTRL_CAM0_CHANNEL, hist->hist_ctrl_channel) | + FIELD_PREP(NEO_STAT_HIST0_CTRL_CAM0_OFFSET, hist->hist_ctrl_offset); + stat->hist0_scale =3D + FIELD_PREP(NEO_STAT_HIST0_SCALE_CAM0_SCALE, hist->hist_scale_scale); + + hist =3D &cfg->hists[1]; + stat->hist1_ctrl =3D + FIELD_PREP(NEO_STAT_HIST1_CTRL_CAM0_LIN_INPUT1_LOG, + hist->hist_ctrl_lin_input1_log) | + FIELD_PREP(NEO_STAT_HIST1_CTRL_CAM0_DIR_INPUT1_DIF, + hist->hist_ctrl_dir_input1_dif) | + FIELD_PREP(NEO_STAT_HIST1_CTRL_CAM0_PATTERN, hist->hist_ctrl_pattern) | + FIELD_PREP(NEO_STAT_HIST1_CTRL_CAM0_CHANNEL, hist->hist_ctrl_channel) | + FIELD_PREP(NEO_STAT_HIST1_CTRL_CAM0_OFFSET, hist->hist_ctrl_offset); + stat->hist1_scale =3D + FIELD_PREP(NEO_STAT_HIST1_SCALE_CAM0_SCALE, hist->hist_scale_scale); + + hist =3D &cfg->hists[2]; + stat->hist2_ctrl =3D + FIELD_PREP(NEO_STAT_HIST2_CTRL_CAM0_LIN_INPUT1_LOG, + hist->hist_ctrl_lin_input1_log) | + FIELD_PREP(NEO_STAT_HIST2_CTRL_CAM0_DIR_INPUT1_DIF, + hist->hist_ctrl_dir_input1_dif) | + FIELD_PREP(NEO_STAT_HIST2_CTRL_CAM0_PATTERN, hist->hist_ctrl_pattern) | + FIELD_PREP(NEO_STAT_HIST2_CTRL_CAM0_CHANNEL, hist->hist_ctrl_channel) | + FIELD_PREP(NEO_STAT_HIST2_CTRL_CAM0_OFFSET, hist->hist_ctrl_offset); + stat->hist2_scale =3D + FIELD_PREP(NEO_STAT_HIST2_SCALE_CAM0_SCALE, hist->hist_scale_scale); + + hist =3D &cfg->hists[3]; + stat->hist3_ctrl =3D + FIELD_PREP(NEO_STAT_HIST2_CTRL_CAM0_LIN_INPUT1_LOG, + hist->hist_ctrl_lin_input1_log) | + FIELD_PREP(NEO_STAT_HIST2_CTRL_CAM0_DIR_INPUT1_DIF, + hist->hist_ctrl_dir_input1_dif) | + FIELD_PREP(NEO_STAT_HIST2_CTRL_CAM0_PATTERN, hist->hist_ctrl_pattern) | + FIELD_PREP(NEO_STAT_HIST2_CTRL_CAM0_CHANNEL, hist->hist_ctrl_channel) | + FIELD_PREP(NEO_STAT_HIST2_CTRL_CAM0_OFFSET, hist->hist_ctrl_offset); + stat->hist3_scale =3D + FIELD_PREP(NEO_STAT_HIST3_SCALE_CAM0_SCALE, hist->hist_scale_scale); +} + +static void +neoisp_params_handler_ir_compress(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + struct neoisp_ir_compress_s *ircomp =3D &ctx->hw.ir_compress; + const struct neoisp_ir_compress_cfg_s *cfg; + + if (block->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_DISABLE) + FIELD_MODIFY(NEO_IR_COMPRESS_CTRL_CAM0_ENABLE, &ircomp->ctrl, 0); + else if (block->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_ENABLE) + FIELD_MODIFY(NEO_IR_COMPRESS_CTRL_CAM0_ENABLE, &ircomp->ctrl, 1); + + if (block->header.size =3D=3D sizeof(struct v4l2_isp_block_header)) + /* nothing else to do */ + return; + + cfg =3D &block->ir_compress.cfg; + + FIELD_MODIFY(NEO_IR_COMPRESS_CTRL_CAM0_OBPP, &ircomp->ctrl, cfg->ctrl_obp= p); + + ircomp->knee_point1 =3D + FIELD_PREP(NEO_IR_COMPRESS_KNEE_POINT1_CAM0_KNEEPOINT, cfg->knee_point1_= kneepoint); + ircomp->knee_point2 =3D + FIELD_PREP(NEO_IR_COMPRESS_KNEE_POINT2_CAM0_KNEEPOINT, cfg->knee_point2_= kneepoint); + ircomp->knee_point3 =3D + FIELD_PREP(NEO_IR_COMPRESS_KNEE_POINT3_CAM0_KNEEPOINT, cfg->knee_point3_= kneepoint); + ircomp->knee_point4 =3D + FIELD_PREP(NEO_IR_COMPRESS_KNEE_POINT4_CAM0_KNEEPOINT, cfg->knee_point4_= kneepoint); + ircomp->knee_offset0 =3D + FIELD_PREP(NEO_IR_COMPRESS_KNEE_OFFSET0_CAM0_OFFSET, cfg->knee_offset0_o= ffset); + ircomp->knee_offset1 =3D + FIELD_PREP(NEO_IR_COMPRESS_KNEE_OFFSET1_CAM0_OFFSET, cfg->knee_offset1_o= ffset); + ircomp->knee_offset2 =3D + FIELD_PREP(NEO_IR_COMPRESS_KNEE_OFFSET2_CAM0_OFFSET, cfg->knee_offset2_o= ffset); + ircomp->knee_offset3 =3D + FIELD_PREP(NEO_IR_COMPRESS_KNEE_OFFSET3_CAM0_OFFSET, cfg->knee_offset3_o= ffset); + ircomp->knee_offset4 =3D + FIELD_PREP(NEO_IR_COMPRESS_KNEE_OFFSET4_CAM0_OFFSET, cfg->knee_offset4_o= ffset); + ircomp->knee_ratio01 =3D + FIELD_PREP(NEO_IR_COMPRESS_KNEE_RATIO01_CAM0_RATIO0, cfg->knee_ratio01_r= atio0) | + FIELD_PREP(NEO_IR_COMPRESS_KNEE_RATIO01_CAM0_RATIO1, cfg->knee_ratio01_r= atio1); + ircomp->knee_ratio23 =3D + FIELD_PREP(NEO_IR_COMPRESS_KNEE_RATIO23_CAM0_RATIO2, cfg->knee_ratio23_r= atio2) | + FIELD_PREP(NEO_IR_COMPRESS_KNEE_RATIO23_CAM0_RATIO3, cfg->knee_ratio23_r= atio3); + ircomp->knee_ratio4 =3D + FIELD_PREP(NEO_IR_COMPRESS_KNEE_RATIO4_CAM0_RATIO4, cfg->knee_ratio4_rat= io4); + ircomp->knee_npoint0 =3D + FIELD_PREP(NEO_IR_COMPRESS_KNEE_NPOINT0_CAM0_KNEEPOINT, + cfg->knee_npoint0_kneepoint); + ircomp->knee_npoint1 =3D + FIELD_PREP(NEO_IR_COMPRESS_KNEE_NPOINT1_CAM0_KNEEPOINT, + cfg->knee_npoint1_kneepoint); + ircomp->knee_npoint2 =3D + FIELD_PREP(NEO_IR_COMPRESS_KNEE_NPOINT2_CAM0_KNEEPOINT, + cfg->knee_npoint2_kneepoint); + ircomp->knee_npoint3 =3D + FIELD_PREP(NEO_IR_COMPRESS_KNEE_NPOINT3_CAM0_KNEEPOINT, + cfg->knee_npoint3_kneepoint); + ircomp->knee_npoint4 =3D + FIELD_PREP(NEO_IR_COMPRESS_KNEE_NPOINT4_CAM0_KNEEPOINT, + cfg->knee_npoint4_kneepoint); +} + +static void +neoisp_params_handler_ctemp(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + struct neoisp_ctemp_s *ctemp =3D &ctx->hw.ctemp; + const struct neoisp_ctemp_cfg_s *cfg; + const struct neoisp_ctemp_roi_desc_s *croi; + + if (block->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_DISABLE) + FIELD_MODIFY(NEO_COLOR_TEMP_CTRL_CAM0_ENABLE, &ctemp->ctrl, 0); + else if (block->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_ENABLE) + FIELD_MODIFY(NEO_COLOR_TEMP_CTRL_CAM0_ENABLE, &ctemp->ctrl, 1); + + if (block->header.size =3D=3D sizeof(struct v4l2_isp_block_header)) + /* nothing else to do */ + return; + + cfg =3D &block->ctemp.cfg; + + FIELD_MODIFY(NEO_COLOR_TEMP_CTRL_CAM0_IBPP, &ctemp->ctrl, cfg->ctrl_ibpp); + FIELD_MODIFY(NEO_COLOR_TEMP_CTRL_CAM0_CSCON, &ctemp->ctrl, cfg->ctrl_csco= n); + + ctemp->roi_pos =3D + FIELD_PREP(NEO_COLOR_TEMP_ROI_POS_CAM0_XPOS, cfg->roi.xpos) | + FIELD_PREP(NEO_COLOR_TEMP_ROI_POS_CAM0_YPOS, cfg->roi.ypos); + ctemp->roi_size =3D + FIELD_PREP(NEO_COLOR_TEMP_ROI_SIZE_CAM0_WIDTH, cfg->roi.width) | + FIELD_PREP(NEO_COLOR_TEMP_ROI_SIZE_CAM0_HEIGHT, cfg->roi.height); + ctemp->redgain =3D + FIELD_PREP(NEO_COLOR_TEMP_REDGAIN_CAM0_MIN, cfg->redgain_min) | + FIELD_PREP(NEO_COLOR_TEMP_REDGAIN_CAM0_MAX, cfg->redgain_max); + ctemp->bluegain =3D + FIELD_PREP(NEO_COLOR_TEMP_BLUEGAIN_CAM0_MIN, cfg->bluegain_min) | + FIELD_PREP(NEO_COLOR_TEMP_BLUEGAIN_CAM0_MAX, cfg->bluegain_max); + ctemp->point1 =3D + FIELD_PREP(NEO_COLOR_TEMP_POINT1_CAM0_BLUE, cfg->point1_blue) | + FIELD_PREP(NEO_COLOR_TEMP_POINT1_CAM0_RED, cfg->point1_red); + ctemp->point2 =3D + FIELD_PREP(NEO_COLOR_TEMP_POINT2_CAM0_BLUE, cfg->point2_blue) | + FIELD_PREP(NEO_COLOR_TEMP_POINT2_CAM0_RED, cfg->point2_red); + ctemp->hoffset =3D + FIELD_PREP(NEO_COLOR_TEMP_HOFFSET_CAM0_RIGHT, cfg->hoffset_right) | + FIELD_PREP(NEO_COLOR_TEMP_HOFFSET_CAM0_LEFT, cfg->hoffset_left); + ctemp->voffset =3D + FIELD_PREP(NEO_COLOR_TEMP_VOFFSET_CAM0_UP, cfg->voffset_up) | + FIELD_PREP(NEO_COLOR_TEMP_VOFFSET_CAM0_DOWN, cfg->voffset_down); + ctemp->point1_slope =3D + FIELD_PREP(NEO_COLOR_TEMP_POINT1_SLOPE_CAM0_SLOPE_L, cfg->point1_slope_s= lope_l) | + FIELD_PREP(NEO_COLOR_TEMP_POINT1_SLOPE_CAM0_SLOPE_R, cfg->point1_slope_s= lope_r); + ctemp->point2_slope =3D + FIELD_PREP(NEO_COLOR_TEMP_POINT2_SLOPE_CAM0_SLOPE_L, cfg->point2_slope_s= lope_l) | + FIELD_PREP(NEO_COLOR_TEMP_POINT2_SLOPE_CAM0_SLOPE_R, cfg->point2_slope_s= lope_r); + ctemp->luma_th =3D + FIELD_PREP(NEO_COLOR_TEMP_LUMA_TH_CAM0_THL, cfg->luma_th_thl) | + FIELD_PREP(NEO_COLOR_TEMP_LUMA_TH_CAM0_THH, cfg->luma_th_thh); + ctemp->csc_mat0 =3D + FIELD_PREP(NEO_COLOR_TEMP_CSC_MAT0_CAM0_R0C0, cfg->csc_matrix[0][0]) | + FIELD_PREP(NEO_COLOR_TEMP_CSC_MAT0_CAM0_R0C1, cfg->csc_matrix[0][1]); + ctemp->csc_mat1 =3D + FIELD_PREP(NEO_COLOR_TEMP_CSC_MAT1_CAM0_R0C2, cfg->csc_matrix[0][2]) | + FIELD_PREP(NEO_COLOR_TEMP_CSC_MAT1_CAM0_R1C0, cfg->csc_matrix[1][0]); + ctemp->csc_mat2 =3D + FIELD_PREP(NEO_COLOR_TEMP_CSC_MAT2_CAM0_R1C1, cfg->csc_matrix[1][1]) | + FIELD_PREP(NEO_COLOR_TEMP_CSC_MAT2_CAM0_R1C2, cfg->csc_matrix[1][2]); + ctemp->csc_mat3 =3D + FIELD_PREP(NEO_COLOR_TEMP_CSC_MAT3_CAM0_R2C0, cfg->csc_matrix[2][0]) | + FIELD_PREP(NEO_COLOR_TEMP_CSC_MAT3_CAM0_R2C1, cfg->csc_matrix[2][1]); + ctemp->csc_mat4 =3D + FIELD_PREP(NEO_COLOR_TEMP_CSC_MAT4_CAM0_R2C2, cfg->csc_matrix[2][2]); + ctemp->r_gr_offset =3D + FIELD_PREP(NEO_COLOR_TEMP_R_GR_OFFSET_CAM0_OFFSET0, cfg->offsets[0]) | + FIELD_PREP(NEO_COLOR_TEMP_R_GR_OFFSET_CAM0_OFFSET1, cfg->offsets[1]); + ctemp->gb_b_offset =3D + FIELD_PREP(NEO_COLOR_TEMP_GB_B_OFFSET_CAM0_OFFSET0, cfg->offsets[2]) | + FIELD_PREP(NEO_COLOR_TEMP_GB_B_OFFSET_CAM0_OFFSET1, cfg->offsets[3]); + ctemp->stat_blk_size0 =3D + FIELD_PREP(NEO_COLOR_TEMP_STAT_BLK_SIZE0_XSIZE, cfg->stat_blk_size0_xsiz= e) | + FIELD_PREP(NEO_COLOR_TEMP_STAT_BLK_SIZE0_YSIZE, cfg->stat_blk_size0_ysiz= e); + + croi =3D &cfg->color_rois[0]; + ctemp->croi0_pos =3D + FIELD_PREP(NEO_COLOR_TEMP_CROI0_POS_CAM0_ROVERG_LOW, croi->pos_roverg_lo= w) | + FIELD_PREP(NEO_COLOR_TEMP_CROI0_POS_CAM0_ROVERG_HIGH, croi->pos_roverg_h= igh) | + FIELD_PREP(NEO_COLOR_TEMP_CROI0_POS_CAM0_BOVERG_LOW, croi->pos_boverg_lo= w) | + FIELD_PREP(NEO_COLOR_TEMP_CROI0_POS_CAM0_BOVERG_HIGH, croi->pos_boverg_h= igh); + + croi =3D &cfg->color_rois[1]; + ctemp->croi1_pos =3D + FIELD_PREP(NEO_COLOR_TEMP_CROI1_POS_CAM0_ROVERG_LOW, croi->pos_roverg_lo= w) | + FIELD_PREP(NEO_COLOR_TEMP_CROI1_POS_CAM0_ROVERG_HIGH, croi->pos_roverg_h= igh) | + FIELD_PREP(NEO_COLOR_TEMP_CROI1_POS_CAM0_BOVERG_LOW, croi->pos_boverg_lo= w) | + FIELD_PREP(NEO_COLOR_TEMP_CROI1_POS_CAM0_BOVERG_HIGH, croi->pos_boverg_h= igh); + + croi =3D &cfg->color_rois[2]; + ctemp->croi2_pos =3D + FIELD_PREP(NEO_COLOR_TEMP_CROI2_POS_CAM0_ROVERG_LOW, croi->pos_roverg_lo= w) | + FIELD_PREP(NEO_COLOR_TEMP_CROI2_POS_CAM0_ROVERG_HIGH, croi->pos_roverg_h= igh) | + FIELD_PREP(NEO_COLOR_TEMP_CROI2_POS_CAM0_BOVERG_LOW, croi->pos_boverg_lo= w) | + FIELD_PREP(NEO_COLOR_TEMP_CROI2_POS_CAM0_BOVERG_HIGH, croi->pos_boverg_h= igh); + + croi =3D &cfg->color_rois[3]; + ctemp->croi3_pos =3D + FIELD_PREP(NEO_COLOR_TEMP_CROI3_POS_CAM0_ROVERG_LOW, croi->pos_roverg_lo= w) | + FIELD_PREP(NEO_COLOR_TEMP_CROI3_POS_CAM0_ROVERG_HIGH, croi->pos_roverg_h= igh) | + FIELD_PREP(NEO_COLOR_TEMP_CROI3_POS_CAM0_BOVERG_LOW, croi->pos_boverg_lo= w) | + FIELD_PREP(NEO_COLOR_TEMP_CROI3_POS_CAM0_BOVERG_HIGH, croi->pos_boverg_h= igh); + + croi =3D &cfg->color_rois[4]; + ctemp->croi4_pos =3D + FIELD_PREP(NEO_COLOR_TEMP_CROI4_POS_CAM0_ROVERG_LOW, croi->pos_roverg_lo= w) | + FIELD_PREP(NEO_COLOR_TEMP_CROI4_POS_CAM0_ROVERG_HIGH, croi->pos_roverg_h= igh) | + FIELD_PREP(NEO_COLOR_TEMP_CROI4_POS_CAM0_BOVERG_LOW, croi->pos_boverg_lo= w) | + FIELD_PREP(NEO_COLOR_TEMP_CROI4_POS_CAM0_BOVERG_HIGH, croi->pos_boverg_h= igh); + + croi =3D &cfg->color_rois[5]; + ctemp->croi5_pos =3D + FIELD_PREP(NEO_COLOR_TEMP_CROI5_POS_CAM0_ROVERG_LOW, croi->pos_roverg_lo= w) | + FIELD_PREP(NEO_COLOR_TEMP_CROI5_POS_CAM0_ROVERG_HIGH, croi->pos_roverg_h= igh) | + FIELD_PREP(NEO_COLOR_TEMP_CROI5_POS_CAM0_BOVERG_LOW, croi->pos_boverg_lo= w) | + FIELD_PREP(NEO_COLOR_TEMP_CROI5_POS_CAM0_BOVERG_HIGH, croi->pos_boverg_h= igh); + + croi =3D &cfg->color_rois[6]; + ctemp->croi6_pos =3D + FIELD_PREP(NEO_COLOR_TEMP_CROI6_POS_CAM0_ROVERG_LOW, croi->pos_roverg_lo= w) | + FIELD_PREP(NEO_COLOR_TEMP_CROI6_POS_CAM0_ROVERG_HIGH, croi->pos_roverg_h= igh) | + FIELD_PREP(NEO_COLOR_TEMP_CROI6_POS_CAM0_BOVERG_LOW, croi->pos_boverg_lo= w) | + FIELD_PREP(NEO_COLOR_TEMP_CROI6_POS_CAM0_BOVERG_HIGH, croi->pos_boverg_h= igh); + + croi =3D &cfg->color_rois[7]; + ctemp->croi7_pos =3D + FIELD_PREP(NEO_COLOR_TEMP_CROI7_POS_CAM0_ROVERG_LOW, croi->pos_roverg_lo= w) | + FIELD_PREP(NEO_COLOR_TEMP_CROI7_POS_CAM0_ROVERG_HIGH, croi->pos_roverg_h= igh) | + FIELD_PREP(NEO_COLOR_TEMP_CROI7_POS_CAM0_BOVERG_LOW, croi->pos_boverg_lo= w) | + FIELD_PREP(NEO_COLOR_TEMP_CROI7_POS_CAM0_BOVERG_HIGH, croi->pos_boverg_h= igh); + + croi =3D &cfg->color_rois[8]; + ctemp->croi8_pos =3D + FIELD_PREP(NEO_COLOR_TEMP_CROI8_POS_CAM0_ROVERG_LOW, croi->pos_roverg_lo= w) | + FIELD_PREP(NEO_COLOR_TEMP_CROI8_POS_CAM0_ROVERG_HIGH, croi->pos_roverg_h= igh) | + FIELD_PREP(NEO_COLOR_TEMP_CROI8_POS_CAM0_BOVERG_LOW, croi->pos_boverg_lo= w) | + FIELD_PREP(NEO_COLOR_TEMP_CROI8_POS_CAM0_BOVERG_HIGH, croi->pos_boverg_h= igh); + + croi =3D &cfg->color_rois[9]; + ctemp->croi9_pos =3D + FIELD_PREP(NEO_COLOR_TEMP_CROI9_POS_CAM0_ROVERG_LOW, croi->pos_roverg_lo= w) | + FIELD_PREP(NEO_COLOR_TEMP_CROI9_POS_CAM0_ROVERG_HIGH, croi->pos_roverg_h= igh) | + FIELD_PREP(NEO_COLOR_TEMP_CROI9_POS_CAM0_BOVERG_LOW, croi->pos_boverg_lo= w) | + FIELD_PREP(NEO_COLOR_TEMP_CROI9_POS_CAM0_BOVERG_HIGH, croi->pos_boverg_h= igh); + + ctemp->gr_avg_in =3D + FIELD_PREP(NEO_COLOR_TEMP_GR_AVG_IN_CAM0_GR_AGV, cfg->gr_avg_in_gr_agv); + ctemp->gb_avg_in =3D + FIELD_PREP(NEO_COLOR_TEMP_GB_AVG_IN_CAM0_GB_AGV, cfg->gb_avg_in_gb_agv); +} + +static void +neoisp_params_handler_bnr(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + struct neoisp_bnr_s *bnr =3D &ctx->hw.bnr; + const struct neoisp_bnr_cfg_s *cfg; + + if (block->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_DISABLE) + FIELD_MODIFY(NEO_BNR_CTRL_CAM0_ENABLE, &bnr->ctrl, 0); + else if (block->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_ENABLE) + FIELD_MODIFY(NEO_BNR_CTRL_CAM0_ENABLE, &bnr->ctrl, 1); + + if (block->header.size =3D=3D sizeof(struct v4l2_isp_block_header)) + /* nothing else to do */ + return; + + cfg =3D &block->bnr.cfg; + + FIELD_MODIFY(NEO_BNR_CTRL_CAM0_OBPP, &bnr->ctrl, cfg->ctrl_obpp); + FIELD_MODIFY(NEO_BNR_CTRL_CAM0_DEBUG, &bnr->ctrl, cfg->ctrl_debug); + FIELD_MODIFY(NEO_BNR_CTRL_CAM0_NHOOD, &bnr->ctrl, cfg->ctrl_nhood); + + bnr->ypeak =3D + FIELD_PREP(NEO_BNR_YPEAK_CAM0_PEAK_LOW, cfg->ypeak_peak_low) | + FIELD_PREP(NEO_BNR_YPEAK_CAM0_PEAK_SEL, cfg->ypeak_peak_sel) | + FIELD_PREP(NEO_BNR_YPEAK_CAM0_PEAK_HIGH, cfg->ypeak_peak_high) | + FIELD_PREP(NEO_BNR_YPEAK_CAM0_PEAK_OUTSEL, cfg->ypeak_peak_outsel); + bnr->yedge_th0 =3D + FIELD_PREP(NEO_BNR_YEDGE_TH0_CAM0_EDGE_TH0, cfg->yedge_th0_edge_th0); + bnr->yedge_scale =3D + FIELD_PREP(NEO_BNR_YEDGE_SCALE_CAM0_SCALE, cfg->yedge_scale_scale) | + FIELD_PREP(NEO_BNR_YEDGE_SCALE_CAM0_SHIFT, cfg->yedge_scale_shift); + bnr->yedges_th0 =3D + FIELD_PREP(NEO_BNR_YEDGES_TH0_CAM0_EDGE_TH0, cfg->yedges_th0_edge_th0); + bnr->yedges_scale =3D + FIELD_PREP(NEO_BNR_YEDGES_SCALE_CAM0_SCALE, cfg->yedges_scale_scale) | + FIELD_PREP(NEO_BNR_YEDGES_SCALE_CAM0_SHIFT, cfg->yedges_scale_shift); + bnr->yedgea_th0 =3D + FIELD_PREP(NEO_BNR_YEDGEA_TH0_CAM0_EDGE_TH0, cfg->yedgea_th0_edge_th0); + bnr->yedgea_scale =3D + FIELD_PREP(NEO_BNR_YEDGEA_SCALE_CAM0_SCALE, cfg->yedgea_scale_scale) | + FIELD_PREP(NEO_BNR_YEDGEA_SCALE_CAM0_SHIFT, cfg->yedgea_scale_shift); + bnr->yluma_x_th0 =3D + FIELD_PREP(NEO_BNR_YLUMA_X_TH0_CAM0_TH, cfg->yluma_x_th0_th); + bnr->yluma_y_th =3D + FIELD_PREP(NEO_BNR_YLUMA_Y_TH_CAM0_LUMA_Y_TH0, cfg->yluma_y_th_luma_y_th= 0) | + FIELD_PREP(NEO_BNR_YLUMA_Y_TH_CAM0_LUMA_Y_TH1, cfg->yluma_y_th_luma_y_th= 1); + bnr->yluma_scale =3D + FIELD_PREP(NEO_BNR_YLUMA_SCALE_CAM0_SCALE, cfg->yluma_scale_scale) | + FIELD_PREP(NEO_BNR_YLUMA_SCALE_CAM0_SHIFT, cfg->yluma_scale_shift); + bnr->yalpha_gain =3D + FIELD_PREP(NEO_BNR_YALPHA_GAIN_CAM0_GAIN, cfg->yalpha_gain_gain) | + FIELD_PREP(NEO_BNR_YALPHA_GAIN_CAM0_OFFSET, cfg->yalpha_gain_offset); + bnr->cpeak =3D + FIELD_PREP(NEO_BNR_CPEAK_CAM0_PEAK_LOW, cfg->cpeak_peak_low) | + FIELD_PREP(NEO_BNR_CPEAK_CAM0_PEAK_SEL, cfg->cpeak_peak_sel) | + FIELD_PREP(NEO_BNR_CPEAK_CAM0_PEAK_HIGH, cfg->cpeak_peak_high) | + FIELD_PREP(NEO_BNR_CPEAK_CAM0_PEAK_OUTSEL, cfg->cpeak_peak_outsel); + bnr->cedge_th0 =3D + FIELD_PREP(NEO_BNR_CEDGE_TH0_CAM0_EDGE_TH0, cfg->cedge_th0_edge_th0); + bnr->cedge_scale =3D + FIELD_PREP(NEO_BNR_CEDGE_SCALE_CAM0_SCALE, cfg->cedge_scale_scale) | + FIELD_PREP(NEO_BNR_CEDGE_SCALE_CAM0_SHIFT, cfg->cedge_scale_shift); + bnr->cedges_th0 =3D + FIELD_PREP(NEO_BNR_CEDGES_TH0_CAM0_EDGE_TH0, cfg->cedges_th0_edge_th0); + bnr->cedges_scale =3D + FIELD_PREP(NEO_BNR_CEDGES_SCALE_CAM0_SCALE, cfg->cedges_scale_scale) | + FIELD_PREP(NEO_BNR_CEDGES_SCALE_CAM0_SHIFT, cfg->cedges_scale_shift); + bnr->cedgea_th0 =3D + FIELD_PREP(NEO_BNR_CEDGEA_TH0_CAM0_EDGE_TH0, cfg->cedgea_th0_edge_th0); + bnr->cedgea_scale =3D + FIELD_PREP(NEO_BNR_CEDGEA_SCALE_CAM0_SCALE, cfg->cedgea_scale_scale) | + FIELD_PREP(NEO_BNR_CEDGEA_SCALE_CAM0_SHIFT, cfg->cedgea_scale_shift); + bnr->cluma_x_th0 =3D + FIELD_PREP(NEO_BNR_CLUMA_X_TH0_CAM0_TH, cfg->cluma_x_th0_th); + bnr->cluma_y_th =3D + FIELD_PREP(NEO_BNR_CLUMA_Y_TH_CAM0_LUMA_Y_TH0, cfg->cluma_y_th_luma_y_th= 0) | + FIELD_PREP(NEO_BNR_CLUMA_Y_TH_CAM0_LUMA_Y_TH1, cfg->cluma_y_th_luma_y_th= 1); + bnr->cluma_scale =3D + FIELD_PREP(NEO_BNR_CLUMA_SCALE_CAM0_SCALE, cfg->cluma_scale_scale) | + FIELD_PREP(NEO_BNR_CLUMA_SCALE_CAM0_SHIFT, cfg->cluma_scale_shift); + bnr->calpha_gain =3D + FIELD_PREP(NEO_BNR_CALPHA_GAIN_CAM0_GAIN, cfg->calpha_gain_gain) | + FIELD_PREP(NEO_BNR_CALPHA_GAIN_CAM0_OFFSET, cfg->calpha_gain_offset); + bnr->stretch =3D + FIELD_PREP(NEO_BNR_STRETCH_CAM0_GAIN, cfg->stretch_gain); +} + +static void +neoisp_params_handler_vignetting_ctrl(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + struct neoisp_vignetting_ctrl_s *vignetting =3D &ctx->hw.vignetting_ctrl; + const struct neoisp_vignetting_ctrl_cfg_s *cfg; + + if (block->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_DISABLE) + FIELD_MODIFY(NEO_VIGNETTING_CTRL_CAM0_ENABLE, &vignetting->ctrl, 0); + else if (block->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_ENABLE) + FIELD_MODIFY(NEO_VIGNETTING_CTRL_CAM0_ENABLE, &vignetting->ctrl, 1); + + if (block->header.size =3D=3D sizeof(struct v4l2_isp_block_header)) + /* nothing else to do */ + return; + + cfg =3D &block->vignetting_ctrl.cfg; + + vignetting->blk_conf =3D + FIELD_PREP(NEO_VIGNETTING_BLK_CONF_CAM0_COLS, cfg->blk_conf_cols) | + FIELD_PREP(NEO_VIGNETTING_BLK_CONF_CAM0_ROWS, cfg->blk_conf_rows); + vignetting->blk_size =3D + FIELD_PREP(NEO_VIGNETTING_BLK_SIZE_CAM0_XSIZE, cfg->blk_size_xsize) | + FIELD_PREP(NEO_VIGNETTING_BLK_SIZE_CAM0_YSIZE, cfg->blk_size_ysize); + vignetting->blk_stepy =3D + FIELD_PREP(NEO_VIGNETTING_BLK_STEPY_CAM0_STEP, cfg->blk_stepy_step); + vignetting->blk_stepx =3D + FIELD_PREP(NEO_VIGNETTING_BLK_STEPX_CAM0_STEP, cfg->blk_stepx_step); +} + +static void +neoisp_params_handler_demosaic(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + struct neoisp_demosaic_s *demosaic =3D &ctx->hw.demosaic; + const struct neoisp_demosaic_cfg_s *cfg; + + if (block->header.size =3D=3D sizeof(struct v4l2_isp_block_header)) + /* nothing to do */ + return; + + cfg =3D &block->demosaic.cfg; + + demosaic->ctrl =3D + FIELD_PREP(NEO_DEMOSAIC_CTRL_CAM0_FMT, cfg->ctrl_fmt); + demosaic->activity_ctl =3D + FIELD_PREP(NEO_DEMOSAIC_ACTIVITY_CTL_CAM0_ALPHA, cfg->activity_ctl_alpha= ) | + FIELD_PREP(NEO_DEMOSAIC_ACTIVITY_CTL_CAM0_ACT_RATIO, cfg->activity_ctl_a= ct_ratio); + demosaic->dynamics_ctl0 =3D + FIELD_PREP(NEO_DEMOSAIC_DYNAMICS_CTL0_CAM0_STRENGTHG, + cfg->dynamics_ctl0_strengthg); + demosaic->dynamics_ctl0 |=3D + FIELD_PREP(NEO_DEMOSAIC_DYNAMICS_CTL0_CAM0_STRENGTHC, + cfg->dynamics_ctl0_strengthc); + demosaic->dynamics_ctl2 =3D + FIELD_PREP(NEO_DEMOSAIC_DYNAMICS_CTL2_CAM0_MAX_IMPACT, + cfg->dynamics_ctl2_max_impact); +} + +static void +neoisp_params_handler_rgb2yuv(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + struct neoisp_rgb2yuv_s *rgb2yuv =3D &ctx->hw.rgb2yuv; + const struct neoisp_rgb2yuv_cfg_s *cfg; + + if (block->header.size =3D=3D sizeof(struct v4l2_isp_block_header)) + /* nothing to do */ + return; + + cfg =3D &block->rgb2yuv.cfg; + + rgb2yuv->gain_ctrl =3D + FIELD_PREP(NEO_RGB_TO_YUV_GAIN_CTRL_CAM0_RGAIN, cfg->gain_ctrl_rgain) | + FIELD_PREP(NEO_RGB_TO_YUV_GAIN_CTRL_CAM0_BGAIN, cfg->gain_ctrl_bgain); + rgb2yuv->mat0 =3D + FIELD_PREP(NEO_RGB_TO_YUV_MAT0_CAM0_R0C0, cfg->mat_rxcy[0][0]) | + FIELD_PREP(NEO_RGB_TO_YUV_MAT0_CAM0_R0C1, cfg->mat_rxcy[0][1]); + rgb2yuv->mat1 =3D + FIELD_PREP(NEO_RGB_TO_YUV_MAT1_CAM0_R0C2, cfg->mat_rxcy[0][2]); + rgb2yuv->mat2 =3D + FIELD_PREP(NEO_RGB_TO_YUV_MAT2_CAM0_R1C0, cfg->mat_rxcy[1][0]) | + FIELD_PREP(NEO_RGB_TO_YUV_MAT2_CAM0_R1C1, cfg->mat_rxcy[1][1]); + rgb2yuv->mat3 =3D + FIELD_PREP(NEO_RGB_TO_YUV_MAT3_CAM0_R1C2, cfg->mat_rxcy[1][2]); + rgb2yuv->mat4 =3D + FIELD_PREP(NEO_RGB_TO_YUV_MAT4_CAM0_R2C0, cfg->mat_rxcy[2][0]) | + FIELD_PREP(NEO_RGB_TO_YUV_MAT4_CAM0_R2C1, cfg->mat_rxcy[2][1]); + rgb2yuv->mat5 =3D + FIELD_PREP(NEO_RGB_TO_YUV_MAT5_CAM0_R2C2, cfg->mat_rxcy[2][2]); + rgb2yuv->offset0 =3D + FIELD_PREP(NEO_RGB_TO_YUV_OFFSET0_CAM0_OFFSET, cfg->csc_offsets[0]); + rgb2yuv->offset1 =3D + FIELD_PREP(NEO_RGB_TO_YUV_OFFSET1_CAM0_OFFSET, cfg->csc_offsets[1]); + rgb2yuv->offset2 =3D + FIELD_PREP(NEO_RGB_TO_YUV_OFFSET2_CAM0_OFFSET, cfg->csc_offsets[2]); +} + +static void +neoisp_params_handler_dr_comp(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + struct neoisp_dr_comp_s *drc =3D &ctx->hw.drc; + const struct neoisp_dr_comp_cfg_s *cfg; + + if (block->header.size =3D=3D sizeof(struct v4l2_isp_block_header)) + /* nothing to do */ + return; + + cfg =3D &block->dr_comp.cfg; + + drc->roi0_pos =3D + FIELD_PREP(NEO_DRC_ROI0_POS_CAM0_XPOS, cfg->roi0.xpos) | + FIELD_PREP(NEO_DRC_ROI0_POS_CAM0_YPOS, cfg->roi0.ypos); + drc->roi0_size =3D + FIELD_PREP(NEO_DRC_ROI0_SIZE_CAM0_WIDTH, cfg->roi0.width) | + FIELD_PREP(NEO_DRC_ROI0_SIZE_CAM0_HEIGHT, cfg->roi0.height); + drc->roi1_pos =3D + FIELD_PREP(NEO_DRC_ROI1_POS_CAM0_XPOS, cfg->roi1.xpos) | + FIELD_PREP(NEO_DRC_ROI1_POS_CAM0_YPOS, cfg->roi1.ypos); + drc->roi1_size =3D + FIELD_PREP(NEO_DRC_ROI1_SIZE_CAM0_WIDTH, cfg->roi1.width) | + FIELD_PREP(NEO_DRC_ROI1_SIZE_CAM0_HEIGHT, cfg->roi1.height); + drc->groi_sum_shift =3D + FIELD_PREP(NEO_DRC_GROI_SUM_SHIFT_CAM0_SHIFT0, cfg->groi_sum_shift_shift= 0) | + FIELD_PREP(NEO_DRC_GROI_SUM_SHIFT_CAM0_SHIFT1, cfg->groi_sum_shift_shift= 1); + drc->gbl_gain =3D + FIELD_PREP(NEO_DRC_GBL_GAIN_CAM0_GAIN, cfg->gbl_gain_gain); + drc->lcl_blk_size =3D + FIELD_PREP(NEO_DRC_LCL_BLK_SIZE_CAM0_XSIZE, cfg->lcl_blk_size_xsize) | + FIELD_PREP(NEO_DRC_LCL_BLK_SIZE_CAM0_YSIZE, cfg->lcl_blk_size_ysize); + drc->lcl_stretch =3D + FIELD_PREP(NEO_DRC_LCL_STRETCH_CAM0_STRETCH, cfg->lcl_stretch_stretch) | + FIELD_PREP(NEO_DRC_LCL_STRETCH_CAM0_OFFSET, cfg->lcl_stretch_offset); + drc->lcl_blk_stepy =3D + FIELD_PREP(NEO_DRC_LCL_BLK_STEPY_CAM0_STEP, cfg->lcl_blk_stepy_step); + drc->lcl_blk_stepx =3D + FIELD_PREP(NEO_DRC_LCL_BLK_STEPX_CAM0_STEP, cfg->lcl_blk_stepx_step); + drc->lcl_sum_shift =3D + FIELD_PREP(NEO_DRC_LCL_SUM_SHIFT_CAM0_SHIFT, cfg->lcl_sum_shift_shift); + drc->alpha =3D + FIELD_PREP(NEO_DRC_ALPHA_CAM0_ALPHA, cfg->alpha_alpha); +} + +static void +neoisp_params_handler_nr(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + struct neoisp_nr_s *nr =3D &ctx->hw.nr; + const struct neoisp_nr_cfg_s *cfg; + + if (block->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_DISABLE) + FIELD_MODIFY(NEO_NR_CTRL_CAM0_ENABLE, &nr->ctrl, 0); + else if (block->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_ENABLE) + FIELD_MODIFY(NEO_NR_CTRL_CAM0_ENABLE, &nr->ctrl, 1); + + if (block->header.size =3D=3D sizeof(struct v4l2_isp_block_header)) + /* nothing else to do */ + return; + + cfg =3D &block->nr.cfg; + + FIELD_MODIFY(NEO_NR_CTRL_CAM0_DEBUG, &nr->ctrl, cfg->ctrl_debug); + + nr->blend_scale =3D + FIELD_PREP(NEO_NR_BLEND_SCALE_CAM0_SCALE, cfg->blend_scale_scale) | + FIELD_PREP(NEO_NR_BLEND_SCALE_CAM0_SHIFT, cfg->blend_scale_shift) | + FIELD_PREP(NEO_NR_BLEND_SCALE_CAM0_GAIN, cfg->blend_scale_gain); + nr->blend_th0 =3D + FIELD_PREP(NEO_NR_BLEND_TH0_CAM0_TH, cfg->blend_th0_th); +} + +static void +neoisp_params_handler_df(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + struct neoisp_df_s *df =3D &ctx->hw.df; + const struct neoisp_df_cfg_s *cfg; + + if (block->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_DISABLE) + FIELD_MODIFY(NEO_DF_CTRL_CAM0_ENABLE, &df->ctrl, 0); + else if (block->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_ENABLE) + FIELD_MODIFY(NEO_DF_CTRL_CAM0_ENABLE, &df->ctrl, 1); + + if (block->header.size =3D=3D sizeof(struct v4l2_isp_block_header)) + /* nothing else to do */ + return; + + cfg =3D &block->df.cfg; + + FIELD_MODIFY(NEO_DF_CTRL_CAM0_DEBUG, &df->ctrl, cfg->ctrl_debug); + + df->th_scale =3D + FIELD_PREP(NEO_DF_TH_SCALE_CAM0_SCALE, cfg->th_scale_scale); + df->blend_shift =3D + FIELD_PREP(NEO_DF_BLEND_SHIFT_CAM0_SHIFT, cfg->blend_shift_shift); + df->blend_th0 =3D + FIELD_PREP(NEO_DF_BLEND_TH0_CAM0_TH, cfg->blend_th0_th); +} + +static void +neoisp_params_handler_ee(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + struct neoisp_ee_s *ee =3D &ctx->hw.ee; + const struct neoisp_ee_cfg_s *cfg; + + if (block->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_DISABLE) + FIELD_MODIFY(NEO_EE_CTRL_CAM0_ENABLE, &ee->ctrl, 0); + else if (block->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_ENABLE) + FIELD_MODIFY(NEO_EE_CTRL_CAM0_ENABLE, &ee->ctrl, 1); + + if (block->header.size =3D=3D sizeof(struct v4l2_isp_block_header)) + /* nothing else to do */ + return; + + cfg =3D &block->ee.cfg; + + FIELD_MODIFY(NEO_EE_CTRL_CAM0_DEBUG, &ee->ctrl, cfg->ctrl_debug); + + ee->coring =3D + FIELD_PREP(NEO_EE_CORING_CAM0_CORING, cfg->coring_coring); + ee->clip =3D + FIELD_PREP(NEO_EE_CLIP_CAM0_CLIP, cfg->clip_clip); + ee->maskgain =3D + FIELD_PREP(NEO_EE_MASKGAIN_CAM0_GAIN, cfg->maskgain_gain); +} + +static void +neoisp_params_handler_convmed(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + struct neoisp_convmed_s *convmed =3D &ctx->hw.convmed; + const struct neoisp_convmed_cfg_s *cfg; + + if (block->header.size =3D=3D sizeof(struct v4l2_isp_block_header)) + /* nothing to do */ + return; + + cfg =3D &block->convmed.cfg; + + convmed->ctrl =3D + FIELD_PREP(NEO_CCONVMED_CTRL_CAM0_FLT, cfg->ctrl_flt); +} + +static void +neoisp_params_handler_cas(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + struct neoisp_cas_s *cas =3D &ctx->hw.cas; + const struct neoisp_cas_cfg_s *cfg; + + if (block->header.size =3D=3D sizeof(struct v4l2_isp_block_header)) + /* nothing to do */ + return; + + cfg =3D &block->cas.cfg; + + cas->gain =3D + FIELD_PREP(NEO_CAS_GAIN_CAM0_SCALE, cfg->gain_scale) | + FIELD_PREP(NEO_CAS_GAIN_CAM0_SHIFT, cfg->gain_shift); + cas->corr =3D + FIELD_PREP(NEO_CAS_CORR_CAM0_CORR, cfg->corr_corr); + cas->offset =3D + FIELD_PREP(NEO_CAS_OFFSET_CAM0_OFFSET, cfg->offset_offset); +} + +static void +neoisp_params_handler_gcm(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + struct neoisp_gcm_s *gcm =3D &ctx->hw.gcm; + const struct neoisp_gcm_cfg_s *cfg; + + if (block->header.size =3D=3D sizeof(struct v4l2_isp_block_header)) + /* nothing to do */ + return; + + cfg =3D &block->gcm.cfg; + + gcm->imat0 =3D + FIELD_PREP(NEO_GCM_IMAT0_CAM0_R0C0, cfg->imat_rxcy[0][0]) | + FIELD_PREP(NEO_GCM_IMAT0_CAM0_R0C1, cfg->imat_rxcy[0][1]); + gcm->imat1 =3D + FIELD_PREP(NEO_GCM_IMAT1_CAM0_R0C2, cfg->imat_rxcy[0][2]); + gcm->imat2 =3D + FIELD_PREP(NEO_GCM_IMAT2_CAM0_R1C0, cfg->imat_rxcy[1][0]) | + FIELD_PREP(NEO_GCM_IMAT2_CAM0_R1C1, cfg->imat_rxcy[1][1]); + gcm->imat3 =3D + FIELD_PREP(NEO_GCM_IMAT3_CAM0_R1C2, cfg->imat_rxcy[1][2]); + gcm->imat4 =3D + FIELD_PREP(NEO_GCM_IMAT4_CAM0_R2C0, cfg->imat_rxcy[2][0]) | + FIELD_PREP(NEO_GCM_IMAT4_CAM0_R2C1, cfg->imat_rxcy[2][1]); + gcm->imat5 =3D + FIELD_PREP(NEO_GCM_IMAT5_CAM0_R2C2, cfg->imat_rxcy[2][2]); + gcm->ioffset0 =3D + FIELD_PREP(NEO_GCM_IOFFSET0_CAM0_OFFSET0, cfg->ioffsets[0]); + gcm->ioffset1 =3D + FIELD_PREP(NEO_GCM_IOFFSET1_CAM0_OFFSET1, cfg->ioffsets[1]); + gcm->ioffset2 =3D + FIELD_PREP(NEO_GCM_IOFFSET2_CAM0_OFFSET2, cfg->ioffsets[2]); + gcm->omat0 =3D + FIELD_PREP(NEO_GCM_OMAT0_CAM0_R0C0, cfg->omat_rxcy[0][0]) | + FIELD_PREP(NEO_GCM_OMAT0_CAM0_R0C1, cfg->omat_rxcy[0][1]); + gcm->omat1 =3D + FIELD_PREP(NEO_GCM_OMAT1_CAM0_R0C2, cfg->omat_rxcy[0][2]); + gcm->omat2 =3D + FIELD_PREP(NEO_GCM_OMAT2_CAM0_R1C0, cfg->omat_rxcy[1][0]) | + FIELD_PREP(NEO_GCM_OMAT2_CAM0_R1C1, cfg->omat_rxcy[1][1]); + gcm->omat3 =3D + FIELD_PREP(NEO_GCM_OMAT3_CAM0_R1C2, cfg->omat_rxcy[1][2]); + gcm->omat4 =3D + FIELD_PREP(NEO_GCM_OMAT4_CAM0_R2C0, cfg->omat_rxcy[2][0]) | + FIELD_PREP(NEO_GCM_OMAT4_CAM0_R2C1, cfg->omat_rxcy[2][1]); + gcm->omat5 =3D + FIELD_PREP(NEO_GCM_OMAT5_CAM0_R2C2, cfg->omat_rxcy[2][2]); + gcm->ooffset0 =3D + FIELD_PREP(NEO_GCM_OOFFSET0_CAM0_OFFSET0, cfg->ooffsets[0]); + gcm->ooffset1 =3D + FIELD_PREP(NEO_GCM_OOFFSET1_CAM0_OFFSET1, cfg->ooffsets[1]); + gcm->ooffset2 =3D + FIELD_PREP(NEO_GCM_OOFFSET2_CAM0_OFFSET2, cfg->ooffsets[2]); + gcm->gamma0 =3D + FIELD_PREP(NEO_GCM_GAMMA0_CAM0_GAMMA0, cfg->gamma0_gamma0) | + FIELD_PREP(NEO_GCM_GAMMA0_CAM0_OFFSET0, cfg->gamma0_offset0); + gcm->gamma1 =3D + FIELD_PREP(NEO_GCM_GAMMA1_CAM0_GAMMA1, cfg->gamma1_gamma1) | + FIELD_PREP(NEO_GCM_GAMMA1_CAM0_OFFSET1, cfg->gamma1_offset1); + gcm->gamma2 =3D + FIELD_PREP(NEO_GCM_GAMMA2_CAM0_GAMMA2, cfg->gamma2_gamma2) | + FIELD_PREP(NEO_GCM_GAMMA2_CAM0_OFFSET2, cfg->gamma2_offset2); + gcm->blklvl0_ctrl =3D + FIELD_PREP(NEO_GCM_BLKLVL0_CTRL_CAM0_OFFSET0, cfg->blklvl0_ctrl_offset0)= | + FIELD_PREP(NEO_GCM_BLKLVL0_CTRL_CAM0_GAIN0, cfg->blklvl0_ctrl_gain0); + gcm->blklvl1_ctrl =3D + FIELD_PREP(NEO_GCM_BLKLVL1_CTRL_CAM0_OFFSET1, cfg->blklvl1_ctrl_offset1)= | + FIELD_PREP(NEO_GCM_BLKLVL1_CTRL_CAM0_GAIN1, cfg->blklvl1_ctrl_gain1); + gcm->blklvl2_ctrl =3D + FIELD_PREP(NEO_GCM_BLKLVL2_CTRL_CAM0_OFFSET2, cfg->blklvl2_ctrl_offset2)= | + FIELD_PREP(NEO_GCM_BLKLVL2_CTRL_CAM0_GAIN2, cfg->blklvl2_ctrl_gain2); + gcm->lowth_ctrl01 =3D + FIELD_PREP(NEO_GCM_LOWTH_CTRL01_CAM0_THRESHOLD0, cfg->lowth_ctrl01_thres= hold0) | + FIELD_PREP(NEO_GCM_LOWTH_CTRL01_CAM0_THRESHOLD1, cfg->lowth_ctrl01_thres= hold1); + gcm->lowth_ctrl2 =3D + FIELD_PREP(NEO_GCM_LOWTH_CTRL2_CAM0_THRESHOLD2, cfg->lowth_ctrl2_thresho= ld2); + gcm->mat_confg =3D + FIELD_PREP(NEO_GCM_MAT_CONFG_CAM0_SIGN_CONFG, cfg->mat_confg_sign_confg); +} + +static void +neoisp_params_handler_af(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + struct neoisp_autofocus_s *af =3D &ctx->hw.autofocus; + const struct neoisp_af_cfg_s *cfg; + + if (block->header.size =3D=3D sizeof(struct v4l2_isp_block_header)) + /* nothing to do */ + return; + + cfg =3D &block->af.cfg; + + af->roi0_pos =3D + FIELD_PREP(NEO_AUTOFOCUS_ROI0_POS_CAM0_XPOS, cfg->af_roi[0].xpos) | + FIELD_PREP(NEO_AUTOFOCUS_ROI0_POS_CAM0_YPOS, cfg->af_roi[0].ypos); + af->roi0_size =3D + FIELD_PREP(NEO_AUTOFOCUS_ROI0_SIZE_CAM0_WIDTH, cfg->af_roi[0].width) | + FIELD_PREP(NEO_AUTOFOCUS_ROI0_SIZE_CAM0_HEIGHT, cfg->af_roi[0].height); + af->roi1_pos =3D + FIELD_PREP(NEO_AUTOFOCUS_ROI1_POS_CAM0_XPOS, cfg->af_roi[1].xpos) | + FIELD_PREP(NEO_AUTOFOCUS_ROI1_POS_CAM0_YPOS, cfg->af_roi[1].ypos); + af->roi1_size =3D + FIELD_PREP(NEO_AUTOFOCUS_ROI1_SIZE_CAM0_WIDTH, cfg->af_roi[1].width) | + FIELD_PREP(NEO_AUTOFOCUS_ROI1_SIZE_CAM0_HEIGHT, cfg->af_roi[1].height); + af->roi2_pos =3D + FIELD_PREP(NEO_AUTOFOCUS_ROI2_POS_CAM0_XPOS, cfg->af_roi[2].xpos) | + FIELD_PREP(NEO_AUTOFOCUS_ROI2_POS_CAM0_YPOS, cfg->af_roi[2].ypos); + af->roi2_size =3D + FIELD_PREP(NEO_AUTOFOCUS_ROI2_SIZE_CAM0_WIDTH, cfg->af_roi[2].width) | + FIELD_PREP(NEO_AUTOFOCUS_ROI2_SIZE_CAM0_HEIGHT, cfg->af_roi[2].height); + af->roi3_pos =3D + FIELD_PREP(NEO_AUTOFOCUS_ROI3_POS_CAM0_XPOS, cfg->af_roi[3].xpos) | + FIELD_PREP(NEO_AUTOFOCUS_ROI3_POS_CAM0_YPOS, cfg->af_roi[3].ypos); + af->roi3_size =3D + FIELD_PREP(NEO_AUTOFOCUS_ROI3_SIZE_CAM0_WIDTH, cfg->af_roi[3].width) | + FIELD_PREP(NEO_AUTOFOCUS_ROI3_SIZE_CAM0_HEIGHT, cfg->af_roi[3].height); + af->roi4_pos =3D + FIELD_PREP(NEO_AUTOFOCUS_ROI4_POS_CAM0_XPOS, cfg->af_roi[4].xpos) | + FIELD_PREP(NEO_AUTOFOCUS_ROI4_POS_CAM0_YPOS, cfg->af_roi[4].ypos); + af->roi4_size =3D + FIELD_PREP(NEO_AUTOFOCUS_ROI4_SIZE_CAM0_WIDTH, cfg->af_roi[4].width) | + FIELD_PREP(NEO_AUTOFOCUS_ROI4_SIZE_CAM0_HEIGHT, cfg->af_roi[4].height); + af->roi5_pos =3D + FIELD_PREP(NEO_AUTOFOCUS_ROI5_POS_CAM0_XPOS, cfg->af_roi[5].xpos) | + FIELD_PREP(NEO_AUTOFOCUS_ROI5_POS_CAM0_YPOS, cfg->af_roi[5].ypos); + af->roi5_size =3D + FIELD_PREP(NEO_AUTOFOCUS_ROI5_SIZE_CAM0_WIDTH, cfg->af_roi[5].width) | + FIELD_PREP(NEO_AUTOFOCUS_ROI5_SIZE_CAM0_HEIGHT, cfg->af_roi[5].height); + af->roi6_pos =3D + FIELD_PREP(NEO_AUTOFOCUS_ROI6_POS_CAM0_XPOS, cfg->af_roi[6].xpos) | + FIELD_PREP(NEO_AUTOFOCUS_ROI6_POS_CAM0_YPOS, cfg->af_roi[6].ypos); + af->roi6_size =3D + FIELD_PREP(NEO_AUTOFOCUS_ROI6_SIZE_CAM0_WIDTH, cfg->af_roi[6].width) | + FIELD_PREP(NEO_AUTOFOCUS_ROI6_SIZE_CAM0_HEIGHT, cfg->af_roi[6].height); + af->roi7_pos =3D + FIELD_PREP(NEO_AUTOFOCUS_ROI7_POS_CAM0_XPOS, cfg->af_roi[7].xpos) | + FIELD_PREP(NEO_AUTOFOCUS_ROI7_POS_CAM0_YPOS, cfg->af_roi[7].ypos); + af->roi7_size =3D + FIELD_PREP(NEO_AUTOFOCUS_ROI7_SIZE_CAM0_WIDTH, cfg->af_roi[7].width) | + FIELD_PREP(NEO_AUTOFOCUS_ROI7_SIZE_CAM0_HEIGHT, cfg->af_roi[7].height); + af->roi8_pos =3D + FIELD_PREP(NEO_AUTOFOCUS_ROI8_POS_CAM0_XPOS, cfg->af_roi[8].xpos) | + FIELD_PREP(NEO_AUTOFOCUS_ROI8_POS_CAM0_YPOS, cfg->af_roi[8].ypos); + af->roi8_size =3D + FIELD_PREP(NEO_AUTOFOCUS_ROI8_SIZE_CAM0_WIDTH, cfg->af_roi[8].width) | + FIELD_PREP(NEO_AUTOFOCUS_ROI8_SIZE_CAM0_HEIGHT, cfg->af_roi[8].height); + af->fil0_coeffs0 =3D + FIELD_PREP(NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0_COEFF0, cfg->fil0_coeffs[0]) | + FIELD_PREP(NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0_COEFF1, cfg->fil0_coeffs[1]) | + FIELD_PREP(NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0_COEFF2, cfg->fil0_coeffs[2]) | + FIELD_PREP(NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0_COEFF3, cfg->fil0_coeffs[3]); + af->fil0_coeffs1 =3D + FIELD_PREP(NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0_COEFF4, cfg->fil0_coeffs[4]) | + FIELD_PREP(NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0_COEFF5, cfg->fil0_coeffs[5]) | + FIELD_PREP(NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0_COEFF6, cfg->fil0_coeffs[6]) | + FIELD_PREP(NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0_COEFF7, cfg->fil0_coeffs[7]); + af->fil0_coeffs2 =3D + FIELD_PREP(NEO_AUTOFOCUS_FIL0_COEFFS2_CAM0_COEFF8, cfg->fil0_coeffs[8]); + af->fil0_shift =3D + FIELD_PREP(NEO_AUTOFOCUS_FIL0_SHIFT_CAM0_SHIFT, cfg->fil0_shift_shift); + af->fil1_coeffs0 =3D + FIELD_PREP(NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0_COEFF0, cfg->fil1_coeffs[0]) | + FIELD_PREP(NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0_COEFF1, cfg->fil1_coeffs[1]) | + FIELD_PREP(NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0_COEFF2, cfg->fil1_coeffs[2]) | + FIELD_PREP(NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0_COEFF3, cfg->fil1_coeffs[3]); + af->fil1_coeffs1 =3D + FIELD_PREP(NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0_COEFF4, cfg->fil1_coeffs[4]) | + FIELD_PREP(NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0_COEFF5, cfg->fil1_coeffs[5]) | + FIELD_PREP(NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0_COEFF6, cfg->fil1_coeffs[6]) | + FIELD_PREP(NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0_COEFF7, cfg->fil1_coeffs[7]); + af->fil1_coeffs2 =3D + FIELD_PREP(NEO_AUTOFOCUS_FIL1_COEFFS2_CAM0_COEFF8, cfg->fil1_coeffs[8]); + af->fil1_shift =3D + FIELD_PREP(NEO_AUTOFOCUS_FIL1_SHIFT_CAM0_SHIFT, cfg->fil1_shift_shift); +} + +static void +neoisp_params_handler_vignetting_table(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + const struct neoisp_vignetting_table_mem_params_s *cfg; + + if (block->header.size =3D=3D sizeof(struct v4l2_isp_block_header)) + /* nothing to do */ + return; + + cfg =3D &block->vignetting_table.cfg; + + memcpy((u8 *)(uintptr_t)&ctx->vig, + (u8 *)(uintptr_t)cfg->vignetting_table, + sizeof(struct neoisp_vignetting_table_mem_params_s)); +} + +static void +neoisp_params_handler_drc_global_tonemap(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + const struct neoisp_drc_global_tonemap_mem_params_s *cfg; + + if (block->header.size =3D=3D sizeof(struct v4l2_isp_block_header)) + /* nothing to do */ + return; + + cfg =3D &block->drc_global_tonemap.cfg; + + memcpy((u8 *)(uintptr_t)&ctx->gtm, + (u8 *)(uintptr_t)cfg->drc_global_tonemap, + sizeof(struct neoisp_drc_global_tonemap_mem_params_s)); +} + +static void +neoisp_params_handler_drc_local_tonemap(struct neoisp_context_s *ctx, + const union neoisp_params_block_u *block) +{ + const struct neoisp_drc_local_tonemap_mem_params_s *cfg; + + if (block->header.size =3D=3D sizeof(struct v4l2_isp_block_header)) + /* nothing to do */ + return; + + cfg =3D &block->drc_local_tonemap.cfg; + + memcpy((u8 *)(uintptr_t)&ctx->ltm, + (u8 *)(uintptr_t)cfg->drc_local_tonemap, + sizeof(struct neoisp_drc_local_tonemap_mem_params_s)); +} + +static const struct neoisp_block_handler_s { + void (*handler)(struct neoisp_context_s *ctx, const union neoisp_params_b= lock_u *blk); +} neoisp_block_handlers[] =3D { + [NEOISP_PARAM_BLK_PIPE_CONF] =3D { + .handler =3D &neoisp_params_handler_pipe_conf, + }, + [NEOISP_PARAM_BLK_HEAD_COLOR] =3D { + .handler =3D &neoisp_params_handler_head_color, + }, + [NEOISP_PARAM_BLK_HDR_DECOMPRESS0] =3D { + .handler =3D &neoisp_params_handler_hdr_decompress0, + }, + [NEOISP_PARAM_BLK_HDR_DECOMPRESS1] =3D { + .handler =3D &neoisp_params_handler_hdr_decompress1, + }, + [NEOISP_PARAM_BLK_OBWB0] =3D { + .handler =3D &neoisp_params_handler_obwb0, + }, + [NEOISP_PARAM_BLK_OBWB1] =3D { + .handler =3D &neoisp_params_handler_obwb1, + }, + [NEOISP_PARAM_BLK_OBWB2] =3D { + .handler =3D &neoisp_params_handler_obwb2, + }, + [NEOISP_PARAM_BLK_HDR_MERGE] =3D { + .handler =3D &neoisp_params_handler_hdr_merge, + }, + [NEOISP_PARAM_BLK_RGBIR] =3D { + .handler =3D &neoisp_params_handler_rgbir, + }, + [NEOISP_PARAM_BLK_STAT] =3D { + .handler =3D &neoisp_params_handler_stat, + }, + [NEOISP_PARAM_BLK_IR_COMPRESS] =3D { + .handler =3D &neoisp_params_handler_ir_compress, + }, + [NEOISP_PARAM_BLK_BNR] =3D { + .handler =3D &neoisp_params_handler_bnr, + }, + [NEOISP_PARAM_BLK_VIGNETTING_CTRL] =3D { + .handler =3D &neoisp_params_handler_vignetting_ctrl, + }, + [NEOISP_PARAM_BLK_CTEMP] =3D { + .handler =3D &neoisp_params_handler_ctemp, + }, + [NEOISP_PARAM_BLK_DEMOSAIC] =3D { + .handler =3D &neoisp_params_handler_demosaic, + }, + [NEOISP_PARAM_BLK_RGB2YUV] =3D { + .handler =3D &neoisp_params_handler_rgb2yuv, + }, + [NEOISP_PARAM_BLK_DR_COMP] =3D { + .handler =3D &neoisp_params_handler_dr_comp, + }, + [NEOISP_PARAM_BLK_NR] =3D { + .handler =3D &neoisp_params_handler_nr, + }, + [NEOISP_PARAM_BLK_AF] =3D { + .handler =3D &neoisp_params_handler_af, + }, + [NEOISP_PARAM_BLK_EE] =3D { + .handler =3D &neoisp_params_handler_ee, + }, + [NEOISP_PARAM_BLK_DF] =3D { + .handler =3D &neoisp_params_handler_df, + }, + [NEOISP_PARAM_BLK_CONVMED] =3D { + .handler =3D &neoisp_params_handler_convmed, + }, + [NEOISP_PARAM_BLK_CAS] =3D { + .handler =3D &neoisp_params_handler_cas, + }, + [NEOISP_PARAM_BLK_GCM] =3D { + .handler =3D &neoisp_params_handler_gcm, + }, + [NEOISP_PARAM_BLK_VIGNETTING_TABLE] =3D { + .handler =3D &neoisp_params_handler_vignetting_table, + }, + [NEOISP_PARAM_BLK_DRC_GLOBAL_TONEMAP] =3D { + .handler =3D &neoisp_params_handler_drc_global_tonemap, + }, + [NEOISP_PARAM_BLK_DRC_LOCAL_TONEMAP] =3D { + .handler =3D &neoisp_params_handler_drc_local_tonemap, + }, +}; + +struct ycbcr_enc { + /* Matrix stored in s8.8 format */ + s16 matrix[NEO_GAMMA_MATRIX_SIZE][NEO_GAMMA_MATRIX_SIZE]; + /* This range [-128, 127] is remapped to [0, 255] for full-range quantiza= tion. + * Thus, chrominance channels offset is 0.5 in s0.12 format that is 0.5 *= 4096. + */ + s16 offsets[NEO_GAMMA_MATRIX_SIZE]; +}; + +struct xfer_func { + s16 gain; /* s8.8 format*/ + s16 blklvl_gain; /* s8.8 format */ + s16 threshold; /* s0.16 format */ + s16 gamma; /* s1.8 format */ + s16 gamma_offset; /* s0.12 format */ +}; + +static const struct ycbcr_enc enc_lut[] =3D { + [V4L2_YCBCR_ENC_601] =3D { + /* BT.601 full-range encoding - floating-point matrix: + * [0.299, 0.5870, 0.1140 + * -0.1687, -0.3313, 0.5 + * 0.5, -0.4187, -0.0813] + */ + .matrix =3D { + {77, 150, 29}, + {-43, -85, 128}, + {128, -107, -21}, + }, + .offsets =3D {0, 2048, 2048}, + }, [V4L2_YCBCR_ENC_709] =3D { + /* BT.709 full-range encoding - floating-point matrix: + * [0.2126, 0.7152, 0.0722 + * -0.1146, -0.3854, 0.5 + * 0.5, -0.4542, -0.0458] + */ + .matrix =3D { + {54, 183, 18}, + {-29, -99, 128}, + {128, -116, -12}, + }, + .offsets =3D {0, 2048, 2048}, + }, [V4L2_YCBCR_ENC_DEFAULT] =3D { + /* No encoding - used for RGB output formats */ + .matrix =3D { + {256, 0, 0}, + {0, 256, 0}, + {0, 0, 256}, + }, + .offsets =3D {0, 0, 0}, + }, +}; + +static const struct xfer_func xfer_lut[] =3D { + [V4L2_XFER_FUNC_709] =3D { + /* L' =3D 4.5L, for 0 <=3D L <=3D 0.018 + * L' =3D 1.099L^0.45 - 0.099, for L >=3D 0.018 + * =3D 1.099 * (L^0.45 - (0.099 / 1.099)), for L >=3D 0.018 + */ + .gain =3D 281, + .blklvl_gain =3D 1152, + .threshold =3D 1180, + .gamma =3D 115, + .gamma_offset =3D 369, + }, [V4L2_XFER_FUNC_SRGB] =3D { + /* L' =3D 12.92L, for 0 <=3D L <=3D 0.0031308 + * L' =3D 1.055L^(1/2.4) - 0.055, for L >=3D 0.0031308 + * =3D 1.055 * (L^(1/2.4) - (0.055 / 1.055)), for L >=3D 0.0031308 + */ + .gain =3D 270, + .blklvl_gain =3D 3308, + .threshold =3D 205, + .gamma =3D 107, + .gamma_offset =3D 214, + }, [V4L2_XFER_FUNC_NONE] =3D { + .gain =3D 256, + .blklvl_gain =3D 0, + .threshold =3D 0, + .gamma =3D 256, + .gamma_offset =3D 0, + }, +}; + +void neoisp_ctx_set_default_context(struct neoisp_context_s *context) +{ + memcpy(context, &def_context, sizeof(struct neoisp_context_s)); +} + +/* + * Set pipe conf volatile settings (i.e. buffer addresses) + */ +void neoisp_ctx_update_buf_addr(struct neoisp_dev_s *neoispd) +{ + struct neoisp_job_s *job =3D &neoispd->queued_job; + struct neoisp_pipe_conf_s *cfg =3D &neoispd->context->hw.pipe_conf; + struct neoisp_buffer_s *buf_inp0 =3D job->buf[NEOISP_INPUT0_NODE]; + struct neoisp_buffer_s *buf_inp1 =3D job->buf[NEOISP_INPUT1_NODE]; + struct neoisp_buffer_s *buf_out =3D job->buf[NEOISP_FRAME_NODE]; + struct neoisp_buffer_s *buf_ir =3D job->buf[NEOISP_IR_NODE]; + struct neoisp_node_s *nd; + u32 ibpp, inp0_stride, inp1_stride; + dma_addr_t inp0_addr, inp1_addr; + + /* Input0 specific */ + nd =3D &neoispd->node[NEOISP_INPUT0_NODE]; + ibpp =3D (nd->neoisp_format->bit_depth + 7) / 8; + inp0_stride =3D nd->format.fmt.pix_mp.plane_fmt[0].bytesperline; + + /* Input0 - Take crop into account if any */ + inp0_addr =3D get_addr(buf_inp0, 0) + (nd->crop.left * ibpp) + (nd->crop.= top * inp0_stride); + + /* Input 1 specific */ + nd =3D &neoispd->node[NEOISP_INPUT1_NODE]; + ibpp =3D (nd->neoisp_format->bit_depth + 7) / 8; + inp1_stride =3D nd->format.fmt.pix_mp.plane_fmt[0].bytesperline; + + /* Input1 - Take crop into account if any */ + inp1_addr =3D get_addr(buf_inp1, 0) + + (nd->crop.left * ibpp) + + (nd->crop.top * inp1_stride); + + cfg->img0_in_addr =3D + FIELD_PREP(NEO_PIPE_CONF_IMG0_IN_ADDR_CAM0_ADDR, + NEO_PIPE_CONF_ADDR_CONVERT(inp0_addr)); + + /* Handle hdr inputs */ + nd =3D &neoispd->node[NEOISP_INPUT1_NODE]; + if (neoisp_node_link_is_enabled(nd)) { + cfg->img1_in_addr =3D + FIELD_PREP(NEO_PIPE_CONF_IMG1_IN_ADDR_CAM0_ADDR, + NEO_PIPE_CONF_ADDR_CONVERT(inp1_addr)); + } + + nd =3D &neoispd->node[NEOISP_FRAME_NODE]; + if (neoisp_node_link_is_enabled(nd)) { + /* Planar/multiplanar output image addresses */ + switch (nd->format.fmt.pix_mp.pixelformat) { + case V4L2_PIX_FMT_GREY: + case V4L2_PIX_FMT_Y10: + case V4L2_PIX_FMT_Y12: + case V4L2_PIX_FMT_Y16: + case V4L2_PIX_FMT_Y16_BE: + /* Monochrome formats: only output channel 0 is used */ + cfg->outch0_addr =3D + FIELD_PREP(NEO_PIPE_CONF_OUTCH0_ADDR_CAM0_ADDR, + NEO_PIPE_CONF_ADDR_CONVERT(get_addr(buf_out, 0))); + break; + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV61: + /* Semi-Planar formats: both output channels are used */ + cfg->outch0_addr =3D + FIELD_PREP(NEO_PIPE_CONF_OUTCH0_ADDR_CAM0_ADDR, + NEO_PIPE_CONF_ADDR_CONVERT(get_addr(buf_out, 0))); + cfg->outch1_addr =3D + FIELD_PREP(NEO_PIPE_CONF_OUTCH1_ADDR_CAM0_ADDR, + NEO_PIPE_CONF_ADDR_CONVERT(get_addr(buf_out, 1))); + break; + default: + /* Interleaved formats: only output channel 1 is used */ + cfg->outch1_addr =3D + FIELD_PREP(NEO_PIPE_CONF_OUTCH1_ADDR_CAM0_ADDR, + NEO_PIPE_CONF_ADDR_CONVERT(get_addr(buf_out, 0))); + break; + } + } + + nd =3D &neoispd->node[NEOISP_IR_NODE]; + if (neoisp_node_link_is_enabled(nd)) + cfg->outir_addr =3D + FIELD_PREP(NEO_PIPE_CONF_OUTIR_ADDR_CAM0_ADDR, + NEO_PIPE_CONF_ADDR_CONVERT(get_addr(buf_ir, 0))); +} + +void neoisp_ctx_update_gcm(struct neoisp_dev_s *neoispd, + struct neoisp_context_s *context, + struct v4l2_pix_format_mplane *pix_mp, + enum v4l2_ycbcr_encoding enc) +{ + struct neoisp_gcm_s *gcm =3D &context->hw.gcm; + enum v4l2_xfer_func xfer =3D pix_mp->xfer_func; + enum v4l2_quantization quant =3D pix_mp->quantization; + + int i, j; + s32 value, tmat[NEO_GAMMA_MATRIX_SIZE][NEO_GAMMA_MATRIX_SIZE]; + u32 tmp; + + /* + * Colorspaces definition are extracted from kernel documentation: + * https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/colorsp= aces-details.html + */ + + /* Transfer function */ + gcm->lowth_ctrl01 =3D + FIELD_PREP(NEO_GCM_LOWTH_CTRL01_CAM0_THRESHOLD0, xfer_lut[xfer].threshol= d) | + FIELD_PREP(NEO_GCM_LOWTH_CTRL01_CAM0_THRESHOLD1, xfer_lut[xfer].threshol= d); + gcm->lowth_ctrl2 =3D + FIELD_PREP(NEO_GCM_LOWTH_CTRL2_CAM0_THRESHOLD2, xfer_lut[xfer].threshold= ); + gcm->gamma0 =3D + FIELD_PREP(NEO_GCM_GAMMA0_CAM0_GAMMA0, xfer_lut[xfer].gamma) | + FIELD_PREP(NEO_GCM_GAMMA0_CAM0_OFFSET0, xfer_lut[xfer].gamma_offset); + gcm->gamma1 =3D + FIELD_PREP(NEO_GCM_GAMMA1_CAM0_GAMMA1, xfer_lut[xfer].gamma) | + FIELD_PREP(NEO_GCM_GAMMA1_CAM0_OFFSET1, xfer_lut[xfer].gamma_offset); + gcm->gamma2 =3D + FIELD_PREP(NEO_GCM_GAMMA2_CAM0_GAMMA2, xfer_lut[xfer].gamma) | + FIELD_PREP(NEO_GCM_GAMMA2_CAM0_OFFSET2, xfer_lut[xfer].gamma_offset); + + FIELD_MODIFY(NEO_GCM_BLKLVL0_CTRL_CAM0_GAIN0, &gcm->blklvl0_ctrl, + xfer_lut[xfer].blklvl_gain); + FIELD_MODIFY(NEO_GCM_BLKLVL1_CTRL_CAM0_GAIN1, &gcm->blklvl1_ctrl, + xfer_lut[xfer].blklvl_gain); + FIELD_MODIFY(NEO_GCM_BLKLVL2_CTRL_CAM0_GAIN2, &gcm->blklvl2_ctrl, + xfer_lut[xfer].blklvl_gain); + + /* + * Quantization + * + * The quantization is amended by transfer function gain. + * The default quantization is full-range for RGB formats and + * V4L2_COLORSPACE_JPEG. + * + * In limited range the offsets are defined by standard as follow: (16, 1= 28, 128) + * for 8-bit range while ISP offsets are defined for 12-bit range. + * Hence, the offsets defined by standard should be multiplied by 2^4=3D1= 6: + * (256, 2048, 2048) for 12-bit range + * The same quantization factors are applied to Y'CbCr for BT.601 and BT.= 709: + * (219*Y, 224*Pb, 224*Pr) + */ + tmp =3D (quant =3D=3D V4L2_QUANTIZATION_LIM_RANGE) ? + 256 : enc_lut[enc].offsets[0]; + gcm->ooffset0 =3D FIELD_PREP(NEO_GCM_OOFFSET0_CAM0_OFFSET0, tmp); + + /* Chrominance has the same offset for full or limited range */ + gcm->ooffset1 =3D FIELD_PREP(NEO_GCM_OOFFSET1_CAM0_OFFSET1, enc_lut[enc].= offsets[1]); + gcm->ooffset2 =3D FIELD_PREP(NEO_GCM_OOFFSET2_CAM0_OFFSET2, enc_lut[enc].= offsets[2]); + for (i =3D 0; i < NEO_GAMMA_MATRIX_SIZE; i++) { + s32 factor =3D (quant =3D=3D V4L2_QUANTIZATION_LIM_RANGE) ? + (i =3D=3D 0 ? 219 : 224) : 256; + for (j =3D 0; j < NEO_GAMMA_MATRIX_SIZE; j++) { + value =3D ((s32)enc_lut[enc].matrix[i][j] * factor) / 256; + value =3D ((s32)value * (s32)xfer_lut[xfer].gain) / 256; + tmat[i][j] =3D (s16)value; + } + } + gcm->omat0 =3D + FIELD_PREP(NEO_GCM_OMAT0_CAM0_R0C0, tmat[0][0]) | + FIELD_PREP(NEO_GCM_OMAT0_CAM0_R0C1, tmat[0][1]); + gcm->omat1 =3D + FIELD_PREP(NEO_GCM_OMAT1_CAM0_R0C2, tmat[0][2]); + gcm->omat2 =3D + FIELD_PREP(NEO_GCM_OMAT2_CAM0_R1C0, tmat[1][0]) | + FIELD_PREP(NEO_GCM_OMAT2_CAM0_R1C1, tmat[1][1]); + gcm->omat3 =3D + FIELD_PREP(NEO_GCM_OMAT3_CAM0_R1C2, tmat[1][2]); + gcm->omat4 =3D + FIELD_PREP(NEO_GCM_OMAT4_CAM0_R2C0, tmat[2][0]) | + FIELD_PREP(NEO_GCM_OMAT4_CAM0_R2C1, tmat[2][1]); + gcm->omat5 =3D + FIELD_PREP(NEO_GCM_OMAT5_CAM0_R2C2, tmat[2][2]); +} + +void neoisp_ctx_update_hdr_mode(struct neoisp_dev_s *neoispd, + struct neoisp_context_s *context) +{ + struct neoisp_hdr_merge_s *hmg =3D &context->hw.hdr_merge; + struct neoisp_hdr_decompress1_s *hd1 =3D &context->hw.hdr_decompress1; + + FIELD_MODIFY(NEO_HDR_MERGE_CTRL_CAM0_ENABLE, &hmg->ctrl, 1); + FIELD_MODIFY(NEO_HDR_DECOMPRESS1_CTRL_CAM0_ENABLE, &hd1->ctrl, 1); +} + +/* + * Set Head Color selection + */ +void neoisp_ctx_update_head_color(struct neoisp_dev_s *neoispd, + struct neoisp_context_s *context, u32 pixfmt) +{ + struct neoisp_hc_s *hc =3D &context->hw.hc; + u8 hoffset, voffset; + + switch (pixfmt) { + case (V4L2_PIX_FMT_SRGGB8): + case (V4L2_PIX_FMT_SRGGB10): + case (V4L2_PIX_FMT_SRGGB12): + case (V4L2_PIX_FMT_SRGGB14): + case (V4L2_PIX_FMT_SRGGB16): + hoffset =3D 0; + voffset =3D 0; + break; + case (V4L2_PIX_FMT_SGRBG8): + case (V4L2_PIX_FMT_SGRBG10): + case (V4L2_PIX_FMT_SGRBG12): + case (V4L2_PIX_FMT_SGRBG14): + case (V4L2_PIX_FMT_SGRBG16): + hoffset =3D 1; + voffset =3D 0; + break; + case (V4L2_PIX_FMT_SGBRG8): + case (V4L2_PIX_FMT_SGBRG10): + case (V4L2_PIX_FMT_SGBRG12): + case (V4L2_PIX_FMT_SGBRG14): + case (V4L2_PIX_FMT_SGBRG16): + hoffset =3D 0; + voffset =3D 1; + break; + case (V4L2_PIX_FMT_SBGGR8): + case (V4L2_PIX_FMT_SBGGR10): + case (V4L2_PIX_FMT_SBGGR12): + case (V4L2_PIX_FMT_SBGGR14): + case (V4L2_PIX_FMT_SBGGR16): + hoffset =3D 1; + voffset =3D 1; + break; + default: + dev_dbg(neoispd->dev, "Unsupported pixel format %#x\n", pixfmt); + return; + } + hc->ctrl =3D + FIELD_PREP(NEO_HC_CTRL_CAM0_HOFFSET, hoffset) | + FIELD_PREP(NEO_HC_CTRL_CAM0_VOFFSET, voffset); +} + +/* + * Update relevant IP parameters for monochrome sensors + */ +void neoisp_ctx_update_monochrome_fmt(struct neoisp_dev_s *neoispd, + struct neoisp_context_s *context, u32 pixfmt) +{ + struct neoisp_demosaic_s *dmsc; + struct neoisp_bnr_s *bnr; + + dmsc =3D &context->hw.demosaic; + bnr =3D &context->hw.bnr; + + if (format_is_monochrome(pixfmt)) { + FIELD_MODIFY(NEO_DEMOSAIC_CTRL_CAM0_FMT, &dmsc->ctrl, 2); /* Monochrome = format */ + FIELD_MODIFY(NEO_BNR_CTRL_CAM0_NHOOD, &bnr->ctrl, 1); /* 1-pixel Neighbo= urhood */ + } else { + FIELD_MODIFY(NEO_DEMOSAIC_CTRL_CAM0_FMT, &dmsc->ctrl, 0); /* Bayer forma= t */ + FIELD_MODIFY(NEO_BNR_CTRL_CAM0_NHOOD, &bnr->ctrl, 0); /* 2-pixel Neighbo= urhood */ + } +} + +void neoisp_ctx_update_packetizer(struct neoisp_dev_s *neoispd) +{ + struct neoisp_node_s *nd =3D &neoispd->node[NEOISP_FRAME_NODE]; + struct neoisp_packetizer_s *pck =3D &neoispd->context->hw.packetizer; + u8 obpp, lsa, rsa, type, order0, order1, order2, a0s, subsample; + u32 pixfmt; + + if (neoisp_node_link_is_enabled(nd)) { + pixfmt =3D nd->format.fmt.pix_mp.pixelformat; + obpp =3D nd->neoisp_format->bpp_enc; + } else { + /* Force dummy buffer configuration to YUYV format */ + const struct neoisp_fmt_s *fmt =3D + neoisp_find_video_capture_format(V4L2_PIX_FMT_YUYV); + + if (!fmt) { + dev_err(neoispd->dev, "YUYV pixel format not found\n"); + return; + } + + pixfmt =3D V4L2_PIX_FMT_YUYV; + obpp =3D fmt->bpp_enc; + } + + switch (pixfmt) { + case V4L2_PIX_FMT_Y10: + rsa =3D 2; + lsa =3D 0; + break; + case V4L2_PIX_FMT_Y12: + rsa =3D 0; + lsa =3D 0; + break; + case V4L2_PIX_FMT_Y16: + rsa =3D 0; + lsa =3D 4; + break; + default: + rsa =3D 4; + lsa =3D 0; + break; + } + + switch (pixfmt) { + case V4L2_PIX_FMT_GREY: + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_Y10: + case V4L2_PIX_FMT_Y12: + case V4L2_PIX_FMT_Y16: + case V4L2_PIX_FMT_Y16_BE: + type =3D 0; + subsample =3D 2; + /* Set channels orders */ + order0 =3D 2; + order1 =3D 0; + order2 =3D 1; + /* Remove 0-padding */ + a0s =3D 0; + break; + case V4L2_PIX_FMT_NV21: + type =3D 0; + subsample =3D 2; + /* Set channels orders */ + order0 =3D 2; + order1 =3D 1; + order2 =3D 0; + /* Remove 0-padding */ + a0s =3D 0; + break; + case V4L2_PIX_FMT_NV16: + type =3D 0; + subsample =3D 1; + /* Set channels orders */ + order0 =3D 2; + order1 =3D 0; + order2 =3D 1; + /* Remove 0-padding */ + a0s =3D 0; + break; + case V4L2_PIX_FMT_NV61: + type =3D 0; + subsample =3D 1; + /* Set channels orders */ + order0 =3D 2; + order1 =3D 1; + order2 =3D 0; + /* Remove 0-padding */ + a0s =3D 0; + break; + case V4L2_PIX_FMT_YUYV: + type =3D 1; + subsample =3D 1; + /* Set channels orders */ + order0 =3D 0; + order1 =3D 1; + order2 =3D 3; + /* Remove 0-padding */ + a0s =3D 0; + break; + case V4L2_PIX_FMT_VYUY: + type =3D 1; + subsample =3D 1; + /* Set channels orders */ + order0 =3D 1; + order1 =3D 2; + order2 =3D 0; + /* Remove 0-padding */ + a0s =3D 0; + break; + case V4L2_PIX_FMT_UYVY: + type =3D 1; + subsample =3D 1; + /* Set channels orders */ + order0 =3D 1; + order1 =3D 0; + order2 =3D 2; + /* Remove 0-padding */ + a0s =3D 0; + break; + case V4L2_PIX_FMT_YUVX32: + type =3D 1; + subsample =3D 0; + /* Set channels orders */ + order0 =3D 0; + order1 =3D 1; + order2 =3D 2; + /* Add 0-padding */ + a0s =3D 8; + break; + case V4L2_PIX_FMT_VUYX32: + type =3D 1; + subsample =3D 0; + /* Set channels orders */ + order0 =3D 2; + order1 =3D 1; + order2 =3D 0; + /* Add 0-padding */ + a0s =3D 8; + break; + case V4L2_PIX_FMT_XBGR32: + type =3D 1; + subsample =3D 0; + /* Set channels orders */ + order0 =3D 2; + order1 =3D 1; + order2 =3D 0; + /* Add 0-padding */ + a0s =3D 8; + break; + case V4L2_PIX_FMT_RGBX32: + type =3D 1; + subsample =3D 0; + /* Set channels orders */ + order0 =3D 0; + order1 =3D 1; + order2 =3D 2; + /* Add 0-padding */ + a0s =3D 8; + break; + case V4L2_PIX_FMT_BGR24: + type =3D 1; + subsample =3D 0; + /* Set channels orders */ + order0 =3D 2; + order1 =3D 1; + order2 =3D 0; + /* Remove 0-padding */ + a0s =3D 0; + break; + default: /* All other pixel formats */ + type =3D 1; + subsample =3D 0; + /* Set channels orders */ + order0 =3D 0; + order1 =3D 1; + order2 =3D 2; + /* Remove 0-padding */ + a0s =3D 0; + break; + } + + pck->ch0_ctrl =3D + FIELD_PREP(NEO_PACKETIZER_CH0_CTRL_CAM0_OBPP, obpp) | + FIELD_PREP(NEO_PACKETIZER_CH0_CTRL_CAM0_RSA, rsa) | + FIELD_PREP(NEO_PACKETIZER_CH0_CTRL_CAM0_LSA, lsa); + + /* Keep same ch12 lsa/rsa config. */ + FIELD_MODIFY(NEO_PACKETIZER_CH12_CTRL_CAM0_OBPP, &pck->ch12_ctrl, obpp); + FIELD_MODIFY(NEO_PACKETIZER_CH12_CTRL_CAM0_SUBSAMPLE, &pck->ch12_ctrl, su= bsample); + + pck->pack_ctrl =3D + FIELD_PREP(NEO_PACKETIZER_PACK_CTRL_CAM0_TYPE, type) | + FIELD_PREP(NEO_PACKETIZER_PACK_CTRL_CAM0_ORDER0, order0) | + FIELD_PREP(NEO_PACKETIZER_PACK_CTRL_CAM0_ORDER1, order1) | + FIELD_PREP(NEO_PACKETIZER_PACK_CTRL_CAM0_ORDER2, order2) | + FIELD_PREP(NEO_PACKETIZER_PACK_CTRL_CAM0_A0S, a0s); +} + +/* + * Set pipe conf fixed settings: image size, bpp, line stride, and dummy + * addresses. + */ +void neoisp_ctx_update_pipe_conf(struct neoisp_dev_s *neoispd) +{ + struct neoisp_pipe_conf_s *cfg =3D &neoispd->context->hw.pipe_conf; + struct neoisp_node_s *nd; + u32 width, height, obpp, irbpp, inp0_stride, inp1_stride; + + /* Input0 specific */ + nd =3D &neoispd->node[NEOISP_INPUT0_NODE]; + width =3D nd->crop.width; + height =3D nd->crop.height; + inp0_stride =3D nd->format.fmt.pix_mp.plane_fmt[0].bytesperline; + + FIELD_MODIFY(NEO_PIPE_CONF_IMG_CONF_CAM0_IBPP0, + &cfg->img_conf, nd->neoisp_format->bpp_enc); + + /* Input 1 specific */ + nd =3D &neoispd->node[NEOISP_INPUT1_NODE]; + inp1_stride =3D nd->format.fmt.pix_mp.plane_fmt[0].bytesperline; + + FIELD_MODIFY(NEO_PIPE_CONF_IMG_CONF_CAM0_IBPP1, + &cfg->img_conf, nd->neoisp_format->bpp_enc); + + /* Configure registers */ + cfg->img_size =3D + FIELD_PREP(NEO_PIPE_CONF_IMG_SIZE_CAM0_WIDTH, width) | + FIELD_PREP(NEO_PIPE_CONF_IMG_SIZE_CAM0_HEIGHT, height); + cfg->img0_in_ls =3D + FIELD_PREP(NEO_PIPE_CONF_IMG0_IN_LS_CAM0_LS, inp0_stride); + + /* Handle hdr inputs */ + nd =3D &neoispd->node[NEOISP_INPUT1_NODE]; + if (neoisp_node_link_is_enabled(nd)) { + cfg->img1_in_ls =3D + FIELD_PREP(NEO_PIPE_CONF_IMG1_IN_LS_CAM0_LS, inp1_stride); + } else { + cfg->img1_in_addr =3D + FIELD_PREP(NEO_PIPE_CONF_IMG1_IN_ADDR_CAM0_ADDR, 0u); + cfg->img1_in_ls =3D + FIELD_PREP(NEO_PIPE_CONF_IMG1_IN_LS_CAM0_LS, 0u); + } + + nd =3D &neoispd->node[NEOISP_FRAME_NODE]; + if (neoisp_node_link_is_enabled(nd)) { + obpp =3D (nd->neoisp_format->bit_depth + 7) / 8; + + switch (nd->format.fmt.pix_mp.pixelformat) { + case V4L2_PIX_FMT_GREY: + case V4L2_PIX_FMT_Y10: + case V4L2_PIX_FMT_Y12: + case V4L2_PIX_FMT_Y16: + case V4L2_PIX_FMT_Y16_BE: + /* + * Monochrome formats: + * - output0 is used for Y component + * - output1 on dummy buffer + */ + cfg->outch1_addr =3D + FIELD_PREP(NEO_PIPE_CONF_OUTCH1_ADDR_CAM0_ADDR, + NEO_PIPE_CONF_ADDR_CONVERT(neoispd->dummy_dma)); + cfg->outch0_ls =3D + FIELD_PREP(NEO_PIPE_CONF_OUTCH0_LS_CAM0_LS, obpp * width); + cfg->outch1_ls =3D + FIELD_PREP(NEO_PIPE_CONF_OUTCH1_LS_CAM0_LS, 0u); + break; + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV61: + /* + * Semi-Planar formats: + * - output0 is used for Y component + * - output1 is used for UV components + */ + cfg->outch1_ls =3D + FIELD_PREP(NEO_PIPE_CONF_OUTCH1_LS_CAM0_LS, obpp * width); + cfg->outch0_ls =3D + FIELD_PREP(NEO_PIPE_CONF_OUTCH0_LS_CAM0_LS, obpp * width); + break; + default: + /* + * Interleaved formats: + * - output0 is not used at all + * - output1 is used for YUV or RGB components + */ + cfg->outch0_addr =3D + FIELD_PREP(NEO_PIPE_CONF_OUTCH0_ADDR_CAM0_ADDR, 0u); + cfg->outch0_ls =3D + FIELD_PREP(NEO_PIPE_CONF_OUTCH0_LS_CAM0_LS, 0u); + cfg->outch1_ls =3D + FIELD_PREP(NEO_PIPE_CONF_OUTCH1_LS_CAM0_LS, obpp * width); + break; + } + } else { + /* Default dummy pixelformat is set to YUYV */ + cfg->outch0_addr =3D + FIELD_PREP(NEO_PIPE_CONF_OUTCH0_ADDR_CAM0_ADDR, + NEO_PIPE_CONF_ADDR_CONVERT(neoispd->dummy_dma)); + cfg->outch1_addr =3D + FIELD_PREP(NEO_PIPE_CONF_OUTCH1_ADDR_CAM0_ADDR, + NEO_PIPE_CONF_ADDR_CONVERT(neoispd->dummy_dma)); + cfg->outch0_ls =3D + FIELD_PREP(NEO_PIPE_CONF_OUTCH0_LS_CAM0_LS, 0u); + cfg->outch1_ls =3D + FIELD_PREP(NEO_PIPE_CONF_OUTCH1_LS_CAM0_LS, 0u); + } + + nd =3D &neoispd->node[NEOISP_IR_NODE]; + if (neoisp_node_link_is_enabled(nd)) { + irbpp =3D (nd->neoisp_format->bit_depth + 7) / 8; + + cfg->outir_ls =3D + FIELD_PREP(NEO_PIPE_CONF_OUTIR_LS_CAM0_LS, irbpp * width); + } else { + cfg->outir_addr =3D + FIELD_PREP(NEO_PIPE_CONF_OUTIR_ADDR_CAM0_ADDR, + NEO_PIPE_CONF_ADDR_CONVERT(neoispd->dummy_dma)); + cfg->outir_ls =3D + FIELD_PREP(NEO_PIPE_CONF_OUTIR_LS_CAM0_LS, 0u); + } +} + +/* + * neoisp_ctx_update_w_user_params is used to update the context of the + * queued node with user space values. + */ +void neoisp_ctx_update_w_user_params(struct neoisp_dev_s *neoispd) +{ + struct neoisp_buffer_s *buf =3D neoispd->queued_job.buf[NEOISP_PARAMS_NOD= E]; + struct v4l2_isp_buffer *params; + size_t block_offset =3D 0, max_offset; + + if (IS_ERR_OR_NULL(buf)) + return; + + params =3D (struct v4l2_isp_buffer *)get_vaddr(buf); + + if (!params || params->data_size =3D=3D 0) + /* No relevant parameters in this buffer */ + return; + + max_offset =3D params->data_size; + + /* + * Walk the list of parameter blocks and process them. No + * validation is done here, as the content of the parameters + * buffer is already checked when the buffer is queued. + */ + while (block_offset < max_offset) { + const struct neoisp_block_handler_s *block_handler; + const union neoisp_params_block_u *block; + + block =3D (const union neoisp_params_block_u *) + ¶ms->data[block_offset]; + block_offset +=3D block->header.size; + + block_handler =3D &neoisp_block_handlers[block->header.type]; + block_handler->handler(neoispd->context, block); + } +} + +/* + * neoisp_upload_context is used to write all parameters to registers and + * memory. + * + * The register copy starts from PIPE_CONF.IMG_CONF offset, up to the late= st + * writable register in AF unit. + * + * The memory copy is performed by block, because base addresses of the LUT + * are not continuous. + */ +void neoisp_ctx_upload_context(struct neoisp_dev_s *neoispd) +{ + struct neoisp_context_s *ctx =3D neoispd->context; + u32 *src =3D (u32 *)&ctx->hw.pipe_conf.img_conf; + + reg_blk_write(neoispd, NEO_PIPE_CONF_IMG_CONF_CAM0, src, + NEO_AUTOFOCUS_ROI0_SUM0_CAM0 - NEO_PIPE_CONF_IMG_CONF_CAM0); + + local_mem_blk_write(neoispd, NEO_VIGNETTING_TABLE_MAP, + &ctx->vig.vignetting_table); + local_mem_blk_write(neoispd, NEO_DRC_GLOBAL_TONEMAP_MAP, + &ctx->gtm.drc_global_tonemap); + local_mem_blk_write(neoispd, NEO_DRC_LOCAL_TONEMAP_MAP, + &ctx->ltm.drc_local_tonemap); +} + +#define NEOISP_STATS_BLOCK_INFO(block, type, ext) \ + [NEOISP_STATS_BLK_## block] =3D { \ + .size =3D sizeof(struct neoisp_ ## type ## _ ## ext ## _stats_es), \ + } + +#define NEOISP_STATS_BLOCK_INFO_REG(block, type) \ + NEOISP_STATS_BLOCK_INFO(block, type, reg) + +#define NEOISP_STATS_BLOCK_INFO_MEM(block, type) \ + NEOISP_STATS_BLOCK_INFO(block, type, mem) + +static const struct +v4l2_isp_stats_block_type_info neoisp_stats_block_types_info[] =3D { + NEOISP_STATS_BLOCK_INFO_REG(RCTEMP, ctemp), + NEOISP_STATS_BLOCK_INFO_REG(RDRC, drc), + NEOISP_STATS_BLOCK_INFO_REG(RAF, af), + NEOISP_STATS_BLOCK_INFO_REG(RBNR, bnr), + NEOISP_STATS_BLOCK_INFO_REG(RNR, nr), + NEOISP_STATS_BLOCK_INFO_REG(REE, ee), + NEOISP_STATS_BLOCK_INFO_REG(RDF, df), + NEOISP_STATS_BLOCK_INFO_MEM(MCTEMP, ctemp), + NEOISP_STATS_BLOCK_INFO_MEM(MRGBIR, rgbir), + NEOISP_STATS_BLOCK_INFO_MEM(MHIST, hist), + NEOISP_STATS_BLOCK_INFO_MEM(MDRC, drc), +}; + +static void neoisp_ctx_get_stats_blk(struct neoisp_dev_s *neoispd, u32 bty= pe, + union neoisp_stats_block_u *blk) +{ + switch (btype) { + case NEOISP_STATS_BLK_RCTEMP: + reg_blk_read(neoispd, NEO_ALIAS_ALIAS_REG0, + (u32 *)&blk->rctemp.stat, + sizeof(struct neoisp_ctemp_reg_stats_s)); + break; + case NEOISP_STATS_BLK_RDRC: + reg_blk_read(neoispd, NEO_ALIAS_ALIAS_REG59, + (u32 *)&blk->rdrc.stat, + sizeof(struct neoisp_drc_reg_stats_s)); + break; + case NEOISP_STATS_BLK_RAF: + reg_blk_read(neoispd, NEO_ALIAS_ALIAS_REG61, + (u32 *)&blk->raf.stat, + sizeof(struct neoisp_af_reg_stats_s)); + break; + case NEOISP_STATS_BLK_RBNR: + reg_blk_read(neoispd, NEO_ALIAS_ALIAS_REG79, + (u32 *)&blk->rbnr.stat, + sizeof(struct neoisp_bnr_reg_stats_s)); + break; + case NEOISP_STATS_BLK_RNR: + reg_blk_read(neoispd, NEO_ALIAS_ALIAS_REG81, + (u32 *)&blk->rnr.stat, + sizeof(struct neoisp_nr_reg_stats_s)); + break; + case NEOISP_STATS_BLK_REE: + reg_blk_read(neoispd, NEO_ALIAS_ALIAS_REG82, + (u32 *)&blk->ree.stat, + sizeof(struct neoisp_ee_reg_stats_s)); + break; + case NEOISP_STATS_BLK_RDF: + reg_blk_read(neoispd, NEO_ALIAS_ALIAS_REG83, + (u32 *)&blk->rdf.stat, + sizeof(struct neoisp_df_reg_stats_s)); + break; + case NEOISP_STATS_BLK_MCTEMP: + /* Get ctemp stats from memory */ + local_mem_blk_read(neoispd, NEO_CTEMP_R_SUM_MAP, + &blk->mctemp.stat.ctemp_r_sum); + + local_mem_blk_read(neoispd, NEO_CTEMP_G_SUM_MAP, + &blk->mctemp.stat.ctemp_g_sum); + + local_mem_blk_read(neoispd, NEO_CTEMP_B_SUM_MAP, + &blk->mctemp.stat.ctemp_b_sum); + + local_mem_blk_read(neoispd, NEO_CTEMP_PIX_CNT_MAP, + &blk->mctemp.stat.ctemp_pix_cnt); + break; + case NEOISP_STATS_BLK_MRGBIR: + /* Get rgbir stats from memory */ + local_mem_blk_read(neoispd, NEO_RGBIR_HIST_MAP, + &blk->mrgbir.stat); + break; + case NEOISP_STATS_BLK_MHIST: + /* Get histograms stats from memory */ + local_mem_blk_read(neoispd, NEO_HIST_STAT_MAP, + &blk->mhist.stat); + break; + case NEOISP_STATS_BLK_MDRC: + /* Get drc local sum stats from memory */ + local_mem_blk_read(neoispd, NEO_DRC_LOCAL_SUM_MAP, + &blk->mdrc.stat.drc_local_sum); + + /* Get drc hist roi0 stats from memory */ + local_mem_blk_read(neoispd, NEO_DRC_GLOBAL_HIST_ROI0_MAP, + &blk->mdrc.stat.drc_global_hist_roi0); + + /* Get drc hist roi1 stats from memory */ + local_mem_blk_read(neoispd, NEO_DRC_GLOBAL_HIST_ROI1_MAP, + &blk->mdrc.stat.drc_global_hist_roi1); + break; + default: + dev_err(neoispd->dev, "Error: unknown stats block id (%u)\n", btype); + return; + } +} + +static const __u32 neoisp_stats_blocks[] =3D { + NEOISP_STATS_BLK_RCTEMP, + NEOISP_STATS_BLK_RDRC, + NEOISP_STATS_BLK_RAF, + NEOISP_STATS_BLK_RBNR, + NEOISP_STATS_BLK_RNR, + NEOISP_STATS_BLK_REE, + NEOISP_STATS_BLK_RDF, + NEOISP_STATS_BLK_MCTEMP, + NEOISP_STATS_BLK_MRGBIR, + NEOISP_STATS_BLK_MHIST, + NEOISP_STATS_BLK_MDRC, +}; + +void neoisp_ctx_get_stats(struct neoisp_dev_s *neoispd, struct neoisp_buff= er_s *buf) +{ + struct neoisp_node_s *node =3D &neoispd->node[NEOISP_STATS_NODE]; + struct v4l2_isp_buffer *stats; + u32 *blk_list, count; + + /* Check if stats node link is enabled */ + if (!neoisp_node_link_is_enabled(node)) + return; + + if (IS_ERR_OR_NULL(buf)) { + dev_err(neoispd->dev, "Error: stats pointer\n"); + return; + } + + stats =3D (struct v4l2_isp_buffer *)get_vaddr(buf); + v4l2_isp_stats_init_buffer(stats, V4L2_ISP_VERSION_V1); + + blk_list =3D (u32 *)neoisp_stats_blocks; + count =3D ARRAY_SIZE(neoisp_stats_blocks); + for (int i =3D 0; i < count; i++) { + struct v4l2_isp_block_header *header =3D + v4l2_isp_stats_init_block(neoispd->dev, stats, + neoisp_stats_block_types_info, + ARRAY_SIZE(neoisp_stats_block_types_info), + blk_list[i], NEOISP_EXT_STATS_MAX_SIZE); + if (IS_ERR(header)) { + dev_err(neoispd->dev, "Error: initializing stats block %d\n", i); + continue; + } + + neoisp_ctx_get_stats_blk(neoispd, blk_list[i], + (union neoisp_stats_block_u *)header); + } +} diff --git a/drivers/media/platform/nxp/neoisp/neoisp_ctx.h b/drivers/media= /platform/nxp/neoisp/neoisp_ctx.h new file mode 100644 index 000000000000..41575c2dfef6 --- /dev/null +++ b/drivers/media/platform/nxp/neoisp/neoisp_ctx.h @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * NEOISP context definition + * + * Copyright 2023-2026 NXP + */ + +#ifndef __NXP_NEOISP_CTX_H +#define __NXP_NEOISP_CTX_H + +#include + +#include "neoisp.h" +#include "neoisp_regs.h" + +#define NEOISP_HDR_SHIFT_RADIX 5 /* Hdr decompress block ratio field form= at is u7.5 */ + +/* Block offset */ +#define ISP_OFF_POS 0UL +#define ISP_OFF_MASK (0xFFFFUL << ISP_OFF_POS) +#define ISP_GET_OFF(x) (((x) & ISP_OFF_MASK) >> ISP_OFF_POS) +#define ISP_OFF(x) (((x) << ISP_OFF_POS) & ISP_OFF_MASK) + +/* Block size */ +#define ISP_SZ_POS 16UL +#define ISP_SZ_MASK (0xFFFFUL << ISP_SZ_POS) +#define ISP_GET_SZ(x) (((x) & ISP_SZ_MASK) >> ISP_SZ_POS) +#define ISP_SZ(x) (((x) << ISP_SZ_POS) & ISP_SZ_MASK) + +#define ISP_MAP_TUPLE(x, y, z) (ISP_OFF((x)) | ISP_SZ(((y) * sizeof(z)))) + +enum isp_block_map_e { + NEO_CTEMP_R_SUM_MAP =3D ISP_MAP_TUPLE(0x0, NEO_CTEMP_R_SUM_CNT, u32), + NEO_CTEMP_G_SUM_MAP =3D ISP_MAP_TUPLE(0x100, NEO_CTEMP_G_SUM_CNT, u32), + NEO_CTEMP_B_SUM_MAP =3D ISP_MAP_TUPLE(0x200, NEO_CTEMP_B_SUM_CNT, u32), + NEO_CTEMP_PIX_CNT_MAP =3D ISP_MAP_TUPLE(0x300, NEO_CTEMP_PIX_CNT_CNT, u16= ), + NEO_RGBIR_HIST_MAP =3D ISP_MAP_TUPLE(0x400, NEO_RGBIR_HIST_CNT, u32), + NEO_HIST_STAT_MAP =3D ISP_MAP_TUPLE(0x800, NEO_HIST_STAT_CNT, u32), + + NEO_DRC_GLOBAL_HIST_ROI0_MAP =3D ISP_MAP_TUPLE(0x1000, NEO_DRC_GLOBAL_HIS= T_ROI_CNT, u32), + NEO_DRC_GLOBAL_HIST_ROI1_MAP =3D ISP_MAP_TUPLE(0x1700, NEO_DRC_GLOBAL_HIS= T_ROI_CNT, u32), + NEO_DRC_LOCAL_SUM_MAP =3D ISP_MAP_TUPLE(0x1E00, NEO_DRC_LOCAL_SUM_CNT, u3= 2), + NEO_VIGNETTING_TABLE_MAP =3D ISP_MAP_TUPLE(0x2E00, NEO_VIGNETTING_TABLE_S= IZE, u16), + NEO_DRC_GLOBAL_TONEMAP_MAP =3D ISP_MAP_TUPLE(0x4600, NEO_DRC_GLOBAL_TONEM= AP_SIZE, u16), + NEO_DRC_LOCAL_TONEMAP_MAP =3D ISP_MAP_TUPLE(0x4A00, NEO_DRC_LOCAL_TONEMAP= _SIZE, u8), +}; + +/* + * Neoisp context API functions, used to configure and update a context fr= om + * the params buffer, to upload a context into HW blocks once image proces= sing + * can start, and to capture the generated stats once processing is done. + */ +void neoisp_ctx_set_default_context(struct neoisp_context_s *context); + +void neoisp_ctx_update_buf_addr(struct neoisp_dev_s *neoispd); +void neoisp_ctx_update_gcm(struct neoisp_dev_s *neoispd, + struct neoisp_context_s *context, + struct v4l2_pix_format_mplane *pix_mp, + enum v4l2_ycbcr_encoding enc); +void neoisp_ctx_update_hdr_mode(struct neoisp_dev_s *neoispd, + struct neoisp_context_s *context); +void neoisp_ctx_update_head_color(struct neoisp_dev_s *neoispd, + struct neoisp_context_s *context, + u32 pixfmt); +void neoisp_ctx_update_monochrome_fmt(struct neoisp_dev_s *neoispd, + struct neoisp_context_s *context, + u32 pixfmt); +void neoisp_ctx_update_packetizer(struct neoisp_dev_s *neoispd); +void neoisp_ctx_update_pipe_conf(struct neoisp_dev_s *neoispd); +void neoisp_ctx_update_w_user_params(struct neoisp_dev_s *neoispd); + +void neoisp_ctx_upload_context(struct neoisp_dev_s *neoispd); + +void neoisp_ctx_get_stats(struct neoisp_dev_s *neoispd, + struct neoisp_buffer_s *buf); + +#endif /* __NXP_NEOISP_CTX_H */ diff --git a/drivers/media/platform/nxp/neoisp/neoisp_fmt.h b/drivers/media= /platform/nxp/neoisp/neoisp_fmt.h new file mode 100644 index 000000000000..954961403eb7 --- /dev/null +++ b/drivers/media/platform/nxp/neoisp/neoisp_fmt.h @@ -0,0 +1,495 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * NEOISP supported formats definition + * + * Copyright 2023-2026 NXP + * + */ + +#ifndef __NXP_NEOISP_FMT_H +#define __NXP_NEOISP_FMT_H + +#include +#include + +#include "neoisp.h" + +static const struct v4l2_frmsize_stepwise neoisp_frmsize_stepwise =3D { + .min_width =3D NEOISP_MIN_W, + .min_height =3D NEOISP_MIN_H, + .max_width =3D NEOISP_MAX_W, + .max_height =3D NEOISP_MAX_H, + .step_width =3D 1UL << NEOISP_ALIGN_W, + .step_height =3D 1UL << NEOISP_ALIGN_H, +}; + +static const struct neoisp_fmt_s formats_vcap[] =3D { + { + .fourcc =3D V4L2_PIX_FMT_BGR24, /* 24-bit BGR 8-8-8 */ + .align =3D 32, + .bit_depth =3D 24, + .num_planes =3D 1, + .bpp_enc =3D 6, + .is_rgb =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_ALL_SRGB, + .colorspace_default =3D V4L2_COLORSPACE_SRGB, + .type =3D NEOISP_FMT_VIDEO_CAPTURE, + }, { + .fourcc =3D V4L2_PIX_FMT_RGB24, /* 24-bit RGB 8-8-8 */ + .align =3D 32, + .bit_depth =3D 24, + .num_planes =3D 1, + .bpp_enc =3D 6, + .is_rgb =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_ALL_SRGB, + .colorspace_default =3D V4L2_COLORSPACE_SRGB, + .type =3D NEOISP_FMT_VIDEO_CAPTURE, + }, { + .fourcc =3D V4L2_PIX_FMT_XBGR32, /* 32-bit BGRX 8-8-8-8 */ + .align =3D 32, + .bit_depth =3D 32, + .num_planes =3D 1, + .bpp_enc =3D 6, + .is_rgb =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_ALL_SRGB, + .colorspace_default =3D V4L2_COLORSPACE_SRGB, + .type =3D NEOISP_FMT_VIDEO_CAPTURE, + }, { + .fourcc =3D V4L2_PIX_FMT_RGBX32, /* 32-bit RGBX 8-8-8-8 */ + .align =3D 32, + .bit_depth =3D 32, + .num_planes =3D 1, + .bpp_enc =3D 6, + .is_rgb =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_ALL_SRGB, + .colorspace_default =3D V4L2_COLORSPACE_SRGB, + .type =3D NEOISP_FMT_VIDEO_CAPTURE, + }, { + .fourcc =3D V4L2_PIX_FMT_NV12, /* 12-bit Y/CbCr 4:2:0 */ + .align =3D 32, + .bit_depth =3D 8, + .num_planes =3D 2, + .pl_divisors =3D {1, 2}, + .bpp_enc =3D 6, + .is_rgb =3D 0, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_ALL_SRGB, + .colorspace_default =3D V4L2_COLORSPACE_SMPTE170M, + .type =3D NEOISP_FMT_VIDEO_CAPTURE, + }, { + .fourcc =3D V4L2_PIX_FMT_NV21, /* 12-bit Y/CrCb 4:2:0 */ + .align =3D 32, + .bit_depth =3D 8, + .num_planes =3D 2, + .pl_divisors =3D {1, 2}, + .bpp_enc =3D 6, + .is_rgb =3D 0, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_ALL_SRGB, + .colorspace_default =3D V4L2_COLORSPACE_SMPTE170M, + .type =3D NEOISP_FMT_VIDEO_CAPTURE, + }, { + .fourcc =3D V4L2_PIX_FMT_NV16, /* 16-bit Y/CbCr 4:2:2 */ + .align =3D 32, + .bit_depth =3D 8, + .num_planes =3D 2, + .pl_divisors =3D {1, 1}, + .bpp_enc =3D 6, + .is_rgb =3D 0, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_ALL_SRGB, + .colorspace_default =3D V4L2_COLORSPACE_SMPTE170M, + .type =3D NEOISP_FMT_VIDEO_CAPTURE, + }, { + .fourcc =3D V4L2_PIX_FMT_NV61, /* 16-bit Y/CrCb 4:2:2 */ + .align =3D 32, + .bit_depth =3D 8, + .num_planes =3D 2, + .pl_divisors =3D {1, 1}, + .bpp_enc =3D 6, + .is_rgb =3D 0, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_ALL_SRGB, + .colorspace_default =3D V4L2_COLORSPACE_SMPTE170M, + .type =3D NEOISP_FMT_VIDEO_CAPTURE, + }, { + .fourcc =3D V4L2_PIX_FMT_UYVY, /* 16-bit YUV 4:2:2 */ + .align =3D 32, + .bit_depth =3D 16, + .num_planes =3D 1, + .bpp_enc =3D 6, + .is_rgb =3D 0, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_ALL_SRGB, + .colorspace_default =3D V4L2_COLORSPACE_SMPTE170M, + .type =3D NEOISP_FMT_VIDEO_CAPTURE, + }, { + .fourcc =3D V4L2_PIX_FMT_YUV24, /* 24-bit YUV 4:4:4 8-8-8 */ + .align =3D 32, + .bit_depth =3D 24, + .num_planes =3D 1, + .bpp_enc =3D 6, + .is_rgb =3D 0, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_ALL_SRGB, + .colorspace_default =3D V4L2_COLORSPACE_SMPTE170M, + .type =3D NEOISP_FMT_VIDEO_CAPTURE, + }, { + .fourcc =3D V4L2_PIX_FMT_YUVX32, /* 32-bit YUVX 4:4:4 */ + .align =3D 32, + .bit_depth =3D 32, + .num_planes =3D 1, + .bpp_enc =3D 6, + .is_rgb =3D 0, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_ALL_SRGB, + .colorspace_default =3D V4L2_COLORSPACE_SMPTE170M, + .type =3D NEOISP_FMT_VIDEO_CAPTURE, + }, { + .fourcc =3D V4L2_PIX_FMT_VUYX32, /* 32-bit VUYX 4:4:4 */ + .align =3D 32, + .bit_depth =3D 32, + .num_planes =3D 1, + .bpp_enc =3D 6, + .is_rgb =3D 0, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_ALL_SRGB, + .colorspace_default =3D V4L2_COLORSPACE_SMPTE170M, + .type =3D NEOISP_FMT_VIDEO_CAPTURE, + }, { + .fourcc =3D V4L2_PIX_FMT_YUYV, /* 16-bit YUYV 4:2:2 */ + .align =3D 32, + .bit_depth =3D 16, + .num_planes =3D 1, + .bpp_enc =3D 6, + .is_rgb =3D 0, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_ALL_SRGB, + .colorspace_default =3D V4L2_COLORSPACE_SMPTE170M, + .type =3D NEOISP_FMT_VIDEO_CAPTURE, + }, { + .fourcc =3D V4L2_PIX_FMT_VYUY, /* 16-bit VYUY 4:2:2 */ + .align =3D 32, + .bit_depth =3D 16, + .num_planes =3D 1, + .bpp_enc =3D 6, + .is_rgb =3D 0, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_ALL_SRGB, + .colorspace_default =3D V4L2_COLORSPACE_SMPTE170M, + .type =3D NEOISP_FMT_VIDEO_CAPTURE, + }, { + .fourcc =3D V4L2_PIX_FMT_GREY, /* 8-bit Monochrome */ + .align =3D 32, + .bit_depth =3D 8, + .num_planes =3D 1, + .bpp_enc =3D 6, + .is_rgb =3D 0, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_CAPTURE, + }, { + .fourcc =3D V4L2_PIX_FMT_Y10, /* 10-bit Monochrome */ + .align =3D 32, + .bit_depth =3D 10, + .num_planes =3D 1, + .bpp_enc =3D 4, + .is_rgb =3D 0, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_CAPTURE, + }, { + .fourcc =3D V4L2_PIX_FMT_Y12, /* 12-bit Monochrome */ + .align =3D 32, + .bit_depth =3D 12, + .num_planes =3D 1, + .bpp_enc =3D 0, + .is_rgb =3D 0, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_CAPTURE, + }, { + .fourcc =3D V4L2_PIX_FMT_Y16, /* 16-bit Monochrome */ + .align =3D 32, + .bit_depth =3D 16, + .num_planes =3D 1, + .bpp_enc =3D 2, + .is_rgb =3D 0, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_CAPTURE, + }, { + .fourcc =3D V4L2_PIX_FMT_Y16_BE, /* 16-bit big-endian Monochrome */ + .align =3D 32, + .bit_depth =3D 16, + .num_planes =3D 1, + .bpp_enc =3D 2, + .is_rgb =3D 0, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_CAPTURE, + } +}; + +static const struct neoisp_fmt_s formats_vcap_ir[] =3D { + { + .fourcc =3D V4L2_PIX_FMT_GREY, /* 8-bit Greyscale */ + .align =3D 32, + .bit_depth =3D 8, + .num_planes =3D 1, + .is_rgb =3D 0, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_CAPTURE, + }, { + .fourcc =3D V4L2_PIX_FMT_Y16, /* 16-bit Greyscale */ + .align =3D 32, + .bit_depth =3D 16, + .num_planes =3D 1, + .is_rgb =3D 0, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_CAPTURE, + } +}; + +static const struct neoisp_fmt_s formats_vout[] =3D { + { + .fourcc =3D V4L2_PIX_FMT_SRGGB8, /* 8-bit Bayer RGRG/GBGB */ + .align =3D 32, + .bit_depth =3D 8, + .bpp_enc =3D 6, + .num_planes =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_OUTPUT, + }, { + .fourcc =3D V4L2_PIX_FMT_SRGGB10, /* 10-bit Bayer RGRG/GBGB */ + .align =3D 32, + .bit_depth =3D 10, + .bpp_enc =3D 4, + .num_planes =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_OUTPUT, + }, { + .fourcc =3D V4L2_PIX_FMT_SRGGB12, /* 12-bit Bayer RGRG/GBGB */ + .align =3D 32, + .bit_depth =3D 12, + .bpp_enc =3D 0, + .num_planes =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_OUTPUT, + }, { + .fourcc =3D V4L2_PIX_FMT_SRGGB14, /* 14-bit Bayer RGRG/GBGB */ + .align =3D 32, + .bit_depth =3D 14, + .bpp_enc =3D 1, + .num_planes =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_OUTPUT, + }, { + .fourcc =3D V4L2_PIX_FMT_SRGGB16, /* 16-bit Bayer RGRG/GBGB */ + .align =3D 32, + .bit_depth =3D 16, + .bpp_enc =3D 2, + .num_planes =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_OUTPUT, + }, { + .fourcc =3D V4L2_PIX_FMT_SBGGR8, + .align =3D 32, + .bit_depth =3D 8, + .bpp_enc =3D 6, + .num_planes =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_OUTPUT, + }, { + .fourcc =3D V4L2_PIX_FMT_SBGGR10, + .align =3D 32, + .bit_depth =3D 10, + .bpp_enc =3D 4, + .num_planes =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_OUTPUT, + }, { + .fourcc =3D V4L2_PIX_FMT_SBGGR12, + .align =3D 32, + .bit_depth =3D 12, + .bpp_enc =3D 0, + .num_planes =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_OUTPUT, + }, { + .fourcc =3D V4L2_PIX_FMT_SBGGR14, + .align =3D 32, + .bit_depth =3D 14, + .bpp_enc =3D 1, + .num_planes =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_OUTPUT, + }, { + .fourcc =3D V4L2_PIX_FMT_SBGGR16, + .align =3D 32, + .bit_depth =3D 16, + .bpp_enc =3D 2, + .num_planes =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_OUTPUT, + }, { + .fourcc =3D V4L2_PIX_FMT_SGBRG8, + .align =3D 32, + .bit_depth =3D 8, + .bpp_enc =3D 6, + .num_planes =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_OUTPUT, + }, { + .fourcc =3D V4L2_PIX_FMT_SGBRG10, + .align =3D 32, + .bit_depth =3D 10, + .bpp_enc =3D 4, + .num_planes =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_OUTPUT, + }, { + .fourcc =3D V4L2_PIX_FMT_SGBRG12, + .align =3D 32, + .bit_depth =3D 12, + .bpp_enc =3D 0, + .num_planes =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_OUTPUT, + }, { + .fourcc =3D V4L2_PIX_FMT_SGBRG14, + .align =3D 32, + .bit_depth =3D 14, + .bpp_enc =3D 1, + .num_planes =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_OUTPUT, + }, { + .fourcc =3D V4L2_PIX_FMT_SGBRG16, + .align =3D 32, + .bit_depth =3D 16, + .bpp_enc =3D 2, + .num_planes =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_OUTPUT, + }, { + .fourcc =3D V4L2_PIX_FMT_SGRBG8, + .align =3D 32, + .bit_depth =3D 8, + .bpp_enc =3D 6, + .num_planes =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_OUTPUT, + }, { + .fourcc =3D V4L2_PIX_FMT_SGRBG10, + .align =3D 32, + .bit_depth =3D 10, + .bpp_enc =3D 4, + .num_planes =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_OUTPUT, + }, { + .fourcc =3D V4L2_PIX_FMT_SGRBG12, + .align =3D 32, + .bit_depth =3D 12, + .bpp_enc =3D 0, + .num_planes =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_OUTPUT, + }, { + .fourcc =3D V4L2_PIX_FMT_SGRBG14, + .align =3D 32, + .bit_depth =3D 14, + .bpp_enc =3D 1, + .num_planes =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_OUTPUT, + }, { + .fourcc =3D V4L2_PIX_FMT_SGRBG16, + .align =3D 32, + .bit_depth =3D 16, + .bpp_enc =3D 2, + .num_planes =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_OUTPUT, + }, { + .fourcc =3D V4L2_PIX_FMT_GREY, /* 8-bit Monochrome */ + .align =3D 32, + .bit_depth =3D 8, + .bpp_enc =3D 6, + .num_planes =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_OUTPUT, + }, { + .fourcc =3D V4L2_PIX_FMT_Y10, /* 10-bit Monochrome */ + .align =3D 32, + .bit_depth =3D 10, + .bpp_enc =3D 4, + .num_planes =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_OUTPUT, + }, { + .fourcc =3D V4L2_PIX_FMT_Y12, /* 12-bit Monochrome */ + .align =3D 32, + .bit_depth =3D 12, + .bpp_enc =3D 0, + .num_planes =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_OUTPUT, + }, { + .fourcc =3D V4L2_PIX_FMT_Y14, /* 14-bit Monochrome */ + .align =3D 32, + .bit_depth =3D 14, + .bpp_enc =3D 1, + .num_planes =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_OUTPUT, + }, { + .fourcc =3D V4L2_PIX_FMT_Y16, /* 16-bit Monochrome */ + .align =3D 32, + .bit_depth =3D 16, + .bpp_enc =3D 2, + .num_planes =3D 1, + .colorspace_mask =3D NEOISP_COLORSPACE_MASK_RAW, + .colorspace_default =3D V4L2_COLORSPACE_RAW, + .type =3D NEOISP_FMT_VIDEO_OUTPUT, + } +}; + +static const struct neoisp_fmt_s formats_mout[] =3D { + { + .fourcc =3D V4L2_META_FMT_NEO_ISP_EXT_PARAMS, /* NXP Neoisp Extensible P= arameters */ + .align =3D 32, + .bit_depth =3D 8, + .num_planes =3D 1, + .type =3D NEOISP_FMT_META_OUTPUT, + } +}; + +static const struct neoisp_fmt_s formats_mcap[] =3D { + { + .fourcc =3D V4L2_META_FMT_NEO_ISP_EXT_STATS, /* NXP Neoisp Extensible St= atistics */ + .align =3D 32, + .bit_depth =3D 8, + .num_planes =3D 1, + .type =3D NEOISP_FMT_META_CAPTURE, + } +}; + +#endif /* __NXP_NEOISP_FMT_H */ diff --git a/drivers/media/platform/nxp/neoisp/neoisp_hw.h b/drivers/media/= platform/nxp/neoisp/neoisp_hw.h new file mode 100644 index 000000000000..afd097de8503 --- /dev/null +++ b/drivers/media/platform/nxp/neoisp/neoisp_hw.h @@ -0,0 +1,557 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * NEOISP hardware structures definition + * + * Copyright 2023-2026 NXP + */ + +#ifndef __NXP_NEOISP_HW_H +#define __NXP_NEOISP_HW_H + +#include "neoisp_regs.h" + +struct neoisp_pipe_conf_s { + u32 reset; + u32 bus_param; + u32 xfer_dis; + u32 unusedw0[1]; + u32 csi_ctrl; + u32 frame_num; + u32 shd_ctrl; + u32 reg_shd_cmd; + u32 trig_cam0; + u32 int_en; + u32 int_stat; + u32 csi_stat; + u32 img_conf; + u32 img_size; + u32 unusedw1[1]; + u32 img0_in_addr; + u32 img1_in_addr; + u32 outch0_addr; + u32 outch1_addr; + u32 outir_addr; + u32 img0_in_ls; + u32 img1_in_ls; + u32 outch0_ls; + u32 outch1_ls; + u32 outir_ls; + u32 skip_ctrl; +}; /* 26 words */ + +struct neoisp_hc_s { + u32 ctrl; +}; + +struct neoisp_hdr_decompress0_s { + u32 ctrl; + u32 knee_point1; + u32 knee_point2; + u32 knee_point3; + u32 knee_point4; + u32 knee_offset0; + u32 knee_offset1; + u32 knee_offset2; + u32 knee_offset3; + u32 knee_offset4; + u32 knee_ratio01; + u32 knee_ratio23; + u32 knee_ratio4; + u32 knee_npoint0; + u32 knee_npoint1; + u32 knee_npoint2; + u32 knee_npoint3; + u32 knee_npoint4; +}; + +struct neoisp_hdr_decompress1_s { + u32 ctrl; + u32 knee_point1; + u32 knee_point2; + u32 knee_point3; + u32 knee_point4; + u32 knee_offset0; + u32 knee_offset1; + u32 knee_offset2; + u32 knee_offset3; + u32 knee_offset4; + u32 knee_ratio01; + u32 knee_ratio23; + u32 knee_ratio4; + u32 knee_npoint0; + u32 knee_npoint1; + u32 knee_npoint2; + u32 knee_npoint3; + u32 knee_npoint4; +}; + +struct neoisp_obwb_s { + u32 ctrl; + u32 r_ctrl; + u32 gr_ctrl; + u32 gb_ctrl; + u32 b_ctrl; +}; + +struct neoisp_hdr_merge_s { + u32 ctrl; + u32 gain_offset; + u32 gain_scale; + u32 gain_shift; + u32 luma_th; + u32 luma_scale; + u32 downscale; + u32 upscale; + u32 post_scale; + u32 s_gain_offset; + u32 s_gain_scale; + u32 s_gain_shift; + u32 s_luma_th; + u32 s_luma_scale; + u32 s_downscale; + u32 s_upscale; + u32 s_post_scale; + u32 s_line_num; +}; + +struct neoisp_ctemp_s { + u32 ctrl; + u32 roi_pos; + u32 roi_size; + u32 redgain; + u32 bluegain; + u32 point1; + u32 point2; + u32 hoffset; + u32 voffset; + u32 point1_slope; + u32 point2_slope; + u32 luma_th; + u32 csc_mat0; + u32 csc_mat1; + u32 csc_mat2; + u32 csc_mat3; + u32 csc_mat4; + u32 r_gr_offset; + u32 gb_b_offset; + u32 cnt_white; + u32 sumrl; + u32 sumrh; + u32 sumgl; + u32 sumgh; + u32 sumbl; + u32 sumbh; + u32 sumrgl; + u32 sumrgh; + u32 sumbgl; + u32 sumbgh; + u32 unused0[2]; + u32 stat_blk_size0; + u32 unused1[1]; + u32 stat_curr_blk_y0; + u32 unused2[1]; + u32 croi0_pos; + u32 unused3[1]; + u32 croi0_pixcnt; + u32 croi0_sumred; + u32 croi0_sumgreen; + u32 croi0_sumblue; + u32 croi1_pos; + u32 unused4[1]; + u32 croi1_pixcnt; + u32 croi1_sumred; + u32 croi1_sumgreen; + u32 croi1_sumblue; + u32 croi2_pos; + u32 unused5[1]; + u32 croi2_pixcnt; + u32 croi2_sumred; + u32 croi2_sumgreen; + u32 croi2_sumblue; + u32 croi3_pos; + u32 unused6[1]; + u32 croi3_pixcnt; + u32 croi3_sumred; + u32 croi3_sumgreen; + u32 croi3_sumblue; + u32 croi4_pos; + u32 unused7[1]; + u32 croi4_pixcnt; + u32 croi4_sumred; + u32 croi4_sumgreen; + u32 croi4_sumblue; + u32 croi5_pos; + u32 unused8[1]; + u32 croi5_pixcnt; + u32 croi5_sumred; + u32 croi5_sumgreen; + u32 croi5_sumblue; + u32 croi6_pos; + u32 unused9[1]; + u32 croi6_pixcnt; + u32 croi6_sumred; + u32 croi6_sumgreen; + u32 croi6_sumblue; + u32 croi7_pos; + u32 unused10[1]; + u32 croi7_pixcnt; + u32 croi7_sumred; + u32 croi7_sumgreen; + u32 croi7_sumblue; + u32 croi8_pos; + u32 unused11[1]; + u32 croi8_pixcnt; + u32 croi8_sumred; + u32 croi8_sumgreen; + u32 croi8_sumblue; + u32 croi9_pos; + u32 unused12[1]; + u32 croi9_pixcnt; + u32 croi9_sumred; + u32 croi9_sumgreen; + u32 croi9_sumblue; + u32 unused13[1]; + u32 gr_avg_in; + u32 gb_avg_in; + u32 gr_gb_cnt; + s32 gr_sum; + s32 gb_sum; + u32 gr2_sum; + u32 gb2_sum; + s32 grgb_sum; +}; + +struct neoisp_rgbir_s { + u32 ctrl; + u32 ccm0; + u32 ccm1; + u32 ccm2; + u32 ccm0_th; + u32 ccm1_th; + u32 ccm2_th; + u32 unused0[1]; + u32 roi0_pos; + u32 roi0_size; + u32 roi1_pos; + u32 roi1_size; + u32 hist0_ctrl; + u32 hist0_scale; + u32 hist1_ctrl; + u32 hist1_scale; +}; + +struct neoisp_stat_s { + u32 roi0_pos; + u32 roi0_size; + u32 roi1_pos; + u32 roi1_size; + u32 unused0[4]; + u32 hist0_ctrl; + u32 hist0_scale; + u32 hist1_ctrl; + u32 hist1_scale; + u32 hist2_ctrl; + u32 hist2_scale; + u32 hist3_ctrl; + u32 hist3_scale; +}; + +struct neoisp_ir_compress_s { + u32 ctrl; + u32 knee_point1; + u32 knee_point2; + u32 knee_point3; + u32 knee_point4; + u32 knee_offset0; + u32 knee_offset1; + u32 knee_offset2; + u32 knee_offset3; + u32 knee_offset4; + u32 knee_ratio01; + u32 knee_ratio23; + u32 knee_ratio4; + u32 knee_npoint0; + u32 knee_npoint1; + u32 knee_npoint2; + u32 knee_npoint3; + u32 knee_npoint4; +}; + +struct neoisp_bnr_s { + u32 ctrl; + u32 ypeak; + u32 yedge_th0; + u32 yedge_scale; + u32 yedges_th0; + u32 yedges_scale; + u32 yedgea_th0; + u32 yedgea_scale; + u32 yluma_x_th0; + u32 yluma_y_th; + u32 yluma_scale; + u32 yalpha_gain; + u32 cpeak; + u32 cedge_th0; + u32 cedge_scale; + u32 cedges_th0; + u32 cedges_scale; + u32 cedgea_th0; + u32 cedgea_scale; + u32 cluma_x_th0; + u32 cluma_y_th; + u32 cluma_scale; + u32 calpha_gain; + u32 edge_stat; + u32 edges_stat; + u32 stretch; +}; + +struct neoisp_vignetting_ctrl_s { + u32 ctrl; + u32 blk_conf; + u32 blk_size; + u32 blk_stepy; + u32 blk_stepx; + u32 punused0[3]; + u32 blk_c_line; + u32 blk_c_row; + u32 blk_c_fracy; +}; + +struct neoisp_idbg1_s { + u32 line_num_t; + u32 curr_line_num_t; + u32 ima_t; + u32 imd; + u32 done_stat_t; +}; + +struct neoisp_demosaic_s { + u32 ctrl; + u32 activity_ctl; + u32 dynamics_ctl0; + u32 dynamics_ctl2; +}; + +struct neoisp_rgb2yuv_s { + u32 gain_ctrl; + u32 mat0; + u32 mat1; + u32 mat2; + u32 mat3; + u32 mat4; + u32 mat5; + u32 unused0[1]; + u32 offset0; + u32 offset1; + u32 offset2; +}; + +struct neoisp_dr_comp_s { + u32 roi0_pos; + u32 roi0_size; + u32 roi1_pos; + u32 roi1_size; + u32 groi_sum_shift; + u32 gbl_gain; + u32 unused0[2]; + u32 lcl_blk_size; + u32 lcl_stretch; + u32 lcl_blk_stepy; + u32 lcl_blk_stepx; + u32 lcl_sum_shift; + u32 alpha; + u32 unused1[2]; + u32 groi0_sum; + u32 groi1_sum; + u32 unused2[2]; + u32 stat_blk_y; + u32 curr_yfract; +}; + +struct neoisp_nr_s { + u32 ctrl; + u32 blend_scale; + u32 blend_th0; + u32 punused0[1]; + u32 edgecnt; +}; + +struct neoisp_df_s { + u32 ctrl; + u32 th_scale; + u32 blend_shift; + u32 blend_th0; + u32 edgecnt; +}; + +struct neoisp_ee_s { + u32 ctrl; + u32 coring; + u32 clip; + u32 maskgain; + u32 edgecnt; +}; + +struct neoisp_convmed_s { + u32 ctrl; +}; + +struct neoisp_cas_s { + u32 unused0[1]; + u32 gain; + u32 corr; + u32 offset; +}; + +struct neoisp_packetizer_s { + u32 ch0_ctrl; + u32 ch12_ctrl; + u32 pack_ctrl; +}; + +struct neoisp_gcm_s { + u32 imat0; + u32 imat1; + u32 punused0[1]; + u32 imat2; + u32 imat3; + u32 punused1[1]; + u32 imat4; + u32 imat5; + u32 ioffset0; + u32 ioffset1; + u32 ioffset2; + u32 punused2[1]; + u32 omat0; + u32 omat1; + u32 omat2; + u32 omat3; + u32 omat4; + u32 omat5; + u32 ooffset0; + u32 ooffset1; + u32 ooffset2; + u32 punused3[3]; + u32 gamma0; + u32 gamma1; + u32 gamma2; + u32 blklvl0_ctrl; + u32 blklvl1_ctrl; + u32 blklvl2_ctrl; + u32 lowth_ctrl01; + u32 lowth_ctrl2; + u32 mat_confg; +}; + +struct neoisp_autofocus_s { + u32 roi0_pos; + u32 roi0_size; + u32 roi1_pos; + u32 roi1_size; + u32 roi2_pos; + u32 roi2_size; + u32 roi3_pos; + u32 roi3_size; + u32 roi4_pos; + u32 roi4_size; + u32 roi5_pos; + u32 roi5_size; + u32 roi6_pos; + u32 roi6_size; + u32 roi7_pos; + u32 roi7_size; + u32 roi8_pos; + u32 roi8_size; + u32 unused0[2]; + u32 fil0_coeffs0; + u32 fil0_coeffs1; + u32 fil0_coeffs2; + u32 fil0_shift; + u32 fil1_coeffs0; + u32 fil1_coeffs1; + u32 fil1_coeffs2; + u32 fil1_shift; + u32 roi0_sum0_cam0; + u32 roi0_sum1_cam0; + u32 roi1_sum0_cam0; + u32 roi1_sum1_cam0; + u32 roi2_sum0_cam0; + u32 roi2_sum1_cam0; + u32 roi3_sum0_cam0; + u32 roi3_sum1_cam0; + u32 roi4_sum0_cam0; + u32 roi4_sum1_cam0; + u32 roi5_sum0_cam0; + u32 roi5_sum1_cam0; + u32 roi6_sum0_cam0; + u32 roi6_sum1_cam0; + u32 roi7_sum0_cam0; + u32 roi7_sum1_cam0; + u32 roi8_sum0_cam0; + u32 roi8_sum1_cam0; +}; + +struct neoisp_idbg2_s { + u32 line_num; + u32 curr_line_num; + u32 ima; + u32 imd; + u32 done_stat; +}; + +struct neoisp_hw_s { + struct neoisp_pipe_conf_s pipe_conf; + u32 unused0[22]; + struct neoisp_hc_s hc; + u32 unused1[15]; + struct neoisp_hdr_decompress0_s hdr_decompress0; + u32 unused2[14]; + struct neoisp_hdr_decompress1_s hdr_decompress1; + u32 unused3[14]; + struct neoisp_obwb_s obwb0; + u32 unused4[11]; + struct neoisp_obwb_s obwb1; + u32 unused5[11]; + struct neoisp_obwb_s obwb2; + u32 unused6[27]; + struct neoisp_hdr_merge_s hdr_merge; + u32 unused7[46]; + struct neoisp_ctemp_s ctemp; + u32 unused8[23]; + struct neoisp_rgbir_s rgbir; + u32 unused9[48]; + struct neoisp_stat_s stat; + u32 unused10[16]; + struct neoisp_ir_compress_s ir_compress; + u32 unused11[14]; + struct neoisp_bnr_s bnr; + u32 unused12[38]; + struct neoisp_vignetting_ctrl_s vignetting_ctrl; + u32 unused13[421]; + struct neoisp_idbg1_s idbg1; + u32 unused14[107]; + struct neoisp_demosaic_s demosaic; + u32 unused15[12]; + struct neoisp_rgb2yuv_s rgb2yuv; + u32 unused16[69]; + struct neoisp_dr_comp_s drc; + u32 unused17[42]; + struct neoisp_nr_s nr; + u32 unused18[11]; + struct neoisp_df_s df; + u32 unused19[11]; + struct neoisp_ee_s ee; + u32 unused20[11]; + struct neoisp_convmed_s convmed; + u32 unused21[15]; + struct neoisp_cas_s cas; + u32 unused22[28]; + struct neoisp_packetizer_s packetizer; + u32 unused23[29]; + struct neoisp_gcm_s gcm; + u32 unused24[31]; + struct neoisp_autofocus_s autofocus; +}; + +#endif /* __NXP_NEOISP_HW_H */ diff --git a/drivers/media/platform/nxp/neoisp/neoisp_main.c b/drivers/medi= a/platform/nxp/neoisp/neoisp_main.c new file mode 100644 index 000000000000..b08995403c59 --- /dev/null +++ b/drivers/media/platform/nxp/neoisp/neoisp_main.c @@ -0,0 +1,1907 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * NEOISP main driver source code + * + * This is a derived work from the PiSP Back End driver + * Copyright (c) 2021-2024 Raspberry Pi Limited + * + * Copyright 2023-2026 NXP + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "neoisp.h" +#include "neoisp_core.h" +#include "neoisp_fmt.h" +#include "neoisp_nodes.h" +#include "neoisp_regs.h" +#include "neoisp_ctx.h" + +#define NODE_NAME(node) \ + (node_desc[(node)->id].ent_name + sizeof(NEOISP_NAME)) + +static int standalone_mdev; +module_param_named(standalone_mdev, standalone_mdev, uint, 0644); +MODULE_PARM_DESC(standalone_mdev, " Create standalone neoisp media device,= default is 0 (off)"); + +static inline bool node_desc_is_output(const struct neoisp_node_desc_s *de= sc) +{ + return desc->buf_type =3D=3D V4L2_BUF_TYPE_META_OUTPUT || + desc->buf_type =3D=3D V4L2_BUF_TYPE_VIDEO_OUTPUT || + desc->buf_type =3D=3D V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; +} + +static inline bool node_is_meta(struct neoisp_node_s *node) +{ + return node->buf_type =3D=3D V4L2_BUF_TYPE_META_OUTPUT || + node->buf_type =3D=3D V4L2_BUF_TYPE_META_CAPTURE; +} + +static inline bool node_is_output(struct neoisp_node_s *node) +{ + return node->buf_type =3D=3D V4L2_BUF_TYPE_META_OUTPUT || + node->buf_type =3D=3D V4L2_BUF_TYPE_VIDEO_OUTPUT || + node->buf_type =3D=3D V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; +} + +static inline bool node_is_capture(struct neoisp_node_s *node) +{ + return node->buf_type =3D=3D V4L2_BUF_TYPE_META_CAPTURE || + node->buf_type =3D=3D V4L2_BUF_TYPE_VIDEO_CAPTURE || + node->buf_type =3D=3D V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; +} + +static inline bool node_is_mplane(struct neoisp_node_s *node) +{ + return node->buf_type =3D=3D V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE || + node->buf_type =3D=3D V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; +} + +static inline const struct neoisp_fmt_s *neoisp_find_pixel_format(u32 pixe= l_format, + const struct neoisp_fmt_s *fmt, + u32 size) +{ + u32 i; + + for (i =3D 0; i < size; i++) + if (fmt[i].fourcc =3D=3D pixel_format) + return &fmt[i]; + return NULL; +} + +/* + * The gain adjustment should be done, as the 12-bit format is managed in = a specific way. + * LPALIGN0/1 bit field is used to select LSB or MSB alignment. However, L= PALIGN0/1 + * is disabled for 12-bit operations and data is always aligned in the fol= lowing manner: + * d[15] -> d[4] + * + * In this sense, a gain is applied to the HDR Decompression block to alig= n the data on d[19] for + * input0 as other formats are defined. As the working BPP of input1 is 16= -bit depth, the data is + * already MSB-aligned and do not need an extra gain. + */ +static inline void neoisp_adjust_gain(struct neoisp_context_s *ctx, u32 ib= pp) +{ + struct neoisp_hdr_decompress0_s *hdr0 =3D &ctx->hw.hdr_decompress0; + + if (ibpp !=3D 12) + return; + + hdr0->knee_ratio4 =3D FIELD_PREP(NEO_HDR_DECOMPRESS0_KNEE_RATIO4_CAM0_RAT= IO4, + 16 << NEOISP_HDR_SHIFT_RADIX); +} + +static void neoisp_fill_mp(struct v4l2_format *f, const struct neoisp_fmt_= s *fmt) +{ + u32 nplanes =3D f->fmt.pix_mp.num_planes; + u32 i; + + for (i =3D 0; i < nplanes; i++) { + struct v4l2_plane_pix_format *p =3D &f->fmt.pix_mp.plane_fmt[i]; + u32 bpl, plane_size; + + bpl =3D f->fmt.pix_mp.width * ((fmt->bit_depth + 7) >> 3); + bpl =3D ALIGN(max(p->bytesperline, bpl), fmt->align); + + plane_size =3D bpl * f->fmt.pix_mp.height; + if (nplanes > 1) + plane_size /=3D fmt->pl_divisors[i]; + plane_size =3D max(p->sizeimage, plane_size); + + p->bytesperline =3D bpl; + p->sizeimage =3D plane_size; + } +} + +static const struct neoisp_fmt_s *neoisp_find_pixel_format_by_node(u32 pix= el_format, + struct neoisp_node_s *node) +{ + if (IS_ERR_OR_NULL(node)) + return NULL; + + switch (node->id) { + case NEOISP_INPUT0_NODE: + case NEOISP_INPUT1_NODE: + return neoisp_find_pixel_format(pixel_format, + formats_vout, + ARRAY_SIZE(formats_vout)); + case NEOISP_FRAME_NODE: + return neoisp_find_pixel_format(pixel_format, + formats_vcap, + ARRAY_SIZE(formats_vcap)); + case NEOISP_IR_NODE: + return neoisp_find_pixel_format(pixel_format, + formats_vcap_ir, + ARRAY_SIZE(formats_vcap_ir)); + case NEOISP_PARAMS_NODE: + return neoisp_find_pixel_format(pixel_format, + formats_mout, + ARRAY_SIZE(formats_mout)); + case NEOISP_STATS_NODE: + return neoisp_find_pixel_format(pixel_format, + formats_mcap, + ARRAY_SIZE(formats_mcap)); + default: + return NULL; + } +} + +const struct neoisp_fmt_s *neoisp_find_video_capture_format(u32 pixel_form= at) +{ + return neoisp_find_pixel_format(pixel_format, + formats_vcap, + ARRAY_SIZE(formats_vcap)); +} + +static int neoisp_node_queue_setup(struct vb2_queue *q, u32 *nbuffers, + u32 *nplanes, u32 sizes[], + struct device *alloc_devs[]) +{ + struct neoisp_node_s *node =3D vb2_get_drv_priv(q); + struct neoisp_dev_s *neoispd =3D node->neoisp; + u32 i, num_planes; + + num_planes =3D node_is_mplane(node) ? + node->format.fmt.pix_mp.num_planes : 1; + if (*nplanes) { + if (*nplanes !=3D num_planes) + return -EINVAL; + + for (i =3D 0; i < *nplanes; i++) { + u32 size =3D node_is_mplane(node) ? + node->format.fmt.pix_mp.plane_fmt[i].sizeimage : + node->format.fmt.meta.buffersize; + + if (sizes[i] < size) + return -EINVAL; + } + + return 0; + } + + *nplanes =3D num_planes; + for (i =3D 0; i < *nplanes; i++) + sizes[i] =3D node_is_mplane(node) ? + node->format.fmt.pix_mp.plane_fmt[i].sizeimage : + node->format.fmt.meta.buffersize; + + dev_dbg(neoispd->dev, + "Image (or metadata) size %u, nbuffers %u for node %s\n", + sizes[0], *nbuffers, NODE_NAME(node)); + + return 0; +} + +static int neoisp_node_buf_prepare(struct vb2_buffer *vb) +{ + struct neoisp_node_s *node =3D vb2_get_drv_priv(vb->vb2_queue); + struct neoisp_dev_s *neoispd =3D node->neoisp; + unsigned long size =3D 0; + u32 i, num_planes =3D node_is_mplane(node) ? + node->format.fmt.pix_mp.num_planes : 1; + + for (i =3D 0; i < num_planes; i++) { + size =3D node_is_mplane(node) + ? node->format.fmt.pix_mp.plane_fmt[i].sizeimage + : node->format.fmt.meta.buffersize; + + if (vb2_plane_size(vb, i) < size) { + dev_err(neoispd->dev, + "data will not fit into plane %d (%lu < %lu)\n", + i, vb2_plane_size(vb, i), size); + return -EINVAL; + } + + vb2_set_plane_payload(vb, i, size); + } + return 0; +} + +#define NEOISP_PARAMS_BLOCK_INFO(block, type, ext) \ + [NEOISP_PARAM_BLK_## block] =3D { \ + .size =3D sizeof(struct neoisp_ ## type ## _ ## ext ## _es), \ + } + +#define NEOISP_PARAMS_BLOCK_INFO_CFG(block, type) \ + NEOISP_PARAMS_BLOCK_INFO(block, type, cfg) + +#define NEOISP_PARAMS_BLOCK_INFO_MEMS(block, type) \ + NEOISP_PARAMS_BLOCK_INFO(block, type, mem_params) + +static const struct +v4l2_isp_params_block_type_info neoisp_params_block_types_info[] =3D { + NEOISP_PARAMS_BLOCK_INFO_CFG(PIPE_CONF, pipe_conf), + NEOISP_PARAMS_BLOCK_INFO_CFG(HEAD_COLOR, head_color), + NEOISP_PARAMS_BLOCK_INFO_CFG(HDR_DECOMPRESS0, hdr_decompress0), + NEOISP_PARAMS_BLOCK_INFO_CFG(HDR_DECOMPRESS1, hdr_decompress1), + NEOISP_PARAMS_BLOCK_INFO_CFG(OBWB0, obwb), + NEOISP_PARAMS_BLOCK_INFO_CFG(OBWB1, obwb), + NEOISP_PARAMS_BLOCK_INFO_CFG(OBWB2, obwb), + NEOISP_PARAMS_BLOCK_INFO_CFG(HDR_MERGE, hdr_merge), + NEOISP_PARAMS_BLOCK_INFO_CFG(RGBIR, rgbir), + NEOISP_PARAMS_BLOCK_INFO_CFG(STAT, stat), + NEOISP_PARAMS_BLOCK_INFO_CFG(CTEMP, ctemp), + NEOISP_PARAMS_BLOCK_INFO_CFG(IR_COMPRESS, ir_compress), + NEOISP_PARAMS_BLOCK_INFO_CFG(BNR, bnr), + NEOISP_PARAMS_BLOCK_INFO_CFG(VIGNETTING_CTRL, vignetting_ctrl), + NEOISP_PARAMS_BLOCK_INFO_CFG(DEMOSAIC, demosaic), + NEOISP_PARAMS_BLOCK_INFO_CFG(RGB2YUV, rgb2yuv), + NEOISP_PARAMS_BLOCK_INFO_CFG(DR_COMP, dr_comp), + NEOISP_PARAMS_BLOCK_INFO_CFG(NR, nr), + NEOISP_PARAMS_BLOCK_INFO_CFG(AF, af), + NEOISP_PARAMS_BLOCK_INFO_CFG(EE, ee), + NEOISP_PARAMS_BLOCK_INFO_CFG(DF, df), + NEOISP_PARAMS_BLOCK_INFO_CFG(CONVMED, convmed), + NEOISP_PARAMS_BLOCK_INFO_CFG(CAS, cas), + NEOISP_PARAMS_BLOCK_INFO_CFG(GCM, gcm), + NEOISP_PARAMS_BLOCK_INFO_MEMS(VIGNETTING_TABLE, vignetting_table), + NEOISP_PARAMS_BLOCK_INFO_MEMS(DRC_GLOBAL_TONEMAP, drc_global_tonemap), + NEOISP_PARAMS_BLOCK_INFO_MEMS(DRC_LOCAL_TONEMAP, drc_local_tonemap), +}; + +static int neoisp_params_node_buf_prepare(struct vb2_buffer *vb) +{ + struct vb2_v4l2_buffer *vbuf =3D to_vb2_v4l2_buffer(vb); + struct neoisp_node_s *node =3D vb2_get_drv_priv(vb->vb2_queue); + struct neoisp_dev_s *neoispd =3D node->neoisp; + struct v4l2_isp_params_buffer *params =3D vb2_plane_vaddr(&vbuf->vb2_buf,= 0); + int ret; + + ret =3D v4l2_isp_params_validate_buffer_size(neoispd->dev, vb, + node->format.fmt.meta.buffersize); + if (ret) + return ret; + + ret =3D v4l2_isp_params_validate_buffer(neoispd->dev, vb, + params, neoisp_params_block_types_info, + ARRAY_SIZE(neoisp_params_block_types_info)); + if (ret) + return ret; + + vb2_set_plane_payload(vb, 0, node->format.fmt.meta.buffersize); + return 0; +} + +static void send_frame_sync_event(struct neoisp_dev_s *neoispd) +{ + struct v4l2_subdev *sd =3D &neoispd->sd; + u32 sequence =3D neoispd->frame_sequence; + + struct v4l2_event ev =3D { + .type =3D V4L2_EVENT_FRAME_SYNC, + .u.frame_sync.frame_sequence =3D sequence, + }; + + v4l2_event_queue(sd->devnode, &ev); +} + +static void neoisp_reset_hw(struct neoisp_dev_s *neoispd, bool is_hw) +{ + u32 bit =3D NEO_PIPE_CONF_SOFT_RESET_SOFT_RESET; + u32 val, count =3D 100; + + if (is_hw) + bit =3D NEO_PIPE_CONF_SOFT_RESET_HARD_RESET; + + neoisp_wr(neoispd, NEO_PIPE_CONF_SOFT_RESET, bit); + + /* Wait for auto-clear */ + do { + usleep_range(1, 2); + val =3D neoisp_rd(neoispd, NEO_PIPE_CONF_SOFT_RESET); + count--; + } while ((val & bit) && count); + + if (val & bit) + dev_warn(neoispd->dev, "%s reset incomplete\n", + is_hw ? "hw" : "sw"); +} + +static void neoisp_run_job(struct neoisp_dev_s *neoispd) +{ + /* Update queued job context buf addresses */ + neoisp_ctx_update_buf_addr(neoispd); + + /* Update queued job context with user space values */ + neoisp_ctx_update_w_user_params(neoispd); + + /* Upload context into HW registers and memories */ + neoisp_ctx_upload_context(neoispd); + + /* Kick off the hw */ + neoisp_wr(neoispd, NEO_PIPE_CONF_TRIG_CAM0, NEO_PIPE_CONF_TRIG_CAM0_TRIGG= ER); + send_frame_sync_event(neoispd); + dev_dbg(neoispd->dev, "isp starting job\n"); +} + +static int neoisp_prepare_job(struct neoisp_dev_s *neoispd) +{ + struct neoisp_job_desc_s __free(kfree) *job =3D NULL; + struct neoisp_buffer_s *buf[NEOISP_NODES_COUNT]; + struct neoisp_node_s *node; + unsigned int streaming_map; + int i; + + lockdep_assert_irqs_enabled(); + + /* + * To schedule a job, we need to have 1 buffer for any enabled node, know= ing that: + * - Input0 is immutable, so it must have 1 buffer. + * - Input1 is mutable, so it is ignored if not used. + * - Params and Stats are also mutable, but enabled by default. + * - Frame and IR are mutable; Only Frame is enabled by default. At leas= t one + * of these 2 should be enabled. + * + * If all the buffers required to form a job are available, append the job + * descriptor to the job queue to be later queued to the HW. + */ + scoped_guard(spinlock_irq, &neoispd->hw_lock) { + if ((BIT(NEOISP_INPUT0_NODE) & neoispd->streaming_map) + !=3D BIT(NEOISP_INPUT0_NODE)) { + dev_dbg(neoispd->dev, "Input0 node not ready, nothing to do\n"); + return -EAGAIN; + } + + node =3D &neoispd->node[NEOISP_INPUT1_NODE]; + if (neoisp_node_link_is_enabled(node)) { + if ((BIT(NEOISP_INPUT1_NODE) & neoispd->streaming_map) + !=3D BIT(NEOISP_INPUT1_NODE)) { + dev_dbg(neoispd->dev, "Input1 is not disabled and not ready\n"); + return -EAGAIN; + } + } + node =3D &neoispd->node[NEOISP_PARAMS_NODE]; + if (neoisp_node_link_is_enabled(node)) { + if ((BIT(NEOISP_PARAMS_NODE) & neoispd->streaming_map) + !=3D BIT(NEOISP_PARAMS_NODE)) { + dev_dbg(neoispd->dev, "Params is not disabled and not ready\n"); + return -EAGAIN; + } + } + node =3D &neoispd->node[NEOISP_FRAME_NODE]; + if (neoisp_node_link_is_enabled(node)) { + if ((BIT(NEOISP_FRAME_NODE) & neoispd->streaming_map) + !=3D BIT(NEOISP_FRAME_NODE)) { + dev_dbg(neoispd->dev, "Frame node not ready, nothing to do\n"); + return -EAGAIN; + } + } + node =3D &neoispd->node[NEOISP_IR_NODE]; + if (neoisp_node_link_is_enabled(node)) { + if ((BIT(NEOISP_IR_NODE) & neoispd->streaming_map) + !=3D BIT(NEOISP_IR_NODE)) { + dev_dbg(neoispd->dev, "IR node not ready, nothing to do\n"); + return -EAGAIN; + } + } + node =3D &neoispd->node[NEOISP_STATS_NODE]; + if (neoisp_node_link_is_enabled(node)) { + if ((BIT(NEOISP_STATS_NODE) & neoispd->streaming_map) + !=3D BIT(NEOISP_STATS_NODE)) { + dev_dbg(neoispd->dev, "Stats is not disabled and not ready\n"); + return -EAGAIN; + } + } + + /* + * Take a copy of streaming_map: nodes activated after this + * point are ignored when preparing this job + */ + streaming_map =3D neoispd->streaming_map; + } + + job =3D kzalloc(sizeof(*job), GFP_KERNEL); + if (!job) + return -ENOMEM; + + for (i =3D 0; i < NEOISP_NODES_COUNT; i++) { + buf[i] =3D NULL; + if (!(streaming_map & BIT(i))) + continue; + + node =3D &neoispd->node[i]; + buf[i] =3D list_first_entry_or_null(&node->ready_queue, + struct neoisp_buffer_s, + ready_list); + + if (!buf[i] && neoisp_node_link_is_enabled(node)) { + dev_dbg(neoispd->dev, "Nothing to do\n"); + return -ENODEV; + } + } + + /* Pull a buffer from each V4L2 queue to form the queued job */ + for (i =3D 0; i < NEOISP_NODES_COUNT; i++) { + if (buf[i]) { + list_del(&buf[i]->ready_list); + job->buffers[i] =3D buf[i]; + } + } + + scoped_guard(spinlock_irq, &neoispd->hw_lock) { + list_add_tail(&job->queue, &neoispd->job_queue); + } + + /* Set job to NULL to avoid automatic release due to __free(). */ + job =3D NULL; + + return 0; +} + +/* + * Try to schedule a job. If neoisp hw is free, and a job is ready + * move it into the queued_job, and launch it. + */ +static void neoisp_schedule(struct neoisp_dev_s *neoispd, + bool clear_hw_busy) +{ + struct neoisp_job_desc_s *job; + int i; + + scoped_guard(spinlock_irqsave, &neoispd->hw_lock) { + if (clear_hw_busy) + neoispd->hw_busy =3D false; + + if (neoispd->hw_busy) + return; + + job =3D list_first_entry_or_null(&neoispd->job_queue, + struct neoisp_job_desc_s, + queue); + + if (!job) + return; + + list_del(&job->queue); + + for (i =3D 0; i < NEOISP_NODES_COUNT; i++) + neoispd->queued_job.buf[i] =3D job->buffers[i]; + + neoispd->hw_busy =3D true; + } + + /* + * We can kick the job off without the hw_lock, as this can + * never run again until hw_busy is cleared, which will happen + * only when the following job has been queued and an interrupt + * is raised. + */ + neoisp_run_job(neoispd); + kfree(job); +} + +static void neoisp_node_buf_queue(struct vb2_buffer *vb) +{ + struct vb2_v4l2_buffer *vbuf =3D to_vb2_v4l2_buffer(vb); + struct neoisp_buffer_s *buffer =3D to_neoisp_buffer(vbuf); + struct neoisp_node_s *node =3D vb2_get_drv_priv(vb->vb2_queue); + struct neoisp_dev_s *neoispd =3D node->neoisp; + + dev_dbg(neoispd->dev, "%s: for node %s\n", __func__, NODE_NAME(node)); + list_add_tail(&buffer->ready_list, &node->ready_queue); + + /* + * Every time we add a buffer, check if there's now some work for the hw + * to do, but only for this client. + */ + if (!neoisp_prepare_job(neoispd)) + neoisp_schedule(neoispd, false); +} + +static void neoisp_set_default_context(struct neoisp_dev_s *neoispd) +{ + /* Prepare the job context with default one */ + neoisp_ctx_set_default_context(neoispd->context); +} + +static int neoisp_prepare_node_streaming(struct neoisp_node_s *node) +{ + struct neoisp_dev_s *neoispd =3D node->neoisp; + struct neoisp_context_s *ctx =3D neoispd->context; + struct neoisp_node_s *in0_node; + u32 pixfmt =3D node->format.fmt.pix_mp.pixelformat; + + switch (node->id) { + case NEOISP_INPUT0_NODE: + /* Preload default parameters */ + neoisp_adjust_gain(ctx, node->neoisp_format->bit_depth); + + neoisp_ctx_update_head_color(neoispd, ctx, pixfmt); + neoisp_ctx_update_monochrome_fmt(neoispd, ctx, pixfmt); + break; + + case NEOISP_INPUT1_NODE: + /* Prepare HDR mode */ + neoisp_ctx_update_hdr_mode(neoispd, ctx); + break; + + case NEOISP_FRAME_NODE: + in0_node =3D &neoispd->node[NEOISP_INPUT0_NODE]; + + if (node->format.fmt.pix_mp.width !=3D in0_node->crop.width || + node->format.fmt.pix_mp.height !=3D in0_node->crop.height) { + dev_err(neoispd->dev, + "Crop & output sizes don't match - w/cw: %d/%d, h/ch : %d/%d\n", + node->format.fmt.pix_mp.width, in0_node->crop.width, + node->format.fmt.pix_mp.height, in0_node->crop.height); + return -EPIPE; + } + + neoisp_ctx_update_gcm(neoispd, ctx, &node->format.fmt.pix_mp, + node->neoisp_format->is_rgb ? + V4L2_YCBCR_ENC_DEFAULT : node->format.fmt.pix_mp.ycbcr_enc); + break; + } + + /* + * Check output modes (frame, ir, dummy or combination) + */ + if ((!neoisp_node_link_is_enabled(&neoispd->node[NEOISP_FRAME_NODE]) || + !neoisp_node_link_is_enabled(&neoispd->node[NEOISP_IR_NODE]) || + format_is_monochrome(pixfmt)) && !neoispd->dummy_buf) { + struct neoisp_node_s *in0_node =3D &neoispd->node[NEOISP_INPUT0_NODE]; + + /* Allocate a single line dummy buffer as line stride is set to 0 */ + neoispd->dummy_size =3D in0_node->crop.width * NEOISP_MAX_BPP; + neoispd->dummy_buf =3D + dma_alloc_coherent(neoispd->dev, + neoispd->dummy_size, + &neoispd->dummy_dma, GFP_KERNEL); + if (!neoispd->dummy_buf) { + dev_err(neoispd->dev, + "Unable to allocate dummy buffer\n"); + return -ENOMEM; + } + } + + return 0; +} + +static int neoisp_node_start_streaming(struct vb2_queue *q, u32 count) +{ + struct neoisp_node_s *node =3D vb2_get_drv_priv(q); + struct neoisp_dev_s *neoispd =3D node->neoisp; + struct neoisp_buffer_s *buf, *tmp; + int ret; + + ret =3D pm_runtime_resume_and_get(neoispd->dev); + if (ret < 0) + goto error; + + ret =3D neoisp_prepare_node_streaming(node); + if (ret < 0) + goto error_streaming; + + scoped_guard(spinlock_irq, &neoispd->hw_lock) { + neoispd->streaming_map |=3D BIT(node->id); + neoispd->frame_sequence =3D 0; + } + + dev_dbg(neoispd->dev, "%s: for node %s (count %u)\n", + __func__, NODE_NAME(node), count); + dev_dbg(neoispd->dev, "Nodes streaming now 0x%x\n", + neoispd->streaming_map); + + /* Update queued job context with current driver configuration */ + neoisp_ctx_update_packetizer(neoispd); + neoisp_ctx_update_pipe_conf(neoispd); + + /* Maybe we're ready to run. */ + if (!neoisp_prepare_job(neoispd)) + neoisp_schedule(neoispd, false); + + return 0; + +error_streaming: + pm_runtime_put_autosuspend(neoispd->dev); +error: + list_for_each_entry_safe(buf, tmp, &node->ready_queue, ready_list) { + list_del(&buf->ready_list); + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED); + } + return ret; +} + +static void neoisp_node_stop_streaming(struct vb2_queue *q) +{ + struct neoisp_node_s *node =3D vb2_get_drv_priv(q); + struct neoisp_dev_s *neoispd =3D node->neoisp; + struct neoisp_job_desc_s *job, *temp; + struct neoisp_buffer_s *buf; + LIST_HEAD(tmp_list); + + /* + * Now this is a bit awkward. In a simple M2M device we could just wait + * for all queued jobs to complete, but here there's a risk that a + * partial set of buffers was queued and cannot be run. For now, just + * cancel all buffers stuck in the "ready queue", then wait for any + * running job. + * + * This may return buffers out of order. + */ + dev_dbg(neoispd->dev, "%s: for node %s\n", __func__, NODE_NAME(node)); + do { + buf =3D list_first_entry_or_null(&node->ready_queue, + struct neoisp_buffer_s, + ready_list); + if (buf) { + list_del(&buf->ready_list); + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); + } + } while (buf); + + vb2_wait_for_all_buffers(&node->queue); + + if (node->id =3D=3D NEOISP_INPUT0_NODE) + neoisp_set_default_context(neoispd); + + spin_lock_irq(&neoispd->hw_lock); + neoispd->streaming_map &=3D ~BIT(node->id); + + if (neoispd->streaming_map =3D=3D 0) { + /* + * If all nodes have stopped streaming release all jobs + * without holding the lock. + */ + list_splice_init(&neoispd->job_queue, &tmp_list); + } + spin_unlock_irq(&neoispd->hw_lock); + + list_for_each_entry_safe(job, temp, &tmp_list, queue) { + list_del(&job->queue); + kfree(job); + } + + if (neoispd->streaming_map =3D=3D 0 && neoispd->dummy_buf) { + dma_free_coherent(neoispd->dev, + neoispd->dummy_size, + neoispd->dummy_buf, + neoispd->dummy_dma); + neoispd->dummy_buf =3D NULL; + } + + pm_runtime_mark_last_busy(neoispd->dev); + pm_runtime_put_autosuspend(neoispd->dev); + + dev_dbg(neoispd->dev, "Nodes streaming now 0x%x\n", + neoispd->streaming_map); +} + +static const struct vb2_ops neoisp_params_node_queue_ops =3D { + .queue_setup =3D neoisp_node_queue_setup, + .buf_prepare =3D neoisp_params_node_buf_prepare, + .buf_queue =3D neoisp_node_buf_queue, + .start_streaming =3D neoisp_node_start_streaming, + .stop_streaming =3D neoisp_node_stop_streaming, +}; + +static const struct vb2_ops neoisp_node_queue_ops =3D { + .queue_setup =3D neoisp_node_queue_setup, + .buf_prepare =3D neoisp_node_buf_prepare, + .buf_queue =3D neoisp_node_buf_queue, + .start_streaming =3D neoisp_node_start_streaming, + .stop_streaming =3D neoisp_node_stop_streaming, +}; + +static const struct v4l2_file_operations neoisp_fops =3D { + .owner =3D THIS_MODULE, + .open =3D v4l2_fh_open, + .release =3D vb2_fop_release, + .poll =3D vb2_fop_poll, + .unlocked_ioctl =3D video_ioctl2, + .mmap =3D vb2_fop_mmap +}; + +static int neoisp_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) +{ + struct neoisp_node_s *node =3D video_drvdata(file); + struct neoisp_dev_s *neoispd =3D node->neoisp; + + strscpy(cap->driver, NEOISP_NAME, sizeof(cap->driver)); + strscpy(cap->card, NEOISP_NAME, sizeof(cap->card)); + snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", + dev_name(neoispd->dev)); + + cap->capabilities =3D V4L2_CAP_VIDEO_CAPTURE_MPLANE | + V4L2_CAP_VIDEO_OUTPUT_MPLANE | + V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS | + V4L2_CAP_META_OUTPUT | V4L2_CAP_META_CAPTURE; + cap->device_caps =3D node->vfd.device_caps; + + dev_dbg(neoispd->dev, "Caps for node %s: %x and %x (dev %x)\n", + NODE_NAME(node), cap->capabilities, cap->device_caps, + node->vfd.device_caps); + + return 0; +} + +static int neoisp_enum_fmt(struct file *file, void *priv, struct v4l2_fmtd= esc *f) +{ + struct neoisp_node_s *node =3D video_drvdata(file); + + if (f->type !=3D node->queue.type) + return -EINVAL; + + f->flags =3D 0; + if (node_is_meta(node)) { + if (node_is_output(node)) { + if (f->index >=3D ARRAY_SIZE(formats_mout)) + return -EINVAL; + + f->pixelformat =3D formats_mout[f->index].fourcc; + } else { + if (f->index >=3D ARRAY_SIZE(formats_mcap)) + return -EINVAL; + + f->pixelformat =3D formats_mcap[f->index].fourcc; + } + return 0; + } + if (node_is_output(node)) { + if (f->index >=3D ARRAY_SIZE(formats_vout)) + return -EINVAL; + + f->pixelformat =3D formats_vout[f->index].fourcc; + } else { + if (node->id =3D=3D NEOISP_IR_NODE) { + if (f->index >=3D ARRAY_SIZE(formats_vcap_ir)) + return -EINVAL; + + f->pixelformat =3D formats_vcap_ir[f->index].fourcc; + } else { + if (f->index >=3D ARRAY_SIZE(formats_vcap)) + return -EINVAL; + + f->pixelformat =3D formats_vcap[f->index].fourcc; + } + } + + return 0; +} + +static int neoisp_enum_framesizes(struct file *file, void *priv, + struct v4l2_frmsizeenum *fsize) +{ + struct neoisp_node_s *node =3D video_drvdata(file); + const struct neoisp_fmt_s *fmt; + + if (fsize->index) + return -EINVAL; + + fmt =3D neoisp_find_pixel_format_by_node(fsize->pixel_format, node); + if (!fmt) + return -EINVAL; + + fsize->type =3D V4L2_FRMSIZE_TYPE_STEPWISE; + fsize->stepwise =3D neoisp_frmsize_stepwise; + + return 0; +} + +static int neoisp_g_fmt_meta(struct file *file, void *priv, struct v4l2_fo= rmat *f) +{ + struct neoisp_node_s *node =3D video_drvdata(file); + struct neoisp_dev_s *neoispd =3D node->neoisp; + + if (!node_is_meta(node)) { + dev_err(neoispd->dev, + "Cannot get meta fmt for video node %s\n", NODE_NAME(node)); + return -EINVAL; + } + *f =3D node->format; + dev_dbg(neoispd->dev, "Get meta format for node %s\n", NODE_NAME(node)); + return 0; +} + +static int neoisp_try_fmt(struct v4l2_format *f, struct neoisp_node_s *nod= e) +{ + const struct neoisp_fmt_s *fmt; + u32 pixfmt =3D f->fmt.pix_mp.pixelformat; + struct neoisp_dev_s *neoispd =3D node->neoisp; + + if (node_is_meta(node)) { + if (node_is_output(node)) + f->fmt.meta.dataformat =3D V4L2_META_FMT_NEO_ISP_EXT_PARAMS; + else + f->fmt.meta.dataformat =3D V4L2_META_FMT_NEO_ISP_EXT_STATS; + + return 0; + } + + fmt =3D neoisp_find_pixel_format_by_node(pixfmt, node); + if (!fmt) { + if (node_is_output(node)) + fmt =3D &formats_vout[0]; + else + if (node->id =3D=3D NEOISP_IR_NODE) + fmt =3D &formats_vcap_ir[0]; + else + fmt =3D &formats_vcap[0]; + } + + f->fmt.pix_mp.pixelformat =3D fmt->fourcc; + f->fmt.pix_mp.num_planes =3D fmt->num_planes; + f->fmt.pix_mp.field =3D V4L2_FIELD_NONE; + + if (f->fmt.pix_mp.width % 16 !=3D 0 || f->fmt.pix_mp.height % 2 !=3D 0) { + dev_warn(neoispd->dev, + "Width and height must be a multiple of 16 and 2 respectively\n"); + /* Round width and height to their respective nearest multiple */ + f->fmt.pix_mp.width =3D (f->fmt.pix_mp.width + 8) / 16 * 16; + f->fmt.pix_mp.height =3D (f->fmt.pix_mp.height + 1) / 2 * 2; + } + f->fmt.pix_mp.width =3D clamp(f->fmt.pix_mp.width, NEOISP_MIN_W, NEOISP_M= AX_W); + f->fmt.pix_mp.height =3D clamp(f->fmt.pix_mp.height, NEOISP_MIN_H, NEOISP= _MAX_H); + + /* + * Fill in the actual color space when the requested one was + * not supported. This also catches the case when the "default" + * color space was requested (as that's never in the mask). + */ + if (!(NEOISP_COLORSPACE_MASK(f->fmt.pix_mp.colorspace) & + fmt->colorspace_mask)) + f->fmt.pix_mp.colorspace =3D fmt->colorspace_default; + + /* In all cases, we only support the defaults for these: */ + f->fmt.pix_mp.ycbcr_enc =3D V4L2_MAP_YCBCR_ENC_DEFAULT(f->fmt.pix_mp.colo= rspace); + f->fmt.pix_mp.xfer_func =3D V4L2_MAP_XFER_FUNC_DEFAULT(f->fmt.pix_mp.colo= rspace); + + f->fmt.pix_mp.quantization =3D + V4L2_MAP_QUANTIZATION_DEFAULT(fmt->is_rgb, f->fmt.pix_mp.colorspace, + f->fmt.pix_mp.ycbcr_enc); + + /* Set plane size and bytes/line for each plane. */ + neoisp_fill_mp(f, fmt); + + return 0; +} + +static int neoisp_try_fmt_meta_out(struct file *file, void *priv, struct v= 4l2_format *f) +{ + struct neoisp_node_s *node =3D video_drvdata(file); + struct neoisp_dev_s *neoispd =3D node->neoisp; + + if (!node_is_meta(node) || node_is_capture(node)) { + dev_err(neoispd->dev, + "Cannot set capture fmt for meta output node %s\n", + NODE_NAME(node)); + return -EINVAL; + } + + f->fmt.meta.buffersize =3D v4l2_isp_buffer_size(NEOISP_EXT_PARAMS_MAX_SIZ= E); + + return neoisp_try_fmt(f, node); +} + +static int neoisp_try_fmt_meta_cap(struct file *file, void *priv, struct v= 4l2_format *f) +{ + struct neoisp_node_s *node =3D video_drvdata(file); + struct neoisp_dev_s *neoispd =3D node->neoisp; + + if (!node_is_meta(node) || node_is_output(node)) { + dev_err(neoispd->dev, + "Cannot set capture fmt for meta output node %s\n", + NODE_NAME(node)); + return -EINVAL; + } + + f->fmt.meta.buffersize =3D v4l2_isp_buffer_size(NEOISP_EXT_STATS_MAX_SIZE= ); + + return neoisp_try_fmt(f, node); +} + +static int neoisp_s_fmt_meta_out(struct file *file, void *priv, struct v4l= 2_format *f) +{ + struct neoisp_node_s *node =3D video_drvdata(file); + struct neoisp_dev_s *neoispd =3D node->neoisp; + int ret; + + ret =3D neoisp_try_fmt_meta_out(file, priv, f); + if (ret < 0) + return ret; + + if (vb2_is_busy(&node->queue)) + return -EBUSY; + + node->format =3D *f; + node->neoisp_format =3D + neoisp_find_pixel_format_by_node(f->fmt.meta.dataformat, node); + + dev_dbg(neoispd->dev, + "Set output format for meta node %s to %x\n", + NODE_NAME(node), + f->fmt.meta.dataformat); + + return 0; +} + +static int neoisp_s_fmt_meta_cap(struct file *file, void *priv, struct v4l= 2_format *f) +{ + struct neoisp_node_s *node =3D video_drvdata(file); + struct neoisp_dev_s *neoispd =3D node->neoisp; + int ret; + + ret =3D neoisp_try_fmt_meta_cap(file, priv, f); + if (ret < 0) + return ret; + + if (vb2_is_busy(&node->queue)) + return -EBUSY; + + node->format =3D *f; + node->neoisp_format =3D + neoisp_find_pixel_format_by_node(f->fmt.meta.dataformat, node); + + dev_dbg(neoispd->dev, + "Set capture format for meta node %s to %x\n", + NODE_NAME(node), + f->fmt.meta.dataformat); + + return 0; +} + +static int neoisp_g_fmt_vid(struct file *file, void *priv, struct v4l2_for= mat *f) +{ + struct neoisp_node_s *node =3D video_drvdata(file); + struct neoisp_dev_s *neoispd =3D node->neoisp; + + if (node_is_meta(node)) { + dev_err(neoispd->dev, + "Cannot get video fmt for meta node %s\n", NODE_NAME(node)); + return -EINVAL; + } + + *f =3D node->format; + + dev_dbg(neoispd->dev, "Get video format for node %s\n", + NODE_NAME(node)); + + return 0; +} + +static int neoisp_try_fmt_vid_cap(struct file *file, void *priv, struct v4= l2_format *f) +{ + struct neoisp_node_s *node =3D video_drvdata(file); + struct neoisp_dev_s *neoispd =3D node->neoisp; + + if (!node_is_capture(node) || node_is_meta(node)) { + dev_err(neoispd->dev, + "Cannot set capture fmt for output node %s\n", NODE_NAME(node)); + return -EINVAL; + } + + return neoisp_try_fmt(f, node); +} + +static int neoisp_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2= _format *f) +{ + struct neoisp_node_s *node =3D video_drvdata(file); + int ret; + + ret =3D neoisp_try_fmt_vid_cap(file, priv, f); + if (ret) + return ret; + + if (vb2_is_busy(&node->queue)) + return -EBUSY; + + node->format =3D *f; + node->neoisp_format =3D + neoisp_find_pixel_format_by_node(f->fmt.pix_mp.pixelformat, node); + + return 0; +} + +static int neoisp_try_fmt_vid_out(struct file *file, void *priv, struct v4= l2_format *f) +{ + struct neoisp_node_s *node =3D video_drvdata(file); + struct neoisp_dev_s *neoispd =3D node->neoisp; + + if (!node_is_output(node) || node_is_meta(node)) { + dev_err(neoispd->dev, + "Cannot set capture fmt for output node %s\n", + NODE_NAME(node)); + return -EINVAL; + } + + return neoisp_try_fmt(f, node); +} + +static int neoisp_s_fmt_vid_out(struct file *file, void *priv, struct v4l2= _format *f) +{ + struct neoisp_node_s *node =3D video_drvdata(file); + struct neoisp_dev_s *neoispd =3D node->neoisp; + int ret =3D neoisp_try_fmt_vid_out(file, priv, f); + + if (ret < 0) + return ret; + + if (vb2_is_busy(&node->queue)) + return -EBUSY; + + node->format =3D *f; + node->neoisp_format =3D + neoisp_find_pixel_format_by_node(f->fmt.pix_mp.pixelformat, node); + + node->crop.top =3D 0; + node->crop.left =3D 0; + node->crop.width =3D f->fmt.pix_mp.width; + node->crop.height =3D f->fmt.pix_mp.height; + dev_dbg(neoispd->dev, + "Set output format for node %s to %x\n", + NODE_NAME(node), + f->fmt.pix_mp.pixelformat); + + return 0; +} + +static int neoisp_g_selection(struct file *file, void *fh, struct v4l2_sel= ection *sel) +{ + struct neoisp_node_s *node =3D video_drvdata(file); + + if (sel->type !=3D V4L2_BUF_TYPE_VIDEO_OUTPUT) + return -EINVAL; + + switch (sel->target) { + case V4L2_SEL_TGT_CROP_DEFAULT: + case V4L2_SEL_TGT_CROP_BOUNDS: + sel->r.top =3D 0; + sel->r.left =3D 0; + sel->r.width =3D node->format.fmt.pix_mp.width; + sel->r.height =3D node->format.fmt.pix_mp.height; + break; + case V4L2_SEL_TGT_CROP: + sel->r.top =3D node->crop.top; + sel->r.left =3D node->crop.left; + sel->r.width =3D node->crop.width; + sel->r.height =3D node->crop.height; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int neoisp_s_selection(struct file *file, void *fh, struct v4l2_sel= ection *sel) +{ + struct neoisp_node_s *node =3D video_drvdata(file); + u32 winput, hinput; + + if (sel->type !=3D V4L2_BUF_TYPE_VIDEO_OUTPUT) + return -EINVAL; + + dev_dbg(node->neoisp->dev, + ">>> Buffer Type: %u Target: %u Rect: %ux%u@%d.%d\n", + sel->type, sel->target, + sel->r.width, sel->r.height, sel->r.left, sel->r.top); + + switch (sel->target) { + case V4L2_SEL_TGT_CROP: + winput =3D node->format.fmt.pix_mp.width; + hinput =3D node->format.fmt.pix_mp.height; + + /* Left and width should be multiple of 16 */ + sel->r.left =3D (sel->r.left / 16) * 16; + sel->r.width =3D (sel->r.width / 16) * 16; + /* Top and height should be even */ + sel->r.top =3D (sel->r.top / 2) * 2; + sel->r.height =3D (sel->r.height / 2) * 2; + + sel->r.top =3D clamp_t(int, sel->r.top, 0, hinput - NEOISP_MIN_H); + sel->r.left =3D clamp_t(int, sel->r.left, 0, winput - NEOISP_MIN_W); + sel->r.width =3D clamp(sel->r.width, NEOISP_MIN_W, winput - sel->r.left); + sel->r.height =3D clamp(sel->r.height, NEOISP_MIN_H, hinput - sel->r.top= ); + + node->crop.top =3D sel->r.top; + node->crop.left =3D sel->r.left; + node->crop.width =3D sel->r.width; + node->crop.height =3D sel->r.height; + break; + + default: + return -EINVAL; + } + + dev_dbg(node->neoisp->dev, + "<<< Buffer Type: %u Target: %u Rect: %ux%u@%d.%d\n", + sel->type, sel->target, + sel->r.width, sel->r.height, sel->r.left, sel->r.top); + + return 0; +} + +static const struct v4l2_ioctl_ops neoisp_ioctl_ops =3D { + .vidioc_querycap =3D neoisp_querycap, + + .vidioc_enum_fmt_vid_cap =3D neoisp_enum_fmt, + .vidioc_enum_fmt_meta_cap =3D neoisp_enum_fmt, + .vidioc_enum_framesizes =3D neoisp_enum_framesizes, + .vidioc_g_fmt_vid_cap_mplane =3D neoisp_g_fmt_vid, + .vidioc_s_fmt_vid_cap_mplane =3D neoisp_s_fmt_vid_cap, + .vidioc_try_fmt_vid_cap_mplane =3D neoisp_try_fmt_vid_cap, + .vidioc_g_fmt_meta_cap =3D neoisp_g_fmt_meta, + .vidioc_s_fmt_meta_cap =3D neoisp_s_fmt_meta_cap, + .vidioc_try_fmt_meta_cap =3D neoisp_try_fmt_meta_cap, + + .vidioc_enum_fmt_vid_out =3D neoisp_enum_fmt, + .vidioc_enum_fmt_meta_out =3D neoisp_enum_fmt, + .vidioc_g_fmt_vid_out_mplane =3D neoisp_g_fmt_vid, + .vidioc_s_fmt_vid_out_mplane =3D neoisp_s_fmt_vid_out, + .vidioc_try_fmt_vid_out_mplane =3D neoisp_try_fmt_vid_out, + .vidioc_g_fmt_meta_out =3D neoisp_g_fmt_meta, + .vidioc_s_fmt_meta_out =3D neoisp_s_fmt_meta_out, + .vidioc_try_fmt_meta_out =3D neoisp_try_fmt_meta_out, + + .vidioc_g_selection =3D neoisp_g_selection, + .vidioc_s_selection =3D neoisp_s_selection, + .vidioc_reqbufs =3D vb2_ioctl_reqbufs, + .vidioc_querybuf =3D vb2_ioctl_querybuf, + .vidioc_qbuf =3D vb2_ioctl_qbuf, + .vidioc_dqbuf =3D vb2_ioctl_dqbuf, + .vidioc_prepare_buf =3D vb2_ioctl_prepare_buf, + .vidioc_create_bufs =3D vb2_ioctl_create_bufs, + .vidioc_expbuf =3D vb2_ioctl_expbuf, + + .vidioc_streamon =3D vb2_ioctl_streamon, + .vidioc_streamoff =3D vb2_ioctl_streamoff, + + .vidioc_subscribe_event =3D v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event =3D v4l2_event_unsubscribe, +}; + +static const struct video_device neoisp_videodev =3D { + .name =3D NEOISP_NAME, + .vfl_dir =3D VFL_DIR_M2M, + .fops =3D &neoisp_fops, + .ioctl_ops =3D &neoisp_ioctl_ops, + .minor =3D -1, + .release =3D video_device_release_empty, +}; + +static struct v4l2_ctrl_config controls[] =3D { + [NEOISP_CTRLS_SUPPORTED_PARAMS_BLOCKS] =3D { + .id =3D V4L2_CID_NEOISP_SUPPORTED_PARAMS_BLOCKS, + .name =3D "Neoisp supported params blocks", + .type =3D V4L2_CTRL_TYPE_BITMASK, + .flags =3D V4L2_CTRL_FLAG_READ_ONLY, + }, +}; + +static irqreturn_t neoisp_irq_handler(int irq, void *dev_id) +{ + struct neoisp_dev_s *neoispd =3D (struct neoisp_dev_s *)dev_id; + struct neoisp_buffer_s **buf =3D neoispd->queued_job.buf; + u64 ts =3D ktime_get_ns(); + u32 irq_status =3D 0; + u32 irq_clear =3D 0; + bool done =3D false; + int i; + + irq_status =3D neoisp_rd(neoispd, NEO_PIPE_CONF_INT_STAT0); + + if (irq_status & NEO_PIPE_CONF_INT_STAT0_S_FS1) { + dev_dbg(neoispd->dev, "Neo IRQ FS1 !\n"); + irq_clear |=3D NEO_PIPE_CONF_INT_STAT0_S_FS1; + done =3D false; + } + + if (irq_status & NEO_PIPE_CONF_INT_STAT0_S_FS2) { + dev_dbg(neoispd->dev, "Neo IRQ FS2 !\n"); + irq_clear |=3D NEO_PIPE_CONF_INT_STAT0_S_FS2; + done =3D false; + } + + if (irq_status & NEO_PIPE_CONF_INT_STAT0_S_FD1) { + dev_dbg(neoispd->dev, "Neo IRQ FD1 !\n"); + irq_clear |=3D NEO_PIPE_CONF_INT_STAT0_S_FD1; + done =3D false; + } + + if (irq_status & NEO_PIPE_CONF_INT_STAT0_S_STATD) { + dev_dbg(neoispd->dev, "Neo IRQ STATD !\n"); + irq_clear |=3D NEO_PIPE_CONF_INT_STAT0_S_STATD; + done =3D false; + } + + if (irq_status & NEO_PIPE_CONF_INT_STAT0_S_DRCD) { + dev_dbg(neoispd->dev, "Neo IRQ DRCD !\n"); + neoisp_ctx_get_stats(neoispd, buf[NEOISP_STATS_NODE]); + irq_clear |=3D NEO_PIPE_CONF_INT_STAT0_S_DRCD; + done =3D false; + } + + if (irq_status & NEO_PIPE_CONF_INT_STAT0_S_BUS_ERR) { + irq_clear |=3D NEO_PIPE_CONF_INT_STAT0_S_BUS_ERR; + dev_err(neoispd->dev, "Neo IRQ BUS ERR!\n"); + done =3D true; + } + + if (irq_status & NEO_PIPE_CONF_INT_STAT0_S_TRIG_ERR) { + dev_err(neoispd->dev, "Neo IRQ TRIG ERR !\n"); + irq_clear |=3D NEO_PIPE_CONF_INT_STAT0_S_TRIG_ERR; + done =3D true; + } + + if (irq_status & NEO_PIPE_CONF_INT_STAT0_S_CSI_TERR) { + dev_err(neoispd->dev, "Neo IRQ TRIG CSI Trigger ERR !\n"); + irq_clear |=3D NEO_PIPE_CONF_INT_STAT0_S_CSI_TERR; + done =3D true; + } + + if (irq_status & NEO_PIPE_CONF_INT_STAT0_S_FD2) { + dev_dbg(neoispd->dev, "Neo IRQ FD2 !\n"); + irq_clear |=3D NEO_PIPE_CONF_INT_STAT0_S_FD2; + done =3D true; + } + + if (irq_status & NEO_PIPE_CONF_INT_STAT0_BUSY) + dev_err(neoispd->dev, "Neo is busy !\n"); + + neoisp_wr(neoispd, NEO_PIPE_CONF_INT_STAT0, irq_clear); + + if (done) { + for (i =3D 0; i < NEOISP_NODES_COUNT; i++) { + if (!buf[i]) + continue; + + buf[i]->vb.sequence =3D neoispd->frame_sequence; + buf[i]->vb.vb2_buf.timestamp =3D ts; + vb2_buffer_done(&buf[i]->vb.vb2_buf, VB2_BUF_STATE_DONE); + + /* To prevent double buffer handling in case of spurius interrupt */ + buf[i] =3D NULL; + } + /* Update frame_sequence */ + neoispd->frame_sequence++; + /* Check if there's more to do before going to sleep */ + neoisp_schedule(neoispd, true); + } + + return IRQ_HANDLED; +} + +static int neoisp_sd_subs_evt(struct v4l2_subdev *sd, struct v4l2_fh *fh, + struct v4l2_event_subscription *sub) +{ + switch (sub->type) { + case V4L2_EVENT_FRAME_SYNC: + return v4l2_event_subscribe(fh, sub, 0, NULL); + case V4L2_EVENT_CTRL: + return v4l2_ctrl_subdev_subscribe_event(sd, fh, sub); + default: + return -EINVAL; + } +} + +static const struct v4l2_subdev_core_ops neoisp_sd_core_ops =3D { + .subscribe_event =3D neoisp_sd_subs_evt, + .unsubscribe_event =3D v4l2_event_subdev_unsubscribe, +}; + +static const struct v4l2_subdev_pad_ops neoisp_sd_pad_ops =3D { + .link_validate =3D v4l2_subdev_link_validate_default, +}; + +static const struct v4l2_subdev_ops neoisp_sd_ops =3D { + .core =3D &neoisp_sd_core_ops, + .pad =3D &neoisp_sd_pad_ops, +}; + +static int neoisp_init_subdev(struct neoisp_dev_s *neoispd) +{ + struct v4l2_subdev *sd =3D &neoispd->sd; + struct v4l2_ctrl_config *control_cfg; + struct v4l2_ctrl_handler *hdl; + u32 i; + int ret; + + v4l2_subdev_init(sd, &neoisp_sd_ops); + sd->entity.function =3D MEDIA_ENT_F_PROC_VIDEO_ISP; + sd->owner =3D THIS_MODULE; + sd->dev =3D neoispd->dev; + sd->flags |=3D V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; + strscpy(sd->name, NEOISP_NAME, sizeof(sd->name)); + + for (i =3D 0; i < NEOISP_NODES_COUNT; i++) + neoispd->pad[i].flags =3D + node_desc_is_output(&node_desc[i]) ? + MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE; + + ret =3D media_entity_pads_init(&sd->entity, NEOISP_NODES_COUNT, neoispd->= pad); + if (ret) + goto err_media; + + /* Prepare Supported Params Block control */ + control_cfg =3D &controls[NEOISP_CTRLS_SUPPORTED_PARAMS_BLOCKS]; + i =3D 0; + while (neoispd->info->blocks_list[i] !=3D -1 && i < 64U) + control_cfg->max |=3D BIT(neoispd->info->blocks_list[i++]); + + control_cfg->def =3D control_cfg->max; + + /* Create custom controls */ + hdl =3D &neoispd->hdl; + v4l2_ctrl_handler_init(hdl, ARRAY_SIZE(controls)); + for (i =3D 0; i < ARRAY_SIZE(controls); i++) { + neoispd->ctrls[i] =3D v4l2_ctrl_new_custom(hdl, &controls[i], NULL); + if (hdl->error) { + dev_err(neoispd->dev, "Adding control (%d) failed\n", i); + ret =3D hdl->error; + goto err_hdl; + } + } + sd->ctrl_handler =3D hdl; + + ret =3D v4l2_device_register_subdev(&neoispd->v4l2_dev, sd); + if (ret) + goto err_hdl; + + return 0; + +err_hdl: + v4l2_ctrl_handler_free(&neoispd->hdl); +err_media: + media_entity_cleanup(&sd->entity); + return ret; +} + +static void node_set_default_format(struct neoisp_node_s *node) +{ + if (node_is_meta(node) && node_is_output(node)) { + /* Params node - exensible format */ + struct v4l2_format *f =3D &node->format; + + f->fmt.meta.dataformat =3D V4L2_META_FMT_NEO_ISP_EXT_PARAMS; + f->fmt.meta.buffersize =3D v4l2_isp_buffer_size(NEOISP_EXT_PARAMS_MAX_SI= ZE); + f->type =3D node->buf_type; + } else if (node_is_meta(node) && node_is_capture(node)) { + /* Stats node - extensible format */ + struct v4l2_format *f =3D &node->format; + + f->fmt.meta.dataformat =3D V4L2_META_FMT_NEO_ISP_EXT_STATS; + f->fmt.meta.buffersize =3D v4l2_isp_buffer_size(NEOISP_EXT_STATS_MAX_SIZ= E); + f->type =3D node->buf_type; + } else { + struct v4l2_format f =3D {0}; + + if (node_is_capture(node)) + f.fmt.pix_mp.pixelformat =3D formats_vcap[0].fourcc; + else + f.fmt.pix_mp.pixelformat =3D formats_vout[0].fourcc; + + f.fmt.pix_mp.width =3D NEOISP_DEF_W; + f.fmt.pix_mp.height =3D NEOISP_DEF_H; + f.type =3D node->buf_type; + neoisp_try_fmt(&f, node); + node->format =3D f; + } + node->crop.width =3D NEOISP_DEF_W; + node->crop.height =3D NEOISP_DEF_H; + + node->neoisp_format =3D + neoisp_find_pixel_format_by_node(node->format.fmt.pix_mp.pixelformat, no= de); +} + +/* + * Initialise a struct neoisp_node_s and register it as /dev/video + * to represent one of the neoisp's input or output streams. + */ +static int neoisp_init_node(struct neoisp_dev_s *neoispd, u32 id) +{ + bool output =3D node_desc_is_output(&node_desc[id]); + struct neoisp_node_s *node =3D &neoispd->node[id]; + struct media_entity *entity =3D &node->vfd.entity; + struct media_pad *mpad; + struct video_device *vdev =3D &node->vfd; + struct vb2_queue *q =3D &node->queue; + int ret; + + node->id =3D id; + node->neoisp =3D neoispd; + node->buf_type =3D node_desc[id].buf_type; + + INIT_LIST_HEAD(&node->ready_queue); + + node->format.type =3D node->buf_type; + node_set_default_format(node); + + q->type =3D node->buf_type; + q->io_modes =3D VB2_MMAP | VB2_DMABUF; + q->mem_ops =3D &vb2_dma_contig_memops; + q->drv_priv =3D node; + if (node->id =3D=3D NEOISP_PARAMS_NODE) + q->ops =3D &neoisp_params_node_queue_ops; + else + q->ops =3D &neoisp_node_queue_ops; + + q->buf_struct_size =3D sizeof(struct neoisp_buffer_s); + q->timestamp_flags =3D V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + q->dev =3D neoispd->dev; + /* Share neoisp lock between video devices */ + q->lock =3D &neoispd->queue_lock; + + ret =3D vb2_queue_init(q); + if (ret < 0) { + dev_err(neoispd->dev, "vb2_queue_init failed\n"); + return ret; + } + + *vdev =3D neoisp_videodev; /* Default initialization */ + strscpy(vdev->name, node_desc[id].ent_name, sizeof(vdev->name)); + vdev->v4l2_dev =3D &neoispd->v4l2_dev; + vdev->vfl_dir =3D output ? VFL_DIR_TX : VFL_DIR_RX; + /* Get V4L2 to serialise our ioctls */ + vdev->queue =3D &node->queue; + vdev->device_caps =3D V4L2_CAP_STREAMING | node_desc[id].caps; + + node->pad.flags =3D output ? MEDIA_PAD_FL_SOURCE : MEDIA_PAD_FL_SINK; + ret =3D media_entity_pads_init(entity, 1, &node->pad); + if (ret) { + dev_err(neoispd->dev, + "Failed to register video %s device node\n", + NODE_NAME(node)); + goto err_unregister_queue; + } + + ret =3D video_register_device(vdev, VFL_TYPE_VIDEO, -1); + if (ret) { + dev_err(neoispd->dev, + "Failed to register media pads for %s device node\n", + NODE_NAME(node)); + goto err_unregister_queue; + } + video_set_drvdata(vdev, node); + + if (output) + ret =3D media_create_pad_link(entity, 0, &neoispd->sd.entity, + id, node_desc[id].link_flags); + else + ret =3D media_create_pad_link(&neoispd->sd.entity, id, entity, + 0, node_desc[id].link_flags); + if (ret) + goto err_unregister_video_dev; + + media_entity_for_each_pad(&neoispd->sd.entity, mpad) + if (mpad->index =3D=3D id) + break; + if (output) + node->intf_link =3D media_entity_find_link(&node->pad, mpad); + else + node->intf_link =3D media_entity_find_link(mpad, &node->pad); + + dev_dbg(neoispd->dev, + "%s device node registered as /dev/video%d\n", + NODE_NAME(node), node->vfd.num); + + return 0; + +err_unregister_video_dev: + video_unregister_device(&node->vfd); +err_unregister_queue: + vb2_queue_release(&node->queue); + return ret; +} + +static int neoisp_init_group(struct neoisp_dev_s *neoispd, struct media_de= vice *mdev) +{ + struct v4l2_device *v4l2_dev =3D &neoispd->v4l2_dev; + u32 num_registered =3D 0; + int ret; + + mutex_init(&neoispd->queue_lock); + + /* Register v4l2_device and media_device */ + v4l2_dev->mdev =3D mdev; + strscpy(v4l2_dev->name, NEOISP_NAME, sizeof(v4l2_dev->name)); + + /* Register the NEOISP subdevice. */ + ret =3D neoisp_init_subdev(neoispd); + if (ret) + goto err_unregister_v4l2; + + /* Create device video nodes */ + for (; num_registered < NEOISP_NODES_COUNT; num_registered++) { + ret =3D neoisp_init_node(neoispd, num_registered); + if (ret) + goto err_unregister_nodes; + } + + ret =3D v4l2_device_register_subdev_nodes(v4l2_dev); + if (ret) + goto err_unregister_nodes; + + return 0; + +err_unregister_nodes: + v4l2_ctrl_handler_free(&neoispd->hdl); + media_entity_cleanup(&neoispd->sd.entity); + while (num_registered-- > 0) { + video_unregister_device(&neoispd->node[num_registered].vfd); + vb2_queue_release(&neoispd->node[num_registered].queue); + } + v4l2_device_unregister_subdev(&neoispd->sd); +err_unregister_v4l2: + v4l2_device_unregister(v4l2_dev); + mutex_destroy(&neoispd->queue_lock); + return ret; +} + +static void neoisp_destroy_devices(struct neoisp_dev_s *neoispd) +{ + int i; + + if (neoispd->context) { + dma_free_coherent(neoispd->dev, + sizeof(struct neoisp_context_s), + neoispd->context, + neoispd->params_dma_addr); + } + + v4l2_device_unregister(&neoispd->v4l2_dev); + + if (standalone_mdev) + media_device_unregister(&neoispd->mdev); + else if (!neoispd->media_registered) + return; + + dev_dbg(neoispd->dev, "Unregister from media controller\n"); + + v4l2_ctrl_handler_free(&neoispd->hdl); + media_entity_cleanup(&neoispd->sd.entity); + + for (i =3D NEOISP_NODES_COUNT - 1; i >=3D 0; i--) { + struct neoisp_node_s *node =3D &neoispd->node[i]; + + video_unregister_device(&node->vfd); + vb2_queue_release(&node->queue); + } + mutex_destroy(&neoispd->queue_lock); +} + +int neoisp_core_media_register(struct device *dev, struct v4l2_subdev *sd) +{ + struct neoisp_dev_s *neoispd =3D dev_get_drvdata(dev); + struct media_device *mdev =3D sd->v4l2_dev->mdev; + int ret; + + if (!neoispd) + return -EINVAL; + + if (neoispd->media_registered || standalone_mdev) + return 0; + + ret =3D neoisp_init_group(neoispd, mdev); + if (ret) + return ret; + + neoispd->media_registered++; + return 0; +} +EXPORT_SYMBOL_GPL(neoisp_core_media_register); + +static int neoisp_init_devices(struct neoisp_dev_s *neoispd) +{ + struct v4l2_device *v4l2_dev; + struct media_device *mdev; + int ret; + + v4l2_dev =3D &neoispd->v4l2_dev; + strscpy(v4l2_dev->name, NEOISP_NAME, sizeof(v4l2_dev->name)); + + ret =3D v4l2_device_register(neoispd->dev, v4l2_dev); + if (ret) + return ret; + + neoispd->streaming_map =3D 0; + neoispd->dummy_buf =3D NULL; + neoispd->context =3D dma_alloc_coherent(neoispd->dev, + sizeof(struct neoisp_context_s), + &neoispd->params_dma_addr, GFP_KERNEL); + if (!neoispd->context) { + dev_err(neoispd->dev, "Unable to allocate cached context buffers.\n"); + v4l2_device_unregister(v4l2_dev); + return -ENOMEM; + } + + if (!standalone_mdev) + return 0; + + /* Prepare neoisp media device in standalone mode only */ + mdev =3D &neoispd->mdev; + mdev->dev =3D neoispd->dev; + strscpy(mdev->model, NEOISP_NAME, sizeof(mdev->model)); + snprintf(mdev->bus_info, sizeof(mdev->bus_info), + "platform:%s", dev_name(neoispd->dev)); + media_device_init(mdev); + + ret =3D neoisp_init_group(neoispd, mdev); + if (ret) { + dma_free_coherent(neoispd->dev, + sizeof(struct neoisp_context_s), + neoispd->context, + neoispd->params_dma_addr); + goto err_group; + } + + ret =3D media_device_register(mdev); + if (ret) + goto err_media; + + return 0; + +err_media: + neoisp_destroy_devices(neoispd); +err_group: + media_device_cleanup(mdev); + return ret; +} + +static void neoisp_init_hw(struct neoisp_dev_s *neoispd) +{ + u32 val; + + neoisp_reset_hw(neoispd, false); + neoisp_reset_hw(neoispd, true); + + /* Disable bus error if eDMA transfer is used */ + neoisp_wr(neoispd, NEO_PIPE_CONF_REG_XFR_DIS, + NEO_PIPE_CONF_REG_XFR_DIS_XFR_ERR_DIS); + + /* Disable debug */ + neoisp_wr(neoispd, NEO_IDBG1_LINE_NUM, + NEO_IDBG1_LINE_NUM_LINE_NUM); + neoisp_wr(neoispd, NEO_IDBG2_LINE_NUM, + NEO_IDBG2_LINE_NUM_LINE_NUM); + + /* Enable interrupts */ + val =3D NEO_PIPE_CONF_INT_EN0_EN_FD2 | + NEO_PIPE_CONF_INT_EN0_EN_DRCD | + NEO_PIPE_CONF_INT_EN0_EN_BUS_ERR | + NEO_PIPE_CONF_INT_EN0_EN_CSI_TERR | + NEO_PIPE_CONF_INT_EN0_EN_TRIG_ERR; + neoisp_wr(neoispd, NEO_PIPE_CONF_INT_EN0, val); +} + +static int neoisp_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct neoisp_dev_s *neoispd; + struct resource *r; + int ret, irq; + + neoispd =3D devm_kzalloc(dev, sizeof(*neoispd), GFP_KERNEL); + if (!neoispd) + return -ENOMEM; + + INIT_LIST_HEAD(&neoispd->job_queue); + + neoispd->dev =3D dev; + neoispd->info =3D (struct neoisp_info_s *)of_device_get_match_data(dev); + + ret =3D devm_clk_bulk_get_all(dev, &neoispd->clks); + if (ret < 0) { + dev_err(dev, "Unable to get clocks: %d\n", ret); + return ret; + } + neoispd->num_clks =3D ret; + + /* Get regs address */ + neoispd->mmio =3D devm_platform_get_and_ioremap_resource(pdev, 0, NULL); + if (IS_ERR(neoispd->mmio)) + return PTR_ERR(neoispd->mmio); + + /* Get internal isp memory address */ + r =3D platform_get_resource(pdev, IORESOURCE_MEM, 1); + neoispd->local_mem =3D (void *)devm_ioremap_resource_wc(dev, r); + if (IS_ERR(neoispd->local_mem)) + return PTR_ERR(neoispd->local_mem); + + irq =3D platform_get_irq(pdev, 0); + if (irq < 0) { + ret =3D irq; + goto err_irq; + } + + platform_set_drvdata(pdev, neoispd); + + ret =3D devm_request_irq(dev, irq, neoisp_irq_handler, 0, + dev_name(dev), neoispd); + if (ret < 0) { + dev_err(dev, "Failed to request irq: %d\n", ret); + goto err_irq; + } + + pm_runtime_set_autosuspend_delay(dev, NEOISP_SUSPEND_TIMEOUT_MS); + pm_runtime_use_autosuspend(dev); + pm_runtime_enable(dev); + ret =3D pm_runtime_resume_and_get(dev); + if (ret < 0) { + dev_err(dev, "Unable to resume the device: %d\n", ret); + goto err_pm_runtime_disable; + } + + ret =3D neoisp_init_devices(neoispd); + if (ret) + goto err_pm_runtime_suspend; + + spin_lock_init(&neoispd->hw_lock); + neoisp_init_hw(neoispd); + neoisp_set_default_context(neoispd); + + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + + return 0; + +err_pm_runtime_suspend: + pm_runtime_put(dev); +err_pm_runtime_disable: + pm_runtime_dont_use_autosuspend(dev); + pm_runtime_disable(dev); +err_irq: + dev_err(dev, "probe: error %d\n", ret); + return ret; +} + +static void neoisp_remove(struct platform_device *pdev) +{ + struct neoisp_dev_s *neoispd =3D platform_get_drvdata(pdev); + + neoisp_destroy_devices(neoispd); + + if (standalone_mdev) + media_device_cleanup(&neoispd->mdev); + + pm_runtime_dont_use_autosuspend(neoispd->dev); + pm_runtime_disable(neoispd->dev); +} + +static int __maybe_unused neoisp_runtime_suspend(struct device *dev) +{ + struct neoisp_dev_s *neoispd =3D dev_get_drvdata(dev); + + clk_bulk_disable_unprepare(neoispd->num_clks, neoispd->clks); + + return 0; +} + +static int __maybe_unused neoisp_runtime_resume(struct device *dev) +{ + int ret; + struct neoisp_dev_s *neoispd =3D dev_get_drvdata(dev); + + ret =3D clk_bulk_prepare_enable(neoispd->num_clks, neoispd->clks); + + if (ret) { + dev_err(dev, "Failed to resume device. Could not re-enable clocks.\n"); + return ret; + } + + neoisp_init_hw(neoispd); + + return 0; +} + +static int __maybe_unused neoisp_pm_suspend(struct device *dev) +{ + struct neoisp_dev_s *neoispd =3D dev_get_drvdata(dev); + unsigned long timeout; + + timeout =3D jiffies + msecs_to_jiffies(NEOISP_SUSPEND_TIMEOUT_MS); + while (neoispd->hw_busy) { + cond_resched(); + if (time_after_eq(jiffies, timeout)) { + dev_err(dev, "Failed to enter idle on system suspend\n"); + return -EBUSY; + } + } + + pm_runtime_force_suspend(dev); + + return 0; +} + +static int __maybe_unused neoisp_pm_resume(struct device *dev) +{ + return pm_runtime_force_resume(dev); +} + +static const struct dev_pm_ops neoisp_pm =3D { + SET_SYSTEM_SLEEP_PM_OPS(neoisp_pm_suspend, neoisp_pm_resume) + SET_RUNTIME_PM_OPS(neoisp_runtime_suspend, neoisp_runtime_resume, NULL) +}; + +static const unsigned int neoisp_blocks_list_imx95x[] =3D { + NEOISP_PARAM_BLK_PIPE_CONF, + NEOISP_PARAM_BLK_HEAD_COLOR, + NEOISP_PARAM_BLK_HDR_DECOMPRESS0, + NEOISP_PARAM_BLK_HDR_DECOMPRESS1, + NEOISP_PARAM_BLK_OBWB0, + NEOISP_PARAM_BLK_OBWB1, + NEOISP_PARAM_BLK_OBWB2, + NEOISP_PARAM_BLK_HDR_MERGE, + NEOISP_PARAM_BLK_RGBIR, + NEOISP_PARAM_BLK_STAT, + NEOISP_PARAM_BLK_CTEMP, + NEOISP_PARAM_BLK_IR_COMPRESS, + NEOISP_PARAM_BLK_BNR, + NEOISP_PARAM_BLK_VIGNETTING_CTRL, + NEOISP_PARAM_BLK_DEMOSAIC, + NEOISP_PARAM_BLK_RGB2YUV, + NEOISP_PARAM_BLK_DR_COMP, + NEOISP_PARAM_BLK_NR, + NEOISP_PARAM_BLK_AF, + NEOISP_PARAM_BLK_EE, + NEOISP_PARAM_BLK_DF, + NEOISP_PARAM_BLK_CONVMED, + NEOISP_PARAM_BLK_CAS, + NEOISP_PARAM_BLK_GCM, + NEOISP_PARAM_BLK_VIGNETTING_TABLE, + NEOISP_PARAM_BLK_DRC_GLOBAL_TONEMAP, + NEOISP_PARAM_BLK_DRC_LOCAL_TONEMAP, + -1, /* end of list */ +}; + +static const struct neoisp_info_s neoisp_imx95_data =3D { + .blocks_list =3D neoisp_blocks_list_imx95x, +}; + +static const struct of_device_id neoisp_dt_ids[] =3D { + { .compatible =3D "nxp,imx95-neoisp", .data =3D &neoisp_imx95_data }, + { }, +}; +MODULE_DEVICE_TABLE(of, neoisp_dt_ids); + +static struct platform_driver neoisp_driver =3D { + .probe =3D neoisp_probe, + .remove =3D neoisp_remove, + .driver =3D { + .name =3D NEOISP_NAME, + .pm =3D &neoisp_pm, + .of_match_table =3D neoisp_dt_ids, + }, +}; + +module_platform_driver(neoisp_driver); + +MODULE_DESCRIPTION("NXP NEOISP Hardware"); +MODULE_AUTHOR("Antoine Bouyer "); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/platform/nxp/neoisp/neoisp_nodes.h b/drivers/med= ia/platform/nxp/neoisp/neoisp_nodes.h new file mode 100644 index 000000000000..54986fe13b33 --- /dev/null +++ b/drivers/media/platform/nxp/neoisp/neoisp_nodes.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * NEOISP nodes description + * + * Copyright 2023-2026 NXP + */ + +#ifndef __NXP_NEOISP_NODES_H +#define __NXP_NEOISP_NODES_H + +#include + +#include "neoisp.h" + +static const struct neoisp_node_desc_s node_desc[NEOISP_NODES_COUNT] =3D { + [NEOISP_INPUT0_NODE] =3D { + .ent_name =3D NEOISP_NAME "-input0", + .buf_type =3D V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + .caps =3D V4L2_CAP_VIDEO_OUTPUT_MPLANE, + .link_flags =3D MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED, + }, + [NEOISP_INPUT1_NODE] =3D { + .ent_name =3D NEOISP_NAME "-input1", + .buf_type =3D V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + .caps =3D V4L2_CAP_VIDEO_OUTPUT_MPLANE, + .link_flags =3D 0u, + }, + [NEOISP_PARAMS_NODE] =3D { + .ent_name =3D NEOISP_NAME "-params", + .buf_type =3D V4L2_BUF_TYPE_META_OUTPUT, + .caps =3D V4L2_CAP_META_OUTPUT, + .link_flags =3D MEDIA_LNK_FL_ENABLED, + }, + [NEOISP_FRAME_NODE] =3D { + .ent_name =3D NEOISP_NAME "-frame", + .buf_type =3D V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, + .caps =3D V4L2_CAP_VIDEO_CAPTURE_MPLANE, + .link_flags =3D MEDIA_LNK_FL_ENABLED, + }, + [NEOISP_IR_NODE] =3D { + .ent_name =3D NEOISP_NAME "-ir", + .buf_type =3D V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, + .caps =3D V4L2_CAP_VIDEO_CAPTURE_MPLANE, + .link_flags =3D 0u, + }, + [NEOISP_STATS_NODE] =3D { + .ent_name =3D NEOISP_NAME "-stats", + .buf_type =3D V4L2_BUF_TYPE_META_CAPTURE, + .caps =3D V4L2_CAP_META_CAPTURE, + .link_flags =3D MEDIA_LNK_FL_ENABLED, + }, +}; + +#endif /* __NXP_NEOISP_NODES_H */ diff --git a/drivers/media/platform/nxp/neoisp/neoisp_regs.h b/drivers/medi= a/platform/nxp/neoisp/neoisp_regs.h new file mode 100644 index 000000000000..8323250b6da6 --- /dev/null +++ b/drivers/media/platform/nxp/neoisp/neoisp_regs.h @@ -0,0 +1,1465 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * NEOISP registers definition + * + * Copyright 2023-2026 NXP + */ + +#ifndef __NXP_NEOISP_REGS_H +#define __NXP_NEOISP_REGS_H + +#include + +/* PIPE_CONF */ +#define NEO_PIPE_CONF_SOFT_RESET 0x0 +#define NEO_PIPE_CONF_SOFT_RESET_SOFT_RESET BIT(0) +#define NEO_PIPE_CONF_SOFT_RESET_HARD_RESET BIT(1) + +#define NEO_PIPE_CONF_BUS_TXPARAM 0x4 +#define NEO_PIPE_CONF_BUS_TXPARAM_OTLT GENMASK(7, 0) +#define NEO_PIPE_CONF_BUS_TXPARAM_OTHT GENMASK(15, 8) +#define NEO_PIPE_CONF_BUS_TXPARAM_POSTQOS GENMASK(23, 16) +#define NEO_PIPE_CONF_BUS_TXPARAM_BSIZE GENMASK(31, 24) + +#define NEO_PIPE_CONF_REG_XFR_DIS 0x8 +#define NEO_PIPE_CONF_REG_XFR_DIS_XFR_ERR_DIS BIT(31) + +#define NEO_PIPE_CONF_CSI_CTRL 0x10 +#define NEO_PIPE_CONF_CSI_CTRL_VID0 GENMASK(4, 0) +#define NEO_PIPE_CONF_CSI_CTRL_VID1 GENMASK(12, 8) +#define NEO_PIPE_CONF_CSI_CTRL_SSEN BIT(29) +#define NEO_PIPE_CONF_CSI_CTRL_DEVL BIT(30) +#define NEO_PIPE_CONF_CSI_CTRL_CSI_EN BIT(31) + +#define NEO_PIPE_CONF_FRAME_NUM 0x14 +#define NEO_PIPE_CONF_FRAME_NUM_CURR_FRAME GENMASK(15, 0) +#define NEO_PIPE_CONF_FRAME_NUM_SHD_FRAME GENMASK(31, 16) + +#define NEO_PIPE_CONF_REG_SHD_CTRL 0x18 +#define NEO_PIPE_CONF_REG_SHD_CTRL_CTRL BIT(31) + +#define NEO_PIPE_CONF_REG_SHD_CMD 0x1c + +#define NEO_PIPE_CONF_TRIG_CAM0 0x20 +#define NEO_PIPE_CONF_TRIG_CAM0_TRIGGER BIT(0) + +#define NEO_PIPE_CONF_IMG_CONF_CAM0 0x30 +#define NEO_PIPE_CONF_IMG_CONF_CAM0_IBPP0 GENMASK(3, 0) +#define NEO_PIPE_CONF_IMG_CONF_CAM0_INALIGN0 BIT(4) +#define NEO_PIPE_CONF_IMG_CONF_CAM0_LPALIGN0 BIT(5) +#define NEO_PIPE_CONF_IMG_CONF_CAM0_IBPP1 GENMASK(19, 16) +#define NEO_PIPE_CONF_IMG_CONF_CAM0_INALIGN1 BIT(20) +#define NEO_PIPE_CONF_IMG_CONF_CAM0_LPALIGN1 BIT(21) + +#define NEO_PIPE_CONF_IMG_SIZE_CAM0 0x34 +#define NEO_PIPE_CONF_IMG_SIZE_CAM0_WIDTH GENMASK(15, 0) +#define NEO_PIPE_CONF_IMG_SIZE_CAM0_HEIGHT GENMASK(31, 16) + +/* PIPE_CONF ADDR registers contain the upper 32-bits of the 36-bit addres= s of an image frame */ +#define NEO_PIPE_CONF_ADDR_CONVERT(x) (((x) >> 4) & ~0u) + +#define NEO_PIPE_CONF_IMG0_IN_ADDR_CAM0 0x3c +#define NEO_PIPE_CONF_IMG0_IN_ADDR_CAM0_ADDR GENMASK(31, 0) + +#define NEO_PIPE_CONF_IMG1_IN_ADDR_CAM0 0x40 +#define NEO_PIPE_CONF_IMG1_IN_ADDR_CAM0_ADDR GENMASK(31, 0) + +#define NEO_PIPE_CONF_OUTCH0_ADDR_CAM0 0x44 +#define NEO_PIPE_CONF_OUTCH0_ADDR_CAM0_ADDR GENMASK(31, 0) + +#define NEO_PIPE_CONF_OUTCH1_ADDR_CAM0 0x48 +#define NEO_PIPE_CONF_OUTCH1_ADDR_CAM0_ADDR GENMASK(31, 0) + +#define NEO_PIPE_CONF_OUTIR_ADDR_CAM0 0x4c +#define NEO_PIPE_CONF_OUTIR_ADDR_CAM0_ADDR GENMASK(31, 0) + +#define NEO_PIPE_CONF_IMG0_IN_LS_CAM0 0x50 +#define NEO_PIPE_CONF_IMG0_IN_LS_CAM0_LS GENMASK(31, 0) + +#define NEO_PIPE_CONF_IMG1_IN_LS_CAM0 0x54 +#define NEO_PIPE_CONF_IMG1_IN_LS_CAM0_LS GENMASK(31, 0) + +#define NEO_PIPE_CONF_OUTCH0_LS_CAM0 0x58 +#define NEO_PIPE_CONF_OUTCH0_LS_CAM0_LS GENMASK(31, 0) + +#define NEO_PIPE_CONF_OUTCH1_LS_CAM0 0x5c +#define NEO_PIPE_CONF_OUTCH1_LS_CAM0_LS GENMASK(31, 0) + +#define NEO_PIPE_CONF_OUTIR_LS_CAM0 0x60 +#define NEO_PIPE_CONF_OUTIR_LS_CAM0_LS GENMASK(31, 0) + +#define NEO_PIPE_CONF_SKIP_CTRL0 0x64 +#define NEO_PIPE_CONF_SKIP_CTRL0_PRESKIP GENMASK(15, 0) +#define NEO_PIPE_CONF_SKIP_CTRL0_POSTSKIP GENMASK(31, 16) + +#define NEO_PIPE_CONF_INT_EN0 0x24 +#define NEO_PIPE_CONF_INT_EN0_EN_FS1 BIT(0) +#define NEO_PIPE_CONF_INT_EN0_EN_FS2 BIT(1) +#define NEO_PIPE_CONF_INT_EN0_EN_FD1 BIT(2) +#define NEO_PIPE_CONF_INT_EN0_EN_FD2 BIT(3) +#define NEO_PIPE_CONF_INT_EN0_EN_STATD BIT(4) +#define NEO_PIPE_CONF_INT_EN0_EN_DRCD BIT(5) +#define NEO_PIPE_CONF_INT_EN0_EN_BUS_ERR GENMASK(19, 16) +#define NEO_PIPE_CONF_INT_EN0_EN_CSI_TERR BIT(29) +#define NEO_PIPE_CONF_INT_EN0_EN_TRIG_ERR BIT(30) + +#define NEO_PIPE_CONF_INT_STAT0 0x28 +#define NEO_PIPE_CONF_INT_STAT0_S_FS1 BIT(0) +#define NEO_PIPE_CONF_INT_STAT0_S_FS2 BIT(1) +#define NEO_PIPE_CONF_INT_STAT0_S_FD1 BIT(2) +#define NEO_PIPE_CONF_INT_STAT0_S_FD2 BIT(3) +#define NEO_PIPE_CONF_INT_STAT0_S_STATD BIT(4) +#define NEO_PIPE_CONF_INT_STAT0_S_DRCD BIT(5) +#define NEO_PIPE_CONF_INT_STAT0_S_BUS_ERR GENMASK(19, 16) +#define NEO_PIPE_CONF_INT_STAT0_S_CSI_TERR BIT(29) +#define NEO_PIPE_CONF_INT_STAT0_S_TRIG_ERR BIT(30) +#define NEO_PIPE_CONF_INT_STAT0_BUSY BIT(31) + +#define NEO_PIPE_CONF_CSI_STAT 0x2c +#define NEO_PIPE_CONF_CSI_STAT_S_SL_LP0 BIT(0) +#define NEO_PIPE_CONF_CSI_STAT_S_SF_LP0 BIT(1) +#define NEO_PIPE_CONF_CSI_STAT_S_DO_LP0 BIT(2) +#define NEO_PIPE_CONF_CSI_STAT_S_LOC_LP0 BIT(3) +#define NEO_PIPE_CONF_CSI_STAT_S_LO_LP0 BIT(4) +#define NEO_PIPE_CONF_CSI_STAT_S_CMD_LP0 BIT(5) +#define NEO_PIPE_CONF_CSI_STAT_S_LL_LP0 BIT(6) +#define NEO_PIPE_CONF_CSI_STAT_S_DATA_LP0 BIT(7) +#define NEO_PIPE_CONF_CSI_STAT_S_SL_LP1 BIT(16) +#define NEO_PIPE_CONF_CSI_STAT_S_SF_LP1 BIT(17) +#define NEO_PIPE_CONF_CSI_STAT_S_DO_LP1 BIT(18) +#define NEO_PIPE_CONF_CSI_STAT_S_LOC_LP1 BIT(19) +#define NEO_PIPE_CONF_CSI_STAT_S_LO_LP1 BIT(20) +#define NEO_PIPE_CONF_CSI_STAT_S_CMD_LP1 BIT(21) +#define NEO_PIPE_CONF_CSI_STAT_S_LL_LP1 BIT(22) +#define NEO_PIPE_CONF_CSI_STAT_S_DATA_LP1 BIT(23) +#define NEO_PIPE_CONF_CSI_STAT_S_STOP BIT(31) + +/* HC */ +#define NEO_HC_CTRL_CAM0 0xc0 +#define NEO_HC_CTRL_CAM0_HOFFSET GENMASK(1, 0) +#define NEO_HC_CTRL_CAM0_VOFFSET GENMASK(3, 2) + +/* HDR_DECOMPRESS0 */ +#define NEO_HDR_DECOMPRESS0_CTRL_CAM0 0x100 +#define NEO_HDR_DECOMPRESS0_CTRL_CAM0_ENABLE BIT(31) + +#define NEO_HDR_DECOMPRESS0_KNEE_POINT1_CAM0 0x104 +#define NEO_HDR_DECOMPRESS0_KNEE_POINT1_CAM0_KNEEPOINT GENMASK(15, 0) + +#define NEO_HDR_DECOMPRESS0_KNEE_POINT2_CAM0 0x108 +#define NEO_HDR_DECOMPRESS0_KNEE_POINT2_CAM0_KNEEPOINT GENMASK(15, 0) + +#define NEO_HDR_DECOMPRESS0_KNEE_POINT3_CAM0 0x10c +#define NEO_HDR_DECOMPRESS0_KNEE_POINT3_CAM0_KNEEPOINT GENMASK(15, 0) + +#define NEO_HDR_DECOMPRESS0_KNEE_POINT4_CAM0 0x110 +#define NEO_HDR_DECOMPRESS0_KNEE_POINT4_CAM0_KNEEPOINT GENMASK(15, 0) + +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET0_CAM0 0x114 +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET0_CAM0_OFFSET GENMASK(15, 0) + +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET1_CAM0 0x118 +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET1_CAM0_OFFSET GENMASK(15, 0) + +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET2_CAM0 0x11c +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET2_CAM0_OFFSET GENMASK(15, 0) + +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET3_CAM0 0x120 +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET3_CAM0_OFFSET GENMASK(15, 0) + +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET4_CAM0 0x124 +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET4_CAM0_OFFSET GENMASK(15, 0) + +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO01_CAM0 0x128 +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO01_CAM0_RATIO0 GENMASK(11, 0) +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO01_CAM0_RATIO1 GENMASK(27, 16) + +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO23_CAM0 0x12c +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO23_CAM0_RATIO2 GENMASK(11, 0) +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO23_CAM0_RATIO3 GENMASK(27, 16) + +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO4_CAM0 0x130 +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO4_CAM0_RATIO4 GENMASK(11, 0) + +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT0_CAM0 0x134 +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT0_CAM0_KNEEPOINT GENMASK(19, 0) + +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT1_CAM0 0x138 +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT1_CAM0_KNEEPOINT GENMASK(19, 0) + +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT2_CAM0 0x13c +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT2_CAM0_KNEEPOINT GENMASK(19, 0) + +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT3_CAM0 0x140 +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT3_CAM0_KNEEPOINT GENMASK(19, 0) + +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT4_CAM0 0x144 +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT4_CAM0_KNEEPOINT GENMASK(19, 0) + +/* HDR_DECOMPRESS1 */ +#define NEO_HDR_DECOMPRESS1_CTRL_CAM0 0x180 +#define NEO_HDR_DECOMPRESS1_CTRL_CAM0_ENABLE BIT(31) + +#define NEO_HDR_DECOMPRESS1_KNEE_POINT1_CAM0 0x184 +#define NEO_HDR_DECOMPRESS1_KNEE_POINT1_CAM0_KNEEPOINT GENMASK(15, 0) + +#define NEO_HDR_DECOMPRESS1_KNEE_POINT2_CAM0 0x188 +#define NEO_HDR_DECOMPRESS1_KNEE_POINT2_CAM0_KNEEPOINT GENMASK(15, 0) + +#define NEO_HDR_DECOMPRESS1_KNEE_POINT3_CAM0 0x18c +#define NEO_HDR_DECOMPRESS1_KNEE_POINT3_CAM0_KNEEPOINT GENMASK(15, 0) + +#define NEO_HDR_DECOMPRESS1_KNEE_POINT4_CAM0 0x190 +#define NEO_HDR_DECOMPRESS1_KNEE_POINT4_CAM0_KNEEPOINT GENMASK(15, 0) + +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET0_CAM0 0x194 +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET0_CAM0_OFFSET GENMASK(15, 0) + +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET1_CAM0 0x198 +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET1_CAM0_OFFSET GENMASK(15, 0) + +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET2_CAM0 0x19c +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET2_CAM0_OFFSET GENMASK(15, 0) + +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET3_CAM0 0x1a0 +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET3_CAM0_OFFSET GENMASK(15, 0) + +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET4_CAM0 0x1a4 +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET4_CAM0_OFFSET GENMASK(15, 0) + +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO01_CAM0 0x1a8 +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO01_CAM0_RATIO0 GENMASK(11, 0) +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO01_CAM0_RATIO1 GENMASK(27, 16) + +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO23_CAM0 0x1ac +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO23_CAM0_RATIO2 GENMASK(11, 0) +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO23_CAM0_RATIO3 GENMASK(27, 16) + +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO4_CAM0 0x1b0 +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO4_CAM0_RATIO4 GENMASK(11, 0) + +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT0_CAM0 0x1b4 +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT0_CAM0_KNEEPOINT GENMASK(15, 0) + +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT1_CAM0 0x1b8 +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT1_CAM0_KNEEPOINT GENMASK(15, 0) + +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT2_CAM0 0x1bc +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT2_CAM0_KNEEPOINT GENMASK(15, 0) + +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT3_CAM0 0x1c0 +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT3_CAM0_KNEEPOINT GENMASK(15, 0) + +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT4_CAM0 0x1c4 +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT4_CAM0_KNEEPOINT GENMASK(15, 0) + +/* OB_WB0 */ +#define NEO_OB_WB0_CTRL_CAM0 0x200 +#define NEO_OB_WB0_CTRL_CAM0_OBPP GENMASK(3, 2) + +#define NEO_OB_WB0_R_CTRL_CAM0 0x204 +#define NEO_OB_WB0_R_CTRL_CAM0_OFFSET GENMASK(15, 0) +#define NEO_OB_WB0_R_CTRL_CAM0_GAIN GENMASK(31, 16) + +#define NEO_OB_WB0_GR_CTRL_CAM0 0x208 +#define NEO_OB_WB0_GR_CTRL_CAM0_OFFSET GENMASK(15, 0) +#define NEO_OB_WB0_GR_CTRL_CAM0_GAIN GENMASK(31, 16) + +#define NEO_OB_WB0_GB_CTRL_CAM0 0x20c +#define NEO_OB_WB0_GB_CTRL_CAM0_OFFSET GENMASK(15, 0) +#define NEO_OB_WB0_GB_CTRL_CAM0_GAIN GENMASK(31, 16) + +#define NEO_OB_WB0_B_CTRL_CAM0 0x210 +#define NEO_OB_WB0_B_CTRL_CAM0_OFFSET GENMASK(15, 0) +#define NEO_OB_WB0_B_CTRL_CAM0_GAIN GENMASK(31, 16) + +/* OB_WB1 */ +#define NEO_OB_WB1_CTRL_CAM0 0x240 +#define NEO_OB_WB1_CTRL_CAM0_OBPP GENMASK(3, 2) + +#define NEO_OB_WB1_R_CTRL_CAM0 0x244 +#define NEO_OB_WB1_R_CTRL_CAM0_OFFSET GENMASK(15, 0) +#define NEO_OB_WB1_R_CTRL_CAM0_GAIN GENMASK(31, 16) + +#define NEO_OB_WB1_GR_CTRL_CAM0 0x248 +#define NEO_OB_WB1_GR_CTRL_CAM0_OFFSET GENMASK(15, 0) +#define NEO_OB_WB1_GR_CTRL_CAM0_GAIN GENMASK(31, 16) + +#define NEO_OB_WB1_GB_CTRL_CAM0 0x24c +#define NEO_OB_WB1_GB_CTRL_CAM0_OFFSET GENMASK(15, 0) +#define NEO_OB_WB1_GB_CTRL_CAM0_GAIN GENMASK(31, 16) + +#define NEO_OB_WB1_B_CTRL_CAM0 0x250 +#define NEO_OB_WB1_B_CTRL_CAM0_OFFSET GENMASK(15, 0) +#define NEO_OB_WB1_B_CTRL_CAM0_GAIN GENMASK(31, 16) + +/* OB_WB2 */ +#define NEO_OB_WB2_CTRL_CAM0 0x280 +#define NEO_OB_WB2_CTRL_CAM0_OBPP GENMASK(3, 2) + +#define NEO_OB_WB2_R_CTRL_CAM0 0x284 +#define NEO_OB_WB2_R_CTRL_CAM0_OFFSET GENMASK(15, 0) +#define NEO_OB_WB2_R_CTRL_CAM0_GAIN GENMASK(31, 16) + +#define NEO_OB_WB2_GR_CTRL_CAM0 0x288 +#define NEO_OB_WB2_GR_CTRL_CAM0_OFFSET GENMASK(15, 0) +#define NEO_OB_WB2_GR_CTRL_CAM0_GAIN GENMASK(31, 16) + +#define NEO_OB_WB2_GB_CTRL_CAM0 0x28c +#define NEO_OB_WB2_GB_CTRL_CAM0_OFFSET GENMASK(15, 0) +#define NEO_OB_WB2_GB_CTRL_CAM0_GAIN GENMASK(31, 16) + +#define NEO_OB_WB2_B_CTRL_CAM0 0x290 +#define NEO_OB_WB2_B_CTRL_CAM0_OFFSET GENMASK(15, 0) +#define NEO_OB_WB2_B_CTRL_CAM0_GAIN GENMASK(31, 16) + +/* HDR_MERGE */ +#define NEO_HDR_MERGE_CTRL_CAM0 0x300 +#define NEO_HDR_MERGE_CTRL_CAM0_OBPP GENMASK(3, 2) +#define NEO_HDR_MERGE_CTRL_CAM0_SAFETY_ON BIT(4) +#define NEO_HDR_MERGE_CTRL_CAM0_MOTION_FIX_EN BIT(8) +#define NEO_HDR_MERGE_CTRL_CAM0_BLEND_3X3 BIT(9) +#define NEO_HDR_MERGE_CTRL_CAM0_GAIN0BPP GENMASK(17, 16) +#define NEO_HDR_MERGE_CTRL_CAM0_GAIN1BPP GENMASK(19, 18) +#define NEO_HDR_MERGE_CTRL_CAM0_ENABLE BIT(31) + +#define NEO_HDR_MERGE_GAIN_OFFSET_CAM0 0x304 +#define NEO_HDR_MERGE_GAIN_OFFSET_CAM0_OFFSET0 GENMASK(15, 0) +#define NEO_HDR_MERGE_GAIN_OFFSET_CAM0_OFFSET1 GENMASK(31, 16) + +#define NEO_HDR_MERGE_GAIN_SCALE_CAM0 0x308 +#define NEO_HDR_MERGE_GAIN_SCALE_CAM0_SCALE0 GENMASK(15, 0) +#define NEO_HDR_MERGE_GAIN_SCALE_CAM0_SCALE1 GENMASK(31, 16) + +#define NEO_HDR_MERGE_GAIN_SHIFT_CAM0 0x30c +#define NEO_HDR_MERGE_GAIN_SHIFT_CAM0_SHIFT0 GENMASK(4, 0) +#define NEO_HDR_MERGE_GAIN_SHIFT_CAM0_SHIFT1 GENMASK(20, 16) + +#define NEO_HDR_MERGE_LUMA_TH_CAM0 0x310 +#define NEO_HDR_MERGE_LUMA_TH_CAM0_TH0 GENMASK(15, 0) + +#define NEO_HDR_MERGE_LUMA_SCALE_CAM0 0x314 +#define NEO_HDR_MERGE_LUMA_SCALE_CAM0_SCALE GENMASK(15, 0) +#define NEO_HDR_MERGE_LUMA_SCALE_CAM0_SHIFT GENMASK(20, 16) +#define NEO_HDR_MERGE_LUMA_SCALE_CAM0_THSHIFT GENMASK(28, 24) + +#define NEO_HDR_MERGE_DOWNSCALE_CAM0 0x318 +#define NEO_HDR_MERGE_DOWNSCALE_CAM0_IMGSCALE0 GENMASK(4, 0) +#define NEO_HDR_MERGE_DOWNSCALE_CAM0_IMGSCALE1 GENMASK(20, 16) + +#define NEO_HDR_MERGE_UPSCALE_CAM0 0x31c +#define NEO_HDR_MERGE_UPSCALE_CAM0_IMGSCALE0 GENMASK(3, 0) +#define NEO_HDR_MERGE_UPSCALE_CAM0_IMGSCALE1 GENMASK(19, 16) + +#define NEO_HDR_MERGE_POST_SCALE_CAM0 0x320 +#define NEO_HDR_MERGE_POST_SCALE_CAM0_SCALE GENMASK(4, 0) + +#define NEO_HDR_MERGE_S_GAIN_OFFSET_CAM0 0x324 +#define NEO_HDR_MERGE_S_GAIN_OFFSET_CAM0_OFFSET0 GENMASK(15, 0) +#define NEO_HDR_MERGE_S_GAIN_OFFSET_CAM0_OFFSET1 GENMASK(31, 16) + +#define NEO_HDR_MERGE_S_GAIN_SCALE_CAM0 0x328 +#define NEO_HDR_MERGE_S_GAIN_SCALE_CAM0_SCALE0 GENMASK(15, 0) +#define NEO_HDR_MERGE_S_GAIN_SCALE_CAM0_SCALE1 GENMASK(31, 16) + +#define NEO_HDR_MERGE_S_GAIN_SHIFT_CAM0 0x32c +#define NEO_HDR_MERGE_S_GAIN_SHIFT_CAM0_SHIFT0 GENMASK(4, 0) +#define NEO_HDR_MERGE_S_GAIN_SHIFT_CAM0_SHIFT1 GENMASK(20, 16) + +#define NEO_HDR_MERGE_S_LUMA_TH_CAM0 0x330 +#define NEO_HDR_MERGE_S_LUMA_TH_CAM0_TH0 GENMASK(15, 0) + +#define NEO_HDR_MERGE_S_LUMA_SCALE_CAM0 0x334 +#define NEO_HDR_MERGE_S_LUMA_SCALE_CAM0_SCALE GENMASK(15, 0) +#define NEO_HDR_MERGE_S_LUMA_SCALE_CAM0_SHIFT GENMASK(20, 16) +#define NEO_HDR_MERGE_S_LUMA_SCALE_CAM0_THSHIFT GENMASK(28, 24) + +#define NEO_HDR_MERGE_S_DOWNSCALE_CAM0 0x338 +#define NEO_HDR_MERGE_S_DOWNSCALE_CAM0_IMGSCALE0 GENMASK(4, 0) +#define NEO_HDR_MERGE_S_DOWNSCALE_CAM0_IMGSCALE1 GENMASK(20, 16) + +#define NEO_HDR_MERGE_S_UPSCALE_CAM0 0x33c +#define NEO_HDR_MERGE_S_UPSCALE_CAM0_IMGSCALE0 GENMASK(3, 0) +#define NEO_HDR_MERGE_S_UPSCALE_CAM0_IMGSCALE1 GENMASK(19, 16) + +#define NEO_HDR_MERGE_S_POST_SCALE_CAM0 0x340 +#define NEO_HDR_MERGE_S_POST_SCALE_CAM0_SCALE GENMASK(4, 0) + +#define NEO_HDR_MERGE_S_LINE_NUM_CAM0 0x344 +#define NEO_HDR_MERGE_S_LINE_NUM_CAM0_LINE GENMASK(15, 1) + +/* COLOR_TEMP */ +#define NEO_COLOR_TEMP_CTRL_CAM0 0x400 +#define NEO_COLOR_TEMP_CTRL_CAM0_IBPP GENMASK(1, 0) +#define NEO_COLOR_TEMP_CTRL_CAM0_CSCON BIT(4) +#define NEO_COLOR_TEMP_CTRL_CAM0_ENABLE BIT(31) + +#define NEO_COLOR_TEMP_ROI_POS_CAM0 0x404 +#define NEO_COLOR_TEMP_ROI_POS_CAM0_XPOS GENMASK(15, 0) +#define NEO_COLOR_TEMP_ROI_POS_CAM0_YPOS GENMASK(31, 16) + +#define NEO_COLOR_TEMP_ROI_SIZE_CAM0 0x408 +#define NEO_COLOR_TEMP_ROI_SIZE_CAM0_WIDTH GENMASK(15, 0) +#define NEO_COLOR_TEMP_ROI_SIZE_CAM0_HEIGHT GENMASK(31, 16) + +#define NEO_COLOR_TEMP_REDGAIN_CAM0 0x40c +#define NEO_COLOR_TEMP_REDGAIN_CAM0_MIN GENMASK(7, 0) +#define NEO_COLOR_TEMP_REDGAIN_CAM0_MAX GENMASK(23, 16) + +#define NEO_COLOR_TEMP_BLUEGAIN_CAM0 0x410 +#define NEO_COLOR_TEMP_BLUEGAIN_CAM0_MIN GENMASK(7, 0) +#define NEO_COLOR_TEMP_BLUEGAIN_CAM0_MAX GENMASK(23, 16) + +#define NEO_COLOR_TEMP_POINT1_CAM0 0x414 +#define NEO_COLOR_TEMP_POINT1_CAM0_BLUE GENMASK(7, 0) +#define NEO_COLOR_TEMP_POINT1_CAM0_RED GENMASK(23, 16) + +#define NEO_COLOR_TEMP_POINT2_CAM0 0x418 +#define NEO_COLOR_TEMP_POINT2_CAM0_BLUE GENMASK(7, 0) +#define NEO_COLOR_TEMP_POINT2_CAM0_RED GENMASK(23, 16) + +#define NEO_COLOR_TEMP_HOFFSET_CAM0 0x41c +#define NEO_COLOR_TEMP_HOFFSET_CAM0_RIGHT GENMASK(7, 0) +#define NEO_COLOR_TEMP_HOFFSET_CAM0_LEFT GENMASK(23, 16) + +#define NEO_COLOR_TEMP_VOFFSET_CAM0 0x420 +#define NEO_COLOR_TEMP_VOFFSET_CAM0_UP GENMASK(7, 0) +#define NEO_COLOR_TEMP_VOFFSET_CAM0_DOWN GENMASK(23, 16) + +#define NEO_COLOR_TEMP_POINT1_SLOPE_CAM0 0x424 +#define NEO_COLOR_TEMP_POINT1_SLOPE_CAM0_SLOPE_L GENMASK(15, 0) +#define NEO_COLOR_TEMP_POINT1_SLOPE_CAM0_SLOPE_R GENMASK(31, 16) + +#define NEO_COLOR_TEMP_POINT2_SLOPE_CAM0 0x428 +#define NEO_COLOR_TEMP_POINT2_SLOPE_CAM0_SLOPE_L GENMASK(15, 0) +#define NEO_COLOR_TEMP_POINT2_SLOPE_CAM0_SLOPE_R GENMASK(31, 16) + +#define NEO_COLOR_TEMP_LUMA_TH_CAM0 0x42c +#define NEO_COLOR_TEMP_LUMA_TH_CAM0_THL GENMASK(15, 0) +#define NEO_COLOR_TEMP_LUMA_TH_CAM0_THH GENMASK(31, 16) + +#define NEO_COLOR_TEMP_CSC_MAT0_CAM0 0x430 +#define NEO_COLOR_TEMP_CSC_MAT0_CAM0_R0C0 GENMASK(15, 0) +#define NEO_COLOR_TEMP_CSC_MAT0_CAM0_R0C1 GENMASK(31, 16) + +#define NEO_COLOR_TEMP_CSC_MAT1_CAM0 0x434 +#define NEO_COLOR_TEMP_CSC_MAT1_CAM0_R0C2 GENMASK(15, 0) +#define NEO_COLOR_TEMP_CSC_MAT1_CAM0_R1C0 GENMASK(31, 16) + +#define NEO_COLOR_TEMP_CSC_MAT2_CAM0 0x438 +#define NEO_COLOR_TEMP_CSC_MAT2_CAM0_R1C1 GENMASK(15, 0) +#define NEO_COLOR_TEMP_CSC_MAT2_CAM0_R1C2 GENMASK(31, 16) + +#define NEO_COLOR_TEMP_CSC_MAT3_CAM0 0x43c +#define NEO_COLOR_TEMP_CSC_MAT3_CAM0_R2C0 GENMASK(15, 0) +#define NEO_COLOR_TEMP_CSC_MAT3_CAM0_R2C1 GENMASK(31, 16) + +#define NEO_COLOR_TEMP_CSC_MAT4_CAM0 0x440 +#define NEO_COLOR_TEMP_CSC_MAT4_CAM0_R2C2 GENMASK(15, 0) + +#define NEO_COLOR_TEMP_R_GR_OFFSET_CAM0 0x444 +#define NEO_COLOR_TEMP_R_GR_OFFSET_CAM0_OFFSET0 GENMASK(15, 0) +#define NEO_COLOR_TEMP_R_GR_OFFSET_CAM0_OFFSET1 GENMASK(31, 16) + +#define NEO_COLOR_TEMP_GB_B_OFFSET_CAM0 0x448 +#define NEO_COLOR_TEMP_GB_B_OFFSET_CAM0_OFFSET0 GENMASK(15, 0) +#define NEO_COLOR_TEMP_GB_B_OFFSET_CAM0_OFFSET1 GENMASK(31, 16) + +#define NEO_COLOR_TEMP_CNT_WHITE_CAM0 0x44c + +#define NEO_COLOR_TEMP_SUMRL_CAM0 0x450 + +#define NEO_COLOR_TEMP_SUMRH_CAM0 0x454 + +#define NEO_COLOR_TEMP_SUMGL_CAM0 0x458 + +#define NEO_COLOR_TEMP_SUMGH_CAM0 0x45c + +#define NEO_COLOR_TEMP_SUMBL_CAM0 0x460 + +#define NEO_COLOR_TEMP_SUMBH_CAM0 0x464 + +#define NEO_COLOR_TEMP_SUMRGL_CAM0 0x468 + +#define NEO_COLOR_TEMP_SUMRGH_CAM0 0x46c + +#define NEO_COLOR_TEMP_SUMBGL_CAM0 0x470 + +#define NEO_COLOR_TEMP_SUMBGH_CAM0 0x474 + +#define NEO_COLOR_TEMP_STAT_BLK_SIZE0 0x480 +#define NEO_COLOR_TEMP_STAT_BLK_SIZE0_XSIZE GENMASK(15, 0) +#define NEO_COLOR_TEMP_STAT_BLK_SIZE0_YSIZE GENMASK(31, 16) + +#define NEO_COLOR_TEMP_STAT_CURR_BLK_Y0 0x488 +#define NEO_COLOR_TEMP_STAT_CURR_BLK_Y0_BLKLNE GENMASK(15, 0) +#define NEO_COLOR_TEMP_STAT_CURR_BLK_Y0_BLKROW GENMASK(18, 16) + +#define NEO_COLOR_TEMP_CROI0_POS_CAM0 0x490 +#define NEO_COLOR_TEMP_CROI0_POS_CAM0_ROVERG_LOW GENMASK(7, 0) +#define NEO_COLOR_TEMP_CROI0_POS_CAM0_ROVERG_HIGH GENMASK(15, 8) +#define NEO_COLOR_TEMP_CROI0_POS_CAM0_BOVERG_LOW GENMASK(23, 16) +#define NEO_COLOR_TEMP_CROI0_POS_CAM0_BOVERG_HIGH GENMASK(31, 24) + +#define NEO_COLOR_TEMP_CROI0_PIXCNT_CAM0 0x498 +#define NEO_COLOR_TEMP_CROI0_PIXCNT_CAM0_PIXCNT GENMASK(23, 0) + +#define NEO_COLOR_TEMP_CROI0_SUMRED_CAM0 0x49c + +#define NEO_COLOR_TEMP_CROI0_SUMGREEN_CAM0 0x4a0 + +#define NEO_COLOR_TEMP_CROI0_SUMBLUE_CAM0 0x4a4 + +#define NEO_COLOR_TEMP_CROI1_POS_CAM0 0x4a8 +#define NEO_COLOR_TEMP_CROI1_POS_CAM0_ROVERG_LOW GENMASK(7, 0) +#define NEO_COLOR_TEMP_CROI1_POS_CAM0_ROVERG_HIGH GENMASK(15, 8) +#define NEO_COLOR_TEMP_CROI1_POS_CAM0_BOVERG_LOW GENMASK(23, 16) +#define NEO_COLOR_TEMP_CROI1_POS_CAM0_BOVERG_HIGH GENMASK(31, 24) + +#define NEO_COLOR_TEMP_CROI1_PIXCNT_CAM0 0x4b0 +#define NEO_COLOR_TEMP_CROI1_PIXCNT_CAM0_PIXCNT GENMASK(23, 0) + +#define NEO_COLOR_TEMP_CROI1_SUMRED_CAM0 0x4b4 + +#define NEO_COLOR_TEMP_CROI1_SUMGREEN_CAM0 0x4b8 + +#define NEO_COLOR_TEMP_CROI1_SUMBLUE_CAM0 0x4bc + +#define NEO_COLOR_TEMP_CROI2_POS_CAM0 0x4c0 +#define NEO_COLOR_TEMP_CROI2_POS_CAM0_ROVERG_LOW GENMASK(7, 0) +#define NEO_COLOR_TEMP_CROI2_POS_CAM0_ROVERG_HIGH GENMASK(15, 8) +#define NEO_COLOR_TEMP_CROI2_POS_CAM0_BOVERG_LOW GENMASK(23, 16) +#define NEO_COLOR_TEMP_CROI2_POS_CAM0_BOVERG_HIGH GENMASK(31, 24) + +#define NEO_COLOR_TEMP_CROI2_PIXCNT_CAM0 0x4c8 +#define NEO_COLOR_TEMP_CROI2_PIXCNT_CAM0_PIXCNT GENMASK(23, 0) + +#define NEO_COLOR_TEMP_CROI2_SUMRED_CAM0 0x4cc + +#define NEO_COLOR_TEMP_CROI2_SUMGREEN_CAM0 0x4d0 + +#define NEO_COLOR_TEMP_CROI2_SUMBLUE_CAM0 0x4d4 + +#define NEO_COLOR_TEMP_CROI3_POS_CAM0 0x4d8 +#define NEO_COLOR_TEMP_CROI3_POS_CAM0_ROVERG_LOW GENMASK(7, 0) +#define NEO_COLOR_TEMP_CROI3_POS_CAM0_ROVERG_HIGH GENMASK(15, 8) +#define NEO_COLOR_TEMP_CROI3_POS_CAM0_BOVERG_LOW GENMASK(23, 16) +#define NEO_COLOR_TEMP_CROI3_POS_CAM0_BOVERG_HIGH GENMASK(31, 24) + +#define NEO_COLOR_TEMP_CROI3_PIXCNT_CAM0 0x4e0 +#define NEO_COLOR_TEMP_CROI3_PIXCNT_CAM0_PIXCNT GENMASK(23, 0) + +#define NEO_COLOR_TEMP_CROI3_SUMRED_CAM0 0x4e4 + +#define NEO_COLOR_TEMP_CROI3_SUMGREEN_CAM0 0x4e8 + +#define NEO_COLOR_TEMP_CROI3_SUMBLUE_CAM0 0x4ec + +#define NEO_COLOR_TEMP_CROI4_POS_CAM0 0x4f0 +#define NEO_COLOR_TEMP_CROI4_POS_CAM0_ROVERG_LOW GENMASK(7, 0) +#define NEO_COLOR_TEMP_CROI4_POS_CAM0_ROVERG_HIGH GENMASK(15, 8) +#define NEO_COLOR_TEMP_CROI4_POS_CAM0_BOVERG_LOW GENMASK(23, 16) +#define NEO_COLOR_TEMP_CROI4_POS_CAM0_BOVERG_HIGH GENMASK(31, 24) + +#define NEO_COLOR_TEMP_CROI4_PIXCNT_CAM0 0x4f8 +#define NEO_COLOR_TEMP_CROI4_PIXCNT_CAM0_PIXCNT GENMASK(23, 0) + +#define NEO_COLOR_TEMP_CROI4_SUMRED_CAM0 0x4fc + +#define NEO_COLOR_TEMP_CROI4_SUMGREEN_CAM0 0x500 + +#define NEO_COLOR_TEMP_CROI4_SUMBLUE_CAM0 0x504 + +#define NEO_COLOR_TEMP_CROI5_POS_CAM0 0x508 +#define NEO_COLOR_TEMP_CROI5_POS_CAM0_ROVERG_LOW GENMASK(7, 0) +#define NEO_COLOR_TEMP_CROI5_POS_CAM0_ROVERG_HIGH GENMASK(15, 8) +#define NEO_COLOR_TEMP_CROI5_POS_CAM0_BOVERG_LOW GENMASK(23, 16) +#define NEO_COLOR_TEMP_CROI5_POS_CAM0_BOVERG_HIGH GENMASK(31, 24) + +#define NEO_COLOR_TEMP_CROI5_PIXCNT_CAM0 0x510 +#define NEO_COLOR_TEMP_CROI5_PIXCNT_CAM0_PIXCNT GENMASK(23, 0) + +#define NEO_COLOR_TEMP_CROI5_SUMRED_CAM0 0x514 + +#define NEO_COLOR_TEMP_CROI5_SUMGREEN_CAM0 0x518 + +#define NEO_COLOR_TEMP_CROI5_SUMBLUE_CAM0 0x51c + +#define NEO_COLOR_TEMP_CROI6_POS_CAM0 0x520 +#define NEO_COLOR_TEMP_CROI6_POS_CAM0_ROVERG_LOW GENMASK(7, 0) +#define NEO_COLOR_TEMP_CROI6_POS_CAM0_ROVERG_HIGH GENMASK(15, 8) +#define NEO_COLOR_TEMP_CROI6_POS_CAM0_BOVERG_LOW GENMASK(23, 16) +#define NEO_COLOR_TEMP_CROI6_POS_CAM0_BOVERG_HIGH GENMASK(31, 24) + +#define NEO_COLOR_TEMP_CROI6_PIXCNT_CAM0 0x528 +#define NEO_COLOR_TEMP_CROI6_PIXCNT_CAM0_PIXCNT GENMASK(23, 0) + +#define NEO_COLOR_TEMP_CROI6_SUMRED_CAM0 0x52c + +#define NEO_COLOR_TEMP_CROI6_SUMGREEN_CAM0 0x530 + +#define NEO_COLOR_TEMP_CROI6_SUMBLUE_CAM0 0x534 + +#define NEO_COLOR_TEMP_CROI7_POS_CAM0 0x538 +#define NEO_COLOR_TEMP_CROI7_POS_CAM0_ROVERG_LOW GENMASK(7, 0) +#define NEO_COLOR_TEMP_CROI7_POS_CAM0_ROVERG_HIGH GENMASK(15, 8) +#define NEO_COLOR_TEMP_CROI7_POS_CAM0_BOVERG_LOW GENMASK(23, 16) +#define NEO_COLOR_TEMP_CROI7_POS_CAM0_BOVERG_HIGH GENMASK(31, 24) + +#define NEO_COLOR_TEMP_CROI7_PIXCNT_CAM0 0x540 +#define NEO_COLOR_TEMP_CROI7_PIXCNT_CAM0_PIXCNT GENMASK(23, 0) + +#define NEO_COLOR_TEMP_CROI7_SUMRED_CAM0 0x544 + +#define NEO_COLOR_TEMP_CROI7_SUMGREEN_CAM0 0x548 + +#define NEO_COLOR_TEMP_CROI7_SUMBLUE_CAM0 0x54c + +#define NEO_COLOR_TEMP_CROI8_POS_CAM0 0x550 +#define NEO_COLOR_TEMP_CROI8_POS_CAM0_ROVERG_LOW GENMASK(7, 0) +#define NEO_COLOR_TEMP_CROI8_POS_CAM0_ROVERG_HIGH GENMASK(15, 8) +#define NEO_COLOR_TEMP_CROI8_POS_CAM0_BOVERG_LOW GENMASK(23, 16) +#define NEO_COLOR_TEMP_CROI8_POS_CAM0_BOVERG_HIGH GENMASK(31, 24) + +#define NEO_COLOR_TEMP_CROI8_PIXCNT_CAM0 0x558 +#define NEO_COLOR_TEMP_CROI8_PIXCNT_CAM0_PIXCNT GENMASK(23, 0) + +#define NEO_COLOR_TEMP_CROI8_SUMRED_CAM0 0x55c + +#define NEO_COLOR_TEMP_CROI8_SUMGREEN_CAM0 0x560 + +#define NEO_COLOR_TEMP_CROI8_SUMBLUE_CAM0 0x564 + +#define NEO_COLOR_TEMP_CROI9_POS_CAM0 0x568 +#define NEO_COLOR_TEMP_CROI9_POS_CAM0_ROVERG_LOW GENMASK(7, 0) +#define NEO_COLOR_TEMP_CROI9_POS_CAM0_ROVERG_HIGH GENMASK(15, 8) +#define NEO_COLOR_TEMP_CROI9_POS_CAM0_BOVERG_LOW GENMASK(23, 16) +#define NEO_COLOR_TEMP_CROI9_POS_CAM0_BOVERG_HIGH GENMASK(31, 24) + +#define NEO_COLOR_TEMP_CROI9_PIXCNT_CAM0 0x570 +#define NEO_COLOR_TEMP_CROI9_PIXCNT_CAM0_PIXCNT GENMASK(23, 0) + +#define NEO_COLOR_TEMP_CROI9_SUMRED_CAM0 0x574 + +#define NEO_COLOR_TEMP_CROI9_SUMGREEN_CAM0 0x578 + +#define NEO_COLOR_TEMP_CROI9_SUMBLUE_CAM0 0x57c + +#define NEO_COLOR_TEMP_GR_AVG_IN_CAM0 0x584 +#define NEO_COLOR_TEMP_GR_AVG_IN_CAM0_GR_AGV GENMASK(19, 0) + +#define NEO_COLOR_TEMP_GB_AVG_IN_CAM0 0x588 +#define NEO_COLOR_TEMP_GB_AVG_IN_CAM0_GB_AGV GENMASK(19, 0) + +#define NEO_COLOR_TEMP_GR_GB_CNT_CAM0 0x58c + +#define NEO_COLOR_TEMP_GR_SUM_CAM0 0x590 + +#define NEO_COLOR_TEMP_GB_SUM_CAM0 0x594 + +#define NEO_COLOR_TEMP_GR2_SUM_CAM0 0x598 + +#define NEO_COLOR_TEMP_GB2_SUM_CAM0 0x59c + +#define NEO_COLOR_TEMP_GRGB_SUM_CAM0 0x5a0 + +/* RGBIR */ +#define NEO_RGBIR_CTRL_CAM0 0x600 +#define NEO_RGBIR_CTRL_CAM0_ENABLE BIT(31) + +#define NEO_RGBIR_CCM0_CAM0 0x604 +#define NEO_RGBIR_CCM0_CAM0_CCM GENMASK(15, 0) + +#define NEO_RGBIR_CCM1_CAM0 0x608 +#define NEO_RGBIR_CCM1_CAM0_CCM GENMASK(15, 0) + +#define NEO_RGBIR_CCM2_CAM0 0x60c +#define NEO_RGBIR_CCM2_CAM0_CCM GENMASK(15, 0) + +#define NEO_RGBIR_CCM0_TH_CAM0 0x610 +#define NEO_RGBIR_CCM0_TH_CAM0_THRESHOLD GENMASK(19, 0) + +#define NEO_RGBIR_CCM1_TH_CAM0 0x614 +#define NEO_RGBIR_CCM1_TH_CAM0_THRESHOLD GENMASK(19, 0) + +#define NEO_RGBIR_CCM2_TH_CAM0 0x618 +#define NEO_RGBIR_CCM2_TH_CAM0_THRESHOLD GENMASK(19, 0) + +#define NEO_RGBIR_ROI0_POS_CAM0 0x620 +#define NEO_RGBIR_ROI0_POS_CAM0_XPOS GENMASK(15, 0) +#define NEO_RGBIR_ROI0_POS_CAM0_YPOS GENMASK(31, 16) + +#define NEO_RGBIR_ROI0_SIZE_CAM0 0x624 +#define NEO_RGBIR_ROI0_SIZE_CAM0_WIDTH GENMASK(15, 0) +#define NEO_RGBIR_ROI0_SIZE_CAM0_HEIGHT GENMASK(31, 16) + +#define NEO_RGBIR_ROI1_POS_CAM0 0x628 +#define NEO_RGBIR_ROI1_POS_CAM0_XPOS GENMASK(15, 0) +#define NEO_RGBIR_ROI1_POS_CAM0_YPOS GENMASK(31, 16) + +#define NEO_RGBIR_ROI1_SIZE_CAM0 0x62c +#define NEO_RGBIR_ROI1_SIZE_CAM0_WIDTH GENMASK(15, 0) +#define NEO_RGBIR_ROI1_SIZE_CAM0_HEIGHT GENMASK(31, 16) + +#define NEO_RGBIR_HIST0_CTRL_CAM0 0x630 +#define NEO_RGBIR_HIST0_CTRL_CAM0_LIN_INPUT1_LOG BIT(0) +#define NEO_RGBIR_HIST0_CTRL_CAM0_DIR_INPUT1_DIF BIT(1) +#define NEO_RGBIR_HIST0_CTRL_CAM0_PATTERN BIT(2) +#define NEO_RGBIR_HIST0_CTRL_CAM0_CHANNEL GENMASK(11, 8) +#define NEO_RGBIR_HIST0_CTRL_CAM0_OFFSET GENMASK(31, 16) + +#define NEO_RGBIR_HIST0_SCALE_CAM0 0x634 +#define NEO_RGBIR_HIST0_SCALE_CAM0_SCALE GENMASK(23, 0) + +#define NEO_RGBIR_HIST1_CTRL_CAM0 0x638 +#define NEO_RGBIR_HIST1_CTRL_CAM0_LIN_INPUT1_LOG BIT(0) +#define NEO_RGBIR_HIST1_CTRL_CAM0_DIR_INPUT1_DIF BIT(1) +#define NEO_RGBIR_HIST1_CTRL_CAM0_PATTERN BIT(2) +#define NEO_RGBIR_HIST1_CTRL_CAM0_CHANNEL GENMASK(11, 8) +#define NEO_RGBIR_HIST1_CTRL_CAM0_OFFSET GENMASK(31, 16) + +#define NEO_RGBIR_HIST1_SCALE_CAM0 0x63c +#define NEO_RGBIR_HIST1_SCALE_CAM0_SCALE GENMASK(23, 0) + +/* STAT */ +#define NEO_STAT_ROI0_POS_CAM0 0x700 +#define NEO_STAT_ROI0_POS_CAM0_XPOS GENMASK(15, 0) +#define NEO_STAT_ROI0_POS_CAM0_YPOS GENMASK(31, 16) + +#define NEO_STAT_ROI0_SIZE_CAM0 0x704 +#define NEO_STAT_ROI0_SIZE_CAM0_WIDTH GENMASK(15, 0) +#define NEO_STAT_ROI0_SIZE_CAM0_HEIGHT GENMASK(31, 16) + +#define NEO_STAT_ROI1_POS_CAM0 0x708 +#define NEO_STAT_ROI1_POS_CAM0_XPOS GENMASK(15, 0) +#define NEO_STAT_ROI1_POS_CAM0_YPOS GENMASK(31, 16) + +#define NEO_STAT_ROI1_SIZE_CAM0 0x70c +#define NEO_STAT_ROI1_SIZE_CAM0_WIDTH GENMASK(15, 0) +#define NEO_STAT_ROI1_SIZE_CAM0_HEIGHT GENMASK(31, 16) + +#define NEO_STAT_HIST0_CTRL_CAM0 0x720 +#define NEO_STAT_HIST0_CTRL_CAM0_LIN_INPUT1_LOG BIT(0) +#define NEO_STAT_HIST0_CTRL_CAM0_DIR_INPUT1_DIF BIT(1) +#define NEO_STAT_HIST0_CTRL_CAM0_PATTERN BIT(2) +#define NEO_STAT_HIST0_CTRL_CAM0_CHANNEL GENMASK(11, 8) +#define NEO_STAT_HIST0_CTRL_CAM0_OFFSET GENMASK(31, 16) + +#define NEO_STAT_HIST0_SCALE_CAM0 0x724 +#define NEO_STAT_HIST0_SCALE_CAM0_SCALE GENMASK(23, 0) + +#define NEO_STAT_HIST1_CTRL_CAM0 0x728 +#define NEO_STAT_HIST1_CTRL_CAM0_LIN_INPUT1_LOG BIT(0) +#define NEO_STAT_HIST1_CTRL_CAM0_DIR_INPUT1_DIF BIT(1) +#define NEO_STAT_HIST1_CTRL_CAM0_PATTERN BIT(2) +#define NEO_STAT_HIST1_CTRL_CAM0_CHANNEL GENMASK(11, 8) +#define NEO_STAT_HIST1_CTRL_CAM0_OFFSET GENMASK(31, 16) + +#define NEO_STAT_HIST1_SCALE_CAM0 0x72c +#define NEO_STAT_HIST1_SCALE_CAM0_SCALE GENMASK(23, 0) + +#define NEO_STAT_HIST2_CTRL_CAM0 0x730 +#define NEO_STAT_HIST2_CTRL_CAM0_LIN_INPUT1_LOG BIT(0) +#define NEO_STAT_HIST2_CTRL_CAM0_DIR_INPUT1_DIF BIT(1) +#define NEO_STAT_HIST2_CTRL_CAM0_PATTERN BIT(2) +#define NEO_STAT_HIST2_CTRL_CAM0_CHANNEL GENMASK(11, 8) +#define NEO_STAT_HIST2_CTRL_CAM0_OFFSET GENMASK(31, 16) + +#define NEO_STAT_HIST2_SCALE_CAM0 0x734 +#define NEO_STAT_HIST2_SCALE_CAM0_SCALE GENMASK(23, 0) + +#define NEO_STAT_HIST3_CTRL_CAM0 0x738 +#define NEO_STAT_HIST3_CTRL_CAM0_LIN_INPUT1_LOG BIT(0) +#define NEO_STAT_HIST3_CTRL_CAM0_DIR_INPUT1_DIF BIT(1) +#define NEO_STAT_HIST3_CTRL_CAM0_PATTERN BIT(2) +#define NEO_STAT_HIST3_CTRL_CAM0_CHANNEL GENMASK(11, 8) +#define NEO_STAT_HIST3_CTRL_CAM0_OFFSET GENMASK(31, 16) + +#define NEO_STAT_HIST3_SCALE_CAM0 0x73c +#define NEO_STAT_HIST3_SCALE_CAM0_SCALE GENMASK(23, 0) + +/* IR_COMPRESS */ +#define NEO_IR_COMPRESS_CTRL_CAM0 0x780 +#define NEO_IR_COMPRESS_CTRL_CAM0_OBPP BIT(0) +#define NEO_IR_COMPRESS_CTRL_CAM0_ENABLE BIT(31) + +#define NEO_IR_COMPRESS_KNEE_POINT1_CAM0 0x784 +#define NEO_IR_COMPRESS_KNEE_POINT1_CAM0_KNEEPOINT GENMASK(19, 0) + +#define NEO_IR_COMPRESS_KNEE_POINT2_CAM0 0x788 +#define NEO_IR_COMPRESS_KNEE_POINT2_CAM0_KNEEPOINT GENMASK(19, 0) + +#define NEO_IR_COMPRESS_KNEE_POINT3_CAM0 0x78c +#define NEO_IR_COMPRESS_KNEE_POINT3_CAM0_KNEEPOINT GENMASK(19, 0) + +#define NEO_IR_COMPRESS_KNEE_POINT4_CAM0 0x790 +#define NEO_IR_COMPRESS_KNEE_POINT4_CAM0_KNEEPOINT GENMASK(19, 0) + +#define NEO_IR_COMPRESS_KNEE_OFFSET0_CAM0 0x794 +#define NEO_IR_COMPRESS_KNEE_OFFSET0_CAM0_OFFSET GENMASK(19, 0) + +#define NEO_IR_COMPRESS_KNEE_OFFSET1_CAM0 0x798 +#define NEO_IR_COMPRESS_KNEE_OFFSET1_CAM0_OFFSET GENMASK(19, 0) + +#define NEO_IR_COMPRESS_KNEE_OFFSET2_CAM0 0x79c +#define NEO_IR_COMPRESS_KNEE_OFFSET2_CAM0_OFFSET GENMASK(19, 0) + +#define NEO_IR_COMPRESS_KNEE_OFFSET3_CAM0 0x7a0 +#define NEO_IR_COMPRESS_KNEE_OFFSET3_CAM0_OFFSET GENMASK(19, 0) + +#define NEO_IR_COMPRESS_KNEE_OFFSET4_CAM0 0x7a4 +#define NEO_IR_COMPRESS_KNEE_OFFSET4_CAM0_OFFSET GENMASK(19, 0) + +#define NEO_IR_COMPRESS_KNEE_RATIO01_CAM0 0x7a8 +#define NEO_IR_COMPRESS_KNEE_RATIO01_CAM0_RATIO0 GENMASK(15, 0) +#define NEO_IR_COMPRESS_KNEE_RATIO01_CAM0_RATIO1 GENMASK(31, 16) + +#define NEO_IR_COMPRESS_KNEE_RATIO23_CAM0 0x7ac +#define NEO_IR_COMPRESS_KNEE_RATIO23_CAM0_RATIO2 GENMASK(15, 0) +#define NEO_IR_COMPRESS_KNEE_RATIO23_CAM0_RATIO3 GENMASK(31, 16) + +#define NEO_IR_COMPRESS_KNEE_RATIO4_CAM0 0x7b0 +#define NEO_IR_COMPRESS_KNEE_RATIO4_CAM0_RATIO4 GENMASK(15, 0) + +#define NEO_IR_COMPRESS_KNEE_NPOINT0_CAM0 0x7b4 +#define NEO_IR_COMPRESS_KNEE_NPOINT0_CAM0_KNEEPOINT GENMASK(15, 0) + +#define NEO_IR_COMPRESS_KNEE_NPOINT1_CAM0 0x7b8 +#define NEO_IR_COMPRESS_KNEE_NPOINT1_CAM0_KNEEPOINT GENMASK(15, 0) + +#define NEO_IR_COMPRESS_KNEE_NPOINT2_CAM0 0x7bc +#define NEO_IR_COMPRESS_KNEE_NPOINT2_CAM0_KNEEPOINT GENMASK(15, 0) + +#define NEO_IR_COMPRESS_KNEE_NPOINT3_CAM0 0x7c0 +#define NEO_IR_COMPRESS_KNEE_NPOINT3_CAM0_KNEEPOINT GENMASK(15, 0) + +#define NEO_IR_COMPRESS_KNEE_NPOINT4_CAM0 0x7c4 +#define NEO_IR_COMPRESS_KNEE_NPOINT4_CAM0_KNEEPOINT GENMASK(15, 0) + +/* BNR */ +#define NEO_BNR_CTRL_CAM0 0x800 +#define NEO_BNR_CTRL_CAM0_OBPP GENMASK(3, 2) +#define NEO_BNR_CTRL_CAM0_DEBUG GENMASK(10, 8) +#define NEO_BNR_CTRL_CAM0_NHOOD BIT(16) +#define NEO_BNR_CTRL_CAM0_ENABLE BIT(31) + +#define NEO_BNR_YPEAK_CAM0 0x804 +#define NEO_BNR_YPEAK_CAM0_PEAK_LOW GENMASK(11, 0) +#define NEO_BNR_YPEAK_CAM0_PEAK_SEL GENMASK(15, 14) +#define NEO_BNR_YPEAK_CAM0_PEAK_HIGH GENMASK(27, 16) +#define NEO_BNR_YPEAK_CAM0_PEAK_OUTSEL BIT(31) + +#define NEO_BNR_YEDGE_TH0_CAM0 0x808 +#define NEO_BNR_YEDGE_TH0_CAM0_EDGE_TH0 GENMASK(19, 0) + +#define NEO_BNR_YEDGE_SCALE_CAM0 0x80c +#define NEO_BNR_YEDGE_SCALE_CAM0_SCALE GENMASK(15, 0) +#define NEO_BNR_YEDGE_SCALE_CAM0_SHIFT GENMASK(20, 16) + +#define NEO_BNR_YEDGES_TH0_CAM0 0x810 +#define NEO_BNR_YEDGES_TH0_CAM0_EDGE_TH0 GENMASK(19, 0) + +#define NEO_BNR_YEDGES_SCALE_CAM0 0x814 +#define NEO_BNR_YEDGES_SCALE_CAM0_SCALE GENMASK(15, 0) +#define NEO_BNR_YEDGES_SCALE_CAM0_SHIFT GENMASK(20, 16) + +#define NEO_BNR_YEDGEA_TH0_CAM0 0x818 +#define NEO_BNR_YEDGEA_TH0_CAM0_EDGE_TH0 GENMASK(19, 0) + +#define NEO_BNR_YEDGEA_SCALE_CAM0 0x81c +#define NEO_BNR_YEDGEA_SCALE_CAM0_SCALE GENMASK(15, 0) +#define NEO_BNR_YEDGEA_SCALE_CAM0_SHIFT GENMASK(20, 16) + +#define NEO_BNR_YLUMA_X_TH0_CAM0 0x820 +#define NEO_BNR_YLUMA_X_TH0_CAM0_TH GENMASK(19, 0) + +#define NEO_BNR_YLUMA_Y_TH_CAM0 0x824 +#define NEO_BNR_YLUMA_Y_TH_CAM0_LUMA_Y_TH0 GENMASK(9, 0) +#define NEO_BNR_YLUMA_Y_TH_CAM0_LUMA_Y_TH1 GENMASK(25, 16) + +#define NEO_BNR_YLUMA_SCALE_CAM0 0x828 +#define NEO_BNR_YLUMA_SCALE_CAM0_SCALE GENMASK(15, 0) +#define NEO_BNR_YLUMA_SCALE_CAM0_SHIFT GENMASK(20, 16) + +#define NEO_BNR_YALPHA_GAIN_CAM0 0x82c +#define NEO_BNR_YALPHA_GAIN_CAM0_GAIN GENMASK(15, 0) +#define NEO_BNR_YALPHA_GAIN_CAM0_OFFSET GENMASK(31, 16) + +#define NEO_BNR_CPEAK_CAM0 0x830 +#define NEO_BNR_CPEAK_CAM0_PEAK_LOW GENMASK(11, 0) +#define NEO_BNR_CPEAK_CAM0_PEAK_SEL GENMASK(15, 14) +#define NEO_BNR_CPEAK_CAM0_PEAK_HIGH GENMASK(27, 16) +#define NEO_BNR_CPEAK_CAM0_PEAK_OUTSEL BIT(31) + +#define NEO_BNR_CEDGE_TH0_CAM0 0x834 +#define NEO_BNR_CEDGE_TH0_CAM0_EDGE_TH0 GENMASK(19, 0) + +#define NEO_BNR_CEDGE_SCALE_CAM0 0x838 +#define NEO_BNR_CEDGE_SCALE_CAM0_SCALE GENMASK(15, 0) +#define NEO_BNR_CEDGE_SCALE_CAM0_SHIFT GENMASK(20, 16) + +#define NEO_BNR_CEDGES_TH0_CAM0 0x83c +#define NEO_BNR_CEDGES_TH0_CAM0_EDGE_TH0 GENMASK(19, 0) + +#define NEO_BNR_CEDGES_SCALE_CAM0 0x840 +#define NEO_BNR_CEDGES_SCALE_CAM0_SCALE GENMASK(15, 0) +#define NEO_BNR_CEDGES_SCALE_CAM0_SHIFT GENMASK(20, 16) + +#define NEO_BNR_CEDGEA_TH0_CAM0 0x844 +#define NEO_BNR_CEDGEA_TH0_CAM0_EDGE_TH0 GENMASK(19, 0) + +#define NEO_BNR_CEDGEA_SCALE_CAM0 0x848 +#define NEO_BNR_CEDGEA_SCALE_CAM0_SCALE GENMASK(15, 0) +#define NEO_BNR_CEDGEA_SCALE_CAM0_SHIFT GENMASK(20, 16) + +#define NEO_BNR_CLUMA_X_TH0_CAM0 0x84c +#define NEO_BNR_CLUMA_X_TH0_CAM0_TH GENMASK(19, 0) + +#define NEO_BNR_CLUMA_Y_TH_CAM0 0x850 +#define NEO_BNR_CLUMA_Y_TH_CAM0_LUMA_Y_TH0 GENMASK(9, 0) +#define NEO_BNR_CLUMA_Y_TH_CAM0_LUMA_Y_TH1 GENMASK(25, 16) + +#define NEO_BNR_CLUMA_SCALE_CAM0 0x854 +#define NEO_BNR_CLUMA_SCALE_CAM0_SCALE GENMASK(15, 0) +#define NEO_BNR_CLUMA_SCALE_CAM0_SHIFT GENMASK(20, 16) + +#define NEO_BNR_CALPHA_GAIN_CAM0 0x858 +#define NEO_BNR_CALPHA_GAIN_CAM0_GAIN GENMASK(15, 0) +#define NEO_BNR_CALPHA_GAIN_CAM0_OFFSET GENMASK(31, 16) + +#define NEO_BNR_EDGE_STAT_CAM0 0x85c +#define NEO_BNR_EDGE_STAT_CAM0_EDGE_PIXELS GENMASK(23, 0) + +#define NEO_BNR_EDGES_STAT_CAM0 0x860 +#define NEO_BNR_EDGES_STAT_CAM0_EDGE_PIXELS GENMASK(23, 0) + +#define NEO_BNR_STRETCH_CAM0 0x864 +#define NEO_BNR_STRETCH_CAM0_GAIN GENMASK(15, 0) + +/* VIGNETTING */ +#define NEO_VIGNETTING_CTRL_CAM0 0x900 +#define NEO_VIGNETTING_CTRL_CAM0_ENABLE BIT(31) + +#define NEO_VIGNETTING_BLK_CONF_CAM0 0x904 +#define NEO_VIGNETTING_BLK_CONF_CAM0_COLS GENMASK(7, 0) +#define NEO_VIGNETTING_BLK_CONF_CAM0_ROWS GENMASK(23, 16) + +#define NEO_VIGNETTING_BLK_SIZE_CAM0 0x908 +#define NEO_VIGNETTING_BLK_SIZE_CAM0_XSIZE GENMASK(15, 0) +#define NEO_VIGNETTING_BLK_SIZE_CAM0_YSIZE GENMASK(31, 16) + +#define NEO_VIGNETTING_BLK_STEPY_CAM0 0x90c +#define NEO_VIGNETTING_BLK_STEPY_CAM0_STEP GENMASK(15, 0) + +#define NEO_VIGNETTING_BLK_STEPX_CAM0 0x910 +#define NEO_VIGNETTING_BLK_STEPX_CAM0_STEP GENMASK(15, 0) + +#define NEO_VIGNETTING_BLK_C_LINE_CAM0 0x920 +#define NEO_VIGNETTING_BLK_C_LINE_CAM0_LINE GENMASK(15, 0) + +#define NEO_VIGNETTING_BLK_C_ROW_CAM0 0x924 +#define NEO_VIGNETTING_BLK_C_ROW_CAM0_BLKROW GENMASK(7, 0) + +#define NEO_VIGNETTING_BLK_C_FRACY_CAM0 0x928 + +/* IDBG1 */ +#define NEO_IDBG1_LINE_NUM 0xfc0 +#define NEO_IDBG1_LINE_NUM_LINE_NUM GENMASK(16, 0) + +#define NEO_IDBG1_CURR_LINE_NUM 0xfc4 +#define NEO_IDBG1_CURR_LINE_NUM_CURR_LINE_NUM GENMASK(16, 0) +#define NEO_IDBG1_CURR_LINE_NUM_DBG_HIT BIT(31) + +#define NEO_IDBG1_IMA 0xfc8 +#define NEO_IDBG1_IMA_ADDR GENMASK(11, 0) +#define NEO_IDBG1_IMA_NAME GENMASK(20, 16) +#define NEO_IDBG1_IMA_RDWF GENMASK(29, 28) +#define NEO_IDBG1_IMA_WDWF GENMASK(31, 30) + +#define NEO_IDBG1_IMD 0xfcc + +#define NEO_IDBG1_DONE_STAT 0xfd0 +#define NEO_IDBG1_DONE_STAT_VIG BIT(0) +#define NEO_IDBG1_DONE_STAT_IRCOMP BIT(1) +#define NEO_IDBG1_DONE_STAT_HDRMERGE BIT(2) +#define NEO_IDBG1_DONE_STAT_BNR0 BIT(3) +#define NEO_IDBG1_DONE_STAT_STAT BIT(4) +#define NEO_IDBG1_DONE_STAT_CTEMP BIT(5) +#define NEO_IDBG1_DONE_STAT_OB_WB2 BIT(6) +#define NEO_IDBG1_DONE_STAT_OBWB1 BIT(7) +#define NEO_IDBG1_DONE_STAT_OBWB0 BIT(8) +#define NEO_IDBG1_DONE_STAT_HDRDECOMP1 BIT(9) +#define NEO_IDBG1_DONE_STAT_HDRDECOMP0 BIT(10) +#define NEO_IDBG1_DONE_STAT_HC BIT(11) +#define NEO_IDBG1_DONE_STAT_RGBIR BIT(12) + +/* DEMOSAIC */ +#define NEO_DEMOSAIC_CTRL_CAM0 0x1180 +#define NEO_DEMOSAIC_CTRL_CAM0_FMT GENMASK(5, 4) + +#define NEO_DEMOSAIC_ACTIVITY_CTL_CAM0 0x1184 +#define NEO_DEMOSAIC_ACTIVITY_CTL_CAM0_ALPHA GENMASK(8, 0) +#define NEO_DEMOSAIC_ACTIVITY_CTL_CAM0_ACT_RATIO GENMASK(31, 16) + +#define NEO_DEMOSAIC_DYNAMICS_CTL0_CAM0 0x1188 +#define NEO_DEMOSAIC_DYNAMICS_CTL0_CAM0_STRENGTHG GENMASK(15, 0) +#define NEO_DEMOSAIC_DYNAMICS_CTL0_CAM0_STRENGTHC GENMASK(31, 16) + +#define NEO_DEMOSAIC_DYNAMICS_CTL2_CAM0 0x118c +#define NEO_DEMOSAIC_DYNAMICS_CTL2_CAM0_MAX_IMPACT GENMASK(15, 0) + +/* RGB_TO_YUV */ +#define NEO_RGB_TO_YUV_GAIN_CTRL_CAM0 0x11c0 +#define NEO_RGB_TO_YUV_GAIN_CTRL_CAM0_RGAIN GENMASK(15, 0) +#define NEO_RGB_TO_YUV_GAIN_CTRL_CAM0_BGAIN GENMASK(31, 16) + +#define NEO_RGB_TO_YUV_MAT0_CAM0 0x11c4 +#define NEO_RGB_TO_YUV_MAT0_CAM0_R0C0 GENMASK(15, 0) +#define NEO_RGB_TO_YUV_MAT0_CAM0_R0C1 GENMASK(31, 16) + +#define NEO_RGB_TO_YUV_MAT1_CAM0 0x11c8 +#define NEO_RGB_TO_YUV_MAT1_CAM0_R0C2 GENMASK(15, 0) + +#define NEO_RGB_TO_YUV_MAT2_CAM0 0x11cc +#define NEO_RGB_TO_YUV_MAT2_CAM0_R1C0 GENMASK(15, 0) +#define NEO_RGB_TO_YUV_MAT2_CAM0_R1C1 GENMASK(31, 16) + +#define NEO_RGB_TO_YUV_MAT3_CAM0 0x11d0 +#define NEO_RGB_TO_YUV_MAT3_CAM0_R1C2 GENMASK(15, 0) + +#define NEO_RGB_TO_YUV_MAT4_CAM0 0x11d4 +#define NEO_RGB_TO_YUV_MAT4_CAM0_R2C0 GENMASK(15, 0) +#define NEO_RGB_TO_YUV_MAT4_CAM0_R2C1 GENMASK(31, 16) + +#define NEO_RGB_TO_YUV_MAT5_CAM0 0x11d8 +#define NEO_RGB_TO_YUV_MAT5_CAM0_R2C2 GENMASK(15, 0) + +#define NEO_RGB_TO_YUV_OFFSET0_CAM0 0x11e0 +#define NEO_RGB_TO_YUV_OFFSET0_CAM0_OFFSET GENMASK(20, 0) + +#define NEO_RGB_TO_YUV_OFFSET1_CAM0 0x11e4 +#define NEO_RGB_TO_YUV_OFFSET1_CAM0_OFFSET GENMASK(20, 0) + +#define NEO_RGB_TO_YUV_OFFSET2_CAM0 0x11e8 +#define NEO_RGB_TO_YUV_OFFSET2_CAM0_OFFSET GENMASK(20, 0) + +/* DRC */ +#define NEO_DRC_ROI0_POS_CAM0 0x1300 +#define NEO_DRC_ROI0_POS_CAM0_XPOS GENMASK(15, 0) +#define NEO_DRC_ROI0_POS_CAM0_YPOS GENMASK(31, 16) + +#define NEO_DRC_ROI0_SIZE_CAM0 0x1304 +#define NEO_DRC_ROI0_SIZE_CAM0_WIDTH GENMASK(15, 0) +#define NEO_DRC_ROI0_SIZE_CAM0_HEIGHT GENMASK(31, 16) + +#define NEO_DRC_ROI1_POS_CAM0 0x1308 +#define NEO_DRC_ROI1_POS_CAM0_XPOS GENMASK(15, 0) +#define NEO_DRC_ROI1_POS_CAM0_YPOS GENMASK(31, 16) + +#define NEO_DRC_ROI1_SIZE_CAM0 0x130c +#define NEO_DRC_ROI1_SIZE_CAM0_WIDTH GENMASK(15, 0) +#define NEO_DRC_ROI1_SIZE_CAM0_HEIGHT GENMASK(31, 16) + +#define NEO_DRC_GROI_SUM_SHIFT_CAM0 0x1310 +#define NEO_DRC_GROI_SUM_SHIFT_CAM0_SHIFT0 GENMASK(4, 0) +#define NEO_DRC_GROI_SUM_SHIFT_CAM0_SHIFT1 GENMASK(20, 16) + +#define NEO_DRC_GBL_GAIN_CAM0 0x1314 +#define NEO_DRC_GBL_GAIN_CAM0_GAIN GENMASK(15, 0) + +#define NEO_DRC_LCL_BLK_SIZE_CAM0 0x1320 +#define NEO_DRC_LCL_BLK_SIZE_CAM0_XSIZE GENMASK(15, 0) +#define NEO_DRC_LCL_BLK_SIZE_CAM0_YSIZE GENMASK(31, 16) + +#define NEO_DRC_LCL_STRETCH_CAM0 0x1324 +#define NEO_DRC_LCL_STRETCH_CAM0_STRETCH GENMASK(15, 0) +#define NEO_DRC_LCL_STRETCH_CAM0_OFFSET GENMASK(31, 16) + +#define NEO_DRC_LCL_BLK_STEPY_CAM0 0x1328 +#define NEO_DRC_LCL_BLK_STEPY_CAM0_STEP GENMASK(15, 0) + +#define NEO_DRC_LCL_BLK_STEPX_CAM0 0x132c +#define NEO_DRC_LCL_BLK_STEPX_CAM0_STEP GENMASK(15, 0) + +#define NEO_DRC_LCL_SUM_SHIFT_CAM0 0x1330 +#define NEO_DRC_LCL_SUM_SHIFT_CAM0_SHIFT GENMASK(4, 0) + +#define NEO_DRC_ALPHA_CAM0 0x1334 +#define NEO_DRC_ALPHA_CAM0_ALPHA GENMASK(8, 0) + +#define NEO_DRC_GROI0_SUM_CAM0 0x1340 + +#define NEO_DRC_GROI1_SUM_CAM0 0x1344 + +#define NEO_DRC_STAT_BLK_Y_CAM0 0x1350 +#define NEO_DRC_STAT_BLK_Y_CAM0_BLKLNE GENMASK(15, 0) +#define NEO_DRC_STAT_BLK_Y_CAM0_BLKROW GENMASK(23, 16) + +#define NEO_DRC_CURR_YFRACT_CAM0 0x1354 + +/* NR */ +#define NEO_NR_CTRL_CAM0 0x1400 +#define NEO_NR_CTRL_CAM0_DEBUG GENMASK(9, 8) +#define NEO_NR_CTRL_CAM0_ENABLE BIT(31) + +#define NEO_NR_BLEND_SCALE_CAM0 0x1404 +#define NEO_NR_BLEND_SCALE_CAM0_SCALE GENMASK(15, 0) +#define NEO_NR_BLEND_SCALE_CAM0_SHIFT GENMASK(23, 16) +#define NEO_NR_BLEND_SCALE_CAM0_GAIN GENMASK(31, 24) + +#define NEO_NR_BLEND_TH0_CAM0 0x1408 +#define NEO_NR_BLEND_TH0_CAM0_TH GENMASK(19, 0) + +#define NEO_NR_EDGECNT_CAM0 0x1410 +#define NEO_NR_EDGECNT_CAM0_EDGE_PIXELS GENMASK(23, 0) + +/* DF */ +#define NEO_DF_CTRL_CAM0 0x1440 +#define NEO_DF_CTRL_CAM0_DEBUG GENMASK(10, 8) +#define NEO_DF_CTRL_CAM0_ENABLE BIT(31) + +#define NEO_DF_TH_SCALE_CAM0 0x1444 +#define NEO_DF_TH_SCALE_CAM0_SCALE GENMASK(19, 0) + +#define NEO_DF_BLEND_SHIFT_CAM0 0x1448 +#define NEO_DF_BLEND_SHIFT_CAM0_SHIFT GENMASK(5, 0) + +#define NEO_DF_BLEND_TH0_CAM0 0x144c +#define NEO_DF_BLEND_TH0_CAM0_TH GENMASK(19, 0) + +#define NEO_DF_EDGECNT_CAM0 0x1450 +#define NEO_DF_EDGECNT_CAM0_EDGE_PIXELS GENMASK(23, 0) + +/* EE */ +#define NEO_EE_CTRL_CAM0 0x1480 +#define NEO_EE_CTRL_CAM0_DEBUG GENMASK(9, 8) +#define NEO_EE_CTRL_CAM0_ENABLE BIT(31) + +#define NEO_EE_CORING_CAM0 0x1484 +#define NEO_EE_CORING_CAM0_CORING GENMASK(19, 0) + +#define NEO_EE_CLIP_CAM0 0x1488 +#define NEO_EE_CLIP_CAM0_CLIP GENMASK(19, 0) + +#define NEO_EE_MASKGAIN_CAM0 0x148c +#define NEO_EE_MASKGAIN_CAM0_GAIN GENMASK(7, 0) + +#define NEO_EE_EDGECNT_CAM0 0x1490 +#define NEO_EE_EDGECNT_CAM0_EDGE_PIXELS GENMASK(23, 0) + +/* CCONVMED */ +#define NEO_CCONVMED_CTRL_CAM0 0x14c0 +#define NEO_CCONVMED_CTRL_CAM0_FLT GENMASK(5, 4) + +/* CAS */ +#define NEO_CAS_GAIN_CAM0 0x1504 +#define NEO_CAS_GAIN_CAM0_SCALE GENMASK(15, 0) +#define NEO_CAS_GAIN_CAM0_SHIFT GENMASK(23, 16) + +#define NEO_CAS_CORR_CAM0 0x1508 +#define NEO_CAS_CORR_CAM0_CORR GENMASK(15, 0) + +#define NEO_CAS_OFFSET_CAM0 0x150c +#define NEO_CAS_OFFSET_CAM0_OFFSET GENMASK(15, 0) + +/* PACKETIZER */ +#define NEO_PACKETIZER_CH0_CTRL_CAM0 0x1580 +#define NEO_PACKETIZER_CH0_CTRL_CAM0_OBPP GENMASK(3, 0) +#define NEO_PACKETIZER_CH0_CTRL_CAM0_RSA GENMASK(10, 8) +#define NEO_PACKETIZER_CH0_CTRL_CAM0_LSA GENMASK(14, 12) + +#define NEO_PACKETIZER_CH12_CTRL_CAM0 0x1584 +#define NEO_PACKETIZER_CH12_CTRL_CAM0_OBPP GENMASK(3, 0) +#define NEO_PACKETIZER_CH12_CTRL_CAM0_RSA GENMASK(10, 8) +#define NEO_PACKETIZER_CH12_CTRL_CAM0_LSA GENMASK(14, 12) +#define NEO_PACKETIZER_CH12_CTRL_CAM0_SUBSAMPLE GENMASK(17, 16) + +#define NEO_PACKETIZER_PACK_CTRL_CAM0 0x1588 +#define NEO_PACKETIZER_PACK_CTRL_CAM0_TYPE BIT(0) +#define NEO_PACKETIZER_PACK_CTRL_CAM0_ORDER0 GENMASK(9, 8) +#define NEO_PACKETIZER_PACK_CTRL_CAM0_ORDER1 GENMASK(11, 10) +#define NEO_PACKETIZER_PACK_CTRL_CAM0_ORDER2 GENMASK(13, 12) +#define NEO_PACKETIZER_PACK_CTRL_CAM0_A0S GENMASK(19, 16) + +/* GCM */ +#define NEO_GCM_IMAT0_CAM0 0x1600 +#define NEO_GCM_IMAT0_CAM0_R0C0 GENMASK(15, 0) +#define NEO_GCM_IMAT0_CAM0_R0C1 GENMASK(31, 16) + +#define NEO_GCM_IMAT1_CAM0 0x1604 +#define NEO_GCM_IMAT1_CAM0_R0C2 GENMASK(15, 0) + +#define NEO_GCM_IMAT2_CAM0 0x160c +#define NEO_GCM_IMAT2_CAM0_R1C0 GENMASK(15, 0) +#define NEO_GCM_IMAT2_CAM0_R1C1 GENMASK(31, 16) + +#define NEO_GCM_IMAT3_CAM0 0x1610 +#define NEO_GCM_IMAT3_CAM0_R1C2 GENMASK(15, 0) + +#define NEO_GCM_IMAT4_CAM0 0x1618 +#define NEO_GCM_IMAT4_CAM0_R2C0 GENMASK(15, 0) +#define NEO_GCM_IMAT4_CAM0_R2C1 GENMASK(31, 16) + +#define NEO_GCM_IMAT5_CAM0 0x161c +#define NEO_GCM_IMAT5_CAM0_R2C2 GENMASK(15, 0) + +#define NEO_GCM_IOFFSET0_CAM0 0x1620 +#define NEO_GCM_IOFFSET0_CAM0_OFFSET0 GENMASK(15, 0) + +#define NEO_GCM_IOFFSET1_CAM0 0x1624 +#define NEO_GCM_IOFFSET1_CAM0_OFFSET1 GENMASK(15, 0) + +#define NEO_GCM_IOFFSET2_CAM0 0x1628 +#define NEO_GCM_IOFFSET2_CAM0_OFFSET2 GENMASK(15, 0) + +#define NEO_GCM_OMAT0_CAM0 0x1630 +#define NEO_GCM_OMAT0_CAM0_R0C0 GENMASK(15, 0) +#define NEO_GCM_OMAT0_CAM0_R0C1 GENMASK(31, 16) + +#define NEO_GCM_OMAT1_CAM0 0x1634 +#define NEO_GCM_OMAT1_CAM0_R0C2 GENMASK(15, 0) + +#define NEO_GCM_OMAT2_CAM0 0x1638 +#define NEO_GCM_OMAT2_CAM0_R1C0 GENMASK(15, 0) +#define NEO_GCM_OMAT2_CAM0_R1C1 GENMASK(31, 16) + +#define NEO_GCM_OMAT3_CAM0 0x163c +#define NEO_GCM_OMAT3_CAM0_R1C2 GENMASK(15, 0) + +#define NEO_GCM_OMAT4_CAM0 0x1640 +#define NEO_GCM_OMAT4_CAM0_R2C0 GENMASK(15, 0) +#define NEO_GCM_OMAT4_CAM0_R2C1 GENMASK(31, 16) + +#define NEO_GCM_OMAT5_CAM0 0x1644 +#define NEO_GCM_OMAT5_CAM0_R2C2 GENMASK(15, 0) + +#define NEO_GCM_OOFFSET0_CAM0 0x1648 +#define NEO_GCM_OOFFSET0_CAM0_OFFSET0 GENMASK(12, 0) + +#define NEO_GCM_OOFFSET1_CAM0 0x164c +#define NEO_GCM_OOFFSET1_CAM0_OFFSET1 GENMASK(12, 0) + +#define NEO_GCM_OOFFSET2_CAM0 0x1650 +#define NEO_GCM_OOFFSET2_CAM0_OFFSET2 GENMASK(12, 0) + +#define NEO_GCM_GAMMA0_CAM0 0x1660 +#define NEO_GCM_GAMMA0_CAM0_GAMMA0 GENMASK(8, 0) +#define NEO_GCM_GAMMA0_CAM0_OFFSET0 GENMASK(27, 16) + +#define NEO_GCM_GAMMA1_CAM0 0x1664 +#define NEO_GCM_GAMMA1_CAM0_GAMMA1 GENMASK(8, 0) +#define NEO_GCM_GAMMA1_CAM0_OFFSET1 GENMASK(27, 16) + +#define NEO_GCM_GAMMA2_CAM0 0x1668 +#define NEO_GCM_GAMMA2_CAM0_GAMMA2 GENMASK(8, 0) +#define NEO_GCM_GAMMA2_CAM0_OFFSET2 GENMASK(27, 16) + +#define NEO_GCM_BLKLVL0_CTRL_CAM0 0x166c +#define NEO_GCM_BLKLVL0_CTRL_CAM0_OFFSET0 GENMASK(15, 0) +#define NEO_GCM_BLKLVL0_CTRL_CAM0_GAIN0 GENMASK(31, 16) + +#define NEO_GCM_BLKLVL1_CTRL_CAM0 0x1670 +#define NEO_GCM_BLKLVL1_CTRL_CAM0_OFFSET1 GENMASK(15, 0) +#define NEO_GCM_BLKLVL1_CTRL_CAM0_GAIN1 GENMASK(31, 16) + +#define NEO_GCM_BLKLVL2_CTRL_CAM0 0x1674 +#define NEO_GCM_BLKLVL2_CTRL_CAM0_OFFSET2 GENMASK(15, 0) +#define NEO_GCM_BLKLVL2_CTRL_CAM0_GAIN2 GENMASK(31, 16) + +#define NEO_GCM_LOWTH_CTRL01_CAM0 0x1678 +#define NEO_GCM_LOWTH_CTRL01_CAM0_THRESHOLD0 GENMASK(15, 0) +#define NEO_GCM_LOWTH_CTRL01_CAM0_THRESHOLD1 GENMASK(31, 16) + +#define NEO_GCM_LOWTH_CTRL2_CAM0 0x167c +#define NEO_GCM_LOWTH_CTRL2_CAM0_THRESHOLD2 GENMASK(15, 0) + +#define NEO_GCM_MAT_CONFG_CAM0 0x1680 +#define NEO_GCM_MAT_CONFG_CAM0_SIGN_CONFG BIT(0) + +/* AUTOFOCUS */ +#define NEO_AUTOFOCUS_ROI0_POS_CAM0 0x1700 +#define NEO_AUTOFOCUS_ROI0_POS_CAM0_XPOS GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI0_POS_CAM0_YPOS GENMASK(31, 16) + +#define NEO_AUTOFOCUS_ROI0_SIZE_CAM0 0x1704 +#define NEO_AUTOFOCUS_ROI0_SIZE_CAM0_WIDTH GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI0_SIZE_CAM0_HEIGHT GENMASK(31, 16) + +#define NEO_AUTOFOCUS_ROI1_POS_CAM0 0x1708 +#define NEO_AUTOFOCUS_ROI1_POS_CAM0_XPOS GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI1_POS_CAM0_YPOS GENMASK(31, 16) + +#define NEO_AUTOFOCUS_ROI1_SIZE_CAM0 0x170c +#define NEO_AUTOFOCUS_ROI1_SIZE_CAM0_WIDTH GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI1_SIZE_CAM0_HEIGHT GENMASK(31, 16) + +#define NEO_AUTOFOCUS_ROI2_POS_CAM0 0x1710 +#define NEO_AUTOFOCUS_ROI2_POS_CAM0_XPOS GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI2_POS_CAM0_YPOS GENMASK(31, 16) + +#define NEO_AUTOFOCUS_ROI2_SIZE_CAM0 0x1714 +#define NEO_AUTOFOCUS_ROI2_SIZE_CAM0_WIDTH GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI2_SIZE_CAM0_HEIGHT GENMASK(31, 16) + +#define NEO_AUTOFOCUS_ROI3_POS_CAM0 0x1718 +#define NEO_AUTOFOCUS_ROI3_POS_CAM0_XPOS GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI3_POS_CAM0_YPOS GENMASK(31, 16) + +#define NEO_AUTOFOCUS_ROI3_SIZE_CAM0 0x171c +#define NEO_AUTOFOCUS_ROI3_SIZE_CAM0_WIDTH GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI3_SIZE_CAM0_HEIGHT GENMASK(31, 16) + +#define NEO_AUTOFOCUS_ROI4_POS_CAM0 0x1720 +#define NEO_AUTOFOCUS_ROI4_POS_CAM0_XPOS GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI4_POS_CAM0_YPOS GENMASK(31, 16) + +#define NEO_AUTOFOCUS_ROI4_SIZE_CAM0 0x1724 +#define NEO_AUTOFOCUS_ROI4_SIZE_CAM0_WIDTH GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI4_SIZE_CAM0_HEIGHT GENMASK(31, 16) + +#define NEO_AUTOFOCUS_ROI5_POS_CAM0 0x1728 +#define NEO_AUTOFOCUS_ROI5_POS_CAM0_XPOS GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI5_POS_CAM0_YPOS GENMASK(31, 16) + +#define NEO_AUTOFOCUS_ROI5_SIZE_CAM0 0x172c +#define NEO_AUTOFOCUS_ROI5_SIZE_CAM0_WIDTH GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI5_SIZE_CAM0_HEIGHT GENMASK(31, 16) + +#define NEO_AUTOFOCUS_ROI6_POS_CAM0 0x1730 +#define NEO_AUTOFOCUS_ROI6_POS_CAM0_XPOS GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI6_POS_CAM0_YPOS GENMASK(31, 16) + +#define NEO_AUTOFOCUS_ROI6_SIZE_CAM0 0x1734 +#define NEO_AUTOFOCUS_ROI6_SIZE_CAM0_WIDTH GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI6_SIZE_CAM0_HEIGHT GENMASK(31, 16) + +#define NEO_AUTOFOCUS_ROI7_POS_CAM0 0x1738 +#define NEO_AUTOFOCUS_ROI7_POS_CAM0_XPOS GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI7_POS_CAM0_YPOS GENMASK(31, 16) + +#define NEO_AUTOFOCUS_ROI7_SIZE_CAM0 0x173c +#define NEO_AUTOFOCUS_ROI7_SIZE_CAM0_WIDTH GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI7_SIZE_CAM0_HEIGHT GENMASK(31, 16) + +#define NEO_AUTOFOCUS_ROI8_POS_CAM0 0x1740 +#define NEO_AUTOFOCUS_ROI8_POS_CAM0_XPOS GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI8_POS_CAM0_YPOS GENMASK(31, 16) + +#define NEO_AUTOFOCUS_ROI8_SIZE_CAM0 0x1744 +#define NEO_AUTOFOCUS_ROI8_SIZE_CAM0_WIDTH GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI8_SIZE_CAM0_HEIGHT GENMASK(31, 16) + +#define NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0 0x1750 +#define NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0_COEFF0 GENMASK(7, 0) +#define NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0_COEFF1 GENMASK(15, 8) +#define NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0_COEFF2 GENMASK(23, 16) +#define NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0_COEFF3 GENMASK(31, 24) + +#define NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0 0x1754 +#define NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0_COEFF4 GENMASK(7, 0) +#define NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0_COEFF5 GENMASK(15, 8) +#define NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0_COEFF6 GENMASK(23, 16) +#define NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0_COEFF7 GENMASK(31, 24) + +#define NEO_AUTOFOCUS_FIL0_COEFFS2_CAM0 0x1758 +#define NEO_AUTOFOCUS_FIL0_COEFFS2_CAM0_COEFF8 GENMASK(7, 0) + +#define NEO_AUTOFOCUS_FIL0_SHIFT_CAM0 0x175c +#define NEO_AUTOFOCUS_FIL0_SHIFT_CAM0_SHIFT GENMASK(4, 0) + +#define NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0 0x1760 +#define NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0_COEFF0 GENMASK(7, 0) +#define NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0_COEFF1 GENMASK(15, 8) +#define NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0_COEFF2 GENMASK(23, 16) +#define NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0_COEFF3 GENMASK(31, 24) + +#define NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0 0x1764 +#define NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0_COEFF4 GENMASK(7, 0) +#define NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0_COEFF5 GENMASK(15, 8) +#define NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0_COEFF6 GENMASK(23, 16) +#define NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0_COEFF7 GENMASK(31, 24) + +#define NEO_AUTOFOCUS_FIL1_COEFFS2_CAM0 0x1768 +#define NEO_AUTOFOCUS_FIL1_COEFFS2_CAM0_COEFF8 GENMASK(7, 0) + +#define NEO_AUTOFOCUS_FIL1_SHIFT_CAM0 0x176c +#define NEO_AUTOFOCUS_FIL1_SHIFT_CAM0_SHIFT GENMASK(4, 0) + +#define NEO_AUTOFOCUS_ROI0_SUM0_CAM0 0x1770 + +#define NEO_AUTOFOCUS_ROI0_SUM1_CAM0 0x1774 + +#define NEO_AUTOFOCUS_ROI1_SUM0_CAM0 0x1778 + +#define NEO_AUTOFOCUS_ROI1_SUM1_CAM0 0x177c + +#define NEO_AUTOFOCUS_ROI2_SUM0_CAM0 0x1780 + +#define NEO_AUTOFOCUS_ROI2_SUM1_CAM0 0x1784 + +#define NEO_AUTOFOCUS_ROI3_SUM0_CAM0 0x1788 + +#define NEO_AUTOFOCUS_ROI3_SUM1_CAM0 0x178c + +#define NEO_AUTOFOCUS_ROI4_SUM0_CAM0 0x1790 + +#define NEO_AUTOFOCUS_ROI4_SUM1_CAM0 0x1794 + +#define NEO_AUTOFOCUS_ROI5_SUM0_CAM0 0x1798 + +#define NEO_AUTOFOCUS_ROI5_SUM1_CAM0 0x179c + +#define NEO_AUTOFOCUS_ROI6_SUM0_CAM0 0x17a0 + +#define NEO_AUTOFOCUS_ROI6_SUM1_CAM0 0x17a4 + +#define NEO_AUTOFOCUS_ROI7_SUM0_CAM0 0x17a8 + +#define NEO_AUTOFOCUS_ROI7_SUM1_CAM0 0x17ac + +#define NEO_AUTOFOCUS_ROI8_SUM0_CAM0 0x17b0 + +#define NEO_AUTOFOCUS_ROI8_SUM1_CAM0 0x17b4 + +/* IDBG2 */ +#define NEO_IDBG2_LINE_NUM 0x1fc0 +#define NEO_IDBG2_LINE_NUM_LINE_NUM GENMASK(16, 0) + +#define NEO_IDBG2_CURR_LINE_NUM 0x1fc4 +#define NEO_IDBG2_CURR_LINE_NUM_CURR_LINE_NUM GENMASK(16, 0) +#define NEO_IDBG2_CURR_LINE_NUM_DBG_HIT BIT(31) + +#define NEO_IDBG2_IMA 0x1fc8 +#define NEO_IDBG2_IMA_ADDR GENMASK(11, 0) +#define NEO_IDBG2_IMA_NAME GENMASK(21, 16) +#define NEO_IDBG2_IMA_RDWF GENMASK(29, 28) +#define NEO_IDBG2_IMA_WDWF GENMASK(31, 30) + +#define NEO_IDBG2_IMD 0x1fcc + +#define NEO_IDBG2_DONE_STAT 0x1fd0 +#define NEO_IDBG2_DONE_STAT_AF BIT(0) +#define NEO_IDBG2_DONE_STAT_GCM BIT(1) +#define NEO_IDBG2_DONE_STAT_CAS BIT(2) +#define NEO_IDBG2_DONE_STAT_CCONVMED BIT(3) +#define NEO_IDBG2_DONE_STAT_EE BIT(4) +#define NEO_IDBG2_DONE_STAT_DF BIT(5) +#define NEO_IDBG2_DONE_STAT_DMAP BIT(6) +#define NEO_IDBG2_DONE_STAT_NR BIT(7) +#define NEO_IDBG2_DONE_STAT_DEMOSAIC BIT(8) +#define NEO_IDBG2_DONE_STAT_CSC BIT(9) +#define NEO_IDBG2_DONE_STAT_DRC BIT(10) +#define NEO_IDBG2_DONE_STAT_PKT BIT(11) +/* ALIAS */ +#define NEOISP_ALIAS_BASE (0x2000) +#define NEOISP_ALIAS_SIZE (0x150) + +#define NEO_ALIAS_ALIAS_REG0 (0x2000) +#define NEO_ALIAS_ALIAS_REG59 (0x20ec) +#define NEO_ALIAS_ALIAS_REG61 (0x20f4) +#define NEO_ALIAS_ALIAS_REG79 (0x213c) +#define NEO_ALIAS_ALIAS_REG81 (0x2144) +#define NEO_ALIAS_ALIAS_REG82 (0x2148) +#define NEO_ALIAS_ALIAS_REG83 (0x214c) + +#endif /* __NXP_NEOISP_REGS_H */ --=20 2.53.0 From nobody Sat Jun 13 02:07:57 2026 Received: from AS8PR04CU009.outbound.protection.outlook.com (mail-westeuropeazon11011050.outbound.protection.outlook.com [52.101.70.50]) (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 00C7A3FE379; Fri, 12 Jun 2026 13:21:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.70.50 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781270487; cv=fail; b=gvVrbU+8W+rj6rO2ceyBtM1IFMZtG697Np9D0BumH9H8JO47z9j0iKwxaATEdKwu2m/FIQSFdHmzOBwjEhAsIhca5ZPpdrgRcczr+70RqWkSLwfiMhW3dpPz1vfYZM61KYH+gmX859ELix8mPXPwFFCjbd9+tSJ2enOtmEZioas= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781270487; c=relaxed/simple; bh=y5VOkNTPYDIKZSzprc7bjiunGRY0wkUtO037+s225VQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=K9SLlVLfikqmZMhv7pZYEvxiJn6ZbEWgA8B4UciR5PybNbFuxgX3k6pUZ3yRIzm4+QP4kkHrnVjIjfehQXcLNDpIP0kV6J+620MS5wjZIwKEnOpNo6Pk6SMskf4O+mMCYJm++teT25vjrrShhNUw2dcYgTybetSFrN63e9g/TZ0= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com; spf=pass smtp.mailfrom=nxp.com; dkim=pass (2048-bit key) header.d=nxp.com header.i=@nxp.com header.b=LGEKKYEM; arc=fail smtp.client-ip=52.101.70.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nxp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nxp.com header.i=@nxp.com header.b="LGEKKYEM" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=gk4Ij1W1/u+63nsXzQzsagmPvgW1y9PJj16Vl8P/mmvAVNPsgVYEubvoydnyBepIHP6nPFFkdIjf+qmMnJRRYbCMywT9dGQOnbB4KpU9AC3S09AFl2QRzmZrL7CbORPj+gucXFMk8gztUZRBi+bpS9MvEKi9/sFMsHB1RBRuVdR6h4zkiQGe7F2BJwCsvEsczIky+nE2hPJQ+LLi+Ill3JXwNBqwePt1CnR9jAWiy6yqjzuM69y+e6Ba10lhqwgVUP0wvnDyRNVUSSJjfiWIX3SqaMpYBX0HPi/eqeOubiU9T2FWf1xm9cpcksbOKReer2IK5ckFjNtJNVIr1+vMzA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ys7g+P+KoB+tyLZML5PHHzf6bGVXMeHGS+LFnO3Nh/M=; b=QXVAXVCEzls6TlvfL/FqDqJi6WUwisnftSj9ODTqZ45Pgq/Qt8W6GU/xx1EIKf2oG0wzccm4hWN/1jCHqWmS/AbkXwNRcOl2W/by9CSJD02D7hcqpevBzqJzUdji7zSXnKHj6g4pKiXufDXxg+JOeonv4SCkjje53m77r4BGuO/xX7IbraUza3eBj0nBJzqbBfULkF5XBo60lTzMhAg/2JlfTVbRB6PZOPO6nogETbD4hrsNaUmKkOAfpjm+ext/mRomDYTxMtmV50nWXzusmI3nzgUmFengK+qWqNL16QEnJMJ6JDyzLm2Zyv4Zup7hj1qemXopPTa8YdGLGLRzdA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nxp.com; dmarc=pass action=none header.from=nxp.com; dkim=pass header.d=nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ys7g+P+KoB+tyLZML5PHHzf6bGVXMeHGS+LFnO3Nh/M=; b=LGEKKYEMGAJ0zFw07PwbDGlVvlXpEDVvvuFchvh+j2FnFog6H1geauuRqSSgRWR8ghljLp5GfNrrNxEitibJf7bgsmebQhS04hkU9D6oGNnK9jqDlXdnmusQka/EpmpNkNbpazLW2rdtchn0lRhDVeDiVl4QYWpAvwEFVKf3DPgaF2J4nxND1ZO6j68Xzm6Fb1sZtM9irGatEPBwmOdZ8b2yxIGKBCz5TFCQt2O0X+iXOZ7O2fBNBlLDV+z0jWif0pmcJtQ+tBFcJO3yBs3HnmOB7pxxRhcIn2+ulDkTyLzi6QpY/6JMdkIgdfkgc0vIcL9ErH4Q3ORWolFcyI+6ig== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from PA6PR04MB11910.eurprd04.prod.outlook.com (2603:10a6:102:516::16) by DB9PR04MB8203.eurprd04.prod.outlook.com (2603:10a6:10:242::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.113.14; Fri, 12 Jun 2026 13:21:00 +0000 Received: from PA6PR04MB11910.eurprd04.prod.outlook.com ([fe80::d3f0:3c24:f717:4989]) by PA6PR04MB11910.eurprd04.prod.outlook.com ([fe80::d3f0:3c24:f717:4989%4]) with mapi id 15.21.0113.013; Fri, 12 Jun 2026 13:21:00 +0000 From: Antoine Bouyer To: julien.vuillaumier@nxp.com, alexi.birlinger@nxp.com, daniel.baluta@nxp.com, peng.fan@nxp.com, frank.li@nxp.com, jacopo.mondi@ideasonboard.com, laurent.pinchart@ideasonboard.com, mchehab@kernel.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, michael.riesch@collabora.com, anthony.mcgivern@arm.com Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, imx@lists.linux.dev, ai.luthra@ideasonboard.com, paul.elder@ideasonboard.com, geert@linux-m68k.org, sakari.ailus@linux.intel.com, hverkuil+cisco@kernel.org, Antoine Bouyer Subject: [PATCH v3 7/8] media: platform: neoisp: Add debugfs support Date: Fri, 12 Jun 2026 15:20:38 +0200 Message-ID: <20260612132039.2089051-8-antoine.bouyer@nxp.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260612132039.2089051-1-antoine.bouyer@nxp.com> References: <20260612132039.2089051-1-antoine.bouyer@nxp.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: FR4P281CA0416.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:d0::19) To PA6PR04MB11910.eurprd04.prod.outlook.com (2603:10a6:102:516::16) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PA6PR04MB11910:EE_|DB9PR04MB8203:EE_ X-MS-Office365-Filtering-Correlation-Id: 207c4062-b9dd-42ad-0caf-08dec88571be X-LD-Processed: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635,ExtAddr X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|19092799006|376014|7416014|366016|23010399003|10086099003|921020|6133799003|18092099006|18002099003|22082099003|3023799007|11063799006|56012099006; X-Microsoft-Antispam-Message-Info: Uf/TjQDDlBDtJRuNU7ggCxELrRxeE4V/kNZ16SCSFolnRb+tdU63xlc9eHuIxBaAV3AWcMhpolxqQm0gMdlwSZ1gv02gRpsDFGc3MDk6r5w8Ac40S9ifIKEZXEpZP/vYiH3cI6JTDzip5vdQdlGQyMK77hu5dfJGjcCgOc4mDkh8WshMz6fw8LIbATObAf5zd/G1b+gKoBVrCHnFOshz63n5Pu8dZxbfwaFQklfAppsdV2g0/pxCcJl1QhYf7xihsuFDqPFtoayIuJgJii4qRe+WYTxAnpfQCwIIhiAj6ZcxszNRNNyKMfze2D0qrl4p0maM9dljGEL9SfSG9lUN3LZYCxZDk6y0cOaI59WrE4Y0HIlabRrWpVyJEGv84BZ9uZbub7036uDFqWQDmeFesy6N+L0Qo30DNTINzRk3hpfO3+XYMELWN+FODuHDLQ8EO4ZNN9GnUg9ygvXngkKb0H44HZ+UGfm7OmStt7dtYxYZqUkXmwpTE1i6S6YFpSVU7FqmirtZ4rRmVtpR02A5jczaBtNhRGOvcMP2XbgrbLeOrINlZ0LVo1EpeV14EoOCYxIbvN32ZBSAW8vicjxRkViNF4JuSpZYupFo3J9/JL/ciJCP43qfZ2z3l9sctpaGkxhQygfK3XMVzejaC29+nJW0GKuvCaAzPJltmEwxQq3G0Tp7ElHNx9qs9yKRbMDu9LGYb7oGIsBDhEIlCivVPCNFsNZJnsgmryFAzLrXw/o= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PA6PR04MB11910.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(1800799024)(19092799006)(376014)(7416014)(366016)(23010399003)(10086099003)(921020)(6133799003)(18092099006)(18002099003)(22082099003)(3023799007)(11063799006)(56012099006);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?S+sLosfot5jCL8sIZBAJJYO31FF0YVKBMoSeeFooCXs2BjGY1NsltgQUHK+a?= =?us-ascii?Q?ABtMyzNXFxMwY9IYSnIHluOQMC51REh481vJscgVg0wRAS0iMuXS8TdeMv0/?= =?us-ascii?Q?kcvsXY9ozV0AQV+eyZq01SfM/mwjfSgyzy+2Hfsm6eYfg/6IZMftxX/VpmdY?= =?us-ascii?Q?PbYmcQiHVVmOCmM7KaL3T2p64W+5ESujU4WTgySZPbF/cHNCWLVwOD0Vbum/?= =?us-ascii?Q?iW4vmf3QGq0X91e8wKK0EANgfWXJo9wMELJONEiuiP+SZDnC4e7J6p06t5rj?= =?us-ascii?Q?smscbrpAdfZitjy2XoveBsx4AC5rmQeFNgYRT5C8cPQ9vSSsGdcRMbbyAOOF?= =?us-ascii?Q?mAyLps+tHR1xJSZu16hOILvyD8nDnSd+q9fYW5FMVD3pS5or3hbaObgwzy2F?= =?us-ascii?Q?8qm9a/KLGoodoTqF51HELY07NqyP/hyPoeD+BZCxZNPv6C90ZnDTGpwk19+7?= =?us-ascii?Q?U3VSszvMhfM5EzmkGfiPJFS4M3doqcTrHVMEvV1vPNycI5wOQmeFh6ZzqwMy?= =?us-ascii?Q?Tfiwd507kntRun0LLjo4cByhJ4aWJhsEq5ENzKKBfBXe5GytIUGYrXVEle5U?= =?us-ascii?Q?UbhqM9hBHJy+4giN88Buimo9vDKMVljmlmiy3dm45N9JxGpc9zb+IZCw6Kpy?= =?us-ascii?Q?JtkRAAvmq6LclDy73ndDJxRtOJQQYiqQNgwDISs1EuGRmu3iwJG++OScysBu?= =?us-ascii?Q?GHeviRaMgYEh4RR63BgJy8qzhMV1JW37d3aMmcGcG3xuN8oL1gICZgHlSUVT?= =?us-ascii?Q?08z8Zz82bC0Zbtta2HvkI0HASG96L6TERu+7v8XKjdJjmhLk+4kG5YauNnS0?= =?us-ascii?Q?TLqdbPUNS7ZHoWmPwD4q1X8Sw9utAldHUOuRwLvn7PZ/0VhP3mrp5jjfUdAx?= =?us-ascii?Q?7QQus/515AXoFmNvwCTwrbqzXEHqUv4sV9xCig1lQ8KBFztG66/AO3d86yz/?= =?us-ascii?Q?IMYvLVVBEFo20dkpH2YeHGyHRjB/8VE3RHT/Zvqq5zX6ojHLoPXo+oi3lnwm?= =?us-ascii?Q?cegevs9DsuIG9avMk/SIGCsibTGHZD3gel7t++QXqAMy1fVT8BZ4SXHROS9Z?= =?us-ascii?Q?no5vlldpX2VGUvD3dOFlknQZU15p9yd41WOF1df+SUfrow6LOG4CZFhMNS5T?= =?us-ascii?Q?Yvq9TLTpmBjVS/fMkjkRH27h9bzeZ/dSfVweEs8gxvnV0S0uig5P36lQzQ/+?= =?us-ascii?Q?c1iOiMM/9snszqOiEPjzWJ/SEI8d/FFqF/YlVQU1kqhNR8x88K8aTg28bhRn?= =?us-ascii?Q?GdM/KD8xspYPxsskCt/Io6AmNIAeNy5Py4srGhxpwHjg0cleqOCMSGvOOCzU?= =?us-ascii?Q?PNAn85AFQePkeGYLUqld6hFIgeO+SUpwHRvDCpIslR0IxzyJMjRugGsf1+X8?= =?us-ascii?Q?PnfLFNehPZ2sudW6uacNL8DLY5eBjzp+bpIMxfnTdqqkR6JgztI3A0FqZZiQ?= =?us-ascii?Q?mxfilDaXt2/SyMNVJSjHa3iKHYnuRp+CjbZkeYL2+gWoc8In7hnukW0s6L09?= =?us-ascii?Q?WXbLm+mNjN83i+BAGXinzJ7PtZnKa4S/foIombiJdfuHnoCWKlkryCjvH+zd?= =?us-ascii?Q?3WvuF872zIOsUx1NB5tLXIHEqedsnwWcL5yG0kChXVJDIgFs+lP4i+Iu4f8N?= =?us-ascii?Q?iitI/l0kLbZaRy6Bs5XJLHdvx6ih3LLbxPlQQn76WW1ykF+MoD7pLQ/dbbY+?= =?us-ascii?Q?yI1hAdi+9gVMTxX5/Akj/GdXOsjTK/BGZuwXw9wGGuN+N8wXaboQdCdlyMqK?= =?us-ascii?Q?4WkbKuR3Aw=3D=3D?= X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 207c4062-b9dd-42ad-0caf-08dec88571be X-MS-Exchange-CrossTenant-AuthSource: PA6PR04MB11910.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Jun 2026 13:20:59.9691 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: aVpcPK/hPxSpr1DDV27Hf7v0o/kjvy7bw6vY6AofeGzlahqZP0H657Rl1pSxiRO8syf6B4SCsoup/yQagtEqVw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB9PR04MB8203 Content-Type: text/plain; charset="utf-8" Add debugfs entries to dump ISP registers, and some internal memory regions used to store Vignetting, DRC global and DRC local coefficients. Debug mode is activated with the `enable_debugfs` module's parameter, to avoid runtime suspend which blocks register access when IP is not active, so we can capture an ISP snapshot after a frame is decoded. Signed-off-by: Antoine Bouyer --- drivers/media/platform/nxp/neoisp/Makefile | 2 + drivers/media/platform/nxp/neoisp/neoisp.h | 16 + .../platform/nxp/neoisp/neoisp_debugfs.c | 495 ++++++++++++++++++ .../media/platform/nxp/neoisp/neoisp_main.c | 19 + 4 files changed, 532 insertions(+) create mode 100644 drivers/media/platform/nxp/neoisp/neoisp_debugfs.c diff --git a/drivers/media/platform/nxp/neoisp/Makefile b/drivers/media/pla= tform/nxp/neoisp/Makefile index 7652df785e98..c68e216980dc 100644 --- a/drivers/media/platform/nxp/neoisp/Makefile +++ b/drivers/media/platform/nxp/neoisp/Makefile @@ -4,3 +4,5 @@ obj-$(CONFIG_VIDEO_NXP_NEOISP) +=3D neoisp.o =20 neoisp-objs :=3D neoisp_ctx.o \ neoisp_main.o + +neoisp-$(CONFIG_DEBUG_FS) +=3D neoisp_debugfs.o diff --git a/drivers/media/platform/nxp/neoisp/neoisp.h b/drivers/media/pla= tform/nxp/neoisp/neoisp.h index a777625974fe..d8ddf057eb4d 100644 --- a/drivers/media/platform/nxp/neoisp/neoisp.h +++ b/drivers/media/platform/nxp/neoisp/neoisp.h @@ -9,6 +9,7 @@ #define __NXP_NEOISP_H =20 #include +#include #include #include #include @@ -223,8 +224,23 @@ struct neoisp_dev_s { dma_addr_t dummy_dma; u32 dummy_size; struct neoisp_context_s *context; + struct dentry *debugfs_entry; + struct debugfs_regset32 *regset; }; =20 +#if IS_ENABLED(CONFIG_DEBUG_FS) +void neoisp_debugfs_init(struct neoisp_dev_s *neoispd); +void neoisp_debugfs_exit(struct neoisp_dev_s *neoispd); +#else +static inline void neoisp_debugfs_init(struct neoisp_dev_s *neoispd) +{ +} + +static inline void neoisp_debugfs_exit(struct neoisp_dev_s *neoispd) +{ +} +#endif + static inline int neoisp_node_link_is_enabled(struct neoisp_node_s *node) { return (node->intf_link->flags & MEDIA_LNK_FL_ENABLED); diff --git a/drivers/media/platform/nxp/neoisp/neoisp_debugfs.c b/drivers/m= edia/platform/nxp/neoisp/neoisp_debugfs.c new file mode 100644 index 000000000000..e730569184b3 --- /dev/null +++ b/drivers/media/platform/nxp/neoisp/neoisp_debugfs.c @@ -0,0 +1,495 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * NEOISP debugfs definition + * + * Copyright 2024-2026 NXP + */ + +#include + +#include "neoisp.h" +#include "neoisp_ctx.h" +#include "neoisp_regs.h" + +#define NEOISP_DFS_REG(reg) {.name =3D #reg, .offset =3D reg} + +static const struct debugfs_reg32 neoisp_dfs_regs[] =3D { + NEOISP_DFS_REG(NEO_PIPE_CONF_SOFT_RESET), + NEOISP_DFS_REG(NEO_PIPE_CONF_BUS_TXPARAM), + NEOISP_DFS_REG(NEO_PIPE_CONF_REG_XFR_DIS), + NEOISP_DFS_REG(NEO_PIPE_CONF_CSI_CTRL), + NEOISP_DFS_REG(NEO_PIPE_CONF_FRAME_NUM), + NEOISP_DFS_REG(NEO_PIPE_CONF_REG_SHD_CTRL), + NEOISP_DFS_REG(NEO_PIPE_CONF_REG_SHD_CMD), + NEOISP_DFS_REG(NEO_PIPE_CONF_TRIG_CAM0), + NEOISP_DFS_REG(NEO_PIPE_CONF_INT_EN0), + NEOISP_DFS_REG(NEO_PIPE_CONF_INT_STAT0), + NEOISP_DFS_REG(NEO_PIPE_CONF_CSI_STAT), + NEOISP_DFS_REG(NEO_PIPE_CONF_IMG_CONF_CAM0), + NEOISP_DFS_REG(NEO_PIPE_CONF_IMG_SIZE_CAM0), + NEOISP_DFS_REG(NEO_PIPE_CONF_IMG0_IN_ADDR_CAM0), + NEOISP_DFS_REG(NEO_PIPE_CONF_IMG1_IN_ADDR_CAM0), + NEOISP_DFS_REG(NEO_PIPE_CONF_OUTCH0_ADDR_CAM0), + NEOISP_DFS_REG(NEO_PIPE_CONF_OUTCH1_ADDR_CAM0), + NEOISP_DFS_REG(NEO_PIPE_CONF_OUTIR_ADDR_CAM0), + NEOISP_DFS_REG(NEO_PIPE_CONF_IMG0_IN_LS_CAM0), + NEOISP_DFS_REG(NEO_PIPE_CONF_IMG1_IN_LS_CAM0), + NEOISP_DFS_REG(NEO_PIPE_CONF_OUTCH0_LS_CAM0), + NEOISP_DFS_REG(NEO_PIPE_CONF_OUTCH1_LS_CAM0), + NEOISP_DFS_REG(NEO_PIPE_CONF_OUTIR_LS_CAM0), + NEOISP_DFS_REG(NEO_PIPE_CONF_SKIP_CTRL0), + NEOISP_DFS_REG(NEO_HC_CTRL_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS0_CTRL_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS0_KNEE_POINT1_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS0_KNEE_POINT2_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS0_KNEE_POINT3_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS0_KNEE_POINT4_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS0_KNEE_OFFSET0_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS0_KNEE_OFFSET1_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS0_KNEE_OFFSET2_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS0_KNEE_OFFSET3_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS0_KNEE_OFFSET4_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS0_KNEE_RATIO01_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS0_KNEE_RATIO23_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS0_KNEE_RATIO4_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS0_KNEE_NPOINT0_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS0_KNEE_NPOINT1_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS0_KNEE_NPOINT2_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS0_KNEE_NPOINT3_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS0_KNEE_NPOINT4_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS1_CTRL_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS1_KNEE_POINT1_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS1_KNEE_POINT2_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS1_KNEE_POINT3_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS1_KNEE_POINT4_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS1_KNEE_OFFSET0_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS1_KNEE_OFFSET1_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS1_KNEE_OFFSET2_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS1_KNEE_OFFSET3_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS1_KNEE_OFFSET4_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS1_KNEE_RATIO01_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS1_KNEE_RATIO23_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS1_KNEE_RATIO4_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS1_KNEE_NPOINT0_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS1_KNEE_NPOINT1_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS1_KNEE_NPOINT2_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS1_KNEE_NPOINT3_CAM0), + NEOISP_DFS_REG(NEO_HDR_DECOMPRESS1_KNEE_NPOINT4_CAM0), + NEOISP_DFS_REG(NEO_OB_WB0_CTRL_CAM0), + NEOISP_DFS_REG(NEO_OB_WB0_R_CTRL_CAM0), + NEOISP_DFS_REG(NEO_OB_WB0_GR_CTRL_CAM0), + NEOISP_DFS_REG(NEO_OB_WB0_GB_CTRL_CAM0), + NEOISP_DFS_REG(NEO_OB_WB0_B_CTRL_CAM0), + NEOISP_DFS_REG(NEO_OB_WB1_CTRL_CAM0), + NEOISP_DFS_REG(NEO_OB_WB1_R_CTRL_CAM0), + NEOISP_DFS_REG(NEO_OB_WB1_GR_CTRL_CAM0), + NEOISP_DFS_REG(NEO_OB_WB1_GB_CTRL_CAM0), + NEOISP_DFS_REG(NEO_OB_WB1_B_CTRL_CAM0), + NEOISP_DFS_REG(NEO_OB_WB2_CTRL_CAM0), + NEOISP_DFS_REG(NEO_OB_WB2_R_CTRL_CAM0), + NEOISP_DFS_REG(NEO_OB_WB2_GR_CTRL_CAM0), + NEOISP_DFS_REG(NEO_OB_WB2_GB_CTRL_CAM0), + NEOISP_DFS_REG(NEO_OB_WB2_B_CTRL_CAM0), + NEOISP_DFS_REG(NEO_HDR_MERGE_CTRL_CAM0), + NEOISP_DFS_REG(NEO_HDR_MERGE_GAIN_OFFSET_CAM0), + NEOISP_DFS_REG(NEO_HDR_MERGE_GAIN_SCALE_CAM0), + NEOISP_DFS_REG(NEO_HDR_MERGE_GAIN_SHIFT_CAM0), + NEOISP_DFS_REG(NEO_HDR_MERGE_LUMA_TH_CAM0), + NEOISP_DFS_REG(NEO_HDR_MERGE_LUMA_SCALE_CAM0), + NEOISP_DFS_REG(NEO_HDR_MERGE_DOWNSCALE_CAM0), + NEOISP_DFS_REG(NEO_HDR_MERGE_UPSCALE_CAM0), + NEOISP_DFS_REG(NEO_HDR_MERGE_POST_SCALE_CAM0), + NEOISP_DFS_REG(NEO_HDR_MERGE_S_GAIN_OFFSET_CAM0), + NEOISP_DFS_REG(NEO_HDR_MERGE_S_GAIN_SCALE_CAM0), + NEOISP_DFS_REG(NEO_HDR_MERGE_S_GAIN_SHIFT_CAM0), + NEOISP_DFS_REG(NEO_HDR_MERGE_S_LUMA_TH_CAM0), + NEOISP_DFS_REG(NEO_HDR_MERGE_S_LUMA_SCALE_CAM0), + NEOISP_DFS_REG(NEO_HDR_MERGE_S_DOWNSCALE_CAM0), + NEOISP_DFS_REG(NEO_HDR_MERGE_S_UPSCALE_CAM0), + NEOISP_DFS_REG(NEO_HDR_MERGE_S_POST_SCALE_CAM0), + NEOISP_DFS_REG(NEO_HDR_MERGE_S_LINE_NUM_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CTRL_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_ROI_POS_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_ROI_SIZE_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_REDGAIN_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_BLUEGAIN_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_POINT1_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_POINT2_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_HOFFSET_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_VOFFSET_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_POINT1_SLOPE_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_POINT2_SLOPE_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_LUMA_TH_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CSC_MAT0_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CSC_MAT1_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CSC_MAT2_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CSC_MAT3_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CSC_MAT4_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_R_GR_OFFSET_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_GB_B_OFFSET_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CNT_WHITE_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_SUMRL_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_SUMRH_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_SUMGL_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_SUMGH_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_SUMBL_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_SUMBH_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_SUMRGL_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_SUMRGH_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_SUMBGL_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_SUMBGH_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_STAT_BLK_SIZE0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_STAT_CURR_BLK_Y0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI0_POS_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI0_PIXCNT_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI0_SUMRED_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI0_SUMGREEN_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI0_SUMBLUE_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI1_POS_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI1_PIXCNT_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI1_SUMRED_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI1_SUMGREEN_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI1_SUMBLUE_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI2_POS_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI2_PIXCNT_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI2_SUMRED_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI2_SUMGREEN_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI2_SUMBLUE_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI3_POS_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI3_PIXCNT_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI3_SUMRED_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI3_SUMGREEN_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI3_SUMBLUE_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI4_POS_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI4_PIXCNT_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI4_SUMRED_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI4_SUMGREEN_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI4_SUMBLUE_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI5_POS_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI5_PIXCNT_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI5_SUMRED_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI5_SUMGREEN_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI5_SUMBLUE_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI6_POS_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI6_PIXCNT_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI6_SUMRED_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI6_SUMGREEN_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI6_SUMBLUE_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI7_POS_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI7_PIXCNT_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI7_SUMRED_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI7_SUMGREEN_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI7_SUMBLUE_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI8_POS_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI8_PIXCNT_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI8_SUMRED_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI8_SUMGREEN_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI8_SUMBLUE_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI9_POS_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI9_PIXCNT_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI9_SUMRED_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI9_SUMGREEN_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_CROI9_SUMBLUE_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_GR_AVG_IN_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_GB_AVG_IN_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_GR_GB_CNT_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_GR_SUM_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_GB_SUM_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_GR2_SUM_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_GB2_SUM_CAM0), + NEOISP_DFS_REG(NEO_COLOR_TEMP_GRGB_SUM_CAM0), + NEOISP_DFS_REG(NEO_RGBIR_CTRL_CAM0), + NEOISP_DFS_REG(NEO_RGBIR_CCM0_CAM0), + NEOISP_DFS_REG(NEO_RGBIR_CCM1_CAM0), + NEOISP_DFS_REG(NEO_RGBIR_CCM2_CAM0), + NEOISP_DFS_REG(NEO_RGBIR_CCM0_TH_CAM0), + NEOISP_DFS_REG(NEO_RGBIR_CCM1_TH_CAM0), + NEOISP_DFS_REG(NEO_RGBIR_CCM2_TH_CAM0), + NEOISP_DFS_REG(NEO_RGBIR_ROI0_POS_CAM0), + NEOISP_DFS_REG(NEO_RGBIR_ROI0_SIZE_CAM0), + NEOISP_DFS_REG(NEO_RGBIR_ROI1_POS_CAM0), + NEOISP_DFS_REG(NEO_RGBIR_ROI1_SIZE_CAM0), + NEOISP_DFS_REG(NEO_RGBIR_HIST0_CTRL_CAM0), + NEOISP_DFS_REG(NEO_RGBIR_HIST0_SCALE_CAM0), + NEOISP_DFS_REG(NEO_RGBIR_HIST1_CTRL_CAM0), + NEOISP_DFS_REG(NEO_RGBIR_HIST1_SCALE_CAM0), + NEOISP_DFS_REG(NEO_STAT_ROI0_POS_CAM0), + NEOISP_DFS_REG(NEO_STAT_ROI0_SIZE_CAM0), + NEOISP_DFS_REG(NEO_STAT_ROI1_POS_CAM0), + NEOISP_DFS_REG(NEO_STAT_ROI1_SIZE_CAM0), + NEOISP_DFS_REG(NEO_STAT_HIST0_CTRL_CAM0), + NEOISP_DFS_REG(NEO_STAT_HIST0_SCALE_CAM0), + NEOISP_DFS_REG(NEO_STAT_HIST1_CTRL_CAM0), + NEOISP_DFS_REG(NEO_STAT_HIST1_SCALE_CAM0), + NEOISP_DFS_REG(NEO_STAT_HIST2_CTRL_CAM0), + NEOISP_DFS_REG(NEO_STAT_HIST2_SCALE_CAM0), + NEOISP_DFS_REG(NEO_STAT_HIST3_CTRL_CAM0), + NEOISP_DFS_REG(NEO_STAT_HIST3_SCALE_CAM0), + NEOISP_DFS_REG(NEO_IR_COMPRESS_CTRL_CAM0), + NEOISP_DFS_REG(NEO_IR_COMPRESS_KNEE_POINT1_CAM0), + NEOISP_DFS_REG(NEO_IR_COMPRESS_KNEE_POINT2_CAM0), + NEOISP_DFS_REG(NEO_IR_COMPRESS_KNEE_POINT3_CAM0), + NEOISP_DFS_REG(NEO_IR_COMPRESS_KNEE_POINT4_CAM0), + NEOISP_DFS_REG(NEO_IR_COMPRESS_KNEE_OFFSET0_CAM0), + NEOISP_DFS_REG(NEO_IR_COMPRESS_KNEE_OFFSET1_CAM0), + NEOISP_DFS_REG(NEO_IR_COMPRESS_KNEE_OFFSET2_CAM0), + NEOISP_DFS_REG(NEO_IR_COMPRESS_KNEE_OFFSET3_CAM0), + NEOISP_DFS_REG(NEO_IR_COMPRESS_KNEE_OFFSET4_CAM0), + NEOISP_DFS_REG(NEO_IR_COMPRESS_KNEE_RATIO01_CAM0), + NEOISP_DFS_REG(NEO_IR_COMPRESS_KNEE_RATIO23_CAM0), + NEOISP_DFS_REG(NEO_IR_COMPRESS_KNEE_RATIO4_CAM0), + NEOISP_DFS_REG(NEO_IR_COMPRESS_KNEE_NPOINT0_CAM0), + NEOISP_DFS_REG(NEO_IR_COMPRESS_KNEE_NPOINT1_CAM0), + NEOISP_DFS_REG(NEO_IR_COMPRESS_KNEE_NPOINT2_CAM0), + NEOISP_DFS_REG(NEO_IR_COMPRESS_KNEE_NPOINT3_CAM0), + NEOISP_DFS_REG(NEO_IR_COMPRESS_KNEE_NPOINT4_CAM0), + NEOISP_DFS_REG(NEO_BNR_CTRL_CAM0), + NEOISP_DFS_REG(NEO_BNR_YPEAK_CAM0), + NEOISP_DFS_REG(NEO_BNR_YEDGE_TH0_CAM0), + NEOISP_DFS_REG(NEO_BNR_YEDGE_SCALE_CAM0), + NEOISP_DFS_REG(NEO_BNR_YEDGES_TH0_CAM0), + NEOISP_DFS_REG(NEO_BNR_YEDGES_SCALE_CAM0), + NEOISP_DFS_REG(NEO_BNR_YEDGEA_TH0_CAM0), + NEOISP_DFS_REG(NEO_BNR_YEDGEA_SCALE_CAM0), + NEOISP_DFS_REG(NEO_BNR_YLUMA_X_TH0_CAM0), + NEOISP_DFS_REG(NEO_BNR_YLUMA_Y_TH_CAM0), + NEOISP_DFS_REG(NEO_BNR_YLUMA_SCALE_CAM0), + NEOISP_DFS_REG(NEO_BNR_YALPHA_GAIN_CAM0), + NEOISP_DFS_REG(NEO_BNR_CPEAK_CAM0), + NEOISP_DFS_REG(NEO_BNR_CEDGE_TH0_CAM0), + NEOISP_DFS_REG(NEO_BNR_CEDGE_SCALE_CAM0), + NEOISP_DFS_REG(NEO_BNR_CEDGES_TH0_CAM0), + NEOISP_DFS_REG(NEO_BNR_CEDGES_SCALE_CAM0), + NEOISP_DFS_REG(NEO_BNR_CEDGEA_TH0_CAM0), + NEOISP_DFS_REG(NEO_BNR_CEDGEA_SCALE_CAM0), + NEOISP_DFS_REG(NEO_BNR_CLUMA_X_TH0_CAM0), + NEOISP_DFS_REG(NEO_BNR_CLUMA_Y_TH_CAM0), + NEOISP_DFS_REG(NEO_BNR_CLUMA_SCALE_CAM0), + NEOISP_DFS_REG(NEO_BNR_CALPHA_GAIN_CAM0), + NEOISP_DFS_REG(NEO_BNR_EDGE_STAT_CAM0), + NEOISP_DFS_REG(NEO_BNR_EDGES_STAT_CAM0), + NEOISP_DFS_REG(NEO_BNR_STRETCH_CAM0), + NEOISP_DFS_REG(NEO_VIGNETTING_CTRL_CAM0), + NEOISP_DFS_REG(NEO_VIGNETTING_BLK_CONF_CAM0), + NEOISP_DFS_REG(NEO_VIGNETTING_BLK_SIZE_CAM0), + NEOISP_DFS_REG(NEO_VIGNETTING_BLK_STEPY_CAM0), + NEOISP_DFS_REG(NEO_VIGNETTING_BLK_STEPX_CAM0), + NEOISP_DFS_REG(NEO_VIGNETTING_BLK_C_LINE_CAM0), + NEOISP_DFS_REG(NEO_VIGNETTING_BLK_C_ROW_CAM0), + NEOISP_DFS_REG(NEO_VIGNETTING_BLK_C_FRACY_CAM0), + NEOISP_DFS_REG(NEO_IDBG1_LINE_NUM), + NEOISP_DFS_REG(NEO_IDBG1_CURR_LINE_NUM), + NEOISP_DFS_REG(NEO_IDBG1_IMA), + NEOISP_DFS_REG(NEO_IDBG1_IMD), + NEOISP_DFS_REG(NEO_IDBG1_DONE_STAT), + NEOISP_DFS_REG(NEO_DEMOSAIC_CTRL_CAM0), + NEOISP_DFS_REG(NEO_DEMOSAIC_ACTIVITY_CTL_CAM0), + NEOISP_DFS_REG(NEO_DEMOSAIC_DYNAMICS_CTL0_CAM0), + NEOISP_DFS_REG(NEO_DEMOSAIC_DYNAMICS_CTL2_CAM0), + NEOISP_DFS_REG(NEO_RGB_TO_YUV_GAIN_CTRL_CAM0), + NEOISP_DFS_REG(NEO_RGB_TO_YUV_MAT0_CAM0), + NEOISP_DFS_REG(NEO_RGB_TO_YUV_MAT1_CAM0), + NEOISP_DFS_REG(NEO_RGB_TO_YUV_MAT2_CAM0), + NEOISP_DFS_REG(NEO_RGB_TO_YUV_MAT3_CAM0), + NEOISP_DFS_REG(NEO_RGB_TO_YUV_MAT4_CAM0), + NEOISP_DFS_REG(NEO_RGB_TO_YUV_MAT5_CAM0), + NEOISP_DFS_REG(NEO_RGB_TO_YUV_OFFSET0_CAM0), + NEOISP_DFS_REG(NEO_RGB_TO_YUV_OFFSET1_CAM0), + NEOISP_DFS_REG(NEO_RGB_TO_YUV_OFFSET2_CAM0), + NEOISP_DFS_REG(NEO_DRC_ROI0_POS_CAM0), + NEOISP_DFS_REG(NEO_DRC_ROI0_SIZE_CAM0), + NEOISP_DFS_REG(NEO_DRC_ROI1_POS_CAM0), + NEOISP_DFS_REG(NEO_DRC_ROI1_SIZE_CAM0), + NEOISP_DFS_REG(NEO_DRC_GROI_SUM_SHIFT_CAM0), + NEOISP_DFS_REG(NEO_DRC_GBL_GAIN_CAM0), + NEOISP_DFS_REG(NEO_DRC_LCL_BLK_SIZE_CAM0), + NEOISP_DFS_REG(NEO_DRC_LCL_STRETCH_CAM0), + NEOISP_DFS_REG(NEO_DRC_LCL_BLK_STEPY_CAM0), + NEOISP_DFS_REG(NEO_DRC_LCL_BLK_STEPX_CAM0), + NEOISP_DFS_REG(NEO_DRC_LCL_SUM_SHIFT_CAM0), + NEOISP_DFS_REG(NEO_DRC_ALPHA_CAM0), + NEOISP_DFS_REG(NEO_DRC_GROI0_SUM_CAM0), + NEOISP_DFS_REG(NEO_DRC_GROI1_SUM_CAM0), + NEOISP_DFS_REG(NEO_DRC_STAT_BLK_Y_CAM0), + NEOISP_DFS_REG(NEO_DRC_CURR_YFRACT_CAM0), + NEOISP_DFS_REG(NEO_NR_CTRL_CAM0), + NEOISP_DFS_REG(NEO_NR_BLEND_SCALE_CAM0), + NEOISP_DFS_REG(NEO_NR_BLEND_TH0_CAM0), + NEOISP_DFS_REG(NEO_NR_EDGECNT_CAM0), + NEOISP_DFS_REG(NEO_DF_CTRL_CAM0), + NEOISP_DFS_REG(NEO_DF_TH_SCALE_CAM0), + NEOISP_DFS_REG(NEO_DF_BLEND_SHIFT_CAM0), + NEOISP_DFS_REG(NEO_DF_BLEND_TH0_CAM0), + NEOISP_DFS_REG(NEO_DF_EDGECNT_CAM0), + NEOISP_DFS_REG(NEO_EE_CTRL_CAM0), + NEOISP_DFS_REG(NEO_EE_CORING_CAM0), + NEOISP_DFS_REG(NEO_EE_CLIP_CAM0), + NEOISP_DFS_REG(NEO_EE_MASKGAIN_CAM0), + NEOISP_DFS_REG(NEO_EE_EDGECNT_CAM0), + NEOISP_DFS_REG(NEO_CCONVMED_CTRL_CAM0), + NEOISP_DFS_REG(NEO_CAS_GAIN_CAM0), + NEOISP_DFS_REG(NEO_CAS_CORR_CAM0), + NEOISP_DFS_REG(NEO_CAS_OFFSET_CAM0), + NEOISP_DFS_REG(NEO_PACKETIZER_CH0_CTRL_CAM0), + NEOISP_DFS_REG(NEO_PACKETIZER_CH12_CTRL_CAM0), + NEOISP_DFS_REG(NEO_PACKETIZER_PACK_CTRL_CAM0), + NEOISP_DFS_REG(NEO_GCM_IMAT0_CAM0), + NEOISP_DFS_REG(NEO_GCM_IMAT1_CAM0), + NEOISP_DFS_REG(NEO_GCM_IMAT2_CAM0), + NEOISP_DFS_REG(NEO_GCM_IMAT3_CAM0), + NEOISP_DFS_REG(NEO_GCM_IMAT4_CAM0), + NEOISP_DFS_REG(NEO_GCM_IMAT5_CAM0), + NEOISP_DFS_REG(NEO_GCM_IOFFSET0_CAM0), + NEOISP_DFS_REG(NEO_GCM_IOFFSET1_CAM0), + NEOISP_DFS_REG(NEO_GCM_IOFFSET2_CAM0), + NEOISP_DFS_REG(NEO_GCM_OMAT0_CAM0), + NEOISP_DFS_REG(NEO_GCM_OMAT1_CAM0), + NEOISP_DFS_REG(NEO_GCM_OMAT2_CAM0), + NEOISP_DFS_REG(NEO_GCM_OMAT3_CAM0), + NEOISP_DFS_REG(NEO_GCM_OMAT4_CAM0), + NEOISP_DFS_REG(NEO_GCM_OMAT5_CAM0), + NEOISP_DFS_REG(NEO_GCM_OOFFSET0_CAM0), + NEOISP_DFS_REG(NEO_GCM_OOFFSET1_CAM0), + NEOISP_DFS_REG(NEO_GCM_OOFFSET2_CAM0), + NEOISP_DFS_REG(NEO_GCM_GAMMA0_CAM0), + NEOISP_DFS_REG(NEO_GCM_GAMMA1_CAM0), + NEOISP_DFS_REG(NEO_GCM_GAMMA2_CAM0), + NEOISP_DFS_REG(NEO_GCM_BLKLVL0_CTRL_CAM0), + NEOISP_DFS_REG(NEO_GCM_BLKLVL1_CTRL_CAM0), + NEOISP_DFS_REG(NEO_GCM_BLKLVL2_CTRL_CAM0), + NEOISP_DFS_REG(NEO_GCM_LOWTH_CTRL01_CAM0), + NEOISP_DFS_REG(NEO_GCM_LOWTH_CTRL2_CAM0), + NEOISP_DFS_REG(NEO_GCM_MAT_CONFG_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI0_POS_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI0_SIZE_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI1_POS_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI1_SIZE_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI2_POS_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI2_SIZE_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI3_POS_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI3_SIZE_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI4_POS_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI4_SIZE_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI5_POS_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI5_SIZE_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI6_POS_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI6_SIZE_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI7_POS_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI7_SIZE_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI8_POS_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI8_SIZE_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_FIL0_COEFFS2_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_FIL0_SHIFT_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_FIL1_COEFFS2_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_FIL1_SHIFT_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI0_SUM0_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI0_SUM1_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI1_SUM0_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI1_SUM1_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI2_SUM0_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI2_SUM1_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI3_SUM0_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI3_SUM1_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI4_SUM0_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI4_SUM1_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI5_SUM0_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI5_SUM1_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI6_SUM0_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI6_SUM1_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI7_SUM0_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI7_SUM1_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI8_SUM0_CAM0), + NEOISP_DFS_REG(NEO_AUTOFOCUS_ROI8_SUM1_CAM0), + NEOISP_DFS_REG(NEO_IDBG2_LINE_NUM), + NEOISP_DFS_REG(NEO_IDBG2_CURR_LINE_NUM), + NEOISP_DFS_REG(NEO_IDBG2_IMA), + NEOISP_DFS_REG(NEO_IDBG2_IMD), + NEOISP_DFS_REG(NEO_IDBG2_DONE_STAT), +}; + +/* Structure to store word when reading memory */ +union udata_t { + u8 byte[4]; + u16 half[2]; + u32 word; +}; + +static inline int +neoisp_dump_memory(struct seq_file *m, enum isp_block_map_e map, int wsize) +{ + struct neoisp_dev_s *neoispd =3D m->private; + union udata_t data; + u32 addr; + u32 *src =3D (u32 *)neoispd->local_mem; + u32 offset =3D ISP_GET_OFF(map) / sizeof(u32); + u32 size =3D ISP_GET_SZ(map) / sizeof(u32); + int i, j; + + for (i =3D 0; i < size; i++) { + addr =3D offset * sizeof(u32); + data.word =3D src[offset++]; + + if (wsize =3D=3D sizeof(u8)) { + for (j =3D 0; j < ARRAY_SIZE(data.byte); j++) + seq_printf(m, "%#x: %#04x\n", + addr + (j * wsize), data.byte[j]); + } + + if (wsize =3D=3D sizeof(u16)) { + for (j =3D 0; j < ARRAY_SIZE(data.half); j++) + seq_printf(m, "%#x: %#06x\n", + addr + (j * wsize), data.half[j]); + } + } + + return 0; +} + +static int neoisp_dump_vignetting_show(struct seq_file *m, void *private) +{ + return neoisp_dump_memory(m, NEO_VIGNETTING_TABLE_MAP, sizeof(u16)); +} +DEFINE_SHOW_ATTRIBUTE(neoisp_dump_vignetting); + +static int neoisp_dump_drc_global_show(struct seq_file *m, void *private) +{ + return neoisp_dump_memory(m, NEO_DRC_GLOBAL_TONEMAP_MAP, sizeof(u16)); +} +DEFINE_SHOW_ATTRIBUTE(neoisp_dump_drc_global); + +static int neoisp_dump_drc_local_show(struct seq_file *m, void *private) +{ + return neoisp_dump_memory(m, NEO_DRC_LOCAL_TONEMAP_MAP, sizeof(u8)); +} +DEFINE_SHOW_ATTRIBUTE(neoisp_dump_drc_local); + +void neoisp_debugfs_init(struct neoisp_dev_s *neoispd) +{ + neoispd->regset =3D devm_kzalloc(neoispd->dev, sizeof(*neoispd->regset), = GFP_KERNEL); + if (!neoispd->regset) + return; + + neoispd->regset->regs =3D neoisp_dfs_regs; + neoispd->regset->nregs =3D ARRAY_SIZE(neoisp_dfs_regs); + neoispd->regset->base =3D neoispd->mmio; + + neoispd->debugfs_entry =3D debugfs_create_dir(dev_name(neoispd->dev), NUL= L); + + debugfs_create_regset32("registers", 0400, neoispd->debugfs_entry, neoisp= d->regset); + + debugfs_create_file("vignetting", 0400, neoispd->debugfs_entry, neoispd, + &neoisp_dump_vignetting_fops); + debugfs_create_file("drc_global", 0400, neoispd->debugfs_entry, neoispd, + &neoisp_dump_drc_global_fops); + debugfs_create_file("drc_local", 0400, neoispd->debugfs_entry, neoispd, + &neoisp_dump_drc_local_fops); +} + +void neoisp_debugfs_exit(struct neoisp_dev_s *neoispd) +{ + debugfs_remove_recursive(neoispd->debugfs_entry); +} diff --git a/drivers/media/platform/nxp/neoisp/neoisp_main.c b/drivers/medi= a/platform/nxp/neoisp/neoisp_main.c index b08995403c59..ca61af8cf66e 100644 --- a/drivers/media/platform/nxp/neoisp/neoisp_main.c +++ b/drivers/media/platform/nxp/neoisp/neoisp_main.c @@ -9,6 +9,7 @@ */ =20 #include +#include #include #include #include @@ -41,6 +42,10 @@ static int standalone_mdev; module_param_named(standalone_mdev, standalone_mdev, uint, 0644); MODULE_PARM_DESC(standalone_mdev, " Create standalone neoisp media device,= default is 0 (off)"); =20 +static int enable_debugfs; +module_param_named(enable_debugfs, enable_debugfs, uint, 0644); +MODULE_PARM_DESC(enable_debugfs, " Turn on/off debugfs, default is 0 (off)= "); + static inline bool node_desc_is_output(const struct neoisp_node_desc_s *de= sc) { return desc->buf_type =3D=3D V4L2_BUF_TYPE_META_OUTPUT || @@ -1766,9 +1771,18 @@ static int neoisp_probe(struct platform_device *pdev) neoisp_init_hw(neoispd); neoisp_set_default_context(neoispd); =20 + if (enable_debugfs) { + neoisp_debugfs_init(neoispd); + /* Increase pm_runtime counter to prevent suspend */ + ret =3D pm_runtime_resume_and_get(dev); + if (ret) + goto err_pm_runtime_suspend; + } + pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); =20 + dev_dbg(dev, "probe: done (%d) debugfs (%x)\n", ret, enable_debugfs); return 0; =20 err_pm_runtime_suspend: @@ -1785,6 +1799,11 @@ static void neoisp_remove(struct platform_device *pd= ev) { struct neoisp_dev_s *neoispd =3D platform_get_drvdata(pdev); =20 + if (neoispd->regset) { + neoisp_debugfs_exit(neoispd); + pm_runtime_put(neoispd->dev); + } + neoisp_destroy_devices(neoispd); =20 if (standalone_mdev) --=20 2.53.0 From nobody Sat Jun 13 02:07:57 2026 Received: from AS8PR04CU009.outbound.protection.outlook.com (mail-westeuropeazon11011050.outbound.protection.outlook.com [52.101.70.50]) (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 C9E58400DED; Fri, 12 Jun 2026 13:21:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.70.50 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781270489; cv=fail; b=dPlflN0XpVHdUki55lShG8uuP7tMM2hb0Rt7viftZk5oFm1MLbYa/yD89h0IXmWXAeYd3xCVRrf4mQeWvUgxm+JJLlJGZMok/8E1WGXvALBCVp7C+FueFN+NdIVMeW/fYQkRu1/mMR1a1yVCDgZJ8vdOEqzEticBeFeTAPbC6hE= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781270489; c=relaxed/simple; bh=0hK/hXS7WJ8wecx79eFip1XZgfkn9OiPZE/gzJje95w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=PNi4OidosvEXq2JIMIezds2WAVFODG5Wd/Zve8lkpls6Dlxnu++pavYi3FTdIfh9Z3mmsHcDKNGmQvUAvpIBGfvAANxU0vodgiyJU+skzOul1eFU7qDA+PC0N7KGrhEEQKm/UjiQtATBF7aVtKb7A6ZDVbNwI2NQCuDEiiL46ck= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com; spf=pass smtp.mailfrom=nxp.com; dkim=pass (2048-bit key) header.d=nxp.com header.i=@nxp.com header.b=Dat2nXjF; arc=fail smtp.client-ip=52.101.70.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nxp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nxp.com header.i=@nxp.com header.b="Dat2nXjF" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=FL1HQRGBIiw2JX571OwNdadTPjRzm2fEoOxETjzSnHfIHBnkmkt89mLXDNe/PRAi+tbTzCz8uW3Gy+FWVqNZYTpGUklU2g8zzI0+zDK2DETkPfxu1jldWKbaWsI2zHTMYu1Rfc2ghieEg/kEDWwAjZJf+V5zVZj3Dcr20HJ3sJ7Xue2hro91K4VAWzKgH1vLPk1CwyU+QGuJReeWFqvqrNifsil1MDhX2YRDFukla+V2Pu3gZylD3g5GBQuTnR6+NMulGoUD1YFZEPvswYvYCapBTym0oNtNszYydK/nif7J+ujM9C0bhj0FAe003Na2lo19uRCO/dI5AdoTGpjWWw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=WJzQOBCcjH3xzbHxEtV2bLiFQoRMPVPrifUMWfuI5eQ=; b=Pa0EQVrHR4J5LJK4zpJhIwjlrKuP41jMjJDhV7tIe0HnltSLL4BpceWkiVo91qLaN8m8Kc0fwSb1PictwTcaOC6F+O2rbuMR99zti/8g+emd+394XRJ7Y0OXz96LXCit0MEEtsGAgsfrfIG2KbqJZmQOY6e560SXqwGTHdTn2tKlAagDzqCCnOFQNjcxwEt2y1oKUOe5XmOAVHHL52sqcaROl3AAgRvIEkzI/6XZQ6mJ/NOL42WZ9u+fN6dqTceSwgh7LToyWH6AXvE3T/wUqF4zN7AM4T+nyO8reZCHB8Fi9iWh66Vu1XpsiDNfxXekVvv7DqmkGWpKksrUKDFWow== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nxp.com; dmarc=pass action=none header.from=nxp.com; dkim=pass header.d=nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=WJzQOBCcjH3xzbHxEtV2bLiFQoRMPVPrifUMWfuI5eQ=; b=Dat2nXjF8fmOwiwf/8pdKccmld9dPG9W4DLjSzVm8//ftt8H+8iJHTKqrBfHkzIm7fpWNUHM5ewJaIX1nTmH9bXpJIoXvQd2DWHITvkEKqAzcX6HvMdZb7gf/QGlGhf2ec9top0DvMQ0HAY0Kh9B+n+Nvz+6qz2aMeIFeC1ft4CeHbgcX8oy0IhXVep+y10QlfSNMDeOh3RisDTYJAz7cQHaTtXugyIQC/hx/Fv5MAHcNjphFlAOBfaMlljMcMwlZjIGP0gpvkerVdIQma5EtkSfolErMVzo17ozNDHN66b6tkutpPal5aSu/Hu4L9FPOmrE72Dk3QQb90YoTaBNlw== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from PA6PR04MB11910.eurprd04.prod.outlook.com (2603:10a6:102:516::16) by DB9PR04MB8203.eurprd04.prod.outlook.com (2603:10a6:10:242::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.113.14; Fri, 12 Jun 2026 13:21:02 +0000 Received: from PA6PR04MB11910.eurprd04.prod.outlook.com ([fe80::d3f0:3c24:f717:4989]) by PA6PR04MB11910.eurprd04.prod.outlook.com ([fe80::d3f0:3c24:f717:4989%4]) with mapi id 15.21.0113.013; Fri, 12 Jun 2026 13:21:02 +0000 From: Antoine Bouyer To: julien.vuillaumier@nxp.com, alexi.birlinger@nxp.com, daniel.baluta@nxp.com, peng.fan@nxp.com, frank.li@nxp.com, jacopo.mondi@ideasonboard.com, laurent.pinchart@ideasonboard.com, mchehab@kernel.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, michael.riesch@collabora.com, anthony.mcgivern@arm.com Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, imx@lists.linux.dev, ai.luthra@ideasonboard.com, paul.elder@ideasonboard.com, geert@linux-m68k.org, sakari.ailus@linux.intel.com, hverkuil+cisco@kernel.org, Antoine Bouyer Subject: [PATCH v3 8/8] arm64: dts: freescale: imx95: Add NXP neoisp device tree node Date: Fri, 12 Jun 2026 15:20:39 +0200 Message-ID: <20260612132039.2089051-9-antoine.bouyer@nxp.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260612132039.2089051-1-antoine.bouyer@nxp.com> References: <20260612132039.2089051-1-antoine.bouyer@nxp.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: FR4P281CA0089.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:cd::18) To PA6PR04MB11910.eurprd04.prod.outlook.com (2603:10a6:102:516::16) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PA6PR04MB11910:EE_|DB9PR04MB8203:EE_ X-MS-Office365-Filtering-Correlation-Id: 6d09e39b-fcf4-44d8-2364-08dec8857307 X-LD-Processed: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635,ExtAddr X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|19092799006|376014|7416014|366016|23010399003|921020|18002099003|22082099003|11063799006|56012099006; X-Microsoft-Antispam-Message-Info: vs9cvFfBCw9XQu721lkQU8poOEgfQENiJr75gMctZsLCh2PqJ4hsUzL3zi++z9NVoHeEe9kIcfjU4cwFP9JwcQ4rD28nIvJWB2X/6rwo388K4JqynblUMmNK2e/pDSrt6iVkWTP16nOEHmFXdpAMBWV3PIsB9L5a2Wh0S9MlDmcPZlY/7awhv7HvpNfdHggc7lJriiGTdWQ2SHn+X5WMnnoE3KrR7RN6DpyXxFrvwGo00U43rYPgTwogcSPb74MAPmu1jEQBif/1LdJEstQCz+lzR9z/PxOPdmJdxzzO/swgS92/fNd+vj8F/stH4pwvc2P4n0nYzbn9qR2NgDZm9801nXTS5yyCaFTKAap5v0/1MpPsaxEWxs+MrzhlWFYuZ6BM/szoukzrGnyj6H15Jh3NYtD38gfPQOhrcxAkQ7up4w183wUgOihLfS0sXt4rVTq4yMa3ASoIsGkdHa3bVN6BmVzHJ6pvDG5V+8R+0T8eLQBvXU27vzj3h4niH/zWazOQy/xANlNq4ICEuK5Il53tEzGhQeVCM2bI9QLa6cWEzdKjkeiTLTwRE4nGFWKwAcJhuSrbdFogOp+yWOy66GFBLgP0o3NRawVOCylQBHZwMdehdkMWUjESyVaF01OuvxiINVmYipkCBaV32rK7f9xHVqXRL1oMH7vC8yvdkhrbuLMPdrzT2rl1+edt6ROYJWPBlIajw6DyhW7n0dWHGMb66ZLlRTf4REbOuyuSDOA= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PA6PR04MB11910.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(1800799024)(19092799006)(376014)(7416014)(366016)(23010399003)(921020)(18002099003)(22082099003)(11063799006)(56012099006);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?VmONU8USgNRIh60KtpAjGjpzfiSfTSlf/qnZAu9cdrcxG1L9mXYEvwD3iyaZ?= =?us-ascii?Q?rEeFWIyfI+QyTiYkNMyAw5BE8qpH05oFtDfHJzScmfp4llj/l0+FIquzQErh?= =?us-ascii?Q?dzNL2517E8o8t3xeLJj8Iv4yK638uy3tzGZzda/J6/YiquSqI3su66oPj56y?= =?us-ascii?Q?UuMPSaXiJhUX/78YYjXHVV0Zok1OjD/Dwd03ki/JrHF+0wZQTZNTzhhVH4D/?= =?us-ascii?Q?xvsUkXYKx+z2WLOOG8bvXwUmrJmS0NS2Nf2KhyEYAogoWTMoASbLe1SWhiiQ?= =?us-ascii?Q?DXLVJzOsOijhtAfXuIrALjr+aBQT/fwtiauhlBWqr/kqxLlh9I3N55NwL7e4?= =?us-ascii?Q?c/DB5vkvTkgxsH7fnsFYtBg/9C6Ca5PxdDQIYo+Bk/3DkVJe4bK7AECy13za?= =?us-ascii?Q?D2IGUttHHQsWvVvTVDSEuNVHUA+n3GG3Spuiuu5EqT5/dvh+yREPDTXxJ52Q?= =?us-ascii?Q?jKV18iLqp553YnP8Iy1FiwVJc645pY/4nG65l32ITjSsM15CB7zXXwx2jDcy?= =?us-ascii?Q?jz+gqQuDVsQIGno2HJOnIiCR5aZfsZPsOL1BaaScHvfGTw5lpmxKQIAcXKsk?= =?us-ascii?Q?758RLXB2as/b/4Ch1jA0Aj71aj3SvIm25BI9mjsKTmfClm3fHFOINDN6AuwS?= =?us-ascii?Q?qnaMH1qoY6BME+1jh3Ej9OP2+czUcr+mgGjPtOmwd8AUWBfDFz0MSx0WtZgn?= =?us-ascii?Q?7sDXovTmy8BVMkbQQaX05JCffxEAadMQIncM3H0KtCx59PRpRbv3V4bAwqy7?= =?us-ascii?Q?S0U9MeVQpaj9wgxHH5+Y2JU8poS1r15yj2gghWZ0B1TaOcFSYb2H7WG2Rkwb?= =?us-ascii?Q?dRhCvUeGM4BCInPV7xzfioylCDwnvx4e7V+kK1EJG/XD5nkuKCl9QxLOfr/m?= =?us-ascii?Q?THWg+b8rDRhXTdG4t35It9QnYuEBgER0C/jxEd79NlZENm1HWgxWgkYubl9b?= =?us-ascii?Q?MIl4PhOxfDolL36ndqzy4J2SS2OYpf30EOPsLA7WEtb0rv0zbeobHmvgIbm8?= =?us-ascii?Q?hw8ku7X0hnLegLfh+LbMo18xc4clK+QxgnrwF6aueMlkiI2++3aultrWfpw1?= =?us-ascii?Q?qkD2n+wBCyT8twsyV9g87VGb1/xRSAh5qmfPA/waBGfvRKg8IVsqCSFIhv3d?= =?us-ascii?Q?SqPQkAsdEL7BpYeCJhs59jlSBQ2aXaydjeUBjo8MYRcXZWs6kYK1mUzlLei7?= =?us-ascii?Q?BOfyrurwXNsRZMkqeEA4KIdcTgtAeN4BiV/NzHCZxnhjlUnEGHfHVVbPeJJd?= =?us-ascii?Q?jgOeVZ2R6Wk8tXSDlHm2FhtsconuOgeoIYJePUpIsn35KTp7zdNGUZv6K+V7?= =?us-ascii?Q?M32ahV9uqvuGl3MccV9NLG8AvGE6oIRkltb1/Y+DUHd2A6gpSlRtY9KBAS/q?= =?us-ascii?Q?Osv7CKtLJ1/oKfBT9tnVfXlgzZFvcLjMJaiErlBvp6gvoVtmelfVPLHqsvrn?= =?us-ascii?Q?8+kP2lqlg2wZDs/yiQbPHsOKI8+chJTEqPU/kT+xZ/kxm2ZdyLLn1EQQNdt4?= =?us-ascii?Q?HIh+i1Y0sARRH7odpBJQhRDl0fZSW4voQ64dnSRm2y6M5zzVRqrI5EBY37Yt?= =?us-ascii?Q?r9DwyhAUcyEZOvuVHztV9MNUPejr7VEeMo47T6PWnPTqNPQOyMOBFES+3owe?= =?us-ascii?Q?pNdggJlGT5/w7Ze0X4tPIDSQfuIl085oRJD2UmgeW4EHNQZO5yvbGvrwu1bp?= =?us-ascii?Q?gJ9svyMWhab2PAEDopIiqQeJKP+yn60SDD0CSkWe1rW07tXiHyKEwQVPSFv2?= =?us-ascii?Q?+4L+ggzR5A=3D=3D?= X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 6d09e39b-fcf4-44d8-2364-08dec8857307 X-MS-Exchange-CrossTenant-AuthSource: PA6PR04MB11910.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Jun 2026 13:21:02.0768 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 6PU6qjN8jxTw8Iwhw63/GPVr5xVsE3HssqGaxg0tqmh3gq01pAYVJeBux4GM343hIRmjaid+1oeUwy9qlx886A== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB9PR04MB8203 Content-Type: text/plain; charset="utf-8" Add neoisp device tree node to imx95.dtsi and enable it by default in 19x19 evk board. Signed-off-by: Antoine Bouyer --- arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts | 4 ++++ arch/arm64/boot/dts/freescale/imx95.dtsi | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts b/arch/arm64= /boot/dts/freescale/imx95-19x19-evk.dts index 2e463bc7c601..306593585c74 100644 --- a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts @@ -511,6 +511,10 @@ &mu7 { status =3D "okay"; }; =20 +&neoisp0 { + status =3D "okay"; +}; + &netcmix_blk_ctrl { status =3D "okay"; }; diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts= /freescale/imx95.dtsi index d6c549c16047..5543a6cb1250 100644 --- a/arch/arm64/boot/dts/freescale/imx95.dtsi +++ b/arch/arm64/boot/dts/freescale/imx95.dtsi @@ -1867,6 +1867,17 @@ pmu@49252000 { }; }; =20 + neoisp0: isp@4ae00000 { + compatible =3D "nxp,imx95-neoisp"; + reg =3D <0x0 0x4ae00000 0x0 0x8000>, + <0x0 0x4afe0000 0x0 0x10000>; + interrupts =3D ; + clocks =3D <&scmi_clk IMX95_CLK_CAMCM0>; + clock-names =3D "camcm0"; + power-domains =3D <&scmi_devpd IMX95_PD_CAMERA>; + status =3D "disabled"; + }; + usb3: usb@4c010010 { compatible =3D "fsl,imx95-dwc3", "fsl,imx8mp-dwc3"; reg =3D <0x0 0x4c010010 0x0 0x04>, --=20 2.53.0