On Fri, Aug 21, 2026 at 1:44 PM Paul Hollinsky <[email protected]> wrote: > > Commit 0be72be03ca7 ("drm/msm: Switch to generic PAS TZ APIs") replaced > the qcom_scm_is_available() check in adreno_zap_shader_load() with > qcom_pas_is_available(). These are not equivalent: the former reports > whether the SCM transport is up, the latter whether the TrustZone > firmware implements the peripheral authentication service. > > On SC7180 Chromebooks (trogdor) TZ does not implement PAS at all. SCM > call-availability queries return 0 for every PAS command while other > services answer normally: > > svc 0x06 cmd 0x01 IS_CALL_AVAIL -> 1 > svc 0x02 cmd 0x01 PAS_INIT_IMAGE -> 0 > svc 0x02 cmd 0x05 PAS_AUTH_RESET -> 0 > svc 0x02 cmd 0x07 PAS_IS_SUPPORTED -> 0 > svc 0x0c cmd 0x16 MP_ASSIGN -> 1 > svc 0x05 cmd 0x01 IO_READ -> 1 > > so qcom_scm_probe() never registers a PAS backend and > qcom_pas_is_available() is false for the lifetime of the boot. > > That on its own need not matter, because sc7180-trogdor.dtsi does > /delete-node/ &gpu_zap_shader;, and the intended path for such a board > is for zap_shader_load_mdt() to find no zap-shader child, clear > zap_available, return -ENODEV, and let the caller fall back to > SECVID_TRUST_CNTL. > > The problem is the ordering. zap_available is a static initialised to > true and is only ever cleared inside zap_shader_load_mdt(), but > adreno_zap_shader_load() consults PAS before calling it. The discovery > that decides whether a zap shader is needed at all can therefore never > run, the flag is never cleared, and every call returns -EPROBE_DEFER: > > adreno 5000000.gpu: [drm:adreno_zap_shader_load] *ERROR* PAS is not > available > msm_dpu ae01000.display-controller: [drm:adreno_load_gpu] *ERROR* gpu hw > init failed: -517 > > Nothing retries that deferral, either. adreno_zap_shader_load() is > called from a6xx_hw_init() rather than from probe, so the -EPROBE_DEFER > is not a probe return value: it propagates up until adreno_load_gpu() > returns NULL. load_gpu() re-attempts on every DRM open while priv->gpu > is NULL, each open fails identically, and PAS cannot become available in > between - which is why the error repeats and userspace stays on > llvmpipe. > > Move the availability check into zap_shader_load_mdt(), behind the > zap-shader node lookup, so the driver only consults PAS once it knows it > needs PAS. Boards with no zap-shader node take the intended -ENODEV > fallback without ever asking, and boards that do have one keep the > qcom_pas_is_available() gate. > > Fixes: 0be72be03ca7 ("drm/msm: Switch to generic PAS TZ APIs") > Link: > https://lore.kernel.org/r/[email protected] > Signed-off-by: Paul Hollinsky <[email protected]> > --- > Reported and analysed in: > https://lore.kernel.org/linux-arm-msm/[email protected]/ > Konrad agreed with this shape in > https://lore.kernel.org/linux-arm-msm/[email protected]/ > > 0be72be03ca7 landed in mainline during the v7.3 merge window (via the > soc-drivers-7.3 pull), so this is based on Linus' tree. Note that > msm-fixes and msm-next both still predate it as I write this, so it > needs a base that includes the merge window; happy to respin against > whatever base you prefer, and it can equally go via the qcom tree the > culprit came through. > > Tested on a Lenovo IdeaPad Duet 3 (sc7180-trogdor-wormdingler) on > next-20260805, which carries the same code: with this applied the GPU > initialises and logs "Zap shader not enabled - using SECVID_TRUST_CNTL > instead", and userspace gets a6xx rather than llvmpipe. > > drivers/gpu/drm/msm/adreno/adreno_gpu.c | 13 ++++++------- > 1 file changed, 6 insertions(+), 7 deletions(-) >
Reviewed-by: Sumit Garg <[email protected]> -Sumit > diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c > b/drivers/gpu/drm/msm/adreno/adreno_gpu.c > index 489462065ea9..995161215ad5 100644 > --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c > +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c > @@ -52,6 +52,12 @@ static int zap_shader_load_mdt(struct msm_gpu *gpu, const > char *fwname, > return -ENODEV; > } > > + /* We need PAS to be able to load the firmware */ > + if (!qcom_pas_is_available()) { > + DRM_DEV_ERROR(dev, "PAS is not available\n"); > + return -EPROBE_DEFER; > + } > + > ret = of_reserved_mem_region_to_resource(np, 0, &r); > if (ret) { > zap_available = false; > @@ -170,18 +176,11 @@ static int zap_shader_load_mdt(struct msm_gpu *gpu, > const char *fwname, > int adreno_zap_shader_load(struct msm_gpu *gpu, u32 pasid) > { > struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); > - struct platform_device *pdev = gpu->pdev; > > /* Short cut if we determine the zap shader isn't available/needed */ > if (!zap_available) > return -ENODEV; > > - /* We need PAS to be able to load the firmware */ > - if (!qcom_pas_is_available()) { > - DRM_DEV_ERROR(&pdev->dev, "PAS is not available\n"); > - return -EPROBE_DEFER; > - } > - > return zap_shader_load_mdt(gpu, adreno_gpu->info->zapfw, pasid); > } > > > base-commit: 818bebeb63dd6bf5f4e07e145f6cdbace520a34c > -- > 2.55.0 >
