From nobody Mon Apr  7 01:01:10 2025
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 7094A1AA1C8;
	Fri,  7 Feb 2025 07:55:26 +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=1738914928; cv=none;
 b=caG97D26pKVtdCf6I22MHRdpSgujcXQtvBEoShsKOXUikqy2W5IN0EPwxF2Fzn7Ln+NCUldNadbPrHlpfvDQfNKPoa20TySjN3xvvnAx4eXqZUH2pO3Z7mjFA8G5urvDYB+CTCIJLBAShn/tCT/EQzu7Xb76fmi7Jh3r7GnkuBE=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738914928; c=relaxed/simple;
	bh=sBDYw/NfyioWk7vSBNe8CdtiQ5M87uDbmojbi8WgXH4=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=EoOkkpMZtzFjWorHii2VP5PEja0QKlIKqfdc78MImI7egUkL8VJHezcofh2tl/O4oKlb4L5izzJHIkB0fvAenA/l4dIzkB4T3SvYkCpB1eoULEBYQelwr0l4/h3bjYrrs4daDGiFpIAX1oN9V0nAjH4AQcTym4wQkTdDJTyEX74=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=V6mbAAFp; arc=none smtp.client-ip=205.220.180.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="V6mbAAFp"
Received: from pps.filterd (m0279871.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 51730E13016280;
	Fri, 7 Feb 2025 07:55:09 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	yLAjX6P2CDz/N4iMFPGfkTGd4y3/euksP/er+yOPZuQ=; b=V6mbAAFpB5dCZvRG
	aK5JlwWGYGHkHtUEZ96DJkUXQnMgGoInxFF9mb5brnjWC9cyZeuv/eKd/qqT7w6k
	rMFgW4WLMCwvzLSVD6Afdoqm2x5bH41XEGC/c7wRI6CdYWyfWHLpjKzBI4t2ozKk
	2bOHq5HAdb2rZbKK9ypK8AXLNDVy5aKtP9h/CuvBeii1rp9dwOCx7XGNU69qyTzt
	+sg7jyK5Fyp6RrYKFt2ysAo59ojicGN5g0Z+Gq429PMKpC/15judh+0wJEuimd/j
	FdzgEoPtaelAwWS3iqY3RrQJ6MLW99u5nLgJl1mTNLF9jN18N2wNd1mwWzoYp+VG
	4d7gYg==
Received: from nalasppmta04.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44n9vq0n2a-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:55:08 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA04.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177t7Wr006339
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:55:07 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:55:00 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:24:41 +0530
Subject: [PATCH v10 01/28] dt-bindings: media: Add video support for QCOM
 SM8550 SoC
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-1-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>,
        Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914892; l=5436;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=sBDYw/NfyioWk7vSBNe8CdtiQ5M87uDbmojbi8WgXH4=;
 b=oBg6m9gmM7es9uO/KOPs33YMpmjh5hw2fwRHpx+MhsTa45ZWnmN6xQXqfcgORVA9Y5SrsZeFW
 ZMQD8boyikFCkh1RDd3RJkSHfeXRVY4xonlzp6khSOwKUSgDc/GxtKl
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-GUID: It602GegiUJC788ENppGi5YU9dHupD_M
X-Proofpoint-ORIG-GUID: It602GegiUJC788ENppGi5YU9dHupD_M
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 bulkscore=0 malwarescore=0
 phishscore=0 mlxscore=0 lowpriorityscore=0 adultscore=0 clxscore=1015
 impostorscore=0 priorityscore=1501 mlxlogscore=999 suspectscore=0
 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070059

Introduce support for Qualcomm new video acceleration hardware i.e.
iris, used for video stream decoding and encoding on QCOM SM8550 SoC.

Cc: devicetree@vger.kernel.org
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 .../bindings/media/qcom,sm8550-iris.yaml           | 158 +++++++++++++++++=
++++
 1 file changed, 158 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/qcom,sm8550-iris.yaml =
b/Documentation/devicetree/bindings/media/qcom,sm8550-iris.yaml
new file mode 100644
index 000000000000..e424ea84c211
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/qcom,sm8550-iris.yaml
@@ -0,0 +1,158 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/qcom,sm8550-iris.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm iris video encode and decode accelerators
+
+maintainers:
+  - Vikash Garodia <quic_vgarodia@quicinc.com>
+  - Dikshita Agarwal <quic_dikshita@quicinc.com>
+
+description:
+  The iris video processing unit is a video encode and decode accelerator
+  present on Qualcomm platforms.
+
+allOf:
+  - $ref: qcom,venus-common.yaml#
+
+properties:
+  compatible:
+    const: qcom,sm8550-iris
+
+  power-domains:
+    maxItems: 4
+
+  power-domain-names:
+    items:
+      - const: venus
+      - const: vcodec0
+      - const: mxc
+      - const: mmcx
+
+  clocks:
+    maxItems: 3
+
+  clock-names:
+    items:
+      - const: iface
+      - const: core
+      - const: vcodec0_core
+
+  interconnects:
+    maxItems: 2
+
+  interconnect-names:
+    items:
+      - const: cpu-cfg
+      - const: video-mem
+
+  resets:
+    maxItems: 1
+
+  reset-names:
+    items:
+      - const: bus
+
+  iommus:
+    maxItems: 2
+
+  dma-coherent: true
+
+  operating-points-v2: true
+
+  opp-table:
+    type: object
+
+required:
+  - compatible
+  - power-domain-names
+  - interconnects
+  - interconnect-names
+  - resets
+  - reset-names
+  - iommus
+  - dma-coherent
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,rpmh.h>
+    #include <dt-bindings/clock/qcom,sm8550-gcc.h>
+    #include <dt-bindings/clock/qcom,sm8450-videocc.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interconnect/qcom,icc.h>
+    #include <dt-bindings/interconnect/qcom,sm8550-rpmh.h>
+    #include <dt-bindings/power/qcom-rpmpd.h>
+    #include <dt-bindings/power/qcom,rpmhpd.h>
+
+    video-codec@aa00000 {
+        compatible =3D "qcom,sm8550-iris";
+        reg =3D <0x0aa00000 0xf0000>;
+        interrupts =3D <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+
+        power-domains =3D <&videocc VIDEO_CC_MVS0C_GDSC>,
+                        <&videocc VIDEO_CC_MVS0_GDSC>,
+                        <&rpmhpd RPMHPD_MXC>,
+                        <&rpmhpd RPMHPD_MMCX>;
+        power-domain-names =3D "venus", "vcodec0", "mxc", "mmcx";
+
+        clocks =3D <&gcc GCC_VIDEO_AXI0_CLK>,
+                 <&videocc VIDEO_CC_MVS0C_CLK>,
+                 <&videocc VIDEO_CC_MVS0_CLK>;
+        clock-names =3D "iface", "core", "vcodec0_core";
+
+        interconnects =3D <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+                         &config_noc SLAVE_VENUS_CFG QCOM_ICC_TAG_ALWAYS>,
+                        <&mmss_noc MASTER_VIDEO QCOM_ICC_TAG_ALWAYS
+                         &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+        interconnect-names =3D "cpu-cfg", "video-mem";
+
+        memory-region =3D <&video_mem>;
+
+        resets =3D <&gcc GCC_VIDEO_AXI0_CLK_ARES>;
+        reset-names =3D "bus";
+
+        iommus =3D <&apps_smmu 0x1940 0x0000>,
+                 <&apps_smmu 0x1947 0x0000>;
+        dma-coherent;
+
+        operating-points-v2 =3D <&iris_opp_table>;
+
+        iris_opp_table: opp-table {
+            compatible =3D "operating-points-v2";
+
+            opp-240000000 {
+                opp-hz =3D /bits/ 64 <240000000>;
+                required-opps =3D <&rpmhpd_opp_svs>,
+                                <&rpmhpd_opp_low_svs>;
+            };
+
+            opp-338000000 {
+                opp-hz =3D /bits/ 64 <338000000>;
+                required-opps =3D <&rpmhpd_opp_svs>,
+                                <&rpmhpd_opp_svs>;
+            };
+
+            opp-366000000 {
+                opp-hz =3D /bits/ 64 <366000000>;
+                required-opps =3D <&rpmhpd_opp_svs_l1>,
+                                <&rpmhpd_opp_svs_l1>;
+            };
+
+            opp-444000000 {
+                opp-hz =3D /bits/ 64 <444000000>;
+                required-opps =3D <&rpmhpd_opp_turbo>,
+                                <&rpmhpd_opp_turbo>;
+            };
+
+            opp-533333334 {
+                opp-hz =3D /bits/ 64 <533333334>;
+                required-opps =3D <&rpmhpd_opp_turbo_l1>,
+                                <&rpmhpd_opp_turbo_l1>;
+            };
+        };
+    };
+...

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 BE6E61A2C25;
	Fri,  7 Feb 2025 07:55:30 +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=1738914932; cv=none;
 b=QAkjdRDO5FAkjKHsa2dHFd8seDiq8uq2noDIoBtWA30ZfzGeBiZXlfkirDGWmMXDqPMtTfG8NH8wVOSZgGcPH6c7NNphENlQvpXhfdAfdbRt32PepQlD7Ibnk7hOA3ZwSlv4dGqjGbxQ3/k2aG21PMKCLAd72czva/yFAftaOos=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738914932; c=relaxed/simple;
	bh=JlyfSKCHt5/PXX1nd90p+aLfTDbpdjw2C+pY44bnqtk=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=CAPY5+NXEyppD3l4n8BGf7ySQLx6bY+KpXkHEND//hP8rHo2HZdt1J+Z1OkYTmjJX3TGws8fYeP0eBlTo93rQKYiVc+o4Qn6yi+sYK89VCicqkh0KbvDWYu8KpAzwVMQhm3bPb2fpDMii3pCG5tW3uBYW0nq1uVo8DoVhnqjaxo=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=IBFrIZLI; arc=none smtp.client-ip=205.220.180.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="IBFrIZLI"
Received: from pps.filterd (m0279872.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 5174KZNK007609;
	Fri, 7 Feb 2025 07:55:16 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	95JojeoAzPdU80RvZUdsoAiyXeGQ6fg99KwJ+CbQYls=; b=IBFrIZLIecDIR/lv
	DgJZargGQSANMgOXzyl/uW05sLgPdzrLVzc7ikcD4ludIZ8cK64JoIpH26AxOS7j
	nx2QxFRoKTEvqGo9AXrb2EAjGAv3xIpeMeHtf7ILigrIWPfN02zDXEz9Pely6F5T
	NLLNAsqB86qa5O1a+LIEYpA2vM3HINanmNYcVKocB06G8sm8vIbSS+7NMizAo7Qi
	R1KPJSW5Ltzxa5D/N7AYQGwQb5Mp8HxlGOyJc+yFkkPmE82V/RXN+ILC2xcbtgnD
	IDL9ckkHJwwINsT6qrMA0ij4mVdn1+jY8Jh1oDQdVEM19e5a/qLYldw8/PFFEwbz
	mdymvg==
Received: from nalasppmta01.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44nb2m8ftt-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:55:16 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA01.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177tD7X007995
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:55:13 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:55:07 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:24:42 +0530
Subject: [PATCH v10 02/28] media: iris: add platform driver for iris video
 device
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-2-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914892; l=13400;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=JlyfSKCHt5/PXX1nd90p+aLfTDbpdjw2C+pY44bnqtk=;
 b=m4Q438mtKyseK8gHaAVXDi3moEPKudI+NLlTEnMZ4D3msTv40DC90EIkWqbCJm2+WxFo0Yl4F
 uqAzhu44kV5B1p3VffgCuec2E02DhRF3oSQ8kTNaWHm8Ok8M2pbvwSU
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-GUID: lxkAFk98jAbY5ouYxAmiRzgWHO6YszlV
X-Proofpoint-ORIG-GUID: lxkAFk98jAbY5ouYxAmiRzgWHO6YszlV
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 mlxlogscore=999
 suspectscore=0 bulkscore=0 phishscore=0 malwarescore=0 mlxscore=0
 spamscore=0 priorityscore=1501 lowpriorityscore=0 adultscore=0
 clxscore=1015 impostorscore=0 classifier=spam adjust=0 reason=mlx
 scancount=1 engine=8.19.0-2501170000 definitions=main-2502070060

In preparation for adding H264 decode functionality, add the probe and
remove functions and platform data to initialize iris resources, which
are clocks, interconnects, power domains, reset clocks, and clock
frequencies used for the iris hardware.

Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl>
Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 drivers/media/platform/qcom/Kconfig                |   1 +
 drivers/media/platform/qcom/Makefile               |   1 +
 drivers/media/platform/qcom/iris/Kconfig           |   9 +
 drivers/media/platform/qcom/iris/Makefile          |   4 +
 drivers/media/platform/qcom/iris/iris_core.h       |  54 +++++
 .../platform/qcom/iris/iris_platform_common.h      |  35 +++
 .../platform/qcom/iris/iris_platform_sm8550.c      |  37 ++++
 drivers/media/platform/qcom/iris/iris_probe.c      | 237 +++++++++++++++++=
++++
 8 files changed, 378 insertions(+)

diff --git a/drivers/media/platform/qcom/Kconfig b/drivers/media/platform/q=
com/Kconfig
index cc5799b9ea00..4f4d3a68e6e5 100644
--- a/drivers/media/platform/qcom/Kconfig
+++ b/drivers/media/platform/qcom/Kconfig
@@ -3,4 +3,5 @@
 comment "Qualcomm media platform drivers"
=20
 source "drivers/media/platform/qcom/camss/Kconfig"
+source "drivers/media/platform/qcom/iris/Kconfig"
 source "drivers/media/platform/qcom/venus/Kconfig"
diff --git a/drivers/media/platform/qcom/Makefile b/drivers/media/platform/=
qcom/Makefile
index 4f055c396e04..ea2221a202c0 100644
--- a/drivers/media/platform/qcom/Makefile
+++ b/drivers/media/platform/qcom/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-y +=3D camss/
+obj-y +=3D iris/
 obj-y +=3D venus/
diff --git a/drivers/media/platform/qcom/iris/Kconfig b/drivers/media/platf=
orm/qcom/iris/Kconfig
new file mode 100644
index 000000000000..34a2f81c5db3
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/Kconfig
@@ -0,0 +1,9 @@
+config VIDEO_QCOM_IRIS
+        tristate "Qualcomm iris V4L2 decoder driver"
+        depends on VIDEO_DEV
+        depends on ARCH_QCOM || COMPILE_TEST
+        help
+          This is a V4L2 driver for Qualcomm iris video accelerator
+          hardware. It accelerates decoding operations on various
+          Qualcomm SoCs.
+          To compile this driver as a module choose m here.
diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/plat=
form/qcom/iris/Makefile
new file mode 100644
index 000000000000..7e701361492e
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/Makefile
@@ -0,0 +1,4 @@
+iris-objs +=3D iris_platform_sm8550.o \
+             iris_probe.o \
+
+obj-$(CONFIG_VIDEO_QCOM_IRIS) +=3D iris.o
diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/p=
latform/qcom/iris/iris_core.h
new file mode 100644
index 000000000000..27bc2ca71e1b
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_core.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#ifndef __IRIS_CORE_H__
+#define __IRIS_CORE_H__
+
+#include <linux/types.h>
+#include <media/v4l2-device.h>
+
+#include "iris_platform_common.h"
+
+struct icc_info {
+	const char		*name;
+	u32			bw_min_kbps;
+	u32			bw_max_kbps;
+};
+
+/**
+ * struct iris_core - holds core parameters valid for all instances
+ *
+ * @dev: reference to device structure
+ * @reg_base: IO memory base address
+ * @irq: iris irq
+ * @v4l2_dev: a holder for v4l2 device structure
+ * @vdev_dec: iris video device structure for decoder
+ * @icc_tbl: table of iris interconnects
+ * @icc_count: count of iris interconnects
+ * @pmdomain_tbl: table of iris power domains
+ * @opp_pmdomain_tbl: table of opp power domains
+ * @clock_tbl: table of iris clocks
+ * @clk_count: count of iris clocks
+ * @resets: table of iris reset clocks
+ * @iris_platform_data: a structure for platform data
+ */
+
+struct iris_core {
+	struct device				*dev;
+	void __iomem				*reg_base;
+	int					irq;
+	struct v4l2_device			v4l2_dev;
+	struct video_device			*vdev_dec;
+	struct icc_bulk_data			*icc_tbl;
+	u32					icc_count;
+	struct dev_pm_domain_list		*pmdomain_tbl;
+	struct dev_pm_domain_list		*opp_pmdomain_tbl;
+	struct clk_bulk_data			*clock_tbl;
+	u32					clk_count;
+	struct reset_control_bulk_data		*resets;
+	const struct iris_platform_data		*iris_platform_data;
+};
+
+#endif
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/driv=
ers/media/platform/qcom/iris/iris_platform_common.h
new file mode 100644
index 000000000000..31c53dad8136
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#ifndef __IRIS_PLATFORM_COMMON_H__
+#define __IRIS_PLATFORM_COMMON_H__
+
+extern struct iris_platform_data sm8550_data;
+
+enum platform_clk_type {
+	IRIS_AXI_CLK,
+	IRIS_CTRL_CLK,
+	IRIS_HW_CLK,
+};
+
+struct platform_clk_data {
+	enum platform_clk_type clk_type;
+	const char *clk_name;
+};
+
+struct iris_platform_data {
+	const struct icc_info *icc_tbl;
+	unsigned int icc_tbl_size;
+	const char * const *pmdomain_tbl;
+	unsigned int pmdomain_tbl_size;
+	const char * const *opp_pd_tbl;
+	unsigned int opp_pd_tbl_size;
+	const struct platform_clk_data *clk_tbl;
+	unsigned int clk_tbl_size;
+	const char * const *clk_rst_tbl;
+	unsigned int clk_rst_tbl_size;
+};
+
+#endif
diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/driv=
ers/media/platform/qcom/iris/iris_platform_sm8550.c
new file mode 100644
index 000000000000..3dd91523d783
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#include "iris_core.h"
+#include "iris_platform_common.h"
+
+static const struct icc_info sm8550_icc_table[] =3D {
+	{ "cpu-cfg",    1000, 1000     },
+	{ "video-mem",  1000, 15000000 },
+};
+
+static const char * const sm8550_clk_reset_table[] =3D { "bus" };
+
+static const char * const sm8550_pmdomain_table[] =3D { "venus", "vcodec0"=
 };
+
+static const char * const sm8550_opp_pd_table[] =3D { "mxc", "mmcx" };
+
+static const struct platform_clk_data sm8550_clk_table[] =3D {
+	{IRIS_AXI_CLK,  "iface"        },
+	{IRIS_CTRL_CLK, "core"         },
+	{IRIS_HW_CLK,   "vcodec0_core" },
+};
+
+struct iris_platform_data sm8550_data =3D {
+	.icc_tbl =3D sm8550_icc_table,
+	.icc_tbl_size =3D ARRAY_SIZE(sm8550_icc_table),
+	.clk_rst_tbl =3D sm8550_clk_reset_table,
+	.clk_rst_tbl_size =3D ARRAY_SIZE(sm8550_clk_reset_table),
+	.pmdomain_tbl =3D sm8550_pmdomain_table,
+	.pmdomain_tbl_size =3D ARRAY_SIZE(sm8550_pmdomain_table),
+	.opp_pd_tbl =3D sm8550_opp_pd_table,
+	.opp_pd_tbl_size =3D ARRAY_SIZE(sm8550_opp_pd_table),
+	.clk_tbl =3D sm8550_clk_table,
+	.clk_tbl_size =3D ARRAY_SIZE(sm8550_clk_table),
+};
diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/=
platform/qcom/iris/iris_probe.c
new file mode 100644
index 000000000000..911e3bc1b434
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_probe.c
@@ -0,0 +1,237 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#include <linux/clk.h>
+#include <linux/interconnect.h>
+#include <linux/module.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_opp.h>
+#include <linux/reset.h>
+
+#include "iris_core.h"
+
+static int iris_init_icc(struct iris_core *core)
+{
+	const struct icc_info *icc_tbl;
+	u32 i =3D 0;
+
+	icc_tbl =3D core->iris_platform_data->icc_tbl;
+
+	core->icc_count =3D core->iris_platform_data->icc_tbl_size;
+	core->icc_tbl =3D devm_kzalloc(core->dev,
+				     sizeof(struct icc_bulk_data) * core->icc_count,
+				     GFP_KERNEL);
+	if (!core->icc_tbl)
+		return -ENOMEM;
+
+	for (i =3D 0; i < core->icc_count; i++) {
+		core->icc_tbl[i].name =3D icc_tbl[i].name;
+		core->icc_tbl[i].avg_bw =3D icc_tbl[i].bw_min_kbps;
+		core->icc_tbl[i].peak_bw =3D 0;
+	}
+
+	return devm_of_icc_bulk_get(core->dev, core->icc_count, core->icc_tbl);
+}
+
+static int iris_init_power_domains(struct iris_core *core)
+{
+	const struct platform_clk_data *clk_tbl;
+	u32 clk_cnt, i;
+	int ret;
+
+	struct dev_pm_domain_attach_data iris_pd_data =3D {
+		.pd_names =3D core->iris_platform_data->pmdomain_tbl,
+		.num_pd_names =3D core->iris_platform_data->pmdomain_tbl_size,
+		.pd_flags =3D PD_FLAG_NO_DEV_LINK,
+	};
+
+	struct dev_pm_domain_attach_data iris_opp_pd_data =3D {
+		.pd_names =3D core->iris_platform_data->opp_pd_tbl,
+		.num_pd_names =3D core->iris_platform_data->opp_pd_tbl_size,
+		.pd_flags =3D PD_FLAG_DEV_LINK_ON,
+	};
+
+	ret =3D devm_pm_domain_attach_list(core->dev, &iris_pd_data, &core->pmdom=
ain_tbl);
+	if (ret < 0)
+		return ret;
+
+	ret =3D  devm_pm_domain_attach_list(core->dev, &iris_opp_pd_data, &core->=
opp_pmdomain_tbl);
+	if (ret < 0)
+		return ret;
+
+	clk_tbl =3D core->iris_platform_data->clk_tbl;
+	clk_cnt =3D core->iris_platform_data->clk_tbl_size;
+
+	for (i =3D 0; i < clk_cnt; i++) {
+		if (clk_tbl[i].clk_type =3D=3D IRIS_HW_CLK) {
+			ret =3D devm_pm_opp_set_clkname(core->dev, clk_tbl[i].clk_name);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return devm_pm_opp_of_add_table(core->dev);
+}
+
+static int iris_init_clocks(struct iris_core *core)
+{
+	int ret;
+
+	ret =3D devm_clk_bulk_get_all(core->dev, &core->clock_tbl);
+	if (ret < 0)
+		return ret;
+
+	core->clk_count =3D ret;
+
+	return 0;
+}
+
+static int iris_init_resets(struct iris_core *core)
+{
+	const char * const *rst_tbl;
+	u32 rst_tbl_size;
+	u32 i =3D 0;
+
+	rst_tbl =3D core->iris_platform_data->clk_rst_tbl;
+	rst_tbl_size =3D core->iris_platform_data->clk_rst_tbl_size;
+
+	core->resets =3D devm_kzalloc(core->dev,
+				    sizeof(*core->resets) * rst_tbl_size,
+				    GFP_KERNEL);
+	if (!core->resets)
+		return -ENOMEM;
+
+	for (i =3D 0; i < rst_tbl_size; i++)
+		core->resets[i].id =3D rst_tbl[i];
+
+	return devm_reset_control_bulk_get_exclusive(core->dev, rst_tbl_size, cor=
e->resets);
+}
+
+static int iris_init_resources(struct iris_core *core)
+{
+	int ret;
+
+	ret =3D iris_init_icc(core);
+	if (ret)
+		return ret;
+
+	ret =3D iris_init_power_domains(core);
+	if (ret)
+		return ret;
+
+	ret =3D iris_init_clocks(core);
+	if (ret)
+		return ret;
+
+	return iris_init_resets(core);
+}
+
+static int iris_register_video_device(struct iris_core *core)
+{
+	struct video_device *vdev;
+	int ret;
+
+	vdev =3D video_device_alloc();
+	if (!vdev)
+		return -ENOMEM;
+
+	strscpy(vdev->name, "qcom-iris-decoder", sizeof(vdev->name));
+	vdev->release =3D video_device_release;
+	vdev->vfl_dir =3D VFL_DIR_M2M;
+	vdev->v4l2_dev =3D &core->v4l2_dev;
+	vdev->device_caps =3D V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
+
+	ret =3D video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+	if (ret)
+		goto err_vdev_release;
+
+	core->vdev_dec =3D vdev;
+	video_set_drvdata(vdev, core);
+
+	return 0;
+
+err_vdev_release:
+	video_device_release(vdev);
+
+	return ret;
+}
+
+static void iris_remove(struct platform_device *pdev)
+{
+	struct iris_core *core;
+
+	core =3D platform_get_drvdata(pdev);
+	if (!core)
+		return;
+
+	video_unregister_device(core->vdev_dec);
+
+	v4l2_device_unregister(&core->v4l2_dev);
+}
+
+static int iris_probe(struct platform_device *pdev)
+{
+	struct device *dev =3D &pdev->dev;
+	struct iris_core *core;
+	int ret;
+
+	core =3D devm_kzalloc(&pdev->dev, sizeof(*core), GFP_KERNEL);
+	if (!core)
+		return -ENOMEM;
+	core->dev =3D dev;
+
+	core->reg_base =3D devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(core->reg_base))
+		return PTR_ERR(core->reg_base);
+
+	core->irq =3D platform_get_irq(pdev, 0);
+	if (core->irq < 0)
+		return core->irq;
+
+	core->iris_platform_data =3D of_device_get_match_data(core->dev);
+
+	ret =3D iris_init_resources(core);
+	if (ret)
+		return ret;
+
+	ret =3D v4l2_device_register(dev, &core->v4l2_dev);
+	if (ret)
+		return ret;
+
+	ret =3D iris_register_video_device(core);
+	if (ret)
+		goto err_v4l2_unreg;
+
+	platform_set_drvdata(pdev, core);
+
+	return 0;
+
+err_v4l2_unreg:
+	v4l2_device_unregister(&core->v4l2_dev);
+
+	return ret;
+}
+
+static const struct of_device_id iris_dt_match[] =3D {
+	{
+		.compatible =3D "qcom,sm8550-iris",
+		.data =3D &sm8550_data,
+	},
+	{ },
+};
+MODULE_DEVICE_TABLE(of, iris_dt_match);
+
+static struct platform_driver qcom_iris_driver =3D {
+	.probe =3D iris_probe,
+	.remove =3D iris_remove,
+	.driver =3D {
+		.name =3D "qcom-iris",
+		.of_match_table =3D iris_dt_match,
+	},
+};
+
+module_platform_driver(qcom_iris_driver);
+MODULE_DESCRIPTION("Qualcomm iris video driver");
+MODULE_LICENSE("GPL");

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 789C0235BE5;
	Fri,  7 Feb 2025 07:55:36 +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=1738914938; cv=none;
 b=qmdWfv0agSEPGxoC2BiLW0q069hNXoJJC3tncBXnm2rYLFceeLg1Rk5rIu4t2hpAqCajQDf8g8JHfFifHSJ1CTurpKXcVwW93AT5IMBOmSaE07TR9rNT2H0MjRASoGTzOBD4vXkWwWhYlH5ZYnUpitfGLsB7qm++9IFrCEAmgsE=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738914938; c=relaxed/simple;
	bh=2p+HvllgW7CtoQYGf02sin3/peMgHvXqqTEqkGyfcm0=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=gVo4eKxXcKDXmXXueY/qy45wAVP7/Op9eRuo7Jm3bXuFLMzg6FFIKS6+oo0HOt6ZGm6Wu5ktkvdtbnIznLeoeJ+9xRGyq2A1hVmuJ5CPGzmPsUiLQdmWxqOvrtavw9aSBUB7/ujMkzlbtk4unQbZD8PNMX1KT+WbgWmIKvBoLsM=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=ZoSfHWm4; arc=none smtp.client-ip=205.220.168.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="ZoSfHWm4"
Received: from pps.filterd (m0279866.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 51770SaP016630;
	Fri, 7 Feb 2025 07:55:21 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	VWKpo4ci74xsqXSDoIqL9s4yseJqWyi1+xu8ZnhEanA=; b=ZoSfHWm4WrCjq0qT
	/72tYMTHIH/rWwebvdGCr6JD5HV3/ekbE2UZ4rZ2UHygFe+ve05soP0MFbBs/aJB
	sznEWqys6ks+wghHQoeu6fSwCE59zCbb0wlqbuzzJZfv0YSsvN3r+1GzRi2U1qxI
	09/m3W4zYKmOPHvK6vLWqSb/fl9tqsLobKxYTn/4XMEopLXnd7IgB1HTZlyZl5+P
	uGiSInJNq8JdzIGW/xIjkfYdjiYQxMrQCcW3TgxsjMZk6uvNKzqcXlIInrFYtUzt
	oTJJ2JPSgzsvuO/iatsn8emJY5jJtytcYk/BxEb7CHUFLZE6nxTQBG+MWsPKYoSJ
	lywu2A==
Received: from nalasppmta01.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44nddh04aq-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:55:20 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA01.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177tKu1008156
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:55:20 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:55:14 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:24:43 +0530
Subject: [PATCH v10 03/28] media: iris: implement iris v4l2 file ops
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-3-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914892; l=14210;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=2p+HvllgW7CtoQYGf02sin3/peMgHvXqqTEqkGyfcm0=;
 b=MCA8jB7VziATEKflAkUU4IP0erTqlQx2OasY733RD1Jbal8XJ5BrGucBruvQgbAEIZh8QLg8V
 o8xcHhd2Q8VBKycXWjIZGM54l6ZK2zTvo8E64I69qz6TNE2obyjrdc8
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-ORIG-GUID: uQ13PjibeMVYWNoTL4oxyne9q0A0zVEN
X-Proofpoint-GUID: uQ13PjibeMVYWNoTL4oxyne9q0A0zVEN
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 phishscore=0 suspectscore=0
 clxscore=1015 mlxlogscore=999 lowpriorityscore=0 impostorscore=0
 mlxscore=0 spamscore=0 priorityscore=1501 adultscore=0 malwarescore=0
 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070060

Implement open, close and poll ops.

Open:
Configure the vb2 queue and v4l2 file handler. Allocate a video instance
and add the instance to core instance list.

Close:
Free the instance and remove it from core instance list.

Poll:
Wait for an event on vb2 src and vb2 dst queues.

Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl>
Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 drivers/media/platform/qcom/iris/Kconfig           |   1 +
 drivers/media/platform/qcom/iris/Makefile          |   5 +-
 drivers/media/platform/qcom/iris/iris_core.h       |   2 +
 drivers/media/platform/qcom/iris/iris_hfi_gen1.h   |  13 ++
 .../platform/qcom/iris/iris_hfi_gen1_command.c     |  12 ++
 drivers/media/platform/qcom/iris/iris_hfi_gen2.h   |  22 +++
 .../platform/qcom/iris/iris_hfi_gen2_command.c     |  11 ++
 drivers/media/platform/qcom/iris/iris_instance.h   |  31 +++++
 .../platform/qcom/iris/iris_platform_common.h      |   1 +
 .../platform/qcom/iris/iris_platform_sm8550.c      |   2 +
 drivers/media/platform/qcom/iris/iris_probe.c      |   3 +
 drivers/media/platform/qcom/iris/iris_vidc.c       | 147 +++++++++++++++++=
++++
 drivers/media/platform/qcom/iris/iris_vidc.h       |  15 +++
 13 files changed, 264 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/qcom/iris/Kconfig b/drivers/media/platf=
orm/qcom/iris/Kconfig
index 34a2f81c5db3..8debddec87a5 100644
--- a/drivers/media/platform/qcom/iris/Kconfig
+++ b/drivers/media/platform/qcom/iris/Kconfig
@@ -2,6 +2,7 @@ config VIDEO_QCOM_IRIS
         tristate "Qualcomm iris V4L2 decoder driver"
         depends on VIDEO_DEV
         depends on ARCH_QCOM || COMPILE_TEST
+        select V4L2_MEM2MEM_DEV
         help
           This is a V4L2 driver for Qualcomm iris video accelerator
           hardware. It accelerates decoding operations on various
diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/plat=
form/qcom/iris/Makefile
index 7e701361492e..6de584090a3a 100644
--- a/drivers/media/platform/qcom/iris/Makefile
+++ b/drivers/media/platform/qcom/iris/Makefile
@@ -1,4 +1,7 @@
-iris-objs +=3D iris_platform_sm8550.o \
+iris-objs +=3D iris_hfi_gen1_command.o \
+             iris_hfi_gen2_command.o \
+             iris_platform_sm8550.o \
              iris_probe.o \
+             iris_vidc.o \
=20
 obj-$(CONFIG_VIDEO_QCOM_IRIS) +=3D iris.o
diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/p=
latform/qcom/iris/iris_core.h
index 27bc2ca71e1b..aebb4eba7e15 100644
--- a/drivers/media/platform/qcom/iris/iris_core.h
+++ b/drivers/media/platform/qcom/iris/iris_core.h
@@ -25,6 +25,7 @@ struct icc_info {
  * @irq: iris irq
  * @v4l2_dev: a holder for v4l2 device structure
  * @vdev_dec: iris video device structure for decoder
+ * @iris_v4l2_file_ops: iris v4l2 file ops
  * @icc_tbl: table of iris interconnects
  * @icc_count: count of iris interconnects
  * @pmdomain_tbl: table of iris power domains
@@ -41,6 +42,7 @@ struct iris_core {
 	int					irq;
 	struct v4l2_device			v4l2_dev;
 	struct video_device			*vdev_dec;
+	const struct v4l2_file_operations	*iris_v4l2_file_ops;
 	struct icc_bulk_data			*icc_tbl;
 	u32					icc_count;
 	struct dev_pm_domain_list		*pmdomain_tbl;
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1.h b/drivers/med=
ia/platform/qcom/iris/iris_hfi_gen1.h
new file mode 100644
index 000000000000..5d05be7470e0
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#ifndef __IRIS_HFI_GEN1_H__
+#define __IRIS_HFI_GEN1_H__
+
+struct iris_inst;
+
+struct iris_inst *iris_hfi_gen1_get_instance(void);
+
+#endif
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen1_command.c
new file mode 100644
index 000000000000..20c68f4ffb72
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#include "iris_hfi_gen1.h"
+#include "iris_instance.h"
+
+struct iris_inst *iris_hfi_gen1_get_instance(void)
+{
+	return kzalloc(sizeof(struct iris_inst), GFP_KERNEL);
+}
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h b/drivers/med=
ia/platform/qcom/iris/iris_hfi_gen2.h
new file mode 100644
index 000000000000..c159ed7f64f9
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#ifndef __IRIS_HFI_GEN2_H__
+#define __IRIS_HFI_GEN2_H__
+
+#include "iris_instance.h"
+
+/**
+ * struct iris_inst_hfi_gen2 - holds per video instance parameters for hfi=
_gen2
+ *
+ * @inst: pointer to iris_instance structure
+ */
+struct iris_inst_hfi_gen2 {
+	struct iris_inst		inst;
+};
+
+struct iris_inst *iris_hfi_gen2_get_instance(void);
+
+#endif
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen2_command.c
new file mode 100644
index 000000000000..3ee33c8befae
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#include "iris_hfi_gen2.h"
+
+struct iris_inst *iris_hfi_gen2_get_instance(void)
+{
+	return kzalloc(sizeof(struct iris_inst_hfi_gen2), GFP_KERNEL);
+}
diff --git a/drivers/media/platform/qcom/iris/iris_instance.h b/drivers/med=
ia/platform/qcom/iris/iris_instance.h
new file mode 100644
index 000000000000..527a270f12d4
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_instance.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#ifndef __IRIS_INSTANCE_H__
+#define __IRIS_INSTANCE_H__
+
+#include "iris_core.h"
+
+/**
+ * struct iris_inst - holds per video instance parameters
+ *
+ * @core: pointer to core structure
+ * @ctx_q_lock: lock to serialize queues related ioctls
+ * @lock: lock to seralise forward and reverse threads
+ * @fh: reference of v4l2 file handler
+ * @m2m_dev:	a reference to m2m device structure
+ * @m2m_ctx:	a reference to m2m context structure
+ */
+
+struct iris_inst {
+	struct iris_core		*core;
+	struct mutex			ctx_q_lock;/* lock to serialize queues related ioctls */
+	struct mutex			lock; /* lock to serialize forward and reverse threads */
+	struct v4l2_fh			fh;
+	struct v4l2_m2m_dev		*m2m_dev;
+	struct v4l2_m2m_ctx		*m2m_ctx;
+};
+
+#endif
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/driv=
ers/media/platform/qcom/iris/iris_platform_common.h
index 31c53dad8136..f82081ea135f 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -20,6 +20,7 @@ struct platform_clk_data {
 };
=20
 struct iris_platform_data {
+	struct iris_inst *(*get_instance)(void);
 	const struct icc_info *icc_tbl;
 	unsigned int icc_tbl_size;
 	const char * const *pmdomain_tbl;
diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/driv=
ers/media/platform/qcom/iris/iris_platform_sm8550.c
index 3dd91523d783..dba8d3c22ce5 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
@@ -4,6 +4,7 @@
  */
=20
 #include "iris_core.h"
+#include "iris_hfi_gen2.h"
 #include "iris_platform_common.h"
=20
 static const struct icc_info sm8550_icc_table[] =3D {
@@ -24,6 +25,7 @@ static const struct platform_clk_data sm8550_clk_table[] =
=3D {
 };
=20
 struct iris_platform_data sm8550_data =3D {
+	.get_instance =3D iris_hfi_gen2_get_instance,
 	.icc_tbl =3D sm8550_icc_table,
 	.icc_tbl_size =3D ARRAY_SIZE(sm8550_icc_table),
 	.clk_rst_tbl =3D sm8550_clk_reset_table,
diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/=
platform/qcom/iris/iris_probe.c
index 911e3bc1b434..ce16d894c809 100644
--- a/drivers/media/platform/qcom/iris/iris_probe.c
+++ b/drivers/media/platform/qcom/iris/iris_probe.c
@@ -11,6 +11,7 @@
 #include <linux/reset.h>
=20
 #include "iris_core.h"
+#include "iris_vidc.h"
=20
 static int iris_init_icc(struct iris_core *core)
 {
@@ -139,6 +140,7 @@ static int iris_register_video_device(struct iris_core =
*core)
=20
 	strscpy(vdev->name, "qcom-iris-decoder", sizeof(vdev->name));
 	vdev->release =3D video_device_release;
+	vdev->fops =3D core->iris_v4l2_file_ops;
 	vdev->vfl_dir =3D VFL_DIR_M2M;
 	vdev->v4l2_dev =3D &core->v4l2_dev;
 	vdev->device_caps =3D V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
@@ -192,6 +194,7 @@ static int iris_probe(struct platform_device *pdev)
=20
 	core->iris_platform_data =3D of_device_get_match_data(core->dev);
=20
+	iris_init_ops(core);
 	ret =3D iris_init_resources(core);
 	if (ret)
 		return ret;
diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/p=
latform/qcom/iris/iris_vidc.c
new file mode 100644
index 000000000000..e91d661c6280
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_vidc.c
@@ -0,0 +1,147 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-mem2mem.h>
+
+#include "iris_vidc.h"
+#include "iris_instance.h"
+#include "iris_platform_common.h"
+
+#define IRIS_DRV_NAME "iris_driver"
+#define IRIS_BUS_NAME "platform:iris_icc"
+#define STEP_WIDTH 1
+#define STEP_HEIGHT 1
+
+static void iris_v4l2_fh_init(struct iris_inst *inst)
+{
+	v4l2_fh_init(&inst->fh, inst->core->vdev_dec);
+	v4l2_fh_add(&inst->fh);
+}
+
+static void iris_v4l2_fh_deinit(struct iris_inst *inst)
+{
+	v4l2_fh_del(&inst->fh);
+	v4l2_fh_exit(&inst->fh);
+}
+
+static inline struct iris_inst *iris_get_inst(struct file *filp, void *fh)
+{
+	return container_of(filp->private_data, struct iris_inst, fh);
+}
+
+static void iris_m2m_device_run(void *priv)
+{
+}
+
+static void iris_m2m_job_abort(void *priv)
+{
+	struct iris_inst *inst =3D priv;
+	struct v4l2_m2m_ctx *m2m_ctx =3D inst->m2m_ctx;
+
+	v4l2_m2m_job_finish(inst->m2m_dev, m2m_ctx);
+}
+
+static const struct v4l2_m2m_ops iris_m2m_ops =3D {
+	.device_run =3D iris_m2m_device_run,
+	.job_abort =3D iris_m2m_job_abort,
+};
+
+static int
+iris_m2m_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue=
 *dst_vq)
+{
+	struct iris_inst *inst =3D priv;
+	int ret;
+
+	src_vq->type =3D V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+	src_vq->io_modes =3D VB2_MMAP | VB2_DMABUF;
+	src_vq->timestamp_flags =3D V4L2_BUF_FLAG_TIMESTAMP_COPY;
+	src_vq->drv_priv =3D inst;
+	src_vq->dev =3D inst->core->dev;
+	src_vq->lock =3D &inst->ctx_q_lock;
+	ret =3D vb2_queue_init(src_vq);
+	if (ret)
+		return ret;
+
+	dst_vq->type =3D V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+	dst_vq->io_modes =3D VB2_MMAP | VB2_DMABUF;
+	dst_vq->timestamp_flags =3D V4L2_BUF_FLAG_TIMESTAMP_COPY;
+	dst_vq->drv_priv =3D inst;
+	dst_vq->dev =3D inst->core->dev;
+	dst_vq->lock =3D &inst->ctx_q_lock;
+
+	return vb2_queue_init(dst_vq);
+}
+
+int iris_open(struct file *filp)
+{
+	struct iris_core *core =3D video_drvdata(filp);
+	struct iris_inst *inst;
+	int ret;
+
+	inst =3D core->iris_platform_data->get_instance();
+	if (!inst)
+		return -ENOMEM;
+
+	inst->core =3D core;
+
+	mutex_init(&inst->ctx_q_lock);
+
+	iris_v4l2_fh_init(inst);
+
+	inst->m2m_dev =3D v4l2_m2m_init(&iris_m2m_ops);
+	if (IS_ERR_OR_NULL(inst->m2m_dev)) {
+		ret =3D -EINVAL;
+		goto fail_v4l2_fh_deinit;
+	}
+
+	inst->m2m_ctx =3D v4l2_m2m_ctx_init(inst->m2m_dev, inst, iris_m2m_queue_i=
nit);
+	if (IS_ERR_OR_NULL(inst->m2m_ctx)) {
+		ret =3D -EINVAL;
+		goto fail_m2m_release;
+	}
+
+	inst->fh.m2m_ctx =3D inst->m2m_ctx;
+	filp->private_data =3D &inst->fh;
+
+	return 0;
+
+fail_m2m_release:
+	v4l2_m2m_release(inst->m2m_dev);
+fail_v4l2_fh_deinit:
+	iris_v4l2_fh_deinit(inst);
+	mutex_destroy(&inst->ctx_q_lock);
+	kfree(inst);
+
+	return ret;
+}
+
+int iris_close(struct file *filp)
+{
+	struct iris_inst *inst =3D iris_get_inst(filp, NULL);
+
+	v4l2_m2m_ctx_release(inst->m2m_ctx);
+	v4l2_m2m_release(inst->m2m_dev);
+	iris_v4l2_fh_deinit(inst);
+	mutex_destroy(&inst->ctx_q_lock);
+	kfree(inst);
+	filp->private_data =3D NULL;
+
+	return 0;
+}
+
+static struct v4l2_file_operations iris_v4l2_file_ops =3D {
+	.owner                          =3D THIS_MODULE,
+	.open                           =3D iris_open,
+	.release                        =3D iris_close,
+	.unlocked_ioctl                 =3D video_ioctl2,
+	.poll                           =3D v4l2_m2m_fop_poll,
+	.mmap                           =3D v4l2_m2m_fop_mmap,
+};
+
+void iris_init_ops(struct iris_core *core)
+{
+	core->iris_v4l2_file_ops =3D &iris_v4l2_file_ops;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_vidc.h b/drivers/media/p=
latform/qcom/iris/iris_vidc.h
new file mode 100644
index 000000000000..a26054ff55b5
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_vidc.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#ifndef __IRIS_VIDC_H__
+#define __IRIS_VIDC_H__
+
+struct iris_core;
+
+void iris_init_ops(struct iris_core *core);
+int iris_open(struct file *filp);
+int iris_close(struct file *filp);
+
+#endif

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 98713236456;
	Fri,  7 Feb 2025 07:55: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=1738914944; cv=none;
 b=lxBk8vzLyb2u8mFjLydgaINuTJQ/R7/M0njs+ikbIUIKEpVQIPd/cD8JjTMdZnz/Xy/6oBsty1uyvXaD57cxyKVvQdHvUZRjldoCFogkmhXpa4rVcqLjxOkMDMM+pYdbEqOyditXjdAaTGIBf5k9wTKqipWPJUC41Tw3fmpRRCQ=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738914944; c=relaxed/simple;
	bh=LNhXMHlIedY5n+vW5w0CKNGgyGuvIrYKaqldPrxQYJ0=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=NZFNVylgeuo97FfxAXKhiXopDWMHf4qGdc+K97GJ9XoIVEpja0EiT0EFudvO5cH0QMx+1dzEq7MEApZce+YjZGjJgJ0WnQISzS2wrHlnB7ufoYgCnmJZOwsQGyh8gBiVg2s9JkeZuEd6kDdWdVfA5tHxEacx0Ojz5VLN8hDUZN4=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=opHwqrCB; arc=none smtp.client-ip=205.220.168.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="opHwqrCB"
Received: from pps.filterd (m0279865.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 51770gbk010561;
	Fri, 7 Feb 2025 07:55:27 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	ttaaZpHrPqQ5zCD2hOoeUH1LpXgISX0fblr7xRmN3AM=; b=opHwqrCBYz+Ua+3S
	m2t/GdZxr7TfszlxmYXTKi9fM7Rh05hriBLCCXnFNCPDBUBULHHTk+pSmtEWxb7o
	7R/AM6etRll8rR6VU3wUmDVJpJQF8E9WAu2Lw9e2boWEKF4pHbpaa3feN8e+P58W
	bGXw6azrLqFxtKtQ/FDTo0hZTXOyC5UXOiDqp9VKVeMFC+GvfEG9L4h691fWYW+y
	rOAFsxj2/nLiG3ByhsIDoTNd5PwwDuIbKkTviwMwf6p0CfLTj5qLfI84lCrYstLn
	6+f6I7TE6GnBc5fzAjyuwNbYBFzO0btptH64JGPYKGmye5IMstKYgxMzrCXpKDgH
	XX3WQg==
Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44nddkg4au-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:55:27 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA05.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177tQBg026306
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:55:26 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:55:20 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:24:44 +0530
Subject: [PATCH v10 04/28] media: iris: introduce iris core state
 management with shared queues
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-4-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914892; l=21441;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=LNhXMHlIedY5n+vW5w0CKNGgyGuvIrYKaqldPrxQYJ0=;
 b=X/kYir5ki8b2sV1eHIyqBb6CVgUQmzir+1sNClVDubYJoSvv2LdEyeafr9OkiH0dpjXssfQYZ
 qOZdGMWZ6D6Cr4iXnPClgOCRTLp6qA91P/vtULjP2Jsv2G5mzwVI4uB
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-GUID: w72K6mH__gIPn6Og_T8R1JoQnnOpkEl6
X-Proofpoint-ORIG-GUID: w72K6mH__gIPn6Og_T8R1JoQnnOpkEl6
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 bulkscore=0
 lowpriorityscore=0 mlxlogscore=999 priorityscore=1501 impostorscore=0
 suspectscore=0 clxscore=1015 malwarescore=0 mlxscore=0 spamscore=0
 adultscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070060

Introduce a core state management for iris driver with the necessary
queues needed for the host firmware communication.

There are 3 types of queues:
Command queue - driver to write any command to firmware.
Message queue - firmware to send any response to the driver.
Debug queue - for the firmware to write debug messages.
Initialize and configure the shared queues during probe.

Different states for core:
IRIS_CORE_DEINIT - default state.
IRIS_CORE_INIT   - core state with core initialized. FW loaded and HW
                   brought out of reset, shared queues established
                   between host driver and firmware.
IRIS_CORE_ERROR  - error state.
      -----------
           |
           V
       -----------
       | DEINIT  |
       -----------
           ^
          / \
         /   \
        /     \
       /       \
      v         v
 -----------   ----------.
 |  INIT  |-->|  ERROR  |
 -----------   ----------.

Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 drivers/media/platform/qcom/iris/Makefile          |   4 +-
 drivers/media/platform/qcom/iris/iris_core.c       |  46 ++++++
 drivers/media/platform/qcom/iris/iris_core.h       |  23 +++
 drivers/media/platform/qcom/iris/iris_hfi_queue.c  | 127 +++++++++++++++
 drivers/media/platform/qcom/iris/iris_hfi_queue.h  | 177 +++++++++++++++++=
++++
 .../platform/qcom/iris/iris_platform_common.h      |   1 +
 .../platform/qcom/iris/iris_platform_sm8550.c      |   2 +
 drivers/media/platform/qcom/iris/iris_probe.c      |  19 +++
 drivers/media/platform/qcom/iris/iris_state.h      |  41 +++++
 drivers/media/platform/qcom/iris/iris_vidc.c       |   6 +
 10 files changed, 445 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/plat=
form/qcom/iris/Makefile
index 6de584090a3a..93711f108a77 100644
--- a/drivers/media/platform/qcom/iris/Makefile
+++ b/drivers/media/platform/qcom/iris/Makefile
@@ -1,5 +1,7 @@
-iris-objs +=3D iris_hfi_gen1_command.o \
+iris-objs +=3D iris_core.o \
+             iris_hfi_gen1_command.o \
              iris_hfi_gen2_command.o \
+             iris_hfi_queue.o \
              iris_platform_sm8550.o \
              iris_probe.o \
              iris_vidc.o \
diff --git a/drivers/media/platform/qcom/iris/iris_core.c b/drivers/media/p=
latform/qcom/iris/iris_core.c
new file mode 100644
index 000000000000..360a54909ef6
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_core.c
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#include "iris_core.h"
+#include "iris_state.h"
+
+void iris_core_deinit(struct iris_core *core)
+{
+	mutex_lock(&core->lock);
+	iris_hfi_queues_deinit(core);
+	core->state =3D IRIS_CORE_DEINIT;
+	mutex_unlock(&core->lock);
+}
+
+int iris_core_init(struct iris_core *core)
+{
+	int ret;
+
+	mutex_lock(&core->lock);
+	if (core->state =3D=3D IRIS_CORE_INIT) {
+		ret =3D 0;
+		goto exit;
+	} else if (core->state =3D=3D IRIS_CORE_ERROR) {
+		ret =3D -EINVAL;
+		goto error;
+	}
+
+	core->state =3D IRIS_CORE_INIT;
+
+	ret =3D iris_hfi_queues_init(core);
+	if (ret)
+		goto error;
+
+	mutex_unlock(&core->lock);
+
+	return 0;
+
+error:
+	core->state =3D IRIS_CORE_DEINIT;
+exit:
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/p=
latform/qcom/iris/iris_core.h
index aebb4eba7e15..516082aa58c9 100644
--- a/drivers/media/platform/qcom/iris/iris_core.h
+++ b/drivers/media/platform/qcom/iris/iris_core.h
@@ -9,7 +9,9 @@
 #include <linux/types.h>
 #include <media/v4l2-device.h>
=20
+#include "iris_hfi_queue.h"
 #include "iris_platform_common.h"
+#include "iris_state.h"
=20
 struct icc_info {
 	const char		*name;
@@ -34,6 +36,15 @@ struct icc_info {
  * @clk_count: count of iris clocks
  * @resets: table of iris reset clocks
  * @iris_platform_data: a structure for platform data
+ * @state: current state of core
+ * @iface_q_table_daddr: device address for interface queue table memory
+ * @sfr_daddr: device address for SFR (Sub System Failure Reason) register=
 memory
+ * @iface_q_table_vaddr: virtual address for interface queue table memory
+ * @sfr_vaddr: virtual address for SFR (Sub System Failure Reason) registe=
r memory
+ * @command_queue: shared interface queue to send commands to firmware
+ * @message_queue: shared interface queue to receive responses from firmwa=
re
+ * @debug_queue: shared interface queue to receive debug info from firmware
+ * @lock: a lock for this strucure
  */
=20
 struct iris_core {
@@ -51,6 +62,18 @@ struct iris_core {
 	u32					clk_count;
 	struct reset_control_bulk_data		*resets;
 	const struct iris_platform_data		*iris_platform_data;
+	enum iris_core_state			state;
+	dma_addr_t				iface_q_table_daddr;
+	dma_addr_t				sfr_daddr;
+	void					*iface_q_table_vaddr;
+	void					*sfr_vaddr;
+	struct iris_iface_q_info		command_queue;
+	struct iris_iface_q_info		message_queue;
+	struct iris_iface_q_info		debug_queue;
+	struct mutex				lock; /* lock for core related operations */
 };
=20
+int iris_core_init(struct iris_core *core);
+void iris_core_deinit(struct iris_core *core);
+
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_queue.c b/drivers/me=
dia/platform/qcom/iris/iris_hfi_queue.c
new file mode 100644
index 000000000000..494ef205133d
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_hfi_queue.c
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#include "iris_core.h"
+#include "iris_hfi_queue.h"
+
+static void iris_hfi_queue_set_header(struct iris_core *core, u32 queue_id,
+				      struct iris_iface_q_info *iface_q)
+{
+	iface_q->qhdr->status =3D 0x1;
+	iface_q->qhdr->start_addr =3D iface_q->device_addr;
+	iface_q->qhdr->header_type =3D IFACEQ_DFLT_QHDR;
+	iface_q->qhdr->queue_type =3D queue_id;
+	iface_q->qhdr->q_size =3D IFACEQ_QUEUE_SIZE / sizeof(u32);
+	iface_q->qhdr->pkt_size =3D 0; /* variable packet size */
+	iface_q->qhdr->rx_wm =3D 0x1;
+	iface_q->qhdr->tx_wm =3D 0x1;
+	iface_q->qhdr->rx_req =3D 0x1;
+	iface_q->qhdr->tx_req =3D 0x0;
+	iface_q->qhdr->rx_irq_status =3D 0x0;
+	iface_q->qhdr->tx_irq_status =3D 0x0;
+	iface_q->qhdr->read_idx =3D 0x0;
+	iface_q->qhdr->write_idx =3D 0x0;
+
+	/*
+	 * Set receive request to zero on debug queue as there is no
+	 * need of interrupt from video hardware for debug messages
+	 */
+	if (queue_id =3D=3D IFACEQ_DBGQ_ID)
+		iface_q->qhdr->rx_req =3D 0;
+}
+
+static void
+iris_hfi_queue_init(struct iris_core *core, u32 queue_id, struct iris_ifac=
e_q_info *iface_q)
+{
+	struct iris_hfi_queue_table_header *q_tbl_hdr =3D core->iface_q_table_vad=
dr;
+	u32 offset =3D sizeof(*q_tbl_hdr) + (queue_id * IFACEQ_QUEUE_SIZE);
+
+	iface_q->device_addr =3D core->iface_q_table_daddr + offset;
+	iface_q->kernel_vaddr =3D
+			(void *)((char *)core->iface_q_table_vaddr + offset);
+	iface_q->qhdr =3D &q_tbl_hdr->q_hdr[queue_id];
+
+	iris_hfi_queue_set_header(core, queue_id, iface_q);
+}
+
+static void iris_hfi_queue_deinit(struct iris_iface_q_info *iface_q)
+{
+	iface_q->qhdr =3D NULL;
+	iface_q->kernel_vaddr =3D NULL;
+	iface_q->device_addr =3D 0;
+}
+
+int iris_hfi_queues_init(struct iris_core *core)
+{
+	struct iris_hfi_queue_table_header *q_tbl_hdr;
+	u32 queue_size;
+
+	/* Iris hardware requires 4K queue alignment */
+	queue_size =3D ALIGN((sizeof(*q_tbl_hdr) + (IFACEQ_QUEUE_SIZE * IFACEQ_NU=
MQ)), SZ_4K);
+	core->iface_q_table_vaddr =3D dma_alloc_attrs(core->dev, queue_size,
+						    &core->iface_q_table_daddr,
+						    GFP_KERNEL, DMA_ATTR_WRITE_COMBINE);
+	if (!core->iface_q_table_vaddr) {
+		dev_err(core->dev, "queues alloc and map failed\n");
+		return -ENOMEM;
+	}
+
+	core->sfr_vaddr =3D dma_alloc_attrs(core->dev, SFR_SIZE,
+					  &core->sfr_daddr,
+					  GFP_KERNEL, DMA_ATTR_WRITE_COMBINE);
+	if (!core->sfr_vaddr) {
+		dev_err(core->dev, "sfr alloc and map failed\n");
+		dma_free_attrs(core->dev, sizeof(*q_tbl_hdr), core->iface_q_table_vaddr,
+			       core->iface_q_table_daddr, DMA_ATTR_WRITE_COMBINE);
+		return -ENOMEM;
+	}
+
+	iris_hfi_queue_init(core, IFACEQ_CMDQ_ID, &core->command_queue);
+	iris_hfi_queue_init(core, IFACEQ_MSGQ_ID, &core->message_queue);
+	iris_hfi_queue_init(core, IFACEQ_DBGQ_ID, &core->debug_queue);
+
+	q_tbl_hdr =3D (struct iris_hfi_queue_table_header *)core->iface_q_table_v=
addr;
+	q_tbl_hdr->version =3D 0;
+	q_tbl_hdr->device_addr =3D (void *)core;
+	strscpy(q_tbl_hdr->name, "iris-hfi-queues", sizeof(q_tbl_hdr->name));
+	q_tbl_hdr->size =3D sizeof(*q_tbl_hdr);
+	q_tbl_hdr->qhdr0_offset =3D sizeof(*q_tbl_hdr) -
+		(IFACEQ_NUMQ * sizeof(struct iris_hfi_queue_header));
+	q_tbl_hdr->qhdr_size =3D sizeof(q_tbl_hdr->q_hdr[0]);
+	q_tbl_hdr->num_q =3D IFACEQ_NUMQ;
+	q_tbl_hdr->num_active_q =3D IFACEQ_NUMQ;
+
+	 /* Write sfr size in first word to be used by firmware */
+	*((u32 *)core->sfr_vaddr) =3D SFR_SIZE;
+
+	return 0;
+}
+
+void iris_hfi_queues_deinit(struct iris_core *core)
+{
+	u32 queue_size;
+
+	if (!core->iface_q_table_vaddr)
+		return;
+
+	iris_hfi_queue_deinit(&core->debug_queue);
+	iris_hfi_queue_deinit(&core->message_queue);
+	iris_hfi_queue_deinit(&core->command_queue);
+
+	dma_free_attrs(core->dev, SFR_SIZE, core->sfr_vaddr,
+		       core->sfr_daddr, DMA_ATTR_WRITE_COMBINE);
+
+	core->sfr_vaddr =3D NULL;
+	core->sfr_daddr =3D 0;
+
+	queue_size =3D ALIGN(sizeof(struct iris_hfi_queue_table_header) +
+		(IFACEQ_QUEUE_SIZE * IFACEQ_NUMQ), SZ_4K);
+
+	dma_free_attrs(core->dev, queue_size, core->iface_q_table_vaddr,
+		       core->iface_q_table_daddr, DMA_ATTR_WRITE_COMBINE);
+
+	core->iface_q_table_vaddr =3D NULL;
+	core->iface_q_table_daddr =3D 0;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_queue.h b/drivers/me=
dia/platform/qcom/iris/iris_hfi_queue.h
new file mode 100644
index 000000000000..99a3b83d063f
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_hfi_queue.h
@@ -0,0 +1,177 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#ifndef __IRIS_HFI_QUEUE_H__
+#define __IRIS_HFI_QUEUE_H__
+
+struct iris_core;
+
+/*
+ * Max 64 Buffers ( 32 input buffers and 32 output buffers)
+ * can be queued by v4l2 framework at any given time.
+ */
+#define IFACEQ_MAX_BUF_COUNT		64
+/*
+ * Max session supported are 16.
+ * this value is used to calcualte the size of
+ * individual shared queue.
+ */
+#define IFACE_MAX_PARALLEL_SESSIONS	16
+#define IFACEQ_DFLT_QHDR		0x0101
+#define IFACEQ_MAX_PKT_SIZE		1024 /* Maximum size of a packet in the queue=
 */
+
+/*
+ * SFR: Subsystem Failure Reason
+ * when hardware goes into bad state/failure, firmware fills this memory
+ * and driver will get to know the actual failure reason from this SFR buf=
fer.
+ */
+#define SFR_SIZE			SZ_4K /* Iris hardware requires 4K queue alignment */
+
+#define IFACEQ_QUEUE_SIZE		(IFACEQ_MAX_PKT_SIZE * \
+					 IFACEQ_MAX_BUF_COUNT * IFACE_MAX_PARALLEL_SESSIONS)
+
+/*
+ * Memory layout of the shared queues:
+ *
+ *   ||=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D||  ^        ^  =
       ^
+ *   ||                 ||  |        |         |
+ *   ||    Queue Table  || 288 Bytes |         |
+ *   ||      Header     ||  |        |         |
+ *   ||                 ||  |        |         |
+ *   ||-----------------||  V        |         |
+ *   ||-----------------||  ^        |         |
+ *   ||                 ||  |        |         |
+ *   ||  Command Queue  || 56 Bytes  |         |
+ *   ||     Header      ||  |        |         |
+ *   ||                 ||  |        |         |
+ *   ||-----------------||  V       456 Bytes  |
+ *   ||-----------------||  ^        |         |
+ *   ||                 ||  |        |         |
+ *   ||  Message Queue  || 56 Bytes  |         |
+ *   ||     Header      ||  |        |         |
+ *   ||                 ||  |        |         |
+ *   ||-----------------||  V        |         Buffer size aligned to 4k
+ *   ||-----------------||  ^        |         Overall Queue Size =3D 2,40=
4 KB
+ *   ||                 ||  |        |         |
+ *   ||   Debug Queue   || 56 Bytes  |         |
+ *   ||     Header      ||  |        |         |
+ *   ||                 ||  |        |         |
+ *   ||=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D||  V        V  =
       |
+ *   ||=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D||           ^  =
       |
+ *   ||                 ||           |         |
+ *   ||     Command     ||         800 KB      |
+ *   ||      Queue      ||           |         |
+ *   ||                 ||           |         |
+ *   ||=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D||           V  =
       |
+ *   ||=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D||           ^  =
       |
+ *   ||                 ||           |         |
+ *   ||     Message     ||         800 KB      |
+ *   ||      Queue      ||           |         |
+ *   ||                 ||           |         |
+ *   ||=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D||           V  =
       |
+ *   ||=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D||           ^  =
       |
+ *   ||                 ||           |         |
+ *   ||      Debug      ||         800 KB      |
+ *   ||      Queue      ||           |         |
+ *   ||                 ||           |         |
+ *   ||=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D||           V  =
       |
+ *   ||                 ||                     |
+ *   ||=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D||              =
       V
+ */
+
+/*
+ * Shared queues are used for communication between driver and firmware.
+ * There are 3 types of queues:
+ * Command queue - driver to write any command to firmware.
+ * Message queue - firmware to send any response to driver.
+ * Debug queue - firmware to write debug message.
+ */
+
+/* Host-firmware shared queue ids */
+enum iris_iface_queue {
+	IFACEQ_CMDQ_ID,
+	IFACEQ_MSGQ_ID,
+	IFACEQ_DBGQ_ID,
+	IFACEQ_NUMQ, /* not an index */
+};
+
+/**
+ * struct iris_hfi_queue_header
+ *
+ * @status: Queue status, bits (7:0), 0x1 - active, 0x0 - inactive
+ * @start_addr: Queue start address in non cached memory
+ * @queue_type: Queue ID
+ * @header_type: Default queue header
+ * @q_size: Queue size
+ *		Number of queue packets if pkt_size is non-zero
+ *		Queue size in bytes if pkt_size is zero
+ * @pkt_size: Size of queue packet entries
+ *		0x0: variable queue packet size
+ *		non zero: size of queue packet entry, fixed
+ * @pkt_drop_cnt: Number of packets dropped by sender
+ * @rx_wm: Receiver watermark, applicable in event driven mode
+ * @tx_wm: Sender watermark, applicable in event driven mode
+ * @rx_req: Receiver sets this bit if queue is empty
+ * @tx_req: Sender sets this bit if queue is full
+ * @rx_irq_status: Receiver sets this bit and triggers an interrupt to
+ *		the sender after packets are dequeued. Sender clears this bit
+ * @tx_irq_status: Sender sets this bit and triggers an interrupt to
+ *		the receiver after packets are queued. Receiver clears this bit
+ * @read_idx: Index till where receiver has consumed the packets from the =
queue.
+ * @write_idx: Index till where sender has written the packets into the qu=
eue.
+ */
+struct iris_hfi_queue_header {
+	u32 status;
+	u32 start_addr;
+	u16 queue_type;
+	u16 header_type;
+	u32 q_size;
+	u32 pkt_size;
+	u32 pkt_drop_cnt;
+	u32 rx_wm;
+	u32 tx_wm;
+	u32 rx_req;
+	u32 tx_req;
+	u32 rx_irq_status;
+	u32 tx_irq_status;
+	u32 read_idx;
+	u32 write_idx;
+};
+
+/**
+ * struct iris_hfi_queue_table_header
+ *
+ * @version: Queue table version number
+ * @size: Queue table size from version to last parametr in qhdr entry
+ * @qhdr0_offset: Offset to the start of first qhdr
+ * @qhdr_size: Queue header size in bytes
+ * @num_q: Total number of queues in Queue table
+ * @num_active_q: Total number of active queues
+ * @device_addr: Device address of the queue
+ * @name: Queue name in characters
+ * @q_hdr: Array of queue headers
+ */
+struct iris_hfi_queue_table_header {
+	u32 version;
+	u32 size;
+	u32 qhdr0_offset;
+	u32 qhdr_size;
+	u32 num_q;
+	u32 num_active_q;
+	void *device_addr;
+	char name[256]; /* NUL-terminated array of characters */
+	struct iris_hfi_queue_header q_hdr[IFACEQ_NUMQ];
+};
+
+struct iris_iface_q_info {
+	struct iris_hfi_queue_header *qhdr;
+	dma_addr_t	device_addr;
+	void		*kernel_vaddr;
+};
+
+int iris_hfi_queues_init(struct iris_core *core);
+void iris_hfi_queues_deinit(struct iris_core *core);
+
+#endif
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/driv=
ers/media/platform/qcom/iris/iris_platform_common.h
index f82081ea135f..b4d63d6677c5 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -31,6 +31,7 @@ struct iris_platform_data {
 	unsigned int clk_tbl_size;
 	const char * const *clk_rst_tbl;
 	unsigned int clk_rst_tbl_size;
+	u64 dma_mask;
 };
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/driv=
ers/media/platform/qcom/iris/iris_platform_sm8550.c
index dba8d3c22ce5..ddaa4991d645 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
@@ -36,4 +36,6 @@ struct iris_platform_data sm8550_data =3D {
 	.opp_pd_tbl_size =3D ARRAY_SIZE(sm8550_opp_pd_table),
 	.clk_tbl =3D sm8550_clk_table,
 	.clk_tbl_size =3D ARRAY_SIZE(sm8550_clk_table),
+	/* Upper bound of DMA address range */
+	.dma_mask =3D 0xe0000000 - 1,
 };
diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/=
platform/qcom/iris/iris_probe.c
index ce16d894c809..3015e6cb347f 100644
--- a/drivers/media/platform/qcom/iris/iris_probe.c
+++ b/drivers/media/platform/qcom/iris/iris_probe.c
@@ -168,15 +168,20 @@ static void iris_remove(struct platform_device *pdev)
 	if (!core)
 		return;
=20
+	iris_core_deinit(core);
+
 	video_unregister_device(core->vdev_dec);
=20
 	v4l2_device_unregister(&core->v4l2_dev);
+
+	mutex_destroy(&core->lock);
 }
=20
 static int iris_probe(struct platform_device *pdev)
 {
 	struct device *dev =3D &pdev->dev;
 	struct iris_core *core;
+	u64 dma_mask;
 	int ret;
=20
 	core =3D devm_kzalloc(&pdev->dev, sizeof(*core), GFP_KERNEL);
@@ -184,6 +189,9 @@ static int iris_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	core->dev =3D dev;
=20
+	core->state =3D IRIS_CORE_DEINIT;
+	mutex_init(&core->lock);
+
 	core->reg_base =3D devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(core->reg_base))
 		return PTR_ERR(core->reg_base);
@@ -209,8 +217,19 @@ static int iris_probe(struct platform_device *pdev)
=20
 	platform_set_drvdata(pdev, core);
=20
+	dma_mask =3D core->iris_platform_data->dma_mask;
+
+	ret =3D dma_set_mask_and_coherent(dev, dma_mask);
+	if (ret)
+		goto err_vdev_unreg;
+
+	dma_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
+	dma_set_seg_boundary(&pdev->dev, DMA_BIT_MASK(32));
+
 	return 0;
=20
+err_vdev_unreg:
+	video_unregister_device(core->vdev_dec);
 err_v4l2_unreg:
 	v4l2_device_unregister(&core->v4l2_dev);
=20
diff --git a/drivers/media/platform/qcom/iris/iris_state.h b/drivers/media/=
platform/qcom/iris/iris_state.h
new file mode 100644
index 000000000000..1ffe6fe706bd
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_state.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#ifndef __IRIS_STATE_H__
+#define __IRIS_STATE_H__
+
+/**
+ * enum iris_core_state
+ *
+ * @IRIS_CORE_DEINIT: default state.
+ * @IRIS_CORE_INIT:   core state with core initialized. FW loaded and
+ *                   HW brought out of reset, shared queues established
+ *                   between host driver and firmware.
+ * @IRIS_CORE_ERROR:  error state.
+ *
+ *        -----------
+ *             |
+ *             V
+ *        -----------
+ *   +--->| DEINIT  |<---+
+ *   |   -----------    |
+ *   |         |        |
+ *   |         v        |
+ *   |   -----------    |
+ *   |     /     \      |
+ *   |    /       \     |
+ *   |   /         \    |
+ *   |  v           v   v
+ * -----------    -----------
+ * |  INIT  |--->|  ERROR  |
+ * -----------    -----------
+ */
+enum iris_core_state {
+	IRIS_CORE_DEINIT,
+	IRIS_CORE_INIT,
+	IRIS_CORE_ERROR,
+};
+
+#endif
diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/p=
latform/qcom/iris/iris_vidc.c
index e91d661c6280..5dd0ccbaa2fb 100644
--- a/drivers/media/platform/qcom/iris/iris_vidc.c
+++ b/drivers/media/platform/qcom/iris/iris_vidc.c
@@ -81,6 +81,12 @@ int iris_open(struct file *filp)
 	struct iris_inst *inst;
 	int ret;
=20
+	ret =3D iris_core_init(core);
+	if (ret) {
+		dev_err(core->dev, "core init failed\n");
+		return ret;
+	}
+
 	inst =3D core->iris_platform_data->get_instance();
 	if (!inst)
 		return -ENOMEM;

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 34E8E236A91;
	Fri,  7 Feb 2025 07:55: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=1738914950; cv=none;
 b=Q4BFFPjm9BowkJ3BZ4SOk/IrGVRduyezM+aS7g68zgtMXBBc67eTc4COW1cpbZ0S1/f3arb0fRTZmVdaycT7FrKorsZU0xgrqT+oX/9aSP+pkaKBhiyWbGJpjdcTgdVJv8VJ5ldRfVeTsQmAy53Q7fabxMz9NmTie0BUqKmowOY=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738914950; c=relaxed/simple;
	bh=Q3IR344rHzicV2ctbGfJr24OrmnQ3YaN5D1PUuMrp64=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=HpJbVaQaGIJTRmqeyYcf2/COSAVpfe/oiTfpTC/zXRYPFDcNauWuuJCCC//1KxI0eGaSkeDQ144XLqItHEhDZI7LQD4eEvmg+YD/1uafMQu0q+acKP5AHNBJS2IekH0mTMajxe648Ge3vjFBrn1H/M8uyS5b4JPo4qiPVr7ePec=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=irNVXaLy; arc=none smtp.client-ip=205.220.168.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="irNVXaLy"
Received: from pps.filterd (m0279867.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 51770TA2029983;
	Fri, 7 Feb 2025 07:55:34 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	rR0bjXSfZNG+dtxNOuJfZCs777VVrP8/vOeXMxhiz8E=; b=irNVXaLyc+klnhyP
	zEIaMKXiO2YH+ouuU4960Yg5qzzka8HPdG0JmwMxzF/60hXLEF1tzjNaNfANQdod
	rivIqn0wv9eRZxmlq4D0v+lcgk5krLFYjSd8NPeFyUXrYIGJm1aZCmhDT8thpUz3
	WqMqPUMb+TWi+MJ5YB7BhN0Jgp6gU9yH/6zHJmzdbmXkDOO7kVZqokuADNvfri8z
	Zm95/j4gVbaBshHLEJ8LS/s4/t/qgvd88zvFkQI2h7jMvXGgVYYL3Kx0lAQywyDv
	ouXtFdlWbLizKodPx16IGrINB6/jt9E6YfiEGnZj4lQ+Y7S1YTmFX7xDqmZ7vfuW
	sS3LJg==
Received: from nalasppmta02.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44nddjg441-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:55:34 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA02.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177tXJq029109
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:55:33 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:55:26 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:24:45 +0530
Subject: [PATCH v10 05/28] media: iris: implement video firmware
 load/unload
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-5-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914892; l=8625;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=Q3IR344rHzicV2ctbGfJr24OrmnQ3YaN5D1PUuMrp64=;
 b=+nA8Ue19O6YYXXhJJumTgwXsiBKxa4IpDsBHzraQqFwCFM2b6Weck2fRIhuqBi8EMi2Z76d90
 PutWwwHtEBOBz9F+Obc+iGAO5HJMqQoNUIPwlZuNSjMl1+tDxMeuijS
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-ORIG-GUID: TImiK_FRfOfRF0aDMldzWOBNP-Jm2PaB
X-Proofpoint-GUID: TImiK_FRfOfRF0aDMldzWOBNP-Jm2PaB
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 mlxscore=0 impostorscore=0
 adultscore=0 bulkscore=0 phishscore=0 malwarescore=0 lowpriorityscore=0
 mlxlogscore=999 priorityscore=1501 clxscore=1015 suspectscore=0
 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070060

Load/unload the firmware into/from  memory via the MDT loader.
The firmware is loaded as part of core initialization and unloaded as
part of core de-initialization.

Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 drivers/media/platform/qcom/iris/Kconfig           |   2 +
 drivers/media/platform/qcom/iris/Makefile          |   1 +
 drivers/media/platform/qcom/iris/iris_core.c       |   8 ++
 drivers/media/platform/qcom/iris/iris_firmware.c   | 111 +++++++++++++++++=
++++
 drivers/media/platform/qcom/iris/iris_firmware.h   |  14 +++
 .../platform/qcom/iris/iris_platform_common.h      |  12 +++
 .../platform/qcom/iris/iris_platform_sm8550.c      |  10 ++
 7 files changed, 158 insertions(+)

diff --git a/drivers/media/platform/qcom/iris/Kconfig b/drivers/media/platf=
orm/qcom/iris/Kconfig
index 8debddec87a5..f92cc7fe9378 100644
--- a/drivers/media/platform/qcom/iris/Kconfig
+++ b/drivers/media/platform/qcom/iris/Kconfig
@@ -3,6 +3,8 @@ config VIDEO_QCOM_IRIS
         depends on VIDEO_DEV
         depends on ARCH_QCOM || COMPILE_TEST
         select V4L2_MEM2MEM_DEV
+        select QCOM_MDT_LOADER if ARCH_QCOM
+        select QCOM_SCM
         help
           This is a V4L2 driver for Qualcomm iris video accelerator
           hardware. It accelerates decoding operations on various
diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/plat=
form/qcom/iris/Makefile
index 93711f108a77..6906caa2c481 100644
--- a/drivers/media/platform/qcom/iris/Makefile
+++ b/drivers/media/platform/qcom/iris/Makefile
@@ -1,4 +1,5 @@
 iris-objs +=3D iris_core.o \
+             iris_firmware.o \
              iris_hfi_gen1_command.o \
              iris_hfi_gen2_command.o \
              iris_hfi_queue.o \
diff --git a/drivers/media/platform/qcom/iris/iris_core.c b/drivers/media/p=
latform/qcom/iris/iris_core.c
index 360a54909ef6..8c7d53c57086 100644
--- a/drivers/media/platform/qcom/iris/iris_core.c
+++ b/drivers/media/platform/qcom/iris/iris_core.c
@@ -4,11 +4,13 @@
  */
=20
 #include "iris_core.h"
+#include "iris_firmware.h"
 #include "iris_state.h"
=20
 void iris_core_deinit(struct iris_core *core)
 {
 	mutex_lock(&core->lock);
+	iris_fw_unload(core);
 	iris_hfi_queues_deinit(core);
 	core->state =3D IRIS_CORE_DEINIT;
 	mutex_unlock(&core->lock);
@@ -33,10 +35,16 @@ int iris_core_init(struct iris_core *core)
 	if (ret)
 		goto error;
=20
+	ret =3D iris_fw_load(core);
+	if (ret)
+		goto error_queue_deinit;
+
 	mutex_unlock(&core->lock);
=20
 	return 0;
=20
+error_queue_deinit:
+	iris_hfi_queues_deinit(core);
 error:
 	core->state =3D IRIS_CORE_DEINIT;
 exit:
diff --git a/drivers/media/platform/qcom/iris/iris_firmware.c b/drivers/med=
ia/platform/qcom/iris/iris_firmware.c
new file mode 100644
index 000000000000..3d14e596a471
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_firmware.c
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#include <linux/firmware.h>
+#include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/of_address.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/soc/qcom/mdt_loader.h>
+
+#include "iris_core.h"
+#include "iris_firmware.h"
+
+#define MAX_FIRMWARE_NAME_SIZE	128
+
+static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_n=
ame)
+{
+	u32 pas_id =3D core->iris_platform_data->pas_id;
+	const struct firmware *firmware =3D NULL;
+	struct device *dev =3D core->dev;
+	struct reserved_mem *rmem;
+	struct device_node *node;
+	phys_addr_t mem_phys;
+	size_t res_size;
+	ssize_t fw_size;
+	void *mem_virt;
+	int ret;
+
+	if (strlen(fw_name) >=3D MAX_FIRMWARE_NAME_SIZE - 4)
+		return -EINVAL;
+
+	node =3D of_parse_phandle(dev->of_node, "memory-region", 0);
+	if (!node)
+		return -EINVAL;
+
+	rmem =3D of_reserved_mem_lookup(node);
+	of_node_put(node);
+	if (!rmem)
+		return -EINVAL;
+
+	mem_phys =3D rmem->base;
+	res_size =3D rmem->size;
+
+	ret =3D request_firmware(&firmware, fw_name, dev);
+	if (ret)
+		return ret;
+
+	fw_size =3D qcom_mdt_get_size(firmware);
+	if (fw_size < 0 || res_size < (size_t)fw_size) {
+		ret =3D -EINVAL;
+		goto err_release_fw;
+	}
+
+	mem_virt =3D memremap(mem_phys, res_size, MEMREMAP_WC);
+	if (!mem_virt)
+		goto err_release_fw;
+
+	ret =3D qcom_mdt_load(dev, firmware, fw_name,
+			    pas_id, mem_virt, mem_phys, res_size, NULL);
+	if (ret)
+		goto err_mem_unmap;
+
+	ret =3D qcom_scm_pas_auth_and_reset(pas_id);
+	if (ret)
+		goto err_mem_unmap;
+
+	return ret;
+
+err_mem_unmap:
+	memunmap(mem_virt);
+err_release_fw:
+	release_firmware(firmware);
+
+	return ret;
+}
+
+int iris_fw_load(struct iris_core *core)
+{
+	struct tz_cp_config *cp_config =3D core->iris_platform_data->tz_cp_config=
_data;
+	const char *fwpath =3D NULL;
+	int ret;
+
+	ret =3D of_property_read_string_index(core->dev->of_node, "firmware-name"=
, 0,
+					    &fwpath);
+	if (ret)
+		fwpath =3D core->iris_platform_data->fwname;
+
+	ret =3D iris_load_fw_to_memory(core, fwpath);
+	if (ret) {
+		dev_err(core->dev, "firmware download failed\n");
+		return -ENOMEM;
+	}
+
+	ret =3D qcom_scm_mem_protect_video_var(cp_config->cp_start,
+					     cp_config->cp_size,
+					     cp_config->cp_nonpixel_start,
+					     cp_config->cp_nonpixel_size);
+	if (ret) {
+		dev_err(core->dev, "protect memory failed\n");
+		qcom_scm_pas_shutdown(core->iris_platform_data->pas_id);
+		return ret;
+	}
+
+	return ret;
+}
+
+int iris_fw_unload(struct iris_core *core)
+{
+	return qcom_scm_pas_shutdown(core->iris_platform_data->pas_id);
+}
diff --git a/drivers/media/platform/qcom/iris/iris_firmware.h b/drivers/med=
ia/platform/qcom/iris/iris_firmware.h
new file mode 100644
index 000000000000..266bdd92a124
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_firmware.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#ifndef __IRIS_FIRMWARE_H__
+#define __IRIS_FIRMWARE_H__
+
+struct iris_core;
+
+int iris_fw_load(struct iris_core *core);
+int iris_fw_unload(struct iris_core *core);
+
+#endif
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/driv=
ers/media/platform/qcom/iris/iris_platform_common.h
index b4d63d6677c5..42c1fe8e4fa6 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -6,6 +6,8 @@
 #ifndef __IRIS_PLATFORM_COMMON_H__
 #define __IRIS_PLATFORM_COMMON_H__
=20
+#define IRIS_PAS_ID				9
+
 extern struct iris_platform_data sm8550_data;
=20
 enum platform_clk_type {
@@ -19,6 +21,13 @@ struct platform_clk_data {
 	const char *clk_name;
 };
=20
+struct tz_cp_config {
+	u32 cp_start;
+	u32 cp_size;
+	u32 cp_nonpixel_start;
+	u32 cp_nonpixel_size;
+};
+
 struct iris_platform_data {
 	struct iris_inst *(*get_instance)(void);
 	const struct icc_info *icc_tbl;
@@ -32,6 +41,9 @@ struct iris_platform_data {
 	const char * const *clk_rst_tbl;
 	unsigned int clk_rst_tbl_size;
 	u64 dma_mask;
+	const char *fwname;
+	u32 pas_id;
+	struct tz_cp_config *tz_cp_config_data;
 };
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/driv=
ers/media/platform/qcom/iris/iris_platform_sm8550.c
index ddaa4991d645..bf389181d8cc 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
@@ -24,6 +24,13 @@ static const struct platform_clk_data sm8550_clk_table[]=
 =3D {
 	{IRIS_HW_CLK,   "vcodec0_core" },
 };
=20
+static struct tz_cp_config tz_cp_config_sm8550 =3D {
+	.cp_start =3D 0,
+	.cp_size =3D 0x25800000,
+	.cp_nonpixel_start =3D 0x01000000,
+	.cp_nonpixel_size =3D 0x24800000,
+};
+
 struct iris_platform_data sm8550_data =3D {
 	.get_instance =3D iris_hfi_gen2_get_instance,
 	.icc_tbl =3D sm8550_icc_table,
@@ -38,4 +45,7 @@ struct iris_platform_data sm8550_data =3D {
 	.clk_tbl_size =3D ARRAY_SIZE(sm8550_clk_table),
 	/* Upper bound of DMA address range */
 	.dma_mask =3D 0xe0000000 - 1,
+	.fwname =3D "qcom/vpu/vpu30_p4.mbn",
+	.pas_id =3D IRIS_PAS_ID,
+	.tz_cp_config_data =3D &tz_cp_config_sm8550,
 };

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 7FBF6234973;
	Fri,  7 Feb 2025 07:55:55 +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=1738914957; cv=none;
 b=sFbxy3CV4Mp5xa+RjlLbeTxSGDtmwTHb3eKCDSYHqkc2pAJ7fUWW2v/cF7xDKj18kEkOGQEhkHWZo3LApobLiyfzWKUkjPUiE5wr6r2nvDskst1tT881IlIB1Dvc+7ADyQCLKKP6sjGVoc53xlueY4vHF/r9Xc4YsTUfNvd7mW8=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738914957; c=relaxed/simple;
	bh=ldjW0qfjOMi5Cp3jQPyURy1Yu7ZZqEgUy1MvjdK8llU=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=UKyWga59vQwf1S0/wQyiHxmNNpbUnsBgz1YwBhNOXPjkVQ2RzjwLsrDhmMxGthSMLLJvRgmSvAvynhmcKLE5kc56byHTp5XblEqWbA9ry+wNFtZy63hOnSySRnJKKNB6+079qmvWmEeRxnARZBgZ4t5REbCLcWA+oLWMhNKv8u4=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=M7mxIOhg; arc=none smtp.client-ip=205.220.180.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="M7mxIOhg"
Received: from pps.filterd (m0279869.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 5175HHkh021719;
	Fri, 7 Feb 2025 07:55:41 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	a0aEZxESiQA/pzHlLz+rA8U3LRjJXTCRtaAhVHfxSYM=; b=M7mxIOhgDv4coKum
	j5mrq68s4Ke1ZPt4Jr7AL0KCxYsAX5EWUu8PN5t6tv8WgFtgD0j1tFCLQiHx6M9/
	NlBSnxeynZQGVfbnm2CzBgD21Ee1ZGP6QOWefk70Go/ttQDX7uqK5wxFlVaZ+T6q
	+wWPzyDrFtxllloXcBbNSic1oEL0EjYEpzDGnR00pjK/EEbiFL8LZW81fIDDsp7P
	TX1ydxDc32XDbODLYbiUKIWc9DpPGVOvY0iOhzPLCyi8pHUFNB60chDXeemiqpzL
	4DGzX1cS1tQmfICk0vDOMZN7rb1/Oh5IH+/hEcnSHpbprVLJwcIp6X+Oq1IODP6X
	EpNsrQ==
Received: from nalasppmta01.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44nbvurbtd-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:55:41 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA01.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177teBl008808
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:55:40 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:55:33 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:24:46 +0530
Subject: [PATCH v10 06/28] media: iris: implement the boot sequence of the
 firmware
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-6-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914892; l=6767;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=ldjW0qfjOMi5Cp3jQPyURy1Yu7ZZqEgUy1MvjdK8llU=;
 b=kHnciWWcq1TpePGSdrXEaWn6dfNBA8fJYi1Lrc4/wETDRnMcv8fGaT4a7i1eZbOjZ7cFYWxDh
 xtxGHdNKu3WDttHdsvzKuIbYhezhIDx/I/8+Xlwr0eyagVRE22rtLc/
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-GUID: z5t_STtHTXNpMfJI3REs3bq3GSYwb0v4
X-Proofpoint-ORIG-GUID: z5t_STtHTXNpMfJI3REs3bq3GSYwb0v4
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 phishscore=0
 lowpriorityscore=0 malwarescore=0 adultscore=0 spamscore=0 impostorscore=0
 suspectscore=0 bulkscore=0 priorityscore=1501 clxscore=1015 mlxscore=0
 mlxlogscore=999 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070060

Set the memory region on the firmware and implement the boot sequence.

Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 drivers/media/platform/qcom/iris/Makefile          |  1 +
 drivers/media/platform/qcom/iris/iris_core.c       |  7 ++
 .../platform/qcom/iris/iris_platform_common.h      |  1 +
 .../platform/qcom/iris/iris_platform_sm8550.c      |  3 +
 drivers/media/platform/qcom/iris/iris_vpu_common.c | 89 ++++++++++++++++++=
++++
 drivers/media/platform/qcom/iris/iris_vpu_common.h | 13 ++++
 6 files changed, 114 insertions(+)

diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/plat=
form/qcom/iris/Makefile
index 6906caa2c481..792f1d6ac8f3 100644
--- a/drivers/media/platform/qcom/iris/Makefile
+++ b/drivers/media/platform/qcom/iris/Makefile
@@ -6,5 +6,6 @@ iris-objs +=3D iris_core.o \
              iris_platform_sm8550.o \
              iris_probe.o \
              iris_vidc.o \
+             iris_vpu_common.o \
=20
 obj-$(CONFIG_VIDEO_QCOM_IRIS) +=3D iris.o
diff --git a/drivers/media/platform/qcom/iris/iris_core.c b/drivers/media/p=
latform/qcom/iris/iris_core.c
index 8c7d53c57086..5ad66ac113ae 100644
--- a/drivers/media/platform/qcom/iris/iris_core.c
+++ b/drivers/media/platform/qcom/iris/iris_core.c
@@ -6,6 +6,7 @@
 #include "iris_core.h"
 #include "iris_firmware.h"
 #include "iris_state.h"
+#include "iris_vpu_common.h"
=20
 void iris_core_deinit(struct iris_core *core)
 {
@@ -39,10 +40,16 @@ int iris_core_init(struct iris_core *core)
 	if (ret)
 		goto error_queue_deinit;
=20
+	ret =3D iris_vpu_boot_firmware(core);
+	if (ret)
+		goto error_unload_fw;
+
 	mutex_unlock(&core->lock);
=20
 	return 0;
=20
+error_unload_fw:
+	iris_fw_unload(core);
 error_queue_deinit:
 	iris_hfi_queues_deinit(core);
 error:
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/driv=
ers/media/platform/qcom/iris/iris_platform_common.h
index 42c1fe8e4fa6..7e661e8928bd 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -44,6 +44,7 @@ struct iris_platform_data {
 	const char *fwname;
 	u32 pas_id;
 	struct tz_cp_config *tz_cp_config_data;
+	u32 core_arch;
 };
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/driv=
ers/media/platform/qcom/iris/iris_platform_sm8550.c
index bf389181d8cc..237f932946d6 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
@@ -7,6 +7,8 @@
 #include "iris_hfi_gen2.h"
 #include "iris_platform_common.h"
=20
+#define VIDEO_ARCH_LX 1
+
 static const struct icc_info sm8550_icc_table[] =3D {
 	{ "cpu-cfg",    1000, 1000     },
 	{ "video-mem",  1000, 15000000 },
@@ -48,4 +50,5 @@ struct iris_platform_data sm8550_data =3D {
 	.fwname =3D "qcom/vpu/vpu30_p4.mbn",
 	.pas_id =3D IRIS_PAS_ID,
 	.tz_cp_config_data =3D &tz_cp_config_sm8550,
+	.core_arch =3D VIDEO_ARCH_LX,
 };
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/m=
edia/platform/qcom/iris/iris_vpu_common.c
new file mode 100644
index 000000000000..959ed46e8f47
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#include <linux/iopoll.h>
+
+#include "iris_core.h"
+#include "iris_vpu_common.h"
+
+#define CPU_BASE_OFFS				0x000A0000
+
+#define CPU_CS_BASE_OFFS			(CPU_BASE_OFFS)
+
+#define CTRL_INIT				(CPU_CS_BASE_OFFS + 0x48)
+#define CTRL_STATUS				(CPU_CS_BASE_OFFS + 0x4C)
+
+#define CTRL_ERROR_STATUS__M			0xfe
+
+#define QTBL_INFO				(CPU_CS_BASE_OFFS + 0x50)
+#define QTBL_ENABLE				BIT(0)
+
+#define QTBL_ADDR				(CPU_CS_BASE_OFFS + 0x54)
+#define CPU_CS_SCIACMDARG3			(CPU_CS_BASE_OFFS + 0x58)
+#define SFR_ADDR				(CPU_CS_BASE_OFFS + 0x5C)
+#define UC_REGION_ADDR				(CPU_CS_BASE_OFFS + 0x64)
+#define UC_REGION_SIZE				(CPU_CS_BASE_OFFS + 0x68)
+
+#define CPU_CS_H2XSOFTINTEN			(CPU_CS_BASE_OFFS + 0x148)
+#define HOST2XTENSA_INTR_ENABLE			BIT(0)
+
+#define CPU_CS_X2RPMH				(CPU_CS_BASE_OFFS + 0x168)
+
+static void iris_vpu_setup_ucregion_memory_map(struct iris_core *core)
+{
+	u32 queue_size, value;
+
+	/* Iris hardware requires 4K queue alignment */
+	queue_size =3D ALIGN(sizeof(struct iris_hfi_queue_table_header) +
+		(IFACEQ_QUEUE_SIZE * IFACEQ_NUMQ), SZ_4K);
+
+	value =3D (u32)core->iface_q_table_daddr;
+	writel(value, core->reg_base + UC_REGION_ADDR);
+
+	/* Iris hardware requires 1M queue alignment */
+	value =3D ALIGN(SFR_SIZE + queue_size, SZ_1M);
+	writel(value, core->reg_base + UC_REGION_SIZE);
+
+	value =3D (u32)core->iface_q_table_daddr;
+	writel(value, core->reg_base + QTBL_ADDR);
+
+	writel(QTBL_ENABLE, core->reg_base + QTBL_INFO);
+
+	if (core->sfr_daddr) {
+		value =3D (u32)core->sfr_daddr + core->iris_platform_data->core_arch;
+		writel(value, core->reg_base + SFR_ADDR);
+	}
+}
+
+int iris_vpu_boot_firmware(struct iris_core *core)
+{
+	u32 ctrl_init =3D BIT(0), ctrl_status =3D 0, count =3D 0, max_tries =3D 1=
000;
+
+	iris_vpu_setup_ucregion_memory_map(core);
+
+	writel(ctrl_init, core->reg_base + CTRL_INIT);
+	writel(0x1, core->reg_base + CPU_CS_SCIACMDARG3);
+
+	while (!ctrl_status && count < max_tries) {
+		ctrl_status =3D readl(core->reg_base + CTRL_STATUS);
+		if ((ctrl_status & CTRL_ERROR_STATUS__M) =3D=3D 0x4) {
+			dev_err(core->dev, "invalid setting for uc_region\n");
+			break;
+		}
+
+		usleep_range(50, 100);
+		count++;
+	}
+
+	if (count >=3D max_tries) {
+		dev_err(core->dev, "error booting up iris firmware\n");
+		return -ETIME;
+	}
+
+	writel(HOST2XTENSA_INTR_ENABLE, core->reg_base + CPU_CS_H2XSOFTINTEN);
+	writel(0x0, core->reg_base + CPU_CS_X2RPMH);
+
+	return 0;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/m=
edia/platform/qcom/iris/iris_vpu_common.h
new file mode 100644
index 000000000000..bafcf46520fd
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#ifndef __IRIS_VPU_COMMON_H__
+#define __IRIS_VPU_COMMON_H__
+
+struct iris_core;
+
+int iris_vpu_boot_firmware(struct iris_core *core);
+
+#endif

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 13CD623498A;
	Fri,  7 Feb 2025 07:56:04 +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=1738914968; cv=none;
 b=sDbSXasMjiu9gVdGHXcAzEpk+JPeELgNMX4xpjVho+Y+YB1WVjcPGsIgUeYN+QzNVRzL6S9IgJrzjpGJwjernHLj8k58JOTFxMFPM067uh1XOTUeXilhvI7iv9hBdCwMktJJp/dT3dtS66DCteuo0KIw+ziLCFeNVAcZGUg1+kE=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738914968; c=relaxed/simple;
	bh=qiuwR9s/1d/ErI4xZS+KgQovghWJZVrNFX1ORYSzMak=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=X2FxxX+Xc4XIzfEQAVEAsV6a/hJWFvzSjV0di8f3P13HkcmMoiRhnPWKGIDixaVUllKgmgKiQ3X4vEtRRUmMxqTz/V4dFQz40buDr2LWzF43ecyz0Qr3MAXf97G2BeBossP0nrU06xuhk5QpALxSK2Rspb3YBvyjprZh11N6+dA=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=Yf6edPoU; arc=none smtp.client-ip=205.220.168.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="Yf6edPoU"
Received: from pps.filterd (m0279867.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 51770S0C029972;
	Fri, 7 Feb 2025 07:55:48 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	32ex0zYYsjp/Z7HCrf8dv7f4HqD8lEgHpXEEetOWplE=; b=Yf6edPoUO5NnEp+Y
	PiFtPeteC2xTMtDqyKSmPMYnxKG6jWvV1Xj4Ec1OM4awtw1R6IWlERXZUxikGQOQ
	7bj8ulYkDEBrS+cfawugyUK61h8jF1d6hDGUqINH5AW01peVEl7tqbujFI8WWO46
	7DnK+4FrpfjTSRVrB/nhlMetpXQGkFgkRrEXyefXJbu/R1dDEeCSiD7lwSXK+juO
	L6zfnZSlnJW34MXWyk9Ro9vprZJDApeTji7OWeWZd1YxD2iaQvGnhkUUFxv3ww6x
	Qej0XH1R61XwORU4Eb/GVYYCJs2pwyh1FnJhLu9+O9Pr1NmK0yCt6XDLg/XlaxkD
	kWy+4w==
Received: from nalasppmta01.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44nddjg44s-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:55:47 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA01.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177tle3008853
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:55:47 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:55:40 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:24:47 +0530
Subject: [PATCH v10 07/28] media: iris: introduce host firmware interface
 with necessary hooks
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-7-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914892; l=50841;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=qiuwR9s/1d/ErI4xZS+KgQovghWJZVrNFX1ORYSzMak=;
 b=CmdgkyQ62ZHbZVMHeMWIxxkBfo5BeByT3zRsjf+w8IzN1qvmZdnxJzlZl/dFBFjlOVZF6quOn
 pZj2hmlBohhBaRvBMG5vK13TVDNFBSi578cRJqsjakXJxfcX0Xtxxpa
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-ORIG-GUID: KuJn0jeH9iDCeABanbXQbOLzOUac6LK0
X-Proofpoint-GUID: KuJn0jeH9iDCeABanbXQbOLzOUac6LK0
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 mlxscore=0 impostorscore=0
 adultscore=0 bulkscore=0 phishscore=0 malwarescore=0 lowpriorityscore=0
 mlxlogscore=999 priorityscore=1501 clxscore=1015 suspectscore=0
 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070060

The Host firmware interface (HFI) is a well defined set of interfaces
for the communication between the host driver and the firmware. The
commands and responses are exchanged in form of packets. One or multiple
packets are grouped under the packet header. Each packet has a packet
type which describes the specific HFI and the payload, which holds the
corresponding value for that HFI.

Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 drivers/media/platform/qcom/iris/Makefile          |   4 +
 drivers/media/platform/qcom/iris/iris_core.c       |  24 ++-
 drivers/media/platform/qcom/iris/iris_core.h       |  20 ++
 drivers/media/platform/qcom/iris/iris_hfi_common.c |  50 +++++
 drivers/media/platform/qcom/iris/iris_hfi_common.h |  60 ++++++
 drivers/media/platform/qcom/iris/iris_hfi_gen1.h   |   3 +
 .../platform/qcom/iris/iris_hfi_gen1_command.c     |  61 ++++++
 .../platform/qcom/iris/iris_hfi_gen1_defines.h     |  94 +++++++++
 .../platform/qcom/iris/iris_hfi_gen1_response.c    | 176 +++++++++++++++++
 drivers/media/platform/qcom/iris/iris_hfi_gen2.h   |   4 +
 .../platform/qcom/iris/iris_hfi_gen2_command.c     |  74 +++++++
 .../platform/qcom/iris/iris_hfi_gen2_defines.h     |  46 +++++
 .../platform/qcom/iris/iris_hfi_gen2_packet.c      | 161 +++++++++++++++
 .../platform/qcom/iris/iris_hfi_gen2_packet.h      |  69 +++++++
 .../platform/qcom/iris/iris_hfi_gen2_response.c    | 215 +++++++++++++++++=
++++
 drivers/media/platform/qcom/iris/iris_hfi_queue.c  | 173 +++++++++++++++++
 drivers/media/platform/qcom/iris/iris_hfi_queue.h  |   5 +
 .../platform/qcom/iris/iris_platform_common.h      |  17 ++
 .../platform/qcom/iris/iris_platform_sm8550.c      |  14 ++
 drivers/media/platform/qcom/iris/iris_probe.c      |  26 +++
 drivers/media/platform/qcom/iris/iris_vpu_common.c |  43 +++++
 drivers/media/platform/qcom/iris/iris_vpu_common.h |   3 +
 22 files changed, 1341 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/plat=
form/qcom/iris/Makefile
index 792f1d6ac8f3..76ca5287c49f 100644
--- a/drivers/media/platform/qcom/iris/Makefile
+++ b/drivers/media/platform/qcom/iris/Makefile
@@ -1,7 +1,11 @@
 iris-objs +=3D iris_core.o \
              iris_firmware.o \
+             iris_hfi_common.o \
              iris_hfi_gen1_command.o \
+             iris_hfi_gen1_response.o \
              iris_hfi_gen2_command.o \
+             iris_hfi_gen2_packet.o \
+             iris_hfi_gen2_response.o \
              iris_hfi_queue.o \
              iris_platform_sm8550.o \
              iris_probe.o \
diff --git a/drivers/media/platform/qcom/iris/iris_core.c b/drivers/media/p=
latform/qcom/iris/iris_core.c
index 5ad66ac113ae..7e19bdd0a19b 100644
--- a/drivers/media/platform/qcom/iris/iris_core.c
+++ b/drivers/media/platform/qcom/iris/iris_core.c
@@ -17,6 +17,24 @@ void iris_core_deinit(struct iris_core *core)
 	mutex_unlock(&core->lock);
 }
=20
+static int iris_wait_for_system_response(struct iris_core *core)
+{
+	u32 hw_response_timeout_val =3D core->iris_platform_data->hw_response_tim=
eout;
+	int ret;
+
+	if (core->state =3D=3D IRIS_CORE_ERROR)
+		return -EIO;
+
+	ret =3D wait_for_completion_timeout(&core->core_init_done,
+					  msecs_to_jiffies(hw_response_timeout_val));
+	if (!ret) {
+		core->state =3D IRIS_CORE_ERROR;
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
 int iris_core_init(struct iris_core *core)
 {
 	int ret;
@@ -44,9 +62,13 @@ int iris_core_init(struct iris_core *core)
 	if (ret)
 		goto error_unload_fw;
=20
+	ret =3D iris_hfi_core_init(core);
+	if (ret)
+		goto error_unload_fw;
+
 	mutex_unlock(&core->lock);
=20
-	return 0;
+	return iris_wait_for_system_response(core);
=20
 error_unload_fw:
 	iris_fw_unload(core);
diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/p=
latform/qcom/iris/iris_core.h
index 516082aa58c9..c0f3c189d779 100644
--- a/drivers/media/platform/qcom/iris/iris_core.h
+++ b/drivers/media/platform/qcom/iris/iris_core.h
@@ -9,6 +9,7 @@
 #include <linux/types.h>
 #include <media/v4l2-device.h>
=20
+#include "iris_hfi_common.h"
 #include "iris_hfi_queue.h"
 #include "iris_platform_common.h"
 #include "iris_state.h"
@@ -19,6 +20,9 @@ struct icc_info {
 	u32			bw_max_kbps;
 };
=20
+#define IRIS_FW_VERSION_LENGTH		128
+#define IFACEQ_CORE_PKT_SIZE		(1024 * 4)
+
 /**
  * struct iris_core - holds core parameters valid for all instances
  *
@@ -45,6 +49,14 @@ struct icc_info {
  * @message_queue: shared interface queue to receive responses from firmwa=
re
  * @debug_queue: shared interface queue to receive debug info from firmware
  * @lock: a lock for this strucure
+ * @response_packet: a pointer to response packet from fw to driver
+ * @header_id: id of packet header
+ * @packet_id: id of packet
+ * @hfi_ops: iris hfi command ops
+ * @hfi_response_ops: iris hfi response ops
+ * @core_init_done: structure of signal completion for system response
+ * @intr_status: interrupt status
+ * @sys_error_handler: a delayed work for handling system fatal error
  */
=20
 struct iris_core {
@@ -71,6 +83,14 @@ struct iris_core {
 	struct iris_iface_q_info		message_queue;
 	struct iris_iface_q_info		debug_queue;
 	struct mutex				lock; /* lock for core related operations */
+	u8					*response_packet;
+	u32					header_id;
+	u32					packet_id;
+	const struct iris_hfi_command_ops	*hfi_ops;
+	const struct iris_hfi_response_ops	*hfi_response_ops;
+	struct completion			core_init_done;
+	u32					intr_status;
+	struct delayed_work			sys_error_handler;
 };
=20
 int iris_core_init(struct iris_core *core);
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.c b/drivers/m=
edia/platform/qcom/iris/iris_hfi_common.c
new file mode 100644
index 000000000000..a19b988c9a88
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#include "iris_core.h"
+#include "iris_hfi_common.h"
+#include "iris_vpu_common.h"
+
+int iris_hfi_core_init(struct iris_core *core)
+{
+	const struct iris_hfi_command_ops *hfi_ops =3D core->hfi_ops;
+	int ret;
+
+	ret =3D hfi_ops->sys_init(core);
+	if (ret)
+		return ret;
+
+	ret =3D hfi_ops->sys_image_version(core);
+	if (ret)
+		return ret;
+
+	return hfi_ops->sys_interframe_powercollapse(core);
+}
+
+irqreturn_t iris_hfi_isr(int irq, void *data)
+{
+	disable_irq_nosync(irq);
+
+	return IRQ_WAKE_THREAD;
+}
+
+irqreturn_t iris_hfi_isr_handler(int irq, void *data)
+{
+	struct iris_core *core =3D data;
+
+	if (!core)
+		return IRQ_NONE;
+
+	mutex_lock(&core->lock);
+	iris_vpu_clear_interrupt(core);
+	mutex_unlock(&core->lock);
+
+	core->hfi_response_ops->hfi_response_handler(core);
+
+	if (!iris_vpu_watchdog(core, core->intr_status))
+		enable_irq(irq);
+
+	return IRQ_HANDLED;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/m=
edia/platform/qcom/iris/iris_hfi_common.h
new file mode 100644
index 000000000000..b46a2f21102a
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#ifndef __IRIS_HFI_COMMON_H__
+#define __IRIS_HFI_COMMON_H__
+
+#include <linux/types.h>
+#include <media/v4l2-device.h>
+
+struct iris_core;
+
+enum hfi_packet_port_type {
+	HFI_PORT_NONE		=3D 0x00000000,
+	HFI_PORT_BITSTREAM	=3D 0x00000001,
+	HFI_PORT_RAW		=3D 0x00000002,
+};
+
+enum hfi_packet_payload_info {
+	HFI_PAYLOAD_NONE	=3D 0x00000000,
+	HFI_PAYLOAD_U32		=3D 0x00000001,
+	HFI_PAYLOAD_S32		=3D 0x00000002,
+	HFI_PAYLOAD_U64		=3D 0x00000003,
+	HFI_PAYLOAD_S64		=3D 0x00000004,
+	HFI_PAYLOAD_STRUCTURE	=3D 0x00000005,
+	HFI_PAYLOAD_BLOB	=3D 0x00000006,
+	HFI_PAYLOAD_STRING	=3D 0x00000007,
+	HFI_PAYLOAD_Q16		=3D 0x00000008,
+	HFI_PAYLOAD_U32_ENUM	=3D 0x00000009,
+	HFI_PAYLOAD_32_PACKED	=3D 0x0000000a,
+	HFI_PAYLOAD_U32_ARRAY	=3D 0x0000000b,
+	HFI_PAYLOAD_S32_ARRAY	=3D 0x0000000c,
+	HFI_PAYLOAD_64_PACKED	=3D 0x0000000d,
+};
+
+enum hfi_packet_host_flags {
+	HFI_HOST_FLAGS_NONE			=3D 0x00000000,
+	HFI_HOST_FLAGS_INTR_REQUIRED		=3D 0x00000001,
+	HFI_HOST_FLAGS_RESPONSE_REQUIRED	=3D 0x00000002,
+	HFI_HOST_FLAGS_NON_DISCARDABLE		=3D 0x00000004,
+	HFI_HOST_FLAGS_GET_PROPERTY		=3D 0x00000008,
+};
+
+struct iris_hfi_command_ops {
+	int (*sys_init)(struct iris_core *core);
+	int (*sys_image_version)(struct iris_core *core);
+	int (*sys_interframe_powercollapse)(struct iris_core *core);
+};
+
+struct iris_hfi_response_ops {
+	void (*hfi_response_handler)(struct iris_core *core);
+};
+
+int iris_hfi_core_init(struct iris_core *core);
+
+irqreturn_t iris_hfi_isr(int irq, void *data);
+irqreturn_t iris_hfi_isr_handler(int irq, void *data);
+
+#endif
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1.h b/drivers/med=
ia/platform/qcom/iris/iris_hfi_gen1.h
index 5d05be7470e0..19b8e9054a75 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1.h
@@ -6,8 +6,11 @@
 #ifndef __IRIS_HFI_GEN1_H__
 #define __IRIS_HFI_GEN1_H__
=20
+struct iris_core;
 struct iris_inst;
=20
+void iris_hfi_gen1_command_ops_init(struct iris_core *core);
+void iris_hfi_gen1_response_ops_init(struct iris_core *core);
 struct iris_inst *iris_hfi_gen1_get_instance(void);
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen1_command.c
index 20c68f4ffb72..07007d8812ba 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
@@ -4,8 +4,69 @@
  */
=20
 #include "iris_hfi_gen1.h"
+#include "iris_hfi_gen1_defines.h"
 #include "iris_instance.h"
=20
+static int iris_hfi_gen1_sys_init(struct iris_core *core)
+{
+	struct hfi_sys_init_pkt sys_init_pkt;
+
+	sys_init_pkt.hdr.size =3D sizeof(sys_init_pkt);
+	sys_init_pkt.hdr.pkt_type =3D HFI_CMD_SYS_INIT;
+	sys_init_pkt.arch_type =3D HFI_VIDEO_ARCH_OX;
+
+	return iris_hfi_queue_cmd_write_locked(core, &sys_init_pkt, sys_init_pkt.=
hdr.size);
+}
+
+static int iris_hfi_gen1_sys_image_version(struct iris_core *core)
+{
+	struct hfi_sys_get_property_pkt packet;
+
+	packet.hdr.size =3D sizeof(packet);
+	packet.hdr.pkt_type =3D HFI_CMD_SYS_GET_PROPERTY;
+	packet.num_properties =3D 1;
+	packet.data =3D HFI_PROPERTY_SYS_IMAGE_VERSION;
+
+	return iris_hfi_queue_cmd_write_locked(core, &packet, packet.hdr.size);
+}
+
+static int iris_hfi_gen1_sys_interframe_powercollapse(struct iris_core *co=
re)
+{
+	struct hfi_sys_set_property_pkt *pkt;
+	struct hfi_enable *hfi;
+	u32 packet_size;
+	int ret;
+
+	packet_size =3D struct_size(pkt, data, 1) + sizeof(*hfi);
+	pkt =3D kzalloc(packet_size, GFP_KERNEL);
+	if (!pkt)
+		return -ENOMEM;
+
+	hfi =3D (struct hfi_enable *)&pkt->data[1];
+
+	pkt->hdr.size =3D packet_size;
+	pkt->hdr.pkt_type =3D HFI_CMD_SYS_SET_PROPERTY;
+	pkt->num_properties =3D 1;
+	pkt->data[0] =3D HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL;
+	hfi->enable =3D true;
+
+	ret =3D iris_hfi_queue_cmd_write_locked(core, pkt, pkt->hdr.size);
+	kfree(pkt);
+
+	return ret;
+}
+
+static const struct iris_hfi_command_ops iris_hfi_gen1_command_ops =3D {
+	.sys_init =3D iris_hfi_gen1_sys_init,
+	.sys_image_version =3D iris_hfi_gen1_sys_image_version,
+	.sys_interframe_powercollapse =3D iris_hfi_gen1_sys_interframe_powercolla=
pse,
+};
+
+void iris_hfi_gen1_command_ops_init(struct iris_core *core)
+{
+	core->hfi_ops =3D &iris_hfi_gen1_command_ops;
+}
+
 struct iris_inst *iris_hfi_gen1_get_instance(void)
 {
 	return kzalloc(sizeof(struct iris_inst), GFP_KERNEL);
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
new file mode 100644
index 000000000000..8af824a42bcf
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#ifndef __IRIS_HFI_GEN1_DEFINES_H__
+#define __IRIS_HFI_GEN1_DEFINES_H__
+
+#include <linux/types.h>
+
+#define HFI_VIDEO_ARCH_OX				0x1
+#define HFI_ERR_NONE					0x0
+
+#define HFI_CMD_SYS_INIT				0x10001
+#define HFI_CMD_SYS_SET_PROPERTY			0x10005
+#define HFI_CMD_SYS_GET_PROPERTY			0x10006
+
+#define HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL		0x5
+#define HFI_PROPERTY_SYS_IMAGE_VERSION			0x6
+
+#define HFI_EVENT_SYS_ERROR				0x1
+
+#define HFI_MSG_SYS_INIT				0x20001
+#define HFI_MSG_SYS_COV					0x20009
+#define HFI_MSG_SYS_PROPERTY_INFO			0x2000a
+
+#define HFI_MSG_EVENT_NOTIFY				0x21001
+
+struct hfi_pkt_hdr {
+	u32 size;
+	u32 pkt_type;
+};
+
+struct hfi_sys_init_pkt {
+	struct hfi_pkt_hdr hdr;
+	u32 arch_type;
+};
+
+struct hfi_sys_set_property_pkt {
+	struct hfi_pkt_hdr hdr;
+	u32 num_properties;
+	u32 data[];
+};
+
+struct hfi_sys_get_property_pkt {
+	struct hfi_pkt_hdr hdr;
+	u32 num_properties;
+	u32 data;
+};
+
+struct hfi_msg_event_notify_pkt {
+	struct hfi_pkt_hdr hdr;
+	u32 event_id;
+	u32 event_data1;
+	u32 event_data2;
+	u32 ext_event_data[];
+};
+
+struct hfi_msg_sys_init_done_pkt {
+	struct hfi_pkt_hdr hdr;
+	u32 error_type;
+	u32 num_properties;
+	u32 data[];
+};
+
+struct hfi_msg_sys_property_info_pkt {
+	struct hfi_pkt_hdr hdr;
+	u32 num_properties;
+	u32 property;
+	u8 data[];
+};
+
+struct hfi_enable {
+	u32 enable;
+};
+
+struct hfi_msg_sys_debug_pkt {
+	struct hfi_pkt_hdr hdr;
+	u32 msg_type;
+	u32 msg_size;
+	u32 time_stamp_hi;
+	u32 time_stamp_lo;
+	u8 msg_data[];
+};
+
+struct hfi_msg_sys_coverage_pkt {
+	struct hfi_pkt_hdr hdr;
+	u32 msg_size;
+	u32 time_stamp_hi;
+	u32 time_stamp_lo;
+	u8 msg_data[];
+};
+
+#endif
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c b/dr=
ivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
new file mode 100644
index 000000000000..78fefa4176f9
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
@@ -0,0 +1,176 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#include "iris_hfi_gen1.h"
+#include "iris_hfi_gen1_defines.h"
+#include "iris_instance.h"
+
+static void
+iris_hfi_gen1_sys_event_notify(struct iris_core *core, void *packet)
+{
+	struct hfi_msg_event_notify_pkt *pkt =3D packet;
+
+	if (pkt->event_id =3D=3D HFI_EVENT_SYS_ERROR)
+		dev_err(core->dev, "sys error (type: %x, data1:%x, data2:%x)\n",
+			pkt->event_id, pkt->event_data1, pkt->event_data2);
+
+	core->state =3D IRIS_CORE_ERROR;
+	schedule_delayed_work(&core->sys_error_handler, msecs_to_jiffies(10));
+}
+
+static void iris_hfi_gen1_sys_init_done(struct iris_core *core, void *pack=
et)
+{
+	struct hfi_msg_sys_init_done_pkt *pkt =3D packet;
+
+	if (pkt->error_type !=3D HFI_ERR_NONE) {
+		core->state =3D IRIS_CORE_ERROR;
+		return;
+	}
+
+	complete(&core->core_init_done);
+}
+
+static void
+iris_hfi_gen1_sys_get_prop_image_version(struct iris_core *core,
+					 struct hfi_msg_sys_property_info_pkt *pkt)
+{
+	int req_bytes =3D pkt->hdr.size - sizeof(*pkt);
+	char fw_version[IRIS_FW_VERSION_LENGTH];
+	u8 *str_image_version;
+	u32 i;
+
+	if (req_bytes < IRIS_FW_VERSION_LENGTH - 1 || !pkt->data[0] || pkt->num_p=
roperties > 1) {
+		dev_err(core->dev, "bad packet\n");
+		return;
+	}
+
+	str_image_version =3D pkt->data;
+	if (!str_image_version) {
+		dev_err(core->dev, "firmware version not available\n");
+		return;
+	}
+
+	for (i =3D 0; i < IRIS_FW_VERSION_LENGTH - 1; i++) {
+		if (str_image_version[i] !=3D '\0')
+			fw_version[i] =3D str_image_version[i];
+		else
+			fw_version[i] =3D ' ';
+	}
+	fw_version[i] =3D '\0';
+	dev_dbg(core->dev, "firmware version: %s\n", fw_version);
+}
+
+static void iris_hfi_gen1_sys_property_info(struct iris_core *core, void *=
packet)
+{
+	struct hfi_msg_sys_property_info_pkt *pkt =3D packet;
+
+	if (!pkt->num_properties) {
+		dev_dbg(core->dev, "no properties\n");
+		return;
+	}
+
+	switch (pkt->property) {
+	case HFI_PROPERTY_SYS_IMAGE_VERSION:
+		iris_hfi_gen1_sys_get_prop_image_version(core, pkt);
+		break;
+	default:
+		dev_dbg(core->dev, "unknown property data\n");
+		break;
+	}
+}
+
+struct iris_hfi_gen1_response_pkt_info {
+	u32 pkt;
+	u32 pkt_sz;
+};
+
+static const struct iris_hfi_gen1_response_pkt_info pkt_infos[] =3D {
+	{
+	 .pkt =3D HFI_MSG_EVENT_NOTIFY,
+	 .pkt_sz =3D sizeof(struct hfi_msg_event_notify_pkt),
+	},
+	{
+	 .pkt =3D HFI_MSG_SYS_INIT,
+	 .pkt_sz =3D sizeof(struct hfi_msg_sys_init_done_pkt),
+	},
+	{
+	 .pkt =3D HFI_MSG_SYS_PROPERTY_INFO,
+	 .pkt_sz =3D sizeof(struct hfi_msg_sys_property_info_pkt),
+	},
+};
+
+static void iris_hfi_gen1_handle_response(struct iris_core *core, void *re=
sponse)
+{
+	struct hfi_pkt_hdr *hdr =3D (struct hfi_pkt_hdr *)response;
+	const struct iris_hfi_gen1_response_pkt_info *pkt_info;
+	struct device *dev =3D core->dev;
+	bool found =3D false;
+	u32 i;
+
+	for (i =3D 0; i < ARRAY_SIZE(pkt_infos); i++) {
+		pkt_info =3D &pkt_infos[i];
+		if (pkt_info->pkt !=3D hdr->pkt_type)
+			continue;
+		found =3D true;
+		break;
+	}
+
+	if (!found || hdr->size < pkt_info->pkt_sz) {
+		dev_err(dev, "bad packet size (%d should be %d, pkt type:%x, found %d)\n=
",
+			hdr->size, pkt_info->pkt_sz, hdr->pkt_type, found);
+
+		return;
+	}
+
+	switch (hdr->pkt_type) {
+	case HFI_MSG_SYS_INIT:
+		iris_hfi_gen1_sys_init_done(core, hdr);
+		break;
+	case HFI_MSG_SYS_PROPERTY_INFO:
+		iris_hfi_gen1_sys_property_info(core, hdr);
+		break;
+	case HFI_MSG_EVENT_NOTIFY:
+		iris_hfi_gen1_sys_event_notify(core, hdr);
+		break;
+	default:
+		break;
+	}
+}
+
+static void iris_hfi_gen1_flush_debug_queue(struct iris_core *core, u8 *pa=
cket)
+{
+	struct hfi_msg_sys_coverage_pkt *pkt;
+
+	while (!iris_hfi_queue_dbg_read(core, packet)) {
+		pkt =3D (struct hfi_msg_sys_coverage_pkt *)packet;
+
+		if (pkt->hdr.pkt_type !=3D HFI_MSG_SYS_COV) {
+			struct hfi_msg_sys_debug_pkt *pkt =3D
+				(struct hfi_msg_sys_debug_pkt *)packet;
+
+			dev_dbg(core->dev, "%s", pkt->msg_data);
+		}
+	}
+}
+
+static void iris_hfi_gen1_response_handler(struct iris_core *core)
+{
+	memset(core->response_packet, 0, sizeof(struct hfi_pkt_hdr));
+	while (!iris_hfi_queue_msg_read(core, core->response_packet)) {
+		iris_hfi_gen1_handle_response(core, core->response_packet);
+		memset(core->response_packet, 0, sizeof(struct hfi_pkt_hdr));
+	}
+
+	iris_hfi_gen1_flush_debug_queue(core, core->response_packet);
+}
+
+static const struct iris_hfi_response_ops iris_hfi_gen1_response_ops =3D {
+	.hfi_response_handler =3D iris_hfi_gen1_response_handler,
+};
+
+void iris_hfi_gen1_response_ops_init(struct iris_core *core)
+{
+	core->hfi_response_ops =3D &iris_hfi_gen1_response_ops;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h b/drivers/med=
ia/platform/qcom/iris/iris_hfi_gen2.h
index c159ed7f64f9..c43b51774978 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h
@@ -8,6 +8,8 @@
=20
 #include "iris_instance.h"
=20
+struct iris_core;
+
 /**
  * struct iris_inst_hfi_gen2 - holds per video instance parameters for hfi=
_gen2
  *
@@ -17,6 +19,8 @@ struct iris_inst_hfi_gen2 {
 	struct iris_inst		inst;
 };
=20
+void iris_hfi_gen2_command_ops_init(struct iris_core *core);
+void iris_hfi_gen2_response_ops_init(struct iris_core *core);
 struct iris_inst *iris_hfi_gen2_get_instance(void);
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen2_command.c
index 3ee33c8befae..5eaebe170214 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
@@ -4,6 +4,80 @@
  */
=20
 #include "iris_hfi_gen2.h"
+#include "iris_hfi_gen2_packet.h"
+
+#define NUM_SYS_INIT_PACKETS 8
+
+#define SYS_INIT_PKT_SIZE (sizeof(struct iris_hfi_header) + \
+	NUM_SYS_INIT_PACKETS * (sizeof(struct iris_hfi_packet) + sizeof(u32)))
+
+#define SYS_IFPC_PKT_SIZE (sizeof(struct iris_hfi_header) + \
+	sizeof(struct iris_hfi_packet) + sizeof(u32))
+
+#define SYS_NO_PAYLOAD_PKT_SIZE (sizeof(struct iris_hfi_header) + \
+	sizeof(struct iris_hfi_packet))
+
+static int iris_hfi_gen2_sys_init(struct iris_core *core)
+{
+	struct iris_hfi_header *hdr;
+	int ret;
+
+	hdr =3D kzalloc(SYS_INIT_PKT_SIZE, GFP_KERNEL);
+	if (!hdr)
+		return -ENOMEM;
+
+	iris_hfi_gen2_packet_sys_init(core, hdr);
+	ret =3D iris_hfi_queue_cmd_write_locked(core, hdr, hdr->size);
+
+	kfree(hdr);
+
+	return ret;
+}
+
+static int iris_hfi_gen2_sys_image_version(struct iris_core *core)
+{
+	struct iris_hfi_header *hdr;
+	int ret;
+
+	hdr =3D kzalloc(SYS_NO_PAYLOAD_PKT_SIZE, GFP_KERNEL);
+	if (!hdr)
+		return -ENOMEM;
+
+	iris_hfi_gen2_packet_image_version(core, hdr);
+	ret =3D iris_hfi_queue_cmd_write_locked(core, hdr, hdr->size);
+
+	kfree(hdr);
+
+	return ret;
+}
+
+static int iris_hfi_gen2_sys_interframe_powercollapse(struct iris_core *co=
re)
+{
+	struct iris_hfi_header *hdr;
+	int ret;
+
+	hdr =3D kzalloc(SYS_IFPC_PKT_SIZE, GFP_KERNEL);
+	if (!hdr)
+		return -ENOMEM;
+
+	iris_hfi_gen2_packet_sys_interframe_powercollapse(core, hdr);
+	ret =3D iris_hfi_queue_cmd_write_locked(core, hdr, hdr->size);
+
+	kfree(hdr);
+
+	return ret;
+}
+
+static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops =3D {
+	.sys_init =3D iris_hfi_gen2_sys_init,
+	.sys_image_version =3D iris_hfi_gen2_sys_image_version,
+	.sys_interframe_powercollapse =3D iris_hfi_gen2_sys_interframe_powercolla=
pse,
+};
+
+void iris_hfi_gen2_command_ops_init(struct iris_core *core)
+{
+	core->hfi_ops =3D &iris_hfi_gen2_command_ops;
+}
=20
 struct iris_inst *iris_hfi_gen2_get_instance(void)
 {
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
new file mode 100644
index 000000000000..2640caa7f9c0
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#ifndef __IRIS_HFI_GEN2_DEFINES_H__
+#define __IRIS_HFI_GEN2_DEFINES_H__
+
+#include <linux/types.h>
+
+#define HFI_VIDEO_ARCH_LX			0x1
+
+#define HFI_CMD_BEGIN				0x01000000
+#define HFI_CMD_INIT				0x01000001
+#define HFI_CMD_END				0x01FFFFFF
+
+#define HFI_PROP_BEGIN				0x03000000
+#define HFI_PROP_IMAGE_VERSION			0x03000001
+#define HFI_PROP_INTRA_FRAME_POWER_COLLAPSE	0x03000002
+#define HFI_PROP_UBWC_MAX_CHANNELS		0x03000003
+#define HFI_PROP_UBWC_MAL_LENGTH		0x03000004
+#define HFI_PROP_UBWC_HBB			0x03000005
+#define HFI_PROP_UBWC_BANK_SWZL_LEVEL1		0x03000006
+#define HFI_PROP_UBWC_BANK_SWZL_LEVEL2		0x03000007
+#define HFI_PROP_UBWC_BANK_SWZL_LEVEL3		0x03000008
+#define HFI_PROP_UBWC_BANK_SPREADING		0x03000009
+#define HFI_PROP_END				0x03FFFFFF
+
+#define HFI_SYSTEM_ERROR_BEGIN			0x05000000
+#define HFI_SYS_ERROR_WD_TIMEOUT		0x05000001
+#define HFI_SYSTEM_ERROR_END			0x05FFFFFF
+
+enum hfi_packet_firmware_flags {
+	HFI_FW_FLAGS_SUCCESS			=3D 0x00000001,
+	HFI_FW_FLAGS_INFORMATION		=3D 0x00000002,
+	HFI_FW_FLAGS_SESSION_ERROR		=3D 0x00000004,
+	HFI_FW_FLAGS_SYSTEM_ERROR		=3D 0x00000008,
+};
+
+struct hfi_debug_header {
+	u32 size;
+	u32 debug_level;
+	u32 reserved[2];
+};
+
+#endif
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c b/driv=
ers/media/platform/qcom/iris/iris_hfi_gen2_packet.c
new file mode 100644
index 000000000000..986013aa62df
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#include "iris_hfi_common.h"
+#include "iris_hfi_gen2.h"
+#include "iris_hfi_gen2_packet.h"
+
+static void iris_hfi_gen2_create_header(struct iris_hfi_header *hdr,
+					u32 session_id, u32 header_id)
+{
+	memset(hdr, 0, sizeof(*hdr));
+
+	hdr->size =3D sizeof(*hdr);
+	hdr->session_id =3D session_id;
+	hdr->header_id =3D header_id;
+	hdr->num_packets =3D 0;
+}
+
+static void iris_hfi_gen2_create_packet(struct iris_hfi_header *hdr, u32 p=
kt_type,
+					u32 pkt_flags, u32 payload_type, u32 port,
+					u32 packet_id, void *payload, u32 payload_size)
+{
+	struct iris_hfi_packet *pkt =3D (struct iris_hfi_packet *)((u8 *)hdr + hd=
r->size);
+	u32 pkt_size =3D sizeof(*pkt) + payload_size;
+
+	memset(pkt, 0, pkt_size);
+	pkt->size =3D pkt_size;
+	pkt->type =3D pkt_type;
+	pkt->flags =3D pkt_flags;
+	pkt->payload_info =3D payload_type;
+	pkt->port =3D port;
+	pkt->packet_id =3D packet_id;
+	if (payload_size)
+		memcpy(&pkt->payload[0], payload, payload_size);
+
+	hdr->num_packets++;
+	hdr->size +=3D pkt->size;
+}
+
+void iris_hfi_gen2_packet_sys_init(struct iris_core *core, struct iris_hfi=
_header *hdr)
+{
+	u32 payload =3D 0;
+
+	iris_hfi_gen2_create_header(hdr, 0, core->header_id++);
+
+	payload =3D HFI_VIDEO_ARCH_LX;
+	iris_hfi_gen2_create_packet(hdr,
+				    HFI_CMD_INIT,
+				    (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+				    HFI_HOST_FLAGS_INTR_REQUIRED |
+				    HFI_HOST_FLAGS_NON_DISCARDABLE),
+				    HFI_PAYLOAD_U32,
+				    HFI_PORT_NONE,
+				    core->packet_id++,
+				    &payload,
+				    sizeof(u32));
+
+	payload =3D core->iris_platform_data->ubwc_config->max_channels;
+	iris_hfi_gen2_create_packet(hdr,
+				    HFI_PROP_UBWC_MAX_CHANNELS,
+				    HFI_HOST_FLAGS_NONE,
+				    HFI_PAYLOAD_U32,
+				    HFI_PORT_NONE,
+				    core->packet_id++,
+				    &payload,
+				    sizeof(u32));
+
+	payload =3D core->iris_platform_data->ubwc_config->mal_length;
+	iris_hfi_gen2_create_packet(hdr,
+				    HFI_PROP_UBWC_MAL_LENGTH,
+				    HFI_HOST_FLAGS_NONE,
+				    HFI_PAYLOAD_U32,
+				    HFI_PORT_NONE,
+				    core->packet_id++,
+				    &payload,
+				    sizeof(u32));
+
+	payload =3D core->iris_platform_data->ubwc_config->highest_bank_bit;
+	iris_hfi_gen2_create_packet(hdr,
+				    HFI_PROP_UBWC_HBB,
+				    HFI_HOST_FLAGS_NONE,
+				    HFI_PAYLOAD_U32,
+				    HFI_PORT_NONE,
+				    core->packet_id++,
+				    &payload,
+				    sizeof(u32));
+
+	payload =3D core->iris_platform_data->ubwc_config->bank_swzl_level;
+	iris_hfi_gen2_create_packet(hdr,
+				    HFI_PROP_UBWC_BANK_SWZL_LEVEL1,
+				    HFI_HOST_FLAGS_NONE,
+				    HFI_PAYLOAD_U32,
+				    HFI_PORT_NONE,
+				    core->packet_id++,
+				    &payload,
+				    sizeof(u32));
+
+	payload =3D core->iris_platform_data->ubwc_config->bank_swz2_level;
+	iris_hfi_gen2_create_packet(hdr,
+				    HFI_PROP_UBWC_BANK_SWZL_LEVEL2,
+				    HFI_HOST_FLAGS_NONE,
+				    HFI_PAYLOAD_U32,
+				    HFI_PORT_NONE,
+				    core->packet_id++,
+				    &payload,
+				    sizeof(u32));
+
+	payload =3D core->iris_platform_data->ubwc_config->bank_swz3_level;
+	iris_hfi_gen2_create_packet(hdr,
+				    HFI_PROP_UBWC_BANK_SWZL_LEVEL3,
+				    HFI_HOST_FLAGS_NONE,
+				    HFI_PAYLOAD_U32,
+				    HFI_PORT_NONE,
+				    core->packet_id++,
+				    &payload,
+				    sizeof(u32));
+
+	payload =3D core->iris_platform_data->ubwc_config->bank_spreading;
+	iris_hfi_gen2_create_packet(hdr,
+				    HFI_PROP_UBWC_BANK_SPREADING,
+				    HFI_HOST_FLAGS_NONE,
+				    HFI_PAYLOAD_U32,
+				    HFI_PORT_NONE,
+				    core->packet_id++,
+				    &payload,
+				    sizeof(u32));
+}
+
+void iris_hfi_gen2_packet_image_version(struct iris_core *core, struct iri=
s_hfi_header *hdr)
+{
+	iris_hfi_gen2_create_header(hdr, 0, core->header_id++);
+
+	iris_hfi_gen2_create_packet(hdr,
+				    HFI_PROP_IMAGE_VERSION,
+				    (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+				    HFI_HOST_FLAGS_INTR_REQUIRED |
+				    HFI_HOST_FLAGS_GET_PROPERTY),
+				    HFI_PAYLOAD_NONE,
+				    HFI_PORT_NONE,
+				    core->packet_id++,
+				    NULL, 0);
+}
+
+void iris_hfi_gen2_packet_sys_interframe_powercollapse(struct iris_core *c=
ore,
+						       struct iris_hfi_header *hdr)
+{
+	u32 payload =3D 1; /* HFI_TRUE */
+
+	iris_hfi_gen2_create_header(hdr, 0 /*session_id*/, core->header_id++);
+
+	iris_hfi_gen2_create_packet(hdr,
+				    HFI_PROP_INTRA_FRAME_POWER_COLLAPSE,
+				    HFI_HOST_FLAGS_NONE,
+				    HFI_PAYLOAD_U32,
+				    HFI_PORT_NONE,
+				    core->packet_id++,
+				    &payload,
+				    sizeof(u32));
+}
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h b/driv=
ers/media/platform/qcom/iris/iris_hfi_gen2_packet.h
new file mode 100644
index 000000000000..10dcb6e4c3d9
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#ifndef __IRIS_HFI_GEN2_PACKET_H__
+#define __IRIS_HFI_GEN2_PACKET_H__
+
+#include "iris_hfi_gen2_defines.h"
+
+struct iris_core;
+
+/**
+ * struct iris_hfi_header
+ *
+ * @size: size of the total packet in bytes including hfi_header
+ * @session_id: For session level hfi_header session_id is non-zero.
+ *                For  system level hfi_header session_id is zero.
+ * @header_id: unique header id for each hfi_header
+ * @reserved: reserved for future use
+ * @num_packets: number of hfi_packet that are included with the hfi_header
+ */
+struct iris_hfi_header {
+	u32 size;
+	u32 session_id;
+	u32 header_id;
+	u32 reserved[4];
+	u32 num_packets;
+};
+
+/**
+ * struct iris_hfi_packet
+ *
+ * @size: size of the hfi_packet in bytes including payload
+ * @type: one of the below hfi_packet types:
+ *        HFI_CMD_*,
+ *        HFI_PROP_*,
+ *        HFI_ERROR_*,
+ *        HFI_INFO_*,
+ *        HFI_SYS_ERROR_*
+ * @flags: hfi_packet flags. It is represented as bit masks.
+ *         host packet flags are "enum hfi_packet_host_flags"
+ *         firmware packet flags are "enum hfi_packet_firmware_flags"
+ * @payload_info: payload information indicated by "enum hfi_packet_payloa=
d_info"
+ * @port: hfi_packet port type indicated by "enum hfi_packet_port_type"
+ *        This is bitmask and may be applicable to multiple ports.
+ * @packet_id: host hfi_packet contains unique packet id.
+ *             firmware returns host packet id in response packet
+ *             wherever applicable. If not applicable firmware sets it to =
zero.
+ * @reserved: reserved for future use.
+ * @payload: flexible array of payload having additional packet informatio=
n.
+ */
+struct iris_hfi_packet {
+	u32 size;
+	u32 type;
+	u32 flags;
+	u32 payload_info;
+	u32 port;
+	u32 packet_id;
+	u32 reserved[2];
+	u32 payload[];
+};
+
+void iris_hfi_gen2_packet_sys_init(struct iris_core *core, struct iris_hfi=
_header *hdr);
+void iris_hfi_gen2_packet_image_version(struct iris_core *core, struct iri=
s_hfi_header *hdr);
+void iris_hfi_gen2_packet_sys_interframe_powercollapse(struct iris_core *c=
ore,
+						       struct iris_hfi_header *hdr);
+
+#endif
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c b/dr=
ivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
new file mode 100644
index 000000000000..007e4a7b6782
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
@@ -0,0 +1,215 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#include "iris_hfi_gen2.h"
+#include "iris_hfi_gen2_defines.h"
+#include "iris_hfi_gen2_packet.h"
+#include "iris_vpu_common.h"
+
+struct iris_hfi_gen2_core_hfi_range {
+	u32 begin;
+	u32 end;
+	int (*handle)(struct iris_core *core, struct iris_hfi_packet *pkt);
+};
+
+static int iris_hfi_gen2_validate_packet(u8 *response_pkt, u8 *core_resp_p=
kt)
+{
+	u8 *response_limit =3D core_resp_pkt + IFACEQ_CORE_PKT_SIZE;
+	u32 response_pkt_size =3D *(u32 *)response_pkt;
+
+	if (!response_pkt_size)
+		return -EINVAL;
+
+	if (response_pkt_size < sizeof(struct iris_hfi_packet))
+		return -EINVAL;
+
+	if (response_pkt + response_pkt_size > response_limit)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int iris_hfi_gen2_validate_hdr_packet(struct iris_core *core, struc=
t iris_hfi_header *hdr)
+{
+	struct iris_hfi_packet *packet;
+	int ret;
+	u8 *pkt;
+	u32 i;
+
+	if (hdr->size < sizeof(*hdr) + sizeof(*packet))
+		return -EINVAL;
+
+	pkt =3D (u8 *)((u8 *)hdr + sizeof(*hdr));
+
+	for (i =3D 0; i < hdr->num_packets; i++) {
+		packet =3D (struct iris_hfi_packet *)pkt;
+		ret =3D iris_hfi_gen2_validate_packet(pkt, core->response_packet);
+		if (ret)
+			return ret;
+
+		pkt +=3D packet->size;
+	}
+
+	return 0;
+}
+
+static int iris_hfi_gen2_handle_system_error(struct iris_core *core,
+					     struct iris_hfi_packet *pkt)
+{
+	dev_err(core->dev, "received system error of type %#x\n", pkt->type);
+
+	core->state =3D IRIS_CORE_ERROR;
+	schedule_delayed_work(&core->sys_error_handler, msecs_to_jiffies(10));
+
+	return 0;
+}
+
+static int iris_hfi_gen2_handle_system_init(struct iris_core *core,
+					    struct iris_hfi_packet *pkt)
+{
+	if (!(pkt->flags & HFI_FW_FLAGS_SUCCESS)) {
+		core->state =3D IRIS_CORE_ERROR;
+		return 0;
+	}
+
+	complete(&core->core_init_done);
+
+	return 0;
+}
+
+static int iris_hfi_gen2_handle_image_version_property(struct iris_core *c=
ore,
+						       struct iris_hfi_packet *pkt)
+{
+	u8 *str_image_version =3D (u8 *)pkt + sizeof(*pkt);
+	u32 req_bytes =3D pkt->size - sizeof(*pkt);
+	char fw_version[IRIS_FW_VERSION_LENGTH];
+	u32 i;
+
+	if (req_bytes < IRIS_FW_VERSION_LENGTH - 1)
+		return -EINVAL;
+
+	for (i =3D 0; i < IRIS_FW_VERSION_LENGTH - 1; i++) {
+		if (str_image_version[i] !=3D '\0')
+			fw_version[i] =3D str_image_version[i];
+		else
+			fw_version[i] =3D ' ';
+	}
+	fw_version[i] =3D '\0';
+	dev_dbg(core->dev, "firmware version: %s\n", fw_version);
+
+	return 0;
+}
+
+static int iris_hfi_gen2_handle_system_property(struct iris_core *core,
+						struct iris_hfi_packet *pkt)
+{
+	switch (pkt->type) {
+	case HFI_PROP_IMAGE_VERSION:
+		return iris_hfi_gen2_handle_image_version_property(core, pkt);
+	default:
+		return 0;
+	}
+}
+
+static int iris_hfi_gen2_handle_system_response(struct iris_core *core,
+						struct iris_hfi_header *hdr)
+{
+	u8 *start_pkt =3D (u8 *)((u8 *)hdr + sizeof(*hdr));
+	struct iris_hfi_packet *packet;
+	u32 i, j;
+	u8 *pkt;
+	int ret;
+	static const struct iris_hfi_gen2_core_hfi_range range[] =3D {
+		{HFI_SYSTEM_ERROR_BEGIN, HFI_SYSTEM_ERROR_END, iris_hfi_gen2_handle_syst=
em_error },
+		{HFI_PROP_BEGIN,         HFI_PROP_END, iris_hfi_gen2_handle_system_prope=
rty },
+		{HFI_CMD_BEGIN,          HFI_CMD_END, iris_hfi_gen2_handle_system_init },
+	};
+
+	for (i =3D 0; i < ARRAY_SIZE(range); i++) {
+		pkt =3D start_pkt;
+		for (j =3D 0; j < hdr->num_packets; j++) {
+			packet =3D (struct iris_hfi_packet *)pkt;
+			if (packet->flags & HFI_FW_FLAGS_SYSTEM_ERROR) {
+				ret =3D iris_hfi_gen2_handle_system_error(core, packet);
+				return ret;
+			}
+
+			if (packet->type > range[i].begin && packet->type < range[i].end) {
+				ret =3D range[i].handle(core, packet);
+				if (ret)
+					return ret;
+
+				if (packet->type >  HFI_SYSTEM_ERROR_BEGIN &&
+				    packet->type < HFI_SYSTEM_ERROR_END)
+					return 0;
+			}
+			pkt +=3D packet->size;
+		}
+	}
+
+	return 0;
+}
+
+static int iris_hfi_gen2_handle_response(struct iris_core *core, void *res=
ponse)
+{
+	struct iris_hfi_header *hdr =3D (struct iris_hfi_header *)response;
+	int ret;
+
+	ret =3D iris_hfi_gen2_validate_hdr_packet(core, hdr);
+	if (ret)
+		return iris_hfi_gen2_handle_system_error(core, NULL);
+
+	return iris_hfi_gen2_handle_system_response(core, hdr);
+}
+
+static void iris_hfi_gen2_flush_debug_queue(struct iris_core *core, u8 *pa=
cket)
+{
+	struct hfi_debug_header *pkt;
+	u8 *log;
+
+	while (!iris_hfi_queue_dbg_read(core, packet)) {
+		pkt =3D (struct hfi_debug_header *)packet;
+
+		if (pkt->size < sizeof(*pkt))
+			continue;
+
+		if (pkt->size >=3D IFACEQ_CORE_PKT_SIZE)
+			continue;
+
+		packet[pkt->size] =3D '\0';
+		log =3D (u8 *)packet + sizeof(*pkt) + 1;
+		dev_dbg(core->dev, "%s", log);
+	}
+}
+
+static void iris_hfi_gen2_response_handler(struct iris_core *core)
+{
+	if (iris_vpu_watchdog(core, core->intr_status)) {
+		struct iris_hfi_packet pkt =3D {.type =3D HFI_SYS_ERROR_WD_TIMEOUT};
+
+		dev_err(core->dev, "cpu watchdog error received\n");
+		core->state =3D IRIS_CORE_ERROR;
+		iris_hfi_gen2_handle_system_error(core, &pkt);
+
+		return;
+	}
+
+	memset(core->response_packet, 0, sizeof(struct iris_hfi_header));
+	while (!iris_hfi_queue_msg_read(core, core->response_packet)) {
+		iris_hfi_gen2_handle_response(core, core->response_packet);
+		memset(core->response_packet, 0, sizeof(struct iris_hfi_header));
+	}
+
+	iris_hfi_gen2_flush_debug_queue(core, core->response_packet);
+}
+
+static const struct iris_hfi_response_ops iris_hfi_gen2_response_ops =3D {
+	.hfi_response_handler =3D iris_hfi_gen2_response_handler,
+};
+
+void iris_hfi_gen2_response_ops_init(struct iris_core *core)
+{
+	core->hfi_response_ops =3D &iris_hfi_gen2_response_ops;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_queue.c b/drivers/me=
dia/platform/qcom/iris/iris_hfi_queue.c
index 494ef205133d..ee245c540ce7 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_queue.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_queue.c
@@ -5,6 +5,179 @@
=20
 #include "iris_core.h"
 #include "iris_hfi_queue.h"
+#include "iris_vpu_common.h"
+
+static int iris_hfi_queue_write(struct iris_iface_q_info *qinfo, void *pac=
ket, u32 packet_size)
+{
+	struct iris_hfi_queue_header *queue =3D qinfo->qhdr;
+	u32 write_idx =3D queue->write_idx * sizeof(u32);
+	u32 read_idx =3D queue->read_idx * sizeof(u32);
+	u32 empty_space, new_write_idx, residue;
+	u32 *write_ptr;
+
+	if (write_idx < read_idx)
+		empty_space =3D read_idx - write_idx;
+	else
+		empty_space =3D IFACEQ_QUEUE_SIZE - (write_idx -  read_idx);
+	if (empty_space < packet_size)
+		return -ENOSPC;
+
+	queue->tx_req =3D  0;
+
+	new_write_idx =3D write_idx + packet_size;
+	write_ptr =3D (u32 *)((u8 *)qinfo->kernel_vaddr + write_idx);
+
+	if (write_ptr < (u32 *)qinfo->kernel_vaddr ||
+	    write_ptr > (u32 *)(qinfo->kernel_vaddr +
+	    IFACEQ_QUEUE_SIZE))
+		return -EINVAL;
+
+	if (new_write_idx < IFACEQ_QUEUE_SIZE) {
+		memcpy(write_ptr, packet, packet_size);
+	} else {
+		residue =3D new_write_idx - IFACEQ_QUEUE_SIZE;
+		memcpy(write_ptr, packet, (packet_size - residue));
+		memcpy(qinfo->kernel_vaddr,
+		       packet + (packet_size - residue), residue);
+		new_write_idx =3D residue;
+	}
+
+	/* Make sure packet is written before updating the write index */
+	mb();
+	queue->write_idx =3D new_write_idx / sizeof(u32);
+
+	/* Make sure write index is updated before an interrupt is raised */
+	mb();
+
+	return 0;
+}
+
+static int iris_hfi_queue_read(struct iris_iface_q_info *qinfo, void *pack=
et)
+{
+	struct iris_hfi_queue_header *queue =3D qinfo->qhdr;
+	u32 write_idx =3D queue->write_idx * sizeof(u32);
+	u32 read_idx =3D queue->read_idx * sizeof(u32);
+	u32 packet_size, receive_request =3D 0;
+	u32 new_read_idx, residue;
+	u32 *read_ptr;
+	int ret =3D 0;
+
+	if (queue->queue_type =3D=3D IFACEQ_MSGQ_ID)
+		receive_request =3D 1;
+
+	if (read_idx =3D=3D write_idx) {
+		queue->rx_req =3D receive_request;
+		/* Ensure qhdr is updated in main memory */
+		mb();
+		return -ENODATA;
+	}
+
+	read_ptr =3D qinfo->kernel_vaddr + read_idx;
+	if (read_ptr < (u32 *)qinfo->kernel_vaddr ||
+	    read_ptr > (u32 *)(qinfo->kernel_vaddr +
+	    IFACEQ_QUEUE_SIZE - sizeof(*read_ptr)))
+		return -ENODATA;
+
+	packet_size =3D *read_ptr;
+	if (!packet_size)
+		return -EINVAL;
+
+	new_read_idx =3D read_idx + packet_size;
+	if (packet_size <=3D IFACEQ_CORE_PKT_SIZE) {
+		if (new_read_idx < IFACEQ_QUEUE_SIZE) {
+			memcpy(packet, read_ptr, packet_size);
+		} else {
+			residue =3D new_read_idx - IFACEQ_QUEUE_SIZE;
+			memcpy(packet, read_ptr, (packet_size - residue));
+			memcpy((packet + (packet_size - residue)),
+			       qinfo->kernel_vaddr, residue);
+			new_read_idx =3D residue;
+		}
+	} else {
+		new_read_idx =3D write_idx;
+		ret =3D -EBADMSG;
+	}
+
+	queue->rx_req =3D receive_request;
+
+	queue->read_idx =3D new_read_idx / sizeof(u32);
+	/* Ensure qhdr is updated in main memory */
+	mb();
+
+	return ret;
+}
+
+int iris_hfi_queue_cmd_write_locked(struct iris_core *core, void *pkt, u32=
 pkt_size)
+{
+	struct iris_iface_q_info *q_info =3D &core->command_queue;
+
+	if (core->state =3D=3D IRIS_CORE_ERROR)
+		return -EINVAL;
+
+	if (!iris_hfi_queue_write(q_info, pkt, pkt_size)) {
+		iris_vpu_raise_interrupt(core);
+	} else {
+		dev_err(core->dev, "queue full\n");
+		return -ENODATA;
+	}
+
+	return 0;
+}
+
+int iris_hfi_queue_cmd_write(struct iris_core *core, void *pkt, u32 pkt_si=
ze)
+{
+	int ret;
+
+	mutex_lock(&core->lock);
+	ret =3D iris_hfi_queue_cmd_write_locked(core, pkt, pkt_size);
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+int iris_hfi_queue_msg_read(struct iris_core *core, void *pkt)
+{
+	struct iris_iface_q_info *q_info =3D &core->message_queue;
+	int ret =3D 0;
+
+	mutex_lock(&core->lock);
+	if (core->state !=3D IRIS_CORE_INIT) {
+		ret =3D -EINVAL;
+		goto unlock;
+	}
+
+	if (iris_hfi_queue_read(q_info, pkt)) {
+		ret =3D -ENODATA;
+		goto unlock;
+	}
+
+unlock:
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+int iris_hfi_queue_dbg_read(struct iris_core *core, void *pkt)
+{
+	struct iris_iface_q_info *q_info =3D &core->debug_queue;
+	int ret =3D 0;
+
+	mutex_lock(&core->lock);
+	if (core->state !=3D IRIS_CORE_INIT) {
+		ret =3D -EINVAL;
+		goto unlock;
+	}
+
+	if (iris_hfi_queue_read(q_info, pkt)) {
+		ret =3D -ENODATA;
+		goto unlock;
+	}
+
+unlock:
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
=20
 static void iris_hfi_queue_set_header(struct iris_core *core, u32 queue_id,
 				      struct iris_iface_q_info *iface_q)
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_queue.h b/drivers/me=
dia/platform/qcom/iris/iris_hfi_queue.h
index 99a3b83d063f..2174fc5ce618 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_queue.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_queue.h
@@ -174,4 +174,9 @@ struct iris_iface_q_info {
 int iris_hfi_queues_init(struct iris_core *core);
 void iris_hfi_queues_deinit(struct iris_core *core);
=20
+int iris_hfi_queue_cmd_write_locked(struct iris_core *core, void *pkt, u32=
 pkt_size);
+int iris_hfi_queue_cmd_write(struct iris_core *core, void *pkt, u32 pkt_si=
ze);
+int iris_hfi_queue_msg_read(struct iris_core *core, void *pkt);
+int iris_hfi_queue_dbg_read(struct iris_core *core, void *pkt);
+
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/driv=
ers/media/platform/qcom/iris/iris_platform_common.h
index 7e661e8928bd..adf639d1a109 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -6,7 +6,10 @@
 #ifndef __IRIS_PLATFORM_COMMON_H__
 #define __IRIS_PLATFORM_COMMON_H__
=20
+struct iris_core;
+
 #define IRIS_PAS_ID				9
+#define HW_RESPONSE_TIMEOUT_VALUE               (1000) /* milliseconds */
=20
 extern struct iris_platform_data sm8550_data;
=20
@@ -28,7 +31,19 @@ struct tz_cp_config {
 	u32 cp_nonpixel_size;
 };
=20
+struct ubwc_config_data {
+	u32	max_channels;
+	u32	mal_length;
+	u32	highest_bank_bit;
+	u32	bank_swzl_level;
+	u32	bank_swz2_level;
+	u32	bank_swz3_level;
+	u32	bank_spreading;
+};
+
 struct iris_platform_data {
+	void (*init_hfi_command_ops)(struct iris_core *core);
+	void (*init_hfi_response_ops)(struct iris_core *core);
 	struct iris_inst *(*get_instance)(void);
 	const struct icc_info *icc_tbl;
 	unsigned int icc_tbl_size;
@@ -45,6 +60,8 @@ struct iris_platform_data {
 	u32 pas_id;
 	struct tz_cp_config *tz_cp_config_data;
 	u32 core_arch;
+	u32 hw_response_timeout;
+	struct ubwc_config_data *ubwc_config;
 };
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/driv=
ers/media/platform/qcom/iris/iris_platform_sm8550.c
index 237f932946d6..30d9664bd419 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
@@ -26,6 +26,16 @@ static const struct platform_clk_data sm8550_clk_table[]=
 =3D {
 	{IRIS_HW_CLK,   "vcodec0_core" },
 };
=20
+static struct ubwc_config_data ubwc_config_sm8550 =3D {
+	.max_channels =3D 8,
+	.mal_length =3D 32,
+	.highest_bank_bit =3D 16,
+	.bank_swzl_level =3D 0,
+	.bank_swz2_level =3D 1,
+	.bank_swz3_level =3D 1,
+	.bank_spreading =3D 1,
+};
+
 static struct tz_cp_config tz_cp_config_sm8550 =3D {
 	.cp_start =3D 0,
 	.cp_size =3D 0x25800000,
@@ -35,6 +45,8 @@ static struct tz_cp_config tz_cp_config_sm8550 =3D {
=20
 struct iris_platform_data sm8550_data =3D {
 	.get_instance =3D iris_hfi_gen2_get_instance,
+	.init_hfi_command_ops =3D iris_hfi_gen2_command_ops_init,
+	.init_hfi_response_ops =3D iris_hfi_gen2_response_ops_init,
 	.icc_tbl =3D sm8550_icc_table,
 	.icc_tbl_size =3D ARRAY_SIZE(sm8550_icc_table),
 	.clk_rst_tbl =3D sm8550_clk_reset_table,
@@ -51,4 +63,6 @@ struct iris_platform_data sm8550_data =3D {
 	.pas_id =3D IRIS_PAS_ID,
 	.tz_cp_config_data =3D &tz_cp_config_sm8550,
 	.core_arch =3D VIDEO_ARCH_LX,
+	.hw_response_timeout =3D HW_RESPONSE_TIMEOUT_VALUE,
+	.ubwc_config =3D &ubwc_config_sm8550,
 };
diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/=
platform/qcom/iris/iris_probe.c
index 3015e6cb347f..02887b3dbe0e 100644
--- a/drivers/media/platform/qcom/iris/iris_probe.c
+++ b/drivers/media/platform/qcom/iris/iris_probe.c
@@ -177,6 +177,15 @@ static void iris_remove(struct platform_device *pdev)
 	mutex_destroy(&core->lock);
 }
=20
+static void iris_sys_error_handler(struct work_struct *work)
+{
+	struct iris_core *core =3D
+			container_of(work, struct iris_core, sys_error_handler.work);
+
+	iris_core_deinit(core);
+	iris_core_init(core);
+}
+
 static int iris_probe(struct platform_device *pdev)
 {
 	struct device *dev =3D &pdev->dev;
@@ -191,6 +200,13 @@ static int iris_probe(struct platform_device *pdev)
=20
 	core->state =3D IRIS_CORE_DEINIT;
 	mutex_init(&core->lock);
+	init_completion(&core->core_init_done);
+
+	core->response_packet =3D devm_kzalloc(core->dev, IFACEQ_CORE_PKT_SIZE, G=
FP_KERNEL);
+	if (!core->response_packet)
+		return -ENOMEM;
+
+	INIT_DELAYED_WORK(&core->sys_error_handler, iris_sys_error_handler);
=20
 	core->reg_base =3D devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(core->reg_base))
@@ -202,7 +218,17 @@ static int iris_probe(struct platform_device *pdev)
=20
 	core->iris_platform_data =3D of_device_get_match_data(core->dev);
=20
+	ret =3D devm_request_threaded_irq(core->dev, core->irq, iris_hfi_isr,
+					iris_hfi_isr_handler, IRQF_TRIGGER_HIGH, "iris", core);
+	if (ret)
+		return ret;
+
+	disable_irq_nosync(core->irq);
+
 	iris_init_ops(core);
+	core->iris_platform_data->init_hfi_command_ops(core);
+	core->iris_platform_data->init_hfi_response_ops(core);
+
 	ret =3D iris_init_resources(core);
 	if (ret)
 		return ret;
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/m=
edia/platform/qcom/iris/iris_vpu_common.c
index 959ed46e8f47..34817573f61b 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_common.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c
@@ -11,10 +11,15 @@
 #define CPU_BASE_OFFS				0x000A0000
=20
 #define CPU_CS_BASE_OFFS			(CPU_BASE_OFFS)
+#define CPU_IC_BASE_OFFS			(CPU_BASE_OFFS)
+
+#define CPU_CS_A2HSOFTINTCLR			(CPU_CS_BASE_OFFS + 0x1C)
+#define CLEAR_XTENSA2HOST_INTR			BIT(0)
=20
 #define CTRL_INIT				(CPU_CS_BASE_OFFS + 0x48)
 #define CTRL_STATUS				(CPU_CS_BASE_OFFS + 0x4C)
=20
+#define CTRL_INIT_IDLE_MSG_BMSK			0x40000000
 #define CTRL_ERROR_STATUS__M			0xfe
=20
 #define QTBL_INFO				(CPU_CS_BASE_OFFS + 0x50)
@@ -31,6 +36,14 @@
=20
 #define CPU_CS_X2RPMH				(CPU_CS_BASE_OFFS + 0x168)
=20
+#define CPU_IC_SOFTINT				(CPU_IC_BASE_OFFS + 0x150)
+#define CPU_IC_SOFTINT_H2A_SHFT			0x0
+
+#define WRAPPER_BASE_OFFS			0x000B0000
+#define WRAPPER_INTR_STATUS			(WRAPPER_BASE_OFFS + 0x0C)
+#define WRAPPER_INTR_STATUS_A2HWD_BMSK		BIT(3)
+#define WRAPPER_INTR_STATUS_A2H_BMSK		BIT(2)
+
 static void iris_vpu_setup_ucregion_memory_map(struct iris_core *core)
 {
 	u32 queue_size, value;
@@ -87,3 +100,33 @@ int iris_vpu_boot_firmware(struct iris_core *core)
=20
 	return 0;
 }
+
+void iris_vpu_raise_interrupt(struct iris_core *core)
+{
+	writel(1 << CPU_IC_SOFTINT_H2A_SHFT, core->reg_base + CPU_IC_SOFTINT);
+}
+
+void iris_vpu_clear_interrupt(struct iris_core *core)
+{
+	u32 intr_status, mask;
+
+	intr_status =3D readl(core->reg_base + WRAPPER_INTR_STATUS);
+	mask =3D (WRAPPER_INTR_STATUS_A2H_BMSK |
+		WRAPPER_INTR_STATUS_A2HWD_BMSK |
+		CTRL_INIT_IDLE_MSG_BMSK);
+
+	if (intr_status & mask)
+		core->intr_status |=3D intr_status;
+
+	writel(CLEAR_XTENSA2HOST_INTR, core->reg_base + CPU_CS_A2HSOFTINTCLR);
+}
+
+int iris_vpu_watchdog(struct iris_core *core, u32 intr_status)
+{
+	if (intr_status & WRAPPER_INTR_STATUS_A2HWD_BMSK) {
+		dev_err(core->dev, "received watchdog interrupt\n");
+		return -ETIME;
+	}
+
+	return 0;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/m=
edia/platform/qcom/iris/iris_vpu_common.h
index bafcf46520fd..c38c055d3d14 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_common.h
+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h
@@ -9,5 +9,8 @@
 struct iris_core;
=20
 int iris_vpu_boot_firmware(struct iris_core *core);
+void iris_vpu_raise_interrupt(struct iris_core *core);
+void iris_vpu_clear_interrupt(struct iris_core *core);
+int iris_vpu_watchdog(struct iris_core *core, u32 intr_status);
=20
 #endif

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 500B6235376;
	Fri,  7 Feb 2025 07:56:11 +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=1738914974; cv=none;
 b=mzXlCYMKF/Kndn2Vxvj8oET0yzkbR4Y1RDT23Cyw5/uDo2+R66WE12sCPyPCQgshHBY2yMdUOqIx0XGeFYtOdoSbv14wcLa7pZth7VcE8pTE0ymymRwVo/Tm+HqW9SjCU0yJ/z2xW9VATvPvqnmdDR9wUFojR+kCbWS3kw/yXzA=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738914974; c=relaxed/simple;
	bh=1QAggecGksWdlobuc57svDzMa9sSzWe3BnSLUy9d2tk=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=RGPEOlF6A+GykBb9DXwbvxRLBL0ZawD7FqgF32fE31dSX958WGUVSHrUapb/d5yHFBjiE/7sbDZ646oeFx4fuog0CzXadF6lyaQbGqS6P6BOMWISnu6qvFv28WK6yudb1dv7KZ1mhEup/564Y7+s4diJS8WxyYrOOnN9G1MbbgI=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=Bls4dXgL; arc=none smtp.client-ip=205.220.168.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="Bls4dXgL"
Received: from pps.filterd (m0279867.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 51770cKg030044;
	Fri, 7 Feb 2025 07:55:54 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	zlofIzsIlw6/PBlZeWddps8hqHMevs+RPFhsHsuHqOU=; b=Bls4dXgL4YU1xAmV
	LvNXjoiHxakoHb7Vlp3n5OVu+myaA2M4OSEfrNoz4KnZBzHZNzheg7FejYdOiPil
	n9AAypArASF+qnvdV1kEkfkO4DPsuTb2tzSktiO1lO6079UnwvzWgfmo/JqCRGI3
	ia9IKxtZ+orM3ibU/Yt8qZSY4viUmvMTJoivdLcp7uQ7okxIymRU2NZWk37fPEnW
	en1M+UgovJpo8SrWBVpfzKyhF617gDO7JnD+/dbBhKpgm57pi3eVDIQ5OQ0XtJut
	C0gx3eE8PFFDPKTVFv2L1rqJIMGUJT5HiLDmlMxjgBdpmJDlqBj7xhrV16x9M+lh
	A8+UdQ==
Received: from nalasppmta02.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44nddjg450-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:55:54 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA02.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177trwW029391
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:55:53 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:55:47 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:24:48 +0530
Subject: [PATCH v10 08/28] media: iris: implement power management
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-8-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914892; l=38835;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=1QAggecGksWdlobuc57svDzMa9sSzWe3BnSLUy9d2tk=;
 b=aRr2MLKvrIbSkWg7MzhXRp0cZ6O86o9vQJkLobyyflhqsGFY3VKmuq1M157F/6Z+ijQ6Q7De4
 9GIG0YHVQYDCAoLIMkJlK8Y8co0kZrDLDqzB02RiapUJcBjtUax74dx
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-ORIG-GUID: PTPVek7HAqU-CdFCrxgvDytEAHxMbXly
X-Proofpoint-GUID: PTPVek7HAqU-CdFCrxgvDytEAHxMbXly
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 mlxscore=0 impostorscore=0
 adultscore=0 bulkscore=0 phishscore=0 malwarescore=0 lowpriorityscore=0
 mlxlogscore=999 priorityscore=1501 clxscore=1015 suspectscore=0
 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070060

Implement runtime power management for iris, including a platform
specific power on/off sequence.

Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 drivers/media/platform/qcom/iris/Makefile          |   3 +
 drivers/media/platform/qcom/iris/iris_core.c       |  15 +-
 drivers/media/platform/qcom/iris/iris_core.h       |   4 +
 drivers/media/platform/qcom/iris/iris_firmware.c   |   5 +
 drivers/media/platform/qcom/iris/iris_firmware.h   |   1 +
 drivers/media/platform/qcom/iris/iris_hfi_common.c |  62 ++++++
 drivers/media/platform/qcom/iris/iris_hfi_common.h |   3 +
 .../platform/qcom/iris/iris_hfi_gen1_command.c     |  11 +
 .../platform/qcom/iris/iris_hfi_gen1_defines.h     |   5 +
 .../platform/qcom/iris/iris_hfi_gen2_command.c     |  18 ++
 .../platform/qcom/iris/iris_hfi_gen2_defines.h     |   1 +
 .../platform/qcom/iris/iris_hfi_gen2_packet.c      |  13 ++
 .../platform/qcom/iris/iris_hfi_gen2_packet.h      |   1 +
 drivers/media/platform/qcom/iris/iris_hfi_queue.c  |  18 ++
 .../platform/qcom/iris/iris_platform_common.h      |  14 ++
 .../platform/qcom/iris/iris_platform_sm8550.c      |   9 +
 drivers/media/platform/qcom/iris/iris_probe.c      |  53 +++++
 drivers/media/platform/qcom/iris/iris_resources.c  | 131 +++++++++++
 drivers/media/platform/qcom/iris/iris_resources.h  |  18 ++
 drivers/media/platform/qcom/iris/iris_vidc.c       |   8 +
 drivers/media/platform/qcom/iris/iris_vpu2.c       |  11 +
 drivers/media/platform/qcom/iris/iris_vpu3.c       |  84 +++++++
 drivers/media/platform/qcom/iris/iris_vpu_common.c | 243 +++++++++++++++++=
+++-
 drivers/media/platform/qcom/iris/iris_vpu_common.h |  11 +
 .../platform/qcom/iris/iris_vpu_register_defines.h |  17 ++
 25 files changed, 755 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/plat=
form/qcom/iris/Makefile
index 76ca5287c49f..a5f290a8c4af 100644
--- a/drivers/media/platform/qcom/iris/Makefile
+++ b/drivers/media/platform/qcom/iris/Makefile
@@ -9,7 +9,10 @@ iris-objs +=3D iris_core.o \
              iris_hfi_queue.o \
              iris_platform_sm8550.o \
              iris_probe.o \
+             iris_resources.o \
              iris_vidc.o \
+             iris_vpu2.o \
+             iris_vpu3.o \
              iris_vpu_common.o \
=20
 obj-$(CONFIG_VIDEO_QCOM_IRIS) +=3D iris.o
diff --git a/drivers/media/platform/qcom/iris/iris_core.c b/drivers/media/p=
latform/qcom/iris/iris_core.c
index 7e19bdd0a19b..0fa0a3b549a2 100644
--- a/drivers/media/platform/qcom/iris/iris_core.c
+++ b/drivers/media/platform/qcom/iris/iris_core.c
@@ -3,6 +3,8 @@
  * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
  */
=20
+#include <linux/pm_runtime.h>
+
 #include "iris_core.h"
 #include "iris_firmware.h"
 #include "iris_state.h"
@@ -10,11 +12,16 @@
=20
 void iris_core_deinit(struct iris_core *core)
 {
+	pm_runtime_resume_and_get(core->dev);
+
 	mutex_lock(&core->lock);
 	iris_fw_unload(core);
+	iris_vpu_power_off(core);
 	iris_hfi_queues_deinit(core);
 	core->state =3D IRIS_CORE_DEINIT;
 	mutex_unlock(&core->lock);
+
+	pm_runtime_put_sync(core->dev);
 }
=20
 static int iris_wait_for_system_response(struct iris_core *core)
@@ -54,10 +61,14 @@ int iris_core_init(struct iris_core *core)
 	if (ret)
 		goto error;
=20
-	ret =3D iris_fw_load(core);
+	ret =3D iris_vpu_power_on(core);
 	if (ret)
 		goto error_queue_deinit;
=20
+	ret =3D iris_fw_load(core);
+	if (ret)
+		goto error_power_off;
+
 	ret =3D iris_vpu_boot_firmware(core);
 	if (ret)
 		goto error_unload_fw;
@@ -72,6 +83,8 @@ int iris_core_init(struct iris_core *core)
=20
 error_unload_fw:
 	iris_fw_unload(core);
+error_power_off:
+	iris_vpu_power_off(core);
 error_queue_deinit:
 	iris_hfi_queues_deinit(core);
 error:
diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/p=
latform/qcom/iris/iris_core.h
index c0f3c189d779..58aab78ab2c4 100644
--- a/drivers/media/platform/qcom/iris/iris_core.h
+++ b/drivers/media/platform/qcom/iris/iris_core.h
@@ -7,11 +7,13 @@
 #define __IRIS_CORE_H__
=20
 #include <linux/types.h>
+#include <linux/pm_domain.h>
 #include <media/v4l2-device.h>
=20
 #include "iris_hfi_common.h"
 #include "iris_hfi_queue.h"
 #include "iris_platform_common.h"
+#include "iris_resources.h"
 #include "iris_state.h"
=20
 struct icc_info {
@@ -52,6 +54,7 @@ struct icc_info {
  * @response_packet: a pointer to response packet from fw to driver
  * @header_id: id of packet header
  * @packet_id: id of packet
+ * @power: a structure for clock and bw information
  * @hfi_ops: iris hfi command ops
  * @hfi_response_ops: iris hfi response ops
  * @core_init_done: structure of signal completion for system response
@@ -86,6 +89,7 @@ struct iris_core {
 	u8					*response_packet;
 	u32					header_id;
 	u32					packet_id;
+	struct iris_core_power			power;
 	const struct iris_hfi_command_ops	*hfi_ops;
 	const struct iris_hfi_response_ops	*hfi_response_ops;
 	struct completion			core_init_done;
diff --git a/drivers/media/platform/qcom/iris/iris_firmware.c b/drivers/med=
ia/platform/qcom/iris/iris_firmware.c
index 3d14e596a471..7c493b4a75db 100644
--- a/drivers/media/platform/qcom/iris/iris_firmware.c
+++ b/drivers/media/platform/qcom/iris/iris_firmware.c
@@ -109,3 +109,8 @@ int iris_fw_unload(struct iris_core *core)
 {
 	return qcom_scm_pas_shutdown(core->iris_platform_data->pas_id);
 }
+
+int iris_set_hw_state(struct iris_core *core, bool resume)
+{
+	return qcom_scm_set_remote_state(resume, 0);
+}
diff --git a/drivers/media/platform/qcom/iris/iris_firmware.h b/drivers/med=
ia/platform/qcom/iris/iris_firmware.h
index 266bdd92a124..e833ecd34887 100644
--- a/drivers/media/platform/qcom/iris/iris_firmware.h
+++ b/drivers/media/platform/qcom/iris/iris_firmware.h
@@ -10,5 +10,6 @@ struct iris_core;
=20
 int iris_fw_load(struct iris_core *core);
 int iris_fw_unload(struct iris_core *core);
+int iris_set_hw_state(struct iris_core *core, bool resume);
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.c b/drivers/m=
edia/platform/qcom/iris/iris_hfi_common.c
index a19b988c9a88..29f56c2bf74c 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_common.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.c
@@ -3,6 +3,9 @@
  * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
  */
=20
+#include <linux/pm_runtime.h>
+
+#include "iris_firmware.h"
 #include "iris_core.h"
 #include "iris_hfi_common.h"
 #include "iris_vpu_common.h"
@@ -38,6 +41,7 @@ irqreturn_t iris_hfi_isr_handler(int irq, void *data)
 		return IRQ_NONE;
=20
 	mutex_lock(&core->lock);
+	pm_runtime_mark_last_busy(core->dev);
 	iris_vpu_clear_interrupt(core);
 	mutex_unlock(&core->lock);
=20
@@ -48,3 +52,61 @@ irqreturn_t iris_hfi_isr_handler(int irq, void *data)
=20
 	return IRQ_HANDLED;
 }
+
+int iris_hfi_pm_suspend(struct iris_core *core)
+{
+	int ret;
+
+	ret =3D iris_vpu_prepare_pc(core);
+	if (ret) {
+		pm_runtime_mark_last_busy(core->dev);
+		ret =3D -EAGAIN;
+		goto error;
+	}
+
+	ret =3D iris_set_hw_state(core, false);
+	if (ret)
+		goto error;
+
+	iris_vpu_power_off(core);
+
+	return 0;
+
+error:
+	dev_err(core->dev, "failed to suspend\n");
+
+	return ret;
+}
+
+int iris_hfi_pm_resume(struct iris_core *core)
+{
+	const struct iris_hfi_command_ops *ops =3D core->hfi_ops;
+	int ret;
+
+	ret =3D iris_vpu_power_on(core);
+	if (ret)
+		goto error;
+
+	ret =3D iris_set_hw_state(core, true);
+	if (ret)
+		goto err_power_off;
+
+	ret =3D iris_vpu_boot_firmware(core);
+	if (ret)
+		goto err_suspend_hw;
+
+	ret =3D ops->sys_interframe_powercollapse(core);
+	if (ret)
+		goto err_suspend_hw;
+
+	return 0;
+
+err_suspend_hw:
+	iris_set_hw_state(core, false);
+err_power_off:
+	iris_vpu_power_off(core);
+error:
+	dev_err(core->dev, "failed to resume\n");
+
+	return -EBUSY;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/m=
edia/platform/qcom/iris/iris_hfi_common.h
index b46a2f21102a..36673aafe1c9 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_common.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h
@@ -46,6 +46,7 @@ struct iris_hfi_command_ops {
 	int (*sys_init)(struct iris_core *core);
 	int (*sys_image_version)(struct iris_core *core);
 	int (*sys_interframe_powercollapse)(struct iris_core *core);
+	int (*sys_pc_prep)(struct iris_core *core);
 };
=20
 struct iris_hfi_response_ops {
@@ -53,6 +54,8 @@ struct iris_hfi_response_ops {
 };
=20
 int iris_hfi_core_init(struct iris_core *core);
+int iris_hfi_pm_suspend(struct iris_core *core);
+int iris_hfi_pm_resume(struct iris_core *core);
=20
 irqreturn_t iris_hfi_isr(int irq, void *data);
 irqreturn_t iris_hfi_isr_handler(int irq, void *data);
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen1_command.c
index 07007d8812ba..b2e76d1dcbf7 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
@@ -56,10 +56,21 @@ static int iris_hfi_gen1_sys_interframe_powercollapse(s=
truct iris_core *core)
 	return ret;
 }
=20
+static int iris_hfi_gen1_sys_pc_prep(struct iris_core *core)
+{
+	struct hfi_sys_pc_prep_pkt pkt;
+
+	pkt.hdr.size =3D sizeof(struct hfi_sys_pc_prep_pkt);
+	pkt.hdr.pkt_type =3D HFI_CMD_SYS_PC_PREP;
+
+	return iris_hfi_queue_cmd_write_locked(core, &pkt, pkt.hdr.size);
+}
+
 static const struct iris_hfi_command_ops iris_hfi_gen1_command_ops =3D {
 	.sys_init =3D iris_hfi_gen1_sys_init,
 	.sys_image_version =3D iris_hfi_gen1_sys_image_version,
 	.sys_interframe_powercollapse =3D iris_hfi_gen1_sys_interframe_powercolla=
pse,
+	.sys_pc_prep =3D iris_hfi_gen1_sys_pc_prep,
 };
=20
 void iris_hfi_gen1_command_ops_init(struct iris_core *core)
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
index 8af824a42bcf..81685a284f23 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
@@ -12,6 +12,7 @@
 #define HFI_ERR_NONE					0x0
=20
 #define HFI_CMD_SYS_INIT				0x10001
+#define HFI_CMD_SYS_PC_PREP				0x10002
 #define HFI_CMD_SYS_SET_PROPERTY			0x10005
 #define HFI_CMD_SYS_GET_PROPERTY			0x10006
=20
@@ -48,6 +49,10 @@ struct hfi_sys_get_property_pkt {
 	u32 data;
 };
=20
+struct hfi_sys_pc_prep_pkt {
+	struct hfi_pkt_hdr hdr;
+};
+
 struct hfi_msg_event_notify_pkt {
 	struct hfi_pkt_hdr hdr;
 	u32 event_id;
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen2_command.c
index 5eaebe170214..f8cb1177ef54 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
@@ -68,10 +68,28 @@ static int iris_hfi_gen2_sys_interframe_powercollapse(s=
truct iris_core *core)
 	return ret;
 }
=20
+static int iris_hfi_gen2_sys_pc_prep(struct iris_core *core)
+{
+	struct iris_hfi_header *hdr;
+	int ret;
+
+	hdr =3D kzalloc(SYS_NO_PAYLOAD_PKT_SIZE, GFP_KERNEL);
+	if (!hdr)
+		return -ENOMEM;
+
+	iris_hfi_gen2_packet_sys_pc_prep(core, hdr);
+	ret =3D iris_hfi_queue_cmd_write_locked(core, hdr, hdr->size);
+
+	kfree(hdr);
+
+	return ret;
+}
+
 static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops =3D {
 	.sys_init =3D iris_hfi_gen2_sys_init,
 	.sys_image_version =3D iris_hfi_gen2_sys_image_version,
 	.sys_interframe_powercollapse =3D iris_hfi_gen2_sys_interframe_powercolla=
pse,
+	.sys_pc_prep =3D iris_hfi_gen2_sys_pc_prep,
 };
=20
 void iris_hfi_gen2_command_ops_init(struct iris_core *core)
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
index 2640caa7f9c0..e6a19ffc12fb 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
@@ -12,6 +12,7 @@
=20
 #define HFI_CMD_BEGIN				0x01000000
 #define HFI_CMD_INIT				0x01000001
+#define HFI_CMD_POWER_COLLAPSE			0x01000002
 #define HFI_CMD_END				0x01FFFFFF
=20
 #define HFI_PROP_BEGIN				0x03000000
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c b/driv=
ers/media/platform/qcom/iris/iris_hfi_gen2_packet.c
index 986013aa62df..510d44408b41 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c
@@ -159,3 +159,16 @@ void iris_hfi_gen2_packet_sys_interframe_powercollapse=
(struct iris_core *core,
 				    &payload,
 				    sizeof(u32));
 }
+
+void iris_hfi_gen2_packet_sys_pc_prep(struct iris_core *core, struct iris_=
hfi_header *hdr)
+{
+	iris_hfi_gen2_create_header(hdr, 0 /*session_id*/, core->header_id++);
+
+	iris_hfi_gen2_create_packet(hdr,
+				    HFI_CMD_POWER_COLLAPSE,
+				    HFI_HOST_FLAGS_NONE,
+				    HFI_PAYLOAD_NONE,
+				    HFI_PORT_NONE,
+				    core->packet_id++,
+				    NULL, 0);
+}
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h b/driv=
ers/media/platform/qcom/iris/iris_hfi_gen2_packet.h
index 10dcb6e4c3d9..3b771b7516de 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h
@@ -65,5 +65,6 @@ void iris_hfi_gen2_packet_sys_init(struct iris_core *core=
, struct iris_hfi_heade
 void iris_hfi_gen2_packet_image_version(struct iris_core *core, struct iri=
s_hfi_header *hdr);
 void iris_hfi_gen2_packet_sys_interframe_powercollapse(struct iris_core *c=
ore,
 						       struct iris_hfi_header *hdr);
+void iris_hfi_gen2_packet_sys_pc_prep(struct iris_core *core, struct iris_=
hfi_header *hdr);
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_queue.c b/drivers/me=
dia/platform/qcom/iris/iris_hfi_queue.c
index ee245c540ce7..fac7df0c4d1a 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_queue.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_queue.c
@@ -3,6 +3,8 @@
  * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
  */
=20
+#include <linux/pm_runtime.h>
+
 #include "iris_core.h"
 #include "iris_hfi_queue.h"
 #include "iris_vpu_common.h"
@@ -128,10 +130,26 @@ int iris_hfi_queue_cmd_write(struct iris_core *core, =
void *pkt, u32 pkt_size)
 {
 	int ret;
=20
+	ret =3D pm_runtime_resume_and_get(core->dev);
+	if (ret < 0)
+		goto exit;
+
 	mutex_lock(&core->lock);
 	ret =3D iris_hfi_queue_cmd_write_locked(core, pkt, pkt_size);
+	if (ret) {
+		mutex_unlock(&core->lock);
+		goto exit;
+	}
 	mutex_unlock(&core->lock);
=20
+	pm_runtime_mark_last_busy(core->dev);
+	pm_runtime_put_autosuspend(core->dev);
+
+	return 0;
+
+exit:
+	pm_runtime_put_sync(core->dev);
+
 	return ret;
 }
=20
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/driv=
ers/media/platform/qcom/iris/iris_platform_common.h
index adf639d1a109..69c0a8b3d12d 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -10,6 +10,7 @@ struct iris_core;
=20
 #define IRIS_PAS_ID				9
 #define HW_RESPONSE_TIMEOUT_VALUE               (1000) /* milliseconds */
+#define AUTOSUSPEND_DELAY_VALUE			(HW_RESPONSE_TIMEOUT_VALUE + 500) /* mil=
liseconds */
=20
 extern struct iris_platform_data sm8550_data;
=20
@@ -41,10 +42,22 @@ struct ubwc_config_data {
 	u32	bank_spreading;
 };
=20
+struct iris_core_power {
+	u64 clk_freq;
+	u64 icc_bw;
+};
+
+enum platform_pm_domain_type {
+	IRIS_CTRL_POWER_DOMAIN,
+	IRIS_HW_POWER_DOMAIN,
+};
+
 struct iris_platform_data {
 	void (*init_hfi_command_ops)(struct iris_core *core);
 	void (*init_hfi_response_ops)(struct iris_core *core);
 	struct iris_inst *(*get_instance)(void);
+	const struct vpu_ops *vpu_ops;
+	void (*set_preset_registers)(struct iris_core *core);
 	const struct icc_info *icc_tbl;
 	unsigned int icc_tbl_size;
 	const char * const *pmdomain_tbl;
@@ -62,6 +75,7 @@ struct iris_platform_data {
 	u32 core_arch;
 	u32 hw_response_timeout;
 	struct ubwc_config_data *ubwc_config;
+	u32 num_vpp_pipe;
 };
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/driv=
ers/media/platform/qcom/iris/iris_platform_sm8550.c
index 30d9664bd419..ed99cdb13d06 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
@@ -6,9 +6,15 @@
 #include "iris_core.h"
 #include "iris_hfi_gen2.h"
 #include "iris_platform_common.h"
+#include "iris_vpu_common.h"
=20
 #define VIDEO_ARCH_LX 1
=20
+static void iris_set_sm8550_preset_registers(struct iris_core *core)
+{
+	writel(0x0, core->reg_base + 0xB0088);
+}
+
 static const struct icc_info sm8550_icc_table[] =3D {
 	{ "cpu-cfg",    1000, 1000     },
 	{ "video-mem",  1000, 15000000 },
@@ -47,6 +53,8 @@ struct iris_platform_data sm8550_data =3D {
 	.get_instance =3D iris_hfi_gen2_get_instance,
 	.init_hfi_command_ops =3D iris_hfi_gen2_command_ops_init,
 	.init_hfi_response_ops =3D iris_hfi_gen2_response_ops_init,
+	.vpu_ops =3D &iris_vpu3_ops,
+	.set_preset_registers =3D iris_set_sm8550_preset_registers,
 	.icc_tbl =3D sm8550_icc_table,
 	.icc_tbl_size =3D ARRAY_SIZE(sm8550_icc_table),
 	.clk_rst_tbl =3D sm8550_clk_reset_table,
@@ -65,4 +73,5 @@ struct iris_platform_data sm8550_data =3D {
 	.core_arch =3D VIDEO_ARCH_LX,
 	.hw_response_timeout =3D HW_RESPONSE_TIMEOUT_VALUE,
 	.ubwc_config =3D &ubwc_config_sm8550,
+	.num_vpp_pipe =3D 4,
 };
diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/=
platform/qcom/iris/iris_probe.c
index 02887b3dbe0e..e8ef258b4f2e 100644
--- a/drivers/media/platform/qcom/iris/iris_probe.c
+++ b/drivers/media/platform/qcom/iris/iris_probe.c
@@ -8,6 +8,7 @@
 #include <linux/module.h>
 #include <linux/pm_domain.h>
 #include <linux/pm_opp.h>
+#include <linux/pm_runtime.h>
 #include <linux/reset.h>
=20
 #include "iris_core.h"
@@ -252,6 +253,12 @@ static int iris_probe(struct platform_device *pdev)
 	dma_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
 	dma_set_seg_boundary(&pdev->dev, DMA_BIT_MASK(32));
=20
+	pm_runtime_set_autosuspend_delay(core->dev, AUTOSUSPEND_DELAY_VALUE);
+	pm_runtime_use_autosuspend(core->dev);
+	ret =3D devm_pm_runtime_enable(core->dev);
+	if (ret)
+		goto err_vdev_unreg;
+
 	return 0;
=20
 err_vdev_unreg:
@@ -262,6 +269,51 @@ static int iris_probe(struct platform_device *pdev)
 	return ret;
 }
=20
+static int __maybe_unused iris_pm_suspend(struct device *dev)
+{
+	struct iris_core *core;
+	int ret =3D 0;
+
+	core =3D dev_get_drvdata(dev);
+
+	mutex_lock(&core->lock);
+	if (core->state !=3D IRIS_CORE_INIT)
+		goto exit;
+
+	ret =3D iris_hfi_pm_suspend(core);
+
+exit:
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+static int __maybe_unused iris_pm_resume(struct device *dev)
+{
+	struct iris_core *core;
+	int ret =3D 0;
+
+	core =3D dev_get_drvdata(dev);
+
+	mutex_lock(&core->lock);
+	if (core->state !=3D IRIS_CORE_INIT)
+		goto exit;
+
+	ret =3D iris_hfi_pm_resume(core);
+	pm_runtime_mark_last_busy(core->dev);
+
+exit:
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+static const struct dev_pm_ops iris_pm_ops =3D {
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				pm_runtime_force_resume)
+	SET_RUNTIME_PM_OPS(iris_pm_suspend, iris_pm_resume, NULL)
+};
+
 static const struct of_device_id iris_dt_match[] =3D {
 	{
 		.compatible =3D "qcom,sm8550-iris",
@@ -277,6 +329,7 @@ static struct platform_driver qcom_iris_driver =3D {
 	.driver =3D {
 		.name =3D "qcom-iris",
 		.of_match_table =3D iris_dt_match,
+		.pm =3D &iris_pm_ops,
 	},
 };
=20
diff --git a/drivers/media/platform/qcom/iris/iris_resources.c b/drivers/me=
dia/platform/qcom/iris/iris_resources.c
new file mode 100644
index 000000000000..cf32f268b703
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_resources.c
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#include <linux/clk.h>
+#include <linux/interconnect.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_opp.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+
+#include "iris_core.h"
+#include "iris_resources.h"
+
+#define BW_THRESHOLD 50000
+
+int iris_set_icc_bw(struct iris_core *core, unsigned long icc_bw)
+{
+	unsigned long bw_kbps =3D 0, bw_prev =3D 0;
+	const struct icc_info *icc_tbl;
+	int ret =3D 0, i;
+
+	icc_tbl =3D core->iris_platform_data->icc_tbl;
+
+	for (i =3D 0; i < core->icc_count; i++) {
+		if (!strcmp(core->icc_tbl[i].name, "video-mem")) {
+			bw_kbps =3D icc_bw;
+			bw_prev =3D core->power.icc_bw;
+
+			bw_kbps =3D clamp_t(typeof(bw_kbps), bw_kbps,
+					  icc_tbl[i].bw_min_kbps, icc_tbl[i].bw_max_kbps);
+
+			if (abs(bw_kbps - bw_prev) < BW_THRESHOLD && bw_prev)
+				return ret;
+
+			core->icc_tbl[i].avg_bw =3D bw_kbps;
+
+			core->power.icc_bw =3D bw_kbps;
+			break;
+		}
+	}
+
+	return icc_bulk_set_bw(core->icc_count, core->icc_tbl);
+}
+
+int iris_unset_icc_bw(struct iris_core *core)
+{
+	u32 i;
+
+	core->power.icc_bw =3D 0;
+
+	for (i =3D 0; i < core->icc_count; i++) {
+		core->icc_tbl[i].avg_bw =3D 0;
+		core->icc_tbl[i].peak_bw =3D 0;
+	}
+
+	return icc_bulk_set_bw(core->icc_count, core->icc_tbl);
+}
+
+int iris_enable_power_domains(struct iris_core *core, struct device *pd_de=
v)
+{
+	int ret;
+
+	ret =3D dev_pm_opp_set_rate(core->dev, ULONG_MAX);
+	if (ret)
+		return ret;
+
+	ret =3D pm_runtime_get_sync(pd_dev);
+	if (ret < 0)
+		return ret;
+
+	return ret;
+}
+
+int iris_disable_power_domains(struct iris_core *core, struct device *pd_d=
ev)
+{
+	int ret;
+
+	ret =3D dev_pm_opp_set_rate(core->dev, 0);
+	if (ret)
+		return ret;
+
+	pm_runtime_put_sync(pd_dev);
+
+	return 0;
+}
+
+static struct clk *iris_get_clk_by_type(struct iris_core *core, enum platf=
orm_clk_type clk_type)
+{
+	const struct platform_clk_data *clk_tbl;
+	u32 clk_cnt, i, j;
+
+	clk_tbl =3D core->iris_platform_data->clk_tbl;
+	clk_cnt =3D core->iris_platform_data->clk_tbl_size;
+
+	for (i =3D 0; i < clk_cnt; i++) {
+		if (clk_tbl[i].clk_type =3D=3D clk_type) {
+			for (j =3D 0; core->clock_tbl && j < core->clk_count; j++) {
+				if (!strcmp(core->clock_tbl[j].id, clk_tbl[i].clk_name))
+					return core->clock_tbl[j].clk;
+			}
+		}
+	}
+
+	return NULL;
+}
+
+int iris_prepare_enable_clock(struct iris_core *core, enum platform_clk_ty=
pe clk_type)
+{
+	struct clk *clock;
+
+	clock =3D iris_get_clk_by_type(core, clk_type);
+	if (!clock)
+		return -EINVAL;
+
+	return clk_prepare_enable(clock);
+}
+
+int iris_disable_unprepare_clock(struct iris_core *core, enum platform_clk=
_type clk_type)
+{
+	struct clk *clock;
+
+	clock =3D iris_get_clk_by_type(core, clk_type);
+	if (!clock)
+		return -EINVAL;
+
+	clk_disable_unprepare(clock);
+
+	return 0;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_resources.h b/drivers/me=
dia/platform/qcom/iris/iris_resources.h
new file mode 100644
index 000000000000..f723dfe5bd81
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_resources.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#ifndef __IRIS_RESOURCES_H__
+#define __IRIS_RESOURCES_H__
+
+struct iris_core;
+
+int iris_enable_power_domains(struct iris_core *core, struct device *pd_de=
v);
+int iris_disable_power_domains(struct iris_core *core, struct device *pd_d=
ev);
+int iris_unset_icc_bw(struct iris_core *core);
+int iris_set_icc_bw(struct iris_core *core, unsigned long icc_bw);
+int iris_disable_unprepare_clock(struct iris_core *core, enum platform_clk=
_type clk_type);
+int iris_prepare_enable_clock(struct iris_core *core, enum platform_clk_ty=
pe clk_type);
+
+#endif
diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/p=
latform/qcom/iris/iris_vidc.c
index 5dd0ccbaa2fb..b8654e73f516 100644
--- a/drivers/media/platform/qcom/iris/iris_vidc.c
+++ b/drivers/media/platform/qcom/iris/iris_vidc.c
@@ -3,6 +3,7 @@
  * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
  */
=20
+#include <linux/pm_runtime.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-mem2mem.h>
=20
@@ -81,12 +82,19 @@ int iris_open(struct file *filp)
 	struct iris_inst *inst;
 	int ret;
=20
+	ret =3D pm_runtime_resume_and_get(core->dev);
+	if (ret < 0)
+		return ret;
+
 	ret =3D iris_core_init(core);
 	if (ret) {
 		dev_err(core->dev, "core init failed\n");
+		pm_runtime_put_sync(core->dev);
 		return ret;
 	}
=20
+	pm_runtime_put_sync(core->dev);
+
 	inst =3D core->iris_platform_data->get_instance();
 	if (!inst)
 		return -ENOMEM;
diff --git a/drivers/media/platform/qcom/iris/iris_vpu2.c b/drivers/media/p=
latform/qcom/iris/iris_vpu2.c
new file mode 100644
index 000000000000..bd8427411576
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_vpu2.c
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#include "iris_instance.h"
+#include "iris_vpu_common.h"
+
+const struct vpu_ops iris_vpu2_ops =3D {
+	.power_off_hw =3D iris_vpu_power_off_hw,
+};
diff --git a/drivers/media/platform/qcom/iris/iris_vpu3.c b/drivers/media/p=
latform/qcom/iris/iris_vpu3.c
new file mode 100644
index 000000000000..10599f1fa789
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_vpu3.c
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#include <linux/iopoll.h>
+
+#include "iris_instance.h"
+#include "iris_vpu_common.h"
+#include "iris_vpu_register_defines.h"
+
+#define AON_MVP_NOC_RESET			0x0001F000
+
+#define WRAPPER_CORE_CLOCK_CONFIG		(WRAPPER_BASE_OFFS + 0x88)
+#define CORE_CLK_RUN				0x0
+
+#define CPU_CS_AHB_BRIDGE_SYNC_RESET		(CPU_CS_BASE_OFFS + 0x160)
+#define CORE_BRIDGE_SW_RESET			BIT(0)
+#define CORE_BRIDGE_HW_RESET_DISABLE		BIT(1)
+
+#define AON_WRAPPER_MVP_NOC_RESET_REQ		(AON_MVP_NOC_RESET + 0x000)
+#define VIDEO_NOC_RESET_REQ			(BIT(0) | BIT(1))
+
+#define AON_WRAPPER_MVP_NOC_RESET_ACK		(AON_MVP_NOC_RESET + 0x004)
+
+#define VCODEC_SS_IDLE_STATUSN			(VCODEC_BASE_OFFS + 0x70)
+
+static bool iris_vpu3_hw_power_collapsed(struct iris_core *core)
+{
+	u32 value, pwr_status;
+
+	value =3D readl(core->reg_base + WRAPPER_CORE_POWER_STATUS);
+	pwr_status =3D value & BIT(1);
+
+	return pwr_status ? false : true;
+}
+
+static void iris_vpu3_power_off_hardware(struct iris_core *core)
+{
+	u32 reg_val =3D 0, value, i;
+	int ret;
+
+	if (iris_vpu3_hw_power_collapsed(core))
+		goto disable_power;
+
+	dev_err(core->dev, "video hw is power on\n");
+
+	value =3D readl(core->reg_base + WRAPPER_CORE_CLOCK_CONFIG);
+	if (value)
+		writel(CORE_CLK_RUN, core->reg_base + WRAPPER_CORE_CLOCK_CONFIG);
+
+	for (i =3D 0; i < core->iris_platform_data->num_vpp_pipe; i++) {
+		ret =3D readl_poll_timeout(core->reg_base + VCODEC_SS_IDLE_STATUSN + 4 *=
 i,
+					 reg_val, reg_val & 0x400000, 2000, 20000);
+		if (ret)
+			goto disable_power;
+	}
+
+	writel(VIDEO_NOC_RESET_REQ, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_RE=
Q);
+
+	ret =3D readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_RESET_ACK,
+				 reg_val, reg_val & 0x3, 200, 2000);
+	if (ret)
+		goto disable_power;
+
+	writel(0x0, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_REQ);
+
+	ret =3D readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_RESET_ACK,
+				 reg_val, !(reg_val & 0x3), 200, 2000);
+	if (ret)
+		goto disable_power;
+
+	writel(CORE_BRIDGE_SW_RESET | CORE_BRIDGE_HW_RESET_DISABLE,
+	       core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
+	writel(CORE_BRIDGE_HW_RESET_DISABLE, core->reg_base + CPU_CS_AHB_BRIDGE_S=
YNC_RESET);
+	writel(0x0, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
+
+disable_power:
+	iris_vpu_power_off_hw(core);
+}
+
+const struct vpu_ops iris_vpu3_ops =3D {
+	.power_off_hw =3D iris_vpu3_power_off_hardware,
+};
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/m=
edia/platform/qcom/iris/iris_vpu_common.c
index 34817573f61b..fe9896d66848 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_common.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c
@@ -4,13 +4,16 @@
  */
=20
 #include <linux/iopoll.h>
+#include <linux/pm_opp.h>
+#include <linux/reset.h>
=20
 #include "iris_core.h"
 #include "iris_vpu_common.h"
+#include "iris_vpu_register_defines.h"
=20
-#define CPU_BASE_OFFS				0x000A0000
+#define WRAPPER_TZ_BASE_OFFS			0x000C0000
+#define AON_BASE_OFFS				0x000E0000
=20
-#define CPU_CS_BASE_OFFS			(CPU_BASE_OFFS)
 #define CPU_IC_BASE_OFFS			(CPU_BASE_OFFS)
=20
 #define CPU_CS_A2HSOFTINTCLR			(CPU_CS_BASE_OFFS + 0x1C)
@@ -21,6 +24,7 @@
=20
 #define CTRL_INIT_IDLE_MSG_BMSK			0x40000000
 #define CTRL_ERROR_STATUS__M			0xfe
+#define CTRL_STATUS_PC_READY			0x100
=20
 #define QTBL_INFO				(CPU_CS_BASE_OFFS + 0x50)
 #define QTBL_ENABLE				BIT(0)
@@ -35,15 +39,48 @@
 #define HOST2XTENSA_INTR_ENABLE			BIT(0)
=20
 #define CPU_CS_X2RPMH				(CPU_CS_BASE_OFFS + 0x168)
+#define MSK_SIGNAL_FROM_TENSILICA		BIT(0)
+#define MSK_CORE_POWER_ON			BIT(1)
=20
 #define CPU_IC_SOFTINT				(CPU_IC_BASE_OFFS + 0x150)
 #define CPU_IC_SOFTINT_H2A_SHFT			0x0
=20
-#define WRAPPER_BASE_OFFS			0x000B0000
 #define WRAPPER_INTR_STATUS			(WRAPPER_BASE_OFFS + 0x0C)
 #define WRAPPER_INTR_STATUS_A2HWD_BMSK		BIT(3)
 #define WRAPPER_INTR_STATUS_A2H_BMSK		BIT(2)
=20
+#define WRAPPER_INTR_MASK			(WRAPPER_BASE_OFFS + 0x10)
+#define WRAPPER_INTR_MASK_A2HWD_BMSK		BIT(3)
+#define WRAPPER_INTR_MASK_A2HCPU_BMSK		BIT(2)
+
+#define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL	(WRAPPER_BASE_OFFS + 0x54)
+#define WRAPPER_DEBUG_BRIDGE_LPI_STATUS		(WRAPPER_BASE_OFFS + 0x58)
+#define WRAPPER_IRIS_CPU_NOC_LPI_CONTROL	(WRAPPER_BASE_OFFS + 0x5C)
+#define WRAPPER_IRIS_CPU_NOC_LPI_STATUS		(WRAPPER_BASE_OFFS + 0x60)
+
+#define WRAPPER_TZ_CPU_STATUS			(WRAPPER_TZ_BASE_OFFS + 0x10)
+#define WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG		(WRAPPER_TZ_BASE_OFFS + 0x14)
+#define CTL_AXI_CLK_HALT			BIT(0)
+#define CTL_CLK_HALT				BIT(1)
+
+#define WRAPPER_TZ_QNS4PDXFIFO_RESET		(WRAPPER_TZ_BASE_OFFS + 0x18)
+#define RESET_HIGH				BIT(0)
+
+#define AON_WRAPPER_MVP_NOC_LPI_CONTROL		(AON_BASE_OFFS)
+#define REQ_POWER_DOWN_PREP			BIT(0)
+
+#define AON_WRAPPER_MVP_NOC_LPI_STATUS		(AON_BASE_OFFS + 0x4)
+
+static void iris_vpu_interrupt_init(struct iris_core *core)
+{
+	u32 mask_val;
+
+	mask_val =3D readl(core->reg_base + WRAPPER_INTR_MASK);
+	mask_val &=3D ~(WRAPPER_INTR_MASK_A2HWD_BMSK |
+		      WRAPPER_INTR_MASK_A2HCPU_BMSK);
+	writel(mask_val, core->reg_base + WRAPPER_INTR_MASK);
+}
+
 static void iris_vpu_setup_ucregion_memory_map(struct iris_core *core)
 {
 	u32 queue_size, value;
@@ -130,3 +167,203 @@ int iris_vpu_watchdog(struct iris_core *core, u32 int=
r_status)
=20
 	return 0;
 }
+
+int iris_vpu_prepare_pc(struct iris_core *core)
+{
+	u32 wfi_status, idle_status, pc_ready;
+	u32 ctrl_status, val =3D 0;
+	int ret;
+
+	ctrl_status =3D readl(core->reg_base + CTRL_STATUS);
+	pc_ready =3D ctrl_status & CTRL_STATUS_PC_READY;
+	idle_status =3D ctrl_status & BIT(30);
+	if (pc_ready)
+		return 0;
+
+	wfi_status =3D readl(core->reg_base + WRAPPER_TZ_CPU_STATUS);
+	wfi_status &=3D BIT(0);
+	if (!wfi_status || !idle_status)
+		goto skip_power_off;
+
+	ret =3D core->hfi_ops->sys_pc_prep(core);
+	if (ret)
+		goto skip_power_off;
+
+	ret =3D readl_poll_timeout(core->reg_base + CTRL_STATUS, val,
+				 val & CTRL_STATUS_PC_READY, 250, 2500);
+	if (ret)
+		goto skip_power_off;
+
+	ret =3D readl_poll_timeout(core->reg_base + WRAPPER_TZ_CPU_STATUS,
+				 val, val & BIT(0), 250, 2500);
+	if (ret)
+		goto skip_power_off;
+
+	return 0;
+
+skip_power_off:
+	ctrl_status =3D readl(core->reg_base + CTRL_STATUS);
+	wfi_status =3D readl(core->reg_base + WRAPPER_TZ_CPU_STATUS);
+	wfi_status &=3D BIT(0);
+	dev_err(core->dev, "skip power collapse, wfi=3D%#x, idle=3D%#x, pcr=3D%#x=
, ctrl=3D%#x)\n",
+		wfi_status, idle_status, pc_ready, ctrl_status);
+
+	return -EAGAIN;
+}
+
+static int iris_vpu_power_off_controller(struct iris_core *core)
+{
+	u32 val =3D 0;
+	int ret;
+
+	writel(MSK_SIGNAL_FROM_TENSILICA | MSK_CORE_POWER_ON, core->reg_base + CP=
U_CS_X2RPMH);
+
+	writel(REQ_POWER_DOWN_PREP, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONT=
ROL);
+
+	ret =3D readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATU=
S,
+				 val, val & BIT(0), 200, 2000);
+	if (ret)
+		goto disable_power;
+
+	writel(REQ_POWER_DOWN_PREP, core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_CON=
TROL);
+
+	ret =3D readl_poll_timeout(core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_STAT=
US,
+				 val, val & BIT(0), 200, 2000);
+	if (ret)
+		goto disable_power;
+
+	writel(0x0, core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_CONTROL);
+
+	ret =3D readl_poll_timeout(core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_STAT=
US,
+				 val, val =3D=3D 0, 200, 2000);
+	if (ret)
+		goto disable_power;
+
+	writel(CTL_AXI_CLK_HALT | CTL_CLK_HALT,
+	       core->reg_base + WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG);
+	writel(RESET_HIGH, core->reg_base + WRAPPER_TZ_QNS4PDXFIFO_RESET);
+	writel(0x0, core->reg_base + WRAPPER_TZ_QNS4PDXFIFO_RESET);
+	writel(0x0, core->reg_base + WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG);
+
+disable_power:
+	iris_disable_unprepare_clock(core, IRIS_CTRL_CLK);
+	iris_disable_unprepare_clock(core, IRIS_AXI_CLK);
+	iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_PO=
WER_DOMAIN]);
+
+	return 0;
+}
+
+void iris_vpu_power_off_hw(struct iris_core *core)
+{
+	dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]=
, false);
+	iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWE=
R_DOMAIN]);
+	iris_disable_unprepare_clock(core, IRIS_HW_CLK);
+}
+
+void iris_vpu_power_off(struct iris_core *core)
+{
+	dev_pm_opp_set_rate(core->dev, 0);
+	core->iris_platform_data->vpu_ops->power_off_hw(core);
+	iris_vpu_power_off_controller(core);
+	iris_unset_icc_bw(core);
+
+	if (!iris_vpu_watchdog(core, core->intr_status))
+		disable_irq_nosync(core->irq);
+}
+
+static int iris_vpu_power_on_controller(struct iris_core *core)
+{
+	u32 rst_tbl_size =3D core->iris_platform_data->clk_rst_tbl_size;
+	int ret;
+
+	ret =3D iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_=
CTRL_POWER_DOMAIN]);
+	if (ret)
+		return ret;
+
+	ret =3D reset_control_bulk_reset(rst_tbl_size, core->resets);
+	if (ret)
+		goto err_disable_power;
+
+	ret =3D iris_prepare_enable_clock(core, IRIS_AXI_CLK);
+	if (ret)
+		goto err_disable_power;
+
+	ret =3D iris_prepare_enable_clock(core, IRIS_CTRL_CLK);
+	if (ret)
+		goto err_disable_clock;
+
+	return 0;
+
+err_disable_clock:
+	iris_disable_unprepare_clock(core, IRIS_AXI_CLK);
+err_disable_power:
+	iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_PO=
WER_DOMAIN]);
+
+	return ret;
+}
+
+static int iris_vpu_power_on_hw(struct iris_core *core)
+{
+	int ret;
+
+	ret =3D iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_=
HW_POWER_DOMAIN]);
+	if (ret)
+		return ret;
+
+	ret =3D iris_prepare_enable_clock(core, IRIS_HW_CLK);
+	if (ret)
+		goto err_disable_power;
+
+	ret =3D dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER=
_DOMAIN], true);
+	if (ret)
+		goto err_disable_clock;
+
+	return 0;
+
+err_disable_clock:
+	iris_disable_unprepare_clock(core, IRIS_HW_CLK);
+err_disable_power:
+	iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWE=
R_DOMAIN]);
+
+	return ret;
+}
+
+int iris_vpu_power_on(struct iris_core *core)
+{
+	u32 freq;
+	int ret;
+
+	ret =3D iris_set_icc_bw(core, INT_MAX);
+	if (ret)
+		goto err;
+
+	ret =3D iris_vpu_power_on_controller(core);
+	if (ret)
+		goto err_unvote_icc;
+
+	ret =3D iris_vpu_power_on_hw(core);
+	if (ret)
+		goto err_power_off_ctrl;
+
+	freq =3D core->power.clk_freq ? core->power.clk_freq :
+				      (u32)ULONG_MAX;
+
+	dev_pm_opp_set_rate(core->dev, freq);
+
+	core->iris_platform_data->set_preset_registers(core);
+
+	iris_vpu_interrupt_init(core);
+	core->intr_status =3D 0;
+	enable_irq(core->irq);
+
+	return 0;
+
+err_power_off_ctrl:
+	iris_vpu_power_off_controller(core);
+err_unvote_icc:
+	iris_unset_icc_bw(core);
+err:
+	dev_err(core->dev, "power on failed\n");
+
+	return ret;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/m=
edia/platform/qcom/iris/iris_vpu_common.h
index c38c055d3d14..d3efa7c0ce9a 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_common.h
+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h
@@ -8,9 +8,20 @@
=20
 struct iris_core;
=20
+extern const struct vpu_ops iris_vpu2_ops;
+extern const struct vpu_ops iris_vpu3_ops;
+
+struct vpu_ops {
+	void (*power_off_hw)(struct iris_core *core);
+};
+
 int iris_vpu_boot_firmware(struct iris_core *core);
 void iris_vpu_raise_interrupt(struct iris_core *core);
 void iris_vpu_clear_interrupt(struct iris_core *core);
 int iris_vpu_watchdog(struct iris_core *core, u32 intr_status);
+int iris_vpu_prepare_pc(struct iris_core *core);
+int iris_vpu_power_on(struct iris_core *core);
+void iris_vpu_power_off_hw(struct iris_core *core);
+void iris_vpu_power_off(struct iris_core *core);
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_register_defines.h b=
/drivers/media/platform/qcom/iris/iris_vpu_register_defines.h
new file mode 100644
index 000000000000..fe8a39e5e5a3
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_vpu_register_defines.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#ifndef __IRIS_VPU_REGISTER_DEFINES_H__
+#define __IRIS_VPU_REGISTER_DEFINES_H__
+
+#define VCODEC_BASE_OFFS			0x00000000
+#define CPU_BASE_OFFS				0x000A0000
+#define WRAPPER_BASE_OFFS			0x000B0000
+
+#define CPU_CS_BASE_OFFS			(CPU_BASE_OFFS)
+
+#define WRAPPER_CORE_POWER_STATUS		(WRAPPER_BASE_OFFS + 0x80)
+
+#endif

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 0A2E8239586;
	Fri,  7 Feb 2025 07:56:18 +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=1738914982; cv=none;
 b=nFSh+i3NVYx/uiKkee8I94Lvmy1hxryAJly2xrMuPUMaw+qTDx3CGILTWDP95seRM4bG589pPi8QEFzXHUoaw3HVznjkRv2Hn693pgW5XJCzlsZLqlGhpYSquNNogV+gR1RmP9YpeN2KSEIZ0NttckjiEa89SGDvbalNgi575wg=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738914982; c=relaxed/simple;
	bh=i1abWfpDch0mhKaZrogBqBunRLzGslWnAXLxoD7clrQ=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=vD8U6CFTFNHit3XD/aV6V2uz7TNvL8qUxUxwJQwWpdln7xpwtWHIJhZtcFc0oZXZ2SDnV9NKSo47ANSs8sl+XWpKb4qX9iAHttuFCjeGKPHb87Bmq0acQxYMdQeXTX9gh4vLPgQwe3ReAK4DfcD5qeaK5dPjn69MXiOD0ZeN310=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=N/yCBODY; arc=none smtp.client-ip=205.220.168.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="N/yCBODY"
Received: from pps.filterd (m0279863.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 51756V7W023974;
	Fri, 7 Feb 2025 07:56:00 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	QpH3nFNVJlejrJ0sCGUPaHX2bNkSJ7gMbPc2C4Nu7lw=; b=N/yCBODYgsKYgyDZ
	BrgJZTOWX8kPNmeus2D673KkLGBdRK7JCmBqEoBSENYJlhj64JzNKVGjPxg/qj1c
	Dwt1nC9ZhZt9h9e5RB91KegRCL+2DAowrQF1CnPtV7erPH+J77M8xutoCPnj1r0h
	3NavVLS56q7dOJfbRz1slCILwR6ElkNo1ESU00LYdN6BSeQGSRU0NOk7Q07nP+f1
	uceXIuNr0FXWRA1+ZbD2QltCENyRf29LfImpCwOj0ECoWFm03UTCT3TA+HMTNdH0
	tXNIPRG0icCM9t5Ixp7v+2HrsIioqbtXogvScZr2YS3kdXCi9hFXUoXaLLBPFAL8
	UUVQXA==
Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44nbr40cee-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:56:00 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA05.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177txHC027666
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:55:59 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:55:53 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:24:49 +0530
Subject: [PATCH v10 09/28] media: iris: implement reqbuf ioctl with
 vb2_queue_setup
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-9-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914893; l=54213;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=i1abWfpDch0mhKaZrogBqBunRLzGslWnAXLxoD7clrQ=;
 b=0MYuCCGXfFaLdqRgdF+GTcuvvqFX2HjEIwEBkA9UgfGmSGtWacrvfYu2x6oLsupnhAcKmqV+F
 8Aj5X61dWvSCAU3H+d7dfQFD3TZ7BPya7PdAdKesZVWiRvJAnpp+Yq6
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-GUID: 18BInWFdezZ1rhVtGXbS_mSWZUJNOkEo
X-Proofpoint-ORIG-GUID: 18BInWFdezZ1rhVtGXbS_mSWZUJNOkEo
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 priorityscore=1501
 phishscore=0 malwarescore=0 bulkscore=0 suspectscore=0 mlxscore=0
 adultscore=0 mlxlogscore=999 spamscore=0 lowpriorityscore=0 clxscore=1015
 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070059

Implement the reqbuf IOCTL op and the vb2_queue_setup vb2 op in the
driver with necessary hooks.

Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl>
Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 drivers/media/platform/qcom/iris/Makefile          |   7 +-
 drivers/media/platform/qcom/iris/iris_buffer.c     | 119 +++++++++++++++++=
++++
 drivers/media/platform/qcom/iris/iris_buffer.h     | 107 ++++++++++++++++++
 drivers/media/platform/qcom/iris/iris_core.h       |   6 ++
 drivers/media/platform/qcom/iris/iris_hfi_common.h |   3 +
 .../platform/qcom/iris/iris_hfi_gen1_command.c     |  40 +++++++
 .../platform/qcom/iris/iris_hfi_gen1_defines.h     |  47 +++++++-
 .../platform/qcom/iris/iris_hfi_gen1_response.c    |  79 +++++++++++++-
 drivers/media/platform/qcom/iris/iris_hfi_gen2.h   |   5 +
 .../platform/qcom/iris/iris_hfi_gen2_command.c     | 105 ++++++++++++++++++
 .../platform/qcom/iris/iris_hfi_gen2_defines.h     |  35 ++++++
 .../platform/qcom/iris/iris_hfi_gen2_packet.c      |  39 +++++++
 .../platform/qcom/iris/iris_hfi_gen2_packet.h      |   7 ++
 .../platform/qcom/iris/iris_hfi_gen2_response.c    | 111 +++++++++++++++++=
+-
 drivers/media/platform/qcom/iris/iris_instance.h   |  22 ++++
 .../platform/qcom/iris/iris_platform_common.h      |   5 +
 .../platform/qcom/iris/iris_platform_sm8550.c      |   6 ++
 drivers/media/platform/qcom/iris/iris_probe.c      |   2 +
 drivers/media/platform/qcom/iris/iris_utils.c      |  52 +++++++++
 drivers/media/platform/qcom/iris/iris_utils.h      |  34 ++++++
 drivers/media/platform/qcom/iris/iris_vb2.c        |  50 +++++++++
 drivers/media/platform/qcom/iris/iris_vb2.h        |  12 +++
 drivers/media/platform/qcom/iris/iris_vdec.c       |  56 ++++++++++
 drivers/media/platform/qcom/iris/iris_vdec.h       |  14 +++
 drivers/media/platform/qcom/iris/iris_vidc.c       |  81 ++++++++++++++
 drivers/media/platform/qcom/iris/iris_vpu_buffer.c |  19 ++++
 drivers/media/platform/qcom/iris/iris_vpu_buffer.h |  15 +++
 27 files changed, 1070 insertions(+), 8 deletions(-)

diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/plat=
form/qcom/iris/Makefile
index a5f290a8c4af..48ab264b7906 100644
--- a/drivers/media/platform/qcom/iris/Makefile
+++ b/drivers/media/platform/qcom/iris/Makefile
@@ -1,4 +1,5 @@
-iris-objs +=3D iris_core.o \
+iris-objs +=3D iris_buffer.o \
+             iris_core.o \
              iris_firmware.o \
              iris_hfi_common.o \
              iris_hfi_gen1_command.o \
@@ -10,9 +11,13 @@ iris-objs +=3D iris_core.o \
              iris_platform_sm8550.o \
              iris_probe.o \
              iris_resources.o \
+             iris_utils.o \
              iris_vidc.o \
+             iris_vb2.o \
+             iris_vdec.o \
              iris_vpu2.o \
              iris_vpu3.o \
+             iris_vpu_buffer.o \
              iris_vpu_common.o \
=20
 obj-$(CONFIG_VIDEO_QCOM_IRIS) +=3D iris.o
diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media=
/platform/qcom/iris/iris_buffer.c
new file mode 100644
index 000000000000..037931ce6550
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_buffer.c
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#include <media/v4l2-mem2mem.h>
+
+#include "iris_buffer.h"
+#include "iris_instance.h"
+
+#define PIXELS_4K 4096
+#define MAX_WIDTH 4096
+#define MAX_HEIGHT 2304
+#define Y_STRIDE_ALIGN 128
+#define UV_STRIDE_ALIGN 128
+#define Y_SCANLINE_ALIGN 32
+#define UV_SCANLINE_ALIGN 16
+#define UV_SCANLINE_ALIGN_QC08C 32
+#define META_STRIDE_ALIGNED 64
+#define META_SCANLINE_ALIGNED 16
+#define NUM_MBS_4K (DIV_ROUND_UP(MAX_WIDTH, 16) * DIV_ROUND_UP(MAX_HEIGHT,=
 16))
+
+/*
+ * NV12:
+ * YUV 4:2:0 image with a plane of 8 bit Y samples followed
+ * by an interleaved U/V plane containing 8 bit 2x2 subsampled
+ * colour difference samples.
+ *
+ * <-Y/UV_Stride (aligned to 128)->
+ * <------- Width ------->
+ * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  ^           ^
+ * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |
+ * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  Height      |
+ * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |          y_scanlines (aligned to 32)
+ * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |
+ * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |
+ * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |
+ * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  V           |
+ * . . . . . . . . . . . . . . . .              |
+ * . . . . . . . . . . . . . . . .              |
+ * . . . . . . . . . . . . . . . .              |
+ * . . . . . . . . . . . . . . . .              V
+ * U V U V U V U V U V U V . . . .  ^
+ * U V U V U V U V U V U V . . . .  |
+ * U V U V U V U V U V U V . . . .  |
+ * U V U V U V U V U V U V . . . .  uv_scanlines (aligned to 16)
+ * . . . . . . . . . . . . . . . .  |
+ * . . . . . . . . . . . . . . . .  V
+ * . . . . . . . . . . . . . . . .  --> Buffer size aligned to 4K
+ *
+ * y_stride : Width aligned to 128
+ * uv_stride : Width aligned to 128
+ * y_scanlines: Height aligned to 32
+ * uv_scanlines: Height/2 aligned to 16
+ * Total size =3D align((y_stride * y_scanlines
+ *          + uv_stride * uv_scanlines , 4096)
+ *
+ * Note: All the alignments are hardware requirements.
+ */
+static u32 iris_yuv_buffer_size_nv12(struct iris_inst *inst)
+{
+	u32 y_plane, uv_plane, y_stride, uv_stride, y_scanlines, uv_scanlines;
+	struct v4l2_format *f =3D inst->fmt_dst;
+
+	y_stride =3D ALIGN(f->fmt.pix_mp.width, Y_STRIDE_ALIGN);
+	uv_stride =3D ALIGN(f->fmt.pix_mp.width, UV_STRIDE_ALIGN);
+	y_scanlines =3D ALIGN(f->fmt.pix_mp.height, Y_SCANLINE_ALIGN);
+	uv_scanlines =3D ALIGN((f->fmt.pix_mp.height + 1) >> 1, UV_SCANLINE_ALIGN=
);
+	y_plane =3D y_stride * y_scanlines;
+	uv_plane =3D uv_stride * uv_scanlines;
+
+	return ALIGN(y_plane + uv_plane, PIXELS_4K);
+}
+
+static u32 iris_bitstream_buffer_size(struct iris_inst *inst)
+{
+	struct platform_inst_caps *caps =3D inst->core->iris_platform_data->inst_=
caps;
+	u32 base_res_mbs =3D NUM_MBS_4K;
+	u32 frame_size, num_mbs;
+	u32 div_factor =3D 2;
+
+	num_mbs =3D iris_get_mbpf(inst);
+	if (num_mbs > NUM_MBS_4K) {
+		div_factor =3D 4;
+		base_res_mbs =3D caps->max_mbpf;
+	}
+
+	/*
+	 * frame_size =3D YUVsize / div_factor
+	 * where YUVsize =3D resolution_in_MBs * MBs_in_pixel * 3 / 2
+	 */
+	frame_size =3D base_res_mbs * (16 * 16) * 3 / 2 / div_factor;
+
+	return ALIGN(frame_size, PIXELS_4K);
+}
+
+int iris_get_buffer_size(struct iris_inst *inst,
+			 enum iris_buffer_type buffer_type)
+{
+	switch (buffer_type) {
+	case BUF_INPUT:
+		return iris_bitstream_buffer_size(inst);
+	case BUF_OUTPUT:
+		return iris_yuv_buffer_size_nv12(inst);
+	default:
+		return 0;
+	}
+}
+
+void iris_vb2_queue_error(struct iris_inst *inst)
+{
+	struct v4l2_m2m_ctx *m2m_ctx =3D inst->m2m_ctx;
+	struct vb2_queue *q;
+
+	q =3D v4l2_m2m_get_src_vq(m2m_ctx);
+	vb2_queue_error(q);
+	q =3D v4l2_m2m_get_dst_vq(m2m_ctx);
+	vb2_queue_error(q);
+}
diff --git a/drivers/media/platform/qcom/iris/iris_buffer.h b/drivers/media=
/platform/qcom/iris/iris_buffer.h
new file mode 100644
index 000000000000..ae2ec5637108
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_buffer.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#ifndef __IRIS_BUFFER_H__
+#define __IRIS_BUFFER_H__
+
+#include <media/videobuf2-v4l2.h>
+
+struct iris_inst;
+
+#define to_iris_buffer(ptr)	container_of(ptr, struct iris_buffer, vb2)
+
+/**
+ * enum iris_buffer_type
+ *
+ * @BUF_INPUT: input buffer to the iris hardware
+ * @BUF_OUTPUT: output buffer from the iris hardware
+ * @BUF_BIN: buffer to store intermediate bin data
+ * @BUF_ARP: buffer for auto register programming
+ * @BUF_COMV: buffer to store colocated motion vectors
+ * @BUF_NON_COMV: buffer to hold config data for HW
+ * @BUF_LINE: buffer to store decoding/encoding context data for HW
+ * @BUF_DPB: buffer to store display picture buffers for reference
+ * @BUF_PERSIST: buffer to store session context data
+ * @BUF_SCRATCH_1: buffer to store decoding/encoding context data for HW
+ * @BUF_TYPE_MAX: max buffer types
+ */
+enum iris_buffer_type {
+	BUF_INPUT =3D 1,
+	BUF_OUTPUT,
+	BUF_BIN,
+	BUF_ARP,
+	BUF_COMV,
+	BUF_NON_COMV,
+	BUF_LINE,
+	BUF_DPB,
+	BUF_PERSIST,
+	BUF_SCRATCH_1,
+	BUF_TYPE_MAX,
+};
+
+/*
+ * enum iris_buffer_attributes
+ *
+ * BUF_ATTR_DEFERRED: buffer queued by client but not submitted to firmwar=
e.
+ * BUF_ATTR_PENDING_RELEASE: buffers requested to be released from firmwar=
e.
+ * BUF_ATTR_QUEUED: buffers submitted to firmware.
+ * BUF_ATTR_DEQUEUED: buffers received from firmware.
+ * BUF_ATTR_BUFFER_DONE: buffers sent back to vb2.
+ */
+enum iris_buffer_attributes {
+	BUF_ATTR_DEFERRED		=3D BIT(0),
+	BUF_ATTR_PENDING_RELEASE	=3D BIT(1),
+	BUF_ATTR_QUEUED			=3D BIT(2),
+	BUF_ATTR_DEQUEUED		=3D BIT(3),
+	BUF_ATTR_BUFFER_DONE		=3D BIT(4),
+};
+
+/**
+ * struct iris_buffer
+ *
+ * @vb2: v4l2 vb2 buffer
+ * @list: list head for the iris_buffers structure
+ * @inst: iris instance structure
+ * @type: enum for type of iris buffer
+ * @index: identifier for the iris buffer
+ * @fd: file descriptor of the buffer
+ * @buffer_size: accessible buffer size in bytes starting from addr_offset
+ * @data_offset: accessible buffer offset from base address
+ * @data_size: data size in bytes
+ * @device_addr: device address of the buffer
+ * @kvaddr: kernel virtual address of the buffer
+ * @dma_attrs: dma attributes
+ * @flags: buffer flags. It is represented as bit masks.
+ * @timestamp: timestamp of the buffer in nano seconds (ns)
+ * @attr: enum for iris buffer attributes
+ */
+struct iris_buffer {
+	struct vb2_v4l2_buffer		vb2;
+	struct list_head		list;
+	struct iris_inst		*inst;
+	enum iris_buffer_type		type;
+	u32				index;
+	int				fd;
+	size_t				buffer_size;
+	u32				data_offset;
+	size_t				data_size;
+	dma_addr_t			device_addr;
+	void				*kvaddr;
+	unsigned long			dma_attrs;
+	u32				flags; /* V4L2_BUF_FLAG_* */
+	u64				timestamp;
+	enum iris_buffer_attributes	attr;
+};
+
+struct iris_buffers {
+	struct list_head	list;
+	u32			min_count;
+	u32			size;
+};
+
+int iris_get_buffer_size(struct iris_inst *inst, enum iris_buffer_type buf=
fer_type);
+void iris_vb2_queue_error(struct iris_inst *inst);
+
+#endif
diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/p=
latform/qcom/iris/iris_core.h
index 58aab78ab2c4..1ddcb8793172 100644
--- a/drivers/media/platform/qcom/iris/iris_core.h
+++ b/drivers/media/platform/qcom/iris/iris_core.h
@@ -34,6 +34,8 @@ struct icc_info {
  * @v4l2_dev: a holder for v4l2 device structure
  * @vdev_dec: iris video device structure for decoder
  * @iris_v4l2_file_ops: iris v4l2 file ops
+ * @iris_v4l2_ioctl_ops: iris v4l2 ioctl ops
+ * @iris_vb2_ops: iris vb2 ops
  * @icc_tbl: table of iris interconnects
  * @icc_count: count of iris interconnects
  * @pmdomain_tbl: table of iris power domains
@@ -60,6 +62,7 @@ struct icc_info {
  * @core_init_done: structure of signal completion for system response
  * @intr_status: interrupt status
  * @sys_error_handler: a delayed work for handling system fatal error
+ * @instances: a list_head of all instances
  */
=20
 struct iris_core {
@@ -69,6 +72,8 @@ struct iris_core {
 	struct v4l2_device			v4l2_dev;
 	struct video_device			*vdev_dec;
 	const struct v4l2_file_operations	*iris_v4l2_file_ops;
+	const struct v4l2_ioctl_ops		*iris_v4l2_ioctl_ops;
+	const struct vb2_ops			*iris_vb2_ops;
 	struct icc_bulk_data			*icc_tbl;
 	u32					icc_count;
 	struct dev_pm_domain_list		*pmdomain_tbl;
@@ -95,6 +100,7 @@ struct iris_core {
 	struct completion			core_init_done;
 	u32					intr_status;
 	struct delayed_work			sys_error_handler;
+	struct list_head			instances;
 };
=20
 int iris_core_init(struct iris_core *core);
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/m=
edia/platform/qcom/iris/iris_hfi_common.h
index 36673aafe1c9..eaa2db469c74 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_common.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h
@@ -9,6 +9,7 @@
 #include <linux/types.h>
 #include <media/v4l2-device.h>
=20
+struct iris_inst;
 struct iris_core;
=20
 enum hfi_packet_port_type {
@@ -47,6 +48,8 @@ struct iris_hfi_command_ops {
 	int (*sys_image_version)(struct iris_core *core);
 	int (*sys_interframe_powercollapse)(struct iris_core *core);
 	int (*sys_pc_prep)(struct iris_core *core);
+	int (*session_open)(struct iris_inst *inst);
+	int (*session_close)(struct iris_inst *inst);
 };
=20
 struct iris_hfi_response_ops {
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen1_command.c
index b2e76d1dcbf7..7ee69c5223ce 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
@@ -66,11 +66,51 @@ static int iris_hfi_gen1_sys_pc_prep(struct iris_core *=
core)
 	return iris_hfi_queue_cmd_write_locked(core, &pkt, pkt.hdr.size);
 }
=20
+static int iris_hfi_gen1_session_open(struct iris_inst *inst)
+{
+	struct hfi_session_open_pkt packet;
+	int ret;
+
+	packet.shdr.hdr.size =3D sizeof(struct hfi_session_open_pkt);
+	packet.shdr.hdr.pkt_type =3D HFI_CMD_SYS_SESSION_INIT;
+	packet.shdr.session_id =3D inst->session_id;
+	packet.session_domain =3D HFI_SESSION_TYPE_DEC;
+	packet.session_codec =3D HFI_VIDEO_CODEC_H264;
+
+	reinit_completion(&inst->completion);
+
+	ret =3D iris_hfi_queue_cmd_write(inst->core, &packet, packet.shdr.hdr.siz=
e);
+	if (ret)
+		return ret;
+
+	return iris_wait_for_session_response(inst);
+}
+
+static void iris_hfi_gen1_packet_session_cmd(struct iris_inst *inst,
+					     struct hfi_session_pkt *packet,
+					     u32 ptype)
+{
+	packet->shdr.hdr.size =3D sizeof(*packet);
+	packet->shdr.hdr.pkt_type =3D ptype;
+	packet->shdr.session_id =3D inst->session_id;
+}
+
+static int iris_hfi_gen1_session_close(struct iris_inst *inst)
+{
+	struct hfi_session_pkt packet;
+
+	iris_hfi_gen1_packet_session_cmd(inst, &packet, HFI_CMD_SYS_SESSION_END);
+
+	return iris_hfi_queue_cmd_write(inst->core, &packet, packet.shdr.hdr.size=
);
+}
+
 static const struct iris_hfi_command_ops iris_hfi_gen1_command_ops =3D {
 	.sys_init =3D iris_hfi_gen1_sys_init,
 	.sys_image_version =3D iris_hfi_gen1_sys_image_version,
 	.sys_interframe_powercollapse =3D iris_hfi_gen1_sys_interframe_powercolla=
pse,
 	.sys_pc_prep =3D iris_hfi_gen1_sys_pc_prep,
+	.session_open =3D iris_hfi_gen1_session_open,
+	.session_close =3D iris_hfi_gen1_session_close,
 };
=20
 void iris_hfi_gen1_command_ops_init(struct iris_core *core)
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
index 81685a284f23..3640f8504db9 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
@@ -9,19 +9,34 @@
 #include <linux/types.h>
=20
 #define HFI_VIDEO_ARCH_OX				0x1
+
+#define HFI_SESSION_TYPE_DEC				2
+
+#define HFI_VIDEO_CODEC_H264				0x00000002
+
 #define HFI_ERR_NONE					0x0
=20
 #define HFI_CMD_SYS_INIT				0x10001
 #define HFI_CMD_SYS_PC_PREP				0x10002
 #define HFI_CMD_SYS_SET_PROPERTY			0x10005
 #define HFI_CMD_SYS_GET_PROPERTY			0x10006
+#define HFI_CMD_SYS_SESSION_INIT			0x10007
+#define HFI_CMD_SYS_SESSION_END				0x10008
=20
-#define HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL		0x5
-#define HFI_PROPERTY_SYS_IMAGE_VERSION			0x6
+#define HFI_ERR_SESSION_UNSUPPORTED_SETTING		0x1008
+#define HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE		0x1010
+#define HFI_ERR_SESSION_INVALID_SCALE_FACTOR		0x1012
+#define HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED		0x1013
=20
 #define HFI_EVENT_SYS_ERROR				0x1
+#define HFI_EVENT_SESSION_ERROR				0x2
+
+#define HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL		0x5
+#define HFI_PROPERTY_SYS_IMAGE_VERSION			0x6
=20
 #define HFI_MSG_SYS_INIT				0x20001
+#define HFI_MSG_SYS_SESSION_INIT			0x20006
+#define HFI_MSG_SYS_SESSION_END				0x20007
 #define HFI_MSG_SYS_COV					0x20009
 #define HFI_MSG_SYS_PROPERTY_INFO			0x2000a
=20
@@ -32,6 +47,21 @@ struct hfi_pkt_hdr {
 	u32 pkt_type;
 };
=20
+struct hfi_session_hdr_pkt {
+	struct hfi_pkt_hdr hdr;
+	u32 session_id;
+};
+
+struct hfi_session_open_pkt {
+	struct hfi_session_hdr_pkt shdr;
+	u32 session_domain;
+	u32 session_codec;
+};
+
+struct hfi_session_pkt {
+	struct hfi_session_hdr_pkt shdr;
+};
+
 struct hfi_sys_init_pkt {
 	struct hfi_pkt_hdr hdr;
 	u32 arch_type;
@@ -54,7 +84,7 @@ struct hfi_sys_pc_prep_pkt {
 };
=20
 struct hfi_msg_event_notify_pkt {
-	struct hfi_pkt_hdr hdr;
+	struct hfi_session_hdr_pkt shdr;
 	u32 event_id;
 	u32 event_data1;
 	u32 event_data2;
@@ -68,6 +98,17 @@ struct hfi_msg_sys_init_done_pkt {
 	u32 data[];
 };
=20
+struct hfi_msg_session_hdr_pkt {
+	struct hfi_session_hdr_pkt shdr;
+	u32 error_type;
+};
+
+struct hfi_msg_session_init_done_pkt {
+	struct hfi_msg_session_hdr_pkt shdr;
+	u32 num_properties;
+	u32 data[];
+};
+
 struct hfi_msg_sys_property_info_pkt {
 	struct hfi_pkt_hdr hdr;
 	u32 num_properties;
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c b/dr=
ivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
index 78fefa4176f9..18ba5f67dd36 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
@@ -13,13 +13,54 @@ iris_hfi_gen1_sys_event_notify(struct iris_core *core, =
void *packet)
 	struct hfi_msg_event_notify_pkt *pkt =3D packet;
=20
 	if (pkt->event_id =3D=3D HFI_EVENT_SYS_ERROR)
-		dev_err(core->dev, "sys error (type: %x, data1:%x, data2:%x)\n",
-			pkt->event_id, pkt->event_data1, pkt->event_data2);
+		dev_err(core->dev, "sys error (type: %x, session id:%x, data1:%x, data2:=
%x)\n",
+			pkt->event_id, pkt->shdr.session_id, pkt->event_data1,
+			pkt->event_data2);
=20
 	core->state =3D IRIS_CORE_ERROR;
 	schedule_delayed_work(&core->sys_error_handler, msecs_to_jiffies(10));
 }
=20
+static void
+iris_hfi_gen1_event_session_error(struct iris_inst *inst, struct hfi_msg_e=
vent_notify_pkt *pkt)
+{
+	switch (pkt->event_data1) {
+	/* non fatal session errors */
+	case HFI_ERR_SESSION_INVALID_SCALE_FACTOR:
+	case HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE:
+	case HFI_ERR_SESSION_UNSUPPORTED_SETTING:
+	case HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED:
+		dev_dbg(inst->core->dev, "session error: event id:%x, session id:%x\n",
+			pkt->event_data1, pkt->shdr.session_id);
+		break;
+	/* fatal session errors */
+	default:
+		/*
+		 * firmware fills event_data2 as an additional information about the
+		 * hfi command for which session error has ouccured.
+		 */
+		dev_err(inst->core->dev,
+			"session error for command: %x, event id:%x, session id:%x\n",
+			pkt->event_data2, pkt->event_data1,
+			pkt->shdr.session_id);
+		iris_vb2_queue_error(inst);
+		break;
+	}
+}
+
+static void iris_hfi_gen1_session_event_notify(struct iris_inst *inst, voi=
d *packet)
+{
+	struct hfi_msg_event_notify_pkt *pkt =3D packet;
+
+	switch (pkt->event_id) {
+	case HFI_EVENT_SESSION_ERROR:
+		iris_hfi_gen1_event_session_error(inst, pkt);
+		break;
+	default:
+		break;
+	}
+}
+
 static void iris_hfi_gen1_sys_init_done(struct iris_core *core, void *pack=
et)
 {
 	struct hfi_msg_sys_init_done_pkt *pkt =3D packet;
@@ -99,6 +140,14 @@ static const struct iris_hfi_gen1_response_pkt_info pkt=
_infos[] =3D {
 	 .pkt =3D HFI_MSG_SYS_PROPERTY_INFO,
 	 .pkt_sz =3D sizeof(struct hfi_msg_sys_property_info_pkt),
 	},
+	{
+	 .pkt =3D HFI_MSG_SYS_SESSION_INIT,
+	 .pkt_sz =3D sizeof(struct hfi_msg_session_init_done_pkt),
+	},
+	{
+	 .pkt =3D HFI_MSG_SYS_SESSION_END,
+	 .pkt_sz =3D sizeof(struct hfi_msg_session_hdr_pkt),
+	},
 };
=20
 static void iris_hfi_gen1_handle_response(struct iris_core *core, void *re=
sponse)
@@ -106,6 +155,8 @@ static void iris_hfi_gen1_handle_response(struct iris_c=
ore *core, void *response
 	struct hfi_pkt_hdr *hdr =3D (struct hfi_pkt_hdr *)response;
 	const struct iris_hfi_gen1_response_pkt_info *pkt_info;
 	struct device *dev =3D core->dev;
+	struct hfi_session_pkt *pkt;
+	struct iris_inst *inst;
 	bool found =3D false;
 	u32 i;
=20
@@ -132,9 +183,31 @@ static void iris_hfi_gen1_handle_response(struct iris_=
core *core, void *response
 		iris_hfi_gen1_sys_property_info(core, hdr);
 		break;
 	case HFI_MSG_EVENT_NOTIFY:
-		iris_hfi_gen1_sys_event_notify(core, hdr);
+		pkt =3D (struct hfi_session_pkt *)hdr;
+		inst =3D iris_get_instance(core, pkt->shdr.session_id);
+		if (inst) {
+			mutex_lock(&inst->lock);
+			iris_hfi_gen1_session_event_notify(inst, hdr);
+			mutex_unlock(&inst->lock);
+		} else {
+			iris_hfi_gen1_sys_event_notify(core, hdr);
+		}
+
 		break;
 	default:
+		pkt =3D (struct hfi_session_pkt *)hdr;
+		inst =3D iris_get_instance(core, pkt->shdr.session_id);
+		if (!inst) {
+			dev_warn(dev, "no valid instance(pkt session_id:%x, pkt:%x)\n",
+				 pkt->shdr.session_id,
+				 pkt_info ? pkt_info->pkt : 0);
+			return;
+		}
+
+		mutex_lock(&inst->lock);
+		complete(&inst->completion);
+		mutex_unlock(&inst->lock);
+
 		break;
 	}
 }
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h b/drivers/med=
ia/platform/qcom/iris/iris_hfi_gen2.h
index c43b51774978..aaf6660bc1fe 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h
@@ -10,13 +10,18 @@
=20
 struct iris_core;
=20
+#define to_iris_inst_hfi_gen2(ptr) \
+	container_of(ptr, struct iris_inst_hfi_gen2, inst)
+
 /**
  * struct iris_inst_hfi_gen2 - holds per video instance parameters for hfi=
_gen2
  *
  * @inst: pointer to iris_instance structure
+ * @packet: HFI packet
  */
 struct iris_inst_hfi_gen2 {
 	struct iris_inst		inst;
+	struct iris_hfi_header		*packet;
 };
=20
 void iris_hfi_gen2_command_ops_init(struct iris_core *core);
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen2_command.c
index f8cb1177ef54..a08e844bb4bb 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
@@ -85,11 +85,116 @@ static int iris_hfi_gen2_sys_pc_prep(struct iris_core =
*core)
 	return ret;
 }
=20
+static int iris_hfi_gen2_session_set_codec(struct iris_inst *inst)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	u32 codec =3D HFI_CODEC_DECODE_AVC;
+
+	iris_hfi_gen2_packet_session_property(inst,
+					      HFI_PROP_CODEC,
+					      HFI_HOST_FLAGS_NONE,
+					      HFI_PORT_NONE,
+					      HFI_PAYLOAD_U32_ENUM,
+					      &codec,
+					      sizeof(u32));
+
+	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
+					inst_hfi_gen2->packet->size);
+}
+
+static int iris_hfi_gen2_session_set_default_header(struct iris_inst *inst)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	u32 default_header =3D false;
+
+	iris_hfi_gen2_packet_session_property(inst,
+					      HFI_PROP_DEC_DEFAULT_HEADER,
+					      HFI_HOST_FLAGS_NONE,
+					      HFI_PORT_BITSTREAM,
+					      HFI_PAYLOAD_U32,
+					      &default_header,
+					      sizeof(u32));
+
+	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
+					inst_hfi_gen2->packet->size);
+}
+
+static int iris_hfi_gen2_session_open(struct iris_inst *inst)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	int ret;
+
+	inst_hfi_gen2->packet =3D kzalloc(4096, GFP_KERNEL);
+	if (!inst_hfi_gen2->packet)
+		return -ENOMEM;
+
+	iris_hfi_gen2_packet_session_command(inst,
+					     HFI_CMD_OPEN,
+					     HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+					     HFI_HOST_FLAGS_INTR_REQUIRED,
+					     HFI_PORT_NONE,
+					     0,
+					     HFI_PAYLOAD_U32,
+					     &inst->session_id,
+					     sizeof(u32));
+
+	ret =3D iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
+				       inst_hfi_gen2->packet->size);
+	if (ret)
+		goto fail_free_packet;
+
+	ret =3D iris_hfi_gen2_session_set_codec(inst);
+	if (ret)
+		goto fail_free_packet;
+
+	ret =3D iris_hfi_gen2_session_set_default_header(inst);
+	if (ret)
+		goto fail_free_packet;
+
+	return 0;
+
+fail_free_packet:
+	kfree(inst_hfi_gen2->packet);
+	inst_hfi_gen2->packet =3D NULL;
+
+	return ret;
+}
+
+static int iris_hfi_gen2_session_close(struct iris_inst *inst)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	int ret;
+
+	if (!inst_hfi_gen2->packet)
+		return -EINVAL;
+
+	iris_hfi_gen2_packet_session_command(inst,
+					     HFI_CMD_CLOSE,
+					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+					     HFI_HOST_FLAGS_INTR_REQUIRED |
+					     HFI_HOST_FLAGS_NON_DISCARDABLE),
+					     HFI_PORT_NONE,
+					     inst->session_id,
+					     HFI_PAYLOAD_NONE,
+					     NULL,
+					     0);
+
+	ret =3D iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
+				       inst_hfi_gen2->packet->size);
+
+	kfree(inst_hfi_gen2->packet);
+	inst_hfi_gen2->packet =3D NULL;
+
+	return ret;
+}
+
 static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops =3D {
 	.sys_init =3D iris_hfi_gen2_sys_init,
 	.sys_image_version =3D iris_hfi_gen2_sys_image_version,
 	.sys_interframe_powercollapse =3D iris_hfi_gen2_sys_interframe_powercolla=
pse,
 	.sys_pc_prep =3D iris_hfi_gen2_sys_pc_prep,
+	.session_open =3D iris_hfi_gen2_session_open,
+	.session_close =3D iris_hfi_gen2_session_close,
 };
=20
 void iris_hfi_gen2_command_ops_init(struct iris_core *core)
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
index e6a19ffc12fb..ccf5fd0902d7 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
@@ -13,6 +13,8 @@
 #define HFI_CMD_BEGIN				0x01000000
 #define HFI_CMD_INIT				0x01000001
 #define HFI_CMD_POWER_COLLAPSE			0x01000002
+#define HFI_CMD_OPEN				0x01000003
+#define HFI_CMD_CLOSE				0x01000004
 #define HFI_CMD_END				0x01FFFFFF
=20
 #define HFI_PROP_BEGIN				0x03000000
@@ -25,12 +27,45 @@
 #define HFI_PROP_UBWC_BANK_SWZL_LEVEL2		0x03000007
 #define HFI_PROP_UBWC_BANK_SWZL_LEVEL3		0x03000008
 #define HFI_PROP_UBWC_BANK_SPREADING		0x03000009
+#define HFI_PROP_CODEC				0x03000100
+#define HFI_PROP_DEC_DEFAULT_HEADER		0x03000168
 #define HFI_PROP_END				0x03FFFFFF
=20
+#define HFI_SESSION_ERROR_BEGIN			0x04000000
+#define HFI_ERROR_UNKNOWN_SESSION		0x04000001
+#define HFI_ERROR_MAX_SESSIONS			0x04000002
+#define HFI_ERROR_FATAL				0x04000003
+#define HFI_ERROR_INVALID_STATE			0x04000004
+#define HFI_ERROR_INSUFFICIENT_RESOURCES	0x04000005
+#define HFI_ERROR_BUFFER_NOT_SET		0x04000006
+#define HFI_ERROR_STREAM_UNSUPPORTED		0x04000008
+#define HFI_SESSION_ERROR_END			0x04FFFFFF
+
 #define HFI_SYSTEM_ERROR_BEGIN			0x05000000
 #define HFI_SYS_ERROR_WD_TIMEOUT		0x05000001
 #define HFI_SYSTEM_ERROR_END			0x05FFFFFF
=20
+enum hfi_codec_type {
+	HFI_CODEC_DECODE_AVC			=3D 1,
+	HFI_CODEC_ENCODE_AVC			=3D 2,
+};
+
+enum hfi_buffer_type {
+	HFI_BUFFER_BITSTREAM			=3D 0x00000001,
+	HFI_BUFFER_RAW				=3D 0x00000002,
+	HFI_BUFFER_METADATA			=3D 0x00000003,
+	HFI_BUFFER_SUBCACHE			=3D 0x00000004,
+	HFI_BUFFER_PARTIAL_DATA			=3D 0x00000005,
+	HFI_BUFFER_DPB				=3D 0x00000006,
+	HFI_BUFFER_BIN				=3D 0x00000007,
+	HFI_BUFFER_LINE				=3D 0x00000008,
+	HFI_BUFFER_ARP				=3D 0x00000009,
+	HFI_BUFFER_COMV				=3D 0x0000000A,
+	HFI_BUFFER_NON_COMV			=3D 0x0000000B,
+	HFI_BUFFER_PERSIST			=3D 0x0000000C,
+	HFI_BUFFER_VPSS				=3D 0x0000000D,
+};
+
 enum hfi_packet_firmware_flags {
 	HFI_FW_FLAGS_SUCCESS			=3D 0x00000001,
 	HFI_FW_FLAGS_INFORMATION		=3D 0x00000002,
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c b/driv=
ers/media/platform/qcom/iris/iris_hfi_gen2_packet.c
index 510d44408b41..739b2ce5bfae 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c
@@ -143,6 +143,45 @@ void iris_hfi_gen2_packet_image_version(struct iris_co=
re *core, struct iris_hfi_
 				    NULL, 0);
 }
=20
+void iris_hfi_gen2_packet_session_command(struct iris_inst *inst, u32 pkt_=
type,
+					  u32 flags, u32 port, u32 session_id,
+					  u32 payload_type, void *payload,
+					  u32 payload_size)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	struct iris_core *core =3D inst->core;
+
+	iris_hfi_gen2_create_header(inst_hfi_gen2->packet, session_id, core->head=
er_id++);
+
+	iris_hfi_gen2_create_packet(inst_hfi_gen2->packet,
+				    pkt_type,
+				    flags,
+				    payload_type,
+				    port,
+				    core->packet_id++,
+				    payload,
+				    payload_size);
+}
+
+void iris_hfi_gen2_packet_session_property(struct iris_inst *inst,
+					   u32 pkt_type, u32 flags, u32 port,
+					   u32 payload_type, void *payload, u32 payload_size)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	struct iris_core *core =3D inst->core;
+
+	iris_hfi_gen2_create_header(inst_hfi_gen2->packet, inst->session_id, core=
->header_id++);
+
+	iris_hfi_gen2_create_packet(inst_hfi_gen2->packet,
+				    pkt_type,
+				    flags,
+				    payload_type,
+				    port,
+				    core->packet_id++,
+				    payload,
+				    payload_size);
+}
+
 void iris_hfi_gen2_packet_sys_interframe_powercollapse(struct iris_core *c=
ore,
 						       struct iris_hfi_header *hdr)
 {
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h b/driv=
ers/media/platform/qcom/iris/iris_hfi_gen2_packet.h
index 3b771b7516de..4a9b88185b0d 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h
@@ -63,6 +63,13 @@ struct iris_hfi_packet {
=20
 void iris_hfi_gen2_packet_sys_init(struct iris_core *core, struct iris_hfi=
_header *hdr);
 void iris_hfi_gen2_packet_image_version(struct iris_core *core, struct iri=
s_hfi_header *hdr);
+void iris_hfi_gen2_packet_session_command(struct iris_inst *inst, u32 pkt_=
type,
+					  u32 flags, u32 port, u32 session_id,
+					  u32 payload_type, void *payload,
+					  u32 payload_size);
+void iris_hfi_gen2_packet_session_property(struct iris_inst *inst,
+					   u32 pkt_type, u32 flags, u32 port,
+					   u32 payload_type, void *payload, u32 payload_size);
 void iris_hfi_gen2_packet_sys_interframe_powercollapse(struct iris_core *c=
ore,
 						       struct iris_hfi_header *hdr);
 void iris_hfi_gen2_packet_sys_pc_prep(struct iris_core *core, struct iris_=
hfi_header *hdr);
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c b/dr=
ivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
index 007e4a7b6782..e1c43daea6c7 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
@@ -14,6 +14,17 @@ struct iris_hfi_gen2_core_hfi_range {
 	int (*handle)(struct iris_core *core, struct iris_hfi_packet *pkt);
 };
=20
+struct iris_hfi_gen2_inst_hfi_range {
+	u32 begin;
+	u32 end;
+	int (*handle)(struct iris_inst *inst, struct iris_hfi_packet *pkt);
+};
+
+struct iris_hfi_gen2_packet_handle {
+	enum hfi_buffer_type type;
+	int (*handle)(struct iris_inst *inst, struct iris_hfi_packet *pkt);
+};
+
 static int iris_hfi_gen2_validate_packet(u8 *response_pkt, u8 *core_resp_p=
kt)
 {
 	u8 *response_limit =3D core_resp_pkt + IFACEQ_CORE_PKT_SIZE;
@@ -55,6 +66,45 @@ static int iris_hfi_gen2_validate_hdr_packet(struct iris=
_core *core, struct iris
 	return 0;
 }
=20
+static int iris_hfi_gen2_handle_session_error(struct iris_inst *inst,
+					      struct iris_hfi_packet *pkt)
+{
+	struct iris_core *core =3D inst->core;
+	char *error;
+
+	switch (pkt->type) {
+	case HFI_ERROR_MAX_SESSIONS:
+		error =3D "exceeded max sessions";
+		break;
+	case HFI_ERROR_UNKNOWN_SESSION:
+		error =3D "unknown session id";
+		break;
+	case HFI_ERROR_INVALID_STATE:
+		error =3D "invalid operation for current state";
+		break;
+	case HFI_ERROR_INSUFFICIENT_RESOURCES:
+		error =3D "insufficient resources";
+		break;
+	case HFI_ERROR_BUFFER_NOT_SET:
+		error =3D "internal buffers not set";
+		break;
+	case HFI_ERROR_FATAL:
+		error =3D "fatal error";
+		break;
+	case HFI_ERROR_STREAM_UNSUPPORTED:
+		error =3D "unsupported stream";
+		break;
+	default:
+		error =3D "unknown";
+		break;
+	}
+
+	dev_err(core->dev, "session error received %#x: %s\n", pkt->type, error);
+	iris_vb2_queue_error(inst);
+
+	return 0;
+}
+
 static int iris_hfi_gen2_handle_system_error(struct iris_core *core,
 					     struct iris_hfi_packet *pkt)
 {
@@ -79,6 +129,22 @@ static int iris_hfi_gen2_handle_system_init(struct iris=
_core *core,
 	return 0;
 }
=20
+static int iris_hfi_gen2_handle_session_command(struct iris_inst *inst,
+						struct iris_hfi_packet *pkt)
+{
+	int ret =3D 0;
+
+	switch (pkt->type) {
+	case HFI_CMD_CLOSE:
+		complete(&inst->completion);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
 static int iris_hfi_gen2_handle_image_version_property(struct iris_core *c=
ore,
 						       struct iris_hfi_packet *pkt)
 {
@@ -152,6 +218,46 @@ static int iris_hfi_gen2_handle_system_response(struct=
 iris_core *core,
 	return 0;
 }
=20
+static int iris_hfi_gen2_handle_session_response(struct iris_core *core,
+						 struct iris_hfi_header *hdr)
+{
+	struct iris_hfi_packet *packet;
+	struct iris_inst *inst;
+	int ret =3D 0;
+	u32 i, j;
+	u8 *pkt;
+	static const struct iris_hfi_gen2_inst_hfi_range range[] =3D {
+		{HFI_SESSION_ERROR_BEGIN, HFI_SESSION_ERROR_END,
+		 iris_hfi_gen2_handle_session_error},
+		{HFI_CMD_BEGIN, HFI_CMD_END,
+		 iris_hfi_gen2_handle_session_command },
+	};
+
+	inst =3D iris_get_instance(core, hdr->session_id);
+	if (!inst)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+
+	pkt =3D (u8 *)((u8 *)hdr + sizeof(*hdr));
+	for (i =3D 0; i < ARRAY_SIZE(range); i++) {
+		pkt =3D (u8 *)((u8 *)hdr + sizeof(*hdr));
+		for (j =3D 0; j < hdr->num_packets; j++) {
+			packet =3D (struct iris_hfi_packet *)pkt;
+			if (packet->flags & HFI_FW_FLAGS_SESSION_ERROR)
+				iris_hfi_gen2_handle_session_error(inst, packet);
+
+			if (packet->type > range[i].begin && packet->type < range[i].end)
+				ret =3D range[i].handle(inst, packet);
+			pkt +=3D packet->size;
+		}
+	}
+
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
 static int iris_hfi_gen2_handle_response(struct iris_core *core, void *res=
ponse)
 {
 	struct iris_hfi_header *hdr =3D (struct iris_hfi_header *)response;
@@ -161,7 +267,10 @@ static int iris_hfi_gen2_handle_response(struct iris_c=
ore *core, void *response)
 	if (ret)
 		return iris_hfi_gen2_handle_system_error(core, NULL);
=20
-	return iris_hfi_gen2_handle_system_response(core, hdr);
+	if (!hdr->session_id)
+		return iris_hfi_gen2_handle_system_response(core, hdr);
+	else
+		return iris_hfi_gen2_handle_session_response(core, hdr);
 }
=20
 static void iris_hfi_gen2_flush_debug_queue(struct iris_core *core, u8 *pa=
cket)
diff --git a/drivers/media/platform/qcom/iris/iris_instance.h b/drivers/med=
ia/platform/qcom/iris/iris_instance.h
index 527a270f12d4..b9c7dcfb20f7 100644
--- a/drivers/media/platform/qcom/iris/iris_instance.h
+++ b/drivers/media/platform/qcom/iris/iris_instance.h
@@ -6,24 +6,46 @@
 #ifndef __IRIS_INSTANCE_H__
 #define __IRIS_INSTANCE_H__
=20
+#include <media/v4l2-ctrls.h>
+
+#include "iris_buffer.h"
 #include "iris_core.h"
+#include "iris_utils.h"
=20
 /**
  * struct iris_inst - holds per video instance parameters
  *
+ * @list: used for attach an instance to the core
  * @core: pointer to core structure
+ * @session_id: id of current video session
  * @ctx_q_lock: lock to serialize queues related ioctls
  * @lock: lock to seralise forward and reverse threads
  * @fh: reference of v4l2 file handler
+ * @fmt_src: structure of v4l2_format for source
+ * @fmt_dst: structure of v4l2_format for destination
+ * @crop: structure of crop info
+ * @completion: structure of signal completions
+ * @buffers: array of different iris buffers
+ * @fw_min_count: minimnum count of buffers needed by fw
+ * @once_per_session_set: boolean to set once per session property
  * @m2m_dev:	a reference to m2m device structure
  * @m2m_ctx:	a reference to m2m context structure
  */
=20
 struct iris_inst {
+	struct list_head		list;
 	struct iris_core		*core;
+	u32				session_id;
 	struct mutex			ctx_q_lock;/* lock to serialize queues related ioctls */
 	struct mutex			lock; /* lock to serialize forward and reverse threads */
 	struct v4l2_fh			fh;
+	struct v4l2_format		*fmt_src;
+	struct v4l2_format		*fmt_dst;
+	struct iris_hfi_rect_desc	crop;
+	struct completion		completion;
+	struct iris_buffers		buffers[BUF_TYPE_MAX];
+	u32				fw_min_count;
+	bool				once_per_session_set;
 	struct v4l2_m2m_dev		*m2m_dev;
 	struct v4l2_m2m_ctx		*m2m_ctx;
 };
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/driv=
ers/media/platform/qcom/iris/iris_platform_common.h
index 69c0a8b3d12d..d508477b066e 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -42,6 +42,9 @@ struct ubwc_config_data {
 	u32	bank_spreading;
 };
=20
+struct platform_inst_caps {
+	u32 max_mbpf;
+};
 struct iris_core_power {
 	u64 clk_freq;
 	u64 icc_bw;
@@ -71,11 +74,13 @@ struct iris_platform_data {
 	u64 dma_mask;
 	const char *fwname;
 	u32 pas_id;
+	struct platform_inst_caps *inst_caps;
 	struct tz_cp_config *tz_cp_config_data;
 	u32 core_arch;
 	u32 hw_response_timeout;
 	struct ubwc_config_data *ubwc_config;
 	u32 num_vpp_pipe;
+	u32 max_session_count;
 };
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/driv=
ers/media/platform/qcom/iris/iris_platform_sm8550.c
index ed99cdb13d06..e4232c755074 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
@@ -10,6 +10,10 @@
=20
 #define VIDEO_ARCH_LX 1
=20
+static struct platform_inst_caps platform_inst_cap_sm8550 =3D {
+	.max_mbpf =3D (8192 * 4352) / 256,
+};
+
 static void iris_set_sm8550_preset_registers(struct iris_core *core)
 {
 	writel(0x0, core->reg_base + 0xB0088);
@@ -69,9 +73,11 @@ struct iris_platform_data sm8550_data =3D {
 	.dma_mask =3D 0xe0000000 - 1,
 	.fwname =3D "qcom/vpu/vpu30_p4.mbn",
 	.pas_id =3D IRIS_PAS_ID,
+	.inst_caps =3D &platform_inst_cap_sm8550,
 	.tz_cp_config_data =3D &tz_cp_config_sm8550,
 	.core_arch =3D VIDEO_ARCH_LX,
 	.hw_response_timeout =3D HW_RESPONSE_TIMEOUT_VALUE,
 	.ubwc_config =3D &ubwc_config_sm8550,
 	.num_vpp_pipe =3D 4,
+	.max_session_count =3D 16,
 };
diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/=
platform/qcom/iris/iris_probe.c
index e8ef258b4f2e..a9162be5f9f6 100644
--- a/drivers/media/platform/qcom/iris/iris_probe.c
+++ b/drivers/media/platform/qcom/iris/iris_probe.c
@@ -142,6 +142,7 @@ static int iris_register_video_device(struct iris_core =
*core)
 	strscpy(vdev->name, "qcom-iris-decoder", sizeof(vdev->name));
 	vdev->release =3D video_device_release;
 	vdev->fops =3D core->iris_v4l2_file_ops;
+	vdev->ioctl_ops =3D core->iris_v4l2_ioctl_ops;
 	vdev->vfl_dir =3D VFL_DIR_M2M;
 	vdev->v4l2_dev =3D &core->v4l2_dev;
 	vdev->device_caps =3D V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
@@ -207,6 +208,7 @@ static int iris_probe(struct platform_device *pdev)
 	if (!core->response_packet)
 		return -ENOMEM;
=20
+	INIT_LIST_HEAD(&core->instances);
 	INIT_DELAYED_WORK(&core->sys_error_handler, iris_sys_error_handler);
=20
 	core->reg_base =3D devm_platform_ioremap_resource(pdev, 0);
diff --git a/drivers/media/platform/qcom/iris/iris_utils.c b/drivers/media/=
platform/qcom/iris/iris_utils.c
new file mode 100644
index 000000000000..d5c8e052922c
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_utils.c
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#include <linux/pm_runtime.h>
+
+#include "iris_instance.h"
+#include "iris_utils.h"
+
+int iris_get_mbpf(struct iris_inst *inst)
+{
+	struct v4l2_format *inp_f =3D inst->fmt_src;
+	u32 height =3D max(inp_f->fmt.pix_mp.height, inst->crop.height);
+	u32 width =3D max(inp_f->fmt.pix_mp.width, inst->crop.width);
+
+	return NUM_MBS_PER_FRAME(height, width);
+}
+
+int iris_wait_for_session_response(struct iris_inst *inst)
+{
+	struct iris_core *core =3D inst->core;
+	u32 hw_response_timeout_val;
+	int ret;
+
+	hw_response_timeout_val =3D core->iris_platform_data->hw_response_timeout;
+
+	mutex_unlock(&inst->lock);
+	ret =3D wait_for_completion_timeout(&inst->completion,
+					  msecs_to_jiffies(hw_response_timeout_val));
+	mutex_lock(&inst->lock);
+	if (!ret)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+struct iris_inst *iris_get_instance(struct iris_core *core, u32 session_id)
+{
+	struct iris_inst *inst;
+
+	mutex_lock(&core->lock);
+	list_for_each_entry(inst, &core->instances, list) {
+		if (inst->session_id =3D=3D session_id) {
+			mutex_unlock(&core->lock);
+			return inst;
+		}
+	}
+
+	mutex_unlock(&core->lock);
+	return NULL;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_utils.h b/drivers/media/=
platform/qcom/iris/iris_utils.h
new file mode 100644
index 000000000000..26649b66d978
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_utils.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#ifndef __IRIS_UTILS_H__
+#define __IRIS_UTILS_H__
+
+struct iris_core;
+#include "iris_buffer.h"
+
+struct iris_hfi_rect_desc {
+	u32 left;
+	u32 top;
+	u32 width;
+	u32 height;
+};
+
+#define NUM_MBS_PER_FRAME(height, width) \
+	(DIV_ROUND_UP(height, 16) * DIV_ROUND_UP(width, 16))
+
+static inline enum iris_buffer_type iris_v4l2_type_to_driver(u32 type)
+{
+	if (type =3D=3D V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+		return BUF_INPUT;
+	else
+		return BUF_OUTPUT;
+}
+
+int iris_get_mbpf(struct iris_inst *inst);
+struct iris_inst *iris_get_instance(struct iris_core *core, u32 session_id=
);
+int iris_wait_for_session_response(struct iris_inst *inst);
+
+#endif
diff --git a/drivers/media/platform/qcom/iris/iris_vb2.c b/drivers/media/pl=
atform/qcom/iris/iris_vb2.c
new file mode 100644
index 000000000000..e9db44515d91
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_vb2.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#include "iris_instance.h"
+#include "iris_vb2.h"
+
+int iris_vb2_queue_setup(struct vb2_queue *q,
+			 unsigned int *num_buffers, unsigned int *num_planes,
+			 unsigned int sizes[], struct device *alloc_devs[])
+{
+	struct iris_inst *inst;
+	struct iris_core *core;
+	struct v4l2_format *f;
+	int ret =3D 0;
+
+	inst =3D vb2_get_drv_priv(q);
+
+	mutex_lock(&inst->lock);
+
+	core =3D inst->core;
+	f =3D V4L2_TYPE_IS_OUTPUT(q->type) ? inst->fmt_src : inst->fmt_dst;
+
+	if (*num_planes) {
+		if (*num_planes !=3D f->fmt.pix_mp.num_planes ||
+		    sizes[0] < f->fmt.pix_mp.plane_fmt[0].sizeimage)
+			ret =3D -EINVAL;
+		goto unlock;
+	}
+
+	if (!inst->once_per_session_set) {
+		inst->once_per_session_set =3D true;
+
+		ret =3D core->hfi_ops->session_open(inst);
+		if (ret) {
+			ret =3D -EINVAL;
+			dev_err(core->dev, "session open failed\n");
+			goto unlock;
+		}
+	}
+
+	*num_planes =3D 1;
+	sizes[0] =3D f->fmt.pix_mp.plane_fmt[0].sizeimage;
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_vb2.h b/drivers/media/pl=
atform/qcom/iris/iris_vb2.h
new file mode 100644
index 000000000000..d2e71d0596cc
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_vb2.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#ifndef __IRIS_VB2_H__
+#define __IRIS_VB2_H__
+
+int iris_vb2_queue_setup(struct vb2_queue *q,
+			 unsigned int *num_buffers, unsigned int *num_planes,
+			 unsigned int sizes[], struct device *alloc_devs[]);
+#endif
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/p=
latform/qcom/iris/iris_vdec.c
new file mode 100644
index 000000000000..2ed50ad5d58b
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_vdec.c
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#include "iris_buffer.h"
+#include "iris_instance.h"
+#include "iris_vdec.h"
+#include "iris_vpu_buffer.h"
+
+#define DEFAULT_WIDTH 320
+#define DEFAULT_HEIGHT 240
+
+void iris_vdec_inst_init(struct iris_inst *inst)
+{
+	struct v4l2_format *f;
+
+	inst->fmt_src  =3D kzalloc(sizeof(*inst->fmt_src), GFP_KERNEL);
+	inst->fmt_dst  =3D kzalloc(sizeof(*inst->fmt_dst), GFP_KERNEL);
+
+	inst->fw_min_count =3D MIN_BUFFERS;
+
+	f =3D inst->fmt_src;
+	f->type =3D V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+	f->fmt.pix_mp.width =3D DEFAULT_WIDTH;
+	f->fmt.pix_mp.height =3D DEFAULT_HEIGHT;
+	f->fmt.pix_mp.pixelformat =3D V4L2_PIX_FMT_H264;
+	f->fmt.pix_mp.num_planes =3D 1;
+	f->fmt.pix_mp.plane_fmt[0].bytesperline =3D 0;
+	f->fmt.pix_mp.plane_fmt[0].sizeimage =3D iris_get_buffer_size(inst, BUF_I=
NPUT);
+	f->fmt.pix_mp.field =3D V4L2_FIELD_NONE;
+	inst->buffers[BUF_INPUT].min_count =3D iris_vpu_buf_count(inst, BUF_INPUT=
);
+	inst->buffers[BUF_INPUT].size =3D f->fmt.pix_mp.plane_fmt[0].sizeimage;
+
+	f =3D inst->fmt_dst;
+	f->type =3D V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+	f->fmt.pix_mp.pixelformat =3D V4L2_PIX_FMT_NV12;
+	f->fmt.pix_mp.width =3D ALIGN(DEFAULT_WIDTH, 128);
+	f->fmt.pix_mp.height =3D ALIGN(DEFAULT_HEIGHT, 32);
+	f->fmt.pix_mp.num_planes =3D 1;
+	f->fmt.pix_mp.plane_fmt[0].bytesperline =3D ALIGN(DEFAULT_WIDTH, 128);
+	f->fmt.pix_mp.plane_fmt[0].sizeimage =3D iris_get_buffer_size(inst, BUF_O=
UTPUT);
+	f->fmt.pix_mp.field =3D V4L2_FIELD_NONE;
+	f->fmt.pix_mp.colorspace =3D V4L2_COLORSPACE_DEFAULT;
+	f->fmt.pix_mp.xfer_func =3D V4L2_XFER_FUNC_DEFAULT;
+	f->fmt.pix_mp.ycbcr_enc =3D V4L2_YCBCR_ENC_DEFAULT;
+	f->fmt.pix_mp.quantization =3D V4L2_QUANTIZATION_DEFAULT;
+	inst->buffers[BUF_OUTPUT].min_count =3D iris_vpu_buf_count(inst, BUF_OUTP=
UT);
+	inst->buffers[BUF_OUTPUT].size =3D f->fmt.pix_mp.plane_fmt[0].sizeimage;
+}
+
+void iris_vdec_inst_deinit(struct iris_inst *inst)
+{
+	kfree(inst->fmt_dst);
+	kfree(inst->fmt_src);
+}
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.h b/drivers/media/p=
latform/qcom/iris/iris_vdec.h
new file mode 100644
index 000000000000..353b73b76230
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_vdec.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#ifndef __IRIS_VDEC_H__
+#define __IRIS_VDEC_H__
+
+struct iris_inst;
+
+void iris_vdec_inst_init(struct iris_inst *inst);
+void iris_vdec_inst_deinit(struct iris_inst *inst);
+
+#endif
diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/p=
latform/qcom/iris/iris_vidc.c
index b8654e73f516..ab3b63171c1d 100644
--- a/drivers/media/platform/qcom/iris/iris_vidc.c
+++ b/drivers/media/platform/qcom/iris/iris_vidc.c
@@ -9,6 +9,9 @@
=20
 #include "iris_vidc.h"
 #include "iris_instance.h"
+#include "iris_vdec.h"
+#include "iris_vb2.h"
+#include "iris_vpu_buffer.h"
 #include "iris_platform_common.h"
=20
 #define IRIS_DRV_NAME "iris_driver"
@@ -28,6 +31,38 @@ static void iris_v4l2_fh_deinit(struct iris_inst *inst)
 	v4l2_fh_exit(&inst->fh);
 }
=20
+static void iris_add_session(struct iris_inst *inst)
+{
+	struct iris_core *core =3D inst->core;
+	struct iris_inst *iter;
+	u32 count =3D 0;
+
+	mutex_lock(&core->lock);
+
+	list_for_each_entry(iter, &core->instances, list)
+		count++;
+
+	if (count < core->iris_platform_data->max_session_count)
+		list_add_tail(&inst->list, &core->instances);
+
+	mutex_unlock(&core->lock);
+}
+
+static void iris_remove_session(struct iris_inst *inst)
+{
+	struct iris_core *core =3D inst->core;
+	struct iris_inst *iter, *temp;
+
+	mutex_lock(&core->lock);
+	list_for_each_entry_safe(iter, temp, &core->instances, list) {
+		if (iter->session_id =3D=3D inst->session_id) {
+			list_del_init(&iter->list);
+			break;
+		}
+	}
+	mutex_unlock(&core->lock);
+}
+
 static inline struct iris_inst *iris_get_inst(struct file *filp, void *fh)
 {
 	return container_of(filp->private_data, struct iris_inst, fh);
@@ -59,7 +94,10 @@ iris_m2m_queue_init(void *priv, struct vb2_queue *src_vq=
, struct vb2_queue *dst_
 	src_vq->type =3D V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
 	src_vq->io_modes =3D VB2_MMAP | VB2_DMABUF;
 	src_vq->timestamp_flags =3D V4L2_BUF_FLAG_TIMESTAMP_COPY;
+	src_vq->ops =3D inst->core->iris_vb2_ops;
 	src_vq->drv_priv =3D inst;
+	src_vq->buf_struct_size =3D sizeof(struct iris_buffer);
+	src_vq->min_reqbufs_allocation =3D MIN_BUFFERS;
 	src_vq->dev =3D inst->core->dev;
 	src_vq->lock =3D &inst->ctx_q_lock;
 	ret =3D vb2_queue_init(src_vq);
@@ -69,7 +107,10 @@ iris_m2m_queue_init(void *priv, struct vb2_queue *src_v=
q, struct vb2_queue *dst_
 	dst_vq->type =3D V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
 	dst_vq->io_modes =3D VB2_MMAP | VB2_DMABUF;
 	dst_vq->timestamp_flags =3D V4L2_BUF_FLAG_TIMESTAMP_COPY;
+	dst_vq->ops =3D inst->core->iris_vb2_ops;
 	dst_vq->drv_priv =3D inst;
+	dst_vq->buf_struct_size =3D sizeof(struct iris_buffer);
+	dst_vq->min_reqbufs_allocation =3D MIN_BUFFERS;
 	dst_vq->dev =3D inst->core->dev;
 	dst_vq->lock =3D &inst->ctx_q_lock;
=20
@@ -100,8 +141,11 @@ int iris_open(struct file *filp)
 		return -ENOMEM;
=20
 	inst->core =3D core;
+	inst->session_id =3D hash32_ptr(inst);
=20
+	mutex_init(&inst->lock);
 	mutex_init(&inst->ctx_q_lock);
+	init_completion(&inst->completion);
=20
 	iris_v4l2_fh_init(inst);
=20
@@ -117,6 +161,10 @@ int iris_open(struct file *filp)
 		goto fail_m2m_release;
 	}
=20
+	iris_vdec_inst_init(inst);
+
+	iris_add_session(inst);
+
 	inst->fh.m2m_ctx =3D inst->m2m_ctx;
 	filp->private_data =3D &inst->fh;
=20
@@ -127,19 +175,42 @@ int iris_open(struct file *filp)
 fail_v4l2_fh_deinit:
 	iris_v4l2_fh_deinit(inst);
 	mutex_destroy(&inst->ctx_q_lock);
+	mutex_destroy(&inst->lock);
 	kfree(inst);
=20
 	return ret;
 }
=20
+static void iris_session_close(struct iris_inst *inst)
+{
+	const struct iris_hfi_command_ops *hfi_ops =3D inst->core->hfi_ops;
+	bool wait_for_response =3D true;
+	int ret;
+
+	reinit_completion(&inst->completion);
+
+	ret =3D hfi_ops->session_close(inst);
+	if (ret)
+		wait_for_response =3D false;
+
+	if (wait_for_response)
+		iris_wait_for_session_response(inst);
+}
+
 int iris_close(struct file *filp)
 {
 	struct iris_inst *inst =3D iris_get_inst(filp, NULL);
=20
 	v4l2_m2m_ctx_release(inst->m2m_ctx);
 	v4l2_m2m_release(inst->m2m_dev);
+	mutex_lock(&inst->lock);
+	iris_vdec_inst_deinit(inst);
+	iris_session_close(inst);
 	iris_v4l2_fh_deinit(inst);
+	iris_remove_session(inst);
+	mutex_unlock(&inst->lock);
 	mutex_destroy(&inst->ctx_q_lock);
+	mutex_destroy(&inst->lock);
 	kfree(inst);
 	filp->private_data =3D NULL;
=20
@@ -155,7 +226,17 @@ static struct v4l2_file_operations iris_v4l2_file_ops =
=3D {
 	.mmap                           =3D v4l2_m2m_fop_mmap,
 };
=20
+static const struct vb2_ops iris_vb2_ops =3D {
+	.queue_setup                    =3D iris_vb2_queue_setup,
+};
+
+static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops =3D {
+	.vidioc_reqbufs                 =3D v4l2_m2m_ioctl_reqbufs,
+};
+
 void iris_init_ops(struct iris_core *core)
 {
 	core->iris_v4l2_file_ops =3D &iris_v4l2_file_ops;
+	core->iris_vb2_ops =3D &iris_vb2_ops;
+	core->iris_v4l2_ioctl_ops =3D &iris_v4l2_ioctl_ops;
 }
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c b/drivers/m=
edia/platform/qcom/iris/iris_vpu_buffer.c
new file mode 100644
index 000000000000..2402a33723ab
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#include "iris_instance.h"
+#include "iris_vpu_buffer.h"
+
+int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffe=
r_type)
+{
+	switch (buffer_type) {
+	case BUF_INPUT:
+		return MIN_BUFFERS;
+	case BUF_OUTPUT:
+		return inst->fw_min_count;
+	default:
+		return 0;
+	}
+}
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h b/drivers/m=
edia/platform/qcom/iris/iris_vpu_buffer.h
new file mode 100644
index 000000000000..06e6e958dcac
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#ifndef __IRIS_VPU_BUFFER_H__
+#define __IRIS_VPU_BUFFER_H__
+
+struct iris_inst;
+
+#define MIN_BUFFERS			4
+
+int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffe=
r_type);
+
+#endif

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 28483239797;
	Fri,  7 Feb 2025 07:56:21 +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=1738914983; cv=none;
 b=JexYmFSibnKOZDqIxKS7rc/u+ts0Kb09W5xPSqIahc1I4AHRD+FYQsS/H/APWhbbxxhUf/15QVPfyFHhvZoIavLZvjcwxrl35KbY3iIQSS8EssK6cMt9dBpLNi0A1FWICrNZIiVgZfiHbtCclJMGnUmfbCWiJRIkIOEcmuF1Ky8=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738914983; c=relaxed/simple;
	bh=X1FMqnU3zRGqCqi+lvIh09KpUW/Dz2v72jzr/ZcI9bY=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=j1jxr++7+k2TJfZb6yKCAgQ+FJFJqr83tcVNl/aThcV099XcvbN0WV/u4KxSwdE5hZAupNerYvAf1Aa2hUga8UATf6Cch6kq2XTgUTiIXO9TsFqE53pqcllS7Gfyt4C/rwn9UnxE+m3zz7BXZxOXFaaLvLBn3dSHaWydH1pAniE=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=O6Jrdi+v; arc=none smtp.client-ip=205.220.180.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="O6Jrdi+v"
Received: from pps.filterd (m0279868.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 5172JFML004711;
	Fri, 7 Feb 2025 07:56:08 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	PoM9/HRHo8DD3n+Ll5d8mPr7OMyWyEBKko0HTDVptkM=; b=O6Jrdi+vuPNv6LVC
	fxSb1xW3jHY4SG6ADLs+QCtup0j6adqy9ALAF/uWwudfQjmJvgnlit7Ipmr1ESk7
	zLCVwr/H+We4IL4LpzixwbX6pMIhK5d+OSYrozIEs/t610DpDr2gxEsg5eCMkDQm
	7KPCx49HohbPfXsTCTscoyt8aBG0mG6WaER5wCEuU3SWPXYgtcupHWiRosos6VJy
	8D5oExmyPu4wshDKURV9Hczivk0uOq24y6Ef8dwEO4pIN+AwFNPshAYZDhUtuNdD
	gbdDPRRSsYxIOQVPTwtKQ5mM1nr+olttDBc5clIXhLF7F8XfB5kmyBP0wcDFfzln
	YLqXfw==
Received: from nalasppmta04.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44n99e8qbk-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:56:07 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA04.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177u62H008390
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:56:06 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:55:59 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:24:50 +0530
Subject: [PATCH v10 10/28] media: iris: implement s_fmt, g_fmt and try_fmt
 ioctls
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-10-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>,
        Vedang Nagar <quic_vnagar@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914893; l=8227;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=EYQ3AicFhbj1+6acGiEj6lNOClTR+yi7J5sAWYEp5l8=;
 b=wyV8pRVp+2zhkZ3q6609PeRXZ1KGf4OJ4BIb2lOEbu0d6PzndYll6bJd9ZBiLOJ4AxJdNQJo9
 DS9LjV5oIl/CiJM/ZPW6GbUcyj7HRkxYqHO/JvYASqHEzuaKQ9WzEPg
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-ORIG-GUID: _0krYjlTR1uxp4OyI7IIyJntcov35c4s
X-Proofpoint-GUID: _0krYjlTR1uxp4OyI7IIyJntcov35c4s
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 clxscore=1015 suspectscore=0
 mlxscore=0 lowpriorityscore=0 impostorscore=0 priorityscore=1501
 phishscore=0 adultscore=0 mlxlogscore=999 malwarescore=0 spamscore=0
 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070060

From: Vedang Nagar <quic_vnagar@quicinc.com>

Implement the s_fmt, g_fmt and try_fmt ioctl ops with the necessary
hooks.

Signed-off-by: Vedang Nagar <quic_vnagar@quicinc.com>
Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl>
Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 drivers/media/platform/qcom/iris/iris_vdec.c | 122 +++++++++++++++++++++++=
++++
 drivers/media/platform/qcom/iris/iris_vdec.h |   2 +
 drivers/media/platform/qcom/iris/iris_vidc.c |  48 +++++++++++
 3 files changed, 172 insertions(+)

diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/p=
latform/qcom/iris/iris_vdec.c
index 2ed50ad5d58b..38a5df8191cc 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.c
+++ b/drivers/media/platform/qcom/iris/iris_vdec.c
@@ -3,6 +3,8 @@
  * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
  */
=20
+#include <media/v4l2-mem2mem.h>
+
 #include "iris_buffer.h"
 #include "iris_instance.h"
 #include "iris_vdec.h"
@@ -10,6 +12,7 @@
=20
 #define DEFAULT_WIDTH 320
 #define DEFAULT_HEIGHT 240
+#define DEFAULT_CODEC_ALIGNMENT 16
=20
 void iris_vdec_inst_init(struct iris_inst *inst)
 {
@@ -54,3 +57,122 @@ void iris_vdec_inst_deinit(struct iris_inst *inst)
 	kfree(inst->fmt_dst);
 	kfree(inst->fmt_src);
 }
+
+int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f)
+{
+	struct v4l2_pix_format_mplane *pixmp =3D &f->fmt.pix_mp;
+	struct v4l2_m2m_ctx *m2m_ctx =3D inst->m2m_ctx;
+	struct v4l2_format *f_inst;
+	struct vb2_queue *src_q;
+
+	memset(pixmp->reserved, 0, sizeof(pixmp->reserved));
+	switch (f->type) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		if (f->fmt.pix_mp.pixelformat !=3D V4L2_PIX_FMT_H264) {
+			f_inst =3D inst->fmt_src;
+			f->fmt.pix_mp.width =3D f_inst->fmt.pix_mp.width;
+			f->fmt.pix_mp.height =3D f_inst->fmt.pix_mp.height;
+			f->fmt.pix_mp.pixelformat =3D f_inst->fmt.pix_mp.pixelformat;
+		}
+		break;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+		if (f->fmt.pix_mp.pixelformat !=3D V4L2_PIX_FMT_NV12) {
+			f_inst =3D inst->fmt_dst;
+			f->fmt.pix_mp.pixelformat =3D f_inst->fmt.pix_mp.pixelformat;
+			f->fmt.pix_mp.width =3D f_inst->fmt.pix_mp.width;
+			f->fmt.pix_mp.height =3D f_inst->fmt.pix_mp.height;
+		}
+
+		src_q =3D v4l2_m2m_get_src_vq(m2m_ctx);
+		if (vb2_is_streaming(src_q)) {
+			f_inst =3D inst->fmt_src;
+			f->fmt.pix_mp.height =3D f_inst->fmt.pix_mp.height;
+			f->fmt.pix_mp.width =3D f_inst->fmt.pix_mp.width;
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (pixmp->field =3D=3D V4L2_FIELD_ANY)
+		pixmp->field =3D V4L2_FIELD_NONE;
+
+	pixmp->num_planes =3D 1;
+
+	return 0;
+}
+
+int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f)
+{
+	struct v4l2_format *fmt, *output_fmt;
+	struct vb2_queue *q;
+	u32 codec_align;
+
+	q =3D v4l2_m2m_get_vq(inst->m2m_ctx, f->type);
+	if (!q)
+		return -EINVAL;
+
+	if (vb2_is_busy(q))
+		return -EBUSY;
+
+	iris_vdec_try_fmt(inst, f);
+
+	switch (f->type) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		if (f->fmt.pix_mp.pixelformat !=3D V4L2_PIX_FMT_H264)
+			return -EINVAL;
+
+		fmt =3D inst->fmt_src;
+		fmt->type =3D V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+
+		codec_align =3D DEFAULT_CODEC_ALIGNMENT;
+		fmt->fmt.pix_mp.width =3D ALIGN(f->fmt.pix_mp.width, codec_align);
+		fmt->fmt.pix_mp.height =3D ALIGN(f->fmt.pix_mp.height, codec_align);
+		fmt->fmt.pix_mp.num_planes =3D 1;
+		fmt->fmt.pix_mp.plane_fmt[0].bytesperline =3D 0;
+		fmt->fmt.pix_mp.plane_fmt[0].sizeimage =3D iris_get_buffer_size(inst, BU=
F_INPUT);
+		inst->buffers[BUF_INPUT].min_count =3D iris_vpu_buf_count(inst, BUF_INPU=
T);
+		inst->buffers[BUF_INPUT].size =3D fmt->fmt.pix_mp.plane_fmt[0].sizeimage;
+
+		fmt->fmt.pix_mp.colorspace =3D f->fmt.pix_mp.colorspace;
+		fmt->fmt.pix_mp.xfer_func =3D f->fmt.pix_mp.xfer_func;
+		fmt->fmt.pix_mp.ycbcr_enc =3D f->fmt.pix_mp.ycbcr_enc;
+		fmt->fmt.pix_mp.quantization =3D f->fmt.pix_mp.quantization;
+
+		output_fmt =3D inst->fmt_dst;
+		output_fmt->fmt.pix_mp.colorspace =3D f->fmt.pix_mp.colorspace;
+		output_fmt->fmt.pix_mp.xfer_func =3D f->fmt.pix_mp.xfer_func;
+		output_fmt->fmt.pix_mp.ycbcr_enc =3D f->fmt.pix_mp.ycbcr_enc;
+		output_fmt->fmt.pix_mp.quantization =3D f->fmt.pix_mp.quantization;
+
+		inst->crop.left =3D 0;
+		inst->crop.top =3D 0;
+		inst->crop.width =3D f->fmt.pix_mp.width;
+		inst->crop.height =3D f->fmt.pix_mp.height;
+		break;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+		fmt =3D inst->fmt_dst;
+		fmt->type =3D V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+		if (fmt->fmt.pix_mp.pixelformat !=3D V4L2_PIX_FMT_NV12)
+			return -EINVAL;
+		fmt->fmt.pix_mp.pixelformat =3D f->fmt.pix_mp.pixelformat;
+		fmt->fmt.pix_mp.width =3D ALIGN(f->fmt.pix_mp.width, 128);
+		fmt->fmt.pix_mp.height =3D ALIGN(f->fmt.pix_mp.height, 32);
+		fmt->fmt.pix_mp.num_planes =3D 1;
+		fmt->fmt.pix_mp.plane_fmt[0].bytesperline =3D ALIGN(f->fmt.pix_mp.width,=
 128);
+		fmt->fmt.pix_mp.plane_fmt[0].sizeimage =3D iris_get_buffer_size(inst, BU=
F_OUTPUT);
+		inst->buffers[BUF_OUTPUT].min_count =3D iris_vpu_buf_count(inst, BUF_OUT=
PUT);
+		inst->buffers[BUF_OUTPUT].size =3D fmt->fmt.pix_mp.plane_fmt[0].sizeimag=
e;
+
+		inst->crop.top =3D 0;
+		inst->crop.left =3D 0;
+		inst->crop.width =3D f->fmt.pix_mp.width;
+		inst->crop.height =3D f->fmt.pix_mp.height;
+		break;
+	default:
+		return -EINVAL;
+	}
+	memcpy(f, fmt, sizeof(*fmt));
+
+	return 0;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.h b/drivers/media/p=
latform/qcom/iris/iris_vdec.h
index 353b73b76230..85e93f33e9e7 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.h
+++ b/drivers/media/platform/qcom/iris/iris_vdec.h
@@ -10,5 +10,7 @@ struct iris_inst;
=20
 void iris_vdec_inst_init(struct iris_inst *inst);
 void iris_vdec_inst_deinit(struct iris_inst *inst);
+int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f);
+int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f);
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/p=
latform/qcom/iris/iris_vidc.c
index ab3b63171c1d..bec965284b6e 100644
--- a/drivers/media/platform/qcom/iris/iris_vidc.c
+++ b/drivers/media/platform/qcom/iris/iris_vidc.c
@@ -217,6 +217,48 @@ int iris_close(struct file *filp)
 	return 0;
 }
=20
+static int iris_try_fmt_vid_mplane(struct file *filp, void *fh, struct v4l=
2_format *f)
+{
+	struct iris_inst *inst =3D iris_get_inst(filp, NULL);
+	int ret;
+
+	mutex_lock(&inst->lock);
+	ret =3D iris_vdec_try_fmt(inst, f);
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int iris_s_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_=
format *f)
+{
+	struct iris_inst *inst =3D iris_get_inst(filp, NULL);
+	int ret;
+
+	mutex_lock(&inst->lock);
+	ret =3D iris_vdec_s_fmt(inst, f);
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int iris_g_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_=
format *f)
+{
+	struct iris_inst *inst =3D iris_get_inst(filp, NULL);
+	int ret =3D 0;
+
+	mutex_lock(&inst->lock);
+	if (V4L2_TYPE_IS_OUTPUT(f->type))
+		*f =3D *inst->fmt_src;
+	else if (V4L2_TYPE_IS_CAPTURE(f->type))
+		*f =3D *inst->fmt_dst;
+	else
+		ret =3D -EINVAL;
+
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
 static struct v4l2_file_operations iris_v4l2_file_ops =3D {
 	.owner                          =3D THIS_MODULE,
 	.open                           =3D iris_open,
@@ -231,6 +273,12 @@ static const struct vb2_ops iris_vb2_ops =3D {
 };
=20
 static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops =3D {
+	.vidioc_try_fmt_vid_cap_mplane  =3D iris_try_fmt_vid_mplane,
+	.vidioc_try_fmt_vid_out_mplane  =3D iris_try_fmt_vid_mplane,
+	.vidioc_s_fmt_vid_cap_mplane    =3D iris_s_fmt_vid_mplane,
+	.vidioc_s_fmt_vid_out_mplane    =3D iris_s_fmt_vid_mplane,
+	.vidioc_g_fmt_vid_cap_mplane    =3D iris_g_fmt_vid_mplane,
+	.vidioc_g_fmt_vid_out_mplane    =3D iris_g_fmt_vid_mplane,
 	.vidioc_reqbufs                 =3D v4l2_m2m_ioctl_reqbufs,
 };
=20

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 142ED23A57F;
	Fri,  7 Feb 2025 07:56:26 +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=1738914988; cv=none;
 b=bMSMJTxkrgU4aVYPNJs7FVzLwYmX+JoVSaGVtxeEgjrCABPZfLNpFiT24Rdso5zbG6ynLu1mVbqsw6rpkqu4hZNpjIbmm94YyI12LwRggAuNxCnDRRuZptQ7efOpsoxdk7FzVb03BPpEWt2Bq722rluEVJSqsR7KE1dr1qTKscM=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738914988; c=relaxed/simple;
	bh=uCU2knxmNGSW/NEwLyYhWNd+FwVuRc2MvXHhCXF98rI=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=jqzlOR3eEMZfPvD99MyROuh8s4mc2tD9zlVV/godiUu239C10GBbDyv4/v7WP1LM3emP1Y7kfkWwR41BdfucGtzXq6KHUQE7nWujErndhOc2a3dbfyD/DKpBTEWiItVNG64uHh/9pcPp90ftVxu+ge9OqzDTjPcbLFw8XtnHvRU=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=GQvTzHuF; arc=none smtp.client-ip=205.220.168.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="GQvTzHuF"
Received: from pps.filterd (m0279867.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 51770UuP030010;
	Fri, 7 Feb 2025 07:56:14 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	kNq6L0c5qKQyE1fQoCQzWkmpOXHchucSyPK/fGOhTAY=; b=GQvTzHuFraxDp1mY
	TzKFb2bZUBgGnCbTYbPc98UWGxUyAw+cOhISnGGMTKuA7NcpuSKY+bD+N9XOiQHp
	VruplfM2K2T8xxzPsYOwh+C+cXl6TLaQ4P9/s1cjWWrA4o8BPKTgDNUd2IpMsZpB
	haEl5jnVuNmVJcC793uABcINrfvXVvGDZmOzbFRQNJBWXPzoFZYjLkxPiv5BHUxj
	MhqP4PR16ZwVS4HEA/2B2ctTm9tl/W08HViLUrBuk/67bEDbTmpUSOBS5O8ALNnb
	oPHNL9veZhOIEQM9StqRcWcTWAnHYq1WinpuY0iI6cu5wvUBEVjnpNlcSmjIMjfV
	4iLeXA==
Received: from nalasppmta03.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44nddjg466-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:56:13 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA03.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177uDSA029182
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:56:13 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:56:06 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:24:51 +0530
Subject: [PATCH v10 11/28] media: iris: implement g_selection ioctl
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-11-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>,
        Vedang Nagar <quic_vnagar@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914893; l=2254;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=7Cs775TlbEU+Di/XtCbY3HQzeUSrCtqWHzQwrkSDLt8=;
 b=FRp+rpk9kwDPg3lfxa9pHNmjfqDrnOJSNfAEdEFq3/TTAVHQWfzdCanac0WgjnF6sXW9s4TIV
 xDeJPqSREc3BtactruExEZx1H+6zxFukGY49cjhVnc7YHCKuC0k0EZ5
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-ORIG-GUID: XJImYgJcxhFAXSvBzfVLV3lDSIkm54r7
X-Proofpoint-GUID: XJImYgJcxhFAXSvBzfVLV3lDSIkm54r7
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 mlxscore=0 impostorscore=0
 adultscore=0 bulkscore=0 phishscore=0 malwarescore=0 lowpriorityscore=0
 mlxlogscore=999 priorityscore=1501 clxscore=1015 suspectscore=0
 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070060

From: Vedang Nagar <quic_vnagar@quicinc.com>

Implement the g_selection ioctl op in the driver with the necessary
hooks.

Signed-off-by: Vedang Nagar <quic_vnagar@quicinc.com>
Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl>
Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 drivers/media/platform/qcom/iris/iris_vidc.c | 28 ++++++++++++++++++++++++=
++++
 1 file changed, 28 insertions(+)

diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/p=
latform/qcom/iris/iris_vidc.c
index bec965284b6e..92eb793cbeb7 100644
--- a/drivers/media/platform/qcom/iris/iris_vidc.c
+++ b/drivers/media/platform/qcom/iris/iris_vidc.c
@@ -259,6 +259,33 @@ static int iris_g_fmt_vid_mplane(struct file *filp, vo=
id *fh, struct v4l2_format
 	return ret;
 }
=20
+static int iris_g_selection(struct file *filp, void *fh, struct v4l2_selec=
tion *s)
+{
+	struct iris_inst *inst =3D iris_get_inst(filp, NULL);
+
+	if (s->type !=3D V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+
+	switch (s->target) {
+	case V4L2_SEL_TGT_CROP_BOUNDS:
+	case V4L2_SEL_TGT_CROP_DEFAULT:
+	case V4L2_SEL_TGT_CROP:
+	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+	case V4L2_SEL_TGT_COMPOSE_PADDED:
+	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+	case V4L2_SEL_TGT_COMPOSE:
+		s->r.left =3D inst->crop.left;
+		s->r.top =3D inst->crop.top;
+		s->r.width =3D inst->crop.width;
+		s->r.height =3D inst->crop.height;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static struct v4l2_file_operations iris_v4l2_file_ops =3D {
 	.owner                          =3D THIS_MODULE,
 	.open                           =3D iris_open,
@@ -280,6 +307,7 @@ static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops =
=3D {
 	.vidioc_g_fmt_vid_cap_mplane    =3D iris_g_fmt_vid_mplane,
 	.vidioc_g_fmt_vid_out_mplane    =3D iris_g_fmt_vid_mplane,
 	.vidioc_reqbufs                 =3D v4l2_m2m_ioctl_reqbufs,
+	.vidioc_g_selection             =3D iris_g_selection,
 };
=20
 void iris_init_ops(struct iris_core *core)

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 412A8235C1F;
	Fri,  7 Feb 2025 07:56:34 +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=1738914996; cv=none;
 b=LV8RHZI5VQS6EPWcCi+mHYFChC8IfhHmphn9+UTwwAp3oxAYUIdI1MySg/m8yfU73QeZR2ioteDPgQG1uC5pZhF2AS1IihqWRzK345DAgfq3FUe9q1bveEzx2+qgI3Fd6J3ZbuChAcLwVgGTy7uExndvo+gBVnhCOSZLUM9kK80=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738914996; c=relaxed/simple;
	bh=cU14kIrDFaUSd5JWoBanQm+8cN7k2BgUFwMbB1TWBBg=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=r6wp7dcRRqJaKT51CVfGyw+QASObx06AbqlxyTqVgJj/d7cxLmD8faiZ1mX8MvqWUtJg7wcxptmoMJJdDRJQIDkZY8BDTNFNE8KdcdjeJdWJ7V2e3F3iLzF1JFdQ9+Kz/I7LZ7BAwGTm4uXbFyb1RfTMI72WPR2sArq+iGn1bq0=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=Y/aU/6Bx; arc=none smtp.client-ip=205.220.168.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="Y/aU/6Bx"
Received: from pps.filterd (m0279867.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 51770UuT030010;
	Fri, 7 Feb 2025 07:56:20 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	0fQw3F4SRYIdQDXfvrtr4Jd95suCujoXKTX1dDm1DWY=; b=Y/aU/6BxDK8zultF
	qqpZjyLO2AmkiO2hjEV4pMKSOAX6NOvVEpgeomN8XhTGEJJA0Wy0jMeR7k512CIE
	JotcjDRl1jR3+UGXVHvyD38yuvYnbln9CgDLzpM6lElxyEvvt+wg10CsdpMR2XTl
	zTiavImEB5zGtMWmz9rPsmIHv4F0Ti9k1D2tK7WzWAs9UxPFQM+0kRePHKJ2zHEI
	aq5Zn0jYeJ40FGuHoDQ/ACDj79pBQy2wbAmFdZJtnZuJGl0P1VErXyJI34XbQz08
	4e+jJ7PIGSisKCkNEiYcBIDLJic8TACeTu6FhyUM6zrooeHeb6Fc5L/qGkkpMGuW
	wr5UWQ==
Received: from nalasppmta01.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44nddjg46j-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:56:20 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA01.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177uJJi010170
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:56:19 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:56:13 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:24:52 +0530
Subject: [PATCH v10 12/28] media: iris: implement enum_fmt and
 enum_framesizes ioctls
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-12-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>,
        Vedang Nagar <quic_vnagar@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914893; l=6088;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=KiUUGBYFOf39z3E6mOkL4Q6ob2pV467Ul16wA8R6Tuw=;
 b=ok3zL1qvjzTKAT4qnhWmka28aYLnsPb7ffimuc+v6uywhKXZRou3pAGWghiNE8v915w1yCGeP
 bd6DOV9Y1IIBpqCluGituXZAro7ZtU3JFCtyNenQMLbHE0kG8HoIxCZ
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-ORIG-GUID: LXMYOlLhP_XRpFHDzXM9mUVVs6vB7Dvz
X-Proofpoint-GUID: LXMYOlLhP_XRpFHDzXM9mUVVs6vB7Dvz
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 mlxscore=0 impostorscore=0
 adultscore=0 bulkscore=0 phishscore=0 malwarescore=0 lowpriorityscore=0
 mlxlogscore=999 priorityscore=1501 clxscore=1015 suspectscore=0
 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070060

From: Vedang Nagar <quic_vnagar@quicinc.com>

Implement the enum_fmt and enum_framesizes ioctls with the necessary
hooks.

Signed-off-by: Vedang Nagar <quic_vnagar@quicinc.com>
Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl>
Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 .../platform/qcom/iris/iris_platform_common.h      |  4 +++
 .../platform/qcom/iris/iris_platform_sm8550.c      |  4 +++
 drivers/media/platform/qcom/iris/iris_vdec.c       | 17 ++++++++++
 drivers/media/platform/qcom/iris/iris_vdec.h       |  1 +
 drivers/media/platform/qcom/iris/iris_vidc.c       | 39 ++++++++++++++++++=
++++
 5 files changed, 65 insertions(+)

diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/driv=
ers/media/platform/qcom/iris/iris_platform_common.h
index d508477b066e..75d4932df910 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -43,6 +43,10 @@ struct ubwc_config_data {
 };
=20
 struct platform_inst_caps {
+	u32 min_frame_width;
+	u32 max_frame_width;
+	u32 min_frame_height;
+	u32 max_frame_height;
 	u32 max_mbpf;
 };
 struct iris_core_power {
diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/driv=
ers/media/platform/qcom/iris/iris_platform_sm8550.c
index e4232c755074..3972b64dbda6 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
@@ -11,6 +11,10 @@
 #define VIDEO_ARCH_LX 1
=20
 static struct platform_inst_caps platform_inst_cap_sm8550 =3D {
+	.min_frame_width =3D 96,
+	.max_frame_width =3D 8192,
+	.min_frame_height =3D 96,
+	.max_frame_height =3D 8192,
 	.max_mbpf =3D (8192 * 4352) / 256,
 };
=20
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/p=
latform/qcom/iris/iris_vdec.c
index 38a5df8191cc..081a9eda5c49 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.c
+++ b/drivers/media/platform/qcom/iris/iris_vdec.c
@@ -58,6 +58,23 @@ void iris_vdec_inst_deinit(struct iris_inst *inst)
 	kfree(inst->fmt_src);
 }
=20
+int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f)
+{
+	switch (f->type) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		f->pixelformat =3D V4L2_PIX_FMT_H264;
+		f->flags =3D V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_DYN_RESOLUTION;
+		break;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+		f->pixelformat =3D V4L2_PIX_FMT_NV12;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f)
 {
 	struct v4l2_pix_format_mplane *pixmp =3D &f->fmt.pix_mp;
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.h b/drivers/media/p=
latform/qcom/iris/iris_vdec.h
index 85e93f33e9e7..ae456676e578 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.h
+++ b/drivers/media/platform/qcom/iris/iris_vdec.h
@@ -10,6 +10,7 @@ struct iris_inst;
=20
 void iris_vdec_inst_init(struct iris_inst *inst);
 void iris_vdec_inst_deinit(struct iris_inst *inst);
+int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f);
 int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f);
 int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f);
=20
diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/p=
latform/qcom/iris/iris_vidc.c
index 92eb793cbeb7..82bd0be8e5da 100644
--- a/drivers/media/platform/qcom/iris/iris_vidc.c
+++ b/drivers/media/platform/qcom/iris/iris_vidc.c
@@ -217,6 +217,16 @@ int iris_close(struct file *filp)
 	return 0;
 }
=20
+static int iris_enum_fmt(struct file *filp, void *fh, struct v4l2_fmtdesc =
*f)
+{
+	struct iris_inst *inst =3D iris_get_inst(filp, NULL);
+
+	if (f->index)
+		return -EINVAL;
+
+	return iris_vdec_enum_fmt(inst, f);
+}
+
 static int iris_try_fmt_vid_mplane(struct file *filp, void *fh, struct v4l=
2_format *f)
 {
 	struct iris_inst *inst =3D iris_get_inst(filp, NULL);
@@ -259,6 +269,32 @@ static int iris_g_fmt_vid_mplane(struct file *filp, vo=
id *fh, struct v4l2_format
 	return ret;
 }
=20
+static int iris_enum_framesizes(struct file *filp, void *fh,
+				struct v4l2_frmsizeenum *fsize)
+{
+	struct iris_inst *inst =3D iris_get_inst(filp, NULL);
+	struct platform_inst_caps *caps;
+
+	if (fsize->index)
+		return -EINVAL;
+
+	if (fsize->pixel_format !=3D V4L2_PIX_FMT_H264 &&
+	    fsize->pixel_format !=3D V4L2_PIX_FMT_NV12)
+		return -EINVAL;
+
+	caps =3D inst->core->iris_platform_data->inst_caps;
+
+	fsize->type =3D V4L2_FRMSIZE_TYPE_STEPWISE;
+	fsize->stepwise.min_width =3D caps->min_frame_width;
+	fsize->stepwise.max_width =3D caps->max_frame_width;
+	fsize->stepwise.step_width =3D STEP_WIDTH;
+	fsize->stepwise.min_height =3D caps->min_frame_height;
+	fsize->stepwise.max_height =3D caps->max_frame_height;
+	fsize->stepwise.step_height =3D STEP_HEIGHT;
+
+	return 0;
+}
+
 static int iris_g_selection(struct file *filp, void *fh, struct v4l2_selec=
tion *s)
 {
 	struct iris_inst *inst =3D iris_get_inst(filp, NULL);
@@ -300,12 +336,15 @@ static const struct vb2_ops iris_vb2_ops =3D {
 };
=20
 static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops =3D {
+	.vidioc_enum_fmt_vid_cap        =3D iris_enum_fmt,
+	.vidioc_enum_fmt_vid_out        =3D iris_enum_fmt,
 	.vidioc_try_fmt_vid_cap_mplane  =3D iris_try_fmt_vid_mplane,
 	.vidioc_try_fmt_vid_out_mplane  =3D iris_try_fmt_vid_mplane,
 	.vidioc_s_fmt_vid_cap_mplane    =3D iris_s_fmt_vid_mplane,
 	.vidioc_s_fmt_vid_out_mplane    =3D iris_s_fmt_vid_mplane,
 	.vidioc_g_fmt_vid_cap_mplane    =3D iris_g_fmt_vid_mplane,
 	.vidioc_g_fmt_vid_out_mplane    =3D iris_g_fmt_vid_mplane,
+	.vidioc_enum_framesizes         =3D iris_enum_framesizes,
 	.vidioc_reqbufs                 =3D v4l2_m2m_ioctl_reqbufs,
 	.vidioc_g_selection             =3D iris_g_selection,
 };

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 6B57C235C1F;
	Fri,  7 Feb 2025 07:56:41 +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=1738915003; cv=none;
 b=NGsOwPOKNBQ+WVxq5nkm/g843pRmFZadpRZncjtY11VyG3eK7yKbGscCDZ5oF0ZMgYDmL/LRuyxBhMp5WHD6hCHXWmPFV57BYilBYcmTrDeZ+Ldy3Zrz4+UKzJdoQChM3Z47rwpiDF4PhnHKwWcEycYRBhS8mZYIbOl+HljVidE=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738915003; c=relaxed/simple;
	bh=SN0+8OUeYx6Ycv5FsKG7ZySHWJvwNydISpq1tV+Ga7w=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=GxVbm+Tl0YZcRxgi9cgZ1dLrLgbWu1uGObBFXNU7iQJHhQQEiGGNHQhtUr6Gj0L71oGrknunu3vIFKbVD0JHIBEK95ZwSwhSCt8yXgv8RN87ZVwRXOjHDCdrqwLed8xjRJAc3FP2MswFsLRUsOVgTunimWO5/IzgUjGHobnrIvE=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=Y5rsZd3e; arc=none smtp.client-ip=205.220.180.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="Y5rsZd3e"
Received: from pps.filterd (m0279873.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 5172RcfF016918;
	Fri, 7 Feb 2025 07:56:27 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	GjXMTVUllVy78EkmOy9kpHwo0A1HaJmZ/QBCxndRtiw=; b=Y5rsZd3es/sYrJ0e
	eTSquJ6kIiaEcjRfPjVRDobsWu+RXtcWEfKjuWpM0rHY4eaFLN3KAJNNdboUViw3
	UlPS5CqaFpZcBWQTdiHrK1rI382ivfK0sK99Ck7zLJmRTRzr6JtR8ot1wXNFqAmY
	EJkLgI73inVsW/+QPazPoVWFa9S/NL7aFftTpXZwLucT3+rL3kGcSWG/w/v7mCBH
	mDK5O/PolT8gR8I/SMbGqmCSb7RC7Zh+K6Zr/b3oIB6mA/XxjAUDPWCzAqJ1iKHG
	UoUrt64Y7PeVO/kF855uJETC9ysfra6k5GUa2mSMfogo8WGgJYSl78IYhGAePdig
	FlgFqg==
Received: from nalasppmta04.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44n9dkgqap-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:56:27 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA04.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177uQaQ009377
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:56:26 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:56:19 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:24:53 +0530
Subject: [PATCH v10 13/28] media: iris: implement subscribe_event and
 unsubscribe_event ioctls
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-13-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>,
        Vedang Nagar <quic_vnagar@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914893; l=3840;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=vp3JWbsgR+QiDhbx+dBhKdtCHa9MNtDw/tSGXG8XdAs=;
 b=xdpSYnnkkehEjsc7U4KAnV7ZMDbQ5Tm314QSt7nVUSl5ajGaCYEsqPvhTebmGB2r6ZkvU1SDF
 sNCDtzbD4DMA+mIG2AS/ZMYgnQe1jEcEOPEaTAsjFM5eKzCZNRYbiNY
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-GUID: Sfjv4eWqszNN9EYSNwUuOQCBdVesflHK
X-Proofpoint-ORIG-GUID: Sfjv4eWqszNN9EYSNwUuOQCBdVesflHK
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 mlxscore=0 suspectscore=0
 phishscore=0 clxscore=1015 priorityscore=1501 mlxlogscore=999 spamscore=0
 bulkscore=0 malwarescore=0 adultscore=0 lowpriorityscore=0 impostorscore=0
 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2501170000
 definitions=main-2502070060

From: Vedang Nagar <quic_vnagar@quicinc.com>

Implement the subscribe_event and unsubscribe_event iocts with the
necessary hooks.

Signed-off-by: Vedang Nagar <quic_vnagar@quicinc.com>
Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl>
Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 drivers/media/platform/qcom/iris/iris_vdec.c | 22 ++++++++++++++++++++++
 drivers/media/platform/qcom/iris/iris_vdec.h |  1 +
 drivers/media/platform/qcom/iris/iris_vidc.c | 10 ++++++++++
 3 files changed, 33 insertions(+)

diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/p=
latform/qcom/iris/iris_vdec.c
index 081a9eda5c49..0ba60bcb9fa9 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.c
+++ b/drivers/media/platform/qcom/iris/iris_vdec.c
@@ -3,6 +3,7 @@
  * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
  */
=20
+#include <media/v4l2-event.h>
 #include <media/v4l2-mem2mem.h>
=20
 #include "iris_buffer.h"
@@ -193,3 +194,24 @@ int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l=
2_format *f)
=20
 	return 0;
 }
+
+int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_ev=
ent_subscription *sub)
+{
+	int ret =3D 0;
+
+	switch (sub->type) {
+	case V4L2_EVENT_EOS:
+		ret =3D v4l2_event_subscribe(&inst->fh, sub, 0, NULL);
+		break;
+	case V4L2_EVENT_SOURCE_CHANGE:
+		ret =3D v4l2_src_change_event_subscribe(&inst->fh, sub);
+		break;
+	case V4L2_EVENT_CTRL:
+		ret =3D v4l2_ctrl_subscribe_event(&inst->fh, sub);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return ret;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.h b/drivers/media/p=
latform/qcom/iris/iris_vdec.h
index ae456676e578..f64ce3234e6a 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.h
+++ b/drivers/media/platform/qcom/iris/iris_vdec.h
@@ -13,5 +13,6 @@ void iris_vdec_inst_deinit(struct iris_inst *inst);
 int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f);
 int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f);
 int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f);
+int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_ev=
ent_subscription *sub);
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/p=
latform/qcom/iris/iris_vidc.c
index 82bd0be8e5da..511cd13ac471 100644
--- a/drivers/media/platform/qcom/iris/iris_vidc.c
+++ b/drivers/media/platform/qcom/iris/iris_vidc.c
@@ -4,6 +4,7 @@
  */
=20
 #include <linux/pm_runtime.h>
+#include <media/v4l2-event.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-mem2mem.h>
=20
@@ -322,6 +323,13 @@ static int iris_g_selection(struct file *filp, void *f=
h, struct v4l2_selection *
 	return 0;
 }
=20
+static int iris_subscribe_event(struct v4l2_fh *fh, const struct v4l2_even=
t_subscription *sub)
+{
+	struct iris_inst *inst =3D container_of(fh, struct iris_inst, fh);
+
+	return iris_vdec_subscribe_event(inst, sub);
+}
+
 static struct v4l2_file_operations iris_v4l2_file_ops =3D {
 	.owner                          =3D THIS_MODULE,
 	.open                           =3D iris_open,
@@ -347,6 +355,8 @@ static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops =
=3D {
 	.vidioc_enum_framesizes         =3D iris_enum_framesizes,
 	.vidioc_reqbufs                 =3D v4l2_m2m_ioctl_reqbufs,
 	.vidioc_g_selection             =3D iris_g_selection,
+	.vidioc_subscribe_event         =3D iris_subscribe_event,
+	.vidioc_unsubscribe_event       =3D v4l2_event_unsubscribe,
 };
=20
 void iris_init_ops(struct iris_core *core)

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 A2873235C1F;
	Fri,  7 Feb 2025 07:56:48 +0000 (UTC)
Authentication-Results: smtp.subspace.kernel.org;
 arc=none smtp.client-ip=205.220.180.131
ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
	t=1738915010; cv=none;
 b=ZGknxvJWAUh5ioJfiQMYUvmDspGrejfFGSqNzklu6uhIL6gxCpQsy0atPYRPYnjTyTM7l+aMzvp+buHva/PtK8cRGOR2rUFDrlqPjNiKvh2SZMjQWxEKn3xKTZY67YGka3wkxhfMOiPQXO9EU/dhagFeSTG8l7Vv6mRNmN2NNc0=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738915010; c=relaxed/simple;
	bh=Pm6W1PNIrvHazH/3PVknozdlUPEWvPEK7Vb7e2OnlXg=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=o/6chxBxQ/Jb8zpw9B2mFML/BsWUKdkz9tY3tVqQmvOtwahymEsyuhVDAlEU8rUy4m1W42m02ieTYSB2knYjLc9DBUM8sk3CcPFQ5xz1WPKf452K1Jqc1+8wXPGjhGK7ytThEMT1pwkFNH/Uyxo8nCii9F6qGq8JhfZ/O0upO3I=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=X76lUe7j; arc=none smtp.client-ip=205.220.180.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="X76lUe7j"
Received: from pps.filterd (m0279868.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 5172IcoN003478;
	Fri, 7 Feb 2025 07:56:34 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	oFuEHSq/wJVbU08B8p3bAiDHmHkb2SE7BCVfApjrwUc=; b=X76lUe7j5jcNYKXq
	gZ50EguFC/+TnUwaP97CQ9/aPi4EnGda/Gpgmjs1A8IqenDa4siU8TPV7HTQly6h
	NycKYL25Am1NxFAqSVPHtDJdulUVNZmwO9Oo5aAD2uIC3S9m38tJeMpboNmLpG7k
	+rezmnFMhsQ+G9jjCkA4uKThy0cv03KV3mMnjfireZZ9yxos4TRjBXWiucPAj4m7
	ihivTJiFz/vc6nMrtQo6QDTMl6EY7e1zVv5G75djNxRF/ISo2AqgOLGcvl4VuHCu
	Yd/2hOykU5b9JjpBndgjYBR20qwGs/Ppf3De4BuHLEMRThYTT/Dli3y9Kyq+fFPW
	K9rEQA==
Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44n99e8qcg-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:56:34 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA05.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177uXJG028748
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:56:33 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:56:26 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:24:54 +0530
Subject: [PATCH v10 14/28] media: iris: implement iris v4l2_ctrl_ops
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-14-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>,
        Vedang Nagar <quic_vnagar@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914893; l=17777;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=Pm6W1PNIrvHazH/3PVknozdlUPEWvPEK7Vb7e2OnlXg=;
 b=4gEyooKOBgnanKMflTkfSGTZdoKXqvn/D0xlsk14s2p8RsoBLogHqJqpGxjwrTbN0EwCKbbZM
 wEVf/J8jFVkDfn+wIo4tTNIZDTlYHm80bpKNdtXG2r2USiUDjOr2mi+
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-ORIG-GUID: iXIh4PONUpm7kN6A_y8lyJu6-CEv5y3m
X-Proofpoint-GUID: iXIh4PONUpm7kN6A_y8lyJu6-CEv5y3m
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 clxscore=1015 suspectscore=0
 mlxscore=0 lowpriorityscore=0 impostorscore=0 priorityscore=1501
 phishscore=0 adultscore=0 mlxlogscore=999 malwarescore=0 spamscore=0
 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070060

Initialize the control handler by reading the platform specific firmware
capabilities. Capabilities are features, which are supported by a
specific platform (SOC). Each capability is defined with a min, max,
range and default value and a corresponding HFI. Implement s_ctrl and
g_volatile_ctrl ctrl ops.

Co-developed-by: Vedang Nagar <quic_vnagar@quicinc.com>
Signed-off-by: Vedang Nagar <quic_vnagar@quicinc.com>
Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl>
Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 drivers/media/platform/qcom/iris/Makefile          |   1 +
 drivers/media/platform/qcom/iris/iris_core.h       |   2 +
 drivers/media/platform/qcom/iris/iris_ctrls.c      | 165 +++++++++++++++++=
++++
 drivers/media/platform/qcom/iris/iris_ctrls.h      |  17 +++
 .../platform/qcom/iris/iris_hfi_gen2_defines.h     |   2 +
 drivers/media/platform/qcom/iris/iris_instance.h   |   4 +
 .../platform/qcom/iris/iris_platform_common.h      |  30 ++++
 .../platform/qcom/iris/iris_platform_sm8550.c      |  47 ++++++
 drivers/media/platform/qcom/iris/iris_probe.c      |   3 +
 drivers/media/platform/qcom/iris/iris_vdec.c       |   9 +-
 drivers/media/platform/qcom/iris/iris_vdec.h       |   2 +-
 drivers/media/platform/qcom/iris/iris_vidc.c       |   9 +-
 12 files changed, 288 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/plat=
form/qcom/iris/Makefile
index 48ab264b7906..f685d76c2f79 100644
--- a/drivers/media/platform/qcom/iris/Makefile
+++ b/drivers/media/platform/qcom/iris/Makefile
@@ -1,5 +1,6 @@
 iris-objs +=3D iris_buffer.o \
              iris_core.o \
+             iris_ctrls.o \
              iris_firmware.o \
              iris_hfi_common.o \
              iris_hfi_gen1_command.o \
diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/p=
latform/qcom/iris/iris_core.h
index 1ddcb8793172..37fb4919fecc 100644
--- a/drivers/media/platform/qcom/iris/iris_core.h
+++ b/drivers/media/platform/qcom/iris/iris_core.h
@@ -63,6 +63,7 @@ struct icc_info {
  * @intr_status: interrupt status
  * @sys_error_handler: a delayed work for handling system fatal error
  * @instances: a list_head of all instances
+ * @inst_fw_caps: an array of supported instance capabilities
  */
=20
 struct iris_core {
@@ -101,6 +102,7 @@ struct iris_core {
 	u32					intr_status;
 	struct delayed_work			sys_error_handler;
 	struct list_head			instances;
+	struct platform_inst_fw_cap		inst_fw_caps[INST_FW_CAP_MAX];
 };
=20
 int iris_core_init(struct iris_core *core);
diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/=
platform/qcom/iris/iris_ctrls.c
new file mode 100644
index 000000000000..3652fa535bf3
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_ctrls.c
@@ -0,0 +1,165 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#include <media/v4l2-mem2mem.h>
+#include "iris_ctrls.h"
+#include "iris_instance.h"
+
+static inline bool iris_valid_cap_id(enum platform_inst_fw_cap_type cap_id)
+{
+	return cap_id >=3D 1 && cap_id < INST_FW_CAP_MAX;
+}
+
+static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)
+{
+	switch (id) {
+	case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER:
+		return DEBLOCK;
+	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
+		return PROFILE;
+	case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
+		return LEVEL;
+	default:
+		return INST_FW_CAP_MAX;
+	}
+}
+
+static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id)
+{
+	if (!iris_valid_cap_id(cap_id))
+		return 0;
+
+	switch (cap_id) {
+	case DEBLOCK:
+		return V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER;
+	case PROFILE:
+		return V4L2_CID_MPEG_VIDEO_H264_PROFILE;
+	case LEVEL:
+		return V4L2_CID_MPEG_VIDEO_H264_LEVEL;
+	default:
+		return 0;
+	}
+}
+
+static int iris_vdec_op_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct iris_inst *inst =3D container_of(ctrl->handler, struct iris_inst, =
ctrl_handler);
+	enum platform_inst_fw_cap_type cap_id;
+	struct platform_inst_fw_cap *cap;
+	struct vb2_queue *q;
+
+	cap =3D &inst->fw_caps[0];
+	cap_id =3D iris_get_cap_id(ctrl->id);
+	if (!iris_valid_cap_id(cap_id))
+		return -EINVAL;
+
+	q =3D v4l2_m2m_get_src_vq(inst->m2m_ctx);
+	if (vb2_is_streaming(q) &&
+	    (!(inst->fw_caps[cap_id].flags & CAP_FLAG_DYNAMIC_ALLOWED)))
+		return -EINVAL;
+
+	cap[cap_id].flags |=3D CAP_FLAG_CLIENT_SET;
+
+	inst->fw_caps[cap_id].value =3D ctrl->val;
+
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops iris_ctrl_ops =3D {
+	.s_ctrl =3D iris_vdec_op_s_ctrl,
+};
+
+int iris_ctrls_init(struct iris_inst *inst)
+{
+	struct platform_inst_fw_cap *cap =3D &inst->fw_caps[0];
+	u32 num_ctrls =3D 0, ctrl_idx =3D 0, idx =3D 0;
+	u32 v4l2_id;
+	int ret;
+
+	for (idx =3D 1; idx < INST_FW_CAP_MAX; idx++) {
+		if (iris_get_v4l2_id(cap[idx].cap_id))
+			num_ctrls++;
+	}
+	if (!num_ctrls)
+		return -EINVAL;
+
+	/* Adding 1 to num_ctrls to include V4L2_CID_MIN_BUFFERS_FOR_CAPTURE */
+
+	ret =3D v4l2_ctrl_handler_init(&inst->ctrl_handler, num_ctrls + 1);
+	if (ret)
+		return ret;
+
+	for (idx =3D 1; idx < INST_FW_CAP_MAX; idx++) {
+		struct v4l2_ctrl *ctrl;
+
+		v4l2_id =3D iris_get_v4l2_id(cap[idx].cap_id);
+		if (!v4l2_id)
+			continue;
+
+		if (ctrl_idx >=3D num_ctrls) {
+			ret =3D -EINVAL;
+			goto error;
+		}
+
+		if (cap[idx].flags & CAP_FLAG_MENU) {
+			ctrl =3D v4l2_ctrl_new_std_menu(&inst->ctrl_handler,
+						      &iris_ctrl_ops,
+						      v4l2_id,
+						      cap[idx].max,
+						      ~(cap[idx].step_or_mask),
+						      cap[idx].value);
+		} else {
+			ctrl =3D v4l2_ctrl_new_std(&inst->ctrl_handler,
+						 &iris_ctrl_ops,
+						 v4l2_id,
+						 cap[idx].min,
+						 cap[idx].max,
+						 cap[idx].step_or_mask,
+						 cap[idx].value);
+		}
+		if (!ctrl) {
+			ret =3D -EINVAL;
+			goto error;
+		}
+
+		ctrl_idx++;
+	}
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, NULL,
+			  V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 4);
+
+	ret =3D inst->ctrl_handler.error;
+	if (ret)
+		goto error;
+
+	return 0;
+error:
+	v4l2_ctrl_handler_free(&inst->ctrl_handler);
+
+	return ret;
+}
+
+void iris_session_init_caps(struct iris_core *core)
+{
+	struct platform_inst_fw_cap *caps;
+	u32 i, num_cap, cap_id;
+
+	caps =3D core->iris_platform_data->inst_fw_caps;
+	num_cap =3D core->iris_platform_data->inst_fw_caps_size;
+
+	for (i =3D 0; i < num_cap; i++) {
+		cap_id =3D caps[i].cap_id;
+		if (!iris_valid_cap_id(cap_id))
+			continue;
+
+		core->inst_fw_caps[cap_id].cap_id =3D caps[i].cap_id;
+		core->inst_fw_caps[cap_id].min =3D caps[i].min;
+		core->inst_fw_caps[cap_id].max =3D caps[i].max;
+		core->inst_fw_caps[cap_id].step_or_mask =3D caps[i].step_or_mask;
+		core->inst_fw_caps[cap_id].value =3D caps[i].value;
+		core->inst_fw_caps[cap_id].flags =3D caps[i].flags;
+		core->inst_fw_caps[cap_id].hfi_id =3D caps[i].hfi_id;
+	}
+}
diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.h b/drivers/media/=
platform/qcom/iris/iris_ctrls.h
new file mode 100644
index 000000000000..fe65a772e6dd
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_ctrls.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#ifndef __IRIS_CTRLS_H__
+#define __IRIS_CTRLS_H__
+
+#include "iris_platform_common.h"
+
+struct iris_core;
+struct iris_inst;
+
+int iris_ctrls_init(struct iris_inst *inst);
+void iris_session_init_caps(struct iris_core *core);
+
+#endif
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
index ccf5fd0902d7..173a554a0d44 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
@@ -28,6 +28,8 @@
 #define HFI_PROP_UBWC_BANK_SWZL_LEVEL3		0x03000008
 #define HFI_PROP_UBWC_BANK_SPREADING		0x03000009
 #define HFI_PROP_CODEC				0x03000100
+#define HFI_PROP_PROFILE			0x03000107
+#define HFI_PROP_LEVEL				0x03000108
 #define HFI_PROP_DEC_DEFAULT_HEADER		0x03000168
 #define HFI_PROP_END				0x03FFFFFF
=20
diff --git a/drivers/media/platform/qcom/iris/iris_instance.h b/drivers/med=
ia/platform/qcom/iris/iris_instance.h
index b9c7dcfb20f7..9f1a1e5ba7c7 100644
--- a/drivers/media/platform/qcom/iris/iris_instance.h
+++ b/drivers/media/platform/qcom/iris/iris_instance.h
@@ -23,8 +23,10 @@
  * @fh: reference of v4l2 file handler
  * @fmt_src: structure of v4l2_format for source
  * @fmt_dst: structure of v4l2_format for destination
+ * @ctrl_handler: reference of v4l2 ctrl handler
  * @crop: structure of crop info
  * @completion: structure of signal completions
+ * @fw_caps: array of supported instance firmware capabilities
  * @buffers: array of different iris buffers
  * @fw_min_count: minimnum count of buffers needed by fw
  * @once_per_session_set: boolean to set once per session property
@@ -41,8 +43,10 @@ struct iris_inst {
 	struct v4l2_fh			fh;
 	struct v4l2_format		*fmt_src;
 	struct v4l2_format		*fmt_dst;
+	struct v4l2_ctrl_handler	ctrl_handler;
 	struct iris_hfi_rect_desc	crop;
 	struct completion		completion;
+	struct platform_inst_fw_cap	fw_caps[INST_FW_CAP_MAX];
 	struct iris_buffers		buffers[BUF_TYPE_MAX];
 	u32				fw_min_count;
 	bool				once_per_session_set;
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/driv=
ers/media/platform/qcom/iris/iris_platform_common.h
index 75d4932df910..23170cd37c04 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -49,6 +49,34 @@ struct platform_inst_caps {
 	u32 max_frame_height;
 	u32 max_mbpf;
 };
+
+enum platform_inst_fw_cap_type {
+	PROFILE =3D 1,
+	LEVEL,
+	DEBLOCK,
+	INST_FW_CAP_MAX,
+};
+
+enum platform_inst_fw_cap_flags {
+	CAP_FLAG_DYNAMIC_ALLOWED	=3D BIT(0),
+	CAP_FLAG_MENU			=3D BIT(1),
+	CAP_FLAG_INPUT_PORT		=3D BIT(2),
+	CAP_FLAG_OUTPUT_PORT		=3D BIT(3),
+	CAP_FLAG_CLIENT_SET		=3D BIT(4),
+	CAP_FLAG_BITMASK		=3D BIT(5),
+	CAP_FLAG_VOLATILE		=3D BIT(6),
+};
+
+struct platform_inst_fw_cap {
+	enum platform_inst_fw_cap_type cap_id;
+	s64 min;
+	s64 max;
+	s64 step_or_mask;
+	s64 value;
+	u32 hfi_id;
+	enum platform_inst_fw_cap_flags flags;
+};
+
 struct iris_core_power {
 	u64 clk_freq;
 	u64 icc_bw;
@@ -79,6 +107,8 @@ struct iris_platform_data {
 	const char *fwname;
 	u32 pas_id;
 	struct platform_inst_caps *inst_caps;
+	struct platform_inst_fw_cap *inst_fw_caps;
+	u32 inst_fw_caps_size;
 	struct tz_cp_config *tz_cp_config_data;
 	u32 core_arch;
 	u32 hw_response_timeout;
diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/driv=
ers/media/platform/qcom/iris/iris_platform_sm8550.c
index 3972b64dbda6..58b1d1d43731 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
@@ -5,11 +5,56 @@
=20
 #include "iris_core.h"
 #include "iris_hfi_gen2.h"
+#include "iris_hfi_gen2_defines.h"
 #include "iris_platform_common.h"
 #include "iris_vpu_common.h"
=20
 #define VIDEO_ARCH_LX 1
=20
+static struct platform_inst_fw_cap inst_fw_cap_sm8550[] =3D {
+	{
+		.cap_id =3D PROFILE,
+		.min =3D V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
+		.max =3D V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH,
+		.step_or_mask =3D BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
+				BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
+				BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
+				BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) |
+				BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH),
+		.value =3D V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
+		.hfi_id =3D HFI_PROP_PROFILE,
+		.flags =3D CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+	},
+	{
+		.cap_id =3D LEVEL,
+		.min =3D V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
+		.max =3D V4L2_MPEG_VIDEO_H264_LEVEL_6_2,
+		.step_or_mask =3D BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
+				BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
+				BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
+				BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |
+				BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |
+				BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |
+				BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |
+				BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |
+				BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |
+				BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |
+				BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
+				BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) |
+				BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) |
+				BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2) |
+				BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) |
+				BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1) |
+				BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_2) |
+				BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_0) |
+				BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_1) |
+				BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_2),
+		.value =3D V4L2_MPEG_VIDEO_H264_LEVEL_6_1,
+		.hfi_id =3D HFI_PROP_LEVEL,
+		.flags =3D CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+	},
+};
+
 static struct platform_inst_caps platform_inst_cap_sm8550 =3D {
 	.min_frame_width =3D 96,
 	.max_frame_width =3D 8192,
@@ -78,6 +123,8 @@ struct iris_platform_data sm8550_data =3D {
 	.fwname =3D "qcom/vpu/vpu30_p4.mbn",
 	.pas_id =3D IRIS_PAS_ID,
 	.inst_caps =3D &platform_inst_cap_sm8550,
+	.inst_fw_caps =3D inst_fw_cap_sm8550,
+	.inst_fw_caps_size =3D ARRAY_SIZE(inst_fw_cap_sm8550),
 	.tz_cp_config_data =3D &tz_cp_config_sm8550,
 	.core_arch =3D VIDEO_ARCH_LX,
 	.hw_response_timeout =3D HW_RESPONSE_TIMEOUT_VALUE,
diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/=
platform/qcom/iris/iris_probe.c
index a9162be5f9f6..954cc7c0cc97 100644
--- a/drivers/media/platform/qcom/iris/iris_probe.c
+++ b/drivers/media/platform/qcom/iris/iris_probe.c
@@ -12,6 +12,7 @@
 #include <linux/reset.h>
=20
 #include "iris_core.h"
+#include "iris_ctrls.h"
 #include "iris_vidc.h"
=20
 static int iris_init_icc(struct iris_core *core)
@@ -236,6 +237,8 @@ static int iris_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
=20
+	iris_session_init_caps(core);
+
 	ret =3D v4l2_device_register(dev, &core->v4l2_dev);
 	if (ret)
 		return ret;
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/p=
latform/qcom/iris/iris_vdec.c
index 0ba60bcb9fa9..132b578b34dc 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.c
+++ b/drivers/media/platform/qcom/iris/iris_vdec.c
@@ -7,6 +7,7 @@
 #include <media/v4l2-mem2mem.h>
=20
 #include "iris_buffer.h"
+#include "iris_ctrls.h"
 #include "iris_instance.h"
 #include "iris_vdec.h"
 #include "iris_vpu_buffer.h"
@@ -15,8 +16,9 @@
 #define DEFAULT_HEIGHT 240
 #define DEFAULT_CODEC_ALIGNMENT 16
=20
-void iris_vdec_inst_init(struct iris_inst *inst)
+int iris_vdec_inst_init(struct iris_inst *inst)
 {
+	struct iris_core *core =3D inst->core;
 	struct v4l2_format *f;
=20
 	inst->fmt_src  =3D kzalloc(sizeof(*inst->fmt_src), GFP_KERNEL);
@@ -51,6 +53,11 @@ void iris_vdec_inst_init(struct iris_inst *inst)
 	f->fmt.pix_mp.quantization =3D V4L2_QUANTIZATION_DEFAULT;
 	inst->buffers[BUF_OUTPUT].min_count =3D iris_vpu_buf_count(inst, BUF_OUTP=
UT);
 	inst->buffers[BUF_OUTPUT].size =3D f->fmt.pix_mp.plane_fmt[0].sizeimage;
+
+	memcpy(&inst->fw_caps[0], &core->inst_fw_caps[0],
+	       INST_FW_CAP_MAX * sizeof(struct platform_inst_fw_cap));
+
+	return iris_ctrls_init(inst);
 }
=20
 void iris_vdec_inst_deinit(struct iris_inst *inst)
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.h b/drivers/media/p=
latform/qcom/iris/iris_vdec.h
index f64ce3234e6a..9f08a13cb6bb 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.h
+++ b/drivers/media/platform/qcom/iris/iris_vdec.h
@@ -8,7 +8,7 @@
=20
 struct iris_inst;
=20
-void iris_vdec_inst_init(struct iris_inst *inst);
+int iris_vdec_inst_init(struct iris_inst *inst);
 void iris_vdec_inst_deinit(struct iris_inst *inst);
 int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f);
 int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f);
diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/p=
latform/qcom/iris/iris_vidc.c
index 511cd13ac471..90e70aa8eedf 100644
--- a/drivers/media/platform/qcom/iris/iris_vidc.c
+++ b/drivers/media/platform/qcom/iris/iris_vidc.c
@@ -23,12 +23,14 @@
 static void iris_v4l2_fh_init(struct iris_inst *inst)
 {
 	v4l2_fh_init(&inst->fh, inst->core->vdev_dec);
+	inst->fh.ctrl_handler =3D &inst->ctrl_handler;
 	v4l2_fh_add(&inst->fh);
 }
=20
 static void iris_v4l2_fh_deinit(struct iris_inst *inst)
 {
 	v4l2_fh_del(&inst->fh);
+	inst->fh.ctrl_handler =3D NULL;
 	v4l2_fh_exit(&inst->fh);
 }
=20
@@ -162,7 +164,9 @@ int iris_open(struct file *filp)
 		goto fail_m2m_release;
 	}
=20
-	iris_vdec_inst_init(inst);
+	ret =3D iris_vdec_inst_init(inst);
+	if (ret)
+		goto fail_m2m_ctx_release;
=20
 	iris_add_session(inst);
=20
@@ -171,6 +175,8 @@ int iris_open(struct file *filp)
=20
 	return 0;
=20
+fail_m2m_ctx_release:
+	v4l2_m2m_ctx_release(inst->m2m_ctx);
 fail_m2m_release:
 	v4l2_m2m_release(inst->m2m_dev);
 fail_v4l2_fh_deinit:
@@ -202,6 +208,7 @@ int iris_close(struct file *filp)
 {
 	struct iris_inst *inst =3D iris_get_inst(filp, NULL);
=20
+	v4l2_ctrl_handler_free(&inst->ctrl_handler);
 	v4l2_m2m_ctx_release(inst->m2m_ctx);
 	v4l2_m2m_release(inst->m2m_dev);
 	mutex_lock(&inst->lock);

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 0C47E23C36C;
	Fri,  7 Feb 2025 07:56:54 +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=1738915016; cv=none;
 b=hcTi/SPHSlQ1cmS3qv4w99GNaz37aEW6wX3uvS+yeB8+GIDtuknjtFDnWKZDBotO2BJAZuUZXpzYvKEJYtnbGY/aRhjg+v11C5GypB3v4l4hrK4yVqZuZhDvIKUV/E9mMCVzjzkp1iyo6Yd1bEAtAfiNx5RYKc3IBhCUCjkHXJs=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738915016; c=relaxed/simple;
	bh=ypnSGcff52MxR6I3AReMIT0RLmyB38HaZDqVcXVXTT8=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=uOg+buJEmAyWyO2LVjp/C/NBNQVx5YB87kwkvaatWlIn1tyBzqF3A6+Y0DioUENuIHLFqkM1BXvPmjiGrpBWefMM1FT6lrnmanm0+Y51OaJdiIYBEBuN4LnzqncvG8VkJ/qAm6ovf277pG/cy5m9jtj1nGiBi72qCANHFnbh254=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=N17W3EXE; arc=none smtp.client-ip=205.220.168.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="N17W3EXE"
Received: from pps.filterd (m0279864.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 51770llQ015199;
	Fri, 7 Feb 2025 07:56:40 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	aYj4c+drkttt6EVgc///D3ckKhrTSSxPMYRTqN/gRKQ=; b=N17W3EXEab2igeDP
	sW5n33iJpVYW9CEupAb0IIu+9hVkG9fRwB5uD/QJovL6uVzUQnmORxbnP8SLRfiR
	lJpB5S1VkaOxL52Zf3/STlOgQqTIe4gDdsRpJqa2X0H1Np6YHXicF0BPm6xMXsI5
	7/4NBWxxPSWIAardJhKMSCfKp4S/TvrsKPnhRwcSVD3xB9nu6yClydPQTQbTuhNX
	8hl7BucLVVI/wiy08fVPQD1eREv2FV3PPnxCOIMlz1J7HxPcK9eVDNmiO4Co8H2d
	q45XIxJGQlcgnOuerm64PXSZLCo5+yLGy3lNUQEG+qH5pfRaEYB2oOqrohxZiD1X
	RGF4cA==
Received: from nalasppmta02.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44nddm84d0-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:56:40 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA02.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177udVV031480
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:56:39 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:56:33 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:24:55 +0530
Subject: [PATCH v10 15/28] media: iris: implement query_cap ioctl
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-15-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>,
        Vedang Nagar <quic_vnagar@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914893; l=1840;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=Wia9U6nrvHa1GQBYuE3MwNdupxy/J3tmecBZa3UaJrc=;
 b=bV/co1aS4bx4gP7meOQSbPeLHsZBckhrAXSzYRf+gf2ChoscfbsH+xaQgFP037uJorFUY4kn3
 JlWEtCMW1OWCS8YKBP6Yj5RQ4pqHcIv+PnrIyMwPsiLBD1YFyi+a/0L
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-GUID: wG5AdwXgAezUNA-EhLR4ICLEy_xFE1V5
X-Proofpoint-ORIG-GUID: wG5AdwXgAezUNA-EhLR4ICLEy_xFE1V5
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 clxscore=1015 spamscore=0
 mlxlogscore=999 adultscore=0 priorityscore=1501 suspectscore=0
 lowpriorityscore=0 malwarescore=0 phishscore=0 mlxscore=0 bulkscore=0
 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070060

From: Vedang Nagar <quic_vnagar@quicinc.com>

Implement the query_cap ioctl with the necessary hooks.

Signed-off-by: Vedang Nagar <quic_vnagar@quicinc.com>
Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl>
Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 drivers/media/platform/qcom/iris/iris_vidc.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/p=
latform/qcom/iris/iris_vidc.c
index 90e70aa8eedf..5b54231f2def 100644
--- a/drivers/media/platform/qcom/iris/iris_vidc.c
+++ b/drivers/media/platform/qcom/iris/iris_vidc.c
@@ -303,6 +303,14 @@ static int iris_enum_framesizes(struct file *filp, voi=
d *fh,
 	return 0;
 }
=20
+static int iris_querycap(struct file *filp, void *fh, struct v4l2_capabili=
ty *cap)
+{
+	strscpy(cap->driver, IRIS_DRV_NAME, sizeof(cap->driver));
+	strscpy(cap->card, "Iris Decoder", sizeof(cap->card));
+
+	return 0;
+}
+
 static int iris_g_selection(struct file *filp, void *fh, struct v4l2_selec=
tion *s)
 {
 	struct iris_inst *inst =3D iris_get_inst(filp, NULL);
@@ -361,6 +369,7 @@ static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops =
=3D {
 	.vidioc_g_fmt_vid_out_mplane    =3D iris_g_fmt_vid_mplane,
 	.vidioc_enum_framesizes         =3D iris_enum_framesizes,
 	.vidioc_reqbufs                 =3D v4l2_m2m_ioctl_reqbufs,
+	.vidioc_querycap                =3D iris_querycap,
 	.vidioc_g_selection             =3D iris_g_selection,
 	.vidioc_subscribe_event         =3D iris_subscribe_event,
 	.vidioc_unsubscribe_event       =3D v4l2_event_unsubscribe,

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 2903F236A7E;
	Fri,  7 Feb 2025 07:57: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=1738915025; cv=none;
 b=FLuG1gA6cMYB2Hn7BO8DN9ab7uXCfO81zCe45zU+E8CCQ+NWRtRyGcfxyqSXgZ0o2zWWTAhryPpF0bjyqnVDuPK439q9LQVAak38uTzm0f8Alp1PJ/FMIOIRxyuJ2CPJy3G1FdaEGDNWsRaNqEuwLCK3KsRD4yQSWZ3OvTG7eC0=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738915025; c=relaxed/simple;
	bh=4+o3D9I2T3EZa3AVjfU0zwXYytUlTs7cGjnF9s4KmKE=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=hV2f3dhI048eYo/MHHNuz69fv+i74/kqdeM2pQ7QHd4XE9AIIl89ZRN0vJT43X0tU+MZGX5MrRekmmTEkE635xf63s4xQ+Csy4c76EVjqlxMHdm6aBMp1MOSmT3tddlA/bVsj/6iqlo0Lou4AUHgbz5bz601hDrqosF+AqTK8SE=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=NoVupIQI; arc=none smtp.client-ip=205.220.168.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="NoVupIQI"
Received: from pps.filterd (m0279867.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 51770d5P030052;
	Fri, 7 Feb 2025 07:56:47 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	VVyQ7mMlGDFvW3LSUWoyYASndj1Pp8d3JZNvOnwq8kE=; b=NoVupIQIbVf6XI64
	Hdi1/vdbTJ5TTXh9C5gonAWyJf5Ptfh8+sWO76nuNRMBkyiyE41dq5KO4PbC+mlW
	O9FigQx0JvDVZas2VD6gfz8P/daQRZybv+ghvFFVre4NzqM0oxm5WYa9k53GETXt
	JWsdyp9aoC73ZbJPdWGfHov8rNI1DzxV++GygV3BiU0N0OXPLEfJiXIhtYdmOr5+
	/NjN5r60EwDR0j/3IJTdgWxKdfU30jll3xXWbAmsZqYsj4GdI6tarLqj8PmEkjbs
	wDmOMcRPgK0Mxs6rcAE7TLQivFxPt/Q/z84av/n/jZ1ARGKWHzgdnSvQoHDY23kA
	93IGow==
Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44nddjg48a-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:56:47 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA05.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177uktY029214
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:56:46 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:56:40 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:24:56 +0530
Subject: [PATCH v10 16/28] media: iris: implement vb2 streaming ops
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-16-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914893; l=37142;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=4+o3D9I2T3EZa3AVjfU0zwXYytUlTs7cGjnF9s4KmKE=;
 b=9JGSo2iXRB35vYRe0NZwrq18KcgCTeE2IcL36VQ/rBbfXs0ynUdo/6ZyBETfnD7TxMoyOCDmA
 igwDn3kRtYeC8m4yJchWS9jGUetBcRZynYWCW5SY1CJ3jtSL2hamxcJ
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-ORIG-GUID: mTDDtwYmwYyiqYW6g3CsQaCdgVTXempK
X-Proofpoint-GUID: mTDDtwYmwYyiqYW6g3CsQaCdgVTXempK
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 mlxscore=0 impostorscore=0
 adultscore=0 bulkscore=0 phishscore=0 malwarescore=0 lowpriorityscore=0
 mlxlogscore=999 priorityscore=1501 clxscore=1015 suspectscore=0
 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070060

During the stream on operation, send HFI_CMD_START on the capture and
output planes to start processing on the respective planes.

During the stream off operation, send HFI_CMD_STOP to the firmware,
which is a synchronous command. After the response is received by the
firmware, the session is closed on the firmware.

Introduce different states for the instance and state transitions.

IRIS_INST_INIT - video instance is opened.
IRIS_INST_INPUT_STREAMING - stream on is completed on output plane.
IRIS_INST_OUTPUT_STREAMING - stream on is completed on capture plane.
IRIS_INST_STREAMING - stream on is completed on both output and capture
planes.
IRIS_INST_DEINIT - video instance is closed.
IRIS_INST_ERROR - error state.

                   |
                   v
            -------------
  +---------|   INIT    |---------  +
  |         -------------           |
  |            ^    ^               |
  |           /      \              |
  |          /        \             |
  |         v          v            |
  |    -----------    -----------   |
  |   |   INPUT         OUTPUT  |   |
  |---| STREAMING     STREAMING |---|
  |    -----------    -----------   |
  |        ^            ^           |
  |         \          /            |
  |          \        /             |
  |           v      v              |
  |         -------------           |
  |--------|  STREAMING |-----------|
  |         -------------           |
  |               |                 |
  |               |                 |
  |               v                 |
  |          -----------            |
  +-------->|  DEINIT   |<----------+
  |          -----------            |
  |               |                 |
  |               |                 |
  |               v                 |
  |          ----------             |
  +-------->|   ERROR  |<-----------+
             ----------.

Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl>
Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 drivers/media/platform/qcom/iris/Makefile          |   1 +
 drivers/media/platform/qcom/iris/iris_hfi_common.h |   2 +
 .../platform/qcom/iris/iris_hfi_gen1_command.c     |  82 +++++++++++++++-
 .../platform/qcom/iris/iris_hfi_gen1_defines.h     |  24 +++++
 .../platform/qcom/iris/iris_hfi_gen1_response.c    |  39 +++++++-
 .../platform/qcom/iris/iris_hfi_gen2_command.c     |  61 ++++++++++++
 .../platform/qcom/iris/iris_hfi_gen2_defines.h     |   2 +
 .../platform/qcom/iris/iris_hfi_gen2_response.c    |  32 ++++++-
 drivers/media/platform/qcom/iris/iris_instance.h   |   4 +
 drivers/media/platform/qcom/iris/iris_state.c      | 104 +++++++++++++++++=
++++
 drivers/media/platform/qcom/iris/iris_state.h      |  58 ++++++++++++
 drivers/media/platform/qcom/iris/iris_utils.c      |  11 ++-
 drivers/media/platform/qcom/iris/iris_utils.h      |   2 +-
 drivers/media/platform/qcom/iris/iris_vb2.c        |  70 ++++++++++++++
 drivers/media/platform/qcom/iris/iris_vb2.h        |   3 +
 drivers/media/platform/qcom/iris/iris_vdec.c       |  75 +++++++++++++++
 drivers/media/platform/qcom/iris/iris_vdec.h       |   3 +
 drivers/media/platform/qcom/iris/iris_vidc.c       |  12 ++-
 18 files changed, 573 insertions(+), 12 deletions(-)

diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/plat=
form/qcom/iris/Makefile
index f685d76c2f79..ab16189aa9e6 100644
--- a/drivers/media/platform/qcom/iris/Makefile
+++ b/drivers/media/platform/qcom/iris/Makefile
@@ -12,6 +12,7 @@ iris-objs +=3D iris_buffer.o \
              iris_platform_sm8550.o \
              iris_probe.o \
              iris_resources.o \
+             iris_state.o \
              iris_utils.o \
              iris_vidc.o \
              iris_vb2.o \
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/m=
edia/platform/qcom/iris/iris_hfi_common.h
index eaa2db469c74..8b1c4d156cf2 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_common.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h
@@ -49,6 +49,8 @@ struct iris_hfi_command_ops {
 	int (*sys_interframe_powercollapse)(struct iris_core *core);
 	int (*sys_pc_prep)(struct iris_core *core);
 	int (*session_open)(struct iris_inst *inst);
+	int (*session_start)(struct iris_inst *inst, u32 plane);
+	int (*session_stop)(struct iris_inst *inst, u32 plane);
 	int (*session_close)(struct iris_inst *inst);
 };
=20
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen1_command.c
index 7ee69c5223ce..a3b09e8d1f49 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
@@ -71,6 +71,9 @@ static int iris_hfi_gen1_session_open(struct iris_inst *i=
nst)
 	struct hfi_session_open_pkt packet;
 	int ret;
=20
+	if (inst->state !=3D IRIS_INST_DEINIT)
+		return -EALREADY;
+
 	packet.shdr.hdr.size =3D sizeof(struct hfi_session_open_pkt);
 	packet.shdr.hdr.pkt_type =3D HFI_CMD_SYS_SESSION_INIT;
 	packet.shdr.session_id =3D inst->session_id;
@@ -83,7 +86,7 @@ static int iris_hfi_gen1_session_open(struct iris_inst *i=
nst)
 	if (ret)
 		return ret;
=20
-	return iris_wait_for_session_response(inst);
+	return iris_wait_for_session_response(inst, false);
 }
=20
 static void iris_hfi_gen1_packet_session_cmd(struct iris_inst *inst,
@@ -104,12 +107,89 @@ static int iris_hfi_gen1_session_close(struct iris_in=
st *inst)
 	return iris_hfi_queue_cmd_write(inst->core, &packet, packet.shdr.hdr.size=
);
 }
=20
+static int iris_hfi_gen1_session_start(struct iris_inst *inst, u32 plane)
+{
+	struct iris_core *core =3D inst->core;
+	struct hfi_session_pkt packet;
+	int ret;
+
+	if (!V4L2_TYPE_IS_OUTPUT(plane))
+		return 0;
+
+	reinit_completion(&inst->completion);
+	iris_hfi_gen1_packet_session_cmd(inst, &packet, HFI_CMD_SESSION_LOAD_RESO=
URCES);
+
+	ret =3D iris_hfi_queue_cmd_write(core, &packet, packet.shdr.hdr.size);
+	if (ret)
+		return ret;
+
+	ret =3D iris_wait_for_session_response(inst, false);
+	if (ret)
+		return ret;
+
+	reinit_completion(&inst->completion);
+	iris_hfi_gen1_packet_session_cmd(inst, &packet, HFI_CMD_SESSION_START);
+
+	ret =3D iris_hfi_queue_cmd_write(core, &packet, packet.shdr.hdr.size);
+	if (ret)
+		return ret;
+
+	return iris_wait_for_session_response(inst, false);
+}
+
+static int iris_hfi_gen1_session_stop(struct iris_inst *inst, u32 plane)
+{
+	struct hfi_session_flush_pkt flush_pkt;
+	struct iris_core *core =3D inst->core;
+	struct hfi_session_pkt pkt;
+	u32 flush_type =3D 0;
+	int ret =3D 0;
+
+	if ((V4L2_TYPE_IS_OUTPUT(plane) &&
+	     inst->state =3D=3D IRIS_INST_INPUT_STREAMING) ||
+	    (V4L2_TYPE_IS_CAPTURE(plane) &&
+	     inst->state =3D=3D IRIS_INST_OUTPUT_STREAMING) ||
+	    inst->state =3D=3D IRIS_INST_ERROR) {
+		reinit_completion(&inst->completion);
+		iris_hfi_gen1_packet_session_cmd(inst, &pkt, HFI_CMD_SESSION_STOP);
+		ret =3D iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size);
+		if (!ret)
+			ret =3D iris_wait_for_session_response(inst, false);
+
+		reinit_completion(&inst->completion);
+		iris_hfi_gen1_packet_session_cmd(inst, &pkt, HFI_CMD_SESSION_RELEASE_RES=
OURCES);
+		ret =3D iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size);
+		if (!ret)
+			ret =3D iris_wait_for_session_response(inst, false);
+	} else if (inst->state =3D=3D IRIS_INST_STREAMING) {
+		if (V4L2_TYPE_IS_OUTPUT(plane))
+			flush_type =3D HFI_FLUSH_ALL;
+		else if (V4L2_TYPE_IS_CAPTURE(plane))
+			flush_type =3D HFI_FLUSH_OUTPUT;
+
+		reinit_completion(&inst->flush_completion);
+
+		flush_pkt.shdr.hdr.size =3D sizeof(struct hfi_session_flush_pkt);
+		flush_pkt.shdr.hdr.pkt_type =3D HFI_CMD_SESSION_FLUSH;
+		flush_pkt.shdr.session_id =3D inst->session_id;
+		flush_pkt.flush_type =3D flush_type;
+
+		ret =3D iris_hfi_queue_cmd_write(core, &flush_pkt, flush_pkt.shdr.hdr.si=
ze);
+		if (!ret)
+			ret =3D iris_wait_for_session_response(inst, true);
+	}
+
+	return ret;
+}
+
 static const struct iris_hfi_command_ops iris_hfi_gen1_command_ops =3D {
 	.sys_init =3D iris_hfi_gen1_sys_init,
 	.sys_image_version =3D iris_hfi_gen1_sys_image_version,
 	.sys_interframe_powercollapse =3D iris_hfi_gen1_sys_interframe_powercolla=
pse,
 	.sys_pc_prep =3D iris_hfi_gen1_sys_pc_prep,
 	.session_open =3D iris_hfi_gen1_session_open,
+	.session_start =3D iris_hfi_gen1_session_start,
+	.session_stop =3D iris_hfi_gen1_session_stop,
 	.session_close =3D iris_hfi_gen1_session_close,
 };
=20
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
index 3640f8504db9..1b2bf6afc6ce 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
@@ -23,6 +23,12 @@
 #define HFI_CMD_SYS_SESSION_INIT			0x10007
 #define HFI_CMD_SYS_SESSION_END				0x10008
=20
+#define HFI_CMD_SESSION_LOAD_RESOURCES			0x211001
+#define HFI_CMD_SESSION_START				0x211002
+#define HFI_CMD_SESSION_STOP				0x211003
+#define HFI_CMD_SESSION_FLUSH				0x211008
+#define HFI_CMD_SESSION_RELEASE_RESOURCES		0x21100c
+
 #define HFI_ERR_SESSION_UNSUPPORTED_SETTING		0x1008
 #define HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE		0x1010
 #define HFI_ERR_SESSION_INVALID_SCALE_FACTOR		0x1012
@@ -31,6 +37,9 @@
 #define HFI_EVENT_SYS_ERROR				0x1
 #define HFI_EVENT_SESSION_ERROR				0x2
=20
+#define HFI_FLUSH_OUTPUT				0x1000002
+#define HFI_FLUSH_OUTPUT2				0x1000003
+#define HFI_FLUSH_ALL					0x1000004
 #define HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL		0x5
 #define HFI_PROPERTY_SYS_IMAGE_VERSION			0x6
=20
@@ -41,6 +50,11 @@
 #define HFI_MSG_SYS_PROPERTY_INFO			0x2000a
=20
 #define HFI_MSG_EVENT_NOTIFY				0x21001
+#define HFI_MSG_SESSION_LOAD_RESOURCES			0x221001
+#define HFI_MSG_SESSION_START				0x221002
+#define HFI_MSG_SESSION_STOP				0x221003
+#define HFI_MSG_SESSION_FLUSH				0x221006
+#define HFI_MSG_SESSION_RELEASE_RESOURCES		0x22100a
=20
 struct hfi_pkt_hdr {
 	u32 size;
@@ -83,6 +97,11 @@ struct hfi_sys_pc_prep_pkt {
 	struct hfi_pkt_hdr hdr;
 };
=20
+struct hfi_session_flush_pkt {
+	struct hfi_session_hdr_pkt shdr;
+	u32 flush_type;
+};
+
 struct hfi_msg_event_notify_pkt {
 	struct hfi_session_hdr_pkt shdr;
 	u32 event_id;
@@ -116,6 +135,11 @@ struct hfi_msg_sys_property_info_pkt {
 	u8 data[];
 };
=20
+struct hfi_msg_session_flush_done_pkt {
+	struct hfi_msg_session_hdr_pkt shdr;
+	u32 flush_type;
+};
+
 struct hfi_enable {
 	u32 enable;
 };
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c b/dr=
ivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
index 18ba5f67dd36..db5858ec04ea 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
@@ -11,6 +11,7 @@ static void
 iris_hfi_gen1_sys_event_notify(struct iris_core *core, void *packet)
 {
 	struct hfi_msg_event_notify_pkt *pkt =3D packet;
+	struct iris_inst *instance;
=20
 	if (pkt->event_id =3D=3D HFI_EVENT_SYS_ERROR)
 		dev_err(core->dev, "sys error (type: %x, session id:%x, data1:%x, data2:=
%x)\n",
@@ -18,6 +19,12 @@ iris_hfi_gen1_sys_event_notify(struct iris_core *core, v=
oid *packet)
 			pkt->event_data2);
=20
 	core->state =3D IRIS_CORE_ERROR;
+
+	mutex_lock(&core->lock);
+	list_for_each_entry(instance, &core->instances, list)
+		iris_inst_change_state(instance, IRIS_INST_ERROR);
+	mutex_unlock(&core->lock);
+
 	schedule_delayed_work(&core->sys_error_handler, msecs_to_jiffies(10));
 }
=20
@@ -44,6 +51,7 @@ iris_hfi_gen1_event_session_error(struct iris_inst *inst,=
 struct hfi_msg_event_n
 			pkt->event_data2, pkt->event_data1,
 			pkt->shdr.session_id);
 		iris_vb2_queue_error(inst);
+		iris_inst_change_state(inst, IRIS_INST_ERROR);
 		break;
 	}
 }
@@ -148,6 +156,26 @@ static const struct iris_hfi_gen1_response_pkt_info pk=
t_infos[] =3D {
 	 .pkt =3D HFI_MSG_SYS_SESSION_END,
 	 .pkt_sz =3D sizeof(struct hfi_msg_session_hdr_pkt),
 	},
+	{
+	 .pkt =3D HFI_MSG_SESSION_LOAD_RESOURCES,
+	 .pkt_sz =3D sizeof(struct hfi_msg_session_hdr_pkt),
+	},
+	{
+	 .pkt =3D HFI_MSG_SESSION_START,
+	 .pkt_sz =3D sizeof(struct hfi_msg_session_hdr_pkt),
+	},
+	{
+	 .pkt =3D HFI_MSG_SESSION_STOP,
+	 .pkt_sz =3D sizeof(struct hfi_msg_session_hdr_pkt),
+	},
+	{
+	 .pkt =3D HFI_MSG_SESSION_FLUSH,
+	 .pkt_sz =3D sizeof(struct hfi_msg_session_flush_done_pkt),
+	},
+	{
+	 .pkt =3D HFI_MSG_SESSION_RELEASE_RESOURCES,
+	 .pkt_sz =3D sizeof(struct hfi_msg_session_hdr_pkt),
+	},
 };
=20
 static void iris_hfi_gen1_handle_response(struct iris_core *core, void *re=
sponse)
@@ -156,6 +184,7 @@ static void iris_hfi_gen1_handle_response(struct iris_c=
ore *core, void *response
 	const struct iris_hfi_gen1_response_pkt_info *pkt_info;
 	struct device *dev =3D core->dev;
 	struct hfi_session_pkt *pkt;
+	struct completion *done;
 	struct iris_inst *inst;
 	bool found =3D false;
 	u32 i;
@@ -205,7 +234,15 @@ static void iris_hfi_gen1_handle_response(struct iris_=
core *core, void *response
 		}
=20
 		mutex_lock(&inst->lock);
-		complete(&inst->completion);
+		struct hfi_msg_session_hdr_pkt *shdr;
+
+		shdr =3D (struct hfi_msg_session_hdr_pkt *)hdr;
+		if (shdr->error_type !=3D HFI_ERR_NONE)
+			iris_inst_change_state(inst, IRIS_INST_ERROR);
+
+		done =3D pkt_info->pkt =3D=3D HFI_MSG_SESSION_FLUSH ?
+			&inst->flush_completion : &inst->completion;
+		complete(done);
 		mutex_unlock(&inst->lock);
=20
 		break;
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen2_command.c
index a08e844bb4bb..b0557917fc52 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
@@ -85,6 +85,18 @@ static int iris_hfi_gen2_sys_pc_prep(struct iris_core *c=
ore)
 	return ret;
 }
=20
+static u32 iris_hfi_gen2_get_port(u32 plane)
+{
+	switch (plane) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		return HFI_PORT_BITSTREAM;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+		return HFI_PORT_RAW;
+	default:
+		return HFI_PORT_NONE;
+	}
+}
+
 static int iris_hfi_gen2_session_set_codec(struct iris_inst *inst)
 {
 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
@@ -124,6 +136,9 @@ static int iris_hfi_gen2_session_open(struct iris_inst =
*inst)
 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
 	int ret;
=20
+	if (inst->state !=3D IRIS_INST_DEINIT)
+		return -EALREADY;
+
 	inst_hfi_gen2->packet =3D kzalloc(4096, GFP_KERNEL);
 	if (!inst_hfi_gen2->packet)
 		return -ENOMEM;
@@ -188,12 +203,58 @@ static int iris_hfi_gen2_session_close(struct iris_in=
st *inst)
 	return ret;
 }
=20
+static int iris_hfi_gen2_session_start(struct iris_inst *inst, u32 plane)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+
+	iris_hfi_gen2_packet_session_command(inst,
+					     HFI_CMD_START,
+					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+					     HFI_HOST_FLAGS_INTR_REQUIRED),
+					     iris_hfi_gen2_get_port(plane),
+					     inst->session_id,
+					     HFI_PAYLOAD_NONE,
+					     NULL,
+					     0);
+
+	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
+					inst_hfi_gen2->packet->size);
+}
+
+static int iris_hfi_gen2_session_stop(struct iris_inst *inst, u32 plane)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	int ret =3D 0;
+
+	reinit_completion(&inst->completion);
+
+	iris_hfi_gen2_packet_session_command(inst,
+					     HFI_CMD_STOP,
+					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+					     HFI_HOST_FLAGS_INTR_REQUIRED |
+					     HFI_HOST_FLAGS_NON_DISCARDABLE),
+					     iris_hfi_gen2_get_port(plane),
+					     inst->session_id,
+					     HFI_PAYLOAD_NONE,
+					     NULL,
+					     0);
+
+	ret =3D iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
+				       inst_hfi_gen2->packet->size);
+	if (ret)
+		return ret;
+
+	return iris_wait_for_session_response(inst, false);
+}
+
 static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops =3D {
 	.sys_init =3D iris_hfi_gen2_sys_init,
 	.sys_image_version =3D iris_hfi_gen2_sys_image_version,
 	.sys_interframe_powercollapse =3D iris_hfi_gen2_sys_interframe_powercolla=
pse,
 	.sys_pc_prep =3D iris_hfi_gen2_sys_pc_prep,
 	.session_open =3D iris_hfi_gen2_session_open,
+	.session_start =3D iris_hfi_gen2_session_start,
+	.session_stop =3D iris_hfi_gen2_session_stop,
 	.session_close =3D iris_hfi_gen2_session_close,
 };
=20
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
index 173a554a0d44..930dbae49dfa 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
@@ -15,6 +15,8 @@
 #define HFI_CMD_POWER_COLLAPSE			0x01000002
 #define HFI_CMD_OPEN				0x01000003
 #define HFI_CMD_CLOSE				0x01000004
+#define HFI_CMD_START				0x01000005
+#define HFI_CMD_STOP				0x01000006
 #define HFI_CMD_END				0x01FFFFFF
=20
 #define HFI_PROP_BEGIN				0x03000000
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c b/dr=
ivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
index e1c43daea6c7..53b700ef852e 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
@@ -101,6 +101,7 @@ static int iris_hfi_gen2_handle_session_error(struct ir=
is_inst *inst,
=20
 	dev_err(core->dev, "session error received %#x: %s\n", pkt->type, error);
 	iris_vb2_queue_error(inst);
+	iris_inst_change_state(inst, IRIS_INST_ERROR);
=20
 	return 0;
 }
@@ -108,9 +109,17 @@ static int iris_hfi_gen2_handle_session_error(struct i=
ris_inst *inst,
 static int iris_hfi_gen2_handle_system_error(struct iris_core *core,
 					     struct iris_hfi_packet *pkt)
 {
+	struct iris_inst *instance;
+
 	dev_err(core->dev, "received system error of type %#x\n", pkt->type);
=20
 	core->state =3D IRIS_CORE_ERROR;
+
+	mutex_lock(&core->lock);
+	list_for_each_entry(instance, &core->instances, list)
+		iris_inst_change_state(instance, IRIS_INST_ERROR);
+	mutex_unlock(&core->lock);
+
 	schedule_delayed_work(&core->sys_error_handler, msecs_to_jiffies(10));
=20
 	return 0;
@@ -129,20 +138,32 @@ static int iris_hfi_gen2_handle_system_init(struct ir=
is_core *core,
 	return 0;
 }
=20
+static void iris_hfi_gen2_handle_session_close(struct iris_inst *inst,
+					       struct iris_hfi_packet *pkt)
+{
+	if (!(pkt->flags & HFI_FW_FLAGS_SUCCESS)) {
+		iris_inst_change_state(inst, IRIS_INST_ERROR);
+		return;
+	}
+
+	complete(&inst->completion);
+}
+
 static int iris_hfi_gen2_handle_session_command(struct iris_inst *inst,
 						struct iris_hfi_packet *pkt)
 {
-	int ret =3D 0;
-
 	switch (pkt->type) {
 	case HFI_CMD_CLOSE:
+		iris_hfi_gen2_handle_session_close(inst, pkt);
+		break;
+	case HFI_CMD_STOP:
 		complete(&inst->completion);
 		break;
 	default:
 		break;
 	}
=20
-	return ret;
+	return 0;
 }
=20
 static int iris_hfi_gen2_handle_image_version_property(struct iris_core *c=
ore,
@@ -247,8 +268,11 @@ static int iris_hfi_gen2_handle_session_response(struc=
t iris_core *core,
 			if (packet->flags & HFI_FW_FLAGS_SESSION_ERROR)
 				iris_hfi_gen2_handle_session_error(inst, packet);
=20
-			if (packet->type > range[i].begin && packet->type < range[i].end)
+			if (packet->type > range[i].begin && packet->type < range[i].end) {
 				ret =3D range[i].handle(inst, packet);
+				if (ret)
+					iris_inst_change_state(inst, IRIS_INST_ERROR);
+			}
 			pkt +=3D packet->size;
 		}
 	}
diff --git a/drivers/media/platform/qcom/iris/iris_instance.h b/drivers/med=
ia/platform/qcom/iris/iris_instance.h
index 9f1a1e5ba7c7..6b88daf31011 100644
--- a/drivers/media/platform/qcom/iris/iris_instance.h
+++ b/drivers/media/platform/qcom/iris/iris_instance.h
@@ -26,9 +26,11 @@
  * @ctrl_handler: reference of v4l2 ctrl handler
  * @crop: structure of crop info
  * @completion: structure of signal completions
+ * @flush_completion: structure of signal completions for flush cmd
  * @fw_caps: array of supported instance firmware capabilities
  * @buffers: array of different iris buffers
  * @fw_min_count: minimnum count of buffers needed by fw
+ * @state: instance state
  * @once_per_session_set: boolean to set once per session property
  * @m2m_dev:	a reference to m2m device structure
  * @m2m_ctx:	a reference to m2m context structure
@@ -46,9 +48,11 @@ struct iris_inst {
 	struct v4l2_ctrl_handler	ctrl_handler;
 	struct iris_hfi_rect_desc	crop;
 	struct completion		completion;
+	struct completion		flush_completion;
 	struct platform_inst_fw_cap	fw_caps[INST_FW_CAP_MAX];
 	struct iris_buffers		buffers[BUF_TYPE_MAX];
 	u32				fw_min_count;
+	enum iris_inst_state		state;
 	bool				once_per_session_set;
 	struct v4l2_m2m_dev		*m2m_dev;
 	struct v4l2_m2m_ctx		*m2m_ctx;
diff --git a/drivers/media/platform/qcom/iris/iris_state.c b/drivers/media/=
platform/qcom/iris/iris_state.c
new file mode 100644
index 000000000000..44362e8fe18f
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_state.c
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#include "iris_instance.h"
+
+static bool iris_allow_inst_state_change(struct iris_inst *inst,
+					 enum iris_inst_state req_state)
+{
+	switch (inst->state) {
+	case IRIS_INST_INIT:
+		if (req_state =3D=3D IRIS_INST_INPUT_STREAMING ||
+		    req_state =3D=3D IRIS_INST_OUTPUT_STREAMING ||
+		    req_state =3D=3D IRIS_INST_DEINIT)
+			return true;
+		return false;
+	case IRIS_INST_INPUT_STREAMING:
+		if (req_state =3D=3D IRIS_INST_INIT ||
+		    req_state =3D=3D IRIS_INST_STREAMING ||
+		    req_state =3D=3D IRIS_INST_DEINIT)
+			return true;
+		return false;
+	case IRIS_INST_OUTPUT_STREAMING:
+		if (req_state =3D=3D IRIS_INST_INIT ||
+		    req_state =3D=3D IRIS_INST_STREAMING ||
+		    req_state =3D=3D IRIS_INST_DEINIT)
+			return true;
+		return false;
+	case IRIS_INST_STREAMING:
+		if (req_state =3D=3D IRIS_INST_INPUT_STREAMING ||
+		    req_state =3D=3D IRIS_INST_OUTPUT_STREAMING ||
+		    req_state =3D=3D IRIS_INST_DEINIT)
+			return true;
+		return false;
+	case IRIS_INST_DEINIT:
+		if (req_state =3D=3D IRIS_INST_INIT)
+			return true;
+		return false;
+	default:
+		return false;
+	}
+}
+
+int iris_inst_change_state(struct iris_inst *inst,
+			   enum iris_inst_state request_state)
+{
+	if (inst->state =3D=3D IRIS_INST_ERROR)
+		return 0;
+
+	if (inst->state =3D=3D request_state)
+		return 0;
+
+	if (request_state =3D=3D IRIS_INST_ERROR)
+		goto change_state;
+
+	if (!iris_allow_inst_state_change(inst, request_state))
+		return -EINVAL;
+
+change_state:
+	inst->state =3D request_state;
+	dev_dbg(inst->core->dev, "state changed from %x to %x\n",
+		inst->state, request_state);
+
+	return 0;
+}
+
+int iris_inst_state_change_streamon(struct iris_inst *inst, u32 plane)
+{
+	enum iris_inst_state new_state =3D IRIS_INST_ERROR;
+
+	if (V4L2_TYPE_IS_OUTPUT(plane)) {
+		if (inst->state =3D=3D IRIS_INST_INIT)
+			new_state =3D IRIS_INST_INPUT_STREAMING;
+		else if (inst->state =3D=3D IRIS_INST_OUTPUT_STREAMING)
+			new_state =3D IRIS_INST_STREAMING;
+	} else if (V4L2_TYPE_IS_CAPTURE(plane)) {
+		if (inst->state =3D=3D IRIS_INST_INIT)
+			new_state =3D IRIS_INST_OUTPUT_STREAMING;
+		else if (inst->state =3D=3D IRIS_INST_INPUT_STREAMING)
+			new_state =3D IRIS_INST_STREAMING;
+	}
+
+	return iris_inst_change_state(inst, new_state);
+}
+
+int iris_inst_state_change_streamoff(struct iris_inst *inst, u32 plane)
+{
+	enum iris_inst_state new_state =3D IRIS_INST_ERROR;
+
+	if (V4L2_TYPE_IS_OUTPUT(plane)) {
+		if (inst->state =3D=3D IRIS_INST_INPUT_STREAMING)
+			new_state =3D IRIS_INST_INIT;
+		else if (inst->state =3D=3D IRIS_INST_STREAMING)
+			new_state =3D IRIS_INST_OUTPUT_STREAMING;
+	} else if (V4L2_TYPE_IS_CAPTURE(plane)) {
+		if (inst->state =3D=3D IRIS_INST_OUTPUT_STREAMING)
+			new_state =3D IRIS_INST_INIT;
+		else if (inst->state =3D=3D IRIS_INST_STREAMING)
+			new_state =3D IRIS_INST_INPUT_STREAMING;
+	}
+
+	return iris_inst_change_state(inst, new_state);
+}
diff --git a/drivers/media/platform/qcom/iris/iris_state.h b/drivers/media/=
platform/qcom/iris/iris_state.h
index 1ffe6fe706bd..0bf9d0e063ac 100644
--- a/drivers/media/platform/qcom/iris/iris_state.h
+++ b/drivers/media/platform/qcom/iris/iris_state.h
@@ -6,6 +6,8 @@
 #ifndef __IRIS_STATE_H__
 #define __IRIS_STATE_H__
=20
+struct iris_inst;
+
 /**
  * enum iris_core_state
  *
@@ -38,4 +40,60 @@ enum iris_core_state {
 	IRIS_CORE_ERROR,
 };
=20
+/**
+ * enum iris_inst_state
+ *
+ * @IRIS_INST_INIT: video instance is opened.
+ * @IRIS_INST_INPUT_STREAMING: stream on is completed on output plane.
+ * @IRIS_INST_OUTPUT_STREAMING: stream on is completed on capture plane.
+ * @IRIS_INST_STREAMING: stream on is completed on both output and capture=
 planes.
+ * @IRIS_INST_DEINIT: video instance is closed.
+ * @IRIS_INST_ERROR: error state.
+ *                    |
+ *                    V
+ *             -------------
+ *   +--------|     INIT    |----------+
+ *   |         -------------           |
+ *   |            ^   ^                |
+ *   |           /      \              |
+ *   |          /        \             |
+ *   |         v          v            |
+ *   |   -----------    -----------    |
+ *   |   |   INPUT         OUTPUT  |   |
+ *   |---| STREAMING     STREAMING |---|
+ *   |   -----------    -----------    |
+ *   |       ^            ^            |
+ *   |         \          /            |
+ *   |          \        /             |
+ *   |           v      v              |
+ *   |         -------------           |
+ *   |--------|  STREAMING |-----------|
+ *   |        -------------            |
+ *   |               |                 |
+ *   |               |                 |
+ *   |               v                 |
+ *   |          -----------            |
+ *   +-------->|  DEINIT   |<----------+
+ *   |          -----------            |
+ *   |               |                 |
+ *   |               |                 |
+ *   |               v                 |
+ *   |          ----------             |
+ *   +-------->|   ERROR |<------------+
+ *              ----------
+ */
+enum iris_inst_state {
+	IRIS_INST_DEINIT,
+	IRIS_INST_INIT,
+	IRIS_INST_INPUT_STREAMING,
+	IRIS_INST_OUTPUT_STREAMING,
+	IRIS_INST_STREAMING,
+	IRIS_INST_ERROR,
+};
+
+int iris_inst_change_state(struct iris_inst *inst,
+			   enum iris_inst_state request_state);
+int iris_inst_state_change_streamon(struct iris_inst *inst, u32 plane);
+int iris_inst_state_change_streamoff(struct iris_inst *inst, u32 plane);
+
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_utils.c b/drivers/media/=
platform/qcom/iris/iris_utils.c
index d5c8e052922c..4833830f30d5 100644
--- a/drivers/media/platform/qcom/iris/iris_utils.c
+++ b/drivers/media/platform/qcom/iris/iris_utils.c
@@ -17,20 +17,23 @@ int iris_get_mbpf(struct iris_inst *inst)
 	return NUM_MBS_PER_FRAME(height, width);
 }
=20
-int iris_wait_for_session_response(struct iris_inst *inst)
+int iris_wait_for_session_response(struct iris_inst *inst, bool is_flush)
 {
 	struct iris_core *core =3D inst->core;
 	u32 hw_response_timeout_val;
+	struct completion *done;
 	int ret;
=20
 	hw_response_timeout_val =3D core->iris_platform_data->hw_response_timeout;
+	done =3D is_flush ? &inst->flush_completion : &inst->completion;
=20
 	mutex_unlock(&inst->lock);
-	ret =3D wait_for_completion_timeout(&inst->completion,
-					  msecs_to_jiffies(hw_response_timeout_val));
+	ret =3D wait_for_completion_timeout(done, msecs_to_jiffies(hw_response_ti=
meout_val));
 	mutex_lock(&inst->lock);
-	if (!ret)
+	if (!ret) {
+		iris_inst_change_state(inst, IRIS_INST_ERROR);
 		return -ETIMEDOUT;
+	}
=20
 	return 0;
 }
diff --git a/drivers/media/platform/qcom/iris/iris_utils.h b/drivers/media/=
platform/qcom/iris/iris_utils.h
index 26649b66d978..40658a6643cf 100644
--- a/drivers/media/platform/qcom/iris/iris_utils.h
+++ b/drivers/media/platform/qcom/iris/iris_utils.h
@@ -29,6 +29,6 @@ static inline enum iris_buffer_type iris_v4l2_type_to_dri=
ver(u32 type)
=20
 int iris_get_mbpf(struct iris_inst *inst);
 struct iris_inst *iris_get_instance(struct iris_core *core, u32 session_id=
);
-int iris_wait_for_session_response(struct iris_inst *inst);
+int iris_wait_for_session_response(struct iris_inst *inst, bool is_flush);
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_vb2.c b/drivers/media/pl=
atform/qcom/iris/iris_vb2.c
index e9db44515d91..b93da860d336 100644
--- a/drivers/media/platform/qcom/iris/iris_vb2.c
+++ b/drivers/media/platform/qcom/iris/iris_vb2.c
@@ -5,6 +5,7 @@
=20
 #include "iris_instance.h"
 #include "iris_vb2.h"
+#include "iris_vdec.h"
=20
 int iris_vb2_queue_setup(struct vb2_queue *q,
 			 unsigned int *num_buffers, unsigned int *num_planes,
@@ -18,6 +19,10 @@ int iris_vb2_queue_setup(struct vb2_queue *q,
 	inst =3D vb2_get_drv_priv(q);
=20
 	mutex_lock(&inst->lock);
+	if (inst->state =3D=3D IRIS_INST_ERROR) {
+		ret =3D -EBUSY;
+		goto unlock;
+	}
=20
 	core =3D inst->core;
 	f =3D V4L2_TYPE_IS_OUTPUT(q->type) ? inst->fmt_src : inst->fmt_dst;
@@ -38,6 +43,10 @@ int iris_vb2_queue_setup(struct vb2_queue *q,
 			dev_err(core->dev, "session open failed\n");
 			goto unlock;
 		}
+
+		ret =3D iris_inst_change_state(inst, IRIS_INST_INIT);
+		if (ret)
+			goto unlock;
 	}
=20
 	*num_planes =3D 1;
@@ -48,3 +57,64 @@ int iris_vb2_queue_setup(struct vb2_queue *q,
=20
 	return ret;
 }
+
+int iris_vb2_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+	struct iris_inst *inst;
+	int ret =3D 0;
+
+	inst =3D vb2_get_drv_priv(q);
+
+	if (V4L2_TYPE_IS_CAPTURE(q->type) && inst->state =3D=3D IRIS_INST_INIT)
+		return 0;
+
+	mutex_lock(&inst->lock);
+	if (inst->state =3D=3D IRIS_INST_ERROR) {
+		ret =3D -EBUSY;
+		goto error;
+	}
+
+	if (!V4L2_TYPE_IS_OUTPUT(q->type) &&
+	    !V4L2_TYPE_IS_CAPTURE(q->type)) {
+		ret =3D -EINVAL;
+		goto error;
+	}
+
+	if (V4L2_TYPE_IS_OUTPUT(q->type))
+		ret =3D iris_vdec_streamon_input(inst);
+	else if (V4L2_TYPE_IS_CAPTURE(q->type))
+		ret =3D iris_vdec_streamon_output(inst);
+	if (ret)
+		goto error;
+
+	mutex_unlock(&inst->lock);
+
+	return ret;
+
+error:
+	iris_inst_change_state(inst, IRIS_INST_ERROR);
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+void iris_vb2_stop_streaming(struct vb2_queue *q)
+{
+	struct iris_inst *inst;
+
+	inst =3D vb2_get_drv_priv(q);
+
+	if (V4L2_TYPE_IS_CAPTURE(q->type) && inst->state =3D=3D IRIS_INST_INIT)
+		return;
+
+	mutex_lock(&inst->lock);
+
+	if (!V4L2_TYPE_IS_OUTPUT(q->type) &&
+	    !V4L2_TYPE_IS_CAPTURE(q->type))
+		goto exit;
+
+	iris_vdec_session_streamoff(inst, q->type);
+
+exit:
+	mutex_unlock(&inst->lock);
+}
diff --git a/drivers/media/platform/qcom/iris/iris_vb2.h b/drivers/media/pl=
atform/qcom/iris/iris_vb2.h
index d2e71d0596cc..3906510fa71f 100644
--- a/drivers/media/platform/qcom/iris/iris_vb2.h
+++ b/drivers/media/platform/qcom/iris/iris_vb2.h
@@ -9,4 +9,7 @@
 int iris_vb2_queue_setup(struct vb2_queue *q,
 			 unsigned int *num_buffers, unsigned int *num_planes,
 			 unsigned int sizes[], struct device *alloc_devs[]);
+int iris_vb2_start_streaming(struct vb2_queue *q, unsigned int count);
+void iris_vb2_stop_streaming(struct vb2_queue *q);
+
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/p=
latform/qcom/iris/iris_vdec.c
index 132b578b34dc..92651d86376d 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.c
+++ b/drivers/media/platform/qcom/iris/iris_vdec.c
@@ -222,3 +222,78 @@ int iris_vdec_subscribe_event(struct iris_inst *inst, =
const struct v4l2_event_su
=20
 	return ret;
 }
+
+static void iris_vdec_kill_session(struct iris_inst *inst)
+{
+	const struct iris_hfi_command_ops *hfi_ops =3D inst->core->hfi_ops;
+
+	if (!inst->session_id)
+		return;
+
+	hfi_ops->session_close(inst);
+	iris_inst_change_state(inst, IRIS_INST_ERROR);
+}
+
+void iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane)
+{
+	const struct iris_hfi_command_ops *hfi_ops =3D inst->core->hfi_ops;
+	int ret;
+
+	ret =3D hfi_ops->session_stop(inst, plane);
+	if (ret)
+		goto error;
+
+	ret =3D iris_inst_state_change_streamoff(inst, plane);
+	if (ret)
+		goto error;
+
+	return;
+
+error:
+	iris_vdec_kill_session(inst);
+}
+
+static int iris_vdec_process_streamon_input(struct iris_inst *inst)
+{
+	const struct iris_hfi_command_ops *hfi_ops =3D inst->core->hfi_ops;
+	int ret;
+
+	ret =3D hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+	if (ret)
+		return ret;
+
+	return iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_M=
PLANE);
+}
+
+int iris_vdec_streamon_input(struct iris_inst *inst)
+{
+	return iris_vdec_process_streamon_input(inst);
+}
+
+static int iris_vdec_process_streamon_output(struct iris_inst *inst)
+{
+	const struct iris_hfi_command_ops *hfi_ops =3D inst->core->hfi_ops;
+	int ret;
+
+	ret =3D hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+	if (ret)
+		return ret;
+
+	return iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_=
MPLANE);
+}
+
+int iris_vdec_streamon_output(struct iris_inst *inst)
+{
+	int ret;
+
+	ret =3D iris_vdec_process_streamon_output(inst);
+	if (ret)
+		goto error;
+
+	return ret;
+
+error:
+	iris_vdec_session_streamoff(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+
+	return ret;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.h b/drivers/media/p=
latform/qcom/iris/iris_vdec.h
index 9f08a13cb6bb..a17bb817b6e5 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.h
+++ b/drivers/media/platform/qcom/iris/iris_vdec.h
@@ -14,5 +14,8 @@ int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l=
2_fmtdesc *f);
 int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f);
 int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f);
 int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_ev=
ent_subscription *sub);
+int iris_vdec_streamon_input(struct iris_inst *inst);
+int iris_vdec_streamon_output(struct iris_inst *inst);
+void iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane);
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/p=
latform/qcom/iris/iris_vidc.c
index 5b54231f2def..1d10c430c795 100644
--- a/drivers/media/platform/qcom/iris/iris_vidc.c
+++ b/drivers/media/platform/qcom/iris/iris_vidc.c
@@ -145,10 +145,12 @@ int iris_open(struct file *filp)
=20
 	inst->core =3D core;
 	inst->session_id =3D hash32_ptr(inst);
+	inst->state =3D IRIS_INST_DEINIT;
=20
 	mutex_init(&inst->lock);
 	mutex_init(&inst->ctx_q_lock);
 	init_completion(&inst->completion);
+	init_completion(&inst->flush_completion);
=20
 	iris_v4l2_fh_init(inst);
=20
@@ -194,6 +196,9 @@ static void iris_session_close(struct iris_inst *inst)
 	bool wait_for_response =3D true;
 	int ret;
=20
+	if (inst->state =3D=3D IRIS_INST_DEINIT)
+		return;
+
 	reinit_completion(&inst->completion);
=20
 	ret =3D hfi_ops->session_close(inst);
@@ -201,7 +206,7 @@ static void iris_session_close(struct iris_inst *inst)
 		wait_for_response =3D false;
=20
 	if (wait_for_response)
-		iris_wait_for_session_response(inst);
+		iris_wait_for_session_response(inst, false);
 }
=20
 int iris_close(struct file *filp)
@@ -214,6 +219,7 @@ int iris_close(struct file *filp)
 	mutex_lock(&inst->lock);
 	iris_vdec_inst_deinit(inst);
 	iris_session_close(inst);
+	iris_inst_change_state(inst, IRIS_INST_DEINIT);
 	iris_v4l2_fh_deinit(inst);
 	iris_remove_session(inst);
 	mutex_unlock(&inst->lock);
@@ -356,6 +362,8 @@ static struct v4l2_file_operations iris_v4l2_file_ops =
=3D {
=20
 static const struct vb2_ops iris_vb2_ops =3D {
 	.queue_setup                    =3D iris_vb2_queue_setup,
+	.start_streaming                =3D iris_vb2_start_streaming,
+	.stop_streaming                 =3D iris_vb2_stop_streaming,
 };
=20
 static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops =3D {
@@ -373,6 +381,8 @@ static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops =
=3D {
 	.vidioc_g_selection             =3D iris_g_selection,
 	.vidioc_subscribe_event         =3D iris_subscribe_event,
 	.vidioc_unsubscribe_event       =3D v4l2_event_unsubscribe,
+	.vidioc_streamon                =3D v4l2_m2m_ioctl_streamon,
+	.vidioc_streamoff               =3D v4l2_m2m_ioctl_streamoff,
 };
=20
 void iris_init_ops(struct iris_core *core)

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 D43DC236A94;
	Fri,  7 Feb 2025 07:57:12 +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=1738915036; cv=none;
 b=e26wbxFEFL2aaUZcjq6xnjdImWH6Ie9uMFBJ0YpdIEAirhxbX6tWJ77p0F5Wadkgm79uAZ17NHIM/JWNgauTWa3qTaooN9gaNFWbYLJGkd8vrM/s6+6h5ri9lA2cU5Ws34k1CMufsEeUU0O8sijFKQiBSdhn7L7fC4IWjgXKMV0=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738915036; c=relaxed/simple;
	bh=5xFPTH+fVGw/gsmNtBILenfW3KExl6L9nEdEuMXAKeE=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=bi++eIQ2MP+NKOY0CbjWPVwtSQ7wn92pXKmGrFq7oYnePGveA7d4SggQOMHtrEkzfAf5w2NjZHVSPeDMih/XiyLyjoAfHcIEjEaMNv2DjS5pV6gdmjV4PcKG7tqGVVUyu4CgS17jCDkrw9gTFd6DF+8PE7h9/s7YRyEDJ4+QbTY=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=MUAisYs7; arc=none smtp.client-ip=205.220.168.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="MUAisYs7"
Received: from pps.filterd (m0279865.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 51770h5x010570;
	Fri, 7 Feb 2025 07:56:54 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	+fcxtoeKsphnGw7ve84swamO78rLGXJoeOaZGyLCbv4=; b=MUAisYs7clNWOCDd
	YnhBKom59L05gaFG7YsnjOodouBnof34TqgPiEhnLPYQeFXHODlPjJiawKi3Khj0
	RbykCVyhF9l0eyJADUAsKhIcBzIhTvGZh84BTawlDgkX+tByl0nKDUkZhBVIFgCD
	I2R5/COFkpQVakXzlD9zpn12erDXLrC5l8UuI/L2yJVOL074s3Pnf3ftLA6c50iI
	DlQ1WvT7ropOtpLA9dkNqSUqMJxWIGl04zqOTjrk8AUJtnuVPBqyGSzFoZHBd9O7
	S0CbbLbYVlqNNXxUcg2nGzPf+Eb2BkH9Iqv524pFw/Sh1ykVMD50QB1EqyqJ0SHN
	LQ2dZg==
Received: from nalasppmta02.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44nddkg4fq-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:56:54 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA02.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177urcM031596
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:56:53 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:56:46 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:24:57 +0530
Subject: [PATCH v10 17/28] media: iris: implement set properties to
 firmware during streamon
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-17-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>,
        Vedang Nagar <quic_vnagar@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914893; l=63943;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=t+ZHGMnYyJfDblPKA+nzTd1/Mhw7uDiILR+TFhSEarc=;
 b=ZwSZJPme+YjNk6OhG1JF+bEeCfLLKD+Gf+UDpvhvR4EPuky0fl+RO6oNvMZ0WIMag8pxSF5Ll
 LE6lnmpiux+CpTr0fVG4QhMFtaHhCayncsI0/Dgabtaz9pnOyRp6SNN
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-GUID: GgjBvLiv4JLsWFNs39bUbyKjFPJ-HT2O
X-Proofpoint-ORIG-GUID: GgjBvLiv4JLsWFNs39bUbyKjFPJ-HT2O
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 bulkscore=0
 lowpriorityscore=0 mlxlogscore=999 priorityscore=1501 impostorscore=0
 suspectscore=0 clxscore=1015 malwarescore=0 mlxscore=0 spamscore=0
 adultscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070060

From: Vedang Nagar <quic_vnagar@quicinc.com>

During the stream on operation, set some mandatory properties on the
firmware to start a session. Set all v4l2 properties, which are set by
the client, on to firmware, which is prepared with the dependency graph.

Signed-off-by: Vedang Nagar <quic_vnagar@quicinc.com>
Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 drivers/media/platform/qcom/iris/iris_buffer.c     | 121 ++++++
 drivers/media/platform/qcom/iris/iris_ctrls.c      |  94 +++++
 drivers/media/platform/qcom/iris/iris_ctrls.h      |   5 +
 drivers/media/platform/qcom/iris/iris_hfi_common.h |  76 ++++
 .../platform/qcom/iris/iris_hfi_gen1_command.c     | 411 +++++++++++++++++=
++++
 .../platform/qcom/iris/iris_hfi_gen1_defines.h     |  83 +++++
 drivers/media/platform/qcom/iris/iris_hfi_gen2.h   |   2 +
 .../platform/qcom/iris/iris_hfi_gen2_command.c     | 300 +++++++++++++++
 .../platform/qcom/iris/iris_hfi_gen2_defines.h     |  27 ++
 .../platform/qcom/iris/iris_hfi_gen2_packet.c      |  79 ++++
 .../platform/qcom/iris/iris_hfi_gen2_packet.h      |   7 +
 .../platform/qcom/iris/iris_hfi_gen2_response.c    |  49 +++
 .../platform/qcom/iris/iris_platform_common.h      |  32 ++
 .../platform/qcom/iris/iris_platform_sm8550.c      |  89 +++++
 drivers/media/platform/qcom/iris/iris_utils.c      |  19 +
 drivers/media/platform/qcom/iris/iris_utils.h      |   3 +
 drivers/media/platform/qcom/iris/iris_vdec.c       |  11 +
 drivers/media/platform/qcom/iris/iris_vpu_buffer.c |  20 +
 drivers/media/platform/qcom/iris/iris_vpu_buffer.h |   1 +
 19 files changed, 1429 insertions(+)

diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media=
/platform/qcom/iris/iris_buffer.c
index 037931ce6550..58d45d23393b 100644
--- a/drivers/media/platform/qcom/iris/iris_buffer.c
+++ b/drivers/media/platform/qcom/iris/iris_buffer.c
@@ -72,6 +72,125 @@ static u32 iris_yuv_buffer_size_nv12(struct iris_inst *=
inst)
 	return ALIGN(y_plane + uv_plane, PIXELS_4K);
 }
=20
+/*
+ * QC08C:
+ * Compressed Macro-tile format for NV12.
+ * Contains 4 planes in the following order -
+ * (A) Y_Meta_Plane
+ * (B) Y_UBWC_Plane
+ * (C) UV_Meta_Plane
+ * (D) UV_UBWC_Plane
+ *
+ * Y_Meta_Plane consists of meta information to decode compressed
+ * tile data in Y_UBWC_Plane.
+ * Y_UBWC_Plane consists of Y data in compressed macro-tile format.
+ * UBWC decoder block will use the Y_Meta_Plane data together with
+ * Y_UBWC_Plane data to produce loss-less uncompressed 8 bit Y samples.
+ *
+ * UV_Meta_Plane consists of meta information to decode compressed
+ * tile data in UV_UBWC_Plane.
+ * UV_UBWC_Plane consists of UV data in compressed macro-tile format.
+ * UBWC decoder block will use UV_Meta_Plane data together with
+ * UV_UBWC_Plane data to produce loss-less uncompressed 8 bit 2x2
+ * subsampled color difference samples.
+ *
+ * Each tile in Y_UBWC_Plane/UV_UBWC_Plane is independently decodable
+ * and randomly accessible. There is no dependency between tiles.
+ *
+ * <----- y_meta_stride ----> (aligned to 64)
+ * <-------- Width ------>
+ * M M M M M M M M M M M M . .      ^           ^
+ * M M M M M M M M M M M M . .      |           |
+ * M M M M M M M M M M M M . .      Height      |
+ * M M M M M M M M M M M M . .      |         y_meta_scanlines  (aligned t=
o 16)
+ * M M M M M M M M M M M M . .      |           |
+ * M M M M M M M M M M M M . .      |           |
+ * M M M M M M M M M M M M . .      |           |
+ * M M M M M M M M M M M M . .      V           |
+ * . . . . . . . . . . . . . .                  |
+ * . . . . . . . . . . . . . .                  |
+ * . . . . . . . . . . . . . .      -------> Buffer size aligned to 4k
+ * . . . . . . . . . . . . . .                  V
+ * <--Compressed tile y_stride---> (aligned to 128)
+ * <------- Width ------->
+ * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  ^           ^
+ * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
+ * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  Height      |
+ * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |        Macro_tile y_scanlines (align=
ed to 32)
+ * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
+ * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
+ * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
+ * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  V           |
+ * . . . . . . . . . . . . . . . .              |
+ * . . . . . . . . . . . . . . . .              |
+ * . . . . . . . . . . . . . . . .  -------> Buffer size aligned to 4k
+ * . . . . . . . . . . . . . . . .              V
+ * <----- uv_meta_stride ---->  (aligned to 64)
+ * M M M M M M M M M M M M . .      ^
+ * M M M M M M M M M M M M . .      |
+ * M M M M M M M M M M M M . .      |
+ * M M M M M M M M M M M M . .      uv_meta_scanlines (aligned to 16)
+ * . . . . . . . . . . . . . .      |
+ * . . . . . . . . . . . . . .      V
+ * . . . . . . . . . . . . . .      -------> Buffer size aligned to 4k
+ * <--Compressed tile uv_stride---> (aligned to 128)
+ * U* V* U* V* U* V* U* V* . . . .  ^
+ * U* V* U* V* U* V* U* V* . . . .  |
+ * U* V* U* V* U* V* U* V* . . . .  |
+ * U* V* U* V* U* V* U* V* . . . .  uv_scanlines (aligned to 32)
+ * . . . . . . . . . . . . . . . .  |
+ * . . . . . . . . . . . . . . . .  V
+ * . . . . . . . . . . . . . . . .  -------> Buffer size aligned to 4k
+ *
+ * y_stride: width aligned to 128
+ * uv_stride: width aligned to 128
+ * y_scanlines: height aligned to 32
+ * uv_scanlines: height aligned to 32
+ * y_plane: buffer size aligned to 4096
+ * uv_plane: buffer size aligned to 4096
+ * y_meta_stride: width aligned to 64
+ * y_meta_scanlines: height aligned to 16
+ * y_meta_plane: buffer size aligned to 4096
+ * uv_meta_stride: width aligned to 64
+ * uv_meta_scanlines: height aligned to 16
+ * uv_meta_plane: buffer size aligned to 4096
+ *
+ * Total size =3D align( y_plane + uv_plane +
+ *           y_meta_plane + uv_meta_plane, 4096)
+ *
+ * Note: All the alignments are hardware requirements.
+ */
+static u32 iris_yuv_buffer_size_qc08c(struct iris_inst *inst)
+{
+	u32 y_plane, uv_plane, y_stride, uv_stride;
+	struct v4l2_format *f =3D inst->fmt_dst;
+	u32 uv_meta_stride, uv_meta_plane;
+	u32 y_meta_stride, y_meta_plane;
+
+	y_meta_stride =3D ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.width, META_STRIDE_ALI=
GNED >> 1),
+			      META_STRIDE_ALIGNED);
+	y_meta_plane =3D y_meta_stride * ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.height,
+							  META_SCANLINE_ALIGNED >> 1),
+					     META_SCANLINE_ALIGNED);
+	y_meta_plane =3D ALIGN(y_meta_plane, PIXELS_4K);
+
+	y_stride =3D ALIGN(f->fmt.pix_mp.width, Y_STRIDE_ALIGN);
+	y_plane =3D ALIGN(y_stride * ALIGN(f->fmt.pix_mp.height, Y_SCANLINE_ALIGN=
), PIXELS_4K);
+
+	uv_meta_stride =3D ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.width / 2, META_STRID=
E_ALIGNED >> 2),
+			       META_STRIDE_ALIGNED);
+	uv_meta_plane =3D uv_meta_stride * ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.heigh=
t / 2,
+							    META_SCANLINE_ALIGNED >> 1),
+					       META_SCANLINE_ALIGNED);
+	uv_meta_plane =3D ALIGN(uv_meta_plane, PIXELS_4K);
+
+	uv_stride =3D ALIGN(f->fmt.pix_mp.width, UV_STRIDE_ALIGN);
+	uv_plane =3D ALIGN(uv_stride * ALIGN(f->fmt.pix_mp.height / 2, UV_SCANLIN=
E_ALIGN_QC08C),
+			 PIXELS_4K);
+
+	return ALIGN(y_meta_plane + y_plane + uv_meta_plane + uv_plane, PIXELS_4K=
);
+}
+
 static u32 iris_bitstream_buffer_size(struct iris_inst *inst)
 {
 	struct platform_inst_caps *caps =3D inst->core->iris_platform_data->inst_=
caps;
@@ -102,6 +221,8 @@ int iris_get_buffer_size(struct iris_inst *inst,
 		return iris_bitstream_buffer_size(inst);
 	case BUF_OUTPUT:
 		return iris_yuv_buffer_size_nv12(inst);
+	case BUF_DPB:
+		return iris_yuv_buffer_size_qc08c(inst);
 	default:
 		return 0;
 	}
diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/=
platform/qcom/iris/iris_ctrls.c
index 3652fa535bf3..b690578256d5 100644
--- a/drivers/media/platform/qcom/iris/iris_ctrls.c
+++ b/drivers/media/platform/qcom/iris/iris_ctrls.c
@@ -3,7 +3,9 @@
  * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
  */
=20
+#include <linux/types.h>
 #include <media/v4l2-mem2mem.h>
+
 #include "iris_ctrls.h"
 #include "iris_instance.h"
=20
@@ -163,3 +165,95 @@ void iris_session_init_caps(struct iris_core *core)
 		core->inst_fw_caps[cap_id].hfi_id =3D caps[i].hfi_id;
 	}
 }
+
+static u32 iris_get_port_info(struct iris_inst *inst,
+			      enum platform_inst_fw_cap_type cap_id)
+{
+	if (inst->fw_caps[cap_id].flags & CAP_FLAG_INPUT_PORT)
+		return HFI_PORT_BITSTREAM;
+	else if (inst->fw_caps[cap_id].flags & CAP_FLAG_OUTPUT_PORT)
+		return HFI_PORT_RAW;
+
+	return HFI_PORT_NONE;
+}
+
+int iris_set_u32_enum(struct iris_inst *inst, enum platform_inst_fw_cap_ty=
pe cap_id)
+{
+	const struct iris_hfi_command_ops *hfi_ops =3D inst->core->hfi_ops;
+	u32 hfi_value =3D inst->fw_caps[cap_id].value;
+	u32 hfi_id =3D inst->fw_caps[cap_id].hfi_id;
+
+	return hfi_ops->session_set_property(inst, hfi_id,
+					     HFI_HOST_FLAGS_NONE,
+					     iris_get_port_info(inst, cap_id),
+					     HFI_PAYLOAD_U32_ENUM,
+					     &hfi_value, sizeof(u32));
+}
+
+int iris_set_u32(struct iris_inst *inst, enum platform_inst_fw_cap_type ca=
p_id)
+{
+	const struct iris_hfi_command_ops *hfi_ops =3D inst->core->hfi_ops;
+	u32 hfi_value =3D inst->fw_caps[cap_id].value;
+	u32 hfi_id =3D inst->fw_caps[cap_id].hfi_id;
+
+	return hfi_ops->session_set_property(inst, hfi_id,
+					     HFI_HOST_FLAGS_NONE,
+					     iris_get_port_info(inst, cap_id),
+					     HFI_PAYLOAD_U32,
+					     &hfi_value, sizeof(u32));
+}
+
+int iris_set_stage(struct iris_inst *inst, enum platform_inst_fw_cap_type =
cap_id)
+{
+	const struct iris_hfi_command_ops *hfi_ops =3D inst->core->hfi_ops;
+	struct v4l2_format *inp_f =3D inst->fmt_src;
+	u32 hfi_id =3D inst->fw_caps[cap_id].hfi_id;
+	u32 height =3D inp_f->fmt.pix_mp.height;
+	u32 width =3D inp_f->fmt.pix_mp.width;
+	u32 work_mode =3D STAGE_2;
+
+	if (iris_res_is_less_than(width, height, 1280, 720))
+		work_mode =3D STAGE_1;
+
+	return hfi_ops->session_set_property(inst, hfi_id,
+					     HFI_HOST_FLAGS_NONE,
+					     iris_get_port_info(inst, cap_id),
+					     HFI_PAYLOAD_U32,
+					     &work_mode, sizeof(u32));
+}
+
+int iris_set_pipe(struct iris_inst *inst, enum platform_inst_fw_cap_type c=
ap_id)
+{
+	const struct iris_hfi_command_ops *hfi_ops =3D inst->core->hfi_ops;
+	u32 work_route =3D inst->fw_caps[PIPE].value;
+	u32 hfi_id =3D inst->fw_caps[cap_id].hfi_id;
+
+	return hfi_ops->session_set_property(inst, hfi_id,
+					     HFI_HOST_FLAGS_NONE,
+					     iris_get_port_info(inst, cap_id),
+					     HFI_PAYLOAD_U32,
+					     &work_route, sizeof(u32));
+}
+
+int iris_set_properties(struct iris_inst *inst, u32 plane)
+{
+	const struct iris_hfi_command_ops *hfi_ops =3D inst->core->hfi_ops;
+	struct platform_inst_fw_cap *cap;
+	int ret;
+	u32 i;
+
+	ret =3D hfi_ops->session_set_config_params(inst, plane);
+	if (ret)
+		return ret;
+
+	for (i =3D 1; i < INST_FW_CAP_MAX; i++) {
+		cap =3D &inst->fw_caps[i];
+		if (!iris_valid_cap_id(cap->cap_id))
+			continue;
+
+		if (cap->cap_id && cap->set)
+			cap->set(inst, i);
+	}
+
+	return 0;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.h b/drivers/media/=
platform/qcom/iris/iris_ctrls.h
index fe65a772e6dd..9b5741868933 100644
--- a/drivers/media/platform/qcom/iris/iris_ctrls.h
+++ b/drivers/media/platform/qcom/iris/iris_ctrls.h
@@ -13,5 +13,10 @@ struct iris_inst;
=20
 int iris_ctrls_init(struct iris_inst *inst);
 void iris_session_init_caps(struct iris_core *core);
+int iris_set_u32_enum(struct iris_inst *inst, enum platform_inst_fw_cap_ty=
pe cap_id);
+int iris_set_stage(struct iris_inst *inst, enum platform_inst_fw_cap_type =
cap_id);
+int iris_set_pipe(struct iris_inst *inst, enum platform_inst_fw_cap_type c=
ap_id);
+int iris_set_u32(struct iris_inst *inst, enum platform_inst_fw_cap_type ca=
p_id);
+int iris_set_properties(struct iris_inst *inst, u32 plane);
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/m=
edia/platform/qcom/iris/iris_hfi_common.h
index 8b1c4d156cf2..1fba5a9292af 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_common.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h
@@ -43,11 +43,75 @@ enum hfi_packet_host_flags {
 	HFI_HOST_FLAGS_GET_PROPERTY		=3D 0x00000008,
 };
=20
+enum hfi_color_primaries {
+	HFI_PRIMARIES_RESERVED		=3D 0,
+	HFI_PRIMARIES_BT709		=3D 1,
+	HFI_PRIMARIES_UNSPECIFIED	=3D 2,
+	HFI_PRIMARIES_BT470_SYSTEM_M	=3D 4,
+	HFI_PRIMARIES_BT470_SYSTEM_BG	=3D 5,
+	HFI_PRIMARIES_BT601_525		=3D 6,
+	HFI_PRIMARIES_SMPTE_ST240M	=3D 7,
+	HFI_PRIMARIES_GENERIC_FILM	=3D 8,
+	HFI_PRIMARIES_BT2020		=3D 9,
+	HFI_PRIMARIES_SMPTE_ST428_1	=3D 10,
+	HFI_PRIMARIES_SMPTE_RP431_2	=3D 11,
+	HFI_PRIMARIES_SMPTE_EG431_1	=3D 12,
+	HFI_PRIMARIES_SMPTE_EBU_TECH	=3D 22,
+};
+
+enum hfi_transfer_characteristics {
+	HFI_TRANSFER_RESERVED		=3D 0,
+	HFI_TRANSFER_BT709		=3D 1,
+	HFI_TRANSFER_UNSPECIFIED	=3D 2,
+	HFI_TRANSFER_BT470_SYSTEM_M	=3D 4,
+	HFI_TRANSFER_BT470_SYSTEM_BG	=3D 5,
+	HFI_TRANSFER_BT601_525_OR_625	=3D 6,
+	HFI_TRANSFER_SMPTE_ST240M	=3D 7,
+	HFI_TRANSFER_LINEAR		=3D 8,
+	HFI_TRANSFER_LOG_100_1		=3D 9,
+	HFI_TRANSFER_LOG_SQRT		=3D 10,
+	HFI_TRANSFER_XVYCC		=3D 11,
+	HFI_TRANSFER_BT1361_0		=3D 12,
+	HFI_TRANSFER_SRGB_SYCC		=3D 13,
+	HFI_TRANSFER_BT2020_14		=3D 14,
+	HFI_TRANSFER_BT2020_15		=3D 15,
+	HFI_TRANSFER_SMPTE_ST2084_PQ	=3D 16,
+	HFI_TRANSFER_SMPTE_ST428_1	=3D 17,
+	HFI_TRANSFER_BT2100_2_HLG	=3D 18,
+};
+
+enum hfi_matrix_coefficients {
+	HFI_MATRIX_COEFF_SRGB_SMPTE_ST428_1		=3D 0,
+	HFI_MATRIX_COEFF_BT709				=3D 1,
+	HFI_MATRIX_COEFF_UNSPECIFIED			=3D 2,
+	HFI_MATRIX_COEFF_RESERVED			=3D 3,
+	HFI_MATRIX_COEFF_FCC_TITLE_47			=3D 4,
+	HFI_MATRIX_COEFF_BT470_SYS_BG_OR_BT601_625	=3D 5,
+	HFI_MATRIX_COEFF_BT601_525_BT1358_525_OR_625	=3D 6,
+	HFI_MATRIX_COEFF_SMPTE_ST240			=3D 7,
+	HFI_MATRIX_COEFF_YCGCO				=3D 8,
+	HFI_MATRIX_COEFF_BT2020_NON_CONSTANT		=3D 9,
+	HFI_MATRIX_COEFF_BT2020_CONSTANT		=3D 10,
+	HFI_MATRIX_COEFF_SMPTE_ST2085			=3D 11,
+	HFI_MATRIX_COEFF_SMPTE_CHROM_DERV_NON_CONSTANT	=3D 12,
+	HFI_MATRIX_COEFF_SMPTE_CHROM_DERV_CONSTANT	=3D 13,
+	HFI_MATRIX_COEFF_BT2100				=3D 14,
+};
+
+struct iris_hfi_prop_type_handle {
+	u32 type;
+	int (*handle)(struct iris_inst *inst);
+};
+
 struct iris_hfi_command_ops {
 	int (*sys_init)(struct iris_core *core);
 	int (*sys_image_version)(struct iris_core *core);
 	int (*sys_interframe_powercollapse)(struct iris_core *core);
 	int (*sys_pc_prep)(struct iris_core *core);
+	int (*session_set_config_params)(struct iris_inst *inst, u32 plane);
+	int (*session_set_property)(struct iris_inst *inst,
+				    u32 packet_type, u32 flag, u32 plane, u32 payload_type,
+				    void *payload, u32 payload_size);
 	int (*session_open)(struct iris_inst *inst);
 	int (*session_start)(struct iris_inst *inst, u32 plane);
 	int (*session_stop)(struct iris_inst *inst, u32 plane);
@@ -58,6 +122,18 @@ struct iris_hfi_response_ops {
 	void (*hfi_response_handler)(struct iris_core *core);
 };
=20
+struct hfi_subscription_params {
+	u32	bitstream_resolution;
+	u32	crop_offsets[2];
+	u32	bit_depth;
+	u32	coded_frames;
+	u32	fw_min_count;
+	u32	pic_order_cnt;
+	u32	color_info;
+	u32	profile;
+	u32	level;
+};
+
 int iris_hfi_core_init(struct iris_core *core);
 int iris_hfi_pm_suspend(struct iris_core *core);
 int iris_hfi_pm_resume(struct iris_core *core);
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen1_command.c
index a3b09e8d1f49..26fe65ddba8a 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
@@ -6,6 +6,7 @@
 #include "iris_hfi_gen1.h"
 #include "iris_hfi_gen1_defines.h"
 #include "iris_instance.h"
+#include "iris_vpu_buffer.h"
=20
 static int iris_hfi_gen1_sys_init(struct iris_core *core)
 {
@@ -182,12 +183,422 @@ static int iris_hfi_gen1_session_stop(struct iris_in=
st *inst, u32 plane)
 	return ret;
 }
=20
+static int
+iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_=
pkt *packet,
+					  struct iris_inst *inst, u32 ptype, void *pdata)
+{
+	void *prop_data =3D &packet->data[1];
+
+	packet->shdr.hdr.size =3D sizeof(*packet);
+	packet->shdr.hdr.pkt_type =3D HFI_CMD_SESSION_SET_PROPERTY;
+	packet->shdr.session_id =3D inst->session_id;
+	packet->num_properties =3D 1;
+	packet->data[0] =3D ptype;
+
+	switch (ptype) {
+	case HFI_PROPERTY_PARAM_FRAME_SIZE: {
+		struct hfi_framesize *in =3D pdata, *fsize =3D prop_data;
+
+		fsize->buffer_type =3D in->buffer_type;
+		fsize->height =3D in->height;
+		fsize->width =3D in->width;
+		packet->shdr.hdr.size +=3D sizeof(u32) + sizeof(*fsize);
+		break;
+	}
+	case HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE: {
+		struct hfi_videocores_usage_type *in =3D pdata, *cu =3D prop_data;
+
+		cu->video_core_enable_mask =3D in->video_core_enable_mask;
+		packet->shdr.hdr.size +=3D sizeof(u32) + sizeof(*cu);
+		break;
+	}
+	case HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT: {
+		struct hfi_uncompressed_format_select *in =3D pdata;
+		struct hfi_uncompressed_format_select *hfi =3D prop_data;
+
+		hfi->buffer_type =3D in->buffer_type;
+		hfi->format =3D in->format;
+		packet->shdr.hdr.size +=3D sizeof(u32) + sizeof(*hfi);
+		break;
+	}
+	case HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO: {
+		struct hfi_uncompressed_plane_actual_constraints_info *info =3D prop_dat=
a;
+
+		info->buffer_type =3D HFI_BUFFER_OUTPUT2;
+		info->num_planes =3D 2;
+		info->plane_format[0].stride_multiples =3D 128;
+		info->plane_format[0].max_stride =3D 8192;
+		info->plane_format[0].min_plane_buffer_height_multiple =3D 32;
+		info->plane_format[0].buffer_alignment =3D 256;
+		if (info->num_planes > 1) {
+			info->plane_format[1].stride_multiples =3D 128;
+			info->plane_format[1].max_stride =3D 8192;
+			info->plane_format[1].min_plane_buffer_height_multiple =3D 16;
+			info->plane_format[1].buffer_alignment =3D 256;
+		}
+
+		packet->shdr.hdr.size +=3D sizeof(u32) + sizeof(*info);
+		break;
+	}
+	case HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL: {
+		struct hfi_buffer_count_actual *in =3D pdata;
+		struct hfi_buffer_count_actual *count =3D prop_data;
+
+		count->type =3D in->type;
+		count->count_actual =3D in->count_actual;
+		count->count_min_host =3D in->count_min_host;
+		packet->shdr.hdr.size +=3D sizeof(u32) + sizeof(*count);
+		break;
+	}
+	case HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM: {
+		struct hfi_multi_stream *in =3D pdata;
+		struct hfi_multi_stream *multi =3D prop_data;
+
+		multi->buffer_type =3D in->buffer_type;
+		multi->enable =3D in->enable;
+		packet->shdr.hdr.size +=3D sizeof(u32) + sizeof(*multi);
+		break;
+	}
+	case HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL: {
+		struct hfi_buffer_size_actual *in =3D pdata, *sz =3D prop_data;
+
+		sz->size =3D in->size;
+		sz->type =3D in->type;
+		packet->shdr.hdr.size +=3D sizeof(u32) + sizeof(*sz);
+		break;
+	}
+	case HFI_PROPERTY_PARAM_WORK_ROUTE: {
+		struct hfi_video_work_route *wr =3D prop_data;
+		u32 *in =3D pdata;
+
+		wr->video_work_route =3D *in;
+		packet->shdr.hdr.size +=3D sizeof(u32) + sizeof(*wr);
+		break;
+	}
+	case HFI_PROPERTY_PARAM_WORK_MODE: {
+		struct hfi_video_work_mode *wm =3D prop_data;
+		u32 *in =3D pdata;
+
+		wm->video_work_mode =3D *in;
+		packet->shdr.hdr.size +=3D sizeof(u32) + sizeof(*wm);
+		break;
+	}
+	case HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER: {
+		struct hfi_enable *en =3D prop_data;
+		u32 *in =3D pdata;
+
+		en->enable =3D *in;
+		packet->shdr.hdr.size +=3D sizeof(u32) + sizeof(*en);
+		break;
+	}
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int hfi_gen1_set_property(struct iris_inst *inst, u32 packet_type,
+				 void *payload, u32 payload_size)
+{
+	struct hfi_session_set_property_pkt *pkt;
+	u32 packet_size;
+	int ret;
+
+	packet_size =3D sizeof(*pkt) + sizeof(u32) + payload_size;
+	pkt =3D kzalloc(packet_size, GFP_KERNEL);
+	if (!pkt)
+		return -ENOMEM;
+
+	ret =3D iris_hfi_gen1_packet_session_set_property(pkt, inst, packet_type,=
 payload);
+	if (ret =3D=3D -EOPNOTSUPP) {
+		ret =3D 0;
+		goto exit;
+	}
+	if (ret)
+		goto exit;
+
+	ret =3D iris_hfi_queue_cmd_write(inst->core, pkt, pkt->shdr.hdr.size);
+
+exit:
+	kfree(pkt);
+
+	return ret;
+}
+
+static int iris_hfi_gen1_session_set_property(struct iris_inst *inst, u32 =
packet_type,
+					      u32 flag, u32 plane, u32 payload_type,
+					      void *payload, u32 payload_size)
+{
+	return hfi_gen1_set_property(inst, packet_type, payload, payload_size);
+}
+
+static int iris_hfi_gen1_set_resolution(struct iris_inst *inst)
+{
+	u32 ptype =3D HFI_PROPERTY_PARAM_FRAME_SIZE;
+	struct hfi_framesize fs;
+	int ret;
+
+	fs.buffer_type =3D HFI_BUFFER_INPUT;
+	fs.width =3D inst->fmt_src->fmt.pix_mp.width;
+	fs.height =3D inst->fmt_src->fmt.pix_mp.height;
+
+	ret =3D hfi_gen1_set_property(inst, ptype, &fs, sizeof(fs));
+	if (ret)
+		return ret;
+
+	fs.buffer_type =3D HFI_BUFFER_OUTPUT2;
+	fs.width =3D inst->fmt_dst->fmt.pix_mp.width;
+	fs.height =3D inst->fmt_dst->fmt.pix_mp.height;
+
+	return hfi_gen1_set_property(inst, ptype, &fs, sizeof(fs));
+}
+
+static int iris_hfi_gen1_decide_core(struct iris_inst *inst)
+{
+	const u32 ptype =3D HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE;
+	struct hfi_videocores_usage_type cu;
+
+	cu.video_core_enable_mask =3D HFI_CORE_ID_1;
+
+	return hfi_gen1_set_property(inst, ptype, &cu, sizeof(cu));
+}
+
+static int iris_hfi_gen1_set_raw_format(struct iris_inst *inst)
+{
+	const u32 ptype =3D HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT;
+	u32 pixelformat =3D inst->fmt_dst->fmt.pix_mp.pixelformat;
+	struct hfi_uncompressed_format_select fmt;
+	int ret;
+
+	if (iris_split_mode_enabled(inst)) {
+		fmt.buffer_type =3D HFI_BUFFER_OUTPUT;
+		fmt.format =3D pixelformat =3D=3D V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_N=
V12_UBWC : 0;
+
+		ret =3D hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt));
+		if (ret)
+			return ret;
+
+		fmt.buffer_type =3D HFI_BUFFER_OUTPUT2;
+		fmt.format =3D pixelformat =3D=3D V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_N=
V12 : 0;
+
+		ret =3D hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt));
+	} else {
+		fmt.buffer_type =3D HFI_BUFFER_OUTPUT;
+		fmt.format =3D pixelformat =3D=3D V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_N=
V12 : 0;
+
+		ret =3D hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt));
+	}
+
+	return ret;
+}
+
+static int iris_hfi_gen1_set_format_constraints(struct iris_inst *inst)
+{
+	const u32 ptype =3D HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAI=
NTS_INFO;
+	struct hfi_uncompressed_plane_actual_constraints_info pconstraint;
+
+	pconstraint.buffer_type =3D HFI_BUFFER_OUTPUT2;
+	pconstraint.num_planes =3D 2;
+	pconstraint.plane_format[0].stride_multiples =3D 128;
+	pconstraint.plane_format[0].max_stride =3D 8192;
+	pconstraint.plane_format[0].min_plane_buffer_height_multiple =3D 32;
+	pconstraint.plane_format[0].buffer_alignment =3D 256;
+
+	pconstraint.plane_format[1].stride_multiples =3D 128;
+	pconstraint.plane_format[1].max_stride =3D 8192;
+	pconstraint.plane_format[1].min_plane_buffer_height_multiple =3D 16;
+	pconstraint.plane_format[1].buffer_alignment =3D 256;
+
+	return hfi_gen1_set_property(inst, ptype, &pconstraint, sizeof(pconstrain=
t));
+}
+
+static int iris_hfi_gen1_set_num_bufs(struct iris_inst *inst)
+{
+	u32 ptype =3D HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL;
+	struct hfi_buffer_count_actual buf_count;
+	int ret;
+
+	buf_count.type =3D HFI_BUFFER_INPUT;
+	buf_count.count_actual =3D VIDEO_MAX_FRAME;
+	buf_count.count_min_host =3D VIDEO_MAX_FRAME;
+
+	ret =3D hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count));
+	if (ret)
+		return ret;
+
+	if (iris_split_mode_enabled(inst)) {
+		buf_count.type =3D HFI_BUFFER_OUTPUT;
+		buf_count.count_actual =3D VIDEO_MAX_FRAME;
+		buf_count.count_min_host =3D VIDEO_MAX_FRAME;
+
+		ret =3D hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count)=
);
+		if (ret)
+			return ret;
+
+		buf_count.type =3D HFI_BUFFER_OUTPUT2;
+		buf_count.count_actual =3D iris_vpu_buf_count(inst, BUF_DPB);
+		buf_count.count_min_host =3D iris_vpu_buf_count(inst, BUF_DPB);
+
+		ret =3D hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count)=
);
+	} else {
+		buf_count.type =3D HFI_BUFFER_OUTPUT;
+		buf_count.count_actual =3D VIDEO_MAX_FRAME;
+		buf_count.count_min_host =3D VIDEO_MAX_FRAME;
+
+		ret =3D hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count)=
);
+	}
+
+	return ret;
+}
+
+static int iris_hfi_gen1_set_multistream(struct iris_inst *inst)
+{
+	u32 ptype =3D HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM;
+	struct hfi_multi_stream multi =3D {0};
+	int ret;
+
+	if (iris_split_mode_enabled(inst)) {
+		multi.buffer_type =3D HFI_BUFFER_OUTPUT;
+		multi.enable =3D 0;
+
+		ret =3D hfi_gen1_set_property(inst, ptype, &multi, sizeof(multi));
+		if (ret)
+			return ret;
+
+		multi.buffer_type =3D HFI_BUFFER_OUTPUT2;
+		multi.enable =3D 1;
+
+		ret =3D hfi_gen1_set_property(inst, ptype, &multi, sizeof(multi));
+	} else {
+		multi.buffer_type =3D HFI_BUFFER_OUTPUT;
+		multi.enable =3D 1;
+
+		ret =3D hfi_gen1_set_property(inst, ptype, &multi, sizeof(multi));
+		if (ret)
+			return ret;
+
+		multi.buffer_type =3D HFI_BUFFER_OUTPUT2;
+		multi.enable =3D 0;
+
+		ret =3D hfi_gen1_set_property(inst, ptype, &multi, sizeof(multi));
+	}
+
+	return ret;
+}
+
+static int iris_hfi_gen1_set_bufsize(struct iris_inst *inst)
+{
+	const u32 ptype =3D HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL;
+	struct hfi_buffer_size_actual bufsz;
+	int ret;
+
+	if (iris_split_mode_enabled(inst)) {
+		bufsz.type =3D HFI_BUFFER_OUTPUT;
+		bufsz.size =3D iris_vpu_dec_dpb_size(inst);
+
+		ret =3D hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz));
+		if (ret)
+			return ret;
+
+		bufsz.type =3D HFI_BUFFER_OUTPUT2;
+		bufsz.size =3D inst->buffers[BUF_OUTPUT].size;
+
+		ret =3D hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz));
+	} else {
+		bufsz.type =3D HFI_BUFFER_OUTPUT;
+		bufsz.size =3D inst->buffers[BUF_OUTPUT].size;
+
+		ret =3D hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz));
+		if (ret)
+			return ret;
+
+		bufsz.type =3D HFI_BUFFER_OUTPUT2;
+		bufsz.size =3D 0;
+
+		ret =3D hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz));
+	}
+
+	return ret;
+}
+
+static int iris_hfi_gen1_session_set_config_params(struct iris_inst *inst,=
 u32 plane)
+{
+	struct iris_core *core =3D inst->core;
+	u32 config_params_size, i, j;
+	const u32 *config_params;
+	int ret;
+
+	static const struct iris_hfi_prop_type_handle prop_type_handle_inp_arr[] =
=3D {
+		{HFI_PROPERTY_PARAM_FRAME_SIZE,
+			iris_hfi_gen1_set_resolution},
+		{HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE,
+			iris_hfi_gen1_decide_core},
+		{HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT,
+			iris_hfi_gen1_set_raw_format},
+		{HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO,
+			iris_hfi_gen1_set_format_constraints},
+		{HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL,
+			iris_hfi_gen1_set_num_bufs},
+		{HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM,
+			iris_hfi_gen1_set_multistream},
+		{HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL,
+			iris_hfi_gen1_set_bufsize},
+	};
+
+	static const struct iris_hfi_prop_type_handle prop_type_handle_out_arr[] =
=3D {
+		{HFI_PROPERTY_PARAM_FRAME_SIZE,
+			iris_hfi_gen1_set_resolution},
+		{HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT,
+			iris_hfi_gen1_set_raw_format},
+		{HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO,
+			iris_hfi_gen1_set_format_constraints},
+		{HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL,
+			iris_hfi_gen1_set_num_bufs},
+		{HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM,
+			iris_hfi_gen1_set_multistream},
+		{HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL,
+			iris_hfi_gen1_set_bufsize},
+	};
+
+	config_params =3D core->iris_platform_data->input_config_params;
+	config_params_size =3D core->iris_platform_data->input_config_params_size;
+
+	if (V4L2_TYPE_IS_OUTPUT(plane)) {
+		for (i =3D 0; i < config_params_size; i++) {
+			for (j =3D 0; j < ARRAY_SIZE(prop_type_handle_inp_arr); j++) {
+				if (prop_type_handle_inp_arr[j].type =3D=3D config_params[i]) {
+					ret =3D prop_type_handle_inp_arr[j].handle(inst);
+					if (ret)
+						return ret;
+					break;
+				}
+			}
+		}
+	} else if (V4L2_TYPE_IS_CAPTURE(plane)) {
+		for (i =3D 0; i < config_params_size; i++) {
+			for (j =3D 0; j < ARRAY_SIZE(prop_type_handle_out_arr); j++) {
+				if (prop_type_handle_out_arr[j].type =3D=3D config_params[i]) {
+					ret =3D prop_type_handle_out_arr[j].handle(inst);
+					if (ret)
+						return ret;
+					break;
+				}
+			}
+		}
+	}
+
+	return 0;
+}
+
 static const struct iris_hfi_command_ops iris_hfi_gen1_command_ops =3D {
 	.sys_init =3D iris_hfi_gen1_sys_init,
 	.sys_image_version =3D iris_hfi_gen1_sys_image_version,
 	.sys_interframe_powercollapse =3D iris_hfi_gen1_sys_interframe_powercolla=
pse,
 	.sys_pc_prep =3D iris_hfi_gen1_sys_pc_prep,
 	.session_open =3D iris_hfi_gen1_session_open,
+	.session_set_config_params =3D iris_hfi_gen1_session_set_config_params,
+	.session_set_property =3D iris_hfi_gen1_session_set_property,
 	.session_start =3D iris_hfi_gen1_session_start,
 	.session_stop =3D iris_hfi_gen1_session_stop,
 	.session_close =3D iris_hfi_gen1_session_close,
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
index 1b2bf6afc6ce..67e7575351d4 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
@@ -23,6 +23,8 @@
 #define HFI_CMD_SYS_SESSION_INIT			0x10007
 #define HFI_CMD_SYS_SESSION_END				0x10008
=20
+#define HFI_CMD_SESSION_SET_PROPERTY			0x11001
+
 #define HFI_CMD_SESSION_LOAD_RESOURCES			0x211001
 #define HFI_CMD_SESSION_START				0x211002
 #define HFI_CMD_SESSION_STOP				0x211003
@@ -40,9 +42,32 @@
 #define HFI_FLUSH_OUTPUT				0x1000002
 #define HFI_FLUSH_OUTPUT2				0x1000003
 #define HFI_FLUSH_ALL					0x1000004
+
+#define HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL				0x201001
+#define HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO	0x20=
1002
+#define HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE				0x201008
+#define HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL				0x20100c
+
+#define HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER	0x1200001
+
+#define HFI_BUFFER_INPUT				0x1
+#define HFI_BUFFER_OUTPUT				0x2
+#define HFI_BUFFER_OUTPUT2				0x3
+
 #define HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL		0x5
 #define HFI_PROPERTY_SYS_IMAGE_VERSION			0x6
=20
+#define HFI_PROPERTY_PARAM_FRAME_SIZE			0x1001
+#define HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT	0x1003
+#define HFI_PROPERTY_PARAM_WORK_MODE			0x1015
+#define HFI_PROPERTY_PARAM_WORK_ROUTE			0x1017
+#define HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE		0x2002
+
+#define HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM		0x1003001
+#define HFI_CORE_ID_1					1
+#define HFI_COLOR_FORMAT_NV12				0x02
+#define HFI_COLOR_FORMAT_NV12_UBWC			0x8002
+
 #define HFI_MSG_SYS_INIT				0x20001
 #define HFI_MSG_SYS_SESSION_INIT			0x20006
 #define HFI_MSG_SYS_SESSION_END				0x20007
@@ -93,6 +118,12 @@ struct hfi_sys_get_property_pkt {
 	u32 data;
 };
=20
+struct hfi_session_set_property_pkt {
+	struct hfi_session_hdr_pkt shdr;
+	u32 num_properties;
+	u32 data[];
+};
+
 struct hfi_sys_pc_prep_pkt {
 	struct hfi_pkt_hdr hdr;
 };
@@ -144,6 +175,58 @@ struct hfi_enable {
 	u32 enable;
 };
=20
+struct hfi_framesize {
+	u32 buffer_type;
+	u32 width;
+	u32 height;
+};
+
+struct hfi_videocores_usage_type {
+	u32 video_core_enable_mask;
+};
+
+struct hfi_video_work_mode {
+	u32 video_work_mode;
+};
+
+struct hfi_video_work_route {
+	u32 video_work_route;
+};
+
+struct hfi_uncompressed_format_select {
+	u32 buffer_type;
+	u32 format;
+};
+
+struct hfi_uncompressed_plane_constraints {
+	u32 stride_multiples;
+	u32 max_stride;
+	u32 min_plane_buffer_height_multiple;
+	u32 buffer_alignment;
+};
+
+struct hfi_uncompressed_plane_actual_constraints_info {
+	u32 buffer_type;
+	u32 num_planes;
+	struct hfi_uncompressed_plane_constraints plane_format[2];
+};
+
+struct hfi_buffer_count_actual {
+	u32 type;
+	u32 count_actual;
+	u32 count_min_host;
+};
+
+struct hfi_buffer_size_actual {
+	u32 type;
+	u32 size;
+};
+
+struct hfi_multi_stream {
+	u32 buffer_type;
+	u32 enable;
+};
+
 struct hfi_msg_sys_debug_pkt {
 	struct hfi_pkt_hdr hdr;
 	u32 msg_type;
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h b/drivers/med=
ia/platform/qcom/iris/iris_hfi_gen2.h
index aaf6660bc1fe..676bcb3dc81f 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h
@@ -18,10 +18,12 @@ struct iris_core;
  *
  * @inst: pointer to iris_instance structure
  * @packet: HFI packet
+ * @src_subcr_params: subscription params to fw on input port
  */
 struct iris_inst_hfi_gen2 {
 	struct iris_inst		inst;
 	struct iris_hfi_header		*packet;
+	struct hfi_subscription_params	src_subcr_params;
 };
=20
 void iris_hfi_gen2_command_ops_init(struct iris_core *core);
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen2_command.c
index b0557917fc52..0845b75aafe9 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
@@ -3,9 +3,12 @@
  * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
  */
=20
+#include <linux/bitfield.h>
+
 #include "iris_hfi_gen2.h"
 #include "iris_hfi_gen2_packet.h"
=20
+#define UNSPECIFIED_COLOR_FORMAT 5
 #define NUM_SYS_INIT_PACKETS 8
=20
 #define SYS_INIT_PKT_SIZE (sizeof(struct iris_hfi_header) + \
@@ -97,6 +100,301 @@ static u32 iris_hfi_gen2_get_port(u32 plane)
 	}
 }
=20
+static int iris_hfi_gen2_session_set_property(struct iris_inst *inst, u32 =
packet_type, u32 flag,
+					      u32 plane, u32 payload_type, void *payload,
+					      u32 payload_size)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+
+	iris_hfi_gen2_packet_session_property(inst,
+					      packet_type,
+					      flag,
+					      plane,
+					      payload_type,
+					      payload,
+					      payload_size);
+
+	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
+					inst_hfi_gen2->packet->size);
+}
+
+static int iris_hfi_gen2_set_bitstream_resolution(struct iris_inst *inst)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	u32 port =3D iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+	u32 resolution =3D inst->fmt_src->fmt.pix_mp.width << 16 |
+		inst->fmt_src->fmt.pix_mp.height;
+
+	inst_hfi_gen2->src_subcr_params.bitstream_resolution =3D resolution;
+
+	return iris_hfi_gen2_session_set_property(inst,
+						  HFI_PROP_BITSTREAM_RESOLUTION,
+						  HFI_HOST_FLAGS_NONE,
+						  port,
+						  HFI_PAYLOAD_U32,
+						  &resolution,
+						  sizeof(u32));
+}
+
+static int iris_hfi_gen2_set_crop_offsets(struct iris_inst *inst)
+{
+	u32 bottom_offset =3D (inst->fmt_src->fmt.pix_mp.height - inst->crop.heig=
ht);
+	u32 right_offset =3D (inst->fmt_src->fmt.pix_mp.width - inst->crop.width);
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	u32 port =3D iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+	u32 left_offset =3D inst->crop.left;
+	u32 top_offset =3D inst->crop.top;
+	u32 payload[2];
+
+	payload[0] =3D FIELD_PREP(GENMASK(31, 16), left_offset) | top_offset;
+	payload[1] =3D FIELD_PREP(GENMASK(31, 16), right_offset) | bottom_offset;
+	inst_hfi_gen2->src_subcr_params.crop_offsets[0] =3D payload[0];
+	inst_hfi_gen2->src_subcr_params.crop_offsets[1] =3D payload[1];
+
+	return iris_hfi_gen2_session_set_property(inst,
+						  HFI_PROP_CROP_OFFSETS,
+						  HFI_HOST_FLAGS_NONE,
+						  port,
+						  HFI_PAYLOAD_64_PACKED,
+						  &payload,
+						  sizeof(u64));
+}
+
+static int iris_hfi_gen2_set_bit_dpeth(struct iris_inst *inst)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	u32 port =3D iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+	u32 bitdepth =3D BIT_DEPTH_8;
+
+	inst_hfi_gen2->src_subcr_params.bit_depth =3D bitdepth;
+
+	return iris_hfi_gen2_session_set_property(inst,
+						  HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
+						  HFI_HOST_FLAGS_NONE,
+						  port,
+						  HFI_PAYLOAD_U32,
+						  &bitdepth,
+						  sizeof(u32));
+}
+
+static int iris_hfi_gen2_set_coded_frames(struct iris_inst *inst)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	u32 port =3D iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+	u32 coded_frames =3D 0;
+
+	if (inst->fw_caps[CODED_FRAMES].value =3D=3D CODED_FRAMES_PROGRESSIVE)
+		coded_frames =3D HFI_BITMASK_FRAME_MBS_ONLY_FLAG;
+	inst_hfi_gen2->src_subcr_params.coded_frames =3D coded_frames;
+
+	return iris_hfi_gen2_session_set_property(inst,
+						  HFI_PROP_CODED_FRAMES,
+						  HFI_HOST_FLAGS_NONE,
+						  port,
+						  HFI_PAYLOAD_U32,
+						  &coded_frames,
+						  sizeof(u32));
+}
+
+static int iris_hfi_gen2_set_min_output_count(struct iris_inst *inst)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	u32 port =3D iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+	u32 min_output =3D inst->buffers[BUF_OUTPUT].min_count;
+
+	inst_hfi_gen2->src_subcr_params.fw_min_count =3D min_output;
+
+	return iris_hfi_gen2_session_set_property(inst,
+						  HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
+						  HFI_HOST_FLAGS_NONE,
+						  port,
+						  HFI_PAYLOAD_U32,
+						  &min_output,
+						  sizeof(u32));
+}
+
+static int iris_hfi_gen2_set_picture_order_count(struct iris_inst *inst)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	u32 port =3D iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+	u32 poc =3D 0;
+
+	inst_hfi_gen2->src_subcr_params.pic_order_cnt =3D poc;
+
+	return iris_hfi_gen2_session_set_property(inst,
+						  HFI_PROP_PIC_ORDER_CNT_TYPE,
+						  HFI_HOST_FLAGS_NONE,
+						  port,
+						  HFI_PAYLOAD_U32,
+						  &poc,
+						  sizeof(u32));
+}
+
+static int iris_hfi_gen2_set_colorspace(struct iris_inst *inst)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	u32 port =3D iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+	struct v4l2_pix_format_mplane *pixmp =3D &inst->fmt_src->fmt.pix_mp;
+	u32 video_signal_type_present_flag =3D 0, color_info;
+	u32 matrix_coeff =3D HFI_MATRIX_COEFF_RESERVED;
+	u32 video_format =3D UNSPECIFIED_COLOR_FORMAT;
+	u32 full_range =3D V4L2_QUANTIZATION_DEFAULT;
+	u32 transfer_char =3D HFI_TRANSFER_RESERVED;
+	u32 colour_description_present_flag =3D 0;
+	u32 primaries =3D HFI_PRIMARIES_RESERVED;
+
+	if (pixmp->colorspace !=3D V4L2_COLORSPACE_DEFAULT ||
+	    pixmp->ycbcr_enc !=3D V4L2_YCBCR_ENC_DEFAULT ||
+	    pixmp->xfer_func !=3D V4L2_XFER_FUNC_DEFAULT) {
+		colour_description_present_flag =3D 1;
+		video_signal_type_present_flag =3D 1;
+		primaries =3D iris_hfi_gen2_get_color_primaries(pixmp->colorspace);
+		matrix_coeff =3D iris_hfi_gen2_get_matrix_coefficients(pixmp->ycbcr_enc);
+		transfer_char =3D iris_hfi_gen2_get_transfer_char(pixmp->xfer_func);
+	}
+
+	if (pixmp->quantization !=3D V4L2_QUANTIZATION_DEFAULT) {
+		video_signal_type_present_flag =3D 1;
+		full_range =3D pixmp->quantization =3D=3D V4L2_QUANTIZATION_FULL_RANGE ?=
 1 : 0;
+	}
+
+	color_info =3D iris_hfi_gen2_get_color_info(matrix_coeff, transfer_char, =
primaries,
+						  colour_description_present_flag, full_range,
+						  video_format, video_signal_type_present_flag);
+
+	inst_hfi_gen2->src_subcr_params.color_info =3D color_info;
+
+	return iris_hfi_gen2_session_set_property(inst,
+						  HFI_PROP_SIGNAL_COLOR_INFO,
+						  HFI_HOST_FLAGS_NONE,
+						  port,
+						  HFI_PAYLOAD_32_PACKED,
+						  &color_info,
+						  sizeof(u32));
+}
+
+static int iris_hfi_gen2_set_profile(struct iris_inst *inst)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	u32 port =3D iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+	u32 profile =3D inst->fw_caps[PROFILE].value;
+
+	inst_hfi_gen2->src_subcr_params.profile =3D profile;
+
+	return iris_hfi_gen2_session_set_property(inst,
+						  HFI_PROP_PROFILE,
+						  HFI_HOST_FLAGS_NONE,
+						  port,
+						  HFI_PAYLOAD_U32_ENUM,
+						  &profile,
+						  sizeof(u32));
+}
+
+static int iris_hfi_gen2_set_level(struct iris_inst *inst)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	u32 port =3D iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+	u32 level =3D inst->fw_caps[LEVEL].value;
+
+	inst_hfi_gen2->src_subcr_params.level =3D level;
+
+	return iris_hfi_gen2_session_set_property(inst,
+						  HFI_PROP_LEVEL,
+						  HFI_HOST_FLAGS_NONE,
+						  port,
+						  HFI_PAYLOAD_U32_ENUM,
+						  &level,
+						  sizeof(u32));
+}
+
+static int iris_hfi_gen2_set_colorformat(struct iris_inst *inst)
+{
+	u32 port =3D iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+	u32 hfi_colorformat, pixelformat;
+
+	pixelformat =3D inst->fmt_dst->fmt.pix_mp.pixelformat;
+	hfi_colorformat =3D pixelformat =3D=3D V4L2_PIX_FMT_NV12 ? HFI_COLOR_FMT_=
NV12 : 0;
+
+	return iris_hfi_gen2_session_set_property(inst,
+						  HFI_PROP_COLOR_FORMAT,
+						  HFI_HOST_FLAGS_NONE,
+						  port,
+						  HFI_PAYLOAD_U32,
+						  &hfi_colorformat,
+						  sizeof(u32));
+}
+
+static int iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst *inst)
+{
+	u32 port =3D iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+	u32 pixelformat =3D inst->fmt_dst->fmt.pix_mp.pixelformat;
+	u32 scanline_y =3D inst->fmt_dst->fmt.pix_mp.height;
+	u32 stride_y =3D inst->fmt_dst->fmt.pix_mp.width;
+	u32 scanline_uv =3D scanline_y / 2;
+	u32 stride_uv =3D stride_y;
+	u32 payload[2];
+
+	if (pixelformat !=3D V4L2_PIX_FMT_NV12)
+		return 0;
+
+	payload[0] =3D stride_y << 16 | scanline_y;
+	payload[1] =3D stride_uv << 16 | scanline_uv;
+
+	return iris_hfi_gen2_session_set_property(inst,
+						  HFI_PROP_LINEAR_STRIDE_SCANLINE,
+						  HFI_HOST_FLAGS_NONE,
+						  port,
+						  HFI_PAYLOAD_U64,
+						  &payload,
+						  sizeof(u64));
+}
+
+static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst,=
 u32 plane)
+{
+	struct iris_core *core =3D inst->core;
+	u32 config_params_size, i, j;
+	const u32 *config_params;
+	int ret;
+
+	static const struct iris_hfi_prop_type_handle prop_type_handle_arr[] =3D {
+		{HFI_PROP_BITSTREAM_RESOLUTION,       iris_hfi_gen2_set_bitstream_resolu=
tion   },
+		{HFI_PROP_CROP_OFFSETS,               iris_hfi_gen2_set_crop_offsets    =
       },
+		{HFI_PROP_CODED_FRAMES,               iris_hfi_gen2_set_coded_frames    =
       },
+		{HFI_PROP_LUMA_CHROMA_BIT_DEPTH,      iris_hfi_gen2_set_bit_dpeth       =
       },
+		{HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, iris_hfi_gen2_set_min_output_count=
       },
+		{HFI_PROP_PIC_ORDER_CNT_TYPE,         iris_hfi_gen2_set_picture_order_co=
unt    },
+		{HFI_PROP_SIGNAL_COLOR_INFO,          iris_hfi_gen2_set_colorspace      =
       },
+		{HFI_PROP_PROFILE,                    iris_hfi_gen2_set_profile         =
       },
+		{HFI_PROP_LEVEL,                      iris_hfi_gen2_set_level           =
       },
+		{HFI_PROP_COLOR_FORMAT,               iris_hfi_gen2_set_colorformat     =
       },
+		{HFI_PROP_LINEAR_STRIDE_SCANLINE,     iris_hfi_gen2_set_linear_stride_sc=
anline },
+	};
+
+	if (V4L2_TYPE_IS_OUTPUT(plane)) {
+		config_params =3D core->iris_platform_data->input_config_params;
+		config_params_size =3D core->iris_platform_data->input_config_params_siz=
e;
+	} else {
+		config_params =3D core->iris_platform_data->output_config_params;
+		config_params_size =3D core->iris_platform_data->output_config_params_si=
ze;
+	}
+
+	if (!config_params || !config_params_size)
+		return -EINVAL;
+
+	for (i =3D 0; i < config_params_size; i++) {
+		for (j =3D 0; j < ARRAY_SIZE(prop_type_handle_arr); j++) {
+			if (prop_type_handle_arr[j].type =3D=3D config_params[i]) {
+				ret =3D prop_type_handle_arr[j].handle(inst);
+				if (ret)
+					return ret;
+				break;
+			}
+		}
+	}
+
+	return 0;
+}
+
 static int iris_hfi_gen2_session_set_codec(struct iris_inst *inst)
 {
 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
@@ -253,6 +551,8 @@ static const struct iris_hfi_command_ops iris_hfi_gen2_=
command_ops =3D {
 	.sys_interframe_powercollapse =3D iris_hfi_gen2_sys_interframe_powercolla=
pse,
 	.sys_pc_prep =3D iris_hfi_gen2_sys_pc_prep,
 	.session_open =3D iris_hfi_gen2_session_open,
+	.session_set_config_params =3D iris_hfi_gen2_session_set_config_params,
+	.session_set_property =3D iris_hfi_gen2_session_set_property,
 	.session_start =3D iris_hfi_gen2_session_start,
 	.session_stop =3D iris_hfi_gen2_session_stop,
 	.session_close =3D iris_hfi_gen2_session_close,
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
index 930dbae49dfa..4c9604b05034 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
@@ -19,6 +19,8 @@
 #define HFI_CMD_STOP				0x01000006
 #define HFI_CMD_END				0x01FFFFFF
=20
+#define HFI_BITMASK_FRAME_MBS_ONLY_FLAG		0x00000001
+
 #define HFI_PROP_BEGIN				0x03000000
 #define HFI_PROP_IMAGE_VERSION			0x03000001
 #define HFI_PROP_INTRA_FRAME_POWER_COLLAPSE	0x03000002
@@ -30,9 +32,23 @@
 #define HFI_PROP_UBWC_BANK_SWZL_LEVEL3		0x03000008
 #define HFI_PROP_UBWC_BANK_SPREADING		0x03000009
 #define HFI_PROP_CODEC				0x03000100
+#define HFI_PROP_COLOR_FORMAT			0x03000101
+#define HFI_PROP_BITSTREAM_RESOLUTION		0x03000103
+#define HFI_PROP_LINEAR_STRIDE_SCANLINE		0x03000104
+#define HFI_PROP_CROP_OFFSETS			0x03000105
 #define HFI_PROP_PROFILE			0x03000107
 #define HFI_PROP_LEVEL				0x03000108
+#define HFI_PROP_STAGE				0x0300010a
+#define HFI_PROP_PIPE				0x0300010b
+#define HFI_PROP_LUMA_CHROMA_BIT_DEPTH		0x0300010f
+#define HFI_PROP_CODED_FRAMES			0x03000120
+#define HFI_PROP_BUFFER_HOST_MAX_COUNT		0x03000123
+#define HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT	0x03000124
+#define HFI_PROP_PIC_ORDER_CNT_TYPE		0x03000128
+#define HFI_PROP_QUALITY_MODE			0x03000148
+#define HFI_PROP_SIGNAL_COLOR_INFO		0x03000155
 #define HFI_PROP_DEC_DEFAULT_HEADER		0x03000168
+#define HFI_PROP_DEC_START_FROM_RAP_FRAME	0x03000169
 #define HFI_PROP_END				0x03FFFFFF
=20
 #define HFI_SESSION_ERROR_BEGIN			0x04000000
@@ -49,6 +65,17 @@
 #define HFI_SYS_ERROR_WD_TIMEOUT		0x05000001
 #define HFI_SYSTEM_ERROR_END			0x05FFFFFF
=20
+enum hfi_color_format {
+	HFI_COLOR_FMT_OPAQUE			=3D 0,
+	HFI_COLOR_FMT_NV12			=3D 1,
+	HFI_COLOR_FMT_NV12_UBWC			=3D 2,
+	HFI_COLOR_FMT_P010			=3D 3,
+	HFI_COLOR_FMT_TP10_UBWC			=3D 4,
+	HFI_COLOR_FMT_RGBA8888			=3D 5,
+	HFI_COLOR_FMT_RGBA8888_UBWC		=3D 6,
+	HFI_COLOR_FMT_NV21			=3D 7,
+};
+
 enum hfi_codec_type {
 	HFI_CODEC_DECODE_AVC			=3D 1,
 	HFI_CODEC_ENCODE_AVC			=3D 2,
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c b/driv=
ers/media/platform/qcom/iris/iris_hfi_gen2_packet.c
index 739b2ce5bfae..d77fa29f44fc 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c
@@ -7,6 +7,85 @@
 #include "iris_hfi_gen2.h"
 #include "iris_hfi_gen2_packet.h"
=20
+u32 iris_hfi_gen2_get_color_primaries(u32 primaries)
+{
+	switch (primaries) {
+	case V4L2_COLORSPACE_DEFAULT:
+		return HFI_PRIMARIES_RESERVED;
+	case V4L2_COLORSPACE_REC709:
+		return HFI_PRIMARIES_BT709;
+	case V4L2_COLORSPACE_470_SYSTEM_M:
+		return HFI_PRIMARIES_BT470_SYSTEM_M;
+	case V4L2_COLORSPACE_470_SYSTEM_BG:
+		return HFI_PRIMARIES_BT470_SYSTEM_BG;
+	case V4L2_COLORSPACE_SMPTE170M:
+		return HFI_PRIMARIES_BT601_525;
+	case V4L2_COLORSPACE_SMPTE240M:
+		return HFI_PRIMARIES_SMPTE_ST240M;
+	case V4L2_COLORSPACE_BT2020:
+		return HFI_PRIMARIES_BT2020;
+	case V4L2_COLORSPACE_DCI_P3:
+		return HFI_PRIMARIES_SMPTE_RP431_2;
+	default:
+		return HFI_PRIMARIES_RESERVED;
+	}
+}
+
+u32 iris_hfi_gen2_get_transfer_char(u32 characterstics)
+{
+	switch (characterstics) {
+	case V4L2_XFER_FUNC_DEFAULT:
+		return HFI_TRANSFER_RESERVED;
+	case V4L2_XFER_FUNC_709:
+		return HFI_TRANSFER_BT709;
+	case V4L2_XFER_FUNC_SMPTE240M:
+		return HFI_TRANSFER_SMPTE_ST240M;
+	case V4L2_XFER_FUNC_SRGB:
+		return HFI_TRANSFER_SRGB_SYCC;
+	case V4L2_XFER_FUNC_SMPTE2084:
+		return HFI_TRANSFER_SMPTE_ST2084_PQ;
+	default:
+		return HFI_TRANSFER_RESERVED;
+	}
+}
+
+u32 iris_hfi_gen2_get_matrix_coefficients(u32 coefficients)
+{
+	switch (coefficients) {
+	case V4L2_YCBCR_ENC_DEFAULT:
+		return HFI_MATRIX_COEFF_RESERVED;
+	case V4L2_YCBCR_ENC_709:
+		return HFI_MATRIX_COEFF_BT709;
+	case V4L2_YCBCR_ENC_XV709:
+		return HFI_MATRIX_COEFF_BT709;
+	case V4L2_YCBCR_ENC_XV601:
+		return HFI_MATRIX_COEFF_BT470_SYS_BG_OR_BT601_625;
+	case V4L2_YCBCR_ENC_601:
+		return HFI_MATRIX_COEFF_BT601_525_BT1358_525_OR_625;
+	case V4L2_YCBCR_ENC_SMPTE240M:
+		return HFI_MATRIX_COEFF_SMPTE_ST240;
+	case V4L2_YCBCR_ENC_BT2020:
+		return HFI_MATRIX_COEFF_BT2020_NON_CONSTANT;
+	case V4L2_YCBCR_ENC_BT2020_CONST_LUM:
+		return HFI_MATRIX_COEFF_BT2020_CONSTANT;
+	default:
+		return HFI_MATRIX_COEFF_RESERVED;
+	}
+}
+
+u32 iris_hfi_gen2_get_color_info(u32 matrix_coeff, u32 transfer_char, u32 =
primaries,
+				 u32 colour_description_present_flag, u32 full_range,
+				 u32 video_format, u32 video_signal_type_present_flag)
+{
+	return (matrix_coeff & 0xFF) |
+		((transfer_char << 8) & 0xFF00) |
+		((primaries << 16) & 0xFF0000) |
+		((colour_description_present_flag << 24) & 0x1000000) |
+		((full_range << 25) & 0x2000000) |
+		((video_format << 26) & 0x1C000000) |
+		((video_signal_type_present_flag << 29) & 0x20000000);
+}
+
 static void iris_hfi_gen2_create_header(struct iris_hfi_header *hdr,
 					u32 session_id, u32 header_id)
 {
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h b/driv=
ers/media/platform/qcom/iris/iris_hfi_gen2_packet.h
index 4a9b88185b0d..0333e37572f6 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h
@@ -61,6 +61,13 @@ struct iris_hfi_packet {
 	u32 payload[];
 };
=20
+u32 iris_hfi_gen2_get_color_primaries(u32 primaries);
+u32 iris_hfi_gen2_get_transfer_char(u32 characterstics);
+u32 iris_hfi_gen2_get_matrix_coefficients(u32 coefficients);
+u32 iris_hfi_gen2_get_color_info(u32 matrix_coeff, u32 transfer_char, u32 =
primaries,
+				 u32 colour_description_present_flag, u32 full_range,
+				 u32 video_format, u32 video_signal_type_present_flag);
+
 void iris_hfi_gen2_packet_sys_init(struct iris_core *core, struct iris_hfi=
_header *hdr);
 void iris_hfi_gen2_packet_image_version(struct iris_core *core, struct iri=
s_hfi_header *hdr);
 void iris_hfi_gen2_packet_session_command(struct iris_inst *inst, u32 pkt_=
type,
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c b/dr=
ivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
index 53b700ef852e..336b43740b72 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
@@ -166,6 +166,53 @@ static int iris_hfi_gen2_handle_session_command(struct=
 iris_inst *inst,
 	return 0;
 }
=20
+static int iris_hfi_gen2_handle_session_property(struct iris_inst *inst,
+						 struct iris_hfi_packet *pkt)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+
+	if (pkt->port !=3D HFI_PORT_BITSTREAM)
+		return 0;
+
+	if (pkt->flags & HFI_FW_FLAGS_INFORMATION)
+		return 0;
+
+	switch (pkt->type) {
+	case HFI_PROP_BITSTREAM_RESOLUTION:
+		inst_hfi_gen2->src_subcr_params.bitstream_resolution =3D pkt->payload[0];
+		break;
+	case HFI_PROP_CROP_OFFSETS:
+		inst_hfi_gen2->src_subcr_params.crop_offsets[0] =3D pkt->payload[0];
+		inst_hfi_gen2->src_subcr_params.crop_offsets[1] =3D pkt->payload[1];
+		break;
+	case HFI_PROP_CODED_FRAMES:
+		inst_hfi_gen2->src_subcr_params.coded_frames =3D pkt->payload[0];
+		break;
+	case HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT:
+		inst_hfi_gen2->src_subcr_params.fw_min_count =3D pkt->payload[0];
+		break;
+	case HFI_PROP_PIC_ORDER_CNT_TYPE:
+		inst_hfi_gen2->src_subcr_params.pic_order_cnt =3D pkt->payload[0];
+		break;
+	case HFI_PROP_SIGNAL_COLOR_INFO:
+		inst_hfi_gen2->src_subcr_params.color_info =3D pkt->payload[0];
+		break;
+	case HFI_PROP_PROFILE:
+		inst_hfi_gen2->src_subcr_params.profile =3D pkt->payload[0];
+		break;
+	case HFI_PROP_LEVEL:
+		inst_hfi_gen2->src_subcr_params.level =3D pkt->payload[0];
+		break;
+	case HFI_PROP_QUALITY_MODE:
+	case HFI_PROP_STAGE:
+	case HFI_PROP_PIPE:
+	default:
+		break;
+	}
+
+	return 0;
+}
+
 static int iris_hfi_gen2_handle_image_version_property(struct iris_core *c=
ore,
 						       struct iris_hfi_packet *pkt)
 {
@@ -250,6 +297,8 @@ static int iris_hfi_gen2_handle_session_response(struct=
 iris_core *core,
 	static const struct iris_hfi_gen2_inst_hfi_range range[] =3D {
 		{HFI_SESSION_ERROR_BEGIN, HFI_SESSION_ERROR_END,
 		 iris_hfi_gen2_handle_session_error},
+		{HFI_PROP_BEGIN, HFI_PROP_END,
+		 iris_hfi_gen2_handle_session_property},
 		{HFI_CMD_BEGIN, HFI_CMD_END,
 		 iris_hfi_gen2_handle_session_command },
 	};
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/driv=
ers/media/platform/qcom/iris/iris_platform_common.h
index 23170cd37c04..5643fb55b09e 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -6,12 +6,31 @@
 #ifndef __IRIS_PLATFORM_COMMON_H__
 #define __IRIS_PLATFORM_COMMON_H__
=20
+#include <linux/bits.h>
+
 struct iris_core;
+struct iris_inst;
=20
 #define IRIS_PAS_ID				9
 #define HW_RESPONSE_TIMEOUT_VALUE               (1000) /* milliseconds */
 #define AUTOSUSPEND_DELAY_VALUE			(HW_RESPONSE_TIMEOUT_VALUE + 500) /* mil=
liseconds */
=20
+#define REGISTER_BIT_DEPTH(luma, chroma)	((luma) << 16 | (chroma))
+#define BIT_DEPTH_8				REGISTER_BIT_DEPTH(8, 8)
+#define CODED_FRAMES_PROGRESSIVE		0x0
+#define DEFAULT_MAX_HOST_BUF_COUNT		64
+#define DEFAULT_MAX_HOST_BURST_BUF_COUNT	256
+enum stage_type {
+	STAGE_1 =3D 1,
+	STAGE_2 =3D 2,
+};
+
+enum pipe_type {
+	PIPE_1 =3D 1,
+	PIPE_2 =3D 2,
+	PIPE_4 =3D 4,
+};
+
 extern struct iris_platform_data sm8550_data;
=20
 enum platform_clk_type {
@@ -53,6 +72,13 @@ struct platform_inst_caps {
 enum platform_inst_fw_cap_type {
 	PROFILE =3D 1,
 	LEVEL,
+	INPUT_BUF_HOST_MAX_COUNT,
+	STAGE,
+	PIPE,
+	POC,
+	CODED_FRAMES,
+	BIT_DEPTH,
+	RAP_FRAME,
 	DEBLOCK,
 	INST_FW_CAP_MAX,
 };
@@ -75,6 +101,8 @@ struct platform_inst_fw_cap {
 	s64 value;
 	u32 hfi_id;
 	enum platform_inst_fw_cap_flags flags;
+	int (*set)(struct iris_inst *inst,
+		   enum platform_inst_fw_cap_type cap_id);
 };
=20
 struct iris_core_power {
@@ -115,6 +143,10 @@ struct iris_platform_data {
 	struct ubwc_config_data *ubwc_config;
 	u32 num_vpp_pipe;
 	u32 max_session_count;
+	const u32 *input_config_params;
+	unsigned int input_config_params_size;
+	const u32 *output_config_params;
+	unsigned int output_config_params_size;
 };
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/driv=
ers/media/platform/qcom/iris/iris_platform_sm8550.c
index 58b1d1d43731..8a55c1f731c0 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
@@ -4,6 +4,7 @@
  */
=20
 #include "iris_core.h"
+#include "iris_ctrls.h"
 #include "iris_hfi_gen2.h"
 #include "iris_hfi_gen2_defines.h"
 #include "iris_platform_common.h"
@@ -24,6 +25,7 @@ static struct platform_inst_fw_cap inst_fw_cap_sm8550[] =
=3D {
 		.value =3D V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
 		.hfi_id =3D HFI_PROP_PROFILE,
 		.flags =3D CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		.set =3D iris_set_u32_enum,
 	},
 	{
 		.cap_id =3D LEVEL,
@@ -52,6 +54,69 @@ static struct platform_inst_fw_cap inst_fw_cap_sm8550[] =
=3D {
 		.value =3D V4L2_MPEG_VIDEO_H264_LEVEL_6_1,
 		.hfi_id =3D HFI_PROP_LEVEL,
 		.flags =3D CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		.set =3D iris_set_u32_enum,
+	},
+	{
+		.cap_id =3D INPUT_BUF_HOST_MAX_COUNT,
+		.min =3D DEFAULT_MAX_HOST_BUF_COUNT,
+		.max =3D DEFAULT_MAX_HOST_BURST_BUF_COUNT,
+		.step_or_mask =3D 1,
+		.value =3D DEFAULT_MAX_HOST_BUF_COUNT,
+		.hfi_id =3D HFI_PROP_BUFFER_HOST_MAX_COUNT,
+		.flags =3D CAP_FLAG_INPUT_PORT,
+		.set =3D iris_set_u32,
+	},
+	{
+		.cap_id =3D STAGE,
+		.min =3D STAGE_1,
+		.max =3D STAGE_2,
+		.step_or_mask =3D 1,
+		.value =3D STAGE_2,
+		.hfi_id =3D HFI_PROP_STAGE,
+		.set =3D iris_set_stage,
+	},
+	{
+		.cap_id =3D PIPE,
+		.min =3D PIPE_1,
+		.max =3D PIPE_4,
+		.step_or_mask =3D 1,
+		.value =3D PIPE_4,
+		.hfi_id =3D HFI_PROP_PIPE,
+		.set =3D iris_set_pipe,
+	},
+	{
+		.cap_id =3D POC,
+		.min =3D 0,
+		.max =3D 2,
+		.step_or_mask =3D 1,
+		.value =3D 1,
+		.hfi_id =3D HFI_PROP_PIC_ORDER_CNT_TYPE,
+	},
+	{
+		.cap_id =3D CODED_FRAMES,
+		.min =3D CODED_FRAMES_PROGRESSIVE,
+		.max =3D CODED_FRAMES_PROGRESSIVE,
+		.step_or_mask =3D 0,
+		.value =3D CODED_FRAMES_PROGRESSIVE,
+		.hfi_id =3D HFI_PROP_CODED_FRAMES,
+	},
+	{
+		.cap_id =3D BIT_DEPTH,
+		.min =3D BIT_DEPTH_8,
+		.max =3D BIT_DEPTH_8,
+		.step_or_mask =3D 1,
+		.value =3D BIT_DEPTH_8,
+		.hfi_id =3D HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
+	},
+	{
+		.cap_id =3D RAP_FRAME,
+		.min =3D 0,
+		.max =3D 1,
+		.step_or_mask =3D 1,
+		.value =3D 1,
+		.hfi_id =3D HFI_PROP_DEC_START_FROM_RAP_FRAME,
+		.flags =3D CAP_FLAG_INPUT_PORT,
+		.set =3D iris_set_u32,
 	},
 };
=20
@@ -102,6 +167,22 @@ static struct tz_cp_config tz_cp_config_sm8550 =3D {
 	.cp_nonpixel_size =3D 0x24800000,
 };
=20
+static const u32 sm8550_vdec_input_config_params[] =3D {
+	HFI_PROP_BITSTREAM_RESOLUTION,
+	HFI_PROP_CROP_OFFSETS,
+	HFI_PROP_CODED_FRAMES,
+	HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
+	HFI_PROP_PIC_ORDER_CNT_TYPE,
+	HFI_PROP_PROFILE,
+	HFI_PROP_LEVEL,
+	HFI_PROP_SIGNAL_COLOR_INFO,
+};
+
+static const u32 sm8550_vdec_output_config_params[] =3D {
+	HFI_PROP_COLOR_FORMAT,
+	HFI_PROP_LINEAR_STRIDE_SCANLINE,
+};
+
 struct iris_platform_data sm8550_data =3D {
 	.get_instance =3D iris_hfi_gen2_get_instance,
 	.init_hfi_command_ops =3D iris_hfi_gen2_command_ops_init,
@@ -131,4 +212,12 @@ struct iris_platform_data sm8550_data =3D {
 	.ubwc_config =3D &ubwc_config_sm8550,
 	.num_vpp_pipe =3D 4,
 	.max_session_count =3D 16,
+	.input_config_params =3D
+		sm8550_vdec_input_config_params,
+	.input_config_params_size =3D
+		ARRAY_SIZE(sm8550_vdec_input_config_params),
+	.output_config_params =3D
+		sm8550_vdec_output_config_params,
+	.output_config_params_size =3D
+		ARRAY_SIZE(sm8550_vdec_output_config_params),
 };
diff --git a/drivers/media/platform/qcom/iris/iris_utils.c b/drivers/media/=
platform/qcom/iris/iris_utils.c
index 4833830f30d5..8bcfa97db97d 100644
--- a/drivers/media/platform/qcom/iris/iris_utils.c
+++ b/drivers/media/platform/qcom/iris/iris_utils.c
@@ -8,6 +8,20 @@
 #include "iris_instance.h"
 #include "iris_utils.h"
=20
+bool iris_res_is_less_than(u32 width, u32 height,
+			   u32 ref_width, u32 ref_height)
+{
+	u32 num_mbs =3D NUM_MBS_PER_FRAME(height, width);
+	u32 max_side =3D max(ref_width, ref_height);
+
+	if (num_mbs < NUM_MBS_PER_FRAME(ref_height, ref_width) &&
+	    width < max_side &&
+	    height < max_side)
+		return true;
+
+	return false;
+}
+
 int iris_get_mbpf(struct iris_inst *inst)
 {
 	struct v4l2_format *inp_f =3D inst->fmt_src;
@@ -17,6 +31,11 @@ int iris_get_mbpf(struct iris_inst *inst)
 	return NUM_MBS_PER_FRAME(height, width);
 }
=20
+bool iris_split_mode_enabled(struct iris_inst *inst)
+{
+	return inst->fmt_dst->fmt.pix_mp.pixelformat =3D=3D V4L2_PIX_FMT_NV12;
+}
+
 int iris_wait_for_session_response(struct iris_inst *inst, bool is_flush)
 {
 	struct iris_core *core =3D inst->core;
diff --git a/drivers/media/platform/qcom/iris/iris_utils.h b/drivers/media/=
platform/qcom/iris/iris_utils.h
index 40658a6643cf..3400847f5e72 100644
--- a/drivers/media/platform/qcom/iris/iris_utils.h
+++ b/drivers/media/platform/qcom/iris/iris_utils.h
@@ -27,7 +27,10 @@ static inline enum iris_buffer_type iris_v4l2_type_to_dr=
iver(u32 type)
 		return BUF_OUTPUT;
 }
=20
+bool iris_res_is_less_than(u32 width, u32 height,
+			   u32 ref_width, u32 ref_height);
 int iris_get_mbpf(struct iris_inst *inst);
+bool iris_split_mode_enabled(struct iris_inst *inst);
 struct iris_inst *iris_get_instance(struct iris_core *core, u32 session_id=
);
 int iris_wait_for_session_response(struct iris_inst *inst, bool is_flush);
=20
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/p=
latform/qcom/iris/iris_vdec.c
index 92651d86376d..13902f4e9724 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.c
+++ b/drivers/media/platform/qcom/iris/iris_vdec.c
@@ -267,6 +267,12 @@ static int iris_vdec_process_streamon_input(struct iri=
s_inst *inst)
=20
 int iris_vdec_streamon_input(struct iris_inst *inst)
 {
+	int ret;
+
+	ret =3D iris_set_properties(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+	if (ret)
+		return ret;
+
 	return iris_vdec_process_streamon_input(inst);
 }
=20
@@ -284,8 +290,13 @@ static int iris_vdec_process_streamon_output(struct ir=
is_inst *inst)
=20
 int iris_vdec_streamon_output(struct iris_inst *inst)
 {
+	const struct iris_hfi_command_ops *hfi_ops =3D inst->core->hfi_ops;
 	int ret;
=20
+	ret =3D hfi_ops->session_set_config_params(inst, V4L2_BUF_TYPE_VIDEO_CAPT=
URE_MPLANE);
+	if (ret)
+		return ret;
+
 	ret =3D iris_vdec_process_streamon_output(inst);
 	if (ret)
 		goto error;
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c b/drivers/m=
edia/platform/qcom/iris/iris_vpu_buffer.c
index 2402a33723ab..0a65a17f13d2 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
@@ -6,6 +6,24 @@
 #include "iris_instance.h"
 #include "iris_vpu_buffer.h"
=20
+u32 iris_vpu_dec_dpb_size(struct iris_inst *inst)
+{
+	if (iris_split_mode_enabled(inst))
+		return iris_get_buffer_size(inst, BUF_DPB);
+	else
+		return 0;
+}
+
+static inline int iris_vpu_dpb_count(struct iris_inst *inst)
+{
+	if (iris_split_mode_enabled(inst)) {
+		return inst->fw_min_count ?
+			inst->fw_min_count : inst->buffers[BUF_OUTPUT].min_count;
+	}
+
+	return 0;
+}
+
 int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffe=
r_type)
 {
 	switch (buffer_type) {
@@ -13,6 +31,8 @@ int iris_vpu_buf_count(struct iris_inst *inst, enum iris_=
buffer_type buffer_type
 		return MIN_BUFFERS;
 	case BUF_OUTPUT:
 		return inst->fw_min_count;
+	case BUF_DPB:
+		return iris_vpu_dpb_count(inst);
 	default:
 		return 0;
 	}
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h b/drivers/m=
edia/platform/qcom/iris/iris_vpu_buffer.h
index 06e6e958dcac..865539d626b7 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
@@ -10,6 +10,7 @@ struct iris_inst;
=20
 #define MIN_BUFFERS			4
=20
+u32 iris_vpu_dec_dpb_size(struct iris_inst *inst);
 int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffe=
r_type);
=20
 #endif

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 7025E23CEFD;
	Fri,  7 Feb 2025 07:57:14 +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=1738915036; cv=none;
 b=DScuzjGVwemtYBwP/o5vDTmkIfvT6seWFUhiX+XQqikMefSuws7oczDxWGUcIoWpFwWRKyTgSaNIaZouXB+Ed58i5zs5frFwv1iM97uTmPPcbYhPY4T+4j+mRi+YyWjjDKNlu0zLHc7igc/wGZ1MdsCq7Y2jZ7zVkuxHdWRvBNk=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738915036; c=relaxed/simple;
	bh=HHu6deM263UvaCePvgFJoH9D5S6qx+7hRpIDTGmDptU=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=EHkJV/qlQQhl5gU+EzaxpxXLvpySXUKM0vwF5wHCZR5EKwQpvGYioTLWYRvKtDAvKJokzBDv+zoF6MwNIr7+IXTAZA8eP7m2vPQjWFhTaUfLiZpnJrsllWUL5Wm40n2OhCOKUSJDRazUIaDx7bZdr79P6R3Y649a4+xiSkoumzI=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=GA5Qms7b; arc=none smtp.client-ip=205.220.168.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="GA5Qms7b"
Received: from pps.filterd (m0279866.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 51770V9x016698;
	Fri, 7 Feb 2025 07:57:01 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	dOG3slx237nH33zPcYs4GCFBCKwvZ/hg/vgGLIsUq9Y=; b=GA5Qms7bp53/KlcM
	GD8QE6jg4OseAH+Ev5wIjEQd3ZbZbQKxx1O+Nrk+brZZH8/IWFLBIrjZUUDPS0Jj
	FzgbPPuz27YKIg/y0Zpb1Q3BDdbTaYaj/EPLUgCC0uWQ0BtQW5GMKv/J1mvlSTE+
	mIM46fHtTnBFn4h3mlyHV9oeD4NN+Cm62xWgCiFl3WWHRvzULIJMzUU/r2Uzk3sm
	cBh/6SdA9FYQzc5lzOAAikMMJskz6RZPlaVYZBIwjyYKPH4remrnQAAiLUCqBMLF
	8ERdUl9KNbE/AThJd6hP4k816n2VLJ53X9H2qn9abOEPskzdOehw2r3KczxWnrFb
	WFwQ2Q==
Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44nddh04ey-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:57:00 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA05.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177uxHh029331
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:56:59 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:56:53 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:24:58 +0530
Subject: [PATCH v10 18/28] media: iris: subscribe parameters and properties
 to firmware for hfi_gen2
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-18-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>,
        Vedang Nagar <quic_vnagar@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914893; l=11685;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=snSkMBLaRsK5d39i1TgsNyUCTBTWm8uT3INL3/NmhW0=;
 b=TJObBmxHPAL7WjxeUB0SWGfaa2Dt73b7Gkt7akBMNOLo+fIwjUbj+D09Oq+jVfgIINA/keCi4
 Tu+ScfGwPbJAumcoZEh4JIrCjmHE+GpDEApFgDlOfab8hyPsRHHOmDS
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-ORIG-GUID: tIVBENrtupshir0-9-mAQLqjkNlkEP1_
X-Proofpoint-GUID: tIVBENrtupshir0-9-mAQLqjkNlkEP1_
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 phishscore=0 suspectscore=0
 clxscore=1015 mlxlogscore=999 lowpriorityscore=0 impostorscore=0
 mlxscore=0 spamscore=0 priorityscore=1501 adultscore=0 malwarescore=0
 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070060

From: Vedang Nagar <quic_vnagar@quicinc.com>

For hfi_gen2, subscribe different bitstream parameters on to firmware,
to get notified of a change in any of the subscribed parameters.

Signed-off-by: Vedang Nagar <quic_vnagar@quicinc.com>
Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 drivers/media/platform/qcom/iris/iris_hfi_gen2.h   |   6 +
 .../platform/qcom/iris/iris_hfi_gen2_command.c     | 174 +++++++++++++++++=
++++
 .../platform/qcom/iris/iris_hfi_gen2_defines.h     |   9 ++
 .../platform/qcom/iris/iris_platform_common.h      |   4 +
 .../platform/qcom/iris/iris_platform_sm8550.c      |  13 ++
 5 files changed, 206 insertions(+)

diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h b/drivers/med=
ia/platform/qcom/iris/iris_hfi_gen2.h
index 676bcb3dc81f..0a946c1e3a4c 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h
@@ -18,12 +18,18 @@ struct iris_core;
  *
  * @inst: pointer to iris_instance structure
  * @packet: HFI packet
+ * @ipsc_properties_set: boolean to set ipsc properties to fw
+ * @opsc_properties_set: boolean to set opsc properties to fw
  * @src_subcr_params: subscription params to fw on input port
+ * @dst_subcr_params: subscription params to fw on output port
  */
 struct iris_inst_hfi_gen2 {
 	struct iris_inst		inst;
 	struct iris_hfi_header		*packet;
+	bool				ipsc_properties_set;
+	bool				opsc_properties_set;
 	struct hfi_subscription_params	src_subcr_params;
+	struct hfi_subscription_params	dst_subcr_params;
 };
=20
 void iris_hfi_gen2_command_ops_init(struct iris_core *core);
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen2_command.c
index 0845b75aafe9..dddaa074cae1 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
@@ -437,6 +437,9 @@ static int iris_hfi_gen2_session_open(struct iris_inst =
*inst)
 	if (inst->state !=3D IRIS_INST_DEINIT)
 		return -EALREADY;
=20
+	inst_hfi_gen2->ipsc_properties_set =3D false;
+	inst_hfi_gen2->opsc_properties_set =3D false;
+
 	inst_hfi_gen2->packet =3D kzalloc(4096, GFP_KERNEL);
 	if (!inst_hfi_gen2->packet)
 		return -ENOMEM;
@@ -501,9 +504,180 @@ static int iris_hfi_gen2_session_close(struct iris_in=
st *inst)
 	return ret;
 }
=20
+static int iris_hfi_gen2_session_subscribe_mode(struct iris_inst *inst,
+						u32 cmd, u32 plane, u32 payload_type,
+						void *payload, u32 payload_size)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+
+	iris_hfi_gen2_packet_session_command(inst,
+					     cmd,
+					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+					     HFI_HOST_FLAGS_INTR_REQUIRED),
+					     iris_hfi_gen2_get_port(plane),
+					     inst->session_id,
+					     payload_type,
+					     payload,
+					     payload_size);
+
+	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
+					inst_hfi_gen2->packet->size);
+}
+
+static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u3=
2 plane)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	struct hfi_subscription_params subsc_params;
+	u32 prop_type, payload_size, payload_type;
+	struct iris_core *core =3D inst->core;
+	const u32 *change_param;
+	u32 change_param_size;
+	u32 payload[32] =3D {0};
+	u32 hfi_port =3D 0, i;
+	int ret;
+
+	if ((V4L2_TYPE_IS_OUTPUT(plane) && inst_hfi_gen2->ipsc_properties_set) ||
+	    (V4L2_TYPE_IS_CAPTURE(plane) && inst_hfi_gen2->opsc_properties_set)) {
+		dev_err(core->dev, "invalid plane\n");
+		return 0;
+	}
+
+	change_param =3D core->iris_platform_data->input_config_params;
+	change_param_size =3D core->iris_platform_data->input_config_params_size;
+
+	payload[0] =3D HFI_MODE_PORT_SETTINGS_CHANGE;
+
+	for (i =3D 0; i < change_param_size; i++)
+		payload[i + 1] =3D change_param[i];
+
+	ret =3D iris_hfi_gen2_session_subscribe_mode(inst,
+						   HFI_CMD_SUBSCRIBE_MODE,
+						   plane,
+						   HFI_PAYLOAD_U32_ARRAY,
+						   &payload[0],
+						   ((change_param_size + 1) * sizeof(u32)));
+	if (ret)
+		return ret;
+
+	if (V4L2_TYPE_IS_OUTPUT(plane)) {
+		inst_hfi_gen2->ipsc_properties_set =3D true;
+	} else {
+		hfi_port =3D iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+		memcpy(&inst_hfi_gen2->dst_subcr_params,
+		       &inst_hfi_gen2->src_subcr_params,
+		       sizeof(inst_hfi_gen2->src_subcr_params));
+		subsc_params =3D inst_hfi_gen2->dst_subcr_params;
+		for (i =3D 0; i < change_param_size; i++) {
+			payload[0] =3D 0;
+			payload[1] =3D 0;
+			payload_size =3D 0;
+			payload_type =3D 0;
+			prop_type =3D change_param[i];
+			switch (prop_type) {
+			case HFI_PROP_BITSTREAM_RESOLUTION:
+				payload[0] =3D subsc_params.bitstream_resolution;
+				payload_size =3D sizeof(u32);
+				payload_type =3D HFI_PAYLOAD_U32;
+				break;
+			case HFI_PROP_CROP_OFFSETS:
+				payload[0] =3D subsc_params.crop_offsets[0];
+				payload[1] =3D subsc_params.crop_offsets[1];
+				payload_size =3D sizeof(u64);
+				payload_type =3D HFI_PAYLOAD_64_PACKED;
+				break;
+			case HFI_PROP_CODED_FRAMES:
+				payload[0] =3D subsc_params.coded_frames;
+				payload_size =3D sizeof(u32);
+				payload_type =3D HFI_PAYLOAD_U32;
+				break;
+			case HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT:
+				payload[0] =3D subsc_params.fw_min_count;
+				payload_size =3D sizeof(u32);
+				payload_type =3D HFI_PAYLOAD_U32;
+				break;
+			case HFI_PROP_PIC_ORDER_CNT_TYPE:
+				payload[0] =3D subsc_params.pic_order_cnt;
+				payload_size =3D sizeof(u32);
+				payload_type =3D HFI_PAYLOAD_U32;
+				break;
+			case HFI_PROP_SIGNAL_COLOR_INFO:
+				payload[0] =3D subsc_params.color_info;
+				payload_size =3D sizeof(u32);
+				payload_type =3D HFI_PAYLOAD_U32;
+				break;
+			case HFI_PROP_PROFILE:
+				payload[0] =3D subsc_params.profile;
+				payload_size =3D sizeof(u32);
+				payload_type =3D HFI_PAYLOAD_U32;
+				break;
+			case HFI_PROP_LEVEL:
+				payload[0] =3D subsc_params.level;
+				payload_size =3D sizeof(u32);
+				payload_type =3D HFI_PAYLOAD_U32;
+				break;
+			default:
+				prop_type =3D 0;
+				ret =3D -EINVAL;
+				break;
+			}
+			if (prop_type) {
+				ret =3D iris_hfi_gen2_session_set_property(inst,
+									 prop_type,
+									 HFI_HOST_FLAGS_NONE,
+									 hfi_port,
+									 payload_type,
+									 &payload,
+									 payload_size);
+				if (ret)
+					return ret;
+			}
+		}
+		inst_hfi_gen2->opsc_properties_set =3D true;
+	}
+
+	return 0;
+}
+
+static int iris_hfi_gen2_subscribe_property(struct iris_inst *inst, u32 pl=
ane)
+{
+	struct iris_core *core =3D inst->core;
+	u32 subscribe_prop_size, i;
+	const u32 *subcribe_prop;
+	u32 payload[32] =3D {0};
+
+	payload[0] =3D HFI_MODE_PROPERTY;
+
+	if (V4L2_TYPE_IS_OUTPUT(plane)) {
+		subscribe_prop_size =3D core->iris_platform_data->dec_input_prop_size;
+		subcribe_prop =3D core->iris_platform_data->dec_input_prop;
+	} else {
+		subscribe_prop_size =3D core->iris_platform_data->dec_output_prop_size;
+		subcribe_prop =3D core->iris_platform_data->dec_output_prop;
+	}
+
+	for (i =3D 0; i < subscribe_prop_size; i++)
+		payload[i + 1] =3D subcribe_prop[i];
+
+	return iris_hfi_gen2_session_subscribe_mode(inst,
+						    HFI_CMD_SUBSCRIBE_MODE,
+						    plane,
+						    HFI_PAYLOAD_U32_ARRAY,
+						    &payload[0],
+						    (subscribe_prop_size + 1) * sizeof(u32));
+}
+
 static int iris_hfi_gen2_session_start(struct iris_inst *inst, u32 plane)
 {
 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	int ret =3D 0;
+
+	ret =3D iris_hfi_gen2_subscribe_change_param(inst, plane);
+	if (ret)
+		return ret;
+
+	ret =3D iris_hfi_gen2_subscribe_property(inst, plane);
+	if (ret)
+		return ret;
=20
 	iris_hfi_gen2_packet_session_command(inst,
 					     HFI_CMD_START,
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
index 4c9604b05034..4fb7a4e4604d 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
@@ -17,6 +17,7 @@
 #define HFI_CMD_CLOSE				0x01000004
 #define HFI_CMD_START				0x01000005
 #define HFI_CMD_STOP				0x01000006
+#define HFI_CMD_SUBSCRIBE_MODE			0x0100000B
 #define HFI_CMD_END				0x01FFFFFF
=20
 #define HFI_BITMASK_FRAME_MBS_ONLY_FLAG		0x00000001
@@ -42,13 +43,16 @@
 #define HFI_PROP_PIPE				0x0300010b
 #define HFI_PROP_LUMA_CHROMA_BIT_DEPTH		0x0300010f
 #define HFI_PROP_CODED_FRAMES			0x03000120
+#define HFI_PROP_CABAC_SESSION			0x03000121
 #define HFI_PROP_BUFFER_HOST_MAX_COUNT		0x03000123
 #define HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT	0x03000124
 #define HFI_PROP_PIC_ORDER_CNT_TYPE		0x03000128
 #define HFI_PROP_QUALITY_MODE			0x03000148
 #define HFI_PROP_SIGNAL_COLOR_INFO		0x03000155
+#define HFI_PROP_PICTURE_TYPE			0x03000162
 #define HFI_PROP_DEC_DEFAULT_HEADER		0x03000168
 #define HFI_PROP_DEC_START_FROM_RAP_FRAME	0x03000169
+#define HFI_PROP_NO_OUTPUT			0x0300016a
 #define HFI_PROP_END				0x03FFFFFF
=20
 #define HFI_SESSION_ERROR_BEGIN			0x04000000
@@ -65,6 +69,11 @@
 #define HFI_SYS_ERROR_WD_TIMEOUT		0x05000001
 #define HFI_SYSTEM_ERROR_END			0x05FFFFFF
=20
+enum hfi_property_mode_type {
+	HFI_MODE_PORT_SETTINGS_CHANGE		=3D 0x00000001,
+	HFI_MODE_PROPERTY			=3D 0x00000002,
+};
+
 enum hfi_color_format {
 	HFI_COLOR_FMT_OPAQUE			=3D 0,
 	HFI_COLOR_FMT_NV12			=3D 1,
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/driv=
ers/media/platform/qcom/iris/iris_platform_common.h
index 5643fb55b09e..50965450cbb9 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -147,6 +147,10 @@ struct iris_platform_data {
 	unsigned int input_config_params_size;
 	const u32 *output_config_params;
 	unsigned int output_config_params_size;
+	const u32 *dec_input_prop;
+	unsigned int dec_input_prop_size;
+	const u32 *dec_output_prop;
+	unsigned int dec_output_prop_size;
 };
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/driv=
ers/media/platform/qcom/iris/iris_platform_sm8550.c
index 8a55c1f731c0..703e48802795 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
@@ -183,6 +183,15 @@ static const u32 sm8550_vdec_output_config_params[] =
=3D {
 	HFI_PROP_LINEAR_STRIDE_SCANLINE,
 };
=20
+static const u32 sm8550_vdec_subscribe_input_properties[] =3D {
+	HFI_PROP_NO_OUTPUT,
+};
+
+static const u32 sm8550_vdec_subscribe_output_properties[] =3D {
+	HFI_PROP_PICTURE_TYPE,
+	HFI_PROP_CABAC_SESSION,
+};
+
 struct iris_platform_data sm8550_data =3D {
 	.get_instance =3D iris_hfi_gen2_get_instance,
 	.init_hfi_command_ops =3D iris_hfi_gen2_command_ops_init,
@@ -220,4 +229,8 @@ struct iris_platform_data sm8550_data =3D {
 		sm8550_vdec_output_config_params,
 	.output_config_params_size =3D
 		ARRAY_SIZE(sm8550_vdec_output_config_params),
+	.dec_input_prop =3D sm8550_vdec_subscribe_input_properties,
+	.dec_input_prop_size =3D ARRAY_SIZE(sm8550_vdec_subscribe_input_propertie=
s),
+	.dec_output_prop =3D sm8550_vdec_subscribe_output_properties,
+	.dec_output_prop_size =3D ARRAY_SIZE(sm8550_vdec_subscribe_output_propert=
ies),
 };

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 5929523770F;
	Fri,  7 Feb 2025 07:57:25 +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=1738915048; cv=none;
 b=NTDS7QHSTGk5x6DYb8vYbACdaxDimQh125Ftof7HF4k17T/pFl7fL+CfN0d/c/e8CaWHscbuH8kzVJym2/Y8tnnDkAaJucpmT1Qq/ALxM7F6ddAimF2iur9jtgzhFq90A2066K15pkcl3mnjzGL0WqnWobwB3X5h19czgJCQppg=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738915048; c=relaxed/simple;
	bh=prHYYj4SNsRurOEMC9IWnhWO6xRP4P0aD1+h3vpZ+uI=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=GSE+xsXiFvUwcShHXLMeCB+DhTFSe9a3O1qG6PGyF+UkcfeQIKMuerce+m0Hiwc98CJRuZ01kg2P16ajRNurCQm9wri0Vsi5/jXA1b3GALQEmYwD5xGfHRA5vORNoDtJHu1zxUtkCWXTrKgDfKuXV11MspPmSG8CdtxVGklIokk=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=L2vRN9qI; arc=none smtp.client-ip=205.220.168.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="L2vRN9qI"
Received: from pps.filterd (m0279865.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 51770h60010570;
	Fri, 7 Feb 2025 07:57:07 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	htX27ELz2Vn+nd8KhX7NQ15nI+bxHuIvriy0dlbCT3A=; b=L2vRN9qIjIsizq1o
	VVD1mqepX3uvm9d8cTQu6/+gl+rgUuY7rgnWREPOk4Tur/RRi/9mA+n9GWnzwMlA
	8JFLM400TGnV/aWEJI7dJmth0YRK92twHeZ9F2H7I3LpjAhTdbS7HVCi73MYZrDd
	DRo1kDwN5qDXKxcUOq/YsQPU2XxSQRcsOyZ2kNFzaFwu+qMqaAt6MR0ticEAz1Er
	y9jebxeS5ukf5eRRvH7tr3ZDgE6FBXycGhhLWCX/hjxcQBP3AWUmJygcT4XI9nY/
	dw7GfG+/V6GeJbVfZFuRk4eVplnXmlACPclVzKNW7wM/mq0uOcFO/KGpYXG4ZRGy
	8Xwitw==
Received: from nalasppmta04.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44nddkg4gb-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:57:07 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA04.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177v6RD009974
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:57:06 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:56:59 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:24:59 +0530
Subject: [PATCH v10 19/28] media: iris: allocate, initialize and queue
 internal buffers
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-19-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914893; l=48820;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=prHYYj4SNsRurOEMC9IWnhWO6xRP4P0aD1+h3vpZ+uI=;
 b=vTOZAk/uQo46lcc9wrL8FmnFCg/aaamPsEGwHBkCaio9lMSKqBMWuChKfXXb8UEX4U2Uh7DIA
 j2fpl4uLeo0AydhbeQ89NVY9cfFfKhYhD2XuKb6a+2IL77CiJqtu/W/
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-GUID: RYKT1iv2Zu5iP0yXgO82Yiilu0PIckjg
X-Proofpoint-ORIG-GUID: RYKT1iv2Zu5iP0yXgO82Yiilu0PIckjg
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 bulkscore=0
 lowpriorityscore=0 mlxlogscore=999 priorityscore=1501 impostorscore=0
 suspectscore=0 clxscore=1015 malwarescore=0 mlxscore=0 spamscore=0
 adultscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070060

Implement the functions for creating, queueing, releasing and destroying
the buffers for internal usage.

Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 drivers/media/platform/qcom/iris/iris_buffer.c     | 206 ++++++++++++++++++
 drivers/media/platform/qcom/iris/iris_buffer.h     |   7 +
 drivers/media/platform/qcom/iris/iris_hfi_common.h |   4 +
 .../platform/qcom/iris/iris_hfi_gen1_command.c     | 127 ++++++++++-
 .../platform/qcom/iris/iris_hfi_gen1_defines.h     |  37 ++++
 .../platform/qcom/iris/iris_hfi_gen1_response.c    |   4 +
 .../platform/qcom/iris/iris_hfi_gen2_command.c     | 132 ++++++++++++
 .../platform/qcom/iris/iris_hfi_gen2_defines.h     |   9 +
 .../platform/qcom/iris/iris_hfi_gen2_packet.h      |  41 ++++
 .../platform/qcom/iris/iris_hfi_gen2_response.c    | 149 ++++++++++++-
 .../platform/qcom/iris/iris_platform_common.h      |   5 +
 .../platform/qcom/iris/iris_platform_sm8550.c      |  17 ++
 drivers/media/platform/qcom/iris/iris_vdec.c       |  32 +++
 drivers/media/platform/qcom/iris/iris_vidc.c       |  11 +
 drivers/media/platform/qcom/iris/iris_vpu_buffer.c | 233 +++++++++++++++++=
+++-
 drivers/media/platform/qcom/iris/iris_vpu_buffer.h |  77 ++++++-
 16 files changed, 1087 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media=
/platform/qcom/iris/iris_buffer.c
index 58d45d23393b..e9d372580b5f 100644
--- a/drivers/media/platform/qcom/iris/iris_buffer.c
+++ b/drivers/media/platform/qcom/iris/iris_buffer.c
@@ -7,6 +7,7 @@
=20
 #include "iris_buffer.h"
 #include "iris_instance.h"
+#include "iris_vpu_buffer.h"
=20
 #define PIXELS_4K 4096
 #define MAX_WIDTH 4096
@@ -228,6 +229,211 @@ int iris_get_buffer_size(struct iris_inst *inst,
 	}
 }
=20
+static void iris_fill_internal_buf_info(struct iris_inst *inst,
+					enum iris_buffer_type buffer_type)
+{
+	struct iris_buffers *buffers =3D &inst->buffers[buffer_type];
+
+	buffers->size =3D iris_vpu_buf_size(inst, buffer_type);
+	buffers->min_count =3D iris_vpu_buf_count(inst, buffer_type);
+}
+
+void iris_get_internal_buffers(struct iris_inst *inst, u32 plane)
+{
+	const struct iris_platform_data *platform_data =3D inst->core->iris_platf=
orm_data;
+	const u32 *internal_buf_type;
+	u32 internal_buffer_count, i;
+
+	if (V4L2_TYPE_IS_OUTPUT(plane)) {
+		internal_buf_type =3D platform_data->dec_ip_int_buf_tbl;
+		internal_buffer_count =3D platform_data->dec_ip_int_buf_tbl_size;
+		for (i =3D 0; i < internal_buffer_count; i++)
+			iris_fill_internal_buf_info(inst, internal_buf_type[i]);
+	} else {
+		internal_buf_type =3D platform_data->dec_op_int_buf_tbl;
+		internal_buffer_count =3D platform_data->dec_op_int_buf_tbl_size;
+		for (i =3D 0; i < internal_buffer_count; i++)
+			iris_fill_internal_buf_info(inst, internal_buf_type[i]);
+	}
+}
+
+static int iris_create_internal_buffer(struct iris_inst *inst,
+				       enum iris_buffer_type buffer_type, u32 index)
+{
+	struct iris_buffers *buffers =3D &inst->buffers[buffer_type];
+	struct iris_core *core =3D inst->core;
+	struct iris_buffer *buffer;
+
+	if (!buffers->size)
+		return 0;
+
+	buffer =3D kzalloc(sizeof(*buffer), GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&buffer->list);
+	buffer->type =3D buffer_type;
+	buffer->index =3D index;
+	buffer->buffer_size =3D buffers->size;
+	buffer->dma_attrs =3D DMA_ATTR_WRITE_COMBINE | DMA_ATTR_NO_KERNEL_MAPPING;
+	list_add_tail(&buffer->list, &buffers->list);
+
+	buffer->kvaddr =3D dma_alloc_attrs(core->dev, buffer->buffer_size,
+					 &buffer->device_addr, GFP_KERNEL, buffer->dma_attrs);
+	if (!buffer->kvaddr)
+		return -ENOMEM;
+
+	return 0;
+}
+
+int iris_create_internal_buffers(struct iris_inst *inst, u32 plane)
+{
+	const struct iris_platform_data *platform_data =3D inst->core->iris_platf=
orm_data;
+	u32 internal_buffer_count, i, j;
+	struct iris_buffers *buffers;
+	const u32 *internal_buf_type;
+	int ret;
+
+	if (V4L2_TYPE_IS_OUTPUT(plane)) {
+		internal_buf_type =3D platform_data->dec_ip_int_buf_tbl;
+		internal_buffer_count =3D platform_data->dec_ip_int_buf_tbl_size;
+	} else {
+		internal_buf_type =3D platform_data->dec_op_int_buf_tbl;
+		internal_buffer_count =3D platform_data->dec_op_int_buf_tbl_size;
+	}
+
+	for (i =3D 0; i < internal_buffer_count; i++) {
+		buffers =3D &inst->buffers[internal_buf_type[i]];
+		for (j =3D 0; j < buffers->min_count; j++) {
+			ret =3D iris_create_internal_buffer(inst, internal_buf_type[i], j);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
+int iris_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf)
+{
+	const struct iris_hfi_command_ops *hfi_ops =3D inst->core->hfi_ops;
+	int ret;
+
+	ret =3D hfi_ops->session_queue_buf(inst, buf);
+	if (ret)
+		return ret;
+
+	buf->attr &=3D ~BUF_ATTR_DEFERRED;
+	buf->attr |=3D BUF_ATTR_QUEUED;
+
+	return 0;
+}
+
+int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane)
+{
+	const struct iris_platform_data *platform_data =3D inst->core->iris_platf=
orm_data;
+	struct iris_buffer *buffer, *next;
+	struct iris_buffers *buffers;
+	const u32 *internal_buf_type;
+	u32 internal_buffer_count, i;
+	int ret;
+
+	if (V4L2_TYPE_IS_OUTPUT(plane)) {
+		internal_buf_type =3D platform_data->dec_ip_int_buf_tbl;
+		internal_buffer_count =3D platform_data->dec_ip_int_buf_tbl_size;
+	} else {
+		internal_buf_type =3D platform_data->dec_op_int_buf_tbl;
+		internal_buffer_count =3D platform_data->dec_op_int_buf_tbl_size;
+	}
+
+	for (i =3D 0; i < internal_buffer_count; i++) {
+		buffers =3D &inst->buffers[internal_buf_type[i]];
+		list_for_each_entry_safe(buffer, next, &buffers->list, list) {
+			if (buffer->attr & BUF_ATTR_PENDING_RELEASE)
+				continue;
+			if (buffer->attr & BUF_ATTR_QUEUED)
+				continue;
+			ret =3D iris_queue_buffer(inst, buffer);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
+int iris_destroy_internal_buffer(struct iris_inst *inst, struct iris_buffe=
r *buffer)
+{
+	struct iris_core *core =3D inst->core;
+
+	list_del(&buffer->list);
+	dma_free_attrs(core->dev, buffer->buffer_size, buffer->kvaddr,
+		       buffer->device_addr, buffer->dma_attrs);
+	kfree(buffer);
+
+	return 0;
+}
+
+int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane)
+{
+	const struct iris_platform_data *platform_data =3D inst->core->iris_platf=
orm_data;
+	struct iris_buffer *buf, *next;
+	struct iris_buffers *buffers;
+	const u32 *internal_buf_type;
+	u32 i, len;
+	int ret;
+
+	if (V4L2_TYPE_IS_OUTPUT(plane)) {
+		internal_buf_type =3D platform_data->dec_ip_int_buf_tbl;
+		len =3D platform_data->dec_ip_int_buf_tbl_size;
+	} else {
+		internal_buf_type =3D platform_data->dec_op_int_buf_tbl;
+		len =3D platform_data->dec_op_int_buf_tbl_size;
+	}
+
+	for (i =3D 0; i < len; i++) {
+		buffers =3D &inst->buffers[internal_buf_type[i]];
+		list_for_each_entry_safe(buf, next, &buffers->list, list) {
+			ret =3D iris_destroy_internal_buffer(inst, buf);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
+int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst)
+{
+	struct iris_buffers *buffers =3D &inst->buffers[BUF_PERSIST];
+	struct iris_buffer *buffer, *next;
+	int ret;
+	u32 i;
+
+	if (!list_empty(&buffers->list))
+		return 0;
+
+	iris_fill_internal_buf_info(inst, BUF_PERSIST);
+
+	for (i =3D 0; i < buffers->min_count; i++) {
+		ret =3D iris_create_internal_buffer(inst, BUF_PERSIST, i);
+		if (ret)
+			return ret;
+	}
+
+	list_for_each_entry_safe(buffer, next, &buffers->list, list) {
+		if (buffer->attr & BUF_ATTR_PENDING_RELEASE)
+			continue;
+		if (buffer->attr & BUF_ATTR_QUEUED)
+			continue;
+		ret =3D iris_queue_buffer(inst, buffer);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 void iris_vb2_queue_error(struct iris_inst *inst)
 {
 	struct v4l2_m2m_ctx *m2m_ctx =3D inst->m2m_ctx;
diff --git a/drivers/media/platform/qcom/iris/iris_buffer.h b/drivers/media=
/platform/qcom/iris/iris_buffer.h
index ae2ec5637108..73f3a16ff7a2 100644
--- a/drivers/media/platform/qcom/iris/iris_buffer.h
+++ b/drivers/media/platform/qcom/iris/iris_buffer.h
@@ -102,6 +102,13 @@ struct iris_buffers {
 };
=20
 int iris_get_buffer_size(struct iris_inst *inst, enum iris_buffer_type buf=
fer_type);
+void iris_get_internal_buffers(struct iris_inst *inst, u32 plane);
+int iris_create_internal_buffers(struct iris_inst *inst, u32 plane);
+int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane);
+int iris_destroy_internal_buffer(struct iris_inst *inst, struct iris_buffe=
r *buffer);
+int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane);
+int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst);
+int iris_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf);
 void iris_vb2_queue_error(struct iris_inst *inst);
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/m=
edia/platform/qcom/iris/iris_hfi_common.h
index 1fba5a9292af..c54c88658633 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_common.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h
@@ -9,6 +9,8 @@
 #include <linux/types.h>
 #include <media/v4l2-device.h>
=20
+#include "iris_buffer.h"
+
 struct iris_inst;
 struct iris_core;
=20
@@ -114,6 +116,8 @@ struct iris_hfi_command_ops {
 				    void *payload, u32 payload_size);
 	int (*session_open)(struct iris_inst *inst);
 	int (*session_start)(struct iris_inst *inst, u32 plane);
+	int (*session_queue_buf)(struct iris_inst *inst, struct iris_buffer *buff=
er);
+	int (*session_release_buf)(struct iris_inst *inst, struct iris_buffer *bu=
ffer);
 	int (*session_stop)(struct iris_inst *inst, u32 plane);
 	int (*session_close)(struct iris_inst *inst);
 };
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen1_command.c
index 26fe65ddba8a..603ca485992d 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
@@ -8,6 +8,24 @@
 #include "iris_instance.h"
 #include "iris_vpu_buffer.h"
=20
+static u32 iris_hfi_gen1_buf_type_from_driver(enum iris_buffer_type buffer=
_type)
+{
+	switch (buffer_type) {
+	case BUF_INPUT:
+		return HFI_BUFFER_INPUT;
+	case BUF_OUTPUT:
+		return HFI_BUFFER_OUTPUT;
+	case BUF_PERSIST:
+		return HFI_BUFFER_INTERNAL_PERSIST_1;
+	case BUF_BIN:
+		return HFI_BUFFER_INTERNAL_SCRATCH;
+	case BUF_SCRATCH_1:
+		return HFI_BUFFER_INTERNAL_SCRATCH_1;
+	default:
+		return -EINVAL;
+	}
+}
+
 static int iris_hfi_gen1_sys_init(struct iris_core *core)
 {
 	struct hfi_sys_init_pkt sys_init_pkt;
@@ -183,6 +201,111 @@ static int iris_hfi_gen1_session_stop(struct iris_ins=
t *inst, u32 plane)
 	return ret;
 }
=20
+static int iris_hfi_gen1_queue_internal_buffer(struct iris_inst *inst, str=
uct iris_buffer *buf)
+{
+	struct hfi_session_set_buffers_pkt *int_pkt;
+	u32 buffer_type, i;
+	u32 packet_size;
+	int ret;
+
+	packet_size =3D struct_size(int_pkt, buffer_info, 1);
+	int_pkt =3D kzalloc(packet_size, GFP_KERNEL);
+	if (!int_pkt)
+		return -ENOMEM;
+
+	int_pkt->shdr.hdr.pkt_type =3D HFI_CMD_SESSION_SET_BUFFERS;
+	int_pkt->shdr.session_id =3D inst->session_id;
+	int_pkt->buffer_size =3D buf->buffer_size;
+	int_pkt->min_buffer_size =3D buf->buffer_size;
+	int_pkt->num_buffers =3D 1;
+	int_pkt->extradata_size =3D 0;
+	int_pkt->shdr.hdr.size =3D packet_size;
+	for (i =3D 0; i < int_pkt->num_buffers; i++)
+		int_pkt->buffer_info[i] =3D buf->device_addr;
+	buffer_type =3D iris_hfi_gen1_buf_type_from_driver(buf->type);
+	if (buffer_type =3D=3D -EINVAL) {
+		ret =3D -EINVAL;
+		goto exit;
+	}
+
+	int_pkt->buffer_type =3D buffer_type;
+	ret =3D iris_hfi_queue_cmd_write(inst->core, int_pkt, int_pkt->shdr.hdr.s=
ize);
+
+exit:
+	kfree(int_pkt);
+
+	return ret;
+}
+
+static int iris_hfi_gen1_session_queue_buffer(struct iris_inst *inst, stru=
ct iris_buffer *buf)
+{
+	switch (buf->type) {
+	case BUF_PERSIST:
+	case BUF_BIN:
+	case BUF_SCRATCH_1:
+		return iris_hfi_gen1_queue_internal_buffer(inst, buf);
+	default:
+		return -EINVAL;
+	}
+}
+
+static int iris_hfi_gen1_session_unset_buffers(struct iris_inst *inst, str=
uct iris_buffer *buf)
+{
+	struct hfi_session_release_buffer_pkt *pkt;
+	u32 packet_size, buffer_type, i;
+	int ret;
+
+	buffer_type =3D iris_hfi_gen1_buf_type_from_driver(buf->type);
+	if (buffer_type =3D=3D -EINVAL)
+		return -EINVAL;
+
+	if (buffer_type =3D=3D HFI_BUFFER_INPUT)
+		return 0;
+
+	packet_size =3D sizeof(*pkt) + sizeof(struct hfi_buffer_info);
+	pkt =3D kzalloc(packet_size, GFP_KERNEL);
+	if (!pkt)
+		return -ENOMEM;
+
+	pkt->shdr.hdr.pkt_type =3D HFI_CMD_SESSION_RELEASE_BUFFERS;
+	pkt->shdr.session_id =3D inst->session_id;
+	pkt->buffer_size =3D buf->buffer_size;
+	pkt->num_buffers =3D 1;
+
+	if (buffer_type =3D=3D HFI_BUFFER_OUTPUT ||
+	    buffer_type =3D=3D HFI_BUFFER_OUTPUT2) {
+		struct hfi_buffer_info *bi;
+
+		bi =3D (struct hfi_buffer_info *)pkt->buffer_info;
+		for (i =3D 0; i < pkt->num_buffers; i++) {
+			bi->buffer_addr =3D buf->device_addr;
+			bi->extradata_addr =3D 0;
+		}
+		pkt->shdr.hdr.size =3D packet_size;
+	} else {
+		for (i =3D 0; i < pkt->num_buffers; i++)
+			pkt->buffer_info[i] =3D buf->device_addr;
+		pkt->extradata_size =3D 0;
+		pkt->shdr.hdr.size =3D
+				sizeof(struct hfi_session_set_buffers_pkt) +
+				((pkt->num_buffers) * sizeof(u32));
+	}
+
+	pkt->response_req =3D true;
+	pkt->buffer_type =3D buffer_type;
+
+	ret =3D iris_hfi_queue_cmd_write(inst->core, pkt, pkt->shdr.hdr.size);
+	if (ret)
+		goto exit;
+
+	ret =3D iris_wait_for_session_response(inst, false);
+
+exit:
+	kfree(pkt);
+
+	return ret;
+}
+
 static int
 iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_=
pkt *packet,
 					  struct iris_inst *inst, u32 ptype, void *pdata)
@@ -495,7 +618,7 @@ static int iris_hfi_gen1_set_bufsize(struct iris_inst *=
inst)
=20
 	if (iris_split_mode_enabled(inst)) {
 		bufsz.type =3D HFI_BUFFER_OUTPUT;
-		bufsz.size =3D iris_vpu_dec_dpb_size(inst);
+		bufsz.size =3D iris_vpu_buf_size(inst, BUF_DPB);
=20
 		ret =3D hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz));
 		if (ret)
@@ -600,6 +723,8 @@ static const struct iris_hfi_command_ops iris_hfi_gen1_=
command_ops =3D {
 	.session_set_config_params =3D iris_hfi_gen1_session_set_config_params,
 	.session_set_property =3D iris_hfi_gen1_session_set_property,
 	.session_start =3D iris_hfi_gen1_session_start,
+	.session_queue_buf =3D iris_hfi_gen1_session_queue_buffer,
+	.session_release_buf =3D iris_hfi_gen1_session_unset_buffers,
 	.session_stop =3D iris_hfi_gen1_session_stop,
 	.session_close =3D iris_hfi_gen1_session_close,
 };
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
index 67e7575351d4..cabd91eafc92 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
@@ -24,11 +24,13 @@
 #define HFI_CMD_SYS_SESSION_END				0x10008
=20
 #define HFI_CMD_SESSION_SET_PROPERTY			0x11001
+#define HFI_CMD_SESSION_SET_BUFFERS			0x11002
=20
 #define HFI_CMD_SESSION_LOAD_RESOURCES			0x211001
 #define HFI_CMD_SESSION_START				0x211002
 #define HFI_CMD_SESSION_STOP				0x211003
 #define HFI_CMD_SESSION_FLUSH				0x211008
+#define HFI_CMD_SESSION_RELEASE_BUFFERS			0x21100b
 #define HFI_CMD_SESSION_RELEASE_RESOURCES		0x21100c
=20
 #define HFI_ERR_SESSION_UNSUPPORTED_SETTING		0x1008
@@ -53,6 +55,9 @@
 #define HFI_BUFFER_INPUT				0x1
 #define HFI_BUFFER_OUTPUT				0x2
 #define HFI_BUFFER_OUTPUT2				0x3
+#define HFI_BUFFER_INTERNAL_PERSIST_1			0x5
+#define HFI_BUFFER_INTERNAL_SCRATCH			0x6
+#define HFI_BUFFER_INTERNAL_SCRATCH_1			0x7
=20
 #define HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL		0x5
 #define HFI_PROPERTY_SYS_IMAGE_VERSION			0x6
@@ -80,6 +85,7 @@
 #define HFI_MSG_SESSION_STOP				0x221003
 #define HFI_MSG_SESSION_FLUSH				0x221006
 #define HFI_MSG_SESSION_RELEASE_RESOURCES		0x22100a
+#define HFI_MSG_SESSION_RELEASE_BUFFERS			0x22100c
=20
 struct hfi_pkt_hdr {
 	u32 size;
@@ -128,11 +134,36 @@ struct hfi_sys_pc_prep_pkt {
 	struct hfi_pkt_hdr hdr;
 };
=20
+struct hfi_session_set_buffers_pkt {
+	struct hfi_session_hdr_pkt shdr;
+	u32 buffer_type;
+	u32 buffer_size;
+	u32 extradata_size;
+	u32 min_buffer_size;
+	u32 num_buffers;
+	u32 buffer_info[];
+};
+
 struct hfi_session_flush_pkt {
 	struct hfi_session_hdr_pkt shdr;
 	u32 flush_type;
 };
=20
+struct hfi_session_release_buffer_pkt {
+	struct hfi_session_hdr_pkt shdr;
+	u32 buffer_type;
+	u32 buffer_size;
+	u32 extradata_size;
+	u32 response_req;
+	u32 num_buffers;
+	u32 buffer_info[];
+};
+
+struct hfi_buffer_info {
+	u32 buffer_addr;
+	u32 extradata_addr;
+};
+
 struct hfi_msg_event_notify_pkt {
 	struct hfi_session_hdr_pkt shdr;
 	u32 event_id;
@@ -227,6 +258,12 @@ struct hfi_multi_stream {
 	u32 enable;
 };
=20
+struct hfi_msg_session_release_buffers_done_pkt {
+	struct hfi_msg_session_hdr_pkt shdr;
+	u32 num_buffers;
+	u32 buffer_info[];
+};
+
 struct hfi_msg_sys_debug_pkt {
 	struct hfi_pkt_hdr hdr;
 	u32 msg_type;
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c b/dr=
ivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
index db5858ec04ea..a84bb00388d9 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
@@ -176,6 +176,10 @@ static const struct iris_hfi_gen1_response_pkt_info pk=
t_infos[] =3D {
 	 .pkt =3D HFI_MSG_SESSION_RELEASE_RESOURCES,
 	 .pkt_sz =3D sizeof(struct hfi_msg_session_hdr_pkt),
 	},
+	{
+	 .pkt =3D HFI_MSG_SESSION_RELEASE_BUFFERS,
+	 .pkt_sz =3D sizeof(struct hfi_msg_session_release_buffers_done_pkt),
+	},
 };
=20
 static void iris_hfi_gen1_handle_response(struct iris_core *core, void *re=
sponse)
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen2_command.c
index dddaa074cae1..cc75231f07f1 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
@@ -100,6 +100,24 @@ static u32 iris_hfi_gen2_get_port(u32 plane)
 	}
 }
=20
+static u32 iris_hfi_gen2_get_port_from_buf_type(enum iris_buffer_type buff=
er_type)
+{
+	switch (buffer_type) {
+	case BUF_INPUT:
+	case BUF_BIN:
+	case BUF_COMV:
+	case BUF_NON_COMV:
+	case BUF_LINE:
+		return HFI_PORT_BITSTREAM;
+	case BUF_OUTPUT:
+	case BUF_DPB:
+		return HFI_PORT_RAW;
+	case BUF_PERSIST:
+	default:
+		return HFI_PORT_NONE;
+	}
+}
+
 static int iris_hfi_gen2_session_set_property(struct iris_inst *inst, u32 =
packet_type, u32 flag,
 					      u32 plane, u32 payload_type, void *payload,
 					      u32 payload_size)
@@ -719,6 +737,118 @@ static int iris_hfi_gen2_session_stop(struct iris_ins=
t *inst, u32 plane)
 	return iris_wait_for_session_response(inst, false);
 }
=20
+static u32 iris_hfi_gen2_buf_type_from_driver(enum iris_buffer_type buffer=
_type)
+{
+	switch (buffer_type) {
+	case BUF_INPUT:
+		return HFI_BUFFER_BITSTREAM;
+	case BUF_OUTPUT:
+		return HFI_BUFFER_RAW;
+	case BUF_BIN:
+		return HFI_BUFFER_BIN;
+	case BUF_COMV:
+		return HFI_BUFFER_COMV;
+	case BUF_NON_COMV:
+		return HFI_BUFFER_NON_COMV;
+	case BUF_LINE:
+		return HFI_BUFFER_LINE;
+	case BUF_DPB:
+		return HFI_BUFFER_DPB;
+	case BUF_PERSIST:
+		return HFI_BUFFER_PERSIST;
+	default:
+		return 0;
+	}
+}
+
+static int iris_set_num_comv(struct iris_inst *inst)
+{
+	struct platform_inst_caps *caps;
+	struct iris_core *core =3D inst->core;
+	u32 num_comv;
+
+	caps =3D core->iris_platform_data->inst_caps;
+	num_comv =3D caps->num_comv;
+
+	return core->hfi_ops->session_set_property(inst,
+						   HFI_PROP_COMV_BUFFER_COUNT,
+						   HFI_HOST_FLAGS_NONE,
+						   HFI_PORT_BITSTREAM,
+						   HFI_PAYLOAD_U32,
+						   &num_comv, sizeof(u32));
+}
+
+static void iris_hfi_gen2_get_buffer(struct iris_buffer *buffer, struct ir=
is_hfi_buffer *buf)
+{
+	memset(buf, 0, sizeof(*buf));
+	buf->type =3D iris_hfi_gen2_buf_type_from_driver(buffer->type);
+	buf->index =3D buffer->index;
+	buf->base_address =3D buffer->device_addr;
+	buf->addr_offset =3D 0;
+	buf->buffer_size =3D buffer->buffer_size;
+
+	if (buffer->type =3D=3D BUF_INPUT)
+		buf->buffer_size =3D ALIGN(buffer->buffer_size, 256);
+	buf->data_offset =3D buffer->data_offset;
+	buf->data_size =3D buffer->data_size;
+	if (buffer->attr & BUF_ATTR_PENDING_RELEASE)
+		buf->flags |=3D HFI_BUF_HOST_FLAG_RELEASE;
+	buf->flags |=3D HFI_BUF_HOST_FLAGS_CB_NON_SECURE;
+	buf->timestamp =3D buffer->timestamp;
+}
+
+static int iris_hfi_gen2_session_queue_buffer(struct iris_inst *inst, stru=
ct iris_buffer *buffer)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	struct iris_hfi_buffer hfi_buffer;
+	u32 port;
+	int ret;
+
+	iris_hfi_gen2_get_buffer(buffer, &hfi_buffer);
+	if (buffer->type =3D=3D BUF_COMV) {
+		ret =3D iris_set_num_comv(inst);
+		if (ret)
+			return ret;
+	}
+
+	port =3D iris_hfi_gen2_get_port_from_buf_type(buffer->type);
+	iris_hfi_gen2_packet_session_command(inst,
+					     HFI_CMD_BUFFER,
+					     HFI_HOST_FLAGS_INTR_REQUIRED,
+					     port,
+					     inst->session_id,
+					     HFI_PAYLOAD_STRUCTURE,
+					     &hfi_buffer,
+					     sizeof(hfi_buffer));
+
+	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
+					inst_hfi_gen2->packet->size);
+}
+
+static int iris_hfi_gen2_session_release_buffer(struct iris_inst *inst, st=
ruct iris_buffer *buffer)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	struct iris_hfi_buffer hfi_buffer;
+	u32 port;
+
+	iris_hfi_gen2_get_buffer(buffer, &hfi_buffer);
+	hfi_buffer.flags |=3D HFI_BUF_HOST_FLAG_RELEASE;
+	port =3D iris_hfi_gen2_get_port_from_buf_type(buffer->type);
+
+	iris_hfi_gen2_packet_session_command(inst,
+					     HFI_CMD_BUFFER,
+					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+					     HFI_HOST_FLAGS_INTR_REQUIRED),
+					     port,
+					     inst->session_id,
+					     HFI_PAYLOAD_STRUCTURE,
+					     &hfi_buffer,
+					     sizeof(hfi_buffer));
+
+	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
+					inst_hfi_gen2->packet->size);
+}
+
 static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops =3D {
 	.sys_init =3D iris_hfi_gen2_sys_init,
 	.sys_image_version =3D iris_hfi_gen2_sys_image_version,
@@ -728,6 +858,8 @@ static const struct iris_hfi_command_ops iris_hfi_gen2_=
command_ops =3D {
 	.session_set_config_params =3D iris_hfi_gen2_session_set_config_params,
 	.session_set_property =3D iris_hfi_gen2_session_set_property,
 	.session_start =3D iris_hfi_gen2_session_start,
+	.session_queue_buf =3D iris_hfi_gen2_session_queue_buffer,
+	.session_release_buf =3D iris_hfi_gen2_session_release_buffer,
 	.session_stop =3D iris_hfi_gen2_session_stop,
 	.session_close =3D iris_hfi_gen2_session_close,
 };
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
index 4fb7a4e4604d..afbdf1f1e68a 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
@@ -17,6 +17,7 @@
 #define HFI_CMD_CLOSE				0x01000004
 #define HFI_CMD_START				0x01000005
 #define HFI_CMD_STOP				0x01000006
+#define HFI_CMD_BUFFER				0x01000009
 #define HFI_CMD_SUBSCRIBE_MODE			0x0100000B
 #define HFI_CMD_END				0x01FFFFFF
=20
@@ -53,6 +54,7 @@
 #define HFI_PROP_DEC_DEFAULT_HEADER		0x03000168
 #define HFI_PROP_DEC_START_FROM_RAP_FRAME	0x03000169
 #define HFI_PROP_NO_OUTPUT			0x0300016a
+#define HFI_PROP_COMV_BUFFER_COUNT		0x03000193
 #define HFI_PROP_END				0x03FFFFFF
=20
 #define HFI_SESSION_ERROR_BEGIN			0x04000000
@@ -106,6 +108,13 @@ enum hfi_buffer_type {
 	HFI_BUFFER_VPSS				=3D 0x0000000D,
 };
=20
+enum hfi_buffer_host_flags {
+	HFI_BUF_HOST_FLAG_RELEASE		=3D 0x00000001,
+	HFI_BUF_HOST_FLAG_READONLY		=3D 0x00000010,
+	HFI_BUF_HOST_FLAG_CODEC_CONFIG		=3D 0x00000100,
+	HFI_BUF_HOST_FLAGS_CB_NON_SECURE	=3D 0x00000200,
+};
+
 enum hfi_packet_firmware_flags {
 	HFI_FW_FLAGS_SUCCESS			=3D 0x00000001,
 	HFI_FW_FLAGS_INFORMATION		=3D 0x00000002,
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h b/driv=
ers/media/platform/qcom/iris/iris_hfi_gen2_packet.h
index 0333e37572f6..25b9582349ca 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h
@@ -61,6 +61,47 @@ struct iris_hfi_packet {
 	u32 payload[];
 };
=20
+/**
+ * struct iris_hfi_buffer
+ *
+ * @type: buffer type indicated by "enum hfi_buffer_type"
+ *        FW needs to return proper type for any buffer command.
+ * @index: index of the buffer
+ * @base_address: base address of the buffer.
+ *                This buffer address is always 4KBytes aligned.
+ * @addr_offset: accessible buffer offset from base address
+ *               Decoder bitstream buffer: 256 Bytes aligned
+ *               Firmware can uniquely identify a buffer based on
+ *               base_address & addr_offset.
+ *               HW can read memory only from base_address+addr_offset.
+ * @buffer_size: accessible buffer size in bytes starting from addr_offset
+ * @data_offset: data starts from "base_address + addr_offset + data_offse=
t"
+ *               RAW buffer: data_offset is 0. Restriction: 4KBytes aligned
+ *               decoder bitstream buffer: no restriction (can be any valu=
e)
+ * @data_size: data size in bytes
+ * @flags: buffer flags. It is represented as bit masks.
+ *         host buffer flags are "enum hfi_buffer_host_flags"
+ *         firmware buffer flags are "enum hfi_buffer_firmware_flags"
+ * @timestamp: timestamp of the buffer in nano seconds (ns)
+ *             It is Presentation timestamp (PTS) for encoder & decoder.
+ *             Decoder: it is pass through from bitstream to raw buffer.
+ *                      firmware does not need to return as part of input =
buffer done.
+ *             For any internal buffers: there is no timestamp. Host sets =
as 0.
+ * @reserved: reserved for future use
+ */
+struct iris_hfi_buffer {
+	u32 type;
+	u32 index;
+	u64 base_address;
+	u32 addr_offset;
+	u32 buffer_size;
+	u32 data_offset;
+	u32 data_size;
+	u64 timestamp;
+	u32 flags;
+	u32 reserved[5];
+};
+
 u32 iris_hfi_gen2_get_color_primaries(u32 primaries);
 u32 iris_hfi_gen2_get_transfer_char(u32 characterstics);
 u32 iris_hfi_gen2_get_matrix_coefficients(u32 coefficients);
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c b/dr=
ivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
index 336b43740b72..9f3764f1903b 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
@@ -25,6 +25,94 @@ struct iris_hfi_gen2_packet_handle {
 	int (*handle)(struct iris_inst *inst, struct iris_hfi_packet *pkt);
 };
=20
+static u32 iris_hfi_gen2_buf_type_to_driver(enum hfi_buffer_type buf_type)
+{
+	switch (buf_type) {
+	case HFI_BUFFER_BITSTREAM:
+		return BUF_INPUT;
+	case HFI_BUFFER_RAW:
+		return BUF_OUTPUT;
+	case HFI_BUFFER_BIN:
+		return BUF_BIN;
+	case HFI_BUFFER_ARP:
+		return BUF_ARP;
+	case HFI_BUFFER_COMV:
+		return BUF_COMV;
+	case HFI_BUFFER_NON_COMV:
+		return BUF_NON_COMV;
+	case HFI_BUFFER_LINE:
+		return BUF_LINE;
+	case HFI_BUFFER_DPB:
+		return BUF_DPB;
+	case HFI_BUFFER_PERSIST:
+		return BUF_PERSIST;
+	default:
+		return 0;
+	}
+}
+
+static bool iris_hfi_gen2_is_valid_hfi_buffer_type(u32 buffer_type)
+{
+	switch (buffer_type) {
+	case HFI_BUFFER_BITSTREAM:
+	case HFI_BUFFER_RAW:
+	case HFI_BUFFER_BIN:
+	case HFI_BUFFER_ARP:
+	case HFI_BUFFER_COMV:
+	case HFI_BUFFER_NON_COMV:
+	case HFI_BUFFER_LINE:
+	case HFI_BUFFER_DPB:
+	case HFI_BUFFER_PERSIST:
+	case HFI_BUFFER_VPSS:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool iris_hfi_gen2_is_valid_hfi_port(u32 port, u32 buffer_type)
+{
+	if (port =3D=3D HFI_PORT_NONE && buffer_type !=3D HFI_BUFFER_PERSIST)
+		return false;
+
+	if (port !=3D HFI_PORT_BITSTREAM && port !=3D HFI_PORT_RAW)
+		return false;
+
+	return true;
+}
+
+static bool iris_hfi_gen2_validate_packet_payload(struct iris_hfi_packet *=
pkt)
+{
+	u32 payload_size =3D 0;
+
+	switch (pkt->payload_info) {
+	case HFI_PAYLOAD_U32:
+	case HFI_PAYLOAD_S32:
+	case HFI_PAYLOAD_Q16:
+	case HFI_PAYLOAD_U32_ENUM:
+	case HFI_PAYLOAD_32_PACKED:
+		payload_size =3D 4;
+		break;
+	case HFI_PAYLOAD_U64:
+	case HFI_PAYLOAD_S64:
+	case HFI_PAYLOAD_64_PACKED:
+		payload_size =3D 8;
+		break;
+	case HFI_PAYLOAD_STRUCTURE:
+		if (pkt->type =3D=3D HFI_CMD_BUFFER)
+			payload_size =3D sizeof(struct iris_hfi_buffer);
+		break;
+	default:
+		payload_size =3D 0;
+		break;
+	}
+
+	if (pkt->size < sizeof(struct iris_hfi_packet) + payload_size)
+		return false;
+
+	return true;
+}
+
 static int iris_hfi_gen2_validate_packet(u8 *response_pkt, u8 *core_resp_p=
kt)
 {
 	u8 *response_limit =3D core_resp_pkt + IFACEQ_CORE_PKT_SIZE;
@@ -149,9 +237,65 @@ static void iris_hfi_gen2_handle_session_close(struct =
iris_inst *inst,
 	complete(&inst->completion);
 }
=20
+static int iris_hfi_gen2_handle_release_internal_buffer(struct iris_inst *=
inst,
+							struct iris_hfi_buffer *buffer)
+{
+	struct iris_buffer *buf, *iter;
+	struct iris_buffers *buffers;
+	u32 buf_type;
+	int ret =3D 0;
+	bool found;
+
+	buf_type =3D iris_hfi_gen2_buf_type_to_driver(buffer->type);
+	buffers =3D &inst->buffers[buf_type];
+
+	found =3D false;
+	list_for_each_entry(iter, &buffers->list, list) {
+		if (iter->device_addr =3D=3D buffer->base_address) {
+			found =3D true;
+			buf =3D iter;
+			break;
+		}
+	}
+	if (!found)
+		return -EINVAL;
+
+	buf->attr &=3D ~BUF_ATTR_QUEUED;
+
+	if (buf->attr & BUF_ATTR_PENDING_RELEASE)
+		ret =3D iris_destroy_internal_buffer(inst, buf);
+
+	return ret;
+}
+
+static int iris_hfi_gen2_handle_session_buffer(struct iris_inst *inst,
+					       struct iris_hfi_packet *pkt)
+{
+	struct iris_hfi_buffer *buffer;
+
+	if (pkt->payload_info =3D=3D HFI_PAYLOAD_NONE)
+		return 0;
+
+	if (!iris_hfi_gen2_validate_packet_payload(pkt)) {
+		iris_inst_change_state(inst, IRIS_INST_ERROR);
+		return 0;
+	}
+
+	buffer =3D (struct iris_hfi_buffer *)((u8 *)pkt + sizeof(*pkt));
+	if (!iris_hfi_gen2_is_valid_hfi_buffer_type(buffer->type))
+		return 0;
+
+	if (!iris_hfi_gen2_is_valid_hfi_port(pkt->port, buffer->type))
+		return 0;
+
+	return iris_hfi_gen2_handle_release_internal_buffer(inst, buffer);
+}
+
 static int iris_hfi_gen2_handle_session_command(struct iris_inst *inst,
 						struct iris_hfi_packet *pkt)
 {
+	int ret =3D 0;
+
 	switch (pkt->type) {
 	case HFI_CMD_CLOSE:
 		iris_hfi_gen2_handle_session_close(inst, pkt);
@@ -159,11 +303,14 @@ static int iris_hfi_gen2_handle_session_command(struc=
t iris_inst *inst,
 	case HFI_CMD_STOP:
 		complete(&inst->completion);
 		break;
+	case HFI_CMD_BUFFER:
+		ret =3D iris_hfi_gen2_handle_session_buffer(inst, pkt);
+		break;
 	default:
 		break;
 	}
=20
-	return 0;
+	return ret;
 }
=20
 static int iris_hfi_gen2_handle_session_property(struct iris_inst *inst,
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/driv=
ers/media/platform/qcom/iris/iris_platform_common.h
index 50965450cbb9..de0388a100c3 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -67,6 +67,7 @@ struct platform_inst_caps {
 	u32 min_frame_height;
 	u32 max_frame_height;
 	u32 max_mbpf;
+	u32 num_comv;
 };
=20
 enum platform_inst_fw_cap_type {
@@ -151,6 +152,10 @@ struct iris_platform_data {
 	unsigned int dec_input_prop_size;
 	const u32 *dec_output_prop;
 	unsigned int dec_output_prop_size;
+	const u32 *dec_ip_int_buf_tbl;
+	unsigned int dec_ip_int_buf_tbl_size;
+	const u32 *dec_op_int_buf_tbl;
+	unsigned int dec_op_int_buf_tbl_size;
 };
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/driv=
ers/media/platform/qcom/iris/iris_platform_sm8550.c
index 703e48802795..dc51df71c377 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
@@ -126,6 +126,7 @@ static struct platform_inst_caps platform_inst_cap_sm85=
50 =3D {
 	.min_frame_height =3D 96,
 	.max_frame_height =3D 8192,
 	.max_mbpf =3D (8192 * 4352) / 256,
+	.num_comv =3D 0,
 };
=20
 static void iris_set_sm8550_preset_registers(struct iris_core *core)
@@ -192,6 +193,17 @@ static const u32 sm8550_vdec_subscribe_output_properti=
es[] =3D {
 	HFI_PROP_CABAC_SESSION,
 };
=20
+static const u32 sm8550_dec_ip_int_buf_tbl[] =3D {
+	BUF_BIN,
+	BUF_COMV,
+	BUF_NON_COMV,
+	BUF_LINE,
+};
+
+static const u32 sm8550_dec_op_int_buf_tbl[] =3D {
+	BUF_DPB,
+};
+
 struct iris_platform_data sm8550_data =3D {
 	.get_instance =3D iris_hfi_gen2_get_instance,
 	.init_hfi_command_ops =3D iris_hfi_gen2_command_ops_init,
@@ -233,4 +245,9 @@ struct iris_platform_data sm8550_data =3D {
 	.dec_input_prop_size =3D ARRAY_SIZE(sm8550_vdec_subscribe_input_propertie=
s),
 	.dec_output_prop =3D sm8550_vdec_subscribe_output_properties,
 	.dec_output_prop_size =3D ARRAY_SIZE(sm8550_vdec_subscribe_output_propert=
ies),
+
+	.dec_ip_int_buf_tbl =3D sm8550_dec_ip_int_buf_tbl,
+	.dec_ip_int_buf_tbl_size =3D ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl),
+	.dec_op_int_buf_tbl =3D sm8550_dec_op_int_buf_tbl,
+	.dec_op_int_buf_tbl_size =3D ARRAY_SIZE(sm8550_dec_op_int_buf_tbl),
 };
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/p=
latform/qcom/iris/iris_vdec.c
index 13902f4e9724..8d489530da31 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.c
+++ b/drivers/media/platform/qcom/iris/iris_vdec.c
@@ -273,6 +273,24 @@ int iris_vdec_streamon_input(struct iris_inst *inst)
 	if (ret)
 		return ret;
=20
+	ret =3D iris_alloc_and_queue_persist_bufs(inst);
+	if (ret)
+		return ret;
+
+	iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+
+	ret =3D iris_destroy_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MP=
LANE);
+	if (ret)
+		return ret;
+
+	ret =3D iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPL=
ANE);
+	if (ret)
+		return ret;
+
+	ret =3D iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLA=
NE);
+	if (ret)
+		return ret;
+
 	return iris_vdec_process_streamon_input(inst);
 }
=20
@@ -297,10 +315,24 @@ int iris_vdec_streamon_output(struct iris_inst *inst)
 	if (ret)
 		return ret;
=20
+	iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+
+	ret =3D iris_destroy_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_M=
PLANE);
+	if (ret)
+		return ret;
+
+	ret =3D iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MP=
LANE);
+	if (ret)
+		return ret;
+
 	ret =3D iris_vdec_process_streamon_output(inst);
 	if (ret)
 		goto error;
=20
+	ret =3D iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPL=
ANE);
+	if (ret)
+		goto error;
+
 	return ret;
=20
 error:
diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/p=
latform/qcom/iris/iris_vidc.c
index 1d10c430c795..ec5694c1c8de 100644
--- a/drivers/media/platform/qcom/iris/iris_vidc.c
+++ b/drivers/media/platform/qcom/iris/iris_vidc.c
@@ -149,6 +149,15 @@ int iris_open(struct file *filp)
=20
 	mutex_init(&inst->lock);
 	mutex_init(&inst->ctx_q_lock);
+
+	INIT_LIST_HEAD(&inst->buffers[BUF_BIN].list);
+	INIT_LIST_HEAD(&inst->buffers[BUF_ARP].list);
+	INIT_LIST_HEAD(&inst->buffers[BUF_COMV].list);
+	INIT_LIST_HEAD(&inst->buffers[BUF_NON_COMV].list);
+	INIT_LIST_HEAD(&inst->buffers[BUF_LINE].list);
+	INIT_LIST_HEAD(&inst->buffers[BUF_DPB].list);
+	INIT_LIST_HEAD(&inst->buffers[BUF_PERSIST].list);
+	INIT_LIST_HEAD(&inst->buffers[BUF_SCRATCH_1].list);
 	init_completion(&inst->completion);
 	init_completion(&inst->flush_completion);
=20
@@ -221,6 +230,8 @@ int iris_close(struct file *filp)
 	iris_session_close(inst);
 	iris_inst_change_state(inst, IRIS_INST_DEINIT);
 	iris_v4l2_fh_deinit(inst);
+	iris_destroy_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+	iris_destroy_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
 	iris_remove_session(inst);
 	mutex_unlock(&inst->lock);
 	mutex_destroy(&inst->ctx_q_lock);
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c b/drivers/m=
edia/platform/qcom/iris/iris_vpu_buffer.c
index 0a65a17f13d2..dce25e410d80 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
@@ -6,7 +6,167 @@
 #include "iris_instance.h"
 #include "iris_vpu_buffer.h"
=20
-u32 iris_vpu_dec_dpb_size(struct iris_inst *inst)
+static u32 size_h264d_hw_bin_buffer(u32 frame_width, u32 frame_height, u32=
 num_vpp_pipes)
+{
+	u32 size_yuv, size_bin_hdr, size_bin_res;
+
+	size_yuv =3D ((frame_width * frame_height) <=3D BIN_BUFFER_THRESHOLD) ?
+			((BIN_BUFFER_THRESHOLD * 3) >> 1) :
+			((frame_width * frame_height * 3) >> 1);
+	size_bin_hdr =3D size_yuv * H264_CABAC_HDR_RATIO_HD_TOT;
+	size_bin_res =3D size_yuv * H264_CABAC_RES_RATIO_HD_TOT;
+	size_bin_hdr =3D ALIGN(size_bin_hdr / num_vpp_pipes,
+			     DMA_ALIGNMENT) * num_vpp_pipes;
+	size_bin_res =3D ALIGN(size_bin_res / num_vpp_pipes,
+			     DMA_ALIGNMENT) * num_vpp_pipes;
+
+	return size_bin_hdr + size_bin_res;
+}
+
+static u32 hfi_buffer_bin_h264d(u32 frame_width, u32 frame_height, u32 num=
_vpp_pipes)
+{
+	u32 n_aligned_h =3D ALIGN(frame_height, 16);
+	u32 n_aligned_w =3D ALIGN(frame_width, 16);
+
+	return size_h264d_hw_bin_buffer(n_aligned_w, n_aligned_h, num_vpp_pipes);
+}
+
+static u32 hfi_buffer_comv_h264d(u32 frame_width, u32 frame_height, u32 _c=
omv_bufcount)
+{
+	u32 frame_height_in_mbs =3D DIV_ROUND_UP(frame_height, 16);
+	u32 frame_width_in_mbs =3D DIV_ROUND_UP(frame_width, 16);
+	u32 col_zero_aligned_width =3D (frame_width_in_mbs << 2);
+	u32 col_mv_aligned_width =3D (frame_width_in_mbs << 7);
+	u32 col_zero_size, size_colloc;
+
+	col_mv_aligned_width =3D ALIGN(col_mv_aligned_width, 16);
+	col_zero_aligned_width =3D ALIGN(col_zero_aligned_width, 16);
+	col_zero_size =3D col_zero_aligned_width *
+			((frame_height_in_mbs + 1) >> 1);
+	col_zero_size =3D ALIGN(col_zero_size, 64);
+	col_zero_size <<=3D 1;
+	col_zero_size =3D ALIGN(col_zero_size, 512);
+	size_colloc =3D col_mv_aligned_width * ((frame_height_in_mbs + 1) >> 1);
+	size_colloc =3D ALIGN(size_colloc, 64);
+	size_colloc <<=3D 1;
+	size_colloc =3D ALIGN(size_colloc, 512);
+	size_colloc +=3D (col_zero_size + SIZE_H264D_BUFTAB_T * 2);
+
+	return (size_colloc * (_comv_bufcount)) + 512;
+}
+
+static u32 size_h264d_bse_cmd_buf(u32 frame_height)
+{
+	u32 height =3D ALIGN(frame_height, 32);
+
+	return min_t(u32, (DIV_ROUND_UP(height, 16) * 48), H264D_MAX_SLICE) *
+		SIZE_H264D_BSE_CMD_PER_BUF;
+}
+
+static u32 size_h264d_vpp_cmd_buf(u32 frame_height)
+{
+	u32 size, height =3D ALIGN(frame_height, 32);
+
+	size =3D min_t(u32, (DIV_ROUND_UP(height, 16) * 48), H264D_MAX_SLICE) *
+			SIZE_H264D_VPP_CMD_PER_BUF;
+
+	return size > VPP_CMD_MAX_SIZE ? VPP_CMD_MAX_SIZE : size;
+}
+
+static u32 hfi_buffer_persist_h264d(void)
+{
+	return ALIGN(SIZE_SLIST_BUF_H264 * NUM_SLIST_BUF_H264 +
+		    H264_DISPLAY_BUF_SIZE * H264_NUM_FRM_INFO +
+		    NUM_HW_PIC_BUF * SIZE_SEI_USERDATA,
+		    DMA_ALIGNMENT);
+}
+
+static u32 hfi_buffer_non_comv_h264d(u32 frame_width, u32 frame_height, u3=
2 num_vpp_pipes)
+{
+	u32 size_bse, size_vpp, size;
+
+	size_bse =3D size_h264d_bse_cmd_buf(frame_height);
+	size_vpp =3D size_h264d_vpp_cmd_buf(frame_height);
+	size =3D ALIGN(size_bse, DMA_ALIGNMENT) +
+		ALIGN(size_vpp, DMA_ALIGNMENT) +
+		ALIGN(SIZE_HW_PIC(SIZE_H264D_HW_PIC_T), DMA_ALIGNMENT);
+
+	return ALIGN(size, DMA_ALIGNMENT);
+}
+
+static u32 size_vpss_lb(u32 frame_width, u32 frame_height)
+{
+	u32 opb_lb_wr_llb_y_buffer_size, opb_lb_wr_llb_uv_buffer_size;
+	u32 opb_wr_top_line_chroma_buffer_size;
+	u32 opb_wr_top_line_luma_buffer_size;
+	u32 macrotiling_size =3D 32;
+
+	opb_wr_top_line_luma_buffer_size =3D
+		ALIGN(frame_width, macrotiling_size) / macrotiling_size * 256;
+	opb_wr_top_line_luma_buffer_size =3D
+		ALIGN(opb_wr_top_line_luma_buffer_size, DMA_ALIGNMENT) +
+		(MAX_TILE_COLUMNS - 1) * 256;
+	opb_wr_top_line_luma_buffer_size =3D
+		max_t(u32, opb_wr_top_line_luma_buffer_size, (32 * ALIGN(frame_height, 8=
)));
+	opb_wr_top_line_chroma_buffer_size =3D opb_wr_top_line_luma_buffer_size;
+	opb_lb_wr_llb_uv_buffer_size =3D
+		ALIGN((ALIGN(frame_height, 8) / (4 / 2)) * 64, 32);
+	opb_lb_wr_llb_y_buffer_size =3D
+		ALIGN((ALIGN(frame_height, 8) / (4 / 2)) * 64, 32);
+	return opb_wr_top_line_luma_buffer_size +
+		opb_wr_top_line_chroma_buffer_size +
+		opb_lb_wr_llb_uv_buffer_size +
+		opb_lb_wr_llb_y_buffer_size;
+}
+
+static u32 hfi_buffer_line_h264d(u32 frame_width, u32 frame_height,
+				 bool is_opb, u32 num_vpp_pipes)
+{
+	u32 vpss_lb_size =3D 0;
+	u32 size;
+
+	size =3D ALIGN(size_h264d_lb_fe_top_data(frame_width), DMA_ALIGNMENT) +
+		ALIGN(size_h264d_lb_fe_top_ctrl(frame_width), DMA_ALIGNMENT) +
+		ALIGN(size_h264d_lb_fe_left_ctrl(frame_height), DMA_ALIGNMENT) * num_vpp=
_pipes +
+		ALIGN(size_h264d_lb_se_top_ctrl(frame_width), DMA_ALIGNMENT) +
+		ALIGN(size_h264d_lb_se_left_ctrl(frame_height), DMA_ALIGNMENT) * num_vpp=
_pipes +
+		ALIGN(size_h264d_lb_pe_top_data(frame_width), DMA_ALIGNMENT) +
+		ALIGN(size_h264d_lb_vsp_top(frame_width), DMA_ALIGNMENT) +
+		ALIGN(size_h264d_lb_recon_dma_metadata_wr(frame_height), DMA_ALIGNMENT) =
* 2 +
+		ALIGN(size_h264d_qp(frame_width, frame_height), DMA_ALIGNMENT);
+	size =3D ALIGN(size, DMA_ALIGNMENT);
+	if (is_opb)
+		vpss_lb_size =3D size_vpss_lb(frame_width, frame_height);
+
+	return ALIGN((size + vpss_lb_size), DMA_ALIGNMENT);
+}
+
+static u32 iris_vpu_dec_bin_size(struct iris_inst *inst)
+{
+	u32 num_vpp_pipes =3D inst->core->iris_platform_data->num_vpp_pipe;
+	struct v4l2_format *f =3D inst->fmt_src;
+	u32 height =3D f->fmt.pix_mp.height;
+	u32 width =3D f->fmt.pix_mp.width;
+
+	return hfi_buffer_bin_h264d(width, height, num_vpp_pipes);
+}
+
+static u32 iris_vpu_dec_comv_size(struct iris_inst *inst)
+{
+	u32 num_comv =3D VIDEO_MAX_FRAME;
+	struct v4l2_format *f =3D inst->fmt_src;
+	u32 height =3D f->fmt.pix_mp.height;
+	u32 width =3D f->fmt.pix_mp.width;
+
+	return hfi_buffer_comv_h264d(width, height, num_comv);
+}
+
+static u32 iris_vpu_dec_persist_size(struct iris_inst *inst)
+{
+	return hfi_buffer_persist_h264d();
+}
+
+static u32 iris_vpu_dec_dpb_size(struct iris_inst *inst)
 {
 	if (iris_split_mode_enabled(inst))
 		return iris_get_buffer_size(inst, BUF_DPB);
@@ -14,6 +174,70 @@ u32 iris_vpu_dec_dpb_size(struct iris_inst *inst)
 		return 0;
 }
=20
+static u32 iris_vpu_dec_non_comv_size(struct iris_inst *inst)
+{
+	u32 num_vpp_pipes =3D inst->core->iris_platform_data->num_vpp_pipe;
+	struct v4l2_format *f =3D inst->fmt_src;
+	u32 height =3D f->fmt.pix_mp.height;
+	u32 width =3D f->fmt.pix_mp.width;
+
+	return hfi_buffer_non_comv_h264d(width, height, num_vpp_pipes);
+}
+
+static u32 iris_vpu_dec_line_size(struct iris_inst *inst)
+{
+	u32 num_vpp_pipes =3D inst->core->iris_platform_data->num_vpp_pipe;
+	struct v4l2_format *f =3D inst->fmt_src;
+	u32 height =3D f->fmt.pix_mp.height;
+	u32 width =3D f->fmt.pix_mp.width;
+	bool is_opb =3D false;
+
+	if (iris_split_mode_enabled(inst))
+		is_opb =3D true;
+
+	return hfi_buffer_line_h264d(width, height, is_opb, num_vpp_pipes);
+}
+
+static u32 iris_vpu_dec_scratch1_size(struct iris_inst *inst)
+{
+	return iris_vpu_dec_comv_size(inst) +
+		iris_vpu_dec_non_comv_size(inst) +
+		iris_vpu_dec_line_size(inst);
+}
+
+struct iris_vpu_buf_type_handle {
+	enum iris_buffer_type type;
+	u32 (*handle)(struct iris_inst *inst);
+};
+
+int iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer=
_type)
+{
+	const struct iris_vpu_buf_type_handle *buf_type_handle_arr;
+	u32 size =3D 0, buf_type_handle_size, i;
+
+	static const struct iris_vpu_buf_type_handle dec_internal_buf_type_handle=
[] =3D {
+		{BUF_BIN,         iris_vpu_dec_bin_size             },
+		{BUF_COMV,        iris_vpu_dec_comv_size            },
+		{BUF_NON_COMV,    iris_vpu_dec_non_comv_size        },
+		{BUF_LINE,        iris_vpu_dec_line_size            },
+		{BUF_PERSIST,     iris_vpu_dec_persist_size         },
+		{BUF_DPB,         iris_vpu_dec_dpb_size             },
+		{BUF_SCRATCH_1,   iris_vpu_dec_scratch1_size        },
+	};
+
+	buf_type_handle_size =3D ARRAY_SIZE(dec_internal_buf_type_handle);
+	buf_type_handle_arr =3D dec_internal_buf_type_handle;
+
+	for (i =3D 0; i < buf_type_handle_size; i++) {
+		if (buf_type_handle_arr[i].type =3D=3D buffer_type) {
+			size =3D buf_type_handle_arr[i].handle(inst);
+			break;
+		}
+	}
+
+	return size;
+}
+
 static inline int iris_vpu_dpb_count(struct iris_inst *inst)
 {
 	if (iris_split_mode_enabled(inst)) {
@@ -31,6 +255,13 @@ int iris_vpu_buf_count(struct iris_inst *inst, enum iri=
s_buffer_type buffer_type
 		return MIN_BUFFERS;
 	case BUF_OUTPUT:
 		return inst->fw_min_count;
+	case BUF_BIN:
+	case BUF_COMV:
+	case BUF_NON_COMV:
+	case BUF_LINE:
+	case BUF_PERSIST:
+	case BUF_SCRATCH_1:
+		return 1; /* internal buffer count needed by firmware is 1 */
 	case BUF_DPB:
 		return iris_vpu_dpb_count(inst);
 	default:
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h b/drivers/m=
edia/platform/qcom/iris/iris_vpu_buffer.h
index 865539d626b7..62af6ea6ba1f 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
@@ -10,7 +10,82 @@ struct iris_inst;
=20
 #define MIN_BUFFERS			4
=20
-u32 iris_vpu_dec_dpb_size(struct iris_inst *inst);
+#define DMA_ALIGNMENT			256
+
+#define NUM_HW_PIC_BUF			32
+#define SIZE_HW_PIC(size_per_buf)	(NUM_HW_PIC_BUF * (size_per_buf))
+
+#define MAX_TILE_COLUMNS		32
+#define BIN_BUFFER_THRESHOLD		(1280 * 736)
+#define VPP_CMD_MAX_SIZE		(BIT(20))
+#define H264D_MAX_SLICE			1800
+
+#define SIZE_H264D_BUFTAB_T		256
+#define SIZE_H264D_BSE_CMD_PER_BUF	(32 * 4)
+#define SIZE_H264D_VPP_CMD_PER_BUF	512
+
+#define NUM_SLIST_BUF_H264		(256 + 32)
+#define SIZE_SLIST_BUF_H264		512
+#define H264_DISPLAY_BUF_SIZE		3328
+#define H264_NUM_FRM_INFO		66
+
+#define SIZE_SEI_USERDATA		4096
+
+#define H264_CABAC_HDR_RATIO_HD_TOT	1
+#define H264_CABAC_RES_RATIO_HD_TOT	3
+#define SIZE_H264D_HW_PIC_T		(BIT(11))
+
+#define MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE	64
+#define MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE	16
+#define MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE	384
+#define MAX_FE_NBR_DATA_LUMA_LINE_BUFFER_SIZE	640
+
+static inline u32 size_h264d_lb_fe_top_data(u32 frame_width)
+{
+	return MAX_FE_NBR_DATA_LUMA_LINE_BUFFER_SIZE * ALIGN(frame_width, 16) * 3;
+}
+
+static inline u32 size_h264d_lb_fe_top_ctrl(u32 frame_width)
+{
+	return MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * DIV_ROUND_UP(frame_width,=
 16);
+}
+
+static inline u32 size_h264d_lb_fe_left_ctrl(u32 frame_height)
+{
+	return MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * DIV_ROUND_UP(frame_height=
, 16);
+}
+
+static inline u32 size_h264d_lb_se_top_ctrl(u32 frame_width)
+{
+	return MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * DIV_ROUND_UP(frame_width,=
 16);
+}
+
+static inline u32 size_h264d_lb_se_left_ctrl(u32 frame_height)
+{
+	return MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * DIV_ROUND_UP(frame_height=
, 16);
+}
+
+static inline u32 size_h264d_lb_pe_top_data(u32 frame_width)
+{
+	return MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE * DIV_ROUND_UP(frame_width,=
 16);
+}
+
+static inline u32 size_h264d_lb_vsp_top(u32 frame_width)
+{
+	return (DIV_ROUND_UP(frame_width, 16) << 7);
+}
+
+static inline u32 size_h264d_lb_recon_dma_metadata_wr(u32 frame_height)
+{
+	return ALIGN(frame_height, 16) * 32;
+}
+
+static inline u32 size_h264d_qp(u32 frame_width, u32 frame_height)
+{
+	return DIV_ROUND_UP(frame_width, 64) * DIV_ROUND_UP(frame_height, 64) * 1=
28;
+}
+
+int iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer=
_type);
 int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffe=
r_type);
=20
 #endif

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 1CCEF234978;
	Fri,  7 Feb 2025 07:57:33 +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=1738915057; cv=none;
 b=H0U+UVrq0VHHcRDLTUyTXee3pFFWpw3xJhFSSrK4Xec92o7BpXTUeuwCx6BIY4w/xITgQDw7SgI7N2EzWt5XQ5wG7CgXGI8QyGi6TM0JRtDN1eOgX2zMlnuQfTt5/E7AayQZdd3uUl+oe1EUChM2G9jN0ggZFyTlGgYP1fgAgg0=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738915057; c=relaxed/simple;
	bh=7/mRLRPRNlVQD5F/PytEpKi1Om1XNrHR262VKqzA5Yo=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=oIyYDqdJZajNQ4GtW5GVtBzEf4l5Ht2vC/LtUPP4hsYcyXcF7ZRucF7O99RBRGylB9cmo37KD6IXXscZc3s9Qx1Ue7CMXz6wYeSFFLmSlBxBqsy6P5kbOG4rPciahMEU0j8lJheiNaCdDeOAkeRvlh02SovzCBZ5YN6b58PTbsk=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=Y9IqE7an; arc=none smtp.client-ip=205.220.168.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="Y9IqE7an"
Received: from pps.filterd (m0279867.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 51770SsK029978;
	Fri, 7 Feb 2025 07:57:15 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	59JxRy/yqFM18n44OFQXEz2guR7+1bgqsm4TP0sv1hU=; b=Y9IqE7anU3DuWd1C
	FGY+FSEbsvTzAR+UE39K3CSkxTxWgGf+KtAioxqSUw8EMJbfY/P2GB8BAuOQJQ3n
	xWAkZnVBgvBPgTbY3IMEWm4FI56wNE0UreMVDl8/RVLp5jS1/s8AxXrIaCW87k1F
	lHf6XSV4+5DseAIwIKpvMq0IsARjJ1TzM0otfp5LYhi9GJpvoM/02bFBR8RFWtfS
	YeAiEcJG2187FUeVs5WunLFYLygp91YSaku9m50PiskxnUd0oYRA8yjtWKZVZcm4
	HZKOvs2tet2lF1iffBlWgvMVr20THkA3xDCOvsQqxlBPM/gFELio2E1x6w1TYHYo
	oCyb2A==
Received: from nalasppmta03.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44nddjg4a1-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:57:15 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA03.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177vCm4030574
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:57:12 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:57:06 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:25:00 +0530
Subject: [PATCH v10 20/28] media: iris: implement vb2 ops for buf_queue and
 firmware response
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-20-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914893; l=48179;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=7/mRLRPRNlVQD5F/PytEpKi1Om1XNrHR262VKqzA5Yo=;
 b=9wdL1iSNM1Y7skTWaBo4P8WmkuBYaMWqG+YDzsGJ6c5qK44M6TgbkhWINZKO4XYFMpq3/NeeE
 n0zXrUQFTx2CPSBtp2bHagdIv8dtI76m4Wdvj+V/m+2WWJnapul/6NN
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-ORIG-GUID: kTYDLG4mwj0Z1tJUkH7DECF1_OLKrsMy
X-Proofpoint-GUID: kTYDLG4mwj0Z1tJUkH7DECF1_OLKrsMy
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 mlxscore=0 impostorscore=0
 adultscore=0 bulkscore=0 phishscore=0 malwarescore=0 lowpriorityscore=0
 mlxlogscore=999 priorityscore=1501 clxscore=1015 suspectscore=0
 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070060

Implement the vb2 ops for the buf queue. These are the different buffer
attributes:
BUF_ATTR_DEFERRED - buffer queued by the client but not submitted to
                    firmware.
BUF_ATTR_PENDING_RELEASE - buffers requested to be released from
                           the firmware.
BUF_ATTR_QUEUED - buffers submitted to the firmware.
BUF_ATTR_DEQUEUED - buffers received from the firmware.
BUF_ATTR_BUFFER_DONE - buffers sent back to vb2.

Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl>
Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 drivers/media/platform/qcom/iris/Kconfig           |   1 +
 drivers/media/platform/qcom/iris/iris_buffer.c     | 116 +++++++++++++
 drivers/media/platform/qcom/iris/iris_buffer.h     |   2 +
 .../platform/qcom/iris/iris_hfi_gen1_command.c     |  53 ++++++
 .../platform/qcom/iris/iris_hfi_gen1_defines.h     |  80 +++++++++
 .../platform/qcom/iris/iris_hfi_gen1_response.c    | 167 +++++++++++++++++=
+-
 drivers/media/platform/qcom/iris/iris_hfi_gen2.h   |   2 +
 .../platform/qcom/iris/iris_hfi_gen2_defines.h     |  22 +++
 .../platform/qcom/iris/iris_hfi_gen2_response.c    | 183 +++++++++++++++++=
+++-
 drivers/media/platform/qcom/iris/iris_instance.h   |   8 +
 drivers/media/platform/qcom/iris/iris_utils.c      |  16 ++
 drivers/media/platform/qcom/iris/iris_utils.h      |  16 ++
 drivers/media/platform/qcom/iris/iris_vb2.c        |  98 ++++++++++-
 drivers/media/platform/qcom/iris/iris_vb2.h        |   4 +
 drivers/media/platform/qcom/iris/iris_vdec.c       | 151 ++++++++++++++++-
 drivers/media/platform/qcom/iris/iris_vdec.h       |   3 +-
 drivers/media/platform/qcom/iris/iris_vidc.c       |  14 ++
 17 files changed, 916 insertions(+), 20 deletions(-)

diff --git a/drivers/media/platform/qcom/iris/Kconfig b/drivers/media/platf=
orm/qcom/iris/Kconfig
index f92cc7fe9378..3c803a05305a 100644
--- a/drivers/media/platform/qcom/iris/Kconfig
+++ b/drivers/media/platform/qcom/iris/Kconfig
@@ -5,6 +5,7 @@ config VIDEO_QCOM_IRIS
         select V4L2_MEM2MEM_DEV
         select QCOM_MDT_LOADER if ARCH_QCOM
         select QCOM_SCM
+        select VIDEOBUF2_DMA_CONTIG
         help
           This is a V4L2 driver for Qualcomm iris video accelerator
           hardware. It accelerates decoding operations on various
diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media=
/platform/qcom/iris/iris_buffer.c
index e9d372580b5f..de1267c387f1 100644
--- a/drivers/media/platform/qcom/iris/iris_buffer.c
+++ b/drivers/media/platform/qcom/iris/iris_buffer.c
@@ -3,6 +3,7 @@
  * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
  */
=20
+#include <media/v4l2-event.h>
 #include <media/v4l2-mem2mem.h>
=20
 #include "iris_buffer.h"
@@ -434,6 +435,36 @@ int iris_alloc_and_queue_persist_bufs(struct iris_inst=
 *inst)
 	return 0;
 }
=20
+int iris_queue_deferred_buffers(struct iris_inst *inst, enum iris_buffer_t=
ype buf_type)
+{
+	struct v4l2_m2m_ctx *m2m_ctx =3D inst->m2m_ctx;
+	struct v4l2_m2m_buffer *buffer, *n;
+	struct iris_buffer *buf;
+	int ret;
+
+	if (buf_type =3D=3D BUF_INPUT) {
+		v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buffer, n) {
+			buf =3D to_iris_buffer(&buffer->vb);
+			if (!(buf->attr & BUF_ATTR_DEFERRED))
+				continue;
+			ret =3D iris_queue_buffer(inst, buf);
+			if (ret)
+				return ret;
+		}
+	} else {
+		v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buffer, n) {
+			buf =3D to_iris_buffer(&buffer->vb);
+			if (!(buf->attr & BUF_ATTR_DEFERRED))
+				continue;
+			ret =3D iris_queue_buffer(inst, buf);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
 void iris_vb2_queue_error(struct iris_inst *inst)
 {
 	struct v4l2_m2m_ctx *m2m_ctx =3D inst->m2m_ctx;
@@ -444,3 +475,88 @@ void iris_vb2_queue_error(struct iris_inst *inst)
 	q =3D v4l2_m2m_get_dst_vq(m2m_ctx);
 	vb2_queue_error(q);
 }
+
+static struct vb2_v4l2_buffer *
+iris_helper_find_buf(struct iris_inst *inst, u32 type, u32 idx)
+{
+	struct v4l2_m2m_ctx *m2m_ctx =3D inst->m2m_ctx;
+
+	if (V4L2_TYPE_IS_OUTPUT(type))
+		return v4l2_m2m_src_buf_remove_by_idx(m2m_ctx, idx);
+	else
+		return v4l2_m2m_dst_buf_remove_by_idx(m2m_ctx, idx);
+}
+
+static void iris_get_ts_metadata(struct iris_inst *inst, u64 timestamp_ns,
+				 struct vb2_v4l2_buffer *vbuf)
+{
+	u32 mask =3D V4L2_BUF_FLAG_TIMECODE | V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+	u32 i;
+
+	for (i =3D 0; i < ARRAY_SIZE(inst->tss); ++i) {
+		if (inst->tss[i].ts_ns !=3D timestamp_ns)
+			continue;
+
+		vbuf->flags &=3D ~mask;
+		vbuf->flags |=3D inst->tss[i].flags;
+		vbuf->timecode =3D inst->tss[i].tc;
+		return;
+	}
+
+	vbuf->flags &=3D ~mask;
+	vbuf->flags |=3D inst->tss[inst->metadata_idx].flags;
+	vbuf->timecode =3D inst->tss[inst->metadata_idx].tc;
+}
+
+int iris_vb2_buffer_done(struct iris_inst *inst, struct iris_buffer *buf)
+{
+	struct v4l2_m2m_ctx *m2m_ctx =3D inst->m2m_ctx;
+	struct vb2_v4l2_buffer *vbuf;
+	struct vb2_buffer *vb2;
+	u32 type, state;
+
+	switch (buf->type) {
+	case BUF_INPUT:
+		type =3D V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+		break;
+	case BUF_OUTPUT:
+		type =3D V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+		break;
+	default:
+		return 0; /* Internal DPB Buffers */
+	}
+
+	vbuf =3D iris_helper_find_buf(inst, type, buf->index);
+	if (!vbuf)
+		return -EINVAL;
+
+	vb2 =3D &vbuf->vb2_buf;
+
+	if (buf->flags & V4L2_BUF_FLAG_ERROR)
+		state =3D VB2_BUF_STATE_ERROR;
+	else
+		state =3D VB2_BUF_STATE_DONE;
+
+	vbuf->flags |=3D buf->flags;
+
+	if (V4L2_TYPE_IS_CAPTURE(type)) {
+		vb2_set_plane_payload(vb2, 0, buf->data_size);
+		vbuf->sequence =3D inst->sequence_cap++;
+		iris_get_ts_metadata(inst, buf->timestamp, vbuf);
+	} else {
+		vbuf->sequence =3D inst->sequence_out++;
+	}
+
+	if (vbuf->flags & V4L2_BUF_FLAG_LAST) {
+		if (!v4l2_m2m_has_stopped(m2m_ctx)) {
+			const struct v4l2_event ev =3D { .type =3D V4L2_EVENT_EOS };
+
+			v4l2_event_queue_fh(&inst->fh, &ev);
+			v4l2_m2m_mark_stopped(m2m_ctx);
+		}
+	}
+	vb2->timestamp =3D buf->timestamp;
+	v4l2_m2m_buf_done(vbuf, state);
+
+	return 0;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_buffer.h b/drivers/media=
/platform/qcom/iris/iris_buffer.h
index 73f3a16ff7a2..2c7432a59906 100644
--- a/drivers/media/platform/qcom/iris/iris_buffer.h
+++ b/drivers/media/platform/qcom/iris/iris_buffer.h
@@ -109,6 +109,8 @@ int iris_destroy_internal_buffer(struct iris_inst *inst=
, struct iris_buffer *buf
 int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane);
 int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst);
 int iris_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf);
+int iris_queue_deferred_buffers(struct iris_inst *inst, enum iris_buffer_t=
ype buf_type);
+int iris_vb2_buffer_done(struct iris_inst *inst, struct iris_buffer *buf);
 void iris_vb2_queue_error(struct iris_inst *inst);
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen1_command.c
index 603ca485992d..03f7e6ea4bf3 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
@@ -180,6 +180,10 @@ static int iris_hfi_gen1_session_stop(struct iris_inst=
 *inst, u32 plane)
 		ret =3D iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size);
 		if (!ret)
 			ret =3D iris_wait_for_session_response(inst, false);
+		iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+					 VB2_BUF_STATE_ERROR);
+		iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+					 VB2_BUF_STATE_ERROR);
 	} else if (inst->state =3D=3D IRIS_INST_STREAMING) {
 		if (V4L2_TYPE_IS_OUTPUT(plane))
 			flush_type =3D HFI_FLUSH_ALL;
@@ -201,6 +205,50 @@ static int iris_hfi_gen1_session_stop(struct iris_inst=
 *inst, u32 plane)
 	return ret;
 }
=20
+static int iris_hfi_gen1_queue_input_buffer(struct iris_inst *inst, struct=
 iris_buffer *buf)
+{
+	struct hfi_session_empty_buffer_compressed_pkt ip_pkt;
+
+	ip_pkt.shdr.hdr.size =3D sizeof(struct hfi_session_empty_buffer_compresse=
d_pkt);
+	ip_pkt.shdr.hdr.pkt_type =3D HFI_CMD_SESSION_EMPTY_BUFFER;
+	ip_pkt.shdr.session_id =3D inst->session_id;
+	ip_pkt.time_stamp_hi =3D upper_32_bits(buf->timestamp);
+	ip_pkt.time_stamp_lo =3D lower_32_bits(buf->timestamp);
+	ip_pkt.flags =3D buf->flags;
+	ip_pkt.mark_target =3D 0;
+	ip_pkt.mark_data =3D 0;
+	ip_pkt.offset =3D buf->data_offset;
+	ip_pkt.alloc_len =3D buf->buffer_size;
+	ip_pkt.filled_len =3D buf->data_size;
+	ip_pkt.input_tag =3D buf->index;
+	ip_pkt.packet_buffer =3D buf->device_addr;
+
+	return iris_hfi_queue_cmd_write(inst->core, &ip_pkt, ip_pkt.shdr.hdr.size=
);
+}
+
+static int iris_hfi_gen1_queue_output_buffer(struct iris_inst *inst, struc=
t iris_buffer *buf)
+{
+	struct hfi_session_fill_buffer_pkt op_pkt;
+
+	op_pkt.shdr.hdr.size =3D sizeof(struct hfi_session_fill_buffer_pkt);
+	op_pkt.shdr.hdr.pkt_type =3D HFI_CMD_SESSION_FILL_BUFFER;
+	op_pkt.shdr.session_id =3D inst->session_id;
+	op_pkt.output_tag =3D buf->index;
+	op_pkt.packet_buffer =3D buf->device_addr;
+	op_pkt.extradata_buffer =3D 0;
+	op_pkt.alloc_len =3D buf->buffer_size;
+	op_pkt.filled_len =3D buf->data_size;
+	op_pkt.offset =3D buf->data_offset;
+	op_pkt.data =3D 0;
+
+	if (buf->type =3D=3D BUF_OUTPUT && iris_split_mode_enabled(inst))
+		op_pkt.stream_id =3D 1;
+	else
+		op_pkt.stream_id =3D 0;
+
+	return iris_hfi_queue_cmd_write(inst->core, &op_pkt, op_pkt.shdr.hdr.size=
);
+}
+
 static int iris_hfi_gen1_queue_internal_buffer(struct iris_inst *inst, str=
uct iris_buffer *buf)
 {
 	struct hfi_session_set_buffers_pkt *int_pkt;
@@ -240,6 +288,11 @@ static int iris_hfi_gen1_queue_internal_buffer(struct =
iris_inst *inst, struct ir
 static int iris_hfi_gen1_session_queue_buffer(struct iris_inst *inst, stru=
ct iris_buffer *buf)
 {
 	switch (buf->type) {
+	case BUF_INPUT:
+		return iris_hfi_gen1_queue_input_buffer(inst, buf);
+	case BUF_OUTPUT:
+	case BUF_DPB:
+		return iris_hfi_gen1_queue_output_buffer(inst, buf);
 	case BUF_PERSIST:
 	case BUF_BIN:
 	case BUF_SCRATCH_1:
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
index cabd91eafc92..108449d703e1 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
@@ -29,11 +29,14 @@
 #define HFI_CMD_SESSION_LOAD_RESOURCES			0x211001
 #define HFI_CMD_SESSION_START				0x211002
 #define HFI_CMD_SESSION_STOP				0x211003
+#define HFI_CMD_SESSION_EMPTY_BUFFER			0x211004
+#define HFI_CMD_SESSION_FILL_BUFFER			0x211005
 #define HFI_CMD_SESSION_FLUSH				0x211008
 #define HFI_CMD_SESSION_RELEASE_BUFFERS			0x21100b
 #define HFI_CMD_SESSION_RELEASE_RESOURCES		0x21100c
=20
 #define HFI_ERR_SESSION_UNSUPPORTED_SETTING		0x1008
+#define HFI_ERR_SESSION_UNSUPPORTED_STREAM		0x100d
 #define HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE		0x1010
 #define HFI_ERR_SESSION_INVALID_SCALE_FACTOR		0x1012
 #define HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED		0x1013
@@ -41,6 +44,8 @@
 #define HFI_EVENT_SYS_ERROR				0x1
 #define HFI_EVENT_SESSION_ERROR				0x2
=20
+#define HFI_BUFFERFLAG_TIMESTAMPINVALID			0x00000100
+
 #define HFI_FLUSH_OUTPUT				0x1000002
 #define HFI_FLUSH_OUTPUT2				0x1000003
 #define HFI_FLUSH_ALL					0x1000004
@@ -84,9 +89,19 @@
 #define HFI_MSG_SESSION_START				0x221002
 #define HFI_MSG_SESSION_STOP				0x221003
 #define HFI_MSG_SESSION_FLUSH				0x221006
+#define HFI_MSG_SESSION_EMPTY_BUFFER			0x221007
+#define HFI_MSG_SESSION_FILL_BUFFER			0x221008
 #define HFI_MSG_SESSION_RELEASE_RESOURCES		0x22100a
 #define HFI_MSG_SESSION_RELEASE_BUFFERS			0x22100c
=20
+#define HFI_PICTURE_I					0x00000001
+#define HFI_PICTURE_P					0x00000002
+#define HFI_PICTURE_B					0x00000004
+#define HFI_PICTURE_IDR					0x00000008
+#define HFI_FRAME_NOTCODED				0x7f002000
+#define HFI_FRAME_YUV					0x7f004000
+#define HFI_UNUSED_PICT					0x10000000
+
 struct hfi_pkt_hdr {
 	u32 size;
 	u32 pkt_type;
@@ -144,6 +159,34 @@ struct hfi_session_set_buffers_pkt {
 	u32 buffer_info[];
 };
=20
+struct hfi_session_empty_buffer_compressed_pkt {
+	struct hfi_session_hdr_pkt shdr;
+	u32 time_stamp_hi;
+	u32 time_stamp_lo;
+	u32 flags;
+	u32 mark_target;
+	u32 mark_data;
+	u32 offset;
+	u32 alloc_len;
+	u32 filled_len;
+	u32 input_tag;
+	u32 packet_buffer;
+	u32 extradata_buffer;
+	u32 data;
+};
+
+struct hfi_session_fill_buffer_pkt {
+	struct hfi_session_hdr_pkt shdr;
+	u32 stream_id;
+	u32 offset;
+	u32 alloc_len;
+	u32 filled_len;
+	u32 output_tag;
+	u32 packet_buffer;
+	u32 extradata_buffer;
+	u32 data;
+};
+
 struct hfi_session_flush_pkt {
 	struct hfi_session_hdr_pkt shdr;
 	u32 flush_type;
@@ -258,6 +301,43 @@ struct hfi_multi_stream {
 	u32 enable;
 };
=20
+struct hfi_msg_session_empty_buffer_done_pkt {
+	struct hfi_msg_session_hdr_pkt shdr;
+	u32 offset;
+	u32 filled_len;
+	u32 input_tag;
+	u32 packet_buffer;
+	u32 extradata_buffer;
+	u32 data[];
+};
+
+struct hfi_msg_session_fbd_uncompressed_plane0_pkt {
+	struct hfi_session_hdr_pkt shdr;
+	u32 stream_id;
+	u32 view_id;
+	u32 error_type;
+	u32 time_stamp_hi;
+	u32 time_stamp_lo;
+	u32 flags;
+	u32 mark_target;
+	u32 mark_data;
+	u32 stats;
+	u32 alloc_len;
+	u32 filled_len;
+	u32 offset;
+	u32 frame_width;
+	u32 frame_height;
+	u32 start_x_coord;
+	u32 start_y_coord;
+	u32 input_tag;
+	u32 input_tag2;
+	u32 output_tag;
+	u32 picture_type;
+	u32 packet_buffer;
+	u32 extradata_buffer;
+	u32 data[];
+};
+
 struct hfi_msg_session_release_buffers_done_pkt {
 	struct hfi_msg_session_hdr_pkt shdr;
 	u32 num_buffers;
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c b/dr=
ivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
index a84bb00388d9..23a8bf29e381 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
@@ -3,6 +3,8 @@
  * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
  */
=20
+#include <media/v4l2-mem2mem.h>
+
 #include "iris_hfi_gen1.h"
 #include "iris_hfi_gen1_defines.h"
 #include "iris_instance.h"
@@ -130,6 +132,143 @@ static void iris_hfi_gen1_sys_property_info(struct ir=
is_core *core, void *packet
 	}
 }
=20
+static void iris_hfi_gen1_session_etb_done(struct iris_inst *inst, void *p=
acket)
+{
+	struct hfi_msg_session_empty_buffer_done_pkt *pkt =3D packet;
+	struct v4l2_m2m_ctx *m2m_ctx =3D inst->m2m_ctx;
+	struct v4l2_m2m_buffer *m2m_buffer, *n;
+	struct iris_buffer *buf =3D NULL;
+	bool found =3D false;
+
+	v4l2_m2m_for_each_src_buf_safe(m2m_ctx, m2m_buffer, n) {
+		buf =3D to_iris_buffer(&m2m_buffer->vb);
+		if (buf->index =3D=3D pkt->input_tag) {
+			found =3D true;
+			break;
+		}
+	}
+	if (!found)
+		goto error;
+
+	if (pkt->shdr.error_type =3D=3D HFI_ERR_SESSION_UNSUPPORTED_STREAM) {
+		buf->flags =3D V4L2_BUF_FLAG_ERROR;
+		iris_vb2_queue_error(inst);
+		iris_inst_change_state(inst, IRIS_INST_ERROR);
+	}
+
+	if (!(buf->attr & BUF_ATTR_QUEUED))
+		return;
+
+	buf->attr &=3D ~BUF_ATTR_QUEUED;
+
+	if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) {
+		buf->attr |=3D BUF_ATTR_BUFFER_DONE;
+		iris_vb2_buffer_done(inst, buf);
+	}
+
+	return;
+
+error:
+	iris_inst_change_state(inst, IRIS_INST_ERROR);
+	dev_err(inst->core->dev, "error in etb done\n");
+}
+
+static void iris_hfi_gen1_session_ftb_done(struct iris_inst *inst, void *p=
acket)
+{
+	struct hfi_msg_session_fbd_uncompressed_plane0_pkt *pkt =3D packet;
+	struct v4l2_m2m_ctx *m2m_ctx =3D inst->m2m_ctx;
+	struct v4l2_m2m_buffer *m2m_buffer, *n;
+	u32 timestamp_hi =3D pkt->time_stamp_hi;
+	u32 timestamp_lo =3D pkt->time_stamp_lo;
+	struct iris_core *core =3D inst->core;
+	u32 filled_len =3D pkt->filled_len;
+	u32 pic_type =3D pkt->picture_type;
+	u32 output_tag =3D pkt->output_tag;
+	struct iris_buffer *buf, *iter;
+	struct iris_buffers *buffers;
+	u32 offset =3D pkt->offset;
+	u64 timestamp_us =3D 0;
+	bool found =3D false;
+	u32 flags =3D 0;
+
+	if (iris_split_mode_enabled(inst) && pkt->stream_id =3D=3D 0) {
+		buffers =3D &inst->buffers[BUF_DPB];
+		if (!buffers)
+			goto error;
+
+		found =3D false;
+		list_for_each_entry(iter, &buffers->list, list) {
+			if (!(iter->attr & BUF_ATTR_QUEUED))
+				continue;
+
+			found =3D (iter->index =3D=3D output_tag &&
+				iter->data_offset =3D=3D offset);
+
+			if (found) {
+				buf =3D iter;
+				break;
+			}
+		}
+	} else {
+		v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, m2m_buffer, n) {
+			buf =3D to_iris_buffer(&m2m_buffer->vb);
+			if (!(buf->attr & BUF_ATTR_QUEUED))
+				continue;
+
+			found =3D (buf->index =3D=3D output_tag &&
+				 buf->data_offset =3D=3D offset);
+
+			if (found)
+				break;
+		}
+	}
+	if (!found)
+		goto error;
+
+	buf->data_offset =3D offset;
+	buf->data_size =3D filled_len;
+
+	if (filled_len) {
+		timestamp_us =3D timestamp_hi;
+		timestamp_us =3D (timestamp_us << 32) | timestamp_lo;
+	} else {
+		flags |=3D V4L2_BUF_FLAG_LAST;
+	}
+	buf->timestamp =3D timestamp_us;
+
+	switch (pic_type) {
+	case HFI_PICTURE_IDR:
+	case HFI_PICTURE_I:
+		flags |=3D V4L2_BUF_FLAG_KEYFRAME;
+		break;
+	case HFI_PICTURE_P:
+		flags |=3D V4L2_BUF_FLAG_PFRAME;
+		break;
+	case HFI_PICTURE_B:
+		flags |=3D V4L2_BUF_FLAG_BFRAME;
+		break;
+	case HFI_FRAME_NOTCODED:
+	case HFI_UNUSED_PICT:
+	case HFI_FRAME_YUV:
+	default:
+		break;
+	}
+
+	buf->attr &=3D ~BUF_ATTR_QUEUED;
+	buf->attr |=3D BUF_ATTR_DEQUEUED;
+	buf->attr |=3D BUF_ATTR_BUFFER_DONE;
+
+	buf->flags |=3D flags;
+
+	iris_vb2_buffer_done(inst, buf);
+
+	return;
+
+error:
+	iris_inst_change_state(inst, IRIS_INST_ERROR);
+	dev_err(core->dev, "error in ftb done\n");
+}
+
 struct iris_hfi_gen1_response_pkt_info {
 	u32 pkt;
 	u32 pkt_sz;
@@ -168,6 +307,14 @@ static const struct iris_hfi_gen1_response_pkt_info pk=
t_infos[] =3D {
 	 .pkt =3D HFI_MSG_SESSION_STOP,
 	 .pkt_sz =3D sizeof(struct hfi_msg_session_hdr_pkt),
 	},
+	{
+	 .pkt =3D HFI_MSG_SESSION_EMPTY_BUFFER,
+	 .pkt_sz =3D sizeof(struct hfi_msg_session_empty_buffer_done_pkt),
+	},
+	{
+	 .pkt =3D HFI_MSG_SESSION_FILL_BUFFER,
+	 .pkt_sz =3D sizeof(struct hfi_msg_session_fbd_uncompressed_plane0_pkt),
+	},
 	{
 	 .pkt =3D HFI_MSG_SESSION_FLUSH,
 	 .pkt_sz =3D sizeof(struct hfi_msg_session_flush_done_pkt),
@@ -238,15 +385,21 @@ static void iris_hfi_gen1_handle_response(struct iris=
_core *core, void *response
 		}
=20
 		mutex_lock(&inst->lock);
-		struct hfi_msg_session_hdr_pkt *shdr;
+		if (hdr->pkt_type =3D=3D HFI_MSG_SESSION_EMPTY_BUFFER) {
+			iris_hfi_gen1_session_etb_done(inst, hdr);
+		} else if (hdr->pkt_type =3D=3D HFI_MSG_SESSION_FILL_BUFFER) {
+			iris_hfi_gen1_session_ftb_done(inst, hdr);
+		} else {
+			struct hfi_msg_session_hdr_pkt *shdr;
=20
-		shdr =3D (struct hfi_msg_session_hdr_pkt *)hdr;
-		if (shdr->error_type !=3D HFI_ERR_NONE)
-			iris_inst_change_state(inst, IRIS_INST_ERROR);
+			shdr =3D (struct hfi_msg_session_hdr_pkt *)hdr;
+			if (shdr->error_type !=3D HFI_ERR_NONE)
+				iris_inst_change_state(inst, IRIS_INST_ERROR);
=20
-		done =3D pkt_info->pkt =3D=3D HFI_MSG_SESSION_FLUSH ?
-			&inst->flush_completion : &inst->completion;
-		complete(done);
+			done =3D pkt_info->pkt =3D=3D HFI_MSG_SESSION_FLUSH ?
+				&inst->flush_completion : &inst->completion;
+			complete(done);
+		}
 		mutex_unlock(&inst->lock);
=20
 		break;
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h b/drivers/med=
ia/platform/qcom/iris/iris_hfi_gen2.h
index 0a946c1e3a4c..b9d3749a10ef 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h
@@ -20,6 +20,7 @@ struct iris_core;
  * @packet: HFI packet
  * @ipsc_properties_set: boolean to set ipsc properties to fw
  * @opsc_properties_set: boolean to set opsc properties to fw
+ * @hfi_frame_info: structure of frame info
  * @src_subcr_params: subscription params to fw on input port
  * @dst_subcr_params: subscription params to fw on output port
  */
@@ -28,6 +29,7 @@ struct iris_inst_hfi_gen2 {
 	struct iris_hfi_header		*packet;
 	bool				ipsc_properties_set;
 	bool				opsc_properties_set;
+	struct iris_hfi_frame_info	hfi_frame_info;
 	struct hfi_subscription_params	src_subcr_params;
 	struct hfi_subscription_params	dst_subcr_params;
 };
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
index afbdf1f1e68a..8a9f2b5517ad 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
@@ -71,6 +71,12 @@
 #define HFI_SYS_ERROR_WD_TIMEOUT		0x05000001
 #define HFI_SYSTEM_ERROR_END			0x05FFFFFF
=20
+#define HFI_INFORMATION_BEGIN			0x06000000
+#define HFI_INFO_UNSUPPORTED			0x06000001
+#define HFI_INFO_DATA_CORRUPT			0x06000002
+#define HFI_INFO_BUFFER_OVERFLOW		0x06000004
+#define HFI_INFORMATION_END			0x06FFFFFF
+
 enum hfi_property_mode_type {
 	HFI_MODE_PORT_SETTINGS_CHANGE		=3D 0x00000001,
 	HFI_MODE_PROPERTY			=3D 0x00000002,
@@ -92,6 +98,15 @@ enum hfi_codec_type {
 	HFI_CODEC_ENCODE_AVC			=3D 2,
 };
=20
+enum hfi_picture_type {
+	HFI_PICTURE_IDR				=3D 0x00000001,
+	HFI_PICTURE_P				=3D 0x00000002,
+	HFI_PICTURE_B				=3D 0x00000004,
+	HFI_PICTURE_I				=3D 0x00000008,
+	HFI_PICTURE_CRA				=3D 0x00000010,
+	HFI_PICTURE_BLA				=3D 0x00000020,
+};
+
 enum hfi_buffer_type {
 	HFI_BUFFER_BITSTREAM			=3D 0x00000001,
 	HFI_BUFFER_RAW				=3D 0x00000002,
@@ -115,6 +130,13 @@ enum hfi_buffer_host_flags {
 	HFI_BUF_HOST_FLAGS_CB_NON_SECURE	=3D 0x00000200,
 };
=20
+enum hfi_buffer_firmware_flags {
+	HFI_BUF_FW_FLAG_RELEASE_DONE		=3D 0x00000001,
+	HFI_BUF_FW_FLAG_READONLY		=3D 0x00000010,
+	HFI_BUF_FW_FLAG_LAST			=3D 0x10000000,
+	HFI_BUF_FW_FLAG_PSC_LAST		=3D 0x20000000,
+};
+
 enum hfi_packet_firmware_flags {
 	HFI_FW_FLAGS_SUCCESS			=3D 0x00000001,
 	HFI_FW_FLAGS_INFORMATION		=3D 0x00000002,
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c b/dr=
ivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
index 9f3764f1903b..e8d8caeef021 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
@@ -3,6 +3,8 @@
  * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
  */
=20
+#include <media/v4l2-mem2mem.h>
+
 #include "iris_hfi_gen2.h"
 #include "iris_hfi_gen2_defines.h"
 #include "iris_hfi_gen2_packet.h"
@@ -81,6 +83,29 @@ static bool iris_hfi_gen2_is_valid_hfi_port(u32 port, u3=
2 buffer_type)
 	return true;
 }
=20
+static int iris_hfi_gen2_get_driver_buffer_flags(struct iris_inst *inst, u=
32 hfi_flags)
+{
+	u32 keyframe =3D HFI_PICTURE_IDR | HFI_PICTURE_I | HFI_PICTURE_CRA | HFI_=
PICTURE_BLA;
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	u32 driver_flags =3D 0;
+
+	if (inst_hfi_gen2->hfi_frame_info.picture_type & keyframe)
+		driver_flags |=3D V4L2_BUF_FLAG_KEYFRAME;
+	else if (inst_hfi_gen2->hfi_frame_info.picture_type & HFI_PICTURE_P)
+		driver_flags |=3D V4L2_BUF_FLAG_PFRAME;
+	else if (inst_hfi_gen2->hfi_frame_info.picture_type & HFI_PICTURE_B)
+		driver_flags |=3D V4L2_BUF_FLAG_BFRAME;
+
+	if (inst_hfi_gen2->hfi_frame_info.data_corrupt || inst_hfi_gen2->hfi_fram=
e_info.overflow)
+		driver_flags |=3D V4L2_BUF_FLAG_ERROR;
+
+	if (hfi_flags & HFI_BUF_FW_FLAG_LAST ||
+	    hfi_flags & HFI_BUF_FW_FLAG_PSC_LAST)
+		driver_flags |=3D V4L2_BUF_FLAG_LAST;
+
+	return driver_flags;
+}
+
 static bool iris_hfi_gen2_validate_packet_payload(struct iris_hfi_packet *=
pkt)
 {
 	u32 payload_size =3D 0;
@@ -154,6 +179,37 @@ static int iris_hfi_gen2_validate_hdr_packet(struct ir=
is_core *core, struct iris
 	return 0;
 }
=20
+static int iris_hfi_gen2_handle_session_info(struct iris_inst *inst,
+					     struct iris_hfi_packet *pkt)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	struct iris_core *core =3D inst->core;
+	int ret =3D 0;
+	char *info;
+
+	switch (pkt->type) {
+	case HFI_INFO_UNSUPPORTED:
+		info =3D "unsupported";
+		break;
+	case HFI_INFO_DATA_CORRUPT:
+		info =3D "data corrupt";
+		inst_hfi_gen2->hfi_frame_info.data_corrupt =3D 1;
+		break;
+	case HFI_INFO_BUFFER_OVERFLOW:
+		info =3D "buffer overflow";
+		inst_hfi_gen2->hfi_frame_info.overflow =3D 1;
+		break;
+	default:
+		info =3D "unknown";
+		break;
+	}
+
+	dev_dbg(core->dev, "session info received %#x: %s\n",
+		pkt->type, info);
+
+	return ret;
+}
+
 static int iris_hfi_gen2_handle_session_error(struct iris_inst *inst,
 					      struct iris_hfi_packet *pkt)
 {
@@ -237,19 +293,108 @@ static void iris_hfi_gen2_handle_session_close(struc=
t iris_inst *inst,
 	complete(&inst->completion);
 }
=20
+static int iris_hfi_gen2_handle_input_buffer(struct iris_inst *inst,
+					     struct iris_hfi_buffer *buffer)
+{
+	struct v4l2_m2m_ctx *m2m_ctx =3D inst->m2m_ctx;
+	struct v4l2_m2m_buffer *m2m_buffer, *n;
+	struct iris_buffer *buf;
+	bool found =3D false;
+
+	v4l2_m2m_for_each_src_buf_safe(m2m_ctx, m2m_buffer, n) {
+		buf =3D to_iris_buffer(&m2m_buffer->vb);
+		if (buf->index =3D=3D buffer->index) {
+			found =3D true;
+			break;
+		}
+	}
+	if (!found)
+		return -EINVAL;
+
+	if (!(buf->attr & BUF_ATTR_QUEUED))
+		return -EINVAL;
+
+	buf->attr &=3D ~BUF_ATTR_QUEUED;
+	buf->attr |=3D BUF_ATTR_DEQUEUED;
+
+	buf->flags =3D iris_hfi_gen2_get_driver_buffer_flags(inst, buffer->flags);
+
+	return 0;
+}
+
+static int iris_hfi_gen2_handle_output_buffer(struct iris_inst *inst,
+					      struct iris_hfi_buffer *hfi_buffer)
+{
+	struct v4l2_m2m_ctx *m2m_ctx =3D inst->m2m_ctx;
+	struct v4l2_m2m_buffer *m2m_buffer, *n;
+	struct iris_buffer *buf;
+	bool found =3D false;
+
+	v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, m2m_buffer, n) {
+		buf =3D to_iris_buffer(&m2m_buffer->vb);
+		if (buf->index =3D=3D hfi_buffer->index &&
+		    buf->device_addr =3D=3D hfi_buffer->base_address &&
+		    buf->data_offset =3D=3D hfi_buffer->data_offset) {
+			found =3D true;
+			break;
+		}
+	}
+	if (!found)
+		return -EINVAL;
+
+	if (!(buf->attr & BUF_ATTR_QUEUED))
+		return -EINVAL;
+
+	buf->data_offset =3D hfi_buffer->data_offset;
+	buf->data_size =3D hfi_buffer->data_size;
+	buf->timestamp =3D hfi_buffer->timestamp;
+
+	buf->attr &=3D ~BUF_ATTR_QUEUED;
+	buf->attr |=3D BUF_ATTR_DEQUEUED;
+
+	buf->flags =3D iris_hfi_gen2_get_driver_buffer_flags(inst, hfi_buffer->fl=
ags);
+
+	return 0;
+}
+
+static void iris_hfi_gen2_handle_dequeue_buffers(struct iris_inst *inst)
+{
+	struct v4l2_m2m_ctx *m2m_ctx =3D inst->m2m_ctx;
+	struct v4l2_m2m_buffer *buffer, *n;
+	struct iris_buffer *buf =3D NULL;
+
+	v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buffer, n) {
+		buf =3D to_iris_buffer(&buffer->vb);
+		if (buf->attr & BUF_ATTR_DEQUEUED) {
+			buf->attr &=3D ~BUF_ATTR_DEQUEUED;
+			if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) {
+				buf->attr |=3D BUF_ATTR_BUFFER_DONE;
+				iris_vb2_buffer_done(inst, buf);
+			}
+		}
+	}
+
+	v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buffer, n) {
+		buf =3D to_iris_buffer(&buffer->vb);
+		if (buf->attr & BUF_ATTR_DEQUEUED) {
+			buf->attr &=3D ~BUF_ATTR_DEQUEUED;
+			if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) {
+				buf->attr |=3D BUF_ATTR_BUFFER_DONE;
+				iris_vb2_buffer_done(inst, buf);
+			}
+		}
+	}
+}
+
 static int iris_hfi_gen2_handle_release_internal_buffer(struct iris_inst *=
inst,
 							struct iris_hfi_buffer *buffer)
 {
+	u32 buf_type =3D iris_hfi_gen2_buf_type_to_driver(buffer->type);
+	struct iris_buffers *buffers =3D &inst->buffers[buf_type];
 	struct iris_buffer *buf, *iter;
-	struct iris_buffers *buffers;
-	u32 buf_type;
+	bool found =3D false;
 	int ret =3D 0;
-	bool found;
=20
-	buf_type =3D iris_hfi_gen2_buf_type_to_driver(buffer->type);
-	buffers =3D &inst->buffers[buf_type];
-
-	found =3D false;
 	list_for_each_entry(iter, &buffers->list, list) {
 		if (iter->device_addr =3D=3D buffer->base_address) {
 			found =3D true;
@@ -261,7 +406,6 @@ static int iris_hfi_gen2_handle_release_internal_buffer=
(struct iris_inst *inst,
 		return -EINVAL;
=20
 	buf->attr &=3D ~BUF_ATTR_QUEUED;
-
 	if (buf->attr & BUF_ATTR_PENDING_RELEASE)
 		ret =3D iris_destroy_internal_buffer(inst, buf);
=20
@@ -288,7 +432,12 @@ static int iris_hfi_gen2_handle_session_buffer(struct =
iris_inst *inst,
 	if (!iris_hfi_gen2_is_valid_hfi_port(pkt->port, buffer->type))
 		return 0;
=20
-	return iris_hfi_gen2_handle_release_internal_buffer(inst, buffer);
+	if (buffer->type =3D=3D HFI_BUFFER_BITSTREAM)
+		return iris_hfi_gen2_handle_input_buffer(inst, buffer);
+	else if (buffer->type =3D=3D HFI_BUFFER_RAW)
+		return iris_hfi_gen2_handle_output_buffer(inst, buffer);
+	else
+		return iris_hfi_gen2_handle_release_internal_buffer(inst, buffer);
 }
=20
 static int iris_hfi_gen2_handle_session_command(struct iris_inst *inst,
@@ -350,6 +499,12 @@ static int iris_hfi_gen2_handle_session_property(struc=
t iris_inst *inst,
 	case HFI_PROP_LEVEL:
 		inst_hfi_gen2->src_subcr_params.level =3D pkt->payload[0];
 		break;
+	case HFI_PROP_PICTURE_TYPE:
+		inst_hfi_gen2->hfi_frame_info.picture_type =3D pkt->payload[0];
+		break;
+	case HFI_PROP_NO_OUTPUT:
+		inst_hfi_gen2->hfi_frame_info.no_output =3D 1;
+		break;
 	case HFI_PROP_QUALITY_MODE:
 	case HFI_PROP_STAGE:
 	case HFI_PROP_PIPE:
@@ -436,14 +591,18 @@ static int iris_hfi_gen2_handle_system_response(struc=
t iris_core *core,
 static int iris_hfi_gen2_handle_session_response(struct iris_core *core,
 						 struct iris_hfi_header *hdr)
 {
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2;
 	struct iris_hfi_packet *packet;
 	struct iris_inst *inst;
+	bool dequeue =3D false;
 	int ret =3D 0;
 	u32 i, j;
 	u8 *pkt;
 	static const struct iris_hfi_gen2_inst_hfi_range range[] =3D {
 		{HFI_SESSION_ERROR_BEGIN, HFI_SESSION_ERROR_END,
 		 iris_hfi_gen2_handle_session_error},
+		{HFI_INFORMATION_BEGIN, HFI_INFORMATION_END,
+		 iris_hfi_gen2_handle_session_info},
 		{HFI_PROP_BEGIN, HFI_PROP_END,
 		 iris_hfi_gen2_handle_session_property},
 		{HFI_CMD_BEGIN, HFI_CMD_END,
@@ -455,6 +614,8 @@ static int iris_hfi_gen2_handle_session_response(struct=
 iris_core *core,
 		return -EINVAL;
=20
 	mutex_lock(&inst->lock);
+	inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	memset(&inst_hfi_gen2->hfi_frame_info, 0, sizeof(struct iris_hfi_frame_in=
fo));
=20
 	pkt =3D (u8 *)((u8 *)hdr + sizeof(*hdr));
 	for (i =3D 0; i < ARRAY_SIZE(range); i++) {
@@ -465,6 +626,7 @@ static int iris_hfi_gen2_handle_session_response(struct=
 iris_core *core,
 				iris_hfi_gen2_handle_session_error(inst, packet);
=20
 			if (packet->type > range[i].begin && packet->type < range[i].end) {
+				dequeue |=3D (packet->type =3D=3D HFI_CMD_BUFFER);
 				ret =3D range[i].handle(inst, packet);
 				if (ret)
 					iris_inst_change_state(inst, IRIS_INST_ERROR);
@@ -473,6 +635,9 @@ static int iris_hfi_gen2_handle_session_response(struct=
 iris_core *core,
 		}
 	}
=20
+	if (dequeue)
+		iris_hfi_gen2_handle_dequeue_buffers(inst);
+
 	mutex_unlock(&inst->lock);
=20
 	return ret;
diff --git a/drivers/media/platform/qcom/iris/iris_instance.h b/drivers/med=
ia/platform/qcom/iris/iris_instance.h
index 6b88daf31011..2886491ad59f 100644
--- a/drivers/media/platform/qcom/iris/iris_instance.h
+++ b/drivers/media/platform/qcom/iris/iris_instance.h
@@ -34,6 +34,10 @@
  * @once_per_session_set: boolean to set once per session property
  * @m2m_dev:	a reference to m2m device structure
  * @m2m_ctx:	a reference to m2m context structure
+ * @sequence_cap: a sequence counter for capture queue
+ * @sequence_out: a sequence counter for output queue
+ * @tss: timestamp metadata
+ * @metadata_idx: index for metadata buffer
  */
=20
 struct iris_inst {
@@ -56,6 +60,10 @@ struct iris_inst {
 	bool				once_per_session_set;
 	struct v4l2_m2m_dev		*m2m_dev;
 	struct v4l2_m2m_ctx		*m2m_ctx;
+	u32				sequence_cap;
+	u32				sequence_out;
+	struct iris_ts_metadata		tss[VIDEO_MAX_FRAME];
+	u32				metadata_idx;
 };
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_utils.c b/drivers/media/=
platform/qcom/iris/iris_utils.c
index 8bcfa97db97d..83c70d6a2d90 100644
--- a/drivers/media/platform/qcom/iris/iris_utils.c
+++ b/drivers/media/platform/qcom/iris/iris_utils.c
@@ -4,6 +4,7 @@
  */
=20
 #include <linux/pm_runtime.h>
+#include <media/v4l2-mem2mem.h>
=20
 #include "iris_instance.h"
 #include "iris_utils.h"
@@ -36,6 +37,21 @@ bool iris_split_mode_enabled(struct iris_inst *inst)
 	return inst->fmt_dst->fmt.pix_mp.pixelformat =3D=3D V4L2_PIX_FMT_NV12;
 }
=20
+void iris_helper_buffers_done(struct iris_inst *inst, unsigned int type,
+			      enum vb2_buffer_state state)
+{
+	struct v4l2_m2m_ctx *m2m_ctx =3D inst->m2m_ctx;
+	struct vb2_v4l2_buffer *buf;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		while ((buf =3D v4l2_m2m_src_buf_remove(m2m_ctx)))
+			v4l2_m2m_buf_done(buf, state);
+	} else if (V4L2_TYPE_IS_CAPTURE(type)) {
+		while ((buf =3D v4l2_m2m_dst_buf_remove(m2m_ctx)))
+			v4l2_m2m_buf_done(buf, state);
+	}
+}
+
 int iris_wait_for_session_response(struct iris_inst *inst, bool is_flush)
 {
 	struct iris_core *core =3D inst->core;
diff --git a/drivers/media/platform/qcom/iris/iris_utils.h b/drivers/media/=
platform/qcom/iris/iris_utils.h
index 3400847f5e72..49869cf7a376 100644
--- a/drivers/media/platform/qcom/iris/iris_utils.h
+++ b/drivers/media/platform/qcom/iris/iris_utils.h
@@ -16,6 +16,20 @@ struct iris_hfi_rect_desc {
 	u32 height;
 };
=20
+struct iris_hfi_frame_info {
+	u32 picture_type;
+	u32 no_output;
+	u32 data_corrupt;
+	u32 overflow;
+};
+
+struct iris_ts_metadata {
+	u64 ts_ns;
+	u64 ts_us;
+	u32 flags;
+	struct v4l2_timecode tc;
+};
+
 #define NUM_MBS_PER_FRAME(height, width) \
 	(DIV_ROUND_UP(height, 16) * DIV_ROUND_UP(width, 16))
=20
@@ -32,6 +46,8 @@ bool iris_res_is_less_than(u32 width, u32 height,
 int iris_get_mbpf(struct iris_inst *inst);
 bool iris_split_mode_enabled(struct iris_inst *inst);
 struct iris_inst *iris_get_instance(struct iris_core *core, u32 session_id=
);
+void iris_helper_buffers_done(struct iris_inst *inst, unsigned int type,
+			      enum vb2_buffer_state state);
 int iris_wait_for_session_response(struct iris_inst *inst, bool is_flush);
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_vb2.c b/drivers/media/pl=
atform/qcom/iris/iris_vb2.c
index b93da860d336..770e51f9ef91 100644
--- a/drivers/media/platform/qcom/iris/iris_vb2.c
+++ b/drivers/media/platform/qcom/iris/iris_vb2.c
@@ -3,10 +3,23 @@
  * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
  */
=20
+#include <media/videobuf2-dma-contig.h>
+#include <media/v4l2-mem2mem.h>
+
 #include "iris_instance.h"
 #include "iris_vb2.h"
 #include "iris_vdec.h"
=20
+int iris_vb2_buf_init(struct vb2_buffer *vb2)
+{
+	struct vb2_v4l2_buffer *vbuf =3D to_vb2_v4l2_buffer(vb2);
+	struct iris_buffer *buf =3D to_iris_buffer(vbuf);
+
+	buf->device_addr =3D vb2_dma_contig_plane_dma_addr(vb2, 0);
+
+	return 0;
+}
+
 int iris_vb2_queue_setup(struct vb2_queue *q,
 			 unsigned int *num_buffers, unsigned int *num_planes,
 			 unsigned int sizes[], struct device *alloc_devs[])
@@ -60,6 +73,7 @@ int iris_vb2_queue_setup(struct vb2_queue *q,
=20
 int iris_vb2_start_streaming(struct vb2_queue *q, unsigned int count)
 {
+	enum iris_buffer_type buf_type;
 	struct iris_inst *inst;
 	int ret =3D 0;
=20
@@ -87,11 +101,18 @@ int iris_vb2_start_streaming(struct vb2_queue *q, unsi=
gned int count)
 	if (ret)
 		goto error;
=20
+	buf_type =3D iris_v4l2_type_to_driver(q->type);
+
+	ret =3D iris_queue_deferred_buffers(inst, buf_type);
+	if (ret)
+		goto error;
+
 	mutex_unlock(&inst->lock);
=20
 	return ret;
=20
 error:
+	iris_helper_buffers_done(inst, q->type, VB2_BUF_STATE_QUEUED);
 	iris_inst_change_state(inst, IRIS_INST_ERROR);
 	mutex_unlock(&inst->lock);
=20
@@ -101,6 +122,7 @@ int iris_vb2_start_streaming(struct vb2_queue *q, unsig=
ned int count)
 void iris_vb2_stop_streaming(struct vb2_queue *q)
 {
 	struct iris_inst *inst;
+	int ret =3D 0;
=20
 	inst =3D vb2_get_drv_priv(q);
=20
@@ -113,8 +135,82 @@ void iris_vb2_stop_streaming(struct vb2_queue *q)
 	    !V4L2_TYPE_IS_CAPTURE(q->type))
 		goto exit;
=20
-	iris_vdec_session_streamoff(inst, q->type);
+	ret =3D iris_vdec_session_streamoff(inst, q->type);
+	if (ret)
+		goto exit;
+
+exit:
+	iris_helper_buffers_done(inst, q->type, VB2_BUF_STATE_ERROR);
+	if (ret)
+		iris_inst_change_state(inst, IRIS_INST_ERROR);
+
+	mutex_unlock(&inst->lock);
+}
+
+int iris_vb2_buf_prepare(struct vb2_buffer *vb)
+{
+	struct iris_inst *inst =3D vb2_get_drv_priv(vb->vb2_queue);
+	struct vb2_v4l2_buffer *vbuf =3D to_vb2_v4l2_buffer(vb);
+
+	if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
+		if (vbuf->field =3D=3D V4L2_FIELD_ANY)
+			vbuf->field =3D V4L2_FIELD_NONE;
+		if (vbuf->field !=3D V4L2_FIELD_NONE)
+			return -EINVAL;
+	}
+
+	if (vb->type =3D=3D V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
+	    vb2_plane_size(vb, 0) < iris_get_buffer_size(inst, BUF_OUTPUT))
+		return -EINVAL;
+	if (vb->type =3D=3D V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
+	    vb2_plane_size(vb, 0) < iris_get_buffer_size(inst, BUF_INPUT))
+		return -EINVAL;
+
+	return 0;
+}
+
+int iris_vb2_buf_out_validate(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *v4l2_buf =3D to_vb2_v4l2_buffer(vb);
+
+	v4l2_buf->field =3D V4L2_FIELD_NONE;
+
+	return 0;
+}
+
+void iris_vb2_buf_queue(struct vb2_buffer *vb2)
+{
+	struct vb2_v4l2_buffer *vbuf =3D to_vb2_v4l2_buffer(vb2);
+	struct v4l2_m2m_ctx *m2m_ctx;
+	struct iris_inst *inst;
+	int ret =3D 0;
+
+	inst =3D vb2_get_drv_priv(vb2->vb2_queue);
+
+	mutex_lock(&inst->lock);
+	if (inst->state =3D=3D IRIS_INST_ERROR) {
+		ret =3D -EBUSY;
+		goto exit;
+	}
+
+	if (vbuf->field =3D=3D V4L2_FIELD_ANY)
+		vbuf->field =3D V4L2_FIELD_NONE;
+
+	m2m_ctx =3D inst->m2m_ctx;
+
+	if (!vb2->planes[0].bytesused && V4L2_TYPE_IS_OUTPUT(vb2->type)) {
+		ret =3D -EINVAL;
+		goto exit;
+	}
+
+	v4l2_m2m_buf_queue(m2m_ctx, vbuf);
+
+	ret =3D iris_vdec_qbuf(inst, vbuf);
=20
 exit:
+	if (ret) {
+		iris_inst_change_state(inst, IRIS_INST_ERROR);
+		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+	}
 	mutex_unlock(&inst->lock);
 }
diff --git a/drivers/media/platform/qcom/iris/iris_vb2.h b/drivers/media/pl=
atform/qcom/iris/iris_vb2.h
index 3906510fa71f..a88565fdd3e4 100644
--- a/drivers/media/platform/qcom/iris/iris_vb2.h
+++ b/drivers/media/platform/qcom/iris/iris_vb2.h
@@ -6,10 +6,14 @@
 #ifndef __IRIS_VB2_H__
 #define __IRIS_VB2_H__
=20
+int iris_vb2_buf_init(struct vb2_buffer *vb2);
 int iris_vb2_queue_setup(struct vb2_queue *q,
 			 unsigned int *num_buffers, unsigned int *num_planes,
 			 unsigned int sizes[], struct device *alloc_devs[]);
 int iris_vb2_start_streaming(struct vb2_queue *q, unsigned int count);
 void iris_vb2_stop_streaming(struct vb2_queue *q);
+int iris_vb2_buf_prepare(struct vb2_buffer *vb);
+int iris_vb2_buf_out_validate(struct vb2_buffer *vb);
+void iris_vb2_buf_queue(struct vb2_buffer *vb2);
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/p=
latform/qcom/iris/iris_vdec.c
index 8d489530da31..d6b092314b34 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.c
+++ b/drivers/media/platform/qcom/iris/iris_vdec.c
@@ -223,6 +223,68 @@ int iris_vdec_subscribe_event(struct iris_inst *inst, =
const struct v4l2_event_su
 	return ret;
 }
=20
+static int iris_vdec_get_num_queued_buffers(struct iris_inst *inst,
+					    enum iris_buffer_type type)
+{
+	struct v4l2_m2m_ctx *m2m_ctx =3D inst->m2m_ctx;
+	struct v4l2_m2m_buffer *buffer, *n;
+	struct iris_buffer *buf;
+	u32 count =3D 0;
+
+	switch (type) {
+	case BUF_INPUT:
+		v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buffer, n) {
+			buf =3D to_iris_buffer(&buffer->vb);
+			if (!(buf->attr & BUF_ATTR_QUEUED))
+				continue;
+			count++;
+		}
+		return count;
+	case BUF_OUTPUT:
+		v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buffer, n) {
+			buf =3D to_iris_buffer(&buffer->vb);
+			if (!(buf->attr & BUF_ATTR_QUEUED))
+				continue;
+			count++;
+		}
+		return count;
+	default:
+		return count;
+	}
+}
+
+static void iris_vdec_flush_deferred_buffers(struct iris_inst *inst,
+					     enum iris_buffer_type type)
+{
+	struct v4l2_m2m_ctx *m2m_ctx =3D inst->m2m_ctx;
+	struct v4l2_m2m_buffer *buffer, *n;
+	struct iris_buffer *buf;
+
+	if (type =3D=3D BUF_INPUT) {
+		v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buffer, n) {
+			buf =3D to_iris_buffer(&buffer->vb);
+			if (buf->attr & BUF_ATTR_DEFERRED) {
+				if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) {
+					buf->attr |=3D BUF_ATTR_BUFFER_DONE;
+					buf->data_size =3D 0;
+					iris_vb2_buffer_done(inst, buf);
+				}
+			}
+		}
+	} else {
+		v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buffer, n) {
+			buf =3D to_iris_buffer(&buffer->vb);
+			if (buf->attr & BUF_ATTR_DEFERRED) {
+				if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) {
+					buf->attr |=3D BUF_ATTR_BUFFER_DONE;
+					buf->data_size =3D 0;
+					iris_vb2_buffer_done(inst, buf);
+				}
+			}
+		}
+	}
+}
+
 static void iris_vdec_kill_session(struct iris_inst *inst)
 {
 	const struct iris_hfi_command_ops *hfi_ops =3D inst->core->hfi_ops;
@@ -234,23 +296,47 @@ static void iris_vdec_kill_session(struct iris_inst *=
inst)
 	iris_inst_change_state(inst, IRIS_INST_ERROR);
 }
=20
-void iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane)
+int iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane)
 {
 	const struct iris_hfi_command_ops *hfi_ops =3D inst->core->hfi_ops;
+	enum iris_buffer_type buffer_type;
+	u32 count;
 	int ret;
=20
+	switch (plane) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		buffer_type =3D BUF_INPUT;
+		break;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+		buffer_type =3D BUF_OUTPUT;
+		break;
+	default:
+		return -EINVAL;
+	}
+
 	ret =3D hfi_ops->session_stop(inst, plane);
 	if (ret)
 		goto error;
=20
+	count =3D iris_vdec_get_num_queued_buffers(inst, buffer_type);
+	if (count) {
+		ret =3D -EINVAL;
+		goto error;
+	}
+
 	ret =3D iris_inst_state_change_streamoff(inst, plane);
 	if (ret)
 		goto error;
=20
-	return;
+	iris_vdec_flush_deferred_buffers(inst, buffer_type);
+
+	return 0;
=20
 error:
 	iris_vdec_kill_session(inst);
+	iris_vdec_flush_deferred_buffers(inst, buffer_type);
+
+	return ret;
 }
=20
 static int iris_vdec_process_streamon_input(struct iris_inst *inst)
@@ -340,3 +426,64 @@ int iris_vdec_streamon_output(struct iris_inst *inst)
=20
 	return ret;
 }
+
+static int
+iris_vdec_vb2_buffer_to_driver(struct vb2_buffer *vb2, struct iris_buffer =
*buf)
+{
+	struct vb2_v4l2_buffer *vbuf =3D to_vb2_v4l2_buffer(vb2);
+
+	buf->type =3D iris_v4l2_type_to_driver(vb2->type);
+	buf->index =3D vb2->index;
+	buf->fd =3D vb2->planes[0].m.fd;
+	buf->buffer_size =3D vb2->planes[0].length;
+	buf->data_offset =3D vb2->planes[0].data_offset;
+	buf->data_size =3D vb2->planes[0].bytesused - vb2->planes[0].data_offset;
+	buf->flags =3D vbuf->flags;
+	buf->timestamp =3D vb2->timestamp;
+	buf->attr =3D 0;
+
+	return 0;
+}
+
+static void
+iris_set_ts_metadata(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf)
+{
+	u32 mask =3D V4L2_BUF_FLAG_TIMECODE | V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+	struct vb2_buffer *vb =3D &vbuf->vb2_buf;
+	u64 ts_us =3D vb->timestamp;
+
+	if (inst->metadata_idx >=3D ARRAY_SIZE(inst->tss))
+		inst->metadata_idx =3D 0;
+
+	do_div(ts_us, NSEC_PER_USEC);
+
+	inst->tss[inst->metadata_idx].flags =3D vbuf->flags & mask;
+	inst->tss[inst->metadata_idx].tc =3D vbuf->timecode;
+	inst->tss[inst->metadata_idx].ts_us =3D ts_us;
+	inst->tss[inst->metadata_idx].ts_ns =3D vb->timestamp;
+
+	inst->metadata_idx++;
+}
+
+int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf)
+{
+	struct iris_buffer *buf =3D to_iris_buffer(vbuf);
+	struct vb2_buffer *vb2 =3D &vbuf->vb2_buf;
+	struct vb2_queue *q;
+	int ret;
+
+	ret =3D iris_vdec_vb2_buffer_to_driver(vb2, buf);
+	if (ret)
+		return ret;
+
+	if (buf->type =3D=3D BUF_INPUT)
+		iris_set_ts_metadata(inst, vbuf);
+
+	q =3D v4l2_m2m_get_vq(inst->m2m_ctx, vb2->type);
+	if (!vb2_is_streaming(q)) {
+		buf->attr |=3D BUF_ATTR_DEFERRED;
+		return 0;
+	}
+
+	return iris_queue_buffer(inst, buf);
+}
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.h b/drivers/media/p=
latform/qcom/iris/iris_vdec.h
index a17bb817b6e5..998d4970a42b 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.h
+++ b/drivers/media/platform/qcom/iris/iris_vdec.h
@@ -16,6 +16,7 @@ int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_f=
ormat *f);
 int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_ev=
ent_subscription *sub);
 int iris_vdec_streamon_input(struct iris_inst *inst);
 int iris_vdec_streamon_output(struct iris_inst *inst);
-void iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane);
+int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf);
+int iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane);
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/p=
latform/qcom/iris/iris_vidc.c
index ec5694c1c8de..2b27df6b1aad 100644
--- a/drivers/media/platform/qcom/iris/iris_vidc.c
+++ b/drivers/media/platform/qcom/iris/iris_vidc.c
@@ -7,6 +7,7 @@
 #include <media/v4l2-event.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-contig.h>
=20
 #include "iris_vidc.h"
 #include "iris_instance.h"
@@ -98,6 +99,7 @@ iris_m2m_queue_init(void *priv, struct vb2_queue *src_vq,=
 struct vb2_queue *dst_
 	src_vq->io_modes =3D VB2_MMAP | VB2_DMABUF;
 	src_vq->timestamp_flags =3D V4L2_BUF_FLAG_TIMESTAMP_COPY;
 	src_vq->ops =3D inst->core->iris_vb2_ops;
+	src_vq->mem_ops =3D &vb2_dma_contig_memops;
 	src_vq->drv_priv =3D inst;
 	src_vq->buf_struct_size =3D sizeof(struct iris_buffer);
 	src_vq->min_reqbufs_allocation =3D MIN_BUFFERS;
@@ -111,6 +113,7 @@ iris_m2m_queue_init(void *priv, struct vb2_queue *src_v=
q, struct vb2_queue *dst_
 	dst_vq->io_modes =3D VB2_MMAP | VB2_DMABUF;
 	dst_vq->timestamp_flags =3D V4L2_BUF_FLAG_TIMESTAMP_COPY;
 	dst_vq->ops =3D inst->core->iris_vb2_ops;
+	dst_vq->mem_ops =3D &vb2_dma_contig_memops;
 	dst_vq->drv_priv =3D inst;
 	dst_vq->buf_struct_size =3D sizeof(struct iris_buffer);
 	dst_vq->min_reqbufs_allocation =3D MIN_BUFFERS;
@@ -372,9 +375,13 @@ static struct v4l2_file_operations iris_v4l2_file_ops =
=3D {
 };
=20
 static const struct vb2_ops iris_vb2_ops =3D {
+	.buf_init                       =3D iris_vb2_buf_init,
 	.queue_setup                    =3D iris_vb2_queue_setup,
 	.start_streaming                =3D iris_vb2_start_streaming,
 	.stop_streaming                 =3D iris_vb2_stop_streaming,
+	.buf_prepare                    =3D iris_vb2_buf_prepare,
+	.buf_out_validate               =3D iris_vb2_buf_out_validate,
+	.buf_queue                      =3D iris_vb2_buf_queue,
 };
=20
 static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops =3D {
@@ -388,6 +395,13 @@ static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops=
 =3D {
 	.vidioc_g_fmt_vid_out_mplane    =3D iris_g_fmt_vid_mplane,
 	.vidioc_enum_framesizes         =3D iris_enum_framesizes,
 	.vidioc_reqbufs                 =3D v4l2_m2m_ioctl_reqbufs,
+	.vidioc_querybuf                =3D v4l2_m2m_ioctl_querybuf,
+	.vidioc_create_bufs             =3D v4l2_m2m_ioctl_create_bufs,
+	.vidioc_prepare_buf             =3D v4l2_m2m_ioctl_prepare_buf,
+	.vidioc_expbuf                  =3D v4l2_m2m_ioctl_expbuf,
+	.vidioc_qbuf                    =3D v4l2_m2m_ioctl_qbuf,
+	.vidioc_dqbuf                   =3D v4l2_m2m_ioctl_dqbuf,
+	.vidioc_remove_bufs             =3D v4l2_m2m_ioctl_remove_bufs,
 	.vidioc_querycap                =3D iris_querycap,
 	.vidioc_g_selection             =3D iris_g_selection,
 	.vidioc_subscribe_event         =3D iris_subscribe_event,

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 C5599234979;
	Fri,  7 Feb 2025 07:57:35 +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=1738915058; cv=none;
 b=FLUN5PWB7++8BBOb/viQ0BllD1UCmwQpZas/+crYEyzvlCbaTZp/APP0R7Pziesk5p81gMUgLklN3PQkzU4+Kwr4xaanHa1ewIWdt9Alr1+uHuSSnJXDWPyKAF99p5F8/gDeNo40kyyFtIK0mQ0V24zG+7d9YTq8HX/OeuutLiA=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738915058; c=relaxed/simple;
	bh=K/rAUfAvsi/TAMZFVDHLEFIbWsBuDnG3SbV7zZ/Otiw=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=lKjc5Yx8ypCrGKgA9ZXQ6lM6LkuKKjbuN4WbJH1nPmOdDnIw3HY65p5DiwFsqvS64DElp21BRj3L9WfkuoFfyTJn9b25Wd5hXvv1HaWHRPubH2ELTEZ11jX558E289zxIfnecsmDFPzLoMHkMv6+xx6Tcii1tFMaWV0buw90zQk=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=WVIru472; arc=none smtp.client-ip=205.220.168.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="WVIru472"
Received: from pps.filterd (m0279867.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 51770S0a029972;
	Fri, 7 Feb 2025 07:57:20 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	cQiVQ5IA9rxpkLBRyElNRVyExiuB3OXb7n1tNI/H93s=; b=WVIru472+bI6sDWz
	Qz2WwQjoXhVh1zwUOiTvLIUIxkMdcOGTTe7Cxy8IXGNH/ZvVgpqPFXPbDqCSYgox
	Vw5bf/F9i/VZLpHtC4AVb7nq16VHc6D6tXCaolpWFEbREQxAluniDBI4TUG/dSBQ
	LJftMcr8p2FxkD5/7vrq3mpba4VXoghvbccrtQwCoGkOQFF48Lg4UsGc8IprLLk7
	0OVujxSTXY/nlyCudJaNsSifxB0zxqFbGsUK2jg2eqMsCHfgjXZgPDHcEJvjMyrH
	4C+vobeJt63IvmU6GGP9ZWS8S5O4UX+eWVn5KFwt0vA3BCSJ+NpuY4GXmMAvfkCt
	bSN+vQ==
Received: from nalasppmta04.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44nddjg4ac-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:57:19 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA04.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177vJB9010682
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:57:19 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:57:12 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:25:01 +0530
Subject: [PATCH v10 21/28] media: iris: add support for dynamic resolution
 change
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-21-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914893; l=35463;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=K/rAUfAvsi/TAMZFVDHLEFIbWsBuDnG3SbV7zZ/Otiw=;
 b=S98UrqbR0A0CWXaj+PyU3A8JFGcfSlWo7ch5Ow8aZc2BKn5Xq2vyDelYRiRVPLzcX/74cIh9g
 NdkADcFpS0dCJIWxrTK68Bjlu+365Y9w6/0RHsWKAi7DEyHJAuSlxt4
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-ORIG-GUID: zubyhRLJ1zDX8pKD3lfIuxRofxpz7RTK
X-Proofpoint-GUID: zubyhRLJ1zDX8pKD3lfIuxRofxpz7RTK
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 mlxscore=0 impostorscore=0
 adultscore=0 bulkscore=0 phishscore=0 malwarescore=0 lowpriorityscore=0
 mlxlogscore=999 priorityscore=1501 clxscore=1015 suspectscore=0
 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070060

Handle the response sent by the firmware, when a source change is
detected. Read the subscribed parameter to get the changed values. Raise
the source change event to the client and update the instance sub-state.

Mark the last buffer from before the source change with the
V4L2_BUF_FLAG_LAST flag and return to the client.

Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl>
Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 drivers/media/platform/qcom/iris/iris_hfi_common.c |  64 +++++++
 drivers/media/platform/qcom/iris/iris_hfi_common.h |   3 +
 .../platform/qcom/iris/iris_hfi_gen1_defines.h     |  82 ++++++++
 .../platform/qcom/iris/iris_hfi_gen1_response.c    | 208 +++++++++++++++++=
++++
 .../platform/qcom/iris/iris_hfi_gen2_defines.h     |   4 +
 .../platform/qcom/iris/iris_hfi_gen2_response.c    | 183 +++++++++++++++++-
 drivers/media/platform/qcom/iris/iris_instance.h   |   2 +
 drivers/media/platform/qcom/iris/iris_state.c      |  64 +++++++
 drivers/media/platform/qcom/iris/iris_state.h      |  33 ++++
 drivers/media/platform/qcom/iris/iris_vb2.c        |  18 ++
 drivers/media/platform/qcom/iris/iris_vdec.c       |  15 ++
 drivers/media/platform/qcom/iris/iris_vdec.h       |   1 +
 12 files changed, 676 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.c b/drivers/m=
edia/platform/qcom/iris/iris_hfi_common.c
index 29f56c2bf74c..92112eb16c11 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_common.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.c
@@ -10,6 +10,70 @@
 #include "iris_hfi_common.h"
 #include "iris_vpu_common.h"
=20
+u32 iris_hfi_get_v4l2_color_primaries(u32 hfi_primaries)
+{
+	switch (hfi_primaries) {
+	case HFI_PRIMARIES_RESERVED:
+		return V4L2_COLORSPACE_DEFAULT;
+	case HFI_PRIMARIES_BT709:
+		return V4L2_COLORSPACE_REC709;
+	case HFI_PRIMARIES_BT470_SYSTEM_M:
+		return V4L2_COLORSPACE_470_SYSTEM_M;
+	case HFI_PRIMARIES_BT470_SYSTEM_BG:
+		return V4L2_COLORSPACE_470_SYSTEM_BG;
+	case HFI_PRIMARIES_BT601_525:
+		return V4L2_COLORSPACE_SMPTE170M;
+	case HFI_PRIMARIES_SMPTE_ST240M:
+		return V4L2_COLORSPACE_SMPTE240M;
+	case HFI_PRIMARIES_BT2020:
+		return V4L2_COLORSPACE_BT2020;
+	case V4L2_COLORSPACE_DCI_P3:
+		return HFI_PRIMARIES_SMPTE_RP431_2;
+	default:
+		return V4L2_COLORSPACE_DEFAULT;
+	}
+}
+
+u32 iris_hfi_get_v4l2_transfer_char(u32 hfi_characterstics)
+{
+	switch (hfi_characterstics) {
+	case HFI_TRANSFER_RESERVED:
+		return V4L2_XFER_FUNC_DEFAULT;
+	case HFI_TRANSFER_BT709:
+		return V4L2_XFER_FUNC_709;
+	case HFI_TRANSFER_SMPTE_ST240M:
+		return V4L2_XFER_FUNC_SMPTE240M;
+	case HFI_TRANSFER_SRGB_SYCC:
+		return V4L2_XFER_FUNC_SRGB;
+	case HFI_TRANSFER_SMPTE_ST2084_PQ:
+		return V4L2_XFER_FUNC_SMPTE2084;
+	default:
+		return V4L2_XFER_FUNC_DEFAULT;
+	}
+}
+
+u32 iris_hfi_get_v4l2_matrix_coefficients(u32 hfi_coefficients)
+{
+	switch (hfi_coefficients) {
+	case HFI_MATRIX_COEFF_RESERVED:
+		return V4L2_YCBCR_ENC_DEFAULT;
+	case HFI_MATRIX_COEFF_BT709:
+		return V4L2_YCBCR_ENC_709;
+	case HFI_MATRIX_COEFF_BT470_SYS_BG_OR_BT601_625:
+		return V4L2_YCBCR_ENC_XV601;
+	case HFI_MATRIX_COEFF_BT601_525_BT1358_525_OR_625:
+		return V4L2_YCBCR_ENC_601;
+	case HFI_MATRIX_COEFF_SMPTE_ST240:
+		return V4L2_YCBCR_ENC_SMPTE240M;
+	case HFI_MATRIX_COEFF_BT2020_NON_CONSTANT:
+		return V4L2_YCBCR_ENC_BT2020;
+	case HFI_MATRIX_COEFF_BT2020_CONSTANT:
+		return V4L2_YCBCR_ENC_BT2020_CONST_LUM;
+	default:
+		return V4L2_YCBCR_ENC_DEFAULT;
+	}
+}
+
 int iris_hfi_core_init(struct iris_core *core)
 {
 	const struct iris_hfi_command_ops *hfi_ops =3D core->hfi_ops;
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/m=
edia/platform/qcom/iris/iris_hfi_common.h
index c54c88658633..6241098dc31d 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_common.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h
@@ -138,6 +138,9 @@ struct hfi_subscription_params {
 	u32	level;
 };
=20
+u32 iris_hfi_get_v4l2_color_primaries(u32 hfi_primaries);
+u32 iris_hfi_get_v4l2_transfer_char(u32 hfi_characterstics);
+u32 iris_hfi_get_v4l2_matrix_coefficients(u32 hfi_coefficients);
 int iris_hfi_core_init(struct iris_core *core);
 int iris_hfi_pm_suspend(struct iris_core *core);
 int iris_hfi_pm_resume(struct iris_core *core);
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
index 108449d703e1..416e9a19a26f 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
@@ -44,18 +44,28 @@
 #define HFI_EVENT_SYS_ERROR				0x1
 #define HFI_EVENT_SESSION_ERROR				0x2
=20
+#define HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUF_RESOURCES   0x10000=
01
+#define HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUF_RESOURCES 0x10000=
02
+#define HFI_EVENT_SESSION_SEQUENCE_CHANGED			   0x1000003
+
 #define HFI_BUFFERFLAG_TIMESTAMPINVALID			0x00000100
=20
 #define HFI_FLUSH_OUTPUT				0x1000002
 #define HFI_FLUSH_OUTPUT2				0x1000003
 #define HFI_FLUSH_ALL					0x1000004
=20
+#define HFI_INDEX_EXTRADATA_INPUT_CROP			0x0700000e
+
 #define HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL				0x201001
 #define HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO	0x20=
1002
 #define HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE				0x201008
 #define HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL				0x20100c
=20
+#define HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS		0x202001
+
 #define HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER	0x1200001
+#define HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS		0x120300e
+#define HFI_PROPERTY_CONFIG_VDEC_ENTROPY		0x1204004
=20
 #define HFI_BUFFER_INPUT				0x1
 #define HFI_BUFFER_OUTPUT				0x2
@@ -69,11 +79,15 @@
=20
 #define HFI_PROPERTY_PARAM_FRAME_SIZE			0x1001
 #define HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT	0x1003
+#define HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT	0x1005
 #define HFI_PROPERTY_PARAM_WORK_MODE			0x1015
 #define HFI_PROPERTY_PARAM_WORK_ROUTE			0x1017
 #define HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE		0x2002
=20
 #define HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM		0x1003001
+#define HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH		0x1003007
+#define HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT		0x1003009
+#define HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE		0x100300a
 #define HFI_CORE_ID_1					1
 #define HFI_COLOR_FORMAT_NV12				0x02
 #define HFI_COLOR_FORMAT_NV12_UBWC			0x8002
@@ -249,6 +263,11 @@ struct hfi_enable {
 	u32 enable;
 };
=20
+struct hfi_profile_level {
+	u32 profile;
+	u32 level;
+};
+
 struct hfi_framesize {
 	u32 buffer_type;
 	u32 width;
@@ -267,6 +286,37 @@ struct hfi_video_work_route {
 	u32 video_work_route;
 };
=20
+struct hfi_bit_depth {
+	u32 buffer_type;
+	u32 bit_depth;
+};
+
+struct hfi_pic_struct {
+	u32 progressive_only;
+};
+
+struct hfi_colour_space {
+	u32 colour_space;
+};
+
+struct hfi_extradata_input_crop {
+	u32 size;
+	u32 version;
+	u32 port_index;
+	u32 left;
+	u32 top;
+	u32 width;
+	u32 height;
+};
+
+struct hfi_dpb_counts {
+	u32 max_dpb_count;
+	u32 max_ref_frames;
+	u32 max_dec_buffering;
+	u32 max_reorder_frames;
+	u32 fw_min_count;
+};
+
 struct hfi_uncompressed_format_select {
 	u32 buffer_type;
 	u32 format;
@@ -301,6 +351,38 @@ struct hfi_multi_stream {
 	u32 enable;
 };
=20
+struct hfi_buffer_requirements {
+	u32 type;
+	u32 size;
+	u32 region_size;
+	u32 hold_count;
+	u32 count_min;
+	u32 count_actual;
+	u32 contiguous;
+	u32 alignment;
+};
+
+struct hfi_event_data {
+	u32 error;
+	u32 height;
+	u32 width;
+	u32 event_type;
+	u32 packet_buffer;
+	u32 extradata_buffer;
+	u32 tag;
+	u32 profile;
+	u32 level;
+	u32 bit_depth;
+	u32 pic_struct;
+	u32 colour_space;
+	u32 entropy_mode;
+	u32 buf_count;
+	struct {
+		u32 left, top;
+		u32 width, height;
+	} input_crop;
+};
+
 struct hfi_msg_session_empty_buffer_done_pkt {
 	struct hfi_msg_session_hdr_pkt shdr;
 	u32 offset;
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c b/dr=
ivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
index 23a8bf29e381..3a47d9f39695 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
@@ -3,11 +3,216 @@
  * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
  */
=20
+#include <linux/bitfield.h>
 #include <media/v4l2-mem2mem.h>
=20
 #include "iris_hfi_gen1.h"
 #include "iris_hfi_gen1_defines.h"
 #include "iris_instance.h"
+#include "iris_vdec.h"
+#include "iris_vpu_buffer.h"
+
+static void iris_hfi_gen1_read_changed_params(struct iris_inst *inst,
+					      struct hfi_msg_event_notify_pkt *pkt)
+{
+	struct v4l2_pix_format_mplane *pixmp_ip =3D &inst->fmt_src->fmt.pix_mp;
+	struct v4l2_pix_format_mplane *pixmp_op =3D &inst->fmt_dst->fmt.pix_mp;
+	u32 num_properties_changed =3D pkt->event_data2;
+	u8 *data_ptr =3D (u8 *)&pkt->ext_event_data[0];
+	u32 primaries, matrix_coeff, transfer_char;
+	struct hfi_dpb_counts *iris_vpu_dpb_count;
+	struct hfi_profile_level *profile_level;
+	struct hfi_buffer_requirements *bufreq;
+	struct hfi_extradata_input_crop *crop;
+	struct hfi_colour_space *colour_info;
+	struct iris_core *core =3D inst->core;
+	u32 colour_description_present_flag;
+	u32 video_signal_type_present_flag;
+	struct hfi_event_data event =3D {0};
+	struct hfi_bit_depth *pixel_depth;
+	struct hfi_pic_struct *pic_struct;
+	struct hfi_framesize *frame_sz;
+	struct vb2_queue *dst_q;
+	struct v4l2_ctrl *ctrl;
+	u32 full_range, ptype;
+
+	do {
+		ptype =3D *((u32 *)data_ptr);
+		switch (ptype) {
+		case HFI_PROPERTY_PARAM_FRAME_SIZE:
+			data_ptr +=3D sizeof(u32);
+			frame_sz =3D (struct hfi_framesize *)data_ptr;
+			event.width =3D frame_sz->width;
+			event.height =3D frame_sz->height;
+			data_ptr +=3D sizeof(*frame_sz);
+			break;
+		case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT:
+			data_ptr +=3D sizeof(u32);
+			profile_level =3D (struct hfi_profile_level *)data_ptr;
+			event.profile =3D profile_level->profile;
+			event.level =3D profile_level->level;
+			data_ptr +=3D sizeof(*profile_level);
+			break;
+		case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH:
+			data_ptr +=3D sizeof(u32);
+			pixel_depth =3D (struct hfi_bit_depth *)data_ptr;
+			event.bit_depth =3D pixel_depth->bit_depth;
+			data_ptr +=3D sizeof(*pixel_depth);
+			break;
+		case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT:
+			data_ptr +=3D sizeof(u32);
+			pic_struct =3D (struct hfi_pic_struct *)data_ptr;
+			event.pic_struct =3D pic_struct->progressive_only;
+			data_ptr +=3D sizeof(*pic_struct);
+			break;
+		case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE:
+			data_ptr +=3D sizeof(u32);
+			colour_info =3D (struct hfi_colour_space *)data_ptr;
+			event.colour_space =3D colour_info->colour_space;
+			data_ptr +=3D sizeof(*colour_info);
+			break;
+		case HFI_PROPERTY_CONFIG_VDEC_ENTROPY:
+			data_ptr +=3D sizeof(u32);
+			event.entropy_mode =3D *(u32 *)data_ptr;
+			data_ptr +=3D sizeof(u32);
+			break;
+		case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
+			data_ptr +=3D sizeof(u32);
+			bufreq =3D (struct hfi_buffer_requirements *)data_ptr;
+			event.buf_count =3D bufreq->count_min;
+			data_ptr +=3D sizeof(*bufreq);
+			break;
+		case HFI_INDEX_EXTRADATA_INPUT_CROP:
+			data_ptr +=3D sizeof(u32);
+			crop =3D (struct hfi_extradata_input_crop *)data_ptr;
+			event.input_crop.left =3D crop->left;
+			event.input_crop.top =3D crop->top;
+			event.input_crop.width =3D crop->width;
+			event.input_crop.height =3D crop->height;
+			data_ptr +=3D sizeof(*crop);
+			break;
+		case HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS:
+			data_ptr +=3D sizeof(u32);
+			iris_vpu_dpb_count =3D (struct hfi_dpb_counts *)data_ptr;
+			event.buf_count =3D iris_vpu_dpb_count->fw_min_count;
+			data_ptr +=3D sizeof(*iris_vpu_dpb_count);
+			break;
+		default:
+			break;
+		}
+		num_properties_changed--;
+	} while (num_properties_changed > 0);
+
+	pixmp_ip->width =3D event.width;
+	pixmp_ip->height =3D event.height;
+
+	pixmp_op->width =3D ALIGN(event.width, 128);
+	pixmp_op->height =3D ALIGN(event.height, 32);
+	pixmp_op->plane_fmt[0].bytesperline =3D ALIGN(event.width, 128);
+	pixmp_op->plane_fmt[0].sizeimage =3D iris_get_buffer_size(inst, BUF_OUTPU=
T);
+
+	matrix_coeff =3D  FIELD_GET(GENMASK(7, 0), event.colour_space);
+	transfer_char =3D FIELD_GET(GENMASK(15, 8), event.colour_space);
+	primaries =3D FIELD_GET(GENMASK(23, 16), event.colour_space);
+	colour_description_present_flag =3D FIELD_GET(GENMASK(24, 24), event.colo=
ur_space);
+	full_range =3D FIELD_GET(GENMASK(25, 25), event.colour_space);
+	video_signal_type_present_flag =3D FIELD_GET(GENMASK(29, 29), event.colou=
r_space);
+
+	pixmp_op->colorspace =3D V4L2_COLORSPACE_DEFAULT;
+	pixmp_op->xfer_func =3D V4L2_XFER_FUNC_DEFAULT;
+	pixmp_op->ycbcr_enc =3D V4L2_YCBCR_ENC_DEFAULT;
+	pixmp_op->quantization =3D V4L2_QUANTIZATION_DEFAULT;
+
+	if (video_signal_type_present_flag) {
+		pixmp_op->quantization =3D
+			full_range ?
+			V4L2_QUANTIZATION_FULL_RANGE :
+			V4L2_QUANTIZATION_LIM_RANGE;
+		if (colour_description_present_flag) {
+			pixmp_op->colorspace =3D
+				iris_hfi_get_v4l2_color_primaries(primaries);
+			pixmp_op->xfer_func =3D
+				iris_hfi_get_v4l2_transfer_char(transfer_char);
+			pixmp_op->ycbcr_enc =3D
+				iris_hfi_get_v4l2_matrix_coefficients(matrix_coeff);
+		}
+	}
+
+	pixmp_ip->colorspace =3D pixmp_op->colorspace;
+	pixmp_ip->xfer_func =3D pixmp_op->xfer_func;
+	pixmp_ip->ycbcr_enc =3D pixmp_op->ycbcr_enc;
+	pixmp_ip->quantization =3D pixmp_op->quantization;
+
+	if (event.input_crop.width > 0 && event.input_crop.height > 0) {
+		inst->crop.left =3D event.input_crop.left;
+		inst->crop.top =3D event.input_crop.top;
+		inst->crop.width =3D event.input_crop.width;
+		inst->crop.height =3D event.input_crop.height;
+	} else {
+		inst->crop.left =3D 0;
+		inst->crop.top =3D 0;
+		inst->crop.width =3D event.width;
+		inst->crop.height =3D event.height;
+	}
+
+	inst->fw_min_count =3D event.buf_count;
+	inst->buffers[BUF_OUTPUT].min_count =3D iris_vpu_buf_count(inst, BUF_OUTP=
UT);
+	inst->buffers[BUF_OUTPUT].size =3D pixmp_op->plane_fmt[0].sizeimage;
+	ctrl =3D v4l2_ctrl_find(&inst->ctrl_handler, V4L2_CID_MIN_BUFFERS_FOR_CAP=
TURE);
+	if (ctrl)
+		v4l2_ctrl_s_ctrl(ctrl, inst->buffers[BUF_OUTPUT].min_count);
+
+	dst_q =3D v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+	dst_q->min_reqbufs_allocation =3D inst->buffers[BUF_OUTPUT].min_count;
+
+	if (event.bit_depth || !event.pic_struct) {
+		dev_err(core->dev, "unsupported content, bit depth: %x, pic_struct =3D %=
x\n",
+			event.bit_depth, event.pic_struct);
+		iris_inst_change_state(inst, IRIS_INST_ERROR);
+	}
+}
+
+static void iris_hfi_gen1_event_seq_changed(struct iris_inst *inst,
+					    struct hfi_msg_event_notify_pkt *pkt)
+{
+	struct hfi_session_flush_pkt flush_pkt;
+	u32 num_properties_changed;
+	int ret;
+
+	ret =3D iris_inst_sub_state_change_drc(inst);
+	if (ret)
+		return;
+
+	switch (pkt->event_data1) {
+	case HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUF_RESOURCES:
+	case HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUF_RESOURCES:
+		break;
+	default:
+		iris_inst_change_state(inst, IRIS_INST_ERROR);
+		return;
+	}
+
+	num_properties_changed =3D pkt->event_data2;
+	if (!num_properties_changed) {
+		iris_inst_change_state(inst, IRIS_INST_ERROR);
+		return;
+	}
+
+	iris_hfi_gen1_read_changed_params(inst, pkt);
+
+	if (inst->state !=3D IRIS_INST_ERROR) {
+		reinit_completion(&inst->flush_completion);
+
+		flush_pkt.shdr.hdr.size =3D sizeof(struct hfi_session_flush_pkt);
+		flush_pkt.shdr.hdr.pkt_type =3D HFI_CMD_SESSION_FLUSH;
+		flush_pkt.shdr.session_id =3D inst->session_id;
+		flush_pkt.flush_type =3D HFI_FLUSH_OUTPUT;
+		iris_hfi_queue_cmd_write(inst->core, &flush_pkt, flush_pkt.shdr.hdr.size=
);
+	}
+
+	iris_vdec_src_change(inst);
+	iris_inst_sub_state_change_drc_last(inst);
+}
=20
 static void
 iris_hfi_gen1_sys_event_notify(struct iris_core *core, void *packet)
@@ -66,6 +271,9 @@ static void iris_hfi_gen1_session_event_notify(struct ir=
is_inst *inst, void *pac
 	case HFI_EVENT_SESSION_ERROR:
 		iris_hfi_gen1_event_session_error(inst, pkt);
 		break;
+	case HFI_EVENT_SESSION_SEQUENCE_CHANGED:
+		iris_hfi_gen1_event_seq_changed(inst, pkt);
+		break;
 	default:
 		break;
 	}
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
index 8a9f2b5517ad..42cd57d5e3b1 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
@@ -19,8 +19,11 @@
 #define HFI_CMD_STOP				0x01000006
 #define HFI_CMD_BUFFER				0x01000009
 #define HFI_CMD_SUBSCRIBE_MODE			0x0100000B
+#define HFI_CMD_SETTINGS_CHANGE			0x0100000C
 #define HFI_CMD_END				0x01FFFFFF
=20
+#define HFI_BITMASK_BITSTREAM_WIDTH		0xffff0000
+#define HFI_BITMASK_BITSTREAM_HEIGHT		0x0000ffff
 #define HFI_BITMASK_FRAME_MBS_ONLY_FLAG		0x00000001
=20
 #define HFI_PROP_BEGIN				0x03000000
@@ -75,6 +78,7 @@
 #define HFI_INFO_UNSUPPORTED			0x06000001
 #define HFI_INFO_DATA_CORRUPT			0x06000002
 #define HFI_INFO_BUFFER_OVERFLOW		0x06000004
+#define HFI_INFO_HFI_FLAG_PSC_LAST		0x06000007
 #define HFI_INFORMATION_END			0x06FFFFFF
=20
 enum hfi_property_mode_type {
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c b/dr=
ivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
index e8d8caeef021..c7552e041138 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
@@ -8,6 +8,8 @@
 #include "iris_hfi_gen2.h"
 #include "iris_hfi_gen2_defines.h"
 #include "iris_hfi_gen2_packet.h"
+#include "iris_vdec.h"
+#include "iris_vpu_buffer.h"
 #include "iris_vpu_common.h"
=20
 struct iris_hfi_gen2_core_hfi_range {
@@ -199,6 +201,10 @@ static int iris_hfi_gen2_handle_session_info(struct ir=
is_inst *inst,
 		info =3D "buffer overflow";
 		inst_hfi_gen2->hfi_frame_info.overflow =3D 1;
 		break;
+	case HFI_INFO_HFI_FLAG_PSC_LAST:
+		info =3D "drc last flag";
+		ret =3D iris_inst_sub_state_change_drc_last(inst);
+		break;
 	default:
 		info =3D "unknown";
 		break;
@@ -329,6 +335,13 @@ static int iris_hfi_gen2_handle_output_buffer(struct i=
ris_inst *inst,
 	struct v4l2_m2m_buffer *m2m_buffer, *n;
 	struct iris_buffer *buf;
 	bool found =3D false;
+	int ret;
+
+	if (hfi_buffer->flags & HFI_BUF_FW_FLAG_PSC_LAST) {
+		ret =3D iris_inst_sub_state_change_drc_last(inst);
+		if (ret)
+			return ret;
+	}
=20
 	v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, m2m_buffer, n) {
 		buf =3D to_iris_buffer(&m2m_buffer->vb);
@@ -440,6 +453,115 @@ static int iris_hfi_gen2_handle_session_buffer(struct=
 iris_inst *inst,
 		return iris_hfi_gen2_handle_release_internal_buffer(inst, buffer);
 }
=20
+static void iris_hfi_gen2_read_input_subcr_params(struct iris_inst *inst)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	struct v4l2_pix_format_mplane *pixmp_ip =3D &inst->fmt_src->fmt.pix_mp;
+	struct v4l2_pix_format_mplane *pixmp_op =3D &inst->fmt_dst->fmt.pix_mp;
+	u32 primaries, matrix_coeff, transfer_char;
+	struct hfi_subscription_params subsc_params;
+	u32 colour_description_present_flag;
+	u32 video_signal_type_present_flag;
+	struct iris_core *core =3D inst->core;
+	u32 full_range, width, height;
+	struct vb2_queue *dst_q;
+	struct v4l2_ctrl *ctrl;
+
+	subsc_params =3D inst_hfi_gen2->src_subcr_params;
+	width =3D (subsc_params.bitstream_resolution &
+		HFI_BITMASK_BITSTREAM_WIDTH) >> 16;
+	height =3D subsc_params.bitstream_resolution &
+		HFI_BITMASK_BITSTREAM_HEIGHT;
+
+	pixmp_ip->width =3D width;
+	pixmp_ip->height =3D height;
+
+	pixmp_op->width =3D ALIGN(width, 128);
+	pixmp_op->height =3D ALIGN(height, 32);
+	pixmp_op->plane_fmt[0].bytesperline =3D ALIGN(width, 128);
+	pixmp_op->plane_fmt[0].sizeimage =3D iris_get_buffer_size(inst, BUF_OUTPU=
T);
+
+	matrix_coeff =3D subsc_params.color_info & 0xFF;
+	transfer_char =3D (subsc_params.color_info & 0xFF00) >> 8;
+	primaries =3D (subsc_params.color_info & 0xFF0000) >> 16;
+	colour_description_present_flag =3D
+		(subsc_params.color_info & 0x1000000) >> 24;
+	full_range =3D (subsc_params.color_info & 0x2000000) >> 25;
+	video_signal_type_present_flag =3D
+		(subsc_params.color_info & 0x20000000) >> 29;
+
+	pixmp_op->colorspace =3D V4L2_COLORSPACE_DEFAULT;
+	pixmp_op->xfer_func =3D V4L2_XFER_FUNC_DEFAULT;
+	pixmp_op->ycbcr_enc =3D V4L2_YCBCR_ENC_DEFAULT;
+	pixmp_op->quantization =3D V4L2_QUANTIZATION_DEFAULT;
+
+	if (video_signal_type_present_flag) {
+		pixmp_op->quantization =3D
+			full_range ?
+			V4L2_QUANTIZATION_FULL_RANGE :
+			V4L2_QUANTIZATION_LIM_RANGE;
+		if (colour_description_present_flag) {
+			pixmp_op->colorspace =3D
+				iris_hfi_get_v4l2_color_primaries(primaries);
+			pixmp_op->xfer_func =3D
+				iris_hfi_get_v4l2_transfer_char(transfer_char);
+			pixmp_op->ycbcr_enc =3D
+				iris_hfi_get_v4l2_matrix_coefficients(matrix_coeff);
+		}
+	}
+
+	pixmp_ip->colorspace =3D pixmp_op->colorspace;
+	pixmp_ip->xfer_func =3D pixmp_op->xfer_func;
+	pixmp_ip->ycbcr_enc =3D pixmp_op->ycbcr_enc;
+	pixmp_ip->quantization =3D pixmp_op->quantization;
+
+	inst->crop.top =3D subsc_params.crop_offsets[0] & 0xFFFF;
+	inst->crop.left =3D (subsc_params.crop_offsets[0] >> 16) & 0xFFFF;
+	inst->crop.height =3D pixmp_ip->height -
+		(subsc_params.crop_offsets[1] & 0xFFFF) - inst->crop.top;
+	inst->crop.width =3D pixmp_ip->width -
+		((subsc_params.crop_offsets[1] >> 16) & 0xFFFF) - inst->crop.left;
+
+	inst->fw_caps[PROFILE].value =3D subsc_params.profile;
+	inst->fw_caps[LEVEL].value =3D subsc_params.level;
+	inst->fw_caps[POC].value =3D subsc_params.pic_order_cnt;
+
+	if (subsc_params.bit_depth !=3D BIT_DEPTH_8 ||
+	    !(subsc_params.coded_frames & HFI_BITMASK_FRAME_MBS_ONLY_FLAG)) {
+		dev_err(core->dev, "unsupported content, bit depth: %x, pic_struct =3D %=
x\n",
+			subsc_params.bit_depth, subsc_params.coded_frames);
+		iris_inst_change_state(inst, IRIS_INST_ERROR);
+	}
+
+	inst->fw_min_count =3D subsc_params.fw_min_count;
+	inst->buffers[BUF_OUTPUT].min_count =3D iris_vpu_buf_count(inst, BUF_OUTP=
UT);
+	inst->buffers[BUF_OUTPUT].size =3D pixmp_op->plane_fmt[0].sizeimage;
+	ctrl =3D v4l2_ctrl_find(&inst->ctrl_handler, V4L2_CID_MIN_BUFFERS_FOR_CAP=
TURE);
+	if (ctrl)
+		v4l2_ctrl_s_ctrl(ctrl, inst->buffers[BUF_OUTPUT].min_count);
+
+	dst_q =3D v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+	dst_q->min_reqbufs_allocation =3D inst->buffers[BUF_OUTPUT].min_count;
+}
+
+static int iris_hfi_gen2_handle_src_change(struct iris_inst *inst,
+					   struct iris_hfi_packet *pkt)
+{
+	int ret;
+
+	if (pkt->port !=3D HFI_PORT_BITSTREAM)
+		return 0;
+
+	ret =3D iris_inst_sub_state_change_drc(inst);
+	if (ret)
+		return ret;
+
+	iris_hfi_gen2_read_input_subcr_params(inst);
+	iris_vdec_src_change(inst);
+
+	return 0;
+}
+
 static int iris_hfi_gen2_handle_session_command(struct iris_inst *inst,
 						struct iris_hfi_packet *pkt)
 {
@@ -455,6 +577,9 @@ static int iris_hfi_gen2_handle_session_command(struct =
iris_inst *inst,
 	case HFI_CMD_BUFFER:
 		ret =3D iris_hfi_gen2_handle_session_buffer(inst, pkt);
 		break;
+	case HFI_CMD_SETTINGS_CHANGE:
+		ret =3D iris_hfi_gen2_handle_src_change(inst, pkt);
+		break;
 	default:
 		break;
 	}
@@ -588,16 +713,61 @@ static int iris_hfi_gen2_handle_system_response(struc=
t iris_core *core,
 	return 0;
 }
=20
+static void iris_hfi_gen2_init_src_change_param(struct iris_inst *inst)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	struct v4l2_pix_format_mplane *pixmp_ip =3D &inst->fmt_src->fmt.pix_mp;
+	struct v4l2_pix_format_mplane *pixmp_op =3D &inst->fmt_dst->fmt.pix_mp;
+	u32 bottom_offset =3D (pixmp_ip->height - inst->crop.height);
+	u32 right_offset =3D (pixmp_ip->width - inst->crop.width);
+	struct hfi_subscription_params *subsc_params;
+	u32 primaries, matrix_coeff, transfer_char;
+	u32 colour_description_present_flag =3D 0;
+	u32 video_signal_type_present_flag =3D 0;
+	u32 full_range, video_format =3D 0;
+	u32 left_offset =3D inst->crop.left;
+	u32 top_offset =3D inst->crop.top;
+
+	subsc_params =3D &inst_hfi_gen2->src_subcr_params;
+	subsc_params->bitstream_resolution =3D
+		pixmp_ip->width << 16 | pixmp_ip->height;
+	subsc_params->crop_offsets[0] =3D
+			left_offset << 16 | top_offset;
+	subsc_params->crop_offsets[1] =3D
+			right_offset << 16 | bottom_offset;
+	subsc_params->fw_min_count =3D inst->buffers[BUF_OUTPUT].min_count;
+
+	primaries =3D iris_hfi_gen2_get_color_primaries(pixmp_op->colorspace);
+	matrix_coeff =3D iris_hfi_gen2_get_matrix_coefficients(pixmp_op->ycbcr_en=
c);
+	transfer_char =3D iris_hfi_gen2_get_transfer_char(pixmp_op->xfer_func);
+	full_range =3D pixmp_op->quantization =3D=3D V4L2_QUANTIZATION_FULL_RANGE=
 ? 1 : 0;
+	subsc_params->color_info =3D
+		iris_hfi_gen2_get_color_info(matrix_coeff, transfer_char, primaries,
+					     colour_description_present_flag,
+					     full_range, video_format,
+					     video_signal_type_present_flag);
+
+	subsc_params->profile =3D inst->fw_caps[PROFILE].value;
+	subsc_params->level =3D inst->fw_caps[LEVEL].value;
+	subsc_params->pic_order_cnt =3D inst->fw_caps[POC].value;
+	subsc_params->bit_depth =3D inst->fw_caps[BIT_DEPTH].value;
+	if (inst->fw_caps[CODED_FRAMES].value =3D=3D
+			CODED_FRAMES_PROGRESSIVE)
+		subsc_params->coded_frames =3D HFI_BITMASK_FRAME_MBS_ONLY_FLAG;
+	else
+		subsc_params->coded_frames =3D 0;
+}
+
 static int iris_hfi_gen2_handle_session_response(struct iris_core *core,
 						 struct iris_hfi_header *hdr)
 {
+	u8 *pkt =3D (u8 *)((u8 *)hdr + sizeof(*hdr));
 	struct iris_inst_hfi_gen2 *inst_hfi_gen2;
 	struct iris_hfi_packet *packet;
 	struct iris_inst *inst;
 	bool dequeue =3D false;
 	int ret =3D 0;
 	u32 i, j;
-	u8 *pkt;
 	static const struct iris_hfi_gen2_inst_hfi_range range[] =3D {
 		{HFI_SESSION_ERROR_BEGIN, HFI_SESSION_ERROR_END,
 		 iris_hfi_gen2_handle_session_error},
@@ -617,6 +787,17 @@ static int iris_hfi_gen2_handle_session_response(struc=
t iris_core *core,
 	inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
 	memset(&inst_hfi_gen2->hfi_frame_info, 0, sizeof(struct iris_hfi_frame_in=
fo));
=20
+	for (i =3D 0; i < hdr->num_packets; i++) {
+		packet =3D (struct iris_hfi_packet *)pkt;
+		if (packet->type =3D=3D HFI_CMD_SETTINGS_CHANGE) {
+			if (packet->port =3D=3D HFI_PORT_BITSTREAM) {
+				iris_hfi_gen2_init_src_change_param(inst);
+				break;
+			}
+		}
+		pkt +=3D packet->size;
+	}
+
 	pkt =3D (u8 *)((u8 *)hdr + sizeof(*hdr));
 	for (i =3D 0; i < ARRAY_SIZE(range); i++) {
 		pkt =3D (u8 *)((u8 *)hdr + sizeof(*hdr));
diff --git a/drivers/media/platform/qcom/iris/iris_instance.h b/drivers/med=
ia/platform/qcom/iris/iris_instance.h
index 2886491ad59f..89fb63644311 100644
--- a/drivers/media/platform/qcom/iris/iris_instance.h
+++ b/drivers/media/platform/qcom/iris/iris_instance.h
@@ -31,6 +31,7 @@
  * @buffers: array of different iris buffers
  * @fw_min_count: minimnum count of buffers needed by fw
  * @state: instance state
+ * @sub_state: instance sub state
  * @once_per_session_set: boolean to set once per session property
  * @m2m_dev:	a reference to m2m device structure
  * @m2m_ctx:	a reference to m2m context structure
@@ -57,6 +58,7 @@ struct iris_inst {
 	struct iris_buffers		buffers[BUF_TYPE_MAX];
 	u32				fw_min_count;
 	enum iris_inst_state		state;
+	enum iris_inst_sub_state	sub_state;
 	bool				once_per_session_set;
 	struct v4l2_m2m_dev		*m2m_dev;
 	struct v4l2_m2m_ctx		*m2m_ctx;
diff --git a/drivers/media/platform/qcom/iris/iris_state.c b/drivers/media/=
platform/qcom/iris/iris_state.c
index 44362e8fe18f..aad7e734d5c8 100644
--- a/drivers/media/platform/qcom/iris/iris_state.c
+++ b/drivers/media/platform/qcom/iris/iris_state.c
@@ -102,3 +102,67 @@ int iris_inst_state_change_streamoff(struct iris_inst =
*inst, u32 plane)
=20
 	return iris_inst_change_state(inst, new_state);
 }
+
+int iris_inst_change_sub_state(struct iris_inst *inst,
+			       enum iris_inst_sub_state clear_sub_state,
+			       enum iris_inst_sub_state set_sub_state)
+{
+	enum iris_inst_sub_state prev_sub_state;
+
+	if (inst->state =3D=3D IRIS_INST_ERROR)
+		return 0;
+
+	if (!clear_sub_state && !set_sub_state)
+		return 0;
+
+	if ((clear_sub_state & set_sub_state) ||
+	    set_sub_state > IRIS_INST_MAX_SUB_STATE_VALUE ||
+	    clear_sub_state > IRIS_INST_MAX_SUB_STATE_VALUE)
+		return -EINVAL;
+
+	prev_sub_state =3D inst->sub_state;
+
+	inst->sub_state |=3D set_sub_state;
+	inst->sub_state &=3D ~clear_sub_state;
+
+	if (inst->sub_state !=3D prev_sub_state)
+		dev_dbg(inst->core->dev, "sub_state changed from %x to %x\n",
+			prev_sub_state, inst->sub_state);
+
+	return 0;
+}
+
+int iris_inst_sub_state_change_drc(struct iris_inst *inst)
+{
+	enum iris_inst_sub_state set_sub_state =3D 0;
+
+	if (inst->sub_state & IRIS_INST_SUB_DRC)
+		return -EINVAL;
+
+	if (inst->state =3D=3D IRIS_INST_INPUT_STREAMING ||
+	    inst->state =3D=3D IRIS_INST_INIT)
+		set_sub_state =3D IRIS_INST_SUB_FIRST_IPSC | IRIS_INST_SUB_INPUT_PAUSE;
+	else
+		set_sub_state =3D IRIS_INST_SUB_DRC | IRIS_INST_SUB_INPUT_PAUSE;
+
+	return iris_inst_change_sub_state(inst, 0, set_sub_state);
+}
+
+int iris_inst_sub_state_change_drc_last(struct iris_inst *inst)
+{
+	enum iris_inst_sub_state set_sub_state;
+
+	if (inst->sub_state & IRIS_INST_SUB_DRC_LAST)
+		return -EINVAL;
+
+	if (!(inst->sub_state & IRIS_INST_SUB_DRC) ||
+	    !(inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE))
+		return -EINVAL;
+
+	if (inst->sub_state & IRIS_INST_SUB_FIRST_IPSC)
+		return 0;
+
+	set_sub_state =3D IRIS_INST_SUB_DRC_LAST | IRIS_INST_SUB_OUTPUT_PAUSE;
+
+	return iris_inst_change_sub_state(inst, 0, set_sub_state);
+}
diff --git a/drivers/media/platform/qcom/iris/iris_state.h b/drivers/media/=
platform/qcom/iris/iris_state.h
index 0bf9d0e063ac..b5f0826142f0 100644
--- a/drivers/media/platform/qcom/iris/iris_state.h
+++ b/drivers/media/platform/qcom/iris/iris_state.h
@@ -91,9 +91,42 @@ enum iris_inst_state {
 	IRIS_INST_ERROR,
 };
=20
+#define IRIS_INST_SUB_STATES		8
+#define IRIS_INST_MAX_SUB_STATE_VALUE	((1 << IRIS_INST_SUB_STATES) - 1)
+
+/**
+ * enum iris_inst_sub_state
+ *
+ * @IRIS_INST_SUB_FIRST_IPSC: indicates source change is received from fir=
mware
+ *			     when output port is not yet streaming.
+ * @IRIS_INST_SUB_DRC: indicates source change is received from firmware
+ *		      when output port is streaming and source change event is
+ *		      sent to client.
+ * @IRIS_INST_SUB_DRC_LAST: indicates last buffer is received from firmware
+ *                         as part of source change.
+ * @IRIS_INST_SUB_INPUT_PAUSE: source change is received form firmware. Th=
is
+ *                            indicates that firmware is paused to process
+ *                            any further input frames.
+ * @IRIS_INST_SUB_OUTPUT_PAUSE: last buffer is received form firmware as p=
art
+ *                             of drc sequence. This indicates that
+ *                             firmware is paused to process any further o=
utput frames.
+ */
+enum iris_inst_sub_state {
+	IRIS_INST_SUB_FIRST_IPSC	=3D BIT(0),
+	IRIS_INST_SUB_DRC		=3D BIT(1),
+	IRIS_INST_SUB_DRC_LAST		=3D BIT(2),
+	IRIS_INST_SUB_INPUT_PAUSE	=3D BIT(3),
+	IRIS_INST_SUB_OUTPUT_PAUSE	=3D BIT(4),
+};
+
 int iris_inst_change_state(struct iris_inst *inst,
 			   enum iris_inst_state request_state);
+int iris_inst_change_sub_state(struct iris_inst *inst,
+			       enum iris_inst_sub_state clear_sub_state,
+			       enum iris_inst_sub_state set_sub_state);
 int iris_inst_state_change_streamon(struct iris_inst *inst, u32 plane);
 int iris_inst_state_change_streamoff(struct iris_inst *inst, u32 plane);
+int iris_inst_sub_state_change_drc(struct iris_inst *inst);
+int iris_inst_sub_state_change_drc_last(struct iris_inst *inst);
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_vb2.c b/drivers/media/pl=
atform/qcom/iris/iris_vb2.c
index 770e51f9ef91..3b94011533e8 100644
--- a/drivers/media/platform/qcom/iris/iris_vb2.c
+++ b/drivers/media/platform/qcom/iris/iris_vb2.c
@@ -4,6 +4,7 @@
  */
=20
 #include <media/videobuf2-dma-contig.h>
+#include <media/v4l2-event.h>
 #include <media/v4l2-mem2mem.h>
=20
 #include "iris_instance.h"
@@ -180,6 +181,7 @@ int iris_vb2_buf_out_validate(struct vb2_buffer *vb)
=20
 void iris_vb2_buf_queue(struct vb2_buffer *vb2)
 {
+	static const struct v4l2_event eos =3D { .type =3D V4L2_EVENT_EOS };
 	struct vb2_v4l2_buffer *vbuf =3D to_vb2_v4l2_buffer(vb2);
 	struct v4l2_m2m_ctx *m2m_ctx;
 	struct iris_inst *inst;
@@ -203,6 +205,22 @@ void iris_vb2_buf_queue(struct vb2_buffer *vb2)
 		goto exit;
 	}
=20
+	if (V4L2_TYPE_IS_CAPTURE(vb2->vb2_queue->type)) {
+		if (inst->sub_state & IRIS_INST_SUB_DRC &&
+		    inst->sub_state & IRIS_INST_SUB_DRC_LAST) {
+			vbuf->flags |=3D V4L2_BUF_FLAG_LAST;
+			vbuf->sequence =3D inst->sequence_cap++;
+			vbuf->field =3D V4L2_FIELD_NONE;
+			vb2_set_plane_payload(vb2, 0, 0);
+			v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
+			if (!v4l2_m2m_has_stopped(m2m_ctx)) {
+				v4l2_event_queue_fh(&inst->fh, &eos);
+				v4l2_m2m_mark_stopped(m2m_ctx);
+			}
+			goto exit;
+		}
+	}
+
 	v4l2_m2m_buf_queue(m2m_ctx, vbuf);
=20
 	ret =3D iris_vdec_qbuf(inst, vbuf);
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/p=
latform/qcom/iris/iris_vdec.c
index d6b092314b34..1da277ed6cb3 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.c
+++ b/drivers/media/platform/qcom/iris/iris_vdec.c
@@ -223,6 +223,21 @@ int iris_vdec_subscribe_event(struct iris_inst *inst, =
const struct v4l2_event_su
 	return ret;
 }
=20
+void iris_vdec_src_change(struct iris_inst *inst)
+{
+	struct v4l2_m2m_ctx *m2m_ctx =3D inst->m2m_ctx;
+	struct v4l2_event event =3D {0};
+	struct vb2_queue *src_q;
+
+	src_q =3D v4l2_m2m_get_src_vq(m2m_ctx);
+	if (!vb2_is_streaming(src_q))
+		return;
+
+	event.type =3D V4L2_EVENT_SOURCE_CHANGE;
+	event.u.src_change.changes =3D V4L2_EVENT_SRC_CH_RESOLUTION;
+	v4l2_event_queue_fh(&inst->fh, &event);
+}
+
 static int iris_vdec_get_num_queued_buffers(struct iris_inst *inst,
 					    enum iris_buffer_type type)
 {
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.h b/drivers/media/p=
latform/qcom/iris/iris_vdec.h
index 998d4970a42b..dfcc2089a1ef 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.h
+++ b/drivers/media/platform/qcom/iris/iris_vdec.h
@@ -14,6 +14,7 @@ int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l=
2_fmtdesc *f);
 int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f);
 int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f);
 int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_ev=
ent_subscription *sub);
+void iris_vdec_src_change(struct iris_inst *inst);
 int iris_vdec_streamon_input(struct iris_inst *inst);
 int iris_vdec_streamon_output(struct iris_inst *inst);
 int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf);

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 B05EE237A34;
	Fri,  7 Feb 2025 07:57: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=1738915062; cv=none;
 b=EgBfgwtZKgxfJkuRJtB939ruk9wzWZfTjgdCIIhCwlo0WMC7GOL76ApW3XdK+LtsYz08idhar2053tASQ1O63FNKiYQPNpBjQUFysSnBpMTR6itLeMO7rnGbtES3Z688rvnqX0yfY6EoamFij9qcKOd5Dp6Scme4YxKngdVkYHU=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738915062; c=relaxed/simple;
	bh=eN8rGck4lknR8/w2rfWpFnUvzoGX5UiFCLMZrzg9znc=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=l0xu/xgEYUTkz7Ozs/Dt3P12huglPTzhWb007YLhXc+chH/sRJvJFKG4ogUN7EZFV+LR83EX10Jx3Z+FoiP/1NZEVYenpoceaKTW61qGoYaDPwvWak5FwW6y+nVE/xfYXy4segip9Q4rIonlLdK2vKqrXBUOxUn2d7hZeBU6G2Y=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=CTw1+hjS; arc=none smtp.client-ip=205.220.180.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="CTw1+hjS"
Received: from pps.filterd (m0279869.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 5175GfO2021026;
	Fri, 7 Feb 2025 07:57:27 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	x0pO1yPds0r6DA7UhGIM0it18khrsgmZLof3iIkG9tA=; b=CTw1+hjSMKeNP9pE
	UX/fqQnhmys9qv4J9QpCYtrn++9E7yurpriGSI/hUy/3C3sVr1IB4MP05kJ54kTg
	/wTbLw+Sakhg5RtG4pg1q8s3zgX1RAo4vKtXShqxarvuPs2ydUXAc0pQ9hl5EZcB
	njm2vUYVJPLDzEOcM19IqRRUZhI7H5SGCqh1VB2VAEDCOvY9AGHayK2KKteVY2w0
	7B907lld1pksAZR+JqOr6mt6jX20UTnGcn3tHlfSo942tIoi6UEKJfDB36LkO07n
	KPWAFadGHJTrAj89zV2C4mkTNZBVU6gNZpBY1puWiTToVGK74KA/WM27BDaVLt3X
	qYmZWg==
Received: from nalasppmta02.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44nbvurby0-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:57:26 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA02.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177vPfc032239
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:57:25 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:57:19 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:25:02 +0530
Subject: [PATCH v10 22/28] media: iris: handle streamoff/on from client in
 dynamic resolution change
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-22-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914893; l=13334;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=eN8rGck4lknR8/w2rfWpFnUvzoGX5UiFCLMZrzg9znc=;
 b=z6Ei4fBXbgrSc6whhFl0FcGOsenElqNatQGTBiZLoCo7MrNwYNMLnMe/2ORCB0Rjrw2Ez87Kt
 2frL+kOnLH7B/IYLhw+RYU//kR9nLmn3gWRSVb8K8G/UelJ+tCbZui4
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-GUID: r1xNu8h0i5CbqoRazMhTS1e58s3qTrtb
X-Proofpoint-ORIG-GUID: r1xNu8h0i5CbqoRazMhTS1e58s3qTrtb
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 phishscore=0
 lowpriorityscore=0 malwarescore=0 adultscore=0 spamscore=0 impostorscore=0
 suspectscore=0 bulkscore=0 priorityscore=1501 clxscore=1015 mlxscore=0
 mlxlogscore=999 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070060

The decoder is stopped after it completes the dynamic resolution change
sequence. Handle VIDIOC_STREAMOFF() and VIDIOC_STREAMON() on the CAPTURE
queue to resume the decoding process.

Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 drivers/media/platform/qcom/iris/iris_buffer.c     | 58 ++++++++++++++++++
 drivers/media/platform/qcom/iris/iris_buffer.h     |  1 +
 drivers/media/platform/qcom/iris/iris_hfi_common.h |  2 +
 .../platform/qcom/iris/iris_hfi_gen1_command.c     | 10 ++++
 .../platform/qcom/iris/iris_hfi_gen1_defines.h     |  1 +
 .../platform/qcom/iris/iris_hfi_gen2_command.c     | 39 ++++++++++++
 .../platform/qcom/iris/iris_hfi_gen2_defines.h     |  2 +
 drivers/media/platform/qcom/iris/iris_vdec.c       | 69 ++++++++++++++++++=
+++-
 8 files changed, 179 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media=
/platform/qcom/iris/iris_buffer.c
index de1267c387f1..dc096e5e95bf 100644
--- a/drivers/media/platform/qcom/iris/iris_buffer.c
+++ b/drivers/media/platform/qcom/iris/iris_buffer.c
@@ -404,6 +404,47 @@ int iris_destroy_internal_buffers(struct iris_inst *in=
st, u32 plane)
 	return 0;
 }
=20
+static int iris_release_internal_buffers(struct iris_inst *inst,
+					 enum iris_buffer_type buffer_type)
+{
+	const struct iris_hfi_command_ops *hfi_ops =3D inst->core->hfi_ops;
+	struct iris_buffers *buffers =3D &inst->buffers[buffer_type];
+	struct iris_buffer *buffer, *next;
+	int ret;
+
+	list_for_each_entry_safe(buffer, next, &buffers->list, list) {
+		if (buffer->attr & BUF_ATTR_PENDING_RELEASE)
+			continue;
+		if (!(buffer->attr & BUF_ATTR_QUEUED))
+			continue;
+		ret =3D hfi_ops->session_release_buf(inst, buffer);
+		if (ret)
+			return ret;
+		buffer->attr |=3D BUF_ATTR_PENDING_RELEASE;
+	}
+
+	return 0;
+}
+
+static int iris_release_input_internal_buffers(struct iris_inst *inst)
+{
+	const struct iris_platform_data *platform_data =3D inst->core->iris_platf=
orm_data;
+	const u32 *internal_buf_type;
+	u32 internal_buffer_count, i;
+	int ret;
+
+	internal_buf_type =3D platform_data->dec_ip_int_buf_tbl;
+	internal_buffer_count =3D platform_data->dec_ip_int_buf_tbl_size;
+
+	for (i =3D 0; i < internal_buffer_count; i++) {
+		ret =3D iris_release_internal_buffers(inst, internal_buf_type[i]);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst)
 {
 	struct iris_buffers *buffers =3D &inst->buffers[BUF_PERSIST];
@@ -435,6 +476,23 @@ int iris_alloc_and_queue_persist_bufs(struct iris_inst=
 *inst)
 	return 0;
 }
=20
+int iris_alloc_and_queue_input_int_bufs(struct iris_inst *inst)
+{
+	int ret;
+
+	iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+
+	ret =3D iris_release_input_internal_buffers(inst);
+	if (ret)
+		return ret;
+
+	ret =3D iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPL=
ANE);
+	if (ret)
+		return ret;
+
+	return iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLAN=
E);
+}
+
 int iris_queue_deferred_buffers(struct iris_inst *inst, enum iris_buffer_t=
ype buf_type)
 {
 	struct v4l2_m2m_ctx *m2m_ctx =3D inst->m2m_ctx;
diff --git a/drivers/media/platform/qcom/iris/iris_buffer.h b/drivers/media=
/platform/qcom/iris/iris_buffer.h
index 2c7432a59906..c36b6347b077 100644
--- a/drivers/media/platform/qcom/iris/iris_buffer.h
+++ b/drivers/media/platform/qcom/iris/iris_buffer.h
@@ -108,6 +108,7 @@ int iris_queue_internal_buffers(struct iris_inst *inst,=
 u32 plane);
 int iris_destroy_internal_buffer(struct iris_inst *inst, struct iris_buffe=
r *buffer);
 int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane);
 int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst);
+int iris_alloc_and_queue_input_int_bufs(struct iris_inst *inst);
 int iris_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf);
 int iris_queue_deferred_buffers(struct iris_inst *inst, enum iris_buffer_t=
ype buf_type);
 int iris_vb2_buffer_done(struct iris_inst *inst, struct iris_buffer *buf);
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/m=
edia/platform/qcom/iris/iris_hfi_common.h
index 6241098dc31d..8e14a61c9be4 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_common.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h
@@ -118,6 +118,8 @@ struct iris_hfi_command_ops {
 	int (*session_start)(struct iris_inst *inst, u32 plane);
 	int (*session_queue_buf)(struct iris_inst *inst, struct iris_buffer *buff=
er);
 	int (*session_release_buf)(struct iris_inst *inst, struct iris_buffer *bu=
ffer);
+	int (*session_pause)(struct iris_inst *inst, u32 plane);
+	int (*session_resume_drc)(struct iris_inst *inst, u32 plane);
 	int (*session_stop)(struct iris_inst *inst, u32 plane);
 	int (*session_close)(struct iris_inst *inst);
 };
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen1_command.c
index 03f7e6ea4bf3..e0cb75a112e3 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
@@ -205,6 +205,15 @@ static int iris_hfi_gen1_session_stop(struct iris_inst=
 *inst, u32 plane)
 	return ret;
 }
=20
+static int iris_hfi_gen1_session_continue(struct iris_inst *inst, u32 plan=
e)
+{
+	struct hfi_session_pkt packet;
+
+	iris_hfi_gen1_packet_session_cmd(inst, &packet, HFI_CMD_SESSION_CONTINUE);
+
+	return iris_hfi_queue_cmd_write(inst->core, &packet, packet.shdr.hdr.size=
);
+}
+
 static int iris_hfi_gen1_queue_input_buffer(struct iris_inst *inst, struct=
 iris_buffer *buf)
 {
 	struct hfi_session_empty_buffer_compressed_pkt ip_pkt;
@@ -778,6 +787,7 @@ static const struct iris_hfi_command_ops iris_hfi_gen1_=
command_ops =3D {
 	.session_start =3D iris_hfi_gen1_session_start,
 	.session_queue_buf =3D iris_hfi_gen1_session_queue_buffer,
 	.session_release_buf =3D iris_hfi_gen1_session_unset_buffers,
+	.session_resume_drc =3D iris_hfi_gen1_session_continue,
 	.session_stop =3D iris_hfi_gen1_session_stop,
 	.session_close =3D iris_hfi_gen1_session_close,
 };
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
index 416e9a19a26f..c40e0a28b21f 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
@@ -34,6 +34,7 @@
 #define HFI_CMD_SESSION_FLUSH				0x211008
 #define HFI_CMD_SESSION_RELEASE_BUFFERS			0x21100b
 #define HFI_CMD_SESSION_RELEASE_RESOURCES		0x21100c
+#define HFI_CMD_SESSION_CONTINUE			0x21100d
=20
 #define HFI_ERR_SESSION_UNSUPPORTED_SETTING		0x1008
 #define HFI_ERR_SESSION_UNSUPPORTED_STREAM		0x100d
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen2_command.c
index cc75231f07f1..8efc6a70a57a 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
@@ -737,6 +737,43 @@ static int iris_hfi_gen2_session_stop(struct iris_inst=
 *inst, u32 plane)
 	return iris_wait_for_session_response(inst, false);
 }
=20
+static int iris_hfi_gen2_session_pause(struct iris_inst *inst, u32 plane)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+
+	iris_hfi_gen2_packet_session_command(inst,
+					     HFI_CMD_PAUSE,
+					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+					     HFI_HOST_FLAGS_INTR_REQUIRED),
+					     iris_hfi_gen2_get_port(plane),
+					     inst->session_id,
+					     HFI_PAYLOAD_NONE,
+					     NULL,
+					     0);
+
+	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
+					inst_hfi_gen2->packet->size);
+}
+
+static int iris_hfi_gen2_session_resume_drc(struct iris_inst *inst, u32 pl=
ane)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	u32 payload =3D HFI_CMD_SETTINGS_CHANGE;
+
+	iris_hfi_gen2_packet_session_command(inst,
+					     HFI_CMD_RESUME,
+					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+					     HFI_HOST_FLAGS_INTR_REQUIRED),
+					     iris_hfi_gen2_get_port(plane),
+					     inst->session_id,
+					     HFI_PAYLOAD_U32,
+					     &payload,
+					     sizeof(u32));
+
+	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
+					inst_hfi_gen2->packet->size);
+}
+
 static u32 iris_hfi_gen2_buf_type_from_driver(enum iris_buffer_type buffer=
_type)
 {
 	switch (buffer_type) {
@@ -860,6 +897,8 @@ static const struct iris_hfi_command_ops iris_hfi_gen2_=
command_ops =3D {
 	.session_start =3D iris_hfi_gen2_session_start,
 	.session_queue_buf =3D iris_hfi_gen2_session_queue_buffer,
 	.session_release_buf =3D iris_hfi_gen2_session_release_buffer,
+	.session_pause =3D iris_hfi_gen2_session_pause,
+	.session_resume_drc =3D iris_hfi_gen2_session_resume_drc,
 	.session_stop =3D iris_hfi_gen2_session_stop,
 	.session_close =3D iris_hfi_gen2_session_close,
 };
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
index 42cd57d5e3b1..620bcb90c35f 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
@@ -17,9 +17,11 @@
 #define HFI_CMD_CLOSE				0x01000004
 #define HFI_CMD_START				0x01000005
 #define HFI_CMD_STOP				0x01000006
+#define HFI_CMD_RESUME				0x01000008
 #define HFI_CMD_BUFFER				0x01000009
 #define HFI_CMD_SUBSCRIBE_MODE			0x0100000B
 #define HFI_CMD_SETTINGS_CHANGE			0x0100000C
+#define HFI_CMD_PAUSE				0x01000011
 #define HFI_CMD_END				0x01FFFFFF
=20
 #define HFI_BITMASK_BITSTREAM_WIDTH		0xffff0000
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/p=
latform/qcom/iris/iris_vdec.c
index 1da277ed6cb3..47a44978869b 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.c
+++ b/drivers/media/platform/qcom/iris/iris_vdec.c
@@ -357,13 +357,37 @@ int iris_vdec_session_streamoff(struct iris_inst *ins=
t, u32 plane)
 static int iris_vdec_process_streamon_input(struct iris_inst *inst)
 {
 	const struct iris_hfi_command_ops *hfi_ops =3D inst->core->hfi_ops;
+	enum iris_inst_sub_state set_sub_state =3D 0;
 	int ret;
=20
 	ret =3D hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
 	if (ret)
 		return ret;
=20
-	return iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_M=
PLANE);
+	if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
+		ret =3D iris_inst_change_sub_state(inst, IRIS_INST_SUB_INPUT_PAUSE, 0);
+		if (ret)
+			return ret;
+	}
+
+	if (inst->sub_state & IRIS_INST_SUB_DRC ||
+	    inst->sub_state & IRIS_INST_SUB_FIRST_IPSC) {
+		if (!(inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE)) {
+			if (hfi_ops->session_pause) {
+				ret =3D hfi_ops->session_pause(inst,
+							     V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+				if (ret)
+					return ret;
+			}
+			set_sub_state =3D IRIS_INST_SUB_INPUT_PAUSE;
+		}
+	}
+
+	ret =3D iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_=
MPLANE);
+	if (ret)
+		return ret;
+
+	return iris_inst_change_sub_state(inst, 0, set_sub_state);
 }
=20
 int iris_vdec_streamon_input(struct iris_inst *inst)
@@ -398,13 +422,52 @@ int iris_vdec_streamon_input(struct iris_inst *inst)
 static int iris_vdec_process_streamon_output(struct iris_inst *inst)
 {
 	const struct iris_hfi_command_ops *hfi_ops =3D inst->core->hfi_ops;
-	int ret;
+	enum iris_inst_sub_state clear_sub_state =3D 0;
+	bool drc_active =3D false;
+	int ret =3D 0;
+
+	drc_active =3D inst->sub_state & IRIS_INST_SUB_DRC &&
+		inst->sub_state & IRIS_INST_SUB_DRC_LAST;
+
+	if (drc_active)
+		clear_sub_state =3D IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRC_LAST;
+
+	if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
+		ret =3D iris_alloc_and_queue_input_int_bufs(inst);
+		if (ret)
+			return ret;
+		ret =3D iris_set_stage(inst, STAGE);
+		if (ret)
+			return ret;
+		ret =3D iris_set_pipe(inst, PIPE);
+		if (ret)
+			return ret;
+	}
+
+	if (inst->state =3D=3D IRIS_INST_INPUT_STREAMING &&
+	    inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
+		ret =3D hfi_ops->session_resume_drc(inst,
+						  V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+		if (ret)
+			return ret;
+		clear_sub_state |=3D IRIS_INST_SUB_INPUT_PAUSE;
+	}
+
+	if (inst->sub_state & IRIS_INST_SUB_FIRST_IPSC)
+		clear_sub_state |=3D IRIS_INST_SUB_FIRST_IPSC;
=20
 	ret =3D hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
 	if (ret)
 		return ret;
=20
-	return iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_=
MPLANE);
+	if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE)
+		clear_sub_state |=3D IRIS_INST_SUB_OUTPUT_PAUSE;
+
+	ret =3D iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE=
_MPLANE);
+	if (ret)
+		return ret;
+
+	return iris_inst_change_sub_state(inst, clear_sub_state, 0);
 }
=20
 int iris_vdec_streamon_output(struct iris_inst *inst)

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 B9AEA23F27B;
	Fri,  7 Feb 2025 07:57: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=1738915070; cv=none;
 b=Iie8GlfMBxa6L3IcfVNKbw4+d1eNKnBAIbdbwIlVULGoTKcdnIkkv6jy0hd0F3YZhaNgHr0rX33eRzBcdMtKXpgIojabad8ih0fAxp7Q64UrcUaYPDdVVKcbI78fjpRN9uZ/UhRwyHs62r/NCBtpVXKlPBrzst9WRZKDubjUq38=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738915070; c=relaxed/simple;
	bh=6+/1jA8bbGoJeBAd7tXdF8ZLN8Pk2E1dwjQIUW+y76k=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=AtVtgs0wTj2FRDQOM30K6gI+FVuxmgEFz2KcsqJGM4WNj6nhWz6JrmDChWrApHeXUlgythMhYg0g/CkqLb1SFJEki9ykIwWsSOYM0ylwVyYcx5Ghm7GOtR9SsQITYVAY7NjbXgw4sZm6kRdbv8aAi0LssDKeIQ5DD54QJHJB4sk=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=jHcsIg9o; arc=none smtp.client-ip=205.220.168.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="jHcsIg9o"
Received: from pps.filterd (m0279864.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 51770cjF014989;
	Fri, 7 Feb 2025 07:57:33 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	sw8J81OBLqCY8/IxOXq+vkC6+hChkbCo1UOmRJevw5I=; b=jHcsIg9ozSbnki8h
	8hnQF0+lVc371Gi6ou+aemjwGNkSO68RQEsGjj2DhUMhK3yzQmbfPeiaSXyAR9m1
	pNl8POLgB8oEoRS1TOtE+/mQVogxM2akm8O4jvx4NIOr4pMVUURq7H7+MmAgX7vv
	3FcEamGlHaZtgCJrkxYQUFCJFM92NYgpx55yWCRKrmlS740uVHTDelUUAjJ0UufP
	tRKaxCWuTN0U5uEIxC2sW2Rad65NZJ2lo7juNmnTrOdKwGBjqck1coQvpl4wu4GG
	4p1vx64dHo/NtQmo8EjHB1AS1in0FZEtYTF0jEBzgoiY7Cj+/7K5cFKKePBrX6ps
	qv/54A==
Received: from nalasppmta04.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44nddm84fp-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:57:32 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA04.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177vWLV010866
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:57:32 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:57:25 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:25:03 +0530
Subject: [PATCH v10 23/28] media: iris: add support for drain sequence
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-23-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914893; l=25315;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=6+/1jA8bbGoJeBAd7tXdF8ZLN8Pk2E1dwjQIUW+y76k=;
 b=pPgf9lFW7epfSXJJUo+BaKC/DFF/uQd6Z6pSQ6/+tIfJf8p06Jl3x2bDel9uLensVfnVdqUPr
 VCMenkEhiMHCYZKjBSXwYHrQnQZ9rPfG2cxgwk/jUD6+pIvpM3N1HS7
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-GUID: ZSGT7VfKxyS4V5QoyNa--PQfC3VF9ECp
X-Proofpoint-ORIG-GUID: ZSGT7VfKxyS4V5QoyNa--PQfC3VF9ECp
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 clxscore=1015 spamscore=0
 mlxlogscore=999 adultscore=0 priorityscore=1501 suspectscore=0
 lowpriorityscore=0 malwarescore=0 phishscore=0 mlxscore=0 bulkscore=0
 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070060

handle the V4L2_DEC_CMD_STOP by initiating a drain sequence on the
firmware. Process and decode all OUTPUT buffers, that are  queued by the
client, before the VIDIOC_DECODER_CMD() was issued and mark the last
buffer with the V4L2_BUF_FLAG_LAST flag. The decoder is stopped, after
processing the last buffer.

Resume the decoder when one of these operations are issued by the client:
- V4L2_DEC_CMD_START
- pair of VIDIOC_STREAMOFF() and VIDIOC_STREAMON() on the CAPTURE queue
- pair of VIDIOC_STREAMOFF() and VIDIOC_STREAMON() on the OUTPUT queue

Add the handling to resume decoding when client issues
V4L2_DEC_CMD_START to resume decoding after a source change is detected.

Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 drivers/media/platform/qcom/iris/iris_hfi_common.h |  2 +
 .../platform/qcom/iris/iris_hfi_gen1_command.c     | 13 ++++
 .../platform/qcom/iris/iris_hfi_gen1_defines.h     |  1 +
 .../platform/qcom/iris/iris_hfi_gen1_response.c    | 15 ++++
 .../platform/qcom/iris/iris_hfi_gen2_command.c     | 43 ++++++++++
 .../platform/qcom/iris/iris_hfi_gen2_defines.h     |  2 +
 .../platform/qcom/iris/iris_hfi_gen2_response.c    | 46 ++++++++++-
 drivers/media/platform/qcom/iris/iris_state.c      | 68 ++++++++++++++++
 drivers/media/platform/qcom/iris/iris_state.h      | 13 +++-
 drivers/media/platform/qcom/iris/iris_vb2.c        |  6 +-
 drivers/media/platform/qcom/iris/iris_vdec.c       | 91 ++++++++++++++++++=
+++-
 drivers/media/platform/qcom/iris/iris_vdec.h       |  2 +
 drivers/media/platform/qcom/iris/iris_vidc.c       | 35 +++++++++
 13 files changed, 329 insertions(+), 8 deletions(-)

diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/m=
edia/platform/qcom/iris/iris_hfi_common.h
index 8e14a61c9be4..b2c541367fc6 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_common.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h
@@ -121,6 +121,8 @@ struct iris_hfi_command_ops {
 	int (*session_pause)(struct iris_inst *inst, u32 plane);
 	int (*session_resume_drc)(struct iris_inst *inst, u32 plane);
 	int (*session_stop)(struct iris_inst *inst, u32 plane);
+	int (*session_drain)(struct iris_inst *inst, u32 plane);
+	int (*session_resume_drain)(struct iris_inst *inst, u32 plane);
 	int (*session_close)(struct iris_inst *inst);
 };
=20
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen1_command.c
index e0cb75a112e3..e1fbbb3c196d 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
@@ -368,6 +368,18 @@ static int iris_hfi_gen1_session_unset_buffers(struct =
iris_inst *inst, struct ir
 	return ret;
 }
=20
+static int iris_hfi_gen1_session_drain(struct iris_inst *inst, u32 plane)
+{
+	struct hfi_session_empty_buffer_compressed_pkt ip_pkt =3D {0};
+
+	ip_pkt.shdr.hdr.size =3D sizeof(struct hfi_session_empty_buffer_compresse=
d_pkt);
+	ip_pkt.shdr.hdr.pkt_type =3D HFI_CMD_SESSION_EMPTY_BUFFER;
+	ip_pkt.shdr.session_id =3D inst->session_id;
+	ip_pkt.flags =3D HFI_BUFFERFLAG_EOS;
+
+	return iris_hfi_queue_cmd_write(inst->core, &ip_pkt, ip_pkt.shdr.hdr.size=
);
+}
+
 static int
 iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_=
pkt *packet,
 					  struct iris_inst *inst, u32 ptype, void *pdata)
@@ -789,6 +801,7 @@ static const struct iris_hfi_command_ops iris_hfi_gen1_=
command_ops =3D {
 	.session_release_buf =3D iris_hfi_gen1_session_unset_buffers,
 	.session_resume_drc =3D iris_hfi_gen1_session_continue,
 	.session_stop =3D iris_hfi_gen1_session_stop,
+	.session_drain =3D iris_hfi_gen1_session_drain,
 	.session_close =3D iris_hfi_gen1_session_close,
 };
=20
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
index c40e0a28b21f..9f246816a286 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
@@ -49,6 +49,7 @@
 #define HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUF_RESOURCES 0x10000=
02
 #define HFI_EVENT_SESSION_SEQUENCE_CHANGED			   0x1000003
=20
+#define HFI_BUFFERFLAG_EOS				0x00000001
 #define HFI_BUFFERFLAG_TIMESTAMPINVALID			0x00000100
=20
 #define HFI_FLUSH_OUTPUT				0x1000002
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c b/dr=
ivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
index 3a47d9f39695..b72d503dd740 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
@@ -386,6 +386,7 @@ static void iris_hfi_gen1_session_ftb_done(struct iris_=
inst *inst, void *packet)
 	struct hfi_msg_session_fbd_uncompressed_plane0_pkt *pkt =3D packet;
 	struct v4l2_m2m_ctx *m2m_ctx =3D inst->m2m_ctx;
 	struct v4l2_m2m_buffer *m2m_buffer, *n;
+	struct hfi_session_flush_pkt flush_pkt;
 	u32 timestamp_hi =3D pkt->time_stamp_hi;
 	u32 timestamp_lo =3D pkt->time_stamp_lo;
 	struct iris_core *core =3D inst->core;
@@ -394,11 +395,25 @@ static void iris_hfi_gen1_session_ftb_done(struct iri=
s_inst *inst, void *packet)
 	u32 output_tag =3D pkt->output_tag;
 	struct iris_buffer *buf, *iter;
 	struct iris_buffers *buffers;
+	u32 hfi_flags =3D pkt->flags;
 	u32 offset =3D pkt->offset;
 	u64 timestamp_us =3D 0;
 	bool found =3D false;
 	u32 flags =3D 0;
=20
+	if ((hfi_flags & HFI_BUFFERFLAG_EOS) && !filled_len) {
+		reinit_completion(&inst->flush_completion);
+
+		flush_pkt.shdr.hdr.size =3D sizeof(struct hfi_session_flush_pkt);
+		flush_pkt.shdr.hdr.pkt_type =3D HFI_CMD_SESSION_FLUSH;
+		flush_pkt.shdr.session_id =3D inst->session_id;
+		flush_pkt.flush_type =3D HFI_FLUSH_OUTPUT;
+		iris_hfi_queue_cmd_write(core, &flush_pkt, flush_pkt.shdr.hdr.size);
+		iris_inst_sub_state_change_drain_last(inst);
+
+		return;
+	}
+
 	if (iris_split_mode_enabled(inst) && pkt->stream_id =3D=3D 0) {
 		buffers =3D &inst->buffers[BUF_DPB];
 		if (!buffers)
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen2_command.c
index 8efc6a70a57a..a908b41e2868 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
@@ -774,6 +774,47 @@ static int iris_hfi_gen2_session_resume_drc(struct iri=
s_inst *inst, u32 plane)
 					inst_hfi_gen2->packet->size);
 }
=20
+static int iris_hfi_gen2_session_resume_drain(struct iris_inst *inst, u32 =
plane)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+	u32 payload =3D HFI_CMD_DRAIN;
+
+	iris_hfi_gen2_packet_session_command(inst,
+					     HFI_CMD_RESUME,
+					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+					     HFI_HOST_FLAGS_INTR_REQUIRED),
+					     iris_hfi_gen2_get_port(plane),
+					     inst->session_id,
+					     HFI_PAYLOAD_U32,
+					     &payload,
+					     sizeof(u32));
+
+	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
+					inst_hfi_gen2->packet->size);
+}
+
+static int iris_hfi_gen2_session_drain(struct iris_inst *inst, u32 plane)
+{
+	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
+
+	if (!V4L2_TYPE_IS_OUTPUT(plane))
+		return 0;
+
+	iris_hfi_gen2_packet_session_command(inst,
+					     HFI_CMD_DRAIN,
+					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+					     HFI_HOST_FLAGS_INTR_REQUIRED |
+					     HFI_HOST_FLAGS_NON_DISCARDABLE),
+					     iris_hfi_gen2_get_port(plane),
+					     inst->session_id,
+					     HFI_PAYLOAD_NONE,
+					     NULL,
+					     0);
+
+	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
+					inst_hfi_gen2->packet->size);
+}
+
 static u32 iris_hfi_gen2_buf_type_from_driver(enum iris_buffer_type buffer=
_type)
 {
 	switch (buffer_type) {
@@ -900,6 +941,8 @@ static const struct iris_hfi_command_ops iris_hfi_gen2_=
command_ops =3D {
 	.session_pause =3D iris_hfi_gen2_session_pause,
 	.session_resume_drc =3D iris_hfi_gen2_session_resume_drc,
 	.session_stop =3D iris_hfi_gen2_session_stop,
+	.session_drain =3D iris_hfi_gen2_session_drain,
+	.session_resume_drain =3D iris_hfi_gen2_session_resume_drain,
 	.session_close =3D iris_hfi_gen2_session_close,
 };
=20
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
index 620bcb90c35f..806f8bb7f505 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
@@ -17,6 +17,7 @@
 #define HFI_CMD_CLOSE				0x01000004
 #define HFI_CMD_START				0x01000005
 #define HFI_CMD_STOP				0x01000006
+#define HFI_CMD_DRAIN				0x01000007
 #define HFI_CMD_RESUME				0x01000008
 #define HFI_CMD_BUFFER				0x01000009
 #define HFI_CMD_SUBSCRIBE_MODE			0x0100000B
@@ -80,6 +81,7 @@
 #define HFI_INFO_UNSUPPORTED			0x06000001
 #define HFI_INFO_DATA_CORRUPT			0x06000002
 #define HFI_INFO_BUFFER_OVERFLOW		0x06000004
+#define HFI_INFO_HFI_FLAG_DRAIN_LAST		0x06000006
 #define HFI_INFO_HFI_FLAG_PSC_LAST		0x06000007
 #define HFI_INFORMATION_END			0x06FFFFFF
=20
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c b/dr=
ivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
index c7552e041138..b75a01641d5d 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
@@ -201,6 +201,10 @@ static int iris_hfi_gen2_handle_session_info(struct ir=
is_inst *inst,
 		info =3D "buffer overflow";
 		inst_hfi_gen2->hfi_frame_info.overflow =3D 1;
 		break;
+	case HFI_INFO_HFI_FLAG_DRAIN_LAST:
+		info =3D "drain last flag";
+		ret =3D iris_inst_sub_state_change_drain_last(inst);
+		break;
 	case HFI_INFO_HFI_FLAG_PSC_LAST:
 		info =3D "drc last flag";
 		ret =3D iris_inst_sub_state_change_drc_last(inst);
@@ -337,6 +341,12 @@ static int iris_hfi_gen2_handle_output_buffer(struct i=
ris_inst *inst,
 	bool found =3D false;
 	int ret;
=20
+	if (hfi_buffer->flags & HFI_BUF_FW_FLAG_LAST) {
+		ret =3D iris_inst_sub_state_change_drain_last(inst);
+		if (ret)
+			return ret;
+	}
+
 	if (hfi_buffer->flags & HFI_BUF_FW_FLAG_PSC_LAST) {
 		ret =3D iris_inst_sub_state_change_drc_last(inst);
 		if (ret)
@@ -425,6 +435,21 @@ static int iris_hfi_gen2_handle_release_internal_buffe=
r(struct iris_inst *inst,
 	return ret;
 }
=20
+static int iris_hfi_gen2_handle_session_stop(struct iris_inst *inst,
+					     struct iris_hfi_packet *pkt)
+{
+	int ret =3D 0;
+
+	if (pkt->port =3D=3D HFI_PORT_RAW)
+		ret =3D iris_inst_sub_state_change_pause(inst, V4L2_BUF_TYPE_VIDEO_CAPTU=
RE_MPLANE);
+	else if (pkt->port =3D=3D HFI_PORT_BITSTREAM)
+		ret =3D iris_inst_sub_state_change_pause(inst, V4L2_BUF_TYPE_VIDEO_OUTPU=
T_MPLANE);
+
+	complete(&inst->completion);
+
+	return ret;
+}
+
 static int iris_hfi_gen2_handle_session_buffer(struct iris_inst *inst,
 					       struct iris_hfi_packet *pkt)
 {
@@ -453,6 +478,22 @@ static int iris_hfi_gen2_handle_session_buffer(struct =
iris_inst *inst,
 		return iris_hfi_gen2_handle_release_internal_buffer(inst, buffer);
 }
=20
+static int iris_hfi_gen2_handle_session_drain(struct iris_inst *inst,
+					      struct iris_hfi_packet *pkt)
+{
+	int ret =3D 0;
+
+	if (!(pkt->flags & HFI_FW_FLAGS_SUCCESS)) {
+		iris_inst_change_state(inst, IRIS_INST_ERROR);
+		return 0;
+	}
+
+	if (inst->sub_state & IRIS_INST_SUB_DRAIN)
+		ret =3D iris_inst_change_sub_state(inst, 0, IRIS_INST_SUB_INPUT_PAUSE);
+
+	return ret;
+}
+
 static void iris_hfi_gen2_read_input_subcr_params(struct iris_inst *inst)
 {
 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 =3D to_iris_inst_hfi_gen2(inst);
@@ -572,7 +613,7 @@ static int iris_hfi_gen2_handle_session_command(struct =
iris_inst *inst,
 		iris_hfi_gen2_handle_session_close(inst, pkt);
 		break;
 	case HFI_CMD_STOP:
-		complete(&inst->completion);
+		iris_hfi_gen2_handle_session_stop(inst, pkt);
 		break;
 	case HFI_CMD_BUFFER:
 		ret =3D iris_hfi_gen2_handle_session_buffer(inst, pkt);
@@ -580,6 +621,9 @@ static int iris_hfi_gen2_handle_session_command(struct =
iris_inst *inst,
 	case HFI_CMD_SETTINGS_CHANGE:
 		ret =3D iris_hfi_gen2_handle_src_change(inst, pkt);
 		break;
+	case HFI_CMD_DRAIN:
+		ret =3D iris_hfi_gen2_handle_session_drain(inst, pkt);
+		break;
 	default:
 		break;
 	}
diff --git a/drivers/media/platform/qcom/iris/iris_state.c b/drivers/media/=
platform/qcom/iris/iris_state.c
index aad7e734d5c8..f12306e735ec 100644
--- a/drivers/media/platform/qcom/iris/iris_state.c
+++ b/drivers/media/platform/qcom/iris/iris_state.c
@@ -3,6 +3,8 @@
  * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
  */
=20
+#include <media/v4l2-mem2mem.h>
+
 #include "iris_instance.h"
=20
 static bool iris_allow_inst_state_change(struct iris_inst *inst,
@@ -148,6 +150,21 @@ int iris_inst_sub_state_change_drc(struct iris_inst *i=
nst)
 	return iris_inst_change_sub_state(inst, 0, set_sub_state);
 }
=20
+int iris_inst_sub_state_change_drain_last(struct iris_inst *inst)
+{
+	enum iris_inst_sub_state set_sub_state;
+
+	if (inst->sub_state & IRIS_INST_SUB_DRAIN_LAST)
+		return -EINVAL;
+
+	if (!(inst->sub_state & IRIS_INST_SUB_DRAIN))
+		return -EINVAL;
+
+	set_sub_state =3D IRIS_INST_SUB_DRAIN_LAST | IRIS_INST_SUB_OUTPUT_PAUSE;
+
+	return iris_inst_change_sub_state(inst, 0, set_sub_state);
+}
+
 int iris_inst_sub_state_change_drc_last(struct iris_inst *inst)
 {
 	enum iris_inst_sub_state set_sub_state;
@@ -166,3 +183,54 @@ int iris_inst_sub_state_change_drc_last(struct iris_in=
st *inst)
=20
 	return iris_inst_change_sub_state(inst, 0, set_sub_state);
 }
+
+int iris_inst_sub_state_change_pause(struct iris_inst *inst, u32 plane)
+{
+	enum iris_inst_sub_state set_sub_state;
+
+	if (V4L2_TYPE_IS_OUTPUT(plane)) {
+		if (inst->sub_state & IRIS_INST_SUB_DRC &&
+		    !(inst->sub_state & IRIS_INST_SUB_DRC_LAST))
+			return -EINVAL;
+
+		if (inst->sub_state & IRIS_INST_SUB_DRAIN &&
+		    !(inst->sub_state & IRIS_INST_SUB_DRAIN_LAST))
+			return -EINVAL;
+
+		set_sub_state =3D IRIS_INST_SUB_INPUT_PAUSE;
+	} else {
+		set_sub_state =3D IRIS_INST_SUB_OUTPUT_PAUSE;
+	}
+
+	return iris_inst_change_sub_state(inst, 0, set_sub_state);
+}
+
+static inline bool iris_drc_pending(struct iris_inst *inst)
+{
+	return inst->sub_state & IRIS_INST_SUB_DRC &&
+		inst->sub_state & IRIS_INST_SUB_DRC_LAST;
+}
+
+static inline bool iris_drain_pending(struct iris_inst *inst)
+{
+	return inst->sub_state & IRIS_INST_SUB_DRAIN &&
+		inst->sub_state & IRIS_INST_SUB_DRAIN_LAST;
+}
+
+bool iris_allow_cmd(struct iris_inst *inst, u32 cmd)
+{
+	struct vb2_queue *src_q =3D v4l2_m2m_get_src_vq(inst->m2m_ctx);
+	struct vb2_queue *dst_q =3D v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+
+	if (cmd =3D=3D V4L2_DEC_CMD_START) {
+		if (vb2_is_streaming(src_q) || vb2_is_streaming(dst_q))
+			if (iris_drc_pending(inst) || iris_drain_pending(inst))
+				return true;
+	} else if (cmd =3D=3D V4L2_DEC_CMD_STOP) {
+		if (vb2_is_streaming(src_q))
+			if (inst->sub_state !=3D IRIS_INST_SUB_DRAIN)
+				return true;
+	}
+
+	return false;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_state.h b/drivers/media/=
platform/qcom/iris/iris_state.h
index b5f0826142f0..a5c0cad4a78c 100644
--- a/drivers/media/platform/qcom/iris/iris_state.h
+++ b/drivers/media/platform/qcom/iris/iris_state.h
@@ -104,6 +104,9 @@ enum iris_inst_state {
  *		      sent to client.
  * @IRIS_INST_SUB_DRC_LAST: indicates last buffer is received from firmware
  *                         as part of source change.
+ * @IRIS_INST_SUB_DRAIN: indicates drain is in progress.
+ * @IRIS_INST_SUB_DRAIN_LAST: indicates last buffer is received from firmw=
are
+ *                           as part of drain sequence.
  * @IRIS_INST_SUB_INPUT_PAUSE: source change is received form firmware. Th=
is
  *                            indicates that firmware is paused to process
  *                            any further input frames.
@@ -115,8 +118,10 @@ enum iris_inst_sub_state {
 	IRIS_INST_SUB_FIRST_IPSC	=3D BIT(0),
 	IRIS_INST_SUB_DRC		=3D BIT(1),
 	IRIS_INST_SUB_DRC_LAST		=3D BIT(2),
-	IRIS_INST_SUB_INPUT_PAUSE	=3D BIT(3),
-	IRIS_INST_SUB_OUTPUT_PAUSE	=3D BIT(4),
+	IRIS_INST_SUB_DRAIN		=3D BIT(3),
+	IRIS_INST_SUB_DRAIN_LAST	=3D BIT(4),
+	IRIS_INST_SUB_INPUT_PAUSE	=3D BIT(5),
+	IRIS_INST_SUB_OUTPUT_PAUSE	=3D BIT(6),
 };
=20
 int iris_inst_change_state(struct iris_inst *inst,
@@ -124,9 +129,13 @@ int iris_inst_change_state(struct iris_inst *inst,
 int iris_inst_change_sub_state(struct iris_inst *inst,
 			       enum iris_inst_sub_state clear_sub_state,
 			       enum iris_inst_sub_state set_sub_state);
+
 int iris_inst_state_change_streamon(struct iris_inst *inst, u32 plane);
 int iris_inst_state_change_streamoff(struct iris_inst *inst, u32 plane);
 int iris_inst_sub_state_change_drc(struct iris_inst *inst);
+int iris_inst_sub_state_change_drain_last(struct iris_inst *inst);
 int iris_inst_sub_state_change_drc_last(struct iris_inst *inst);
+int iris_inst_sub_state_change_pause(struct iris_inst *inst, u32 plane);
+bool iris_allow_cmd(struct iris_inst *inst, u32 cmd);
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_vb2.c b/drivers/media/pl=
atform/qcom/iris/iris_vb2.c
index 3b94011533e8..59fc133c9f98 100644
--- a/drivers/media/platform/qcom/iris/iris_vb2.c
+++ b/drivers/media/platform/qcom/iris/iris_vb2.c
@@ -206,8 +206,10 @@ void iris_vb2_buf_queue(struct vb2_buffer *vb2)
 	}
=20
 	if (V4L2_TYPE_IS_CAPTURE(vb2->vb2_queue->type)) {
-		if (inst->sub_state & IRIS_INST_SUB_DRC &&
-		    inst->sub_state & IRIS_INST_SUB_DRC_LAST) {
+		if ((inst->sub_state & IRIS_INST_SUB_DRC &&
+		     inst->sub_state & IRIS_INST_SUB_DRC_LAST) ||
+		    (inst->sub_state & IRIS_INST_SUB_DRAIN &&
+		     inst->sub_state & IRIS_INST_SUB_DRAIN_LAST)) {
 			vbuf->flags |=3D V4L2_BUF_FLAG_LAST;
 			vbuf->sequence =3D inst->sequence_cap++;
 			vbuf->field =3D V4L2_FIELD_NONE;
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/p=
latform/qcom/iris/iris_vdec.c
index 47a44978869b..076e3ee7969f 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.c
+++ b/drivers/media/platform/qcom/iris/iris_vdec.c
@@ -371,6 +371,7 @@ static int iris_vdec_process_streamon_input(struct iris=
_inst *inst)
 	}
=20
 	if (inst->sub_state & IRIS_INST_SUB_DRC ||
+	    inst->sub_state & IRIS_INST_SUB_DRAIN ||
 	    inst->sub_state & IRIS_INST_SUB_FIRST_IPSC) {
 		if (!(inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE)) {
 			if (hfi_ops->session_pause) {
@@ -422,15 +423,20 @@ int iris_vdec_streamon_input(struct iris_inst *inst)
 static int iris_vdec_process_streamon_output(struct iris_inst *inst)
 {
 	const struct iris_hfi_command_ops *hfi_ops =3D inst->core->hfi_ops;
+	bool drain_active =3D false, drc_active =3D false;
 	enum iris_inst_sub_state clear_sub_state =3D 0;
-	bool drc_active =3D false;
 	int ret =3D 0;
=20
+	drain_active =3D inst->sub_state & IRIS_INST_SUB_DRAIN &&
+		inst->sub_state & IRIS_INST_SUB_DRAIN_LAST;
+
 	drc_active =3D inst->sub_state & IRIS_INST_SUB_DRC &&
 		inst->sub_state & IRIS_INST_SUB_DRC_LAST;
=20
 	if (drc_active)
 		clear_sub_state =3D IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRC_LAST;
+	else if (drain_active)
+		clear_sub_state =3D IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST;
=20
 	if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
 		ret =3D iris_alloc_and_queue_input_int_bufs(inst);
@@ -446,8 +452,12 @@ static int iris_vdec_process_streamon_output(struct ir=
is_inst *inst)
=20
 	if (inst->state =3D=3D IRIS_INST_INPUT_STREAMING &&
 	    inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
-		ret =3D hfi_ops->session_resume_drc(inst,
-						  V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+		if (!drain_active)
+			ret =3D hfi_ops->session_resume_drc(inst,
+							  V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+		else if (hfi_ops->session_resume_drain)
+			ret =3D hfi_ops->session_resume_drain(inst,
+							    V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
 		if (ret)
 			return ret;
 		clear_sub_state |=3D IRIS_INST_SUB_INPUT_PAUSE;
@@ -565,3 +575,78 @@ int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_=
v4l2_buffer *vbuf)
=20
 	return iris_queue_buffer(inst, buf);
 }
+
+int iris_vdec_start_cmd(struct iris_inst *inst)
+{
+	const struct iris_hfi_command_ops *hfi_ops =3D inst->core->hfi_ops;
+	enum iris_inst_sub_state clear_sub_state =3D 0;
+	struct vb2_queue *dst_vq;
+	int ret;
+
+	dst_vq =3D v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+
+	if (inst->sub_state & IRIS_INST_SUB_DRC &&
+	    inst->sub_state & IRIS_INST_SUB_DRC_LAST) {
+		vb2_clear_last_buffer_dequeued(dst_vq);
+		clear_sub_state =3D IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRC_LAST;
+
+		if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
+			ret =3D hfi_ops->session_resume_drc(inst,
+							  V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+			if (ret)
+				return ret;
+			clear_sub_state |=3D IRIS_INST_SUB_INPUT_PAUSE;
+		}
+		if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) {
+			ret =3D hfi_ops->session_resume_drc(inst,
+							  V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+			if (ret)
+				return ret;
+			clear_sub_state |=3D IRIS_INST_SUB_OUTPUT_PAUSE;
+		}
+	} else if (inst->sub_state & IRIS_INST_SUB_DRAIN &&
+		   inst->sub_state & IRIS_INST_SUB_DRAIN_LAST) {
+		vb2_clear_last_buffer_dequeued(dst_vq);
+		clear_sub_state =3D IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST;
+		if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
+			if (hfi_ops->session_resume_drain) {
+				ret =3D
+				hfi_ops->session_resume_drain(inst,
+							      V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+				if (ret)
+					return ret;
+			}
+
+			clear_sub_state |=3D IRIS_INST_SUB_INPUT_PAUSE;
+		}
+		if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) {
+			if (hfi_ops->session_resume_drain) {
+				ret =3D
+				hfi_ops->session_resume_drain(inst,
+							      V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+				if (ret)
+					return ret;
+			}
+
+			clear_sub_state |=3D IRIS_INST_SUB_OUTPUT_PAUSE;
+		}
+	} else {
+		dev_err(inst->core->dev, "start called before receiving last_flag\n");
+		iris_inst_change_state(inst, IRIS_INST_ERROR);
+		return -EBUSY;
+	}
+
+	return iris_inst_change_sub_state(inst, clear_sub_state, 0);
+}
+
+int iris_vdec_stop_cmd(struct iris_inst *inst)
+{
+	const struct iris_hfi_command_ops *hfi_ops =3D inst->core->hfi_ops;
+	int ret;
+
+	ret =3D hfi_ops->session_drain(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+	if (ret)
+		return ret;
+
+	return iris_inst_change_sub_state(inst, 0, IRIS_INST_SUB_DRAIN);
+}
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.h b/drivers/media/p=
latform/qcom/iris/iris_vdec.h
index dfcc2089a1ef..b24932dc511a 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.h
+++ b/drivers/media/platform/qcom/iris/iris_vdec.h
@@ -18,6 +18,8 @@ void iris_vdec_src_change(struct iris_inst *inst);
 int iris_vdec_streamon_input(struct iris_inst *inst);
 int iris_vdec_streamon_output(struct iris_inst *inst);
 int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf);
+int iris_vdec_start_cmd(struct iris_inst *inst);
+int iris_vdec_stop_cmd(struct iris_inst *inst);
 int iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane);
=20
 #endif
diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/p=
latform/qcom/iris/iris_vidc.c
index 2b27df6b1aad..ca0f4e310f77 100644
--- a/drivers/media/platform/qcom/iris/iris_vidc.c
+++ b/drivers/media/platform/qcom/iris/iris_vidc.c
@@ -365,6 +365,39 @@ static int iris_subscribe_event(struct v4l2_fh *fh, co=
nst struct v4l2_event_subs
 	return iris_vdec_subscribe_event(inst, sub);
 }
=20
+static int iris_dec_cmd(struct file *filp, void *fh,
+			struct v4l2_decoder_cmd *dec)
+{
+	struct iris_inst *inst =3D iris_get_inst(filp, NULL);
+	int ret =3D 0;
+
+	mutex_lock(&inst->lock);
+
+	ret =3D v4l2_m2m_ioctl_decoder_cmd(filp, fh, dec);
+	if (ret)
+		goto unlock;
+
+	if (inst->state =3D=3D IRIS_INST_DEINIT)
+		goto unlock;
+
+	if (!iris_allow_cmd(inst, dec->cmd)) {
+		ret =3D -EBUSY;
+		goto unlock;
+	}
+
+	if (dec->cmd =3D=3D V4L2_DEC_CMD_START)
+		ret =3D iris_vdec_start_cmd(inst);
+	else if (dec->cmd =3D=3D V4L2_DEC_CMD_STOP)
+		ret =3D iris_vdec_stop_cmd(inst);
+	else
+		ret =3D -EINVAL;
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
 static struct v4l2_file_operations iris_v4l2_file_ops =3D {
 	.owner                          =3D THIS_MODULE,
 	.open                           =3D iris_open,
@@ -408,6 +441,8 @@ static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops =
=3D {
 	.vidioc_unsubscribe_event       =3D v4l2_event_unsubscribe,
 	.vidioc_streamon                =3D v4l2_m2m_ioctl_streamon,
 	.vidioc_streamoff               =3D v4l2_m2m_ioctl_streamoff,
+	.vidioc_try_decoder_cmd         =3D v4l2_m2m_ioctl_try_decoder_cmd,
+	.vidioc_decoder_cmd             =3D iris_dec_cmd,
 };
=20
 void iris_init_ops(struct iris_core *core)

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 08DB723F29F;
	Fri,  7 Feb 2025 07:57:53 +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=1738915075; cv=none;
 b=rVwY9ihnxPQWnPvm4aINlvUyMp2QXnzhX9e9G2Ks0pl2dj+La4NKb06fIHZISJjPk3C05/P1eFPtHat7qpDV6IKYl1U8W1rdidP/K06d3nxduT4+S4nPp5ouJV7fWXjDQH3W+Wj14w9rO2Ss9lmSTosZX9g1Dp5DLKXuhRWcmdQ=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738915075; c=relaxed/simple;
	bh=WXhOMhECcNOkVrYgz1QvVAgkcqxP0Mp1kLkuJ3+L/hI=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=Kuim4/DQ+86CC+Rurd7GxVgxZmkHXGDNtEWeYmqV5rENcxA7FO4pB+nIz1tAkStLFcbTJoFmX7dtJVy2mgPQY0hUKPBO36rzpy0csvMTpANdd4uCJ4gH2NB9sHxhNo3mgSWN/+gar1iQL16glYCH2PNxFrWvVH9Jf4fjwjYwn2g=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=T74CPC0Q; arc=none smtp.client-ip=205.220.180.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="T74CPC0Q"
Received: from pps.filterd (m0279868.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 5172JVdZ004869;
	Fri, 7 Feb 2025 07:57:40 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	x9jgL+GENlImNhJqXkUELJQkmB7T637O3elV3P6D3SA=; b=T74CPC0Q04cRbJLX
	/wQwc9lqNWp8DgXJCM9mbQVbDBARtVUAVvF5FAXxYsY1Z0G8eUruVnEPKzeDapSs
	SbLlXqeIML4TIngZvAiqowp06DQMZPD3g25gFJBUepDj0cmYu7zhntZr7CYN039P
	qAHGTlB9L3RRfHsw2+C/H2kHT8hwpvfE26ms2dqZ5qqZwfpCUamThdzx+dCU1HLD
	BrTx47xH28Xk0JnS2+1JvnZn8S8UPxKnQteXJVmJ4Dk9geUF06KomXtOn78o7S0u
	w6RYRucn8z0s1ZeIiEN35A8dUebZucrL7LeJLOjqho7Apj6mndUm09clDEaxVUIL
	GmqHSg==
Received: from nalasppmta03.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44n99e8qfg-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:57:39 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA03.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177vcFC031343
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:57:38 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:57:32 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:25:04 +0530
Subject: [PATCH v10 24/28] media: iris: add check whether the video session
 is supported or not
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-24-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>,
        Vedang Nagar <quic_vnagar@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914893; l=5009;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=e47WfzfF9+DkZJKPyjKCXOf6iMSEkmftWnHWcbEN90M=;
 b=IJ6Zbaw342mSrFiMY0RZ5L7AM91En3UvC5juNPm/1keACJ5VHynaNWGQh3kwfm3WcMuiqrcb6
 UaEkU8YKgbrAkhK8HlSILTycL4Haw3E06fTVJqKO0pbKO4UftTMYgkV
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-ORIG-GUID: SnVWSe7aHvYk-SO3lIO6F_QuXkC44lZK
X-Proofpoint-GUID: SnVWSe7aHvYk-SO3lIO6F_QuXkC44lZK
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 clxscore=1015 suspectscore=0
 mlxscore=0 lowpriorityscore=0 impostorscore=0 priorityscore=1501
 phishscore=0 adultscore=0 mlxlogscore=999 malwarescore=0 spamscore=0
 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070060

From: Vedang Nagar <quic_vnagar@quicinc.com>

Based on the hardware capabilities, add a check during start_streaming
and queue_setup, whether the video session is supported by the hardware.

Signed-off-by: Vedang Nagar <quic_vnagar@quicinc.com>
Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 .../platform/qcom/iris/iris_platform_common.h      |  1 +
 .../platform/qcom/iris/iris_platform_sm8550.c      |  1 +
 drivers/media/platform/qcom/iris/iris_vb2.c        | 96 ++++++++++++++++++=
++++
 3 files changed, 98 insertions(+)

diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/driv=
ers/media/platform/qcom/iris/iris_platform_common.h
index de0388a100c3..a5a7d6838d16 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -144,6 +144,7 @@ struct iris_platform_data {
 	struct ubwc_config_data *ubwc_config;
 	u32 num_vpp_pipe;
 	u32 max_session_count;
+	u32 max_core_mbpf;
 	const u32 *input_config_params;
 	unsigned int input_config_params_size;
 	const u32 *output_config_params;
diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/driv=
ers/media/platform/qcom/iris/iris_platform_sm8550.c
index dc51df71c377..8d23978f5cee 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
@@ -233,6 +233,7 @@ struct iris_platform_data sm8550_data =3D {
 	.ubwc_config =3D &ubwc_config_sm8550,
 	.num_vpp_pipe =3D 4,
 	.max_session_count =3D 16,
+	.max_core_mbpf =3D ((8192 * 4352) / 256) * 2,
 	.input_config_params =3D
 		sm8550_vdec_input_config_params,
 	.input_config_params_size =3D
diff --git a/drivers/media/platform/qcom/iris/iris_vb2.c b/drivers/media/pl=
atform/qcom/iris/iris_vb2.c
index 59fc133c9f98..712d37723ec3 100644
--- a/drivers/media/platform/qcom/iris/iris_vb2.c
+++ b/drivers/media/platform/qcom/iris/iris_vb2.c
@@ -11,6 +11,94 @@
 #include "iris_vb2.h"
 #include "iris_vdec.h"
=20
+static int iris_check_core_mbpf(struct iris_inst *inst)
+{
+	struct iris_core *core =3D inst->core;
+	struct iris_inst *instance;
+	u32 total_mbpf =3D 0;
+
+	mutex_lock(&core->lock);
+	list_for_each_entry(instance, &core->instances, list)
+		total_mbpf +=3D iris_get_mbpf(instance);
+	mutex_unlock(&core->lock);
+
+	if (total_mbpf > core->iris_platform_data->max_core_mbpf)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static int iris_check_inst_mbpf(struct iris_inst *inst)
+{
+	struct platform_inst_caps *caps;
+	u32 mbpf, max_mbpf;
+
+	caps =3D inst->core->iris_platform_data->inst_caps;
+	max_mbpf =3D caps->max_mbpf;
+	mbpf =3D iris_get_mbpf(inst);
+	if (mbpf > max_mbpf)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static int iris_check_resolution_supported(struct iris_inst *inst)
+{
+	u32 width, height, min_width, min_height, max_width, max_height;
+	struct platform_inst_caps *caps;
+
+	caps =3D inst->core->iris_platform_data->inst_caps;
+	width =3D inst->fmt_src->fmt.pix_mp.width;
+	height =3D inst->fmt_src->fmt.pix_mp.height;
+
+	min_width =3D caps->min_frame_width;
+	max_width =3D caps->max_frame_width;
+	min_height =3D caps->min_frame_height;
+	max_height =3D caps->max_frame_height;
+
+	if (!(min_width <=3D width && width <=3D max_width) ||
+	    !(min_height <=3D height && height <=3D max_height))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int iris_check_session_supported(struct iris_inst *inst)
+{
+	struct iris_core *core =3D inst->core;
+	struct iris_inst *instance =3D NULL;
+	bool found =3D false;
+	int ret;
+
+	list_for_each_entry(instance, &core->instances, list) {
+		if (instance =3D=3D inst)
+			found =3D true;
+	}
+
+	if (!found) {
+		ret =3D -EINVAL;
+		goto exit;
+	}
+
+	ret =3D iris_check_core_mbpf(inst);
+	if (ret)
+		goto exit;
+
+	ret =3D iris_check_inst_mbpf(inst);
+	if (ret)
+		goto exit;
+
+	ret =3D iris_check_resolution_supported(inst);
+	if (ret)
+		goto exit;
+
+	return 0;
+exit:
+	dev_err(inst->core->dev, "current session not supported(%d)\n", ret);
+
+	return ret;
+}
+
 int iris_vb2_buf_init(struct vb2_buffer *vb2)
 {
 	struct vb2_v4l2_buffer *vbuf =3D to_vb2_v4l2_buffer(vb2);
@@ -48,6 +136,10 @@ int iris_vb2_queue_setup(struct vb2_queue *q,
 		goto unlock;
 	}
=20
+	ret =3D iris_check_session_supported(inst);
+	if (ret)
+		goto unlock;
+
 	if (!inst->once_per_session_set) {
 		inst->once_per_session_set =3D true;
=20
@@ -95,6 +187,10 @@ int iris_vb2_start_streaming(struct vb2_queue *q, unsig=
ned int count)
 		goto error;
 	}
=20
+	ret =3D iris_check_session_supported(inst);
+	if (ret)
+		goto error;
+
 	if (V4L2_TYPE_IS_OUTPUT(q->type))
 		ret =3D iris_vdec_streamon_input(inst);
 	else if (V4L2_TYPE_IS_CAPTURE(q->type))

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 BC649235362;
	Fri,  7 Feb 2025 07:58:01 +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=1738915083; cv=none;
 b=K6RWZYhZyTgwF9YgB+TWb56Nuh88b/LjZSMGGttNJSiXp89T6GVPk02cAPJwgvw4bJW8Z5/hm/41vVOtsGbB6/GGX2TtuuTcRAzBM0dqZh9ptXXMZIgcjNOXOv4URTVAiC3roQlfRJWJQ/T1hUktCL52h3AfGWa0EH1CvZJ0ivc=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738915083; c=relaxed/simple;
	bh=JeSAn9Xg3SoB0PP1HQSwaKAc2ZkCzoTDgktXnnABW8o=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=F5Q7KEPjq6GC7l6XHVpFBisGwRed1NALX/o/uNQPWolE0rqcypGZq2yx46V3FooNTHiUPjWus6vIPc5Ko3cGq9FyTEy0Geh0b4W6WSrVrq199+hOGn3FehLD7oE9oTfrf40uQ2db7CYTVa378OZhNyst3WTas/NiNCBKit3n7kA=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=Jh9+m/+I; arc=none smtp.client-ip=205.220.168.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="Jh9+m/+I"
Received: from pps.filterd (m0279862.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 51770cex018057;
	Fri, 7 Feb 2025 07:57:47 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	bvFNb+E4vOoVGaJf7ib2I4vKgf0gppffCBHbcG9cKh4=; b=Jh9+m/+It2K2ruNZ
	dUW5qexTR0goIaiIUzp7WGqnUoQe3GNuT8fZsMVTdmoyjJY/d6P/M7p10mpoFJeB
	wBhr+9ZFDmqdxzwG5wV87jx2j929cr3PtyCBBuxhv/JEgZzXG3YtCfCfyktSNvrg
	UPdO0vMALjKgn2Jxbrw3AlojpHNgt23zeMe2nsK+hljks5Rrbgl7shO6l1vJ17ft
	v1gr5Mq51kqeox5O/vJxHYhwWSpTZHjbqbZCthy8K72zJ1UeG9Sf3cKJ4o2iR/qu
	0w0fEn4Kv/W900A/0NUIMZbB9ZnXA2gQr0A5SS4qFSBh0QIycp6hMAVrdbHI+hAD
	/isOvA==
Received: from nalasppmta04.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44nddkr4f6-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:57:46 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA04.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177vkJk010976
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:57:46 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:57:39 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:25:05 +0530
Subject: [PATCH v10 25/28] media: iris: implement power scaling for vpu2
 and vpu3
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-25-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>,
        Vedang Nagar <quic_vnagar@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914893; l=16531;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=MYbLtCWM+QVnOW6MG3nZbi8kBOyOEN42oLKftnoqzVY=;
 b=2TKOFgg0DIKre3bdn7Fwyz1UJDw/SjM60WU7/m5QMLN7caf5xcUe81PlbOoeA51V8GKGKV2mv
 ekgwTrLkDhkArOXuyibisCMMiHnSUzT0/r8LVopl3HUZaqR2JB2dc1P
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-ORIG-GUID: TVzrauhZWNtgEpMmoJXyR2ALGOJj3oBQ
X-Proofpoint-GUID: TVzrauhZWNtgEpMmoJXyR2ALGOJj3oBQ
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 impostorscore=0 adultscore=0
 mlxlogscore=999 suspectscore=0 priorityscore=1501 bulkscore=0
 malwarescore=0 phishscore=0 spamscore=0 mlxscore=0 clxscore=1015
 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070060

From: Vedang Nagar <quic_vnagar@quicinc.com>

Implement power scaling including a specific vpu2 and vpu3 calculation
for clock and bus bandwidth, which depends on the hardware
configuration, codec format, resolution and frame rate.

Signed-off-by: Vedang Nagar <quic_vnagar@quicinc.com>
Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 drivers/media/platform/qcom/iris/Makefile          |   1 +
 drivers/media/platform/qcom/iris/iris_buffer.c     |   3 +
 drivers/media/platform/qcom/iris/iris_instance.h   |   6 +
 .../platform/qcom/iris/iris_platform_common.h      |  23 ++++
 .../platform/qcom/iris/iris_platform_sm8550.c      |  12 ++
 drivers/media/platform/qcom/iris/iris_power.c      | 140 +++++++++++++++++=
++++
 drivers/media/platform/qcom/iris/iris_power.h      |  13 ++
 drivers/media/platform/qcom/iris/iris_vb2.c        |   3 +
 drivers/media/platform/qcom/iris/iris_vdec.c       |   7 ++
 drivers/media/platform/qcom/iris/iris_vpu2.c       |  27 ++++
 drivers/media/platform/qcom/iris/iris_vpu3.c       |  38 ++++++
 drivers/media/platform/qcom/iris/iris_vpu_common.h |   1 +
 12 files changed, 274 insertions(+)

diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/plat=
form/qcom/iris/Makefile
index ab16189aa9e6..ca31db847273 100644
--- a/drivers/media/platform/qcom/iris/Makefile
+++ b/drivers/media/platform/qcom/iris/Makefile
@@ -10,6 +10,7 @@ iris-objs +=3D iris_buffer.o \
              iris_hfi_gen2_response.o \
              iris_hfi_queue.o \
              iris_platform_sm8550.o \
+             iris_power.o \
              iris_probe.o \
              iris_resources.o \
              iris_state.o \
diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media=
/platform/qcom/iris/iris_buffer.c
index dc096e5e95bf..e5c5a564fcb8 100644
--- a/drivers/media/platform/qcom/iris/iris_buffer.c
+++ b/drivers/media/platform/qcom/iris/iris_buffer.c
@@ -8,6 +8,7 @@
=20
 #include "iris_buffer.h"
 #include "iris_instance.h"
+#include "iris_power.h"
 #include "iris_vpu_buffer.h"
=20
 #define PIXELS_4K 4096
@@ -500,6 +501,8 @@ int iris_queue_deferred_buffers(struct iris_inst *inst,=
 enum iris_buffer_type bu
 	struct iris_buffer *buf;
 	int ret;
=20
+	iris_scale_power(inst);
+
 	if (buf_type =3D=3D BUF_INPUT) {
 		v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buffer, n) {
 			buf =3D to_iris_buffer(&buffer->vb);
diff --git a/drivers/media/platform/qcom/iris/iris_instance.h b/drivers/med=
ia/platform/qcom/iris/iris_instance.h
index 89fb63644311..caa3c6507006 100644
--- a/drivers/media/platform/qcom/iris/iris_instance.h
+++ b/drivers/media/platform/qcom/iris/iris_instance.h
@@ -33,6 +33,9 @@
  * @state: instance state
  * @sub_state: instance sub state
  * @once_per_session_set: boolean to set once per session property
+ * @max_input_data_size: max size of input data
+ * @power: structure of power info
+ * @icc_data: structure of interconnect data
  * @m2m_dev:	a reference to m2m device structure
  * @m2m_ctx:	a reference to m2m context structure
  * @sequence_cap: a sequence counter for capture queue
@@ -60,6 +63,9 @@ struct iris_inst {
 	enum iris_inst_state		state;
 	enum iris_inst_sub_state	sub_state;
 	bool				once_per_session_set;
+	size_t				max_input_data_size;
+	struct iris_inst_power		power;
+	struct icc_vote_data		icc_data;
 	struct v4l2_m2m_dev		*m2m_dev;
 	struct v4l2_m2m_ctx		*m2m_ctx;
 	u32				sequence_cap;
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/driv=
ers/media/platform/qcom/iris/iris_platform_common.h
index a5a7d6838d16..189dd081ad0a 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -20,6 +20,8 @@ struct iris_inst;
 #define CODED_FRAMES_PROGRESSIVE		0x0
 #define DEFAULT_MAX_HOST_BUF_COUNT		64
 #define DEFAULT_MAX_HOST_BURST_BUF_COUNT	256
+#define DEFAULT_FPS				30
+
 enum stage_type {
 	STAGE_1 =3D 1,
 	STAGE_2 =3D 2,
@@ -67,6 +69,10 @@ struct platform_inst_caps {
 	u32 min_frame_height;
 	u32 max_frame_height;
 	u32 max_mbpf;
+	u32 mb_cycles_vsp;
+	u32 mb_cycles_vpp;
+	u32 mb_cycles_fw;
+	u32 mb_cycles_fw_vpp;
 	u32 num_comv;
 };
=20
@@ -106,11 +112,26 @@ struct platform_inst_fw_cap {
 		   enum platform_inst_fw_cap_type cap_id);
 };
=20
+struct bw_info {
+	u32 mbs_per_sec;
+	u32 bw_ddr;
+};
+
 struct iris_core_power {
 	u64 clk_freq;
 	u64 icc_bw;
 };
=20
+struct iris_inst_power {
+	u64 min_freq;
+	u32 icc_bw;
+};
+
+struct icc_vote_data {
+	u32 height, width;
+	u32 fps;
+};
+
 enum platform_pm_domain_type {
 	IRIS_CTRL_POWER_DOMAIN,
 	IRIS_HW_POWER_DOMAIN,
@@ -124,6 +145,8 @@ struct iris_platform_data {
 	void (*set_preset_registers)(struct iris_core *core);
 	const struct icc_info *icc_tbl;
 	unsigned int icc_tbl_size;
+	const struct bw_info *bw_tbl_dec;
+	unsigned int bw_tbl_dec_size;
 	const char * const *pmdomain_tbl;
 	unsigned int pmdomain_tbl_size;
 	const char * const *opp_pd_tbl;
diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/driv=
ers/media/platform/qcom/iris/iris_platform_sm8550.c
index 8d23978f5cee..35d278996c43 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
@@ -126,6 +126,9 @@ static struct platform_inst_caps platform_inst_cap_sm85=
50 =3D {
 	.min_frame_height =3D 96,
 	.max_frame_height =3D 8192,
 	.max_mbpf =3D (8192 * 4352) / 256,
+	.mb_cycles_vpp =3D 200,
+	.mb_cycles_fw =3D 489583,
+	.mb_cycles_fw_vpp =3D 66234,
 	.num_comv =3D 0,
 };
=20
@@ -141,6 +144,13 @@ static const struct icc_info sm8550_icc_table[] =3D {
=20
 static const char * const sm8550_clk_reset_table[] =3D { "bus" };
=20
+static const struct bw_info sm8550_bw_table_dec[] =3D {
+	{ ((4096 * 2160) / 256) * 60, 1608000 },
+	{ ((4096 * 2160) / 256) * 30,  826000 },
+	{ ((1920 * 1080) / 256) * 60,  567000 },
+	{ ((1920 * 1080) / 256) * 30,  294000 },
+};
+
 static const char * const sm8550_pmdomain_table[] =3D { "venus", "vcodec0"=
 };
=20
 static const char * const sm8550_opp_pd_table[] =3D { "mxc", "mmcx" };
@@ -214,6 +224,8 @@ struct iris_platform_data sm8550_data =3D {
 	.icc_tbl_size =3D ARRAY_SIZE(sm8550_icc_table),
 	.clk_rst_tbl =3D sm8550_clk_reset_table,
 	.clk_rst_tbl_size =3D ARRAY_SIZE(sm8550_clk_reset_table),
+	.bw_tbl_dec =3D sm8550_bw_table_dec,
+	.bw_tbl_dec_size =3D ARRAY_SIZE(sm8550_bw_table_dec),
 	.pmdomain_tbl =3D sm8550_pmdomain_table,
 	.pmdomain_tbl_size =3D ARRAY_SIZE(sm8550_pmdomain_table),
 	.opp_pd_tbl =3D sm8550_opp_pd_table,
diff --git a/drivers/media/platform/qcom/iris/iris_power.c b/drivers/media/=
platform/qcom/iris/iris_power.c
new file mode 100644
index 000000000000..dbca42df0910
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_power.c
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#include <linux/pm_opp.h>
+#include <linux/pm_runtime.h>
+#include <media/v4l2-mem2mem.h>
+
+#include "iris_buffer.h"
+#include "iris_instance.h"
+#include "iris_power.h"
+#include "iris_resources.h"
+#include "iris_vpu_common.h"
+
+static u32 iris_calc_bw(struct iris_inst *inst, struct icc_vote_data *data)
+{
+	const struct bw_info *bw_tbl =3D NULL;
+	struct iris_core *core =3D inst->core;
+	u32 num_rows, i, mbs, mbps;
+	u32 icc_bw =3D 0;
+
+	mbs =3D DIV_ROUND_UP(data->height, 16) * DIV_ROUND_UP(data->width, 16);
+	mbps =3D mbs * data->fps;
+	if (mbps =3D=3D 0)
+		goto exit;
+
+	bw_tbl =3D core->iris_platform_data->bw_tbl_dec;
+	num_rows =3D core->iris_platform_data->bw_tbl_dec_size;
+
+	for (i =3D 0; i < num_rows; i++) {
+		if (i !=3D 0 && mbps > bw_tbl[i].mbs_per_sec)
+			break;
+
+		icc_bw =3D bw_tbl[i].bw_ddr;
+	}
+
+exit:
+	return icc_bw;
+}
+
+static int iris_set_interconnects(struct iris_inst *inst)
+{
+	struct iris_core *core =3D inst->core;
+	struct iris_inst *instance;
+	u64 total_bw_ddr =3D 0;
+	int ret;
+
+	mutex_lock(&core->lock);
+	list_for_each_entry(instance, &core->instances, list) {
+		if (!instance->max_input_data_size)
+			continue;
+
+		total_bw_ddr +=3D instance->power.icc_bw;
+	}
+
+	ret =3D iris_set_icc_bw(core, total_bw_ddr);
+
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+static int iris_vote_interconnects(struct iris_inst *inst)
+{
+	struct icc_vote_data *vote_data =3D &inst->icc_data;
+	struct v4l2_format *inp_f =3D inst->fmt_src;
+
+	vote_data->width =3D inp_f->fmt.pix_mp.width;
+	vote_data->height =3D inp_f->fmt.pix_mp.height;
+	vote_data->fps =3D DEFAULT_FPS;
+
+	inst->power.icc_bw =3D iris_calc_bw(inst, vote_data);
+
+	return iris_set_interconnects(inst);
+}
+
+static int iris_set_clocks(struct iris_inst *inst)
+{
+	struct iris_core *core =3D inst->core;
+	struct iris_inst *instance;
+	u64 freq =3D 0;
+	int ret;
+
+	mutex_lock(&core->lock);
+	list_for_each_entry(instance, &core->instances, list) {
+		if (!instance->max_input_data_size)
+			continue;
+
+		freq +=3D instance->power.min_freq;
+	}
+
+	core->power.clk_freq =3D freq;
+	ret =3D dev_pm_opp_set_rate(core->dev, freq);
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+static int iris_scale_clocks(struct iris_inst *inst)
+{
+	const struct vpu_ops *vpu_ops =3D inst->core->iris_platform_data->vpu_ops;
+	struct v4l2_m2m_ctx *m2m_ctx =3D inst->m2m_ctx;
+	struct v4l2_m2m_buffer *buffer, *n;
+	struct iris_buffer *buf;
+	size_t data_size =3D 0;
+
+	v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buffer, n) {
+		buf =3D to_iris_buffer(&buffer->vb);
+		data_size =3D max(data_size, buf->data_size);
+	}
+
+	inst->max_input_data_size =3D data_size;
+	if (!inst->max_input_data_size)
+		return 0;
+
+	inst->power.min_freq =3D vpu_ops->calc_freq(inst, inst->max_input_data_si=
ze);
+
+	return iris_set_clocks(inst);
+}
+
+int iris_scale_power(struct iris_inst *inst)
+{
+	struct iris_core *core =3D inst->core;
+	int ret;
+
+	if (pm_runtime_suspended(core->dev)) {
+		ret =3D pm_runtime_resume_and_get(core->dev);
+		if (ret < 0)
+			return ret;
+
+		pm_runtime_put_autosuspend(core->dev);
+	}
+
+	ret =3D iris_scale_clocks(inst);
+	if (ret)
+		return ret;
+
+	return iris_vote_interconnects(inst);
+}
diff --git a/drivers/media/platform/qcom/iris/iris_power.h b/drivers/media/=
platform/qcom/iris/iris_power.h
new file mode 100644
index 000000000000..55212660e72d
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_power.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#ifndef __IRIS_POWER_H__
+#define __IRIS_POWER_H__
+
+struct iris_inst;
+
+int iris_scale_power(struct iris_inst *inst);
+
+#endif
diff --git a/drivers/media/platform/qcom/iris/iris_vb2.c b/drivers/media/pl=
atform/qcom/iris/iris_vb2.c
index 712d37723ec3..cdf11feb590b 100644
--- a/drivers/media/platform/qcom/iris/iris_vb2.c
+++ b/drivers/media/platform/qcom/iris/iris_vb2.c
@@ -10,6 +10,7 @@
 #include "iris_instance.h"
 #include "iris_vb2.h"
 #include "iris_vdec.h"
+#include "iris_power.h"
=20
 static int iris_check_core_mbpf(struct iris_inst *inst)
 {
@@ -187,6 +188,8 @@ int iris_vb2_start_streaming(struct vb2_queue *q, unsig=
ned int count)
 		goto error;
 	}
=20
+	iris_scale_power(inst);
+
 	ret =3D iris_check_session_supported(inst);
 	if (ret)
 		goto error;
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/p=
latform/qcom/iris/iris_vdec.c
index 076e3ee7969f..4143acedfc57 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.c
+++ b/drivers/media/platform/qcom/iris/iris_vdec.c
@@ -9,6 +9,7 @@
 #include "iris_buffer.h"
 #include "iris_ctrls.h"
 #include "iris_instance.h"
+#include "iris_power.h"
 #include "iris_vdec.h"
 #include "iris_vpu_buffer.h"
=20
@@ -360,6 +361,8 @@ static int iris_vdec_process_streamon_input(struct iris=
_inst *inst)
 	enum iris_inst_sub_state set_sub_state =3D 0;
 	int ret;
=20
+	iris_scale_power(inst);
+
 	ret =3D hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
 	if (ret)
 		return ret;
@@ -427,6 +430,8 @@ static int iris_vdec_process_streamon_output(struct iri=
s_inst *inst)
 	enum iris_inst_sub_state clear_sub_state =3D 0;
 	int ret =3D 0;
=20
+	iris_scale_power(inst);
+
 	drain_active =3D inst->sub_state & IRIS_INST_SUB_DRAIN &&
 		inst->sub_state & IRIS_INST_SUB_DRAIN_LAST;
=20
@@ -573,6 +578,8 @@ int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v=
4l2_buffer *vbuf)
 		return 0;
 	}
=20
+	iris_scale_power(inst);
+
 	return iris_queue_buffer(inst, buf);
 }
=20
diff --git a/drivers/media/platform/qcom/iris/iris_vpu2.c b/drivers/media/p=
latform/qcom/iris/iris_vpu2.c
index bd8427411576..8f502aed43ce 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu2.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu2.c
@@ -6,6 +6,33 @@
 #include "iris_instance.h"
 #include "iris_vpu_common.h"
=20
+static u64 iris_vpu2_calc_freq(struct iris_inst *inst, size_t data_size)
+{
+	struct platform_inst_caps *caps =3D inst->core->iris_platform_data->inst_=
caps;
+	struct v4l2_format *inp_f =3D inst->fmt_src;
+	u32 mbs_per_second, mbpf, height, width;
+	unsigned long vpp_freq, vsp_freq;
+	u32 fps =3D DEFAULT_FPS;
+
+	width =3D max(inp_f->fmt.pix_mp.width, inst->crop.width);
+	height =3D max(inp_f->fmt.pix_mp.height, inst->crop.height);
+
+	mbpf =3D NUM_MBS_PER_FRAME(height, width);
+	mbs_per_second =3D mbpf * fps;
+
+	vpp_freq =3D mbs_per_second * caps->mb_cycles_vpp;
+
+	/* 21 / 20 is overhead factor */
+	vpp_freq +=3D vpp_freq / 20;
+	vsp_freq =3D mbs_per_second * caps->mb_cycles_vsp;
+
+	/* 10 / 7 is overhead factor */
+	vsp_freq +=3D ((fps * data_size * 8) * 10) / 7;
+
+	return max(vpp_freq, vsp_freq);
+}
+
 const struct vpu_ops iris_vpu2_ops =3D {
 	.power_off_hw =3D iris_vpu_power_off_hw,
+	.calc_freq =3D iris_vpu2_calc_freq,
 };
diff --git a/drivers/media/platform/qcom/iris/iris_vpu3.c b/drivers/media/p=
latform/qcom/iris/iris_vpu3.c
index 10599f1fa789..b484638e6105 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu3.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu3.c
@@ -79,6 +79,44 @@ static void iris_vpu3_power_off_hardware(struct iris_cor=
e *core)
 	iris_vpu_power_off_hw(core);
 }
=20
+static u64 iris_vpu3_calculate_frequency(struct iris_inst *inst, size_t da=
ta_size)
+{
+	struct platform_inst_caps *caps =3D inst->core->iris_platform_data->inst_=
caps;
+	struct v4l2_format *inp_f =3D inst->fmt_src;
+	u32 height, width, mbs_per_second, mbpf;
+	u64 fw_cycles, fw_vpp_cycles;
+	u64 vsp_cycles, vpp_cycles;
+	u32 fps =3D DEFAULT_FPS;
+
+	width =3D max(inp_f->fmt.pix_mp.width, inst->crop.width);
+	height =3D max(inp_f->fmt.pix_mp.height, inst->crop.height);
+
+	mbpf =3D NUM_MBS_PER_FRAME(height, width);
+	mbs_per_second =3D mbpf * fps;
+
+	fw_cycles =3D fps * caps->mb_cycles_fw;
+	fw_vpp_cycles =3D fps * caps->mb_cycles_fw_vpp;
+
+	vpp_cycles =3D mult_frac(mbs_per_second, caps->mb_cycles_vpp, (u32)inst->=
fw_caps[PIPE].value);
+	/* 21 / 20 is minimum overhead factor */
+	vpp_cycles +=3D max(div_u64(vpp_cycles, 20), fw_vpp_cycles);
+
+	/* 1.059 is multi-pipe overhead */
+	if (inst->fw_caps[PIPE].value > 1)
+		vpp_cycles +=3D div_u64(vpp_cycles * 59, 1000);
+
+	vsp_cycles =3D fps * data_size * 8;
+	vsp_cycles =3D div_u64(vsp_cycles, 2);
+	/* VSP FW overhead 1.05 */
+	vsp_cycles =3D div_u64(vsp_cycles * 21, 20);
+
+	if (inst->fw_caps[STAGE].value =3D=3D STAGE_1)
+		vsp_cycles =3D vsp_cycles * 3;
+
+	return max3(vpp_cycles, vsp_cycles, fw_cycles);
+}
+
 const struct vpu_ops iris_vpu3_ops =3D {
 	.power_off_hw =3D iris_vpu3_power_off_hardware,
+	.calc_freq =3D iris_vpu3_calculate_frequency,
 };
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/m=
edia/platform/qcom/iris/iris_vpu_common.h
index d3efa7c0ce9a..63fa1fa5a498 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_common.h
+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h
@@ -13,6 +13,7 @@ extern const struct vpu_ops iris_vpu3_ops;
=20
 struct vpu_ops {
 	void (*power_off_hw)(struct iris_core *core);
+	u64 (*calc_freq)(struct iris_inst *inst, size_t data_size);
 };
=20
 int iris_vpu_boot_firmware(struct iris_core *core);

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 E064F240616;
	Fri,  7 Feb 2025 07:58:07 +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=1738915089; cv=none;
 b=tJoHGa/r3Gd6oMjvnpdMIBhAq+oIMrVgxstiLUgK/Rack7Gf+ckXMZOTFSyFwbT1FLdwmaXbJ/xSK21p0fEMtH0qNC2Iv0JoY6patYrnboQssDhKoTpXILjt5rg9fAYURUcc5RB0TD/hvX3j0ersy92sjOz095mpsndxqr43SPI=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738915089; c=relaxed/simple;
	bh=cq7TJjmOzv2SaDhUpLh2coznevHyG5NE2XaXyA1Yf5Q=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=oIJ8TPssr62P5BrsVMs/2tzzz7boZ/p8OZlkVDCWT0oe4jQleuu2CApV0n5sf453hV1B9MD2qu25LSVp5zMOgBQV+8fCvKuWTO++ZQp2ll9VTvQwZK5h6EZ7YRZtLJtwJJZmIFIyoZbvkp1ptqJCEKX13o0pq4liEh24eTkPTOo=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=Tzp4n9ze; arc=none smtp.client-ip=205.220.180.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="Tzp4n9ze"
Received: from pps.filterd (m0279868.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 5172JJZ2004726;
	Fri, 7 Feb 2025 07:57:54 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	C8PzkfFZ9Vj20Xm1sJ0n2Ylk4FyTe+JBAkXcXmE1TpY=; b=Tzp4n9zeQgsQCRtL
	bMBGfQBdtVBgVgpKL/INL4CCAmXKwOyQL6Ar+D5HIKgDYVKzS9l8lwLAtae4bFWZ
	8v8vwExl8HZ8waClyfbaUbQKymyvJkFYqgEv45DNZu+L8gO86r5J3s2Hej0J4pYX
	E3TDapaNOgyqyahAKUCOJ6UjIbRo/kVQjGZUemWBcbsIvdnX6Rju3tfUYiHJZzN9
	Sn2b8+Aa7WpCl5E8yd2EVz2t5/oUPzyfunjYZR4H9Hvm2mLoP1S2XA4RLvqYNuD2
	oOxE04I8gtJQZP23SnXF1UyPp+NvHTcemC/xsuwMZ70ByRdRkR2VOoSkHk9T08Y1
	osOKLw==
Received: from nalasppmta03.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44n99e8qg0-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:57:54 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA03.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177vrar031447
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:57:53 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:57:46 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:25:06 +0530
Subject: [PATCH v10 26/28] media: iris: add check to allow sub states
 transitions
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-26-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>,
        Vedang Nagar <quic_vnagar@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914893; l=5432;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=3ouVPOI5/LfMAQdAAK/4mo4Y7vdpNLOsus75bx7hpWg=;
 b=KrKyKhGYFIveoypa6Z+XozmmELoyyDXVga5JPJA4Yk9F2EjtqwxlbkaYyqNuB4BTScsqaByD+
 puuHmNHEMmdC8x/cx0m/WwffmhBhnMZX7DKihlqjqX9zivJ1zfN+bHk
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-ORIG-GUID: KQr2Sm1jp0GvZnnlpB4td_8xj6xBz4u_
X-Proofpoint-GUID: KQr2Sm1jp0GvZnnlpB4td_8xj6xBz4u_
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 clxscore=1015 suspectscore=0
 mlxscore=0 lowpriorityscore=0 impostorscore=0 priorityscore=1501
 phishscore=0 adultscore=0 mlxlogscore=999 malwarescore=0 spamscore=0
 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070060

From: Vedang Nagar <quic_vnagar@quicinc.com>

Based on the design of the state machine, add checks whether the
transition from one sub-state to another is allowed.

Signed-off-by: Vedang Nagar <quic_vnagar@quicinc.com>
Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 .../platform/qcom/iris/iris_hfi_gen1_command.c     | 12 ++++++-
 drivers/media/platform/qcom/iris/iris_state.c      | 40 ++++++++++++++++++=
++++
 drivers/media/platform/qcom/iris/iris_state.h      |  3 ++
 3 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/dri=
vers/media/platform/qcom/iris/iris_hfi_gen1_command.c
index e1fbbb3c196d..64f887d9a17d 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
@@ -135,6 +135,9 @@ static int iris_hfi_gen1_session_start(struct iris_inst=
 *inst, u32 plane)
 	if (!V4L2_TYPE_IS_OUTPUT(plane))
 		return 0;
=20
+	if (inst->sub_state & IRIS_INST_SUB_LOAD_RESOURCES)
+		return 0;
+
 	reinit_completion(&inst->completion);
 	iris_hfi_gen1_packet_session_cmd(inst, &packet, HFI_CMD_SESSION_LOAD_RESO=
URCES);
=20
@@ -153,7 +156,11 @@ static int iris_hfi_gen1_session_start(struct iris_ins=
t *inst, u32 plane)
 	if (ret)
 		return ret;
=20
-	return iris_wait_for_session_response(inst, false);
+	ret =3D iris_wait_for_session_response(inst, false);
+	if (ret)
+		return ret;
+
+	return iris_inst_change_sub_state(inst, 0, IRIS_INST_SUB_LOAD_RESOURCES);
 }
=20
 static int iris_hfi_gen1_session_stop(struct iris_inst *inst, u32 plane)
@@ -180,6 +187,9 @@ static int iris_hfi_gen1_session_stop(struct iris_inst =
*inst, u32 plane)
 		ret =3D iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size);
 		if (!ret)
 			ret =3D iris_wait_for_session_response(inst, false);
+
+		iris_inst_change_sub_state(inst, IRIS_INST_SUB_LOAD_RESOURCES, 0);
+
 		iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
 					 VB2_BUF_STATE_ERROR);
 		iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
diff --git a/drivers/media/platform/qcom/iris/iris_state.c b/drivers/media/=
platform/qcom/iris/iris_state.c
index f12306e735ec..5976e926c83d 100644
--- a/drivers/media/platform/qcom/iris/iris_state.c
+++ b/drivers/media/platform/qcom/iris/iris_state.c
@@ -105,6 +105,43 @@ int iris_inst_state_change_streamoff(struct iris_inst =
*inst, u32 plane)
 	return iris_inst_change_state(inst, new_state);
 }
=20
+static bool iris_inst_allow_sub_state(struct iris_inst *inst, enum iris_in=
st_sub_state sub_state)
+{
+	if (!sub_state)
+		return true;
+
+	switch (inst->state) {
+	case IRIS_INST_INIT:
+		if (sub_state & IRIS_INST_SUB_LOAD_RESOURCES)
+			return true;
+		return false;
+	case IRIS_INST_INPUT_STREAMING:
+		if (sub_state & (IRIS_INST_SUB_FIRST_IPSC | IRIS_INST_SUB_DRC |
+			IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_INPUT_PAUSE))
+			return true;
+		return false;
+	case IRIS_INST_OUTPUT_STREAMING:
+		if (sub_state & (IRIS_INST_SUB_DRC_LAST |
+			IRIS_INST_SUB_DRAIN_LAST | IRIS_INST_SUB_OUTPUT_PAUSE))
+			return true;
+		return false;
+	case IRIS_INST_STREAMING:
+		if (sub_state & (IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRAIN |
+			IRIS_INST_SUB_DRC_LAST | IRIS_INST_SUB_DRAIN_LAST |
+			IRIS_INST_SUB_INPUT_PAUSE | IRIS_INST_SUB_OUTPUT_PAUSE))
+			return true;
+		return false;
+	case IRIS_INST_DEINIT:
+		if (sub_state & (IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRAIN |
+			IRIS_INST_SUB_DRC_LAST | IRIS_INST_SUB_DRAIN_LAST |
+			IRIS_INST_SUB_INPUT_PAUSE | IRIS_INST_SUB_OUTPUT_PAUSE))
+			return true;
+		return false;
+	default:
+		return false;
+	}
+}
+
 int iris_inst_change_sub_state(struct iris_inst *inst,
 			       enum iris_inst_sub_state clear_sub_state,
 			       enum iris_inst_sub_state set_sub_state)
@@ -124,6 +161,9 @@ int iris_inst_change_sub_state(struct iris_inst *inst,
=20
 	prev_sub_state =3D inst->sub_state;
=20
+	if (!iris_inst_allow_sub_state(inst, set_sub_state))
+		return -EINVAL;
+
 	inst->sub_state |=3D set_sub_state;
 	inst->sub_state &=3D ~clear_sub_state;
=20
diff --git a/drivers/media/platform/qcom/iris/iris_state.h b/drivers/media/=
platform/qcom/iris/iris_state.h
index a5c0cad4a78c..78c61aac5e7e 100644
--- a/drivers/media/platform/qcom/iris/iris_state.h
+++ b/drivers/media/platform/qcom/iris/iris_state.h
@@ -113,6 +113,8 @@ enum iris_inst_state {
  * @IRIS_INST_SUB_OUTPUT_PAUSE: last buffer is received form firmware as p=
art
  *                             of drc sequence. This indicates that
  *                             firmware is paused to process any further o=
utput frames.
+ * @IRIS_INST_SUB_LOAD_RESOURCES: indicates all the resources have been lo=
aded by the
+ *                               firmware and it is ready for processing.
  */
 enum iris_inst_sub_state {
 	IRIS_INST_SUB_FIRST_IPSC	=3D BIT(0),
@@ -122,6 +124,7 @@ enum iris_inst_sub_state {
 	IRIS_INST_SUB_DRAIN_LAST	=3D BIT(4),
 	IRIS_INST_SUB_INPUT_PAUSE	=3D BIT(5),
 	IRIS_INST_SUB_OUTPUT_PAUSE	=3D BIT(6),
+	IRIS_INST_SUB_LOAD_RESOURCES	=3D BIT(7),
 };
=20
 int iris_inst_change_state(struct iris_inst *inst,

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 7A949234973;
	Fri,  7 Feb 2025 07:58:15 +0000 (UTC)
Authentication-Results: smtp.subspace.kernel.org;
 arc=none smtp.client-ip=205.220.180.131
ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
	t=1738915098; cv=none;
 b=upVp/8SEeikqyFj4/NQ8SuE08cNM8/CzBvsE0k5YQJo1H7j1LhGjxGVacsRdRSuu1vqvSVgm/4/9aixDuH0IeazUerewvGzkSqdsVfOsWsSQxFx0Ep4zfqBt7ji1kTcytGp8XT+cJnZkDT1EeCG11gIobiwL307GpxZAVaj+16U=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738915098; c=relaxed/simple;
	bh=/cvOfoVHgzoLiQi+Z7Kq4L1LQEOh/rz9FzLVXhFUy/8=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=iv5+n/4kwG5Z/R2MNMDD7s88HNG/CNc2ligpoCN8dAI+K3jOKN2pYrso/fUhJzCkBEOAiPSMNudzFfIFjD22goevUJ/Zrs0Z/ST1iPC4hvHJxYFw+c0qLrB4IDXiToQAaunSpYMxcWeOpFrm3epTWOTB0tOg9WZXc9iS3HW5wE8=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=hL9x4vUK; arc=none smtp.client-ip=205.220.180.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="hL9x4vUK"
Received: from pps.filterd (m0279870.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 5176WupR009174;
	Fri, 7 Feb 2025 07:58:01 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	UtfeC/nwBi1v432efVKitAcIyRJVq/+KVWx4MeVNHDc=; b=hL9x4vUKH/ZyvuxH
	wctdKEGM0NeF+x/Qj3v6vuwErI8yLZI1cFUaTHWUgojt25mISqyBNbPXKhVTlrRu
	EfePTD+6RUpfvgZc6EN4a3sqq35Th9V+7Qf4mARqUREVfoYMGelwN+vZwmcyrVtR
	eDfx6DIlsBfZQ7SUn/bzKiDdU4g+m3Fvms31E+td9nS9eadZVXsu+JQsESZK/guY
	0hAK/KHraQ/aCSpZv+9VK/GCJtE6CTSm41pQlFcDE//TYs6DPsvbIR7gY54KpZPp
	C0abrS4EEYvAqxsOK9roaJO+Y5gmxWnJnwev4Ws8d8MgiQwSVo2mH5GBIdauSR+c
	u+gOPw==
Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44nd0f06vf-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:58:01 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA05.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177w06j030643
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:58:00 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:57:53 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:25:07 +0530
Subject: [PATCH v10 27/28] media: iris: enable video driver probe of SM8250
 SoC
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-27-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914893; l=7222;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=/cvOfoVHgzoLiQi+Z7Kq4L1LQEOh/rz9FzLVXhFUy/8=;
 b=xdn2kBREVml43tNzldJqrrLAMcoLf4czanJ08gn2qb6P6zP4RpX36mEX75b6tqakbNllufHzC
 iixvKarQHYOD2dq75Klg456v3a++7qYNS9VvFKMBWXCF37kuqZYD9Pc
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-ORIG-GUID: eAIoLr3i7ycss2eXoper7ZUb_-cYtCnf
X-Proofpoint-GUID: eAIoLr3i7ycss2eXoper7ZUb_-cYtCnf
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 clxscore=1015 bulkscore=0
 lowpriorityscore=0 spamscore=0 suspectscore=0 mlxlogscore=999 mlxscore=0
 adultscore=0 malwarescore=0 phishscore=0 priorityscore=1501
 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070060

Initialize the platform data and enable video driver probe of SM8250
SoC.

Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 drivers/media/platform/qcom/iris/Makefile          |   4 +
 .../platform/qcom/iris/iris_platform_common.h      |   1 +
 .../platform/qcom/iris/iris_platform_sm8250.c      | 149 +++++++++++++++++=
++++
 drivers/media/platform/qcom/iris/iris_probe.c      |   6 +
 4 files changed, 160 insertions(+)

diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/plat=
form/qcom/iris/Makefile
index ca31db847273..f6d22b88f6db 100644
--- a/drivers/media/platform/qcom/iris/Makefile
+++ b/drivers/media/platform/qcom/iris/Makefile
@@ -23,4 +23,8 @@ iris-objs +=3D iris_buffer.o \
              iris_vpu_buffer.o \
              iris_vpu_common.o \
=20
+ifeq ($(CONFIG_VIDEO_QCOM_VENUS),)
+iris-objs +=3D iris_platform_sm8250.o
+endif
+
 obj-$(CONFIG_VIDEO_QCOM_IRIS) +=3D iris.o
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/driv=
ers/media/platform/qcom/iris/iris_platform_common.h
index 189dd081ad0a..f6b15d2805fb 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -33,6 +33,7 @@ enum pipe_type {
 	PIPE_4 =3D 4,
 };
=20
+extern struct iris_platform_data sm8250_data;
 extern struct iris_platform_data sm8550_data;
=20
 enum platform_clk_type {
diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8250.c b/driv=
ers/media/platform/qcom/iris/iris_platform_sm8250.c
new file mode 100644
index 000000000000..5c86fd7b7b6f
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8250.c
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights res=
erved.
+ */
+
+#include "iris_core.h"
+#include "iris_ctrls.h"
+#include "iris_platform_common.h"
+#include "iris_resources.h"
+#include "iris_hfi_gen1.h"
+#include "iris_hfi_gen1_defines.h"
+#include "iris_vpu_common.h"
+
+static struct platform_inst_fw_cap inst_fw_cap_sm8250[] =3D {
+	{
+		.cap_id =3D PIPE,
+		.min =3D PIPE_1,
+		.max =3D PIPE_4,
+		.step_or_mask =3D 1,
+		.value =3D PIPE_4,
+		.hfi_id =3D HFI_PROPERTY_PARAM_WORK_ROUTE,
+		.set =3D iris_set_pipe,
+	},
+	{
+		.cap_id =3D STAGE,
+		.min =3D STAGE_1,
+		.max =3D STAGE_2,
+		.step_or_mask =3D 1,
+		.value =3D STAGE_2,
+		.hfi_id =3D HFI_PROPERTY_PARAM_WORK_MODE,
+		.set =3D iris_set_stage,
+	},
+	{
+		.cap_id =3D DEBLOCK,
+		.min =3D 0,
+		.max =3D 1,
+		.step_or_mask =3D 1,
+		.value =3D 0,
+		.hfi_id =3D HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER,
+		.set =3D iris_set_u32,
+	},
+};
+
+static struct platform_inst_caps platform_inst_cap_sm8250 =3D {
+	.min_frame_width =3D 128,
+	.max_frame_width =3D 8192,
+	.min_frame_height =3D 128,
+	.max_frame_height =3D 8192,
+	.max_mbpf =3D 138240,
+	.mb_cycles_vsp =3D 25,
+	.mb_cycles_vpp =3D 200,
+};
+
+static void iris_set_sm8250_preset_registers(struct iris_core *core)
+{
+	writel(0x0, core->reg_base + 0xB0088);
+}
+
+static const struct icc_info sm8250_icc_table[] =3D {
+	{ "cpu-cfg",    1000, 1000     },
+	{ "video-mem",  1000, 15000000 },
+};
+
+static const char * const sm8250_clk_reset_table[] =3D { "bus", "core" };
+
+static const struct bw_info sm8250_bw_table_dec[] =3D {
+	{ ((4096 * 2160) / 256) * 60, 2403000 },
+	{ ((4096 * 2160) / 256) * 30, 1224000 },
+	{ ((1920 * 1080) / 256) * 60,  812000 },
+	{ ((1920 * 1080) / 256) * 30,  416000 },
+};
+
+static const char * const sm8250_pmdomain_table[] =3D { "venus", "vcodec0"=
 };
+
+static const char * const sm8250_opp_pd_table[] =3D { "mx" };
+
+static const struct platform_clk_data sm8250_clk_table[] =3D {
+	{IRIS_AXI_CLK,  "iface"        },
+	{IRIS_CTRL_CLK, "core"         },
+	{IRIS_HW_CLK,   "vcodec0_core" },
+};
+
+static struct tz_cp_config tz_cp_config_sm8250 =3D {
+	.cp_start =3D 0,
+	.cp_size =3D 0x25800000,
+	.cp_nonpixel_start =3D 0x01000000,
+	.cp_nonpixel_size =3D 0x24800000,
+};
+
+static const u32 sm8250_vdec_input_config_param_default[] =3D {
+	HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE,
+	HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT,
+	HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO,
+	HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL,
+	HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM,
+	HFI_PROPERTY_PARAM_FRAME_SIZE,
+	HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL,
+	HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE,
+};
+
+static const u32 sm8250_dec_ip_int_buf_tbl[] =3D {
+	BUF_BIN,
+	BUF_SCRATCH_1,
+};
+
+static const u32 sm8250_dec_op_int_buf_tbl[] =3D {
+	BUF_DPB,
+};
+
+struct iris_platform_data sm8250_data =3D {
+	.get_instance =3D iris_hfi_gen1_get_instance,
+	.init_hfi_command_ops =3D &iris_hfi_gen1_command_ops_init,
+	.init_hfi_response_ops =3D iris_hfi_gen1_response_ops_init,
+	.vpu_ops =3D &iris_vpu2_ops,
+	.set_preset_registers =3D iris_set_sm8250_preset_registers,
+	.icc_tbl =3D sm8250_icc_table,
+	.icc_tbl_size =3D ARRAY_SIZE(sm8250_icc_table),
+	.clk_rst_tbl =3D sm8250_clk_reset_table,
+	.clk_rst_tbl_size =3D ARRAY_SIZE(sm8250_clk_reset_table),
+	.bw_tbl_dec =3D sm8250_bw_table_dec,
+	.bw_tbl_dec_size =3D ARRAY_SIZE(sm8250_bw_table_dec),
+	.pmdomain_tbl =3D sm8250_pmdomain_table,
+	.pmdomain_tbl_size =3D ARRAY_SIZE(sm8250_pmdomain_table),
+	.opp_pd_tbl =3D sm8250_opp_pd_table,
+	.opp_pd_tbl_size =3D ARRAY_SIZE(sm8250_opp_pd_table),
+	.clk_tbl =3D sm8250_clk_table,
+	.clk_tbl_size =3D ARRAY_SIZE(sm8250_clk_table),
+	/* Upper bound of DMA address range */
+	.dma_mask =3D 0xe0000000 - 1,
+	.fwname =3D "qcom/vpu-1.0/venus.mbn",
+	.pas_id =3D IRIS_PAS_ID,
+	.inst_caps =3D &platform_inst_cap_sm8250,
+	.inst_fw_caps =3D inst_fw_cap_sm8250,
+	.inst_fw_caps_size =3D ARRAY_SIZE(inst_fw_cap_sm8250),
+	.tz_cp_config_data =3D &tz_cp_config_sm8250,
+	.hw_response_timeout =3D HW_RESPONSE_TIMEOUT_VALUE,
+	.num_vpp_pipe =3D 4,
+	.max_session_count =3D 16,
+	.max_core_mbpf =3D (8192 * 4352) / 256,
+	.input_config_params =3D
+		sm8250_vdec_input_config_param_default,
+	.input_config_params_size =3D
+		ARRAY_SIZE(sm8250_vdec_input_config_param_default),
+
+	.dec_ip_int_buf_tbl =3D sm8250_dec_ip_int_buf_tbl,
+	.dec_ip_int_buf_tbl_size =3D ARRAY_SIZE(sm8250_dec_ip_int_buf_tbl),
+	.dec_op_int_buf_tbl =3D sm8250_dec_op_int_buf_tbl,
+	.dec_op_int_buf_tbl_size =3D ARRAY_SIZE(sm8250_dec_op_int_buf_tbl),
+};
diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/=
platform/qcom/iris/iris_probe.c
index 954cc7c0cc97..aca442dcc153 100644
--- a/drivers/media/platform/qcom/iris/iris_probe.c
+++ b/drivers/media/platform/qcom/iris/iris_probe.c
@@ -324,6 +324,12 @@ static const struct of_device_id iris_dt_match[] =3D {
 		.compatible =3D "qcom,sm8550-iris",
 		.data =3D &sm8550_data,
 	},
+#if (!IS_ENABLED(CONFIG_VIDEO_QCOM_VENUS))
+		{
+			.compatible =3D "qcom,sm8250-venus",
+			.data =3D &sm8250_data,
+		},
+#endif
 	{ },
 };
 MODULE_DEVICE_TABLE(of, iris_dt_match);

--=20
2.34.1
From nobody Mon Apr  7 01:01:10 2025
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 18BEE246323;
	Fri,  7 Feb 2025 07:58:21 +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=1738915102; cv=none;
 b=Wdopnqkm8HxlpYIZY8hsERXIHfQPO7eEgtQlQBRWgnzi9Uj8oJ4+PEdcIGx1Gs4d+MOmqtxf6pIqQzRSXstJHXX+wOkAqwgz6QcGimifqXQP8qk7RepQYoVpVxO+qpjIF8Yo2Jv79ig4pJQKesaVgDTuS6McLV7QtnifuFM3nBU=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1738915102; c=relaxed/simple;
	bh=f1R4bitQrRJlRfWyXE0apdgMwbAZlRAvnd1OwuO1upQ=;
	h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:
	 In-Reply-To:To:CC;
 b=Lyj/Y41aiaCFqaBrhg21BEUV39WmK6WuJJF+yLK3An9oFeFmTaSSgM0OxeZUPeUT3BkEhh271McPQA+oktgvwpxKeTd66CbReTxOvv6axg0KtwStMukf9Bb2L5cwWHW7jKIkPcUN0lM7paSXmJHJX+8vq/aNaLzAONWpqLlTPjI=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com;
 spf=pass smtp.mailfrom=quicinc.com;
 dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b=AdcvZkvw; arc=none smtp.client-ip=205.220.180.131
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=quicinc.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com
 header.b="AdcvZkvw"
Received: from pps.filterd (m0279869.ppops.net [127.0.0.1])
	by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id
 5175GfO7021026;
	Fri, 7 Feb 2025 07:58:08 GMT
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=
	cc:content-transfer-encoding:content-type:date:from:in-reply-to
	:message-id:mime-version:references:subject:to; s=qcppdkim1; bh=
	1lykkkUImhEmn7iU2wCNDHiWuqHTLsVzcCLDHlBUQp8=; b=AdcvZkvwhqBr8Vpq
	e3B9pu7euLdv+qOzU0ErYPuD9ewFyvpv1Ug3OXaMfZRYfaDAb1CUP06QACdZ/Qtb
	+udycu/lKwqcmUZ5PXwzUsfYGNICch8y9oOZMSxrdS+unikDpafT0+rIOhVdtFBs
	NXf+4EH5NcMHTf7EaBA6ILzw1k1gAfonFr50vVULUkbf80HEjIvH767D7z6rPA7K
	uRsVrAEskyBAOPATgzgyIwTRU9NHlEH5qx/mK7BfPRHO72lIM7332ePUz/by1vat
	SSJu834F5r60NNV+IY4ewYcauvXaom2cGi4/KUr2QzXByp5YTgzt/4dhyljx/i/t
	Cln4JA==
Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com
 [129.46.96.20])
	by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 44nbvurc18-1
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 07 Feb 2025 07:58:08 +0000 (GMT)
Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com
 [10.47.209.196])
	by NALASPPMTA05.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id
 5177w7Tw030975
	(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);
	Fri, 7 Feb 2025 07:58:07 GMT
Received: from hu-dikshita-hyd.qualcomm.com (10.80.80.8) by
 nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.2.1544.9; Thu, 6 Feb 2025 23:58:00 -0800
From: Dikshita Agarwal <quic_dikshita@quicinc.com>
Date: Fri, 7 Feb 2025 13:25:08 +0530
Subject: [PATCH v10 28/28] media: MAINTAINERS: add Qualcomm iris video
 accelerator driver
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Message-ID: <20250207-qcom-video-iris-v10-28-ab66eeffbd20@quicinc.com>
References: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
In-Reply-To: <20250207-qcom-video-iris-v10-0-ab66eeffbd20@quicinc.com>
To: Vikash Garodia <quic_vgarodia@quicinc.com>,
        Abhinav Kumar
	<quic_abhinavk@quicinc.com>,
        Mauro Carvalho Chehab <mchehab@kernel.org>,
        "Rob
 Herring" <robh@kernel.org>,
        Krzysztof Kozlowski <krzk+dt@kernel.org>,
        "Conor
 Dooley" <conor+dt@kernel.org>,
        Philipp Zabel <p.zabel@pengutronix.de>
CC: Hans Verkuil <hverkuil@xs4all.nl>,
        Sebastian Fricke
	<sebastian.fricke@collabora.com>,
        Bryan O'Donoghue
	<bryan.odonoghue@linaro.org>,
        Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
        Neil Armstrong <neil.armstrong@linaro.org>,
        Nicolas Dufresne
	<nicolas@ndufresne.ca>,
        =?utf-8?q?Uwe_Kleine-K=C3=B6nig?=
	<u.kleine-koenig@baylibre.com>,
        Jianhua Lu <lujianhua000@gmail.com>,
        "Stefan
 Schmidt" <stefan.schmidt@linaro.org>,
        Joel Stanley <joel@jms.id.au>, "Johan
 Hovold" <johan@kernel.org>,
        <linux-media@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
        <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
        Dikshita Agarwal <quic_dikshita@quicinc.com>
X-Mailer: b4 0.14.1
X-Developer-Signature: v=1; a=ed25519-sha256; t=1738914893; l=1348;
 i=quic_dikshita@quicinc.com; s=20240917; h=from:subject:message-id;
 bh=f1R4bitQrRJlRfWyXE0apdgMwbAZlRAvnd1OwuO1upQ=;
 b=7KIrKKvXcH7TX4Bdxx88JLnHAE0GCzC0jeQWH4QO2aSxv+IKE6va6KyoYV6NX0rffDZ4G5nrV
 QOwXClBOuQ0DJG+S5TRcxb3dT5hTVYEYAgbwGuunp+EPzjljB0+MwhS
X-Developer-Key: i=quic_dikshita@quicinc.com; a=ed25519;
 pk=EEvKY6Ar1OI5SWf44FJ1Ebo1KuQEVbbf5UNPO+UHVhM=
X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To
 nalasex01a.na.qualcomm.com (10.47.209.196)
X-QCInternal: smtphost
X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800
 signatures=585085
X-Proofpoint-GUID: wO-BdD0yYO7lFYgRaLI-0IjJEveBN_8n
X-Proofpoint-ORIG-GUID: wO-BdD0yYO7lFYgRaLI-0IjJEveBN_8n
X-Proofpoint-Virus-Version: vendor=baseguard
 engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34
 definitions=2025-02-07_03,2025-02-07_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
 phishscore=0
 lowpriorityscore=0 malwarescore=0 adultscore=0 spamscore=0 impostorscore=0
 suspectscore=0 bulkscore=0 priorityscore=1501 clxscore=1015 mlxscore=0
 mlxlogscore=999 classifier=spam adjust=0 reason=mlx scancount=1
 engine=8.19.0-2501170000 definitions=main-2502070060

Add an entry for the iris video decoder accelerator driver.

Signed-off-by: Vikash Garodia <quic_vgarodia@quicinc.com>
Tested-by: Stefan Schmidt <stefan.schmidt@linaro.org> # x1e80100 (Dell XPS =
13 9345)
Reviewed-by: Stefan Schmidt <stefan.schmidt@linaro.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 MAINTAINERS | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 7a14891a8fa9..d647e59d9912 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19156,6 +19156,16 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/regulator/vqmmc-ipq4019-regulator.yaml
 F:	drivers/regulator/vqmmc-ipq4019-regulator.c
=20
+QUALCOMM IRIS VIDEO ACCELERATOR DRIVER
+M:	Vikash Garodia <quic_vgarodia@quicinc.com>
+M:	Dikshita Agarwal <quic_dikshita@quicinc.com>
+R:	Abhinav Kumar <quic_abhinavk@quicinc.com>
+L:	linux-media@vger.kernel.org
+L:	linux-arm-msm@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/media/qcom,*-iris.yaml
+F:	drivers/media/platform/qcom/iris/
+
 QUALCOMM NAND CONTROLLER DRIVER
 M:	Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
 L:	linux-mtd@lists.infradead.org

--=20
2.34.1