Loading drivers/gpu/msm/a6xx_reg.h +3 −0 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _A6XX_REG_H Loading Loading @@ -406,6 +407,8 @@ #define A6XX_RBBM_PERFCTR_RBBM_SEL_2 0x509 #define A6XX_RBBM_PERFCTR_RBBM_SEL_3 0x50A #define A6XX_RBBM_PERFCTR_GPU_BUSY_MASKED 0x50B #define A6XX_RBBM_PERFCTR_SRAM_INIT_CMD 0x50e #define A6XX_RBBM_PERFCTR_SRAM_INIT_STATUS 0x50f #define A6XX_RBBM_ISDB_CNT 0x533 #define A6XX_RBBM_NC_MODE_CNTL 0X534 Loading drivers/gpu/msm/adreno.h +8 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ #include "adreno_ringbuffer.h" #include "kgsl_sharedmem.h" /* Index to preemption scratch buffer to store KMD postamble */ #define KMD_POSTAMBLE_IDX 100 /* ADRENO_DEVICE - Given a kgsl_device return the adreno device struct */ #define ADRENO_DEVICE(device) \ container_of(device, struct adreno_device, dev) Loading Loading @@ -232,6 +235,9 @@ struct adreno_gpudev; /* Time to allow preemption to complete (in ms) */ #define ADRENO_PREEMPT_TIMEOUT 10000 #define PREEMPT_SCRATCH_ADDR(dev, id) \ ((dev)->preempt.scratch->gpuaddr + (id * sizeof(u64))) /** * enum adreno_preempt_states * ADRENO_PREEMPT_NONE: No preemption is scheduled Loading Loading @@ -261,6 +267,7 @@ enum adreno_preempt_states { * skipsaverestore: To skip saverestore during L1 preemption (for 6XX) * usesgmem: enable GMEM save/restore across preemption (for 6XX) * count: Track the number of preemptions triggered * @postamble_len: Number of dwords in KMD postamble pm4 packet */ struct adreno_preemption { atomic_t state; Loading @@ -271,6 +278,7 @@ struct adreno_preemption { bool skipsaverestore; bool usesgmem; unsigned int count; u32 postamble_len; }; struct adreno_busy_data { Loading drivers/gpu/msm/adreno_a6xx_preempt.c +40 −4 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include "adreno.h" Loading Loading @@ -543,13 +544,24 @@ unsigned int a6xx_preemption_pre_ibsubmit( if (context) { struct adreno_context *drawctxt = ADRENO_CONTEXT(context); struct adreno_ringbuffer *rb = drawctxt->rb; uint64_t dest = adreno_dev->preempt.scratch->gpuaddr + (rb->id * sizeof(u64)); uint64_t dest = PREEMPT_SCRATCH_ADDR(adreno_dev, rb->id); *cmds++ = cp_mem_packet(adreno_dev, CP_MEM_WRITE, 2, 2); cmds += cp_gpuaddr(adreno_dev, cmds, dest); *cmds++ = lower_32_bits(gpuaddr); *cmds++ = upper_32_bits(gpuaddr); /* Add a KMD post amble to clear the perf counters during preemption */ if (!adreno_dev->perfcounter) { u64 kmd_postamble_addr = PREEMPT_SCRATCH_ADDR(adreno_dev, KMD_POSTAMBLE_IDX); *cmds++ = cp_type7_packet(CP_SET_AMBLE, 3); *cmds++ = lower_32_bits(kmd_postamble_addr); *cmds++ = upper_32_bits(kmd_postamble_addr); *cmds++ = FIELD_PREP(GENMASK(22, 20), CP_KMD_AMBLE_TYPE) | (FIELD_PREP(GENMASK(19, 0), adreno_dev->preempt.postamble_len)); } } return (unsigned int) (cmds - cmds_orig); Loading @@ -562,8 +574,7 @@ unsigned int a6xx_preemption_post_ibsubmit(struct adreno_device *adreno_dev, struct adreno_ringbuffer *rb = adreno_dev->cur_rb; if (rb) { uint64_t dest = adreno_dev->preempt.scratch->gpuaddr + (rb->id * sizeof(u64)); uint64_t dest = PREEMPT_SCRATCH_ADDR(adreno_dev, adreno_dev->cur_rb->id); *cmds++ = cp_mem_packet(adreno_dev, CP_MEM_WRITE, 2, 2); cmds += cp_gpuaddr(adreno_dev, cmds, dest); Loading Loading @@ -721,6 +732,31 @@ int a6xx_preemption_init(struct adreno_device *adreno_dev) if (ret) return ret; /* * First 8 dwords of the preemption scratch buffer is used to store the address for CP * to save/restore VPC data. Reserve 11 dwords in the preemption scratch buffer from * index KMD_POSTAMBLE_IDX for KMD postamble pm4 packets */ if (!adreno_dev->perfcounter) { u32 *postamble = preempt->scratch->hostptr + (KMD_POSTAMBLE_IDX * sizeof(u64)); u32 count = 0; postamble[count++] = cp_type7_packet(CP_REG_RMW, 3); postamble[count++] = A6XX_RBBM_PERFCTR_SRAM_INIT_CMD; postamble[count++] = 0x0; postamble[count++] = 0x1; postamble[count++] = cp_type7_packet(CP_WAIT_REG_MEM, 6); postamble[count++] = 0x3; postamble[count++] = A6XX_RBBM_PERFCTR_SRAM_INIT_STATUS; postamble[count++] = 0x0; postamble[count++] = 0x1; postamble[count++] = 0x1; postamble[count++] = 0x0; preempt->postamble_len = count; } set_bit(ADRENO_DEVICE_PREEMPTION, &adreno_dev->priv); return 0; } Loading drivers/gpu/msm/adreno_iommu.c +18 −0 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include <linux/slab.h> Loading Loading @@ -217,6 +218,12 @@ static unsigned int _adreno_iommu_set_pt_v2_a6xx(struct kgsl_device *device, struct adreno_device *adreno_dev = ADRENO_DEVICE(device); unsigned int *cmds = cmds_orig; /* Clear performance counters during contect switches */ if (!adreno_dev->perfcounter) { *cmds++ = cp_type4_packet(A6XX_RBBM_PERFCTR_SRAM_INIT_CMD, 1); *cmds++ = 0x1; } /* CP switches the pagetable and flushes the Caches */ *cmds++ = cp_packet(adreno_dev, CP_SMMU_TABLE_UPDATE, 4); *cmds++ = lower_32_bits(ttbr0); Loading Loading @@ -245,6 +252,17 @@ static unsigned int _adreno_iommu_set_pt_v2_a6xx(struct kgsl_device *device, *cmds++ = 0; } /* Wait for performance counter clear to finish */ if (!adreno_dev->perfcounter) { *cmds++ = cp_type7_packet(CP_WAIT_REG_MEM, 6); *cmds++ = 0x3; *cmds++ = A6XX_RBBM_PERFCTR_SRAM_INIT_STATUS; *cmds++ = 0x0; *cmds++ = 0x1; *cmds++ = 0x1; *cmds++ = 0x0; } return cmds - cmds_orig; } Loading drivers/gpu/msm/adreno_perfcounter.c +5 −2 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include <linux/slab.h> Loading Loading @@ -72,7 +73,8 @@ void adreno_perfcounter_restore(struct adreno_device *adreno_dev) const struct adreno_perfcount_group *group; unsigned int counter, groupid; if (counters == NULL) /* Do not save/restore if not requested */ if (counters == NULL || !adreno_dev->perfcounter) return; for (groupid = 0; groupid < counters->group_count; groupid++) { Loading Loading @@ -106,7 +108,8 @@ inline void adreno_perfcounter_save(struct adreno_device *adreno_dev) const struct adreno_perfcount_group *group; unsigned int counter, groupid; if (counters == NULL) /* Do not save/restore if not requested */ if (counters == NULL || !adreno_dev->perfcounter) return; for (groupid = 0; groupid < counters->group_count; groupid++) { Loading Loading
drivers/gpu/msm/a6xx_reg.h +3 −0 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _A6XX_REG_H Loading Loading @@ -406,6 +407,8 @@ #define A6XX_RBBM_PERFCTR_RBBM_SEL_2 0x509 #define A6XX_RBBM_PERFCTR_RBBM_SEL_3 0x50A #define A6XX_RBBM_PERFCTR_GPU_BUSY_MASKED 0x50B #define A6XX_RBBM_PERFCTR_SRAM_INIT_CMD 0x50e #define A6XX_RBBM_PERFCTR_SRAM_INIT_STATUS 0x50f #define A6XX_RBBM_ISDB_CNT 0x533 #define A6XX_RBBM_NC_MODE_CNTL 0X534 Loading
drivers/gpu/msm/adreno.h +8 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ #include "adreno_ringbuffer.h" #include "kgsl_sharedmem.h" /* Index to preemption scratch buffer to store KMD postamble */ #define KMD_POSTAMBLE_IDX 100 /* ADRENO_DEVICE - Given a kgsl_device return the adreno device struct */ #define ADRENO_DEVICE(device) \ container_of(device, struct adreno_device, dev) Loading Loading @@ -232,6 +235,9 @@ struct adreno_gpudev; /* Time to allow preemption to complete (in ms) */ #define ADRENO_PREEMPT_TIMEOUT 10000 #define PREEMPT_SCRATCH_ADDR(dev, id) \ ((dev)->preempt.scratch->gpuaddr + (id * sizeof(u64))) /** * enum adreno_preempt_states * ADRENO_PREEMPT_NONE: No preemption is scheduled Loading Loading @@ -261,6 +267,7 @@ enum adreno_preempt_states { * skipsaverestore: To skip saverestore during L1 preemption (for 6XX) * usesgmem: enable GMEM save/restore across preemption (for 6XX) * count: Track the number of preemptions triggered * @postamble_len: Number of dwords in KMD postamble pm4 packet */ struct adreno_preemption { atomic_t state; Loading @@ -271,6 +278,7 @@ struct adreno_preemption { bool skipsaverestore; bool usesgmem; unsigned int count; u32 postamble_len; }; struct adreno_busy_data { Loading
drivers/gpu/msm/adreno_a6xx_preempt.c +40 −4 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include "adreno.h" Loading Loading @@ -543,13 +544,24 @@ unsigned int a6xx_preemption_pre_ibsubmit( if (context) { struct adreno_context *drawctxt = ADRENO_CONTEXT(context); struct adreno_ringbuffer *rb = drawctxt->rb; uint64_t dest = adreno_dev->preempt.scratch->gpuaddr + (rb->id * sizeof(u64)); uint64_t dest = PREEMPT_SCRATCH_ADDR(adreno_dev, rb->id); *cmds++ = cp_mem_packet(adreno_dev, CP_MEM_WRITE, 2, 2); cmds += cp_gpuaddr(adreno_dev, cmds, dest); *cmds++ = lower_32_bits(gpuaddr); *cmds++ = upper_32_bits(gpuaddr); /* Add a KMD post amble to clear the perf counters during preemption */ if (!adreno_dev->perfcounter) { u64 kmd_postamble_addr = PREEMPT_SCRATCH_ADDR(adreno_dev, KMD_POSTAMBLE_IDX); *cmds++ = cp_type7_packet(CP_SET_AMBLE, 3); *cmds++ = lower_32_bits(kmd_postamble_addr); *cmds++ = upper_32_bits(kmd_postamble_addr); *cmds++ = FIELD_PREP(GENMASK(22, 20), CP_KMD_AMBLE_TYPE) | (FIELD_PREP(GENMASK(19, 0), adreno_dev->preempt.postamble_len)); } } return (unsigned int) (cmds - cmds_orig); Loading @@ -562,8 +574,7 @@ unsigned int a6xx_preemption_post_ibsubmit(struct adreno_device *adreno_dev, struct adreno_ringbuffer *rb = adreno_dev->cur_rb; if (rb) { uint64_t dest = adreno_dev->preempt.scratch->gpuaddr + (rb->id * sizeof(u64)); uint64_t dest = PREEMPT_SCRATCH_ADDR(adreno_dev, adreno_dev->cur_rb->id); *cmds++ = cp_mem_packet(adreno_dev, CP_MEM_WRITE, 2, 2); cmds += cp_gpuaddr(adreno_dev, cmds, dest); Loading Loading @@ -721,6 +732,31 @@ int a6xx_preemption_init(struct adreno_device *adreno_dev) if (ret) return ret; /* * First 8 dwords of the preemption scratch buffer is used to store the address for CP * to save/restore VPC data. Reserve 11 dwords in the preemption scratch buffer from * index KMD_POSTAMBLE_IDX for KMD postamble pm4 packets */ if (!adreno_dev->perfcounter) { u32 *postamble = preempt->scratch->hostptr + (KMD_POSTAMBLE_IDX * sizeof(u64)); u32 count = 0; postamble[count++] = cp_type7_packet(CP_REG_RMW, 3); postamble[count++] = A6XX_RBBM_PERFCTR_SRAM_INIT_CMD; postamble[count++] = 0x0; postamble[count++] = 0x1; postamble[count++] = cp_type7_packet(CP_WAIT_REG_MEM, 6); postamble[count++] = 0x3; postamble[count++] = A6XX_RBBM_PERFCTR_SRAM_INIT_STATUS; postamble[count++] = 0x0; postamble[count++] = 0x1; postamble[count++] = 0x1; postamble[count++] = 0x0; preempt->postamble_len = count; } set_bit(ADRENO_DEVICE_PREEMPTION, &adreno_dev->priv); return 0; } Loading
drivers/gpu/msm/adreno_iommu.c +18 −0 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include <linux/slab.h> Loading Loading @@ -217,6 +218,12 @@ static unsigned int _adreno_iommu_set_pt_v2_a6xx(struct kgsl_device *device, struct adreno_device *adreno_dev = ADRENO_DEVICE(device); unsigned int *cmds = cmds_orig; /* Clear performance counters during contect switches */ if (!adreno_dev->perfcounter) { *cmds++ = cp_type4_packet(A6XX_RBBM_PERFCTR_SRAM_INIT_CMD, 1); *cmds++ = 0x1; } /* CP switches the pagetable and flushes the Caches */ *cmds++ = cp_packet(adreno_dev, CP_SMMU_TABLE_UPDATE, 4); *cmds++ = lower_32_bits(ttbr0); Loading Loading @@ -245,6 +252,17 @@ static unsigned int _adreno_iommu_set_pt_v2_a6xx(struct kgsl_device *device, *cmds++ = 0; } /* Wait for performance counter clear to finish */ if (!adreno_dev->perfcounter) { *cmds++ = cp_type7_packet(CP_WAIT_REG_MEM, 6); *cmds++ = 0x3; *cmds++ = A6XX_RBBM_PERFCTR_SRAM_INIT_STATUS; *cmds++ = 0x0; *cmds++ = 0x1; *cmds++ = 0x1; *cmds++ = 0x0; } return cmds - cmds_orig; } Loading
drivers/gpu/msm/adreno_perfcounter.c +5 −2 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include <linux/slab.h> Loading Loading @@ -72,7 +73,8 @@ void adreno_perfcounter_restore(struct adreno_device *adreno_dev) const struct adreno_perfcount_group *group; unsigned int counter, groupid; if (counters == NULL) /* Do not save/restore if not requested */ if (counters == NULL || !adreno_dev->perfcounter) return; for (groupid = 0; groupid < counters->group_count; groupid++) { Loading Loading @@ -106,7 +108,8 @@ inline void adreno_perfcounter_save(struct adreno_device *adreno_dev) const struct adreno_perfcount_group *group; unsigned int counter, groupid; if (counters == NULL) /* Do not save/restore if not requested */ if (counters == NULL || !adreno_dev->perfcounter) return; for (groupid = 0; groupid < counters->group_count; groupid++) { Loading