diff --git a/drivers/gpu/msm/adreno-gpulist.h b/drivers/gpu/msm/adreno-gpulist.h index 606837dd690a..544f80d98f8f 100644 --- a/drivers/gpu/msm/adreno-gpulist.h +++ b/drivers/gpu/msm/adreno-gpulist.h @@ -28,7 +28,6 @@ static const struct adreno_a3xx_core adreno_gpu_core_a306 = { .gpudev = &adreno_a3xx_gpudev, .gmem_base = 0, .gmem_size = SZ_128K, - .busy_mask = 0x7ffffffe, .bus_width = 0, .snapshot_size = 600 * SZ_1K, }, @@ -51,7 +50,6 @@ static const struct adreno_a3xx_core adreno_gpu_core_a306a = { .gpudev = &adreno_a3xx_gpudev, .gmem_base = 0, .gmem_size = SZ_128K, - .busy_mask = 0x7ffffffe, .bus_width = 16, .snapshot_size = 600 * SZ_1K, }, @@ -72,7 +70,6 @@ static const struct adreno_a3xx_core adreno_gpu_core_a304 = { .gpudev = &adreno_a3xx_gpudev, .gmem_base = 0, .gmem_size = (SZ_64K + SZ_32K), - .busy_mask = 0x7ffffffe, .bus_width = 0, .snapshot_size = 600 * SZ_1K, }, @@ -197,7 +194,6 @@ static const struct adreno_a5xx_core adreno_gpu_core_a530v2 = { .gpudev = &adreno_a5xx_gpudev, .gmem_base = 0x100000, .gmem_size = SZ_1M, - .busy_mask = 0xfffffffe, .bus_width = 32, .snapshot_size = SZ_1M, }, @@ -224,7 +220,6 @@ static const struct adreno_a5xx_core adreno_gpu_core_a530v3 = { .gpudev = &adreno_a5xx_gpudev, .gmem_base = 0x100000, .gmem_size = SZ_1M, - .busy_mask = 0xfffffffe, .bus_width = 32, .snapshot_size = SZ_1M, }, @@ -291,7 +286,6 @@ static const struct adreno_a5xx_core adreno_gpu_core_a505 = { .gpudev = &adreno_a5xx_gpudev, .gmem_base = 0x100000, .gmem_size = (SZ_128K + SZ_8K), - .busy_mask = 0xfffffffe, .bus_width = 16, .snapshot_size = SZ_1M, }, @@ -311,7 +305,6 @@ static const struct adreno_a5xx_core adreno_gpu_core_a506 = { .gpudev = &adreno_a5xx_gpudev, .gmem_base = 0x100000, .gmem_size = (SZ_128K + SZ_8K), - .busy_mask = 0xfffffffe, .bus_width = 16, .snapshot_size = SZ_1M, }, @@ -390,7 +383,6 @@ static const struct adreno_a5xx_core adreno_gpu_core_a510 = { .gpudev = &adreno_a5xx_gpudev, .gmem_base = 0x100000, .gmem_size = SZ_256K, - .busy_mask = 0xfffffffe, .bus_width = 16, .snapshot_size = SZ_1M, }, @@ -516,7 +508,6 @@ static const struct adreno_a5xx_core adreno_gpu_core_a540v2 = { .gpudev = &adreno_a5xx_gpudev, .gmem_base = 0x100000, .gmem_size = SZ_1M, - .busy_mask = 0xfffffffe, .bus_width = 32, .snapshot_size = SZ_1M, }, @@ -600,7 +591,6 @@ static const struct adreno_a5xx_core adreno_gpu_core_a512 = { .gpudev = &adreno_a5xx_gpudev, .gmem_base = 0x100000, .gmem_size = (SZ_256K + SZ_16K), - .busy_mask = 0xfffffffe, .bus_width = 32, .snapshot_size = SZ_1M, }, @@ -620,7 +610,6 @@ static const struct adreno_a5xx_core adreno_gpu_core_a508 = { .gpudev = &adreno_a5xx_gpudev, .gmem_base = 0x100000, .gmem_size = (SZ_128K + SZ_8K), - .busy_mask = 0xfffffffe, .bus_width = 32, .snapshot_size = SZ_1M, }, @@ -796,7 +785,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a630v2 = { .gpudev = &adreno_a6xx_gpudev, .gmem_base = 0x100000, .gmem_size = SZ_1M, - .busy_mask = 0xfffffffe, .bus_width = 32, .snapshot_size = SZ_1M, }, @@ -897,7 +885,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a615 = { .gpudev = &adreno_a6xx_gpudev, .gmem_base = 0x100000, .gmem_size = SZ_512K, - .busy_mask = 0xfffffffe, .bus_width = 32, .snapshot_size = 600 * SZ_1K, }, @@ -926,7 +913,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a618 = { .gpudev = &adreno_a6xx_gpudev, .gmem_base = 0x100000, .gmem_size = SZ_512K, - .busy_mask = 0xfffffffe, .bus_width = 32, .snapshot_size = SZ_1M, }, @@ -1056,7 +1042,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a620 = { .gpudev = &adreno_a6xx_gpudev, .gmem_base = 0, .gmem_size = SZ_512K, - .busy_mask = 0xfffffffe, .bus_width = 32, .snapshot_size = 2 * SZ_1M, }, @@ -1148,7 +1133,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a640 = { .gpudev = &adreno_a6xx_gpudev, .gmem_base = 0x100000, .gmem_size = SZ_1M, //Verified 1MB - .busy_mask = 0xfffffffe, .bus_width = 32, .snapshot_size = 2 * SZ_1M, }, @@ -1230,7 +1214,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a650 = { .gpudev = &adreno_a6xx_gpudev, .gmem_base = 0, .gmem_size = SZ_1M + SZ_128K, /* verified 1152kB */ - .busy_mask = 0xfffffffe, .bus_width = 32, .snapshot_size = 2 * SZ_1M, }, @@ -1261,7 +1244,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a650v2 = { .gpudev = &adreno_a6xx_gpudev, .gmem_base = 0, .gmem_size = SZ_1M + SZ_128K, /* verified 1152kB */ - .busy_mask = 0xfffffffe, .bus_width = 32, .snapshot_size = 2 * SZ_1M, }, @@ -1289,7 +1271,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a680 = { .gpudev = &adreno_a6xx_gpudev, .gmem_base = 0x100000, .gmem_size = SZ_2M, - .busy_mask = 0xfffffffe, .bus_width = 32, .snapshot_size = SZ_1M, }, @@ -1368,7 +1349,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a612 = { .gpudev = &adreno_a6xx_gpudev, .gmem_base = 0x100000, .gmem_size = (SZ_128K + SZ_4K), - .busy_mask = 0xfffffffe, .bus_width = 32, .snapshot_size = SZ_1M, }, @@ -1395,7 +1375,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a616 = { .gpudev = &adreno_a6xx_gpudev, .gmem_base = 0x100000, .gmem_size = SZ_512K, - .busy_mask = 0xfffffffe, .bus_width = 32, .snapshot_size = SZ_1M, }, @@ -1423,7 +1402,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a610 = { .gpudev = &adreno_a6xx_gpudev, .gmem_base = 0x100000, .gmem_size = (SZ_128K + SZ_4K), - .busy_mask = 0xfffffffe, .bus_width = 32, }, .prim_fifo_threshold = 0x00080000, @@ -1537,7 +1515,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a660 = { .gpudev = &adreno_a6xx_gpudev, .gmem_base = 0, .gmem_size = SZ_1M + SZ_512K, - .busy_mask = 0xfffffffe, .bus_width = 32, .snapshot_size = SZ_1M, }, diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 3e5d2226b17e..06c9b3b65fcd 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -2740,7 +2740,7 @@ static int adreno_setproperty(struct kgsl_device_private *dev_priv, * * Returns true if interrupts are pending from device else 0. */ -inline unsigned int adreno_irq_pending(struct adreno_device *adreno_dev) +bool adreno_irq_pending(struct adreno_device *adreno_dev) { unsigned int status; @@ -2755,48 +2755,9 @@ inline unsigned int adreno_irq_pending(struct adreno_device *adreno_dev) */ if ((status & adreno_dev->irq_mask) || atomic_read(&adreno_dev->pending_irq_refcnt)) - return 1; - else - return 0; -} + return true; - -/** - * adreno_hw_isidle() - Check if the GPU core is idle - * @adreno_dev: Pointer to the Adreno device structure for the GPU - * - * Return true if the RBBM status register for the GPU type indicates that the - * hardware is idle - */ -bool adreno_hw_isidle(struct adreno_device *adreno_dev) -{ - const struct adreno_gpu_core *gpucore = adreno_dev->gpucore; - unsigned int reg_rbbm_status; - struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); - - /* if hw driver implements idle check - use it */ - if (gpudev->hw_isidle) - return gpudev->hw_isidle(adreno_dev); - - if (adreno_is_a540(adreno_dev)) - /** - * Due to CRC idle throttling GPU - * idle hysteresys can take up to - * 3usec for expire - account for it - */ - udelay(5); - - adreno_readreg(adreno_dev, ADRENO_REG_RBBM_STATUS, - ®_rbbm_status); - - if (reg_rbbm_status & gpucore->busy_mask) - return false; - - /* Don't consider ourselves idle if there is an IRQ pending */ - if (adreno_irq_pending(adreno_dev)) - return false; - - return true; + return false; } /* @@ -2884,20 +2845,13 @@ static int adreno_soft_reset(struct kgsl_device *device) return ret; } -/* - * adreno_isidle() - return true if the GPU hardware is idle - * @device: Pointer to the KGSL device structure for the GPU - * - * Return true if the GPU hardware is idle and there are no commands pending in - * the ringbuffer - */ -bool adreno_isidle(struct kgsl_device *device) +static bool adreno_isidle(struct adreno_device *adreno_dev) { - struct adreno_device *adreno_dev = ADRENO_DEVICE(device); + struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); struct adreno_ringbuffer *rb; int i; - if (!kgsl_state_is_awake(device)) + if (!kgsl_state_is_awake(KGSL_DEVICE(adreno_dev))) return true; /* @@ -2916,7 +2870,7 @@ bool adreno_isidle(struct kgsl_device *device) return false; } - return adreno_hw_isidle(adreno_dev); + return gpudev->hw_isidle(adreno_dev); } /* Print some key registers if a spin-for-idle times out */ @@ -2977,7 +2931,7 @@ int adreno_spin_idle(struct adreno_device *adreno_dev, unsigned int timeout) if (adreno_gpu_fault(adreno_dev) != 0) return -EDEADLK; - if (adreno_isidle(KGSL_DEVICE(adreno_dev))) + if (adreno_isidle(adreno_dev)) return 0; } while (time_before(jiffies, wait)); @@ -2990,7 +2944,7 @@ int adreno_spin_idle(struct adreno_device *adreno_dev, unsigned int timeout) if (adreno_gpu_fault(adreno_dev) != 0) return -EDEADLK; - if (adreno_isidle(KGSL_DEVICE(adreno_dev))) + if (adreno_isidle(adreno_dev)) return 0; return -ETIMEDOUT; @@ -3018,7 +2972,7 @@ int adreno_idle(struct kgsl_device *device) return -EDEADLK; /* Check if we are already idle before idling dispatcher */ - if (adreno_isidle(device)) + if (adreno_isidle(adreno_dev)) return 0; /* * Wait for dispatcher to finish completing commands @@ -3715,7 +3669,7 @@ static bool adreno_is_hw_collapsible(struct kgsl_device *device) device->pwrctrl.ctrl_flags) return false; - return adreno_isidle(device) && (gpudev->is_sptp_idle ? + return adreno_isidle(adreno_dev) && (gpudev->is_sptp_idle ? gpudev->is_sptp_idle(adreno_dev) : true); } @@ -3801,7 +3755,6 @@ static const struct kgsl_functable adreno_functable = { .regread = adreno_regread, .regwrite = adreno_regwrite, .idle = adreno_idle, - .isidle = adreno_isidle, .suspend_context = adreno_suspend_context, .first_open = adreno_first_open, .start = adreno_start, diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h index e81d9087b987..9f442a513376 100644 --- a/drivers/gpu/msm/adreno.h +++ b/drivers/gpu/msm/adreno.h @@ -340,7 +340,6 @@ struct adreno_reglist { * @gpudev: Pointer to the GPU family specific functions for this core * @gmem_base: Base address of binning memory (GMEM/OCMEM) * @gmem_size: Amount of binning memory (GMEM/OCMEM) to reserve for the core - * @busy_mask: mask to check if GPU is busy in RBBM_STATUS * @bus_width: Bytes transferred in 1 cycle */ struct adreno_gpu_core { @@ -350,7 +349,6 @@ struct adreno_gpu_core { struct adreno_gpudev *gpudev; unsigned long gmem_base; size_t gmem_size; - unsigned int busy_mask; u32 bus_width; /** @snapshot_size: Size of the static snapshot region in bytes */ u32 snapshot_size; @@ -889,7 +887,6 @@ int adreno_switch_to_unsecure_mode(struct adreno_device *adreno_dev, void adreno_spin_idle_debug(struct adreno_device *adreno_dev, const char *str); int adreno_spin_idle(struct adreno_device *device, unsigned int timeout); int adreno_idle(struct kgsl_device *device); -bool adreno_isidle(struct kgsl_device *device); int adreno_set_constraint(struct kgsl_device *device, struct kgsl_context *context, @@ -905,8 +902,6 @@ void adreno_fault_skipcmd_detached(struct adreno_device *adreno_dev, struct adreno_context *drawctxt, struct kgsl_drawobj *drawobj); -bool adreno_hw_isidle(struct adreno_device *adreno_dev); - void adreno_fault_detect_start(struct adreno_device *adreno_dev); void adreno_fault_detect_stop(struct adreno_device *adreno_dev); @@ -946,6 +941,13 @@ void adreno_rscc_regread(struct adreno_device *adreno_dev, void adreno_isense_regread(struct adreno_device *adreno_dev, unsigned int offsetwords, unsigned int *value); +/** + * adreno_irq_pending - Return true if an interrupt is pending + * @adreno_dev: An Adreno GPU device handle + * + * Returns: true if interrupts are pending on the device + */ +bool adreno_irq_pending(struct adreno_device *adreno_dev); #define ADRENO_TARGET(_name, _id) \ static inline int adreno_is_##_name(struct adreno_device *adreno_dev) \ diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c index 150af9a93ff5..a36d2b74e598 100644 --- a/drivers/gpu/msm/adreno_a3xx.c +++ b/drivers/gpu/msm/adreno_a3xx.c @@ -1381,6 +1381,19 @@ static irqreturn_t a3xx_irq_handler(struct adreno_device *adreno_dev) return ret; } +static bool a3xx_hw_isidle(struct adreno_device *adreno_dev) +{ + struct kgsl_device *device = KGSL_DEVICE(adreno_dev); + u32 status; + + kgsl_regread(device, A3XX_RBBM_STATUS, &status); + + if (status & 0x7ffffffe) + return false; + + return adreno_irq_pending(adreno_dev) ? false : true; +} + struct adreno_gpudev adreno_a3xx_gpudev = { .reg_offsets = a3xx_register_offsets, .ft_perf_counters = a3xx_ft_perf_counters, @@ -1399,4 +1412,5 @@ struct adreno_gpudev adreno_a3xx_gpudev = { #endif .clk_set_options = a3xx_clk_set_options, .read_alwayson = a3xx_read_alwayson, + .hw_isidle = a3xx_hw_isidle, }; diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c index 4a8d6efed37c..c2d7a68f77a9 100644 --- a/drivers/gpu/msm/adreno_a5xx.c +++ b/drivers/gpu/msm/adreno_a5xx.c @@ -2752,6 +2752,26 @@ static irqreturn_t a5xx_irq_handler(struct adreno_device *adreno_dev) return ret; } +static bool a5xx_hw_isidle(struct adreno_device *adreno_dev) +{ + struct kgsl_device *device = KGSL_DEVICE(adreno_dev); + u32 status; + + /* + * Due to CRC idle throttling the GPU idle hysteresis on a540 can take + * up to 5uS to expire + */ + if (adreno_is_a540(adreno_dev)) + udelay(5); + + kgsl_regread(device, A5XX_RBBM_STATUS, &status); + + if (status & 0xfffffffe) + return false; + + return adreno_irq_pending(adreno_dev) ? false : true; +} + #ifdef CONFIG_QCOM_KGSL_CORESIGHT static struct adreno_coresight_register a5xx_coresight_registers[] = { { A5XX_RBBM_CFG_DBGBUS_SEL_A }, @@ -2978,4 +2998,5 @@ struct adreno_gpudev adreno_a5xx_gpudev = { .preemption_schedule = a5xx_preemption_schedule, .clk_set_options = a5xx_clk_set_options, .read_alwayson = a5xx_read_alwayson, + .hw_isidle = a5xx_hw_isidle, }; diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c index 0e639aaa7a85..9135f78ba679 100644 --- a/drivers/gpu/msm/adreno_a6xx.c +++ b/drivers/gpu/msm/adreno_a6xx.c @@ -405,10 +405,6 @@ static void a6xx_start(struct adreno_device *adreno_dev) adreno_dev->irq_mask = A6XX_INT_MASK; - /* runtime adjust callbacks based on feature sets */ - if (!gmu_core_isenabled(device)) - /* Legacy idle management if gmu is disabled */ - ADRENO_GPU_DEVICE(adreno_dev)->hw_isidle = NULL; /* enable hardware clockgating */ a6xx_hwcg_set(adreno_dev, true); @@ -986,17 +982,24 @@ static void a6xx_gpu_keepalive(struct adreno_device *adreno_dev, ADRENO_REG_GMU_PWR_COL_KEEPALIVE, state); } -/* Bitmask for GPU idle status check */ -#define GPUBUSYIGNAHB BIT(23) static bool a6xx_hw_isidle(struct adreno_device *adreno_dev) { + struct kgsl_device *device = KGSL_DEVICE(adreno_dev); unsigned int reg; - gmu_core_regread(KGSL_DEVICE(adreno_dev), - A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS, ®); - if (reg & GPUBUSYIGNAHB) - return false; - return true; + /* Non GMU devices monitor the RBBM status */ + if (!gmu_core_isenabled(device)) { + kgsl_regread(device, A6XX_RBBM_STATUS, ®); + if (reg & 0xfffffffe) + return false; + + return adreno_irq_pending(adreno_dev) ? false : true; + } + + gmu_core_regread(device, A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS, ®); + + /* Bit 23 is GPUBUSYIGNAHB */ + return (reg & BIT(23)) ? false : true; } /* @@ -2585,7 +2588,7 @@ struct adreno_gpudev adreno_a6xx_gpudev = { .read_throttling_counters = a6xx_read_throttling_counters, .microcode_read = a6xx_microcode_read, .gpu_keepalive = a6xx_gpu_keepalive, - .hw_isidle = a6xx_hw_isidle, /* Replaced by NULL if GMU is disabled */ + .hw_isidle = a6xx_hw_isidle, .iommu_fault_block = a6xx_iommu_fault_block, .reset = a6xx_reset, .preemption_pre_ibsubmit = a6xx_preemption_pre_ibsubmit, diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c index 55f2a54355c7..cf5176404627 100644 --- a/drivers/gpu/msm/adreno_dispatch.c +++ b/drivers/gpu/msm/adreno_dispatch.c @@ -175,8 +175,8 @@ static void fault_detect_read(struct adreno_device *adreno_dev) */ static inline bool _isidle(struct adreno_device *adreno_dev) { - const struct adreno_gpu_core *gpucore = adreno_dev->gpucore; unsigned int reg_rbbm_status; + u32 mask; if (!kgsl_state_is_awake(KGSL_DEVICE(adreno_dev))) goto ret; @@ -187,7 +187,12 @@ static inline bool _isidle(struct adreno_device *adreno_dev) /* only check rbbm status to determine if GPU is idle */ adreno_readreg(adreno_dev, ADRENO_REG_RBBM_STATUS, ®_rbbm_status); - if (reg_rbbm_status & gpucore->busy_mask) + if (adreno_is_a3xx(adreno_dev)) + mask = 0x7ffffffe; + else + mask = 0xfffffffe; + + if (reg_rbbm_status & mask) return false; ret: diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h index 5d6c25383fb1..9e45d8455f58 100644 --- a/drivers/gpu/msm/kgsl_device.h +++ b/drivers/gpu/msm/kgsl_device.h @@ -97,7 +97,6 @@ struct kgsl_functable { void (*regwrite)(struct kgsl_device *device, unsigned int offsetwords, unsigned int value); int (*idle)(struct kgsl_device *device); - bool (*isidle)(struct kgsl_device *device); int (*suspend_context)(struct kgsl_device *device); int (*first_open)(struct kgsl_device *device); int (*last_close)(struct kgsl_device *device);