From nobody Fri Jun 12 14:18:25 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 902D93CFF4A for ; Thu, 7 May 2026 22:50:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194210; cv=none; b=pe24RvozsyEmyHRYqP3Mi3XjwhBcIYdzCNu45a33l2KvtqoZ58we3jClfgefq1WM+vUTGMlbWG2iOa4NeW0zUcYctL9no21zWBTO9oCpbDN4i0KrROTmQpOagtojeD08nndwLE8WaiAXUDLJOBrmLRIWihIDxlAUwOldCi41MkY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194210; c=relaxed/simple; bh=3/PXA8vkhOv7EJKuy7xYJV6ch+FY6mnuT3BK3IazYV4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qt4grkWmsQ/cK9FVbNa8iu6K/N/YcUhQ7ja93IiSMdUxj6J1we0wuzqjoVBnLOi1h8V3hxfmx4xG7LFPhCFk5RHkThvT6LqemlNsRfOJWqEmpwGIDk00HXlIpP4bqulyxo+2SuQclalL0T+uMaGk0lO8l7vQxu/G+TX7jtggfdU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=TTHU3Hzf; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=CuMx8bMg; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="TTHU3Hzf"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="CuMx8bMg" Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 647J7MCb2530922 for ; Thu, 7 May 2026 22:50:09 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= NNvpJoXiOTAqnoe0lRn4vTv9RKO5efKsHYJSTSQ49gc=; b=TTHU3HzfnLQX9hOb tMyE/tUP7kxxNeaiWJTHOm9ekM+e+Dr98sLps8N3230KYu/N9nEkbdZ/tx/QrAp+ kSxtAKre56rqMJM6mDB7TziQ60VV8xPiapxT9pIrhiK7WU9pLRi1NAfZ7mJQjPjR RQjl0Gm8bgjKpSgCrNBQXM3ivF3DgMXL0HmDfP7UIh81T3Ue8plvbNE0Yc/SkKcl ziezxCyv7ayDH72hv2sBOF5fBeVTwM5irGkQTnumQLhfkP4tsl9ElT40AU/vEKcA Q0OlEyWH9S22r7uZtfV9oafaugERuER2g7Ls35+oz21AwHLz42lmGXaPscVHRyeL V112HQ== Received: from mail-vs1-f70.google.com (mail-vs1-f70.google.com [209.85.217.70]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4e10m9rm10-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 07 May 2026 22:50:08 +0000 (GMT) Received: by mail-vs1-f70.google.com with SMTP id ada2fe7eead31-62ee100050eso2664800137.0 for ; Thu, 07 May 2026 15:50:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1778194208; x=1778799008; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=NNvpJoXiOTAqnoe0lRn4vTv9RKO5efKsHYJSTSQ49gc=; b=CuMx8bMgkH/V3CjKiCwBNPb6YUrqiRkEA9VutR3Gp0QRU5ly9lC4+izqJBFohk/AI7 YvRZ6jdqQWJOwU4F1rr3B7SHYBaAcM5WYMcAsBDru/q54Dcv5KfEy9g9I3LxZXyynh86 RW7OdFdaHi4laD7QXJTBX7z3yWjigeGKsU1Cl1bspsP+N0m4NNf5oGIrT59UVgwbQIc/ 9rkhqy0l1IP21+NdhzWBUxq8DQHXVdCdDCr1CheMWU8be/iVpjKh7kR1nl0IJ9AXyRI8 IH7JOL7LZIxfKDrNAiJev0R4y+v/hBBtJDmd36Bv2veArPTHMGw7+HxWZJl2o+3dlJUy /hEg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778194208; x=1778799008; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=NNvpJoXiOTAqnoe0lRn4vTv9RKO5efKsHYJSTSQ49gc=; b=gl3z2PNsvpyRIhLegsK7740Y/TL6pYF7Lcc9lu746ggTtfqnsnP/iqzN+ThNeZUG1O frMi49WOBf/UU1NSyiMC817HqrpZZrM/4DnmobUO/pJyEOnK7tW6+LR0pdESh6QsWzOS WEVmJe/PzuEz/AtCj8sxuqcX0ijw2Zck4t78dAEKXYhXJYj7sp51VbvOY/bjFlWNWDcY LDs+MrqZTeaBWULHE/izDPAo/019mu6PuaOLEKA+WVVWSDDC4xy1vqLWbJgyN95+rBLv TwZgQbqKAxOVOZHqgV9RxfZeoxn7GJDDt4eOjClImXAGtjbjIIyeOhS9kRvNrN9RcT97 Oywg== X-Forwarded-Encrypted: i=1; AFNElJ+bJc8Tvd6Grmu1xk24Wt/uiwhZ8KfyhJFMFn8ZKDeMmhn+wABvpdK6L8KSaPJEvY99T14M9ncKYG9d1gM=@vger.kernel.org X-Gm-Message-State: AOJu0YxPXgCzUrWkYCbS2xxkzdd8S4OSU6xBQ04iM+bQ3+D6gp2ImR6c BAL26s6R+Kl/NrE0v8foXQkZZ2oEwfc3Od3Hc4IUs7pXJ4n1s55pWxkVCaynUQmnZl7MeH2aIon /hdDW7sG8w2zOlAaOVLzPvsPHEHJ0dbeV94GcNKPJvm4SNY/Ef/D50izm+jwwdNiL8cE= X-Gm-Gg: AeBDiet0zIMwvJuIJUQskbuCDX5rM5FcHYtTPgv0RqdrW6QIoGr5nsj93qokYF3VSQA YHrQIKAXqZb11c77eLq04Tfv4cHf7bV4R3gnPfiaJY4kQ7STfTuC1nxMCTFSvhySKJr2VgbZ6ZK +iwOJuVM6NgNCQjYxpxnV7KWzUSZwX5wHR6DvLNkKWQ6XQRKxlP3jbXw3yWZrowcz7pu+r9bvXe 4yf3om8mwrrC3wX/dyJqtIOwHgfGgxj1DfK/Z33IYCoReXQG/PIAqM5WHxV8Xw6C3C+2HMtEuLL WiANSEk3N4dOlYiSz0/a7TMuabBtkxJRojeYjXgwP6MzorUjAyYAki7MjhBhhLlt+jCb7sIW9FR Jh2BCsLGJhTlB0cS2/4T07rE3tC2IzBWgJHh54I41LAcj1aLnjumzc0qgj1sXMEBCzEKmUHFyG/ VtwQbxS/LHN1iTSZB4iG2PWss8iNA= X-Received: by 2002:a05:6102:3048:b0:614:bef5:637c with SMTP id ada2fe7eead31-630f8c2bb7dmr5807135137.0.1778194207826; Thu, 07 May 2026 15:50:07 -0700 (PDT) X-Received: by 2002:a05:6102:3048:b0:614:bef5:637c with SMTP id ada2fe7eead31-630f8c2bb7dmr5807109137.0.1778194207421; Thu, 07 May 2026 15:50:07 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:b16a:3475:ec42:bcfa]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bcac4359dbesm102466b.48.2026.05.07.15.50.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 May 2026 15:50:05 -0700 (PDT) From: Loic Poulain Date: Fri, 08 May 2026 00:49:16 +0200 Subject: [PATCH v3 01/15] media: qcom: camss: Add PM clock support and integrate with runtime PM Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260508-camss-isp-ope-v3-1-bb1055274603@oss.qualcomm.com> References: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> In-Reply-To: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> To: Bryan O'Donoghue , Vladimir Zapolskiy , Loic Poulain , Mauro Carvalho Chehab , Kees Cook , "Gustavo A. R. Silva" , Bryan O'Donoghue , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio Cc: linux-media@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devicetree@vger.kernel.org, laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com, johannes.goede@oss.qualcomm.com X-Mailer: b4 0.14.2 X-Proofpoint-GUID: HCSOBaFtUHOXV4L7LiyUlRsYRQzajnnL X-Authority-Analysis: v=2.4 cv=VP3tWdPX c=1 sm=1 tr=0 ts=69fd1720 cx=c_pps a=N1BjEkVkxJi3uNfLdpvX3g==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yOCtJkima9RkubShWh1s:22 a=EUspDBNiAAAA:8 a=KmNvnciZBadtvzOit0AA:9 a=QEXdDO2ut3YA:10 a=crWF4MFLhNY0qMRaF8an:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTA3MDIzMSBTYWx0ZWRfX9j3knGBCFsxg LEvPVXJrJERTxl3V70tto9xubB0dqnKBOCaVG3eBeDVt0elDWeL3SWZEaH0kcg4ctELI6b/0uoV neqRenAgF0YNY1CDwrKq2TDPmMrZHRZwDV2/z71/Aw0g/wk/2+EikIAs9kvfJC74/OgtnvbAiCU 9EPqK5FJdL1xMRrHlp96JRP0RbkfcdUAq1AR2KV7g/1TP8AUvyEMqO1RfQjzQ7SkznO6nT946st t5tMDjir+nycoLiSi6pCqWv2PjqyBv8YDhH32SQeydnZBi3cfj5FiewPA0Kq9hZbQUvVKvJgAaC vh5ItIIOb+C4SjYcSDwioqtsLOXC8ez8yUfNQQLONeTl/l8zwumHl57ANSbDjDRNW1BOl6CksmT WJydCCpxFpORBRJCQmj3t/UPwGGt9EnNyp70UfSsYCrR1eE0LsUbEzHaZJTsGu3EQlDJvHIWVSQ FKFUs9tZGE16l9zTwaA== X-Proofpoint-ORIG-GUID: HCSOBaFtUHOXV4L7LiyUlRsYRQzajnnL X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-05-07_02,2026-05-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 spamscore=0 bulkscore=0 impostorscore=0 lowpriorityscore=0 malwarescore=0 clxscore=1015 suspectscore=0 phishscore=0 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2605070231 Add optional PM clock support to the CAMSS driver using the PM clock framework. This allows CAMSS clocks to be registered once and automatically managed during runtime suspend and resume. This is especially useful for global CAMSS clocks that are shared across multiple CAMSS subnodes. Now that CAMSS is modeled as a simple-bus, these clocks are automatically enabled whenever a child node becomes active. This avoids the need for each subdevice to reference and manage the shared clocks individually. A typical example is the set of clocks in the top_group, which may be used by CSID, PHY, CCI, OPE, and other CAMSS blocks. Introduce a small PM clock descriptor table in the CAMSS resources structure to describe clocks and their optional rates. Initialize these clocks at probe time and delegate clock ownership to the PM core. Hook PM clock handling into the runtime PM callbacks to ensure clocks are properly suspended and resumed alongside power domains and ICC paths. Signed-off-by: Loic Poulain --- drivers/media/platform/qcom/camss/camss.c | 41 +++++++++++++++++++++++++++= +++- drivers/media/platform/qcom/camss/camss.h | 1 + 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/plat= form/qcom/camss/camss.c index 36c601c595053ddad8d327b1416d7ff587920174..c37d5bfb4072d4d94a8abd453b8= 9c9aad7e15001 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include =20 @@ -4592,6 +4593,36 @@ static void camss_genpd_cleanup(struct camss *camss) dev_pm_domain_detach(camss->genpd, true); } =20 +/* + * camss_init_pm_clks - register shared CAMSS clocks with the PM clock fra= mework + * + * Clocks listed in res->pm_clks are shared across all CAMSS sub-devices (= e.g. + * top_ahb, axi). We kept them on for the lifetime of any active child, ma= naged + * automatically by the PM framework. + */ +static int camss_init_pm_clks(struct camss *camss) +{ + struct device *dev =3D camss->dev; + unsigned int i; + int ret; + + if (!camss->res->pm_clks[0]) + return 0; + + ret =3D devm_pm_clk_create(dev); + if (ret) + return ret; + + for (i =3D 0; i < CAMSS_RES_MAX && camss->res->pm_clks[i]; i++) { + ret =3D pm_clk_add(dev, camss->res->pm_clks[i]); + if (ret) + dev_warn(dev, "failed to add pm_clk %s: %d\n", + camss->res->pm_clks[i], ret); + } + + return 0; +} + /* * camss_probe - Probe CAMSS platform device * @pdev: Pointer to CAMSS platform device @@ -4674,6 +4705,10 @@ static int camss_probe(struct platform_device *pdev) =20 pm_runtime_enable(dev); =20 + ret =3D camss_init_pm_clks(camss); + if (ret) + goto err_v4l2_device_unregister; + ret =3D camss_of_parse_ports(camss); if (ret < 0) goto err_v4l2_device_unregister; @@ -4981,7 +5016,7 @@ static int __maybe_unused camss_runtime_suspend(struc= t device *dev) return ret; } =20 - return 0; + return pm_clk_suspend(dev); } =20 static int __maybe_unused camss_runtime_resume(struct device *dev) @@ -4991,6 +5026,10 @@ static int __maybe_unused camss_runtime_resume(struc= t device *dev) int i; int ret; =20 + ret =3D pm_clk_resume(dev); + if (ret) + return ret; + for (i =3D 0; i < camss->res->icc_path_num; i++) { ret =3D icc_set_bw(camss->icc_path[i], icc_res[i].icc_bw_tbl.avg, diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/plat= form/qcom/camss/camss.h index 9d9a62640e25dce0e8d45af9df01bbfd64b9bb4b..44599abce4a850afa7cf0e38c45= 3c4a7b54e4e25 100644 --- a/drivers/media/platform/qcom/camss/camss.h +++ b/drivers/media/platform/qcom/camss/camss.h @@ -103,6 +103,7 @@ enum icc_count { struct camss_resources { enum camss_version version; const char *pd_name; + const char *pm_clks[CAMSS_RES_MAX]; const struct camss_subdev_resources *csiphy_res; const struct camss_subdev_resources *csid_res; const struct camss_subdev_resources *ispif_res; --=20 2.34.1 From nobody Fri Jun 12 14:18:25 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 A73083B27F1 for ; Thu, 7 May 2026 22:50:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194214; cv=none; b=gd05TzknGDY+nOAwaavNdQa8lYzofAYcY5w9Ut7GBLHkvET+I3Opkdp/GkkTO6v8KW7IpoQPdzfjYUqNr3FsUrez+ej9pt+2JOxmW/Ywu0drVTRVi1jzvP6ww1yRDTklw0+MJBeTpObP53o06JMthuziV6HtAXAA1JyAM3i5u8E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194214; c=relaxed/simple; bh=DeoGvIk2JM6d3iYKy2epXQEX0HxjaKrwSQKtJe5us/o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=XMGcRjb6vsZlGO1P5cS9rxwqEdXnJ8u371jZUo5BEM+IEOUdsJqLMI3qSUMrKjFBY6h4fAHizOq6lIvWQnupdKUZqltDFD6TANCEZtjiqbjfLQH37Q2IH+AgQr6s1Xj826+Lbt/CZqhP+QJItzX+XkmP7bBpk14QunWtvPKnMPI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=mCQoeyTp; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=hY84Ia4U; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="mCQoeyTp"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="hY84Ia4U" Received: from pps.filterd (m0279871.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 647LYTJ61424474 for ; Thu, 7 May 2026 22:50:11 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= c9vAhl3V7MUdd4qjbESfTeY51BTylAF+5R3us3v248k=; b=mCQoeyTpvVA7XDYn ZJ3rL90ZeOGF12kxncfq0nwsHq0+hl9jeWIqVrJyX34O39r6SHIQuPGMBduHpyeQ uV32k9OdLE91iCmWbyfcEgi7EQnxrBHnynuYk2XknEWh9EszpJgM08yjF/BVDW+6 nLsHvSLahnbyUZGVpc/9qsrv7lUr5j/9RxW2vZxlwuKGOTjknbCQ4mkfoO4E2QCb AP9PMNeNN5mgW1+xhf9TPCwYOcwZN+Xls53EMqkDBYDGoGM913ftm5DNl7xLBWam E7jFutzSm4uhPoc2w2Kcr5hYr7oiZgRAb6coakDzXDhePcAjZsoXDcd2mIsdIoV/ uGk1OQ== Received: from mail-ua1-f70.google.com (mail-ua1-f70.google.com [209.85.222.70]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4e0pqfub81-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 07 May 2026 22:50:11 +0000 (GMT) Received: by mail-ua1-f70.google.com with SMTP id a1e0cc1a2514c-95cf2f6a8d6so3246106241.1 for ; Thu, 07 May 2026 15:50:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1778194211; x=1778799011; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=c9vAhl3V7MUdd4qjbESfTeY51BTylAF+5R3us3v248k=; b=hY84Ia4UACwUitlRjctguziFEGWLtwiJU5yxbCZbmLM3QIHWabZ9D0m2oO+7u7Yqcq fXdEcXDqM86PCWjjXvHakGpxgWPYBN5jCMQ/h24ef1gadthThUfBLDZOszeW6NVs0qvu PnbhfDZIOH7enMVbYtMEcQrNbrOjSoYGmhWhKyHw8eWZT1QsN9Nflk3Q/yy3/9NAtEIy HuF1UzN0RlZICpmEplkKm+XqMksPkaZcSsKeuDyrtuzuPn4VcjyqciCHtL+t5km914gr s/2rB8hWAw/wQ4i2LOn+jIlF1xwu1NCxWhfLLdueQY28jP8MY3wC8BrlUtD+YHwJQYNS IuLg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778194211; x=1778799011; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=c9vAhl3V7MUdd4qjbESfTeY51BTylAF+5R3us3v248k=; b=m0w6mzKxbBUItfK+u5UIlxKoTAWtNkQKdiZxP+ljxNye9cYk019lg08/ow3TOBJ/Xo iSiywWReq2lziEqDGQMJh9YhVFO6CdXGtKvjJo+EuS08l4cW2hVHNkCgl+6tII8APsM8 vv4gaoADW+l8k9RdwUw3YfPQtO877+6/Wf2GPy8zlNcyeslKB319UM0P0IvCmZSMKYSA JeLumhpyrOQDpY3IvZ/gSLXoepU/9bD6zX0s6aaNB4SsyxKwC7DwNQEuU/xVLkqSGf/x 0nXqpNkA8aDF82EeSAi0nZDMERfTjoszXMuv7ublUFvQ6Dr9qVRti1qQ7fslRGBVF1uX 2BrA== X-Forwarded-Encrypted: i=1; AFNElJ8shif9rERLw5k/I08a+VSxj417P6Yc5C2sCJElOhY/j3D9KWJv39mENhGQJpeUjYyYF1UxbpfLYEylbK4=@vger.kernel.org X-Gm-Message-State: AOJu0YwOgwJihlCrmOK4F7kMwKR2fDFtVBxvxlo8A7xCUHR/rdrXk0vo KW+QUQzC6bMgvv/8G3DoOTWoMuSIQhQv3vPvOn8P+HyofZxeUZSnyB7eSKdcmohXMrlfFtcU9fq cGmi3wzLd+kubaExX1V0j0URCpncW8dzcDxg0xQpaklk3m/gvHcl9QVxKztKxWes0DiY= X-Gm-Gg: AeBDiesuCcqv2JdwBiTsf4laYJ41+4Qza+LI4GJxQLIv7h4NDGbWLDomfIoTb9mus9n LRrt338BnzruL3l/ee64GH4Z7ZpUuYIR96PFPTqbglAqFwspBUyoQz9JWhz6EDDeXR/aXcMWdAU syqZXeJuOCcLtYyF0RXaI5u2KGijpBMlMqcxoqMF5loTkdyajVPXWgM9yqmPIc28PK+xbPnG+ug eWZM0ZPF5Zlk/nk6ifXJhmb2hICd+l0K7rv2B77Jg2ozHwlYaha1fpKA4RsIxZXTdWgtmFExmon uC0/Nv3psLHHfhPuE1A0QedV6WchyT+0HRuMFfb5ZGf7Y8y3gxzlDj65KV8Y5xTYiSIvu2aRwqg vTuzt7RrAPkUOqIyeiR1d/vvDZTSgwr7J/1bP8Z+79atqF0vtehqDhJgoCyC0Cc5s3DHARLBZSo NzUQP6vNbYNojdCEW9 X-Received: by 2002:a05:6102:32d0:b0:607:d68f:d0f6 with SMTP id ada2fe7eead31-631160350cfmr2101563137.20.1778194211135; Thu, 07 May 2026 15:50:11 -0700 (PDT) X-Received: by 2002:a05:6102:32d0:b0:607:d68f:d0f6 with SMTP id ada2fe7eead31-631160350cfmr2101543137.20.1778194210720; Thu, 07 May 2026 15:50:10 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:b16a:3475:ec42:bcfa]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bcac4359dbesm102466b.48.2026.05.07.15.50.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 May 2026 15:50:09 -0700 (PDT) From: Loic Poulain Date: Fri, 08 May 2026 00:49:17 +0200 Subject: [PATCH v3 02/15] media: qcom: camss: Add PM clock definitions for QCM2290 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260508-camss-isp-ope-v3-2-bb1055274603@oss.qualcomm.com> References: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> In-Reply-To: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> To: Bryan O'Donoghue , Vladimir Zapolskiy , Loic Poulain , Mauro Carvalho Chehab , Kees Cook , "Gustavo A. R. Silva" , Bryan O'Donoghue , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio Cc: linux-media@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devicetree@vger.kernel.org, laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com, johannes.goede@oss.qualcomm.com X-Mailer: b4 0.14.2 X-Authority-Analysis: v=2.4 cv=TJB1jVla c=1 sm=1 tr=0 ts=69fd1723 cx=c_pps a=R6oCqFB+Yf/t2GF8e0/dFg==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=3WHJM1ZQz_JShphwDgj5:22 a=EUspDBNiAAAA:8 a=gZ4aIBoJpEVIEF-KsNAA:9 a=QEXdDO2ut3YA:10 a=TD8TdBvy0hsOASGTdmB-:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTA3MDIzMSBTYWx0ZWRfX4DRm023OyByz WxteeiB4xqvevK+1RUUsoXmibUcwIoFda6SBuYoiCNQH7HipeNQqrEn8zMT5/hP9wBIWZF4FgZP 5xrH7kvLVs6jhqXvG5+gsr98u8jEsV/K2qlXU7H/rqURN5GYc/43z6pPLvmkytO3zuDgeE98yF1 0NPFNNjPmpX1l097SBKm5qsF0CbAL6eGoBdwp/LMZHlG/B/zq8QKsS+GXo3ZhkTUWfuCwAlLXGo ejtea5thsg+gprS1S9UcA1jmMkj6J1c3ZTn6cfCSLV6U2wdPM2tMm/sOvuI1ImlqIcIMZp9TmTi C2m3c9xU7vOz+UDNxWUUcLbL9iPRC+GSfiU1Bc6Q+JfQDtc7icnh2VfxlnoAdjDxP80u/DbMhTT 0Ekjnx8+zvcW2Q4A2sOy0nzDsggPcL5mEj0eIkV0vw8UFc3w6ZhwmyW3R2dj3gd0oDzy18OPELW pTmqkeqy0UcL3WbwbpA== X-Proofpoint-GUID: xM1tygMoK8P_CnJS1ddDGE1PxpgJ7frG X-Proofpoint-ORIG-GUID: xM1tygMoK8P_CnJS1ddDGE1PxpgJ7frG X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-05-07_02,2026-05-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 lowpriorityscore=0 malwarescore=0 impostorscore=0 bulkscore=0 phishscore=0 priorityscore=1501 adultscore=0 spamscore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2605070231 Provide the required CAMSS PM clock descriptors for the QCM2290 platform. Register the top_ahb and axi clocks with their appropriate nominal rates so they can be managed automatically through the PM clock framework (both are part of the camss-top group). Signed-off-by: Loic Poulain --- drivers/media/platform/qcom/camss/camss.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/plat= form/qcom/camss/camss.c index c37d5bfb4072d4d94a8abd453b89c9aad7e15001..3bde26c4750ea932ea69fdbf5c5= da9f959e5e5e2 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -4830,6 +4830,7 @@ static const struct camss_resources msm8996_resources= =3D { =20 static const struct camss_resources qcm2290_resources =3D { .version =3D CAMSS_2290, + .pm_clks =3D { "top_ahb", "axi" }, .csiphy_res =3D csiphy_res_2290, .csid_res =3D csid_res_2290, .vfe_res =3D vfe_res_2290, --=20 2.34.1 From nobody Fri Jun 12 14:18:25 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 577DE3D349F for ; Thu, 7 May 2026 22:50:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194216; cv=none; b=NIPuyWdlG9ucShA0MY7+mYrKpXs6akPPwjA3VqwwLfD5z1fMWKxAe5WSrVTeGLktJ+FSwHQSSbk5n0NfviovpBslp8m1BOliU4ytOizT8NfScVrSb5d5IvexPwC2kyfxj7GqspN1QkJdRsWBwjUmMoqOzjxGKSBH5Hy5RHLeo8g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194216; c=relaxed/simple; bh=d6sTldzr20rxqyeexiCHog1RigxMQcbtDegyP5w3YpA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=u9OWlUhXdNYttNtCZA+QZBde3nw8OnVnU1oMbHUkRW1sjnbMVPhQ17A8PrdFv9UFYiUxKe8+ZNurcz9yW6UbazDlTTscknwBAizxtr37bnE/ihhf3Rva5qWGxW5faRc7ic1tryPEfi3D2TUj5Ncwfzazdbr58mv9banAWVFzNlU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=mi5j+ZlJ; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=ArQpPrT2; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="mi5j+ZlJ"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="ArQpPrT2" Received: from pps.filterd (m0279870.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 647JrWfw2199585 for ; Thu, 7 May 2026 22:50:14 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= dQvxefKofl/MWew8drQPijHpKnkbQHmoKvevMGmHYPQ=; b=mi5j+ZlJdbfKBhd1 Y6dLOtI2uozcHYMzVfe/0bwdeUBpGEvTuBh1uFUtEEdXlr0kkxbSjrZ0MbxG/Wc/ 2WiCDHULMGVuZe9n6J+HPk+eD1WZ4ycoo3v5d/bGEpJAmQbITKQb4hfRUYsrvfWA WYSkjH+OMJNTAfz/V5sjF1flMIS66yv1a06AWW5tTeimaa7FbUZxhubAmwWBbisq BEC8Xhipbp2t50SYtGzCtcJ/JgzuG8mF5ZFoPcW+2KPBYcJqaRl9zAhKnz5hUk3P Bq64Mit6uPyOUgzklRt6mkfNf6O7U+jDAzXrzMIStmfqAH+79bnQKQsd5g+D6Zz2 UPJlZQ== Received: from mail-ua1-f71.google.com (mail-ua1-f71.google.com [209.85.222.71]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4e119sgg66-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 07 May 2026 22:50:14 +0000 (GMT) Received: by mail-ua1-f71.google.com with SMTP id a1e0cc1a2514c-95cfcad1f82so1077402241.2 for ; Thu, 07 May 2026 15:50:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1778194214; x=1778799014; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=dQvxefKofl/MWew8drQPijHpKnkbQHmoKvevMGmHYPQ=; b=ArQpPrT2oMGZeCYJKXVyrIkUPhB6yI7Qm/Sze8dFw7bFuc/7albtp+Sj2JtJgjVhSJ FKTdh/ouj9RcIL/x95DsDVTNgRW6H+NO11ZVGfHwNC5NEheAqxxico7ws9SsL7/OzJAW xglhmxEgxuq2xu3WwhSOJk5BEEM9OV96yxQQ3nAKRBUNWpNgccWTjnVPsAwhQ02HKgjV P/koEXgJ28DdCVQYBUkUHl/sQuBGbnTfB1I8NDXOXjqNqDbz0RqlHqkKG4L6PsVoYoWP V1Ef8bxPL+3T+4jgxGAu6pZG+N+MzBJG3HM6wuP8CvXtGlLgaY3Tv+A/+ugJqsUQxHBE VfLA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778194214; x=1778799014; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=dQvxefKofl/MWew8drQPijHpKnkbQHmoKvevMGmHYPQ=; b=E0WJhZkxQQ+jnIPBOt53ZNSgwRmayCzRGn8XNk1dsIiWk7HFD0KTMKwma6XbgH4aSS GWsrWqszbg+auxquqs3hC5Mp2xM99v94h8VMTTHpRWdThCoX78WOMP1g8YjLjrsLO7G6 WuRGFigawvWHzh5bQUiZBOkVeMy8ulmq/vxerYsPCAk3UaZdx7Yp8j1yvC1ycrSHEQKS JxTV8vVClZ3F8eiGQ6PC53ze7Ls6DpvZAqFZPzlaOtb1eU+X35iVkmWdb6HKR7baSoVg 4a2noI82K9Rim3zURspCG96bx5uF6Cjbl2XOcFzpLOirNbWem7XaXPVDxGfTzoJOvJT9 4LOQ== X-Forwarded-Encrypted: i=1; AFNElJ9/QOYrO+dm78r1pHyGZ2NMdEUASgZmCz+bqS9gFbrpY3gT0DrApMlqCKVnweBtIfB+NOc/9Asi+O96b24=@vger.kernel.org X-Gm-Message-State: AOJu0YwNvAv7srPwX5b4m9KM3AUv3eo+ySDf6u9Hmm34YsSxYTZgjNkm /qA4ky/I6eLBx0vhryJN7ytHTFaCO3NLZe7L1v9WjCP9wc03UrWaFUgznMcgCeA38k1zSdltXjQ 3CyoWT7aidy7O9tkiZhxrkmNTLwBaWjBWGIVQtV16GjwTeeq+LjY+KnRmtlGnY6Uhg7c= X-Gm-Gg: AeBDievF06Bw3Oh6pyTyYUvKuM+MIvgkE4VhG/lc3udUprsrHPUSDsJgUFAHkCKpcZU 1sok7yJ1UwcZbaPzSUMQ6HOpihmjwGfYWj6wblXrNIQ8czPGQSHfJXLlsHplxkpoJNVzLUTc8qC QUuTtt9+NxUukcFusX5ASKYAy+mFdbkQkD7i3NiA/HrUA+FR4OFWRWXXjXuANyoL2gotxCAt6Bq LPGcpmyXZaJfhCVr3tBIzwtvkPQwPIpc/fubWb5iW7pLeSl6QimuqFxYV0ImcO+jBusoqOzk4uc wKGbwteaH2+1c8MPLkaX9pybWpIV6aQHv2NQDHnkqte6TkGuvdrXLvk0ykYjgJ9HXeWdwX0nr4/ VxZfkyUTdB0pQz6C1MMw5lOH0IM1ihuBz/Oxm2SSLnERGlLqS1741toJiGIV59RCz0E1z2f+fCr aomr+cxu29/ukuTKeI X-Received: by 2002:a05:6102:b01:b0:631:3b92:9dcc with SMTP id ada2fe7eead31-6313b92aa4emr424417137.27.1778194213788; Thu, 07 May 2026 15:50:13 -0700 (PDT) X-Received: by 2002:a05:6102:b01:b0:631:3b92:9dcc with SMTP id ada2fe7eead31-6313b92aa4emr424408137.27.1778194213371; Thu, 07 May 2026 15:50:13 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:b16a:3475:ec42:bcfa]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bcac4359dbesm102466b.48.2026.05.07.15.50.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 May 2026 15:50:12 -0700 (PDT) From: Loic Poulain Date: Fri, 08 May 2026 00:49:18 +0200 Subject: [PATCH v3 03/15] media: qcom: camss: Drop top_ahb/axi from QCM2290 subdevice clocks Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260508-camss-isp-ope-v3-3-bb1055274603@oss.qualcomm.com> References: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> In-Reply-To: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> To: Bryan O'Donoghue , Vladimir Zapolskiy , Loic Poulain , Mauro Carvalho Chehab , Kees Cook , "Gustavo A. R. Silva" , Bryan O'Donoghue , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio Cc: linux-media@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devicetree@vger.kernel.org, laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com, johannes.goede@oss.qualcomm.com X-Mailer: b4 0.14.2 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTA3MDIzMSBTYWx0ZWRfX+lWGe0xUfwXK D8WF/v4SJealUaV93b/oK2VbbZkxi6Z2mcakfwcyfrj03QAberTzPRbomkdzZulHn9IPWL2bcS2 Da3gEknQAQq0Z4cKo0OOJ3dkuVGTkh1wBTfMm0UzhIg8LEdHWT3PTADx/hV5fbDOMWv/Zacgaju i3ScqpCkNlQYvLQONdqrVX+8DvS/dkL603gosmGbCbC8/EYiYx4ppAFTH3QCxX2FAuPs70ygMXC 0q4iuCZTRxfFG1K5h9e8IbcZ2ZwKfZS2cRUY58BJQrbFkN+lxcyEomy1Jay47VMbGQWYU6B3sKE uSym2SmOgS554ORbjhn9PyWQzBXeBI/3H5CzjRJv9niqTihzHBOXs79gUunqe32iUf2nNAOOwXo uLuk4hAHcmLEskwO0Z2YU22+DB8uhKPQ5z+ynCiBYsW5oHQoS/hAbhhNSNkCilFrn5KTJOH3bCD 6/q8PMBJ/PzU4FKXLkQ== X-Proofpoint-ORIG-GUID: qTz_HWnBzJWPuSnm_UfIr7LEiSIWfxNt X-Proofpoint-GUID: qTz_HWnBzJWPuSnm_UfIr7LEiSIWfxNt X-Authority-Analysis: v=2.4 cv=Dd4nbPtW c=1 sm=1 tr=0 ts=69fd1726 cx=c_pps a=KB4UBwrhAZV1kjiGHFQexw==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=gowsoOTTUOVcmtlkKump:22 a=EUspDBNiAAAA:8 a=yFrQIQtVvbDJ7NVWecMA:9 a=QEXdDO2ut3YA:10 a=o1xkdb1NAhiiM49bd1HK:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-05-07_02,2026-05-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 bulkscore=0 clxscore=1015 adultscore=0 lowpriorityscore=0 suspectscore=0 spamscore=0 impostorscore=0 phishscore=0 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2605070231 Remove the top_ahb/axi clocks from QCM2290 subdevice clock lists. These clocks are now handled centrally as a global CAMSS PM clock and are automatically enabled when any CAMSS child is active. This avoids redundant clock references in individual subdevices and ensures consistent clock management across the CAMSS pipeline. Signed-off-by: Loic Poulain --- drivers/media/platform/qcom/camss/camss.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/plat= form/qcom/camss/camss.c index 3bde26c4750ea932ea69fdbf5c5da9f959e5e5e2..0ceab12d573ee7521d44b77d23e= e563930d6aac3 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -663,9 +663,8 @@ static const struct camss_subdev_resources csiphy_res_2= 290[] =3D { /* CSIPHY0 */ { .regulators =3D { "vdd-csiphy-1p2", "vdd-csiphy-1p8" }, - .clock =3D { "top_ahb", "ahb", "csiphy0", "csiphy0_timer" }, + .clock =3D { "ahb", "csiphy0", "csiphy0_timer" }, .clock_rate =3D { { 0 }, - { 0 }, { 240000000, 341330000, 384000000 }, { 100000000, 200000000, 268800000 } }, .reg =3D { "csiphy0" }, @@ -680,9 +679,8 @@ static const struct camss_subdev_resources csiphy_res_2= 290[] =3D { /* CSIPHY1 */ { .regulators =3D { "vdd-csiphy-1p2", "vdd-csiphy-1p8" }, - .clock =3D { "top_ahb", "ahb", "csiphy1", "csiphy1_timer" }, + .clock =3D { "ahb", "csiphy1", "csiphy1_timer" }, .clock_rate =3D { { 0 }, - { 0 }, { 240000000, 341330000, 384000000 }, { 100000000, 200000000, 268800000 } }, .reg =3D { "csiphy1" }, @@ -699,9 +697,8 @@ static const struct camss_subdev_resources csid_res_229= 0[] =3D { /* CSID0 */ { .regulators =3D {}, - .clock =3D { "top_ahb", "ahb", "csi0", "vfe0_cphy_rx", "vfe0" }, + .clock =3D { "ahb", "csi0", "vfe0_cphy_rx", "vfe0" }, .clock_rate =3D { { 0 }, - { 0 }, { 192000000, 240000000, 384000000, 426400000 }, { 0 }, { 0 } }, @@ -717,9 +714,8 @@ static const struct camss_subdev_resources csid_res_229= 0[] =3D { /* CSID1 */ { .regulators =3D {}, - .clock =3D { "top_ahb", "ahb", "csi1", "vfe1_cphy_rx", "vfe1" }, - .clock_rate =3D { { 0 }, - { 0 }, + .clock =3D { "ahb", "csi1", "vfe1_cphy_rx", "vfe1" }, + .clock_rate =3D { { 0 }, { 192000000, 240000000, 384000000, 426400000 }, { 0 }, { 0 } }, @@ -737,10 +733,8 @@ static const struct camss_subdev_resources vfe_res_229= 0[] =3D { /* VFE0 */ { .regulators =3D {}, - .clock =3D { "top_ahb", "ahb", "axi", "vfe0", "camnoc_rt_axi", "camnoc_n= rt_axi" }, + .clock =3D { "ahb", "vfe0", "camnoc_rt_axi", "camnoc_nrt_axi" }, .clock_rate =3D { { 0 }, - { 0 }, - { 0 }, { 19200000, 153600000, 192000000, 256000000, 384000000, 460800000 }, { 0 }, { 0 }, }, @@ -757,10 +751,8 @@ static const struct camss_subdev_resources vfe_res_229= 0[] =3D { /* VFE1 */ { .regulators =3D {}, - .clock =3D { "top_ahb", "ahb", "axi", "vfe1", "camnoc_rt_axi", "camnoc_n= rt_axi" }, + .clock =3D { "ahb", "vfe1", "camnoc_rt_axi", "camnoc_nrt_axi" }, .clock_rate =3D { { 0 }, - { 0 }, - { 0 }, { 19200000, 153600000, 192000000, 256000000, 384000000, 460800000 }, { 0 }, { 0 }, }, --=20 2.34.1 From nobody Fri Jun 12 14:18:25 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 C80273D413A for ; Thu, 7 May 2026 22:50:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194220; cv=none; b=m5HVEVuPlWNitM8m9IsdmRUAhrYkkzixn1NZFPPzkFvfQRSBIEBE0qjdpAAfW6jxiCHE3GL/U2XmmrQx4sWaVl1Eijac/3+jXPsGLbbSosQmlSlZD+9JgLeLXQxQfSli1b9A1gByMWeo1ELlPf9pgvAjbydztirUTxWhSpxa6wI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194220; c=relaxed/simple; bh=7Krz7pN0WV1WEwE+SM/17Byvte7UfrNb2WulyP8M938=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KL2t4vweDo/aOsNxR4glQE8iILSWoUnqRDKGWPmY5p4CLgCZ3wUq0c3vVQ0K1pSYCBOKQYCCssVIewR5BRHkWt8zGp13Oitut34N5h8nFyz1sw4S8ej/h8nNA5cKndPAOglkF+PHOO06S7vonMCceDeWhDYsttQnlE4FYdk1aDo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=aEqAB1J2; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=RX84c+y5; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="aEqAB1J2"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="RX84c+y5" Received: from pps.filterd (m0279871.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 647L5rOB1424511 for ; Thu, 7 May 2026 22:50:17 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= 9MkPXhNFKpgj51RT3nXElFSkq09L7clUycFsPNU23WU=; b=aEqAB1J2DNsPcjx9 jt6JhCscOwesf++9Opc/65eYqOp9+o9pH0P1OK0YX/DoQqFuGZkL6bKiMGyaGhBi PYIOBMk0+NKRy4Tc07QkEyMlUq3vNYLvjqJlmqHqwyLedYLUVGDy+dQOmVNMKj8m mHIa4qdfP9dcDxyrE0L0g8y0WhLJqpqMsJXW0Qa6W0Xw9uljkJ70x37gxigrp2ft MWo7nnRtFniQQMFnz7b2w6pA/+EYUq6F3cOvgdwXrb/ykr7CJPqHJdgbVw3MtgEu f4MPSYU8hA8KqaF7+CZV4meeTP7ow9Lss4NxwzHZVs3JtFCKDBC67E7ukK5cG97Y 1N8SRQ== Received: from mail-ua1-f70.google.com (mail-ua1-f70.google.com [209.85.222.70]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4e0pqfub8d-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 07 May 2026 22:50:17 +0000 (GMT) Received: by mail-ua1-f70.google.com with SMTP id a1e0cc1a2514c-95cc77982c5so4277152241.1 for ; Thu, 07 May 2026 15:50:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1778194217; x=1778799017; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=9MkPXhNFKpgj51RT3nXElFSkq09L7clUycFsPNU23WU=; b=RX84c+y5180DBXRSkor5q/VBH98Zc5SnwB7x3xKVbxIEayRsx2JSYC434xN7OfTAIw 8LQfeJ4544XSoh7IjBObFTtokzYachdLfh0OWVhN9JY9GjTh/4xTO/WtchVoe7aYY7u/ WnZDkuDD/IrgMlikceSRDEBlwYfk6Ds+qWoBPvfTca6VtFlw73m1d8i3H4rfiyEaEcqD Kr7750m/nM3SNPwBvlPzhQRBeb0ipLHI9ftOcLYCkrGZihec5OpvYCTGUK7eUHPV9KyX 4L3KV/VZJOXbowAZYvi0whJeHfltGeRqj+ya4Texw35MYLJyroyeBJ6AhF7qg8ydOifF Q4Dw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778194217; x=1778799017; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=9MkPXhNFKpgj51RT3nXElFSkq09L7clUycFsPNU23WU=; b=Vxxl8FU1QboCY9t1JoJ4bquTy8CISBhHsS5SWMm7/drqLLVTAbdOJ3gkMBc/zHwA9e Bb/34Jf91jGGiSjV8wizITfJdjjB3ogN37688d2f3SqV0QCAyKmzzmpOOV8GSVpX6nyQ wotvzZ2A8+8jdHxJDDxAJ3LN+c4/k8nXTIusbjsh4vF37xyRyneixhEHu+nBjiBukxeg nAI9lz/KbLRUDlIVCMK7nVp6g24KVWGTBJlcnR4jwlHmvJQpkQKfXNN/+//hznZZ8jow mmMCExzm3vGSeEFKbEJoI0y1mZiBrSQZZ9OCboZHfyhomEVBQ/wDUVW2EITnJXgbH5C+ o+RQ== X-Forwarded-Encrypted: i=1; AFNElJ9q6V5snff8BwkmWVJ9Ahhpp4I9H65nm1nO51o4mjcsbveelhITHJGk4YkaFw/4UXr+0Aei/kOK+oM9XN0=@vger.kernel.org X-Gm-Message-State: AOJu0YxKoEt8YsK3PJhmlvH+tBRutWRvjwDs/lZbuV8tWaAZYUL8AUA1 hdwPGcwTiQ+Jc7iSQl+pFhH1tQzr58BYLsrPGnPw9GEV87/hB4iupIv2eogxBpx/yELE6OvHptA Zz1i/t24yMswRfsmhZbF42hlUsINxIHEiXncX8ZHOBbMXFlESIOn0B3WHqSJTeSmXdtU= X-Gm-Gg: AeBDiet28/nauf2+wh/jO8XX5txSCm1Tfty0BNpVPJWRzNZ2PrRF+mcAdR/B1o3KgGi LBCFmd4iT7KJupKZc5rnfn0+dlAD6m/95/xoo1V81dexq0RlVZD5hP+LN3Y4eOYXCRWIeIIh0gm TaSaRJhCsKmIamQxBkAafZffCBhBAjUKo9VDMfOUw2PSmox63bgs/6sZKx7PvaJxBIgZoE9hp0n QCcIpbAqt/iHiDhUw89Rb4yekwf2O62u8s76+aSbLVgHvp1q0H9EJYl/5hdYSK+EVakfPqo+pS9 E2ecT3Ipnip4afiIaF/Z0I/OgUbuFzvw/grx4E9D9ljAElAAVxYUPZsN94A480rk5SAEzZIrmls VYS69Ujm4ksgIJZSiJiDRfLvRXBHmENTF76GDp8oPxNIUlV/oa+X8sMkSAoRSVDOxg6Gpj4tup2 IWAUAVZDIqGu5bBHijvvvYcoabJdQ= X-Received: by 2002:a05:6102:1497:b0:62f:4854:8c53 with SMTP id ada2fe7eead31-63115f8712cmr2441537137.12.1778194217103; Thu, 07 May 2026 15:50:17 -0700 (PDT) X-Received: by 2002:a05:6102:1497:b0:62f:4854:8c53 with SMTP id ada2fe7eead31-63115f8712cmr2441524137.12.1778194216623; Thu, 07 May 2026 15:50:16 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:b16a:3475:ec42:bcfa]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bcac4359dbesm102466b.48.2026.05.07.15.50.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 May 2026 15:50:15 -0700 (PDT) From: Loic Poulain Date: Fri, 08 May 2026 00:49:19 +0200 Subject: [PATCH v3 04/15] media: qcom: camss: Add camss-isp-bufq helper Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260508-camss-isp-ope-v3-4-bb1055274603@oss.qualcomm.com> References: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> In-Reply-To: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> To: Bryan O'Donoghue , Vladimir Zapolskiy , Loic Poulain , Mauro Carvalho Chehab , Kees Cook , "Gustavo A. R. Silva" , Bryan O'Donoghue , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio Cc: linux-media@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devicetree@vger.kernel.org, laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com, johannes.goede@oss.qualcomm.com X-Mailer: b4 0.14.2 X-Authority-Analysis: v=2.4 cv=TJB1jVla c=1 sm=1 tr=0 ts=69fd1729 cx=c_pps a=R6oCqFB+Yf/t2GF8e0/dFg==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=3WHJM1ZQz_JShphwDgj5:22 a=EUspDBNiAAAA:8 a=Rj2g1MzNgR17_EpZbusA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=TD8TdBvy0hsOASGTdmB-:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTA3MDIzMSBTYWx0ZWRfX9dO3/ZkMhqp+ W4fLMTEmctTsMEw3FQzhiemnesEr+nhOdUoZMaQgUImJn2Gx7xSPpYcRL2FkAIsdbJ63LDn4NeD rSLC6e4/Np+B1V+P3js+9YxFa4yBsxJEaiIGYoLQed/RMg63JrxN6RQzH2ojGWmPF3L4DhLKdLI BNUD7eyH7YQ26exXzhMHnXpHjmS1m8ZLNnxlarOVKhy9K1XosyYxF6wbDyP8vT1SVWjndCBSIkk 49F9+VvNi/N3XfzRw+ddcrhtsTdX64nyPQHlUV1+YFaev1PErmlzQPMtF15o9P0ZnIarhCGl7hp R2LujaNqmcrJqrx8YsHA10ClKa3wmbyAwYC8SXK7JMvCOOHaBb0BCdQNeAZ3nIdr0J2c3zzXfJA etCcaTKFo/TXNRFyvYgwFDuYKUAVhQmcZce2RPstoNMoOkPvoVjN3mypZjpx+W4m3azOka37Y06 jMNj4n37hpwQb1JP1FQ== X-Proofpoint-GUID: G84g_2eeF5uofaW3bwikiDJUfSVuYU40 X-Proofpoint-ORIG-GUID: G84g_2eeF5uofaW3bwikiDJUfSVuYU40 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-05-07_02,2026-05-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 lowpriorityscore=0 malwarescore=0 impostorscore=0 bulkscore=0 phishscore=0 priorityscore=1501 adultscore=0 spamscore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2605070231 Add a per-queue ready-buffer FIFO helper for CAMSS offline ISP drivers. camss_isp_bufq provides N spinlock-protected FIFO lists of ready vb2 buffers, one per queue index. This can help multi-queues management and synchronization in ISP context. Signed-off-by: Loic Poulain --- drivers/media/platform/qcom/camss/Kconfig | 14 +++ drivers/media/platform/qcom/camss/Makefile | 5 + drivers/media/platform/qcom/camss/camss-isp-bufq.c | 101 +++++++++++++++++ drivers/media/platform/qcom/camss/camss-isp-bufq.h | 122 +++++++++++++++++= ++++ 4 files changed, 242 insertions(+) diff --git a/drivers/media/platform/qcom/camss/Kconfig b/drivers/media/plat= form/qcom/camss/Kconfig index 4eda48cb1adf049a7fb6cb59b9da3c0870fe57f4..d77482f3f5eadc65856806b9b23= 7d65ea484f267 100644 --- a/drivers/media/platform/qcom/camss/Kconfig +++ b/drivers/media/platform/qcom/camss/Kconfig @@ -7,3 +7,17 @@ config VIDEO_QCOM_CAMSS select VIDEO_V4L2_SUBDEV_API select VIDEOBUF2_DMA_SG select V4L2_FWNODE + +config VIDEO_QCOM_CAMSS_ISP + tristate "Qualcomm CAMSS ISP common helpers" + depends on VIDEO_DEV + depends on MEDIA_CONTROLLER + select V4L2_ISP + select VIDEOBUF2_CORE + help + Common helper library for Qualcomm CAMSS offline ISP drivers. + Provides buffer queue management, job scheduling, MC pipeline + topology builder, and ISP parameter buffer parsing. + + This module is selected automatically by drivers that need it. + diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/pla= tform/qcom/camss/Makefile index 5e349b4915130c71dbff90e73102e46dfede1520..bfc05db0eada1d801839ceb8a3b= 157baae613053 100644 --- a/drivers/media/platform/qcom/camss/Makefile +++ b/drivers/media/platform/qcom/camss/Makefile @@ -29,3 +29,8 @@ qcom-camss-objs +=3D \ camss-format.o \ =20 obj-$(CONFIG_VIDEO_QCOM_CAMSS) +=3D qcom-camss.o + +qcom-camss-isp-objs :=3D camss-isp-bufq.o + +obj-$(CONFIG_VIDEO_QCOM_CAMSS_ISP) +=3D qcom-camss-isp.o + diff --git a/drivers/media/platform/qcom/camss/camss-isp-bufq.c b/drivers/m= edia/platform/qcom/camss/camss-isp-bufq.c new file mode 100644 index 0000000000000000000000000000000000000000..b1dcf60afcc63d112eee7bd143f= 08a7b4aac9a18 --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-isp-bufq.c @@ -0,0 +1,101 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * camss-isp-bufq.c + * + * CAMSS ISP per-queue ready-buffer FIFO. + * + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include + +#include "camss-isp-bufq.h" + +struct camss_isp_bufq *camss_isp_bufq_init(unsigned int num_queues) +{ + struct camss_isp_bufq *bufq; + unsigned int i; + + bufq =3D kzalloc(struct_size(bufq, entries, num_queues), GFP_KERNEL); + if (!bufq) + return ERR_PTR(-ENOMEM); + + bufq->num_queues =3D num_queues; + + for (i =3D 0; i < num_queues; i++) { + INIT_LIST_HEAD(&bufq->entries[i].rdy_queue); + spin_lock_init(&bufq->entries[i].rdy_spinlock); + } + + return bufq; +} +EXPORT_SYMBOL_GPL(camss_isp_bufq_init); + +void camss_isp_bufq_release(struct camss_isp_bufq *bufq) +{ + kfree(bufq); +} +EXPORT_SYMBOL_GPL(camss_isp_bufq_release); + +void camss_isp_bufq_queue(struct camss_isp_bufq *bufq, unsigned int queue_= idx, + struct vb2_v4l2_buffer *vbuf) +{ + struct camss_isp_buf *buf =3D + container_of(vbuf, struct camss_isp_buf, vb); + struct camss_isp_bufq_entry *entry =3D &bufq->entries[queue_idx]; + unsigned long flags; + + spin_lock_irqsave(&entry->rdy_spinlock, flags); + list_add_tail(&buf->list, &entry->rdy_queue); + entry->num_rdy++; + spin_unlock_irqrestore(&entry->rdy_spinlock, flags); +} +EXPORT_SYMBOL_GPL(camss_isp_bufq_queue); + +struct vb2_v4l2_buffer *camss_isp_bufq_next(struct camss_isp_bufq *bufq, u= nsigned int queue_idx) +{ + struct camss_isp_bufq_entry *entry =3D &bufq->entries[queue_idx]; + struct camss_isp_buf *buf; + unsigned long flags; + + spin_lock_irqsave(&entry->rdy_spinlock, flags); + buf =3D list_first_entry_or_null(&entry->rdy_queue, + struct camss_isp_buf, list); + spin_unlock_irqrestore(&entry->rdy_spinlock, flags); + + return buf ? &buf->vb : NULL; +} +EXPORT_SYMBOL_GPL(camss_isp_bufq_next); + +struct vb2_v4l2_buffer *camss_isp_bufq_remove(struct camss_isp_bufq *bufq,= unsigned int queue_idx) +{ + struct camss_isp_bufq_entry *entry =3D &bufq->entries[queue_idx]; + struct camss_isp_buf *buf; + unsigned long flags; + + spin_lock_irqsave(&entry->rdy_spinlock, flags); + buf =3D list_first_entry_or_null(&entry->rdy_queue, + struct camss_isp_buf, list); + if (buf) { + list_del(&buf->list); + entry->num_rdy--; + } + spin_unlock_irqrestore(&entry->rdy_spinlock, flags); + + return buf ? &buf->vb : NULL; +} +EXPORT_SYMBOL_GPL(camss_isp_bufq_remove); + +void camss_isp_bufq_drain(struct camss_isp_bufq *bufq, unsigned int queue_= idx, + enum vb2_buffer_state state) +{ + struct vb2_v4l2_buffer *vbuf; + + while ((vbuf =3D camss_isp_bufq_remove(bufq, queue_idx))) + camss_isp_buf_done(vbuf, state); +} +EXPORT_SYMBOL_GPL(camss_isp_bufq_drain); + +MODULE_DESCRIPTION("CAMSS ISP per-queue ready-buffer FIFO"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/platform/qcom/camss/camss-isp-bufq.h b/drivers/m= edia/platform/qcom/camss/camss-isp-bufq.h new file mode 100644 index 0000000000000000000000000000000000000000..1a8bc7b112a1b039233cfc7be57= 3f1f40fcda7c9 --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-isp-bufq.h @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * camss-isp-bufq.h + * + * CAMSS ISP per-queue ready-buffer FIFO. + * + * Provides N spinlock-protected FIFO lists of ready vb2 buffers, one per + * queue index. Drivers call these helpers from their vb2 ops and job + * completion paths. + * + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef CAMSS_ISP_BUFQ_H +#define CAMSS_ISP_BUFQ_H + +#include +#include +#include +#include + +/** + * struct camss_isp_buf - vb2 buffer wrapper + * + * Use as vb2_queue.buf_struct_size so buffers can be placed on the + * ready lists managed by camss_isp_bufq. + * + * @vb: The vb2 V4L2 buffer =E2=80=94 must be first. + * @list: Entry in the per-queue ready list. + */ +struct camss_isp_buf { + struct vb2_v4l2_buffer vb; /* must be first */ + struct list_head list; +}; + +/** + * struct camss_isp_bufq_entry - per-queue ready-buffer state (opaque) + */ +struct camss_isp_bufq_entry { + struct list_head rdy_queue; + spinlock_t rdy_spinlock; + u32 num_rdy; +}; + +/** + * struct camss_isp_bufq - multi-queue ready-buffer state + * + * Allocate with camss_isp_bufq_init(), free with camss_isp_bufq_release(). + * + * @num_queues: Number of entries in @entries. + * @entries: Per-queue state; flexible array. + */ +struct camss_isp_bufq { + unsigned int num_queues; + struct camss_isp_bufq_entry entries[] __counted_by(num_queues); +}; + +/** + * camss_isp_bufq_init() - allocate a multi-queue ready-buffer state + * @num_queues: number of per-queue FIFO lists to create + * + * Returns a pointer to the new bufq or ERR_PTR on allocation failure. + */ +struct camss_isp_bufq *camss_isp_bufq_init(unsigned int num_queues); + +/** + * camss_isp_bufq_release() - free a bufq allocated with camss_isp_bufq_in= it() + * @bufq: bufq to free + */ +void camss_isp_bufq_release(struct camss_isp_bufq *bufq); + +/** + * camss_isp_bufq_queue() - append a buffer to the ready list for @queue_i= dx + * @bufq: target bufq + * @queue_idx: queue index (must be < bufq->num_queues) + * @vbuf: buffer to enqueue; must be embedded in a &struct camss_isp_= buf + */ +void camss_isp_bufq_queue(struct camss_isp_bufq *bufq, unsigned int queue_= idx, + struct vb2_v4l2_buffer *vbuf); + +/** + * camss_isp_bufq_next() - peek at the head of the ready list without remo= ving + * @bufq: target bufq + * @queue_idx: queue index + * + * Returns the head buffer or NULL if the list is empty. + */ +struct vb2_v4l2_buffer *camss_isp_bufq_next(struct camss_isp_bufq *bufq, + unsigned int queue_idx); + +/** + * camss_isp_bufq_remove() - dequeue and return the head of the ready list + * @bufq: target bufq + * @queue_idx: queue index + * + * Returns the dequeued buffer or NULL if the list is empty. + */ +struct vb2_v4l2_buffer *camss_isp_bufq_remove(struct camss_isp_bufq *bufq, + unsigned int queue_idx); + +/** + * camss_isp_bufq_drain() - return all ready buffers with the given state + * @bufq: target bufq + * @queue_idx: queue index + * @state: vb2 state to pass to vb2_buffer_done() for each buffer + */ +void camss_isp_bufq_drain(struct camss_isp_bufq *bufq, unsigned int queue_= idx, + enum vb2_buffer_state state); + +static inline u32 camss_isp_bufq_num_ready(struct camss_isp_bufq *bufq, + unsigned int queue_idx) +{ + return bufq->entries[queue_idx].num_rdy; +} + +static inline void camss_isp_buf_done(struct vb2_v4l2_buffer *vbuf, + enum vb2_buffer_state state) +{ + vb2_buffer_done(&vbuf->vb2_buf, state); +} + +#endif /* CAMSS_ISP_BUFQ_H */ --=20 2.34.1 From nobody Fri Jun 12 14:18:25 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 AD6E63D47DE for ; Thu, 7 May 2026 22:50:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194224; cv=none; b=nKU5Ksu5gJGCj8NHr3cX+kOYcEL4C8LvlVUe8zT6O0VTgrGFfjbRlvwewzlcq+re5N9x4wGrBR7W3aov+MqnOWxEaQZu5q+OyUqUOo8aAJq2w75YCFHpcZ7aYU0oPYT80gzb+qG8mXInHrPgWTyV97dLmG4arxOUJ02h0fio+uw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194224; c=relaxed/simple; bh=tpFWk8SAVs3UFv/o3uYrm+TV/zcL6UrJjTCyzPTfeK4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=OH2sJ2GIRvyMPOmedw+1C/YRimSgFDWTv0uF5Qf8lbpSRLyPmyl9U9hOZMP1/6IbDFbfP3BBk/DuCDd37rlHpjmqoT92oN25zKJFyrGO3535AAcXynaysKjGJRDJO77ObwR2iu6Q5bNv7s3C3t+wQDhrVLb5MSlxzx9qMb/p0nA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=nKPm5gka; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=WcTOHfri; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="nKPm5gka"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="WcTOHfri" Received: from pps.filterd (m0279864.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 647Hofbh1971771 for ; Thu, 7 May 2026 22:50:22 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= MSAAlTqOMhQg/xg1nez/7uASR3nN13lqXsz4IVOsiYY=; b=nKPm5gkawbLOk5Z0 ZqxmELOEv7QG8jjjc0nwUHYSDF7Ljg57YvUC917rGOJy8bZRwEk8NZ7ayR15fwJc D/Tw4qIHOuyJWpc84eg2BVvHYqThSh+3lAp0OSV+WaJW0kMdpfJwi/mXY/sztVQH 6Es2aXaZGHJJz6RNDLgTKU5D5e5gnCLWewX99HaqbfBftlBpCWqqmoVA3IvpHUgd lkzag7ynbw3hT/KErl2s8UQ7LLYFgtra+KtAD0bUAqmfEc2XDDZhO9Y7IQw1aORT CuR9ZnV/Sb6tsG7LHUcbnkWgtRXMw5l83nViwA2tybgGa32HwFAXRb2kZlUN/Vlp mEMQXg== Received: from mail-vs1-f71.google.com (mail-vs1-f71.google.com [209.85.217.71]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4e0tejacet-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 07 May 2026 22:50:22 +0000 (GMT) Received: by mail-vs1-f71.google.com with SMTP id ada2fe7eead31-62e66a6ee35so1310159137.3 for ; Thu, 07 May 2026 15:50:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1778194221; x=1778799021; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=MSAAlTqOMhQg/xg1nez/7uASR3nN13lqXsz4IVOsiYY=; b=WcTOHfribNfV/QmSwO4gRzv2V8kTTFQbYjABM4DX7DvGdPTKMBgXj52TP0WlwrZ7n2 OWXm3oqmxwnn6F2In9Jr6fQqCUO2JDiq6CpAjW9iyFGZn+OSasTBq0PZBDmL4Luxv/gt cZJ7u/TkQal2vQOXeH8yAuD9YzzpFnOwwHAG7Q4CBs0fWyTNfNiOazTBAdd9xuyxQkRH /iG4zAklvPejh+trHGL6lljeLSaeCmpDcwvF8E91KVKX70Z3QHOBoS1EBSkDX/DG9/nX qz0Ozwajw8iGem2IN4AxxZZ2GNSQqRGA8RiJvWoCV+OVwb/UVeXf7Jybs1naJjgE3Z73 1R+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778194221; x=1778799021; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=MSAAlTqOMhQg/xg1nez/7uASR3nN13lqXsz4IVOsiYY=; b=XNCxzbntfbwkZ9UAKwjCAmFPy5GkJBi28TpzQg4B6N13dXgqcQYN2K3GT4tzqdtHni y41McAR5z5UYr7n8bhoN3heOuSBicOU/KrLSQXQvTjjtpGqd35lAVuHfBJuTQbA2+QLs i6GNoIYS25cSurmWK6YG8S+fbOFOEVITdooJrDWDtntzy7YVxQWcBAgOpz90c49GYoPM 0elUOli8FlrQUCwz0APR3s19xmSbvkTF68oy8wLJWUhzQcHCXyRd1y71VVsQ5j02giGU BHhKoalisotGASOMOz45LPkhEqDiHDiXPZ1dhRoj+st5x0d23e8y0M4E8x1wAKdbCenF w/xQ== X-Forwarded-Encrypted: i=1; AFNElJ9U1TE/aAUDKEx0gTN02A1tHHfghtPs8ORm1Or1EHyfjAgTkg0GAnv2S3UHmpLIQf83LCnYO7NT0iZgKC8=@vger.kernel.org X-Gm-Message-State: AOJu0Yx3lsPw/xhRQLpkc+MRp+IouRJn908RjiNnfQUncbJdraWI5QjR 2iRsu+LjwD4YZdLgvy1VF7ygRCCtPvUjbSKhRbWRu0hIzN22PM0gRnbMJyB+/kc+pmboPB40IKg PkO0X44u91hd9fafyKNM/LWBabR6uyJ84AWsX+Zmhf8nOd7owWbc7hVWun9UGsIYxQ358EHLpCn A= X-Gm-Gg: AeBDietfCKCGZrEmga1YzZY6cwK93LFLInepwvqftLh6Ye/xuUOG+DbQG6UHZ7gCTzR MJ8QwwKiznSzqQWMzo7GvGDToxclbOIaidVxEYGSIoNUPnjuJk2bISVgIJviwFToVEhEa/cdzN6 cWu6842999kIku1HYyohL33c1phdJCl2i/p4eH7iUvBARcmicWqGTKRB+vhrxLYn6N0fvLvdys3 ixIOlPcueoochFJgVZYgMdUeI8ib+BStHVCPAqn5I/IxCNJvJvsiSIxKNfHxDaN/VRoTHkQKVhn Rjffx7ANWBn+n04XVTLt4aiiWhy5y3qCk39cQSKp6looCZkWXsdtIrrM8evqyuyQLwv6BnUKJCC ciAjc0NDVslHj4tNBUk9ejd+2jaRRYfPChG2KttB8oqQOTMYgt3YtXlV1wg19hOsypUDkAtOGyI 1H4vzQi8HzhUNs5wxE X-Received: by 2002:a05:6102:8499:10b0:631:28c1:155c with SMTP id ada2fe7eead31-63128c11e98mr1893178137.7.1778194220494; Thu, 07 May 2026 15:50:20 -0700 (PDT) X-Received: by 2002:a05:6102:8499:10b0:631:28c1:155c with SMTP id ada2fe7eead31-63128c11e98mr1893159137.7.1778194220003; Thu, 07 May 2026 15:50:20 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:b16a:3475:ec42:bcfa]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bcac4359dbesm102466b.48.2026.05.07.15.50.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 May 2026 15:50:18 -0700 (PDT) From: Loic Poulain Date: Fri, 08 May 2026 00:49:20 +0200 Subject: [PATCH v3 05/15] media: qcom: camss: Add camss-isp-sched helper Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260508-camss-isp-ope-v3-5-bb1055274603@oss.qualcomm.com> References: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> In-Reply-To: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> To: Bryan O'Donoghue , Vladimir Zapolskiy , Loic Poulain , Mauro Carvalho Chehab , Kees Cook , "Gustavo A. R. Silva" , Bryan O'Donoghue , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio Cc: linux-media@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devicetree@vger.kernel.org, laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com, johannes.goede@oss.qualcomm.com X-Mailer: b4 0.14.2 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTA3MDIzMSBTYWx0ZWRfX23iM4g6UEsNo x3vvMnplhRSWRAYK8IoOKd08OGe+tckyhIM/brfZwV4wKDpsHLPRQQt/AXf/baHiog7kohBBCi8 AbF3AfGDst94wIJoLGpgrPXVhLJPycnwFFon2Ys3CPk+qSrYRivWsQhJpgTtFPDfn09UOWCrZYg GKFWXf+KG8NxehE7Pu2hSbWFWZxXxXfQyVKJug4GIa9ZGPFsmdDxVmTaUPzeSEFNoo422YQmGIp QSHRIvLDFyXc86LeyobwjEyH0/HcskD+84mXAbTPQv7GFTaLMxrr8IiUYUMdEMw5u1UM7PL19g+ 9scpP9ruKWyltpwW+7XxEkDDWrRevSMrY3JPe7m2e0P6TI1fSK+/4sj7UlgVkXxBQAV9WyEmAAZ bAqSi9ZTfhg1h1IByRp1FCbq5wjey8qVfHU1p1+O+rH6fhB6ql+Nfl8VDyb5WrvEfTtBPs5D/i2 8nUExXlI1KpXZj8+18w== X-Proofpoint-GUID: yadm4NCJDKSSPUrXv81hpmO_DbpHa7WZ X-Authority-Analysis: v=2.4 cv=VNbtWdPX c=1 sm=1 tr=0 ts=69fd172e cx=c_pps a=P2rfLEam3zuxRRdjJWA2cw==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=DJpcGTmdVt4CTyJn9g5Z:22 a=EUspDBNiAAAA:8 a=LvVHALaGuq2LPpMeDEoA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=ODZdjJIeia2B_SHc_B0f:22 X-Proofpoint-ORIG-GUID: yadm4NCJDKSSPUrXv81hpmO_DbpHa7WZ X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-05-07_02,2026-05-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 spamscore=0 impostorscore=0 priorityscore=1501 malwarescore=0 bulkscore=0 lowpriorityscore=0 phishscore=0 suspectscore=0 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2605070231 Add a job scheduler for CAMSS offline ISP drivers which serialises job execution, tracks which context is currently running on hardware, and provides cancel/suspend/resume operations. Jobs carry optional ready/run/abort callbacks via camss_isp_job_ops, allowing the scheduler to gate submission on hardware and buffer availability. Signed-off-by: Loic Poulain --- drivers/media/platform/qcom/camss/Makefile | 3 +- .../media/platform/qcom/camss/camss-isp-sched.c | 223 +++++++++++++++++= ++++ .../media/platform/qcom/camss/camss-isp-sched.h | 174 ++++++++++++++++ 3 files changed, 399 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/pla= tform/qcom/camss/Makefile index bfc05db0eada1d801839ceb8a3b157baae613053..f13c9f326cf81962bd165dc8dd2= bb60207cd54a7 100644 --- a/drivers/media/platform/qcom/camss/Makefile +++ b/drivers/media/platform/qcom/camss/Makefile @@ -30,7 +30,8 @@ qcom-camss-objs +=3D \ =20 obj-$(CONFIG_VIDEO_QCOM_CAMSS) +=3D qcom-camss.o =20 -qcom-camss-isp-objs :=3D camss-isp-bufq.o +qcom-camss-isp-objs :=3D camss-isp-bufq.o \ + camss-isp-sched.o =20 obj-$(CONFIG_VIDEO_QCOM_CAMSS_ISP) +=3D qcom-camss-isp.o =20 diff --git a/drivers/media/platform/qcom/camss/camss-isp-sched.c b/drivers/= media/platform/qcom/camss/camss-isp-sched.c new file mode 100644 index 0000000000000000000000000000000000000000..6940087f94d00570a82666e882f= fc8b38891736b --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-isp-sched.c @@ -0,0 +1,223 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * CAMSS ISP scheduler helper =E2=80=94 ISP job scheduling + * + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include + +#include "camss-isp-sched.h" + +/* Job state flags */ +#define ISP_JOB_QUEUED BIT(0) +#define ISP_JOB_RUNNING BIT(1) +#define ISP_JOB_ABORT BIT(2) + +/* Scheduler flags */ +#define ISP_SCHED_PAUSED BIT(0) + +/* -------- Internal helpers -------- */ + +static void isp_sched_try_run(struct camss_isp_sched *sched) +{ + void (*run_fn)(void *priv, bool ctx_changed); + struct camss_isp_job *job; + unsigned long flags; + bool ctx_changed; + void *priv; + + spin_lock_irqsave(&sched->lock, flags); + + if (sched->curr_job || list_empty(&sched->pending) || + (sched->flags & ISP_SCHED_PAUSED)) { + spin_unlock_irqrestore(&sched->lock, flags); + return; + } + + job =3D list_first_entry(&sched->pending, struct camss_isp_job, queue); + job->flags |=3D ISP_JOB_RUNNING; + sched->curr_job =3D job; + run_fn =3D job->ops ? job->ops->run : NULL; + priv =3D job->priv; + ctx_changed =3D (sched->prev_job !=3D job); + + spin_unlock_irqrestore(&sched->lock, flags); + + run_fn(priv, ctx_changed); + sched->prev_job =3D job; +} + +static void isp_sched_work(struct work_struct *work) +{ + struct camss_isp_sched *sched =3D + container_of(work, struct camss_isp_sched, work); + + isp_sched_try_run(sched); +} + +/* -------- Public API -------- */ + +void camss_isp_sched_init(struct camss_isp_sched *sched) +{ + sched->curr_job =3D NULL; + sched->prev_job =3D NULL; + INIT_LIST_HEAD(&sched->pending); + spin_lock_init(&sched->lock); + INIT_WORK(&sched->work, isp_sched_work); + sched->flags =3D 0; +} +EXPORT_SYMBOL_GPL(camss_isp_sched_init); + +void camss_isp_sched_destroy(struct camss_isp_sched *sched) +{ + cancel_work_sync(&sched->work); +} +EXPORT_SYMBOL_GPL(camss_isp_sched_destroy); + +void camss_isp_job_init(struct camss_isp_job *job, + const struct camss_isp_job_ops *ops, + void *priv) +{ + INIT_LIST_HEAD(&job->queue); + job->flags =3D 0; + job->ops =3D ops; + job->priv =3D priv; + init_waitqueue_head(&job->finished); +} +EXPORT_SYMBOL_GPL(camss_isp_job_init); + +void camss_isp_sched_try_run(struct camss_isp_sched *sched, + struct camss_isp_job *job) +{ + unsigned long flags; + + if (job->ops && job->ops->ready && !job->ops->ready(job->priv)) + return; + + spin_lock_irqsave(&sched->lock, flags); + + if (job->flags & (ISP_JOB_ABORT | ISP_JOB_QUEUED | ISP_JOB_RUNNING)) { + spin_unlock_irqrestore(&sched->lock, flags); + return; + } + + list_add_tail(&job->queue, &sched->pending); + job->flags |=3D ISP_JOB_QUEUED; + + spin_unlock_irqrestore(&sched->lock, flags); + + isp_sched_try_run(sched); +} +EXPORT_SYMBOL_GPL(camss_isp_sched_try_run); + +void camss_isp_sched_job_finish(struct camss_isp_sched *sched, + struct camss_isp_job *job, + bool requeue) +{ + unsigned long flags; + + spin_lock_irqsave(&sched->lock, flags); + + if (sched->curr_job !=3D job) { + /* + * curr_job may have been cleared by a racing cancel/streamoff. + * If this job is still marked RUNNING, clear it and wake any + * waiter in camss_isp_sched_cancel() so it can unblock. + */ + if (job->flags & ISP_JOB_RUNNING) { + job->flags &=3D ~(ISP_JOB_QUEUED | ISP_JOB_RUNNING); + wake_up(&job->finished); + } + spin_unlock_irqrestore(&sched->lock, flags); + return; + } + + list_del(&job->queue); + job->flags &=3D ~(ISP_JOB_QUEUED | ISP_JOB_RUNNING); + wake_up(&job->finished); + sched->curr_job =3D NULL; + + if (requeue && !(job->flags & ISP_JOB_ABORT)) { + job->flags |=3D ISP_JOB_QUEUED; + list_add(&job->queue, &sched->pending); + } + + spin_unlock_irqrestore(&sched->lock, flags); + + schedule_work(&sched->work); +} +EXPORT_SYMBOL_GPL(camss_isp_sched_job_finish); + +void camss_isp_sched_cancel(struct camss_isp_sched *sched, + struct camss_isp_job *job) +{ + unsigned long flags; + + spin_lock_irqsave(&sched->lock, flags); + job->flags |=3D ISP_JOB_ABORT; + + if (job->flags & ISP_JOB_RUNNING) { + spin_unlock_irqrestore(&sched->lock, flags); + if (job->ops && job->ops->abort) + job->ops->abort(job->priv); + wait_event(job->finished, !(job->flags & ISP_JOB_RUNNING)); + } else if (job->flags & ISP_JOB_QUEUED) { + list_del(&job->queue); + job->flags &=3D ~(ISP_JOB_QUEUED | ISP_JOB_RUNNING); + spin_unlock_irqrestore(&sched->lock, flags); + } else { + spin_unlock_irqrestore(&sched->lock, flags); + } + + /* Clear abort flag so the job can be reused after cancel */ + spin_lock_irqsave(&sched->lock, flags); + job->flags &=3D ~ISP_JOB_ABORT; + spin_unlock_irqrestore(&sched->lock, flags); +} +EXPORT_SYMBOL_GPL(camss_isp_sched_cancel); + +void camss_isp_sched_suspend(struct camss_isp_sched *sched) +{ + struct camss_isp_job *curr; + unsigned long flags; + + spin_lock_irqsave(&sched->lock, flags); + sched->flags |=3D ISP_SCHED_PAUSED; + curr =3D sched->curr_job; + spin_unlock_irqrestore(&sched->lock, flags); + + if (curr) + wait_event(curr->finished, !(curr->flags & ISP_JOB_RUNNING)); +} +EXPORT_SYMBOL_GPL(camss_isp_sched_suspend); + +void camss_isp_sched_resume(struct camss_isp_sched *sched) +{ + unsigned long flags; + + spin_lock_irqsave(&sched->lock, flags); + sched->flags &=3D ~ISP_SCHED_PAUSED; + spin_unlock_irqrestore(&sched->lock, flags); + + isp_sched_try_run(sched); +} +EXPORT_SYMBOL_GPL(camss_isp_sched_resume); + +bool camss_isp_sched_is_running(struct camss_isp_sched *sched, + struct camss_isp_job *job) +{ + unsigned long flags; + bool running; + + spin_lock_irqsave(&sched->lock, flags); + running =3D (sched->curr_job =3D=3D job); + spin_unlock_irqrestore(&sched->lock, flags); + + return running; +} +EXPORT_SYMBOL_GPL(camss_isp_sched_is_running); + +MODULE_DESCRIPTION("CAMSS ISP job scheduler"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/platform/qcom/camss/camss-isp-sched.h b/drivers/= media/platform/qcom/camss/camss-isp-sched.h new file mode 100644 index 0000000000000000000000000000000000000000..5b6034976de65be57581ccaa92d= 1f15d7cb4a688 --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-isp-sched.h @@ -0,0 +1,174 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * CAMSS ISP scheduler helper =E2=80=94 ISP job scheduling + * + * Tracks which context is currently running on the hardware and + * serialises job execution. This is a pure helper: it has no knowledge + * of buffers, vb2 queues, or the uAPI. Drivers call these functions + * explicitly from their own code paths. + * + * Usage pattern: + * - Embed struct camss_isp_sched in the driver's device struct. + * - Call camss_isp_sched_init() at probe time. + * - Call camss_isp_job_init() with ready_fn/run_fn/abort_fn/priv. + * - Call camss_isp_sched_try_run() from buf_queue / streamon to start j= obs. + * - Call camss_isp_sched_job_finish() from the IRQ handler when done. + * - Call camss_isp_sched_cancel() from streamoff / release. + * + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _CAMSS_ISP_SCHED_H +#define _CAMSS_ISP_SCHED_H + +#include +#include +#include +#include + +/** + * struct camss_isp_job_ops - per-job operation callbacks + * + * @ready: Optional; return %true if the job can be submitted to hardware. + * Called outside the scheduler spinlock. May be NULL (always re= ady). + * @run: Start the hardware for this job. Called from workqueue contex= t. + * @ctx_changed is %true when this job differs from the previously + * run job (i.e. first run ever, or a different context took over= ). + * @abort: Optional; abort a running job (e.g. trigger a HW reset). + * Called from process context during camss_isp_sched_cancel(). + * May be NULL. + */ +struct camss_isp_job_ops { + bool (*ready)(void *priv); + void (*run)(void *priv, bool ctx_changed); + void (*abort)(void *priv); +}; + +/** + * struct camss_isp_job - per-context scheduler state + * + * Embed one of these in the driver's per-context struct. + * Initialise with camss_isp_job_init(). + * + * @queue: Entry in the scheduler's pending-job list. + * @flags: Internal state flags (ISP_JOB_*). + * @finished: Wait queue signalled when the running job completes. + * @ops: Job operation callbacks (ready/run/abort). + * @priv: Opaque pointer passed to all callbacks. + */ +struct camss_isp_job { + struct list_head queue; + unsigned long flags; + wait_queue_head_t finished; + const struct camss_isp_job_ops *ops; + void *priv; +}; + +/** + * struct camss_isp_sched - ISP job scheduler + * + * Embed one of these in the driver's device struct. + * Initialise with camss_isp_sched_init(). + * + * @curr_job: Job currently running on hardware (NULL if idle). + * @prev_job: Job that ran most recently (never dereferenced, pointer o= nly). + * @pending: List of jobs waiting to run. + * @lock: Protects @curr_job, @pending, and @flags. + * @work: Work item used to run jobs from non-atomic context. + * @flags: Scheduler-level flags (ISP_SCHED_PAUSED). + */ +struct camss_isp_sched { + struct camss_isp_job *curr_job; + struct camss_isp_job *prev_job; + struct list_head pending; + spinlock_t lock; + struct work_struct work; + unsigned long flags; +}; + +/** + * camss_isp_sched_init() - initialise a scheduler + * @sched: scheduler to initialise + */ +void camss_isp_sched_init(struct camss_isp_sched *sched); + +/** + * camss_isp_sched_destroy() - destroy a scheduler (waits for any running = job) + * @sched: scheduler to destroy + */ +void camss_isp_sched_destroy(struct camss_isp_sched *sched); + +/** + * camss_isp_job_init() - initialise per-context job state + * @job: job to initialise + * @ops: operation callbacks (run is required; ready and abort may be NUL= L) + * @priv: opaque pointer passed to all callbacks + */ +void camss_isp_job_init(struct camss_isp_job *job, + const struct camss_isp_job_ops *ops, + void *priv); + +/** + * camss_isp_sched_try_run() - enqueue a job and try to start it + * @sched: scheduler + * @job: job to enqueue; callbacks and @priv are taken from the job. + * + * Calls @job->ready_fn (if set); returns immediately if it returns %false. + * Otherwise enqueues the job and starts it if the hardware is idle. + * Safe to call from atomic context. + */ +void camss_isp_sched_try_run(struct camss_isp_sched *sched, + struct camss_isp_job *job); + +/** + * camss_isp_sched_job_finish() - signal that the current job has completed + * @sched: scheduler + * @job: job that just finished (must be the currently running job) + * @requeue: if %true and the job's ready_fn passes, immediately re-enqueue + * the job so the next frame starts as soon as the workqueue run= s. + * + * Clears the running state, wakes any waiter in camss_isp_sched_cancel(), + * and schedules the next pending job via the work queue. + * Safe to call from atomic/IRQ context. + */ +void camss_isp_sched_job_finish(struct camss_isp_sched *sched, + struct camss_isp_job *job, + bool requeue); + +/** + * camss_isp_sched_cancel() - cancel a pending or running job and wait + * @sched: scheduler + * @job: job to cancel; @job->abort_fn is called if the job is running. + * + * If the job is queued but not yet running, it is simply removed. + * If the job is running, @job->abort_fn is called (if set) and the + * function blocks until camss_isp_sched_job_finish() is called. + * Must be called from process context (may sleep). + */ +void camss_isp_sched_cancel(struct camss_isp_sched *sched, + struct camss_isp_job *job); + +/** + * camss_isp_sched_suspend() - pause the scheduler and wait for current job + * @sched: scheduler + * + * No new jobs will be started until camss_isp_sched_resume() is called. + * Blocks until any currently running job finishes. + */ +void camss_isp_sched_suspend(struct camss_isp_sched *sched); + +/** + * camss_isp_sched_resume() - resume the scheduler + * @sched: scheduler + */ +void camss_isp_sched_resume(struct camss_isp_sched *sched); + +/** + * camss_isp_sched_is_running() - check if a job is currently running + * @sched: scheduler + * @job: job to check + */ +bool camss_isp_sched_is_running(struct camss_isp_sched *sched, + struct camss_isp_job *job); + +#endif /* _CAMSS_ISP_SCHED_H */ --=20 2.34.1 From nobody Fri Jun 12 14:18:25 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 1388B3D34B2 for ; Thu, 7 May 2026 22:50:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194227; cv=none; b=WESsEn76diXoxvoliWH9HW4yp5+vrNcEcccStrELznnDUoFsV+TpFcAKIWlTWxGiTtA04ubtaZtR7YCnSJdh9xzqANQehz+7Tl9cEWRNiFKl4fTgEDlnuquJv8NjAw7nVP6GfXpJKi6WfLYPewnJVt5g2uluFzE1zsTnjH8PbRE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194227; c=relaxed/simple; bh=BEE5xtYLMIHM5H/+X+OLu6ImhtuWkEKhW4lS9LNnceo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=h00ric9aAN6S2+uXCAjqSSqEgU1p2JgqUw1RY5Tx49H9qIxAilCeVYsLl9ljNTevUIL2PimQpSPvddPmCEoSrnoikHNAoQwFdNep6Ppt4nI2hd2NbBv2mlmZwae0nS9ECyjZKqxYET1MpZT6y5F7GMZ9nWVtObhWKoUddFQLQrs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=a66+iYEc; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=OZgddfL5; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="a66+iYEc"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="OZgddfL5" Received: from pps.filterd (m0279869.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 647LsPdr1174043 for ; Thu, 7 May 2026 22:50:24 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= hJybU2elZh0mwCIYOkkkEG3pKmTbc3qa3OZ8DwGiHk4=; b=a66+iYEcSaiNMUCx 6Wke6HFpcgqlrVazEMty9Dfmz+yQ13FDpAbDaNvHB2iqOwhEhKWmBA6mTSzsS5mj TVMvo0JgEtaycOTvc86KcgzZCaE9gKh0RrK1NLKzBOIkQ1/a48rl3cffFWScbo9e ItOwD0H3u+hHapsuPNzPBE68svW2LgxQiI+K5oEKRn5h30XlohXVafFwhcohXzfZ vUD55UTcqXvDEuDldgegUEyDL3dpsuaAW0CygHOrKltC1bp/LsqWFrNq+Y61rotm hXdvhlQ4XW70LJ6DbFJ8qBTj9173gz+M+YgGkuC+4+uxSr7PZHkSKIPqzjS7PZPF jlNItQ== Received: from mail-ua1-f70.google.com (mail-ua1-f70.google.com [209.85.222.70]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4e132h84ar-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 07 May 2026 22:50:24 +0000 (GMT) Received: by mail-ua1-f70.google.com with SMTP id a1e0cc1a2514c-95ce6d50ea7so1013400241.1 for ; Thu, 07 May 2026 15:50:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1778194223; x=1778799023; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=hJybU2elZh0mwCIYOkkkEG3pKmTbc3qa3OZ8DwGiHk4=; b=OZgddfL50ztMgPQv7kJMVLYb08KX0Xj+xL/iArZ9hCBD92RijvbljdBB5W0Ujy5gAM wgcfwJ7UaFfChXKxMNiGaK9GwJzt+sspJmPeDljGvnAryCckowZj6KAPbqLyHzUY0yrE LsM5mmW1jb1VhSoFbncQ7HyiFIFHk0KopRlmnDHXPOLecrFW128lCfe0eUV1UKv/FDwn Qpy7M6rpsDWh/YpHO58dMJf+X8fJ2IHX8s7A0P4XModqqnBtyQG4tsBGFCpv77uxOheJ 3Oywycq5S6z2wiRwygWXgAX7vNjtxEHzhJonEEj5FkfWmqQxornyTo/Qfse/sOg+rEsO Qtmw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778194223; x=1778799023; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=hJybU2elZh0mwCIYOkkkEG3pKmTbc3qa3OZ8DwGiHk4=; b=Va1qLgW19adjvr2oUbvbFME+HFm6L1+VYrkTP10nD+AI8Qa5OAu7orLjQD3dA6GlEM +RfaMnHxEc1TULy8d2Sk1AxwsgyM5ubBHOrvpviFVISMj2xaR7ARp92RSLowIC/t0B4U Jb7daYBl3Hml2dp/P2Umnf5YKWXUrMVdlOB5buUfpgQdUry2Yuf/8uMuiXHvoLf3DLH8 rTkmjDpJhrSvSwdUEtGHNves6H1h7x6NSW1mW/SiB2J9nz1U8S7hOZa18t+4rt1uZ9Dj EWCbF6r99HgRi7mTShsjep/iBFKyRpNTQIrP2F7gMlFVNa3lZbnJgPDHZqSpWl8Y/dCL zzHQ== X-Forwarded-Encrypted: i=1; AFNElJ+tAVSGDiAOppMwWyUda6wz5MLdLtSllGR0mCMpfDgXt2VsLEsaCevKjgDlesLpLxKc4lz5DX3pH8Wk8Jo=@vger.kernel.org X-Gm-Message-State: AOJu0YxqWTIRJrPTnqOoP6Gi0D7DajXiPx/WAwsCqBhl/8MDV3RL3LYe eWwxVPT2JTcTqXBEp+cFfmiFyWNEbeSHLC3qj3z8EP3YXYt8eg2tQ3KGmENHyRaGHczhVtHP9qv xufSDStfE2MAZyFp18zx5WhLRVEJx0RWuwEnyYsWcXF8IYe+fJ+zKUKm/10jLRQF20vc= X-Gm-Gg: AeBDieuKZG9Wl2WaxmU6I/1+9y/5uSTeoAPTubP7fjaYU8GjuZA8tIR+VHCJE3VjSLB Mx935fAGguy0xQ1HhekycYtjSzwKS1VzGPcWejcD4JdBiAHXcas8Iu6ubem+28h6/+KCQ/72oVn xLIg/DF+Vvc+rL7n8IU1gPp0+sMAbE8Gvthmi/UtaoELWZl2szGWulIhb12YrnwNhXIXI23Ovem A6NyL9opmIYtxLRuudCeIUc59TFDcpHIM8eDUKVR2WQQIoJfg44a7fhDCXK2l77cjCXpPRGsYcq OXAXhW2DPbwm0MIyvsJH01LEfj50POiW44BRFacxFmfHurkINWWC7Afk2z89GTb+JVgFNzm+k58 88B37xT/g0wlKQQMaSSvQRX8e3Fvjz5jae3E6Ss8WDhp/6DboInOb5eERuZY50HeHty5AD0Dany 09p7wdr/N04ED28c+A X-Received: by 2002:a05:6102:54ab:b0:62f:3cb7:8652 with SMTP id ada2fe7eead31-6313e9f142dmr64753137.13.1778194223115; Thu, 07 May 2026 15:50:23 -0700 (PDT) X-Received: by 2002:a05:6102:54ab:b0:62f:3cb7:8652 with SMTP id ada2fe7eead31-6313e9f142dmr64726137.13.1778194222561; Thu, 07 May 2026 15:50:22 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:b16a:3475:ec42:bcfa]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bcac4359dbesm102466b.48.2026.05.07.15.50.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 May 2026 15:50:21 -0700 (PDT) From: Loic Poulain Date: Fri, 08 May 2026 00:49:21 +0200 Subject: [PATCH v3 06/15] media: qcom: camss: Add camss-isp-pipeline helper Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260508-camss-isp-ope-v3-6-bb1055274603@oss.qualcomm.com> References: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> In-Reply-To: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> To: Bryan O'Donoghue , Vladimir Zapolskiy , Loic Poulain , Mauro Carvalho Chehab , Kees Cook , "Gustavo A. R. Silva" , Bryan O'Donoghue , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio Cc: linux-media@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devicetree@vger.kernel.org, laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com, johannes.goede@oss.qualcomm.com X-Mailer: b4 0.14.2 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTA3MDIzMSBTYWx0ZWRfX+WkwPWT+UrkQ iijfxEo6Jw4LgXt6kJIVREr34YG5YkLy8yme4+wi/4bDociTYxlOGMbxVT4JV0JEa+v4Opo2T/L 0Pnjw5AaeIKol5qSiUvs1WI5ukw7pfXt/oxeDIhroxzAa2JzQbKKMPyTKKSNYMYViN0O5whOROc PCXqxp7Ql2ETQv/v52Ma78yTblAsv5YtIjzQNfRbYEO+R35SrC5xaev8pdYToAXNWI28SrPVIaX 7369tHdzZODOphL9q7Jjea0eZsiFcTjikoblpdnRo4K0e+B0BN468VaVHD/U1oDXMdWl/AFAAV5 Q9codWlGukZsOTzrmSuvlFBvj//7Hu3tArvwu4ERs864/z+Fpj8Xa5QZmiRMrOmaQPC3V+bJ4Uq eVMFImWnBXyu9GTFROfI6OYYHJroIQNVIXV2yoxmjMducqAYFIU3ODP6gRkoDtFiljQ4qdcWuEO 668NXm5s3wEbizPuaBw== X-Proofpoint-ORIG-GUID: p3Ej3btiaLxLN3iP2fIOMVCcKfnU8RTk X-Proofpoint-GUID: p3Ej3btiaLxLN3iP2fIOMVCcKfnU8RTk X-Authority-Analysis: v=2.4 cv=McxcfZ/f c=1 sm=1 tr=0 ts=69fd1730 cx=c_pps a=R6oCqFB+Yf/t2GF8e0/dFg==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=_glEPmIy2e8OvE2BGh3C:22 a=EUspDBNiAAAA:8 a=0HvUUkHzQstEScuQiJkA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=TD8TdBvy0hsOASGTdmB-:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-05-07_02,2026-05-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 malwarescore=0 suspectscore=0 spamscore=0 bulkscore=0 adultscore=0 priorityscore=1501 lowpriorityscore=0 impostorscore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2605070231 Add a declarative MC topology builder for CAMSS offline ISP drivers. Drivers describe their entire media graph, entities (video devices, subdevs, or base entities), their pads, and the links between them in a static descriptor table. The builder validates the table, allocates and registers all entities, and creates all MC pad links. Signed-off-by: Loic Poulain --- drivers/media/platform/qcom/camss/Makefile | 3 +- .../media/platform/qcom/camss/camss-isp-pipeline.c | 361 +++++++++++++++++= ++++ .../media/platform/qcom/camss/camss-isp-pipeline.h | 228 +++++++++++++ 3 files changed, 591 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/pla= tform/qcom/camss/Makefile index f13c9f326cf81962bd165dc8dd2bb60207cd54a7..f3acb1b54b6c1455d72e2d947c8= 60f0c337648de 100644 --- a/drivers/media/platform/qcom/camss/Makefile +++ b/drivers/media/platform/qcom/camss/Makefile @@ -31,7 +31,8 @@ qcom-camss-objs +=3D \ obj-$(CONFIG_VIDEO_QCOM_CAMSS) +=3D qcom-camss.o =20 qcom-camss-isp-objs :=3D camss-isp-bufq.o \ - camss-isp-sched.o + camss-isp-sched.o \ + camss-isp-pipeline.o =20 obj-$(CONFIG_VIDEO_QCOM_CAMSS_ISP) +=3D qcom-camss-isp.o =20 diff --git a/drivers/media/platform/qcom/camss/camss-isp-pipeline.c b/drive= rs/media/platform/qcom/camss/camss-isp-pipeline.c new file mode 100644 index 0000000000000000000000000000000000000000..8e44bedb0a41e3cf4fc7e3a138c= 1f48854f5efc8 --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-isp-pipeline.c @@ -0,0 +1,361 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * CAMSS ISP pipeline helper =E2=80=94 declarative MC topology builder + * + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include + +#include +#include +#include +#include +#include +#include "camss-isp-pipeline.h" + +#if !IS_ENABLED(CONFIG_MEDIA_CONTROLLER) +static inline int media_entity_pads_init(struct media_entity *e, u16 n, + struct media_pad *p) { return 0; } +static inline void media_entity_remove_links(struct media_entity *e) {} +static inline int media_create_pad_link(struct media_entity *src, u16 sp, + struct media_entity *sink, u16 dp, + u32 flags) { return 0; } +#endif + +/* -------- Internal elpers -------- */ + +static enum vfl_devnode_direction isp_caps_to_vfl_dir(u32 caps) +{ + if (caps & (V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE)) + return VFL_DIR_M2M; + if (caps & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE | + V4L2_CAP_META_OUTPUT | V4L2_CAP_VBI_OUTPUT | V4L2_CAP_SDR_OUTPUT)) + return VFL_DIR_TX; + return VFL_DIR_RX; +} + +static unsigned int isp_count_pads(const struct camss_isp_pad_desc *pads) +{ + unsigned int n =3D 0; + + if (!pads) + return 0; + while (pads[n].flags) + n++; + return n; +} + +static struct media_entity *isp_pipeline_media_entity(struct camss_isp_pip= eline *pipeline, + unsigned int idx) +{ + struct camss_isp_pipeline_entity *slot =3D &pipeline->entities[idx]; + + switch (slot->obj_type) { + case MEDIA_ENTITY_TYPE_VIDEO_DEVICE: + return &slot->vdev.entity; + case MEDIA_ENTITY_TYPE_V4L2_SUBDEV: + return &slot->subdev.entity; + default: + return &slot->entity; + } +} + +/* -------- Validation -------- */ + +static int isp_pipeline_validate(struct device *dev, + const struct camss_isp_entity_desc *descs, + unsigned int num_entities) +{ + unsigned int i, pi; + + for (i =3D 0; i < num_entities; i++) { + const struct camss_isp_pad_desc *pads =3D descs[i].pads; + unsigned int num_pads =3D isp_count_pads(pads); + + for (pi =3D 0; pi < num_pads; pi++) { + const struct camss_isp_pad_desc *pad =3D &pads[pi]; + const struct camss_isp_pad_desc *peer_pad; + unsigned int peer_num_pads; + int peer_ent =3D pad->peer_entity; + + if (peer_ent < 0) + continue; + + if ((unsigned int)peer_ent >=3D num_entities) { + dev_err(dev, "entity[%u].p%u: peer_entity %d out of range\n", + i, pi, peer_ent); + return -EINVAL; + } + + peer_num_pads =3D isp_count_pads(descs[peer_ent].pads); + if (pad->peer_pad >=3D peer_num_pads) { + dev_err(dev, "entity[%u].p%u: peer_pad %u out of range\n", + i, pi, pad->peer_pad); + return -EINVAL; + } + + peer_pad =3D &descs[peer_ent].pads[pad->peer_pad]; + + /* Links are SOURCE->SINK; reject SOURCE->SOURCE or SINK->SINK */ + if (((pad->flags & MEDIA_PAD_FL_SOURCE) && + (peer_pad->flags & MEDIA_PAD_FL_SOURCE)) || + ((pad->flags & MEDIA_PAD_FL_SINK) && + (peer_pad->flags & MEDIA_PAD_FL_SINK))) { + dev_err(dev, "entity[%u].p%u -> entity[%d].p%u: invalid\n", + i, pi, peer_ent, pad->peer_pad); + return -EINVAL; + } + + /* Verify back-reference consistency */ + if (peer_pad->peer_entity >=3D 0 && + ((unsigned int)peer_pad->peer_entity !=3D i || + peer_pad->peer_pad !=3D pi)) { + dev_err(dev, "entity[%u].p%u <-> entity[%d].p%u: mismatch\n", + i, pi, peer_ent, pad->peer_pad); + return -EINVAL; + } + } + } + + return 0; +} + +/* -------- Allocation / Release -------- */ + +struct camss_isp_pipeline *camss_isp_pipeline_alloc(unsigned int num_entit= ies) +{ + struct camss_isp_pipeline *pipeline; + + pipeline =3D kzalloc(struct_size(pipeline, entities, num_entities), + GFP_KERNEL); + if (!pipeline) + return ERR_PTR(-ENOMEM); + + pipeline->num_entities =3D num_entities; + return pipeline; +} +EXPORT_SYMBOL_GPL(camss_isp_pipeline_alloc); + +void camss_isp_pipeline_free(struct camss_isp_pipeline *pipeline) +{ + kfree(pipeline); +} +EXPORT_SYMBOL_GPL(camss_isp_pipeline_free); + +/* -------- Registration -------- */ + +void camss_isp_pipeline_unregister(struct camss_isp_pipeline *pipeline) +{ + int i; + + /* Unregister entities in reverse order */ + for (i =3D (int)pipeline->num_entities - 1; i >=3D 0; i--) { + struct camss_isp_pipeline_entity *slot =3D &pipeline->entities[i]; + + switch (slot->obj_type) { + case MEDIA_ENTITY_TYPE_VIDEO_DEVICE: + if (slot->vdev.name[0]) + video_unregister_device(&slot->vdev); + break; + case MEDIA_ENTITY_TYPE_V4L2_SUBDEV: + if (slot->subdev.name[0]) + v4l2_device_unregister_subdev(&slot->subdev); + break; + case MEDIA_ENTITY_TYPE_BASE: + if (slot->entity.name) { + media_entity_remove_links(&slot->entity); + media_device_unregister_entity(&slot->entity); + } + break; + } + + kfree(slot->pads); + slot->pads =3D NULL; + } + + pipeline->v4l2_dev =3D NULL; +} +EXPORT_SYMBOL_GPL(camss_isp_pipeline_unregister); + +static int isp_register_vdev(struct camss_isp_pipeline_entity *slot, + const struct camss_isp_entity_desc *desc, + struct v4l2_device *v4l2_dev) +{ + struct video_device *vdev =3D &slot->vdev; + int ret; + + strscpy(vdev->name, desc->name, sizeof(vdev->name)); + vdev->vfl_dir =3D isp_caps_to_vfl_dir(desc->vdev.caps); + vdev->v4l2_dev =3D v4l2_dev; + vdev->device_caps =3D desc->vdev.caps; + vdev->release =3D video_device_release_empty; + if (desc->vdev.fops) + vdev->fops =3D desc->vdev.fops; + if (desc->vdev.ioctl_ops) + vdev->ioctl_ops =3D desc->vdev.ioctl_ops; + + vdev->entity.obj_type =3D MEDIA_ENTITY_TYPE_VIDEO_DEVICE; + vdev->entity.function =3D desc->function ? desc->function : MEDIA_ENT_F_I= O_V4L; + + ret =3D media_entity_pads_init(&vdev->entity, slot->num_pads, slot->pads); + if (ret) + return ret; + + ret =3D video_register_device(vdev, VFL_TYPE_VIDEO, -1); + if (ret) + return ret; + + video_set_drvdata(vdev, desc->vdev.drvdata); + + return 0; +} + +static int isp_register_subdev(struct camss_isp_pipeline_entity *slot, + const struct camss_isp_entity_desc *desc, + struct v4l2_device *v4l2_dev) +{ + struct v4l2_subdev *sd =3D &slot->subdev; + int ret; + + v4l2_subdev_init(sd, desc->subdev.ops); + strscpy(sd->name, desc->name, sizeof(sd->name)); + sd->entity.function =3D desc->function ? + desc->function : MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN; + + ret =3D media_entity_pads_init(&sd->entity, slot->num_pads, slot->pads); + if (ret) + return ret; + + return v4l2_device_register_subdev(v4l2_dev, sd); +} + +static int isp_register_base_entity(struct camss_isp_pipeline_entity *slot, + const struct camss_isp_entity_desc *desc, + struct v4l2_device *v4l2_dev) +{ + struct media_entity *entity =3D &slot->entity; + int ret; + + entity->obj_type =3D MEDIA_ENTITY_TYPE_BASE; + entity->name =3D desc->name; + entity->function =3D desc->function; + + ret =3D media_entity_pads_init(entity, slot->num_pads, slot->pads); + if (ret) + return ret; + + return media_device_register_entity(v4l2_dev->mdev, entity); +} + +static int isp_alloc_pads(struct camss_isp_pipeline_entity *slot, + const struct camss_isp_entity_desc *desc) +{ + unsigned int num_pads =3D isp_count_pads(desc->pads); + unsigned int i; + + if (!num_pads) + goto done; + + slot->pads =3D kcalloc(num_pads, sizeof(*slot->pads), GFP_KERNEL); + if (!slot->pads) + return -ENOMEM; + + for (i =3D 0; i < num_pads; i++) + slot->pads[i].flags =3D desc->pads[i].flags; +done: + slot->num_pads =3D num_pads; + return 0; +} + +int camss_isp_pipeline_register(struct camss_isp_pipeline *pipeline, + struct v4l2_device *v4l2_dev, + const struct camss_isp_entity_desc *descs, + unsigned int num_entities) +{ + unsigned int i, pi; + int ret; + + if (WARN_ON(num_entities !=3D pipeline->num_entities)) + return -EINVAL; + + if (WARN_ON(!v4l2_dev || !v4l2_dev->mdev)) + return -EINVAL; + + ret =3D isp_pipeline_validate(v4l2_dev->dev, descs, num_entities); + if (ret) + return ret; + + pipeline->v4l2_dev =3D v4l2_dev; + + /* Register each entity */ + for (i =3D 0; i < num_entities; i++) { + const struct camss_isp_entity_desc *desc =3D &descs[i]; + struct camss_isp_pipeline_entity *slot =3D &pipeline->entities[i]; + + slot->obj_type =3D desc->obj_type; + + ret =3D isp_alloc_pads(slot, desc); + if (ret) + goto err_unregister; + + switch (desc->obj_type) { + case MEDIA_ENTITY_TYPE_VIDEO_DEVICE: + ret =3D isp_register_vdev(slot, desc, v4l2_dev); + break; + case MEDIA_ENTITY_TYPE_V4L2_SUBDEV: + ret =3D isp_register_subdev(slot, desc, v4l2_dev); + break; + case MEDIA_ENTITY_TYPE_BASE: + default: + ret =3D isp_register_base_entity(slot, desc, v4l2_dev); + break; + } + if (ret) + goto err_unregister; + } + + /* Create links =E2=80=94 only from SOURCE side to avoid duplicates */ + for (i =3D 0; i < num_entities; i++) { + const struct camss_isp_entity_desc *desc =3D &descs[i]; + unsigned int num_pads =3D isp_count_pads(desc->pads); + + for (pi =3D 0; pi < num_pads; pi++) { + const struct camss_isp_pad_desc *pad =3D &desc->pads[pi]; + struct media_entity *src_entity, *sink_entity; + unsigned int src_pad_idx, sink_pad_idx; + u32 lflags; + + if (!(pad->flags & MEDIA_PAD_FL_SOURCE)) + continue; + if (pad->peer_entity < 0) + continue; + + src_entity =3D isp_pipeline_media_entity(pipeline, i); + sink_entity =3D isp_pipeline_media_entity(pipeline, + (unsigned int)pad->peer_entity); + src_pad_idx =3D pi; + sink_pad_idx =3D pad->peer_pad; + + lflags =3D pad->link_flags ? + pad->link_flags : + (MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); + + ret =3D media_create_pad_link(src_entity, src_pad_idx, + sink_entity, sink_pad_idx, + lflags); + if (ret) + goto err_unregister; + } + } + + return 0; + +err_unregister: + camss_isp_pipeline_unregister(pipeline); + return ret; +} +EXPORT_SYMBOL_GPL(camss_isp_pipeline_register); + +MODULE_DESCRIPTION("CAMSS ISP pipeline topology builder"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/platform/qcom/camss/camss-isp-pipeline.h b/drive= rs/media/platform/qcom/camss/camss-isp-pipeline.h new file mode 100644 index 0000000000000000000000000000000000000000..5dfa32dcafc0a944ca2c160fb58= 46a2c73214acc --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-isp-pipeline.h @@ -0,0 +1,228 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * CAMSS ISP pipeline helper =E2=80=94 declarative MC topology builder + * + * Drivers describe their entire media graph =E2=80=94 entities (video dev= ices, + * subdevs, or base entities), their pads, and the links between them =E2= =80=94 + * in a single static descriptor table. The builder validates the table, + * allocates and registers all entities, and creates all MC links. + * + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _CAMSS_ISP_PIPELINE_H +#define _CAMSS_ISP_PIPELINE_H + +#include +#include +#include +#include +#include +#include + +/** + * struct camss_isp_pad_desc - descriptor for one pad and its optional link + * + * @flags: Pad flags: MEDIA_PAD_FL_SINK, MEDIA_PAD_FL_SOURCE, + * MEDIA_PAD_FL_MUST_CONNECT. A zero @flags value acts as + * the sentinel that terminates the pad list. + * @peer_entity: Index of the peer entity in the descriptor array, or -1 + * if this pad has no link. + * @peer_pad: Pad index on the peer entity to link to. + * @link_flags: MC link flags (MEDIA_LNK_FL_*). Defaults to + * MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED when zero. + * + * Links are described from both sides (each endpoint references the other= ), + * but the builder only creates each link once =E2=80=94 from the SOURCE s= ide. + */ +struct camss_isp_pad_desc { + u32 flags; + int peer_entity; + unsigned int peer_pad; + u32 link_flags; +}; + +/** + * struct camss_isp_entity_desc - descriptor for one entity in the pipeline + * + * @name: Human-readable entity name (also used as video device name + * suffix when @obj_type is MEDIA_ENTITY_TYPE_VIDEO_DEVICE). + * @obj_type: MEDIA_ENTITY_TYPE_VIDEO_DEVICE, MEDIA_ENTITY_TYPE_V4L2_SUBD= EV, + * or MEDIA_ENTITY_TYPE_BASE. + * @function: MEDIA_ENT_F_* function identifier. + * @pads: Sentinel-terminated (flags =3D=3D 0) array of pad descripto= rs. + * + * Fields used only for MEDIA_ENTITY_TYPE_VIDEO_DEVICE: + * @vdev.caps: V4L2_CAP_* device capabilities. + * The video device direction (VFL_DIR_RX/TX/M2M) is derived + * automatically from @caps by the builder. + * @vdev.drvdata: Opaque pointer set via video_set_drvdata() after registr= ation. + * @vdev.fops: File operations (may be NULL to use kernel defaults). + * @vdev.ioctl_ops: ioctl operations (may be NULL). + * + * Fields used only for MEDIA_ENTITY_TYPE_V4L2_SUBDEV: + * @subdev.ops: Subdev operations (may be NULL). + */ +struct camss_isp_entity_desc { + const char *name; + u32 obj_type; + u32 function; + const struct camss_isp_pad_desc *pads; + + union { + /* MEDIA_ENTITY_TYPE_VIDEO_DEVICE */ + struct { + u32 caps; + void *drvdata; + const struct v4l2_file_operations *fops; + const struct v4l2_ioctl_ops *ioctl_ops; + } vdev; + /* MEDIA_ENTITY_TYPE_V4L2_SUBDEV */ + struct { + const struct v4l2_subdev_ops *ops; + } subdev; + }; +}; + +/** + * struct camss_isp_pipeline_entity - one registered entity slot + * + * Internal to the pipeline; drivers access entities via the accessor help= ers. + * + * @obj_type: mirrors the descriptor's @obj_type. + * @pads: allocated pad array for this entity. + * @num_pads: number of entries in @pads. + * @vdev: valid when @obj_type =3D=3D MEDIA_ENTITY_TYPE_VIDEO_DEVICE. + * @subdev: valid when @obj_type =3D=3D MEDIA_ENTITY_TYPE_V4L2_SUBDEV. + * @entity: valid when @obj_type =3D=3D MEDIA_ENTITY_TYPE_BASE. + */ +struct camss_isp_pipeline_entity { + u32 obj_type; + struct media_pad *pads; + unsigned int num_pads; + union { + struct video_device vdev; + struct v4l2_subdev subdev; + struct media_entity entity; + }; +}; + +/** + * struct camss_isp_pipeline - registered ISP pipeline topology + * + * Allocate with camss_isp_pipeline_alloc(), register with + * camss_isp_pipeline_register(), tear down with + * camss_isp_pipeline_unregister(), free with camss_isp_pipeline_free(). + * + * @v4l2_dev: Pointer to the caller-provided V4L2 device. + * @drv_priv: Driver-private pointer; not touched by the framework. + * @num_entities: Number of entries in @entities. + * @entities: Per-entity state; flexible array. + */ +struct camss_isp_pipeline { + struct v4l2_device *v4l2_dev; + void *drv_priv; + + unsigned int num_entities; + struct camss_isp_pipeline_entity entities[] __counted_by(num_entities); +}; + +/** + * camss_isp_pipeline_alloc() - allocate a pipeline for @num_entities enti= ties + * + * Returns a pointer to the new pipeline or ERR_PTR on failure. + * Free with camss_isp_pipeline_free() if never registered, or call + * camss_isp_pipeline_unregister() followed by camss_isp_pipeline_free(). + */ +struct camss_isp_pipeline *camss_isp_pipeline_alloc(unsigned int num_entit= ies); + +/** + * camss_isp_pipeline_free() - free an unregistered pipeline + * @pipeline: pipeline to free (may be NULL) + */ +void camss_isp_pipeline_free(struct camss_isp_pipeline *pipeline); + +/** + * camss_isp_pipeline_register() - validate descriptors and register the g= raph + * @pipeline: pipeline (allocated with camss_isp_pipeline_alloc()) + * @v4l2_dev: caller-owned and already-registered V4L2 device; its + * associated media_device (v4l2_dev->mdev) must also be + * initialised and registered before this call. + * @descs: array of @num_entities entity descriptors + * @num_entities: number of entities; must equal pipeline->num_entities + * + * Validates the descriptor table (link direction consistency, index bound= s), + * then registers all entities into the provided v4l2_device / media_device + * and creates all MC pad links. + * + * Returns 0 on success or a negative error code. + */ +int camss_isp_pipeline_register(struct camss_isp_pipeline *pipeline, + struct v4l2_device *v4l2_dev, + const struct camss_isp_entity_desc *descs, + unsigned int num_entities); + +/** + * camss_isp_pipeline_unregister() - tear down a registered pipeline + * @pipeline: pipeline to unregister + */ +void camss_isp_pipeline_unregister(struct camss_isp_pipeline *pipeline); + +/** + * camss_isp_pipeline_get_vdev() - return the video_device for entity @idx + * @pipeline: registered pipeline + * @idx: entity index (must be MEDIA_ENTITY_TYPE_VIDEO_DEVICE) + * + * Returns NULL if @idx is out of range or the entity is not a video devic= e. + */ +static inline struct video_device * +camss_isp_pipeline_get_vdev(struct camss_isp_pipeline *pipeline, + unsigned int idx) +{ + if (WARN_ON(idx >=3D pipeline->num_entities)) + return NULL; + if (WARN_ON(pipeline->entities[idx].obj_type !=3D + MEDIA_ENTITY_TYPE_VIDEO_DEVICE)) + return NULL; + return &pipeline->entities[idx].vdev; +} + +/** + * camss_isp_pipeline_get_subdev() - return the v4l2_subdev for entity @idx + * @pipeline: registered pipeline + * @idx: entity index (must be MEDIA_ENTITY_TYPE_V4L2_SUBDEV) + * + * Returns NULL if @idx is out of range or the entity is not a subdev. + */ +static inline struct v4l2_subdev * +camss_isp_pipeline_get_subdev(struct camss_isp_pipeline *pipeline, + unsigned int idx) +{ + if (WARN_ON(idx >=3D pipeline->num_entities)) + return NULL; + if (WARN_ON(pipeline->entities[idx].obj_type !=3D + MEDIA_ENTITY_TYPE_V4L2_SUBDEV)) + return NULL; + return &pipeline->entities[idx].subdev; +} + +/** + * camss_isp_pipeline_get_entity() - return the media_entity for entity @i= dx + * @pipeline: registered pipeline + * @idx: entity index (must be MEDIA_ENTITY_TYPE_BASE) + * + * Returns NULL if @idx is out of range or the entity is not a base entity. + */ +static inline struct media_entity * +camss_isp_pipeline_get_entity(struct camss_isp_pipeline *pipeline, + unsigned int idx) +{ + if (WARN_ON(idx >=3D pipeline->num_entities)) + return NULL; + if (WARN_ON(pipeline->entities[idx].obj_type !=3D + MEDIA_ENTITY_TYPE_BASE)) + return NULL; + return &pipeline->entities[idx].entity; +} + +#endif /* _CAMSS_ISP_PIPELINE_H */ --=20 2.34.1 From nobody Fri Jun 12 14:18:25 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 CC1D63D3CF0 for ; Thu, 7 May 2026 22:50:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194229; cv=none; b=UfTBtihO8t25QsOgQEVVuof8mQovBexc5Efc3ARjCEh1UkJBay8XH5bo1olnfAWqdLhqka/C6l/Q20kUfkGjzHJqMKi+H3RDgLJhEjp7Nwg14Qu31mqd/4vrfBCVkp+V2GEtklFJJ66SLotBg1B3JINSK0VueR7iyM9SqaiWZN0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194229; c=relaxed/simple; bh=Mh7PVsHAeBxro5wjXWn2s92lyXis/97vUohYTl63Csk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Wyp2ASVjld8ZZESluXto3SJI6qZsRTNLuTjZWP8OnwrHEhfudGeKjSdN4tLhtaiQsHas1eLd9cakW81cIAXme5HX44uPfxAtNq8DEKgBMvRERDSYQJQfSEZp39ZQh+FYVCwoK3J2K4AF4veHneM2fe9atYxVQEVSi0PYdMclG7k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=cm5cXAyn; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=j6jHnOaK; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="cm5cXAyn"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="j6jHnOaK" Received: from pps.filterd (m0279862.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 647HRfit2734318 for ; Thu, 7 May 2026 22:50:27 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= GkDMdHG4MAKPTHoh78zrZYswwET0RC/m0vlXIvO5Ql8=; b=cm5cXAynoc4yOlLQ Jgq7Sn2/5lfb8qefqI1moOAHcnBVK6py1EVTTTQBE9ZuPE8ue/beKKNxKf79hVer d+8PcKd90wkmQj3WTNzlUGRc8iZyDyaNmYzHBZpcLeOcZa9wueyNPcaocMcXN08b bOo8l1r8O3pdhi38r0eAQhUoVCeiS9PkSLQXvlOMsG8vh64beufan/GDnrG8nPIc CXcQKCCxfDGL3TLfFi1WGdA+y4BA0RklDrpoDvzDAKaau/R2PAG4uduZIxTdp9FW R2h+m19auigZT+nl5ixXBMcph2gCg+wAZThbJWDKnJRN0i08+3ryCt3s9FnVXFCD uTwIQA== Received: from mail-vs1-f71.google.com (mail-vs1-f71.google.com [209.85.217.71]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4e0tbqtbqf-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 07 May 2026 22:50:27 +0000 (GMT) Received: by mail-vs1-f71.google.com with SMTP id ada2fe7eead31-6313cb80e7eso216984137.2 for ; Thu, 07 May 2026 15:50:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1778194226; x=1778799026; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=GkDMdHG4MAKPTHoh78zrZYswwET0RC/m0vlXIvO5Ql8=; b=j6jHnOaKrmorfm+f9mAo8le7AMYl+hjGCVyNCRuytYyYfU/mD0y0ELN18+YyJNQddz gQBXCPkDmVrmgMUsBE2rIHbfD8DGLv9pM39cEqyREeWT7uW7S1DFeQQABlpIO0v/R1Qi OWWrNeacCb6Sm5+AJ9UcGxd1zMrefX80qouObUz2EN4vYlBbS3dv9WarQbdjkyRyvodO zScYU3rWoqhLmse1S1hnDZ+0yGi7myF4UVXby8BOtwlLRbY0pcxP7J0bgPAgDV3Dj9b5 Cj/xil7Z4FiWKTrN6Yjbn+QHnRHdwTNdp0U5B9sU8a5bKH1Gmiv4u6Sqc9BZl/QRyGhy uzvA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778194226; x=1778799026; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=GkDMdHG4MAKPTHoh78zrZYswwET0RC/m0vlXIvO5Ql8=; b=C+FFQPNPxLBlBG4fWTPacDdZBrYkNAwBqlRn3dAy6Gq+K/xrwLPOkNVPkHZqmilxwZ DCm+o550zyJ4gjQuo0Rz+4O4GPWYeeKK/IJpKgGqw6t/lHQrK7r8NPvwofZk3A75Mrfi ibz/qLlNmTA7DuSq1LeqqtDcRMiH+1DUV114wBc75CQpxVNLIG+CEbVbP7u/MLiLJ6zM UH4J3TX6G21gljoUUU0QtE59795HMYkxeVS8sYtHITmeH9ZRNjC3WTt0RhpsaKllF+sy pIKQpTUnWh1xZobPcLJyrFyKpRmkw1kKvdPWlgvJPmxqNRPzWONEnjurRCH1OIgdodyk XQxg== X-Forwarded-Encrypted: i=1; AFNElJ+5YTK6K6gIs1POGvjO7NOQ0luIP+zEsVLGTU2+Fgu23fkgXbSg0gnwXmxkiWz3AtYUvLQ6kvoIdAg4bdY=@vger.kernel.org X-Gm-Message-State: AOJu0YygmJfIfabtqOJ95nSWLT5evnRN2ReDSNNBgElC6IhWa9QWxz1J hGPF361g/itxsc7Tki2x3kgUWqj/EPO/vXk94hUnFK0tCr5Jxxxht1uxLM6l9XPWdU+60b86lja H0udi+FxWfeP/2r/WIYjVtyy4C/FrWYSrxld3h8EfPv/Lw66ZC/Epaw1xG8JwYm9dcwo= X-Gm-Gg: AeBDiesK15FEjB0GauDG3F9Y2FHfmmpvL+BFPGXCcfhrNWGf4IQwmgCSXQyxefBpZon GOeaSsFL9X/LrCTs/cQ5M8CXddcfIZ+EBFH32l0sC9NfAvw18GMazOCjdisn4p9BrSIHB6MlTOi MWYaARei7Z4dtHT+PUBPnqNfsMfSgYspDhIFS2fi542AuCIMH2NiUDdQTXoGVY8KuHpiO4s3ruk qOZ2rPrMWh94zU+HGWz3YZVtxTT4eeb0F3twMafxf75VvgfMoU8N2qNi0LSaG3qbSB7Q3c0ClJT Yp3kwFkyzoz71LCFtUusgI/mDJhXTfYKWe4BZiaKJqfskX5a0+WUF7nWBLqqa8smvaOgw+mLOq4 lTCm7mPBBhoAT+6k7xsVfv6LRs1AqZM+1CGLz96g9/JjnXXn3MQkRUeEsMpMVg1qugJMHVKbntp 7AknVolS7WmFHMKOUNvR/DLjFrjPw= X-Received: by 2002:a05:6102:f0f:b0:606:49d:1861 with SMTP id ada2fe7eead31-630f9058f05mr5648720137.27.1778194226280; Thu, 07 May 2026 15:50:26 -0700 (PDT) X-Received: by 2002:a05:6102:f0f:b0:606:49d:1861 with SMTP id ada2fe7eead31-630f9058f05mr5648702137.27.1778194225890; Thu, 07 May 2026 15:50:25 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:b16a:3475:ec42:bcfa]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bcac4359dbesm102466b.48.2026.05.07.15.50.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 May 2026 15:50:24 -0700 (PDT) From: Loic Poulain Date: Fri, 08 May 2026 00:49:22 +0200 Subject: [PATCH v3 07/15] media: qcom: camss: Add V4L2 meta format for CAMSS ISP parameters Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260508-camss-isp-ope-v3-7-bb1055274603@oss.qualcomm.com> References: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> In-Reply-To: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> To: Bryan O'Donoghue , Vladimir Zapolskiy , Loic Poulain , Mauro Carvalho Chehab , Kees Cook , "Gustavo A. R. Silva" , Bryan O'Donoghue , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio Cc: linux-media@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devicetree@vger.kernel.org, laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com, johannes.goede@oss.qualcomm.com X-Mailer: b4 0.14.2 X-Proofpoint-ORIG-GUID: EzRKYMOWyjbHw-ugcphhprVfpj3yrBVJ X-Authority-Analysis: v=2.4 cv=SJVykuvH c=1 sm=1 tr=0 ts=69fd1733 cx=c_pps a=P2rfLEam3zuxRRdjJWA2cw==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=_K5XuSEh1TEqbUxoQ0s3:22 a=EUspDBNiAAAA:8 a=mDm0RygAtmZY0osY0NEA:9 a=QEXdDO2ut3YA:10 a=ODZdjJIeia2B_SHc_B0f:22 X-Proofpoint-GUID: EzRKYMOWyjbHw-ugcphhprVfpj3yrBVJ X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTA3MDIzMSBTYWx0ZWRfX0c5zw1xXsSYC IUWOD5ShsgGl3Fb/POx6gk/MypATJtIS3kbK2kCm/lrsqMTnChdwu2n+ljhpoNgvE/rdVBSz/DW 0C0DGJ+83xSimid04rpndXicLbL5rFpRl2QLyDKFS6M6gQDc5bJRKrk22DCp4gt6d6XErieEpGr SjFFXlDoyF8F6pdwj1n2L5T/dE0kqghwIei5f8Q0pQt2qXxIiNfYPUfE0eZ8l/PoB+oadHMdGbV UurYvg8lBwVcKPuXg4mAvWPtnUOW1n1BqzhbPLOs5carTkMgx3YSUNr28eb1EEHp4vG/px0JitW JCLWiIqRfW0o+TEQ039Wzz0fa8FC5N9o+wY8xqtzuGsVMZFMcn4xPEE0mkeMh9bfKHyMWsWrtOQ 8GRMg1uNGi/u25e6kgOBE+kfacN3acZuGbobie7ubdwnz2FmQayelZjYUI5PlJPtBDbFJHPUQPE oa5xAFk0jQ+uYQNOSPQ== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-05-07_02,2026-05-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 priorityscore=1501 suspectscore=0 lowpriorityscore=0 impostorscore=0 bulkscore=0 adultscore=0 malwarescore=0 spamscore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2605070231 Add a V4L2 meta format code (V4L2_META_FMT_QCOM_CAMSS_PARAMS) for the Qualcomm CAMSS ISP parameter buffer. This format is used by the params video node exposed by CAMSS offline ISP drivers (e.g. OPE) to carry per-frame ISP tuning data such as white balance, color correction and chroma enhancement settings. Signed-off-by: Loic Poulain --- drivers/media/v4l2-core/v4l2-ioctl.c | 1 + include/uapi/linux/videodev2.h | 3 +++ 2 files changed, 4 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core= /v4l2-ioctl.c index 98512ea4cc5b9d725e1851af2ed38df85bb4fa8c..7b6e9a9a514f037190d55d59409= dd6cc97522943 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1471,6 +1471,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_META_FMT_C3ISP_STATS: descr =3D "Amlogic C3 ISP Statistics"; b= reak; case V4L2_META_FMT_MALI_C55_PARAMS: descr =3D "ARM Mali-C55 ISP Parameter= s"; break; case V4L2_META_FMT_MALI_C55_STATS: descr =3D "ARM Mali-C55 ISP 3A Statist= ics"; break; + case V4L2_META_FMT_QCOM_ISP_PARAMS: descr =3D "Qualcomm CAMSS ISP Paramet= ers"; 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 add08188f06890182a5c399a223c1ab0a546cae1..f861211ebd7aefbcf4096885388= 069efed27ddc3 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -888,6 +888,9 @@ 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 Qualcomm CAMSS offline ISP */ +#define V4L2_META_FMT_QCOM_ISP_PARAMS v4l2_fourcc('Q', 'C', 'I', 'P') /* Q= ualcomm CAMSS ISP Parameters */ + #ifdef __KERNEL__ /* * Line-based metadata formats. Remember to update v4l_fill_fmtdesc() when --=20 2.34.1 From nobody Fri Jun 12 14:18:25 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 8D80A3D6462 for ; Thu, 7 May 2026 22:50:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194232; cv=none; b=b92JdcmSB7NxWTPFMHq3w/2cID8MLMtnIPS9DTHJAW8FcHd2exn5aWOlfP3ldVuZ3vQY/Bh+rUIzIj9gSbVPlxp1oq4mvKKrVKCp973nlU4cUK7mp0rOQBV1j4OsnpVBafRdZZDM5AzRFiMAJPQ6NSC7KEarOG7llvL4uXW5Gv8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194232; c=relaxed/simple; bh=KTYQxoDHRK+AaxLzVW7P0uYiEE/yFjt5Rigb2R9yyTw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DwXd+I4Kgo9qUJjMludyQCpa2eQYrMN00j0BZw2pDLazhq0mgdqCRmUQHhBqqSi87hVED3p7RWuLPeRoXPC3AkrMcPJg3ysV1Ob84z4RBsa8VjjdfRE1WcUOsPAA8VIKVWxEelAhqqx+ycA0KJfRYTdpKPM34o2Ldww5C6L7R2U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=CKxR98FL; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=CLFRJgYD; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="CKxR98FL"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="CLFRJgYD" Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 647J7NOP2531198 for ; Thu, 7 May 2026 22:50:30 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= gnBfolT3jX6CNISr4JxMcRA7ySnkS3THYsCQYykqpxA=; b=CKxR98FLhzhXSFsV Mqz5y/JoLwgyfQLmiQ4OUDfi0QC6Z0fjQ45VahFmB1jG/WNQI4jNOi9KA5mpTsIi vheIPckggPKlCOE9nIMa0bJU+TpxWCvAYq6cufddqXbq0yaPUx7QdHKdh+nYR06T 34vpxkWOVS1ULNQF2k6kcoDuPtWU7b+ej5J+kcEoXYfMtqU76OKWn8OUFlEStRAC YS4Aw5QwTLFq8w91TEHIeO4Ijta1mCfBQjBmh3dXPtZglsSwXpgjChsRixiXadqM HJaqdqa0NmS0rIkmMQLR94MdehFs1ya7Qi2uTka91iL1f7rlxHNNXnUi5oEggVWv R/jyIw== Received: from mail-vs1-f71.google.com (mail-vs1-f71.google.com [209.85.217.71]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4e10m9rm3e-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 07 May 2026 22:50:29 +0000 (GMT) Received: by mail-vs1-f71.google.com with SMTP id ada2fe7eead31-6313c9d983fso81897137.3 for ; Thu, 07 May 2026 15:50:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1778194229; x=1778799029; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=gnBfolT3jX6CNISr4JxMcRA7ySnkS3THYsCQYykqpxA=; b=CLFRJgYDP/R82vxmlOqcthSl3rPCa8+C8luB3uOgVs3LBmxPy/vExI5Mzy2CJvj6I0 fXiAw4y8gExZMYxo7ZjHQtVt1Rcw3NmWT4T6KzcrcD4Ce74q/LhkbAxIxG1v+hufpCoj +WiAQjl+zhpuxm0y9PMzQo0yjLcl0rLOaobZqOqVX8mMNMVp3NFvWj7NCbuuZwIkbkZP LApDC4lIVpnKHzsnGjHtOt77jFGP1Mc3QpdWacvu2l3U+8ACPV0RC24xXBjmGs/MRn/3 KBKY7cxi4oMIRMAxmwPI+14QzycyoqbddlXtKzjeDyNHaeZJDzNUE4xfboA7bd/xV+M3 NXPQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778194229; x=1778799029; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=gnBfolT3jX6CNISr4JxMcRA7ySnkS3THYsCQYykqpxA=; b=lWtLw3aGcyWGiftISTA5He6dY6wKqTZg4Q5r+skwfxufTpj5qvea4ZPBr51jnFD0Ba lZI2lsvgk4kU66EiQ2W9neB49nMLiwLSPrnz8VKdzpRvbL4vKoTiSRPW5pHjDI1ziTOV M4eRLLmw/f23WhCRWBo7B2s6QnSTq3koW+ALiXAAAQs1uTI6gqXiHJNGDqXnx0k8ICio 1eBO6TTK/K1HyuTEHaMmwpa6JPccuoCN2Sr5MWpQVF3xZ7MQLVJyeq3jeY56MK/m7JaZ D2KMwRaxicwViiyp3OICywW125K+1U5JadLdJtyiQhBpi9oYMTcgHpfBTatvNLWbDq8v zUtg== X-Forwarded-Encrypted: i=1; AFNElJ+BxumW9puZnmoUZ7pdGifEwhcpL2pdnoif9n1P+YASUumLnha9QDOwE14HKum/Q3QskheJ/sZzlUBH2oE=@vger.kernel.org X-Gm-Message-State: AOJu0YxznL/mYWvCGmV+b3fC7f7RzpVNxtX0CH4/FDlypfCYB7ZsLe1r ag8HHhxExGNodmWiyLKytu1CrP5rBx5B0wQ9nqXu+n3xPzF5idUqICMCrXp3CScCDcjhsVPbI2a A2d1aIQJOumK05h44wJPQuueQ3BYpoTftA1Ixe8QgEx069Khi17wx9XZWKg0iwrUUwgU= X-Gm-Gg: AeBDietsRizwSeyMIvjU7okWFOFl/WFplRPJsDUVRodOSvYPkfx1KLD4AUPwLFz+M+z RIzyLlDB8XCp7wDIx/ZgmbRS+uPPNqclEMDCCPybRTNj/awrPEfTH7lBqN6h9D/3TMcYYdFlSzf MMIqlSWkhtfn6tXg4CqO5/9G2uXr8ia1O9V/AJ20X1CYhx1tJLkfhQ4/YVZpywgylvLgUvMGZx7 HvEw89FJ8MTFnv6k27iNhJtcXwqu6X7BaeV9gQPFZWSvDDdgCqyL28O+t0HAZpVq3J4rn1kD/lz C572hdAq0IDjEqWHaAP1CL+LdTds7tqoLbb0yGGWWwibG6XzVQHVVpYk2wLdvIoL+g4CD1tNaRJ 9eNKhMsoN31jOP/4AFiNFskcugQTX6S2CGYDP52VHB/GSk2wQatCnwt7/7ybxY7/QPwKc+tmctE lmlEXCykDVTtC+k1pLBQw4jE7d9hc= X-Received: by 2002:a05:6102:580a:b0:62f:3c55:d41f with SMTP id ada2fe7eead31-630f8e6a743mr6379581137.2.1778194228843; Thu, 07 May 2026 15:50:28 -0700 (PDT) X-Received: by 2002:a05:6102:580a:b0:62f:3c55:d41f with SMTP id ada2fe7eead31-630f8e6a743mr6379564137.2.1778194228416; Thu, 07 May 2026 15:50:28 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:b16a:3475:ec42:bcfa]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bcac4359dbesm102466b.48.2026.05.07.15.50.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 May 2026 15:50:27 -0700 (PDT) From: Loic Poulain Date: Fri, 08 May 2026 00:49:23 +0200 Subject: [PATCH v3 08/15] media: qcom: camss: Add camss-isp-params helper Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260508-camss-isp-ope-v3-8-bb1055274603@oss.qualcomm.com> References: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> In-Reply-To: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> To: Bryan O'Donoghue , Vladimir Zapolskiy , Loic Poulain , Mauro Carvalho Chehab , Kees Cook , "Gustavo A. R. Silva" , Bryan O'Donoghue , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio Cc: linux-media@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devicetree@vger.kernel.org, laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com, johannes.goede@oss.qualcomm.com X-Mailer: b4 0.14.2 X-Proofpoint-GUID: q8he4WZG_rtlftM7zB_VrDOktmYv0-Jr X-Authority-Analysis: v=2.4 cv=VP3tWdPX c=1 sm=1 tr=0 ts=69fd1735 cx=c_pps a=P2rfLEam3zuxRRdjJWA2cw==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yOCtJkima9RkubShWh1s:22 a=EUspDBNiAAAA:8 a=ELVW7ba-Z2avb-AJsJIA:9 a=QEXdDO2ut3YA:10 a=ODZdjJIeia2B_SHc_B0f:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTA3MDIzMSBTYWx0ZWRfX1UJrmxoU72HX AIpoEcS26+EQruYMUiyV3lvE2/jt3BeDv7NR4MDhY1LrTTxm2HGtsp0i3LV/MgoOkwoxQyM8dRF e4E15C+JSrHKb3gECgvtxRtViF7l8xjEB0i6/Ly0EBCKdL8bDJNDkrdoCi4n3KeDDqdfWVYfmA1 59cAdqekSlBJp5oYpM1EGMFRV+qk5ii7BJO/WOGf6Gw8sJuS9cROekRra+5hu6yZdiLNE7CsStj NBBHgSGiQBLISy+RFzT35aiYvOZr9JKzRumurUwBTceVXckI7y2CHbYRO2/Y0A1iL3Pt5P5jVDQ 13Sywrvt73H5b9kcQy1jrAurjhaceCuXR+i7zCZXRgVAzo4VvtCBEoS7TAX0v4NsKvrIMoEYbvA S/o2LaVN5KPgyWpTqeVxf4Cg/6GFXr5tL6ku5/UNAzFbZoZ1iFmoFo5A4SydF/4hv0SWpPIQbU1 Gw7h6me5RSBxNYwdGnw== X-Proofpoint-ORIG-GUID: q8he4WZG_rtlftM7zB_VrDOktmYv0-Jr X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-05-07_02,2026-05-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 spamscore=0 bulkscore=0 impostorscore=0 lowpriorityscore=0 malwarescore=0 clxscore=1015 suspectscore=0 phishscore=0 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2605070231 Add an ISP parameter buffer parser for CAMSS offline ISP drivers. camss_isp_params_apply() wraps the upstream v4l2-isp buffer validation and adds a dispatch layer: after validation each block is forwarded to a driver-supplied handler indexed by block type. Signed-off-by: Loic Poulain --- drivers/media/platform/qcom/camss/Makefile | 3 +- .../media/platform/qcom/camss/camss-isp-params.c | 67 ++++++++++++++++++= ++++ .../media/platform/qcom/camss/camss-isp-params.h | 62 ++++++++++++++++++= ++ 3 files changed, 131 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/pla= tform/qcom/camss/Makefile index f3acb1b54b6c1455d72e2d947c860f0c337648de..fba6f34b8d9f70ea258f7ae1a29= 3a8d58d866498 100644 --- a/drivers/media/platform/qcom/camss/Makefile +++ b/drivers/media/platform/qcom/camss/Makefile @@ -32,7 +32,8 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS) +=3D qcom-camss.o =20 qcom-camss-isp-objs :=3D camss-isp-bufq.o \ camss-isp-sched.o \ - camss-isp-pipeline.o + camss-isp-pipeline.o \ + camss-isp-params.o =20 obj-$(CONFIG_VIDEO_QCOM_CAMSS_ISP) +=3D qcom-camss-isp.o =20 diff --git a/drivers/media/platform/qcom/camss/camss-isp-params.c b/drivers= /media/platform/qcom/camss/camss-isp-params.c new file mode 100644 index 0000000000000000000000000000000000000000..66dc717bb3a2a26707d206e5376= 91deb4d58f04d --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-isp-params.c @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * camss-isp-params.c + * + * CAMSS ISP parameter buffer parser. + * + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include + +#include "camss-isp-params.h" + +int camss_isp_params_apply(struct device *dev, + struct vb2_buffer *vb, + const struct v4l2_isp_params_block_type_info *type_info, + const camss_isp_params_handler_fn *handlers, + unsigned int num_handlers, + void *priv) +{ + const struct v4l2_isp_params_buffer *buf; + unsigned int remaining; + unsigned int offset =3D 0; + int ret; + + ret =3D v4l2_isp_params_validate_buffer_size(dev, vb, + v4l2_isp_params_buffer_size(CAMSS_PARAMS_MAX_PAYLOAD)); + if (ret) + return ret; + + buf =3D vb2_plane_vaddr(vb, 0); + + ret =3D v4l2_isp_params_validate_buffer(dev, vb, buf, type_info, num_hand= lers); + if (ret) + return ret; + + dev_dbg(dev, "params: version=3D%u data_size=3D%u\n", buf->version, buf->= data_size); + + remaining =3D buf->data_size; + + while (remaining >=3D sizeof(struct v4l2_isp_params_block_header)) { + const union camss_isp_params_block *block =3D + (const union camss_isp_params_block *)&buf->data[offset]; + u16 type =3D block->header.type; + u32 bsize =3D block->header.size; + + if (type < num_handlers && handlers[type]) + handlers[type](priv, block); + else + dev_dbg(dev, "params: no handler for block type %u\n", type); + + offset +=3D bsize; + remaining -=3D bsize; + } + + dev_dbg(dev, "params: buffer parsed successfully\n"); + + return 0; +} +EXPORT_SYMBOL_GPL(camss_isp_params_apply); + +MODULE_DESCRIPTION("CAMSS ISP parameter buffer parser"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/platform/qcom/camss/camss-isp-params.h b/drivers= /media/platform/qcom/camss/camss-isp-params.h new file mode 100644 index 0000000000000000000000000000000000000000..4cedfbc745f81655569ff8bdd8e= 389b35f2c67a7 --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-isp-params.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * camss-isp-params.h + * + * CAMSS ISP parameter buffer parser. + * + * Wraps the upstream v4l2_isp_params_validate_buffer() validation and adds + * a dispatch layer: after validation each block is forwarded to a + * driver-supplied handler. + * + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef CAMSS_ISP_PARAMS_H +#define CAMSS_ISP_PARAMS_H + +#include +#include +#include + +#define CAMSS_ISP_PARAMS_FMT_INIT \ + { .fourcc =3D V4L2_META_FMT_QCOM_ISP_PARAMS, .depth =3D 8, .align =3D 0, = .num_planes =3D 1 } + +#define CAMSS_ISP_PARAMS_FL_BLOCK_DIRTY (1U << V4L2_ISP_PARAMS_FL_DRIVER= _FLAGS(0)) + +struct device; +struct vb2_buffer; +struct camss_isp_fmt; + +union camss_isp_params_block { + struct v4l2_isp_params_block_header header; + struct camss_params_wb_gain wb_gain; + struct camss_params_chroma_enhan chroma_enhan; + struct camss_params_color_correct color_correct; +}; + +typedef void (*camss_isp_params_handler_fn)(void *priv, const union camss_= isp_params_block *block); + +/** + * camss_isp_params_apply - validate and dispatch a params buffer + * + * @dev: device for error logging + * @vb: the vb2 buffer (used for size validation) + * @type_info: per-block-type validation info, indexed by block type + * @handlers: per-block-type handlers, indexed by block type + * @num_handlers: number of entries in @type_info and @handlers + * @priv: opaque pointer forwarded to each handler + * + * Calls v4l2_isp_params_validate_buffer_size(), then + * v4l2_isp_params_validate_buffer(), then walks the validated block stream + * dispatching each block to its handler. + * + * Returns 0 on success, negative errno on validation failure. + */ +int camss_isp_params_apply(struct device *dev, + struct vb2_buffer *vb, + const struct v4l2_isp_params_block_type_info *type_info, + const camss_isp_params_handler_fn *handlers, + unsigned int num_handlers, + void *priv); + +#endif /* CAMSS_ISP_PARAMS_H */ --=20 2.34.1 From nobody Fri Jun 12 14:18:25 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 D70073D75DA for ; Thu, 7 May 2026 22:50:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194235; cv=none; b=fMINFMOTaDnPpDQK45eR9fdUB3MXyhiTE5BsF3Z/YR/OAmgOZYSS/3dfCVCeKeRuCAw1jLKDtfLcEalw8qbaZLW8fgtZd8xVb06HgWLbT9Ixofj9l2mWEl52o+Sr0SGx5+uRM8rMhLmwFe0+xDZMzjxu6PSsYRowXb4FAv+8WX8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194235; c=relaxed/simple; bh=HnARY+NkaPNMNUfBnCSEykpZMQqEGOfF6pr1czcSrpk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=kC38mX3bCdCagtf+oLqmIgZ9kphhJGmdmZloq/fN9xbknjbRxaNu/fhgBf9n6FqLT+aKDwaG3iDMC3Vt7iutcLhB6zUm6Gl4EVLFnqw5TRvSUUFJoRFBMaDPeChvc5MXStsNZgs7qLEwb1fmIQfLCCgSr7Lg6UITJ3e2aX77wQk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=bUBFhLsk; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=O43INbA3; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="bUBFhLsk"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="O43INbA3" Received: from pps.filterd (m0279870.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 647JrDX12198694 for ; Thu, 7 May 2026 22:50:33 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= 0Q0b5h3vUIlMdYhm0j7sbnZMJtdjyZUlMTDf45sV05Q=; b=bUBFhLskwAmbqqKZ WBd9gh4rFtkYZ2PJs7seBp1fnAbqgGZ3o3Z/5MxhhCQnCdKuGtjPg73dozAVMQ6e /YS5/KktrLbxVDC8E7om3a/2tTiM2xwU8LayCXkbrE9zXfMGO+rGEHu3dR4LyPbR ELXZidV4g7EHfR6x9EsfPnwNjrj/xnI/JmkXe98BdCdlAuzSaHGnlUEKcggQ2AMg aUE3mdzVFd/0RMYQ1JoycCPPjia4Rkyqgoqn4o0ZL/NQ3802SiPup1epPj44rKJ4 uv9L2QcUYOyA/Bc5ThCrc29pycE6TnKlGwiEwuS4dfUq/2MmN8Hx7vT/a2QCJH5z VssuKg== Received: from mail-ua1-f71.google.com (mail-ua1-f71.google.com [209.85.222.71]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4e119sgg7k-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 07 May 2026 22:50:32 +0000 (GMT) Received: by mail-ua1-f71.google.com with SMTP id a1e0cc1a2514c-95d434f3356so1327730241.0 for ; Thu, 07 May 2026 15:50:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1778194232; x=1778799032; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=0Q0b5h3vUIlMdYhm0j7sbnZMJtdjyZUlMTDf45sV05Q=; b=O43INbA31XQNhHM6Yes940vuK3EAa3vrOR9xqVx87BFLjiXxvhAJrI/gGoVluw9wYO libeDdrNbKea2z/fEO6cG7tlXmSn/00nky98ZZZP5pgNchOSVRB7pag6RnqY1e2FEJJu jnqkVirPOuvdLU5z0LO93yHcLqFOstBe8nXlWX6uZxu/ARm3KE2bi646E4Vuuhljk23F 2vzlFGFwDNgFzHJGfCX3BEFWzveGMuCJBu0tgItU+/G1AE3I2vrS9JXXpB39XcG/LHEQ JhlnPekE4RscmE+CGpfYCPfOx+ao2NudStWbvuCgkVv2VZGvNyX8d3NHqoYB3Cj3GcDX 3HgA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778194232; x=1778799032; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=0Q0b5h3vUIlMdYhm0j7sbnZMJtdjyZUlMTDf45sV05Q=; b=JqE24bVSKRwXY0+sMGEWWn/WLHQ9FVTe+Z6W/VG301Kc4BkAgnLiZ26dbunajJ2STI ZIlunr6l4Ae2qwofu58pODteEys9g5xppm/OrEprcXc4G789mDlFzCO/pyWWkh45pJeZ 2y7PLYqBCxhfC2DCvgSErp4jEDtA38r6p7cSBwqvFagTNnRw4LNXR1IvzbCm9AxsLbSC KtOp6UN91W68bJ9u0Dg9pYjZ/QLhhwEGJ8c53R5GlQMO/WU5EMdvIF/k9qyl7NN+EXjh 1J7ir/RGoDabwKIfcX8yEl31iYf8AVlAA+53O2D6zx4OPtBciDiNa+x5ZP0yr0pKOlXA 6/PQ== X-Forwarded-Encrypted: i=1; AFNElJ+6vRl9cSce+s04unQmd/3C8+0R002KKO1XQ93EIeyXZQB43x0dhgt0z+OGt4ylhr9ZyWH4khhrPe8CS50=@vger.kernel.org X-Gm-Message-State: AOJu0Yx3FjPVboqbHNnJIJDxd70ugLL+7e/fRbo9gcXjYPX4wXYumq7s 4lFgbUQ3wA3tZO1Wfw3epfjRK26TWsLlq500HUTUqsk4/6aIcqw+fJnyOHfyGz++f8y18aONVF+ XZ15YO4ZRJEpPaRuhlkQI4P5XkDVEdZU9Cgko/B9pu9goB/8WR0P6d4dX5o7m8Pq/CwQ= X-Gm-Gg: AeBDieuzzaNNbpcTVcKukt5avR66qNkPObz5ug1M5u2nvsLv/nkm/XdfKHGKoCcbCjB oY1cBAkERC0KtkgWfNfErIqFqDmjijjrE/2VcjreCw397dsE8QnR50zdcYlfEcLiJh5Qxb/WNaH xasicX3xinRX6wFxr1jFOuGfecjcuTdgfeS2Njd89m9OSFuc7FA5ShX5wQYQHttaEP+Xe0rid/L 8cIKD0rUMuisQ5LrUGsABzdVf9/H37/XtgFsSAmYyArkW9xNOqc7NIrdv5gJJxuaP8/cQdWIc5c IKE3YehwjfpUUAZ4CCA4o7R1TOBI0RergsofEw+InVzGwvAEHwSkJzU4+2uZ/dscRO+zKSDlL2e Etl1AgA7dekEziCOzpeTnp+Uuq1YFGMXcyXIg6I+HXkY6ZN0+Ao/hsayDNEOEz0kE/dpPlhcI5N J5UZB41ASo2urlRJtV X-Received: by 2002:a67:e102:0:b0:60f:c9ba:b999 with SMTP id ada2fe7eead31-630f9023892mr5232283137.21.1778194232278; Thu, 07 May 2026 15:50:32 -0700 (PDT) X-Received: by 2002:a67:e102:0:b0:60f:c9ba:b999 with SMTP id ada2fe7eead31-630f9023892mr5232256137.21.1778194231783; Thu, 07 May 2026 15:50:31 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:b16a:3475:ec42:bcfa]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bcac4359dbesm102466b.48.2026.05.07.15.50.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 May 2026 15:50:30 -0700 (PDT) From: Loic Poulain Date: Fri, 08 May 2026 00:49:24 +0200 Subject: [PATCH v3 09/15] dt-bindings: media: qcom: Add CAMSS Offline Processing Engine (OPE) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260508-camss-isp-ope-v3-9-bb1055274603@oss.qualcomm.com> References: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> In-Reply-To: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> To: Bryan O'Donoghue , Vladimir Zapolskiy , Loic Poulain , Mauro Carvalho Chehab , Kees Cook , "Gustavo A. R. Silva" , Bryan O'Donoghue , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio Cc: linux-media@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devicetree@vger.kernel.org, laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com, johannes.goede@oss.qualcomm.com, Krzysztof Kozlowski X-Mailer: b4 0.14.2 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTA3MDIzMiBTYWx0ZWRfX0Ci4YYJjVNdv xSjWkywb/QI5azHcv6aUELRcAOj+yLnC8yX3FGkGHQIGo8hbyQHTgXTbKr5vKQeUDSot1Y0PPQL iciGc1DYf96YEcyHX2uLnpEAVH4xRdVOHtGsC1lwcOtQClTu1VgW4o66aitIag7BUCHcX4fBjqi qiDhMut8nsAkAQ6L8COXOISSrvgF6kimJ5cfB3z8yYyQhHqjx8Xch/NRPAUvgjVluuI5AvzgZWe xjcrkZGt7UlLF6eumE0rBZBFODMcU0zC+P2Sae1dp0AhltWahXQAyiEfMhswPdGud/6WK+UIl3L Nu3kSnYLZs0o2Igbg6/Rq3GmF7qcjaCTxwa8yc0Jo6ncrFEx/V9HKhtrgIv7v9By1KFtFy3oRFE gfFtmtAySOdJDODA61Sxkcee1KEWczq085N73248KgDJag1IjQ+19o64Y6L22nYHUXm9B33uEkt W6PusiQbZ9QSRPM8D9w== X-Proofpoint-ORIG-GUID: fUBvMBemEOexCp0ILPSZ-6eVynsH-JDM X-Proofpoint-GUID: fUBvMBemEOexCp0ILPSZ-6eVynsH-JDM X-Authority-Analysis: v=2.4 cv=Dd4nbPtW c=1 sm=1 tr=0 ts=69fd1738 cx=c_pps a=KB4UBwrhAZV1kjiGHFQexw==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=gowsoOTTUOVcmtlkKump:22 a=gEfo2CItAAAA:8 a=EUspDBNiAAAA:8 a=l64rWm3OqFMOLA4dSg0A:9 a=QEXdDO2ut3YA:10 a=o1xkdb1NAhiiM49bd1HK:22 a=sptkURWiP4Gy88Gu7hUp:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-05-07_02,2026-05-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 bulkscore=0 clxscore=1015 adultscore=0 lowpriorityscore=0 suspectscore=0 spamscore=0 impostorscore=0 phishscore=0 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2605070232 Add Devicetree binding documentation for the Qualcomm Camera Subsystem Offline Processing Engine (OPE) found on platforms such as Agatti. The OPE is a memory-to-memory image processing block which operates on frames read from and written back to system memory. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Loic Poulain --- .../bindings/media/qcom,qcm2290-camss-ope.yaml | 131 +++++++++++++++++= ++++ 1 file changed, 131 insertions(+) diff --git a/Documentation/devicetree/bindings/media/qcom,qcm2290-camss-ope= .yaml b/Documentation/devicetree/bindings/media/qcom,qcm2290-camss-ope.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c91d73af61f5cbf8384be5ff9b0= 3683de8413542 --- /dev/null +++ b/Documentation/devicetree/bindings/media/qcom,qcm2290-camss-ope.yaml @@ -0,0 +1,131 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/qcom,qcm2290-camss-ope.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Camera Subsystem Offline Processing Engine + +maintainers: + - Loic Poulain + +description: + The Qualcomm Camera Subsystem (CAMSS) Offline Processing Engine (OPE) + is a memory-to-memory image processing block. It supports a range of + pixel-processing operations such as scaling, cropping, gain adjustments, + white-balancing, and various format conversions. The OPE does not + interface directly with image sensors, instead, it processes frames + sourced from and written back to system memory. + +properties: + compatible: + const: qcom,qcm2290-camss-ope + + reg: + maxItems: 5 + + reg-names: + items: + - const: top + - const: qos + - const: pipeline + - const: bus_read + - const: bus_write + + clocks: + maxItems: 3 + + clock-names: + items: + - const: core + - const: iface + - const: data + + interrupts: + maxItems: 1 + + interconnects: + maxItems: 2 + + interconnect-names: + items: + - const: config + - const: data + + iommus: + maxItems: 2 + + operating-points-v2: true + + opp-table: + type: object + + power-domains: + maxItems: 1 + +required: + - compatible + - reg + - reg-names + - clocks + - clock-names + - interrupts + - interconnects + - interconnect-names + - iommus + - power-domains + +additionalProperties: false + +examples: + - | + #include + #include + #include + #include + #include + + camss_ope: isp@5c42400 { + compatible =3D "qcom,qcm2290-camss-ope"; + + reg =3D <0x5c42400 0x200>, + <0x5c42600 0x200>, + <0x5c42800 0x4400>, + <0x5c46c00 0x190>, + <0x5c46d90 0xa00>; + reg-names =3D "top", "qos", "pipeline", + "bus_read", "bus_write"; + + clocks =3D <&gcc GCC_CAMSS_OPE_CLK>, + <&gcc GCC_CAMSS_OPE_AHB_CLK>, + <&gcc GCC_CAMSS_NRT_AXI_CLK>; + clock-names =3D "core", "iface", "data"; + + interrupts =3D ; + + interconnects =3D <&bimc MASTER_APPSS_PROC RPM_ACTIVE_TAG + &config_noc SLAVE_CAMERA_CFG RPM_ACTIVE_TAG>, + <&mmnrt_virt MASTER_CAMNOC_SF RPM_ALWAYS_TAG + &bimc SLAVE_EBI1 RPM_ALWAYS_TAG>; + interconnect-names =3D "config", "data"; + + iommus =3D <&apps_smmu 0x820 0x0>, + <&apps_smmu 0x840 0x0>; + + operating-points-v2 =3D <&ope_opp_table>; + power-domains =3D <&rpmpd QCM2290_VDDCX>; + + ope_opp_table: opp-table { + compatible =3D "operating-points-v2"; + + opp-200000000 { + opp-hz =3D /bits/ 64 <200000000>; + required-opps =3D <&rpmpd_opp_svs>; + }; + + opp-465000000 { + opp-hz =3D /bits/ 64 <465000000>; + required-opps =3D <&rpmpd_opp_nom>; + }; + }; + }; --=20 2.34.1 From nobody Fri Jun 12 14:18:25 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 35C6B3D4137 for ; Thu, 7 May 2026 22:50:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194238; cv=none; b=Yf1RWNJ08aj+xA/wJ/U2GQ8LJ/tNKnPoscviKKBQpGEmLmQ/1RCjyv8h9wSNe9U3ryim6uIg0whtJ4SenqxZCKPqtAWgqyt5eHvFR6m++WBNi8wC5myDIA1g9+b7iXu/bdLngcXNYpcAC/RjI2OOeHDvycBU8yv203tMMnGd+7c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194238; c=relaxed/simple; bh=y/+a20YL+ysQIFGE4+AK114lY8/mBSFRbp2rnNsk+9o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Gmwn3qJX65jGeVYigGWfsuIEW1L5SsZR8si9n80qqSFawOAFMCch6aThuui5Onmk1hGiyY59u4+fmxEFSTpQV+QXpLPpnA3KpukzH916TaWI3iGlfoXGAljiuGB7cp9v2s+YGm7BqsSMx393ab9BMX/BZuLn4fLztZnqG905YRc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=LihrcusZ; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=TBU+4Uj/; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="LihrcusZ"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="TBU+4Uj/" Received: from pps.filterd (m0279873.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 647JD3tA2182882 for ; Thu, 7 May 2026 22:50:36 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= fWBniTwp1rVPBTuTnmxciCl5iow63nGmhGyjthKvyds=; b=LihrcusZCPNaVV8G /hcNguhVavhDf3AN2SifQLSR7abJ7MknEWJyaSPOQ54/J7nV2i3nbNXDy0sbMx7b TGJ2FYEFkO1HIqciqVsVVyJJc2j7ExC5M/1TxuwMtBYv+yhstnBx0xq9IBN8WtsD l9W6KeVz2M9tBSLWBh6Z5EI9dhpObyszrtiPGU8EW+n8QR+7yinUg9UaazD8AAfn qNjuafvaImrtgS8ZCQPeViu3nyTi0w4Cp8ut2ktZRhWMVkkwgZsesf63VcYwhu3v yweuedmyEbfgTvjQ5jkZ9n8TBqILvjtUFkNr/If2DoOo8aPGWB0B3yarBmBjJKvw MXJtKw== Received: from mail-ua1-f70.google.com (mail-ua1-f70.google.com [209.85.222.70]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4e10py8m6q-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 07 May 2026 22:50:36 +0000 (GMT) Received: by mail-ua1-f70.google.com with SMTP id a1e0cc1a2514c-95d5e66646aso2508222241.0 for ; Thu, 07 May 2026 15:50:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1778194236; x=1778799036; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=fWBniTwp1rVPBTuTnmxciCl5iow63nGmhGyjthKvyds=; b=TBU+4Uj/UoaKu+Gjxjb3mU0QSsRrG+pT+zcKgmlqKxPiCcgbAMTekVI7zlkUO8j6kJ aHGtCIhKcLhejN/jg6EpdpLGQQvXVHeFJRSbNVDc+5ABvre4m2QC+41Hehxps7joaBJg Cqw8eHTVO8thp7okVgFncfTxwV8BLl5rXLSklMe282oN2WITs4NX4830XifNWGHpV9ch ATln4qWi4cpV5sjqOfYoXYzzZhkk9bZawqVc0SyUOYHteHSwXsA4ma4bqIqV+ZrxDsRQ sBeqO65dj2dQYXx/5ob9U0LO9rJBsUx1mO2GmXSnXTFXPpk05bBJNfTAKmcIY0mbbFY0 to4g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778194236; x=1778799036; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=fWBniTwp1rVPBTuTnmxciCl5iow63nGmhGyjthKvyds=; b=PgIs6sUb8dkO5pC5AJN52YL85mvwHiie+v9mCpw3ueGKjPP2koq3zhVZxVc4DyozEC EcoyE5rhDOde5yfXLV6qW7l0COW226DYAP8TCl5GXym0aEWjgD/pEI0L6yKIXVXIa7wV If/uq16/T7HhCml4ltp7q6y+7zS1O2n3DZvBt7RIVNi2G9ut31dtQ8mJ0PT3utUqEuva 6oboayOmB7kQQrx7NYWYAKUFRX6ySygK+3vARXY7F9XRFJtu18Mc1WVTU8UBP9ku1Lq5 HHTloz83EKg++FAy6LrwPMb2LZX69HA7Ub7yQhv8Rs/1IhXYSjM4eDQmlK+wejLiSJBc QpOQ== X-Forwarded-Encrypted: i=1; AFNElJ8vf4ANedfUFw43F9/UIRyaMWwHbNNnP9h0bGee0vkAcqqkr4SWS0/MpC5AOKNmITzp6R4gKks1QJEZPYo=@vger.kernel.org X-Gm-Message-State: AOJu0Yzum78ynB4LRSmascPhjBfG0V5jsc08Vf2i+QTZmJ8ju3NalLpv ntzHkDDyBffeKKC4UCTSqgpXhqC5osjBZ3xiztjDLTN2LfxyI5ItTXvsM5SUujh+3UI+LaMqU+6 iplYPiAARBlvvCJYeXcHwBqQ/eWg1IQYFjWVv22v+sbOnLscd0ZDxZEmpqOy9eRh8FFs= X-Gm-Gg: AeBDies6APCdvQYUEyIytAJxvAszfHOaozbL/PG0jrslxN8aI5GL9CHaSActO/1MOyX I8e+qziyk+ml9DTyhOix7lcsl5cOkHTlX7BBmmR+QVvEkdXwKDTXqJUmxCoFeO9feYxp7xHDPdK w1+h9SACIbVjnBow7Y8cS7dPHNX7T0BupTmVwQqOClWNCkocVFkqKJbAS1Ij/X0ZAHpB3M3XrfO mHN9kGoD5IcZ6T7qvTpgm/+JflclQnJT7t/+orSjsEyKxWplfY2hwM5Eklokc7V+h72cugBk3ng TavnnL+g6O5XdE7mCW/3+9t+h0/ILJPTWmLQupLrXpk6a1aRMBHP5P2mENM0nh5kHyJ+14TA0Y+ HwxnjYiQ6xj01x57iYpw/R6LZxyzssXXEI2Zo7b8OuM4dkE4M3/Ez4K76uXxvWUD/la0rUdN5p7 7w+PRSzDqm78r0/1iH X-Received: by 2002:a05:6102:8515:10b0:631:2973:5c2c with SMTP id ada2fe7eead31-63129736518mr1766716137.21.1778194235713; Thu, 07 May 2026 15:50:35 -0700 (PDT) X-Received: by 2002:a05:6102:8515:10b0:631:2973:5c2c with SMTP id ada2fe7eead31-63129736518mr1766690137.21.1778194235272; Thu, 07 May 2026 15:50:35 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:b16a:3475:ec42:bcfa]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bcac4359dbesm102466b.48.2026.05.07.15.50.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 May 2026 15:50:33 -0700 (PDT) From: Loic Poulain Date: Fri, 08 May 2026 00:49:25 +0200 Subject: [PATCH v3 10/15] dt-bindings: media: qcom,qcm2290-camss: Add OPE ISP subnode Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260508-camss-isp-ope-v3-10-bb1055274603@oss.qualcomm.com> References: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> In-Reply-To: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> To: Bryan O'Donoghue , Vladimir Zapolskiy , Loic Poulain , Mauro Carvalho Chehab , Kees Cook , "Gustavo A. R. Silva" , Bryan O'Donoghue , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio Cc: linux-media@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devicetree@vger.kernel.org, laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com, johannes.goede@oss.qualcomm.com X-Mailer: b4 0.14.2 X-Authority-Analysis: v=2.4 cv=DZUnbPtW c=1 sm=1 tr=0 ts=69fd173c cx=c_pps a=R6oCqFB+Yf/t2GF8e0/dFg==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=rJkE3RaqiGZ5pbrm-msn:22 a=EUspDBNiAAAA:8 a=M8sXMW5dAYDte-7YvdsA:9 a=QEXdDO2ut3YA:10 a=TD8TdBvy0hsOASGTdmB-:22 X-Proofpoint-GUID: 6e-KQQ4ACcP5W5_N-cWR4m9KWPZnduPg X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTA3MDIzMiBTYWx0ZWRfX6wOyYDUZojsh r4qcrSeXzKO8worg6MFuq3InzzRErNh0IXJyZ6Lfqs7lWtVMWfsBOfl+N8d3YJBvNYxbFdMrcDU wQoExNSya2F5AOmP0YpEV98whGVEbL/trReUVhvzziBlsXN2KjPhLHyahFiSUIYQUxkGWo6+ayf dfa+UOBQu9O6XsCyWxRk7gvmoGoubp+rRhU/yYrButahwX3EcJDr8dCYV/GJwkelv6vtnAhwCnm NBrjF9BpAFIbqU+dbMwj4celNxhLRWnb1+yac3oOnAN3vV/8RPYIV3D8nADGZMauh86T0+JIeVR Gw4DQdjkJMGvFce7Qrj682HA3TmRivVLeejluBjH1CBJEhmkroZWfison/6OmQTFmuSZWW3XaR2 BpYzVNtWrOUjPmwdZIyG4x7waiISTyoQC/634S4iEd3rB5sYi6Ve9jduXPQqMSQWh7T5uuF7Xx9 NtaDzlJJbytBpYUei4Q== X-Proofpoint-ORIG-GUID: 6e-KQQ4ACcP5W5_N-cWR4m9KWPZnduPg X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-05-07_02,2026-05-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 lowpriorityscore=0 adultscore=0 suspectscore=0 bulkscore=0 malwarescore=0 priorityscore=1501 clxscore=1015 phishscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2605070232 Extend the qcm2290 CAMSS binding to describe CAMSS as a simple bus by allowing child ISP nodes. Add the required address and size cells, as well as ranges, and validate ISP subnodes against the existing qcom,qcm2290-camss-ope schema. On qcm2290 the OPE (Offline Processing Engine) is a memory-to-memory ISP (Image Signal Processor). The address-cells for the CAMSS bus is <2> (64-bit) as related DMA/IOMMUs offer 36-bit addressing support. Signed-off-by: Loic Poulain --- .../devicetree/bindings/media/qcom,qcm2290-camss.yaml | 13 +++++++++= ++++ 1 file changed, 13 insertions(+) diff --git a/Documentation/devicetree/bindings/media/qcom,qcm2290-camss.yam= l b/Documentation/devicetree/bindings/media/qcom,qcm2290-camss.yaml index 391d0f6f67ef5fdfea31dd3683477561516b1556..e70f4cd1348b8065ee9f0e44481= 85cfd8a8fb7de 100644 --- a/Documentation/devicetree/bindings/media/qcom,qcm2290-camss.yaml +++ b/Documentation/devicetree/bindings/media/qcom,qcm2290-camss.yaml @@ -52,6 +52,14 @@ properties: - const: vfe1 - const: vfe1_cphy_rx =20 + "#address-cells": + const: 2 + + "#size-cells": + const: 2 + + ranges: true + interrupts: maxItems: 8 =20 @@ -117,6 +125,11 @@ properties: required: - data-lanes =20 +patternProperties: + "^isp@[0-9a-f]+$": + $ref: /schemas/media/qcom,qcm2290-camss-ope.yaml + unevaluatedProperties: false + required: - compatible - reg --=20 2.34.1 From nobody Fri Jun 12 14:18:25 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 AD3093D8900 for ; Thu, 7 May 2026 22:50:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194241; cv=none; b=ftDkNIlVitFjvxu31xZyzAe+iktXos78py4nPpRbibFIZ6Xc5uyjtMBokEAFQRiYnxiwjoo9JZzx6oSNipkEOMxc2TSh8RkMOz7PQbRt/Hz6/YZfOXo3XwluXunYdcP9t4MV2jgD6lT2mqQgPXbKQFvqF5xUFeA7sQZio73kU9A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194241; c=relaxed/simple; bh=to/mt8DVhWYg+PxpdqvrCs2worc7HH9azPMfci+8vno=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BDpG7+73N7+W5/nQVDyTcqd3L866kFQhyi7Q30yCulzOV+uaTKj3BCysyvuG63DdJrz4KgAGgunhppgHWM5eZ7wsfxe7dCpA2rD/2XkAY6QKynH4SWWen77TBBCKWImzhTFs3L16D17mK3ceMB/hYVd2dgPU1pVaxo/+DpVhgoE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=JMfRawXS; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=f4+pxWvd; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="JMfRawXS"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="f4+pxWvd" Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 647J7xlM2532079 for ; Thu, 7 May 2026 22:50:39 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= niYYIC3IDYsrggvEJkZ+xh9PaeYuDpO3NXqcH2ayGgo=; b=JMfRawXSv9QljR4f bqyCyWotnAiHLkD+GdZPIG1ly1Ti7cPUFD/VSa609y+Bka8FRxLZFJDXdQkXRa+l ivyZd/zWh3at6druFCXLg97FZNgzE01ge5JmgbXKJvsY6++CmYZVZJwmQOoWqw1B 32e1e840D3buKyhKiEDzJ9CgafHXAyKmY2NB4rpUQud7KKtXkNhJu1LQ/69o4sAi 4J33dqFqfZwriuHLmVq0AM/FsHveHYuxFg7eHWKYkhGaUQgW0w1b6hXojgs0bF2W 57yZ3CipxukRrIlbCoUg99MWW1IomkQ9OEH6AuHcJs0pDyLTmZyH2mO5mEDRwt2D fU4NoQ== Received: from mail-vs1-f71.google.com (mail-vs1-f71.google.com [209.85.217.71]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4e10m9rm3x-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 07 May 2026 22:50:39 +0000 (GMT) Received: by mail-vs1-f71.google.com with SMTP id ada2fe7eead31-6312aa1d7adso1198724137.0 for ; Thu, 07 May 2026 15:50:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1778194238; x=1778799038; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=niYYIC3IDYsrggvEJkZ+xh9PaeYuDpO3NXqcH2ayGgo=; b=f4+pxWvd2NNpTzGM92AnI5MAEmrRth+n+4fOflfARGtzLo6QSmNmlF6HStLu1g6nYq rsRibi/g6dRG79qsPJWpTNPS5xD160RZmu0I9ajVU9m4JnMTNLt/Ps+73E/QBsXD0ErJ QlIYgkq7KvUcMHDRh7dO6avXCFxcAJ5hTq7j9EvFCiUGm/6sc1mPqCsulQEXQEONfh/8 BQjMmvaOVxtjAQo2BRCoMvd7lYRe+7O2KQyxGc5wxqNKcNjQVToh7AgBwqZjoQ36dkmA vqExyQd8zZS9RuSXqxas1lBYr9ux054mzpi1vQ1nQesp14DBVmC70TKGIkr66jS78Iuf 6h2Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778194238; x=1778799038; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=niYYIC3IDYsrggvEJkZ+xh9PaeYuDpO3NXqcH2ayGgo=; b=ijyRctdRjWWf0EMilHBHk6OPwjKwch8TGtDmoa4N9c0q2G10/mpsFHhBeVvvy0nR+B dytvq3h731jdK2sm7w9kjKPz1NKS4vcMDND8lz8rASOkI6eSbbsnjSI5zFUqa+/6Xvc+ cTX5QBbuR7cCyFYSOQF8Za8G9L5ZgjWtvQ87KTCCnF1b2F2ZHobJSYqeH81X6dWUs+sl GG06bWEhmfA0oF2gGRMsZw/YJWNvmMwsQPvCBVoaUlCR0Dn90BoFu1XtI2hhFZLssw5T obzFgK794UrjvAY1WzJBPUcslH3Exr7fitu0WFBBX2yCqGrcjpybxI/4IxOqO8j4WaPZ y6xw== X-Forwarded-Encrypted: i=1; AFNElJ9YFC7ArohAqBqh/Mchyoq9vXa3j0jijLFGSNjfNVNy4tA3hKqSUD+WbsdGJ3iXJILcKXoGYIs9u0UhgfM=@vger.kernel.org X-Gm-Message-State: AOJu0Yz7iOfp0Vw3otjQ7CIMfPq2PaTLtYLCUiA8ckYlZjmKGL5L4FWG ZfR/GP4SWrD9RmKatp8owAcHLFGOpilo/EueVJZwfbWxGmMKwa6tsXLIjh6WGcDrOGEZgJvUN85 25p3b0XC8aHz6uou1pAhMXKayL2ZY4qesFCc82z44VPGDMO8PKjQYB8eaotKUQ16SPYE= X-Gm-Gg: AeBDiesuO5SQghHU0i0qgSGievXmSU6p4z2+L0Y0ZMU6BM5UUMK9DIoi+XfD0xp7XqN 5pnVpPWZ35JRPmnK6X1X4z0AJAlvCTU9kWOzLbdCTZL0VJC0XbvCyEfRFwRuT4TgJhNy/s3jAJm Rb5GznHKM+Tv+AHtqdMwaiAwbDV3FmVAqt30NjEW1cMlnnolKLoGnz3T01vQqZf3fItb+NQ5V0Y /PCZKs/2fJ92f347Orb6gR6PqqqA5Jkg3KLV/W94c9FCYj27U6iziHPdhJlan1hTzxv2DH93S5c mRR2pDjfPR2I30UGChoE9bDfmaXEz9T2r5qSvrJQDlsR/M33o0+vHk6V4pl0Pi1yxvaPKu9xZsa 5l860ZPMBoDTFgEC2FDyXILwj98FpftAgc8EaJMfnQ8ZRG1sGySZEReKR2WVb5IhoZxT7lKptxz /EDg1FcPGMAMdum153 X-Received: by 2002:a05:6102:4408:b0:5ff:c5c8:2734 with SMTP id ada2fe7eead31-630f9017661mr5371540137.25.1778194238040; Thu, 07 May 2026 15:50:38 -0700 (PDT) X-Received: by 2002:a05:6102:4408:b0:5ff:c5c8:2734 with SMTP id ada2fe7eead31-630f9017661mr5371528137.25.1778194237657; Thu, 07 May 2026 15:50:37 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:b16a:3475:ec42:bcfa]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bcac4359dbesm102466b.48.2026.05.07.15.50.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 May 2026 15:50:37 -0700 (PDT) From: Loic Poulain Date: Fri, 08 May 2026 00:49:26 +0200 Subject: [PATCH v3 11/15] media: qcom: camss: Populate CAMSS child devices via DT Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260508-camss-isp-ope-v3-11-bb1055274603@oss.qualcomm.com> References: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> In-Reply-To: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> To: Bryan O'Donoghue , Vladimir Zapolskiy , Loic Poulain , Mauro Carvalho Chehab , Kees Cook , "Gustavo A. R. Silva" , Bryan O'Donoghue , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio Cc: linux-media@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devicetree@vger.kernel.org, laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com, johannes.goede@oss.qualcomm.com X-Mailer: b4 0.14.2 X-Proofpoint-GUID: mQScYTp1O2-HNDbrNUrR0VhcvakXWFvd X-Authority-Analysis: v=2.4 cv=VP3tWdPX c=1 sm=1 tr=0 ts=69fd173f cx=c_pps a=P2rfLEam3zuxRRdjJWA2cw==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yOCtJkima9RkubShWh1s:22 a=KKAkSRfTAAAA:8 a=EUspDBNiAAAA:8 a=5bRy6lfvdnCUHtv4pvsA:9 a=QEXdDO2ut3YA:10 a=ODZdjJIeia2B_SHc_B0f:22 a=cvBusfyB2V15izCimMoJ:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTA3MDIzMSBTYWx0ZWRfXydm678beDzvS 6tSIChrtQ3ffpdnbPOoz/S4XQYPtAr+QNed+yYDRYDWY1TtDJJpDi89IQILnR1mMh5S5KSPDBuy C3U4L26T1XAGl3bFa8yq53w6Ddmhu9DoJAX11ZS5fXUbHjdmMqroiESJjPTccar72oFHwZxeL39 sNMWN2cqPoISlnASQmdmcoU90FMO5IPltTigH6h36XOTF1byldyQfWGR8XXNPtRPeETsjswHXoj JfhjNMOWK+2AtIrpd544IHD3nL3UcCriu1DXmwqFGmNPn03+hGZ1BrobsGd582lIH1tXVE0vITL POk7w+upDLpL59Y2w/WuSwmHYLUa2+cYFzIaeEoHnOB+cYWevx9VXK941JQXrQP0s3mQ45V57hW dogaah/NQluXrPbAVMxExS+CbjlZFpUhX++NZgWuKg/N+2SBaPd5wnfgf8v6FZIFe4wauSV5uYc Ww4mZyqYvc2gaHqVf9g== X-Proofpoint-ORIG-GUID: mQScYTp1O2-HNDbrNUrR0VhcvakXWFvd X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-05-07_02,2026-05-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 spamscore=0 bulkscore=0 impostorscore=0 lowpriorityscore=0 malwarescore=0 clxscore=1015 suspectscore=0 phishscore=0 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2605070231 From: Bryan O'Donoghue Use devm_of_platform_populate() so that child nodes declared under the CAMSS device tree node (e.g. OPE) are automatically instantiated as platform devices. This is required now that CAMSS is modelled as a simple-bus and ISP blocks such as OPE are described as child nodes. Signed-off-by: Bryan O'Donoghue Reviewed-by: Loic Poulain --- drivers/media/platform/qcom/camss/camss.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/plat= form/qcom/camss/camss.c index 0ceab12d573ee7521d44b77d23ee563930d6aac3..6d65b1e08e30246389657a0e464= 77d33bb5ac27c 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -4631,6 +4632,8 @@ static int camss_probe(struct platform_device *pdev) if (!camss) return -ENOMEM; =20 + devm_of_platform_populate(dev); + camss->res =3D of_device_get_match_data(dev); =20 atomic_set(&camss->ref_count, 0); --=20 2.34.1 From nobody Fri Jun 12 14:18:25 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 C373F3ACEF7 for ; Thu, 7 May 2026 22:50:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194245; cv=none; b=QGqnOeO7VvJl6BGaVwH7rw+Rf1j6BlCY2WWao1Hp3eV53GBNKLgA9glEXGRMwwy4pwylDoSlhd0/pXqKoX0CXNT3R9SYHbO59qBxzCQ9k/xeSTPzvoT8nx2w+1I3q4e/Yq/7ZjdOdegwm/CAPQiX5RN/GfdujvKnu0DCRyzF458= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194245; c=relaxed/simple; bh=HkTdVxm4w+k0/TVpI0ca5qa4aiZZTdLwg/kSTlh/tJc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=iLCnOrmAkWGlnYp9IbsTnvf6CIur3qa/c9nZCAagMepp6WfXdaWSa87thxOJ83ZophAWqC/WEOS7HzQF+aFSs/joIxxY7k8R7bH+rJsjPwgeNgmwP5+PuUdtdqhH8DEmOYbAI3fuc52W5JYHwtmRsoGwxcg3qwNyu2JlLC0gi28= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=XXoGOZgl; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=C2ZhE1nk; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="XXoGOZgl"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="C2ZhE1nk" Received: from pps.filterd (m0279865.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 647LZMM44069381 for ; Thu, 7 May 2026 22:50:43 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= PzmyzEi/9mP9ktBgplmP+G5vCsx1+ZwiDnCaxaRy2DU=; b=XXoGOZglB4Qa4NtS IJ/KERF7XAEEzfg5VydkPoYxF981Asfr6QicQqQ29VuIYQkz4cwjVg9MeA2DquED mntLMhIpH9ABZvrjTIUEM1dpEWvCO2rmExgBHVpupYiyhL/Jq6pKt8Iy/ouMPzPg M/JJ11nM1nTURwnDryoRBCsTY6x95jDC9BUTfI+Ij0rjNGbaWYec7VnJWtTNbLdy 9r3FQBLQZeMPteOvn4dQ1N7QRaC4QqD7gvmALWaTmYxcc2frr6wQJxQGrp3QGpQi QSKAGKE5u7nVHfYNQfT5/3JPjQVE8bzwlNrP59sMBLxOfM4NERW/HUnbWBzXGKZk 8c3kYQ== Received: from mail-vs1-f72.google.com (mail-vs1-f72.google.com [209.85.217.72]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4e12sp05wk-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 07 May 2026 22:50:42 +0000 (GMT) Received: by mail-vs1-f72.google.com with SMTP id ada2fe7eead31-62e59da69d7so1315462137.1 for ; Thu, 07 May 2026 15:50:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1778194242; x=1778799042; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=PzmyzEi/9mP9ktBgplmP+G5vCsx1+ZwiDnCaxaRy2DU=; b=C2ZhE1nkvUwTBk/HVNvDG5r53qTQ6RUxoAB72YmkaAu3HtFpWbtdpHazflaphUH9Dy CedgxfzHcJjcn5BiiRvQ40/dA4xjG2K1xKELpiIi2d/OGdFTK45LTYTJbvmyPTmQWSoe xmD2S3xj6kx7xD+fWrGBQcomXyhGhTfaftjE1LC9kodcNWVV22zEeHGLvgi+pjWhQAVE O7MAwEU453EQZORzkxXh0shHKZqkKm0J4oqExr2xKfJF8c83/NnIkfWRO6nZg2UgvfXZ 6l8XouUApDv00EV+tZKxKEiJIK4HngqLd4XCqIBgV3pSOtzBPk0TD+uw85uDBd54NGex LJRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778194242; x=1778799042; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=PzmyzEi/9mP9ktBgplmP+G5vCsx1+ZwiDnCaxaRy2DU=; b=VEPSlcnPxyJ/kx72r7XzIIiZnUmmhnvSp2U4pTtJIlxF9wwFQYrbSIsHOoVv1r/VNe APx74tc9wO+nzVx298FIm17T27cV+zXdt9DeixH444berFKGQKuY9JeBFs/M0kqQo85y U/caDPtCqxlGj5dybdJaj/Ul58uRj1+P8lU6d7J2mEl8fSGmYXHl70wDWqMHEmVdvwU/ mpF6IbgOVmME5oFILW/ktugZ6NZQD8f9DhdrW+Buto3I9KPpStXeZ/MWbRVUXhNfdXBC ZstjeZDWzLW55LIvW1/C5jENV1YGDqU8vLxj1l16gdoKSolpetxiRJEwzVB/2GKMY8jH XEXA== X-Forwarded-Encrypted: i=1; AFNElJ/srfwA0js6T0lFO7GBS5deCGAoBsKXGsXSqsgjzbTfHOKQIHGc6a1CLFWV0DwY3Ff/l8njUemP84/9kHw=@vger.kernel.org X-Gm-Message-State: AOJu0YyvzilVB+2/XUxChh9DCuxhlpXJ4g4lOlSNcf2srMLGAylV9T3f FJMJWYXtJACCmxmHZ2LP1ouhCoTIpetHmJVau3zECmNDtfOoDxnatOF0xkobomjrfmgaL96icja A95+c6f6YKZFX6F1R0YlxTnunbZIucegPyPuE5SolYKC7BDx601n0RqjOZc51F2qjv17PfFLFmD g= X-Gm-Gg: AeBDieuh4Iavu+0TdQizHZ/0ADLcv67CFYChu7eqs/iDEtYlw198xCy7Ag+dfARI9LG kbQNbbPWsILYJWioA/FbtlAWmZAdpIRYve70vqWq5tRAG8eStC93H5cheAc1dmhD04N5X/n6+rO BqT+iW5dWxWQuzOIAjy9me0LTSj/iKhLY4Qs6bIwQ0Cle/E/F8XSMLs1O3CGi39Up2UcouKwi2G ved9/dcAeMsgcZ7RH5I+P1ZODV85jmuhJ2uaz0PbVErBJ6jPxp7js22kv+hK+TPmQ0srvEdUMCr Rhiwqe++vmjU2YztyWxdI6lXOwp81VecVzrGco14Eh7wKcGy2appjJN2oUOqXTTjW70LH9fgn0P ZTYt0uxmn0uRsmmnDEnoA69jLhDSVx1V9dRxJJHTsQcq+DgiSCWPrEhNHDBWhZhTVBV8dry3nw7 Z5K2N6uL/S7nHxmOfn X-Received: by 2002:a05:6102:5a96:b0:611:61d3:819c with SMTP id ada2fe7eead31-630f8ee055dmr6123860137.10.1778194241582; Thu, 07 May 2026 15:50:41 -0700 (PDT) X-Received: by 2002:a05:6102:5a96:b0:611:61d3:819c with SMTP id ada2fe7eead31-630f8ee055dmr6123850137.10.1778194241060; Thu, 07 May 2026 15:50:41 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:b16a:3475:ec42:bcfa]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bcac4359dbesm102466b.48.2026.05.07.15.50.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 May 2026 15:50:39 -0700 (PDT) From: Loic Poulain Date: Fri, 08 May 2026 00:49:27 +0200 Subject: [PATCH v3 12/15] media: uapi: Add CAMSS ISP configuration definition Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260508-camss-isp-ope-v3-12-bb1055274603@oss.qualcomm.com> References: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> In-Reply-To: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> To: Bryan O'Donoghue , Vladimir Zapolskiy , Loic Poulain , Mauro Carvalho Chehab , Kees Cook , "Gustavo A. R. Silva" , Bryan O'Donoghue , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio Cc: linux-media@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devicetree@vger.kernel.org, laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com, johannes.goede@oss.qualcomm.com X-Mailer: b4 0.14.2 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTA3MDIzMSBTYWx0ZWRfX/BvT+AFH1Mkr M8/bqXRVEQOzNA2jNn0194NNfbUmOGcs1qhsiTwHpdMCJ5KzMFcLX8i+uaTOeraO15LSIIMW0NP atGjmhrzYMzclJht0IVT/TPc+ioMZ1RqNxx/3WwRVXCsacg5eq3wZEGEEPXdf4nxj1ic/oie6CC ii39nNhYQd16rRNEheCl7qyvg+0KJuTCQnSuEIPZpX1lMQ8tt4S090pn2b6OHEF1Z7iBrYI/wsq oSze3dUSMrJ6hWUP/UQbLFHThurw9+gmabI79vkANlUEvgG87RZcesLMRH1NgJpu/RnqRXMsj5N Ft1R+WF+IsZZNeu4rruYme7/MVBhHkhvf8pu3AZs3sjZYvVRZS0swoQ3UsnRsOvUlPiKHg7OGxW XjQLAm4nrwGFTpnFR4pDiMHL1cQ2qkz7OMVOmFnVCH92a9yrF+Mp4BW6c8cdqewBDDnr2SY25K+ YFt30uCWQJYuRPQ93OA== X-Proofpoint-ORIG-GUID: MXue2gJIB1ttAvu38ValN8ezyt9j1bla X-Authority-Analysis: v=2.4 cv=Wu4b99fv c=1 sm=1 tr=0 ts=69fd1742 cx=c_pps a=DUEm7b3gzWu7BqY5nP7+9g==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=Um2Pa8k9VHT-vaBCBUpS:22 a=EUspDBNiAAAA:8 a=GU9a0yZhNO0hLPa97fIA:9 a=QEXdDO2ut3YA:10 a=-aSRE8QhW-JAV6biHavz:22 X-Proofpoint-GUID: MXue2gJIB1ttAvu38ValN8ezyt9j1bla X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-05-07_02,2026-05-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 malwarescore=0 priorityscore=1501 suspectscore=0 lowpriorityscore=0 bulkscore=0 spamscore=0 impostorscore=0 phishscore=0 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2605070231 Add the uapi header camss-config.h defining the ISP parameter structures used by the CAMSS Offline Processing Engine (OPE) driver. This includes structures for white balance, chroma enhancement and color correction configuration. Signed-off-by: Loic Poulain --- include/uapi/linux/camss-config.h | 115 ++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 115 insertions(+) diff --git a/include/uapi/linux/camss-config.h b/include/uapi/linux/camss-c= onfig.h new file mode 100644 index 0000000000000000000000000000000000000000..665406969e66927e8bce83afaa9= a3aae53ba2803 --- /dev/null +++ b/include/uapi/linux/camss-config.h @@ -0,0 +1,115 @@ +/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ +/* + * Qualcomm CAMSS ISP parameters UAPI + * + * Uses the generic V4L2 extensible ISP parameters buffer format defined in + * . + * + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _UAPI_LINUX_CAMSS_CONFIG_H +#define _UAPI_LINUX_CAMSS_CONFIG_H + +#include +#include +/** + * enum camss_params_block_type - CAMSS ISP parameter block identifiers + * + * Each value identifies one ISP processing block. The value is placed in + * the @type field of &struct v4l2_isp_params_block_header. + */ +enum camss_params_block_type { + CAMSS_PARAMS_WB_GAIN =3D 1, + CAMSS_PARAMS_CHROMA_ENHAN =3D 2, + CAMSS_PARAMS_COLOR_CORRECT =3D 3, + CAMSS_PARAMS_MAX, +}; + +/** + * struct camss_params_wb_gain - White Balance gains + * + * @header: generic block header; @header.type =3D CAMSS_PARAMS_WB_GAIN + * @g_gain: green channel gain (15uQ10) + * @b_gain: blue channel gain (15uQ10) + * @r_gain: red channel gain (15uQ10) + */ +struct camss_params_wb_gain { + struct v4l2_isp_params_block_header header; + __u16 g_gain; + __u16 b_gain; + __u16 r_gain; + __u16 _pad; +} __aligned(8); + +/** + * struct camss_params_chroma_enhan - RGB to YUV colour matrix + * + * Implements the CLC_CHROMA_ENHAN pipeline module. All coefficients are + * signed 12-bit fixed-point Q3.8 (range roughly -8.0 to +7.996). + * + * Luma (Y) row of the matrix: + * @luma_v0: R-to-Y coefficient (12sQ8, e.g. 0x04d =3D 0.299) + * @luma_v1: G-to-Y coefficient (12sQ8, e.g. 0x096 =3D 0.587) + * @luma_v2: B-to-Y coefficient (12sQ8, e.g. 0x01d =3D 0.114) + * @luma_k: Y output offset (9s, 0 =3D no offset) + * + * Chroma (Cb) row: + * @coeff_ap: Cb positive coefficient (12sQ8, e.g. 0x0e6 =3D 0.886) + * @coeff_am: Cb negative coefficient (12sQ8, e.g. 0xfb3 =3D -0.338) + * @kcb: Cb output offset (11s, 128 =3D +128) + * + * Chroma (Cr) row: + * @coeff_cp: Cr positive coefficient (12sQ8, e.g. 0x0b3 =3D 0.701) + * @coeff_cm: Cr negative coefficient (12sQ8, e.g. 0xfe3 =3D -0.114) + * @coeff_dp: Cr positive coefficient (12sQ8) + * @coeff_dm: Cr negative coefficient (12sQ8) + * @kcr: Cr output offset (11s, 128 =3D +128) + * + * @header: generic block header; @header.type =3D CAMSS_PARAMS_CHROMA_ENH= AN + */ +struct camss_params_chroma_enhan { + struct v4l2_isp_params_block_header header; + __u16 luma_v0; + __u16 luma_v1; + __u16 luma_v2; + __u16 luma_k; + __u16 coeff_ap; + __u16 coeff_am; + __u16 coeff_cp; + __u16 coeff_cm; + __u16 coeff_dp; + __u16 coeff_dm; + __u16 kcb; + __u16 kcr; +} __aligned(8); + +/** + * struct camss_params_color_correct - colour correction matrix + * + * signed 12-bit fixed-point (Qm) + * + * Out_ch0 (g) =3D A0*G+B0*B+C0*R + K0 + * Out_ch1 (b) =3D A1*G+B1*B+C1*R + K1 + * Out_ch2 (r) =3D A2*G+B2*B+C2*R + K2 + * + * m =3D 0x0 - Coefficients are signed 12sQ7 numbers + * m =3D 0x1 - Coefficients are signed 12sQ8 numbers + * m =3D 0x2 - Coefficients are signed 12sQ9 numbers + * m =3D 0x3 - Coefficients are signed 12sQ10 numbers + */ +struct camss_params_color_correct { + struct v4l2_isp_params_block_header header; + __u16 a[3]; + __u16 b[3]; + __u16 c[3]; + __u16 k[3]; + __u16 m; +} __aligned(8); + +#define CAMSS_PARAMS_MAX_PAYLOAD \ + (sizeof(struct camss_params_wb_gain) +\ + sizeof(struct camss_params_chroma_enhan) +\ + sizeof(struct camss_params_color_correct)) + +#endif /* _UAPI_LINUX_CAMSS_CONFIG_H */ --=20 2.34.1 From nobody Fri Jun 12 14:18:25 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 983D33D47DC for ; Thu, 7 May 2026 22:50:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194255; cv=none; b=C3MF81w7H0M21isrWTr51h1Az27M/sz9tNqSZ2ve/Oe6TnXPTkgoa85WFy9e5MXuiDrGY8M7NqhQ6aUO85YPbx2SKHSgxel5D4VuSbth0kNFf2U/W2FF4I8YFt0NW+Yp5dx2mimAVo0qQz0o73OzwfFuUQ7kAzKdzHaCAkVjxsY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194255; c=relaxed/simple; bh=Roey3CNSSDI4jd0q8xOJrIInRkj2PRCPZ1uqQvUJL1k=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=j+42Mtofni6/dPeTAsGz8PWSnm3jiq8Z24OUieo1Vv0ZWMMojK23jr6IY1y9jK6wC5ETBRKBKmyD3q76dnSxCTb8Vf2WHa/kr9leBSPqJMhFg+TLl8EB3p60wGego2Y1CT+uYOTiMMNQt1UMEriQXbW6bkXiaj6FczXty/J2loc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=k9BrwEGA; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=DEYpVfld; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="k9BrwEGA"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="DEYpVfld" Received: from pps.filterd (m0279869.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 647LsJC31173958 for ; Thu, 7 May 2026 22:50:47 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= ziRXEDGZjaNdT4wgv57F1l7Uvhd3K/Kp4qlrbJu598Q=; b=k9BrwEGAVtqjvH2f uLMPXebLOtNJtGUhxkDupz9/Xoca4m+XaGTT7nR3FQueV51jpZzzzxT+Ovw2L8hN WKPeo6d8a3YTSHhwPseRrCvXYDmce3GAh8qnRnduQS9fgqFVf7u+ncn20TIE0Qvr Z31RGplg3hrAajQsSgKgz5sdNLZv4n7KJLoXdhIZXyOuJAO4+uV2oAWirGrCClra KQn+TNh5OAJcNiZ35ansxFeUX2AJUufwq0Z6MDdBYCJWs+rhDGszUP3nTLuC0Bte lP7wHyINVptmwoVmbCxkrgR5oDg1QIOWxPfQETwDLzP4j7BXS0NTlLEzlJlItszB 2sxmnQ== Received: from mail-vk1-f200.google.com (mail-vk1-f200.google.com [209.85.221.200]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4e132h84c6-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 07 May 2026 22:50:47 +0000 (GMT) Received: by mail-vk1-f200.google.com with SMTP id 71dfb90a1353d-57536338b89so2079735e0c.3 for ; Thu, 07 May 2026 15:50:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1778194247; x=1778799047; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=ziRXEDGZjaNdT4wgv57F1l7Uvhd3K/Kp4qlrbJu598Q=; b=DEYpVfldwNOxN6VX8fxuDJhmD+6tgJRLy9CbUiucrwrTcGQbla+z7uAmtbQrjpT7Gc 9T/ceLrk5JSRsCzyIqnOAP214t5NCYKXTE18KH9isHIbaLvNwbTQfjSr3/SFqtW4XkXv OlvT7pgL/yjPPyl8JP82JHIhryoad0s+CyNw4HBBHOnKy+kXr7TSC6/4P5ivGA/C6TK5 vxDxPBvTxzA/R8pl/BkTbB3Qob6oA8prnC3RGACPDLWM5a6GDUmkdPR5VuMqQ7/p+BjV zCZ7JpJPNICnH8gtDy3BfMHkeJusthNFwmv5UP2cdFLAW+yf2NxLNmQYGjaRNxZT96Aa pWbA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778194247; x=1778799047; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=ziRXEDGZjaNdT4wgv57F1l7Uvhd3K/Kp4qlrbJu598Q=; b=OpNy+hjiXskJ8b1uGEWRH3hs9P3wHnEEy83nVvvB1LW9OMPtGlm6Z/1ZlFaGpw5ysH ndQPxM23U3Zl1+sleN6XV0CAeHLWtx4O9jlrXDVhdog3epkMXUw+bbmszXIDeRU85RKx OD/hQArHkMGMEwstEaXCw+bQLFktxvH62UTOAVnUPiAUOCftgtUSVUngEGKCwaQkXYIp OaZjPwkLEYyYq2Xx6ot1ZYsoaTIl3aqVpWqaswwRe2PcJKvrkpyZDdOpVxePD5wQJcHl sdW/q3l/zOrKaKrNaewpzzKWw4pGFAfgV1BCGB1nDWQnFMz+Hre3H5eCjwEjeAxvNetr 2JMQ== X-Forwarded-Encrypted: i=1; AFNElJ8QVUKwgGwwRlp03nc9BqHFOb6BpaBGuwCwPlRP1u8WMMVTDZ2hTShNok9h3RNNajpjerFB9C4BzhAFxNs=@vger.kernel.org X-Gm-Message-State: AOJu0YwcedDqoyZDQ3/SebdpQuG0Z76QGe8prnfJY4au6Td+lWV+GVkj X4MXIKvXrrkyw7RE5Oy+oLYKNbKAsGD9DkVM6vVAljHMKgiAQv5hV/0tuiU4Yy8qTf+k7p7WAkA YogjpMq8wVHvHfV0JHKj7NzldwzZGeYM/NOrAsOa8RMnTeWZEH4bZRVayHbOvMA2FLZs= X-Gm-Gg: AeBDiev/73Ns+t+v/wcpTEecclEbwjscNIt13tbezSDoalBcnFYEmcot3uaLuH4uutw GXi9yJ1H7D6F0L+sTutU3jPolwmrksT105pxi/W4GrAcjD/Q/dJBmI/RiMPh1Zlg4beS87cj64p 4S44V9c3B95Y727EF3vnOMiQaDF619o/aAINPmF5QKNZPPcAGyHp5m6JrEArkTIcvkLwXRquGn6 gDHkyk4HVQqgjERss+WqH1FsfNTa33Eh2dJyCao5VUByhWTch064nisZXvqlzXs8aOAbAgDB7xQ eiUaaBN4q1TXw9FmFCsClMxuKD3n+fcMhcWcWjUaUCpHCYgpPzZ2w0ebXDuGO79Ldift316mcnz v8YJMEYomJIsTZ1tSUj0pO8MbENJl+lbm7rXeLZt1N4hqiPiurbGQ+IZhIGDhlI02OxQ7IjtvM9 n9wVk9XMmD9D0/N1bL X-Received: by 2002:a05:6102:6a94:b0:62f:3ba3:3039 with SMTP id ada2fe7eead31-630f8c252cemr5481580137.0.1778194245139; Thu, 07 May 2026 15:50:45 -0700 (PDT) X-Received: by 2002:a05:6102:6a94:b0:62f:3ba3:3039 with SMTP id ada2fe7eead31-630f8c252cemr5481564137.0.1778194244172; Thu, 07 May 2026 15:50:44 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:b16a:3475:ec42:bcfa]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bcac4359dbesm102466b.48.2026.05.07.15.50.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 May 2026 15:50:42 -0700 (PDT) From: Loic Poulain Date: Fri, 08 May 2026 00:49:28 +0200 Subject: [PATCH v3 13/15] media: qcom: camss: Add CAMSS Offline Processing Engine driver Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260508-camss-isp-ope-v3-13-bb1055274603@oss.qualcomm.com> References: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> In-Reply-To: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> To: Bryan O'Donoghue , Vladimir Zapolskiy , Loic Poulain , Mauro Carvalho Chehab , Kees Cook , "Gustavo A. R. Silva" , Bryan O'Donoghue , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio Cc: linux-media@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devicetree@vger.kernel.org, laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com, johannes.goede@oss.qualcomm.com X-Mailer: b4 0.14.2 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTA3MDIzMiBTYWx0ZWRfX9Iq98qYWiKwu KGCjGl3KiW3eEGE8HNQj6Gu7YqiSGH+JI8iyEwIf3GlGiFjA5m2OneW7kBWumaCvTpFOo5cM8kE oymyZz0XzxEIkhCvt89KXastJag3uiAF7aKeSxtdaAZGUpM/HPFxzz1axvxGNT8jaHbsmRmNN9n YJd55NmlniB1vuckeqeT3gCeM7ifSmqcghW0RvU/CGa5s8haI0TQ6s8RIG9Nlp+UOZSlC7R4JQN S5MklIgSs+yltNuABnHaQc428t+MBWMbIGfDcPu1ETHK+7pKNcZ0oSkipEJ3zLz/Lyfq5mRbU4k aSyEiKt4c1Q+785iJ7h2qRCFkW350NszNI7bmzopXnhFmtuuj2eeA0/hj8yoPbtuZWn1pSlXzUW uqHmKugRJsNbrOqWNBFVSfJ0kPA7ph+8bSSWswV+MvX1q26zf23gf3jRgVDfFv69rEi7QUaXiuE nXHB/iHkF7QrQGbtnrw== X-Proofpoint-ORIG-GUID: 3eoXEn0E8Fq4X9WjIWIGezcXdItzskwE X-Proofpoint-GUID: 3eoXEn0E8Fq4X9WjIWIGezcXdItzskwE X-Authority-Analysis: v=2.4 cv=McxcfZ/f c=1 sm=1 tr=0 ts=69fd1747 cx=c_pps a=wuOIiItHwq1biOnFUQQHKA==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=_glEPmIy2e8OvE2BGh3C:22 a=EUspDBNiAAAA:8 a=dg9WyN4cMKTUCAbeD44A:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=O8hF6Hzn-FEA:10 a=XD7yVLdPMpWraOa8Un9W:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-05-07_02,2026-05-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 malwarescore=0 suspectscore=0 spamscore=0 bulkscore=0 adultscore=0 priorityscore=1501 lowpriorityscore=0 impostorscore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2605070232 Add a V4L2 mem-to-mem driver for the Qualcomm Offline Processing Engine (OPE). OPE is a memory-to-memory ISP block that converts raw Bayer frames to YUV, performing white balance, demosaic, chroma enhancement, color correction and downscaling. The hardware architecture consists of Fetch Engines and Write Engines, connected through intermediate pipeline modules for pix processing. The driver exposes three video nodes per pipeline instance: - ope_input: Bayer RAW input (V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) - ope_disp_output: YUV output (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) - ope_params: ISP parameters (V4L2_BUF_TYPE_META_OUTPUT) Hardware features: - Stripe-based processing (up to 336 pixels wide per stripe) - White balance (CLC_WB) - Demosaic / Bayer-to-RGB (CLC_DEMO) - RGB-to-YUV conversion (CLC_CHROMA_ENHAN) - Color correction matrix (CLC_CC) - MN downscaler for chroma and luma planes Default configuration values are based on public standards such as BT.601. Processing Model: OPE processes frames in stripes of up to 336 pixels. Therefore, frames must be split into stripes for processing. Each stripe is configured after the previous one has been acquired (double buffered registers). To minimize inter-stripe latency, stripe configurations are generated ahead of time. Signed-off-by: Loic Poulain --- drivers/media/platform/qcom/camss/Kconfig | 18 + drivers/media/platform/qcom/camss/Makefile | 3 + drivers/media/platform/qcom/camss/camss-isp-ope.c | 3025 ++++++++++++++++= ++++ .../media/platform/qcom/camss/camss-isp-pipeline.c | 11 + .../media/platform/qcom/camss/camss-isp-pipeline.h | 2 + 5 files changed, 3059 insertions(+) diff --git a/drivers/media/platform/qcom/camss/Kconfig b/drivers/media/plat= form/qcom/camss/Kconfig index d77482f3f5eadc65856806b9b237d65ea484f267..aae87e109b336a953a25a7b3bc8= ada66b29135ce 100644 --- a/drivers/media/platform/qcom/camss/Kconfig +++ b/drivers/media/platform/qcom/camss/Kconfig @@ -21,3 +21,21 @@ config VIDEO_QCOM_CAMSS_ISP =20 This module is selected automatically by drivers that need it. =20 +config VIDEO_QCOM_CAMSS_OPE + tristate "Qualcomm CAMSS Offline Processing Engine (OPE) driver" + depends on V4L_PLATFORM_DRIVERS + depends on VIDEO_DEV + depends on (ARCH_QCOM && IOMMU_DMA) || COMPILE_TEST + select MEDIA_CONTROLLER + select VIDEO_QCOM_CAMSS_ISP + select V4L2_ISP + select VIDEOBUF2_DMA_CONTIG + select VIDEOBUF2_VMALLOC + help + Enable support for the Qualcomm Offline Processing Engine (OPE). + OPE is a memory-to-memory ISP block that converts raw Bayer frames + to YUV, performing white balance, demosaic, chroma enhancement and + downscaling. Found on QCM2290 and related SoCs. + + To compile this driver as a module, choose M here: the module + will be called qcom-camss-ope. diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/pla= tform/qcom/camss/Makefile index fba6f34b8d9f70ea258f7ae1a293a8d58d866498..9d47e4f5fe6dc8d168d86681373= 2655eb0c547a6 100644 --- a/drivers/media/platform/qcom/camss/Makefile +++ b/drivers/media/platform/qcom/camss/Makefile @@ -37,3 +37,6 @@ qcom-camss-isp-objs :=3D camss-isp-bufq.o \ =20 obj-$(CONFIG_VIDEO_QCOM_CAMSS_ISP) +=3D qcom-camss-isp.o =20 +qcom-camss-ope-objs :=3D camss-isp-ope.o + +obj-$(CONFIG_VIDEO_QCOM_CAMSS_OPE) +=3D qcom-camss-ope.o diff --git a/drivers/media/platform/qcom/camss/camss-isp-ope.c b/drivers/me= dia/platform/qcom/camss/camss-isp-ope.c new file mode 100644 index 0000000000000000000000000000000000000000..1febe3e7417f90dc59deca47a2c= 164b97116fec6 --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-isp-ope.c @@ -0,0 +1,3025 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * camss-ope.c + * + * Qualcomm MSM Camera Subsystem - Offline Processing Engine + * + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/* + * This driver provides driver implementation for the Qualcomm Offline + * Processing Engine (OPE). OPE is a memory-to-memory hardware block + * designed for image processing on a source frame. Typically, the input + * frame originates from the SoC CSI capture path, though not limited to. + * + * The hardware architecture consists of Fetch Engines and Write Engines, + * connected through intermediate pipeline modules: + * [FETCH ENGINES] =3D> [Pipeline Modules] =3D> [WRITE ENGINES] + * + * Current Configuration: + * Fetch Engine: One fetch engine is used for Bayer frame input. + * Write Engines: Two display write engines for Y and UV planes output. + * + * Only a subset of the pipeline modules are enabled: + * CLC_WB: White balance for channel gain configuration + * CLC_DEMO: Demosaic for Bayer to RGB conversion + * CLC_CC: Color Correct, coefficient based RGB correction + * CLC_CHROMA_ENHAN: for RGB to YUV conversion + * CLC_DOWNSCALE*: Downscaling for UV (YUV444 -> YUV422/YUV420) and YUV = planes + * + * Default configuration values are based on public standards such as BT.6= 01. + * + * Processing Model: + * OPE processes frames in stripes of up to 336 pixels. Therefore, frames = must + * be split into stripes for processing. Each stripe is configured after t= he + * previous one has been acquired (double buffered registers). To minimize + * inter-stripe latency, the stripe configurations are generated ahead of = time. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "camss-isp-bufq.h" +#include "camss-isp-pipeline.h" +#include "camss-isp-sched.h" +#include +#include + +#include + +#include "camss-isp-params.h" + +#define OPE_NAME "qcom-camss-ope" + +/* Format descriptor */ +struct ope_fmt { + u32 fourcc; + unsigned int depth; + unsigned int align; + unsigned int num_planes; + u32 mbus_code; +}; + +/* Per-queue format state */ +struct ope_fmt_state { + const struct ope_fmt *fmt; + unsigned int width; + unsigned int height; + struct v4l2_rect crop; + unsigned int bytesperline; + unsigned int sizeimage; + enum v4l2_colorspace colorspace; + enum v4l2_xfer_func xfer_func; + enum v4l2_ycbcr_encoding ycbcr_enc; + enum v4l2_quantization quantization; + unsigned int sequence; + struct v4l2_fract timeperframe; +}; + +/* -------- Register layout -------- */ + +#define OPE_TOP_HW_VERSION 0x000 +#define OPE_TOP_HW_VERSION_STEP GENMASK(15, 0) +#define OPE_TOP_HW_VERSION_REV GENMASK(27, 16) +#define OPE_TOP_HW_VERSION_GEN GENMASK(31, 28) +#define OPE_TOP_RESET_CMD 0x004 +#define OPE_TOP_RESET_CMD_HW BIT(0) +#define OPE_TOP_RESET_CMD_SW BIT(1) +#define OPE_TOP_IRQ_STATUS 0x014 +#define OPE_TOP_IRQ_MASK 0x018 +#define OPE_TOP_IRQ_STATUS_RST_DONE BIT(0) +#define OPE_TOP_IRQ_STATUS_WE BIT(1) +#define OPE_TOP_IRQ_STATUS_FE BIT(2) +#define OPE_TOP_IRQ_STATUS_VIOL BIT(3) +#define OPE_TOP_IRQ_STATUS_IDLE BIT(4) +#define OPE_TOP_IRQ_CLEAR 0x01c +#define OPE_TOP_IRQ_CMD 0x024 +#define OPE_TOP_IRQ_CMD_CLEAR BIT(0) +#define OPE_TOP_VIOLATION_STATUS 0x028 + +/* Fetch engine */ +#define OPE_BUS_RD_INPUT_IF_IRQ_MASK 0x00c +#define OPE_BUS_RD_INPUT_IF_IRQ_CLEAR 0x010 +#define OPE_BUS_RD_INPUT_IF_IRQ_CMD 0x014 +#define OPE_BUS_RD_INPUT_IF_IRQ_CMD_CLEAR BIT(0) +#define OPE_BUS_RD_INPUT_IF_IRQ_STATUS 0x018 +#define OPE_BUS_RD_INPUT_IF_CMD 0x01c +#define OPE_BUS_RD_INPUT_IF_CMD_GO_CMD BIT(0) +#define OPE_BUS_RD_CLIENT_0_CORE_CFG 0x050 +#define OPE_BUS_RD_CLIENT_0_CORE_CFG_EN BIT(0) +#define OPE_BUS_RD_CLIENT_0_CCIF_META_DATA 0x054 +#define OPE_BUS_RD_CLIENT_0_CCIF_MD_PIX_PATTERN GENMASK(7, 2) +#define OPE_BUS_RD_CLIENT_0_ADDR_IMAGE 0x058 +#define OPE_BUS_RD_CLIENT_0_RD_BUFFER_SIZE 0x05c +#define OPE_BUS_RD_CLIENT_0_RD_STRIDE 0x060 +#define OPE_BUS_RD_CLIENT_0_UNPACK_CFG_0 0x064 + +/* Write engines */ +#define OPE_BUS_WR_INPUT_IF_IRQ_MASK_0 0x018 +#define OPE_BUS_WR_INPUT_IF_IRQ_MASK_1 0x01c +#define OPE_BUS_WR_INPUT_IF_IRQ_CLEAR_0 0x020 +#define OPE_BUS_WR_INPUT_IF_IRQ_STATUS_0 0x028 +#define OPE_BUS_WR_INPUT_IF_IRQ_STATUS_0_RUP_DONE BIT(0) +#define OPE_BUS_WR_INPUT_IF_IRQ_STATUS_0_BUF_DONE BIT(8) +#define OPE_BUS_WR_INPUT_IF_IRQ_STATUS_0_CONS_VIOL BIT(28) +#define OPE_BUS_WR_INPUT_IF_IRQ_STATUS_0_VIOL BIT(30) +#define OPE_BUS_WR_INPUT_IF_IRQ_STATUS_0_IMG_SZ_VIOL BIT(31) +#define OPE_BUS_WR_INPUT_IF_IRQ_CMD 0x030 +#define OPE_BUS_WR_INPUT_IF_IRQ_CMD_CLEAR BIT(0) +#define OPE_BUS_WR_VIOLATION_STATUS 0x064 +#define OPE_BUS_WR_IMAGE_SIZE_VIOLATION_STATUS 0x070 +#define OPE_BUS_WR_CLIENT_CFG(c) (0x200 + (c) * 0x100) +#define OPE_BUS_WR_CLIENT_CFG_EN BIT(0) +#define OPE_BUS_WR_CLIENT_CFG_AUTORECOVER BIT(4) +#define OPE_BUS_WR_CLIENT_ADDR_IMAGE(c) (0x204 + (c) * 0x100) +#define OPE_BUS_WR_CLIENT_IMAGE_CFG_0(c) (0x20c + (c) * 0x100) +#define OPE_BUS_WR_CLIENT_IMAGE_CFG_1(c) (0x210 + (c) * 0x100) +#define OPE_BUS_WR_CLIENT_IMAGE_CFG_2(c) (0x214 + (c) * 0x100) +#define OPE_BUS_WR_CLIENT_PACKER_CFG(c) (0x218 + (c) * 0x100) +#define OPE_BUS_WR_CLIENT_MAX 4 + +/* Pipeline modules */ +#define OPE_PP_CLC_WB_GAIN_MODULE_CFG (0x200 + 0x60) +#define OPE_PP_CLC_WB_GAIN_MODULE_CFG_EN BIT(0) +#define OPE_PP_CLC_WB_GAIN_WB_CFG(ch) (0x200 + 0x68 + 4 * (ch)) + +#define OPE_PP_CLC_CC_BASE 0x400 +#define OPE_PP_CLC_CC_MODULE_CFG (OPE_PP_CLC_CC_BASE + 0x60) +#define OPE_PP_CLC_CC_MODULE_CFG_EN BIT(0) +#define OPE_PP_CLC_CC_COEFF_A_CFG_0 (OPE_PP_CLC_CC_BASE + 0x68) +#define OPE_PP_CLC_CC_COEFF_A_CFG_0_A0 GENMASK(11, 0) +#define OPE_PP_CLC_CC_COEFF_A_CFG_0_A1 GENMASK(27, 16) +#define OPE_PP_CLC_CC_COEFF_A_CFG_1 (OPE_PP_CLC_CC_BASE + 0x6c) +#define OPE_PP_CLC_CC_COEFF_A_CFG_1_A2 GENMASK(11, 0) +#define OPE_PP_CLC_CC_COEFF_B_CFG_0 (OPE_PP_CLC_CC_BASE + 0x70) +#define OPE_PP_CLC_CC_COEFF_B_CFG_0_B0 GENMASK(11, 0) +#define OPE_PP_CLC_CC_COEFF_B_CFG_0_B1 GENMASK(27, 16) +#define OPE_PP_CLC_CC_COEFF_B_CFG_1 (OPE_PP_CLC_CC_BASE + 0x74) +#define OPE_PP_CLC_CC_COEFF_B_CFG_1_B2 GENMASK(11, 0) +#define OPE_PP_CLC_CC_COEFF_C_CFG_0 (OPE_PP_CLC_CC_BASE + 0x78) +#define OPE_PP_CLC_CC_COEFF_C_CFG_0_C0 GENMASK(11, 0) +#define OPE_PP_CLC_CC_COEFF_C_CFG_0_C1 GENMASK(27, 16) +#define OPE_PP_CLC_CC_COEFF_C_CFG_1 (OPE_PP_CLC_CC_BASE + 0x7c) +#define OPE_PP_CLC_CC_COEFF_C_CFG_1_C2 GENMASK(11, 0) +#define OPE_PP_CLC_CC_COEFF_K_CFG_0 (OPE_PP_CLC_CC_BASE + 0x80) +#define OPE_PP_CLC_CC_COEFF_K_CFG_0_K0 GENMASK(12, 0) +#define OPE_PP_CLC_CC_COEFF_K_CFG_1 (OPE_PP_CLC_CC_BASE + 0x84) +#define OPE_PP_CLC_CC_COEFF_K_CFG_1_K1 GENMASK(12, 0) +#define OPE_PP_CLC_CC_COEFF_K_CFG_2 (OPE_PP_CLC_CC_BASE + 0x88) +#define OPE_PP_CLC_CC_COEFF_K_CFG_2_K2 GENMASK(12, 0) +#define OPE_PP_CLC_CC_COEFF_M_CFG (OPE_PP_CLC_CC_BASE + 0x8c) +#define OPE_PP_CLC_CC_COEFF_M_CFG_M GENMASK(11, 0) + +#define OPE_PP_CLC_DEMO_MODULE_CFG (0x800 + 0x60) +#define OPE_PP_CLC_DEMO_MODULE_CFG_EN BIT(0) +#define OPE_PP_CLC_DEMO_MODULE_CFG_DYN_G_CLAMP_EN BIT(4) +#define OPE_PP_CLC_DEMO_INTERP_COEFF_CFG (0x800 + 0x68) +#define OPE_PP_CLC_DEMO_INTERP_COEFF_CFG_LAMBDA_G GENMASK(15, 8) +#define OPE_PP_CLC_DEMO_INTERP_COEFF_CFG_LAMBDA_RB GENMASK(7, 0) +#define OPE_PP_CLC_DEMO_INTERP_CLASSIFIER_CFG_0 (0x800 + 0x6c) +#define OPE_PP_CLC_DEMO_INTERP_CLASSIFIER_CFG_0_AK GENMASK(15, 0) +#define OPE_PP_CLC_DEMO_INTERP_CLASSIFIER_CFG_1 (0x800 + 0x70) +#define OPE_PP_CLC_DEMO_INTERP_CLASSIFIER_CFG_1_WK GENMASK(15, 0) + +#define OPE_PP_CLC_DOWNSCALE_MN_DS_C_PRE_BASE 0x1c00 +#define OPE_PP_CLC_DOWNSCALE_MN_DS_Y_DISP_BASE 0x3000 +#define OPE_PP_CLC_DOWNSCALE_MN_DS_C_DISP_BASE 0x3200 +#define OPE_PP_CLC_CROP_RND_CLAMP_Y_DISP_BASE 0x3400 +#define OPE_PP_CLC_CROP_RND_CLAMP_C_DISP_BASE 0x3600 +#define OPE_PP_CLC_CROP_RND_CLAMP_HW_STATUS(base) ((base) + 0x04) +#define OPE_PP_CLC_CROP_RND_CLAMP_HEIGHT_VIOL BIT(2) +#define OPE_PP_CLC_CROP_RND_CLAMP_WIDTH_VIOL BIT(1) +#define OPE_PP_CLC_CROP_RND_CLAMP_MODULE_CFG(base) ((base) + 0x60) +#define OPE_PP_CLC_CROP_RND_CLAMP_EN BIT(0) +#define OPE_PP_CLC_CROP_RND_CLAMP_CROP_EN BIT(9) +#define OPE_PP_CLC_CROP_RND_CLAMP_CROP_LINE_CFG(base) ((base) + 0x68) +#define OPE_PP_CLC_CROP_RND_CLAMP_CROP_PIXEL_CFG(base) ((base) + 0x6c) +#define OPE_PP_CLC_CROP_RND_CLAMP_CROP_FIRST GENMASK(29, 16) +#define OPE_PP_CLC_CROP_RND_CLAMP_CROP_LAST GENMASK(13, 0) +#define OPE_PP_CLC_DOWNSCALE_MN_CFG(ds) ((ds) + 0x60) +#define OPE_PP_CLC_DOWNSCALE_MN_CFG_EN BIT(0) +#define OPE_PP_CLC_DOWNSCALE_MN_DS_CFG(ds) ((ds) + 0x64) +#define OPE_PP_CLC_DOWNSCALE_MN_DS_CFG_H_SCALE_EN BIT(9) +#define OPE_PP_CLC_DOWNSCALE_MN_DS_CFG_V_SCALE_EN BIT(10) +#define OPE_PP_CLC_DOWNSCALE_MN_DS_IMAGE_SIZE_CFG(ds) ((ds) + 0x68) +#define OPE_PP_CLC_DOWNSCALE_MN_DS_MN_H_CFG(ds) ((ds) + 0x6c) +#define OPE_PP_CLC_DOWNSCALE_MN_DS_MN_V_CFG(ds) ((ds) + 0x74) + +#define OPE_PP_CLC_CHROMA_ENHAN_MODULE_CFG (0x1200 + 0x60) +#define OPE_PP_CLC_CHROMA_ENHAN_MODULE_CFG_EN BIT(0) +#define OPE_PP_CLC_CHROMA_ENHAN_LUMA_CFG_0 (0x1200 + 0x68) +#define OPE_PP_CLC_CHROMA_ENHAN_LUMA_CFG_0_V0 GENMASK(11, 0) +#define OPE_PP_CLC_CHROMA_ENHAN_LUMA_CFG_0_V1 GENMASK(27, 16) +#define OPE_PP_CLC_CHROMA_ENHAN_LUMA_CFG_1 (0x1200 + 0x6c) +#define OPE_PP_CLC_CHROMA_ENHAN_LUMA_CFG_1_K GENMASK(31, 23) +#define OPE_PP_CLC_CHROMA_ENHAN_LUMA_CFG_2 (0x1200 + 0x70) +#define OPE_PP_CLC_CHROMA_ENHAN_LUMA_CFG_2_V2 GENMASK(11, 0) +#define OPE_PP_CLC_CHROMA_ENHAN_COEFF_A_CFG (0x1200 + 0x74) +#define OPE_PP_CLC_CHROMA_ENHAN_COEFF_A_CFG_AP GENMASK(11, 0) +#define OPE_PP_CLC_CHROMA_ENHAN_COEFF_A_CFG_AM GENMASK(27, 16) +#define OPE_PP_CLC_CHROMA_ENHAN_COEFF_B_CFG (0x1200 + 0x78) +#define OPE_PP_CLC_CHROMA_ENHAN_COEFF_B_CFG_BP GENMASK(11, 0) +#define OPE_PP_CLC_CHROMA_ENHAN_COEFF_B_CFG_BM GENMASK(27, 16) +#define OPE_PP_CLC_CHROMA_ENHAN_COEFF_C_CFG (0x1200 + 0x7C) +#define OPE_PP_CLC_CHROMA_ENHAN_COEFF_C_CFG_CP GENMASK(11, 0) +#define OPE_PP_CLC_CHROMA_ENHAN_COEFF_C_CFG_CM GENMASK(27, 16) +#define OPE_PP_CLC_CHROMA_ENHAN_COEFF_D_CFG (0x1200 + 0x80) +#define OPE_PP_CLC_CHROMA_ENHAN_COEFF_D_CFG_DP GENMASK(11, 0) +#define OPE_PP_CLC_CHROMA_ENHAN_COEFF_D_CFG_DM GENMASK(27, 16) +#define OPE_PP_CLC_CHROMA_ENHAN_CHROMA_CFG_0 (0x1200 + 0x84) +#define OPE_PP_CLC_CHROMA_ENHAN_CHROMA_CFG_0_KCB GENMASK(31, 21) +#define OPE_PP_CLC_CHROMA_ENHAN_CHROMA_CFG_1 (0x1200 + 0x88) +#define OPE_PP_CLC_CHROMA_ENHAN_CHROMA_CFG_1_KCR GENMASK(31, 21) + +/* -------- OPE-specific constants -------- */ + +#define OPE_STRIPE_MAX_W 336 +#define OPE_STRIPE_MAX_H 8192 +#define OPE_STRIPE_MIN_W 16 +#define OPE_STRIPE_MIN_H OPE_STRIPE_MIN_W +#define OPE_MAX_STRIPE 16 +#define OPE_ALIGN_H 1 +#define OPE_ALIGN_W 1 +#define OPE_MIN_W 24 +#define OPE_MIN_H 16 +#define OPE_MAX_W (OPE_STRIPE_MAX_W * OPE_MAX_STRIPE) +#define OPE_MAX_H OPE_STRIPE_MAX_H +#define OPE_RESET_TIMEOUT_MS 100 +#define DEFAULT_FRAMERATE 60 + +/* Downscaler fixed-point helpers */ +#define Q21(v) (((uint64_t)(v)) << 21) +#define DS_Q21(n, d) ((uint32_t)(((uint64_t)(n) << 21) / (d))) +#define DS_RESOLUTION(in, out) \ + (((out) * 128 <=3D (in)) ? 0x0 : \ + ((out) * 16 <=3D (in)) ? 0x1 : \ + ((out) * 8 <=3D (in)) ? 0x2 : 0x3) +#define DS_OUTPUT_PIX(in, phase_init, phase_step) \ + ((Q21(in) - (phase_init)) / (phase_step)) +#define OPE_WB(n, d) (((n) << 10) / (d)) + +enum ope_downscaler { + OPE_DS_C_PRE, + OPE_DS_C_DISP, + OPE_DS_Y_DISP, + OPE_DS_MAX, +}; + +static const u32 ope_ds_base[OPE_DS_MAX] =3D { + OPE_PP_CLC_DOWNSCALE_MN_DS_C_PRE_BASE, + OPE_PP_CLC_DOWNSCALE_MN_DS_C_DISP_BASE, + OPE_PP_CLC_DOWNSCALE_MN_DS_Y_DISP_BASE, +}; + +enum ope_wr_client { + OPE_WR_CLIENT_VID_Y, + OPE_WR_CLIENT_VID_C, + OPE_WR_CLIENT_DISP_Y, + OPE_WR_CLIENT_DISP_C, + OPE_WR_CLIENT_MAX, +}; + +enum ope_pixel_pattern { + OPE_PIXEL_PATTERN_RGRGRG, + OPE_PIXEL_PATTERN_GRGRGR, + OPE_PIXEL_PATTERN_BGBGBG, + OPE_PIXEL_PATTERN_GBGBGB, + OPE_PIXEL_PATTERN_YCBYCR, + OPE_PIXEL_PATTERN_YCRYCB, + OPE_PIXEL_PATTERN_CBYCRY, + OPE_PIXEL_PATTERN_CRYCBY, +}; + +enum ope_stripe_location { + OPE_STRIPE_LOCATION_FULL, + OPE_STRIPE_LOCATION_LEFT, + OPE_STRIPE_LOCATION_RIGHT, + OPE_STRIPE_LOCATION_MIDDLE, +}; + +enum ope_unpacker_format { + OPE_UNPACKER_FMT_PLAIN_8 =3D 1, + OPE_UNPACKER_FMT_PLAIN_16_10BPP =3D 2, + OPE_UNPACKER_FMT_MIPI_10 =3D 13, +}; + +enum ope_packer_format { + OPE_PACKER_FMT_PLAIN_8 =3D 1, + OPE_PACKER_FMT_PLAIN_8_ODD_EVEN =3D 2, + OPE_PACKER_FMT_MIPI_10 =3D 12, +}; + +struct ope_hw_fmt { + u32 fourcc; + enum ope_pixel_pattern pattern; + enum ope_unpacker_format unpacker; + enum ope_packer_format packer; +}; + +static const struct ope_hw_fmt ope_hw_fmts[] =3D { + { V4L2_PIX_FMT_SBGGR10P, OPE_PIXEL_PATTERN_BGBGBG, + OPE_UNPACKER_FMT_MIPI_10, OPE_PACKER_FMT_MIPI_10 }, + { V4L2_PIX_FMT_SGBRG10P, OPE_PIXEL_PATTERN_GBGBGB, + OPE_UNPACKER_FMT_MIPI_10, OPE_PACKER_FMT_MIPI_10 }, + { V4L2_PIX_FMT_SGRBG10P, OPE_PIXEL_PATTERN_GRGRGR, + OPE_UNPACKER_FMT_MIPI_10, OPE_PACKER_FMT_MIPI_10 }, + { V4L2_PIX_FMT_SRGGB10P, OPE_PIXEL_PATTERN_RGRGRG, + OPE_UNPACKER_FMT_MIPI_10, OPE_PACKER_FMT_MIPI_10 }, + { V4L2_PIX_FMT_SRGGB8, OPE_PIXEL_PATTERN_RGRGRG, + OPE_UNPACKER_FMT_PLAIN_8, OPE_PACKER_FMT_PLAIN_8 }, + { V4L2_PIX_FMT_SBGGR8, OPE_PIXEL_PATTERN_BGBGBG, + OPE_UNPACKER_FMT_PLAIN_8, OPE_PACKER_FMT_PLAIN_8 }, + { V4L2_PIX_FMT_SGBRG8, OPE_PIXEL_PATTERN_GBGBGB, + OPE_UNPACKER_FMT_PLAIN_8, OPE_PACKER_FMT_PLAIN_8 }, + { V4L2_PIX_FMT_SGRBG8, OPE_PIXEL_PATTERN_GRGRGR, + OPE_UNPACKER_FMT_PLAIN_8, OPE_PACKER_FMT_PLAIN_8 }, + { V4L2_PIX_FMT_NV24, OPE_PIXEL_PATTERN_YCBYCR, + OPE_UNPACKER_FMT_PLAIN_8, OPE_PACKER_FMT_PLAIN_8 }, + { V4L2_PIX_FMT_NV42, OPE_PIXEL_PATTERN_YCRYCB, + OPE_UNPACKER_FMT_PLAIN_8, OPE_PACKER_FMT_PLAIN_8_ODD_EVEN }, + { V4L2_PIX_FMT_NV16, OPE_PIXEL_PATTERN_CBYCRY, + OPE_UNPACKER_FMT_PLAIN_8, OPE_PACKER_FMT_PLAIN_8 }, + { V4L2_PIX_FMT_NV61, OPE_PIXEL_PATTERN_CBYCRY, + OPE_UNPACKER_FMT_PLAIN_8, OPE_PACKER_FMT_PLAIN_8_ODD_EVEN }, + { V4L2_PIX_FMT_NV12, OPE_PIXEL_PATTERN_CBYCRY, + OPE_UNPACKER_FMT_PLAIN_8, OPE_PACKER_FMT_PLAIN_8 }, + { V4L2_PIX_FMT_NV21, OPE_PIXEL_PATTERN_CBYCRY, + OPE_UNPACKER_FMT_PLAIN_8, OPE_PACKER_FMT_PLAIN_8_ODD_EVEN }, + { V4L2_PIX_FMT_GREY, OPE_PIXEL_PATTERN_RGRGRG, + OPE_UNPACKER_FMT_PLAIN_8, OPE_PACKER_FMT_PLAIN_8 }, +}; + +static const struct ope_hw_fmt *ope_find_hw_fmt(u32 fourcc) +{ + unsigned int i; + + for (i =3D 0; i < ARRAY_SIZE(ope_hw_fmts); i++) + if (ope_hw_fmts[i].fourcc =3D=3D fourcc) + return &ope_hw_fmts[i]; + + return NULL; +} + +static const struct ope_fmt ope_input_fmts[] =3D { + { V4L2_PIX_FMT_SBGGR10P, 10, 2, 1, MEDIA_BUS_FMT_SBGGR10_1X10 }, + { V4L2_PIX_FMT_SGBRG10P, 10, 2, 1, MEDIA_BUS_FMT_SGBRG10_1X10 }, + { V4L2_PIX_FMT_SGRBG10P, 10, 2, 1, MEDIA_BUS_FMT_SGRBG10_1X10 }, + { V4L2_PIX_FMT_SRGGB10P, 10, 2, 1, MEDIA_BUS_FMT_SRGGB10_1X10 }, + { V4L2_PIX_FMT_SRGGB8, 8, 0, 1, MEDIA_BUS_FMT_SRGGB8_1X8 }, + { V4L2_PIX_FMT_SBGGR8, 8, 0, 1, MEDIA_BUS_FMT_SBGGR8_1X8 }, + { V4L2_PIX_FMT_SGBRG8, 8, 0, 1, MEDIA_BUS_FMT_SGBRG8_1X8 }, + { V4L2_PIX_FMT_SGRBG8, 8, 0, 1, MEDIA_BUS_FMT_SGRBG8_1X8 }, +}; + +static const struct ope_fmt ope_output_fmts[] =3D { + { V4L2_PIX_FMT_NV24, 24, 0, 1, MEDIA_BUS_FMT_YUV8_1X24 }, + { V4L2_PIX_FMT_NV42, 24, 0, 1, MEDIA_BUS_FMT_YUV8_1X24 }, + { V4L2_PIX_FMT_NV16, 16, 1, 1, MEDIA_BUS_FMT_YUYV8_2X8 }, + { V4L2_PIX_FMT_NV61, 16, 1, 1, MEDIA_BUS_FMT_YUYV8_2X8 }, + { V4L2_PIX_FMT_NV12, 12, 1, 1, MEDIA_BUS_FMT_YUYV8_1_5X8 }, + { V4L2_PIX_FMT_NV21, 12, 1, 1, MEDIA_BUS_FMT_YUYV8_1_5X8 }, + { V4L2_PIX_FMT_GREY, 8, 0, 1, MEDIA_BUS_FMT_Y8_1X8 }, +}; + +struct ope_dsc_config { + u32 input_width; + u32 input_height; + u32 output_width; + u32 output_height; + u32 phase_step_h; + u32 phase_step_v; + u32 crop_last_pixel; + u32 crop_last_line; +}; + +struct ope_stripe { + struct { + dma_addr_t addr; + u32 width; + u32 height; + u32 stride; + enum ope_stripe_location location; + enum ope_pixel_pattern pattern; + enum ope_unpacker_format format; + } src; + struct { + dma_addr_t addr; + u32 width; + u32 height; + u32 stride; + u32 x_init; + enum ope_packer_format format; + bool enabled; + } dst[OPE_WR_CLIENT_MAX]; + struct ope_dsc_config dsc[OPE_DS_MAX]; +}; + +/* OPE tuning parameter state */ + +/* Demosaic (CLC_DEMO) coefficients =E2=80=94 internal only, not user-conf= igurable. */ +#define CAMSS_PARAMS_INTERNAL (-1) + +struct ope_params_demo { + struct v4l2_isp_params_block_header header; + u8 lambda_rb; + u8 lambda_g; + u16 a_k; + u16 w_k; + u16 _pad; +}; + +/* OPE tuning parameter state */ +struct ope_config { + struct camss_params_wb_gain wb_gain; + struct camss_params_chroma_enhan chroma_enhan; + struct camss_params_color_correct color_correct; + struct ope_params_demo demo; +}; + +enum ope_entity { + OPE_ENTITY_FRAME_IN, + OPE_ENTITY_PARAMS, + OPE_ENTITY_PROC, + OPE_ENTITY_DISP, + OPE_ENTITY_DISP_OUT, + OPE_ENTITY_COUNT +}; + +enum ope_queue_idx { + OPE_QUEUE_FRAME_IN, + OPE_QUEUE_DISP_OUT, + OPE_QUEUE_PARAMS, + OPE_QUEUE_COUNT +}; + +/* per-context state */ +struct ope_ctx { + struct camss_isp_bufq *bufq; + struct camss_isp_job job; + struct ope_dev *ope; + struct mutex vbq_lock; + struct vb2_queue vqs[OPE_QUEUE_COUNT]; + + unsigned int framerate; + struct ope_fmt_state fmt_in; + struct ope_fmt_state fmt_out; + u32 proc_mbus_code; + struct v4l2_rect disp_compose; + + struct list_head list; + bool started; + + struct ope_config config; + u8 current_stripe; + struct ope_stripe stripe[OPE_MAX_STRIPE]; +}; + +/* Per OPE device state */ +struct ope_dev { + struct device *dev; + struct v4l2_device v4l2_dev; + struct media_device mdev; + struct camss_isp_pipeline *pipeline; + struct mutex mutex; + struct camss_isp_sched sched; + + struct icc_path *icc_data; + struct icc_path *icc_config; + + void __iomem *base; + void __iomem *base_rd; + void __iomem *base_wr; + void __iomem *base_pp; + + struct completion reset_complete; + + struct list_head ctx_list; + struct ope_ctx *shared_ctx; + unsigned int open_count; + + /* Currently active hardware context (set at job start) */ + struct ope_ctx *hw_ctx; +}; + +/* -------- Register accessors -------- */ + +static inline u32 ope_read(struct ope_dev *ope, u32 reg) +{ + return readl(ope->base + reg); +} + +static inline void ope_write(struct ope_dev *ope, u32 reg, u32 val) +{ + writel(val, ope->base + reg); +} + +static inline void ope_write_wr(struct ope_dev *ope, u32 reg, u32 val) +{ + writel_relaxed(val, ope->base_wr + reg); +} + +static inline u32 ope_read_wr(struct ope_dev *ope, u32 reg) +{ + return readl_relaxed(ope->base_wr + reg); +} + +static inline void ope_write_rd(struct ope_dev *ope, u32 reg, u32 val) +{ + writel_relaxed(val, ope->base_rd + reg); +} + +static inline void ope_write_pp(struct ope_dev *ope, u32 reg, u32 val) +{ + writel_relaxed(val, ope->base_pp + reg); +} + +static inline void ope_start(struct ope_dev *ope) +{ + wmb(); /* ensure all register writes are visible before GO_CMD */ + ope_write_rd(ope, OPE_BUS_RD_INPUT_IF_CMD, OPE_BUS_RD_INPUT_IF_CMD_GO_CMD= ); +} + +/* -------- Stripe helpers -------- */ + +static inline enum ope_stripe_location ope_stripe_location(unsigned int id= x, unsigned int count) +{ + if (count =3D=3D 1) + return OPE_STRIPE_LOCATION_FULL; + if (idx =3D=3D 0) + return OPE_STRIPE_LOCATION_LEFT; + if (idx =3D=3D count - 1) + return OPE_STRIPE_LOCATION_RIGHT; + + return OPE_STRIPE_LOCATION_MIDDLE; +} + +static inline bool ope_stripe_is_last(const struct ope_stripe *s) +{ + return s && (s->src.location =3D=3D OPE_STRIPE_LOCATION_RIGHT || + s->src.location =3D=3D OPE_STRIPE_LOCATION_FULL); +} + +static inline struct ope_stripe *ope_current_stripe(struct ope_ctx *ctx) +{ + if (ctx->current_stripe >=3D OPE_MAX_STRIPE) + return NULL; + + return &ctx->stripe[ctx->current_stripe]; +} + +static inline unsigned int ope_stripe_index(struct ope_ctx *ctx, + const struct ope_stripe *stripe) +{ + return stripe - &ctx->stripe[0]; +} + +static inline struct ope_stripe *ope_prev_stripe(struct ope_ctx *ctx, + struct ope_stripe *stripe) +{ + unsigned int idx =3D ope_stripe_index(ctx, stripe); + + return idx ? &ctx->stripe[idx - 1] : NULL; +} + +static void ope_gen_stripe_chroma_dsc(struct ope_ctx *ctx, + struct ope_stripe *stripe) +{ + struct ope_dsc_config *dsc =3D &stripe->dsc[OPE_DS_C_PRE]; + u32 dst_fourcc =3D ctx->fmt_out.fmt->fourcc; + + dsc->input_width =3D stripe->src.width; + dsc->input_height =3D stripe->src.height; + + switch (dst_fourcc) { + case V4L2_PIX_FMT_NV61: + case V4L2_PIX_FMT_NV16: + dsc->output_width =3D dsc->input_width / 2; + dsc->output_height =3D dsc->input_height; + break; + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + dsc->output_width =3D dsc->input_width / 2; + dsc->output_height =3D dsc->input_height / 2; + break; + default: + dsc->output_width =3D dsc->input_width; + dsc->output_height =3D dsc->input_height; + } + + dsc->phase_step_h =3D DS_Q21(dsc->input_width, dsc->output_width); + dsc->phase_step_v =3D DS_Q21(dsc->input_height, dsc->output_height); +} + +static void ope_gen_stripe_dsc(struct ope_ctx *ctx, struct ope_stripe *str= ipe, + u32 h_scale, u32 v_scale) +{ + struct ope_dsc_config *dsc_c =3D &stripe->dsc[OPE_DS_C_DISP]; + struct ope_dsc_config *dsc_y =3D &stripe->dsc[OPE_DS_Y_DISP]; + unsigned int sw =3D stripe->src.width; + unsigned int sw_c =3D stripe->dsc[OPE_DS_C_PRE].output_width; + + dsc_c->phase_step_h =3D dsc_y->phase_step_h =3D h_scale; + dsc_c->phase_step_v =3D dsc_y->phase_step_v =3D v_scale; + + dsc_c->input_width =3D stripe->dsc[OPE_DS_C_PRE].output_width; + dsc_c->input_height =3D stripe->dsc[OPE_DS_C_PRE].output_height; + dsc_y->input_width =3D stripe->src.width; + dsc_y->input_height =3D stripe->src.height; + + /* + * WE width/height =3D DS_OUTPUT_PIX (floor). The scaler may deliver + * floor or floor+1 pixels/lines; CROP_RND_CLAMP clips the output to + * exactly floor so the WE always receives the expected count. + */ + dsc_y->output_width =3D DS_OUTPUT_PIX(sw, 0, h_scale); + dsc_y->output_height =3D DS_OUTPUT_PIX(stripe->src.height, 0, v_scale); + dsc_c->output_width =3D DS_OUTPUT_PIX(sw_c, 0, h_scale); + dsc_c->output_height =3D DS_OUTPUT_PIX(stripe->dsc[OPE_DS_C_PRE].output_h= eight, 0, v_scale); + + dsc_y->crop_last_pixel =3D dsc_y->output_width - 1; + dsc_y->crop_last_line =3D dsc_y->output_height - 1; + dsc_c->crop_last_pixel =3D dsc_c->output_width - 1; + dsc_c->crop_last_line =3D dsc_c->output_height - 1; +} + +static void ope_gen_stripe_yuv_dst(struct ope_ctx *ctx, struct ope_stripe = *stripe, dma_addr_t dst) +{ + const struct ope_fmt_state *fo =3D &ctx->fmt_out; + unsigned int img_h =3D fo->height; + unsigned int bpl =3D fo->bytesperline; /* Y-plane row stride in bytes */ + const struct ope_hw_fmt *hw =3D ope_find_hw_fmt(fo->fmt->fourcc); + struct ope_stripe *prev =3D ope_prev_stripe(ctx, stripe); + const struct v4l2_rect *compose =3D &ctx->disp_compose; + dma_addr_t y_base =3D dst + compose->top * bpl; + dma_addr_t c_base; + u32 x_init =3D compose->left; + u32 c_x_init; + + switch (fo->fmt->fourcc) { + case V4L2_PIX_FMT_NV24: + case V4L2_PIX_FMT_NV42: + /* YUV444: C plane starts after Y plane; full-height, 2 bytes/luma-col */ + c_base =3D dst + bpl * img_h + compose->top * bpl * 2; + c_x_init =3D compose->left * 2; + break; + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV61: + /* YUV422: C plane =3D Y plane size; full-height, 1 byte/luma-col */ + c_base =3D dst + bpl * img_h + compose->top * bpl; + c_x_init =3D compose->left; + break; + default: + /* YUV420 (NV12/NV21): C plane =3D Y/2 height, 1 byte/luma-col */ + c_base =3D dst + bpl * img_h + (compose->top / 2) * bpl; + c_x_init =3D compose->left; + break; + } + + stripe->dst[OPE_WR_CLIENT_DISP_Y].enabled =3D true; + stripe->dst[OPE_WR_CLIENT_DISP_C].enabled =3D true; + + /* Y plane */ + if (prev) + x_init =3D prev->dst[OPE_WR_CLIENT_DISP_Y].x_init + + prev->dst[OPE_WR_CLIENT_DISP_Y].width; + + stripe->dst[OPE_WR_CLIENT_DISP_Y].addr =3D y_base; + stripe->dst[OPE_WR_CLIENT_DISP_Y].x_init =3D x_init; + stripe->dst[OPE_WR_CLIENT_DISP_Y].width =3D stripe->dsc[OPE_DS_Y_DISP].o= utput_width; + stripe->dst[OPE_WR_CLIENT_DISP_Y].height =3D stripe->dsc[OPE_DS_Y_DISP].o= utput_height; + stripe->dst[OPE_WR_CLIENT_DISP_Y].stride =3D bpl; + stripe->dst[OPE_WR_CLIENT_DISP_Y].format =3D OPE_PACKER_FMT_PLAIN_8; + + /* UV plane */ + x_init =3D c_x_init; + if (prev) + x_init =3D prev->dst[OPE_WR_CLIENT_DISP_C].x_init + + prev->dst[OPE_WR_CLIENT_DISP_C].width; + + stripe->dst[OPE_WR_CLIENT_DISP_C].addr =3D c_base; + stripe->dst[OPE_WR_CLIENT_DISP_C].x_init =3D x_init; + stripe->dst[OPE_WR_CLIENT_DISP_C].format =3D hw ? hw->packer : OPE_PACKER= _FMT_PLAIN_8; + stripe->dst[OPE_WR_CLIENT_DISP_C].width =3D stripe->dsc[OPE_DS_C_DISP].o= utput_width * 2; + stripe->dst[OPE_WR_CLIENT_DISP_C].height =3D stripe->dsc[OPE_DS_C_DISP].o= utput_height; + + switch (fo->fmt->fourcc) { + case V4L2_PIX_FMT_NV42: + case V4L2_PIX_FMT_NV24: + stripe->dst[OPE_WR_CLIENT_DISP_C].stride =3D bpl * 2; + break; + case V4L2_PIX_FMT_GREY: + stripe->dst[OPE_WR_CLIENT_DISP_C].enabled =3D false; + break; + default: + stripe->dst[OPE_WR_CLIENT_DISP_C].stride =3D bpl; + } +} + +static void ope_gen_stripes(struct ope_ctx *ctx, dma_addr_t src, dma_addr_= t dst) +{ + const struct ope_fmt_state *fi =3D &ctx->fmt_in; + const struct v4l2_rect *crop =3D &fi->crop; + const struct v4l2_rect *compose =3D &ctx->disp_compose; + const struct ope_hw_fmt *src_hw =3D ope_find_hw_fmt(fi->fmt->fourcc); + unsigned int num_stripes, width, x_out, x_out_c, i; + u32 h_scale, v_scale; + + /* Advance source pointer to the crop origin */ + src +=3D crop->top * fi->bytesperline + crop->left * fi->fmt->depth / 8; + width =3D crop->width; + num_stripes =3D DIV_ROUND_UP(crop->width, OPE_STRIPE_MAX_W); + h_scale =3D DS_Q21(crop->width, compose->width); + v_scale =3D DS_Q21(crop->height, compose->height); + + x_out =3D x_out_c =3D 0; + + for (i =3D 0; i < num_stripes; i++) { + struct ope_stripe *stripe =3D &ctx->stripe[i]; + unsigned int sw; + + memset(stripe, 0, sizeof(*stripe)); + + stripe->src.addr =3D src; + stripe->src.width =3D width; + stripe->src.height =3D crop->height; + stripe->src.stride =3D fi->bytesperline; + stripe->src.location =3D ope_stripe_location(i, num_stripes); + stripe->src.pattern =3D src_hw ? src_hw->pattern : 0; + stripe->src.format =3D src_hw ? src_hw->unpacker : 0; + + /* Ensure last stripe is wide enough */ + if (width > OPE_STRIPE_MAX_W && width < OPE_STRIPE_MAX_W + OPE_STRIPE_MI= N_W) + stripe->src.width -=3D OPE_STRIPE_MIN_W * 2; + + v4l_bound_align_image(&stripe->src.width, + OPE_STRIPE_MIN_W, OPE_STRIPE_MAX_W, + fi->fmt->align, + &stripe->src.height, + OPE_STRIPE_MIN_H, OPE_STRIPE_MAX_H, + OPE_ALIGN_H, 0); + + sw =3D stripe->src.width; + + width -=3D stripe->src.width; + src +=3D stripe->src.width * fi->fmt->depth / 8; + + /* + * Last-stripe adjustment: grow the input width (up to the + * available remaining input) until the scaler delivers at + * least the remaining output pixels for both Y and C. + * CROP_RND_CLAMP then clips the scaler output to exactly + * the remaining pixels so the total sums to fo->width. + */ + if (ope_stripe_is_last(stripe)) { + unsigned int rem_y =3D compose->width - x_out; + unsigned int rem_c =3D compose->width / 2 - x_out_c; + unsigned int s; + + for (s =3D OPE_STRIPE_MIN_W; s <=3D sw; s +=3D 2) { + if (DS_OUTPUT_PIX(s, 0, h_scale) >=3D rem_y && + DS_OUTPUT_PIX(s / 2, 0, h_scale) >=3D rem_c) { + stripe->src.width =3D s; + break; + } + } + } + + ope_gen_stripe_chroma_dsc(ctx, stripe); + ope_gen_stripe_dsc(ctx, stripe, h_scale, v_scale); + ope_gen_stripe_yuv_dst(ctx, stripe, dst); + + x_out +=3D stripe->dsc[OPE_DS_Y_DISP].output_width; + x_out_c +=3D stripe->dsc[OPE_DS_C_DISP].output_width; + + /* Width in bytes for the fetch engine */ + stripe->src.width =3D stripe->src.width * fi->fmt->depth / 8; + } +} + +/* -------- Pipeline IQ module programming -------- */ + +static bool ope_module_update(struct ope_ctx *ctx, u32 module_cfg_reg, u32= enable_mask, + struct v4l2_isp_params_block_header *hdr, bool force) +{ + bool enable =3D !(hdr->flags & V4L2_ISP_PARAMS_FL_BLOCK_DISABLE); + bool dirty =3D hdr->flags & CAMSS_ISP_PARAMS_FL_BLOCK_DIRTY; + + /* skip if neither forced (new context) nor dirty (updated params) */ + if (!force && !dirty) + return false; + + hdr->flags &=3D ~CAMSS_ISP_PARAMS_FL_BLOCK_DIRTY; + + ope_write_pp(ctx->ope, module_cfg_reg, enable ? enable_mask : 0); + + /* If module is disabled, not need to update content */ + if (!enable) + return false; + + dev_dbg(ctx->ope->dev, "IQ module (%u) update (flags:0x%x)\n", hdr->type,= hdr->flags); + + return true; +} + +static void ope_prog_wb(struct ope_ctx *ctx, bool force) +{ + struct camss_params_wb_gain *wb =3D &ctx->config.wb_gain; + struct ope_dev *ope =3D ctx->ope; + + if (!ope_module_update(ctx, OPE_PP_CLC_WB_GAIN_MODULE_CFG, + OPE_PP_CLC_WB_GAIN_MODULE_CFG_EN, + &wb->header, force)) + return; + + ope_write_pp(ope, OPE_PP_CLC_WB_GAIN_WB_CFG(0), wb->g_gain); + ope_write_pp(ope, OPE_PP_CLC_WB_GAIN_WB_CFG(1), wb->b_gain); + ope_write_pp(ope, OPE_PP_CLC_WB_GAIN_WB_CFG(2), wb->r_gain); +} + +static void ope_prog_bayer2rgb(struct ope_ctx *ctx, bool force) +{ + struct ope_params_demo *demo =3D &ctx->config.demo; + struct ope_dev *ope =3D ctx->ope; + + if (!ope_module_update(ctx, OPE_PP_CLC_DEMO_MODULE_CFG, + OPE_PP_CLC_DEMO_MODULE_CFG_EN | + OPE_PP_CLC_DEMO_MODULE_CFG_DYN_G_CLAMP_EN, + &demo->header, force)) + return; + + ope_write_pp(ope, OPE_PP_CLC_DEMO_INTERP_COEFF_CFG, + FIELD_PREP(OPE_PP_CLC_DEMO_INTERP_COEFF_CFG_LAMBDA_G, demo->lambda= _g) | + FIELD_PREP(OPE_PP_CLC_DEMO_INTERP_COEFF_CFG_LAMBDA_RB, demo->lambda= _rb)); + ope_write_pp(ope, OPE_PP_CLC_DEMO_INTERP_CLASSIFIER_CFG_0, + FIELD_PREP(OPE_PP_CLC_DEMO_INTERP_CLASSIFIER_CFG_0_AK, demo->a_k)); + ope_write_pp(ope, OPE_PP_CLC_DEMO_INTERP_CLASSIFIER_CFG_1, + FIELD_PREP(OPE_PP_CLC_DEMO_INTERP_CLASSIFIER_CFG_1_WK, demo->w_k)); +} + +static void ope_prog_rgb2yuv(struct ope_ctx *ctx, bool force) +{ + struct camss_params_chroma_enhan *cc =3D &ctx->config.chroma_enhan; + struct ope_dev *ope =3D ctx->ope; + + if (!ope_module_update(ctx, OPE_PP_CLC_CHROMA_ENHAN_MODULE_CFG, + OPE_PP_CLC_CHROMA_ENHAN_MODULE_CFG_EN, + &cc->header, force)) + return; + + ope_write_pp(ope, OPE_PP_CLC_CHROMA_ENHAN_LUMA_CFG_0, + FIELD_PREP(OPE_PP_CLC_CHROMA_ENHAN_LUMA_CFG_0_V0, cc->luma_v0) | + FIELD_PREP(OPE_PP_CLC_CHROMA_ENHAN_LUMA_CFG_0_V1, cc->luma_v1)); + ope_write_pp(ope, OPE_PP_CLC_CHROMA_ENHAN_LUMA_CFG_2, + FIELD_PREP(OPE_PP_CLC_CHROMA_ENHAN_LUMA_CFG_2_V2, cc->luma_v2)); + ope_write_pp(ope, OPE_PP_CLC_CHROMA_ENHAN_LUMA_CFG_1, + FIELD_PREP(OPE_PP_CLC_CHROMA_ENHAN_LUMA_CFG_1_K, cc->luma_k)); + ope_write_pp(ope, OPE_PP_CLC_CHROMA_ENHAN_COEFF_A_CFG, + FIELD_PREP(OPE_PP_CLC_CHROMA_ENHAN_COEFF_A_CFG_AP, cc->coeff_ap) | + FIELD_PREP(OPE_PP_CLC_CHROMA_ENHAN_COEFF_A_CFG_AM, cc->coeff_am)); + ope_write_pp(ope, OPE_PP_CLC_CHROMA_ENHAN_COEFF_B_CFG, + FIELD_PREP(OPE_PP_CLC_CHROMA_ENHAN_COEFF_B_CFG_BP, cc->coeff_dp) | + FIELD_PREP(OPE_PP_CLC_CHROMA_ENHAN_COEFF_B_CFG_BM, cc->coeff_dm)); + ope_write_pp(ope, OPE_PP_CLC_CHROMA_ENHAN_COEFF_C_CFG, + FIELD_PREP(OPE_PP_CLC_CHROMA_ENHAN_COEFF_C_CFG_CP, cc->coeff_cp) | + FIELD_PREP(OPE_PP_CLC_CHROMA_ENHAN_COEFF_C_CFG_CM, cc->coeff_cm)); + ope_write_pp(ope, OPE_PP_CLC_CHROMA_ENHAN_COEFF_D_CFG, + FIELD_PREP(OPE_PP_CLC_CHROMA_ENHAN_COEFF_D_CFG_DP, cc->coeff_dp) | + FIELD_PREP(OPE_PP_CLC_CHROMA_ENHAN_COEFF_D_CFG_DM, cc->coeff_dm)); + ope_write_pp(ope, OPE_PP_CLC_CHROMA_ENHAN_CHROMA_CFG_0, + FIELD_PREP(OPE_PP_CLC_CHROMA_ENHAN_CHROMA_CFG_0_KCB, cc->kcb)); + ope_write_pp(ope, OPE_PP_CLC_CHROMA_ENHAN_CHROMA_CFG_1, + FIELD_PREP(OPE_PP_CLC_CHROMA_ENHAN_CHROMA_CFG_1_KCR, cc->kcr)); +} + +static void ope_prog_color_correct(struct ope_ctx *ctx, bool force) +{ + struct camss_params_color_correct *cc =3D &ctx->config.color_correct; + struct ope_dev *ope =3D ctx->ope; + + if (!ope_module_update(ctx, OPE_PP_CLC_CC_MODULE_CFG, + OPE_PP_CLC_CC_MODULE_CFG_EN, + &cc->header, force)) + return; + + ope_write_pp(ope, OPE_PP_CLC_CC_COEFF_A_CFG_0, + FIELD_PREP(OPE_PP_CLC_CC_COEFF_A_CFG_0_A0, cc->a[0]) | + FIELD_PREP(OPE_PP_CLC_CC_COEFF_A_CFG_0_A1, cc->a[1])); + ope_write_pp(ope, OPE_PP_CLC_CC_COEFF_A_CFG_1, + FIELD_PREP(OPE_PP_CLC_CC_COEFF_A_CFG_1_A2, cc->a[2])); + ope_write_pp(ope, OPE_PP_CLC_CC_COEFF_B_CFG_0, + FIELD_PREP(OPE_PP_CLC_CC_COEFF_B_CFG_0_B0, cc->b[0]) | + FIELD_PREP(OPE_PP_CLC_CC_COEFF_B_CFG_0_B1, cc->b[1])); + ope_write_pp(ope, OPE_PP_CLC_CC_COEFF_B_CFG_1, + FIELD_PREP(OPE_PP_CLC_CC_COEFF_B_CFG_1_B2, cc->b[2])); + ope_write_pp(ope, OPE_PP_CLC_CC_COEFF_C_CFG_0, + FIELD_PREP(OPE_PP_CLC_CC_COEFF_C_CFG_0_C0, cc->c[0]) | + FIELD_PREP(OPE_PP_CLC_CC_COEFF_C_CFG_0_C1, cc->c[1])); + ope_write_pp(ope, OPE_PP_CLC_CC_COEFF_C_CFG_1, + FIELD_PREP(OPE_PP_CLC_CC_COEFF_C_CFG_1_C2, cc->c[2])); + ope_write_pp(ope, OPE_PP_CLC_CC_COEFF_K_CFG_0, + FIELD_PREP(OPE_PP_CLC_CC_COEFF_K_CFG_0_K0, cc->k[0])); + ope_write_pp(ope, OPE_PP_CLC_CC_COEFF_K_CFG_1, + FIELD_PREP(OPE_PP_CLC_CC_COEFF_K_CFG_1_K1, cc->k[1])); + ope_write_pp(ope, OPE_PP_CLC_CC_COEFF_K_CFG_2, + FIELD_PREP(OPE_PP_CLC_CC_COEFF_K_CFG_2_K2, cc->k[2])); + ope_write_pp(ope, OPE_PP_CLC_CC_COEFF_M_CFG, + FIELD_PREP(OPE_PP_CLC_CC_COEFF_M_CFG_M, cc->m)); +} + +static void ope_prog_crop_rnd_clamp(struct ope_dev *ope, const struct ope_= stripe *stripe) +{ + static const u32 crop_bases[] =3D { + OPE_PP_CLC_CROP_RND_CLAMP_Y_DISP_BASE, + OPE_PP_CLC_CROP_RND_CLAMP_C_DISP_BASE, + }; + static const enum ope_downscaler ds_idx[] =3D { + OPE_DS_Y_DISP, + OPE_DS_C_DISP, + }; + unsigned int i; + + for (i =3D 0; i < ARRAY_SIZE(crop_bases); i++) { + const struct ope_dsc_config *dsc =3D &stripe->dsc[ds_idx[i]]; + u32 cbase =3D crop_bases[i]; + + if (!dsc->output_width || !dsc->output_height) { + ope_write_pp(ope, OPE_PP_CLC_CROP_RND_CLAMP_MODULE_CFG(cbase), 0); + continue; + } + + ope_write_pp(ope, OPE_PP_CLC_CROP_RND_CLAMP_CROP_PIXEL_CFG(cbase), + FIELD_PREP(OPE_PP_CLC_CROP_RND_CLAMP_CROP_FIRST, 0) | + FIELD_PREP(OPE_PP_CLC_CROP_RND_CLAMP_CROP_LAST, + dsc->crop_last_pixel)); + ope_write_pp(ope, OPE_PP_CLC_CROP_RND_CLAMP_CROP_LINE_CFG(cbase), + FIELD_PREP(OPE_PP_CLC_CROP_RND_CLAMP_CROP_FIRST, 0) | + FIELD_PREP(OPE_PP_CLC_CROP_RND_CLAMP_CROP_LAST, dsc->crop_last_lin= e)); + ope_write_pp(ope, OPE_PP_CLC_CROP_RND_CLAMP_MODULE_CFG(cbase), + OPE_PP_CLC_CROP_RND_CLAMP_EN | OPE_PP_CLC_CROP_RND_CLAMP_CROP_EN); + } +} + +static void ope_prog_stripe(struct ope_ctx *ctx, struct ope_stripe *stripe) +{ + struct ope_dev *ope =3D ctx->ope; + int i; + + dev_dbg(ope->dev, "ctx=3D%p programming stripe %u\n", + ctx, (unsigned int)(stripe - ctx->stripe)); + + /* Fetch Engine */ + ope_write_rd(ope, OPE_BUS_RD_CLIENT_0_UNPACK_CFG_0, stripe->src.format); + ope_write_rd(ope, OPE_BUS_RD_CLIENT_0_RD_BUFFER_SIZE, + (stripe->src.width << 16) | stripe->src.height); + ope_write_rd(ope, OPE_BUS_RD_CLIENT_0_ADDR_IMAGE, stripe->src.addr); + ope_write_rd(ope, OPE_BUS_RD_CLIENT_0_RD_STRIDE, stripe->src.stride); + ope_write_rd(ope, OPE_BUS_RD_CLIENT_0_CCIF_META_DATA, + FIELD_PREP(OPE_BUS_RD_CLIENT_0_CCIF_MD_PIX_PATTERN, + stripe->src.pattern)); + ope_write_rd(ope, OPE_BUS_RD_CLIENT_0_CORE_CFG, + OPE_BUS_RD_CLIENT_0_CORE_CFG_EN); + + /* Write Engines */ + for (i =3D 0; i < OPE_WR_CLIENT_MAX; i++) { + if (!stripe->dst[i].enabled) { + ope_write_wr(ope, OPE_BUS_WR_CLIENT_CFG(i), 0); + continue; + } + ope_write_wr(ope, OPE_BUS_WR_CLIENT_ADDR_IMAGE(i), + stripe->dst[i].addr); + ope_write_wr(ope, OPE_BUS_WR_CLIENT_IMAGE_CFG_0(i), + (stripe->dst[i].height << 16) | stripe->dst[i].width); + ope_write_wr(ope, OPE_BUS_WR_CLIENT_IMAGE_CFG_1(i), + stripe->dst[i].x_init); + ope_write_wr(ope, OPE_BUS_WR_CLIENT_IMAGE_CFG_2(i), + stripe->dst[i].stride); + ope_write_wr(ope, OPE_BUS_WR_CLIENT_PACKER_CFG(i), + stripe->dst[i].format); + ope_write_wr(ope, OPE_BUS_WR_CLIENT_CFG(i), + OPE_BUS_WR_CLIENT_CFG_EN | + OPE_BUS_WR_CLIENT_CFG_AUTORECOVER); + } + + /* Downscalers */ + for (i =3D 0; i < OPE_DS_MAX; i++) { + struct ope_dsc_config *dsc =3D &stripe->dsc[i]; + u32 base =3D ope_ds_base[i]; + u32 cfg =3D 0; + + if (dsc->input_width !=3D dsc->output_width) { + dsc->phase_step_h |=3D + DS_RESOLUTION(dsc->input_width, + dsc->output_width) << 30; + cfg |=3D OPE_PP_CLC_DOWNSCALE_MN_DS_CFG_H_SCALE_EN; + } + if (dsc->input_height !=3D dsc->output_height) { + dsc->phase_step_v |=3D + DS_RESOLUTION(dsc->input_height, + dsc->output_height) << 30; + cfg |=3D OPE_PP_CLC_DOWNSCALE_MN_DS_CFG_V_SCALE_EN; + } + + ope_write_pp(ope, OPE_PP_CLC_DOWNSCALE_MN_DS_CFG(base), cfg); + ope_write_pp(ope, OPE_PP_CLC_DOWNSCALE_MN_DS_IMAGE_SIZE_CFG(base), + ((dsc->input_width - 1) << 16) | (dsc->input_height - 1)); + ope_write_pp(ope, OPE_PP_CLC_DOWNSCALE_MN_DS_MN_H_CFG(base), + dsc->phase_step_h); + ope_write_pp(ope, OPE_PP_CLC_DOWNSCALE_MN_DS_MN_V_CFG(base), + dsc->phase_step_v); + ope_write_pp(ope, OPE_PP_CLC_DOWNSCALE_MN_CFG(base), + cfg ? OPE_PP_CLC_DOWNSCALE_MN_CFG_EN : 0); + + dev_dbg(ope->dev, + "DS[%d] cfg=3D0x%x in=3D%ux%u out=3D%ux%u\n", + i, cfg, + dsc->input_width, dsc->input_height, + dsc->output_width, dsc->output_height); + } + + ope_prog_crop_rnd_clamp(ope, stripe); +} + +static void ope_params_apply_wb(void *priv, const union camss_isp_params_b= lock *block) +{ + struct ope_ctx *ctx =3D priv; + + ctx->config.wb_gain =3D block->wb_gain; + ctx->config.wb_gain.header.flags |=3D CAMSS_ISP_PARAMS_FL_BLOCK_DIRTY; +} + +static void ope_params_apply_chroma_enhan(void *priv, const union camss_is= p_params_block *block) +{ + struct ope_ctx *ctx =3D priv; + + ctx->config.chroma_enhan =3D block->chroma_enhan; + ctx->config.chroma_enhan.header.flags |=3D CAMSS_ISP_PARAMS_FL_BLOCK_DIRT= Y; +} + +static void ope_params_apply_color_correct(void *priv, const union camss_i= sp_params_block *block) +{ + struct ope_ctx *ctx =3D priv; + + ctx->config.color_correct =3D block->color_correct; + ctx->config.color_correct.header.flags |=3D CAMSS_ISP_PARAMS_FL_BLOCK_DIR= TY; +} + +static const struct v4l2_isp_params_block_type_info ope_params_type_info[]= =3D { + [CAMSS_PARAMS_WB_GAIN] =3D { sizeof(struct camss_params_wb_gain) }, + [CAMSS_PARAMS_CHROMA_ENHAN] =3D { sizeof(struct camss_params_chroma_enhan= ) }, + [CAMSS_PARAMS_COLOR_CORRECT] =3D { sizeof(struct camss_params_color_corre= ct) }, +}; + +static const camss_isp_params_handler_fn ope_params_handlers[] =3D { + [CAMSS_PARAMS_WB_GAIN] =3D ope_params_apply_wb, + [CAMSS_PARAMS_CHROMA_ENHAN] =3D ope_params_apply_chroma_enhan, + [CAMSS_PARAMS_COLOR_CORRECT] =3D ope_params_apply_color_correct, +}; + +static void ope_apply_params(struct ope_ctx *ctx) +{ + struct vb2_v4l2_buffer *vbuf; + + vbuf =3D camss_isp_bufq_next(ctx->bufq, OPE_QUEUE_PARAMS); + if (!vbuf) + return; + + camss_isp_params_apply(ctx->ope->dev, &vbuf->vb2_buf, + ope_params_type_info, + ope_params_handlers, + ARRAY_SIZE(ope_params_handlers), + ctx); +} + +/* Default/initial tuning parameters */ +static const struct ope_config ope_default_config =3D { + .wb_gain =3D { + .header.type =3D CAMSS_PARAMS_WB_GAIN, + .header.flags =3D V4L2_ISP_PARAMS_FL_BLOCK_ENABLE | + CAMSS_ISP_PARAMS_FL_BLOCK_DIRTY, + .g_gain =3D OPE_WB(1, 1), + .b_gain =3D OPE_WB(3, 2), + .r_gain =3D OPE_WB(3, 2), + }, + .demo =3D { + .header.type =3D CAMSS_PARAMS_INTERNAL, + .header.flags =3D V4L2_ISP_PARAMS_FL_BLOCK_ENABLE | + CAMSS_ISP_PARAMS_FL_BLOCK_DIRTY, + .lambda_rb =3D 0, + .lambda_g =3D 128, + .a_k =3D 128, + .w_k =3D 102, + }, + .chroma_enhan =3D { /* RGB -> YUV values from BT.601 */ + .header.type =3D CAMSS_PARAMS_CHROMA_ENHAN, + .header.flags =3D V4L2_ISP_PARAMS_FL_BLOCK_ENABLE | + CAMSS_ISP_PARAMS_FL_BLOCK_DIRTY, + .luma_v0 =3D 0x04d, + .luma_v1 =3D 0x096, + .luma_v2 =3D 0x01d, + .luma_k =3D 0, + .coeff_ap =3D 0x0e6, + .coeff_am =3D 0x0e6, + .coeff_cp =3D 0x0b3, + .coeff_cm =3D 0x0b3, + .coeff_dp =3D 0xfb3, + .coeff_dm =3D 0xfb3, + .kcb =3D 128, + .kcr =3D 128, + }, + .color_correct =3D { + .header.type =3D CAMSS_PARAMS_COLOR_CORRECT, + .header.flags =3D V4L2_ISP_PARAMS_FL_BLOCK_DISABLE | + CAMSS_ISP_PARAMS_FL_BLOCK_DIRTY, + } +}; + +/* -------- Job scheduling -------- */ +static bool ope_job_ready(void *priv) +{ + struct ope_ctx *ctx =3D priv; + + return ctx->started && + camss_isp_bufq_num_ready(ctx->bufq, OPE_QUEUE_FRAME_IN) >=3D 1 && + camss_isp_bufq_num_ready(ctx->bufq, OPE_QUEUE_DISP_OUT) >=3D 1; +} + +static void ope_job_finish(struct ope_ctx *ctx, enum vb2_buffer_state stat= e) +{ + struct vb2_v4l2_buffer *src, *dst, *params; + bool requeue =3D false; + + src =3D camss_isp_bufq_remove(ctx->bufq, OPE_QUEUE_FRAME_IN); + dst =3D camss_isp_bufq_remove(ctx->bufq, OPE_QUEUE_DISP_OUT); + params =3D camss_isp_bufq_remove(ctx->bufq, OPE_QUEUE_PARAMS); + + if (dst) { + dst->sequence =3D ctx->fmt_in.sequence++; + dst->vb2_buf.timestamp =3D src->vb2_buf.timestamp; + } + + if (dst) + camss_isp_buf_done(dst, state); + if (src) + camss_isp_buf_done(src, state); + if (params) + camss_isp_buf_done(params, state); + + if (ope_job_ready(ctx) && state =3D=3D VB2_BUF_STATE_DONE) + requeue =3D true; + + dev_dbg(ctx->ope->dev, "done ctx=3D%p continue=3D%s\n", ctx, requeue ? "y= es" : "no"); + + ctx->ope->hw_ctx =3D NULL; + camss_isp_sched_job_finish(&ctx->ope->sched, &ctx->job, requeue); +} + +static dma_addr_t ope_buf_dma_addr(struct ope_ctx *ctx, unsigned int queue= _idx) +{ + struct vb2_v4l2_buffer *vbuf =3D camss_isp_bufq_next(ctx->bufq, queue_idx= ); + + if (!vbuf) + return 0; + + return vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0); +} + +static void ope_run_job(void *priv, bool ctx_changed) +{ + struct ope_ctx *ctx =3D priv; + struct ope_dev *ope =3D ctx->ope; + dma_addr_t src, dst; + + src =3D ope_buf_dma_addr(ctx, OPE_QUEUE_FRAME_IN); + dst =3D ope_buf_dma_addr(ctx, OPE_QUEUE_DISP_OUT); + + if (!src || !dst) { + dev_warn(ope->dev, "Job cannot run, missing buffer\n"); + camss_isp_sched_job_finish(&ope->sched, &ctx->job, false); + return; + } + + dev_dbg(ope->dev, "start ctx=3D%p->%p src=3D%pad dst=3D%pad\n", + ope->hw_ctx, ctx, &src, &dst); + + ope_apply_params(ctx); + ope_gen_stripes(ctx, src, dst); + + ope_prog_wb(ctx, ctx_changed); + ope_prog_bayer2rgb(ctx, ctx_changed); + ope_prog_color_correct(ctx, ctx_changed); + ope_prog_rgb2yuv(ctx, ctx_changed); + + ctx->current_stripe =3D 0; + ope->hw_ctx =3D ctx; + ope_prog_stripe(ctx, &ctx->stripe[0]); + + ope_start(ope); +} + +static void ope_abort_job(void *priv) +{ + struct ope_ctx *ctx =3D priv; + + dev_dbg(ctx->ope->dev, "job abort ctx=3D%p\n", ctx); + ope_write(ctx->ope, OPE_TOP_RESET_CMD, OPE_TOP_RESET_CMD_SW); + + /* Scheduler will wait for completion (on reset complete isr) */ +} + +static void ope_try_schedule(struct ope_ctx *ctx) +{ + camss_isp_sched_try_run(&ctx->ope->sched, &ctx->job); +} + +static const struct camss_isp_job_ops ope_job_ops =3D { + .ready =3D ope_job_ready, + .run =3D ope_run_job, + .abort =3D ope_abort_job, +}; + +/* -------- Interrupt handlers -------- */ + +static void ope_fe_irq(struct ope_dev *ope) +{ + u32 status =3D readl_relaxed(ope->base_rd + OPE_BUS_RD_INPUT_IF_IRQ_STATU= S); + + writel_relaxed(status, ope->base_rd + OPE_BUS_RD_INPUT_IF_IRQ_CLEAR); + writel_relaxed(OPE_BUS_RD_INPUT_IF_IRQ_CMD_CLEAR, + ope->base_rd + OPE_BUS_RD_INPUT_IF_IRQ_CMD); +} + +static void ope_we_irq(struct ope_dev *ope, struct ope_ctx *ctx) +{ + u32 status; + + status =3D ope_read_wr(ope, OPE_BUS_WR_INPUT_IF_IRQ_STATUS_0); + ope_write_wr(ope, OPE_BUS_WR_INPUT_IF_IRQ_CLEAR_0, status); + ope_write_wr(ope, OPE_BUS_WR_INPUT_IF_IRQ_CMD, OPE_BUS_WR_INPUT_IF_IRQ_CM= D_CLEAR); + + if (!ctx) + return; + + if (status & OPE_BUS_WR_INPUT_IF_IRQ_STATUS_0_CONS_VIOL) { + u32 viol =3D ope_read_wr(ope, OPE_BUS_WR_VIOLATION_STATUS); + + dev_err_ratelimited(ope->dev, "constraint violation (clients=3D0x%x)\n",= viol); + ope_write(ctx->ope, OPE_TOP_RESET_CMD, OPE_TOP_RESET_CMD_SW); + } + + if (status & OPE_BUS_WR_INPUT_IF_IRQ_STATUS_0_IMG_SZ_VIOL) { + u32 viol =3D ope_read_wr(ope, OPE_BUS_WR_IMAGE_SIZE_VIOLATION_STATUS); + int i; + + for (i =3D 0; i < OPE_WR_CLIENT_MAX; i++) { + if (BIT(i) & viol) + dev_err_ratelimited(ope->dev, "WE%d: image size violation\n", i); + } + ope_write(ctx->ope, OPE_TOP_RESET_CMD, OPE_TOP_RESET_CMD_SW); + } + + if (status & OPE_BUS_WR_INPUT_IF_IRQ_STATUS_0_VIOL) { + u32 viol =3D ope_read_wr(ope, OPE_BUS_WR_VIOLATION_STATUS); + + dev_err_ratelimited(ope->dev, "fatal violation (status=3D0x%08x)\n", vio= l); + ope_write(ctx->ope, OPE_TOP_RESET_CMD, OPE_TOP_RESET_CMD_SW); + } + + if (status & OPE_BUS_WR_INPUT_IF_IRQ_STATUS_0_RUP_DONE) { + /* Register update done: program next stripe (double-buffered) */ + struct ope_stripe *stripe =3D ope_current_stripe(ctx); + + if (stripe && !ope_stripe_is_last(stripe)) + ope_prog_stripe(ctx, stripe + 1); + } +} + + +static void __ope_irq_init(struct ope_dev *ope) +{ + ope_write(ope, OPE_TOP_IRQ_MASK, + OPE_TOP_IRQ_STATUS_RST_DONE | + OPE_TOP_IRQ_STATUS_WE | + OPE_TOP_IRQ_STATUS_VIOL | + OPE_TOP_IRQ_STATUS_IDLE); + ope_write_wr(ope, OPE_BUS_WR_INPUT_IF_IRQ_MASK_0, + OPE_BUS_WR_INPUT_IF_IRQ_STATUS_0_RUP_DONE | + OPE_BUS_WR_INPUT_IF_IRQ_STATUS_0_CONS_VIOL | + OPE_BUS_WR_INPUT_IF_IRQ_STATUS_0_VIOL | + OPE_BUS_WR_INPUT_IF_IRQ_STATUS_0_IMG_SZ_VIOL); +} + +static irqreturn_t ope_irq(int irq, void *dev_id) +{ + struct ope_dev *ope =3D dev_id; + struct ope_ctx *ctx; + u32 status; + + /* + * hw_ctx is safe to read here without a lock: ope_run_job() sets it + * before calling ope_start(), so the hardware cannot raise an IRQ + * before hw_ctx is visible. ope_job_finish() clears it in IRQ context + * (i.e. here), so the clear is serialised with this read by the IRQ + * itself. + */ + ctx =3D ope->hw_ctx; + + status =3D ope_read(ope, OPE_TOP_IRQ_STATUS); + ope_write(ope, OPE_TOP_IRQ_CLEAR, status); + ope_write(ope, OPE_TOP_IRQ_CMD, OPE_TOP_IRQ_CMD_CLEAR); + + if (status & OPE_TOP_IRQ_STATUS_RST_DONE) { + dev_dbg(ope->dev, "reset done ctx=3D%p\n", ctx); + if (ctx) + ope_job_finish(ctx, VB2_BUF_STATE_ERROR); + complete(&ope->reset_complete); + } + + if (status & OPE_TOP_IRQ_STATUS_VIOL) + dev_warn(ope->dev, "OPE violation: 0x%08x\n", + ope_read(ope, OPE_TOP_VIOLATION_STATUS)); + + if (status & OPE_TOP_IRQ_STATUS_FE) + ope_fe_irq(ope); + + if (status & OPE_TOP_IRQ_STATUS_WE) + ope_we_irq(ope, ctx); + + if ((status & OPE_TOP_IRQ_STATUS_IDLE) && ctx) { + struct ope_stripe *stripe =3D ope_current_stripe(ctx); + + dev_dbg(ope->dev, "stripe %u done ctx=3D%p\n", ctx->current_stripe, ctx); + + if (ope_stripe_is_last(stripe)) { + ctx->current_stripe =3D 0; + ope_job_finish(ctx, VB2_BUF_STATE_DONE); + } else { + ctx->current_stripe++; + ope_start(ope); + } + } + + return IRQ_HANDLED; +} + +/* -------- vb2 queue private data -------- */ + +struct ope_vq_priv { + struct ope_ctx *ctx; + unsigned int queue_idx; +}; + +static inline struct ope_ctx *ope_ctx_from_vq(struct vb2_queue *q) +{ + return ((struct ope_vq_priv *)vb2_get_drv_priv(q))->ctx; +} + +static inline unsigned int ope_idx_from_vq(struct vb2_queue *q) +{ + return ((struct ope_vq_priv *)vb2_get_drv_priv(q))->queue_idx; +} + +/* -------- vb2 ops -------- */ + +static int ope_queue_setup(struct vb2_queue *q, unsigned int *nbuffers, + unsigned int *nplanes, unsigned int sizes[], + struct device *alloc_devs[]) +{ + struct ope_ctx *ctx =3D ope_ctx_from_vq(q); + unsigned int idx =3D ope_idx_from_vq(q); + unsigned int size; + + if (idx =3D=3D OPE_QUEUE_FRAME_IN) + size =3D ctx->fmt_in.sizeimage ? ctx->fmt_in.sizeimage : PAGE_SIZE; + else if (idx =3D=3D OPE_QUEUE_DISP_OUT) + size =3D ctx->fmt_out.sizeimage ? ctx->fmt_out.sizeimage : PAGE_SIZE; + else + size =3D v4l2_isp_params_buffer_size(CAMSS_PARAMS_MAX_PAYLOAD); + + if (*nplanes) { + if (*nplanes !=3D 1 || sizes[0] < size) + return -EINVAL; + } else { + *nplanes =3D 1; + sizes[0] =3D size; + } + + return 0; +} + +static int ope_buf_prepare(struct vb2_buffer *vb) +{ + struct ope_ctx *ctx =3D ope_ctx_from_vq(vb->vb2_queue); + unsigned int idx =3D ope_idx_from_vq(vb->vb2_queue); + struct vb2_v4l2_buffer *vbuf =3D to_vb2_v4l2_buffer(vb); + unsigned int sizeimage; + + if (idx =3D=3D OPE_QUEUE_FRAME_IN) + sizeimage =3D ctx->fmt_in.sizeimage; + else if (idx =3D=3D OPE_QUEUE_DISP_OUT) + sizeimage =3D ctx->fmt_out.sizeimage; + else + sizeimage =3D v4l2_isp_params_buffer_size(CAMSS_PARAMS_MAX_PAYLOAD); + + if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { + if (vb->vb2_queue->type =3D=3D V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + if (vbuf->field =3D=3D V4L2_FIELD_ANY) + vbuf->field =3D V4L2_FIELD_NONE; + if (vbuf->field !=3D V4L2_FIELD_NONE) + return -EINVAL; + } + } + + if (vb2_plane_size(vb, 0) < sizeimage) + return -EINVAL; + + if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type)) + vb2_set_plane_payload(vb, 0, sizeimage); + + return 0; +} + +static void ope_buf_queue(struct vb2_buffer *vb) +{ + struct ope_ctx *ctx =3D ope_ctx_from_vq(vb->vb2_queue); + unsigned int idx =3D ope_idx_from_vq(vb->vb2_queue); + struct vb2_v4l2_buffer *vbuf =3D to_vb2_v4l2_buffer(vb); + + camss_isp_bufq_queue(ctx->bufq, idx, vbuf); + ope_try_schedule(ctx); +} + +/* -------- Power scaling -------- */ + +static inline unsigned long ope_pixclk(const struct ope_fmt_state *fs, uns= igned int fps) +{ + return (unsigned long)fs->width * fs->height * fps; +} + +static inline unsigned int ope_load_avg(const struct ope_fmt_state *fs, un= signed int fps) +{ + return mult_frac(ope_pixclk(fs, fps), fs->fmt->depth, 1000) / 8; +} + +static inline unsigned int ope_load_peak(const struct ope_fmt_state *fs, u= nsigned int fps) +{ + return ope_load_avg(fs, fps) * 2; +} + +static inline unsigned int ope_load_config(const struct ope_fmt_state *fs,= unsigned int fps) +{ + unsigned int stripe_count =3D fs->width / OPE_STRIPE_MAX_W + 1; + + /* In worst case we have ~50 32-bit registers to write */ + return mult_frac(stripe_count * 50 * 4, fps, 1000); +} + +static void ope_adjust_power(struct ope_dev *ope) +{ + unsigned int loadavg =3D 0, loadpeak =3D 0, loadconfig =3D 0; + unsigned long pixclk =3D 0; + struct dev_pm_opp *opp; + struct ope_ctx *ctx; + int ret; + + list_for_each_entry(ctx, &ope->ctx_list, list) { + unsigned int fps; + + if (!ctx->started) + continue; + + fps =3D ctx->framerate ? ctx->framerate : DEFAULT_FRAMERATE; + + pixclk +=3D ope_pixclk(&ctx->fmt_in, fps); + loadavg +=3D ope_load_avg(&ctx->fmt_in, fps); + loadavg +=3D ope_load_avg(&ctx->fmt_out, fps); + loadpeak +=3D ope_load_peak(&ctx->fmt_in, fps); + loadpeak +=3D ope_load_peak(&ctx->fmt_out, fps); + loadconfig +=3D ope_load_config(&ctx->fmt_in, fps); + } + + /* 30% margin for overhead */ + pixclk =3D mult_frac(pixclk, 13, 10); + + dev_dbg(ope->dev, "adjust power: clk=3D%luHz avg=3D%uKBps peak=3D%uKBps c= fg=3D%uKBps\n", + pixclk, loadavg, loadpeak, loadconfig); + + opp =3D dev_pm_opp_find_freq_ceil(ope->dev, &pixclk); + if (IS_ERR(opp)) + dev_warn(ope->dev, "Requested pixel clock %luHz exceeds hardware limit\n= ", pixclk); + else + dev_pm_opp_put(opp); + + ret =3D dev_pm_opp_set_rate(ope->dev, pixclk); + if (ret) + dev_warn(ope->dev, "Failed to set OPP rate: %d\n", ret); + + ret =3D icc_set_bw(ope->icc_data, loadavg, loadpeak); + if (ret) + dev_warn(ope->dev, "Failed to set data path BW: %d\n", ret); + + ret =3D icc_set_bw(ope->icc_config, loadconfig, loadconfig * 5); + if (ret) + dev_warn(ope->dev, "Failed to set config path BW: %d\n", ret); +} + +static int ope_start_streaming(struct vb2_queue *q, unsigned int count) +{ + struct ope_ctx *ctx =3D ope_ctx_from_vq(q); + unsigned int idx =3D ope_idx_from_vq(q); + int ret; + + dev_dbg(ctx->ope->dev, "streaming start ctx=3D%p queue=3D%u\n", ctx, idx); + + ret =3D pm_runtime_resume_and_get(ctx->ope->dev); + if (ret) { + dev_err(ctx->ope->dev, "resume failed (%d)\n", ret); + return ret; + } + + if (idx =3D=3D OPE_QUEUE_FRAME_IN) { + ctx->fmt_in.sequence =3D 0; + ctx->started =3D true; + ope_adjust_power(ctx->ope); + __ope_irq_init(ctx->ope); + } + + ope_try_schedule(ctx); + + return 0; +} + +static void ope_stop_streaming(struct vb2_queue *q) +{ + struct ope_ctx *ctx =3D ope_ctx_from_vq(q); + unsigned int idx =3D ope_idx_from_vq(q); + + dev_dbg(ctx->ope->dev, "streaming stop ctx=3D%p queue=3D%u\n", ctx, idx); + + if (idx =3D=3D OPE_QUEUE_FRAME_IN) { + ctx->started =3D false; + ope_adjust_power(ctx->ope); + } + + camss_isp_bufq_drain(ctx->bufq, idx, VB2_BUF_STATE_ERROR); + + pm_runtime_put(ctx->ope->dev); +} + +static const struct vb2_ops ope_vb2_ops =3D { + .queue_setup =3D ope_queue_setup, + .buf_prepare =3D ope_buf_prepare, + .buf_queue =3D ope_buf_queue, + .start_streaming =3D ope_start_streaming, + .stop_streaming =3D ope_stop_streaming, +}; + +static int ope_init_vq(struct ope_ctx *ctx, unsigned int idx) +{ + struct ope_dev *ope =3D ctx->ope; + struct ope_vq_priv *qpriv; + struct vb2_queue *q =3D &ctx->vqs[idx]; + + qpriv =3D devm_kzalloc(ope->dev, sizeof(*qpriv), GFP_KERNEL); + if (!qpriv) + return -ENOMEM; + + qpriv->ctx =3D ctx; + qpriv->queue_idx =3D idx; + q->drv_priv =3D qpriv; + q->ops =3D &ope_vb2_ops; + q->lock =3D &ctx->vbq_lock; + q->dev =3D ope->dev; + q->buf_struct_size =3D sizeof(struct camss_isp_buf); + q->timestamp_flags =3D V4L2_BUF_FLAG_TIMESTAMP_COPY; + + if (idx =3D=3D OPE_QUEUE_PARAMS) { + q->type =3D V4L2_BUF_TYPE_META_OUTPUT; + q->mem_ops =3D &vb2_vmalloc_memops; + q->io_modes =3D VB2_MMAP | VB2_USERPTR; + } else if (idx =3D=3D OPE_QUEUE_DISP_OUT) { + q->type =3D V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + q->mem_ops =3D &vb2_dma_contig_memops; + q->io_modes =3D VB2_MMAP | VB2_DMABUF; + } else { + q->type =3D V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + q->mem_ops =3D &vb2_dma_contig_memops; + q->io_modes =3D VB2_MMAP | VB2_DMABUF; + } + + return vb2_queue_init(q); +} + +/* -------- Format helpers -------- */ + +static const struct ope_fmt *ope_find_fmt(const struct ope_fmt *fmts, + unsigned int n, u32 fourcc) +{ + unsigned int i; + + for (i =3D 0; i < n; i++) + if (fmts[i].fourcc =3D=3D fourcc) + return &fmts[i]; + + return NULL; +} + +static const struct ope_fmt *ope_fmt_try(struct ope_dev *ope, bool is_outp= ut, + struct v4l2_pix_format_mplane *pix) +{ + const struct ope_fmt *fmts =3D is_output ? ope_output_fmts : ope_input_fm= ts; + unsigned int n =3D is_output ? ARRAY_SIZE(ope_output_fmts) : ARRAY_SIZE(o= pe_input_fmts); + unsigned int max_w =3D OPE_MAX_W, max_h =3D OPE_MAX_H; + const struct ope_fmt *fmt; + unsigned int bytesperline; + + fmt =3D ope_find_fmt(fmts, n, pix->pixelformat); + if (!fmt) { + fmt =3D &fmts[0]; + pix->pixelformat =3D fmt->fourcc; + } + + v4l_bound_align_image(&pix->width, OPE_MIN_W, max_w, fmt->align, + &pix->height, OPE_MIN_H, max_h, 0, 0); + + pix->num_planes =3D 1; + pix->field =3D V4L2_FIELD_NONE; + if (!pix->colorspace) + pix->colorspace =3D is_output ? V4L2_COLORSPACE_SRGB : V4L2_COLORSPACE_R= AW; + /* + * Output formats are semi-planar or grey-scale (Y plane only) always + * using 1 byte per Y value. pix->bytesperline stores the Y-plane bpl. + * Depth tracks the total storage size including the second combined + * Cb + Cr plane which directly follows the Y plane and is used for + * sizeimage calculations rather then for bytesperline. + */ + if (is_output) + bytesperline =3D pix->width; + else + bytesperline =3D pix->width * fmt->depth / 8; + + if (pix->plane_fmt[0].bytesperline < bytesperline) + pix->plane_fmt[0].bytesperline =3D bytesperline; + + + if (is_output) + pix->plane_fmt[0].sizeimage =3D + (u64)pix->plane_fmt[0].bytesperline * pix->height * fmt->depth / 8; + else + pix->plane_fmt[0].sizeimage =3D pix->plane_fmt[0].bytesperline * pix->he= ight; + + return fmt; +} + +/* -------- ioctl helpers/ops -------- */ + +static inline unsigned int ope_queue_idx_from_file(struct file *file) +{ + return (unsigned int)(uintptr_t)video_get_drvdata(video_devdata(file)); +} + +static struct vb2_queue *ope_vq_from_file(struct file *file, struct ope_ct= x *ctx) +{ + unsigned int idx =3D ope_queue_idx_from_file(file); + + if (idx >=3D OPE_QUEUE_COUNT) + return NULL; + + return &ctx->vqs[idx]; +} + +static struct ope_ctx *ope_ctx_from_file(struct file *file) +{ + struct ope_dev *ope =3D container_of(video_devdata(file)->v4l2_dev, + struct ope_dev, v4l2_dev); + + return ope->shared_ctx; +} + +static int ope_querycap(struct file *file, void *priv, struct v4l2_capabil= ity *cap) +{ + strscpy(cap->driver, OPE_NAME, sizeof(cap->driver)); + strscpy(cap->card, "Qualcomm CAMSS OPE", sizeof(cap->card)); + + return 0; +} + +static int ope_enum_fmt_vid_out(struct file *file, void *priv, struct v4l2= _fmtdesc *f) +{ + if (f->index >=3D ARRAY_SIZE(ope_input_fmts)) + return -EINVAL; + + f->pixelformat =3D ope_input_fmts[f->index].fourcc; + + return 0; +} + +static int ope_g_fmt_vid_out(struct file *file, void *priv, struct v4l2_fo= rmat *f) +{ + struct ope_ctx *ctx =3D ope_ctx_from_file(file); + struct ope_fmt_state *fs =3D &ctx->fmt_in; + struct v4l2_pix_format_mplane *pix =3D &f->fmt.pix_mp; + + pix->pixelformat =3D fs->fmt->fourcc; + pix->width =3D fs->width; + pix->height =3D fs->height; + pix->num_planes =3D 1; + pix->field =3D V4L2_FIELD_NONE; + pix->colorspace =3D fs->colorspace; + pix->xfer_func =3D fs->xfer_func; + pix->ycbcr_enc =3D fs->ycbcr_enc; + pix->quantization =3D fs->quantization; + pix->plane_fmt[0].bytesperline =3D fs->bytesperline; + pix->plane_fmt[0].sizeimage =3D fs->sizeimage; + + return 0; +} + +static int ope_try_fmt_vid_out(struct file *file, void *priv, struct v4l2_= format *f) +{ + struct ope_ctx *ctx =3D ope_ctx_from_file(file); + + ope_fmt_try(ctx->ope, false, &f->fmt.pix_mp); + + return 0; +} + +static int ope_s_fmt_vid_out(struct file *file, void *priv, struct v4l2_fo= rmat *f) +{ + struct ope_ctx *ctx =3D ope_ctx_from_file(file); + const struct ope_fmt *fmt; + + if (vb2_is_busy(&ctx->vqs[OPE_QUEUE_FRAME_IN])) + return -EBUSY; + + fmt =3D ope_fmt_try(ctx->ope, false, &f->fmt.pix_mp); + ctx->fmt_in.fmt =3D fmt; + ctx->fmt_in.width =3D f->fmt.pix_mp.width; + ctx->fmt_in.height =3D f->fmt.pix_mp.height; + ctx->fmt_in.bytesperline =3D f->fmt.pix_mp.plane_fmt[0].bytesperline; + ctx->fmt_in.sizeimage =3D f->fmt.pix_mp.plane_fmt[0].sizeimage; + ctx->fmt_in.colorspace =3D f->fmt.pix_mp.colorspace; + ctx->fmt_in.xfer_func =3D f->fmt.pix_mp.xfer_func; + ctx->fmt_in.ycbcr_enc =3D f->fmt.pix_mp.ycbcr_enc; + ctx->fmt_in.quantization =3D f->fmt.pix_mp.quantization; + + /* Reset crop to full input frame */ + ctx->fmt_in.crop.left =3D 0; + ctx->fmt_in.crop.top =3D 0; + ctx->fmt_in.crop.width =3D ctx->fmt_in.width; + ctx->fmt_in.crop.height =3D ctx->fmt_in.height; + + return 0; +} + +static int ope_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2= _fmtdesc *f) +{ + struct ope_ctx *ctx =3D ope_ctx_from_file(file); + unsigned int i, n =3D 0; + + for (i =3D 0; i < ARRAY_SIZE(ope_output_fmts); i++) { + if (ope_output_fmts[i].mbus_code !=3D ctx->proc_mbus_code) + continue; + if (n++ =3D=3D f->index) { + f->pixelformat =3D ope_output_fmts[i].fourcc; + return 0; + } + } + + return -EINVAL; +} + +static int ope_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fo= rmat *f) +{ + struct ope_ctx *ctx =3D ope_ctx_from_file(file); + struct ope_fmt_state *fs =3D &ctx->fmt_out; + struct v4l2_pix_format_mplane *pix =3D &f->fmt.pix_mp; + + pix->pixelformat =3D fs->fmt->fourcc; + pix->width =3D fs->width; + pix->height =3D fs->height; + pix->num_planes =3D 1; + pix->field =3D V4L2_FIELD_NONE; + pix->colorspace =3D fs->colorspace; + pix->xfer_func =3D fs->xfer_func; + pix->ycbcr_enc =3D fs->ycbcr_enc; + pix->quantization =3D fs->quantization; + pix->plane_fmt[0].bytesperline =3D fs->bytesperline; + pix->plane_fmt[0].sizeimage =3D fs->sizeimage; + + return 0; +} + +static int ope_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_= format *f) +{ + struct ope_ctx *ctx =3D ope_ctx_from_file(file); + + ope_fmt_try(ctx->ope, true, &f->fmt.pix_mp); + + return 0; +} + +static int ope_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fo= rmat *f) +{ + struct ope_ctx *ctx =3D ope_ctx_from_file(file); + const struct ope_fmt *fmt; + + if (vb2_is_busy(&ctx->vqs[OPE_QUEUE_DISP_OUT])) + return -EBUSY; + + fmt =3D ope_fmt_try(ctx->ope, true, &f->fmt.pix_mp); + + ctx->fmt_out.fmt =3D fmt; + ctx->fmt_out.width =3D f->fmt.pix_mp.width; + ctx->fmt_out.height =3D f->fmt.pix_mp.height; + ctx->fmt_out.bytesperline =3D f->fmt.pix_mp.plane_fmt[0].bytesperline; + ctx->fmt_out.sizeimage =3D f->fmt.pix_mp.plane_fmt[0].sizeimage; + ctx->fmt_out.colorspace =3D f->fmt.pix_mp.colorspace; + ctx->fmt_out.xfer_func =3D f->fmt.pix_mp.xfer_func; + ctx->fmt_out.ycbcr_enc =3D f->fmt.pix_mp.ycbcr_enc; + ctx->fmt_out.quantization =3D f->fmt.pix_mp.quantization; + /* Sync proc mbus code with selected pixel format */ + ctx->proc_mbus_code =3D fmt->mbus_code; + /* Reset scaler output to full crop (no scaling) */ + ctx->disp_compose.left =3D 0; + ctx->disp_compose.top =3D 0; + ctx->disp_compose.width =3D ctx->fmt_in.crop.width; + ctx->disp_compose.height =3D ctx->fmt_in.crop.height; + + return 0; +} + +/* Input crop */ +static int ope_g_selection(struct file *file, void *priv, + struct v4l2_selection *s) +{ + struct ope_ctx *ctx =3D ope_ctx_from_file(file); + + if (s->type !=3D V4L2_BUF_TYPE_VIDEO_OUTPUT && + s->type !=3D V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + return -EINVAL; + + switch (s->target) { + case V4L2_SEL_TGT_CROP: + s->r =3D ctx->fmt_in.crop; + return 0; + case V4L2_SEL_TGT_CROP_DEFAULT: + case V4L2_SEL_TGT_CROP_BOUNDS: + s->r.left =3D s->r.top =3D 0; + s->r.width =3D ctx->fmt_in.width; + s->r.height =3D ctx->fmt_in.height; + return 0; + } + + return -EINVAL; +} + +static int ope_s_selection(struct file *file, void *priv, + struct v4l2_selection *s) +{ + struct ope_ctx *ctx =3D ope_ctx_from_file(file); + + if (s->type !=3D V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type !=3D V4L2_BUF_TYPE= _VIDEO_OUTPUT_MPLANE) + return -EINVAL; + if (s->target !=3D V4L2_SEL_TGT_CROP) + return -EINVAL; + if (vb2_is_busy(&ctx->vqs[OPE_QUEUE_FRAME_IN])) + return -EBUSY; + + s->r.left =3D clamp_t(int, s->r.left, 0, (int)ctx->fmt_in.width - OPE_MIN= _W); + s->r.top =3D clamp_t(int, s->r.top, 0, (int)ctx->fmt_in.height - OPE_MIN= _H); + s->r.width =3D clamp(s->r.width, (unsigned int)OPE_MIN_W, + ctx->fmt_in.width - (unsigned int)s->r.left); + s->r.height =3D clamp(s->r.height, (unsigned int)OPE_MIN_H, + ctx->fmt_in.height - (unsigned int)s->r.top); + ctx->fmt_in.crop =3D s->r; + + return 0; +} + +static int ope_g_fmt_meta(struct file *file, void *priv, struct v4l2_forma= t *f) +{ + f->fmt.meta.dataformat =3D V4L2_META_FMT_QCOM_ISP_PARAMS; + f->fmt.meta.buffersize =3D v4l2_isp_params_buffer_size(CAMSS_PARAMS_MAX_P= AYLOAD); + + return 0; +} + +static int ope_enum_fmt_meta_out(struct file *file, void *priv, struct v4l= 2_fmtdesc *f) +{ + if (f->index > 0) + return -EINVAL; + + f->pixelformat =3D V4L2_META_FMT_QCOM_ISP_PARAMS; + + return 0; +} + +static int ope_g_parm(struct file *file, void *priv, struct v4l2_streampar= m *sp) +{ + struct ope_ctx *ctx =3D ope_ctx_from_file(file); + + if (!V4L2_TYPE_IS_OUTPUT(sp->type)) + return -EINVAL; + + sp->parm.output.capability =3D V4L2_CAP_TIMEPERFRAME; + sp->parm.output.timeperframe =3D ctx->fmt_in.timeperframe; + + return 0; +} + +static int ope_s_parm(struct file *file, void *priv, struct v4l2_streampar= m *sp) +{ + struct ope_ctx *ctx =3D ope_ctx_from_file(file); + struct v4l2_fract *tpf =3D &sp->parm.output.timeperframe; + + if (!V4L2_TYPE_IS_OUTPUT(sp->type)) + return -EINVAL; + + if (vb2_is_busy(&ctx->vqs[OPE_QUEUE_FRAME_IN])) + return -EBUSY; + + if (!tpf->denominator) + tpf->denominator =3D 1; + if (!tpf->numerator) + tpf->numerator =3D 1; + + ctx->fmt_in.timeperframe =3D *tpf; + ctx->framerate =3D tpf->denominator / tpf->numerator; + sp->parm.output.capability =3D V4L2_CAP_TIMEPERFRAME; + + ope_adjust_power(ctx->ope); + + return 0; +} + +static int ope_enum_framesizes(struct file *file, void *priv, struct v4l2_= frmsizeenum *fsize) +{ + unsigned int idx =3D ope_queue_idx_from_file(file); + const struct ope_fmt *fmts; + unsigned int n; + + if (idx =3D=3D OPE_QUEUE_FRAME_IN) { + fmts =3D ope_input_fmts; + n =3D ARRAY_SIZE(ope_input_fmts); + } else { + fmts =3D ope_output_fmts; + n =3D ARRAY_SIZE(ope_output_fmts); + } + + if (fsize->index > 0 || !ope_find_fmt(fmts, n, fsize->pixel_format)) + return -EINVAL; + + fsize->type =3D V4L2_FRMSIZE_TYPE_STEPWISE; + fsize->stepwise.min_width =3D OPE_MIN_W; + fsize->stepwise.max_width =3D OPE_MAX_W; + fsize->stepwise.step_width =3D 1; + fsize->stepwise.min_height =3D OPE_MIN_H; + fsize->stepwise.max_height =3D OPE_MAX_H; + fsize->stepwise.step_height =3D 1; + + return 0; +} + +static int ope_reqbufs(struct file *file, void *priv, struct v4l2_requestb= uffers *rb) +{ + struct ope_ctx *ctx =3D ope_ctx_from_file(file); + struct vb2_queue *vq =3D ope_vq_from_file(file, ctx); + int ret; + + if (!vq) + return -EINVAL; + + if (vb2_queue_is_busy(vq, file)) + return -EBUSY; + + ret =3D vb2_reqbufs(vq, rb); + if (!ret) + vq->owner =3D rb->count ? file->private_data : NULL; + + return ret; +} + +static int ope_querybuf(struct file *file, void *priv, struct v4l2_buffer = *buf) +{ + struct ope_ctx *ctx =3D ope_ctx_from_file(file); + struct vb2_queue *vq =3D ope_vq_from_file(file, ctx); + + return vq ? vb2_querybuf(vq, buf) : -EINVAL; +} + +static int ope_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) +{ + struct ope_ctx *ctx =3D ope_ctx_from_file(file); + struct video_device *vdev =3D video_devdata(file); + struct vb2_queue *vq =3D ope_vq_from_file(file, ctx); + + if (!vq) + return -EINVAL; + if (vb2_queue_is_busy(vq, file)) + return -EBUSY; + + return vb2_qbuf(vq, vdev->v4l2_dev->mdev, buf); +} + +static int ope_dqbuf(struct file *file, void *priv, struct v4l2_buffer *bu= f) +{ + struct ope_ctx *ctx =3D ope_ctx_from_file(file); + struct vb2_queue *vq =3D ope_vq_from_file(file, ctx); + + return vq ? vb2_dqbuf(vq, buf, file->f_flags & O_NONBLOCK) : -EINVAL; +} + +static int ope_prepare_buf(struct file *file, void *priv, struct v4l2_buff= er *buf) +{ + struct ope_ctx *ctx =3D ope_ctx_from_file(file); + struct video_device *vdev =3D video_devdata(file); + struct vb2_queue *vq =3D ope_vq_from_file(file, ctx); + + if (!vq) + return -EINVAL; + if (vb2_queue_is_busy(vq, file)) + return -EBUSY; + + return vb2_prepare_buf(vq, vdev->v4l2_dev->mdev, buf); +} + +static int ope_create_bufs(struct file *file, void *priv, struct v4l2_crea= te_buffers *create) +{ + struct ope_ctx *ctx =3D ope_ctx_from_file(file); + struct vb2_queue *vq =3D ope_vq_from_file(file, ctx); + int ret; + + if (!vq) + return -EINVAL; + if (vb2_queue_is_busy(vq, file)) + return -EBUSY; + ret =3D vb2_create_bufs(vq, create); + if (!ret && create->count) + vq->owner =3D file->private_data; + + return ret; +} + +static int ope_expbuf(struct file *file, void *priv, struct v4l2_exportbuf= fer *eb) +{ + struct ope_ctx *ctx =3D ope_ctx_from_file(file); + struct vb2_queue *vq =3D ope_vq_from_file(file, ctx); + + if (!vq) + return -EINVAL; + if (vb2_queue_is_busy(vq, file)) + return -EBUSY; + + return vb2_expbuf(vq, eb); +} + +static int ope_streamon(struct file *file, void *priv, enum v4l2_buf_type = type) +{ + struct ope_ctx *ctx =3D ope_ctx_from_file(file); + struct vb2_queue *vq =3D ope_vq_from_file(file, ctx); + + if (!vq) + return -EINVAL; + if (vb2_queue_is_busy(vq, file)) + return -EBUSY; + + return vb2_streamon(vq, type); +} + +static int ope_streamoff(struct file *file, void *priv, enum v4l2_buf_type= type) +{ + struct ope_ctx *ctx =3D ope_ctx_from_file(file); + struct vb2_queue *vq =3D ope_vq_from_file(file, ctx); + + if (!vq) + return -EINVAL; + + if (vb2_queue_is_busy(vq, file)) + return -EBUSY; + + camss_isp_sched_cancel(&ctx->ope->sched, &ctx->job); + + return vb2_streamoff(vq, type); +} + +/* -------- proc subdev ops -------- */ + +enum ope_proc_pad { + OPE_PROC_PAD_SINK_IN, + OPE_PROC_PAD_SINK_PAR, + OPE_PROC_PAD_SOURCE, + OPE_PROC_PADS_NUM, +}; + +static int ope_proc_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_sta= te *state, + struct v4l2_subdev_format *fmt) +{ + struct ope_ctx *ctx =3D container_of(sd->v4l2_dev, struct ope_dev, v4l2_d= ev)->shared_ctx; + + if (fmt->pad =3D=3D OPE_PROC_PAD_SOURCE) { + /* Source carries the scaler output (compose) size */ + fmt->format.width =3D ctx ? ctx->disp_compose.width : 640; + fmt->format.height =3D ctx ? ctx->disp_compose.height : 480; + fmt->format.code =3D ctx ? ctx->proc_mbus_code : MEDIA_BUS_FMT_YUYV8_1_5= X8; + fmt->format.field =3D V4L2_FIELD_NONE; + fmt->format.colorspace =3D V4L2_COLORSPACE_SRGB; + } else if (fmt->pad =3D=3D OPE_PROC_PAD_SINK_IN) { + fmt->format.width =3D ctx ? ctx->fmt_in.width : 640; + fmt->format.height =3D ctx ? ctx->fmt_in.height : 480; + fmt->format.code =3D ctx ? ctx->fmt_in.fmt->mbus_code : MEDIA_BUS_FMT_SR= GGB8_1X8; + fmt->format.field =3D V4L2_FIELD_NONE; + fmt->format.colorspace =3D V4L2_COLORSPACE_RAW; + } else { /* Params sink (pad1): no image format */ + fmt->format.width =3D 0; + fmt->format.height =3D 0; + fmt->format.code =3D MEDIA_BUS_FMT_FIXED; + fmt->format.field =3D V4L2_FIELD_NONE; + fmt->format.colorspace =3D V4L2_COLORSPACE_DEFAULT; + } + + return 0; +} + +static int ope_proc_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_sta= te *state, + struct v4l2_subdev_format *fmt) +{ + struct ope_dev *ope =3D container_of(sd->v4l2_dev, struct ope_dev, v4l2_d= ev); + struct ope_ctx *ctx =3D ope->shared_ctx; + + if (!ctx && fmt->which =3D=3D V4L2_SUBDEV_FORMAT_ACTIVE) + return -ENODEV; + + if (fmt->pad !=3D OPE_PROC_PAD_SOURCE) + return ope_proc_get_fmt(sd, state, fmt); + + unsigned int i; + + /* Validate mbus code: must match one of the output formats */ + for (i =3D 0; i < ARRAY_SIZE(ope_output_fmts); i++) + if (ope_output_fmts[i].mbus_code =3D=3D fmt->format.code) + goto valid; + + fmt->format.code =3D MEDIA_BUS_FMT_YUYV8_1_5X8; + +valid: + /* Clamp to crop size: OPE can only downscale */ + fmt->format.width =3D clamp(fmt->format.width, (unsigned int)OPE_MIN_W, + ctx->fmt_in.crop.width); + fmt->format.height =3D clamp(fmt->format.height, (unsigned int)OPE_MIN_H, + ctx->fmt_in.crop.height); + fmt->format.field =3D V4L2_FIELD_NONE; + fmt->format.colorspace =3D V4L2_COLORSPACE_SRGB; + + if (fmt->which =3D=3D V4L2_SUBDEV_FORMAT_ACTIVE) { + ctx->proc_mbus_code =3D fmt->format.code; + ctx->disp_compose.width =3D fmt->format.width; + ctx->disp_compose.height =3D fmt->format.height; + /* Clip compose origin if it no longer fits */ + ctx->disp_compose.left =3D clamp_t(int, ctx->disp_compose.left, 0, + (int)ctx->fmt_out.width - + (int)ctx->disp_compose.width); + ctx->disp_compose.top =3D clamp_t(int, ctx->disp_compose.top, 0, + (int)ctx->fmt_out.height - + (int)ctx->disp_compose.height); + } + + return 0; +} + +static int ope_proc_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_mbus_code_enum *code) +{ + unsigned int n =3D 0; + + if (code->pad !=3D OPE_PROC_PAD_SOURCE) + return -EINVAL; + + /* Enumerate unique mbus codes from output format table */ + for (unsigned int i =3D 0; i < ARRAY_SIZE(ope_output_fmts); i++) { + u32 mc =3D ope_output_fmts[i].mbus_code; + bool seen =3D false; + + for (unsigned int j =3D 0; j < i; j++) { + if (ope_output_fmts[j].mbus_code =3D=3D mc) { + seen =3D true; + break; + } + } + + if (seen) + continue; + + if (n++ =3D=3D code->index) { + code->code =3D mc; + return 0; + } + } + + return -EINVAL; +} + +static int ope_proc_init_state(struct v4l2_subdev *sd, struct v4l2_subdev_= state *state) +{ + unsigned int pad; + + for (pad =3D 0; pad < OPE_PROC_PADS_NUM; pad++) { + struct v4l2_subdev_format fmt =3D { + .which =3D V4L2_SUBDEV_FORMAT_TRY, + .pad =3D pad + }; + int ret; + + ret =3D ope_proc_get_fmt(sd, state, &fmt); + if (ret) + return ret; + + *v4l2_subdev_state_get_format(state, pad) =3D fmt.format; + } + + return 0; +} + +static int ope_proc_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_selection *sel) +{ + struct ope_ctx *ctx =3D container_of(sd->v4l2_dev, struct ope_dev, v4l2_d= ev)->shared_ctx; + + if (sel->pad !=3D OPE_PROC_PAD_SINK_IN) + goto source; + + switch (sel->target) { + case V4L2_SEL_TGT_CROP: + sel->r =3D ctx ? ctx->fmt_in.crop : (struct v4l2_rect){ 0, 0, 640, 480 }; + return 0; + case V4L2_SEL_TGT_CROP_DEFAULT: + case V4L2_SEL_TGT_CROP_BOUNDS: + sel->r.left =3D sel->r.top =3D 0; + sel->r.width =3D ctx ? ctx->fmt_in.width : 640; + sel->r.height =3D ctx ? ctx->fmt_in.height : 480; + return 0; + } + +source: + if (sel->pad !=3D OPE_PROC_PAD_SOURCE) + return -EINVAL; + + switch (sel->target) { + case V4L2_SEL_TGT_COMPOSE: + sel->r =3D ctx ? ctx->disp_compose : (struct v4l2_rect){ 0, 0, 640, 480 = }; + return 0; + case V4L2_SEL_TGT_COMPOSE_DEFAULT: + sel->r.left =3D sel->r.top =3D 0; + sel->r.width =3D ctx ? ctx->fmt_in.crop.width : 640; + sel->r.height =3D ctx ? ctx->fmt_in.crop.height : 480; + return 0; + case V4L2_SEL_TGT_COMPOSE_BOUNDS: + sel->r.left =3D sel->r.top =3D 0; + sel->r.width =3D ctx ? ctx->fmt_out.width : 640; + sel->r.height =3D ctx ? ctx->fmt_out.height : 480; + return 0; + } + + return -EINVAL; +} + +static int ope_proc_set_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_selection *sel) +{ + struct ope_dev *ope =3D container_of(sd->v4l2_dev, struct ope_dev, v4l2_d= ev); + struct ope_ctx *ctx =3D ope->shared_ctx; + + if (!ctx) + return -ENODEV; + + if (sel->pad =3D=3D OPE_PROC_PAD_SINK_IN) { + if (sel->target !=3D V4L2_SEL_TGT_CROP) + return -EINVAL; + sel->r.left =3D clamp_t(int, sel->r.left, 0, + (int)ctx->fmt_in.width - OPE_MIN_W); + sel->r.top =3D clamp_t(int, sel->r.top, 0, + (int)ctx->fmt_in.height - OPE_MIN_H); + sel->r.width =3D clamp(sel->r.width, (unsigned int)OPE_MIN_W, + ctx->fmt_in.width - (unsigned int)sel->r.left); + sel->r.height =3D clamp(sel->r.height, (unsigned int)OPE_MIN_H, + ctx->fmt_in.height - (unsigned int)sel->r.top); + if (sel->which =3D=3D V4L2_SUBDEV_FORMAT_ACTIVE) + ctx->fmt_in.crop =3D sel->r; + return 0; + } + + if (sel->pad =3D=3D OPE_PROC_PAD_SOURCE) { + if (sel->target !=3D V4L2_SEL_TGT_COMPOSE) + return -EINVAL; + /* Scale size: clamp to crop (downscale only) */ + sel->r.width =3D clamp(sel->r.width, (unsigned int)OPE_MIN_W, + ctx->fmt_in.crop.width); + sel->r.height =3D clamp(sel->r.height, (unsigned int)OPE_MIN_H, + ctx->fmt_in.crop.height); + /* Placement: clamp origin to output buffer bounds */ + sel->r.left =3D clamp_t(int, sel->r.left, 0, + (int)ctx->fmt_out.width - (int)sel->r.width); + sel->r.top =3D clamp_t(int, sel->r.top, 0, + (int)ctx->fmt_out.height - (int)sel->r.height); + if (sel->which =3D=3D V4L2_SUBDEV_FORMAT_ACTIVE) + ctx->disp_compose =3D sel->r; + return 0; + } + + return -EINVAL; +} + +static const struct v4l2_subdev_pad_ops ope_proc_pad_ops =3D { + .get_fmt =3D ope_proc_get_fmt, + .set_fmt =3D ope_proc_set_fmt, + .enum_mbus_code =3D ope_proc_enum_mbus_code, + .get_selection =3D ope_proc_get_selection, + .set_selection =3D ope_proc_set_selection, +}; + +static const struct v4l2_subdev_internal_ops ope_proc_internal_ops =3D { + .init_state =3D ope_proc_init_state, +}; + +static const struct v4l2_subdev_ops ope_proc_ops =3D { + .pad =3D &ope_proc_pad_ops, +}; + +/* -------- disp subdev ops -------- */ + +enum ope_disp_pad { + OPE_DISP_PAD_SINK, + OPE_DISP_PAD_SOURCE, + OPE_DISP_PADS_NUM, +}; + +static int ope_disp_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_format *fmt) +{ + struct ope_ctx *ctx =3D container_of(sd->v4l2_dev, + struct ope_dev, v4l2_dev)->shared_ctx; + u32 mbus =3D ctx ? ctx->proc_mbus_code : MEDIA_BUS_FMT_YUYV8_1_5X8; + + /* Both sink and source reflect the scaler output (compose) size */ + fmt->format.width =3D ctx ? ctx->disp_compose.width : 640; + fmt->format.height =3D ctx ? ctx->disp_compose.height : 480; + fmt->format.code =3D mbus; + fmt->format.field =3D V4L2_FIELD_NONE; + fmt->format.colorspace =3D (fmt->pad =3D=3D OPE_DISP_PAD_SOURCE && ctx) + ? ctx->fmt_out.colorspace : V4L2_COLORSPACE_SRGB; + + return 0; +} + +static int ope_disp_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_format *fmt) +{ + struct ope_dev *ope =3D container_of(sd->v4l2_dev, struct ope_dev, v4l2_d= ev); + struct ope_ctx *ctx =3D ope->shared_ctx; + + if (!ctx) + return -ENODEV; + + /* Both pads are read-only: size is set via ope_proc source S_FMT */ + return ope_disp_get_fmt(sd, state, fmt); +} + + +static int ope_disp_init_state(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state) +{ + unsigned int pad; + + for (pad =3D 0; pad < OPE_DISP_PADS_NUM; pad++) { + struct v4l2_subdev_format fmt =3D { + .which =3D V4L2_SUBDEV_FORMAT_TRY, + fmt.pad =3D pad + }; + int ret; + + ret =3D ope_disp_get_fmt(sd, state, &fmt); + if (ret) + return ret; + + *v4l2_subdev_state_get_format(state, pad) =3D fmt.format; + } + + return 0; +} + +static const struct v4l2_subdev_pad_ops ope_disp_pad_ops =3D { + .get_fmt =3D ope_disp_get_fmt, + .set_fmt =3D ope_disp_set_fmt, +}; + +static const struct v4l2_subdev_internal_ops ope_disp_internal_ops =3D { + .init_state =3D ope_disp_init_state, +}; + +static const struct v4l2_subdev_ops ope_disp_ops =3D { + .pad =3D &ope_disp_pad_ops, +}; + +/* -------- disp-output video ops -------- */ + +static int ope_disp_output_link_validate(struct media_link *link) +{ + struct video_device *vdev =3D media_entity_to_video_device(link->sink->en= tity); + struct v4l2_subdev *sd =3D media_entity_to_v4l2_subdev(link->source->enti= ty); + struct ope_ctx *ctx =3D video_get_drvdata(vdev); + struct v4l2_subdev_format sd_fmt =3D { + .which =3D V4L2_SUBDEV_FORMAT_ACTIVE, + .pad =3D link->source->index, + }; + int ret; + + if (!ctx) + return 0; + + ret =3D v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_fmt); + if (ret) + return ret; + + if (ctx->fmt_out.fmt->mbus_code !=3D sd_fmt.format.code) { + dev_dbg(ctx->ope->dev, "link validate: mbus 0x%04x incompatible with %.4= s\n", + sd_fmt.format.code, (char *)&ctx->fmt_out.fmt->fourcc); + return -EPIPE; + } + + return 0; +} + +static const struct media_entity_operations ope_disp_output_entity_ops =3D= { + .link_validate =3D ope_disp_output_link_validate, +}; + +static const struct v4l2_ioctl_ops ope_video_ioctl_ops =3D { + .vidioc_querycap =3D ope_querycap, + .vidioc_enum_fmt_vid_out =3D ope_enum_fmt_vid_out, + .vidioc_g_fmt_vid_out_mplane =3D ope_g_fmt_vid_out, + .vidioc_try_fmt_vid_out_mplane =3D ope_try_fmt_vid_out, + .vidioc_s_fmt_vid_out_mplane =3D ope_s_fmt_vid_out, + .vidioc_enum_fmt_vid_cap =3D ope_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap_mplane =3D ope_g_fmt_vid_cap, + .vidioc_try_fmt_vid_cap_mplane =3D ope_try_fmt_vid_cap, + .vidioc_s_fmt_vid_cap_mplane =3D ope_s_fmt_vid_cap, + .vidioc_g_selection =3D ope_g_selection, + .vidioc_s_selection =3D ope_s_selection, + .vidioc_enum_framesizes =3D ope_enum_framesizes, + .vidioc_g_parm =3D ope_g_parm, + .vidioc_s_parm =3D ope_s_parm, + .vidioc_reqbufs =3D ope_reqbufs, + .vidioc_querybuf =3D ope_querybuf, + .vidioc_qbuf =3D ope_qbuf, + .vidioc_dqbuf =3D ope_dqbuf, + .vidioc_prepare_buf =3D ope_prepare_buf, + .vidioc_create_bufs =3D ope_create_bufs, + .vidioc_expbuf =3D ope_expbuf, + .vidioc_streamon =3D ope_streamon, + .vidioc_streamoff =3D ope_streamoff, + .vidioc_subscribe_event =3D v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event =3D v4l2_event_unsubscribe, +}; + +static const struct v4l2_ioctl_ops ope_meta_ioctl_ops =3D { + .vidioc_querycap =3D ope_querycap, + .vidioc_enum_fmt_meta_out =3D ope_enum_fmt_meta_out, + .vidioc_g_fmt_meta_out =3D ope_g_fmt_meta, + .vidioc_s_fmt_meta_out =3D ope_g_fmt_meta, + .vidioc_try_fmt_meta_out =3D ope_g_fmt_meta, + .vidioc_reqbufs =3D ope_reqbufs, + .vidioc_querybuf =3D ope_querybuf, + .vidioc_qbuf =3D ope_qbuf, + .vidioc_dqbuf =3D ope_dqbuf, + .vidioc_prepare_buf =3D ope_prepare_buf, + .vidioc_create_bufs =3D ope_create_bufs, + .vidioc_expbuf =3D ope_expbuf, + .vidioc_streamon =3D ope_streamon, + .vidioc_streamoff =3D ope_streamoff, +}; + +/* -------- File/Context ops -------- */ + +static struct ope_ctx *ope_ctx_create(struct ope_dev *ope) +{ + struct ope_ctx *ctx; + unsigned int i; + int ret; + + ctx =3D kvzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return ERR_PTR(-ENOMEM); + + ctx->ope =3D ope; + + mutex_init(&ctx->vbq_lock); + + ctx->bufq =3D camss_isp_bufq_init(OPE_QUEUE_COUNT); + if (IS_ERR(ctx->bufq)) { + ret =3D PTR_ERR(ctx->bufq); + kvfree(ctx); + return ERR_PTR(ret); + } + + camss_isp_job_init(&ctx->job, &ope_job_ops, ctx); + ctx->config =3D ope_default_config; + + /* Default input format */ + ctx->fmt_in.fmt =3D &ope_input_fmts[0]; + ctx->fmt_in.width =3D OPE_MIN_W; + ctx->fmt_in.height =3D OPE_MIN_H; + ctx->fmt_in.bytesperline =3D OPE_MIN_W * ope_input_fmts[0].depth / 8; + ctx->fmt_in.sizeimage =3D ctx->fmt_in.bytesperline * OPE_MIN_H; + ctx->fmt_in.colorspace =3D V4L2_COLORSPACE_RAW; + ctx->fmt_in.crop =3D (struct v4l2_rect){ 0, 0, OPE_MIN_W, OPE_MIN_H }; + ctx->fmt_in.timeperframe.numerator =3D 1; + ctx->fmt_in.timeperframe.denominator =3D DEFAULT_FRAMERATE; + + /* Default output format */ + ctx->fmt_out.fmt =3D &ope_output_fmts[0]; + ctx->fmt_out.width =3D OPE_MIN_W; + ctx->fmt_out.height =3D OPE_MIN_H; + ctx->fmt_out.bytesperline =3D OPE_MIN_W; + ctx->fmt_out.sizeimage =3D (u64)ope_output_fmts[0].depth * OPE_MIN_W * = OPE_MIN_H / 8; + ctx->fmt_out.colorspace =3D V4L2_COLORSPACE_SRGB; + ctx->disp_compose =3D (struct v4l2_rect){ 0, 0, OPE_MIN_W, OPE_MIN_H }; + ctx->proc_mbus_code =3D ope_output_fmts[0].mbus_code; + + for (i =3D 0; i < OPE_QUEUE_COUNT; i++) { + ret =3D ope_init_vq(ctx, i); + if (ret) { + while (i--) + vb2_queue_release(&ctx->vqs[i]); + camss_isp_bufq_release(ctx->bufq); + kvfree(ctx); + return ERR_PTR(ret); + } + } + + INIT_LIST_HEAD(&ctx->list); + list_add(&ctx->list, &ope->ctx_list); + ope->shared_ctx =3D ctx; + + return ctx; +} + +static void ope_ctx_destroy(struct ope_ctx *ctx) +{ + struct ope_dev *ope =3D ctx->ope; + unsigned int i; + + list_del(&ctx->list); + camss_isp_sched_cancel(&ope->sched, &ctx->job); + for (i =3D 0; i < OPE_QUEUE_COUNT; i++) + vb2_queue_release(&ctx->vqs[i]); + camss_isp_bufq_release(ctx->bufq); + mutex_destroy(&ctx->vbq_lock); + kvfree(ctx); +} + +static int ope_open(struct file *file) +{ + struct video_device *vdev =3D video_devdata(file); + struct ope_dev *ope =3D container_of(vdev->v4l2_dev, struct ope_dev, v4l2= _dev); + struct ope_ctx *ctx; + struct v4l2_fh *fh; + int ret =3D 0; + + fh =3D kzalloc(sizeof(*fh), GFP_KERNEL); + if (!fh) + return -ENOMEM; + + if (mutex_lock_interruptible(&ope->mutex)) { + kfree(fh); + return -ERESTARTSYS; + } + + /* + * For now, only a single shared context is supported, + * until media multi-context support is available. + */ + if (!ope->shared_ctx) { + ctx =3D ope_ctx_create(ope); + if (IS_ERR(ctx)) { + ret =3D PTR_ERR(ctx); + goto unlock; + } + } else { + ctx =3D ope->shared_ctx; + } + + v4l2_fh_init(fh, vdev); + v4l2_fh_add(fh, file); + ope->open_count++; + +unlock: + if (ret) + kfree(fh); + mutex_unlock(&ope->mutex); + return ret; +} + +static int ope_release(struct file *file) +{ + struct v4l2_fh *fh =3D file_to_v4l2_fh(file); + struct ope_ctx *ctx =3D ope_ctx_from_file(file); + struct ope_dev *ope =3D ctx->ope; + + v4l2_fh_del(fh, file); + v4l2_fh_exit(fh); + kfree(fh); + + mutex_lock(&ope->mutex); + + if (--ope->open_count =3D=3D 0) { + ope->shared_ctx =3D NULL; + mutex_unlock(&ope->mutex); + ope_ctx_destroy(ctx); + } else { + mutex_unlock(&ope->mutex); + } + + return 0; +} + +static __poll_t ope_poll(struct file *file, poll_table *wait) +{ + unsigned int idx =3D ope_queue_idx_from_file(file); + struct ope_ctx *ctx =3D ope_ctx_from_file(file); + struct v4l2_fh *fh =3D file_to_v4l2_fh(file); + struct vb2_queue *vq; + unsigned long flags; + __poll_t rc =3D 0; + + if (idx >=3D OPE_QUEUE_COUNT) + return EPOLLERR; + + vq =3D &ctx->vqs[idx]; + + poll_wait(file, &vq->done_wq, wait); + poll_wait(file, &fh->wait, wait); + + spin_lock_irqsave(&vq->done_lock, flags); + if (!list_empty(&vq->done_list)) { + if (V4L2_TYPE_IS_OUTPUT(vq->type)) + rc |=3D EPOLLOUT | EPOLLWRNORM; + else + rc |=3D EPOLLIN | EPOLLRDNORM; + } + spin_unlock_irqrestore(&vq->done_lock, flags); + + if (v4l2_event_pending(fh)) + rc |=3D EPOLLPRI; + + return rc; +} + +static int ope_mmap(struct file *file, struct vm_area_struct *vma) +{ + unsigned int idx =3D ope_queue_idx_from_file(file); + struct ope_ctx *ctx =3D ope_ctx_from_file(file); + + if (idx >=3D OPE_QUEUE_COUNT) + return -EINVAL; + + return vb2_mmap(&ctx->vqs[idx], vma); +} + +static const struct v4l2_file_operations ope_fops =3D { + .owner =3D THIS_MODULE, + .open =3D ope_open, + .release =3D ope_release, + .poll =3D ope_poll, + .unlocked_ioctl =3D video_ioctl2, + .mmap =3D ope_mmap, +}; + +/* Pipeline descriptor */ +static const struct camss_isp_entity_desc ope_entity_descs[] =3D { + [OPE_ENTITY_FRAME_IN] =3D { + .name =3D "ope_input", + .obj_type =3D MEDIA_ENTITY_TYPE_VIDEO_DEVICE, + .function =3D MEDIA_ENT_F_IO_V4L, + .vdev.caps =3D V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_STREAMING, + .vdev.drvdata =3D (void *)(uintptr_t)OPE_QUEUE_FRAME_IN, + .vdev.fops =3D &ope_fops, + .vdev.ioctl_ops =3D &ope_video_ioctl_ops, + .pads =3D (const struct camss_isp_pad_desc[]) { + { MEDIA_PAD_FL_SOURCE, OPE_ENTITY_PROC, OPE_PROC_PAD_SINK_IN, 0 }, + { } + }, + }, + [OPE_ENTITY_DISP_OUT] =3D { + .name =3D "ope_disp_output", + .obj_type =3D MEDIA_ENTITY_TYPE_VIDEO_DEVICE, + .function =3D MEDIA_ENT_F_IO_V4L, + .vdev.caps =3D V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING, + .vdev.drvdata =3D (void *)(uintptr_t)OPE_QUEUE_DISP_OUT, + .vdev.fops =3D &ope_fops, + .vdev.ioctl_ops =3D &ope_video_ioctl_ops, + .vdev.entity_ops =3D &ope_disp_output_entity_ops, + .pads =3D (const struct camss_isp_pad_desc[]) { + { MEDIA_PAD_FL_SINK, OPE_ENTITY_DISP, OPE_DISP_PAD_SOURCE, 0 }, + { } + }, + }, + [OPE_ENTITY_PARAMS] =3D { + .name =3D "ope_params", + .obj_type =3D MEDIA_ENTITY_TYPE_VIDEO_DEVICE, + .function =3D MEDIA_ENT_F_IO_V4L, + .vdev.caps =3D V4L2_CAP_META_OUTPUT | V4L2_CAP_STREAMING, + .vdev.drvdata =3D (void *)(uintptr_t)OPE_QUEUE_PARAMS, + .vdev.fops =3D &ope_fops, + .vdev.ioctl_ops =3D &ope_meta_ioctl_ops, + .pads =3D (const struct camss_isp_pad_desc[]) { + { MEDIA_PAD_FL_SOURCE, OPE_ENTITY_PROC, OPE_PROC_PAD_SINK_PAR, 0 }, + { } + }, + }, + [OPE_ENTITY_PROC] =3D { + .name =3D "ope_proc", + .obj_type =3D MEDIA_ENTITY_TYPE_V4L2_SUBDEV, + .function =3D MEDIA_ENT_F_PROC_VIDEO_ISP, + .subdev.ops =3D &ope_proc_ops, + .subdev.internal_ops =3D &ope_proc_internal_ops, + .pads =3D (const struct camss_isp_pad_desc[]) { + { MEDIA_PAD_FL_SINK, OPE_ENTITY_FRAME_IN, 0, 0 }, + { MEDIA_PAD_FL_SINK, OPE_ENTITY_PARAMS, 0, 0 }, + { MEDIA_PAD_FL_SOURCE, OPE_ENTITY_DISP, OPE_DISP_PAD_SINK, MEDIA_LNK_FL= _ENABLED }, + { } + }, + }, + [OPE_ENTITY_DISP] =3D { + .name =3D "ope_disp", + .obj_type =3D MEDIA_ENTITY_TYPE_V4L2_SUBDEV, + .function =3D MEDIA_ENT_F_PROC_VIDEO_SCALER, + .subdev.ops =3D &ope_disp_ops, + .subdev.internal_ops =3D &ope_disp_internal_ops, + .pads =3D (const struct camss_isp_pad_desc[]) { + { MEDIA_PAD_FL_SINK, OPE_ENTITY_PROC, OPE_PROC_PAD_SOURCE, 0 }, + { MEDIA_PAD_FL_SOURCE, OPE_ENTITY_DISP_OUT, 0, 0 }, + { } + }, + }, +}; + +static int ope_v4l2_init(struct ope_dev *ope) +{ + int ret; + + mutex_init(&ope->mutex); + INIT_LIST_HEAD(&ope->ctx_list); + camss_isp_sched_init(&ope->sched); + + ope->mdev.dev =3D ope->dev; + strscpy(ope->mdev.model, OPE_NAME, sizeof(ope->mdev.model)); + media_device_init(&ope->mdev); + ope->v4l2_dev.mdev =3D &ope->mdev; + + ret =3D v4l2_device_register(ope->dev, &ope->v4l2_dev); + if (ret) + goto err_mdev_cleanup; + + ret =3D media_device_register(&ope->mdev); + if (ret) + goto err_v4l2; + + ope->pipeline =3D camss_isp_pipeline_alloc(OPE_ENTITY_COUNT); + if (IS_ERR(ope->pipeline)) { + ret =3D PTR_ERR(ope->pipeline); + goto err_media; + } + + ret =3D camss_isp_pipeline_register(ope->pipeline, &ope->v4l2_dev, + ope_entity_descs, ARRAY_SIZE(ope_entity_descs)); + if (ret) { + camss_isp_pipeline_free(ope->pipeline); + ope->pipeline =3D NULL; + goto err_media; + } + + ope->pipeline->drv_priv =3D ope; + return 0; + +err_media: + media_device_unregister(&ope->mdev); +err_v4l2: + v4l2_device_unregister(&ope->v4l2_dev); +err_mdev_cleanup: + media_device_cleanup(&ope->mdev); + return ret; +} + +static void ope_v4l2_cleanup(struct ope_dev *ope) +{ + if (ope->pipeline) { + camss_isp_pipeline_unregister(ope->pipeline); + camss_isp_pipeline_free(ope->pipeline); + ope->pipeline =3D NULL; + } + media_device_unregister(&ope->mdev); + v4l2_device_unregister(&ope->v4l2_dev); + media_device_cleanup(&ope->mdev); + camss_isp_sched_destroy(&ope->sched); +} + +static int ope_soft_reset(struct ope_dev *ope) +{ + u32 version; + int ret; + + ret =3D pm_runtime_resume_and_get(ope->dev); + if (ret) + return dev_err_probe(ope->dev, ret, "resume failed\n"); + + version =3D ope_read(ope, OPE_TOP_HW_VERSION); + dev_dbg(ope->dev, "HW version %u.%u.%u\n", + (u32)FIELD_GET(OPE_TOP_HW_VERSION_GEN, version), + (u32)FIELD_GET(OPE_TOP_HW_VERSION_REV, version), + (u32)FIELD_GET(OPE_TOP_HW_VERSION_STEP, version)); + + reinit_completion(&ope->reset_complete); + ope_write(ope, OPE_TOP_RESET_CMD, OPE_TOP_RESET_CMD_SW); + + if (!wait_for_completion_timeout(&ope->reset_complete, + msecs_to_jiffies(OPE_RESET_TIMEOUT_MS))) { + dev_err(ope->dev, "Reset timeout\n"); + pm_runtime_put(ope->dev); + return -ETIMEDOUT; + } + + pm_runtime_put(ope->dev); + + return 0; +} + +static int ope_init_power(struct ope_dev *ope) +{ + struct dev_pm_domain_list *pmdomains; + struct device *dev =3D ope->dev; + int ret; + + ope->icc_data =3D devm_of_icc_get(dev, "data"); + if (IS_ERR(ope->icc_data)) + return dev_err_probe(dev, PTR_ERR(ope->icc_data), + "failed to get interconnect data path\n"); + + ope->icc_config =3D devm_of_icc_get(dev, "config"); + if (IS_ERR(ope->icc_config)) + return dev_err_probe(dev, PTR_ERR(ope->icc_config), + "failed to get interconnect config path\n"); + + devm_pm_domain_attach_list(dev, NULL, &pmdomains); + + ret =3D devm_pm_opp_set_clkname(dev, "core"); + if (ret) + return ret; + + ret =3D devm_pm_opp_of_add_table(dev); + if (ret && ret !=3D -ENODEV) + return dev_err_probe(dev, ret, "invalid OPP table\n"); + + ret =3D devm_pm_runtime_enable(dev); + if (ret) + return ret; + + ret =3D devm_pm_clk_create(dev); + if (ret) + return ret; + + ret =3D of_pm_clk_add_clks(dev); + if (ret < 0) + return ret; + + return 0; +} + +static int ope_init_mmio(struct ope_dev *ope) +{ + struct platform_device *pdev =3D to_platform_device(ope->dev); + + ope->base =3D devm_platform_ioremap_resource_byname(pdev, "top"); + if (IS_ERR(ope->base)) + return PTR_ERR(ope->base); + + ope->base_rd =3D devm_platform_ioremap_resource_byname(pdev, "bus_read"); + if (IS_ERR(ope->base_rd)) + return PTR_ERR(ope->base_rd); + + ope->base_wr =3D devm_platform_ioremap_resource_byname(pdev, "bus_write"); + if (IS_ERR(ope->base_wr)) + return PTR_ERR(ope->base_wr); + + ope->base_pp =3D devm_platform_ioremap_resource_byname(pdev, "pipeline"); + if (IS_ERR(ope->base_pp)) + return PTR_ERR(ope->base_pp); + + return 0; +} + +static int ope_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct ope_dev *ope; + int ret, irq; + + ope =3D devm_kzalloc(dev, sizeof(*ope), GFP_KERNEL); + if (!ope) + return -ENOMEM; + + ope->dev =3D dev; + init_completion(&ope->reset_complete); + + ret =3D dma_set_mask(dev, DMA_BIT_MASK(32)); + if (ret) + return dev_err_probe(dev, ret, "Failed to set DMA mask\n"); + + ret =3D ope_init_power(ope); + if (ret) + return dev_err_probe(dev, ret, "Power init failed\n"); + + ret =3D ope_init_mmio(ope); + if (ret) + return dev_err_probe(dev, ret, "MMIO init failed\n"); + + irq =3D platform_get_irq(pdev, 0); + if (irq < 0) + return dev_err_probe(dev, irq, "Unable to get IRQ\n"); + + ret =3D devm_request_irq(dev, irq, ope_irq, 0, "camss-ope", ope); + if (ret < 0) + return dev_err_probe(dev, ret, "Requesting IRQ failed\n"); + + ret =3D ope_soft_reset(ope); + if (ret) + return ret; + + ret =3D ope_v4l2_init(ope); + if (ret) + return dev_err_probe(dev, ret, "V4L2 init failed\n"); + + platform_set_drvdata(pdev, ope); + + return 0; +} + +static void ope_remove(struct platform_device *pdev) +{ + struct ope_dev *ope =3D platform_get_drvdata(pdev); + + ope_v4l2_cleanup(ope); +} + +static const struct of_device_id ope_dt_ids[] =3D { + { .compatible =3D "qcom,qcm2290-camss-ope" }, + { }, +}; +MODULE_DEVICE_TABLE(of, ope_dt_ids); + +static const struct dev_pm_ops ope_pm_ops =3D { + SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL) +}; + +static struct platform_driver ope_driver =3D { + .probe =3D ope_probe, + .remove =3D ope_remove, + .driver =3D { + .name =3D OPE_NAME, + .of_match_table =3D ope_dt_ids, + .pm =3D &ope_pm_ops, + }, +}; + +module_platform_driver(ope_driver); + +MODULE_DESCRIPTION("CAMSS Offline Processing Engine"); +MODULE_AUTHOR("Loic Poulain "); +MODULE_LICENSE("GPL"); +/* Downscaler fixed-point helpers */ diff --git a/drivers/media/platform/qcom/camss/camss-isp-pipeline.c b/drive= rs/media/platform/qcom/camss/camss-isp-pipeline.c index 8e44bedb0a41e3cf4fc7e3a138c1f48854f5efc8..625e6a65137fa980fb1a8c2b8a8= 132623f5b7b62 100644 --- a/drivers/media/platform/qcom/camss/camss-isp-pipeline.c +++ b/drivers/media/platform/qcom/camss/camss-isp-pipeline.c @@ -194,6 +194,8 @@ static int isp_register_vdev(struct camss_isp_pipeline_= entity *slot, vdev->fops =3D desc->vdev.fops; if (desc->vdev.ioctl_ops) vdev->ioctl_ops =3D desc->vdev.ioctl_ops; + if (desc->vdev.entity_ops) + vdev->entity.ops =3D desc->vdev.entity_ops; =20 vdev->entity.obj_type =3D MEDIA_ENTITY_TYPE_VIDEO_DEVICE; vdev->entity.function =3D desc->function ? desc->function : MEDIA_ENT_F_I= O_V4L; @@ -222,6 +224,10 @@ static int isp_register_subdev(struct camss_isp_pipeli= ne_entity *slot, strscpy(sd->name, desc->name, sizeof(sd->name)); sd->entity.function =3D desc->function ? desc->function : MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN; + /* Create a /dev/v4l-subdevN node so userspace can query pad formats */ + sd->flags |=3D V4L2_SUBDEV_FL_HAS_DEVNODE; + if (desc->subdev.internal_ops) + sd->internal_ops =3D desc->subdev.internal_ops; =20 ret =3D media_entity_pads_init(&sd->entity, slot->num_pads, slot->pads); if (ret) @@ -349,6 +355,11 @@ int camss_isp_pipeline_register(struct camss_isp_pipel= ine *pipeline, } } =20 + /* Create /dev/v4l-subdevN nodes for all registered subdevs */ + ret =3D v4l2_device_register_subdev_nodes(v4l2_dev); + if (ret) + goto err_unregister; + return 0; =20 err_unregister: diff --git a/drivers/media/platform/qcom/camss/camss-isp-pipeline.h b/drive= rs/media/platform/qcom/camss/camss-isp-pipeline.h index 5dfa32dcafc0a944ca2c160fb5846a2c73214acc..06654948e1eceb7e35aedcabcd8= ac3bd92280018 100644 --- a/drivers/media/platform/qcom/camss/camss-isp-pipeline.h +++ b/drivers/media/platform/qcom/camss/camss-isp-pipeline.h @@ -76,10 +76,12 @@ struct camss_isp_entity_desc { void *drvdata; const struct v4l2_file_operations *fops; const struct v4l2_ioctl_ops *ioctl_ops; + const struct media_entity_operations *entity_ops; } vdev; /* MEDIA_ENTITY_TYPE_V4L2_SUBDEV */ struct { const struct v4l2_subdev_ops *ops; + const struct v4l2_subdev_internal_ops *internal_ops; } subdev; }; }; --=20 2.34.1 From nobody Fri Jun 12 14:18:25 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 984623D522C for ; Thu, 7 May 2026 22:50:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194250; cv=none; b=TgWVKl9TPtnCjXytudHICb7MrL7zK3O21VFc2mrW2S0jqvME9dwKJiq8huVdYa+yI4xam2q9N04fF0n/26XL3Bnw1wcs5cMclMqjcGmskMBpiE0mOYdRA7fQVZq4RSNDWRxh/2AIomNcOo1OSQNaW1MX03xjpBorBTR8g0ZzLpc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194250; c=relaxed/simple; bh=LHNi+12cboraoNbCzpt/W6iWtyjIVws+K21hs0+sClI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=kd8FmcCeGj82nPrB/VrTK3OaOrrhcNMh3X/K3q1n3h0yNvIcDp/Sq6AnDwgDq5V8No4l4pZNxGYJPbGzvaoT8Eko3UrnUiH1C1D6Fr+Jclz9jgQdn7CJkfYw0X21E3UunaLgptzbabHwe1AydZqpBU6U1eKwi0nFGDwMZloNYiI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=HQngIrc/; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=Nsma7KOR; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="HQngIrc/"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="Nsma7KOR" Received: from pps.filterd (m0279870.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 647JrFFi2198887 for ; Thu, 7 May 2026 22:50:47 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= edJue4htj1/6yA330XjSk4emEsskraGJVNTPDwrcKdE=; b=HQngIrc/io4BeD8i ZNTtsFiiaegrguhhJrfqFW/WFVa49f/NvGeqsrpbsYTbpmCKxYkdCluIH7x+mArs XW79CSSU67He9YmA3ncj9z9wLpwlNOjeInW4kNjhoUuhrKWXDJmu/croAIaloVf1 7eRsys2lgrPJKnl5nshK5U7BFY2HJOD8TiuNLoCVDEgoEu4YuypDVH8vob5SFcck 4+81JYTjha9UUxpamE6UA09JBYIEowvo+r2K1g155KTFaWYhREFB99OB+MpxU/nL uTyJXkn7yZmKr/BS2reSCjV//FfEc6fCYUXCCiY4yPXMAW3nOMfHx5Qoq8th6E0r isGHNw== Received: from mail-ua1-f71.google.com (mail-ua1-f71.google.com [209.85.222.71]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4e119sgg8j-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 07 May 2026 22:50:47 +0000 (GMT) Received: by mail-ua1-f71.google.com with SMTP id a1e0cc1a2514c-94ad0ada31bso5130494241.0 for ; Thu, 07 May 2026 15:50:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1778194247; x=1778799047; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=edJue4htj1/6yA330XjSk4emEsskraGJVNTPDwrcKdE=; b=Nsma7KOR+vLrGr+q/CtwlrYtpfX/353EdJlJzhQc6hqFGnu5JSTWQ5stT052Yw0Ovm tBWZhEJN6miwbWhLCgUxRMekM8vYU6Ojn8NLQXh8b7BN7c204chtCEaDnjYF5oEZmrQK 4vtkzDD3EFdQheIOxBIiCawhTdewq6BXg5hyKzmQ5lPkoVZmDwJ3MvEQSvxUXKFfhO3d DqSLBKvgbT0lOQo/s2KUGSpwbL4KJI73Ls/a1OFuovFRQZifjCHWcdL+QAexfILsGxSe u76imxgcNsNrbGOLVP2TG1LgVMz5lKdsN7OytdU++jqJjip3YH8SnpwVIbxEJrqvEmqH ldOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778194247; x=1778799047; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=edJue4htj1/6yA330XjSk4emEsskraGJVNTPDwrcKdE=; b=GaULLj60hT2zyrkz9A6/aK2xUvYoNGSQWPvIOyGlYgoewkUtPscKBVECtfz/NlxPUt tF2n5L8RxPROCJ2Cn+GzqLWprbqGzKw6DtjH5vGi8535l6MJ960n179WR4zdOosjThB7 ug2i+p0dZMQGmskCCKSMMlD5smVT6Vvbz/CmJd2INdcNMFXxn0gSZAFjnZijVIID9g8P vSMniU1I4ppBx9I5cuKwLcT+uRxbNwaNvesyLw9I+L1+5RGHfbFNovi5sNs79cgmeo3z onbSaTr3KT/yE0E2y8GDBkuWin6P+59/8pEh1IExkrr7JE4WcmYmI5iH6pkmrqNbim1r rYvw== X-Forwarded-Encrypted: i=1; AFNElJ8fYccElDdjEuippY0dyc/siWYD/+sI7sYY65XnxPj4ZsFlLnf23e0XtYgsA6Ecp11yyffckikk3k/n8mE=@vger.kernel.org X-Gm-Message-State: AOJu0Yx8agqOwashTA0rpOH/WK+K4R17XxCjoGbF2g/2SE5Dmhk16N61 NEZIfnw9IcpAdIF0psalCj+kLr52B76rGKnisgIktmCMozaiNCssOAFgcCHEYaNbTLs/Po02SiK pCgkaZ75gXpHt+ZQ0cSp2ou4D6dLkeoUqUO8I/W3fgS8qzTAIqKcNaz9g8VR7XX0rQG0= X-Gm-Gg: AeBDievBnz9cTNCCHfKFX2L2Iq2EAXkrbK/Xi5UJWARmOCgpgDZcEafLmmM6E0YoaoX wQa/4xCgkEgCpVQS2YuQRylIGJmzpVAKCaX/46dX+i2E+4jT9dqc3HBpIZCeviMSrRkHRW2XAlU aIxodpf3t3z1zJQVy+wZ9ML1nJB0l4caNGF/OvldnLyz7acM7NkzYv+iKRbpwwPyw2xKePizsjZ Og+lNO0j9r102ttSSjVdZ0FF5drM21L9oxmvc3HTp++DC7lr/0GXxY5vMdY5wJHPxf6OvTFX6B+ 3JZ4yjC0cYCV4EJeRdZXTBmPEKPk0wWYXfRDqlpb035reF/Tt8jyJiPr8ABjxwX26qBxM0tdvpL Pl7qkn4WjKa4oJCAR+UFkkkIwx3nPPoxNCY83aQWmx65IsvFw3YrXS1jZkP47xqivh/3mw3Qnse dDqpwoo4ZMRdQoX3rd X-Received: by 2002:a05:6102:54a7:b0:607:f4e7:d2e8 with SMTP id ada2fe7eead31-63115d82c8emr2076944137.4.1778194247132; Thu, 07 May 2026 15:50:47 -0700 (PDT) X-Received: by 2002:a05:6102:54a7:b0:607:f4e7:d2e8 with SMTP id ada2fe7eead31-63115d82c8emr2076938137.4.1778194246707; Thu, 07 May 2026 15:50:46 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:b16a:3475:ec42:bcfa]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bcac4359dbesm102466b.48.2026.05.07.15.50.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 May 2026 15:50:45 -0700 (PDT) From: Loic Poulain Date: Fri, 08 May 2026 00:49:29 +0200 Subject: [PATCH v3 14/15] arm64: dts: qcom: agatti: Assigned clock rate for CAMSS AXI Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260508-camss-isp-ope-v3-14-bb1055274603@oss.qualcomm.com> References: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> In-Reply-To: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> To: Bryan O'Donoghue , Vladimir Zapolskiy , Loic Poulain , Mauro Carvalho Chehab , Kees Cook , "Gustavo A. R. Silva" , Bryan O'Donoghue , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio Cc: linux-media@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devicetree@vger.kernel.org, laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com, johannes.goede@oss.qualcomm.com X-Mailer: b4 0.14.2 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTA3MDIzMiBTYWx0ZWRfX1EJeKMTgvnZt ZYQsq8yn5nJtlkn+PobgCRW5zsTXCewCzw/tcUHpDC/kAFZTn7duzMvXX7PCz1ETFJxEUNZbXQn j0MjKlXXGJ58OOBndb6dVbRPscLeCgevXSF3FZLRDz3TFXCZIfDg4mveQxKu2ZTWQ8mWC/8gGH7 8QOcy1IhcZB1VfIJq3xJOevkAL1LJNvDQ11bHSnv4rxb6kMJKsoT6ynvK4P+7HcRYH/TKkc2kBA I1UT0zHf3OQPw8FP6kCaq0ZogCT2jRzmXd/gLDhf2MCZWX4n6mraip/fWd/ANtlbLWZa6N2dT2a 443gjxeEp3kKAyIQT0GE/Tg4iDT7cBFmUwDxzJQkg61SJKM/ikR4C105HIDG2NJUe0I3Uk30Yc4 eND1jgkndD58JCuPtU55hqVq/HT1Jo9hWGbm0zO18zzgl2N4OXltPedwWrlKdno6EqR8TSRDQ1C kWZrWtrS7d2D6EVbpMg== X-Proofpoint-ORIG-GUID: zQSTcy5NizTCMN7e6zZpE6Z5pE07ImEt X-Proofpoint-GUID: zQSTcy5NizTCMN7e6zZpE6Z5pE07ImEt X-Authority-Analysis: v=2.4 cv=Dd4nbPtW c=1 sm=1 tr=0 ts=69fd1747 cx=c_pps a=KB4UBwrhAZV1kjiGHFQexw==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=gowsoOTTUOVcmtlkKump:22 a=EUspDBNiAAAA:8 a=gjCkitBQ8UzLeNF7HDgA:9 a=QEXdDO2ut3YA:10 a=o1xkdb1NAhiiM49bd1HK:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-05-07_02,2026-05-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 bulkscore=0 clxscore=1015 adultscore=0 lowpriorityscore=0 suspectscore=0 spamscore=0 impostorscore=0 phishscore=0 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2605070232 On Agatti, the CAMSS AXI clock is not managed by the interconnect and defaults to its lowest rate (19.2 MHz), which is insufficient and leads to throttling of CAMSS-related traffic. Set the CAMSS AXI clock to a suitable operating point by assigning it to its nominal frequency (300 MHz) as defined by the specification. This ensures correct and stable operation while leaving room for future dynamic scaling support in the driver. Avoid relying on boot default by explicitly specifying the expected initial clock rate in the device tree. Signed-off-by: Loic Poulain --- arch/arm64/boot/dts/qcom/agatti.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/agatti.dtsi b/arch/arm64/boot/dts/qco= m/agatti.dtsi index f9b46cf1c6462a89784429565e1636ce2ba68d73..6a6ab3f15c49eb1e8150f57198f= fe2515fa9ae52 100644 --- a/arch/arm64/boot/dts/qcom/agatti.dtsi +++ b/arch/arm64/boot/dts/qcom/agatti.dtsi @@ -1884,6 +1884,8 @@ camss: camss@5c11000 { "vfe0_cphy_rx", "vfe1", "vfe1_cphy_rx"; + assigned-clocks =3D <&gcc GCC_CAMSS_AXI_CLK>; + assigned-clock-rates =3D <300000000>; =20 interrupts =3D , , --=20 2.34.1 From nobody Fri Jun 12 14:18:25 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 6DF543DA5DE for ; Thu, 7 May 2026 22:50:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194253; cv=none; b=O80wJ3cirdnCdkTkJQ8dyij3e4AEmtDp7mlzpIaPCRs9Z06r3uLnJK3Qn8j8WGndZOb+Bn97b2icMvgATxTYtye5/LwjFBUvswsxSiUjEhl3oqVN9hgpFtZPMXvmk/7frbd+2Kw/ZhcvOvtEIbLVaiW5Iypyei+vzb9RbAd1sBc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778194253; c=relaxed/simple; bh=R+kSDRMSN9/B8tlN2xVgcRcrO+d5Ja9eWUBrLluzDIc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CpDThlzedh550VijN3trYU2iFTm98ia4fCdPHFeys2loKrNfwswOhUxozuDb668wR5/MAtqNxui+Kx6OzHITz39E0x426YNDxEi7IuyvPj4ALJ2wSVXNnLKz/XfPQjQvzMElRrmewXBjxy+Wb/KC/vEgRqmrAB11WZ5RyMW2vBM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=PoKIWwbu; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=IE+eDP90; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="PoKIWwbu"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="IE+eDP90" Received: from pps.filterd (m0279869.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 647LsR0L1174056 for ; Thu, 7 May 2026 22:50:50 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= jAc7c3OjUWNzZpEVKTXCzAfrbPiTEQqMeY2cMkUfy/8=; b=PoKIWwbucm1ZDyCU XoeQpipv44QEblbsICOAPOcNZHSVxPt9EWv1ouUa2JqTVnbiY6pARFkL0yXIwpRg 7q6Rk+hRYVDpfTP3ipZI7/optFd1N8ZqysfnVHJXh/h3PNvy2e9p/4FAM+iZLQU/ MxeGx+kQqJioqnvNgHvM0tKouYVK2lCJFN3qoaZStAjWpd4izZgL8mk6INVjGSxz pOy6qdbFVQsjRTZq5oNVMzakw/yNLPW+InDJM6ppC3KabF86I/ovzfYzFDhEcIWq 0fJmukSBH1c6zAv7GnBxHVJV6MHsuGBHspjoENQKxOYk3DA4tnP2cPPUpXijoLzQ 14hL1g== Received: from mail-ua1-f69.google.com (mail-ua1-f69.google.com [209.85.222.69]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4e132h84cc-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 07 May 2026 22:50:50 +0000 (GMT) Received: by mail-ua1-f69.google.com with SMTP id a1e0cc1a2514c-9569b029e1cso1629667241.1 for ; Thu, 07 May 2026 15:50:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1778194250; x=1778799050; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=jAc7c3OjUWNzZpEVKTXCzAfrbPiTEQqMeY2cMkUfy/8=; b=IE+eDP90p4As+Ce89K02Mo3qlnn2BP+bh1PeetbwTOG6EXh5xeWog5342QW0jd6GIx LbeUlnGLl0UkXYm16SzIxWsAjYjQSA2/Mw39OxGXkfdMyL+XFUE7G8lbQW0a4pZCJxI6 5NTtzTVqQk4gIlQ9Zy+ZFiI4FSkQZGWzDkEBYWpq6FtXctq1kylOf6BdglvFrt7fZ/mu JN+NccmFInrsjrmSb/pb364XaSUt5wTrcjZ61tnTk7kVwttHccp1lVkTlBVw962arce0 hRsJoVhpmby9X/vLFOQ+LRkChEug5FEdL1XIr+qRPr32ieFwL3Sq9G0Oe6BYXO05alhv cDyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778194250; x=1778799050; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=jAc7c3OjUWNzZpEVKTXCzAfrbPiTEQqMeY2cMkUfy/8=; b=oiKXpTCgJTrMzgikcUMJK9zneE38LzqFoE4kkoqfsSpDcvp4Fn4zhutKyYhEf94laz dBDmHw7stizdz9uwpeqgcCTwJADne37mzc3ohuWpgf2IpgEFWPwSXloGISNNe9EpLj7v 3WRsubSzXgBP1XaedytuO4xvAPCOc3ufJptShOaBULXcwl43r0cKJ9npo/GTVf/0ged9 88QFqnNkQB3AC00Kfz2aEUOhki3rXWMx0w9TzeM+yc8SMgIhhFWT7aHhiLseWXvI+13K OXfpZlQHfrun2jTenFCtXnaYpKwcp4vLPBcrigT2FXV5m23dHAVtaRebtcjXOR308jWl BL/A== X-Forwarded-Encrypted: i=1; AFNElJ8dwNspIlWzZlUj8MaGNwTl9bQpXciskzDqo20WaBYmQZ0m/+Al1VYLb8EDS9xHEouE2gRqpvWsufxbnZo=@vger.kernel.org X-Gm-Message-State: AOJu0YzS7R17Mi6atMgOy2KHRdGINBw4PM8gYp+YE3tLLR2dBOtmC/XS tZdZ2oIlgiB2ybPeTMzJRi67zDDF8GXwd/LTKWitnR2oLRi0ggL0INcPs4fmv/dYDeuPtOEDFSr p9zJGqJqurFuN/9jrx0tJpa5rHhOs/CTD1M0GbnTXm/FXEbHLaYuAc0B9hA6mncG5l/8= X-Gm-Gg: AeBDieskVjJ0uC0Ax7XX6C6g6we+Cmy1f3T75zV24qxHEVSXxjxmm2OFETbcgQRNFQ3 h1AYrt5JiivBGdz8x4gFg439U0qrbGZIU5aT4VB3N7Br3CLQSw8uR/m2Ck6JqxuEIGTGw/1RfPL 3ln3cHm8ruD92Ap8ubnFeESNO4uuD6zuWySpIqms0RN2NSdaei/oewIl3ZhMDM6GWgKjIdjvwXo XEqnpuCYMxJgoMWvP9RzKKIfb7QPBUAz3qmFMcvhraDeXXPKlaFZ3aJaNT5vbKJiw8QlKuyrgaK Sn2Pg2eEFIHTkajDLMAfUcs+rjjt2Robj3tfKJ/4gZvfzdv0Mhtm39ISZjq9KlfYD/5w7iP96SI L5EGJHpXnbw8RXkruW/R6o9CZpyMaMegvhyVvMIHzTNN7LwrQqEJYE7GYPLyUnjF8NjMVe4EGGv XNQahdFdNHyr3f7CSy X-Received: by 2002:a05:6102:5983:b0:62f:33f9:37f7 with SMTP id ada2fe7eead31-630f8ec5f1bmr5882005137.10.1778194249861; Thu, 07 May 2026 15:50:49 -0700 (PDT) X-Received: by 2002:a05:6102:5983:b0:62f:33f9:37f7 with SMTP id ada2fe7eead31-630f8ec5f1bmr5881988137.10.1778194249350; Thu, 07 May 2026 15:50:49 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:b16a:3475:ec42:bcfa]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bcac4359dbesm102466b.48.2026.05.07.15.50.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 May 2026 15:50:48 -0700 (PDT) From: Loic Poulain Date: Fri, 08 May 2026 00:49:30 +0200 Subject: [PATCH v3 15/15] arm64: dts: qcom: agatti: Add OPE node Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260508-camss-isp-ope-v3-15-bb1055274603@oss.qualcomm.com> References: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> In-Reply-To: <20260508-camss-isp-ope-v3-0-bb1055274603@oss.qualcomm.com> To: Bryan O'Donoghue , Vladimir Zapolskiy , Loic Poulain , Mauro Carvalho Chehab , Kees Cook , "Gustavo A. R. Silva" , Bryan O'Donoghue , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio Cc: linux-media@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, devicetree@vger.kernel.org, laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com, johannes.goede@oss.qualcomm.com X-Mailer: b4 0.14.2 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTA3MDIzMiBTYWx0ZWRfX/AD2aI+GeBiz 3DhQdxLaZU45PPdAeTO4vG62AG7V12DgWBd7mb8w0NsHWpGX92gJemq2lhOea8KuiFiW4vgtdoT fLzCnO0JtDMd+tYP7od1mnMY3xUq8NHa1t4J0H4u3nHvZLi+p7TbAKkpLZCccAI2/2JcHQS1qFp p730eXKBpbPSizbSiROiXyuBKOv4+rjI5wbM9jizhXK0+DzGKPUFuL5dIUnQoVgd6UbgfZBw/v1 l+bagHmzvlh/e78xBBdHzyh7c11tU8uezmBzqvH4WMRgyNiUaMed10CBqmXyujbR2lGSqQkYZ4r 8MfL6mvM6F2U5kjCwKC1bwo99HmgPsgLRrkIUP4s+S5WS1MUV/R+XTrZurmhbjF/Pse8sTGRWnR Q4KbiXGXBep9QgHKFDSquH74UgKEWe6q6H7YNNVJGfUORD3QDVMiGsy288+A8Anoe7LcJu6vZVJ +dNpexlKFChzaUtyrtA== X-Proofpoint-ORIG-GUID: vm5bJ1-yxNyHmfjL9cPbkz9XQaZQlhSh X-Proofpoint-GUID: vm5bJ1-yxNyHmfjL9cPbkz9XQaZQlhSh X-Authority-Analysis: v=2.4 cv=McxcfZ/f c=1 sm=1 tr=0 ts=69fd174a cx=c_pps a=UbhLPJ621ZpgOD2l3yZY1w==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=_glEPmIy2e8OvE2BGh3C:22 a=EUspDBNiAAAA:8 a=1BEw5LmG3YzgyHxDt7YA:9 a=qQ54gDEPcyxammeZ:21 a=QEXdDO2ut3YA:10 a=TOPH6uDL9cOC6tEoww4z:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-05-07_02,2026-05-06_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 malwarescore=0 suspectscore=0 spamscore=0 bulkscore=0 adultscore=0 priorityscore=1501 lowpriorityscore=0 impostorscore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2605070232 Add the Offline Processing Engine (OPE) device tree node for the Agatti platform (QCM2290). The node describes the five register regions (top, bus_read, bus_write, pipeline, qos), clocks, interrupt, interconnects, IOMMU mappings, and OPP table. Signed-off-by: Loic Poulain --- arch/arm64/boot/dts/qcom/agatti.dtsi | 71 ++++++++++++++++++++++++++++++++= ++++ 1 file changed, 71 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/agatti.dtsi b/arch/arm64/boot/dts/qco= m/agatti.dtsi index 6a6ab3f15c49eb1e8150f57198ffe2515fa9ae52..e93da2c64044d1f0d49b3ea41fa= a39cda42e86d4 100644 --- a/arch/arm64/boot/dts/qcom/agatti.dtsi +++ b/arch/arm64/boot/dts/qcom/agatti.dtsi @@ -1921,6 +1921,10 @@ &bimc SLAVE_EBI1 RPM_ALWAYS_TAG>, =20 power-domains =3D <&gcc GCC_CAMSS_TOP_GDSC>; =20 + #address-cells =3D <2>; + #size-cells =3D <2>; + ranges; + status =3D "disabled"; =20 ports { @@ -1935,6 +1939,73 @@ port@1 { reg =3D <1>; }; }; + + camss_ope: isp@5c42400 { + compatible =3D "qcom,qcm2290-camss-ope"; + + reg =3D <0x0 0x5c42400 0x0 0x200>, + <0x0 0x5c42600 0x0 0x200>, + <0x0 0x5c42800 0x0 0x4400>, + <0x0 0x5c46c00 0x0 0x190>, + <0x0 0x5c46d90 0x0 0xa00>; + reg-names =3D "top", + "qos", + "pipeline", + "bus_read", + "bus_write"; + + clocks =3D <&gcc GCC_CAMSS_OPE_CLK>, + <&gcc GCC_CAMSS_OPE_AHB_CLK>, + <&gcc GCC_CAMSS_NRT_AXI_CLK>; + clock-names =3D "core", + "iface", + "data"; + + interrupts =3D ; + + interconnects =3D <&bimc MASTER_APPSS_PROC RPM_ACTIVE_TAG + &config_noc SLAVE_CAMERA_CFG RPM_ACTIVE_TAG>, + <&mmnrt_virt MASTER_CAMNOC_SF RPM_ALWAYS_TAG + &bimc SLAVE_EBI1 RPM_ALWAYS_TAG>; + interconnect-names =3D "config", + "data"; + + iommus =3D <&apps_smmu 0x820 0x0>, + <&apps_smmu 0x840 0x0>; + + operating-points-v2 =3D <&ope_opp_table>; + power-domains =3D <&rpmpd QCM2290_VDDCX>; + + ope_opp_table: opp-table { + compatible =3D "operating-points-v2"; + + opp-19200000 { + opp-hz =3D /bits/ 64 <19200000>; + required-opps =3D <&rpmpd_opp_min_svs>; + }; + + opp-200000000 { + opp-hz =3D /bits/ 64 <200000000>; + required-opps =3D <&rpmpd_opp_svs>; + }; + + opp-266600000 { + opp-hz =3D /bits/ 64 <266600000>; + required-opps =3D <&rpmpd_opp_svs_plus>; + }; + + opp-465000000 { + opp-hz =3D /bits/ 64 <465000000>; + required-opps =3D <&rpmpd_opp_nom>; + }; + + opp-580000000 { + opp-hz =3D /bits/ 64 <580000000>; + required-opps =3D <&rpmpd_opp_turbo>; + turbo-mode; + }; + }; + }; }; =20 mdss: display-subsystem@5e00000 { --=20 2.34.1