mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-24 10:11:26 +03:00
video: tegra: host: nvdla: fix fw reloading
- Engine hang like issue causes device power reference count to go out of sync - So forcefully put device into idle before firmware reload - Reset device after firmware reload to make sure engine in clean state Jira DLA-3147 Change-Id: I22c825065cb9157c85b8fd5ad4fcaac764383a9f Signed-off-by: Shridhar Rasal <srasal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2329686 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Ken Adams <kadams@nvidia.com> Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
Laxman Dewangan
parent
e793ebb2f8
commit
e5d321cc10
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* NVDLA debug utils
|
||||
*
|
||||
* Copyright (c) 2016 - 2018, NVIDIA Corporation. All rights reserved.
|
||||
* Copyright (c) 2016 - 2020, NVIDIA Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -26,9 +26,11 @@
|
||||
#include <linux/uaccess.h>
|
||||
#include <soc/tegra/fuse.h>
|
||||
#include <soc/tegra/chip-id.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "nvdla/nvdla.h"
|
||||
#include "nvdla_debug.h"
|
||||
#include "nvhost_acm.h"
|
||||
|
||||
/*
|
||||
* Header in ring buffer consist (start, end) two uint32_t values.
|
||||
@@ -494,6 +496,8 @@ static ssize_t debug_dla_fw_reload_set(struct file *file,
|
||||
struct nvdla_device *nvdla_dev;
|
||||
struct platform_device *pdev;
|
||||
long val;
|
||||
int ref_cnt;
|
||||
unsigned long end_jiffies;
|
||||
|
||||
if (!p)
|
||||
return -EFAULT;
|
||||
@@ -511,12 +515,32 @@ static ssize_t debug_dla_fw_reload_set(struct file *file,
|
||||
if (!val)
|
||||
return count; /* "0" does nothing */
|
||||
|
||||
nvdla_dbg_info(pdev, "firmware reload requested.\n");
|
||||
|
||||
/* check current power ref count and make forced idle to
|
||||
* suspend.
|
||||
*/
|
||||
ref_cnt = atomic_read(&pdev->dev.power.usage_count);
|
||||
nvhost_module_idle_mult(pdev, ref_cnt);
|
||||
|
||||
/* check and wait until module is idle (with a timeout) */
|
||||
end_jiffies = jiffies + msecs_to_jiffies(2000);
|
||||
do {
|
||||
msleep(1);
|
||||
ref_cnt = atomic_read(&pdev->dev.power.usage_count);
|
||||
} while (ref_cnt != 0 && time_before(jiffies, end_jiffies));
|
||||
|
||||
if (ref_cnt != 0)
|
||||
return -EBUSY;
|
||||
|
||||
nvdla_dbg_info(pdev, "firmware reload requesting..\n");
|
||||
|
||||
err = flcn_reload_fw(pdev);
|
||||
if (err)
|
||||
return err; /* propagate firmware reload errors */
|
||||
|
||||
/* make sure device in clean state by reset */
|
||||
nvhost_module_reset(pdev, true);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user