From patchwork Wed Feb 19 10:16:38 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Riesch X-Patchwork-Id: 13981909 Received: from EUR05-AM6-obe.outbound.protection.outlook.com (mail-am6eur05on2102.outbound.protection.outlook.com [40.107.22.102]) (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 9F6A31EA7E1; Wed, 19 Feb 2025 10:17:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.22.102 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739960228; cv=fail; b=Uk7qA5pOC+MgtOQqisCP6i5CTENc9Qj7G+e8LjsRt+GXCGrDQeYRuEYssEzTv6LsZ0gjR//EUb+tY8pBKyfOtdRMzU+dbLDGD2f9OPuIm3lHJyTU0SSEdk374ixwMpOle2h7n+NBqWLZ2LETNTAiGpXDWx4pQZuN51Lx3qYy49Q= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739960228; c=relaxed/simple; bh=8Sv3qzMjLle5B2Db/ntmB6Er3Sh5MdDzsjE02HgBVUY=; h=From:Date:Subject:Content-Type:Message-Id:References:In-Reply-To: To:Cc:MIME-Version; b=IWCx2Coeoryn6Ew+EbNc7yzimdVvCsBG4bH9+xXcViOjc0Dw51oRwaCc8tDzuUh7O5JYMisjyZRXpx4SvsawQ95GWuz4f/ysu9LWdTUwDI6u/rf3J3CMn+ywFJsh9ZY2ClTM+Y1KJSswFHCSri/quTsbfK3kG6aF5YOQPL0PgaI= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wolfvision.net; spf=pass smtp.mailfrom=wolfvision.net; dkim=pass (1024-bit key) header.d=wolfvision.net header.i=@wolfvision.net header.b=mIhcfoDr; arc=fail smtp.client-ip=40.107.22.102 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=wolfvision.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=wolfvision.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=wolfvision.net header.i=@wolfvision.net header.b="mIhcfoDr" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=O2ckZJq2UTMSut1tBFW3kf664+0Pi+TT2KfErdRd/KI28CPhKS90daJt7CcspT0Uv+FsbPySvxxp0ardjff7pHqHnyza8mf8nW460dN01o3UBtonMCBuJ+JsumD6jP/G+5VhUrTDF23OwmA5sKNiyEMfMNWTxlguuUQlG7i08b+FR2snjd5eOj6/BhPpnflXU1kaKZ4Z4ErnzkWjfJmrFcJBXg+7UZgTSYr2Ma1kuYvUBh4926aatf12WlinnxHFITipov+b56/UocralQHPEbe0RQurDgcE7LUtcjsb+j8VT9TqqWqumBAR9p9AtoNc21aSVQLxVQuGzur97mVO+w== 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=7MmC+vttOPClVYEq8kqxqWZzmlFP5TNh88NVLGG+gkM=; b=k4kKEcEHTP7xNdn8c7id/ARMQIbp1c9pXvXdQPKvAidLrP15aGdgXpCnjbgQVBoUVvVhJxLljWkAMj/j/r2JXSuPaMj5c0V9O+gxu/KdoGIV+B9grhJIY30UWcmGQTGVXlVOqhN8XoQSSNJUIzyot+6SWlFWpoPcbe0v86WlLzDdK/e1raciunIE+FUOi2TIw9BNZ9cfub1gKQmqFgQWE6uGiU3WjZOrr/NUY1mwRm69RDzJJ7v+KvTd0Q4r+d168oC9z8ctecMZGOrum1ykYGplpoyhfBs6yXdYFyc1O0OOwNPr71K3EKDSuEApcPXEmd94UriLOd8dZafoTRPIDA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=wolfvision.net; dmarc=pass action=none header.from=wolfvision.net; dkim=pass header.d=wolfvision.net; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=wolfvision.net; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=7MmC+vttOPClVYEq8kqxqWZzmlFP5TNh88NVLGG+gkM=; b=mIhcfoDr/Xn3YZrP5j0pjjgErEg2RQIWL6viB5mkWDMVBuKRy72f/BhW4cKKWDe0eaccVj4cZibXOAg0v89rdTkJyyrw/uYz0TMimnfwQgSoPfb3MH4BTl7NE+NaAqs48rllQHb1TtWZ2yUyvnXDWGrDKU/q6o+CRPGGolegRCs= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=wolfvision.net; Received: from DU0PR08MB9155.eurprd08.prod.outlook.com (2603:10a6:10:416::5) by DU0PR08MB8138.eurprd08.prod.outlook.com (2603:10a6:10:3ed::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8445.18; Wed, 19 Feb 2025 10:16:51 +0000 Received: from DU0PR08MB9155.eurprd08.prod.outlook.com ([fe80::4e72:c5d4:488e:f16d]) by DU0PR08MB9155.eurprd08.prod.outlook.com ([fe80::4e72:c5d4:488e:f16d%5]) with mapi id 15.20.8466.015; Wed, 19 Feb 2025 10:16:51 +0000 From: Michael Riesch Date: Wed, 19 Feb 2025 11:16:38 +0100 Subject: [PATCH v4 07/11] media: rockchip: rkcif: add support for mipi csi-2 receiver Message-Id: <20250219-v6-8-topic-rk3568-vicap-v4-7-e906600ae3b0@wolfvision.net> References: <20250219-v6-8-topic-rk3568-vicap-v4-0-e906600ae3b0@wolfvision.net> In-Reply-To: <20250219-v6-8-topic-rk3568-vicap-v4-0-e906600ae3b0@wolfvision.net> To: Mehdi Djait , Maxime Chevallier , =?utf-8?q?Th=C3=A9o_Leb?= =?utf-8?q?run?= , Gerald Loacker , Thomas Petazzoni , Laurent Pinchart , Mauro Carvalho Chehab , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Kever Yang , Nicolas Dufresne , Sebastian Fricke , Sebastian Reichel , Paul Kocialkowski , Alexander Shiyan , Val Packett , Rob Herring , Philipp Zabel , Sakari Ailus Cc: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, Michael Riesch X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1739960197; l=24428; i=michael.riesch@wolfvision.net; s=20240405; h=from:subject:message-id; bh=8Sv3qzMjLle5B2Db/ntmB6Er3Sh5MdDzsjE02HgBVUY=; b=VwToprCzjkQOR7ppnTwhOZNrPMiqjtxIZ8KQxOf+SS3/NlBgCg6SQvsywJ6B0xwPRnrhcqukV OqWw30IpTWZAUmFSLYvrLSau+dfR90QZEoAch6+HFoh4AOVh36EtDpL X-Developer-Key: i=michael.riesch@wolfvision.net; a=ed25519; pk=cSJmgKSH3B6kdCIDCl+IYDW1Pw/Ybc6g9rmnUd/G7Ck= X-ClientProxiedBy: VI1P190CA0041.EURP190.PROD.OUTLOOK.COM (2603:10a6:800:1bb::8) To DU0PR08MB9155.eurprd08.prod.outlook.com (2603:10a6:10:416::5) Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DU0PR08MB9155:EE_|DU0PR08MB8138:EE_ X-MS-Office365-Filtering-Correlation-Id: 9531973b-7ecb-4d20-34df-08dd50ce86dc X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|52116014|376014|7416014|1800799024|366016|921020|38350700014; X-Microsoft-Antispam-Message-Info: =?utf-8?q?/4po+yn0k+a9p/uoTkznRzNRR78HB1f?= =?utf-8?q?J42nni2980DsYa6EFWldidtS6sDCcNZ9eI/6i3YVhFYflYOhZtfZXSAmzcqpygUVI?= =?utf-8?q?hIpQXl1kqlSgKZykh8UDKTF8UuCTTPoHu4ksyPW10qUhnbjXrY7t5sMRZbXuJIJj0?= =?utf-8?q?X1dZV/0TGDPH4qV7qetqwirwqQd06aJRVtsevQb8nVqm6i2S0ipMwxUFJr9+VusBr?= =?utf-8?q?lTLPMXS79LAuoHdmw2m+W/EPs4GOy2KC6l6sojY9GnyuTuT0CqKhP/jhZ5aepHbAr?= =?utf-8?q?2u9IUWJLu6kDlTEIi8Gbclkyn7Cm1ZBDT+G0RT+HQfXLdB9r4gvII3qghaca3Ll5f?= =?utf-8?q?xppAQSvmpheevJP/BuGaT7UXQ7/CL7d8fkaADvLymbaMPWiM1MoPjgtv8wSQYk7Z5?= =?utf-8?q?c8GopuHJL53XH6xxyopTbxWTdt43BGITq0cik3b4Z0wiEivCey7pS/gazag03wXVX?= =?utf-8?q?svJmCuZFTP9MstnwCzWGZM+isrv0Zy2OfZnLs0WKK4z/y5FA45kynIPqPTvkwt38z?= =?utf-8?q?SzKIBpFytob6FxxfIgiMgiqxDff/8fwtKE23y1Oayol7WC9IHeR2dSm4GjxW2XuKb?= =?utf-8?q?DCD6hMmgipMRA0vvg6rRyjFu6WA9LmBZgsqRF3uTWe3XLI9YGtVmqlfU36vuBtyi5?= =?utf-8?q?Neqk2ecGytjQGEkXXh2YWek0PYU50cv0AjsAaRRisY3Lm2+Io6ijWQlb7IypU+HwR?= =?utf-8?q?DNJ0EP9yttn3Ds1w8iInwNLX5Y0mKpN44BRVGKbPgfJilfyoAhMPd3unSol6Z7Q0X?= =?utf-8?q?s/7QGUMvus4imxV/miSPoKt8P2EfO8efZoy4H51Kjrriz8haSnUWRmQ9gW9WSPOae?= =?utf-8?q?ilDJfdf1XzTa4CFpffimfGHKDRLnhQAG6XyefpuhheMuc6z4JEXBrubIStLbkayrE?= =?utf-8?q?oe938qhx+F1LynN1JUKFKdGOJRmRaajgaSZ/p5XVrjnbOawAEkOeoKjTb0ux5qljA?= =?utf-8?q?Q14ztu5mNZ/c62RJVJbkR0IZGEk48VPknzrBIXpIuw6yswyEmywI8lhhLEKCvoZTD?= =?utf-8?q?bxpFGwUZUHjL4GtyYJ0p7HvVk7weJULZngd4VJEqtYrfb203J/sfx6vBZRqgMvvrK?= =?utf-8?q?r+0XUiMrmWdZgxmKcIsGoeBpTPyk7Pw7dlO4kE28Qz8EhP1skiuzrBvnnSDEmsZ+4?= =?utf-8?q?RDBmkv4dN3JDo5KzXvCngvxrqnbextu0RNUmoBo7WJzQG4FUvRk+lCxlVl/DiJ6Ck?= =?utf-8?q?DVj7wZWo0Ey0LIyyhKxgoXIY9+hyeEngQ5Mqwz3CA6hHWrAJJ4lM+K3ZYuFKchPGI?= =?utf-8?q?S684EoCJJ6njmxYqT6Le/xWnMeh/vfUfJ/i9RwJEJ4DsqeBfn4MT6PTB46Z57doSt?= =?utf-8?q?22gEtm7RoQcW5NN/qU6u9ZLgARk4mDww9Rs93re0UPw+jtqhsimMp1x3L+gyT2S3u?= =?utf-8?q?T58FIj9qeXpZJVqYXASIEtCW5N6ylN7ow=3D=3D?= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DU0PR08MB9155.eurprd08.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(52116014)(376014)(7416014)(1800799024)(366016)(921020)(38350700014);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?gBI4zUaWiQYReDxpNgloXQk4HCGl?= =?utf-8?q?YB2XsLvZBW1tfMGAGk+2I08YDK0kFwDm3xsE1GHgdT/K36PBWBHAL+IIUJ4CTfPwX?= =?utf-8?q?6mtX7j4+O9AP6QSPnJugj9wSxMs6w/J/jZSklfQPUr/rMf/v9KaPeCk4qlsiM3/na?= =?utf-8?q?djwJcX606NuGnoi6bZQiBUqjsOdv4atK9Bk3/6rjM7IWOmXZJMpSaoxt4aLdzULqB?= =?utf-8?q?ztkslYC5tRM/7+aqOnvHw6ECPDD9/Shut3tqQjuMwt2nE0uJb23X4vgj94zr1dhVh?= =?utf-8?q?wMKCjb3BtynYHKgVeWD7CuDLeXTqeP/rzMh9BzWp5bmV751mtc3tY5ott/bjTARo1?= =?utf-8?q?FZHSfpRXyW8HZH5hQoKMR6zCQNGikAsBcKvAreCXvi6CCpkjhDt9zHp3odRkGMzVT?= =?utf-8?q?mF8bB9yz6AVuPMp6IZnwNV1nEJqQlO6lViZ+EpoX+/AXBReXuyUoio/V4z6WqJE5C?= =?utf-8?q?/PdMB4VEP401iw/SYIT6DXa2Oyfk8iXHgaXxo2ce2pIkTOcXxOPJC4qto0O/l24bq?= =?utf-8?q?Vg3gNNTRFhs9h/IDk+Px7IeC1li0S0UN25jbQPd2vSDz2LIW+su275721BERt10WZ?= =?utf-8?q?PL8Klii7MiM1aA2hbht/l/OtfCohYkcqLysaQgbb7+D1gz2BQmZE7rCYg5KvLJjxp?= =?utf-8?q?t98ZuqQay9z5Wk5IH3c0V3C0rTeVExy6V0luBcKnyqR75GjXD1urAiVL9mRsBY50U?= =?utf-8?q?Q2H6poBGwIObapG0DYYAyNsOwdmq8fvnKnHF/HS6K40h8FHDrZZdT1m0pm2w0WYRd?= =?utf-8?q?+aZ5w9Lw28jEGDsrsGEt0cb1cz2SKyXnaRa/QIoX+UJakOo9o4phx3iCxoOj7AisO?= =?utf-8?q?UJu+57z0zKnxwZfj32E6W/x+ZwPxYr6IdhQ6+u/Yb0OCv8Q2JWYoKMfLjJfBT9XXB?= =?utf-8?q?fo9v6KTCUqePym9m7xoA0gKYrgnCuhnR7ZJLMRX/H2rcQzZkCNJQ2bb9BrRapt6FW?= =?utf-8?q?Q//3f9bAHqi/AT7uCY5ILDqUZRueq+V2UApVUsSDGmwYtSmRgQJPCMfEc9ftl01F8?= =?utf-8?q?y/XUQy4EmyGhWpdkH422FCBmjAwky/mGrhBexV4bKA2wKYOJRPXVYfwQ4lHYJ7T9Y?= =?utf-8?q?cx/MYh/DJsgtUMnlEUhK7+rlrDfc/waGvPkT/OJ5l8g02Kuom1oIRdJaoSjUuWKLk?= =?utf-8?q?TzxeMIxyDnFFtTBjcDuBeWRUcbcA6zrjuYnAO6EVXxtxlFhzSFvrd+C4Xcy1zhfpH?= =?utf-8?q?Lo10n+gzcj3yIG9/n1nZiwPD4n64zd7qwb8nNSzg26+XIOu04ZzrHztI+NNTHbdiM?= =?utf-8?q?fsDkp0sSxFj6KNA2h4/vNGd0iQwCRaAoUXyZWb1I1/OCkrA4ypq1dardwtsdzvzGE?= =?utf-8?q?W6Hd8zRe4E5Vtgi7riAR2RIxR5UOhAnyoc9f1gCYgUI4SpVLUXHJGkD7nVOkKSwKG?= =?utf-8?q?Xcze7N99p+ZWttKks0K3gNXAcyLTHGL5JDxI2SGmB6ZsRnB1OSqV4M8APo8lB+Pw2?= =?utf-8?q?3CSGccD59+n+db014GmgY26HjIOJ0f+JsijmyYIuIUe/kDh9JGzzZVkYiuHYPF4CV?= =?utf-8?q?QhRsLwOpkQvsL3aPZUsqGD3lGY8rd6kg6g=3D=3D?= X-OriginatorOrg: wolfvision.net X-MS-Exchange-CrossTenant-Network-Message-Id: 9531973b-7ecb-4d20-34df-08dd50ce86dc X-MS-Exchange-CrossTenant-AuthSource: DU0PR08MB9155.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 Feb 2025 10:16:51.4399 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e94ec9da-9183-471e-83b3-51baa8eb804f X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: OAsQJXeEzvJNYytPye7GYlkBT2QEy406eomEyD/d8FNPsIaC/C4CZP2+cEQM/E5H9D43m7iXTWDsTUbkVauPbWM60cEnfqPwXBSvjkD5JRQ= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0PR08MB8138 The RK3568 Video Capture (VICAP) unit features a MIPI CSI-2 receiver that can receive video data and write it into system memory using the ping-pong scheme. Add support for it. Signed-off-by: Michael Riesch --- .../platform/rockchip/rkcif/rkcif-capture-mipi.c | 688 +++++++++++++++++++++ .../platform/rockchip/rkcif/rkcif-capture-mipi.h | 2 + .../media/platform/rockchip/rkcif/rkcif-common.h | 16 + drivers/media/platform/rockchip/rkcif/rkcif-dev.c | 1 + .../platform/rockchip/rkcif/rkcif-interface.c | 5 +- drivers/media/platform/rockchip/rkcif/rkcif-regs.h | 24 +- 6 files changed, 734 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c b/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c index 0c3f7b8cfa18..751a2351cfd2 100644 --- a/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c +++ b/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c @@ -6,22 +6,710 @@ * Copyright (C) 2025 Michael Riesch */ +#include + +#include +#include +#include +#include +#include +#include +#include +#include + #include "rkcif-capture-mipi.h" #include "rkcif-common.h" +#include "rkcif-interface.h" +#include "rkcif-regs.h" #include "rkcif-stream.h" +#define RKCIF_MIPI_CTRL0_COMPACT_EN BIT(6) +#define RKCIF_MIPI_CTRL0_CROP_EN BIT(5) +#define RKCIF_MIPI_CTRL0_TYPE_RAW8 (0 << 1) +#define RKCIF_MIPI_CTRL0_TYPE_RAW10 (1 << 1) +#define RKCIF_MIPI_CTRL0_TYPE_RAW12 (2 << 1) +#define RKCIF_MIPI_CTRL0_TYPE_RGB888 (3 << 1) +#define RKCIF_MIPI_CTRL0_TYPE_YUV422SP (4 << 1) +#define RKCIF_MIPI_CTRL0_TYPE_YUV420SP (5 << 1) +#define RKCIF_MIPI_CTRL0_TYPE_YUV400 (6 << 1) +#define RKCIF_MIPI_CTRL0_CAP_EN BIT(0) + +#define RKCIF_MIPI_INT_FRAME0_END(id) BIT(8 + id * 2 + 0) +#define RKCIF_MIPI_INT_FRAME1_END(id) BIT(8 + id * 2 + 1) + +static const struct rkcif_output_fmt mipi_out_fmts[] = { + /* YUV formats */ + { + .fourcc = V4L2_PIX_FMT_YUYV, + .mbus_code = MEDIA_BUS_FMT_YUYV8_1X16, + .depth = 16, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_YUV422_8B, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RAW8, + }, + }, + { + .fourcc = V4L2_PIX_FMT_UYVY, + .mbus_code = MEDIA_BUS_FMT_UYVY8_1X16, + .depth = 16, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_YUV422_8B, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RAW8, + }, + }, + { + .fourcc = V4L2_PIX_FMT_YVYU, + .mbus_code = MEDIA_BUS_FMT_YVYU8_1X16, + .depth = 16, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_YUV422_8B, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RAW8, + }, + }, + { + .fourcc = V4L2_PIX_FMT_VYUY, + .mbus_code = MEDIA_BUS_FMT_VYUY8_1X16, + .depth = 16, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_YUV422_8B, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RAW8, + }, + }, + /* RGB formats */ + { + .fourcc = V4L2_PIX_FMT_RGB24, + .mbus_code = MEDIA_BUS_FMT_RGB888_1X24, + .depth = 24, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_RGB888, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RGB888, + }, + }, + { + .fourcc = V4L2_PIX_FMT_BGR24, + .mbus_code = MEDIA_BUS_FMT_BGR888_1X24, + .depth = 24, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_RGB888, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RGB888, + }, + }, + /* Bayer formats */ + { + .fourcc = V4L2_PIX_FMT_SBGGR8, + .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, + .depth = 8, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_RAW8, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RAW8, + }, + }, + { + .fourcc = V4L2_PIX_FMT_SGBRG8, + .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8, + .depth = 8, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_RAW8, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RAW8, + }, + }, + { + .fourcc = V4L2_PIX_FMT_SGRBG8, + .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8, + .depth = 8, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_RAW8, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RAW8, + }, + }, + { + .fourcc = V4L2_PIX_FMT_SRGGB8, + .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8, + .depth = 8, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_RAW8, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RAW8, + }, + }, + { + .fourcc = V4L2_PIX_FMT_SBGGR10, + .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10, + .depth = 10, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_RAW10, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RAW10, + }, + }, + { + .fourcc = V4L2_PIX_FMT_SBGGR10P, + .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10, + .depth = 10, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_RAW10, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RAW10 | RKCIF_MIPI_CTRL0_COMPACT_EN, + }, + }, + { + .fourcc = V4L2_PIX_FMT_SGBRG10, + .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10, + .depth = 10, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_RAW10, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RAW10, + }, + }, + { + .fourcc = V4L2_PIX_FMT_SGBRG10P, + .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10, + .depth = 10, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_RAW10, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RAW10 | RKCIF_MIPI_CTRL0_COMPACT_EN, + }, + }, + { + .fourcc = V4L2_PIX_FMT_SGRBG10, + .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10, + .depth = 10, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_RAW10, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RAW10, + }, + }, + { + .fourcc = V4L2_PIX_FMT_SGRBG10P, + .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10, + .depth = 10, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_RAW10, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RAW10 | RKCIF_MIPI_CTRL0_COMPACT_EN, + }, + }, + { + .fourcc = V4L2_PIX_FMT_SRGGB10, + .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10, + .depth = 10, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_RAW10, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RAW10, + }, + }, + { + .fourcc = V4L2_PIX_FMT_SRGGB10P, + .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10, + .depth = 10, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_RAW10, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RAW10 | RKCIF_MIPI_CTRL0_COMPACT_EN, + }, + }, + { + .fourcc = V4L2_PIX_FMT_SBGGR12, + .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12, + .depth = 12, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_RAW12, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RAW12, + }, + }, + { + .fourcc = V4L2_PIX_FMT_SBGGR12P, + .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12, + .depth = 12, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_RAW12, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RAW12 | RKCIF_MIPI_CTRL0_COMPACT_EN, + }, + }, + { + .fourcc = V4L2_PIX_FMT_SGBRG12, + .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12, + .depth = 12, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_RAW12, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RAW12, + }, + }, + { + .fourcc = V4L2_PIX_FMT_SGBRG12P, + .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12, + .depth = 12, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_RAW12, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RAW12 | RKCIF_MIPI_CTRL0_COMPACT_EN, + }, + }, + { + .fourcc = V4L2_PIX_FMT_SGRBG12, + .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12, + .depth = 12, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_RAW12, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RAW12, + }, + }, + { + .fourcc = V4L2_PIX_FMT_SGRBG12P, + .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12, + .depth = 12, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_RAW12, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RAW12 | RKCIF_MIPI_CTRL0_COMPACT_EN, + }, + }, + { + .fourcc = V4L2_PIX_FMT_SRGGB12, + .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12, + .depth = 12, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_RAW12, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RAW12, + }, + }, + { + .fourcc = V4L2_PIX_FMT_SRGGB12P, + .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12, + .depth = 12, + .cplanes = 1, + .mipi = { + .dt = MIPI_CSI2_DT_RAW12, + .ctrl0_val = RKCIF_MIPI_CTRL0_TYPE_RAW12 | RKCIF_MIPI_CTRL0_COMPACT_EN, + }, + }, +}; + +static const struct rkcif_input_fmt mipi_in_fmts[] = { + /* YUV formats */ + { + .mbus_code = MEDIA_BUS_FMT_YUYV8_1X16, + }, + { + .mbus_code = MEDIA_BUS_FMT_UYVY8_1X16, + }, + { + .mbus_code = MEDIA_BUS_FMT_YVYU8_1X16, + }, + { + .mbus_code = MEDIA_BUS_FMT_VYUY8_1X16, + }, + /* RGB formats */ + { + .mbus_code = MEDIA_BUS_FMT_RGB888_1X24, + }, + { + .mbus_code = MEDIA_BUS_FMT_BGR888_1X24, + }, + /* Bayer formats */ + { + .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, + }, + { + .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8, + }, + { + .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8, + }, + { + .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8, + }, + { + .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10, + }, + { + .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10, + }, + { + .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10, + }, + { + .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10, + }, + { + .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12, + }, + { + .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12, + }, + { + .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12, + }, + { + .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12, + }, +}; + +const struct rkcif_mipi_match_data rk3568_vicap_mipi_match_data = { + .mipi_num = 1, + .regs = { + [RKCIF_MIPI_CTRL] = 0x20, + [RKCIF_MIPI_INTEN] = 0xa4, + [RKCIF_MIPI_INTSTAT] = 0xa8, + }, + .regs_id = { + [RKCIF_ID0] = { + [RKCIF_MIPI_CTRL0] = 0x00, + [RKCIF_MIPI_CTRL1] = 0x04, + [RKCIF_MIPI_FRAME0_ADDR_Y] = 0x24, + [RKCIF_MIPI_FRAME0_ADDR_UV] = 0x2c, + [RKCIF_MIPI_FRAME0_VLW_Y] = 0x34, + [RKCIF_MIPI_FRAME0_VLW_UV] = 0x3c, + [RKCIF_MIPI_FRAME1_ADDR_Y] = 0x28, + [RKCIF_MIPI_FRAME1_ADDR_UV] = 0x30, + [RKCIF_MIPI_FRAME1_VLW_Y] = 0x38, + [RKCIF_MIPI_FRAME1_VLW_UV] = 0x40, + [RKCIF_MIPI_CROP_START] = 0xbc, + }, + [RKCIF_ID1] = { + [RKCIF_MIPI_CTRL0] = 0x08, + [RKCIF_MIPI_CTRL1] = 0x0c, + [RKCIF_MIPI_FRAME0_ADDR_Y] = 0x44, + [RKCIF_MIPI_FRAME0_ADDR_UV] = 0x4c, + [RKCIF_MIPI_FRAME0_VLW_Y] = 0x54, + [RKCIF_MIPI_FRAME0_VLW_UV] = 0x5c, + [RKCIF_MIPI_FRAME1_ADDR_Y] = 0x48, + [RKCIF_MIPI_FRAME1_ADDR_UV] = 0x50, + [RKCIF_MIPI_FRAME1_VLW_Y] = 0x58, + [RKCIF_MIPI_FRAME1_VLW_UV] = 0x60, + [RKCIF_MIPI_CROP_START] = 0xc0, + }, + [RKCIF_ID2] = { + [RKCIF_MIPI_CTRL0] = 0x10, + [RKCIF_MIPI_CTRL1] = 0x14, + [RKCIF_MIPI_FRAME0_ADDR_Y] = 0x64, + [RKCIF_MIPI_FRAME0_ADDR_UV] = 0x6c, + [RKCIF_MIPI_FRAME0_VLW_Y] = 0x74, + [RKCIF_MIPI_FRAME0_VLW_UV] = 0x7c, + [RKCIF_MIPI_FRAME1_ADDR_Y] = 0x68, + [RKCIF_MIPI_FRAME1_ADDR_UV] = 0x70, + [RKCIF_MIPI_FRAME1_VLW_Y] = 0x78, + [RKCIF_MIPI_FRAME1_VLW_UV] = 0x80, + [RKCIF_MIPI_CROP_START] = 0xc4, + }, + [RKCIF_ID3] = { + [RKCIF_MIPI_CTRL0] = 0x18, + [RKCIF_MIPI_CTRL1] = 0x1c, + [RKCIF_MIPI_FRAME0_ADDR_Y] = 0x84, + [RKCIF_MIPI_FRAME0_ADDR_UV] = 0x8c, + [RKCIF_MIPI_FRAME0_VLW_Y] = 0x94, + [RKCIF_MIPI_FRAME0_VLW_UV] = 0x9c, + [RKCIF_MIPI_FRAME1_ADDR_Y] = 0x88, + [RKCIF_MIPI_FRAME1_ADDR_UV] = 0x90, + [RKCIF_MIPI_FRAME1_VLW_Y] = 0x98, + [RKCIF_MIPI_FRAME1_VLW_UV] = 0xa0, + [RKCIF_MIPI_CROP_START] = 0xc8, + }, + }, + .blocks = { + { + .offset = 0x80, + }, + }, +}; + +static inline unsigned int rkcif_mipi_get_reg(struct rkcif_interface *interface, + unsigned int index) +{ + struct rkcif_device *rkcif = interface->rkcif; + unsigned int block, offset, reg; + + block = interface->index - RKCIF_MIPI_BASE; + + if (WARN_ON(block > RKCIF_MIPI_MAX - RKCIF_MIPI_BASE) || + WARN_ON(index > RKCIF_MIPI_REGISTER_MAX)) + return RKCIF_REGISTER_NOTSUPPORTED; + + offset = rkcif->match_data->mipi->blocks[block].offset; + reg = rkcif->match_data->mipi->regs[index]; + return offset + reg; +} + +static inline unsigned int rkcif_mipi_id_get_reg(struct rkcif_stream *stream, + unsigned int index) +{ + struct rkcif_device *rkcif = stream->rkcif; + unsigned int block, id, offset, reg; + + block = stream->interface->index - RKCIF_MIPI_BASE; + id = stream->id; + + if (WARN_ON(block > RKCIF_MIPI_MAX - RKCIF_MIPI_BASE) || + WARN_ON(id > RKCIF_ID_MAX) || + WARN_ON(index > RKCIF_MIPI_ID_REGISTER_MAX)) + return RKCIF_REGISTER_NOTSUPPORTED; + + offset = rkcif->match_data->mipi->blocks[block].offset; + reg = rkcif->match_data->mipi->regs_id[id][index]; + return offset + reg; +} + +static inline __maybe_unused void +rkcif_mipi_write(struct rkcif_interface *interface, unsigned int index, u32 val) +{ + unsigned int addr = rkcif_mipi_get_reg(interface, index); + + if (addr == RKCIF_REGISTER_NOTSUPPORTED) + return; + + writel(val, interface->rkcif->base_addr + addr); +} + +static inline __maybe_unused void +rkcif_mipi_stream_write(struct rkcif_stream *stream, unsigned int index, + u32 val) +{ + unsigned int addr = rkcif_mipi_id_get_reg(stream, index); + + if (addr == RKCIF_REGISTER_NOTSUPPORTED) + return; + + writel(val, stream->rkcif->base_addr + addr); +} + +static inline __maybe_unused u32 +rkcif_mipi_read(struct rkcif_interface *interface, unsigned int index) +{ + unsigned int addr = rkcif_mipi_get_reg(interface, index); + + if (addr == RKCIF_REGISTER_NOTSUPPORTED) + return 0; + + return readl(interface->rkcif->base_addr + addr); +} + +static inline __maybe_unused u32 +rkcif_mipi_stream_read(struct rkcif_stream *stream, unsigned int index) +{ + unsigned int addr = rkcif_mipi_id_get_reg(stream, index); + + if (addr == RKCIF_REGISTER_NOTSUPPORTED) + return 0; + + return readl(stream->rkcif->base_addr + addr); +} + +static void rkcif_mipi_queue_buffer(struct rkcif_stream *stream, + unsigned int index) +{ + struct rkcif_buffer *buffer = stream->buffers[index]; + u32 frm_addr_y, frm_addr_uv; + + frm_addr_y = index ? RKCIF_MIPI_FRAME1_ADDR_Y : + RKCIF_MIPI_FRAME0_ADDR_Y; + frm_addr_uv = index ? RKCIF_MIPI_FRAME1_ADDR_UV : + RKCIF_MIPI_FRAME0_ADDR_UV; + + rkcif_mipi_stream_write(stream, frm_addr_y, + buffer->buff_addr[RKCIF_PLANE_Y]); + rkcif_mipi_stream_write(stream, frm_addr_uv, + buffer->buff_addr[RKCIF_PLANE_UV]); +} + +static int rkcif_mipi_start_streaming(struct rkcif_stream *stream) +{ + struct rkcif_interface *interface = stream->interface; + const struct rkcif_output_fmt *active_out_fmt; + struct v4l2_subdev_state *state; + u32 ctrl0 = 0, ctrl1 = 0, int_temp = 0, int_mask = 0, vlw = 0; + u16 height, width; + int ret = -EINVAL; + + state = v4l2_subdev_lock_and_get_active_state(&interface->sd); + + active_out_fmt = rkcif_stream_find_output_fmt(stream, false, + stream->pix.pixelformat); + if (!active_out_fmt) + goto out; + + height = stream->pix.height; + width = stream->pix.width; + /* TODO there may be different factors and/or alignment constraints */ + vlw = ALIGN(width * 2, 8); + + ctrl0 |= active_out_fmt->mipi.dt << 10; + ctrl0 |= active_out_fmt->mipi.ctrl0_val; + ctrl0 |= RKCIF_MIPI_CTRL0_CROP_EN; + ctrl0 |= RKCIF_MIPI_CTRL0_CAP_EN; + + ctrl1 = RKCIF_XY_COORD(width, height); + + int_mask |= RKCIF_MIPI_INT_FRAME0_END(stream->id); + int_mask |= RKCIF_MIPI_INT_FRAME1_END(stream->id); + + int_temp = rkcif_mipi_read(interface, RKCIF_MIPI_INTEN); + int_temp |= int_mask; + rkcif_mipi_write(interface, RKCIF_MIPI_INTEN, int_temp); + + int_temp = rkcif_mipi_read(interface, RKCIF_MIPI_INTSTAT); + int_temp &= ~int_mask; + rkcif_mipi_write(interface, RKCIF_MIPI_INTSTAT, int_temp); + + rkcif_mipi_stream_write(stream, RKCIF_MIPI_FRAME0_VLW_Y, vlw); + rkcif_mipi_stream_write(stream, RKCIF_MIPI_FRAME1_VLW_Y, vlw); + rkcif_mipi_stream_write(stream, RKCIF_MIPI_FRAME0_VLW_UV, vlw); + rkcif_mipi_stream_write(stream, RKCIF_MIPI_FRAME1_VLW_UV, vlw); + rkcif_mipi_stream_write(stream, RKCIF_MIPI_CROP_START, 0x0); + rkcif_mipi_stream_write(stream, RKCIF_MIPI_CTRL1, ctrl1); + rkcif_mipi_stream_write(stream, RKCIF_MIPI_CTRL0, ctrl0); + + ret = 0; + +out: + v4l2_subdev_unlock_state(state); + return ret; +} + +static void rkcif_mipi_stop_streaming(struct rkcif_stream *stream) +{ + struct rkcif_interface *interface = stream->interface; + struct v4l2_subdev_state *state; + u32 int_temp = 0, int_mask = 0; + + state = v4l2_subdev_lock_and_get_active_state(&interface->sd); + + rkcif_mipi_stream_write(stream, RKCIF_MIPI_CTRL0, 0); + + int_mask |= RKCIF_MIPI_INT_FRAME0_END(stream->id); + int_mask |= RKCIF_MIPI_INT_FRAME1_END(stream->id); + + int_temp = rkcif_mipi_read(interface, RKCIF_MIPI_INTEN); + int_temp &= ~int_mask; + rkcif_mipi_write(interface, RKCIF_MIPI_INTEN, int_temp); + + int_temp = rkcif_mipi_read(interface, RKCIF_MIPI_INTSTAT); + int_temp &= ~int_mask; + rkcif_mipi_write(interface, RKCIF_MIPI_INTSTAT, int_temp); + + stream->stopping = false; + + v4l2_subdev_unlock_state(state); +} + +static void rkcif_mipi_set_crop(struct rkcif_stream *stream, u16 left, u16 top) +{ + u32 val; + + val = RKCIF_XY_COORD(left, top); + rkcif_mipi_stream_write(stream, RKCIF_MIPI_CROP_START, val); +} + irqreturn_t rkcif_mipi_isr(int irq, void *ctx) { + struct device *dev = ctx; + struct rkcif_device *rkcif = dev_get_drvdata(dev); irqreturn_t ret = IRQ_NONE; + u32 intstat; + + for (int i = 0; i < rkcif->match_data->mipi->mipi_num; i++) { + enum rkcif_interface_index index = RKCIF_MIPI_BASE + i; + struct rkcif_interface *interface = &rkcif->interfaces[index]; + + intstat = rkcif_mipi_read(interface, RKCIF_MIPI_INTSTAT); + rkcif_mipi_write(interface, RKCIF_MIPI_INTSTAT, intstat); + + for (int j = 0; j < interface->streams_num; j++) { + struct rkcif_stream *stream = &interface->streams[j]; + + if (intstat & RKCIF_MIPI_INT_FRAME0_END(stream->id) || + intstat & RKCIF_MIPI_INT_FRAME1_END(stream->id)) { + rkcif_stream_pingpong(stream); + ret = IRQ_HANDLED; + } + } + } return ret; } int rkcif_mipi_register(struct rkcif_device *rkcif) { + int ret, i; + + if (!rkcif->match_data->mipi) + return 0; + + for (i = 0; i < rkcif->match_data->mipi->mipi_num; i++) { + enum rkcif_interface_index index = RKCIF_MIPI_BASE + i; + struct rkcif_interface *interface = &rkcif->interfaces[index]; + + interface->index = index; + interface->type = RKCIF_IF_MIPI; + interface->in_fmts = mipi_in_fmts; + interface->in_fmts_num = ARRAY_SIZE(mipi_in_fmts); + interface->set_crop = rkcif_mipi_set_crop; + interface->streams_num = 0; + ret = rkcif_interface_register(rkcif, interface); + if (ret) + goto err; + + for (int j = 0; j < 4; j++) { + struct rkcif_stream *stream = &interface->streams[j]; + + stream->id = j; + stream->interface = interface; + stream->out_fmts = mipi_out_fmts; + stream->out_fmts_num = ARRAY_SIZE(mipi_out_fmts); + stream->queue_buffer = rkcif_mipi_queue_buffer; + stream->start_streaming = rkcif_mipi_start_streaming; + stream->stop_streaming = rkcif_mipi_stop_streaming; + ret = rkcif_stream_register(rkcif, stream); + if (ret) + goto err; + interface->streams_num++; + } + } + return 0; + +err: + for (; i >= 0; i--) { + enum rkcif_interface_index index = RKCIF_MIPI_BASE + i; + struct rkcif_interface *interface = &rkcif->interfaces[index]; + + for (int j = 0; j < interface->streams_num; j++) + rkcif_stream_unregister(&interface->streams[j]); + + rkcif_interface_unregister(interface); + } + return ret; } void rkcif_mipi_unregister(struct rkcif_device *rkcif) { + if (!rkcif->match_data->mipi) + return; + + for (int i = 0; i < rkcif->match_data->mipi->mipi_num; i++) { + enum rkcif_interface_index index = RKCIF_MIPI_BASE + i; + struct rkcif_interface *interface = &rkcif->interfaces[index]; + + for (int j = 0; j < interface->streams_num; j++) + rkcif_stream_unregister(&interface->streams[j]); + + rkcif_interface_unregister(interface); + } } diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.h b/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.h index ee1a50a59505..48d04a60c750 100644 --- a/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.h +++ b/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.h @@ -11,6 +11,8 @@ #include "rkcif-common.h" +extern const struct rkcif_mipi_match_data rk3568_vicap_mipi_match_data; + int rkcif_mipi_register(struct rkcif_device *rkcif); void rkcif_mipi_unregister(struct rkcif_device *rkcif); diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-common.h b/drivers/media/platform/rockchip/rkcif/rkcif-common.h index 32f6f0238656..99249a85048e 100644 --- a/drivers/media/platform/rockchip/rkcif/rkcif-common.h +++ b/drivers/media/platform/rockchip/rkcif/rkcif-common.h @@ -93,9 +93,14 @@ struct rkcif_output_fmt { u32 fourcc; u32 mbus_code; u8 cplanes; + u8 depth; union { u32 dvp_fmt_val; + struct { + u8 dt; + u32 ctrl0_val; + } mipi; }; }; @@ -183,6 +188,16 @@ struct rkcif_interface { void (*set_crop)(struct rkcif_stream *stream, u16 left, u16 top); }; +struct rkcif_mipi_match_data { + unsigned int mipi_num; + unsigned int regs[RKCIF_MIPI_REGISTER_MAX]; + unsigned int regs_id[RKCIF_ID_MAX][RKCIF_MIPI_ID_REGISTER_MAX]; + + struct { + unsigned int offset; + } blocks[RKCIF_MIPI_MAX - RKCIF_MIPI_BASE]; +}; + struct rkcif_dvp_match_data { const struct rkcif_input_fmt *in_fmts; unsigned int in_fmts_num; @@ -198,6 +213,7 @@ struct rkcif_match_data { const char *const *clks; unsigned int clks_num; const struct rkcif_dvp_match_data *dvp; + const struct rkcif_mipi_match_data *mipi; }; struct rkcif_device { diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-dev.c b/drivers/media/platform/rockchip/rkcif/rkcif-dev.c index 2adf04e46a37..98513feaf985 100644 --- a/drivers/media/platform/rockchip/rkcif/rkcif-dev.c +++ b/drivers/media/platform/rockchip/rkcif/rkcif-dev.c @@ -49,6 +49,7 @@ static const struct rkcif_match_data rk3568_vicap_match_data = { .clks = rk3568_vicap_clks, .clks_num = ARRAY_SIZE(rk3568_vicap_clks), .dvp = &rk3568_vicap_dvp_match_data, + .mipi = &rk3568_vicap_mipi_match_data, }; static const struct of_device_id rkcif_plat_of_match[] = { diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-interface.c b/drivers/media/platform/rockchip/rkcif/rkcif-interface.c index 5dcbf656073b..5ee09604fb92 100644 --- a/drivers/media/platform/rockchip/rkcif/rkcif-interface.c +++ b/drivers/media/platform/rockchip/rkcif/rkcif-interface.c @@ -188,7 +188,10 @@ static int rkcif_interface_enable_streams(struct v4l2_subdev *sd, stream = &interface->streams[RKCIF_ID0]; rkcif_interface_apply_crop(stream, state); } else { - /* TODO implement for MIPI */ + for_each_active_route(&state->routing, route) { + stream = &interface->streams[route->sink_stream]; + rkcif_interface_apply_crop(stream, state); + } } mask = v4l2_subdev_state_xlate_streams(state, RKCIF_IF_PAD_SINK, diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-regs.h b/drivers/media/platform/rockchip/rkcif/rkcif-regs.h index 07fd64174e80..3d1f0c45c638 100644 --- a/drivers/media/platform/rockchip/rkcif/rkcif-regs.h +++ b/drivers/media/platform/rockchip/rkcif/rkcif-regs.h @@ -30,7 +30,29 @@ enum rkcif_dvp_register_index { RKCIF_DVP_REGISTER_MAX }; -#define RKCIF_REGISTER_NOTSUPPORTED 0x420000 +enum rkcif_mipi_register_index { + RKCIF_MIPI_CTRL, + RKCIF_MIPI_INTEN, + RKCIF_MIPI_INTSTAT, + RKCIF_MIPI_REGISTER_MAX +}; + +enum rkcif_mipi_id_register_index { + RKCIF_MIPI_CTRL0, + RKCIF_MIPI_CTRL1, + RKCIF_MIPI_FRAME0_ADDR_Y, + RKCIF_MIPI_FRAME0_ADDR_UV, + RKCIF_MIPI_FRAME0_VLW_Y, + RKCIF_MIPI_FRAME0_VLW_UV, + RKCIF_MIPI_FRAME1_ADDR_Y, + RKCIF_MIPI_FRAME1_ADDR_UV, + RKCIF_MIPI_FRAME1_VLW_Y, + RKCIF_MIPI_FRAME1_VLW_UV, + RKCIF_MIPI_CROP_START, + RKCIF_MIPI_ID_REGISTER_MAX +}; + +#define RKCIF_REGISTER_NOTSUPPORTED 0x420000 #define RKCIF_FETCH_Y(VAL) ((VAL) & 0x1fff)