From patchwork Thu Jun 27 13:09:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 13714387 Received: from lelv0143.ext.ti.com (lelv0143.ext.ti.com [198.47.23.248]) (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 DF63018A924; Thu, 27 Jun 2024 13:10:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.23.248 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493849; cv=none; b=dWU807EfR+KcjbMevAmyXSKKTHsKGKVVHsIpDAPe58Yd5QQmS2rFDu9scUrkaNZ8BaBsQxw1dwWb+UB5X+btmWkA+3Sbd4/f24UDsKdUuI/DIahBxnXknAdEbPBZpIZ1AwT13VBjhPy8F8hhOGzAsTe04UR/uE1SWdnqTo1SyOs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493849; c=relaxed/simple; bh=mOPOzpOxDm8At4aQJ1DhFOiUZ8dOL9TTrKSHJfLLFC4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=D17BmHzJ2C+NCfAjZAaf4sj5wjVHhCaxZFL1+3WHhW1yag3jx5d/jPGlp+LCAuLlk/ZkOFZFQQ0A3kXOyuaDFWT+RgqTdKY1b8rukLwHDpUK0meuqvCGksuCMvqkWng1t4fspcN/os3cZAqLSvs1s6Ub7MkQV0fyOzyDfvR092Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=cC+QLSKb; arc=none smtp.client-ip=198.47.23.248 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="cC+QLSKb" Received: from lelv0266.itg.ti.com ([10.180.67.225]) by lelv0143.ext.ti.com (8.15.2/8.15.2) with ESMTP id 45RDAQAa110206; Thu, 27 Jun 2024 08:10:26 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1719493826; bh=0j+pRnYIz0YmwJf02oM8YeGAX8XHeGu62s1LydGmz+4=; h=From:Date:Subject:References:In-Reply-To:To:CC; b=cC+QLSKbV+3xODMuBtA1LrYRMlYoGhxRIiqHyyp4gCEXmC0jSU0IJqTJzK8L1/anB WdKGOvFdZJi/B06wAXzrRClEfD8fEt1CPw80KMtPJP9hBRDaHDx0TiJYmyaVxSMCfL 8N6JSD6PuxFpJIGXkYj/gZoASkMvKugmz9OqnvbQ= Received: from DFLE114.ent.ti.com (dfle114.ent.ti.com [10.64.6.35]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 45RDAQhN109079 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 27 Jun 2024 08:10:26 -0500 Received: from DFLE112.ent.ti.com (10.64.6.33) by DFLE114.ent.ti.com (10.64.6.35) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Thu, 27 Jun 2024 08:10:26 -0500 Received: from lelvsmtp6.itg.ti.com (10.180.75.249) by DFLE112.ent.ti.com (10.64.6.33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Thu, 27 Jun 2024 08:10:26 -0500 Received: from localhost (jluthra.dhcp.ti.com [172.24.227.116]) by lelvsmtp6.itg.ti.com (8.15.2/8.15.2) with ESMTP id 45RDAPI4038401; Thu, 27 Jun 2024 08:10:25 -0500 From: Jai Luthra Date: Thu, 27 Jun 2024 18:39:56 +0530 Subject: [PATCH v2 01/13] media: cadence: csi2rx: Support runtime PM Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <20240627-multistream-v2-1-6ae96c54c1c3@ti.com> References: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> In-Reply-To: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> To: Tomi Valkeinen , Mauro Carvalho Chehab , Sakari Ailus , Hans Verkuil , Vaishnav Achath , Maxime Ripard , Rob Herring , Krzysztof Kozlowski , Conor Dooley CC: , , Vignesh Raghavendra , Aradhya Bhatia , Devarsh Thakkar , Changhuang Liang , Jack Zhu , Julien Massot , Laurent Pinchart , Jai Luthra X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=openpgp-sha256; l=3486; i=j-luthra@ti.com; h=from:subject:message-id; bh=tXWucuzl8lsBqZDdK9Xa9QSqspro1tIHfpB88oP8kVY=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBmfWSyY1mUjV+r0gi6AEE+mDxcG80C11C3v0iz/ cFcoADbdBOJAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZn1ksgAKCRBD3pH5JJpx RYRuD/49QcTVhDjFDpCmcBH5UqIClgaCNj0YOlSbreynilOmz4jN+fTtPsE9r7LMq08JnZyy0OY BejyBq0Mr4nEgfDNpOpNyXlMwYxB89x71ffzYB0tgY32GyA+q4t6Ns70qvw8z/0z9hbqDZ1cDkS BOymj+4jLhIRdSyMNFGSXjvvAx0G4DGiITP6q9dYSnIJrIndKMbKjP18kYQcxRHTOgHWVxidBEZ YWd6itX3zXJyLD4454WlhxDMiVtexjbyHuDebuvkEEC0uLgQEHBo2Yf4lhi1vJXVTeEC/yTf46n 4Gxt7rVrgrnDiCOl1wQYruwwmI3BMzQyfTW34tjrI4pYJZKgF0zQLk3PWy4yr3he6C7m4Gm3uNh ZinpLXcCDJ+vCTNxp8+jbRlp3Oserw9Cfv6VFE7PIowfZEfTUfgCA1xJ+gkEfT7cIvvhYiyekUF et5A+xMQLxrrq0hpRlLOi0MI4NjbNCtKZCaMuMoDl9UPKkm47iyfwLcdzUx/oH9NfssgIKji/L6 u8VMn3N0k7xlaHGFPM5lPxjrHlN4OppgWi9CyNvml8kZMIh8M3/ourQFQwo8lB2l+w76WRAHzYk APzzTeW3qApchd2r1GmcZRYDcs+A/Hu08PRdwYpjDRCkvh4y94BnvcT7GmhIapM8jubcBVw/xGR X6GiHuvREUBL5iA== X-Developer-Key: i=j-luthra@ti.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 From: Jayshri Pawar Use runtime power management hooks to save power when CSI-RX is not in use. Also stop/start any in-progress streams, which might happen during a system suspend/resume cycle. Signed-off-by: Jayshri Pawar Co-developed-by: Jai Luthra Signed-off-by: Jai Luthra --- drivers/media/platform/cadence/cdns-csi2rx.c | 43 +++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c index 6f7d27a48eff..751eadbe61ef 100644 --- a/drivers/media/platform/cadence/cdns-csi2rx.c +++ b/drivers/media/platform/cadence/cdns-csi2rx.c @@ -366,6 +366,12 @@ static int csi2rx_s_stream(struct v4l2_subdev *subdev, int enable) struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev); int ret = 0; + if (enable) { + ret = pm_runtime_resume_and_get(csi2rx->dev); + if (ret < 0) + return ret; + } + mutex_lock(&csi2rx->lock); if (enable) { @@ -375,8 +381,10 @@ static int csi2rx_s_stream(struct v4l2_subdev *subdev, int enable) */ if (!csi2rx->count) { ret = csi2rx_start(csi2rx); - if (ret) + if (ret) { + pm_runtime_put(csi2rx->dev); goto out; + } } csi2rx->count++; @@ -388,6 +396,8 @@ static int csi2rx_s_stream(struct v4l2_subdev *subdev, int enable) */ if (!csi2rx->count) csi2rx_stop(csi2rx); + + pm_runtime_put(csi2rx->dev); } out: @@ -661,6 +671,29 @@ static int csi2rx_parse_dt(struct csi2rx_priv *csi2rx) return ret; } +static int csi2rx_suspend(struct device *dev) +{ + struct csi2rx_priv *csi2rx = dev_get_drvdata(dev); + + mutex_lock(&csi2rx->lock); + if (csi2rx->count) + csi2rx_stop(csi2rx); + mutex_unlock(&csi2rx->lock); + + return 0; +} + +static int csi2rx_resume(struct device *dev) +{ + struct csi2rx_priv *csi2rx = dev_get_drvdata(dev); + + mutex_lock(&csi2rx->lock); + if (csi2rx->count) + csi2rx_start(csi2rx); + mutex_unlock(&csi2rx->lock); + return 0; +} + static int csi2rx_probe(struct platform_device *pdev) { struct csi2rx_priv *csi2rx; @@ -707,6 +740,7 @@ static int csi2rx_probe(struct platform_device *pdev) if (ret) goto err_cleanup; + pm_runtime_enable(csi2rx->dev); ret = v4l2_async_register_subdev(&csi2rx->subdev); if (ret < 0) goto err_free_state; @@ -721,6 +755,7 @@ static int csi2rx_probe(struct platform_device *pdev) err_free_state: v4l2_subdev_cleanup(&csi2rx->subdev); + pm_runtime_disable(csi2rx->dev); err_cleanup: v4l2_async_nf_unregister(&csi2rx->notifier); v4l2_async_nf_cleanup(&csi2rx->notifier); @@ -739,9 +774,14 @@ static void csi2rx_remove(struct platform_device *pdev) v4l2_async_unregister_subdev(&csi2rx->subdev); v4l2_subdev_cleanup(&csi2rx->subdev); media_entity_cleanup(&csi2rx->subdev.entity); + pm_runtime_disable(csi2rx->dev); kfree(csi2rx); } +static const struct dev_pm_ops csi2rx_pm_ops = { + SET_RUNTIME_PM_OPS(csi2rx_suspend, csi2rx_resume, NULL) +}; + static const struct of_device_id csi2rx_of_table[] = { { .compatible = "starfive,jh7110-csi2rx" }, { .compatible = "cdns,csi2rx" }, @@ -756,6 +796,7 @@ static struct platform_driver csi2rx_driver = { .driver = { .name = "cdns-csi2rx", .of_match_table = csi2rx_of_table, + .pm = &csi2rx_pm_ops, }, }; module_platform_driver(csi2rx_driver); From patchwork Thu Jun 27 13:09:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 13714383 Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) (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 77EB7188CB9; Thu, 27 Jun 2024 13:10:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.19.141 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493848; cv=none; b=qoBA5UzFd7ksVapN3j+em+bZ77m+0/759mKPaQlkgdXwd1up4MIRQa0QAud0h5x45qBEk2UFIMMnS+nYbBVAqcjq+0cI56h8ze4SZZkTba37f6xDaw51GvoFz3xiiejNC2GoYj+ohIPm2KEeWFinm05PzFWTktR08aZAHmcBnxY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493848; c=relaxed/simple; bh=24D3XNVBK9Dmv+4yYpQCrJXrk43bw9jFtHr0iPUMswk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=L0fQuQmG3JWyA41kSVfjt5oQT6W9SfqTWZxxbUQCtQDSMor9FFM97jU3GBX4mSxz3FKaw0aZHp5MU9IstKtwXM3h9l0kdyNMijhrgVRSJuBnLYG/AxcCyiD9431zIpqMu2xY4Et0F+IvvaiIfWFnOZAsVUPAu2ytibqPjx8Ihr8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=DrHwsbBg; arc=none smtp.client-ip=198.47.19.141 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="DrHwsbBg" Received: from fllv0035.itg.ti.com ([10.64.41.0]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 45RDASMT117441; Thu, 27 Jun 2024 08:10:28 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1719493828; bh=SKvlDdGZFIbN30XgC3XarKQ1FX7j3zWjtGxbHfAaf9A=; h=From:Date:Subject:References:In-Reply-To:To:CC; b=DrHwsbBgSqtXTyATAhVSca5v8CFXfwBcbPhthIw9NZkMnSUkC853wO0MQKR9sNkTS j0bhSlXz0dX775YJcbCmARglxjmiNHpJaWnwmEE5HwKGYHRvIV3yhRlcwACxjsihPA i+5iowqgRYwyaifgxsKlXr9Rel5TJwaQ034xyhf4= Received: from DFLE100.ent.ti.com (dfle100.ent.ti.com [10.64.6.21]) by fllv0035.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 45RDASCw095631 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 27 Jun 2024 08:10:28 -0500 Received: from DFLE110.ent.ti.com (10.64.6.31) by DFLE100.ent.ti.com (10.64.6.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Thu, 27 Jun 2024 08:10:27 -0500 Received: from lelvsmtp5.itg.ti.com (10.180.75.250) by DFLE110.ent.ti.com (10.64.6.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Thu, 27 Jun 2024 08:10:27 -0500 Received: from localhost (jluthra.dhcp.ti.com [172.24.227.116]) by lelvsmtp5.itg.ti.com (8.15.2/8.15.2) with ESMTP id 45RDAQUq072036; Thu, 27 Jun 2024 08:10:27 -0500 From: Jai Luthra Date: Thu, 27 Jun 2024 18:39:57 +0530 Subject: [PATCH v2 02/13] dt-bindings: media: ti,j721e-csi2rx-shim: Support 32 dma chans Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <20240627-multistream-v2-2-6ae96c54c1c3@ti.com> References: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> In-Reply-To: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> To: Tomi Valkeinen , Mauro Carvalho Chehab , Sakari Ailus , Hans Verkuil , Vaishnav Achath , Maxime Ripard , Rob Herring , Krzysztof Kozlowski , Conor Dooley CC: , , Vignesh Raghavendra , Aradhya Bhatia , Devarsh Thakkar , Changhuang Liang , Jack Zhu , Julien Massot , Laurent Pinchart , Jai Luthra X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=openpgp-sha256; l=2357; i=j-luthra@ti.com; h=from:subject:message-id; bh=24D3XNVBK9Dmv+4yYpQCrJXrk43bw9jFtHr0iPUMswk=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBmfWSzv7MySL0FTesXdooSEM5hPyLoCARKft5Ze 8R/DF6JzmmJAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZn1kswAKCRBD3pH5JJpx RbzKD/4vbD5acj/hG7LS+2Zg+E3I8TtCFax3iAE4aelwhzRiQkl/qJZ6zWLWjI96hnLifePXnNM GP/QV0m8AROv1M4DYOfxDZODwKuPmdnpdNwyxXfK8fAoXiPSYH73D3i3s+yq70TsLaJwYSFeP06 Gyfp//a25HnI0apZSLI4swe3qsg44IVzPAbFWIfzePOVJ/tHMr5NWXkBWjOLGoYfELEjgnBfthQ APVro4n99mytxDDyMjYkvd5hL8zsvWiA0qjPz72H07lWCURKqx2HjeRfzJpH3+eH2KJfSvBEE3d 52NyOmViipLh5BPczHytQhVLd4gdpLAnCkzqkHqZCmGWj72xRbA5zI22RCk8dTSoIsTS5V/8Fu7 VLhbPV6HXYjIF1o7kGvvsI0fC3qD/pDsxFUTF6J6JFwUwu4geTnnWx7+OUJM+6IURiwFMwkU9jg bww2sWImNFP82u7ligtO1JvXlo0Y8HHtQ4130WMsqQ+IViJgHl9yY+w5tvcTlXf+oXdPWPw1Fzq 1Y9iNZdj8qV0V0NQu40vZPiE7UBB0kSIia4uwC6UQj8+iD1chpOZRrwK4lon6mLqBOrTmd5w9CI oyraAcE7aZ2dp+45h3SPDkp2PtHjvNxzsyNbMhsSl85jlRJbCD0iP2RF1v0UloozC3CFyZEs8n4 uXZXtztGH7z+HAQ== X-Developer-Key: i=j-luthra@ti.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 The CSI2RX SHIM IP can support a maximum of 32x DMA channels. These can be used to split incoming "streams" of data on the CSI-RX port, distinguished by MIPI Virtual Channel (or Data Type), into different locations in memory (/dev/videoX nodes). Actual number of DMA channels reserved is different for each SoC integrating this IP, but a maximum of 32x channels are always available in this IP's register space, so set minimum as 1 and maximum as 32. Link: https://www.ti.com/lit/pdf/spruiv7 Signed-off-by: Jai Luthra Reviewed-by: Tomi Valkeinen --- .../bindings/media/ti,j721e-csi2rx-shim.yaml | 39 ++++++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/media/ti,j721e-csi2rx-shim.yaml b/Documentation/devicetree/bindings/media/ti,j721e-csi2rx-shim.yaml index f762fdc05e4d..0e00533c7b68 100644 --- a/Documentation/devicetree/bindings/media/ti,j721e-csi2rx-shim.yaml +++ b/Documentation/devicetree/bindings/media/ti,j721e-csi2rx-shim.yaml @@ -20,11 +20,44 @@ properties: const: ti,j721e-csi2rx-shim dmas: - maxItems: 1 + minItems: 1 + maxItems: 32 dma-names: + minItems: 1 items: - const: rx0 + - const: rx1 + - const: rx2 + - const: rx3 + - const: rx4 + - const: rx5 + - const: rx6 + - const: rx7 + - const: rx8 + - const: rx9 + - const: rx10 + - const: rx11 + - const: rx12 + - const: rx13 + - const: rx14 + - const: rx15 + - const: rx16 + - const: rx17 + - const: rx18 + - const: rx19 + - const: rx20 + - const: rx21 + - const: rx22 + - const: rx23 + - const: rx24 + - const: rx25 + - const: rx26 + - const: rx27 + - const: rx28 + - const: rx29 + - const: rx30 + - const: rx31 reg: maxItems: 1 @@ -62,8 +95,8 @@ examples: ti_csi2rx0: ticsi2rx@4500000 { compatible = "ti,j721e-csi2rx-shim"; - dmas = <&main_udmap 0x4940>; - dma-names = "rx0"; + dmas = <&main_udmap 0x4940>, <&main_udmap 0x4941>; + dma-names = "rx0", "rx1"; reg = <0x4500000 0x1000>; power-domains = <&k3_pds 26 TI_SCI_PD_EXCLUSIVE>; #address-cells = <1>; From patchwork Thu Jun 27 13:09:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 13714393 Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (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 C90E4188CB4; Thu, 27 Jun 2024 13:10:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.19.142 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493859; cv=none; b=S0C1rmlT3uZ03PnnBlDrqqGJVLU0VC2mkZluIbeOFRXK0J4eUDdm29s+1lOfAlZtYHeGNDWY2N1Tsd21nasuqWNa+59NNveC49NuNzMsHLEcrD/K+ZpAmFmBL+p2I+dvDpFMwKhimCJ7dojnM4lIa8KzS9d/zmWzkzddlKCxREw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493859; c=relaxed/simple; bh=RDngiRmegaVpmtiwswQNbcJcgzgEEmR3QpUY2irL1ng=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=B+EhDWv3tbbM4GtsdnR/KN4bAhTdc6atJ2Bkd1F5Lv8WSPbsGhAOCDNOqd96pdyXjmepmfuwQLFVNVs/dJuvLk8Ypvy3xQxfjklYrDRE8YM9iWBqlnelzMqWKXlBHB/nAPsHAFrwEPJF1M/pI7lP7SifuX54JC5UCWD6YzBgo2E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=g5hJ7GNf; arc=none smtp.client-ip=198.47.19.142 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="g5hJ7GNf" Received: from fllv0034.itg.ti.com ([10.64.40.246]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 45RDATHO118614; Thu, 27 Jun 2024 08:10:29 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1719493829; bh=Z0jJIr/emntF1D7KoGv8oiZaVWFFd2ee75t61eDYY6I=; h=From:Date:Subject:References:In-Reply-To:To:CC; b=g5hJ7GNfxDu9yuSSIzg+ieM2FK7owPLUSm+r8qb6UNHPDSzAO9vSMLKw+ZkH6acDn QG1ZAXaOMocAs6ziMUCu5UdaURiLaklnHvsyD9iAOwPodk+2/2WVlXhLzXemTGwsOu 7HbYFmIKTVokexfQle0yOv9GrcAPZtflaMybs+7Y= Received: from DLEE105.ent.ti.com (dlee105.ent.ti.com [157.170.170.35]) by fllv0034.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 45RDAT9B117581 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 27 Jun 2024 08:10:29 -0500 Received: from DLEE114.ent.ti.com (157.170.170.25) by DLEE105.ent.ti.com (157.170.170.35) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Thu, 27 Jun 2024 08:10:29 -0500 Received: from lelvsmtp6.itg.ti.com (10.180.75.249) by DLEE114.ent.ti.com (157.170.170.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Thu, 27 Jun 2024 08:10:29 -0500 Received: from localhost (jluthra.dhcp.ti.com [172.24.227.116]) by lelvsmtp6.itg.ti.com (8.15.2/8.15.2) with ESMTP id 45RDAS2W038515; Thu, 27 Jun 2024 08:10:29 -0500 From: Jai Luthra Date: Thu, 27 Jun 2024 18:39:58 +0530 Subject: [PATCH v2 03/13] media: ti: j721e-csi2rx: separate out device and context Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <20240627-multistream-v2-3-6ae96c54c1c3@ti.com> References: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> In-Reply-To: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> To: Tomi Valkeinen , Mauro Carvalho Chehab , Sakari Ailus , Hans Verkuil , Vaishnav Achath , Maxime Ripard , Rob Herring , Krzysztof Kozlowski , Conor Dooley CC: , , Vignesh Raghavendra , Aradhya Bhatia , Devarsh Thakkar , Changhuang Liang , Jack Zhu , Julien Massot , Laurent Pinchart , Jai Luthra X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=openpgp-sha256; l=26507; i=j-luthra@ti.com; h=from:subject:message-id; bh=RDngiRmegaVpmtiwswQNbcJcgzgEEmR3QpUY2irL1ng=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBmfWS0wwRSMdrfKBHFDGJ0vz14vddHh1HH7atm0 F92UH/ojaqJAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZn1ktAAKCRBD3pH5JJpx RZoqEACHk9wdXAjn1SZEbifpJYWairOrn47XWn/0WgT9bzETYMMFRzV7nV9owWTySAlnWRZmvG+ Y7O+bNExYyospblTkSusw43yxc9BTbmCyQKKU6D+Fjtk2paj6NVshK9FuwGUIIhpKRu1WzOvABi 6S9XTweFEQlpyZttA7m4S4ojXiXg084IE4IKIJglBkfo1FHGSeC39V4n5mGAGNt68wc5kWi9JP6 2Gt8QZ/cWnMdNHDiZFB6ns/xp1IJqgy0PFNEQnYPKuDA92ivCm4MI2+kDANh3TyTykjcDAAB44U iFonZCCwTsHpjm+Q0YY8zDX400tXGh1SDp9g70lSTORYWCF7eZiiEHduW/iCRZ3BeF/xdMtjwZh KoE71SKCjioHcr+OQVYR4T8zR2ynJkNjbbBOFoNPLo2OOFi4mT+5Prf2b+pWAP70puNph6S9Zda ++tnVdhqGB/q7sadNxrzV3VFnKTEwO+vgm9lpV9tDeUHjldCzG4CZh7oLTTbX8JC8p7YH7Q3dRq xQ0sNwRHTgE89b+UJy4e+Vl6okSlWskIal8/WVqib++xr9bmYmU/FrHsATBeM6V6UDxAmM8idkR GLrTE39+ZlTdiFWg/I6lIz3bb7ehkFcocjRitpCw2bl1RTnVbLi/BsrbER0d6xB2+pt+PZtK1f/ e95uK31O/f6tW9w== X-Developer-Key: i=j-luthra@ti.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 The TI CSI2RX wrapper has two parts: the main device and the DMA contexts. The driver was originally written with single camera capture in mind, so only one DMA context was needed. For the sake of simplicity, the context specific stuff was not modeled different to the main device. To enable multiplexed stream capture, the contexts need to be separated out from the main device. Create a struct ti_csi2rx_ctx that holds the DMA context specific things. Separate out functions handling the device and context related functionality. Co-developed-by: Pratyush Yadav Signed-off-by: Pratyush Yadav Signed-off-by: Jai Luthra --- .../media/platform/ti/j721e-csi2rx/j721e-csi2rx.c | 423 ++++++++++++--------- 1 file changed, 242 insertions(+), 181 deletions(-) diff --git a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c index 22442fce7607..d8dfe0002b72 100644 --- a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c +++ b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c @@ -40,6 +40,8 @@ #define SHIM_PSI_CFG0_DST_TAG GENMASK(31, 16) #define PSIL_WORD_SIZE_BYTES 16 +#define TI_CSI2RX_NUM_CTX 1 + /* * There are no hard limits on the width or height. The DMA engine can handle * all sizes. The max width and height are arbitrary numbers for this driver. @@ -64,7 +66,7 @@ struct ti_csi2rx_buffer { /* Common v4l2 buffer. Must be first. */ struct vb2_v4l2_buffer vb; struct list_head list; - struct ti_csi2rx_dev *csi; + struct ti_csi2rx_ctx *ctx; }; enum ti_csi2rx_dma_state { @@ -84,29 +86,37 @@ struct ti_csi2rx_dma { * Queue of buffers submitted to DMA engine. */ struct list_head submitted; - /* Buffer to drain stale data from PSI-L endpoint */ - struct { - void *vaddr; - dma_addr_t paddr; - size_t len; - } drain; +}; + +struct ti_csi2rx_dev; + +struct ti_csi2rx_ctx { + struct ti_csi2rx_dev *csi; + struct video_device vdev; + struct vb2_queue vidq; + struct mutex mutex; /* To serialize ioctls. */ + struct v4l2_format v_fmt; + struct ti_csi2rx_dma dma; + u32 sequence; + u32 idx; }; struct ti_csi2rx_dev { struct device *dev; void __iomem *shim; struct v4l2_device v4l2_dev; - struct video_device vdev; struct media_device mdev; struct media_pipeline pipe; struct media_pad pad; struct v4l2_async_notifier notifier; struct v4l2_subdev *source; - struct vb2_queue vidq; - struct mutex mutex; /* To serialize ioctls. */ - struct v4l2_format v_fmt; - struct ti_csi2rx_dma dma; - u32 sequence; + struct ti_csi2rx_ctx ctx[TI_CSI2RX_NUM_CTX]; + /* Buffer to drain stale data from PSI-L endpoint */ + struct { + void *vaddr; + dma_addr_t paddr; + size_t len; + } drain; }; static const struct ti_csi2rx_fmt ti_csi2rx_formats[] = { @@ -212,7 +222,7 @@ static const struct ti_csi2rx_fmt ti_csi2rx_formats[] = { }; /* Forward declaration needed by ti_csi2rx_dma_callback. */ -static int ti_csi2rx_start_dma(struct ti_csi2rx_dev *csi, +static int ti_csi2rx_start_dma(struct ti_csi2rx_ctx *ctx, struct ti_csi2rx_buffer *buf); static const struct ti_csi2rx_fmt *find_format_by_fourcc(u32 pixelformat) @@ -302,7 +312,7 @@ static int ti_csi2rx_enum_fmt_vid_cap(struct file *file, void *priv, static int ti_csi2rx_g_fmt_vid_cap(struct file *file, void *prov, struct v4l2_format *f) { - struct ti_csi2rx_dev *csi = video_drvdata(file); + struct ti_csi2rx_ctx *csi = video_drvdata(file); *f = csi->v_fmt; @@ -333,7 +343,7 @@ static int ti_csi2rx_try_fmt_vid_cap(struct file *file, void *priv, static int ti_csi2rx_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct ti_csi2rx_dev *csi = video_drvdata(file); + struct ti_csi2rx_ctx *csi = video_drvdata(file); struct vb2_queue *q = &csi->vidq; int ret; @@ -419,25 +429,33 @@ static int csi_async_notifier_bound(struct v4l2_async_notifier *notifier, static int csi_async_notifier_complete(struct v4l2_async_notifier *notifier) { struct ti_csi2rx_dev *csi = dev_get_drvdata(notifier->v4l2_dev->dev); - struct video_device *vdev = &csi->vdev; - int ret; + int ret, i; - ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); - if (ret) - return ret; + for (i = 0; i < TI_CSI2RX_NUM_CTX; i++) { + struct ti_csi2rx_ctx *ctx = &csi->ctx[i]; + struct video_device *vdev = &ctx->vdev; - ret = v4l2_create_fwnode_links_to_pad(csi->source, &csi->pad, - MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); - - if (ret) { - video_unregister_device(vdev); - return ret; + ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); + if (ret) + goto unregister_dev; } + ret = v4l2_create_fwnode_links_to_pad(csi->source, &csi->pad, + MEDIA_LNK_FL_IMMUTABLE | + MEDIA_LNK_FL_ENABLED); + if (ret) + goto unregister_dev; + ret = v4l2_device_register_subdev_nodes(&csi->v4l2_dev); if (ret) - video_unregister_device(vdev); + goto unregister_dev; + + return 0; +unregister_dev: + i--; + for (; i >= 0; i--) + video_unregister_device(&csi->ctx[i].vdev); return ret; } @@ -483,12 +501,13 @@ static int ti_csi2rx_notifier_register(struct ti_csi2rx_dev *csi) return 0; } -static void ti_csi2rx_setup_shim(struct ti_csi2rx_dev *csi) +static void ti_csi2rx_setup_shim(struct ti_csi2rx_ctx *ctx) { + struct ti_csi2rx_dev *csi = ctx->csi; const struct ti_csi2rx_fmt *fmt; unsigned int reg; - fmt = find_format_by_fourcc(csi->v_fmt.fmt.pix.pixelformat); + fmt = find_format_by_fourcc(ctx->v_fmt.fmt.pix.pixelformat); /* De-assert the pixel interface reset. */ reg = SHIM_CNTL_PIX_RST; @@ -555,8 +574,9 @@ static void ti_csi2rx_drain_callback(void *param) * To prevent that stale data corrupting the subsequent transactions, it is * required to issue DMA requests to drain it out. */ -static int ti_csi2rx_drain_dma(struct ti_csi2rx_dev *csi) +static int ti_csi2rx_drain_dma(struct ti_csi2rx_ctx *ctx) { + struct ti_csi2rx_dev *csi = ctx->csi; struct dma_async_tx_descriptor *desc; struct completion drain_complete; dma_cookie_t cookie; @@ -564,8 +584,8 @@ static int ti_csi2rx_drain_dma(struct ti_csi2rx_dev *csi) init_completion(&drain_complete); - desc = dmaengine_prep_slave_single(csi->dma.chan, csi->dma.drain.paddr, - csi->dma.drain.len, DMA_DEV_TO_MEM, + desc = dmaengine_prep_slave_single(ctx->dma.chan, csi->drain.paddr, + csi->drain.len, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!desc) { ret = -EIO; @@ -580,11 +600,11 @@ static int ti_csi2rx_drain_dma(struct ti_csi2rx_dev *csi) if (ret) goto out; - dma_async_issue_pending(csi->dma.chan); + dma_async_issue_pending(ctx->dma.chan); if (!wait_for_completion_timeout(&drain_complete, msecs_to_jiffies(DRAIN_TIMEOUT_MS))) { - dmaengine_terminate_sync(csi->dma.chan); + dmaengine_terminate_sync(ctx->dma.chan); dev_dbg(csi->dev, "DMA transfer timed out for drain buffer\n"); ret = -ETIMEDOUT; goto out; @@ -596,8 +616,8 @@ static int ti_csi2rx_drain_dma(struct ti_csi2rx_dev *csi) static void ti_csi2rx_dma_callback(void *param) { struct ti_csi2rx_buffer *buf = param; - struct ti_csi2rx_dev *csi = buf->csi; - struct ti_csi2rx_dma *dma = &csi->dma; + struct ti_csi2rx_ctx *ctx = buf->ctx; + struct ti_csi2rx_dma *dma = &ctx->dma; unsigned long flags; /* @@ -605,7 +625,7 @@ static void ti_csi2rx_dma_callback(void *param) * hardware monitor registers. */ buf->vb.vb2_buf.timestamp = ktime_get_ns(); - buf->vb.sequence = csi->sequence++; + buf->vb.sequence = ctx->sequence++; spin_lock_irqsave(&dma->lock, flags); @@ -617,8 +637,9 @@ static void ti_csi2rx_dma_callback(void *param) while (!list_empty(&dma->queue)) { buf = list_entry(dma->queue.next, struct ti_csi2rx_buffer, list); - if (ti_csi2rx_start_dma(csi, buf)) { - dev_err(csi->dev, "Failed to queue the next buffer for DMA\n"); + if (ti_csi2rx_start_dma(ctx, buf)) { + dev_err(ctx->csi->dev, + "Failed to queue the next buffer for DMA\n"); vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); } else { list_move_tail(&buf->list, &dma->submitted); @@ -631,17 +652,17 @@ static void ti_csi2rx_dma_callback(void *param) spin_unlock_irqrestore(&dma->lock, flags); } -static int ti_csi2rx_start_dma(struct ti_csi2rx_dev *csi, +static int ti_csi2rx_start_dma(struct ti_csi2rx_ctx *ctx, struct ti_csi2rx_buffer *buf) { unsigned long addr; struct dma_async_tx_descriptor *desc; - size_t len = csi->v_fmt.fmt.pix.sizeimage; + size_t len = ctx->v_fmt.fmt.pix.sizeimage; dma_cookie_t cookie; int ret = 0; addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0); - desc = dmaengine_prep_slave_single(csi->dma.chan, addr, len, + desc = dmaengine_prep_slave_single(ctx->dma.chan, addr, len, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!desc) @@ -655,20 +676,20 @@ static int ti_csi2rx_start_dma(struct ti_csi2rx_dev *csi, if (ret) return ret; - dma_async_issue_pending(csi->dma.chan); + dma_async_issue_pending(ctx->dma.chan); return 0; } -static void ti_csi2rx_stop_dma(struct ti_csi2rx_dev *csi) +static void ti_csi2rx_stop_dma(struct ti_csi2rx_ctx *ctx) { - struct ti_csi2rx_dma *dma = &csi->dma; + struct ti_csi2rx_dma *dma = &ctx->dma; enum ti_csi2rx_dma_state state; unsigned long flags; int ret; spin_lock_irqsave(&dma->lock, flags); - state = csi->dma.state; + state = ctx->dma.state; dma->state = TI_CSI2RX_DMA_STOPPED; spin_unlock_irqrestore(&dma->lock, flags); @@ -679,30 +700,30 @@ static void ti_csi2rx_stop_dma(struct ti_csi2rx_dev *csi) * is stopped, as the module-level pixel reset cannot be * enforced before terminating DMA. */ - ret = ti_csi2rx_drain_dma(csi); + ret = ti_csi2rx_drain_dma(ctx); if (ret && ret != -ETIMEDOUT) - dev_warn(csi->dev, + dev_warn(ctx->csi->dev, "Failed to drain DMA. Next frame might be bogus\n"); } - ret = dmaengine_terminate_sync(csi->dma.chan); + ret = dmaengine_terminate_sync(ctx->dma.chan); if (ret) - dev_err(csi->dev, "Failed to stop DMA: %d\n", ret); + dev_err(ctx->csi->dev, "Failed to stop DMA: %d\n", ret); } -static void ti_csi2rx_cleanup_buffers(struct ti_csi2rx_dev *csi, +static void ti_csi2rx_cleanup_buffers(struct ti_csi2rx_ctx *ctx, enum vb2_buffer_state state) { - struct ti_csi2rx_dma *dma = &csi->dma; + struct ti_csi2rx_dma *dma = &ctx->dma; struct ti_csi2rx_buffer *buf, *tmp; unsigned long flags; spin_lock_irqsave(&dma->lock, flags); - list_for_each_entry_safe(buf, tmp, &csi->dma.queue, list) { + list_for_each_entry_safe(buf, tmp, &ctx->dma.queue, list) { list_del(&buf->list); vb2_buffer_done(&buf->vb.vb2_buf, state); } - list_for_each_entry_safe(buf, tmp, &csi->dma.submitted, list) { + list_for_each_entry_safe(buf, tmp, &ctx->dma.submitted, list) { list_del(&buf->list); vb2_buffer_done(&buf->vb.vb2_buf, state); } @@ -713,8 +734,8 @@ static int ti_csi2rx_queue_setup(struct vb2_queue *q, unsigned int *nbuffers, unsigned int *nplanes, unsigned int sizes[], struct device *alloc_devs[]) { - struct ti_csi2rx_dev *csi = vb2_get_drv_priv(q); - unsigned int size = csi->v_fmt.fmt.pix.sizeimage; + struct ti_csi2rx_ctx *ctx = vb2_get_drv_priv(q); + unsigned int size = ctx->v_fmt.fmt.pix.sizeimage; if (*nplanes) { if (sizes[0] < size) @@ -730,11 +751,11 @@ static int ti_csi2rx_queue_setup(struct vb2_queue *q, unsigned int *nbuffers, static int ti_csi2rx_buffer_prepare(struct vb2_buffer *vb) { - struct ti_csi2rx_dev *csi = vb2_get_drv_priv(vb->vb2_queue); - unsigned long size = csi->v_fmt.fmt.pix.sizeimage; + struct ti_csi2rx_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + unsigned long size = ctx->v_fmt.fmt.pix.sizeimage; if (vb2_plane_size(vb, 0) < size) { - dev_err(csi->dev, "Data will not fit into plane\n"); + dev_err(ctx->csi->dev, "Data will not fit into plane\n"); return -EINVAL; } @@ -744,15 +765,15 @@ static int ti_csi2rx_buffer_prepare(struct vb2_buffer *vb) static void ti_csi2rx_buffer_queue(struct vb2_buffer *vb) { - struct ti_csi2rx_dev *csi = vb2_get_drv_priv(vb->vb2_queue); + struct ti_csi2rx_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); struct ti_csi2rx_buffer *buf; - struct ti_csi2rx_dma *dma = &csi->dma; + struct ti_csi2rx_dma *dma = &ctx->dma; bool restart_dma = false; unsigned long flags = 0; int ret; buf = container_of(vb, struct ti_csi2rx_buffer, vb.vb2_buf); - buf->csi = csi; + buf->ctx = ctx; spin_lock_irqsave(&dma->lock, flags); /* @@ -781,18 +802,18 @@ static void ti_csi2rx_buffer_queue(struct vb2_buffer *vb) * the application and will only confuse it. Issue a DMA * transaction to drain that up. */ - ret = ti_csi2rx_drain_dma(csi); + ret = ti_csi2rx_drain_dma(ctx); if (ret && ret != -ETIMEDOUT) - dev_warn(csi->dev, + dev_warn(ctx->csi->dev, "Failed to drain DMA. Next frame might be bogus\n"); spin_lock_irqsave(&dma->lock, flags); - ret = ti_csi2rx_start_dma(csi, buf); + ret = ti_csi2rx_start_dma(ctx, buf); if (ret) { vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); dma->state = TI_CSI2RX_DMA_IDLE; spin_unlock_irqrestore(&dma->lock, flags); - dev_err(csi->dev, "Failed to start DMA: %d\n", ret); + dev_err(ctx->csi->dev, "Failed to start DMA: %d\n", ret); } else { list_add_tail(&buf->list, &dma->submitted); spin_unlock_irqrestore(&dma->lock, flags); @@ -802,8 +823,9 @@ static void ti_csi2rx_buffer_queue(struct vb2_buffer *vb) static int ti_csi2rx_start_streaming(struct vb2_queue *vq, unsigned int count) { - struct ti_csi2rx_dev *csi = vb2_get_drv_priv(vq); - struct ti_csi2rx_dma *dma = &csi->dma; + struct ti_csi2rx_ctx *ctx = vb2_get_drv_priv(vq); + struct ti_csi2rx_dev *csi = ctx->csi; + struct ti_csi2rx_dma *dma = &ctx->dma; struct ti_csi2rx_buffer *buf; unsigned long flags; int ret = 0; @@ -815,18 +837,18 @@ static int ti_csi2rx_start_streaming(struct vb2_queue *vq, unsigned int count) if (ret) return ret; - ret = video_device_pipeline_start(&csi->vdev, &csi->pipe); + ret = video_device_pipeline_start(&ctx->vdev, &csi->pipe); if (ret) goto err; - ti_csi2rx_setup_shim(csi); + ti_csi2rx_setup_shim(ctx); - csi->sequence = 0; + ctx->sequence = 0; spin_lock_irqsave(&dma->lock, flags); buf = list_entry(dma->queue.next, struct ti_csi2rx_buffer, list); - ret = ti_csi2rx_start_dma(csi, buf); + ret = ti_csi2rx_start_dma(ctx, buf); if (ret) { dev_err(csi->dev, "Failed to start DMA: %d\n", ret); spin_unlock_irqrestore(&dma->lock, flags); @@ -844,22 +866,23 @@ static int ti_csi2rx_start_streaming(struct vb2_queue *vq, unsigned int count) return 0; err_dma: - ti_csi2rx_stop_dma(csi); + ti_csi2rx_stop_dma(ctx); err_pipeline: - video_device_pipeline_stop(&csi->vdev); + video_device_pipeline_stop(&ctx->vdev); writel(0, csi->shim + SHIM_CNTL); writel(0, csi->shim + SHIM_DMACNTX); err: - ti_csi2rx_cleanup_buffers(csi, VB2_BUF_STATE_QUEUED); + ti_csi2rx_cleanup_buffers(ctx, VB2_BUF_STATE_QUEUED); return ret; } static void ti_csi2rx_stop_streaming(struct vb2_queue *vq) { - struct ti_csi2rx_dev *csi = vb2_get_drv_priv(vq); + struct ti_csi2rx_ctx *ctx = vb2_get_drv_priv(vq); + struct ti_csi2rx_dev *csi = ctx->csi; int ret; - video_device_pipeline_stop(&csi->vdev); + video_device_pipeline_stop(&ctx->vdev); writel(0, csi->shim + SHIM_CNTL); writel(0, csi->shim + SHIM_DMACNTX); @@ -868,8 +891,8 @@ static void ti_csi2rx_stop_streaming(struct vb2_queue *vq) if (ret) dev_err(csi->dev, "Failed to stop subdev stream\n"); - ti_csi2rx_stop_dma(csi); - ti_csi2rx_cleanup_buffers(csi, VB2_BUF_STATE_ERROR); + ti_csi2rx_stop_dma(ctx); + ti_csi2rx_cleanup_buffers(ctx, VB2_BUF_STATE_ERROR); } static const struct vb2_ops csi_vb2_qops = { @@ -882,27 +905,60 @@ static const struct vb2_ops csi_vb2_qops = { .wait_finish = vb2_ops_wait_finish, }; -static int ti_csi2rx_init_vb2q(struct ti_csi2rx_dev *csi) +static void ti_csi2rx_cleanup_dma(struct ti_csi2rx_ctx *ctx) { - struct vb2_queue *q = &csi->vidq; + dma_release_channel(ctx->dma.chan); +} + +static void ti_csi2rx_cleanup_v4l2(struct ti_csi2rx_dev *csi) +{ + media_device_unregister(&csi->mdev); + v4l2_device_unregister(&csi->v4l2_dev); + media_device_cleanup(&csi->mdev); +} + +static void ti_csi2rx_cleanup_notifier(struct ti_csi2rx_dev *csi) +{ + v4l2_async_nf_unregister(&csi->notifier); + v4l2_async_nf_cleanup(&csi->notifier); +} + +static void ti_csi2rx_cleanup_vb2q(struct ti_csi2rx_ctx *ctx) +{ + vb2_queue_release(&ctx->vidq); +} + +static void ti_csi2rx_cleanup_ctx(struct ti_csi2rx_ctx *ctx) +{ + ti_csi2rx_cleanup_dma(ctx); + ti_csi2rx_cleanup_vb2q(ctx); + + video_unregister_device(&ctx->vdev); + + mutex_destroy(&ctx->mutex); +} + +static int ti_csi2rx_init_vb2q(struct ti_csi2rx_ctx *ctx) +{ + struct vb2_queue *q = &ctx->vidq; int ret; q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; q->io_modes = VB2_MMAP | VB2_DMABUF; - q->drv_priv = csi; + q->drv_priv = ctx; q->buf_struct_size = sizeof(struct ti_csi2rx_buffer); q->ops = &csi_vb2_qops; q->mem_ops = &vb2_dma_contig_memops; q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; - q->dev = dmaengine_get_dma_device(csi->dma.chan); - q->lock = &csi->mutex; + q->dev = dmaengine_get_dma_device(ctx->dma.chan); + q->lock = &ctx->mutex; q->min_queued_buffers = 1; ret = vb2_queue_init(q); if (ret) return ret; - csi->vdev.queue = q; + ctx->vdev.queue = q; return 0; } @@ -911,8 +967,9 @@ static int ti_csi2rx_link_validate(struct media_link *link) { struct media_entity *entity = link->sink->entity; struct video_device *vdev = media_entity_to_video_device(entity); - struct ti_csi2rx_dev *csi = container_of(vdev, struct ti_csi2rx_dev, vdev); - struct v4l2_pix_format *csi_fmt = &csi->v_fmt.fmt.pix; + struct ti_csi2rx_ctx *ctx = container_of(vdev, struct ti_csi2rx_ctx, vdev); + struct ti_csi2rx_dev *csi = ctx->csi; + struct v4l2_pix_format *csi_fmt = &ctx->v_fmt.fmt.pix; struct v4l2_subdev_format source_fmt = { .which = V4L2_SUBDEV_FORMAT_ACTIVE, .pad = link->source->index, @@ -965,47 +1022,69 @@ static const struct media_entity_operations ti_csi2rx_video_entity_ops = { .link_validate = ti_csi2rx_link_validate, }; -static int ti_csi2rx_init_dma(struct ti_csi2rx_dev *csi) +static int ti_csi2rx_init_dma(struct ti_csi2rx_ctx *ctx) { struct dma_slave_config cfg = { .src_addr_width = DMA_SLAVE_BUSWIDTH_16_BYTES, }; int ret; - INIT_LIST_HEAD(&csi->dma.queue); - INIT_LIST_HEAD(&csi->dma.submitted); - spin_lock_init(&csi->dma.lock); + INIT_LIST_HEAD(&ctx->dma.queue); + INIT_LIST_HEAD(&ctx->dma.submitted); + spin_lock_init(&ctx->dma.lock); - csi->dma.state = TI_CSI2RX_DMA_STOPPED; + ctx->dma.state = TI_CSI2RX_DMA_STOPPED; - csi->dma.chan = dma_request_chan(csi->dev, "rx0"); - if (IS_ERR(csi->dma.chan)) - return PTR_ERR(csi->dma.chan); + ctx->dma.chan = dma_request_chan(ctx->csi->dev, "rx0"); + if (IS_ERR(ctx->dma.chan)) + return PTR_ERR(ctx->dma.chan); - ret = dmaengine_slave_config(csi->dma.chan, &cfg); + ret = dmaengine_slave_config(ctx->dma.chan, &cfg); if (ret) { - dma_release_channel(csi->dma.chan); + dma_release_channel(ctx->dma.chan); return ret; } - csi->dma.drain.len = DRAIN_BUFFER_SIZE; - csi->dma.drain.vaddr = dma_alloc_coherent(csi->dev, csi->dma.drain.len, - &csi->dma.drain.paddr, - GFP_KERNEL); - if (!csi->dma.drain.vaddr) - return -ENOMEM; - return 0; } static int ti_csi2rx_v4l2_init(struct ti_csi2rx_dev *csi) { struct media_device *mdev = &csi->mdev; - struct video_device *vdev = &csi->vdev; + int ret; + + mdev->dev = csi->dev; + mdev->hw_revision = 1; + strscpy(mdev->model, "TI-CSI2RX", sizeof(mdev->model)); + + media_device_init(mdev); + + csi->v4l2_dev.mdev = mdev; + + ret = v4l2_device_register(csi->dev, &csi->v4l2_dev); + if (ret) + return ret; + + ret = media_device_register(mdev); + if (ret) { + v4l2_device_unregister(&csi->v4l2_dev); + media_device_cleanup(mdev); + return ret; + } + + return 0; +} + +static int ti_csi2rx_init_ctx(struct ti_csi2rx_ctx *ctx) +{ + struct ti_csi2rx_dev *csi = ctx->csi; + struct video_device *vdev = &ctx->vdev; const struct ti_csi2rx_fmt *fmt; - struct v4l2_pix_format *pix_fmt = &csi->v_fmt.fmt.pix; + struct v4l2_pix_format *pix_fmt = &ctx->v_fmt.fmt.pix; int ret; + mutex_init(&ctx->mutex); + fmt = find_format_by_fourcc(V4L2_PIX_FMT_UYVY); if (!fmt) return -EINVAL; @@ -1018,15 +1097,16 @@ static int ti_csi2rx_v4l2_init(struct ti_csi2rx_dev *csi) pix_fmt->quantization = V4L2_QUANTIZATION_LIM_RANGE, pix_fmt->xfer_func = V4L2_XFER_FUNC_SRGB, - ti_csi2rx_fill_fmt(fmt, &csi->v_fmt); - - mdev->dev = csi->dev; - mdev->hw_revision = 1; - strscpy(mdev->model, "TI-CSI2RX", sizeof(mdev->model)); + ti_csi2rx_fill_fmt(fmt, &ctx->v_fmt); - media_device_init(mdev); + csi->pad.flags = MEDIA_PAD_FL_SINK; + vdev->entity.ops = &ti_csi2rx_video_entity_ops; + ret = media_entity_pads_init(&ctx->vdev.entity, 1, &csi->pad); + if (ret) + return ret; - strscpy(vdev->name, TI_CSI2RX_MODULE_NAME, sizeof(vdev->name)); + snprintf(vdev->name, sizeof(vdev->name), "%s context %u", + dev_name(csi->dev), ctx->idx); vdev->v4l2_dev = &csi->v4l2_dev; vdev->vfl_dir = VFL_DIR_RX; vdev->fops = &csi_fops; @@ -1034,61 +1114,28 @@ static int ti_csi2rx_v4l2_init(struct ti_csi2rx_dev *csi) vdev->release = video_device_release_empty; vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | V4L2_CAP_IO_MC; - vdev->lock = &csi->mutex; - video_set_drvdata(vdev, csi); + vdev->lock = &ctx->mutex; + video_set_drvdata(vdev, ctx); - csi->pad.flags = MEDIA_PAD_FL_SINK; - vdev->entity.ops = &ti_csi2rx_video_entity_ops; - ret = media_entity_pads_init(&csi->vdev.entity, 1, &csi->pad); + ret = ti_csi2rx_init_dma(ctx); if (ret) return ret; - csi->v4l2_dev.mdev = mdev; - - ret = v4l2_device_register(csi->dev, &csi->v4l2_dev); + ret = ti_csi2rx_init_vb2q(ctx); if (ret) - return ret; - - ret = media_device_register(mdev); - if (ret) { - v4l2_device_unregister(&csi->v4l2_dev); - media_device_cleanup(mdev); - return ret; - } + goto cleanup_dma; return 0; -} -static void ti_csi2rx_cleanup_dma(struct ti_csi2rx_dev *csi) -{ - dma_free_coherent(csi->dev, csi->dma.drain.len, - csi->dma.drain.vaddr, csi->dma.drain.paddr); - csi->dma.drain.vaddr = NULL; - dma_release_channel(csi->dma.chan); -} - -static void ti_csi2rx_cleanup_v4l2(struct ti_csi2rx_dev *csi) -{ - media_device_unregister(&csi->mdev); - v4l2_device_unregister(&csi->v4l2_dev); - media_device_cleanup(&csi->mdev); -} - -static void ti_csi2rx_cleanup_subdev(struct ti_csi2rx_dev *csi) -{ - v4l2_async_nf_unregister(&csi->notifier); - v4l2_async_nf_cleanup(&csi->notifier); -} - -static void ti_csi2rx_cleanup_vb2q(struct ti_csi2rx_dev *csi) -{ - vb2_queue_release(&csi->vidq); +cleanup_dma: + ti_csi2rx_cleanup_dma(ctx); + return ret; } static int ti_csi2rx_probe(struct platform_device *pdev) { struct ti_csi2rx_dev *csi; - int ret; + int ret, i; csi = devm_kzalloc(&pdev->dev, sizeof(*csi), GFP_KERNEL); if (!csi) @@ -1097,62 +1144,76 @@ static int ti_csi2rx_probe(struct platform_device *pdev) csi->dev = &pdev->dev; platform_set_drvdata(pdev, csi); - mutex_init(&csi->mutex); csi->shim = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(csi->shim)) { ret = PTR_ERR(csi->shim); - goto err_mutex; + return ret; } - ret = ti_csi2rx_init_dma(csi); - if (ret) - goto err_mutex; + csi->drain.len = DRAIN_BUFFER_SIZE; + csi->drain.vaddr = dma_alloc_coherent(csi->dev, csi->drain.len, + &csi->drain.paddr, + GFP_KERNEL); + if (!csi->drain.vaddr) + return -ENOMEM; ret = ti_csi2rx_v4l2_init(csi); - if (ret) - goto err_dma; - - ret = ti_csi2rx_init_vb2q(csi); if (ret) goto err_v4l2; + for (i = 0; i < TI_CSI2RX_NUM_CTX; i++) { + csi->ctx[i].idx = i; + csi->ctx[i].csi = csi; + ret = ti_csi2rx_init_ctx(&csi->ctx[i]); + if (ret) + goto err_ctx; + } + ret = ti_csi2rx_notifier_register(csi); if (ret) - goto err_vb2q; + goto err_ctx; ret = of_platform_populate(csi->dev->of_node, NULL, NULL, csi->dev); if (ret) { dev_err(csi->dev, "Failed to create children: %d\n", ret); - goto err_subdev; + goto err_notifier; } return 0; -err_subdev: - ti_csi2rx_cleanup_subdev(csi); -err_vb2q: - ti_csi2rx_cleanup_vb2q(csi); -err_v4l2: +err_notifier: + ti_csi2rx_cleanup_notifier(csi); +err_ctx: + i--; + for (; i >= 0; i--) + ti_csi2rx_cleanup_ctx(&csi->ctx[i]); ti_csi2rx_cleanup_v4l2(csi); -err_dma: - ti_csi2rx_cleanup_dma(csi); -err_mutex: - mutex_destroy(&csi->mutex); +err_v4l2: + dma_free_coherent(csi->dev, csi->drain.len, csi->drain.vaddr, + csi->drain.paddr); return ret; } static void ti_csi2rx_remove(struct platform_device *pdev) { struct ti_csi2rx_dev *csi = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < TI_CSI2RX_NUM_CTX; i++) { + if (vb2_is_busy(&csi->ctx[i].vidq)) + dev_err(csi->dev, + "Failed to remove as queue busy for ctx %u\n", + i); + } - video_unregister_device(&csi->vdev); + for (i = 0; i < TI_CSI2RX_NUM_CTX; i++) + ti_csi2rx_cleanup_ctx(&csi->ctx[i]); - ti_csi2rx_cleanup_vb2q(csi); - ti_csi2rx_cleanup_subdev(csi); + ti_csi2rx_cleanup_notifier(csi); ti_csi2rx_cleanup_v4l2(csi); - ti_csi2rx_cleanup_dma(csi); - mutex_destroy(&csi->mutex); + dma_free_coherent(csi->dev, csi->drain.len, csi->drain.vaddr, + csi->drain.paddr); } static const struct of_device_id ti_csi2rx_of_match[] = { From patchwork Thu Jun 27 13:09:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 13714384 Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) (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 77F1B18A939; Thu, 27 Jun 2024 13:10:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.19.141 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493848; cv=none; b=Q722P1LXUADmzn75TQtPR5Gxt7zIVIEVIhNNabefu/vpUBdEvP4ud9tMrp5+VsQTEckzUGDuMmdbc+KObWTIPO2o7enfe66gJLQIkCh7q9o6ZgDge6MBYb0nrxnyDrfUIyi7P3s3+rX+y1aQMlowrmP+LZTaFiswHZF05gmrnGU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493848; c=relaxed/simple; bh=v3gEkPdG9b7eYy0/FF4jb8UhEm5GRijCHvs7LwoGo2E=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=IlhWeFJR2aOoqLzdEoQgIox/2Ds1p3Z3mpqbFP03c3nJCbrzCrdsA54AbwS9ek515l5UrbHW88WfOtvWCRBOfx3wcsqjh/uodd2zmfVnZIfplBcsFMcI7fKRyvxAVZotEZPF5f68NEx1lOW2wmHIpoRIc6AS1670xT55Ru+TKSA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=jar8vWOi; arc=none smtp.client-ip=198.47.19.141 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="jar8vWOi" Received: from fllv0035.itg.ti.com ([10.64.41.0]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 45RDAVN4117473; Thu, 27 Jun 2024 08:10:31 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1719493831; bh=HB+flKInIVpcWdRlTa6Zzhif0gbdAzt/xBNWPP/eYRM=; h=From:Date:Subject:References:In-Reply-To:To:CC; b=jar8vWOiLrruK8MMulrKuxWAapYVqAqdQKV5XAFY97S0vHht1PFk55v2hHvNcccpx 0WdmUbIyismcQy6O1Qw4VK+Q0NHnUnBV3WgX89fShkMgULkwd+oufhlzhTTgs29iBa LUGA+ijSYITLE+/cmUGpulP5CvtgeGaOnLxVOgvE= Received: from DFLE111.ent.ti.com (dfle111.ent.ti.com [10.64.6.32]) by fllv0035.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 45RDAV9f095648 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 27 Jun 2024 08:10:31 -0500 Received: from DFLE103.ent.ti.com (10.64.6.24) by DFLE111.ent.ti.com (10.64.6.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Thu, 27 Jun 2024 08:10:30 -0500 Received: from lelvsmtp6.itg.ti.com (10.180.75.249) by DFLE103.ent.ti.com (10.64.6.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Thu, 27 Jun 2024 08:10:30 -0500 Received: from localhost (jluthra.dhcp.ti.com [172.24.227.116]) by lelvsmtp6.itg.ti.com (8.15.2/8.15.2) with ESMTP id 45RDAURw038539; Thu, 27 Jun 2024 08:10:30 -0500 From: Jai Luthra Date: Thu, 27 Jun 2024 18:39:59 +0530 Subject: [PATCH v2 04/13] media: ti: j721e-csi2rx: prepare SHIM code for multiple contexts Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <20240627-multistream-v2-4-6ae96c54c1c3@ti.com> References: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> In-Reply-To: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> To: Tomi Valkeinen , Mauro Carvalho Chehab , Sakari Ailus , Hans Verkuil , Vaishnav Achath , Maxime Ripard , Rob Herring , Krzysztof Kozlowski , Conor Dooley CC: , , Vignesh Raghavendra , Aradhya Bhatia , Devarsh Thakkar , Changhuang Liang , Jack Zhu , Julien Massot , Laurent Pinchart , Jai Luthra X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=openpgp-sha256; l=2436; i=j-luthra@ti.com; h=from:subject:message-id; bh=LpLlB+YmYVSUi0YgNLhdccCiz/SToDm+eRN4FDifDXY=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBmfWS1ploOz/OFRtwmZ4wW5tZGbQtitE0Iek7JG WFkFRE9kcCJAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZn1ktQAKCRBD3pH5JJpx RQTTD/9/W9Pi0VpvwdtJW2kwsoUWw/RQl4maIOR1WULpe7FZmEepcywqdvv95i/t0ILfXqFHZOF CSSPVSVHUW3m4tx96o2g5C2W+OoTaisnfMoR9tu2we/2Gk5BrlyWApY02TYeYTg1883cLzfVcmo fa8lIokLUDouFd1LJDxn0l6f3gx3fgHNymZzzS3UdpWP2QvAWJaBeEC+0CyDEO1FumsTHHF0xAA yc8FfCNZQd7g6XxPy6eiPXltn6e3WmrSkf02woxJ5JBrT2m6BZB5KcAK4eDuDhKdt7g1wBPodQX 8N0CS0cGbwUR87oXePZVfj7/I9lBupFibxjfTEMYhbo7uyUNfIsZER0qLuTIyhoALGXfIJjGICN 4qwqdL+2GhivLaUTkUAhKbT8ZWVYcNvrmgJgAMLPzWuEfwX1b0e7kQT36M1gLxde2Id8m+3i1Cc Sjusf+iC+KguFSCmCMmrNSMFDkXB956veWJ9L1NFk556/pGm6K9Xbi+V3eTYHgIG+MVcBwFvr7Z MEVqOERM7olWVnK9eOjOpEzDta/B5Tk+kpsZCA9WAs5+Oi7gw7wV6bMccKne1JYhdQdnrdRVKyJ CZdbvLgyWTBPSG4pZXTPH3eIk0MgiTtBIKJEeX5eDkoj4lmt8KNsYfkQ0dW8+7tNSZOjJ5wZxKC cnvuc68MpmAsQDw== X-Developer-Key: i=j-luthra@ti.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 From: Pratyush Yadav Currently the SHIM code to configure the context only touches the first context. Add support for writing to the context's registers based on the context index. Signed-off-by: Pratyush Yadav Signed-off-by: Jai Luthra --- drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c index d8dfe0002b72..bffc8165fd33 100644 --- a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c +++ b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c @@ -25,7 +25,7 @@ #define SHIM_CNTL 0x10 #define SHIM_CNTL_PIX_RST BIT(0) -#define SHIM_DMACNTX 0x20 +#define SHIM_DMACNTX(i) (0x20 + ((i) * 0x20)) #define SHIM_DMACNTX_EN BIT(31) #define SHIM_DMACNTX_YUV422 GENMASK(27, 26) #define SHIM_DMACNTX_SIZE GENMASK(21, 20) @@ -35,7 +35,7 @@ #define SHIM_DMACNTX_SIZE_16 1 #define SHIM_DMACNTX_SIZE_32 2 -#define SHIM_PSI_CFG0 0x24 +#define SHIM_PSI_CFG0(i) (0x24 + ((i) * 0x20)) #define SHIM_PSI_CFG0_SRC_TAG GENMASK(15, 0) #define SHIM_PSI_CFG0_DST_TAG GENMASK(31, 16) @@ -549,11 +549,11 @@ static void ti_csi2rx_setup_shim(struct ti_csi2rx_ctx *ctx) reg |= FIELD_PREP(SHIM_DMACNTX_SIZE, fmt->size); - writel(reg, csi->shim + SHIM_DMACNTX); + writel(reg, csi->shim + SHIM_DMACNTX(ctx->idx)); reg = FIELD_PREP(SHIM_PSI_CFG0_SRC_TAG, 0) | FIELD_PREP(SHIM_PSI_CFG0_DST_TAG, 0); - writel(reg, csi->shim + SHIM_PSI_CFG0); + writel(reg, csi->shim + SHIM_PSI_CFG0(ctx->idx)); } static void ti_csi2rx_drain_callback(void *param) @@ -870,7 +870,7 @@ static int ti_csi2rx_start_streaming(struct vb2_queue *vq, unsigned int count) err_pipeline: video_device_pipeline_stop(&ctx->vdev); writel(0, csi->shim + SHIM_CNTL); - writel(0, csi->shim + SHIM_DMACNTX); + writel(0, csi->shim + SHIM_DMACNTX(ctx->idx)); err: ti_csi2rx_cleanup_buffers(ctx, VB2_BUF_STATE_QUEUED); return ret; @@ -885,7 +885,7 @@ static void ti_csi2rx_stop_streaming(struct vb2_queue *vq) video_device_pipeline_stop(&ctx->vdev); writel(0, csi->shim + SHIM_CNTL); - writel(0, csi->shim + SHIM_DMACNTX); + writel(0, csi->shim + SHIM_DMACNTX(ctx->idx)); ret = v4l2_subdev_call(csi->source, video, s_stream, 0); if (ret) From patchwork Thu Jun 27 13:10:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 13714385 Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) (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 5A47D187541; Thu, 27 Jun 2024 13:10:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.19.141 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493849; cv=none; b=Sd3gEVS83tzEzqa+R+LgKkDVd6+zVgiUbfSjH2Tmh4O86c5T+I5BQ3aWU5zx08eOLOsWcB/VLD0iXcwZlyn+Q0Sse3ssXHDJS9zrHIfeRY29HVhelOKJ8voHxXVBAzczALyisiIaZozz2DZ++X+TqMXzL1hJb2AQorg6ATPtn+g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493849; c=relaxed/simple; bh=8r2RdSHt2YjQ0rTY1yZfo7ktNYhxZheXvFzleRNTY/E=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=pipOUNLWD+3MeBK+Wq0h1tON2iOkc6TRRuBPMn06zsJhwwotXMTPJOUu4oxTkPoGgavFUnoU/T4MvU+VRrhDfm/xxXWT7brk7iqAqGV+2XZVMKLwgfUQ9J5RgFYFRUbgvj7g7QOGBiVBmB7yhYIkWnZVMPUgir97wDbH69X0U0Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=gGyJ6tCz; arc=none smtp.client-ip=198.47.19.141 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="gGyJ6tCz" Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 45RDAWqL117536; Thu, 27 Jun 2024 08:10:32 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1719493832; bh=rvjj93156JqPjji8laigDSZtIiGKXU+ePd7dmdJpi98=; h=From:Date:Subject:References:In-Reply-To:To:CC; b=gGyJ6tCzW+Q8GGi0ZWXJ8MXd7o85NDAh93Br+DvhZi5rTuOzZrIfmKMBT53MMnv51 cY5r+wOeIZDL90pommvuCPMvG/aags4MenUTRX69kPOFsTgSsaY4PYxrTOJMTxy2ap J7n8xyo6TEmOQg9tiGZ6ICO9Bord82m3ZTuC8IRY= Received: from DLEE111.ent.ti.com (dlee111.ent.ti.com [157.170.170.22]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 45RDAWdK029330 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 27 Jun 2024 08:10:32 -0500 Received: from DLEE108.ent.ti.com (157.170.170.38) by DLEE111.ent.ti.com (157.170.170.22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Thu, 27 Jun 2024 08:10:32 -0500 Received: from lelvsmtp5.itg.ti.com (10.180.75.250) by DLEE108.ent.ti.com (157.170.170.38) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Thu, 27 Jun 2024 08:10:32 -0500 Received: from localhost (jluthra.dhcp.ti.com [172.24.227.116]) by lelvsmtp5.itg.ti.com (8.15.2/8.15.2) with ESMTP id 45RDAVXb072157; Thu, 27 Jun 2024 08:10:32 -0500 From: Jai Luthra Date: Thu, 27 Jun 2024 18:40:00 +0530 Subject: [PATCH v2 05/13] media: ti: j721e-csi2rx: allocate DMA channel based on context index Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <20240627-multistream-v2-5-6ae96c54c1c3@ti.com> References: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> In-Reply-To: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> To: Tomi Valkeinen , Mauro Carvalho Chehab , Sakari Ailus , Hans Verkuil , Vaishnav Achath , Maxime Ripard , Rob Herring , Krzysztof Kozlowski , Conor Dooley CC: , , Vignesh Raghavendra , Aradhya Bhatia , Devarsh Thakkar , Changhuang Liang , Jack Zhu , Julien Massot , Laurent Pinchart , Jai Luthra X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=openpgp-sha256; l=1393; i=j-luthra@ti.com; h=from:subject:message-id; bh=R9mMnP/JSopLpke8aHuxGzEhJHa0s3R5X6kvouNnMf8=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBmfWS2jEPMEc2y61Zlo+3X8LmuexbBUcb5vxcxx UpixU69HFGJAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZn1ktgAKCRBD3pH5JJpx RdRCEADBwHMtFRzckWo9F/DwThFX3D8U9LwT7CI/bsbn12iDimB+zoCL9rupURqA49YBQ4MvKPI 66H0OE+rPWwVeCAqhiBcUh5om3jTmDgJpTNOD5f0oQAuFMt6F65k32NWMOjVi8T7pdQG5DtGDHX sW4ZBAdRm7HAL6V5XzZja0dNGnPGOdAfU2Oy5DBrrzPojHnRFk4WGMAejI43ECgCJ2UrtpA3a2U N4p70zwh8NcqiTK+WZFf+Pf7Ugr8UzKKsXmVZhflilFgXJLHV2T2G8BhzLLB36A1A4OpHHJ4gy9 i2cavG9Pp22QpQTNUmlQ9BzQ9TSYvcH+EcSowbNtcXKRCdQjRfkE+begaVIjKGPQop4TatcO+g8 E/VcYH3oAlFTKCqbfokAKGga6MQY7yp2/Kml3EKtpJH0rw0FpRoUCGqqDjZxwxGJxyzaL3z8j+6 f2VxHWf5Sgz2qQNGb4R3vffE6Hfy3B7/h0apgkhOUAUUHfCY3ey/hOFGCpiNQVBSlJoAsJ7Rq3Z B77OMPqSgXVNhgXQt1eZsmVw3Dud3iJD2t6ZN3QdDts8Dok98eml2qQWFuygRQFBf5aNK7mvZTP jiGpr4NvBy1Wjpusd1EyokKB/wNERWcr6OB2LhS3+eZYJPzYO0nsirrSXK0tqCDa/sLin3YOmpp rhKbPfJTmTAF1dw== X-Developer-Key: i=j-luthra@ti.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 From: Pratyush Yadav With multiple contexts, there needs to be a different DMA channel for each context. Earlier, the DMA channel name was hard coded to "rx0" for the sake of simplicity. Generate the DMA channel name based on its index and get the channel corresponding to the context. Signed-off-by: Pratyush Yadav Signed-off-by: Jai Luthra --- drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c index bffc8165fd33..361b0ea8e0d9 100644 --- a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c +++ b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c @@ -1027,6 +1027,7 @@ static int ti_csi2rx_init_dma(struct ti_csi2rx_ctx *ctx) struct dma_slave_config cfg = { .src_addr_width = DMA_SLAVE_BUSWIDTH_16_BYTES, }; + char name[32]; int ret; INIT_LIST_HEAD(&ctx->dma.queue); @@ -1035,7 +1036,8 @@ static int ti_csi2rx_init_dma(struct ti_csi2rx_ctx *ctx) ctx->dma.state = TI_CSI2RX_DMA_STOPPED; - ctx->dma.chan = dma_request_chan(ctx->csi->dev, "rx0"); + snprintf(name, sizeof(name), "rx%u", ctx->idx); + ctx->dma.chan = dma_request_chan(ctx->csi->dev, name); if (IS_ERR(ctx->dma.chan)) return PTR_ERR(ctx->dma.chan); From patchwork Thu Jun 27 13:10:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 13714391 Received: from lelv0143.ext.ti.com (lelv0143.ext.ti.com [198.47.23.248]) (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 BC6A7188CB4; Thu, 27 Jun 2024 13:10:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.23.248 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493853; cv=none; b=B4ajCnrQQtr5bOPhSA1ZWeWTZYXumtuBVmSzbfQRw06hGsW9rHDrNAeJtWXKHrYxvk7OIk+elVGh6IVwOoh2QCHC0suwmpEoPSmHvK9OYEf1CjpKtpp3nhDkotOyRhdVDeyOqBJHrDORnz6lF6wQ+r1aMStHA84yBDh+udeN9O4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493853; c=relaxed/simple; bh=yyxtthi9p6UTAr7uLnRPfVyD++ADD1tyats8zxjM5W4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=G2dQ2GMz0HLNMKSzvw2sZGZuoiTKss07O6OvMTor0tV3MPgrK4v/924aSLleT5IO2JVPWnuBYdHdLgmR+NkRXk8VzG2BYdKrLY0+bJ9CafrcTy+X3u7HDJhYxUZO/P2n1V4Y1uBxCkeN+hBqKG1TdQfyxUokuBDIWbi28UKaris= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=P3szRGYV; arc=none smtp.client-ip=198.47.23.248 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="P3szRGYV" Received: from fllv0035.itg.ti.com ([10.64.41.0]) by lelv0143.ext.ti.com (8.15.2/8.15.2) with ESMTP id 45RDAYnD110232; Thu, 27 Jun 2024 08:10:34 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1719493834; bh=PwOvTyxf/jW9XjXeX0PFsj+Ejzs5gpxyJIVQYJgwVz0=; h=From:Date:Subject:References:In-Reply-To:To:CC; b=P3szRGYVUnOYM7Zx+ndWQPIrBhSWSxM7GDwAGI4r9Z1nR+d64WtmvFpX3TeJ0qIdG owklcIPU6N3+bZS+XjayrmRApA1g3PEql9Y+iB0HxQtvsVd2kMi1OFTX9sAQSr6OfV DNCkK6RsqEEd8vx9qAQPoHl5ehuDNlrxQx1KBLFg= Received: from DFLE111.ent.ti.com (dfle111.ent.ti.com [10.64.6.32]) by fllv0035.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 45RDAYZv095663 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 27 Jun 2024 08:10:34 -0500 Received: from DFLE100.ent.ti.com (10.64.6.21) by DFLE111.ent.ti.com (10.64.6.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Thu, 27 Jun 2024 08:10:33 -0500 Received: from lelvsmtp6.itg.ti.com (10.180.75.249) by DFLE100.ent.ti.com (10.64.6.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Thu, 27 Jun 2024 08:10:33 -0500 Received: from localhost (jluthra.dhcp.ti.com [172.24.227.116]) by lelvsmtp6.itg.ti.com (8.15.2/8.15.2) with ESMTP id 45RDAXmV038593; Thu, 27 Jun 2024 08:10:33 -0500 From: Jai Luthra Date: Thu, 27 Jun 2024 18:40:01 +0530 Subject: [PATCH v2 06/13] media: ti: j721e-csi2rx: add a subdev for the core device Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <20240627-multistream-v2-6-6ae96c54c1c3@ti.com> References: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> In-Reply-To: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> To: Tomi Valkeinen , Mauro Carvalho Chehab , Sakari Ailus , Hans Verkuil , Vaishnav Achath , Maxime Ripard , Rob Herring , Krzysztof Kozlowski , Conor Dooley CC: , , Vignesh Raghavendra , Aradhya Bhatia , Devarsh Thakkar , Changhuang Liang , Jack Zhu , Julien Massot , Laurent Pinchart , Jai Luthra X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=openpgp-sha256; l=12457; i=j-luthra@ti.com; h=from:subject:message-id; bh=yyxtthi9p6UTAr7uLnRPfVyD++ADD1tyats8zxjM5W4=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBmfWS3b02P9ZA4mhKlEFNGdNQMFWHPJA8P1tRDq XF0jru5d7iJAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZn1ktwAKCRBD3pH5JJpx RT+gEACa39l4D6TDL+XbhiSvVfe2NppWwthwGpc4uAJ7aOoim5SzrsYciKgFkdk11y3EdMMZuDn D2M1A4Xz2Qms1uUNzj73y4bB8HYyZ3CSdIuWJAzQP3OXzO375qg8xiwItIff2wScRrd98SAJpQJ DMscw1hiq07UiJ0GwfnW9di8G4t5D59WK7d/IQ9dj86XoFe+a0KtbE9rlnUp7Ob1vi0ZtUeODSD VjxiiuuahAEttVKl/4D3WMKDH8VpxcAqpSMFXRO0dhn2XT+zGB9ifV0UocZmY/5rosWjY+ljZ5K F/YLxkaUXgOo+nfZuW0yw9Tg5Zg7Pwk3u3zFldpsBnesCTf/LwC7phEjiFXI7/7/fzChl58IhyC JBfe25VayrwKwit82FlcfVOcGdS+TbwDMB2TwBfc0w0nmF4LyR5vtojXk5rFMYLrDaVu8Wmw/Rv laR+3/KIPb8mqf26alhpVXvp/ouWnh/mZVA/0MSlDGtw/bRzKfacO/qoKATGV1B4bj6lxWt6IJn wZx7/zCBSFYsslX+9TWVwZVXgdBjCDJZDRWiU0ABDATHpp/HrQlACeiNbODspP+JeOnV9+3HKMO Q0wDVNwacEwN5dlBLqCtvYn7H4ps/Fb2xYXHg8ab8rM5pNooE4zAdyM+mbZ3aYkZchkJzygZTbA sMllvpLpqj717YA== X-Developer-Key: i=j-luthra@ti.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 With single stream capture, it was simpler to use the video device as the media entity representing the main TI CSI2RX device. Now with multi stream capture coming into the picture, the model has shifted to each video device having a link to the main device's subdev. The routing would then be set on this subdev. Add this subdev, link each context to this subdev's entity and link the subdev's entity to the source. Also add an array of media pads. It will have one sink pad and source pads equal to the number of contexts. Co-developed-by: Pratyush Yadav Signed-off-by: Pratyush Yadav Signed-off-by: Jai Luthra --- .../media/platform/ti/j721e-csi2rx/j721e-csi2rx.c | 237 ++++++++++++++++++--- 1 file changed, 212 insertions(+), 25 deletions(-) diff --git a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c index 361b0ea8e0d9..13d7426ab4ba 100644 --- a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c +++ b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c @@ -51,6 +51,11 @@ #define MAX_WIDTH_BYTES SZ_16K #define MAX_HEIGHT_LINES SZ_16K +#define TI_CSI2RX_PAD_SINK 0 +#define TI_CSI2RX_PAD_FIRST_SOURCE 1 +#define TI_CSI2RX_NUM_SOURCE_PADS 1 +#define TI_CSI2RX_NUM_PADS (1 + TI_CSI2RX_NUM_SOURCE_PADS) + #define DRAIN_TIMEOUT_MS 50 #define DRAIN_BUFFER_SIZE SZ_32K @@ -97,6 +102,7 @@ struct ti_csi2rx_ctx { struct mutex mutex; /* To serialize ioctls. */ struct v4l2_format v_fmt; struct ti_csi2rx_dma dma; + struct media_pad pad; u32 sequence; u32 idx; }; @@ -104,12 +110,15 @@ struct ti_csi2rx_ctx { struct ti_csi2rx_dev { struct device *dev; void __iomem *shim; + struct mutex mutex; /* To serialize ioctls. */ + unsigned int enable_count; struct v4l2_device v4l2_dev; struct media_device mdev; struct media_pipeline pipe; - struct media_pad pad; + struct media_pad pads[TI_CSI2RX_NUM_PADS]; struct v4l2_async_notifier notifier; struct v4l2_subdev *source; + struct v4l2_subdev subdev; struct ti_csi2rx_ctx ctx[TI_CSI2RX_NUM_CTX]; /* Buffer to drain stale data from PSI-L endpoint */ struct { @@ -431,6 +440,15 @@ static int csi_async_notifier_complete(struct v4l2_async_notifier *notifier) struct ti_csi2rx_dev *csi = dev_get_drvdata(notifier->v4l2_dev->dev); int ret, i; + /* Create link from source to subdev */ + ret = v4l2_create_fwnode_links_to_pad(csi->source, + &csi->pads[TI_CSI2RX_PAD_SINK], + MEDIA_LNK_FL_IMMUTABLE | + MEDIA_LNK_FL_ENABLED); + if (ret) + return ret; + + /* Create and link video nodes for all DMA contexts */ for (i = 0; i < TI_CSI2RX_NUM_CTX; i++) { struct ti_csi2rx_ctx *ctx = &csi->ctx[i]; struct video_device *vdev = &ctx->vdev; @@ -438,13 +456,17 @@ static int csi_async_notifier_complete(struct v4l2_async_notifier *notifier) ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); if (ret) goto unregister_dev; - } - ret = v4l2_create_fwnode_links_to_pad(csi->source, &csi->pad, - MEDIA_LNK_FL_IMMUTABLE | - MEDIA_LNK_FL_ENABLED); - if (ret) - goto unregister_dev; + ret = media_create_pad_link(&csi->subdev.entity, + TI_CSI2RX_PAD_FIRST_SOURCE + ctx->idx, + &vdev->entity, 0, + MEDIA_LNK_FL_IMMUTABLE | + MEDIA_LNK_FL_ENABLED); + if (ret) { + video_unregister_device(vdev); + goto unregister_dev; + } + } ret = v4l2_device_register_subdev_nodes(&csi->v4l2_dev); if (ret) @@ -859,7 +881,7 @@ static int ti_csi2rx_start_streaming(struct vb2_queue *vq, unsigned int count) dma->state = TI_CSI2RX_DMA_ACTIVE; spin_unlock_irqrestore(&dma->lock, flags); - ret = v4l2_subdev_call(csi->source, video, s_stream, 1); + ret = v4l2_subdev_call(&csi->subdev, video, s_stream, 1); if (ret) goto err_dma; @@ -887,7 +909,7 @@ static void ti_csi2rx_stop_streaming(struct vb2_queue *vq) writel(0, csi->shim + SHIM_CNTL); writel(0, csi->shim + SHIM_DMACNTX(ctx->idx)); - ret = v4l2_subdev_call(csi->source, video, s_stream, 0); + ret = v4l2_subdev_call(&csi->subdev, video, s_stream, 0); if (ret) dev_err(csi->dev, "Failed to stop subdev stream\n"); @@ -905,6 +927,119 @@ static const struct vb2_ops csi_vb2_qops = { .wait_finish = vb2_ops_wait_finish, }; +static inline struct ti_csi2rx_dev *to_csi2rx_dev(struct v4l2_subdev *sd) +{ + return container_of(sd, struct ti_csi2rx_dev, subdev); +} + +static int ti_csi2rx_sd_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_format *format) +{ + struct v4l2_mbus_framefmt *fmt; + int ret = 0; + + /* No transcoding, don't allow setting source fmt */ + if (format->pad >= TI_CSI2RX_PAD_FIRST_SOURCE) + return v4l2_subdev_get_fmt(sd, state, format); + + if (!find_format_by_code(format->format.code)) + format->format.code = ti_csi2rx_formats[0].code; + + format->format.field = V4L2_FIELD_NONE; + + fmt = v4l2_subdev_state_get_format(state, format->pad, format->stream); + if (!fmt) { + ret = -EINVAL; + goto out; + } + *fmt = format->format; + + fmt = v4l2_subdev_state_get_format(state, TI_CSI2RX_PAD_FIRST_SOURCE, + format->stream); + if (!fmt) { + ret = -EINVAL; + goto out; + } + *fmt = format->format; + +out: + return ret; +} + +static int ti_csi2rx_sd_init_state(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state) +{ + struct v4l2_subdev_format format = { + .pad = TI_CSI2RX_PAD_SINK, + .format = { + .width = 640, + .height = 480, + .code = MEDIA_BUS_FMT_UYVY8_1X16, + .field = V4L2_FIELD_NONE, + .colorspace = V4L2_COLORSPACE_SRGB, + .ycbcr_enc = V4L2_YCBCR_ENC_601, + .quantization = V4L2_QUANTIZATION_LIM_RANGE, + .xfer_func = V4L2_XFER_FUNC_SRGB, + }, + }; + + return ti_csi2rx_sd_set_fmt(sd, state, &format); +} + +static int ti_csi2rx_sd_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct ti_csi2rx_dev *csi = to_csi2rx_dev(sd); + int ret = 0; + + mutex_lock(&csi->mutex); + + if (enable) { + if (csi->enable_count > 0) { + csi->enable_count++; + goto out; + } + + ret = v4l2_subdev_call(csi->source, video, s_stream, 1); + if (ret) + goto out; + + csi->enable_count++; + } else { + if (csi->enable_count == 0) { + ret = -EINVAL; + goto out; + } + + if (--csi->enable_count > 0) + goto out; + + ret = v4l2_subdev_call(csi->source, video, s_stream, 0); + } + +out: + mutex_unlock(&csi->mutex); + return ret; +} + +static const struct v4l2_subdev_pad_ops ti_csi2rx_subdev_pad_ops = { + .get_fmt = v4l2_subdev_get_fmt, + .set_fmt = ti_csi2rx_sd_set_fmt, +}; + +static const struct v4l2_subdev_video_ops ti_csi2rx_subdev_video_ops = { + .s_stream = ti_csi2rx_sd_s_stream, +}; + +static const struct v4l2_subdev_ops ti_csi2rx_subdev_ops = { + .video = &ti_csi2rx_subdev_video_ops, + .pad = &ti_csi2rx_subdev_pad_ops, +}; + +static const struct v4l2_subdev_internal_ops ti_csi2rx_internal_ops = { + .init_state = ti_csi2rx_sd_init_state, +}; + static void ti_csi2rx_cleanup_dma(struct ti_csi2rx_ctx *ctx) { dma_release_channel(ctx->dma.chan); @@ -912,6 +1047,7 @@ static void ti_csi2rx_cleanup_dma(struct ti_csi2rx_ctx *ctx) static void ti_csi2rx_cleanup_v4l2(struct ti_csi2rx_dev *csi) { + v4l2_subdev_cleanup(&csi->subdev); media_device_unregister(&csi->mdev); v4l2_device_unregister(&csi->v4l2_dev); media_device_cleanup(&csi->mdev); @@ -973,14 +1109,22 @@ static int ti_csi2rx_link_validate(struct media_link *link) struct v4l2_subdev_format source_fmt = { .which = V4L2_SUBDEV_FORMAT_ACTIVE, .pad = link->source->index, + .stream = 0, }; + struct v4l2_subdev_state *state; const struct ti_csi2rx_fmt *ti_fmt; int ret; - ret = v4l2_subdev_call_state_active(csi->source, pad, - get_fmt, &source_fmt); - if (ret) - return ret; + state = v4l2_subdev_lock_and_get_active_state(&csi->subdev); + ret = v4l2_subdev_call(&csi->subdev, pad, get_fmt, state, &source_fmt); + v4l2_subdev_unlock_state(state); + + if (ret) { + dev_dbg(csi->dev, + "Skipping validation as no format present on \"%s\":%u:0\n", + link->source->entity->name, link->source->index); + return 0; + } if (source_fmt.format.width != csi_fmt->width) { dev_dbg(csi->dev, "Width does not match (source %u, sink %u)\n", @@ -1010,8 +1154,9 @@ static int ti_csi2rx_link_validate(struct media_link *link) if (ti_fmt->fourcc != csi_fmt->pixelformat) { dev_dbg(csi->dev, - "Cannot transform source fmt 0x%x to sink fmt 0x%x\n", - ti_fmt->fourcc, csi_fmt->pixelformat); + "Cannot transform \"%s\":%u format %p4cc to %p4cc\n", + link->source->entity->name, link->source->index, + &ti_fmt->fourcc, &csi_fmt->pixelformat); return -EPIPE; } @@ -1022,6 +1167,10 @@ static const struct media_entity_operations ti_csi2rx_video_entity_ops = { .link_validate = ti_csi2rx_link_validate, }; +static const struct media_entity_operations ti_csi2rx_subdev_entity_ops = { + .link_validate = v4l2_subdev_link_validate, +}; + static int ti_csi2rx_init_dma(struct ti_csi2rx_ctx *ctx) { struct dma_slave_config cfg = { @@ -1053,7 +1202,8 @@ static int ti_csi2rx_init_dma(struct ti_csi2rx_ctx *ctx) static int ti_csi2rx_v4l2_init(struct ti_csi2rx_dev *csi) { struct media_device *mdev = &csi->mdev; - int ret; + struct v4l2_subdev *sd = &csi->subdev; + int ret, i; mdev->dev = csi->dev; mdev->hw_revision = 1; @@ -1065,16 +1215,50 @@ static int ti_csi2rx_v4l2_init(struct ti_csi2rx_dev *csi) ret = v4l2_device_register(csi->dev, &csi->v4l2_dev); if (ret) - return ret; + goto cleanup_media; ret = media_device_register(mdev); - if (ret) { - v4l2_device_unregister(&csi->v4l2_dev); - media_device_cleanup(mdev); - return ret; - } + if (ret) + goto unregister_v4l2; + + v4l2_subdev_init(sd, &ti_csi2rx_subdev_ops); + sd->internal_ops = &ti_csi2rx_internal_ops; + sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; + sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE; + strscpy(sd->name, dev_name(csi->dev), sizeof(sd->name)); + sd->dev = csi->dev; + sd->entity.ops = &ti_csi2rx_subdev_entity_ops; + + csi->pads[TI_CSI2RX_PAD_SINK].flags = MEDIA_PAD_FL_SINK; + + for (i = TI_CSI2RX_PAD_FIRST_SOURCE; i < TI_CSI2RX_NUM_PADS; i++) + csi->pads[i].flags = MEDIA_PAD_FL_SOURCE; + + ret = media_entity_pads_init(&sd->entity, ARRAY_SIZE(csi->pads), + csi->pads); + if (ret) + goto unregister_media; + + ret = v4l2_subdev_init_finalize(sd); + if (ret) + goto unregister_media; + + ret = v4l2_device_register_subdev(&csi->v4l2_dev, sd); + if (ret) + goto cleanup_subdev; return 0; + +cleanup_subdev: + v4l2_subdev_cleanup(sd); +unregister_media: + media_device_unregister(mdev); +unregister_v4l2: + v4l2_device_unregister(&csi->v4l2_dev); +cleanup_media: + media_device_cleanup(mdev); + + return ret; } static int ti_csi2rx_init_ctx(struct ti_csi2rx_ctx *ctx) @@ -1101,9 +1285,9 @@ static int ti_csi2rx_init_ctx(struct ti_csi2rx_ctx *ctx) ti_csi2rx_fill_fmt(fmt, &ctx->v_fmt); - csi->pad.flags = MEDIA_PAD_FL_SINK; + ctx->pad.flags = MEDIA_PAD_FL_SINK; vdev->entity.ops = &ti_csi2rx_video_entity_ops; - ret = media_entity_pads_init(&ctx->vdev.entity, 1, &csi->pad); + ret = media_entity_pads_init(&ctx->vdev.entity, 1, &ctx->pad); if (ret) return ret; @@ -1159,6 +1343,8 @@ static int ti_csi2rx_probe(struct platform_device *pdev) if (!csi->drain.vaddr) return -ENOMEM; + mutex_init(&csi->mutex); + ret = ti_csi2rx_v4l2_init(csi); if (ret) goto err_v4l2; @@ -1191,6 +1377,7 @@ static int ti_csi2rx_probe(struct platform_device *pdev) ti_csi2rx_cleanup_ctx(&csi->ctx[i]); ti_csi2rx_cleanup_v4l2(csi); err_v4l2: + mutex_destroy(&csi->mutex); dma_free_coherent(csi->dev, csi->drain.len, csi->drain.vaddr, csi->drain.paddr); return ret; @@ -1213,7 +1400,7 @@ static void ti_csi2rx_remove(struct platform_device *pdev) ti_csi2rx_cleanup_notifier(csi); ti_csi2rx_cleanup_v4l2(csi); - + mutex_destroy(&csi->mutex); dma_free_coherent(csi->dev, csi->drain.len, csi->drain.vaddr, csi->drain.paddr); } From patchwork Thu Jun 27 13:10:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 13714386 Received: from lelv0142.ext.ti.com (lelv0142.ext.ti.com [198.47.23.249]) (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 3960C18A95A; Thu, 27 Jun 2024 13:10:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.23.249 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493849; cv=none; b=SW0zOLWjjDe1ZXCTOGcORjQBlqev2gb/VaNngVCror94bIRGe8lyOghlj+6bUYMnUzq6a7jqgtQsO42jgZtdyOsA12PwTh36GVzmGSxqpaGNw4OGrcGMNX4CZP9wgWTWjNJIbXXymb3vcNJH4zE6wrG8Jt5Hl4Ie/lsi1ple8tQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493849; c=relaxed/simple; bh=68LVj1oE1pTdNepeTTo1j5i/yW0M1c8ykIhjhV/j7WE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=JeeOlnFr/OiWsCf142ThwD1V3OxlTmXcrfjkVIU65MKZebl23xZxMqQvTtO8fzWsMurj5fip0wMLgtZMsyao8T0BG6rrySD/Hly958lioHBQBEFxbWyAwKgB9gE92BG6XxX1gbu9rcxVySg9oRJzJB/CF8D8vEugoJk9W8EWWrI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=rLEENLuL; arc=none smtp.client-ip=198.47.23.249 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="rLEENLuL" Received: from lelv0265.itg.ti.com ([10.180.67.224]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id 45RDAZDe024326; Thu, 27 Jun 2024 08:10:35 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1719493835; bh=FTR3j+QY166Sc0ZGtrcvupHWrRk9mFeditwaNhcbjOs=; h=From:Date:Subject:References:In-Reply-To:To:CC; b=rLEENLuLdkMOKl8OhfZ8ffH/22Lkc7VVmht1wgw5Ks7I8Z+eXVk8mTBJkKAsNcRg2 oUhLTF4ZKpOiI1lKbtpiNwOGJ/QVnHdjVCmbPURnGpC5v2LamQn8HTMv2xTVhBjADH AaIkgwxfPrZX/fmMn6A5nB173m+KrIMoce/htt4s= Received: from DFLE112.ent.ti.com (dfle112.ent.ti.com [10.64.6.33]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 45RDAZmc029344 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 27 Jun 2024 08:10:35 -0500 Received: from DFLE110.ent.ti.com (10.64.6.31) by DFLE112.ent.ti.com (10.64.6.33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Thu, 27 Jun 2024 08:10:35 -0500 Received: from lelvsmtp6.itg.ti.com (10.180.75.249) by DFLE110.ent.ti.com (10.64.6.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Thu, 27 Jun 2024 08:10:35 -0500 Received: from localhost (jluthra.dhcp.ti.com [172.24.227.116]) by lelvsmtp6.itg.ti.com (8.15.2/8.15.2) with ESMTP id 45RDAYj4038620; Thu, 27 Jun 2024 08:10:35 -0500 From: Jai Luthra Date: Thu, 27 Jun 2024 18:40:02 +0530 Subject: [PATCH v2 07/13] media: ti: j721e-csi2rx: get number of contexts from device tree Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <20240627-multistream-v2-7-6ae96c54c1c3@ti.com> References: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> In-Reply-To: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> To: Tomi Valkeinen , Mauro Carvalho Chehab , Sakari Ailus , Hans Verkuil , Vaishnav Achath , Maxime Ripard , Rob Herring , Krzysztof Kozlowski , Conor Dooley CC: , , Vignesh Raghavendra , Aradhya Bhatia , Devarsh Thakkar , Changhuang Liang , Jack Zhu , Julien Massot , Laurent Pinchart , Jai Luthra X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=openpgp-sha256; l=4925; i=j-luthra@ti.com; h=from:subject:message-id; bh=cw/2znIn7kZScgpxBbiZaWCy4kGMw3Xlo68xy9d3zwc=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBmfWS4mU/fabnNqcdXABwGDJLt8ROYBhBjUpZXw Xv9G+pNNASJAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZn1kuAAKCRBD3pH5JJpx Rfp9EACT+1bDI/BMDifmUxkESJcsHSE6jPd+pxHJTPymW75Lj1+0Pqla8KtcJ8ARhK+3/pyEKFR 9e/GUz467IzLS+F1c7fkKY2Yrt6JEcIelv4tvqBV11gck0/o+YZNaGySftSae4L0NIZmdsg9I5k 6P95gz1VhqodN8ZAzegXa4q1ImrisaYE2joQgahFR5yoULJorxCGIVOZFGU8mueW4Zr9ikRAJhH yXmr06z8QGtGkvINyXqq4kW3dn/mfixRewxnRS5DKUUtU/su5nl1sVd+ZqEURYCXF9vMcqw36lB FPE5NiBA2qh0NveB8lPUCddsKBRV+UkHMs/oM/nTmaHd6e8CXFXTgBFY6g58PpFqo1FMY4Tihtv MNN90/LmIjPeTJ0Lq2bpmI74b/o1Uex2x3wRMtzBBoWALzMooIPvVHOU7gzlirNz7LvpFvR8DK0 766Q/KSvbV6s1jTHQjQs5/38CCSgQZht37uS9Ef2ABP7p8d2QMrzoAyN6k/jbb9WkjK0QJyRP6j UlZGqA7mXTdCWVNF2CFywVHlCWEG8TajOs3p1WKNZRMs79U+I4xyR14GV1Qrpb2uGInsioClZRL mMgC/02FTHIpDK8tVVge5xbYO56xRDPyJMefAEEBHDPoQ/A0CjZ6efvlqA0S+9kr6zCq1qoOFNV kmM6qKNhXKanhOg== X-Developer-Key: i=j-luthra@ti.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 From: Pratyush Yadav Different platforms that use this driver might have different number of DMA channels allocated for CSI. So only as many DMA contexts can be used as the number of DMA channels available. Get the number of channels provided via device tree and only configure that many contexts, and hence only that many pads. Signed-off-by: Pratyush Yadav Co-developed-by: Jai Luthra Signed-off-by: Jai Luthra --- .../media/platform/ti/j721e-csi2rx/j721e-csi2rx.c | 44 ++++++++++++++++------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c index 13d7426ab4ba..b4b4bb69c88a 100644 --- a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c +++ b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c @@ -40,7 +40,7 @@ #define SHIM_PSI_CFG0_DST_TAG GENMASK(31, 16) #define PSIL_WORD_SIZE_BYTES 16 -#define TI_CSI2RX_NUM_CTX 1 +#define TI_CSI2RX_MAX_CTX 32 /* * There are no hard limits on the width or height. The DMA engine can handle @@ -53,8 +53,8 @@ #define TI_CSI2RX_PAD_SINK 0 #define TI_CSI2RX_PAD_FIRST_SOURCE 1 -#define TI_CSI2RX_NUM_SOURCE_PADS 1 -#define TI_CSI2RX_NUM_PADS (1 + TI_CSI2RX_NUM_SOURCE_PADS) +#define TI_CSI2RX_MAX_SOURCE_PADS TI_CSI2RX_MAX_CTX +#define TI_CSI2RX_MAX_PADS (1 + TI_CSI2RX_MAX_SOURCE_PADS) #define DRAIN_TIMEOUT_MS 50 #define DRAIN_BUFFER_SIZE SZ_32K @@ -112,14 +112,15 @@ struct ti_csi2rx_dev { void __iomem *shim; struct mutex mutex; /* To serialize ioctls. */ unsigned int enable_count; + unsigned int num_ctx; struct v4l2_device v4l2_dev; struct media_device mdev; struct media_pipeline pipe; - struct media_pad pads[TI_CSI2RX_NUM_PADS]; + struct media_pad pads[TI_CSI2RX_MAX_PADS]; struct v4l2_async_notifier notifier; struct v4l2_subdev *source; struct v4l2_subdev subdev; - struct ti_csi2rx_ctx ctx[TI_CSI2RX_NUM_CTX]; + struct ti_csi2rx_ctx ctx[TI_CSI2RX_MAX_CTX]; /* Buffer to drain stale data from PSI-L endpoint */ struct { void *vaddr; @@ -449,7 +450,7 @@ static int csi_async_notifier_complete(struct v4l2_async_notifier *notifier) return ret; /* Create and link video nodes for all DMA contexts */ - for (i = 0; i < TI_CSI2RX_NUM_CTX; i++) { + for (i = 0; i < csi->num_ctx; i++) { struct ti_csi2rx_ctx *ctx = &csi->ctx[i]; struct video_device *vdev = &ctx->vdev; @@ -1231,10 +1232,12 @@ static int ti_csi2rx_v4l2_init(struct ti_csi2rx_dev *csi) csi->pads[TI_CSI2RX_PAD_SINK].flags = MEDIA_PAD_FL_SINK; - for (i = TI_CSI2RX_PAD_FIRST_SOURCE; i < TI_CSI2RX_NUM_PADS; i++) + for (i = TI_CSI2RX_PAD_FIRST_SOURCE; + i < TI_CSI2RX_PAD_FIRST_SOURCE + csi->num_ctx; i++) csi->pads[i].flags = MEDIA_PAD_FL_SOURCE; - ret = media_entity_pads_init(&sd->entity, ARRAY_SIZE(csi->pads), + ret = media_entity_pads_init(&sd->entity, + TI_CSI2RX_PAD_FIRST_SOURCE + csi->num_ctx, csi->pads); if (ret) goto unregister_media; @@ -1320,8 +1323,9 @@ static int ti_csi2rx_init_ctx(struct ti_csi2rx_ctx *ctx) static int ti_csi2rx_probe(struct platform_device *pdev) { + struct device_node *np = pdev->dev.of_node; struct ti_csi2rx_dev *csi; - int ret, i; + int ret, i, count; csi = devm_kzalloc(&pdev->dev, sizeof(*csi), GFP_KERNEL); if (!csi) @@ -1343,13 +1347,29 @@ static int ti_csi2rx_probe(struct platform_device *pdev) if (!csi->drain.vaddr) return -ENOMEM; + /* Only use as many contexts as the number of DMA channels allocated. */ + count = of_property_count_strings(np, "dma-names"); + if (count < 0) { + dev_err(csi->dev, "Failed to get DMA channel count: %d\n", + count); + return count; + } + + csi->num_ctx = count; + if (csi->num_ctx > TI_CSI2RX_MAX_CTX) { + dev_warn(csi->dev, + "%u DMA channels passed. Maximum is %u. Ignoring the rest.\n", + csi->num_ctx, TI_CSI2RX_MAX_CTX); + csi->num_ctx = TI_CSI2RX_MAX_CTX; + } + mutex_init(&csi->mutex); ret = ti_csi2rx_v4l2_init(csi); if (ret) goto err_v4l2; - for (i = 0; i < TI_CSI2RX_NUM_CTX; i++) { + for (i = 0; i < csi->num_ctx; i++) { csi->ctx[i].idx = i; csi->ctx[i].csi = csi; ret = ti_csi2rx_init_ctx(&csi->ctx[i]); @@ -1388,14 +1408,14 @@ static void ti_csi2rx_remove(struct platform_device *pdev) struct ti_csi2rx_dev *csi = platform_get_drvdata(pdev); int i; - for (i = 0; i < TI_CSI2RX_NUM_CTX; i++) { + for (i = 0; i < csi->num_ctx; i++) { if (vb2_is_busy(&csi->ctx[i].vidq)) dev_err(csi->dev, "Failed to remove as queue busy for ctx %u\n", i); } - for (i = 0; i < TI_CSI2RX_NUM_CTX; i++) + for (i = 0; i < csi->num_ctx; i++) ti_csi2rx_cleanup_ctx(&csi->ctx[i]); ti_csi2rx_cleanup_notifier(csi); From patchwork Thu Jun 27 13:10:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 13714388 Received: from lelv0143.ext.ti.com (lelv0143.ext.ti.com [198.47.23.248]) (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 F2E2318C342; Thu, 27 Jun 2024 13:10:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.23.248 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493850; cv=none; b=jAu9xe5hzE5HTyzRccm2ZXm96xYe9F/g35QsUqXXsc/oX8+dQP5yyYKGVFYwrY7Qx0fRMYdgKhCLYrL3ZMrHfsoi+2IUOT+qxramjzDySZaKArdV43nJtwU9iWbEQAFLj5u/DXJK7099XkQ7Uiu7G/MTkQAU2O9LHap/gqwxq2w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493850; c=relaxed/simple; bh=2vFuVo+bGPPecHogl/3Txdtb7wk2+AmyvjLdF8g5D1c=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=ZdIb0QpE3HG+82rVg0rDwi67SqgwBe0w6QpAzw2FSdlVm9KgmETmnNsW6KZwYNMGexWrQILe98BYoRK9ae5zI1fgvI40IbxTw2Hkfet0E5Ftt0UQE5WbIBcHqR+xN4l8Jc4jvhz9JWe986dRwsDTQKC5FeQn1hTy1uaWog8NaVc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=QySt7jfI; arc=none smtp.client-ip=198.47.23.248 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="QySt7jfI" Received: from lelv0265.itg.ti.com ([10.180.67.224]) by lelv0143.ext.ti.com (8.15.2/8.15.2) with ESMTP id 45RDAb2A110243; Thu, 27 Jun 2024 08:10:37 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1719493837; bh=d1NREPANpw432CzvUECzmUTRPruFVZvBjGhgyeTjW2M=; h=From:Date:Subject:References:In-Reply-To:To:CC; b=QySt7jfIxo2KqCQDBzoEh5kkg3hZoAYQr5JNjyw3toQr1Q3E2oU+yYFVBGNoVfpe2 kDrEMsrp64as06RHMz4Qe5Zert2xxYEQ8iuCN5cWy2Ig5pRk/CedOL/1VpWt/ppuCw uZSkvzgMIgxKzQYjx/8d2x3prWidkr+/04Kerhsc= Received: from DLEE108.ent.ti.com (dlee108.ent.ti.com [157.170.170.38]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 45RDAbN4029355 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 27 Jun 2024 08:10:37 -0500 Received: from DLEE113.ent.ti.com (157.170.170.24) by DLEE108.ent.ti.com (157.170.170.38) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Thu, 27 Jun 2024 08:10:36 -0500 Received: from lelvsmtp6.itg.ti.com (10.180.75.249) by DLEE113.ent.ti.com (157.170.170.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Thu, 27 Jun 2024 08:10:36 -0500 Received: from localhost (jluthra.dhcp.ti.com [172.24.227.116]) by lelvsmtp6.itg.ti.com (8.15.2/8.15.2) with ESMTP id 45RDAaZB038665; Thu, 27 Jun 2024 08:10:36 -0500 From: Jai Luthra Date: Thu, 27 Jun 2024 18:40:03 +0530 Subject: [PATCH v2 08/13] media: cadence: csi2rx: add get_frame_desc wrapper Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <20240627-multistream-v2-8-6ae96c54c1c3@ti.com> References: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> In-Reply-To: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> To: Tomi Valkeinen , Mauro Carvalho Chehab , Sakari Ailus , Hans Verkuil , Vaishnav Achath , Maxime Ripard , Rob Herring , Krzysztof Kozlowski , Conor Dooley CC: , , Vignesh Raghavendra , Aradhya Bhatia , Devarsh Thakkar , Changhuang Liang , Jack Zhu , Julien Massot , Laurent Pinchart , Jai Luthra X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=openpgp-sha256; l=2073; i=j-luthra@ti.com; h=from:subject:message-id; bh=JtptYl9pWQyib/AWqwA187Qcdcnrfn7aG9FAK3/vGqA=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBmfWS527ImTZLiFEOQ5Xg8bvJcnev8SegdmIezz 8SgaEGPt16JAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZn1kuQAKCRBD3pH5JJpx RSigEACd6lCD+0c0Z5dyQqGiA+nfMwiSLo02Hjiw9r5Tu9glT3XdX19bkkLuTtCz4bmPzDA1TT9 7NO0JCk9N6ZIhOloJQQXadcooxoYUOMY5GPAizVWDA9kOvcgNjTuocb3Lr05SHfxqsNSocft2E0 hb2eTCeC5CcVAfC5LG8RCODjiVzYswxwvR5V4L9lkSDy24hoVPoRl01sQVle9rFSUWn9Nzt0lXi chhcR+zCDO/0im0iOnzdoV/P5ntRuPq5+q4N3l+yjUMkaj5qPXA8cAdeXzmyRPFLEPh7zKOwOfv e5WHZz9N0IlziAf6OKFx9+bsjpsVUw8qA+95m19fI85g9tlGiJOPPnP1oHGhJM1QiM+1u5Syth/ kRpr3lBaDv48ecJ6Ly/kvLIILKy7Tou9vCu+jL/u+bJ++jU42bVok/ASI5K9ZhxgHIa5FyUfNwU hEBdUvHExU31W1fGJfLLZqH85JsROIb6+KOfLAA33BzpUOjlfJSCUU+LRXsV79QaLNXRa+z6Nyb H1LbM4TjTrG/SYNfg3qt6c/T94kl2iwFbpAhk6c6DHNQnv7tuQvstLmz0g5QCtugnk1vOQAO8Bd wDQ3YVcn4GOM+RVA16BnMcX8KByUfBHdZMrnXh7L5/zrBgBBWQ4T3j0yGCEJrdANMpa0B1frigL 7YeY12kJWOnbi+g== X-Developer-Key: i=j-luthra@ti.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 From: Pratyush Yadav J721E wrapper CSI2RX driver needs to get the frame descriptor from the source to find out info about virtual channel. This driver itself does not touch the routing or virtual channels in any way. So simply pass the descriptor through from the source. Signed-off-by: Pratyush Yadav Signed-off-by: Jai Luthra --- drivers/media/platform/cadence/cdns-csi2rx.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c index 751eadbe61ef..b6054d62c799 100644 --- a/drivers/media/platform/cadence/cdns-csi2rx.c +++ b/drivers/media/platform/cadence/cdns-csi2rx.c @@ -135,6 +135,21 @@ static const struct csi2rx_fmt *csi2rx_get_fmt_by_code(u32 code) return NULL; } +static int csi2rx_get_frame_desc_from_source(struct csi2rx_priv *csi2rx, + struct v4l2_mbus_frame_desc *fd) +{ + struct media_pad *remote_pad; + + remote_pad = media_entity_remote_source_pad_unique(&csi2rx->subdev.entity); + if (!remote_pad) { + dev_err(csi2rx->dev, "No remote pad found for sink\n"); + return -ENODEV; + } + + return v4l2_subdev_call(csi2rx->source_subdev, pad, get_frame_desc, + remote_pad->index, fd); +} + static inline struct csi2rx_priv *v4l2_subdev_to_csi2rx(struct v4l2_subdev *subdev) { @@ -466,10 +481,19 @@ static int csi2rx_init_state(struct v4l2_subdev *subdev, return csi2rx_set_fmt(subdev, state, &format); } +static int csi2rx_get_frame_desc(struct v4l2_subdev *subdev, unsigned int pad, + struct v4l2_mbus_frame_desc *fd) +{ + struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev); + + return csi2rx_get_frame_desc_from_source(csi2rx, fd); +} + static const struct v4l2_subdev_pad_ops csi2rx_pad_ops = { .enum_mbus_code = csi2rx_enum_mbus_code, .get_fmt = v4l2_subdev_get_fmt, .set_fmt = csi2rx_set_fmt, + .get_frame_desc = csi2rx_get_frame_desc, }; static const struct v4l2_subdev_video_ops csi2rx_video_ops = { From patchwork Thu Jun 27 13:10:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 13714390 Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) (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 C46C818F2D4; Thu, 27 Jun 2024 13:10:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.19.141 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493853; cv=none; b=Z6dS31BvsNDbzGJrt//erCCDDff6BYWYdPPZMacYuR6lsONBIviX1Zkw6qWtHoJgeg1iRGfaz7ZSvR4WDPIdHgxzTn6FDs7caGLtBD3OfJLKDzEiO2hK1mnsmhyHFNfH4LjQUlko64s8qGYxhUzxZdE4DvbLpyZ4zG03fvAL7xg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493853; c=relaxed/simple; bh=5yUEdo0G8hpZub9m+y1PoqKCC1LAzx0pO2pfWf4gvxA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=fMl/iEPUD/IbgKaEeuw/TJ6wPwNCqvArT3T6vHly14xaqR1Bfp/c8I5K2uUdIkZG9L/LC5RNCxu3Um0dsUcA04tbdP5rlJV7LG6bvffCLAQzb+fekTZrNGT6YKoE5jopwklRdyvNNPwuBpmoMjAmfgMBSFDLcijWgYW4BXCq9+M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=mcWVv1gv; arc=none smtp.client-ip=198.47.19.141 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="mcWVv1gv" Received: from fllv0035.itg.ti.com ([10.64.41.0]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 45RDAccZ117639; Thu, 27 Jun 2024 08:10:38 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1719493838; bh=kLUfBBB3ygNK3Vcq73Ko/V1h89L0/lK2Pi+iSHcgALs=; h=From:Date:Subject:References:In-Reply-To:To:CC; b=mcWVv1gvkT4y10qvR1HX8nZ9egjSrN4ZM3CFVe2k121kkG2DnWKF/oCqwayoYovs6 rMohF96bN3R3lUaL/3lMPAAPPBnyq2LVyjij6zGdvInAH6O4/fNhKKUcPOLM4ERkkX 3SZ+I0khlUeRWUZkgj/hadt/YV5QxIqqDwDXoOh8= Received: from DLEE108.ent.ti.com (dlee108.ent.ti.com [157.170.170.38]) by fllv0035.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 45RDAc8m095764 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 27 Jun 2024 08:10:38 -0500 Received: from DLEE100.ent.ti.com (157.170.170.30) by DLEE108.ent.ti.com (157.170.170.38) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Thu, 27 Jun 2024 08:10:38 -0500 Received: from lelvsmtp5.itg.ti.com (10.180.75.250) by DLEE100.ent.ti.com (157.170.170.30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Thu, 27 Jun 2024 08:10:38 -0500 Received: from localhost (jluthra.dhcp.ti.com [172.24.227.116]) by lelvsmtp5.itg.ti.com (8.15.2/8.15.2) with ESMTP id 45RDAbQS072373; Thu, 27 Jun 2024 08:10:38 -0500 From: Jai Luthra Date: Thu, 27 Jun 2024 18:40:04 +0530 Subject: [PATCH v2 09/13] media: ti: j721e-csi2rx: add support for processing virtual channels Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <20240627-multistream-v2-9-6ae96c54c1c3@ti.com> References: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> In-Reply-To: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> To: Tomi Valkeinen , Mauro Carvalho Chehab , Sakari Ailus , Hans Verkuil , Vaishnav Achath , Maxime Ripard , Rob Herring , Krzysztof Kozlowski , Conor Dooley CC: , , Vignesh Raghavendra , Aradhya Bhatia , Devarsh Thakkar , Changhuang Liang , Jack Zhu , Julien Massot , Laurent Pinchart , Jai Luthra X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=openpgp-sha256; l=2874; i=j-luthra@ti.com; h=from:subject:message-id; bh=5yUEdo0G8hpZub9m+y1PoqKCC1LAzx0pO2pfWf4gvxA=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBmfWS64FV3r2sgKcInLAAU3yEoopI2g8C5+URLz 05Ik4+pyJWJAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZn1kugAKCRBD3pH5JJpx RVBvEACNCKEYzC9bkE9HfEXc4RlY9S7JLwFAShNyoV8BEwWAQWqjCKrqgmD8sxWBi8ySrkAy9N8 N0sen8FPJQdhCIpCexLzsMClvmPX8rIWLUOnnhHSZIhFbc1PXgmoNckN/eQYtQFgnzk9FbWAhCV oj3pom2vB+N3ecq35r7mFLdqHqMhACh2bcsTkjJnmGyVxrZm9kmhIMYIQAyanR2cKJFG+bGT/NZ 1xXzWqiX/mLMC860FBY/YdNMvUpLP/Vse2hgJf/o5916RyAqhfHuI7voRY9pAsxTlhA/c1legTH s7Y0XrRO/maCfWtVNeHX0SRl3kYpBh0z+vQwMyt5XVNG8tjLyQHNYG/uMy/Q+s1PLWEoMAMfLug iyZ95du3b68udRCJl/BQcmC0vK2wmSBmlOY504TC5aDhP3MXpXRliPZ+o0zmHsILmNWa0kUwsKB m/+IqMvSWdX6GbRR0oBo9lIhTTNpZArWUhJs5HlWr2BK4VRNqX0gTxBEphjhTWxdhbjWu9vluke pjqFg85EekBAeFqni1zfQH0FIdLKS7Ff4aggLqS32DzLOliNCWN2KQIDcvaBvaYpZFxDTbMJdV+ wB3PTZK7NPS/Gpbe7vIqbAtRQV+prUGJHBGMHygs7axHcJaIweqnq8W9xLW/7mWrJN9t0lslga2 5uN9+czawhQ2x3g== X-Developer-Key: i=j-luthra@ti.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Use get_frame_desc() to get the frame desc from the connected source, and use the provided virtual channel instead of hardcoded one. get_frame_desc() works per stream, but as we don't support multiple streams yet, we will just always use stream 0. If the source doesn't support get_frame_desc(), fall back to the previous method of always capturing virtual channel 0. Co-developed-by: Pratyush Yadav Signed-off-by: Pratyush Yadav Signed-off-by: Jai Luthra --- .../media/platform/ti/j721e-csi2rx/j721e-csi2rx.c | 39 ++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c index b4b4bb69c88a..c0916ca1a6f8 100644 --- a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c +++ b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c @@ -29,6 +29,7 @@ #define SHIM_DMACNTX_EN BIT(31) #define SHIM_DMACNTX_YUV422 GENMASK(27, 26) #define SHIM_DMACNTX_SIZE GENMASK(21, 20) +#define SHIM_DMACNTX_VC GENMASK(9, 6) #define SHIM_DMACNTX_FMT GENMASK(5, 0) #define SHIM_DMACNTX_YUV422_MODE_11 3 #define SHIM_DMACNTX_SIZE_8 0 @@ -105,6 +106,8 @@ struct ti_csi2rx_ctx { struct media_pad pad; u32 sequence; u32 idx; + u32 vc; + u32 stream; }; struct ti_csi2rx_dev { @@ -571,6 +574,7 @@ static void ti_csi2rx_setup_shim(struct ti_csi2rx_ctx *ctx) } reg |= FIELD_PREP(SHIM_DMACNTX_SIZE, fmt->size); + reg |= FIELD_PREP(SHIM_DMACNTX_VC, ctx->vc); writel(reg, csi->shim + SHIM_DMACNTX(ctx->idx)); @@ -844,6 +848,33 @@ static void ti_csi2rx_buffer_queue(struct vb2_buffer *vb) } } +static int ti_csi2rx_get_vc(struct ti_csi2rx_ctx *ctx) +{ + struct ti_csi2rx_dev *csi = ctx->csi; + struct v4l2_mbus_frame_desc fd; + struct media_pad *pad; + int ret, i; + + pad = media_entity_remote_pad_unique(&csi->subdev.entity, MEDIA_PAD_FL_SOURCE); + if (!pad) + return -ENODEV; + + ret = v4l2_subdev_call(csi->source, pad, get_frame_desc, pad->index, + &fd); + if (ret) + return ret; + + if (fd.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) + return -EINVAL; + + for (i = 0; i < fd.num_entries; i++) { + if (ctx->stream == fd.entry[i].stream) + return fd.entry[i].bus.csi2.vc; + } + + return -ENODEV; +} + static int ti_csi2rx_start_streaming(struct vb2_queue *vq, unsigned int count) { struct ti_csi2rx_ctx *ctx = vb2_get_drv_priv(vq); @@ -864,6 +895,14 @@ static int ti_csi2rx_start_streaming(struct vb2_queue *vq, unsigned int count) if (ret) goto err; + ret = ti_csi2rx_get_vc(ctx); + if (ret == -ENOIOCTLCMD) + ctx->vc = 0; + else if (ret < 0) + goto err; + else + ctx->vc = ret; + ti_csi2rx_setup_shim(ctx); ctx->sequence = 0; From patchwork Thu Jun 27 13:10:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 13714389 Received: from lelv0142.ext.ti.com (lelv0142.ext.ti.com [198.47.23.249]) (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 C692318EFD3; Thu, 27 Jun 2024 13:10:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.23.249 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493852; cv=none; b=B1KBTg+WgvPSinmcFoUcTVxVggKugS6cTozziPE4MZ1LL3tb9tmnUySUMYDZxKpIe97z/VZJISVIl+sLeBYBTU76DuIlrzXkPVNQ9h5QS+BV5zeyyd1AAio+oeWzIsuK4l7Gt/O5brbdMqPvZ5UFZWt0JuiyDoGaIJ4xCuhms5w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493852; c=relaxed/simple; bh=+/EnvUrM4ZPWCtrpdzk+4GojwCIuX8pMK1WphzTTUK0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=T2CNEc5uiTfcn9xD0AJE4D+30iqkbAuK6QBWKx9wopdRe3MMmCfaAVGyCamR2PFX5nG/ShDp51OjF6uxkcWKoXuzFfBVQkbXm2J8sawhUmS7STDszyOC9PDfaBB6awR7IoKb3EpSj2dPcB7UFOlkPMMDAPELHNPwoPOXq0jn8rY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=AK6P6MZ5; arc=none smtp.client-ip=198.47.23.249 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="AK6P6MZ5" Received: from fllv0034.itg.ti.com ([10.64.40.246]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id 45RDAe84024343; Thu, 27 Jun 2024 08:10:40 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1719493840; bh=8pnwDRf5zvvCFyhKGj1stRmE7TXO+7c8UQvSNtofPhk=; h=From:Date:Subject:References:In-Reply-To:To:CC; b=AK6P6MZ5/S9muQETiJGVJMfBtz23yMC3UT7CJv3WFoYWviekUUCjiUMXdYDOmzXcw wjo8151R7qvjkhXUGuaVJo0+CMbZv67MxXQAsBO7vbqVjA6LmJcrjQE/SKSaqpMrjH 2OgzFUR8jqfHUw6pFEpugSdKVtBaErk5GuGjrI7s= Received: from DFLE105.ent.ti.com (dfle105.ent.ti.com [10.64.6.26]) by fllv0034.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 45RDAeNu117673 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 27 Jun 2024 08:10:40 -0500 Received: from DFLE115.ent.ti.com (10.64.6.36) by DFLE105.ent.ti.com (10.64.6.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Thu, 27 Jun 2024 08:10:39 -0500 Received: from lelvsmtp6.itg.ti.com (10.180.75.249) by DFLE115.ent.ti.com (10.64.6.36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Thu, 27 Jun 2024 08:10:39 -0500 Received: from localhost (jluthra.dhcp.ti.com [172.24.227.116]) by lelvsmtp6.itg.ti.com (8.15.2/8.15.2) with ESMTP id 45RDAdNC038728; Thu, 27 Jun 2024 08:10:39 -0500 From: Jai Luthra Date: Thu, 27 Jun 2024 18:40:05 +0530 Subject: [PATCH v2 10/13] media: cadence: csi2rx: Use new enable stream APIs Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <20240627-multistream-v2-10-6ae96c54c1c3@ti.com> References: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> In-Reply-To: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> To: Tomi Valkeinen , Mauro Carvalho Chehab , Sakari Ailus , Hans Verkuil , Vaishnav Achath , Maxime Ripard , Rob Herring , Krzysztof Kozlowski , Conor Dooley CC: , , Vignesh Raghavendra , Aradhya Bhatia , Devarsh Thakkar , Changhuang Liang , Jack Zhu , Julien Massot , Laurent Pinchart , Jai Luthra X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=openpgp-sha256; l=2442; i=j-luthra@ti.com; h=from:subject:message-id; bh=+/EnvUrM4ZPWCtrpdzk+4GojwCIuX8pMK1WphzTTUK0=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBmfWS7OfDqioXJZI8fnZEa4wpgqbGgmassDG72w BkOFF9PVH+JAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZn1kuwAKCRBD3pH5JJpx ReDmD/9/dyPzxoCU46hjGnzhJDbl7cAwBkarMeyvjGS7RDbRZ2rETX2ad7BbzyjlZ90YAAHq0Pt bFGFI7TCyZ+QSwjSW7e/sLCyvQNBji5kMya00DHU+mjIDCJOKYame5x//s3pVQWu6lob3vU7QPG e/6+GilGLbiWo7yavhg5r05LPpGIxSXJXcmjVVyJtbse/LdTmRU+5oy5eEa8Varlvs/QLSialJe zzGbloHrktXNfg8lNyRbRMn1LQU+jmmF1/vZectyVO0gxbUGliINOAQizZgViI77C4o6TI0cXyc 5Fo1huXY/Bn4QEp1h7TrKHmBRaR43k0bPC8tdW5C9nhrpxaYpzoKX1rVTW0RedZ6LYSyalfGbXj FyXZm3sFyioCLpv5pqoEXHd/Geqmb0NPixVlTNLKdrLQ2D3FVypptuw5z0KkcrjyXHId4fjLNdi /Xe4Yp1iTru9VZXsqXetHrp+la1oSJSCmVxT2A7VcynPsIJzd7B6cxdTzJSZOjeXq5+AaMDfpDX Tyi8A85NLCJYMPk5ay/ufm1LfCJBALDJop8P5Tv3HbfWv+I2ZisgF4qftrcMagAUGVlrULUb9TL WECbgkUUZAwU5i5rKC3mHfmWqmQiRK+X38dvpN1rUBB8cwfntHfoyG6an6ZiCFVEDLebaiYYU2q EMAFjJaoJXoTkhw== X-Developer-Key: i=j-luthra@ti.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 The enable_streams() API in v4l2 supports passing a bitmask to enable each pad/stream combination individually on any media subdev instead of doing s_stream(1) to start all streams on the subdev at once. This API is implemented by ds90ub960 driver (FPDLink deser) and thus the caller (cdns-csi2x) is required to use it. For now we only enable stream0. Signed-off-by: Jai Luthra --- drivers/media/platform/cadence/cdns-csi2rx.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c index b6054d62c799..2ec34fc9c524 100644 --- a/drivers/media/platform/cadence/cdns-csi2rx.c +++ b/drivers/media/platform/cadence/cdns-csi2rx.c @@ -222,10 +222,18 @@ static int csi2rx_configure_ext_dphy(struct csi2rx_priv *csi2rx) static int csi2rx_start(struct csi2rx_priv *csi2rx) { unsigned int i; + struct media_pad *remote_pad; unsigned long lanes_used = 0; u32 reg; int ret; + remote_pad = media_pad_remote_pad_first(&csi2rx->pads[CSI2RX_PAD_SINK]); + if (!remote_pad) { + dev_err(csi2rx->dev, + "Failed to find connected source\n"); + return -ENODEV; + } + ret = clk_prepare_enable(csi2rx->p_clk); if (ret) return ret; @@ -309,7 +317,8 @@ static int csi2rx_start(struct csi2rx_priv *csi2rx) reset_control_deassert(csi2rx->sys_rst); - ret = v4l2_subdev_call(csi2rx->source_subdev, video, s_stream, true); + ret = v4l2_subdev_enable_streams(csi2rx->source_subdev, + remote_pad->index, BIT(0)); if (ret) goto err_disable_sysclk; @@ -337,6 +346,7 @@ static int csi2rx_start(struct csi2rx_priv *csi2rx) static void csi2rx_stop(struct csi2rx_priv *csi2rx) { + struct media_pad *remote_pad; unsigned int i; u32 val; int ret; @@ -365,8 +375,12 @@ static void csi2rx_stop(struct csi2rx_priv *csi2rx) reset_control_assert(csi2rx->p_rst); clk_disable_unprepare(csi2rx->p_clk); - if (v4l2_subdev_call(csi2rx->source_subdev, video, s_stream, false)) + remote_pad = media_pad_remote_pad_first(&csi2rx->pads[CSI2RX_PAD_SINK]); + if (!remote_pad || + v4l2_subdev_disable_streams(csi2rx->source_subdev, + remote_pad->index, BIT(0))) { dev_warn(csi2rx->dev, "Couldn't disable our subdev\n"); + } if (csi2rx->dphy) { writel(0, csi2rx->base + CSI2RX_DPHY_LANE_CTRL_REG); From patchwork Thu Jun 27 13:10:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 13714394 Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (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 4E02619148F; Thu, 27 Jun 2024 13:10:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.19.142 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493859; cv=none; b=UAiWIFTujIoMRFJi7bvgyVQ1wkQF8Uc0BS/0GFQVAASKJNAzwgaur8Mw0P0oStaGocRdDjoO4pPL6JiDmOH4GsuzKgO65JxpqkVINhsUpRe0zMCojCoWgd4dEEzjQLL70LWwPU2uaNRqGNMRpK5H+B3cLCAKML0wx3pp5x62wpc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493859; c=relaxed/simple; bh=WZ2gAxTS7fZA7Ln7bwpB4aZ+mMTaAMP5yoJH7VSPXII=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=ow9UF8Cq6XUjgfa8shb8A5ONeHgN31sl+me+Qkyie4iRw6LbCSgnWNqVswMuRatTtpDtWpdiPKoU4GfJRUPCWAuujgPmWBak13+707C/rDiNwzoM/RlTg+SDViTEysYCqv5Yz7O4UIQSIZOHzM5Xnuk2dHJUuxmqQKS8va6UUCs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=HN4Oyu8J; arc=none smtp.client-ip=198.47.19.142 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="HN4Oyu8J" Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 45RDAfoN118794; Thu, 27 Jun 2024 08:10:41 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1719493841; bh=TuGcjpY/SSWwMollyfrfG2FCoWRm4VbYrHc8nyRtYiM=; h=From:Date:Subject:References:In-Reply-To:To:CC; b=HN4Oyu8Jm5AOD6w28sbaTCoDWKijMldXVZy1bjg0ZhMlv4SXGghJ1doBHux/7HxOq TXJbc9d1d8cJZMSOO3mejCWHPVOba1HEyH2tXI2vz7yyOJ2SbZDKQbwTyiCVl2I/ME SqwhXrlXd7d4UQsvD6ysIOdvGcDGcXMPlmewn0IY= Received: from DLEE109.ent.ti.com (dlee109.ent.ti.com [157.170.170.41]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 45RDAfUJ029383 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 27 Jun 2024 08:10:41 -0500 Received: from DLEE113.ent.ti.com (157.170.170.24) by DLEE109.ent.ti.com (157.170.170.41) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Thu, 27 Jun 2024 08:10:41 -0500 Received: from lelvsmtp6.itg.ti.com (10.180.75.249) by DLEE113.ent.ti.com (157.170.170.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Thu, 27 Jun 2024 08:10:41 -0500 Received: from localhost (jluthra.dhcp.ti.com [172.24.227.116]) by lelvsmtp6.itg.ti.com (8.15.2/8.15.2) with ESMTP id 45RDAeEW038757; Thu, 27 Jun 2024 08:10:41 -0500 From: Jai Luthra Date: Thu, 27 Jun 2024 18:40:06 +0530 Subject: [PATCH v2 11/13] media: cadence: csi2rx: Enable multi-stream support Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <20240627-multistream-v2-11-6ae96c54c1c3@ti.com> References: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> In-Reply-To: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> To: Tomi Valkeinen , Mauro Carvalho Chehab , Sakari Ailus , Hans Verkuil , Vaishnav Achath , Maxime Ripard , Rob Herring , Krzysztof Kozlowski , Conor Dooley CC: , , Vignesh Raghavendra , Aradhya Bhatia , Devarsh Thakkar , Changhuang Liang , Jack Zhu , Julien Massot , Laurent Pinchart , Jai Luthra X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=openpgp-sha256; l=17618; i=j-luthra@ti.com; h=from:subject:message-id; bh=WZ2gAxTS7fZA7Ln7bwpB4aZ+mMTaAMP5yoJH7VSPXII=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBmfWS8kXWgUxWEmhheeqfIJ3N/gJAQoee87ZgJj BqsAwEXNteJAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZn1kvAAKCRBD3pH5JJpx RY7nD/43z7oRdY/2s4jXmQYZl/vxw7EmMt1wCYeai0UjJ4BLxkE4eEALCtB4LSPulKO/ClQ5LoS tFaS9dWOx8JiKXmcUhGs8pa0Q6+AthBms6zJL1eXptJMexQN+pdUiySXnz+eMJzd2Ac+DGiMyaZ L4xmegJZ/oRy4/TXtWuoqbDReqnUHylDNgCknhKq07Borte8LuL83fcbR9hWNus2MFZasHz39Gh 1auogaceZBUqjKUMYCszGzvDmSrofi2TTb1fgw+V5p1jDEUZ4hSPiDpcFkC/CdZWm33Fnis6Ymc oiKnUbK5Uuxb6Gh8u8PC3YRgDgs2bMLVIGzSIWmm8AP4WrwKswXjUi02vyCrvJ+NhCFNhiCcfsJ k/mW8r4SSXoT2PSxp9JapXTcr0hT1dHOSCptXv5GCLN2uRUtdR7VPjeSAhBaADsIxMoC1ZwFs8M J3Ijh2FdShAU9/nCzujxiCzphk50KmMIN7R1QqW20TBeACVLJbQvRAOZsAKkqjLv70/2gi5Y27E Iqu6IoWSRRON3Q3JxNp7AOxDUSqGH8iGmN6WKvDBhb4n6UU/Kd8JR7b4/1nBM4s1JO8h3rnaS0b riLWDSmlELrAcBK2q+LLbnOSYuu1Ald6CHQd9AWdNHhnF7ZC9mLiTVl7OjMsZa/hyLLtGu6z/zQ mwVDONTECvt8SYw== X-Developer-Key: i=j-luthra@ti.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cadence CSI-2 bridge IP supports capturing multiple virtual "streams" of data over the same physical interface using MIPI Virtual Channels. The V4L2 subdev APIs should reflect this capability and allow per-stream routing and controls. While the hardware IP supports usecases where streams coming in the sink pad can be broadcasted to multiple source pads, the driver will need significant re-architecture to make that possible. The two users of this IP in mainline linux are TI Shim and StarFive JH7110 CAMSS, and both have only integrated the first source pad i.e stream0 of this IP. So for now keep it simple and only allow 1-to-1 mapping of streams from sink to source, without any broadcasting. With stream routing now supported in the driver, implement the enable_stream and disable_stream hooks in place of the stream-unaware s_stream hook. This allows consumer devices like a DMA bridge or ISP, to enable particular streams on a source pad, which in turn can be used to enable only particular streams on the CSI-TX device connected on the sink pad. Implement a fallback s_stream hook that internally calls enable_stream on each source pad, for consumer drivers that don't use multi-stream APIs to still work. Signed-off-by: Jai Luthra --- drivers/media/platform/cadence/cdns-csi2rx.c | 407 ++++++++++++++++++++------- 1 file changed, 313 insertions(+), 94 deletions(-) diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c index 2ec34fc9c524..b0c91a9c65e8 100644 --- a/drivers/media/platform/cadence/cdns-csi2rx.c +++ b/drivers/media/platform/cadence/cdns-csi2rx.c @@ -90,6 +90,7 @@ struct csi2rx_priv { struct reset_control *pixel_rst[CSI2RX_STREAMS_MAX]; struct phy *dphy; + u32 vc_select[CSI2RX_STREAMS_MAX]; u8 lanes[CSI2RX_LANES_MAX]; u8 num_lanes; u8 max_lanes; @@ -179,27 +180,43 @@ static void csi2rx_reset(struct csi2rx_priv *csi2rx) static int csi2rx_configure_ext_dphy(struct csi2rx_priv *csi2rx) { + struct v4l2_ctrl_handler *handler = csi2rx->source_subdev->ctrl_handler; union phy_configure_opts opts = { }; struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy; - struct v4l2_subdev_format sd_fmt = { - .which = V4L2_SUBDEV_FORMAT_ACTIVE, - .pad = CSI2RX_PAD_SINK, - }; + struct v4l2_mbus_framefmt *framefmt; + struct v4l2_subdev_state *state; const struct csi2rx_fmt *fmt; s64 link_freq; int ret; - ret = v4l2_subdev_call_state_active(&csi2rx->subdev, pad, get_fmt, - &sd_fmt); - if (ret < 0) - return ret; + if (v4l2_ctrl_find(handler, V4L2_CID_LINK_FREQ)) { + link_freq = v4l2_get_link_freq(handler, 0, 0); + } else { + state = v4l2_subdev_get_locked_active_state(&csi2rx->subdev); + framefmt = v4l2_subdev_state_get_format(state, CSI2RX_PAD_SINK, + 0); + + if (framefmt) { + fmt = csi2rx_get_fmt_by_code(framefmt->code); + } else { + dev_err(csi2rx->dev, + "Did not find active sink format\n"); + return -EINVAL; + } - fmt = csi2rx_get_fmt_by_code(sd_fmt.format.code); + link_freq = v4l2_get_link_freq(handler, fmt->bpp, + 2 * csi2rx->num_lanes); - link_freq = v4l2_get_link_freq(csi2rx->source_subdev->ctrl_handler, - fmt->bpp, 2 * csi2rx->num_lanes); - if (link_freq < 0) + dev_warn(csi2rx->dev, + "Guessing link frequency using bitdepth of stream 0.\n"); + dev_warn(csi2rx->dev, + "V4L2_CID_LINK_FREQ control is required for multi format sources.\n"); + } + + if (link_freq < 0) { + dev_err(csi2rx->dev, "Unable to calculate link frequency\n"); return link_freq; + } ret = phy_mipi_dphy_get_default_config_for_hsclk(link_freq, csi2rx->num_lanes, cfg); @@ -222,18 +239,10 @@ static int csi2rx_configure_ext_dphy(struct csi2rx_priv *csi2rx) static int csi2rx_start(struct csi2rx_priv *csi2rx) { unsigned int i; - struct media_pad *remote_pad; unsigned long lanes_used = 0; u32 reg; int ret; - remote_pad = media_pad_remote_pad_first(&csi2rx->pads[CSI2RX_PAD_SINK]); - if (!remote_pad) { - dev_err(csi2rx->dev, - "Failed to find connected source\n"); - return -ENODEV; - } - ret = clk_prepare_enable(csi2rx->p_clk); if (ret) return ret; @@ -300,11 +309,7 @@ static int csi2rx_start(struct csi2rx_priv *csi2rx) writel(CSI2RX_STREAM_CFG_FIFO_MODE_LARGE_BUF, csi2rx->base + CSI2RX_STREAM_CFG_REG(i)); - /* - * Enable one virtual channel. When multiple virtual channels - * are supported this will have to be changed. - */ - writel(CSI2RX_STREAM_DATA_CFG_VC_SELECT(0), + writel(csi2rx->vc_select[i], csi2rx->base + CSI2RX_STREAM_DATA_CFG_REG(i)); writel(CSI2RX_STREAM_CTRL_START, @@ -317,17 +322,10 @@ static int csi2rx_start(struct csi2rx_priv *csi2rx) reset_control_deassert(csi2rx->sys_rst); - ret = v4l2_subdev_enable_streams(csi2rx->source_subdev, - remote_pad->index, BIT(0)); - if (ret) - goto err_disable_sysclk; - clk_disable_unprepare(csi2rx->p_clk); return 0; -err_disable_sysclk: - clk_disable_unprepare(csi2rx->sys_clk); err_disable_pixclk: for (; i > 0; i--) { reset_control_assert(csi2rx->pixel_rst[i - 1]); @@ -346,7 +344,6 @@ static int csi2rx_start(struct csi2rx_priv *csi2rx) static void csi2rx_stop(struct csi2rx_priv *csi2rx) { - struct media_pad *remote_pad; unsigned int i; u32 val; int ret; @@ -375,13 +372,6 @@ static void csi2rx_stop(struct csi2rx_priv *csi2rx) reset_control_assert(csi2rx->p_rst); clk_disable_unprepare(csi2rx->p_clk); - remote_pad = media_pad_remote_pad_first(&csi2rx->pads[CSI2RX_PAD_SINK]); - if (!remote_pad || - v4l2_subdev_disable_streams(csi2rx->source_subdev, - remote_pad->index, BIT(0))) { - dev_warn(csi2rx->dev, "Couldn't disable our subdev\n"); - } - if (csi2rx->dphy) { writel(0, csi2rx->base + CSI2RX_DPHY_LANE_CTRL_REG); @@ -390,47 +380,167 @@ static void csi2rx_stop(struct csi2rx_priv *csi2rx) } } -static int csi2rx_s_stream(struct v4l2_subdev *subdev, int enable) +static void csi2rx_update_vc_select(struct csi2rx_priv *csi2rx, + struct v4l2_subdev_state *state) { - struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev); - int ret = 0; + struct v4l2_mbus_frame_desc fd = {0}; + struct v4l2_subdev_route *route; + unsigned int i; + int ret; - if (enable) { - ret = pm_runtime_resume_and_get(csi2rx->dev); - if (ret < 0) - return ret; + for (i = 0; i < CSI2RX_STREAMS_MAX; i++) + csi2rx->vc_select[i] = 0; + + ret = csi2rx_get_frame_desc_from_source(csi2rx, &fd); + if (ret || fd.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) { + dev_dbg(csi2rx->dev, + "Failed to get source frame desc, allowing only VC=0\n"); + goto err_no_fd; } - mutex_lock(&csi2rx->lock); + /* If source provides per-stream VC info, use it to filter by VC */ + for_each_active_route(&state->routing, route) { + int cdns_stream = route->source_pad - CSI2RX_PAD_SOURCE_STREAM0; + u8 used_vc = 0; - if (enable) { - /* - * If we're not the first users, there's no need to - * enable the whole controller. - */ - if (!csi2rx->count) { - ret = csi2rx_start(csi2rx); - if (ret) { - pm_runtime_put(csi2rx->dev); - goto out; + for (i = 0; i < fd.num_entries; i++) { + if (fd.entry[i].stream == route->sink_stream) { + used_vc = fd.entry[i].bus.csi2.vc; + break; } } + csi2rx->vc_select[cdns_stream] |= + CSI2RX_STREAM_DATA_CFG_VC_SELECT(used_vc); + } - csi2rx->count++; - } else { - csi2rx->count--; +err_no_fd: + for (i = 0; i < CSI2RX_STREAMS_MAX; i++) { + if (!csi2rx->vc_select[i]) { + csi2rx->vc_select[i] = + CSI2RX_STREAM_DATA_CFG_VC_SELECT(0); + } + } +} - /* - * Let the last user turn off the lights. - */ - if (!csi2rx->count) - csi2rx_stop(csi2rx); +static int csi2rx_enable_streams(struct v4l2_subdev *subdev, + struct v4l2_subdev_state *state, u32 pad, + u64 streams_mask) +{ + struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev); + struct media_pad *remote_pad; + u64 sink_streams; + int ret; + + remote_pad = media_pad_remote_pad_first(&csi2rx->pads[CSI2RX_PAD_SINK]); + if (!remote_pad) { + dev_err(csi2rx->dev, + "Failed to find connected source\n"); + return -ENODEV; + } + + ret = pm_runtime_resume_and_get(csi2rx->dev); + if (ret < 0) + return ret; + + sink_streams = v4l2_subdev_state_xlate_streams(state, pad, + CSI2RX_PAD_SINK, + &streams_mask); - pm_runtime_put(csi2rx->dev); + mutex_lock(&csi2rx->lock); + /* + * If we're not the first users, there's no need to + * enable the whole controller. + */ + if (!csi2rx->count) { + ret = csi2rx_start(csi2rx); + if (ret) + goto err_stream_start; } -out: + /* Start streaming on the source */ + ret = v4l2_subdev_enable_streams(csi2rx->source_subdev, remote_pad->index, + sink_streams); + if (ret) { + dev_err(csi2rx->dev, + "Failed to start streams %#llx on subdev\n", + sink_streams); + goto err_subdev_enable; + } + + csi2rx->count++; + mutex_unlock(&csi2rx->lock); + + return 0; + +err_subdev_enable: + if (!csi2rx->count) + csi2rx_stop(csi2rx); +err_stream_start: mutex_unlock(&csi2rx->lock); + pm_runtime_put(csi2rx->dev); + return ret; +} + +static int csi2rx_disable_streams(struct v4l2_subdev *subdev, + struct v4l2_subdev_state *state, u32 pad, + u64 streams_mask) +{ + struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev); + struct media_pad *remote_pad; + u64 sink_streams; + + sink_streams = v4l2_subdev_state_xlate_streams(state, pad, + CSI2RX_PAD_SINK, + &streams_mask); + + remote_pad = media_pad_remote_pad_first(&csi2rx->pads[CSI2RX_PAD_SINK]); + if (!remote_pad || + v4l2_subdev_disable_streams(csi2rx->source_subdev, + remote_pad->index, sink_streams)) { + dev_err(csi2rx->dev, "Couldn't disable our subdev\n"); + } + + mutex_lock(&csi2rx->lock); + csi2rx->count--; + /* + * Let the last user turn off the lights. + */ + if (!csi2rx->count) + csi2rx_stop(csi2rx); + mutex_unlock(&csi2rx->lock); + + pm_runtime_put(csi2rx->dev); + + return 0; +} + +static int csi2rx_s_stream_fallback(struct v4l2_subdev *sd, int enable) +{ + struct v4l2_subdev_state *state; + struct v4l2_subdev_route *route; + u64 mask[CSI2RX_PAD_MAX] = {0}; + int i, ret; + + /* Find the stream mask on all source pads */ + state = v4l2_subdev_lock_and_get_active_state(sd); + for (i = CSI2RX_PAD_SOURCE_STREAM0; i < CSI2RX_PAD_MAX; i++) { + for_each_active_route(&state->routing, route) { + if (route->source_pad == i) + mask[i] |= BIT_ULL(route->source_stream); + } + } + v4l2_subdev_unlock_state(state); + + /* Start streaming on each pad */ + for (i = CSI2RX_PAD_SOURCE_STREAM0; i < CSI2RX_PAD_MAX; i++) { + if (enable) + ret = v4l2_subdev_enable_streams(sd, i, mask[i]); + else + ret = v4l2_subdev_disable_streams(sd, i, mask[i]); + if (ret) + return ret; + } + return ret; } @@ -446,12 +556,63 @@ static int csi2rx_enum_mbus_code(struct v4l2_subdev *subdev, return 0; } +static int _csi2rx_set_routing(struct v4l2_subdev *subdev, + struct v4l2_subdev_state *state, + struct v4l2_subdev_krouting *routing) +{ + static const struct v4l2_mbus_framefmt format = { + .width = 640, + .height = 480, + .code = MEDIA_BUS_FMT_UYVY8_1X16, + .field = V4L2_FIELD_NONE, + .colorspace = V4L2_COLORSPACE_SRGB, + .ycbcr_enc = V4L2_YCBCR_ENC_601, + .quantization = V4L2_QUANTIZATION_LIM_RANGE, + .xfer_func = V4L2_XFER_FUNC_SRGB, + }; + int ret; + + if (routing->num_routes > V4L2_FRAME_DESC_ENTRY_MAX) + return -EINVAL; + + ret = v4l2_subdev_routing_validate(subdev, routing, + V4L2_SUBDEV_ROUTING_ONLY_1_TO_1); + if (ret) + return ret; + + ret = v4l2_subdev_set_routing_with_fmt(subdev, state, routing, &format); + if (ret) + return ret; + + return 0; +} + +static int csi2rx_set_routing(struct v4l2_subdev *subdev, + struct v4l2_subdev_state *state, + enum v4l2_subdev_format_whence which, + struct v4l2_subdev_krouting *routing) +{ + struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev); + int ret; + + if (which == V4L2_SUBDEV_FORMAT_ACTIVE && csi2rx->count) + return -EBUSY; + + ret = _csi2rx_set_routing(subdev, state, routing); + + if (ret) + return ret; + + csi2rx_update_vc_select(csi2rx, state); + + return 0; +} + static int csi2rx_set_fmt(struct v4l2_subdev *subdev, struct v4l2_subdev_state *state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt; - unsigned int i; /* No transcoding, source and sink formats must match. */ if (format->pad != CSI2RX_PAD_SINK) @@ -463,14 +624,19 @@ static int csi2rx_set_fmt(struct v4l2_subdev *subdev, format->format.field = V4L2_FIELD_NONE; /* Set sink format */ - fmt = v4l2_subdev_state_get_format(state, format->pad); + fmt = v4l2_subdev_state_get_format(state, format->pad, format->stream); + if (!fmt) + return -EINVAL; + *fmt = format->format; - /* Propagate to source formats */ - for (i = CSI2RX_PAD_SOURCE_STREAM0; i < CSI2RX_PAD_MAX; i++) { - fmt = v4l2_subdev_state_get_format(state, i); - *fmt = format->format; - } + /* Propagate to source format */ + fmt = v4l2_subdev_state_get_opposite_stream_format(state, format->pad, + format->stream); + if (!fmt) + return -EINVAL; + + *fmt = format->format; return 0; } @@ -478,40 +644,92 @@ static int csi2rx_set_fmt(struct v4l2_subdev *subdev, static int csi2rx_init_state(struct v4l2_subdev *subdev, struct v4l2_subdev_state *state) { - struct v4l2_subdev_format format = { - .pad = CSI2RX_PAD_SINK, - .format = { - .width = 640, - .height = 480, - .code = MEDIA_BUS_FMT_UYVY8_1X16, - .field = V4L2_FIELD_NONE, - .colorspace = V4L2_COLORSPACE_SRGB, - .ycbcr_enc = V4L2_YCBCR_ENC_601, - .quantization = V4L2_QUANTIZATION_LIM_RANGE, - .xfer_func = V4L2_XFER_FUNC_SRGB, + struct v4l2_subdev_route routes[] = { + { + .sink_pad = CSI2RX_PAD_SINK, + .sink_stream = 0, + .source_pad = CSI2RX_PAD_SOURCE_STREAM0, + .source_stream = 0, + .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE, }, }; - return csi2rx_set_fmt(subdev, state, &format); + struct v4l2_subdev_krouting routing = { + .num_routes = ARRAY_SIZE(routes), + .routes = routes, + }; + + return _csi2rx_set_routing(subdev, state, &routing); } static int csi2rx_get_frame_desc(struct v4l2_subdev *subdev, unsigned int pad, struct v4l2_mbus_frame_desc *fd) { struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev); + struct v4l2_mbus_frame_desc source_fd = {0}; + struct v4l2_subdev_route *route; + struct v4l2_subdev_state *state; + int ret; + + ret = csi2rx_get_frame_desc_from_source(csi2rx, &source_fd); + if (ret) + return ret; + + fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2; - return csi2rx_get_frame_desc_from_source(csi2rx, fd); + state = v4l2_subdev_lock_and_get_active_state(subdev); + + for_each_active_route(&state->routing, route) { + struct v4l2_mbus_frame_desc_entry *source_entry = NULL; + unsigned int i; + + if (route->source_pad != pad) + continue; + + for (i = 0; i < source_fd.num_entries; i++) { + if (source_fd.entry[i].stream == route->sink_stream) { + source_entry = &source_fd.entry[i]; + break; + } + } + + if (!source_entry) { + dev_err(csi2rx->dev, + "Failed to find stream from source frame desc\n"); + ret = -EPIPE; + goto err_missing_stream; + } + + fd->entry[fd->num_entries].stream = route->source_stream; + fd->entry[fd->num_entries].flags = source_entry->flags; + fd->entry[fd->num_entries].length = source_entry->length; + fd->entry[fd->num_entries].pixelcode = source_entry->pixelcode; + fd->entry[fd->num_entries].bus.csi2.vc = + source_entry->bus.csi2.vc; + fd->entry[fd->num_entries].bus.csi2.dt = + source_entry->bus.csi2.dt; + + fd->num_entries++; + } + +err_missing_stream: + v4l2_subdev_unlock_state(state); + + return ret; } static const struct v4l2_subdev_pad_ops csi2rx_pad_ops = { - .enum_mbus_code = csi2rx_enum_mbus_code, - .get_fmt = v4l2_subdev_get_fmt, - .set_fmt = csi2rx_set_fmt, - .get_frame_desc = csi2rx_get_frame_desc, + .enum_mbus_code = csi2rx_enum_mbus_code, + .get_fmt = v4l2_subdev_get_fmt, + .set_fmt = csi2rx_set_fmt, + .get_frame_desc = csi2rx_get_frame_desc, + .set_routing = csi2rx_set_routing, + .enable_streams = csi2rx_enable_streams, + .disable_streams = csi2rx_disable_streams, }; static const struct v4l2_subdev_video_ops csi2rx_video_ops = { - .s_stream = csi2rx_s_stream, + .s_stream = csi2rx_s_stream_fallback, }; static const struct v4l2_subdev_ops csi2rx_subdev_ops = { @@ -766,7 +984,8 @@ static int csi2rx_probe(struct platform_device *pdev) csi2rx->pads[CSI2RX_PAD_SINK].flags = MEDIA_PAD_FL_SINK; for (i = CSI2RX_PAD_SOURCE_STREAM0; i < CSI2RX_PAD_MAX; i++) csi2rx->pads[i].flags = MEDIA_PAD_FL_SOURCE; - csi2rx->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + csi2rx->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | + V4L2_SUBDEV_FL_STREAMS; csi2rx->subdev.entity.ops = &csi2rx_media_ops; ret = media_entity_pads_init(&csi2rx->subdev.entity, CSI2RX_PAD_MAX, From patchwork Thu Jun 27 13:10:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 13714395 Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (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 2D5691922ED; Thu, 27 Jun 2024 13:10:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.19.142 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493860; cv=none; b=cinNNIp8bVOsKKMh0lt/4Wjt0Ha/6FoIhwZSPHOjbb6siMEftgPzv58LDk1TlpF61ew9Xd5yJKi9Iah/gN/WD4c62cYxf4OlE405+L2VrSmMwa5OY8iE+3X+IZOvC++6Kksd3AupwFfGGPz1I0QVIf1uMofFnZXUW2BrJHF+OAg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493860; c=relaxed/simple; bh=1ILCKrJLk9yaR4g/99eHvsKhfmfkthRxGFvcqEtG0NI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=HEB5KCv74g7M0d/aR6r7oP1q7444PlsPNZGYtwryus5lJFU4XzTG49eTZp7bJyiKLJ/cjaFSIIaH8nzZnm9V/E57Tu6hS+YeqPPxbGoGGoQ0+d6UlyU7MyVNZSViF2zwZTl74PWwt3gGMgtjBn3ZX8LJr8l0eJZrSB/Cc6RoJ58= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=idCEbP6Z; arc=none smtp.client-ip=198.47.19.142 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="idCEbP6Z" Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 45RDAhI5118853; Thu, 27 Jun 2024 08:10:43 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1719493843; bh=eqpXbGgbSDm8LbfkG0ZxunuOipJ1J05Yvt9OotQs7a8=; h=From:Date:Subject:References:In-Reply-To:To:CC; b=idCEbP6Z/ulilRRAFS2BPfu+i27lbFIH0qVd5Mp6F2D8FxkSf3UV9uzdUmCrkNvTA iurUEl0CjQpJaPgBcF2RLqrk/ZKgE9EJkT6nk4MUYH+zZpVpOenGawsWWKajc0dMKT /kAJ3uVUenwZMevo5fXN1boVk3LswqVxjnylAcYY= Received: from DFLE113.ent.ti.com (dfle113.ent.ti.com [10.64.6.34]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 45RDAhwE029395 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 27 Jun 2024 08:10:43 -0500 Received: from DFLE108.ent.ti.com (10.64.6.29) by DFLE113.ent.ti.com (10.64.6.34) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Thu, 27 Jun 2024 08:10:42 -0500 Received: from lelvsmtp5.itg.ti.com (10.180.75.250) by DFLE108.ent.ti.com (10.64.6.29) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Thu, 27 Jun 2024 08:10:42 -0500 Received: from localhost (jluthra.dhcp.ti.com [172.24.227.116]) by lelvsmtp5.itg.ti.com (8.15.2/8.15.2) with ESMTP id 45RDAgTC072577; Thu, 27 Jun 2024 08:10:42 -0500 From: Jai Luthra Date: Thu, 27 Jun 2024 18:40:07 +0530 Subject: [PATCH v2 12/13] media: ti: j721e-csi2rx: add multistream support Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <20240627-multistream-v2-12-6ae96c54c1c3@ti.com> References: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> In-Reply-To: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> To: Tomi Valkeinen , Mauro Carvalho Chehab , Sakari Ailus , Hans Verkuil , Vaishnav Achath , Maxime Ripard , Rob Herring , Krzysztof Kozlowski , Conor Dooley CC: , , Vignesh Raghavendra , Aradhya Bhatia , Devarsh Thakkar , Changhuang Liang , Jack Zhu , Julien Massot , Laurent Pinchart , Jai Luthra X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=openpgp-sha256; l=11269; i=j-luthra@ti.com; h=from:subject:message-id; bh=1ILCKrJLk9yaR4g/99eHvsKhfmfkthRxGFvcqEtG0NI=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBmfWS9xlUOGi/ECwQK3YAyanGnwOtFrNvGwsBJi qG+4jiLD0WJAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZn1kvQAKCRBD3pH5JJpx RdhGEADBveKpD0i+iHxWxXWsVueUUedeG39hSYdb/OmQoU15I8X6qtX6COKX5g2ejnEt9mRtY/P DayQZrCQ+RzCfjFou4cZ+sGtLNQXa5AF2KCrTwKSysMVPdJodoIdSYHfMjGuBzHlDumI+PIR+2X nd2HsxF8F99lzCMe0xc/Zbtj5//Qdik6Qu23jbsoTJGIZYxQJNMqVSrhY3cyDkEwdzVMDtD594R XClUG/6i2CyWgaZxWnX04ooehJwzRf5H7Pwcyvx2/xJt64auMcRPIAajTMGmBaP2twz7LFsNi9H 9/1DqNPDygMSeksapc1+ChDUOd3xQ7Dbg2YC1txQ5Q9KNMf+Z7B5MHUpyPzRQYq07sBSYAy4HL/ 37PJs5NzZfvwCfpdKxTDp3WE3xFrx30i0WfM/K47HN/gpzEMiJaFHr29H8u9JSxJdFnpugcCyjk ZL90NN3lexonahQ5rQ8Ew8X+r8gY0YYa47zrWoEpR26NSwY46gwu0j5Tv2GxBlRK3EU/AUMnwcs k7KSzeRG+iDAZlPn9dLIwziR1DunqW3unGnnzbnJKfUr6Eaq035r2q9BjIQDCx4/cQmo+9suvDp /HGgUDL1skGoZhjxkhIhn+Luo3LFVG/I+2o+P49IXKw3PMS328SF8EYfkIqbubdIAQsXycCdf0R cmfrHRyLS+NOrHg== X-Developer-Key: i=j-luthra@ti.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Each CSI2 stream can be multiplexed into 4 independent streams, each identified by its virtual channel number. To capture this multiplexed stream, the application needs to tell the driver how it wants to route the data. It needs to specify which context should process which stream. This is done via the new routing APIs. Add ioctls to accept routing information from the application and save that in the driver. This can be used when starting streaming on a context to determine which route and consequently which virtual channel it should process. Support the new enable_stream()/disable_stream() APIs in the subdev instead of s_stream() hook. We wait for the userspace to start capturing on all video nodes that have active routes, and once all video nodes are STREAMON, we request the source to enable_stream() for all the sink streams. Co-developed-by: Pratyush Yadav Signed-off-by: Pratyush Yadav Signed-off-by: Jai Luthra --- .../media/platform/ti/j721e-csi2rx/j721e-csi2rx.c | 231 +++++++++++++++++---- 1 file changed, 185 insertions(+), 46 deletions(-) diff --git a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c index c0916ca1a6f8..84b972c251e8 100644 --- a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c +++ b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c @@ -124,6 +124,7 @@ struct ti_csi2rx_dev { struct v4l2_subdev *source; struct v4l2_subdev subdev; struct ti_csi2rx_ctx ctx[TI_CSI2RX_MAX_CTX]; + u64 streams_mask; /* Enabled sink streams */ /* Buffer to drain stale data from PSI-L endpoint */ struct { void *vaddr; @@ -535,10 +536,6 @@ static void ti_csi2rx_setup_shim(struct ti_csi2rx_ctx *ctx) fmt = find_format_by_fourcc(ctx->v_fmt.fmt.pix.pixelformat); - /* De-assert the pixel interface reset. */ - reg = SHIM_CNTL_PIX_RST; - writel(reg, csi->shim + SHIM_CNTL); - reg = SHIM_DMACNTX_EN; reg |= FIELD_PREP(SHIM_DMACNTX_FMT, fmt->csi_dt); @@ -881,8 +878,12 @@ static int ti_csi2rx_start_streaming(struct vb2_queue *vq, unsigned int count) struct ti_csi2rx_dev *csi = ctx->csi; struct ti_csi2rx_dma *dma = &ctx->dma; struct ti_csi2rx_buffer *buf; + struct v4l2_subdev_krouting *routing; + struct v4l2_subdev_route *route = NULL; + struct media_pad *remote_pad; unsigned long flags; - int ret = 0; + int ret = 0, i; + struct v4l2_subdev_state *state; spin_lock_irqsave(&dma->lock, flags); if (list_empty(&dma->queue)) @@ -895,6 +896,40 @@ static int ti_csi2rx_start_streaming(struct vb2_queue *vq, unsigned int count) if (ret) goto err; + remote_pad = media_entity_remote_source_pad_unique(ctx->pad.entity); + if (!remote_pad) { + ret = -ENODEV; + goto err; + } + + state = v4l2_subdev_lock_and_get_active_state(&csi->subdev); + + routing = &state->routing; + + /* Find the stream to process. */ + for (i = 0; i < routing->num_routes; i++) { + struct v4l2_subdev_route *r = &routing->routes[i]; + + if (!(r->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE)) + continue; + + if (r->source_pad != remote_pad->index) + continue; + + route = r; + break; + } + + if (!route) { + ret = -ENODEV; + v4l2_subdev_unlock_state(state); + goto err; + } + + ctx->stream = route->sink_stream; + + v4l2_subdev_unlock_state(state); + ret = ti_csi2rx_get_vc(ctx); if (ret == -ENOIOCTLCMD) ctx->vc = 0; @@ -921,7 +956,10 @@ static int ti_csi2rx_start_streaming(struct vb2_queue *vq, unsigned int count) dma->state = TI_CSI2RX_DMA_ACTIVE; spin_unlock_irqrestore(&dma->lock, flags); - ret = v4l2_subdev_call(&csi->subdev, video, s_stream, 1); + /* Start stream 0, we don't allow multiple streams on the source pad */ + ret = v4l2_subdev_enable_streams(&csi->subdev, + TI_CSI2RX_PAD_FIRST_SOURCE + ctx->idx, + BIT(0)); if (ret) goto err_dma; @@ -944,12 +982,16 @@ static void ti_csi2rx_stop_streaming(struct vb2_queue *vq) struct ti_csi2rx_dev *csi = ctx->csi; int ret; - video_device_pipeline_stop(&ctx->vdev); - + /* assert pixel reset to prevent stale data */ writel(0, csi->shim + SHIM_CNTL); + + video_device_pipeline_stop(&ctx->vdev); writel(0, csi->shim + SHIM_DMACNTX(ctx->idx)); - ret = v4l2_subdev_call(&csi->subdev, video, s_stream, 0); + ret = v4l2_subdev_disable_streams(&csi->subdev, + TI_CSI2RX_PAD_FIRST_SOURCE + ctx->idx, + BIT(0)); + if (ret) dev_err(csi->dev, "Failed to stop subdev stream\n"); @@ -995,8 +1037,8 @@ static int ti_csi2rx_sd_set_fmt(struct v4l2_subdev *sd, } *fmt = format->format; - fmt = v4l2_subdev_state_get_format(state, TI_CSI2RX_PAD_FIRST_SOURCE, - format->stream); + fmt = v4l2_subdev_state_get_opposite_stream_format(state, format->pad, + format->stream); if (!fmt) { ret = -EINVAL; goto out; @@ -1007,72 +1049,169 @@ static int ti_csi2rx_sd_set_fmt(struct v4l2_subdev *sd, return ret; } +static int _ti_csi2rx_sd_set_routing(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_krouting *routing) +{ + int ret; + + const struct v4l2_mbus_framefmt format = { + .width = 640, + .height = 480, + .code = MEDIA_BUS_FMT_UYVY8_1X16, + .field = V4L2_FIELD_NONE, + .colorspace = V4L2_COLORSPACE_SRGB, + .ycbcr_enc = V4L2_YCBCR_ENC_601, + .quantization = V4L2_QUANTIZATION_LIM_RANGE, + .xfer_func = V4L2_XFER_FUNC_SRGB, + }; + + ret = v4l2_subdev_routing_validate(sd, routing, + V4L2_SUBDEV_ROUTING_ONLY_1_TO_1 | + V4L2_SUBDEV_ROUTING_NO_SOURCE_MULTIPLEXING); + + if (ret) + return ret; + + /* Only stream ID 0 allowed on source pads */ + for (unsigned int i = 0; i < routing->num_routes; ++i) { + const struct v4l2_subdev_route *route = &routing->routes[i]; + + if (route->source_stream != 0) + return -EINVAL; + } + + ret = v4l2_subdev_set_routing_with_fmt(sd, state, routing, &format); + + return ret; +} + +static int ti_csi2rx_sd_set_routing(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + enum v4l2_subdev_format_whence which, + struct v4l2_subdev_krouting *routing) +{ + struct ti_csi2rx_dev *csi = to_csi2rx_dev(sd); + + if (csi->enable_count > 0) + return -EBUSY; + + return _ti_csi2rx_sd_set_routing(sd, state, routing); +} + static int ti_csi2rx_sd_init_state(struct v4l2_subdev *sd, struct v4l2_subdev_state *state) { - struct v4l2_subdev_format format = { - .pad = TI_CSI2RX_PAD_SINK, - .format = { - .width = 640, - .height = 480, - .code = MEDIA_BUS_FMT_UYVY8_1X16, - .field = V4L2_FIELD_NONE, - .colorspace = V4L2_COLORSPACE_SRGB, - .ycbcr_enc = V4L2_YCBCR_ENC_601, - .quantization = V4L2_QUANTIZATION_LIM_RANGE, - .xfer_func = V4L2_XFER_FUNC_SRGB, - }, + struct v4l2_subdev_route routes[] = { { + .sink_pad = 0, + .sink_stream = 0, + .source_pad = TI_CSI2RX_PAD_FIRST_SOURCE, + .source_stream = 0, + .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE, + } }; + + struct v4l2_subdev_krouting routing = { + .num_routes = 1, + .routes = routes, }; - return ti_csi2rx_sd_set_fmt(sd, state, &format); + /* Initialize routing to single route to the fist source pad */ + return _ti_csi2rx_sd_set_routing(sd, state, &routing); } -static int ti_csi2rx_sd_s_stream(struct v4l2_subdev *sd, int enable) +static int ti_csi2rx_sd_enable_streams(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + u32 pad, u64 streams_mask) { struct ti_csi2rx_dev *csi = to_csi2rx_dev(sd); + struct v4l2_subdev_route *route; + struct media_pad *remote_pad; + u64 sink_streams; int ret = 0; + u32 reg; + remote_pad = media_entity_remote_source_pad_unique(&csi->subdev.entity); + if (!remote_pad) + return -ENODEV; + sink_streams = v4l2_subdev_state_xlate_streams(state, pad, + TI_CSI2RX_PAD_SINK, + &streams_mask); mutex_lock(&csi->mutex); - if (enable) { - if (csi->enable_count > 0) { - csi->enable_count++; + csi->streams_mask |= sink_streams; + /* + * Check if all active streams are enabled, and only then start + * streaming on the source + */ + for_each_active_route(&state->routing, route) { + if (!(csi->streams_mask & BIT_ULL(route->sink_stream))) goto out; - } + } - ret = v4l2_subdev_call(csi->source, video, s_stream, 1); - if (ret) - goto out; + /* De-assert the pixel interface reset. */ + reg = SHIM_CNTL_PIX_RST; + writel(reg, csi->shim + SHIM_CNTL); + ret = v4l2_subdev_enable_streams(csi->source, remote_pad->index, + csi->streams_mask); +out: + if (!ret) csi->enable_count++; - } else { - if (csi->enable_count == 0) { - ret = -EINVAL; - goto out; - } + mutex_unlock(&csi->mutex); - if (--csi->enable_count > 0) - goto out; + return ret; +} + +static int ti_csi2rx_sd_disable_streams(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + u32 pad, u64 streams_mask) +{ + struct ti_csi2rx_dev *csi = to_csi2rx_dev(sd); + struct v4l2_subdev_route *route; + struct media_pad *remote_pad; + u64 sink_streams; + int ret = 0; - ret = v4l2_subdev_call(csi->source, video, s_stream, 0); + remote_pad = media_entity_remote_source_pad_unique(&csi->subdev.entity); + if (!remote_pad) + return -ENODEV; + sink_streams = v4l2_subdev_state_xlate_streams(state, pad, + TI_CSI2RX_PAD_SINK, + &streams_mask); + + mutex_lock(&csi->mutex); + if (csi->enable_count == 0) { + ret = -EINVAL; + goto out; } + /* Check if any of the active streams are already disabled */ + for_each_active_route(&state->routing, route) { + if (!(csi->streams_mask & BIT_ULL(route->sink_stream))) { + --csi->enable_count; + goto out; + } + } + /* Disable all streams on the source */ + ret = v4l2_subdev_disable_streams(csi->source, remote_pad->index, + csi->streams_mask); + if (!ret) + --csi->enable_count; out: + csi->streams_mask &= ~sink_streams; mutex_unlock(&csi->mutex); return ret; } static const struct v4l2_subdev_pad_ops ti_csi2rx_subdev_pad_ops = { + .set_routing = ti_csi2rx_sd_set_routing, .get_fmt = v4l2_subdev_get_fmt, .set_fmt = ti_csi2rx_sd_set_fmt, -}; - -static const struct v4l2_subdev_video_ops ti_csi2rx_subdev_video_ops = { - .s_stream = ti_csi2rx_sd_s_stream, + .enable_streams = ti_csi2rx_sd_enable_streams, + .disable_streams = ti_csi2rx_sd_disable_streams, }; static const struct v4l2_subdev_ops ti_csi2rx_subdev_ops = { - .video = &ti_csi2rx_subdev_video_ops, .pad = &ti_csi2rx_subdev_pad_ops, }; @@ -1264,7 +1403,7 @@ static int ti_csi2rx_v4l2_init(struct ti_csi2rx_dev *csi) v4l2_subdev_init(sd, &ti_csi2rx_subdev_ops); sd->internal_ops = &ti_csi2rx_internal_ops; sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; - sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE; + sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_STREAMS; strscpy(sd->name, dev_name(csi->dev), sizeof(sd->name)); sd->dev = csi->dev; sd->entity.ops = &ti_csi2rx_subdev_entity_ops; From patchwork Thu Jun 27 13:10:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 13714392 Received: from lelv0143.ext.ti.com (lelv0143.ext.ti.com [198.47.23.248]) (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 01F70191491; Thu, 27 Jun 2024 13:10:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.23.248 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493857; cv=none; b=EDLbMhIpD7ep3y8uf52MatB8HfV8Av1AHzlVAMys3R1M0ZxR0H9QS2wIjoGumHpweOoWpJmf6HgqSo6XV/OZarCwLYMjetZfm16MtCoGlF8wXFvs3fPd/464pc0uwtc15Ddl0fgNub8QcdZZCPha8SqFAPqIi9+5LM2Fd/mgoHE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719493857; c=relaxed/simple; bh=FbcR+dVVbxUGN0wBjf6lwvb+us2pjWAIe25ELsV0j6A=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=WpdXU8v2YMz93F8JFuUWX/6bHYGBTJ2ScvA/pQrWPz8dYufWbDZ0HUOVWNeDIOzOLsJcGEnllskUWZZ5bujl3AGnmyMYxneDzewgzyzgI6iwqETK4jRSPgL8a3GGffp6LGKltwE58UyFxnikCsvEW1UFDnC4HfN0hDrradCn4hY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=Ncaa1QRy; arc=none smtp.client-ip=198.47.23.248 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="Ncaa1QRy" Received: from lelv0265.itg.ti.com ([10.180.67.224]) by lelv0143.ext.ti.com (8.15.2/8.15.2) with ESMTP id 45RDAiKD110257; Thu, 27 Jun 2024 08:10:44 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1719493844; bh=W9I8M0fJ29EEa1Vs6py4YdDpWiT/n+FZs2W3TvBARoY=; h=From:Date:Subject:References:In-Reply-To:To:CC; b=Ncaa1QRyHcB6HIbgB9a1F70yTCxDCAEM0J/+TgdAwbJKcQM9Sk1fXpA3nw7Jhtarb x6xH8e/2VzngLT1LfympFwLoAWO0jL6H/1M/D6NiAFHJsYVdF6uAzzote8rAQK74IZ ZgnO40rd1TkIGG1eZZ1eHn19BaJNDClZbF8rjNQQ= Received: from DLEE105.ent.ti.com (dlee105.ent.ti.com [157.170.170.35]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 45RDAik3029431 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 27 Jun 2024 08:10:44 -0500 Received: from DLEE114.ent.ti.com (157.170.170.25) by DLEE105.ent.ti.com (157.170.170.35) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Thu, 27 Jun 2024 08:10:44 -0500 Received: from lelvsmtp5.itg.ti.com (10.180.75.250) by DLEE114.ent.ti.com (157.170.170.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Thu, 27 Jun 2024 08:10:44 -0500 Received: from localhost (jluthra.dhcp.ti.com [172.24.227.116]) by lelvsmtp5.itg.ti.com (8.15.2/8.15.2) with ESMTP id 45RDAhJh072744; Thu, 27 Jun 2024 08:10:44 -0500 From: Jai Luthra Date: Thu, 27 Jun 2024 18:40:08 +0530 Subject: [PATCH v2 13/13] media: ti: j721e-csi2rx: Submit all available buffers Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <20240627-multistream-v2-13-6ae96c54c1c3@ti.com> References: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> In-Reply-To: <20240627-multistream-v2-0-6ae96c54c1c3@ti.com> To: Tomi Valkeinen , Mauro Carvalho Chehab , Sakari Ailus , Hans Verkuil , Vaishnav Achath , Maxime Ripard , Rob Herring , Krzysztof Kozlowski , Conor Dooley CC: , , Vignesh Raghavendra , Aradhya Bhatia , Devarsh Thakkar , Changhuang Liang , Jack Zhu , Julien Massot , Laurent Pinchart , Jai Luthra X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=openpgp-sha256; l=3576; i=j-luthra@ti.com; h=from:subject:message-id; bh=FbcR+dVVbxUGN0wBjf6lwvb+us2pjWAIe25ELsV0j6A=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBmfWS+jgHgO1a5SJEwXQ37yzNnduJruvc/sx6CU 4hkmKyvqUmJAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZn1kvgAKCRBD3pH5JJpx RdyjD/9QcfTeOz89dcMzVZ3z4tXfZyeKqFX5GXRBDV/S+SqZemYQ3K4Pkw1ABQRL8tSRo5LcZvh CqsMIZVGWgY2A1cIynS0mSI9qrGDJbUXSyUS/bL5ceWTUYiKd8m/J0/6Og7+3/3x6i0jQmgNkW7 rlLibDNaZYTqWEIDTnqGpXbTZInqjFzhte2IBKH51BtrHk3zxX/BWLU1jbW5Z0o+DiEJt+NfICu WOiW+Y5yp266MoLG5RyGcTIrv4ndwkMMGqBhOP0bZsMyH7j+qkBN4h84j4YcDlxtTZN6/58Iw6p n8UhynuGNG38zZQNOop5OOuCkbzFnkDThp7ClCz6Q6nJEfHK6V8u6ZiZb5c489RP2G/fwGFwySc XwNRFg7UyoJ4r3YKw/VfdzVfPMZid8ZqOfIY+uEDiNB1fmt+2LUd+vvUhZzZPI3jLbeJL7CSJxK qC5iEHD7Ty0EG/XEP8dY8fAxrLmjYZ0e8mYfIvg4zW0+fFIJEMpeY+D8GxIknTir/HHjDQ2JKrs EirR25dDLy2AEw1sMMJ25HL3/CXUrhj8Rym/xTVKdUh+DSKon5nVBuLPwL0OBiys0j+vZHnfnOt pd0VrpKSnL+F8B/dUg7ZbwruvT8iolrNtFIt5mvlwzcwi9GiRtbngS7GsV8YNrV8bHJqBpNDyyv w1Pxq7uJqC3mSCg== X-Developer-Key: i=j-luthra@ti.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 We already make sure to submit all available buffers to DMA in each DMA completion callback. Move that logic in a separate function, and use it during stream start as well, as most application queue all their buffers before stream on. Signed-off-by: Jai Luthra --- .../media/platform/ti/j721e-csi2rx/j721e-csi2rx.c | 43 ++++++++++++---------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c index 84b972c251e8..a258477b9084 100644 --- a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c +++ b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c @@ -637,6 +637,27 @@ static int ti_csi2rx_drain_dma(struct ti_csi2rx_ctx *ctx) return ret; } +static int ti_csi2rx_dma_submit_pending(struct ti_csi2rx_ctx *ctx) +{ + struct ti_csi2rx_dma *dma = &ctx->dma; + struct ti_csi2rx_buffer *buf; + int ret = 0; + + /* If there are more buffers to process then start their transfer. */ + while (!list_empty(&dma->queue)) { + buf = list_entry(dma->queue.next, struct ti_csi2rx_buffer, list); + ret = ti_csi2rx_start_dma(ctx, buf); + if (ret) { + dev_err(ctx->csi->dev, + "Failed to queue the next buffer for DMA\n"); + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); + break; + } + list_move_tail(&buf->list, &dma->submitted); + } + return ret; +} + static void ti_csi2rx_dma_callback(void *param) { struct ti_csi2rx_buffer *buf = param; @@ -657,18 +678,7 @@ static void ti_csi2rx_dma_callback(void *param) vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); list_del(&buf->list); - /* If there are more buffers to process then start their transfer. */ - while (!list_empty(&dma->queue)) { - buf = list_entry(dma->queue.next, struct ti_csi2rx_buffer, list); - - if (ti_csi2rx_start_dma(ctx, buf)) { - dev_err(ctx->csi->dev, - "Failed to queue the next buffer for DMA\n"); - vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); - } else { - list_move_tail(&buf->list, &dma->submitted); - } - } + ti_csi2rx_dma_submit_pending(ctx); if (list_empty(&dma->submitted)) dma->state = TI_CSI2RX_DMA_IDLE; @@ -877,7 +887,6 @@ static int ti_csi2rx_start_streaming(struct vb2_queue *vq, unsigned int count) struct ti_csi2rx_ctx *ctx = vb2_get_drv_priv(vq); struct ti_csi2rx_dev *csi = ctx->csi; struct ti_csi2rx_dma *dma = &ctx->dma; - struct ti_csi2rx_buffer *buf; struct v4l2_subdev_krouting *routing; struct v4l2_subdev_route *route = NULL; struct media_pad *remote_pad; @@ -943,16 +952,13 @@ static int ti_csi2rx_start_streaming(struct vb2_queue *vq, unsigned int count) ctx->sequence = 0; spin_lock_irqsave(&dma->lock, flags); - buf = list_entry(dma->queue.next, struct ti_csi2rx_buffer, list); - ret = ti_csi2rx_start_dma(ctx, buf); + ret = ti_csi2rx_dma_submit_pending(ctx); if (ret) { - dev_err(csi->dev, "Failed to start DMA: %d\n", ret); spin_unlock_irqrestore(&dma->lock, flags); - goto err_pipeline; + goto err_dma; } - list_move_tail(&buf->list, &dma->submitted); dma->state = TI_CSI2RX_DMA_ACTIVE; spin_unlock_irqrestore(&dma->lock, flags); @@ -967,7 +973,6 @@ static int ti_csi2rx_start_streaming(struct vb2_queue *vq, unsigned int count) err_dma: ti_csi2rx_stop_dma(ctx); -err_pipeline: video_device_pipeline_stop(&ctx->vdev); writel(0, csi->shim + SHIM_CNTL); writel(0, csi->shim + SHIM_DMACNTX(ctx->idx));