[PATCH v4 0/2] More preparation for multi gt patches
Hi, the first of the two patches concludes the first stage of refactoring which makes the use of intel_gt on the different subsystem. It's taken from Matt's series and it has alread been reviewed. The patch has just been replaced before any multitile patches and I think it can be already pushed. The second patch is on more step to prepare for the coming multi tile. It's very invasive but it's an effort that can be paid once and for all in order to have a cleaner way to refer to GTs. Andi Changelog: == Patchwork: https://patchwork.freedesktop.org/series/97020/ v3 -> v4: - the intel_gt_init_early() has been split as it was causing some headaches for the order of the early initialization. The split has been done keeping in mind the coming next patch in the series that wil make this a static function. v2 -> v3: - sed -i ... took too much freedom and changed more than it was supposed to. - fix a compile error which did not appear in my local build v1 -> v2: - patch 2: do not use anymore the reference i915->gt but use to_root_gt(), coming from Matt Roper's patch. - fix some comments from Chris. Andi Shyti (1): drm/i915: Use to_root_gt() to refer to the root tile Michał Winiarski (1): drm/i915: Store backpointer to GT in uncore .../gpu/drm/i915/display/intel_atomic_plane.c | 4 +- drivers/gpu/drm/i915/display/intel_display.c | 23 +--- drivers/gpu/drm/i915/display/intel_dpt.c | 2 +- drivers/gpu/drm/i915/display/intel_overlay.c | 2 +- .../drm/i915/display/skl_universal_plane.c| 2 +- drivers/gpu/drm/i915/gem/i915_gem_context.c | 22 drivers/gpu/drm/i915/gem/i915_gem_create.c| 2 +- .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 4 +- drivers/gpu/drm/i915/gem/i915_gem_mman.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_phys.c | 6 +- drivers/gpu/drm/i915/gem/i915_gem_pm.c| 6 +- drivers/gpu/drm/i915/gem/i915_gem_shrinker.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_throttle.c | 3 +- drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c | 29 +++--- drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 2 +- .../gpu/drm/i915/gem/selftests/huge_pages.c | 4 +- .../i915/gem/selftests/i915_gem_client_blt.c | 2 +- .../drm/i915/gem/selftests/i915_gem_context.c | 10 ++-- .../drm/i915/gem/selftests/i915_gem_migrate.c | 2 +- .../drm/i915/gem/selftests/i915_gem_mman.c| 28 +- drivers/gpu/drm/i915/gt/intel_engine_user.c | 2 +- drivers/gpu/drm/i915/gt/intel_ggtt.c | 2 +- drivers/gpu/drm/i915/gt/intel_gt.c| 11 ++-- drivers/gpu/drm/i915/gt/intel_gt.h| 1 + drivers/gpu/drm/i915/gt/intel_rps.c | 12 ++-- drivers/gpu/drm/i915/gt/intel_workarounds.c | 3 +- drivers/gpu/drm/i915/gt/mock_engine.c | 10 ++-- drivers/gpu/drm/i915/gt/selftest_context.c| 2 +- drivers/gpu/drm/i915/gt/selftest_engine.c | 2 +- drivers/gpu/drm/i915/gt/selftest_engine_cs.c | 4 +- .../drm/i915/gt/selftest_engine_heartbeat.c | 4 +- drivers/gpu/drm/i915/gt/selftest_execlists.c | 6 +- drivers/gpu/drm/i915/gt/selftest_gt_pm.c | 8 +-- drivers/gpu/drm/i915/gt/selftest_hangcheck.c | 2 +- drivers/gpu/drm/i915/gt/selftest_lrc.c| 2 +- drivers/gpu/drm/i915/gt/selftest_migrate.c| 4 +- drivers/gpu/drm/i915/gt/selftest_mocs.c | 2 +- drivers/gpu/drm/i915/gt/selftest_reset.c | 2 +- .../drm/i915/gt/selftest_ring_submission.c| 4 +- drivers/gpu/drm/i915/gt/selftest_slpc.c | 6 +- drivers/gpu/drm/i915/gt/selftest_timeline.c | 6 +- .../gpu/drm/i915/gt/selftest_workarounds.c| 4 +- drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c | 2 +- drivers/gpu/drm/i915/gt/uc/selftest_guc.c | 2 +- .../drm/i915/gt/uc/selftest_guc_multi_lrc.c | 2 +- drivers/gpu/drm/i915/gvt/gvt.c| 2 +- drivers/gpu/drm/i915/gvt/scheduler.c | 2 +- drivers/gpu/drm/i915/i915_debugfs.c | 38 ++--- drivers/gpu/drm/i915/i915_debugfs_params.c| 4 +- drivers/gpu/drm/i915/i915_driver.c| 31 +- drivers/gpu/drm/i915/i915_drv.h | 9 ++- drivers/gpu/drm/i915/i915_gem.c | 16 +++--- drivers/gpu/drm/i915/i915_getparam.c | 10 ++-- drivers/gpu/drm/i915/i915_gpu_error.c | 4 +- drivers/gpu/drm/i915/i915_irq.c | 56 +-- drivers/gpu/drm/i915/i915_perf.c | 2 +- drivers/gpu/drm/i915/i915_pmu.c | 14 ++--- drivers/gpu/drm/i915/i915_query.c | 2 +- drivers/gpu/drm/i915/i915_sysfs.c | 22 drivers/gpu/drm/i915/intel_gvt.c | 2 +- drivers/gpu/drm/i915/intel_uncore.c | 9 +-- drivers/gpu/drm/i915/intel_uncore.h | 3 +- drivers/gpu/drm/i915/intel_wopcm.c| 2 +- drivers/gpu/drm/i915/pxp/intel_pxp_tee.c | 6 +- drivers/gpu/drm/i915/selftests/i915_active.c | 2 +- drivers/gpu/drm/i915/selftests/i915_gem.c | 2
[PATCH v4 1/2] drm/i915: Store backpointer to GT in uncore
From: Michał Winiarski We now support a per-gt uncore, yet we're not able to infer which GT we're operating upon. Let's store a backpointer for now. Signed-off-by: Michał Winiarski Signed-off-by: Matt Roper Reviewed-by: Andi Shyti Signed-off-by: Andi Shyti --- drivers/gpu/drm/i915/gt/intel_gt.c | 11 +++ drivers/gpu/drm/i915/gt/intel_gt.h | 1 + drivers/gpu/drm/i915/i915_driver.c | 5 +++-- drivers/gpu/drm/i915/intel_uncore.c | 9 + drivers/gpu/drm/i915/intel_uncore.h | 3 ++- drivers/gpu/drm/i915/selftests/mock_gem_device.c | 4 ++-- drivers/gpu/drm/i915/selftests/mock_uncore.c | 2 +- 7 files changed, 21 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c index f2422d48be32..f98f0fb21efb 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt.c +++ b/drivers/gpu/drm/i915/gt/intel_gt.c @@ -25,11 +25,8 @@ #include "shmem_utils.h" #include "pxp/intel_pxp.h" -void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915) +void __intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915) { - gt->i915 = i915; - gt->uncore = &i915->uncore; - spin_lock_init(>->irq_lock); INIT_LIST_HEAD(>->closed_vma); @@ -48,6 +45,12 @@ void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915) intel_rps_init_early(>->rps); } +void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915) +{ + gt->i915 = i915; + gt->uncore = &i915->uncore; +} + int intel_gt_probe_lmem(struct intel_gt *gt) { struct drm_i915_private *i915 = gt->i915; diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h b/drivers/gpu/drm/i915/gt/intel_gt.h index 74e771871a9b..3ace129eb2af 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt.h +++ b/drivers/gpu/drm/i915/gt/intel_gt.h @@ -35,6 +35,7 @@ static inline struct intel_gt *huc_to_gt(struct intel_huc *huc) } void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915); +void __intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915); void intel_gt_init_hw_early(struct intel_gt *gt, struct i915_ggtt *ggtt); int intel_gt_probe_lmem(struct intel_gt *gt); int intel_gt_init_mmio(struct intel_gt *gt); diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index a1327dad..35f491238e22 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -315,8 +315,9 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv) intel_device_info_subplatform_init(dev_priv); intel_step_init(dev_priv); + intel_gt_init_early(&dev_priv->gt, dev_priv); intel_uncore_mmio_debug_init_early(&dev_priv->mmio_debug); - intel_uncore_init_early(&dev_priv->uncore, dev_priv); + intel_uncore_init_early(&dev_priv->uncore, &dev_priv->gt); spin_lock_init(&dev_priv->irq_lock); spin_lock_init(&dev_priv->gpu_error.lock); @@ -347,7 +348,7 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv) intel_wopcm_init_early(&dev_priv->wopcm); - intel_gt_init_early(&dev_priv->gt, dev_priv); + __intel_gt_init_early(&dev_priv->gt, dev_priv); i915_gem_init_early(dev_priv); diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index abdac78d3976..fc25ebf1a593 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -2061,12 +2061,13 @@ void intel_uncore_cleanup_mmio(struct intel_uncore *uncore) } void intel_uncore_init_early(struct intel_uncore *uncore, -struct drm_i915_private *i915) +struct intel_gt *gt) { spin_lock_init(&uncore->lock); - uncore->i915 = i915; - uncore->rpm = &i915->runtime_pm; - uncore->debug = &i915->mmio_debug; + uncore->i915 = gt->i915; + uncore->gt = gt; + uncore->rpm = >->i915->runtime_pm; + uncore->debug = >->i915->mmio_debug; } static void uncore_raw_init(struct intel_uncore *uncore) diff --git a/drivers/gpu/drm/i915/intel_uncore.h b/drivers/gpu/drm/i915/intel_uncore.h index d1d17b04e29f..210fe2a71612 100644 --- a/drivers/gpu/drm/i915/intel_uncore.h +++ b/drivers/gpu/drm/i915/intel_uncore.h @@ -129,6 +129,7 @@ struct intel_uncore { void __iomem *regs; struct drm_i915_private *i915; + struct intel_gt *gt; struct intel_runtime_pm *rpm; spinlock_t lock; /** lock is also taken in irq contexts. */ @@ -217,7 +218,7 @@ u32 intel_uncore_read_with_mcr_steering(struct intel_uncore *uncore, void intel_uncore_mmio_debug_init_early(struct intel_uncore_mmio_debug *mmio_debug); void intel_uncore_init_early(struct intel_uncore *uncore, -struct drm_i915_private *i915); +
[PATCH v4 2/2] drm/i915: Use to_root_gt() to refer to the root tile
Starting from a patch from Matt to_root_gt() returns the reference to the root tile in order to abstract the root tile from th callers. Being the root tile identified as tile '0', embed the id in the name so that i915->gt becomes i915->gt0. The renaming has been mostly done with the following command and some manual fixes. sed -i -e sed -i 's/\&i915\->gt\./\&to_root_gt(i915)\->/g' \ -e sed -i 's/\&dev_priv\->gt\./\&to_root_gt(dev_priv)\->/g' \ -e 's/\&dev_priv\->gt/to_root_gt(dev_priv)/g' \ -e 's/\&i915\->gt/to_root_gt(i915)/g' \ -e 's/dev_priv\->gt\./to_root_gt(dev_priv)\->/g' \ -e 's/i915\->gt\./to_root_gt(i915)\->/g' \ `find drivers/gpu/drm/i915/ -name *.[ch]` Two small changes have been added to this commit: 1. intel_reset_gpu() in intel_display.c retreives the gt from to_scanout_gt() 2. in set_scheduler_caps() the gt is taken from the engine and not from i915. Signed-off-by: Matt Roper Signed-off-by: Andi Shyti Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Lucas De Marchi Cc: Rodrigo Vivi Cc: Thomas Hellström Cc: Tvrtko Ursulin --- .../gpu/drm/i915/display/intel_atomic_plane.c | 4 +- drivers/gpu/drm/i915/display/intel_display.c | 23 +--- drivers/gpu/drm/i915/display/intel_dpt.c | 2 +- drivers/gpu/drm/i915/display/intel_overlay.c | 2 +- .../drm/i915/display/skl_universal_plane.c| 2 +- drivers/gpu/drm/i915/gem/i915_gem_context.c | 22 drivers/gpu/drm/i915/gem/i915_gem_create.c| 2 +- .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 4 +- drivers/gpu/drm/i915/gem/i915_gem_mman.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_phys.c | 6 +- drivers/gpu/drm/i915/gem/i915_gem_pm.c| 6 +- drivers/gpu/drm/i915/gem/i915_gem_shrinker.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_throttle.c | 3 +- drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c | 29 +++--- drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 2 +- .../gpu/drm/i915/gem/selftests/huge_pages.c | 4 +- .../i915/gem/selftests/i915_gem_client_blt.c | 2 +- .../drm/i915/gem/selftests/i915_gem_context.c | 10 ++-- .../drm/i915/gem/selftests/i915_gem_migrate.c | 2 +- .../drm/i915/gem/selftests/i915_gem_mman.c| 28 +- drivers/gpu/drm/i915/gt/intel_engine_user.c | 2 +- drivers/gpu/drm/i915/gt/intel_ggtt.c | 2 +- drivers/gpu/drm/i915/gt/intel_rps.c | 12 ++-- drivers/gpu/drm/i915/gt/intel_workarounds.c | 3 +- drivers/gpu/drm/i915/gt/mock_engine.c | 10 ++-- drivers/gpu/drm/i915/gt/selftest_context.c| 2 +- drivers/gpu/drm/i915/gt/selftest_engine.c | 2 +- drivers/gpu/drm/i915/gt/selftest_engine_cs.c | 4 +- .../drm/i915/gt/selftest_engine_heartbeat.c | 4 +- drivers/gpu/drm/i915/gt/selftest_execlists.c | 6 +- drivers/gpu/drm/i915/gt/selftest_gt_pm.c | 8 +-- drivers/gpu/drm/i915/gt/selftest_hangcheck.c | 2 +- drivers/gpu/drm/i915/gt/selftest_lrc.c| 2 +- drivers/gpu/drm/i915/gt/selftest_migrate.c| 4 +- drivers/gpu/drm/i915/gt/selftest_mocs.c | 2 +- drivers/gpu/drm/i915/gt/selftest_reset.c | 2 +- .../drm/i915/gt/selftest_ring_submission.c| 4 +- drivers/gpu/drm/i915/gt/selftest_slpc.c | 6 +- drivers/gpu/drm/i915/gt/selftest_timeline.c | 6 +- .../gpu/drm/i915/gt/selftest_workarounds.c| 4 +- drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c | 2 +- drivers/gpu/drm/i915/gt/uc/selftest_guc.c | 2 +- .../drm/i915/gt/uc/selftest_guc_multi_lrc.c | 2 +- drivers/gpu/drm/i915/gvt/gvt.c| 2 +- drivers/gpu/drm/i915/gvt/scheduler.c | 2 +- drivers/gpu/drm/i915/i915_debugfs.c | 38 ++--- drivers/gpu/drm/i915/i915_debugfs_params.c| 4 +- drivers/gpu/drm/i915/i915_driver.c| 32 +-- drivers/gpu/drm/i915/i915_drv.h | 9 ++- drivers/gpu/drm/i915/i915_gem.c | 16 +++--- drivers/gpu/drm/i915/i915_getparam.c | 10 ++-- drivers/gpu/drm/i915/i915_gpu_error.c | 4 +- drivers/gpu/drm/i915/i915_irq.c | 56 +-- drivers/gpu/drm/i915/i915_perf.c | 2 +- drivers/gpu/drm/i915/i915_pmu.c | 14 ++--- drivers/gpu/drm/i915/i915_query.c | 2 +- drivers/gpu/drm/i915/i915_sysfs.c | 22 drivers/gpu/drm/i915/intel_gvt.c | 2 +- drivers/gpu/drm/i915/intel_wopcm.c| 2 +- drivers/gpu/drm/i915/pxp/intel_pxp_tee.c | 6 +- drivers/gpu/drm/i915/selftests/i915_active.c | 2 +- drivers/gpu/drm/i915/selftests/i915_gem.c | 2 +- .../gpu/drm/i915/selftests/i915_gem_evict.c | 6 +- drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 4 +- drivers/gpu/drm/i915/selftests/i915_perf.c| 2 +- drivers/gpu/drm/i915/selftests/i915_request.c | 10 ++-- .../gpu/drm/i915/selftests/i915_selftest.c| 4 +- .../gpu/drm/i915/selftests/igt_flush_test.c | 2 +- .../gpu/drm/i915/selftests/igt_live_test.c|
[PATCH] staging: fbtft: add spi_device_id table
After 5fa6863ba692 ("spi: Check we have a spi_device_id for each DT compatible") we need the following to make the SPI core happy. Works for me with a SH1106-based OLED display. Signed-off-by: Heiner Kallweit --- drivers/staging/fbtft/fbtft.h | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/staging/fbtft/fbtft.h b/drivers/staging/fbtft/fbtft.h index 6869f3603..3f1fbdd48 100644 --- a/drivers/staging/fbtft/fbtft.h +++ b/drivers/staging/fbtft/fbtft.h @@ -307,12 +307,19 @@ static const struct of_device_id dt_ids[] = { \ \ MODULE_DEVICE_TABLE(of, dt_ids); \ \ +static const struct spi_device_id spi_ids[] = {\ + { .name = _compatible }, \ + {},\ +}; \ + \ +MODULE_DEVICE_TABLE(spi, spi_ids);\ \ static struct spi_driver fbtft_driver_spi_driver = { \ .driver = {\ .name = _name, \ .of_match_table = dt_ids, \ }, \ + .id_table = spi_ids, \ .probe = fbtft_driver_probe_spi, \ .remove = fbtft_driver_remove_spi, \ }; \ -- 2.34.0
Re: [PATCH 11/15] iio: buffer-dma: Boost performance using write-combine cache setting
On 11/27/21 5:05 PM, Jonathan Cameron wrote: Non-coherent mapping with no cache sync: - fileio: read: 156 MiB/s write: 123 MiB/s - dmabuf: read: 234 MiB/s (capped by sample rate) write: 182 MiB/s Non-coherent reads with no cache sync + write-combine writes: - fileio: read: 156 MiB/s write: 140 MiB/s - dmabuf: read: 234 MiB/s (capped by sample rate) write: 210 MiB/s A few things we can deduce from this: * Write-combine is not available on Zynq/ARM? If it was working, it should give a better performance than the coherent mapping, but it doesn't seem to do anything at all. At least it doesn't harm performance. I'm not sure it's very relevant to this sort of streaming write. If you write a sequence of addresses then nothing stops them getting combined into a single write whether or not it is write-combining. There is a difference at which point they can get combined. With write-combine they can be coalesced into a single transaction anywhere in the interconnect, as early as the CPU itself. Without write-cobmine the DDR controller might decide to combine them, but not earlier. This can make a difference especially if the write is a narrow write, i.e. the access size is smaller than the buswidth. Lets say you do 32-bit writes, but your bus is 64 bits wide. With WC two 32-bits can be combined into a 64-bit write. Without WC that is not possible and you are potentially not using the bus to its fullest capacity. This is especially true if the memory bus is wider than the widest access size of the CPU.
[Bug 205089] amdgpu : drm:amdgpu_cs_ioctl : Failed to initialize parser -125
https://bugzilla.kernel.org/show_bug.cgi?id=205089 --- Comment #30 from David Nichols (da...@qore.org) --- The amdgpu problems in my system were completely and definitively resolved with a memcpy() patch to glibc: https://gist.github.com/jnettlet/f6f8b49bb7c731255c46f541f875f436 The SoC I'm using (NXP LX2160A - SolidRun HoneyComb system) has a known bug regarding PCI device memory writes that can be completely addressed with a simple reordering of the assembly instructions in the arch-specific memcpy() implementation. In any case, this is not a kernel bug for me after all. I can't comment on the source of the problem for others who most likely are running an x86_64 kernel. -- You may reply to this email to add a comment. You are receiving this mail because: You are watching the assignee of the bug.
Re: [PATCH 1/3] mialbox: move cmdq suspend,resume and remove after cmdq_mbox_flush
Hi Tzung-Bi, Thanks for the reviews. On Thu, 2021-11-18 at 13:55 +0800, Tzung-Bi Shih wrote: > On Wed, Nov 17, 2021 at 02:41:56PM +0800, jason-jh.lin wrote: > > Typo in the commit title "mialbox: move cmdq suspend,resume and > remove after cmdq_mbox_flush". > > s/mialbox/mailbox/ -- I'll fix this typo at the next version. Regards, Jason-JH Lin
Re: Fix drm suspend and resume issue
Hi Tzung-Bi, Thanks, I'll fix it. On Thu, 2021-11-18 at 13:54 +0800, Tzung-Bi Shih wrote: > On Wed, Nov 17, 2021 at 02:41:55PM +0800, jason-jh.lin wrote: > > Subject: [PATCH 0/3] Fix drm suspend and resume issue > > You have 2 Subjects. The first one takes precedence. -- Regards, Jason-JH Lin
Re: [PATCH 2/3] mailbox: add cmdq_mbox_flush to clear all task before suspend
Hi Chun-Kuang, Thanks for the reviews. On Fri, 2021-11-19 at 08:01 +0800, Chun-Kuang Hu wrote: > Hi, Jason: > > jason-jh.lin 於 2021年11月17日 週三 下午2:42寫道: > > > > CMDQ driver will occupy GCE clock to execute the task in GCE > > thread. > > > > So call cmdq_mbox_flush to clear all task in GCE thread before > > CMDQ suspend. > > > > Signed-off-by: jason-jh.lin > > --- > > drivers/mailbox/mtk-cmdq-mailbox.c | 9 +++-- > > 1 file changed, 3 insertions(+), 6 deletions(-) > > > > diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c > > b/drivers/mailbox/mtk-cmdq-mailbox.c > > index 03f9ed4c5131..28cadfc0091b 100644 > > --- a/drivers/mailbox/mtk-cmdq-mailbox.c > > +++ b/drivers/mailbox/mtk-cmdq-mailbox.c > > @@ -484,21 +484,18 @@ static int cmdq_suspend(struct device *dev) > > struct cmdq *cmdq = dev_get_drvdata(dev); > > struct cmdq_thread *thread; > > int i; > > - bool task_running = false; > > > > cmdq->suspended = true; > > > > for (i = 0; i < cmdq->thread_nr; i++) { > > thread = &cmdq->thread[i]; > > if (!list_empty(&thread->task_busy_list)) { > > - task_running = true; > > - break; > > + /* try to clear all task in this thread */ > > + cmdq_mbox_flush(thread->chan, 2000); > > I would like the normal control flow rather than error handling. So > the normal control flow is: > > 1. Client driver suspend: Flush command. > 2. CMDQ driver suspend: There is no command to flush. If there are > command, show error message and debug the client driver. > > The error handling flow: > > 1. Client driver suspend: Does not flush command. > 2. CMDQ driver suspend: Flush command and callback to client driver. > Client driver process these callback as error handling. > > The client driver may integrate multiple driver. In the suspend flow, > it may need to stop these driver in a sequence such as. > > 1. Stop driver 1 > 2. Stop driver 2 > 3. Stop driver 3 (cmdq) > 4. Stop driver 4 > 5. Stop driver 5. > > In the normal flow, client driver could control the stop flow. In the > error handling flow, it does not match the stop flow. > > Regards, > Chun-Kuang. > I have tried the normal flow: 1. Client driver suspend: Flush command. 2. CMDQ driver suspend: There is no command to flush. If there are command, show error message and debug the client driver. Then I found the cmdq task of crtc_1 is still executing when cmdq_suspend sometimes. I think it is the latest async cmd sent in mtk_drm_crtc_disable. So I'll try to change it to blocking cmd and see the issue is still happened or not. If it works, then I'll revert this patch and send add blocking cmd in mtk_drm_crtc_disable at the next version. Regards, Jason-JH.Lin > > + dev_warn(dev, "thread[%d] exist running > > task(s) in suspend\n", i); > > } > > } > > > > - if (task_running) > > - dev_warn(dev, "exist running task(s) in > > suspend\n"); > > - > > clk_bulk_unprepare(cmdq->gce_num, cmdq->clocks); > > > > return 0; > > -- > > 2.18.0 > > -- Jason-JH Lin
Re: FW: [PATCH 3/3] drm/mediatek: add devlink to cmdq dev
Hi Tzung-Bi, Thanks for the reviews. > From: Linux-mediatek On > Behalf Of Tzung-Bi Shih > Sent: Thursday, November 18, 2021 1:55 PM > To: Jason-JH Lin (林睿祥) > Cc: Chun-Kuang Hu ; Philipp Zabel < > p.za...@pengutronix.de>; Matthias Brugger ; > Jassi Brar ; David Airlie linux-media...@lists.infradead.org; > linux-arm-ker...@lists.infradead.org; linux-ker...@vger.kernel.org; > hsi...@chromium.org; fs...@chromium.org; Nancy Lin (林欣螢) < > nancy@mediatek.com>; Singo Chang (張興國)singo.ch...@mediatek.com> > Subject: Re: [PATCH 3/3] drm/mediatek: add devlink to cmdq dev > > On Wed, Nov 17, 2021 at 02:41:58PM +0800, jason-jh.lin wrote: > > @@ -158,6 +159,7 @@ static void mtk_drm_crtc_destroy(struct > > drm_crtc *crtc) > > mtk_drm_cmdq_pkt_destroy(&mtk_crtc->cmdq_handle); > > > > if (mtk_crtc->cmdq_client.chan) { > > + device_link_remove(mtk_crtc->drm_dev, mtk_crtc-> > > cmdq_client.chan->mbox->dev); > > > > mbox_free_channel(mtk_crtc->cmdq_client.chan); > > mtk_crtc->cmdq_client.chan = NULL; > > } > > [...] > > @@ -956,6 +959,16 @@ int mtk_drm_crtc_create(struct drm_device > > *drm_dev, > > } > > > > if (mtk_crtc->cmdq_client.chan) { > > + struct device_link *link; > > + > > + /* add devlink to cmdq dev to make sure suspend/resume > > order is correct */ > > + link = device_link_add(dev, mtk_crtc->cmdq_client.chan- > > > mbox->dev, > > > > + DL_FLAG_PM_RUNTIME | > > DL_FLAG_STATELESS); > > + if (!link) { > > + dev_err(dev, "Unable to link dev=%s\n", > > + dev_name(mtk_crtc->cmdq_client.chan- > > > mbox->dev)); > > > > + } > > + > > If device_link_add() failed, doesn't mtk_drm_crtc_create() need to > return an error and exit? OK, I'll add the return error at the next verion. > > OTOH, if device_link_add() failed, won't it bring any side effects to > call device_link_remove()? > Because device_link_remove() will find the device_link of supplier and consumer, then delete the device_link between them. If device_link_add() failed, supplier and consumer won't create the device_link. So calling device_link_remove() won't do anything without deive_link and won't bring any side effects. Regards, Jason-JH.Lin > ___ > Linux-mediatek mailing list > linux-media...@lists.infradead.org > > > > https://urldefense.com/v3/__http://lists.infradead.org/mailman/listinfo/linux-mediatek__;!!CTRNKA9wMg0ARbw!125dmOZ7xCLkwbIrzZf1VqVLQBbdT4RFHoMjR38U1GeCxaTM6xvvB-mSr7sTc6BuY5IH$ > https://urldefense.com/v3/__http://lists.infradead.org/mailman/listinfo/linux-mediatek__;!!CTRNKA9wMg0ARbw!125dmOZ7xCLkwbIrzZf1VqVLQBbdT4RFHoMjR38U1GeCxaTM6xvvB-mSr7sTc6BuY5IH$ > https://urldefense.com/v3/__http://lists.infradead.org/mailman/listinfo/linux-mediatek__;!!CTRNKA9wMg0ARbw!125dmOZ7xCLkwbIrzZf1VqVLQBbdT4RFHoMjR38U1GeCxaTM6xvvB-mSr7sTc6BuY5IH$ > -- Jason-JH Lin
Re: FW: [PATCH 3/3] drm/mediatek: add devlink to cmdq dev
Hi Tzung-Bi, Thanks for the reviews. > From: Linux-mediatek On > Behalf Of Tzung-Bi Shih > Sent: Thursday, November 18, 2021 1:55 PM > To: Jason-JH Lin (林睿祥) > Cc: Chun-Kuang Hu ; Philipp Zabel < > p.za...@pengutronix.de>; Matthias Brugger ; > Jassi Brar ; David Airlie >; Daniel Vetter ; dri-devel@lists.freedesktop.org; > linux-media...@lists.infradead.org; > linux-arm-ker...@lists.infradead.org; linux-ker...@vger.kernel.org; > hsi...@chromium.org; fs...@chromium.org; Nancy Lin (林欣螢) < > nancy@mediatek.com>; Singo Chang (張興國) > Subject: Re: [PATCH 3/3] drm/mediatek: add devlink to cmdq dev > > On Wed, Nov 17, 2021 at 02:41:58PM +0800, jason-jh.lin wrote: > > @@ -158,6 +159,7 @@ static void mtk_drm_crtc_destroy(struct > > drm_crtc *crtc) > > mtk_drm_cmdq_pkt_destroy(&mtk_crtc->cmdq_handle); > > > > if (mtk_crtc->cmdq_client.chan) { > > + device_link_remove(mtk_crtc->drm_dev, mtk_crtc- > > >cmdq_client.chan->mbox->dev); > > mbox_free_channel(mtk_crtc->cmdq_client.chan); > > mtk_crtc->cmdq_client.chan = NULL; > > } > > [...] > > @@ -956,6 +959,16 @@ int mtk_drm_crtc_create(struct drm_device > > *drm_dev, > > } > > > > if (mtk_crtc->cmdq_client.chan) { > > + struct device_link *link; > > + > > + /* add devlink to cmdq dev to make sure suspend/resume > > order is correct */ > > + link = device_link_add(dev, mtk_crtc->cmdq_client.chan- > > >mbox->dev, > > + DL_FLAG_PM_RUNTIME | > > DL_FLAG_STATELESS); > > + if (!link) { > > + dev_err(dev, "Unable to link dev=%s\n", > > + dev_name(mtk_crtc->cmdq_client.chan- > > >mbox->dev)); > > + } > > + > > If device_link_add() failed, doesn't mtk_drm_crtc_create() need to > return an error and exit? OK, I'll add the return error at the next verion. > > OTOH, if device_link_add() failed, won't it bring any side effects to > call device_link_remove()? > Because device_link_remove() will find the device_link of supplier and consumer, then delete the device_link between them. If device_link_add() failed, supplier and consumer won't create the device_link. So calling device_link_remove() won't do anything without deive_link and won't bring any side effects. Regards, Jason-JH.Lin > ___ > Linux-mediatek mailing list > linux-media...@lists.infradead.org > https://urldefense.com/v3/__http://lists.infradead.org/mailman/listinfo/linux-mediatek__;!!CTRNKA9wMg0ARbw!125dmOZ7xCLkwbIrzZf1VqVLQBbdT4RFHoMjR38U1GeCxaTM6xvvB-mSr7sTc6BuY5IH$ > -- Jason-JH Lin
[PATCH 1/2] drm/amdkfd: Use bitmap_zalloc() when applicable
'kfd->gtt_sa_bitmap' is a bitmap. So use 'bitmap_zalloc()' to simplify code, improve the semantic and avoid some open-coded arithmetic in allocator arguments. Also change the corresponding 'kfree()' into 'bitmap_free()' to keep consistency. --- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 12 +++- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index e1294fba0c26..c5a0ce44a295 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -1252,8 +1252,6 @@ int kgd2kfd_schedule_evict_and_restore_process(struct mm_struct *mm, static int kfd_gtt_sa_init(struct kfd_dev *kfd, unsigned int buf_size, unsigned int chunk_size) { - unsigned int num_of_longs; - if (WARN_ON(buf_size < chunk_size)) return -EINVAL; if (WARN_ON(buf_size == 0)) @@ -1264,11 +1262,8 @@ static int kfd_gtt_sa_init(struct kfd_dev *kfd, unsigned int buf_size, kfd->gtt_sa_chunk_size = chunk_size; kfd->gtt_sa_num_of_chunks = buf_size / chunk_size; - num_of_longs = (kfd->gtt_sa_num_of_chunks + BITS_PER_LONG - 1) / - BITS_PER_LONG; - - kfd->gtt_sa_bitmap = kcalloc(num_of_longs, sizeof(long), GFP_KERNEL); - + kfd->gtt_sa_bitmap = bitmap_zalloc(kfd->gtt_sa_num_of_chunks, + GFP_KERNEL); if (!kfd->gtt_sa_bitmap) return -ENOMEM; @@ -1278,13 +1273,12 @@ static int kfd_gtt_sa_init(struct kfd_dev *kfd, unsigned int buf_size, mutex_init(&kfd->gtt_sa_lock); return 0; - } static void kfd_gtt_sa_fini(struct kfd_dev *kfd) { mutex_destroy(&kfd->gtt_sa_lock); - kfree(kfd->gtt_sa_bitmap); + bitmap_free(kfd->gtt_sa_bitmap); } static inline uint64_t kfd_gtt_sa_calc_gpu_addr(uint64_t start_addr, -- 2.30.2
[PATCH 2/2] drm/amdkfd: Use non-atomic bitmap functions when possible
All uses of the 'kfd->gtt_sa_bitmap' bitmap are protected with the 'kfd->gtt_sa_lock' mutex. So: - prefer the non-atomic '__set_bit()' function - use the non-atomic 'bitmap_[set|clear]()' functions instead of equivalent 'for' loops. These functions can work on several bits at a time Signed-off-by: Christophe JAILLET --- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 16 +--- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index c5a0ce44a295..c4d868a5dd97 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -1346,7 +1346,7 @@ int kfd_gtt_sa_allocate(struct kfd_dev *kfd, unsigned int size, /* If we need only one chunk, mark it as allocated and get out */ if (size <= kfd->gtt_sa_chunk_size) { pr_debug("Single bit\n"); - set_bit(found, kfd->gtt_sa_bitmap); + __set_bit(found, kfd->gtt_sa_bitmap); goto kfd_gtt_out; } @@ -1384,10 +1384,8 @@ int kfd_gtt_sa_allocate(struct kfd_dev *kfd, unsigned int size, (*mem_obj)->range_start, (*mem_obj)->range_end); /* Mark the chunks as allocated */ - for (found = (*mem_obj)->range_start; - found <= (*mem_obj)->range_end; - found++) - set_bit(found, kfd->gtt_sa_bitmap); + bitmap_set(kfd->gtt_sa_bitmap, (*mem_obj)->range_start, + (*mem_obj)->range_end - (*mem_obj)->range_start + 1); kfd_gtt_out: mutex_unlock(&kfd->gtt_sa_lock); @@ -1402,8 +1400,6 @@ int kfd_gtt_sa_allocate(struct kfd_dev *kfd, unsigned int size, int kfd_gtt_sa_free(struct kfd_dev *kfd, struct kfd_mem_obj *mem_obj) { - unsigned int bit; - /* Act like kfree when trying to free a NULL object */ if (!mem_obj) return 0; @@ -1414,10 +1410,8 @@ int kfd_gtt_sa_free(struct kfd_dev *kfd, struct kfd_mem_obj *mem_obj) mutex_lock(&kfd->gtt_sa_lock); /* Mark the chunks as free */ - for (bit = mem_obj->range_start; - bit <= mem_obj->range_end; - bit++) - clear_bit(bit, kfd->gtt_sa_bitmap); + bitmap_clear(kfd->gtt_sa_bitmap, mem_obj->range_start, +mem_obj->range_end - mem_obj->range_start + 1); mutex_unlock(&kfd->gtt_sa_lock); -- 2.30.2
[pull] drm/msm: drm-msm-fixes-2021-11-28 for v5.16
Hi Dave & Daniel, A few fixes for v5.16. The following changes since commit fa55b7dcdc43c1aa1ba12bca9d2dd4318c2a0dbf: Linux 5.16-rc1 (2021-11-14 13:56:52 -0800) are available in the Git repository at: https://gitlab.freedesktop.org/drm/msm.git drm-msm-fixes-2021-11-28 for you to fetch changes up to afece15a68dc83b438cc4c3a64634e48a5735573: drm: msm: fix building without CONFIG_COMMON_CLK (2021-11-26 08:58:57 -0800) Akhil P Oommen (2): drm/msm: Fix null ptr access msm_ioctl_gem_submit() drm/msm/a6xx: Fix uinitialized use of gpu_scid Arnd Bergmann (1): drm: msm: fix building without CONFIG_COMMON_CLK Douglas Anderson (3): drm/msm/a6xx: Allocate enough space for GMU registers drm/msm: Fix mmap to include VM_IO and VM_DONTDUMP drm/msm/dp: Avoid unpowered AUX xfers that caused crashes Philip Chen (1): drm/msm/dsi: set default num_data_lanes Rob Clark (8): drm/msm/devfreq: Fix OPP refcnt leak drm/msm: Fix wait_fence submitqueue leak drm/msm: Restore error return on invalid fence drm/msm: Make a6xx_gpu_set_freq() static drm/msm: Demote debug message drm/msm/gpu: Fix idle_work time drm/msm/gpu: Fix check for devices without devfreq drm/msm: Do hw_init() before capturing GPU state drivers/gpu/drm/msm/Kconfig | 2 +- drivers/gpu/drm/msm/Makefile| 6 ++-- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 20 ++-- drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 4 +-- drivers/gpu/drm/msm/dp/dp_aux.c | 17 ++ drivers/gpu/drm/msm/dsi/dsi_host.c | 2 ++ drivers/gpu/drm/msm/msm_debugfs.c | 1 + drivers/gpu/drm/msm/msm_drv.c | 49 +++-- drivers/gpu/drm/msm/msm_gem.c | 5 ++- drivers/gpu/drm/msm/msm_gem_submit.c| 2 ++ drivers/gpu/drm/msm/msm_gpu.h | 3 ++ drivers/gpu/drm/msm/msm_gpu_devfreq.c | 13 +--- 12 files changed, 84 insertions(+), 40 deletions(-)
[Bug 214921] amdgpu hangs HP Laptop on shutdown
https://bugzilla.kernel.org/show_bug.cgi?id=214921 --- Comment #7 from Paul Gover (pmw.go...@yahoo.co.uk) --- Kernel 5.15.5 (which IIUC contains the patch or equivalent) works for me. -- You may reply to this email to add a comment. You are receiving this mail because: You are watching the assignee of the bug.
[PATCH] drm/etnaviv: constify static struct cooling_ops
The only usage of cooling_ops is to pass its address to thermal_of_cooling_device_register(), which takes a pointer to const struct thermal_cooling_device_ops as input. Make it const to allow the compiler to put it in read-only memory. Signed-off-by: Rikard Falkeborn --- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index 06bde46df451..37018bc55810 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -1658,7 +1658,7 @@ etnaviv_gpu_cooling_set_cur_state(struct thermal_cooling_device *cdev, return 0; } -static struct thermal_cooling_device_ops cooling_ops = { +static const struct thermal_cooling_device_ops cooling_ops = { .get_max_state = etnaviv_gpu_cooling_get_max_state, .get_cur_state = etnaviv_gpu_cooling_get_cur_state, .set_cur_state = etnaviv_gpu_cooling_set_cur_state, -- 2.34.1
Re: [PATCH v15 12/39] drm/tegra: gr2d: Support generic power domain and runtime PM
28.11.2021 08:47, Michał Mirosław пишет: > On Sun, Nov 14, 2021 at 10:34:08PM +0300, Dmitry Osipenko wrote: >> Add runtime power management and support generic power domains. > [...] >> @@ -104,10 +127,17 @@ static int gr2d_open_channel(struct tegra_drm_client >> *client, >> struct tegra_drm_context *context) >> { >> struct gr2d *gr2d = to_gr2d(client); >> +int err; >> + >> +err = pm_runtime_resume_and_get(client->base.dev); >> +if (err) >> +return err; >> >> context->channel = host1x_channel_get(gr2d->channel); >> -if (!context->channel) >> +if (!context->channel) { >> +pm_runtime_put(context->client->base.dev); > > Could host1x_channel_get/put() handle pm_runtime* calls ? I would expect > this to be common code for the users. We already have host1x code that manages runtime PM of the client drivers, but it does that only for the code path of the new UAPI. In case of the older UAPI, seems we can move the RPM get/put into tegra/drm.c. I'll consider that change for v16, thank you. > BTW, pm_runtime_resume_and_get() uses different dev than > pm_runtime_put() in the error path - is this intended? These functions use the same dev. The context->client is redundant there, good catch.
Re: [PATCH v15 00/39] NVIDIA Tegra power management patches for 5.17
28.11.2021 08:40, Michał Mirosław пишет: > On Sun, Nov 14, 2021 at 10:33:56PM +0300, Dmitry Osipenko wrote: >> This series adds runtime PM support to Tegra drivers and enables core >> voltage scaling for Tegra20/30 SoCs, resolving overheating troubles. >> >> All patches in this series are interdependent and should go via Tegra tree >> for simplicity. > [...] > > I would suggest pushing all the fixes to the front of the series (those are > at least patches 1, 3, 17, 27-31 and 39). All those patches, apart from 17, should be irrelevant to stable kernel. There is no real benefit in reordering them, IMO. The patches are grouped logically in this series. In the case of patch 17, perhaps won't hurt to add stable tag to it. Then the "drm/tegra: submit:" patches could be swapped to prioritize the fix, though there is no danger of a merge conflict there.
Re: [PATCH] drm/msm: Initialize MDSS irq domain at probe time
Hi, On 25/11/2021 18:09, AngeloGioacchino Del Regno wrote: Since commit 8f59ee9a570c ("drm/msm/dsi: Adjust probe order"), the DSI host gets initialized earlier, but this caused unability to probe the entire stack of components because they all depend on interrupts coming from the main `mdss` node (mdp5, or dpu1). To fix this issue, also anticipate probing mdp5 or dpu1 by initializing them at msm_pdev_probe() time: this will make sure that we add the required interrupt controller mapping before dsi and/or other components try to initialize, finally satisfying the dependency. While at it, also change the allocation of msm_drm_private to use the devm variant of kzalloc(). Fixes: 8f59ee9a570c ("drm/msm/dsi: Adjust probe order") Signed-off-by: AngeloGioacchino Del Regno I have been thinking about this. I do not feel that this is the correct approach. Currently DRM device exists only when all components are bound. If any of the subdevices is removed, corresponding component is delteted (and thus all components are unbound), the DRM device is taken down. This results in the state cleanup, userspace notifications, etc. With your changes, DRM device will continue to exist even after one of subdevices is removed. This is not an expected behaviour, since subdrivers do not perform full cleanup, delegating that to DRM device takedown. I suppose that proper solution would be to split msm_drv.c into into: - generic components & drm code to be called from mdp4/mdp5/dpu driver (making mdp4, mdp5 or dpu1 the components master) - bare mdss driver, taking care only about IRQs, OF devices population - calling proper mdss_init/mdss_destroy functions. Most probably we can drop this part altogether and just make md5_mdss.c/dpu_mdss.c proper platform drivers. --- drivers/gpu/drm/msm/msm_drv.c | 81 --- 1 file changed, 38 insertions(+), 43 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 7936e8d498dd..790acf4993c0 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -512,45 +512,12 @@ static int msm_init_vram(struct drm_device *dev) static int msm_drm_init(struct device *dev, const struct drm_driver *drv) { struct platform_device *pdev = to_platform_device(dev); - struct drm_device *ddev; - struct msm_drm_private *priv; - struct msm_kms *kms; - struct msm_mdss *mdss; + struct drm_device *ddev = platform_get_drvdata(pdev); + struct msm_drm_private *priv = ddev->dev_private; + struct msm_kms *kms = priv->kms; + struct msm_mdss *mdss = priv->mdss; int ret, i; - ddev = drm_dev_alloc(drv, dev); - if (IS_ERR(ddev)) { - DRM_DEV_ERROR(dev, "failed to allocate drm_device\n"); - return PTR_ERR(ddev); - } - - platform_set_drvdata(pdev, ddev); - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) { - ret = -ENOMEM; - goto err_put_drm_dev; - } - - ddev->dev_private = priv; - priv->dev = ddev; - - switch (get_mdp_ver(pdev)) { - case KMS_MDP5: - ret = mdp5_mdss_init(ddev); - break; - case KMS_DPU: - ret = dpu_mdss_init(ddev); - break; - default: - ret = 0; - break; - } - if (ret) - goto err_free_priv; - - mdss = priv->mdss; - priv->wq = alloc_ordered_workqueue("msm", 0); priv->hangcheck_period = DRM_MSM_HANGCHECK_DEFAULT_PERIOD; @@ -685,11 +652,6 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv) err_destroy_mdss: if (mdss && mdss->funcs) mdss->funcs->destroy(ddev); -err_free_priv: - kfree(priv); -err_put_drm_dev: - drm_dev_put(ddev); - platform_set_drvdata(pdev, NULL); return ret; } @@ -1382,12 +1344,42 @@ static const struct component_master_ops msm_drm_ops = { static int msm_pdev_probe(struct platform_device *pdev) { struct component_match *match = NULL; + struct msm_drm_private *priv; + struct drm_device *ddev; int ret; + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + ddev = drm_dev_alloc(&msm_driver, &pdev->dev); + if (IS_ERR(ddev)) { + DRM_DEV_ERROR(&pdev->dev, "failed to allocate drm_device\n"); + return PTR_ERR(ddev); + } + + platform_set_drvdata(pdev, ddev); + ddev->dev_private = priv; + priv->dev = ddev; + + switch (get_mdp_ver(pdev)) { + case KMS_MDP5: + ret = mdp5_mdss_init(ddev); + break; + case KMS_DPU: + ret = dpu_mdss_init(ddev); + break; + default: + ret = 0; + break; + } + if (ret) +
[PATCH v11, 00/19] Support multi hardware decode using of_platform_populate
This series adds support for multi hardware decode into mtk-vcodec, by first adding use of_platform_populate to manage each hardware information: interrupt, clock, register bases and power. Secondly add core work queue to deal with core hardware message, at the same time, add msg queue for different hardware share messages. Lastly, the architecture of different specs are not the same, using specs type to separate them. This series has been tested with both MT8183 and MT8173. Decoding was working for both chips. Patches 1~3 rewrite get register bases and power on/off interface. Patches 4 export decoder pm interfaces. Patches 5 add to support 8192. Patch 6 support multi hardware. Patch 7 separate video encoder and decoder document Patch 8-17 add interfaces to support core hardware. Patch 18-19 remove mtk_vcodec_release_dec/enc_pm interfaces. --- changes compared with v9: - fix comments from tzung-bi for patch 06/19. - add more detail information for hardware block diagram 15/19 changes compared with v9: - need not to build ko, just export pm interfaces for patch 04/19. - fix comments for patch 06/19 changes compared with v8: - add new patch 18~19 to remove mtk_vcodec_release_de/enc_pm interfaces. - fix spelling mistakes for patch 17/19 - fix yaml comments for patch 15/19 Changes compared with v7: - add new patch 4 to build decoder pm file as module - add new patch 5 to support 8192 - fix comments for patch 6/17 - change some logic for using work queue instead of create thread for core hardware decode for patch 10/17 - using work queue for hardware decode instead of create thread for patch 13/17 - add returen value for patch 14/17 - fix yaml check fail 15/17 Changes compared with v6: - Use of_platform_populate to manage multi hardware, not component framework for patch 4/15 - Re-write dtsi document for hardware architecture changed for patch 13/15 -The dtsi will write like below in patch 13/15: vcodec_dec: vcodec_dec@1600 { compatible = "mediatek,mt8192-vcodec-dec"; #address-cells = <2>; #size-cells = <2>; ranges; reg = <0 0x1600 0 0x1000>; /* VDEC_SYS */ mediatek,scp = <&scp>; iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>; dma-ranges = <0x1 0x0 0x0 0x4000 0x0 0xfff0>; vcodec_lat { compatible = "mediatek,mtk-vcodec-lat"; reg = <0 0x1601 0 0x800>; /* VDEC_MISC */ reg-name = "reg-misc"; interrupts = ; iommus = <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD_EXT>, <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD2_EXT>, <&iommu0 M4U_PORT_L5_VDEC_LAT0_AVC_MV_EXT>, <&iommu0 M4U_PORT_L5_VDEC_LAT0_PRED_RD_EXT>, <&iommu0 M4U_PORT_L5_VDEC_LAT0_TILE_EXT>, <&iommu0 M4U_PORT_L5_VDEC_LAT0_WDMA_EXT>, <&iommu0 M4U_PORT_L5_VDEC_LAT0_RG_CTRL_DMA_EXT>, <&iommu0 M4U_PORT_L5_VDEC_UFO_ENC_EXT>; clocks = <&topckgen CLK_TOP_VDEC_SEL>, <&vdecsys_soc CLK_VDEC_SOC_VDEC>, <&vdecsys_soc CLK_VDEC_SOC_LAT>, <&vdecsys_soc CLK_VDEC_SOC_LARB1>, <&topckgen CLK_TOP_MAINPLL_D4>; clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat", "vdec-vdec", "vdec-top"; assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>; assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>; power-domains = <&spm MT8192_POWER_DOMAIN_VDEC>; }; vcodec_core { compatible = "mediatek,mtk-vcodec-core"; reg = <0 0x16025000 0 0x1000>; /* VDEC_CORE_MISC */ reg-names = "reg-misc"; interrupts = ; iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>, <&iommu0 M4U_PORT_L4_VDEC_UFO_EXT>, <&iommu0 M4U_PORT_L4_VDEC_PP_EXT>, <&iommu0 M4U_PORT_L4_VDEC_PRED_RD_EXT>, <&iommu0 M4U_PORT_L4_VDEC_PRED_WR_EXT>, <&iommu0 M4U_PORT_L4_VDEC_PPWRAP_EXT>, <&iommu0 M4U_PORT_L4_VDEC_TILE_EXT>, <&iommu0 M4U_PORT_L4_VDEC_VLD_EXT>, <&iommu0 M4U_PORT_L4_VDEC_VLD2_EXT>, <&iommu0 M4U_PORT_L4_VDEC_AVC_MV_EXT>, <&iommu0 M4U_PORT_L4_VDEC_RG_CTRL_DMA_EXT>; clocks = <&topckgen CLK_TOP_VDEC_SEL>, <&vdecsys CLK_VDEC_VDEC>, <&vdecsys CLK_VDEC_LAT>, <&vdecsys CLK_VDEC_LARB1>, <&topckgen CLK_TOP_MAINPLL_D4>; clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat", "vdec-vdec", "vdec-top"; assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>; assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>; power-domains = <&spm MT8192_POWER_DOMAIN_VDEC2>; }; }; Changes compared with v5: - Add decoder hardware bl
[PATCH v11, 01/19] media: mtk-vcodec: Get numbers of register bases from DT
Different platform may has different numbers of register bases. Gets the numbers of register bases from DT (sizeof(u32) * 4 bytes for each). Reviewed-by: Tzung-Bi Shih Signed-off-by: Yunfei Dong --- .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 37 ++- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c index e6e6a8203eeb..59caf2163349 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c @@ -78,6 +78,30 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv) return IRQ_HANDLED; } +static int mtk_vcodec_get_reg_bases(struct mtk_vcodec_dev *dev) +{ + struct platform_device *pdev = dev->plat_dev; + int reg_num, i; + + /* Sizeof(u32) * 4 bytes for each register base. */ + reg_num = of_property_count_elems_of_size(pdev->dev.of_node, "reg", + sizeof(u32) * 4); + if (reg_num <= 0 || reg_num > NUM_MAX_VDEC_REG_BASE) { + dev_err(&pdev->dev, "Invalid register property size: %d\n", reg_num); + return -EINVAL; + } + + for (i = 0; i < reg_num; i++) { + dev->reg_base[i] = devm_platform_ioremap_resource(pdev, i); + if (IS_ERR(dev->reg_base[i])) + return PTR_ERR(dev->reg_base[i]); + + mtk_v4l2_debug(2, "reg[%d] base=%p", i, dev->reg_base[i]); + } + + return 0; +} + static int fops_vcodec_open(struct file *file) { struct mtk_vcodec_dev *dev = video_drvdata(file); @@ -206,7 +230,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) struct resource *res; phandle rproc_phandle; enum mtk_vcodec_fw_type fw_type; - int i, ret; + int ret; dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); if (!dev) @@ -238,14 +262,9 @@ static int mtk_vcodec_probe(struct platform_device *pdev) goto err_dec_pm; } - for (i = 0; i < NUM_MAX_VDEC_REG_BASE; i++) { - dev->reg_base[i] = devm_platform_ioremap_resource(pdev, i); - if (IS_ERR((__force void *)dev->reg_base[i])) { - ret = PTR_ERR((__force void *)dev->reg_base[i]); - goto err_res; - } - mtk_v4l2_debug(2, "reg[%d] base=%p", i, dev->reg_base[i]); - } + ret = mtk_vcodec_get_reg_bases(dev); + if (ret) + goto err_res; res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res == NULL) { -- 2.25.1
[PATCH v11, 03/19] media: mtk-vcodec: Refactor vcodec pm interface
Using the needed param for pm init/release function and remove unused param mtkdev in 'struct mtk_vcodec_pm'. Reviewed-by: Tzung-Bi Shih Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Yunfei Dong --- .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 6 ++--- .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c | 22 --- .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h | 5 +++-- .../platform/mtk-vcodec/mtk_vcodec_drv.h | 1 - .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c | 1 - 5 files changed, 15 insertions(+), 20 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c index 055d50e52720..3ac4c3935e4e 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c @@ -249,7 +249,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) if (IS_ERR(dev->fw_handler)) return PTR_ERR(dev->fw_handler); - ret = mtk_vcodec_init_dec_pm(dev); + ret = mtk_vcodec_init_dec_pm(dev->plat_dev, &dev->pm); if (ret < 0) { dev_err(&pdev->dev, "Failed to get mt vcodec clock source"); goto err_dec_pm; @@ -378,7 +378,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) err_dec_alloc: v4l2_device_unregister(&dev->v4l2_dev); err_res: - mtk_vcodec_release_dec_pm(dev); + mtk_vcodec_release_dec_pm(&dev->pm); err_dec_pm: mtk_vcodec_fw_release(dev->fw_handler); return ret; @@ -418,7 +418,7 @@ static int mtk_vcodec_dec_remove(struct platform_device *pdev) video_unregister_device(dev->vfd_dec); v4l2_device_unregister(&dev->v4l2_dev); - mtk_vcodec_release_dec_pm(dev); + mtk_vcodec_release_dec_pm(&dev->pm); mtk_vcodec_fw_release(dev->fw_handler); return 0; } diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c index 6038db96f71c..20bd157a855c 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c @@ -13,18 +13,15 @@ #include "mtk_vcodec_dec_pm.h" #include "mtk_vcodec_util.h" -int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev) +int mtk_vcodec_init_dec_pm(struct platform_device *pdev, + struct mtk_vcodec_pm *pm) { struct device_node *node; - struct platform_device *pdev; - struct mtk_vcodec_pm *pm; + struct platform_device *larb_pdev; struct mtk_vcodec_clk *dec_clk; struct mtk_vcodec_clk_info *clk_info; int i = 0, ret = 0; - pdev = mtkdev->plat_dev; - pm = &mtkdev->pm; - pm->mtkdev = mtkdev; dec_clk = &pm->vdec_clk; node = of_parse_phandle(pdev->dev.of_node, "mediatek,larb", 0); if (!node) { @@ -32,13 +29,12 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev) return -1; } - pdev = of_find_device_by_node(node); + larb_pdev = of_find_device_by_node(node); of_node_put(node); - if (WARN_ON(!pdev)) { + if (WARN_ON(!larb_pdev)) { return -1; } - pm->larbvdec = &pdev->dev; - pdev = mtkdev->plat_dev; + pm->larbvdec = &larb_pdev->dev; pm->dev = &pdev->dev; dec_clk->clk_num = @@ -82,10 +78,10 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev) return ret; } -void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev) +void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm) { - pm_runtime_disable(dev->pm.dev); - put_device(dev->pm.larbvdec); + pm_runtime_disable(pm->dev); + put_device(pm->larbvdec); } int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h index 280aeaefdb65..a3df6aef6cb9 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h @@ -9,8 +9,9 @@ #include "mtk_vcodec_drv.h" -int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *dev); -void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev); +int mtk_vcodec_init_dec_pm(struct platform_device *pdev, + struct mtk_vcodec_pm *pm); +void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm); int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm); void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm); diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index 1d2370608d0d..0fa9d85114b9 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h @@ -195,7 +195,6 @@ struct mtk_vcodec_pm { struct mtk_vcodec_clk venc_clk; struct device *larbvenc; struct device *dev; -
[PATCH v11, 02/19] media: mtk-vcodec: Align vcodec wake up interrupt interface
Vdec and venc can use the same function to wake up interrupt event. Reviewed-by: Tzung-Bi Shih Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Yunfei Dong --- drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 9 + drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h | 8 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c | 8 3 files changed, 9 insertions(+), 16 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c index 59caf2163349..055d50e52720 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c @@ -31,13 +31,6 @@ module_param(mtk_v4l2_dbg_level, int, 0644); module_param(mtk_vcodec_dbg, bool, 0644); -/* Wake up context wait_queue */ -static void wake_up_ctx(struct mtk_vcodec_ctx *ctx) -{ - ctx->int_cond = 1; - wake_up_interruptible(&ctx->queue); -} - static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv) { struct mtk_vcodec_dev *dev = priv; @@ -69,7 +62,7 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv) writel((readl(vdec_misc_addr) & ~VDEC_IRQ_CLR), dev->reg_base[VDEC_MISC] + VDEC_IRQ_CFG_REG); - wake_up_ctx(ctx); + wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED); mtk_v4l2_debug(3, "mtk_vcodec_dec_irq_handler :wake up ctx %d, dec_done_status=%x", diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index 581522177308..1d2370608d0d 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h @@ -473,4 +473,12 @@ static inline struct mtk_vcodec_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl) return container_of(ctrl->handler, struct mtk_vcodec_ctx, ctrl_hdl); } +/* Wake up context wait_queue */ +static inline void wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason) +{ + ctx->int_cond = 1; + ctx->int_type = reason; + wake_up_interruptible(&ctx->queue); +} + #endif /* _MTK_VCODEC_DRV_H_ */ diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c index eed67394cf46..7c3487fb3498 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c @@ -65,14 +65,6 @@ static const struct mtk_video_fmt mtk_video_formats_capture_vp8[] = { }, }; -/* Wake up context wait_queue */ -static void wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason) -{ - ctx->int_cond = 1; - ctx->int_type = reason; - wake_up_interruptible(&ctx->queue); -} - static void clean_irq_status(unsigned int irq_status, void __iomem *addr) { if (irq_status & MTK_VENC_IRQ_STATUS_PAUSE) -- 2.25.1
[PATCH v11, 05/19] media: mtk-vcodec: Support MT8192
From: Yunfei Dong Adds MT8192's compatible "mediatek,mt8192-vcodec-dec". Adds MT8192's device private data mtk_lat_sig_core_pdata. Signed-off-by: Yunfei Dong --- .../media/platform/mtk-vcodec/mtk_vcodec_dec.h | 1 + .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 4 .../mtk-vcodec/mtk_vcodec_dec_stateless.c| 16 3 files changed, 21 insertions(+) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h index 46783516b84a..e30806c1faea 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h @@ -67,6 +67,7 @@ extern const struct v4l2_m2m_ops mtk_vdec_m2m_ops; extern const struct media_device_ops mtk_vcodec_media_ops; extern const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata; extern const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata; +extern const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata; /* diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c index 3ac4c3935e4e..b7a51e96d4ba 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c @@ -393,6 +393,10 @@ static const struct of_device_id mtk_vcodec_match[] = { .compatible = "mediatek,mt8183-vcodec-dec", .data = &mtk_vdec_8183_pdata, }, + { + .compatible = "mediatek,mt8192-vcodec-dec", + .data = &mtk_lat_sig_core_pdata, + }, {}, }; diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c index 8f4a1f0a0769..26e4d6f4ec04 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c @@ -358,3 +358,19 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = { .worker = mtk_vdec_worker, .flush_decoder = mtk_vdec_flush_decoder, }; + +const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = { + .chip = MTK_MT8192, + .init_vdec_params = mtk_init_vdec_params, + .ctrls_setup = mtk_vcodec_dec_ctrls_setup, + .vdec_vb2_ops = &mtk_vdec_request_vb2_ops, + .vdec_formats = mtk_video_formats, + .num_formats = NUM_FORMATS, + .default_out_fmt = &mtk_video_formats[DEFAULT_OUT_FMT_IDX], + .default_cap_fmt = &mtk_video_formats[DEFAULT_CAP_FMT_IDX], + .vdec_framesizes = mtk_vdec_framesizes, + .num_framesizes = NUM_SUPPORTED_FRAMESIZE, + .uses_stateless_api = true, + .worker = mtk_vdec_worker, + .flush_decoder = mtk_vdec_flush_decoder, +}; -- 2.25.1
[PATCH v11, 04/19] media: mtk-vcodec: export decoder pm functions
Register each hardware as platform device, need to call pm functions to open/close power and clock from module mtk-vcodec-dec, export these functions. Signed-off-by: Yunfei Dong --- drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c index 20bd157a855c..221cf60e9fbf 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c @@ -77,12 +77,14 @@ int mtk_vcodec_init_dec_pm(struct platform_device *pdev, put_device(pm->larbvdec); return ret; } +EXPORT_SYMBOL_GPL(mtk_vcodec_init_dec_pm); void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm) { pm_runtime_disable(pm->dev); put_device(pm->larbvdec); } +EXPORT_SYMBOL_GPL(mtk_vcodec_release_dec_pm); int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm) { @@ -94,6 +96,7 @@ int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm) return ret; } +EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_on); void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm) { @@ -103,6 +106,7 @@ void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm) if (ret) mtk_v4l2_err("pm_runtime_put_sync fail %d", ret); } +EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_off); void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm) { @@ -129,6 +133,7 @@ void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm) for (i -= 1; i >= 0; i--) clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk); } +EXPORT_SYMBOL_GPL(mtk_vcodec_dec_clock_on); void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm) { @@ -139,3 +144,4 @@ void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm) for (i = dec_clk->clk_num - 1; i >= 0; i--) clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk); } +EXPORT_SYMBOL_GPL(mtk_vcodec_dec_clock_off); -- 2.25.1
[PATCH v11, 07/19] dt-bindings: media: mtk-vcodec: Separate video encoder and decoder dt-bindings
Separate decoder and encoder document for the dts are big difference. Reviewed-by: Rob Herring Signed-off-by: Yunfei Dong --- .../media/mediatek,vcodec-decoder.yaml| 176 + .../media/mediatek,vcodec-encoder.yaml| 187 ++ .../bindings/media/mediatek-vcodec.txt| 131 3 files changed, 363 insertions(+), 131 deletions(-) create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml delete mode 100644 Documentation/devicetree/bindings/media/mediatek-vcodec.txt diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml new file mode 100644 index ..df1d677098fd --- /dev/null +++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml @@ -0,0 +1,176 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) + +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/mediatek,vcodec-decoder.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Mediatek Video Decode Accelerator + +maintainers: + - Yunfei Dong + +description: |+ + Mediatek Video Decode is the video decode hardware present in Mediatek + SoCs which supports high resolution decoding functionalities. + +properties: + compatible: +enum: + - mediatek,mt8173-vcodec-dec + - mediatek,mt8183-vcodec-dec + + reg: +maxItems: 12 + + interrupts: +maxItems: 1 + + clocks: +maxItems: 8 + + clock-names: +items: + - const: vcodecpll + - const: univpll_d2 + - const: clk_cci400_sel + - const: vdec_sel + - const: vdecpll + - const: vencpll + - const: venc_lt_sel + - const: vdec_bus_clk_src + + assigned-clocks: true + + assigned-clock-parents: true + + assigned-clock-rates: true + + power-domains: +maxItems: 1 + + iommus: +minItems: 1 +maxItems: 32 +description: | + List of the hardware port in respective IOMMU block for current Socs. + Refer to bindings/iommu/mediatek,iommu.yaml. + + dma-ranges: +maxItems: 1 +description: | + Describes the physical address space of IOMMU maps to memory. + + mediatek,larb: +$ref: /schemas/types.yaml#/definitions/phandle +maxItems: 1 +description: | + Must contain the local arbiters in the current Socs. + + mediatek,vpu: +$ref: /schemas/types.yaml#/definitions/phandle +maxItems: 1 +description: + Describes point to vpu. + + mediatek,scp: +$ref: /schemas/types.yaml#/definitions/phandle +maxItems: 1 +description: + Describes point to scp. + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - iommus + - assigned-clocks + - assigned-clock-parents + +allOf: + - if: + properties: +compatible: + contains: +enum: + - mediatek,mt8183-vcodec-dec + +then: + required: +- mediatek,scp + + - if: + properties: +compatible: + contains: +enum: + - mediatek,mt8173-vcodec-dec + +then: + required: +- mediatek,vpu + +additionalProperties: false + +examples: + - | +#include +#include +#include +#include +#include + +vcodec_dec: vcodec@1600 { + compatible = "mediatek,mt8173-vcodec-dec"; + reg = <0x1600 0x100>, /*VDEC_SYS*/ + <0x1602 0x1000>, /*VDEC_MISC*/ + <0x16021000 0x800>, /*VDEC_LD*/ + <0x16021800 0x800>, /*VDEC_TOP*/ + <0x16022000 0x1000>, /*VDEC_CM*/ + <0x16023000 0x1000>, /*VDEC_AD*/ + <0x16024000 0x1000>, /*VDEC_AV*/ + <0x16025000 0x1000>, /*VDEC_PP*/ + <0x16026800 0x800>, /*VP8_VD*/ + <0x16027000 0x800>, /*VP6_VD*/ + <0x16027800 0x800>, /*VP8_VL*/ + <0x16028400 0x400>; /*VP9_VD*/ + interrupts = ; + mediatek,larb = <&larb1>; + iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>, + <&iommu M4U_PORT_HW_VDEC_PP_EXT>, + <&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>, + <&iommu M4U_PORT_HW_VDEC_PRED_RD_EXT>, + <&iommu M4U_PORT_HW_VDEC_PRED_WR_EXT>, + <&iommu M4U_PORT_HW_VDEC_UFO_EXT>, + <&iommu M4U_PORT_HW_VDEC_VLD_EXT>, + <&iommu M4U_PORT_HW_VDEC_VLD2_EXT>; + mediatek,vpu = <&vpu>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>; + clocks = <&apmixedsys CLK_APMIXED_VCODECPLL>, + <&topckgen CLK_TOP_UNIVPLL_D2>, + <&topckgen CLK_TOP_CCI400_SEL>, + <&topckgen CLK_TOP_VDEC_SEL>, + <&topckgen CLK_TOP_VCODECPLL>, + <&apmixedsys CLK_APMIXED_VENCPLL>, + <&topckgen CLK_TOP_VENC_LT_SEL>, + <&topckgen CLK_TOP_VCODECPLL_370P5>; + clock-names = "vcodecpl
[PATCH v11, 13/19] media: mtk-vcodec: Add work queue for core hardware decode
Add work queue to process core hardware information. First, get lat_buf from message queue, then call core hardware of each codec(H264/VP9/AV1) to decode, finally puts lat_buf back to the message. Signed-off-by: Yunfei Dong --- .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 16 +++- .../platform/mtk-vcodec/mtk_vcodec_drv.h | 3 ++ .../platform/mtk-vcodec/vdec_msg_queue.c | 41 --- .../platform/mtk-vcodec/vdec_msg_queue.h | 8 ++-- 4 files changed, 57 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c index 2dbc3b8ece93..489165663400 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c @@ -342,6 +342,17 @@ static int mtk_vcodec_probe(struct platform_device *pdev) goto err_dec_pm; } + if (IS_VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch)) { + vdec_msg_queue_init_ctx(&dev->msg_queue_core_ctx, MTK_VDEC_CORE); + dev->core_workqueue = alloc_ordered_workqueue("core-decoder", + WQ_MEM_RECLAIM | WQ_FREEZABLE); + if (!dev->core_workqueue) { + mtk_v4l2_err("Failed to create core workqueue"); + ret = -EINVAL; + goto err_res; + } + } + for (i = 0; i < MTK_VDEC_HW_MAX; i++) mutex_init(&dev->dec_mutex[i]); spin_lock_init(&dev->irqlock); @@ -352,7 +363,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); if (ret) { mtk_v4l2_err("v4l2_device_register err=%d", ret); - goto err_res; + goto err_core_workq; } init_waitqueue_head(&dev->queue); @@ -451,6 +462,9 @@ static int mtk_vcodec_probe(struct platform_device *pdev) video_unregister_device(vfd_dec); err_dec_alloc: v4l2_device_unregister(&dev->v4l2_dev); +err_core_workq: + if (IS_VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch)) + destroy_workqueue(dev->core_workqueue); err_res: mtk_vcodec_release_dec_pm(&dev->pm); err_dec_pm: diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index cbaed96dcfa2..a558cc16026d 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h @@ -27,6 +27,7 @@ #define MTK_VCODEC_MAX_PLANES 3 #define MTK_V4L2_BENCHMARK 0 #define WAIT_INTR_TIMEOUT_MS 1000 +#define IS_VDEC_LAT_ARCH(hw_arch) ((hw_arch) >= MTK_VDEC_LAT_SINGLE_CORE) /* * enum mtk_hw_reg_idx - MTK hw register base index @@ -464,6 +465,7 @@ struct mtk_vcodec_enc_pdata { * @dec_capability: used to identify decode capability, ex: 4k * @enc_capability: used to identify encode capability * + * @core_workqueue: queue used for core hardware decode * @msg_queue_core_ctx: msg queue context used for core workqueue * * @subdev_dev: subdev hardware device @@ -506,6 +508,7 @@ struct mtk_vcodec_dev { unsigned int dec_capability; unsigned int enc_capability; + struct workqueue_struct *core_workqueue; struct vdec_msg_queue_ctx msg_queue_core_ctx; void *subdev_dev[MTK_VDEC_HW_MAX]; diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c index da4d114f7ad0..79411b73c45b 100644 --- a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c +++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c @@ -69,6 +69,9 @@ void vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *msg_ctx, if (msg_ctx->hardware_index != MTK_VDEC_CORE) wake_up_all(&msg_ctx->ready_to_use); + else + queue_work(buf->ctx->dev->core_workqueue, + &buf->ctx->msg_queue.core_work); mtk_v4l2_debug(3, "enqueue buf type: %d addr: 0x%p num: %d", msg_ctx->hardware_index, buf, msg_ctx->ready_num); @@ -170,8 +173,7 @@ bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue) return false; } -void vdec_msg_queue_deinit( - struct vdec_msg_queue *msg_queue, +void vdec_msg_queue_deinit(struct vdec_msg_queue *msg_queue, struct mtk_vcodec_ctx *ctx) { struct vdec_lat_buf *lat_buf; @@ -197,10 +199,36 @@ void vdec_msg_queue_deinit( } } -int vdec_msg_queue_init( - struct vdec_msg_queue *msg_queue, - struct mtk_vcodec_ctx *ctx, - core_decode_cb_t core_decode, +static void vdec_msg_queue_core_work(struct work_struct *work) +{ + struct vdec_msg_queue *msg_queue = + container_of(work, struct vdec_msg_queue, core_work); + struct mtk_vcodec_ctx *ctx = + container_of(msg_queue, struct mtk_vcodec_ctx, msg_queue); +
[PATCH v11, 09/19] media: mtk-vcodec: Add irq interface for multi hardware
Adds irq interface for multi hardware. Signed-off-by: Yunfei Dong --- .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 33 --- .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c | 2 +- .../platform/mtk-vcodec/mtk_vcodec_drv.h | 25 ++ .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c | 4 +-- .../platform/mtk-vcodec/mtk_vcodec_intr.c | 27 +++ .../platform/mtk-vcodec/mtk_vcodec_intr.h | 4 +-- .../platform/mtk-vcodec/vdec/vdec_h264_if.c | 2 +- .../mtk-vcodec/vdec/vdec_h264_req_if.c| 2 +- .../platform/mtk-vcodec/vdec/vdec_vp8_if.c| 2 +- .../platform/mtk-vcodec/vdec/vdec_vp9_if.c| 2 +- .../platform/mtk-vcodec/venc/venc_h264_if.c | 2 +- .../platform/mtk-vcodec/venc/venc_vp8_if.c| 2 +- 12 files changed, 70 insertions(+), 37 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c index 95fbe9be3f6d..ac279c2a3f8a 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c @@ -52,6 +52,20 @@ static int mtk_vcodec_subdev_device_check(struct mtk_vcodec_dev *vdec_dev) return 0; } +static int mtk_vcodec_get_hw_count(struct mtk_vcodec_dev *dev) +{ + switch (dev->vdec_pdata->hw_arch) { + case MTK_VDEC_PURE_SINGLE_CORE: +return MTK_VDEC_ONE_CORE; + case MTK_VDEC_LAT_SINGLE_CORE: + return MTK_VDEC_ONE_LAT_ONE_CORE; + default: + mtk_v4l2_err("not support hw arch:%d", + dev->vdec_pdata->hw_arch); + return MTK_VDEC_NO_HW; + } +} + static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv) { struct mtk_vcodec_dev *dev = priv; @@ -83,7 +97,7 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv) writel((readl(vdec_misc_addr) & ~VDEC_IRQ_CLR), dev->reg_base[VDEC_MISC] + VDEC_IRQ_CFG_REG); - wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED); + wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0); mtk_v4l2_debug(3, "mtk_vcodec_dec_irq_handler :wake up ctx %d, dec_done_status=%x", @@ -156,7 +170,7 @@ static int fops_vcodec_open(struct file *file) { struct mtk_vcodec_dev *dev = video_drvdata(file); struct mtk_vcodec_ctx *ctx = NULL; - int ret = 0; + int ret = 0, i, hw_count; struct vb2_queue *src_vq; ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); @@ -170,9 +184,20 @@ static int fops_vcodec_open(struct file *file) v4l2_fh_add(&ctx->fh); INIT_LIST_HEAD(&ctx->list); ctx->dev = dev; - init_waitqueue_head(&ctx->queue); - mutex_init(&ctx->lock); + if (ctx->dev->vdec_pdata->is_subdev_supported) { + hw_count = mtk_vcodec_get_hw_count(dev); + if (!hw_count) { + ret = -EINVAL; + goto err_ctrls_setup; + } + for (i = 0; i < hw_count; i++) + init_waitqueue_head(&ctx->queue[i]); + } else { + init_waitqueue_head(&ctx->queue[0]); + } + + mutex_init(&ctx->lock); ret = mtk_vcodec_subdev_device_check(dev); if (ret) { mtk_v4l2_err("Failed to check vdec comp device."); diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c index 025a103008ba..8bd23504cf4c 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c @@ -61,7 +61,7 @@ static irqreturn_t mtk_vdec_hw_irq_handler(int irq, void *priv) writel(dec_done_status | VDEC_IRQ_CFG, vdec_misc_addr); writel(dec_done_status & ~VDEC_IRQ_CLR, vdec_misc_addr); - wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED); + wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, dev->hw_idx); mtk_v4l2_debug(3, "wake up ctx %d, dec_done_status=%x", ctx->id, dec_done_status); diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index 79957222c979..7fc106df039b 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h @@ -104,6 +104,16 @@ enum mtk_vdec_hw_id { MTK_VDEC_HW_MAX, }; +/** + * struct mtk_vdec_hw_count - Supported hardware count + */ +enum mtk_vdec_hw_count { + MTK_VDEC_NO_HW = 0, + MTK_VDEC_ONE_CORE, + MTK_VDEC_ONE_LAT_ONE_CORE, + MTK_VDEC_MAX_HW_COUNT, +}; + /* * struct mtk_video_fmt - Structure used to store information about pixelformats */ @@ -293,9 +303,9 @@ struct mtk_vcodec_ctx { struct vdec_pic_info picinfo; int dpb_size; - int int_cond; - int int_type; - wait_queue_head_t queue; + int int_cond[MTK_VDEC_HW_MAX]; + int
[PATCH v11, 08/19] media: mtk-vcodec: Use pure single core for MT8183
Separates different architecture for hardware: pure_sin_core and lat_sin_core. MT8183 is pure single core. Uses .hw_arch to distinguish. Signed-off-by: Yunfei Dong Reviewed-by: AngeloGioacchino Del Regno --- .../platform/mtk-vcodec/mtk_vcodec_dec_stateful.c | 1 + .../platform/mtk-vcodec/mtk_vcodec_dec_stateless.c | 2 ++ drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h | 10 ++ 3 files changed, 13 insertions(+) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c index c7f9259ad094..04ca43c77e5f 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c @@ -626,4 +626,5 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = { .worker = mtk_vdec_worker, .flush_decoder = mtk_vdec_flush_decoder, .is_subdev_supported = false, + .hw_arch = MTK_VDEC_PURE_SINGLE_CORE, }; diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c index 2d285515b625..d98f49fbbc3b 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c @@ -358,6 +358,7 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = { .worker = mtk_vdec_worker, .flush_decoder = mtk_vdec_flush_decoder, .is_subdev_supported = false, + .hw_arch = MTK_VDEC_PURE_SINGLE_CORE, }; const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = { @@ -375,4 +376,5 @@ const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = { .worker = mtk_vdec_worker, .flush_decoder = mtk_vdec_flush_decoder, .is_subdev_supported = true, + .hw_arch = MTK_VDEC_LAT_SINGLE_CORE, }; diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index 2160f26263ef..79957222c979 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h @@ -324,6 +324,14 @@ enum mtk_chip { MTK_MT8195, }; +/** + * struct mtk_vdec_hw_arch - Used to separate different hardware architecture + */ +enum mtk_vdec_hw_arch { + MTK_VDEC_PURE_SINGLE_CORE, + MTK_VDEC_LAT_SINGLE_CORE, +}; + /** * struct mtk_vcodec_dec_pdata - compatible data for each IC * @init_vdec_params: init vdec params @@ -342,6 +350,7 @@ enum mtk_chip { * @num_framesizes: count of video decoder frame sizes * * @chip: chip this decoder is compatible with + * @hw_arch: hardware arch is used to separate pure_sin_core and lat_sin_core * * @is_subdev_supported: whether support parent-node architecture(subdev) * @uses_stateless_api: whether the decoder uses the stateless API with requests @@ -364,6 +373,7 @@ struct mtk_vcodec_dec_pdata { const int num_framesizes; enum mtk_chip chip; + enum mtk_vdec_hw_arch hw_arch; bool is_subdev_supported; bool uses_stateless_api; -- 2.25.1
[PATCH v11, 06/19] media: mtk-vcodec: Add to support multi hardware decode
There are more than two hardwares for decoder: LAT0, LAT1 and CORE. In order to manage these hardwares, register each hardware as independent platform device for the larbs are different. Each hardware module controls its own information which includes interrupt/power/ clocks/registers. Calling of_platform_populate in parent device, and use subdev_bitmap to record whether the hardwares are registered done. Signed-off-by: Yunfei Dong --- Add more detail commit message. Fix comments from tzung-bi. --- drivers/media/platform/mtk-vcodec/Makefile| 5 +- .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 111 +++ .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c | 172 ++ .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h | 51 ++ .../mtk-vcodec/mtk_vcodec_dec_stateful.c | 1 + .../mtk-vcodec/mtk_vcodec_dec_stateless.c | 2 + .../platform/mtk-vcodec/mtk_vcodec_drv.h | 19 ++ 7 files changed, 329 insertions(+), 32 deletions(-) create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile index ca8e9e7a9c4e..c61bfb179bcc 100644 --- a/drivers/media/platform/mtk-vcodec/Makefile +++ b/drivers/media/platform/mtk-vcodec/Makefile @@ -2,7 +2,8 @@ obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-dec.o \ mtk-vcodec-enc.o \ - mtk-vcodec-common.o + mtk-vcodec-common.o \ + mtk-vcodec-dec-hw.o mtk-vcodec-dec-y := vdec/vdec_h264_if.o \ vdec/vdec_vp8_if.o \ @@ -16,6 +17,8 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \ mtk_vcodec_dec_stateless.o \ mtk_vcodec_dec_pm.o \ +mtk-vcodec-dec-hw-y := mtk_vcodec_dec_hw.o + mtk-vcodec-enc-y := venc/venc_vp8_if.o \ venc/venc_h264_if.o \ mtk_vcodec_enc.o \ diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c index b7a51e96d4ba..95fbe9be3f6d 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c @@ -18,19 +18,40 @@ #include "mtk_vcodec_drv.h" #include "mtk_vcodec_dec.h" +#include "mtk_vcodec_dec_hw.h" #include "mtk_vcodec_dec_pm.h" #include "mtk_vcodec_intr.h" #include "mtk_vcodec_util.h" #include "mtk_vcodec_fw.h" -#define VDEC_HW_ACTIVE 0x10 -#define VDEC_IRQ_CFG 0x11 -#define VDEC_IRQ_CLR 0x10 -#define VDEC_IRQ_CFG_REG 0xa4 - module_param(mtk_v4l2_dbg_level, int, 0644); module_param(mtk_vcodec_dbg, bool, 0644); +static int mtk_vcodec_subdev_device_check(struct mtk_vcodec_dev *vdec_dev) +{ + struct platform_device *pdev = vdec_dev->plat_dev; + struct device_node *subdev_node; + enum mtk_vdec_hw_id hw_idx; + const struct of_device_id *of_id; + int i; + + for (i = 0; i < ARRAY_SIZE(mtk_vdec_hw_match); i++) { + of_id = &mtk_vdec_hw_match[i]; + subdev_node = of_find_compatible_node(NULL, NULL, + of_id->compatible); + if (!subdev_node) + continue; + + hw_idx = (enum mtk_vdec_hw_id)(uintptr_t)of_id->data; + if (!test_bit(hw_idx, vdec_dev->subdev_bitmap)) { + dev_err(&pdev->dev, "Vdec %d is not ready", hw_idx); + return -EAGAIN; + } + } + + return 0; +} + static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv) { struct mtk_vcodec_dev *dev = priv; @@ -95,6 +116,42 @@ static int mtk_vcodec_get_reg_bases(struct mtk_vcodec_dev *dev) return 0; } +static int mtk_vcodec_init_dec_resources(struct mtk_vcodec_dev *dev) +{ + struct platform_device *pdev = dev->plat_dev; + int ret; + + ret = mtk_vcodec_get_reg_bases(dev); + if (ret) + return ret; + + if (dev->vdec_pdata->is_subdev_supported) + return 0; + + dev->dec_irq = platform_get_irq(pdev, 0); + if (dev->dec_irq < 0) { + dev_err(&pdev->dev, "failed to get irq number"); + return dev->dec_irq; + } + + irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN); + ret = devm_request_irq(&pdev->dev, dev->dec_irq, + mtk_vcodec_dec_irq_handler, 0, pdev->name, dev); + if (ret) { + dev_err(&pdev->dev, "failed to install dev->dec_irq %d (%d)", + dev->dec_irq, ret); + return ret; + } + + ret = mtk_vcodec_init_dec_pm(pdev, &dev->pm); + if (ret < 0) { + dev_err(&pdev->dev, "failed to get mt vcodec clock source"); + return ret; + } + + return 0; +} + static
[PATCH v11, 16/19] media: mtk-vcodec: Add core dec and dec end ipi msg
Add core dec and dec end ipi msg: AP_IPIMSG_DEC_CORE/AP_IPIMSG_DEC_CORE_END. Signed-off-by: Yunfei Dong Reviewed-by: AngeloGioacchino Del Regno --- .../media/platform/mtk-vcodec/vdec_ipi_msg.h | 4 .../media/platform/mtk-vcodec/vdec_vpu_if.c| 12 .../media/platform/mtk-vcodec/vdec_vpu_if.h| 18 ++ 3 files changed, 34 insertions(+) diff --git a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h index 5f45a537beb4..9d8079c4f976 100644 --- a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h +++ b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h @@ -18,12 +18,16 @@ enum vdec_ipi_msgid { AP_IPIMSG_DEC_END = 0xA002, AP_IPIMSG_DEC_DEINIT = 0xA003, AP_IPIMSG_DEC_RESET = 0xA004, + AP_IPIMSG_DEC_CORE = 0xA005, + AP_IPIMSG_DEC_CORE_END = 0xA006, VPU_IPIMSG_DEC_INIT_ACK = 0xB000, VPU_IPIMSG_DEC_START_ACK = 0xB001, VPU_IPIMSG_DEC_END_ACK = 0xB002, VPU_IPIMSG_DEC_DEINIT_ACK = 0xB003, VPU_IPIMSG_DEC_RESET_ACK = 0xB004, + VPU_IPIMSG_DEC_CORE_ACK = 0xB005, + VPU_IPIMSG_DEC_CORE_END_ACK = 0xB006, }; /** diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c index 5dffc459a33d..bfd8e87dceff 100644 --- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c +++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c @@ -85,6 +85,8 @@ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv) case VPU_IPIMSG_DEC_END_ACK: case VPU_IPIMSG_DEC_DEINIT_ACK: case VPU_IPIMSG_DEC_RESET_ACK: + case VPU_IPIMSG_DEC_CORE_ACK: + case VPU_IPIMSG_DEC_CORE_END_ACK: break; default: @@ -191,11 +193,21 @@ int vpu_dec_start(struct vdec_vpu_inst *vpu, uint32_t *data, unsigned int len) return err; } +int vpu_dec_core(struct vdec_vpu_inst *vpu) +{ + return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_CORE); +} + int vpu_dec_end(struct vdec_vpu_inst *vpu) { return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_END); } +int vpu_dec_core_end(struct vdec_vpu_inst *vpu) +{ + return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_CORE_END); +} + int vpu_dec_deinit(struct vdec_vpu_inst *vpu) { return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_DEINIT); diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h index c2ed5b6cab8b..ae24b75d1649 100644 --- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h +++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h @@ -82,4 +82,22 @@ int vpu_dec_deinit(struct vdec_vpu_inst *vpu); */ int vpu_dec_reset(struct vdec_vpu_inst *vpu); +/** + * vpu_dec_core - core start decoding, basically the function will be invoked once + * every frame. + * + * @vpu : instance for vdec_vpu_inst + */ +int vpu_dec_core(struct vdec_vpu_inst *vpu); + +/** + * vpu_dec_core_end - core end decoding, basically the function will be invoked once + * when core HW decoding done and receive interrupt successfully. The + * decoder in VPU will updata hardware information and deinit hardware + * and check if there is a new decoded frame available to display. + * + * @vpu : instance for vdec_vpu_inst + */ +int vpu_dec_core_end(struct vdec_vpu_inst *vpu); + #endif -- 2.25.1
[PATCH v11, 15/19] dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for mt8192
Adds decoder dt-bindings for mt8192. Signed-off-by: Yunfei Dong --- Change example dtsi node. Add more information for hardware block diagram. --- .../media/mediatek,vcodec-subdev-decoder.yaml | 266 ++ 1 file changed, 266 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml new file mode 100644 index ..bd487be30256 --- /dev/null +++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml @@ -0,0 +1,266 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) + +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/media/mediatek,vcodec-subdev-decoder.yaml#"; +$schema: "http://devicetree.org/meta-schemas/core.yaml#"; + +title: Mediatek Video Decode Accelerator With Multi Hardware + +maintainers: + - Yunfei Dong + +description: | + Mediatek Video Decode is the video decode hardware present in Mediatek + SoCs which supports high resolution decoding functionalities. Required + parent and child device node. + + About the Decoder Hardware Block Diagram, please check below: + ++-++ +| || +| input -> lat HW -> lat buffer --|--> lat buffer -> core HW -> output | +||| | || | ++||---+-||-+ + lat workqueue | core workqueue + -||-||-- + || || + \/\/ + +--+ + |enable/disable| + | clk powerirqiommu | + | (lat/lat soc/core0/core1)| + +--+ + + As above, there are parent and child devices, child mean each hardware. The child device + controls the information of each hardware independent which include clk/power/irq. + + There are two workqueues in parent device: lat workqueue and core workqueue. They are used + to lat and core hardware deocder. Lat workqueue need to get input bitstream and lat buffer, + then enable lat to decode, writing the result to lat buffer, dislabe hardware when lat decode + done. Core workqueue need to get lat buffer and output buffer, then enable core to decode, + writing the result to output buffer, disable hardware when core decode done. These two + hardwares will decode each frame cyclically. + + For the smi common may not the same for each hardware, can't combine all hardware in one node, + or leading to iommu fault when access dram data. + +properties: + compatible: +const: mediatek,mt8192-vcodec-dec + + reg: +maxItems: 1 + + iommus: +minItems: 1 +maxItems: 32 +description: | + List of the hardware port in respective IOMMU block for current Socs. + Refer to bindings/iommu/mediatek,iommu.yaml. + + mediatek,scp: +$ref: /schemas/types.yaml#/definitions/phandle +maxItems: 1 +description: | + The node of system control processor (SCP), using + the remoteproc & rpmsg framework. + $ref: /schemas/remoteproc/mtk,scp.yaml + + dma-ranges: +maxItems: 1 +description: | + Describes the physical address space of IOMMU maps to memory. + + "#address-cells": +const: 1 + + "#size-cells": +const: 1 + + ranges: true + +# Required child node: +patternProperties: + vcodec-lat: +type: object + +properties: + compatible: +const: mediatek,mtk-vcodec-lat + + reg: +maxItems: 1 + + interrupts: +maxItems: 1 + + iommus: +minItems: 1 +maxItems: 32 +description: | + List of the hardware port in respective IOMMU block for current Socs. + Refer to bindings/iommu/mediatek,iommu.yaml. + + clocks: +maxItems: 5 + + clock-names: +items: + - const: sel + - const: soc-vdec + - const: soc-lat + - const: vdec + - const: top + + assigned-clocks: +maxItems: 1 + + assigned-clock-parents: +maxItems: 1 + + power-domains: +maxItems: 1 + +required: + - compatible + - reg + - interrupts + - iommus + - clocks + - clock-names + - assigned-clocks + - assigned-clock-parents + - power-domains + +additionalProperties: false + + vcodec-core: +type: o
[PATCH v11, 11/19] media: mtk-vcodec: Generalize power and clock on/off interfaces
Generalizes power and clock on/off interfaces to support different hardware. Signed-off-by: Yunfei Dong --- .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 6 +- .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c | 2 +- .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h | 4 + .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c | 76 +-- .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h | 8 +- .../platform/mtk-vcodec/mtk_vcodec_drv.h | 2 + .../platform/mtk-vcodec/mtk_vcodec_util.c | 60 --- .../platform/mtk-vcodec/mtk_vcodec_util.h | 8 +- .../media/platform/mtk-vcodec/vdec_drv_if.c | 21 ++--- 9 files changed, 147 insertions(+), 40 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c index ac279c2a3f8a..001cdf447ab8 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c @@ -75,7 +75,7 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv) void __iomem *vdec_misc_addr = dev->reg_base[VDEC_MISC] + VDEC_IRQ_CFG_REG; - ctx = mtk_vcodec_get_curr_ctx(dev); + ctx = mtk_vcodec_get_curr_ctx(dev, MTK_VDEC_CORE); /* check if HW active or not */ cg_status = readl(dev->reg_base[0]); @@ -224,7 +224,7 @@ static int fops_vcodec_open(struct file *file) mtk_vcodec_dec_set_default_params(ctx); if (v4l2_fh_is_singular(&ctx->fh)) { - ret = mtk_vcodec_dec_pw_on(&dev->pm); + ret = mtk_vcodec_dec_pw_on(dev, MTK_VDEC_LAT0); if (ret < 0) goto err_load_fw; /* @@ -284,7 +284,7 @@ static int fops_vcodec_release(struct file *file) mtk_vcodec_dec_release(ctx); if (v4l2_fh_is_singular(&ctx->fh)) - mtk_vcodec_dec_pw_off(&dev->pm); + mtk_vcodec_dec_pw_off(dev, MTK_VDEC_LAT0); v4l2_fh_del(&ctx->fh); v4l2_fh_exit(&ctx->fh); v4l2_ctrl_handler_free(&ctx->ctrl_hdl); diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c index 8bd23504cf4c..389a17eb4085 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c @@ -42,7 +42,7 @@ static irqreturn_t mtk_vdec_hw_irq_handler(int irq, void *priv) void __iomem *vdec_misc_addr = dev->reg_base[VDEC_HW_MISC] + VDEC_IRQ_CFG_REG; - ctx = mtk_vcodec_get_curr_ctx(dev->main_dev); + ctx = mtk_vcodec_get_curr_ctx(dev->main_dev, dev->hw_idx); /* check if HW active or not */ cg_status = readl(dev->reg_base[VDEC_HW_SYS]); diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h index f7f36790629d..fdf1435fc932 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h @@ -34,6 +34,8 @@ enum mtk_vdec_hw_reg_idx { * @main_dev: main device * @reg_base: Mapped address of MTK Vcodec registers. * + * @curr_ctx: the context that is waiting for codec hardware + * * @dec_irq: decoder irq resource * @pm: power management control * @hw_idx: each hardware index @@ -43,6 +45,8 @@ struct mtk_vdec_hw_dev { struct mtk_vcodec_dev *main_dev; void __iomem *reg_base[VDEC_HW_MAX]; + struct mtk_vcodec_ctx *curr_ctx; + int dec_irq; struct mtk_vcodec_pm pm; int hw_idx; diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c index 221cf60e9fbf..4cf03d38d141 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c @@ -5,11 +5,13 @@ */ #include +#include #include #include #include #include +#include "mtk_vcodec_dec_hw.h" #include "mtk_vcodec_dec_pm.h" #include "mtk_vcodec_util.h" @@ -86,10 +88,23 @@ void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm) } EXPORT_SYMBOL_GPL(mtk_vcodec_release_dec_pm); -int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm) +int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx) { + struct mtk_vdec_hw_dev *subdev_dev; + struct mtk_vcodec_pm *pm; int ret; + if (vdec_dev->vdec_pdata->is_subdev_supported) { + subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx); + if (!subdev_dev) { + mtk_v4l2_err("Failed to get hw dev\n"); + return -EINVAL; + } + pm = &subdev_dev->pm; + } else { + pm = &vdec_dev->pm; + } + ret = pm_runtime_resume_and_get(pm->dev); if (ret) mtk_v4l2_err("pm_runtime_resume_and_ge
[PATCH v11, 10/19] media: mtk-vcodec: Add msg queue feature for lat and core architecture
For lat and core architecture, lat thread will send message to core thread when lat decode done. Core hardware will use the message from lat to decode, then free message to lat thread when decode done. Signed-off-by: Yunfei Dong --- drivers/media/platform/mtk-vcodec/Makefile| 1 + .../platform/mtk-vcodec/mtk_vcodec_drv.h | 9 + .../platform/mtk-vcodec/vdec_msg_queue.c | 257 ++ .../platform/mtk-vcodec/vdec_msg_queue.h | 148 ++ 4 files changed, 415 insertions(+) create mode 100644 drivers/media/platform/mtk-vcodec/vdec_msg_queue.c create mode 100644 drivers/media/platform/mtk-vcodec/vdec_msg_queue.h diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile index c61bfb179bcc..359619653a0e 100644 --- a/drivers/media/platform/mtk-vcodec/Makefile +++ b/drivers/media/platform/mtk-vcodec/Makefile @@ -12,6 +12,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \ mtk_vcodec_dec_drv.o \ vdec_drv_if.o \ vdec_vpu_if.o \ + vdec_msg_queue.o \ mtk_vcodec_dec.o \ mtk_vcodec_dec_stateful.o \ mtk_vcodec_dec_stateless.o \ diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index 7fc106df039b..610b0af13879 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h @@ -15,7 +15,9 @@ #include #include #include + #include "mtk_vcodec_util.h" +#include "vdec_msg_queue.h" #define MTK_VCODEC_DRV_NAME"mtk_vcodec_drv" #define MTK_VCODEC_DEC_NAME"mtk-vcodec-dec" @@ -282,6 +284,8 @@ struct vdec_pic_info { * @decoded_frame_cnt: number of decoded frames * @lock: protect variables accessed by V4L2 threads and worker thread such as * mtk_video_dec_buf. + * + * @msg_queue: msg queue used to store lat buffer information. */ struct mtk_vcodec_ctx { enum mtk_instance_type type; @@ -325,6 +329,7 @@ struct mtk_vcodec_ctx { int decoded_frame_cnt; struct mutex lock; + struct vdec_msg_queue msg_queue; }; enum mtk_chip { @@ -457,6 +462,8 @@ struct mtk_vcodec_enc_pdata { * @dec_capability: used to identify decode capability, ex: 4k * @enc_capability: used to identify encode capability * + * @msg_queue_core_ctx: msg queue context used for core workqueue + * * @subdev_dev: subdev hardware device * @subdev_bitmap: used to record hardware is ready or not */ @@ -497,6 +504,8 @@ struct mtk_vcodec_dev { unsigned int dec_capability; unsigned int enc_capability; + struct vdec_msg_queue_ctx msg_queue_core_ctx; + void *subdev_dev[MTK_VDEC_HW_MAX]; DECLARE_BITMAP(subdev_bitmap, MTK_VDEC_HW_MAX); }; diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c new file mode 100644 index ..da4d114f7ad0 --- /dev/null +++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c @@ -0,0 +1,257 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 MediaTek Inc. + * Author: Yunfei Dong + */ + +#include +#include +#include + +#include "mtk_vcodec_dec_pm.h" +#include "mtk_vcodec_drv.h" +#include "vdec_msg_queue.h" + +/* the size used to store lat slice header information */ +#define VDEC_LAT_SLICE_HEADER_SZ(640 * SZ_1K) + +/* the size used to store avc error information */ +#define VDEC_ERR_MAP_SZ_AVC (17 * SZ_1K) + +/* core will read the trans buffer which decoded by lat to decode again. + * The trans buffer size of FHD and 4K bitstreams are different. + */ +static int vde_msg_queue_get_trans_size(int width, int height) +{ + if (width > 1920 || height > 1088) + return 30 * SZ_1M; + else + return 6 * SZ_1M; +} + +void vdec_msg_queue_init_ctx(struct vdec_msg_queue_ctx *ctx, + int hardware_index) +{ + init_waitqueue_head(&ctx->ready_to_use); + INIT_LIST_HEAD(&ctx->ready_queue); + spin_lock_init(&ctx->ready_lock); + ctx->ready_num = 0; + ctx->hardware_index = hardware_index; +} + +static struct list_head *vdec_get_buf_list(int hardware_index, + struct vdec_lat_buf *buf) +{ + switch (hardware_index) { + case MTK_VDEC_CORE: + return &buf->core_list; + case MTK_VDEC_LAT0: + return &buf->lat_list; + default: + return NULL; + } +} + +void vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *msg_ctx, + struct vdec_lat_buf *buf) +{ + struct list_head *head; + + head = vdec_get_buf_list(msg_ctx->hardware_index, buf); + if (!head) { + mtk_v4l2_err("fail to qbuf: %d",msg_ctx->hardware_index); + return; + } + + spin_lock(&msg_ctx->ready_lock); + list_add_tail(head, &msg_ctx->ready_queue); + msg_ctx->ready_num++; + + if (ms
[PATCH v11, 14/19] media: mtk-vcodec: Support 34bits dma address for vdec
Use the dma_set_mask_and_coherent helper to set vdec DMA bit mask to support 34bits iova space(16GB) that the mt8192 iommu HW support. Whole the iova range separate to 0~4G/4G~8G/8G~12G/12G~16G, regarding which iova range VDEC actually locate, it depends on the dma-ranges property of vdec dtsi node. Signed-off-by: Yunfei Dong --- drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c index 489165663400..e6af9ed506ac 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c @@ -353,6 +353,14 @@ static int mtk_vcodec_probe(struct platform_device *pdev) } } + if (of_get_property(pdev->dev.of_node, "dma-ranges", NULL)) { + ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(34)); + if (ret) { + mtk_v4l2_err("Failed to set mask"); + goto err_core_workq; + } + } + for (i = 0; i < MTK_VDEC_HW_MAX; i++) mutex_init(&dev->dec_mutex[i]); spin_lock_init(&dev->irqlock); -- 2.25.1
[PATCH v11, 12/19] media: mtk-vcodec: Add new interface to lock different hardware
For add new hardware, not only need to lock lat hardware, also need to lock core hardware in case of different instance start to decoder at the same time. Signed-off-by: Yunfei Dong Reviewed-by: AngeloGioacchino Del Regno --- drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 4 ++-- drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 6 +++--- drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c index 2b334a8a81c6..130ecef2e766 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c @@ -105,12 +105,12 @@ static int vidioc_decoder_cmd(struct file *file, void *priv, void mtk_vdec_unlock(struct mtk_vcodec_ctx *ctx) { - mutex_unlock(&ctx->dev->dec_mutex); + mutex_unlock(&ctx->dev->dec_mutex[ctx->hw_id]); } void mtk_vdec_lock(struct mtk_vcodec_ctx *ctx) { - mutex_lock(&ctx->dev->dec_mutex); + mutex_lock(&ctx->dev->dec_mutex[ctx->hw_id]); } void mtk_vcodec_dec_release(struct mtk_vcodec_ctx *ctx) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c index 001cdf447ab8..2dbc3b8ece93 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c @@ -310,7 +310,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) struct video_device *vfd_dec; phandle rproc_phandle; enum mtk_vcodec_fw_type fw_type; - int ret; + int i, ret; dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); if (!dev) @@ -342,8 +342,8 @@ static int mtk_vcodec_probe(struct platform_device *pdev) goto err_dec_pm; } - mutex_init(&dev->dec_mutex); - mutex_init(&dev->dev_mutex); + for (i = 0; i < MTK_VDEC_HW_MAX; i++) + mutex_init(&dev->dec_mutex[i]); spin_lock_init(&dev->irqlock); snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s", diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index 5d5376fcf0a7..cbaed96dcfa2 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h @@ -499,7 +499,7 @@ struct mtk_vcodec_dev { int dec_irq; int enc_irq; - struct mutex dec_mutex; + struct mutex dec_mutex[MTK_VDEC_HW_MAX]; struct mutex enc_mutex; struct mtk_vcodec_pm pm; -- 2.25.1
[PATCH v11, 19/19] media: mtk-vcodec: Remove mtk_vcodec_release_enc_pm
There are only two lines in mtk_vcodec_release_enc_pm, using pm_runtime_disable and put_device instead directly. Move pm_runtime_enable outside mtk_vcodec_release_enc_pm to symmetry with pm_runtime_disable, after that, rename mtk_vcodec_init_enc_pm to *_clk since it only has clock operations now. Signed-off-by: Yunfei Dong Co-developed-by: Yong Wu --- drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c | 9 ++--- drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c | 9 + drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h | 3 +-- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c index 0f326d82dea0..7816efb90cbe 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -260,7 +261,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) return PTR_ERR(dev->fw_handler); dev->venc_pdata = of_device_get_match_data(&pdev->dev); - ret = mtk_vcodec_init_enc_pm(dev); + ret = mtk_vcodec_init_enc_clk(dev); if (ret < 0) { dev_err(&pdev->dev, "Failed to get mtk vcodec clock source!"); goto err_enc_pm; @@ -372,7 +373,8 @@ static int mtk_vcodec_probe(struct platform_device *pdev) err_enc_alloc: v4l2_device_unregister(&dev->v4l2_dev); err_res: - mtk_vcodec_release_enc_pm(dev); + pm_runtime_disable(dev->pm.dev); + put_device(dev->pm.larbvenc); err_enc_pm: mtk_vcodec_fw_release(dev->fw_handler); return ret; @@ -462,7 +464,8 @@ static int mtk_vcodec_enc_remove(struct platform_device *pdev) video_unregister_device(dev->vfd_enc); v4l2_device_unregister(&dev->v4l2_dev); - mtk_vcodec_release_enc_pm(dev); + pm_runtime_disable(dev->pm.dev); + put_device(dev->pm.larbvenc); mtk_vcodec_fw_release(dev->fw_handler); return 0; } diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c index 0c8c8f86788c..0825c6ec4eb7 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c @@ -13,7 +13,7 @@ #include "mtk_vcodec_enc_pm.h" #include "mtk_vcodec_util.h" -int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev) +int mtk_vcodec_init_enc_clk(struct mtk_vcodec_dev *mtkdev) { struct device_node *node; struct platform_device *pdev; @@ -86,13 +86,6 @@ int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev) return ret; } -void mtk_vcodec_release_enc_pm(struct mtk_vcodec_dev *mtkdev) -{ - pm_runtime_disable(mtkdev->pm.dev); - put_device(mtkdev->pm.larbvenc); -} - - void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm) { struct mtk_vcodec_clk *enc_clk = &pm->venc_clk; diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h index b7ecdfd74823..bc455cefc0cd 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h @@ -9,8 +9,7 @@ #include "mtk_vcodec_drv.h" -int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *dev); -void mtk_vcodec_release_enc_pm(struct mtk_vcodec_dev *dev); +int mtk_vcodec_init_enc_clk(struct mtk_vcodec_dev *dev); void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm); void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm); -- 2.25.1
[PATCH v11, 18/19] media: mtk-vcodec: Remove mtk_vcodec_release_dec_pm
There are only two lines in mtk_vcodec_release_dec_pm, using pm_runtime_disable and put_device instead directly. Move pm_runtime_enable outside mtk_vcodec_init_dec_pm to symmetry with pm_runtime_disable, after that, rename mtk_vcodec_init_dec_pm to *_clk since it only has clock operations now. Signed-off-by: Yunfei Dong Co-developed-by: Yong Wu --- .../media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 10 +++--- .../media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c| 7 +-- .../media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c| 12 ++-- .../media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h| 3 +-- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c index e6af9ed506ac..5b732b76f64c 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -157,12 +158,13 @@ static int mtk_vcodec_init_dec_resources(struct mtk_vcodec_dev *dev) return ret; } - ret = mtk_vcodec_init_dec_pm(pdev, &dev->pm); + ret = mtk_vcodec_init_dec_clk(pdev, &dev->pm); if (ret < 0) { dev_err(&pdev->dev, "failed to get mt vcodec clock source"); return ret; } + pm_runtime_enable(&pdev->dev); return 0; } @@ -474,7 +476,8 @@ static int mtk_vcodec_probe(struct platform_device *pdev) if (IS_VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch)) destroy_workqueue(dev->core_workqueue); err_res: - mtk_vcodec_release_dec_pm(&dev->pm); + pm_runtime_disable(dev->pm.dev); + put_device(dev->pm.larbvdec); err_dec_pm: mtk_vcodec_fw_release(dev->fw_handler); return ret; @@ -518,7 +521,8 @@ static int mtk_vcodec_dec_remove(struct platform_device *pdev) video_unregister_device(dev->vfd_dec); v4l2_device_unregister(&dev->v4l2_dev); - mtk_vcodec_release_dec_pm(&dev->pm); + pm_runtime_disable(dev->pm.dev); + put_device(dev->pm.larbvdec); mtk_vcodec_fw_release(dev->fw_handler); return 0; } diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c index 389a17eb4085..34dd178e07d7 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "mtk_vcodec_drv.h" @@ -117,9 +118,10 @@ static int mtk_vdec_hw_probe(struct platform_device *pdev) return -ENOMEM; subdev_dev->plat_dev = pdev; - ret = mtk_vcodec_init_dec_pm(pdev, &subdev_dev->pm); + ret = mtk_vcodec_init_dec_clk(pdev, &subdev_dev->pm); if (ret) return ret; + pm_runtime_enable(&pdev->dev); subdev_dev->reg_base[VDEC_HW_MISC] = devm_platform_ioremap_resource(pdev, 0); @@ -155,7 +157,8 @@ static int mtk_vdec_hw_probe(struct platform_device *pdev) platform_set_drvdata(pdev, subdev_dev); return 0; err: - mtk_vcodec_release_dec_pm(&subdev_dev->pm); + pm_runtime_disable(subdev_dev->pm.dev); + put_device(subdev_dev->pm.larbvdec); return ret; } diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c index 4cf03d38d141..b9f5ef979c69 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c @@ -15,7 +15,7 @@ #include "mtk_vcodec_dec_pm.h" #include "mtk_vcodec_util.h" -int mtk_vcodec_init_dec_pm(struct platform_device *pdev, +int mtk_vcodec_init_dec_clk(struct platform_device *pdev, struct mtk_vcodec_pm *pm) { struct device_node *node; @@ -73,20 +73,12 @@ int mtk_vcodec_init_dec_pm(struct platform_device *pdev, } } - pm_runtime_enable(&pdev->dev); return 0; put_device: put_device(pm->larbvdec); return ret; } -EXPORT_SYMBOL_GPL(mtk_vcodec_init_dec_pm); - -void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm) -{ - pm_runtime_disable(pm->dev); - put_device(pm->larbvdec); -} -EXPORT_SYMBOL_GPL(mtk_vcodec_release_dec_pm); +EXPORT_SYMBOL_GPL(mtk_vcodec_init_dec_clk); int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx) { diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h index 6ae29fea4e7f..c4121df9764f 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h @@ -9,9 +9,8 @@ #include "mtk_vcodec_drv.h" -int mtk_vcodec_init_dec_pm(struct platform_device *pdev, +int mtk_
[PATCH v11, 17/19] media: mtk-vcodec: Use codec type to separate different hardware
There is just one core thread, in order to separate different hardware, using codec type to separeate it in scp driver. Signed-off-by: Yunfei Dong Reviewed-by: AngeloGioacchino Del Regno --- .../media/platform/mtk-vcodec/vdec_ipi_msg.h | 12 --- .../media/platform/mtk-vcodec/vdec_vpu_if.c | 34 --- .../media/platform/mtk-vcodec/vdec_vpu_if.h | 4 +++ 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h index 9d8079c4f976..5daca8d52ebb 100644 --- a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h +++ b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h @@ -35,6 +35,8 @@ enum vdec_ipi_msgid { * @msg_id : vdec_ipi_msgid * @vpu_inst_addr : VPU decoder instance address. Used if ABI version < 2. * @inst_id : instance ID. Used if the ABI version >= 2. + * @codec_type : codec fourcc + * @reserved : reserved param */ struct vdec_ap_ipi_cmd { uint32_t msg_id; @@ -42,6 +44,8 @@ struct vdec_ap_ipi_cmd { uint32_t vpu_inst_addr; uint32_t inst_id; }; + uint32_t codec_type; + uint32_t reserved; }; /** @@ -59,12 +63,12 @@ struct vdec_vpu_ipi_ack { /** * struct vdec_ap_ipi_init - for AP_IPIMSG_DEC_INIT * @msg_id : AP_IPIMSG_DEC_INIT - * @reserved : Reserved field + * @codec_type : codec fourcc * @ap_inst_addr : AP video decoder instance address */ struct vdec_ap_ipi_init { uint32_t msg_id; - uint32_t reserved; + uint32_t codec_type; uint64_t ap_inst_addr; }; @@ -77,7 +81,7 @@ struct vdec_ap_ipi_init { * H264 decoder [0]:buf_sz [1]:nal_start * VP8 decoder [0]:width/height * VP9 decoder [0]:profile, [1][2] width/height - * @reserved : Reserved field + * @codec_type : codec fourcc */ struct vdec_ap_ipi_dec_start { uint32_t msg_id; @@ -86,7 +90,7 @@ struct vdec_ap_ipi_dec_start { uint32_t inst_id; }; uint32_t data[3]; - uint32_t reserved; + uint32_t codec_type; }; /** diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c index bfd8e87dceff..c84fac52fe26 100644 --- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c +++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c @@ -100,18 +100,29 @@ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv) static int vcodec_vpu_send_msg(struct vdec_vpu_inst *vpu, void *msg, int len) { - int err; + int err, id, msgid; - mtk_vcodec_debug(vpu, "id=%X", *(uint32_t *)msg); + msgid = *(uint32_t *)msg; + mtk_vcodec_debug(vpu, "id=%X", msgid); vpu->failure = 0; vpu->signaled = 0; - err = mtk_vcodec_fw_ipi_send(vpu->ctx->dev->fw_handler, vpu->id, msg, + if (vpu->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_LAT_SINGLE_CORE) { + if (msgid == AP_IPIMSG_DEC_CORE || + msgid == AP_IPIMSG_DEC_CORE_END) + id = vpu->core_id; + else + id = vpu->id; + } else { + id = vpu->id; + } + + err = mtk_vcodec_fw_ipi_send(vpu->ctx->dev->fw_handler, id, msg, len, 2000); if (err) { mtk_vcodec_err(vpu, "send fail vpu_id=%d msg_id=%X status=%d", - vpu->id, *(uint32_t *)msg, err); + id, msgid, err); return err; } @@ -131,6 +142,7 @@ static int vcodec_send_ap_ipi(struct vdec_vpu_inst *vpu, unsigned int msg_id) msg.vpu_inst_addr = vpu->inst_addr; else msg.inst_id = vpu->inst_id; + msg.codec_type = vpu->codec_type; err = vcodec_vpu_send_msg(vpu, &msg, sizeof(msg)); mtk_vcodec_debug(vpu, "- id=%X ret=%d", msg_id, err); @@ -149,14 +161,25 @@ int vpu_dec_init(struct vdec_vpu_inst *vpu) err = mtk_vcodec_fw_ipi_register(vpu->ctx->dev->fw_handler, vpu->id, vpu->handler, "vdec", NULL); - if (err != 0) { + if (err) { mtk_vcodec_err(vpu, "vpu_ipi_register fail status=%d", err); return err; } + if (vpu->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_LAT_SINGLE_CORE) { + err = mtk_vcodec_fw_ipi_register(vpu->ctx->dev->fw_handler, +vpu->core_id, vpu->handler, +"vdec", NULL); + if (err) { + mtk_vcodec_err(vpu, "vpu_ipi_register core fail status=%d", err); + return err; + } + } + memset(&msg, 0, sizeof(msg)); msg.msg_id = AP_IPIMSG_DEC_INIT; msg.ap_inst_addr = (unsigned long)vpu; + msg.codec_type = vpu->codec_type;
[PATCH] drm/tidss: Fix warning: unused variable 'tidss_pm_ops'
Mark 'tidss_pm_ops' as __maybe_unused to avoid the warning: unused variable 'tidss_pm_ops' Fixes: 6e120594631f ("drm/tidss: Make use of the helper macro SET_RUNTIME_PM_OPS()") Signed-off-by: Cai Huoqing --- drivers/gpu/drm/tidss/tidss_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c index 4366b5c798e0..7c784e90e40e 100644 --- a/drivers/gpu/drm/tidss/tidss_drv.c +++ b/drivers/gpu/drm/tidss/tidss_drv.c @@ -88,7 +88,7 @@ static int __maybe_unused tidss_resume(struct device *dev) return drm_mode_config_helper_resume(&tidss->ddev); } -static const struct dev_pm_ops tidss_pm_ops = { +static __maybe_unused const struct dev_pm_ops tidss_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(tidss_suspend, tidss_resume) SET_RUNTIME_PM_OPS(tidss_pm_runtime_suspend, tidss_pm_runtime_resume, NULL) }; -- 2.25.1
[PATCH] dma_fence_array: Fix PENDING_ERROR leak in dma_fence_array_signaled()
If a dma_fence_array is reported signaled by a call to dma_fence_is_signaled(), it may leak the PENDING_ERROR status. Fix this by clearing the PENDING_ERROR status if we return true in dma_fence_array_signaled(). Fixes: 1f70b8b812f3 ("dma-fence: Propagate errors to dma-fence-array container") Cc: linaro-mm-...@lists.linaro.org Cc: Christian König Cc: Chris Wilson Signed-off-by: Thomas Hellström --- drivers/dma-buf/dma-fence-array.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/dma-buf/dma-fence-array.c b/drivers/dma-buf/dma-fence-array.c index d3fbd950be94..3e07f961e2f3 100644 --- a/drivers/dma-buf/dma-fence-array.c +++ b/drivers/dma-buf/dma-fence-array.c @@ -104,7 +104,11 @@ static bool dma_fence_array_signaled(struct dma_fence *fence) { struct dma_fence_array *array = to_dma_fence_array(fence); - return atomic_read(&array->num_pending) <= 0; + if (atomic_read(&array->num_pending) > 0) + return false; + + dma_fence_array_clear_pending_error(array); + return true; } static void dma_fence_array_release(struct dma_fence *fence) -- 2.31.1