From 87ea95808d53e56b03e620e8f8f3add48899a88d Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Fri, 10 Sep 2021 15:09:39 +0200 Subject: [PATCH 1/9] drm/bridge: Add a function to abstract away panels Display drivers so far need to have a lot of boilerplate to first retrieve either the panel or bridge that they are connected to using drm_of_find_panel_or_bridge(), and then either deal with each with ad-hoc functions or create a drm panel bridge through drm_panel_bridge_add. In order to reduce the boilerplate and hopefully create a path of least resistance towards using the DRM panel bridge layer, let's create the function devm_drm_of_get_bridge() to reduce that boilerplate. Signed-off-by: Maxime Ripard Reviewed-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20210910130941.1740182-2-maxime@cerno.tech --- drivers/gpu/drm/drm_bridge.c | 41 ++++++++++++++++++++++++++++++++---- drivers/gpu/drm/drm_of.c | 3 +++ include/drm/drm_bridge.h | 2 ++ 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index a8ed66751c2d..4c68733fa660 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "drm_crtc_internal.h" @@ -51,10 +52,8 @@ * * Display drivers are responsible for linking encoders with the first bridge * in the chains. This is done by acquiring the appropriate bridge with - * of_drm_find_bridge() or drm_of_find_panel_or_bridge(), or creating it for a - * panel with drm_panel_bridge_add_typed() (or the managed version - * devm_drm_panel_bridge_add_typed()). Once acquired, the bridge shall be - * attached to the encoder with a call to drm_bridge_attach(). + * devm_drm_of_get_bridge(). Once acquired, the bridge shall be attached to the + * encoder with a call to drm_bridge_attach(). * * Bridges are responsible for linking themselves with the next bridge in the * chain, if any. This is done the same way as for encoders, with the call to @@ -1233,6 +1232,40 @@ struct drm_bridge *of_drm_find_bridge(struct device_node *np) return NULL; } EXPORT_SYMBOL(of_drm_find_bridge); + +/** + * devm_drm_of_get_bridge - Return next bridge in the chain + * @dev: device to tie the bridge lifetime to + * @np: device tree node containing encoder output ports + * @port: port in the device tree node + * @endpoint: endpoint in the device tree node + * + * Given a DT node's port and endpoint number, finds the connected node + * and returns the associated bridge if any, or creates and returns a + * drm panel bridge instance if a panel is connected. + * + * Returns a pointer to the bridge if successful, or an error pointer + * otherwise. + */ +struct drm_bridge *devm_drm_of_get_bridge(struct device *dev, + struct device_node *np, + u32 port, u32 endpoint) +{ + struct drm_bridge *bridge; + struct drm_panel *panel; + int ret; + + ret = drm_of_find_panel_or_bridge(np, port, endpoint, + &panel, &bridge); + if (ret) + return ERR_PTR(ret); + + if (panel) + bridge = devm_drm_panel_bridge_add(dev, panel); + + return bridge; +} +EXPORT_SYMBOL(devm_drm_of_get_bridge); #endif MODULE_AUTHOR("Ajay Kumar "); diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c index 997b8827fed2..37c34146eea8 100644 --- a/drivers/gpu/drm/drm_of.c +++ b/drivers/gpu/drm/drm_of.c @@ -231,6 +231,9 @@ EXPORT_SYMBOL_GPL(drm_of_encoder_active_endpoint); * return either the associated struct drm_panel or drm_bridge device. Either * @panel or @bridge must not be NULL. * + * This function is deprecated and should not be used in new drivers. Use + * devm_drm_of_get_bridge() instead. + * * Returns zero if successful, or one of the standard error codes if it fails. */ int drm_of_find_panel_or_bridge(const struct device_node *np, diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 46bdfa48c413..9cdbd209388e 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -911,6 +911,8 @@ struct drm_bridge *devm_drm_panel_bridge_add(struct device *dev, struct drm_bridge *devm_drm_panel_bridge_add_typed(struct device *dev, struct drm_panel *panel, u32 connector_type); +struct drm_bridge *devm_drm_of_get_bridge(struct device *dev, struct device_node *node, + u32 port, u32 endpoint); struct drm_connector *drm_panel_bridge_connector(struct drm_bridge *bridge); #endif From 0caddbbfdfa257ae48e496aecc4b96f9b975b30e Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Fri, 10 Sep 2021 15:09:40 +0200 Subject: [PATCH 2/9] drm/vc4: dpi: Switch to devm_drm_of_get_bridge The new devm_drm_of_get_bridge removes most of the boilerplate we have to deal with. Let's switch to it. Signed-off-by: Maxime Ripard Acked-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20210910130941.1740182-3-maxime@cerno.tech --- drivers/gpu/drm/vc4/vc4_dpi.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c index a90f2545baee..c180eb60bee8 100644 --- a/drivers/gpu/drm/vc4/vc4_dpi.c +++ b/drivers/gpu/drm/vc4/vc4_dpi.c @@ -229,26 +229,19 @@ static const struct of_device_id vc4_dpi_dt_match[] = { static int vc4_dpi_init_bridge(struct vc4_dpi *dpi) { struct device *dev = &dpi->pdev->dev; - struct drm_panel *panel; struct drm_bridge *bridge; - int ret; - ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, - &panel, &bridge); - if (ret) { + bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0); + if (IS_ERR(bridge)) { /* If nothing was connected in the DT, that's not an * error. */ - if (ret == -ENODEV) + if (PTR_ERR(bridge) == -ENODEV) return 0; else - return ret; + return PTR_ERR(bridge); } - if (panel) - bridge = drm_panel_bridge_add_typed(panel, - DRM_MODE_CONNECTOR_DPI); - return drm_bridge_attach(dpi->encoder, bridge, NULL, 0); } From a43dd76bacd0d5441a4c84f60d64bdfaedc95bac Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Fri, 10 Sep 2021 15:09:41 +0200 Subject: [PATCH 3/9] drm/vc4: dsi: Switch to devm_drm_of_get_bridge The new devm_drm_of_get_bridge removes most of the boilerplate we have to deal with. Let's switch to it. Signed-off-by: Maxime Ripard Acked-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20210910130941.1740182-4-maxime@cerno.tech --- drivers/gpu/drm/vc4/vc4_dsi.c | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c index a185027911ce..a229da58962a 100644 --- a/drivers/gpu/drm/vc4/vc4_dsi.c +++ b/drivers/gpu/drm/vc4/vc4_dsi.c @@ -1497,7 +1497,6 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data) struct drm_device *drm = dev_get_drvdata(master); struct vc4_dsi *dsi = dev_get_drvdata(dev); struct vc4_dsi_encoder *vc4_dsi_encoder; - struct drm_panel *panel; const struct of_device_id *match; dma_cap_mask_t dma_mask; int ret; @@ -1609,27 +1608,9 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data) return ret; } - ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, - &panel, &dsi->bridge); - if (ret) { - /* If the bridge or panel pointed by dev->of_node is not - * enabled, just return 0 here so that we don't prevent the DRM - * dev from being registered. Of course that means the DSI - * encoder won't be exposed, but that's not a problem since - * nothing is connected to it. - */ - if (ret == -ENODEV) - return 0; - - return ret; - } - - if (panel) { - dsi->bridge = devm_drm_panel_bridge_add_typed(dev, panel, - DRM_MODE_CONNECTOR_DSI); - if (IS_ERR(dsi->bridge)) - return PTR_ERR(dsi->bridge); - } + dsi->bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0); + if (IS_ERR(dsi->bridge)) + return PTR_ERR(dsi->bridge); /* The esc clock rate is supposed to always be 100Mhz. */ ret = clk_set_rate(dsi->escape_clock, 100 * 1000000); @@ -1667,8 +1648,7 @@ static void vc4_dsi_unbind(struct device *dev, struct device *master, { struct vc4_dsi *dsi = dev_get_drvdata(dev); - if (dsi->bridge) - pm_runtime_disable(dev); + pm_runtime_disable(dev); /* * Restore the bridge_chain so the bridge detach procedure can happen From 5ad2d11feafbb9a51291754c66b35e450ac6ee59 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 9 Sep 2021 02:37:41 +0000 Subject: [PATCH 4/9] dma-buf: system_heap: Avoid warning on mid-order allocations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When trying to do mid-order allocations, set __GFP_NOWARN to avoid warning messages if the allocation fails, as we will still fall back to single page allocatitions in that case. This is the similar to what we already do for large order allocations. Cc: Daniel Vetter Cc: Christian Koenig Cc: Sumit Semwal Cc: Liam Mark Cc: Chris Goldsworthy Cc: Laura Abbott Cc: Brian Starkey Cc: Hridya Valsaraju Cc: Suren Baghdasaryan Cc: Sandeep Patil Cc: Daniel Mentz Cc: Ørjan Eide Cc: Robin Murphy Cc: Simon Ser Cc: James Jones Cc: Leo Yan Cc: linux-media@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Signed-off-by: John Stultz Acked-by: Daniel Vetter Signed-off-by: Sumit Semwal Link: https://patchwork.freedesktop.org/patch/msgid/20210909023741.2592429-1-john.stultz@linaro.org --- drivers/dma-buf/heaps/system_heap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c index 23a7e74ef966..f57a39ddd063 100644 --- a/drivers/dma-buf/heaps/system_heap.c +++ b/drivers/dma-buf/heaps/system_heap.c @@ -40,11 +40,12 @@ struct dma_heap_attachment { bool mapped; }; +#define LOW_ORDER_GFP (GFP_HIGHUSER | __GFP_ZERO | __GFP_COMP) +#define MID_ORDER_GFP (LOW_ORDER_GFP | __GFP_NOWARN) #define HIGH_ORDER_GFP (((GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN \ | __GFP_NORETRY) & ~__GFP_RECLAIM) \ | __GFP_COMP) -#define LOW_ORDER_GFP (GFP_HIGHUSER | __GFP_ZERO | __GFP_COMP) -static gfp_t order_flags[] = {HIGH_ORDER_GFP, LOW_ORDER_GFP, LOW_ORDER_GFP}; +static gfp_t order_flags[] = {HIGH_ORDER_GFP, MID_ORDER_GFP, LOW_ORDER_GFP}; /* * The selection of the orders used for allocation (1MB, 64K, 4K) is designed * to match with the sizes often found in IOMMUs. Using order 4 pages instead From 0b7383331c0032c8f7eab8311b73cdbc534ccdd5 Mon Sep 17 00:00:00 2001 From: bibo mao Date: Tue, 14 Sep 2021 02:23:51 -0400 Subject: [PATCH 5/9] drm/qxl: User page size macro for qxl release bo Some architectures have different default page size, this patch replaces hardcoded 4096 with PAGE_SIZE macro, since cmd bo size is page aligned. Signed-off-by: bibo mao Link: http://patchwork.freedesktop.org/patch/msgid/20210914062352.6102-1-maobibo@loongson.cn Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/qxl/qxl_release.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c index b19f2f00b215..469979cd0341 100644 --- a/drivers/gpu/drm/qxl/qxl_release.c +++ b/drivers/gpu/drm/qxl/qxl_release.c @@ -36,10 +36,10 @@ /* manage releaseables */ /* stack them 16 high for now -drawable object is 191 */ #define RELEASE_SIZE 256 -#define RELEASES_PER_BO (4096 / RELEASE_SIZE) +#define RELEASES_PER_BO (PAGE_SIZE / RELEASE_SIZE) /* put an alloc/dealloc surface cmd into one bo and round up to 128 */ #define SURFACE_RELEASE_SIZE 128 -#define SURFACE_RELEASES_PER_BO (4096 / SURFACE_RELEASE_SIZE) +#define SURFACE_RELEASES_PER_BO (PAGE_SIZE / SURFACE_RELEASE_SIZE) static const int release_size_per_bo[] = { RELEASE_SIZE, SURFACE_RELEASE_SIZE, RELEASE_SIZE }; static const int releases_per_bo[] = { RELEASES_PER_BO, SURFACE_RELEASES_PER_BO, RELEASES_PER_BO }; From 78afff2acea1c184525dbccafad9aa061f73478a Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin (Intel)" Date: Thu, 9 Sep 2021 18:06:55 -0700 Subject: [PATCH 6/9] drm/bochs: add Bochs PCI ID for Simics model Current (and older) Simics models for the Bochs VGA used the wrong PCI vendor ID (0x4321 instead of 0x1234). Although this can hopefully be fixed in the future, it is a problem for users of the current version, not the least because to update the device ID the BIOS has to be rebuilt in order to see BIOS output. Add support for the 4321:1111 device number in addition to the 1234:1111 one. Signed-off-by: H. Peter Anvin (Intel) Link: http://patchwork.freedesktop.org/patch/msgid/20210910010655.2356245-1-hpa@zytor.com Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/tiny/bochs.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c index 73415fa9ae0f..2ce3bd903b70 100644 --- a/drivers/gpu/drm/tiny/bochs.c +++ b/drivers/gpu/drm/tiny/bochs.c @@ -63,6 +63,7 @@ MODULE_PARM_DESC(defy, "default y resolution"); enum bochs_types { BOCHS_QEMU_STDVGA, + BOCHS_SIMICS, BOCHS_UNKNOWN, }; @@ -695,6 +696,13 @@ static const struct pci_device_id bochs_pci_tbl[] = { .subdevice = PCI_ANY_ID, .driver_data = BOCHS_UNKNOWN, }, + { + .vendor = 0x4321, + .device = 0x1111, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = BOCHS_SIMICS, + }, { /* end of list */ } }; From 282abb5a1f381d0ec10b20893961563be174a1c3 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Tue, 7 Sep 2021 18:03:02 +0800 Subject: [PATCH 7/9] drm/ttm: fix the type mismatch error on sparc64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit __fls() on sparc64 return "int", but here it is expected as "unsigned long" (x86). It will cause the build errors because the warning becomes fatal while it is using sparc configuration. As suggested by Linus, it can use min_t instead of min to force the type as "unsigned int". Suggested-by: Linus Torvalds Signed-off-by: Huang Rui Cc: Christian König Reviewed-by: Christian König Signed-off-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20210907100302.3684453-1-ray.huang@amd.com --- drivers/gpu/drm/ttm/ttm_pool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c index af1b41369626..c961a788b519 100644 --- a/drivers/gpu/drm/ttm/ttm_pool.c +++ b/drivers/gpu/drm/ttm/ttm_pool.c @@ -382,7 +382,8 @@ int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt, else gfp_flags |= GFP_HIGHUSER; - for (order = min(MAX_ORDER - 1UL, __fls(num_pages)); num_pages; + for (order = min_t(unsigned int, MAX_ORDER - 1, __fls(num_pages)); + num_pages; order = min_t(unsigned int, order, __fls(num_pages))) { bool apply_caching = false; struct ttm_pool_type *pt; From bcf26654a38f8e55ecac4635dac2e72c161d0063 Mon Sep 17 00:00:00 2001 From: Monk Liu Date: Wed, 1 Sep 2021 08:46:46 +0800 Subject: [PATCH 8/9] drm/sched: fix the bug of time out calculation(v4) issue: in cleanup_job the cancle_delayed_work will cancel a TO timer even the its corresponding job is still running. fix: do not cancel the timer in cleanup_job, instead do the cancelling only when the heading job is signaled, and if there is a "next" job we start_timeout again. v2: further cleanup the logic, and do the TDR timer cancelling if the signaled job is the last one in its scheduler. v3: change the issue description remove the cancel_delayed_work in the begining of the cleanup_job recover the implement of drm_sched_job_begin. v4: remove the kthread_should_park() checking in cleanup_job routine, we should cleanup the signaled job asap TODO: 1)introduce pause/resume scheduler in job_timeout to serial the handling of scheduler and job_timeout. 2)drop the bad job's del and insert in scheduler due to above serialization (no race issue anymore with the serialization) Tested-by: jingwen Signed-off-by: Monk Liu Signed-off-by: Andrey Grodzovsky Link: https://patchwork.freedesktop.org/patch/msgid/1630457207-13107-1-git-send-email-Monk.Liu@amd.com --- drivers/gpu/drm/scheduler/sched_main.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c index 6987d412a946..042c16b5d54a 100644 --- a/drivers/gpu/drm/scheduler/sched_main.c +++ b/drivers/gpu/drm/scheduler/sched_main.c @@ -827,15 +827,6 @@ drm_sched_get_cleanup_job(struct drm_gpu_scheduler *sched) { struct drm_sched_job *job, *next; - /* - * Don't destroy jobs while the timeout worker is running OR thread - * is being parked and hence assumed to not touch pending_list - */ - if ((sched->timeout != MAX_SCHEDULE_TIMEOUT && - !cancel_delayed_work(&sched->work_tdr)) || - kthread_should_park()) - return NULL; - spin_lock(&sched->job_list_lock); job = list_first_entry_or_null(&sched->pending_list, @@ -844,17 +835,21 @@ drm_sched_get_cleanup_job(struct drm_gpu_scheduler *sched) if (job && dma_fence_is_signaled(&job->s_fence->finished)) { /* remove job from pending_list */ list_del_init(&job->list); + + /* cancel this job's TO timer */ + cancel_delayed_work(&sched->work_tdr); /* make the scheduled timestamp more accurate */ next = list_first_entry_or_null(&sched->pending_list, typeof(*next), list); - if (next) + + if (next) { next->s_fence->scheduled.timestamp = job->s_fence->finished.timestamp; - + /* start TO timer for next job */ + drm_sched_start_timeout(sched); + } } else { job = NULL; - /* queue timeout for next job */ - drm_sched_start_timeout(sched); } spin_unlock(&sched->job_list_lock); @@ -942,11 +937,8 @@ static int drm_sched_main(void *param) (entity = drm_sched_select_entity(sched))) || kthread_should_stop()); - if (cleanup_job) { + if (cleanup_job) sched->ops->free_job(cleanup_job); - /* queue timeout for next job */ - drm_sched_start_timeout(sched); - } if (!entity) continue; From e4f868191138975f2fdf2f37c11318b47db4acc9 Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Wed, 15 Sep 2021 12:05:07 +0200 Subject: [PATCH 9/9] drm/v3d: fix wait for TMU write combiner flush The hardware sets the TMUWCF bit back to 0 when the TMU write combiner flush completes so we should be checking for that instead of the L2TFLS bit. v2 (Melissa Wen): - Add Signed-off-by and Fixes tags. - Change the error message for the timeout to be more clear. Fixes spurious Vulkan CTS failures in: dEQP-VK.binding_model.descriptorset_random.* Fixes: d223f98f02099 ("drm/v3d: Add support for compute shader dispatch.") Signed-off-by: Iago Toral Quiroga Reviewed-by: Melissa Wen Signed-off-by: Melissa Wen Link: https://patchwork.freedesktop.org/patch/msgid/20210915100507.3945-1-itoral@igalia.com --- drivers/gpu/drm/v3d/v3d_gem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c index a3529809d547..1953706bdaeb 100644 --- a/drivers/gpu/drm/v3d/v3d_gem.c +++ b/drivers/gpu/drm/v3d/v3d_gem.c @@ -197,8 +197,8 @@ v3d_clean_caches(struct v3d_dev *v3d) V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL, V3D_L2TCACTL_TMUWCF); if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) & - V3D_L2TCACTL_L2TFLS), 100)) { - DRM_ERROR("Timeout waiting for L1T write combiner flush\n"); + V3D_L2TCACTL_TMUWCF), 100)) { + DRM_ERROR("Timeout waiting for TMU write combiner flush\n"); } mutex_lock(&v3d->cache_clean_lock);