[Freedreno] [PATCH v3 2/3] arm64: dts: qcom: sc7180: Add gpu cooling support
Add cooling-cells property and the cooling maps for the gpu tzones to support GPU cooling. Signed-off-by: Akhil P Oommen --- arch/arm64/boot/dts/qcom/sc7180.dtsi | 30 +++--- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi index d46b383..a7ea029 100644 --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -2,7 +2,7 @@ /* * SC7180 SoC device tree source * - * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-20, The Linux Foundation. All rights reserved. */ #include @@ -1886,6 +1886,8 @@ operating-points-v2 = <&gpu_opp_table>; qcom,gmu = <&gmu>; + #cooling-cells = <2>; + interconnects = <&gem_noc MASTER_GFX3D &mc_virt SLAVE_EBI1>; interconnect-names = "gfx-mem"; @@ -3825,16 +3827,16 @@ }; gpuss0-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <100>; polling-delay = <0>; thermal-sensors = <&tsens0 13>; trips { gpuss0_alert0: trip-point0 { - temperature = <9>; + temperature = <95000>; hysteresis = <2000>; - type = "hot"; + type = "passive"; }; gpuss0_crit: gpuss0_crit { @@ -3843,19 +3845,26 @@ type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss0_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss1-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <100>; polling-delay = <0>; thermal-sensors = <&tsens0 14>; trips { gpuss1_alert0: trip-point0 { - temperature = <9>; + temperature = <95000>; hysteresis = <2000>; - type = "hot"; + type = "passive"; }; gpuss1_crit: gpuss1_crit { @@ -3864,6 +3873,13 @@ type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss0_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; aoss1-thermal { -- 2.7.4 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v3 1/3] drm/msm: Add support for GPU cooling
Register GPU as a devfreq cooling device so that it can be passively cooled by the thermal framework. Signed-off-by: Akhil P Oommen --- Changes in v3: 1. Minor fix in binding documentation (RobH) Changes in v2: 1. Update the dt bindings documentation drivers/gpu/drm/msm/msm_gpu.c | 12 drivers/gpu/drm/msm/msm_gpu.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 55d1648..9f9db46 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -107,9 +108,18 @@ static void msm_devfreq_init(struct msm_gpu *gpu) if (IS_ERR(gpu->devfreq.devfreq)) { DRM_DEV_ERROR(&gpu->pdev->dev, "Couldn't initialize GPU devfreq\n"); gpu->devfreq.devfreq = NULL; + return; } devfreq_suspend_device(gpu->devfreq.devfreq); + + gpu->cooling = of_devfreq_cooling_register(gpu->pdev->dev.of_node, + gpu->devfreq.devfreq); + if (IS_ERR(gpu->cooling)) { + DRM_DEV_ERROR(&gpu->pdev->dev, + "Couldn't register GPU cooling device\n"); + gpu->cooling = NULL; + } } static int enable_pwrrail(struct msm_gpu *gpu) @@ -1005,4 +1015,6 @@ void msm_gpu_cleanup(struct msm_gpu *gpu) gpu->aspace->mmu->funcs->detach(gpu->aspace->mmu); msm_gem_address_space_put(gpu->aspace); } + + devfreq_cooling_unregister(gpu->cooling); } diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 6c9e1fd..9a8f20d 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -147,6 +147,8 @@ struct msm_gpu { struct msm_gpu_state *crashstate; /* True if the hardware supports expanded apriv (a650 and newer) */ bool hw_apriv; + + struct thermal_cooling_device *cooling; }; static inline struct msm_gpu *dev_to_gpu(struct device *dev) -- 2.7.4 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v3 3/3] dt-bindings: drm/msm/gpu: Add cooling device support
Add cooling device support to gpu. A cooling device is bound to a thermal zone to allow thermal mitigation. Signed-off-by: Akhil P Oommen --- Documentation/devicetree/bindings/display/msm/gpu.txt | 7 +++ 1 file changed, 7 insertions(+) diff --git a/Documentation/devicetree/bindings/display/msm/gpu.txt b/Documentation/devicetree/bindings/display/msm/gpu.txt index 1af0ff1..090dcb3 100644 --- a/Documentation/devicetree/bindings/display/msm/gpu.txt +++ b/Documentation/devicetree/bindings/display/msm/gpu.txt @@ -39,6 +39,10 @@ Required properties: a4xx Snapdragon SoCs. See Documentation/devicetree/bindings/sram/qcom,ocmem.yaml. +Optional properties: +- #cooling-cells: The value must be 2. For details, please refer + Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml. + Example 3xx/4xx: / { @@ -61,6 +65,7 @@ Example 3xx/4xx: power-domains = <&mmcc OXILICX_GDSC>; operating-points-v2 = <&gpu_opp_table>; iommus = <&gpu_iommu 0>; + #cooling-cells = <2>; }; gpu_sram: ocmem@fdd0 { @@ -98,6 +103,8 @@ Example a6xx (with GMU): reg = <0x500 0x4>, <0x509e000 0x10>; reg-names = "kgsl_3d0_reg_memory", "cx_mem"; + #cooling-cells = <2>; + /* * Look ma, no clocks! The GPU clocks and power are * controlled entirely by the GMU -- 2.7.4 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v2 1/2] drm/msm: Implement shutdown callback for adreno
Implement the shutdown callback for adreno gpu platform device to safely shutdown it before a system reboot. This helps to avoid futher transactions from gpu after the smmu is moved to bypass mode. Signed-off-by: Akhil P Oommen --- drivers/gpu/drm/msm/adreno/adreno_device.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 58e03b2..87c8b03 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -475,6 +475,11 @@ static int adreno_remove(struct platform_device *pdev) return 0; } +static void adreno_shutdown(struct platform_device *pdev) +{ + pm_runtime_force_suspend(&pdev->dev); +} + static const struct of_device_id dt_match[] = { { .compatible = "qcom,adreno" }, { .compatible = "qcom,adreno-3xx" }, @@ -509,6 +514,7 @@ static const struct dev_pm_ops adreno_pm_ops = { static struct platform_driver adreno_driver = { .probe = adreno_probe, .remove = adreno_remove, + .shutdown = adreno_shutdown, .driver = { .name = "adreno", .of_match_table = dt_match, -- 2.7.4 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v2 2/2] drm/msm: Fix duplicate gpu node in icc summary
The dev_pm_opp_of_add_table() api initializes the icc nodes for gpu indirectly. So we can avoid using of_icc_get() api in the common probe path. To improve this, move of_icc_get() to target specific code where it is required. This patch helps to fix duplicate gpu node listed in the interconnect summary from the debugfs. Signed-off-by: Akhil P Oommen --- Changes in v2: 1. Minor updates (Jordan) drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 21 +++-- drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 20 ++-- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 32 +--- 3 files changed, 38 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index f29c77d..93da668 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c @@ -519,6 +519,8 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev) struct msm_gpu *gpu; struct msm_drm_private *priv = dev->dev_private; struct platform_device *pdev = priv->gpu_pdev; + struct icc_path *ocmem_icc_path; + struct icc_path *icc_path; int ret; if (!pdev) { @@ -566,13 +568,28 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev) goto fail; } + icc_path = devm_of_icc_get(&pdev->dev, "gfx-mem"); + ret = IS_ERR(icc_path); + if (ret) + goto fail; + + ocmem_icc_path = devm_of_icc_get(&pdev->dev, "ocmem"); + ret = IS_ERR(ocmem_icc_path); + if (ret) { + /* allow -ENODATA, ocmem icc is optional */ + if (ret != -ENODATA) + goto fail; + ocmem_icc_path = NULL; + } + + /* * Set the ICC path to maximum speed for now by multiplying the fastest * frequency by the bus width (8). We'll want to scale this later on to * improve battery life. */ - icc_set_bw(gpu->icc_path, 0, Bps_to_icc(gpu->fast_rate) * 8); - icc_set_bw(gpu->ocmem_icc_path, 0, Bps_to_icc(gpu->fast_rate) * 8); + icc_set_bw(icc_path, 0, Bps_to_icc(gpu->fast_rate) * 8); + icc_set_bw(ocmem_icc_path, 0, Bps_to_icc(gpu->fast_rate) * 8); return gpu; diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c index 2b93b33..c0be3a0 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c @@ -648,6 +648,8 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev) struct msm_gpu *gpu; struct msm_drm_private *priv = dev->dev_private; struct platform_device *pdev = priv->gpu_pdev; + struct icc_path *ocmem_icc_path; + struct icc_path *icc_path; int ret; if (!pdev) { @@ -694,13 +696,27 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev) goto fail; } + icc_path = devm_of_icc_get(&pdev->dev, "gfx-mem"); + ret = IS_ERR(icc_path); + if (ret) + goto fail; + + ocmem_icc_path = devm_of_icc_get(&pdev->dev, "ocmem"); + ret = IS_ERR(ocmem_icc_path); + if (ret) { + /* allow -ENODATA, ocmem icc is optional */ + if (ret != -ENODATA) + goto fail; + ocmem_icc_path = NULL; + } + /* * Set the ICC path to maximum speed for now by multiplying the fastest * frequency by the bus width (8). We'll want to scale this later on to * improve battery life. */ - icc_set_bw(gpu->icc_path, 0, Bps_to_icc(gpu->fast_rate) * 8); - icc_set_bw(gpu->ocmem_icc_path, 0, Bps_to_icc(gpu->fast_rate) * 8); + icc_set_bw(icc_path, 0, Bps_to_icc(gpu->fast_rate) * 8); + icc_set_bw(ocmem_icc_path, 0, Bps_to_icc(gpu->fast_rate) * 8); return gpu; diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index fd8f491..ddbd863 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -899,7 +899,6 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, struct adreno_platform_config *config = dev->platform_data; struct msm_gpu_config adreno_gpu_config = { 0 }; struct msm_gpu *gpu = &adreno_gpu->base; - int ret; adreno_gpu->funcs = funcs; adreno_gpu->info = adreno_info(config->rev); @@ -918,37 +917,8 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, pm_runtime_use_autosuspend(dev); pm_runtime_enable(dev); - ret = msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base, + return msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base,
Re: [Freedreno] [v3, 2/3] arm64: dts: qcom: sc7180: Add gpu cooling support
On 10/29/2020 6:09 AM, m...@chromium.org wrote: Hi Akhil, On Wed, Oct 28, 2020 at 07:09:53PM +0530, Akhil P Oommen wrote: Add cooling-cells property and the cooling maps for the gpu tzones to support GPU cooling. Signed-off-by: Akhil P Oommen --- arch/arm64/boot/dts/qcom/sc7180.dtsi | 30 +++--- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi index d46b383..a7ea029 100644 --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -2,7 +2,7 @@ /* * SC7180 SoC device tree source * - * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-20, The Linux Foundation. All rights reserved. */ #include @@ -1886,6 +1886,8 @@ operating-points-v2 = <&gpu_opp_table>; qcom,gmu = <&gmu>; + #cooling-cells = <2>; + interconnects = <&gem_noc MASTER_GFX3D &mc_virt SLAVE_EBI1>; interconnect-names = "gfx-mem"; @@ -3825,16 +3827,16 @@ }; gpuss0-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <100>; polling-delay = <0>; thermal-sensors = <&tsens0 13>; trips { gpuss0_alert0: trip-point0 { - temperature = <9>; + temperature = <95000>; hysteresis = <2000>; - type = "hot"; + type = "passive"; }; gpuss0_crit: gpuss0_crit { @@ -3843,19 +3845,26 @@ type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss0_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss1-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <100>; polling-delay = <0>; thermal-sensors = <&tsens0 14>; trips { gpuss1_alert0: trip-point0 { - temperature = <9>; + temperature = <95000>; hysteresis = <2000>; - type = "hot"; + type = "passive"; }; gpuss1_crit: gpuss1_crit { @@ -3864,6 +3873,13 @@ type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss0_alert0>; Copy & paste error, this should be 'gpuss1_alert0'. aah! you are correct. --Akhil + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; aoss1-thermal { Other than the C&P error: Reviewed-by: Matthias Kaehlcke ___ dri-devel mailing list dri-de...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v4 1/3] drm/msm: Add support for GPU cooling
Register GPU as a devfreq cooling device so that it can be passively cooled by the thermal framework. Signed-off-by: Akhil P Oommen Reviewed-by: Matthias Kaehlcke --- Changes in v4: 1. Fix gpu cooling map. 2. Add mka's Reviewed-by tag. Changes in v3: 1. Minor fix in binding documentation (RobH) Changes in v2: 1. Update the dt bindings documentation drivers/gpu/drm/msm/msm_gpu.c | 12 drivers/gpu/drm/msm/msm_gpu.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 55d1648..9f9db46 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -107,9 +108,18 @@ static void msm_devfreq_init(struct msm_gpu *gpu) if (IS_ERR(gpu->devfreq.devfreq)) { DRM_DEV_ERROR(&gpu->pdev->dev, "Couldn't initialize GPU devfreq\n"); gpu->devfreq.devfreq = NULL; + return; } devfreq_suspend_device(gpu->devfreq.devfreq); + + gpu->cooling = of_devfreq_cooling_register(gpu->pdev->dev.of_node, + gpu->devfreq.devfreq); + if (IS_ERR(gpu->cooling)) { + DRM_DEV_ERROR(&gpu->pdev->dev, + "Couldn't register GPU cooling device\n"); + gpu->cooling = NULL; + } } static int enable_pwrrail(struct msm_gpu *gpu) @@ -1005,4 +1015,6 @@ void msm_gpu_cleanup(struct msm_gpu *gpu) gpu->aspace->mmu->funcs->detach(gpu->aspace->mmu); msm_gem_address_space_put(gpu->aspace); } + + devfreq_cooling_unregister(gpu->cooling); } diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 6c9e1fd..9a8f20d 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -147,6 +147,8 @@ struct msm_gpu { struct msm_gpu_state *crashstate; /* True if the hardware supports expanded apriv (a650 and newer) */ bool hw_apriv; + + struct thermal_cooling_device *cooling; }; static inline struct msm_gpu *dev_to_gpu(struct device *dev) -- 2.7.4 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v4 2/3] arm64: dts: qcom: sc7180: Add gpu cooling support
Add cooling-cells property and the cooling maps for the gpu tzones to support GPU cooling. Signed-off-by: Akhil P Oommen Reviewed-by: Matthias Kaehlcke --- arch/arm64/boot/dts/qcom/sc7180.dtsi | 30 +++--- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi index d46b383..8e2000c 100644 --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -2,7 +2,7 @@ /* * SC7180 SoC device tree source * - * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-20, The Linux Foundation. All rights reserved. */ #include @@ -1886,6 +1886,8 @@ operating-points-v2 = <&gpu_opp_table>; qcom,gmu = <&gmu>; + #cooling-cells = <2>; + interconnects = <&gem_noc MASTER_GFX3D &mc_virt SLAVE_EBI1>; interconnect-names = "gfx-mem"; @@ -3825,16 +3827,16 @@ }; gpuss0-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <100>; polling-delay = <0>; thermal-sensors = <&tsens0 13>; trips { gpuss0_alert0: trip-point0 { - temperature = <9>; + temperature = <95000>; hysteresis = <2000>; - type = "hot"; + type = "passive"; }; gpuss0_crit: gpuss0_crit { @@ -3843,19 +3845,26 @@ type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss0_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss1-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <100>; polling-delay = <0>; thermal-sensors = <&tsens0 14>; trips { gpuss1_alert0: trip-point0 { - temperature = <9>; + temperature = <95000>; hysteresis = <2000>; - type = "hot"; + type = "passive"; }; gpuss1_crit: gpuss1_crit { @@ -3864,6 +3873,13 @@ type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss1_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; aoss1-thermal { -- 2.7.4 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v4 3/3] dt-bindings: drm/msm/gpu: Add cooling device support
Add cooling device support to gpu. A cooling device is bound to a thermal zone to allow thermal mitigation. Signed-off-by: Akhil P Oommen --- Documentation/devicetree/bindings/display/msm/gpu.txt | 7 +++ 1 file changed, 7 insertions(+) diff --git a/Documentation/devicetree/bindings/display/msm/gpu.txt b/Documentation/devicetree/bindings/display/msm/gpu.txt index 1af0ff1..090dcb3 100644 --- a/Documentation/devicetree/bindings/display/msm/gpu.txt +++ b/Documentation/devicetree/bindings/display/msm/gpu.txt @@ -39,6 +39,10 @@ Required properties: a4xx Snapdragon SoCs. See Documentation/devicetree/bindings/sram/qcom,ocmem.yaml. +Optional properties: +- #cooling-cells: The value must be 2. For details, please refer + Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml. + Example 3xx/4xx: / { @@ -61,6 +65,7 @@ Example 3xx/4xx: power-domains = <&mmcc OXILICX_GDSC>; operating-points-v2 = <&gpu_opp_table>; iommus = <&gpu_iommu 0>; + #cooling-cells = <2>; }; gpu_sram: ocmem@fdd0 { @@ -98,6 +103,8 @@ Example a6xx (with GMU): reg = <0x500 0x4>, <0x509e000 0x10>; reg-names = "kgsl_3d0_reg_memory", "cx_mem"; + #cooling-cells = <2>; + /* * Look ma, no clocks! The GPU clocks and power are * controlled entirely by the GMU -- 2.7.4 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [v4,1/3] drm/msm: Add support for GPU cooling
On 10/30/2020 2:18 AM, m...@chromium.org wrote: On Thu, Oct 29, 2020 at 01:37:19PM +0530, Akhil P Oommen wrote: Register GPU as a devfreq cooling device so that it can be passively cooled by the thermal framework. Signed-off-by: Akhil P Oommen Reviewed-by: Matthias Kaehlcke Wait, I did not post a 'Reviewed-by' tag for this patch! I think the patch should be ok, but I'm still not super happy about the resource management involving devfreq in general (see discussion on https://patchwork.freedesktop.org/patch/394291/?series=82476&rev=1). It's not really something introduced by this patch, but if it ever gets fixed releasing the cooling device at the end of msm_gpu_cleanup() after everything else might cause trouble. In summary, I'm supportive of landing this patch, but reluctant to 'sign it off' because of the above. In any case: Tested-by: Matthias Kaehlcke Sorry, Matthias. My mistake. You shared the reviewed tag for the dt-bindings update. Will fix this ASAP. Thanks for verifying this. -Akhil. ___ dri-devel mailing list dri-de...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v5 3/3] dt-bindings: drm/msm/gpu: Add cooling device support
Add cooling device support to gpu. A cooling device is bound to a thermal zone to allow thermal mitigation. Signed-off-by: Akhil P Oommen Reviewed-by: Matthias Kaehlcke --- Documentation/devicetree/bindings/display/msm/gpu.txt | 7 +++ 1 file changed, 7 insertions(+) diff --git a/Documentation/devicetree/bindings/display/msm/gpu.txt b/Documentation/devicetree/bindings/display/msm/gpu.txt index 1af0ff1..090dcb3 100644 --- a/Documentation/devicetree/bindings/display/msm/gpu.txt +++ b/Documentation/devicetree/bindings/display/msm/gpu.txt @@ -39,6 +39,10 @@ Required properties: a4xx Snapdragon SoCs. See Documentation/devicetree/bindings/sram/qcom,ocmem.yaml. +Optional properties: +- #cooling-cells: The value must be 2. For details, please refer + Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml. + Example 3xx/4xx: / { @@ -61,6 +65,7 @@ Example 3xx/4xx: power-domains = <&mmcc OXILICX_GDSC>; operating-points-v2 = <&gpu_opp_table>; iommus = <&gpu_iommu 0>; + #cooling-cells = <2>; }; gpu_sram: ocmem@fdd0 { @@ -98,6 +103,8 @@ Example a6xx (with GMU): reg = <0x500 0x4>, <0x509e000 0x10>; reg-names = "kgsl_3d0_reg_memory", "cx_mem"; + #cooling-cells = <2>; + /* * Look ma, no clocks! The GPU clocks and power are * controlled entirely by the GMU -- 2.7.4 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v5 2/3] arm64: dts: qcom: sc7180: Add gpu cooling support
Add cooling-cells property and the cooling maps for the gpu tzones to support GPU cooling. Signed-off-by: Akhil P Oommen Reviewed-by: Matthias Kaehlcke --- arch/arm64/boot/dts/qcom/sc7180.dtsi | 30 +++--- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi index d46b383..8e2000c 100644 --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -2,7 +2,7 @@ /* * SC7180 SoC device tree source * - * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-20, The Linux Foundation. All rights reserved. */ #include @@ -1886,6 +1886,8 @@ operating-points-v2 = <&gpu_opp_table>; qcom,gmu = <&gmu>; + #cooling-cells = <2>; + interconnects = <&gem_noc MASTER_GFX3D &mc_virt SLAVE_EBI1>; interconnect-names = "gfx-mem"; @@ -3825,16 +3827,16 @@ }; gpuss0-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <100>; polling-delay = <0>; thermal-sensors = <&tsens0 13>; trips { gpuss0_alert0: trip-point0 { - temperature = <9>; + temperature = <95000>; hysteresis = <2000>; - type = "hot"; + type = "passive"; }; gpuss0_crit: gpuss0_crit { @@ -3843,19 +3845,26 @@ type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss0_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss1-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <100>; polling-delay = <0>; thermal-sensors = <&tsens0 14>; trips { gpuss1_alert0: trip-point0 { - temperature = <9>; + temperature = <95000>; hysteresis = <2000>; - type = "hot"; + type = "passive"; }; gpuss1_crit: gpuss1_crit { @@ -3864,6 +3873,13 @@ type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss1_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; aoss1-thermal { -- 2.7.4 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v5 1/3] drm/msm: Add support for GPU cooling
Register GPU as a devfreq cooling device so that it can be passively cooled by the thermal framework. Signed-off-by: Akhil P Oommen Tested-by: Matthias Kaehlcke --- Changes in v5: 1. Update Reviewed-by/Tested-by tags Changes in v4: 1. Fix gpu cooling map. 2. Add mka's Reviewed-by tag. Changes in v3: 1. Minor fix in binding documentation (RobH) Changes in v2: 1. Update the dt bindings documentation drivers/gpu/drm/msm/msm_gpu.c | 12 drivers/gpu/drm/msm/msm_gpu.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 55d1648..9f9db46 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -107,9 +108,18 @@ static void msm_devfreq_init(struct msm_gpu *gpu) if (IS_ERR(gpu->devfreq.devfreq)) { DRM_DEV_ERROR(&gpu->pdev->dev, "Couldn't initialize GPU devfreq\n"); gpu->devfreq.devfreq = NULL; + return; } devfreq_suspend_device(gpu->devfreq.devfreq); + + gpu->cooling = of_devfreq_cooling_register(gpu->pdev->dev.of_node, + gpu->devfreq.devfreq); + if (IS_ERR(gpu->cooling)) { + DRM_DEV_ERROR(&gpu->pdev->dev, + "Couldn't register GPU cooling device\n"); + gpu->cooling = NULL; + } } static int enable_pwrrail(struct msm_gpu *gpu) @@ -1005,4 +1015,6 @@ void msm_gpu_cleanup(struct msm_gpu *gpu) gpu->aspace->mmu->funcs->detach(gpu->aspace->mmu); msm_gem_address_space_put(gpu->aspace); } + + devfreq_cooling_unregister(gpu->cooling); } diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 6c9e1fd..9a8f20d 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -147,6 +147,8 @@ struct msm_gpu { struct msm_gpu_state *crashstate; /* True if the hardware supports expanded apriv (a650 and newer) */ bool hw_apriv; + + struct thermal_cooling_device *cooling; }; static inline struct msm_gpu *dev_to_gpu(struct device *dev) -- 2.7.4 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH v5 3/3] dt-bindings: drm/msm/gpu: Add cooling device support
On 11/5/2020 2:28 AM, Rob Clark wrote: On Wed, Nov 4, 2020 at 12:03 PM Rob Herring wrote: On Fri, 30 Oct 2020 16:17:12 +0530, Akhil P Oommen wrote: Add cooling device support to gpu. A cooling device is bound to a thermal zone to allow thermal mitigation. Signed-off-by: Akhil P Oommen Reviewed-by: Matthias Kaehlcke --- Documentation/devicetree/bindings/display/msm/gpu.txt | 7 +++ 1 file changed, 7 insertions(+) Please add Acked-by/Reviewed-by tags when posting new versions. However, there's no need to repost patches *only* to add the tags. The upstream maintainer will do that for acks received on the version they apply. If a tag was not added on purpose, please state why and what changed. Thanks Rob I've copied over your ack from the previous version.. but yes, it definitely makes my life easier when patch senders do this for me ;-) BR, -R Robh, you Acked v4 after I shared v5 patches!! -Akhil. ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH] drm/msm: adreno: Make speed-bin support generic
So far a530v2 gpu has support for detecting its supported opps based on a fuse value called speed-bin. This patch makes this support generic across gpu families. This is in preparation to extend speed-bin support to a6x family. Signed-off-by: Akhil P Oommen --- This patch is rebased on top of msm-next-staging branch in rob's tree. drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 34 -- drivers/gpu/drm/msm/adreno/adreno_device.c | 4 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.c| 71 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.h| 5 +++ 4 files changed, 80 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 8fa5c91..7d42321 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -1531,38 +1531,6 @@ static const struct adreno_gpu_funcs funcs = { .get_timestamp = a5xx_get_timestamp, }; -static void check_speed_bin(struct device *dev) -{ - struct nvmem_cell *cell; - u32 val; - - /* -* If the OPP table specifies a opp-supported-hw property then we have -* to set something with dev_pm_opp_set_supported_hw() or the table -* doesn't get populated so pick an arbitrary value that should -* ensure the default frequencies are selected but not conflict with any -* actual bins -*/ - val = 0x80; - - cell = nvmem_cell_get(dev, "speed_bin"); - - if (!IS_ERR(cell)) { - void *buf = nvmem_cell_read(cell, NULL); - - if (!IS_ERR(buf)) { - u8 bin = *((u8 *) buf); - - val = (1 << bin); - kfree(buf); - } - - nvmem_cell_put(cell); - } - - dev_pm_opp_set_supported_hw(dev, &val, 1); -} - struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; @@ -1588,8 +1556,6 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) a5xx_gpu->lm_leakage = 0x4E001A; - check_speed_bin(&pdev->dev); - ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 4); if (ret) { a5xx_destroy(&(a5xx_gpu->base.base)); diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 87c8b03..e0ff16c 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -18,6 +18,8 @@ bool snapshot_debugbus = false; MODULE_PARM_DESC(snapshot_debugbus, "Include debugbus sections in GPU devcoredump (if not fused off)"); module_param_named(snapshot_debugbus, snapshot_debugbus, bool, 0600); +const u32 a530v2_speedbins[] = {0, 1, 2, 3, 4, 5, 6, 7}; + static const struct adreno_info gpulist[] = { { .rev = ADRENO_REV(2, 0, 0, 0), @@ -163,6 +165,8 @@ static const struct adreno_info gpulist[] = { ADRENO_QUIRK_FAULT_DETECT_MASK, .init = a5xx_gpu_init, .zapfw = "a530_zap.mdt", + .speedbins = a530v2_speedbins, + .speedbins_count = ARRAY_SIZE(a530v2_speedbins), }, { .rev = ADRENO_REV(5, 4, 0, 2), .revn = 540, diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index f21561d..cdd0c11 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "adreno_gpu.h" #include "msm_gem.h" @@ -891,6 +892,69 @@ void adreno_gpu_ocmem_cleanup(struct adreno_ocmem *adreno_ocmem) adreno_ocmem->hdl); } +static int adreno_set_supported_hw(struct device *dev, + struct adreno_gpu *adreno_gpu) +{ + u8 speedbins_count = adreno_gpu->info->speedbins_count; + const u32 *speedbins = adreno_gpu->info->speedbins; + struct nvmem_cell *cell; + u32 bin, i; + u32 val = 0; + void *buf, *opp_table; + + cell = nvmem_cell_get(dev, "speed_bin"); + /* +* -ENOENT means that the platform doesn't support speedbin which is +* fine +*/ + if (PTR_ERR(cell) == -ENOENT) + return 0; + else if (IS_ERR(cell)) + return PTR_ERR(cell); + + /* A speedbin table is must if the platform supports speedbin */ + if (!speedbins) { + DRM_DEV_ERROR(dev, "speed-bin table is missing\n"); + return -ENOENT; + } + + buf = nvmem_cell_read(cell, NULL); + if (IS_ERR(buf)) { + nvmem_cell_put(cell); + return PTR_ERR(buf); + } + + bin = *((u32 *) buf); + + for (i = 0; i <
Re: [Freedreno] [PATCH] drm/msm: adreno: Make speed-bin support generic
On 11/12/2020 10:05 PM, Jordan Crouse wrote: On Thu, Nov 12, 2020 at 09:19:04PM +0530, Akhil P Oommen wrote: So far a530v2 gpu has support for detecting its supported opps based on a fuse value called speed-bin. This patch makes this support generic across gpu families. This is in preparation to extend speed-bin support to a6x family. Signed-off-by: Akhil P Oommen --- This patch is rebased on top of msm-next-staging branch in rob's tree. drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 34 -- drivers/gpu/drm/msm/adreno/adreno_device.c | 4 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.c| 71 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.h| 5 +++ 4 files changed, 80 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 8fa5c91..7d42321 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -1531,38 +1531,6 @@ static const struct adreno_gpu_funcs funcs = { .get_timestamp = a5xx_get_timestamp, }; -static void check_speed_bin(struct device *dev) -{ - struct nvmem_cell *cell; - u32 val; - - /* -* If the OPP table specifies a opp-supported-hw property then we have -* to set something with dev_pm_opp_set_supported_hw() or the table -* doesn't get populated so pick an arbitrary value that should -* ensure the default frequencies are selected but not conflict with any -* actual bins -*/ - val = 0x80; - - cell = nvmem_cell_get(dev, "speed_bin"); - - if (!IS_ERR(cell)) { - void *buf = nvmem_cell_read(cell, NULL); - - if (!IS_ERR(buf)) { - u8 bin = *((u8 *) buf); - - val = (1 << bin); - kfree(buf); - } - - nvmem_cell_put(cell); - } - - dev_pm_opp_set_supported_hw(dev, &val, 1); -} - struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; @@ -1588,8 +1556,6 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) a5xx_gpu->lm_leakage = 0x4E001A; - check_speed_bin(&pdev->dev); - ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 4); if (ret) { a5xx_destroy(&(a5xx_gpu->base.base)); diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 87c8b03..e0ff16c 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -18,6 +18,8 @@ bool snapshot_debugbus = false; MODULE_PARM_DESC(snapshot_debugbus, "Include debugbus sections in GPU devcoredump (if not fused off)"); module_param_named(snapshot_debugbus, snapshot_debugbus, bool, 0600); +const u32 a530v2_speedbins[] = {0, 1, 2, 3, 4, 5, 6, 7}; + static const struct adreno_info gpulist[] = { { .rev = ADRENO_REV(2, 0, 0, 0), @@ -163,6 +165,8 @@ static const struct adreno_info gpulist[] = { ADRENO_QUIRK_FAULT_DETECT_MASK, .init = a5xx_gpu_init, .zapfw = "a530_zap.mdt", + .speedbins = a530v2_speedbins, + .speedbins_count = ARRAY_SIZE(a530v2_speedbins), }, { .rev = ADRENO_REV(5, 4, 0, 2), .revn = 540, diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index f21561d..cdd0c11 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "adreno_gpu.h" #include "msm_gem.h" @@ -891,6 +892,69 @@ void adreno_gpu_ocmem_cleanup(struct adreno_ocmem *adreno_ocmem) adreno_ocmem->hdl); } +static int adreno_set_supported_hw(struct device *dev, + struct adreno_gpu *adreno_gpu) +{ + u8 speedbins_count = adreno_gpu->info->speedbins_count; + const u32 *speedbins = adreno_gpu->info->speedbins; We don't need to make this generic and put it in the table. Just call the function from the target specific code and pass the speedbin array and size from there. I didn't get you entirely. Do you mean we should avoid keeping speedbin array in the adreno_gpu->info table? -Akhil. + struct nvmem_cell *cell; + u32 bin, i; + u32 val = 0; + void *buf, *opp_table; + + cell = nvmem_cell_get(dev, "speed_bin"); + /* +* -ENOENT means that the platform doesn't support speedbin which is +* fine +*/ + if (PTR_ERR(cell) == -ENOENT) + return 0; + else if (IS_ERR(cell)) + return PTR_ERR(cell); + +
Re: [Freedreno] [PATCH] drm/msm: adreno: Make speed-bin support generic
On 11/12/2020 10:07 PM, Rob Clark wrote: On Thu, Nov 12, 2020 at 7:49 AM Akhil P Oommen wrote: So far a530v2 gpu has support for detecting its supported opps based on a fuse value called speed-bin. This patch makes this support generic across gpu families. This is in preparation to extend speed-bin support to a6x family. Signed-off-by: Akhil P Oommen --- This patch is rebased on top of msm-next-staging branch in rob's tree. drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 34 -- drivers/gpu/drm/msm/adreno/adreno_device.c | 4 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.c| 71 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.h| 5 +++ 4 files changed, 80 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 8fa5c91..7d42321 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -1531,38 +1531,6 @@ static const struct adreno_gpu_funcs funcs = { .get_timestamp = a5xx_get_timestamp, }; -static void check_speed_bin(struct device *dev) -{ - struct nvmem_cell *cell; - u32 val; - - /* -* If the OPP table specifies a opp-supported-hw property then we have -* to set something with dev_pm_opp_set_supported_hw() or the table -* doesn't get populated so pick an arbitrary value that should -* ensure the default frequencies are selected but not conflict with any -* actual bins -*/ - val = 0x80; - - cell = nvmem_cell_get(dev, "speed_bin"); - - if (!IS_ERR(cell)) { - void *buf = nvmem_cell_read(cell, NULL); - - if (!IS_ERR(buf)) { - u8 bin = *((u8 *) buf); - - val = (1 << bin); - kfree(buf); - } - - nvmem_cell_put(cell); - } - - dev_pm_opp_set_supported_hw(dev, &val, 1); -} - struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; @@ -1588,8 +1556,6 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) a5xx_gpu->lm_leakage = 0x4E001A; - check_speed_bin(&pdev->dev); - ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 4); if (ret) { a5xx_destroy(&(a5xx_gpu->base.base)); diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 87c8b03..e0ff16c 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -18,6 +18,8 @@ bool snapshot_debugbus = false; MODULE_PARM_DESC(snapshot_debugbus, "Include debugbus sections in GPU devcoredump (if not fused off)"); module_param_named(snapshot_debugbus, snapshot_debugbus, bool, 0600); +const u32 a530v2_speedbins[] = {0, 1, 2, 3, 4, 5, 6, 7}; + static const struct adreno_info gpulist[] = { { .rev = ADRENO_REV(2, 0, 0, 0), @@ -163,6 +165,8 @@ static const struct adreno_info gpulist[] = { ADRENO_QUIRK_FAULT_DETECT_MASK, .init = a5xx_gpu_init, .zapfw = "a530_zap.mdt", + .speedbins = a530v2_speedbins, + .speedbins_count = ARRAY_SIZE(a530v2_speedbins), }, { .rev = ADRENO_REV(5, 4, 0, 2), .revn = 540, diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index f21561d..cdd0c11 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "adreno_gpu.h" #include "msm_gem.h" @@ -891,6 +892,69 @@ void adreno_gpu_ocmem_cleanup(struct adreno_ocmem *adreno_ocmem) adreno_ocmem->hdl); } +static int adreno_set_supported_hw(struct device *dev, + struct adreno_gpu *adreno_gpu) +{ + u8 speedbins_count = adreno_gpu->info->speedbins_count; + const u32 *speedbins = adreno_gpu->info->speedbins; + struct nvmem_cell *cell; + u32 bin, i; + u32 val = 0; + void *buf, *opp_table; + + cell = nvmem_cell_get(dev, "speed_bin"); + /* +* -ENOENT means that the platform doesn't support speedbin which is +* fine +*/ + if (PTR_ERR(cell) == -ENOENT) + return 0; + else if (IS_ERR(cell)) + return PTR_ERR(cell); + + /* A speedbin table is must if the platform supports speedbin */ + if (!speedbins) { + DRM_DEV_ERROR(dev, "speed-bin table is missing\n"); + return -ENOENT; Hmm, this means that hw which supports speed-bin, but for which we haven't yet added a speedb
Re: [Freedreno] [PATCH] drm/msm: adreno: Make speed-bin support generic
On 11/16/2020 9:52 PM, Rob Clark wrote: On Mon, Nov 16, 2020 at 6:34 AM Akhil P Oommen wrote: On 11/12/2020 10:07 PM, Rob Clark wrote: On Thu, Nov 12, 2020 at 7:49 AM Akhil P Oommen wrote: So far a530v2 gpu has support for detecting its supported opps based on a fuse value called speed-bin. This patch makes this support generic across gpu families. This is in preparation to extend speed-bin support to a6x family. Signed-off-by: Akhil P Oommen --- This patch is rebased on top of msm-next-staging branch in rob's tree. drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 34 -- drivers/gpu/drm/msm/adreno/adreno_device.c | 4 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.c| 71 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.h| 5 +++ 4 files changed, 80 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 8fa5c91..7d42321 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -1531,38 +1531,6 @@ static const struct adreno_gpu_funcs funcs = { .get_timestamp = a5xx_get_timestamp, }; -static void check_speed_bin(struct device *dev) -{ - struct nvmem_cell *cell; - u32 val; - - /* -* If the OPP table specifies a opp-supported-hw property then we have -* to set something with dev_pm_opp_set_supported_hw() or the table -* doesn't get populated so pick an arbitrary value that should -* ensure the default frequencies are selected but not conflict with any -* actual bins -*/ - val = 0x80; - - cell = nvmem_cell_get(dev, "speed_bin"); - - if (!IS_ERR(cell)) { - void *buf = nvmem_cell_read(cell, NULL); - - if (!IS_ERR(buf)) { - u8 bin = *((u8 *) buf); - - val = (1 << bin); - kfree(buf); - } - - nvmem_cell_put(cell); - } - - dev_pm_opp_set_supported_hw(dev, &val, 1); -} - struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; @@ -1588,8 +1556,6 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) a5xx_gpu->lm_leakage = 0x4E001A; - check_speed_bin(&pdev->dev); - ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 4); if (ret) { a5xx_destroy(&(a5xx_gpu->base.base)); diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 87c8b03..e0ff16c 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -18,6 +18,8 @@ bool snapshot_debugbus = false; MODULE_PARM_DESC(snapshot_debugbus, "Include debugbus sections in GPU devcoredump (if not fused off)"); module_param_named(snapshot_debugbus, snapshot_debugbus, bool, 0600); +const u32 a530v2_speedbins[] = {0, 1, 2, 3, 4, 5, 6, 7}; + static const struct adreno_info gpulist[] = { { .rev = ADRENO_REV(2, 0, 0, 0), @@ -163,6 +165,8 @@ static const struct adreno_info gpulist[] = { ADRENO_QUIRK_FAULT_DETECT_MASK, .init = a5xx_gpu_init, .zapfw = "a530_zap.mdt", + .speedbins = a530v2_speedbins, + .speedbins_count = ARRAY_SIZE(a530v2_speedbins), }, { .rev = ADRENO_REV(5, 4, 0, 2), .revn = 540, diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index f21561d..cdd0c11 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "adreno_gpu.h" #include "msm_gem.h" @@ -891,6 +892,69 @@ void adreno_gpu_ocmem_cleanup(struct adreno_ocmem *adreno_ocmem) adreno_ocmem->hdl); } +static int adreno_set_supported_hw(struct device *dev, + struct adreno_gpu *adreno_gpu) +{ + u8 speedbins_count = adreno_gpu->info->speedbins_count; + const u32 *speedbins = adreno_gpu->info->speedbins; + struct nvmem_cell *cell; + u32 bin, i; + u32 val = 0; + void *buf, *opp_table; + + cell = nvmem_cell_get(dev, "speed_bin"); + /* +* -ENOENT means that the platform doesn't support speedbin which is +* fine +*/ + if (PTR_ERR(cell) == -ENOENT) + return 0; + else if (IS_ERR(cell)) + return PTR_ERR(cell); + + /* A speedbin table is must if the platform supports speedbin */ + if (!speedbins) { + DRM_DEV_ERROR(dev, "speed-bin table is missing\n"); +
[Freedreno] [PATCH v2 2/3] drm/msm: Add speed-bin support for a618 gpu
Extend speed-bin support to a618 gpu. Signed-off-by: Akhil P Oommen --- drivers/gpu/drm/msm/adreno/adreno_device.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index e0ff16c..21db7ae 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -18,6 +18,7 @@ bool snapshot_debugbus = false; MODULE_PARM_DESC(snapshot_debugbus, "Include debugbus sections in GPU devcoredump (if not fused off)"); module_param_named(snapshot_debugbus, snapshot_debugbus, bool, 0600); +const u32 a618_speedbins[] = {0, 169, 174}; const u32 a530v2_speedbins[] = {0, 1, 2, 3, 4, 5, 6, 7}; static const struct adreno_info gpulist[] = { @@ -196,6 +197,8 @@ static const struct adreno_info gpulist[] = { .gmem = SZ_512K, .inactive_period = DRM_MSM_INACTIVE_PERIOD, .init = a6xx_gpu_init, + .speedbins = a618_speedbins, + .speedbins_count = ARRAY_SIZE(a618_speedbins), }, { .rev = ADRENO_REV(6, 3, 0, ANY_ID), .revn = 630, -- 2.7.4 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v2 1/3] drm/msm: adreno: Make speed-bin support generic
So far a530v2 gpu has support for detecting its supported opps based on a fuse value called speed-bin. This patch makes this support generic across gpu families. This is in preparation to extend speed-bin support to a6x family. Signed-off-by: Akhil P Oommen --- Changes from v1: 1. Added the changes to support a618 sku to the series. 2. Avoid failing probe in case of an unsupported sku. (Rob) drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 34 -- drivers/gpu/drm/msm/adreno/adreno_device.c | 4 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.c| 71 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.h| 5 +++ 4 files changed, 80 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 8fa5c91..7d42321 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -1531,38 +1531,6 @@ static const struct adreno_gpu_funcs funcs = { .get_timestamp = a5xx_get_timestamp, }; -static void check_speed_bin(struct device *dev) -{ - struct nvmem_cell *cell; - u32 val; - - /* -* If the OPP table specifies a opp-supported-hw property then we have -* to set something with dev_pm_opp_set_supported_hw() or the table -* doesn't get populated so pick an arbitrary value that should -* ensure the default frequencies are selected but not conflict with any -* actual bins -*/ - val = 0x80; - - cell = nvmem_cell_get(dev, "speed_bin"); - - if (!IS_ERR(cell)) { - void *buf = nvmem_cell_read(cell, NULL); - - if (!IS_ERR(buf)) { - u8 bin = *((u8 *) buf); - - val = (1 << bin); - kfree(buf); - } - - nvmem_cell_put(cell); - } - - dev_pm_opp_set_supported_hw(dev, &val, 1); -} - struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; @@ -1588,8 +1556,6 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) a5xx_gpu->lm_leakage = 0x4E001A; - check_speed_bin(&pdev->dev); - ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 4); if (ret) { a5xx_destroy(&(a5xx_gpu->base.base)); diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 87c8b03..e0ff16c 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -18,6 +18,8 @@ bool snapshot_debugbus = false; MODULE_PARM_DESC(snapshot_debugbus, "Include debugbus sections in GPU devcoredump (if not fused off)"); module_param_named(snapshot_debugbus, snapshot_debugbus, bool, 0600); +const u32 a530v2_speedbins[] = {0, 1, 2, 3, 4, 5, 6, 7}; + static const struct adreno_info gpulist[] = { { .rev = ADRENO_REV(2, 0, 0, 0), @@ -163,6 +165,8 @@ static const struct adreno_info gpulist[] = { ADRENO_QUIRK_FAULT_DETECT_MASK, .init = a5xx_gpu_init, .zapfw = "a530_zap.mdt", + .speedbins = a530v2_speedbins, + .speedbins_count = ARRAY_SIZE(a530v2_speedbins), }, { .rev = ADRENO_REV(5, 4, 0, 2), .revn = 540, diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index f21561d..b342fa4 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "adreno_gpu.h" #include "msm_gem.h" @@ -891,6 +892,69 @@ void adreno_gpu_ocmem_cleanup(struct adreno_ocmem *adreno_ocmem) adreno_ocmem->hdl); } +static int adreno_set_supported_hw(struct device *dev, + struct adreno_gpu *adreno_gpu) +{ + u8 speedbins_count = adreno_gpu->info->speedbins_count; + const u32 *speedbins = adreno_gpu->info->speedbins; + struct nvmem_cell *cell; + u32 bin, i; + u32 val = 0; + void *buf, *opp_table; + + cell = nvmem_cell_get(dev, "speed_bin"); + /* +* -ENOENT means that the platform doesn't support speedbin which is +* fine +*/ + if (PTR_ERR(cell) == -ENOENT) + return 0; + else if (IS_ERR(cell)) + return PTR_ERR(cell); + + if (!speedbins) + goto done; + + buf = nvmem_cell_read(cell, NULL); + if (IS_ERR(buf)) { + nvmem_cell_put(cell); + return PTR_ERR(buf); + } + + bin = *((u32 *) buf); + + for (i = 0; i < speedbins_count; i++) { + if (bin == speedbins[i]) { + val
[Freedreno] [PATCH v2 3/3] arm: dts: sc7180: Add support for gpu fuse
Add support for gpu fuse to help identify the supported opps. Signed-off-by: Akhil P Oommen --- arch/arm64/boot/dts/qcom/sc7180.dtsi | 22 ++ 1 file changed, 22 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi index 6678f1e..8cae3eb 100644 --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -675,6 +675,11 @@ reg = <0x25b 0x1>; bits = <1 3>; }; + + gpu_speed_bin: gpu_speed_bin@1d2 { + reg = <0x1d2 0x2>; + bits = <5 8>; + }; }; sdhc_1: sdhci@7c4000 { @@ -1907,52 +1912,69 @@ operating-points-v2 = <&gpu_opp_table>; qcom,gmu = <&gmu>; + nvmem-cells = <&gpu_speed_bin>; + nvmem-cell-names = "speed_bin"; + interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "gfx-mem"; gpu_opp_table: opp-table { compatible = "operating-points-v2"; + opp-82500 { + opp-hz = /bits/ 64 <82500>; + opp-level = ; + opp-peak-kBps = <8532000>; + opp-supported-hw = <0x04>; + }; + opp-8 { opp-hz = /bits/ 64 <8>; opp-level = ; opp-peak-kBps = <8532000>; + opp-supported-hw = <0x07>; }; opp-65000 { opp-hz = /bits/ 64 <65000>; opp-level = ; opp-peak-kBps = <7216000>; + opp-supported-hw = <0x07>; }; opp-56500 { opp-hz = /bits/ 64 <56500>; opp-level = ; opp-peak-kBps = <5412000>; + opp-supported-hw = <0x07>; }; opp-43000 { opp-hz = /bits/ 64 <43000>; opp-level = ; opp-peak-kBps = <5412000>; + opp-supported-hw = <0x07>; }; opp-35500 { opp-hz = /bits/ 64 <35500>; opp-level = ; opp-peak-kBps = <3072000>; + opp-supported-hw = <0x07>; }; opp-26700 { opp-hz = /bits/ 64 <26700>; opp-level = ; opp-peak-kBps = <3072000>; + opp-supported-hw = <0x07>; }; opp-18000 { opp-hz = /bits/ 64 <18000>; opp-level = ; opp-peak-kBps = <1804000>; + opp-supported-hw = <0x07>; }; }; }; -- 2.7.4 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH] drm/msm: adreno: Make speed-bin support generic
On 11/16/2020 10:44 PM, Jordan Crouse wrote: On Mon, Nov 16, 2020 at 07:40:03PM +0530, Akhil P Oommen wrote: On 11/12/2020 10:05 PM, Jordan Crouse wrote: On Thu, Nov 12, 2020 at 09:19:04PM +0530, Akhil P Oommen wrote: So far a530v2 gpu has support for detecting its supported opps based on a fuse value called speed-bin. This patch makes this support generic across gpu families. This is in preparation to extend speed-bin support to a6x family. Signed-off-by: Akhil P Oommen --- This patch is rebased on top of msm-next-staging branch in rob's tree. drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 34 -- drivers/gpu/drm/msm/adreno/adreno_device.c | 4 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.c| 71 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.h| 5 +++ 4 files changed, 80 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 8fa5c91..7d42321 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -1531,38 +1531,6 @@ static const struct adreno_gpu_funcs funcs = { .get_timestamp = a5xx_get_timestamp, }; -static void check_speed_bin(struct device *dev) -{ - struct nvmem_cell *cell; - u32 val; - - /* -* If the OPP table specifies a opp-supported-hw property then we have -* to set something with dev_pm_opp_set_supported_hw() or the table -* doesn't get populated so pick an arbitrary value that should -* ensure the default frequencies are selected but not conflict with any -* actual bins -*/ - val = 0x80; - - cell = nvmem_cell_get(dev, "speed_bin"); - - if (!IS_ERR(cell)) { - void *buf = nvmem_cell_read(cell, NULL); - - if (!IS_ERR(buf)) { - u8 bin = *((u8 *) buf); - - val = (1 << bin); - kfree(buf); - } - - nvmem_cell_put(cell); - } - - dev_pm_opp_set_supported_hw(dev, &val, 1); -} - struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; @@ -1588,8 +1556,6 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) a5xx_gpu->lm_leakage = 0x4E001A; - check_speed_bin(&pdev->dev); - ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 4); if (ret) { a5xx_destroy(&(a5xx_gpu->base.base)); diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 87c8b03..e0ff16c 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -18,6 +18,8 @@ bool snapshot_debugbus = false; MODULE_PARM_DESC(snapshot_debugbus, "Include debugbus sections in GPU devcoredump (if not fused off)"); module_param_named(snapshot_debugbus, snapshot_debugbus, bool, 0600); +const u32 a530v2_speedbins[] = {0, 1, 2, 3, 4, 5, 6, 7}; + static const struct adreno_info gpulist[] = { { .rev = ADRENO_REV(2, 0, 0, 0), @@ -163,6 +165,8 @@ static const struct adreno_info gpulist[] = { ADRENO_QUIRK_FAULT_DETECT_MASK, .init = a5xx_gpu_init, .zapfw = "a530_zap.mdt", + .speedbins = a530v2_speedbins, + .speedbins_count = ARRAY_SIZE(a530v2_speedbins), }, { .rev = ADRENO_REV(5, 4, 0, 2), .revn = 540, diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index f21561d..cdd0c11 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "adreno_gpu.h" #include "msm_gem.h" @@ -891,6 +892,69 @@ void adreno_gpu_ocmem_cleanup(struct adreno_ocmem *adreno_ocmem) adreno_ocmem->hdl); } +static int adreno_set_supported_hw(struct device *dev, + struct adreno_gpu *adreno_gpu) +{ + u8 speedbins_count = adreno_gpu->info->speedbins_count; + const u32 *speedbins = adreno_gpu->info->speedbins; We don't need to make this generic and put it in the table. Just call the function from the target specific code and pass the speedbin array and size from there. I didn't get you entirely. Do you mean we should avoid keeping speedbin array in the adreno_gpu->info table? Exactly. Jordan But why duplicate this code if it can be made generic? Could you please check the v2 version? -Akhil. -Akhil. + struct nvmem_cell *cell; + u32 bin, i; + u32 val = 0; + void *buf, *opp_table; + + cell = nvmem_cell_get(dev, "speed_bin"); + /* +
Re: [Freedreno] [PATCH v2 1/3] drm/msm: adreno: Make speed-bin support generic
<< Resending since Jordan wasn't in the CC list >> On 11/30/2020 10:32 PM, Jordan Crouse wrote: On Fri, Nov 27, 2020 at 06:19:44PM +0530, Akhil P Oommen wrote: So far a530v2 gpu has support for detecting its supported opps based on a fuse value called speed-bin. This patch makes this support generic across gpu families. This is in preparation to extend speed-bin support to a6x family. Signed-off-by: Akhil P Oommen --- Changes from v1: 1. Added the changes to support a618 sku to the series. 2. Avoid failing probe in case of an unsupported sku. (Rob) drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 34 -- drivers/gpu/drm/msm/adreno/adreno_device.c | 4 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.c| 71 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.h| 5 +++ 4 files changed, 80 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 8fa5c91..7d42321 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -1531,38 +1531,6 @@ static const struct adreno_gpu_funcs funcs = { .get_timestamp = a5xx_get_timestamp, }; -static void check_speed_bin(struct device *dev) -{ - struct nvmem_cell *cell; - u32 val; - - /* -* If the OPP table specifies a opp-supported-hw property then we have -* to set something with dev_pm_opp_set_supported_hw() or the table -* doesn't get populated so pick an arbitrary value that should -* ensure the default frequencies are selected but not conflict with any -* actual bins -*/ - val = 0x80; - - cell = nvmem_cell_get(dev, "speed_bin"); - - if (!IS_ERR(cell)) { - void *buf = nvmem_cell_read(cell, NULL); - - if (!IS_ERR(buf)) { - u8 bin = *((u8 *) buf); - - val = (1 << bin); - kfree(buf); - } - - nvmem_cell_put(cell); - } - - dev_pm_opp_set_supported_hw(dev, &val, 1); -} - struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; @@ -1588,8 +1556,6 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) a5xx_gpu->lm_leakage = 0x4E001A; - check_speed_bin(&pdev->dev); - ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 4); if (ret) { a5xx_destroy(&(a5xx_gpu->base.base)); diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 87c8b03..e0ff16c 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -18,6 +18,8 @@ bool snapshot_debugbus = false; MODULE_PARM_DESC(snapshot_debugbus, "Include debugbus sections in GPU devcoredump (if not fused off)"); module_param_named(snapshot_debugbus, snapshot_debugbus, bool, 0600); +const u32 a530v2_speedbins[] = {0, 1, 2, 3, 4, 5, 6, 7}; + static const struct adreno_info gpulist[] = { { .rev = ADRENO_REV(2, 0, 0, 0), @@ -163,6 +165,8 @@ static const struct adreno_info gpulist[] = { ADRENO_QUIRK_FAULT_DETECT_MASK, .init = a5xx_gpu_init, .zapfw = "a530_zap.mdt", + .speedbins = a530v2_speedbins, + .speedbins_count = ARRAY_SIZE(a530v2_speedbins), }, { .rev = ADRENO_REV(5, 4, 0, 2), .revn = 540, diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index f21561d..b342fa4 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "adreno_gpu.h" #include "msm_gem.h" @@ -891,6 +892,69 @@ void adreno_gpu_ocmem_cleanup(struct adreno_ocmem *adreno_ocmem) adreno_ocmem->hdl); } +static int adreno_set_supported_hw(struct device *dev, + struct adreno_gpu *adreno_gpu) +{ + u8 speedbins_count = adreno_gpu->info->speedbins_count; + const u32 *speedbins = adreno_gpu->info->speedbins; + struct nvmem_cell *cell; + u32 bin, i; + u32 val = 0; + void *buf, *opp_table; + + cell = nvmem_cell_get(dev, "speed_bin"); + /* +* -ENOENT means that the platform doesn't support speedbin which is +* fine +*/ + if (PTR_ERR(cell) == -ENOENT) + return 0; + else if (IS_ERR(cell)) + return PTR_ERR(cell); + + if (!speedbins) + goto done; + + buf = nvmem_cell_read(cell, NULL); + if (IS_ERR(buf)) { + nvmem_cel
Re: [Freedreno] [PATCH v2 1/3] drm/msm: adreno: Make speed-bin support generic
On 12/2/2020 10:00 PM, Jordan Crouse wrote: On Wed, Dec 02, 2020 at 08:53:51PM +0530, Akhil P Oommen wrote: On 11/30/2020 10:32 PM, Jordan Crouse wrote: On Fri, Nov 27, 2020 at 06:19:44PM +0530, Akhil P Oommen wrote: So far a530v2 gpu has support for detecting its supported opps based on a fuse value called speed-bin. This patch makes this support generic across gpu families. This is in preparation to extend speed-bin support to a6x family. Signed-off-by: Akhil P Oommen --- Changes from v1: 1. Added the changes to support a618 sku to the series. 2. Avoid failing probe in case of an unsupported sku. (Rob) drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 34 -- drivers/gpu/drm/msm/adreno/adreno_device.c | 4 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.c| 71 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.h| 5 +++ 4 files changed, 80 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 8fa5c91..7d42321 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -1531,38 +1531,6 @@ static const struct adreno_gpu_funcs funcs = { .get_timestamp = a5xx_get_timestamp, }; -static void check_speed_bin(struct device *dev) -{ - struct nvmem_cell *cell; - u32 val; - - /* -* If the OPP table specifies a opp-supported-hw property then we have -* to set something with dev_pm_opp_set_supported_hw() or the table -* doesn't get populated so pick an arbitrary value that should -* ensure the default frequencies are selected but not conflict with any -* actual bins -*/ - val = 0x80; - - cell = nvmem_cell_get(dev, "speed_bin"); - - if (!IS_ERR(cell)) { - void *buf = nvmem_cell_read(cell, NULL); - - if (!IS_ERR(buf)) { - u8 bin = *((u8 *) buf); - - val = (1 << bin); - kfree(buf); - } - - nvmem_cell_put(cell); - } - - dev_pm_opp_set_supported_hw(dev, &val, 1); -} - struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; @@ -1588,8 +1556,6 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) a5xx_gpu->lm_leakage = 0x4E001A; - check_speed_bin(&pdev->dev); - ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 4); if (ret) { a5xx_destroy(&(a5xx_gpu->base.base)); diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 87c8b03..e0ff16c 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -18,6 +18,8 @@ bool snapshot_debugbus = false; MODULE_PARM_DESC(snapshot_debugbus, "Include debugbus sections in GPU devcoredump (if not fused off)"); module_param_named(snapshot_debugbus, snapshot_debugbus, bool, 0600); +const u32 a530v2_speedbins[] = {0, 1, 2, 3, 4, 5, 6, 7}; + static const struct adreno_info gpulist[] = { { .rev = ADRENO_REV(2, 0, 0, 0), @@ -163,6 +165,8 @@ static const struct adreno_info gpulist[] = { ADRENO_QUIRK_FAULT_DETECT_MASK, .init = a5xx_gpu_init, .zapfw = "a530_zap.mdt", + .speedbins = a530v2_speedbins, + .speedbins_count = ARRAY_SIZE(a530v2_speedbins), }, { .rev = ADRENO_REV(5, 4, 0, 2), .revn = 540, diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index f21561d..b342fa4 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "adreno_gpu.h" #include "msm_gem.h" @@ -891,6 +892,69 @@ void adreno_gpu_ocmem_cleanup(struct adreno_ocmem *adreno_ocmem) adreno_ocmem->hdl); } +static int adreno_set_supported_hw(struct device *dev, + struct adreno_gpu *adreno_gpu) +{ + u8 speedbins_count = adreno_gpu->info->speedbins_count; + const u32 *speedbins = adreno_gpu->info->speedbins; + struct nvmem_cell *cell; + u32 bin, i; + u32 val = 0; + void *buf, *opp_table; + + cell = nvmem_cell_get(dev, "speed_bin"); + /* +* -ENOENT means that the platform doesn't support speedbin which is +* fine +*/ + if (PTR_ERR(cell) == -ENOENT) + return 0; + else if (IS_ERR(cell)) + return PTR_ERR(cell); + + if (!speedbins) + goto done; + + buf = nvmem_cell_read(cell, NULL); + if (IS_ERR(buf)) { +
[Freedreno] [PATCH v3 1/2] drm/msm: Add speed-bin support to a618 gpu
Some GPUs support different max frequencies depending on the platform. To identify the correct variant, we should check the gpu speedbin fuse value. Add support for this speedbin detection to a6xx family along with the required fuse details for a618 gpu. Signed-off-by: Akhil P Oommen --- Changes from v2: 1. Made the changes a6xx specific to save space. Changes from v1: 1. Added the changes to support a618 sku to the series. 2. Avoid failing probe in case of an unsupported sku. (Rob) drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 74 +++ drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 2 + 2 files changed, 76 insertions(+) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 1306618..6304578 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -10,10 +10,13 @@ #include #include +#include #include #define GPU_PAS_ID 13 +const u32 a618_speedbins[] = {0, 169, 174}; + static inline bool _a6xx_check_idle(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); @@ -1208,6 +1211,10 @@ static void a6xx_destroy(struct msm_gpu *gpu) a6xx_gmu_remove(a6xx_gpu); adreno_gpu_cleanup(adreno_gpu); + + if (a6xx_gpu->opp_table) + dev_pm_opp_put_supported_hw(a6xx_gpu->opp_table); + kfree(a6xx_gpu); } @@ -1264,6 +1271,67 @@ static uint32_t a6xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring) return ring->memptrs->rptr = gpu_read(gpu, REG_A6XX_CP_RB_RPTR); } +static u32 fuse_to_supp_hw(struct device *dev, u32 revn, u32 fuse) +{ + int i; + + if (revn == 618) { + for (i = 0; i < ARRAY_SIZE(a618_speedbins); i++) { + if (fuse == a618_speedbins[i]) + return (1 << i); + } + } + + DRM_DEV_ERROR(dev, + "missing support for speed-bin: %u. Some OPPs may not be supported by hardware", + fuse); + return ~0U; +} + +static int a6xx_set_supported_hw(struct device *dev, struct a6xx_gpu *a6xx_gpu, + u32 revn) +{ + + struct opp_table *opp_table; + struct nvmem_cell *cell; + u32 supp_hw = ~0U; + void *buf; + + cell = nvmem_cell_get(dev, "speed_bin"); + /* +* -ENOENT means that the platform doesn't support speedbin which is +* fine +*/ + if (PTR_ERR(cell) == -ENOENT) + return 0; + else if (IS_ERR(cell)) { + DRM_DEV_ERROR(dev, + "failed to read speed-bin. Some OPPs may not be supported by hardware"); + goto done; + } + + buf = nvmem_cell_read(cell, NULL); + if (IS_ERR(buf)) { + nvmem_cell_put(cell); + DRM_DEV_ERROR(dev, + "failed to read speed-bin. Some OPPs may not be supported by hardware"); + goto done; + } + + supp_hw = fuse_to_supp_hw(dev, revn, *((u32 *) buf)); + + kfree(buf); + nvmem_cell_put(cell); + +done: + opp_table = dev_pm_opp_set_supported_hw(dev, &supp_hw, 1); + if (IS_ERR(opp_table)) + return PTR_ERR(opp_table); + + a6xx_gpu->opp_table = opp_table; + return 0; +} + static const struct adreno_gpu_funcs funcs = { .base = { .get_param = adreno_get_param, @@ -1325,6 +1393,12 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) a6xx_llc_slices_init(pdev, a6xx_gpu); + ret = a6xx_set_supported_hw(&pdev->dev, a6xx_gpu, info->revn); + if (ret) { + a6xx_destroy(&(a6xx_gpu->base.base)); + return ERR_PTR(ret); + } + ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1); if (ret) { a6xx_destroy(&(a6xx_gpu->base.base)); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h index e793d32..ce0610c 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h @@ -33,6 +33,8 @@ struct a6xx_gpu { void *llc_slice; void *htw_llc_slice; bool have_mmu500; + + struct opp_table *opp_table; }; #define to_a6xx_gpu(x) container_of(x, struct a6xx_gpu, base) -- 2.7.4 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v3 2/2] arm: dts: sc7180: Add support for gpu fuse
Add support for gpu fuse to help identify the supported opps. Signed-off-by: Akhil P Oommen --- arch/arm64/boot/dts/qcom/sc7180.dtsi | 22 ++ 1 file changed, 22 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi index 6678f1e..8cae3eb 100644 --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -675,6 +675,11 @@ reg = <0x25b 0x1>; bits = <1 3>; }; + + gpu_speed_bin: gpu_speed_bin@1d2 { + reg = <0x1d2 0x2>; + bits = <5 8>; + }; }; sdhc_1: sdhci@7c4000 { @@ -1907,52 +1912,69 @@ operating-points-v2 = <&gpu_opp_table>; qcom,gmu = <&gmu>; + nvmem-cells = <&gpu_speed_bin>; + nvmem-cell-names = "speed_bin"; + interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "gfx-mem"; gpu_opp_table: opp-table { compatible = "operating-points-v2"; + opp-82500 { + opp-hz = /bits/ 64 <82500>; + opp-level = ; + opp-peak-kBps = <8532000>; + opp-supported-hw = <0x04>; + }; + opp-8 { opp-hz = /bits/ 64 <8>; opp-level = ; opp-peak-kBps = <8532000>; + opp-supported-hw = <0x07>; }; opp-65000 { opp-hz = /bits/ 64 <65000>; opp-level = ; opp-peak-kBps = <7216000>; + opp-supported-hw = <0x07>; }; opp-56500 { opp-hz = /bits/ 64 <56500>; opp-level = ; opp-peak-kBps = <5412000>; + opp-supported-hw = <0x07>; }; opp-43000 { opp-hz = /bits/ 64 <43000>; opp-level = ; opp-peak-kBps = <5412000>; + opp-supported-hw = <0x07>; }; opp-35500 { opp-hz = /bits/ 64 <35500>; opp-level = ; opp-peak-kBps = <3072000>; + opp-supported-hw = <0x07>; }; opp-26700 { opp-hz = /bits/ 64 <26700>; opp-level = ; opp-peak-kBps = <3072000>; + opp-supported-hw = <0x07>; }; opp-18000 { opp-hz = /bits/ 64 <18000>; opp-level = ; opp-peak-kBps = <1804000>; + opp-supported-hw = <0x07>; }; }; }; -- 2.7.4 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH v3 1/2] drm/msm: Add speed-bin support to a618 gpu
On 12/7/2020 4:12 PM, Akhil P Oommen wrote: Some GPUs support different max frequencies depending on the platform. To identify the correct variant, we should check the gpu speedbin fuse value. Add support for this speedbin detection to a6xx family along with the required fuse details for a618 gpu. Signed-off-by: Akhil P Oommen --- Changes from v2: 1. Made the changes a6xx specific to save space. Changes from v1: 1. Added the changes to support a618 sku to the series. 2. Avoid failing probe in case of an unsupported sku. (Rob) drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 74 +++ drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 2 + 2 files changed, 76 insertions(+) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 1306618..6304578 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -10,10 +10,13 @@ #include #include +#include #include #define GPU_PAS_ID 13 +const u32 a618_speedbins[] = {0, 169, 174}; + static inline bool _a6xx_check_idle(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); @@ -1208,6 +1211,10 @@ static void a6xx_destroy(struct msm_gpu *gpu) a6xx_gmu_remove(a6xx_gpu); adreno_gpu_cleanup(adreno_gpu); + + if (a6xx_gpu->opp_table) + dev_pm_opp_put_supported_hw(a6xx_gpu->opp_table); + kfree(a6xx_gpu); } @@ -1264,6 +1271,67 @@ static uint32_t a6xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring) return ring->memptrs->rptr = gpu_read(gpu, REG_A6XX_CP_RB_RPTR); } +static u32 fuse_to_supp_hw(struct device *dev, u32 revn, u32 fuse) +{ + int i; + + if (revn == 618) { + for (i = 0; i < ARRAY_SIZE(a618_speedbins); i++) { + if (fuse == a618_speedbins[i]) + return (1 << i); + } + } + + DRM_DEV_ERROR(dev, + "missing support for speed-bin: %u. Some OPPs may not be supported by hardware", + fuse); + return ~0U; +} + +static int a6xx_set_supported_hw(struct device *dev, struct a6xx_gpu *a6xx_gpu, + u32 revn) +{ + + struct opp_table *opp_table; + struct nvmem_cell *cell; + u32 supp_hw = ~0U; + void *buf; + + cell = nvmem_cell_get(dev, "speed_bin"); + /* +* -ENOENT means that the platform doesn't support speedbin which is +* fine +*/ + if (PTR_ERR(cell) == -ENOENT) + return 0; + else if (IS_ERR(cell)) { + DRM_DEV_ERROR(dev, + "failed to read speed-bin. Some OPPs may not be supported by hardware"); + goto done; + } + + buf = nvmem_cell_read(cell, NULL); + if (IS_ERR(buf)) { + nvmem_cell_put(cell); + DRM_DEV_ERROR(dev, + "failed to read speed-bin. Some OPPs may not be supported by hardware"); + goto done; + } + + supp_hw = fuse_to_supp_hw(dev, revn, *((u32 *) buf)); + + kfree(buf); + nvmem_cell_put(cell); + +done: + opp_table = dev_pm_opp_set_supported_hw(dev, &supp_hw, 1); + if (IS_ERR(opp_table)) + return PTR_ERR(opp_table); + + a6xx_gpu->opp_table = opp_table; + return 0; +} + static const struct adreno_gpu_funcs funcs = { .base = { .get_param = adreno_get_param, @@ -1325,6 +1393,12 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) a6xx_llc_slices_init(pdev, a6xx_gpu); + ret = a6xx_set_supported_hw(&pdev->dev, a6xx_gpu, info->revn); + if (ret) { + a6xx_destroy(&(a6xx_gpu->base.base)); + return ERR_PTR(ret); + } + ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1); if (ret) { a6xx_destroy(&(a6xx_gpu->base.base)); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h index e793d32..ce0610c 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h @@ -33,6 +33,8 @@ struct a6xx_gpu { void *llc_slice; void *htw_llc_slice; bool have_mmu500; + + struct opp_table *opp_table; }; #define to_a6xx_gpu(x) container_of(x, struct a6xx_gpu, base) A gentle ping. -Akhil. ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH v3 2/2] arm: dts: sc7180: Add support for gpu fuse
On 12/7/2020 4:12 PM, Akhil P Oommen wrote: Add support for gpu fuse to help identify the supported opps. Signed-off-by: Akhil P Oommen --- arch/arm64/boot/dts/qcom/sc7180.dtsi | 22 ++ 1 file changed, 22 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi index 6678f1e..8cae3eb 100644 --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -675,6 +675,11 @@ reg = <0x25b 0x1>; bits = <1 3>; }; + + gpu_speed_bin: gpu_speed_bin@1d2 { + reg = <0x1d2 0x2>; + bits = <5 8>; + }; }; sdhc_1: sdhci@7c4000 { @@ -1907,52 +1912,69 @@ operating-points-v2 = <&gpu_opp_table>; qcom,gmu = <&gmu>; + nvmem-cells = <&gpu_speed_bin>; + nvmem-cell-names = "speed_bin"; + interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "gfx-mem"; gpu_opp_table: opp-table { compatible = "operating-points-v2"; +opp-82500 { + opp-hz = /bits/ 64 <82500>; + opp-level = ; + opp-peak-kBps = <8532000>; + opp-supported-hw = <0x04>; + }; + opp-8 { opp-hz = /bits/ 64 <8>; opp-level = ; opp-peak-kBps = <8532000>; + opp-supported-hw = <0x07>; }; opp-65000 { opp-hz = /bits/ 64 <65000>; opp-level = ; opp-peak-kBps = <7216000>; + opp-supported-hw = <0x07>; }; opp-56500 { opp-hz = /bits/ 64 <56500>; opp-level = ; opp-peak-kBps = <5412000>; + opp-supported-hw = <0x07>; }; opp-43000 { opp-hz = /bits/ 64 <43000>; opp-level = ; opp-peak-kBps = <5412000>; + opp-supported-hw = <0x07>; }; opp-35500 { opp-hz = /bits/ 64 <35500>; opp-level = ; opp-peak-kBps = <3072000>; + opp-supported-hw = <0x07>; }; opp-26700 { opp-hz = /bits/ 64 <26700>; opp-level = ; opp-peak-kBps = <3072000>; + opp-supported-hw = <0x07>; }; opp-18000 { opp-hz = /bits/ 64 <18000>; opp-level = ; opp-peak-kBps = <1804000>; + opp-supported-hw = <0x07>; }; }; }; A gentle ping. -Akhil. ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v4 1/2] drm/msm: Add speed-bin support to a618 gpu
Some GPUs support different max frequencies depending on the platform. To identify the correct variant, we should check the gpu speedbin fuse value. Add support for this speedbin detection to a6xx family along with the required fuse details for a618 gpu. Signed-off-by: Akhil P Oommen --- Changes from v2: 1. Made the changes a6xx specific to save space. Changes from v1: 1. Added the changes to support a618 sku to the series. 2. Avoid failing probe in case of an unsupported sku. (Rob) Changes from v3: 1. Replace a618_speedbins[] with a function. (Jordan) drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 83 +++ drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 2 + 2 files changed, 85 insertions(+) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 1306618..499d134 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -10,6 +10,7 @@ #include #include +#include #include #define GPU_PAS_ID 13 @@ -1208,6 +1209,10 @@ static void a6xx_destroy(struct msm_gpu *gpu) a6xx_gmu_remove(a6xx_gpu); adreno_gpu_cleanup(adreno_gpu); + + if (a6xx_gpu->opp_table) + dev_pm_opp_put_supported_hw(a6xx_gpu->opp_table); + kfree(a6xx_gpu); } @@ -1264,6 +1269,78 @@ static uint32_t a6xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring) return ring->memptrs->rptr = gpu_read(gpu, REG_A6XX_CP_RB_RPTR); } +static u32 a618_get_speed_bin(u32 fuse) +{ + if (fuse == 0) + return 0; + else if (fuse == 169) + return 1; + else if (fuse == 174) + return 2; + + return UINT_MAX; +} + +static u32 fuse_to_supp_hw(struct device *dev, u32 revn, u32 fuse) +{ + u32 val = UINT_MAX; + + if (revn == 618) + val = a618_get_speed_bin(fuse); + + if (val == UINT_MAX) { + DRM_DEV_ERROR(dev, + "missing support for speed-bin: %u. Some OPPs may not be supported by hardware", + fuse); + return UINT_MAX; + } + + return (1 << val); +} + +static int a6xx_set_supported_hw(struct device *dev, struct a6xx_gpu *a6xx_gpu, + u32 revn) +{ + struct opp_table *opp_table; + struct nvmem_cell *cell; + u32 supp_hw = UINT_MAX; + void *buf; + + cell = nvmem_cell_get(dev, "speed_bin"); + /* +* -ENOENT means that the platform doesn't support speedbin which is +* fine +*/ + if (PTR_ERR(cell) == -ENOENT) + return 0; + else if (IS_ERR(cell)) { + DRM_DEV_ERROR(dev, + "failed to read speed-bin. Some OPPs may not be supported by hardware"); + goto done; + } + + buf = nvmem_cell_read(cell, NULL); + if (IS_ERR(buf)) { + nvmem_cell_put(cell); + DRM_DEV_ERROR(dev, + "failed to read speed-bin. Some OPPs may not be supported by hardware"); + goto done; + } + + supp_hw = fuse_to_supp_hw(dev, revn, *((u32 *) buf)); + + kfree(buf); + nvmem_cell_put(cell); + +done: + opp_table = dev_pm_opp_set_supported_hw(dev, &supp_hw, 1); + if (IS_ERR(opp_table)) + return PTR_ERR(opp_table); + + a6xx_gpu->opp_table = opp_table; + return 0; +} + static const struct adreno_gpu_funcs funcs = { .base = { .get_param = adreno_get_param, @@ -1325,6 +1402,12 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) a6xx_llc_slices_init(pdev, a6xx_gpu); + ret = a6xx_set_supported_hw(&pdev->dev, a6xx_gpu, info->revn); + if (ret) { + a6xx_destroy(&(a6xx_gpu->base.base)); + return ERR_PTR(ret); + } + ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1); if (ret) { a6xx_destroy(&(a6xx_gpu->base.base)); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h index e793d32..ce0610c 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h @@ -33,6 +33,8 @@ struct a6xx_gpu { void *llc_slice; void *htw_llc_slice; bool have_mmu500; + + struct opp_table *opp_table; }; #define to_a6xx_gpu(x) container_of(x, struct a6xx_gpu, base) -- 2.7.4 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v4 2/2] arm: dts: sc7180: Add support for gpu fuse
Add support for gpu fuse to help identify the supported opps. Signed-off-by: Akhil P Oommen --- arch/arm64/boot/dts/qcom/sc7180.dtsi | 22 ++ 1 file changed, 22 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi index 6678f1e..8cae3eb 100644 --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -675,6 +675,11 @@ reg = <0x25b 0x1>; bits = <1 3>; }; + + gpu_speed_bin: gpu_speed_bin@1d2 { + reg = <0x1d2 0x2>; + bits = <5 8>; + }; }; sdhc_1: sdhci@7c4000 { @@ -1907,52 +1912,69 @@ operating-points-v2 = <&gpu_opp_table>; qcom,gmu = <&gmu>; + nvmem-cells = <&gpu_speed_bin>; + nvmem-cell-names = "speed_bin"; + interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "gfx-mem"; gpu_opp_table: opp-table { compatible = "operating-points-v2"; + opp-82500 { + opp-hz = /bits/ 64 <82500>; + opp-level = ; + opp-peak-kBps = <8532000>; + opp-supported-hw = <0x04>; + }; + opp-8 { opp-hz = /bits/ 64 <8>; opp-level = ; opp-peak-kBps = <8532000>; + opp-supported-hw = <0x07>; }; opp-65000 { opp-hz = /bits/ 64 <65000>; opp-level = ; opp-peak-kBps = <7216000>; + opp-supported-hw = <0x07>; }; opp-56500 { opp-hz = /bits/ 64 <56500>; opp-level = ; opp-peak-kBps = <5412000>; + opp-supported-hw = <0x07>; }; opp-43000 { opp-hz = /bits/ 64 <43000>; opp-level = ; opp-peak-kBps = <5412000>; + opp-supported-hw = <0x07>; }; opp-35500 { opp-hz = /bits/ 64 <35500>; opp-level = ; opp-peak-kBps = <3072000>; + opp-supported-hw = <0x07>; }; opp-26700 { opp-hz = /bits/ 64 <26700>; opp-level = ; opp-peak-kBps = <3072000>; + opp-supported-hw = <0x07>; }; opp-18000 { opp-hz = /bits/ 64 <18000>; opp-level = ; opp-peak-kBps = <1804000>; + opp-supported-hw = <0x07>; }; }; }; -- 2.7.4 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH v4 2/2] arm: dts: sc7180: Add support for gpu fuse
On 2/3/2021 4:22 AM, Bjorn Andersson wrote: On Fri 08 Jan 12:15 CST 2021, Akhil P Oommen wrote: Please align the $subject prefix with other changes in the same file. I fixed it up while picking up the patch this time. Will take of this in future. Thanks, Bjorn. -Akhil. Regards, Bjorn Add support for gpu fuse to help identify the supported opps. Signed-off-by: Akhil P Oommen --- arch/arm64/boot/dts/qcom/sc7180.dtsi | 22 ++ 1 file changed, 22 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi index 6678f1e..8cae3eb 100644 --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -675,6 +675,11 @@ reg = <0x25b 0x1>; bits = <1 3>; }; + + gpu_speed_bin: gpu_speed_bin@1d2 { + reg = <0x1d2 0x2>; + bits = <5 8>; + }; }; sdhc_1: sdhci@7c4000 { @@ -1907,52 +1912,69 @@ operating-points-v2 = <&gpu_opp_table>; qcom,gmu = <&gmu>; + nvmem-cells = <&gpu_speed_bin>; + nvmem-cell-names = "speed_bin"; + interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "gfx-mem"; gpu_opp_table: opp-table { compatible = "operating-points-v2"; +opp-82500 { + opp-hz = /bits/ 64 <82500>; + opp-level = ; + opp-peak-kBps = <8532000>; + opp-supported-hw = <0x04>; + }; + opp-8 { opp-hz = /bits/ 64 <8>; opp-level = ; opp-peak-kBps = <8532000>; + opp-supported-hw = <0x07>; }; opp-65000 { opp-hz = /bits/ 64 <65000>; opp-level = ; opp-peak-kBps = <7216000>; + opp-supported-hw = <0x07>; }; opp-56500 { opp-hz = /bits/ 64 <56500>; opp-level = ; opp-peak-kBps = <5412000>; + opp-supported-hw = <0x07>; }; opp-43000 { opp-hz = /bits/ 64 <43000>; opp-level = ; opp-peak-kBps = <5412000>; + opp-supported-hw = <0x07>; }; opp-35500 { opp-hz = /bits/ 64 <35500>; opp-level = ; opp-peak-kBps = <3072000>; + opp-supported-hw = <0x07>; }; opp-26700 { opp-hz = /bits/ 64 <26700>; opp-level = ; opp-peak-kBps = <3072000>; + opp-supported-hw = <0x07>; }; opp-18000 { opp-hz = /bits/ 64 <18000>; opp-level = ; opp-peak-kBps = <1804000>; + opp-supported-hw = <0x07>; }; }; }; -- 2.7.4 ___ dri-devel mailing list dri-de...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH] drm/msm: Fix legacy relocs path
On 2/5/2021 4:26 AM, Rob Clark wrote: From: Rob Clark In moving code around, we ended up using the same pointer to copy_from_user() the relocs tables as we used for the cmd table entry, which is clearly not right. This went unnoticed because modern mesa on non-ancent kernels does not actually use relocs. But this broke ancient mesa on modern kernels. Reported-by: Emil Velikov Fixes: 20224d715a88 ("drm/msm/submit: Move copy_from_user ahead of locking bos") Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gem_submit.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index d04c349d8112..5480852bdeda 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -198,6 +198,8 @@ static int submit_lookup_cmds(struct msm_gem_submit *submit, submit->cmd[i].idx = submit_cmd.submit_idx; submit->cmd[i].nr_relocs = submit_cmd.nr_relocs; + userptr = u64_to_user_ptr(submit_cmd.relocs); + sz = array_size(submit_cmd.nr_relocs, sizeof(struct drm_msm_gem_submit_reloc)); /* check for overflow: */ Reviewed-by: Akhil P Oommen -Akhil. ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH v2] drm/msm: a6xx: Make sure the SQE microcode is safe
On 2/10/2021 6:22 AM, Jordan Crouse wrote: Most a6xx targets have security issues that were fixed with new versions of the microcode(s). Make sure that we are booting with a safe version of the microcode for the target and print a message and error if not. v2: Add more informative error messages and fix typos Signed-off-by: Jordan Crouse --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 77 ++- 1 file changed, 64 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index ba8e9d3cf0fe..064b7face504 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -522,28 +522,73 @@ static int a6xx_cp_init(struct msm_gpu *gpu) return a6xx_idle(gpu, ring) ? 0 : -EINVAL; } -static void a6xx_ucode_check_version(struct a6xx_gpu *a6xx_gpu, +/* + * Check that the microcode version is new enough to include several key + * security fixes. Return true if the ucode is safe. + */ +static bool a6xx_ucode_check_version(struct a6xx_gpu *a6xx_gpu, struct drm_gem_object *obj) { + struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; + struct msm_gpu *gpu = &adreno_gpu->base; u32 *buf = msm_gem_get_vaddr(obj); + bool ret = false; if (IS_ERR(buf)) - return; + return false; /* -* If the lowest nibble is 0xa that is an indication that this microcode -* has been patched. The actual version is in dword [3] but we only care -* about the patchlevel which is the lowest nibble of dword [3] -* -* Otherwise check that the firmware is greater than or equal to 1.90 -* which was the first version that had this fix built in +* Targets up to a640 (a618, a630 and a640) need to check for a +* microcode version that is patched to support the whereami opcode or +* one that is new enough to include it by default. */ - if (((buf[0] & 0xf) == 0xa) && (buf[2] & 0xf) >= 1) - a6xx_gpu->has_whereami = true; - else if ((buf[0] & 0xfff) > 0x190) - a6xx_gpu->has_whereami = true; + if (adreno_is_a618(adreno_gpu) || adreno_is_a630(adreno_gpu) || + adreno_is_a640(adreno_gpu)) { + /* +* If the lowest nibble is 0xa that is an indication that this +* microcode has been patched. The actual version is in dword +* [3] but we only care about the patchlevel which is the lowest +* nibble of dword [3] +* +* Otherwise check that the firmware is greater than or equal +* to 1.90 which was the first version that had this fix built +* in +*/ + if buf[0] & 0xf) == 0xa) && (buf[2] & 0xf) >= 1) || + (buf[0] & 0xfff) >= 0x190) { + a6xx_gpu->has_whereami = true; + ret = true; + goto out; + } + DRM_DEV_ERROR(&gpu->pdev->dev, + "a630 SQE ucode is too old. Have version %x need at least %x\n", + buf[0] & 0xfff, 0x190); + } else { + /* +* a650 tier targets don't need whereami but still need to be +* equal to or newer than 1.95 for other security fixes +*/ + if (adreno_is_a650(adreno_gpu)) { + if ((buf[0] & 0xfff) >= 0x195) { + ret = true; + goto out; + } + + DRM_DEV_ERROR(&gpu->pdev->dev, + "a650 SQE ucode is too old. Have version %x need at least %x\n", + buf[0] & 0xfff, 0x195); + } + + /* +* When a660 is added those targets should return true here +* since those have all the critical security fixes built in +* from the start +*/ Or we can just initialize 'ret' as true. -Akhil + } +out: msm_gem_put_vaddr(obj); + return ret; } static int a6xx_ucode_init(struct msm_gpu *gpu) @@ -566,7 +611,13 @@ static int a6xx_ucode_init(struct msm_gpu *gpu) } msm_gem_object_set_name(a6xx_gpu->sqe_bo, "sqefw"); - a6xx_ucode_check_version(a6xx_gpu, a6xx_gpu->sqe_bo); + if (!a6xx_ucode_check_version(a6xx_gpu, a6xx_gpu->sqe_bo)) { + msm_gem_unpin_iova(a6xx_gpu->sqe_bo, gpu->aspace); + drm_gem_object_put(a6xx_gpu->sqe_bo); + + a6xx_gpu->sqe_bo = NULL; + return -EPERM; + } } gpu_write64(gpu, REG_A6XX_CP_SQE_INSTR_BASE_LO, ___
Re: [Freedreno] [PATCH v2] drm/msm: a6xx: Make sure the SQE microcode is safe
On 2/11/2021 9:32 PM, Jordan Crouse wrote: On Thu, Feb 11, 2021 at 06:50:28PM +0530, Akhil P Oommen wrote: On 2/10/2021 6:22 AM, Jordan Crouse wrote: Most a6xx targets have security issues that were fixed with new versions of the microcode(s). Make sure that we are booting with a safe version of the microcode for the target and print a message and error if not. v2: Add more informative error messages and fix typos Signed-off-by: Jordan Crouse --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 77 ++- 1 file changed, 64 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index ba8e9d3cf0fe..064b7face504 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -522,28 +522,73 @@ static int a6xx_cp_init(struct msm_gpu *gpu) return a6xx_idle(gpu, ring) ? 0 : -EINVAL; } -static void a6xx_ucode_check_version(struct a6xx_gpu *a6xx_gpu, +/* + * Check that the microcode version is new enough to include several key + * security fixes. Return true if the ucode is safe. + */ +static bool a6xx_ucode_check_version(struct a6xx_gpu *a6xx_gpu, struct drm_gem_object *obj) { + struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; + struct msm_gpu *gpu = &adreno_gpu->base; u32 *buf = msm_gem_get_vaddr(obj); + bool ret = false; if (IS_ERR(buf)) - return; + return false; /* -* If the lowest nibble is 0xa that is an indication that this microcode -* has been patched. The actual version is in dword [3] but we only care -* about the patchlevel which is the lowest nibble of dword [3] -* -* Otherwise check that the firmware is greater than or equal to 1.90 -* which was the first version that had this fix built in +* Targets up to a640 (a618, a630 and a640) need to check for a +* microcode version that is patched to support the whereami opcode or +* one that is new enough to include it by default. */ - if (((buf[0] & 0xf) == 0xa) && (buf[2] & 0xf) >= 1) - a6xx_gpu->has_whereami = true; - else if ((buf[0] & 0xfff) > 0x190) - a6xx_gpu->has_whereami = true; + if (adreno_is_a618(adreno_gpu) || adreno_is_a630(adreno_gpu) || + adreno_is_a640(adreno_gpu)) { nit: I feel a 'switch(revn)' would be more readable. Reviewed-by: Akhil P Oommen -Akhil + /* +* If the lowest nibble is 0xa that is an indication that this +* microcode has been patched. The actual version is in dword +* [3] but we only care about the patchlevel which is the lowest +* nibble of dword [3] +* +* Otherwise check that the firmware is greater than or equal +* to 1.90 which was the first version that had this fix built +* in +*/ + if buf[0] & 0xf) == 0xa) && (buf[2] & 0xf) >= 1) || + (buf[0] & 0xfff) >= 0x190) { + a6xx_gpu->has_whereami = true; + ret = true; + goto out; + } + DRM_DEV_ERROR(&gpu->pdev->dev, + "a630 SQE ucode is too old. Have version %x need at least %x\n", + buf[0] & 0xfff, 0x190); + } else { + /* +* a650 tier targets don't need whereami but still need to be +* equal to or newer than 1.95 for other security fixes +*/ + if (adreno_is_a650(adreno_gpu)) { + if ((buf[0] & 0xfff) >= 0x195) { + ret = true; + goto out; + } + + DRM_DEV_ERROR(&gpu->pdev->dev, + "a650 SQE ucode is too old. Have version %x need at least %x\n", + buf[0] & 0xfff, 0x195); + } + + /* +* When a660 is added those targets should return true here +* since those have all the critical security fixes built in +* from the start +*/ Or we can just initialize 'ret' as true. I thought about it and I think I want to force an accept list here instead of letting new targets get by with an implicit pass. Jordan -Akhil + } +out: msm_gem_put_vaddr(obj); + return ret; } static int a6xx_ucode_init(struct msm_gpu *gpu) @@ -566,7 +611,13 @@ static int a6xx_ucode_init(struct msm_gpu *gpu) } msm_gem_object_set_name(a6xx_gpu->sq
Re: [Freedreno] [PATCH] drm/msm/a6xx: fix for kernels without CONFIG_NVMEM
On 2/17/2021 8:36 AM, Rob Clark wrote: On Tue, Feb 16, 2021 at 12:10 PM Jonathan Marek wrote: Ignore nvmem_cell_get() EOPNOTSUPP error in the same way as a ENOENT error, to fix the case where the kernel was compiled without CONFIG_NVMEM. Fixes: fe7952c629da ("drm/msm: Add speed-bin support to a618 gpu") Signed-off-by: Jonathan Marek --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index ba8e9d3cf0fe..7fe5d97606aa 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1356,10 +1356,10 @@ static int a6xx_set_supported_hw(struct device *dev, struct a6xx_gpu *a6xx_gpu, cell = nvmem_cell_get(dev, "speed_bin"); /* -* -ENOENT means that the platform doesn't support speedbin which is -* fine +* -ENOENT means no speed bin in device tree, +* -EOPNOTSUPP means kernel was built without CONFIG_NVMEM very minor nit, it would be nice to at least preserve the gist of the "which is fine" (ie. some variation of "this is an optional thing and things won't catch fire without it" ;-)) (which is, I believe, is true, hopefully Akhil could confirm.. if not we should have a harder dependency on CONFIG_NVMEM..) IIRC, if the gpu opp table in the DT uses the 'opp-supported-hw' property, we will see some error during boot up if we don't call dev_pm_opp_set_supported_hw(). So calling "nvmem_cell_get(dev, "speed_bin")" is a way to test this. If there is no other harm, we can put a hard dependency on CONFIG_NVMEM. -Akhil. BR, -R */ - if (PTR_ERR(cell) == -ENOENT) + if (PTR_ERR(cell) == -ENOENT || PTR_ERR(cell) == -EOPNOTSUPP) return 0; else if (IS_ERR(cell)) { DRM_DEV_ERROR(dev, -- 2.26.1 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH] drm/msm/a6xx: fix for kernels without CONFIG_NVMEM
On 2/18/2021 2:05 AM, Jonathan Marek wrote: On 2/17/21 3:18 PM, Rob Clark wrote: On Wed, Feb 17, 2021 at 11:08 AM Jordan Crouse wrote: On Wed, Feb 17, 2021 at 07:14:16PM +0530, Akhil P Oommen wrote: On 2/17/2021 8:36 AM, Rob Clark wrote: On Tue, Feb 16, 2021 at 12:10 PM Jonathan Marek wrote: Ignore nvmem_cell_get() EOPNOTSUPP error in the same way as a ENOENT error, to fix the case where the kernel was compiled without CONFIG_NVMEM. Fixes: fe7952c629da ("drm/msm: Add speed-bin support to a618 gpu") Signed-off-by: Jonathan Marek --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index ba8e9d3cf0fe..7fe5d97606aa 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1356,10 +1356,10 @@ static int a6xx_set_supported_hw(struct device *dev, struct a6xx_gpu *a6xx_gpu, cell = nvmem_cell_get(dev, "speed_bin"); /* - * -ENOENT means that the platform doesn't support speedbin which is - * fine + * -ENOENT means no speed bin in device tree, + * -EOPNOTSUPP means kernel was built without CONFIG_NVMEM very minor nit, it would be nice to at least preserve the gist of the "which is fine" (ie. some variation of "this is an optional thing and things won't catch fire without it" ;-)) (which is, I believe, is true, hopefully Akhil could confirm.. if not we should have a harder dependency on CONFIG_NVMEM..) IIRC, if the gpu opp table in the DT uses the 'opp-supported-hw' property, we will see some error during boot up if we don't call dev_pm_opp_set_supported_hw(). So calling "nvmem_cell_get(dev, "speed_bin")" is a way to test this. If there is no other harm, we can put a hard dependency on CONFIG_NVMEM. I'm not sure if we want to go this far given the squishiness about module dependencies. As far as I know we are the only driver that uses this seriously on QCOM SoCs and this is only needed for certain targets. I don't know if we want to force every target to build NVMEM and QFPROM on our behalf. But maybe I'm just saying that because Kconfig dependencies tend to break my brain (and then Arnd has to send a patch to fix it). Hmm, good point.. looks like CONFIG_NVMEM itself doesn't have any other dependencies, so I suppose it wouldn't be the end of the world to select that.. but I guess we don't want to require QFPROM I guess at the end of the day, what is the failure mode if you have a speed-bin device, but your kernel config misses QFPROM (and possibly NVMEM)? If the result is just not having the highest clk rate(s) Atleast on sc7180's gpu, using an unsupported FMAX breaks gmu. It won't be very obvious what went wrong when this happens! -Akhil. available, that isn't the end of the world. But if it makes things not-work, that is sub-optimal. Generally, especially on ARM, kconfig seems to be way harder than it should be to build a kernel that works, if we could somehow not add to that problem (for both people with a6xx and older gens) that would be nice ;-) There is a "imply" kconfig option which solves exactly this problem. (you would "imply NVMEM" instead of "select NVMEM". then it would be possible to disable NVMEM but it would get enabled by default) BR, -R ___ dri-devel mailing list dri-de...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH] drm/msm/a6xx: fix for kernels without CONFIG_NVMEM
On 2/18/2021 9:41 PM, Rob Clark wrote: On Thu, Feb 18, 2021 at 4:28 AM Akhil P Oommen wrote: On 2/18/2021 2:05 AM, Jonathan Marek wrote: On 2/17/21 3:18 PM, Rob Clark wrote: On Wed, Feb 17, 2021 at 11:08 AM Jordan Crouse wrote: On Wed, Feb 17, 2021 at 07:14:16PM +0530, Akhil P Oommen wrote: On 2/17/2021 8:36 AM, Rob Clark wrote: On Tue, Feb 16, 2021 at 12:10 PM Jonathan Marek wrote: Ignore nvmem_cell_get() EOPNOTSUPP error in the same way as a ENOENT error, to fix the case where the kernel was compiled without CONFIG_NVMEM. Fixes: fe7952c629da ("drm/msm: Add speed-bin support to a618 gpu") Signed-off-by: Jonathan Marek --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index ba8e9d3cf0fe..7fe5d97606aa 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1356,10 +1356,10 @@ static int a6xx_set_supported_hw(struct device *dev, struct a6xx_gpu *a6xx_gpu, cell = nvmem_cell_get(dev, "speed_bin"); /* -* -ENOENT means that the platform doesn't support speedbin which is -* fine +* -ENOENT means no speed bin in device tree, +* -EOPNOTSUPP means kernel was built without CONFIG_NVMEM very minor nit, it would be nice to at least preserve the gist of the "which is fine" (ie. some variation of "this is an optional thing and things won't catch fire without it" ;-)) (which is, I believe, is true, hopefully Akhil could confirm.. if not we should have a harder dependency on CONFIG_NVMEM..) IIRC, if the gpu opp table in the DT uses the 'opp-supported-hw' property, we will see some error during boot up if we don't call dev_pm_opp_set_supported_hw(). So calling "nvmem_cell_get(dev, "speed_bin")" is a way to test this. If there is no other harm, we can put a hard dependency on CONFIG_NVMEM. I'm not sure if we want to go this far given the squishiness about module dependencies. As far as I know we are the only driver that uses this seriously on QCOM SoCs and this is only needed for certain targets. I don't know if we want to force every target to build NVMEM and QFPROM on our behalf. But maybe I'm just saying that because Kconfig dependencies tend to break my brain (and then Arnd has to send a patch to fix it). Hmm, good point.. looks like CONFIG_NVMEM itself doesn't have any other dependencies, so I suppose it wouldn't be the end of the world to select that.. but I guess we don't want to require QFPROM I guess at the end of the day, what is the failure mode if you have a speed-bin device, but your kernel config misses QFPROM (and possibly NVMEM)? If the result is just not having the highest clk rate(s) Atleast on sc7180's gpu, using an unsupported FMAX breaks gmu. It won't be very obvious what went wrong when this happens! Ugg, ok.. I suppose we could select NVMEM, but not QFPROM, and then the case where QFPROM is not enabled on platforms that have the speed-bin field in DT will fail gracefully and all other platforms would continue on happily? BR, -R Sounds good to me. -Akhil. available, that isn't the end of the world. But if it makes things not-work, that is sub-optimal. Generally, especially on ARM, kconfig seems to be way harder than it should be to build a kernel that works, if we could somehow not add to that problem (for both people with a6xx and older gens) that would be nice ;-) There is a "imply" kconfig option which solves exactly this problem. (you would "imply NVMEM" instead of "select NVMEM". then it would be possible to disable NVMEM but it would get enabled by default) BR, -R ___ dri-devel mailing list dri-de...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH] drm/msm/a6xx: fix for kernels without CONFIG_NVMEM
On 2/19/2021 9:30 PM, Rob Clark wrote: On Fri, Feb 19, 2021 at 2:44 AM Akhil P Oommen wrote: On 2/18/2021 9:41 PM, Rob Clark wrote: On Thu, Feb 18, 2021 at 4:28 AM Akhil P Oommen wrote: On 2/18/2021 2:05 AM, Jonathan Marek wrote: On 2/17/21 3:18 PM, Rob Clark wrote: On Wed, Feb 17, 2021 at 11:08 AM Jordan Crouse wrote: On Wed, Feb 17, 2021 at 07:14:16PM +0530, Akhil P Oommen wrote: On 2/17/2021 8:36 AM, Rob Clark wrote: On Tue, Feb 16, 2021 at 12:10 PM Jonathan Marek wrote: Ignore nvmem_cell_get() EOPNOTSUPP error in the same way as a ENOENT error, to fix the case where the kernel was compiled without CONFIG_NVMEM. Fixes: fe7952c629da ("drm/msm: Add speed-bin support to a618 gpu") Signed-off-by: Jonathan Marek --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index ba8e9d3cf0fe..7fe5d97606aa 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1356,10 +1356,10 @@ static int a6xx_set_supported_hw(struct device *dev, struct a6xx_gpu *a6xx_gpu, cell = nvmem_cell_get(dev, "speed_bin"); /* -* -ENOENT means that the platform doesn't support speedbin which is -* fine +* -ENOENT means no speed bin in device tree, +* -EOPNOTSUPP means kernel was built without CONFIG_NVMEM very minor nit, it would be nice to at least preserve the gist of the "which is fine" (ie. some variation of "this is an optional thing and things won't catch fire without it" ;-)) (which is, I believe, is true, hopefully Akhil could confirm.. if not we should have a harder dependency on CONFIG_NVMEM..) IIRC, if the gpu opp table in the DT uses the 'opp-supported-hw' property, we will see some error during boot up if we don't call dev_pm_opp_set_supported_hw(). So calling "nvmem_cell_get(dev, "speed_bin")" is a way to test this. If there is no other harm, we can put a hard dependency on CONFIG_NVMEM. I'm not sure if we want to go this far given the squishiness about module dependencies. As far as I know we are the only driver that uses this seriously on QCOM SoCs and this is only needed for certain targets. I don't know if we want to force every target to build NVMEM and QFPROM on our behalf. But maybe I'm just saying that because Kconfig dependencies tend to break my brain (and then Arnd has to send a patch to fix it). Hmm, good point.. looks like CONFIG_NVMEM itself doesn't have any other dependencies, so I suppose it wouldn't be the end of the world to select that.. but I guess we don't want to require QFPROM I guess at the end of the day, what is the failure mode if you have a speed-bin device, but your kernel config misses QFPROM (and possibly NVMEM)? If the result is just not having the highest clk rate(s) Atleast on sc7180's gpu, using an unsupported FMAX breaks gmu. It won't be very obvious what went wrong when this happens! Ugg, ok.. I suppose we could select NVMEM, but not QFPROM, and then the case where QFPROM is not enabled on platforms that have the speed-bin field in DT will fail gracefully and all other platforms would continue on happily? BR, -R Sounds good to me. You probably should do a quick test with NVMEM enabled but QFPROM disabled to confirm my theory, but I *think* that should work BR, -R I tried it on an sc7180 device. The suggested combo (CONFIG_NVMEM + no CONFIG_QCOM_QFPROM) makes the gpu probe fail with error "failed to read speed-bin. Some OPPs may not be supported by hardware". This is good enough clue for the developer that he should fix the broken speedbin detection. -Akhil. ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH] drm/msm: Fix removal of valid error case when checking speed_bin
On 3/30/2021 7:04 AM, John Stultz wrote: Commit 7bf168c8fe8c ("drm/msm: Fix speed-bin support not to access outside valid memory"), reworked the nvmem reading of "speed_bin", but in doing so dropped handling of the -ENOENT case which was previously documented as "fine". That change resulted in the db845c board display to fail to start, with the following error: adreno 500.gpu: [drm:a6xx_gpu_init] *ERROR* failed to read speed-bin (-2). Some OPPs may not be supported by hardware Thus, this patch simply re-adds the ENOENT handling so the lack of the speed_bin entry isn't fatal for display, and gets things working on db845c. Cc: Rob Clark Cc: Sean Paul Cc: Jordan Crouse Cc: Eric Anholt Cc: Douglas Anderson Cc: linux-arm-...@vger.kernel.org Cc: freedreno@lists.freedesktop.org Cc: Bjorn Andersson Cc: YongQin Liu Reported-by: YongQin Liu Fixes: 7bf168c8fe8c ("drm/msm: Fix speed-bin support not to access outside valid memory") Signed-off-by: John Stultz --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 690409ca8a186..cb2df8736ca85 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1406,7 +1406,13 @@ static int a6xx_set_supported_hw(struct device *dev, struct a6xx_gpu *a6xx_gpu, int ret; ret = nvmem_cell_read_u16(dev, "speed_bin", &speedbin); - if (ret) { + /* +* -ENOENT means that the platform doesn't support speedbin which is +* fine +*/ + if (ret == -ENOENT) { + return 0; + } else if (ret) { DRM_DEV_ERROR(dev, "failed to read speed-bin (%d). Some OPPs may not be supported by hardware", ret); Reviewed-by: Akhil P Oommen This looks "fine" to me. ;) -Akhil. ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH] drm/msm/a6xx: fix for kernels without CONFIG_NVMEM
On 4/2/2021 3:19 AM, Rob Clark wrote: On Thu, Apr 1, 2021 at 2:03 PM Dmitry Baryshkov wrote: On Thu, 1 Apr 2021 at 23:09, Rob Clark wrote: On Mon, Feb 22, 2021 at 8:06 AM Rob Clark wrote: On Mon, Feb 22, 2021 at 7:45 AM Akhil P Oommen wrote: On 2/19/2021 9:30 PM, Rob Clark wrote: On Fri, Feb 19, 2021 at 2:44 AM Akhil P Oommen wrote: On 2/18/2021 9:41 PM, Rob Clark wrote: On Thu, Feb 18, 2021 at 4:28 AM Akhil P Oommen wrote: On 2/18/2021 2:05 AM, Jonathan Marek wrote: On 2/17/21 3:18 PM, Rob Clark wrote: On Wed, Feb 17, 2021 at 11:08 AM Jordan Crouse wrote: On Wed, Feb 17, 2021 at 07:14:16PM +0530, Akhil P Oommen wrote: On 2/17/2021 8:36 AM, Rob Clark wrote: On Tue, Feb 16, 2021 at 12:10 PM Jonathan Marek wrote: Ignore nvmem_cell_get() EOPNOTSUPP error in the same way as a ENOENT error, to fix the case where the kernel was compiled without CONFIG_NVMEM. Fixes: fe7952c629da ("drm/msm: Add speed-bin support to a618 gpu") Signed-off-by: Jonathan Marek --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index ba8e9d3cf0fe..7fe5d97606aa 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1356,10 +1356,10 @@ static int a6xx_set_supported_hw(struct device *dev, struct a6xx_gpu *a6xx_gpu, cell = nvmem_cell_get(dev, "speed_bin"); /* -* -ENOENT means that the platform doesn't support speedbin which is -* fine +* -ENOENT means no speed bin in device tree, +* -EOPNOTSUPP means kernel was built without CONFIG_NVMEM very minor nit, it would be nice to at least preserve the gist of the "which is fine" (ie. some variation of "this is an optional thing and things won't catch fire without it" ;-)) (which is, I believe, is true, hopefully Akhil could confirm.. if not we should have a harder dependency on CONFIG_NVMEM..) IIRC, if the gpu opp table in the DT uses the 'opp-supported-hw' property, we will see some error during boot up if we don't call dev_pm_opp_set_supported_hw(). So calling "nvmem_cell_get(dev, "speed_bin")" is a way to test this. If there is no other harm, we can put a hard dependency on CONFIG_NVMEM. I'm not sure if we want to go this far given the squishiness about module dependencies. As far as I know we are the only driver that uses this seriously on QCOM SoCs and this is only needed for certain targets. I don't know if we want to force every target to build NVMEM and QFPROM on our behalf. But maybe I'm just saying that because Kconfig dependencies tend to break my brain (and then Arnd has to send a patch to fix it). Hmm, good point.. looks like CONFIG_NVMEM itself doesn't have any other dependencies, so I suppose it wouldn't be the end of the world to select that.. but I guess we don't want to require QFPROM I guess at the end of the day, what is the failure mode if you have a speed-bin device, but your kernel config misses QFPROM (and possibly NVMEM)? If the result is just not having the highest clk rate(s) Atleast on sc7180's gpu, using an unsupported FMAX breaks gmu. It won't be very obvious what went wrong when this happens! Ugg, ok.. I suppose we could select NVMEM, but not QFPROM, and then the case where QFPROM is not enabled on platforms that have the speed-bin field in DT will fail gracefully and all other platforms would continue on happily? BR, -R Sounds good to me. You probably should do a quick test with NVMEM enabled but QFPROM disabled to confirm my theory, but I *think* that should work BR, -R I tried it on an sc7180 device. The suggested combo (CONFIG_NVMEM + no CONFIG_QCOM_QFPROM) makes the gpu probe fail with error "failed to read speed-bin. Some OPPs may not be supported by hardware". This is good enough clue for the developer that he should fix the broken speedbin detection. Ok, great.. then sounds like selecting NVMEM is a good approach btw, did anyone ever send a patch to select NVMEM? I'm not seeing one but I could be overlooking something I thought Jonathan would send it as the discussion was going on in his patch. No problem, I will send it out. :) -Akhil. Judging by the amount of issues surrounding speed-bin, I might have a bold suggestion to revert these patches for now and get them once all the issues are sorted, so that we'd have a single working commit instead of scattered patch series breaking git bisect, having bad side-effects on non-sc7180 platforms, etc. We do really need some pre-merge CI like we have on the mesa side of things (and we at least have 845 devices in our CI farm, but it would be useful to add more generations).. but other than the config issue, I *think* this fixes the last of the spe
[Freedreno] [PATCH 1/2] drm/msm/a6xx: Fix perfcounter oob timeout
We were not programing the correct bit while clearing the perfcounter oob. So, clear it correctly using the new 'clear' bit. This fixes the below error: [drm:a6xx_gmu_set_oob] *ERROR* Timeout waiting for GMU OOB set PERFCOUNTER: 0x8000 Signed-off-by: Akhil P Oommen --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 12 +--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 863047b..6a86cd0 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -246,7 +246,7 @@ static int a6xx_gmu_hfi_start(struct a6xx_gmu *gmu) } struct a6xx_gmu_oob_bits { - int set, ack, set_new, ack_new; + int set, ack, set_new, ack_new, clear, clear_new; const char *name; }; @@ -260,6 +260,8 @@ static const struct a6xx_gmu_oob_bits a6xx_gmu_oob_bits[] = { .ack = 24, .set_new = 30, .ack_new = 31, + .clear = 24, + .clear_new = 31, }, [GMU_OOB_PERFCOUNTER_SET] = { @@ -268,18 +270,22 @@ static const struct a6xx_gmu_oob_bits a6xx_gmu_oob_bits[] = { .ack = 25, .set_new = 28, .ack_new = 30, + .clear = 25, + .clear_new = 29, }, [GMU_OOB_BOOT_SLUMBER] = { .name = "BOOT_SLUMBER", .set = 22, .ack = 30, + .clear = 30, }, [GMU_OOB_DCVS_SET] = { .name = "GPU_DCVS", .set = 23, .ack = 31, + .clear = 31, }, }; @@ -335,9 +341,9 @@ void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state) return; if (gmu->legacy) - bit = a6xx_gmu_oob_bits[state].ack; + bit = a6xx_gmu_oob_bits[state].clear; else - bit = a6xx_gmu_oob_bits[state].ack_new; + bit = a6xx_gmu_oob_bits[state].clear_new; gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET, 1 << bit); } -- 2.7.4 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH 2/2] drm/msm: Select CONFIG_NVMEM
The speedbin support requires nvmem driver api. So lets explicitly enable CONFIG_NVMEM to have this support. Signed-off-by: Akhil P Oommen --- drivers/gpu/drm/msm/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index dabb4a1..d12fa35 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -20,6 +20,7 @@ config DRM_MSM select SND_SOC_HDMI_CODEC if SND_SOC select SYNC_FILE select PM_OPP + select NVMEM help DRM/KMS driver for MSM/snapdragon. -- 2.7.4 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH] freedreno/a6xx: Add a few registers
Add a few new registers for a6xx gpu. Signed-off-by: Akhil P Oommen --- registers/adreno/a6xx.xml | 2 ++ registers/adreno/a6xx_gmu.xml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/registers/adreno/a6xx.xml b/registers/adreno/a6xx.xml index 15314fb..3b04565 100644 --- a/registers/adreno/a6xx.xml +++ b/registers/adreno/a6xx.xml @@ -1107,6 +1107,7 @@ to upconvert to 32b float internally? + @@ -1740,6 +1741,7 @@ to upconvert to 32b float internally? + diff --git a/registers/adreno/a6xx_gmu.xml b/registers/adreno/a6xx_gmu.xml index dbefd0c..f8bf1fd 100644 --- a/registers/adreno/a6xx_gmu.xml +++ b/registers/adreno/a6xx_gmu.xml @@ -112,6 +112,7 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd"> + @@ -193,6 +194,7 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd"> + -- 2.7.4 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH] freedreno/a6xx: Add a few registers
Add a few new registers for a6xx gpu. Signed-off-by: Akhil P Oommen --- registers/adreno/a6xx.xml | 2 ++ registers/adreno/a6xx_gmu.xml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/registers/adreno/a6xx.xml b/registers/adreno/a6xx.xml index 15314fb..3b04565 100644 --- a/registers/adreno/a6xx.xml +++ b/registers/adreno/a6xx.xml @@ -1107,6 +1107,7 @@ to upconvert to 32b float internally? + @@ -1740,6 +1741,7 @@ to upconvert to 32b float internally? + diff --git a/registers/adreno/a6xx_gmu.xml b/registers/adreno/a6xx_gmu.xml index dbefd0c..f8bf1fd 100644 --- a/registers/adreno/a6xx_gmu.xml +++ b/registers/adreno/a6xx_gmu.xml @@ -112,6 +112,7 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd"> + @@ -193,6 +194,7 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd"> + -- 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
Re: [Freedreno] [PATCH v2 2/8] drm/msm/a6xx: use AOP-initialized PDC for a650
On 5/13/2021 10:43 PM, Jonathan Marek wrote: SM8250 AOP firmware already sets up PDC registers for us, and it only needs to be enabled. This path will be used for other newer GPUs. Signed-off-by: Jonathan Marek --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 21 - 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 3d55e153fa9c..c1ee02d6371d 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -512,19 +512,26 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu) struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; struct platform_device *pdev = to_platform_device(gmu->dev); void __iomem *pdcptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc"); - void __iomem *seqptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc_seq"); + void __iomem *seqptr; uint32_t pdc_address_offset; + bool pdc_in_aop = false; - if (!pdcptr || !seqptr) + if (!pdcptr) goto err; - if (adreno_is_a618(adreno_gpu) || adreno_is_a640(adreno_gpu)) + if (adreno_is_a650(adreno_gpu)) + pdc_in_aop = true; + else if (adreno_is_a618(adreno_gpu) || adreno_is_a640(adreno_gpu)) pdc_address_offset = 0x30090; - else if (adreno_is_a650(adreno_gpu)) - pdc_address_offset = 0x300a0; else pdc_address_offset = 0x30080; + if (!pdc_in_aop) { + seqptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc_seq"); + if (!seqptr) + goto err; + } + /* Disable SDE clock gating */ gmu_write_rscc(gmu, REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0, BIT(24)); @@ -556,6 +563,9 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu) gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 4, 0x0020e8a8); } + if (pdc_in_aop) + goto setup_pdc; + /* Load PDC sequencer uCode for power up and power down sequence */ pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0, 0xfebea1e1); pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0 + 1, 0xa5a4a3a2); @@ -596,6 +606,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu) pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 8, 0x3); /* Setup GPU PDC */ +setup_pdc: pdc_write(pdcptr, REG_A6XX_PDC_GPU_SEQ_START_ADDR, 0); pdc_write(pdcptr, REG_A6XX_PDC_GPU_ENABLE_PDC, 0x8001); We can simply swap the order of PDC and rsc programming here and skip pdc sequence to jump to the rscc programming for a650. This is the order followed in the downstream driver anyway. -Akhil. ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH v2 1/8] drm/msm: remove unused icc_path/ocmem_icc_path
On 5/13/2021 10:43 PM, Jonathan Marek wrote: These aren't used by anything anymore. Signed-off-by: Jonathan Marek --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 3 --- drivers/gpu/drm/msm/msm_gpu.h | 9 - 2 files changed, 12 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 8fd0777f2dc9..009f4c560f16 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -946,7 +946,4 @@ void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu) pm_runtime_disable(&priv->gpu_pdev->dev); msm_gpu_cleanup(&adreno_gpu->base); - - icc_put(gpu->icc_path); - icc_put(gpu->ocmem_icc_path); } diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 18baf935e143..c302ab7ffb06 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -118,15 +118,6 @@ struct msm_gpu { struct clk *ebi1_clk, *core_clk, *rbbmtimer_clk; uint32_t fast_rate; - /* The gfx-mem interconnect path that's used by all GPU types. */ - struct icc_path *icc_path; - - /* -* Second interconnect path for some A3xx and all A4xx GPUs to the -* On Chip MEMory (OCMEM). -*/ - struct icc_path *ocmem_icc_path; - /* Hang and Inactivity Detection: */ #define DRM_MSM_INACTIVE_PERIOD 66 /* in ms (roughly four frames) */ Reviewed-by: Akhil P Oommen -Akhil. ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH v2 3/8] drm/msm/a6xx: fix incorrectly set uavflagprd_inv field for A650
On 5/13/2021 10:43 PM, Jonathan Marek wrote: Value was shifted in the wrong direction, resulting in the field always being zero, which is incorrect for A650. Fixes: d0bac4e9cd66 ("drm/msm/a6xx: set ubwc config for A640 and A650") Signed-off-by: Jonathan Marek --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 727d111a413f..45a6a0fce7d7 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -489,7 +489,7 @@ static void a6xx_set_ubwc_config(struct msm_gpu *gpu) rgb565_predicator << 11 | amsbc << 4 | lower_bit << 1); gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL, lower_bit << 1); gpu_write(gpu, REG_A6XX_SP_NC_MODE_CNTL, - uavflagprd_inv >> 4 | lower_bit << 1); + uavflagprd_inv << 4 | lower_bit << 1); gpu_write(gpu, REG_A6XX_UCHE_MODE_CNTL, lower_bit << 21); } Reviewed-by: Akhil P Oommen -Akhil. ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH v2 4/8] drm/msm/a6xx: update/fix CP_PROTECT initialization
om the start +* address all the way to the end of the register address space +*/ + gpu_write(gpu, REG_A6XX_CP_PROTECT_CNTL, BIT(0) | BIT(1) | BIT(3)); + + for (i = 0; i < count - 1; i++) + gpu_write(gpu, REG_A6XX_CP_PROTECT(i), regs[i]); + /* last CP_PROTECT to have "infinite" length on the last entry */ + gpu_write(gpu, REG_A6XX_CP_PROTECT(count_max - 1), regs[i]); +} + static void a6xx_set_ubwc_config(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); @@ -776,41 +883,7 @@ static int a6xx_hw_init(struct msm_gpu *gpu) } /* Protect registers from the CP */ - gpu_write(gpu, REG_A6XX_CP_PROTECT_CNTL, 0x0003); - - gpu_write(gpu, REG_A6XX_CP_PROTECT(0), - A6XX_PROTECT_RDONLY(0x600, 0x51)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(1), A6XX_PROTECT_RW(0xae50, 0x2)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(2), A6XX_PROTECT_RW(0x9624, 0x13)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(3), A6XX_PROTECT_RW(0x8630, 0x8)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(4), A6XX_PROTECT_RW(0x9e70, 0x1)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(5), A6XX_PROTECT_RW(0x9e78, 0x187)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(6), A6XX_PROTECT_RW(0xf000, 0x810)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(7), - A6XX_PROTECT_RDONLY(0xfc00, 0x3)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(8), A6XX_PROTECT_RW(0x50e, 0x0)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(9), A6XX_PROTECT_RDONLY(0x50f, 0x0)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(10), A6XX_PROTECT_RW(0x510, 0x0)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(11), - A6XX_PROTECT_RDONLY(0x0, 0x4f9)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(12), - A6XX_PROTECT_RDONLY(0x501, 0xa)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(13), - A6XX_PROTECT_RDONLY(0x511, 0x44)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(14), A6XX_PROTECT_RW(0xe00, 0xe)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(15), A6XX_PROTECT_RW(0x8e00, 0x0)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(16), A6XX_PROTECT_RW(0x8e50, 0xf)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(17), A6XX_PROTECT_RW(0xbe02, 0x0)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(18), - A6XX_PROTECT_RW(0xbe20, 0x11f3)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(19), A6XX_PROTECT_RW(0x800, 0x82)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(20), A6XX_PROTECT_RW(0x8a0, 0x8)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(21), A6XX_PROTECT_RW(0x8ab, 0x19)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(22), A6XX_PROTECT_RW(0x900, 0x4d)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(23), A6XX_PROTECT_RW(0x98d, 0x76)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(24), - A6XX_PROTECT_RDONLY(0x980, 0x4)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(25), A6XX_PROTECT_RW(0xa630, 0x0)); + a6xx_set_cp_protect(gpu); /* Enable expanded apriv for targets that support it */ if (gpu->hw_apriv) { diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h index ce0610c5256f..bb544dfe5737 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h @@ -44,7 +44,7 @@ struct a6xx_gpu { * REG_CP_PROTECT_REG(n) - this will block both reads and writes for _len * registers starting at _reg. */ -#define A6XX_PROTECT_RW(_reg, _len) \ +#define A6XX_PROTECT_NORDWR(_reg, _len) \ ((1 << 31) | \ (((_len) & 0x3FFF) << 18) | ((_reg) & 0x3)) Reviewed-by: Akhil P Oommen -Akhil ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH v2 5/8] drm/msm/a6xx: avoid shadow NULL reference in failure path
On 5/13/2021 10:44 PM, Jonathan Marek wrote: If a6xx_hw_init() fails before creating the shadow_bo, the a6xx_pm_suspend code referencing it will crash. Change the condition to one that avoids this problem (note: creation of shadow_bo is behind this same condition) Fixes: e8b0b994c3a5 ("drm/msm/a6xx: Clear shadow on suspend") Signed-off-by: Jonathan Marek --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 909e3ff08f89..ff3c328604f8 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1284,7 +1284,7 @@ static int a6xx_pm_suspend(struct msm_gpu *gpu) if (ret) return ret; - if (adreno_gpu->base.hw_apriv || a6xx_gpu->has_whereami) + if (a6xx_gpu->shadow_bo) for (i = 0; i < gpu->nr_rings; i++) a6xx_gpu->shadow[i] = 0; Reviewed-by: Akhil P Oommen -Akhil ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH v2 6/8] drm/msm/a6xx: add support for Adreno 660 GPU
On 5/13/2021 10:44 PM, Jonathan Marek wrote: Add adreno_is_{a660,a650_family} helpers and convert update existing adreno_is_a650 usage based on downstream driver's logic (changing into adreno_is_a650_family or adding adreno_is_a660). And add the remaining changes required for A660, again based on the downstream driver: missing GMU allocations, additional register init, dummy hfi BW table, cp protect list, entry in gpulist table. Signed-off-by: Jonathan Marek --- drivers/gpu/drm/msm/adreno/a6xx.xml.h | 4 ++ drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 32 +++--- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 73 +++--- drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 33 ++ drivers/gpu/drm/msm/adreno/adreno_device.c | 12 drivers/gpu/drm/msm/adreno/adreno_gpu.c| 2 +- drivers/gpu/drm/msm/adreno/adreno_gpu.h| 12 7 files changed, 152 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx.xml.h b/drivers/gpu/drm/msm/adreno/a6xx.xml.h index 920c5e6b8e96..631c36672560 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx.xml.h +++ b/drivers/gpu/drm/msm/adreno/a6xx.xml.h @@ -2240,6 +2240,8 @@ static inline uint32_t A6XX_DBGC_CFG_DBGBUS_BYTEL_1_BYTEL15(uint32_t val) #define REG_A6XX_DBGC_CFG_DBGBUS_TRACE_BUF2 0x0630 +#define REG_A6XX_CP_LPAC_PROG_FIFO_SIZE 0x0b34 + #define REG_A6XX_VSC_PERFCTR_VSC_SEL_0 0x0cd8 #define REG_A6XX_VSC_PERFCTR_VSC_SEL_10x0cd9 @@ -2340,6 +2342,8 @@ static inline uint32_t A6XX_UCHE_CLIENT_PF_PERFSEL(uint32_t val) #define REG_A6XX_UCHE_PERFCTR_UCHE_SEL_11 0x0e27 +#define REG_A6XX_UCHE_CMDQ_CONFIG 0x0e3c + #define REG_A6XX_SP_ADDR_MODE_CNTL0xae01 #define REG_A6XX_SP_NC_MODE_CNTL0xae02 diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index c1ee02d6371d..91052a661c6e 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -519,7 +519,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu) if (!pdcptr) goto err; - if (adreno_is_a650(adreno_gpu)) + if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu)) why not adreno_is_a650_family() here? pdc_in_aop = true; else if (adreno_is_a618(adreno_gpu) || adreno_is_a640(adreno_gpu)) pdc_address_offset = 0x30090; @@ -549,7 +549,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu) gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_HI, 0x4514); /* Load RSC sequencer uCode for sleep and wakeup */ - if (adreno_is_a650(adreno_gpu)) { + if (adreno_is_a650_family(adreno_gpu)) { gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0, 0xeaaae5a0); gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 1, 0xe1a1ebab); gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 2, 0xa2e0a581); @@ -597,7 +597,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu) pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_MSGID + 4, 0x10108); pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR + 4, 0x3); - if (adreno_is_a618(adreno_gpu) || adreno_is_a650(adreno_gpu)) + if (adreno_is_a618(adreno_gpu) || adreno_is_a650_family(adreno_gpu)) pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 4, 0x2); else pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 4, 0x3); @@ -698,7 +698,7 @@ static int a6xx_gmu_fw_load(struct a6xx_gmu *gmu) u32 itcm_base = 0x; u32 dtcm_base = 0x0004; - if (adreno_is_a650(adreno_gpu)) + if (adreno_is_a650_family(adreno_gpu)) dtcm_base = 0x10004000; if (gmu->legacy) { @@ -751,7 +751,7 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state) int ret; u32 chipid; We need to program this register here: gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_CX_FALNEXT_INTF, 1); - if (adreno_is_a650(adreno_gpu)) + if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu)) gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_CX_FAL_INTF, 1); if (state == GMU_WARM_BOOT) { @@ -1494,12 +1494,28 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) if (ret) goto err_put_device; + + /* A660 now requires handling "prealloc requests" in GMU firmware +* For now just hardcode allocations based on the known firmware. +* note: there is no indication that these correspond to "dummy" or +* "debug" regions, but this "guess" allows reusing these BOs which +* are otherwise unused by a660. +*/ + gmu->dummy.size = SZ_4K; + if (adreno_is_a660(adreno_gpu)) { + ret = a6xx_gmu_memory_alloc(gmu, &gmu->debug, SZ_4K * 7, 0x6040
Re: [Freedreno] [PATCH v2 7/8] drm/msm/a6xx: update a6xx_ucode_check_version for a660
On 5/13/2021 10:44 PM, Jonathan Marek wrote: Accept all SQE firmware versions for A660. Re-organize the function a bit and print an error message for unexpected GPU IDs instead of failing silently. Signed-off-by: Jonathan Marek --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 36 +-- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 3cc23057b11d..ec66a24fc37e 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -697,6 +697,11 @@ static bool a6xx_ucode_check_version(struct a6xx_gpu *a6xx_gpu, * Targets up to a640 (a618, a630 and a640) need to check for a * microcode version that is patched to support the whereami opcode or * one that is new enough to include it by default. +* +* a650 tier targets don't need whereami but still need to be +* equal to or newer than 0.95 for other security fixes +* +* a660 targets have all the critical security fixes from the start */ if (adreno_is_a618(adreno_gpu) || adreno_is_a630(adreno_gpu) || adreno_is_a640(adreno_gpu)) { @@ -720,27 +725,20 @@ static bool a6xx_ucode_check_version(struct a6xx_gpu *a6xx_gpu, DRM_DEV_ERROR(&gpu->pdev->dev, "a630 SQE ucode is too old. Have version %x need at least %x\n", buf[0] & 0xfff, 0x190); - } else { - /* -* a650 tier targets don't need whereami but still need to be -* equal to or newer than 0.95 for other security fixes -*/ - if (adreno_is_a650(adreno_gpu)) { - if ((buf[0] & 0xfff) >= 0x095) { - ret = true; - goto out; - } - - DRM_DEV_ERROR(&gpu->pdev->dev, - "a650 SQE ucode is too old. Have version %x need at least %x\n", - buf[0] & 0xfff, 0x095); + } else if (adreno_is_a650(adreno_gpu)) { + if ((buf[0] & 0xfff) >= 0x095) { + ret = true; + goto out; } - /* -* When a660 is added those targets should return true here -* since those have all the critical security fixes built in -* from the start -*/ + DRM_DEV_ERROR(&gpu->pdev->dev, + "a650 SQE ucode is too old. Have version %x need at least %x\n", + buf[0] & 0xfff, 0x095); + } else if (adreno_is_a660(adreno_gpu)) { + ret = true; + } else { + DRM_DEV_ERROR(&gpu->pdev->dev, + "unknown GPU, add it to a6xx_ucode_check_version()!!\n"); } out: msm_gem_put_vaddr(obj); Can we squash this patch with the previous one? -Akhil. ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH v2 8/8] drm/msm/a6xx: add a660 hwcg table
On 5/13/2021 10:44 PM, Jonathan Marek wrote: Add a660 hwcg table, ported over from downstream. Signed-off-by: Jonathan Marek --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 53 ++ drivers/gpu/drm/msm/adreno/adreno_device.c | 1 + drivers/gpu/drm/msm/adreno/adreno_gpu.h| 2 +- 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index ec66a24fc37e..2713f69e916d 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -427,6 +427,59 @@ const struct adreno_reglist a650_hwcg[] = { {}, }; +const struct adreno_reglist a660_hwcg[] = { + {REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x0222}, + {REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x0220}, + {REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x0080}, + {REG_A6XX_RBBM_CLOCK_HYST_SP0, 0xF3CF}, + {REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x0002}, + {REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x0001}, + {REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x0007}, + {REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x}, + {REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x0100}, + {REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x2220}, + {REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040F00}, + {REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x25222022}, + {REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x}, + {REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x0011}, + {REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044}, + {REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x0422}, + {REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x}, + {REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x0022}, + {REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x0002}, + {REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x}, + {REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x4000}, + {REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x}, + {REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x0200}, + {REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x}, + {REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x}, + {REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x}, + {REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004}, + {REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x}, + {REG_A6XX_RBBM_CLOCK_CNTL_TEX_FCHE, 0x0222}, + {REG_A6XX_RBBM_CLOCK_DELAY_TEX_FCHE, 0x0111}, + {REG_A6XX_RBBM_CLOCK_HYST_TEX_FCHE, 0x}, + {REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x}, + {REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x0004}, + {REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x0002}, + {REG_A6XX_RBBM_ISDB_CNT, 0x0182}, + {REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x}, + {REG_A6XX_RBBM_SP_HYST_CNT, 0x}, + {REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x0222}, + {REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x0111}, + {REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x0555}, + {}, +}; + static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index e4db0683d381..6dad8015c9a1 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -299,6 +299,7 @@ static const struct adreno_info gpulist[] = { .inactive_period = DRM_MSM_INACTIVE_PERIOD, .init = a6xx_gpu_init, .zapfw = "a660_zap.mdt", + .hwcg = a660_hwcg, }, }; diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index 63c050919d85..e6b11e6ec82d 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -55,7 +55,7 @@ struct adreno_reglist { u32 value; }; -extern const struct adreno_reglist a630_hwcg[], a640_hwcg[], a650_hwcg[]; +extern const struct adreno_reglist a630_hwcg[], a640_hwcg[], a650_hwcg[], a660_hwcg[]; struct adreno_info { struct adreno_rev rev; squash with previous one? -Akhil ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH 3/3] drm/msm: Devfreq tuning
On 7/23/2021 3:51 AM, Rob Clark wrote: From: Rob Clark This adds a few things to try and make frequency scaling better match the workload: 1) Longer polling interval to avoid whip-lashing between too-high and too-low frequencies in certain workloads, like mobile games which throttle themselves to 30fps. Previously our polling interval was short enough to let things ramp down to minimum freq in the "off" frame, but long enough to not react quickly enough when rendering started on the next frame, leading to uneven frame times. (Ie. rather than a consistent 33ms it would alternate between 16/33/48ms.) 2) Awareness of when the GPU is active vs idle. Since we know when the GPU is active vs idle, we can clamp the frequency down to the minimum while it is idle. (If it is idle for long enough, then the autosuspend delay will eventually kick in and power down the GPU.) Since devfreq has no knowledge of powered-but-idle, this takes a small bit of trickery to maintain a "fake" frequency while idle. This, combined with the longer polling period allows devfreq to arrive at a reasonable "active" frequency, while still clamping to minimum freq when idle to reduce power draw. 3) Boost. Because simple_ondemand needs to see a certain threshold of busyness to ramp up, we could end up needing multiple polling cycles before it reacts appropriately on interactive workloads (ex. scrolling a web page after reading for some time), on top of the already lengthened polling interval, when we see a idle to active transition after a period of idle time we boost the frequency that we return to. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gpu.c | 8 +++ drivers/gpu/drm/msm/msm_gpu.h | 9 drivers/gpu/drm/msm/msm_gpu_devfreq.c | 73 ++- 3 files changed, 89 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 70d8610b1b73..68d2df590054 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -667,6 +667,10 @@ static void retire_submit(struct msm_gpu *gpu, struct msm_ringbuffer *ring, list_del(&submit->node); spin_unlock(&ring->submit_lock); + /* Update devfreq on transition from active->idle: */ + if (atomic_dec_return(&gpu->active_submits) == 0) This will race with the submit path. To avoid that, this test and the msm_devfreq_idle should be under the same lock. Same applies for the submit path. -Akhil + msm_devfreq_idle(gpu); + msm_gem_submit_put(submit); } @@ -747,6 +751,10 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) list_add_tail(&submit->node, &ring->submits); spin_unlock(&ring->submit_lock); + /* Update devfreq on transition from idle->active: */ + if (atomic_inc_return(&gpu->active_submits) == 1) + msm_devfreq_active(gpu); + gpu->funcs->submit(gpu, submit); priv->lastctx = submit->queue->ctx; diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index ada15e28f251..e14edda3d778 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -84,6 +84,10 @@ struct msm_gpu_devfreq { struct devfreq *devfreq; u64 busy_cycles; ktime_t time; + + /* Time and freq of last transition to idle: */ + ktime_t idle_time; + unsigned long idle_freq; }; struct msm_gpu { @@ -115,6 +119,9 @@ struct msm_gpu { */ struct list_head active_list; + /* number of in-flight submits: */ + atomic_t active_submits; + /* does gpu need hw_init? */ bool needs_hw_init; @@ -384,6 +391,8 @@ void msm_devfreq_init(struct msm_gpu *gpu); void msm_devfreq_cleanup(struct msm_gpu *gpu); void msm_devfreq_resume(struct msm_gpu *gpu); void msm_devfreq_suspend(struct msm_gpu *gpu); +void msm_devfreq_active(struct msm_gpu *gpu); +void msm_devfreq_idle(struct msm_gpu *gpu); int msm_gpu_hw_init(struct msm_gpu *gpu); diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c b/drivers/gpu/drm/msm/msm_gpu_devfreq.c index 2e24a97be624..0a1ee20296a2 100644 --- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c +++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c @@ -22,6 +22,15 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq, opp = devfreq_recommended_opp(dev, freq, flags); + /* +* If the GPU is idle, devfreq is not aware, so just ignore +* it's requests +*/ + if (gpu->devfreq.idle_freq) { + gpu->devfreq.idle_freq = *freq; + return 0; + } + if (IS_ERR(opp)) return PTR_ERR(opp); @@ -39,6 +48,9 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq, static unsigned long get_freq(struct msm_gpu *gpu) { + if (gpu->devfreq.idl
[Freedreno] [PATCH 1/2] drm/msm/a6xx: Fix llcc configuration for a660 gpu
Add the missing scache_cntl0 register programing which is required for a660 gpu. Signed-off-by: Akhil P Oommen --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 46 --- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 9c5e461..183b9f9 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1383,13 +1383,13 @@ static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu) { struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; struct msm_gpu *gpu = &adreno_gpu->base; - u32 cntl1_regval = 0; + u32 gpu_scid, cntl1_regval = 0; if (IS_ERR(a6xx_gpu->llc_mmio)) return; if (!llcc_slice_activate(a6xx_gpu->llc_slice)) { - u32 gpu_scid = llcc_get_slice_id(a6xx_gpu->llc_slice); + gpu_scid = llcc_get_slice_id(a6xx_gpu->llc_slice); gpu_scid &= 0x1f; cntl1_regval = (gpu_scid << 0) | (gpu_scid << 5) | (gpu_scid << 10) | @@ -1409,26 +1409,34 @@ static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu) } } - if (cntl1_regval) { + if (!cntl1_regval) + return; + + /* +* Program the slice IDs for the various GPU blocks and GPU MMU +* pagetables +*/ + if (!a6xx_gpu->have_mmu500) { + a6xx_llc_write(a6xx_gpu, + REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_1, cntl1_regval); + /* -* Program the slice IDs for the various GPU blocks and GPU MMU -* pagetables +* Program cacheability overrides to not allocate cache +* lines on a write miss */ - if (a6xx_gpu->have_mmu500) - gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL1, GENMASK(24, 0), - cntl1_regval); - else { - a6xx_llc_write(a6xx_gpu, - REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_1, cntl1_regval); - - /* -* Program cacheability overrides to not allocate cache -* lines on a write miss -*/ - a6xx_llc_rmw(a6xx_gpu, - REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_0, 0xF, 0x03); - } + a6xx_llc_rmw(a6xx_gpu, + REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_0, 0xF, 0x03); + return; } + + gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL1, GENMASK(24, 0), cntl1_regval); + + /* On A660, the SCID programming for UCHE traffic is done in +* A6XX_GBIF_SCACHE_CNTL0[14:10] +*/ + if (adreno_is_a660(adreno_gpu)) + gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL0, (0x1f << 10) | + (1 << 8), (gpu_scid << 10) | (1 << 8)); } static void a6xx_llc_slices_destroy(struct a6xx_gpu *a6xx_gpu) -- 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 2/2] drm/msm/a6xx: Add support for Adreno 7c Gen 3 gpu
This patch adds support for the gpu found in the Snapdragon 7c Gen 3 compute platform. This gpu is similar to the exisiting a660 gpu with minor delta in the programing sequence. As the Adreno GPUs are moving away from a numeric chipid based naming scheme to a string, it was decided to use 0x06030500 as the gpu id of this gpu to communicate to the userspace driver. Signed-off-by: Akhil P Oommen --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 20 ++- drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 1 + drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h | 2 ++ drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 21 ++-- drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 32 ++ drivers/gpu/drm/msm/adreno/adreno_device.c | 12 +++ drivers/gpu/drm/msm/adreno/adreno_gpu.h| 11 -- 7 files changed, 90 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index b349692..332301f 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -933,6 +933,7 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu) /* Use a known rate to bring up the GMU */ clk_set_rate(gmu->core_clk, 2); + clk_set_rate(gmu->hub_clk, 15000); ret = clk_bulk_prepare_enable(gmu->nr_clocks, gmu->clocks); if (ret) { pm_runtime_put(gmu->gxpd); @@ -1094,6 +1095,7 @@ static void a6xx_gmu_shutdown(struct a6xx_gmu *gmu) int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu) { + struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; struct a6xx_gmu *gmu = &a6xx_gpu->gmu; struct msm_gpu *gpu = &a6xx_gpu->base.base; @@ -1117,9 +1119,22 @@ int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu) * domain. Usually the GMU does this but only if the shutdown sequence * was successful */ - if (!IS_ERR_OR_NULL(gmu->gxpd)) + if (!IS_ERR_OR_NULL(gmu->gxpd)) { + /* +* Toggle the loop_en bit, across disabling the gx gdsc, +* with a delay of 10 XO cycles before disabling gx +* gdsc. This is to prevent CPR measurements from +* failing. +*/ + if (adreno_is_a660(adreno_gpu)) + gmu_rmw(gmu, REG_A6XX_GPU_CPR_FSM_CTL, 1, 0); + pm_runtime_put_sync(gmu->gxpd); + if (adreno_is_a660(adreno_gpu)) + gmu_rmw(gmu, REG_A6XX_GPU_CPR_FSM_CTL, 1, 1); + } + clk_bulk_disable_unprepare(gmu->nr_clocks, gmu->clocks); pm_runtime_put_sync(gmu->dev); @@ -1393,6 +1408,9 @@ static int a6xx_gmu_clocks_probe(struct a6xx_gmu *gmu) gmu->core_clk = msm_clk_bulk_get_clock(gmu->clocks, gmu->nr_clocks, "gmu"); + gmu->hub_clk = msm_clk_bulk_get_clock(gmu->clocks, + gmu->nr_clocks, "hub"); + return 0; } diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h index 71dfa600..3c74f64 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h @@ -66,6 +66,7 @@ struct a6xx_gmu { int nr_clocks; struct clk_bulk_data *clocks; struct clk *core_clk; + struct clk *hub_clk; /* current performance index set externally */ int current_perf_index; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h index 8115892..d46733f 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h @@ -479,5 +479,7 @@ static inline uint32_t A6XX_GMU_GPU_NAP_CTRL_SID(uint32_t val) #define REG_A6XX_RSCC_TCS3_DRV0_STATUS 0x053e +#define REG_A6XX_GPU_CPR_FSM_CTL 0xc001 + #endif /* A6XX_GMU_XML */ diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 183b9f9..c0882536 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -694,6 +694,13 @@ static void a6xx_set_ubwc_config(struct msm_gpu *gpu) uavflagprd_inv = 2; } + if (adreno_is_7c3(adreno_gpu)) { + lower_bit = 1; + amsbc = 1; + rgb565_predicator = 1; + uavflagprd_inv = 2; + } + gpu_write(gpu, REG_A6XX_RB_NC_MODE_CNTL, rgb565_predicator << 11 | amsbc << 4 | lower_bit << 1); gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL, lower_bit << 1); @@ -950,10 +957,10 @@ static int a6xx_hw_init(struct msm_gpu *gpu) /* Setting the primFifo thresholds default values, * and vccCacheSkipDis=1 bit (0x200) for A640 and newer */ - if (adreno_is
[Freedreno] [PATCH] arm64: dts: qcom: sc7280: Add gpu support
Add the necessary dt nodes for gpu support in sc7280. Signed-off-by: Akhil P Oommen --- This patch has dependency on the GPUCC bindings patch here: https://patchwork.kernel.org/project/linux-arm-msm/patch/1619519590-3019-4-git-send-email-t...@codeaurora.org/ arch/arm64/boot/dts/qcom/sc7280.dtsi | 107 +++ 1 file changed, 107 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi index 029723a..beb313c 100644 --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi @@ -16,6 +16,8 @@ #include #include #include +#include +#include / { interrupt-parent = <&intc>; @@ -592,6 +594,111 @@ qcom,bcm-voters = <&apps_bcm_voter>; }; + gpu: gpu@3d0 { + compatible = "qcom,adreno-635.0", "qcom,adreno"; + #stream-id-cells = <16>; + reg = <0 0x03d0 0 0x4>, <0 0x03d9e000 0 0x1000>, + <0 0x03d61000 0 0x800>; + reg-names = "kgsl_3d0_reg_memory", "cx_mem", "cx_dbgc"; + interrupts = ; + iommus = <&adreno_smmu 0 0x401>; + operating-points-v2 = <&gpu_opp_table>; + qcom,gmu = <&gmu>; + interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "gfx-mem"; + + gpu_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-55000 { + opp-hz = /bits/ 64 <55000>; + opp-level = ; + opp-peak-kBps = <6832000>; + }; + + opp-45000 { + opp-hz = /bits/ 64 <45000>; + opp-level = ; + opp-peak-kBps = <4068000>; + }; + + opp-31500 { + opp-hz = /bits/ 64 <31500>; + opp-level = ; + opp-peak-kBps = <1804000>; + }; + }; + }; + + adreno_smmu: iommu@3da { + compatible = "qcom,sc7280-smmu-500", "qcom,adreno-smmu", "arm,mmu-500"; + reg = <0 0x03da 0 0x2>; + #iommu-cells = <2>; + #global-interrupts = <2>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + ; + + clocks = <&gcc GCC_GPU_MEMNOC_GFX_CLK>, + <&gcc GCC_GPU_SNOC_DVM_GFX_CLK>, + <&gpucc GPU_CC_AHB_CLK>, + <&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>, + <&gpucc GPU_CC_CX_GMU_CLK>, + <&gpucc GPU_CC_HUB_CX_INT_CLK>, + <&gpucc GPU_CC_HUB_AON_CLK>; + clock-names = "gcc_gpu_memnoc_gfx_clk", + "gcc_gpu_snoc_dvm_gfx_clk", + "gpu_cc_ahb_clk", + "gpu_cc_hlos1_vote_gpu_smmu_clk", + "gpu_cc_cx_gmu_clk", + "gpu_cc_hub_cx_int_clk", + "gpu_cc_hub_aon_clk"; + + power-domains = <&gpucc GPU_CC_CX_GDSC>; + }; + + gmu: gmu@3d69000 { + compatible="qcom,adreno-gmu-635.0", "qcom,adreno-gmu"; + reg = <0 0x03d6a000 0 0x34000>, +
[Freedreno] [PATCH v2] arm64: dts: qcom: sc7280: Add gpu support
Add the necessary dt nodes for gpu support in sc7280. Signed-off-by: Akhil P Oommen --- This patch has dependency on the GPUCC bindings patch here: https://patchwork.kernel.org/project/linux-arm-msm/patch/1619519590-3019-4-git-send-email-t...@codeaurora.org/ Changes in v2: - formatting update and removed a duplicate header (Stephan) arch/arm64/boot/dts/qcom/sc7280.dtsi | 116 +++ 1 file changed, 116 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi index 029723a..524a5e0 100644 --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -585,6 +586,121 @@ #clock-cells = <1>; }; + gpu@3d0 { + compatible = "qcom,adreno-635.0", "qcom,adreno"; + #stream-id-cells = <16>; + reg = <0 0x03d0 0 0x4>, + <0 0x03d9e000 0 0x1000>, + <0 0x03d61000 0 0x800>; + reg-names = "kgsl_3d0_reg_memory", + "cx_mem", + "cx_dbgc"; + interrupts = ; + iommus = <&adreno_smmu 0 0x401>; + operating-points-v2 = <&gpu_opp_table>; + qcom,gmu = <&gmu>; + interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "gfx-mem"; + + gpu_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-55000 { + opp-hz = /bits/ 64 <55000>; + opp-level = ; + opp-peak-kBps = <6832000>; + }; + + opp-45000 { + opp-hz = /bits/ 64 <45000>; + opp-level = ; + opp-peak-kBps = <4068000>; + }; + + opp-31500 { + opp-hz = /bits/ 64 <31500>; + opp-level = ; + opp-peak-kBps = <1804000>; + }; + }; + }; + + gmu: gmu@3d69000 { + compatible="qcom,adreno-gmu-635.0", "qcom,adreno-gmu"; + reg = <0 0x03d6a000 0 0x34000>, + <0 0x3de 0 0x1>, + <0 0x0b29 0 0x1>; + reg-names = "gmu", "rscc", "gmu_pdc"; + interrupts = , + ; + interrupt-names = "hfi", "gmu"; + clocks = <&gpucc GPU_CC_CX_GMU_CLK>, + <&gpucc GPU_CC_CXO_CLK>, + <&gcc GCC_DDRSS_GPU_AXI_CLK>, + <&gcc GCC_GPU_MEMNOC_GFX_CLK>, + <&gpucc GPU_CC_AHB_CLK>, + <&gpucc GPU_CC_HUB_CX_INT_CLK>, + <&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>; + clock-names = "gmu", + "cxo", + "axi", + "memnoc", + "ahb", + "hub", + "smmu_vote"; + power-domains = <&gpucc GPU_CC_CX_GDSC>, + <&gpucc GPU_CC_GX_GDSC>; + power-domain-names = "cx", +"gx"; + iommus = <&adreno_smmu 5 0x400>; + operating-points-v2 = <&gmu_opp_table>; + + gmu_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-2 { +
Re: [Freedreno] [PATCH 2/2] drm/msm/a6xx: Add support for Adreno 7c Gen 3 gpu
On 7/24/2021 11:42 PM, Rob Clark wrote: () On Fri, Jul 23, 2021 at 3:38 AM Akhil P Oommen wrote: This patch adds support for the gpu found in the Snapdragon 7c Gen 3 compute platform. This gpu is similar to the exisiting a660 gpu with minor delta in the programing sequence. As the Adreno GPUs are moving away from a numeric chipid based naming scheme to a string, it was decided to use 0x06030500 as the gpu id of this gpu to communicate to the userspace driver. Signed-off-by: Akhil P Oommen --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 20 ++- drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 1 + drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h | 2 ++ drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 21 ++-- drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 32 ++ drivers/gpu/drm/msm/adreno/adreno_device.c | 12 +++ drivers/gpu/drm/msm/adreno/adreno_gpu.h| 11 -- 7 files changed, 90 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index b349692..332301f 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -933,6 +933,7 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu) /* Use a known rate to bring up the GMU */ clk_set_rate(gmu->core_clk, 2); + clk_set_rate(gmu->hub_clk, 15000); ret = clk_bulk_prepare_enable(gmu->nr_clocks, gmu->clocks); if (ret) { pm_runtime_put(gmu->gxpd); @@ -1094,6 +1095,7 @@ static void a6xx_gmu_shutdown(struct a6xx_gmu *gmu) int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu) { + struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; struct a6xx_gmu *gmu = &a6xx_gpu->gmu; struct msm_gpu *gpu = &a6xx_gpu->base.base; @@ -1117,9 +1119,22 @@ int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu) * domain. Usually the GMU does this but only if the shutdown sequence * was successful */ - if (!IS_ERR_OR_NULL(gmu->gxpd)) + if (!IS_ERR_OR_NULL(gmu->gxpd)) { + /* +* Toggle the loop_en bit, across disabling the gx gdsc, +* with a delay of 10 XO cycles before disabling gx +* gdsc. This is to prevent CPR measurements from +* failing. +*/ + if (adreno_is_a660(adreno_gpu)) + gmu_rmw(gmu, REG_A6XX_GPU_CPR_FSM_CTL, 1, 0); + pm_runtime_put_sync(gmu->gxpd); + if (adreno_is_a660(adreno_gpu)) + gmu_rmw(gmu, REG_A6XX_GPU_CPR_FSM_CTL, 1, 1); This kinda seems like it should be a separate patch.. but I noticed you silently turned adreno_is_a660() into what should probably be adreno_is_a660_family() I'd suggest to break this out into it's own patch, so it is clear that it effects a660 as well, and then a next patch to rename adreno_is_a660_family() Longer term, we might want to think about refactoring all the if(adreno_is_xyz()) into a features table (see i915_pci.c for ideas) I agree. This should have been a seperate patch. + } + clk_bulk_disable_unprepare(gmu->nr_clocks, gmu->clocks); pm_runtime_put_sync(gmu->dev); @@ -1393,6 +1408,9 @@ static int a6xx_gmu_clocks_probe(struct a6xx_gmu *gmu) gmu->core_clk = msm_clk_bulk_get_clock(gmu->clocks, gmu->nr_clocks, "gmu"); + gmu->hub_clk = msm_clk_bulk_get_clock(gmu->clocks, + gmu->nr_clocks, "hub"); + return 0; } diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h index 71dfa600..3c74f64 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h @@ -66,6 +66,7 @@ struct a6xx_gmu { int nr_clocks; struct clk_bulk_data *clocks; struct clk *core_clk; + struct clk *hub_clk; /* current performance index set externally */ int current_perf_index; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h index 8115892..d46733f 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h @@ -479,5 +479,7 @@ static inline uint32_t A6XX_GMU_GPU_NAP_CTRL_SID(uint32_t val) #define REG_A6XX_RSCC_TCS3_DRV0_STATUS 0x053e +#define REG_A6XX_GPU_CPR_FSM_CTL 0xc001 + #endif /* A6XX_GMU_XML */ diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 183b9f9..c0882536 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -694,6 +694,13 @@ static void a6xx_set_ubwc_config(struct msm_gpu *gpu) uavflagprd_inv = 2;
Re: [Freedreno] [PATCH v2] arm64: dts: qcom: sc7280: Add gpu support
On 7/27/2021 5:46 AM, Stephen Boyd wrote: Quoting Akhil P Oommen (2021-07-24 10:29:00) Add the necessary dt nodes for gpu support in sc7280. Signed-off-by: Akhil P Oommen --- This patch has dependency on the GPUCC bindings patch here: https://patchwork.kernel.org/project/linux-arm-msm/patch/1619519590-3019-4-git-send-email-t...@codeaurora.org/ To avoid the dependency the plain numbers can be used. But, won't that reduce readability and make things prone to error? If the other patch doesn't get picked up soon, we should try this option. We like to get this patch merged in v5.15. Changes in v2: - formatting update and removed a duplicate header (Stephan) arch/arm64/boot/dts/qcom/sc7280.dtsi | 116 +++ 1 file changed, 116 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi index 029723a..524a5e0 100644 --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi @@ -585,6 +586,121 @@ #clock-cells = <1>; }; + gpu@3d0 { + compatible = "qcom,adreno-635.0", "qcom,adreno"; + #stream-id-cells = <16>; + reg = <0 0x03d0 0 0x4>, + <0 0x03d9e000 0 0x1000>, + <0 0x03d61000 0 0x800>; + reg-names = "kgsl_3d0_reg_memory", + "cx_mem", + "cx_dbgc"; + interrupts = ; + iommus = <&adreno_smmu 0 0x401>; + operating-points-v2 = <&gpu_opp_table>; + qcom,gmu = <&gmu>; + interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "gfx-mem"; + + gpu_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-55000 { + opp-hz = /bits/ 64 <55000>; + opp-level = ; + opp-peak-kBps = <6832000>; + }; + + opp-45000 { + opp-hz = /bits/ 64 <45000>; + opp-level = ; + opp-peak-kBps = <4068000>; + }; + + opp-31500 { + opp-hz = /bits/ 64 <31500>; + opp-level = ; + opp-peak-kBps = <1804000>; + }; + }; + }; + + gmu: gmu@3d69000 { + compatible="qcom,adreno-gmu-635.0", "qcom,adreno-gmu"; + reg = <0 0x03d6a000 0 0x34000>, + <0 0x3de 0 0x1>, + <0 0x0b29 0 0x1>; + reg-names = "gmu", "rscc", "gmu_pdc"; + interrupts = , + ; + interrupt-names = "hfi", "gmu"; + clocks = <&gpucc GPU_CC_CX_GMU_CLK>, + <&gpucc GPU_CC_CXO_CLK>, + <&gcc GCC_DDRSS_GPU_AXI_CLK>, + <&gcc GCC_GPU_MEMNOC_GFX_CLK>, + <&gpucc GPU_CC_AHB_CLK>, + <&gpucc GPU_CC_HUB_CX_INT_CLK>, + <&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>; + clock-names = "gmu", + "cxo", + "axi", + "memnoc", + "ahb", + "hub", + "smmu_vote"; + power-domains = <&gpucc GPU_CC_CX_GDSC>, + <&gpucc GPU_CC_GX_GDSC>; + power-domain-names = "cx", +"gx"; + iommus = <&adreno_smmu 5 0x400>; +
[Freedreno] [PATCH v3 2/2] arm64: dts: qcom: sc7280: Add gpu thermal zone cooling support
From: Manaf Meethalavalappu Pallikunhi Add cooling-cells property and the cooling maps for the gpu thermal zones to support GPU thermal cooling. Signed-off-by: Manaf Meethalavalappu Pallikunhi Signed-off-by: Akhil P Oommen --- (no changes since v1) arch/arm64/boot/dts/qcom/sc7280.dtsi | 29 ++--- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi index c88f366..45a96d1 100644 --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi @@ -593,7 +593,7 @@ qcom,bcm-voters = <&apps_bcm_voter>; }; - gpu@3d0 { + gpu: gpu@3d0 { compatible = "qcom,adreno-635.0", "qcom,adreno"; #stream-id-cells = <16>; reg = <0 0x03d0 0 0x4>, @@ -608,6 +608,7 @@ qcom,gmu = <&gmu>; interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "gfx-mem"; + #cooling-cells = <2>; gpu_opp_table: opp-table { compatible = "operating-points-v2"; @@ -2524,16 +2525,16 @@ }; gpuss0-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <100>; polling-delay = <0>; thermal-sensors = <&tsens1 1>; trips { gpuss0_alert0: trip-point0 { - temperature = <9>; + temperature = <95000>; hysteresis = <2000>; - type = "hot"; + type = "passive"; }; gpuss0_crit: gpuss0-crit { @@ -2542,19 +2543,26 @@ type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss0_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss1-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <100>; polling-delay = <0>; thermal-sensors = <&tsens1 2>; trips { gpuss1_alert0: trip-point0 { - temperature = <9>; + temperature = <95000>; hysteresis = <2000>; - type = "hot"; + type = "passive"; }; gpuss1_crit: gpuss1-crit { @@ -2563,6 +2571,13 @@ type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss1_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; nspss0-thermal { -- 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 v3 1/2] arm64: dts: qcom: sc7280: Add gpu support
Add the necessary dt nodes for gpu support in sc7280. Signed-off-by: Akhil P Oommen --- This has dependency on the below GPUCC bindings patch which is already accepted in clk-next: https://patchwork.kernel.org/project/linux-clk/list/?series=514831&state=%2A&archive=both Changes in v3: - Re-ordered the nodes based on address (Stephan) - Added the patch for gpu cooling to the stack. Changes in v2: - formatting update and removed a duplicate header (Stephan) arch/arm64/boot/dts/qcom/sc7280.dtsi | 116 +++ 1 file changed, 116 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi index 029723a..c88f366 100644 --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -592,6 +593,85 @@ qcom,bcm-voters = <&apps_bcm_voter>; }; + gpu@3d0 { + compatible = "qcom,adreno-635.0", "qcom,adreno"; + #stream-id-cells = <16>; + reg = <0 0x03d0 0 0x4>, + <0 0x03d9e000 0 0x1000>, + <0 0x03d61000 0 0x800>; + reg-names = "kgsl_3d0_reg_memory", + "cx_mem", + "cx_dbgc"; + interrupts = ; + iommus = <&adreno_smmu 0 0x401>; + operating-points-v2 = <&gpu_opp_table>; + qcom,gmu = <&gmu>; + interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "gfx-mem"; + + gpu_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-55000 { + opp-hz = /bits/ 64 <55000>; + opp-level = ; + opp-peak-kBps = <6832000>; + }; + + opp-45000 { + opp-hz = /bits/ 64 <45000>; + opp-level = ; + opp-peak-kBps = <4068000>; + }; + + opp-31500 { + opp-hz = /bits/ 64 <31500>; + opp-level = ; + opp-peak-kBps = <1804000>; + }; + }; + }; + + gmu: gmu@3d69000 { + compatible="qcom,adreno-gmu-635.0", "qcom,adreno-gmu"; + reg = <0 0x03d6a000 0 0x34000>, + <0 0x3de 0 0x1>, + <0 0x0b29 0 0x1>; + reg-names = "gmu", "rscc", "gmu_pdc"; + interrupts = , + ; + interrupt-names = "hfi", "gmu"; + clocks = <&gpucc GPU_CC_CX_GMU_CLK>, + <&gpucc GPU_CC_CXO_CLK>, + <&gcc GCC_DDRSS_GPU_AXI_CLK>, + <&gcc GCC_GPU_MEMNOC_GFX_CLK>, + <&gpucc GPU_CC_AHB_CLK>, + <&gpucc GPU_CC_HUB_CX_INT_CLK>, + <&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>; + clock-names = "gmu", + "cxo", + "axi", + "memnoc", + "ahb", + "hub", + "smmu_vote"; + power-domains = <&gpucc GPU_CC_CX_GDSC>, + <&gpucc GPU_CC_GX_GDSC>; + power-domain-names = "cx", +"gx"; + iommus = <&adreno_smmu 5 0x400>; + operating-points-v2 = <&gmu_opp_table>; + + gmu_opp_table: opp-table { +
[Freedreno] [PATCH v2 1/3] drm/msm/a6xx: Fix llcc configuration for a660 gpu
Add the missing scache_cntl0 register programing which is required for a660 gpu. Signed-off-by: Akhil P Oommen --- (no changes since v1) drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 46 --- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 9c5e461..183b9f9 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1383,13 +1383,13 @@ static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu) { struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; struct msm_gpu *gpu = &adreno_gpu->base; - u32 cntl1_regval = 0; + u32 gpu_scid, cntl1_regval = 0; if (IS_ERR(a6xx_gpu->llc_mmio)) return; if (!llcc_slice_activate(a6xx_gpu->llc_slice)) { - u32 gpu_scid = llcc_get_slice_id(a6xx_gpu->llc_slice); + gpu_scid = llcc_get_slice_id(a6xx_gpu->llc_slice); gpu_scid &= 0x1f; cntl1_regval = (gpu_scid << 0) | (gpu_scid << 5) | (gpu_scid << 10) | @@ -1409,26 +1409,34 @@ static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu) } } - if (cntl1_regval) { + if (!cntl1_regval) + return; + + /* +* Program the slice IDs for the various GPU blocks and GPU MMU +* pagetables +*/ + if (!a6xx_gpu->have_mmu500) { + a6xx_llc_write(a6xx_gpu, + REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_1, cntl1_regval); + /* -* Program the slice IDs for the various GPU blocks and GPU MMU -* pagetables +* Program cacheability overrides to not allocate cache +* lines on a write miss */ - if (a6xx_gpu->have_mmu500) - gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL1, GENMASK(24, 0), - cntl1_regval); - else { - a6xx_llc_write(a6xx_gpu, - REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_1, cntl1_regval); - - /* -* Program cacheability overrides to not allocate cache -* lines on a write miss -*/ - a6xx_llc_rmw(a6xx_gpu, - REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_0, 0xF, 0x03); - } + a6xx_llc_rmw(a6xx_gpu, + REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_0, 0xF, 0x03); + return; } + + gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL1, GENMASK(24, 0), cntl1_regval); + + /* On A660, the SCID programming for UCHE traffic is done in +* A6XX_GBIF_SCACHE_CNTL0[14:10] +*/ + if (adreno_is_a660(adreno_gpu)) + gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL0, (0x1f << 10) | + (1 << 8), (gpu_scid << 10) | (1 << 8)); } static void a6xx_llc_slices_destroy(struct a6xx_gpu *a6xx_gpu) -- 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 v2 3/3] drm/msm/a6xx: Add support for Adreno 7c Gen 3 gpu
This patch adds support for the gpu found in the Snapdragon 7c Gen 3 compute platform. This gpu is similar to the exisiting a660 gpu with minor delta in the programing sequence. As the Adreno GPUs are moving away from a numeric chipid based naming scheme to a string, it was decided to use 0x06030500 as the gpu id of this gpu to communicate to the userspace driver. Signed-off-by: Akhil P Oommen --- Changes in v2: - Introduce adreno_is_a660_family() (Rob) - Remove revn for 7c3 (Rob) - Remove CPR register programing since they are not required for 7c3 drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 8 ++-- drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 1 + drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 32 -- drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 32 ++ drivers/gpu/drm/msm/adreno/adreno_device.c | 27 +++-- drivers/gpu/drm/msm/adreno/adreno_gpu.h| 18 - 6 files changed, 98 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index b349692..70ba3bf 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -519,7 +519,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu) if (!pdcptr) goto err; - if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu)) + if (adreno_is_a650(adreno_gpu) || adreno_is_a660_family(adreno_gpu)) pdc_in_aop = true; else if (adreno_is_a618(adreno_gpu) || adreno_is_a640(adreno_gpu)) pdc_address_offset = 0x30090; @@ -933,6 +933,7 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu) /* Use a known rate to bring up the GMU */ clk_set_rate(gmu->core_clk, 2); + clk_set_rate(gmu->hub_clk, 15000); ret = clk_bulk_prepare_enable(gmu->nr_clocks, gmu->clocks); if (ret) { pm_runtime_put(gmu->gxpd); @@ -1393,6 +1394,9 @@ static int a6xx_gmu_clocks_probe(struct a6xx_gmu *gmu) gmu->core_clk = msm_clk_bulk_get_clock(gmu->clocks, gmu->nr_clocks, "gmu"); + gmu->hub_clk = msm_clk_bulk_get_clock(gmu->clocks, + gmu->nr_clocks, "hub"); + return 0; } @@ -1504,7 +1508,7 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) * are otherwise unused by a660. */ gmu->dummy.size = SZ_4K; - if (adreno_is_a660(adreno_gpu)) { + if (adreno_is_a660_family(adreno_gpu)) { ret = a6xx_gmu_memory_alloc(gmu, &gmu->debug, SZ_4K * 7, 0x6040); if (ret) goto err_memory; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h index 71dfa600..3c74f64 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h @@ -66,6 +66,7 @@ struct a6xx_gmu { int nr_clocks; struct clk_bulk_data *clocks; struct clk *core_clk; + struct clk *hub_clk; /* current performance index set externally */ int current_perf_index; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 0da1a66..1881e09 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -652,7 +652,7 @@ static void a6xx_set_cp_protect(struct msm_gpu *gpu) regs = a650_protect; count = ARRAY_SIZE(a650_protect); count_max = 48; - } else if (adreno_is_a660(adreno_gpu)) { + } else if (adreno_is_a660_family(adreno_gpu)) { regs = a660_protect; count = ARRAY_SIZE(a660_protect); count_max = 48; @@ -694,6 +694,13 @@ static void a6xx_set_ubwc_config(struct msm_gpu *gpu) uavflagprd_inv = 2; } + if (adreno_is_7c3(adreno_gpu)) { + lower_bit = 1; + amsbc = 1; + rgb565_predicator = 1; + uavflagprd_inv = 2; + } + gpu_write(gpu, REG_A6XX_RB_NC_MODE_CNTL, rgb565_predicator << 11 | amsbc << 4 | lower_bit << 1); gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL, lower_bit << 1); @@ -787,7 +794,7 @@ static bool a6xx_ucode_check_version(struct a6xx_gpu *a6xx_gpu, DRM_DEV_ERROR(&gpu->pdev->dev, "a650 SQE ucode is too old. Have version %x need at least %x\n", buf[0] & 0xfff, 0x095); - } else if (adreno_is_a660(adreno_gpu)) { + } else if (adreno_is_a660_family(adreno_gpu)) { ret = true; } else { DRM_DEV_ERROR(&gpu->pdev->dev, @@ -941,7 +948,7 @@ static int a6xx_hw_init(struct msm_gpu *gpu) gpu_write(gpu,
[Freedreno] [PATCH v2 2/3] drm/msm/a6xx: Use rev to identify SKU
Use rev instead of revn to identify the SKU. This is in preparation to the introduction of 7c3 gpu which won't have a revn. Signed-off-by: Akhil P Oommen --- (no changes since v1) drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 183b9f9..0da1a66 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1675,11 +1675,11 @@ static u32 a618_get_speed_bin(u32 fuse) return UINT_MAX; } -static u32 fuse_to_supp_hw(struct device *dev, u32 revn, u32 fuse) +static u32 fuse_to_supp_hw(struct device *dev, struct adreno_rev rev, u32 fuse) { u32 val = UINT_MAX; - if (revn == 618) + if (adreno_cmp_rev(ADRENO_REV(6, 1, 8, ANY_ID), rev)) val = a618_get_speed_bin(fuse); if (val == UINT_MAX) { @@ -1692,8 +1692,7 @@ static u32 fuse_to_supp_hw(struct device *dev, u32 revn, u32 fuse) return (1 << val); } -static int a6xx_set_supported_hw(struct device *dev, struct a6xx_gpu *a6xx_gpu, - u32 revn) +static int a6xx_set_supported_hw(struct device *dev, struct adreno_rev rev) { u32 supp_hw = UINT_MAX; u16 speedbin; @@ -1714,7 +1713,7 @@ static int a6xx_set_supported_hw(struct device *dev, struct a6xx_gpu *a6xx_gpu, } speedbin = le16_to_cpu(speedbin); - supp_hw = fuse_to_supp_hw(dev, revn, speedbin); + supp_hw = fuse_to_supp_hw(dev, rev, speedbin); done: ret = devm_pm_opp_set_supported_hw(dev, &supp_hw, 1); @@ -1785,7 +1784,7 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) a6xx_llc_slices_init(pdev, a6xx_gpu); - ret = a6xx_set_supported_hw(&pdev->dev, a6xx_gpu, info->revn); + ret = a6xx_set_supported_hw(&pdev->dev, config->rev); if (ret) { a6xx_destroy(&(a6xx_gpu->base.base)); return ERR_PTR(ret); -- 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 v3 0/3] Support Adreno 7c Gen 3 gpu
This series adds support for the gpu found in the Snapdragon 7c Gen 3 compute platform. This gpu is similar to the exisiting a660 gpu with minor delta in the programing sequence. As the Adreno GPUs are moving away from a numeric chipid based naming scheme to a string, it was decided to use 0x06030500 as the gpu id of this gpu to communicate to the userspace driver. Changes in v3: - Add a cover letter. Changes in v2: - Use rev to identify SKU - Introduce adreno_is_a660_family() (Rob) - Remove revn for 7c3 (Rob) - Remove CPR register programing since they are not required for 7c3 Akhil P Oommen (3): drm/msm/a6xx: Fix llcc configuration for a660 gpu drm/msm/a6xx: Use rev to identify SKU drm/msm/a6xx: Add support for Adreno 7c Gen 3 gpu drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 8 ++- drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 1 + drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 87 ++ drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 32 +++ drivers/gpu/drm/msm/adreno/adreno_device.c | 27 +++--- drivers/gpu/drm/msm/adreno/adreno_gpu.h| 18 ++- 6 files changed, 129 insertions(+), 44 deletions(-) -- 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 v3 2/3] drm/msm/a6xx: Use rev to identify SKU
Use rev instead of revn to identify the SKU. This is in preparation to the introduction of 7c3 gpu which won't have a revn. Signed-off-by: Akhil P Oommen --- (no changes since v1) drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 183b9f9..0da1a66 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1675,11 +1675,11 @@ static u32 a618_get_speed_bin(u32 fuse) return UINT_MAX; } -static u32 fuse_to_supp_hw(struct device *dev, u32 revn, u32 fuse) +static u32 fuse_to_supp_hw(struct device *dev, struct adreno_rev rev, u32 fuse) { u32 val = UINT_MAX; - if (revn == 618) + if (adreno_cmp_rev(ADRENO_REV(6, 1, 8, ANY_ID), rev)) val = a618_get_speed_bin(fuse); if (val == UINT_MAX) { @@ -1692,8 +1692,7 @@ static u32 fuse_to_supp_hw(struct device *dev, u32 revn, u32 fuse) return (1 << val); } -static int a6xx_set_supported_hw(struct device *dev, struct a6xx_gpu *a6xx_gpu, - u32 revn) +static int a6xx_set_supported_hw(struct device *dev, struct adreno_rev rev) { u32 supp_hw = UINT_MAX; u16 speedbin; @@ -1714,7 +1713,7 @@ static int a6xx_set_supported_hw(struct device *dev, struct a6xx_gpu *a6xx_gpu, } speedbin = le16_to_cpu(speedbin); - supp_hw = fuse_to_supp_hw(dev, revn, speedbin); + supp_hw = fuse_to_supp_hw(dev, rev, speedbin); done: ret = devm_pm_opp_set_supported_hw(dev, &supp_hw, 1); @@ -1785,7 +1784,7 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) a6xx_llc_slices_init(pdev, a6xx_gpu); - ret = a6xx_set_supported_hw(&pdev->dev, a6xx_gpu, info->revn); + ret = a6xx_set_supported_hw(&pdev->dev, config->rev); if (ret) { a6xx_destroy(&(a6xx_gpu->base.base)); return ERR_PTR(ret); -- 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 v3 3/3] drm/msm/a6xx: Add support for Adreno 7c Gen 3 gpu
This patch adds support for the gpu found in the Snapdragon 7c Gen 3 compute platform. This gpu is similar to the exisiting a660 gpu with minor delta in the programing sequence. As the Adreno GPUs are moving away from a numeric chipid based naming scheme to a string, it was decided to use 0x06030500 as the gpu id of this gpu to communicate to the userspace driver. Signed-off-by: Akhil P Oommen --- (no changes since v2) Changes in v2: - Introduce adreno_is_a660_family() (Rob) - Remove revn for 7c3 (Rob) - Remove CPR register programing since they are not required for 7c3 drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 8 ++-- drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 1 + drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 32 -- drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 32 ++ drivers/gpu/drm/msm/adreno/adreno_device.c | 27 +++-- drivers/gpu/drm/msm/adreno/adreno_gpu.h| 18 - 6 files changed, 98 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index b349692..70ba3bf 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -519,7 +519,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu) if (!pdcptr) goto err; - if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu)) + if (adreno_is_a650(adreno_gpu) || adreno_is_a660_family(adreno_gpu)) pdc_in_aop = true; else if (adreno_is_a618(adreno_gpu) || adreno_is_a640(adreno_gpu)) pdc_address_offset = 0x30090; @@ -933,6 +933,7 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu) /* Use a known rate to bring up the GMU */ clk_set_rate(gmu->core_clk, 2); + clk_set_rate(gmu->hub_clk, 15000); ret = clk_bulk_prepare_enable(gmu->nr_clocks, gmu->clocks); if (ret) { pm_runtime_put(gmu->gxpd); @@ -1393,6 +1394,9 @@ static int a6xx_gmu_clocks_probe(struct a6xx_gmu *gmu) gmu->core_clk = msm_clk_bulk_get_clock(gmu->clocks, gmu->nr_clocks, "gmu"); + gmu->hub_clk = msm_clk_bulk_get_clock(gmu->clocks, + gmu->nr_clocks, "hub"); + return 0; } @@ -1504,7 +1508,7 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) * are otherwise unused by a660. */ gmu->dummy.size = SZ_4K; - if (adreno_is_a660(adreno_gpu)) { + if (adreno_is_a660_family(adreno_gpu)) { ret = a6xx_gmu_memory_alloc(gmu, &gmu->debug, SZ_4K * 7, 0x6040); if (ret) goto err_memory; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h index 71dfa600..3c74f64 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h @@ -66,6 +66,7 @@ struct a6xx_gmu { int nr_clocks; struct clk_bulk_data *clocks; struct clk *core_clk; + struct clk *hub_clk; /* current performance index set externally */ int current_perf_index; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 0da1a66..1881e09 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -652,7 +652,7 @@ static void a6xx_set_cp_protect(struct msm_gpu *gpu) regs = a650_protect; count = ARRAY_SIZE(a650_protect); count_max = 48; - } else if (adreno_is_a660(adreno_gpu)) { + } else if (adreno_is_a660_family(adreno_gpu)) { regs = a660_protect; count = ARRAY_SIZE(a660_protect); count_max = 48; @@ -694,6 +694,13 @@ static void a6xx_set_ubwc_config(struct msm_gpu *gpu) uavflagprd_inv = 2; } + if (adreno_is_7c3(adreno_gpu)) { + lower_bit = 1; + amsbc = 1; + rgb565_predicator = 1; + uavflagprd_inv = 2; + } + gpu_write(gpu, REG_A6XX_RB_NC_MODE_CNTL, rgb565_predicator << 11 | amsbc << 4 | lower_bit << 1); gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL, lower_bit << 1); @@ -787,7 +794,7 @@ static bool a6xx_ucode_check_version(struct a6xx_gpu *a6xx_gpu, DRM_DEV_ERROR(&gpu->pdev->dev, "a650 SQE ucode is too old. Have version %x need at least %x\n", buf[0] & 0xfff, 0x095); - } else if (adreno_is_a660(adreno_gpu)) { + } else if (adreno_is_a660_family(adreno_gpu)) { ret = true; } else { DRM_DEV_ERROR(&gpu->pdev->dev, @@ -941,7 +948,7 @@ static int a6xx_hw_init(struct msm_gpu *gpu)
[Freedreno] [PATCH v3 1/3] drm/msm/a6xx: Fix llcc configuration for a660 gpu
Add the missing scache_cntl0 register programing which is required for a660 gpu. Signed-off-by: Akhil P Oommen --- (no changes since v1) drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 46 --- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 9c5e461..183b9f9 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1383,13 +1383,13 @@ static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu) { struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; struct msm_gpu *gpu = &adreno_gpu->base; - u32 cntl1_regval = 0; + u32 gpu_scid, cntl1_regval = 0; if (IS_ERR(a6xx_gpu->llc_mmio)) return; if (!llcc_slice_activate(a6xx_gpu->llc_slice)) { - u32 gpu_scid = llcc_get_slice_id(a6xx_gpu->llc_slice); + gpu_scid = llcc_get_slice_id(a6xx_gpu->llc_slice); gpu_scid &= 0x1f; cntl1_regval = (gpu_scid << 0) | (gpu_scid << 5) | (gpu_scid << 10) | @@ -1409,26 +1409,34 @@ static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu) } } - if (cntl1_regval) { + if (!cntl1_regval) + return; + + /* +* Program the slice IDs for the various GPU blocks and GPU MMU +* pagetables +*/ + if (!a6xx_gpu->have_mmu500) { + a6xx_llc_write(a6xx_gpu, + REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_1, cntl1_regval); + /* -* Program the slice IDs for the various GPU blocks and GPU MMU -* pagetables +* Program cacheability overrides to not allocate cache +* lines on a write miss */ - if (a6xx_gpu->have_mmu500) - gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL1, GENMASK(24, 0), - cntl1_regval); - else { - a6xx_llc_write(a6xx_gpu, - REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_1, cntl1_regval); - - /* -* Program cacheability overrides to not allocate cache -* lines on a write miss -*/ - a6xx_llc_rmw(a6xx_gpu, - REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_0, 0xF, 0x03); - } + a6xx_llc_rmw(a6xx_gpu, + REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_0, 0xF, 0x03); + return; } + + gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL1, GENMASK(24, 0), cntl1_regval); + + /* On A660, the SCID programming for UCHE traffic is done in +* A6XX_GBIF_SCACHE_CNTL0[14:10] +*/ + if (adreno_is_a660(adreno_gpu)) + gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL0, (0x1f << 10) | + (1 << 8), (gpu_scid << 10) | (1 << 8)); } static void a6xx_llc_slices_destroy(struct a6xx_gpu *a6xx_gpu) -- 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] [RFC PATCH] drm/msm: Introduce Adreno Features
Introduce a feature flag in gpulist to easily identify the capabilities of each gpu revision. This will help to avoid a lot of adreno_is_axxx() check when we add new features. In the current patch, HW APRIV feature is converted to a feature flag. Signed-off-by: Akhil P Oommen --- This patch is rebased on top of the below series: https://patchwork.freedesktop.org/series/93192/ drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 12 drivers/gpu/drm/msm/adreno/adreno_device.c | 3 +++ drivers/gpu/drm/msm/adreno/adreno_gpu.c| 3 +++ drivers/gpu/drm/msm/adreno/adreno_gpu.h| 9 + 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 1881e09..b28305b 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1765,7 +1765,6 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) struct msm_drm_private *priv = dev->dev_private; struct platform_device *pdev = priv->gpu_pdev; struct adreno_platform_config *config = pdev->dev.platform_data; - const struct adreno_info *info; struct device_node *node; struct a6xx_gpu *a6xx_gpu; struct adreno_gpu *adreno_gpu; @@ -1781,17 +1780,6 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) adreno_gpu->registers = NULL; - /* -* We need to know the platform type before calling into adreno_gpu_init -* so that the hw_apriv flag can be correctly set. Snoop into the info -* and grab the revision number -*/ - info = adreno_info(config->rev); - - if (info && (info->revn == 650 || info->revn == 660 || - adreno_cmp_rev(ADRENO_REV(6, 3, 5, ANY_ID), info->rev))) - adreno_gpu->base.hw_apriv = true; - a6xx_llc_slices_init(pdev, a6xx_gpu); ret = a6xx_set_supported_hw(&pdev->dev, config->rev); diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 7b9d605..44321ec 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -276,6 +276,7 @@ static const struct adreno_info gpulist[] = { .rev = ADRENO_REV(6, 5, 0, ANY_ID), .revn = 650, .name = "A650", + .features = ADRENO_APRIV, .fw = { [ADRENO_FW_SQE] = "a650_sqe.fw", [ADRENO_FW_GMU] = "a650_gmu.bin", @@ -289,6 +290,7 @@ static const struct adreno_info gpulist[] = { .rev = ADRENO_REV(6, 6, 0, ANY_ID), .revn = 660, .name = "A660", + .features = ADRENO_APRIV, .fw = { [ADRENO_FW_SQE] = "a660_sqe.fw", [ADRENO_FW_GMU] = "a660_gmu.bin", @@ -301,6 +303,7 @@ static const struct adreno_info gpulist[] = { }, { .rev = ADRENO_REV(6, 3, 5, ANY_ID), .name = "Adreno 7c Gen 3", + .features = ADRENO_APRIV, .fw = { [ADRENO_FW_SQE] = "a660_sqe.fw", [ADRENO_FW_GMU] = "a660_gmu.bin", diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 9f5a302..e8acadf5 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -945,6 +945,9 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, pm_runtime_use_autosuspend(dev); pm_runtime_enable(dev); + if (ADRENO_FEAT(adreno_gpu, ADRENO_APRIV)) + adreno_gpu->base.hw_apriv = true; + return msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base, adreno_gpu->info->name, &adreno_gpu_config); } diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index 50b4d53..61797c3 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -35,6 +35,11 @@ enum adreno_quirks { ADRENO_QUIRK_LMLOADKILL_DISABLE = 3, }; +enum adreno_features { + /* ADRENO has HW APRIV feature */ + ADRENO_APRIV, +}; + struct adreno_rev { uint8_t core; uint8_t major; @@ -63,6 +68,7 @@ struct adreno_info { struct adreno_rev rev; uint32_t revn; const char *name; + u32 features; const char *fw[ADRENO_FW_MAX]; uint32_t gmem; enum adreno_quirks quirks; @@ -388,6 +394,9 @@ static inline uint32_t get_wptr(struct msm_ringbuffer *ring) return (ring->cur - ring->start) % (MSM_GPU_RINGBUFFER_SZ >> 2); } +#define ADRENO_FEAT(adreno_gpu, feature) \
Re: [Freedreno] [PATCH v2 2/3] drm/msm/a6xx: Use rev to identify SKU
On 7/29/2021 8:57 PM, Rob Clark wrote: On Thu, Jul 29, 2021 at 7:33 AM Akhil P Oommen wrote: Use rev instead of revn to identify the SKU. This is in preparation to the introduction of 7c3 gpu which won't have a revn. Signed-off-by: Akhil P Oommen --- (no changes since v1) drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 183b9f9..0da1a66 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1675,11 +1675,11 @@ static u32 a618_get_speed_bin(u32 fuse) return UINT_MAX; } -static u32 fuse_to_supp_hw(struct device *dev, u32 revn, u32 fuse) +static u32 fuse_to_supp_hw(struct device *dev, struct adreno_rev rev, u32 fuse) { u32 val = UINT_MAX; - if (revn == 618) + if (adreno_cmp_rev(ADRENO_REV(6, 1, 8, ANY_ID), rev)) Looks like adreno_cmp_rev() ended up in patch 3/3 when it should have been in this patch.. But I guess we could also move this into adreno_is_a618() and use that here BR, -R Ahh! I reordered the patches. This is too early in the probe sequence to call adreno_is_axxx(), right? -Akhil. val = a618_get_speed_bin(fuse); if (val == UINT_MAX) { @@ -1692,8 +1692,7 @@ static u32 fuse_to_supp_hw(struct device *dev, u32 revn, u32 fuse) return (1 << val); } -static int a6xx_set_supported_hw(struct device *dev, struct a6xx_gpu *a6xx_gpu, - u32 revn) +static int a6xx_set_supported_hw(struct device *dev, struct adreno_rev rev) { u32 supp_hw = UINT_MAX; u16 speedbin; @@ -1714,7 +1713,7 @@ static int a6xx_set_supported_hw(struct device *dev, struct a6xx_gpu *a6xx_gpu, } speedbin = le16_to_cpu(speedbin); - supp_hw = fuse_to_supp_hw(dev, revn, speedbin); + supp_hw = fuse_to_supp_hw(dev, rev, speedbin); done: ret = devm_pm_opp_set_supported_hw(dev, &supp_hw, 1); @@ -1785,7 +1784,7 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) a6xx_llc_slices_init(pdev, a6xx_gpu); - ret = a6xx_set_supported_hw(&pdev->dev, a6xx_gpu, info->revn); + ret = a6xx_set_supported_hw(&pdev->dev, config->rev); if (ret) { a6xx_destroy(&(a6xx_gpu->base.base)); return ERR_PTR(ret); -- 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
Re: [Freedreno] [PATCH v3 3/3] drm/msm/a6xx: Add support for Adreno 7c Gen 3 gpu
On 7/29/2021 9:08 PM, Rob Clark wrote: On Thu, Jul 29, 2021 at 8:21 AM Akhil P Oommen wrote: This patch adds support for the gpu found in the Snapdragon 7c Gen 3 compute platform. This gpu is similar to the exisiting a660 gpu with minor delta in the programing sequence. As the Adreno GPUs are moving away from a numeric chipid based naming scheme to a string, it was decided to use 0x06030500 as the gpu id of this gpu to communicate to the userspace driver. s/gpu id/chip id/ (and in the cover letter too) Signed-off-by: Akhil P Oommen --- (no changes since v2) Changes in v2: - Introduce adreno_is_a660_family() (Rob) - Remove revn for 7c3 (Rob) - Remove CPR register programing since they are not required for 7c3 drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 8 ++-- drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 1 + drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 32 -- drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 32 ++ drivers/gpu/drm/msm/adreno/adreno_device.c | 27 +++-- drivers/gpu/drm/msm/adreno/adreno_gpu.h| 18 - 6 files changed, 98 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index b349692..70ba3bf 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -519,7 +519,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu) if (!pdcptr) goto err; - if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu)) + if (adreno_is_a650(adreno_gpu) || adreno_is_a660_family(adreno_gpu)) pdc_in_aop = true; else if (adreno_is_a618(adreno_gpu) || adreno_is_a640(adreno_gpu)) pdc_address_offset = 0x30090; @@ -933,6 +933,7 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu) /* Use a known rate to bring up the GMU */ clk_set_rate(gmu->core_clk, 2); + clk_set_rate(gmu->hub_clk, 15000); ret = clk_bulk_prepare_enable(gmu->nr_clocks, gmu->clocks); if (ret) { pm_runtime_put(gmu->gxpd); @@ -1393,6 +1394,9 @@ static int a6xx_gmu_clocks_probe(struct a6xx_gmu *gmu) gmu->core_clk = msm_clk_bulk_get_clock(gmu->clocks, gmu->nr_clocks, "gmu"); + gmu->hub_clk = msm_clk_bulk_get_clock(gmu->clocks, + gmu->nr_clocks, "hub"); + return 0; } @@ -1504,7 +1508,7 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) * are otherwise unused by a660. */ gmu->dummy.size = SZ_4K; - if (adreno_is_a660(adreno_gpu)) { + if (adreno_is_a660_family(adreno_gpu)) { ret = a6xx_gmu_memory_alloc(gmu, &gmu->debug, SZ_4K * 7, 0x6040); if (ret) goto err_memory; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h index 71dfa600..3c74f64 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h @@ -66,6 +66,7 @@ struct a6xx_gmu { int nr_clocks; struct clk_bulk_data *clocks; struct clk *core_clk; + struct clk *hub_clk; /* current performance index set externally */ int current_perf_index; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 0da1a66..1881e09 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -652,7 +652,7 @@ static void a6xx_set_cp_protect(struct msm_gpu *gpu) regs = a650_protect; count = ARRAY_SIZE(a650_protect); count_max = 48; - } else if (adreno_is_a660(adreno_gpu)) { + } else if (adreno_is_a660_family(adreno_gpu)) { regs = a660_protect; count = ARRAY_SIZE(a660_protect); count_max = 48; @@ -694,6 +694,13 @@ static void a6xx_set_ubwc_config(struct msm_gpu *gpu) uavflagprd_inv = 2; } + if (adreno_is_7c3(adreno_gpu)) { + lower_bit = 1; + amsbc = 1; + rgb565_predicator = 1; + uavflagprd_inv = 2; + } + gpu_write(gpu, REG_A6XX_RB_NC_MODE_CNTL, rgb565_predicator << 11 | amsbc << 4 | lower_bit << 1); gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL, lower_bit << 1); @@ -787,7 +794,7 @@ static bool a6xx_ucode_check_version(struct a6xx_gpu *a6xx_gpu, DRM_DEV_ERROR(&gpu->pdev->dev, "a650 SQE ucode is too old. Have version %x need at least %x\n", buf[0] & 0xfff, 0x095); - } else if (adreno_is_a660(adreno_gpu)) { + } else if (adreno_is_a660_fami
Re: [Freedreno] [RFC PATCH] drm/msm: Introduce Adreno Features
On 7/29/2021 9:26 PM, Rob Clark wrote: On Thu, Jul 29, 2021 at 8:31 AM Akhil P Oommen wrote: Introduce a feature flag in gpulist to easily identify the capabilities of each gpu revision. This will help to avoid a lot of adreno_is_axxx() check when we add new features. In the current patch, HW APRIV feature is converted to a feature flag. Signed-off-by: Akhil P Oommen --- This patch is rebased on top of the below series: https://patchwork.freedesktop.org/series/93192/ drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 12 drivers/gpu/drm/msm/adreno/adreno_device.c | 3 +++ drivers/gpu/drm/msm/adreno/adreno_gpu.c| 3 +++ drivers/gpu/drm/msm/adreno/adreno_gpu.h| 9 + 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 1881e09..b28305b 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1765,7 +1765,6 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) struct msm_drm_private *priv = dev->dev_private; struct platform_device *pdev = priv->gpu_pdev; struct adreno_platform_config *config = pdev->dev.platform_data; - const struct adreno_info *info; struct device_node *node; struct a6xx_gpu *a6xx_gpu; struct adreno_gpu *adreno_gpu; @@ -1781,17 +1780,6 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) adreno_gpu->registers = NULL; - /* -* We need to know the platform type before calling into adreno_gpu_init -* so that the hw_apriv flag can be correctly set. Snoop into the info -* and grab the revision number -*/ - info = adreno_info(config->rev); - - if (info && (info->revn == 650 || info->revn == 660 || - adreno_cmp_rev(ADRENO_REV(6, 3, 5, ANY_ID), info->rev))) - adreno_gpu->base.hw_apriv = true; - a6xx_llc_slices_init(pdev, a6xx_gpu); ret = a6xx_set_supported_hw(&pdev->dev, config->rev); diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 7b9d605..44321ec 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -276,6 +276,7 @@ static const struct adreno_info gpulist[] = { .rev = ADRENO_REV(6, 5, 0, ANY_ID), .revn = 650, .name = "A650", + .features = ADRENO_APRIV, I guess this should be: .features = BIT(ADRENO_APRIV), D'oh! .fw = { [ADRENO_FW_SQE] = "a650_sqe.fw", [ADRENO_FW_GMU] = "a650_gmu.bin", @@ -289,6 +290,7 @@ static const struct adreno_info gpulist[] = { .rev = ADRENO_REV(6, 6, 0, ANY_ID), .revn = 660, .name = "A660", + .features = ADRENO_APRIV, .fw = { [ADRENO_FW_SQE] = "a660_sqe.fw", [ADRENO_FW_GMU] = "a660_gmu.bin", @@ -301,6 +303,7 @@ static const struct adreno_info gpulist[] = { }, { .rev = ADRENO_REV(6, 3, 5, ANY_ID), .name = "Adreno 7c Gen 3", + .features = ADRENO_APRIV, .fw = { [ADRENO_FW_SQE] = "a660_sqe.fw", [ADRENO_FW_GMU] = "a660_gmu.bin", diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 9f5a302..e8acadf5 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -945,6 +945,9 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, pm_runtime_use_autosuspend(dev); pm_runtime_enable(dev); + if (ADRENO_FEAT(adreno_gpu, ADRENO_APRIV)) + adreno_gpu->base.hw_apriv = true; + return msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base, adreno_gpu->info->name, &adreno_gpu_config); } diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index 50b4d53..61797c3 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -35,6 +35,11 @@ enum adreno_quirks { ADRENO_QUIRK_LMLOADKILL_DISABLE = 3, }; +enum adreno_features { + /* ADRENO has HW APRIV feature */ + ADRENO_APRIV, +}; + struct adreno_rev { uint8_t core; uint8_t major; @@ -63,6 +68,7 @@ struct adreno_info { struct adreno_rev rev; uint32_t revn; const char *name; + u32 features; const char *fw[ADRENO_FW_MAX]; uint32_t gmem; enum adreno_
Re: [Freedreno] [PATCH v2] arm64: dts: qcom: sc7280: Add gpu support
On 7/29/2021 10:46 PM, Stephen Boyd wrote: Quoting Akhil P Oommen (2021-07-28 00:17:45) On 7/27/2021 5:46 AM, Stephen Boyd wrote: Quoting Akhil P Oommen (2021-07-24 10:29:00) Add the necessary dt nodes for gpu support in sc7280. Signed-off-by: Akhil P Oommen --- This patch has dependency on the GPUCC bindings patch here: https://patchwork.kernel.org/project/linux-arm-msm/patch/1619519590-3019-4-git-send-email-t...@codeaurora.org/ To avoid the dependency the plain numbers can be used. But, won't that reduce readability and make things prone to error? The numbers are not supposed to change so maybe it reduces readability but I don't see how it is prone to error. I cross check GPU's clock list whenever there is a system level issue like NoC errors. So it is convenient to have the clock names here, at least for me. But, I will budge if it is not easy to manage the dependency. If the other patch doesn't get picked up soon, we should try this option. We like to get this patch merged in v5.15. The clk binding is already picked up but Bjorn would need to merge it into the qcom tree to use it. I don't know what the plan is there. Bjorn, could you please advise here? -Akhil. ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v4 0/3] Support Adreno 7c Gen 3 gpu
This series adds support for the gpu found in the Snapdragon 7c Gen 3 compute platform. This gpu is similar to the exisiting a660 gpu with minor delta in the programing sequence. As the Adreno GPUs are moving away from a numeric chipid based naming scheme to a string, it was decided to use 0x06030500 as the chip id of this gpu to communicate to the userspace driver. Changes in v4: - Move adreno_cmp_rev() to patch-2/3 to fix compilation - Minor updates to commit msg (Rob) Changes in v3: - Add a cover letter. Changes in v2: - Use rev to identify SKU - Introduce adreno_is_a660_family() (Rob) - Remove revn for 7c3 (Rob) - Remove CPR register programing since they are not required for 7c3 Akhil P Oommen (3): drm/msm/a6xx: Fix llcc configuration for a660 gpu drm/msm/a6xx: Use rev to identify SKU drm/msm/a6xx: Add support for Adreno 7c Gen 3 gpu drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 8 ++- drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 1 + drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 87 ++ drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 32 +++ drivers/gpu/drm/msm/adreno/adreno_device.c | 27 +++--- drivers/gpu/drm/msm/adreno/adreno_gpu.h| 18 ++- 6 files changed, 129 insertions(+), 44 deletions(-) -- 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 v4 1/3] drm/msm/a6xx: Fix llcc configuration for a660 gpu
Add the missing scache_cntl0 register programing which is required for a660 gpu. Signed-off-by: Akhil P Oommen --- (no changes since v1) drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 46 --- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 9c5e461..183b9f9 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1383,13 +1383,13 @@ static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu) { struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; struct msm_gpu *gpu = &adreno_gpu->base; - u32 cntl1_regval = 0; + u32 gpu_scid, cntl1_regval = 0; if (IS_ERR(a6xx_gpu->llc_mmio)) return; if (!llcc_slice_activate(a6xx_gpu->llc_slice)) { - u32 gpu_scid = llcc_get_slice_id(a6xx_gpu->llc_slice); + gpu_scid = llcc_get_slice_id(a6xx_gpu->llc_slice); gpu_scid &= 0x1f; cntl1_regval = (gpu_scid << 0) | (gpu_scid << 5) | (gpu_scid << 10) | @@ -1409,26 +1409,34 @@ static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu) } } - if (cntl1_regval) { + if (!cntl1_regval) + return; + + /* +* Program the slice IDs for the various GPU blocks and GPU MMU +* pagetables +*/ + if (!a6xx_gpu->have_mmu500) { + a6xx_llc_write(a6xx_gpu, + REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_1, cntl1_regval); + /* -* Program the slice IDs for the various GPU blocks and GPU MMU -* pagetables +* Program cacheability overrides to not allocate cache +* lines on a write miss */ - if (a6xx_gpu->have_mmu500) - gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL1, GENMASK(24, 0), - cntl1_regval); - else { - a6xx_llc_write(a6xx_gpu, - REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_1, cntl1_regval); - - /* -* Program cacheability overrides to not allocate cache -* lines on a write miss -*/ - a6xx_llc_rmw(a6xx_gpu, - REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_0, 0xF, 0x03); - } + a6xx_llc_rmw(a6xx_gpu, + REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_0, 0xF, 0x03); + return; } + + gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL1, GENMASK(24, 0), cntl1_regval); + + /* On A660, the SCID programming for UCHE traffic is done in +* A6XX_GBIF_SCACHE_CNTL0[14:10] +*/ + if (adreno_is_a660(adreno_gpu)) + gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL0, (0x1f << 10) | + (1 << 8), (gpu_scid << 10) | (1 << 8)); } static void a6xx_llc_slices_destroy(struct a6xx_gpu *a6xx_gpu) -- 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 v4 2/3] drm/msm/a6xx: Use rev to identify SKU
Use rev instead of revn to identify the SKU. This is in preparation to the introduction of 7c3 gpu which won't have a revn. Signed-off-by: Akhil P Oommen --- Changes in v4: - Move adreno_cmp_rev() here to fix compilation drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 11 +-- drivers/gpu/drm/msm/adreno/adreno_device.c | 16 ++-- drivers/gpu/drm/msm/adreno/adreno_gpu.h| 4 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 183b9f9..0da1a66 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1675,11 +1675,11 @@ static u32 a618_get_speed_bin(u32 fuse) return UINT_MAX; } -static u32 fuse_to_supp_hw(struct device *dev, u32 revn, u32 fuse) +static u32 fuse_to_supp_hw(struct device *dev, struct adreno_rev rev, u32 fuse) { u32 val = UINT_MAX; - if (revn == 618) + if (adreno_cmp_rev(ADRENO_REV(6, 1, 8, ANY_ID), rev)) val = a618_get_speed_bin(fuse); if (val == UINT_MAX) { @@ -1692,8 +1692,7 @@ static u32 fuse_to_supp_hw(struct device *dev, u32 revn, u32 fuse) return (1 << val); } -static int a6xx_set_supported_hw(struct device *dev, struct a6xx_gpu *a6xx_gpu, - u32 revn) +static int a6xx_set_supported_hw(struct device *dev, struct adreno_rev rev) { u32 supp_hw = UINT_MAX; u16 speedbin; @@ -1714,7 +1713,7 @@ static int a6xx_set_supported_hw(struct device *dev, struct a6xx_gpu *a6xx_gpu, } speedbin = le16_to_cpu(speedbin); - supp_hw = fuse_to_supp_hw(dev, revn, speedbin); + supp_hw = fuse_to_supp_hw(dev, rev, speedbin); done: ret = devm_pm_opp_set_supported_hw(dev, &supp_hw, 1); @@ -1785,7 +1784,7 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) a6xx_llc_slices_init(pdev, a6xx_gpu); - ret = a6xx_set_supported_hw(&pdev->dev, a6xx_gpu, info->revn); + ret = a6xx_set_supported_hw(&pdev->dev, config->rev); if (ret) { a6xx_destroy(&(a6xx_gpu->base.base)); return ERR_PTR(ret); diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 6dad801..7e6fafe 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -8,8 +8,6 @@ #include "adreno_gpu.h" -#define ANY_ID 0xff - bool hang_debug = false; MODULE_PARM_DESC(hang_debug, "Dump registers when hang is detected (can be slow!)"); module_param_named(hang_debug, hang_debug, bool, 0600); @@ -325,6 +323,15 @@ static inline bool _rev_match(uint8_t entry, uint8_t id) return (entry == ANY_ID) || (entry == id); } +bool adreno_cmp_rev(struct adreno_rev rev1, struct adreno_rev rev2) +{ + + return _rev_match(rev1.core, rev2.core) && + _rev_match(rev1.major, rev2.major) && + _rev_match(rev1.minor, rev2.minor) && + _rev_match(rev1.patchid, rev2.patchid); +} + const struct adreno_info *adreno_info(struct adreno_rev rev) { int i; @@ -332,10 +339,7 @@ const struct adreno_info *adreno_info(struct adreno_rev rev) /* identify gpu: */ for (i = 0; i < ARRAY_SIZE(gpulist); i++) { const struct adreno_info *info = &gpulist[i]; - if (_rev_match(info->rev.core, rev.core) && - _rev_match(info->rev.major, rev.major) && - _rev_match(info->rev.minor, rev.minor) && - _rev_match(info->rev.patchid, rev.patchid)) + if (adreno_cmp_rev(info->rev, rev)) return info; } diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index 8dbe0d1..a368a16 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -42,6 +42,8 @@ struct adreno_rev { uint8_t patchid; }; +#define ANY_ID 0xff + #define ADRENO_REV(core, major, minor, patchid) \ ((struct adreno_rev){ core, major, minor, patchid }) @@ -141,6 +143,8 @@ struct adreno_platform_config { __ret; \ }) +bool adreno_cmp_rev(struct adreno_rev rev1, struct adreno_rev rev2); + static inline bool adreno_is_a2xx(struct adreno_gpu *gpu) { return (gpu->revn < 300); -- 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 v4 3/3] drm/msm/a6xx: Add support for Adreno 7c Gen 3 gpu
This patch adds support for the gpu found in the Snapdragon 7c Gen 3 compute platform. This gpu is similar to the exisiting a660 gpu with minor delta in the programing sequence. As the Adreno GPUs are moving away from a numeric chipid based naming scheme to a string, it was decided to use 0x06030500 as the chip id of this gpu to communicate to the userspace driver. Signed-off-by: Akhil P Oommen --- Changes in v4: - Move out adreno_cmp_rev() to patch-2/3 to fix compilation Changes in v2: - Introduce adreno_is_a660_family() (Rob) - Remove revn for 7c3 (Rob) - Remove CPR register programing since they are not required for 7c3 drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 8 ++-- drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 1 + drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 32 -- drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 32 ++ drivers/gpu/drm/msm/adreno/adreno_device.c | 11 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.h| 14 - 6 files changed, 84 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index b349692..70ba3bf 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -519,7 +519,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu) if (!pdcptr) goto err; - if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu)) + if (adreno_is_a650(adreno_gpu) || adreno_is_a660_family(adreno_gpu)) pdc_in_aop = true; else if (adreno_is_a618(adreno_gpu) || adreno_is_a640(adreno_gpu)) pdc_address_offset = 0x30090; @@ -933,6 +933,7 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu) /* Use a known rate to bring up the GMU */ clk_set_rate(gmu->core_clk, 2); + clk_set_rate(gmu->hub_clk, 15000); ret = clk_bulk_prepare_enable(gmu->nr_clocks, gmu->clocks); if (ret) { pm_runtime_put(gmu->gxpd); @@ -1393,6 +1394,9 @@ static int a6xx_gmu_clocks_probe(struct a6xx_gmu *gmu) gmu->core_clk = msm_clk_bulk_get_clock(gmu->clocks, gmu->nr_clocks, "gmu"); + gmu->hub_clk = msm_clk_bulk_get_clock(gmu->clocks, + gmu->nr_clocks, "hub"); + return 0; } @@ -1504,7 +1508,7 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) * are otherwise unused by a660. */ gmu->dummy.size = SZ_4K; - if (adreno_is_a660(adreno_gpu)) { + if (adreno_is_a660_family(adreno_gpu)) { ret = a6xx_gmu_memory_alloc(gmu, &gmu->debug, SZ_4K * 7, 0x6040); if (ret) goto err_memory; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h index 71dfa600..3c74f64 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h @@ -66,6 +66,7 @@ struct a6xx_gmu { int nr_clocks; struct clk_bulk_data *clocks; struct clk *core_clk; + struct clk *hub_clk; /* current performance index set externally */ int current_perf_index; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 0da1a66..1881e09 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -652,7 +652,7 @@ static void a6xx_set_cp_protect(struct msm_gpu *gpu) regs = a650_protect; count = ARRAY_SIZE(a650_protect); count_max = 48; - } else if (adreno_is_a660(adreno_gpu)) { + } else if (adreno_is_a660_family(adreno_gpu)) { regs = a660_protect; count = ARRAY_SIZE(a660_protect); count_max = 48; @@ -694,6 +694,13 @@ static void a6xx_set_ubwc_config(struct msm_gpu *gpu) uavflagprd_inv = 2; } + if (adreno_is_7c3(adreno_gpu)) { + lower_bit = 1; + amsbc = 1; + rgb565_predicator = 1; + uavflagprd_inv = 2; + } + gpu_write(gpu, REG_A6XX_RB_NC_MODE_CNTL, rgb565_predicator << 11 | amsbc << 4 | lower_bit << 1); gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL, lower_bit << 1); @@ -787,7 +794,7 @@ static bool a6xx_ucode_check_version(struct a6xx_gpu *a6xx_gpu, DRM_DEV_ERROR(&gpu->pdev->dev, "a650 SQE ucode is too old. Have version %x need at least %x\n", buf[0] & 0xfff, 0x095); - } else if (adreno_is_a660(adreno_gpu)) { + } else if (adreno_is_a660_family(adreno_gpu)) { ret = true; } else { DRM_DEV_ERROR(&gpu->pdev->dev, @@ -941,7 +948,7 @@ static int a6xx_hw_
Re: [Freedreno] [PATCH] drm: msm: Add 680 gpu to the adreno gpu list
On 7/30/2021 5:38 AM, Rob Clark wrote: On Sat, Jul 24, 2021 at 8:21 PM Bjorn Andersson wrote: This patch adds a Adreno 680 entry to the gpulist. Looks reasonable, but I wonder if we should just go ahead and add adreno_is_a640_family() in a similar vein to adreno_is_a650_familiy()/adreno_is_a660_family().. I think most of the 'if (a640) ...' should also apply to a680? If there is no delta, wouldn't it be better to simply add a680 to adreno_is_a640? -Akhil. BR, -R Signed-off-by: Bjorn Andersson --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 5 +++-- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 12 +++- drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 2 +- drivers/gpu/drm/msm/adreno/adreno_device.c | 13 + drivers/gpu/drm/msm/adreno/adreno_gpu.h| 5 + 5 files changed, 29 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index b349692219b7..1c0d75e1189f 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -521,7 +521,8 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu) if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu)) pdc_in_aop = true; - else if (adreno_is_a618(adreno_gpu) || adreno_is_a640(adreno_gpu)) + else if (adreno_is_a618(adreno_gpu) || adreno_is_a640(adreno_gpu) || +adreno_is_a680(adreno_gpu)) pdc_address_offset = 0x30090; else pdc_address_offset = 0x30080; @@ -1522,7 +1523,7 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) SZ_16M - SZ_16K, 0x04000); if (ret) goto err_memory; - } else if (adreno_is_a640(adreno_gpu)) { + } else if (adreno_is_a640(adreno_gpu) || adreno_is_a680(adreno_gpu)) { ret = a6xx_gmu_memory_alloc(gmu, &gmu->icache, SZ_256K - SZ_16K, 0x04000); if (ret) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 9c5e4618aa0a..5cdafc6c8bb0 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -683,7 +683,7 @@ static void a6xx_set_ubwc_config(struct msm_gpu *gpu) if (adreno_is_a618(adreno_gpu)) return; - if (adreno_is_a640(adreno_gpu)) + if (adreno_is_a640(adreno_gpu) || adreno_is_a680(adreno_gpu)) amsbc = 1; if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu)) { @@ -757,7 +757,7 @@ static bool a6xx_ucode_check_version(struct a6xx_gpu *a6xx_gpu, * a660 targets have all the critical security fixes from the start */ if (adreno_is_a618(adreno_gpu) || adreno_is_a630(adreno_gpu) || - adreno_is_a640(adreno_gpu)) { + adreno_is_a640(adreno_gpu) || adreno_is_a680(adreno_gpu)) { /* * If the lowest nibble is 0xa that is an indication that this * microcode has been patched. The actual version is in dword @@ -897,7 +897,8 @@ static int a6xx_hw_init(struct msm_gpu *gpu) a6xx_set_hwcg(gpu, true); /* VBIF/GBIF start*/ - if (adreno_is_a640(adreno_gpu) || adreno_is_a650_family(adreno_gpu)) { + if (adreno_is_a640(adreno_gpu) || adreno_is_a650_family(adreno_gpu) || + adreno_is_a680(adreno_gpu)) { gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE0, 0x00071620); gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE1, 0x00071620); gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE2, 0x00071620); @@ -935,7 +936,8 @@ static int a6xx_hw_init(struct msm_gpu *gpu) gpu_write(gpu, REG_A6XX_UCHE_FILTER_CNTL, 0x804); gpu_write(gpu, REG_A6XX_UCHE_CACHE_WAYS, 0x4); - if (adreno_is_a640(adreno_gpu) || adreno_is_a650_family(adreno_gpu)) + if (adreno_is_a640(adreno_gpu) || adreno_is_a650_family(adreno_gpu) || + adreno_is_a680(adreno_gpu)) gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x02000140); else gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x01c0); @@ -952,7 +954,7 @@ static int a6xx_hw_init(struct msm_gpu *gpu) */ if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu)) gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00300200); - else if (adreno_is_a640(adreno_gpu)) + else if (adreno_is_a640(adreno_gpu) || adreno_is_a680(adreno_gpu)) gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00200200); else gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x0018); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c index 919433732b43..df8af237cf6a 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c @@ -428,7 +428,7 @@ static i
Re: [Freedreno] [PATCH] drm/msm: Disable frequency clamping on a630
On 8/8/2021 10:22 PM, Rob Clark wrote: On Sun, Aug 8, 2021 at 7:33 AM Caleb Connolly wrote: On 07/08/2021 21:04, Rob Clark wrote: On Sat, Aug 7, 2021 at 12:21 PM Caleb Connolly wrote: Hi Rob, Akhil, On 29/07/2021 21:53, Rob Clark wrote: On Thu, Jul 29, 2021 at 1:28 PM Caleb Connolly wrote: On 29/07/2021 21:24, Rob Clark wrote: On Thu, Jul 29, 2021 at 1:06 PM Caleb Connolly wrote: Hi Rob, I've done some more testing! It looks like before that patch ("drm/msm: Devfreq tuning") the GPU would never get above the second frequency in the OPP table (342MHz) (at least, not in glxgears). With the patch applied it would more aggressively jump up to the max frequency which seems to be unstable at the default regulator voltages. *ohh*, yeah, ok, that would explain it Hacking the pm8005 s1 regulator (which provides VDD_GFX) up to 0.988v (instead of the stock 0.516v) makes the GPU stable at the higher frequencies. Applying this patch reverts the behaviour, and the GPU never goes above 342MHz in glxgears, losing ~30% performance in glxgear. I think (?) that enabling CPR support would be the proper solution to this - that would ensure that the regulators run at the voltage the hardware needs to be stable. Is hacking the voltage higher (although ideally not quite that high) an acceptable short term solution until we have CPR? Or would it be safer to just not make use of the higher frequencies on a630 for now? tbh, I'm not sure about the regulator stuff and CPR.. Bjorn is already on CC and I added sboyd, maybe one of them knows better. In the short term, removing the higher problematic OPPs from dts might be a better option than this patch (which I'm dropping), since there is nothing stopping other workloads from hitting higher OPPs. Oh yeah that sounds like a more sensible workaround than mine . I'm slightly curious why I didn't have problems at higher OPPs on my c630 laptop (sdm850) Perhaps you won the sillicon lottery - iirc sdm850 is binned for higher clocks as is out of the factory. Would it be best to drop the OPPs for all devices? Or just those affected? I guess it's possible another c630 might crash where yours doesn't? I've not heard any reports of similar issues from the handful of other folks with c630's on #aarch64-laptops.. but I can't really say if that is luck or not. It looks like this affects at least the OnePlus 6 and PocoPhone F1, I've done some more poking and the following diff seems to fix the stability issues completely, it seems the delay is required to let the update propagate. This doesn't feel like the right fix, but hopefully it's enough to come up with a better solution than disabling the new devfreq behaviour on a630. diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index d7cec7f0dde0..69e2a5e84dae 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -139,6 +139,10 @@ void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp) return; } + dev_pm_opp_set_opp(&gpu->pdev->dev, opp); + + usleep_range(300, 500); + I am a bit confused. We don't define a power domain for gpu in dt, correct? Then what exactly set_opp do here? Do you think this usleep is what is helping here somehow to mask the issue? I feel we should just leave the new dcvs feature (shall we call it NAP?) disabled for a630 (and 10ms devfreq interval), until this is root caused. Hmm, this is going to be in the critical path on idle -> active transition (ie. think response time to user-input).. so we defn don't want to do this unconditionally.. If I understand the problem, we just want to limit how far we jump the gpu freq in one go.. maybe deleting the lowest (and perhaps highest) OPP would accomplish that? Could that be done in the board(s)'s toplevel dts files? That would be a workaround, however I'd really like to avoid limiting performance as a solution if I can help it, especially as the fix might just be "set the opp first, wait for it to apply, then set the core clock". Is there a sensible way to get a callback from the opp notify chain? Or from rpmh directly? Or is this solution really not the right way to go? It does seem a bit strange to me that we are telling GMU to change freq before calling dev_pm_opp_set_opp().. if dev_pm_opp_set_opp() is increasing voltage, it seems like you'd want to do that *before* increasing freq (but reverse the order when decreasing freq).. But I'm not an expert on the ways of the GMU.. maybe Akhil or Jordan knows better how this is supposed to work. For legacy gmu, we trigger DCVS using DCVS OOB which comes later in this function. But the order between regulator and clock which you mentioned is correct. But the delay seems like papering something over, and I'm trying to go in the other direction and reduce latency between user input and pageflip.. BR, -R BR, -R
Re: [Freedreno] [PATCH] drm/msm: Disable frequency clamping on a630
On 8/9/2021 9:48 PM, Caleb Connolly wrote: On 09/08/2021 17:12, Rob Clark wrote: On Mon, Aug 9, 2021 at 7:52 AM Akhil P Oommen wrote: On 8/8/2021 10:22 PM, Rob Clark wrote: On Sun, Aug 8, 2021 at 7:33 AM Caleb Connolly wrote: On 07/08/2021 21:04, Rob Clark wrote: On Sat, Aug 7, 2021 at 12:21 PM Caleb Connolly wrote: Hi Rob, Akhil, On 29/07/2021 21:53, Rob Clark wrote: On Thu, Jul 29, 2021 at 1:28 PM Caleb Connolly wrote: On 29/07/2021 21:24, Rob Clark wrote: On Thu, Jul 29, 2021 at 1:06 PM Caleb Connolly wrote: Hi Rob, I've done some more testing! It looks like before that patch ("drm/msm: Devfreq tuning") the GPU would never get above the second frequency in the OPP table (342MHz) (at least, not in glxgears). With the patch applied it would more aggressively jump up to the max frequency which seems to be unstable at the default regulator voltages. *ohh*, yeah, ok, that would explain it Hacking the pm8005 s1 regulator (which provides VDD_GFX) up to 0.988v (instead of the stock 0.516v) makes the GPU stable at the higher frequencies. Applying this patch reverts the behaviour, and the GPU never goes above 342MHz in glxgears, losing ~30% performance in glxgear. I think (?) that enabling CPR support would be the proper solution to this - that would ensure that the regulators run at the voltage the hardware needs to be stable. Is hacking the voltage higher (although ideally not quite that high) an acceptable short term solution until we have CPR? Or would it be safer to just not make use of the higher frequencies on a630 for now? tbh, I'm not sure about the regulator stuff and CPR.. Bjorn is already on CC and I added sboyd, maybe one of them knows better. In the short term, removing the higher problematic OPPs from dts might be a better option than this patch (which I'm dropping), since there is nothing stopping other workloads from hitting higher OPPs. Oh yeah that sounds like a more sensible workaround than mine . I'm slightly curious why I didn't have problems at higher OPPs on my c630 laptop (sdm850) Perhaps you won the sillicon lottery - iirc sdm850 is binned for higher clocks as is out of the factory. Would it be best to drop the OPPs for all devices? Or just those affected? I guess it's possible another c630 might crash where yours doesn't? I've not heard any reports of similar issues from the handful of other folks with c630's on #aarch64-laptops.. but I can't really say if that is luck or not. It looks like this affects at least the OnePlus 6 and PocoPhone F1, I've done some more poking and the following diff seems to fix the stability issues completely, it seems the delay is required to let the update propagate. This doesn't feel like the right fix, but hopefully it's enough to come up with a better solution than disabling the new devfreq behaviour on a630. diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index d7cec7f0dde0..69e2a5e84dae 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -139,6 +139,10 @@ void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp) return; } + dev_pm_opp_set_opp(&gpu->pdev->dev, opp); + + usleep_range(300, 500); + I am a bit confused. We don't define a power domain for gpu in dt, correct? Then what exactly set_opp do here? Do you think this usleep is what is helping here somehow to mask the issue? The power domains (for cx and gx) are defined in the GMU DT, the OPPs in the GPU DT. For the sake of simplicity I'll refer to the lowest frequency (25700) and OPP level (RPMH_REGULATOR_LEVEL_LOW_SVS) as the "min" state, and the highest frequency (71000) and OPP level (RPMH_REGULATOR_LEVEL_TURBO_L1) as the "max" state. These are defined in sdm845.dtsi under the gpu node. The new devfreq behaviour unmasks what I think is a driver bug, it inadvertently puts much more strain on the GPU regulators than they usually get. With the new behaviour the GPU jumps from it's min state to the max state and back again extremely rapidly under workloads as small as refreshing UI. Where previously the GPU would rarely if ever go above 342MHz when interacting with the device, it now jumps between min and max many times per second. If my understanding is correct, the current implementation of the GMU set freq is the following: - Get OPP for frequency to set - Push the frequency to the GMU - immediately updating the core clock - Call dev_pm_opp_set_opp() which triggers a notify chain, this winds up somewhere in power management code and causes the gx regulator level to be updated Nope. dev_pm_opp_set_opp() sets the bandwidth for gpu and nothing else. We were using a different api earlier which got deprecated - dev_pm
[Freedreno] [PATCH v4 2/2] arm64: dts: qcom: sc7280: Add gpu thermal zone cooling support
From: Manaf Meethalavalappu Pallikunhi Add cooling-cells property and the cooling maps for the gpu thermal zones to support GPU thermal cooling. Signed-off-by: Manaf Meethalavalappu Pallikunhi Signed-off-by: Akhil P Oommen --- (no changes since v1) arch/arm64/boot/dts/qcom/sc7280.dtsi | 29 ++--- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi index b9006d8..cd2bbf0 100644 --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi @@ -592,7 +592,7 @@ qcom,bcm-voters = <&apps_bcm_voter>; }; - gpu@3d0 { + gpu: gpu@3d0 { compatible = "qcom,adreno-635.0", "qcom,adreno"; #stream-id-cells = <16>; reg = <0 0x03d0 0 0x4>, @@ -607,6 +607,7 @@ qcom,gmu = <&gmu>; interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "gfx-mem"; + #cooling-cells = <2>; gpu_opp_table: opp-table { compatible = "operating-points-v2"; @@ -2523,16 +2524,16 @@ }; gpuss0-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <100>; polling-delay = <0>; thermal-sensors = <&tsens1 1>; trips { gpuss0_alert0: trip-point0 { - temperature = <9>; + temperature = <95000>; hysteresis = <2000>; - type = "hot"; + type = "passive"; }; gpuss0_crit: gpuss0-crit { @@ -2541,19 +2542,26 @@ type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss0_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss1-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <100>; polling-delay = <0>; thermal-sensors = <&tsens1 2>; trips { gpuss1_alert0: trip-point0 { - temperature = <9>; + temperature = <95000>; hysteresis = <2000>; - type = "hot"; + type = "passive"; }; gpuss1_crit: gpuss1-crit { @@ -2562,6 +2570,13 @@ type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss1_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; nspss0-thermal { -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation.
[Freedreno] [PATCH v4 1/2] arm64: dts: qcom: sc7280: Add gpu support
Add the necessary dt nodes for gpu support in sc7280. Signed-off-by: Akhil P Oommen --- Changes in v4: - Removed the dependency on gpucc bindings (Stephen) - Reordered GPU's opp table Changes in v3: - Re-ordered the nodes based on address (Stephen) - Added the patch for gpu cooling to the stack. Changes in v2: - formatting update and removed a duplicate header (Stephen) arch/arm64/boot/dts/qcom/sc7280.dtsi | 115 +++ 1 file changed, 115 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi index 029723a..b9006d8 100644 --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi @@ -592,6 +592,85 @@ qcom,bcm-voters = <&apps_bcm_voter>; }; + gpu@3d0 { + compatible = "qcom,adreno-635.0", "qcom,adreno"; + #stream-id-cells = <16>; + reg = <0 0x03d0 0 0x4>, + <0 0x03d9e000 0 0x1000>, + <0 0x03d61000 0 0x800>; + reg-names = "kgsl_3d0_reg_memory", + "cx_mem", + "cx_dbgc"; + interrupts = ; + iommus = <&adreno_smmu 0 0x401>; + operating-points-v2 = <&gpu_opp_table>; + qcom,gmu = <&gmu>; + interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "gfx-mem"; + + gpu_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-31500 { + opp-hz = /bits/ 64 <31500>; + opp-level = ; + opp-peak-kBps = <1804000>; + }; + + opp-45000 { + opp-hz = /bits/ 64 <45000>; + opp-level = ; + opp-peak-kBps = <4068000>; + }; + + opp-55000 { + opp-hz = /bits/ 64 <55000>; + opp-level = ; + opp-peak-kBps = <6832000>; + }; + }; + }; + + gmu: gmu@3d69000 { + compatible="qcom,adreno-gmu-635.0", "qcom,adreno-gmu"; + reg = <0 0x03d6a000 0 0x34000>, + <0 0x3de 0 0x1>, + <0 0x0b29 0 0x1>; + reg-names = "gmu", "rscc", "gmu_pdc"; + interrupts = , + ; + interrupt-names = "hfi", "gmu"; + clocks = <&gpucc 5>, + <&gpucc 8>, + <&gcc GCC_DDRSS_GPU_AXI_CLK>, + <&gcc GCC_GPU_MEMNOC_GFX_CLK>, + <&gpucc 2>, + <&gpucc 15>, + <&gpucc 11>; + clock-names = "gmu", + "cxo", + "axi", + "memnoc", + "ahb", + "hub", + "smmu_vote"; + power-domains = <&gpucc 0>, + <&gpucc 1>; + power-domain-names = "cx", +"gx"; + iommus = <&adreno_smmu 5 0x400>; + operating-points-v2 = <&gmu_opp_table>; + + gmu_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-2 { + opp-hz = /bits/ 64 <2>; + opp-level = ; + }; +
[Freedreno] [PATCH v5 1/2] arm64: dts: qcom: sc7280: Add gpu support
Add the necessary dt nodes for gpu support in sc7280. Signed-off-by: Akhil P Oommen --- Changes in v5: - Added Stephen's reviewed-by tag to patch-2 Changes in v4: - Removed the dependency on gpucc bindings (Stephen) - Reordered GPU's opp table Changes in v3: - Re-ordered the nodes based on address (Stephen) - Added the patch for gpu cooling to the stack. Changes in v2: - formatting update and removed a duplicate header (Stephen) arch/arm64/boot/dts/qcom/sc7280.dtsi | 115 +++ 1 file changed, 115 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi index 029723a..b9006d8 100644 --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi @@ -592,6 +592,85 @@ qcom,bcm-voters = <&apps_bcm_voter>; }; + gpu@3d0 { + compatible = "qcom,adreno-635.0", "qcom,adreno"; + #stream-id-cells = <16>; + reg = <0 0x03d0 0 0x4>, + <0 0x03d9e000 0 0x1000>, + <0 0x03d61000 0 0x800>; + reg-names = "kgsl_3d0_reg_memory", + "cx_mem", + "cx_dbgc"; + interrupts = ; + iommus = <&adreno_smmu 0 0x401>; + operating-points-v2 = <&gpu_opp_table>; + qcom,gmu = <&gmu>; + interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "gfx-mem"; + + gpu_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-31500 { + opp-hz = /bits/ 64 <31500>; + opp-level = ; + opp-peak-kBps = <1804000>; + }; + + opp-45000 { + opp-hz = /bits/ 64 <45000>; + opp-level = ; + opp-peak-kBps = <4068000>; + }; + + opp-55000 { + opp-hz = /bits/ 64 <55000>; + opp-level = ; + opp-peak-kBps = <6832000>; + }; + }; + }; + + gmu: gmu@3d69000 { + compatible="qcom,adreno-gmu-635.0", "qcom,adreno-gmu"; + reg = <0 0x03d6a000 0 0x34000>, + <0 0x3de 0 0x1>, + <0 0x0b29 0 0x1>; + reg-names = "gmu", "rscc", "gmu_pdc"; + interrupts = , + ; + interrupt-names = "hfi", "gmu"; + clocks = <&gpucc 5>, + <&gpucc 8>, + <&gcc GCC_DDRSS_GPU_AXI_CLK>, + <&gcc GCC_GPU_MEMNOC_GFX_CLK>, + <&gpucc 2>, + <&gpucc 15>, + <&gpucc 11>; + clock-names = "gmu", + "cxo", + "axi", + "memnoc", + "ahb", + "hub", + "smmu_vote"; + power-domains = <&gpucc 0>, + <&gpucc 1>; + power-domain-names = "cx", +"gx"; + iommus = <&adreno_smmu 5 0x400>; + operating-points-v2 = <&gmu_opp_table>; + + gmu_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-2 { + opp-hz = /bits/ 64 <2>; +
[Freedreno] [PATCH v5 2/2] arm64: dts: qcom: sc7280: Add gpu thermal zone cooling support
From: Manaf Meethalavalappu Pallikunhi Add cooling-cells property and the cooling maps for the gpu thermal zones to support GPU thermal cooling. Signed-off-by: Manaf Meethalavalappu Pallikunhi Signed-off-by: Akhil P Oommen Reviewed-by: Stephen Boyd --- (no changes since v1) arch/arm64/boot/dts/qcom/sc7280.dtsi | 29 ++--- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi index b9006d8..cd2bbf0 100644 --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi @@ -592,7 +592,7 @@ qcom,bcm-voters = <&apps_bcm_voter>; }; - gpu@3d0 { + gpu: gpu@3d0 { compatible = "qcom,adreno-635.0", "qcom,adreno"; #stream-id-cells = <16>; reg = <0 0x03d0 0 0x4>, @@ -607,6 +607,7 @@ qcom,gmu = <&gmu>; interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "gfx-mem"; + #cooling-cells = <2>; gpu_opp_table: opp-table { compatible = "operating-points-v2"; @@ -2523,16 +2524,16 @@ }; gpuss0-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <100>; polling-delay = <0>; thermal-sensors = <&tsens1 1>; trips { gpuss0_alert0: trip-point0 { - temperature = <9>; + temperature = <95000>; hysteresis = <2000>; - type = "hot"; + type = "passive"; }; gpuss0_crit: gpuss0-crit { @@ -2541,19 +2542,26 @@ type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss0_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss1-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <100>; polling-delay = <0>; thermal-sensors = <&tsens1 2>; trips { gpuss1_alert0: trip-point0 { - temperature = <9>; + temperature = <95000>; hysteresis = <2000>; - type = "hot"; + type = "passive"; }; gpuss1_crit: gpuss1-crit { @@ -2562,6 +2570,13 @@ type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss1_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; nspss0-thermal { -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation.
Re: [Freedreno] [PATCH] drm/msm: Disable frequency clamping on a630
On 9/9/2021 9:42 PM, Amit Pundir wrote: On Thu, 9 Sept 2021 at 17:47, Amit Pundir wrote: On Wed, 8 Sept 2021 at 07:50, Bjorn Andersson wrote: On Mon 09 Aug 10:26 PDT 2021, Akhil P Oommen wrote: On 8/9/2021 9:48 PM, Caleb Connolly wrote: On 09/08/2021 17:12, Rob Clark wrote: On Mon, Aug 9, 2021 at 7:52 AM Akhil P Oommen wrote: [..] I am a bit confused. We don't define a power domain for gpu in dt, correct? Then what exactly set_opp do here? Do you think this usleep is what is helping here somehow to mask the issue? The power domains (for cx and gx) are defined in the GMU DT, the OPPs in the GPU DT. For the sake of simplicity I'll refer to the lowest frequency (25700) and OPP level (RPMH_REGULATOR_LEVEL_LOW_SVS) as the "min" state, and the highest frequency (71000) and OPP level (RPMH_REGULATOR_LEVEL_TURBO_L1) as the "max" state. These are defined in sdm845.dtsi under the gpu node. The new devfreq behaviour unmasks what I think is a driver bug, it inadvertently puts much more strain on the GPU regulators than they usually get. With the new behaviour the GPU jumps from it's min state to the max state and back again extremely rapidly under workloads as small as refreshing UI. Where previously the GPU would rarely if ever go above 342MHz when interacting with the device, it now jumps between min and max many times per second. If my understanding is correct, the current implementation of the GMU set freq is the following: - Get OPP for frequency to set - Push the frequency to the GMU - immediately updating the core clock - Call dev_pm_opp_set_opp() which triggers a notify chain, this winds up somewhere in power management code and causes the gx regulator level to be updated Nope. dev_pm_opp_set_opp() sets the bandwidth for gpu and nothing else. We were using a different api earlier which got deprecated - dev_pm_opp_set_bw(). On the Lenovo Yoga C630 this is reproduced by starting alacritty and if I'm lucky I managed to hit a few keys before it crashes, so I spent a few hours looking into this as well... As you say, the dev_pm_opp_set_opp() will only cast a interconnect vote. The opp-level is just there for show and isn't used by anything, at least not on 845. Further more, I'm missing something in my tree, so the interconnect doesn't hit sync_state, and as such we're not actually scaling the buses. So the problem is not that Linux doesn't turn on the buses in time. So I suspect that the "AHB bus error" isn't saying that we turned off the bus, but rather that the GPU becomes unstable or something of that sort. Lastly, I reverted 9bc95570175a ("drm/msm: Devfreq tuning") and ran Aquarium for 20 minutes without a problem. I then switched the gpu devfreq governor to "userspace" and ran the following: while true; do echo 25700 > /sys/class/devfreq/500.gpu/userspace/set_freq echo 71000 > /sys/class/devfreq/500.gpu/userspace/set_freq done It took 19 iterations of this loop to crash the GPU. Ack. With your above script, I can reproduce a crash too on db845c (A630) running v5.14. I didn't get any crash log though and device just rebooted to USB crash mode. And same crash on RB5 (A650) too https://hastebin.com/raw/ejutetuwun Are we sure this is the same issue? It could be, but I thought we were seeing a bunch of random gpu errors (which may eventually hit device crash). -Akhil fwiw I can't reproduce this crash on RB5 so far with v5.15-rc1 merge window (HEAD: 477f70cd2a67) So the problem doesn't seem to be Rob's change, it's just that prior to it the chance to hitting it is way lower. Question is still what it is that we're triggering. Regards, Bjorn
Re: [Freedreno] [PATCH] drm/msm: Disable frequency clamping on a630
On 9/10/2021 11:04 PM, Caleb Connolly wrote: On 10/09/2021 18:18, Rob Clark wrote: On Tue, Sep 7, 2021 at 7:20 PM Bjorn Andersson wrote: On Mon 09 Aug 10:26 PDT 2021, Akhil P Oommen wrote: On 8/9/2021 9:48 PM, Caleb Connolly wrote: On 09/08/2021 17:12, Rob Clark wrote: On Mon, Aug 9, 2021 at 7:52 AM Akhil P Oommen wrote: [..] I am a bit confused. We don't define a power domain for gpu in dt, correct? Then what exactly set_opp do here? Do you think this usleep is what is helping here somehow to mask the issue? The power domains (for cx and gx) are defined in the GMU DT, the OPPs in the GPU DT. For the sake of simplicity I'll refer to the lowest frequency (25700) and OPP level (RPMH_REGULATOR_LEVEL_LOW_SVS) as the "min" state, and the highest frequency (71000) and OPP level (RPMH_REGULATOR_LEVEL_TURBO_L1) as the "max" state. These are defined in sdm845.dtsi under the gpu node. The new devfreq behaviour unmasks what I think is a driver bug, it inadvertently puts much more strain on the GPU regulators than they usually get. With the new behaviour the GPU jumps from it's min state to the max state and back again extremely rapidly under workloads as small as refreshing UI. Where previously the GPU would rarely if ever go above 342MHz when interacting with the device, it now jumps between min and max many times per second. If my understanding is correct, the current implementation of the GMU set freq is the following: - Get OPP for frequency to set - Push the frequency to the GMU - immediately updating the core clock - Call dev_pm_opp_set_opp() which triggers a notify chain, this winds up somewhere in power management code and causes the gx regulator level to be updated Nope. dev_pm_opp_set_opp() sets the bandwidth for gpu and nothing else. We were using a different api earlier which got deprecated - dev_pm_opp_set_bw(). On the Lenovo Yoga C630 this is reproduced by starting alacritty and if I'm lucky I managed to hit a few keys before it crashes, so I spent a few hours looking into this as well... As you say, the dev_pm_opp_set_opp() will only cast a interconnect vote. The opp-level is just there for show and isn't used by anything, at least not on 845. Further more, I'm missing something in my tree, so the interconnect doesn't hit sync_state, and as such we're not actually scaling the buses. So the problem is not that Linux doesn't turn on the buses in time. So I suspect that the "AHB bus error" isn't saying that we turned off the bus, but rather that the GPU becomes unstable or something of that sort. Lastly, I reverted 9bc95570175a ("drm/msm: Devfreq tuning") and ran Aquarium for 20 minutes without a problem. I then switched the gpu devfreq governor to "userspace" and ran the following: while true; do echo 25700 > /sys/class/devfreq/500.gpu/userspace/set_freq echo 71000 > /sys/class/devfreq/500.gpu/userspace/set_freq done It took 19 iterations of this loop to crash the GPU. I assume you still had aquarium running, to keep the gpu awake while you ran that loop? Fwiw, I modified this slightly to match sc7180's min/max gpu freq and could not trigger any issue.. interestingly sc7180 has a lower min freq (180) and higher max freq (800) so it was toggling over a wider freq range. I also tried on a device that had the higher 825MHz opp (since I noticed that was the only opp that used RPMH_REGULATOR_LEVEL_TURBO_L1 and wanted to rule that out), but could not reproduce. I guess a630 (sdm845) should have higher power draw (it is 2x # of shader cores and 2x GMEM size, but lower max freq).. the question is, is this the reason we see this on sdm845 and not sc7180? Or is there some other difference. On the gpu side of this, they are both closely related (ie. the same "sub-generation" of a6xx, same gmu fw, etc).. I'm less sure about the other parts (icc, rpmh, etc) My guess would be power draw, nobody has mentioned this yet but I've realised that the vdd_gfx rail is powered by a buck converter, which could explain a lot of the symptoms. Buck converters depend on high frequency switching and inductors to work, this inherently leads to some lag time when changing voltages, and also means that the behaviour of the regulator is defined in part by how much current is being drawn. Wikipedia has a pretty good explanation: https://en.wikipedia.org/wiki/Buck_converter At the best of times these regulators have a known voltage ripple, when under load and when rapidly switching voltages this will get a lot worse. Someone with an oscilloscope and schematics could probe the rail and probably see exactly what's going on when the GPU crashes. Because of the lag time in the regulator changing voltage, it might be undershooting whilst the GPU is trying to clock up and draw more current - causi
Re: [Freedreno] [PATCH] drm/msm: Switch ordering of runpm put vs devfreq_idle
On 9/27/2021 8:59 PM, Rob Clark wrote: From: Rob Clark I've seen a few crashes like: Internal error: synchronous external abort: 9610 [#1] PREEMPT SMP Modules linked in: snd_seq_dummy snd_seq snd_seq_device bridge stp llc tun nf_nat_tftp nf_conntrack_tftp nf_nat_ftp nf_conntrack_ftp esp6 ah6 ip6t_REJECT ip6t_ipv6header vhost_vsock vhost vmw_vsock_virtio_transport_common vsock rfcomm algif_hash algif_skcipher af_alg uinput veth xt_cgroup xt_MASQUERADE venus_enc venus_dec videobuf2_dma_contig qcom_spmi_adc5 qcom_spmi_adc_tm5 hci_uart qcom_vadc_common cros_ec_typec qcom_spmi_temp_alarm typec btqca snd_soc_rt5682_i2c snd_soc_rt5682 snd_soc_sc7180 bluetooth snd_soc_qcom_common snd_soc_rl6231 ecdh_generic ecc venus_core v4l2_mem2mem snd_soc_lpass_sc7180 snd_soc_lpass_hdmi snd_soc_lpass_cpu snd_soc_lpass_platform snd_soc_max98357a ip6table_nat fuse iio_trig_sysfs cros_ec_lid_angle cros_ec_sensors cros_ec_sensors_core industrialio_triggered_buffer kfifo_buf cros_ec_sensorhub lzo_rle ath10k_snoc lzo_compress ath10k_core ath zram mac80211 cfg80211 ax88179_178a usbnet mii uvcvideo videobuf2_vmalloc joydev CPU: 3 PID: 212 Comm: A618-worker Tainted: G W 5.4.139-16300-g88d8e1285982 #1 Hardware name: Google Pompom (rev1) with LTE (DT) pstate: 60c9 (nZCv daif +PAN +UAO) pc : a6xx_gmu_set_oob+0x114/0x200 lr : a6xx_gmu_set_oob+0x10c/0x200 sp : ffc011b7bc20 x29: ffc011b7bc20 x28: ffdad27c5000 x27: 0001 x26: ffdad1521044 x25: ffbef7498338 x24: 0018 x23: 0002 x22: 00014648 x21: 033732fe638b x20: 8000 x19: ffbef7433bc8 x18: 4000 x17: 00243508d982 x16: b67e x15: 90d4 x14: 0024 x13: 0024 x12: 00017521 x11: 0b48 x10: 00326a48 x9 : 1a130d33f6371600 x8 : ffc011e54648 x7 : 614948e5003c x6 : ffbe3cd17e60 x5 : 0040 x4 : 0004 x3 : x2 : ffbef7488000 x1 : ffbef7488000 x0 : Call trace: a6xx_gmu_set_oob+0x114/0x200 a6xx_gmu_set_freq+0xe0/0x1fc msm_devfreq_target+0x80/0x13c msm_devfreq_idle+0x54/0x94 retire_submit+0x170/0x254 retire_submits+0xa4/0xdc retire_worker+0x1c/0x28 kthread_worker_fn+0xf4/0x1bc kthread+0x140/0x158 ret_from_fork+0x10/0x18 Code: 52800c81 9415bbe5 f9400a68 8b160108 (b9400108) ---[ end trace 16b871df2482cd61 ]--- Kernel panic - not syncing: Fatal exception SMP: stopping secondary CPUs Kernel Offset: 0x1ac140 from 0xffc01000 PHYS_OFFSET: 0xffc28000 CPU features: 0x88102e,2a80aa38 Memory Limit: none Which smells a lot like touching hw after power collapse. I'm not *entirely* sure how it could have taken 66ms (the autosuspend delay) before we get to a6xx_gmu_set_oob(), but to be safe we should move the pm_runtime_put_autosuspend() after msm_devfreq_idle(). https://elixir.bootlin.com/linux/v5.15-rc1/source/drivers/gpu/drm/msm/adreno/a6xx_gmu.c#L132 We have this check in the gmu freq set path which should avoid this scenario. I might be a bit pedantic here, but I feel that the original code is more accurate. We should immediately mark last busy and put runtime_pm refcount. -Akhil. Fixes: 9bc95570175a ("drm/msm: Devfreq tuning") Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gpu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index d1a16642ecd5..2b2bbe7499e6 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -667,9 +667,6 @@ static void retire_submit(struct msm_gpu *gpu, struct msm_ringbuffer *ring, msm_submit_retire(submit); - pm_runtime_mark_last_busy(&gpu->pdev->dev); - pm_runtime_put_autosuspend(&gpu->pdev->dev); - spin_lock_irqsave(&ring->submit_lock, flags); list_del(&submit->node); spin_unlock_irqrestore(&ring->submit_lock, flags); @@ -683,6 +680,9 @@ static void retire_submit(struct msm_gpu *gpu, struct msm_ringbuffer *ring, mutex_unlock(&gpu->active_lock); msm_gem_submit_put(submit); + + pm_runtime_mark_last_busy(&gpu->pdev->dev); + pm_runtime_put_autosuspend(&gpu->pdev->dev); } static void retire_submits(struct msm_gpu *gpu)
Re: [Freedreno] [PATCH] drm/msm/a6xx: Serialize GMU communication
set_freq(gpu, opp); + mutex_unlock(&a6xx_gpu->gmu.lock); +} + static struct msm_gem_address_space * a6xx_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev) { @@ -1766,7 +1794,7 @@ static const struct adreno_gpu_funcs funcs = { #endif .gpu_busy = a6xx_gpu_busy, .gpu_get_freq = a6xx_gmu_get_freq, - .gpu_set_freq = a6xx_gmu_set_freq, + .gpu_set_freq = a6xx_gpu_set_freq, #if defined(CONFIG_DRM_MSM_GPU_STATE) .gpu_state_get = a6xx_gpu_state_get, .gpu_state_put = a6xx_gpu_state_put, I think I overlooked this because every hw access is serialized in the downstream driver. Reviewed-by: Akhil P Oommen -Akhil
Re: [Freedreno] [bug report] drm/msm/a6xx: Fix llcc configuration for a660 gpu
On 10/12/2021 3:30 PM, Dan Carpenter wrote: Hello Akhil P Oommen, The patch a6f24383f6c0: "drm/msm/a6xx: Fix llcc configuration for a660 gpu" from Jul 30, 2021, leads to the following Smatch static checker warning: drivers/gpu/drm/msm/adreno/a6xx_gpu.c:1480 a6xx_llc_activate() error: uninitialized symbol 'gpu_scid'. drivers/gpu/drm/msm/adreno/a6xx_gpu.c 1423 static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu) 1424 { 1425 struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; 1426 struct msm_gpu *gpu = &adreno_gpu->base; 1427 u32 gpu_scid, cntl1_regval = 0; 1428 1429 if (IS_ERR(a6xx_gpu->llc_mmio)) 1430 return; 1431 1432 if (!llcc_slice_activate(a6xx_gpu->llc_slice)) { 1433 gpu_scid = llcc_get_slice_id(a6xx_gpu->llc_slice); 1434 1435 gpu_scid &= 0x1f; 1436 cntl1_regval = (gpu_scid << 0) | (gpu_scid << 5) | (gpu_scid << 10) | 1437(gpu_scid << 15) | (gpu_scid << 20); 1438 } gpu_scid not initialized on the else path. 1439 1440 /* 1441 * For targets with a MMU500, activate the slice but don't program the 1442 * register. The XBL will take care of that. 1443 */ 1444 if (!llcc_slice_activate(a6xx_gpu->htw_llc_slice)) { 1445 if (!a6xx_gpu->have_mmu500) { 1446 u32 gpuhtw_scid = llcc_get_slice_id(a6xx_gpu->htw_llc_slice); 1447 1448 gpuhtw_scid &= 0x1f; 1449 cntl1_regval |= FIELD_PREP(GENMASK(29, 25), gpuhtw_scid); 1450 } 1451 } 1452 1453 if (!cntl1_regval) 1454 return; 1455 1456 /* 1457 * Program the slice IDs for the various GPU blocks and GPU MMU 1458 * pagetables 1459 */ 1460 if (!a6xx_gpu->have_mmu500) { 1461 a6xx_llc_write(a6xx_gpu, 1462 REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_1, cntl1_regval); 1463 1464 /* 1465 * Program cacheability overrides to not allocate cache 1466 * lines on a write miss 1467 */ 1468 a6xx_llc_rmw(a6xx_gpu, 1469 REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_0, 0xF, 0x03); 1470 return; 1471 } 1472 1473 gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL1, GENMASK(24, 0), cntl1_regval); 1474 1475 /* On A660, the SCID programming for UCHE traffic is done in 1476 * A6XX_GBIF_SCACHE_CNTL0[14:10] 1477 */ 1478 if (adreno_is_a660_family(adreno_gpu)) 1479 gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL0, (0x1f << 10) | --> 1480 (1 << 8), (gpu_scid << 10) | (1 << 8)); ^^ Used here. 1481 } regards, dan carpenter Thanks, Dan. I will fix this in the stack I share. -Akhil.
Re: [Freedreno] [PATCH v2] drm/msm/devfreq: Fix OPP refcnt leak
On 11/6/2021 1:50 AM, Rob Clark wrote: From: Rob Clark Reported-by: Douglas Anderson Fixes: 9bc95570175a ("drm/msm: Devfreq tuning") Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gpu_devfreq.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c b/drivers/gpu/drm/msm/msm_gpu_devfreq.c index d32b729b4616..07f1169df89b 100644 --- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c +++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c @@ -20,6 +20,10 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq, struct msm_gpu *gpu = dev_to_gpu(dev); struct dev_pm_opp *opp; + /* +* Note that devfreq_recommended_opp() can modify the freq +* to something that actually is in the opp table: +*/ opp = devfreq_recommended_opp(dev, freq, flags); /* @@ -28,6 +32,7 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq, */ if (gpu->devfreq.idle_freq) { gpu->devfreq.idle_freq = *freq; + dev_pm_opp_put(opp); return 0; } Reviewed-by: Akhil P Oommen -Akhil
Re: [Freedreno] [PATCH v4 07/13] drm/msm: Track "seqno" fences by idr
On 7/28/2021 6:36 AM, Rob Clark wrote: From: Rob Clark Previously the (non-fd) fence returned from submit ioctl was a raw seqno, which is scoped to the ring. But from UABI standpoint, the ioctls related to seqno fences all specify a submitqueue. We can take advantage of that to replace the seqno fences with a cyclic idr handle. This is in preperation for moving to drm scheduler, at which point the submit ioctl will return after queuing the submit job to the scheduler, but before the submit is written into the ring (and therefore before a ring seqno has been assigned). Which means we need to replace the dma_fence that userspace may need to wait on with a scheduler fence. Signed-off-by: Rob Clark Acked-by: Christian König --- drivers/gpu/drm/msm/msm_drv.c | 30 +-- drivers/gpu/drm/msm/msm_fence.c | 42 --- drivers/gpu/drm/msm/msm_fence.h | 3 -- drivers/gpu/drm/msm/msm_gem.h | 1 + drivers/gpu/drm/msm/msm_gem_submit.c | 23 ++- drivers/gpu/drm/msm/msm_gpu.h | 5 drivers/gpu/drm/msm/msm_submitqueue.c | 5 7 files changed, 61 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 9b8fa2ad0d84..1594ae39d54f 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -911,6 +911,7 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data, ktime_t timeout = to_ktime(args->timeout); struct msm_gpu_submitqueue *queue; struct msm_gpu *gpu = priv->gpu; + struct dma_fence *fence; int ret; if (args->pad) { @@ -925,10 +926,35 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data, if (!queue) return -ENOENT; - ret = msm_wait_fence(gpu->rb[queue->prio]->fctx, args->fence, &timeout, - true); + /* +* Map submitqueue scoped "seqno" (which is actually an idr key) +* back to underlying dma-fence +* +* The fence is removed from the fence_idr when the submit is +* retired, so if the fence is not found it means there is nothing +* to wait for +*/ + ret = mutex_lock_interruptible(&queue->lock); + if (ret) + return ret; + fence = idr_find(&queue->fence_idr, args->fence); + if (fence) + fence = dma_fence_get_rcu(fence); + mutex_unlock(&queue->lock); + + if (!fence) + return 0; + ret = dma_fence_wait_timeout(fence, true, timeout_to_jiffies(&timeout)); + if (ret == 0) { + ret = -ETIMEDOUT; + } else if (ret != -ERESTARTSYS) { + ret = 0; + } + + dma_fence_put(fence); msm_submitqueue_put(queue); + return ret; } diff --git a/drivers/gpu/drm/msm/msm_fence.c b/drivers/gpu/drm/msm/msm_fence.c index b92a9091a1e2..f2cece542c3f 100644 --- a/drivers/gpu/drm/msm/msm_fence.c +++ b/drivers/gpu/drm/msm/msm_fence.c @@ -24,7 +24,6 @@ msm_fence_context_alloc(struct drm_device *dev, volatile uint32_t *fenceptr, strncpy(fctx->name, name, sizeof(fctx->name)); fctx->context = dma_fence_context_alloc(1); fctx->fenceptr = fenceptr; - init_waitqueue_head(&fctx->event); spin_lock_init(&fctx->spinlock); return fctx; @@ -45,53 +44,12 @@ static inline bool fence_completed(struct msm_fence_context *fctx, uint32_t fenc (int32_t)(*fctx->fenceptr - fence) >= 0; } -/* legacy path for WAIT_FENCE ioctl: */ -int msm_wait_fence(struct msm_fence_context *fctx, uint32_t fence, - ktime_t *timeout, bool interruptible) -{ - int ret; - - if (fence > fctx->last_fence) { - DRM_ERROR_RATELIMITED("%s: waiting on invalid fence: %u (of %u)\n", - fctx->name, fence, fctx->last_fence); - return -EINVAL; Rob, we changed this pre-existing behaviour in this patch. Now, when userspace tries to wait on a future fence, we don't return an error. I just want to check if this was accidental or not? -Akhil. - } - - if (!timeout) { - /* no-wait: */ - ret = fence_completed(fctx, fence) ? 0 : -EBUSY; - } else { - unsigned long remaining_jiffies = timeout_to_jiffies(timeout); - - if (interruptible) - ret = wait_event_interruptible_timeout(fctx->event, - fence_completed(fctx, fence), - remaining_jiffies); - else - ret = wait_event_timeout(fctx->event, - fence_completed(fctx, fence), - remaining_jiffies); - - if (ret == 0) { - DBG("timeout waiting for fence: %u (completed: %u)", - fence, fctx->co
Re: [Freedreno] [PATCH v4 07/13] drm/msm: Track "seqno" fences by idr
On 11/10/2021 10:25 PM, Rob Clark wrote: On Wed, Nov 10, 2021 at 7:28 AM Akhil P Oommen wrote: On 7/28/2021 6:36 AM, Rob Clark wrote: From: Rob Clark Previously the (non-fd) fence returned from submit ioctl was a raw seqno, which is scoped to the ring. But from UABI standpoint, the ioctls related to seqno fences all specify a submitqueue. We can take advantage of that to replace the seqno fences with a cyclic idr handle. This is in preperation for moving to drm scheduler, at which point the submit ioctl will return after queuing the submit job to the scheduler, but before the submit is written into the ring (and therefore before a ring seqno has been assigned). Which means we need to replace the dma_fence that userspace may need to wait on with a scheduler fence. Signed-off-by: Rob Clark Acked-by: Christian König --- drivers/gpu/drm/msm/msm_drv.c | 30 +-- drivers/gpu/drm/msm/msm_fence.c | 42 --- drivers/gpu/drm/msm/msm_fence.h | 3 -- drivers/gpu/drm/msm/msm_gem.h | 1 + drivers/gpu/drm/msm/msm_gem_submit.c | 23 ++- drivers/gpu/drm/msm/msm_gpu.h | 5 drivers/gpu/drm/msm/msm_submitqueue.c | 5 7 files changed, 61 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 9b8fa2ad0d84..1594ae39d54f 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -911,6 +911,7 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data, ktime_t timeout = to_ktime(args->timeout); struct msm_gpu_submitqueue *queue; struct msm_gpu *gpu = priv->gpu; + struct dma_fence *fence; int ret; if (args->pad) { @@ -925,10 +926,35 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data, if (!queue) return -ENOENT; - ret = msm_wait_fence(gpu->rb[queue->prio]->fctx, args->fence, &timeout, - true); + /* + * Map submitqueue scoped "seqno" (which is actually an idr key) + * back to underlying dma-fence + * + * The fence is removed from the fence_idr when the submit is + * retired, so if the fence is not found it means there is nothing + * to wait for + */ + ret = mutex_lock_interruptible(&queue->lock); + if (ret) + return ret; + fence = idr_find(&queue->fence_idr, args->fence); + if (fence) + fence = dma_fence_get_rcu(fence); + mutex_unlock(&queue->lock); + + if (!fence) + return 0; + ret = dma_fence_wait_timeout(fence, true, timeout_to_jiffies(&timeout)); + if (ret == 0) { + ret = -ETIMEDOUT; + } else if (ret != -ERESTARTSYS) { + ret = 0; + } + + dma_fence_put(fence); msm_submitqueue_put(queue); + return ret; } diff --git a/drivers/gpu/drm/msm/msm_fence.c b/drivers/gpu/drm/msm/msm_fence.c index b92a9091a1e2..f2cece542c3f 100644 --- a/drivers/gpu/drm/msm/msm_fence.c +++ b/drivers/gpu/drm/msm/msm_fence.c @@ -24,7 +24,6 @@ msm_fence_context_alloc(struct drm_device *dev, volatile uint32_t *fenceptr, strncpy(fctx->name, name, sizeof(fctx->name)); fctx->context = dma_fence_context_alloc(1); fctx->fenceptr = fenceptr; - init_waitqueue_head(&fctx->event); spin_lock_init(&fctx->spinlock); return fctx; @@ -45,53 +44,12 @@ static inline bool fence_completed(struct msm_fence_context *fctx, uint32_t fenc (int32_t)(*fctx->fenceptr - fence) >= 0; } -/* legacy path for WAIT_FENCE ioctl: */ -int msm_wait_fence(struct msm_fence_context *fctx, uint32_t fence, - ktime_t *timeout, bool interruptible) -{ - int ret; - - if (fence > fctx->last_fence) { - DRM_ERROR_RATELIMITED("%s: waiting on invalid fence: %u (of %u)\n", - fctx->name, fence, fctx->last_fence); - return -EINVAL; Rob, we changed this pre-existing behaviour in this patch. Now, when userspace tries to wait on a future fence, we don't return an error. I just want to check if this was accidental or not? Hmm, perhaps we should do this to restore the previous behavior: - diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 73e827641024..3dd6da56eae6 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -1000,8 +1000,12 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data, fence = dma_fence_get_rcu(fence); mutex_unlock(&queue->lock); - if (!fence) - return 0; + if (!fence) { + struct msm_fence_context *fctx = gpu->rb[queue->ring_nr]->fctx; + DRM_ERROR_RATELIMITED("%s: wait
Re: [Freedreno] [PATCH 2/5] drm/msm: Drop priv->lastctx
struct msm_gpu *gpu; - struct msm_file_private *lastctx; + /* gpu is only set on open(), but we need this info earlier */ bool is_a2xx; bool has_cached_coherent; diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 2c46cd968ac4..3dfc58e6498f 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -763,7 +763,7 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) mutex_unlock(&gpu->active_lock); gpu->funcs->submit(gpu, submit); - priv->lastctx = submit->queue->ctx; + gpu->cur_ctx_seqno = submit->queue->ctx->seqno; hangcheck_timer_reset(gpu); } diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 59870095ea41..623ee416c568 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -144,6 +144,17 @@ struct msm_gpu { struct msm_ringbuffer *rb[MSM_GPU_MAX_RINGS]; int nr_rings; + /** +* cur_ctx_seqno: +* +* The ctx->seqno value of the last context to submit rendering, +* and the one with current pgtables installed (for generations +* that support per-context pgtables). Tracked by seqno rather + * than pointer value to avoid dangling pointers, and cases where +* a ctx can be freed and a new one created with the same address. +*/ + int cur_ctx_seqno; + /* * List of GEM active objects on this gpu. Protected by * msm_drm_private::mm_lock Reviewed-by: Akhil P Oommen -Akhil.
Re: [Freedreno] [PATCH 4/5] drm/msm: Handle fence rollover
On 11/9/2021 11:41 PM, Rob Clark wrote: From: Rob Clark Add some helpers for fence comparision, which handle rollover properly, and stop open coding fence seqno comparisions. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_fence.h | 12 drivers/gpu/drm/msm/msm_gpu.c | 6 +++--- drivers/gpu/drm/msm/msm_gpu.h | 2 +- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_fence.h b/drivers/gpu/drm/msm/msm_fence.h index 4783db528bcc..17ee3822b423 100644 --- a/drivers/gpu/drm/msm/msm_fence.h +++ b/drivers/gpu/drm/msm/msm_fence.h @@ -60,4 +60,16 @@ void msm_update_fence(struct msm_fence_context *fctx, uint32_t fence); struct dma_fence * msm_fence_alloc(struct msm_fence_context *fctx); +static inline bool +fence_before(uint32_t a, uint32_t b) +{ + return (int32_t)(a - b) < 0; This is good enough when a and b have close values. And that is a good assumption for KMD generated seqno. Reviewed-by: Akhil P Oommen -Akhil. +} + +static inline bool +fence_after(uint32_t a, uint32_t b) +{ + return (int32_t)(a - b) > 0; +} + #endif diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 13de1241d595..0f78c2615272 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -172,7 +172,7 @@ static void update_fences(struct msm_gpu *gpu, struct msm_ringbuffer *ring, spin_lock_irqsave(&ring->submit_lock, flags); list_for_each_entry(submit, &ring->submits, node) { - if (submit->seqno > fence) + if (fence_after(submit->seqno, fence)) break; msm_update_fence(submit->ring->fctx, @@ -509,7 +509,7 @@ static void hangcheck_handler(struct timer_list *t) if (fence != ring->hangcheck_fence) { /* some progress has been made.. ya! */ ring->hangcheck_fence = fence; - } else if (fence < ring->seqno) { + } else if (fence_before(fence, ring->seqno)) { /* no progress and not done.. hung! */ ring->hangcheck_fence = fence; DRM_DEV_ERROR(dev->dev, "%s: hangcheck detected gpu lockup rb %d!\n", @@ -523,7 +523,7 @@ static void hangcheck_handler(struct timer_list *t) } /* if still more pending work, reset the hangcheck timer: */ - if (ring->seqno > ring->hangcheck_fence) + if (fence_after(ring->seqno, ring->hangcheck_fence)) hangcheck_timer_reset(gpu); /* workaround for missing irq: */ diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 0dcc31c27ac3..bd4e0024033e 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -258,7 +258,7 @@ static inline bool msm_gpu_active(struct msm_gpu *gpu) for (i = 0; i < gpu->nr_rings; i++) { struct msm_ringbuffer *ring = gpu->rb[i]; - if (ring->seqno > ring->memptrs->fence) + if (fence_after(ring->seqno, ring->memptrs->fence)) return true; }
Re: [Freedreno] [PATCH 5/5] drm/msm: Add debugfs to disable hw err handling
On 11/9/2021 11:41 PM, Rob Clark wrote: From: Rob Clark Add a debugfs interface to ignore hw error irqs, in order to force fallback to sw hangcheck mechanism. Because the hw error detection is pretty good on newer gens, we need this for igt tests to test the sw hang detection. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 6 ++ drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 4 drivers/gpu/drm/msm/msm_debugfs.c | 3 +++ drivers/gpu/drm/msm/msm_drv.h | 9 + 4 files changed, 22 insertions(+) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 6163990a4d09..ec8e043c9d38 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -1252,6 +1252,7 @@ static void a5xx_fault_detect_irq(struct msm_gpu *gpu) static irqreturn_t a5xx_irq(struct msm_gpu *gpu) { + struct msm_drm_private *priv = gpu->dev->dev_private; u32 status = gpu_read(gpu, REG_A5XX_RBBM_INT_0_STATUS); /* @@ -1261,6 +1262,11 @@ static irqreturn_t a5xx_irq(struct msm_gpu *gpu) gpu_write(gpu, REG_A5XX_RBBM_INT_CLEAR_CMD, status & ~A5XX_RBBM_INT_0_MASK_RBBM_AHB_ERROR); + if (priv->disable_err_irq) { + status &= A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS | + A5XX_RBBM_INT_0_MASK_CP_SW; + } + /* Pass status to a5xx_rbbm_err_irq because we've already cleared it */ if (status & RBBM_ERROR_MASK) a5xx_rbbm_err_irq(gpu, status); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 3d2da81cb2c9..8a2af3a27e33 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1373,10 +1373,14 @@ static void a6xx_fault_detect_irq(struct msm_gpu *gpu) static irqreturn_t a6xx_irq(struct msm_gpu *gpu) { + struct msm_drm_private *priv = gpu->dev->dev_private; u32 status = gpu_read(gpu, REG_A6XX_RBBM_INT_0_STATUS); gpu_write(gpu, REG_A6XX_RBBM_INT_CLEAR_CMD, status); + if (priv->disable_err_irq) + status &= A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS; + if (status & A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT) a6xx_fault_detect_irq(gpu); diff --git a/drivers/gpu/drm/msm/msm_debugfs.c b/drivers/gpu/drm/msm/msm_debugfs.c index 6a99e8b5d25d..956b1efc3721 100644 --- a/drivers/gpu/drm/msm/msm_debugfs.c +++ b/drivers/gpu/drm/msm/msm_debugfs.c @@ -242,6 +242,9 @@ void msm_debugfs_init(struct drm_minor *minor) debugfs_create_u32("hangcheck_period_ms", 0600, minor->debugfs_root, &priv->hangcheck_period); + debugfs_create_bool("disable_err_irq", 0600, minor->debugfs_root, + &priv->disable_err_irq); + debugfs_create_file("shrink", S_IRWXU, minor->debugfs_root, dev, &shrink_fops); diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 2943c21d9aac..a8da7a7efb84 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -246,6 +246,15 @@ struct msm_drm_private { /* For hang detection, in ms */ unsigned int hangcheck_period; + + /** +* disable_err_irq: +* +* Disable handling of GPU hw error interrupts, to force fallback to +* sw hangcheck timer. Written (via debugfs) by igt tests to test +* the sw hangcheck mechanism. + */ + bool disable_err_irq; }; struct msm_format { Reviewed-by: Akhil P Oommen -Akhil.
Re: [Freedreno] [PATCH 2/2] drm/msm: Restore error return on invalid fence
On 11/12/2021 12:54 AM, Rob Clark wrote: From: Rob Clark When converting to use an idr to map userspace fence seqno values back to a dma_fence, we lost the error return when userspace passes seqno that is larger than the last submitted fence. Restore this check. Reported-by: Akhil P Oommen Fixes: a61acbbe9cf8 ("drm/msm: Track "seqno" fences by idr") Signed-off-by: Rob Clark --- Note: I will rebase "drm/msm: Handle fence rollover" on top of this, to simplify backporting this patch to stable kernels drivers/gpu/drm/msm/msm_drv.c| 6 ++ drivers/gpu/drm/msm/msm_gem_submit.c | 1 + drivers/gpu/drm/msm/msm_gpu.h| 3 +++ 3 files changed, 10 insertions(+) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index cb14d997c174..56500eb5219e 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -967,6 +967,12 @@ static int wait_fence(struct msm_gpu_submitqueue *queue, uint32_t fence_id, struct dma_fence *fence; int ret; + if (fence_id > queue->last_fence) { But fence_id can wrap around and then this check won't be valid. -Akhil. + DRM_ERROR_RATELIMITED("waiting on invalid fence: %u (of %u)\n", + fence_id, queue->last_fence); + return -EINVAL; + } + /* * Map submitqueue scoped "seqno" (which is actually an idr key) * back to underlying dma-fence diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 151d19e4453c..a38f23be497d 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -911,6 +911,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, drm_sched_entity_push_job(&submit->base, queue->entity); args->fence = submit->fence_id; + queue->last_fence = submit->fence_id; msm_reset_syncobjs(syncobjs_to_reset, args->nr_in_syncobjs); msm_process_post_deps(post_deps, args->nr_out_syncobjs, diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index bd4e0024033e..e73a5bb03544 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -376,6 +376,8 @@ static inline int msm_gpu_convert_priority(struct msm_gpu *gpu, int prio, * @ring_nr: the ringbuffer used by this submitqueue, which is determined * by the submitqueue's priority * @faults:the number of GPU hangs associated with this submitqueue + * @last_fence: the sequence number of the last allocated fence (for error + * checking) * @ctx: the per-drm_file context associated with the submitqueue (ie. * which set of pgtables do submits jobs associated with the * submitqueue use) @@ -391,6 +393,7 @@ struct msm_gpu_submitqueue { u32 flags; u32 ring_nr; int faults; + uint32_t last_fence; struct msm_file_private *ctx; struct list_head node; struct idr fence_idr;
Re: [Freedreno] [PATCH 2/2] drm/msm: Restore error return on invalid fence
On 11/15/2021 10:26 PM, Rob Clark wrote: On Mon, Nov 15, 2021 at 6:43 AM Akhil P Oommen wrote: On 11/12/2021 12:54 AM, Rob Clark wrote: From: Rob Clark When converting to use an idr to map userspace fence seqno values back to a dma_fence, we lost the error return when userspace passes seqno that is larger than the last submitted fence. Restore this check. Reported-by: Akhil P Oommen Fixes: a61acbbe9cf8 ("drm/msm: Track "seqno" fences by idr") Signed-off-by: Rob Clark --- Note: I will rebase "drm/msm: Handle fence rollover" on top of this, to simplify backporting this patch to stable kernels drivers/gpu/drm/msm/msm_drv.c| 6 ++ drivers/gpu/drm/msm/msm_gem_submit.c | 1 + drivers/gpu/drm/msm/msm_gpu.h| 3 +++ 3 files changed, 10 insertions(+) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index cb14d997c174..56500eb5219e 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -967,6 +967,12 @@ static int wait_fence(struct msm_gpu_submitqueue *queue, uint32_t fence_id, struct dma_fence *fence; int ret; + if (fence_id > queue->last_fence) { But fence_id can wrap around and then this check won't be valid. that is correct, but see my note about rebasing "drm/msm: Handle fence rollover" on top of this patch, so this patch could be more easily cherry-picked to stable/lts branches BR, -R Missed that. Thanks. Reviewed-by: Akhil P Oommen -Akhil. -Akhil. + DRM_ERROR_RATELIMITED("waiting on invalid fence: %u (of %u)\n", + fence_id, queue->last_fence); + return -EINVAL; + } + /* * Map submitqueue scoped "seqno" (which is actually an idr key) * back to underlying dma-fence diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 151d19e4453c..a38f23be497d 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -911,6 +911,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, drm_sched_entity_push_job(&submit->base, queue->entity); args->fence = submit->fence_id; + queue->last_fence = submit->fence_id; msm_reset_syncobjs(syncobjs_to_reset, args->nr_in_syncobjs); msm_process_post_deps(post_deps, args->nr_out_syncobjs, diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index bd4e0024033e..e73a5bb03544 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -376,6 +376,8 @@ static inline int msm_gpu_convert_priority(struct msm_gpu *gpu, int prio, * @ring_nr: the ringbuffer used by this submitqueue, which is determined * by the submitqueue's priority * @faults:the number of GPU hangs associated with this submitqueue + * @last_fence: the sequence number of the last allocated fence (for error + * checking) * @ctx: the per-drm_file context associated with the submitqueue (ie. * which set of pgtables do submits jobs associated with the * submitqueue use) @@ -391,6 +393,7 @@ struct msm_gpu_submitqueue { u32 flags; u32 ring_nr; int faults; + uint32_t last_fence; struct msm_file_private *ctx; struct list_head node; struct idr fence_idr;
[Freedreno] [PATCH 1/4] drm/msm: Increase gpu boost interval
Currently, we boost gpu freq after 25ms of inactivity. This regresses some of the 30 fps usecases where the workload on gpu (at 33ms internval) is very small which it can finish at the lowest OPP before the deadline. Lets increase this inactivity threshold to 50ms (same as the current devfreq interval) to fix this. Signed-off-by: Akhil P Oommen --- drivers/gpu/drm/msm/msm_gpu_devfreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c b/drivers/gpu/drm/msm/msm_gpu_devfreq.c index d32b729..c4d8920 100644 --- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c +++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c @@ -178,7 +178,7 @@ void msm_devfreq_active(struct msm_gpu *gpu) * interval, then we won't meet the threshold of busyness for * the governor to ramp up the freq.. so give some boost */ - if (idle_time > msm_devfreq_profile.polling_ms/2) { + if (idle_time > msm_devfreq_profile.polling_ms) { target_freq *= 2; } -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation.
[Freedreno] [PATCH 2/4] drm/msm: Fix null ptr access msm_ioctl_gem_submit()
Fix the below null pointer dereference in msm_ioctl_gem_submit(): 26545.260705: Call trace: 26545.263223:kref_put+0x1c/0x60 26545.266452:msm_ioctl_gem_submit+0x254/0x744 26545.270937:drm_ioctl_kernel+0xa8/0x124 26545.274976:drm_ioctl+0x21c/0x33c 26545.278478:drm_compat_ioctl+0xdc/0xf0 26545.282428:__arm64_compat_sys_ioctl+0xc8/0x100 26545.287169:el0_svc_common+0xf8/0x250 26545.291025:do_el0_svc_compat+0x28/0x54 26545.295066:el0_svc_compat+0x10/0x1c 26545.298838:el0_sync_compat_handler+0xa8/0xcc 26545.303403:el0_sync_compat+0x188/0x1c0 26545.307445: Code: d503201f d503201f 52800028 4b0803e8 (b8680008) 26545.318799: Kernel panic - not syncing: Oops: Fatal exception Signed-off-by: Akhil P Oommen --- drivers/gpu/drm/msm/msm_gem_submit.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 151d19e..bf95b81 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -780,6 +780,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, args->nr_cmds); if (IS_ERR(submit)) { ret = PTR_ERR(submit); + submit = NULL; goto out_unlock; } -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation.
[Freedreno] [PATCH 3/4] drm/msm/a6xx: Fix uinitialized use of gpu_scid
Avoid a possible uninitialized use of gpu_scid variable to fix the below smatch warning: drivers/gpu/drm/msm/adreno/a6xx_gpu.c:1480 a6xx_llc_activate() error: uninitialized symbol 'gpu_scid'. Reported-by: Dan Carpenter Signed-off-by: Akhil P Oommen --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 18 +- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 33da25b..68ee58f 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1424,17 +1424,24 @@ static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu) { struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; struct msm_gpu *gpu = &adreno_gpu->base; - u32 gpu_scid, cntl1_regval = 0; + u32 cntl1_regval = 0; if (IS_ERR(a6xx_gpu->llc_mmio)) return; if (!llcc_slice_activate(a6xx_gpu->llc_slice)) { - gpu_scid = llcc_get_slice_id(a6xx_gpu->llc_slice); + u32 gpu_scid = llcc_get_slice_id(a6xx_gpu->llc_slice); gpu_scid &= 0x1f; cntl1_regval = (gpu_scid << 0) | (gpu_scid << 5) | (gpu_scid << 10) | (gpu_scid << 15) | (gpu_scid << 20); + + /* On A660, the SCID programming for UCHE traffic is done in +* A6XX_GBIF_SCACHE_CNTL0[14:10] +*/ + if (adreno_is_a660_family(adreno_gpu)) + gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL0, (0x1f << 10) | + (1 << 8), (gpu_scid << 10) | (1 << 8)); } /* @@ -1471,13 +1478,6 @@ static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu) } gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL1, GENMASK(24, 0), cntl1_regval); - - /* On A660, the SCID programming for UCHE traffic is done in -* A6XX_GBIF_SCACHE_CNTL0[14:10] -*/ - if (adreno_is_a660_family(adreno_gpu)) - gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL0, (0x1f << 10) | - (1 << 8), (gpu_scid << 10) | (1 << 8)); } static void a6xx_llc_slices_destroy(struct a6xx_gpu *a6xx_gpu) -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation.