diff --git a/drivers/accel/rocket/rocket_core.c b/drivers/accel/rocket/rocket_core.c index ccc9774ebbb626dd41601ad4226c5a27e7945d1e..c5905544f6996d2ac5276bdf3e835283c91398da 100644 --- a/drivers/accel/rocket/rocket_core.c +++ b/drivers/accel/rocket/rocket_core.c @@ -17,14 +17,14 @@ static int rocket_clk_init(struct rocket_core *core) { int err; - core->a_clk = devm_clk_get_enabled(core->dev, "aclk"); + core->a_clk = devm_clk_get(core->dev, "aclk"); if (IS_ERR(core->a_clk)) { err = PTR_ERR(core->a_clk); dev_err(core->dev, "devm_clk_get_enabled failed %d for core %d\n", err, core->index); return err; } - core->h_clk = devm_clk_get_enabled(core->dev, "hclk"); + core->h_clk = devm_clk_get(core->dev, "hclk"); if (IS_ERR(core->h_clk)) { err = PTR_ERR(core->h_clk); dev_err(core->dev, "devm_clk_get_enabled failed %d for core %d\n", err, core->index); @@ -68,6 +68,7 @@ int rocket_core_bind(struct device *dev, struct device *master, void *data) return -ENOMEM; core->index = rdev->num_cores++; + core->rdev = rdev; rdev->cores[core->index] = core; core->dev = dev; dev_set_drvdata(dev, core); @@ -92,15 +93,13 @@ int rocket_core_bind(struct device *dev, struct device *master, void *data) if (err) return err; - version = rocket_read(core, RKNN_OFFSET_VERSION) + (rocket_read(core, RKNN_OFFSET_VERSION_NUM) & 0xffff); - dev_info(dev, "Rockchip NPU core %d version: %d\n", core->index, version); - printk("*** %s: child_count %d usage_count %d disable_depth %d\n", __func__, dev->power.child_count.counter, dev->power.usage_count.counter, dev->power.disable_depth); pm_runtime_use_autosuspend(dev); pm_runtime_set_autosuspend_delay(dev, 50); /* ~3 frames */ - pm_runtime_set_active(dev); + pm_runtime_set_suspended(dev); pm_runtime_enable(dev); - pm_runtime_mark_last_busy(dev); + + printk("*** %s: child_count %d usage_count %d disable_depth %d 2\n", __func__, dev->power.child_count.counter, dev->power.usage_count.counter, dev->power.disable_depth); return 0; } @@ -120,30 +119,20 @@ void rocket_core_unbind(struct device *dev, struct device *master, void *data) printk("*** %s: %d\n", __func__, 2); } -void rocket_core_reset(struct rocket_core *core) +int rocket_core_runtime_resume(struct device *dev) { - pm_runtime_get(core->dev); - - printk("*** %s: %d\n", __func__, 1); - reset_control_assert(core->a_reset); - reset_control_assert(core->h_reset); + struct rocket_core *core = dev_get_drvdata(dev); - udelay(10); + printk("*** %s: core %d\n", __func__, core->index); - reset_control_deassert(core->a_reset); - reset_control_deassert(core->h_reset); - printk("*** %s: %d\n", __func__, 2); + pm_runtime_get_sync(core->rdev->dev); - pm_runtime_put(core->dev); -} + clk_prepare_enable(core->a_clk); + clk_prepare_enable(core->h_clk); -int rocket_core_runtime_resume(struct device *dev) -{ - struct rocket_core *core = dev_get_drvdata(dev); + printk("*** %s: core %d - done\n", __func__, core->index); - printk("*** %s: %d\n", __func__, 1); - //rocket_core_reset(core); - printk("*** %s: %d\n", __func__, 2); + udelay(1000); return 0; } @@ -152,12 +141,16 @@ int rocket_core_runtime_suspend(struct device *dev) { struct rocket_core *core = dev_get_drvdata(dev); - printk("*** %s: %d\n", __func__, 1); + printk("*** %s: core %d\n", __func__, core->index); if (atomic_read(&core->sched.credit_count)) return -EBUSY; - printk("*** %s: %d\n", __func__, 2); + clk_disable_unprepare(core->h_clk); + clk_disable_unprepare(core->a_clk); + + pm_runtime_put_sync(core->rdev->dev); + printk("*** %s: core %d - done\n", __func__, core->index); return 0; } @@ -173,3 +166,14 @@ int rocket_core_suspend(struct device *dev) printk("*** %s: %d\n", __func__, 1); return pm_runtime_force_suspend(dev); } + +unsigned int rocket_core_get_version(struct rocket_core *core) +{ + unsigned int version; + + pm_runtime_get_sync(core->dev); + version = rocket_read(core, RKNN_OFFSET_VERSION) + (rocket_read(core, RKNN_OFFSET_VERSION_NUM) & 0xffff); + pm_runtime_put(core->dev); + + return version; +} \ No newline at end of file diff --git a/drivers/accel/rocket/rocket_core.h b/drivers/accel/rocket/rocket_core.h index a2a66b7f65b67e2e24643df8bc975ef0ff9ba543..2a0df07b7ead620db9728e5240adddaa3ac71127 100644 --- a/drivers/accel/rocket/rocket_core.h +++ b/drivers/accel/rocket/rocket_core.h @@ -15,6 +15,7 @@ struct rocket_core { struct device *dev; + struct rocket_device *rdev; unsigned int index; struct reset_control *a_reset; @@ -41,7 +42,7 @@ struct rocket_core { int rocket_core_bind(struct device *dev, struct device *master, void *data); void rocket_core_unbind(struct device *dev, struct device *master, void *data); -void rocket_core_reset(struct rocket_core *core); +unsigned int rocket_core_get_version(struct rocket_core *core); int rocket_core_runtime_resume(struct device *dev); int rocket_core_runtime_suspend(struct device *dev); diff --git a/drivers/accel/rocket/rocket_drv.c b/drivers/accel/rocket/rocket_drv.c index 60cadba90a4e6d2cef063eb2bee14f7bd5579533..2f481eb8f65eede49c15bf8aed44100e2270d7c7 100644 --- a/drivers/accel/rocket/rocket_drv.c +++ b/drivers/accel/rocket/rocket_drv.c @@ -7,6 +7,7 @@ #include "linux/dma-mapping.h" #include "linux/err.h" #include "linux/pm_runtime.h" +#include "rocket_core.h" #include <linux/of.h> #include <linux/module.h> #include <linux/platform_device.h> @@ -137,6 +138,8 @@ static int rocket_drm_bind(struct device *dev) { struct rocket_device *rdev; struct drm_device *ddev; + unsigned int core; + unsigned int version; int err; rdev = devm_kzalloc(dev, sizeof(*rdev), GFP_KERNEL); @@ -159,7 +162,7 @@ static int rocket_drm_bind(struct device *dev) if (err) goto err_drm_dev; - rdev->clk_npu = devm_clk_get_enabled(rdev->dev, "clk_npu"); + rdev->clk_npu = devm_clk_get(rdev->dev, "clk_npu"); if (IS_ERR(rdev->clk_npu)) { if (PTR_ERR(rdev->clk_npu) != -EPROBE_DEFER) dev_err(dev, "Couldn't find clk_npu\n"); @@ -167,7 +170,7 @@ static int rocket_drm_bind(struct device *dev) goto err_drm_dev; } - rdev->pclk = devm_clk_get_enabled(rdev->dev, "pclk"); + rdev->pclk = devm_clk_get(rdev->dev, "pclk"); if (IS_ERR(rdev->pclk)) { if (PTR_ERR(rdev->clk_npu) != -EPROBE_DEFER) dev_err(dev, "Couldn't find pclk\n"); @@ -180,11 +183,16 @@ static int rocket_drm_bind(struct device *dev) goto err_drm_dev; printk("*** %s: child_count %d usage_count %d disable_depth %d\n", __func__, rdev->dev->power.child_count.counter, rdev->dev->power.usage_count.counter, rdev->dev->power.disable_depth); - pm_runtime_use_autosuspend(rdev->dev); - pm_runtime_set_autosuspend_delay(rdev->dev, 50); /* ~3 frames */ - pm_runtime_set_active(rdev->dev); - pm_runtime_enable(rdev->dev); - pm_runtime_mark_last_busy(rdev->dev); + pm_runtime_use_autosuspend(dev); + pm_runtime_set_autosuspend_delay(dev, 50); /* ~3 frames */ + pm_runtime_set_suspended(dev); + pm_runtime_enable(dev); + printk("*** %s: child_count %d usage_count %d disable_depth %d 2\n", __func__, rdev->dev->power.child_count.counter, rdev->dev->power.usage_count.counter, rdev->dev->power.disable_depth); + + for (core = 0; core < rdev->num_cores; core++) { + version = rocket_core_get_version(rdev->cores[core]); + dev_info(dev, "Rockchip NPU core %d version: %d\n", core, version); + } err = drm_dev_register(ddev, 0); if (err < 0) @@ -252,15 +260,29 @@ MODULE_DEVICE_TABLE(of, dt_match); static int rocket_runtime_suspend(struct device *dev) { + struct rocket_device *rdev = dev_get_drvdata(dev); + printk("*** %s: %d\n", __func__, 1); + clk_disable_unprepare(rdev->pclk); + clk_disable_unprepare(rdev->clk_npu); + + printk("*** %s: %d\n", __func__, 2); + return 0; } static int rocket_runtime_resume(struct device *dev) { + struct rocket_device *rdev = dev_get_drvdata(dev); + printk("*** %s: %d\n", __func__, 1); + clk_prepare_enable(rdev->clk_npu); + clk_prepare_enable(rdev->pclk); + + printk("*** %s: %d\n", __func__, 2); + return 0; } diff --git a/drivers/accel/rocket/rocket_gem.c b/drivers/accel/rocket/rocket_gem.c index 1d2efa7c1700236bdd52f15ffba095853a3fa366..ef2f96da9cf018681d8eec819f3df5996a688d07 100644 --- a/drivers/accel/rocket/rocket_gem.c +++ b/drivers/accel/rocket/rocket_gem.c @@ -2,7 +2,6 @@ /* Copyright 2024 Tomeu Vizoso <tomeu@tomeuvizoso.net> */ #include "drm/drm_gem_shmem_helper.h" -#include "linux/delay.h" #include <linux/pagemap.h> #include <linux/dma-mapping.h> #include <drm/drm_utils.h> @@ -70,14 +69,10 @@ int rocket_ioctl_create_bo(struct drm_device *dev, void *data, struct drm_file * unsigned int core; int ret; - printk("*** %s: %d\n", __func__, 1); - shmem_obj = drm_gem_shmem_create(dev, args->size); if (IS_ERR(shmem_obj)) return PTR_ERR(shmem_obj); - printk("*** %s: %d\n", __func__, 2); - gem_obj = &shmem_obj->base; rkt_obj = to_rocket_bo(gem_obj); @@ -90,8 +85,6 @@ int rocket_ioctl_create_bo(struct drm_device *dev, void *data, struct drm_file * if (ret) goto err; - printk("*** %s: %d\n", __func__, 3); - sgt = drm_gem_shmem_get_pages_sgt(shmem_obj); if (IS_ERR(sgt)) { ret = PTR_ERR(sgt); @@ -104,15 +97,9 @@ int rocket_ioctl_create_bo(struct drm_device *dev, void *data, struct drm_file * goto err; } - printk("*** %s: %d\n", __func__, 4); - args->offset = drm_vma_node_offset_addr(&gem_obj->vma_node); - - printk("*** %s: %d\n", __func__, 5); args->dma_address = sg_dma_address(shmem_obj->sgt->sgl); - printk("*** %s: %d\n", __func__, 6); - return 0; err: @@ -142,8 +129,6 @@ int rocket_ioctl_prep_bo(struct drm_device *dev, void *data, struct drm_file *fi unsigned int core; long ret = 0; - printk("*** %s: %d\n", __func__, 1); - if (args->op & ~(ROCKET_PREP_READ | ROCKET_PREP_WRITE)) return -EINVAL; @@ -151,10 +136,8 @@ int rocket_ioctl_prep_bo(struct drm_device *dev, void *data, struct drm_file *fi if (!gem_obj) return -ENOENT; - printk("*** %s: waiting for job\n", __func__); ret = dma_resv_wait_timeout(gem_obj->resv, dma_resv_usage_rw(write), true, timeout); - printk("*** %s: waited for job\n", __func__); if (!ret) ret = timeout ? -ETIMEDOUT : -EBUSY; @@ -169,8 +152,6 @@ int rocket_ioctl_prep_bo(struct drm_device *dev, void *data, struct drm_file *fi drm_gem_object_put(gem_obj); - printk("*** %s: %d\n", __func__, 2); - return ret; } @@ -183,8 +164,6 @@ int rocket_ioctl_fini_bo(struct drm_device *dev, void *data, struct drm_file *fi struct drm_gem_shmem_object *shmem_obj; unsigned int core; - printk("*** %s: %d\n", __func__, 1); - gem_obj = drm_gem_object_lookup(file, args->handle); if (!gem_obj) return -ENOENT; @@ -204,7 +183,5 @@ int rocket_ioctl_fini_bo(struct drm_device *dev, void *data, struct drm_file *fi drm_gem_object_put(gem_obj); - printk("*** %s: %d\n", __func__, 2); - return 0; } diff --git a/drivers/accel/rocket/rocket_job.c b/drivers/accel/rocket/rocket_job.c index 4eeb67487669680fa96bfa465298f256c50311b6..b95313b4661c4cd007f96dcc482e0279863c7e06 100644 --- a/drivers/accel/rocket/rocket_job.c +++ b/drivers/accel/rocket/rocket_job.c @@ -301,7 +301,7 @@ static struct dma_fence *rocket_job_run(struct drm_sched_job *sched_job) dma_fence_put(job->done_fence); job->done_fence = dma_fence_get(fence); - ret = pm_runtime_get_sync(job->rdev->dev); + //ret = pm_runtime_get_sync(job->rdev->dev); ret = pm_runtime_get_sync(core->dev); if (ret < 0) return fence; @@ -327,7 +327,7 @@ static void rocket_job_handle_done(struct rocket_core *core, core->in_flight_job = NULL; dma_fence_signal_locked(job->done_fence); pm_runtime_put_autosuspend(core->dev); - pm_runtime_put_autosuspend(job->rdev->dev); + //pm_runtime_put_autosuspend(job->rdev->dev); } static void rocket_job_handle_irq(struct rocket_core *core) @@ -349,7 +349,7 @@ static void rocket_job_handle_irq(struct rocket_core *core) spin_lock(&core->job_lock); if (core->in_flight_job) { - pm_runtime_mark_last_busy(core->in_flight_job->rdev->dev); + pm_runtime_mark_last_busy(core->dev); rocket_job_handle_done(core, core->in_flight_job); } @@ -384,40 +384,18 @@ rocket_reset(struct rocket_core *core, struct drm_sched_job *bad) if (bad) drm_sched_increase_karma(bad); - /* Mask job interrupts and synchronize to make sure we won't be - * interrupted during our reset. - */ - rocket_write(core, RKNN_OFFSET_INT_MASK, 0x0); synchronize_irq(core->irq); - /* Handle the remaining interrupts before we reset. */ + /* Handle any remaining interrupts before we reset. */ rocket_job_handle_irq(core); - /* Remaining interrupts have been handled, but we might still have - * stuck jobs. Let's make sure the PM counters stay balanced by - * manually calling pm_runtime_put_noidle() and - * rocket_devfreq_record_idle() for each stuck job. - * Let's also make sure the cycle counting register's refcnt is - * kept balanced to prevent it from running forever - */ spin_lock(&core->job_lock); if (core->in_flight_job) { - pm_runtime_put_noidle(core->dev); - pm_runtime_put_noidle(core->in_flight_job->rdev->dev); + pm_runtime_put_sync(core->dev); + core->in_flight_job = NULL; } - - core->in_flight_job = NULL; spin_unlock(&core->job_lock); - /* Proceed with reset now. */ - pm_runtime_force_suspend(core->dev); - pm_runtime_force_resume(core->dev); - - /* rocket_device_reset() unmasks job interrupts, but we want to - * keep them masked a bit longer. - */ - rocket_write(core, RKNN_OFFSET_INT_MASK, 0x0); - /* GPU has been reset, we can clear the reset pending bit. */ atomic_set(&core->reset.pending, 0); @@ -435,9 +413,6 @@ rocket_reset(struct rocket_core *core, struct drm_sched_job *bad) /* Restart the scheduler */ drm_sched_start(&core->sched, true); - /* Re-enable job interrupts now that everything has been restarted. */ - rocket_write(core, RKNN_OFFSET_INT_MASK, (1 << RKNN_DPU_GROUP_0) | (1 << RKNN_DPU_GROUP_1)); - dma_fence_end_signalling(cookie); } diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index f5629515bd78d0ea3abd713c56c9d5de2812f5f1..81f3e6986d028bd5cab6c74d02a0cd48641d1c0b 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c @@ -1317,10 +1317,14 @@ static int __maybe_unused rk_iommu_suspend(struct device *dev) { struct rk_iommu *iommu = dev_get_drvdata(dev); + printk("*** %s: %s %d\n", __func__, dev_name(dev), 1); + if (iommu->domain == &rk_identity_domain) return 0; rk_iommu_disable(iommu); + + printk("*** %s: %s %d\n", __func__, dev_name(dev), 2); return 0; } @@ -1328,10 +1332,14 @@ static int __maybe_unused rk_iommu_resume(struct device *dev) { struct rk_iommu *iommu = dev_get_drvdata(dev); + printk("*** %s: %s %d\n", __func__, dev_name(dev), 1); + if (iommu->domain == &rk_identity_domain) return 0; - return rk_iommu_enable(iommu); + int ret = rk_iommu_enable(iommu); + printk("*** %s: %s %d\n", __func__, dev_name(dev), 2); + return ret; } static const struct dev_pm_ops rk_iommu_pm_ops = { diff --git a/drivers/pmdomain/rockchip/pm-domains.c b/drivers/pmdomain/rockchip/pm-domains.c index 9b76b62869d0df51e0439379976ea76da088a144..3578100ba3e692c56854ad62bb64ac6a4a77ae7d 100644 --- a/drivers/pmdomain/rockchip/pm-domains.c +++ b/drivers/pmdomain/rockchip/pm-domains.c @@ -566,6 +566,8 @@ static int rockchip_pd_power_on(struct generic_pm_domain *domain) { struct rockchip_pm_domain *pd = to_rockchip_pd(domain); + printk("*** %s: %s %d\n", __func__, dev_name(&domain->dev), 1); + return rockchip_pd_power(pd, true); } @@ -573,6 +575,8 @@ static int rockchip_pd_power_off(struct generic_pm_domain *domain) { struct rockchip_pm_domain *pd = to_rockchip_pd(domain); + printk("*** %s: %s %d\n", __func__, dev_name(&domain->dev), 1); + return rockchip_pd_power(pd, false); }