Check for errors instead of silently not using icc if the msm driver probes before the interconnect driver.
Allow ENODATA for ocmem path, as it is optional and this error is returned when "gfx-mem" path is provided but not "ocmem".
Because msm_gpu_cleanup assumes msm_gpu_init has been called, the icc path init needs to be after msm_gpu_init for the error path to work.
v2: changed to not only check for EPROBE_DEFER v3: move icc path init after msm_gpu_init to avoid deleting a WARN_ON v4: added two patches to fix issues with probe deferring later in v3
Jonathan Marek (3): drm/msm: fix unbalanced pm_runtime_enable in adreno_gpu_{init,cleanup} drm/msm: reset devfreq freq_table/max_state before devfreq_add_device drm/msm: handle for EPROBE_DEFER for of_icc_get
drivers/gpu/drm/msm/adreno/adreno_gpu.c | 68 +++++++++++++++---------- drivers/gpu/drm/msm/msm_gpu.c | 4 ++ 2 files changed, 45 insertions(+), 27 deletions(-)
adreno_gpu_init calls pm_runtime_enable, so adreno_gpu_cleanup needs to call pm_runtime_disable.
Signed-off-by: Jonathan Marek jonathan@marek.ca --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 89673c7ed473..ad64d4b7e8d7 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -1021,11 +1021,14 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu) { struct msm_gpu *gpu = &adreno_gpu->base; + struct msm_drm_private *priv = gpu->dev->dev_private; unsigned int i;
for (i = 0; i < ARRAY_SIZE(adreno_gpu->info->fw); i++) release_firmware(adreno_gpu->fw[i]);
+ pm_runtime_disable(&priv->gpu_pdev->dev); + icc_put(gpu->icc_path); icc_put(gpu->ocmem_icc_path);
On Mon, Jul 13, 2020 at 06:53:40PM -0400, Jonathan Marek wrote:
adreno_gpu_init calls pm_runtime_enable, so adreno_gpu_cleanup needs to call pm_runtime_disable.
Reviewed-by: Jordan Crouse jcrouse@codeaurora.org
Signed-off-by: Jonathan Marek jonathan@marek.ca
drivers/gpu/drm/msm/adreno/adreno_gpu.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 89673c7ed473..ad64d4b7e8d7 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -1021,11 +1021,14 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu) { struct msm_gpu *gpu = &adreno_gpu->base;
struct msm_drm_private *priv = gpu->dev->dev_private; unsigned int i;
for (i = 0; i < ARRAY_SIZE(adreno_gpu->info->fw); i++) release_firmware(adreno_gpu->fw[i]);
pm_runtime_disable(&priv->gpu_pdev->dev);
icc_put(gpu->icc_path); icc_put(gpu->ocmem_icc_path);
-- 2.26.1
These never get set back to 0 when probing fails, so an attempt to probe again results in broken behavior. Fix the problem by setting thse to zero before they are used.
Signed-off-by: Jonathan Marek jonathan@marek.ca --- drivers/gpu/drm/msm/msm_gpu.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index a22d30622306..aa9775ab52f0 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -93,7 +93,11 @@ static void msm_devfreq_init(struct msm_gpu *gpu) /* * Don't set the freq_table or max_state and let devfreq build the table * from OPP + * After a deferred probe, these may have be left to non-zero values, + * so set them back to zero before creating the devfreq device */ + msm_devfreq_profile.freq_table = NULL; + msm_devfreq_profile.max_state = 0;
gpu->devfreq.devfreq = devm_devfreq_add_device(&gpu->pdev->dev, &msm_devfreq_profile, DEVFREQ_GOV_SIMPLE_ONDEMAND,
On Mon, Jul 13, 2020 at 06:53:41PM -0400, Jonathan Marek wrote:
These never get set back to 0 when probing fails, so an attempt to probe again results in broken behavior. Fix the problem by setting thse to zero before they are used.
Reviewed-by: Jordan Crouse jcrouse@codeaurora.org
Signed-off-by: Jonathan Marek jonathan@marek.ca
drivers/gpu/drm/msm/msm_gpu.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index a22d30622306..aa9775ab52f0 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -93,7 +93,11 @@ static void msm_devfreq_init(struct msm_gpu *gpu) /* * Don't set the freq_table or max_state and let devfreq build the table * from OPP
* After a deferred probe, these may have be left to non-zero values,
* so set them back to zero before creating the devfreq device
*/
msm_devfreq_profile.freq_table = NULL;
msm_devfreq_profile.max_state = 0;
gpu->devfreq.devfreq = devm_devfreq_add_device(&gpu->pdev->dev, &msm_devfreq_profile, DEVFREQ_GOV_SIMPLE_ONDEMAND,
-- 2.26.1
Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Check for errors instead of silently not using icc if the msm driver probes before the interconnect driver.
Allow ENODATA for ocmem path, as it is optional and this error is returned when "gfx-mem" path is provided but not "ocmem".
Because msm_gpu_cleanup assumes msm_gpu_init has been called, the icc path init needs to be after msm_gpu_init for the error path to work.
Signed-off-by: Jonathan Marek jonathan@marek.ca --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 65 +++++++++++++++---------- 1 file changed, 38 insertions(+), 27 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index ad64d4b7e8d7..3f1ecc1de965 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -895,7 +895,7 @@ static int adreno_get_legacy_pwrlevels(struct device *dev) return 0; }
-static int adreno_get_pwrlevels(struct device *dev, +static void adreno_get_pwrlevels(struct device *dev, struct msm_gpu *gpu) { unsigned long freq = ULONG_MAX; @@ -930,24 +930,6 @@ static int adreno_get_pwrlevels(struct device *dev, }
DBG("fast_rate=%u, slow_rate=27000000", gpu->fast_rate); - - /* Check for an interconnect path for the bus */ - gpu->icc_path = of_icc_get(dev, "gfx-mem"); - if (!gpu->icc_path) { - /* - * Keep compatbility with device trees that don't have an - * interconnect-names property. - */ - gpu->icc_path = of_icc_get(dev, NULL); - } - if (IS_ERR(gpu->icc_path)) - gpu->icc_path = NULL; - - gpu->ocmem_icc_path = of_icc_get(dev, "ocmem"); - if (IS_ERR(gpu->ocmem_icc_path)) - gpu->ocmem_icc_path = NULL; - - return 0; }
int adreno_gpu_ocmem_init(struct device *dev, struct adreno_gpu *adreno_gpu, @@ -993,9 +975,11 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, struct adreno_gpu *adreno_gpu, const struct adreno_gpu_funcs *funcs, int nr_rings) { - struct adreno_platform_config *config = pdev->dev.platform_data; + struct device *dev = &pdev->dev; + 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); @@ -1007,15 +991,42 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
adreno_gpu_config.nr_rings = nr_rings;
- adreno_get_pwrlevels(&pdev->dev, gpu); + adreno_get_pwrlevels(dev, gpu);
- pm_runtime_set_autosuspend_delay(&pdev->dev, + pm_runtime_set_autosuspend_delay(dev, adreno_gpu->info->inactive_period); - pm_runtime_use_autosuspend(&pdev->dev); - pm_runtime_enable(&pdev->dev); + pm_runtime_use_autosuspend(dev); + pm_runtime_enable(dev);
- return msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base, + ret = msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base, adreno_gpu->info->name, &adreno_gpu_config); + if (ret) + return ret; + + /* Check for an interconnect path for the bus */ + gpu->icc_path = of_icc_get(dev, "gfx-mem"); + if (!gpu->icc_path) { + /* + * Keep compatbility with device trees that don't have an + * interconnect-names property. + */ + gpu->icc_path = of_icc_get(dev, NULL); + } + if (IS_ERR(gpu->icc_path)) { + ret = PTR_ERR(gpu->icc_path); + gpu->icc_path = NULL; + return ret; + } + + gpu->ocmem_icc_path = of_icc_get(dev, "ocmem"); + if (IS_ERR(gpu->ocmem_icc_path)) { + ret = PTR_ERR(gpu->ocmem_icc_path); + gpu->ocmem_icc_path = NULL; + /* allow -ENODATA, ocmem icc is optional */ + if (ret != -ENODATA) + return ret; + } + return 0; }
void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu) @@ -1029,8 +1040,8 @@ 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); - - msm_gpu_cleanup(&adreno_gpu->base); }
On Mon, Jul 13, 2020 at 06:53:42PM -0400, Jonathan Marek wrote:
Check for errors instead of silently not using icc if the msm driver probes before the interconnect driver.
Allow ENODATA for ocmem path, as it is optional and this error is returned when "gfx-mem" path is provided but not "ocmem".
Because msm_gpu_cleanup assumes msm_gpu_init has been called, the icc path init needs to be after msm_gpu_init for the error path to work.
A possible future improvement would be to move the ocmem check to the target specific code for 3xx and 4xx where you could be a bit more demanding that the ocmem path actually exist.
Reviewed-by: Jordan Crouse jcrouse@codeaurora.org
Signed-off-by: Jonathan Marek jonathan@marek.ca
drivers/gpu/drm/msm/adreno/adreno_gpu.c | 65 +++++++++++++++---------- 1 file changed, 38 insertions(+), 27 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index ad64d4b7e8d7..3f1ecc1de965 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -895,7 +895,7 @@ static int adreno_get_legacy_pwrlevels(struct device *dev) return 0; }
-static int adreno_get_pwrlevels(struct device *dev, +static void adreno_get_pwrlevels(struct device *dev, struct msm_gpu *gpu) { unsigned long freq = ULONG_MAX; @@ -930,24 +930,6 @@ static int adreno_get_pwrlevels(struct device *dev, }
DBG("fast_rate=%u, slow_rate=27000000", gpu->fast_rate);
- /* Check for an interconnect path for the bus */
- gpu->icc_path = of_icc_get(dev, "gfx-mem");
- if (!gpu->icc_path) {
/*
* Keep compatbility with device trees that don't have an
* interconnect-names property.
*/
gpu->icc_path = of_icc_get(dev, NULL);
- }
- if (IS_ERR(gpu->icc_path))
gpu->icc_path = NULL;
- gpu->ocmem_icc_path = of_icc_get(dev, "ocmem");
- if (IS_ERR(gpu->ocmem_icc_path))
gpu->ocmem_icc_path = NULL;
- return 0;
}
int adreno_gpu_ocmem_init(struct device *dev, struct adreno_gpu *adreno_gpu, @@ -993,9 +975,11 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, struct adreno_gpu *adreno_gpu, const struct adreno_gpu_funcs *funcs, int nr_rings) {
- struct adreno_platform_config *config = pdev->dev.platform_data;
struct device *dev = &pdev->dev;
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);
@@ -1007,15 +991,42 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
adreno_gpu_config.nr_rings = nr_rings;
- adreno_get_pwrlevels(&pdev->dev, gpu);
- adreno_get_pwrlevels(dev, gpu);
- pm_runtime_set_autosuspend_delay(&pdev->dev,
- pm_runtime_set_autosuspend_delay(dev, adreno_gpu->info->inactive_period);
- pm_runtime_use_autosuspend(&pdev->dev);
- pm_runtime_enable(&pdev->dev);
- pm_runtime_use_autosuspend(dev);
- pm_runtime_enable(dev);
- return msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base,
- ret = msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base, adreno_gpu->info->name, &adreno_gpu_config);
- if (ret)
return ret;
- /* Check for an interconnect path for the bus */
- gpu->icc_path = of_icc_get(dev, "gfx-mem");
- if (!gpu->icc_path) {
/*
* Keep compatbility with device trees that don't have an
* interconnect-names property.
*/
gpu->icc_path = of_icc_get(dev, NULL);
- }
- if (IS_ERR(gpu->icc_path)) {
ret = PTR_ERR(gpu->icc_path);
gpu->icc_path = NULL;
return ret;
- }
- gpu->ocmem_icc_path = of_icc_get(dev, "ocmem");
- if (IS_ERR(gpu->ocmem_icc_path)) {
ret = PTR_ERR(gpu->ocmem_icc_path);
gpu->ocmem_icc_path = NULL;
/* allow -ENODATA, ocmem icc is optional */
if (ret != -ENODATA)
return ret;
- }
- return 0;
}
void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu) @@ -1029,8 +1040,8 @@ 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);
- msm_gpu_cleanup(&adreno_gpu->base);
}
2.26.1
dri-devel@lists.freedesktop.org