mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
gpu: nvgpu: poweron for manual mode scheduling
Manual mode scheduling is incompatible with Runtime PM, Added busy() and idle() calls during open/close of control-fifo nodes. Also, added functions to handle for the extra ref during SC7 suspend/resume. Jira NVGPU-8619 Signed-off-by: Debarshi Dutta <ddutta@nvidia.com> Change-Id: Ic8003c90a4535c2db3aef8f8d78b9dc4a6590b1f Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2766058 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
e4d1a739da
commit
1e2817e022
@@ -27,6 +27,7 @@
|
|||||||
#include <nvgpu/gk20a.h>
|
#include <nvgpu/gk20a.h>
|
||||||
#include <nvgpu/list.h>
|
#include <nvgpu/list.h>
|
||||||
#include <nvgpu/dma.h>
|
#include <nvgpu/dma.h>
|
||||||
|
#include <nvgpu/nvgpu_init.h>
|
||||||
|
|
||||||
struct nvgpu_nvs_domain_ctrl_fifo_users {
|
struct nvgpu_nvs_domain_ctrl_fifo_users {
|
||||||
/* Flag to reserve exclusive user */
|
/* Flag to reserve exclusive user */
|
||||||
@@ -216,6 +217,36 @@ struct nvgpu_nvs_domain_ctrl_fifo *nvgpu_nvs_ctrl_fifo_create(struct gk20a *g)
|
|||||||
return sched;
|
return sched;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nvgpu_nvs_ctrl_fifo_idle(struct gk20a *g)
|
||||||
|
{
|
||||||
|
struct nvgpu_nvs_domain_ctrl_fifo *sched_ctrl = g->sched_ctrl_fifo;
|
||||||
|
|
||||||
|
if (sched_ctrl == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nvgpu_nvs_ctrl_fifo_is_busy(sched_ctrl)) {
|
||||||
|
gk20a_idle(g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void nvgpu_nvs_ctrl_fifo_unidle(struct gk20a *g)
|
||||||
|
{
|
||||||
|
struct nvgpu_nvs_domain_ctrl_fifo *sched_ctrl = g->sched_ctrl_fifo;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (sched_ctrl == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nvgpu_nvs_ctrl_fifo_is_busy(sched_ctrl)) {
|
||||||
|
err = gk20a_busy(g);
|
||||||
|
if (err != 0) {
|
||||||
|
nvgpu_err(g, "cannot busy() again!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool nvgpu_nvs_ctrl_fifo_is_busy(struct nvgpu_nvs_domain_ctrl_fifo *sched_ctrl)
|
bool nvgpu_nvs_ctrl_fifo_is_busy(struct nvgpu_nvs_domain_ctrl_fifo *sched_ctrl)
|
||||||
{
|
{
|
||||||
bool ret = 0;
|
bool ret = 0;
|
||||||
|
|||||||
@@ -259,6 +259,8 @@ void nvgpu_nvs_worker_resume(struct gk20a *g);
|
|||||||
struct nvgpu_nvs_domain_ctrl_fifo *nvgpu_nvs_ctrl_fifo_create(struct gk20a *g);
|
struct nvgpu_nvs_domain_ctrl_fifo *nvgpu_nvs_ctrl_fifo_create(struct gk20a *g);
|
||||||
bool nvgpu_nvs_ctrl_fifo_user_exists(struct nvgpu_nvs_domain_ctrl_fifo *sched_ctrl,
|
bool nvgpu_nvs_ctrl_fifo_user_exists(struct nvgpu_nvs_domain_ctrl_fifo *sched_ctrl,
|
||||||
int pid, bool rw);
|
int pid, bool rw);
|
||||||
|
void nvgpu_nvs_ctrl_fifo_idle(struct gk20a *g);
|
||||||
|
void nvgpu_nvs_ctrl_fifo_unidle(struct gk20a *g);
|
||||||
bool nvgpu_nvs_ctrl_fifo_is_busy(struct nvgpu_nvs_domain_ctrl_fifo *sched_ctrl);
|
bool nvgpu_nvs_ctrl_fifo_is_busy(struct nvgpu_nvs_domain_ctrl_fifo *sched_ctrl);
|
||||||
void nvgpu_nvs_ctrl_fifo_destroy(struct gk20a *g);
|
void nvgpu_nvs_ctrl_fifo_destroy(struct gk20a *g);
|
||||||
bool nvgpu_nvs_ctrl_fifo_user_is_active(struct nvs_domain_ctrl_fifo_user *user);
|
bool nvgpu_nvs_ctrl_fifo_user_is_active(struct nvs_domain_ctrl_fifo_user *user);
|
||||||
|
|||||||
@@ -609,24 +609,34 @@ int nvgpu_nvs_ctrl_fifo_ops_open(struct inode *inode, struct file *filp)
|
|||||||
struct nvgpu_cdev *cdev;
|
struct nvgpu_cdev *cdev;
|
||||||
struct gk20a *g;
|
struct gk20a *g;
|
||||||
int pid;
|
int pid;
|
||||||
|
int err = 0;
|
||||||
struct nvgpu_nvs_domain_ctrl_fifo_user_linux *linux_user;
|
struct nvgpu_nvs_domain_ctrl_fifo_user_linux *linux_user;
|
||||||
bool writable = filp->f_mode & FMODE_WRITE;
|
bool writable = filp->f_mode & FMODE_WRITE;
|
||||||
|
|
||||||
cdev = container_of(inode->i_cdev, struct nvgpu_cdev, cdev);
|
cdev = container_of(inode->i_cdev, struct nvgpu_cdev, cdev);
|
||||||
g = nvgpu_get_gk20a_from_cdev(cdev);
|
g = nvgpu_get_gk20a_from_cdev(cdev);
|
||||||
|
|
||||||
|
err = gk20a_busy(g);
|
||||||
|
if (err != 0) {
|
||||||
|
nvgpu_err(g, "Unable to power on the device");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
if (!nvgpu_is_enabled(g, NVGPU_SUPPORT_NVS_CTRL_FIFO)) {
|
if (!nvgpu_is_enabled(g, NVGPU_SUPPORT_NVS_CTRL_FIFO)) {
|
||||||
|
gk20a_idle(g);
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
pid = nvgpu_current_pid(g);
|
pid = nvgpu_current_pid(g);
|
||||||
if (nvgpu_nvs_ctrl_fifo_user_exists(g->sched_ctrl_fifo, pid, writable)) {
|
if (nvgpu_nvs_ctrl_fifo_user_exists(g->sched_ctrl_fifo, pid, writable)) {
|
||||||
nvgpu_err(g, "User already exists");
|
nvgpu_err(g, "User already exists");
|
||||||
|
gk20a_idle(g);
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
linux_user = nvgpu_kzalloc(g, sizeof(*linux_user));
|
linux_user = nvgpu_kzalloc(g, sizeof(*linux_user));
|
||||||
if (linux_user == NULL) {
|
if (linux_user == NULL) {
|
||||||
|
gk20a_idle(g);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -638,7 +648,6 @@ int nvgpu_nvs_ctrl_fifo_ops_open(struct inode *inode, struct file *filp)
|
|||||||
nvgpu_nvs_ctrl_fifo_add_user(g->sched_ctrl_fifo, &linux_user->user);
|
nvgpu_nvs_ctrl_fifo_add_user(g->sched_ctrl_fifo, &linux_user->user);
|
||||||
|
|
||||||
filp->private_data = linux_user;
|
filp->private_data = linux_user;
|
||||||
nvgpu_get(g);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -660,6 +669,7 @@ int nvgpu_nvs_ctrl_fifo_ops_release(struct inode *inode, struct file *filp)
|
|||||||
|
|
||||||
if (nvgpu_nvs_ctrl_fifo_user_is_active(&linux_user->user)) {
|
if (nvgpu_nvs_ctrl_fifo_user_is_active(&linux_user->user)) {
|
||||||
err = -EBUSY;
|
err = -EBUSY;
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nvgpu_nvs_ctrl_fifo_is_exclusive_user(g->sched_ctrl_fifo, &linux_user->user)) {
|
if (nvgpu_nvs_ctrl_fifo_is_exclusive_user(g->sched_ctrl_fifo, &linux_user->user)) {
|
||||||
@@ -674,7 +684,7 @@ int nvgpu_nvs_ctrl_fifo_ops_release(struct inode *inode, struct file *filp)
|
|||||||
filp->private_data = NULL;
|
filp->private_data = NULL;
|
||||||
|
|
||||||
nvgpu_kfree(g, linux_user);
|
nvgpu_kfree(g, linux_user);
|
||||||
nvgpu_put(g);
|
gk20a_idle(g);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1429,6 +1429,11 @@ static int gk20a_pm_suspend(struct device *dev)
|
|||||||
*/
|
*/
|
||||||
nvgpu_channel_deterministic_idle(g);
|
nvgpu_channel_deterministic_idle(g);
|
||||||
|
|
||||||
|
#ifdef CONFIG_NVS_PRESENT
|
||||||
|
/* Release the busy() lock taken here if control-fifo is enabled */
|
||||||
|
nvgpu_nvs_ctrl_fifo_idle(g);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* check and wait until GPU is idle (with a timeout) */
|
/* check and wait until GPU is idle (with a timeout) */
|
||||||
do {
|
do {
|
||||||
nvgpu_usleep_range(1000, 1100);
|
nvgpu_usleep_range(1000, 1100);
|
||||||
@@ -1467,6 +1472,10 @@ static int gk20a_pm_suspend(struct device *dev)
|
|||||||
fail_suspend:
|
fail_suspend:
|
||||||
gk20a_pm_runtime_resume(dev);
|
gk20a_pm_runtime_resume(dev);
|
||||||
fail_idle:
|
fail_idle:
|
||||||
|
#ifdef CONFIG_NVS_PRESENT
|
||||||
|
/* Re-Acquire the busy() lock taken here if control-fifo is enabled */
|
||||||
|
nvgpu_nvs_ctrl_fifo_unidle(g);
|
||||||
|
#endif
|
||||||
nvgpu_channel_deterministic_unidle(g);
|
nvgpu_channel_deterministic_unidle(g);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -1509,6 +1518,10 @@ static int gk20a_pm_resume(struct device *dev)
|
|||||||
|
|
||||||
g->suspended = false;
|
g->suspended = false;
|
||||||
|
|
||||||
|
#ifdef CONFIG_NVS_PRESENT
|
||||||
|
/* Re-Acquire the busy() lock taken here if control-fifo is enabled */
|
||||||
|
nvgpu_nvs_ctrl_fifo_unidle(g);
|
||||||
|
#endif
|
||||||
nvgpu_channel_deterministic_unidle(g);
|
nvgpu_channel_deterministic_unidle(g);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
Reference in New Issue
Block a user