Commit c928a05e authored by Rob Clark's avatar Rob Clark

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: default avatarRob Clark <robdclark@chromium.org>
Reviewed-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Patchwork: https://patchwork.freedesktop.org/patch/549769/
parent f30a648d
...@@ -2204,159 +2204,19 @@ static bool a6xx_progress(struct msm_gpu *gpu, struct msm_ringbuffer *ring) ...@@ -2204,159 +2204,19 @@ static bool a6xx_progress(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
return progress; return progress;
} }
static u32 a610_get_speed_bin(u32 fuse) static u32 fuse_to_supp_hw(const struct adreno_info *info, u32 fuse)
{ {
/* if (!info->speedbins)
* 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; 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)) for (int i = 0; info->speedbins[i].fuse != SHRT_MAX; i++)
val = a618_get_speed_bin(fuse); if (info->speedbins[i].fuse == fuse)
return BIT(info->speedbins[i].speedbin);
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);
return UINT_MAX; return UINT_MAX;
}
return (1 << val);
} }
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 supp_hw;
u32 speedbin; u32 speedbin;
...@@ -2375,7 +2235,14 @@ static int a6xx_set_supported_hw(struct device *dev, struct adreno_gpu *adreno_g ...@@ -2375,7 +2235,14 @@ static int a6xx_set_supported_hw(struct device *dev, struct adreno_gpu *adreno_g
return ret; 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); ret = devm_pm_opp_set_supported_hw(dev, &supp_hw, 1);
if (ret) if (ret)
...@@ -2483,17 +2350,11 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) ...@@ -2483,17 +2350,11 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
if (!info) if (!info)
return ERR_PTR(-EINVAL); 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); adreno_gpu->base.hw_apriv = !!(info->quirks & ADRENO_QUIRK_HAS_HW_APRIV);
a6xx_llc_slices_init(pdev, a6xx_gpu); 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) { if (ret) {
a6xx_destroy(&(a6xx_gpu->base.base)); a6xx_destroy(&(a6xx_gpu->base.base));
return ERR_PTR(ret); return ERR_PTR(ret);
......
...@@ -247,6 +247,20 @@ static const struct adreno_info gpulist[] = { ...@@ -247,6 +247,20 @@ static const struct adreno_info gpulist[] = {
.init = a6xx_gpu_init, .init = a6xx_gpu_init,
.zapfw = "a610_zap.mdt", .zapfw = "a610_zap.mdt",
.hwcg = a612_hwcg, .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), .rev = ADRENO_REV(6, 1, 8, ANY_ID),
.revn = 618, .revn = 618,
...@@ -258,6 +272,11 @@ static const struct adreno_info gpulist[] = { ...@@ -258,6 +272,11 @@ static const struct adreno_info gpulist[] = {
.inactive_period = DRM_MSM_INACTIVE_PERIOD, .inactive_period = DRM_MSM_INACTIVE_PERIOD,
.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT, .quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
.init = a6xx_gpu_init, .init = a6xx_gpu_init,
.speedbins = ADRENO_SPEEDBINS(
{ 0, 0 },
{ 169, 1 },
{ 174, 2 },
),
}, { }, {
.machine = "qcom,sm4350", .machine = "qcom,sm4350",
.rev = ADRENO_REV(6, 1, 9, ANY_ID), .rev = ADRENO_REV(6, 1, 9, ANY_ID),
...@@ -271,6 +290,11 @@ static const struct adreno_info gpulist[] = { ...@@ -271,6 +290,11 @@ static const struct adreno_info gpulist[] = {
.init = a6xx_gpu_init, .init = a6xx_gpu_init,
.zapfw = "a615_zap.mdt", .zapfw = "a615_zap.mdt",
.hwcg = a615_hwcg, .hwcg = a615_hwcg,
.speedbins = ADRENO_SPEEDBINS(
{ 0, 0 },
{ 138, 1 },
{ 92, 2 },
),
}, { }, {
.machine = "qcom,sm6375", .machine = "qcom,sm6375",
.rev = ADRENO_REV(6, 1, 9, ANY_ID), .rev = ADRENO_REV(6, 1, 9, ANY_ID),
...@@ -284,6 +308,11 @@ static const struct adreno_info gpulist[] = { ...@@ -284,6 +308,11 @@ static const struct adreno_info gpulist[] = {
.init = a6xx_gpu_init, .init = a6xx_gpu_init,
.zapfw = "a615_zap.mdt", .zapfw = "a615_zap.mdt",
.hwcg = a615_hwcg, .hwcg = a615_hwcg,
.speedbins = ADRENO_SPEEDBINS(
{ 0, 0 },
{ 190, 1 },
{ 177, 2 },
),
}, { }, {
.rev = ADRENO_REV(6, 1, 9, ANY_ID), .rev = ADRENO_REV(6, 1, 9, ANY_ID),
.revn = 619, .revn = 619,
...@@ -297,6 +326,13 @@ static const struct adreno_info gpulist[] = { ...@@ -297,6 +326,13 @@ static const struct adreno_info gpulist[] = {
.init = a6xx_gpu_init, .init = a6xx_gpu_init,
.zapfw = "a615_zap.mdt", .zapfw = "a615_zap.mdt",
.hwcg = a615_hwcg, .hwcg = a615_hwcg,
.speedbins = ADRENO_SPEEDBINS(
{ 0, 0 },
{ 120, 4 },
{ 138, 3 },
{ 169, 2 },
{ 180, 1 },
),
}, { }, {
.rev = ADRENO_REV(6, 3, 0, ANY_ID), .rev = ADRENO_REV(6, 3, 0, ANY_ID),
.revn = 630, .revn = 630,
...@@ -323,6 +359,10 @@ static const struct adreno_info gpulist[] = { ...@@ -323,6 +359,10 @@ static const struct adreno_info gpulist[] = {
.init = a6xx_gpu_init, .init = a6xx_gpu_init,
.zapfw = "a640_zap.mdt", .zapfw = "a640_zap.mdt",
.hwcg = a640_hwcg, .hwcg = a640_hwcg,
.speedbins = ADRENO_SPEEDBINS(
{ 0, 0 },
{ 1, 1 },
),
}, { }, {
.rev = ADRENO_REV(6, 5, 0, ANY_ID), .rev = ADRENO_REV(6, 5, 0, ANY_ID),
.revn = 650, .revn = 650,
...@@ -338,6 +378,12 @@ static const struct adreno_info gpulist[] = { ...@@ -338,6 +378,12 @@ static const struct adreno_info gpulist[] = {
.zapfw = "a650_zap.mdt", .zapfw = "a650_zap.mdt",
.hwcg = a650_hwcg, .hwcg = a650_hwcg,
.address_space_size = SZ_16G, .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), .rev = ADRENO_REV(6, 6, 0, ANY_ID),
.revn = 660, .revn = 660,
...@@ -366,6 +412,11 @@ static const struct adreno_info gpulist[] = { ...@@ -366,6 +412,11 @@ static const struct adreno_info gpulist[] = {
.init = a6xx_gpu_init, .init = a6xx_gpu_init,
.hwcg = a660_hwcg, .hwcg = a660_hwcg,
.address_space_size = SZ_16G, .address_space_size = SZ_16G,
.speedbins = ADRENO_SPEEDBINS(
{ 0, 0 },
{ 117, 0 },
{ 190, 1 },
),
}, { }, {
.rev = ADRENO_REV(6, 8, 0, ANY_ID), .rev = ADRENO_REV(6, 8, 0, ANY_ID),
.revn = 680, .revn = 680,
......
...@@ -60,6 +60,11 @@ struct adreno_reglist { ...@@ -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 a612_hwcg[], a615_hwcg[], a630_hwcg[], a640_hwcg[], a650_hwcg[];
extern const struct adreno_reglist a660_hwcg[], a690_hwcg[]; extern const struct adreno_reglist a660_hwcg[], a690_hwcg[];
struct adreno_speedbin {
uint16_t fuse;
uint16_t speedbin;
};
struct adreno_info { struct adreno_info {
const char *machine; const char *machine;
struct adreno_rev rev; struct adreno_rev rev;
...@@ -72,8 +77,33 @@ struct adreno_info { ...@@ -72,8 +77,33 @@ struct adreno_info {
u32 inactive_period; u32 inactive_period;
const struct adreno_reglist *hwcg; const struct adreno_reglist *hwcg;
u64 address_space_size; 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); const struct adreno_info *adreno_info(struct adreno_rev rev);
struct adreno_gpu { struct adreno_gpu {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment