[3/5] drm: msm: add support for A750 GPU
Commit Message
Add support for the A750 GPU found on the SM8650 platform
Unlike the the very close A740 GPU on the SM8550 SoC, the A750 GPU
doesn't have an HWCFG block but a separate register set.
The missing registers are added in the a6xx.xml.h file that would
require a subsequent sync and the non-existent hwcfg is handled
in a6xx_set_hwcg().
The A750 GPU info are added under the adreno_is_a750() macro and
the ADRENO_7XX_GEN3 family id.
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
---
drivers/gpu/drm/msm/adreno/a6xx.xml.h | 8 ++++++++
drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 2 ++
drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 29 ++++++++++++++++++++++++++---
drivers/gpu/drm/msm/adreno/adreno_device.c | 14 ++++++++++++++
drivers/gpu/drm/msm/adreno/adreno_gpu.h | 9 ++++++++-
5 files changed, 58 insertions(+), 4 deletions(-)
Comments
On 12.02.2024 11:37, Neil Armstrong wrote:
> Add support for the A750 GPU found on the SM8650 platform
>
> Unlike the the very close A740 GPU on the SM8550 SoC, the A750 GPU
> doesn't have an HWCFG block but a separate register set.
>
> The missing registers are added in the a6xx.xml.h file that would
> require a subsequent sync and the non-existent hwcfg is handled
> in a6xx_set_hwcg().
These should also be submitted to mesa to make sure the next header sync
doesn't wipe them
[...]
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> @@ -958,10 +958,11 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
> struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
> struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
> const struct adreno_reglist *reg;
> + bool skip_programming = !(adreno_gpu->info->hwcg || adreno_is_a7xx(adreno_gpu));
is_a750?
> unsigned int i;
> u32 val, clock_cntl_on, cgc_mode;
>
> - if (!adreno_gpu->info->hwcg)
> + if (skip_programming)
> return;
>
> if (adreno_is_a630(adreno_gpu))
> @@ -982,6 +983,25 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
> state ? 0x5555 : 0);
> }
>
> + if (!adreno_gpu->info->hwcg) {
I don't think this block of code is reachable now, no?
Maybe remove the skip_programming and if_a750 here?
> + gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 1);
> + gpu_write(gpu, REG_A7XX_RBBM_CGC_GLOBAL_LOAD_CMD, state ? 1 : 0);
> +
> + if (state) {
> + gpu_write(gpu, REG_A7XX_RBBM_CGC_P2S_TRIG_CMD, 1);
> +
> + if (gpu_poll_timeout(gpu, REG_A7XX_RBBM_CGC_P2S_STATUS, val,
> + val & BIT(0), 1, 10)) {
We should define that bit name (the err suggests it's
REG_A7XX_RBBM_GCC_P2S_STATUS_TXDONE or so)
[...]
> +static inline int adreno_is_a750(struct adreno_gpu *gpu)
> +{
> + return gpu->info->chip_ids[0] == 0x43051401;
> +}
> +
> /* Placeholder to make future diffs smaller */
Please also remove this comment now that it's invalid
Konrad
On 12/02/2024 11:46, Konrad Dybcio wrote:
> On 12.02.2024 11:37, Neil Armstrong wrote:
>> Add support for the A750 GPU found on the SM8650 platform
>>
>> Unlike the the very close A740 GPU on the SM8550 SoC, the A750 GPU
>> doesn't have an HWCFG block but a separate register set.
>>
>> The missing registers are added in the a6xx.xml.h file that would
>> require a subsequent sync and the non-existent hwcfg is handled
>> in a6xx_set_hwcg().
>
> These should also be submitted to mesa to make sure the next header sync
> doesn't wipe them
Ack submitting them right now: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27576
>
> [...]
>
>> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>> @@ -958,10 +958,11 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
>> struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
>> struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
>> const struct adreno_reglist *reg;
>> + bool skip_programming = !(adreno_gpu->info->hwcg || adreno_is_a7xx(adreno_gpu));
>
> is_a750?
OK right, I was thinking of the next gpu which will probably also miss an hwcfg
>
>> unsigned int i;
>> u32 val, clock_cntl_on, cgc_mode;
>>
>> - if (!adreno_gpu->info->hwcg)
>> + if (skip_programming)
>> return;
>>
>> if (adreno_is_a630(adreno_gpu))
>> @@ -982,6 +983,25 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
>> state ? 0x5555 : 0);
>> }
>>
>> + if (!adreno_gpu->info->hwcg) {
>
> I don't think this block of code is reachable now, no?
It is because we didn't skip when adreno_is_a7xx(adreno_gpu)
>
> Maybe remove the skip_programming and if_a750 here?
This would require:
>> - if (!adreno_gpu->info->hwcg || )
>> + if (!(adreno_gpu->info->hwcg || adreno_is_a750(adreno_gpu)))
and:
>> + if (adreno_is_a750(adreno_gpu)) {
But if the next gpu also doesn't have an hwcfg, we will need to use
the current design...
I just tried with:
====================><===============================
@@ -961,7 +961,7 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
unsigned int i;
u32 val, clock_cntl_on, cgc_mode;
- if (!adreno_gpu->info->hwcg)
+ if (!(adreno_gpu->info->hwcg || adreno_is_a750(adreno_gpu)))
return;
if (adreno_is_a630(adreno_gpu))
@@ -982,6 +982,25 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
state ? 0x5555 : 0);
}
+ if (adreno_is_a750(adreno_gpu)) {
+ gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 1);
+ gpu_write(gpu, REG_A7XX_RBBM_CGC_GLOBAL_LOAD_CMD, state ? 1 : 0);
+
+ if (state) {
+ gpu_write(gpu, REG_A7XX_RBBM_CGC_P2S_TRIG_CMD, 1);
+
+ if (gpu_poll_timeout(gpu, REG_A7XX_RBBM_CGC_P2S_STATUS, val,
+ val & A7XX_RBBM_CGC_P2S_STATUS_TXDONE, 1, 10)) {
+ dev_err(&gpu->pdev->dev, "RBBM_CGC_P2S_STATUS TXDONE Poll failed\n");
+ return;
+ }
+
+ gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 0);
+ }
+
+ return;
+ }
+
val = gpu_read(gpu, REG_A6XX_RBBM_CLOCK_CNTL);
/* Don't re-program the registers if they are already correct */
====================><===============================
And it works fine, does it work it for you ?
>
>> + gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 1);
>> + gpu_write(gpu, REG_A7XX_RBBM_CGC_GLOBAL_LOAD_CMD, state ? 1 : 0);
>> +
>> + if (state) {
>> + gpu_write(gpu, REG_A7XX_RBBM_CGC_P2S_TRIG_CMD, 1);
>> +
>> + if (gpu_poll_timeout(gpu, REG_A7XX_RBBM_CGC_P2S_STATUS, val,
>> + val & BIT(0), 1, 10)) {
>
> We should define that bit name (the err suggests it's
> REG_A7XX_RBBM_GCC_P2S_STATUS_TXDONE or so)
>
> [...]
>
>> +static inline int adreno_is_a750(struct adreno_gpu *gpu)
>> +{
>> + return gpu->info->chip_ids[0] == 0x43051401;
>> +}
>> +
>> /* Placeholder to make future diffs smaller */
>
> Please also remove this comment now that it's invalid
Ack
>
> Konrad
Thanks,
Neil
On 12.02.2024 15:45, Neil Armstrong wrote:
> On 12/02/2024 11:46, Konrad Dybcio wrote:
>> On 12.02.2024 11:37, Neil Armstrong wrote:
>>> Add support for the A750 GPU found on the SM8650 platform
>>>
>>> Unlike the the very close A740 GPU on the SM8550 SoC, the A750 GPU
>>> doesn't have an HWCFG block but a separate register set.
>>>
>>> The missing registers are added in the a6xx.xml.h file that would
>>> require a subsequent sync and the non-existent hwcfg is handled
>>> in a6xx_set_hwcg().
>>
>> These should also be submitted to mesa to make sure the next header sync
>> doesn't wipe them
>
> Ack submitting them right now: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27576
Thanks
>
>>
>> [...]
>>
>>> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>>> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>>> @@ -958,10 +958,11 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
>>> struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
>>> struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
>>> const struct adreno_reglist *reg;
>>> + bool skip_programming = !(adreno_gpu->info->hwcg || adreno_is_a7xx(adreno_gpu));
>>
>> is_a750?
>
> OK right, I was thinking of the next gpu which will probably also miss an hwcfg
>
>>
>>> unsigned int i;
>>> u32 val, clock_cntl_on, cgc_mode;
>>> - if (!adreno_gpu->info->hwcg)
>>> + if (skip_programming)
>>> return;
>>> if (adreno_is_a630(adreno_gpu))
>>> @@ -982,6 +983,25 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
>>> state ? 0x5555 : 0);
>>> }
>>> + if (!adreno_gpu->info->hwcg) {
>>
>> I don't think this block of code is reachable now, no?
>
> It is because we didn't skip when adreno_is_a7xx(adreno_gpu)
Ahh I misread the brackets within the assignment
>
>>
>> Maybe remove the skip_programming and if_a750 here?
> This would require:
>>> - if (!adreno_gpu->info->hwcg || )
>>> + if (!(adreno_gpu->info->hwcg || adreno_is_a750(adreno_gpu)))
>
> and:
>
>>> + if (adreno_is_a750(adreno_gpu)) {
>
> But if the next gpu also doesn't have an hwcfg, we will need to use
> the current design...
>
> I just tried with:
> ====================><===============================
> @@ -961,7 +961,7 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
> unsigned int i;
> u32 val, clock_cntl_on, cgc_mode;
>
> - if (!adreno_gpu->info->hwcg)
> + if (!(adreno_gpu->info->hwcg || adreno_is_a750(adreno_gpu)))
> return;
>
> if (adreno_is_a630(adreno_gpu))
> @@ -982,6 +982,25 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
> state ? 0x5555 : 0);
> }
>
> + if (adreno_is_a750(adreno_gpu)) {
> + gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 1);
> + gpu_write(gpu, REG_A7XX_RBBM_CGC_GLOBAL_LOAD_CMD, state ? 1 : 0);
> +
> + if (state) {
> + gpu_write(gpu, REG_A7XX_RBBM_CGC_P2S_TRIG_CMD, 1);
> +
> + if (gpu_poll_timeout(gpu, REG_A7XX_RBBM_CGC_P2S_STATUS, val,
> + val & A7XX_RBBM_CGC_P2S_STATUS_TXDONE, 1, 10)) {
> + dev_err(&gpu->pdev->dev, "RBBM_CGC_P2S_STATUS TXDONE Poll failed\n");
> + return;
> + }
> +
> + gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 0);
> + }
> +
> + return;
> + }
> +
> val = gpu_read(gpu, REG_A6XX_RBBM_CLOCK_CNTL);
>
> /* Don't re-program the registers if they are already correct */
> ====================><===============================
>
> And it works fine, does it work it for you ?
Let's keep it as-is in the original submission, as I've mentioned, I had
misread the code
Konrad
>
>>
>>> + gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 1);
>>> + gpu_write(gpu, REG_A7XX_RBBM_CGC_GLOBAL_LOAD_CMD, state ? 1 : 0);
>>> +
>>> + if (state) {
>>> + gpu_write(gpu, REG_A7XX_RBBM_CGC_P2S_TRIG_CMD, 1);
>>> +
>>> + if (gpu_poll_timeout(gpu, REG_A7XX_RBBM_CGC_P2S_STATUS, val,
>>> + val & BIT(0), 1, 10)) {
>>
>> We should define that bit name (the err suggests it's
>> REG_A7XX_RBBM_GCC_P2S_STATUS_TXDONE or so)
>>
>> [...]
>>
>>> +static inline int adreno_is_a750(struct adreno_gpu *gpu)
>>> +{
>>> + return gpu->info->chip_ids[0] == 0x43051401;
>>> +}
>>> +
>>> /* Placeholder to make future diffs smaller */
>>
>> Please also remove this comment now that it's invalid
>
> Ack
>
>>
>> Konrad
>
> Thanks,
> Neil
>
On 14/02/2024 22:43, Konrad Dybcio wrote:
> On 12.02.2024 15:45, Neil Armstrong wrote:
>> On 12/02/2024 11:46, Konrad Dybcio wrote:
>>> On 12.02.2024 11:37, Neil Armstrong wrote:
>>>> Add support for the A750 GPU found on the SM8650 platform
>>>>
>>>> Unlike the the very close A740 GPU on the SM8550 SoC, the A750 GPU
>>>> doesn't have an HWCFG block but a separate register set.
>>>>
>>>> The missing registers are added in the a6xx.xml.h file that would
>>>> require a subsequent sync and the non-existent hwcfg is handled
>>>> in a6xx_set_hwcg().
>>>
>>> These should also be submitted to mesa to make sure the next header sync
>>> doesn't wipe them
>>
>> Ack submitting them right now: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27576
>
> Thanks
>
>>
>>>
>>> [...]
>>>
>>>> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>>>> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>>>> @@ -958,10 +958,11 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
>>>> struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
>>>> struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
>>>> const struct adreno_reglist *reg;
>>>> + bool skip_programming = !(adreno_gpu->info->hwcg || adreno_is_a7xx(adreno_gpu));
>>>
>>> is_a750?
>>
>> OK right, I was thinking of the next gpu which will probably also miss an hwcfg
>>
>>>
>>>> unsigned int i;
>>>> u32 val, clock_cntl_on, cgc_mode;
>>>> - if (!adreno_gpu->info->hwcg)
>>>> + if (skip_programming)
>>>> return;
>>>> if (adreno_is_a630(adreno_gpu))
>>>> @@ -982,6 +983,25 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
>>>> state ? 0x5555 : 0);
>>>> }
>>>> + if (!adreno_gpu->info->hwcg) {
>>>
>>> I don't think this block of code is reachable now, no?
>>
>> It is because we didn't skip when adreno_is_a7xx(adreno_gpu)
>
> Ahh I misread the brackets within the assignment
>
>>
>>>
>>> Maybe remove the skip_programming and if_a750 here?
>> This would require:
>>>> - if (!adreno_gpu->info->hwcg || )
>>>> + if (!(adreno_gpu->info->hwcg || adreno_is_a750(adreno_gpu)))
>>
>> and:
>>
>>>> + if (adreno_is_a750(adreno_gpu)) {
>>
>> But if the next gpu also doesn't have an hwcfg, we will need to use
>> the current design...
>>
>> I just tried with:
>> ====================><===============================
>> @@ -961,7 +961,7 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
>> unsigned int i;
>> u32 val, clock_cntl_on, cgc_mode;
>>
>> - if (!adreno_gpu->info->hwcg)
>> + if (!(adreno_gpu->info->hwcg || adreno_is_a750(adreno_gpu)))
>> return;
>>
>> if (adreno_is_a630(adreno_gpu))
>> @@ -982,6 +982,25 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
>> state ? 0x5555 : 0);
>> }
>>
>> + if (adreno_is_a750(adreno_gpu)) {
>> + gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 1);
>> + gpu_write(gpu, REG_A7XX_RBBM_CGC_GLOBAL_LOAD_CMD, state ? 1 : 0);
>> +
>> + if (state) {
>> + gpu_write(gpu, REG_A7XX_RBBM_CGC_P2S_TRIG_CMD, 1);
>> +
>> + if (gpu_poll_timeout(gpu, REG_A7XX_RBBM_CGC_P2S_STATUS, val,
>> + val & A7XX_RBBM_CGC_P2S_STATUS_TXDONE, 1, 10)) {
>> + dev_err(&gpu->pdev->dev, "RBBM_CGC_P2S_STATUS TXDONE Poll failed\n");
>> + return;
>> + }
>> +
>> + gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 0);
>> + }
>> +
>> + return;
>> + }
>> +
>> val = gpu_read(gpu, REG_A6XX_RBBM_CLOCK_CNTL);
>>
>> /* Don't re-program the registers if they are already correct */
>> ====================><===============================
>>
>> And it works fine, does it work it for you ?
>
> Let's keep it as-is in the original submission, as I've mentioned, I had
> misread the code
Ack thanks
Neil
>
> Konrad
>
>>
>>>
>>>> + gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 1);
>>>> + gpu_write(gpu, REG_A7XX_RBBM_CGC_GLOBAL_LOAD_CMD, state ? 1 : 0);
>>>> +
>>>> + if (state) {
>>>> + gpu_write(gpu, REG_A7XX_RBBM_CGC_P2S_TRIG_CMD, 1);
>>>> +
>>>> + if (gpu_poll_timeout(gpu, REG_A7XX_RBBM_CGC_P2S_STATUS, val,
>>>> + val & BIT(0), 1, 10)) {
>>>
>>> We should define that bit name (the err suggests it's
>>> REG_A7XX_RBBM_GCC_P2S_STATUS_TXDONE or so)
>>>
>>> [...]
>>>
>>>> +static inline int adreno_is_a750(struct adreno_gpu *gpu)
>>>> +{
>>>> + return gpu->info->chip_ids[0] == 0x43051401;
>>>> +}
>>>> +
>>>> /* Placeholder to make future diffs smaller */
>>>
>>> Please also remove this comment now that it's invalid
>>
>> Ack
>>
>>>
>>> Konrad
>>
>> Thanks,
>> Neil
>>
@@ -1725,6 +1725,8 @@ static inline uint32_t REG_A6XX_RBBM_PERFCTR_RBBM_SEL(uint32_t i0) { return 0x00
#define REG_A6XX_RBBM_BLOCK_SW_RESET_CMD2 0x00000046
+#define REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL 0x000000ad
+
#define REG_A6XX_RBBM_CLOCK_CNTL 0x000000ae
#define REG_A6XX_RBBM_CLOCK_CNTL_SP0 0x000000b0
@@ -1939,12 +1941,18 @@ static inline uint32_t REG_A6XX_RBBM_PERFCTR_RBBM_SEL(uint32_t i0) { return 0x00
#define REG_A6XX_RBBM_CLOCK_HYST_HLSQ 0x0000011d
+#define REG_A7XX_RBBM_CGC_GLOBAL_LOAD_CMD 0x0000011e
+
+#define REG_A7XX_RBBM_CGC_P2S_TRIG_CMD 0x0000011f
+
#define REG_A6XX_RBBM_CLOCK_CNTL_TEX_FCHE 0x00000120
#define REG_A6XX_RBBM_CLOCK_DELAY_TEX_FCHE 0x00000121
#define REG_A6XX_RBBM_CLOCK_HYST_TEX_FCHE 0x00000122
+#define REG_A7XX_RBBM_CGC_P2S_STATUS 0x00000122
+
#define REG_A7XX_RBBM_CLOCK_HYST2_VFD 0x0000012f
#define REG_A6XX_RBBM_LPAC_GBIF_CLIENT_QOS_CNTL 0x000005ff
@@ -842,6 +842,8 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state)
*/
if (adreno_is_a740(adreno_gpu))
chipid_min = 2;
+ else if (adreno_is_a750(adreno_gpu))
+ chipid_min = 9;
else
return -EINVAL;
@@ -958,10 +958,11 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
const struct adreno_reglist *reg;
+ bool skip_programming = !(adreno_gpu->info->hwcg || adreno_is_a7xx(adreno_gpu));
unsigned int i;
u32 val, clock_cntl_on, cgc_mode;
- if (!adreno_gpu->info->hwcg)
+ if (skip_programming)
return;
if (adreno_is_a630(adreno_gpu))
@@ -982,6 +983,25 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
state ? 0x5555 : 0);
}
+ if (!adreno_gpu->info->hwcg) {
+ gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 1);
+ gpu_write(gpu, REG_A7XX_RBBM_CGC_GLOBAL_LOAD_CMD, state ? 1 : 0);
+
+ if (state) {
+ gpu_write(gpu, REG_A7XX_RBBM_CGC_P2S_TRIG_CMD, 1);
+
+ if (gpu_poll_timeout(gpu, REG_A7XX_RBBM_CGC_P2S_STATUS, val,
+ val & BIT(0), 1, 10)) {
+ dev_err(&gpu->pdev->dev, "RBBM_CGC_P2S_STATUS TXDONE Poll failed\n");
+ return;
+ }
+
+ gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 0);
+ }
+
+ return;
+ }
+
val = gpu_read(gpu, REG_A6XX_RBBM_CLOCK_CNTL);
/* Don't re-program the registers if they are already correct */
@@ -1239,7 +1259,9 @@ static void a6xx_set_cp_protect(struct msm_gpu *gpu)
count = ARRAY_SIZE(a660_protect);
count_max = 48;
BUILD_BUG_ON(ARRAY_SIZE(a660_protect) > 48);
- } else if (adreno_is_a730(adreno_gpu) || adreno_is_a740(adreno_gpu)) {
+ } else if (adreno_is_a730(adreno_gpu) ||
+ adreno_is_a740(adreno_gpu) ||
+ adreno_is_a750(adreno_gpu)) {
regs = a730_protect;
count = ARRAY_SIZE(a730_protect);
count_max = 48;
@@ -2880,7 +2902,8 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
/* gpu->info only gets assigned in adreno_gpu_init() */
is_a7xx = config->info->family == ADRENO_7XX_GEN1 ||
- config->info->family == ADRENO_7XX_GEN2;
+ config->info->family == ADRENO_7XX_GEN2 ||
+ config->info->family == ADRENO_7XX_GEN3;
a6xx_llc_slices_init(pdev, a6xx_gpu, is_a7xx);
@@ -522,6 +522,20 @@ static const struct adreno_info gpulist[] = {
.zapfw = "a740_zap.mdt",
.hwcg = a740_hwcg,
.address_space_size = SZ_16G,
+ }, {
+ .chip_ids = ADRENO_CHIP_IDS(0x43051401), /* "C520v2" */
+ .family = ADRENO_7XX_GEN3,
+ .fw = {
+ [ADRENO_FW_SQE] = "gen70900_sqe.fw",
+ [ADRENO_FW_GMU] = "gmu_gen70900.bin",
+ },
+ .gmem = 3 * SZ_1M,
+ .inactive_period = DRM_MSM_INACTIVE_PERIOD,
+ .quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+ ADRENO_QUIRK_HAS_HW_APRIV,
+ .init = a6xx_gpu_init,
+ .zapfw = "gen70900_zap.mbn",
+ .address_space_size = SZ_16G,
},
};
@@ -48,6 +48,7 @@ enum adreno_family {
ADRENO_6XX_GEN4, /* a660 family */
ADRENO_7XX_GEN1, /* a730 family */
ADRENO_7XX_GEN2, /* a740 family */
+ ADRENO_7XX_GEN3, /* a750 family */
};
#define ADRENO_QUIRK_TWO_PASS_USE_WFI BIT(0)
@@ -423,12 +424,18 @@ static inline int adreno_is_a740(struct adreno_gpu *gpu)
return gpu->info->chip_ids[0] == 0x43050a01;
}
+static inline int adreno_is_a750(struct adreno_gpu *gpu)
+{
+ return gpu->info->chip_ids[0] == 0x43051401;
+}
+
/* Placeholder to make future diffs smaller */
static inline int adreno_is_a740_family(struct adreno_gpu *gpu)
{
if (WARN_ON_ONCE(!gpu->info))
return false;
- return gpu->info->family == ADRENO_7XX_GEN2;
+ return gpu->info->family == ADRENO_7XX_GEN2 ||
+ gpu->info->family == ADRENO_7XX_GEN3;
}
static inline int adreno_is_a7xx(struct adreno_gpu *gpu)