Skip to content

Commit

Permalink
drm/msm: Add speed-bin support to a618 gpu
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Jordan Crouse <[email protected]>
Signed-off-by: Rob Clark <[email protected]>
  • Loading branch information
Akhil P Oommen authored and robclark committed Jan 31, 2021
1 parent 6ee1d74 commit fe7952c
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 0 deletions.
83 changes: 83 additions & 0 deletions drivers/gpu/drm/msm/adreno/a6xx_gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <linux/bitfield.h>
#include <linux/devfreq.h>
#include <linux/nvmem-consumer.h>
#include <linux/soc/qcom/llcc-qcom.h>

#define GPU_PAS_ID 13
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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));
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/msm/adreno/a6xx_gpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit fe7952c

Please sign in to comment.