Loading drivers/gpu/msm/adreno-gpulist.h +1 −0 Original line number Diff line number Diff line Loading @@ -971,6 +971,7 @@ static const struct adreno_a6xx_core adreno_gpu_core_a619_variant = { .vbif_count = ARRAY_SIZE(a615_gbif_regs), .hang_detect_cycles = 0x3fffff, .protected_regs = a630_protected_regs, .gx_cpr_toggle = true, }; static const struct adreno_reglist a620_hwcg_regs[] = { Loading drivers/gpu/msm/adreno_a6xx.c +49 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. */ #include <linux/io.h> #include <linux/of.h> #include <linux/of_fdt.h> #include <linux/soc/qcom/llcc-qcom.h> Loading Loading @@ -1089,6 +1090,51 @@ static int64_t a6xx_read_throttling_counters(struct adreno_device *adreno_dev) return adj; } #define GPU_CPR_FSM_CTL_OFFSET 0x4 void a6xx_gx_cpr_toggle(struct kgsl_device *device) { struct adreno_device *adreno_dev = ADRENO_DEVICE(device); const struct adreno_a6xx_core *a6xx_core = to_a6xx_core(adreno_dev); static void __iomem *gx_cpr_virt; struct resource *res; u32 val = 0; if (!a6xx_core->gx_cpr_toggle) return; if (!gx_cpr_virt) { res = platform_get_resource_byname(device->pdev, IORESOURCE_MEM, "gx_cpr"); if (res == NULL) return; gx_cpr_virt = devm_ioremap_resource(&device->pdev->dev, res); if (!gx_cpr_virt) { dev_err(device->dev, "Failed to map GX CPR\n"); return; } } /* * Toggle(disable -> enable) closed loop functionality to recover * CPR measurements stall happened under certain conditions. */ val = readl_relaxed(gx_cpr_virt + GPU_CPR_FSM_CTL_OFFSET); /* Make sure memory is updated before access */ rmb(); writel_relaxed(val & 0xfffffff0, gx_cpr_virt + GPU_CPR_FSM_CTL_OFFSET); /* make sure register write committed */ wmb(); /* Wait for small time before we enable GX CPR */ udelay(5); writel_relaxed(val | 0x00000001, gx_cpr_virt + GPU_CPR_FSM_CTL_OFFSET); /* make sure register write committed */ wmb(); } /** * a6xx_reset() - Helper function to reset the GPU Loading Loading @@ -1122,6 +1168,9 @@ static int a6xx_reset(struct kgsl_device *device, int fault) kgsl_pwrctrl_change_state(device, KGSL_STATE_ACTIVE); /* Toggle GX CPR on demand */ a6xx_gx_cpr_toggle(device); /* * If active_cnt is zero, there is no need to keep the GPU active. So, * we should transition to SLUMBER. Loading drivers/gpu/msm/adreno_a6xx.h +2 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,8 @@ struct adreno_a6xx_core { const struct a6xx_protected_regs *protected_regs; /** @disable_tseskip: True if TSESkip logic is disabled */ bool disable_tseskip; /** @gx_cpr_toggle: True to toggle GX CPR FSM to avoid CPR stalls */ bool gx_cpr_toggle; /** @highest_bank_bit: The bit of the highest DDR bank */ u32 highest_bank_bit; }; Loading Loading
drivers/gpu/msm/adreno-gpulist.h +1 −0 Original line number Diff line number Diff line Loading @@ -971,6 +971,7 @@ static const struct adreno_a6xx_core adreno_gpu_core_a619_variant = { .vbif_count = ARRAY_SIZE(a615_gbif_regs), .hang_detect_cycles = 0x3fffff, .protected_regs = a630_protected_regs, .gx_cpr_toggle = true, }; static const struct adreno_reglist a620_hwcg_regs[] = { Loading
drivers/gpu/msm/adreno_a6xx.c +49 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. */ #include <linux/io.h> #include <linux/of.h> #include <linux/of_fdt.h> #include <linux/soc/qcom/llcc-qcom.h> Loading Loading @@ -1089,6 +1090,51 @@ static int64_t a6xx_read_throttling_counters(struct adreno_device *adreno_dev) return adj; } #define GPU_CPR_FSM_CTL_OFFSET 0x4 void a6xx_gx_cpr_toggle(struct kgsl_device *device) { struct adreno_device *adreno_dev = ADRENO_DEVICE(device); const struct adreno_a6xx_core *a6xx_core = to_a6xx_core(adreno_dev); static void __iomem *gx_cpr_virt; struct resource *res; u32 val = 0; if (!a6xx_core->gx_cpr_toggle) return; if (!gx_cpr_virt) { res = platform_get_resource_byname(device->pdev, IORESOURCE_MEM, "gx_cpr"); if (res == NULL) return; gx_cpr_virt = devm_ioremap_resource(&device->pdev->dev, res); if (!gx_cpr_virt) { dev_err(device->dev, "Failed to map GX CPR\n"); return; } } /* * Toggle(disable -> enable) closed loop functionality to recover * CPR measurements stall happened under certain conditions. */ val = readl_relaxed(gx_cpr_virt + GPU_CPR_FSM_CTL_OFFSET); /* Make sure memory is updated before access */ rmb(); writel_relaxed(val & 0xfffffff0, gx_cpr_virt + GPU_CPR_FSM_CTL_OFFSET); /* make sure register write committed */ wmb(); /* Wait for small time before we enable GX CPR */ udelay(5); writel_relaxed(val | 0x00000001, gx_cpr_virt + GPU_CPR_FSM_CTL_OFFSET); /* make sure register write committed */ wmb(); } /** * a6xx_reset() - Helper function to reset the GPU Loading Loading @@ -1122,6 +1168,9 @@ static int a6xx_reset(struct kgsl_device *device, int fault) kgsl_pwrctrl_change_state(device, KGSL_STATE_ACTIVE); /* Toggle GX CPR on demand */ a6xx_gx_cpr_toggle(device); /* * If active_cnt is zero, there is no need to keep the GPU active. So, * we should transition to SLUMBER. Loading
drivers/gpu/msm/adreno_a6xx.h +2 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,8 @@ struct adreno_a6xx_core { const struct a6xx_protected_regs *protected_regs; /** @disable_tseskip: True if TSESkip logic is disabled */ bool disable_tseskip; /** @gx_cpr_toggle: True to toggle GX CPR FSM to avoid CPR stalls */ bool gx_cpr_toggle; /** @highest_bank_bit: The bit of the highest DDR bank */ u32 highest_bank_bit; }; Loading