drm/msm/adreno: Move speedbin mapping to device table
This simplifies the code. v2: Use a table of structs instead of flat uint32_t[] Signed-off-by: Rob Clark <robdclark@chromium.org> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Patchwork: https://patchwork.freedesktop.org/patch/549769/
This commit is contained in:
parent
f30a648d87
commit
c928a05e44
3 changed files with 98 additions and 156 deletions
|
@ -2204,159 +2204,19 @@ static bool a6xx_progress(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
|
|||
return progress;
|
||||
}
|
||||
|
||||
static u32 a610_get_speed_bin(u32 fuse)
|
||||
static u32 fuse_to_supp_hw(const struct adreno_info *info, u32 fuse)
|
||||
{
|
||||
/*
|
||||
* There are (at least) three SoCs implementing A610: SM6125 (trinket),
|
||||
* SM6115 (bengal) and SM6225 (khaje). Trinket does not have speedbinning,
|
||||
* as only a single SKU exists and we don't support khaje upstream yet.
|
||||
* Hence, this matching table is only valid for bengal and can be easily
|
||||
* expanded if need be.
|
||||
*/
|
||||
|
||||
if (fuse == 0)
|
||||
return 0;
|
||||
else if (fuse == 206)
|
||||
return 1;
|
||||
else if (fuse == 200)
|
||||
return 2;
|
||||
else if (fuse == 157)
|
||||
return 3;
|
||||
else if (fuse == 127)
|
||||
return 4;
|
||||
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
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 a619_holi_get_speed_bin(u32 fuse)
|
||||
{
|
||||
/*
|
||||
* There are (at least) two SoCs implementing A619_holi: SM4350 (holi)
|
||||
* and SM6375 (blair). Limit the fuse matching to the corresponding
|
||||
* SoC to prevent bogus frequency setting (as improbable as it may be,
|
||||
* given unexpected fuse values are.. unexpected! But still possible.)
|
||||
*/
|
||||
|
||||
if (fuse == 0)
|
||||
return 0;
|
||||
|
||||
if (of_machine_is_compatible("qcom,sm4350")) {
|
||||
if (fuse == 138)
|
||||
return 1;
|
||||
else if (fuse == 92)
|
||||
return 2;
|
||||
} else if (of_machine_is_compatible("qcom,sm6375")) {
|
||||
if (fuse == 190)
|
||||
return 1;
|
||||
else if (fuse == 177)
|
||||
return 2;
|
||||
} else
|
||||
pr_warn("Unknown SoC implementing A619_holi!\n");
|
||||
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
static u32 a619_get_speed_bin(u32 fuse)
|
||||
{
|
||||
if (fuse == 0)
|
||||
return 0;
|
||||
else if (fuse == 120)
|
||||
return 4;
|
||||
else if (fuse == 138)
|
||||
return 3;
|
||||
else if (fuse == 169)
|
||||
return 2;
|
||||
else if (fuse == 180)
|
||||
return 1;
|
||||
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
static u32 a640_get_speed_bin(u32 fuse)
|
||||
{
|
||||
if (fuse == 0)
|
||||
return 0;
|
||||
else if (fuse == 1)
|
||||
return 1;
|
||||
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
static u32 a650_get_speed_bin(u32 fuse)
|
||||
{
|
||||
if (fuse == 0)
|
||||
return 0;
|
||||
else if (fuse == 1)
|
||||
return 1;
|
||||
/* Yep, 2 and 3 are swapped! :/ */
|
||||
else if (fuse == 2)
|
||||
return 3;
|
||||
else if (fuse == 3)
|
||||
return 2;
|
||||
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
static u32 adreno_7c3_get_speed_bin(u32 fuse)
|
||||
{
|
||||
if (fuse == 0)
|
||||
return 0;
|
||||
else if (fuse == 117)
|
||||
return 0;
|
||||
else if (fuse == 190)
|
||||
return 1;
|
||||
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
static u32 fuse_to_supp_hw(struct device *dev, struct adreno_gpu *adreno_gpu, u32 fuse)
|
||||
{
|
||||
u32 val = UINT_MAX;
|
||||
|
||||
if (adreno_is_a610(adreno_gpu))
|
||||
val = a610_get_speed_bin(fuse);
|
||||
|
||||
if (adreno_is_a618(adreno_gpu))
|
||||
val = a618_get_speed_bin(fuse);
|
||||
|
||||
else if (adreno_is_a619_holi(adreno_gpu))
|
||||
val = a619_holi_get_speed_bin(fuse);
|
||||
|
||||
else if (adreno_is_a619(adreno_gpu))
|
||||
val = a619_get_speed_bin(fuse);
|
||||
|
||||
else if (adreno_is_7c3(adreno_gpu))
|
||||
val = adreno_7c3_get_speed_bin(fuse);
|
||||
|
||||
else if (adreno_is_a640(adreno_gpu))
|
||||
val = a640_get_speed_bin(fuse);
|
||||
|
||||
else if (adreno_is_a650(adreno_gpu))
|
||||
val = a650_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\n",
|
||||
fuse);
|
||||
if (!info->speedbins)
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
return (1 << val);
|
||||
for (int i = 0; info->speedbins[i].fuse != SHRT_MAX; i++)
|
||||
if (info->speedbins[i].fuse == fuse)
|
||||
return BIT(info->speedbins[i].speedbin);
|
||||
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
static int a6xx_set_supported_hw(struct device *dev, struct adreno_gpu *adreno_gpu)
|
||||
static int a6xx_set_supported_hw(struct device *dev, const struct adreno_info *info)
|
||||
{
|
||||
u32 supp_hw;
|
||||
u32 speedbin;
|
||||
|
@ -2375,7 +2235,14 @@ static int a6xx_set_supported_hw(struct device *dev, struct adreno_gpu *adreno_g
|
|||
return ret;
|
||||
}
|
||||
|
||||
supp_hw = fuse_to_supp_hw(dev, adreno_gpu, speedbin);
|
||||
supp_hw = fuse_to_supp_hw(info, speedbin);
|
||||
|
||||
if (supp_hw == UINT_MAX) {
|
||||
DRM_DEV_ERROR(dev,
|
||||
"missing support for speed-bin: %u. Some OPPs may not be supported by hardware\n",
|
||||
speedbin);
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
ret = devm_pm_opp_set_supported_hw(dev, &supp_hw, 1);
|
||||
if (ret)
|
||||
|
@ -2483,17 +2350,11 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
|
|||
if (!info)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
/* Assign these early so that we can use the is_aXYZ helpers */
|
||||
/* New-style ADRENO_REV()-only */
|
||||
adreno_gpu->rev = info->rev;
|
||||
/* Quirk data */
|
||||
adreno_gpu->info = info;
|
||||
|
||||
adreno_gpu->base.hw_apriv = !!(info->quirks & ADRENO_QUIRK_HAS_HW_APRIV);
|
||||
|
||||
a6xx_llc_slices_init(pdev, a6xx_gpu);
|
||||
|
||||
ret = a6xx_set_supported_hw(&pdev->dev, adreno_gpu);
|
||||
ret = a6xx_set_supported_hw(&pdev->dev, info);
|
||||
if (ret) {
|
||||
a6xx_destroy(&(a6xx_gpu->base.base));
|
||||
return ERR_PTR(ret);
|
||||
|
|
|
@ -247,6 +247,20 @@ static const struct adreno_info gpulist[] = {
|
|||
.init = a6xx_gpu_init,
|
||||
.zapfw = "a610_zap.mdt",
|
||||
.hwcg = a612_hwcg,
|
||||
/*
|
||||
* There are (at least) three SoCs implementing A610: SM6125
|
||||
* (trinket), SM6115 (bengal) and SM6225 (khaje). Trinket does
|
||||
* not have speedbinning, as only a single SKU exists and we
|
||||
* don't support khaje upstream yet. Hence, this matching
|
||||
* table is only valid for bengal.
|
||||
*/
|
||||
.speedbins = ADRENO_SPEEDBINS(
|
||||
{ 0, 0 },
|
||||
{ 206, 1 },
|
||||
{ 200, 2 },
|
||||
{ 157, 3 },
|
||||
{ 127, 4 },
|
||||
),
|
||||
}, {
|
||||
.rev = ADRENO_REV(6, 1, 8, ANY_ID),
|
||||
.revn = 618,
|
||||
|
@ -258,6 +272,11 @@ static const struct adreno_info gpulist[] = {
|
|||
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
|
||||
.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
|
||||
.init = a6xx_gpu_init,
|
||||
.speedbins = ADRENO_SPEEDBINS(
|
||||
{ 0, 0 },
|
||||
{ 169, 1 },
|
||||
{ 174, 2 },
|
||||
),
|
||||
}, {
|
||||
.machine = "qcom,sm4350",
|
||||
.rev = ADRENO_REV(6, 1, 9, ANY_ID),
|
||||
|
@ -271,6 +290,11 @@ static const struct adreno_info gpulist[] = {
|
|||
.init = a6xx_gpu_init,
|
||||
.zapfw = "a615_zap.mdt",
|
||||
.hwcg = a615_hwcg,
|
||||
.speedbins = ADRENO_SPEEDBINS(
|
||||
{ 0, 0 },
|
||||
{ 138, 1 },
|
||||
{ 92, 2 },
|
||||
),
|
||||
}, {
|
||||
.machine = "qcom,sm6375",
|
||||
.rev = ADRENO_REV(6, 1, 9, ANY_ID),
|
||||
|
@ -284,6 +308,11 @@ static const struct adreno_info gpulist[] = {
|
|||
.init = a6xx_gpu_init,
|
||||
.zapfw = "a615_zap.mdt",
|
||||
.hwcg = a615_hwcg,
|
||||
.speedbins = ADRENO_SPEEDBINS(
|
||||
{ 0, 0 },
|
||||
{ 190, 1 },
|
||||
{ 177, 2 },
|
||||
),
|
||||
}, {
|
||||
.rev = ADRENO_REV(6, 1, 9, ANY_ID),
|
||||
.revn = 619,
|
||||
|
@ -297,6 +326,13 @@ static const struct adreno_info gpulist[] = {
|
|||
.init = a6xx_gpu_init,
|
||||
.zapfw = "a615_zap.mdt",
|
||||
.hwcg = a615_hwcg,
|
||||
.speedbins = ADRENO_SPEEDBINS(
|
||||
{ 0, 0 },
|
||||
{ 120, 4 },
|
||||
{ 138, 3 },
|
||||
{ 169, 2 },
|
||||
{ 180, 1 },
|
||||
),
|
||||
}, {
|
||||
.rev = ADRENO_REV(6, 3, 0, ANY_ID),
|
||||
.revn = 630,
|
||||
|
@ -323,6 +359,10 @@ static const struct adreno_info gpulist[] = {
|
|||
.init = a6xx_gpu_init,
|
||||
.zapfw = "a640_zap.mdt",
|
||||
.hwcg = a640_hwcg,
|
||||
.speedbins = ADRENO_SPEEDBINS(
|
||||
{ 0, 0 },
|
||||
{ 1, 1 },
|
||||
),
|
||||
}, {
|
||||
.rev = ADRENO_REV(6, 5, 0, ANY_ID),
|
||||
.revn = 650,
|
||||
|
@ -338,6 +378,12 @@ static const struct adreno_info gpulist[] = {
|
|||
.zapfw = "a650_zap.mdt",
|
||||
.hwcg = a650_hwcg,
|
||||
.address_space_size = SZ_16G,
|
||||
.speedbins = ADRENO_SPEEDBINS(
|
||||
{ 0, 0 },
|
||||
{ 1, 1 },
|
||||
{ 2, 3 }, /* Yep, 2 and 3 are swapped! :/ */
|
||||
{ 3, 2 },
|
||||
),
|
||||
}, {
|
||||
.rev = ADRENO_REV(6, 6, 0, ANY_ID),
|
||||
.revn = 660,
|
||||
|
@ -366,6 +412,11 @@ static const struct adreno_info gpulist[] = {
|
|||
.init = a6xx_gpu_init,
|
||||
.hwcg = a660_hwcg,
|
||||
.address_space_size = SZ_16G,
|
||||
.speedbins = ADRENO_SPEEDBINS(
|
||||
{ 0, 0 },
|
||||
{ 117, 0 },
|
||||
{ 190, 1 },
|
||||
),
|
||||
}, {
|
||||
.rev = ADRENO_REV(6, 8, 0, ANY_ID),
|
||||
.revn = 680,
|
||||
|
|
|
@ -60,6 +60,11 @@ struct adreno_reglist {
|
|||
extern const struct adreno_reglist a612_hwcg[], a615_hwcg[], a630_hwcg[], a640_hwcg[], a650_hwcg[];
|
||||
extern const struct adreno_reglist a660_hwcg[], a690_hwcg[];
|
||||
|
||||
struct adreno_speedbin {
|
||||
uint16_t fuse;
|
||||
uint16_t speedbin;
|
||||
};
|
||||
|
||||
struct adreno_info {
|
||||
const char *machine;
|
||||
struct adreno_rev rev;
|
||||
|
@ -72,8 +77,33 @@ struct adreno_info {
|
|||
u32 inactive_period;
|
||||
const struct adreno_reglist *hwcg;
|
||||
u64 address_space_size;
|
||||
/**
|
||||
* @speedbins: Optional table of fuse to speedbin mappings
|
||||
*
|
||||
* Consists of pairs of fuse, index mappings, terminated with
|
||||
* {SHRT_MAX, 0} sentinal.
|
||||
*/
|
||||
struct adreno_speedbin *speedbins;
|
||||
};
|
||||
|
||||
/*
|
||||
* Helper to build a speedbin table, ie. the table:
|
||||
* fuse | speedbin
|
||||
* -----+---------
|
||||
* 0 | 0
|
||||
* 169 | 1
|
||||
* 174 | 2
|
||||
*
|
||||
* would be declared as:
|
||||
*
|
||||
* .speedbins = ADRENO_SPEEDBINS(
|
||||
* { 0, 0 },
|
||||
* { 169, 1 },
|
||||
* { 174, 2 },
|
||||
* ),
|
||||
*/
|
||||
#define ADRENO_SPEEDBINS(tbl...) (struct adreno_speedbin[]) { tbl {SHRT_MAX, 0} }
|
||||
|
||||
const struct adreno_info *adreno_info(struct adreno_rev rev);
|
||||
|
||||
struct adreno_gpu {
|
||||
|
|
Loading…
Add table
Reference in a new issue