From nobody Sat Feb 7 07:31:36 2026 Received: from PA4PR04CU001.outbound.protection.outlook.com (mail-francecentralazon11013031.outbound.protection.outlook.com [40.107.162.31]) (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 2521C33C53D; Fri, 23 Jan 2026 08:06:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.162.31 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769155582; cv=fail; b=Ju3lb8itK55rNctgFV+wlY/jBn5qHKHPVGXiqSr9tqIiCquMKyfRGHbyCEPKGIRgziwseQFdiFHUqMZdCan+s4pZnTRdOYWRbUC1rxVm+pPq1awhp2PM3lZ271e8LSm8w9T2ef+ysChnpEROv9cZkH9GoFWoaM+kEaebhD5J8N8= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769155582; c=relaxed/simple; bh=t+cn0Kj3R8F7IjjL3bAIqL8WhZlGQXcN1TGOSEh0b5Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=R9q3/6HR1feOMN4EVMWGd7NDkU+sPCaaZir6lQURM/4/V+BkRQHfWY26erRI6ZlCv5o4h7WypJnOdWaPmx0Tcaml64B5TYoI6xzb9VXNtC8uuBhhJgiUktqNsnopB5am054+NUA/gUdQ+EJhRyZb2oqtJnl4oVbQqamUvb2dvzw= 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=nkfxO8OG; arc=fail smtp.client-ip=40.107.162.31 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="nkfxO8OG" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=v/l9PjJH63Z6zNI5cjQPz8b9z3po4u/L6KnZtkQq/Bgayvbjis5oDpzwKNdsPL1MfD1MwXp3qIcpVc9mnoNW+ADmaEUFyKkJXOuCVnh39FPkuPt3b4QrHlOmPgw0ZYZdQlpcR6HaMs1EpWvjh/FJ/o2xomgQUiubmOyI3glM/1V3c91BLbWi+EIvEQBESWUR/m6dUit/chXlG7Ry9VHUckoxw7fzaEoIaoEJ5gw4jOz13qpoFTmDuSH+CXy+VrLDOm+tLqwaNUf5pr4RabtE7c4L6utKvQl83BqosDQ+SzKJymcqXbN0liYrvqnPYptuxAQTMM/xij9BjLev6OFuyw== 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=RCqTEfTykEiz2CNjpeF8sSdmKnv+ngiRI6OD1IcW20g=; b=mZRhfOPfGj49T+dYdbSAeT50S15VIbE5TfXAZA66zQxDdbAgYOI2TMc6FXj/JpP8iVKFAgGnXTOM6mywbgJMvNxhRpBG3jUK02hnYHysp1VbzMkQmBKaOJxnEdW0Bh0qSRU+SnJ2S8R3OMyBrRZ7k5Kk4n0ppZapTq9YChgPsxt0RHp5omwW3ALgMPpk7uoY+sXQdbamwquXzD7d0k+bQsFTOu01E+KWRfKl2QsYHZFpTkPf8tPhyg/3fZ/7YKAsdLTEOLB4BOxxzOzhtq4/URBvn5m3hQNjGdhrZH+09ZuMKBPFMQGtoiGSDrYURB2prrch90DRY1GYMTleJEdoGA== 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=RCqTEfTykEiz2CNjpeF8sSdmKnv+ngiRI6OD1IcW20g=; b=nkfxO8OGEEFM19mJdSMPONB393xWImkzeSapBPtD5xmpRwBIqqMZ+LTCYNBWr+PPZ8tDU8JmXbwCoUgmJn8GRguks4QQUcaiTfS+aPLDyUcIDwqx0VOXEGPAFud7j0RtfINh+3T8HFdLPeUEsuDZ1ZP4SuuRLd5xnB9wMTtDg0j2WhrL3IdusHCy/8PNoEYhNYFqw/PYPGcpIhLhPJx8Fcga8tKVdoU4GAdHOG53MkqUjs3zlT4DzNs+p+bQG0b+sidEQPqglycc1fs3bWnqTWC09fARWvit7Zjha+lFHky0/WbZVHt8FBCoW8FwY6AwFgkoliyBSUOa4NAUjd37LA== 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 PAXPR04MB8624.eurprd04.prod.outlook.com (2603:10a6:102:21b::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9542.10; Fri, 23 Jan 2026 08:06:17 +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.20.9542.008; Fri, 23 Jan 2026 08:06:17 +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, shawnguo@kernel.org, s.hauer@pengutronix.de, kernel@pengutronix.de, festevam@gmail.com Cc: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Antoine Bouyer Subject: [RFC v1 01/11] media: uapi: v4l2-isp: Add v4l2 ISP extensible statistics definitions Date: Fri, 23 Jan 2026 09:09:28 +0100 Message-ID: <20260123080938.3367348-2-antoine.bouyer@nxp.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260123080938.3367348-1-antoine.bouyer@nxp.com> References: <20260123080938.3367348-1-antoine.bouyer@nxp.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: FR4P281CA0026.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:c9::11) 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_|PAXPR04MB8624:EE_ X-MS-Office365-Filtering-Correlation-Id: e213c87b-2f02-4d61-e2b5-08de5a56491b 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|376014|7416014|52116014|1800799024|19092799006|366016|921020|38350700014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?/woFGUCNnZ8OIPd+hX+ZaD1kGhdaKzNI61mNrRO4Cd+v8CjXAvVgVNn1fXXC?= =?us-ascii?Q?s5lIUqOds8+t3YsliI6G46tq0TLXv5dhmkG94jz4FtBxntJ8QHkW5TCvCXhO?= =?us-ascii?Q?72XOT1YECkjaNhmdzwEDuWOfbUcB8ub1LvPe+sA/qHnZ2mZbVz+p3xq4pKU4?= =?us-ascii?Q?5eygHjbucpGW3kpfWLI6Knyec89tzjQg/dPLVmRslsQtzKEk7kvlGSK/YHGS?= =?us-ascii?Q?6CzbVRMwXGRskzySF5u/A/RfOe18FeJSD329OQC1YQp/mYyhqoiHlmgLZdcw?= =?us-ascii?Q?K/7Ueb9JEo/GhJWMVTK5cJNKj2VPlNlRcGTCnq0YmVyxzsQoSf5vqTjPmT6E?= =?us-ascii?Q?JwNrZB/uHMOKD3hOYGxK7b+HUFOOpxCITxG5QkaTfAoPFEwy1uWgykhIaW9O?= =?us-ascii?Q?t/zuJ6VndlL39Ii36d2mktEj5r7+ABgQpiK03wyWgwoZcOFm6RAQ6N6eNvIM?= =?us-ascii?Q?yc6TaA4jrI5gZhp7CjD6usDv2QJ2b9vPxXjoVrwTlC29Gy09WamFDYY7IbZ1?= =?us-ascii?Q?L2G8Oaxj9ePtuVTo61jYlOj48ufgLQN9G11wkZXWfixZTrMIuPvrQyOBDftU?= =?us-ascii?Q?FawD89Tt0lyVWPxReptozBNa/Av0yoSh0pPOo3WNlMApaXqWVvADJl3cuBhC?= =?us-ascii?Q?u7oMhR8vx7DA5GJpw7Wq63xA39X1sXu/WyrJK5RfTJbUhL/qzK9qUQrgnplY?= =?us-ascii?Q?5fcEglGqSHdHPUL426QD1ggTgUxpTgZmu6Zgqxyb1SKAh3Ipor8qWdjCJEiJ?= =?us-ascii?Q?RJhkDH7KeqWZQ7d+RyLnkMZALG0W78/gl+T1mH12Ed6cHa27ODiOw7SSfVNp?= =?us-ascii?Q?MXR88JEh+HBtklG20hVmxyEdoiicYUchw60JkXs9cgu7qsEwQ6JzzgvKBbgO?= =?us-ascii?Q?fOxhMfhuzDsiNIQ/Da/URmP0QXrJbNh7ERsHtZKZfLZQ/MsNquyl272zcobq?= =?us-ascii?Q?Pu2WliY5s6OoGB7hO2TE5qB+mi2e6O+5aBynfdajCESHjoExwcULuTEaLHRC?= =?us-ascii?Q?W1BSlMHxdoCX4DZe3TPB5wvfCoWYqnLNR2v+INlfkPG8fD+Kj9esK9WokaUK?= =?us-ascii?Q?ESAJcTgf/qys9GuNjabO6ty2ChL9y8PJNO2FBUW5NRxIqRVkrx2O04glFhyl?= =?us-ascii?Q?HeuHzkfHO0HFPxFzqVhSzH5chYL8tX8jEFCgT1fSNIAzWVE52g9nF9DiwrLn?= =?us-ascii?Q?kxGjWCw++ijRetzrRA9w/SQZIBQs0D742s+tAtAOKYXhPR5Zu7hxH3/Hclvo?= =?us-ascii?Q?d+p43a6dqV8Y256IH88Wx4XykjEkLdlCSdfoyeVNrEIYN0sRorMyM1zX6NMh?= =?us-ascii?Q?j2IFOQ/BeZrYFpmCu6/lvD/2xGtN2BmgBWrSNzqfUe5PxzH9S4l15U6ERADl?= =?us-ascii?Q?NUajWu1rso5ZreKKDs1auwFkScy8XP2aNNizxhzGALctFyNUUcrujJJGi8aF?= =?us-ascii?Q?5nrRIaGxOedgNtsqOS/WlkZ+CNff8DRKKaAp3gdD+48gK2MRe1q6SExdBnMS?= =?us-ascii?Q?Tg1EGTgB3yvpx0Byfx5snAgBmguQ3ejn9AO+pYMo7/voymYE7etlYrMqSxXy?= =?us-ascii?Q?mqwXMIa2AfkoPhi2LefxhAp0CK3QIOz2QKqXI75sySRGTcsvW55ZRkb3Dg07?= =?us-ascii?Q?P+JcEcUalJIm1ICCRPXn2G2ykx9/8O1OdfTEebWYFm+8?= 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)(376014)(7416014)(52116014)(1800799024)(19092799006)(366016)(921020)(38350700014);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?6VyQiOsOvsYNhhjWLU9kGNCN1qydim7x2sRPzYi1UAYILbIANm9CSlvBrsXP?= =?us-ascii?Q?xRJH77tB9awYY36pUVO6AEQOn7C7F2wI6Fw+64W96d3nX2Phk+rULfcXet55?= =?us-ascii?Q?RgVAPJBJ0r+9orRM7DwUmBHJUhUC9WIwnN0fIm8lC4WaSizADK2Rm13G0CLM?= =?us-ascii?Q?z/bxG4UCPPLqhK4RXvCC+KcIcgcdlMlp0OyhkH8qZsAo6ZkVwgKLbHimaeUk?= =?us-ascii?Q?I1PPb5iexYPB35xFdmj1j2/8hwExuzPkidNEwJ/yszbOzfxzcr+ORjyZoUk9?= =?us-ascii?Q?dgXoEzXAdbNJ0uiuUMv6jXKPNQB0yPpR95UsA+Ehu0IZVYZ7kRx/WBmxyt2z?= =?us-ascii?Q?/7gelDPrNZ3gY53iHL8IB3MuD86usdGEB91bbOeL35HZ6bxODRWaxJUWKKWr?= =?us-ascii?Q?YgqyqbWeme3YgObmcRHbDy8aDJDL3paQtESNOzCsD9S0aKvjzxKR+o4l/1Y2?= =?us-ascii?Q?DuqoO7+i5gEzT+3DhDPB2fxnCTYdm6RrZ+vWsFvgojM5vEvozzoBjpXjLZMD?= =?us-ascii?Q?Y+F/UCFKMna5tXheYAIuVFDO61bGcC/0zR4dT4qoB6cYN/0jV1Ssz4GA4ex0?= =?us-ascii?Q?Pf3rQEMQu9Iao1EX1VwYz7WgGBqNSjwfBIFWm9v7GpWtS/kL3o8VXWfJcbf/?= =?us-ascii?Q?TP9P1d4j2FPNCj1sEKQrsIC7dMnLd0XuoMtPNG5xoQJ3DLRAt9Oyq/IhPn1Q?= =?us-ascii?Q?+iE+UHaVnIftb77FnpqI7VsRIl8ffoxB7iPQ12opIMSHdY3uVKGShLuwUlQg?= =?us-ascii?Q?0pfTJfE07y3JpHO/dAIZAbN9ORocKWZrr3/DUNMcRAVJ8/6i0Cx3nbAlhq3w?= =?us-ascii?Q?Xl0rmnSswQPz8fIrUJViIC3cZ+zHFQNYTgjI/7Tm58Sy9Bn0J7ZfSeUIjtv7?= =?us-ascii?Q?X/xIFxuMUmGXDqyzMisMP3vF40D7sNlhQIReIlj2O68b4FxmwGz/ecuvRprB?= =?us-ascii?Q?hNVJUnisZCD3+4x4DT7r7CmV0GPzBmUyJu+veSzshWhxQElM7QSTgw1n6HM7?= =?us-ascii?Q?VUcZ1FFKe7Tbhw+tKT7BLnBFR0EiQGh1c59piNO6stv7eR9J8LbMOAauKH9x?= =?us-ascii?Q?dSHtaLvfARGdd6HB+euDgTl1nyo/Fwgx/uJ2BenYTZakbVqnw4XRpQKLn7nW?= =?us-ascii?Q?PGSXQTSN07MdMt0zm/77ijqCRYIBotLMTcgAqv6VKwCrV8mYMq6bIh+0LI38?= =?us-ascii?Q?88tfYWFaQV63wCmeVrWhkDp1gPRfGGktXPZ6jzZiTUINGKbruXG3OcVbxddK?= =?us-ascii?Q?4Vbb0mvrc0+jhHzs3ui5SJnFAcS7LJtXcnIrcBuiya0eKAdy7Z857PleON/d?= =?us-ascii?Q?06NlZp/7KNzf3tzWXzYDld3yD/n2GxUQWo6oGmTj4e8byy1XP1fWYN4GxQgE?= =?us-ascii?Q?vzKfRB2qYn7Gl/+UHK1tAgyrm2+7cXPmd80eH6AQEo2xa9USaaRG9WpEEr8N?= =?us-ascii?Q?+3MxRq3g2YOsXK0ToTip5g+BRwIA9ssUeUW9RmtcpNGaHXUw/jGoxUNOhxJa?= =?us-ascii?Q?DYaWPqzCSDm5Ik/T/4kX58xod6TnsMZkuPEFZItHyV3YZ2FLFZE5y5EoV7pP?= =?us-ascii?Q?QkYEOBoLiVr2MvgdKqeo/0BJnTgz+e1ozu5gHrPm8wQ+X9TZeoNNRaNwljY+?= =?us-ascii?Q?byPFiPzbrJRBI6tgzvrh5f4IXlqIRkWxDJAb39NFPr+k/2T5IIN92o/DrcmF?= =?us-ascii?Q?YX43ru74BGt2LuBT5eno0mxAqJApoTfafUf5TjWVX4t//Z6aPRS9odCHyhfa?= =?us-ascii?Q?bSqzw2k4Hw=3D=3D?= X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: e213c87b-2f02-4d61-e2b5-08de5a56491b X-MS-Exchange-CrossTenant-AuthSource: PA6PR04MB11910.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Jan 2026 08:06:17.6402 (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: Fb6tukg8ZCTyC90pZOZLcyXdGv99NZKU2B3iU+RrYB0CTVTPw3dKw5PQS1E5BRj/kNkHVZ7UnVZXWULr1F2Yxw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAXPR04MB8624 Content-Type: text/plain; charset="utf-8" Extend the v4l2-isp extensible format introduced for isp parameters buffer to the statistics buffer as well. Like for ISP configuration purpose, that will help supporting various ISP hardware versions reporting different statistics data with less impact on userspace. The `v4l2_isp_stats_buffer` reuses the `v4l2_isp_params_buffer` container definitions, with similar header, versions and flags. V0 and V1 versions are provided to match with params versions. On the other side, ENABLE and DISABLE flags are not really meaningfull for statistics purpose. So VALID and INVALID flags are introduced. Purpose is to force ISP driver to validate a statistics buffer, before it is consumed by userspace. Signed-off-by: Antoine Bouyer --- include/uapi/linux/media/v4l2-isp.h | 85 +++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/include/uapi/linux/media/v4l2-isp.h b/include/uapi/linux/media= /v4l2-isp.h index 779168f9058e..ed1279b86694 100644 --- a/include/uapi/linux/media/v4l2-isp.h +++ b/include/uapi/linux/media/v4l2-isp.h @@ -99,4 +99,89 @@ struct v4l2_isp_params_buffer { __u8 data[] __counted_by(data_size); }; =20 +/** + * enum v4l2_isp_stats_version - V4L2 ISP statistics versioning + * + * @V4L2_ISP_STATS_VERSION_V0: First version of the V4L2 ISP statistics fo= rmat + * (for compatibility) + * @V4L2_ISP_STATS_VERSION_V1: First version of the V4L2 ISP statistics fo= rmat + * + * V0 and V1 are identical, and comply with V4l2 ISP parameters versions. = So + * both V0 and V1 refers to the first version of the V4L2 ISP statistics + * format. + * + * Future revisions of the V4L2 ISP statistics format should start from the + * value of 2. + */ +enum v4l2_isp_stats_version { + V4L2_ISP_STATS_VERSION_V0 =3D 0, + V4L2_ISP_STATS_VERSION_V1, +}; + +#define V4L2_ISP_PARAMS_FL_BLOCK_VALID (1U << 0) +#define V4L2_ISP_PARAMS_FL_BLOCK_INVALID (1U << 1) + +/* + * Reserve the first 8 bits for V4L2_ISP_STATS_FL_* flag. + * + * Driver-specific flags should be defined as: + * #define DRIVER_SPECIFIC_FLAG0 ((1U << V4L2_ISP_STATS_FL_DRIVER_FLAG= S(0)) + * #define DRIVER_SPECIFIC_FLAG1 ((1U << V4L2_ISP_STATS_FL_DRIVER_FLAG= S(1)) + */ +#define V4L2_ISP_STATS_FL_DRIVER_FLAGS(n) ((n) + 8) + +/** + * struct v4l2_isp_stats_block_header - V4L2 extensible statistics block h= eader + * @type: The statistics block type (driver-specific) + * @flags: A bitmask of block flags (driver-specific) + * @size: Size (in bytes) of the statistics block, including this header + * + * This structure represents the common part of all the ISP statistics blo= cks. + * Each statistics block shall embed an instance of this structure type as= its + * first member, followed by the block-specific statistics data. + * + * The @type field is an ISP driver-specific value that identifies the blo= ck + * type. The @size field specifies the size of the parameters block. + * + * The @flags field is a bitmask of per-block flags V4L2_STATS_ISP_FL_* and + * driver-specific flags specified by the driver header. + */ +struct v4l2_isp_stats_block_header { + __u16 type; + __u16 flags; + __u32 size; +} __attribute__((aligned(8))); + +/** + * struct v4l2_isp_stats_buffer - V4L2 extensible statistics data + * @version: The statistics buffer version (driver-specific) + * @data_size: The statistics data effective size, excluding this header + * @data: The statistics data + * + * This structure contains the statistics information of the ISP hardware, + * serialized for userspace into a data buffer. Each statistics block is + * represented by a block-specific structure which contains a + * :c:type:`v4l2_isp_stats_block_header` entry as first member. Driver + * populates the @data buffer with statistics information of the ISP block= s it + * intends to share to userspace. As a consequence, the data buffer effect= ive + * size changes according to the number of ISP blocks that driver intends = to + * provide and is set by the driver in the @data_size field. + * + * The statistics buffer is versioned by the @version field to allow modif= ying + * and extending its definition. Driver shall populate the @version field = to + * inform the userpsace about the version it intends to use. The userspace= will + * parse and handle the @data buffer according to the data layout specific= to + * the indicated version. + * + * For each ISP block that driver wants to report, a block-specific struct= ure + * is appended to the @data buffer, one after the other without gaps in + * between. Driver shall populate the @data_size field with the effective + * size, in bytes, of the @data buffer. + */ +struct v4l2_isp_stats_buffer { + __u32 version; + __u32 data_size; + __u8 data[] __counted_by(data_size); +}; + #endif /* _UAPI_V4L2_ISP_H_ */ --=20 2.52.0 From nobody Sat Feb 7 07:31:36 2026 Received: from PA4PR04CU001.outbound.protection.outlook.com (mail-francecentralazon11013031.outbound.protection.outlook.com [40.107.162.31]) (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 1C82433F8B3; Fri, 23 Jan 2026 08:06:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.162.31 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769155584; cv=fail; b=D+08NyPRnPzUfNVmeqDnhjSeANeyKtG6m9wwkroub8FXqdlHH7sHwiWpswkVRVciYuSZTr/cxlVSfqoDroCy5/SLqQn60Ffhho3NY4Jv7T9WQoZgWZFgEm7IeaL+1ZfiZIULZYfqYavEybO3U6n9ARosz0qe6arZTbHRCGY19EQ= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769155584; c=relaxed/simple; bh=aY7Bh/dLWa+4j6dWRwRfiZ4OgmBQgP4EgR9lzaR2GnA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=s5+EZGBwOm8NuS6vDiLNfRBN6MqC8OhbOc4seR6oZtTryQZ0aPk8dFM/bAvwo1AAg+IYIzw7V+fz/pWU/LnJOOZCUvtoM7PNmR4/eQOyZSjh9ykrdhAfbDx148UexqOqKQMajpU5xHHjSy+NU8gYlahgFCD+UtIwvnLVjiuyM0Y= 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=iRzL654q; arc=fail smtp.client-ip=40.107.162.31 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="iRzL654q" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=UZKrQZkxId6ysIqQUkb5KB3XTbJhT/Ayw9E3cL2EdG53R8DNljUr+sHz+KGOjiSFKJoMB1BV9xXvGc3fGocmXfJgQaoAszijWct0M3TT0smMqW8xjc1or9gjpVEW90IyTqDpuUJszFVtaMvyViThXWO79CWJV5WHxemTout9jQYq3q1IuoEJR5lzXEbFHIw/YoetJ6NUG6Y+fZzpnJZjjQa+OPFx0zZybuLALm4DvyAn4BoaWRiICFB2cDSLVuOFcF1zE7NGNdaKJaU0dEW+TLEYcTu35ZZM9AhOGHcEizay2Z37l70pBhXs+iCmJiSbsZmxDLzr6h0dz5/HW2kH3g== 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=NMEi1H5AF9to/9RA4CfAP2VOWux6r6MRYkM9sdThIjo=; b=wkqIZCCLvql5PSY6uNUHnfEYJWZyUHaPjMaFYKKsGuK71IBYin2Ea4YNLVkOW13i06E1H2rn1qB5IcpPWjikF7Q9ZzeO8hgteNASn5k4aTQo/2yizRBb3gQLrrIxjI9NWNoJRv20bKTcfDZDrLOFs1UflXwNKb2AtGDNvywmtWO4lAoDsAaeUo+jQrki84AodyMUbcveWehOSFPkfyN+3KfnX9u0Lgd7m0DN+FNlHbj9WfJz9Zzj9FlcQsb+EWH4ghWbw6CpwTCHwXysLhEAC4H0YaOKk5TvM98S7vwnbz6++1QaLupjA4ZnmsfwdEvQvHTO9KJn/14SW5kpb1kp3Q== 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=NMEi1H5AF9to/9RA4CfAP2VOWux6r6MRYkM9sdThIjo=; b=iRzL654qK8KIeBpwEdinrBJ/BPXwodd6WIDZ6RFS92+FrQBNqUcdjIvS2Fmd2ki44e2ehGuDjx7VQzQTV923AGNzx6bcWEu1VQtgSHK2HdXwgo1fqN5xh9JU+ryTYygrv2I2vXUOhM/jiIGkkyIW1q5axa7ETC7WkOXshh/hH904lBvtk0pGTT+yY5rTsyk1I/+Lk+xmap8JU103n2DRdnmLhnTlHRmPQD//XTQkERb+3Id9naUWAac1SlW4Hj0WUQkVUgikfV6LMohWmTRnx325+qKqbipfZ1JBZutNDCnmpLz3yt7aeQ9TtbVB3RhCK5UnEV8O3C5L2jyZ+JdJiQ== 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 PAXPR04MB8624.eurprd04.prod.outlook.com (2603:10a6:102:21b::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9542.10; Fri, 23 Jan 2026 08:06:19 +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.20.9542.008; Fri, 23 Jan 2026 08:06:19 +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, shawnguo@kernel.org, s.hauer@pengutronix.de, kernel@pengutronix.de, festevam@gmail.com Cc: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Antoine Bouyer Subject: [RFC v1 02/11] media: v4l2-isp: Add helper function to compute extended stats size Date: Fri, 23 Jan 2026 09:09:29 +0100 Message-ID: <20260123080938.3367348-3-antoine.bouyer@nxp.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260123080938.3367348-1-antoine.bouyer@nxp.com> References: <20260123080938.3367348-1-antoine.bouyer@nxp.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: FR4P281CA0026.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:c9::11) 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_|PAXPR04MB8624:EE_ X-MS-Office365-Filtering-Correlation-Id: 14aae559-c8f3-4ae6-0949-08de5a564a05 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|376014|7416014|52116014|1800799024|19092799006|366016|921020|38350700014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?cv6R4MKgCQ7hMSpVohKoI8W5els3lZM2VFgTIzyfP+4uDT8z6RD64ROoegBO?= =?us-ascii?Q?nm4JWWf0BMS+VPOaKViEQSGn+BW9Qg67UUIgMI6qrvlaL5yTXMaR81qvJrQ6?= =?us-ascii?Q?ZXSVPSL0j29l7ssj1w/rcZsZWR79oaQen4f3HLfrLTlnylv64X+cmaLKfOvU?= =?us-ascii?Q?C5E2Q/eb92y9jGgYxvYJHSkU5fJ3V873livM/KEiM//nVYgLFJcyVhbrU2E0?= =?us-ascii?Q?DBrmJWpuwmPztI6bqQejOHlthu7ZKVO6xf4ISceSis9b8o1xwQPNTELg3RlW?= =?us-ascii?Q?K6x8/SixSZpdyjb/p+hW+gCVPWvKTfBg2J/1U0VSWCVqOeR5ozxpHUrEcM7K?= =?us-ascii?Q?Wnda2PTqIXYyp5Pput8fGTM6rot6++c0gahWkprOvQ0grwbPgs5fqCMbGsti?= =?us-ascii?Q?m6n9XfrkGaDQOSh/ZPhE3D5OoYDzbioporWrg1JYZWKmBCkl/hTMEWtQhNMr?= =?us-ascii?Q?duyDhqyorswPqnQo4WrtJVCga80A8dzwFtpdYN2iA3jHI+ThCYL1TFGGW5lv?= =?us-ascii?Q?LK/3IhqCYVxehejsofxNiekfFie8SmyLANz0TSleCFb+YWYMZJ83nZtCnNMO?= =?us-ascii?Q?+Wb3GOBda4K4dhdtGpW/FuWvHTH4NeeZF9WBTJVpFhf5Yzz/YI70LoettVdJ?= =?us-ascii?Q?Aj+WFjuOSyQZQrT++FwQudUwe74JEHbU0u+tWuCLQILMpyY2/Ll/h0H8ru65?= =?us-ascii?Q?SFkKo7f3xlOlspaKToJ167oiV2/fRysUCLXAGkw9BGoRI++GZCMeMVE0tYj+?= =?us-ascii?Q?+fLmsAQmiDuHvhrdKiiFV9mlrtcF5yypnmFSA5LseCkmg+rG05kM2X+qziI4?= =?us-ascii?Q?cCThmKUSWX+AaOEur+447A/5LIlb5fhD7tdwmRX1szQd5yOixhyhmy8vRZJw?= =?us-ascii?Q?o9jRuUzrcoJP2MoMwPGufwNcXmJ+04Vd+TZwvGCLXTUK5lajTDYGOz8w+8Rt?= =?us-ascii?Q?Ia4qWVovkmYhr2lZ+cbihJQZow5GJP+PdncVxrUFCJxenvNSqUPqlrTXPxV/?= =?us-ascii?Q?M7I56GBO74nGi/AJQC6yZSQjNlGbc7JIElkjM3HlVRt4v4TUXG354ztqHqoP?= =?us-ascii?Q?CqtF+hBVEululGXeAMwIhpFGLhv9Bi3VPobn2pNtcY9yvhhxE+PKMv9wslKk?= =?us-ascii?Q?bWmCQJiSkwDt7uGzAB81ClJsFGyImf+XymonLHCzD0YylFhanPYd3BQebBUm?= =?us-ascii?Q?u/WN6IGDBQG9b7jpvXetoXc/aJ+prKAKTKxveyK7aDzo2hOIeql5D/KLeiK8?= =?us-ascii?Q?ZsgBAAbkHv737C5DjddmkwO5rryeU5WNsevZ/lpBDEQsVzY0aqscUXzZLkNv?= =?us-ascii?Q?MoIQwtsa1B4CaFNa1rNz/l9i8hry0NRiN0GpfsbF+yOHbXMeF7w6aHR/20Mm?= =?us-ascii?Q?79kQ5Jxnx3YZr4VGKGPrMu7PTRE4MsqwLXyV+QLfQVh9zBXu/zxgFI1YBrRI?= =?us-ascii?Q?7McFkaQx1uGF3+p44irZjlvHnBUqyGQgYBcOUTi8i8X0wuOqh5GU9L9iZXiu?= =?us-ascii?Q?FF0cFM4XFXbinro+HTcul/MTAJfrqeacSMw0YP9NgShktkcqooQggJOKbgmZ?= =?us-ascii?Q?0uc80hUfuadbxarb0nAy9Oe3fzpKV5pS9Nb84xzevHKqRy6Ja6GnRPHLW+/n?= =?us-ascii?Q?ubUHCsPVN/SocuypP+AFp5FQtrgVQuEEGcsvyQNHVpN1?= 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)(376014)(7416014)(52116014)(1800799024)(19092799006)(366016)(921020)(38350700014);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?EcpcyDAkfmNpHUb8FUpF6rqyivsTeKU4f1zMIsPJ2GpgJlgfM0v4FjMtBdqE?= =?us-ascii?Q?5LzWxANYdvCXHopD3HEI5PwAZeUrt6jTDk561fdfI4BZpmYot7YRWAEJQyXw?= =?us-ascii?Q?RTedCasVdC8w+K9mOzyKobnSeq6gE+GCwDZa5DRXMNUzqZtOihtslPITAAPW?= =?us-ascii?Q?5V0HAfe/ItTzXRYQb+n+0l6EzQmJpufbcla2rnO+k0qtVfACwezpC7gV/Oi+?= =?us-ascii?Q?8emlLcDPZlgBIQWN3sO+KnsLoUdremeKXAxz9MEfMARmRYPbsuXy1KUgWyh2?= =?us-ascii?Q?1f/VzbDY1VrTa0z/tpT/Tzlcm4th/F4uS9fEbUrKT5YqwN+5/rjU3XDJubIX?= =?us-ascii?Q?/2Lmpu81oGQZpc+zFLK6NNGQKf/vyUZY2QzWheHF02YQoYIha7jtlZv3lUk4?= =?us-ascii?Q?cXqkJNT/8jb7iGiegPVRgDIZiu5br/YASwVx9J8xPG1hxV6QMSGq78UXSMxa?= =?us-ascii?Q?K4kroy6XdNYLjrQTwsuIv2F+kzh59NUWGrQ8Qw+QkPYAk+5sLeU0P/Lwzqpi?= =?us-ascii?Q?abkAR+vhy+7t+T8uCIWjZ4cMVeOZp0z5ZU8uuJ8lFccvQFSJGS2PfMce5J+2?= =?us-ascii?Q?MM/L0XwFn3A6/Wwx/jg9Z3eRy6HlMLkLex52v0TTkJFXnHIIriZtOEMQXWdv?= =?us-ascii?Q?0xuKzOs83qTArhxb7JvAjWKWRaQKw9cniGupIt/R0pCnpPQH5xZdE3lBuhx2?= =?us-ascii?Q?7GS1Se7FAQm4BNj4zU3L/cAsn6mzeo06nO0zAA1Fd8V22zCX+L7YyjDcYfZ0?= =?us-ascii?Q?g5xORckqR7yL23SIPIikJWMPP4Pq3KtiNHr5qCHFTeBa10Mz9OZyWLJfPB+K?= =?us-ascii?Q?jv0Q18RqAUhbnBzGmiyJbzh7dfq/GmZ6N1NMlcDZw8G1crOAyLwU4mbr4cnF?= =?us-ascii?Q?O4nCMnMJllNLwZk+wrSWvMGGIRbLkq4ajfPLm304J/pTAchIACgeKYAA0EcT?= =?us-ascii?Q?CcL0GUI5k9/rs355Hu8qk3AFeKSKSKTVPj69B+li1U/+cN4fQRcQsdOrNsUz?= =?us-ascii?Q?m2IJgvKCnaMtOwP4OesixUEAhdMMhRCWMw/0cO8UhIFsrwjMjN5iU5ARa4S1?= =?us-ascii?Q?zpjEdvkUNad3x4XvJLiX+1IXbR6A0fGhT3wIo82f8tVmcRe2SHfSzdacxS4H?= =?us-ascii?Q?itMXarNwVvHoxdVtpCaJqos6DcbobDErKxR2IfTNN+esvtqW9PLe6qU6WFU6?= =?us-ascii?Q?To39wNrwUggKzuV81iUgULiNoxvcLI/qZ95q6hRZcPioCmY3fJ+7LpglpZWJ?= =?us-ascii?Q?Bp0kZ/0wv//7tFvIqHlAtgKRmJxqAAsenok+w93CoM2fI1iIQUaGgJ/voR9f?= =?us-ascii?Q?B984yhl/1JAD7bGRlnyn9G+zjnXIl/bvnHHHXfoRWJ8dgmqlV8gvwjWL7/7V?= =?us-ascii?Q?dxZpGvUB9zm/BlFwTrhORWh82yd0v4TexX5Ua7BcckBK4rDGOPFezsMXWqKf?= =?us-ascii?Q?+neONJ/j8/u+JJDhuc+CENLY4/zfL7mFgp3TAb7wwMe6voMiuWuLVT7qQ7NQ?= =?us-ascii?Q?NCXJ1oz6LP19z3TZvYunsnOGnPKOepD6lWIEyWpXgcL9D824OrJDoZK3bqs6?= =?us-ascii?Q?s/7WJPMMkA2ONodKJ0EgL5Wpfe16fiuzajmg5kprH8+1QrGkQOISYIccj3Gs?= =?us-ascii?Q?rM/rj++fCVDxL92Nh9QkPm1NOj8qxKO8Rp9Y+TY4C/PnpQCsIA900OPgCLhp?= =?us-ascii?Q?UXKqkv7FiOZYZgKBO+Fi21YPKBiNHMlVXQoKsqk0EpQRdxgdZmQ+TRUbBgS+?= =?us-ascii?Q?4CEAi3WSFw=3D=3D?= X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 14aae559-c8f3-4ae6-0949-08de5a564a05 X-MS-Exchange-CrossTenant-AuthSource: PA6PR04MB11910.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Jan 2026 08:06:19.1483 (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: Qh5N7jKhoTKWLJQiHeBlcvtDQJtKQ3XZHDfe2jUeUPTSnDixjCzmJfUs3FNki07lIOc3Q4xFycf86mHCTtE/hQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAXPR04MB8624 Content-Type: text/plain; charset="utf-8" v4l2-isp framework only supports extended buffer for generic ISP configuration. This patch adds simple helper function to compute the extended statistics buffer size, exactly the same as for extended parameters, except that it uses the `v4l2_isp_stats_block_header` structure definition to prevent conflict with the `v4l2_isp_params_block_header` one. Signed-off-by: Antoine Bouyer --- include/media/v4l2-isp.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/media/v4l2-isp.h b/include/media/v4l2-isp.h index f3a6d0edcb24..d0a265162440 100644 --- a/include/media/v4l2-isp.h +++ b/include/media/v4l2-isp.h @@ -27,6 +27,19 @@ struct vb2_buffer; #define v4l2_isp_params_buffer_size(max_params_size) \ (offsetof(struct v4l2_isp_params_buffer, data) + (max_params_size)) =20 +/** + * v4l2_isp_stats_buffer_size - Calculate size of v4l2_isp_stats_buffer + * @max_stats_size: The total size of the ISP statistic blocks + * + * Users of the v4l2 extensible statistics will produce differing sized da= ta + * arrays depending on their specific ISP blocks. Drivers and userspace wi= ll + * need to be able to calculate the appropriate size of the structure to + * accommodate all ISP statistics blocks provided by the driver. + * This macro provides a convenient tool for the calculation. + */ +#define v4l2_isp_stats_buffer_size(max_stats_size) \ + (offsetof(struct v4l2_isp_stats_buffer, data) + (max_stats_size)) + /** * v4l2_isp_params_validate_buffer_size - Validate a V4L2 ISP buffer sizes * @dev: the driver's device pointer --=20 2.52.0 From nobody Sat Feb 7 07:31:36 2026 Received: from PA4PR04CU001.outbound.protection.outlook.com (mail-francecentralazon11013031.outbound.protection.outlook.com [40.107.162.31]) (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 D084A33EB09; Fri, 23 Jan 2026 08:06:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.162.31 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769155586; cv=fail; b=pjzUPDwZQB5xaZZmjIZ1EbYpwo60LUG9jsMOTz8/DHujzkc0Sg5+Owz2wPJkPQudJuEO7OGKPWFqMRzYN27cvpwVE1CiGD+Gq5MvYgPi9VKFq7GzUwJXn50PLQtraU2DdBDBy2T9P+u+Y8Z6Uo8CEP+KVDV63n1BTHyupEz8+2s= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769155586; c=relaxed/simple; bh=yA8mJWYUQt8QkX95vu6Y30VTaDJZwo30ECOwLiht3N0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=EUTdZ3VUiHjd0xrl2OaM/bwa0cKkfMLDHG5/5Rmjiw770bQaJ7p0WRzQ7J8aqnUzbVjYh7CgJ/vIyEhJwQKSXuEY/sW9yfccP8ENOrn6Tt0hZwYDK4D5qEjm/LGW3V8uAqS5L4EVoLqYukUPMNKkeXXY9xmW4Z+jx+z3FrI4jz4= 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=AVvlU6WS; arc=fail smtp.client-ip=40.107.162.31 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="AVvlU6WS" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=Te0m8GPt+6cT+NtMm2tkyDbixrcDtK33jYWhUFykBI2bygPrPEdHe4RlohZxmi9dRBh2zyT8DW0HUU6iITfwQqieUcsLaUZ4PzP5GO54K6nDLY4cZmglgTi1huQ4uPsIIwKQesJoJOARXdh8adWBKjvUHbtP0gnA4uNKyCUtkV1JLkY/rJZWfBLYU9EuR6kIv75kRwU5OsXOQS6Pbd0SaHxUGczfD/amcIW8w5QPVqo0wjzUDDjiLjTSlbIgbuayuqznumZXr2v7yiAAV8IdGxHwhVlbm6qu14E4ksZnwOE9PGuuh9HsmlzWZOOdtxadbuozutXB5FzP7YMay1/d+g== 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=cvUi5TFlScof0fEnlRtvFyObMHeHnfHxenbPI72oqt8=; b=siCmAHd6G3PvqNlgNXjbxlHnWfSzmQkvgosXnZrPDJQRd3OB4JkI8ryys2QEFTh6fYq8YcJUB3+AX27khJHm9142UtSKQBm+68RzIaE/EEBaoIVG6OdknefFvbhxMNQ8Zzc5H/BXmMl6IS0VEg2Qg3a4DxRIJM0C51w9R4ih6cRJCUPNzJFG+Wi4S1l7wWbWFsrDHr1Rh7BpqRMriFXyuyUbfhJJDi5WAQMRXD5kh++rRSjbngY37kJ4g+Iwk/yUT8KUECH6xoDtkdrGcTk5aKd9iq6jQxgubcVRdXKBfwJWLqAadBpE1wLkHoAXlp7fvRn+V++MmnTRaZM/EjR4zw== 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=cvUi5TFlScof0fEnlRtvFyObMHeHnfHxenbPI72oqt8=; b=AVvlU6WSf5AkxCBffAW9kSt7UK4p1hq1CxNa+VJJPSfZZx/XF95oyK9Vx7BCNcLmifluV4t8vCsMO42pZDhdQ5MiDnGgbLJNQ4j79sLySIw+Pb/jCGzES9v3gkSkNyn0kk9C6lp2EGz3eCOXeYgewTr+y7GwC3ofwha6aoFMu2bOUfjfq/UkQ4BiLLeQDlFtTxmGLyqGyptbdhgmp3ZcfDZ9j4yJydrXkwpxsSWAsuKpafyQMIsHohfPnC2/39ekRxuye0yyhFQlVUFpFCFLlJZTriWP1zjpnNjssyd72WpDqrPWWNX/MtMMX/+SfWnAqGP3bIq6DXR0brmGUXdy5w== 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 PAXPR04MB8624.eurprd04.prod.outlook.com (2603:10a6:102:21b::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9542.10; Fri, 23 Jan 2026 08:06:21 +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.20.9542.008; Fri, 23 Jan 2026 08:06:21 +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, shawnguo@kernel.org, s.hauer@pengutronix.de, kernel@pengutronix.de, festevam@gmail.com Cc: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Antoine Bouyer Subject: [RFC v1 03/11] media: Documentation: uapi: Update V4L2 ISP for extensible stats Date: Fri, 23 Jan 2026 09:09:30 +0100 Message-ID: <20260123080938.3367348-4-antoine.bouyer@nxp.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260123080938.3367348-1-antoine.bouyer@nxp.com> References: <20260123080938.3367348-1-antoine.bouyer@nxp.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: FR4P281CA0026.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:c9::11) 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_|PAXPR04MB8624:EE_ X-MS-Office365-Filtering-Correlation-Id: 2e04d26c-c574-44f2-c47e-08de5a564b26 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|376014|7416014|52116014|1800799024|19092799006|366016|921020|38350700014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?+Wzc5I60YN2zi1WyKW9dxYfiku8ozgL9NIsGVMmWCfCYJXoGYpmJatyzLKN7?= =?us-ascii?Q?+WN3lDJg5e+AvuZNswAHxX1iRN+2DffFQSyqZc+Sb5nI0KQHu3z2t8i9RtUe?= =?us-ascii?Q?9RwGFC5lsiVf3rnjCa2b7rnx3JtczPHBarl2TihIROouOljMEig0PWlcY/OU?= =?us-ascii?Q?iAJC3v+9R+PfhvnhdS+D4updky1+Lnkhv55z6srYfSCZQU4BwoowHrhGtoXU?= =?us-ascii?Q?QgsBSxgasQWeFfFmgiD8iafJe+aRtZFmwdfH1V8H0dPpOZRX1GyuxTgiCu76?= =?us-ascii?Q?0W3/B/wRqUqEPCwDqIc6cbzdklgnS3sCjsRcIEN8vO4LK8zaSrdpQlDWab+n?= =?us-ascii?Q?Ae4cJ5Z/Zs5baxSeyK+/WwSnDltZgHAG9y4zp89e0/bMQflNxV1W3Pg7BA8I?= =?us-ascii?Q?BG/QZGRh6SJOzTIHrfnf7270ZJria4o8Fbsg0QzubtrPB7rv4WUpp3szgDUL?= =?us-ascii?Q?2LnQEdZ9QJw+IoYeurTvbNOPYB1sdLuVlCy1DwGLdQb8HikP9aKRBx5pTGs0?= =?us-ascii?Q?Uhw93om+9pJ03K+8kaQPRprMK/lKDgNG1DierKiR6YROwEedELMgIdFoA79O?= =?us-ascii?Q?Lq5UyYkJiKOUimE8fpvXhMUE4VZQ28oHLo5AB7PA0Y5Ez9v8mf7G2MYHby/h?= =?us-ascii?Q?ZAjB8yhcbmPas+AKCiravj4bvF/JuA6ksj/Krix5kFcYWM33qLV9StqTDLkz?= =?us-ascii?Q?X3mgshJdPffZtgA0WHFXFyo7evlI5iw6TwEILfICXgRdfdGTUI5VEqr7hQqU?= =?us-ascii?Q?4nc0+WNKMZhDzCBoiVdOdAY9AaFjzpHhbdQNJ3zYY3dQEAfYww3QcAOw87ZF?= =?us-ascii?Q?JQH5B+wcLo28YefPKk3lAzXuhmvHmGFUD0zsZiKCH4RgaX7aVIyT1WdRjUwG?= =?us-ascii?Q?nL/RPlvirL9Uiu4bnWRXnQ+6ORzQiCtMOES2z08FPmp3kLTNfvcs2pRMwjFY?= =?us-ascii?Q?ZLRlopsWMaDknhzWIPTDE+y9CdEFYJCoXHQVDgbLK8Fu6ZG/fseS97hte4r5?= =?us-ascii?Q?lPLusiSHpjcCDD6xpXbDg8fiVpFZ8uMc7zz25L+6gxgDijOS4kDhuYuPLTAo?= =?us-ascii?Q?AC9+5w/jW9sJfkd4sWDn3QNADlKLeH8g6akM+cMVEkJCsLVCxLWmozRDJqba?= =?us-ascii?Q?M5j5+jJqapcHUGCnmJvP0/kU3FRDmiY5i2OrfWKgLLcMWTVWfhezrgk+GvXO?= =?us-ascii?Q?MdPG/FZYA1yNMc4M5VN5GQzzCRw+WExyF6jhs9Jnd6tuURaZU3gwVZoovQLb?= =?us-ascii?Q?bVS3JsLjwI6OABOCuozbJrwCz/H/NmvxjuWCFYqzTEHyEt8Lhxd7whOtHStj?= =?us-ascii?Q?wamyhG2kQnyBY3eA6tdQcL3lpsEEAuCPMjGJJaryslNnlXxKsrDu7Ko8mtAT?= =?us-ascii?Q?eAxd0/26ZM+l5p8YBxbR4kA5xbkE+4RGK+KgeYfvL9cvszfIs/rZXVLR5rOx?= =?us-ascii?Q?VuQL1peoJ3mk03ASzJgyY1TUSFnoAQiPiFaCUCkrLvnDvZQgkqJEXTEDT4Tm?= =?us-ascii?Q?JsOvuSA2/EKC6bD0co4Ne86FuRhIvnQApww2hDWzg7RmwzZjeHCwr6CHcL89?= =?us-ascii?Q?XE2PkOfHV+OMFjDV8GfEun3gUtwTZ4WCDMN4AHdvc9Mc7qTjXSgm/Wq+m4/u?= =?us-ascii?Q?Xltn5rbSC5IoiMN+Y9rn0iihfthzH5AU0auf/kYcH9dl?= 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)(376014)(7416014)(52116014)(1800799024)(19092799006)(366016)(921020)(38350700014);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?ig3jNqCdRn9geEPa6mOjUh/P6UFAWXZDWNKq+moaQWtn09369sfPKeyhSnoU?= =?us-ascii?Q?tiPZMrQGgvT9hReVtjj51OvMQYjgkl4MzDjfBwL1IEUYjZJFEyk9saXohHlD?= =?us-ascii?Q?GQJmqECKYEfHCqLVm0q5AQPEZ2FXpazCktmqwx6FCzaEE1l6SgyXbB0ghkxI?= =?us-ascii?Q?ljnzFUYrLzbsrX2djy6KxqEUjOBrdB5lMGdpqeZ7bLxhoPCnIjJtEtLR/A3k?= =?us-ascii?Q?7Cx2JptQL7G5Ruz7UDygtpSZgCWAdlgkR7WqIYFH0Z0YxAgqlghFQ5pIfedb?= =?us-ascii?Q?018fkmG31fyBJ/dmZxqcVnYjl8ftk+xp8hwbx1iNqpFgWXe8rTCK3W7aiNRG?= =?us-ascii?Q?mwvHgWJgQUXJVauNXTyopBkW+bHRkmsI4w1juTA/xMOn8BahDXupblQ3jutA?= =?us-ascii?Q?BYCMnV0uljvux5mwDWeAH4Ar7QfBiuVLSZ0Z7Ehsf6/QgLFDyboE2PtfFysr?= =?us-ascii?Q?u6dJkYjtMsrXUINw0cFgRlk3Bm7SZ+TtsCODVF3dfc3gHS038AiaOE04G5VZ?= =?us-ascii?Q?UIXDJx2G+TAQXPBpudmq/X900tGCuoy0P8+YJT0/Q62bln2Tz4Vzd59PTjIp?= =?us-ascii?Q?0ttHVZUE3k+9Yec2215ayOLaYIOmp6ZriLMXmqS3/jZ695c51wg5eL5Bm8/Q?= =?us-ascii?Q?j1ibeOemT8abGCQVcNApj5A5BGymOK2woM3JvVQnW8pONoluch7kCnbAvnMb?= =?us-ascii?Q?J4B0meHPjQTN9bOnGAyv3OPTwaRBGuue5YPKlf6IflYW2F4+njyjcpmrGDwI?= =?us-ascii?Q?02wzEeB0zJLtS4RVB9z3E9ZqxarD+cQPwLwVMxKpNFLsA/KTe0wx4Bc61ahe?= =?us-ascii?Q?eq0VmAoFoRKFMGT6qmnKl6Tb0QHLBMT4Qs3mBj5Ut4xwEpZjqV0+3tME7bLL?= =?us-ascii?Q?lLRYfx27yffQpHFbnL5xia4Pmfu8oIVjPzAiNkYX3ydYw9qAhSti5XZmtwNI?= =?us-ascii?Q?ZnyhFbg0I6uc3gop6klE9/5D8GImz53AV+gk75SQxbOV46SGKiWoWxv5Sm1q?= =?us-ascii?Q?kDba3UDV71uRHsJCryx7umO2qhYaEI6RXD8dnGUQ7hl/8PFyl1KnmHtafG7m?= =?us-ascii?Q?x8EV4Qc/VQjNfxnl9sOFc92Cof1UUOsx3/zRJdQff8nakw2zdJzu08pqORBS?= =?us-ascii?Q?Xuk6sjcj3mCyiNrfScMX5DQkJs4Wsahs51wA93/TxT7HdeYmepBZlFbarzW6?= =?us-ascii?Q?+Kx2GNvdNLnY0FYadtDehcnWqCwH3xy+lfilBnRp1mqOK1x2gL8HmTjd43Ty?= =?us-ascii?Q?H2uzPLlvkYiahUpxKRcgB/3V6BsFSsuXxYDeirYioUpin+BTSkBZaq7f7eN2?= =?us-ascii?Q?qTD9w7lJ1H+nM1UBoSmWtbtBEKbMaDoEorT9ruzYD59NV8UfkTlh0WFLi/3c?= =?us-ascii?Q?5F82oRaCANXFKjWFtc1LLCHl/yEnp+e+e1aGAc/sD7hcRJFn51XYGM/11dzy?= =?us-ascii?Q?g2CNwUPERyig0EXyttqQ3N/4Z1miy2RO7u3aj/+vE1uYCSTQxHg5nVZ/70NO?= =?us-ascii?Q?NV7Fug0AcxXn1B0cH/5zadV9+2lnhHIoTqiHpJOu03rYWqApQM1+jwGac/7Y?= =?us-ascii?Q?FLeeLe5nQ3/sI9JzbfwKwS+tmhw9RGTRCP05S3m96UExnUaXOwEaOzCcPcYn?= =?us-ascii?Q?L/h6m34W8B8lagBUiHoRMYOfuTrSb8hCXAoPpNMjK+4345wt1NbvY7ig3sYN?= =?us-ascii?Q?ttKbzDhUgh4c/VvG+gnZWlDO+9nteYqK9GEgo48n6dlEMyJv3guKTF3H059y?= =?us-ascii?Q?NrTlgvdOkA=3D=3D?= X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2e04d26c-c574-44f2-c47e-08de5a564b26 X-MS-Exchange-CrossTenant-AuthSource: PA6PR04MB11910.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Jan 2026 08:06:20.9342 (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: 195AmShFwjudS0L83y13/qkZvMBgojXeyoCOW/ein0AE9AhMYVc33ZKH6N7v6Hjuddg6NkdMTZGHBmPymR5DcQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAXPR04MB8624 Content-Type: text/plain; charset="utf-8" Add driver documentation for V4L2 ISP generic statistics format, mainly copied from the generic parameters one. Signed-off-by: Antoine Bouyer --- .../userspace-api/media/v4l/v4l2-isp.rst | 42 +++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/Documentation/userspace-api/media/v4l/v4l2-isp.rst b/Documenta= tion/userspace-api/media/v4l/v4l2-isp.rst index facf6dba1ca7..9024c6998b2c 100644 --- a/Documentation/userspace-api/media/v4l/v4l2-isp.rst +++ b/Documentation/userspace-api/media/v4l/v4l2-isp.rst @@ -32,8 +32,8 @@ types. Userspace applications are responsible for correctly populating each block= 's header fields (type, flags and size) and the block-specific parameters. =20 -ISP block enabling, disabling and configuration ------------------------------------------------ +ISP parameters block enabling, disabling and configuration +---------------------------------------------------------- =20 When userspace wants to configure and enable an ISP block it shall fully populate the block configuration and set the V4L2_ISP_PARAMS_FL_BLOCK_ENAB= LE @@ -59,7 +59,43 @@ definition without invalidating the existing ones. ISP statistics =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 -Support for generic statistics format is not yet implemented in Video4Linu= x2. +The generic ISP statistics format is similar to the generic ISP configurat= ion +parameters format. It is realized by defineing a C structure that contains= a +header, followed by binary buffer where the ISP driver copies a variable n= umber +of ISP statistics block. + +The :c:type:`v4l2_isp_stats_buffer` structure defines the buffer header wh= ich +is followed by a binary buffer of ISP statistics data. ISP driver shall +correctly populate the buffer header with the generic statistics format ve= rsion +and with the size (in bytes) of the binary data buffer where it will store= the +ISP statistics data. + +Each *ISP statistics block* is preceded by a header implemented by the +:c:type:`v4l2_isp_stats_block_header` structure, followed by the statistics +data for that specific block, defined by the ISP driver specific data type= s. + +Driver is responsible for correctly populating each block's header fields +(type, flags and size) and the block-specific statistics data. + +ISP statistics block configuration +---------------------------------- + +When ISP driver wants to share statistics from an ISP block, it shall fully +populate the block statistics and set the V4L2_ISP_STATS_FL_BLOCK_VALID +bit in the block header's `flags` field. + +When ISP driver wants userspace to ignore statistics from an ISP block, it= can +simply omit the full block, or set the V4L2_ISP_STATS_FL_BLOCK_INVALID bit= in +the block headers's `flags` field. Then driver can omit the additional data +after header, and set block header's `size` to the header structure's size= only +in such case. + +Setting both the V4L2_ISP_STATS_FL_BLOCK_VALID and +V4L2_ISP_STATS_FL_BLOCK_INVALID bits in the flags field is not allowed and +userspace shall not handle it. + +Extension to the statistics format can be implemented by adding new blocks +definition without invalidating the existing ones. =20 V4L2 ISP uAPI data types =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --=20 2.52.0 From nobody Sat Feb 7 07:31:36 2026 Received: from PA4PR04CU001.outbound.protection.outlook.com (mail-francecentralazon11013031.outbound.protection.outlook.com [40.107.162.31]) (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 15A1934DCFD; Fri, 23 Jan 2026 08:06:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.162.31 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769155589; cv=fail; b=Fcp7Pv1JAn3UBZ0Ot9XqHpmBKiHOM0HLgP9LPQqaOquQCJj+3yJNFOADdJoKJ5EkOkI/1cIYkWXuFeHDUYSMvsm7eR3VCLLBKODEiIHcj0x7Q+kWxb5ZpjuOroduiibhDN8lFcKYJPXy3iIXmUa8lK9JoRV5omUWo68Hr8cS7wk= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769155589; c=relaxed/simple; bh=Fz1b+9/Z3zba0mBQEwBcvkFi4Wn8xHUqmeJPFm5vM0M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=A+2Iz8OGPn3HKCPH5l3izqkUQv2TbyyHHOjynDh+cjA8fHtm5W3ZYzq0N5yVwWY/yTDfGSB6+V/9H/kkafkkOO/oqtBdXIqzRTNV3DjKfwMZGzJkBPyPjzC4Pp1klraggdtv3o0T5wGFO3uW0rVc9R8nHJ4AoXmibqX4JzUcrdo= 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=SfOKoTe+; arc=fail smtp.client-ip=40.107.162.31 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="SfOKoTe+" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=qZP9SigOYf5r2K+nq8RjEJ9EPYDXl8wwsBSsiyB0XxaTcnanuybEQIRK2poJBQAkVyKLBOdii+dUy7i/gKXybDkF8gGi8iL4Cudt/7MIEIfnZfWfM9cO5exMR8oCryNXLpLC+bGsM9rVTCh3BfmPq0KgyYPLW5PDQlmspGbKHGZvgi8S58BNgdlRCPtmNcYDnEcQsNXzGSWRlP1PvITlrApjxEC6nRttFJpA8qkfwnEUG+b7KtzJLDa44q0X9MveA7zHAE9JfKHC45a8rnp+MqBICSh9jonaRen6kjjUAM7S3D+afSQs5rG5tZuLWhEvt2qcGQ7UG89v2s9zRUIevQ== 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=IveoOprG3oUjHGXJid12Av2zpWUXRu/uEj2s0NVOtrQ=; b=lWR5V+lmFltVSl3KPpT1g5YrzetFZgiMhG3OvVB3RPhFUTLcs4gaQt6F1veJWhvoeDdgB4cHkpqySN8Upm3HquV7kG3Dnh4L+yo2MUZ+yXHJ0s58vvVCOGXMOA5Dxar5jJ4N7i90wes2s3MTiOzrJCm+eHa7ZGnqmt2ZECkfEeM7qtVIDdCnJL+MFRuwXsGgxgvcXdlDO3RKJqyiL4/U/Dk2LrKd4joJFdt3VTNfl+FpfPYaGVOkT/HvmIKiZejhbeT9rFJruokEMw5aUgR/sKssA5t365XaHF83yB5mrXkCVC/fD0kANLXWtdgSo5H9vuJHe8lislYf/LfPj158bw== 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=IveoOprG3oUjHGXJid12Av2zpWUXRu/uEj2s0NVOtrQ=; b=SfOKoTe+SwK3QhhJMECn67yXa1MXx1RLadj0dOJgaj9GipcdWXOIFFMKVX1gcuxDQ5EOR40dSgmqdOe3Riy4DpPsq12oYgtTR+M8kyR+UhD2pmv2EFXPAMPAHlE6en+nEGFNwzFG3v0xenifttHxoaEYghkEqf+xqb9jXzInWI76jiTM6Pqd0xOSTQFaG2DDPm/qlNx+aCvmigbi4GHNGKbu0YB9bq2FzzJKdZdCobsqYHWP5MAj5A/nMG0z9TzpzCoZZolJQHaGLCFH/VMLCk40uRmUOlFuQqBTqpv5/GXkDOml9aI9faN9hiFKY06Upb8o+kvIU8irvXV7mvS8NQ== 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 PAXPR04MB8624.eurprd04.prod.outlook.com (2603:10a6:102:21b::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9542.10; Fri, 23 Jan 2026 08:06:22 +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.20.9542.008; Fri, 23 Jan 2026 08:06:22 +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, shawnguo@kernel.org, s.hauer@pengutronix.de, kernel@pengutronix.de, festevam@gmail.com Cc: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Antoine Bouyer Subject: [RFC v1 04/11] media: Documentation: Add NXP neoisp driver documentation Date: Fri, 23 Jan 2026 09:09:31 +0100 Message-ID: <20260123080938.3367348-5-antoine.bouyer@nxp.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260123080938.3367348-1-antoine.bouyer@nxp.com> References: <20260123080938.3367348-1-antoine.bouyer@nxp.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: FR4P281CA0026.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:c9::11) 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_|PAXPR04MB8624:EE_ X-MS-Office365-Filtering-Correlation-Id: a083b261-5c9d-48af-df46-08de5a564bf4 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|376014|7416014|52116014|1800799024|19092799006|366016|921020|38350700014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?0X/us+BGRWJFdtqqpOw23phR/3bBRIdtG6/cbRQTGVC9cna+kOw/bUU1rP/9?= =?us-ascii?Q?7DZd80tHM+aXVbfGqPMMiDAUOtr+x+QXZ8r3AJKc8uGfp9ZRAe2G3dle58z8?= =?us-ascii?Q?PjkGRfkqE8giQlnQBpOzVKS/UWbe7f+wwYzBLcJnQhOUFPhvqUV6ErrTnmzY?= =?us-ascii?Q?gK5vi572zA46bjL3DHADg9gjndsqDVu1y4X+xV/efVX3ALisC+66Y9B+O4/m?= =?us-ascii?Q?PiYeg7XPDlm5ChVApz9L7H3ZVhBuIaR9rWT9thsHZ+Ll0pup1/fufIqxCDrX?= =?us-ascii?Q?5+sy5Li0cluAi8V6QvAgbzDxt3pDXALOUl4Lf8nzRyA2aIP1LKowj5saGjbs?= =?us-ascii?Q?eOrHTmGxG76Lt9K41j+QUbroNNFaMcR2Ock0gceAxxhPc6obxOGkUvblKt8O?= =?us-ascii?Q?JlrFgM78iTLcO1AKevnKUKpv0l0soua3+l8b65PaP31yA70Nv9wAJX0gLndM?= =?us-ascii?Q?nWaWWqJSMcQRlEROF/UrJrCfcaSc6xXVZaEmeXVJNPdDk2exnKwPxj4G8OTJ?= =?us-ascii?Q?o38ZMM2EVMcvfsuKZGtLR9HopXS/DmH8d84Ft2T/hHLGQFwm7THly5Epc5IR?= =?us-ascii?Q?2ADVSOxzyVjGCODs80U+fAM6Yhq3zK908CCtHtypJO2iUdFPsuBjHqTBASpu?= =?us-ascii?Q?Ny1yTJ+l9wGR1u/XY+jsJsXSHSGVn4oBxOsutSZ6/f+dhp+wkAYsSMzxuL15?= =?us-ascii?Q?+MkLTM4/L58ziKJW34jwSYrlwxi4m9hajQX+brMP8Sry7XAyZ2PTo+0zl3Ay?= =?us-ascii?Q?/ySZIRMB4F5n/gLK4lo4RR3W5rl9v+64elSKvJVMKf0dKUTwTcTCt+Mv51f/?= =?us-ascii?Q?gmtkH146kGJnlESuSGbOvbAZmUpjzSCjZI0IPcBi/RLfjiw1qjUOnXoyUNtR?= =?us-ascii?Q?e9XO0NfKuB1e4Oo8W+N7JGN52mvj812eVAINUJ4hItHwgH/10Abk1ba745LO?= =?us-ascii?Q?dQjSC9fee1xp5T6zcuU2EE8i5CLfDjKwTEGu6TnFAvuU34KrBZDx2jK3OhpR?= =?us-ascii?Q?EtggLVzwGBN6h916nmvBQsOFM7IBbyzhmYPbBLrEidxikE/lLTU7H3YSMEy2?= =?us-ascii?Q?/3Sj5PT6fKAHjQvdJZjxSzv0yyyRWrZJ+RgXXZeAO5rH6owGf/OavWljLXT8?= =?us-ascii?Q?hj0XqyC6dGScXkLDXQggdNfptc1muW89Oj21XdtYWTtkcpSHr0qmkEqgIAqx?= =?us-ascii?Q?IdTXvlN/TpPz2ZUJ8Q9IMcWGY9AgtGj2b279QRCGXSne4iucL8NkgbX2G7Ik?= =?us-ascii?Q?DBPpXsbLqQtrFhy0WV/vp7RBicjbTlm8ApEsIHPlcQL3IAn3e3iv665YTCZA?= =?us-ascii?Q?p8rooj+1QT08Z1Mcsob9QvHzqvI3xfKKpeiiGZ5UPv6zQYtZxfvftgOg/5ij?= =?us-ascii?Q?XPVWZwU1dDqyarLTQcTJSouycktUy/G83Hl7NI1sdRbpf/JORkfIDPCPLNMO?= =?us-ascii?Q?/A0RV0HMTyUUDtxBowsrYcmB1Dlev9Pw4F1CGAvOxesrYOLU5XxSMpI+3B2L?= =?us-ascii?Q?6ljCRh9sUaChyaLZPx46uCKm6/T+hGkvCaqXEm85tbCgBntp0yLUl0vOTGL/?= =?us-ascii?Q?gRjz1S0F0keB9Lfh3pSM8Z6SqBr9994TVyOp2YgkxpzQoAbMTHRm4sG5pGHi?= =?us-ascii?Q?aZ2Pt337A352TyMqCPZ6ii1YP3V2PUCPUet/4MAGOiEt?= 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)(376014)(7416014)(52116014)(1800799024)(19092799006)(366016)(921020)(38350700014);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?ZuodAPOxc6x3yCCUp0+vm7WM5rPIc5W+eY8K8D1xVOjj+ewt0ysIQ6wYoD0X?= =?us-ascii?Q?j6++5fkKQycmdY2pCt+9hc5ytUYN5q4KPn82zQLRrmbmCWnh5m5tYEbwGlUL?= =?us-ascii?Q?G/TCP0SZ1civ2GLUr2LHNvdsPovmwTTz6dZWqJVNQDqj/KY8hbH41S4J4CM+?= =?us-ascii?Q?PnM2zUGD/lXodGTWS6Ello9gEZa5FaBs4uvOQt3ht7TzNfntGBWHO7ngMsaF?= =?us-ascii?Q?MbL3E8vI1OR5IAtJlVQ0uRhJ8PCNm22Qt4MAANc+53gn+eiRSXe8ifSQ/dZK?= =?us-ascii?Q?o5aXBb/tcyAhjBMbFLwxxHBjLwvMf7fLPPutNvc9ziuXbbS3Z2AsTFSRbBUV?= =?us-ascii?Q?NNNhP2yr4ADvTD7f1eCI094a+SRp53KZwwWvqlfNqqRjB+qT9uVkHgZ/hIqU?= =?us-ascii?Q?s2tIQoFdA3LbBpXi25DzU9WRx2WDWFW1E8DA2vqM/UHmkeaDKRmA4wyUuqh8?= =?us-ascii?Q?LdOJQWTtZBKzrw4+0f+vyHt+YM8IFPGDEUV523hg/hHKnEf1HgE2mjnslmqa?= =?us-ascii?Q?7GO7RVDa+EnQ1xSs/PiV61ekYVhT6x1zlLTtRJZQxGHMYZ/wvoVY4OwTmMS/?= =?us-ascii?Q?DRM6wrWntRLW3Shvyf1mHcXLgKZ3PRME/pJqaULkn4758vCe5+B+cNVstnzA?= =?us-ascii?Q?jX8jxX5LX1BXy+3cBi1XO3Bj8dDpgEVbo5Br97muJz/jUTz4hWJXtDp5rrMq?= =?us-ascii?Q?xDEmqvZjfWqKN11I8+oBdqKC1SZ3ZtizdaLJoXZiDUNGoeeIz6k+D5+svdlS?= =?us-ascii?Q?DHzGZXh7aWGhWxPvIQYd3JcmYEx2hE0PhNS8N0Iz6jMpVxW5vbUB9JAMZFa5?= =?us-ascii?Q?C2bdFqOiKPIfkURSqCOm/TrCnzfEURhKXId5lWClica0Ls+kwJNRfUjw686i?= =?us-ascii?Q?qoRM6a53Wdp8zTtJILbP0ogXOzhGmCqPxDGy78AOPXgwZ6V8Tsbj+418xVEd?= =?us-ascii?Q?GTyR9k1nbF/AP/Fv+7YJ5yONi2p6KawgKBG0nMLueENY/GcO0ATDO2xvIN9G?= =?us-ascii?Q?mGiiYApbuZJ0hm0qwoRb1Kzv59qSpaNHJX4ODg1zO+jyG5/C8QMuAb8PzYWo?= =?us-ascii?Q?Ud3rCa79hWBFMs8V4ZMFA+mNvlL68ZQVgafqy1Fe0OW3marh/Y+8h60nlHm+?= =?us-ascii?Q?g2J9AuYsVsAzUPCJgDZLaZbXf0D+iG/n3zuJ+0nTZ2wDV03o/Lpnh3D5Mlpm?= =?us-ascii?Q?kNVHMXZMqFox/IF5Ak4nyRyv7ce1BX8gfz0dOmOGspdbq1w1FHlZUld2DDEb?= =?us-ascii?Q?1SmukuNugkGT+GSuTV4jTbNsLsfI7B0fEYw3FBdHdfXUvF5PrI5Xk+PN/j2S?= =?us-ascii?Q?4pBAX6Fx7rZAM7yPVSkuvQ9KeIXpoKnkgZvvniWm5aS9vhIyLUOFq1/NhX38?= =?us-ascii?Q?v3I28phAS6tsa8UyiaJzgDCespGYdl7GxVENUcqrszZYWKMuwlKxk4+x1l9i?= =?us-ascii?Q?goaQDPnIbmwnV/s74TMrL41LpeUPRtYXJDV4zfq45f89cdmJ2Gr6sbE9hbi4?= =?us-ascii?Q?Tqp6KZ80PSUabYWMgi63BOdGvxjCR8KjoZYf7TKTJX2YmGwCfd7wmM3tzaSa?= =?us-ascii?Q?f5xSdFenn6hkhXCkX9xmhG7IFU3iAIRaaJV2tmu8dvY2HHKChdEIZ4pvmCU6?= =?us-ascii?Q?fa1fXmoHNE8NE5G/CVpaiA8oAtEOfQ+xxthzYRDEoZ8vx9tAy75Y/gk6QGOI?= =?us-ascii?Q?UE45EubQx1z/2rHiMBVx4G+lrIRkbPZeJqm46dhiruizD7e/tYE0l4XyCSSr?= =?us-ascii?Q?SikVjx9wAQ=3D=3D?= X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: a083b261-5c9d-48af-df46-08de5a564bf4 X-MS-Exchange-CrossTenant-AuthSource: PA6PR04MB11910.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Jan 2026 08:06:22.4417 (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: dP/j/V1eAmDJbrAzajUtbZ9uQI2ugHAMjizFZ1JZCBFiRMQd7cWyHfRNmY6UZhuWkv+jyvcyue8L9mbpgLigew== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAXPR04MB8624 Content-Type: text/plain; charset="utf-8" Document the NXP neoisp driver both in the admin-guide for neoisp IP description, and in the userpace-api for neoisp interface description. Signed-off-by: Antoine Bouyer --- .../admin-guide/media/nxp-neoisp-diagram.dot | 22 ++ .../admin-guide/media/nxp-neoisp.dot | 16 ++ .../admin-guide/media/nxp-neoisp.rst | 189 ++++++++++++++++++ .../admin-guide/media/v4l-drivers.rst | 1 + .../userspace-api/media/v4l/meta-formats.rst | 1 + .../media/v4l/metafmt-nxp-neoisp.rst | 114 +++++++++++ 6 files changed, 343 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..ac0d950bc1dc --- /dev/null +++ b/Documentation/admin-guide/media/nxp-neoisp-diagram.dot @@ -0,0 +1,22 @@ +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..abcc2dc9bb55 --- /dev/null +++ b/Documentation/admin-guide/media/nxp-neoisp.dot @@ -0,0 +1,16 @@ +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..0632de6bc51d --- /dev/null +++ b/Documentation/admin-guide/media/nxp-neoisp.rst @@ -0,0 +1,189 @@ +.. 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 hw revisions are listed in UAPI in enum :c:type:`neoisp_version= _e`. +Version is stored in the Media device information, hw revision field, +accessible from the ioctl MEDIA_IOC_DEVICE_INFO. + +There are 2 versions: + +- NEOISP_HW_V1: used at least in i.MX95 A0/A1 SoC, not targeted for produc= tion. +- NEOISP_HW_V2: used at least in i.MX95 B0 SoC. + +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 by 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 usespace application and Ima= ge +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 in a single media graph realized using the `Media Controller (MC) = API`. + +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 media graph 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 `legacy parameters` format, or the `extensible +parameters` format. + +When using the `legacy parameters` format, the parameters buffer is define= d by +structure :c:type:`neoisp_meta_params_s`, and userspace should set +:ref:`V4L2_META_FMT_NEO_ISP_PARAMS ` as data= format. + +When using the `extensible parameters` format, the parameters buffer is de= fined +by structure :c:type:`neoisp_ext_params_s`, 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 `legacy statistics` format, or the `extensible +statistics` format. + +When using the `legacy statistics` format, the statistics buffer is define= d by +structure :c:type:`neoisp_meta_stats_s`, and userspace should set +:ref:`V4L2_META_FMT_NEO_ISP_STATS ` as datafo= rmat. + +When using the `extensible statistics` format, the statistics buffer is de= fined +by structure :c:type:`neoisp_ext_stats_s`, 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 393f83e8dc4d..5b6c71ae369d 100644 --- a/Documentation/admin-guide/media/v4l-drivers.rst +++ b/Documentation/admin-guide/media/v4l-drivers.rst @@ -21,6 +21,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..bcde8edcb441 --- /dev/null +++ b/Documentation/userspace-api/media/v4l/metafmt-nxp-neoisp.rst @@ -0,0 +1,114 @@ +.. SPDX-License-Identifier: GPL-2.0 + +**************************************************************************= ****** +V4L2_META_FMT_NEO_ISP_PARAMS ('nnip'), 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. + +There are two methods that allow to configure the Neoisp: the `legacy +parameters` configuration format and the `extensible parameters` configura= tion +format. + +.. _v4l2-meta-fmt-neo-isp-params: + +Legacy 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 + +When using the `legacy parameters` configuration format, parameters are pa= ssed +to the :ref:`neoisp-params ` metadata output video node usi= ng +the `V4L2_META_FMT_NEO_ISP_PARAMS` meta format. + +The buffer contains a single instance of the C structure +:c:type:`neoisp_meta_params_s` defined in ``nxp_neoisp.h``. So the structu= re +can be obtained from the buffer by: + +.. code-block:: c + + struct neoisp_meta_params_s *params =3D (struct neoisp_meta_params_s *) b= uffer; + +This method supports the Neoisp features currently available, it won't be +maintained for future Neoisp versions. New applications should use the +`extensible parameters` method then. + +.. _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_params_buffer` defined in ``v4l2-isp.h``. The +:c:type:`v4l2_isp_params_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_STATS ('nnis'), V4L2_META_FMT_NEO_ISP_EXT_STATS ('nn= es') +**************************************************************************= **** + +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. + +There are two methods to capture the statistics: the `legacy statistics` f= ormat +and the `extensible statistics` format. + +.. _v4l2-meta-fmt-neo-isp-stats: + +Legacy 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 + +When using the `legacy statistics` format, Neoisp statistics are passed fr= om +the :ref:`neoisp-stats ` metadata capture video node using t= he +`V4L2_META_FMT_NEO_ISP_STATS` meta format. + +The buffer contains a single instance of the C structure +:c:type:`neoisp_meta_stats_s` defined in ``nxp_neoisp.h``. So the structur= e can +be obtained from the buffer by: + +.. code-block:: c + + struct neoisp_meta_stats_s *params =3D (struct neoisp_meta_stats_s *) buf= fer; + +This method supports the Neoisp statistics currently available, it won't be +maintained for future Neoisp versions. New applications should use the +`extensible statistics` method then. + +.. _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_stats_buffer` defined in ``v4l2-isp.h``. The +:c:type:`v4l2_isp_stats_buffer` structure is designed to allow future Neoi= sp +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.52.0 From nobody Sat Feb 7 07:31:36 2026 Received: from PA4PR04CU001.outbound.protection.outlook.com (mail-francecentralazon11013031.outbound.protection.outlook.com [40.107.162.31]) (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 566A43542FC; Fri, 23 Jan 2026 08:06:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.162.31 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769155590; cv=fail; b=SUf89S56/aWLXLawo/zqNsvuDfvLvo0wMkR0DFtQ+2YhEoYH+im0q0x0t36wj9aKLUDW1NHKi0XcxfMyPRzWlJK4fO7xeSpbOA1CLl1Dl43/Hlq9XrI74ShyyNlqazML4HqzKw26dmuMl1+ARULeFOJDrhmhzW4NHaZvWCrP5FE= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769155590; c=relaxed/simple; bh=FLopBFZZOiTjYAvzTI0XPtR2ggJVMLk30myUxskJcgI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=PW9h21o1kxVHitoV5fcydyvSvZFsubzFG/2bAJE1ZEzGrTPQPVX7Q0WKEpd4CKymHaSD1yefjUtEzvb4jEkMXbE0LNL4WiP2nhOT9UVP0hs76cadUZAvhTHBH9SwSn8r/FD4YOjVcBhrkATQVQsZJvQoFISdB/WLFnVt+wa8Wl4= 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=cAjxTaEA; arc=fail smtp.client-ip=40.107.162.31 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="cAjxTaEA" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=KdbIDHJ/LdFhS8Bs0R2c8bRqE5TqGEBRn22YPTOA1zVFhkkFYEXQ2pXPbn/+2c7o5fFRBpdeNmQE1y8uuF+ntA8tiQn4/mikt8dMWq7YAdEtSZ8Z68tB7kBjzaYKzFNHoRSV8BxJw/iUOdS1x7norScW65KY2fzJvYWoqSxWUpcb8I5J3nBOuHOW7MIem7tcBYpaGCbPi3Wyqb6vGVtwYb5NPGdK526FDe5QQAI1/keinZq+l32Az9l5DB73EIuXvUvegL8oDi+2LdyJoC8CTYCbUaSJc6GVv7/Ok/vjzvBnCu+6iPvEZJrDgmsCXQq3hlwtyrYD6nHh2OWZIKTcYA== 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=3aChj2SbxNQQEHhSFSFBcxQW2EPd/uKsI/AgWNMQxQc=; b=lxvaiWqSCimo4H4t/crBc14lO1F0wl61haocjfvXlWOCsfhkrl1kPP7fIJq+j4MO4CHIzOYuDK3ckiUQhrIPsRmoyPVlt8QAQdiEgcro0ssEdKFso9CUyq99/jhMSmviA1qapc7vrdf7Ee8CgNBX1eF0PLJ1ab9HxEg/EmQSk6p5305svjJUCsai7h6W/utwYPM71kuv8F+xblXtJAcOks5csOk4Ekva7l6R4gMipbthyULbtv1PRhycTHmY/SJzEK0EXNyCpFB5mKe49ihRLtneLRrom7aznkpcArxfOj1XWZYZShqoY2FhPtFP+s3Sdul7mpxCTMiTp6uC9epeNA== 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=3aChj2SbxNQQEHhSFSFBcxQW2EPd/uKsI/AgWNMQxQc=; b=cAjxTaEAUAXTzpmOuaGwvEAlq+lisgRHO3bKsgZlqGYYMP1nfN2hNiJiYVlqllgx3dNjE8I39AYK9EZsLSOanrx/vYRfVx62She/cYbeKzslofw5iVa+2W3ZkihE77DKKLfc1Mx/sK57ExuiiesnIqI4qrd/9ptgK7RBGHr1DiPVLQh3zSbLgTPtLp8X0mqqdLybkAr1RYnaUpjQmCCEjJLVJ9JVGFaBjNLklJlWRZkyw500mg9Ke7yIFPWcFZxLID1SAU+wpcnFYnhwWRhEVEbspDNjl+5M1BDkrQUVqLeBlIRTUIU1/CkSyxBGaQMTPHbfTYrVFuv/Tnfosc1vvQ== 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 PAXPR04MB8624.eurprd04.prod.outlook.com (2603:10a6:102:21b::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9542.10; Fri, 23 Jan 2026 08:06:23 +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.20.9542.008; Fri, 23 Jan 2026 08:06:23 +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, shawnguo@kernel.org, s.hauer@pengutronix.de, kernel@pengutronix.de, festevam@gmail.com Cc: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Antoine Bouyer Subject: [RFC v1 05/11] dt-bindings: media: Add nxp neoisp support Date: Fri, 23 Jan 2026 09:09:32 +0100 Message-ID: <20260123080938.3367348-6-antoine.bouyer@nxp.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260123080938.3367348-1-antoine.bouyer@nxp.com> References: <20260123080938.3367348-1-antoine.bouyer@nxp.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: FR4P281CA0026.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:c9::11) 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_|PAXPR04MB8624:EE_ X-MS-Office365-Filtering-Correlation-Id: 09ff73f8-49b6-4433-7413-08de5a564cca 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|376014|7416014|52116014|1800799024|19092799006|366016|921020|38350700014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?yNEdYVCq7yyKzVwgDW3TfY3vEqS7sMMcHCDR/wp+GspeYU+UHq4UAobCrEPN?= =?us-ascii?Q?xEERsnvF9F5wbSnnT0RpjviRoOGGCJh41GH5g6BGtcC6RXihrgmk1DMeHwmD?= =?us-ascii?Q?OQ3wE04JFv+sV2eqEnV7hlYt61d1cVFLpxsIZ/NRmfRZDss46M+zWNNRJFYc?= =?us-ascii?Q?KrDYef9ESX6lykLyw+wezaCftPtaqyqk/xycM3eLOrFmpWlBDoFKaOdEIAMc?= =?us-ascii?Q?qoSrN8pmD603yq84tv2+SWAHGOA4/rb+qBEWKg4PCOMxi4cNnhE9+gDJwuey?= =?us-ascii?Q?ts1qXAuzuiw6EsmGdSukjWp7Xo+RB8Pp9bunq4eNmJhb5rbEtdEM4S+LR/cP?= =?us-ascii?Q?ESSn7E8Qe+W2A1qftyM9cbvfALg2D0UG1UZKMejao5pcZt6pAU3Q4AXEAGVr?= =?us-ascii?Q?RTCzkJW1TioUbeF3O9lvoM4YngS7MtYH53NHq+sjLoqB6zJ1fA8NWhrsmJLS?= =?us-ascii?Q?m3IbrD+HTjRYKMQNUx7dxMCYKWVejcNERXX6KN1giTxSnIjf4UdWB47n6J+6?= =?us-ascii?Q?yUUlo1q89QgHqZ6ESBAEW0PefRxuR2FIwnIToxe50D4zYDC0JVFlNcdegRmi?= =?us-ascii?Q?QPO/NFK2VPJbRnM7sd+BTEBs+u9DeuGXkNfZbaSfqnVkNF1iQFwb4DGwBORQ?= =?us-ascii?Q?kQ6+SKjVixcIe3X/HL0qLltTvBSbzrgnBT/FLEWr9LNV0UP6YlgSXMj/I6iP?= =?us-ascii?Q?udErfWin0AdtUCVFuNrAyPmJ5JRBiFeYo45TLDNXbBdEIeWN0DsygEhtlz7g?= =?us-ascii?Q?2/Kd98E3YgpxcnZDerF9ihRZG0x/5oRsMS591Odkhm3WzyL3SWpAYeGUjhZU?= =?us-ascii?Q?+xLhSZULKqFOZUVsEYjTxeMEOSticvENqd197xDQHN2ieFm1Pr17zgHpQm5G?= =?us-ascii?Q?Ub5rJc0JpMfSqKPvN1GaAXuevyNhGUtPOSfr3mOFq9TIecCPF2dciq+HoJWP?= =?us-ascii?Q?fdH2+FqvY1OCF0RDjW9e43ggJsJXV8ekKfrN1n70CysDFDw4KCkwKLMWdH2s?= =?us-ascii?Q?eJPb+BCvnrcma2GuboT/ABmcvAhRAHQZGdyymaQYGNTm0a7vOgJkO6J3GPeP?= =?us-ascii?Q?83h7eC/daiiZN4f21rrQs2oNWErmd4k0lFe9Yfj11SQQOE1lCRrGsW3N+uAT?= =?us-ascii?Q?FNNXh75ZnYL8mF/kM/KnrPuG3iqmNfqdHxEd1Hbg5+5xdY4QhDuMJCNvyRkn?= =?us-ascii?Q?3wMl/TwHvH/AWvshzZtOVaY+/uO8Kir82ZOCifNZ7/VZZt8hPPfCuIqWqxQS?= =?us-ascii?Q?yTECZO6B4lQqhSq3iQYbx5HVRosRPvtgq66lowmJm8BVJWlvUFZJk5SusPcu?= =?us-ascii?Q?nZCHouQH2byfm28yXw6kymBLIYJgNiucuHeS5i0NzQ1eDXlcRCqBsUhXYRvv?= =?us-ascii?Q?Sn78Y7qYnM1JSSC84ms0NRgl61DgeHklqHeQ4aKVeatTii7K1/0efmrwe3r0?= =?us-ascii?Q?90gWb8jCLAjeu/02afQIQ513fPZjugIG1GwbbsOp0kTXkS2LvCyIDU8lSZ8B?= =?us-ascii?Q?Qc3PAYhOR2KJtG1uJ9PR2TjAjIYM+H8dEV2webna1tTVRTteswi+ymACf8p2?= =?us-ascii?Q?C3MsJmkYpn+VNLDXYi9WBm1BZTEaom7y0EG3tJrrBGOtf6e9l4Qwm3GCPhYq?= =?us-ascii?Q?lQ=3D=3D?= 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)(376014)(7416014)(52116014)(1800799024)(19092799006)(366016)(921020)(38350700014);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?MBbHTrXja19qdZcGbO6NhmPykLvH5FOtqFWAtgSK6GUKE7Ukax/gMQKa0n9o?= =?us-ascii?Q?JVsEY6Tx8MqYFZpoA/p5M52MGuvV53PchhCNBcStUPf1auaybRN6kUhiop7u?= =?us-ascii?Q?/NDb5QGyYVaQQTBNgkalBwmPu+RqtebVNDFlDI/y8jwlxhjbjrkT0UOh00NG?= =?us-ascii?Q?B+se6x3LwBIoJRdILXupdOQfEx3suZFlwrwnoE3Xcw6oWtkIBy3NZNr/hzph?= =?us-ascii?Q?fTFVRxVGu67CdcQnDvfax/vcp4DKo/OQ2o2D9yzL72Pmv/pvz1P/t4o4ToL6?= =?us-ascii?Q?4OdDrRVU5DI7P7P71TGXFANQVpM8ZmnPBlXtySGEZA60O2kFJdtnBQKPVI0H?= =?us-ascii?Q?cixFP01VDFH1viGrgdKRDCwt4gqP/jhWZBEoFO4L+9iDwcVwVoWiqUVLK6er?= =?us-ascii?Q?9ScpVc9UuDOb54Z/XGzbFWh2F2KNBUqKxVR8WmRrfOySC/uB+ng7Rm5J//4b?= =?us-ascii?Q?hW2cNuQQ+eKXNlB+oZLw3K0LAuSVfccuaw/Rtm3wb6coZUGbi0/0/DX+0AXp?= =?us-ascii?Q?fpqrdppN5PMIecbqgxKhRPldXnaoVLijk7nu/0dH9tmKN9GzeB9mJYUUXBE0?= =?us-ascii?Q?cVn4SP5SaiiCuuYUV9alOuwbjNDg6r1DauUEXtnSGkvbLMmOBWI6fi0uY3ft?= =?us-ascii?Q?qm90OoHFYAxDcBAVAvU2YfcpYny4paT/Bt4yYre20OWICuAEKhM+gR+/zWKz?= =?us-ascii?Q?B9nYrfIxGv2Q5uttNn7qqNA4Ht/r4ET+wCYVF0rdnCDTb35+owFE0m1yC6xx?= =?us-ascii?Q?hcWEHv/M1+m3mZR80+MzJtQvjMya+Ob7t5XedUPqUydjD34Zi1n+yB4fTr0r?= =?us-ascii?Q?SJ4Fs3ynudOSxHGYTKb2/ptlHH1OEefXRp7aSDHi0dLavBtKeqRXd4jHcKKZ?= =?us-ascii?Q?Kpko7ycRUkN5/mq+G1J8GH6KImtKogSBjmKb3r4FOTIIojJAfUxvK7bPzbNY?= =?us-ascii?Q?QyA/Q3VB3AmmzATvFl8f8vW+9uiq41AxEXXJhOU0vNaIDXEHU3ZXomEvTlaP?= =?us-ascii?Q?lBU7blAhzZDsyznRARZczumMCLpZ8h6oOY8z7fMMThLQ3pKhALUuHQ3zOtej?= =?us-ascii?Q?tUr6pYVd94bXjIzY8eRqfPFxFl3B7ReHu9dcuX0DHhIGnumK+g1tE5H2qIuu?= =?us-ascii?Q?77bsplqWLgaAWYATY+p155tHfE//l8HOmLBYWdZtiyBzvvjVOlyXCB1j9YK2?= =?us-ascii?Q?pQZ5+BgI4LVMahBxnKZaOXOmXMsFSQNa+K9xuSVBz7tsYJEdH8w+epBID1D8?= =?us-ascii?Q?3mAtJiXskXC3JyU6mtTPg5FIuMD/gr7bxOptU7EkPLO1xrWPAwYY7dxWrbFF?= =?us-ascii?Q?ciHdX7sffXATNUquR5wWxzCIJ7dcEY6ipM/BzgIodZBYV3TcDp87mT5cavnQ?= =?us-ascii?Q?sCV6K7Fh+NUBYZOEjGSxfHZms+ivUI6GDhTlUESfLHAVxZbrR1OL0rl7BUtF?= =?us-ascii?Q?P6Xs1yxxGM6Fw75TU/4fZE3Gaiqe2DhLQUz2/T5G169LTUEdNTREdvwRSb21?= =?us-ascii?Q?ZteEYVN1iMhQ6eY1bx6OyyVUFRvaf3Mwwo2hfmRTTwrwPoz1whp6AloRzLye?= =?us-ascii?Q?Z4Nj/bpFOBg8Z2uAxed2xJaq1YJwuLQCmPB1dhL6eFoMp/cdRwWxvvk2SK6+?= =?us-ascii?Q?LMA3j7iCvbwUT8L3u8OvBSaB936s91HarrwrTv9iCrolFBE0Ufy/UDtJdNAa?= =?us-ascii?Q?oauob059mW7wog7UsKrtnNMyyVXq413l4swLL2vF7uBYQZAfXishZHtVm+vS?= =?us-ascii?Q?uw5V1MRCbg=3D=3D?= X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 09ff73f8-49b6-4433-7413-08de5a564cca X-MS-Exchange-CrossTenant-AuthSource: PA6PR04MB11910.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Jan 2026 08:06:23.6807 (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: utIuQbx9XpN/qpzbzAIhhDlUyD7B52vZHFZVwmVgMd6K+Z+liK9MSHHEQadhcRzbbP43Fi8ZJ3O6g73BejvyBA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAXPR04MB8624 Content-Type: text/plain; charset="utf-8" Add dt-bindings for NXP neoisp module. Signed-off-by: Antoine Bouyer --- .../devicetree/bindings/media/nxp,neoisp.yaml | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/nxp,neoisp.yaml diff --git a/Documentation/devicetree/bindings/media/nxp,neoisp.yaml b/Docu= mentation/devicetree/bindings/media/nxp,neoisp.yaml new file mode 100644 index 000000000000..4dc9fa5a03b7 --- /dev/null +++ b/Documentation/devicetree/bindings/media/nxp,neoisp.yaml @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/nxp,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,neoisp + - nxp,imx95-a0-neoisp + - nxp,imx95-a1-neoisp + - nxp,imx95-b0-neoisp + + reg: + items: + - description: The configuration registers + - description: ISP local memories + + interrupts: + maxItems: 1 + + clocks: + minItems: 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,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.52.0 From nobody Sat Feb 7 07:31:36 2026 Received: from PA4PR04CU001.outbound.protection.outlook.com (mail-francecentralazon11013031.outbound.protection.outlook.com [40.107.162.31]) (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 2D6B535CB8D; Fri, 23 Jan 2026 08:06:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.162.31 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769155592; cv=fail; b=TZBkHcgUD0br1JlDfAGodAIFyWniOWvdcRNw8CqOv0no/i4jRyen5xpx4Wns5D+xbywLx/f34wmoIpl68g3mq2q1p4fxFIcDkeO/+jFtafkkTobZYA/h7HU5d5SijVymnwMZCqDS1kDeZOnT1Q2V2tt+sN2tCKquxBFcGCoM9vQ= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769155592; c=relaxed/simple; bh=5AdoobAH29s2pXPZeQWQo19uuOQ5ELqEYNhcvi0Ndok=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=N8mZSEqphi+dLmCAI9qrTSiI1vLkUVBd7oMuvG6To6o5r73FgL0rmIyQAkEPW5nlquFVHrzTXyd4n6hsjw0PIs6mX05K0ryG4JpJYlHhFkCgrNILUsVv5lhYjcWz7V4ngl1R7m+2dBbAI9OmOmwMfLr5Y1bHp9iLFj9p6ghEfsA= 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=Hp+z7Nak; arc=fail smtp.client-ip=40.107.162.31 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="Hp+z7Nak" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=PpP+gunfY2svC5l3/FtUu//zpV/lS3GS9xbgElPzk71Ai/Gr+Qh4qVXKKA1w3Lxi4OTsWbXIRtGMIw93w5b6QmlANUrYaIgAY/lK0ok6mJ2mVvIIPIIGeLU2HUYvMv9leHaRBTgLhoqq36QKuybeDYHUGJO/8413N4mpLYP84Tptj7kWqjkmhMDHDNM68+xBzC5KDROGifysZRVh/z3qqZ33nnrhtLS1UFMgwO1YiD3KMf76S29ttFoztWGdu2xB7Tu3OL9TR5ojGvW7cWkR9OqIqFkraj0ruTcqA9rKkqFnEdIV/kBWlNrRhY4VboTrmDQY1uTRDu6nUexl58Knhw== 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=ClJukCw7buNVm7qYcWHNun39CV79NCBXix7pwRj/Zc0=; b=ChJ/MYj7C7xqjWj71Oqfk2CGJyQj5I5m7OMTkml2Ss/u16+e6gB8OrGEotuEiFPNgeax2K1iEeNYu3BvN5Q+TjOsJ4oopJyrQgmTr4/fDBs8+IARnmRPSZzs5T/Ke+P0Dt+AXetfRBCLbqyoB341FBapIRo6e5KX8CAVopK38igHtaHnEW635ByN18NWSdswLUNwYUvcxywxLjjWZhYv9EgaU2BKjZP9avAfcl8bK3XZUnUAg6pZmKyhDy7M+WenI+wvDSwhuQVZ+9feHSHDAie3NGqHNacnm+uGm+PUV2yyE9+AwEK6zn5VLZJsl9EuPNUEzzoSrmlV+5yR7pAnEw== 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=ClJukCw7buNVm7qYcWHNun39CV79NCBXix7pwRj/Zc0=; b=Hp+z7Nak3S40ieCnc5//ZcLU2cx/JBpmEKrl9EK+BivsrRpFYLHYALx+9af2UOiTsEB5TAxN8dy45P13Qjlxdvi60Q/jnwubcVGSwx5eWD0tkAYWMciVvWzopnYZQN1H1BLnM43hCB2/AbSRCEsc6WHFL5HtD2d0+0OwDOcNR3qXMzKFuBe89QEkrLwOVeN04OFaTQKJiISaN6hep9ic9t6eBOstKVKP9KK2a5cZrDzJaV0JcoU6pxW9uMVglKS+wdUGQR4wTj32LDhNSzaRrJMLwQJPUgW4ytkFsWvoWkxs//7KSEequlRuAFHHD5LvQyKcWoSkc3s47lEz9nQPoA== 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 PAXPR04MB8624.eurprd04.prod.outlook.com (2603:10a6:102:21b::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9542.10; Fri, 23 Jan 2026 08:06:25 +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.20.9542.008; Fri, 23 Jan 2026 08:06:25 +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, shawnguo@kernel.org, s.hauer@pengutronix.de, kernel@pengutronix.de, festevam@gmail.com Cc: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Antoine Bouyer Subject: [RFC v1 06/11] media: v4l2-ctrls: Add user control base for NXP neoisp controls Date: Fri, 23 Jan 2026 09:09:33 +0100 Message-ID: <20260123080938.3367348-7-antoine.bouyer@nxp.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260123080938.3367348-1-antoine.bouyer@nxp.com> References: <20260123080938.3367348-1-antoine.bouyer@nxp.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: FR4P281CA0026.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:c9::11) 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_|PAXPR04MB8624:EE_ X-MS-Office365-Filtering-Correlation-Id: b34bca29-b976-49d0-1cf4-08de5a564d8c 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|376014|7416014|52116014|1800799024|19092799006|366016|921020|38350700014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?ryM/Pw8L4hetK077lNA+QWyFbQiQdLRAA7OPMwsrvoB/qSRI8VdP70mHaBPT?= =?us-ascii?Q?1JCDrZIQY+XvD3j6u0os7tk1/DpaiYsyJkvqhHzCL5F8MdHPiClWZMqmaNCb?= =?us-ascii?Q?jsxpdzBBEzSpvmT0Cs+3AsgALKrePI4QkOgH9zIbbODNI88cqpZaWgllTJ+h?= =?us-ascii?Q?yj+1nuCFAtsEhaUuAAVaZQU4c8S9h2WkfX1e1ktdMEJ5NM52HaFzsUeYSW1b?= =?us-ascii?Q?iLbJLGs/gTlC9FZ3VdlqICxxDzloDO04Z/hmDSZWXensy6QyU8530LzM6pXo?= =?us-ascii?Q?/zBluzz+vP+bhs0WSWK89ej8jVcrTQybGhnXk/AIxeaUVHdGWNGiNiiQKY7G?= =?us-ascii?Q?dwRfF31DY3MlGqG+BccNqFUkh8U1eLkdtXxdKjEtw9BZBMgQshfN3DTH202K?= =?us-ascii?Q?aPGpCFxBYm6J52nxSM1HEF0QOUM0PxMUkU5BxKnmpOKbNReOdOq4wHD3Bh2C?= =?us-ascii?Q?WF7ceyj5gUGjyBH9dN/yDhi2dnopkVS6+47V56ElOh4sNWf2mmaz3hN3Dx9+?= =?us-ascii?Q?cHhGq5B/jVtaeJ06z8h1B7EkaHf7mptJEmtMFrN+oq3SUML+BJvHexwTDrUp?= =?us-ascii?Q?7/Mgw+BWHbYQwHjzYwYqZWrTs/Hx7eqv72qh/ATaZBGGtXRkyRKvKWinCgRd?= =?us-ascii?Q?cWJX6oCec/JShEOLJ+T2KzaLbWaA9gAYPpP01hYB/HH+q61k1CvrGvykbD+X?= =?us-ascii?Q?WkSi94Q9wFvP3lmp9WzHE52VHk1IDlWXjdSsZE1Z03hcmxigNMYMZUXztS4u?= =?us-ascii?Q?Q/kmJIyN+g8GCHZ+v1AFRTKHhpva8O/alb/4wtK9Y/tikyAmSuXhgR9Hm0Jn?= =?us-ascii?Q?Lfqy/JIvrlCN+ZrXCOzMCTRljThaIA+u53b4vZGvfJ6pbXkEbtqlgkAf1Ch7?= =?us-ascii?Q?Ot7NhAjuaHBFofGhL7Kvb6XDuYh6lvYwvgbaMkksU3WZmJ2L5im0ZRCs4C6+?= =?us-ascii?Q?aNILRqNXJpyPzgdC55eUkBLMkuvW8V9dFkdmWpX6N93QnctVtQfoIgrVHeFQ?= =?us-ascii?Q?EK9liffJlZmoh6RpHMjSugm95+MvtpxCOIzb0b2klNcsFFaSPP9yVFv+zx+4?= =?us-ascii?Q?//OY3+XY5Cx5665ELZv+RAa5s5Da74zgE0YTSkjSJSvwMnKE8pvKgKzoC5lp?= =?us-ascii?Q?Z0qRUXkxRYuaS5w3+9jhoyjt4qE7hbFDc20RHKlg9z116n/BF7hj17H6jN5S?= =?us-ascii?Q?tD1Uyvg9YavCrCsmUEk5lztG2CUQm0kA+0gaSJExMp3cr96vajp9K7Iw5p2Y?= =?us-ascii?Q?2mV042VO8aUwvyZBKtQ5nLvLUzysm3fLfRHIoO6iTZTOsWXpHrjAEl3Z7fE+?= =?us-ascii?Q?Z7JcDaHqfpYbz5hhu1j7Nztu3TNtfXDnnwNmELTWGQwg/CWGO19/zozKUZcK?= =?us-ascii?Q?u/PfgJvtmHv8x9p3LecjMd6+JC4DpIq6UlnDKjaAOZKlLzyEbjdzd0fi40Jk?= =?us-ascii?Q?1EhAB7BL2XQ3J3D805wY/hMNsvNw7qsj44nJxugNtkZWSmGfvC0ZBMHXArl1?= =?us-ascii?Q?EtotehT6ipWS3d8sTh9AGHFgKT7wnsguGlWpJbD6GQ/yns9oNjihgDCS5tI5?= =?us-ascii?Q?kyOux+PPaiU615/YfF6V1kzL+gnFEOZLWgACtW4qRCyb1XvG2YhaOBRC5gFk?= =?us-ascii?Q?dHc5fMDZjRu6ZAVEzyjxB3QA6YZtR/0bHtQgP3VEoy4t?= 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)(376014)(7416014)(52116014)(1800799024)(19092799006)(366016)(921020)(38350700014);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?ivQmA5Xy27NRGXZdhBt/EEd6eGxXG+abzPpT0y7SzH0L4gxCR23YDbfQdaJI?= =?us-ascii?Q?IWfgL7O9iz90XeW7W+AigA9KsclQoX4K8GVGCD1tCV4S4MtgbmDGCe7qXaPc?= =?us-ascii?Q?eNem+RMsksHfHbfYm6d4dEpHAUq34KRnhaqqsSeVtR3UoxhzZP3G3rgRbyGK?= =?us-ascii?Q?yUVmL0piPx8+WOKap+KM2Js/iY0a4xB/nqv6eIDUcYpK17p7vQvuhdSaJyxY?= =?us-ascii?Q?n4YQi581L9QaOb3+bpKUT52M7Ga8OAyL1sJib/zMk45+aaQWMh7QHNuQZ3fd?= =?us-ascii?Q?akrmKNrzvxgUrN9za0/Tv/pCHHRlac4IgMZSHehc0QyV79x2RXDjguEYnEd6?= =?us-ascii?Q?VPVSsRrDllCTyXLwP58Z8P87PKA81zoN3Jihb+hdyLIjN4h/KNIJEkeyEuNk?= =?us-ascii?Q?5mgTifYip0PtRz2YdQ3shYzgEahN4G6qnUCNvmuFpHApyPZkmDMQ27lAN3k+?= =?us-ascii?Q?H8xyCvQXQj+etOMxnLzAC1JskRFwHQNdW4fWKXFUjzw77PfNgbIS/ai/wgh4?= =?us-ascii?Q?GZGg6eO8o7Wp//f9y8T7UyErIO+dJ1auDfNCcyf0M2A6WqweuNSx4yDDen2i?= =?us-ascii?Q?tJ4ExaJq/TibkFBnCsF4kM0NIxmvIRw8OyHVuieSd0p3fts9PNFM1/BJt9wY?= =?us-ascii?Q?fUNbbupEeCc1UZQaUQhmt3eL61wwvM++2UBL9KQQ1AFVoUNmJ3rCb5rdvP2/?= =?us-ascii?Q?5gYliWuPXkhh4YJLHHxWcMuIha3txzei/Wh6KCbj2jRspUvM0KU57q7PkDWA?= =?us-ascii?Q?qhrflSy7+Hv+5e7PBuKohPpzJFwkfX6uNQGw51I9cr+Cl68OLu7vNVcCJa3v?= =?us-ascii?Q?fuiIX2MM/a3VR5MU/DrUiLUMTnjoGOh2GRLUYmDU4fmzzdEREjOkxQrssst9?= =?us-ascii?Q?Q41BMxFh8H28NGXh+Hx6pl/4t9z4iDJStJ/pnJaLtT0izZ/3WlRywPqdk/xW?= =?us-ascii?Q?U6+/bq7Aox4RfIVs2iIZdh2Rr8LeKL1l8/ehv7DulYw+WhVUEBSGJlE+6XN/?= =?us-ascii?Q?n67Xx/51nTcKMYFvLh1unkQaI2jFHhYBw/DENCfz/sNNOiH0/sdetRTwcHps?= =?us-ascii?Q?/i9a4M0LiV7EPJ8gK/xVaKNWsy7C6HNjIBmim4w3WbqrvEHyK3PzVHswoSaC?= =?us-ascii?Q?Qrxqwx0p8gr3cWCaMguGlrezzLaD3Tb3D7hfwRTl0pamBPzikc4VPsELkauv?= =?us-ascii?Q?pbOvNLDKA8xZXb1/YfB+3gLUPIHe0GKXav2AJCQg4k+hHnNCkO1VBVRO3apx?= =?us-ascii?Q?1Oi5ou/t6xWFiOF3PbADMlk6RFl08n1tDJ6i+Tt1/b2vG7Dd5yQlfIHu2eOK?= =?us-ascii?Q?HDpulXDXKepZ0E37D3RnY4agzNB2hKaHLKZOT0skaX6A21A52ot2/FLBQiou?= =?us-ascii?Q?DCCmro4B80wB5YT6oI4mvDbSDrPsuLzq2oHn9GdaNINocwqAT3kGZRP5JZWb?= =?us-ascii?Q?jdGKrIdoQ1vuSwZ3WyW1zbixJYnSJgAvYlFFWU1VlpJjuNZJGG9r0odFbbyC?= =?us-ascii?Q?VVj1MU44Y8gvQiHuA/O1+zgOkRC1OEtSSeWzhIH6d8+NYo2z4L8lPdaec8dm?= =?us-ascii?Q?gxaOJSurMgGlfORt0z2KCfklO9uXajES5kI32EclpJ2ELO3k5s7CumejsOVj?= =?us-ascii?Q?JV6L0HDYxcouCMLiwFfm38cNs4qDrmDVkzW5rYu0U8pEAXi/KBY8W8IgGGAv?= =?us-ascii?Q?rLCeQ+UbSaNSZ01V/3fJrPIRCepBd9aPCmvfuDoHiRXbafUXhl7MjuSnN0AC?= =?us-ascii?Q?WxPCuY82VA=3D=3D?= X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: b34bca29-b976-49d0-1cf4-08de5a564d8c X-MS-Exchange-CrossTenant-AuthSource: PA6PR04MB11910.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Jan 2026 08:06:24.9768 (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: H6BNMxPRE7UF3K2AN1p72nz32XZUyRFSmNCANNu0Fk7hb/FiFJ48Xw7kcYUs3gUag95z3C2+e6sa4Pa2n8Hw/Q== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAXPR04MB8624 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 572622e4535e..e4d3c07fcd2e 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.52.0 From nobody Sat Feb 7 07:31:36 2026 Received: from PA4PR04CU001.outbound.protection.outlook.com (mail-francecentralazon11013031.outbound.protection.outlook.com [40.107.162.31]) (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 1A08435FF62; Fri, 23 Jan 2026 08:06:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.162.31 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769155595; cv=fail; b=QKm89/W8pp3XYaoN4V1dDoIVDZWgY8Yy7UG3UUMGm+uzBPqctLgV0XWSqbRfGyLDuD9KON08lHqEpaAp2t2zS0P0zw7uuvkUheLDLCTj66pT2/raQmktp9qoBpe6R7ZVj0RvAk6OMwZgdPr9YPhK2enx6Q9KE8Kr9de7AOWotcg= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769155595; c=relaxed/simple; bh=8qcmiAXAfFhRzOcdzw6VYCAVs1GvnuvxRgWznf38Vog=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=Yw8ns7AIQJ9HnpD7Rci5GzL6WSDboRVgLIi2KSbkvBD0F+FEeSI7cS9Xb/OHFlOalop5LDYvN4NGgQlnvXvms+6qYWdr2S4M823ooFrrT60a4kT38PCH+k09hGLVx8AwKUgzA+n7TSyTCdib8j+hPV4Sxb71G1dM5KWdnh3wZYg= 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=F78Q8KnY; arc=fail smtp.client-ip=40.107.162.31 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="F78Q8KnY" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=bwygi4KSoExah3NQ5UDAXJOc0D98pjx1Zozsdji2dsUglj099kjb5GD8fCJxg5CqwSWRe1nRbICLECPhk8LS3aEJahTS+dk/ZOIP3Th4ZhINN7jx2YsZ8KSZ3+KVSSyIqWB5Yd/90FSFn5+dYrwAB0Zdx4DVfo7QJfGB5Xp+u1uCUs6ZNAeBWLyEPTM1Tic71gLgjCSut0su3FmkpOwtFeUOczHmBZx3/uducgjo3tIfdkBAYDS7JOK1C/pvIIDvUSLKlVJEgLRLwP8utR+d2sC3PJk9J+PhDJNmYU5nBm60OUGIcVFVjDGN08ThnostQ6iBiVdX3252shiHYafh6Q== 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=D5qLtTr1raItO4ahuJoWddqFLI+ABdy8cAhkgnBCyg8=; b=Hk9KR6ehETM/fs9ukXktsq8gEgpySwNhQvBgY6iivBKIamE9OfpwnoO4PVMHpD8wM91/jr+7niNqkPLKy+OCdyZRBPh/RwHvd2I+G+QohRDjOwJmZTTOAJG7ohfBqY/x9qHyGluX01EmVGBXdUR2TT4d5kEUI0vxU9vquwJfc24TVbMzpHGK6gqD9XXdExJ2xF7MZau8i/ex5X8jtxThQ13TpVijfzikdE/7lvPV3jxVWUxgk/rJfYysHIzjcRPERyVZLdZCWr9n07tYj2Rz3ss2r9ZBcAMbo9uzcj5iAwT6FrmIsmNLEGwyrQlEE5nBMsEIGw9UTeYbd3e/178zVQ== 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=D5qLtTr1raItO4ahuJoWddqFLI+ABdy8cAhkgnBCyg8=; b=F78Q8KnYOm5Z2doxJ8jelY/VCE6pZsTN9lkqz8TixXf3FI/YNi4dIq49AsWriW+r31Q/6C6/pWSnYABxYW3D7hgCLGsbdoQQx2xM78xKhz/5uuXe7+foH5SBcAJ9LRUJEI6MmwJMFjIT1GhCJffyfmL8WFeaQKycgR8L+tS8KbZmjHmVrahNPWy5Cp/0IDXQrDhbHR9IqMKrcmU9trzigLI1a0NpdG+dCU28bU8HiJBiC1ZECSeS40aBDt9Q05pWie30OI4yLtJNyU8Kl1S3zfoYGyPMtvC2D+3OCK9y8dEDs2O68N7s7ugSiByeof5+AKd4osZP4BBwzbZgcEmtgw== 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 PAXPR04MB8624.eurprd04.prod.outlook.com (2603:10a6:102:21b::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9542.10; Fri, 23 Jan 2026 08:06:26 +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.20.9542.008; Fri, 23 Jan 2026 08:06:26 +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, shawnguo@kernel.org, s.hauer@pengutronix.de, kernel@pengutronix.de, festevam@gmail.com Cc: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Antoine Bouyer Subject: [RFC v1 07/11] media: Add meta formats supported by NXP neoisp driver Date: Fri, 23 Jan 2026 09:09:34 +0100 Message-ID: <20260123080938.3367348-8-antoine.bouyer@nxp.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260123080938.3367348-1-antoine.bouyer@nxp.com> References: <20260123080938.3367348-1-antoine.bouyer@nxp.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: FR4P281CA0026.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:c9::11) 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_|PAXPR04MB8624:EE_ X-MS-Office365-Filtering-Correlation-Id: a535eeb8-8426-4c0b-e17c-08de5a564e4c 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|376014|7416014|52116014|1800799024|19092799006|366016|921020|38350700014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?3uySMottksfffAKaWd50TYl5oD6FFTV83EnQJa/yvSEgL4QzAXLucspvtMkZ?= =?us-ascii?Q?oaDgG0QEhsK9DSdKx/eWT05183mOG9ynhRYh86M/rUMyENxXz/GPrRHRF24n?= =?us-ascii?Q?j8GRbkvqErH4RXg3rDooV05y3QjPwQd0lMEbVLgoOD6cS3ndp9QrGTvijKM5?= =?us-ascii?Q?LdQtLey4gyWSbQ1JGn3UxikOuIr5/1sMHDS3XbM+KZg6UClOnTP7T2gCXYHy?= =?us-ascii?Q?jr7rMcfcYayaC/F+SKe+qJ0B1fg8FY+S6qd3Q9gtgnB4MXr7KQsY5Yp2pcDb?= =?us-ascii?Q?o63LthcIqzf0/WrT7tAsHxWUEmrb2obdMVncnm+BYtYnuIeh8nkg+YoljSzc?= =?us-ascii?Q?nZbGKufW1bv7gvIP05CQV3Q7i8/OlKyTZG8WhjmjdEObHbZm8vhykbABx5If?= =?us-ascii?Q?PkjBEcsGtwtSP2yVw6L1u92zVz+CzsJJHKUURZGJgz6OPJg9IMVLyojTyb4M?= =?us-ascii?Q?HriTI7Lr0z+a06bKpGih+JDielKinM31XqJIfs/ZLPBXtDS6nZAipF4sNtCz?= =?us-ascii?Q?gnA17cW+ukSkLdTANb4lFWiTa2lZMLKoiFDlh5h31us+68uYJIdhFGxAmj0A?= =?us-ascii?Q?uXUDv4oG80K7Z6VpJrj8CPds3p7v/gH5SqW5FIi/fFHaK94f93bFsvn18DCl?= =?us-ascii?Q?jh7Mvmi9D1Wdng8tXvTEqUkaOy31Dmll+JQeWn4rcf8s0PQRhDXzBPxQt/qP?= =?us-ascii?Q?4h3+mgzUhPhF4sFF+z9Y2TKfWRouSBnGHgo/Ljua/yIEfhFUsjzWzrtoHUpd?= =?us-ascii?Q?sHr/1TLFG05D63J1uD0lR2K1JbKjrXMg6ETBeIwNpuGxnZEk1UgkJKD6fFnE?= =?us-ascii?Q?Nikd9kSAsAZpx7YyWG4QB89P2RWAxSfl7avucYFoUkz5W+x/Tw3VEXBebUMR?= =?us-ascii?Q?XwDqgqsOW1ZfKrOwfLj0xM9NdysM35sTFlUMlxRUMsv3X1BNZ2/YpD1U08iZ?= =?us-ascii?Q?Aa5Q9edD31gqRHUaO4oYrwHPy+wS2yk9hBv6EZbRVE6Pb0wTxNkT9LU1+YBb?= =?us-ascii?Q?laFmfH+vg+TdIK1ZeNQgC07SY1MpLBWCS9tRYeeQeq6kJxj+AF5nsvYLzWti?= =?us-ascii?Q?DEKPwMB2g1sgzq1QMw/BibK9zZ/4mPLTyKM/kyPKvUG6MqQ6HDogn1oeQOH+?= =?us-ascii?Q?4pKzn5Drah+Ie/wc1QIsKCPF7xx+nt+fgjMMW358rjHczbdAGIVVRNnfFKV5?= =?us-ascii?Q?f1eys9h67MVdynk8+G7CFhx540Kq0JmCFKWCZSnkRq1nssObJVC4Mpv5UpqA?= =?us-ascii?Q?3q+GWz2jXbIu5uRNr9jRffp0JlQXBl0jat7WwL86jIXgV90c/ZDC37vfzg5U?= =?us-ascii?Q?xFco3gFyuF4dnE6Le1BiRYRfErHiwl8xP5OY3qyjGO5SAPBq6ftOxq2TYTjC?= =?us-ascii?Q?q0xYKr2ikaVopwMRsY5Eofi8DuzKO1CMaYc6CwvfyRLRgrMlUleJgLZIeZi3?= =?us-ascii?Q?xiW9b1fthJ/cVLuiTvQ/lhBA6Z24O1WGjLWV/oj+geXVApCmj3+0rnrmUBii?= =?us-ascii?Q?h7hy9M08F6SATIh7f3RNXTYOWgJZnrc/vmHyMC8xaiblS8ShQodrdpRv/MqO?= =?us-ascii?Q?uAC8wP/sAufQcu/Q6sxXksYoziEyZKMkcI7te9zXK7dpmYoxkS9PhqzLlX0a?= =?us-ascii?Q?Kq7t6CP0mjhgH6LygjoZqh2eTW/giX6q/cQQqEqxAeks?= 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)(376014)(7416014)(52116014)(1800799024)(19092799006)(366016)(921020)(38350700014);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?twEhgGEp7f9YlkZ5oJYexSapuamMVnvpxX/9I+milwZzrFE2PtVrK9tc8D/d?= =?us-ascii?Q?jTo8B6tx+Y1kMzY1OKXq9jitDbgNdJl92pXZZMQWKWnV4Bjas7HXLJTCrOOu?= =?us-ascii?Q?MiMOZ8VAwd5OBWz7bt+UJtzVXXwGcvtm8H13NFYHNlikY6XACmRqFZqZP7ie?= =?us-ascii?Q?7YrMXngKyTHVyy+XXm+IkSleV4Vdo5o6ydNu0mAXG+T/XNi0nrzM6ZXllnt+?= =?us-ascii?Q?0X62xC0jI1YX86gW2WgW+bnP8abHu4vH41PDAIZgsLVamu4vU3YbpEByBQxr?= =?us-ascii?Q?xXJoc27Gpb96NLBscrxKSxeiYsCroLXKOaKD25I2LmV60V4EHh6CkQGaHPxv?= =?us-ascii?Q?NiaJ3lRyLRbjMx1TPKcBrhR9noAEcE6rBaayvCcbagmPjSI1fT5EYVa4hSos?= =?us-ascii?Q?kFeVbB/CIGaBB7E/w+nOx1K4lAwIm20n6fBeBlGmFuavoU2fqLny1/IiegK/?= =?us-ascii?Q?zLzeT7atqw3ixggHlMifDLhpp46PfMxS+oQY5d+fsiuYzqHbRxsBsBb0DEaW?= =?us-ascii?Q?Xc1bMD557nJlcTW2mUtIFlvu13E923jMirHC/HScUAUm4nlPQYiRTNupsV5e?= =?us-ascii?Q?gr0uOUOnzbb5dKZ5qZh0yJmUfeqRoDQ/9COBT782flMa9OzGPzdsHndkysLN?= =?us-ascii?Q?4InQGlrayd11twazVPrDih8RkslL0CWkwcP4vS8QPT50MDcA/QSCL9Q2V4uI?= =?us-ascii?Q?5tKIsAyWW1YUxz3eSJ4VZbllcR5WvII+hRysDxYC6JxXXEAUAj2srLXkgRu1?= =?us-ascii?Q?lKm2dfEYkbqKkPLw3KCijHbsa4XynyQoDOAUCfYnY2TF1D6pZdTfbOhTGjEP?= =?us-ascii?Q?SP3FRdC2xDT2Ib74l/p0khOrnU+I19gf6xTCtVWJhUddLb8D6G0TgXloQ8Db?= =?us-ascii?Q?F5Re1mdWZhr8vmDcWzrAZleujnwDs1UzLr01gQHrrTqsa2RrW40LQp3Wtryg?= =?us-ascii?Q?cWzDCY/RNvrQJfcBVwRKGXzeRssSXSTP6JQGz2d3u9ElkSVzjfaLHoZiii48?= =?us-ascii?Q?wsBOUDCnKrnBArlhO/wqaRT3T0VR6rY5IzZcSUjIn+9iY4BLJpHhyUzB1vk/?= =?us-ascii?Q?l8U1frcmmCBI8HF8Fxj+mBHfIOUZPXWldJ8mQP9F5rn9hf954rZUF0JdJacF?= =?us-ascii?Q?A/RGn7p4M4cvNAoU9ZGzs7jZbLg3SvTnmZ16FdctnKI38Nr6Szip1SHR7lTp?= =?us-ascii?Q?gDrsjwOu9eSlz7PNN25IVNDhTfdJITN2S8Pn2Zoc4z7xbEr25SKDg7r5bj2/?= =?us-ascii?Q?qzYHTMamndQlZceA+z7dNIUWR0I3QfwSUfoWhjPSuBlIMFp41WRrTTSjS6+L?= =?us-ascii?Q?m1oSjTWFjfInIyKOm+GIzd46GuLT3/ZS6d+o5SOQ5K268qkwRoX0IeupBbpa?= =?us-ascii?Q?j0IbWxH8zGL07t8nq7/UvccqVO7gSzq1oSNh26F0ON7KkANXSBVcONPdzdJl?= =?us-ascii?Q?F4A0NtAIueuPkC9MJ1drwStV1EAeBkg6lsqa0Hb6HnkvaJkmQ4X5LSgXLl8b?= =?us-ascii?Q?hCFca2hwfh+8hG9W0j6+zqAxo4Bt+y15pprlnX+QIw0TzXqIVQ9Gwmd8kvSt?= =?us-ascii?Q?mz9QHMSpex2o3qN+GlcZL/y1HLKA13YP0je0YZZElOQKSJv4mMb6OixFpB5H?= =?us-ascii?Q?bp+xfhEIbYfacaXqwr/RYTcTBt132dkQoJR9fWWawHvGM2pV5CRl9BQvs1dC?= =?us-ascii?Q?zW60zXggT1rGpYwF/r+lfW+uag/zMfuSDlpqX4EgNtqNH2EW2D8YKzBbmxmX?= =?us-ascii?Q?5eoJqBBBsw=3D=3D?= X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: a535eeb8-8426-4c0b-e17c-08de5a564e4c X-MS-Exchange-CrossTenant-AuthSource: PA6PR04MB11910.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Jan 2026 08:06:26.2824 (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: pxjdSR8P/ozXJXcc5p769GbzPPoU0PvXFAGIdsX27a/7Yr2o0klBZIr2Q2pAVML6iX8PGguv0cogi2q71NWiaQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAXPR04MB8624 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_PARAMS` used for the legacy fixed-size parameters buffer structure. - `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_STATS` used for the legacy fixed-size statistics buffer structure. - `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 | 4 ++++ include/uapi/linux/videodev2.h | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core= /v4l2-ioctl.c index 37d33d4a363d..c797cf11be38 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1471,6 +1471,10 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fm= t) 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_PARAMS: descr =3D "NXP Neo ISP 3A Parameters";= 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_STATS: descr =3D "NXP Neo ISP 3A Statistics"; = 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 848e86617d5c..5f4992452c66 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -889,6 +889,12 @@ 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_PARAMS v4l2_fourcc('N', 'N', 'I', 'P') /* N= XP NEOISP Parameters */ +#define V4L2_META_FMT_NEO_ISP_EXT_PARAMS v4l2_fourcc('N', 'N', 'E', 'P') /= * NXP NEOISP Ext Params */ +#define V4L2_META_FMT_NEO_ISP_STATS v4l2_fourcc('N', 'N', 'I', 'S') /* NX= P NEOISP Statistics */ +#define V4L2_META_FMT_NEO_ISP_EXT_STATS v4l2_fourcc('N', 'N', 'E', 'S') /= * NXP NEOISP Ext Stats */ + #ifdef __KERNEL__ /* * Line-based metadata formats. Remember to update v4l_fill_fmtdesc() when --=20 2.52.0 From nobody Sat Feb 7 07:31:36 2026 Received: from PA4PR04CU001.outbound.protection.outlook.com (mail-francecentralazon11013031.outbound.protection.outlook.com [40.107.162.31]) (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 4A5E23659F1; Fri, 23 Jan 2026 08:06:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.162.31 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769155600; cv=fail; b=e0LG9x6lKXwemKD60fn9R6Fgn6NhPY0NDsvIf16JQiOGNoVwroVoDDZvB6hGR8PnPCldV2WdBLKGESHtC/NbHGyOVJVijroKBnGnFqmRXTK0o6JknSz/skD5QwedBWxiPVnRxUAJAxGybm0F5qdt+e0vb+d7pQ5NQ/2IYCZBUvs= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769155600; c=relaxed/simple; bh=DiOGD4+lF6bdMdOMM+NwcKseLLx+cuq60ufd1JM0EAU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=PiwiQgz+KzYlnW+5aiiW06YGAuvNdS4YZfWUrrY710xzabbJD2Fv1rYA0NdFRqJELkfA6K7cjuzjUYxnKF007pxkVRwe0SCOmCeE72oLm+1eadzk2fiW//VzqPKz2ynQ1KlERMICQOCFg5W1CVx7KDZVIQPSczs3JNBpuWgYiqE= 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=LHsrTf4B; arc=fail smtp.client-ip=40.107.162.31 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="LHsrTf4B" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=btSe8bkmaOmkRRHXjLxIxujA4HwMUXBA4Vv5Tvw8w13jimTJu8reeKsJHf+6eqm9oT/dE22nvF3dGl9W8afCS3Jn3xDNNpg1pUX7sjVXkipSFX5f3JyoDIyONqdL95ELk6ZPsT5q/XEowfKAobGZejFuG/NnvWOPvTD5lS4c0RF4Opm9FS52lEqcdOEAyJzq3XNiipUGQHVciFFZmug9ZKFakRjJiby80QSD0a1/yGmSb2fMaawmG7VUQlb59mjLMu0P/1eDAtqV0+dKAnbicGFFTT1e9z9ZpQkJ7xvdBildwDFMYgnVtAl/v/wkVx0efIQtbIkd4LfqFhyov/9PVw== 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=QbkVna9StJH64YeJacAlLh6t9RMiGc8k0ikrLN/7VF8=; b=fNhXxqFqmABqBIEgPwXFBZamhhxpibpzBqnIoREa+f42pcj19/UU1BPMB/LtoM0PW5ETGaHGrrBe7+6Ht6XuVkASftKe7b9XUbVkeZoRC/GoCE0WVgTXk0Aa6GMV50daq2d8kybZoQNjIV7vXzN/IEz7pVvf6t5tewkuN+g2L7M4xvicEEWpd0P6XIge9Y588lWwltRfylT/X8tFyj1qgsUqSQknNyCZ8ZQtIgwEqxNuIXaFGrS2eVLEEEfdJV7XnLEitZH7yeJy7ZEyTPNI1nN8c5g8uC7Hh6BJCLz2q4z0LpXKPcon4SwFB3CiPpip3maSR7hMZo+WsBLxxxekdw== 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=QbkVna9StJH64YeJacAlLh6t9RMiGc8k0ikrLN/7VF8=; b=LHsrTf4BpDRJYntD+06Zvn6bPJ+GueUokMoM8pNJjAjEuJX5BGfP0BpT1qjUJZ1XnlP2N8CTu+KHM16Z+45zEN+O7/ofhtHherzlI4aJKMqbFPwk4/5w57qLfCX0NWDMcatv5C8ArYbZuAbapN+kM7AKlPTPEpXNmkeBQIrF0UPdu+/Pzlb7b28NyMIh4RrN9OyNBjx9Nz0rL100RDGohg4fWR38SlVBq7he2vSfsMDvpH06SF3kWznCratskXUFbWwaagXwwvfKOVZdVUj2WQhf2PzGdPft+PNUgjKtXnmTCjkDCijTBNy1hwh0gW2ZfUyQN7a9pKtRIq5HANGY/Q== 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 PAXPR04MB8624.eurprd04.prod.outlook.com (2603:10a6:102:21b::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9542.10; Fri, 23 Jan 2026 08:06:30 +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.20.9542.008; Fri, 23 Jan 2026 08:06:30 +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, shawnguo@kernel.org, s.hauer@pengutronix.de, kernel@pengutronix.de, festevam@gmail.com Cc: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Antoine Bouyer Subject: [RFC v1 08/11] media: uapi: Add NXP NEOISP user interface header file Date: Fri, 23 Jan 2026 09:09:35 +0100 Message-ID: <20260123080938.3367348-9-antoine.bouyer@nxp.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260123080938.3367348-1-antoine.bouyer@nxp.com> References: <20260123080938.3367348-1-antoine.bouyer@nxp.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: FR4P281CA0026.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:c9::11) 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_|PAXPR04MB8624:EE_ X-MS-Office365-Filtering-Correlation-Id: dd0c24e5-48b4-4d26-c0f4-08de5a564f22 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|376014|7416014|52116014|1800799024|19092799006|366016|921020|38350700014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?9zGYEqc47T0qcF5jEjGsZkvjedHX8UilUEebcQvCMPHGpssZptpFn8X3+F4M?= =?us-ascii?Q?pnbJDalyxVTuP2hlQg+BiCmLmNyIwaCpJrG56wZU33kNhG14u3WU3ehPjwQP?= =?us-ascii?Q?EMe5WIDMew8mwAWis6hMhoMhJgjLy3EvMisFisKQDR4E59zLehHCiJwBfObQ?= =?us-ascii?Q?ZtE/imXndUHkTH8tSS/M5mSxCG0BWC8jOB9Wx9+oaRFD0QBn+sgoyFsrc36g?= =?us-ascii?Q?CAkJcDit7zh5nlOqr+hEQpR7xi03PDhu7GeV8XEdSdD41HVAVb46CrbO0Z7L?= =?us-ascii?Q?Op8YRh2qLmCZw93upTcRJ0GTQE4TPa0FSd5MHcmc6ZGwnIiP6QOKZkRnoC40?= =?us-ascii?Q?9Yc9004HjwMe+HMgY3tFXgWA5x6gHRhJXVtmFtXojcgiDj3M79KVcfXoVZDR?= =?us-ascii?Q?Vpsc3kJP/m6wHFUsUMIjeNEFeim8zOkS0Eq0mT4E4MA1h/Oif1kQF1NbRdmg?= =?us-ascii?Q?lEJmWNkbqOcruW3IpfX04oQHRvO3uncxrIFNrLtVMH7XXkPTds+3PwaV+I+R?= =?us-ascii?Q?OdIdkDWu/uaeicRRuuBznplTrJ98dWUmXpIFiGoiyNk5bATvtQZDHPr5gG62?= =?us-ascii?Q?t2bjCrClkeH2cqXqAJyKorqscoS/vCWmwQA1QWIW9VPJHC0oz4zJ3YWD8v8j?= =?us-ascii?Q?8ruxsLM5PslQcpAfNRtrnPoVnf4UIwzwSj8PypyoLDGYMajqBNCjb18v++Bd?= =?us-ascii?Q?1IG+ilNszUgOOC9buDfvlLVohvvEj4Lj1JwKMAkFIKQ0OA2UjTqQUl1DZgAK?= =?us-ascii?Q?qO/D7dx0bYK3c6U3zTYmHvzrp7x4RsYX30BARx7WeTf1V4/LgjMxRn58rvah?= =?us-ascii?Q?auOKk9MEBEjV9GW2IZ0CLmy1LwiKGypLk13w73hpxnz3kVeV6ClRmcKDSUsX?= =?us-ascii?Q?Ni/+PUFinVHfSYknTF0NACzIaqWZwBOUnfigMEzHAcL/kXt6JVe6JcXRnMv6?= =?us-ascii?Q?nVqTkF7dmTPi4Voeidm6XHJ4w7rf6bLBkIEDXpZZt19B+omGCdnsxPe8uaGy?= =?us-ascii?Q?tisS6berKtAyaSpqAIRBfZifWJgMVu4UrYRJjPTyeoqHpG/gVcBz0wBaiphz?= =?us-ascii?Q?hTxkeSSHpGSKKKrMqd7PFAQaDeIbR5Saj6IEAq13F3mDIJtAp+EBuvKI8Ej5?= =?us-ascii?Q?M9wHiiOt5H2ZhWDeVRe1ZC7nBzauBsdoj1YQ5LxoPl0TG8AEzU2pHu4xys7P?= =?us-ascii?Q?Jh+X24bA2W3z2Tl3tdZoqzy8nJXnFhEwvVVPsQmOUJi4LFcsGut8fVHnwFkl?= =?us-ascii?Q?No6CJ/T2rhRLkh1IVnd/6C/bFE8yEAQHHb3uvYRRjlw19BzgxHay0R/dGjA0?= =?us-ascii?Q?Gl9jtKR0GClpJLqvC6eSaTmRI+bg4DEzNUPYGDg7+gm624EtIGam9xCNs2hp?= =?us-ascii?Q?m5jo6+mhrlrfMQBZgVwkz0O2mqcNpwbzaLklSyLUlWbRkLjtComJ8FoCf2hI?= =?us-ascii?Q?T7YUjgKR1D3V8OKfMtTBwtfGWpTYZNBMWQXJQjLlhqlVhGZmeMTu+hpbumNU?= =?us-ascii?Q?rksScmjHZii0wqiLdsm6OsRasgNDSbHIggDmLSWFZbG14+EIXUph5f8REjUE?= =?us-ascii?Q?OWmIemq+bngnLrXwmP6pYghy5VO/xgCW5HY+duZXPa3VFST9U0ZrIXOmyyQa?= =?us-ascii?Q?DqpcR/ySeLW0GUf9yKOlbWfuY/1xnLaHarkR7kDnsDrU?= 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)(376014)(7416014)(52116014)(1800799024)(19092799006)(366016)(921020)(38350700014);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?i20/5UzNbbTK4TzvkeXtgX2QIN8HxAX5iXdTkLeS6hhAGIBPZKyhXQlfem+7?= =?us-ascii?Q?1PwS4NYSolJ9+NR+zbv3q/WHwaX0mo6oEU1eQG9veFhLB+IajE3/a93Zzm7h?= =?us-ascii?Q?nIWZhkttu4foZZAaLedYsTS5aW5n/3oB/ZST1B552ciw0c5QFT4OIrOVOCh6?= =?us-ascii?Q?6eMN9pC7oVAWBORnN8StFexq82v6ZpH7rNH6P+6Uu/cEVbdJguBBgi/j+xb3?= =?us-ascii?Q?ADuW6gHSh8yCnbL+XA50X7L+dEY4ui9JiA9nbSRM51TSHTQ0LmE2dnAo7KPr?= =?us-ascii?Q?WgDMuOYay0WhzNNeW5aUNxiDU4akKHuQUfKcU0I5v7FKPvVOLWuODe1ixqZK?= =?us-ascii?Q?SbQlwRtiKjjMfjgOgpU9FKzRX67sb9GZwvbuBIcfU9mhDZ/zI2RF2W+Rs7cw?= =?us-ascii?Q?ipXavC5tRpa8nT0DN4zz/Bir0ih+bWQUd8hrCtaWQl56k/vNHDPxK/WziW1K?= =?us-ascii?Q?0ucKoUT8vOpyYavmC6AUny1c7hsUZsQicI4ktFweFmgaBB7SDM7TOU5DfAoc?= =?us-ascii?Q?Vh7NXzkB/qJF1Cvcw/gKsX0TbF4RAqBbcZVe1rDg/QH7GBFNWKU2bmDUkwCj?= =?us-ascii?Q?WtbV43x+9ysPzzORsQjhUu8tj3Dnww3SeV6o0C/eA5vFiTH0YwJ9VqMlpD89?= =?us-ascii?Q?/anhdogwRxDSr1vnVgklBncy7+wQL40SQQL8enApJYIRgo/BCdKTiXvHnWRe?= =?us-ascii?Q?9+JDKYk1YD33g0+yvibNnWhxo2ci1EtKS8z1bYuAxi0JIY/2geqW1JtfuCBR?= =?us-ascii?Q?FGllsNbSKBMqhKmYI9QLr2Ls4KG1vVSvmsII/+iBGIprW3aKvc+5RjjyasOm?= =?us-ascii?Q?euIe+WEtLTOEWVlGLFxx66NPNrHyFCy+XjI7iqVGQ+sGZ6HUkYRWf8x+e/AN?= =?us-ascii?Q?C/s78ZWT+1HP/7Iuvbx93SW6VLWAY2tXnBD8c/T0lNw9wotP7wP48C4qFsyz?= =?us-ascii?Q?0c1SYqm+hbzHqxbb3gPjW03lH9Oi0CkeJ8ABK169eWEcBqY5F4RvwxCGay+R?= =?us-ascii?Q?DmDNg9DCy4FJk5qabOMy2RdtZlkOToQ8fnxmmqydusgm8Y+0opX3sJRpYkll?= =?us-ascii?Q?K4R/W73v6qj92EoAHO3p9fb2bjnHG4L3x85LdZf6+LyIO6OGz6aQymFCt82J?= =?us-ascii?Q?Rt2tY819XuhKcKAt8NCpuBiVczFhgVn1E9lwosYL0GOReLq8IGwXHDwCLuv6?= =?us-ascii?Q?enj3vemJx1qSrYtvk4kFLUuC984N54gnf0sj3nZlnIK7QVeTlyp/6NDomWMU?= =?us-ascii?Q?Io+ZypR9wWBu/AANJUONpuhwIBoClSt7lNlwoEp5JPTu0tXzInDOAHJ4SuBa?= =?us-ascii?Q?UXmWNKoUXxwPfAFuKVZsQ3NolTvkmVfTVIcLCkbvfrWdouSDxbrBkOdtDgwD?= =?us-ascii?Q?E5adEn92G29FIBg5AliZ0ke2z80amY+gwiOxAXF4EFJJ3dTr3HA3GgtBSDRW?= =?us-ascii?Q?XiGeCAz5DS+RtrXqpayhnbEh0Wg1odx/8eB9Zg5TVdzAzPnX5Lc9LMfzWIld?= =?us-ascii?Q?zg+K/glf30qbKiDIx0BXeqMgh/W7JCUACvMsfW1Vg+ExPGP0BCFjjD5rKXIb?= =?us-ascii?Q?jDZ/x16II0u38gHree7NUdDR0IEIQsEAd1qAoUsacym/CA5okVXSCHhlnusG?= =?us-ascii?Q?cWV4HO5hJET4R5xLxZkkhJzj5eB5llsUGfzyksH8gNVmp2mV5wRC/1Fbk1OK?= =?us-ascii?Q?Z1HCd9n2hRyQk12jBTpPtINlwkTxIb1B9rtxhSoUwYc0YakwkzHZ7JZwy9zT?= =?us-ascii?Q?1ecRsi0jFQ=3D=3D?= X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: dd0c24e5-48b4-4d26-c0f4-08de5a564f22 X-MS-Exchange-CrossTenant-AuthSource: PA6PR04MB11910.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Jan 2026 08:06:27.9510 (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: d8EzcepXbgi4bZfCOi4lDoBYDekMTCoXSa1zCIXGbX1XrASGjTdudBlRLif7CpPuDu2lwdFo+Xkx9M50wRKWgw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAXPR04MB8624 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. These 2 buffers both support legacy and extensible modes. Legacy mode is a static fixed buffer structure, while extensible mode uses the v4l2-isp generic definitions to support various amount of ISP blocks. Parameters buffer uses v4l2-isp generic definitions, so as other ISP devices (rkisp1, mali-c55). Statistics buffer uses the newly introduced generic `v4l2_isp_stats_buffer`, which behaves the same as the generic `v4l2_isp_params_buffer`. Signed-off-by: Antoine Bouyer --- include/uapi/linux/media/nxp/nxp_neoisp.h | 1968 +++++++++++++++++++++ 1 file changed, 1968 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..186973a1a6b2 --- /dev/null +++ b/include/uapi/linux/media/nxp/nxp_neoisp.h @@ -0,0 +1,1968 @@ +/* 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= + 1) + +/* 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 + +/** + * enum neoisp_version_e - NXP NEO ISP variants + * + * @NEOISP_HW_V1: First Neoisp hardware variant used in i.MX95 A0/A1 boards + * @NEOISP_HW_V2: Neoisp hardware variant used in i.MX95 B0 boards + * @NEOISP_HW_MAX: Neoisp maximum variant index + */ +enum neoisp_version_e { + NEOISP_HW_V1 =3D 1, + NEOISP_HW_V2, + NEOISP_HW_MAX =3D NEOISP_HW_V2, +}; + +/** + * struct neoisp_feat_ctrl_s - ISP features control flags + * + * This register allows applying or bypassing each block parameters. There= is + * one bit per feature block: + * + * * 1: Update - settings in associated configuration block are applied + * * 0: Don't update - settings in associated configuration block are igno= red + * + * @pipe_conf_cfg: Set 1 to update the Pipeline Configuration unit + * @head_color_cfg: Set 1 to update the Head Color unit + * @hdr_decompress_input0_cfg: Set 1 to update the HDR Decomp0 unit + * @hdr_decompress_input1_cfg: Set 1 to update the HDR Decomp1 unit + * @obwb0_cfg: Set 1 to update the OBWB0 unit + * @obwb1_cfg: Set 1 to update the OBWB1 unit + * @obwb2_cfg: Set 1 to update the OBWB2 unit + * @hdr_merge_cfg: Set 1 to update the HDR Merge unit + * @rgbir_cfg: Set 1 to update the RGBIR unit + * @stat_cfg: Set 1 to update the Statistics unit + * @ir_compress_cfg: Set 1 to update the IR Compression unit + * @bnr_cfg: Set 1 to update the BNR unit + * @vignetting_ctrl_cfg: Set 1 to update the Vignetting unit + * @ctemp_cfg: Set 1 to update the Color Temperature unit + * @demosaic_cfg: Set 1 to update the Demosaic unit + * @rgb2yuv_cfg: Set 1 to update the RGB2IR unit + * @dr_comp_cfg: Set 1 to update the DRC unit + * @nr_cfg: Set 1 to update the NR unit + * @af_cfg: Set 1 to update the AF unit + * @ee_cfg: Set 1 to update the EE unit + * @df_cfg: Set 1 to update the DF unit + * @convmed_cfg: Set 1 to update the CCONV unit + * @cas_cfg: Set 1 to update the CAS unit + * @gcm_cfg: Set 1 to update the Gamma unit + * @vignetting_table_cfg: Set 1 to update the Vignetting LUT unit + * @drc_global_tonemap_cfg: Set 1 to update the DRC global tonemap LUT + * @drc_local_tonemap_cfg: Set 1 to update the DRC local tonemap LUT + */ +struct neoisp_feat_ctrl_s { + __u32 pipe_conf_cfg : 1; + __u32 head_color_cfg : 1; + __u32 hdr_decompress_input0_cfg : 1; + __u32 hdr_decompress_input1_cfg : 1; + __u32 obwb0_cfg : 1; + __u32 obwb1_cfg : 1; + __u32 obwb2_cfg : 1; + __u32 hdr_merge_cfg : 1; + __u32 rgbir_cfg : 1; + __u32 stat_cfg : 1; + __u32 ir_compress_cfg : 1; + __u32 bnr_cfg : 1; + __u32 vignetting_ctrl_cfg : 1; + __u32 ctemp_cfg : 1; + __u32 demosaic_cfg : 1; + __u32 rgb2yuv_cfg : 1; + __u32 dr_comp_cfg : 1; + __u32 nr_cfg : 1; + __u32 af_cfg : 1; + __u32 ee_cfg : 1; + __u32 df_cfg : 1; + __u32 convmed_cfg : 1; + __u32 cas_cfg : 1; + __u32 gcm_cfg : 1; + __u32 vignetting_table_cfg : 1; + __u32 drc_global_tonemap_cfg : 1; + __u32 drc_local_tonemap_cfg : 1; +}; + +/** + * 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 + * @ctrl_enable: Set 1 to enable HDR decompression unit, 0 disabled + * @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 { + __u8 ctrl_enable; + __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 + * @ctrl_enable: Set 1 to enable HDR decompression unit, 0 disabled + * @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 { + __u8 ctrl_enable; + __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_enable: Set 1 to enable HDR merge unit, 0 disabled + * @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_enable; + __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 + * @ctrl_enable: Set 1 to enable RGBIR, 0 disabled + * @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 { + __u8 ctrl_enable; + __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_enable: Set 1 to enable ir compression, 0 disabled + * @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_enable; + __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_enable: Set 1 to enable BNR, 0 disabled + * @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_enable; + __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 + * @ctrl_enable: Set 1 to enable vignetting, 0 disabled + * @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 ctrl_enable; + __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_enable: Set 1 to enable color temperature unit, 0 disabled + * @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_enable; + __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_enable: Set 1 to enable noise reduction unit, 0 disabled + * @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_enable; + __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_enable: Set 1 to enable edge enhancement, 0 disabled + * @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_enable; + __u8 ctrl_debug; + __u8 maskgain_gain; + __u32 coring_coring; + __u32 clip_clip; +}; + +/** + * struct neoisp_df_cfg_s - Direction Filter unit configuration + * @ctrl_enable: Set 1 to enable direction filter, 0 disabled + * @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_enable; + __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]; +}; + +/** + * struct neoisp_reg_params_s - Neoisp parameters accessed over registers + * + * This struct contains configuration parameters of the various Neoisp uni= ts, + * located in Pipeline 1, Pipeline 2 and Denoising pipelines, which are ac= cessed + * over register address space. However, not all register bit fields are n= ot + * available from userspace, only the relevant parameters are present. + * + * Userspace's algorithms are responsible for fully populating each block.= Some + * optional blocks have their own 'enable' bit. Driver may omit block cont= aint + * if this bit is not set to enabled state. If userspace wants the paramet= ers to + * be applied as expected, 'enable' bit must also be set then. + * + * @pipe_conf: Pipeline configuration + * @head_color: Head color unit configuration + * @decompress_input0: HDR Decompression for line path 0 unit configuration + * @decompress_input1: HDR Decompression for line path 1 unit configuration + * @obwb: Optical Black correction and White Balance units configuration + * @hdr_merge: HDR merge unit configuration + * @rgbir: RGBIR to RGGB and IR unit configuration + * @stat: Statistics and Histogram unit configuration + * @ir_compress: Infra-red Compression unit configuration + * @bnr: Bayer Noise Reduction unit configuration + * @vignetting_ctrl: Vignetting controlling configuration + * @ctemp: Color temperature unit configuration + * @demosaic: Demosaic unit configuration + * @rgb2yuv: RGB to YUV unit configuration + * @drc: Dynamic Range Compression unit configuration + * @nr: Noise Reduction unit configuration + * @af: AutoFocus unit configuration + * @ee: Edge Enhancement unit configuration + * @df: Direction Filter unit configuration + * @convmed: Color Convolution and Median Filter unit configuration + * @cas: Color Adaptive Saturation unit configuration + * @gcm: Gamma Correction Matrix unit configuration + */ +struct neoisp_reg_params_s { + /* Control */ + struct neoisp_pipe_conf_cfg_s pipe_conf; + + /* Pipeline 1 */ + struct neoisp_head_color_cfg_s head_color; + struct neoisp_hdr_decompress0_cfg_s decompress_input0; + struct neoisp_hdr_decompress1_cfg_s decompress_input1; + struct neoisp_obwb_cfg_s obwb[NEO_OBWB_CNT]; + struct neoisp_hdr_merge_cfg_s hdr_merge; + struct neoisp_rgbir_cfg_s rgbir; + struct neoisp_stat_cfg_s stat; + struct neoisp_ir_compress_cfg_s ir_compress; + struct neoisp_bnr_cfg_s bnr; + struct neoisp_vignetting_ctrl_cfg_s vignetting_ctrl; + struct neoisp_ctemp_cfg_s ctemp; + + /* Pipeline 2 */ + struct neoisp_demosaic_cfg_s demosaic; + struct neoisp_rgb2yuv_cfg_s rgb2yuv; + struct neoisp_dr_comp_cfg_s drc; + + /* Denoising pipeline */ + struct neoisp_nr_cfg_s nr; + struct neoisp_af_cfg_s af; + struct neoisp_ee_cfg_s ee; + struct neoisp_df_cfg_s df; + struct neoisp_convmed_cfg_s convmed; + struct neoisp_cas_cfg_s cas; + struct neoisp_gcm_cfg_s gcm; +}; + +/** + * struct neoisp_mem_params_s - Neoisp parameters accessed over local memo= ries + * + * This struct contains parameters blocks accessed over local memories. + * + * @vt: Vignetting table LUT + * @gtm: Global Tonemap LUT + * @ltm: Local Tonemap LUT + */ +struct neoisp_mem_params_s { + struct neoisp_vignetting_table_mem_params_s vt; + struct neoisp_drc_global_tonemap_mem_params_s gtm; + struct neoisp_drc_local_tonemap_mem_params_s ltm; +}; + +/** + * struct neoisp_meta_params_s - Neoisp legacy parameters + * + * This struct contains all configuration parameters for the various Neoisp + * blocks. It is used when userspace doesn't support extended API. The full + * parameters buffer is copied for every frame, even if some blocks are not + * relevant. + * + * Userspace's algorithms are responsible for correctly populating all the + * parameters blocks. However, local memory parameters @mems must be filled + * before starting camera streaming to be applied as expected. @regs can be + * updated at any time. + * + * @features_cfg field is used to control whether a parameters block must = be + * applied or not, see :c:type:`neoisp_feat_ctrl_s`. It allows bypassing s= ome + * block(s) easily. + * + * @frame_id: Frame index the parameters are computed from + * @features_cfg: Bitfield mask to ignore some configuration blocks + * @regs: Neoisp parameters accessed over registers + * @mems: Neoisp parameters accessed over local memories + */ +struct neoisp_meta_params_s { + __u32 frame_id; + struct neoisp_feat_ctrl_s features_cfg; + struct neoisp_reg_params_s regs; + struct neoisp_mem_params_s mems; +}; + +/* + * Extensible parameters + */ + +/** + * 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_params_block_header` + * @cfg: Pipeline configuration, see + * :c:type:`neoisp_pipe_conf_cfg_s` + */ +struct neoisp_pipe_conf_cfg_es { + struct v4l2_isp_params_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_params_block_header` + * @cfg: Head color configuration, see + * :c:type:`neoisp_head_color_cfg_s` + */ +struct neoisp_head_color_cfg_es { + struct v4l2_isp_params_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_params_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_params_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_params_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_params_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_params_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_params_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_params_block_header` + * @cfg: HDR merge configuration, see + * :c:type:`neoisp_hdr_merge_cfg_s` + */ +struct neoisp_hdr_merge_cfg_es { + struct v4l2_isp_params_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_params_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_params_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_params_block_header` + * @cfg: Statistics and Histogram unit configuration, see + * :c:type:`neoisp_stat_cfg_s` + */ +struct neoisp_stat_cfg_es { + struct v4l2_isp_params_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_params_block_header` + * @cfg: Infra-red Compression configuration, see + * :c:type:`neoisp_ir_compress_cfg_s` + */ +struct neoisp_ir_compress_cfg_es { + struct v4l2_isp_params_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_params_block_header` + * @cfg: Bayer Noise Reduction configuration, see + * :c:type:`neoisp_bnr_cfg_s` + */ +struct neoisp_bnr_cfg_es { + struct v4l2_isp_params_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_params_block_header` + * @cfg: Vignetting unit configuration, see + * :c:type:`neoisp_vignetting_ctrl_cfg_s` + */ +struct neoisp_vignetting_ctrl_cfg_es { + struct v4l2_isp_params_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_params_block_header` + * @cfg: Color Temperature unit configuration, see + * :c:type:`neoisp_ctemp_cfg_s` + */ +struct neoisp_ctemp_cfg_es { + struct v4l2_isp_params_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_params_block_header` + * @cfg: Demosaic unit configuration, see + * :c:type:`neoisp_demosaic_cfg_s` + */ +struct neoisp_demosaic_cfg_es { + struct v4l2_isp_params_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_params_block_header` + * @cfg: Color space conversion unit configuration, see + * :c:type:`neoisp_rgb2yuv_cfg_s` + */ +struct neoisp_rgb2yuv_cfg_es { + struct v4l2_isp_params_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_params_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_params_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_params_block_header` + * @cfg: Noise Reduction unit configuration, see + * :c:type:`neoisp_nr_cfg_s` + */ +struct neoisp_nr_cfg_es { + struct v4l2_isp_params_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_params_block_header` + * @cfg: AutoFocus unit configuration, see + * :c:type:`neoisp_af_cfg_s` + */ +struct neoisp_af_cfg_es { + struct v4l2_isp_params_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_params_block_header` + * @cfg: Edge Enhancement unit configuration, see + * :c:type:`neoisp_ee_cfg_s` + */ +struct neoisp_ee_cfg_es { + struct v4l2_isp_params_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_params_block_header` + * @cfg: Direction Filter configuration, see + * :c:type:`neoisp_df_cfg_s` + */ +struct neoisp_df_cfg_es { + struct v4l2_isp_params_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_params_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_params_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_params_block_header` + * @cfg: Color Adaptive Saturation unit configuration, see + * :c:type:`neoisp_cas_cfg_s` + */ +struct neoisp_cas_cfg_es { + struct v4l2_isp_params_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_params_block_header` + * @cfg: Gamma Correction Matrix configuration, see + * :c:type:`neoisp_gcm_cfg_s` + */ +struct neoisp_gcm_cfg_es { + struct v4l2_isp_params_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_params_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_params_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_params_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_params_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_params_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_params_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_reg_stats_s - Contiguous statistics accessed over aliased= address space + * @ct: Color temperature statistics + * @drc: Dynamic Range Compression statistics + * @af: Auto Focus statistics + * @bnr: Bayer Noise Reduction statistics + * @nr: Noise Reduction statistics + * @ee: Edge enhancement statistics + * @df: Contiguous statistics to access over aliased address space + */ +struct neoisp_reg_stats_s { + struct neoisp_ctemp_reg_stats_s ct; + struct neoisp_drc_reg_stats_s drc; + struct neoisp_af_reg_stats_s af; + struct neoisp_bnr_reg_stats_s bnr; + struct neoisp_nr_reg_stats_s nr; + struct neoisp_ee_reg_stats_s ee; + struct neoisp_df_reg_stats_s df; +}; + +/** + * 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]; +}; + +/** + * struct neoisp_mem_stats_s - Contiguous statistics accessed over local m= emories + * @ctemp: Color temperature statistics + * @rgbir: Dynamic Range Compression statistics + * @hist: Auto Focus statistics + * @drc: Bayer Noise Reduction statistics + */ +struct neoisp_mem_stats_s { + struct neoisp_ctemp_mem_stats_s ctemp; + struct neoisp_rgbir_mem_stats_s rgbir; + struct neoisp_hist_mem_stats_s hist; + struct neoisp_drc_mem_stats_s drc; +}; + +/** + * struct neoisp_meta_stats_s - Neoisp legacy statistics + * + * This structure contains all statistics provided by the various ISP bloc= ks. + * It is used when userspace doesn't support extended API. The full statis= tic + * buffer is copied for every frame. + * + * Driver is responsible for correctly populating all the statistics block= s, + * whatever the block is accessed over aliased address space, or local mem= ories. + * + * @regs: Aliased address space statistics + * @mems: Local memories statistics + */ +struct neoisp_meta_stats_s { + struct neoisp_reg_stats_s regs; + struct neoisp_mem_stats_s mems; +}; + +/* + * Extensible statistics + */ + +/** + * 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_stats_block_header` + * @stat: Pipeline configuration, see + * :c:type:`neoisp_ctemp_reg_stats_s` + */ +struct neoisp_ctemp_reg_stats_es { + struct v4l2_isp_stats_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_stats_block_header` + * @stat: Pipeline configuration, see + * :c:type:`neoisp_drc_reg_stats_s` + */ +struct neoisp_drc_reg_stats_es { + struct v4l2_isp_stats_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_stats_block_header` + * @stat: Pipeline configuration, see + * :c:type:`neoisp_af_reg_stats_s` + */ +struct neoisp_af_reg_stats_es { + struct v4l2_isp_stats_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_stats_block_header` + * @stat: Pipeline configuration, see + * :c:type:`neoisp_bnr_reg_stats_s` + */ +struct neoisp_bnr_reg_stats_es { + struct v4l2_isp_stats_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_stats_block_header` + * @stat: Pipeline configuration, see + * :c:type:`neoisp_nr_reg_stats_s` + */ +struct neoisp_nr_reg_stats_es { + struct v4l2_isp_stats_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_stats_block_header` + * @stat: Pipeline configuration, see + * :c:type:`neoisp_ee_reg_stats_s` + */ +struct neoisp_ee_reg_stats_es { + struct v4l2_isp_stats_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_stats_block_header` + * @stat: Pipeline configuration, see + * :c:type:`neoisp_df_reg_stats_s` + */ +struct neoisp_df_reg_stats_es { + struct v4l2_isp_stats_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_stats_block_header` + * @stat: Pipeline configuration, see + * :c:type:`neoisp_ctemp_mem_stats_s` + */ +struct neoisp_ctemp_mem_stats_es { + struct v4l2_isp_stats_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_stats_block_header` + * @stat: Pipeline configuration, see + * :c:type:`neoisp_rgbir_mem_stats_s` + */ +struct neoisp_rgbir_mem_stats_es { + struct v4l2_isp_stats_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_stats_block_header` + * @stat: Pipeline configuration, see + * :c:type:`neoisp_hist_mem_stats_s` + */ +struct neoisp_hist_mem_stats_es { + struct v4l2_isp_stats_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_stats_block_header` + * @stat: Pipeline configuration, see + * :c:type:`neoisp_drc_mem_stats_s` + */ +struct neoisp_drc_mem_stats_es { + struct v4l2_isp_stats_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.52.0 From nobody Sat Feb 7 07:31:36 2026 Received: from PA4PR04CU001.outbound.protection.outlook.com (mail-francecentralazon11013031.outbound.protection.outlook.com [40.107.162.31]) (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 F0C96369973; Fri, 23 Jan 2026 08:06:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.162.31 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769155618; cv=fail; b=c0ggCopyK6N7fDSoWqvAauMykK+hZCl0bTNAYR/GwKRXSziQy0P1bMWOEFAj4LvJUS49I9W3l5FzGWd7Hx4UD9z2GanLlYYrQVEwcsSMoy3NPUSIxPGhmLd8x9VQQVV9uDyzY2dKceTZX68t+b7ijq8tFOxJSUn1uh9OAnhOj7Y= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769155618; c=relaxed/simple; bh=x3dlg+OXadv/2+OZ8Ar1yeoJWlutWcnn04EG0QuhctI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=XF1ehZWnvuAq46r4kNrSChVs33KQpBXbugWhmihFlmjDmwpMeIzUF8hkD044zuqNzKHggiBFNQOHL8KY1a8jNy+abHeMCQVAxe982hNXSaotZ9mca1xw+hPg5gPxCAlbfeqF7sKmcvzFrQRmXQJzRSlGoNHvuMInQ9dblKsryqc= 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=Or4AyINy; arc=fail smtp.client-ip=40.107.162.31 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="Or4AyINy" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=wH1GTuaFAg0Ygptv8BUJIWIOlU3qxMUm8I/+59MJMKLbEhlcJso6v9YCVNNnrI1TZ2mAEUFvoLBTHiv1R+r+mFwBxRBID6uxb1CC9J0kqoOJ0fUfcSEUCaZB08bHNUCo3E9w7+5hu9U6n8dg7z2a6qHy8evOE9MJWbMYxkjpinPDrF2zr/QOVjG0I3eDXZSkJX+3Ub/8hco/8sQg4OepTGyUVIlO1aLGgPcNf/wI2IVLE7A8V9zwjaTZPEPYbPEL4ORRzX5PAwwMZ8XIqdp40h1xNH3UfXz+BXWE4k0c7ODSwRa77x2o6+36AVO0WI0c67l4itomW3Qp0zpNbKH45A== 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=PUbXXjvm0oGwrx0WqCATjxKizYBqB1IqVEsO70adHVg=; b=hT5YJ9Rg28BxAinKlkiuH96LeVC/C7U17WidlZOgPST4tU45KRBydTc1epaNimNdjJ0sfBqifB54x+F1iNdb8xLygUd8H5tZusZAbIGwXQZ9NjMBYGDqgo84xK9B1yTyMNyubFM7pjjJbsKn+NaVSB1U4KT69RHAXxrQX+6mYaLEqOYUWm4/srzPLEGyqALtSEuEhflb11gmJg5/GiaREqwNIqeSwiEI0DS1J8oTE2JtfY3LzzQEjFt5MHQ2z4iooLWkUaIqP9avZuMJOuxw/hP3FAdj/8mG8m4ByAIacZlED55E40PwRUGVBGilAhOQrszFYDxRUt9yYSGTDnsBjA== 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=PUbXXjvm0oGwrx0WqCATjxKizYBqB1IqVEsO70adHVg=; b=Or4AyINykPXIcRsC1ACUF/Q5K4hA68eD+pvfasp2njxctsgT/ZQJq9E50ZyX2Sw+qyQxmTtRiztNw8D8dXbW6rjudrvn31tmdnh0YwlCRIWtEFtGVAoAyOdXrvpKt3sAPycKHuxbA6zpuIDldSoT7jidm4lUVuVtl8iah++dheBCm4G3ghnNadziWkps7pE4jeu9mtaDwZwXEk8sKFdN+kTvRzZazC3qB81i/igTG5FNUhv4pgu7G2zOe/b4ZeqWBLqoBld5kJGK3o3J09lLJQaCMYmbwRLYuP6IQOmDinaJPF3MYv1q7sYirNdvXqHPP2yn3sT+g/QqDJEaDVunkQ== 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 PAXPR04MB8624.eurprd04.prod.outlook.com (2603:10a6:102:21b::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9542.10; Fri, 23 Jan 2026 08:06:30 +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.20.9542.008; Fri, 23 Jan 2026 08:06:30 +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, shawnguo@kernel.org, s.hauer@pengutronix.de, kernel@pengutronix.de, festevam@gmail.com Cc: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Antoine Bouyer Subject: [RFC v1 09/11] media: platform: Add NXP Neoisp Image Signal Processor Date: Fri, 23 Jan 2026 09:09:36 +0100 Message-ID: <20260123080938.3367348-10-antoine.bouyer@nxp.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260123080938.3367348-1-antoine.bouyer@nxp.com> References: <20260123080938.3367348-1-antoine.bouyer@nxp.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: FR4P281CA0026.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:c9::11) 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_|PAXPR04MB8624:EE_ X-MS-Office365-Filtering-Correlation-Id: 279f1fec-4fd1-444e-8bc4-08de5a565031 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|376014|7416014|52116014|1800799024|19092799006|366016|4022899009|13003099007|921020|38350700014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?Y4mQs8bvrzuaPvy53XAaZtfIJ/lMP8WL0vDLM0Z5gglecLylL9e929jXIcH2?= =?us-ascii?Q?PbT2DT7ZzKPx3elyDdOdRY4lZFMsY/xaz4dIRtpYce2ZfBD3fb5eaPczeMTh?= =?us-ascii?Q?ghJfLnLNX+WXdnD5F/emaqnSsAa7RdnrwOzkABZZtdUL74t2WP5E3W7brZb2?= =?us-ascii?Q?cJk9uz2vLaM4DJtoBL8bWFa0x1cf42eCg6vGscPzBj7NN0waL6T5XNw6Dazk?= =?us-ascii?Q?TbPUWgEHDQwQZz4ZaF53IfpqgPjLaRRFpNKxy/X3zuPFwColJPBeV9j4x9Fg?= =?us-ascii?Q?Rc7X+XsgnoLlyguTTeR4BUU45Ix0nzkM+RIkxW9irpy99jYCqSdINseBuU91?= =?us-ascii?Q?BoCBjEhRWoj5dExFlHHBQdHvNIjUmzzDUEaLY4N7+dKmvLl4u3Elk0IN4qct?= =?us-ascii?Q?dyTzJL+rpJbTvZQdvxentU/O9Mh2jdi/L8SMSlgFiBh2pRgMZrfe5gdt6OIE?= =?us-ascii?Q?+TjbA5VAONINYsg5YgfPjxiYAvHzGsPmB8uI+aPxt/lXzCKNkFHDcKJiJrN/?= =?us-ascii?Q?LRXKbuyGLxThWd2xdI8M0cmLdQiX8q6wpusfeUzMuWqZjLemb+c6PdwOz8/Q?= =?us-ascii?Q?3q+E8AwgxsaZthf8cQnC0IdLcvD9zcEQ4dwE4DBzKKIGONYqL2T0fPQgwpty?= =?us-ascii?Q?WwjGavynMP6X9v2XIZ4HrADh+ax9FuOrZEHUihqpbbj93x2CgV2E1ElsNXih?= =?us-ascii?Q?8vED8AaM5oFGlDOc1dzy07eX7TpEB22iHD2HHgtSmU/3xs1TbOxY/U9uF2Cs?= =?us-ascii?Q?iVrMtLAwx3gBKZb5k1gqqgsz39nftcJoB39uRhX0eNS20Pp19uY/UGS4DHzX?= =?us-ascii?Q?wswZA7xxZ3nPc1oWoRr6unUDmTAWJjdsNj/gLapQj9QGpKt5B9N4KRqGGnyR?= =?us-ascii?Q?E881Y5t/5i+p/9VOKIdrtTx1zmZZrnfMrGimZKBhnrjfxY4iJhkWAbJ0iXDQ?= =?us-ascii?Q?9hhTUgGzbD48pqUre+Yua+DDufPGHNckDB8Cu8JLrGSjWuPNEq3Dywa3OKLi?= =?us-ascii?Q?6Zj5M8+DNCt3WJOOjsd2mjhszAMPs2HS3kvLjAyq5HDKY74QI59rpqhRKSEj?= =?us-ascii?Q?6Ubc9BSJGpzpHLfKWkzorGnMrHIGacfQbXRcyLtC8wRyZjroxeFqKBdiErfv?= =?us-ascii?Q?sj1iRgxEHpVdY327xUQHRKqhWarJ1M8EkhF44YiToe3bXiuSBnPJtlc9CSkH?= =?us-ascii?Q?VAwrV6XkrQ4Ln2Ek2HBhjJJCsdev5tROK0Fx6Ap1riGTRQwVWFOF60SJ40lC?= =?us-ascii?Q?gmMWrHfKBy6LDaKVwOvUHM+ueiZThuWWP+gSQkXJfktRUk62aYMX91eje+fq?= =?us-ascii?Q?BIdfU4cGCvC3YJlp+f2YtmnHe0a47lvf1WGnZ9Vsd2J7NgJuDmYKlQX3tYdv?= =?us-ascii?Q?imYJ4vYpJlbux0+5Jfqxs2chPwHcoVXynfh9eEhlbg3aQBM131f9u+Ck4z5+?= =?us-ascii?Q?M8YcVfU3NLz+0VOF+7RLRqQyK/YaEy13O4J69GnSz3Q/cVj6vVjnug8kd2xu?= =?us-ascii?Q?KruCGaDIR8JfQ2d+q3ncNaH+BzjnrZUPWBChSvGy0nBKJNa9/htLVyoQ0LrK?= =?us-ascii?Q?N3sacpGmpflyCt4w0lNO1yaUWTygzHFKFuyA1vuS?= 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)(376014)(7416014)(52116014)(1800799024)(19092799006)(366016)(4022899009)(13003099007)(921020)(38350700014);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?dMAWYeVyQigvPSewHg1NG7HsdwSEbTF+ruDj8jRAD/MylWs5H88n8ibHlTK3?= =?us-ascii?Q?+w9Eo2Hs/8KcQpmdziDY3GZQzLkCEc9b2liGroE77BjnQlWwWpbZmsb1MWZY?= =?us-ascii?Q?UUdn9L+3Y1/G/RJYNHUmZCnLL7oyBnq8baxu/VDuRChR8xT3SwV33HbXUS3n?= =?us-ascii?Q?yAc7Dya0hKpheJP7aQeu9yYZoFuRWSFqSbPsPaMNoa5holITm/EgFPeUi3Uq?= =?us-ascii?Q?8EEwaPvGYbWH23s+GfK+reWL+y+gvNBdykAp5R/SqZzJnPHU234omF/z6FTB?= =?us-ascii?Q?W+DKPdH39RMquNzPAxAO2DeMPhdK2Kl/29Jpdl0zt47mSYEXod3FZ55L/xLY?= =?us-ascii?Q?chHJpACPh01WUa7M7Vlq7RjgSwpNtunUYHfetwkpTUERWmt3TnC8rmXs3JB0?= =?us-ascii?Q?JxCIZSuopb/yviB46wyLGzKtq5DvWNZoBmGCtYATwRqDeUbU8vOVF8/vvSoO?= =?us-ascii?Q?Nk5jFzD2wPd4kkUG17+SbYr2GruLY6RtoJ1qkmmVxcLxIgEoJKJUVVW2aQQu?= =?us-ascii?Q?I10GJOZKWWEcIGI1gsNzwFHsVZ6cvelX4EDTyhfa00OK7gdwaQDXYMiNI+4i?= =?us-ascii?Q?SjMdQxAqqpkgnPeC1AzVfwlqRbNe6Dak887qTMB1iLehNf7g/y4vfZLjKArG?= =?us-ascii?Q?Zvg9QEoHf3QkOVX01Juik0szjCJdbzV3ZnvCB4EGMQAdIpM0iuYW/WPZWk7s?= =?us-ascii?Q?BIsCeQThTpJA8AulTkfbLWg4QjJHTHAUpKVoTsCVq4mKRxTIwPqju+9XcR+1?= =?us-ascii?Q?VlGswZJMfrA/XdhsHFjsecqIIX2yspxOhnmARBFw00wKZHw/eUtJdF6T5CLO?= =?us-ascii?Q?B+sxeIVgqdRUuwkd0TWTyHsrfapynbWDstDjyva3EmWRRgPd+alxc5cZo8Wg?= =?us-ascii?Q?Af/C9gh9OttrCqWt+n5HoMVyzjopGq4Sk+MJ1/YTMFw22KBw9AHcLrqe6DGt?= =?us-ascii?Q?FqaBlBeWstIezXKOsx3Ni2AFmDVyoY9PXwmZ+5yM4mPI3dqSc2aqFlFuRTkM?= =?us-ascii?Q?AE6aPDAP66kyq/DM8MHk6q8ie2B+Ec/Sm0gAHVCHtTL74o4VsWMWc5kIAAC2?= =?us-ascii?Q?s3GixUCT+pejbGLi/uOB/Hx32CHv+RBjgXhDsOxjF2I40AcL9WmgWIk8/22l?= =?us-ascii?Q?xzOB49ToMGGRWgwww74iHpHcUp1VLvI5c1M3pb91TNQkvj0JzrWlEAKJ3WFT?= =?us-ascii?Q?xz5Ki/QdGV2TGofN+CVWZTfkUaGcRVqMqwi9ujm4LY7ofKVkWd0DNE1hBFUO?= =?us-ascii?Q?ZHmjbcICl5TAQ/9uRj2pPwFZ7ARNtSu0p/helO297rj2Bt0agyppNbyrvAjK?= =?us-ascii?Q?6vR2pg7vMYl3e2JtwGcSLYxovpvYts4jvEgUOs+MH72CdB2cBLq0KXpr1O3w?= =?us-ascii?Q?I3aYa6rd2y4zR91zG6e4HVe7dJYi/qojhF0QbbjQkyVC16KVSiz+FiQ3Atce?= =?us-ascii?Q?3AhzBbTQcbdxzqE2bq3tWbRVbS580ghdl9HGZXXStWqtujeo1JYKiOJ+w6gO?= =?us-ascii?Q?2RZ7Tzu9P8KEa5BoEsWIG8TLMz6d7eD/zRUvYZhWH4zh/5XCsBDLi0zssCB/?= =?us-ascii?Q?TVXNLWn4HI3L9dJNvVEBpZI7sjGtJxoeHEH/x8GBgCkoS+8okSVE7aGVxyHX?= =?us-ascii?Q?zCBqhN02JWzZvL3VCuma2kLnlULG9lYxnRphgw37OEdJ/CXO3kK/qeNg7++r?= =?us-ascii?Q?DnVMQsM0nKjK1XHREZcDpXU614FdZhg0DPUwG/AwCW4eo6Nd7a8oQ1t70mpk?= =?us-ascii?Q?71UG4sQ+Qw=3D=3D?= X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 279f1fec-4fd1-444e-8bc4-08de5a565031 X-MS-Exchange-CrossTenant-AuthSource: PA6PR04MB11910.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Jan 2026 08:06:30.2058 (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: d9EZoQrTvBiOBzsQICI2cwlus3RkqlRl520AzPTRka+b+jvsBX0c8LZPPIe9jx5GcLhQ+DrTwKm+e6QLfgaAbA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAXPR04MB8624 Content-Type: text/plain; charset="utf-8" First NXP neoisp driver version with the following contents: This driver was originaly inpired from raspberrypi pisp_be driver. It reuses same approach for ISP job scheduling. The Neoisp driver supports: * RAW Bayer images input: (tested V4L2 formats) - V4L2_PIX_FMT_SBGGR8 - V4L2_PIX_FMT_SBGGR12 - V4L2_PIX_FMT_SGBRG8 - V4L2_PIX_FMT_SGRBG8 - V4L2_PIX_FMT_SRGGB8 - V4L2_PIX_FMT_SRGGB16 * Monochrome sensors input: (tested V4L2 formats) - V4L2_PIX_FMT_GREY - V4L2_PIX_FMT_Y10 * RGB/YUV output formats: (tested V4L2 formats) - V4L2_PIX_FMT_RGB24 (RGB-8-8-8) - V4L2_PIX_FMT_YUYV (YUV 4:2:2) - V4L2_PIX_FMT_YUV24 (YUV3 4:4:4) - V4L2_PIX_FMT_NV12 - V4L2_PIX_FMT_NV16 - V4L2_PIX_FMT_GREY - V4L2_PIX_FMT_Y10 - V4L2_PIX_FMT_Y12 - V4L2_PIX_FMT_Y16 * Up to 8 camera contexts * Both input0 and input1 pads are supported * Frame and IR output pads are supported * Params and stats nodes are supported * Use of extensible parameters and statistics buffers 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 | 15 + drivers/media/platform/nxp/neoisp/Makefile | 6 + drivers/media/platform/nxp/neoisp/neoisp.h | 254 ++ .../media/platform/nxp/neoisp/neoisp_ctx.c | 2798 +++++++++++++++++ .../media/platform/nxp/neoisp/neoisp_ctx.h | 85 + .../media/platform/nxp/neoisp/neoisp_fmt.h | 509 +++ drivers/media/platform/nxp/neoisp/neoisp_hw.h | 577 ++++ .../media/platform/nxp/neoisp/neoisp_main.c | 1985 ++++++++++++ .../media/platform/nxp/neoisp/neoisp_nodes.h | 60 + .../media/platform/nxp/neoisp/neoisp_regs.h | 2501 +++++++++++++++ 13 files changed, 8801 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_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 5560da0deb71..925aba2f1fa4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15803,6 +15803,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,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..4ff05d7b9b85 --- /dev/null +++ b/drivers/media/platform/nxp/neoisp/Kconfig @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config VIDEO_NXP_NEOISP + tristate "NXP NEOISP v4l2 hardware driver" + 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..381e11454d37 --- /dev/null +++ b/drivers/media/platform/nxp/neoisp/neoisp.h @@ -0,0 +1,254 @@ +/* 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_NODE_GROUPS_COUNT 8 +#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) + +#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 + * + * @hw_ver: ISP hardware version + * @context_ops: Context related operators + * @mems: The active memory blocks of ISP version + * @blocks_list: The list of ISP units supported by an ISP version + * + * This structure contains information about the ISP specific model, + * like hardware version, parameters buffer version or integration in a pa= rticular SoC. + */ +struct neoisp_info_s { + enum neoisp_version_e hw_ver; + struct neoisp_context_ops_s *context_ops; + const struct isp_block_map_s *mems; + 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_node_group_s *node_group; + /* Video device lock */ + struct mutex node_lock; + /* vb2_queue lock */ + struct mutex queue_lock; + /* neoisp hw lock */ + spinlock_t ready_lock; + 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_node_group_s { + u32 id; + 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 neoisp_dev_s *neoisp_dev; + struct media_device mdev; + struct neoisp_node_s node[NEOISP_NODES_COUNT]; + 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; +}; + +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_node_group_s *node_group; + struct neoisp_buffer_s *buf[NEOISP_NODES_COUNT]; +}; + +struct neoisp_dev_s { + struct platform_device *pdev; + struct neoisp_info_s *info; + void __iomem *mmio; + void __iomem *mmio_tcm; + struct clk_bulk_data *clks; + s32 num_clks; + struct neoisp_node_group_s node_group[NEOISP_NODE_GROUPS_COUNT]; + struct neoisp_job_s queued_job; + bool hw_busy; /* Non-zero if a job is queued or is being started */ + spinlock_t hw_lock; /* Protects "hw_busy" flag and streaming_map */ +}; + +static inline int neoisp_node_link_is_enabled(struct neoisp_node_s *node) +{ + return (node->intf_link->flags & MEDIA_LNK_FL_ENABLED); +} + +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_ctx.c b/drivers/media= /platform/nxp/neoisp/neoisp_ctx.c new file mode 100644 index 000000000000..f9e08e7c9e8b --- /dev/null +++ b/drivers/media/platform/nxp/neoisp/neoisp_ctx.c @@ -0,0 +1,2798 @@ +// 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 "neoisp.h" +#include "neoisp_ctx.h" + +/** + * 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.common =3D { + .img_conf =3D + NEO_PIPE_CONF_IMG_CONF_CAM0_INALIGN0_SET(1) | + NEO_PIPE_CONF_IMG_CONF_CAM0_LPALIGN0_SET(1) | + NEO_PIPE_CONF_IMG_CONF_CAM0_INALIGN1_SET(1) | + NEO_PIPE_CONF_IMG_CONF_CAM0_LPALIGN1_SET(1), + }, + .hdr_decompress0 =3D { + .ctrl =3D + NEO_CTRL_CAM0_ENABLE_SET(1), + .knee_ratio4 =3D + NEO_HDR_DECOMPRESS0_KNEE_RATIO4_CAM0_RATIO4_SET(1 << 5), + }, + .hdr_decompress1 =3D { + .ctrl =3D + NEO_CTRL_CAM0_ENABLE_SET(0), + .knee_ratio4 =3D + NEO_HDR_DECOMPRESS1_KNEE_RATIO4_CAM0_RATIO4_SET(1 << 5), + }, + .obwb0 =3D { + .ctrl =3D + NEO_OB_WB0_CTRL_CAM0_OBPP_SET(3), + .r_ctrl =3D + NEO_OB_WB0_R_CTRL_CAM0_GAIN_SET(1 << 8) | + NEO_OB_WB0_R_CTRL_CAM0_OFFSET_SET(0), + .gr_ctrl =3D + NEO_OB_WB0_GR_CTRL_CAM0_GAIN_SET(1 << 8) | + NEO_OB_WB0_GR_CTRL_CAM0_OFFSET_SET(0), + .gb_ctrl =3D + NEO_OB_WB0_GB_CTRL_CAM0_GAIN_SET(1 << 8) | + NEO_OB_WB0_GB_CTRL_CAM0_OFFSET_SET(0), + .b_ctrl =3D + NEO_OB_WB0_B_CTRL_CAM0_GAIN_SET(1 << 8) | + NEO_OB_WB0_B_CTRL_CAM0_OFFSET_SET(0), + }, + .obwb1 =3D { + .ctrl =3D + NEO_OB_WB1_CTRL_CAM0_OBPP_SET(2), + .r_ctrl =3D + NEO_OB_WB1_R_CTRL_CAM0_GAIN_SET(1 << 8) | + NEO_OB_WB1_R_CTRL_CAM0_OFFSET_SET(0), + .gr_ctrl =3D + NEO_OB_WB1_GR_CTRL_CAM0_GAIN_SET(1 << 8) | + NEO_OB_WB1_GR_CTRL_CAM0_OFFSET_SET(0), + .gb_ctrl =3D + NEO_OB_WB1_GB_CTRL_CAM0_GAIN_SET(1 << 8) | + NEO_OB_WB1_GB_CTRL_CAM0_OFFSET_SET(0), + .b_ctrl =3D + NEO_OB_WB1_B_CTRL_CAM0_GAIN_SET(1 << 8) | + NEO_OB_WB1_B_CTRL_CAM0_OFFSET_SET(0), + }, + .obwb2 =3D { + .ctrl =3D + NEO_OB_WB2_CTRL_CAM0_OBPP_SET(3), + .r_ctrl =3D + NEO_OB_WB2_R_CTRL_CAM0_GAIN_SET(1 << 8) | + NEO_OB_WB2_R_CTRL_CAM0_OFFSET_SET(0), + .gr_ctrl =3D + NEO_OB_WB2_GR_CTRL_CAM0_GAIN_SET(1 << 8) | + NEO_OB_WB2_GR_CTRL_CAM0_OFFSET_SET(0), + .gb_ctrl =3D + NEO_OB_WB2_GB_CTRL_CAM0_GAIN_SET(1 << 8) | + NEO_OB_WB2_GB_CTRL_CAM0_OFFSET_SET(0), + .b_ctrl =3D + NEO_OB_WB2_B_CTRL_CAM0_GAIN_SET(1 << 8) | + NEO_OB_WB2_B_CTRL_CAM0_OFFSET_SET(0), + }, + .hdr_merge =3D { + .ctrl =3D + NEO_HDR_MERGE_CTRL_CAM0_ENABLE_SET(0) | + NEO_HDR_MERGE_CTRL_CAM0_GAIN1BPP_SET(3) | + NEO_HDR_MERGE_CTRL_CAM0_GAIN0BPP_SET(3) | + NEO_HDR_MERGE_CTRL_CAM0_OBPP_SET(3), + .gain_scale =3D + NEO_HDR_MERGE_GAIN_SCALE_CAM0_SCALE1_SET(8) | + NEO_HDR_MERGE_GAIN_SCALE_CAM0_SCALE0_SET(1 << 12), + .gain_shift =3D + NEO_HDR_MERGE_GAIN_SHIFT_CAM0_SHIFT1_SET(12) | + NEO_HDR_MERGE_GAIN_SHIFT_CAM0_SHIFT0_SET(4), + .luma_th =3D + NEO_HDR_MERGE_LUMA_TH_CAM0_TH0_SET(4), + .luma_scale =3D + NEO_HDR_MERGE_LUMA_SCALE_CAM0_SCALE_SET(1 << 8) | + NEO_HDR_MERGE_LUMA_SCALE_CAM0_SHIFT_SET(8) | + NEO_HDR_MERGE_LUMA_SCALE_CAM0_THSHIFT_SET(8), + .downscale =3D + NEO_HDR_MERGE_DOWNSCALE_CAM0_IMGSCALE0_SET(8), + .upscale =3D + NEO_HDR_MERGE_UPSCALE_CAM0_IMGSCALE1_SET(8), + }, + .ctemp =3D {}, + .rgbir =3D { + .ctrl =3D + NEO_RGBIR_CTRL_CAM0_ENABLE_SET(0), + .ccm0 =3D + NEO_RGBIR_CCM0_CAM0_CCM_SET(1 << 8), + .ccm1 =3D + NEO_RGBIR_CCM1_CAM0_CCM_SET(1 << 8), + .ccm2 =3D + NEO_RGBIR_CCM2_CAM0_CCM_SET(1 << 8), + .ccm0_th =3D + NEO_RGBIR_CCM0_TH_CAM0_THRESHOLD_SET(0xff000), + .ccm1_th =3D + NEO_RGBIR_CCM1_TH_CAM0_THRESHOLD_SET(0xff000), + .ccm2_th =3D + NEO_RGBIR_CCM2_TH_CAM0_THRESHOLD_SET(0xff000), + }, + .stat =3D {}, + .ir_compress =3D { + .ctrl =3D + NEO_IR_COMPRESS_CTRL_CAM0_ENABLE_SET(0) | + NEO_IR_COMPRESS_CTRL_CAM0_OBPP_SET(0), + .knee_point1 =3D + NEO_IR_COMPRESS_KNEE_POINT1_CAM0_KNEEPOINT_SET((1 << 20) - 1), + .knee_ratio01 =3D + NEO_IR_COMPRESS_KNEE_RATIO01_CAM0_RATIO0_SET(8), + .knee_ratio4 =3D + NEO_IR_COMPRESS_KNEE_RATIO4_CAM0_RATIO4_SET(8), + }, + .bnr =3D { + .ctrl =3D + NEO_BNR_CTRL_CAM0_ENABLE_SET(1) | + NEO_BNR_CTRL_CAM0_NHOOD_SET(0) | + NEO_BNR_CTRL_CAM0_DEBUG_SET(0) | + NEO_BNR_CTRL_CAM0_OBPP_SET(3), + .ypeak =3D + NEO_BNR_YPEAK_CAM0_PEAK_OUTSEL_SET(0) | + NEO_BNR_YPEAK_CAM0_PEAK_HIGH_SET(1 << 8) | + NEO_BNR_YPEAK_CAM0_PEAK_SEL_SET(0) | + NEO_BNR_YPEAK_CAM0_PEAK_LOW_SET(1 << 7), + .yedge_th0 =3D + NEO_BNR_YEDGE_TH0_CAM0_EDGE_TH0_SET(20), + .yedge_scale =3D + NEO_BNR_YEDGE_SCALE_CAM0_SHIFT_SET(10) | + NEO_BNR_YEDGE_SCALE_CAM0_SCALE_SET(1 << 10), + .yedges_th0 =3D + NEO_BNR_YEDGES_TH0_CAM0_EDGE_TH0_SET(20), + .yedges_scale =3D + NEO_BNR_YEDGES_SCALE_CAM0_SHIFT_SET(10) | + NEO_BNR_YEDGES_SCALE_CAM0_SCALE_SET(1 << 10), + .yedgea_th0 =3D + NEO_BNR_YEDGEA_TH0_CAM0_EDGE_TH0_SET(20), + .yedgea_scale =3D + NEO_BNR_YEDGEA_SCALE_CAM0_SHIFT_SET(10) | + NEO_BNR_YEDGEA_SCALE_CAM0_SCALE_SET(10), + .yluma_x_th0 =3D + NEO_BNR_YLUMA_X_TH0_CAM0_TH_SET(20), + .yluma_y_th =3D + NEO_BNR_YLUMA_Y_TH_CAM0_LUMA_Y_TH1_SET(1 << 8) | + NEO_BNR_YLUMA_Y_TH_CAM0_LUMA_Y_TH0_SET(10), + .yluma_scale =3D + NEO_BNR_YLUMA_SCALE_CAM0_SHIFT_SET(10) | + NEO_BNR_YLUMA_SCALE_CAM0_SCALE_SET(1 << 10), + .yalpha_gain =3D + NEO_BNR_YALPHA_GAIN_CAM0_OFFSET_SET(0) | + NEO_BNR_YALPHA_GAIN_CAM0_GAIN_SET(1 << 8), + .cpeak =3D + NEO_BNR_CPEAK_CAM0_PEAK_OUTSEL_SET(0) | + NEO_BNR_CPEAK_CAM0_PEAK_HIGH_SET(1 << 8) | + NEO_BNR_CPEAK_CAM0_PEAK_SEL_SET(0) | + NEO_BNR_CPEAK_CAM0_PEAK_LOW_SET(1 << 7), + .cedge_th0 =3D + NEO_BNR_CEDGE_TH0_CAM0_EDGE_TH0_SET(20), + .cedge_scale =3D + NEO_BNR_CEDGE_SCALE_CAM0_SHIFT_SET(10) | + NEO_BNR_CEDGE_SCALE_CAM0_SCALE_SET(1 << 10), + .cedges_th0 =3D + NEO_BNR_CEDGES_TH0_CAM0_EDGE_TH0_SET(20), + .cedges_scale =3D + NEO_BNR_CEDGES_SCALE_CAM0_SHIFT_SET(10) | + NEO_BNR_CEDGES_SCALE_CAM0_SCALE_SET(1 << 10), + .cedgea_th0 =3D + NEO_BNR_CEDGEA_TH0_CAM0_EDGE_TH0_SET(20), + .cedgea_scale =3D + NEO_BNR_CEDGEA_SCALE_CAM0_SHIFT_SET(10) | + NEO_BNR_CEDGEA_SCALE_CAM0_SCALE_SET(1 << 10), + .cluma_x_th0 =3D + NEO_BNR_CLUMA_X_TH0_CAM0_TH_SET(20), + .cluma_y_th =3D + NEO_BNR_CLUMA_Y_TH_CAM0_LUMA_Y_TH1_SET(1 << 8) | + NEO_BNR_CLUMA_Y_TH_CAM0_LUMA_Y_TH0_SET(10), + .cluma_scale =3D + NEO_BNR_CLUMA_SCALE_CAM0_SHIFT_SET(10) | + NEO_BNR_CLUMA_SCALE_CAM0_SCALE_SET(1 << 10), + .calpha_gain =3D + NEO_BNR_CALPHA_GAIN_CAM0_OFFSET_SET(0) | + NEO_BNR_CALPHA_GAIN_CAM0_GAIN_SET(1 << 8), + .stretch =3D + NEO_BNR_STRETCH_CAM0_GAIN_SET(1 << 8), + }, + .idbg1 =3D { + .line_num_t =3D + NEO_IDBG1_LINE_NUM_LINE_NUM_MASK, + }, + .demosaic =3D { + .ctrl =3D + NEO_DEMOSAIC_CTRL_CAM0_FMT_SET(0), + .activity_ctl =3D + NEO_DEMOSAIC_ACTIVITY_CTL_CAM0_ACT_RATIO_SET(1 << 8) | + NEO_DEMOSAIC_ACTIVITY_CTL_CAM0_ALPHA_SET(1 << 8), + .dynamics_ctl0 =3D + NEO_DEMOSAIC_DYNAMICS_CTL0_CAM0_STRENGTHC_SET(1 << 8) | + NEO_DEMOSAIC_DYNAMICS_CTL0_CAM0_STRENGTHG_SET(1 << 8), + .dynamics_ctl2 =3D + NEO_DEMOSAIC_DYNAMICS_CTL2_CAM0_MAX_IMPACT_SET(1 << 7), + }, + .rgb2yuv =3D { + .gain_ctrl =3D + NEO_RGB_TO_YUV_GAIN_CTRL_CAM0_BGAIN_SET(1 << 8) | + NEO_RGB_TO_YUV_GAIN_CTRL_CAM0_RGAIN_SET(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 + NEO_RGB_TO_YUV_MAT0_CAM0_R0C0_SET(77) | + NEO_RGB_TO_YUV_MAT0_CAM0_R0C1_SET(150), + .mat1 =3D + NEO_RGB_TO_YUV_MAT1_CAM0_R0C2_SET(29), + .mat2 =3D + NEO_RGB_TO_YUV_MAT2_CAM0_R1C0_SET(-43) | + NEO_RGB_TO_YUV_MAT2_CAM0_R1C1_SET(-85), + .mat3 =3D + NEO_RGB_TO_YUV_MAT3_CAM0_R1C2_SET(128), + .mat4 =3D + NEO_RGB_TO_YUV_MAT4_CAM0_R2C0_SET(128) | + NEO_RGB_TO_YUV_MAT4_CAM0_R2C1_SET(-107), + .mat5 =3D + NEO_RGB_TO_YUV_MAT5_CAM0_R2C2_SET(-21), + }, + .drc =3D { + .gbl_gain =3D + NEO_DRC_GBL_GAIN_CAM0_GAIN_SET(1 << 8), + .lcl_stretch =3D + NEO_DRC_LCL_STRETCH_CAM0_STRETCH_SET(1 << 8), + .alpha =3D + NEO_DRC_ALPHA_CAM0_ALPHA_SET(1 << 8), + }, + .cas =3D { + .gain =3D + NEO_CAS_GAIN_CAM0_SCALE_SET(1), + }, + .packetizer =3D { + .ch0_ctrl =3D + NEO_PACKETIZER_CH0_CTRL_CAM0_OBPP_SET(6) | + NEO_PACKETIZER_CH0_CTRL_CAM0_RSA_SET(4) | + NEO_PACKETIZER_CH0_CTRL_CAM0_LSA_SET(0), + .ch12_ctrl =3D + NEO_PACKETIZER_CH12_CTRL_CAM0_OBPP_SET(6) | + NEO_PACKETIZER_CH12_CTRL_CAM0_RSA_SET(4) | + NEO_PACKETIZER_CH12_CTRL_CAM0_LSA_SET(0) | + NEO_PACKETIZER_CH12_CTRL_CAM0_SUBSAMPLE_SET(0), + .pack_ctrl =3D + NEO_PACKETIZER_PACK_CTRL_CAM0_TYPE_SET(1) | + NEO_PACKETIZER_PACK_CTRL_CAM0_ORDER0_SET(0) | + NEO_PACKETIZER_PACK_CTRL_CAM0_ORDER1_SET(1) | + NEO_PACKETIZER_PACK_CTRL_CAM0_ORDER2_SET(2) | + NEO_PACKETIZER_PACK_CTRL_CAM0_A0S_SET(0), + }, + .gcm =3D { + .imat0 =3D + NEO_GCM_IMAT0_CAM0_R0C0_SET(256) | + NEO_GCM_IMAT0_CAM0_R0C1_SET(0), + .imat1 =3D + NEO_GCM_IMAT1_CAM0_R0C2_SET(359), + .imat2 =3D + NEO_GCM_IMAT2_CAM0_R1C0_SET(256) | + NEO_GCM_IMAT2_CAM0_R1C1_SET(-88), + .imat3 =3D + NEO_GCM_IMAT3_CAM0_R1C2_SET(-183), + .imat4 =3D + NEO_GCM_IMAT4_CAM0_R2C0_SET(256) | + NEO_GCM_IMAT4_CAM0_R2C1_SET(454), + .imat5 =3D + NEO_GCM_IMAT5_CAM0_R2C2_SET(0), + .omat0 =3D + NEO_GCM_OMAT0_CAM0_R0C0_SET(256), + .omat2 =3D + NEO_GCM_OMAT2_CAM0_R1C1_SET(256), + .omat5 =3D + NEO_GCM_OMAT5_CAM0_R2C2_SET(256), + .mat_confg =3D + NEO_GCM_MAT_CONFG_CAM0_SIGN_CONFG_SET(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) }, + }, +}; + +static const __u32 neoisp_ext_stats_blocks_v1[] =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, +}; + +union neoisp_params_block_u { + struct neoisp_pipe_conf_cfg_s pipe_conf; + struct neoisp_head_color_cfg_s head_color; + struct neoisp_hdr_decompress0_cfg_s hdr_decompress0; + struct neoisp_hdr_decompress1_cfg_s hdr_decompress1; + struct neoisp_obwb_cfg_s obwb; + struct neoisp_hdr_merge_cfg_s hdr_merge; + struct neoisp_rgbir_cfg_s rgbir; + struct neoisp_stat_cfg_s stat; + struct neoisp_ir_compress_cfg_s ir_compress; + struct neoisp_bnr_cfg_s bnr; + struct neoisp_vignetting_ctrl_cfg_s vignetting_ctrl; + struct neoisp_ctemp_cfg_s ctemp; + struct neoisp_demosaic_cfg_s demosaic; + struct neoisp_rgb2yuv_cfg_s rgb2yuv; + struct neoisp_dr_comp_cfg_s drc; + struct neoisp_nr_cfg_s nrc; + struct neoisp_af_cfg_s afc; + struct neoisp_ee_cfg_s eec; + struct neoisp_df_cfg_s dfc; + struct neoisp_convmed_cfg_s convmed; + struct neoisp_cas_cfg_s cas; + struct neoisp_gcm_cfg_s gcm; + struct neoisp_vignetting_table_mem_params_s vignetting_table; + struct neoisp_drc_global_tonemap_mem_params_s drc_global_tonemap; + struct neoisp_drc_local_tonemap_mem_params_s drc_local_tonemap; +}; + +union neoisp_ext_params_block_u { + struct v4l2_isp_params_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_stats_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 ctx_blk_write(enum isp_block_map_e map, u32 *ptr, u32 *= dest) +{ + u32 woffset, count; + + get_offsize(map, &woffset, &count); + + if (IS_ERR_OR_NULL(ptr) || IS_ERR_OR_NULL(dest)) { + pr_err("Invalid pointer for memcpy block !"); + return; + } + + woffset /=3D sizeof(u32); + memcpy(dest + woffset, ptr, count); +} + +static void neoisp_params_handler_pipe_conf(struct neoisp_dev_s *neoispd, + union neoisp_params_block_u *blk) +{ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context; + struct neoisp_pipe_conf_s *pc =3D &ctx->hw.pipe_conf.common; + u32 tmp =3D pc->img_conf; + + tmp &=3D ~(NEO_PIPE_CONF_IMG_CONF_CAM0_INALIGN0 | + NEO_PIPE_CONF_IMG_CONF_CAM0_LPALIGN0 | + NEO_PIPE_CONF_IMG_CONF_CAM0_INALIGN1 | + NEO_PIPE_CONF_IMG_CONF_CAM0_LPALIGN1); + tmp |=3D + NEO_PIPE_CONF_IMG_CONF_CAM0_INALIGN0_SET(blk->pipe_conf.img_conf_inalign= 0) | + NEO_PIPE_CONF_IMG_CONF_CAM0_LPALIGN0_SET(blk->pipe_conf.img_conf_lpalign= 0) | + NEO_PIPE_CONF_IMG_CONF_CAM0_INALIGN1_SET(blk->pipe_conf.img_conf_inalign= 1) | + NEO_PIPE_CONF_IMG_CONF_CAM0_LPALIGN1_SET(blk->pipe_conf.img_conf_lpalign= 1); + pc->img_conf =3D tmp; +} + +static void neoisp_params_handler_head_color(struct neoisp_dev_s *neoispd, + union neoisp_params_block_u *blk) +{ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context; + struct neoisp_hc_s *hc =3D &ctx->hw.hc; + + hc->ctrl =3D + NEO_HC_CTRL_CAM0_HOFFSET_SET(blk->head_color.ctrl_hoffset) | + NEO_HC_CTRL_CAM0_VOFFSET_SET(blk->head_color.ctrl_voffset); +} + +static void neoisp_params_handler_hdr_decompress0(struct neoisp_dev_s *neo= ispd, + union neoisp_params_block_u *blk) +{ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context; + struct neoisp_hdr_decompress0_s *hd0 =3D &ctx->hw.hdr_decompress0; + + hd0->ctrl =3D + NEO_CTRL_CAM0_ENABLE_SET(blk->hdr_decompress0.ctrl_enable); + hd0->knee_point1 =3D + NEO_HDR_DECOMPRESS0_KNEE_POINT1_CAM0_KNEEPOINT_SET + (blk->hdr_decompress0.knee_point1); + hd0->knee_point2 =3D + NEO_HDR_DECOMPRESS0_KNEE_POINT2_CAM0_KNEEPOINT_SET + (blk->hdr_decompress0.knee_point2); + hd0->knee_point3 =3D + NEO_HDR_DECOMPRESS0_KNEE_POINT3_CAM0_KNEEPOINT_SET + (blk->hdr_decompress0.knee_point3); + hd0->knee_point4 =3D + NEO_HDR_DECOMPRESS0_KNEE_POINT4_CAM0_KNEEPOINT_SET + (blk->hdr_decompress0.knee_point4); + hd0->knee_offset0 =3D + NEO_HDR_DECOMPRESS0_KNEE_OFFSET0_CAM0_OFFSET_SET + (blk->hdr_decompress0.knee_offset0); + hd0->knee_offset1 =3D + NEO_HDR_DECOMPRESS0_KNEE_OFFSET1_CAM0_OFFSET_SET + (blk->hdr_decompress0.knee_offset1); + hd0->knee_offset2 =3D + NEO_HDR_DECOMPRESS0_KNEE_OFFSET2_CAM0_OFFSET_SET + (blk->hdr_decompress0.knee_offset2); + hd0->knee_offset3 =3D + NEO_HDR_DECOMPRESS0_KNEE_OFFSET3_CAM0_OFFSET_SET + (blk->hdr_decompress0.knee_offset3); + hd0->knee_offset4 =3D + NEO_HDR_DECOMPRESS0_KNEE_OFFSET4_CAM0_OFFSET_SET + (blk->hdr_decompress0.knee_offset4); + hd0->knee_ratio01 =3D + NEO_HDR_DECOMPRESS0_KNEE_RATIO01_CAM0_RATIO0_SET + (blk->hdr_decompress0.knee_ratio0); + hd0->knee_ratio01 |=3D + NEO_HDR_DECOMPRESS0_KNEE_RATIO01_CAM0_RATIO1_SET + (blk->hdr_decompress0.knee_ratio1); + hd0->knee_ratio23 =3D + NEO_HDR_DECOMPRESS0_KNEE_RATIO23_CAM0_RATIO2_SET + (blk->hdr_decompress0.knee_ratio2); + hd0->knee_ratio23 |=3D + NEO_HDR_DECOMPRESS0_KNEE_RATIO23_CAM0_RATIO3_SET + (blk->hdr_decompress0.knee_ratio3); + hd0->knee_ratio4 =3D + NEO_HDR_DECOMPRESS0_KNEE_RATIO4_CAM0_RATIO4_SET + (blk->hdr_decompress0.knee_ratio4); + hd0->knee_npoint0 =3D + NEO_HDR_DECOMPRESS0_KNEE_NPOINT0_CAM0_KNEEPOINT_SET + (blk->hdr_decompress0.knee_npoint0); + hd0->knee_npoint1 =3D + NEO_HDR_DECOMPRESS0_KNEE_NPOINT1_CAM0_KNEEPOINT_SET + (blk->hdr_decompress0.knee_npoint1); + hd0->knee_npoint2 =3D + NEO_HDR_DECOMPRESS0_KNEE_NPOINT2_CAM0_KNEEPOINT_SET + (blk->hdr_decompress0.knee_npoint2); + hd0->knee_npoint3 =3D + NEO_HDR_DECOMPRESS0_KNEE_NPOINT3_CAM0_KNEEPOINT_SET + (blk->hdr_decompress0.knee_npoint3); + hd0->knee_npoint4 =3D + NEO_HDR_DECOMPRESS0_KNEE_NPOINT4_CAM0_KNEEPOINT_SET + (blk->hdr_decompress0.knee_npoint4); +} + +static void neoisp_params_handler_hdr_decompress1(struct neoisp_dev_s *neo= ispd, + union neoisp_params_block_u *blk) +{ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context; + struct neoisp_hdr_decompress1_s *hd1 =3D &ctx->hw.hdr_decompress1; + + hd1->ctrl =3D + NEO_CTRL_CAM0_ENABLE_SET(blk->hdr_decompress1.ctrl_enable); + hd1->knee_point1 =3D + NEO_HDR_DECOMPRESS1_KNEE_POINT1_CAM0_KNEEPOINT_SET + (blk->hdr_decompress1.knee_point1); + hd1->knee_point2 =3D + NEO_HDR_DECOMPRESS1_KNEE_POINT2_CAM0_KNEEPOINT_SET + (blk->hdr_decompress1.knee_point2); + hd1->knee_point3 =3D + NEO_HDR_DECOMPRESS1_KNEE_POINT3_CAM0_KNEEPOINT_SET + (blk->hdr_decompress1.knee_point3); + hd1->knee_point4 =3D + NEO_HDR_DECOMPRESS1_KNEE_POINT4_CAM0_KNEEPOINT_SET + (blk->hdr_decompress1.knee_point4); + hd1->knee_offset0 =3D + NEO_HDR_DECOMPRESS1_KNEE_OFFSET0_CAM0_OFFSET_SET + (blk->hdr_decompress1.knee_offset0); + hd1->knee_offset1 =3D + NEO_HDR_DECOMPRESS1_KNEE_OFFSET1_CAM0_OFFSET_SET + (blk->hdr_decompress1.knee_offset1); + hd1->knee_offset2 =3D + NEO_HDR_DECOMPRESS1_KNEE_OFFSET2_CAM0_OFFSET_SET + (blk->hdr_decompress1.knee_offset2); + hd1->knee_offset3 =3D + NEO_HDR_DECOMPRESS1_KNEE_OFFSET3_CAM0_OFFSET_SET + (blk->hdr_decompress1.knee_offset3); + hd1->knee_offset4 =3D + NEO_HDR_DECOMPRESS1_KNEE_OFFSET4_CAM0_OFFSET_SET + (blk->hdr_decompress1.knee_offset4); + hd1->knee_ratio01 =3D + NEO_HDR_DECOMPRESS1_KNEE_RATIO01_CAM0_RATIO0_SET + (blk->hdr_decompress1.knee_ratio0); + hd1->knee_ratio01 |=3D + NEO_HDR_DECOMPRESS1_KNEE_RATIO01_CAM0_RATIO1_SET + (blk->hdr_decompress1.knee_ratio1); + hd1->knee_ratio23 =3D + NEO_HDR_DECOMPRESS1_KNEE_RATIO23_CAM0_RATIO2_SET + (blk->hdr_decompress1.knee_ratio2); + hd1->knee_ratio23 |=3D + NEO_HDR_DECOMPRESS1_KNEE_RATIO23_CAM0_RATIO3_SET + (blk->hdr_decompress1.knee_ratio3); + hd1->knee_ratio4 =3D + NEO_HDR_DECOMPRESS1_KNEE_RATIO4_CAM0_RATIO4_SET + (blk->hdr_decompress1.knee_ratio4); + hd1->knee_npoint0 =3D + NEO_HDR_DECOMPRESS1_KNEE_NPOINT0_CAM0_KNEEPOINT_SET + (blk->hdr_decompress1.knee_npoint0); + hd1->knee_npoint1 =3D + NEO_HDR_DECOMPRESS1_KNEE_NPOINT1_CAM0_KNEEPOINT_SET + (blk->hdr_decompress1.knee_npoint1); + hd1->knee_npoint2 =3D + NEO_HDR_DECOMPRESS1_KNEE_NPOINT2_CAM0_KNEEPOINT_SET + (blk->hdr_decompress1.knee_npoint2); + hd1->knee_npoint3 =3D + NEO_HDR_DECOMPRESS1_KNEE_NPOINT3_CAM0_KNEEPOINT_SET + (blk->hdr_decompress1.knee_npoint3); + hd1->knee_npoint4 =3D + NEO_HDR_DECOMPRESS1_KNEE_NPOINT4_CAM0_KNEEPOINT_SET + (blk->hdr_decompress1.knee_npoint4); +} + +static void __neoisp_params_handler_obwb(struct neoisp_dev_s *neoispd, + union neoisp_params_block_u *blk, u8 id) +{ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context; + struct neoisp_obwb_s *obwb; + + 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: + dev_err(&neoispd->pdev->dev, "Unexpected OBWB instance %u\n", id); + return; + } + + obwb->ctrl =3D + NEO_OB_WB0_CTRL_CAM0_OBPP_SET(blk->obwb.ctrl_obpp); + obwb->r_ctrl =3D + NEO_OB_WB0_R_CTRL_CAM0_OFFSET_SET(blk->obwb.r_ctrl_offset) | + NEO_OB_WB0_R_CTRL_CAM0_GAIN_SET(blk->obwb.r_ctrl_gain); + obwb->gr_ctrl =3D + NEO_OB_WB0_GR_CTRL_CAM0_OFFSET_SET(blk->obwb.gr_ctrl_offset) | + NEO_OB_WB0_GR_CTRL_CAM0_GAIN_SET(blk->obwb.gr_ctrl_gain); + obwb->gb_ctrl =3D + NEO_OB_WB0_GB_CTRL_CAM0_OFFSET_SET(blk->obwb.gb_ctrl_offset) | + NEO_OB_WB0_GB_CTRL_CAM0_GAIN_SET(blk->obwb.gb_ctrl_gain); + obwb->b_ctrl =3D + NEO_OB_WB0_B_CTRL_CAM0_OFFSET_SET(blk->obwb.b_ctrl_offset) | + NEO_OB_WB0_B_CTRL_CAM0_GAIN_SET(blk->obwb.b_ctrl_gain); +} + +static void neoisp_params_handler_obwb0(struct neoisp_dev_s *neoispd, + union neoisp_params_block_u *blk) +{ + __neoisp_params_handler_obwb(neoispd, blk, 0); +} + +static void neoisp_params_handler_obwb1(struct neoisp_dev_s *neoispd, + union neoisp_params_block_u *blk) +{ + __neoisp_params_handler_obwb(neoispd, blk, 1); +} + +static void neoisp_params_handler_obwb2(struct neoisp_dev_s *neoispd, + union neoisp_params_block_u *blk) +{ + __neoisp_params_handler_obwb(neoispd, blk, 2); +} + +static void neoisp_params_handler_hdr_merge(struct neoisp_dev_s *neoispd, + union neoisp_params_block_u *blk) +{ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context; + struct neoisp_hdr_merge_s *hmg =3D &ctx->hw.hdr_merge; + + hmg->ctrl =3D + NEO_HDR_MERGE_CTRL_CAM0_OBPP_SET(blk->hdr_merge.ctrl_obpp) | + NEO_HDR_MERGE_CTRL_CAM0_MOTION_FIX_EN_SET(blk->hdr_merge.ctrl_motion_fix= _en) | + NEO_HDR_MERGE_CTRL_CAM0_BLEND_3X3_SET(blk->hdr_merge.ctrl_blend_3x3) | + NEO_HDR_MERGE_CTRL_CAM0_GAIN0BPP_SET(blk->hdr_merge.ctrl_gain0bpp) | + NEO_HDR_MERGE_CTRL_CAM0_GAIN1BPP_SET(blk->hdr_merge.ctrl_gain1bpp) | + NEO_HDR_MERGE_CTRL_CAM0_ENABLE_SET(blk->hdr_merge.ctrl_enable); + hmg->gain_offset =3D + NEO_HDR_MERGE_GAIN_OFFSET_CAM0_OFFSET0_SET(blk->hdr_merge.gain_offset_of= fset0) | + NEO_HDR_MERGE_GAIN_OFFSET_CAM0_OFFSET1_SET(blk->hdr_merge.gain_offset_of= fset1); + hmg->gain_scale =3D + NEO_HDR_MERGE_GAIN_SCALE_CAM0_SCALE0_SET(blk->hdr_merge.gain_scale_scale= 0) | + NEO_HDR_MERGE_GAIN_SCALE_CAM0_SCALE1_SET(blk->hdr_merge.gain_scale_scale= 1); + hmg->gain_shift =3D + NEO_HDR_MERGE_GAIN_SHIFT_CAM0_SHIFT0_SET(blk->hdr_merge.gain_shift_shift= 0) | + NEO_HDR_MERGE_GAIN_SHIFT_CAM0_SHIFT1_SET(blk->hdr_merge.gain_shift_shift= 1); + hmg->luma_th =3D + NEO_HDR_MERGE_LUMA_TH_CAM0_TH0_SET(blk->hdr_merge.luma_th_th0); + hmg->luma_scale =3D + NEO_HDR_MERGE_LUMA_SCALE_CAM0_SCALE_SET(blk->hdr_merge.luma_scale_scale)= | + NEO_HDR_MERGE_LUMA_SCALE_CAM0_SHIFT_SET(blk->hdr_merge.luma_scale_shift)= | + NEO_HDR_MERGE_LUMA_SCALE_CAM0_THSHIFT_SET(blk->hdr_merge.luma_scale_thsh= ift); + hmg->downscale =3D + NEO_HDR_MERGE_DOWNSCALE_CAM0_IMGSCALE0_SET(blk->hdr_merge.downscale_imgs= cale0) | + NEO_HDR_MERGE_DOWNSCALE_CAM0_IMGSCALE1_SET(blk->hdr_merge.downscale_imgs= cale1); + hmg->upscale =3D + NEO_HDR_MERGE_UPSCALE_CAM0_IMGSCALE0_SET(blk->hdr_merge.upscale_imgscale= 0) | + NEO_HDR_MERGE_UPSCALE_CAM0_IMGSCALE1_SET(blk->hdr_merge.upscale_imgscale= 1); + hmg->post_scale =3D + NEO_HDR_MERGE_POST_SCALE_CAM0_SCALE_SET(blk->hdr_merge.post_scale_scale); +} + +static void neoisp_params_handler_rgbir(struct neoisp_dev_s *neoispd, + union neoisp_params_block_u *blk) +{ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context; + struct neoisp_rgbir_s *rgbir =3D &ctx->hw.rgbir; + struct neoisp_stat_hist_cfg_s *hist; + + rgbir->ctrl =3D + NEO_RGBIR_CTRL_CAM0_ENABLE_SET(blk->rgbir.ctrl_enable); + rgbir->ccm0 =3D + NEO_RGBIR_CCM0_CAM0_CCM_SET(blk->rgbir.ccm0_ccm); + rgbir->ccm1 =3D + NEO_RGBIR_CCM1_CAM0_CCM_SET(blk->rgbir.ccm1_ccm); + rgbir->ccm2 =3D + NEO_RGBIR_CCM2_CAM0_CCM_SET(blk->rgbir.ccm2_ccm); + rgbir->ccm0_th =3D + NEO_RGBIR_CCM0_TH_CAM0_THRESHOLD_SET(blk->rgbir.ccm0_th_threshold); + rgbir->ccm1_th =3D + NEO_RGBIR_CCM1_TH_CAM0_THRESHOLD_SET(blk->rgbir.ccm1_th_threshold); + rgbir->ccm2_th =3D + NEO_RGBIR_CCM2_TH_CAM0_THRESHOLD_SET(blk->rgbir.ccm2_th_threshold); + rgbir->roi0_pos =3D + NEO_RGBIR_ROI0_POS_CAM0_XPOS_SET(blk->rgbir.roi[0].xpos) | + NEO_RGBIR_ROI0_POS_CAM0_YPOS_SET(blk->rgbir.roi[0].ypos); + rgbir->roi0_size =3D + NEO_RGBIR_ROI0_SIZE_CAM0_WIDTH_SET(blk->rgbir.roi[0].width) | + NEO_RGBIR_ROI0_SIZE_CAM0_HEIGHT_SET(blk->rgbir.roi[0].height); + rgbir->roi1_pos =3D + NEO_RGBIR_ROI1_POS_CAM0_XPOS_SET(blk->rgbir.roi[1].xpos) | + NEO_RGBIR_ROI1_POS_CAM0_YPOS_SET(blk->rgbir.roi[1].ypos); + rgbir->roi1_size =3D + NEO_RGBIR_ROI1_SIZE_CAM0_WIDTH_SET(blk->rgbir.roi[1].width) | + NEO_RGBIR_ROI1_SIZE_CAM0_HEIGHT_SET(blk->rgbir.roi[1].height); + hist =3D &blk->rgbir.hists[0]; + rgbir->hist0_ctrl =3D + NEO_RGBIR_HIST0_CTRL_CAM0_LIN_INPUT1_LOG_SET(hist->hist_ctrl_lin_input1_= log) | + NEO_RGBIR_HIST0_CTRL_CAM0_DIR_INPUT1_DIF_SET(hist->hist_ctrl_dir_input1_= dif) | + NEO_RGBIR_HIST0_CTRL_CAM0_PATTERN_SET(hist->hist_ctrl_pattern) | + NEO_RGBIR_HIST0_CTRL_CAM0_CHANNEL_SET(hist->hist_ctrl_channel) | + NEO_RGBIR_HIST0_CTRL_CAM0_OFFSET_SET(hist->hist_ctrl_offset); + rgbir->hist0_scale =3D + NEO_RGBIR_HIST0_SCALE_CAM0_SCALE_SET(hist->hist_scale_scale); + hist =3D &blk->rgbir.hists[1]; + rgbir->hist1_ctrl =3D + NEO_RGBIR_HIST1_CTRL_CAM0_LIN_INPUT1_LOG_SET(hist->hist_ctrl_lin_input1_= log) | + NEO_RGBIR_HIST1_CTRL_CAM0_DIR_INPUT1_DIF_SET(hist->hist_ctrl_dir_input1_= dif) | + NEO_RGBIR_HIST1_CTRL_CAM0_PATTERN_SET(hist->hist_ctrl_pattern) | + NEO_RGBIR_HIST1_CTRL_CAM0_CHANNEL_SET(hist->hist_ctrl_channel) | + NEO_RGBIR_HIST1_CTRL_CAM0_OFFSET_SET(hist->hist_ctrl_offset); + rgbir->hist1_scale =3D + NEO_RGBIR_HIST1_SCALE_CAM0_SCALE_SET(hist->hist_scale_scale); +} + +static void neoisp_params_handler_stat(struct neoisp_dev_s *neoispd, + union neoisp_params_block_u *blk) +{ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context; + struct neoisp_stat_s *stat =3D &ctx->hw.stat; + struct neoisp_stat_hist_cfg_s *hist; + + stat->roi0_pos =3D + NEO_STAT_ROI0_POS_CAM0_XPOS_SET(blk->stat.roi0.xpos) | + NEO_STAT_ROI0_POS_CAM0_YPOS_SET(blk->stat.roi0.ypos); + stat->roi0_size =3D + NEO_STAT_ROI0_SIZE_CAM0_WIDTH_SET(blk->stat.roi0.width) | + NEO_STAT_ROI0_SIZE_CAM0_HEIGHT_SET(blk->stat.roi0.height); + stat->roi1_pos =3D + NEO_STAT_ROI1_POS_CAM0_XPOS_SET(blk->stat.roi1.xpos) | + NEO_STAT_ROI1_POS_CAM0_YPOS_SET(blk->stat.roi1.ypos); + stat->roi1_size =3D + NEO_STAT_ROI1_SIZE_CAM0_WIDTH_SET(blk->stat.roi1.width) | + NEO_STAT_ROI1_SIZE_CAM0_HEIGHT_SET(blk->stat.roi1.height); + hist =3D &blk->stat.hists[0]; + stat->hist0_ctrl =3D + NEO_STAT_HIST0_CTRL_CAM0_LIN_INPUT1_LOG_SET(hist->hist_ctrl_lin_input1_l= og) | + NEO_STAT_HIST0_CTRL_CAM0_DIR_INPUT1_DIF_SET(hist->hist_ctrl_dir_input1_d= if) | + NEO_STAT_HIST0_CTRL_CAM0_PATTERN_SET(hist->hist_ctrl_pattern) | + NEO_STAT_HIST0_CTRL_CAM0_CHANNEL_SET(hist->hist_ctrl_channel) | + NEO_STAT_HIST0_CTRL_CAM0_OFFSET_SET(hist->hist_ctrl_offset); + stat->hist0_scale =3D + NEO_STAT_HIST0_SCALE_CAM0_SCALE_SET(hist->hist_scale_scale); + hist =3D &blk->stat.hists[1]; + stat->hist1_ctrl =3D + NEO_STAT_HIST1_CTRL_CAM0_LIN_INPUT1_LOG_SET(hist->hist_ctrl_lin_input1_l= og) | + NEO_STAT_HIST1_CTRL_CAM0_DIR_INPUT1_DIF_SET(hist->hist_ctrl_dir_input1_d= if) | + NEO_STAT_HIST1_CTRL_CAM0_PATTERN_SET(hist->hist_ctrl_pattern) | + NEO_STAT_HIST1_CTRL_CAM0_CHANNEL_SET(hist->hist_ctrl_channel) | + NEO_STAT_HIST1_CTRL_CAM0_OFFSET_SET(hist->hist_ctrl_offset); + stat->hist1_scale =3D + NEO_STAT_HIST1_SCALE_CAM0_SCALE_SET(hist->hist_scale_scale); + hist =3D &blk->stat.hists[2]; + stat->hist2_ctrl =3D + NEO_STAT_HIST2_CTRL_CAM0_LIN_INPUT1_LOG_SET(hist->hist_ctrl_lin_input1_l= og) | + NEO_STAT_HIST2_CTRL_CAM0_DIR_INPUT1_DIF_SET(hist->hist_ctrl_dir_input1_d= if) | + NEO_STAT_HIST2_CTRL_CAM0_PATTERN_SET(hist->hist_ctrl_pattern) | + NEO_STAT_HIST2_CTRL_CAM0_CHANNEL_SET(hist->hist_ctrl_channel) | + NEO_STAT_HIST2_CTRL_CAM0_OFFSET_SET(hist->hist_ctrl_offset); + stat->hist2_scale =3D + NEO_STAT_HIST2_SCALE_CAM0_SCALE_SET(hist->hist_scale_scale); + hist =3D &blk->stat.hists[3]; + stat->hist3_ctrl =3D + NEO_STAT_HIST2_CTRL_CAM0_LIN_INPUT1_LOG_SET(hist->hist_ctrl_lin_input1_l= og) | + NEO_STAT_HIST2_CTRL_CAM0_DIR_INPUT1_DIF_SET(hist->hist_ctrl_dir_input1_d= if) | + NEO_STAT_HIST2_CTRL_CAM0_PATTERN_SET(hist->hist_ctrl_pattern) | + NEO_STAT_HIST2_CTRL_CAM0_CHANNEL_SET(hist->hist_ctrl_channel) | + NEO_STAT_HIST2_CTRL_CAM0_OFFSET_SET(hist->hist_ctrl_offset); + stat->hist3_scale =3D + NEO_STAT_HIST3_SCALE_CAM0_SCALE_SET(hist->hist_scale_scale); +} + +static void neoisp_params_handler_ir_compress(struct neoisp_dev_s *neoispd, + union neoisp_params_block_u *blk) +{ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context; + struct neoisp_ir_compress_s *ircomp =3D &ctx->hw.ir_compress; + + ircomp->ctrl =3D + NEO_IR_COMPRESS_CTRL_CAM0_OBPP_SET(blk->ir_compress.ctrl_obpp) | + NEO_IR_COMPRESS_CTRL_CAM0_ENABLE_SET(blk->ir_compress.ctrl_enable); + ircomp->knee_point1 =3D + NEO_IR_COMPRESS_KNEE_POINT1_CAM0_KNEEPOINT_SET + (blk->ir_compress.knee_point1_kneepoint); + ircomp->knee_point2 =3D + NEO_IR_COMPRESS_KNEE_POINT2_CAM0_KNEEPOINT_SET + (blk->ir_compress.knee_point2_kneepoint); + ircomp->knee_point3 =3D + NEO_IR_COMPRESS_KNEE_POINT3_CAM0_KNEEPOINT_SET + (blk->ir_compress.knee_point3_kneepoint); + ircomp->knee_point4 =3D + NEO_IR_COMPRESS_KNEE_POINT4_CAM0_KNEEPOINT_SET + (blk->ir_compress.knee_point4_kneepoint); + ircomp->knee_offset0 =3D + NEO_IR_COMPRESS_KNEE_OFFSET0_CAM0_OFFSET_SET + (blk->ir_compress.knee_offset0_offset); + ircomp->knee_offset1 =3D + NEO_IR_COMPRESS_KNEE_OFFSET1_CAM0_OFFSET_SET + (blk->ir_compress.knee_offset1_offset); + ircomp->knee_offset2 =3D + NEO_IR_COMPRESS_KNEE_OFFSET2_CAM0_OFFSET_SET + (blk->ir_compress.knee_offset2_offset); + ircomp->knee_offset3 =3D + NEO_IR_COMPRESS_KNEE_OFFSET3_CAM0_OFFSET_SET + (blk->ir_compress.knee_offset3_offset); + ircomp->knee_offset4 =3D + NEO_IR_COMPRESS_KNEE_OFFSET4_CAM0_OFFSET_SET + (blk->ir_compress.knee_offset4_offset); + ircomp->knee_ratio01 =3D + NEO_IR_COMPRESS_KNEE_RATIO01_CAM0_RATIO0_SET + (blk->ir_compress.knee_ratio01_ratio0); + ircomp->knee_ratio01 |=3D + NEO_IR_COMPRESS_KNEE_RATIO01_CAM0_RATIO1_SET + (blk->ir_compress.knee_ratio01_ratio1); + ircomp->knee_ratio23 =3D + NEO_IR_COMPRESS_KNEE_RATIO23_CAM0_RATIO2_SET + (blk->ir_compress.knee_ratio23_ratio2); + ircomp->knee_ratio23 |=3D + NEO_IR_COMPRESS_KNEE_RATIO23_CAM0_RATIO3_SET + (blk->ir_compress.knee_ratio23_ratio3); + ircomp->knee_ratio4 =3D + NEO_IR_COMPRESS_KNEE_RATIO4_CAM0_RATIO4_SET + (blk->ir_compress.knee_ratio4_ratio4); + ircomp->knee_npoint0 =3D + NEO_IR_COMPRESS_KNEE_NPOINT0_CAM0_KNEEPOINT_SET + (blk->ir_compress.knee_npoint0_kneepoint); + ircomp->knee_npoint1 =3D + NEO_IR_COMPRESS_KNEE_NPOINT1_CAM0_KNEEPOINT_SET + (blk->ir_compress.knee_npoint1_kneepoint); + ircomp->knee_npoint2 =3D + NEO_IR_COMPRESS_KNEE_NPOINT2_CAM0_KNEEPOINT_SET + (blk->ir_compress.knee_npoint2_kneepoint); + ircomp->knee_npoint3 =3D + NEO_IR_COMPRESS_KNEE_NPOINT3_CAM0_KNEEPOINT_SET + (blk->ir_compress.knee_npoint3_kneepoint); + ircomp->knee_npoint4 =3D + NEO_IR_COMPRESS_KNEE_NPOINT4_CAM0_KNEEPOINT_SET + (blk->ir_compress.knee_npoint4_kneepoint); +} + +static void neoisp_params_handler_ctemp(struct neoisp_dev_s *neoispd, + union neoisp_params_block_u *blk) +{ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context; + struct neoisp_ctemp_s *ctemp =3D &ctx->hw.ctemp; + struct neoisp_ctemp_roi_desc_s *croi; + + ctemp->ctrl =3D + NEO_COLOR_TEMP_CTRL_CAM0_IBPP_SET(blk->ctemp.ctrl_ibpp) | + NEO_COLOR_TEMP_CTRL_CAM0_CSCON_SET(blk->ctemp.ctrl_cscon) | + NEO_COLOR_TEMP_CTRL_CAM0_ENABLE_SET(blk->ctemp.ctrl_enable); + ctemp->roi_pos =3D + NEO_COLOR_TEMP_ROI_POS_CAM0_XPOS_SET(blk->ctemp.roi.xpos) | + NEO_COLOR_TEMP_ROI_POS_CAM0_YPOS_SET(blk->ctemp.roi.ypos); + ctemp->roi_size =3D + NEO_COLOR_TEMP_ROI_SIZE_CAM0_WIDTH_SET(blk->ctemp.roi.width) | + NEO_COLOR_TEMP_ROI_SIZE_CAM0_HEIGHT_SET(blk->ctemp.roi.height); + ctemp->redgain =3D + NEO_COLOR_TEMP_REDGAIN_CAM0_MIN_SET(blk->ctemp.redgain_min) | + NEO_COLOR_TEMP_REDGAIN_CAM0_MAX_SET(blk->ctemp.redgain_max); + ctemp->bluegain =3D + NEO_COLOR_TEMP_BLUEGAIN_CAM0_MIN_SET(blk->ctemp.bluegain_min) | + NEO_COLOR_TEMP_BLUEGAIN_CAM0_MAX_SET(blk->ctemp.bluegain_max); + ctemp->point1 =3D + NEO_COLOR_TEMP_POINT1_CAM0_BLUE_SET(blk->ctemp.point1_blue) | + NEO_COLOR_TEMP_POINT1_CAM0_RED_SET(blk->ctemp.point1_red); + ctemp->point2 =3D + NEO_COLOR_TEMP_POINT2_CAM0_BLUE_SET(blk->ctemp.point2_blue) | + NEO_COLOR_TEMP_POINT2_CAM0_RED_SET(blk->ctemp.point2_red); + ctemp->hoffset =3D + NEO_COLOR_TEMP_HOFFSET_CAM0_RIGHT_SET(blk->ctemp.hoffset_right) | + NEO_COLOR_TEMP_HOFFSET_CAM0_LEFT_SET(blk->ctemp.hoffset_left); + ctemp->voffset =3D + NEO_COLOR_TEMP_VOFFSET_CAM0_UP_SET(blk->ctemp.voffset_up) | + NEO_COLOR_TEMP_VOFFSET_CAM0_DOWN_SET(blk->ctemp.voffset_down); + ctemp->point1_slope =3D + NEO_COLOR_TEMP_POINT1_SLOPE_CAM0_SLOPE_L_SET(blk->ctemp.point1_slope_slo= pe_l) | + NEO_COLOR_TEMP_POINT1_SLOPE_CAM0_SLOPE_R_SET(blk->ctemp.point1_slope_slo= pe_r); + ctemp->point2_slope =3D + NEO_COLOR_TEMP_POINT2_SLOPE_CAM0_SLOPE_L_SET(blk->ctemp.point2_slope_slo= pe_l) | + NEO_COLOR_TEMP_POINT2_SLOPE_CAM0_SLOPE_R_SET(blk->ctemp.point2_slope_slo= pe_r); + ctemp->luma_th =3D + NEO_COLOR_TEMP_LUMA_TH_CAM0_THL_SET(blk->ctemp.luma_th_thl) | + NEO_COLOR_TEMP_LUMA_TH_CAM0_THH_SET(blk->ctemp.luma_th_thh); + ctemp->csc_mat0 =3D + NEO_COLOR_TEMP_CSC_MAT0_CAM0_R0C0_SET(blk->ctemp.csc_matrix[0][0]) | + NEO_COLOR_TEMP_CSC_MAT0_CAM0_R0C1_SET(blk->ctemp.csc_matrix[0][1]); + ctemp->csc_mat1 =3D + NEO_COLOR_TEMP_CSC_MAT1_CAM0_R0C2_SET(blk->ctemp.csc_matrix[0][2]) | + NEO_COLOR_TEMP_CSC_MAT1_CAM0_R1C0_SET(blk->ctemp.csc_matrix[1][0]); + ctemp->csc_mat2 =3D + NEO_COLOR_TEMP_CSC_MAT2_CAM0_R1C1_SET(blk->ctemp.csc_matrix[1][1]) | + NEO_COLOR_TEMP_CSC_MAT2_CAM0_R1C2_SET(blk->ctemp.csc_matrix[1][2]); + ctemp->csc_mat3 =3D + NEO_COLOR_TEMP_CSC_MAT3_CAM0_R2C0_SET(blk->ctemp.csc_matrix[2][0]) | + NEO_COLOR_TEMP_CSC_MAT3_CAM0_R2C1_SET(blk->ctemp.csc_matrix[2][1]); + ctemp->csc_mat4 =3D + NEO_COLOR_TEMP_CSC_MAT4_CAM0_R2C2_SET(blk->ctemp.csc_matrix[2][2]); + ctemp->r_gr_offset =3D + NEO_COLOR_TEMP_R_GR_OFFSET_CAM0_OFFSET0_SET(blk->ctemp.offsets[0]) | + NEO_COLOR_TEMP_R_GR_OFFSET_CAM0_OFFSET1_SET(blk->ctemp.offsets[1]); + ctemp->gb_b_offset =3D + NEO_COLOR_TEMP_GB_B_OFFSET_CAM0_OFFSET0_SET(blk->ctemp.offsets[2]) | + NEO_COLOR_TEMP_GB_B_OFFSET_CAM0_OFFSET1_SET(blk->ctemp.offsets[3]); + ctemp->stat_blk_size0 =3D + NEO_COLOR_TEMP_STAT_BLK_SIZE0_XSIZE_SET(blk->ctemp.stat_blk_size0_xsize)= | + NEO_COLOR_TEMP_STAT_BLK_SIZE0_YSIZE_SET(blk->ctemp.stat_blk_size0_ysize); + croi =3D &blk->ctemp.color_rois[0]; + ctemp->croi0_pos =3D + NEO_COLOR_TEMP_CROI0_POS_CAM0_ROVERG_LOW_SET(croi->pos_roverg_low) | + NEO_COLOR_TEMP_CROI0_POS_CAM0_ROVERG_HIGH_SET(croi->pos_roverg_high) | + NEO_COLOR_TEMP_CROI0_POS_CAM0_BOVERG_LOW_SET(croi->pos_boverg_low) | + NEO_COLOR_TEMP_CROI0_POS_CAM0_BOVERG_HIGH_SET(croi->pos_boverg_high); + croi =3D &blk->ctemp.color_rois[1]; + ctemp->croi1_pos =3D + NEO_COLOR_TEMP_CROI1_POS_CAM0_ROVERG_LOW_SET(croi->pos_roverg_low) | + NEO_COLOR_TEMP_CROI1_POS_CAM0_ROVERG_HIGH_SET(croi->pos_roverg_high) | + NEO_COLOR_TEMP_CROI1_POS_CAM0_BOVERG_LOW_SET(croi->pos_boverg_low) | + NEO_COLOR_TEMP_CROI1_POS_CAM0_BOVERG_HIGH_SET(croi->pos_boverg_high); + croi =3D &blk->ctemp.color_rois[2]; + ctemp->croi2_pos =3D + NEO_COLOR_TEMP_CROI2_POS_CAM0_ROVERG_LOW_SET(croi->pos_roverg_low) | + NEO_COLOR_TEMP_CROI2_POS_CAM0_ROVERG_HIGH_SET(croi->pos_roverg_high) | + NEO_COLOR_TEMP_CROI2_POS_CAM0_BOVERG_LOW_SET(croi->pos_boverg_low) | + NEO_COLOR_TEMP_CROI2_POS_CAM0_BOVERG_HIGH_SET(croi->pos_boverg_high); + croi =3D &blk->ctemp.color_rois[3]; + ctemp->croi3_pos =3D + NEO_COLOR_TEMP_CROI3_POS_CAM0_ROVERG_LOW_SET(croi->pos_roverg_low) | + NEO_COLOR_TEMP_CROI3_POS_CAM0_ROVERG_HIGH_SET(croi->pos_roverg_high) | + NEO_COLOR_TEMP_CROI3_POS_CAM0_BOVERG_LOW_SET(croi->pos_boverg_low) | + NEO_COLOR_TEMP_CROI3_POS_CAM0_BOVERG_HIGH_SET(croi->pos_boverg_high); + croi =3D &blk->ctemp.color_rois[4]; + ctemp->croi4_pos =3D + NEO_COLOR_TEMP_CROI4_POS_CAM0_ROVERG_LOW_SET(croi->pos_roverg_low) | + NEO_COLOR_TEMP_CROI4_POS_CAM0_ROVERG_HIGH_SET(croi->pos_roverg_high) | + NEO_COLOR_TEMP_CROI4_POS_CAM0_BOVERG_LOW_SET(croi->pos_boverg_low) | + NEO_COLOR_TEMP_CROI4_POS_CAM0_BOVERG_HIGH_SET(croi->pos_boverg_high); + croi =3D &blk->ctemp.color_rois[5]; + ctemp->croi5_pos =3D + NEO_COLOR_TEMP_CROI5_POS_CAM0_ROVERG_LOW_SET(croi->pos_roverg_low) | + NEO_COLOR_TEMP_CROI5_POS_CAM0_ROVERG_HIGH_SET(croi->pos_roverg_high) | + NEO_COLOR_TEMP_CROI5_POS_CAM0_BOVERG_LOW_SET(croi->pos_boverg_low) | + NEO_COLOR_TEMP_CROI5_POS_CAM0_BOVERG_HIGH_SET(croi->pos_boverg_high); + croi =3D &blk->ctemp.color_rois[6]; + ctemp->croi6_pos =3D + NEO_COLOR_TEMP_CROI6_POS_CAM0_ROVERG_LOW_SET(croi->pos_roverg_low) | + NEO_COLOR_TEMP_CROI6_POS_CAM0_ROVERG_HIGH_SET(croi->pos_roverg_high) | + NEO_COLOR_TEMP_CROI6_POS_CAM0_BOVERG_LOW_SET(croi->pos_boverg_low) | + NEO_COLOR_TEMP_CROI6_POS_CAM0_BOVERG_HIGH_SET(croi->pos_boverg_high); + croi =3D &blk->ctemp.color_rois[7]; + ctemp->croi7_pos =3D + NEO_COLOR_TEMP_CROI7_POS_CAM0_ROVERG_LOW_SET(croi->pos_roverg_low) | + NEO_COLOR_TEMP_CROI7_POS_CAM0_ROVERG_HIGH_SET(croi->pos_roverg_high) | + NEO_COLOR_TEMP_CROI7_POS_CAM0_BOVERG_LOW_SET(croi->pos_boverg_low) | + NEO_COLOR_TEMP_CROI7_POS_CAM0_BOVERG_HIGH_SET(croi->pos_boverg_high); + croi =3D &blk->ctemp.color_rois[8]; + ctemp->croi8_pos =3D + NEO_COLOR_TEMP_CROI8_POS_CAM0_ROVERG_LOW_SET(croi->pos_roverg_low) | + NEO_COLOR_TEMP_CROI8_POS_CAM0_ROVERG_HIGH_SET(croi->pos_roverg_high) | + NEO_COLOR_TEMP_CROI8_POS_CAM0_BOVERG_LOW_SET(croi->pos_boverg_low) | + NEO_COLOR_TEMP_CROI8_POS_CAM0_BOVERG_HIGH_SET(croi->pos_boverg_high); + croi =3D &blk->ctemp.color_rois[9]; + ctemp->croi9_pos =3D + NEO_COLOR_TEMP_CROI9_POS_CAM0_ROVERG_LOW_SET(croi->pos_roverg_low) | + NEO_COLOR_TEMP_CROI9_POS_CAM0_ROVERG_HIGH_SET(croi->pos_roverg_high) | + NEO_COLOR_TEMP_CROI9_POS_CAM0_BOVERG_LOW_SET(croi->pos_boverg_low) | + NEO_COLOR_TEMP_CROI9_POS_CAM0_BOVERG_HIGH_SET(croi->pos_boverg_high); + ctemp->gr_avg_in =3D + NEO_COLOR_TEMP_GR_AVG_IN_CAM0_GR_AGV_SET(blk->ctemp.gr_avg_in_gr_agv); + ctemp->gb_avg_in =3D + NEO_COLOR_TEMP_GB_AVG_IN_CAM0_GB_AGV_SET(blk->ctemp.gb_avg_in_gb_agv); +} + +static void neoisp_params_handler_bnr(struct neoisp_dev_s *neoispd, + union neoisp_params_block_u *blk) +{ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context; + struct neoisp_bnr_s *bnr =3D &ctx->hw.bnr; + + bnr->ctrl =3D + NEO_BNR_CTRL_CAM0_OBPP_SET(blk->bnr.ctrl_obpp) | + NEO_BNR_CTRL_CAM0_DEBUG_SET(blk->bnr.ctrl_debug) | + NEO_BNR_CTRL_CAM0_NHOOD_SET(blk->bnr.ctrl_nhood) | + NEO_BNR_CTRL_CAM0_ENABLE_SET(blk->bnr.ctrl_enable); + bnr->ypeak =3D + NEO_BNR_YPEAK_CAM0_PEAK_LOW_SET(blk->bnr.ypeak_peak_low) | + NEO_BNR_YPEAK_CAM0_PEAK_SEL_SET(blk->bnr.ypeak_peak_sel) | + NEO_BNR_YPEAK_CAM0_PEAK_HIGH_SET(blk->bnr.ypeak_peak_high) | + NEO_BNR_YPEAK_CAM0_PEAK_OUTSEL_SET(blk->bnr.ypeak_peak_outsel); + bnr->yedge_th0 =3D + NEO_BNR_YEDGE_TH0_CAM0_EDGE_TH0_SET(blk->bnr.yedge_th0_edge_th0); + bnr->yedge_scale =3D + NEO_BNR_YEDGE_SCALE_CAM0_SCALE_SET(blk->bnr.yedge_scale_scale) | + NEO_BNR_YEDGE_SCALE_CAM0_SHIFT_SET(blk->bnr.yedge_scale_shift); + bnr->yedges_th0 =3D + NEO_BNR_YEDGES_TH0_CAM0_EDGE_TH0_SET(blk->bnr.yedges_th0_edge_th0); + bnr->yedges_scale =3D + NEO_BNR_YEDGES_SCALE_CAM0_SCALE_SET(blk->bnr.yedges_scale_scale) | + NEO_BNR_YEDGES_SCALE_CAM0_SHIFT_SET(blk->bnr.yedges_scale_shift); + bnr->yedgea_th0 =3D + NEO_BNR_YEDGEA_TH0_CAM0_EDGE_TH0_SET(blk->bnr.yedgea_th0_edge_th0); + bnr->yedgea_scale =3D + NEO_BNR_YEDGEA_SCALE_CAM0_SCALE_SET(blk->bnr.yedgea_scale_scale) | + NEO_BNR_YEDGEA_SCALE_CAM0_SHIFT_SET(blk->bnr.yedgea_scale_shift); + bnr->yluma_x_th0 =3D + NEO_BNR_YLUMA_X_TH0_CAM0_TH_SET(blk->bnr.yluma_x_th0_th); + bnr->yluma_y_th =3D + NEO_BNR_YLUMA_Y_TH_CAM0_LUMA_Y_TH0_SET(blk->bnr.yluma_y_th_luma_y_th0) | + NEO_BNR_YLUMA_Y_TH_CAM0_LUMA_Y_TH1_SET(blk->bnr.yluma_y_th_luma_y_th1); + bnr->yluma_scale =3D + NEO_BNR_YLUMA_SCALE_CAM0_SCALE_SET(blk->bnr.yluma_scale_scale) | + NEO_BNR_YLUMA_SCALE_CAM0_SHIFT_SET(blk->bnr.yluma_scale_shift); + bnr->yalpha_gain =3D + NEO_BNR_YALPHA_GAIN_CAM0_GAIN_SET(blk->bnr.yalpha_gain_gain) | + NEO_BNR_YALPHA_GAIN_CAM0_OFFSET_SET(blk->bnr.yalpha_gain_offset); + bnr->cpeak =3D + NEO_BNR_CPEAK_CAM0_PEAK_LOW_SET(blk->bnr.cpeak_peak_low) | + NEO_BNR_CPEAK_CAM0_PEAK_SEL_SET(blk->bnr.cpeak_peak_sel) | + NEO_BNR_CPEAK_CAM0_PEAK_HIGH_SET(blk->bnr.cpeak_peak_high) | + NEO_BNR_CPEAK_CAM0_PEAK_OUTSEL_SET(blk->bnr.cpeak_peak_outsel); + bnr->cedge_th0 =3D + NEO_BNR_CEDGE_TH0_CAM0_EDGE_TH0_SET(blk->bnr.cedge_th0_edge_th0); + bnr->cedge_scale =3D + NEO_BNR_CEDGE_SCALE_CAM0_SCALE_SET(blk->bnr.cedge_scale_scale) | + NEO_BNR_CEDGE_SCALE_CAM0_SHIFT_SET(blk->bnr.cedge_scale_shift); + bnr->cedges_th0 =3D + NEO_BNR_CEDGES_TH0_CAM0_EDGE_TH0_SET(blk->bnr.cedges_th0_edge_th0); + bnr->cedges_scale =3D + NEO_BNR_CEDGES_SCALE_CAM0_SCALE_SET(blk->bnr.cedges_scale_scale) | + NEO_BNR_CEDGES_SCALE_CAM0_SHIFT_SET(blk->bnr.cedges_scale_shift); + bnr->cedgea_th0 =3D + NEO_BNR_CEDGEA_TH0_CAM0_EDGE_TH0_SET(blk->bnr.cedgea_th0_edge_th0); + bnr->cedgea_scale =3D + NEO_BNR_CEDGEA_SCALE_CAM0_SCALE_SET(blk->bnr.cedgea_scale_scale) | + NEO_BNR_CEDGEA_SCALE_CAM0_SHIFT_SET(blk->bnr.cedgea_scale_shift); + bnr->cluma_x_th0 =3D + NEO_BNR_CLUMA_X_TH0_CAM0_TH_SET(blk->bnr.cluma_x_th0_th); + bnr->cluma_y_th =3D + NEO_BNR_CLUMA_Y_TH_CAM0_LUMA_Y_TH0_SET(blk->bnr.cluma_y_th_luma_y_th0) | + NEO_BNR_CLUMA_Y_TH_CAM0_LUMA_Y_TH1_SET(blk->bnr.cluma_y_th_luma_y_th1); + bnr->cluma_scale =3D + NEO_BNR_CLUMA_SCALE_CAM0_SCALE_SET(blk->bnr.cluma_scale_scale) | + NEO_BNR_CLUMA_SCALE_CAM0_SHIFT_SET(blk->bnr.cluma_scale_shift); + bnr->calpha_gain =3D + NEO_BNR_CALPHA_GAIN_CAM0_GAIN_SET(blk->bnr.calpha_gain_gain) | + NEO_BNR_CALPHA_GAIN_CAM0_OFFSET_SET(blk->bnr.calpha_gain_offset); + bnr->stretch =3D + NEO_BNR_STRETCH_CAM0_GAIN_SET(blk->bnr.stretch_gain); +} + +static void neoisp_params_handler_vignetting_ctrl(struct neoisp_dev_s *neo= ispd, + union neoisp_params_block_u *blk) +{ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context; + struct neoisp_vignetting_ctrl_s *vignetting =3D &ctx->hw.vignetting_ctrl; + + vignetting->ctrl =3D + NEO_VIGNETTING_CTRL_CAM0_ENABLE_SET(blk->vignetting_ctrl.ctrl_enable); + vignetting->blk_conf =3D + NEO_VIGNETTING_BLK_CONF_CAM0_COLS_SET(blk->vignetting_ctrl.blk_conf_cols= ) | + NEO_VIGNETTING_BLK_CONF_CAM0_ROWS_SET(blk->vignetting_ctrl.blk_conf_rows= ); + vignetting->blk_size =3D + NEO_VIGNETTING_BLK_SIZE_CAM0_XSIZE_SET(blk->vignetting_ctrl.blk_size_xsi= ze) | + NEO_VIGNETTING_BLK_SIZE_CAM0_YSIZE_SET(blk->vignetting_ctrl.blk_size_ysi= ze); + vignetting->blk_stepy =3D + NEO_VIGNETTING_BLK_STEPY_CAM0_STEP_SET(blk->vignetting_ctrl.blk_stepy_st= ep); + vignetting->blk_stepx =3D + NEO_VIGNETTING_BLK_STEPX_CAM0_STEP_SET(blk->vignetting_ctrl.blk_stepx_st= ep); +} + +static void neoisp_params_handler_demosaic(struct neoisp_dev_s *neoispd, + union neoisp_params_block_u *blk) +{ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context; + struct neoisp_demosaic_s *demosaic =3D &ctx->hw.demosaic; + + demosaic->ctrl =3D + NEO_DEMOSAIC_CTRL_CAM0_FMT_SET(blk->demosaic.ctrl_fmt); + demosaic->activity_ctl =3D + NEO_DEMOSAIC_ACTIVITY_CTL_CAM0_ALPHA_SET(blk->demosaic.activity_ctl_alph= a) | + NEO_DEMOSAIC_ACTIVITY_CTL_CAM0_ACT_RATIO_SET(blk->demosaic.activity_ctl_= act_ratio); + demosaic->dynamics_ctl0 =3D + NEO_DEMOSAIC_DYNAMICS_CTL0_CAM0_STRENGTHG_SET + (blk->demosaic.dynamics_ctl0_strengthg); + demosaic->dynamics_ctl0 |=3D + NEO_DEMOSAIC_DYNAMICS_CTL0_CAM0_STRENGTHC_SET + (blk->demosaic.dynamics_ctl0_strengthc); + demosaic->dynamics_ctl2 =3D + NEO_DEMOSAIC_DYNAMICS_CTL2_CAM0_MAX_IMPACT_SET + (blk->demosaic.dynamics_ctl2_max_impact); +} + +static void neoisp_params_handler_rgb2yuv(struct neoisp_dev_s *neoispd, + union neoisp_params_block_u *blk) +{ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context; + struct neoisp_rgb2yuv_s *rgb2yuv =3D &ctx->hw.rgb2yuv; + + rgb2yuv->gain_ctrl =3D + NEO_RGB_TO_YUV_GAIN_CTRL_CAM0_RGAIN_SET(blk->rgb2yuv.gain_ctrl_rgain) | + NEO_RGB_TO_YUV_GAIN_CTRL_CAM0_BGAIN_SET(blk->rgb2yuv.gain_ctrl_bgain); + rgb2yuv->mat0 =3D + NEO_RGB_TO_YUV_MAT0_CAM0_R0C0_SET(blk->rgb2yuv.mat_rxcy[0][0]) | + NEO_RGB_TO_YUV_MAT0_CAM0_R0C1_SET(blk->rgb2yuv.mat_rxcy[0][1]); + rgb2yuv->mat1 =3D + NEO_RGB_TO_YUV_MAT1_CAM0_R0C2_SET(blk->rgb2yuv.mat_rxcy[0][2]); + rgb2yuv->mat2 =3D + NEO_RGB_TO_YUV_MAT2_CAM0_R1C0_SET(blk->rgb2yuv.mat_rxcy[1][0]) | + NEO_RGB_TO_YUV_MAT2_CAM0_R1C1_SET(blk->rgb2yuv.mat_rxcy[1][1]); + rgb2yuv->mat3 =3D + NEO_RGB_TO_YUV_MAT3_CAM0_R1C2_SET(blk->rgb2yuv.mat_rxcy[1][2]); + rgb2yuv->mat4 =3D + NEO_RGB_TO_YUV_MAT4_CAM0_R2C0_SET(blk->rgb2yuv.mat_rxcy[2][0]) | + NEO_RGB_TO_YUV_MAT4_CAM0_R2C1_SET(blk->rgb2yuv.mat_rxcy[2][1]); + rgb2yuv->mat5 =3D + NEO_RGB_TO_YUV_MAT5_CAM0_R2C2_SET(blk->rgb2yuv.mat_rxcy[2][2]); + rgb2yuv->offset0 =3D + NEO_RGB_TO_YUV_OFFSET0_CAM0_OFFSET_SET(blk->rgb2yuv.csc_offsets[0]); + rgb2yuv->offset1 =3D + NEO_RGB_TO_YUV_OFFSET1_CAM0_OFFSET_SET(blk->rgb2yuv.csc_offsets[1]); + rgb2yuv->offset2 =3D + NEO_RGB_TO_YUV_OFFSET2_CAM0_OFFSET_SET(blk->rgb2yuv.csc_offsets[2]); +} + +static void neoisp_params_handler_dr_comp(struct neoisp_dev_s *neoispd, + union neoisp_params_block_u *blk) +{ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context; + struct neoisp_drc_s *drc =3D &ctx->hw.drc; + + drc->roi0_pos =3D + NEO_DRC_ROI0_POS_CAM0_XPOS_SET(blk->drc.roi0.xpos) | + NEO_DRC_ROI0_POS_CAM0_YPOS_SET(blk->drc.roi0.ypos); + drc->roi0_size =3D + NEO_DRC_ROI0_SIZE_CAM0_WIDTH_SET(blk->drc.roi0.width) | + NEO_DRC_ROI0_SIZE_CAM0_HEIGHT_SET(blk->drc.roi0.height); + drc->roi1_pos =3D + NEO_DRC_ROI1_POS_CAM0_XPOS_SET(blk->drc.roi1.xpos) | + NEO_DRC_ROI1_POS_CAM0_YPOS_SET(blk->drc.roi1.ypos); + drc->roi1_size =3D + NEO_DRC_ROI1_SIZE_CAM0_WIDTH_SET(blk->drc.roi1.width) | + NEO_DRC_ROI1_SIZE_CAM0_HEIGHT_SET(blk->drc.roi1.height); + drc->groi_sum_shift =3D + NEO_DRC_GROI_SUM_SHIFT_CAM0_SHIFT0_SET(blk->drc.groi_sum_shift_shift0) | + NEO_DRC_GROI_SUM_SHIFT_CAM0_SHIFT1_SET(blk->drc.groi_sum_shift_shift1); + drc->gbl_gain =3D + NEO_DRC_GBL_GAIN_CAM0_GAIN_SET(blk->drc.gbl_gain_gain); + drc->lcl_blk_size =3D + NEO_DRC_LCL_BLK_SIZE_CAM0_XSIZE_SET(blk->drc.lcl_blk_size_xsize) | + NEO_DRC_LCL_BLK_SIZE_CAM0_YSIZE_SET(blk->drc.lcl_blk_size_ysize); + drc->lcl_stretch =3D + NEO_DRC_LCL_STRETCH_CAM0_STRETCH_SET(blk->drc.lcl_stretch_stretch) | + NEO_DRC_LCL_STRETCH_CAM0_OFFSET_SET(blk->drc.lcl_stretch_offset); + drc->lcl_blk_stepy =3D + NEO_DRC_LCL_BLK_STEPY_CAM0_STEP_SET(blk->drc.lcl_blk_stepy_step); + drc->lcl_blk_stepx =3D + NEO_DRC_LCL_BLK_STEPX_CAM0_STEP_SET(blk->drc.lcl_blk_stepx_step); + drc->lcl_sum_shift =3D + NEO_DRC_LCL_SUM_SHIFT_CAM0_SHIFT_SET(blk->drc.lcl_sum_shift_shift); + drc->alpha =3D + NEO_DRC_ALPHA_CAM0_ALPHA_SET(blk->drc.alpha_alpha); +} + +static void neoisp_params_handler_nr(struct neoisp_dev_s *neoispd, + union neoisp_params_block_u *blk) +{ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context; + struct neoisp_nr_s *nr =3D &ctx->hw.nr; + + nr->ctrl =3D + NEO_NR_CTRL_CAM0_DEBUG_SET(blk->nrc.ctrl_debug) | + NEO_NR_CTRL_CAM0_ENABLE_SET(blk->nrc.ctrl_enable); + nr->blend_scale =3D + NEO_NR_BLEND_SCALE_CAM0_SCALE_SET(blk->nrc.blend_scale_scale) | + NEO_NR_BLEND_SCALE_CAM0_SHIFT_SET(blk->nrc.blend_scale_shift) | + NEO_NR_BLEND_SCALE_CAM0_GAIN_SET(blk->nrc.blend_scale_gain); + nr->blend_th0 =3D + NEO_NR_BLEND_TH0_CAM0_TH_SET(blk->nrc.blend_th0_th); +} + +static void neoisp_params_handler_df(struct neoisp_dev_s *neoispd, + union neoisp_params_block_u *blk) +{ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context; + struct neoisp_df_s *df =3D &ctx->hw.df; + + df->ctrl =3D + NEO_DF_CTRL_CAM0_DEBUG_SET(blk->dfc.ctrl_debug) | + NEO_DF_CTRL_CAM0_ENABLE_SET(blk->dfc.ctrl_enable); + df->th_scale =3D + NEO_DF_TH_SCALE_CAM0_SCALE_SET(blk->dfc.th_scale_scale); + df->blend_shift =3D + NEO_DF_BLEND_SHIFT_CAM0_SHIFT_SET(blk->dfc.blend_shift_shift); + df->blend_th0 =3D + NEO_DF_BLEND_TH0_CAM0_TH_SET(blk->dfc.blend_th0_th); +} + +static void neoisp_params_handler_ee(struct neoisp_dev_s *neoispd, + union neoisp_params_block_u *blk) +{ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context; + struct neoisp_ee_s *ee =3D &ctx->hw.ee; + + ee->ctrl =3D + NEO_EE_CTRL_CAM0_DEBUG_SET(blk->eec.ctrl_debug) | + NEO_EE_CTRL_CAM0_ENABLE_SET(blk->eec.ctrl_enable); + ee->coring =3D + NEO_EE_CORING_CAM0_CORING_SET(blk->eec.coring_coring); + ee->clip =3D + NEO_EE_CLIP_CAM0_CLIP_SET(blk->eec.clip_clip); + ee->maskgain =3D + NEO_EE_MASKGAIN_CAM0_GAIN_SET(blk->eec.maskgain_gain); +} + +static void neoisp_params_handler_convmed(struct neoisp_dev_s *neoispd, + union neoisp_params_block_u *blk) +{ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context; + struct neoisp_convmed_s *convmed =3D &ctx->hw.convmed; + + convmed->ctrl =3D + NEO_CCONVMED_CTRL_CAM0_FLT_SET(blk->convmed.ctrl_flt); +} + +static void neoisp_params_handler_cas(struct neoisp_dev_s *neoispd, + union neoisp_params_block_u *blk) +{ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context; + struct neoisp_cas_s *cas =3D &ctx->hw.cas; + + cas->gain =3D + NEO_CAS_GAIN_CAM0_SCALE_SET(blk->cas.gain_scale) | + NEO_CAS_GAIN_CAM0_SHIFT_SET(blk->cas.gain_shift); + cas->corr =3D + NEO_CAS_CORR_CAM0_CORR_SET(blk->cas.corr_corr); + cas->offset =3D + NEO_CAS_OFFSET_CAM0_OFFSET_SET(blk->cas.offset_offset); +} + +static void neoisp_params_handler_gcm(struct neoisp_dev_s *neoispd, + union neoisp_params_block_u *blk) +{ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context; + struct neoisp_gcm_s *gcm =3D &ctx->hw.gcm; + + gcm->imat0 =3D + NEO_GCM_IMAT0_CAM0_R0C0_SET(blk->gcm.imat_rxcy[0][0]) | + NEO_GCM_IMAT0_CAM0_R0C1_SET(blk->gcm.imat_rxcy[0][1]); + gcm->imat1 =3D + NEO_GCM_IMAT1_CAM0_R0C2_SET(blk->gcm.imat_rxcy[0][2]); + gcm->imat2 =3D + NEO_GCM_IMAT2_CAM0_R1C0_SET(blk->gcm.imat_rxcy[1][0]) | + NEO_GCM_IMAT2_CAM0_R1C1_SET(blk->gcm.imat_rxcy[1][1]); + gcm->imat3 =3D + NEO_GCM_IMAT3_CAM0_R1C2_SET(blk->gcm.imat_rxcy[1][2]); + gcm->imat4 =3D + NEO_GCM_IMAT4_CAM0_R2C0_SET(blk->gcm.imat_rxcy[2][0]) | + NEO_GCM_IMAT4_CAM0_R2C1_SET(blk->gcm.imat_rxcy[2][1]); + gcm->imat5 =3D + NEO_GCM_IMAT5_CAM0_R2C2_SET(blk->gcm.imat_rxcy[2][2]); + gcm->ioffset0 =3D + NEO_GCM_IOFFSET0_CAM0_OFFSET0_SET(blk->gcm.ioffsets[0]); + gcm->ioffset1 =3D + NEO_GCM_IOFFSET1_CAM0_OFFSET1_SET(blk->gcm.ioffsets[1]); + gcm->ioffset2 =3D + NEO_GCM_IOFFSET2_CAM0_OFFSET2_SET(blk->gcm.ioffsets[2]); + gcm->omat0 =3D + NEO_GCM_OMAT0_CAM0_R0C0_SET(blk->gcm.omat_rxcy[0][0]) | + NEO_GCM_OMAT0_CAM0_R0C1_SET(blk->gcm.omat_rxcy[0][1]); + gcm->omat1 =3D + NEO_GCM_OMAT1_CAM0_R0C2_SET(blk->gcm.omat_rxcy[0][2]); + gcm->omat2 =3D + NEO_GCM_OMAT2_CAM0_R1C0_SET(blk->gcm.omat_rxcy[1][0]) | + NEO_GCM_OMAT2_CAM0_R1C1_SET(blk->gcm.omat_rxcy[1][1]); + gcm->omat3 =3D + NEO_GCM_OMAT3_CAM0_R1C2_SET(blk->gcm.omat_rxcy[1][2]); + gcm->omat4 =3D + NEO_GCM_OMAT4_CAM0_R2C0_SET(blk->gcm.omat_rxcy[2][0]) | + NEO_GCM_OMAT4_CAM0_R2C1_SET(blk->gcm.omat_rxcy[2][1]); + gcm->omat5 =3D + NEO_GCM_OMAT5_CAM0_R2C2_SET(blk->gcm.omat_rxcy[2][2]); + gcm->ooffset0 =3D + NEO_GCM_OOFFSET0_CAM0_OFFSET0_SET(blk->gcm.ooffsets[0]); + gcm->ooffset1 =3D + NEO_GCM_OOFFSET1_CAM0_OFFSET1_SET(blk->gcm.ooffsets[1]); + gcm->ooffset2 =3D + NEO_GCM_OOFFSET2_CAM0_OFFSET2_SET(blk->gcm.ooffsets[2]); + gcm->gamma0 =3D + NEO_GCM_GAMMA0_CAM0_GAMMA0_SET(blk->gcm.gamma0_gamma0) | + NEO_GCM_GAMMA0_CAM0_OFFSET0_SET(blk->gcm.gamma0_offset0); + gcm->gamma1 =3D + NEO_GCM_GAMMA1_CAM0_GAMMA1_SET(blk->gcm.gamma1_gamma1) | + NEO_GCM_GAMMA1_CAM0_OFFSET1_SET(blk->gcm.gamma1_offset1); + gcm->gamma2 =3D + NEO_GCM_GAMMA2_CAM0_GAMMA2_SET(blk->gcm.gamma2_gamma2) | + NEO_GCM_GAMMA2_CAM0_OFFSET2_SET(blk->gcm.gamma2_offset2); + gcm->blklvl0_ctrl =3D + NEO_GCM_BLKLVL0_CTRL_CAM0_OFFSET0_SET(blk->gcm.blklvl0_ctrl_offset0) | + NEO_GCM_BLKLVL0_CTRL_CAM0_GAIN0_SET(blk->gcm.blklvl0_ctrl_gain0); + gcm->blklvl1_ctrl =3D + NEO_GCM_BLKLVL1_CTRL_CAM0_OFFSET1_SET(blk->gcm.blklvl1_ctrl_offset1) | + NEO_GCM_BLKLVL1_CTRL_CAM0_GAIN1_SET(blk->gcm.blklvl1_ctrl_gain1); + gcm->blklvl2_ctrl =3D + NEO_GCM_BLKLVL2_CTRL_CAM0_OFFSET2_SET(blk->gcm.blklvl2_ctrl_offset2) | + NEO_GCM_BLKLVL2_CTRL_CAM0_GAIN2_SET(blk->gcm.blklvl2_ctrl_gain2); + gcm->lowth_ctrl01 =3D + NEO_GCM_LOWTH_CTRL01_CAM0_THRESHOLD0_SET(blk->gcm.lowth_ctrl01_threshold= 0) | + NEO_GCM_LOWTH_CTRL01_CAM0_THRESHOLD1_SET(blk->gcm.lowth_ctrl01_threshold= 1); + gcm->lowth_ctrl2 =3D + NEO_GCM_LOWTH_CTRL2_CAM0_THRESHOLD2_SET(blk->gcm.lowth_ctrl2_threshold2); + gcm->mat_confg =3D + NEO_GCM_MAT_CONFG_CAM0_SIGN_CONFG_SET(blk->gcm.mat_confg_sign_confg); +} + +static void neoisp_params_handler_af(struct neoisp_dev_s *neoispd, + union neoisp_params_block_u *blk) +{ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context; + struct neoisp_autofocus_s *af =3D &ctx->hw.autofocus; + + af->roi0_pos =3D + NEO_AUTOFOCUS_ROI0_POS_CAM0_XPOS_SET(blk->afc.af_roi[0].xpos) | + NEO_AUTOFOCUS_ROI0_POS_CAM0_YPOS_SET(blk->afc.af_roi[0].ypos); + af->roi0_size =3D + NEO_AUTOFOCUS_ROI0_SIZE_CAM0_WIDTH_SET(blk->afc.af_roi[0].width) | + NEO_AUTOFOCUS_ROI0_SIZE_CAM0_HEIGHT_SET(blk->afc.af_roi[0].height); + af->roi1_pos =3D + NEO_AUTOFOCUS_ROI1_POS_CAM0_XPOS_SET(blk->afc.af_roi[1].xpos) | + NEO_AUTOFOCUS_ROI1_POS_CAM0_YPOS_SET(blk->afc.af_roi[1].ypos); + af->roi1_size =3D + NEO_AUTOFOCUS_ROI1_SIZE_CAM0_WIDTH_SET(blk->afc.af_roi[1].width) | + NEO_AUTOFOCUS_ROI1_SIZE_CAM0_HEIGHT_SET(blk->afc.af_roi[1].height); + af->roi2_pos =3D + NEO_AUTOFOCUS_ROI2_POS_CAM0_XPOS_SET(blk->afc.af_roi[2].xpos) | + NEO_AUTOFOCUS_ROI2_POS_CAM0_YPOS_SET(blk->afc.af_roi[2].ypos); + af->roi2_size =3D + NEO_AUTOFOCUS_ROI2_SIZE_CAM0_WIDTH_SET(blk->afc.af_roi[2].width) | + NEO_AUTOFOCUS_ROI2_SIZE_CAM0_HEIGHT_SET(blk->afc.af_roi[2].height); + af->roi3_pos =3D + NEO_AUTOFOCUS_ROI3_POS_CAM0_XPOS_SET(blk->afc.af_roi[3].xpos) | + NEO_AUTOFOCUS_ROI3_POS_CAM0_YPOS_SET(blk->afc.af_roi[3].ypos); + af->roi3_size =3D + NEO_AUTOFOCUS_ROI3_SIZE_CAM0_WIDTH_SET(blk->afc.af_roi[3].width) | + NEO_AUTOFOCUS_ROI3_SIZE_CAM0_HEIGHT_SET(blk->afc.af_roi[3].height); + af->roi4_pos =3D + NEO_AUTOFOCUS_ROI4_POS_CAM0_XPOS_SET(blk->afc.af_roi[4].xpos) | + NEO_AUTOFOCUS_ROI4_POS_CAM0_YPOS_SET(blk->afc.af_roi[4].ypos); + af->roi4_size =3D + NEO_AUTOFOCUS_ROI4_SIZE_CAM0_WIDTH_SET(blk->afc.af_roi[4].width) | + NEO_AUTOFOCUS_ROI4_SIZE_CAM0_HEIGHT_SET(blk->afc.af_roi[4].height); + af->roi5_pos =3D + NEO_AUTOFOCUS_ROI5_POS_CAM0_XPOS_SET(blk->afc.af_roi[5].xpos) | + NEO_AUTOFOCUS_ROI5_POS_CAM0_YPOS_SET(blk->afc.af_roi[5].ypos); + af->roi5_size =3D + NEO_AUTOFOCUS_ROI5_SIZE_CAM0_WIDTH_SET(blk->afc.af_roi[5].width) | + NEO_AUTOFOCUS_ROI5_SIZE_CAM0_HEIGHT_SET(blk->afc.af_roi[5].height); + af->roi6_pos =3D + NEO_AUTOFOCUS_ROI6_POS_CAM0_XPOS_SET(blk->afc.af_roi[6].xpos) | + NEO_AUTOFOCUS_ROI6_POS_CAM0_YPOS_SET(blk->afc.af_roi[6].ypos); + af->roi6_size =3D + NEO_AUTOFOCUS_ROI6_SIZE_CAM0_WIDTH_SET(blk->afc.af_roi[6].width) | + NEO_AUTOFOCUS_ROI6_SIZE_CAM0_HEIGHT_SET(blk->afc.af_roi[6].height); + af->roi7_pos =3D + NEO_AUTOFOCUS_ROI7_POS_CAM0_XPOS_SET(blk->afc.af_roi[7].xpos) | + NEO_AUTOFOCUS_ROI7_POS_CAM0_YPOS_SET(blk->afc.af_roi[7].ypos); + af->roi7_size =3D + NEO_AUTOFOCUS_ROI7_SIZE_CAM0_WIDTH_SET(blk->afc.af_roi[7].width) | + NEO_AUTOFOCUS_ROI7_SIZE_CAM0_HEIGHT_SET(blk->afc.af_roi[7].height); + af->roi8_pos =3D + NEO_AUTOFOCUS_ROI8_POS_CAM0_XPOS_SET(blk->afc.af_roi[8].xpos) | + NEO_AUTOFOCUS_ROI8_POS_CAM0_YPOS_SET(blk->afc.af_roi[8].ypos); + af->roi8_size =3D + NEO_AUTOFOCUS_ROI8_SIZE_CAM0_WIDTH_SET(blk->afc.af_roi[8].width) | + NEO_AUTOFOCUS_ROI8_SIZE_CAM0_HEIGHT_SET(blk->afc.af_roi[8].height); + af->fil0_coeffs0 =3D + NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0_COEFF0_SET(blk->afc.fil0_coeffs[0]) | + NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0_COEFF1_SET(blk->afc.fil0_coeffs[1]) | + NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0_COEFF2_SET(blk->afc.fil0_coeffs[2]) | + NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0_COEFF3_SET(blk->afc.fil0_coeffs[3]); + af->fil0_coeffs1 =3D + NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0_COEFF4_SET(blk->afc.fil0_coeffs[4]) | + NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0_COEFF5_SET(blk->afc.fil0_coeffs[5]) | + NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0_COEFF6_SET(blk->afc.fil0_coeffs[6]) | + NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0_COEFF7_SET(blk->afc.fil0_coeffs[7]); + af->fil0_coeffs2 =3D + NEO_AUTOFOCUS_FIL0_COEFFS2_CAM0_COEFF8_SET(blk->afc.fil0_coeffs[8]); + af->fil0_shift =3D + NEO_AUTOFOCUS_FIL0_SHIFT_CAM0_SHIFT_SET(blk->afc.fil0_shift_shift); + af->fil1_coeffs0 =3D + NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0_COEFF0_SET(blk->afc.fil1_coeffs[0]) | + NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0_COEFF1_SET(blk->afc.fil1_coeffs[1]) | + NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0_COEFF2_SET(blk->afc.fil1_coeffs[2]) | + NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0_COEFF3_SET(blk->afc.fil1_coeffs[3]); + af->fil1_coeffs1 =3D + NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0_COEFF4_SET(blk->afc.fil1_coeffs[4]) | + NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0_COEFF5_SET(blk->afc.fil1_coeffs[5]) | + NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0_COEFF6_SET(blk->afc.fil1_coeffs[6]) | + NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0_COEFF7_SET(blk->afc.fil1_coeffs[7]); + af->fil1_coeffs2 =3D + NEO_AUTOFOCUS_FIL1_COEFFS2_CAM0_COEFF8_SET(blk->afc.fil1_coeffs[8]); + af->fil1_shift =3D + NEO_AUTOFOCUS_FIL1_SHIFT_CAM0_SHIFT_SET(blk->afc.fil1_shift_shift); +} + +static void neoisp_params_handler_vignetting_table(struct neoisp_dev_s *ne= oispd, + union neoisp_params_block_u *blk) +{ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context; + + memcpy((u8 *)(uintptr_t)&ctx->vig, + (u8 *)(uintptr_t)blk->vignetting_table.vignetting_table, + sizeof(struct neoisp_vignetting_table_mem_params_s)); +} + +static void neoisp_params_handler_drc_global_tonemap(struct neoisp_dev_s *= neoispd, + union neoisp_params_block_u *blk) +{ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context; + + memcpy((u8 *)(uintptr_t)&ctx->gtm, + (u8 *)(uintptr_t)blk->drc_global_tonemap.drc_global_tonemap, + sizeof(struct neoisp_drc_global_tonemap_mem_params_s)); +} + +static void neoisp_params_handler_drc_local_tonemap(struct neoisp_dev_s *n= eoispd, + union neoisp_params_block_u *blk) +{ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context; + + memcpy((u8 *)(uintptr_t)&ctx->ltm, + (u8 *)(uintptr_t)blk->drc_local_tonemap.drc_local_tonemap, + sizeof(struct neoisp_drc_local_tonemap_mem_params_s)); +} + +/* + * Extended params block handlers + * + * Handlers are created with below macros. Extended parameters handlers go= al is + * to prepare all the block parameters' fields, then forward to the second + * level handler (used from legacy API too) that performs the copy into hw + * context memory region. The extended parameters handlers check block siz= e and + * header flag from the struct c:type:`v4l2_isp_params_block_header`. Flag= s are + * not handled the same on all macros, depending on ISP blocks. Reason is = that + * some ISP blocks do have a ctrl_enable bit, then associated contexts do = have + * ctrl_enable field, while some other ISP blocks don't. + * + * When ctrl_enable bit is present: + * - if :c:type:`v4l2_isp_params_block_header` flag is set to either ENAB= LE + * or DISABLE, then the block's parameter `ctrl_enable` field is configure= d the + * same. + * - if :c:type:`v4l2_isp_params_block_header` flag is not set at all, th= en + * the `ctrl_enable` value from the hw context is copied to the block's + * parameters `ctrl_enable` field. This is because 2nd level handler uses = all + * the parameters block fields and overwrite the whole hw context. Thus we + * ensure that `ctrl_enable` in hw context is overwritten with same value. + * - According to v4l2-isp documentation, a block data could be omitted if + * DISABLE flag is set. In such case, the `ctrl_enable` field value from t= he hw + * context is forced to DISABLE. + * + * When `ctrl_enable` bit is not present in an ISP block, all the block fi= elds + * are shared to the 2nd level handler, to be copied into hw context, exce= pt + * when the :c:type:`v4l2_isp_params_block_header` flag is DISABLED and the + * block is empty. In such case, the block is simply ignored. + */ +#define NEOISP_EXT_PARAMS_HANDLER(block, type) \ + static void neoisp_ext_params_handler_ ## block \ + (struct neoisp_dev_s *neoispd, \ + union neoisp_ext_params_block_u *ext_blk) \ + { \ + struct neoisp_ ## block ## _ ## type ## _es *ext_params =3D &ext_blk->bl= ock; \ + if (ext_params->header.flags =3D=3D V4L2_ISP_PARAMS_FL_BLOCK_DISABLE && \ + ext_params->header.size =3D=3D sizeof(struct v4l2_isp_params_block_h= eader)) \ + /* Only header w/ DISABLE flag, then bypass context update */ \ + return; \ + union neoisp_params_block_u *cfg =3D \ + (union neoisp_params_block_u *)&ext_params->cfg; \ + neoisp_params_handler_ ## block(neoispd, cfg); \ + } + +#define NEOISP_EXT_PARAMS_HANDLER_MULT(block, inst) \ + static void neoisp_ext_params_handler_ ## block ## inst \ + (struct neoisp_dev_s *neoispd, \ + union neoisp_ext_params_block_u *ext_blk) \ + { \ + struct neoisp_ ## block ## _cfg_es *ext_params =3D &ext_blk->block; \ + if (ext_params->header.flags =3D=3D V4L2_ISP_PARAMS_FL_BLOCK_DISABLE && \ + ext_params->header.size =3D=3D sizeof(struct v4l2_isp_params_block_h= eader)) \ + /* Only header w/ DISABLE flag, then bypass context update */ \ + return; \ + union neoisp_params_block_u *cfg =3D \ + (union neoisp_params_block_u *)&ext_params->cfg; \ + __neoisp_params_handler_ ## block(neoispd, cfg, inst); \ + } + +#define NEOISP_EXT_PARAMS_HANDLER_CTRL_ENABLE(block) \ + static void neoisp_ext_params_handler_ ## block \ + (struct neoisp_dev_s *neoispd, \ + union neoisp_ext_params_block_u *ext_blk) \ + { \ + struct neoisp_ ## block ## _cfg_es *ext_params =3D &ext_blk->block; \ + union neoisp_params_block_u *cfg; \ + struct neoisp_context_s *ctx =3D neoispd->queued_job.node_group->context= ; \ + struct neoisp_ ## block ## _s *blk =3D &ctx->hw.block; \ + if (ext_params->header.flags =3D=3D V4L2_ISP_PARAMS_FL_BLOCK_DISABLE && \ + ext_params->header.size =3D=3D sizeof(struct v4l2_isp_params_block_h= eader)) { \ + /* Only header w/ DISABLE flag, then disable in context */ \ + blk->ctrl =3D 0; \ + return; \ + } \ + if (ext_params->header.flags =3D=3D V4L2_ISP_PARAMS_FL_BLOCK_DISABLE) \ + ext_params->cfg.ctrl_enable =3D 0; \ + else if (ext_params->header.flags =3D=3D V4L2_ISP_PARAMS_FL_BLOCK_ENABLE= ) \ + ext_params->cfg.ctrl_enable =3D 1; \ + else \ + ext_params->cfg.ctrl_enable =3D blk->ctrl; \ + cfg =3D (union neoisp_params_block_u *)&ext_params->cfg; \ + neoisp_params_handler_ ## block(neoispd, cfg); \ + } + +#define NEOISP_EXT_PARAMS_HANDLER_CFG(block) \ + NEOISP_EXT_PARAMS_HANDLER(block, cfg) + +NEOISP_EXT_PARAMS_HANDLER_CFG(pipe_conf) +NEOISP_EXT_PARAMS_HANDLER_CFG(head_color) +NEOISP_EXT_PARAMS_HANDLER_CTRL_ENABLE(hdr_decompress0) +NEOISP_EXT_PARAMS_HANDLER_CTRL_ENABLE(hdr_decompress1) +NEOISP_EXT_PARAMS_HANDLER_MULT(obwb, 0) +NEOISP_EXT_PARAMS_HANDLER_MULT(obwb, 1) +NEOISP_EXT_PARAMS_HANDLER_MULT(obwb, 2) +NEOISP_EXT_PARAMS_HANDLER_CTRL_ENABLE(hdr_merge) +NEOISP_EXT_PARAMS_HANDLER_CTRL_ENABLE(rgbir) +NEOISP_EXT_PARAMS_HANDLER_CFG(stat) +NEOISP_EXT_PARAMS_HANDLER_CTRL_ENABLE(ir_compress) +NEOISP_EXT_PARAMS_HANDLER_CTRL_ENABLE(bnr) +NEOISP_EXT_PARAMS_HANDLER_CTRL_ENABLE(vignetting_ctrl) +NEOISP_EXT_PARAMS_HANDLER_CTRL_ENABLE(ctemp) +NEOISP_EXT_PARAMS_HANDLER_CFG(demosaic) +NEOISP_EXT_PARAMS_HANDLER_CFG(rgb2yuv) +NEOISP_EXT_PARAMS_HANDLER_CFG(dr_comp) +NEOISP_EXT_PARAMS_HANDLER_CTRL_ENABLE(nr) +NEOISP_EXT_PARAMS_HANDLER_CFG(af) +NEOISP_EXT_PARAMS_HANDLER_CTRL_ENABLE(ee) +NEOISP_EXT_PARAMS_HANDLER_CTRL_ENABLE(df) +NEOISP_EXT_PARAMS_HANDLER_CFG(convmed) +NEOISP_EXT_PARAMS_HANDLER_CFG(cas) +NEOISP_EXT_PARAMS_HANDLER_CFG(gcm) +NEOISP_EXT_PARAMS_HANDLER(vignetting_table, mem_params) +NEOISP_EXT_PARAMS_HANDLER(drc_global_tonemap, mem_params) +NEOISP_EXT_PARAMS_HANDLER(drc_local_tonemap, mem_params) + +static const struct neoisp_block_handler_s { + size_t size; + void (*handler)(struct neoisp_dev_s *neoispd, union neoisp_params_block_u= *blk); + void (*ext_handler)(struct neoisp_dev_s *neoispd, union neoisp_ext_params= _block_u *ext_blk); +} neoisp_block_handlers[] =3D { + [NEOISP_PARAM_BLK_PIPE_CONF] =3D { + .size =3D sizeof(struct neoisp_pipe_conf_cfg_s), + .handler =3D &neoisp_params_handler_pipe_conf, + .ext_handler =3D &neoisp_ext_params_handler_pipe_conf, + }, + [NEOISP_PARAM_BLK_HEAD_COLOR] =3D { + .size =3D sizeof(struct neoisp_head_color_cfg_s), + .handler =3D &neoisp_params_handler_head_color, + .ext_handler =3D &neoisp_ext_params_handler_head_color, + }, + [NEOISP_PARAM_BLK_HDR_DECOMPRESS0] =3D { + .size =3D sizeof(struct neoisp_hdr_decompress0_cfg_s), + .handler =3D &neoisp_params_handler_hdr_decompress0, + .ext_handler =3D &neoisp_ext_params_handler_hdr_decompress0, + }, + [NEOISP_PARAM_BLK_HDR_DECOMPRESS1] =3D { + .size =3D sizeof(struct neoisp_hdr_decompress1_cfg_s), + .handler =3D &neoisp_params_handler_hdr_decompress1, + .ext_handler =3D &neoisp_ext_params_handler_hdr_decompress1, + }, + [NEOISP_PARAM_BLK_OBWB0] =3D { + .size =3D sizeof(struct neoisp_obwb_cfg_s), + .handler =3D &neoisp_params_handler_obwb0, + .ext_handler =3D &neoisp_ext_params_handler_obwb0, + }, + [NEOISP_PARAM_BLK_OBWB1] =3D { + .size =3D sizeof(struct neoisp_obwb_cfg_s), + .handler =3D &neoisp_params_handler_obwb1, + .ext_handler =3D &neoisp_ext_params_handler_obwb1, + }, + [NEOISP_PARAM_BLK_OBWB2] =3D { + .size =3D sizeof(struct neoisp_obwb_cfg_s), + .handler =3D &neoisp_params_handler_obwb2, + .ext_handler =3D &neoisp_ext_params_handler_obwb2, + }, + [NEOISP_PARAM_BLK_HDR_MERGE] =3D { + .size =3D sizeof(struct neoisp_hdr_merge_cfg_s), + .handler =3D &neoisp_params_handler_hdr_merge, + .ext_handler =3D &neoisp_ext_params_handler_hdr_merge, + }, + [NEOISP_PARAM_BLK_RGBIR] =3D { + .size =3D sizeof(struct neoisp_rgbir_cfg_s), + .handler =3D &neoisp_params_handler_rgbir, + .ext_handler =3D &neoisp_ext_params_handler_rgbir, + }, + [NEOISP_PARAM_BLK_STAT] =3D { + .size =3D sizeof(struct neoisp_stat_cfg_s), + .handler =3D &neoisp_params_handler_stat, + .ext_handler =3D &neoisp_ext_params_handler_stat, + }, + [NEOISP_PARAM_BLK_IR_COMPRESS] =3D { + .size =3D sizeof(struct neoisp_ir_compress_cfg_s), + .handler =3D &neoisp_params_handler_ir_compress, + .ext_handler =3D &neoisp_ext_params_handler_ir_compress, + }, + [NEOISP_PARAM_BLK_BNR] =3D { + .size =3D sizeof(struct neoisp_bnr_cfg_s), + .handler =3D &neoisp_params_handler_bnr, + .ext_handler =3D &neoisp_ext_params_handler_bnr, + }, + [NEOISP_PARAM_BLK_VIGNETTING_CTRL] =3D { + .size =3D sizeof(struct neoisp_vignetting_ctrl_cfg_s), + .handler =3D &neoisp_params_handler_vignetting_ctrl, + .ext_handler =3D &neoisp_ext_params_handler_vignetting_ctrl, + }, + [NEOISP_PARAM_BLK_CTEMP] =3D { + .size =3D sizeof(struct neoisp_ctemp_cfg_s), + .handler =3D &neoisp_params_handler_ctemp, + .ext_handler =3D &neoisp_ext_params_handler_ctemp, + }, + [NEOISP_PARAM_BLK_DEMOSAIC] =3D { + .size =3D sizeof(struct neoisp_demosaic_cfg_s), + .handler =3D &neoisp_params_handler_demosaic, + .ext_handler =3D &neoisp_ext_params_handler_demosaic, + }, + [NEOISP_PARAM_BLK_RGB2YUV] =3D { + .size =3D sizeof(struct neoisp_rgb2yuv_cfg_s), + .handler =3D &neoisp_params_handler_rgb2yuv, + .ext_handler =3D &neoisp_ext_params_handler_rgb2yuv, + }, + [NEOISP_PARAM_BLK_DR_COMP] =3D { + .size =3D sizeof(struct neoisp_dr_comp_cfg_s), + .handler =3D &neoisp_params_handler_dr_comp, + .ext_handler =3D &neoisp_ext_params_handler_dr_comp, + }, + [NEOISP_PARAM_BLK_NR] =3D { + .size =3D sizeof(struct neoisp_nr_cfg_s), + .handler =3D &neoisp_params_handler_nr, + .ext_handler =3D &neoisp_ext_params_handler_nr, + }, + [NEOISP_PARAM_BLK_AF] =3D { + .size =3D sizeof(struct neoisp_af_cfg_s), + .handler =3D &neoisp_params_handler_af, + .ext_handler =3D &neoisp_ext_params_handler_af, + }, + [NEOISP_PARAM_BLK_EE] =3D { + .size =3D sizeof(struct neoisp_ee_cfg_s), + .handler =3D &neoisp_params_handler_ee, + .ext_handler =3D &neoisp_ext_params_handler_ee, + }, + [NEOISP_PARAM_BLK_DF] =3D { + .size =3D sizeof(struct neoisp_df_cfg_s), + .handler =3D &neoisp_params_handler_df, + .ext_handler =3D &neoisp_ext_params_handler_df, + }, + [NEOISP_PARAM_BLK_CONVMED] =3D { + .size =3D sizeof(struct neoisp_convmed_cfg_s), + .handler =3D &neoisp_params_handler_convmed, + .ext_handler =3D &neoisp_ext_params_handler_convmed, + }, + [NEOISP_PARAM_BLK_CAS] =3D { + .size =3D sizeof(struct neoisp_cas_cfg_s), + .handler =3D &neoisp_params_handler_cas, + .ext_handler =3D &neoisp_ext_params_handler_cas, + }, + [NEOISP_PARAM_BLK_GCM] =3D { + .size =3D sizeof(struct neoisp_gcm_cfg_s), + .handler =3D &neoisp_params_handler_gcm, + .ext_handler =3D &neoisp_ext_params_handler_gcm, + }, + [NEOISP_PARAM_BLK_VIGNETTING_TABLE] =3D { + .size =3D sizeof(struct neoisp_vignetting_table_mem_params_s), + .handler =3D &neoisp_params_handler_vignetting_table, + .ext_handler =3D &neoisp_ext_params_handler_vignetting_table, + }, + [NEOISP_PARAM_BLK_DRC_GLOBAL_TONEMAP] =3D { + .size =3D sizeof(struct neoisp_drc_global_tonemap_mem_params_s), + .handler =3D &neoisp_params_handler_drc_global_tonemap, + .ext_handler =3D &neoisp_ext_params_handler_drc_global_tonemap, + }, + [NEOISP_PARAM_BLK_DRC_LOCAL_TONEMAP] =3D { + .size =3D sizeof(struct neoisp_drc_local_tonemap_mem_params_s), + .handler =3D &neoisp_params_handler_drc_local_tonemap, + .ext_handler =3D &neoisp_ext_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_dev_s *neoispd, struct n= eoisp_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 &job->node_group->context->hw.pipe_con= f.common; + 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 width, height, ibpp, inp0_stride, inp1_stride; + dma_addr_t inp0_addr, inp1_addr; + + /* Input0 specific */ + nd =3D &job->node_group->node[NEOISP_INPUT0_NODE]; + width =3D nd->crop.width; + height =3D nd->crop.height; + 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 &job->node_group->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 + NEO_PIPE_CONF_ADDR_SET(inp0_addr); + + /* Handle hdr inputs */ + nd =3D &job->node_group->node[NEOISP_INPUT1_NODE]; + if (neoisp_node_link_is_enabled(nd)) { + cfg->img1_in_addr =3D + NEO_PIPE_CONF_ADDR_SET(inp1_addr); + } + + nd =3D &job->node_group->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 + NEO_PIPE_CONF_ADDR_SET(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 + NEO_PIPE_CONF_ADDR_SET(get_addr(buf_out, 0)); + cfg->outch1_addr =3D + NEO_PIPE_CONF_ADDR_SET(get_addr(buf_out, 1)); + break; + default: + /* Interleaved formats: only output channel 1 is used */ + cfg->outch1_addr =3D + NEO_PIPE_CONF_ADDR_SET(get_addr(buf_out, 0)); + break; + } + } + + nd =3D &job->node_group->node[NEOISP_IR_NODE]; + if (neoisp_node_link_is_enabled(nd)) + cfg->outir_addr =3D + NEO_PIPE_CONF_ADDR_SET(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 + NEO_GCM_LOWTH_CTRL01_CAM0_THRESHOLD0_SET(xfer_lut[xfer].threshold) | + NEO_GCM_LOWTH_CTRL01_CAM0_THRESHOLD1_SET(xfer_lut[xfer].threshold); + gcm->lowth_ctrl2 =3D + NEO_GCM_LOWTH_CTRL2_CAM0_THRESHOLD2_SET(xfer_lut[xfer].threshold); + + tmp =3D NEO_GCM_BLKLVL0_CTRL_CAM0_OFFSET0_GET(gcm->blklvl0_ctrl); + gcm->blklvl0_ctrl |=3D + NEO_GCM_BLKLVL0_CTRL_CAM0_OFFSET0_SET(tmp) | + NEO_GCM_BLKLVL0_CTRL_CAM0_GAIN0_SET(xfer_lut[xfer].blklvl_gain); + + tmp =3D NEO_GCM_BLKLVL1_CTRL_CAM0_OFFSET1_GET(gcm->blklvl1_ctrl); + gcm->blklvl1_ctrl |=3D + NEO_GCM_BLKLVL1_CTRL_CAM0_OFFSET1_SET(tmp) | + NEO_GCM_BLKLVL1_CTRL_CAM0_GAIN1_SET(xfer_lut[xfer].blklvl_gain); + + tmp =3D NEO_GCM_BLKLVL2_CTRL_CAM0_OFFSET2_GET(gcm->blklvl2_ctrl); + gcm->blklvl2_ctrl |=3D + NEO_GCM_BLKLVL2_CTRL_CAM0_OFFSET2_SET(tmp) | + NEO_GCM_BLKLVL2_CTRL_CAM0_GAIN2_SET(xfer_lut[xfer].blklvl_gain); + + gcm->gamma0 =3D + NEO_GCM_GAMMA0_CAM0_GAMMA0_SET(xfer_lut[xfer].gamma) | + NEO_GCM_GAMMA0_CAM0_OFFSET0_SET(xfer_lut[xfer].gamma_offset); + gcm->gamma1 =3D + NEO_GCM_GAMMA1_CAM0_GAMMA1_SET(xfer_lut[xfer].gamma) | + NEO_GCM_GAMMA1_CAM0_OFFSET1_SET(xfer_lut[xfer].gamma_offset); + gcm->gamma2 =3D + NEO_GCM_GAMMA2_CAM0_GAMMA2_SET(xfer_lut[xfer].gamma) | + NEO_GCM_GAMMA2_CAM0_OFFSET2_SET(xfer_lut[xfer].gamma_offset); + + /* 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 NEO_GCM_OOFFSET0_CAM0_OFFSET0_SET(tmp); + + /* Chrominance has the same offset for full or limited range */ + gcm->ooffset1 =3D NEO_GCM_OOFFSET1_CAM0_OFFSET1_SET(enc_lut[enc].offsets[= 1]); + gcm->ooffset2 =3D NEO_GCM_OOFFSET2_CAM0_OFFSET2_SET(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 + NEO_GCM_OMAT0_CAM0_R0C0_SET(tmat[0][0]) | + NEO_GCM_OMAT0_CAM0_R0C1_SET(tmat[0][1]); + gcm->omat1 =3D + NEO_GCM_OMAT1_CAM0_R0C2_SET(tmat[0][2]); + gcm->omat2 =3D + NEO_GCM_OMAT2_CAM0_R1C0_SET(tmat[1][0]) | + NEO_GCM_OMAT2_CAM0_R1C1_SET(tmat[1][1]); + gcm->omat3 =3D + NEO_GCM_OMAT3_CAM0_R1C2_SET(tmat[1][2]); + gcm->omat4 =3D + NEO_GCM_OMAT4_CAM0_R2C0_SET(tmat[2][0]) | + NEO_GCM_OMAT4_CAM0_R2C1_SET(tmat[2][1]); + gcm->omat5 =3D + NEO_GCM_OMAT5_CAM0_R2C2_SET(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; + + hmg->ctrl |=3D NEO_HDR_MERGE_CTRL_CAM0_ENABLE; + hd1->ctrl |=3D NEO_HDR_DECOMPRESS1_CTRL_CAM0_ENABLE; +} + +/* + * 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; + } + hc->ctrl =3D + NEO_HC_CTRL_CAM0_HOFFSET_SET(hoffset) | + NEO_HC_CTRL_CAM0_VOFFSET_SET(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)) { + dmsc->ctrl =3D NEO_DEMOSAIC_CTRL_CAM0_FMT_SET(2); /* Monochrome format */ + bnr->ctrl |=3D NEO_BNR_CTRL_CAM0_NHOOD; /* 1-pixel Neighbourhood */ + } else { + dmsc->ctrl =3D NEO_DEMOSAIC_CTRL_CAM0_FMT_SET(0); /* Bayer format */ + bnr->ctrl &=3D ~NEO_BNR_CTRL_CAM0_NHOOD; /* 2-pixel Neighbourhood */ + } +} + +void neoisp_ctx_update_packetizer(struct neoisp_node_group_s *node_group) +{ + struct neoisp_dev_s *neoispd =3D node_group->neoisp_dev; + struct neoisp_node_s *nd =3D &node_group->node[NEOISP_FRAME_NODE]; + struct neoisp_packetizer_s *pck =3D &node_group->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->pdev->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 + NEO_PACKETIZER_CH0_CTRL_CAM0_OBPP_SET(obpp) | + NEO_PACKETIZER_CH0_CTRL_CAM0_RSA_SET(rsa) | + NEO_PACKETIZER_CH0_CTRL_CAM0_LSA_SET(lsa); + + /* Keep same ch12 lsa/rsa config. */ + lsa =3D NEO_PACKETIZER_CH12_CTRL_CAM0_LSA_GET(pck->ch12_ctrl); + rsa =3D NEO_PACKETIZER_CH12_CTRL_CAM0_RSA_GET(pck->ch12_ctrl); + pck->ch12_ctrl =3D + NEO_PACKETIZER_CH12_CTRL_CAM0_OBPP_SET(obpp) | + NEO_PACKETIZER_CH12_CTRL_CAM0_RSA_SET(rsa) | + NEO_PACKETIZER_CH12_CTRL_CAM0_LSA_SET(lsa) | + NEO_PACKETIZER_CH12_CTRL_CAM0_SUBSAMPLE_SET(subsample); + pck->pack_ctrl =3D + NEO_PACKETIZER_PACK_CTRL_CAM0_TYPE_SET(type) | + NEO_PACKETIZER_PACK_CTRL_CAM0_ORDER0_SET(order0) | + NEO_PACKETIZER_PACK_CTRL_CAM0_ORDER1_SET(order1) | + NEO_PACKETIZER_PACK_CTRL_CAM0_ORDER2_SET(order2) | + NEO_PACKETIZER_PACK_CTRL_CAM0_A0S_SET(a0s); +} + +/* + * Set pipe conf fixed settings: image size, bpp, line stride, and dummy + * addresses. + */ +void neoisp_ctx_update_pipe_conf(struct neoisp_node_group_s *node_group) +{ + struct neoisp_pipe_conf_s *cfg =3D &node_group->context->hw.pipe_conf.com= mon; + struct neoisp_node_s *nd; + u32 tmp, width, height, obpp, irbpp, inp0_stride, inp1_stride; + + /* Input0 specific */ + nd =3D &node_group->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; + + tmp =3D cfg->img_conf & ~NEO_PIPE_CONF_IMG_CONF_CAM0_IBPP0_MASK; + tmp |=3D NEO_PIPE_CONF_IMG_CONF_CAM0_IBPP0_SET(nd->neoisp_format->bpp_enc= ); + cfg->img_conf =3D tmp; + + /* Input 1 specific */ + nd =3D &node_group->node[NEOISP_INPUT1_NODE]; + inp1_stride =3D nd->format.fmt.pix_mp.plane_fmt[0].bytesperline; + + tmp =3D cfg->img_conf & ~NEO_PIPE_CONF_IMG_CONF_CAM0_IBPP1_MASK; + tmp |=3D NEO_PIPE_CONF_IMG_CONF_CAM0_IBPP1_SET(nd->neoisp_format->bpp_enc= ); + cfg->img_conf =3D tmp; + + /* Configure registers */ + cfg->img_size =3D + NEO_PIPE_CONF_IMG_SIZE_CAM0_WIDTH_SET(width) | + NEO_PIPE_CONF_IMG_SIZE_CAM0_HEIGHT_SET(height); + cfg->img0_in_ls =3D + NEO_PIPE_CONF_IMG0_IN_LS_CAM0_LS_SET(inp0_stride); + + /* Handle hdr inputs */ + nd =3D &node_group->node[NEOISP_INPUT1_NODE]; + if (neoisp_node_link_is_enabled(nd)) { + cfg->img1_in_ls =3D + NEO_PIPE_CONF_IMG1_IN_LS_CAM0_LS_SET(inp1_stride); + } else { + cfg->img1_in_addr =3D + NEO_PIPE_CONF_ADDR_SET(0u); + cfg->img1_in_ls =3D + NEO_PIPE_CONF_IMG1_IN_LS_CAM0_LS_SET(0u); + } + + nd =3D &node_group->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 + NEO_PIPE_CONF_ADDR_SET(node_group->dummy_dma); + + cfg->outch0_ls =3D + NEO_PIPE_CONF_OUTCH0_LS_CAM0_LS_SET(obpp * width); + cfg->outch1_ls =3D + NEO_PIPE_CONF_OUTCH1_LS_CAM0_LS_SET(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 + NEO_PIPE_CONF_OUTCH1_LS_CAM0_LS_SET(obpp * width); + cfg->outch0_ls =3D + NEO_PIPE_CONF_OUTCH0_LS_CAM0_LS_SET(obpp * width); + break; + default: + /* + * Interleaved formats: + * - output0 is not used at all + * - output1 is used for YUV or RGB components + */ + cfg->outch0_addr =3D + NEO_PIPE_CONF_ADDR_SET(0u); + cfg->outch0_ls =3D + NEO_PIPE_CONF_OUTCH0_LS_CAM0_LS_SET(0u); + cfg->outch1_ls =3D + NEO_PIPE_CONF_OUTCH1_LS_CAM0_LS_SET(obpp * width); + break; + } + } else { + /* Default dummy pixelformat is set to YUYV */ + cfg->outch0_addr =3D + NEO_PIPE_CONF_ADDR_SET(node_group->dummy_dma); + cfg->outch1_addr =3D + NEO_PIPE_CONF_ADDR_SET(node_group->dummy_dma); + cfg->outch0_ls =3D + NEO_PIPE_CONF_OUTCH0_LS_CAM0_LS_SET(0u); + cfg->outch1_ls =3D + NEO_PIPE_CONF_OUTCH1_LS_CAM0_LS_SET(0u); + } + + nd =3D &node_group->node[NEOISP_IR_NODE]; + if (neoisp_node_link_is_enabled(nd)) { + irbpp =3D (nd->neoisp_format->bit_depth + 7) / 8; + + cfg->outir_ls =3D + NEO_PIPE_CONF_OUTIR_LS_CAM0_LS_SET(irbpp * width); + } else { + cfg->outir_addr =3D + NEO_PIPE_CONF_ADDR_SET(node_group->dummy_dma); + cfg->outir_ls =3D + NEO_PIPE_CONF_OUTIR_LS_CAM0_LS_SET(0u); + } +} + +/* + * neoisp_ctx_update_w_user_params is used to update the context of the + * queued node_group 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 neoisp_node_group_s *node_group =3D neoispd->queued_job.node_group; + struct neoisp_node_s *node =3D &node_group->node[NEOISP_PARAMS_NODE]; + + if (IS_ERR_OR_NULL(buf)) + return; + + /* Check parameters buffer format */ + switch (node->neoisp_format->fourcc) { + case V4L2_META_FMT_NEO_ISP_PARAMS: { + /* Legacy params API */ + struct neoisp_meta_params_s *lparams =3D + (struct neoisp_meta_params_s *)get_vaddr(buf); + const struct neoisp_block_handler_s *block_handler; + union neoisp_params_block_u *block; + + /* Update selected blocks wrt feature config flag */ + if (lparams->features_cfg.pipe_conf_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_PIPE_CONF]; + block =3D (union neoisp_params_block_u *)&lparams->regs.pipe_conf; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.head_color_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_HEAD_COLOR]; + block =3D (union neoisp_params_block_u *)&lparams->regs.head_color; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.hdr_decompress_input0_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_HDR_DECOMPRES= S0]; + block =3D (union neoisp_params_block_u *)&lparams->regs.decompress_inpu= t0; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.hdr_decompress_input1_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_HDR_DECOMPRES= S1]; + block =3D (union neoisp_params_block_u *)&lparams->regs.decompress_inpu= t1; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.obwb0_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_OBWB0]; + block =3D (union neoisp_params_block_u *)&lparams->regs.obwb[0]; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.obwb1_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_OBWB1]; + block =3D (union neoisp_params_block_u *)&lparams->regs.obwb[1]; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.obwb2_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_OBWB2]; + block =3D (union neoisp_params_block_u *)&lparams->regs.obwb[2]; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.hdr_merge_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_HDR_MERGE]; + block =3D (union neoisp_params_block_u *)&lparams->regs.hdr_merge; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.rgbir_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_RGBIR]; + block =3D (union neoisp_params_block_u *)&lparams->regs.rgbir; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.stat_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_STAT]; + block =3D (union neoisp_params_block_u *)&lparams->regs.stat; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.ir_compress_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_IR_COMPRESS]; + block =3D (union neoisp_params_block_u *)&lparams->regs.ir_compress; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.bnr_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_BNR]; + block =3D (union neoisp_params_block_u *)&lparams->regs.bnr; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.vignetting_ctrl_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_VIGNETTING_CT= RL]; + block =3D (union neoisp_params_block_u *)&lparams->regs.vignetting_ctrl; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.ctemp_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_CTEMP]; + block =3D (union neoisp_params_block_u *)&lparams->regs.ctemp; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.demosaic_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_DEMOSAIC]; + block =3D (union neoisp_params_block_u *)&lparams->regs.demosaic; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.rgb2yuv_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_RGB2YUV]; + block =3D (union neoisp_params_block_u *)&lparams->regs.rgb2yuv; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.dr_comp_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_DR_COMP]; + block =3D (union neoisp_params_block_u *)&lparams->regs.drc; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.nr_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_NR]; + block =3D (union neoisp_params_block_u *)&lparams->regs.nr; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.af_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_AF]; + block =3D (union neoisp_params_block_u *)&lparams->regs.af; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.ee_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_EE]; + block =3D (union neoisp_params_block_u *)&lparams->regs.ee; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.df_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_DF]; + block =3D (union neoisp_params_block_u *)&lparams->regs.df; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.convmed_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_CONVMED]; + block =3D (union neoisp_params_block_u *)&lparams->regs.convmed; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.cas_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_CAS]; + block =3D (union neoisp_params_block_u *)&lparams->regs.cas; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.gcm_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_GCM]; + block =3D (union neoisp_params_block_u *)&lparams->regs.gcm; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.vignetting_table_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_VIGNETTING_TA= BLE]; + block =3D (union neoisp_params_block_u *)&lparams->mems.vt; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.drc_global_tonemap_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_DRC_GLOBAL_TO= NEMAP]; + block =3D (union neoisp_params_block_u *)&lparams->mems.gtm; + block_handler->handler(neoispd, block); + } + if (lparams->features_cfg.drc_local_tonemap_cfg) { + block_handler =3D &neoisp_block_handlers[NEOISP_PARAM_BLK_DRC_LOCAL_TON= EMAP]; + block =3D (union neoisp_params_block_u *)&lparams->mems.ltm; + block_handler->handler(neoispd, block); + } + + break; + } + case V4L2_META_FMT_NEO_ISP_EXT_PARAMS: { + /* Extended params API */ + const struct neoisp_block_handler_s *block_handler; + struct v4l2_isp_params_buffer *ext_params =3D + (struct v4l2_isp_params_buffer *)get_vaddr(buf); + size_t block_offset =3D 0, max_offset; + + if (ext_params->data_size =3D=3D 0) + /* No relevant parameters in this buffer */ + break; + + max_offset =3D ext_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) { + union neoisp_ext_params_block_u *block =3D (union neoisp_ext_params_blo= ck_u *) + &ext_params->data[block_offset]; + block_offset +=3D block->header.size; + + block_handler =3D &neoisp_block_handlers[block->header.type]; + block_handler->ext_handler(neoispd, block); + } + break; + } + default: + dev_err(&neoispd->pdev->dev, "Error: unknown params fmt (%#x)\n", + node->neoisp_format->fourcc); + break; + } +} + +/* + * 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 + * depend on the hw version. + */ +void neoisp_ctx_upload_context(struct neoisp_dev_s *neoispd) +{ + struct neoisp_node_group_s *node_group =3D neoispd->queued_job.node_group; + struct neoisp_context_s *ctx =3D node_group->context; + u8 *src =3D (u8 *)(uintptr_t)&ctx->hw.pipe_conf.common.img_conf; + u8 *dst =3D (u8 *)(uintptr_t)(neoispd->mmio + NEO_PIPE_CONF_IMG_CONF_CAM0= ); + u32 *imem =3D (u32 *)(uintptr_t)neoispd->mmio_tcm; + + memcpy(dst, src, NEO_AUTOFOCUS_ROI0_SUM0_CAM0 - NEO_PIPE_CONF_IMG_CONF_CA= M0); + + ctx_blk_write(neoispd->info->mems->vignetting_table, + (u32 *)ctx->vig.vignetting_table, imem); + + ctx_blk_write(neoispd->info->mems->drc_global_tonemap, + (u32 *)ctx->gtm.drc_global_tonemap, imem); + + ctx_blk_write(neoispd->info->mems->drc_local_tonemap, + (u32 *)ctx->ltm.drc_local_tonemap, imem); +} + +static void neoisp_ctx_get_stats_blk(struct neoisp_dev_s *neoispd, u32 bty= pe, u8 *src, + struct v4l2_isp_stats_buffer *ext_stats, u32 *offset) +{ + union neoisp_stats_block_u *blk =3D (union neoisp_stats_block_u *)&ext_st= ats->data[*offset]; + u32 size, loff, lsz; + + blk->header.type =3D btype; + switch (btype) { + case NEOISP_STATS_BLK_RCTEMP: + size =3D sizeof(struct neoisp_ctemp_reg_stats_s); + memcpy_fromio(&blk->rctemp.stat, neoispd->mmio + NEO_ALIAS_ALIAS_REG0, s= ize); + break; + case NEOISP_STATS_BLK_RDRC: + size =3D sizeof(struct neoisp_drc_reg_stats_s); + memcpy_fromio(&blk->rdrc.stat, neoispd->mmio + NEO_ALIAS_ALIAS_REG59, si= ze); + break; + case NEOISP_STATS_BLK_RAF: + size =3D sizeof(struct neoisp_af_reg_stats_s); + memcpy_fromio(&blk->raf.stat, neoispd->mmio + NEO_ALIAS_ALIAS_REG61, siz= e); + break; + case NEOISP_STATS_BLK_RBNR: + size =3D sizeof(struct neoisp_bnr_reg_stats_s); + memcpy_fromio(&blk->rbnr.stat, neoispd->mmio + NEO_ALIAS_ALIAS_REG79, si= ze); + break; + case NEOISP_STATS_BLK_RNR: + size =3D sizeof(struct neoisp_nr_reg_stats_s); + memcpy_fromio(&blk->rnr.stat, neoispd->mmio + NEO_ALIAS_ALIAS_REG81, siz= e); + break; + case NEOISP_STATS_BLK_REE: + size =3D sizeof(struct neoisp_ee_reg_stats_s); + memcpy_fromio(&blk->ree.stat, neoispd->mmio + NEO_ALIAS_ALIAS_REG82, siz= e); + break; + case NEOISP_STATS_BLK_RDF: + size =3D sizeof(struct neoisp_df_reg_stats_s); + memcpy_fromio(&blk->rdf.stat, neoispd->mmio + NEO_ALIAS_ALIAS_REG83, siz= e); + break; + case NEOISP_STATS_BLK_MCTEMP: + size =3D sizeof(struct neoisp_ctemp_mem_stats_s); + /* Get ctemp stats from memory */ + get_offsize(NEO_CTEMP_R_SUM_MAP, &loff, &lsz); + memcpy(&blk->mctemp.stat.ctemp_r_sum, &src[loff], lsz); + + get_offsize(NEO_CTEMP_G_SUM_MAP, &loff, &lsz); + memcpy(&blk->mctemp.stat.ctemp_g_sum, &src[loff], lsz); + + get_offsize(NEO_CTEMP_B_SUM_MAP, &loff, &lsz); + memcpy(&blk->mctemp.stat.ctemp_b_sum, &src[loff], lsz); + + get_offsize(NEO_CTEMP_PIX_CNT_MAP, &loff, &lsz); + memcpy(&blk->mctemp.stat.ctemp_pix_cnt, &src[loff], lsz); + break; + case NEOISP_STATS_BLK_MRGBIR: + size =3D sizeof(struct neoisp_rgbir_mem_stats_s); + /* Get rgbir stats from memory */ + get_offsize(NEO_RGBIR_HIST_MAP, &loff, &lsz); + memcpy(&blk->mrgbir.stat, &src[loff], lsz); + break; + case NEOISP_STATS_BLK_MHIST: + size =3D sizeof(struct neoisp_hist_mem_stats_s); + /* Get histograms stats from memory */ + get_offsize(NEO_HIST_STAT_MAP, &loff, &lsz); + memcpy(&blk->mhist.stat, &src[loff], lsz); + break; + case NEOISP_STATS_BLK_MDRC: + size =3D sizeof(struct neoisp_drc_mem_stats_s); + /* Get drc local sum stats from memory */ + get_offsize(neoispd->info->mems->drc_local_sum, &loff, &lsz); + memcpy(&blk->mdrc.stat.drc_local_sum, &src[loff], lsz); + + /* Get drc hist roi0 stats from memory */ + get_offsize(neoispd->info->mems->drc_global_hist_roi0, &loff, &lsz); + memcpy(&blk->mdrc.stat.drc_global_hist_roi0, &src[loff], lsz); + + /* Get drc hist roi1 stats from memory */ + get_offsize(neoispd->info->mems->drc_global_hist_roi1, &loff, &lsz); + memcpy(&blk->mdrc.stat.drc_global_hist_roi1, &src[loff], lsz); + break; + } + blk->header.size =3D ALIGN(size + sizeof(struct v4l2_isp_stats_block_head= er), 8); + blk->header.flags =3D V4L2_ISP_PARAMS_FL_BLOCK_VALID; + *offset +=3D blk->header.size; +} + +void neoisp_ctx_get_stats(struct neoisp_dev_s *neoispd, struct neoisp_buff= er_s *buf) +{ + struct neoisp_node_s *node =3D &neoispd->queued_job.node_group->node[NEOI= SP_STATS_NODE]; + u8 *src =3D (u8 *)(uintptr_t)neoispd->mmio_tcm; + u32 offset, size, *blk_list, count; + + /* Check if stats node link is enabled */ + if (!neoisp_node_link_is_enabled(node)) + return; + + if (IS_ERR_OR_NULL(buf) || IS_ERR_OR_NULL(src)) { + dev_err(&neoispd->pdev->dev, "Error: stats pointer\n"); + return; + } + + switch (node->neoisp_format->fourcc) { + case V4L2_META_FMT_NEO_ISP_STATS: { + struct neoisp_meta_stats_s *lstats =3D (struct neoisp_meta_stats_s *)get= _vaddr(buf); + + /* Get stats from registers */ + memcpy_fromio((u32 *)(uintptr_t)&lstats->regs, + neoispd->mmio + NEO_ALIAS_ALIAS_REG0, + sizeof(struct neoisp_reg_stats_s)); + + /* Get ctemp stats from memory */ + get_offsize(NEO_CTEMP_R_SUM_MAP, &offset, &size); + memcpy(&lstats->mems.ctemp.ctemp_r_sum, &src[offset], size); + + get_offsize(NEO_CTEMP_G_SUM_MAP, &offset, &size); + memcpy(&lstats->mems.ctemp.ctemp_g_sum, &src[offset], size); + + get_offsize(NEO_CTEMP_B_SUM_MAP, &offset, &size); + memcpy(&lstats->mems.ctemp.ctemp_b_sum, &src[offset], size); + + get_offsize(NEO_CTEMP_PIX_CNT_MAP, &offset, &size); + memcpy(&lstats->mems.ctemp.ctemp_pix_cnt, &src[offset], size); + + /* Get rgbir stats from memory */ + get_offsize(NEO_RGBIR_HIST_MAP, &offset, &size); + memcpy(&lstats->mems.rgbir.rgbir_hist, &src[offset], size); + + /* Get histograms stats from memory */ + get_offsize(NEO_HIST_STAT_MAP, &offset, &size); + memcpy(&lstats->mems.hist.hist_stat, &src[offset], size); + + /* Get drc local sum stats from memory */ + get_offsize(neoispd->info->mems->drc_local_sum, &offset, &size); + memcpy(&lstats->mems.drc.drc_local_sum, &src[offset], size); + + /* Get drc hist roi0 stats from memory */ + get_offsize(neoispd->info->mems->drc_global_hist_roi0, &offset, &size); + memcpy(&lstats->mems.drc.drc_global_hist_roi0, &src[offset], size); + + /* Get drc hist roi1 stats from memory */ + get_offsize(neoispd->info->mems->drc_global_hist_roi1, &offset, &size); + memcpy(&lstats->mems.drc.drc_global_hist_roi1, &src[offset], size); + break; + } + + case V4L2_META_FMT_NEO_ISP_EXT_STATS: { + struct v4l2_isp_stats_buffer *ext_stats =3D + (struct v4l2_isp_stats_buffer *)get_vaddr(buf); + + ext_stats->version =3D V4L2_ISP_STATS_VERSION_V1; + offset =3D 0; + blk_list =3D (u32 *)neoisp_ext_stats_blocks_v1; + count =3D ARRAY_SIZE(neoisp_ext_stats_blocks_v1); + for (int i =3D 0; i < count; i++) + neoisp_ctx_get_stats_blk(neoispd, blk_list[i], src, ext_stats, &offset); + + ext_stats->data_size =3D offset; + break; + } + default: + dev_err(&neoispd->pdev->dev, "Error: unknown stats fmt (%#x)\n", + node->neoisp_format->fourcc); + break; + } +} + 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..9f728f2aca06 --- /dev/null +++ b/drivers/media/platform/nxp/neoisp/neoisp_ctx.h @@ -0,0 +1,85 @@ +/* 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_VIGNETTING_TABLE_MAP_V1 =3D ISP_MAP_TUPLE(0x1000, NEO_VIGNETTING_TABL= E_SIZE, u16), + NEO_DRC_GLOBAL_TONEMAP_MAP_V1 =3D ISP_MAP_TUPLE(0x4000, NEO_DRC_GLOBAL_TO= NEMAP_SIZE, u16), + NEO_DRC_LOCAL_TONEMAP_MAP_V1 =3D ISP_MAP_TUPLE(0x4400, NEO_DRC_LOCAL_TONE= MAP_SIZE, u8), + NEO_DRC_LOCAL_SUM_MAP_V1 =3D ISP_MAP_TUPLE(0x4800, NEO_DRC_LOCAL_SUM_CNT,= u32), + NEO_DRC_GLOBAL_HIST_ROI0_MAP_V1 =3D ISP_MAP_TUPLE(0x5800, NEO_DRC_GLOBAL_= HIST_ROI_CNT, u32), + NEO_DRC_GLOBAL_HIST_ROI1_MAP_V1 =3D ISP_MAP_TUPLE(0x5F00, NEO_DRC_GLOBAL_= HIST_ROI_CNT, u32), + + NEO_DRC_GLOBAL_HIST_ROI0_MAP_V2 =3D ISP_MAP_TUPLE(0x1000, NEO_DRC_GLOBAL_= HIST_ROI_CNT, u32), + NEO_DRC_GLOBAL_HIST_ROI1_MAP_V2 =3D ISP_MAP_TUPLE(0x1700, NEO_DRC_GLOBAL_= HIST_ROI_CNT, u32), + NEO_DRC_LOCAL_SUM_MAP_V2 =3D ISP_MAP_TUPLE(0x1E00, NEO_DRC_LOCAL_SUM_CNT,= u32), + NEO_VIGNETTING_TABLE_MAP_V2 =3D ISP_MAP_TUPLE(0x2E00, NEO_VIGNETTING_TABL= E_SIZE, u16), + NEO_DRC_GLOBAL_TONEMAP_MAP_V2 =3D ISP_MAP_TUPLE(0x4600, NEO_DRC_GLOBAL_TO= NEMAP_SIZE, u16), + NEO_DRC_LOCAL_TONEMAP_MAP_V2 =3D ISP_MAP_TUPLE(0x4A00, NEO_DRC_LOCAL_TONE= MAP_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_dev_s *neoispd, + 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_node_group_s *node_group); +void neoisp_ctx_update_pipe_conf(struct neoisp_node_group_s *node_group); +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..f8ff8f13ddda --- /dev/null +++ b/drivers/media/platform/nxp/neoisp/neoisp_fmt.h @@ -0,0 +1,509 @@ +/* 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_PARAMS, /* NXP neoisp 3A parameters */ + .align =3D 32, + .bit_depth =3D 8, + .num_planes =3D 1, + .type =3D NEOISP_FMT_META_OUTPUT + }, + { + .fourcc =3D V4L2_META_FMT_NEO_ISP_EXT_PARAMS, /* NXP neoisp extended 3A = parameters */ + .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_STATS, /* NXP neoisp 3A Statistics */ + .align =3D 32, + .bit_depth =3D 8, + .num_planes =3D 1, + .type =3D NEOISP_FMT_META_CAPTURE + }, + { + .fourcc =3D V4L2_META_FMT_NEO_ISP_EXT_STATS, /* NXP neoisp extended 3A S= tatistics */ + .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..87bc0cf28e81 --- /dev/null +++ b/drivers/media/platform/nxp/neoisp/neoisp_hw.h @@ -0,0 +1,577 @@ +/* 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_v1_s { + u32 unusedw0[26]; + u32 int_en; + u32 int_stat; + u32 csi_stat; +}; + +struct neoisp_pipe_conf_v2_s { + u32 unusedw0[9]; + u32 int_en; + u32 int_stat; + u32 csi_stat; + u32 unusedw1[14]; +}; + +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 unusedw1_int_on_v2[3]; /* int_en + int_stat + csi_stat on V2 */ + u32 img_conf; + u32 img_size; + u32 unusedw2[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; + u32 unusedw3_int_on_v1[3]; /* int_en + int_stat + csi_stat on V1 */ +}; /* 29 words */ + +union neoisp_pipe_conf_u { + struct neoisp_pipe_conf_s common; + struct neoisp_pipe_conf_v1_s v1; + struct neoisp_pipe_conf_v2_s v2; +}; + +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_drc_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 { + union neoisp_pipe_conf_u pipe_conf; + u32 unused0[19]; + 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_drc_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..f053a2136dad --- /dev/null +++ b/drivers/media/platform/nxp/neoisp/neoisp_main.c @@ -0,0 +1,1985 @@ +// 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 "neoisp.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 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; +} + +static const struct isp_block_map_s active_block_map[] =3D { + [NEOISP_HW_V1] =3D { + .vignetting_table =3D NEO_VIGNETTING_TABLE_MAP_V1, + .drc_global_tonemap =3D NEO_DRC_GLOBAL_TONEMAP_MAP_V1, + .drc_global_hist_roi0 =3D NEO_DRC_GLOBAL_HIST_ROI0_MAP_V1, + .drc_global_hist_roi1 =3D NEO_DRC_GLOBAL_HIST_ROI1_MAP_V1, + .drc_local_tonemap =3D NEO_DRC_LOCAL_TONEMAP_MAP_V1, + .drc_local_sum =3D NEO_DRC_LOCAL_SUM_MAP_V1, + }, + [NEOISP_HW_V2] =3D { + .vignetting_table =3D NEO_VIGNETTING_TABLE_MAP_V2, + .drc_global_tonemap =3D NEO_DRC_GLOBAL_TONEMAP_MAP_V2, + .drc_global_hist_roi0 =3D NEO_DRC_GLOBAL_HIST_ROI0_MAP_V2, + .drc_global_hist_roi1 =3D NEO_DRC_GLOBAL_HIST_ROI1_MAP_V2, + .drc_local_tonemap =3D NEO_DRC_LOCAL_TONEMAP_MAP_V2, + .drc_local_sum =3D NEO_DRC_LOCAL_SUM_MAP_V2, + }, +}; + +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->node_group->neoisp_dev; + 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->pdev->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->node_group->neoisp_dev; + 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->pdev->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_ext_params_bloc= k_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->node_group->neoisp_dev; + struct v4l2_isp_params_buffer *params =3D vb2_plane_vaddr(&vbuf->vb2_buf,= 0); + int ret; + + if (node->neoisp_format->fourcc =3D=3D V4L2_META_FMT_NEO_ISP_PARAMS) + return neoisp_node_buf_prepare(vb); + + ret =3D v4l2_isp_params_validate_buffer_size(&neoispd->pdev->dev, vb, + node->format.fmt.meta.buffersize); + if (ret) + return ret; + + ret =3D v4l2_isp_params_validate_buffer(&neoispd->pdev->dev, vb, + params, neoisp_ext_params_block_types_info, + ARRAY_SIZE(neoisp_ext_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->queued_job.node_group->sd; + u32 sequence =3D neoispd->queued_job.node_group->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->pdev->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->pdev->dev, "isp starting ctx id: %d\n", + neoispd->queued_job.node_group->id); +} + +static int neoisp_prepare_job(struct neoisp_node_group_s *node_group) +{ + struct neoisp_dev_s *neoispd =3D node_group->neoisp_dev; + struct neoisp_buffer_s *buf[NEOISP_NODES_COUNT]; + struct neoisp_node_s *node; + unsigned long flags; + int i; + + lockdep_assert_held(&neoispd->hw_lock); + + /* + * 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. + * + * (Note that streaming_map is protected by hw_lock, which is held here) + */ + if ((BIT(NEOISP_INPUT0_NODE) & node_group->streaming_map) + !=3D BIT(NEOISP_INPUT0_NODE)) { + dev_dbg(&neoispd->pdev->dev, "Input0 node not ready, nothing to do\n"); + return -EAGAIN; + } + + node =3D &node_group->node[NEOISP_INPUT1_NODE]; + if (neoisp_node_link_is_enabled(node)) { + if ((BIT(NEOISP_INPUT1_NODE) & node_group->streaming_map) + !=3D BIT(NEOISP_INPUT1_NODE)) { + dev_dbg(&neoispd->pdev->dev, "Input1 is not disabled and not ready\n"); + return -EAGAIN; + } + } + node =3D &node_group->node[NEOISP_PARAMS_NODE]; + if (neoisp_node_link_is_enabled(node)) { + if ((BIT(NEOISP_PARAMS_NODE) & node_group->streaming_map) + !=3D BIT(NEOISP_PARAMS_NODE)) { + dev_dbg(&neoispd->pdev->dev, "Params is not disabled and not ready\n"); + return -EAGAIN; + } + } + node =3D &node_group->node[NEOISP_FRAME_NODE]; + if (neoisp_node_link_is_enabled(node)) { + if ((BIT(NEOISP_FRAME_NODE) & node_group->streaming_map) + !=3D BIT(NEOISP_FRAME_NODE)) { + dev_dbg(&neoispd->pdev->dev, "Frame node not ready, nothing to do\n"); + return -EAGAIN; + } + } + node =3D &node_group->node[NEOISP_IR_NODE]; + if (neoisp_node_link_is_enabled(node)) { + if ((BIT(NEOISP_IR_NODE) & node_group->streaming_map) + !=3D BIT(NEOISP_IR_NODE)) { + dev_dbg(&neoispd->pdev->dev, "IR node not ready, nothing to do\n"); + return -EAGAIN; + } + } + node =3D &node_group->node[NEOISP_STATS_NODE]; + if (neoisp_node_link_is_enabled(node)) { + if ((BIT(NEOISP_STATS_NODE) & node_group->streaming_map) + !=3D BIT(NEOISP_STATS_NODE)) { + dev_dbg(&neoispd->pdev->dev, "Stats is not disabled and not ready\n"); + return -EAGAIN; + } + } + + for (i =3D 0; i < NEOISP_NODES_COUNT; i++) { + buf[i] =3D NULL; + if (!(node_group->streaming_map & BIT(i))) + continue; + + node =3D &node_group->node[i]; + spin_lock_irqsave(&node->ready_lock, flags); + buf[i] =3D list_first_entry_or_null(&node->ready_queue, + struct neoisp_buffer_s, + ready_list); + spin_unlock_irqrestore(&node->ready_lock, flags); + + if (!buf[i] && neoisp_node_link_is_enabled(node)) { + dev_dbg(&neoispd->pdev->dev, "Nothing to do\n"); + return -EINVAL; + } + } + + /* Pull a buffer from each V4L2 queue to form the queued job */ + for (i =3D 0; i < NEOISP_NODES_COUNT; i++) { + if (buf[i]) { + node =3D &node_group->node[i]; + spin_lock_irqsave(&node->ready_lock, flags); + list_del(&buf[i]->ready_list); + spin_unlock_irqrestore(&node->ready_lock, flags); + } + neoispd->queued_job.buf[i] =3D buf[i]; + } + + /* Save the currently running node_group */ + neoispd->queued_job.node_group =3D node_group; + + return 0; +} + +/* + * Try to schedule a job for a single node group. If neoisp hw is free, go + * through all the groups starting from index of the one sent in parameter= s. + * If one group is ready, move it into the queued_job, and launch it. + */ +static void neoisp_schedule(struct neoisp_dev_s *neoispd, + struct neoisp_node_group_s *node_group, + bool clear_hw_busy) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&neoispd->hw_lock, flags); + + if (clear_hw_busy) + neoispd->hw_busy =3D false; + + if (neoispd->hw_busy) { + spin_unlock_irqrestore(&neoispd->hw_lock, flags); + return; + } + + if (clear_hw_busy) { + u32 idx =3D node_group->id; + + for (u32 i =3D 1; i <=3D NEOISP_NODE_GROUPS_COUNT; i++) { + /* Try to schedule next index from last processed one. */ + u32 next =3D (i + idx) % NEOISP_NODE_GROUPS_COUNT; + + ret =3D neoisp_prepare_job(&neoispd->node_group[next]); + if (ret) + continue; + + /* + * Prepare job was successful then save the node_group pointer and + * stop checking other streams/groups + */ + node_group =3D &neoispd->node_group[next]; + break; + } + } else { + ret =3D neoisp_prepare_job(node_group); + } + + if (ret) { + spin_unlock_irqrestore(&neoispd->hw_lock, flags); + return; + } + + /* + * 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. + */ + neoispd->hw_busy =3D true; + spin_unlock_irqrestore(&neoispd->hw_lock, flags); + + neoisp_run_job(neoispd); +} + +static void neoisp_try_start(struct neoisp_node_group_s *node_group) +{ + struct neoisp_dev_s *neoispd =3D node_group->neoisp_dev; + + /* Update queued job context with current driver configuration */ + neoisp_ctx_update_packetizer(node_group); + neoisp_ctx_update_pipe_conf(node_group); + + neoisp_schedule(neoispd, node_group, false); +} + +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_node_group_s *node_group =3D node->node_group; + struct neoisp_dev_s *neoispd =3D node->node_group->neoisp_dev; + unsigned long flags; + + dev_dbg(&neoispd->pdev->dev, "%s: for node %s\n", __func__, NODE_NAME(nod= e)); + spin_lock_irqsave(&node->ready_lock, flags); + list_add_tail(&buffer->ready_list, &node->ready_queue); + spin_unlock_irqrestore(&node->ready_lock, flags); + + /* + * Every time we add a buffer, check if there's now some work for the hw + * to do, but only for this client. + */ + neoisp_schedule(neoispd, node_group, false); +} + +static void neoisp_set_default_context(struct neoisp_dev_s *neoispd, int c= tx_id) +{ + /* Prepare node group's context with default one */ + neoisp_ctx_set_default_context(neoispd, neoispd->node_group[ctx_id].conte= xt); + + /* + * After init, context parameters are copied by the 'neoisp_program_conte= xt' + * function, starting from pipe_conf->img_conf register, up to latest + * ISP register. + * + * However, depending on hw version, some critical registers such as + * INT_EN are impacted by this copy. Indeed, on V1 version, interrupt + * registers are located _after_ pipe_conf->img_conf register, so they + * would be overwritten with 0s during 'neoisp_program_context' execution. + * + * As a consequence, default context must be updated with appropriate + * INT_EN register value. This is not required for V2 since INT_EN + * register is out of memory copy section (i.e. _before_ img_conf). + */ + if (neoispd->info->hw_ver =3D=3D NEOISP_HW_V1) { + struct neoisp_context_s *context =3D neoispd->node_group[ctx_id].context; + struct neoisp_pipe_conf_v1_s *pc =3D &context->hw.pipe_conf.v1; + + pc->int_en =3D + NEO_PIPE_CONF_INT_EN0_EN_FD2 | + NEO_PIPE_CONF_INT_EN0_EN_DRCD | + NEO_PIPE_CONF_INT_EN0_EN_BUS_ERR_MASK | + NEO_PIPE_CONF_INT_EN0_EN_CSI_TERR | + NEO_PIPE_CONF_INT_EN0_EN_TRIG_ERR; + } +} + +static int neoisp_prepare_node_streaming(struct neoisp_node_s *node) +{ + struct neoisp_node_group_s *node_group =3D node->node_group; + struct neoisp_dev_s *neoispd =3D node_group->neoisp_dev; + struct neoisp_context_s *ctx =3D node_group->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 */ + if (neoispd->info->context_ops->adjust_gain) + neoispd->info->context_ops->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 &node_group->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->pdev->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(&node_group->node[NEOISP_FRAME_NODE]) || + !neoisp_node_link_is_enabled(&node_group->node[NEOISP_IR_NODE]) || + format_is_monochrome(pixfmt)) { + if (!node_group->dummy_buf) { + struct neoisp_node_s *in0_node =3D &node_group->node[NEOISP_INPUT0_NODE= ]; + + /* Allocate a single line dummy buffer as line stride is set to 0 */ + node_group->dummy_size =3D in0_node->crop.width * NEOISP_MAX_BPP; + node_group->dummy_buf =3D + dma_alloc_coherent(&neoispd->pdev->dev, + node_group->dummy_size, + &node_group->dummy_dma, GFP_KERNEL); + } + } + + 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_node_group_s *node_group =3D node->node_group; + struct neoisp_dev_s *neoispd =3D node_group->neoisp_dev; + struct neoisp_buffer_s *buf, *tmp; + unsigned long flags; + int ret; + + ret =3D pm_runtime_resume_and_get(&neoispd->pdev->dev); + if (ret < 0) + goto error; + + ret =3D neoisp_prepare_node_streaming(node); + if (ret < 0) + goto error; + + node->node_group->streaming_map |=3D BIT(node->id); + node_group->frame_sequence =3D 0; + + dev_dbg(&neoispd->pdev->dev, "%s: for node %s (count %u)\n", + __func__, NODE_NAME(node), count); + dev_dbg(&neoispd->pdev->dev, "Nodes streaming for this group now 0x%x\n", + node->node_group->streaming_map); + + /* Maybe we're ready to run. */ + neoisp_try_start(node_group); + + return 0; + +error: + spin_lock_irqsave(&node->ready_lock, flags); + 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); + } + spin_unlock_irqrestore(&node->ready_lock, flags); + 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_node_group_s *node_group =3D node->node_group; + struct neoisp_dev_s *neoispd =3D node_group->neoisp_dev; + struct neoisp_buffer_s *buf; + unsigned long flags; + + /* + * 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->pdev->dev, "%s: for node %s\n", __func__, NODE_NAME(nod= e)); + spin_lock_irqsave(&neoispd->hw_lock, flags); + do { + unsigned long flags1; + + spin_lock_irqsave(&node->ready_lock, flags1); + 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); + } + spin_unlock_irqrestore(&node->ready_lock, flags1); + } while (buf); + spin_unlock_irqrestore(&neoispd->hw_lock, flags); + + vb2_wait_for_all_buffers(&node->queue); + + if (node->id =3D=3D NEOISP_INPUT0_NODE) + neoisp_set_default_context(neoispd, node_group->id); + + if (node_group->dummy_buf) { + dma_free_coherent(&neoispd->pdev->dev, + node_group->dummy_size, + node_group->dummy_buf, + node_group->dummy_dma); + node_group->dummy_buf =3D NULL; + } + + spin_lock_irqsave(&neoispd->hw_lock, flags); + node_group->streaming_map &=3D ~BIT(node->id); + spin_unlock_irqrestore(&neoispd->hw_lock, flags); + + pm_runtime_mark_last_busy(&neoispd->pdev->dev); + pm_runtime_put_autosuspend(&neoispd->pdev->dev); + + dev_dbg(&neoispd->pdev->dev, "Nodes streaming for this group now 0x%x\n", + node_group->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->node_group->neoisp_dev; + + 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->pdev->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->pdev->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->node_group->neoisp_dev; + + if (!node_is_meta(node)) { + dev_err(&neoispd->pdev->dev, + "Cannot get meta fmt for video node %s\n", NODE_NAME(node)); + return -EINVAL; + } + *f =3D node->format; + dev_dbg(&neoispd->pdev->dev, "Get meta format for node %s\n", NODE_NAME(n= ode)); + 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->node_group->neoisp_dev; + + if (node_is_meta(node)) { + pixfmt =3D f->fmt.meta.dataformat; + + if (node_is_output(node) && + pixfmt !=3D V4L2_META_FMT_NEO_ISP_PARAMS && + pixfmt !=3D V4L2_META_FMT_NEO_ISP_EXT_PARAMS) + f->fmt.meta.dataformat =3D V4L2_META_FMT_NEO_ISP_PARAMS; + else if (!node_is_output(node) && + pixfmt !=3D V4L2_META_FMT_NEO_ISP_STATS && + pixfmt !=3D V4L2_META_FMT_NEO_ISP_EXT_STATS) + f->fmt.meta.dataformat =3D V4L2_META_FMT_NEO_ISP_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->pdev->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->node_group->neoisp_dev; + + if (!node_is_meta(node) || node_is_capture(node)) { + dev_err(&neoispd->pdev->dev, + "Cannot set capture fmt for meta output node %s\n", + NODE_NAME(node)); + return -EINVAL; + } + + if (!f->fmt.meta.buffersize) + f->fmt.meta.buffersize =3D v4l2_isp_params_buffer_size(NEOISP_EXT_PARAMS= _MAX_SIZE); + + 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->node_group->neoisp_dev; + + if (!node_is_meta(node) || node_is_output(node)) { + dev_err(&neoispd->pdev->dev, + "Cannot set capture fmt for meta output node %s\n", + NODE_NAME(node)); + return -EINVAL; + } + + if (!f->fmt.meta.buffersize) + f->fmt.meta.buffersize =3D v4l2_isp_stats_buffer_size(NEOISP_EXT_STATS_M= AX_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->node_group->neoisp_dev; + 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->pdev->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->node_group->neoisp_dev; + 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->pdev->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->node_group->neoisp_dev; + + if (node_is_meta(node)) { + dev_err(&neoispd->pdev->dev, + "Cannot get video fmt for meta node %s\n", NODE_NAME(node)); + return -EINVAL; + } + + *f =3D node->format; + + dev_dbg(&neoispd->pdev->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->node_group->neoisp_dev; + + if (!node_is_capture(node) || node_is_meta(node)) { + dev_err(&neoispd->pdev->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->node_group->neoisp_dev; + + if (!node_is_output(node) || node_is_meta(node)) { + dev_err(&neoispd->pdev->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->node_group->neoisp_dev; + 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->pdev->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->node_group->neoisp_dev->pdev->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->node_group->neoisp_dev->pdev->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; + struct neoisp_node_group_s *node_group =3D neoispd->queued_job.node_group; + 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 neoispd->info->context_ops->get_irq_status(neoispd); + + if (irq_status & NEO_PIPE_CONF_INT_STAT0_S_FS1) { + dev_dbg(&neoispd->pdev->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->pdev->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->pdev->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->pdev->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->pdev->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_MASK) { + irq_clear |=3D NEO_PIPE_CONF_INT_STAT0_S_BUS_ERR_MASK; + dev_err(&neoispd->pdev->dev, "Neo IRQ BUS ERR!\n"); + done =3D true; + } + + if (irq_status & NEO_PIPE_CONF_INT_STAT0_S_TRIG_ERR) { + dev_err(&neoispd->pdev->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->pdev->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->pdev->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->pdev->dev, "Neo is busy !\n"); + + neoispd->info->context_ops->clear_irq(neoispd, irq_clear); + + if (done) { + for (i =3D 0; i < NEOISP_NODES_COUNT; i++) { + if (buf[i]) { + buf[i]->vb.sequence =3D node_group->frame_sequence; + buf[i]->vb.vb2_buf.timestamp =3D ts; + vb2_buffer_done(&buf[i]->vb.vb2_buf, VB2_BUF_STATE_DONE); + } + } + /* Update frame_sequence */ + node_group->frame_sequence++; + /* Check if there's more to do before going to sleep */ + neoisp_schedule(neoispd, node_group, 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_node_group_s *node_group) +{ + struct neoisp_dev_s *neoispd =3D node_group->neoisp_dev; + struct v4l2_subdev *sd =3D &node_group->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->pdev->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++) + node_group->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, node_grou= p->pad); + if (ret) + goto error; + + /* 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 &node_group->hdl; + v4l2_ctrl_handler_init(hdl, ARRAY_SIZE(controls)); + for (i =3D 0; i < ARRAY_SIZE(controls); i++) { + node_group->ctrls[i] =3D v4l2_ctrl_new_custom(hdl, &controls[i], NULL); + if (hdl->error) { + dev_err(&neoispd->pdev->dev, "Adding control (%d) failed\n", i); + ret =3D hdl->error; + goto error; + } + } + sd->ctrl_handler =3D hdl; + + ret =3D v4l2_device_register_subdev(&node_group->v4l2_dev, sd); + if (ret) + goto error; + + return 0; + +error: + 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 - legacy format */ + struct v4l2_format *f =3D &node->format; + + f->fmt.meta.dataformat =3D V4L2_META_FMT_NEO_ISP_PARAMS; + f->fmt.meta.buffersize =3D sizeof(struct neoisp_meta_params_s); + f->type =3D node->buf_type; + } else if (node_is_meta(node) && node_is_capture(node)) { + /* Stats node - legacy format */ + struct v4l2_format *f =3D &node->format; + + f->fmt.meta.dataformat =3D V4L2_META_FMT_NEO_ISP_STATS; + f->fmt.meta.buffersize =3D sizeof(struct neoisp_meta_stats_s); + 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_node_group_s *node_group, u32 id) +{ + bool output =3D node_desc_is_output(&node_desc[id]); + struct neoisp_node_s *node =3D &node_group->node[id]; + struct neoisp_dev_s *neoispd =3D node_group->neoisp_dev; + 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->node_group =3D node_group; + node->buf_type =3D node_desc[id].buf_type; + + mutex_init(&node->node_lock); + mutex_init(&node->queue_lock); + INIT_LIST_HEAD(&node->ready_queue); + spin_lock_init(&node->ready_lock); + + 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->pdev->dev; + /* Get V4L2 to handle node->queue locking */ + q->lock =3D &node->queue_lock; + + ret =3D vb2_queue_init(q); + if (ret < 0) { + dev_err(&neoispd->pdev->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 &node_group->v4l2_dev; + vdev->vfl_dir =3D output ? VFL_DIR_TX : VFL_DIR_RX; + /* Get V4L2 to serialise our ioctls */ + vdev->lock =3D &node->node_lock; + 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->pdev->dev, + "Failed to register media pads for %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->pdev->dev, + "Failed to register video %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, &node_group->sd.entity, + id, node_desc[id].link_flags); + else + ret =3D media_create_pad_link(&node_group->sd.entity, id, entity, + 0, node_desc[id].link_flags); + if (ret) + goto err_unregister_video_dev; + + media_entity_for_each_pad(&node_group->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->pdev->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, u32 id) +{ + struct neoisp_node_group_s *node_group =3D &neoispd->node_group[id]; + struct v4l2_device *v4l2_dev; + struct media_device *mdev; + u32 num_registered =3D 0; + int ret; + + node_group->id =3D id; + node_group->neoisp_dev =3D neoispd; + node_group->streaming_map =3D 0; + node_group->dummy_buf =3D NULL; + + dev_dbg(&neoispd->pdev->dev, "Register nodes for group %u\n", id); + + /* Register v4l2_device and media_device */ + mdev =3D &node_group->mdev; + mdev->dev =3D &neoispd->pdev->dev; + mdev->hw_revision =3D neoispd->info->hw_ver; + strscpy(mdev->model, NEOISP_NAME, sizeof(mdev->model)); + snprintf(mdev->bus_info, sizeof(mdev->bus_info), + "platform:%s", dev_name(&neoispd->pdev->dev)); + media_device_init(mdev); + + v4l2_dev =3D &node_group->v4l2_dev; + v4l2_dev->mdev =3D &node_group->mdev; + strscpy(v4l2_dev->name, NEOISP_NAME, sizeof(v4l2_dev->name)); + + ret =3D v4l2_device_register(mdev->dev, &node_group->v4l2_dev); + if (ret) + goto err_media_dev_cleanup; + + /* Register the NEOISP subdevice. */ + ret =3D neoisp_init_subdev(node_group); + if (ret) + goto err_unregister_v4l2; + + /* Create device video nodes */ + for (; num_registered < NEOISP_NODES_COUNT; num_registered++) { + ret =3D neoisp_init_node(node_group, num_registered); + if (ret) + goto err_unregister_nodes; + } + + ret =3D media_device_register(mdev); + if (ret) + goto err_unregister_nodes; + + ret =3D v4l2_device_register_subdev_nodes(&node_group->v4l2_dev); + if (ret) + goto err_unregister_nodes; + + node_group->context =3D dma_alloc_coherent(mdev->dev, + sizeof(struct neoisp_context_s), + &node_group->params_dma_addr, GFP_KERNEL); + if (!node_group->context) { + dev_err(mdev->dev, "Unable to allocate cached context buffers.\n"); + ret =3D -ENOMEM; + goto err_unregister_mdev; + } + return 0; + +err_unregister_mdev: + media_device_unregister(mdev); +err_unregister_nodes: + while (num_registered-- > 0) { + video_unregister_device(&node_group->node[num_registered].vfd); + vb2_queue_release(&node_group->node[num_registered].queue); + } + v4l2_device_unregister_subdev(&node_group->sd); + media_entity_cleanup(&node_group->sd.entity); +err_unregister_v4l2: + v4l2_device_unregister(v4l2_dev); +err_media_dev_cleanup: + media_device_cleanup(mdev); + return ret; +} + +static void neoisp_destroy_node_group(struct neoisp_node_group_s *node_gro= up) +{ + struct neoisp_dev_s *neoispd =3D node_group->neoisp_dev; + int i; + + if (node_group->context) { + dma_free_coherent(&neoispd->pdev->dev, + sizeof(struct neoisp_context_s), + node_group->context, + node_group->params_dma_addr); + } + + dev_dbg(&neoispd->pdev->dev, "Unregister from media controller\n"); + + v4l2_device_unregister_subdev(&node_group->sd); + media_entity_cleanup(&node_group->sd.entity); + media_device_unregister(&node_group->mdev); + + for (i =3D NEOISP_NODES_COUNT - 1; i >=3D 0; i--) { + video_unregister_device(&node_group->node[i].vfd); + vb2_queue_release(&node_group->node[i].queue); + } + + media_device_cleanup(&node_group->mdev); + v4l2_device_unregister(&node_group->v4l2_dev); +} + +static int neoisp_init_groups_context(struct neoisp_dev_s *neoispd) +{ + int i; + + for (i =3D 0; i < NEOISP_NODE_GROUPS_COUNT; i++) + neoisp_set_default_context(neoispd, i); + + return 0; +} + +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_X= FR_ERR_DIS); + + /* Disable debug */ + neoisp_wr(neoispd, NEO_IDBG1_LINE_NUM, NEO_IDBG1_LINE_NUM_LINE_NUM_MASK); + neoisp_wr(neoispd, NEO_IDBG2_LINE_NUM, NEO_IDBG2_LINE_NUM_LINE_NUM_MASK); + + /* 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_MASK | + NEO_PIPE_CONF_INT_EN0_EN_CSI_TERR | + NEO_PIPE_CONF_INT_EN0_EN_TRIG_ERR; + neoispd->info->context_ops->set_irq_enable(neoispd, val); +} + +static int neoisp_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct neoisp_dev_s *neoispd; + int num_groups, ret, irq; + + neoispd =3D devm_kzalloc(dev, sizeof(*neoispd), GFP_KERNEL); + if (!neoispd) + return -ENOMEM; + neoispd->pdev =3D pdev; + 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 */ + neoispd->mmio_tcm =3D devm_platform_get_and_ioremap_resource(pdev, 1, NUL= L); + if (IS_ERR(neoispd->mmio_tcm)) + return PTR_ERR(neoispd->mmio_tcm); + + irq =3D platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + platform_set_drvdata(pdev, neoispd); + + pm_runtime_set_autosuspend_delay(&pdev->dev, NEOISP_SUSPEND_TIMEOUT_MS); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_enable(&pdev->dev); + ret =3D pm_runtime_resume_and_get(&pdev->dev); + if (ret < 0) { + dev_err(&pdev->dev, "Unable to resume the device: %d\n", ret); + goto err_pm; + } + + ret =3D devm_request_irq(&pdev->dev, irq, neoisp_irq_handler, IRQF_ONESHO= T, + dev_name(&pdev->dev), neoispd); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to request irq: %d\n", ret); + goto err_pm; + } + + /* + * Initialise and register devices for each node_group, including media + * device + */ + for (num_groups =3D 0; num_groups < NEOISP_NODE_GROUPS_COUNT; num_groups+= +) { + ret =3D neoisp_init_group(neoispd, num_groups); + if (ret) + goto disable_nodes_err; + } + + spin_lock_init(&neoispd->hw_lock); + neoisp_init_hw(neoispd); + + ret =3D neoisp_init_groups_context(neoispd); + if (ret) + goto disable_nodes_err; + + pm_runtime_mark_last_busy(&pdev->dev); + pm_runtime_put_autosuspend(&pdev->dev); + + return ret; + +disable_nodes_err: + while (num_groups-- > 0) + neoisp_destroy_node_group(&neoispd->node_group[num_groups]); +err_pm: + pm_runtime_dont_use_autosuspend(&pdev->dev); + pm_runtime_disable(&pdev->dev); + + dev_err(&pdev->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); + int i; + + for (i =3D NEOISP_NODE_GROUPS_COUNT - 1; i >=3D 0; i--) + neoisp_destroy_node_group(&neoispd->node_group[i]); + + pm_runtime_dont_use_autosuspend(&pdev->dev); + pm_runtime_disable(&pdev->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) +}; + +/* + * The gain adjustment should be done for v2 only, as the 12-bit format is= managed in a specific + * way. Both versions use LPALIGN0/1 bit field to select LSB or MSB alignm= ent. However, LPALIGN0/1 + * is disabled for 12-bit operations in v2 and data is always aligned in t= he following 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 void neoisp_adjust_gain_v2(struct neoisp_context_s *ctx, u32 ibpp) +{ + struct neoisp_hdr_decompress0_s *hdr0 =3D &ctx->hw.hdr_decompress0; + + if (ibpp !=3D 12) + return; + + hdr0->knee_ratio4 =3D + NEO_HDR_DECOMPRESS0_KNEE_RATIO4_CAM0_RATIO4_SET(16 << NEOISP_HDR_SHIFT_R= ADIX); +} + +static u32 neoisp_get_irq_status(struct neoisp_dev_s *neoispd) +{ + return neoisp_rd(neoispd, NEO_PIPE_CONF_INT_STAT0); +} + +static u32 neoisp_get_irq_status_v2(struct neoisp_dev_s *neoispd) +{ + return neoisp_rd(neoispd, NEO_PIPE_CONF_INT_STAT0_V2); +} + +static void neoisp_clear_irq(struct neoisp_dev_s *neoispd, u32 val) +{ + neoisp_wr(neoispd, NEO_PIPE_CONF_INT_STAT0, val); +} + +static void neoisp_clear_irq_v2(struct neoisp_dev_s *neoispd, u32 val) +{ + neoisp_wr(neoispd, NEO_PIPE_CONF_INT_STAT0_V2, val); +} + +static void neoisp_set_irq_enable(struct neoisp_dev_s *neoispd, u32 val) +{ + neoisp_wr(neoispd, NEO_PIPE_CONF_INT_EN0, val); +} + +static void neoisp_set_irq_enable_v2(struct neoisp_dev_s *neoispd, u32 val) +{ + neoisp_wr(neoispd, NEO_PIPE_CONF_INT_EN0_V2, val); +} + +static struct neoisp_context_ops_s neoisp_context_ops[] =3D { + [NEOISP_HW_V1] =3D { + .set_irq_enable =3D neoisp_set_irq_enable, + .get_irq_status =3D neoisp_get_irq_status, + .clear_irq =3D neoisp_clear_irq, + .adjust_gain =3D NULL, + }, + [NEOISP_HW_V2] =3D { + .set_irq_enable =3D neoisp_set_irq_enable_v2, + .get_irq_status =3D neoisp_get_irq_status_v2, + .clear_irq =3D neoisp_clear_irq_v2, + .adjust_gain =3D neoisp_adjust_gain_v2, + }, +}; + +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_v1_data =3D { + .hw_ver =3D NEOISP_HW_V1, + .context_ops =3D &neoisp_context_ops[NEOISP_HW_V1], + .mems =3D &active_block_map[NEOISP_HW_V1], + .blocks_list =3D neoisp_blocks_list_imx95x, +}; + +static const struct neoisp_info_s neoisp_v2_data =3D { + .hw_ver =3D NEOISP_HW_V2, + .context_ops =3D &neoisp_context_ops[NEOISP_HW_V2], + .mems =3D &active_block_map[NEOISP_HW_V2], + .blocks_list =3D neoisp_blocks_list_imx95x, +}; + +static const struct of_device_id neoisp_dt_ids[] =3D { + { .compatible =3D "nxp,neoisp", .data =3D &neoisp_v2_data }, + { .compatible =3D "nxp,imx95-a0-neoisp", .data =3D &neoisp_v1_data }, + { .compatible =3D "nxp,imx95-a1-neoisp", .data =3D &neoisp_v1_data }, + { .compatible =3D "nxp,imx95-b0-neoisp", .data =3D &neoisp_v2_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..8858e87eab2d --- /dev/null +++ b/drivers/media/platform/nxp/neoisp/neoisp_nodes.h @@ -0,0 +1,60 @@ +/* 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 */ + { + .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 */ + { + .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 */ + { + .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 */ + { + .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 */ + { + .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 */ + { + .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..0a3b99d3cbc3 --- /dev/null +++ b/drivers/media/platform/nxp/neoisp/neoisp_regs.h @@ -0,0 +1,2501 @@ +/* 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_MASK GENMASK(7, 0) +#define NEO_PIPE_CONF_BUS_TXPARAM_OTLT_SET(x) (((x) & GENMASK(7, 0)) << 0) +#define NEO_PIPE_CONF_BUS_TXPARAM_OTLT_GET(x) (((x) >> 0) & GENMASK(7, 0)) +#define NEO_PIPE_CONF_BUS_TXPARAM_OTHT_MASK GENMASK(15, 8) +#define NEO_PIPE_CONF_BUS_TXPARAM_OTHT_SET(x) (((x) & GENMASK(7, 0)) << 8) +#define NEO_PIPE_CONF_BUS_TXPARAM_OTHT_GET(x) (((x) >> 8) & GENMASK(7, 0)) +#define NEO_PIPE_CONF_BUS_TXPARAM_POSTQOS_MASK GENMASK(23, 16) +#define NEO_PIPE_CONF_BUS_TXPARAM_POSTQOS_SET(x) (((x) & GENMASK(7, 0)) <<= 16) +#define NEO_PIPE_CONF_BUS_TXPARAM_POSTQOS_GET(x) (((x) >> 16) & GENMASK(7= , 0)) +#define NEO_PIPE_CONF_BUS_TXPARAM_BSIZE_MASK GENMASK(31, 24) +#define NEO_PIPE_CONF_BUS_TXPARAM_BSIZE_SET(x) (((x) & GENMASK(7, 0)) << 2= 4) +#define NEO_PIPE_CONF_BUS_TXPARAM_BSIZE_GET(x) (((x) >> 24) & GENMASK(7, = 0)) + +#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_MASK GENMASK(4, 0) +#define NEO_PIPE_CONF_CSI_CTRL_VID0_SET(x) (((x) & GENMASK(4, 0)) << 0) +#define NEO_PIPE_CONF_CSI_CTRL_VID0_GET(x) (((x) >> 0) & GENMASK(4, 0)) +#define NEO_PIPE_CONF_CSI_CTRL_VID1_MASK GENMASK(12, 8) +#define NEO_PIPE_CONF_CSI_CTRL_VID1_SET(x) (((x) & GENMASK(4, 0)) << 8) +#define NEO_PIPE_CONF_CSI_CTRL_VID1_GET(x) (((x) >> 8) & GENMASK(4, 0)) +#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_MASK GENMASK(15, 0) +#define NEO_PIPE_CONF_FRAME_NUM_CURR_FRAME_SET(x) (((x) & GENMASK(15, 0)) = << 0) +#define NEO_PIPE_CONF_FRAME_NUM_CURR_FRAME_GET(x) (((x) >> 0) & GENMASK(1= 5, 0)) +#define NEO_PIPE_CONF_FRAME_NUM_SHD_FRAME_MASK GENMASK(31, 16) +#define NEO_PIPE_CONF_FRAME_NUM_SHD_FRAME_SET(x) (((x) & GENMASK(15, 0)) <= < 16) +#define NEO_PIPE_CONF_FRAME_NUM_SHD_FRAME_GET(x) (((x) >> 16) & GENMASK(1= 5, 0)) + +#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_MASK GENMASK(3, 0) +#define NEO_PIPE_CONF_IMG_CONF_CAM0_IBPP0_SET(x) (((x) & GENMASK(3, 0)) <<= 0) +#define NEO_PIPE_CONF_IMG_CONF_CAM0_IBPP0_GET(x) (((x) >> 0) & GENMASK(3,= 0)) +#define NEO_PIPE_CONF_IMG_CONF_CAM0_INALIGN0 BIT(4) +#define NEO_PIPE_CONF_IMG_CONF_CAM0_INALIGN0_SET(x) (((x) & BIT(0)) << 4) +#define NEO_PIPE_CONF_IMG_CONF_CAM0_LPALIGN0 BIT(5) +#define NEO_PIPE_CONF_IMG_CONF_CAM0_LPALIGN0_SET(x) (((x) & BIT(0)) << 5) +#define NEO_PIPE_CONF_IMG_CONF_CAM0_IBPP1_MASK GENMASK(19, 16) +#define NEO_PIPE_CONF_IMG_CONF_CAM0_IBPP1_SET(x) (((x) & GENMASK(3, 0)) <<= 16) +#define NEO_PIPE_CONF_IMG_CONF_CAM0_IBPP1_GET(x) (((x) >> 16) & GENMASK(3= , 0)) +#define NEO_PIPE_CONF_IMG_CONF_CAM0_INALIGN1 BIT(20) +#define NEO_PIPE_CONF_IMG_CONF_CAM0_INALIGN1_SET(x) (((x) & BIT(0)) << 20) +#define NEO_PIPE_CONF_IMG_CONF_CAM0_LPALIGN1 BIT(21) +#define NEO_PIPE_CONF_IMG_CONF_CAM0_LPALIGN1_SET(x) (((x) & BIT(0)) << 21) + +#define NEO_PIPE_CONF_IMG_SIZE_CAM0 0x34 +#define NEO_PIPE_CONF_IMG_SIZE_CAM0_WIDTH_MASK GENMASK(15, 0) +#define NEO_PIPE_CONF_IMG_SIZE_CAM0_WIDTH_SET(x) (((x) & GENMASK(15, 0)) <= < 0) +#define NEO_PIPE_CONF_IMG_SIZE_CAM0_WIDTH_GET(x) (((x) >> 0) & GENMASK(15= , 0)) +#define NEO_PIPE_CONF_IMG_SIZE_CAM0_HEIGHT_MASK GENMASK(31, 16) +#define NEO_PIPE_CONF_IMG_SIZE_CAM0_HEIGHT_SET(x) (((x) & GENMASK(15, 0)) = << 16) +#define NEO_PIPE_CONF_IMG_SIZE_CAM0_HEIGHT_GET(x) (((x) >> 16) & GENMASK(= 15, 0)) + +/* PIPE_CONF ADDR registers contain the upper 32-bits of the 36-bit addres= s of an image frame */ +#define NEO_PIPE_CONF_ADDR_SET(x) (((x) >> 4) & ~0u) + +#define NEO_PIPE_CONF_IMG0_IN_ADDR_CAM0 0x3c + +#define NEO_PIPE_CONF_IMG1_IN_ADDR_CAM0 0x40 + +#define NEO_PIPE_CONF_OUTCH0_ADDR_CAM0 0x44 + +#define NEO_PIPE_CONF_OUTCH1_ADDR_CAM0 0x48 + +#define NEO_PIPE_CONF_OUTIR_ADDR_CAM0 0x4c + +#define NEO_PIPE_CONF_IMG0_IN_LS_CAM0 0x50 +#define NEO_PIPE_CONF_IMG0_IN_LS_CAM0_LS_MASK GENMASK(31, 4) +#define NEO_PIPE_CONF_IMG0_IN_LS_CAM0_LS_SET(x) ((x) & GENMASK(31, 4)) + +#define NEO_PIPE_CONF_IMG1_IN_LS_CAM0 0x54 +#define NEO_PIPE_CONF_IMG1_IN_LS_CAM0_LS_MASK GENMASK(31, 4) +#define NEO_PIPE_CONF_IMG1_IN_LS_CAM0_LS_SET(x) ((x) & GENMASK(31, 4)) + +#define NEO_PIPE_CONF_OUTCH0_LS_CAM0 0x58 +#define NEO_PIPE_CONF_OUTCH0_LS_CAM0_LS_MASK GENMASK(31, 4) +#define NEO_PIPE_CONF_OUTCH0_LS_CAM0_LS_SET(x) ((x) & GENMASK(31, 4)) + +#define NEO_PIPE_CONF_OUTCH1_LS_CAM0 0x5c +#define NEO_PIPE_CONF_OUTCH1_LS_CAM0_LS_MASK GENMASK(31, 4) +#define NEO_PIPE_CONF_OUTCH1_LS_CAM0_LS_SET(x) ((x) & GENMASK(31, 4)) + +#define NEO_PIPE_CONF_OUTIR_LS_CAM0 0x60 +#define NEO_PIPE_CONF_OUTIR_LS_CAM0_LS_MASK GENMASK(31, 4) +#define NEO_PIPE_CONF_OUTIR_LS_CAM0_LS_SET(x) ((x) & GENMASK(31, 4)) + +#define NEO_PIPE_CONF_SKIP_CTRL0 0x64 +#define NEO_PIPE_CONF_SKIP_CTRL0_PRESKIP_MASK GENMASK(15, 0) +#define NEO_PIPE_CONF_SKIP_CTRL0_PRESKIP_SET(x) (((x) & GENMASK(15, 0)) <<= 0) +#define NEO_PIPE_CONF_SKIP_CTRL0_PRESKIP_GET(x) (((x) >> 0) & GENMASK(15,= 0)) +#define NEO_PIPE_CONF_SKIP_CTRL0_POSTSKIP_MASK GENMASK(31, 16) +#define NEO_PIPE_CONF_SKIP_CTRL0_POSTSKIP_SET(x) (((x) & GENMASK(15, 0)) <= < 16) +#define NEO_PIPE_CONF_SKIP_CTRL0_POSTSKIP_GET(x) (((x) >> 16) & GENMASK(1= 5, 0)) + +#define NEO_PIPE_CONF_INT_EN0 0x68 +#define NEO_PIPE_CONF_INT_EN0_V2 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_MASK GENMASK(19, 16) +#define NEO_PIPE_CONF_INT_EN0_EN_BUS_ERR_SET(x) (((x) & GENMASK(3, 0)) << = 16) +#define NEO_PIPE_CONF_INT_EN0_EN_BUS_ERR_GET(x) (((x) >> 16) & GENMASK(3,= 0)) +#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 0x6c +#define NEO_PIPE_CONF_INT_STAT0_V2 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_MASK GENMASK(19, 16) +#define NEO_PIPE_CONF_INT_STAT0_S_BUS_ERR_SET(x) (((x) & GENMASK(3, 0)) <<= 16) +#define NEO_PIPE_CONF_INT_STAT0_S_BUS_ERR_GET(x) (((x) >> 16) & GENMASK(3= , 0)) +#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 0x70 +#define NEO_PIPE_CONF_CSI_STAT_V2 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_MASK GENMASK(1, 0) +#define NEO_HC_CTRL_CAM0_HOFFSET_SET(x) (((x) & GENMASK(1, 0)) << 0) +#define NEO_HC_CTRL_CAM0_HOFFSET_GET(x) (((x) >> 0) & GENMASK(1, 0)) +#define NEO_HC_CTRL_CAM0_VOFFSET_MASK GENMASK(3, 2) +#define NEO_HC_CTRL_CAM0_VOFFSET_SET(x) (((x) & GENMASK(1, 0)) << 2) +#define NEO_HC_CTRL_CAM0_VOFFSET_GET(x) (((x) >> 2) & GENMASK(1, 0)) + +/* HDR_DECOMPRESS0 */ +#define NEO_HDR_DECOMPRESS0_CTRL_CAM0 0x100 +#define NEO_HDR_DECOMPRESS0_CTRL_CAM0_ENABLE BIT(31) +#define NEO_CTRL_CAM0_ENABLE_SET(x) (((x) << 31) & BIT(31)) + +#define NEO_HDR_DECOMPRESS0_KNEE_POINT1_CAM0 0x104 +#define NEO_HDR_DECOMPRESS0_KNEE_POINT1_CAM0_KNEEPOINT_MASK GENMASK(15, 0) +#define NEO_HDR_DECOMPRESS0_KNEE_POINT1_CAM0_KNEEPOINT_SET(x) (((x) & GENM= ASK(15, 0)) << 0) +#define NEO_HDR_DECOMPRESS0_KNEE_POINT1_CAM0_KNEEPOINT_GET(x) (((x) >> 0) = & GENMASK(15, 0)) + +#define NEO_HDR_DECOMPRESS0_KNEE_POINT2_CAM0 0x108 +#define NEO_HDR_DECOMPRESS0_KNEE_POINT2_CAM0_KNEEPOINT_MASK GENMASK(15, 0) +#define NEO_HDR_DECOMPRESS0_KNEE_POINT2_CAM0_KNEEPOINT_SET(x) (((x) & GENM= ASK(15, 0)) << 0) +#define NEO_HDR_DECOMPRESS0_KNEE_POINT2_CAM0_KNEEPOINT_GET(x) (((x) >> 0) = & GENMASK(15, 0)) + +#define NEO_HDR_DECOMPRESS0_KNEE_POINT3_CAM0 0x10c +#define NEO_HDR_DECOMPRESS0_KNEE_POINT3_CAM0_KNEEPOINT_MASK GENMASK(15, 0) +#define NEO_HDR_DECOMPRESS0_KNEE_POINT3_CAM0_KNEEPOINT_SET(x) (((x) & GENM= ASK(15, 0)) << 0) +#define NEO_HDR_DECOMPRESS0_KNEE_POINT3_CAM0_KNEEPOINT_GET(x) (((x) >> 0) = & GENMASK(15, 0)) + +#define NEO_HDR_DECOMPRESS0_KNEE_POINT4_CAM0 0x110 +#define NEO_HDR_DECOMPRESS0_KNEE_POINT4_CAM0_KNEEPOINT_MASK GENMASK(15, 0) +#define NEO_HDR_DECOMPRESS0_KNEE_POINT4_CAM0_KNEEPOINT_SET(x) (((x) & GENM= ASK(15, 0)) << 0) +#define NEO_HDR_DECOMPRESS0_KNEE_POINT4_CAM0_KNEEPOINT_GET(x) (((x) >> 0) = & GENMASK(15, 0)) + +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET0_CAM0 0x114 +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET0_CAM0_OFFSET_MASK GENMASK(15, 0) +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET0_CAM0_OFFSET_SET(x) (((x) & GENMAS= K(15, 0)) << 0) +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET0_CAM0_OFFSET_GET(x) (((x) >> 0) & = GENMASK(15, 0)) + +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET1_CAM0 0x118 +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET1_CAM0_OFFSET_MASK GENMASK(15, 0) +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET1_CAM0_OFFSET_SET(x) (((x) & GENMAS= K(15, 0)) << 0) +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET1_CAM0_OFFSET_GET(x) (((x) >> 0) & = GENMASK(15, 0)) + +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET2_CAM0 0x11c +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET2_CAM0_OFFSET_MASK GENMASK(15, 0) +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET2_CAM0_OFFSET_SET(x) (((x) & GENMAS= K(15, 0)) << 0) +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET2_CAM0_OFFSET_GET(x) (((x) >> 0) & = GENMASK(15, 0)) + +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET3_CAM0 0x120 +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET3_CAM0_OFFSET_MASK GENMASK(15, 0) +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET3_CAM0_OFFSET_SET(x) (((x) & GENMAS= K(15, 0)) << 0) +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET3_CAM0_OFFSET_GET(x) (((x) >> 0) & = GENMASK(15, 0)) + +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET4_CAM0 0x124 +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET4_CAM0_OFFSET_MASK GENMASK(15, 0) +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET4_CAM0_OFFSET_SET(x) (((x) & GENMAS= K(15, 0)) << 0) +#define NEO_HDR_DECOMPRESS0_KNEE_OFFSET4_CAM0_OFFSET_GET(x) (((x) >> 0) & = GENMASK(15, 0)) + +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO01_CAM0 0x128 +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO01_CAM0_RATIO0_MASK GENMASK(11, 0) +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO01_CAM0_RATIO0_SET(x) (((x) & GENMAS= K(11, 0)) << 0) +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO01_CAM0_RATIO0_GET(x) (((x) >> 0) & = GENMASK(11, 0)) +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO01_CAM0_RATIO1_MASK GENMASK(27, 16) +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO01_CAM0_RATIO1_SET(x) (((x) & GENMAS= K(11, 0)) << 16) +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO01_CAM0_RATIO1_GET(x) (((x) >> 16) &= GENMASK(11, 0)) + +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO23_CAM0 0x12c +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO23_CAM0_RATIO2_MASK GENMASK(11, 0) +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO23_CAM0_RATIO2_SET(x) (((x) & GENMAS= K(11, 0)) << 0) +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO23_CAM0_RATIO2_GET(x) (((x) >> 0) & = GENMASK(11, 0)) +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO23_CAM0_RATIO3_MASK GENMASK(27, 16) +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO23_CAM0_RATIO3_SET(x) (((x) & GENMAS= K(11, 0)) << 16) +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO23_CAM0_RATIO3_GET(x) (((x) >> 16) &= GENMASK(11, 0)) + +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO4_CAM0 0x130 +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO4_CAM0_RATIO4_MASK GENMASK(11, 0) +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO4_CAM0_RATIO4_SET(x) (((x) & GENMASK= (11, 0)) << 0) +#define NEO_HDR_DECOMPRESS0_KNEE_RATIO4_CAM0_RATIO4_GET(x) (((x) >> 0) & = GENMASK(11, 0)) + +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT0_CAM0 0x134 +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT0_CAM0_KNEEPOINT_MASK GENMASK(19, 0) +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT0_CAM0_KNEEPOINT_SET(x) (((x) & GEN= MASK(19, 0)) << 0) +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT0_CAM0_KNEEPOINT_GET(x) (((x) >> 0)= & GENMASK(19, 0)) + +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT1_CAM0 0x138 +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT1_CAM0_KNEEPOINT_MASK GENMASK(19, 0) +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT1_CAM0_KNEEPOINT_SET(x) (((x) & GEN= MASK(19, 0)) << 0) +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT1_CAM0_KNEEPOINT_GET(x) (((x) >> 0)= & GENMASK(19, 0)) + +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT2_CAM0 0x13c +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT2_CAM0_KNEEPOINT_MASK GENMASK(19, 0) +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT2_CAM0_KNEEPOINT_SET(x) (((x) & GEN= MASK(19, 0)) << 0) +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT2_CAM0_KNEEPOINT_GET(x) (((x) >> 0)= & GENMASK(19, 0)) + +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT3_CAM0 0x140 +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT3_CAM0_KNEEPOINT_MASK GENMASK(19, 0) +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT3_CAM0_KNEEPOINT_SET(x) (((x) & GEN= MASK(19, 0)) << 0) +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT3_CAM0_KNEEPOINT_GET(x) (((x) >> 0)= & GENMASK(19, 0)) + +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT4_CAM0 0x144 +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT4_CAM0_KNEEPOINT_MASK GENMASK(19, 0) +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT4_CAM0_KNEEPOINT_SET(x) (((x) & GEN= MASK(19, 0)) << 0) +#define NEO_HDR_DECOMPRESS0_KNEE_NPOINT4_CAM0_KNEEPOINT_GET(x) (((x) >> 0)= & 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_MASK GENMASK(15, 0) +#define NEO_HDR_DECOMPRESS1_KNEE_POINT1_CAM0_KNEEPOINT_SET(x) (((x) & GENM= ASK(15, 0)) << 0) +#define NEO_HDR_DECOMPRESS1_KNEE_POINT1_CAM0_KNEEPOINT_GET(x) (((x) >> 0) = & GENMASK(15, 0)) + +#define NEO_HDR_DECOMPRESS1_KNEE_POINT2_CAM0 0x188 +#define NEO_HDR_DECOMPRESS1_KNEE_POINT2_CAM0_KNEEPOINT_MASK GENMASK(15, 0) +#define NEO_HDR_DECOMPRESS1_KNEE_POINT2_CAM0_KNEEPOINT_SET(x) (((x) & GENM= ASK(15, 0)) << 0) +#define NEO_HDR_DECOMPRESS1_KNEE_POINT2_CAM0_KNEEPOINT_GET(x) (((x) >> 0) = & GENMASK(15, 0)) + +#define NEO_HDR_DECOMPRESS1_KNEE_POINT3_CAM0 0x18c +#define NEO_HDR_DECOMPRESS1_KNEE_POINT3_CAM0_KNEEPOINT_MASK GENMASK(15, 0) +#define NEO_HDR_DECOMPRESS1_KNEE_POINT3_CAM0_KNEEPOINT_SET(x) (((x) & GENM= ASK(15, 0)) << 0) +#define NEO_HDR_DECOMPRESS1_KNEE_POINT3_CAM0_KNEEPOINT_GET(x) (((x) >> 0) = & GENMASK(15, 0)) + +#define NEO_HDR_DECOMPRESS1_KNEE_POINT4_CAM0 0x190 +#define NEO_HDR_DECOMPRESS1_KNEE_POINT4_CAM0_KNEEPOINT_MASK GENMASK(15, 0) +#define NEO_HDR_DECOMPRESS1_KNEE_POINT4_CAM0_KNEEPOINT_SET(x) (((x) & GENM= ASK(15, 0)) << 0) +#define NEO_HDR_DECOMPRESS1_KNEE_POINT4_CAM0_KNEEPOINT_GET(x) (((x) >> 0) = & GENMASK(15, 0)) + +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET0_CAM0 0x194 +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET0_CAM0_OFFSET_MASK GENMASK(15, 0) +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET0_CAM0_OFFSET_SET(x) (((x) & GENMAS= K(15, 0)) << 0) +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET0_CAM0_OFFSET_GET(x) (((x) >> 0) & = GENMASK(15, 0)) + +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET1_CAM0 0x198 +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET1_CAM0_OFFSET_MASK GENMASK(15, 0) +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET1_CAM0_OFFSET_SET(x) (((x) & GENMAS= K(15, 0)) << 0) +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET1_CAM0_OFFSET_GET(x) (((x) >> 0) & = GENMASK(15, 0)) + +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET2_CAM0 0x19c +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET2_CAM0_OFFSET_MASK GENMASK(15, 0) +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET2_CAM0_OFFSET_SET(x) (((x) & GENMAS= K(15, 0)) << 0) +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET2_CAM0_OFFSET_GET(x) (((x) >> 0) & = GENMASK(15, 0)) + +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET3_CAM0 0x1a0 +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET3_CAM0_OFFSET_MASK GENMASK(15, 0) +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET3_CAM0_OFFSET_SET(x) (((x) & GENMAS= K(15, 0)) << 0) +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET3_CAM0_OFFSET_GET(x) (((x) >> 0) & = GENMASK(15, 0)) + +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET4_CAM0 0x1a4 +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET4_CAM0_OFFSET_MASK GENMASK(15, 0) +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET4_CAM0_OFFSET_SET(x) (((x) & GENMAS= K(15, 0)) << 0) +#define NEO_HDR_DECOMPRESS1_KNEE_OFFSET4_CAM0_OFFSET_GET(x) (((x) >> 0) & = GENMASK(15, 0)) + +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO01_CAM0 0x1a8 +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO01_CAM0_RATIO0_MASK GENMASK(11, 0) +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO01_CAM0_RATIO0_SET(x) (((x) & GENMAS= K(11, 0)) << 0) +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO01_CAM0_RATIO0_GET(x) (((x) >> 0) & = GENMASK(11, 0)) +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO01_CAM0_RATIO1_MASK GENMASK(27, 16) +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO01_CAM0_RATIO1_SET(x) (((x) & GENMAS= K(11, 0)) << 16) +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO01_CAM0_RATIO1_GET(x) (((x) >> 16) &= GENMASK(11, 0)) + +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO23_CAM0 0x1ac +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO23_CAM0_RATIO2_MASK GENMASK(11, 0) +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO23_CAM0_RATIO2_SET(x) (((x) & GENMAS= K(11, 0)) << 0) +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO23_CAM0_RATIO2_GET(x) (((x) >> 0) & = GENMASK(11, 0)) +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO23_CAM0_RATIO3_MASK GENMASK(27, 16) +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO23_CAM0_RATIO3_SET(x) (((x) & GENMAS= K(11, 0)) << 16) +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO23_CAM0_RATIO3_GET(x) (((x) >> 16) &= GENMASK(11, 0)) + +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO4_CAM0 0x1b0 +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO4_CAM0_RATIO4_MASK GENMASK(11, 0) +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO4_CAM0_RATIO4_SET(x) (((x) & GENMASK= (11, 0)) << 0) +#define NEO_HDR_DECOMPRESS1_KNEE_RATIO4_CAM0_RATIO4_GET(x) (((x) >> 0) & = GENMASK(11, 0)) + +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT0_CAM0 0x1b4 +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT0_CAM0_KNEEPOINT_MASK GENMASK(15, 0) +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT0_CAM0_KNEEPOINT_SET(x) (((x) & GEN= MASK(15, 0)) << 0) +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT0_CAM0_KNEEPOINT_GET(x) (((x) >> 0)= & GENMASK(15, 0)) + +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT1_CAM0 0x1b8 +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT1_CAM0_KNEEPOINT_MASK GENMASK(15, 0) +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT1_CAM0_KNEEPOINT_SET(x) (((x) & GEN= MASK(15, 0)) << 0) +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT1_CAM0_KNEEPOINT_GET(x) (((x) >> 0)= & GENMASK(15, 0)) + +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT2_CAM0 0x1bc +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT2_CAM0_KNEEPOINT_MASK GENMASK(15, 0) +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT2_CAM0_KNEEPOINT_SET(x) (((x) & GEN= MASK(15, 0)) << 0) +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT2_CAM0_KNEEPOINT_GET(x) (((x) >> 0)= & GENMASK(15, 0)) + +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT3_CAM0 0x1c0 +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT3_CAM0_KNEEPOINT_MASK GENMASK(15, 0) +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT3_CAM0_KNEEPOINT_SET(x) (((x) & GEN= MASK(15, 0)) << 0) +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT3_CAM0_KNEEPOINT_GET(x) (((x) >> 0)= & GENMASK(15, 0)) + +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT4_CAM0 0x1c4 +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT4_CAM0_KNEEPOINT_MASK GENMASK(15, 0) +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT4_CAM0_KNEEPOINT_SET(x) (((x) & GEN= MASK(15, 0)) << 0) +#define NEO_HDR_DECOMPRESS1_KNEE_NPOINT4_CAM0_KNEEPOINT_GET(x) (((x) >> 0)= & GENMASK(15, 0)) + +/* OB_WB0 */ +#define NEO_OB_WB0_CTRL_CAM0 0x200 +#define NEO_OB_WB0_CTRL_CAM0_OBPP_MASK GENMASK(3, 2) +#define NEO_OB_WB0_CTRL_CAM0_OBPP_SET(x) (((x) & GENMASK(1, 0)) << 2) +#define NEO_OB_WB0_CTRL_CAM0_OBPP_GET(x) (((x) >> 2) & GENMASK(1, 0)) + +#define NEO_OB_WB0_R_CTRL_CAM0 0x204 +#define NEO_OB_WB0_R_CTRL_CAM0_OFFSET_MASK GENMASK(15, 0) +#define NEO_OB_WB0_R_CTRL_CAM0_OFFSET_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_OB_WB0_R_CTRL_CAM0_OFFSET_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_OB_WB0_R_CTRL_CAM0_GAIN_MASK GENMASK(31, 16) +#define NEO_OB_WB0_R_CTRL_CAM0_GAIN_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_OB_WB0_R_CTRL_CAM0_GAIN_GET(x) (((x) >> 16) & GENMASK(15, 0)) + +#define NEO_OB_WB0_GR_CTRL_CAM0 0x208 +#define NEO_OB_WB0_GR_CTRL_CAM0_OFFSET_MASK GENMASK(15, 0) +#define NEO_OB_WB0_GR_CTRL_CAM0_OFFSET_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_OB_WB0_GR_CTRL_CAM0_OFFSET_GET(x) (((x) >> 0) & GENMASK(15, 0= )) +#define NEO_OB_WB0_GR_CTRL_CAM0_GAIN_MASK GENMASK(31, 16) +#define NEO_OB_WB0_GR_CTRL_CAM0_GAIN_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_OB_WB0_GR_CTRL_CAM0_GAIN_GET(x) (((x) >> 16) & GENMASK(15, 0)) + +#define NEO_OB_WB0_GB_CTRL_CAM0 0x20c +#define NEO_OB_WB0_GB_CTRL_CAM0_OFFSET_MASK GENMASK(15, 0) +#define NEO_OB_WB0_GB_CTRL_CAM0_OFFSET_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_OB_WB0_GB_CTRL_CAM0_OFFSET_GET(x) (((x) >> 0) & GENMASK(15, 0= )) +#define NEO_OB_WB0_GB_CTRL_CAM0_GAIN_MASK GENMASK(31, 16) +#define NEO_OB_WB0_GB_CTRL_CAM0_GAIN_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_OB_WB0_GB_CTRL_CAM0_GAIN_GET(x) (((x) >> 16) & GENMASK(15, 0)) + +#define NEO_OB_WB0_B_CTRL_CAM0 0x210 +#define NEO_OB_WB0_B_CTRL_CAM0_OFFSET_MASK GENMASK(15, 0) +#define NEO_OB_WB0_B_CTRL_CAM0_OFFSET_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_OB_WB0_B_CTRL_CAM0_OFFSET_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_OB_WB0_B_CTRL_CAM0_GAIN_MASK GENMASK(31, 16) +#define NEO_OB_WB0_B_CTRL_CAM0_GAIN_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_OB_WB0_B_CTRL_CAM0_GAIN_GET(x) (((x) >> 16) & GENMASK(15, 0)) + +/* OB_WB1 */ +#define NEO_OB_WB1_CTRL_CAM0 0x240 +#define NEO_OB_WB1_CTRL_CAM0_OBPP_MASK GENMASK(3, 2) +#define NEO_OB_WB1_CTRL_CAM0_OBPP_SET(x) (((x) & GENMASK(1, 0)) << 2) +#define NEO_OB_WB1_CTRL_CAM0_OBPP_GET(x) (((x) >> 2) & GENMASK(1, 0)) + +#define NEO_OB_WB1_R_CTRL_CAM0 0x244 +#define NEO_OB_WB1_R_CTRL_CAM0_OFFSET_MASK GENMASK(15, 0) +#define NEO_OB_WB1_R_CTRL_CAM0_OFFSET_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_OB_WB1_R_CTRL_CAM0_OFFSET_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_OB_WB1_R_CTRL_CAM0_GAIN_MASK GENMASK(31, 16) +#define NEO_OB_WB1_R_CTRL_CAM0_GAIN_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_OB_WB1_R_CTRL_CAM0_GAIN_GET(x) (((x) >> 16) & GENMASK(15, 0)) + +#define NEO_OB_WB1_GR_CTRL_CAM0 0x248 +#define NEO_OB_WB1_GR_CTRL_CAM0_OFFSET_MASK GENMASK(15, 0) +#define NEO_OB_WB1_GR_CTRL_CAM0_OFFSET_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_OB_WB1_GR_CTRL_CAM0_OFFSET_GET(x) (((x) >> 0) & GENMASK(15, 0= )) +#define NEO_OB_WB1_GR_CTRL_CAM0_GAIN_MASK GENMASK(31, 16) +#define NEO_OB_WB1_GR_CTRL_CAM0_GAIN_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_OB_WB1_GR_CTRL_CAM0_GAIN_GET(x) (((x) >> 16) & GENMASK(15, 0)) + +#define NEO_OB_WB1_GB_CTRL_CAM0 0x24c +#define NEO_OB_WB1_GB_CTRL_CAM0_OFFSET_MASK GENMASK(15, 0) +#define NEO_OB_WB1_GB_CTRL_CAM0_OFFSET_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_OB_WB1_GB_CTRL_CAM0_OFFSET_GET(x) (((x) >> 0) & GENMASK(15, 0= )) +#define NEO_OB_WB1_GB_CTRL_CAM0_GAIN_MASK GENMASK(31, 16) +#define NEO_OB_WB1_GB_CTRL_CAM0_GAIN_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_OB_WB1_GB_CTRL_CAM0_GAIN_GET(x) (((x) >> 16) & GENMASK(15, 0)) + +#define NEO_OB_WB1_B_CTRL_CAM0 0x250 +#define NEO_OB_WB1_B_CTRL_CAM0_OFFSET_MASK GENMASK(15, 0) +#define NEO_OB_WB1_B_CTRL_CAM0_OFFSET_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_OB_WB1_B_CTRL_CAM0_OFFSET_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_OB_WB1_B_CTRL_CAM0_GAIN_MASK GENMASK(31, 16) +#define NEO_OB_WB1_B_CTRL_CAM0_GAIN_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_OB_WB1_B_CTRL_CAM0_GAIN_GET(x) (((x) >> 16) & GENMASK(15, 0)) + +/* OB_WB2 */ +#define NEO_OB_WB2_CTRL_CAM0 0x280 +#define NEO_OB_WB2_CTRL_CAM0_OBPP_MASK GENMASK(3, 2) +#define NEO_OB_WB2_CTRL_CAM0_OBPP_SET(x) (((x) & GENMASK(1, 0)) << 2) +#define NEO_OB_WB2_CTRL_CAM0_OBPP_GET(x) (((x) >> 2) & GENMASK(1, 0)) + +#define NEO_OB_WB2_R_CTRL_CAM0 0x284 +#define NEO_OB_WB2_R_CTRL_CAM0_OFFSET_MASK GENMASK(15, 0) +#define NEO_OB_WB2_R_CTRL_CAM0_OFFSET_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_OB_WB2_R_CTRL_CAM0_OFFSET_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_OB_WB2_R_CTRL_CAM0_GAIN_MASK GENMASK(31, 16) +#define NEO_OB_WB2_R_CTRL_CAM0_GAIN_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_OB_WB2_R_CTRL_CAM0_GAIN_GET(x) (((x) >> 16) & GENMASK(15, 0)) + +#define NEO_OB_WB2_GR_CTRL_CAM0 0x288 +#define NEO_OB_WB2_GR_CTRL_CAM0_OFFSET_MASK GENMASK(15, 0) +#define NEO_OB_WB2_GR_CTRL_CAM0_OFFSET_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_OB_WB2_GR_CTRL_CAM0_OFFSET_GET(x) (((x) >> 0) & GENMASK(15, 0= )) +#define NEO_OB_WB2_GR_CTRL_CAM0_GAIN_MASK GENMASK(31, 16) +#define NEO_OB_WB2_GR_CTRL_CAM0_GAIN_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_OB_WB2_GR_CTRL_CAM0_GAIN_GET(x) (((x) >> 16) & GENMASK(15, 0)) + +#define NEO_OB_WB2_GB_CTRL_CAM0 0x28c +#define NEO_OB_WB2_GB_CTRL_CAM0_OFFSET_MASK GENMASK(15, 0) +#define NEO_OB_WB2_GB_CTRL_CAM0_OFFSET_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_OB_WB2_GB_CTRL_CAM0_OFFSET_GET(x) (((x) >> 0) & GENMASK(15, 0= )) +#define NEO_OB_WB2_GB_CTRL_CAM0_GAIN_MASK GENMASK(31, 16) +#define NEO_OB_WB2_GB_CTRL_CAM0_GAIN_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_OB_WB2_GB_CTRL_CAM0_GAIN_GET(x) (((x) >> 16) & GENMASK(15, 0)) + +#define NEO_OB_WB2_B_CTRL_CAM0 0x290 +#define NEO_OB_WB2_B_CTRL_CAM0_OFFSET_MASK GENMASK(15, 0) +#define NEO_OB_WB2_B_CTRL_CAM0_OFFSET_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_OB_WB2_B_CTRL_CAM0_OFFSET_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_OB_WB2_B_CTRL_CAM0_GAIN_MASK GENMASK(31, 16) +#define NEO_OB_WB2_B_CTRL_CAM0_GAIN_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_OB_WB2_B_CTRL_CAM0_GAIN_GET(x) (((x) >> 16) & GENMASK(15, 0)) + +/* HDR_MERGE */ +#define NEO_HDR_MERGE_CTRL_CAM0 0x300 +#define NEO_HDR_MERGE_CTRL_CAM0_OBPP_MASK GENMASK(3, 2) +#define NEO_HDR_MERGE_CTRL_CAM0_OBPP_SET(x) (((x) & GENMASK(1, 0)) << 2) +#define NEO_HDR_MERGE_CTRL_CAM0_OBPP_GET(x) (((x) >> 2) & GENMASK(1, 0)) +#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_MOTION_FIX_EN_SET(x) (((x) << 8) & BIT(8)) +#define NEO_HDR_MERGE_CTRL_CAM0_BLEND_3X3 BIT(9) +#define NEO_HDR_MERGE_CTRL_CAM0_BLEND_3X3_SET(x) (((x) << 9) & BIT(9)) +#define NEO_HDR_MERGE_CTRL_CAM0_GAIN0BPP_MASK GENMASK(17, 16) +#define NEO_HDR_MERGE_CTRL_CAM0_GAIN0BPP_SET(x) (((x) & GENMASK(1, 0)) << = 16) +#define NEO_HDR_MERGE_CTRL_CAM0_GAIN0BPP_GET(x) (((x) >> 16) & GENMASK(1,= 0)) +#define NEO_HDR_MERGE_CTRL_CAM0_GAIN1BPP_MASK GENMASK(19, 18) +#define NEO_HDR_MERGE_CTRL_CAM0_GAIN1BPP_SET(x) (((x) & GENMASK(1, 0)) << = 18) +#define NEO_HDR_MERGE_CTRL_CAM0_GAIN1BPP_GET(x) (((x) >> 18) & GENMASK(1,= 0)) +#define NEO_HDR_MERGE_CTRL_CAM0_ENABLE BIT(31) +#define NEO_HDR_MERGE_CTRL_CAM0_ENABLE_SET(x) (((x) << 31) & BIT(31)) + +#define NEO_HDR_MERGE_GAIN_OFFSET_CAM0 0x304 +#define NEO_HDR_MERGE_GAIN_OFFSET_CAM0_OFFSET0_MASK GENMASK(15, 0) +#define NEO_HDR_MERGE_GAIN_OFFSET_CAM0_OFFSET0_SET(x) (((x) & GENMASK(15, = 0)) << 0) +#define NEO_HDR_MERGE_GAIN_OFFSET_CAM0_OFFSET0_GET(x) (((x) >> 0) & GENMA= SK(15, 0)) +#define NEO_HDR_MERGE_GAIN_OFFSET_CAM0_OFFSET1_MASK GENMASK(31, 16) +#define NEO_HDR_MERGE_GAIN_OFFSET_CAM0_OFFSET1_SET(x) (((x) & GENMASK(15, = 0)) << 16) +#define NEO_HDR_MERGE_GAIN_OFFSET_CAM0_OFFSET1_GET(x) (((x) >> 16) & GENM= ASK(15, 0)) + +#define NEO_HDR_MERGE_GAIN_SCALE_CAM0 0x308 +#define NEO_HDR_MERGE_GAIN_SCALE_CAM0_SCALE0_MASK GENMASK(15, 0) +#define NEO_HDR_MERGE_GAIN_SCALE_CAM0_SCALE0_SET(x) (((x) & GENMASK(15, 0)= ) << 0) +#define NEO_HDR_MERGE_GAIN_SCALE_CAM0_SCALE0_GET(x) (((x) >> 0) & GENMASK= (15, 0)) +#define NEO_HDR_MERGE_GAIN_SCALE_CAM0_SCALE1_MASK GENMASK(31, 16) +#define NEO_HDR_MERGE_GAIN_SCALE_CAM0_SCALE1_SET(x) (((x) & GENMASK(15, 0)= ) << 16) +#define NEO_HDR_MERGE_GAIN_SCALE_CAM0_SCALE1_GET(x) (((x) >> 16) & GENMAS= K(15, 0)) + +#define NEO_HDR_MERGE_GAIN_SHIFT_CAM0 0x30c +#define NEO_HDR_MERGE_GAIN_SHIFT_CAM0_SHIFT0_MASK GENMASK(4, 0) +#define NEO_HDR_MERGE_GAIN_SHIFT_CAM0_SHIFT0_SET(x) (((x) & GENMASK(4, 0))= << 0) +#define NEO_HDR_MERGE_GAIN_SHIFT_CAM0_SHIFT0_GET(x) (((x) >> 0) & GENMASK= (4, 0)) +#define NEO_HDR_MERGE_GAIN_SHIFT_CAM0_SHIFT1_MASK GENMASK(20, 16) +#define NEO_HDR_MERGE_GAIN_SHIFT_CAM0_SHIFT1_SET(x) (((x) & GENMASK(4, 0))= << 16) +#define NEO_HDR_MERGE_GAIN_SHIFT_CAM0_SHIFT1_GET(x) (((x) >> 16) & GENMAS= K(4, 0)) + +#define NEO_HDR_MERGE_LUMA_TH_CAM0 0x310 +#define NEO_HDR_MERGE_LUMA_TH_CAM0_TH0_MASK GENMASK(15, 0) +#define NEO_HDR_MERGE_LUMA_TH_CAM0_TH0_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_HDR_MERGE_LUMA_TH_CAM0_TH0_GET(x) (((x) >> 0) & GENMASK(15, 0= )) + +#define NEO_HDR_MERGE_LUMA_SCALE_CAM0 0x314 +#define NEO_HDR_MERGE_LUMA_SCALE_CAM0_SCALE_MASK GENMASK(15, 0) +#define NEO_HDR_MERGE_LUMA_SCALE_CAM0_SCALE_SET(x) (((x) & GENMASK(15, 0))= << 0) +#define NEO_HDR_MERGE_LUMA_SCALE_CAM0_SCALE_GET(x) (((x) >> 0) & GENMASK(= 15, 0)) +#define NEO_HDR_MERGE_LUMA_SCALE_CAM0_SHIFT_MASK GENMASK(20, 16) +#define NEO_HDR_MERGE_LUMA_SCALE_CAM0_SHIFT_SET(x) (((x) & GENMASK(4, 0)) = << 16) +#define NEO_HDR_MERGE_LUMA_SCALE_CAM0_SHIFT_GET(x) (((x) >> 16) & GENMASK= (4, 0)) +#define NEO_HDR_MERGE_LUMA_SCALE_CAM0_THSHIFT_MASK GENMASK(28, 24) +#define NEO_HDR_MERGE_LUMA_SCALE_CAM0_THSHIFT_SET(x) (((x) & GENMASK(4, 0)= ) << 24) +#define NEO_HDR_MERGE_LUMA_SCALE_CAM0_THSHIFT_GET(x) (((x) >> 24) & GENMA= SK(4, 0)) + +#define NEO_HDR_MERGE_DOWNSCALE_CAM0 0x318 +#define NEO_HDR_MERGE_DOWNSCALE_CAM0_IMGSCALE0_MASK GENMASK(4, 0) +#define NEO_HDR_MERGE_DOWNSCALE_CAM0_IMGSCALE0_SET(x) (((x) & GENMASK(4, 0= )) << 0) +#define NEO_HDR_MERGE_DOWNSCALE_CAM0_IMGSCALE0_GET(x) (((x) >> 0) & GENMA= SK(4, 0)) +#define NEO_HDR_MERGE_DOWNSCALE_CAM0_IMGSCALE1_MASK GENMASK(20, 16) +#define NEO_HDR_MERGE_DOWNSCALE_CAM0_IMGSCALE1_SET(x) (((x) & GENMASK(4, 0= )) << 16) +#define NEO_HDR_MERGE_DOWNSCALE_CAM0_IMGSCALE1_GET(x) (((x) >> 16) & GENM= ASK(4, 0)) + +#define NEO_HDR_MERGE_UPSCALE_CAM0 0x31c +#define NEO_HDR_MERGE_UPSCALE_CAM0_IMGSCALE0_MASK GENMASK(3, 0) +#define NEO_HDR_MERGE_UPSCALE_CAM0_IMGSCALE0_SET(x) (((x) & GENMASK(3, 0))= << 0) +#define NEO_HDR_MERGE_UPSCALE_CAM0_IMGSCALE0_GET(x) (((x) >> 0) & GENMASK= (3, 0)) +#define NEO_HDR_MERGE_UPSCALE_CAM0_IMGSCALE1_MASK GENMASK(19, 16) +#define NEO_HDR_MERGE_UPSCALE_CAM0_IMGSCALE1_SET(x) (((x) & GENMASK(3, 0))= << 16) +#define NEO_HDR_MERGE_UPSCALE_CAM0_IMGSCALE1_GET(x) (((x) >> 16) & GENMAS= K(3, 0)) + +#define NEO_HDR_MERGE_POST_SCALE_CAM0 0x320 +#define NEO_HDR_MERGE_POST_SCALE_CAM0_SCALE_MASK GENMASK(4, 0) +#define NEO_HDR_MERGE_POST_SCALE_CAM0_SCALE_SET(x) (((x) & GENMASK(4, 0)) = << 0) +#define NEO_HDR_MERGE_POST_SCALE_CAM0_SCALE_GET(x) (((x) >> 0) & GENMASK(= 4, 0)) + +#define NEO_HDR_MERGE_S_GAIN_OFFSET_CAM0 0x324 +#define NEO_HDR_MERGE_S_GAIN_OFFSET_CAM0_OFFSET0_MASK GENMASK(15, 0) +#define NEO_HDR_MERGE_S_GAIN_OFFSET_CAM0_OFFSET0_SET(x) (((x) & GENMASK(15= , 0)) << 0) +#define NEO_HDR_MERGE_S_GAIN_OFFSET_CAM0_OFFSET0_GET(x) (((x) >> 0) & GEN= MASK(15, 0)) +#define NEO_HDR_MERGE_S_GAIN_OFFSET_CAM0_OFFSET1_MASK GENMASK(31, 16) +#define NEO_HDR_MERGE_S_GAIN_OFFSET_CAM0_OFFSET1_SET(x) (((x) & GENMASK(15= , 0)) << 16) +#define NEO_HDR_MERGE_S_GAIN_OFFSET_CAM0_OFFSET1_GET(x) (((x) >> 16) & GE= NMASK(15, 0)) + +#define NEO_HDR_MERGE_S_GAIN_SCALE_CAM0 0x328 +#define NEO_HDR_MERGE_S_GAIN_SCALE_CAM0_SCALE0_MASK GENMASK(15, 0) +#define NEO_HDR_MERGE_S_GAIN_SCALE_CAM0_SCALE0_SET(x) (((x) & GENMASK(15, = 0)) << 0) +#define NEO_HDR_MERGE_S_GAIN_SCALE_CAM0_SCALE0_GET(x) (((x) >> 0) & GENMA= SK(15, 0)) +#define NEO_HDR_MERGE_S_GAIN_SCALE_CAM0_SCALE1_MASK GENMASK(31, 16) +#define NEO_HDR_MERGE_S_GAIN_SCALE_CAM0_SCALE1_SET(x) (((x) & GENMASK(15, = 0)) << 16) +#define NEO_HDR_MERGE_S_GAIN_SCALE_CAM0_SCALE1_GET(x) (((x) >> 16) & GENM= ASK(15, 0)) + +#define NEO_HDR_MERGE_S_GAIN_SHIFT_CAM0 0x32c +#define NEO_HDR_MERGE_S_GAIN_SHIFT_CAM0_SHIFT0_MASK GENMASK(4, 0) +#define NEO_HDR_MERGE_S_GAIN_SHIFT_CAM0_SHIFT0_SET(x) (((x) & GENMASK(4, 0= )) << 0) +#define NEO_HDR_MERGE_S_GAIN_SHIFT_CAM0_SHIFT0_GET(x) (((x) >> 0) & GENMA= SK(4, 0)) +#define NEO_HDR_MERGE_S_GAIN_SHIFT_CAM0_SHIFT1_MASK GENMASK(20, 16) +#define NEO_HDR_MERGE_S_GAIN_SHIFT_CAM0_SHIFT1_SET(x) (((x) & GENMASK(4, 0= )) << 16) +#define NEO_HDR_MERGE_S_GAIN_SHIFT_CAM0_SHIFT1_GET(x) (((x) >> 16) & GENM= ASK(4, 0)) + +#define NEO_HDR_MERGE_S_LUMA_TH_CAM0 0x330 +#define NEO_HDR_MERGE_S_LUMA_TH_CAM0_TH0_MASK GENMASK(15, 0) +#define NEO_HDR_MERGE_S_LUMA_TH_CAM0_TH0_SET(x) (((x) & GENMASK(15, 0)) <<= 0) +#define NEO_HDR_MERGE_S_LUMA_TH_CAM0_TH0_GET(x) (((x) >> 0) & GENMASK(15,= 0)) + +#define NEO_HDR_MERGE_S_LUMA_SCALE_CAM0 0x334 +#define NEO_HDR_MERGE_S_LUMA_SCALE_CAM0_SCALE_MASK GENMASK(15, 0) +#define NEO_HDR_MERGE_S_LUMA_SCALE_CAM0_SCALE_SET(x) (((x) & GENMASK(15, 0= )) << 0) +#define NEO_HDR_MERGE_S_LUMA_SCALE_CAM0_SCALE_GET(x) (((x) >> 0) & GENMAS= K(15, 0)) +#define NEO_HDR_MERGE_S_LUMA_SCALE_CAM0_SHIFT_MASK GENMASK(20, 16) +#define NEO_HDR_MERGE_S_LUMA_SCALE_CAM0_SHIFT_SET(x) (((x) & GENMASK(4, 0)= ) << 16) +#define NEO_HDR_MERGE_S_LUMA_SCALE_CAM0_SHIFT_GET(x) (((x) >> 16) & GENMA= SK(4, 0)) +#define NEO_HDR_MERGE_S_LUMA_SCALE_CAM0_THSHIFT_MASK GENMASK(28, 24) +#define NEO_HDR_MERGE_S_LUMA_SCALE_CAM0_THSHIFT_SET(x) (((x) & GENMASK(4, = 0)) << 24) +#define NEO_HDR_MERGE_S_LUMA_SCALE_CAM0_THSHIFT_GET(x) (((x) >> 24) & GEN= MASK(4, 0)) + +#define NEO_HDR_MERGE_S_DOWNSCALE_CAM0 0x338 +#define NEO_HDR_MERGE_S_DOWNSCALE_CAM0_IMGSCALE0_MASK GENMASK(4, 0) +#define NEO_HDR_MERGE_S_DOWNSCALE_CAM0_IMGSCALE0_SET(x) (((x) & GENMASK(4,= 0)) << 0) +#define NEO_HDR_MERGE_S_DOWNSCALE_CAM0_IMGSCALE0_GET(x) (((x) >> 0) & GEN= MASK(4, 0)) +#define NEO_HDR_MERGE_S_DOWNSCALE_CAM0_IMGSCALE1_MASK GENMASK(20, 16) +#define NEO_HDR_MERGE_S_DOWNSCALE_CAM0_IMGSCALE1_SET(x) (((x) & GENMASK(4,= 0)) << 16) +#define NEO_HDR_MERGE_S_DOWNSCALE_CAM0_IMGSCALE1_GET(x) (((x) >> 16) & GE= NMASK(4, 0)) + +#define NEO_HDR_MERGE_S_UPSCALE_CAM0 0x33c +#define NEO_HDR_MERGE_S_UPSCALE_CAM0_IMGSCALE0_MASK GENMASK(3, 0) +#define NEO_HDR_MERGE_S_UPSCALE_CAM0_IMGSCALE0_SET(x) (((x) & GENMASK(3, 0= )) << 0) +#define NEO_HDR_MERGE_S_UPSCALE_CAM0_IMGSCALE0_GET(x) (((x) >> 0) & GENMA= SK(3, 0)) +#define NEO_HDR_MERGE_S_UPSCALE_CAM0_IMGSCALE1_MASK GENMASK(19, 16) +#define NEO_HDR_MERGE_S_UPSCALE_CAM0_IMGSCALE1_SET(x) (((x) & GENMASK(3, 0= )) << 16) +#define NEO_HDR_MERGE_S_UPSCALE_CAM0_IMGSCALE1_GET(x) (((x) >> 16) & GENM= ASK(3, 0)) + +#define NEO_HDR_MERGE_S_POST_SCALE_CAM0 0x340 +#define NEO_HDR_MERGE_S_POST_SCALE_CAM0_SCALE_MASK GENMASK(4, 0) +#define NEO_HDR_MERGE_S_POST_SCALE_CAM0_SCALE_SET(x) (((x) & GENMASK(4, 0)= ) << 0) +#define NEO_HDR_MERGE_S_POST_SCALE_CAM0_SCALE_GET(x) (((x) >> 0) & GENMAS= K(4, 0)) + +#define NEO_HDR_MERGE_S_LINE_NUM_CAM0 0x344 +#define NEO_HDR_MERGE_S_LINE_NUM_CAM0_LINE_MASK GENMASK(15, 1) +#define NEO_HDR_MERGE_S_LINE_NUM_CAM0_LINE_SET(x) (((x) & GENMASK(14, 0)) = << 1) +#define NEO_HDR_MERGE_S_LINE_NUM_CAM0_LINE_GET(x) (((x) >> 1) & GENMASK(1= 4, 0)) + +/* COLOR_TEMP */ +#define NEO_COLOR_TEMP_CTRL_CAM0 0x400 +#define NEO_COLOR_TEMP_CTRL_CAM0_IBPP_MASK GENMASK(1, 0) +#define NEO_COLOR_TEMP_CTRL_CAM0_IBPP_SET(x) (((x) & GENMASK(1, 0)) << 0) +#define NEO_COLOR_TEMP_CTRL_CAM0_IBPP_GET(x) (((x) >> 0) & GENMASK(1, 0)) +#define NEO_COLOR_TEMP_CTRL_CAM0_CSCON BIT(4) +#define NEO_COLOR_TEMP_CTRL_CAM0_CSCON_SET(x) (((x) << 4) & BIT(4)) +#define NEO_COLOR_TEMP_CTRL_CAM0_ENABLE BIT(31) +#define NEO_COLOR_TEMP_CTRL_CAM0_ENABLE_SET(x) (((x) << 31) & BIT(31)) + +#define NEO_COLOR_TEMP_ROI_POS_CAM0 0x404 +#define NEO_COLOR_TEMP_ROI_POS_CAM0_XPOS_MASK GENMASK(15, 0) +#define NEO_COLOR_TEMP_ROI_POS_CAM0_XPOS_SET(x) (((x) & GENMASK(15, 0)) <<= 0) +#define NEO_COLOR_TEMP_ROI_POS_CAM0_XPOS_GET(x) (((x) >> 0) & GENMASK(15,= 0)) +#define NEO_COLOR_TEMP_ROI_POS_CAM0_YPOS_MASK GENMASK(31, 16) +#define NEO_COLOR_TEMP_ROI_POS_CAM0_YPOS_SET(x) (((x) & GENMASK(15, 0)) <<= 16) +#define NEO_COLOR_TEMP_ROI_POS_CAM0_YPOS_GET(x) (((x) >> 16) & GENMASK(15= , 0)) + +#define NEO_COLOR_TEMP_ROI_SIZE_CAM0 0x408 +#define NEO_COLOR_TEMP_ROI_SIZE_CAM0_WIDTH_MASK GENMASK(15, 0) +#define NEO_COLOR_TEMP_ROI_SIZE_CAM0_WIDTH_SET(x) (((x) & GENMASK(15, 0)) = << 0) +#define NEO_COLOR_TEMP_ROI_SIZE_CAM0_WIDTH_GET(x) (((x) >> 0) & GENMASK(1= 5, 0)) +#define NEO_COLOR_TEMP_ROI_SIZE_CAM0_HEIGHT_MASK GENMASK(31, 16) +#define NEO_COLOR_TEMP_ROI_SIZE_CAM0_HEIGHT_SET(x) (((x) & GENMASK(15, 0))= << 16) +#define NEO_COLOR_TEMP_ROI_SIZE_CAM0_HEIGHT_GET(x) (((x) >> 16) & GENMASK= (15, 0)) + +#define NEO_COLOR_TEMP_REDGAIN_CAM0 0x40c +#define NEO_COLOR_TEMP_REDGAIN_CAM0_MIN_MASK GENMASK(7, 0) +#define NEO_COLOR_TEMP_REDGAIN_CAM0_MIN_SET(x) (((x) & GENMASK(7, 0)) << 0) +#define NEO_COLOR_TEMP_REDGAIN_CAM0_MIN_GET(x) (((x) >> 0) & GENMASK(7, 0= )) +#define NEO_COLOR_TEMP_REDGAIN_CAM0_MAX_MASK GENMASK(23, 16) +#define NEO_COLOR_TEMP_REDGAIN_CAM0_MAX_SET(x) (((x) & GENMASK(7, 0)) << 1= 6) +#define NEO_COLOR_TEMP_REDGAIN_CAM0_MAX_GET(x) (((x) >> 16) & GENMASK(7, = 0)) + +#define NEO_COLOR_TEMP_BLUEGAIN_CAM0 0x410 +#define NEO_COLOR_TEMP_BLUEGAIN_CAM0_MIN_MASK GENMASK(7, 0) +#define NEO_COLOR_TEMP_BLUEGAIN_CAM0_MIN_SET(x) (((x) & GENMASK(7, 0)) << = 0) +#define NEO_COLOR_TEMP_BLUEGAIN_CAM0_MIN_GET(x) (((x) >> 0) & GENMASK(7, = 0)) +#define NEO_COLOR_TEMP_BLUEGAIN_CAM0_MAX_MASK GENMASK(23, 16) +#define NEO_COLOR_TEMP_BLUEGAIN_CAM0_MAX_SET(x) (((x) & GENMASK(7, 0)) << = 16) +#define NEO_COLOR_TEMP_BLUEGAIN_CAM0_MAX_GET(x) (((x) >> 16) & GENMASK(7,= 0)) + +#define NEO_COLOR_TEMP_POINT1_CAM0 0x414 +#define NEO_COLOR_TEMP_POINT1_CAM0_BLUE_MASK GENMASK(7, 0) +#define NEO_COLOR_TEMP_POINT1_CAM0_BLUE_SET(x) (((x) & GENMASK(7, 0)) << 0) +#define NEO_COLOR_TEMP_POINT1_CAM0_BLUE_GET(x) (((x) >> 0) & GENMASK(7, 0= )) +#define NEO_COLOR_TEMP_POINT1_CAM0_RED_MASK GENMASK(23, 16) +#define NEO_COLOR_TEMP_POINT1_CAM0_RED_SET(x) (((x) & GENMASK(7, 0)) << 16) +#define NEO_COLOR_TEMP_POINT1_CAM0_RED_GET(x) (((x) >> 16) & GENMASK(7, 0= )) + +#define NEO_COLOR_TEMP_POINT2_CAM0 0x418 +#define NEO_COLOR_TEMP_POINT2_CAM0_BLUE_MASK GENMASK(7, 0) +#define NEO_COLOR_TEMP_POINT2_CAM0_BLUE_SET(x) (((x) & GENMASK(7, 0)) << 0) +#define NEO_COLOR_TEMP_POINT2_CAM0_BLUE_GET(x) (((x) >> 0) & GENMASK(7, 0= )) +#define NEO_COLOR_TEMP_POINT2_CAM0_RED_MASK GENMASK(23, 16) +#define NEO_COLOR_TEMP_POINT2_CAM0_RED_SET(x) (((x) & GENMASK(7, 0)) << 16) +#define NEO_COLOR_TEMP_POINT2_CAM0_RED_GET(x) (((x) >> 16) & GENMASK(7, 0= )) + +#define NEO_COLOR_TEMP_HOFFSET_CAM0 0x41c +#define NEO_COLOR_TEMP_HOFFSET_CAM0_RIGHT_MASK GENMASK(7, 0) +#define NEO_COLOR_TEMP_HOFFSET_CAM0_RIGHT_SET(x) (((x) & GENMASK(7, 0)) <<= 0) +#define NEO_COLOR_TEMP_HOFFSET_CAM0_RIGHT_GET(x) (((x) >> 0) & GENMASK(7,= 0)) +#define NEO_COLOR_TEMP_HOFFSET_CAM0_LEFT_MASK GENMASK(23, 16) +#define NEO_COLOR_TEMP_HOFFSET_CAM0_LEFT_SET(x) (((x) & GENMASK(7, 0)) << = 16) +#define NEO_COLOR_TEMP_HOFFSET_CAM0_LEFT_GET(x) (((x) >> 16) & GENMASK(7,= 0)) + +#define NEO_COLOR_TEMP_VOFFSET_CAM0 0x420 +#define NEO_COLOR_TEMP_VOFFSET_CAM0_UP_MASK GENMASK(7, 0) +#define NEO_COLOR_TEMP_VOFFSET_CAM0_UP_SET(x) (((x) & GENMASK(7, 0)) << 0) +#define NEO_COLOR_TEMP_VOFFSET_CAM0_UP_GET(x) (((x) >> 0) & GENMASK(7, 0)) +#define NEO_COLOR_TEMP_VOFFSET_CAM0_DOWN_MASK GENMASK(23, 16) +#define NEO_COLOR_TEMP_VOFFSET_CAM0_DOWN_SET(x) (((x) & GENMASK(7, 0)) << = 16) +#define NEO_COLOR_TEMP_VOFFSET_CAM0_DOWN_GET(x) (((x) >> 16) & GENMASK(7,= 0)) + +#define NEO_COLOR_TEMP_POINT1_SLOPE_CAM0 0x424 +#define NEO_COLOR_TEMP_POINT1_SLOPE_CAM0_SLOPE_L_MASK GENMASK(15, 0) +#define NEO_COLOR_TEMP_POINT1_SLOPE_CAM0_SLOPE_L_SET(x) (((x) & GENMASK(15= , 0)) << 0) +#define NEO_COLOR_TEMP_POINT1_SLOPE_CAM0_SLOPE_L_GET(x) (((x) >> 0) & GEN= MASK(15, 0)) +#define NEO_COLOR_TEMP_POINT1_SLOPE_CAM0_SLOPE_R_MASK GENMASK(31, 16) +#define NEO_COLOR_TEMP_POINT1_SLOPE_CAM0_SLOPE_R_SET(x) (((x) & GENMASK(15= , 0)) << 16) +#define NEO_COLOR_TEMP_POINT1_SLOPE_CAM0_SLOPE_R_GET(x) (((x) >> 16) & GE= NMASK(15, 0)) + +#define NEO_COLOR_TEMP_POINT2_SLOPE_CAM0 0x428 +#define NEO_COLOR_TEMP_POINT2_SLOPE_CAM0_SLOPE_L_MASK GENMASK(15, 0) +#define NEO_COLOR_TEMP_POINT2_SLOPE_CAM0_SLOPE_L_SET(x) (((x) & GENMASK(15= , 0)) << 0) +#define NEO_COLOR_TEMP_POINT2_SLOPE_CAM0_SLOPE_L_GET(x) (((x) >> 0) & GEN= MASK(15, 0)) +#define NEO_COLOR_TEMP_POINT2_SLOPE_CAM0_SLOPE_R_MASK GENMASK(31, 16) +#define NEO_COLOR_TEMP_POINT2_SLOPE_CAM0_SLOPE_R_SET(x) (((x) & GENMASK(15= , 0)) << 16) +#define NEO_COLOR_TEMP_POINT2_SLOPE_CAM0_SLOPE_R_GET(x) (((x) >> 16) & GE= NMASK(15, 0)) + +#define NEO_COLOR_TEMP_LUMA_TH_CAM0 0x42c +#define NEO_COLOR_TEMP_LUMA_TH_CAM0_THL_MASK GENMASK(15, 0) +#define NEO_COLOR_TEMP_LUMA_TH_CAM0_THL_SET(x) (((x) & GENMASK(15, 0)) << = 0) +#define NEO_COLOR_TEMP_LUMA_TH_CAM0_THL_GET(x) (((x) >> 0) & GENMASK(15, = 0)) +#define NEO_COLOR_TEMP_LUMA_TH_CAM0_THH_MASK GENMASK(31, 16) +#define NEO_COLOR_TEMP_LUMA_TH_CAM0_THH_SET(x) (((x) & GENMASK(15, 0)) << = 16) +#define NEO_COLOR_TEMP_LUMA_TH_CAM0_THH_GET(x) (((x) >> 16) & GENMASK(15,= 0)) + +#define NEO_COLOR_TEMP_CSC_MAT0_CAM0 0x430 +#define NEO_COLOR_TEMP_CSC_MAT0_CAM0_R0C0_MASK GENMASK(15, 0) +#define NEO_COLOR_TEMP_CSC_MAT0_CAM0_R0C0_SET(x) (((x) & GENMASK(15, 0)) <= < 0) +#define NEO_COLOR_TEMP_CSC_MAT0_CAM0_R0C0_GET(x) (((x) >> 0) & GENMASK(15= , 0)) +#define NEO_COLOR_TEMP_CSC_MAT0_CAM0_R0C1_MASK GENMASK(31, 16) +#define NEO_COLOR_TEMP_CSC_MAT0_CAM0_R0C1_SET(x) (((x) & GENMASK(15, 0)) <= < 16) +#define NEO_COLOR_TEMP_CSC_MAT0_CAM0_R0C1_GET(x) (((x) >> 16) & GENMASK(1= 5, 0)) + +#define NEO_COLOR_TEMP_CSC_MAT1_CAM0 0x434 +#define NEO_COLOR_TEMP_CSC_MAT1_CAM0_R0C2_MASK GENMASK(15, 0) +#define NEO_COLOR_TEMP_CSC_MAT1_CAM0_R0C2_SET(x) (((x) & GENMASK(15, 0)) <= < 0) +#define NEO_COLOR_TEMP_CSC_MAT1_CAM0_R0C2_GET(x) (((x) >> 0) & GENMASK(15= , 0)) +#define NEO_COLOR_TEMP_CSC_MAT1_CAM0_R1C0_MASK GENMASK(31, 16) +#define NEO_COLOR_TEMP_CSC_MAT1_CAM0_R1C0_SET(x) (((x) & GENMASK(15, 0)) <= < 16) +#define NEO_COLOR_TEMP_CSC_MAT1_CAM0_R1C0_GET(x) (((x) >> 16) & GENMASK(1= 5, 0)) + +#define NEO_COLOR_TEMP_CSC_MAT2_CAM0 0x438 +#define NEO_COLOR_TEMP_CSC_MAT2_CAM0_R1C1_MASK GENMASK(15, 0) +#define NEO_COLOR_TEMP_CSC_MAT2_CAM0_R1C1_SET(x) (((x) & GENMASK(15, 0)) <= < 0) +#define NEO_COLOR_TEMP_CSC_MAT2_CAM0_R1C1_GET(x) (((x) >> 0) & GENMASK(15= , 0)) +#define NEO_COLOR_TEMP_CSC_MAT2_CAM0_R1C2_MASK GENMASK(31, 16) +#define NEO_COLOR_TEMP_CSC_MAT2_CAM0_R1C2_SET(x) (((x) & GENMASK(15, 0)) <= < 16) +#define NEO_COLOR_TEMP_CSC_MAT2_CAM0_R1C2_GET(x) (((x) >> 16) & GENMASK(1= 5, 0)) + +#define NEO_COLOR_TEMP_CSC_MAT3_CAM0 0x43c +#define NEO_COLOR_TEMP_CSC_MAT3_CAM0_R2C0_MASK GENMASK(15, 0) +#define NEO_COLOR_TEMP_CSC_MAT3_CAM0_R2C0_SET(x) (((x) & GENMASK(15, 0)) <= < 0) +#define NEO_COLOR_TEMP_CSC_MAT3_CAM0_R2C0_GET(x) (((x) >> 0) & GENMASK(15= , 0)) +#define NEO_COLOR_TEMP_CSC_MAT3_CAM0_R2C1_MASK GENMASK(31, 16) +#define NEO_COLOR_TEMP_CSC_MAT3_CAM0_R2C1_SET(x) (((x) & GENMASK(15, 0)) <= < 16) +#define NEO_COLOR_TEMP_CSC_MAT3_CAM0_R2C1_GET(x) (((x) >> 16) & GENMASK(1= 5, 0)) + +#define NEO_COLOR_TEMP_CSC_MAT4_CAM0 0x440 +#define NEO_COLOR_TEMP_CSC_MAT4_CAM0_R2C2_MASK GENMASK(15, 0) +#define NEO_COLOR_TEMP_CSC_MAT4_CAM0_R2C2_SET(x) (((x) & GENMASK(15, 0)) <= < 0) +#define NEO_COLOR_TEMP_CSC_MAT4_CAM0_R2C2_GET(x) (((x) >> 0) & GENMASK(15= , 0)) + +#define NEO_COLOR_TEMP_R_GR_OFFSET_CAM0 0x444 +#define NEO_COLOR_TEMP_R_GR_OFFSET_CAM0_OFFSET0_MASK GENMASK(15, 0) +#define NEO_COLOR_TEMP_R_GR_OFFSET_CAM0_OFFSET0_SET(x) (((x) & GENMASK(15,= 0)) << 0) +#define NEO_COLOR_TEMP_R_GR_OFFSET_CAM0_OFFSET0_GET(x) (((x) >> 0) & GENM= ASK(15, 0)) +#define NEO_COLOR_TEMP_R_GR_OFFSET_CAM0_OFFSET1_MASK GENMASK(31, 16) +#define NEO_COLOR_TEMP_R_GR_OFFSET_CAM0_OFFSET1_SET(x) (((x) & GENMASK(15,= 0)) << 16) +#define NEO_COLOR_TEMP_R_GR_OFFSET_CAM0_OFFSET1_GET(x) (((x) >> 16) & GEN= MASK(15, 0)) + +#define NEO_COLOR_TEMP_GB_B_OFFSET_CAM0 0x448 +#define NEO_COLOR_TEMP_GB_B_OFFSET_CAM0_OFFSET0_MASK GENMASK(15, 0) +#define NEO_COLOR_TEMP_GB_B_OFFSET_CAM0_OFFSET0_SET(x) (((x) & GENMASK(15,= 0)) << 0) +#define NEO_COLOR_TEMP_GB_B_OFFSET_CAM0_OFFSET0_GET(x) (((x) >> 0) & GENM= ASK(15, 0)) +#define NEO_COLOR_TEMP_GB_B_OFFSET_CAM0_OFFSET1_MASK GENMASK(31, 16) +#define NEO_COLOR_TEMP_GB_B_OFFSET_CAM0_OFFSET1_SET(x) (((x) & GENMASK(15,= 0)) << 16) +#define NEO_COLOR_TEMP_GB_B_OFFSET_CAM0_OFFSET1_GET(x) (((x) >> 16) & GEN= MASK(15, 0)) + +#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_MASK GENMASK(15, 0) +#define NEO_COLOR_TEMP_STAT_BLK_SIZE0_XSIZE_SET(x) (((x) & GENMASK(15, 0))= << 0) +#define NEO_COLOR_TEMP_STAT_BLK_SIZE0_XSIZE_GET(x) (((x) >> 0) & GENMASK(= 15, 0)) +#define NEO_COLOR_TEMP_STAT_BLK_SIZE0_YSIZE_MASK GENMASK(31, 16) +#define NEO_COLOR_TEMP_STAT_BLK_SIZE0_YSIZE_SET(x) (((x) & GENMASK(15, 0))= << 16) +#define NEO_COLOR_TEMP_STAT_BLK_SIZE0_YSIZE_GET(x) (((x) >> 16) & GENMASK= (15, 0)) + +#define NEO_COLOR_TEMP_STAT_CURR_BLK_Y0 0x488 +#define NEO_COLOR_TEMP_STAT_CURR_BLK_Y0_BLKLNE_MASK GENMASK(15, 0) +#define NEO_COLOR_TEMP_STAT_CURR_BLK_Y0_BLKLNE_GET(x) (((x) >> 0) & GENMA= SK(15, 0)) +#define NEO_COLOR_TEMP_STAT_CURR_BLK_Y0_BLKROW_MASK GENMASK(18, 16) +#define NEO_COLOR_TEMP_STAT_CURR_BLK_Y0_BLKROW_GET(x) (((x) >> 16) & GENM= ASK(2, 0)) + +#define NEO_COLOR_TEMP_CROI0_POS_CAM0 0x490 +#define NEO_COLOR_TEMP_CROI0_POS_CAM0_ROVERG_LOW_MASK GENMASK(7, 0) +#define NEO_COLOR_TEMP_CROI0_POS_CAM0_ROVERG_LOW_SET(x) (((x) & GENMASK(7,= 0)) << 0) +#define NEO_COLOR_TEMP_CROI0_POS_CAM0_ROVERG_LOW_GET(x) (((x) >> 0) & GEN= MASK(7, 0)) +#define NEO_COLOR_TEMP_CROI0_POS_CAM0_ROVERG_HIGH_MASK GENMASK(15, 8) +#define NEO_COLOR_TEMP_CROI0_POS_CAM0_ROVERG_HIGH_SET(x) (((x) & GENMASK(7= , 0)) << 8) +#define NEO_COLOR_TEMP_CROI0_POS_CAM0_ROVERG_HIGH_GET(x) (((x) >> 8) & GE= NMASK(7, 0)) +#define NEO_COLOR_TEMP_CROI0_POS_CAM0_BOVERG_LOW_MASK GENMASK(23, 16) +#define NEO_COLOR_TEMP_CROI0_POS_CAM0_BOVERG_LOW_SET(x) (((x) & GENMASK(7,= 0)) << 16) +#define NEO_COLOR_TEMP_CROI0_POS_CAM0_BOVERG_LOW_GET(x) (((x) >> 16) & GE= NMASK(7, 0)) +#define NEO_COLOR_TEMP_CROI0_POS_CAM0_BOVERG_HIGH_MASK GENMASK(31, 24) +#define NEO_COLOR_TEMP_CROI0_POS_CAM0_BOVERG_HIGH_SET(x) (((x) & GENMASK(7= , 0)) << 24) +#define NEO_COLOR_TEMP_CROI0_POS_CAM0_BOVERG_HIGH_GET(x) (((x) >> 24) & G= ENMASK(7, 0)) + +#define NEO_COLOR_TEMP_CROI0_PIXCNT_CAM0 0x498 +#define NEO_COLOR_TEMP_CROI0_PIXCNT_CAM0_PIXCNT_MASK GENMASK(23, 0) +#define NEO_COLOR_TEMP_CROI0_PIXCNT_CAM0_PIXCNT_SET(x) (((x) & GENMASK(23,= 0)) << 0) +#define NEO_COLOR_TEMP_CROI0_PIXCNT_CAM0_PIXCNT_GET(x) (((x) >> 0) & GENM= ASK(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_MASK GENMASK(7, 0) +#define NEO_COLOR_TEMP_CROI1_POS_CAM0_ROVERG_LOW_SET(x) (((x) & GENMASK(7,= 0)) << 0) +#define NEO_COLOR_TEMP_CROI1_POS_CAM0_ROVERG_LOW_GET(x) (((x) >> 0) & GEN= MASK(7, 0)) +#define NEO_COLOR_TEMP_CROI1_POS_CAM0_ROVERG_HIGH_MASK GENMASK(15, 8) +#define NEO_COLOR_TEMP_CROI1_POS_CAM0_ROVERG_HIGH_SET(x) (((x) & GENMASK(7= , 0)) << 8) +#define NEO_COLOR_TEMP_CROI1_POS_CAM0_ROVERG_HIGH_GET(x) (((x) >> 8) & GE= NMASK(7, 0)) +#define NEO_COLOR_TEMP_CROI1_POS_CAM0_BOVERG_LOW_MASK GENMASK(23, 16) +#define NEO_COLOR_TEMP_CROI1_POS_CAM0_BOVERG_LOW_SET(x) (((x) & GENMASK(7,= 0)) << 16) +#define NEO_COLOR_TEMP_CROI1_POS_CAM0_BOVERG_LOW_GET(x) (((x) >> 16) & GE= NMASK(7, 0)) +#define NEO_COLOR_TEMP_CROI1_POS_CAM0_BOVERG_HIGH_MASK GENMASK(31, 24) +#define NEO_COLOR_TEMP_CROI1_POS_CAM0_BOVERG_HIGH_SET(x) (((x) & GENMASK(7= , 0)) << 24) +#define NEO_COLOR_TEMP_CROI1_POS_CAM0_BOVERG_HIGH_GET(x) (((x) >> 24) & G= ENMASK(7, 0)) + +#define NEO_COLOR_TEMP_CROI1_PIXCNT_CAM0 0x4b0 +#define NEO_COLOR_TEMP_CROI1_PIXCNT_CAM0_PIXCNT_MASK GENMASK(23, 0) +#define NEO_COLOR_TEMP_CROI1_PIXCNT_CAM0_PIXCNT_SET(x) (((x) & GENMASK(23,= 0)) << 0) +#define NEO_COLOR_TEMP_CROI1_PIXCNT_CAM0_PIXCNT_GET(x) (((x) >> 0) & GENM= ASK(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_MASK GENMASK(7, 0) +#define NEO_COLOR_TEMP_CROI2_POS_CAM0_ROVERG_LOW_SET(x) (((x) & GENMASK(7,= 0)) << 0) +#define NEO_COLOR_TEMP_CROI2_POS_CAM0_ROVERG_LOW_GET(x) (((x) >> 0) & GEN= MASK(7, 0)) +#define NEO_COLOR_TEMP_CROI2_POS_CAM0_ROVERG_HIGH_MASK GENMASK(15, 8) +#define NEO_COLOR_TEMP_CROI2_POS_CAM0_ROVERG_HIGH_SET(x) (((x) & GENMASK(7= , 0)) << 8) +#define NEO_COLOR_TEMP_CROI2_POS_CAM0_ROVERG_HIGH_GET(x) (((x) >> 8) & GE= NMASK(7, 0)) +#define NEO_COLOR_TEMP_CROI2_POS_CAM0_BOVERG_LOW_MASK GENMASK(23, 16) +#define NEO_COLOR_TEMP_CROI2_POS_CAM0_BOVERG_LOW_SET(x) (((x) & GENMASK(7,= 0)) << 16) +#define NEO_COLOR_TEMP_CROI2_POS_CAM0_BOVERG_LOW_GET(x) (((x) >> 16) & GE= NMASK(7, 0)) +#define NEO_COLOR_TEMP_CROI2_POS_CAM0_BOVERG_HIGH_MASK GENMASK(31, 24) +#define NEO_COLOR_TEMP_CROI2_POS_CAM0_BOVERG_HIGH_SET(x) (((x) & GENMASK(7= , 0)) << 24) +#define NEO_COLOR_TEMP_CROI2_POS_CAM0_BOVERG_HIGH_GET(x) (((x) >> 24) & G= ENMASK(7, 0)) + +#define NEO_COLOR_TEMP_CROI2_PIXCNT_CAM0 0x4c8 +#define NEO_COLOR_TEMP_CROI2_PIXCNT_CAM0_PIXCNT_MASK GENMASK(23, 0) +#define NEO_COLOR_TEMP_CROI2_PIXCNT_CAM0_PIXCNT_SET(x) (((x) & GENMASK(23,= 0)) << 0) +#define NEO_COLOR_TEMP_CROI2_PIXCNT_CAM0_PIXCNT_GET(x) (((x) >> 0) & GENM= ASK(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_MASK GENMASK(7, 0) +#define NEO_COLOR_TEMP_CROI3_POS_CAM0_ROVERG_LOW_SET(x) (((x) & GENMASK(7,= 0)) << 0) +#define NEO_COLOR_TEMP_CROI3_POS_CAM0_ROVERG_LOW_GET(x) (((x) >> 0) & GEN= MASK(7, 0)) +#define NEO_COLOR_TEMP_CROI3_POS_CAM0_ROVERG_HIGH_MASK GENMASK(15, 8) +#define NEO_COLOR_TEMP_CROI3_POS_CAM0_ROVERG_HIGH_SET(x) (((x) & GENMASK(7= , 0)) << 8) +#define NEO_COLOR_TEMP_CROI3_POS_CAM0_ROVERG_HIGH_GET(x) (((x) >> 8) & GE= NMASK(7, 0)) +#define NEO_COLOR_TEMP_CROI3_POS_CAM0_BOVERG_LOW_MASK GENMASK(23, 16) +#define NEO_COLOR_TEMP_CROI3_POS_CAM0_BOVERG_LOW_SET(x) (((x) & GENMASK(7,= 0)) << 16) +#define NEO_COLOR_TEMP_CROI3_POS_CAM0_BOVERG_LOW_GET(x) (((x) >> 16) & GE= NMASK(7, 0)) +#define NEO_COLOR_TEMP_CROI3_POS_CAM0_BOVERG_HIGH_MASK GENMASK(31, 24) +#define NEO_COLOR_TEMP_CROI3_POS_CAM0_BOVERG_HIGH_SET(x) (((x) & GENMASK(7= , 0)) << 24) +#define NEO_COLOR_TEMP_CROI3_POS_CAM0_BOVERG_HIGH_GET(x) (((x) >> 24) & G= ENMASK(7, 0)) + +#define NEO_COLOR_TEMP_CROI3_PIXCNT_CAM0 0x4e0 +#define NEO_COLOR_TEMP_CROI3_PIXCNT_CAM0_PIXCNT_MASK GENMASK(23, 0) +#define NEO_COLOR_TEMP_CROI3_PIXCNT_CAM0_PIXCNT_SET(x) (((x) & GENMASK(23,= 0)) << 0) +#define NEO_COLOR_TEMP_CROI3_PIXCNT_CAM0_PIXCNT_GET(x) (((x) >> 0) & GENM= ASK(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_MASK GENMASK(7, 0) +#define NEO_COLOR_TEMP_CROI4_POS_CAM0_ROVERG_LOW_SET(x) (((x) & GENMASK(7,= 0)) << 0) +#define NEO_COLOR_TEMP_CROI4_POS_CAM0_ROVERG_LOW_GET(x) (((x) >> 0) & GEN= MASK(7, 0)) +#define NEO_COLOR_TEMP_CROI4_POS_CAM0_ROVERG_HIGH_MASK GENMASK(15, 8) +#define NEO_COLOR_TEMP_CROI4_POS_CAM0_ROVERG_HIGH_SET(x) (((x) & GENMASK(7= , 0)) << 8) +#define NEO_COLOR_TEMP_CROI4_POS_CAM0_ROVERG_HIGH_GET(x) (((x) >> 8) & GE= NMASK(7, 0)) +#define NEO_COLOR_TEMP_CROI4_POS_CAM0_BOVERG_LOW_MASK GENMASK(23, 16) +#define NEO_COLOR_TEMP_CROI4_POS_CAM0_BOVERG_LOW_SET(x) (((x) & GENMASK(7,= 0)) << 16) +#define NEO_COLOR_TEMP_CROI4_POS_CAM0_BOVERG_LOW_GET(x) (((x) >> 16) & GE= NMASK(7, 0)) +#define NEO_COLOR_TEMP_CROI4_POS_CAM0_BOVERG_HIGH_MASK GENMASK(31, 24) +#define NEO_COLOR_TEMP_CROI4_POS_CAM0_BOVERG_HIGH_SET(x) (((x) & GENMASK(7= , 0)) << 24) +#define NEO_COLOR_TEMP_CROI4_POS_CAM0_BOVERG_HIGH_GET(x) (((x) >> 24) & G= ENMASK(7, 0)) + +#define NEO_COLOR_TEMP_CROI4_PIXCNT_CAM0 0x4f8 +#define NEO_COLOR_TEMP_CROI4_PIXCNT_CAM0_PIXCNT_MASK GENMASK(23, 0) +#define NEO_COLOR_TEMP_CROI4_PIXCNT_CAM0_PIXCNT_SET(x) (((x) & GENMASK(23,= 0)) << 0) +#define NEO_COLOR_TEMP_CROI4_PIXCNT_CAM0_PIXCNT_GET(x) (((x) >> 0) & GENM= ASK(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_MASK GENMASK(7, 0) +#define NEO_COLOR_TEMP_CROI5_POS_CAM0_ROVERG_LOW_SET(x) (((x) & GENMASK(7,= 0)) << 0) +#define NEO_COLOR_TEMP_CROI5_POS_CAM0_ROVERG_LOW_GET(x) (((x) >> 0) & GEN= MASK(7, 0)) +#define NEO_COLOR_TEMP_CROI5_POS_CAM0_ROVERG_HIGH_MASK GENMASK(15, 8) +#define NEO_COLOR_TEMP_CROI5_POS_CAM0_ROVERG_HIGH_SET(x) (((x) & GENMASK(7= , 0)) << 8) +#define NEO_COLOR_TEMP_CROI5_POS_CAM0_ROVERG_HIGH_GET(x) (((x) >> 8) & GE= NMASK(7, 0)) +#define NEO_COLOR_TEMP_CROI5_POS_CAM0_BOVERG_LOW_MASK GENMASK(23, 16) +#define NEO_COLOR_TEMP_CROI5_POS_CAM0_BOVERG_LOW_SET(x) (((x) & GENMASK(7,= 0)) << 16) +#define NEO_COLOR_TEMP_CROI5_POS_CAM0_BOVERG_LOW_GET(x) (((x) >> 16) & GE= NMASK(7, 0)) +#define NEO_COLOR_TEMP_CROI5_POS_CAM0_BOVERG_HIGH_MASK GENMASK(31, 24) +#define NEO_COLOR_TEMP_CROI5_POS_CAM0_BOVERG_HIGH_SET(x) (((x) & GENMASK(7= , 0)) << 24) +#define NEO_COLOR_TEMP_CROI5_POS_CAM0_BOVERG_HIGH_GET(x) (((x) >> 24) & G= ENMASK(7, 0)) + +#define NEO_COLOR_TEMP_CROI5_PIXCNT_CAM0 0x510 +#define NEO_COLOR_TEMP_CROI5_PIXCNT_CAM0_PIXCNT_MASK GENMASK(23, 0) +#define NEO_COLOR_TEMP_CROI5_PIXCNT_CAM0_PIXCNT_SET(x) (((x) & GENMASK(23,= 0)) << 0) +#define NEO_COLOR_TEMP_CROI5_PIXCNT_CAM0_PIXCNT_GET(x) (((x) >> 0) & GENM= ASK(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_MASK GENMASK(7, 0) +#define NEO_COLOR_TEMP_CROI6_POS_CAM0_ROVERG_LOW_SET(x) (((x) & GENMASK(7,= 0)) << 0) +#define NEO_COLOR_TEMP_CROI6_POS_CAM0_ROVERG_LOW_GET(x) (((x) >> 0) & GEN= MASK(7, 0)) +#define NEO_COLOR_TEMP_CROI6_POS_CAM0_ROVERG_HIGH_MASK GENMASK(15, 8) +#define NEO_COLOR_TEMP_CROI6_POS_CAM0_ROVERG_HIGH_SET(x) (((x) & GENMASK(7= , 0)) << 8) +#define NEO_COLOR_TEMP_CROI6_POS_CAM0_ROVERG_HIGH_GET(x) (((x) >> 8) & GE= NMASK(7, 0)) +#define NEO_COLOR_TEMP_CROI6_POS_CAM0_BOVERG_LOW_MASK GENMASK(23, 16) +#define NEO_COLOR_TEMP_CROI6_POS_CAM0_BOVERG_LOW_SET(x) (((x) & GENMASK(7,= 0)) << 16) +#define NEO_COLOR_TEMP_CROI6_POS_CAM0_BOVERG_LOW_GET(x) (((x) >> 16) & GE= NMASK(7, 0)) +#define NEO_COLOR_TEMP_CROI6_POS_CAM0_BOVERG_HIGH_MASK GENMASK(31, 24) +#define NEO_COLOR_TEMP_CROI6_POS_CAM0_BOVERG_HIGH_SET(x) (((x) & GENMASK(7= , 0)) << 24) +#define NEO_COLOR_TEMP_CROI6_POS_CAM0_BOVERG_HIGH_GET(x) (((x) >> 24) & G= ENMASK(7, 0)) + +#define NEO_COLOR_TEMP_CROI6_PIXCNT_CAM0 0x528 +#define NEO_COLOR_TEMP_CROI6_PIXCNT_CAM0_PIXCNT_MASK GENMASK(23, 0) +#define NEO_COLOR_TEMP_CROI6_PIXCNT_CAM0_PIXCNT_SET(x) (((x) & GENMASK(23,= 0)) << 0) +#define NEO_COLOR_TEMP_CROI6_PIXCNT_CAM0_PIXCNT_GET(x) (((x) >> 0) & GENM= ASK(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_MASK GENMASK(7, 0) +#define NEO_COLOR_TEMP_CROI7_POS_CAM0_ROVERG_LOW_SET(x) (((x) & GENMASK(7,= 0)) << 0) +#define NEO_COLOR_TEMP_CROI7_POS_CAM0_ROVERG_LOW_GET(x) (((x) >> 0) & GEN= MASK(7, 0)) +#define NEO_COLOR_TEMP_CROI7_POS_CAM0_ROVERG_HIGH_MASK GENMASK(15, 8) +#define NEO_COLOR_TEMP_CROI7_POS_CAM0_ROVERG_HIGH_SET(x) (((x) & GENMASK(7= , 0)) << 8) +#define NEO_COLOR_TEMP_CROI7_POS_CAM0_ROVERG_HIGH_GET(x) (((x) >> 8) & GE= NMASK(7, 0)) +#define NEO_COLOR_TEMP_CROI7_POS_CAM0_BOVERG_LOW_MASK GENMASK(23, 16) +#define NEO_COLOR_TEMP_CROI7_POS_CAM0_BOVERG_LOW_SET(x) (((x) & GENMASK(7,= 0)) << 16) +#define NEO_COLOR_TEMP_CROI7_POS_CAM0_BOVERG_LOW_GET(x) (((x) >> 16) & GE= NMASK(7, 0)) +#define NEO_COLOR_TEMP_CROI7_POS_CAM0_BOVERG_HIGH_MASK GENMASK(31, 24) +#define NEO_COLOR_TEMP_CROI7_POS_CAM0_BOVERG_HIGH_SET(x) (((x) & GENMASK(7= , 0)) << 24) +#define NEO_COLOR_TEMP_CROI7_POS_CAM0_BOVERG_HIGH_GET(x) (((x) >> 24) & G= ENMASK(7, 0)) + +#define NEO_COLOR_TEMP_CROI7_PIXCNT_CAM0 0x540 +#define NEO_COLOR_TEMP_CROI7_PIXCNT_CAM0_PIXCNT_MASK GENMASK(23, 0) +#define NEO_COLOR_TEMP_CROI7_PIXCNT_CAM0_PIXCNT_SET(x) (((x) & GENMASK(23,= 0)) << 0) +#define NEO_COLOR_TEMP_CROI7_PIXCNT_CAM0_PIXCNT_GET(x) (((x) >> 0) & GENM= ASK(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_MASK GENMASK(7, 0) +#define NEO_COLOR_TEMP_CROI8_POS_CAM0_ROVERG_LOW_SET(x) (((x) & GENMASK(7,= 0)) << 0) +#define NEO_COLOR_TEMP_CROI8_POS_CAM0_ROVERG_LOW_GET(x) (((x) >> 0) & GEN= MASK(7, 0)) +#define NEO_COLOR_TEMP_CROI8_POS_CAM0_ROVERG_HIGH_MASK GENMASK(15, 8) +#define NEO_COLOR_TEMP_CROI8_POS_CAM0_ROVERG_HIGH_SET(x) (((x) & GENMASK(7= , 0)) << 8) +#define NEO_COLOR_TEMP_CROI8_POS_CAM0_ROVERG_HIGH_GET(x) (((x) >> 8) & GE= NMASK(7, 0)) +#define NEO_COLOR_TEMP_CROI8_POS_CAM0_BOVERG_LOW_MASK GENMASK(23, 16) +#define NEO_COLOR_TEMP_CROI8_POS_CAM0_BOVERG_LOW_SET(x) (((x) & GENMASK(7,= 0)) << 16) +#define NEO_COLOR_TEMP_CROI8_POS_CAM0_BOVERG_LOW_GET(x) (((x) >> 16) & GE= NMASK(7, 0)) +#define NEO_COLOR_TEMP_CROI8_POS_CAM0_BOVERG_HIGH_MASK GENMASK(31, 24) +#define NEO_COLOR_TEMP_CROI8_POS_CAM0_BOVERG_HIGH_SET(x) (((x) & GENMASK(7= , 0)) << 24) +#define NEO_COLOR_TEMP_CROI8_POS_CAM0_BOVERG_HIGH_GET(x) (((x) >> 24) & G= ENMASK(7, 0)) + +#define NEO_COLOR_TEMP_CROI8_PIXCNT_CAM0 0x558 +#define NEO_COLOR_TEMP_CROI8_PIXCNT_CAM0_PIXCNT_MASK GENMASK(23, 0) +#define NEO_COLOR_TEMP_CROI8_PIXCNT_CAM0_PIXCNT_SET(x) (((x) & GENMASK(23,= 0)) << 0) +#define NEO_COLOR_TEMP_CROI8_PIXCNT_CAM0_PIXCNT_GET(x) (((x) >> 0) & GENM= ASK(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_MASK GENMASK(7, 0) +#define NEO_COLOR_TEMP_CROI9_POS_CAM0_ROVERG_LOW_SET(x) (((x) & GENMASK(7,= 0)) << 0) +#define NEO_COLOR_TEMP_CROI9_POS_CAM0_ROVERG_LOW_GET(x) (((x) >> 0) & GEN= MASK(7, 0)) +#define NEO_COLOR_TEMP_CROI9_POS_CAM0_ROVERG_HIGH_MASK GENMASK(15, 8) +#define NEO_COLOR_TEMP_CROI9_POS_CAM0_ROVERG_HIGH_SET(x) (((x) & GENMASK(7= , 0)) << 8) +#define NEO_COLOR_TEMP_CROI9_POS_CAM0_ROVERG_HIGH_GET(x) (((x) >> 8) & GE= NMASK(7, 0)) +#define NEO_COLOR_TEMP_CROI9_POS_CAM0_BOVERG_LOW_MASK GENMASK(23, 16) +#define NEO_COLOR_TEMP_CROI9_POS_CAM0_BOVERG_LOW_SET(x) (((x) & GENMASK(7,= 0)) << 16) +#define NEO_COLOR_TEMP_CROI9_POS_CAM0_BOVERG_LOW_GET(x) (((x) >> 16) & GE= NMASK(7, 0)) +#define NEO_COLOR_TEMP_CROI9_POS_CAM0_BOVERG_HIGH_MASK GENMASK(31, 24) +#define NEO_COLOR_TEMP_CROI9_POS_CAM0_BOVERG_HIGH_SET(x) (((x) & GENMASK(7= , 0)) << 24) +#define NEO_COLOR_TEMP_CROI9_POS_CAM0_BOVERG_HIGH_GET(x) (((x) >> 24) & G= ENMASK(7, 0)) + +#define NEO_COLOR_TEMP_CROI9_PIXCNT_CAM0 0x570 +#define NEO_COLOR_TEMP_CROI9_PIXCNT_CAM0_PIXCNT_MASK GENMASK(23, 0) +#define NEO_COLOR_TEMP_CROI9_PIXCNT_CAM0_PIXCNT_SET(x) (((x) & GENMASK(23,= 0)) << 0) +#define NEO_COLOR_TEMP_CROI9_PIXCNT_CAM0_PIXCNT_GET(x) (((x) >> 0) & GENM= ASK(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_MASK GENMASK(19, 0) +#define NEO_COLOR_TEMP_GR_AVG_IN_CAM0_GR_AGV_SET(x) (((x) & GENMASK(19, 0)= ) << 0) +#define NEO_COLOR_TEMP_GR_AVG_IN_CAM0_GR_AGV_GET(x) (((x) >> 0) & GENMASK= (19, 0)) + +#define NEO_COLOR_TEMP_GB_AVG_IN_CAM0 0x588 +#define NEO_COLOR_TEMP_GB_AVG_IN_CAM0_GB_AGV_MASK GENMASK(19, 0) +#define NEO_COLOR_TEMP_GB_AVG_IN_CAM0_GB_AGV_SET(x) (((x) & GENMASK(19, 0)= ) << 0) +#define NEO_COLOR_TEMP_GB_AVG_IN_CAM0_GB_AGV_GET(x) (((x) >> 0) & 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_CTRL_CAM0_ENABLE_SET(x) (((x) << 31) & BIT(31)) + +#define NEO_RGBIR_CCM0_CAM0 0x604 +#define NEO_RGBIR_CCM0_CAM0_CCM_MASK GENMASK(15, 0) +#define NEO_RGBIR_CCM0_CAM0_CCM_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_RGBIR_CCM0_CAM0_CCM_GET(x) (((x) >> 0) & GENMASK(15, 0)) + +#define NEO_RGBIR_CCM1_CAM0 0x608 +#define NEO_RGBIR_CCM1_CAM0_CCM_MASK GENMASK(15, 0) +#define NEO_RGBIR_CCM1_CAM0_CCM_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_RGBIR_CCM1_CAM0_CCM_GET(x) (((x) >> 0) & GENMASK(15, 0)) + +#define NEO_RGBIR_CCM2_CAM0 0x60c +#define NEO_RGBIR_CCM2_CAM0_CCM_MASK GENMASK(15, 0) +#define NEO_RGBIR_CCM2_CAM0_CCM_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_RGBIR_CCM2_CAM0_CCM_GET(x) (((x) >> 0) & GENMASK(15, 0)) + +#define NEO_RGBIR_CCM0_TH_CAM0 0x610 +#define NEO_RGBIR_CCM0_TH_CAM0_THRESHOLD_MASK GENMASK(19, 0) +#define NEO_RGBIR_CCM0_TH_CAM0_THRESHOLD_SET(x) (((x) & GENMASK(19, 0)) <<= 0) +#define NEO_RGBIR_CCM0_TH_CAM0_THRESHOLD_GET(x) (((x) >> 0) & GENMASK(19,= 0)) + +#define NEO_RGBIR_CCM1_TH_CAM0 0x614 +#define NEO_RGBIR_CCM1_TH_CAM0_THRESHOLD_MASK GENMASK(19, 0) +#define NEO_RGBIR_CCM1_TH_CAM0_THRESHOLD_SET(x) (((x) & GENMASK(19, 0)) <<= 0) +#define NEO_RGBIR_CCM1_TH_CAM0_THRESHOLD_GET(x) (((x) >> 0) & GENMASK(19,= 0)) + +#define NEO_RGBIR_CCM2_TH_CAM0 0x618 +#define NEO_RGBIR_CCM2_TH_CAM0_THRESHOLD_MASK GENMASK(19, 0) +#define NEO_RGBIR_CCM2_TH_CAM0_THRESHOLD_SET(x) (((x) & GENMASK(19, 0)) <<= 0) +#define NEO_RGBIR_CCM2_TH_CAM0_THRESHOLD_GET(x) (((x) >> 0) & GENMASK(19,= 0)) + +#define NEO_RGBIR_ROI0_POS_CAM0 0x620 +#define NEO_RGBIR_ROI0_POS_CAM0_XPOS_MASK GENMASK(15, 0) +#define NEO_RGBIR_ROI0_POS_CAM0_XPOS_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_RGBIR_ROI0_POS_CAM0_XPOS_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_RGBIR_ROI0_POS_CAM0_YPOS_MASK GENMASK(31, 16) +#define NEO_RGBIR_ROI0_POS_CAM0_YPOS_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_RGBIR_ROI0_POS_CAM0_YPOS_GET(x) (((x) >> 16) & GENMASK(15, 0)) + +#define NEO_RGBIR_ROI0_SIZE_CAM0 0x624 +#define NEO_RGBIR_ROI0_SIZE_CAM0_WIDTH_MASK GENMASK(15, 0) +#define NEO_RGBIR_ROI0_SIZE_CAM0_WIDTH_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_RGBIR_ROI0_SIZE_CAM0_WIDTH_GET(x) (((x) >> 0) & GENMASK(15, 0= )) +#define NEO_RGBIR_ROI0_SIZE_CAM0_HEIGHT_MASK GENMASK(31, 16) +#define NEO_RGBIR_ROI0_SIZE_CAM0_HEIGHT_SET(x) (((x) & GENMASK(15, 0)) << = 16) +#define NEO_RGBIR_ROI0_SIZE_CAM0_HEIGHT_GET(x) (((x) >> 16) & GENMASK(15,= 0)) + +#define NEO_RGBIR_ROI1_POS_CAM0 0x628 +#define NEO_RGBIR_ROI1_POS_CAM0_XPOS_MASK GENMASK(15, 0) +#define NEO_RGBIR_ROI1_POS_CAM0_XPOS_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_RGBIR_ROI1_POS_CAM0_XPOS_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_RGBIR_ROI1_POS_CAM0_YPOS_MASK GENMASK(31, 16) +#define NEO_RGBIR_ROI1_POS_CAM0_YPOS_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_RGBIR_ROI1_POS_CAM0_YPOS_GET(x) (((x) >> 16) & GENMASK(15, 0)) + +#define NEO_RGBIR_ROI1_SIZE_CAM0 0x62c +#define NEO_RGBIR_ROI1_SIZE_CAM0_WIDTH_MASK GENMASK(15, 0) +#define NEO_RGBIR_ROI1_SIZE_CAM0_WIDTH_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_RGBIR_ROI1_SIZE_CAM0_WIDTH_GET(x) (((x) >> 0) & GENMASK(15, 0= )) +#define NEO_RGBIR_ROI1_SIZE_CAM0_HEIGHT_MASK GENMASK(31, 16) +#define NEO_RGBIR_ROI1_SIZE_CAM0_HEIGHT_SET(x) (((x) & GENMASK(15, 0)) << = 16) +#define NEO_RGBIR_ROI1_SIZE_CAM0_HEIGHT_GET(x) (((x) >> 16) & GENMASK(15,= 0)) + +#define NEO_RGBIR_HIST0_CTRL_CAM0 0x630 +#define NEO_RGBIR_HIST0_CTRL_CAM0_LIN_INPUT1_LOG BIT(0) +#define NEO_RGBIR_HIST0_CTRL_CAM0_LIN_INPUT1_LOG_SET(x) ((x) & BIT(0)) +#define NEO_RGBIR_HIST0_CTRL_CAM0_DIR_INPUT1_DIF BIT(1) +#define NEO_RGBIR_HIST0_CTRL_CAM0_DIR_INPUT1_DIF_SET(x) (((x) << 1) & BIT(= 1)) +#define NEO_RGBIR_HIST0_CTRL_CAM0_PATTERN BIT(2) +#define NEO_RGBIR_HIST0_CTRL_CAM0_PATTERN_SET(x) (((x) << 2) & BIT(2)) +#define NEO_RGBIR_HIST0_CTRL_CAM0_CHANNEL_MASK GENMASK(11, 8) +#define NEO_RGBIR_HIST0_CTRL_CAM0_CHANNEL_SET(x) (((x) & GENMASK(3, 0)) <<= 8) +#define NEO_RGBIR_HIST0_CTRL_CAM0_CHANNEL_GET(x) (((x) >> 8) & GENMASK(3,= 0)) +#define NEO_RGBIR_HIST0_CTRL_CAM0_OFFSET_MASK GENMASK(31, 16) +#define NEO_RGBIR_HIST0_CTRL_CAM0_OFFSET_SET(x) (((x) & GENMASK(15, 0)) <<= 16) +#define NEO_RGBIR_HIST0_CTRL_CAM0_OFFSET_GET(x) (((x) >> 16) & GENMASK(15= , 0)) + +#define NEO_RGBIR_HIST0_SCALE_CAM0 0x634 +#define NEO_RGBIR_HIST0_SCALE_CAM0_SCALE_MASK GENMASK(23, 0) +#define NEO_RGBIR_HIST0_SCALE_CAM0_SCALE_SET(x) (((x) & GENMASK(23, 0)) <<= 0) +#define NEO_RGBIR_HIST0_SCALE_CAM0_SCALE_GET(x) (((x) >> 0) & 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_LIN_INPUT1_LOG_SET(x) ((x) & BIT(0)) +#define NEO_RGBIR_HIST1_CTRL_CAM0_DIR_INPUT1_DIF BIT(1) +#define NEO_RGBIR_HIST1_CTRL_CAM0_DIR_INPUT1_DIF_SET(x) (((x) << 1) & BIT(= 1)) +#define NEO_RGBIR_HIST1_CTRL_CAM0_PATTERN BIT(2) +#define NEO_RGBIR_HIST1_CTRL_CAM0_PATTERN_SET(x) (((x) << 2) & BIT(2)) +#define NEO_RGBIR_HIST1_CTRL_CAM0_CHANNEL_MASK GENMASK(11, 8) +#define NEO_RGBIR_HIST1_CTRL_CAM0_CHANNEL_SET(x) (((x) & GENMASK(3, 0)) <<= 8) +#define NEO_RGBIR_HIST1_CTRL_CAM0_CHANNEL_GET(x) (((x) >> 8) & GENMASK(3,= 0)) +#define NEO_RGBIR_HIST1_CTRL_CAM0_OFFSET_MASK GENMASK(31, 16) +#define NEO_RGBIR_HIST1_CTRL_CAM0_OFFSET_SET(x) (((x) & GENMASK(15, 0)) <<= 16) +#define NEO_RGBIR_HIST1_CTRL_CAM0_OFFSET_GET(x) (((x) >> 16) & GENMASK(15= , 0)) + +#define NEO_RGBIR_HIST1_SCALE_CAM0 0x63c +#define NEO_RGBIR_HIST1_SCALE_CAM0_SCALE_MASK GENMASK(23, 0) +#define NEO_RGBIR_HIST1_SCALE_CAM0_SCALE_SET(x) (((x) & GENMASK(23, 0)) <<= 0) +#define NEO_RGBIR_HIST1_SCALE_CAM0_SCALE_GET(x) (((x) >> 0) & GENMASK(23,= 0)) + +/* STAT */ +#define NEO_STAT_ROI0_POS_CAM0 0x700 +#define NEO_STAT_ROI0_POS_CAM0_XPOS_MASK GENMASK(15, 0) +#define NEO_STAT_ROI0_POS_CAM0_XPOS_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_STAT_ROI0_POS_CAM0_XPOS_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_STAT_ROI0_POS_CAM0_YPOS_MASK GENMASK(31, 16) +#define NEO_STAT_ROI0_POS_CAM0_YPOS_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_STAT_ROI0_POS_CAM0_YPOS_GET(x) (((x) >> 16) & GENMASK(15, 0)) + +#define NEO_STAT_ROI0_SIZE_CAM0 0x704 +#define NEO_STAT_ROI0_SIZE_CAM0_WIDTH_MASK GENMASK(15, 0) +#define NEO_STAT_ROI0_SIZE_CAM0_WIDTH_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_STAT_ROI0_SIZE_CAM0_WIDTH_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_STAT_ROI0_SIZE_CAM0_HEIGHT_MASK GENMASK(31, 16) +#define NEO_STAT_ROI0_SIZE_CAM0_HEIGHT_SET(x) (((x) & GENMASK(15, 0)) << 1= 6) +#define NEO_STAT_ROI0_SIZE_CAM0_HEIGHT_GET(x) (((x) >> 16) & GENMASK(15, = 0)) + +#define NEO_STAT_ROI1_POS_CAM0 0x708 +#define NEO_STAT_ROI1_POS_CAM0_XPOS_MASK GENMASK(15, 0) +#define NEO_STAT_ROI1_POS_CAM0_XPOS_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_STAT_ROI1_POS_CAM0_XPOS_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_STAT_ROI1_POS_CAM0_YPOS_MASK GENMASK(31, 16) +#define NEO_STAT_ROI1_POS_CAM0_YPOS_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_STAT_ROI1_POS_CAM0_YPOS_GET(x) (((x) >> 16) & GENMASK(15, 0)) + +#define NEO_STAT_ROI1_SIZE_CAM0 0x70c +#define NEO_STAT_ROI1_SIZE_CAM0_WIDTH_MASK GENMASK(15, 0) +#define NEO_STAT_ROI1_SIZE_CAM0_WIDTH_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_STAT_ROI1_SIZE_CAM0_WIDTH_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_STAT_ROI1_SIZE_CAM0_HEIGHT_MASK GENMASK(31, 16) +#define NEO_STAT_ROI1_SIZE_CAM0_HEIGHT_SET(x) (((x) & GENMASK(15, 0)) << 1= 6) +#define NEO_STAT_ROI1_SIZE_CAM0_HEIGHT_GET(x) (((x) >> 16) & GENMASK(15, = 0)) + +#define NEO_STAT_HIST0_CTRL_CAM0 0x720 +#define NEO_STAT_HIST0_CTRL_CAM0_LIN_INPUT1_LOG BIT(0) +#define NEO_STAT_HIST0_CTRL_CAM0_LIN_INPUT1_LOG_SET(x) ((x) & BIT(0)) +#define NEO_STAT_HIST0_CTRL_CAM0_DIR_INPUT1_DIF BIT(1) +#define NEO_STAT_HIST0_CTRL_CAM0_DIR_INPUT1_DIF_SET(x) (((x) << 1) & BIT(1= )) +#define NEO_STAT_HIST0_CTRL_CAM0_PATTERN BIT(2) +#define NEO_STAT_HIST0_CTRL_CAM0_PATTERN_SET(x) (((x) << 2) & BIT(2)) +#define NEO_STAT_HIST0_CTRL_CAM0_CHANNEL_MASK GENMASK(11, 8) +#define NEO_STAT_HIST0_CTRL_CAM0_CHANNEL_SET(x) (((x) & GENMASK(3, 0)) << = 8) +#define NEO_STAT_HIST0_CTRL_CAM0_CHANNEL_GET(x) (((x) >> 8) & GENMASK(3, = 0)) +#define NEO_STAT_HIST0_CTRL_CAM0_OFFSET_MASK GENMASK(31, 16) +#define NEO_STAT_HIST0_CTRL_CAM0_OFFSET_SET(x) (((x) & GENMASK(15, 0)) << = 16) +#define NEO_STAT_HIST0_CTRL_CAM0_OFFSET_GET(x) (((x) >> 16) & GENMASK(15,= 0)) + +#define NEO_STAT_HIST0_SCALE_CAM0 0x724 +#define NEO_STAT_HIST0_SCALE_CAM0_SCALE_MASK GENMASK(23, 0) +#define NEO_STAT_HIST0_SCALE_CAM0_SCALE_SET(x) (((x) & GENMASK(23, 0)) << = 0) +#define NEO_STAT_HIST0_SCALE_CAM0_SCALE_GET(x) (((x) >> 0) & 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_LIN_INPUT1_LOG_SET(x) ((x) & BIT(0)) +#define NEO_STAT_HIST1_CTRL_CAM0_DIR_INPUT1_DIF BIT(1) +#define NEO_STAT_HIST1_CTRL_CAM0_DIR_INPUT1_DIF_SET(x) (((x) << 1) & BIT(1= )) +#define NEO_STAT_HIST1_CTRL_CAM0_PATTERN BIT(2) +#define NEO_STAT_HIST1_CTRL_CAM0_PATTERN_SET(x) (((x) << 2) & BIT(2)) +#define NEO_STAT_HIST1_CTRL_CAM0_CHANNEL_MASK GENMASK(11, 8) +#define NEO_STAT_HIST1_CTRL_CAM0_CHANNEL_SET(x) (((x) & GENMASK(3, 0)) << = 8) +#define NEO_STAT_HIST1_CTRL_CAM0_CHANNEL_GET(x) (((x) >> 8) & GENMASK(3, = 0)) +#define NEO_STAT_HIST1_CTRL_CAM0_OFFSET_MASK GENMASK(31, 16) +#define NEO_STAT_HIST1_CTRL_CAM0_OFFSET_SET(x) (((x) & GENMASK(15, 0)) << = 16) +#define NEO_STAT_HIST1_CTRL_CAM0_OFFSET_GET(x) (((x) >> 16) & GENMASK(15,= 0)) + +#define NEO_STAT_HIST1_SCALE_CAM0 0x72c +#define NEO_STAT_HIST1_SCALE_CAM0_SCALE_MASK GENMASK(23, 0) +#define NEO_STAT_HIST1_SCALE_CAM0_SCALE_SET(x) (((x) & GENMASK(23, 0)) << = 0) +#define NEO_STAT_HIST1_SCALE_CAM0_SCALE_GET(x) (((x) >> 0) & 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_LIN_INPUT1_LOG_SET(x) ((x) & BIT(0)) +#define NEO_STAT_HIST2_CTRL_CAM0_DIR_INPUT1_DIF BIT(1) +#define NEO_STAT_HIST2_CTRL_CAM0_DIR_INPUT1_DIF_SET(x) (((x) << 1) & BIT(1= )) +#define NEO_STAT_HIST2_CTRL_CAM0_PATTERN BIT(2) +#define NEO_STAT_HIST2_CTRL_CAM0_PATTERN_SET(x) (((x) << 2) & BIT(2)) +#define NEO_STAT_HIST2_CTRL_CAM0_CHANNEL_MASK GENMASK(11, 8) +#define NEO_STAT_HIST2_CTRL_CAM0_CHANNEL_SET(x) (((x) & GENMASK(3, 0)) << = 8) +#define NEO_STAT_HIST2_CTRL_CAM0_CHANNEL_GET(x) (((x) >> 8) & GENMASK(3, = 0)) +#define NEO_STAT_HIST2_CTRL_CAM0_OFFSET_MASK GENMASK(31, 16) +#define NEO_STAT_HIST2_CTRL_CAM0_OFFSET_SET(x) (((x) & GENMASK(15, 0)) << = 16) +#define NEO_STAT_HIST2_CTRL_CAM0_OFFSET_GET(x) (((x) >> 16) & GENMASK(15,= 0)) + +#define NEO_STAT_HIST2_SCALE_CAM0 0x734 +#define NEO_STAT_HIST2_SCALE_CAM0_SCALE_MASK GENMASK(23, 0) +#define NEO_STAT_HIST2_SCALE_CAM0_SCALE_SET(x) (((x) & GENMASK(23, 0)) << = 0) +#define NEO_STAT_HIST2_SCALE_CAM0_SCALE_GET(x) (((x) >> 0) & 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_LIN_INPUT1_LOG_SET(x) ((x) & BIT(0)) +#define NEO_STAT_HIST3_CTRL_CAM0_DIR_INPUT1_DIF BIT(1) +#define NEO_STAT_HIST3_CTRL_CAM0_DIR_INPUT1_DIF_SET(x) (((x) << 1) & BIT(1= )) +#define NEO_STAT_HIST3_CTRL_CAM0_PATTERN BIT(2) +#define NEO_STAT_HIST3_CTRL_CAM0_PATTERN_SET(x) (((x) << 2) & BIT(2)) +#define NEO_STAT_HIST3_CTRL_CAM0_CHANNEL_MASK GENMASK(11, 8) +#define NEO_STAT_HIST3_CTRL_CAM0_CHANNEL_SET(x) (((x) & GENMASK(3, 0)) << = 8) +#define NEO_STAT_HIST3_CTRL_CAM0_CHANNEL_GET(x) (((x) >> 8) & GENMASK(3, = 0)) +#define NEO_STAT_HIST3_CTRL_CAM0_OFFSET_MASK GENMASK(31, 16) +#define NEO_STAT_HIST3_CTRL_CAM0_OFFSET_SET(x) (((x) & GENMASK(15, 0)) << = 16) +#define NEO_STAT_HIST3_CTRL_CAM0_OFFSET_GET(x) (((x) >> 16) & GENMASK(15,= 0)) + +#define NEO_STAT_HIST3_SCALE_CAM0 0x73c +#define NEO_STAT_HIST3_SCALE_CAM0_SCALE_MASK GENMASK(23, 0) +#define NEO_STAT_HIST3_SCALE_CAM0_SCALE_SET(x) (((x) & GENMASK(23, 0)) << = 0) +#define NEO_STAT_HIST3_SCALE_CAM0_SCALE_GET(x) (((x) >> 0) & 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_OBPP_SET(x) ((x) & BIT(0)) +#define NEO_IR_COMPRESS_CTRL_CAM0_ENABLE BIT(31) +#define NEO_IR_COMPRESS_CTRL_CAM0_ENABLE_SET(x) (((x) << 31) & BIT(31)) + +#define NEO_IR_COMPRESS_KNEE_POINT1_CAM0 0x784 +#define NEO_IR_COMPRESS_KNEE_POINT1_CAM0_KNEEPOINT_MASK GENMASK(19, 0) +#define NEO_IR_COMPRESS_KNEE_POINT1_CAM0_KNEEPOINT_SET(x) (((x) & GENMASK(= 19, 0)) << 0) +#define NEO_IR_COMPRESS_KNEE_POINT1_CAM0_KNEEPOINT_GET(x) (((x) >> 0) & G= ENMASK(19, 0)) + +#define NEO_IR_COMPRESS_KNEE_POINT2_CAM0 0x788 +#define NEO_IR_COMPRESS_KNEE_POINT2_CAM0_KNEEPOINT_MASK GENMASK(19, 0) +#define NEO_IR_COMPRESS_KNEE_POINT2_CAM0_KNEEPOINT_SET(x) (((x) & GENMASK(= 19, 0)) << 0) +#define NEO_IR_COMPRESS_KNEE_POINT2_CAM0_KNEEPOINT_GET(x) (((x) >> 0) & G= ENMASK(19, 0)) + +#define NEO_IR_COMPRESS_KNEE_POINT3_CAM0 0x78c +#define NEO_IR_COMPRESS_KNEE_POINT3_CAM0_KNEEPOINT_MASK GENMASK(19, 0) +#define NEO_IR_COMPRESS_KNEE_POINT3_CAM0_KNEEPOINT_SET(x) (((x) & GENMASK(= 19, 0)) << 0) +#define NEO_IR_COMPRESS_KNEE_POINT3_CAM0_KNEEPOINT_GET(x) (((x) >> 0) & G= ENMASK(19, 0)) + +#define NEO_IR_COMPRESS_KNEE_POINT4_CAM0 0x790 +#define NEO_IR_COMPRESS_KNEE_POINT4_CAM0_KNEEPOINT_MASK GENMASK(19, 0) +#define NEO_IR_COMPRESS_KNEE_POINT4_CAM0_KNEEPOINT_SET(x) (((x) & GENMASK(= 19, 0)) << 0) +#define NEO_IR_COMPRESS_KNEE_POINT4_CAM0_KNEEPOINT_GET(x) (((x) >> 0) & G= ENMASK(19, 0)) + +#define NEO_IR_COMPRESS_KNEE_OFFSET0_CAM0 0x794 +#define NEO_IR_COMPRESS_KNEE_OFFSET0_CAM0_OFFSET_MASK GENMASK(19, 0) +#define NEO_IR_COMPRESS_KNEE_OFFSET0_CAM0_OFFSET_SET(x) (((x) & GENMASK(19= , 0)) << 0) +#define NEO_IR_COMPRESS_KNEE_OFFSET0_CAM0_OFFSET_GET(x) (((x) >> 0) & GEN= MASK(19, 0)) + +#define NEO_IR_COMPRESS_KNEE_OFFSET1_CAM0 0x798 +#define NEO_IR_COMPRESS_KNEE_OFFSET1_CAM0_OFFSET_MASK GENMASK(19, 0) +#define NEO_IR_COMPRESS_KNEE_OFFSET1_CAM0_OFFSET_SET(x) (((x) & GENMASK(19= , 0)) << 0) +#define NEO_IR_COMPRESS_KNEE_OFFSET1_CAM0_OFFSET_GET(x) (((x) >> 0) & GEN= MASK(19, 0)) + +#define NEO_IR_COMPRESS_KNEE_OFFSET2_CAM0 0x79c +#define NEO_IR_COMPRESS_KNEE_OFFSET2_CAM0_OFFSET_MASK GENMASK(19, 0) +#define NEO_IR_COMPRESS_KNEE_OFFSET2_CAM0_OFFSET_SET(x) (((x) & GENMASK(19= , 0)) << 0) +#define NEO_IR_COMPRESS_KNEE_OFFSET2_CAM0_OFFSET_GET(x) (((x) >> 0) & GEN= MASK(19, 0)) + +#define NEO_IR_COMPRESS_KNEE_OFFSET3_CAM0 0x7a0 +#define NEO_IR_COMPRESS_KNEE_OFFSET3_CAM0_OFFSET_MASK GENMASK(19, 0) +#define NEO_IR_COMPRESS_KNEE_OFFSET3_CAM0_OFFSET_SET(x) (((x) & GENMASK(19= , 0)) << 0) +#define NEO_IR_COMPRESS_KNEE_OFFSET3_CAM0_OFFSET_GET(x) (((x) >> 0) & GEN= MASK(19, 0)) + +#define NEO_IR_COMPRESS_KNEE_OFFSET4_CAM0 0x7a4 +#define NEO_IR_COMPRESS_KNEE_OFFSET4_CAM0_OFFSET_MASK GENMASK(19, 0) +#define NEO_IR_COMPRESS_KNEE_OFFSET4_CAM0_OFFSET_SET(x) (((x) & GENMASK(19= , 0)) << 0) +#define NEO_IR_COMPRESS_KNEE_OFFSET4_CAM0_OFFSET_GET(x) (((x) >> 0) & GEN= MASK(19, 0)) + +#define NEO_IR_COMPRESS_KNEE_RATIO01_CAM0 0x7a8 +#define NEO_IR_COMPRESS_KNEE_RATIO01_CAM0_RATIO0_MASK GENMASK(15, 0) +#define NEO_IR_COMPRESS_KNEE_RATIO01_CAM0_RATIO0_SET(x) (((x) & GENMASK(15= , 0)) << 0) +#define NEO_IR_COMPRESS_KNEE_RATIO01_CAM0_RATIO0_GET(x) (((x) >> 0) & GEN= MASK(15, 0)) +#define NEO_IR_COMPRESS_KNEE_RATIO01_CAM0_RATIO1_MASK GENMASK(31, 16) +#define NEO_IR_COMPRESS_KNEE_RATIO01_CAM0_RATIO1_SET(x) (((x) & GENMASK(15= , 0)) << 16) +#define NEO_IR_COMPRESS_KNEE_RATIO01_CAM0_RATIO1_GET(x) (((x) >> 16) & GE= NMASK(15, 0)) + +#define NEO_IR_COMPRESS_KNEE_RATIO23_CAM0 0x7ac +#define NEO_IR_COMPRESS_KNEE_RATIO23_CAM0_RATIO2_MASK GENMASK(15, 0) +#define NEO_IR_COMPRESS_KNEE_RATIO23_CAM0_RATIO2_SET(x) (((x) & GENMASK(15= , 0)) << 0) +#define NEO_IR_COMPRESS_KNEE_RATIO23_CAM0_RATIO2_GET(x) (((x) >> 0) & GEN= MASK(15, 0)) +#define NEO_IR_COMPRESS_KNEE_RATIO23_CAM0_RATIO3_MASK GENMASK(31, 16) +#define NEO_IR_COMPRESS_KNEE_RATIO23_CAM0_RATIO3_SET(x) (((x) & GENMASK(15= , 0)) << 16) +#define NEO_IR_COMPRESS_KNEE_RATIO23_CAM0_RATIO3_GET(x) (((x) >> 16) & GE= NMASK(15, 0)) + +#define NEO_IR_COMPRESS_KNEE_RATIO4_CAM0 0x7b0 +#define NEO_IR_COMPRESS_KNEE_RATIO4_CAM0_RATIO4_MASK GENMASK(15, 0) +#define NEO_IR_COMPRESS_KNEE_RATIO4_CAM0_RATIO4_SET(x) (((x) & GENMASK(15,= 0)) << 0) +#define NEO_IR_COMPRESS_KNEE_RATIO4_CAM0_RATIO4_GET(x) (((x) >> 0) & GENM= ASK(15, 0)) + +#define NEO_IR_COMPRESS_KNEE_NPOINT0_CAM0 0x7b4 +#define NEO_IR_COMPRESS_KNEE_NPOINT0_CAM0_KNEEPOINT_MASK GENMASK(15, 0) +#define NEO_IR_COMPRESS_KNEE_NPOINT0_CAM0_KNEEPOINT_SET(x) (((x) & GENMASK= (15, 0)) << 0) +#define NEO_IR_COMPRESS_KNEE_NPOINT0_CAM0_KNEEPOINT_GET(x) (((x) >> 0) & = GENMASK(15, 0)) + +#define NEO_IR_COMPRESS_KNEE_NPOINT1_CAM0 0x7b8 +#define NEO_IR_COMPRESS_KNEE_NPOINT1_CAM0_KNEEPOINT_MASK GENMASK(15, 0) +#define NEO_IR_COMPRESS_KNEE_NPOINT1_CAM0_KNEEPOINT_SET(x) (((x) & GENMASK= (15, 0)) << 0) +#define NEO_IR_COMPRESS_KNEE_NPOINT1_CAM0_KNEEPOINT_GET(x) (((x) >> 0) & = GENMASK(15, 0)) + +#define NEO_IR_COMPRESS_KNEE_NPOINT2_CAM0 0x7bc +#define NEO_IR_COMPRESS_KNEE_NPOINT2_CAM0_KNEEPOINT_MASK GENMASK(15, 0) +#define NEO_IR_COMPRESS_KNEE_NPOINT2_CAM0_KNEEPOINT_SET(x) (((x) & GENMASK= (15, 0)) << 0) +#define NEO_IR_COMPRESS_KNEE_NPOINT2_CAM0_KNEEPOINT_GET(x) (((x) >> 0) & = GENMASK(15, 0)) + +#define NEO_IR_COMPRESS_KNEE_NPOINT3_CAM0 0x7c0 +#define NEO_IR_COMPRESS_KNEE_NPOINT3_CAM0_KNEEPOINT_MASK GENMASK(15, 0) +#define NEO_IR_COMPRESS_KNEE_NPOINT3_CAM0_KNEEPOINT_SET(x) (((x) & GENMASK= (15, 0)) << 0) +#define NEO_IR_COMPRESS_KNEE_NPOINT3_CAM0_KNEEPOINT_GET(x) (((x) >> 0) & = GENMASK(15, 0)) + +#define NEO_IR_COMPRESS_KNEE_NPOINT4_CAM0 0x7c4 +#define NEO_IR_COMPRESS_KNEE_NPOINT4_CAM0_KNEEPOINT_MASK GENMASK(15, 0) +#define NEO_IR_COMPRESS_KNEE_NPOINT4_CAM0_KNEEPOINT_SET(x) (((x) & GENMASK= (15, 0)) << 0) +#define NEO_IR_COMPRESS_KNEE_NPOINT4_CAM0_KNEEPOINT_GET(x) (((x) >> 0) & = GENMASK(15, 0)) + +/* BNR */ +#define NEO_BNR_CTRL_CAM0 0x800 +#define NEO_BNR_CTRL_CAM0_OBPP_MASK GENMASK(3, 2) +#define NEO_BNR_CTRL_CAM0_OBPP_SET(x) (((x) & GENMASK(1, 0)) << 2) +#define NEO_BNR_CTRL_CAM0_OBPP_GET(x) (((x) >> 2) & GENMASK(1, 0)) +#define NEO_BNR_CTRL_CAM0_DEBUG_MASK GENMASK(10, 8) +#define NEO_BNR_CTRL_CAM0_DEBUG_SET(x) (((x) & GENMASK(2, 0)) << 8) +#define NEO_BNR_CTRL_CAM0_DEBUG_GET(x) (((x) >> 8) & GENMASK(2, 0)) +#define NEO_BNR_CTRL_CAM0_NHOOD BIT(16) +#define NEO_BNR_CTRL_CAM0_NHOOD_SET(x) (((x) << 16) & BIT(16)) +#define NEO_BNR_CTRL_CAM0_ENABLE BIT(31) +#define NEO_BNR_CTRL_CAM0_ENABLE_SET(x) (((x) << 31) & BIT(31)) + +#define NEO_BNR_YPEAK_CAM0 0x804 +#define NEO_BNR_YPEAK_CAM0_PEAK_LOW_MASK GENMASK(11, 0) +#define NEO_BNR_YPEAK_CAM0_PEAK_LOW_SET(x) (((x) & GENMASK(11, 0)) << 0) +#define NEO_BNR_YPEAK_CAM0_PEAK_LOW_GET(x) (((x) >> 0) & GENMASK(11, 0)) +#define NEO_BNR_YPEAK_CAM0_PEAK_SEL_MASK GENMASK(15, 14) +#define NEO_BNR_YPEAK_CAM0_PEAK_SEL_SET(x) (((x) & GENMASK(1, 0)) << 14) +#define NEO_BNR_YPEAK_CAM0_PEAK_SEL_GET(x) (((x) >> 14) & GENMASK(1, 0)) +#define NEO_BNR_YPEAK_CAM0_PEAK_HIGH_MASK GENMASK(27, 16) +#define NEO_BNR_YPEAK_CAM0_PEAK_HIGH_SET(x) (((x) & GENMASK(11, 0)) << 16) +#define NEO_BNR_YPEAK_CAM0_PEAK_HIGH_GET(x) (((x) >> 16) & GENMASK(11, 0)) +#define NEO_BNR_YPEAK_CAM0_PEAK_OUTSEL BIT(31) +#define NEO_BNR_YPEAK_CAM0_PEAK_OUTSEL_SET(x) (((x) << 31) & BIT(31)) + +#define NEO_BNR_YEDGE_TH0_CAM0 0x808 +#define NEO_BNR_YEDGE_TH0_CAM0_EDGE_TH0_MASK GENMASK(19, 0) +#define NEO_BNR_YEDGE_TH0_CAM0_EDGE_TH0_SET(x) (((x) & GENMASK(19, 0)) << = 0) +#define NEO_BNR_YEDGE_TH0_CAM0_EDGE_TH0_GET(x) (((x) >> 0) & GENMASK(19, = 0)) + +#define NEO_BNR_YEDGE_SCALE_CAM0 0x80c +#define NEO_BNR_YEDGE_SCALE_CAM0_SCALE_MASK GENMASK(15, 0) +#define NEO_BNR_YEDGE_SCALE_CAM0_SCALE_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_BNR_YEDGE_SCALE_CAM0_SCALE_GET(x) (((x) >> 0) & GENMASK(15, 0= )) +#define NEO_BNR_YEDGE_SCALE_CAM0_SHIFT_MASK GENMASK(20, 16) +#define NEO_BNR_YEDGE_SCALE_CAM0_SHIFT_SET(x) (((x) & GENMASK(4, 0)) << 16) +#define NEO_BNR_YEDGE_SCALE_CAM0_SHIFT_GET(x) (((x) >> 16) & GENMASK(4, 0= )) + +#define NEO_BNR_YEDGES_TH0_CAM0 0x810 +#define NEO_BNR_YEDGES_TH0_CAM0_EDGE_TH0_MASK GENMASK(19, 0) +#define NEO_BNR_YEDGES_TH0_CAM0_EDGE_TH0_SET(x) (((x) & GENMASK(19, 0)) <<= 0) +#define NEO_BNR_YEDGES_TH0_CAM0_EDGE_TH0_GET(x) (((x) >> 0) & GENMASK(19,= 0)) + +#define NEO_BNR_YEDGES_SCALE_CAM0 0x814 +#define NEO_BNR_YEDGES_SCALE_CAM0_SCALE_MASK GENMASK(15, 0) +#define NEO_BNR_YEDGES_SCALE_CAM0_SCALE_SET(x) (((x) & GENMASK(15, 0)) << = 0) +#define NEO_BNR_YEDGES_SCALE_CAM0_SCALE_GET(x) (((x) >> 0) & GENMASK(15, = 0)) +#define NEO_BNR_YEDGES_SCALE_CAM0_SHIFT_MASK GENMASK(20, 16) +#define NEO_BNR_YEDGES_SCALE_CAM0_SHIFT_SET(x) (((x) & GENMASK(4, 0)) << 1= 6) +#define NEO_BNR_YEDGES_SCALE_CAM0_SHIFT_GET(x) (((x) >> 16) & GENMASK(4, = 0)) + +#define NEO_BNR_YEDGEA_TH0_CAM0 0x818 +#define NEO_BNR_YEDGEA_TH0_CAM0_EDGE_TH0_MASK GENMASK(19, 0) +#define NEO_BNR_YEDGEA_TH0_CAM0_EDGE_TH0_SET(x) (((x) & GENMASK(19, 0)) <<= 0) +#define NEO_BNR_YEDGEA_TH0_CAM0_EDGE_TH0_GET(x) (((x) >> 0) & GENMASK(19,= 0)) + +#define NEO_BNR_YEDGEA_SCALE_CAM0 0x81c +#define NEO_BNR_YEDGEA_SCALE_CAM0_SCALE_MASK GENMASK(15, 0) +#define NEO_BNR_YEDGEA_SCALE_CAM0_SCALE_SET(x) (((x) & GENMASK(15, 0)) << = 0) +#define NEO_BNR_YEDGEA_SCALE_CAM0_SCALE_GET(x) (((x) >> 0) & GENMASK(15, = 0)) +#define NEO_BNR_YEDGEA_SCALE_CAM0_SHIFT_MASK GENMASK(20, 16) +#define NEO_BNR_YEDGEA_SCALE_CAM0_SHIFT_SET(x) (((x) & GENMASK(4, 0)) << 1= 6) +#define NEO_BNR_YEDGEA_SCALE_CAM0_SHIFT_GET(x) (((x) >> 16) & GENMASK(4, = 0)) + +#define NEO_BNR_YLUMA_X_TH0_CAM0 0x820 +#define NEO_BNR_YLUMA_X_TH0_CAM0_TH_MASK GENMASK(19, 0) +#define NEO_BNR_YLUMA_X_TH0_CAM0_TH_SET(x) (((x) & GENMASK(19, 0)) << 0) +#define NEO_BNR_YLUMA_X_TH0_CAM0_TH_GET(x) (((x) >> 0) & GENMASK(19, 0)) + +#define NEO_BNR_YLUMA_Y_TH_CAM0 0x824 +#define NEO_BNR_YLUMA_Y_TH_CAM0_LUMA_Y_TH0_MASK GENMASK(9, 0) +#define NEO_BNR_YLUMA_Y_TH_CAM0_LUMA_Y_TH0_SET(x) (((x) & GENMASK(9, 0)) <= < 0) +#define NEO_BNR_YLUMA_Y_TH_CAM0_LUMA_Y_TH0_GET(x) (((x) >> 0) & GENMASK(9= , 0)) +#define NEO_BNR_YLUMA_Y_TH_CAM0_LUMA_Y_TH1_MASK GENMASK(25, 16) +#define NEO_BNR_YLUMA_Y_TH_CAM0_LUMA_Y_TH1_SET(x) (((x) & GENMASK(9, 0)) <= < 16) +#define NEO_BNR_YLUMA_Y_TH_CAM0_LUMA_Y_TH1_GET(x) (((x) >> 16) & GENMASK(= 9, 0)) + +#define NEO_BNR_YLUMA_SCALE_CAM0 0x828 +#define NEO_BNR_YLUMA_SCALE_CAM0_SCALE_MASK GENMASK(15, 0) +#define NEO_BNR_YLUMA_SCALE_CAM0_SCALE_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_BNR_YLUMA_SCALE_CAM0_SCALE_GET(x) (((x) >> 0) & GENMASK(15, 0= )) +#define NEO_BNR_YLUMA_SCALE_CAM0_SHIFT_MASK GENMASK(20, 16) +#define NEO_BNR_YLUMA_SCALE_CAM0_SHIFT_SET(x) (((x) & GENMASK(4, 0)) << 16) +#define NEO_BNR_YLUMA_SCALE_CAM0_SHIFT_GET(x) (((x) >> 16) & GENMASK(4, 0= )) + +#define NEO_BNR_YALPHA_GAIN_CAM0 0x82c +#define NEO_BNR_YALPHA_GAIN_CAM0_GAIN_MASK GENMASK(15, 0) +#define NEO_BNR_YALPHA_GAIN_CAM0_GAIN_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_BNR_YALPHA_GAIN_CAM0_GAIN_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_BNR_YALPHA_GAIN_CAM0_OFFSET_MASK GENMASK(31, 16) +#define NEO_BNR_YALPHA_GAIN_CAM0_OFFSET_SET(x) (((x) & GENMASK(15, 0)) << = 16) +#define NEO_BNR_YALPHA_GAIN_CAM0_OFFSET_GET(x) (((x) >> 16) & GENMASK(15,= 0)) + +#define NEO_BNR_CPEAK_CAM0 0x830 +#define NEO_BNR_CPEAK_CAM0_PEAK_LOW_MASK GENMASK(11, 0) +#define NEO_BNR_CPEAK_CAM0_PEAK_LOW_SET(x) (((x) & GENMASK(11, 0)) << 0) +#define NEO_BNR_CPEAK_CAM0_PEAK_LOW_GET(x) (((x) >> 0) & GENMASK(11, 0)) +#define NEO_BNR_CPEAK_CAM0_PEAK_SEL_MASK GENMASK(15, 14) +#define NEO_BNR_CPEAK_CAM0_PEAK_SEL_SET(x) (((x) & GENMASK(1, 0)) << 14) +#define NEO_BNR_CPEAK_CAM0_PEAK_SEL_GET(x) (((x) >> 14) & GENMASK(1, 0)) +#define NEO_BNR_CPEAK_CAM0_PEAK_HIGH_MASK GENMASK(27, 16) +#define NEO_BNR_CPEAK_CAM0_PEAK_HIGH_SET(x) (((x) & GENMASK(11, 0)) << 16) +#define NEO_BNR_CPEAK_CAM0_PEAK_HIGH_GET(x) (((x) >> 16) & GENMASK(11, 0)) +#define NEO_BNR_CPEAK_CAM0_PEAK_OUTSEL BIT(31) +#define NEO_BNR_CPEAK_CAM0_PEAK_OUTSEL_SET(x) (((x) << 31) & BIT(31)) + +#define NEO_BNR_CEDGE_TH0_CAM0 0x834 +#define NEO_BNR_CEDGE_TH0_CAM0_EDGE_TH0_MASK GENMASK(19, 0) +#define NEO_BNR_CEDGE_TH0_CAM0_EDGE_TH0_SET(x) (((x) & GENMASK(19, 0)) << = 0) +#define NEO_BNR_CEDGE_TH0_CAM0_EDGE_TH0_GET(x) (((x) >> 0) & GENMASK(19, = 0)) + +#define NEO_BNR_CEDGE_SCALE_CAM0 0x838 +#define NEO_BNR_CEDGE_SCALE_CAM0_SCALE_MASK GENMASK(15, 0) +#define NEO_BNR_CEDGE_SCALE_CAM0_SCALE_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_BNR_CEDGE_SCALE_CAM0_SCALE_GET(x) (((x) >> 0) & GENMASK(15, 0= )) +#define NEO_BNR_CEDGE_SCALE_CAM0_SHIFT_MASK GENMASK(20, 16) +#define NEO_BNR_CEDGE_SCALE_CAM0_SHIFT_SET(x) (((x) & GENMASK(4, 0)) << 16) +#define NEO_BNR_CEDGE_SCALE_CAM0_SHIFT_GET(x) (((x) >> 16) & GENMASK(4, 0= )) + +#define NEO_BNR_CEDGES_TH0_CAM0 0x83c +#define NEO_BNR_CEDGES_TH0_CAM0_EDGE_TH0_MASK GENMASK(19, 0) +#define NEO_BNR_CEDGES_TH0_CAM0_EDGE_TH0_SET(x) (((x) & GENMASK(19, 0)) <<= 0) +#define NEO_BNR_CEDGES_TH0_CAM0_EDGE_TH0_GET(x) (((x) >> 0) & GENMASK(19,= 0)) + +#define NEO_BNR_CEDGES_SCALE_CAM0 0x840 +#define NEO_BNR_CEDGES_SCALE_CAM0_SCALE_MASK GENMASK(15, 0) +#define NEO_BNR_CEDGES_SCALE_CAM0_SCALE_SET(x) (((x) & GENMASK(15, 0)) << = 0) +#define NEO_BNR_CEDGES_SCALE_CAM0_SCALE_GET(x) (((x) >> 0) & GENMASK(15, = 0)) +#define NEO_BNR_CEDGES_SCALE_CAM0_SHIFT_MASK GENMASK(20, 16) +#define NEO_BNR_CEDGES_SCALE_CAM0_SHIFT_SET(x) (((x) & GENMASK(4, 0)) << 1= 6) +#define NEO_BNR_CEDGES_SCALE_CAM0_SHIFT_GET(x) (((x) >> 16) & GENMASK(4, = 0)) + +#define NEO_BNR_CEDGEA_TH0_CAM0 0x844 +#define NEO_BNR_CEDGEA_TH0_CAM0_EDGE_TH0_MASK GENMASK(19, 0) +#define NEO_BNR_CEDGEA_TH0_CAM0_EDGE_TH0_SET(x) (((x) & GENMASK(19, 0)) <<= 0) +#define NEO_BNR_CEDGEA_TH0_CAM0_EDGE_TH0_GET(x) (((x) >> 0) & GENMASK(19,= 0)) + +#define NEO_BNR_CEDGEA_SCALE_CAM0 0x848 +#define NEO_BNR_CEDGEA_SCALE_CAM0_SCALE_MASK GENMASK(15, 0) +#define NEO_BNR_CEDGEA_SCALE_CAM0_SCALE_SET(x) (((x) & GENMASK(15, 0)) << = 0) +#define NEO_BNR_CEDGEA_SCALE_CAM0_SCALE_GET(x) (((x) >> 0) & GENMASK(15, = 0)) +#define NEO_BNR_CEDGEA_SCALE_CAM0_SHIFT_MASK GENMASK(20, 16) +#define NEO_BNR_CEDGEA_SCALE_CAM0_SHIFT_SET(x) (((x) & GENMASK(4, 0)) << 1= 6) +#define NEO_BNR_CEDGEA_SCALE_CAM0_SHIFT_GET(x) (((x) >> 16) & GENMASK(4, = 0)) + +#define NEO_BNR_CLUMA_X_TH0_CAM0 0x84c +#define NEO_BNR_CLUMA_X_TH0_CAM0_TH_MASK GENMASK(19, 0) +#define NEO_BNR_CLUMA_X_TH0_CAM0_TH_SET(x) (((x) & GENMASK(19, 0)) << 0) +#define NEO_BNR_CLUMA_X_TH0_CAM0_TH_GET(x) (((x) >> 0) & GENMASK(19, 0)) + +#define NEO_BNR_CLUMA_Y_TH_CAM0 0x850 +#define NEO_BNR_CLUMA_Y_TH_CAM0_LUMA_Y_TH0_MASK GENMASK(9, 0) +#define NEO_BNR_CLUMA_Y_TH_CAM0_LUMA_Y_TH0_SET(x) (((x) & GENMASK(9, 0)) <= < 0) +#define NEO_BNR_CLUMA_Y_TH_CAM0_LUMA_Y_TH0_GET(x) (((x) >> 0) & GENMASK(9= , 0)) +#define NEO_BNR_CLUMA_Y_TH_CAM0_LUMA_Y_TH1_MASK GENMASK(25, 16) +#define NEO_BNR_CLUMA_Y_TH_CAM0_LUMA_Y_TH1_SET(x) (((x) & GENMASK(9, 0)) <= < 16) +#define NEO_BNR_CLUMA_Y_TH_CAM0_LUMA_Y_TH1_GET(x) (((x) >> 16) & GENMASK(= 9, 0)) + +#define NEO_BNR_CLUMA_SCALE_CAM0 0x854 +#define NEO_BNR_CLUMA_SCALE_CAM0_SCALE_MASK GENMASK(15, 0) +#define NEO_BNR_CLUMA_SCALE_CAM0_SCALE_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_BNR_CLUMA_SCALE_CAM0_SCALE_GET(x) (((x) >> 0) & GENMASK(15, 0= )) +#define NEO_BNR_CLUMA_SCALE_CAM0_SHIFT_MASK GENMASK(20, 16) +#define NEO_BNR_CLUMA_SCALE_CAM0_SHIFT_SET(x) (((x) & GENMASK(4, 0)) << 16) +#define NEO_BNR_CLUMA_SCALE_CAM0_SHIFT_GET(x) (((x) >> 16) & GENMASK(4, 0= )) + +#define NEO_BNR_CALPHA_GAIN_CAM0 0x858 +#define NEO_BNR_CALPHA_GAIN_CAM0_GAIN_MASK GENMASK(15, 0) +#define NEO_BNR_CALPHA_GAIN_CAM0_GAIN_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_BNR_CALPHA_GAIN_CAM0_GAIN_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_BNR_CALPHA_GAIN_CAM0_OFFSET_MASK GENMASK(31, 16) +#define NEO_BNR_CALPHA_GAIN_CAM0_OFFSET_SET(x) (((x) & GENMASK(15, 0)) << = 16) +#define NEO_BNR_CALPHA_GAIN_CAM0_OFFSET_GET(x) (((x) >> 16) & GENMASK(15,= 0)) + +#define NEO_BNR_EDGE_STAT_CAM0 0x85c +#define NEO_BNR_EDGE_STAT_CAM0_EDGE_PIXELS_MASK GENMASK(23, 0) +#define NEO_BNR_EDGE_STAT_CAM0_EDGE_PIXELS_SET(x) (((x) & GENMASK(23, 0)) = << 0) +#define NEO_BNR_EDGE_STAT_CAM0_EDGE_PIXELS_GET(x) (((x) >> 0) & GENMASK(2= 3, 0)) + +#define NEO_BNR_EDGES_STAT_CAM0 0x860 +#define NEO_BNR_EDGES_STAT_CAM0_EDGE_PIXELS_MASK GENMASK(23, 0) +#define NEO_BNR_EDGES_STAT_CAM0_EDGE_PIXELS_SET(x) (((x) & GENMASK(23, 0))= << 0) +#define NEO_BNR_EDGES_STAT_CAM0_EDGE_PIXELS_GET(x) (((x) >> 0) & GENMASK(= 23, 0)) + +#define NEO_BNR_STRETCH_CAM0 0x864 +#define NEO_BNR_STRETCH_CAM0_GAIN_MASK GENMASK(15, 0) +#define NEO_BNR_STRETCH_CAM0_GAIN_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_BNR_STRETCH_CAM0_GAIN_GET(x) (((x) >> 0) & GENMASK(15, 0)) + +/* VIGNETTING */ +#define NEO_VIGNETTING_CTRL_CAM0 0x900 +#define NEO_VIGNETTING_CTRL_CAM0_ENABLE BIT(31) +#define NEO_VIGNETTING_CTRL_CAM0_ENABLE_SET(x) (((x) << 31) & BIT(31)) + +#define NEO_VIGNETTING_BLK_CONF_CAM0 0x904 +#define NEO_VIGNETTING_BLK_CONF_CAM0_COLS_MASK GENMASK(7, 0) +#define NEO_VIGNETTING_BLK_CONF_CAM0_COLS_SET(x) (((x) & GENMASK(7, 0)) <<= 0) +#define NEO_VIGNETTING_BLK_CONF_CAM0_COLS_GET(x) (((x) >> 0) & GENMASK(7,= 0)) +#define NEO_VIGNETTING_BLK_CONF_CAM0_ROWS_MASK GENMASK(23, 16) +#define NEO_VIGNETTING_BLK_CONF_CAM0_ROWS_SET(x) (((x) & GENMASK(7, 0)) <<= 16) +#define NEO_VIGNETTING_BLK_CONF_CAM0_ROWS_GET(x) (((x) >> 16) & GENMASK(7= , 0)) + +#define NEO_VIGNETTING_BLK_SIZE_CAM0 0x908 +#define NEO_VIGNETTING_BLK_SIZE_CAM0_XSIZE_MASK GENMASK(15, 0) +#define NEO_VIGNETTING_BLK_SIZE_CAM0_XSIZE_SET(x) (((x) & GENMASK(15, 0)) = << 0) +#define NEO_VIGNETTING_BLK_SIZE_CAM0_XSIZE_GET(x) (((x) >> 0) & GENMASK(1= 5, 0)) +#define NEO_VIGNETTING_BLK_SIZE_CAM0_YSIZE_MASK GENMASK(31, 16) +#define NEO_VIGNETTING_BLK_SIZE_CAM0_YSIZE_SET(x) (((x) & GENMASK(15, 0)) = << 16) +#define NEO_VIGNETTING_BLK_SIZE_CAM0_YSIZE_GET(x) (((x) >> 16) & GENMASK(= 15, 0)) + +#define NEO_VIGNETTING_BLK_STEPY_CAM0 0x90c +#define NEO_VIGNETTING_BLK_STEPY_CAM0_STEP_MASK GENMASK(15, 0) +#define NEO_VIGNETTING_BLK_STEPY_CAM0_STEP_SET(x) (((x) & GENMASK(15, 0)) = << 0) +#define NEO_VIGNETTING_BLK_STEPY_CAM0_STEP_GET(x) (((x) >> 0) & GENMASK(1= 5, 0)) + +#define NEO_VIGNETTING_BLK_STEPX_CAM0 0x910 +#define NEO_VIGNETTING_BLK_STEPX_CAM0_STEP_MASK GENMASK(15, 0) +#define NEO_VIGNETTING_BLK_STEPX_CAM0_STEP_SET(x) (((x) & GENMASK(15, 0)) = << 0) +#define NEO_VIGNETTING_BLK_STEPX_CAM0_STEP_GET(x) (((x) >> 0) & GENMASK(1= 5, 0)) + +#define NEO_VIGNETTING_BLK_C_LINE_CAM0 0x920 +#define NEO_VIGNETTING_BLK_C_LINE_CAM0_LINE_MASK GENMASK(15, 0) +#define NEO_VIGNETTING_BLK_C_LINE_CAM0_LINE_GET(x) (((x) >> 0) & GENMASK(= 15, 0)) + +#define NEO_VIGNETTING_BLK_C_ROW_CAM0 0x924 +#define NEO_VIGNETTING_BLK_C_ROW_CAM0_BLKROW_MASK GENMASK(7, 0) +#define NEO_VIGNETTING_BLK_C_ROW_CAM0_BLKROW_GET(x) (((x) >> 0) & 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_MASK GENMASK(16, 0) +#define NEO_IDBG1_LINE_NUM_LINE_NUM_SET(x) (((x) & GENMASK(16, 0)) << 0) +#define NEO_IDBG1_LINE_NUM_LINE_NUM_GET(x) (((x) >> 0) & GENMASK(16, 0)) + +#define NEO_IDBG1_CURR_LINE_NUM 0xfc4 +#define NEO_IDBG1_CURR_LINE_NUM_CURR_LINE_NUM_MASK GENMASK(16, 0) +#define NEO_IDBG1_CURR_LINE_NUM_CURR_LINE_NUM_SET(x) (((x) & GENMASK(16, 0= )) << 0) +#define NEO_IDBG1_CURR_LINE_NUM_CURR_LINE_NUM_GET(x) (((x) >> 0) & GENMAS= K(16, 0)) +#define NEO_IDBG1_CURR_LINE_NUM_DBG_HIT BIT(31) + +#define NEO_IDBG1_IMA 0xfc8 +#define NEO_IDBG1_IMA_ADDR_MASK GENMASK(11, 0) +#define NEO_IDBG1_IMA_ADDR_SET(x) (((x) & GENMASK(11, 0)) << 0) +#define NEO_IDBG1_IMA_ADDR_GET(x) (((x) >> 0) & GENMASK(11, 0)) +#define NEO_IDBG1_IMA_NAME_MASK GENMASK(20, 16) +#define NEO_IDBG1_IMA_NAME_SET(x) (((x) & GENMASK(4, 0)) << 16) +#define NEO_IDBG1_IMA_NAME_GET(x) (((x) >> 16) & GENMASK(4, 0)) +#define NEO_IDBG1_IMA_RDWF_MASK GENMASK(29, 28) +#define NEO_IDBG1_IMA_RDWF_SET(x) (((x) & GENMASK(1, 0)) << 28) +#define NEO_IDBG1_IMA_RDWF_GET(x) (((x) >> 28) & GENMASK(1, 0)) +#define NEO_IDBG1_IMA_WDWF_MASK GENMASK(31, 30) +#define NEO_IDBG1_IMA_WDWF_SET(x) (((x) & GENMASK(1, 0)) << 30) +#define NEO_IDBG1_IMA_WDWF_GET(x) (((x) >> 30) & GENMASK(1, 0)) + +#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_MASK GENMASK(5, 4) +#define NEO_DEMOSAIC_CTRL_CAM0_FMT_SET(x) (((x) & GENMASK(1, 0)) << 4) +#define NEO_DEMOSAIC_CTRL_CAM0_FMT_GET(x) (((x) >> 4) & GENMASK(1, 0)) + +#define NEO_DEMOSAIC_ACTIVITY_CTL_CAM0 0x1184 +#define NEO_DEMOSAIC_ACTIVITY_CTL_CAM0_ALPHA_MASK GENMASK(8, 0) +#define NEO_DEMOSAIC_ACTIVITY_CTL_CAM0_ALPHA_SET(x) (((x) & GENMASK(8, 0))= << 0) +#define NEO_DEMOSAIC_ACTIVITY_CTL_CAM0_ALPHA_GET(x) (((x) >> 0) & GENMASK= (8, 0)) +#define NEO_DEMOSAIC_ACTIVITY_CTL_CAM0_ACT_RATIO_MASK GENMASK(31, 16) +#define NEO_DEMOSAIC_ACTIVITY_CTL_CAM0_ACT_RATIO_SET(x) (((x) & GENMASK(15= , 0)) << 16) +#define NEO_DEMOSAIC_ACTIVITY_CTL_CAM0_ACT_RATIO_GET(x) (((x) >> 16) & GE= NMASK(15, 0)) + +#define NEO_DEMOSAIC_DYNAMICS_CTL0_CAM0 0x1188 +#define NEO_DEMOSAIC_DYNAMICS_CTL0_CAM0_STRENGTHG_MASK GENMASK(15, 0) +#define NEO_DEMOSAIC_DYNAMICS_CTL0_CAM0_STRENGTHG_SET(x) (((x) & GENMASK(1= 5, 0)) << 0) +#define NEO_DEMOSAIC_DYNAMICS_CTL0_CAM0_STRENGTHG_GET(x) (((x) >> 0) & GE= NMASK(15, 0)) +#define NEO_DEMOSAIC_DYNAMICS_CTL0_CAM0_STRENGTHC_MASK GENMASK(31, 16) +#define NEO_DEMOSAIC_DYNAMICS_CTL0_CAM0_STRENGTHC_SET(x) (((x) & GENMASK(1= 5, 0)) << 16) +#define NEO_DEMOSAIC_DYNAMICS_CTL0_CAM0_STRENGTHC_GET(x) (((x) >> 16) & G= ENMASK(15, 0)) + +#define NEO_DEMOSAIC_DYNAMICS_CTL2_CAM0 0x118c +#define NEO_DEMOSAIC_DYNAMICS_CTL2_CAM0_MAX_IMPACT_MASK GENMASK(15, 0) +#define NEO_DEMOSAIC_DYNAMICS_CTL2_CAM0_MAX_IMPACT_SET(x) (((x) & GENMASK(= 15, 0)) << 0) +#define NEO_DEMOSAIC_DYNAMICS_CTL2_CAM0_MAX_IMPACT_GET(x) (((x) >> 0) & G= ENMASK(15, 0)) + +/* RGB_TO_YUV */ +#define NEO_RGB_TO_YUV_GAIN_CTRL_CAM0 0x11c0 +#define NEO_RGB_TO_YUV_GAIN_CTRL_CAM0_RGAIN_MASK GENMASK(15, 0) +#define NEO_RGB_TO_YUV_GAIN_CTRL_CAM0_RGAIN_SET(x) (((x) & GENMASK(15, 0))= << 0) +#define NEO_RGB_TO_YUV_GAIN_CTRL_CAM0_RGAIN_GET(x) (((x) >> 0) & GENMASK(= 15, 0)) +#define NEO_RGB_TO_YUV_GAIN_CTRL_CAM0_BGAIN_MASK GENMASK(31, 16) +#define NEO_RGB_TO_YUV_GAIN_CTRL_CAM0_BGAIN_SET(x) (((x) & GENMASK(15, 0))= << 16) +#define NEO_RGB_TO_YUV_GAIN_CTRL_CAM0_BGAIN_GET(x) (((x) >> 16) & GENMASK= (15, 0)) + +#define NEO_RGB_TO_YUV_MAT0_CAM0 0x11c4 +#define NEO_RGB_TO_YUV_MAT0_CAM0_R0C0_MASK GENMASK(15, 0) +#define NEO_RGB_TO_YUV_MAT0_CAM0_R0C0_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_RGB_TO_YUV_MAT0_CAM0_R0C0_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_RGB_TO_YUV_MAT0_CAM0_R0C1_MASK GENMASK(31, 16) +#define NEO_RGB_TO_YUV_MAT0_CAM0_R0C1_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_RGB_TO_YUV_MAT0_CAM0_R0C1_GET(x) (((x) >> 16) & GENMASK(15, 0= )) + +#define NEO_RGB_TO_YUV_MAT1_CAM0 0x11c8 +#define NEO_RGB_TO_YUV_MAT1_CAM0_R0C2_MASK GENMASK(15, 0) +#define NEO_RGB_TO_YUV_MAT1_CAM0_R0C2_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_RGB_TO_YUV_MAT1_CAM0_R0C2_GET(x) (((x) >> 0) & GENMASK(15, 0)) + +#define NEO_RGB_TO_YUV_MAT2_CAM0 0x11cc +#define NEO_RGB_TO_YUV_MAT2_CAM0_R1C0_MASK GENMASK(15, 0) +#define NEO_RGB_TO_YUV_MAT2_CAM0_R1C0_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_RGB_TO_YUV_MAT2_CAM0_R1C0_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_RGB_TO_YUV_MAT2_CAM0_R1C1_MASK GENMASK(31, 16) +#define NEO_RGB_TO_YUV_MAT2_CAM0_R1C1_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_RGB_TO_YUV_MAT2_CAM0_R1C1_GET(x) (((x) >> 16) & GENMASK(15, 0= )) + +#define NEO_RGB_TO_YUV_MAT3_CAM0 0x11d0 +#define NEO_RGB_TO_YUV_MAT3_CAM0_R1C2_MASK GENMASK(15, 0) +#define NEO_RGB_TO_YUV_MAT3_CAM0_R1C2_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_RGB_TO_YUV_MAT3_CAM0_R1C2_GET(x) (((x) >> 0) & GENMASK(15, 0)) + +#define NEO_RGB_TO_YUV_MAT4_CAM0 0x11d4 +#define NEO_RGB_TO_YUV_MAT4_CAM0_R2C0_MASK GENMASK(15, 0) +#define NEO_RGB_TO_YUV_MAT4_CAM0_R2C0_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_RGB_TO_YUV_MAT4_CAM0_R2C0_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_RGB_TO_YUV_MAT4_CAM0_R2C1_MASK GENMASK(31, 16) +#define NEO_RGB_TO_YUV_MAT4_CAM0_R2C1_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_RGB_TO_YUV_MAT4_CAM0_R2C1_GET(x) (((x) >> 16) & GENMASK(15, 0= )) + +#define NEO_RGB_TO_YUV_MAT5_CAM0 0x11d8 +#define NEO_RGB_TO_YUV_MAT5_CAM0_R2C2_MASK GENMASK(15, 0) +#define NEO_RGB_TO_YUV_MAT5_CAM0_R2C2_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_RGB_TO_YUV_MAT5_CAM0_R2C2_GET(x) (((x) >> 0) & GENMASK(15, 0)) + +#define NEO_RGB_TO_YUV_OFFSET0_CAM0 0x11e0 +#define NEO_RGB_TO_YUV_OFFSET0_CAM0_OFFSET_MASK GENMASK(20, 0) +#define NEO_RGB_TO_YUV_OFFSET0_CAM0_OFFSET_SET(x) (((x) & GENMASK(20, 0)) = << 0) +#define NEO_RGB_TO_YUV_OFFSET0_CAM0_OFFSET_GET(x) (((x) >> 0) & GENMASK(2= 0, 0)) + +#define NEO_RGB_TO_YUV_OFFSET1_CAM0 0x11e4 +#define NEO_RGB_TO_YUV_OFFSET1_CAM0_OFFSET_MASK GENMASK(20, 0) +#define NEO_RGB_TO_YUV_OFFSET1_CAM0_OFFSET_SET(x) (((x) & GENMASK(20, 0)) = << 0) +#define NEO_RGB_TO_YUV_OFFSET1_CAM0_OFFSET_GET(x) (((x) >> 0) & GENMASK(2= 0, 0)) + +#define NEO_RGB_TO_YUV_OFFSET2_CAM0 0x11e8 +#define NEO_RGB_TO_YUV_OFFSET2_CAM0_OFFSET_MASK GENMASK(20, 0) +#define NEO_RGB_TO_YUV_OFFSET2_CAM0_OFFSET_SET(x) (((x) & GENMASK(20, 0)) = << 0) +#define NEO_RGB_TO_YUV_OFFSET2_CAM0_OFFSET_GET(x) (((x) >> 0) & GENMASK(2= 0, 0)) + +/* DRC */ +#define NEO_DRC_ROI0_POS_CAM0 0x1300 +#define NEO_DRC_ROI0_POS_CAM0_XPOS_MASK GENMASK(15, 0) +#define NEO_DRC_ROI0_POS_CAM0_XPOS_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_DRC_ROI0_POS_CAM0_XPOS_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_DRC_ROI0_POS_CAM0_YPOS_MASK GENMASK(31, 16) +#define NEO_DRC_ROI0_POS_CAM0_YPOS_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_DRC_ROI0_POS_CAM0_YPOS_GET(x) (((x) >> 16) & GENMASK(15, 0)) + +#define NEO_DRC_ROI0_SIZE_CAM0 0x1304 +#define NEO_DRC_ROI0_SIZE_CAM0_WIDTH_MASK GENMASK(15, 0) +#define NEO_DRC_ROI0_SIZE_CAM0_WIDTH_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_DRC_ROI0_SIZE_CAM0_WIDTH_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_DRC_ROI0_SIZE_CAM0_HEIGHT_MASK GENMASK(31, 16) +#define NEO_DRC_ROI0_SIZE_CAM0_HEIGHT_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_DRC_ROI0_SIZE_CAM0_HEIGHT_GET(x) (((x) >> 16) & GENMASK(15, 0= )) + +#define NEO_DRC_ROI1_POS_CAM0 0x1308 +#define NEO_DRC_ROI1_POS_CAM0_XPOS_MASK GENMASK(15, 0) +#define NEO_DRC_ROI1_POS_CAM0_XPOS_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_DRC_ROI1_POS_CAM0_XPOS_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_DRC_ROI1_POS_CAM0_YPOS_MASK GENMASK(31, 16) +#define NEO_DRC_ROI1_POS_CAM0_YPOS_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_DRC_ROI1_POS_CAM0_YPOS_GET(x) (((x) >> 16) & GENMASK(15, 0)) + +#define NEO_DRC_ROI1_SIZE_CAM0 0x130c +#define NEO_DRC_ROI1_SIZE_CAM0_WIDTH_MASK GENMASK(15, 0) +#define NEO_DRC_ROI1_SIZE_CAM0_WIDTH_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_DRC_ROI1_SIZE_CAM0_WIDTH_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_DRC_ROI1_SIZE_CAM0_HEIGHT_MASK GENMASK(31, 16) +#define NEO_DRC_ROI1_SIZE_CAM0_HEIGHT_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_DRC_ROI1_SIZE_CAM0_HEIGHT_GET(x) (((x) >> 16) & GENMASK(15, 0= )) + +#define NEO_DRC_GROI_SUM_SHIFT_CAM0 0x1310 +#define NEO_DRC_GROI_SUM_SHIFT_CAM0_SHIFT0_MASK GENMASK(4, 0) +#define NEO_DRC_GROI_SUM_SHIFT_CAM0_SHIFT0_SET(x) (((x) & GENMASK(4, 0)) <= < 0) +#define NEO_DRC_GROI_SUM_SHIFT_CAM0_SHIFT0_GET(x) (((x) >> 0) & GENMASK(4= , 0)) +#define NEO_DRC_GROI_SUM_SHIFT_CAM0_SHIFT1_MASK GENMASK(20, 16) +#define NEO_DRC_GROI_SUM_SHIFT_CAM0_SHIFT1_SET(x) (((x) & GENMASK(4, 0)) <= < 16) +#define NEO_DRC_GROI_SUM_SHIFT_CAM0_SHIFT1_GET(x) (((x) >> 16) & GENMASK(= 4, 0)) + +#define NEO_DRC_GBL_GAIN_CAM0 0x1314 +#define NEO_DRC_GBL_GAIN_CAM0_GAIN_MASK GENMASK(15, 0) +#define NEO_DRC_GBL_GAIN_CAM0_GAIN_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_DRC_GBL_GAIN_CAM0_GAIN_GET(x) (((x) >> 0) & GENMASK(15, 0)) + +#define NEO_DRC_LCL_BLK_SIZE_CAM0 0x1320 +#define NEO_DRC_LCL_BLK_SIZE_CAM0_XSIZE_MASK GENMASK(15, 0) +#define NEO_DRC_LCL_BLK_SIZE_CAM0_XSIZE_SET(x) (((x) & GENMASK(15, 0)) << = 0) +#define NEO_DRC_LCL_BLK_SIZE_CAM0_XSIZE_GET(x) (((x) >> 0) & GENMASK(15, = 0)) +#define NEO_DRC_LCL_BLK_SIZE_CAM0_YSIZE_MASK GENMASK(31, 16) +#define NEO_DRC_LCL_BLK_SIZE_CAM0_YSIZE_SET(x) (((x) & GENMASK(15, 0)) << = 16) +#define NEO_DRC_LCL_BLK_SIZE_CAM0_YSIZE_GET(x) (((x) >> 16) & GENMASK(15,= 0)) + +#define NEO_DRC_LCL_STRETCH_CAM0 0x1324 +#define NEO_DRC_LCL_STRETCH_CAM0_STRETCH_MASK GENMASK(15, 0) +#define NEO_DRC_LCL_STRETCH_CAM0_STRETCH_SET(x) (((x) & GENMASK(15, 0)) <<= 0) +#define NEO_DRC_LCL_STRETCH_CAM0_STRETCH_GET(x) (((x) >> 0) & GENMASK(15,= 0)) +#define NEO_DRC_LCL_STRETCH_CAM0_OFFSET_MASK GENMASK(31, 16) +#define NEO_DRC_LCL_STRETCH_CAM0_OFFSET_SET(x) (((x) & GENMASK(15, 0)) << = 16) +#define NEO_DRC_LCL_STRETCH_CAM0_OFFSET_GET(x) (((x) >> 16) & GENMASK(15,= 0)) + +#define NEO_DRC_LCL_BLK_STEPY_CAM0 0x1328 +#define NEO_DRC_LCL_BLK_STEPY_CAM0_STEP_MASK GENMASK(15, 0) +#define NEO_DRC_LCL_BLK_STEPY_CAM0_STEP_SET(x) (((x) & GENMASK(15, 0)) << = 0) +#define NEO_DRC_LCL_BLK_STEPY_CAM0_STEP_GET(x) (((x) >> 0) & GENMASK(15, = 0)) + +#define NEO_DRC_LCL_BLK_STEPX_CAM0 0x132c +#define NEO_DRC_LCL_BLK_STEPX_CAM0_STEP_MASK GENMASK(15, 0) +#define NEO_DRC_LCL_BLK_STEPX_CAM0_STEP_SET(x) (((x) & GENMASK(15, 0)) << = 0) +#define NEO_DRC_LCL_BLK_STEPX_CAM0_STEP_GET(x) (((x) >> 0) & GENMASK(15, = 0)) + +#define NEO_DRC_LCL_SUM_SHIFT_CAM0 0x1330 +#define NEO_DRC_LCL_SUM_SHIFT_CAM0_SHIFT_MASK GENMASK(4, 0) +#define NEO_DRC_LCL_SUM_SHIFT_CAM0_SHIFT_SET(x) (((x) & GENMASK(4, 0)) << = 0) +#define NEO_DRC_LCL_SUM_SHIFT_CAM0_SHIFT_GET(x) (((x) >> 0) & GENMASK(4, = 0)) + +#define NEO_DRC_ALPHA_CAM0 0x1334 +#define NEO_DRC_ALPHA_CAM0_ALPHA_MASK GENMASK(8, 0) +#define NEO_DRC_ALPHA_CAM0_ALPHA_SET(x) (((x) & GENMASK(8, 0)) << 0) +#define NEO_DRC_ALPHA_CAM0_ALPHA_GET(x) (((x) >> 0) & 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_MASK GENMASK(15, 0) +#define NEO_DRC_STAT_BLK_Y_CAM0_BLKLNE_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_DRC_STAT_BLK_Y_CAM0_BLKLNE_GET(x) (((x) >> 0) & GENMASK(15, 0= )) +#define NEO_DRC_STAT_BLK_Y_CAM0_BLKROW_MASK GENMASK(23, 16) +#define NEO_DRC_STAT_BLK_Y_CAM0_BLKROW_SET(x) (((x) & GENMASK(7, 0)) << 16) +#define NEO_DRC_STAT_BLK_Y_CAM0_BLKROW_GET(x) (((x) >> 16) & GENMASK(7, 0= )) + +#define NEO_DRC_CURR_YFRACT_CAM0 0x1354 + +/* NR */ +#define NEO_NR_CTRL_CAM0 0x1400 +#define NEO_NR_CTRL_CAM0_DEBUG_MASK GENMASK(9, 8) +#define NEO_NR_CTRL_CAM0_DEBUG_SET(x) (((x) & GENMASK(1, 0)) << 8) +#define NEO_NR_CTRL_CAM0_DEBUG_GET(x) (((x) >> 8) & GENMASK(1, 0)) +#define NEO_NR_CTRL_CAM0_ENABLE BIT(31) +#define NEO_NR_CTRL_CAM0_ENABLE_SET(x) (((x) << 31) & BIT(31)) + +#define NEO_NR_BLEND_SCALE_CAM0 0x1404 +#define NEO_NR_BLEND_SCALE_CAM0_SCALE_MASK GENMASK(15, 0) +#define NEO_NR_BLEND_SCALE_CAM0_SCALE_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_NR_BLEND_SCALE_CAM0_SCALE_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_NR_BLEND_SCALE_CAM0_SHIFT_MASK GENMASK(23, 16) +#define NEO_NR_BLEND_SCALE_CAM0_SHIFT_SET(x) (((x) & GENMASK(7, 0)) << 16) +#define NEO_NR_BLEND_SCALE_CAM0_SHIFT_GET(x) (((x) >> 16) & GENMASK(7, 0)) +#define NEO_NR_BLEND_SCALE_CAM0_GAIN_MASK GENMASK(31, 24) +#define NEO_NR_BLEND_SCALE_CAM0_GAIN_SET(x) (((x) & GENMASK(7, 0)) << 24) +#define NEO_NR_BLEND_SCALE_CAM0_GAIN_GET(x) (((x) >> 24) & GENMASK(7, 0)) + +#define NEO_NR_BLEND_TH0_CAM0 0x1408 +#define NEO_NR_BLEND_TH0_CAM0_TH_MASK GENMASK(19, 0) +#define NEO_NR_BLEND_TH0_CAM0_TH_SET(x) (((x) & GENMASK(19, 0)) << 0) +#define NEO_NR_BLEND_TH0_CAM0_TH_GET(x) (((x) >> 0) & GENMASK(19, 0)) + +#define NEO_NR_EDGECNT_CAM0 0x1410 +#define NEO_NR_EDGECNT_CAM0_EDGE_PIXELS_MASK GENMASK(23, 0) +#define NEO_NR_EDGECNT_CAM0_EDGE_PIXELS_SET(x) (((x) & GENMASK(23, 0)) << = 0) +#define NEO_NR_EDGECNT_CAM0_EDGE_PIXELS_GET(x) (((x) >> 0) & GENMASK(23, = 0)) + +/* DF */ +#define NEO_DF_CTRL_CAM0 0x1440 +#define NEO_DF_CTRL_CAM0_DEBUG_MASK GENMASK(10, 8) +#define NEO_DF_CTRL_CAM0_DEBUG_SET(x) (((x) & GENMASK(2, 0)) << 8) +#define NEO_DF_CTRL_CAM0_DEBUG_GET(x) (((x) >> 8) & GENMASK(2, 0)) +#define NEO_DF_CTRL_CAM0_ENABLE BIT(31) +#define NEO_DF_CTRL_CAM0_ENABLE_SET(x) (((x) << 31) & BIT(31)) + +#define NEO_DF_TH_SCALE_CAM0 0x1444 +#define NEO_DF_TH_SCALE_CAM0_SCALE_MASK GENMASK(19, 0) +#define NEO_DF_TH_SCALE_CAM0_SCALE_SET(x) (((x) & GENMASK(19, 0)) << 0) +#define NEO_DF_TH_SCALE_CAM0_SCALE_GET(x) (((x) >> 0) & GENMASK(19, 0)) + +#define NEO_DF_BLEND_SHIFT_CAM0 0x1448 +#define NEO_DF_BLEND_SHIFT_CAM0_SHIFT_MASK GENMASK(5, 0) +#define NEO_DF_BLEND_SHIFT_CAM0_SHIFT_SET(x) (((x) & GENMASK(5, 0)) << 0) +#define NEO_DF_BLEND_SHIFT_CAM0_SHIFT_GET(x) (((x) >> 0) & GENMASK(5, 0)) + +#define NEO_DF_BLEND_TH0_CAM0 0x144c +#define NEO_DF_BLEND_TH0_CAM0_TH_MASK GENMASK(19, 0) +#define NEO_DF_BLEND_TH0_CAM0_TH_SET(x) (((x) & GENMASK(19, 0)) << 0) +#define NEO_DF_BLEND_TH0_CAM0_TH_GET(x) (((x) >> 0) & GENMASK(19, 0)) + +#define NEO_DF_EDGECNT_CAM0 0x1450 +#define NEO_DF_EDGECNT_CAM0_EDGE_PIXELS_MASK GENMASK(23, 0) +#define NEO_DF_EDGECNT_CAM0_EDGE_PIXELS_GET(x) (((x) >> 0) & GENMASK(23, = 0)) + +/* EE */ +#define NEO_EE_CTRL_CAM0 0x1480 +#define NEO_EE_CTRL_CAM0_DEBUG_MASK GENMASK(9, 8) +#define NEO_EE_CTRL_CAM0_DEBUG_SET(x) (((x) & GENMASK(1, 0)) << 8) +#define NEO_EE_CTRL_CAM0_DEBUG_GET(x) (((x) >> 8) & GENMASK(1, 0)) +#define NEO_EE_CTRL_CAM0_ENABLE BIT(31) +#define NEO_EE_CTRL_CAM0_ENABLE_SET(x) (((x) << 31) & BIT(31)) + +#define NEO_EE_CORING_CAM0 0x1484 +#define NEO_EE_CORING_CAM0_CORING_MASK GENMASK(19, 0) +#define NEO_EE_CORING_CAM0_CORING_SET(x) (((x) & GENMASK(19, 0)) << 0) +#define NEO_EE_CORING_CAM0_CORING_GET(x) (((x) >> 0) & GENMASK(19, 0)) + +#define NEO_EE_CLIP_CAM0 0x1488 +#define NEO_EE_CLIP_CAM0_CLIP_MASK GENMASK(19, 0) +#define NEO_EE_CLIP_CAM0_CLIP_SET(x) (((x) & GENMASK(19, 0)) << 0) +#define NEO_EE_CLIP_CAM0_CLIP_GET(x) (((x) >> 0) & GENMASK(19, 0)) + +#define NEO_EE_MASKGAIN_CAM0 0x148c +#define NEO_EE_MASKGAIN_CAM0_GAIN_MASK GENMASK(7, 0) +#define NEO_EE_MASKGAIN_CAM0_GAIN_SET(x) (((x) & GENMASK(7, 0)) << 0) +#define NEO_EE_MASKGAIN_CAM0_GAIN_GET(x) (((x) >> 0) & GENMASK(7, 0)) + +#define NEO_EE_EDGECNT_CAM0 0x1490 +#define NEO_EE_EDGECNT_CAM0_EDGE_PIXELS_MASK GENMASK(23, 0) +#define NEO_EE_EDGECNT_CAM0_EDGE_PIXELS_GET(x) (((x) >> 0) & GENMASK(23, = 0)) + +/* CCONVMED */ +#define NEO_CCONVMED_CTRL_CAM0 0x14c0 +#define NEO_CCONVMED_CTRL_CAM0_FLT_MASK GENMASK(5, 4) +#define NEO_CCONVMED_CTRL_CAM0_FLT_SET(x) (((x) & GENMASK(1, 0)) << 4) +#define NEO_CCONVMED_CTRL_CAM0_FLT_GET(x) (((x) >> 4) & GENMASK(1, 0)) + +/* CAS */ +#define NEO_CAS_GAIN_CAM0 0x1504 +#define NEO_CAS_GAIN_CAM0_SCALE_MASK GENMASK(15, 0) +#define NEO_CAS_GAIN_CAM0_SCALE_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_CAS_GAIN_CAM0_SCALE_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_CAS_GAIN_CAM0_SHIFT_MASK GENMASK(23, 16) +#define NEO_CAS_GAIN_CAM0_SHIFT_SET(x) (((x) & GENMASK(7, 0)) << 16) +#define NEO_CAS_GAIN_CAM0_SHIFT_GET(x) (((x) >> 16) & GENMASK(7, 0)) + +#define NEO_CAS_CORR_CAM0 0x1508 +#define NEO_CAS_CORR_CAM0_CORR_MASK GENMASK(15, 0) +#define NEO_CAS_CORR_CAM0_CORR_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_CAS_CORR_CAM0_CORR_GET(x) (((x) >> 0) & GENMASK(15, 0)) + +#define NEO_CAS_OFFSET_CAM0 0x150c +#define NEO_CAS_OFFSET_CAM0_OFFSET_MASK GENMASK(15, 0) +#define NEO_CAS_OFFSET_CAM0_OFFSET_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_CAS_OFFSET_CAM0_OFFSET_GET(x) (((x) >> 0) & GENMASK(15, 0)) + +/* PACKETIZER */ +#define NEO_PACKETIZER_CH0_CTRL_CAM0 0x1580 +#define NEO_PACKETIZER_CH0_CTRL_CAM0_OBPP_MASK GENMASK(3, 0) +#define NEO_PACKETIZER_CH0_CTRL_CAM0_OBPP_SET(x) (((x) & GENMASK(3, 0)) <<= 0) +#define NEO_PACKETIZER_CH0_CTRL_CAM0_OBPP_GET(x) (((x) >> 0) & GENMASK(3,= 0)) +#define NEO_PACKETIZER_CH0_CTRL_CAM0_RSA_MASK GENMASK(10, 8) +#define NEO_PACKETIZER_CH0_CTRL_CAM0_RSA_SET(x) (((x) & GENMASK(2, 0)) << = 8) +#define NEO_PACKETIZER_CH0_CTRL_CAM0_RSA_GET(x) (((x) >> 8) & GENMASK(2, = 0)) +#define NEO_PACKETIZER_CH0_CTRL_CAM0_LSA_MASK GENMASK(14, 12) +#define NEO_PACKETIZER_CH0_CTRL_CAM0_LSA_SET(x) (((x) & GENMASK(2, 0)) << = 12) +#define NEO_PACKETIZER_CH0_CTRL_CAM0_LSA_GET(x) (((x) >> 12) & GENMASK(2,= 0)) + +#define NEO_PACKETIZER_CH12_CTRL_CAM0 0x1584 +#define NEO_PACKETIZER_CH12_CTRL_CAM0_OBPP_MASK GENMASK(3, 0) +#define NEO_PACKETIZER_CH12_CTRL_CAM0_OBPP_SET(x) (((x) & GENMASK(3, 0)) <= < 0) +#define NEO_PACKETIZER_CH12_CTRL_CAM0_OBPP_GET(x) (((x) >> 0) & GENMASK(3= , 0)) +#define NEO_PACKETIZER_CH12_CTRL_CAM0_RSA_MASK GENMASK(10, 8) +#define NEO_PACKETIZER_CH12_CTRL_CAM0_RSA_SET(x) (((x) & GENMASK(2, 0)) <<= 8) +#define NEO_PACKETIZER_CH12_CTRL_CAM0_RSA_GET(x) (((x) >> 8) & GENMASK(2,= 0)) +#define NEO_PACKETIZER_CH12_CTRL_CAM0_LSA_MASK GENMASK(14, 12) +#define NEO_PACKETIZER_CH12_CTRL_CAM0_LSA_SET(x) (((x) & GENMASK(2, 0)) <<= 12) +#define NEO_PACKETIZER_CH12_CTRL_CAM0_LSA_GET(x) (((x) >> 12) & GENMASK(2= , 0)) +#define NEO_PACKETIZER_CH12_CTRL_CAM0_SUBSAMPLE_MASK GENMASK(17, 16) +#define NEO_PACKETIZER_CH12_CTRL_CAM0_SUBSAMPLE_SET(x) (((x) & GENMASK(1, = 0)) << 16) +#define NEO_PACKETIZER_CH12_CTRL_CAM0_SUBSAMPLE_GET(x) (((x) >> 16) & GEN= MASK(1, 0)) + +#define NEO_PACKETIZER_PACK_CTRL_CAM0 0x1588 +#define NEO_PACKETIZER_PACK_CTRL_CAM0_TYPE BIT(0) +#define NEO_PACKETIZER_PACK_CTRL_CAM0_TYPE_SET(x) ((x) & BIT(0)) +#define NEO_PACKETIZER_PACK_CTRL_CAM0_ORDER0_MASK GENMASK(9, 8) +#define NEO_PACKETIZER_PACK_CTRL_CAM0_ORDER0_SET(x) (((x) & GENMASK(1, 0))= << 8) +#define NEO_PACKETIZER_PACK_CTRL_CAM0_ORDER0_GET(x) (((x) >> 8) & GENMASK= (1, 0)) +#define NEO_PACKETIZER_PACK_CTRL_CAM0_ORDER1_MASK GENMASK(11, 10) +#define NEO_PACKETIZER_PACK_CTRL_CAM0_ORDER1_SET(x) (((x) & GENMASK(1, 0))= << 10) +#define NEO_PACKETIZER_PACK_CTRL_CAM0_ORDER1_GET(x) (((x) >> 10) & GENMAS= K(1, 0)) +#define NEO_PACKETIZER_PACK_CTRL_CAM0_ORDER2_MASK GENMASK(13, 12) +#define NEO_PACKETIZER_PACK_CTRL_CAM0_ORDER2_SET(x) (((x) & GENMASK(1, 0))= << 12) +#define NEO_PACKETIZER_PACK_CTRL_CAM0_ORDER2_GET(x) (((x) >> 12) & GENMAS= K(1, 0)) +#define NEO_PACKETIZER_PACK_CTRL_CAM0_A0S_MASK GENMASK(19, 16) +#define NEO_PACKETIZER_PACK_CTRL_CAM0_A0S_SET(x) (((x) & GENMASK(3, 0)) <<= 16) +#define NEO_PACKETIZER_PACK_CTRL_CAM0_A0S_GET(x) (((x) >> 16) & GENMASK(3= , 0)) + +/* GCM */ +#define NEO_GCM_IMAT0_CAM0 0x1600 +#define NEO_GCM_IMAT0_CAM0_R0C0_MASK GENMASK(15, 0) +#define NEO_GCM_IMAT0_CAM0_R0C0_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_GCM_IMAT0_CAM0_R0C0_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_GCM_IMAT0_CAM0_R0C1_MASK GENMASK(31, 16) +#define NEO_GCM_IMAT0_CAM0_R0C1_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_GCM_IMAT0_CAM0_R0C1_GET(x) (((x) >> 16) & GENMASK(15, 0)) + +#define NEO_GCM_IMAT1_CAM0 0x1604 +#define NEO_GCM_IMAT1_CAM0_R0C2_MASK GENMASK(15, 0) +#define NEO_GCM_IMAT1_CAM0_R0C2_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_GCM_IMAT1_CAM0_R0C2_GET(x) (((x) >> 0) & GENMASK(15, 0)) + +#define NEO_GCM_IMAT2_CAM0 0x160c +#define NEO_GCM_IMAT2_CAM0_R1C0_MASK GENMASK(15, 0) +#define NEO_GCM_IMAT2_CAM0_R1C0_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_GCM_IMAT2_CAM0_R1C0_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_GCM_IMAT2_CAM0_R1C1_MASK GENMASK(31, 16) +#define NEO_GCM_IMAT2_CAM0_R1C1_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_GCM_IMAT2_CAM0_R1C1_GET(x) (((x) >> 16) & GENMASK(15, 0)) + +#define NEO_GCM_IMAT3_CAM0 0x1610 +#define NEO_GCM_IMAT3_CAM0_R1C2_MASK GENMASK(15, 0) +#define NEO_GCM_IMAT3_CAM0_R1C2_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_GCM_IMAT3_CAM0_R1C2_GET(x) (((x) >> 0) & GENMASK(15, 0)) + +#define NEO_GCM_IMAT4_CAM0 0x1618 +#define NEO_GCM_IMAT4_CAM0_R2C0_MASK GENMASK(15, 0) +#define NEO_GCM_IMAT4_CAM0_R2C0_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_GCM_IMAT4_CAM0_R2C0_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_GCM_IMAT4_CAM0_R2C1_MASK GENMASK(31, 16) +#define NEO_GCM_IMAT4_CAM0_R2C1_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_GCM_IMAT4_CAM0_R2C1_GET(x) (((x) >> 16) & GENMASK(15, 0)) + +#define NEO_GCM_IMAT5_CAM0 0x161c +#define NEO_GCM_IMAT5_CAM0_R2C2_MASK GENMASK(15, 0) +#define NEO_GCM_IMAT5_CAM0_R2C2_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_GCM_IMAT5_CAM0_R2C2_GET(x) (((x) >> 0) & GENMASK(15, 0)) + +#define NEO_GCM_IOFFSET0_CAM0 0x1620 +#define NEO_GCM_IOFFSET0_CAM0_OFFSET0_MASK GENMASK(15, 0) +#define NEO_GCM_IOFFSET0_CAM0_OFFSET0_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_GCM_IOFFSET0_CAM0_OFFSET0_GET(x) (((x) >> 0) & GENMASK(15, 0)) + +#define NEO_GCM_IOFFSET1_CAM0 0x1624 +#define NEO_GCM_IOFFSET1_CAM0_OFFSET1_MASK GENMASK(15, 0) +#define NEO_GCM_IOFFSET1_CAM0_OFFSET1_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_GCM_IOFFSET1_CAM0_OFFSET1_GET(x) (((x) >> 0) & GENMASK(15, 0)) + +#define NEO_GCM_IOFFSET2_CAM0 0x1628 +#define NEO_GCM_IOFFSET2_CAM0_OFFSET2_MASK GENMASK(15, 0) +#define NEO_GCM_IOFFSET2_CAM0_OFFSET2_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_GCM_IOFFSET2_CAM0_OFFSET2_GET(x) (((x) >> 0) & GENMASK(15, 0)) + +#define NEO_GCM_OMAT0_CAM0 0x1630 +#define NEO_GCM_OMAT0_CAM0_R0C0_MASK GENMASK(15, 0) +#define NEO_GCM_OMAT0_CAM0_R0C0_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_GCM_OMAT0_CAM0_R0C0_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_GCM_OMAT0_CAM0_R0C1_MASK GENMASK(31, 16) +#define NEO_GCM_OMAT0_CAM0_R0C1_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_GCM_OMAT0_CAM0_R0C1_GET(x) (((x) >> 16) & GENMASK(15, 0)) + +#define NEO_GCM_OMAT1_CAM0 0x1634 +#define NEO_GCM_OMAT1_CAM0_R0C2_MASK GENMASK(15, 0) +#define NEO_GCM_OMAT1_CAM0_R0C2_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_GCM_OMAT1_CAM0_R0C2_GET(x) (((x) >> 0) & GENMASK(15, 0)) + +#define NEO_GCM_OMAT2_CAM0 0x1638 +#define NEO_GCM_OMAT2_CAM0_R1C0_MASK GENMASK(15, 0) +#define NEO_GCM_OMAT2_CAM0_R1C0_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_GCM_OMAT2_CAM0_R1C0_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_GCM_OMAT2_CAM0_R1C1_MASK GENMASK(31, 16) +#define NEO_GCM_OMAT2_CAM0_R1C1_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_GCM_OMAT2_CAM0_R1C1_GET(x) (((x) >> 16) & GENMASK(15, 0)) + +#define NEO_GCM_OMAT3_CAM0 0x163c +#define NEO_GCM_OMAT3_CAM0_R1C2_MASK GENMASK(15, 0) +#define NEO_GCM_OMAT3_CAM0_R1C2_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_GCM_OMAT3_CAM0_R1C2_GET(x) (((x) >> 0) & GENMASK(15, 0)) + +#define NEO_GCM_OMAT4_CAM0 0x1640 +#define NEO_GCM_OMAT4_CAM0_R2C0_MASK GENMASK(15, 0) +#define NEO_GCM_OMAT4_CAM0_R2C0_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_GCM_OMAT4_CAM0_R2C0_GET(x) (((x) >> 0) & GENMASK(15, 0)) +#define NEO_GCM_OMAT4_CAM0_R2C1_MASK GENMASK(31, 16) +#define NEO_GCM_OMAT4_CAM0_R2C1_SET(x) (((x) & GENMASK(15, 0)) << 16) +#define NEO_GCM_OMAT4_CAM0_R2C1_GET(x) (((x) >> 16) & GENMASK(15, 0)) + +#define NEO_GCM_OMAT5_CAM0 0x1644 +#define NEO_GCM_OMAT5_CAM0_R2C2_MASK GENMASK(15, 0) +#define NEO_GCM_OMAT5_CAM0_R2C2_SET(x) (((x) & GENMASK(15, 0)) << 0) +#define NEO_GCM_OMAT5_CAM0_R2C2_GET(x) (((x) >> 0) & GENMASK(15, 0)) + +#define NEO_GCM_OOFFSET0_CAM0 0x1648 +#define NEO_GCM_OOFFSET0_CAM0_OFFSET0_MASK GENMASK(12, 0) +#define NEO_GCM_OOFFSET0_CAM0_OFFSET0_SET(x) (((x) & GENMASK(12, 0)) << 0) +#define NEO_GCM_OOFFSET0_CAM0_OFFSET0_GET(x) (((x) >> 0) & GENMASK(12, 0)) + +#define NEO_GCM_OOFFSET1_CAM0 0x164c +#define NEO_GCM_OOFFSET1_CAM0_OFFSET1_MASK GENMASK(12, 0) +#define NEO_GCM_OOFFSET1_CAM0_OFFSET1_SET(x) (((x) & GENMASK(12, 0)) << 0) +#define NEO_GCM_OOFFSET1_CAM0_OFFSET1_GET(x) (((x) >> 0) & GENMASK(12, 0)) + +#define NEO_GCM_OOFFSET2_CAM0 0x1650 +#define NEO_GCM_OOFFSET2_CAM0_OFFSET2_MASK GENMASK(12, 0) +#define NEO_GCM_OOFFSET2_CAM0_OFFSET2_SET(x) (((x) & GENMASK(12, 0)) << 0) +#define NEO_GCM_OOFFSET2_CAM0_OFFSET2_GET(x) (((x) >> 0) & GENMASK(12, 0)) + +#define NEO_GCM_GAMMA0_CAM0 0x1660 +#define NEO_GCM_GAMMA0_CAM0_GAMMA0_MASK GENMASK(8, 0) +#define NEO_GCM_GAMMA0_CAM0_GAMMA0_SET(x) (((x) & GENMASK(8, 0)) << 0) +#define NEO_GCM_GAMMA0_CAM0_GAMMA0_GET(x) (((x) >> 0) & GENMASK(8, 0)) +#define NEO_GCM_GAMMA0_CAM0_OFFSET0_MASK GENMASK(27, 16) +#define NEO_GCM_GAMMA0_CAM0_OFFSET0_SET(x) (((x) & GENMASK(11, 0)) << 16) +#define NEO_GCM_GAMMA0_CAM0_OFFSET0_GET(x) (((x) >> 16) & GENMASK(11, 0)) + +#define NEO_GCM_GAMMA1_CAM0 0x1664 +#define NEO_GCM_GAMMA1_CAM0_GAMMA1_MASK GENMASK(8, 0) +#define NEO_GCM_GAMMA1_CAM0_GAMMA1_SET(x) (((x) & GENMASK(8, 0)) << 0) +#define NEO_GCM_GAMMA1_CAM0_GAMMA1_GET(x) (((x) >> 0) & GENMASK(8, 0)) +#define NEO_GCM_GAMMA1_CAM0_OFFSET1_MASK GENMASK(27, 16) +#define NEO_GCM_GAMMA1_CAM0_OFFSET1_SET(x) (((x) & GENMASK(11, 0)) << 16) +#define NEO_GCM_GAMMA1_CAM0_OFFSET1_GET(x) (((x) >> 16) & GENMASK(11, 0)) + +#define NEO_GCM_GAMMA2_CAM0 0x1668 +#define NEO_GCM_GAMMA2_CAM0_GAMMA2_MASK GENMASK(8, 0) +#define NEO_GCM_GAMMA2_CAM0_GAMMA2_SET(x) (((x) & GENMASK(8, 0)) << 0) +#define NEO_GCM_GAMMA2_CAM0_GAMMA2_GET(x) (((x) >> 0) & GENMASK(8, 0)) +#define NEO_GCM_GAMMA2_CAM0_OFFSET2_MASK GENMASK(27, 16) +#define NEO_GCM_GAMMA2_CAM0_OFFSET2_SET(x) (((x) & GENMASK(11, 0)) << 16) +#define NEO_GCM_GAMMA2_CAM0_OFFSET2_GET(x) (((x) >> 16) & GENMASK(11, 0)) + +#define NEO_GCM_BLKLVL0_CTRL_CAM0 0x166c +#define NEO_GCM_BLKLVL0_CTRL_CAM0_OFFSET0_MASK GENMASK(15, 0) +#define NEO_GCM_BLKLVL0_CTRL_CAM0_OFFSET0_SET(x) (((x) & GENMASK(15, 0)) <= < 0) +#define NEO_GCM_BLKLVL0_CTRL_CAM0_OFFSET0_GET(x) (((x) >> 0) & GENMASK(15= , 0)) +#define NEO_GCM_BLKLVL0_CTRL_CAM0_GAIN0_MASK GENMASK(31, 16) +#define NEO_GCM_BLKLVL0_CTRL_CAM0_GAIN0_SET(x) (((x) & GENMASK(15, 0)) << = 16) +#define NEO_GCM_BLKLVL0_CTRL_CAM0_GAIN0_GET(x) (((x) >> 16) & GENMASK(15,= 0)) + +#define NEO_GCM_BLKLVL1_CTRL_CAM0 0x1670 +#define NEO_GCM_BLKLVL1_CTRL_CAM0_OFFSET1_MASK GENMASK(15, 0) +#define NEO_GCM_BLKLVL1_CTRL_CAM0_OFFSET1_SET(x) (((x) & GENMASK(15, 0)) <= < 0) +#define NEO_GCM_BLKLVL1_CTRL_CAM0_OFFSET1_GET(x) (((x) >> 0) & GENMASK(15= , 0)) +#define NEO_GCM_BLKLVL1_CTRL_CAM0_GAIN1_MASK GENMASK(31, 16) +#define NEO_GCM_BLKLVL1_CTRL_CAM0_GAIN1_SET(x) (((x) & GENMASK(15, 0)) << = 16) +#define NEO_GCM_BLKLVL1_CTRL_CAM0_GAIN1_GET(x) (((x) >> 16) & GENMASK(15,= 0)) + +#define NEO_GCM_BLKLVL2_CTRL_CAM0 0x1674 +#define NEO_GCM_BLKLVL2_CTRL_CAM0_OFFSET2_MASK GENMASK(15, 0) +#define NEO_GCM_BLKLVL2_CTRL_CAM0_OFFSET2_SET(x) (((x) & GENMASK(15, 0)) <= < 0) +#define NEO_GCM_BLKLVL2_CTRL_CAM0_OFFSET2_GET(x) (((x) >> 0) & GENMASK(15= , 0)) +#define NEO_GCM_BLKLVL2_CTRL_CAM0_GAIN2_MASK GENMASK(31, 16) +#define NEO_GCM_BLKLVL2_CTRL_CAM0_GAIN2_SET(x) (((x) & GENMASK(15, 0)) << = 16) +#define NEO_GCM_BLKLVL2_CTRL_CAM0_GAIN2_GET(x) (((x) >> 16) & GENMASK(15,= 0)) + +#define NEO_GCM_LOWTH_CTRL01_CAM0 0x1678 +#define NEO_GCM_LOWTH_CTRL01_CAM0_THRESHOLD0_MASK GENMASK(15, 0) +#define NEO_GCM_LOWTH_CTRL01_CAM0_THRESHOLD0_SET(x) (((x) & GENMASK(15, 0)= ) << 0) +#define NEO_GCM_LOWTH_CTRL01_CAM0_THRESHOLD0_GET(x) (((x) >> 0) & GENMASK= (15, 0)) +#define NEO_GCM_LOWTH_CTRL01_CAM0_THRESHOLD1_MASK GENMASK(31, 16) +#define NEO_GCM_LOWTH_CTRL01_CAM0_THRESHOLD1_SET(x) (((x) & GENMASK(15, 0)= ) << 16) +#define NEO_GCM_LOWTH_CTRL01_CAM0_THRESHOLD1_GET(x) (((x) >> 16) & GENMAS= K(15, 0)) + +#define NEO_GCM_LOWTH_CTRL2_CAM0 0x167c +#define NEO_GCM_LOWTH_CTRL2_CAM0_THRESHOLD2_MASK GENMASK(15, 0) +#define NEO_GCM_LOWTH_CTRL2_CAM0_THRESHOLD2_SET(x) (((x) & GENMASK(15, 0))= << 0) +#define NEO_GCM_LOWTH_CTRL2_CAM0_THRESHOLD2_GET(x) (((x) >> 0) & GENMASK(= 15, 0)) + +#define NEO_GCM_MAT_CONFG_CAM0 0x1680 +#define NEO_GCM_MAT_CONFG_CAM0_SIGN_CONFG BIT(0) +#define NEO_GCM_MAT_CONFG_CAM0_SIGN_CONFG_SET(x) ((x) & BIT(0)) + +/* AUTOFOCUS */ +#define NEO_AUTOFOCUS_ROI0_POS_CAM0 0x1700 +#define NEO_AUTOFOCUS_ROI0_POS_CAM0_XPOS_MASK GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI0_POS_CAM0_XPOS_SET(x) (((x) & GENMASK(15, 0)) <<= 0) +#define NEO_AUTOFOCUS_ROI0_POS_CAM0_XPOS_GET(x) (((x) >> 0) & GENMASK(15,= 0)) +#define NEO_AUTOFOCUS_ROI0_POS_CAM0_YPOS_MASK GENMASK(31, 16) +#define NEO_AUTOFOCUS_ROI0_POS_CAM0_YPOS_SET(x) (((x) & GENMASK(15, 0)) <<= 16) +#define NEO_AUTOFOCUS_ROI0_POS_CAM0_YPOS_GET(x) (((x) >> 16) & GENMASK(15= , 0)) + +#define NEO_AUTOFOCUS_ROI0_SIZE_CAM0 0x1704 +#define NEO_AUTOFOCUS_ROI0_SIZE_CAM0_WIDTH_MASK GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI0_SIZE_CAM0_WIDTH_SET(x) (((x) & GENMASK(15, 0)) = << 0) +#define NEO_AUTOFOCUS_ROI0_SIZE_CAM0_WIDTH_GET(x) (((x) >> 0) & GENMASK(1= 5, 0)) +#define NEO_AUTOFOCUS_ROI0_SIZE_CAM0_HEIGHT_MASK GENMASK(31, 16) +#define NEO_AUTOFOCUS_ROI0_SIZE_CAM0_HEIGHT_SET(x) (((x) & GENMASK(15, 0))= << 16) +#define NEO_AUTOFOCUS_ROI0_SIZE_CAM0_HEIGHT_GET(x) (((x) >> 16) & GENMASK= (15, 0)) + +#define NEO_AUTOFOCUS_ROI1_POS_CAM0 0x1708 +#define NEO_AUTOFOCUS_ROI1_POS_CAM0_XPOS_MASK GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI1_POS_CAM0_XPOS_SET(x) (((x) & GENMASK(15, 0)) <<= 0) +#define NEO_AUTOFOCUS_ROI1_POS_CAM0_XPOS_GET(x) (((x) >> 0) & GENMASK(15,= 0)) +#define NEO_AUTOFOCUS_ROI1_POS_CAM0_YPOS_MASK GENMASK(31, 16) +#define NEO_AUTOFOCUS_ROI1_POS_CAM0_YPOS_SET(x) (((x) & GENMASK(15, 0)) <<= 16) +#define NEO_AUTOFOCUS_ROI1_POS_CAM0_YPOS_GET(x) (((x) >> 16) & GENMASK(15= , 0)) + +#define NEO_AUTOFOCUS_ROI1_SIZE_CAM0 0x170c +#define NEO_AUTOFOCUS_ROI1_SIZE_CAM0_WIDTH_MASK GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI1_SIZE_CAM0_WIDTH_SET(x) (((x) & GENMASK(15, 0)) = << 0) +#define NEO_AUTOFOCUS_ROI1_SIZE_CAM0_WIDTH_GET(x) (((x) >> 0) & GENMASK(1= 5, 0)) +#define NEO_AUTOFOCUS_ROI1_SIZE_CAM0_HEIGHT_MASK GENMASK(31, 16) +#define NEO_AUTOFOCUS_ROI1_SIZE_CAM0_HEIGHT_SET(x) (((x) & GENMASK(15, 0))= << 16) +#define NEO_AUTOFOCUS_ROI1_SIZE_CAM0_HEIGHT_GET(x) (((x) >> 16) & GENMASK= (15, 0)) + +#define NEO_AUTOFOCUS_ROI2_POS_CAM0 0x1710 +#define NEO_AUTOFOCUS_ROI2_POS_CAM0_XPOS_MASK GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI2_POS_CAM0_XPOS_SET(x) (((x) & GENMASK(15, 0)) <<= 0) +#define NEO_AUTOFOCUS_ROI2_POS_CAM0_XPOS_GET(x) (((x) >> 0) & GENMASK(15,= 0)) +#define NEO_AUTOFOCUS_ROI2_POS_CAM0_YPOS_MASK GENMASK(31, 16) +#define NEO_AUTOFOCUS_ROI2_POS_CAM0_YPOS_SET(x) (((x) & GENMASK(15, 0)) <<= 16) +#define NEO_AUTOFOCUS_ROI2_POS_CAM0_YPOS_GET(x) (((x) >> 16) & GENMASK(15= , 0)) + +#define NEO_AUTOFOCUS_ROI2_SIZE_CAM0 0x1714 +#define NEO_AUTOFOCUS_ROI2_SIZE_CAM0_WIDTH_MASK GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI2_SIZE_CAM0_WIDTH_SET(x) (((x) & GENMASK(15, 0)) = << 0) +#define NEO_AUTOFOCUS_ROI2_SIZE_CAM0_WIDTH_GET(x) (((x) >> 0) & GENMASK(1= 5, 0)) +#define NEO_AUTOFOCUS_ROI2_SIZE_CAM0_HEIGHT_MASK GENMASK(31, 16) +#define NEO_AUTOFOCUS_ROI2_SIZE_CAM0_HEIGHT_SET(x) (((x) & GENMASK(15, 0))= << 16) +#define NEO_AUTOFOCUS_ROI2_SIZE_CAM0_HEIGHT_GET(x) (((x) >> 16) & GENMASK= (15, 0)) + +#define NEO_AUTOFOCUS_ROI3_POS_CAM0 0x1718 +#define NEO_AUTOFOCUS_ROI3_POS_CAM0_XPOS_MASK GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI3_POS_CAM0_XPOS_SET(x) (((x) & GENMASK(15, 0)) <<= 0) +#define NEO_AUTOFOCUS_ROI3_POS_CAM0_XPOS_GET(x) (((x) >> 0) & GENMASK(15,= 0)) +#define NEO_AUTOFOCUS_ROI3_POS_CAM0_YPOS_MASK GENMASK(31, 16) +#define NEO_AUTOFOCUS_ROI3_POS_CAM0_YPOS_SET(x) (((x) & GENMASK(15, 0)) <<= 16) +#define NEO_AUTOFOCUS_ROI3_POS_CAM0_YPOS_GET(x) (((x) >> 16) & GENMASK(15= , 0)) + +#define NEO_AUTOFOCUS_ROI3_SIZE_CAM0 0x171c +#define NEO_AUTOFOCUS_ROI3_SIZE_CAM0_WIDTH_MASK GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI3_SIZE_CAM0_WIDTH_SET(x) (((x) & GENMASK(15, 0)) = << 0) +#define NEO_AUTOFOCUS_ROI3_SIZE_CAM0_WIDTH_GET(x) (((x) >> 0) & GENMASK(1= 5, 0)) +#define NEO_AUTOFOCUS_ROI3_SIZE_CAM0_HEIGHT_MASK GENMASK(31, 16) +#define NEO_AUTOFOCUS_ROI3_SIZE_CAM0_HEIGHT_SET(x) (((x) & GENMASK(15, 0))= << 16) +#define NEO_AUTOFOCUS_ROI3_SIZE_CAM0_HEIGHT_GET(x) (((x) >> 16) & GENMASK= (15, 0)) + +#define NEO_AUTOFOCUS_ROI4_POS_CAM0 0x1720 +#define NEO_AUTOFOCUS_ROI4_POS_CAM0_XPOS_MASK GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI4_POS_CAM0_XPOS_SET(x) (((x) & GENMASK(15, 0)) <<= 0) +#define NEO_AUTOFOCUS_ROI4_POS_CAM0_XPOS_GET(x) (((x) >> 0) & GENMASK(15,= 0)) +#define NEO_AUTOFOCUS_ROI4_POS_CAM0_YPOS_MASK GENMASK(31, 16) +#define NEO_AUTOFOCUS_ROI4_POS_CAM0_YPOS_SET(x) (((x) & GENMASK(15, 0)) <<= 16) +#define NEO_AUTOFOCUS_ROI4_POS_CAM0_YPOS_GET(x) (((x) >> 16) & GENMASK(15= , 0)) + +#define NEO_AUTOFOCUS_ROI4_SIZE_CAM0 0x1724 +#define NEO_AUTOFOCUS_ROI4_SIZE_CAM0_WIDTH_MASK GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI4_SIZE_CAM0_WIDTH_SET(x) (((x) & GENMASK(15, 0)) = << 0) +#define NEO_AUTOFOCUS_ROI4_SIZE_CAM0_WIDTH_GET(x) (((x) >> 0) & GENMASK(1= 5, 0)) +#define NEO_AUTOFOCUS_ROI4_SIZE_CAM0_HEIGHT_MASK GENMASK(31, 16) +#define NEO_AUTOFOCUS_ROI4_SIZE_CAM0_HEIGHT_SET(x) (((x) & GENMASK(15, 0))= << 16) +#define NEO_AUTOFOCUS_ROI4_SIZE_CAM0_HEIGHT_GET(x) (((x) >> 16) & GENMASK= (15, 0)) + +#define NEO_AUTOFOCUS_ROI5_POS_CAM0 0x1728 +#define NEO_AUTOFOCUS_ROI5_POS_CAM0_XPOS_MASK GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI5_POS_CAM0_XPOS_SET(x) (((x) & GENMASK(15, 0)) <<= 0) +#define NEO_AUTOFOCUS_ROI5_POS_CAM0_XPOS_GET(x) (((x) >> 0) & GENMASK(15,= 0)) +#define NEO_AUTOFOCUS_ROI5_POS_CAM0_YPOS_MASK GENMASK(31, 16) +#define NEO_AUTOFOCUS_ROI5_POS_CAM0_YPOS_SET(x) (((x) & GENMASK(15, 0)) <<= 16) +#define NEO_AUTOFOCUS_ROI5_POS_CAM0_YPOS_GET(x) (((x) >> 16) & GENMASK(15= , 0)) + +#define NEO_AUTOFOCUS_ROI5_SIZE_CAM0 0x172c +#define NEO_AUTOFOCUS_ROI5_SIZE_CAM0_WIDTH_MASK GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI5_SIZE_CAM0_WIDTH_SET(x) (((x) & GENMASK(15, 0)) = << 0) +#define NEO_AUTOFOCUS_ROI5_SIZE_CAM0_WIDTH_GET(x) (((x) >> 0) & GENMASK(1= 5, 0)) +#define NEO_AUTOFOCUS_ROI5_SIZE_CAM0_HEIGHT_MASK GENMASK(31, 16) +#define NEO_AUTOFOCUS_ROI5_SIZE_CAM0_HEIGHT_SET(x) (((x) & GENMASK(15, 0))= << 16) +#define NEO_AUTOFOCUS_ROI5_SIZE_CAM0_HEIGHT_GET(x) (((x) >> 16) & GENMASK= (15, 0)) + +#define NEO_AUTOFOCUS_ROI6_POS_CAM0 0x1730 +#define NEO_AUTOFOCUS_ROI6_POS_CAM0_XPOS_MASK GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI6_POS_CAM0_XPOS_SET(x) (((x) & GENMASK(15, 0)) <<= 0) +#define NEO_AUTOFOCUS_ROI6_POS_CAM0_XPOS_GET(x) (((x) >> 0) & GENMASK(15,= 0)) +#define NEO_AUTOFOCUS_ROI6_POS_CAM0_YPOS_MASK GENMASK(31, 16) +#define NEO_AUTOFOCUS_ROI6_POS_CAM0_YPOS_SET(x) (((x) & GENMASK(15, 0)) <<= 16) +#define NEO_AUTOFOCUS_ROI6_POS_CAM0_YPOS_GET(x) (((x) >> 16) & GENMASK(15= , 0)) + +#define NEO_AUTOFOCUS_ROI6_SIZE_CAM0 0x1734 +#define NEO_AUTOFOCUS_ROI6_SIZE_CAM0_WIDTH_MASK GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI6_SIZE_CAM0_WIDTH_SET(x) (((x) & GENMASK(15, 0)) = << 0) +#define NEO_AUTOFOCUS_ROI6_SIZE_CAM0_WIDTH_GET(x) (((x) >> 0) & GENMASK(1= 5, 0)) +#define NEO_AUTOFOCUS_ROI6_SIZE_CAM0_HEIGHT_MASK GENMASK(31, 16) +#define NEO_AUTOFOCUS_ROI6_SIZE_CAM0_HEIGHT_SET(x) (((x) & GENMASK(15, 0))= << 16) +#define NEO_AUTOFOCUS_ROI6_SIZE_CAM0_HEIGHT_GET(x) (((x) >> 16) & GENMASK= (15, 0)) + +#define NEO_AUTOFOCUS_ROI7_POS_CAM0 0x1738 +#define NEO_AUTOFOCUS_ROI7_POS_CAM0_XPOS_MASK GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI7_POS_CAM0_XPOS_SET(x) (((x) & GENMASK(15, 0)) <<= 0) +#define NEO_AUTOFOCUS_ROI7_POS_CAM0_XPOS_GET(x) (((x) >> 0) & GENMASK(15,= 0)) +#define NEO_AUTOFOCUS_ROI7_POS_CAM0_YPOS_MASK GENMASK(31, 16) +#define NEO_AUTOFOCUS_ROI7_POS_CAM0_YPOS_SET(x) (((x) & GENMASK(15, 0)) <<= 16) +#define NEO_AUTOFOCUS_ROI7_POS_CAM0_YPOS_GET(x) (((x) >> 16) & GENMASK(15= , 0)) + +#define NEO_AUTOFOCUS_ROI7_SIZE_CAM0 0x173c +#define NEO_AUTOFOCUS_ROI7_SIZE_CAM0_WIDTH_MASK GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI7_SIZE_CAM0_WIDTH_SET(x) (((x) & GENMASK(15, 0)) = << 0) +#define NEO_AUTOFOCUS_ROI7_SIZE_CAM0_WIDTH_GET(x) (((x) >> 0) & GENMASK(1= 5, 0)) +#define NEO_AUTOFOCUS_ROI7_SIZE_CAM0_HEIGHT_MASK GENMASK(31, 16) +#define NEO_AUTOFOCUS_ROI7_SIZE_CAM0_HEIGHT_SET(x) (((x) & GENMASK(15, 0))= << 16) +#define NEO_AUTOFOCUS_ROI7_SIZE_CAM0_HEIGHT_GET(x) (((x) >> 16) & GENMASK= (15, 0)) + +#define NEO_AUTOFOCUS_ROI8_POS_CAM0 0x1740 +#define NEO_AUTOFOCUS_ROI8_POS_CAM0_XPOS_MASK GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI8_POS_CAM0_XPOS_SET(x) (((x) & GENMASK(15, 0)) <<= 0) +#define NEO_AUTOFOCUS_ROI8_POS_CAM0_XPOS_GET(x) (((x) >> 0) & GENMASK(15,= 0)) +#define NEO_AUTOFOCUS_ROI8_POS_CAM0_YPOS_MASK GENMASK(31, 16) +#define NEO_AUTOFOCUS_ROI8_POS_CAM0_YPOS_SET(x) (((x) & GENMASK(15, 0)) <<= 16) +#define NEO_AUTOFOCUS_ROI8_POS_CAM0_YPOS_GET(x) (((x) >> 16) & GENMASK(15= , 0)) + +#define NEO_AUTOFOCUS_ROI8_SIZE_CAM0 0x1744 +#define NEO_AUTOFOCUS_ROI8_SIZE_CAM0_WIDTH_MASK GENMASK(15, 0) +#define NEO_AUTOFOCUS_ROI8_SIZE_CAM0_WIDTH_SET(x) (((x) & GENMASK(15, 0)) = << 0) +#define NEO_AUTOFOCUS_ROI8_SIZE_CAM0_WIDTH_GET(x) (((x) >> 0) & GENMASK(1= 5, 0)) +#define NEO_AUTOFOCUS_ROI8_SIZE_CAM0_HEIGHT_MASK GENMASK(31, 16) +#define NEO_AUTOFOCUS_ROI8_SIZE_CAM0_HEIGHT_SET(x) (((x) & GENMASK(15, 0))= << 16) +#define NEO_AUTOFOCUS_ROI8_SIZE_CAM0_HEIGHT_GET(x) (((x) >> 16) & GENMASK= (15, 0)) + +#define NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0 0x1750 +#define NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0_COEFF0_MASK GENMASK(7, 0) +#define NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0_COEFF0_SET(x) (((x) & GENMASK(7, 0= )) << 0) +#define NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0_COEFF0_GET(x) (((x) >> 0) & GENMA= SK(7, 0)) +#define NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0_COEFF1_MASK GENMASK(15, 8) +#define NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0_COEFF1_SET(x) (((x) & GENMASK(7, 0= )) << 8) +#define NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0_COEFF1_GET(x) (((x) >> 8) & GENMA= SK(7, 0)) +#define NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0_COEFF2_MASK GENMASK(23, 16) +#define NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0_COEFF2_SET(x) (((x) & GENMASK(7, 0= )) << 16) +#define NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0_COEFF2_GET(x) (((x) >> 16) & GENM= ASK(7, 0)) +#define NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0_COEFF3_MASK GENMASK(31, 24) +#define NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0_COEFF3_SET(x) (((x) & GENMASK(7, 0= )) << 24) +#define NEO_AUTOFOCUS_FIL0_COEFFS0_CAM0_COEFF3_GET(x) (((x) >> 24) & GENM= ASK(7, 0)) + +#define NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0 0x1754 +#define NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0_COEFF4_MASK GENMASK(7, 0) +#define NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0_COEFF4_SET(x) (((x) & GENMASK(7, 0= )) << 0) +#define NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0_COEFF4_GET(x) (((x) >> 0) & GENMA= SK(7, 0)) +#define NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0_COEFF5_MASK GENMASK(15, 8) +#define NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0_COEFF5_SET(x) (((x) & GENMASK(7, 0= )) << 8) +#define NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0_COEFF5_GET(x) (((x) >> 8) & GENMA= SK(7, 0)) +#define NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0_COEFF6_MASK GENMASK(23, 16) +#define NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0_COEFF6_SET(x) (((x) & GENMASK(7, 0= )) << 16) +#define NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0_COEFF6_GET(x) (((x) >> 16) & GENM= ASK(7, 0)) +#define NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0_COEFF7_MASK GENMASK(31, 24) +#define NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0_COEFF7_SET(x) (((x) & GENMASK(7, 0= )) << 24) +#define NEO_AUTOFOCUS_FIL0_COEFFS1_CAM0_COEFF7_GET(x) (((x) >> 24) & GENM= ASK(7, 0)) + +#define NEO_AUTOFOCUS_FIL0_COEFFS2_CAM0 0x1758 +#define NEO_AUTOFOCUS_FIL0_COEFFS2_CAM0_COEFF8_MASK GENMASK(7, 0) +#define NEO_AUTOFOCUS_FIL0_COEFFS2_CAM0_COEFF8_SET(x) (((x) & GENMASK(7, 0= )) << 0) +#define NEO_AUTOFOCUS_FIL0_COEFFS2_CAM0_COEFF8_GET(x) (((x) >> 0) & GENMA= SK(7, 0)) + +#define NEO_AUTOFOCUS_FIL0_SHIFT_CAM0 0x175c +#define NEO_AUTOFOCUS_FIL0_SHIFT_CAM0_SHIFT_MASK GENMASK(4, 0) +#define NEO_AUTOFOCUS_FIL0_SHIFT_CAM0_SHIFT_SET(x) (((x) & GENMASK(4, 0)) = << 0) +#define NEO_AUTOFOCUS_FIL0_SHIFT_CAM0_SHIFT_GET(x) (((x) >> 0) & GENMASK(= 4, 0)) + +#define NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0 0x1760 +#define NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0_COEFF0_MASK GENMASK(7, 0) +#define NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0_COEFF0_SET(x) (((x) & GENMASK(7, 0= )) << 0) +#define NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0_COEFF0_GET(x) (((x) >> 0) & GENMA= SK(7, 0)) +#define NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0_COEFF1_MASK GENMASK(15, 8) +#define NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0_COEFF1_SET(x) (((x) & GENMASK(7, 0= )) << 8) +#define NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0_COEFF1_GET(x) (((x) >> 8) & GENMA= SK(7, 0)) +#define NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0_COEFF2_MASK GENMASK(23, 16) +#define NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0_COEFF2_SET(x) (((x) & GENMASK(7, 0= )) << 16) +#define NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0_COEFF2_GET(x) (((x) >> 16) & GENM= ASK(7, 0)) +#define NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0_COEFF3_MASK GENMASK(31, 24) +#define NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0_COEFF3_SET(x) (((x) & GENMASK(7, 0= )) << 24) +#define NEO_AUTOFOCUS_FIL1_COEFFS0_CAM0_COEFF3_GET(x) (((x) >> 24) & GENM= ASK(7, 0)) + +#define NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0 0x1764 +#define NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0_COEFF4_MASK GENMASK(7, 0) +#define NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0_COEFF4_SET(x) (((x) & GENMASK(7, 0= )) << 0) +#define NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0_COEFF4_GET(x) (((x) >> 0) & GENMA= SK(7, 0)) +#define NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0_COEFF5_MASK GENMASK(15, 8) +#define NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0_COEFF5_SET(x) (((x) & GENMASK(7, 0= )) << 8) +#define NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0_COEFF5_GET(x) (((x) >> 8) & GENMA= SK(7, 0)) +#define NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0_COEFF6_MASK GENMASK(23, 16) +#define NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0_COEFF6_SET(x) (((x) & GENMASK(7, 0= )) << 16) +#define NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0_COEFF6_GET(x) (((x) >> 16) & GENM= ASK(7, 0)) +#define NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0_COEFF7_MASK GENMASK(31, 24) +#define NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0_COEFF7_SET(x) (((x) & GENMASK(7, 0= )) << 24) +#define NEO_AUTOFOCUS_FIL1_COEFFS1_CAM0_COEFF7_GET(x) (((x) >> 24) & GENM= ASK(7, 0)) + +#define NEO_AUTOFOCUS_FIL1_COEFFS2_CAM0 0x1768 +#define NEO_AUTOFOCUS_FIL1_COEFFS2_CAM0_COEFF8_MASK GENMASK(7, 0) +#define NEO_AUTOFOCUS_FIL1_COEFFS2_CAM0_COEFF8_SET(x) (((x) & GENMASK(7, 0= )) << 0) +#define NEO_AUTOFOCUS_FIL1_COEFFS2_CAM0_COEFF8_GET(x) (((x) >> 0) & GENMA= SK(7, 0)) + +#define NEO_AUTOFOCUS_FIL1_SHIFT_CAM0 0x176c +#define NEO_AUTOFOCUS_FIL1_SHIFT_CAM0_SHIFT_MASK GENMASK(4, 0) +#define NEO_AUTOFOCUS_FIL1_SHIFT_CAM0_SHIFT_SET(x) (((x) & GENMASK(4, 0)) = << 0) +#define NEO_AUTOFOCUS_FIL1_SHIFT_CAM0_SHIFT_GET(x) (((x) >> 0) & 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_MASK GENMASK(16, 0) +#define NEO_IDBG2_LINE_NUM_LINE_NUM_SET(x) (((x) & GENMASK(16, 0)) << 0) +#define NEO_IDBG2_LINE_NUM_LINE_NUM_GET(x) (((x) >> 0) & GENMASK(16, 0)) + +#define NEO_IDBG2_CURR_LINE_NUM 0x1fc4 +#define NEO_IDBG2_CURR_LINE_NUM_CURR_LINE_NUM_MASK GENMASK(16, 0) +#define NEO_IDBG2_CURR_LINE_NUM_CURR_LINE_NUM_SET(x) (((x) & GENMASK(16, 0= )) << 0) +#define NEO_IDBG2_CURR_LINE_NUM_CURR_LINE_NUM_GET(x) (((x) >> 0) & GENMAS= K(16, 0)) +#define NEO_IDBG2_CURR_LINE_NUM_DBG_HIT BIT(31) + +#define NEO_IDBG2_IMA 0x1fc8 +#define NEO_IDBG2_IMA_ADDR_MASK GENMASK(11, 0) +#define NEO_IDBG2_IMA_ADDR_SET(x) (((x) & GENMASK(11, 0)) << 0) +#define NEO_IDBG2_IMA_ADDR_GET(x) (((x) >> 0) & GENMASK(11, 0)) +#define NEO_IDBG2_IMA_NAME_MASK GENMASK(21, 16) +#define NEO_IDBG2_IMA_NAME_SET(x) (((x) & GENMASK(5, 0)) << 16) +#define NEO_IDBG2_IMA_NAME_GET(x) (((x) >> 16) & GENMASK(5, 0)) +#define NEO_IDBG2_IMA_RDWF_MASK GENMASK(29, 28) +#define NEO_IDBG2_IMA_RDWF_SET(x) (((x) & GENMASK(1, 0)) << 28) +#define NEO_IDBG2_IMA_RDWF_GET(x) (((x) >> 28) & GENMASK(1, 0)) +#define NEO_IDBG2_IMA_WDWF_MASK GENMASK(31, 30) +#define NEO_IDBG2_IMA_WDWF_SET(x) (((x) & GENMASK(1, 0)) << 30) +#define NEO_IDBG2_IMA_WDWF_GET(x) (((x) >> 30) & GENMASK(1, 0)) + +#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.52.0 From nobody Sat Feb 7 07:31:36 2026 Received: from PA4PR04CU001.outbound.protection.outlook.com (mail-francecentralazon11013031.outbound.protection.outlook.com [40.107.162.31]) (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 5AC7A33EAE0; Fri, 23 Jan 2026 08:06:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.162.31 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769155603; cv=fail; b=GA0LANq3WIFu7BW/pzD4rwlQ24Cgftoo/QjSyRnZn8dy6MyvfPzUeIP3XKoaYMzn9Et2r9UKt+zaohuRm4v/1Ydkk3ZWRQrs2gdRVPFNVjHKuKQHpjqMF8FM2rddea4Re/I8C5BLyeIpn/c1O2zpK5iYZDh4LC9nEu70E1ym9oo= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769155603; c=relaxed/simple; bh=ISyhDkDup93TvG+tu/tkao0yiIvTCfA0oR6n7rTRjY0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=NmAArAjvCMUznjfARVorMd8HiEvwCfjmd+Mkibyr0DBMP51a1fFrlSf/JRc2KI01YVabsxUC4nuEV6UeO/smerRtXGBRWLqJVWI7dKUXSZpaZs5oBgnE7rm/BubnZIinZwzx05p1iOdzHxudIUYCmkBPsVPUoZIYn02lDLCd8IU= 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=KJgvMn04; arc=fail smtp.client-ip=40.107.162.31 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="KJgvMn04" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=GwPIlXuWxsnOe+LRG0ML3Vr21BhBL3feenBHDWq7wbNKVbosS69BooeiC6k0H69gq7r63pWSD0uT2Z84pJ9KSFmwJx0hqJACvBdCkZepSitHQT6SC9aqQZZBjcjZrGMdNtzaQtDZSPmfsSIrp54GuCySRHMouVaz/02xEjz85ScjaOzgKiIVmloHsUEHxW/UQ6BoLt1mOtKYgx2vfkrgPVw8H1EJXGvUbA2TsL5wLs6Ofxx/Ggyfx5y4Y83Wa/ESldpzJsu+e9gxYen56s0WyymH8zSkyEtJuKYYo3BwZPvE0utmqXQyA+IwIOFaihn90eEaxvB9bw8l9/5P1n08FQ== 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=FROKsA3yvhUyBmpeJ2BIDuRWG2TwaPrnPwJg0LIVHqI=; b=DnF0dugEyBs+88qe+fPE7UVkBs+800lrRstf8wqCmueO0YbM1DIniBzxoFGqDafyD60ZxY8ABDgKGxBu8Nn5ijTlR1yCnGOxaL9IcsoId9P1YVyV7ToZTjZD754riiqjVGg7jfr0J+eCyufYrqLt7PPXu9QDs1n1EIgR1KCRtHm3tUY5ReoPBtQRt3dP4kSi+N0pnxIxShwQkjMz+G9uXVnYyezW2bJrF2uIE7lZlYU1jMoSCr4u2bBF1VmXNVEdj161cgeuac/odMcsyqp4xVwd3hBPwMcmRTo11Yogu2t81VWUCQLbPXVyfMkhT0yQCJiOaZJVWQOyPaI9/dnz+w== 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=FROKsA3yvhUyBmpeJ2BIDuRWG2TwaPrnPwJg0LIVHqI=; b=KJgvMn048qGGM+Dj4YeUJW+k6sbWN5Uh3har/FABxZx4r7pP4JUehkj12oXcSt9yKEulZMSlNSjtzqzqxKjx081pDIrbx/ROBSim8a2kmOJSuaAueJdpt4MT0o3AvPJbTAoAO6p9hAtwIACHhlTSnEskBxUr7ceUgKZIfRjgXEstbPq6sD5zgqBBQWLORFoP51WB+xfMbNK2SvYmS0Dg7BiVxR3d+2W/jpeyYpIIL40x3uHBLg0N1pejiRHSJksXT52NLeyoLSfV8DFCzL6/sYSUWCArBmG8fFlBLodDEKbgydnS65amk+Y8K7lLZZml8PpIup8BHoPsrDdwDDEGDA== 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 PAXPR04MB8624.eurprd04.prod.outlook.com (2603:10a6:102:21b::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9542.10; Fri, 23 Jan 2026 08:06:31 +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.20.9542.008; Fri, 23 Jan 2026 08:06:31 +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, shawnguo@kernel.org, s.hauer@pengutronix.de, kernel@pengutronix.de, festevam@gmail.com Cc: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Antoine Bouyer Subject: [RFC v1 10/11] media: platform: neoisp: Add debugfs support Date: Fri, 23 Jan 2026 09:09:37 +0100 Message-ID: <20260123080938.3367348-11-antoine.bouyer@nxp.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260123080938.3367348-1-antoine.bouyer@nxp.com> References: <20260123080938.3367348-1-antoine.bouyer@nxp.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: FR4P281CA0026.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:c9::11) 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_|PAXPR04MB8624:EE_ X-MS-Office365-Filtering-Correlation-Id: 7b9547cb-b5cc-4cdc-ad20-08de5a565172 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|376014|7416014|52116014|1800799024|19092799006|366016|18082099003|921020|38350700014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?JCpf0t7hjyCBsQe/2XTkZxm6mjHeWnHaCb+VgF7eC7zlf9ucrTQOeM4jRLDE?= =?us-ascii?Q?eZ8Uxlpq+X0RfZuGZajHQZU8xbqkB8oP9VobhO8Ibf+QUQ5Gmel9x3Ho4AAv?= =?us-ascii?Q?smYLBvySG3U8p4ZT7ogLwWNUc5QJtoK4zeRnh1GEXX1HiCzKEmnVSDtbkVdh?= =?us-ascii?Q?TGuvu2AxjVawdDHv79iETb/S6BS/cm+mlnH/pS/fp1EtffKxS6YsKy5YB0LM?= =?us-ascii?Q?h4/mNqfKg2FyLG6Nj9XKa1aX5sdhaUu0w34hyJjhgjNW81Np/XfwsFTRh9bq?= =?us-ascii?Q?+xyD5pn7icaYKrZkqvS6WXfYjrr8ek2uWoRNRHQLhjrK/pTJa3qZqM2c4IpP?= =?us-ascii?Q?NreyptaIP4G7iCbTQII8r9ajRThrju9KsEYFm7jDZLKYMCTK9Cgim9ze9f8n?= =?us-ascii?Q?MHZ/ekaCSWtSSfV2J9Mqq3P0swiRVhSA0+lQqIO5+P2HkTOdDWiWkFZbyjn0?= =?us-ascii?Q?eAUR8tRlmXp580shqkF9w1rc8tNl09FtMMkDzQzDKWhO1WIOq2SyFLa9buVP?= =?us-ascii?Q?dsOqPE9EsDMXUFXe8XUQt/0Miqc4YtlrhkG0Pqja4ri9HVIYxjDb/Z6KimPK?= =?us-ascii?Q?DatobZmN7Aj+dwbQKQoah+/i+reM8CD8LClNEWNTyt9deagLY1QAbndbMCFp?= =?us-ascii?Q?5Tn8hQEyL7hv9AcQqF1PjCZr326pO8CbKYhA+JjxkwaiL5R0V+R7dk2f7W5h?= =?us-ascii?Q?3/mqfKcTJZYGDvDIOYe+t7f529RNTzj3hPxP6ZNkcQ4RuHMa1HyRJigHQ43c?= =?us-ascii?Q?Ukxc+oEh75GY2pOFdiLvRDqqnP6QagHy+Gp/zi2u8d9VWcscZ99U2P/5d46P?= =?us-ascii?Q?HQer6K063mlDvGnG7z5wU75GAhIKTt4aqhtD8UOIMo8TrMFG6fnv6LkR8fS7?= =?us-ascii?Q?h9Xv32ERnn3tOrG64Ei6ABvEKos8qVx6Lbmu82dTVyUulrWLHcb6sFoDjo94?= =?us-ascii?Q?bsRhlpO7YIk4YsqOmBvHct4swbbqHHgvfLf1F5TGpy51Rg8yjKmQJVVz+qBH?= =?us-ascii?Q?DC5oiBkvVLpkboN2GnGCPX2OyA0w51CGD/0oIdFSa5HImut5GZ5sBE3+dO8m?= =?us-ascii?Q?XjduTbL5KRjDkgYMm0Iiq5GfjY7r8qI4hpZV8FFlPZEfqeBbvH0tYqu5xu3/?= =?us-ascii?Q?6NK1M4Xl95Lade5ZHYd8FlWupS3sy2VqvUYSFokSQXXpbyhXm9d/gt0u3d1a?= =?us-ascii?Q?C7bD8vh1wXlWsUwJbMFfVwX+HVrmg5dHW6ZSlKhKotBmWfJoNoOSFET5vA46?= =?us-ascii?Q?srvb0V1xpFWCJfxaDkxWHdCFD3aZwYtfiKcCZbOpR65HxKEi8Vw9MKQG7oNw?= =?us-ascii?Q?KLSTVs8goo3OvEid+4j28+l7/6M6UTHhcMG1s2/t9kMSU+1KKY2N+Ct2r1NW?= =?us-ascii?Q?XSzbDX62IQC4xFqLknb/3rpEh+n8aXaNFFrSNsLq3ogFSxwsLH6KWNl6Z5z0?= =?us-ascii?Q?tFY2SN01itefGG+vb/ZgfUXE90dBUom55BpvJTYP94kfk/bXKdKvC25nHUcP?= =?us-ascii?Q?D4m8x0svRsI2R5R6IdDnZJvnaBgOpBfdTSe1hyez2ZFK4l/mSVNsbmkBFw/y?= =?us-ascii?Q?niTDej0cYyMNsHLzd3hicOYTqqVRQWuchFmvv9kJeMLvg0SEm+VOPoUw8bCd?= =?us-ascii?Q?MAhsWklgbFwP0bozQkQrzlJAmSl4vnR+XpZ5UA1HqTnj?= 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)(376014)(7416014)(52116014)(1800799024)(19092799006)(366016)(18082099003)(921020)(38350700014);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?VdEvULrJjceT/NPACIg0xG6qZaoM0SgLA/q5LSew2ta46US86J4ii0jmkjeP?= =?us-ascii?Q?2Zc4oBdN5S7PIP5UWBnmvycVeAnZsQTvYy7LelA7QwcDkXPw9IT5+ExXB+t6?= =?us-ascii?Q?8qDkgxuwxKDky7ZvMWjWV3eON8eGBugQ++dspJBPlv2WRkKpjHhUrUlMhoYd?= =?us-ascii?Q?dfrWA2kWlPK6V7SLjDkyRUcPhpFM0EWFTS8X6aMz2SicC56BgqEQXmYFgZmg?= =?us-ascii?Q?9ynyw+cfTaXbddOl4if/VOE23XiZbS3S08R2QhVBi9QnCHthQdCPiJa/O4MK?= =?us-ascii?Q?8V4DPIpUgMGbwqnPd4LH5EWJi/34xe/lugecQjU7HXLI2wMkFLc3YLoBiG4k?= =?us-ascii?Q?06Lz5WX/0L35pcBKlk9PIyL0BvA3psMrkpXewBggCAPFVWjSLYC9854qpv1J?= =?us-ascii?Q?5dtP6ZeVQ+VwWSsxRXzdOmAInA9RnPAKa6pVuTrwpqm2xwFNgTHQDiKBvv6F?= =?us-ascii?Q?22m5VwVKKBY7sWwyo+Zq+5ZSVNv1sLhUq0xUcKa8uOw5NrKeTtNV9gM9740y?= =?us-ascii?Q?kBoxf0quneyb13iWqFcoUw8S4iOy58Wo8UdZvmd7iN4ZUk5yk4ti98Aaq9D5?= =?us-ascii?Q?np41zdCLv/GNFpVQOkJ3Qz42+vGg9qbVy/Vsu9jTe7T1mx00JzZZzWhdXNUZ?= =?us-ascii?Q?zlLsVob6w2q7KS+4drWuLyS6BHFUyxkPSDUQdj09AiYd4HeE4hndWTtJbo15?= =?us-ascii?Q?UhwFRu0WqSdvOeeF5mf0JrISIj/3TTN+qPc/vDsi1i8RMMi4//1Rs8FdErVx?= =?us-ascii?Q?BVkBfMAnpqoKmDi+ZUzAkp82Nbdkiw5bgAqM83cIELWBgXyiQYje8/mBQVnZ?= =?us-ascii?Q?OzqU7rp2h5EIxzERqzmZc6TNa1TWcKbQ75GtyVpbIJucJGrgb1apZCXFl8KE?= =?us-ascii?Q?MNfm4yYyIMs2PiZHiM5K1JXUzZMcLCt0Jzhgz6jHBGxbBQ8wbTwuzdVsCHFV?= =?us-ascii?Q?rTJtM8iHrXDIgAAwk30muWsR/7vy/17KP2l/3Nr0lReL2Hrv1gMa9x2GJ+ra?= =?us-ascii?Q?TcG71WbdZyYEJYTHVN0jORUE+JRK9FfcN7+vFUukNaxwyALIxCTf4xhpz3Th?= =?us-ascii?Q?SHD9xEUPY6faB3T+xLuQV+1NWleGA6H/u4gTpl7puQnFP0a5XvhVql60as1y?= =?us-ascii?Q?J751JcMj5/CtUX5sbwyznwvlWJZDAnsZUb4Ls/uaMDqWEBsi2tu6VIpec/4X?= =?us-ascii?Q?9661Ro7qyv7BWXjx1OaSXmwFYuUQ6pEpjYgufoCtCyproQkyimeC//DzEvae?= =?us-ascii?Q?dupp3F6se5OwwBawB0DnCN/aj8qTQzlbFXDMY1e0ab6fwxNmEaLlvmKUGWmK?= =?us-ascii?Q?JOSBmmelVYkuvjUG4FyiD2VEjPWtp4lCwrA5jOf5NkMrriWAHq3tgwC95eph?= =?us-ascii?Q?cUy050ygcIxphYZiVaQpUoUuHYeVens55yxvCLZS5uyo2ndGt0zGW3/0BSUT?= =?us-ascii?Q?usS4ICMehu2Pv8iWibE+iV7K3MQTqFqVS2Hmyobs6tvlahe/TizLC5Jb4gI9?= =?us-ascii?Q?TwFX2vaEueZjOK8rDYwfV5fl66eJ80GxTj4w2MP7soycKty6BpZjAi/m5nHx?= =?us-ascii?Q?54DmuXNAbk9GpRwWcPUgR0A1XTEIzvsfn/XrYGFqvcPxF4jCLDFiH7vVEfxN?= =?us-ascii?Q?4qJsjkmlr27pVTRuU+TB236OX17XrQeyyca0dOkbh80MtsXJ2/kBU7qYTOGx?= =?us-ascii?Q?kUmHMJ2mpf1Q7fxWAOPkBQhEYlXFM2oreSua7R8kU5RG4gsrrCNBMnncWO3V?= =?us-ascii?Q?iPx0SZkfax/S3q8+DrPhv2RlYxpnzso=3D?= X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 7b9547cb-b5cc-4cdc-ad20-08de5a565172 X-MS-Exchange-CrossTenant-AuthSource: PA6PR04MB11910.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Jan 2026 08:06:31.5291 (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: LTp+5+M9RQA6qqnFYz7RKgr/rKa1Ead59+WhjXUOj8+j+GaoVKDXnJbZeoxQnVikxLvHGzn6DrOUlx6jJgqPIA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAXPR04MB8624 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 | 503 ++++++++++++++++++ .../media/platform/nxp/neoisp/neoisp_main.c | 14 + 4 files changed, 535 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 381e11454d37..3402efdbc923 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 @@ -232,8 +233,23 @@ struct neoisp_dev_s { struct neoisp_job_s queued_job; bool hw_busy; /* Non-zero if a job is queued or is being started */ spinlock_t hw_lock; /* Protects "hw_busy" flag and streaming_map */ + 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..a4b9af1e9e86 --- /dev/null +++ b/drivers/media/platform/nxp/neoisp/neoisp_debugfs.c @@ -0,0 +1,503 @@ +// 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_V2), + NEOISP_DFS_REG(NEO_PIPE_CONF_INT_STAT0_V2), + NEOISP_DFS_REG(NEO_PIPE_CONF_CSI_STAT_V2), + 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_PIPE_CONF_INT_EN0), + NEOISP_DFS_REG(NEO_PIPE_CONF_INT_STAT0), + NEOISP_DFS_REG(NEO_PIPE_CONF_CSI_STAT), + 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_ma= p_e map, int wsize) +{ + struct neoisp_dev_s *neoispd =3D m->private; + union udata_t data; + u32 addr; + u32 *src =3D (u32 *)(uintptr_t)neoispd->mmio_tcm; + 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 + i) * sizeof(u32); + data.word =3D src[offset + i]; + + if (wsize =3D=3D sizeof(u8)) { + for (j =3D 0; j < ARRAY_SIZE(data.byte); j++) + seq_printf(m, "%#x: %#x\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: %#x\n", + addr + (j * wsize), data.half[j]); + } + } + + return 0; +} + +static int neoisp_dump_vignetting_show(struct seq_file *m, void *private) +{ + struct neoisp_dev_s *neoispd =3D m->private; + + return neoisp_dump_memory(m, neoispd->info->mems->vignetting_table, sizeo= f(u16)); +} +DEFINE_SHOW_ATTRIBUTE(neoisp_dump_vignetting); + +static int neoisp_dump_drc_global_show(struct seq_file *m, void *private) +{ + struct neoisp_dev_s *neoispd =3D m->private; + + return neoisp_dump_memory(m, neoispd->info->mems->drc_global_tonemap, siz= eof(u16)); +} +DEFINE_SHOW_ATTRIBUTE(neoisp_dump_drc_global); + +static int neoisp_dump_drc_local_show(struct seq_file *m, void *private) +{ + struct neoisp_dev_s *neoispd =3D m->private; + + return neoisp_dump_memory(m, neoispd->info->mems->drc_local_tonemap, size= of(u8)); +} +DEFINE_SHOW_ATTRIBUTE(neoisp_dump_drc_local); + +void neoisp_debugfs_init(struct neoisp_dev_s *neoispd) +{ + neoispd->regset =3D devm_kzalloc(&neoispd->pdev->dev, sizeof(*neoispd->re= gset), 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->pdev->de= v), NULL); + + 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 f053a2136dad..a6d4dc40f9ea 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 @@ -35,6 +36,9 @@ #define NODE_NAME(node) \ (node_desc[(node)->id].ent_name + sizeof(NEOISP_NAME)) =20 +static int enable_debugfs; +module_param_named(enable_debugfs, enable_debugfs, uint, 0600); + 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 || @@ -1765,9 +1769,16 @@ static int neoisp_probe(struct platform_device *pdev) if (ret) goto disable_nodes_err; =20 + if (enable_debugfs) { + neoisp_debugfs_init(neoispd); + /* Increase pm_runtime counter to prevent suspend */ + pm_runtime_resume_and_get(&pdev->dev); + } + pm_runtime_mark_last_busy(&pdev->dev); pm_runtime_put_autosuspend(&pdev->dev); =20 + dev_info(&pdev->dev, "probe: done (%d) debugfs (%x)\n", ret, enable_debug= fs); return ret; =20 disable_nodes_err: @@ -1786,6 +1797,9 @@ static void neoisp_remove(struct platform_device *pde= v) struct neoisp_dev_s *neoispd =3D platform_get_drvdata(pdev); int i; =20 + if (enable_debugfs) + neoisp_debugfs_exit(neoispd); + for (i =3D NEOISP_NODE_GROUPS_COUNT - 1; i >=3D 0; i--) neoisp_destroy_node_group(&neoispd->node_group[i]); =20 --=20 2.52.0 From nobody Sat Feb 7 07:31:36 2026 Received: from PA4PR04CU001.outbound.protection.outlook.com (mail-francecentralazon11013031.outbound.protection.outlook.com [40.107.162.31]) (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 58CF5358D31; Fri, 23 Jan 2026 08:06:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.162.31 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769155604; cv=fail; b=KwQ90wMfyZcnzqfOxgGwQlC+/lzhOP71ngWVYTfwZeOPUwr6KbZReBBQcq2PjGEDiEZtDaObnIg6b2/6qFbDDh4sx4YBc1I9YmPZbZe3TgNVHokEu3PFBBkiCUYY5ibg483V33r4XQMZqbwwbAOMDxs3ex/tDQfVBUQgaA/9KdA= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769155604; c=relaxed/simple; bh=avb6y1kP8lDHC8Q+smLiGSEf7o6Y7mOfagOIAofRwcU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=TA6foXvA2sVFJCnnyoOEj2lMmgvKcdZJv6mGBDh8uhfHSwoBSTxuxZw8uy23ARIcfkk0w2fdkd04ewReR+LlYzyFcXiqqJ/y2luZjzY14YLUYDlbon6jXNocC8ohvV8Q04mDtfyVZ20ljrY8w99Z4N+NraPOHMg23bQAf8Bndok= 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=gzBZSseQ; arc=fail smtp.client-ip=40.107.162.31 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="gzBZSseQ" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=tdeaZIoDY1XmfuiPiSjgfUdWKcPDNbcstz/mb4z/GgAHvsJ7AQ1+iWpKlfXLJfM1bw8Dd8qD1XqzeCRWM671ZQnRf1ne3ZyeiDw0X20epct8MvLxXp9svIvqZztzYyTFykxcZ835obTJF3+HvBWKLKPAMaRue1CzXXswM3VrJOowbmqoWbNxH60dvAY/K9CUFtVKUevAEdYgc+CfRqxQNg2Av5YTs4/o8VehIr5kV59FAxqYXXcd0TIzfavMlskOLUanCYiY0uwc3xcw8ddPG2bmq4QjyOznn88wJ2FdysrSwnPScqC+ZlMvyvUQP4eAz4wxejJ7kF/6ZBKrwnIfKQ== 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=r3xlcBEraFMkRr6HeCEEn4iV/Wo2WflG4sAd7esjSqs=; b=J8llQXNSO0xJjEFEimCKEl7CTo7pzdpu2EAViuquzLwoYQkVnZBV90XVyMcnxL02120TLSTWS030QT/zt80j+Z1I2nl1vL8rOxcv2XBjK812plWzOhgI+nxXZRwV34QDzCTUDonQG0CdsyD7H3RofFBXVq6HJiL6Mn1KixpbHIaFw6MDO9ZiNgwROucUyAjovAd7HJ2cpl5YJ/4wPW4D47Bh90eWHZRexpmE7WxmGKHIKG4DC2vl3NDEXYhGRilv3D8FNYqol6yg3fHB2NwFUczUKCAEN4HltdbxNM2RvQAS90p1uWxc2OQMMQ6UILX12+ATKeYZrgAYDCfBD45ZRw== 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=r3xlcBEraFMkRr6HeCEEn4iV/Wo2WflG4sAd7esjSqs=; b=gzBZSseQJX+V/WZXlX/fgrinDvVxuwiE8ip7xoQv0pdXE76BGjKgPGMyci12SFv/nPNnxaS4zQzEruW1qBQmqQFV7Ep2cyaAFmOiZ4Xoq41GPN1Bdms2aBfLBj9+4Fqcp8VmB9pvKPgQEY7fmW5ai6rFThF1TUV/0zst/bdDs3WJRlLQMruR89Gr4hclvsZYz0eZUUXYNM/+KUGAV7Be2UknfX0sThMAXo5+h17uWOb93e3C+uEG65/u4KbIzPL3yAoGp5iwsZ92eVzAb4vQqLJoJmy5JA1RAntF7UEAiqHPEzfmAs9GgMFUqBshxOWUknhONSE/RL3KbfXo6yhrpw== 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 PAXPR04MB8624.eurprd04.prod.outlook.com (2603:10a6:102:21b::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9542.10; Fri, 23 Jan 2026 08:06:33 +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.20.9542.008; Fri, 23 Jan 2026 08:06:32 +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, shawnguo@kernel.org, s.hauer@pengutronix.de, kernel@pengutronix.de, festevam@gmail.com Cc: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Antoine Bouyer Subject: [RFC v1 11/11] arm64: dts: freescale: imx95: Add NXP neoisp device tree node Date: Fri, 23 Jan 2026 09:09:38 +0100 Message-ID: <20260123080938.3367348-12-antoine.bouyer@nxp.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260123080938.3367348-1-antoine.bouyer@nxp.com> References: <20260123080938.3367348-1-antoine.bouyer@nxp.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: FR4P281CA0026.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:c9::11) 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_|PAXPR04MB8624:EE_ X-MS-Office365-Filtering-Correlation-Id: 38c91e67-369c-49a3-a7d4-08de5a56523b 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|376014|7416014|52116014|1800799024|19092799006|366016|921020|38350700014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?diipDJPYaitVQsh7OyzPjOcQfYr7s7grVWqTJMwnW+T2mMDX5tbvyxZRU8hk?= =?us-ascii?Q?L4GR6ffeTFM+8VQ6Rj1AiymJGRyL6l1ajGZqc298QFnRX3KxmqYEiYxwnhfY?= =?us-ascii?Q?jBVqDYJ0LyvF4tArog9h+FMaIyEWsP8jtn3rzoXZ2jrWWqkzV7zIb+B3A9w+?= =?us-ascii?Q?FYSq7v+NAKBlYMtlxK7jyyg8uq9CSNsYDhlQmsMRRCyzYYiPXW+1rd9i2bsU?= =?us-ascii?Q?tuBpscxooGTMnH4C+nq/r84A1SJ1N2p16rPVf8mXBE9auxi6NIoqjcgOMKG7?= =?us-ascii?Q?KTbYaOGSe99UXCAFTv/yxsnbiOf0sP7J78h+xR53zyRRT+lX7hbLNRSq809i?= =?us-ascii?Q?wyDJjhrO/1X/ajpBTEBU4yjJckMW2Hjo2mMUAb6CVhcvIQsiGtxDATJKvXJh?= =?us-ascii?Q?nU8ektvgVvyQsx/0MYj1aFb3/0elfP/OfjyNPqvxcaPpz/WawFEPR84D5UvF?= =?us-ascii?Q?5F6M9d4rU1hIBiMOxrKL5TGwOnR2IC9ptNwGM/gdSL4KysA6CG3YrMsrwXup?= =?us-ascii?Q?jYej94ViLChEtU4ctO7QPyRXrmZCHln6x6NDlKMsXQ25HIUItGFtx9xnl6Bm?= =?us-ascii?Q?Jl5Ls/1rd4xR9cUXOOcb2AQ+8qjlwIl+pcX4Mk0AZaCflkJLSiHU385X5axe?= =?us-ascii?Q?5N3s4ApfE8jODj5JhTvTH2Z+S8g10y+/c2poEkR3GZTmRbRuSFIjfHEcEbfa?= =?us-ascii?Q?R/fXKbCcUmoRQzLm9Ta8xJ97qu3V5uDjiu2JuwAZGE1xWObdTG7HHcHP7HE7?= =?us-ascii?Q?Imx2F8tOT/DJTSO4drLexYezHW3xJGMJz9mL9iNp5uW+F3izCg3Q3hLWbwDT?= =?us-ascii?Q?+rWtxuo/5canthSTghEoR+gFC9bTuwK1YpASY5B5I4Bwx5ermVI4RLoJN26H?= =?us-ascii?Q?NZ4cpq89dle1X0rIMsl8cJbCWTQPoFOBNRvr34Bb9ivLOH7iTy/N0YmZifUy?= =?us-ascii?Q?DwA0+YVI16ib9hPwVSLLIF3UeiCWtgFmPvZ5ucQb+Sodz4vGoI1R17sgHozD?= =?us-ascii?Q?Xxytbss2ovUQi4hxHIbCq8WEaIWKHKFH6lAnWSGO13SRjPq5gmdBd1Hr3/FJ?= =?us-ascii?Q?myCB0y1OmdOeL8YPXi7WilvQot0b9wjkkshgidKrhsc2TAvUdByc9SHuLKIf?= =?us-ascii?Q?BJY6/EJDc02RuPu4ltbeQpoS0MSI3lTsOLAKzS88kr1FWy2xPCXLbpFEIYaY?= =?us-ascii?Q?66YpjSoDrmGsVGUn9I6iYmzBH+zwvKVvK00CLNiZx3PLem/UmrbxrVR34JxK?= =?us-ascii?Q?6ObAzHixc83d56F4xSdMLOFu55v1LIG5KwT3+HuYSw3tniuLJVq2CBUWQThI?= =?us-ascii?Q?0/LIpOJuXW82B1KV8B9HTIiaAudDQyzUDrq/sna5p7TizgJ88n1rBdZgEFCO?= =?us-ascii?Q?rakw0wPm+oG+ShCxsuzFd9eFJe/y4dWC+tA+6i9paxUouQkw+RHR9Optpi6v?= =?us-ascii?Q?BVow65W6VS7Wd3DvcYUR4lZ+NS+MJFZsPgxvLUcN+PLp3vrIGET9VYcIfm9/?= =?us-ascii?Q?bVyINa97XhGA2YgB3r0+Ttm9XPmsX68PElKCLtXAzyc8L4Yhl1FVC/5BTBKN?= =?us-ascii?Q?OogalFYoYYPCMVXSJG6r50jzr1b9eTXvFCY05VnTQASy5ikdsomrnyS8MsVw?= =?us-ascii?Q?vRMT6987J4bjdvndRAG9u6kDJTGBaJF66xap8PhZYd4G?= 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)(376014)(7416014)(52116014)(1800799024)(19092799006)(366016)(921020)(38350700014);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?oAOM3d5tgA5UwCsTWNDie2ksv34vivkpEMGR40jzyzS9UBAQ6uw0/ltQt8a5?= =?us-ascii?Q?gm1hd1dis723ggvtgEUhe8Yfhs8utwEfhX5Bn8d6bnfJMCwcbzrZQKX9M+PB?= =?us-ascii?Q?MXv75/LTVJ6pTcb8p0Zs79OfQp6R4LtYezsHnwBZ6EGG8kvysAP2uTrvVPvx?= =?us-ascii?Q?nAXrHCelSGYI6x/bv11Kt4snPXi3Wudksya2/sUPyQXyLAGJftsEjuDRrvUF?= =?us-ascii?Q?F5AfWkzG1newVZpCVLsRWU03SZ3FZJz4XbxIvyc0dvg/CYySPA+f4XOmh/M9?= =?us-ascii?Q?t0l8xqUWObAfytThrjkAOj1g4bxuyFOgcE8mrfakihCs+ve15FOZit9uIYbH?= =?us-ascii?Q?OuylI32t9UsbHcATKx0/XpIkkU8BsTncEuRiE0txqvdtQfJF/lmXqbscoDLG?= =?us-ascii?Q?zdXMMHBd9pLalJqIuspX0ON0Z3oL0DkBCYe4Huw5M8ZugNvjVGdtho52CRdO?= =?us-ascii?Q?H7FF3Ulj6r3D1foIX618J01Qy/ox8WxsbvYe2QYP0laqu2fVcXb+IIQa2b9V?= =?us-ascii?Q?RJg+vBVmgjMyzRTDziI54ijl03dzt/uJCWDHAsGnYhsaVcprZdcDUjqbGhTA?= =?us-ascii?Q?U61UkrFwzMBd9T6TSnopIAzd62Vlm0ogM2GQugVhiMlcQPFKjXuxWaY2kfCp?= =?us-ascii?Q?WwWLyKhGyN77i24iHDvvAk5yzTkZS6CSmJT/oGlwyD5dp7EZQWEUYZDsAT8L?= =?us-ascii?Q?/rOey0lykwMlagcrR5JlsQJX+acG8PYRMkVX7AwNnecumBZcIQCkMyisrTKf?= =?us-ascii?Q?EzfBCDwBj4g4H3/NMnYCMAfXIoGIuJmzmb0b/bp1tV/uK/K1Iot0lh2Yp6t5?= =?us-ascii?Q?hxpjEhoT5xAzzXj03bjqYdIJpqw0s9aFTsNMHbv5Bg9jCjjljL3YYRb18WlM?= =?us-ascii?Q?mnnqrh8sLDeMbS8/cgxHRG8+S1kn4UifE1PpC7COvu3g87bBQIEDv1TAsoy+?= =?us-ascii?Q?ljKqQpyuliamCtf0tuo0XiuYEzkPvSeg/IIod36/dcnCbKOFU97ntOZAvvvH?= =?us-ascii?Q?2nfnQVQjGjWojqijb+zOEgxbtbtcOAAV0XOmbywdAzOpv1+DzENs7SltuN/Q?= =?us-ascii?Q?LtdT7HQqWABKpBrbs+tJpG7RCBYRH8JBNJF1ro2nDfmIg+usvAbcCuc5PItI?= =?us-ascii?Q?VGVLD9CsgFOO9l45BzhoVN8arg/36NBQghMRHdnSWNy1AsFpGfa1Azar40Ki?= =?us-ascii?Q?7yWyc0VWDTo53eJC83IKv3yqt4OsusBg5kG+hmY7twGxFba25GpKCmf8CDBJ?= =?us-ascii?Q?uLAs53F9EGwAVCxtJlwQp+k7OgozW3LcK4z6VC7mq1T1Xq1839e3vl4Atxvw?= =?us-ascii?Q?ZMKYpqDi3+Irb0mDrTZze2zXCenWOxqIT351/hbo25qK2zAE3XArceQ2vJ6R?= =?us-ascii?Q?MRyBCTMf8ITxcFf5C9z67KlP2g2/fpyH2NYDk7+oaliHizI8Dm7n4JbqI+q2?= =?us-ascii?Q?aVVb1y3Iy1dHutuKQXs5pAPS9X9e49Rr4oPQThoVZe2DOzcMvzIBDVZEo4w+?= =?us-ascii?Q?smpoVggi+WGJ8QYsiaHD5muVXAEZc6cgonh6YrAesNVS/CJDG9jWd7NqP/Mg?= =?us-ascii?Q?GiNpHjtWiOBZC3MeeqtvPCmvoYfchkL+kBnqMKm/UIAzX+nHHzZp8LAjtCGe?= =?us-ascii?Q?t9gytOGtgwoTilWcKWozXuIzbRHaBwfRNPjWu6TfTzeFqj7NPHFrEHpbSCcR?= =?us-ascii?Q?jvVAifQj77CjfrIEFrhP9Qra6vz/a2Afp+g0vrPDN/gTTr0bzUTrp3ddvhN5?= =?us-ascii?Q?7gXAXsJwVTuaajqir8tybzzXtIB2G9k=3D?= X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 38c91e67-369c-49a3-a7d4-08de5a56523b X-MS-Exchange-CrossTenant-AuthSource: PA6PR04MB11910.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Jan 2026 08:06:32.8567 (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: FQWdonKix+Or1SOG3TdmIQQfjAQMA6COMjDt0EjocvbabfQM2Q9xVGWvKU/jF3sxuwBDKCoRidR87Y3m9Ej61A== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAXPR04MB8624 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 aaa0da55a22b..9fbf22a57dba 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 e45014d50abe..03c7f3de6e9c 100644 --- a/arch/arm64/boot/dts/freescale/imx95.dtsi +++ b/arch/arm64/boot/dts/freescale/imx95.dtsi @@ -1765,6 +1765,17 @@ smmu: iommu@490d0000 { }; }; =20 + neoisp0: isp@4ae00000 { + compatible =3D "nxp,imx95-b0-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.52.0