[Freedreno] [PATCH 2/2] drm/msm/mdp4: Return directly after a failed kzalloc() in mdp4_kms_init()
From: Markus Elfring Date: Wed, 7 Feb 2018 22:34:45 +0100 * Return directly after a call of the function "kzalloc" failed at the beginning. * Delete an initialisation and a check (for the local variable "kms") which became unnecessary with this refactoring. Signed-off-by: Markus Elfring --- drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | 11 --- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c index 5c5965a9d1f9..4f15cd569ee1 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c @@ -411,15 +411,13 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) struct platform_device *pdev = to_platform_device(dev->dev); struct mdp4_platform_config *config = mdp4_get_config(pdev); struct mdp4_kms *mdp4_kms; - struct msm_kms *kms = NULL; + struct msm_kms *kms; struct msm_gem_address_space *aspace; int irq, ret; mdp4_kms = kzalloc(sizeof(*mdp4_kms), GFP_KERNEL); - if (!mdp4_kms) { - ret = -ENOMEM; - goto fail; - } + if (!mdp4_kms) + return ERR_PTR(-ENOMEM); mdp_kms_init(&mdp4_kms->base, &kms_funcs); @@ -550,8 +548,7 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) return kms; fail: - if (kms) - mdp4_destroy(kms); + mdp4_destroy(kms); return ERR_PTR(ret); } -- 2.16.1 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH 1/2] drm/msm/mdp4: Delete an error message for a failed memory allocation in mdp4_kms_init()
From: Markus Elfring Date: Wed, 7 Feb 2018 22:22:28 +0100 Omit an extra message for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring --- drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c index f7f087419ed8..5c5965a9d1f9 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c @@ -417,7 +417,6 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) mdp4_kms = kzalloc(sizeof(*mdp4_kms), GFP_KERNEL); if (!mdp4_kms) { - dev_err(dev->dev, "failed to allocate kms\n"); ret = -ENOMEM; goto fail; } -- 2.16.1 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH 0/2] drm/msm/mdp4: Adjustments for mdp4_kms_init()
From: Markus Elfring Date: Wed, 7 Feb 2018 22:38:44 +0100 Two update suggestions were taken into account from static source code analysis. Markus Elfring (2): Delete an error message for a failed memory allocation Return directly after a failed kzalloc() drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | 12 1 file changed, 4 insertions(+), 8 deletions(-) -- 2.16.1 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH] drm/msm/mdp5: Delete an error message for a failed memory allocation in two functions
From: Markus Elfring Date: Wed, 7 Feb 2018 21:50:07 +0100 Omit an extra message for a memory allocation failure in these functions. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c | 1 - drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c index 439e0a300e25..daa224df4457 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c @@ -717,7 +717,6 @@ struct mdp5_ctl_manager *mdp5_ctlm_init(struct drm_device *dev, ctl_mgr = kzalloc(sizeof(*ctl_mgr), GFP_KERNEL); if (!ctl_mgr) { - dev_err(dev->dev, "failed to allocate CTL manager\n"); ret = -ENOMEM; goto fail; } diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 3e9bba4d6624..5bf54ca7ab0a 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -844,10 +844,8 @@ static int interface_init(struct mdp5_kms *mdp5_kms) continue; intf = kzalloc(sizeof(*intf), GFP_KERNEL); - if (!intf) { - dev_err(dev->dev, "failed to construct INTF%d\n", i); + if (!intf) return -ENOMEM; - } intf->num = i; intf->type = intf_types[i]; -- 2.16.1 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [bug report] drm/msm: add a5xx specific debugfs
Hello Rob Clark, This is a semi-automatic email about new static checker warnings. The patch 024ad8df763f: "drm/msm: add a5xx specific debugfs" from Dec 13, 2017, leads to the following Smatch complaint: ./drivers/gpu/drm/msm/adreno/a5xx_debugfs.c:166 a5xx_debugfs_init() warn: variable dereferenced before check 'minor' (see line 162) ./drivers/gpu/drm/msm/adreno/a5xx_debugfs.c 161 { 162 struct drm_device *dev = minor->dev; ^^ Dereference 163 struct dentry *ent; 164 int ret; 165 166 if (!minor) ^^ Check 167 return 0; 168 regards, dan carpenter ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH] gpu: msm: remove unused headers
All thoses files are not used by anybody. Lets just remove them. Signed-off-by: Corentin Labbe --- drivers/gpu/drm/msm/adreno/a2xx.xml.h | 1845 - drivers/gpu/drm/msm/dsi/mmss_cc.xml.h | 124 --- drivers/gpu/drm/msm/hdmi/qfprom.xml.h | 54 - 3 files changed, 2023 deletions(-) delete mode 100644 drivers/gpu/drm/msm/adreno/a2xx.xml.h delete mode 100644 drivers/gpu/drm/msm/dsi/mmss_cc.xml.h delete mode 100644 drivers/gpu/drm/msm/hdmi/qfprom.xml.h diff --git a/drivers/gpu/drm/msm/adreno/a2xx.xml.h b/drivers/gpu/drm/msm/adreno/a2xx.xml.h deleted file mode 100644 index 644374c7b3e0.. --- a/drivers/gpu/drm/msm/adreno/a2xx.xml.h +++ /dev/null @@ -1,1845 +0,0 @@ -#ifndef A2XX_XML -#define A2XX_XML - -/* Autogenerated file, DO NOT EDIT manually! - -This file was generated by the rules-ng-ng headergen tool in this git repository: -http://github.com/freedreno/envytools/ -git clone https://github.com/freedreno/envytools.git - -The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 431 bytes, from 2017-05-17 13:21:27) -- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2017-05-17 13:21:27) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 37162 bytes, from 2017-05-17 13:21:27) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 13324 bytes, from 2017-05-17 13:21:27) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml( 31866 bytes, from 2017-06-06 18:26:14) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 83840 bytes, from 2017-05-17 13:21:27) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 111898 bytes, from 2017-06-06 18:23:59) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a5xx.xml ( 139480 bytes, from 2017-06-16 12:44:39) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2017-05-17 13:21:27) - -Copyright (C) 2013-2017 by the following authors: -- Rob Clark (robclark) -- Ilia Mirkin (imirkin) - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - - -enum a2xx_rb_dither_type { - DITHER_PIXEL = 0, - DITHER_SUBPIXEL = 1, -}; - -enum a2xx_colorformatx { - COLORX_4_4_4_4 = 0, - COLORX_1_5_5_5 = 1, - COLORX_5_6_5 = 2, - COLORX_8 = 3, - COLORX_8_8 = 4, - COLORX_8_8_8_8 = 5, - COLORX_S8_8_8_8 = 6, - COLORX_16_FLOAT = 7, - COLORX_16_16_FLOAT = 8, - COLORX_16_16_16_16_FLOAT = 9, - COLORX_32_FLOAT = 10, - COLORX_32_32_FLOAT = 11, - COLORX_32_32_32_32_FLOAT = 12, - COLORX_2_3_3 = 13, - COLORX_8_8_8 = 14, -}; - -enum a2xx_sq_surfaceformat { - FMT_1_REVERSE = 0, - FMT_1 = 1, - FMT_8 = 2, - FMT_1_5_5_5 = 3, - FMT_5_6_5 = 4, - FMT_6_5_5 = 5, - FMT_8_8_8_8 = 6, - FMT_2_10_10_10 = 7, - FMT_8_A = 8, - FMT_8_B = 9, - FMT_8_8 = 10, - FMT_Cr_Y1_Cb_Y0 = 11, - FMT_Y1_Cr_Y0_Cb = 12, - FMT_5_5_5_1 = 13, - FMT_8_8_8_8_A = 14, - FMT_4_4_4_4 = 15, - FMT_10_11_11 = 16, - FMT_11_11_10 = 17, - FMT_DXT1 = 18, - FMT_DXT2_3 = 19, - FMT_DXT4_5 = 20, - FMT_24_8 = 22, - FMT_24_8_FLOAT = 23, - FMT_16 = 24, - FMT_16_16 = 25, - FMT_16_16_16_16 = 26, - FMT_16_EXPAND = 27, - FMT_16_16_EXPAND = 28, - FMT_16_16_16_16_EXPAND = 29, - FMT_16_FLOAT = 30, - FMT_16_16_FLOAT = 31, - FMT_16_16_16_16_FLOAT = 32, - FMT_32 = 33, - FMT_32_32 = 34, - FMT_32_32_32_32 = 35, - FMT_32_FLOAT = 36, - FMT_32_32_FLOAT = 37, - FMT_32_32_32_32_FLOAT = 38, - FMT_32_AS_8 = 39, - FMT_32_AS_8_8 = 40, - FMT_16_MPEG = 41, - FMT_16_16_MPEG = 42, -
[Freedreno] [PATCH v7 6/6] drm/msm: iommu: Replace runtime calls with runtime suppliers
While handling the concerned iommu, there should not be a need to power control the drm devices from iommu interface. If these drm devices need to be powered around this time, the respective drivers should take care of this. Replace the pm_runtime_get/put_sync() with pm_runtime_get/put_suppliers() calls, to power-up the connected iommu through the device link interface. In case the device link is not setup these get/put_suppliers() calls will be a no-op, and the iommu driver should take care of powering on its devices accordingly. Signed-off-by: Vivek Gautam --- drivers/gpu/drm/msm/msm_iommu.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c index b23d33622f37..1ab629bbee69 100644 --- a/drivers/gpu/drm/msm/msm_iommu.c +++ b/drivers/gpu/drm/msm/msm_iommu.c @@ -40,9 +40,9 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const char * const *names, struct msm_iommu *iommu = to_msm_iommu(mmu); int ret; - pm_runtime_get_sync(mmu->dev); + pm_runtime_get_suppliers(mmu->dev); ret = iommu_attach_device(iommu->domain, mmu->dev); - pm_runtime_put_sync(mmu->dev); + pm_runtime_put_suppliers(mmu->dev); return ret; } @@ -52,9 +52,9 @@ static void msm_iommu_detach(struct msm_mmu *mmu, const char * const *names, { struct msm_iommu *iommu = to_msm_iommu(mmu); - pm_runtime_get_sync(mmu->dev); + pm_runtime_get_suppliers(mmu->dev); iommu_detach_device(iommu->domain, mmu->dev); - pm_runtime_put_sync(mmu->dev); + pm_runtime_put_suppliers(mmu->dev); } static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova, @@ -63,9 +63,9 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova, struct msm_iommu *iommu = to_msm_iommu(mmu); size_t ret; -// pm_runtime_get_sync(mmu->dev); + pm_runtime_get_suppliers(mmu->dev); ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot); -// pm_runtime_put_sync(mmu->dev); + pm_runtime_put_suppliers(mmu->dev); WARN_ON(ret < 0); return (ret == len) ? 0 : -EINVAL; @@ -76,9 +76,9 @@ static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova, { struct msm_iommu *iommu = to_msm_iommu(mmu); - pm_runtime_get_sync(mmu->dev); + pm_runtime_get_suppliers(mmu->dev); iommu_unmap(iommu->domain, iova, len); - pm_runtime_put_sync(mmu->dev); + pm_runtime_put_suppliers(mmu->dev); return 0; } -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v7 5/6] iommu/arm-smmu: Add support for qcom, smmu-v2 variant
qcom,smmu-v2 is an arm,smmu-v2 implementation with specific clock and power requirements. This smmu core is used with multiple masters on msm8996, viz. mdss, video, etc. Add bindings for the same. Signed-off-by: Vivek Gautam Reviewed-by: Rob Herring --- .../devicetree/bindings/iommu/arm,smmu.txt | 43 ++ drivers/iommu/arm-smmu.c | 13 +++ 2 files changed, 56 insertions(+) diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt b/Documentation/devicetree/bindings/iommu/arm,smmu.txt index 8a6ffce12af5..169222ae2706 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt @@ -17,10 +17,19 @@ conditions. "arm,mmu-401" "arm,mmu-500" "cavium,smmu-v2" +"qcom,-smmu-v2", "qcom,smmu-v2" depending on the particular implementation and/or the version of the architecture implemented. + A number of Qcom SoCs use qcom,smmu-v2 version of the IP. + "qcom,-smmu-v2" represents a soc specific compatible + string that should be present along with the "qcom,smmu-v2" + to facilitate SoC specific clocks/power connections and to + address specific bug fixes. + An example string would be - + "qcom,msm8996-smmu-v2", "qcom,smmu-v2". + - reg : Base address and size of the SMMU. - #global-interrupts : The number of global interrupts exposed by the @@ -71,6 +80,23 @@ conditions. or using stream matching with #iommu-cells = <2>, and may be ignored if present in such cases. +- clock-names:Should be "bus", and "iface" for "qcom,smmu-v2" + implementation. + + "bus" clock for "qcom,smmu-v2" is required for downstream + bus access and for the smmu ptw. + + "iface" clock is required to access smmu's registers through + the TCU's programming interface. + +- clocks: Phandles for respective clocks described by clock-names. + +- power-domains: Phandles to SMMU's power domain specifier. This is + required even if SMMU belongs to the master's power + domain, as the SMMU will have to be enabled and + accessed before master gets enabled and linked to its + SMMU. + ** Deprecated properties: - mmu-masters (deprecated in favour of the generic "iommus" binding) : @@ -137,3 +163,20 @@ conditions. iommu-map = <0 &smmu3 0 0x400>; ... }; + + /* Qcom's arm,smmu-v2 implementation */ + smmu4: iommu { + compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2"; + reg = <0xd0 0x1>; + + #global-interrupts = <1>; + interrupts = , +, +; + #iommu-cells = <1>; + power-domains = <&mmcc MDSS_GDSC>; + + clocks = <&mmcc SMMU_MDP_AXI_CLK>, +<&mmcc SMMU_MDP_AHB_CLK>; + clock-names = "bus", "iface"; + }; diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index c7e924d553bd..721cf1291f85 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -119,6 +119,7 @@ enum arm_smmu_implementation { GENERIC_SMMU, ARM_MMU500, CAVIUM_SMMUV2, + QCOM_SMMUV2, }; struct arm_smmu_s2cr { @@ -1950,6 +1951,17 @@ struct arm_smmu_match_data { ARM_SMMU_MATCH_DATA(arm_mmu500, ARM_SMMU_V2, ARM_MMU500); ARM_SMMU_MATCH_DATA(cavium_smmuv2, ARM_SMMU_V2, CAVIUM_SMMUV2); +static const char * const qcom_smmuv2_clks[] = { + "bus", "iface", +}; + +static const struct arm_smmu_match_data qcom_smmuv2 = { + .version = ARM_SMMU_V2, + .model = QCOM_SMMUV2, + .clks = qcom_smmuv2_clks, + .num_clks = ARRAY_SIZE(qcom_smmuv2_clks), +}; + static const struct of_device_id arm_smmu_of_match[] = { { .compatible = "arm,smmu-v1", .data = &smmu_generic_v1 }, { .compatible = "arm,smmu-v2", .data = &smmu_generic_v2 }, @@ -1957,6 +1969,7 @@ struct arm_smmu_match_data { { .compatible = "arm,mmu-401", .data = &arm_mmu401 }, { .compatible = "arm,mmu-500", .data = &arm_mmu500 }, { .compatible = "cavium,smmu-v2", .data = &cavium_smmuv2 }, + { .compatible = "qcom,smmu-v2", .data = &qcom_smmuv2 }, { }, }; MODULE_DEVICE_TABLE(of, arm_smmu_of_match); -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listi
[Freedreno] [PATCH v7 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device
From: Sricharan R The smmu device probe/remove and add/remove master device callbacks gets called when the smmu is not linked to its master, that is without the context of the master device. So calling runtime apis in those places separately. Signed-off-by: Sricharan R [vivek: Cleanup pm runtime calls] Signed-off-by: Vivek Gautam --- drivers/iommu/arm-smmu.c | 42 ++ 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 9e2f917e16c2..c024f69c1682 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -913,11 +913,15 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain) struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); struct arm_smmu_device *smmu = smmu_domain->smmu; struct arm_smmu_cfg *cfg = &smmu_domain->cfg; - int irq; + int ret, irq; if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY) return; + ret = pm_runtime_get_sync(smmu->dev); + if (ret) + return; + /* * Disable the context bank and free the page tables before freeing * it. @@ -932,6 +936,8 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain) free_io_pgtable_ops(smmu_domain->pgtbl_ops); __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx); + + pm_runtime_put_sync(smmu->dev); } static struct iommu_domain *arm_smmu_domain_alloc(unsigned type) @@ -1407,14 +1413,22 @@ static int arm_smmu_add_device(struct device *dev) while (i--) cfg->smendx[i] = INVALID_SMENDX; - ret = arm_smmu_master_alloc_smes(dev); + ret = pm_runtime_get_sync(smmu->dev); if (ret) goto out_cfg_free; + ret = arm_smmu_master_alloc_smes(dev); + if (ret) + goto out_rpm_put; + iommu_device_link(&smmu->iommu, dev); + pm_runtime_put_sync(smmu->dev); + return 0; +out_rpm_put: + pm_runtime_put_sync(smmu->dev); out_cfg_free: kfree(cfg); out_free: @@ -1427,7 +1441,7 @@ static void arm_smmu_remove_device(struct device *dev) struct iommu_fwspec *fwspec = dev->iommu_fwspec; struct arm_smmu_master_cfg *cfg; struct arm_smmu_device *smmu; - + int ret; if (!fwspec || fwspec->ops != &arm_smmu_ops) return; @@ -1435,8 +1449,15 @@ static void arm_smmu_remove_device(struct device *dev) cfg = fwspec->iommu_priv; smmu = cfg->smmu; + ret = pm_runtime_get_sync(smmu->dev); + if (ret) + return; + iommu_device_unlink(&smmu->iommu, dev); arm_smmu_master_free_smes(fwspec); + + pm_runtime_put_sync(smmu->dev); + iommu_group_remove_device(dev); kfree(fwspec->iommu_priv); iommu_fwspec_free(dev); @@ -2131,6 +2152,14 @@ static int arm_smmu_device_probe(struct platform_device *pdev) if (err) return err; + platform_set_drvdata(pdev, smmu); + + pm_runtime_enable(dev); + + err = pm_runtime_get_sync(dev); + if (err) + return err; + err = arm_smmu_device_cfg_probe(smmu); if (err) return err; @@ -2172,9 +2201,9 @@ static int arm_smmu_device_probe(struct platform_device *pdev) return err; } - platform_set_drvdata(pdev, smmu); arm_smmu_device_reset(smmu); arm_smmu_test_smr_masks(smmu); + pm_runtime_put_sync(dev); /* * For ACPI and generic DT bindings, an SMMU will be probed before @@ -2211,8 +2240,13 @@ static int arm_smmu_device_remove(struct platform_device *pdev) if (!bitmap_empty(smmu->context_map, ARM_SMMU_MAX_CBS)) dev_err(&pdev->dev, "removing device with active domains!\n"); + pm_runtime_get_sync(smmu->dev); /* Turn the thing off */ writel(sCR0_CLIENTPD, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0); + pm_runtime_put_sync(smmu->dev); + + pm_runtime_disable(smmu->dev); + return 0; } -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v7 4/6] iommu/arm-smmu: Add the device_link between masters and smmu
From: Sricharan R Finally add the device link between the master device and smmu, so that the smmu gets runtime enabled/disabled only when the master needs it. This is done from add_device callback which gets called once when the master is added to the smmu. Signed-off-by: Sricharan R Signed-off-by: Vivek Gautam --- drivers/iommu/arm-smmu.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index c024f69c1682..c7e924d553bd 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -215,6 +215,9 @@ struct arm_smmu_device { /* IOMMU core code handle */ struct iommu_device iommu; + + /* runtime PM link to master */ + struct device_link *link; }; enum arm_smmu_context_fmt { @@ -1425,6 +1428,17 @@ static int arm_smmu_add_device(struct device *dev) pm_runtime_put_sync(smmu->dev); + /* +* Establish the link between smmu and master, so that the +* smmu gets runtime enabled/disabled as per the master's +* needs. +*/ + smmu->link = device_link_add(dev, smmu->dev, DL_FLAG_PM_RUNTIME); + if (!smmu->link) + dev_warn(smmu->dev, +"Unable to create device link between %s and %s\n", +dev_name(smmu->dev), dev_name(dev)); + return 0; out_rpm_put: @@ -1449,6 +1463,8 @@ static void arm_smmu_remove_device(struct device *dev) cfg = fwspec->iommu_priv; smmu = cfg->smmu; + device_link_del(smmu->link); + ret = pm_runtime_get_sync(smmu->dev); if (ret) return; -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v7 2/6] iommu/arm-smmu: Add pm_runtime/sleep ops
From: Sricharan R The smmu needs to be functional only when the respective master's using it are active. The device_link feature helps to track such functional dependencies, so that the iommu gets powered when the master device enables itself using pm_runtime. So by adapting the smmu driver for runtime pm, above said dependency can be addressed. This patch adds the pm runtime/sleep callbacks to the driver and also the functions to parse the smmu clocks from DT and enable them in resume/suspend. Signed-off-by: Sricharan R Signed-off-by: Archit Taneja [vivek: Clock rework to request bulk of clocks] Signed-off-by: Vivek Gautam --- drivers/iommu/arm-smmu.c | 56 ++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 69e7c60792a8..9e2f917e16c2 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -205,6 +206,8 @@ struct arm_smmu_device { u32 num_global_irqs; u32 num_context_irqs; unsigned int*irqs; + struct clk_bulk_data*clocks; + int num_clks; u32 cavium_id_base; /* Specific to Cavium */ @@ -1897,10 +1900,12 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) struct arm_smmu_match_data { enum arm_smmu_arch_version version; enum arm_smmu_implementation model; + const char * const *clks; + int num_clks; }; #define ARM_SMMU_MATCH_DATA(name, ver, imp)\ -static struct arm_smmu_match_data name = { .version = ver, .model = imp } +static const struct arm_smmu_match_data name = { .version = ver, .model = imp } ARM_SMMU_MATCH_DATA(smmu_generic_v1, ARM_SMMU_V1, GENERIC_SMMU); ARM_SMMU_MATCH_DATA(smmu_generic_v2, ARM_SMMU_V2, GENERIC_SMMU); @@ -2001,6 +2006,7 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev, data = of_device_get_match_data(dev); smmu->version = data->version; smmu->model = data->model; + smmu->num_clks = data->num_clks; parse_driver_options(smmu); @@ -2039,6 +2045,28 @@ static void arm_smmu_bus_init(void) #endif } +static int arm_smmu_init_clks(struct arm_smmu_device *smmu) +{ + int i; + int num = smmu->num_clks; + const struct arm_smmu_match_data *data; + + if (num < 1) + return 0; + + smmu->clocks = devm_kcalloc(smmu->dev, num, + sizeof(*smmu->clocks), GFP_KERNEL); + if (!smmu->clocks) + return -ENOMEM; + + data = of_device_get_match_data(smmu->dev); + + for (i = 0; i < num; i++) + smmu->clocks[i].id = data->clks[i]; + + return devm_clk_bulk_get(smmu->dev, num, smmu->clocks); +} + static int arm_smmu_device_probe(struct platform_device *pdev) { struct resource *res; @@ -2099,6 +2127,10 @@ static int arm_smmu_device_probe(struct platform_device *pdev) smmu->irqs[i] = irq; } + err = arm_smmu_init_clks(smmu); + if (err) + return err; + err = arm_smmu_device_cfg_probe(smmu); if (err) return err; @@ -2197,7 +2229,27 @@ static int __maybe_unused arm_smmu_pm_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(arm_smmu_pm_ops, NULL, arm_smmu_pm_resume); +static int __maybe_unused arm_smmu_runtime_resume(struct device *dev) +{ + struct arm_smmu_device *smmu = dev_get_drvdata(dev); + + return clk_bulk_prepare_enable(smmu->num_clks, smmu->clocks); +} + +static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev) +{ + struct arm_smmu_device *smmu = dev_get_drvdata(dev); + + clk_bulk_disable_unprepare(smmu->num_clks, smmu->clocks); + + return 0; +} + +static const struct dev_pm_ops arm_smmu_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(NULL, arm_smmu_pm_resume) + SET_RUNTIME_PM_OPS(arm_smmu_runtime_suspend, + arm_smmu_runtime_resume, NULL) +}; static struct platform_driver arm_smmu_driver = { .driver = { -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v7 1/6] base: power: runtime: Export pm_runtime_get/put_suppliers
The device link allows the pm framework to tie the supplier and consumer. So, whenever the consumer is powered-on the supplier is powered-on first. There are however cases in which the consumer wants to power-on the supplier, but not itself. E.g., A Graphics or multimedia driver wants to power-on the SMMU to unmap a buffer and finish the TLB operations without powering on itself. Some of these unmap requests are coming from the user space when the controller itself is not powered-up, and it can be huge penalty in terms of power and latency to power-up the graphics/mm controllers. There can be an argument that the supplier should handle this case on its own and there should not be a need for the consumer to power-on the supplier. But as discussed on the thread [1] about ARM-SMMU runtime pm, we don't want to introduce runtime pm calls in atomic path in arm_smmu_unmap. [1] https://patchwork.kernel.org/patch/9827825/ Signed-off-by: Vivek Gautam Acked-by: Rafael J. Wysocki --- drivers/base/power/runtime.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 8bef3cb2424d..5b8226c8af19 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -1579,6 +1579,7 @@ void pm_runtime_get_suppliers(struct device *dev) device_links_read_unlock(idx); } +EXPORT_SYMBOL_GPL(pm_runtime_get_suppliers); /** * pm_runtime_put_suppliers - Drop references to supplier devices. @@ -1597,6 +1598,7 @@ void pm_runtime_put_suppliers(struct device *dev) device_links_read_unlock(idx); } +EXPORT_SYMBOL_GPL(pm_runtime_put_suppliers); void pm_runtime_new_link(struct device *dev) { -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v7 0/6] iommu/arm-smmu: Add runtime pm/sleep support
This series provides the support for turning on the arm-smmu's clocks/power domains using runtime pm. This is done using the recently introduced device links patches, which lets the smmu's runtime to follow the master's runtime pm, so the smmu remains powered only when the masters use it. It also adds support for Qcom's arm-smmu-v2 variant that has different clocks and power requirements. Took some reference from the exynos runtime patches [1]. After much discussion [3] over the use of pm_runtime_get/put() in .unmap op path for the arm-smmu, and after disussing over more than a couple of approaches to address this, we are putting forward the changes *without* using pm_runtime APIs in 'unmap'. Rather, letting the client device take the control of powering on/off the connected iommu through pm_runtime_get(put)_suppliers() APIs for the scnerios when the iommu power can't be directly controlled by clients through device links. Rafael acked the change to export the suppliers APIs. Previous version of this patch series is @ [5]. [v7] * Addressed review comments given by Robin Murphy - -- Added device_link_del() in .remove_device path. -- Error path cleanup in arm_smmu_add_device(). -- Added pm_runtime_get/put_sync() in .remove path, and replaced pm_runtime_force_suspend() with pm_runtime_disable(). -- clk_names cleanup in arm_smmu_init_clks() * Added 'Reviewed-by' given by Rob H. [V6] * Added Ack given by Rafael to first patch in the series. * Addressed Rob Herring's comment for adding soc specific compatible string as well besides 'qcom,smmu-v2'. [V5] * Dropped runtime pm calls from "arm_smmu_unmap" op as discussed over the list [3] for the last patch series. * Added a patch to export pm_runtime_get/put_suppliers() APIs to the series as agreed with Rafael [4]. * Added the related patch for msm drm iommu layer to use pm_runtime_get/put_suppliers() APIs in msm_mmu_funcs. * Dropped arm-mmu500 clock patch since that would break existing platforms. * Changed compatible 'qcom,msm8996-smmu-v2' to 'qcom,smmu-v2' to reflect the IP version rather than the platform on which it is used. The same IP is used across multiple platforms including msm8996, and sdm845 etc. * Using clock bulk APIs to handle the clocks available to the IP as suggested by Stephen Boyd. * The first patch in v4 version of the patch-series: ("iommu/arm-smmu: Fix the error path in arm_smmu_add_device") has already made it to mainline. [V4] * Reworked the clock handling part. We now take clock names as data in the driver for supported compatible versions, and loop over them to get, enable, and disable the clocks. * Using qcom,msm8996 based compatibles for bindings instead of a generic qcom compatible. * Refactor MMU500 patch to just add the necessary clock names data and corresponding bindings. * Added the pm_runtime_get/put() calls in .unmap iommu op (fix added by Stanimir on top of previous patch version. * Added a patch to fix error path in arm_smmu_add_device() * Removed patch 3/5 of V3 patch series that added qcom,smmu-v2 bindings. [V3] * Reworked the patches to keep the clocks init/enabling function separately for each compatible. * Added clocks bindings for MMU40x/500. * Added a new compatible for qcom,smmu-v2 implementation and the clock bindings for the same. * Rebased on top of 4.11-rc1 [V2] * Split the patches little differently. * Addressed comments. * Removed the patch #4 [2] from previous post for arm-smmu context save restore. Planning to post this separately after reworking/addressing Robin's feedback. * Reversed the sequence to disable clocks than enabling. This was required for those cases where the clocks are populated in a dependent order from DT. [1] https://lkml.org/lkml/2016/10/20/70 [2] https://patchwork.kernel.org/patch/9389717/ [3] https://patchwork.kernel.org/patch/9827825/ [4] https://patchwork.kernel.org/patch/10102445/ [5] https://lkml.org/lkml/2018/1/19/217 Sricharan R (3): iommu/arm-smmu: Add pm_runtime/sleep ops iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device iommu/arm-smmu: Add the device_link between masters and smmu Vivek Gautam (3): base: power: runtime: Export pm_runtime_get/put_suppliers iommu/arm-smmu: Add support for qcom,smmu-v2 variant drm/msm: iommu: Replace runtime calls with runtime suppliers .../devicetree/bindings/iommu/arm,smmu.txt | 43 +++ drivers/base/power/runtime.c | 2 + drivers/gpu/drm/msm/msm_iommu.c| 16 +-- drivers/iommu/arm-smmu.c | 127 - 4 files changed, 174 insertions(+), 14 deletions(-) -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation