Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/panfrost: Add basic support for speed binning

Some SoCs implementing ARM Mali GPUs are subject to speed binning:
this means that some versions of the same SoC model may need to be
limited to a slower frequency compared to the other:
this is being addressed by reading nvmem (usually, an eFuse array)
containing a number that identifies the speed binning of the chip,
which is usually related to silicon quality.

To address such situation, add basic support for reading the
speed-bin through nvmem, as to make it possible to specify the
supported hardware in the OPP table for GPUs.
This commit also keeps compatibility with any platform that does
not specify (and does not even support) speed-binning.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230323090822.61766-3-angelogioacchino.delregno@collabora.com

authored by

AngeloGioacchino Del Regno and committed by
Boris Brezillon
7d690f93 191308ba

+30
+30
drivers/gpu/drm/panfrost/panfrost_devfreq.c
··· 4 4 #include <linux/clk.h> 5 5 #include <linux/devfreq.h> 6 6 #include <linux/devfreq_cooling.h> 7 + #include <linux/nvmem-consumer.h> 7 8 #include <linux/platform_device.h> 8 9 #include <linux/pm_opp.h> 9 10 ··· 83 82 .get_dev_status = panfrost_devfreq_get_dev_status, 84 83 }; 85 84 85 + static int panfrost_read_speedbin(struct device *dev) 86 + { 87 + u32 val; 88 + int ret; 89 + 90 + ret = nvmem_cell_read_variable_le_u32(dev, "speed-bin", &val); 91 + if (ret) { 92 + /* 93 + * -ENOENT means that this platform doesn't support speedbins 94 + * as it didn't declare any speed-bin nvmem: in this case, we 95 + * keep going without it; any other error means that we are 96 + * supposed to read the bin value, but we failed doing so. 97 + */ 98 + if (ret != -ENOENT) { 99 + DRM_DEV_ERROR(dev, "Cannot read speed-bin (%d).", ret); 100 + return ret; 101 + } 102 + 103 + return 0; 104 + } 105 + DRM_DEV_DEBUG(dev, "Using speed-bin = 0x%x\n", val); 106 + 107 + return devm_pm_opp_set_supported_hw(dev, &val, 1); 108 + } 109 + 86 110 int panfrost_devfreq_init(struct panfrost_device *pfdev) 87 111 { 88 112 int ret; ··· 126 100 DRM_DEV_INFO(dev, "More than 1 supply is not supported yet\n"); 127 101 return 0; 128 102 } 103 + 104 + ret = panfrost_read_speedbin(dev); 105 + if (ret) 106 + return ret; 129 107 130 108 ret = devm_pm_opp_set_regulators(dev, pfdev->comp->supply_names); 131 109 if (ret) {