summaryrefslogtreecommitdiff
path: root/mali_kbase/csf/mali_kbase_csf_reset_gpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'mali_kbase/csf/mali_kbase_csf_reset_gpu.c')
-rw-r--r--mali_kbase/csf/mali_kbase_csf_reset_gpu.c140
1 files changed, 64 insertions, 76 deletions
diff --git a/mali_kbase/csf/mali_kbase_csf_reset_gpu.c b/mali_kbase/csf/mali_kbase_csf_reset_gpu.c
index 952209f..240397e 100644
--- a/mali_kbase/csf/mali_kbase_csf_reset_gpu.c
+++ b/mali_kbase/csf/mali_kbase_csf_reset_gpu.c
@@ -38,21 +38,18 @@ enum kbasep_soft_reset_status {
MCU_REINIT_FAILED
};
-static inline bool
-kbase_csf_reset_state_is_silent(enum kbase_csf_reset_gpu_state state)
+static inline bool kbase_csf_reset_state_is_silent(enum kbase_csf_reset_gpu_state state)
{
return (state == KBASE_CSF_RESET_GPU_COMMITTED_SILENT);
}
-static inline bool
-kbase_csf_reset_state_is_committed(enum kbase_csf_reset_gpu_state state)
+static inline bool kbase_csf_reset_state_is_committed(enum kbase_csf_reset_gpu_state state)
{
return (state == KBASE_CSF_RESET_GPU_COMMITTED ||
state == KBASE_CSF_RESET_GPU_COMMITTED_SILENT);
}
-static inline bool
-kbase_csf_reset_state_is_active(enum kbase_csf_reset_gpu_state state)
+static inline bool kbase_csf_reset_state_is_active(enum kbase_csf_reset_gpu_state state)
{
return (state == KBASE_CSF_RESET_GPU_HAPPENING);
}
@@ -100,8 +97,7 @@ int kbase_reset_gpu_prevent_and_wait(struct kbase_device *kbdev)
{
down_read(&kbdev->csf.reset.sem);
- if (atomic_read(&kbdev->csf.reset.state) ==
- KBASE_CSF_RESET_GPU_FAILED) {
+ if (atomic_read(&kbdev->csf.reset.state) == KBASE_CSF_RESET_GPU_FAILED) {
up_read(&kbdev->csf.reset.sem);
return -ENOMEM;
}
@@ -120,8 +116,7 @@ int kbase_reset_gpu_try_prevent(struct kbase_device *kbdev)
if (!down_read_trylock(&kbdev->csf.reset.sem))
return -EAGAIN;
- if (atomic_read(&kbdev->csf.reset.state) ==
- KBASE_CSF_RESET_GPU_FAILED) {
+ if (atomic_read(&kbdev->csf.reset.state) == KBASE_CSF_RESET_GPU_FAILED) {
up_read(&kbdev->csf.reset.sem);
return -ENOMEM;
}
@@ -166,9 +161,8 @@ void kbase_reset_gpu_assert_failed_or_prevented(struct kbase_device *kbdev)
/* Mark the reset as now happening, and synchronize with other threads that
* might be trying to access the GPU
*/
-static void kbase_csf_reset_begin_hw_access_sync(
- struct kbase_device *kbdev,
- enum kbase_csf_reset_gpu_state initial_reset_state)
+static void kbase_csf_reset_begin_hw_access_sync(struct kbase_device *kbdev,
+ enum kbase_csf_reset_gpu_state initial_reset_state)
{
unsigned long hwaccess_lock_flags;
unsigned long scheduler_spin_lock_flags;
@@ -193,15 +187,13 @@ static void kbase_csf_reset_begin_hw_access_sync(
/* Mark the reset as finished and allow others threads to once more access the
* GPU
*/
-static void kbase_csf_reset_end_hw_access(struct kbase_device *kbdev,
- int err_during_reset,
+static void kbase_csf_reset_end_hw_access(struct kbase_device *kbdev, int err_during_reset,
bool firmware_inited)
{
unsigned long hwaccess_lock_flags;
unsigned long scheduler_spin_lock_flags;
- WARN_ON(!kbase_csf_reset_state_is_active(
- atomic_read(&kbdev->csf.reset.state)));
+ WARN_ON(!kbase_csf_reset_state_is_active(atomic_read(&kbdev->csf.reset.state)));
/* Once again, we synchronize with atomic context threads accessing the
* HW, as otherwise any actions they defer could get lost
@@ -210,8 +202,7 @@ static void kbase_csf_reset_end_hw_access(struct kbase_device *kbdev,
kbase_csf_scheduler_spin_lock(kbdev, &scheduler_spin_lock_flags);
if (!err_during_reset) {
- atomic_set(&kbdev->csf.reset.state,
- KBASE_CSF_RESET_GPU_NOT_PENDING);
+ atomic_set(&kbdev->csf.reset.state, KBASE_CSF_RESET_GPU_NOT_PENDING);
} else {
dev_err(kbdev->dev, "Reset failed to complete");
atomic_set(&kbdev->csf.reset.state, KBASE_CSF_RESET_GPU_FAILED);
@@ -236,26 +227,30 @@ static void kbase_csf_debug_dump_registers(struct kbase_device *kbdev)
kbase_io_history_dump(kbdev);
dev_err(kbdev->dev, "Register state:");
- dev_err(kbdev->dev, " GPU_IRQ_RAWSTAT=0x%08x GPU_STATUS=0x%08x MCU_STATUS=0x%08x",
- kbase_reg_read(kbdev, GPU_CONTROL_REG(GPU_IRQ_RAWSTAT)),
- kbase_reg_read(kbdev, GPU_CONTROL_REG(GPU_STATUS)),
- kbase_reg_read(kbdev, GPU_CONTROL_REG(MCU_STATUS)));
+ dev_err(kbdev->dev, " GPU_IRQ_RAWSTAT=0x%08x GPU_STATUS=0x%08x MCU_STATUS=0x%08x",
+ kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(GPU_IRQ_RAWSTAT)),
+ kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(GPU_STATUS)),
+ kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(MCU_STATUS)));
dev_err(kbdev->dev,
- " JOB_IRQ_RAWSTAT=0x%08x MMU_IRQ_RAWSTAT=0x%08x GPU_FAULTSTATUS=0x%08x",
- kbase_reg_read(kbdev, JOB_CONTROL_REG(JOB_IRQ_RAWSTAT)),
- kbase_reg_read(kbdev, MMU_CONTROL_REG(MMU_IRQ_RAWSTAT)),
- kbase_reg_read(kbdev, GPU_CONTROL_REG(GPU_FAULTSTATUS)));
- dev_err(kbdev->dev, " GPU_IRQ_MASK=0x%08x JOB_IRQ_MASK=0x%08x MMU_IRQ_MASK=0x%08x",
- kbase_reg_read(kbdev, GPU_CONTROL_REG(GPU_IRQ_MASK)),
- kbase_reg_read(kbdev, JOB_CONTROL_REG(JOB_IRQ_MASK)),
- kbase_reg_read(kbdev, MMU_CONTROL_REG(MMU_IRQ_MASK)));
- dev_err(kbdev->dev, " PWR_OVERRIDE0=0x%08x PWR_OVERRIDE1=0x%08x",
- kbase_reg_read(kbdev, GPU_CONTROL_REG(PWR_OVERRIDE0)),
- kbase_reg_read(kbdev, GPU_CONTROL_REG(PWR_OVERRIDE1)));
- dev_err(kbdev->dev, " SHADER_CONFIG=0x%08x L2_MMU_CONFIG=0x%08x TILER_CONFIG=0x%08x",
- kbase_reg_read(kbdev, GPU_CONTROL_REG(SHADER_CONFIG)),
- kbase_reg_read(kbdev, GPU_CONTROL_REG(L2_MMU_CONFIG)),
- kbase_reg_read(kbdev, GPU_CONTROL_REG(TILER_CONFIG)));
+ " JOB_IRQ_RAWSTAT=0x%08x MMU_IRQ_RAWSTAT=0x%08x GPU_FAULTSTATUS=0x%08x",
+ kbase_reg_read32(kbdev, JOB_CONTROL_ENUM(JOB_IRQ_RAWSTAT)),
+ kbase_reg_read32(kbdev, MMU_CONTROL_ENUM(IRQ_RAWSTAT)),
+ kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(GPU_FAULTSTATUS)));
+ dev_err(kbdev->dev, " GPU_IRQ_MASK=0x%08x JOB_IRQ_MASK=0x%08x MMU_IRQ_MASK=0x%08x",
+ kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(GPU_IRQ_MASK)),
+ kbase_reg_read32(kbdev, JOB_CONTROL_ENUM(JOB_IRQ_MASK)),
+ kbase_reg_read32(kbdev, MMU_CONTROL_ENUM(IRQ_MASK)));
+ if (kbdev->gpu_props.gpu_id.arch_id < GPU_ID_ARCH_MAKE(14, 10, 0)) {
+ dev_err(kbdev->dev, " PWR_OVERRIDE0=0x%08x PWR_OVERRIDE1=0x%08x",
+ kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(PWR_OVERRIDE0)),
+ kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(PWR_OVERRIDE1)));
+ dev_err(kbdev->dev,
+ " SHADER_CONFIG=0x%08x L2_MMU_CONFIG=0x%08x TILER_CONFIG=0x%08x",
+ kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(SHADER_CONFIG)),
+ kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(L2_MMU_CONFIG)),
+ kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(TILER_CONFIG)));
+ }
+
}
/**
@@ -294,8 +289,7 @@ static enum kbasep_soft_reset_status kbase_csf_reset_gpu_once(struct kbase_devic
spin_lock(&kbdev->mmu_mask_change);
kbase_pm_reset_start_locked(kbdev);
- dev_dbg(kbdev->dev,
- "We're about to flush out the IRQs and their bottom halves\n");
+ dev_dbg(kbdev->dev, "We're about to flush out the IRQs and their bottom halves\n");
kbdev->irq_reset_flush = true;
/* Disable IRQ to avoid IRQ handlers to kick in after releasing the
@@ -313,13 +307,11 @@ static enum kbasep_soft_reset_status kbase_csf_reset_gpu_once(struct kbase_devic
dev_dbg(kbdev->dev, "Flush out any in-flight work items\n");
kbase_flush_mmu_wqs(kbdev);
- dev_dbg(kbdev->dev,
- "The flush has completed so reset the active indicator\n");
+ dev_dbg(kbdev->dev, "The flush has completed so reset the active indicator\n");
kbdev->irq_reset_flush = false;
if (!silent)
- dev_err(kbdev->dev, "Resetting GPU (allowing up to %d ms)",
- RESET_TIMEOUT);
+ dev_err(kbdev->dev, "Resetting GPU (allowing up to %d ms)", RESET_TIMEOUT);
/* Output the state of some interesting registers to help in the
* debugging of GPU resets, and dump the firmware trace buffer
@@ -330,9 +322,11 @@ static enum kbasep_soft_reset_status kbase_csf_reset_gpu_once(struct kbase_devic
kbase_csf_firmware_log_dump_buffer(kbdev);
}
- spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
- kbase_ipa_control_handle_gpu_reset_pre(kbdev);
- spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
+ {
+ spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
+ kbase_ipa_control_handle_gpu_reset_pre(kbdev);
+ spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
+ }
/* Tell hardware counters a reset is about to occur.
* If the backend is in an unrecoverable error state (e.g. due to
@@ -353,7 +347,9 @@ static enum kbasep_soft_reset_status kbase_csf_reset_gpu_once(struct kbase_devic
mutex_lock(&kbdev->mmu_hw_mutex);
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
kbase_ctx_sched_restore_all_as(kbdev);
- kbase_ipa_control_handle_gpu_reset_post(kbdev);
+ {
+ kbase_ipa_control_handle_gpu_reset_post(kbdev);
+ }
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
mutex_unlock(&kbdev->mmu_hw_mutex);
@@ -443,16 +439,14 @@ err:
static void kbase_csf_reset_gpu_worker(struct work_struct *data)
{
- struct kbase_device *kbdev = container_of(data, struct kbase_device,
- csf.reset.work);
+ struct kbase_device *kbdev = container_of(data, struct kbase_device, csf.reset.work);
bool gpu_sleep_mode_active = false;
bool firmware_inited;
unsigned long flags;
int err = 0;
const enum kbase_csf_reset_gpu_state initial_reset_state =
atomic_read(&kbdev->csf.reset.state);
- const bool silent =
- kbase_csf_reset_state_is_silent(initial_reset_state);
+ const bool silent = kbase_csf_reset_state_is_silent(initial_reset_state);
/* Ensure any threads (e.g. executing the CSF scheduler) have finished
* using the HW
@@ -482,8 +476,8 @@ static void kbase_csf_reset_gpu_worker(struct work_struct *data)
err = kbase_csf_reset_gpu_now(kbdev, firmware_inited, silent);
#endif
- } else if (!kbase_pm_context_active_handle_suspend(kbdev,
- KBASE_PM_SUSPEND_HANDLER_DONT_REACTIVATE)) {
+ } else if (!kbase_pm_context_active_handle_suspend(
+ kbdev, KBASE_PM_SUSPEND_HANDLER_DONT_REACTIVATE)) {
err = kbase_csf_reset_gpu_now(kbdev, firmware_inited, silent);
kbase_pm_context_idle(kbdev);
}
@@ -497,22 +491,22 @@ static void kbase_csf_reset_gpu_worker(struct work_struct *data)
bool kbase_prepare_to_reset_gpu(struct kbase_device *kbdev, unsigned int flags)
{
if (flags & RESET_FLAGS_HWC_UNRECOVERABLE_ERROR)
- kbase_hwcnt_backend_csf_on_unrecoverable_error(
- &kbdev->hwcnt_gpu_iface);
+ kbase_hwcnt_backend_csf_on_unrecoverable_error(&kbdev->hwcnt_gpu_iface);
- if (atomic_cmpxchg(&kbdev->csf.reset.state,
- KBASE_CSF_RESET_GPU_NOT_PENDING,
- KBASE_CSF_RESET_GPU_PREPARED) !=
- KBASE_CSF_RESET_GPU_NOT_PENDING)
+ if (atomic_cmpxchg(&kbdev->csf.reset.state, KBASE_CSF_RESET_GPU_NOT_PENDING,
+ KBASE_CSF_RESET_GPU_PREPARED) != KBASE_CSF_RESET_GPU_NOT_PENDING)
/* Some other thread is already resetting the GPU */
return false;
+ /* Issue the wake up of threads waiting for PM state transition.
+ * They might want to exit the wait since GPU reset has been triggered.
+ */
+ wake_up(&kbdev->pm.backend.gpu_in_desired_state_wait);
return true;
}
KBASE_EXPORT_TEST_API(kbase_prepare_to_reset_gpu);
-bool kbase_prepare_to_reset_gpu_locked(struct kbase_device *kbdev,
- unsigned int flags)
+bool kbase_prepare_to_reset_gpu_locked(struct kbase_device *kbdev, unsigned int flags)
{
lockdep_assert_held(&kbdev->hwaccess_lock);
@@ -524,8 +518,7 @@ void kbase_reset_gpu(struct kbase_device *kbdev)
/* Note this is a WARN/atomic_set because it is a software issue for
* a race to be occurring here
*/
- if (WARN_ON(atomic_read(&kbdev->csf.reset.state) !=
- KBASE_RESET_GPU_PREPARED))
+ if (WARN_ON(atomic_read(&kbdev->csf.reset.state) != KBASE_RESET_GPU_PREPARED))
return;
atomic_set(&kbdev->csf.reset.state, KBASE_CSF_RESET_GPU_COMMITTED);
@@ -546,10 +539,9 @@ void kbase_reset_gpu_locked(struct kbase_device *kbdev)
int kbase_reset_gpu_silent(struct kbase_device *kbdev)
{
- if (atomic_cmpxchg(&kbdev->csf.reset.state,
- KBASE_CSF_RESET_GPU_NOT_PENDING,
- KBASE_CSF_RESET_GPU_COMMITTED_SILENT) !=
- KBASE_CSF_RESET_GPU_NOT_PENDING) {
+ if (atomic_cmpxchg(&kbdev->csf.reset.state, KBASE_CSF_RESET_GPU_NOT_PENDING,
+ KBASE_CSF_RESET_GPU_COMMITTED_SILENT) !=
+ KBASE_CSF_RESET_GPU_NOT_PENDING) {
/* Some other thread is already resetting the GPU */
return -EAGAIN;
}
@@ -564,8 +556,7 @@ KBASE_EXPORT_TEST_API(kbase_reset_gpu_silent);
bool kbase_reset_gpu_is_active(struct kbase_device *kbdev)
{
- enum kbase_csf_reset_gpu_state reset_state =
- atomic_read(&kbdev->csf.reset.state);
+ enum kbase_csf_reset_gpu_state reset_state = atomic_read(&kbdev->csf.reset.state);
/* For CSF, the reset is considered active only when the reset worker
* is actually executing and other threads would have to wait for it to
@@ -600,10 +591,8 @@ int kbase_reset_gpu_wait(struct kbase_device *kbdev)
remaining = wait_event_timeout(
kbdev->csf.reset.wait,
- (atomic_read(&kbdev->csf.reset.state) ==
- KBASE_CSF_RESET_GPU_NOT_PENDING) ||
- (atomic_read(&kbdev->csf.reset.state) ==
- KBASE_CSF_RESET_GPU_FAILED),
+ (atomic_read(&kbdev->csf.reset.state) == KBASE_CSF_RESET_GPU_NOT_PENDING) ||
+ (atomic_read(&kbdev->csf.reset.state) == KBASE_CSF_RESET_GPU_FAILED),
wait_timeout);
if (!remaining) {
@@ -611,8 +600,7 @@ int kbase_reset_gpu_wait(struct kbase_device *kbdev)
return -ETIMEDOUT;
- } else if (atomic_read(&kbdev->csf.reset.state) ==
- KBASE_CSF_RESET_GPU_FAILED) {
+ } else if (atomic_read(&kbdev->csf.reset.state) == KBASE_CSF_RESET_GPU_FAILED) {
return -ENOMEM;
}