From nobody Wed Jun 17 06:13:00 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 1EFA52FD69D for ; Mon, 27 Apr 2026 12:46:38 +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=1777294000; cv=none; b=CjhW868Ie8Z+rUg2xkshewq6+j73Sg5G+73YIxUFTp8RTHrCkZ7JD2OaMY1I6pNWtUYMwJz9GLNHFlp1uYyTWe4/b2yk7HBEi/Mx7ls/m8jEV/cWDExcIfCGrGNnV2n8+VG9CgcF6HR6MKXk6X3TnytuTYDsPKNQjAY9nqHfUsQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777294000; c=relaxed/simple; bh=8W5y78VKUavviXikxj7dAYRekuTy1qq9Xl81Z8IQtNw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Vtp0nmaVzXkd+6/86U1ynQprYOzpYeYAFExC5zamUWtYymwGmskflQh6SOcvak7KCTFdQ54hjFeHRTz4/uxdMsytHQUt59LEPNfpyGlWWkO/NgJWU6l2mSPBpuH1NRzSgrh/CRQxyNQ10FZEJs0DGHNZeelFsj5AV4QajsKYLsg= 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=dOvuZIMR; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=G+6r4IgR; 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="dOvuZIMR"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="G+6r4IgR" 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 63R8TCjg2913909 for ; Mon, 27 Apr 2026 12:46:38 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= lCJ9j9cXMZuO871EpV/2lp8v7oOXkTCu0ysZH6cE8Us=; b=dOvuZIMRDKj2fsPO rey3TLa65b68eWZrdBiA3kmksbE2ZUzz7/xMoOBH/YtCghhCPQyHO+GJsA7ektCr TJpgi4cTerxyjmPDs5gtz3LsNSgN6EMbX3+vKB9xCEB9d8Kd69g9G03iCkdVJuo8 K9I3LhBxl2hp0GRyUEc8akNzqzaaCtfN1iV90PS9QfdMoh0SZ3bCGQdHvDJNDFBC z3kzrOz9yONT0JW95F2awgIaZDHATPlmgSmmH1S7Z6u7dIfBBS4RM9ZKetlCVCuv +Voa0ibEC2Ky3SvcxxyN8FjHVR5Hx7DBrcGyqzYy58pg7SwaPGMnJNAX58VcDlxY TUA3Dw== 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 4dt26xhgbh-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 27 Apr 2026 12:46:38 +0000 (GMT) Received: by mail-vs1-f70.google.com with SMTP id ada2fe7eead31-6130270a5f1so14154587137.1 for ; Mon, 27 Apr 2026 05:46:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1777293997; x=1777898797; 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=lCJ9j9cXMZuO871EpV/2lp8v7oOXkTCu0ysZH6cE8Us=; b=G+6r4IgROX4alcWPUNrzlQ+vIlheTjWOTFZ0sDtKeas/mRDwZ0VHuBC531QcVbn/zn oIQokG6VerEAvYVGdo0VFZMzWOvAogfKnSr+c6ZhhEXOjNFF+jUqqHO4LPefiC2yH2BJ nVYopGf1zuBDvioQlipsX4loYqw/k+CLFKCwnhOa4YcyURqrJGkTGx/DDpHnsMcjZkN5 54AJN6HYH8hR6KO4OIXuxYCafFHwxNp11cncMHx1Ib3CO4OtzJ2K+NwPT8LOY8f7oaUm 18C997GPVkqalfuSZyOjigLX0LN6dg5SKC2OOTNwKww5Ot5pm2s+cMWtTmn26s9OFE+o nhvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777293997; x=1777898797; 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=lCJ9j9cXMZuO871EpV/2lp8v7oOXkTCu0ysZH6cE8Us=; b=Yeo1yFN5jEy+0/8RU7IOD7zoKdh39EiZnGwTWB2uil7SwC156nNLlM29O/lqDJaNJp OYRNrgbJs2nl6JAjf63/h2aHHTqJMAcoS/dgGLwDfLf+PexVPpo9FM5007pvKX3UQXz5 8FuTAohCnO1QxtVBxLpHj64sWC486Hmi0L2/xc5oMPTawi35sQtIju5oH9j7UlqGMtSo 43tQ75uxQzewttPsjnfmUE+SjsHalzFSJOdWBWMYzduugNd0kPvM/luZ/zQPScQBwFJe goap7WDFw4i7FbrMWl8lLB4lxxHMfRfqldFvWVOawlBw/jlhEAFvyhsRfgWCYbLeFTQ4 H7uA== X-Forwarded-Encrypted: i=1; AFNElJ8EjrlX2okDXikTHtaNT0JCPB8+wPg+4PLy10xBb7NU/woYXP6T1fphGgT5opdCsIOtM3aTyRPt5sv2kSc=@vger.kernel.org X-Gm-Message-State: AOJu0YzGJZQfgAMbWhMUPoTp4cUVg0DH62rJq5TWHhwgoedunvdAxaqQ GBcnoWeGeizH3MXwp8TPgzpfV7kdUU6ZG50Oe2P+psjPu37dlyqms7bqcA3nCVP0UNOq25mSZI8 CSClbf0sIVs1SKc7gVpTesHKwdEBlhiwiUfoqX3v+GcpDP6vKADq4Ejg5efOugrdLTQM= X-Gm-Gg: AeBDieuHrNeQU8JlFTb7iauzElqSEfOjazn4rrUwcEQU2eRRNAg+v4WaQsp+3RWwl+g vUv7iHOSbwp+xXuTaRs7YEMVD5Y1QtI/PN7I2FIlYwr55kwHfc7KbQ8EZVfojBFquM1fUeKy+YV ZS8Iv8vN1fH6dMAOG1afPfMLmKnAC8SkEUyDULGgNiDD7gimRe2NcU2+KS6S7QVh2kgBhmaLZyU OKaRrEjUdELFiG7B8BIQzyIfBpZ3cZkIX0NUOFn5lnG6N6EnkvfmsCsPdBcXzwK7T7IS0t+5k7H kZUWH9n+teJuNdWUHCe4oPIiMsU9Id60aXRUL3GtUvQ0Czm1ezEt7B34+Plxs1W3XjkDooRky0K o26xpQewzsvANotZiY+mUX4e4E3CItd2/MiEwppIknYJjM2RuQ5vZT0Je7AKmARpdRewwg8rfTE gSbEKw7G9tLuB1zKWNSj785WHh+uw= X-Received: by 2002:a05:6102:2d09:b0:605:17b8:16dc with SMTP id ada2fe7eead31-616f6ef7d62mr22668430137.20.1777293997383; Mon, 27 Apr 2026 05:46:37 -0700 (PDT) X-Received: by 2002:a05:6102:2d09:b0:605:17b8:16dc with SMTP id ada2fe7eead31-616f6ef7d62mr22668384137.20.1777293996955; Mon, 27 Apr 2026 05:46:36 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:653f:4d28:6a78:a6ca]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ba454d1bd19sm1091496866b.37.2026.04.27.05.46.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Apr 2026 05:46:36 -0700 (PDT) From: Loic Poulain Date: Mon, 27 Apr 2026 14:43:28 +0200 Subject: [PATCH v2 01/14] media: qcom: camss: Add support to populate sub-devices 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: <20260427-camss-isp-ope-v2-1-f430e7485009@oss.qualcomm.com> References: <20260427-camss-isp-ope-v2-0-f430e7485009@oss.qualcomm.com> In-Reply-To: <20260427-camss-isp-ope-v2-0-f430e7485009@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 X-Mailer: b4 0.14.2 X-Proofpoint-GUID: qV88tWc2S907ra9ueUBLBWLb0uMZlItu X-Proofpoint-ORIG-GUID: qV88tWc2S907ra9ueUBLBWLb0uMZlItu X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDI3MDEzMyBTYWx0ZWRfX2j7STtS6ny0i E5YCp8I7Ch0F5Z0QnRXyW/sfbIBmodlzsQQZXZBvtZA7y8edT6E/wKA8obtYgPCiFJfQXLi36DG 2nQK4UaeaKtzKE7MeMAXKrKtM10hoD2YLSKetiWyohZTUcQet9pjG1G/OqUnuVaRPYXlDJvzxrG i53JeOWeplgZ8Hu7+coMgdEJi40Ozc2Mc21sUtBK1RAVPunKIHggYr1clUWGQGDfbPeV3/8DiFo 7LfdMwa5kNmqgj9jFhe5B0CasZ6gWjze2RIKrqq3xprwucDq7ohY5Yuiz7PNoTLNfRUAFGskFqS pGZCRIhcxl3GY9GKeKvESyUI/dwyFJsT7DF5X/RilFEDk+Wrm0X5/u9znE4bClbS6juqkmywqbw XkBIMgqR0dFlhJiS1iZnIYtFFpH8uWQ7Pc4av2iCO4V7QvFz+f7RBLgZNibQymq4LEXAGkU+DVH Zk8tIt+eohJeaVHPgtg== X-Authority-Analysis: v=2.4 cv=FM8rAeos c=1 sm=1 tr=0 ts=69ef5aae cx=c_pps a=N1BjEkVkxJi3uNfLdpvX3g==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=rJkE3RaqiGZ5pbrm-msn:22 a=KKAkSRfTAAAA:8 a=EUspDBNiAAAA:8 a=5bRy6lfvdnCUHtv4pvsA:9 a=QEXdDO2ut3YA:10 a=crWF4MFLhNY0qMRaF8an:22 a=cvBusfyB2V15izCimMoJ: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-04-27_03,2026-04-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 suspectscore=0 adultscore=0 bulkscore=0 phishscore=0 spamscore=0 malwarescore=0 priorityscore=1501 impostorscore=0 clxscore=1015 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2604270133 From: Bryan O'Donoghue Use devm_of_platform_populate() to populate subs in the tree. 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 36c601c595053ddad8d327b1416d7ff587920174..8f2b1d3cd9f289895aa439443d2= a18bb036fccde 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 @@ -4608,6 +4609,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 Wed Jun 17 06:13:00 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 D385130C62E for ; Mon, 27 Apr 2026 12:46:40 +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=1777294003; cv=none; b=mmeD3IA2WoBw76MFz8PfjgaRcYHa4qlx31KL02Krlo2e6XHT5UQWopEUzXa+LHEun4MMqyLpDwqxBHt3xVI1J3MUvS+U/fhyQ3fAOaiJ0gg9s4yJ4XtDvvnnviWMnbxkGQbpKQKY9oZK8IhugFeM8JDDy4huKMRpzlxoaw2Xg0w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777294003; c=relaxed/simple; bh=U/xIWfIVyxF2mQ02rx0FKseSqm13qZ1XiNmxrWwriB8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=r9WBVxOlylLL96HPpXvuNNu/3LrkJB5d5D8cXi8GC9UhvQBrC/gfLW44qzq6D6ePPFO+aDPAmUz1SO8NctqViVvhs48yg/zN+gw6TMKXv8KK0lp40GZXHRDX8w9TZBUvTROXVU1U/jbHYRr4TWDa6sN7/1QsgQpNkJbo72Jjs0E= 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=X1uPdLIG; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=bzkQREdo; 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="X1uPdLIG"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="bzkQREdo" 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 63R8TGII3682645 for ; Mon, 27 Apr 2026 12:46:40 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= S4kiIupbbdzP1AaB54zj5uEJPC21c2MwWBaLlQ5wgiU=; b=X1uPdLIGlNZRxzwR /7qKi6EbNQ10JMyLzWgqarhhPJB6jpuCwCq6dUInbebyfQxxVR45i9Zh+6WnaWe8 buVESTnNACxCrhJ360/QEVLLoCAQiNObjtvn95RAVJNB/JHQD01D6Svg4QJGkjSn zmdg0WVGe9BtQDbRIWE8W4QZ2uGof6Gmmkj9jRoxeH5JV8EKYyrlLneRvBB6Yenv na8hoh2eAzO5nPjBOQrOU43sgWVC8/KZO3sKviNMv/EsSV0Ajz3nlsptD91M5Yad 3NOsazrLiaEWOPeXnVwGaKQAC5PayTXPpfpDnqOzfJwENY+afWbm0MfDIthQ5FJS +J1SUA== 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 4drnmr643b-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 27 Apr 2026 12:46:39 +0000 (GMT) Received: by mail-ua1-f69.google.com with SMTP id a1e0cc1a2514c-9587174003aso12711871241.2 for ; Mon, 27 Apr 2026 05:46:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1777293999; x=1777898799; 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=S4kiIupbbdzP1AaB54zj5uEJPC21c2MwWBaLlQ5wgiU=; b=bzkQREdohcoh3eE6JVy9aJV+4+0Ls6pyw+ExBe/rypz2J3G8wg4cnQZNJkHWwhhS7+ s70zZVIBI7sWy+/AzXcQOimWFwBQmTjNFy9UxUrlOvwy0dMfBKPmolOBfUkdNIBTDZ26 4CIOu8ieNRyAyqTaqAxFjrzCRxZsGPd8nQGACy5TZ8F4G+AMc6L97G/4IqxTH8IqWxmc 7FjKjetZh/8BdG4P3PHg95rHHSJPNCN6DUVmhX+kBcMrL5leQ7R+Nluu2XiBhE9gN21k iLSKEx3uttx1glvRdlbrMbmzMvWGcCvIRNzdY/+8oYv7GF71xK193CNV7yBRJ83FKRg6 tSXw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777293999; x=1777898799; 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=S4kiIupbbdzP1AaB54zj5uEJPC21c2MwWBaLlQ5wgiU=; b=nu92j5utGPGY5A5jAzDXMaUWHDBDb6CTIGfixS1uD0HRSSfYMT9fM2/kjLIvNhmalK la6RS5mTR4+5WAbnYdQx6qMxaSsdngzJor6bAC+wXPx6pJjcC/qbIOSkUf6NIf/Dr/JX oLBH3Vwtwy7uPzNH/EpazlX7+y1sudFE6ERfJGRw0DcWIeEYr6UliE8WKrJaQmT2XzsY KJvzeOftgWJccYRratm0j4V4CRU9tuUi4GYxfbSxXAUf5duclTSAyRr9KAqa5a/6FO/i PC4zw6L3/YDzW9cBbXCusFMbPkIef+EYx0ZYUQGV5ErZFSo5GcouKh9qY1iBsFZPsWpk rY+Q== X-Forwarded-Encrypted: i=1; AFNElJ+gkKH7iYUTzvUbUp01fCJo/yvHzZ1u6oX3rSrKAE005hlVzLDmclpTTxztAGpuV55aSzdaD0EeDRU5yWI=@vger.kernel.org X-Gm-Message-State: AOJu0Yzm2AadGB8Pw4ApIZsjRTlUyexU/2CktFMsu7LKJf8Nq3Gr0FTk M/68Dx4FfjaJbVXO+PM0dW8irSAPkZmBCg8ec3sPYyFud33/1iL4H8ENd7Yak8PfXxor9WH3vIL lV5UlaSwMVK4DeTj/eBHXKWruns0IYLjuVZSxH3Su7wFDx0amVUhvCv0NjyeFNX2Y7ds= X-Gm-Gg: AeBDieu+o0gGn8w7gQtdymFrtUSYO9lGGAwTVrk8XJPm7N4vKF8Jamg6M9yLrag8K6z 4A9li/dOw5KhbS6Z/eb8XY4EbVk7VTkerFskefia10pwEDiomRmtr+Lfn81Ru6zJ6XKVZN9DG67 LPKf4rvAI4i1SctxSg4mA0fBW47+pikK/Ku8VAK1P2/uIY/Lb3/OjSqh3TH12ee/EGr/bySuSyJ ytuECtclEj3j/bLqMbFvS/Ait03xYRu9JC9zVNr5OCNhgzmUTCWRYz4SPwA3CgYdyzFHTwQ14qH uuOjcoR1hca/3CkquzzqhiZxXbDoYmt17RKRn0/Qo8ebk4ZsrCrjKgFY1Y7jcd1uR9bwCC7LMiW qsCdTRSwF7tBSGPL9I7CsZlRSOqwNYfHfUP2gq65n/Hb7QWjzfAVeda+i3o6COwcTeI5d5oa4CX loT7J4hSUFAZGGCDqAXvvOX5xGI6w= X-Received: by 2002:a05:6102:4e:b0:617:9372:dd24 with SMTP id ada2fe7eead31-6179372e22amr15468837137.20.1777293999089; Mon, 27 Apr 2026 05:46:39 -0700 (PDT) X-Received: by 2002:a05:6102:4e:b0:617:9372:dd24 with SMTP id ada2fe7eead31-6179372e22amr15468817137.20.1777293998705; Mon, 27 Apr 2026 05:46:38 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:653f:4d28:6a78:a6ca]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ba454d1bd19sm1091496866b.37.2026.04.27.05.46.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Apr 2026 05:46:37 -0700 (PDT) From: Loic Poulain Date: Mon, 27 Apr 2026 14:43:29 +0200 Subject: [PATCH v2 02/14] 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: <20260427-camss-isp-ope-v2-2-f430e7485009@oss.qualcomm.com> References: <20260427-camss-isp-ope-v2-0-f430e7485009@oss.qualcomm.com> In-Reply-To: <20260427-camss-isp-ope-v2-0-f430e7485009@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 X-Mailer: b4 0.14.2 X-Authority-Analysis: v=2.4 cv=aqCCzyZV c=1 sm=1 tr=0 ts=69ef5aaf cx=c_pps a=UbhLPJ621ZpgOD2l3yZY1w==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=3WHJM1ZQz_JShphwDgj5:22 a=EUspDBNiAAAA:8 a=yohlUIewGNSudplHeboA:9 a=QEXdDO2ut3YA:10 a=TOPH6uDL9cOC6tEoww4z:22 X-Proofpoint-GUID: N3kdJynXm7HystfeOvBSIPIMTxXYiM97 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDI3MDEzMyBTYWx0ZWRfXyRrk155duTu1 FHMqxKUFxWL4BBGEC9teX40mRZu0YQHPi/D/VdB+9SKS7c5gB2tB0TePoSI+QTUL0ehKv1nxenO DedCylUrBf+JbLPivU3M6ojffQ3hfXv6GKGKdBr2PSwGgzC2y7CemBy+aMgJzeQ/abLecwWmqAI C5waakKzNlE8x3HHz53vH9kN8Ot4nw7MgGz2wzZrk2Zr7IvYmdNnta3z4GDGzGA62lk5P6BsqMW qZLbcA40C4dUUlolJZBQaaBt0PY1hOYpH3ulTXNY1YFXk3Z5yF9hXDiXwPRYO0AIkOZDEhw+XSi MiNVJM50wY3W45HufCrprAVr0S+jbItIWnvGUaQqdy0BLcq4hY4JPTuBgdPdbjvhvGNwiyU1d4j EesS05eQz9vpTCXweEVtREU47uVNLHG4GAL4O/sf0E3Uy5E0TI5tAA3oelM3QExZ5eCCWbqWfS9 jJ3Hx8NY9dwAcQwQacw== X-Proofpoint-ORIG-GUID: N3kdJynXm7HystfeOvBSIPIMTxXYiM97 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-04-27_03,2026-04-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 impostorscore=0 phishscore=0 spamscore=0 adultscore=0 suspectscore=0 malwarescore=0 bulkscore=0 clxscore=1015 lowpriorityscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2604270133 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 | 54 +++++++++++++++++++++++++++= +++- drivers/media/platform/qcom/camss/camss.h | 6 ++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/plat= form/qcom/camss/camss.c index 8f2b1d3cd9f289895aa439443d2a18bb036fccde..ca68ad7fc9ff30eae23d3baf34c= f1ca642acf9d7 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include =20 @@ -4593,6 +4594,49 @@ static void camss_genpd_cleanup(struct camss *camss) dev_pm_domain_detach(camss->genpd, true); } =20 +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].name) + 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].name; i++) { + const struct camss_pm_clk *entry =3D &camss->res->pm_clks[i]; + struct clk *clk; + + clk =3D clk_get(dev, entry->name); + if (IS_ERR(clk)) { + dev_warn(dev, "failed to get pm_clk %s: %pe\n", + entry->name, clk); + continue; + } + + if (entry->rate) { + ret =3D clk_set_rate(clk, entry->rate); + if (ret) + dev_warn(dev, "failed to set rate for pm_clk %s: %d\n", + entry->name, ret); + } + + /* PM takes ownership of the clock, no explicit clk_put() is required. */ + ret =3D pm_clk_add_clk(dev, clk); + if (ret) { + dev_warn(dev, "failed to add pm_clk %s: %d\n", + entry->name, ret); + clk_put(clk); + } + } + + return 0; +} + /* * camss_probe - Probe CAMSS platform device * @pdev: Pointer to CAMSS platform device @@ -4677,6 +4721,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; @@ -4984,7 +5032,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) @@ -4994,6 +5042,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..bd5e572f0a0a7daa1668831b7d2= fc60e0498200d 100644 --- a/drivers/media/platform/qcom/camss/camss.h +++ b/drivers/media/platform/qcom/camss/camss.h @@ -100,9 +100,15 @@ enum icc_count { ICC_SM8250_COUNT =3D 4, }; =20 +struct camss_pm_clk { + const char *name; + unsigned long rate; /* 0 =3D do not set rate */ +}; + struct camss_resources { enum camss_version version; const char *pd_name; + struct camss_pm_clk 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 Wed Jun 17 06:13:00 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 97FE43BA241 for ; Mon, 27 Apr 2026 12:46:42 +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=1777294003; cv=none; b=lfK5LbC5reW39ZxqSZGb23qfZy3Z/3N42QCfyVMruFK+Z6793WrMKjHvDmNGgWnB1dGka8URAxbWM4wqQhbiF/ZwG0fygqDUHmbVCTLWT7DSkXTUAMh5Upf7z+Ss16EbSLA5uvpDszSkAlmKn1tlsYd2aus2UG8pNI+G8DGugmo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777294003; c=relaxed/simple; bh=us+Y4Cb7pFVSLnADy916NDIEoYZAuE4XXB6lyTKrzXE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZH5oLavpcap2EKL0tC66RY3oxZXlCr/1mRyHgk3z4q7AZ71kqsJ8yBnN00WCtghTK4HNKQLoJM/Ku+7e0hW2kV77h0n2oeMLy50NAyF6WGovq2HBFg9+8aujpTv2Breky9nYqQ84Bv2DvYdQz+hrqVnu9YJpc1Y2bqIxSyyYlkw= 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=d4onTU89; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=JWPD7G4j; 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="d4onTU89"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="JWPD7G4j" 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 63R8kSQY3962085 for ; Mon, 27 Apr 2026 12:46:42 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= zpAVUiE0mWNRiDxsSieW36zbJskMY3EKSaK21P2YpUw=; b=d4onTU89SjGFIA92 +Dw4xpZDQ6Tg8GvDUi2FEzcjwhlE8/TfgV/Xbt4kQIXZuyGCzxwEcwKjw20gItR1 sh/trF/BOGYFIzf4SgDVFnMxdyPlKitrZGfdYGFB8bYucbK+TlTKOzHN+pzMCfHE OLvldclOEfDS2Ynh4Uu1SD6I3JvGYsPE3P3rEpT3D2/NhM9kOYqgr/5qoxZtXrsL mBK90fmUBxyOKJKv2W7CNl2IB3YzexdKgMxIQfT668CoZM+dSVmH+4+VHg+i407k j7h6Dg8ne/Uwj9h0hBUJu/3yJfC+Q+Wct+UwS2g1iCJbecYyY7/OoZzVtF2txBK9 e18EFQ== Received: from mail-qt1-f199.google.com (mail-qt1-f199.google.com [209.85.160.199]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4dt4k313m6-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 27 Apr 2026 12:46:41 +0000 (GMT) Received: by mail-qt1-f199.google.com with SMTP id d75a77b69052e-50fbc70cfbdso151353001cf.2 for ; Mon, 27 Apr 2026 05:46:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1777294001; x=1777898801; 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=zpAVUiE0mWNRiDxsSieW36zbJskMY3EKSaK21P2YpUw=; b=JWPD7G4jZwwfw5gCpH7kwworxGE4Wg8pOPtCfc4pQ1av8UpwNVAGtMaN4ch+xOBY15 Vpo4mXqDWBe754KGWZ06IgAfOdXw9121TAxlH1R7WB+MEccgFNQSy2fJJ+t8suS1qhlb WVFLqCpRpSp4N40YQrjLjhd1J7p795XebIz8QuahxqX5gCZ8s/C+nATV+aSIUjDHWaJE UbQMpQcObnpf1KaS48ijKpLpkRXfawdVB46gXBiHT9qaN4gbzWSAdZ3/n8/qzCpEMyMC C3CgoQ9ZC37FB1LHoTJu+4nqn6arEIfkxIZZhFLG6E99DCgWKkeQM0mCVVNpvW4jrWHi 4gIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777294001; x=1777898801; 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=zpAVUiE0mWNRiDxsSieW36zbJskMY3EKSaK21P2YpUw=; b=DDsXaQvMfsjt2PrrO+Nq5D4MmPYPXFVoJqIqTT6Io9Xa9CX/JJeo0X5MIxTYIpRsnY R3N9qFME7+aEqxQxa9kAouYlBY3N/zqG7hSwKZEZcMV3D+qUxLM1MZovoFOlqTqIOFLd N22JSQKgGSiSWengJ+Ti3o2zw3REHTziYZ72I4QpY+ZF/zp4jGrIYEngm35dWZWhuF0F UfaGFdCnp8HnxXD6Ur3ORoydv5k87ADFUBZ3XJAjuT4Gk06L7U+Z/qGJ4l74inFRkVle XyGiSnMM1CqDSMiswxHjN+IJ+5IhXncrzWRQWOrTHR2BjxEuP9FfXHX9HLsEzjp4J9h+ uxlA== X-Forwarded-Encrypted: i=1; AFNElJ/xtSjCnzWMe225Ooc5nLwBXlmv4bj8uilCE6xnKYmbVzPqJOzo0iZi5hZ9PpP2uIqMHqlzoHs+R2NXrN8=@vger.kernel.org X-Gm-Message-State: AOJu0YzqOB+PS78E3yj9aPBxF0Hb4d0l+amt/I1hXv5tz+vNhjO4+hRW uOrbtcQsp8yf02rWHVAcsBp9nzRU053pPbxph7WWCtt35+7scLMnEDuc+NEVU8yOhSs4YLEZw+d dFBOdfxSpA7DdEbv9ohZvot8lKFpw1D1TQlVvqcbQm83RDf7ST4RbVxLks2eEuQixeOM= X-Gm-Gg: AeBDieuulRHlfr387vQzFRfjP1vwgUyvNSg7uq+nFUaGNIFYVHcOUoeLavuKqyBtru7 RukZt8nxbB1qJvLm44AQfrtda3s2UYVH3ih9WmYDB1dqNtAsb0F3/d8LdiBewY5JMLQcoRc4PAz 088FWXxVhRnO9qAKZDldRPGr5KwWWQc2hgsbjo/HAFUBktzk9KULUecJLe98+quBWYkS+rHvSLk unOVfkWbSZfLIfceXH7MWiV0JDcRrTLLHdfwhqnsLUtHjf3INSA66pvGbTc8XtbwfdcLr6W8ZxN WXwFtXBFUajYTZ/rSJm/2KO3ti4hPmy3ktWjnibxsrmOvrURePZQyfhIILzDJrouIeyNj9tBtRm auoT8USbaLb7ZFt2I4M6gVlPONXV8Spb7lYG6l4gbPk8wCmtRaSfjDueLx2r9xGjmcv5V3gd6l+ qIEetEmeFnZ/JtkBATbcXSiXd8zZA= X-Received: by 2002:a05:622a:2449:b0:50e:6399:eed4 with SMTP id d75a77b69052e-50e6399f879mr479265451cf.27.1777294000911; Mon, 27 Apr 2026 05:46:40 -0700 (PDT) X-Received: by 2002:a05:622a:2449:b0:50e:6399:eed4 with SMTP id d75a77b69052e-50e6399f879mr479264881cf.27.1777294000497; Mon, 27 Apr 2026 05:46:40 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:653f:4d28:6a78:a6ca]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ba454d1bd19sm1091496866b.37.2026.04.27.05.46.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Apr 2026 05:46:39 -0700 (PDT) From: Loic Poulain Date: Mon, 27 Apr 2026 14:43:30 +0200 Subject: [PATCH v2 03/14] 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: <20260427-camss-isp-ope-v2-3-f430e7485009@oss.qualcomm.com> References: <20260427-camss-isp-ope-v2-0-f430e7485009@oss.qualcomm.com> In-Reply-To: <20260427-camss-isp-ope-v2-0-f430e7485009@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 X-Mailer: b4 0.14.2 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDI3MDEzNSBTYWx0ZWRfXwSRxc/r7CnC0 ++5whcb2F+huMgSUgvoDSYpWPxpqMQtE+fTsLQjNeO3gqG3Rkuxr9vShtvQHNXtVTVJeKUso3Bi MlC3FeS2bO0ZGFvRPB7gSqv1M1oFXejMlvGPzWqKPl2NHJ0bqBZppffANY2xpQ3pS0YoxMoWrL6 Fllxn3vjhLl/4JA7scWyddQnqJyivgFLcfnvg87xEmyepB8IO0c89hvDPc+s77mYRqpGNZFIyBq WvdMPsnDcYWKAIv5m73phUdRFNzBISnQa2Q5L6J6JnrqGsO3OEbgsgi0fHWkec8Ly25TgReKT17 hIHGeLOYsTT54kzUZe8bLHZeUStMG5iOOzN1VKXcEhZvMObeq4QE00UvIYOmTI3l1AYwY/dgeN6 w/MqDA4ELP+QGY7geg4Xhq9s1sJ2eE2tzRpxkOS9npcV+RyTXAGBvMT5K8d5/qLXXjvMJzsN6ng 50PEr2ueJyaQeRWypSA== X-Authority-Analysis: v=2.4 cv=a7QAM0SF c=1 sm=1 tr=0 ts=69ef5ab1 cx=c_pps a=WeENfcodrlLV9YRTxbY/uA==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=Um2Pa8k9VHT-vaBCBUpS:22 a=EUspDBNiAAAA:8 a=6k50daf3fveMbYCwvhsA:9 a=QEXdDO2ut3YA:10 a=kacYvNCVWA4VmyqE58fU:22 X-Proofpoint-GUID: NkQYSXmtHpGskhT8AuV4uU9ZY2nCeLb8 X-Proofpoint-ORIG-GUID: NkQYSXmtHpGskhT8AuV4uU9ZY2nCeLb8 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-04-27_04,2026-04-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 malwarescore=0 spamscore=0 phishscore=0 impostorscore=0 lowpriorityscore=0 suspectscore=0 bulkscore=0 priorityscore=1501 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2604270135 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 ca68ad7fc9ff30eae23d3baf34cf1ca642acf9d7..b2b0afc3fb5f597622f9b4ebfee= 2ec6703bf0890 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -4846,6 +4846,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", 80000000 }, { "axi", 300000000 } }, .csiphy_res =3D csiphy_res_2290, .csid_res =3D csid_res_2290, .vfe_res =3D vfe_res_2290, --=20 2.34.1 From nobody Wed Jun 17 06:13:00 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 7729D3BADBD for ; Mon, 27 Apr 2026 12:46:44 +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=1777294005; cv=none; b=VTAFamz6y/ox53aUss9IgUFI2H2X8VuVRm+qt0f27ig/8XqBnFLXS6BDnLE/9bXt1wSKI3DrUjB63c6EyO9uDqvD7Ok9ky3k2QuVtLqZCO5aUI5QLCAsLmqoOj7en9uD7SvJolBGJ39r0PRA3uJZFwHIIzoWIiIhZrfEZjE3RUM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777294005; c=relaxed/simple; bh=20WLnkiYWDQEOKwJiDNPOzP1Og78Nshg+iIm1A20VvE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ooHqKQpwOirTIVmqLjrDL4H1LuW6Z5lTwLbEEKjAsOZ6krq6/XmPJlFOkUvAJ7QjXhUHK2pIFHK6JRUcNR9L20LArl4s+jodTWtuBESbZwdJZG+C6xDv8MOJqeoaZFHhV1ad/ParUyd01/CZ3TMcyIaailVmAbRdeReXW5sdnxU= 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=G6+nG4/S; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=Vv1g8Tf6; 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="G6+nG4/S"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="Vv1g8Tf6" 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 63RA3nOu3123516 for ; Mon, 27 Apr 2026 12:46: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= 0rj2JamDaDnv/s7jI1Vm/rkzZOBtp55LTzg2o5dZC7s=; b=G6+nG4/SWFx3ErrK UsnkIxKAviaOcZrqkJhfVlmOmbHoQzjgInzE76+F9jqEJRA18gFD2uktvRJSUQ6C 4N9Ql9YDNEKkztC1cCidMFzTvuSuhClbSb/nvjjimlVbmXhCpCkr0RKK5VLQGsfF j29a1QNebdiFh6bk8yZwvQZZ8axh3iM3XNoya32/60lLGvc4VMG+JhcEQRHWJL26 Hlwlxb6cbPuvT2SHiR/odV23rSda1dvRxaY3x+2Xlf7mp59M8Gj0GuXPdDv64rva qd3+3TTDarwBXBKyGKV5CBtRSapgTvbeBUEDkTBIpMASK2Banbu5An6qfCIqY6Wb C0vtGQ== Received: from mail-qt1-f199.google.com (mail-qt1-f199.google.com [209.85.160.199]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4dt5qgghqk-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 27 Apr 2026 12:46:43 +0000 (GMT) Received: by mail-qt1-f199.google.com with SMTP id d75a77b69052e-50ea1a7a5d0so180468781cf.3 for ; Mon, 27 Apr 2026 05:46:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1777294003; x=1777898803; 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=0rj2JamDaDnv/s7jI1Vm/rkzZOBtp55LTzg2o5dZC7s=; b=Vv1g8Tf614rePhjf5rlkqimSv9sOhCtmKzRxPyctx9LuU46ck/2XmGQwGZhIsIs8Ds 5MquywZMwhSHVml8L0rNJUYF7BW+ZNdrp9Su8Z17RZjqwGFSJGfRH6wABO6jFM8T/xve W9WVPHw6IvuAZQwCnJsT9IEKihbH0H3OrWNCWZ4M9ySOhBzS9te8q8Xded6AIiEQVVJb Yi4xnoWI0IUBWLrkCnbxn2eJcK4USgh3XCTDyclgK5yvEucf+uLwGNcVTu6Ub+RcW9fH fnCVijCTwr/1F8HezX/GgTPzRTuWLBFchP7Pjg20ZsiFscb+VmI0zpPjSinbLt6mndis P/Tw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777294003; x=1777898803; 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=0rj2JamDaDnv/s7jI1Vm/rkzZOBtp55LTzg2o5dZC7s=; b=BbC3LMxwaKszqiguStmP7aPRFEjPTQ6tnxtdZBBnAr92odszKd2v03ekZHc4Z2cKm7 enFD61/8JvBPXoLDCbAV0Cmi6tFrqN0cjIiMs7//p+4/FZy9AxIXFGVhV2B1dKECu/ge VI94bf9IhICZRxWHen6ljrgIhtgfX19JWi+u8jZ86GaK1SDYmOVq+VqTXOndwAZvBNy0 JzCH2mGMc04G7G45MSHEUy8G6lalvnKN3EbUSb6sYPxEdadD0/0ZeaI+VmEMnc3/oAkD mOZ6NNolU02MWd5X5dOz7L3puwBLOFbnT3QtBtUp0bltJq4rhX8MupVFTKaEz7su+gSs 93lg== X-Forwarded-Encrypted: i=1; AFNElJ9YA8UMEeg3gdx0Mf2P7nRXEaX5D3O3/2Is/ujbAejwaUReYwIJbU63iTqY1wU1lupqfzC3QIEGxDRhheQ=@vger.kernel.org X-Gm-Message-State: AOJu0YzfyQOrxX1UvweZtPaoZ9qoG9+UbAuYM83wbsNw9HrzeR/G6uW+ kpT7ZG/0rSYPoFbAXXMV4USPPFqbhXT8toZKZV8r57J04YUHhAOik8Fg7MANCvSz7w7Th8XkGVF tglo42cmdCNYql1QfRfRFNDnQHk5S92/xaKO4v77f0TTU40ReRi2YB0TXBqIj8DKd6Us= X-Gm-Gg: AeBDiet1VobCr1Bz2AN1xa0epDHTBA3gZorY/CGiYYaKQ6IIkEizLtnvz3mRfY7TkBI xhCxRSzy9BuuMt/LijlXwVeVk1i3qPFuQU+vvfRkvIQANCVNC2xUKuNBBwUFjeV/2QFCAtNH0bT OwnTwwvDdj2CPwDaf6pAK5RsORVvjOmLcAXCws1J1rH+Z1LeEuTzVZDGquRdH/d+UnZXX82U68D Uk5Ff7H8C1HrWJQtSUfXtFFa6Jaub27RNkcMTQteUJsTW2c44Exkbp/jDpKBkXwouFH1nhYYzOU ix7Bt3hmxHKRWNIajg5YQyBRe0VcPAbmnwsmCwYvAsjqVKUO2y0PKfk+8RQl7X5uoRhHt06Tvjn jG5AU9Wb9DUHJvm4IhPyxWMgTpgucrrWJLvXcX7FxGFmCrtcGMhrkPLiHzz9kq50FfX9ByiHCx2 HeFmbdVwLdaDrimCLTfCSXpUQDS0Y= X-Received: by 2002:a05:622a:2615:b0:50d:8792:b6d1 with SMTP id d75a77b69052e-50e36c122efmr629758831cf.38.1777294002719; Mon, 27 Apr 2026 05:46:42 -0700 (PDT) X-Received: by 2002:a05:622a:2615:b0:50d:8792:b6d1 with SMTP id d75a77b69052e-50e36c122efmr629758091cf.38.1777294002214; Mon, 27 Apr 2026 05:46:42 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:653f:4d28:6a78:a6ca]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ba454d1bd19sm1091496866b.37.2026.04.27.05.46.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Apr 2026 05:46:41 -0700 (PDT) From: Loic Poulain Date: Mon, 27 Apr 2026 14:43:31 +0200 Subject: [PATCH v2 04/14] 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: <20260427-camss-isp-ope-v2-4-f430e7485009@oss.qualcomm.com> References: <20260427-camss-isp-ope-v2-0-f430e7485009@oss.qualcomm.com> In-Reply-To: <20260427-camss-isp-ope-v2-0-f430e7485009@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 X-Mailer: b4 0.14.2 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDI3MDEzNSBTYWx0ZWRfX5jCe8GHJV4BM CpHge9CketCk8PD9/ROG/lkNbB+oWP25GStOT0F0O7pKnBVLSGsrdLTOtqhTGcop3bmAwbwFuAx yWPfebxQEQqlFlIbbqLv1Y4LsUA5dOHqP8zpT8gwpZJqiIa+enWV0ObInWec8JOtXQP2BkSo3Ag YaGxAUg8SdSn6OYYj/E0kxmSLTqsC2RRR8RG1DhyzOBxTQ20ixrAD1dlavB/LuvEhfHknkQ09PY wvtIuFZUCKOift9epTfKQ6vIhz3VqPFFWl4nNJLNkcUHVXVJT6hX32ERMjCzOczfuhgXhdFMT73 9s1pStcu51nQFIy7YxWEifg20O7ZrkTXyP/87/W/O2JMOQcW0I8m2piNWgKc6pG/Odc9vmHgaLk lqSVc+Rthy2UsQw/oVNI5MR2TDvZpw2V+u3qNJJMYCqrLe3Xz2LaWnIefylhDhTwgFurxEdInT0 isZtpTCpuXTSn8xOLyQ== X-Authority-Analysis: v=2.4 cv=V69NF+ni c=1 sm=1 tr=0 ts=69ef5ab3 cx=c_pps a=WeENfcodrlLV9YRTxbY/uA==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yOCtJkima9RkubShWh1s:22 a=EUspDBNiAAAA:8 a=yFrQIQtVvbDJ7NVWecMA:9 a=QEXdDO2ut3YA:10 a=kacYvNCVWA4VmyqE58fU:22 X-Proofpoint-GUID: FYOsQF1EFRVcSWMZoARtIMXhrXihLpEQ X-Proofpoint-ORIG-GUID: FYOsQF1EFRVcSWMZoARtIMXhrXihLpEQ 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-04-27_04,2026-04-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 clxscore=1015 suspectscore=0 adultscore=0 spamscore=0 phishscore=0 priorityscore=1501 bulkscore=0 impostorscore=0 lowpriorityscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2604270135 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 b2b0afc3fb5f597622f9b4ebfee2ec6703bf0890..1fa42565c28a8cd461771821518= 875a8f468834c 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -664,9 +664,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" }, @@ -681,9 +680,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" }, @@ -700,9 +698,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 } }, @@ -718,9 +715,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 } }, @@ -738,10 +734,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 }, }, @@ -758,10 +752,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 Wed Jun 17 06:13:00 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 7B45D30648C for ; Mon, 27 Apr 2026 12:46:47 +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=1777294009; cv=none; b=BEQ0j+1umLnI8W+WRxqD2WyttxYU5llafZFbIUadSPDWXg60svjd2IeDt//SYAuUagMI5x4uWXFhzsULe+lxTtstF4JeW30Nx4HrVUIGcg5Ze2Jxvw4suqRScYiQEouYDjj/pzQ0Stn82pRh2gLfKNQjMk3EqgWtIHba6BAyetY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777294009; c=relaxed/simple; bh=WcsQ1A2YxNcqZOtl9cSQ1R0tPKuBbn7v12WXFUOf7gA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=W4Wd7HCHMjSYfHM24aX4Fj2Ml7yvQ2bpP2ro3kYI38HdK6YNpCt1AlYC3ZyypUsi3wyJ0aqyjK1GqGbMEzWWruhhGFXLZeoRwqjmA3z0XDe66tXF6j9EgueQfDx6pqOy1WubaMKmL+5XnOPAer/saVdGo2Nu+YKl0BRcn+Cz4gY= 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=onozB9Fk; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=AlmHr04M; 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="onozB9Fk"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="AlmHr04M" 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 63RA3pGV3123642 for ; Mon, 27 Apr 2026 12:46:45 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= 51hUPVD+vSajWa56BxpGzwnPphsgTAXfhVqxxWUWJ2A=; b=onozB9Fk2So+31yc 6n8zto0WVmWOWM7tC3ZnIxzQGo0enUF+9w9nizPp6/tIgDiw1YfKZExvV1VxAvIH VwUaxVxQiaMtf2Lx77RBQAEhfjpi1WnuL9zz4YEWcN7aH605q5wu8kcNaKKx+DrP WsllUYQHuvEWsZsMz5qoUlLhb2ghlAPu0kW+f0riXoDZWRDvLalwk9B89GxLftl/ lkBTzSqhp66uwbDUjHc9izohJxouSL4pKrF0soAl8VD2kJapUvmnS97GZ0EuJBHC nF9l98pA4r6eQWDaxWC12GgOhVL3MmZjQihDDwodxg7Sx42frZFtvk3OBnim5/bd CbyFfQ== Received: from mail-qk1-f198.google.com (mail-qk1-f198.google.com [209.85.222.198]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4dt5qgghqw-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 27 Apr 2026 12:46:45 +0000 (GMT) Received: by mail-qk1-f198.google.com with SMTP id af79cd13be357-8cd722c1a69so1823374085a.0 for ; Mon, 27 Apr 2026 05:46:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1777294005; x=1777898805; 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=51hUPVD+vSajWa56BxpGzwnPphsgTAXfhVqxxWUWJ2A=; b=AlmHr04M38iTcj87LzwsNtybHGwHYg9Uqf4Po6ZlgVzof83CyGpRzj0X8tQaLMBMkU pJK+u3KlruQXRdguVWww3eGlS8Ne0dGWdLbNqiBj2gSOZ3dj1g1RtApLu5JOt9IKrVJz Qrr9ePePQ2TY0KexStWgSwhu0LHwpRH0IRpIDZMRomnblYB/k7cFG3rW1otQ9xvbkI20 2evT8gU9pS2Bu8eelEskXo4ZQoHMhfsjK6dZE0gby/qjRNInK0IwOOV/42tw26rGr9pN jkvTksdo5684KVeXz+vmmzOM/6S/xXAvoU8C9+vsTHCwj54UOtsxWa3oeip1MGFwbW71 IGAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777294005; x=1777898805; 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=51hUPVD+vSajWa56BxpGzwnPphsgTAXfhVqxxWUWJ2A=; b=I/HoetPncO2FyfjPMvGRZtoElY62ltACF1bXPleP01YBYK29Ug38c/mw1DSgvPcl3B 7yd+rzZZfo7zr4LzJW5aTmfkGIQcjZcH0REZrSSmB5/QgJ9fv8/Enrtg3BZs+57yGjcE RJeR86ORQLOXRXYzmXEBgn/a0jATTaYmOakwWP0RlwktmbG2qipTCq3WQRDI17wZ6By9 S4Ks7SEfv2XlhZOeKYyCPYDSB0ZEdlny9TAElNXhKlpNNJ9iKSCp0ZrLkwAtCRAN7W2r m98fDQ2TK1JFUzrWPFWSHgd/3Q5t1VRm8b0Zs4fb0p9ZT7Ce5qTtglHDBlVUW79+c2kM 0smg== X-Forwarded-Encrypted: i=1; AFNElJ8aAQ8PutdfHQWwjLtmI5dt1SzXHFCAAjXIcyKMwqnmErcRTJeQfR/7pgr/Gg1nLdGg3NR8tIvIHG+FkRU=@vger.kernel.org X-Gm-Message-State: AOJu0YwcmLdBAdOZltEGSr9Ofv51pW9dE8siHx5MPPe9wfDrnvo4+FSN cJUyXlbQF8s377NpiNdw071i3C9XVtJ81Y2teSN/P41CaUp/6ETJ65TYTXs67ekLSPsdZCotbgV nssK+Ql2yvAQLlckt69A9Ow8iM78uMj7fIASBVATUgyPepAJBQLeHnxRX+INqNHAl4Hg= X-Gm-Gg: AeBDieuYSqXAig0jPnwge30xKwkdR/4gqgqMV1fESAG3j32HcslkWJe3FGpzMYCG1h0 rmxmzXlYHro7803xeyXZcywtuTx9//ANCAAWOyIFb7XaQdA4sYf1JvmPunCQ1C3SueHpEEsneKX 5UV+RAOCiDwfuXcouNrXjmWVnTwmbmWUeYFjfiP+QEUEY+SBzToS27VDqXc6IvPdD/6UQkUiGJF OcrJ+1MovMwbstnKPbnXaG2azhaJpOhmO/rK8Cmm4CPRfVjHjALCgnefRRwBGAQLekpIObd0RfV x/YHDs7HYEjWw5YCZlpzTo6JKQ0raXKAb0aLIpWXxL6kZ60GfkZxYteohnak16wDyYj6pXsKYEj maHda5sIAuoH01kqlj7k/QkGJDGZ7480J4KZTsUA16L8qUmkRHalhpw9SxmvSScWQKKTZ+9TI77 P8iwdy8kEinRzbFTMaqWDKq4FiydQ= X-Received: by 2002:a05:622a:8404:10b0:50e:57de:40d7 with SMTP id d75a77b69052e-50e57de4894mr368757631cf.19.1777294004552; Mon, 27 Apr 2026 05:46:44 -0700 (PDT) X-Received: by 2002:a05:622a:8404:10b0:50e:57de:40d7 with SMTP id d75a77b69052e-50e57de4894mr368757181cf.19.1777294004003; Mon, 27 Apr 2026 05:46:44 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:653f:4d28:6a78:a6ca]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ba454d1bd19sm1091496866b.37.2026.04.27.05.46.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Apr 2026 05:46:43 -0700 (PDT) From: Loic Poulain Date: Mon, 27 Apr 2026 14:43:32 +0200 Subject: [PATCH v2 05/14] 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: <20260427-camss-isp-ope-v2-5-f430e7485009@oss.qualcomm.com> References: <20260427-camss-isp-ope-v2-0-f430e7485009@oss.qualcomm.com> In-Reply-To: <20260427-camss-isp-ope-v2-0-f430e7485009@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 X-Mailer: b4 0.14.2 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDI3MDEzNSBTYWx0ZWRfX/TEeePcOTCve qc6eqjhwnxLF5ecl7Wmbhv9jVjmKUwDP/erEmHGjvUQ0SIb5jSyKz2GqjBRF135xylB69Q4pirZ ofBkXt/E5nMlMEuVSnePPv7RKwF/qvNdvHbo9bizSX//N/QAvAnMOE4ADDKoSQkINcvbGkfpOAe D4itWfTrW8l59xoZvwJJA+F76+Qiygq3rs2D8CVVGLCmdw8j2N4cOdUV3nDl8nICmPtdzknn5Ny NBnRjcU02XiMrUmOcn+LyIoVbCd1/N9wPTGVR50a1zFL4Wo7+QlQIVxt0N+R2Vltt6aEf3B7/Ev 3obDiYMt+5FBitL63ZmQrRCy5pUR9YeyCSektLfs/c7WtVA8VwLvzsB5zm2Nat7hBmfM3PfltbW 45vydJkwga59SLVPgqTKwn8CVrzvRu4z1JZzzPap61vnV8QFJ5/ftqOFpUGgNOvIf6LMflaB9iI MUeTodS4ycZK5XqGTqg== X-Authority-Analysis: v=2.4 cv=V69NF+ni c=1 sm=1 tr=0 ts=69ef5ab5 cx=c_pps a=qKBjSQ1v91RyAK45QCPf5w==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yOCtJkima9RkubShWh1s:22 a=EUspDBNiAAAA:8 a=jGd-OSDL_v5yqi5i-noA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=NFOGd7dJGGMPyQGDc5-O:22 X-Proofpoint-GUID: HUZzd9kvT0BnAsVlkZbgf4mAIE0yPXYW X-Proofpoint-ORIG-GUID: HUZzd9kvT0BnAsVlkZbgf4mAIE0yPXYW 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-04-27_04,2026-04-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 clxscore=1015 suspectscore=0 adultscore=0 spamscore=0 phishscore=0 priorityscore=1501 bulkscore=0 impostorscore=0 lowpriorityscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2604270135 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 | 85 +++++++++++++++++ 4 files changed, 205 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..2f04e38cb1cd198f180d744b0b9= 869b6f2b8ef46 --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-isp-bufq.h @@ -0,0 +1,85 @@ +/* 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); +}; + +struct camss_isp_bufq *camss_isp_bufq_init(unsigned int num_queues); +void camss_isp_bufq_release(struct camss_isp_bufq *bufq); + +void camss_isp_bufq_queue(struct camss_isp_bufq *bufq, unsigned int queue_= idx, + struct vb2_v4l2_buffer *vbuf); + +struct vb2_v4l2_buffer *camss_isp_bufq_next(struct camss_isp_bufq *bufq, + unsigned int queue_idx); + +struct vb2_v4l2_buffer *camss_isp_bufq_remove(struct camss_isp_bufq *bufq, + unsigned int queue_idx); + +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 Wed Jun 17 06:13:00 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 ACB373BD246 for ; Mon, 27 Apr 2026 12:46:48 +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=1777294010; cv=none; b=pHPQQhEyy9CU9mwQNOkxVFijvXEdle4ieNEHIMfBcAiZcPM/mUjwU+l5gQnKawFULtbSofQy6vMqtqUExzHNENt5sJ5twYxcSS0x6FeAY6SE66ehlV2wpkMRaw7ijBpsFTi3GobH+W+NEnkMP91i4tBCeGwnmH7v5cl6Y5PPrP4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777294010; 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=NnFXicrBajD3zMGcc7/EjW+ZdMxXcsPIQu27epyc8YzhMjCJyXtBdqOyJN7fg8KOJHVxQKNtJFSM64OpM+Csxl6lIhRTFKha2GDTTXZxvbQyW8w2WwV5ZKpRPihXHXnV5vCaxoQT0Rzqi+rUUHp/1ArBS9W1Bo9p1NJKyqASXJM= 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=eLF8F5PU; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=PyyL++1a; 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="eLF8F5PU"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="PyyL++1a" 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 63R9OlK13825438 for ; Mon, 27 Apr 2026 12:46:48 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=eLF8F5PUgIlyjlqU wU96H/fNTLCKWqK2P7rDL9L+IcjBLEe4hw/8WTX2A1zeerd+A7exH+Bz5Aaqevhx jPF+1wApxwdiWmL7XFcheqdYAfRmpgnw09ecyE9BYV0bqcXBfS3TxcvIrHYxdukF 2YF2he00UUyeAKxtiw0XQk6nuwdcUttcyaN9VbM/JSSoK9VLmfyenyYoYjFQ2nwg Ax9m/4RkF4v1gEU7AtrNgS+6+fEcbiJ97rMg+G9HIRtd3aIM5DpaX1X4+GUhCTuj 2OkFsen9lSAUBbYOFTXrcLQ9uT46kDcF+36ncGi2QvIcgi0M+IlgfZCcyom4yZ1/ oSltUw== Received: from mail-qt1-f199.google.com (mail-qt1-f199.google.com [209.85.160.199]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4dt5550r1m-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 27 Apr 2026 12:46:47 +0000 (GMT) Received: by mail-qt1-f199.google.com with SMTP id d75a77b69052e-50e5a336b44so130473911cf.0 for ; Mon, 27 Apr 2026 05:46:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1777294007; x=1777898807; 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=PyyL++1ayb6oGpeanS9EqfjbrskNY6HppWVqwIY6/68SQsoCtoTrpn2rnghh7y+7Yr QFwg/4iOLcvTRBiUUEAQIPdqkHRBwJ+JpKwbsVJAnIzOsieilBGRplTj9mUI2XYRvkCK nDdnISvsng/8Gn78wYwtfviAffWXwbDUnOql9V/vdByese89nTGsz7yqO+h2cKBFQ0Ji VvKgYUDzMsndpCzg7rX7Derv1BGB/Jgod5ugU1yWi8+92+8/YP7MHhLFqPUOd52hZEQY uXmnj9k/+Yig+yaSnirct2fNy+mUqElhy2hjbTiRnZqo2j77xsZO8DlY7oZC1X8hgTUD VrgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777294007; x=1777898807; 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=bjwhfgw0ABNGi86CjrwlqY6mVir3aXnf0fXkTXiPwWyEgsYVwR6qx6Ug4s8xFiHBUn XjxyCEOsZqPkDS7omj12FY5FIvrhlc+6B03QO8KKyvn5m/iVLFV+GcqF/vfiRYPmFViv YmN+5ofSIHRO91zZqh+B+Oq24yZ8+I2608eFGq1qO2KyMhWFUs9mAfSDTSo4MxDPyDte uDmLeYTOOcL7BWI4CsHb60sr0MMYA1IhUr2IK5ZshXXS2syv4A8kx+NfUzTuWCFrk/+r DsjBrjhRl/up+ULczRzoM7hICwXPeiVu3SdMGFWymLxyAz+l18G4boBY0GQPzshnJCbd 7HLw== X-Forwarded-Encrypted: i=1; AFNElJ9nM3jAHzWXwZYyyLcswu/0gaEj0bKeYwLepumOvzfjCt/yXVCKqDZWocWnDdL0ma3ubuXGaNgSBGmYgqs=@vger.kernel.org X-Gm-Message-State: AOJu0YycZOWgSfGC6HH0HNQZEWGSUShKP9kr+dhxE8VnNIQnzPYkbAW2 Ja9cP2pebIiUrkKrdw5sQHK2N4qmx6B2V2MDWo/2AABu2Isegc95efFu8w5e2sbB6G0Iat5vAuW 4ScPJw0IEC/YRXhp1YXXcl+DX7w43psuvvjxcnXmVW6sa/vC5KhfQkD+IqhfGpJm0jCw= X-Gm-Gg: AeBDiesB0amzOhBGezGFSoDZF2O/6f0kSdBv1WU8P7QxzuCLczuRviyOfhmcRAEmpcE 7u83oeDkp2b0Ioo4efXY6h5FreoZN+0JavYvnZQ7uBCd6fdo2LOMOKpOBvzxcvulXKY8mU7RUWm AtyncBMN3xmmjVX5FTQ2vIfK+5bloztjxTX5ppxTGtT2YhgXSk5pnf2tsvlwATxfYLl599sK5+s ZZdan3UG6hKXPMJnL5e6J3Ry5vuGq2ndtxDhV+qfU7pnuak9vSDDl5cpeqTkLABVzindU2QA50z XVa3wdEnYSBC1hnAmis7Cts4eLHuFGODzHbI8TU2Zo7nUyI64cwxuWIxUq5qZTMwJrKYAno4+uv fQnSi6PrC5s+qRY3ZvAW4rxQrJG5fOhKNhvQS7Z4gqRYjgXCkZtP5vuQISIWgxqKaZ2cepYvNPV dHIioUwzEqmAibCQx6l4ayUt/GLeI= X-Received: by 2002:a05:622a:d14:b0:50d:af03:c9ca with SMTP id d75a77b69052e-50e367b5588mr467378371cf.38.1777294006423; Mon, 27 Apr 2026 05:46:46 -0700 (PDT) X-Received: by 2002:a05:622a:d14:b0:50d:af03:c9ca with SMTP id d75a77b69052e-50e367b5588mr467378001cf.38.1777294005912; Mon, 27 Apr 2026 05:46:45 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:653f:4d28:6a78:a6ca]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ba454d1bd19sm1091496866b.37.2026.04.27.05.46.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Apr 2026 05:46:45 -0700 (PDT) From: Loic Poulain Date: Mon, 27 Apr 2026 14:43:33 +0200 Subject: [PATCH v2 06/14] 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: <20260427-camss-isp-ope-v2-6-f430e7485009@oss.qualcomm.com> References: <20260427-camss-isp-ope-v2-0-f430e7485009@oss.qualcomm.com> In-Reply-To: <20260427-camss-isp-ope-v2-0-f430e7485009@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 X-Mailer: b4 0.14.2 X-Proofpoint-GUID: 8iGauqeV1wi9foJ-VZaXYs8pvU11If0n X-Authority-Analysis: v=2.4 cv=CJEamxrD c=1 sm=1 tr=0 ts=69ef5ab7 cx=c_pps a=WeENfcodrlLV9YRTxbY/uA==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA: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=kacYvNCVWA4VmyqE58fU:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDI3MDEzNSBTYWx0ZWRfX56T4BsaTwB7S 1c5EshiX3DM8qgfVGJlP+lZuxH7dT7IS0zobqonC1TytOYMSI0IPLlZYinWehepzzT30rBGnmIR VqY8k6CDzTH+Zuz/17FvgghslqA5DM6VaBFdLAXqNfDDsNwm88GSJh/L74o1EfFfM0CHT1V1SEw gHHDJhOew7Ya3EwUUWW4FOEX6B+nPfOUce3kpe492rrGNx+LJb/zqGOkb/+EzmNOpYGIM2eqSRT CxoLheAjXBl8GYv6EWUrA2M1gTAvdM0B3j7jDJkof+tGDCzdZxJn/AYahMEn0pNm+a+m5gvwQ9A ZS0V2yOzfSvrdGZPg9d4MiRsTvJmnPHV5OPr/WqDqkK+u2DV9TX+X0wRLuPE34emr2WO1/9Hd74 tjNwBXLDn+1eDXmvkhvWJVYqIt05pv/CmTJEE9jIjwNPO4qVKDN/Py33IgjIG5qr/QCQn+UfcGh op+53nCAFytA6pYueGg== X-Proofpoint-ORIG-GUID: 8iGauqeV1wi9foJ-VZaXYs8pvU11If0n 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-04-27_04,2026-04-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 impostorscore=0 malwarescore=0 spamscore=0 lowpriorityscore=0 priorityscore=1501 adultscore=0 bulkscore=0 phishscore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2604270135 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 Wed Jun 17 06:13:00 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 6ACD43BC69E for ; Mon, 27 Apr 2026 12:46:50 +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=1777294012; cv=none; b=CRcQM1kAQETUaxndDbZLuFN+U+Pmft7rlRKTFYAgfw3Gt6kBTjsW5fYoo1khuqzoaCD75i6m1wgQ6uumCFUKMf92Y+5spQtII1ApEHNg2UCxi37mbpgFL7Thg2Otf9QFGAEWkmBx5BrEwnjVHkGR7jXIsoWbRf83PxzMbUfqNEc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777294012; c=relaxed/simple; bh=BEE5xtYLMIHM5H/+X+OLu6ImhtuWkEKhW4lS9LNnceo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZZg1DsYw8LaZxQHHALYvFL2MUSSBWXig6NzFIpz9odL0ppLYs0fUcf6vto/rLq4dj0xagjFJXvVtKsNjDeDiHhek688drQVTWzvRgdj90vgTJXGkHiINzRi3/rukj52UJZKuDQB1HdhZp2VvsOPlYYfserBHrNJeiSDcVFUl6KY= 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=jgLRx+rz; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=RQsIWcUl; 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="jgLRx+rz"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="RQsIWcUl" 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 63R8kMjn3962028 for ; Mon, 27 Apr 2026 12:46:49 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=jgLRx+rzZgP4KP5M AVIpy+VUCzJW4b6Ru3qG4RzGzz8ug7kFG4hWUipt5DZ3bjBDf5vVynPEVpgwBVR+ 1VUJWJnlPyqclak3UHjX+FqPdhe6SZRrIdGE5vn/BcJTvoczNA1YLFB0K06pjRx5 eiGU9KZAfQcuk5GIsI6n2qxBM1CLBsOXwDcbWGIQaDZHE++7/n+mTTX/6zNeTroG MOUI4HRwhrCmAu/5eWleYB9ZNlSccS4dlXuereGrEuwtDz7MKMKXEghKgeql/sB8 ceapq30dqZ5LrVYz1fYXYDvdC95cHRiwucsvoXNs8Cy5/NWWG99c6T6Wxn8N5VaB Fl4NQw== Received: from mail-qt1-f199.google.com (mail-qt1-f199.google.com [209.85.160.199]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4dt4k313nj-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 27 Apr 2026 12:46:49 +0000 (GMT) Received: by mail-qt1-f199.google.com with SMTP id d75a77b69052e-50fbc49bef6so109245361cf.0 for ; Mon, 27 Apr 2026 05:46:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1777294008; x=1777898808; 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=RQsIWcUlZepwL3U8bJ0EUX5nOTdCwCwRrfcClmWcw2ed4S7Iu5YyaSd0dD9cJm7KrG ZdgfxS/uROnrjKSyP61al9igkd6J2ltTkSbxwlevdNKWagYE3vKCxJDLljQwK8wkxSZq 2cjI90eM2l4LTmf7Y0FOcUNdLOj3A/z2KccEyeze0pHukgdYQXMfDVOZeJDTIYTW41o8 7fKAzMBVK+BgQerMLqSK6pSQgAUhM7CPpqvhubrZEp33/6Ky5erjZGxWQyls4svvR+ba nHrSW8szBFGdckkmp/HvF6KreArYAZAUGqvbBqI27E9SbQC34xLHr6HfW7CnJ/Qh5Rqg M8HA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777294008; x=1777898808; 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=T/7gTyhDIe/EaRN/X89p1JGpEqUvpgWDQHjV3L9ECDkjPedDqnmUqP/qfl3zuqOuhj V2c2MfK46tN2ZJdFuLA0dNQt/0mJCvvxkb3+Ru2Q0ggPrQS4er+eLAmYM531lOpblmjl r44SRJscA3hKgA2GcOMo3NDiIxYZtmSWzmk6zL0ELTMcw/AkcHHs05gH6geWIXYweAWg dS0Dxx39vGzdz7AULWTO9PuRcxO2KmbkQiIX52NJJNPorMr57bGhhIiJ7dFztDaqK8Vd DIuIMAZDU4yR2VPxSSVL71b0WvwVs/9ktb18yITAjrdiskyRzcKG+6XMWUicjQvbFVAL MK/Q== X-Forwarded-Encrypted: i=1; AFNElJ+1k+wqJwCsYihvsRwAlZdJA3nKNpKEy0dQNXr6ThTUigQWeZKK04I0kT+yPXyYvsJ0OhVqqTuJFZ5Q94w=@vger.kernel.org X-Gm-Message-State: AOJu0Yym/QK2pKV0YQsooAn2yEpVq9ojg1g3eiyJM43e2ysyME2Arigq ZRjUUcyUhTVaiWV6SwiUaNzSTV9sW/SkJVFj6bn1g55T7mPfpayhfgCk2GRrPbffgZjTzjVDcs+ 3FAbaXJXFPO1B+iL9qlYiLYnmlCwbk6a1gVeHwQ0XXIGFiSskSr4YbALqZulWeBFm9Cw= X-Gm-Gg: AeBDieuaTa+k+LbaGQLWWbimTl+Wh9IMdedjlG2Jc1zW7cLDAbIkZk2UNku07q7SiFO LWrjsZnT8zzLv3xeRdMPpupR21X1kbZ9oM0d4noFHTN0MZvXPknRMrITkRi610H8cUgENCDr5rt kcnx3i0Pba02LvNsYfn6sSzoIc5GwOUhsc0aIzZft6yi11GO0ishelXwrUADU6K9xiDAauAO4hA H8V0Jn2Gv9Nb5tBXkZw794ZwZG5gAWiPFqRcLebKox5FPLZexQUMEVKPhxy1JSELsZyJe0WwYd8 rK4jL1kYGDL6IkawFWjJPuRKVRas15j8Vg8fmG1LyNY0YGVCz27OwlQFHqqTaNUrl5Core68BQi 0c9wRVwOs/Oy9rgY3Yk7u0gDNC0qKFxSHGjJIJpYi1cz/I1yggqirjNFcYWP/Ancqd44FAaZctb ttPIH6aKoXf4l2QTg8Hv1SLUEvmZ8= X-Received: by 2002:ac8:5f09:0:b0:50f:ae67:96df with SMTP id d75a77b69052e-50fae679938mr458565901cf.50.1777294008240; Mon, 27 Apr 2026 05:46:48 -0700 (PDT) X-Received: by 2002:ac8:5f09:0:b0:50f:ae67:96df with SMTP id d75a77b69052e-50fae679938mr458565501cf.50.1777294007639; Mon, 27 Apr 2026 05:46:47 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:653f:4d28:6a78:a6ca]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ba454d1bd19sm1091496866b.37.2026.04.27.05.46.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Apr 2026 05:46:46 -0700 (PDT) From: Loic Poulain Date: Mon, 27 Apr 2026 14:43:34 +0200 Subject: [PATCH v2 07/14] 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: <20260427-camss-isp-ope-v2-7-f430e7485009@oss.qualcomm.com> References: <20260427-camss-isp-ope-v2-0-f430e7485009@oss.qualcomm.com> In-Reply-To: <20260427-camss-isp-ope-v2-0-f430e7485009@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 X-Mailer: b4 0.14.2 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDI3MDEzNSBTYWx0ZWRfX0Z71EJjJiYIE EV/eYuQzjZaQHnJtiwsxX5rRpWoTGQZ6yN6nuRie2B4I7RbAZwifLHZryCTBlr3OgNNvGSJIFFZ 98UHZFQgfr/z7CUk1sqJdHLAMXZ52vLariAcFVoZZD09BUgR4D+8k/BDMmk9LtkZS2+LGaZaCqW IRWDgEdOHveYK8RQgB7qkreogbucIifbNXwbA5NeKpNjUJOH+FxJfFCpKm5OOkfF+cn4j2VEueX 8aZQUN2ZRZ403JOejpAQH8wcVEfbiFuLjy2Ux3tiHMVSOkIDjmv3MSdoTojv1rpPd9c7swnvTOS QsW1Zhwz6A/exTN1ofBQ1+JePIIU2ntHcXR2pd4gfzmqxHMvY0YHhRyguVY1j7C0DsWMV0/C90y rRDoYhKh7PYL0Arq5vNjwT2FYwLT8cCp5vZhrOr4Ogu2+wwnVQl2jRJC4VHgTQ3jahK4SXB0GFT bwE9L6hJs52aTaO9BgA== X-Authority-Analysis: v=2.4 cv=a7QAM0SF c=1 sm=1 tr=0 ts=69ef5ab9 cx=c_pps a=WeENfcodrlLV9YRTxbY/uA==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=Um2Pa8k9VHT-vaBCBUpS:22 a=EUspDBNiAAAA:8 a=0HvUUkHzQstEScuQiJkA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=kacYvNCVWA4VmyqE58fU:22 X-Proofpoint-GUID: 6alKSiiiA014AbWtsuWFr-5K8DDw940g X-Proofpoint-ORIG-GUID: 6alKSiiiA014AbWtsuWFr-5K8DDw940g 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-04-27_04,2026-04-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 malwarescore=0 spamscore=0 phishscore=0 impostorscore=0 lowpriorityscore=0 suspectscore=0 bulkscore=0 priorityscore=1501 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2604270135 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 Wed Jun 17 06:13:00 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 A0EE83BED0C for ; Mon, 27 Apr 2026 12:46:51 +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=1777294013; cv=none; b=AoRNrfu+vH5VMH606dZB9Yj2vzvuDy2NslvEgA9+pUC/h7aOCFXS9yIuBwAg+MExNXSKVCsP/C8J8kehMzjIVCtaR5Jq+l1eykCcfJ7I+ptxo3dXy3jnJFdzvTSWzNlDjv/C3Z4x91NMJAKzojTlOaOm1XAb414VCvq6zaOx4GQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777294013; c=relaxed/simple; bh=lPbPNpJ2ajYXcbSU6CUgF1cdOaknw2iS5g76PqOTMJc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=A/yu4evCjbdb+xOPSeZfYPa446T+hehLn/X0y9y898pKNQtlQ7ezNfjQin8ftAs+QEvYfjZPBH7yNjibQE80A3TzCP5PCekvarnt7RFLpBaf/NQzHtZw4A9vqRZ0nTTc3kVue2/cKYnhfDYRKgfMQEK46JqFBljquqOCe1Qmg30= 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=kbDvfWxb; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=iqlwG8O7; 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="kbDvfWxb"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="iqlwG8O7" Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 63R8TAaS2793059 for ; Mon, 27 Apr 2026 12:46:51 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= +rZxWV2BVzHNmwNyI4KXBWCRAzv77VAsdiAZYzEAZKc=; b=kbDvfWxbKpo8tYce l1OaVfKx2eJfaNCcN3nbhN2Lz1E/0sxlqzqE/RjKegt0WTh9cMYUFgojSREZ4iho 2G7DoUdE2u87qIdqOfGsDgpSnjO/UeVqeaYIuYoPyPjmcNh269gdn+l1EVtu3ZgH +3qRqwo8MA8ftaSrORJj6BJ05Gmb+NUUib8F0+6TEmz3dlVjcszu1YOtB8EGELvs Dn9x5RQK9EM3RuD8CMbvwpS4ah+fXLPlfnifaFrHDDDHIDer/qS39P+6RjTWwLA9 xMFRRJfGWaH9MZsyAroL7IndcN6/4lbKkLRlYs2SO3fbHmVd7LmyHKZPZcA5u1Jh BYXN4g== Received: from mail-qt1-f198.google.com (mail-qt1-f198.google.com [209.85.160.198]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4dsa4uv6wj-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 27 Apr 2026 12:46:50 +0000 (GMT) Received: by mail-qt1-f198.google.com with SMTP id d75a77b69052e-50edf0245b0so35499891cf.1 for ; Mon, 27 Apr 2026 05:46:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1777294010; x=1777898810; 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=+rZxWV2BVzHNmwNyI4KXBWCRAzv77VAsdiAZYzEAZKc=; b=iqlwG8O75Zg7jCNRHXfk5Vqk7CUxc3cbbc7NSwUjEZ4ftprGERSPIwg82wPaYLTnlJ 7UKNtS/ToV8pRjmmHd8d8ZklUizB5k5o/+kKc7BBnTC2sNu10y2nlcZSkSdhmQzVwYXF VEy020Y0HWNpUpFhaGxBchZcuHkZSppoKPNmCpYnV2fDnzsaxnEWNCAqeoVJYCFC3Pvm LEVh4U2TQ0LmyQkw6k1PwmsVD9WNZZKOoqoqjp4JiYjh+SMR6BOdz7YKELwExpKn9OgJ IQN/ymehbm/oEzd5nCv8Fow5Zo26lEnApjQKl4tD3crygFuaBMypmg/7mQF05uuNlR4P atFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777294010; x=1777898810; 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=+rZxWV2BVzHNmwNyI4KXBWCRAzv77VAsdiAZYzEAZKc=; b=JJ1Ae+v5v3brL9uit8FShzj3Xteb46X6q5cGL8IRPxWUOtwkQpZtz/uwe2Sgo39DXZ J9qRSC2woWOPueubDLYsLQAzImRRtvbft/OGjOLX0YXamHD6Ha2t3uWvyDL3k1ycVkqv 4iiNxvRlj2/v3tbkz7XmOvhn3yzCDpeD8n3KZ/vQubixor0pDs8uPY7IR4cARgo8YrXR O0ipykQX6xUV+hNq20Rx6SbiLI+VskDjXvfry2QPNsckQzxN6EBhSfZGtqKOE4x5cifl WMAcd7tf9csl+dU1pd1I6fKXcIniiI5IUb5BaSPPfMvWArGe4YT/DX+cGKlt70q+HILV yQ7A== X-Forwarded-Encrypted: i=1; AFNElJ9g3/l5Qa+SzNaEMPa5w1AhuKQRn1w6KLjelRe456kkWrG/Y5wZGxQUQMMmWErkYeVxX8wcwdfBXouxBF8=@vger.kernel.org X-Gm-Message-State: AOJu0Yzbt4XnxckVwxKrSOZPUkyLyjoVYjvCDbYbfqtMuIzmDFNNiPSh Aj+O2sPdl0WZ95AFV2yeXhtBSD560DxfmI4KSbi5DOzHEkE8ZwIRNCACuq5VyPeeHi3NcDOV4NT 32OX94Nmea1xO5qgpblVg/j/7Ck7rA38GNgD1/w6br3SadD7t+bXDPjkuX71OvwrS8E4= X-Gm-Gg: AeBDievJdtXVZKEb3cDv4plzu/YHPidtgILDM/Se7xnQGJ4EZY5oycmhUrbUbVExdaI nnPxI5kaUxAVXA24E5ZJxp8s+aNG7RWQSTtHTHkR5CAQbf4tt9IheGlFSJ+IbvT2gXIoHokVL1R lHsxfBbYONycZPVXyoGzlSpaDHRISnslHRthnAL3Ggnr21WjaOHZTwncY6U+6uKk/SwjrlCYvFp yQENHMVEpHMeMsDJEcEXksqzRzvTRSaf3EpjBWiC/dQc0t6yQifY49TxMC/IIPds9eprFqEJheD ijtYIWL3aO1iLq79VAGzBLeDAyhRjNw1ZFdIi2lrTpJ8yXxvl8c6GdbQNUxFiyKxXxgZ4i6K/RR 3E6S0uyl2dAzzGupcn6E7wh2AEH8TD5mj8o+s+p4NfhYtR/0lNp1jl707kXDxdOxpGU+LmQjDXw cihT3Yi1hm6E8fU/6+7I6Pu9Tj7sI= X-Received: by 2002:a05:622a:65c2:b0:50e:5acc:e792 with SMTP id d75a77b69052e-50e5accf287mr351235111cf.14.1777294009715; Mon, 27 Apr 2026 05:46:49 -0700 (PDT) X-Received: by 2002:a05:622a:65c2:b0:50e:5acc:e792 with SMTP id d75a77b69052e-50e5accf287mr351234781cf.14.1777294009301; Mon, 27 Apr 2026 05:46:49 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:653f:4d28:6a78:a6ca]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ba454d1bd19sm1091496866b.37.2026.04.27.05.46.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Apr 2026 05:46:48 -0700 (PDT) From: Loic Poulain Date: Mon, 27 Apr 2026 14:43:35 +0200 Subject: [PATCH v2 08/14] media: qcom-camss: Add image formats for Qualcomm CAMSS parameters buffer 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: <20260427-camss-isp-ope-v2-8-f430e7485009@oss.qualcomm.com> References: <20260427-camss-isp-ope-v2-0-f430e7485009@oss.qualcomm.com> In-Reply-To: <20260427-camss-isp-ope-v2-0-f430e7485009@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 X-Mailer: b4 0.14.2 X-Proofpoint-GUID: DltyWIVs_KkzqiYigzCmB6x9scaswRhO X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDI3MDEzNSBTYWx0ZWRfX4NLEW8MrnkKT Qa3kMhx+dtYn0Gw4BfKa/U3xV/utJ1Ht4e7Oi1PEnXMU6yvW8kaandnJLs8YV3jGhqheRTxf2s/ voK1ZJtaEIlQwLJ360GDfVp1LXfWspQBv6WxhqN/ed2E16hhavLdfUs0bxnw1fQQ1yGjGv6g8fM Bdd0IN2et0/k3UWPeMssj4eiIbLJ2SiKQBsNVzC6QJEb0d5L7x+3FgMvo7xhMekp6sTcajs+LHO aOhg+rymrhcs1YoAoqVYD7d6PQ22ZgXlp9g2aIVj7SaXr7msOiMc7f98OLR+pd2BRfYMWDYNyrZ Nt60uvrWf2MxdGQfYABTqmm8tEG9IgNoXjfinGhHda3Nu7DtGuCUFk7ly4j8Y8NPqOI9m00IHxQ /+0OeiiKJM5zFhCHMUe+EFjs3G1Nv9dwlUOIPgbTcHl1dCnC5J94tqTVBCQ3H7owubLWV2zrKyp L31QFDrSBGj12+lcy1g== X-Proofpoint-ORIG-GUID: DltyWIVs_KkzqiYigzCmB6x9scaswRhO X-Authority-Analysis: v=2.4 cv=J/GaKgnS c=1 sm=1 tr=0 ts=69ef5aba cx=c_pps a=mPf7EqFMSY9/WdsSgAYMbA==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=eoimf2acIAo5FJnRuUoq:22 a=EUspDBNiAAAA:8 a=QedBaXGEmMrZQ1XkLmwA:9 a=QEXdDO2ut3YA:10 a=dawVfQjAaf238kedN5IG: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-04-27_04,2026-04-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 bulkscore=0 spamscore=0 phishscore=0 lowpriorityscore=0 impostorscore=0 priorityscore=1501 adultscore=0 suspectscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2604270135 Add a V4L2 meta format code for the Qualcomm CAMSS ISP parameters. 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 Wed Jun 17 06:13:00 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 E2EEE3C0617 for ; Mon, 27 Apr 2026 12:46:53 +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=1777294016; cv=none; b=efKdSFgsQXHxP0Oy9BhcwJfy+GwXhkSm0GFKPtFkzUmVSPl4xNUsASlRkOq27tV0d8nv5hLCpEKN0WI/HcE0sg1b1tQyGTPtRHlZ+X+YcRU0yTheMt3YDMNNvnoBCkMUWxyFBxInH+uCIr68v/ZRZ0R/cXbdSPhBi4tXBKJbhR4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777294016; c=relaxed/simple; bh=KTYQxoDHRK+AaxLzVW7P0uYiEE/yFjt5Rigb2R9yyTw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Wsroydu4mVPxx1BgK3q3ZCUfJqzNJ9uXpR3PY2om4rfdv0YKtu58qCrwzyWGfX8ENJjBxuIrqkjJquh65qyIPBgFTKHOu02d4vINCMJHEeyEpZKrheel3iFUL1akoKLmYECIqolb4T13dj+90AuddDI01xQ9sgIb+w2QfIh6VsE= 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=WxzE5sKU; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=Eiagujgi; 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="WxzE5sKU"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="Eiagujgi" Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 63R8TAw02793056 for ; Mon, 27 Apr 2026 12:46:53 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=WxzE5sKUJY2CJxiK nESqJSdcWh/FJc+J3JBtN8HnTz1fuuzS2hrg2UBweobcL19MDT/Ouoo/xFeQd3ef brOpMDIlzKWfnwMzo0vpi96xZNEYl3/6sFYyfM3JpDQwuo17LIbvTzSYExoOtuOx w/UGwb+fLTsRArABEHW8tBnA9/yv7t73qemSza51qf4KcM5QKRNW0BkWiCAHw/XR rbmYp7hgCbOvaLbsjXY6PLz/OsVyAH78giWn9zdIk59Kw0W0glVd/Dbmxu7KposP 48DeUl1MXSf+mwNN8sNf6FZBBX3F4//h/6Ub13Z2qk9IobI5uozO2qGEsLUMfbqc ieehiQ== Received: from mail-qt1-f197.google.com (mail-qt1-f197.google.com [209.85.160.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4dsa4uv6x5-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 27 Apr 2026 12:46:52 +0000 (GMT) Received: by mail-qt1-f197.google.com with SMTP id d75a77b69052e-50d9a6a853bso143495451cf.0 for ; Mon, 27 Apr 2026 05:46:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1777294012; x=1777898812; 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=Eiagujgi36awTPYrqmRdkgP6OU+ORKOONattM93eKzMuWQOYUkncHbu2czqXE0FikC 1nzb/NaoPYD9OuRu6Fi6sUA9IIcsbvZz2+jYtTf0iQnP5rfBBqpzuESUl4knkuLUpbkk oo1t4YinT12rgK9ig+igwq8TslHxiO2CrbAJLNPQRjEhdOeIKofSTXGyXOPvA2WskqYi XSulytnKA/Q2u9KxiZKENzeaHlpNZRHdumLZENklZxNExhO1aI6zUkyUn5lbqeCj6UAV 4c8bq4shcRPJhHHcu5ykPpdRRuG6UI60NzCyXwKfqt3g7bs8kkaseDI+wZW+YUqL7pon DxAg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777294012; x=1777898812; 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=cI4Q6qR/caJoFRlXqobGxwIz3ZKxKcan8R/SaSry+C5otCM2ikPamOQieZSZax/GCP x28EpG1DLKQRfVSEeu7Lt/1XYiAqMQe7d5kYcu6+fGmkZikjFjZAlwBkRr9Sg/iCZrPh IW5b0G+U5KoiAw2GkqLSOoq+mDw7oBLwFDDBzBuaCrUyAkDqXEeBEfxzyxev9pWMp6Ms k8U/MkMh07sK+OIVl5yJLsNjBvgXx5SHJTGavM8f5pHb597ljs8eKUXHiK6lbpd28Xti K98UupCHhqmofMSuVWPEuWdNiQFDinDBmBeBj1nGP3Vk5e8f3UJpz7WmIZBFwfWy/QS/ 6tWw== X-Forwarded-Encrypted: i=1; AFNElJ/ds0wyZdZ4CwRUhmYBZjIzHjnM+Yx5aZ5Hojel7lJ8TUkLgA5DpgNgrC+CmWN2aNpDRCDjRb3a8oUN2Ss=@vger.kernel.org X-Gm-Message-State: AOJu0YzdW34is42zNPsvvF14QvvocdklYwePzv9HR2vRDb9Kj1EotDux RTElIM8D1yQzyUspiMzycar76+fTJFjzDvcSkqJoWXVCep94ChCoJ0ORxdIsTYY4qh1O2VnD82e FrC7zSCUqGno1z6JyJunkHiXZbK3uTcmljWIRHjigo1X3W+SpJwVG1lDhKAAN3BzRpZk= X-Gm-Gg: AeBDiesXzRgrRGMdR1fuSLLbRum+9Mfx9W66oWDByd5JuUXLAWzO2S2OoIww361cCUw oJ9bXPTAbYDYtKXanbKRTvR+OOlZBMFXjXnD6DV1FEAfBbSN7aWPRwf/pK+5jYke1ZES+bmSUHh RjZiYCqMsfTZwS/wa2HJjy2kcLkwtc6qb+vqffzjO8skUmGZz+tQOTJZxhg4t8c8MqAUri8rdJc iLSZwVCE+AhvxK3UmIJeCHpEpZBKZKcxJsYNkdTiW7ixreOIgHmeEPEH7PXBEQU8Af1lpnvjWWg 3lAmDr+FQFeWeLctGX5o/4ce6rD6qzSGmbloexvBhec3LYV5jUyFLx8JK7OQEuIZukVErJj8NBW c2/pgoWjwBJLCgknUnCYJMw+XsGtv1cfyakG9K05qyyUpGrRnavSwNF4Fqt89C6j1UbtipWNCfj gzcdGJFWUbfigD2WfSEZ+34PdDsJg= X-Received: by 2002:ac8:5895:0:b0:50d:ce35:6e67 with SMTP id d75a77b69052e-50e36eba371mr600763641cf.42.1777294011632; Mon, 27 Apr 2026 05:46:51 -0700 (PDT) X-Received: by 2002:ac8:5895:0:b0:50d:ce35:6e67 with SMTP id d75a77b69052e-50e36eba371mr600763061cf.42.1777294011031; Mon, 27 Apr 2026 05:46:51 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:653f:4d28:6a78:a6ca]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ba454d1bd19sm1091496866b.37.2026.04.27.05.46.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Apr 2026 05:46:50 -0700 (PDT) From: Loic Poulain Date: Mon, 27 Apr 2026 14:43:36 +0200 Subject: [PATCH v2 09/14] 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: <20260427-camss-isp-ope-v2-9-f430e7485009@oss.qualcomm.com> References: <20260427-camss-isp-ope-v2-0-f430e7485009@oss.qualcomm.com> In-Reply-To: <20260427-camss-isp-ope-v2-0-f430e7485009@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 X-Mailer: b4 0.14.2 X-Proofpoint-GUID: COx72v5GnWC-VTAOqhDU8ik87N9tuo0t X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDI3MDEzNSBTYWx0ZWRfX137ja70Gnv0W I+7Jm5b3K2Ff2JhZkooM8aPot0emuMTxQ7hWJI8GRoVVbkgyxI46DAShin6kA3bSAg3ufHSK4FP Yw9IU3qPtYrT0dJos0O5WPR+9sS13lvJXKqEH2nzG3U5VZli8RBDC/WPfH96rwaL3YJon9mkgPr k0JixOo/iccprMT/5HnkEDaLDgIjOWbvLMQxrYdPOyVlpxwoH+ifqViyhQZmLAxEdywngIpyFxp E/vgtAs8PRQAHpQHflzSdQdyOsydJaa4ekx/WDWuhKtlImfaSFfaSRefvRBROgjJbevqF9aELLi UeQjhaK+/8LAe3MkVCPGCfn9kyDnQYW7Su7bIKkJE9/EmtPO1UB/IIXBzQEluPq3wdcfk22sFga 0A3Hz9GIZWXUGz0y+TCBmLeiN/5UuAAR4VucfMS9u/3KG7qq1VVmBzc7f8X/ZyuQVcJpk/03trd SBxz4Dvc7pa5wYY6qaQ== X-Proofpoint-ORIG-GUID: COx72v5GnWC-VTAOqhDU8ik87N9tuo0t X-Authority-Analysis: v=2.4 cv=J/GaKgnS c=1 sm=1 tr=0 ts=69ef5abd cx=c_pps a=EVbN6Ke/fEF3bsl7X48z0g==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=eoimf2acIAo5FJnRuUoq:22 a=EUspDBNiAAAA:8 a=ELVW7ba-Z2avb-AJsJIA:9 a=QEXdDO2ut3YA:10 a=a_PwQJl-kcHnX1M80qC6: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-04-27_04,2026-04-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 bulkscore=0 spamscore=0 phishscore=0 lowpriorityscore=0 impostorscore=0 priorityscore=1501 adultscore=0 suspectscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2604270135 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 Wed Jun 17 06:13:00 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 1310C3C1977 for ; Mon, 27 Apr 2026 12:46:55 +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=1777294017; cv=none; b=nS/MN9+wD/AdpFC5+xYulXDyzC5/uwOsq7ICeEsnHZyu4t4X81Cy4FeH6mhRiE/B6xaiuv/7s6+r7xyKP6T99YkVIObMifV0V49Nrn1dVFcBd/Sv1S//soWgptm4EGsgE8BH87WrNLYzWFd8zvQ3SZ5q3jLdusdY1p7iVr4Fano= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777294017; c=relaxed/simple; bh=MOx96nk8+K3X65iJbnE7cnDVWRW2qZP90gd3iYGxINQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KLF1pe3UCf8PNm/CpZXpZKe0zs73Gav0ENb2bSysJvwsTFz1geYdC5V5ZLo1JKEHmWmskFOmzmA+Ggd9vQgvTgpZQ9nEzDnJCvwvKd7/2982azF8hmYQH6l4/4h9SE6raxmjeaK744JUiJlCNj4B9fcesfFeY8L/SVfbTGW3HZk= 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=AI9xGh/B; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=e9oJZFMl; 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="AI9xGh/B"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="e9oJZFMl" Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 63R8TAlU2793094 for ; Mon, 27 Apr 2026 12:46:54 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= 60/MBbjIS4gVvBbUhWp9MfPwL6PKKn1z3/apxZjK3bY=; b=AI9xGh/BRtgdIiC/ G3cXNFb2/9zGLySsZmTuS71/F5HZ2is7rBQyDpAyZ5DO9itit+OLa7lGpJTSTDv3 LWGdm6yuujh+U9hRMP5eL+QNAq0se0Bbc8iPHIcW76P5/H/XX+0pEx/V166H05HD goCPdVPFISgU36lMEZuevGetYm2QL9Fi9dqzHk4czy0g+ub/FfktFJpofaGn81XQ 04PdpGRC5AyNCIRNr2Ansut5spZyzRa0O8DEgCjyvqdz3TKe3wEZ51dfY8m8QNjw Qtop29DAzQH9b0N9bEKq7TWWcHVuz3BGc9s9c/Gndcf5pQ+lgY3t7CovxnoCYIyC nrhWpg== Received: from mail-qt1-f197.google.com (mail-qt1-f197.google.com [209.85.160.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4dsa4uv6xb-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 27 Apr 2026 12:46:54 +0000 (GMT) Received: by mail-qt1-f197.google.com with SMTP id d75a77b69052e-50d9a6a853bso143496021cf.0 for ; Mon, 27 Apr 2026 05:46:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1777294013; x=1777898813; 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=60/MBbjIS4gVvBbUhWp9MfPwL6PKKn1z3/apxZjK3bY=; b=e9oJZFMlZe7Xuu+aSI3VgRbRgBefH0AF7hE16xZ5skg2TfoEjBMC9xxGmril5Hkpv/ 2vhGJZS4TyVhXX4kzAdp/TNnhl7XAyWcYs7vGP0pxm3WqVILtyOY8/9IHv7pkM50s5Hj BxC6KsQwKlNH/nRWC7tYKSEtlLLwA27iGeMi6qCNnZMOh7MzqA4eboi8Zi9rTEQs50fl tcK65/sAAV0jb87sceUWxI/N0ok7PjPwTbXTT7+eQ1k3twRUtMUVa+rWjLt+h9emVnUB CM94PYNQgxI1Sfv6t7QBwkQHCTsOAfZ/QDeGfxPqUuyZyraxPiwdkPhPl+QRrNSR088h EnwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777294013; x=1777898813; 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=60/MBbjIS4gVvBbUhWp9MfPwL6PKKn1z3/apxZjK3bY=; b=bo89c9U3Cz93BXSZETD50D8A3AmNqc6IerbHfc9fFDfQK9CF3a7D+prIsCbzkbqb95 ThEr6avuGJso9nW3lz0YcG4TroPC4b01WUKMV/MJZVbcXIDi6C3w8hBYACDH/FNrSrJe q+LbEBdwsqup8OLsLhiirrvhZhalkufhJCZ/I0xNhYd5WiIpgDLDKAlD1t5rIe3GbvmC jIVLDis/3+nXp3XjsRhmV1r/6oQ1YCPjCmCf6Xd8CBCasJ0auumBr66blHEy04j7tdAW bz7QKq5KVwHz9g9mzdESo9eJdCRcTNS7rtuf2k6deq1nMiLimKs3uQvYs2Yc+hERrb2E ABgw== X-Forwarded-Encrypted: i=1; AFNElJ/aK9zBcXeHbOTQG6/DVy547Xb7sdYWgVsH1slhwq53hNvLR+c1v0/T1BS3LqFS7g3fP5NBFsioDx9TulM=@vger.kernel.org X-Gm-Message-State: AOJu0YxlbydeLog+qycSNuyWZ9YrhQlAG05XDu7CvGtaigjufaIJWD7Q z4WzdEvxbjUn+8NjPaxr8m5Ns5FaXRr95UqdHdWPaJOBtxBCHrowBOCZ54D9jWdgjv9KfEvDDfQ BI4h6reGSCxFaDN3nJpEDeTXOFaGObDWZJlF1Mn67ZNnQyikpg9Nc9O4BaAWDLWZO7yc= X-Gm-Gg: AeBDiet1wxy56KNe2/scd7R1X4zdZSs/RuVbPCnvhB9gnRkGYtQXOYVgbDSGHCwWobU G/Nw6irW3AAyVMJF6YfDvdpTxcoGT9jAKeDDo9BWBoDT7mL01vJa7gl7Z213ce7sbAQt8M8MGsB I4w8SHoqbf7eOhuaA72NIkEe33JXJBA2ZmZc/075DZtbWhNe1Xt3ydihNflGrOUeQS2Yo/lsfnQ 43ePpQbzxfcmzb345IUMfTY+eVZkROVql+vH3dF8iUZG1qdJRvRqWXubCQZaObBy+1qpEyJeLI2 aEpE8x4/aOPoZ6kp7f0posVzEp0uqpiINfoH5uiAnRDesj6+KEAi6RPbejlbzqfnY0CzEyEuAdq 41Sa2a0XWOXskBcLQyyxDWulAm539uDE8ucF6tmTwSXbrSLY0NUdHTuL0d0X1MV/pjlG/tjor+I LBL27ikGAuWi6fOuFa/EnK5kAXCM0= X-Received: by 2002:a05:622a:5e16:b0:50f:c36a:3821 with SMTP id d75a77b69052e-50fc36a3c68mr332980991cf.34.1777294013367; Mon, 27 Apr 2026 05:46:53 -0700 (PDT) X-Received: by 2002:a05:622a:5e16:b0:50f:c36a:3821 with SMTP id d75a77b69052e-50fc36a3c68mr332980301cf.34.1777294012973; Mon, 27 Apr 2026 05:46:52 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:653f:4d28:6a78:a6ca]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ba454d1bd19sm1091496866b.37.2026.04.27.05.46.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Apr 2026 05:46:52 -0700 (PDT) From: Loic Poulain Date: Mon, 27 Apr 2026 14:43:37 +0200 Subject: [PATCH v2 10/14] 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: <20260427-camss-isp-ope-v2-10-f430e7485009@oss.qualcomm.com> References: <20260427-camss-isp-ope-v2-0-f430e7485009@oss.qualcomm.com> In-Reply-To: <20260427-camss-isp-ope-v2-0-f430e7485009@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 X-Mailer: b4 0.14.2 X-Proofpoint-GUID: t_0HucOUlcjc4tNhhUfIOuAE927QHTt7 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDI3MDEzNSBTYWx0ZWRfX11qT9n3uHJuW lPaxNLmaXjx3oJZyshm4HR/QwSkeGfLh54smt083kOe4RWroA69ALJW/yxSwSecgbSJJeS2gS4l jhg2YXrk6YL80dE7+UoQwjwQQDj05YW3r/9UbeSc34IHRTDoK3FkTJ20inmFtH7b+Efj5y+gVR7 FFh1DUlPkfctBEeP37TkFu2HbnAZjyRKEBrei101HZlscyhoD1FbBpO6tmQtMaBYgA7Jg3aymvh EZ7qYyyjOoKDMVa7fTMlCvWuatQsfgJ87H1R/o3zmB0G78/xseNbCduZPMFlhkorBJiiwNbVRi9 TXSUviTkRgOBbWIZ8/eMOFDfhBunbzg/r/DL0//uWNya0pqti8TL4TGLfLyiAxF3nFi6D7akpTx 07HZBx9D12W7Q6aEGUr98MwRQWQjdhns/PaMTBA+7C64cM5UeZEQdBYrew66zIC/ixdDJz53X+A +pgzuPJbP+1nsHwDyxg== X-Proofpoint-ORIG-GUID: t_0HucOUlcjc4tNhhUfIOuAE927QHTt7 X-Authority-Analysis: v=2.4 cv=J/GaKgnS c=1 sm=1 tr=0 ts=69ef5abe cx=c_pps a=EVbN6Ke/fEF3bsl7X48z0g==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=eoimf2acIAo5FJnRuUoq:22 a=gEfo2CItAAAA:8 a=EUspDBNiAAAA:8 a=l64rWm3OqFMOLA4dSg0A:9 a=V6_9baJ7xsrOGZ_p:21 a=QEXdDO2ut3YA:10 a=a_PwQJl-kcHnX1M80qC6: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-04-27_04,2026-04-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 bulkscore=0 spamscore=0 phishscore=0 lowpriorityscore=0 impostorscore=0 priorityscore=1501 adultscore=0 suspectscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2604270135 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. Signed-off-by: Loic Poulain Reviewed-by: Krzysztof Kozlowski --- .../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 Wed Jun 17 06:13:00 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 391E03C4576 for ; Mon, 27 Apr 2026 12:46:58 +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=1777294019; cv=none; b=GpyLJmLClwb6VE6pPgy6I5ePf+KwRbgMKWfC3CFM1ovywfJ6j2nrWjlT8Ouv/VBSKS7rK8ni4G/x8y9CUTnQYuRAabtBbRRemHvFwgZoYsM9wPFiNL/EyoywLPENs88W+qpMedjlvdG72R94hzWwBmAri8PCfjR3jCsFM1Pe6BI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777294019; c=relaxed/simple; bh=t3oD0Wav7XG6nXX5m+LNYCFF8Do+gS8hdZjFgoDgo8Y=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=b8y+puTuhRMpYHEC/tz66m2y/pvNYLR8DqK5jLxtF8fBJHCTF9tpYentDH3Isv5Irk3rjxOH3BP5LaLt6tvohICqNNvSkXIdL8l+xk5Li0qiKBdnjYE3GxPtKXvRNbZ+UC0i4sxQsyc1FPD3moA6w+aL1l3vBnk4s6YUs4XxHyE= 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=lFX8rnwF; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=S1Wi6fqm; 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="lFX8rnwF"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="S1Wi6fqm" 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 63R8TB3a665673 for ; Mon, 27 Apr 2026 12:46:56 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= LiDzM8ITkpj2w4YZF7EhsRvWIrQfPBSfCjKhrtsK9Ck=; b=lFX8rnwFiwmXWMMV uKZWpXFNFFpewz5mV4Blv5ebSfs0DLv/1Evh8VsiDfUtNGIQqCR09+Mn2KrVuyfj DHzwr1ZJ4uV8Fbnbz2MOo2nfsluC0WQ4hS+3/gAcIBqAtDcmX6cEU2JfDf2Y9tlJ t8fFMJC7z/bDl8Xw/q+D1y89VxTjtjhh+MuC4q+yp7dRP/FvQgmD8bn725XU3L9H wy8ASAHmObO8Um5OyCdIaiPHgDmckMhA672HEQlOuSNr5Z8aOoW9W0Z2H9CRZtd3 NU3qwxGWzqBiwD99SX1vhpOrDjm11MVK9fd3hNFTLCpemNH+QtlYWwV1lDLVfbs4 CK9oDw== Received: from mail-qt1-f198.google.com (mail-qt1-f198.google.com [209.85.160.198]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4dt30n1d4m-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 27 Apr 2026 12:46:56 +0000 (GMT) Received: by mail-qt1-f198.google.com with SMTP id d75a77b69052e-50fcdd579e1so76127361cf.1 for ; Mon, 27 Apr 2026 05:46:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1777294015; x=1777898815; 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=LiDzM8ITkpj2w4YZF7EhsRvWIrQfPBSfCjKhrtsK9Ck=; b=S1Wi6fqmYU7Y0sSWuPDqDBkwHXyUemTAAFAVl4VoXuDVHqBIv6q2PLWNsDNz8NaMpe 3pPFF3Jzm8HbAHDa8/PdG9XlJXMzdDi7l1jLDSQyIuMWxCOoyd0iYLPeu26pJ0IeYrX8 E8hDaqcIyXW0YrV8hul2rq7JjK5pfxaPlcT+QcCQjDD37+gClRSu1rbNRYtyEuNvm+pM IELOVuFL6IDG8DpNxcqXzBhWN15sH+3tLC9KmXXfHbby2DyDcW/GPwTfKjtVHTquykre a8O7wusZxVl5XcOokSH4mhQNHGKCcJrgYqNNdURYW5RFiktADFvp59fWkUdXRyNkCYYR QkKQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777294015; x=1777898815; 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=LiDzM8ITkpj2w4YZF7EhsRvWIrQfPBSfCjKhrtsK9Ck=; b=dDe/4CDd6LI8CgY5Pzn1Q6ASZ3Ko8pucXOssYFstxQcSy7MgbqjiRpag+CQKtlZJh5 Ntfpe3zahio0o6gL5donOrt0I4qqNGYWaOh1fGrrWPIdlz7gFE0Sq7Zpsjy2f3KdmEHy C8sN3+v7OtsLpMy24gNBxg8oe90MYyI0vlIMxVR4cWOK4wJTjiOg3owAgU22laATUa75 6UZ3oHbsPiKeEXTQDUZIZxcjdAgaSwr9M8n6fAlRdUJbApvp2cg9Kfe8GOpRCuur48xE XYlrWCd+D6SaQsIRldfwg46Rk9tZNDz+eInhKjWhDVaN+UuiMSUF8HKI4bcz5NinpwDm yiiA== X-Forwarded-Encrypted: i=1; AFNElJ/csPd7Dib3xLhvFfdxAeRY/87FRhSR4H6TADpsnhY1jfPBaioQTNQzGjW6Q4JxD9NvG6Vb8o8IzDSob8I=@vger.kernel.org X-Gm-Message-State: AOJu0YxyPpKrBCbZppcvjEvPAdEKj8wFecaobzLjhrPP2mh4flS8IJ2C uxGgBHYqCxMsWHurqI5EXMxVJJencIl4obiY7e0dArHc6bj+tovO10/BlMUsNr9w5e2ten0yDkj QV+bBP4jMxaCCVlz54A5XDoKX9gmgRX0cTQmHH3b2jCHc2QUefo+lfOu15+Bbs74+OLQ= X-Gm-Gg: AeBDietnINN4Ti1gUVHqT4U6ePILyyZpKciijBoN0+pfRwcCYhJPSZY8iTIhPUx45As Qb3qPgtnkDvx07WdLct5j1EIBpN3oa2te+CaZBWDiAtWgkTQPPKyz3gOehbpzjiiRmiSOxT0RVL WrTjJ+eXnLc9k/b7sECINelTehMdBNkHHEN0Bcnh3ZdOta/8l1l1y7cB5ma8kCtleOGkz5TtYwi pwv3OUBYNAlyb5tNBtGPX5Mprzr6Lnic5LMZpVQo1utSS60SK11/HkXEpvbqZKojb8gBWyv4Lbx dLGxXt/fGRyzmGpHavS0hKVQPzHFut7VG0JZrfZK+ooZI7YomtZuyDvKj22Y7jMck+BR6FSWCaE Bdw2iUmeZwnF2h+sXd3/+s2mBlj/OFKaMMyhke5ux1Ox1IPPAtkl5aiqtJ4ET6bJVqVQYdum0UH mmZrovc4dBnWEzYh2v/6MtrRVCowo= X-Received: by 2002:ac8:5d12:0:b0:50f:ba44:ce4e with SMTP id d75a77b69052e-50fba44d76fmr368833341cf.6.1777294015210; Mon, 27 Apr 2026 05:46:55 -0700 (PDT) X-Received: by 2002:ac8:5d12:0:b0:50f:ba44:ce4e with SMTP id d75a77b69052e-50fba44d76fmr368832821cf.6.1777294014697; Mon, 27 Apr 2026 05:46:54 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:653f:4d28:6a78:a6ca]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ba454d1bd19sm1091496866b.37.2026.04.27.05.46.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Apr 2026 05:46:53 -0700 (PDT) From: Loic Poulain Date: Mon, 27 Apr 2026 14:43:38 +0200 Subject: [PATCH v2 11/14] 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: <20260427-camss-isp-ope-v2-11-f430e7485009@oss.qualcomm.com> References: <20260427-camss-isp-ope-v2-0-f430e7485009@oss.qualcomm.com> In-Reply-To: <20260427-camss-isp-ope-v2-0-f430e7485009@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 X-Mailer: b4 0.14.2 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDI3MDEzNSBTYWx0ZWRfX94qxHyY9IypE oeO8H5CndCNOA/w4kV8WJW4zpCKI2CWQZLVFcBNWTCxn9w2SIW8rGT1jQT5tVPcI42zqGQp/uho v+T6p6hDgGuEylnyEufMoM9N3o1YxQUUMJ3YhRvUmbD2dZj60G2qh3VLWlsLkpJMfeiV8sryqTy wHCxbXVI5ghE/Mc8Dq/6yVTZDCaTIM40UWDzxFLTxGiKTHtY/cBDVJCbR/n+hrypzcLLtMwRCfG VRg2c8wZEn5U6S/vggdm0hk4V70o6eL0UxlroFzZxYFUGK7l+vyUDJCMqLky9znHXkQkVrEEHFS sUx+3bfUR1HAVX4sTNKSAz0uuSXupFDyFArNMEAYbr4q47C2YM9AJcokHyrUtNzbYBp7aqTKP09 e5+Zj94okdCIMmuE0bWLaYiC10GKrJrAsfwlglm0BT8clejbnN1Ub3WkHs+/5U4gs1wzRt/+QDo Vd8LALlJV9bNVJi0GXg== X-Proofpoint-GUID: S5Arwr4rIYQfy3ifdz55kVaECww01Hat X-Authority-Analysis: v=2.4 cv=efANubEH c=1 sm=1 tr=0 ts=69ef5ac0 cx=c_pps a=mPf7EqFMSY9/WdsSgAYMbA==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=_K5XuSEh1TEqbUxoQ0s3:22 a=EUspDBNiAAAA:8 a=M8sXMW5dAYDte-7YvdsA:9 a=QEXdDO2ut3YA:10 a=dawVfQjAaf238kedN5IG:22 X-Proofpoint-ORIG-GUID: S5Arwr4rIYQfy3ifdz55kVaECww01Hat 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-04-27_04,2026-04-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 malwarescore=0 adultscore=0 bulkscore=0 clxscore=1015 priorityscore=1501 lowpriorityscore=0 spamscore=0 phishscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2604270135 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). 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..d8b356028e24c3c5b2e9b7f20e2= 20db7d491ad68 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.yaml + unevaluatedProperties: false + required: - compatible - reg --=20 2.34.1 From nobody Wed Jun 17 06:13:00 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 A58EE3C5539 for ; Mon, 27 Apr 2026 12:46:58 +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=1777294020; cv=none; b=JkDGAQzg6tzTL+qkcVDyQ5W/WV6QS/5STLNf97wjpUXiWUdxfYHf/R/LwhnPmgXDVrJUeqXo7wM07hXC8qdXLNNorBHBIw8oyZXVtQmlIq7J5xZASBqZ9eqVKkhF8lF9zx8eCnfX5RqLE+ZLWU7RR5ItcaRlaDQWC8ZP+V427G8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777294020; c=relaxed/simple; bh=ZQlKG4lDzXyaqGSPFJgTd5YAx0ybEvqo7MO3JGSvZSU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Xtto0LE47DVd4VnwE3/INzJsb1EK01Vz1HTFdKen5Y4YeI2eiTgRxiIxvwwql9p9q7I07J9PpjFqZ2U4vYTbeYtpzXPf6YoZc8j70/qTZtjaTtzoTDrE/M0eZJ58KH12MZ2z/DMyB4Yu31HhTMT+v2E3hSFq79j6E7zW6lOZTyU= 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=pZwNEPuY; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=Anb3hwMl; 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="pZwNEPuY"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="Anb3hwMl" 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 63RA3nP23123516 for ; Mon, 27 Apr 2026 12:46:58 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= 6CxZxIRAyhpEt1Z9NG+XcoFGfUkZoM/tpt7JPmbxHt8=; b=pZwNEPuYznxiEzxQ elsLWQ00CAh1xtjVDqrlNr2NAOyTCo3byAmUDYzGE4buUnFee8ZcnZjKZPWDAgTy lSvqvxaKdLL0oobiuu1AbqrdtFf9RvklZSXYYnhSKGaMJ/9xtfZ02CdUiC1VKAwC SR28qbkVgPraZCc8Gc3zvYcgQw6om7I4yWvOlykl11585KAAU7a1NhIM9PeFqbi/ KhrYhXjLWHFuwjk8PhT2gVgekycUfepDcEvdzLhOvQjKzdsFUuxB9Ow2ZTr6oKvA qbXc2Z88k2d9lr28Y4YWoYbSMNR9WAyTTaOUCeg8tIIylHF5LoZXlW/DMwcmPbI1 3pC5fw== Received: from mail-qt1-f199.google.com (mail-qt1-f199.google.com [209.85.160.199]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4dt5qgghsy-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 27 Apr 2026 12:46:58 +0000 (GMT) Received: by mail-qt1-f199.google.com with SMTP id d75a77b69052e-50f13da9684so96275031cf.3 for ; Mon, 27 Apr 2026 05:46:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1777294017; x=1777898817; 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=6CxZxIRAyhpEt1Z9NG+XcoFGfUkZoM/tpt7JPmbxHt8=; b=Anb3hwMlRGGphE2p+G9NbjynEXq6/2A1b5kywhKumMwy2fgdY8MPIPObLl+KfcHSKa 01hfpnMjsSFr29weT1WUVQyqYBeqaz6PNmLoyI1YZ31n9EG4uFAufLn7qiWpybKhshjh XMdJhtUPJQlwv6uRXMuAK84QdiQ4PvWb0xGFE1kDuIKXmrx/H80NGtcYEHNRe7FEe3w5 K1hunMDd7D44o0iejB+769F0+ZiWGJgVwGSUvRhYN9NGbh3NmwLtMxxIQ/1Kiw2wyboV MJ8ByxsN7h1vy08HW9xMtz/e7rdpnBqMxPZju6/41VIGeY3OjSvBuw74F5Bmj661sc1j FT6A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777294017; x=1777898817; 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=6CxZxIRAyhpEt1Z9NG+XcoFGfUkZoM/tpt7JPmbxHt8=; b=jp+I7S+2iQTe/C9004o+qpGoYvWI03P7AOgXg2lJLlPKbnQl20obdL7pWKcX6ltTbr NpXVL3KOyBNlG7D/EY4YLQy2phtaRkzc1tQqg9jijEnVap2BFRpnfhOguKSw6xed9VU5 xL+Vediqy4IBPmOboL0Vvqnr2xe47h7J14d+YYbrVthtVA9j2SFHjPzHquXiFo+tyqm5 Xy3Dn/IhgFmNVFOcl0yi0x+sDupOw22wockpnObKDb7qlJ2dqfE1+yxoWk5qVNF4JCiI 28ww3QMgP2FadBRQXdKxLJU4RE9eRUX3ObOgRxd8PCxAVeH/g+aNoSwDHK5/vwLcW9TA ERdg== X-Forwarded-Encrypted: i=1; AFNElJ83YPi1QDyFvuWaRAJrjf/voxaNOgzJnFHHBsk3+/o07BT+2YJKJM4tMG4kwJcF54wkt/Y5O9mgo4e2bXE=@vger.kernel.org X-Gm-Message-State: AOJu0YwEJcWh3aRecdQXKQ7VCJayLC1Rdy+0UHmeUNo8mN2xVmyFTVKi m/jRtt8qEuGkVry6eFQ1dgAwimdd3PQwpgyC6/2teNlpygg/xxLA3i6qPNF/Ha+QL1CDwROeTOn qJmdY7KOzj0qa0IKNpCcveeYMV3cQElYX0Guyvl75LOL4EmsQI6u0E25sTKnBTKF8vf8= X-Gm-Gg: AeBDieso49WTUShIt/8dHwnS2NE9eCUcwb7Zrn+Eqg3bJwRlKmQcYN/cg90sLnPbk1t QxwRQF4vyt+Md8gZQxGtV73tOdG4I0qrwYmmaHLySXti4JtdSK5u8PSsks0jJ2PgrI89PVeVLqV rQbgK6XWddw78ZI5Yc6egPi2wK51fH89OFqIfsJI91e4tbM76Q/MSAluDSNtgyPTHPeQXBZvire OcKjsO2+YAWaOMBfWACPABhiWgN0P2Ak9b9lbU+cC6tsP39BexlC7GrJtDZPv/NOHbC5S6DBnoX QeJrTTBBpFK+O8HjlKtQwVIpTXOnKKSAcii26mJ6BSawgRZD5FUnyY6tM0rz1SWnfL8l3HueJUM p/19coO8fnnY188FyEPgxk8CkN+Pst3KmDu2AUPYllGKSPVS42F+DpCJTooEWMD7yCL/A5AZPg6 81Si3K9UvgjEX5gGsEei3MClB9Vg8= X-Received: by 2002:a05:622a:1aa0:b0:50b:37a6:4f0a with SMTP id d75a77b69052e-50e5b2c1ba9mr496627931cf.57.1777294016927; Mon, 27 Apr 2026 05:46:56 -0700 (PDT) X-Received: by 2002:a05:622a:1aa0:b0:50b:37a6:4f0a with SMTP id d75a77b69052e-50e5b2c1ba9mr496627531cf.57.1777294016431; Mon, 27 Apr 2026 05:46:56 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:653f:4d28:6a78:a6ca]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ba454d1bd19sm1091496866b.37.2026.04.27.05.46.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Apr 2026 05:46:55 -0700 (PDT) From: Loic Poulain Date: Mon, 27 Apr 2026 14:43:39 +0200 Subject: [PATCH v2 12/14] 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: <20260427-camss-isp-ope-v2-12-f430e7485009@oss.qualcomm.com> References: <20260427-camss-isp-ope-v2-0-f430e7485009@oss.qualcomm.com> In-Reply-To: <20260427-camss-isp-ope-v2-0-f430e7485009@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 X-Mailer: b4 0.14.2 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDI3MDEzNSBTYWx0ZWRfX7QpUlYGVhXfH ZABpd2vPGuxJLYaLrlwAVZ0g1voZ3Pw82agXwewTHzMuU77r5VywX+s5UN1Ll1Mb+BNpPhI3xiQ XvM0myJlqU6Y33Ew/B0MyaFG4n7GFxL9u+LR//hG0o7CDZNj8CFYYSPdgrOvGapFtbkcsc8LiB0 Brb3Yqw0/kMkxPWpkey87artyL3nuCwGiSV9B/Z+rapddGhIePMKsroB+He7uDgTyGlAimh/of6 kbbWktL2hBK13RRQaOC1gLt0RIVfx0PMeatuZNiZonX8q5OhLql/ieJEPKVC/0x0M3J1Nh6UghG zUKVOLWusuF2Zh4pbz06NbwPG+2fD9Skgxezd3cemtCUCKqJneu8ow3y9O24isPk9NZkGq5NQVK MyKC4LS0RCDBJ11Dv+uVue+Kwp2lnqp8cS6rXPFvHJK3nMqNsr6tJsWtTJSic7LJrCwknAFqQMP bTll28EZzUpoxJqiVaA== X-Authority-Analysis: v=2.4 cv=V69NF+ni c=1 sm=1 tr=0 ts=69ef5ac2 cx=c_pps a=WeENfcodrlLV9YRTxbY/uA==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yOCtJkima9RkubShWh1s:22 a=EUspDBNiAAAA:8 a=GU9a0yZhNO0hLPa97fIA:9 a=QEXdDO2ut3YA:10 a=kacYvNCVWA4VmyqE58fU:22 X-Proofpoint-GUID: RkyPcu1ww6b9vFTFMTU_uiVc4PpOG92A X-Proofpoint-ORIG-GUID: RkyPcu1ww6b9vFTFMTU_uiVc4PpOG92A 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-04-27_04,2026-04-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 clxscore=1015 suspectscore=0 adultscore=0 spamscore=0 phishscore=0 priorityscore=1501 bulkscore=0 impostorscore=0 lowpriorityscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2604270135 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 | 118 ++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 118 insertions(+) diff --git a/include/uapi/linux/camss-config.h b/include/uapi/linux/camss-c= onfig.h new file mode 100644 index 0000000000000000000000000000000000000000..2e15f03f16025c4a4852ad62afc= 39a5df6542422 --- /dev/null +++ b/include/uapi/linux/camss-config.h @@ -0,0 +1,118 @@ +/* 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 + +#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; +} __attribute__((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; +} __attribute__((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; +} __attribute__((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 Wed Jun 17 06:13:00 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 759133CA487 for ; Mon, 27 Apr 2026 12:47:02 +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=1777294027; cv=none; b=J8hLtH3RYhHdjhQJaVdWGjHSyE4qbH9la52QyLbSlfuq8om8vdht6lLGYL+yjtEXFEEdWU/lNTTN2pZqzIjcydM/44cw1LyNiRenwHwjGmwqJG9GnRqDdHtz+rG9nOOOYnMyqrkC38NoOAYuo+xy4pt964nMyxu/RB00qNMtU3g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777294027; c=relaxed/simple; bh=9U9InPT5ak8VswAjdBBKVw2kAaJAOl78Tp083vhLaHU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=W+Q3b0lnn/yeguYXC3BvmSaxvrh3kFstu9DUgVDM2s7PO7brB3sa5xfHeo74ma7kUHu4swvZ6MTByNsLyIsZAuPXaSu5CklAAW7hmDGLhursJX2e1MesKwmXsxniSbh4b6nSZwP46B5czl3VLmDFUIKdL/RXhaRCJGQY8ieBVuU= 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=iZR6h8GF; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=VvRHKqKg; 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="iZR6h8GF"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="VvRHKqKg" Received: from pps.filterd (m0279866.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 63R8TDKF1762370 for ; Mon, 27 Apr 2026 12:47:01 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= xuWfnMl/kyIdwFnSWCzbTGGKs9wL2quUvaFywU8AXdk=; b=iZR6h8GFrC0RVKRX Lk9Sno9YPK8G2pxffarjzmE7QLAgxG8rdI1Um4bIyaFmOLznHyYFuk3FfKKwk3pE aX1hbaPgHB13VX6nl2rCBhBG3Imag/fo7C/SuXtLJLAeyecQTw9XH7BhrXGy6afA Sz+/inHRHPjmnS8Muwc8unGO3TyZjC9OX02MCZbXbQrbuYpY3CtGZrYU5LXk388N VRgtWavH3C15BLHZQwQSTIxGphOJg3VJtYVwhTHL5EqIv0hP2qEa+okOlcaZ+Bj3 hcrd9LEjDBLR6Jxj12IACYle8Htlpr8OojJiYtxtCQID/WVULI2sn11F+SPsNxMM e9Pyhw== Received: from mail-qt1-f198.google.com (mail-qt1-f198.google.com [209.85.160.198]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4drpw9e3f1-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 27 Apr 2026 12:47:01 +0000 (GMT) Received: by mail-qt1-f198.google.com with SMTP id d75a77b69052e-50df4c130dbso169940221cf.1 for ; Mon, 27 Apr 2026 05:47:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1777294020; x=1777898820; 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=xuWfnMl/kyIdwFnSWCzbTGGKs9wL2quUvaFywU8AXdk=; b=VvRHKqKgWw6mqFA65d/4RGm2w9Kfpr+RkoIb5mwGgR3n5+cmSdeDGJ6jbVGv5ljxcP W2zJSbuAV/G0R2BQ/9o1trZOvr2ukDiTJ3xt8QIR+oR97qc+C9bhMka1o+tiDlqYT6no c4wKaS+Oth5P/l2qPldKS11IWRxf/GmD2RXDuToZ9uPDx0IJiJso3JIrOsRLnCy6Rqrk 55UkEK3H/wIqeo5aUl4cH9WxZZig2Oq7KLxSmo4P8hruPRIpRVbAo9Do3Wh9EMOBTj/j GJqsqdhtGc4FwBV2GzRylgux/eIhysaSKNsKZ59XteHRSftSw0OGozjXZNik1+ebjbTn s9rQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777294020; x=1777898820; 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=xuWfnMl/kyIdwFnSWCzbTGGKs9wL2quUvaFywU8AXdk=; b=NFq0yx96nByn9ER2e3SQtTJSimv88MEE0mFI64lOvuJP1hzj1G/m51W3mw4Bv7CiLj GgSaMb+boPbCUN3OmmTiccoIR36fezZW3q2bgEoOggM7TmCmLv9FCbR8wEyqcGAyYqf1 vgD0WeErfLBt04CSvzbwzID8nTovMz9z6zJnhC+r/UnApDv1yf76udQ55Qkh9X5qpDJG aH8hUjKuLiq760B4/cPhXEw6GklNmi/rA44OcJVry3byu/p98fsN3M/26+QISbzTbomS UTVKinGwYZxXXNI1+48gHdXaRqu50qYCfwa6K025dA811LNJymjmTSU0mcqD2w3+qUho rt4g== X-Forwarded-Encrypted: i=1; AFNElJ9R3yxL9oVpPyztFJXkA+pc4dVgZpjcjqudQp4bn28sO1tZlp6NyvP6E+Tem9FLiHvjdkL9HMlf8vOw7pc=@vger.kernel.org X-Gm-Message-State: AOJu0Yx1IAarFr31kvDghKghZL0aJcv6qIp2tJtcVkPgrxOhBTWigk+k +ypNwQxUOJHXjoztfrzCZ06xbYFV/LiqKn0metXDV8tRZPuceErBDTiLA8yIXzTbqGjUCFviNXj q+ANl3J4ec8h5RFft3wXCSyqX2sIEWVMdwd2xKZxdaIB1XpVAR5EjfpPRldBQ5SwPgpo= X-Gm-Gg: AeBDieuPSiBJAVLNnzz36mvrgG1+7CkybqyfZLkDzRLyxKIet0Wh3eVucGpmqjcDWAT vKQykjsGjpT6Js7uRDCiIRktfn/ZV8MNtXZM7nWDl25PZv9zfD0xDLRVhsrRop1sOHZWCfzkW2U CQyVNVeHjKUHQa/3y+ekwo6vZwT5drsgZ8XkSruxRSdN7pwMKjFUHjU8M8BncHM4a0BZioaNq0T ITNqdSslsRecL8S21nymSDRD/NDdhmI2giam9QzlNIIZ5RjnyUDY0Hn/5BSbZJoJYGUXMT2zLol yBXmBTJoDhmUUJrA24C/eQH4YGSB7lYVhsXSv+h3Y7qqDa0NwPqL8sc9cpPskcjKZx8XiSK/Nop PYtpItsInbYQO0fTXctLr5CK6qf9yFtenSw9WHagDNlQgknfw8tXrZItoPE/fHhcQ7sF6a0Q2Fc jsE54Ikf3HfPOxMh2GAZX4E0Ndz6U= X-Received: by 2002:a05:622a:1304:b0:50e:18f9:b5e2 with SMTP id d75a77b69052e-50e3661da7amr559657961cf.6.1777294019356; Mon, 27 Apr 2026 05:46:59 -0700 (PDT) X-Received: by 2002:a05:622a:1304:b0:50e:18f9:b5e2 with SMTP id d75a77b69052e-50e3661da7amr559657231cf.6.1777294018480; Mon, 27 Apr 2026 05:46:58 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:653f:4d28:6a78:a6ca]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ba454d1bd19sm1091496866b.37.2026.04.27.05.46.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Apr 2026 05:46:57 -0700 (PDT) From: Loic Poulain Date: Mon, 27 Apr 2026 14:43:40 +0200 Subject: [PATCH v2 13/14] 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: <20260427-camss-isp-ope-v2-13-f430e7485009@oss.qualcomm.com> References: <20260427-camss-isp-ope-v2-0-f430e7485009@oss.qualcomm.com> In-Reply-To: <20260427-camss-isp-ope-v2-0-f430e7485009@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 X-Mailer: b4 0.14.2 X-Proofpoint-GUID: dlZGLAeJgJ8UiG6DJ5PXEDcDiMT7wBg6 X-Authority-Analysis: v=2.4 cv=H67rBeYi c=1 sm=1 tr=0 ts=69ef5ac5 cx=c_pps a=mPf7EqFMSY9/WdsSgAYMbA==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=YMgV9FUhrdKAYTUUvYB2:22 a=EUspDBNiAAAA:8 a=f3c5Xx6MYDYPG6KXI0wA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=O8hF6Hzn-FEA:10 a=dawVfQjAaf238kedN5IG:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDI3MDEzNSBTYWx0ZWRfX2o0jcrCG/eR2 /ZdFApqvXg+bMA34HtZsz+wKmFHephpD0BGRtW/7USimgdhYyuUvbrlNtV9te5FqyEuGy808EGI s1X5ydFfJSyAugoRLJJ2BaVEAuEbZsnI5bKVymNeN7H2hirpF6GFsJlEJ1ngCYuiGjiU/3TFCw6 MBtI730XO6vUwhZjwrlSRy0L6QlOVn1lephFgBcNBp9jzPbMW9cBMtUnT3jCySs4ixHhE+zBdX7 Ko3YUVtlf1evwzD/utEn/qwno8S8So9wMgsrNDreiFpkbXCUzmcNzVOFhHoYdwoxBkw9EdOq8Qr UlBelAv9ghNw9wOSeni2VQpZF66m02PTMlJ33AkCsRdP90UdD17vH0kfjlCBS3HkiSjOW+AYuBS x0sKhQCg5wYxyfyK29Mi1S2RIpBwiLluFF59Mj/R8XZzAS6+O6uWXvK+s34rfdrigkVUk/fTEGX 9x2zl/bn4/eHledgkJw== X-Proofpoint-ORIG-GUID: dlZGLAeJgJ8UiG6DJ5PXEDcDiMT7wBg6 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-04-27_04,2026-04-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 bulkscore=0 adultscore=0 suspectscore=0 phishscore=0 priorityscore=1501 spamscore=0 impostorscore=0 clxscore=1015 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2604270135 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: - frame-input: Bayer RAW input (V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) - frame-output: YUV output (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) - 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 | 2466 +++++++++++++++++= ++++ 3 files changed, 2487 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..6c5792311e19f0b4feda5741e0e= 40af575338684 --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-isp-ope.c @@ -0,0 +1,2466 @@ +// 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; +}; + +/* Per-queue format state */ +struct ope_fmt_state { + const struct ope_fmt *fmt; + unsigned int width; + unsigned int height; + 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 8 + +/* 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_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_ARGB, + 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_PLAIN_64 =3D 10, + 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 }, + { V4L2_PIX_FMT_SGBRG10P, 10, 2, 1 }, + { V4L2_PIX_FMT_SGRBG10P, 10, 2, 1 }, + { V4L2_PIX_FMT_SRGGB10P, 10, 2, 1 }, + { V4L2_PIX_FMT_SRGGB8, 8, 0, 1 }, + { V4L2_PIX_FMT_SBGGR8, 8, 0, 1 }, + { V4L2_PIX_FMT_SGBRG8, 8, 0, 1 }, + { V4L2_PIX_FMT_SGRBG8, 8, 0, 1 }, +}; + +static const struct ope_fmt ope_output_fmts[] =3D { + { V4L2_PIX_FMT_NV24, 24, 0, 1 }, + { V4L2_PIX_FMT_NV42, 24, 0, 1 }, + { V4L2_PIX_FMT_NV16, 16, 1, 1 }, + { V4L2_PIX_FMT_NV61, 16, 1, 1 }, + { V4L2_PIX_FMT_NV12, 12, 1, 1 }, + { V4L2_PIX_FMT_NV21, 12, 1, 1 }, + { V4L2_PIX_FMT_GREY, 8, 0, 1 }, +}; + +struct ope_dsc_config { + u32 input_width, input_height; + u32 output_width, output_height; + u32 phase_step_h, phase_step_v; +}; + +struct ope_stripe { + struct { + dma_addr_t addr; + u32 width, height, stride; + enum ope_stripe_location location; + enum ope_pixel_pattern pattern; + enum ope_unpacker_format format; + } src; + struct { + dma_addr_t addr; + u32 width, height, stride, 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 ope_params_demo demo; + struct camss_params_chroma_enhan chroma_enhan; + struct camss_params_color_correct color_correct; +}; + +enum ope_queue_idx { + OPE_QUEUE_FRAME_IN =3D 0, + OPE_QUEUE_FRAME_OUT =3D 1, + OPE_QUEUE_PARAMS =3D 2, + OPE_QUEUE_COUNT, +}; + +#define OPE_ENTITY_PROC 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; + + unsigned int framerate; + + struct ope_fmt_state fmt_in; + struct ope_fmt_state fmt_out; + + struct list_head list; + bool started; + + struct vb2_queue vqs[OPE_QUEUE_COUNT]; + + 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 inline bool ope_pix_fmt_is_yuv(u32 fourcc) +{ + switch (fourcc) { + case V4L2_PIX_FMT_NV16: case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV24: case V4L2_PIX_FMT_NV61: + case V4L2_PIX_FMT_NV21: case V4L2_PIX_FMT_NV42: + case V4L2_PIX_FMT_GREY: + return true; + default: + return false; + } +} + +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]; + + 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; + + dsc_c->output_width =3D DS_OUTPUT_PIX(dsc_c->input_width, 0, h_scale); + dsc_c->output_height =3D DS_OUTPUT_PIX(dsc_c->input_height, 0, v_scale); + dsc_y->output_width =3D DS_OUTPUT_PIX(dsc_y->input_width, 0, h_scale); + dsc_y->output_height =3D DS_OUTPUT_PIX(dsc_y->input_height, 0, v_scale); +} + +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_w =3D fo->width, img_h =3D fo->height; + const struct ope_hw_fmt *hw =3D ope_find_hw_fmt(fo->fmt->fourcc); + struct ope_stripe *prev =3D ope_prev_stripe(ctx, stripe); + u32 x_init =3D 0; + + 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 dst; + 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 img_w; + stripe->dst[OPE_WR_CLIENT_DISP_Y].format =3D OPE_PACKER_FMT_PLAIN_8; + + /* UV plane */ + x_init =3D 0; + 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 dst + img_w * img_h; + 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 img_w * 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 img_w; + } +} + +static void ope_gen_stripe_argb_dst(struct ope_ctx *ctx, struct ope_stripe= *stripe, dma_addr_t dst) +{ + unsigned int img_w =3D ctx->fmt_out.width; + dma_addr_t addr; + + stripe->dst[OPE_WR_CLIENT_ARGB].enabled =3D true; + + struct ope_stripe *prev =3D ope_prev_stripe(ctx, stripe); + + if (prev) + addr =3D prev->dst[OPE_WR_CLIENT_ARGB].addr + + prev->dst[OPE_WR_CLIENT_ARGB].width * 8; + else + addr =3D dst; + + stripe->dst[OPE_WR_CLIENT_ARGB].addr =3D addr; + stripe->dst[OPE_WR_CLIENT_ARGB].x_init =3D 0; + stripe->dst[OPE_WR_CLIENT_ARGB].width =3D stripe->src.width; + stripe->dst[OPE_WR_CLIENT_ARGB].height =3D stripe->src.height; + stripe->dst[OPE_WR_CLIENT_ARGB].stride =3D img_w * 8; + stripe->dst[OPE_WR_CLIENT_ARGB].format =3D OPE_PACKER_FMT_PLAIN_64; +} + +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 ope_fmt_state *fo =3D &ctx->fmt_out; + const struct ope_hw_fmt *src_hw =3D ope_find_hw_fmt(fi->fmt->fourcc); + unsigned int num_stripes, width, i; + u32 h_scale, v_scale; + + width =3D fi->width; + num_stripes =3D DIV_ROUND_UP(fi->width, OPE_STRIPE_MAX_W); + h_scale =3D DS_Q21(fi->width, fo->width); + v_scale =3D DS_Q21(fi->height, fo->height); + + for (i =3D 0; i < num_stripes; i++) { + struct ope_stripe *stripe =3D &ctx->stripe[i]; + + memset(stripe, 0, sizeof(*stripe)); + + stripe->src.addr =3D src; + stripe->src.width =3D width; + stripe->src.height =3D fi->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_MIN_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); + + width -=3D stripe->src.width; + src +=3D stripe->src.width * fi->fmt->depth / 8; + + if (ope_pix_fmt_is_yuv(fo->fmt->fourcc)) { + 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); + } else { + ope_gen_stripe_argb_dst(ctx, stripe, dst); + } + + /* 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_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); + } +} + +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 { + .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_FRAME_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_FRAME_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_FRAME_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_CMD_CLEAR); + + if (!ctx) + return; + + if (status & OPE_BUS_WR_INPUT_IF_IRQ_STATUS_0_CONS_VIOL) { + dev_err_ratelimited(ope->dev, + "Write Engine: configuration constraint violation\n"); + 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, + "Write Engine 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) { + dev_err_ratelimited(ope->dev, "Write Engine: fatal violation\n"); + 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_FRAME_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_FRAME_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, + unsigned int fps) +{ + return (unsigned long)fs->width * fs->height * fps; +} + +static inline unsigned int ope_load_avg(const struct ope_fmt_state *fs, + unsigned 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, + unsigned 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_FRAME_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_state *input) +{ + 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); + const struct ope_fmt *fmt; + unsigned int max_w =3D OPE_MAX_W, max_h =3D OPE_MAX_H; + + fmt =3D ope_find_fmt(fmts, n, pix->pixelformat); + if (!fmt) { + fmt =3D &fmts[0]; + pix->pixelformat =3D fmt->fourcc; + } + + if (is_output && input && input->fmt) { + max_w =3D min(max_w, input->width); + max_h =3D min(max_h, input->height); + } + + 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_RAW; + if (pix->plane_fmt[0].bytesperline < pix->width * fmt->depth / 8) + pix->plane_fmt[0].bytesperline =3D pix->width * fmt->depth / 8; + pix->plane_fmt[0].sizeimage =3D (u64)fmt->depth * pix->width * pix->heigh= t / 8; + + 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, NULL); + + 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, NULL); + 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; + + return 0; +} + +static int ope_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2= _fmtdesc *f) +{ + if (f->index >=3D ARRAY_SIZE(ope_output_fmts)) + return -EINVAL; + + f->pixelformat =3D ope_output_fmts[f->index].fourcc; + + return 0; +} + +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, &ctx->fmt_in); + + 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_FRAME_OUT])) + return -EBUSY; + + fmt =3D ope_fmt_try(ctx->ope, true, &f->fmt.pix_mp, &ctx->fmt_in); + 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; + + 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); +} + +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_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.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 * ope_output_fmts[0].depth / 8; + 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; + + 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_QUEUE_FRAME_IN] =3D { + .name =3D "frame-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, 0, 0 }, + { } + }, + }, + [OPE_QUEUE_FRAME_OUT] =3D { + .name =3D "frame-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_FRAME_OUT, + .vdev.fops =3D &ope_fops, + .vdev.ioctl_ops =3D &ope_video_ioctl_ops, + .pads =3D (const struct camss_isp_pad_desc[]) { + { MEDIA_PAD_FL_SINK, OPE_ENTITY_PROC, 2, 0 }, + { } + }, + }, + [OPE_QUEUE_PARAMS] =3D { + .name =3D "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, 1, 0 }, + { } + }, + }, + [OPE_ENTITY_PROC] =3D { + .name =3D "proc", + .obj_type =3D MEDIA_ENTITY_TYPE_BASE, + .function =3D MEDIA_ENT_F_PROC_VIDEO_ISP, + .pads =3D (const struct camss_isp_pad_desc[]) { + { MEDIA_PAD_FL_SINK, OPE_QUEUE_FRAME_IN, 0, 0 }, + { MEDIA_PAD_FL_SINK, OPE_QUEUE_PARAMS, 0, 0 }, + { MEDIA_PAD_FL_SOURCE, OPE_QUEUE_FRAME_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(ARRAY_SIZE(ope_entity_descs)); + 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 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"); --=20 2.34.1 From nobody Wed Jun 17 06:13:00 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 8A25C3BB9F8 for ; Mon, 27 Apr 2026 12:47:03 +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=1777294025; cv=none; b=G8xjhilOh1hbxv1YLmPHj2nZxqG0mjlTad4fzfhfzBTmQki6Ie3UqqHXR5gnsyeUXN1DlvfejSv5678/jLNl+RmBENpU4rf/uyItv/Bw1Wc06kyVQXl4xvpSnn6ZjgvTb9IA9qrwzkWY/BLf2j67P1YbIH1CxJ2FqKjgGw4gjAA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777294025; c=relaxed/simple; bh=keJ16zCRgQ+7YWtz1ydY/Dm8A91/0/g1XPoTpBY7qXc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TSApDBVly38MXfScdZ+essm02rZJ53Z6XdODgDEXX2hbsz2C8DKhFbQxrNkFqA2XPcnhUf43iVACwQUMDxG+9MKRFBsAeTgtS2uhVssEtoOnL1eRraPmTYAbSEiSNp309JS+/reckTUiDiK+86g9dP7pOATB6m4eXIWrtDqIr0Y= 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=ar8oH8ll; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=GQqkeyqt; 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="ar8oH8ll"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="GQqkeyqt" 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 63R8kMjq3962028 for ; Mon, 27 Apr 2026 12:47:03 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= npU9buGBkOswEXBY2Iw0wFN7bz1kBrMayAzI2eUT5/o=; b=ar8oH8llepQOZxd+ UTZpfHbUkAWmyjaA22ALnke7mxRsIOez0vBkv4ytx7Pm5HnD9weTiQBtCGEwavQv 3gB90EB61foqm5OwruI+oCn5fKivfKbwV/eBIfBDBeN/sCMB0AiQ2zX7qBpykMGY uJ96dToVNa9/IrP+986kQja56/lEWU+5fhAx+CCiWCvHY3uvuivDVjan83DNRuiU eP2P6hkrt45LGz7vQGboiofcIPOzXborTKPSuEjCCvQpAEgKsqYkpysyo7UHuf5W dmxVvrFKsWGqO3AFTiLIv4z07bTNJT8OGyUGljdD1WCOM51uHzPbnnu9EFK5TVbf jev2vw== Received: from mail-qt1-f198.google.com (mail-qt1-f198.google.com [209.85.160.198]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4dt4k313r2-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 27 Apr 2026 12:47:02 +0000 (GMT) Received: by mail-qt1-f198.google.com with SMTP id d75a77b69052e-50e67a4f642so77857261cf.0 for ; Mon, 27 Apr 2026 05:47:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1777294021; x=1777898821; 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=npU9buGBkOswEXBY2Iw0wFN7bz1kBrMayAzI2eUT5/o=; b=GQqkeyqtFeC8NuDhyYoEhBhjyUFa1ANEEQNUnO9aj8MNxkLHpQxkPzngr/4h0kJoex 3SLvNZ5EJza3mJzvepOcoZ3ubWf9ichIq6miPoQYrtnI79rf/4/LSTP5ViHsO41gzkBA 2vraUZF31iuYp4coo/CNotQRcsmFkBMngmUuGUI7vlocHGpSjEQLHUqRjtse/0nDTkLW c5HYxxuJ4a97yKo7nEvcW3pPXlOcDylGQJruWjVmI+kTqW6kta0ozVxNMfufyD3OXGse pbRoP+fTsDpA8htUFrlPiC+8pRBR9y8LWOC2DfYvBLg1UI1U3tiBFTlswmR9P+Glgvv+ 7EGg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777294021; x=1777898821; 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=npU9buGBkOswEXBY2Iw0wFN7bz1kBrMayAzI2eUT5/o=; b=W52HmGBUsPUCAKPb1dkZx4BH5BArkHeHuR0a0s0sCBvn5spthK8kQ6fnFiCCZyg+Hu EX3k90EFdZv/G4EO/Z62Qiov9SnRKhhUsljEkQ4M45Odqpqbo1jOCkTlP65Z/0Lte0Qy vBzGFgIe8Ov63E2oKGSp/2fJvLnWJAGLxN4gDfsmCM8kF7u7UypjHmSPI+dBU/pfXPqa xbLJuILMcY+GYrdQ5bS53QYg+RxcLSc2yiGgs9pS27+1AiCjK6TZK5YPZeFBjlvgwKdG dogSxoe1WhOeG2+xahd8CqEZItnQPn4k7hbJeJH+fy6crK7U5S5RfClL28JD31CJslDj zdRQ== X-Forwarded-Encrypted: i=1; AFNElJ9lp4YrryunRQuMWKypFCm49JFJQCbtXJnS7nbJMF1IxorykkKqPgwYM/5povBV23v1166HeYk6PwOk3Qo=@vger.kernel.org X-Gm-Message-State: AOJu0YyRvpo/4XvteKtJirUZDCqaJEmjiLufWtmNSSqukecuPLykAu2o K2afkDS+9A8msW+qquSe+TwSr0li6nROe69qROQduSqCzONoEd+U3kLVhOsA1K4iciQ6ZTGmFPG paBhZ1eclQdPAFY+UCpWR1oTup0AnwQ6U6jhIH8tb79gPhsNL99WW0MI+ZvOr2RG8U9w= X-Gm-Gg: AeBDiet3yQ/urKK86Hl96xSPDRD5VTsCYbTrdrhMi9/sMvlXTEMNwQfK/wOy9aVKOtM VRQYXpUZbNn891Nfwlmhn/jwFXK7ygbJRMYbguITViyhdtxIbsyOj1hRJVHBcwCRGK9sVQAzybL /eE0Q/fKcnMFUG+wR/Cuyxx2WEBRsuGp75UdV3Kin0xIy/EovDLz6YGbqWiIaW7DBX/JPr7Bkmz dtUAPWbpV9G7wR8lKmkHINe4+m4NCQsrAKtop09McIANaoNQaw9kLbSoelyPpgic6MU2JqgfppU y9v+64s2X3cxeALBnBdD8bPTGBCOu3jEKMsEaL3ACuTU+3X5XDEobp+oYDTDI/3/bnLbvi/3r8u EtB/867jm5H5JZlbSQSwFmxVcvmlFlKirG0aK3Likw73veR6Kcptx1xzmqJ5x1MpDR40tMkVAQ0 TIoEeWQOLA8NlmIkHI0pdkHAP74nc= X-Received: by 2002:ac8:5890:0:b0:50d:6ee0:3822 with SMTP id d75a77b69052e-50e36b3c598mr624428661cf.4.1777294020690; Mon, 27 Apr 2026 05:47:00 -0700 (PDT) X-Received: by 2002:ac8:5890:0:b0:50d:6ee0:3822 with SMTP id d75a77b69052e-50e36b3c598mr624428121cf.4.1777294020214; Mon, 27 Apr 2026 05:47:00 -0700 (PDT) Received: from QCOM-eG0v1AUPpu.na.qualcomm.com ([2a01:e0a:830:450:653f:4d28:6a78:a6ca]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ba454d1bd19sm1091496866b.37.2026.04.27.05.46.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Apr 2026 05:46:59 -0700 (PDT) From: Loic Poulain Date: Mon, 27 Apr 2026 14:43:41 +0200 Subject: [PATCH v2 14/14] 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: <20260427-camss-isp-ope-v2-14-f430e7485009@oss.qualcomm.com> References: <20260427-camss-isp-ope-v2-0-f430e7485009@oss.qualcomm.com> In-Reply-To: <20260427-camss-isp-ope-v2-0-f430e7485009@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 X-Mailer: b4 0.14.2 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDI3MDEzNSBTYWx0ZWRfXxoJNOHW+teNo Y7yDORyQEHqxHMUxp6EABoX9q9jKh6hieQZg+KQtAI48M3kZIiZX0xNrXRGsBTrfJt2/ZGgNGyv iKDxEcSAO2L79WuZYWtM3rNFEf9F8GwcpvtMo67DNgsuZleOE4effcBxKYGrG34rr1tZ7qhHQQS pm15B0kmKG67nqEdnrG25FctwkgA0CoDBfN8QH54wI5/QI3XVk7sEhOQllMn4sTdmqAdgvg5Lh/ +UxIxjOXluabhmKYaMZVw/io9wuJ7F1xIw53Fjtw2iXzZv7dm870UYQRdPP4DDWJaTIjGcqUGFS qZo1kJ91dmgEgA6QSXzQPZuVK/KJxoorpT5jERYDbR3sbE5kJW19YG27WHrQw68ejXAidgPxjEU WVjDrKqsjeDEPjfZlyH3z1an1jUzh0sxb0iOYECRPMT2Tn80ep2AxfyceLN3tZW10w/DxoI/M2D i11ycPMA7l7MIQF3nyg== X-Authority-Analysis: v=2.4 cv=a7QAM0SF c=1 sm=1 tr=0 ts=69ef5ac6 cx=c_pps a=mPf7EqFMSY9/WdsSgAYMbA==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=Um2Pa8k9VHT-vaBCBUpS:22 a=EUspDBNiAAAA:8 a=1BEw5LmG3YzgyHxDt7YA:9 a=L3Ch9UzycIYwzZWD:21 a=QEXdDO2ut3YA:10 a=dawVfQjAaf238kedN5IG:22 X-Proofpoint-GUID: 3yDiGmq6Ky_B73KEWHqKRO89gB_pCpoR X-Proofpoint-ORIG-GUID: 3yDiGmq6Ky_B73KEWHqKRO89gB_pCpoR 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-04-27_04,2026-04-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 malwarescore=0 spamscore=0 phishscore=0 impostorscore=0 lowpriorityscore=0 suspectscore=0 bulkscore=0 priorityscore=1501 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2604270135 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 f9b46cf1c6462a89784429565e1636ce2ba68d73..ee0fe1832248eed8405968bf05d= 4c73dd6e8d13d 100644 --- a/arch/arm64/boot/dts/qcom/agatti.dtsi +++ b/arch/arm64/boot/dts/qcom/agatti.dtsi @@ -1919,6 +1919,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 { @@ -1933,6 +1937,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