Message ID | 1527884768-22392-6-git-send-email-vgarodia@codeaurora.org (mailing list archive) |
---|---|
State | Changes Requested, archived |
Delegated to: | Hans Verkuil |
Headers |
Received: from vger.kernel.org ([209.132.180.67]) by www.linuxtv.org with esmtp (Exim 4.84_2) (envelope-from <linux-media-owner@vger.kernel.org>) id 1fOqe1-0003L9-RV; Fri, 01 Jun 2018 20:27:30 +0000 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753711AbeFAU10 (ORCPT <rfc822;mkrufky@linuxtv.org> + 1 other); Fri, 1 Jun 2018 16:27:26 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:54886 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753658AbeFAU1K (ORCPT <rfc822; linux-media@vger.kernel.org>); Fri, 1 Jun 2018 16:27:10 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 1E9C260708; Fri, 1 Jun 2018 20:27:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1527884830; bh=SiH6jCPIlPiRwSgeHB44AZ6a3GJvpWlOsJa2gvLv6pU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=P6j0pHcFWEiIMVLcWhUZDferNGIUR9e/Pm+AhGPmaea42nA5v2sC9vNvC4MZyq1xO R1VxWNY/3sJhZik3xZPLYpM9vf5UGlP+V4hg+hPRwITyJR6TgcaYzB5I6W7geY9gTQ 0Wn87Yq+K5Q4yQsgEbQyILqenW2cieqldVKFk3ps= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on pdx-caf-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.8 required=2.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED, T_DKIM_INVALID autolearn=no autolearn_force=no version=3.4.0 Received: from vgarodia-linux.qualcomm.com (blr-c-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.19.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: vgarodia@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 4DB85607E7; Fri, 1 Jun 2018 20:27:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1527884829; bh=SiH6jCPIlPiRwSgeHB44AZ6a3GJvpWlOsJa2gvLv6pU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=D22nUGnsN3VZLW9zkIDyQKwKE/0SncIYrg4EsFG/dDGZGplDgKAz0+X+7NcPtFZcP MmgBl9TKFPOxLDI2m9lCgQhvj+ByHlqOOfwgao09Lr/vK5nak981BCjWaTk7s9slCX 4tIOMyYSZhkMGtvd220F1FglVRBI59QbsYOvhEVA= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 4DB85607E7 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=vgarodia@codeaurora.org From: Vikash Garodia <vgarodia@codeaurora.org> To: hverkuil@xs4all.nl, mchehab@kernel.org, robh@kernel.org, mark.rutland@arm.com, andy.gross@linaro.org, bjorn.andersson@linaro.org, stanimir.varbanov@linaro.org Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-soc@vger.kernel.org, devicetree@vger.kernel.org, vgarodia@codeaurora.org, acourbot@chromium.org Subject: [PATCH v2 5/5] venus: register separate driver for firmware device Date: Sat, 2 Jun 2018 01:56:08 +0530 Message-Id: <1527884768-22392-6-git-send-email-vgarodia@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1527884768-22392-1-git-send-email-vgarodia@codeaurora.org> References: <1527884768-22392-1-git-send-email-vgarodia@codeaurora.org> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: <linux-media.vger.kernel.org> X-Mailing-List: linux-media@vger.kernel.org |
Commit Message
Vikash Garodia
June 1, 2018, 8:26 p.m. UTC
A separate child device is added for video firmware.
This is needed to
[1] configure the firmware context bank with the desired SID.
[2] ensure that the iova for firmware region is from 0x0.
Signed-off-by: Vikash Garodia <vgarodia@codeaurora.org>
---
.../devicetree/bindings/media/qcom,venus.txt | 8 +++-
drivers/media/platform/qcom/venus/core.c | 48 +++++++++++++++++++---
drivers/media/platform/qcom/venus/firmware.c | 20 ++++++++-
drivers/media/platform/qcom/venus/firmware.h | 2 +
4 files changed, 71 insertions(+), 7 deletions(-)
Comments
On Sat, Jun 02, 2018 at 01:56:08AM +0530, Vikash Garodia wrote: > A separate child device is added for video firmware. > This is needed to > [1] configure the firmware context bank with the desired SID. > [2] ensure that the iova for firmware region is from 0x0. > > Signed-off-by: Vikash Garodia <vgarodia@codeaurora.org> > --- > .../devicetree/bindings/media/qcom,venus.txt | 8 +++- > drivers/media/platform/qcom/venus/core.c | 48 +++++++++++++++++++--- > drivers/media/platform/qcom/venus/firmware.c | 20 ++++++++- > drivers/media/platform/qcom/venus/firmware.h | 2 + > 4 files changed, 71 insertions(+), 7 deletions(-) > > diff --git a/Documentation/devicetree/bindings/media/qcom,venus.txt b/Documentation/devicetree/bindings/media/qcom,venus.txt > index 00d0d1b..701cbe8 100644 > --- a/Documentation/devicetree/bindings/media/qcom,venus.txt > +++ b/Documentation/devicetree/bindings/media/qcom,venus.txt > @@ -53,7 +53,7 @@ > > * Subnodes > The Venus video-codec node must contain two subnodes representing > -video-decoder and video-encoder. > +video-decoder and video-encoder, one optional firmware subnode. > > Every of video-encoder or video-decoder subnode should have: > > @@ -79,6 +79,8 @@ Every of video-encoder or video-decoder subnode should have: > power domain which is responsible for collapsing > and restoring power to the subcore. > > +The firmware sub node must contain the iommus specifiers for ARM9. > + > * An Example > video-codec@1d00000 { > compatible = "qcom,msm8916-venus"; > @@ -105,4 +107,8 @@ Every of video-encoder or video-decoder subnode should have: > clock-names = "core"; > power-domains = <&mmcc VENUS_CORE1_GDSC>; > }; > + venus-firmware { > + compatible = "qcom,venus-firmware-no-tz"; > + iommus = <&apps_smmu 0x10b2 0x0>; > + } > }; > diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c > index 101612b..5cfb3c2 100644 > --- a/drivers/media/platform/qcom/venus/core.c > +++ b/drivers/media/platform/qcom/venus/core.c > @@ -179,6 +179,19 @@ static u32 to_v4l2_codec_type(u32 codec) > } > } > > +static int store_firmware_dev(struct device *dev, void *data) > +{ > + struct venus_core *core = data; > + > + if (!core) > + return -EINVAL; Core is not going to be null here - you don't need to check it. <snip>
Hi Vikash, On Sat, Jun 2, 2018 at 5:27 AM Vikash Garodia <vgarodia@codeaurora.org> wrote: > > A separate child device is added for video firmware. > This is needed to > [1] configure the firmware context bank with the desired SID. > [2] ensure that the iova for firmware region is from 0x0. > > Signed-off-by: Vikash Garodia <vgarodia@codeaurora.org> > --- > .../devicetree/bindings/media/qcom,venus.txt | 8 +++- > drivers/media/platform/qcom/venus/core.c | 48 +++++++++++++++++++--- > drivers/media/platform/qcom/venus/firmware.c | 20 ++++++++- > drivers/media/platform/qcom/venus/firmware.h | 2 + > 4 files changed, 71 insertions(+), 7 deletions(-) > > diff --git a/Documentation/devicetree/bindings/media/qcom,venus.txt b/Documentation/devicetree/bindings/media/qcom,venus.txt > index 00d0d1b..701cbe8 100644 > --- a/Documentation/devicetree/bindings/media/qcom,venus.txt > +++ b/Documentation/devicetree/bindings/media/qcom,venus.txt > @@ -53,7 +53,7 @@ > > * Subnodes > The Venus video-codec node must contain two subnodes representing > -video-decoder and video-encoder. > +video-decoder and video-encoder, one optional firmware subnode. > > Every of video-encoder or video-decoder subnode should have: > > @@ -79,6 +79,8 @@ Every of video-encoder or video-decoder subnode should have: > power domain which is responsible for collapsing > and restoring power to the subcore. > > +The firmware sub node must contain the iommus specifiers for ARM9. Please document the compatible string here as well. > + > * An Example > video-codec@1d00000 { > compatible = "qcom,msm8916-venus"; > @@ -105,4 +107,8 @@ Every of video-encoder or video-decoder subnode should have: > clock-names = "core"; > power-domains = <&mmcc VENUS_CORE1_GDSC>; > }; > + venus-firmware { > + compatible = "qcom,venus-firmware-no-tz"; I don't think "-no-tz" should be mentioned here in DT, since it's a firmware/software detail. > + iommus = <&apps_smmu 0x10b2 0x0>; > + } > }; > diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c > index 101612b..5cfb3c2 100644 > --- a/drivers/media/platform/qcom/venus/core.c > +++ b/drivers/media/platform/qcom/venus/core.c > @@ -179,6 +179,19 @@ static u32 to_v4l2_codec_type(u32 codec) > } > } > > +static int store_firmware_dev(struct device *dev, void *data) > +{ > + struct venus_core *core = data; > + > + if (!core) > + return -EINVAL; > + No need to check this AFAICT. > + if (of_device_is_compatible(dev->of_node, "qcom,venus-firmware-no-tz")) > + core->fw.dev = dev; > + > + return 0; > +} > + > static int venus_enumerate_codecs(struct venus_core *core, u32 type) > { > const struct hfi_inst_ops dummy_ops = {}; > @@ -279,6 +292,13 @@ static int venus_probe(struct platform_device *pdev) > if (ret < 0) > goto err_runtime_disable; > > + ret = of_platform_populate(dev->of_node, NULL, NULL, dev); > + if (ret) > + goto err_runtime_disable; > + > + /* Attempt to store firmware device */ > + device_for_each_child(dev, core, store_firmware_dev); > + > ret = venus_boot(core); > if (ret) > goto err_runtime_disable; > @@ -303,10 +323,6 @@ static int venus_probe(struct platform_device *pdev) > if (ret) > goto err_core_deinit; > > - ret = of_platform_populate(dev->of_node, NULL, NULL, dev); > - if (ret) > - goto err_dev_unregister; > - > ret = pm_runtime_put_sync(dev); > if (ret) > goto err_dev_unregister; > @@ -483,7 +499,29 @@ static __maybe_unused int venus_runtime_resume(struct device *dev) > .pm = &venus_pm_ops, > }, > }; > -module_platform_driver(qcom_venus_driver); > + > +static int __init venus_init(void) > +{ > + int ret; > + > + ret = platform_driver_register(&qcom_video_firmware_driver); > + if (ret) > + return ret; Do we really need this firmware driver? As far as I can see, the approach used here should work even without any driver bound to the firmware device. Best regards, Tomasz
Hi Tomasz, On 06/04/2018 04:18 PM, Tomasz Figa wrote: > Hi Vikash, > > On Sat, Jun 2, 2018 at 5:27 AM Vikash Garodia <vgarodia@codeaurora.org> wrote: >> >> A separate child device is added for video firmware. >> This is needed to >> [1] configure the firmware context bank with the desired SID. >> [2] ensure that the iova for firmware region is from 0x0. >> >> Signed-off-by: Vikash Garodia <vgarodia@codeaurora.org> >> --- >> .../devicetree/bindings/media/qcom,venus.txt | 8 +++- >> drivers/media/platform/qcom/venus/core.c | 48 +++++++++++++++++++--- >> drivers/media/platform/qcom/venus/firmware.c | 20 ++++++++- >> drivers/media/platform/qcom/venus/firmware.h | 2 + >> 4 files changed, 71 insertions(+), 7 deletions(-) >> >> diff --git a/Documentation/devicetree/bindings/media/qcom,venus.txt b/Documentation/devicetree/bindings/media/qcom,venus.txt >> index 00d0d1b..701cbe8 100644 >> --- a/Documentation/devicetree/bindings/media/qcom,venus.txt >> +++ b/Documentation/devicetree/bindings/media/qcom,venus.txt >> @@ -53,7 +53,7 @@ >> >> * Subnodes >> The Venus video-codec node must contain two subnodes representing >> -video-decoder and video-encoder. >> +video-decoder and video-encoder, one optional firmware subnode. >> >> Every of video-encoder or video-decoder subnode should have: >> >> @@ -79,6 +79,8 @@ Every of video-encoder or video-decoder subnode should have: >> power domain which is responsible for collapsing >> and restoring power to the subcore. >> >> +The firmware sub node must contain the iommus specifiers for ARM9. > > Please document the compatible string here as well. > >> + >> * An Example >> video-codec@1d00000 { >> compatible = "qcom,msm8916-venus"; >> @@ -105,4 +107,8 @@ Every of video-encoder or video-decoder subnode should have: >> clock-names = "core"; >> power-domains = <&mmcc VENUS_CORE1_GDSC>; >> }; >> + venus-firmware { >> + compatible = "qcom,venus-firmware-no-tz"; > > I don't think "-no-tz" should be mentioned here in DT, since it's a > firmware/software detail. I have to agree with Tomasz, non-tz or tz is a software detail and it shouldn't be reflected in compatible string. Also I'm not sure but what will happen if this video-firmware subnode is not added, do you expect that backward compatibility is satisfied for older venus versions? > >> + iommus = <&apps_smmu 0x10b2 0x0>; >> + } >> }; >> diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c >> index 101612b..5cfb3c2 100644 >> --- a/drivers/media/platform/qcom/venus/core.c >> +++ b/drivers/media/platform/qcom/venus/core.c >> @@ -179,6 +179,19 @@ static u32 to_v4l2_codec_type(u32 codec) >> } >> } >> >> +static int store_firmware_dev(struct device *dev, void *data) >> +{ >> + struct venus_core *core = data; >> + >> + if (!core) >> + return -EINVAL; >> + > > No need to check this AFAICT.> >> + if (of_device_is_compatible(dev->of_node, "qcom,venus-firmware-no-tz")) >> + core->fw.dev = dev; >> + >> + return 0; >> +} >> + >> static int venus_enumerate_codecs(struct venus_core *core, u32 type) >> { >> const struct hfi_inst_ops dummy_ops = {}; >> @@ -279,6 +292,13 @@ static int venus_probe(struct platform_device *pdev) >> if (ret < 0) >> goto err_runtime_disable; >> >> + ret = of_platform_populate(dev->of_node, NULL, NULL, dev); >> + if (ret) >> + goto err_runtime_disable; >> + >> + /* Attempt to store firmware device */ >> + device_for_each_child(dev, core, store_firmware_dev); >> + >> ret = venus_boot(core); >> if (ret) >> goto err_runtime_disable; >> @@ -303,10 +323,6 @@ static int venus_probe(struct platform_device *pdev) >> if (ret) >> goto err_core_deinit; >> >> - ret = of_platform_populate(dev->of_node, NULL, NULL, dev); >> - if (ret) >> - goto err_dev_unregister; >> - >> ret = pm_runtime_put_sync(dev); >> if (ret) >> goto err_dev_unregister; >> @@ -483,7 +499,29 @@ static __maybe_unused int venus_runtime_resume(struct device *dev) >> .pm = &venus_pm_ops, >> }, >> }; >> -module_platform_driver(qcom_venus_driver); >> + >> +static int __init venus_init(void) >> +{ >> + int ret; >> + >> + ret = platform_driver_register(&qcom_video_firmware_driver); >> + if (ret) >> + return ret; > > Do we really need this firmware driver? As far as I can see, the > approach used here should work even without any driver bound to the > firmware device. We need device/driver bind because we need to call dma_configure() which internally doing iommus sID parsing.
On Mon, Jun 4, 2018 at 10:56 PM Stanimir Varbanov <stanimir.varbanov@linaro.org> wrote: > > Hi Tomasz, > > On 06/04/2018 04:18 PM, Tomasz Figa wrote: > > Hi Vikash, > > > > On Sat, Jun 2, 2018 at 5:27 AM Vikash Garodia <vgarodia@codeaurora.org> wrote: > >> +static int __init venus_init(void) > >> +{ > >> + int ret; > >> + > >> + ret = platform_driver_register(&qcom_video_firmware_driver); > >> + if (ret) > >> + return ret; > > > > Do we really need this firmware driver? As far as I can see, the > > approach used here should work even without any driver bound to the > > firmware device. > > We need device/driver bind because we need to call dma_configure() which > internally doing iommus sID parsing. I can see some drivers calling of_dma_configure() directly: https://elixir.bootlin.com/linux/latest/ident/of_dma_configure I'm not sure if it's more elegant, but should at least require less code. By the way, can we really assume that probe of firmware platform device really completes before we call venus_boot()? Best regards, Tomasz
Cc: Arnd On 06/05/2018 07:08 AM, Tomasz Figa wrote: > On Mon, Jun 4, 2018 at 10:56 PM Stanimir Varbanov > <stanimir.varbanov@linaro.org> wrote: >> >> Hi Tomasz, >> >> On 06/04/2018 04:18 PM, Tomasz Figa wrote: >>> Hi Vikash, >>> >>> On Sat, Jun 2, 2018 at 5:27 AM Vikash Garodia <vgarodia@codeaurora.org> wrote: >>>> +static int __init venus_init(void) >>>> +{ >>>> + int ret; >>>> + >>>> + ret = platform_driver_register(&qcom_video_firmware_driver); >>>> + if (ret) >>>> + return ret; >>> >>> Do we really need this firmware driver? As far as I can see, the >>> approach used here should work even without any driver bound to the >>> firmware device. >> >> We need device/driver bind because we need to call dma_configure() which >> internally doing iommus sID parsing. > > I can see some drivers calling of_dma_configure() directly: > https://elixir.bootlin.com/linux/latest/ident/of_dma_configure > > I'm not sure if it's more elegant, but should at least require less code. I think that in this case of non-TZ where we do iommu mapping by hand we can use shared-dma-pool reserved memory see how venus_boot has been implemented in the beginning [1]. Arnd what do you think? Some background, we have a use-case where the memory for firmware needs to be mapped by the venus driver by hand instead of TZ firmware calls. I.e. we want to support both, iommu mapping from the driver and mapping done by TZ firmware. How we will differentiate what mapping (TZ or non-TZ) will be used is a separate issue. > > By the way, can we really assume that probe of firmware platform > device really completes before we call venus_boot()? I'd say we cannot.
On Sat, Jun 02, 2018 at 01:56:08AM +0530, Vikash Garodia wrote: > A separate child device is added for video firmware. > This is needed to > [1] configure the firmware context bank with the desired SID. > [2] ensure that the iova for firmware region is from 0x0. > > Signed-off-by: Vikash Garodia <vgarodia@codeaurora.org> > --- > .../devicetree/bindings/media/qcom,venus.txt | 8 +++- > drivers/media/platform/qcom/venus/core.c | 48 +++++++++++++++++++--- > drivers/media/platform/qcom/venus/firmware.c | 20 ++++++++- > drivers/media/platform/qcom/venus/firmware.h | 2 + > 4 files changed, 71 insertions(+), 7 deletions(-) > > diff --git a/Documentation/devicetree/bindings/media/qcom,venus.txt b/Documentation/devicetree/bindings/media/qcom,venus.txt > index 00d0d1b..701cbe8 100644 > --- a/Documentation/devicetree/bindings/media/qcom,venus.txt > +++ b/Documentation/devicetree/bindings/media/qcom,venus.txt > @@ -53,7 +53,7 @@ > > * Subnodes > The Venus video-codec node must contain two subnodes representing > -video-decoder and video-encoder. > +video-decoder and video-encoder, one optional firmware subnode. > > Every of video-encoder or video-decoder subnode should have: > > @@ -79,6 +79,8 @@ Every of video-encoder or video-decoder subnode should have: > power domain which is responsible for collapsing > and restoring power to the subcore. > > +The firmware sub node must contain the iommus specifiers for ARM9. > + > * An Example > video-codec@1d00000 { > compatible = "qcom,msm8916-venus"; > @@ -105,4 +107,8 @@ Every of video-encoder or video-decoder subnode should have: > clock-names = "core"; > power-domains = <&mmcc VENUS_CORE1_GDSC>; > }; > + venus-firmware { > + compatible = "qcom,venus-firmware-no-tz"; > + iommus = <&apps_smmu 0x10b2 0x0>; This mostly looks like you are adding a node in order to create a platform device. DT is not the only way to create platform devices and shouldn't be used when the device is not really a separate h/w device. Plus it seems like it is debatable that you even need a driver. For iommus, just move it up to the parent (or add to existing prop). Rob
Hi Rob, On Wed, Jun 6, 2018 at 6:08 AM Rob Herring <robh@kernel.org> wrote: > > On Sat, Jun 02, 2018 at 01:56:08AM +0530, Vikash Garodia wrote: > > A separate child device is added for video firmware. > > This is needed to > > [1] configure the firmware context bank with the desired SID. > > [2] ensure that the iova for firmware region is from 0x0. > > > > Signed-off-by: Vikash Garodia <vgarodia@codeaurora.org> > > --- > > .../devicetree/bindings/media/qcom,venus.txt | 8 +++- > > drivers/media/platform/qcom/venus/core.c | 48 +++++++++++++++++++--- > > drivers/media/platform/qcom/venus/firmware.c | 20 ++++++++- > > drivers/media/platform/qcom/venus/firmware.h | 2 + > > 4 files changed, 71 insertions(+), 7 deletions(-) > > > > diff --git a/Documentation/devicetree/bindings/media/qcom,venus.txt b/Documentation/devicetree/bindings/media/qcom,venus.txt > > index 00d0d1b..701cbe8 100644 > > --- a/Documentation/devicetree/bindings/media/qcom,venus.txt > > +++ b/Documentation/devicetree/bindings/media/qcom,venus.txt > > @@ -53,7 +53,7 @@ > > > > * Subnodes > > The Venus video-codec node must contain two subnodes representing > > -video-decoder and video-encoder. > > +video-decoder and video-encoder, one optional firmware subnode. > > > > Every of video-encoder or video-decoder subnode should have: > > > > @@ -79,6 +79,8 @@ Every of video-encoder or video-decoder subnode should have: > > power domain which is responsible for collapsing > > and restoring power to the subcore. > > > > +The firmware sub node must contain the iommus specifiers for ARM9. > > + > > * An Example > > video-codec@1d00000 { > > compatible = "qcom,msm8916-venus"; > > @@ -105,4 +107,8 @@ Every of video-encoder or video-decoder subnode should have: > > clock-names = "core"; > > power-domains = <&mmcc VENUS_CORE1_GDSC>; > > }; > > + venus-firmware { > > + compatible = "qcom,venus-firmware-no-tz"; > > + iommus = <&apps_smmu 0x10b2 0x0>; > > This mostly looks like you are adding a node in order to create a > platform device. DT is not the only way to create platform devices and > shouldn't be used when the device is not really a separate h/w device. > Plus it seems like it is debatable that you even need a driver. > > For iommus, just move it up to the parent (or add to existing prop). As far as I understood the issue from reading this series and also talking a bit with Stanimir, there are multiple (physical?) ports from the Venus hardware block and that includes one dedicated for firmware loading, which has IOVA range restrictions up to 6 MiBs or something like that. If we add the firmware port to the iommus property of the main node, we would bind it to the same IOVA address space as the other ports and so it would be part of the main full 32-bit IOMMU domain. Best regards, Tomasz
On Tue, Jun 5, 2018 at 5:45 PM Stanimir Varbanov <stanimir.varbanov@linaro.org> wrote: > > Cc: Arnd > > On 06/05/2018 07:08 AM, Tomasz Figa wrote: > > On Mon, Jun 4, 2018 at 10:56 PM Stanimir Varbanov > > <stanimir.varbanov@linaro.org> wrote: > >> > >> Hi Tomasz, > >> > >> On 06/04/2018 04:18 PM, Tomasz Figa wrote: > >>> Hi Vikash, > >>> > >>> On Sat, Jun 2, 2018 at 5:27 AM Vikash Garodia <vgarodia@codeaurora.org> wrote: > >>>> +static int __init venus_init(void) > >>>> +{ > >>>> + int ret; > >>>> + > >>>> + ret = platform_driver_register(&qcom_video_firmware_driver); > >>>> + if (ret) > >>>> + return ret; > >>> > >>> Do we really need this firmware driver? As far as I can see, the > >>> approach used here should work even without any driver bound to the > >>> firmware device. > >> > >> We need device/driver bind because we need to call dma_configure() which > >> internally doing iommus sID parsing. > > > > I can see some drivers calling of_dma_configure() directly: > > https://elixir.bootlin.com/linux/latest/ident/of_dma_configure > > > > I'm not sure if it's more elegant, but should at least require less code. > > I think that in this case of non-TZ where we do iommu mapping by hand we > can use shared-dma-pool reserved memory see how venus_boot has been > implemented in the beginning [1]. I might have misunderstood something, but wasn't the shared-dma-pool about reserving physical memory, while the venus firmware problem is about reserving certain range of IOVA? > > Arnd what do you think? > > Some background, we have a use-case where the memory for firmware needs > to be mapped by the venus driver by hand instead of TZ firmware calls. > I.e. we want to support both, iommu mapping from the driver and mapping > done by TZ firmware. How we will differentiate what mapping (TZ or > non-TZ) will be used is a separate issue. > > > > > By the way, can we really assume that probe of firmware platform > > device really completes before we call venus_boot()? > > I'd say we cannot. Looking at current implementation in driver core, of_platform_populate() would actually trigger a synchronous probe, so I guess it could work. However, I'm not sure if this is a general guarantee here or it's an implementation detail that shouldn't be relied on. If we end up really need to have this platform_driver, I guess we could call platform_driver_probe() after of_platform_populate(), rather than pre-registering the driver. That seems to be the way to ensure that the probe is synchronous and we can also check that a matching device was found by the return value. Best regards, Tomasz
On Tue, Jun 5, 2018 at 11:46 PM, Tomasz Figa <tfiga@google.com> wrote: > Hi Rob, > > On Wed, Jun 6, 2018 at 6:08 AM Rob Herring <robh@kernel.org> wrote: >> >> On Sat, Jun 02, 2018 at 01:56:08AM +0530, Vikash Garodia wrote: >> > A separate child device is added for video firmware. >> > This is needed to >> > [1] configure the firmware context bank with the desired SID. >> > [2] ensure that the iova for firmware region is from 0x0. >> > >> > Signed-off-by: Vikash Garodia <vgarodia@codeaurora.org> >> > --- >> > .../devicetree/bindings/media/qcom,venus.txt | 8 +++- >> > drivers/media/platform/qcom/venus/core.c | 48 +++++++++++++++++++--- >> > drivers/media/platform/qcom/venus/firmware.c | 20 ++++++++- >> > drivers/media/platform/qcom/venus/firmware.h | 2 + >> > 4 files changed, 71 insertions(+), 7 deletions(-) >> > >> > diff --git a/Documentation/devicetree/bindings/media/qcom,venus.txt b/Documentation/devicetree/bindings/media/qcom,venus.txt >> > index 00d0d1b..701cbe8 100644 >> > --- a/Documentation/devicetree/bindings/media/qcom,venus.txt >> > +++ b/Documentation/devicetree/bindings/media/qcom,venus.txt >> > @@ -53,7 +53,7 @@ >> > >> > * Subnodes >> > The Venus video-codec node must contain two subnodes representing >> > -video-decoder and video-encoder. >> > +video-decoder and video-encoder, one optional firmware subnode. >> > >> > Every of video-encoder or video-decoder subnode should have: >> > >> > @@ -79,6 +79,8 @@ Every of video-encoder or video-decoder subnode should have: >> > power domain which is responsible for collapsing >> > and restoring power to the subcore. >> > >> > +The firmware sub node must contain the iommus specifiers for ARM9. >> > + >> > * An Example >> > video-codec@1d00000 { >> > compatible = "qcom,msm8916-venus"; >> > @@ -105,4 +107,8 @@ Every of video-encoder or video-decoder subnode should have: >> > clock-names = "core"; >> > power-domains = <&mmcc VENUS_CORE1_GDSC>; >> > }; >> > + venus-firmware { >> > + compatible = "qcom,venus-firmware-no-tz"; >> > + iommus = <&apps_smmu 0x10b2 0x0>; >> >> This mostly looks like you are adding a node in order to create a >> platform device. DT is not the only way to create platform devices and >> shouldn't be used when the device is not really a separate h/w device. >> Plus it seems like it is debatable that you even need a driver. >> >> For iommus, just move it up to the parent (or add to existing prop). > > As far as I understood the issue from reading this series and also > talking a bit with Stanimir, there are multiple (physical?) ports from > the Venus hardware block and that includes one dedicated for firmware > loading, which has IOVA range restrictions up to 6 MiBs or something > like that. > > If we add the firmware port to the iommus property of the main node, > we would bind it to the same IOVA address space as the other ports and > so it would be part of the main full 32-bit IOMMU domain. Sounds like an OS limitation, not a DT problem. That being said, I suppose we can live with having this sub-node if we can't fix or work-around this limitation. Rob
On 2018-06-06 10:16, Tomasz Figa wrote: > Hi Rob, > > On Wed, Jun 6, 2018 at 6:08 AM Rob Herring <robh@kernel.org> wrote: >> >> On Sat, Jun 02, 2018 at 01:56:08AM +0530, Vikash Garodia wrote: >> > A separate child device is added for video firmware. >> > This is needed to >> > [1] configure the firmware context bank with the desired SID. >> > [2] ensure that the iova for firmware region is from 0x0. >> > >> > Signed-off-by: Vikash Garodia <vgarodia@codeaurora.org> >> > --- >> > .../devicetree/bindings/media/qcom,venus.txt | 8 +++- >> > drivers/media/platform/qcom/venus/core.c | 48 +++++++++++++++++++--- >> > drivers/media/platform/qcom/venus/firmware.c | 20 ++++++++- >> > drivers/media/platform/qcom/venus/firmware.h | 2 + >> > 4 files changed, 71 insertions(+), 7 deletions(-) >> > >> > diff --git a/Documentation/devicetree/bindings/media/qcom,venus.txt b/Documentation/devicetree/bindings/media/qcom,venus.txt >> > index 00d0d1b..701cbe8 100644 >> > --- a/Documentation/devicetree/bindings/media/qcom,venus.txt >> > +++ b/Documentation/devicetree/bindings/media/qcom,venus.txt >> > @@ -53,7 +53,7 @@ >> > >> > * Subnodes >> > The Venus video-codec node must contain two subnodes representing >> > -video-decoder and video-encoder. >> > +video-decoder and video-encoder, one optional firmware subnode. >> > >> > Every of video-encoder or video-decoder subnode should have: >> > >> > @@ -79,6 +79,8 @@ Every of video-encoder or video-decoder subnode should have: >> > power domain which is responsible for collapsing >> > and restoring power to the subcore. >> > >> > +The firmware sub node must contain the iommus specifiers for ARM9. >> > + >> > * An Example >> > video-codec@1d00000 { >> > compatible = "qcom,msm8916-venus"; >> > @@ -105,4 +107,8 @@ Every of video-encoder or video-decoder subnode should have: >> > clock-names = "core"; >> > power-domains = <&mmcc VENUS_CORE1_GDSC>; >> > }; >> > + venus-firmware { >> > + compatible = "qcom,venus-firmware-no-tz"; >> > + iommus = <&apps_smmu 0x10b2 0x0>; >> >> This mostly looks like you are adding a node in order to create a >> platform device. DT is not the only way to create platform devices and >> shouldn't be used when the device is not really a separate h/w device. >> Plus it seems like it is debatable that you even need a driver. >> >> For iommus, just move it up to the parent (or add to existing prop). > > As far as I understood the issue from reading this series and also > talking a bit with Stanimir, there are multiple (physical?) ports from > the Venus hardware block and that includes one dedicated for firmware > loading, which has IOVA range restrictions up to 6 MiBs or something > like that. > > If we add the firmware port to the iommus property of the main node, > we would bind it to the same IOVA address space as the other ports and > so it would be part of the main full 32-bit IOMMU domain. Not really port-wise, but the restriction part is right. Once the firmware is loaded, the ARM9 can only execute those firmware instructions if it is present in iova address 0x0. Merging it to parent device cannot guarantee that the firmware memory is mapped from 0x0. > Best regards, > Tomasz
On Mon 04 Jun 06:56 PDT 2018, Stanimir Varbanov wrote: > On 06/04/2018 04:18 PM, Tomasz Figa wrote: > > On Sat, Jun 2, 2018 at 5:27 AM Vikash Garodia <vgarodia@codeaurora.org> wrote: [..] > >> + venus-firmware { > >> + compatible = "qcom,venus-firmware-no-tz"; > > > > I don't think "-no-tz" should be mentioned here in DT, since it's a > > firmware/software detail. > > I have to agree with Tomasz, non-tz or tz is a software detail and it > shouldn't be reflected in compatible string. > While it is software, the alternative boot and security configuration does imply different requirements on how the driver deals with the hardware. I'm not sure how you expect the kernel to be informed about the abilities of the boot/security capabilities if it's not passed through DT. In the other cases of firmware loading for co-processors this means that a number of additional resources (clocks, resets) needs to be specified in the DT node; something it seems like Venus doesn't have to do. > Also I'm not sure but what will happen if this video-firmware subnode is > not added, do you expect that backward compatibility is satisfied for > older venus versions? > I do expect that the driver should be possible to run on a 845 with the normal TZ based security model we've seen on e.g. 820. I don't know the details of Venus well enough to see if this differentiation would be sufficient. Regards, Bjorn
diff --git a/Documentation/devicetree/bindings/media/qcom,venus.txt b/Documentation/devicetree/bindings/media/qcom,venus.txt index 00d0d1b..701cbe8 100644 --- a/Documentation/devicetree/bindings/media/qcom,venus.txt +++ b/Documentation/devicetree/bindings/media/qcom,venus.txt @@ -53,7 +53,7 @@ * Subnodes The Venus video-codec node must contain two subnodes representing -video-decoder and video-encoder. +video-decoder and video-encoder, one optional firmware subnode. Every of video-encoder or video-decoder subnode should have: @@ -79,6 +79,8 @@ Every of video-encoder or video-decoder subnode should have: power domain which is responsible for collapsing and restoring power to the subcore. +The firmware sub node must contain the iommus specifiers for ARM9. + * An Example video-codec@1d00000 { compatible = "qcom,msm8916-venus"; @@ -105,4 +107,8 @@ Every of video-encoder or video-decoder subnode should have: clock-names = "core"; power-domains = <&mmcc VENUS_CORE1_GDSC>; }; + venus-firmware { + compatible = "qcom,venus-firmware-no-tz"; + iommus = <&apps_smmu 0x10b2 0x0>; + } }; diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c index 101612b..5cfb3c2 100644 --- a/drivers/media/platform/qcom/venus/core.c +++ b/drivers/media/platform/qcom/venus/core.c @@ -179,6 +179,19 @@ static u32 to_v4l2_codec_type(u32 codec) } } +static int store_firmware_dev(struct device *dev, void *data) +{ + struct venus_core *core = data; + + if (!core) + return -EINVAL; + + if (of_device_is_compatible(dev->of_node, "qcom,venus-firmware-no-tz")) + core->fw.dev = dev; + + return 0; +} + static int venus_enumerate_codecs(struct venus_core *core, u32 type) { const struct hfi_inst_ops dummy_ops = {}; @@ -279,6 +292,13 @@ static int venus_probe(struct platform_device *pdev) if (ret < 0) goto err_runtime_disable; + ret = of_platform_populate(dev->of_node, NULL, NULL, dev); + if (ret) + goto err_runtime_disable; + + /* Attempt to store firmware device */ + device_for_each_child(dev, core, store_firmware_dev); + ret = venus_boot(core); if (ret) goto err_runtime_disable; @@ -303,10 +323,6 @@ static int venus_probe(struct platform_device *pdev) if (ret) goto err_core_deinit; - ret = of_platform_populate(dev->of_node, NULL, NULL, dev); - if (ret) - goto err_dev_unregister; - ret = pm_runtime_put_sync(dev); if (ret) goto err_dev_unregister; @@ -483,7 +499,29 @@ static __maybe_unused int venus_runtime_resume(struct device *dev) .pm = &venus_pm_ops, }, }; -module_platform_driver(qcom_venus_driver); + +static int __init venus_init(void) +{ + int ret; + + ret = platform_driver_register(&qcom_video_firmware_driver); + if (ret) + return ret; + + ret = platform_driver_register(&qcom_venus_driver); + if (ret) + platform_driver_unregister(&qcom_video_firmware_driver); + + return ret; +} +module_init(venus_init); + +static void __exit venus_exit(void) +{ + platform_driver_unregister(&qcom_venus_driver); + platform_driver_unregister(&qcom_video_firmware_driver); +} +module_exit(venus_exit); MODULE_ALIAS("platform:qcom-venus"); MODULE_DESCRIPTION("Qualcomm Venus video encoder and decoder driver"); diff --git a/drivers/media/platform/qcom/venus/firmware.c b/drivers/media/platform/qcom/venus/firmware.c index 058d544..ed29d10 100644 --- a/drivers/media/platform/qcom/venus/firmware.c +++ b/drivers/media/platform/qcom/venus/firmware.c @@ -12,6 +12,7 @@ * */ +#include <linux/module.h> #include <linux/platform_device.h> #include <linux/device.h> #include <linux/firmware.h> @@ -124,7 +125,7 @@ static int venus_load_fw(struct device *dev, const char *fwname, } if (qcom_scm_is_available()) ret = qcom_mdt_load(dev, mdt, fwname, VENUS_PAS_ID, mem_va, - *mem_phys, *mem_size); + *mem_phys, *mem_size, NULL); else ret = qcom_mdt_load_no_init(dev, mdt, fwname, VENUS_PAS_ID, mem_va, *mem_phys, *mem_size, NULL); @@ -243,3 +244,20 @@ int venus_shutdown(struct venus_core *core) return ret; } + +static const struct of_device_id firmware_dt_match[] = { + { .compatible = "qcom,venus-firmware-no-tz" }, + { } +}; +MODULE_DEVICE_TABLE(of, firmware_dt_match); + +struct platform_driver qcom_video_firmware_driver = { + .driver = { + .name = "qcom-video-firmware", + .of_match_table = firmware_dt_match, + }, +}; + +MODULE_ALIAS("platform:qcom-video-firmware"); +MODULE_DESCRIPTION("Qualcomm Venus firmware driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/platform/qcom/venus/firmware.h b/drivers/media/platform/qcom/venus/firmware.h index 67fdd89..23c0409 100644 --- a/drivers/media/platform/qcom/venus/firmware.h +++ b/drivers/media/platform/qcom/venus/firmware.h @@ -21,6 +21,8 @@ struct device; +extern struct platform_driver qcom_video_firmware_driver; + int venus_boot(struct venus_core *core); int venus_shutdown(struct venus_core *core); int venus_set_hw_state(enum tzbsp_video_state, struct venus_core *core);