Commit c40b50c3 authored by Nicolas Frattaroli's avatar Nicolas Frattaroli Committed by Boris Brezillon
Browse files

drm/panthor: Implement reading shader_present from nvmem



On some platforms, notably MediaTek MT8196, the shader_present bitmask
in the Mali GPU register for it has cores enabled that may be faulty.
The true shader_present bitmask is found in an efuse instead.

Implement reading shader_present from an nvmem cell if one is present,
falling back to the Mali register if it's absent. The error codes are
trickled up through to the probe function so that probe deferral works.

Signed-off-by: default avatarNicolas Frattaroli <nicolas.frattaroli@collabora.com>
Reviewed-by: default avatarLiviu Dudau <liviu.dudau@arm.com>
Reviewed-by: default avatarSteven Price <steven.price@arm.com>
Link: https://patch.msgid.link/20251220-mt8196-shader-present-v2-3-45b1ff1dfab0@collabora.com


Signed-off-by: default avatarBoris Brezillon <boris.brezillon@collabora.com>
parent 2568b8b0
Loading
Loading
Loading
Loading
+30 −6
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0 or MIT
/* Copyright 2025 ARM Limited. All rights reserved. */

#include <linux/nvmem-consumer.h>
#include <drm/drm_print.h>

#include "panthor_device.h"
@@ -109,7 +110,25 @@ static char *get_gpu_model_name(struct panthor_device *ptdev)
	return "(Unknown Mali GPU)";
}

static void panthor_gpu_info_init(struct panthor_device *ptdev)
static int overload_shader_present(struct panthor_device *ptdev)
{
	u64 contents;
	int ret;

	ret = nvmem_cell_read_variable_le_u64(ptdev->base.dev, "shader-present",
					      &contents);
	if (!ret)
		ptdev->gpu_info.shader_present = contents;
	else if (ret == -ENOENT)
		return 0;
	else
		return dev_err_probe(ptdev->base.dev, ret,
				     "Failed to read shader-present nvmem cell\n");

	return 0;
}

static int panthor_gpu_info_init(struct panthor_device *ptdev)
{
	unsigned int i;

@@ -143,13 +162,18 @@ static void panthor_gpu_info_init(struct panthor_device *ptdev)
		ptdev->gpu_info.tiler_present = gpu_read64(ptdev, GPU_TILER_PRESENT);
		ptdev->gpu_info.l2_present = gpu_read64(ptdev, GPU_L2_PRESENT);
	}

	return overload_shader_present(ptdev);
}

static void panthor_hw_info_init(struct panthor_device *ptdev)
static int panthor_hw_info_init(struct panthor_device *ptdev)
{
	u32 major, minor, status;
	int ret;

	panthor_gpu_info_init(ptdev);
	ret = panthor_gpu_info_init(ptdev);
	if (ret)
		return ret;

	major = GPU_VER_MAJOR(ptdev->gpu_info.gpu_id);
	minor = GPU_VER_MINOR(ptdev->gpu_info.gpu_id);
@@ -172,6 +196,8 @@ static void panthor_hw_info_init(struct panthor_device *ptdev)
		 "shader_present=0x%0llx l2_present=0x%0llx tiler_present=0x%0llx",
		 ptdev->gpu_info.shader_present, ptdev->gpu_info.l2_present,
		 ptdev->gpu_info.tiler_present);

	return 0;
}

static int panthor_hw_bind_device(struct panthor_device *ptdev)
@@ -218,7 +244,5 @@ int panthor_hw_init(struct panthor_device *ptdev)
	if (ret)
		return ret;

	panthor_hw_info_init(ptdev);

	return 0;
	return panthor_hw_info_init(ptdev);
}