From 523be44c334bc4e4c014032738dc277b8909d009 Mon Sep 17 00:00:00 2001 From: Wang ShaoBo Date: Fri, 11 Sep 2020 09:44:14 +0800 Subject: [PATCH 001/235] drm/imx/dcss: fix unused but set variable warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix unused but set variable warning building with `make W=1`: drivers/gpu/drm/imx/dcss/dcss-plane.c:270:6: warning: variable ‘pixel_format’ set but not used [-Wunused-but-set-variable] u32 pixel_format; ^~~~~~~~~~~~ Fixes: 9021c317b770 ("drm/imx: Add initial support for DCSS on iMX8MQ") Reported-by: Hulk Robot Signed-off-by: Wang ShaoBo Reviewed-by: Laurentiu Palcu Signed-off-by: Lucas Stach Link: https://patchwork.freedesktop.org/patch/msgid/20200911014414.4663-1-bobo.shaobowang@huawei.com --- drivers/gpu/drm/imx/dcss/dcss-plane.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/imx/dcss/dcss-plane.c b/drivers/gpu/drm/imx/dcss/dcss-plane.c index 961d671f171b..e13652e3a115 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-plane.c +++ b/drivers/gpu/drm/imx/dcss/dcss-plane.c @@ -267,7 +267,6 @@ static void dcss_plane_atomic_update(struct drm_plane *plane, struct dcss_plane *dcss_plane = to_dcss_plane(plane); struct dcss_dev *dcss = plane->dev->dev_private; struct drm_framebuffer *fb = state->fb; - u32 pixel_format; struct drm_crtc_state *crtc_state; bool modifiers_present; u32 src_w, src_h, dst_w, dst_h; @@ -277,7 +276,6 @@ static void dcss_plane_atomic_update(struct drm_plane *plane, if (!fb || !state->crtc || !state->visible) return; - pixel_format = state->fb->format->format; crtc_state = state->crtc->state; modifiers_present = !!(fb->flags & DRM_MODE_FB_MODIFIERS); From d7b1c018140fb4b513c4e05685d74ef8178ef179 Mon Sep 17 00:00:00 2001 From: Jason Yan Date: Wed, 16 Sep 2020 21:23:01 +0800 Subject: [PATCH 002/235] drm/panel: samsung: make vint_table static const This eliminates the following sparse warning: drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c:217:15: warning: symbol 'vint_table' was not declared. Should it be static? While at it, make the table const as it is never modified. Reported-by: Hulk Robot Signed-off-by: Jason Yan Reviewed-by: Laurent Pinchart Signed-off-by: Linus Walleij Link: https://patchwork.freedesktop.org/patch/msgid/20200916132301.2914017-1-yanaijie@huawei.com --- drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c b/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c index 1d1c79a18613..0ab1b7ec84cd 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c @@ -214,7 +214,7 @@ static const u8 gamma_tbl[S6E3HA2_NUM_GAMMA_STEPS][S6E3HA2_GAMMA_CMD_CNT] = { 0x00, 0x00 } }; -unsigned char vint_table[S6E3HA2_VINT_STATUS_MAX] = { +static const unsigned char vint_table[S6E3HA2_VINT_STATUS_MAX] = { 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21 }; From b8f8dbf6495850b0babc551377bde754b7bc0eea Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 21 Sep 2020 16:25:36 +0200 Subject: [PATCH 003/235] drm/vram-helper: Fix use of top-down placement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 7053e0eab473 ("drm/vram-helper: stop using TTM placement flags") cleared the BO placement flags if top-down placement had been selected. Hence, BOs that were supposed to go into VRAM are now placed in a default location in system memory. Trying to scanout the incorrectly pinned BO results in displayed garbage and an error message. [ 146.108127] ------------[ cut here ]------------ [ 146.1V08180] WARNING: CPU: 0 PID: 152 at drivers/gpu/drm/drm_gem_vram_helper.c:284 drm_gem_vram_offset+0x59/0x60 [drm_vram_helper] ... [ 146.108591] ast_cursor_page_flip+0x3e/0x150 [ast] [ 146.108622] ast_cursor_plane_helper_atomic_update+0x8a/0xc0 [ast] [ 146.108654] drm_atomic_helper_commit_planes+0x197/0x4c0 [ 146.108699] drm_atomic_helper_commit_tail_rpm+0x59/0xa0 [ 146.108718] commit_tail+0x103/0x1c0 ... [ 146.109302] ---[ end trace d901a1ba1d949036 ]--- Fix the bug by keeping the placement flags. The top-down placement flag is stored in a separate variable. Signed-off-by: Thomas Zimmermann Reviewed-by: Christian König Fixes: 7053e0eab473 ("drm/vram-helper: stop using TTM placement flags") Cc: Christian König Cc: Dave Airlie Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann Cc: David Airlie Cc: Daniel Vetter Cc: dri-devel@lists.freedesktop.org Link: https://patchwork.freedesktop.org/patch/msgid/20200921142536.4392-1-tzimmermann@suse.de --- drivers/gpu/drm/drm_gem_vram_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c b/drivers/gpu/drm/drm_gem_vram_helper.c index 50cad0e4a92e..375c79e23ca5 100644 --- a/drivers/gpu/drm/drm_gem_vram_helper.c +++ b/drivers/gpu/drm/drm_gem_vram_helper.c @@ -140,7 +140,7 @@ static void drm_gem_vram_placement(struct drm_gem_vram_object *gbo, unsigned int c = 0; if (pl_flag & DRM_GEM_VRAM_PL_FLAG_TOPDOWN) - pl_flag = TTM_PL_FLAG_TOPDOWN; + invariant_flags = TTM_PL_FLAG_TOPDOWN; gbo->placement.placement = gbo->placements; gbo->placement.busy_placement = gbo->placements; From ca4bd68e11c86bbaf73cfc18dbc041350096e9ab Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Sun, 20 Sep 2020 15:14:07 +0100 Subject: [PATCH 004/235] drm/gma500: clean up indentation issues There are a couple of statements that are indented too deeply, remove the extraneous tabs and also an empty line. Signed-off-by: Colin Ian King Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20200920141407.32672-1-colin.king@canonical.com --- drivers/gpu/drm/gma500/cdv_intel_dp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/gma500/cdv_intel_dp.c b/drivers/gpu/drm/gma500/cdv_intel_dp.c index 720a767118c9..50016a754172 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_dp.c +++ b/drivers/gpu/drm/gma500/cdv_intel_dp.c @@ -1501,8 +1501,7 @@ cdv_intel_dp_start_link_train(struct gma_encoder *encoder) clock_recovery = false; DRM_DEBUG_KMS("Start train\n"); - reg = DP | DP_LINK_TRAIN_PAT_1; - + reg = DP | DP_LINK_TRAIN_PAT_1; for (;;) { /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ @@ -1575,7 +1574,7 @@ cdv_intel_dp_complete_link_train(struct gma_encoder *encoder) cr_tries = 0; DRM_DEBUG_KMS("\n"); - reg = DP | DP_LINK_TRAIN_PAT_2; + reg = DP | DP_LINK_TRAIN_PAT_2; for (;;) { From 9572e6693cd731268521ab5af43858315a8cfb10 Mon Sep 17 00:00:00 2001 From: Qinglang Miao Date: Mon, 21 Sep 2020 21:11:10 +0800 Subject: [PATCH 005/235] vga_switcheroo: simplify the return expression of vga_switcheroo_runtime_resume Simplify the return expression. Signed-off-by: Qinglang Miao Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20200921131110.93365-1-miaoqinglang@huawei.com --- drivers/gpu/vga/vga_switcheroo.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index 087304b1a5d7..1401fd52f37a 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c @@ -1034,17 +1034,12 @@ static int vga_switcheroo_runtime_suspend(struct device *dev) static int vga_switcheroo_runtime_resume(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); - int ret; mutex_lock(&vgasr_mutex); vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_ON); mutex_unlock(&vgasr_mutex); pci_wakeup_bus(pdev->bus); - ret = dev->bus->pm->runtime_resume(dev); - if (ret) - return ret; - - return 0; + return dev->bus->pm->runtime_resume(dev); } /** From ad44c03208e46b83e4ae3269e32c9e524aa71cf8 Mon Sep 17 00:00:00 2001 From: Koba Ko Date: Tue, 22 Sep 2020 14:53:13 +0800 Subject: [PATCH 006/235] drm/dp_mst: Retrieve extended DPCD caps for topology manager As per DP-1.3, First check DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT. If DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is 1,read the DP_DP13_DPCD_REV to get the faster capability. If DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT is 0,read DP_DPCD_REV. Signed-off-by: Koba Ko Reviewed-by: Lyude Paul [added aux name to drm_dbg_kms() call] Signed-off-by: Lyude Paul Link: https://patchwork.freedesktop.org/patch/msgid/20200922065313.4794-1-koba.ko@canonical.com --- drivers/gpu/drm/drm_dp_mst_topology.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index b9c5a98c5c9c..b4a4bb340910 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -3536,9 +3536,10 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms WARN_ON(mgr->mst_primary); /* get dpcd info */ - ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd, DP_RECEIVER_CAP_SIZE); - if (ret != DP_RECEIVER_CAP_SIZE) { - DRM_DEBUG_KMS("failed to read DPCD\n"); + ret = drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd); + if (ret < 0) { + drm_dbg_kms(mgr->dev, "%s: failed to read DPCD, ret %d\n", + mgr->aux->name, ret); goto out_unlock; } From 4127a6204970b3d7cb140117472eb3dd99bd1a0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 18 Sep 2020 16:20:20 +0200 Subject: [PATCH 007/235] drm/ttm: remove nonsense AGP handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit map_page_into_agp() and unmap_page_from_agp() are only defined on x86. On all other platforms they are defined as noops. So this code doesn't has any effect at all. Signed-off-by: Christian König Reviewed-by: Alex Deucher Link: https://patchwork.freedesktop.org/patch/391292/ --- include/drm/ttm/ttm_set_memory.h | 44 -------------------------------- 1 file changed, 44 deletions(-) diff --git a/include/drm/ttm/ttm_set_memory.h b/include/drm/ttm/ttm_set_memory.h index 7c492b49e38c..3966655b72f1 100644 --- a/include/drm/ttm/ttm_set_memory.h +++ b/include/drm/ttm/ttm_set_memory.h @@ -71,48 +71,6 @@ static inline int ttm_set_pages_uc(struct page *page, int numpages) #else /* for CONFIG_X86 */ -#if IS_ENABLED(CONFIG_AGP) - -#include - -static inline int ttm_set_pages_array_wb(struct page **pages, int addrinarray) -{ - int i; - - for (i = 0; i < addrinarray; i++) - unmap_page_from_agp(pages[i]); - return 0; -} - -static inline int ttm_set_pages_array_wc(struct page **pages, int addrinarray) -{ - int i; - - for (i = 0; i < addrinarray; i++) - map_page_into_agp(pages[i]); - return 0; -} - -static inline int ttm_set_pages_array_uc(struct page **pages, int addrinarray) -{ - int i; - - for (i = 0; i < addrinarray; i++) - map_page_into_agp(pages[i]); - return 0; -} - -static inline int ttm_set_pages_wb(struct page *page, int numpages) -{ - int i; - - for (i = 0; i < numpages; i++) - unmap_page_from_agp(page++); - return 0; -} - -#else /* for CONFIG_AGP */ - static inline int ttm_set_pages_array_wb(struct page **pages, int addrinarray) { return 0; @@ -133,8 +91,6 @@ static inline int ttm_set_pages_wb(struct page *page, int numpages) return 0; } -#endif /* for CONFIG_AGP */ - static inline int ttm_set_pages_wc(struct page *page, int numpages) { return 0; From db9c1734ad69c0ba5e5e420ba31ebc1048976be6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 18 Sep 2020 16:34:49 +0200 Subject: [PATCH 008/235] drm/ttm: stop dangerous caching attribute change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When we swapout/in a BO we try to change the caching attributes of the pages before/after doing the copy. On x86 this is done by calling set_pages_uc(), set_memory_wc() or set_pages_wb() for not highmem pages to update the linear mapping of the page. On all other platforms we do exactly nothing. Now on x86 this is unnecessary because copy_highpage() will either create a temporary mapping of the page which is wb anyway and destroyed immediately again or use the linear mapping with the correct caching attributes. So stop this nonsense and just keep the caching as it is and return an error when a driver tries to change the caching of an already populated TT object. This is much more defensive since changing caching attributes is platform and driver specific and usually doesn't work after the page was initially allocated. Signed-off-by: Christian König Reviewed-by: Alex Deucher Link: https://patchwork.freedesktop.org/patch/391293/ --- drivers/gpu/drm/ttm/ttm_bo.c | 5 +-- drivers/gpu/drm/ttm/ttm_tt.c | 71 ++------------------------------ include/drm/ttm/ttm_set_memory.h | 22 ---------- 3 files changed, 5 insertions(+), 93 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 70b3bee27850..61c05c47ea66 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1551,14 +1551,13 @@ int ttm_bo_swapout(struct ttm_bo_global *glob, struct ttm_operation_ctx *ctx) * Move to system cached */ - if (bo->mem.mem_type != TTM_PL_SYSTEM || - bo->ttm->caching_state != tt_cached) { + if (bo->mem.mem_type != TTM_PL_SYSTEM) { struct ttm_operation_ctx ctx = { false, false }; struct ttm_resource evict_mem; evict_mem = bo->mem; evict_mem.mm_node = NULL; - evict_mem.placement = TTM_PL_FLAG_CACHED; + evict_mem.placement = TTM_PL_MASK_CACHING; evict_mem.mem_type = TTM_PL_SYSTEM; ret = ttm_bo_handle_move_mem(bo, &evict_mem, true, &ctx); diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index f43fa69a1e65..87dd887f7806 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -38,7 +38,6 @@ #include #include #include -#include /** * Allocates a ttm structure for the given BO. @@ -115,81 +114,19 @@ static int ttm_sg_tt_alloc_page_directory(struct ttm_dma_tt *ttm) return 0; } -static int ttm_tt_set_page_caching(struct page *p, - enum ttm_caching_state c_old, - enum ttm_caching_state c_new) -{ - int ret = 0; - - if (PageHighMem(p)) - return 0; - - if (c_old != tt_cached) { - /* p isn't in the default caching state, set it to - * writeback first to free its current memtype. */ - - ret = ttm_set_pages_wb(p, 1); - if (ret) - return ret; - } - - if (c_new == tt_wc) - ret = ttm_set_pages_wc(p, 1); - else if (c_new == tt_uncached) - ret = ttm_set_pages_uc(p, 1); - - return ret; -} - -/* - * Change caching policy for the linear kernel map - * for range of pages in a ttm. - */ - static int ttm_tt_set_caching(struct ttm_tt *ttm, enum ttm_caching_state c_state) { - int i, j; - struct page *cur_page; - int ret; - if (ttm->caching_state == c_state) return 0; - if (!ttm_tt_is_populated(ttm)) { - /* Change caching but don't populate */ - ttm->caching_state = c_state; - return 0; - } - - if (ttm->caching_state == tt_cached) - drm_clflush_pages(ttm->pages, ttm->num_pages); - - for (i = 0; i < ttm->num_pages; ++i) { - cur_page = ttm->pages[i]; - if (likely(cur_page != NULL)) { - ret = ttm_tt_set_page_caching(cur_page, - ttm->caching_state, - c_state); - if (unlikely(ret != 0)) - goto out_err; - } - } + /* Can't change the caching state after TT is populated */ + if (WARN_ON_ONCE(ttm_tt_is_populated(ttm))) + return -EINVAL; ttm->caching_state = c_state; return 0; - -out_err: - for (j = 0; j < i; ++j) { - cur_page = ttm->pages[j]; - if (likely(cur_page != NULL)) { - (void)ttm_tt_set_page_caching(cur_page, c_state, - ttm->caching_state); - } - } - - return ret; } int ttm_tt_set_placement_caching(struct ttm_tt *ttm, uint32_t placement) @@ -358,8 +295,6 @@ int ttm_tt_swapout(struct ttm_bo_device *bdev, int i; int ret = -ENOMEM; - BUG_ON(ttm->caching_state != tt_cached); - if (!persistent_swap_storage) { swap_storage = shmem_file_setup("ttm swap", ttm->num_pages << PAGE_SHIFT, diff --git a/include/drm/ttm/ttm_set_memory.h b/include/drm/ttm/ttm_set_memory.h index 3966655b72f1..2343c18a6133 100644 --- a/include/drm/ttm/ttm_set_memory.h +++ b/include/drm/ttm/ttm_set_memory.h @@ -57,18 +57,6 @@ static inline int ttm_set_pages_wb(struct page *page, int numpages) return set_pages_wb(page, numpages); } -static inline int ttm_set_pages_wc(struct page *page, int numpages) -{ - unsigned long addr = (unsigned long)page_address(page); - - return set_memory_wc(addr, numpages); -} - -static inline int ttm_set_pages_uc(struct page *page, int numpages) -{ - return set_pages_uc(page, numpages); -} - #else /* for CONFIG_X86 */ static inline int ttm_set_pages_array_wb(struct page **pages, int addrinarray) @@ -91,16 +79,6 @@ static inline int ttm_set_pages_wb(struct page *page, int numpages) return 0; } -static inline int ttm_set_pages_wc(struct page *page, int numpages) -{ - return 0; -} - -static inline int ttm_set_pages_uc(struct page *page, int numpages) -{ - return 0; -} - #endif /* for CONFIG_X86 */ #endif From 9e9f605fb5af8ae350d59de3c2a54422cb2d9301 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 17 Sep 2020 18:47:22 +0200 Subject: [PATCH 009/235] drm/doc: Document that modifiers are always required for fb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Even for legacy userspace, since otherwise GETFB2 is broken and if you switch between modifier-less and modifier-aware compositors, smooth transitions break. Also it's just best practice to make sure modifiers are invariant for a given drm_fb, and that a modifier-aware kms drivers only has one place to store them, ignoring any old implicit bo flags or whatever else might float around. Motivated by some irc discussion with Bas about amdgpu modifier support. Acked-by: Bas Nieuwenhuizen Acked-by: Simon Ser Acked-by: Daniel Stone Acked-by: Pekka Paalanen Fixes: 455e00f1412f ("drm: Add getfb2 ioctl") Cc: Daniel Stone Cc: Juston Li Cc: Daniel Vetter Cc: Ville Syrjälä Cc: Bas Nieuwenhuizen Cc: Marek Olšák Cc: "Wentland, Harry" Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20200917164721.2038541-1-daniel.vetter@ffwll.ch --- include/drm/drm_mode_config.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index a18f73eb3cf6..5ffbb4ed5b35 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -58,6 +58,12 @@ struct drm_mode_config_funcs { * actual modifier used if the request doesn't have it specified, * ie. when (@mode_cmd->flags & DRM_MODE_FB_MODIFIERS) == 0. * + * IMPORTANT: These implied modifiers for legacy userspace must be + * stored in struct &drm_framebuffer, including all relevant metadata + * like &drm_framebuffer.pitches and &drm_framebuffer.offsets if the + * modifier enables additional planes beyond the fourcc pixel format + * code. This is required by the GETFB2 ioctl. + * * If the parameters are deemed valid and the backing storage objects in * the underlying memory manager all exist, then the driver allocates * a new &drm_framebuffer structure, subclassed to contain @@ -915,6 +921,13 @@ struct drm_mode_config { * @allow_fb_modifiers: * * Whether the driver supports fb modifiers in the ADDFB2.1 ioctl call. + * + * IMPORTANT: + * + * If this is set the driver must fill out the full implicit modifier + * information in their &drm_mode_config_funcs.fb_create hook for legacy + * userspace which does not set modifiers. Otherwise the GETFB2 ioctl is + * broken for modifier aware userspace. */ bool allow_fb_modifiers; From 313bbdee84542437672824edbf03ba43ea07de04 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 23 Sep 2020 13:04:45 +1000 Subject: [PATCH 010/235] drm/radeon: kill radeon_bo_wait MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit this is unused Reviewed-by: Christian König Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20200923030454.362731-2-airlied@gmail.com --- drivers/gpu/drm/radeon/radeon_object.c | 15 --------------- drivers/gpu/drm/radeon/radeon_object.h | 3 --- 2 files changed, 18 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 316e35d3f8a9..76dfed30d61c 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -844,21 +844,6 @@ int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo) return 0; } -int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type, bool no_wait) -{ - int r; - - r = ttm_bo_reserve(&bo->tbo, true, no_wait, NULL); - if (unlikely(r != 0)) - return r; - if (mem_type) - *mem_type = bo->tbo.mem.mem_type; - - r = ttm_bo_wait(&bo->tbo, true, no_wait); - ttm_bo_unreserve(&bo->tbo); - return r; -} - /** * radeon_bo_fence - add fence to buffer object * diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index 44b47241ee42..430574caaf09 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h @@ -133,9 +133,6 @@ static inline u64 radeon_bo_mmap_offset(struct radeon_bo *bo) return drm_vma_node_offset_addr(&bo->tbo.base.vma_node); } -extern int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type, - bool no_wait); - extern int radeon_bo_create(struct radeon_device *rdev, unsigned long size, int byte_align, bool kernel, u32 domain, u32 flags, From 6b7741e42a49250a98b4a5ef2798ae5f8638aba0 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 23 Sep 2020 13:04:46 +1000 Subject: [PATCH 011/235] drm/qxl: kill unused bo wait wrapper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This wasn't used anywheere Acked-by: Christian König Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20200923030454.362731-3-airlied@gmail.com --- drivers/gpu/drm/qxl/qxl_object.h | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_object.h b/drivers/gpu/drm/qxl/qxl_object.h index 6b434e5ef795..32d3bb967251 100644 --- a/drivers/gpu/drm/qxl/qxl_object.h +++ b/drivers/gpu/drm/qxl/qxl_object.h @@ -58,29 +58,6 @@ static inline u64 qxl_bo_mmap_offset(struct qxl_bo *bo) return drm_vma_node_offset_addr(&bo->tbo.base.vma_node); } -static inline int qxl_bo_wait(struct qxl_bo *bo, u32 *mem_type, - bool no_wait) -{ - int r; - - r = ttm_bo_reserve(&bo->tbo, true, no_wait, NULL); - if (unlikely(r != 0)) { - if (r != -ERESTARTSYS) { - struct drm_device *ddev = bo->tbo.base.dev; - - dev_err(ddev->dev, "%p reserve failed for wait\n", - bo); - } - return r; - } - if (mem_type) - *mem_type = bo->tbo.mem.mem_type; - - r = ttm_bo_wait(&bo->tbo, true, no_wait); - ttm_bo_unreserve(&bo->tbo); - return r; -} - extern int qxl_bo_create(struct qxl_device *qdev, unsigned long size, bool kernel, bool pinned, u32 domain, From b1ec2924aa5a284aee1b829a15864378e88f423a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 23 Sep 2020 13:04:47 +1000 Subject: [PATCH 012/235] drm/radeon: cleanup ttm operation ctx usage. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just pass it around move, and remove unused pieces Reviewed-by: Christian König Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20200923030454.362731-4-airlied@gmail.com --- drivers/gpu/drm/radeon/radeon_ttm.c | 34 +++++++++++++---------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 36150b7f31a9..f3d424b3148e 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -151,7 +151,7 @@ static int radeon_verify_access(struct ttm_buffer_object *bo, struct file *filp) } static int radeon_move_blit(struct ttm_buffer_object *bo, - bool evict, bool no_wait_gpu, + bool evict, struct ttm_resource *new_mem, struct ttm_resource *old_mem) { @@ -206,11 +206,10 @@ static int radeon_move_blit(struct ttm_buffer_object *bo, } static int radeon_move_vram_ram(struct ttm_buffer_object *bo, - bool evict, bool interruptible, - bool no_wait_gpu, + bool evict, + struct ttm_operation_ctx *ctx, struct ttm_resource *new_mem) { - struct ttm_operation_ctx ctx = { interruptible, no_wait_gpu }; struct ttm_resource *old_mem = &bo->mem; struct ttm_resource tmp_mem; struct ttm_place placements; @@ -227,7 +226,7 @@ static int radeon_move_vram_ram(struct ttm_buffer_object *bo, placements.lpfn = 0; placements.mem_type = TTM_PL_TT; placements.flags = TTM_PL_MASK_CACHING; - r = ttm_bo_mem_space(bo, &placement, &tmp_mem, &ctx); + r = ttm_bo_mem_space(bo, &placement, &tmp_mem, ctx); if (unlikely(r)) { return r; } @@ -237,7 +236,7 @@ static int radeon_move_vram_ram(struct ttm_buffer_object *bo, goto out_cleanup; } - r = ttm_tt_populate(bo->bdev, bo->ttm, &ctx); + r = ttm_tt_populate(bo->bdev, bo->ttm, ctx); if (unlikely(r)) { goto out_cleanup; } @@ -246,22 +245,21 @@ static int radeon_move_vram_ram(struct ttm_buffer_object *bo, if (unlikely(r)) { goto out_cleanup; } - r = radeon_move_blit(bo, true, no_wait_gpu, &tmp_mem, old_mem); + r = radeon_move_blit(bo, true, &tmp_mem, old_mem); if (unlikely(r)) { goto out_cleanup; } - r = ttm_bo_move_ttm(bo, &ctx, new_mem); + r = ttm_bo_move_ttm(bo, ctx, new_mem); out_cleanup: ttm_resource_free(bo, &tmp_mem); return r; } static int radeon_move_ram_vram(struct ttm_buffer_object *bo, - bool evict, bool interruptible, - bool no_wait_gpu, + bool evict, + struct ttm_operation_ctx *ctx, struct ttm_resource *new_mem) { - struct ttm_operation_ctx ctx = { interruptible, no_wait_gpu }; struct ttm_resource *old_mem = &bo->mem; struct ttm_resource tmp_mem; struct ttm_placement placement; @@ -278,15 +276,15 @@ static int radeon_move_ram_vram(struct ttm_buffer_object *bo, placements.lpfn = 0; placements.mem_type = TTM_PL_TT; placements.flags = TTM_PL_MASK_CACHING; - r = ttm_bo_mem_space(bo, &placement, &tmp_mem, &ctx); + r = ttm_bo_mem_space(bo, &placement, &tmp_mem, ctx); if (unlikely(r)) { return r; } - r = ttm_bo_move_ttm(bo, &ctx, &tmp_mem); + r = ttm_bo_move_ttm(bo, ctx, &tmp_mem); if (unlikely(r)) { goto out_cleanup; } - r = radeon_move_blit(bo, true, no_wait_gpu, new_mem, old_mem); + r = radeon_move_blit(bo, true, new_mem, old_mem); if (unlikely(r)) { goto out_cleanup; } @@ -334,14 +332,12 @@ static int radeon_bo_move(struct ttm_buffer_object *bo, bool evict, if (old_mem->mem_type == TTM_PL_VRAM && new_mem->mem_type == TTM_PL_SYSTEM) { - r = radeon_move_vram_ram(bo, evict, ctx->interruptible, - ctx->no_wait_gpu, new_mem); + r = radeon_move_vram_ram(bo, evict, ctx, new_mem); } else if (old_mem->mem_type == TTM_PL_SYSTEM && new_mem->mem_type == TTM_PL_VRAM) { - r = radeon_move_ram_vram(bo, evict, ctx->interruptible, - ctx->no_wait_gpu, new_mem); + r = radeon_move_ram_vram(bo, evict, ctx, new_mem); } else { - r = radeon_move_blit(bo, evict, ctx->no_wait_gpu, + r = radeon_move_blit(bo, evict, new_mem, old_mem); } From 5466186745937e950bd17ee66f3f59cc329b6b71 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 23 Sep 2020 13:04:48 +1000 Subject: [PATCH 013/235] drm/nouveau/ttm: plumb ctx through move functions. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This just uses the ctx instead of passing bools and recreating it. Acked-by: Christian König Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20200923030454.362731-5-airlied@gmail.com --- drivers/gpu/drm/nouveau/nouveau_bo.c | 48 +++++++++++++--------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 2ee75646ad6f..0cbf5fb764ed 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -796,8 +796,9 @@ done: } static int -nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr, - bool no_wait_gpu, struct ttm_resource *new_reg) +nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, + struct ttm_operation_ctx *ctx, + struct ttm_resource *new_reg) { struct nouveau_drm *drm = nouveau_bdev(bo->bdev); struct nouveau_channel *chan = drm->ttm.chan; @@ -816,7 +817,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr, } mutex_lock_nested(&cli->mutex, SINGLE_DEPTH_NESTING); - ret = nouveau_fence_sync(nouveau_bo(bo), chan, true, intr); + ret = nouveau_fence_sync(nouveau_bo(bo), chan, true, ctx->interruptible); if (ret == 0) { ret = drm->ttm.move(chan, bo, &bo->mem, new_reg); if (ret == 0) { @@ -903,10 +904,10 @@ nouveau_bo_move_init(struct nouveau_drm *drm) } static int -nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr, - bool no_wait_gpu, struct ttm_resource *new_reg) +nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, + struct ttm_operation_ctx *ctx, + struct ttm_resource *new_reg) { - struct ttm_operation_ctx ctx = { intr, no_wait_gpu }; struct ttm_place placement_memtype = { .fpfn = 0, .lpfn = 0, @@ -922,11 +923,11 @@ nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr, tmp_reg = *new_reg; tmp_reg.mm_node = NULL; - ret = ttm_bo_mem_space(bo, &placement, &tmp_reg, &ctx); + ret = ttm_bo_mem_space(bo, &placement, &tmp_reg, ctx); if (ret) return ret; - ret = ttm_tt_populate(bo->bdev, bo->ttm, &ctx); + ret = ttm_tt_populate(bo->bdev, bo->ttm, ctx); if (ret) goto out; @@ -934,21 +935,21 @@ nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr, if (ret) goto out; - ret = nouveau_bo_move_m2mf(bo, true, intr, no_wait_gpu, &tmp_reg); + ret = nouveau_bo_move_m2mf(bo, true, ctx, &tmp_reg); if (ret) goto out; - ret = ttm_bo_move_ttm(bo, &ctx, new_reg); + ret = ttm_bo_move_ttm(bo, ctx, new_reg); out: ttm_resource_free(bo, &tmp_reg); return ret; } static int -nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, bool intr, - bool no_wait_gpu, struct ttm_resource *new_reg) +nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, + struct ttm_operation_ctx *ctx, + struct ttm_resource *new_reg) { - struct ttm_operation_ctx ctx = { intr, no_wait_gpu }; struct ttm_place placement_memtype = { .fpfn = 0, .lpfn = 0, @@ -964,15 +965,15 @@ nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, bool intr, tmp_reg = *new_reg; tmp_reg.mm_node = NULL; - ret = ttm_bo_mem_space(bo, &placement, &tmp_reg, &ctx); + ret = ttm_bo_mem_space(bo, &placement, &tmp_reg, ctx); if (ret) return ret; - ret = ttm_bo_move_ttm(bo, &ctx, &tmp_reg); + ret = ttm_bo_move_ttm(bo, ctx, &tmp_reg); if (ret) goto out; - ret = nouveau_bo_move_m2mf(bo, true, intr, no_wait_gpu, new_reg); + ret = nouveau_bo_move_m2mf(bo, true, ctx, new_reg); if (ret) goto out; @@ -1083,17 +1084,14 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, /* Hardware assisted copy. */ if (drm->ttm.move) { if (new_reg->mem_type == TTM_PL_SYSTEM) - ret = nouveau_bo_move_flipd(bo, evict, - ctx->interruptible, - ctx->no_wait_gpu, new_reg); + ret = nouveau_bo_move_flipd(bo, evict, ctx, + new_reg); else if (old_reg->mem_type == TTM_PL_SYSTEM) - ret = nouveau_bo_move_flips(bo, evict, - ctx->interruptible, - ctx->no_wait_gpu, new_reg); + ret = nouveau_bo_move_flips(bo, evict, ctx, + new_reg); else - ret = nouveau_bo_move_m2mf(bo, evict, - ctx->interruptible, - ctx->no_wait_gpu, new_reg); + ret = nouveau_bo_move_m2mf(bo, evict, ctx, + new_reg); if (!ret) goto out; } From 0ef1ed813e6b13d29331088070c7f554b350a266 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 23 Sep 2020 13:04:49 +1000 Subject: [PATCH 014/235] drm/ttm: add bo wait that takes a ctx wrapper. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I'm thinking of pushing the wait into the drivers. Reviewed-by: Christian König Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20200923030454.362731-6-airlied@gmail.com --- drivers/gpu/drm/nouveau/nouveau_bo.c | 4 ++-- drivers/gpu/drm/qxl/qxl_ttm.c | 2 +- drivers/gpu/drm/radeon/radeon_ttm.c | 2 +- drivers/gpu/drm/ttm/ttm_bo_util.c | 4 ++-- include/drm/ttm/ttm_bo_api.h | 5 +++++ 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 0cbf5fb764ed..a74bf1e8fdbe 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1062,7 +1062,7 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, struct nouveau_drm_tile *new_tile = NULL; int ret = 0; - ret = ttm_bo_wait(bo, ctx->interruptible, ctx->no_wait_gpu); + ret = ttm_bo_wait_ctx(bo, ctx); if (ret) return ret; @@ -1097,7 +1097,7 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, } /* Fallback to software copy. */ - ret = ttm_bo_wait(bo, ctx->interruptible, ctx->no_wait_gpu); + ret = ttm_bo_wait_ctx(bo, ctx); if (ret == 0) ret = ttm_bo_move_memcpy(bo, ctx, new_reg); diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c index fd691fff8394..320c202f163c 100644 --- a/drivers/gpu/drm/qxl/qxl_ttm.c +++ b/drivers/gpu/drm/qxl/qxl_ttm.c @@ -160,7 +160,7 @@ static int qxl_bo_move(struct ttm_buffer_object *bo, bool evict, struct ttm_resource *old_mem = &bo->mem; int ret; - ret = ttm_bo_wait(bo, ctx->interruptible, ctx->no_wait_gpu); + ret = ttm_bo_wait_ctx(bo, ctx); if (ret) return ret; diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index f3d424b3148e..6869770e2eef 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -302,7 +302,7 @@ static int radeon_bo_move(struct ttm_buffer_object *bo, bool evict, struct ttm_resource *old_mem = &bo->mem; int r; - r = ttm_bo_wait(bo, ctx->interruptible, ctx->no_wait_gpu); + r = ttm_bo_wait_ctx(bo, ctx); if (r) return r; diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index fb2a25f8408f..c90133d8a612 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -59,7 +59,7 @@ int ttm_bo_move_ttm(struct ttm_buffer_object *bo, int ret; if (old_mem->mem_type != TTM_PL_SYSTEM) { - ret = ttm_bo_wait(bo, ctx->interruptible, ctx->no_wait_gpu); + ret = ttm_bo_wait_ctx(bo, ctx); if (unlikely(ret != 0)) { if (ret != -ERESTARTSYS) @@ -231,7 +231,7 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, unsigned long add = 0; int dir; - ret = ttm_bo_wait(bo, ctx->interruptible, ctx->no_wait_gpu); + ret = ttm_bo_wait_ctx(bo, ctx); if (ret) return ret; diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 0f7cd21d6d74..6f544b6d70a3 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -261,6 +261,11 @@ ttm_bo_get_unless_zero(struct ttm_buffer_object *bo) */ int ttm_bo_wait(struct ttm_buffer_object *bo, bool interruptible, bool no_wait); +static inline int ttm_bo_wait_ctx(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx) +{ + return ttm_bo_wait(bo, ctx->interruptible, ctx->no_wait_gpu); +} + /** * ttm_bo_mem_compat - Check if proposed placement is compatible with a bo * From 6e5702980b14fccc79ba3f2a3331ff21bc6554be Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 18 Sep 2020 14:40:16 +0300 Subject: [PATCH 015/235] drm/dp: add subheadings to DPCD address definitions Add the subheadings from the DP spec. No functional changes. Reviewed-by: Manasi Navare Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20200918114017.30198-1-jani.nikula@intel.com --- include/drm/drm_dp_helper.h | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 85513eeb2196..a114b8f55909 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -104,8 +104,9 @@ #define DP_AUX_I2C_REPLY_DEFER (0x2 << 2) #define DP_AUX_I2C_REPLY_MASK (0x3 << 2) -/* AUX CH addresses */ -/* DPCD */ +/* DPCD Field Address Mapping */ + +/* Receiver Capability */ #define DP_DPCD_REV 0x000 # define DP_DPCD_REV_10 0x10 # define DP_DPCD_REV_11 0x11 @@ -407,7 +408,7 @@ #define DP_DSC_BRANCH_OVERALL_THROUGHPUT_1 0x0a1 #define DP_DSC_BRANCH_MAX_LINE_WIDTH 0x0a2 -/* link configuration */ +/* Link Configuration */ #define DP_LINK_BW_SET 0x100 # define DP_LINK_RATE_TABLE 0x00 /* eDP 1.4 */ # define DP_LINK_BW_1_62 0x06 @@ -561,6 +562,7 @@ #define DP_PAYLOAD_ALLOCATE_START_TIME_SLOT 0x1c1 #define DP_PAYLOAD_ALLOCATE_TIME_SLOT_COUNT 0x1c2 +/* Link/Sink Device Status */ #define DP_SINK_COUNT 0x200 /* prior to 1.2 bit 7 was reserved mbz */ # define DP_GET_SINK_COUNT(x) ((((x) & 0x80) >> 1) | ((x) & 0x3f)) @@ -760,20 +762,27 @@ #define DP_VC_PAYLOAD_ID_SLOT_1 0x2c1 /* 1.2 MST */ /* up to ID_SLOT_63 at 0x2ff */ +/* Source Device-specific */ #define DP_SOURCE_OUI 0x300 + +/* Sink Device-specific */ #define DP_SINK_OUI 0x400 + +/* Branch Device-specific */ #define DP_BRANCH_OUI 0x500 #define DP_BRANCH_ID 0x503 #define DP_BRANCH_REVISION_START 0x509 #define DP_BRANCH_HW_REV 0x509 #define DP_BRANCH_SW_REV 0x50A +/* Link/Sink Device Power Control */ #define DP_SET_POWER 0x600 # define DP_SET_POWER_D0 0x1 # define DP_SET_POWER_D3 0x2 # define DP_SET_POWER_MASK 0x3 # define DP_SET_POWER_D3_AUX_ON 0x5 +/* eDP-specific */ #define DP_EDP_DPCD_REV 0x700 /* eDP 1.2 */ # define DP_EDP_11 0x00 # define DP_EDP_12 0x01 @@ -857,11 +866,13 @@ #define DP_EDP_REGIONAL_BACKLIGHT_BASE 0x740 /* eDP 1.4 */ #define DP_EDP_REGIONAL_BACKLIGHT_0 0x741 /* eDP 1.4 */ +/* Sideband MSG Buffers */ #define DP_SIDEBAND_MSG_DOWN_REQ_BASE 0x1000 /* 1.2 MST */ #define DP_SIDEBAND_MSG_UP_REP_BASE 0x1200 /* 1.2 MST */ #define DP_SIDEBAND_MSG_DOWN_REP_BASE 0x1400 /* 1.2 MST */ #define DP_SIDEBAND_MSG_UP_REQ_BASE 0x1600 /* 1.2 MST */ +/* DPRX Event Status Indicator */ #define DP_SINK_COUNT_ESI 0x2002 /* 1.2 */ /* 0-5 sink count */ # define DP_SINK_COUNT_CP_READY (1 << 6) @@ -915,6 +926,7 @@ #define DP_LANE_ALIGN_STATUS_UPDATED_ESI 0x200e /* status same as 0x204 */ #define DP_SINK_STATUS_ESI 0x200f /* status same as 0x205 */ +/* Extended Receiver Capability */ #define DP_DP13_DPCD_REV 0x2200 #define DP_DP13_MAX_LINK_RATE 0x2201 @@ -928,6 +940,7 @@ # define DP_VSC_EXT_CEA_SDP_SUPPORTED (1 << 6) /* DP 1.4 */ # define DP_VSC_EXT_CEA_SDP_CHAINING_SUPPORTED (1 << 7) /* DP 1.4 */ +/* Protocol Converter Extension */ /* HDMI CEC tunneling over AUX DP 1.3 section 5.3.3.3.1 DPCD 1.4+ */ #define DP_CEC_TUNNELING_CAPABILITY 0x3000 # define DP_CEC_TUNNELING_CAPABLE (1 << 0) @@ -984,6 +997,7 @@ #define DP_CEC_TX_MESSAGE_BUFFER 0x3020 #define DP_CEC_MESSAGE_BUFFER_LENGTH 0x10 +/* HDCP 1.3 and HDCP 2.2 */ #define DP_AUX_HDCP_BKSV 0x68000 #define DP_AUX_HDCP_RI_PRIME 0x68005 #define DP_AUX_HDCP_AKSV 0x68007 @@ -1029,7 +1043,7 @@ #define DP_HDCP_2_2_REG_STREAM_TYPE_OFFSET 0x69494 #define DP_HDCP_2_2_REG_DBG_OFFSET 0x69518 -/* Link Training (LT)-tunable PHY Repeaters */ +/* LTTPR: Link Training (LT)-tunable PHY Repeaters */ #define DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV 0xf0000 /* 1.3 */ #define DP_MAX_LINK_RATE_PHY_REPEATER 0xf0001 /* 1.4a */ #define DP_PHY_REPEATER_CNT 0xf0002 /* 1.3 */ From 7d56927efac71dd9bf4df7bfffcc80cef1d2ccb8 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 18 Sep 2020 14:40:17 +0300 Subject: [PATCH 016/235] drm/dp: add a number of DP 2.0 DPCD definitions Prepare for future with DP 2.0 DPCD definitions, with a couple of related drive-by cleanups. No functional changes. v2: Send the version that actually builds. Reviewed-by: Manasi Navare Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20200918114017.30198-2-jani.nikula@intel.com --- include/drm/drm_dp_helper.h | 52 ++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index a114b8f55909..ae4e20245ba3 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -123,6 +123,7 @@ #define DP_MAX_DOWNSPREAD 0x003 # define DP_MAX_DOWNSPREAD_0_5 (1 << 0) +# define DP_STREAM_REGENERATION_STATUS_CAP (1 << 1) /* 2.0 */ # define DP_NO_AUX_HANDSHAKE_LINK_TRAINING (1 << 6) # define DP_TPS4_SUPPORTED (1 << 7) @@ -140,6 +141,7 @@ #define DP_MAIN_LINK_CHANNEL_CODING 0x006 # define DP_CAP_ANSI_8B10B (1 << 0) +# define DP_CAP_ANSI_128B132B (1 << 1) /* 2.0 */ #define DP_DOWN_STREAM_PORT_COUNT 0x007 # define DP_PORT_COUNT_MASK 0x0f @@ -183,8 +185,14 @@ #define DP_FAUX_CAP 0x020 /* 1.2 */ # define DP_FAUX_CAP_1 (1 << 0) +#define DP_SINK_VIDEO_FALLBACK_FORMATS 0x020 /* 2.0 */ +# define DP_FALLBACK_1024x768_60HZ_24BPP (1 << 0) +# define DP_FALLBACK_1280x720_60HZ_24BPP (1 << 1) +# define DP_FALLBACK_1920x1080_60HZ_24BPP (1 << 2) + #define DP_MSTM_CAP 0x021 /* 1.2 */ # define DP_MST_CAP (1 << 0) +# define DP_SINGLE_STREAM_SIDEBAND_MSG (1 << 1) /* 2.0 */ #define DP_NUMBER_OF_AUDIO_ENDPOINTS 0x022 /* 1.2 */ @@ -415,6 +423,9 @@ # define DP_LINK_BW_2_7 0x0a # define DP_LINK_BW_5_4 0x14 /* 1.2 */ # define DP_LINK_BW_8_1 0x1e /* 1.4 */ +# define DP_LINK_BW_10 0x01 /* 2.0 128b/132b Link Layer */ +# define DP_LINK_BW_13_5 0x04 /* 2.0 128b/132b Link Layer */ +# define DP_LINK_BW_20 0x02 /* 2.0 128b/132b Link Layer */ #define DP_LANE_COUNT_SET 0x101 # define DP_LANE_COUNT_MASK 0x0f @@ -466,12 +477,15 @@ # define DP_TRAIN_PRE_EMPHASIS_SHIFT 3 # define DP_TRAIN_MAX_PRE_EMPHASIS_REACHED (1 << 5) +# define DP_TX_FFE_PRESET_VALUE_MASK (0xf << 0) /* 2.0 128b/132b Link Layer */ + #define DP_DOWNSPREAD_CTRL 0x107 # define DP_SPREAD_AMP_0_5 (1 << 4) # define DP_MSA_TIMING_PAR_IGNORE_EN (1 << 7) /* eDP */ #define DP_MAIN_LINK_CHANNEL_CODING_SET 0x108 # define DP_SET_ANSI_8B10B (1 << 0) +# define DP_SET_ANSI_128B132B (1 << 1) #define DP_I2C_SPEED_CONTROL_STATUS 0x109 /* DPI */ /* bitmask as for DP_I2C_SPEED_CAP */ @@ -490,8 +504,19 @@ # define DP_LINK_QUAL_PATTERN_ERROR_RATE 2 # define DP_LINK_QUAL_PATTERN_PRBS7 3 # define DP_LINK_QUAL_PATTERN_80BIT_CUSTOM 4 -# define DP_LINK_QUAL_PATTERN_HBR2_EYE 5 -# define DP_LINK_QUAL_PATTERN_MASK 7 +# define DP_LINK_QUAL_PATTERN_CP2520_PAT_1 5 +# define DP_LINK_QUAL_PATTERN_CP2520_PAT_2 6 +# define DP_LINK_QUAL_PATTERN_CP2520_PAT_3 7 +/* DP 2.0 UHBR10, UHBR13.5, UHBR20 */ +# define DP_LINK_QUAL_PATTERN_128B132B_TPS1 0x08 +# define DP_LINK_QUAL_PATTERN_128B132B_TPS2 0x10 +# define DP_LINK_QUAL_PATTERN_PRSBS9 0x18 +# define DP_LINK_QUAL_PATTERN_PRSBS11 0x20 +# define DP_LINK_QUAL_PATTERN_PRSBS15 0x28 +# define DP_LINK_QUAL_PATTERN_PRSBS23 0x30 +# define DP_LINK_QUAL_PATTERN_PRSBS31 0x38 +# define DP_LINK_QUAL_PATTERN_CUSTOM 0x40 +# define DP_LINK_QUAL_PATTERN_SQUARE 0x48 #define DP_TRAINING_LANE0_1_SET2 0x10f #define DP_TRAINING_LANE2_3_SET2 0x110 @@ -594,9 +619,9 @@ #define DP_LINK_STATUS_UPDATED (1 << 7) #define DP_SINK_STATUS 0x205 - -#define DP_RECEIVE_PORT_0_STATUS (1 << 0) -#define DP_RECEIVE_PORT_1_STATUS (1 << 1) +# define DP_RECEIVE_PORT_0_STATUS (1 << 0) +# define DP_RECEIVE_PORT_1_STATUS (1 << 1) +# define DP_STREAM_REGENERATION_STATUS (1 << 2) /* 2.0 */ #define DP_ADJUST_REQUEST_LANE0_1 0x206 #define DP_ADJUST_REQUEST_LANE2_3 0x207 @@ -609,6 +634,12 @@ # define DP_ADJUST_PRE_EMPHASIS_LANE1_MASK 0xc0 # define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT 6 +/* DP 2.0 128b/132b Link Layer */ +# define DP_ADJUST_TX_FFE_PRESET_LANE0_MASK (0xf << 0) +# define DP_ADJUST_TX_FFE_PRESET_LANE0_SHIFT 0 +# define DP_ADJUST_TX_FFE_PRESET_LANE1_MASK (0xf << 4) +# define DP_ADJUST_TX_FFE_PRESET_LANE1_SHIFT 4 + #define DP_ADJUST_REQUEST_POST_CURSOR2 0x20c # define DP_ADJUST_POST_CURSOR2_LANE0_MASK 0x03 # define DP_ADJUST_POST_CURSOR2_LANE0_SHIFT 0 @@ -926,9 +957,8 @@ #define DP_LANE_ALIGN_STATUS_UPDATED_ESI 0x200e /* status same as 0x204 */ #define DP_SINK_STATUS_ESI 0x200f /* status same as 0x205 */ -/* Extended Receiver Capability */ +/* Extended Receiver Capability: See DP_DPCD_REV for definitions */ #define DP_DP13_DPCD_REV 0x2200 -#define DP_DP13_MAX_LINK_RATE 0x2201 #define DP_DPRX_FEATURE_ENUMERATION_LIST 0x2210 /* DP 1.3 */ # define DP_GTC_CAP (1 << 0) /* DP 1.3 */ @@ -940,6 +970,14 @@ # define DP_VSC_EXT_CEA_SDP_SUPPORTED (1 << 6) /* DP 1.4 */ # define DP_VSC_EXT_CEA_SDP_CHAINING_SUPPORTED (1 << 7) /* DP 1.4 */ +#define DP_128B132B_SUPPORTED_LINK_RATES 0x2215 /* 2.0 */ +# define DP_UHBR10 (1 << 0) +# define DP_UHBR20 (1 << 1) +# define DP_UHBR13_5 (1 << 2) + +#define DP_128B132B_TRAINING_AUX_RD_INTERVAL 0x2216 /* 2.0 */ +# define DP_128B132B_TRAINING_AUX_RD_INTERVAL_MASK 0x7f + /* Protocol Converter Extension */ /* HDMI CEC tunneling over AUX DP 1.3 section 5.3.3.3.1 DPCD 1.4+ */ #define DP_CEC_TUNNELING_CAPABILITY 0x3000 From 84d28b4717578888fbdade0dc2a98941cdfd12a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 17 Sep 2020 13:16:53 +0200 Subject: [PATCH 017/235] drm/nouveau: stop using persistent_swap_storage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to Ben this is most likely just a leftover. Signed-off-by: Christian König Link: https://patchwork.freedesktop.org/patch/391078/?series=81804&rev=1 Reviewed-by: Dave Airlie --- drivers/gpu/drm/nouveau/nouveau_gem.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 89adadf4706b..5945c663381d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -209,7 +209,6 @@ nouveau_gem_new(struct nouveau_cli *cli, u64 size, int align, uint32_t domain, if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) nvbo->valid_domains &= domain; - nvbo->bo.persistent_swap_storage = nvbo->bo.base.filp; *pnvbo = nvbo; return 0; } From ab861424cb58283f46040fe42c2e44234a5070ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 17 Sep 2020 13:27:35 +0200 Subject: [PATCH 018/235] drm/ttm: remove persistent_swap_storage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not used any more. Cleanup the code as well while at it. Signed-off-by: Christian König Link: https://patchwork.freedesktop.org/patch/391079/?series=81804&rev=1 Reviewed-by: Dave Airlie --- drivers/gpu/drm/ttm/ttm_bo.c | 2 +- drivers/gpu/drm/ttm/ttm_tt.c | 61 ++++++++++++++++-------------------- include/drm/ttm/ttm_bo_api.h | 4 --- include/drm/ttm/ttm_tt.h | 3 +- 4 files changed, 29 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 61c05c47ea66..f341532243f1 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1583,7 +1583,7 @@ int ttm_bo_swapout(struct ttm_bo_global *glob, struct ttm_operation_ctx *ctx) if (bo->bdev->driver->swap_notify) bo->bdev->driver->swap_notify(bo); - ret = ttm_tt_swapout(bo->bdev, bo->ttm, bo->persistent_swap_storage); + ret = ttm_tt_swapout(bo->bdev, bo->ttm); out: /** diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index 87dd887f7806..23e9604bc924 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -148,8 +148,7 @@ void ttm_tt_destroy_common(struct ttm_bo_device *bdev, struct ttm_tt *ttm) { ttm_tt_unpopulate(bdev, ttm); - if (!(ttm->page_flags & TTM_PAGE_FLAG_PERSISTENT_SWAP) && - ttm->swap_storage) + if (ttm->swap_storage) fput(ttm->swap_storage); ttm->swap_storage = NULL; @@ -249,71 +248,67 @@ int ttm_tt_swapin(struct ttm_tt *ttm) struct file *swap_storage; struct page *from_page; struct page *to_page; - int i; - int ret = -ENOMEM; + gfp_t gfp_mask; + int i, ret; swap_storage = ttm->swap_storage; BUG_ON(swap_storage == NULL); swap_space = swap_storage->f_mapping; + gfp_mask = mapping_gfp_mask(swap_space); + if (ttm->page_flags & TTM_PAGE_FLAG_NO_RETRY) + gfp_mask |= __GFP_RETRY_MAYFAIL; for (i = 0; i < ttm->num_pages; ++i) { - gfp_t gfp_mask = mapping_gfp_mask(swap_space); - - gfp_mask |= (ttm->page_flags & TTM_PAGE_FLAG_NO_RETRY ? __GFP_RETRY_MAYFAIL : 0); - from_page = shmem_read_mapping_page_gfp(swap_space, i, gfp_mask); - + from_page = shmem_read_mapping_page_gfp(swap_space, i, + gfp_mask); if (IS_ERR(from_page)) { ret = PTR_ERR(from_page); goto out_err; } to_page = ttm->pages[i]; - if (unlikely(to_page == NULL)) + if (unlikely(to_page == NULL)) { + ret = -ENOMEM; goto out_err; + } copy_highpage(to_page, from_page); put_page(from_page); } - if (!(ttm->page_flags & TTM_PAGE_FLAG_PERSISTENT_SWAP)) - fput(swap_storage); + fput(swap_storage); ttm->swap_storage = NULL; ttm->page_flags &= ~TTM_PAGE_FLAG_SWAPPED; return 0; + out_err: return ret; } -int ttm_tt_swapout(struct ttm_bo_device *bdev, - struct ttm_tt *ttm, struct file *persistent_swap_storage) +int ttm_tt_swapout(struct ttm_bo_device *bdev, struct ttm_tt *ttm) { struct address_space *swap_space; struct file *swap_storage; struct page *from_page; struct page *to_page; - int i; - int ret = -ENOMEM; + gfp_t gfp_mask; + int i, ret; - if (!persistent_swap_storage) { - swap_storage = shmem_file_setup("ttm swap", - ttm->num_pages << PAGE_SHIFT, - 0); - if (IS_ERR(swap_storage)) { - pr_err("Failed allocating swap storage\n"); - return PTR_ERR(swap_storage); - } - } else { - swap_storage = persistent_swap_storage; + swap_storage = shmem_file_setup("ttm swap", + ttm->num_pages << PAGE_SHIFT, + 0); + if (IS_ERR(swap_storage)) { + pr_err("Failed allocating swap storage\n"); + return PTR_ERR(swap_storage); } swap_space = swap_storage->f_mapping; + gfp_mask = mapping_gfp_mask(swap_space); + if (ttm->page_flags & TTM_PAGE_FLAG_NO_RETRY) + gfp_mask |= __GFP_RETRY_MAYFAIL; for (i = 0; i < ttm->num_pages; ++i) { - gfp_t gfp_mask = mapping_gfp_mask(swap_space); - - gfp_mask |= (ttm->page_flags & TTM_PAGE_FLAG_NO_RETRY ? __GFP_RETRY_MAYFAIL : 0); - from_page = ttm->pages[i]; if (unlikely(from_page == NULL)) continue; @@ -332,13 +327,11 @@ int ttm_tt_swapout(struct ttm_bo_device *bdev, ttm_tt_unpopulate(bdev, ttm); ttm->swap_storage = swap_storage; ttm->page_flags |= TTM_PAGE_FLAG_SWAPPED; - if (persistent_swap_storage) - ttm->page_flags |= TTM_PAGE_FLAG_PERSISTENT_SWAP; return 0; + out_err: - if (!persistent_swap_storage) - fput(swap_storage); + fput(swap_storage); return ret; } diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 6f544b6d70a3..da837d22f78e 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -90,9 +90,6 @@ struct ttm_tt; * @kref: Reference count of this buffer object. When this refcount reaches * zero, the object is destroyed or put on the delayed delete list. * @mem: structure describing current placement. - * @persistent_swap_storage: Usually the swap storage is deleted for buffers - * pinned in physical memory. If this behaviour is not desired, this member - * holds a pointer to a persistent shmem object. * @ttm: TTM structure holding system pages. * @evicted: Whether the object was evicted without user-space knowing. * @deleted: True if the object is only a zombie and already deleted. @@ -139,7 +136,6 @@ struct ttm_buffer_object { */ struct ttm_resource mem; - struct file *persistent_swap_storage; struct ttm_tt *ttm; bool deleted; diff --git a/include/drm/ttm/ttm_tt.h b/include/drm/ttm/ttm_tt.h index 75208c0a0cac..91691240a509 100644 --- a/include/drm/ttm/ttm_tt.h +++ b/include/drm/ttm/ttm_tt.h @@ -36,7 +36,6 @@ struct ttm_operation_ctx; #define TTM_PAGE_FLAG_WRITE (1 << 3) #define TTM_PAGE_FLAG_SWAPPED (1 << 4) -#define TTM_PAGE_FLAG_PERSISTENT_SWAP (1 << 5) #define TTM_PAGE_FLAG_ZERO_ALLOC (1 << 6) #define TTM_PAGE_FLAG_DMA32 (1 << 7) #define TTM_PAGE_FLAG_SG (1 << 8) @@ -185,7 +184,7 @@ int ttm_tt_swapin(struct ttm_tt *ttm); * and cache flushes and potential page splitting / combining. */ int ttm_tt_set_placement_caching(struct ttm_tt *ttm, uint32_t placement); -int ttm_tt_swapout(struct ttm_bo_device *bdev, struct ttm_tt *ttm, struct file *persistent_swap_storage); +int ttm_tt_swapout(struct ttm_bo_device *bdev, struct ttm_tt *ttm); /** * ttm_tt_populate - allocate pages for a ttm From 8e3784dfef8a03143b13e7e4011f276a954f1bc6 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 22 Sep 2020 16:46:55 +0200 Subject: [PATCH 019/235] drm/ast: Reload gamma LUT after changing primary plane's color format The gamma LUT has to be reloaded after changing the primary plane's color format. This used to be done implicitly by the CRTC atomic_enable() helper after updating the primary plane. With the recent reordering of the steps, the primary plane's setup was moved last and invalidated the gamma LUT. Fix this by setting the LUT from within atomic_flush(). Signed-off-by: Thomas Zimmermann Reviewed-by: Daniel Vetter Fixes: 2f0ddd89fe32 ("drm/ast: Enable CRTC before planes") Cc: Thomas Zimmermann Cc: Daniel Vetter Cc: Dave Airlie Cc: dri-devel@lists.freedesktop.org Link: https://patchwork.freedesktop.org/patch/msgid/20200922144655.23624-1-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_mode.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 834a156e3a75..0a1e1cf57e19 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -742,7 +742,6 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) case DRM_MODE_DPMS_SUSPEND: if (ast->tx_chip_type == AST_TX_DP501) ast_set_dp501_video_output(crtc->dev, 1); - ast_crtc_load_lut(ast, crtc); break; case DRM_MODE_DPMS_OFF: if (ast->tx_chip_type == AST_TX_DP501) @@ -777,6 +776,21 @@ static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc, return 0; } +static void +ast_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) +{ + struct ast_private *ast = to_ast_private(crtc->dev); + struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc->state); + struct ast_crtc_state *old_ast_crtc_state = to_ast_crtc_state(old_crtc_state); + + /* + * The gamma LUT has to be reloaded after changing the primary + * plane's color format. + */ + if (old_ast_crtc_state->format != ast_crtc_state->format) + ast_crtc_load_lut(ast, crtc); +} + static void ast_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) @@ -830,6 +844,7 @@ ast_crtc_helper_atomic_disable(struct drm_crtc *crtc, static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = { .atomic_check = ast_crtc_helper_atomic_check, + .atomic_flush = ast_crtc_helper_atomic_flush, .atomic_enable = ast_crtc_helper_atomic_enable, .atomic_disable = ast_crtc_helper_atomic_disable, }; From deb0814b43f370a448a498409d949e38c9d8f02e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 21 Sep 2020 13:05:54 +0200 Subject: [PATCH 020/235] drm/ttm: add ttm_bo_pin()/ttm_bo_unpin() v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As an alternative to the placement flag add a pin count to the ttm buffer object. v2: add dma_resv_assert_help() calls Signed-off-by: Christian König Reviewed-by: Dave Airlie Reviewed-by: Huang Rui Link: https://patchwork.freedesktop.org/patch/391596/?series=81973&rev=1 --- drivers/gpu/drm/ttm/ttm_bo.c | 9 ++++++--- drivers/gpu/drm/ttm/ttm_bo_util.c | 2 +- include/drm/ttm/ttm_bo_api.h | 26 ++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index f341532243f1..ecb93fea50f6 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -115,7 +115,7 @@ static void ttm_bo_add_mem_to_lru(struct ttm_buffer_object *bo, struct ttm_bo_device *bdev = bo->bdev; struct ttm_resource_manager *man; - if (!list_empty(&bo->lru)) + if (!list_empty(&bo->lru) || bo->pin_count) return; if (mem->placement & TTM_PL_FLAG_NO_EVICT) @@ -165,7 +165,8 @@ void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo, ttm_bo_del_from_lru(bo); ttm_bo_add_mem_to_lru(bo, &bo->mem); - if (bulk && !(bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) { + if (bulk && !(bo->mem.placement & TTM_PL_FLAG_NO_EVICT) && + !bo->pin_count) { switch (bo->mem.mem_type) { case TTM_PL_TT: ttm_bo_bulk_move_set_pos(&bulk->tt[bo->priority], bo); @@ -544,8 +545,9 @@ static void ttm_bo_release(struct kref *kref) * shrinkers, now that they are queued for * destruction. */ - if (bo->mem.placement & TTM_PL_FLAG_NO_EVICT) { + if (bo->mem.placement & TTM_PL_FLAG_NO_EVICT || bo->pin_count) { bo->mem.placement &= ~TTM_PL_FLAG_NO_EVICT; + bo->pin_count = 0; ttm_bo_del_from_lru(bo); ttm_bo_add_mem_to_lru(bo, &bo->mem); } @@ -1172,6 +1174,7 @@ int ttm_bo_init_reserved(struct ttm_bo_device *bdev, bo->moving = NULL; bo->mem.placement = TTM_PL_FLAG_CACHED; bo->acc_size = acc_size; + bo->pin_count = 0; bo->sg = sg; if (resv) { bo->base.resv = resv; diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index c90133d8a612..bdee4df1f3f2 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -352,7 +352,6 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, return -ENOMEM; fbo->base = *bo; - fbo->base.mem.placement |= TTM_PL_FLAG_NO_EVICT; ttm_bo_get(bo); fbo->bo = bo; @@ -372,6 +371,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, kref_init(&fbo->base.kref); fbo->base.destroy = &ttm_transfered_destroy; fbo->base.acc_size = 0; + fbo->base.pin_count = 1; if (bo->type != ttm_bo_type_sg) fbo->base.base.resv = &fbo->base.base._resv; diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index da837d22f78e..2ff4fdada333 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -153,6 +153,7 @@ struct ttm_buffer_object { struct dma_fence *moving; unsigned priority; + unsigned pin_count; /** * Special members that are protected by the reserve lock @@ -607,6 +608,31 @@ static inline bool ttm_bo_uses_embedded_gem_object(struct ttm_buffer_object *bo) return bo->base.dev != NULL; } +/** + * ttm_bo_pin - Pin the buffer object. + * @bo: The buffer object to pin + * + * Make sure the buffer is not evicted any more during memory pressure. + */ +static inline void ttm_bo_pin(struct ttm_buffer_object *bo) +{ + dma_resv_assert_held(bo->base.resv); + ++bo->pin_count; +} + +/** + * ttm_bo_unpin - Unpin the buffer object. + * @bo: The buffer object to unpin + * + * Allows the buffer object to be evicted again during memory pressure. + */ +static inline void ttm_bo_unpin(struct ttm_buffer_object *bo) +{ + dma_resv_assert_held(bo->base.resv); + WARN_ON_ONCE(!bo->pin_count); + --bo->pin_count; +} + int ttm_mem_evict_first(struct ttm_bo_device *bdev, struct ttm_resource_manager *man, const struct ttm_place *place, From a3b3bef33519fa8edba60849dea29d93a503ebc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 21 Sep 2020 12:56:48 +0200 Subject: [PATCH 021/235] drm/vmwgfx: remove unused placement combination MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just some dead code cleanup. Signed-off-by: Christian König Reviewed-by: Dave Airlie Reviewed-by: Huang Rui Link: https://patchwork.freedesktop.org/patch/391599/?series=81973&rev=1 --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 1 - drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c | 30 ---------------------- 2 files changed, 31 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 1523b51a7284..9ceee4eb0b13 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -1008,7 +1008,6 @@ extern struct ttm_placement vmw_vram_placement; extern struct ttm_placement vmw_vram_ne_placement; extern struct ttm_placement vmw_vram_sys_placement; extern struct ttm_placement vmw_vram_gmr_placement; -extern struct ttm_placement vmw_vram_gmr_ne_placement; extern struct ttm_placement vmw_sys_placement; extern struct ttm_placement vmw_sys_ne_placement; extern struct ttm_placement vmw_evictable_placement; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c index 7454f797d37b..d7ea658e9910 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c @@ -65,13 +65,6 @@ static const struct ttm_place gmr_placement_flags = { .flags = TTM_PL_FLAG_CACHED }; -static const struct ttm_place gmr_ne_placement_flags = { - .fpfn = 0, - .lpfn = 0, - .mem_type = VMW_PL_GMR, - .flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_NO_EVICT -}; - static const struct ttm_place mob_placement_flags = { .fpfn = 0, .lpfn = 0, @@ -128,29 +121,6 @@ struct ttm_placement vmw_vram_gmr_placement = { .busy_placement = &gmr_placement_flags }; -static const struct ttm_place vram_gmr_ne_placement_flags[] = { - { - .fpfn = 0, - .lpfn = 0, - .mem_type = TTM_PL_VRAM, - .flags = TTM_PL_FLAG_CACHED | - TTM_PL_FLAG_NO_EVICT - }, { - .fpfn = 0, - .lpfn = 0, - .mem_type = VMW_PL_GMR, - .flags = TTM_PL_FLAG_CACHED | - TTM_PL_FLAG_NO_EVICT - } -}; - -struct ttm_placement vmw_vram_gmr_ne_placement = { - .num_placement = 2, - .placement = vram_gmr_ne_placement_flags, - .num_busy_placement = 1, - .busy_placement = &gmr_ne_placement_flags -}; - struct ttm_placement vmw_vram_sys_placement = { .num_placement = 1, .placement = &vram_placement_flags, From b254557cb244e2c18e59ee1cc2293128c52d2473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 21 Sep 2020 14:14:32 +0200 Subject: [PATCH 022/235] drm/vmwgfx: stop using ttm_bo_create v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement in the driver instead since it is the only user of that function. v2: fix usage of ttm_bo_init_reserved Signed-off-by: Christian König Reviewed-by: Dave Airlie Reviewed-by: Huang Rui Link: https://patchwork.freedesktop.org/patch/391614/?series=81973&rev=1 --- drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 43 ++++++++++++++++++++++ drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c | 6 +-- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 4 ++ drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c | 8 ++-- 4 files changed, 53 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c index 813f1b148094..c8ca09f0e627 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c @@ -487,6 +487,49 @@ static void vmw_user_bo_destroy(struct ttm_buffer_object *bo) ttm_prime_object_kfree(vmw_user_bo, prime); } +/** + * vmw_bo_create_kernel - Create a pinned BO for internal kernel use. + * + * @dev_priv: Pointer to the device private struct + * @size: size of the BO we need + * @placement: where to put it + * @p_bo: resulting BO + * + * Creates and pin a simple BO for in kernel use. + */ +int vmw_bo_create_kernel(struct vmw_private *dev_priv, unsigned long size, + struct ttm_placement *placement, + struct ttm_buffer_object **p_bo) +{ + unsigned npages = PAGE_ALIGN(size) >> PAGE_SHIFT; + struct ttm_operation_ctx ctx = { false, false }; + struct ttm_buffer_object *bo; + size_t acc_size; + int ret; + + bo = kzalloc(sizeof(*bo), GFP_KERNEL); + if (unlikely(!bo)) + return -ENOMEM; + + acc_size = ttm_round_pot(sizeof(*bo)); + acc_size += ttm_round_pot(npages * sizeof(void *)); + acc_size += ttm_round_pot(sizeof(struct ttm_tt)); + ret = ttm_bo_init_reserved(&dev_priv->bdev, bo, size, + ttm_bo_type_device, placement, 0, + &ctx, acc_size, NULL, NULL, NULL); + if (unlikely(ret)) + goto error_free; + + ttm_bo_pin(bo); + ttm_bo_unreserve(bo); + *p_bo = bo; + + return 0; + +error_free: + kfree(bo); + return ret; +} /** * vmw_bo_init - Initialize a vmw buffer object diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c index 3b41cf63110a..9a9fe10d829b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c @@ -1245,9 +1245,9 @@ int vmw_cmdbuf_set_pool_size(struct vmw_cmdbuf_man *man, !dev_priv->has_mob) return -ENOMEM; - ret = ttm_bo_create(&dev_priv->bdev, size, ttm_bo_type_device, - &vmw_mob_ne_placement, 0, false, - &man->cmd_space); + ret = vmw_bo_create_kernel(dev_priv, size, + &vmw_mob_placement, + &man->cmd_space); if (ret) return ret; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 9ceee4eb0b13..5d07de5183e1 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -845,6 +845,10 @@ extern void vmw_bo_get_guest_ptr(const struct ttm_buffer_object *buf, SVGAGuestPtr *ptr); extern void vmw_bo_pin_reserved(struct vmw_buffer_object *bo, bool pin); extern void vmw_bo_bo_free(struct ttm_buffer_object *bo); +extern int vmw_bo_create_kernel(struct vmw_private *dev_priv, + unsigned long size, + struct ttm_placement *placement, + struct ttm_buffer_object **p_bo); extern int vmw_bo_init(struct vmw_private *dev_priv, struct vmw_buffer_object *vmw_bo, size_t size, struct ttm_placement *placement, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c index d7ea658e9910..39a2f720f4ed 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c @@ -793,11 +793,9 @@ int vmw_bo_create_and_populate(struct vmw_private *dev_priv, struct ttm_buffer_object *bo; int ret; - ret = ttm_bo_create(&dev_priv->bdev, bo_size, - ttm_bo_type_device, - &vmw_sys_ne_placement, - 0, false, &bo); - + ret = vmw_bo_create_kernel(dev_priv, bo_size, + &vmw_sys_placement, + &bo); if (unlikely(ret != 0)) return ret; From fbe86ca567919b22bbba1220ce55020b1868879f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 21 Sep 2020 14:37:25 +0200 Subject: [PATCH 023/235] drm/vmwgfx: switch over to the new pin interface v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stop using TTM_PL_FLAG_NO_EVICT. v2: fix unconditional pinning Signed-off-by: Christian König Reviewed-by: Dave Airlie Reviewed-by: Huang Rui Link: https://patchwork.freedesktop.org/patch/391601/?series=81973&rev=1 --- drivers/gpu/drm/vmwgfx/vmwgfx_blit.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 49 +++++++++++----------- drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 7 +--- drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_shader.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c | 42 ------------------- drivers/gpu/drm/vmwgfx/vmwgfx_validation.c | 2 +- 11 files changed, 39 insertions(+), 85 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c b/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c index e8d66182cd7b..ea2f2f937eb3 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c @@ -459,9 +459,9 @@ int vmw_bo_cpu_blit(struct ttm_buffer_object *dst, int ret = 0; /* Buffer objects need to be either pinned or reserved: */ - if (!(dst->mem.placement & TTM_PL_FLAG_NO_EVICT)) + if (!(dst->pin_count)) dma_resv_assert_held(dst->base.resv); - if (!(src->mem.placement & TTM_PL_FLAG_NO_EVICT)) + if (!(src->pin_count)) dma_resv_assert_held(src->base.resv); if (!ttm_tt_is_populated(dst->ttm)) { diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c index c8ca09f0e627..9a66ba254326 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c @@ -106,7 +106,7 @@ int vmw_bo_pin_in_placement(struct vmw_private *dev_priv, if (unlikely(ret != 0)) goto err; - if (buf->pin_count > 0) + if (buf->base.pin_count > 0) ret = ttm_bo_mem_compat(placement, &bo->mem, &new_flags) == true ? 0 : -EINVAL; else @@ -155,7 +155,7 @@ int vmw_bo_pin_in_vram_or_gmr(struct vmw_private *dev_priv, if (unlikely(ret != 0)) goto err; - if (buf->pin_count > 0) { + if (buf->base.pin_count > 0) { ret = ttm_bo_mem_compat(&vmw_vram_gmr_placement, &bo->mem, &new_flags) == true ? 0 : -EINVAL; goto out_unreserve; @@ -246,12 +246,12 @@ int vmw_bo_pin_in_start_of_vram(struct vmw_private *dev_priv, if (bo->mem.mem_type == TTM_PL_VRAM && bo->mem.start < bo->num_pages && bo->mem.start > 0 && - buf->pin_count == 0) { + buf->base.pin_count == 0) { ctx.interruptible = false; (void) ttm_bo_validate(bo, &vmw_sys_placement, &ctx); } - if (buf->pin_count > 0) + if (buf->base.pin_count > 0) ret = ttm_bo_mem_compat(&placement, &bo->mem, &new_flags) == true ? 0 : -EINVAL; else @@ -343,23 +343,13 @@ void vmw_bo_pin_reserved(struct vmw_buffer_object *vbo, bool pin) dma_resv_assert_held(bo->base.resv); - if (pin) { - if (vbo->pin_count++ > 0) - return; - } else { - WARN_ON(vbo->pin_count <= 0); - if (--vbo->pin_count > 0) - return; - } + if (pin == !!bo->pin_count) + return; pl.fpfn = 0; pl.lpfn = 0; pl.mem_type = bo->mem.mem_type; pl.flags = bo->mem.placement; - if (pin) - pl.flags |= TTM_PL_FLAG_NO_EVICT; - else - pl.flags &= ~TTM_PL_FLAG_NO_EVICT; memset(&placement, 0, sizeof(placement)); placement.num_placement = 1; @@ -368,8 +358,12 @@ void vmw_bo_pin_reserved(struct vmw_buffer_object *vbo, bool pin) ret = ttm_bo_validate(bo, &placement, &ctx); BUG_ON(ret != 0 || bo->mem.mem_type != old_mem_type); -} + if (pin) + ttm_bo_pin(bo); + else + ttm_bo_unpin(bo); +} /** * vmw_bo_map_and_cache - Map a buffer object and cache the map @@ -539,6 +533,7 @@ error_free: * @size: Buffer object size in bytes. * @placement: Initial placement. * @interruptible: Whether waits should be performed interruptible. + * @pin: If the BO should be created pinned at a fixed location. * @bo_free: The buffer object destructor. * Returns: Zero on success, negative error code on error. * @@ -547,9 +542,10 @@ error_free: int vmw_bo_init(struct vmw_private *dev_priv, struct vmw_buffer_object *vmw_bo, size_t size, struct ttm_placement *placement, - bool interruptible, + bool interruptible, bool pin, void (*bo_free)(struct ttm_buffer_object *bo)) { + struct ttm_operation_ctx ctx = { interruptible, false }; struct ttm_bo_device *bdev = &dev_priv->bdev; size_t acc_size; int ret; @@ -563,11 +559,16 @@ int vmw_bo_init(struct vmw_private *dev_priv, vmw_bo->base.priority = 3; vmw_bo->res_tree = RB_ROOT; - ret = ttm_bo_init(bdev, &vmw_bo->base, size, - ttm_bo_type_device, placement, - 0, interruptible, acc_size, - NULL, NULL, bo_free); - return ret; + ret = ttm_bo_init_reserved(bdev, &vmw_bo->base, size, + ttm_bo_type_device, placement, + 0, &ctx, acc_size, NULL, NULL, bo_free); + if (unlikely(ret)) + return ret; + + if (pin) + ttm_bo_pin(&vmw_bo->base); + ttm_bo_unreserve(&vmw_bo->base); + return 0; } @@ -656,7 +657,7 @@ int vmw_user_bo_alloc(struct vmw_private *dev_priv, ret = vmw_bo_init(dev_priv, &user_bo->vbo, size, (dev_priv->has_mob) ? &vmw_sys_placement : - &vmw_vram_sys_placement, true, + &vmw_vram_sys_placement, true, false, &vmw_user_bo_destroy); if (unlikely(ret != 0)) return ret; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c index 65e8e7a97724..984d8884357d 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c @@ -410,8 +410,8 @@ static int vmw_cotable_resize(struct vmw_resource *res, size_t new_size) if (!buf) return -ENOMEM; - ret = vmw_bo_init(dev_priv, buf, new_size, &vmw_mob_ne_placement, - true, vmw_bo_bo_free); + ret = vmw_bo_init(dev_priv, buf, new_size, &vmw_mob_placement, + true, true, vmw_bo_bo_free); if (ret) { DRM_ERROR("Failed initializing new cotable MOB.\n"); return ret; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 31e3e5c9f362..bdb7a5e96560 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -372,7 +372,7 @@ static int vmw_dummy_query_bo_create(struct vmw_private *dev_priv) return -ENOMEM; ret = vmw_bo_init(dev_priv, vbo, PAGE_SIZE, - &vmw_sys_ne_placement, false, + &vmw_sys_placement, false, true, &vmw_bo_bo_free); if (unlikely(ret != 0)) return ret; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 5d07de5183e1..b45becbb00f8 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -99,7 +99,6 @@ struct vmw_fpriv { * struct vmw_buffer_object - TTM buffer object with vmwgfx additions * @base: The TTM buffer object * @res_tree: RB tree of resources using this buffer object as a backing MOB - * @pin_count: pin depth * @cpu_writers: Number of synccpu write grabs. Protected by reservation when * increased. May be decreased without reservation. * @dx_query_ctx: DX context if this buffer object is used as a DX query MOB @@ -110,7 +109,6 @@ struct vmw_fpriv { struct vmw_buffer_object { struct ttm_buffer_object base; struct rb_root res_tree; - s32 pin_count; atomic_t cpu_writers; /* Not ref-counted. Protected by binding_mutex */ struct vmw_resource *dx_query_ctx; @@ -852,7 +850,7 @@ extern int vmw_bo_create_kernel(struct vmw_private *dev_priv, extern int vmw_bo_init(struct vmw_private *dev_priv, struct vmw_buffer_object *vmw_bo, size_t size, struct ttm_placement *placement, - bool interruptible, + bool interruptible, bool pin, void (*bo_free)(struct ttm_buffer_object *bo)); extern int vmw_user_bo_verify_access(struct ttm_buffer_object *bo, struct ttm_object_file *tfile); @@ -1009,15 +1007,12 @@ extern void vmw_validation_mem_init_ttm(struct vmw_private *dev_priv, extern const size_t vmw_tt_size; extern struct ttm_placement vmw_vram_placement; -extern struct ttm_placement vmw_vram_ne_placement; extern struct ttm_placement vmw_vram_sys_placement; extern struct ttm_placement vmw_vram_gmr_placement; extern struct ttm_placement vmw_sys_placement; -extern struct ttm_placement vmw_sys_ne_placement; extern struct ttm_placement vmw_evictable_placement; extern struct ttm_placement vmw_srf_placement; extern struct ttm_placement vmw_mob_placement; -extern struct ttm_placement vmw_mob_ne_placement; extern struct ttm_placement vmw_nonfixed_placement; extern struct ttm_bo_driver vmw_bo_driver; extern const struct vmw_sg_table * diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index c59806d40e15..4d60201037d1 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c @@ -406,7 +406,7 @@ static int vmw_fb_create_bo(struct vmw_private *vmw_priv, ret = vmw_bo_init(vmw_priv, vmw_bo, size, &vmw_sys_placement, - false, + false, false, &vmw_bo_bo_free); if (unlikely(ret != 0)) goto err_unlock; /* init frees the buffer on failure */ diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index c0f156078dda..5e922d9d5f2c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c @@ -370,7 +370,7 @@ static int vmw_resource_buf_alloc(struct vmw_resource *res, ret = vmw_bo_init(res->dev_priv, backup, res->backup_size, res->func->backup_placement, - interruptible, + interruptible, false, &vmw_bo_bo_free); if (unlikely(ret != 0)) goto out_no_bo; @@ -1002,7 +1002,7 @@ int vmw_resource_pin(struct vmw_resource *res, bool interruptible) vbo = res->backup; ttm_bo_reserve(&vbo->base, interruptible, false, NULL); - if (!vbo->pin_count) { + if (!vbo->base.pin_count) { ret = ttm_bo_validate (&vbo->base, res->func->backup_placement, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index 4bf0f5ec4fc2..0a53d189fceb 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -451,8 +451,8 @@ vmw_sou_primary_plane_prepare_fb(struct drm_plane *plane, */ vmw_overlay_pause_all(dev_priv); ret = vmw_bo_init(dev_priv, vps->bo, size, - &vmw_vram_ne_placement, - false, &vmw_bo_bo_free); + &vmw_vram_placement, + false, true, &vmw_bo_bo_free); vmw_overlay_resume_all(dev_priv); if (ret) { vps->bo = NULL; /* vmw_bo_init frees on error */ diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c index e139fdfd1635..f328aa5839a2 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c @@ -978,8 +978,8 @@ int vmw_compat_shader_add(struct vmw_private *dev_priv, if (unlikely(!buf)) return -ENOMEM; - ret = vmw_bo_init(dev_priv, buf, size, &vmw_sys_ne_placement, - true, vmw_bo_bo_free); + ret = vmw_bo_init(dev_priv, buf, size, &vmw_sys_placement, + true, true, vmw_bo_bo_free); if (unlikely(ret != 0)) goto out; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c index 39a2f720f4ed..fc68f54df46a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c @@ -37,13 +37,6 @@ static const struct ttm_place vram_placement_flags = { .flags = TTM_PL_FLAG_CACHED }; -static const struct ttm_place vram_ne_placement_flags = { - .fpfn = 0, - .lpfn = 0, - .mem_type = TTM_PL_VRAM, - .flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_NO_EVICT -}; - static const struct ttm_place sys_placement_flags = { .fpfn = 0, .lpfn = 0, @@ -51,13 +44,6 @@ static const struct ttm_place sys_placement_flags = { .flags = TTM_PL_FLAG_CACHED }; -static const struct ttm_place sys_ne_placement_flags = { - .fpfn = 0, - .lpfn = 0, - .mem_type = TTM_PL_SYSTEM, - .flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_NO_EVICT -}; - static const struct ttm_place gmr_placement_flags = { .fpfn = 0, .lpfn = 0, @@ -72,13 +58,6 @@ static const struct ttm_place mob_placement_flags = { .flags = TTM_PL_FLAG_CACHED }; -static const struct ttm_place mob_ne_placement_flags = { - .fpfn = 0, - .lpfn = 0, - .mem_type = VMW_PL_MOB, - .flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_NO_EVICT -}; - struct ttm_placement vmw_vram_placement = { .num_placement = 1, .placement = &vram_placement_flags, @@ -128,13 +107,6 @@ struct ttm_placement vmw_vram_sys_placement = { .busy_placement = &sys_placement_flags }; -struct ttm_placement vmw_vram_ne_placement = { - .num_placement = 1, - .placement = &vram_ne_placement_flags, - .num_busy_placement = 1, - .busy_placement = &vram_ne_placement_flags -}; - struct ttm_placement vmw_sys_placement = { .num_placement = 1, .placement = &sys_placement_flags, @@ -142,13 +114,6 @@ struct ttm_placement vmw_sys_placement = { .busy_placement = &sys_placement_flags }; -struct ttm_placement vmw_sys_ne_placement = { - .num_placement = 1, - .placement = &sys_ne_placement_flags, - .num_busy_placement = 1, - .busy_placement = &sys_ne_placement_flags -}; - static const struct ttm_place evictable_placement_flags[] = { { .fpfn = 0, @@ -213,13 +178,6 @@ struct ttm_placement vmw_mob_placement = { .busy_placement = &mob_placement_flags }; -struct ttm_placement vmw_mob_ne_placement = { - .num_placement = 1, - .num_busy_placement = 1, - .placement = &mob_ne_placement_flags, - .busy_placement = &mob_ne_placement_flags -}; - struct ttm_placement vmw_nonfixed_placement = { .num_placement = 3, .placement = nonfixed_placement_flags, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c index e69bc373ae2e..f2e2bf6d1421 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c @@ -540,7 +540,7 @@ int vmw_validation_bo_validate_single(struct ttm_buffer_object *bo, if (atomic_read(&vbo->cpu_writers)) return -EBUSY; - if (vbo->pin_count > 0) + if (vbo->base.pin_count > 0) return 0; if (validate_as_mob) From 6797cea18d3982fce6a7d63e51b4cea0e3c8eb06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 21 Sep 2020 15:37:12 +0200 Subject: [PATCH 024/235] drm/nouveau: switch over to the new pin interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stop using TTM_PL_FLAG_NO_EVICT. Signed-off-by: Christian König Reviewed-by: Dave Airlie Reviewed-by: Huang Rui Link: https://patchwork.freedesktop.org/patch/391606/?series=81973&rev=1 --- drivers/gpu/drm/nouveau/nouveau_bo.c | 48 +++++++------------------- drivers/gpu/drm/nouveau/nouveau_bo.h | 3 -- drivers/gpu/drm/nouveau/nouveau_chan.c | 2 +- 3 files changed, 13 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index a74bf1e8fdbe..8d51cfca07c8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -139,7 +139,7 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo) struct drm_device *dev = drm->dev; struct nouveau_bo *nvbo = nouveau_bo(bo); - WARN_ON(nvbo->pin_refcnt > 0); + WARN_ON(nvbo->bo.pin_count > 0); nouveau_bo_del_io_reserve_lru(bo); nv10_bo_put_tile_region(dev, nvbo->tile, NULL); @@ -417,9 +417,8 @@ nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t domain, { struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); struct ttm_placement *pl = &nvbo->placement; - uint32_t flags = (nvbo->force_coherent ? TTM_PL_FLAG_UNCACHED : - TTM_PL_MASK_CACHING) | - (nvbo->pin_refcnt ? TTM_PL_FLAG_NO_EVICT : 0); + uint32_t flags = nvbo->force_coherent ? TTM_PL_FLAG_UNCACHED : + TTM_PL_MASK_CACHING; pl->placement = nvbo->placements; set_placement_list(drm, nvbo->placements, &pl->num_placement, @@ -453,7 +452,7 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t domain, bool contig) } } - if (nvbo->pin_refcnt) { + if (nvbo->bo.pin_count) { bool error = evict; switch (bo->mem.mem_type) { @@ -472,7 +471,7 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t domain, bool contig) bo->mem.mem_type, domain); ret = -EBUSY; } - nvbo->pin_refcnt++; + ttm_bo_pin(&nvbo->bo); goto out; } @@ -483,18 +482,12 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t domain, bool contig) goto out; } - nvbo->pin_refcnt++; nouveau_bo_placement_set(nvbo, domain, 0); - - /* drop pin_refcnt temporarily, so we don't trip the assertion - * in nouveau_bo_move() that makes sure we're not trying to - * move a pinned buffer - */ - nvbo->pin_refcnt--; ret = nouveau_bo_validate(nvbo, false, false); if (ret) goto out; - nvbo->pin_refcnt++; + + ttm_bo_pin(&nvbo->bo); switch (bo->mem.mem_type) { case TTM_PL_VRAM: @@ -519,30 +512,14 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo) { struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); struct ttm_buffer_object *bo = &nvbo->bo; - int ret, ref; + int ret; ret = ttm_bo_reserve(bo, false, false, NULL); if (ret) return ret; - ref = --nvbo->pin_refcnt; - WARN_ON_ONCE(ref < 0); - if (ref) - goto out; - - switch (bo->mem.mem_type) { - case TTM_PL_VRAM: - nouveau_bo_placement_set(nvbo, NOUVEAU_GEM_DOMAIN_VRAM, 0); - break; - case TTM_PL_TT: - nouveau_bo_placement_set(nvbo, NOUVEAU_GEM_DOMAIN_GART, 0); - break; - default: - break; - } - - ret = nouveau_bo_validate(nvbo, false, false); - if (ret == 0) { + ttm_bo_unpin(&nvbo->bo); + if (!nvbo->bo.pin_count) { switch (bo->mem.mem_type) { case TTM_PL_VRAM: drm->gem.vram_available += bo->mem.size; @@ -555,9 +532,8 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo) } } -out: ttm_bo_unreserve(bo); - return ret; + return 0; } int @@ -1066,7 +1042,7 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, if (ret) return ret; - if (nvbo->pin_refcnt) + if (nvbo->bo.pin_count) NV_WARN(drm, "Moving pinned object %p!\n", nvbo); if (drm->client.device.info.family < NV_DEVICE_INFO_V0_TESLA) { diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.h b/drivers/gpu/drm/nouveau/nouveau_bo.h index 2a23c8207436..ff68ded8d590 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.h +++ b/drivers/gpu/drm/nouveau/nouveau_bo.h @@ -40,9 +40,6 @@ struct nouveau_bo { struct nouveau_drm_tile *tile; - /* protect by the ttm reservation lock */ - int pin_refcnt; - struct ttm_bo_kmap_obj dma_buf_vmap; }; diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index 8f099601d2f2..5d191e58edf1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -107,7 +107,7 @@ nouveau_channel_del(struct nouveau_channel **pchan) nvif_object_dtor(&chan->push.ctxdma); nouveau_vma_del(&chan->push.vma); nouveau_bo_unmap(chan->push.buffer); - if (chan->push.buffer && chan->push.buffer->pin_refcnt) + if (chan->push.buffer && chan->push.buffer->bo.pin_count) nouveau_bo_unpin(chan->push.buffer); nouveau_bo_ref(NULL, &chan->push.buffer); kfree(chan); From d582723d76a4eeafdff70c0051225fcf7bc69e55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 21 Sep 2020 14:43:59 +0200 Subject: [PATCH 025/235] drm/vram-helper: switch over to the new pin interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stop using TTM_PL_FLAG_NO_EVICT. Signed-off-by: Christian König Acked-by: Thomas Zimmermann Reviewed-by: Dave Airlie Reviewed-by: Huang Rui Link: https://patchwork.freedesktop.org/patch/391603/?series=81973&rev=1 --- drivers/gpu/drm/drm_gem_vram_helper.c | 37 +++++++-------------------- include/drm/drm_gem_vram_helper.h | 3 --- 2 files changed, 9 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c b/drivers/gpu/drm/drm_gem_vram_helper.c index 375c79e23ca5..171ea57b0311 100644 --- a/drivers/gpu/drm/drm_gem_vram_helper.c +++ b/drivers/gpu/drm/drm_gem_vram_helper.c @@ -301,7 +301,7 @@ static u64 drm_gem_vram_pg_offset(struct drm_gem_vram_object *gbo) */ s64 drm_gem_vram_offset(struct drm_gem_vram_object *gbo) { - if (WARN_ON_ONCE(!gbo->pin_count)) + if (WARN_ON_ONCE(!gbo->bo.pin_count)) return (s64)-ENODEV; return drm_gem_vram_pg_offset(gbo) << PAGE_SHIFT; } @@ -310,24 +310,21 @@ EXPORT_SYMBOL(drm_gem_vram_offset); static int drm_gem_vram_pin_locked(struct drm_gem_vram_object *gbo, unsigned long pl_flag) { - int i, ret; struct ttm_operation_ctx ctx = { false, false }; + int ret; - if (gbo->pin_count) + if (gbo->bo.pin_count) goto out; if (pl_flag) drm_gem_vram_placement(gbo, pl_flag); - for (i = 0; i < gbo->placement.num_placement; ++i) - gbo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT; - ret = ttm_bo_validate(&gbo->bo, &gbo->placement, &ctx); if (ret < 0) return ret; out: - ++gbo->pin_count; + ttm_bo_pin(&gbo->bo); return 0; } @@ -369,26 +366,9 @@ int drm_gem_vram_pin(struct drm_gem_vram_object *gbo, unsigned long pl_flag) } EXPORT_SYMBOL(drm_gem_vram_pin); -static int drm_gem_vram_unpin_locked(struct drm_gem_vram_object *gbo) +static void drm_gem_vram_unpin_locked(struct drm_gem_vram_object *gbo) { - int i, ret; - struct ttm_operation_ctx ctx = { false, false }; - - if (WARN_ON_ONCE(!gbo->pin_count)) - return 0; - - --gbo->pin_count; - if (gbo->pin_count) - return 0; - - for (i = 0; i < gbo->placement.num_placement ; ++i) - gbo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT; - - ret = ttm_bo_validate(&gbo->bo, &gbo->placement, &ctx); - if (ret < 0) - return ret; - - return 0; + ttm_bo_unpin(&gbo->bo); } /** @@ -406,10 +386,11 @@ int drm_gem_vram_unpin(struct drm_gem_vram_object *gbo) ret = ttm_bo_reserve(&gbo->bo, true, false, NULL); if (ret) return ret; - ret = drm_gem_vram_unpin_locked(gbo); + + drm_gem_vram_unpin_locked(gbo); ttm_bo_unreserve(&gbo->bo); - return ret; + return 0; } EXPORT_SYMBOL(drm_gem_vram_unpin); diff --git a/include/drm/drm_gem_vram_helper.h b/include/drm/drm_gem_vram_helper.h index 62cc6e6c3a4f..128f88174d32 100644 --- a/include/drm/drm_gem_vram_helper.h +++ b/include/drm/drm_gem_vram_helper.h @@ -35,7 +35,6 @@ struct vm_area_struct; * @placement: TTM placement information. Supported placements are \ %TTM_PL_VRAM and %TTM_PL_SYSTEM * @placements: TTM placement information. - * @pin_count: Pin counter * * The type struct drm_gem_vram_object represents a GEM object that is * backed by VRAM. It can be used for simple framebuffer devices with @@ -64,8 +63,6 @@ struct drm_gem_vram_object { /* Supported placements are %TTM_PL_VRAM and %TTM_PL_SYSTEM */ struct ttm_placement placement; struct ttm_place placements[2]; - - int pin_count; }; /** From 9d36d4320462ce2d7de9f1eb81156f5d0d4919a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 21 Sep 2020 15:24:53 +0200 Subject: [PATCH 026/235] drm/qxl: switch over to the new pin interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stop using TTM_PL_FLAG_NO_EVICT. Signed-off-by: Christian König Reviewed-by: Gerd Hoffmann Tested-by: Gerd Hoffmann Reviewed-by: Dave Airlie Reviewed-by: Huang Rui Link: https://patchwork.freedesktop.org/patch/391607/?series=81973&rev=1 --- drivers/gpu/drm/qxl/qxl_debugfs.c | 2 +- drivers/gpu/drm/qxl/qxl_drv.h | 1 - drivers/gpu/drm/qxl/qxl_ioctl.c | 4 +-- drivers/gpu/drm/qxl/qxl_object.c | 44 +++++++++---------------------- drivers/gpu/drm/qxl/qxl_object.h | 2 +- drivers/gpu/drm/qxl/qxl_release.c | 4 +-- drivers/gpu/drm/qxl/qxl_ttm.c | 2 +- 7 files changed, 20 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_debugfs.c b/drivers/gpu/drm/qxl/qxl_debugfs.c index 524d35b648d8..183d15e2cf58 100644 --- a/drivers/gpu/drm/qxl/qxl_debugfs.c +++ b/drivers/gpu/drm/qxl/qxl_debugfs.c @@ -67,7 +67,7 @@ qxl_debugfs_buffers_info(struct seq_file *m, void *data) seq_printf(m, "size %ld, pc %d, num releases %d\n", (unsigned long)bo->tbo.base.size, - bo->pin_count, rel); + bo->tbo.pin_count, rel); } return 0; } diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index aae90a9ee1db..3602e8b34189 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -80,7 +80,6 @@ struct qxl_bo { struct ttm_place placements[3]; struct ttm_placement placement; struct ttm_bo_kmap_obj kmap; - unsigned int pin_count; void *kptr; unsigned int map_count; int type; diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c index 5cea6eea72ab..0bab9ec6adc1 100644 --- a/drivers/gpu/drm/qxl/qxl_ioctl.c +++ b/drivers/gpu/drm/qxl/qxl_ioctl.c @@ -326,8 +326,8 @@ static int qxl_update_area_ioctl(struct drm_device *dev, void *data, if (ret) goto out; - if (!qobj->pin_count) { - qxl_ttm_placement_from_domain(qobj, qobj->type, false); + if (!qobj->tbo.pin_count) { + qxl_ttm_placement_from_domain(qobj, qobj->type); ret = ttm_bo_validate(&qobj->tbo, &qobj->placement, &ctx); if (unlikely(ret)) goto out; diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c index 2bc364412e8b..d3635e3e3267 100644 --- a/drivers/gpu/drm/qxl/qxl_object.c +++ b/drivers/gpu/drm/qxl/qxl_object.c @@ -51,14 +51,12 @@ bool qxl_ttm_bo_is_qxl_bo(struct ttm_buffer_object *bo) return false; } -void qxl_ttm_placement_from_domain(struct qxl_bo *qbo, u32 domain, bool pinned) +void qxl_ttm_placement_from_domain(struct qxl_bo *qbo, u32 domain) { u32 c = 0; u32 pflag = 0; unsigned int i; - if (pinned) - pflag |= TTM_PL_FLAG_NO_EVICT; if (qbo->tbo.base.size <= PAGE_SIZE) pflag |= TTM_PL_FLAG_TOPDOWN; @@ -128,14 +126,13 @@ int qxl_bo_create(struct qxl_device *qdev, } bo->tbo.base.funcs = &qxl_object_funcs; bo->type = domain; - bo->pin_count = pinned ? 1 : 0; bo->surface_id = 0; INIT_LIST_HEAD(&bo->list); if (surf) bo->surf = *surf; - qxl_ttm_placement_from_domain(bo, domain, pinned); + qxl_ttm_placement_from_domain(bo, domain); r = ttm_bo_init(&qdev->mman.bdev, &bo->tbo, size, type, &bo->placement, 0, !kernel, size, @@ -147,6 +144,8 @@ int qxl_bo_create(struct qxl_device *qdev, size, domain); return r; } + if (pinned) + ttm_bo_pin(&bo->tbo); *bo_ptr = bo; return 0; } @@ -248,39 +247,22 @@ static int __qxl_bo_pin(struct qxl_bo *bo) struct drm_device *ddev = bo->tbo.base.dev; int r; - if (bo->pin_count) { - bo->pin_count++; + if (bo->tbo.pin_count) { + ttm_bo_pin(&bo->tbo); return 0; } - qxl_ttm_placement_from_domain(bo, bo->type, true); + qxl_ttm_placement_from_domain(bo, bo->type); r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); - if (likely(r == 0)) { - bo->pin_count = 1; - } + if (likely(r == 0)) + ttm_bo_pin(&bo->tbo); if (unlikely(r != 0)) dev_err(ddev->dev, "%p pin failed\n", bo); return r; } -static int __qxl_bo_unpin(struct qxl_bo *bo) +static void __qxl_bo_unpin(struct qxl_bo *bo) { - struct ttm_operation_ctx ctx = { false, false }; - struct drm_device *ddev = bo->tbo.base.dev; - int r, i; - - if (!bo->pin_count) { - dev_warn(ddev->dev, "%p unpin not necessary\n", bo); - return 0; - } - bo->pin_count--; - if (bo->pin_count) - return 0; - for (i = 0; i < bo->placement.num_placement; i++) - bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT; - r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); - if (unlikely(r != 0)) - dev_err(ddev->dev, "%p validate failed for unpin\n", bo); - return r; + ttm_bo_unpin(&bo->tbo); } /* @@ -314,9 +296,9 @@ int qxl_bo_unpin(struct qxl_bo *bo) if (r) return r; - r = __qxl_bo_unpin(bo); + __qxl_bo_unpin(bo); qxl_bo_unreserve(bo); - return r; + return 0; } void qxl_bo_force_delete(struct qxl_device *qdev) diff --git a/drivers/gpu/drm/qxl/qxl_object.h b/drivers/gpu/drm/qxl/qxl_object.h index 32d3bb967251..09a5c818324d 100644 --- a/drivers/gpu/drm/qxl/qxl_object.h +++ b/drivers/gpu/drm/qxl/qxl_object.h @@ -71,7 +71,7 @@ extern struct qxl_bo *qxl_bo_ref(struct qxl_bo *bo); extern void qxl_bo_unref(struct qxl_bo **bo); extern int qxl_bo_pin(struct qxl_bo *bo); extern int qxl_bo_unpin(struct qxl_bo *bo); -extern void qxl_ttm_placement_from_domain(struct qxl_bo *qbo, u32 domain, bool pinned); +extern void qxl_ttm_placement_from_domain(struct qxl_bo *qbo, u32 domain); extern bool qxl_ttm_bo_is_qxl_bo(struct ttm_buffer_object *bo); #endif diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c index 4fae3e393da1..e75e364655b8 100644 --- a/drivers/gpu/drm/qxl/qxl_release.c +++ b/drivers/gpu/drm/qxl/qxl_release.c @@ -231,8 +231,8 @@ static int qxl_release_validate_bo(struct qxl_bo *bo) struct ttm_operation_ctx ctx = { true, false }; int ret; - if (!bo->pin_count) { - qxl_ttm_placement_from_domain(bo, bo->type, false); + if (!bo->tbo.pin_count) { + qxl_ttm_placement_from_domain(bo, bo->type); ret = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); if (ret) return ret; diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c index 320c202f163c..2c35ca4270c6 100644 --- a/drivers/gpu/drm/qxl/qxl_ttm.c +++ b/drivers/gpu/drm/qxl/qxl_ttm.c @@ -67,7 +67,7 @@ static void qxl_evict_flags(struct ttm_buffer_object *bo, return; } qbo = to_qxl_bo(bo); - qxl_ttm_placement_from_domain(qbo, QXL_GEM_DOMAIN_CPU, false); + qxl_ttm_placement_from_domain(qbo, QXL_GEM_DOMAIN_CPU); *placement = qbo->placement; } From 0b8793f6e7fc097c112f1848aa7dab60b9ede5a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 21 Sep 2020 13:18:02 +0200 Subject: [PATCH 027/235] drm/radeon: switch over to the new pin interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stop using TTM_PL_FLAG_NO_EVICT. Signed-off-by: Christian König Reviewed-by: Dave Airlie Reviewed-by: Huang Rui Link: https://patchwork.freedesktop.org/patch/391610/?series=81973&rev=1 --- drivers/gpu/drm/radeon/radeon.h | 1 - drivers/gpu/drm/radeon/radeon_display.c | 9 ++---- drivers/gpu/drm/radeon/radeon_object.c | 37 ++++++------------------- drivers/gpu/drm/radeon/radeon_object.h | 2 +- drivers/gpu/drm/radeon/radeon_ttm.c | 2 +- 5 files changed, 13 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index a6d8de01194a..5d54bccebd4d 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -497,7 +497,6 @@ struct radeon_bo { struct ttm_buffer_object tbo; struct ttm_bo_kmap_obj kmap; u32 flags; - unsigned pin_count; void *kptr; u32 tiling_flags; u32 pitch; diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 7b69d6dfe44a..3eacf33bbe48 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -273,10 +273,7 @@ static void radeon_unpin_work_func(struct work_struct *__work) /* unpin of the old buffer */ r = radeon_bo_reserve(work->old_rbo, false); if (likely(r == 0)) { - r = radeon_bo_unpin(work->old_rbo); - if (unlikely(r != 0)) { - DRM_ERROR("failed to unpin buffer after flip\n"); - } + radeon_bo_unpin(work->old_rbo); radeon_bo_unreserve(work->old_rbo); } else DRM_ERROR("failed to reserve buffer after flip\n"); @@ -607,9 +604,7 @@ pflip_cleanup: DRM_ERROR("failed to reserve new rbo in error path\n"); goto cleanup; } - if (unlikely(radeon_bo_unpin(new_rbo) != 0)) { - DRM_ERROR("failed to unpin new rbo in error path\n"); - } + radeon_bo_unpin(new_rbo); radeon_bo_unreserve(new_rbo); cleanup: diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 76dfed30d61c..689426dd8480 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -334,8 +334,8 @@ int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, u64 max_offset, if (radeon_ttm_tt_has_userptr(bo->rdev, bo->tbo.ttm)) return -EPERM; - if (bo->pin_count) { - bo->pin_count++; + if (bo->tbo.pin_count) { + ttm_bo_pin(&bo->tbo); if (gpu_addr) *gpu_addr = radeon_bo_gpu_offset(bo); @@ -367,13 +367,11 @@ int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, u64 max_offset, bo->rdev->mc.visible_vram_size >> PAGE_SHIFT; else bo->placements[i].lpfn = max_offset >> PAGE_SHIFT; - - bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT; } r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); if (likely(r == 0)) { - bo->pin_count = 1; + ttm_bo_pin(&bo->tbo); if (gpu_addr != NULL) *gpu_addr = radeon_bo_gpu_offset(bo); if (domain == RADEON_GEM_DOMAIN_VRAM) @@ -391,32 +389,15 @@ int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr) return radeon_bo_pin_restricted(bo, domain, 0, gpu_addr); } -int radeon_bo_unpin(struct radeon_bo *bo) +void radeon_bo_unpin(struct radeon_bo *bo) { - struct ttm_operation_ctx ctx = { false, false }; - int r, i; - - if (!bo->pin_count) { - dev_warn(bo->rdev->dev, "%p unpin not necessary\n", bo); - return 0; - } - bo->pin_count--; - if (bo->pin_count) - return 0; - for (i = 0; i < bo->placement.num_placement; i++) { - bo->placements[i].lpfn = 0; - bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT; - } - r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); - if (likely(r == 0)) { + ttm_bo_unpin(&bo->tbo); + if (!bo->tbo.pin_count) { if (bo->tbo.mem.mem_type == TTM_PL_VRAM) bo->rdev->vram_pin_size -= radeon_bo_size(bo); else bo->rdev->gart_pin_size -= radeon_bo_size(bo); - } else { - dev_err(bo->rdev->dev, "%p validate failed for unpin\n", bo); } - return r; } int radeon_bo_evict_vram(struct radeon_device *rdev) @@ -549,7 +530,7 @@ int radeon_bo_list_validate(struct radeon_device *rdev, list_for_each_entry(lobj, head, tv.head) { struct radeon_bo *bo = lobj->robj; - if (!bo->pin_count) { + if (!bo->tbo.pin_count) { u32 domain = lobj->preferred_domains; u32 allowed = lobj->allowed_domains; u32 current_domain = @@ -629,7 +610,7 @@ int radeon_bo_get_surface_reg(struct radeon_bo *bo) break; old_object = reg->bo; - if (old_object->pin_count == 0) + if (old_object->tbo.pin_count == 0) steal = i; } @@ -816,7 +797,7 @@ int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo) return 0; /* Can't move a pinned BO to visible VRAM */ - if (rbo->pin_count > 0) + if (rbo->tbo.pin_count > 0) return -EINVAL; /* hurrah the memory is not visible ! */ diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index 430574caaf09..27cfb64057fe 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h @@ -146,7 +146,7 @@ extern void radeon_bo_unref(struct radeon_bo **bo); extern int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr); extern int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, u64 max_offset, u64 *gpu_addr); -extern int radeon_bo_unpin(struct radeon_bo *bo); +extern void radeon_bo_unpin(struct radeon_bo *bo); extern int radeon_bo_evict_vram(struct radeon_device *rdev); extern void radeon_bo_force_delete(struct radeon_device *rdev); extern int radeon_bo_init(struct radeon_device *rdev); diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 6869770e2eef..ea9ffa6198da 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -308,7 +308,7 @@ static int radeon_bo_move(struct ttm_buffer_object *bo, bool evict, /* Can't move a pinned BO */ rbo = container_of(bo, struct radeon_bo, tbo); - if (WARN_ON_ONCE(rbo->pin_count > 0)) + if (WARN_ON_ONCE(rbo->tbo.pin_count > 0)) return -EINVAL; rdev = radeon_get_rdev(bo->bdev); From 4671078eb8e390bd44c458e2f482fbb61f5bc612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 21 Sep 2020 15:55:39 +0200 Subject: [PATCH 028/235] drm/amdgpu: switch over to the new pin interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stop using TTM_PL_FLAG_NO_EVICT. Signed-off-by: Christian König Tested-by: Nirmoy Das Reviewed-by: Dave Airlie Reviewed-by: Huang Rui Link: https://patchwork.freedesktop.org/patch/391617/?series=81973&rev=1 --- .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 5 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 8 +--- drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 5 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 41 +++++-------------- drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | 3 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 2 +- 9 files changed, 24 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index b6b821500d30..64d4b5ff95d6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -1479,7 +1479,7 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu( } } - if (!amdgpu_ttm_tt_get_usermm(bo->tbo.ttm) && !bo->pin_count) + if (!amdgpu_ttm_tt_get_usermm(bo->tbo.ttm) && !bo->tbo.pin_count) amdgpu_bo_fence(bo, &avm->process_info->eviction_fence->base, true); @@ -1558,7 +1558,8 @@ int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu( * required. */ if (mem->mapped_to_gpu_memory == 0 && - !amdgpu_ttm_tt_get_usermm(mem->bo->tbo.ttm) && !mem->bo->pin_count) + !amdgpu_ttm_tt_get_usermm(mem->bo->tbo.ttm) && + !mem->bo->tbo.pin_count) amdgpu_amdkfd_remove_eviction_fence(mem->bo, process_info->eviction_fence); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 12598a4b5c78..d50b63a93d37 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -410,7 +410,7 @@ static int amdgpu_cs_bo_validate(struct amdgpu_cs_parser *p, uint32_t domain; int r; - if (bo->pin_count) + if (bo->tbo.pin_count) return 0; /* Don't move this buffer if we have depleted our allowance diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index c81206e6096f..4cba095b6c44 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -132,10 +132,7 @@ static void amdgpu_display_unpin_work_func(struct work_struct *__work) /* unpin of the old buffer */ r = amdgpu_bo_reserve(work->old_abo, true); if (likely(r == 0)) { - r = amdgpu_bo_unpin(work->old_abo); - if (unlikely(r != 0)) { - DRM_ERROR("failed to unpin buffer after flip\n"); - } + amdgpu_bo_unpin(work->old_abo); amdgpu_bo_unreserve(work->old_abo); } else DRM_ERROR("failed to reserve buffer after flip\n"); @@ -249,8 +246,7 @@ pflip_cleanup: } unpin: if (!adev->enable_virtual_display) - if (unlikely(amdgpu_bo_unpin(new_abo) != 0)) - DRM_ERROR("failed to unpin new abo in error path\n"); + amdgpu_bo_unpin(new_abo); unreserve: amdgpu_bo_unreserve(new_abo); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c index 957934926b24..5b465ab774d1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c @@ -281,7 +281,7 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach, struct sg_table *sgt; long r; - if (!bo->pin_count) { + if (!bo->tbo.pin_count) { /* move buffer into GTT or VRAM */ struct ttm_operation_ctx ctx = { false, false }; unsigned domains = AMDGPU_GEM_DOMAIN_GTT; @@ -390,7 +390,8 @@ static int amdgpu_dma_buf_begin_cpu_access(struct dma_buf *dma_buf, if (unlikely(ret != 0)) return ret; - if (!bo->pin_count && (bo->allowed_domains & AMDGPU_GEM_DOMAIN_GTT)) { + if (!bo->tbo.pin_count && + (bo->allowed_domains & AMDGPU_GEM_DOMAIN_GTT)) { amdgpu_bo_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_GTT); ret = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index aa7f230c71bf..59b52804622d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -860,7 +860,7 @@ static int amdgpu_debugfs_gem_bo_info(int id, void *ptr, void *data) seq_printf(m, "\t0x%08x: %12ld byte %s", id, amdgpu_bo_size(bo), placement); - pin_count = READ_ONCE(bo->pin_count); + pin_count = READ_ONCE(bo->tbo.pin_count); if (pin_count) seq_printf(m, " pin count %d", pin_count); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index ac043baac05d..63e9c5793c30 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -78,7 +78,7 @@ static void amdgpu_bo_destroy(struct ttm_buffer_object *tbo) struct amdgpu_device *adev = amdgpu_ttm_adev(tbo->bdev); struct amdgpu_bo *bo = ttm_to_amdgpu_bo(tbo); - if (bo->pin_count > 0) + if (bo->tbo.pin_count > 0) amdgpu_bo_subtract_pin_size(bo); amdgpu_bo_kunmap(bo); @@ -721,7 +721,7 @@ int amdgpu_bo_validate(struct amdgpu_bo *bo) uint32_t domain; int r; - if (bo->pin_count) + if (bo->tbo.pin_count) return 0; domain = bo->preferred_domains; @@ -918,13 +918,13 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, */ domain = amdgpu_bo_get_preferred_pin_domain(adev, domain); - if (bo->pin_count) { + if (bo->tbo.pin_count) { uint32_t mem_type = bo->tbo.mem.mem_type; if (!(domain & amdgpu_mem_type_to_domain(mem_type))) return -EINVAL; - bo->pin_count++; + ttm_bo_pin(&bo->tbo); if (max_offset != 0) { u64 domain_start = amdgpu_ttm_domain_start(adev, @@ -955,7 +955,6 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, if (!bo->placements[i].lpfn || (lpfn && lpfn < bo->placements[i].lpfn)) bo->placements[i].lpfn = lpfn; - bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT; } r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); @@ -964,7 +963,7 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, goto error; } - bo->pin_count = 1; + ttm_bo_pin(&bo->tbo); domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type); if (domain == AMDGPU_GEM_DOMAIN_VRAM) { @@ -1006,34 +1005,16 @@ int amdgpu_bo_pin(struct amdgpu_bo *bo, u32 domain) * Returns: * 0 for success or a negative error code on failure. */ -int amdgpu_bo_unpin(struct amdgpu_bo *bo) +void amdgpu_bo_unpin(struct amdgpu_bo *bo) { - struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); - struct ttm_operation_ctx ctx = { false, false }; - int r, i; - - if (WARN_ON_ONCE(!bo->pin_count)) { - dev_warn(adev->dev, "%p unpin not necessary\n", bo); - return 0; - } - bo->pin_count--; - if (bo->pin_count) - return 0; + ttm_bo_unpin(&bo->tbo); + if (bo->tbo.pin_count) + return; amdgpu_bo_subtract_pin_size(bo); if (bo->tbo.base.import_attach) dma_buf_unpin(bo->tbo.base.import_attach); - - for (i = 0; i < bo->placement.num_placement; i++) { - bo->placements[i].lpfn = 0; - bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT; - } - r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); - if (unlikely(r)) - dev_err(adev->dev, "%p validate failed for unpin\n", bo); - - return r; } /** @@ -1385,7 +1366,7 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo) return 0; /* Can't move a pinned BO to visible VRAM */ - if (abo->pin_count > 0) + if (abo->tbo.pin_count > 0) return -EINVAL; /* hurrah the memory is not visible ! */ @@ -1489,7 +1470,7 @@ u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo) { WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_SYSTEM); WARN_ON_ONCE(!dma_resv_is_locked(bo->tbo.base.resv) && - !bo->pin_count && bo->tbo.type != ttm_bo_type_kernel); + !bo->tbo.pin_count && bo->tbo.type != ttm_bo_type_kernel); WARN_ON_ONCE(bo->tbo.mem.start == AMDGPU_BO_INVALID_OFFSET); WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_VRAM && !(bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS)); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h index 5ddb6cf96030..e91750e43448 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h @@ -89,7 +89,6 @@ struct amdgpu_bo { struct ttm_buffer_object tbo; struct ttm_bo_kmap_obj kmap; u64 flags; - unsigned pin_count; u64 tiling_flags; u64 metadata_flags; void *metadata; @@ -267,7 +266,7 @@ void amdgpu_bo_unref(struct amdgpu_bo **bo); int amdgpu_bo_pin(struct amdgpu_bo *bo, u32 domain); int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, u64 min_offset, u64 max_offset); -int amdgpu_bo_unpin(struct amdgpu_bo *bo); +void amdgpu_bo_unpin(struct amdgpu_bo *bo); int amdgpu_bo_evict_vram(struct amdgpu_device *adev); int amdgpu_bo_init(struct amdgpu_device *adev); int amdgpu_bo_late_init(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index e7b67dc330a4..db5f761f37ec 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -662,7 +662,7 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict, /* Can't move a pinned BO */ abo = ttm_to_amdgpu_bo(bo); - if (WARN_ON_ONCE(abo->pin_count > 0)) + if (WARN_ON_ONCE(abo->tbo.pin_count > 0)) return -EINVAL; adev = amdgpu_ttm_adev(bo->bdev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 420931d36732..3e6243623082 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -609,7 +609,7 @@ void amdgpu_vm_del_from_lru_notify(struct ttm_buffer_object *bo) if (!amdgpu_bo_is_amdgpu_bo(bo)) return; - if (bo->mem.placement & TTM_PL_FLAG_NO_EVICT) + if (bo->pin_count) return; abo = ttm_to_amdgpu_bo(bo); From 28578f35338f9ec021d5a84f7931eb420a850f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 21 Sep 2020 15:59:50 +0200 Subject: [PATCH 029/235] drm/ttm: remove ttm_bo_create MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not used any more. Signed-off-by: Christian König Reviewed-by: Dave Airlie Reviewed-by: Huang Rui Link: https://patchwork.freedesktop.org/patch/391616/?series=81973&rev=1 --- drivers/gpu/drm/ttm/ttm_bo.c | 40 ------------------------------------ include/drm/ttm/ttm_bo_api.h | 24 ---------------------- 2 files changed, 64 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index ecb93fea50f6..8db822a65745 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1254,19 +1254,6 @@ int ttm_bo_init(struct ttm_bo_device *bdev, } EXPORT_SYMBOL(ttm_bo_init); -static size_t ttm_bo_acc_size(struct ttm_bo_device *bdev, - unsigned long bo_size, - unsigned struct_size) -{ - unsigned npages = (PAGE_ALIGN(bo_size)) >> PAGE_SHIFT; - size_t size = 0; - - size += ttm_round_pot(struct_size); - size += ttm_round_pot(npages * sizeof(void *)); - size += ttm_round_pot(sizeof(struct ttm_tt)); - return size; -} - size_t ttm_bo_dma_acc_size(struct ttm_bo_device *bdev, unsigned long bo_size, unsigned struct_size) @@ -1281,33 +1268,6 @@ size_t ttm_bo_dma_acc_size(struct ttm_bo_device *bdev, } EXPORT_SYMBOL(ttm_bo_dma_acc_size); -int ttm_bo_create(struct ttm_bo_device *bdev, - unsigned long size, - enum ttm_bo_type type, - struct ttm_placement *placement, - uint32_t page_alignment, - bool interruptible, - struct ttm_buffer_object **p_bo) -{ - struct ttm_buffer_object *bo; - size_t acc_size; - int ret; - - bo = kzalloc(sizeof(*bo), GFP_KERNEL); - if (unlikely(bo == NULL)) - return -ENOMEM; - - acc_size = ttm_bo_acc_size(bdev, size, sizeof(struct ttm_buffer_object)); - ret = ttm_bo_init(bdev, bo, size, type, placement, page_alignment, - interruptible, acc_size, - NULL, NULL, NULL); - if (likely(ret == 0)) - *p_bo = bo; - - return ret; -} -EXPORT_SYMBOL(ttm_bo_create); - int ttm_bo_evict_mm(struct ttm_bo_device *bdev, unsigned mem_type) { struct ttm_resource_manager *man = ttm_manager_type(bdev, mem_type); diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 2ff4fdada333..c96a25d571c8 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -448,30 +448,6 @@ int ttm_bo_init(struct ttm_bo_device *bdev, struct ttm_buffer_object *bo, struct sg_table *sg, struct dma_resv *resv, void (*destroy) (struct ttm_buffer_object *)); -/** - * ttm_bo_create - * - * @bdev: Pointer to a ttm_bo_device struct. - * @size: Requested size of buffer object. - * @type: Requested type of buffer object. - * @placement: Initial placement. - * @page_alignment: Data alignment in pages. - * @interruptible: If needing to sleep while waiting for GPU resources, - * sleep interruptible. - * @p_bo: On successful completion *p_bo points to the created object. - * - * This function allocates a ttm_buffer_object, and then calls ttm_bo_init - * on that object. The destroy function is set to kfree(). - * Returns - * -ENOMEM: Out of memory. - * -EINVAL: Invalid placement flags. - * -ERESTARTSYS: Interrupted by signal while waiting for resources. - */ -int ttm_bo_create(struct ttm_bo_device *bdev, unsigned long size, - enum ttm_bo_type type, struct ttm_placement *placement, - uint32_t page_alignment, bool interruptible, - struct ttm_buffer_object **p_bo); - /** * ttm_bo_evict_mm * From e8c93e0c6a1207ad96e99849410f2f5f4af853ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 21 Sep 2020 16:06:36 +0200 Subject: [PATCH 030/235] drm/ttm: remove TTM_PL_FLAG_NO_EVICT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not used any more. Signed-off-by: Christian König Reviewed-by: Dave Airlie Reviewed-by: Huang Rui Link: https://patchwork.freedesktop.org/patch/391604/?series=81973&rev=1 --- drivers/gpu/drm/ttm/ttm_bo.c | 11 +++-------- include/drm/ttm/ttm_placement.h | 1 - 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 8db822a65745..77a998b81843 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -118,9 +118,6 @@ static void ttm_bo_add_mem_to_lru(struct ttm_buffer_object *bo, if (!list_empty(&bo->lru) || bo->pin_count) return; - if (mem->placement & TTM_PL_FLAG_NO_EVICT) - return; - man = ttm_manager_type(bdev, mem->mem_type); list_add_tail(&bo->lru, &man->lru[bo->priority]); @@ -165,8 +162,7 @@ void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo, ttm_bo_del_from_lru(bo); ttm_bo_add_mem_to_lru(bo, &bo->mem); - if (bulk && !(bo->mem.placement & TTM_PL_FLAG_NO_EVICT) && - !bo->pin_count) { + if (bulk && !bo->pin_count) { switch (bo->mem.mem_type) { case TTM_PL_TT: ttm_bo_bulk_move_set_pos(&bulk->tt[bo->priority], bo); @@ -541,12 +537,11 @@ static void ttm_bo_release(struct kref *kref) spin_lock(&ttm_bo_glob.lru_lock); /* - * Make NO_EVICT bos immediately available to + * Make pinned bos immediately available to * shrinkers, now that they are queued for * destruction. */ - if (bo->mem.placement & TTM_PL_FLAG_NO_EVICT || bo->pin_count) { - bo->mem.placement &= ~TTM_PL_FLAG_NO_EVICT; + if (bo->pin_count) { bo->pin_count = 0; ttm_bo_del_from_lru(bo); ttm_bo_add_mem_to_lru(bo, &bo->mem); diff --git a/include/drm/ttm/ttm_placement.h b/include/drm/ttm/ttm_placement.h index d4022655eae4..50e72df48b8d 100644 --- a/include/drm/ttm/ttm_placement.h +++ b/include/drm/ttm/ttm_placement.h @@ -58,7 +58,6 @@ #define TTM_PL_FLAG_UNCACHED (1 << 17) #define TTM_PL_FLAG_WC (1 << 18) #define TTM_PL_FLAG_CONTIGUOUS (1 << 19) -#define TTM_PL_FLAG_NO_EVICT (1 << 21) #define TTM_PL_FLAG_TOPDOWN (1 << 22) #define TTM_PL_MASK_CACHING (TTM_PL_FLAG_CACHED | \ From b809979f112b6079acdae2649e2696f0cc812f84 Mon Sep 17 00:00:00 2001 From: Qinglang Miao Date: Mon, 21 Sep 2020 21:10:18 +0800 Subject: [PATCH 031/235] drm/panel: simplify the return expression of td028ttec1_prepare Simplify the return expression. Signed-off-by: Qinglang Miao Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200921131018.91513-1-miaoqinglang@huawei.com --- drivers/gpu/drm/panel/panel-tpo-td028ttec1.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-tpo-td028ttec1.c b/drivers/gpu/drm/panel/panel-tpo-td028ttec1.c index 037c14fd6bac..ba0c00d1a001 100644 --- a/drivers/gpu/drm/panel/panel-tpo-td028ttec1.c +++ b/drivers/gpu/drm/panel/panel-tpo-td028ttec1.c @@ -242,13 +242,8 @@ static int td028ttec1_prepare(struct drm_panel *panel) static int td028ttec1_enable(struct drm_panel *panel) { struct td028ttec1_panel *lcd = to_td028ttec1_device(panel); - int ret; - ret = jbt_ret_write_0(lcd, JBT_REG_DISPLAY_ON, NULL); - if (ret) - return ret; - - return 0; + return jbt_ret_write_0(lcd, JBT_REG_DISPLAY_ON, NULL); } static int td028ttec1_disable(struct drm_panel *panel) From 6236d953f7aca13403a1fada9d1dd12978cf93e8 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 24 Sep 2020 15:18:02 +1000 Subject: [PATCH 032/235] drm/ttm: handle the SYSTEM->TT path in same place as others. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This just consolidates the code making the flow easier to understand and also helps when moving move to the driver side. Reviewed-by: Christian König . Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20200924051845.397177-3-airlied@gmail.com --- drivers/gpu/drm/ttm/ttm_bo.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 77a998b81843..e11e8eaa6602 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -265,24 +265,22 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, if (ret) goto out_err; } - - if (bo->mem.mem_type == TTM_PL_SYSTEM) { - if (bdev->driver->move_notify) - bdev->driver->move_notify(bo, evict, mem); - bo->mem = *mem; - goto moved; - } } if (bdev->driver->move_notify) bdev->driver->move_notify(bo, evict, mem); - if (old_man->use_tt && new_man->use_tt) - ret = ttm_bo_move_ttm(bo, ctx, mem); - else if (bdev->driver->move) + if (old_man->use_tt && new_man->use_tt) { + if (bo->mem.mem_type == TTM_PL_SYSTEM) { + ttm_bo_assign_mem(bo, mem); + ret = 0; + } else + ret = ttm_bo_move_ttm(bo, ctx, mem); + } else if (bdev->driver->move) { ret = bdev->driver->move(bo, evict, ctx, mem); - else + } else { ret = ttm_bo_move_memcpy(bo, ctx, mem); + } if (ret) { if (bdev->driver->move_notify) { @@ -294,7 +292,6 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, goto out_err; } -moved: ctx->bytes_moved += bo->num_pages << PAGE_SHIFT; return 0; From 3a08446b31e3614f6e018c6ac297b1312689a73a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 24 Sep 2020 15:18:03 +1000 Subject: [PATCH 033/235] drm/amdgpu/ttm: handle tt moves properly. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The core move code currently handles use_tt moves, for amdgpu this was being handled also in the driver, but not using the same paths. If moving between TT/SYSTEM (all the use_tt paths on amdgpu) use the core move function. Eventually the core will be flipped over to calling the driver. Reviewed-by: Christian König Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20200924051845.397177-4-airlied@gmail.com --- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index db5f761f37ec..d3bd2fd448be 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -671,14 +671,16 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict, ttm_bo_move_null(bo, new_mem); return 0; } - if ((old_mem->mem_type == TTM_PL_TT && - new_mem->mem_type == TTM_PL_SYSTEM) || - (old_mem->mem_type == TTM_PL_SYSTEM && - new_mem->mem_type == TTM_PL_TT)) { - /* bind is enough */ + if (old_mem->mem_type == TTM_PL_SYSTEM && + new_mem->mem_type == TTM_PL_TT) { ttm_bo_move_null(bo, new_mem); return 0; } + + if (old_mem->mem_type == TTM_PL_TT && + new_mem->mem_type == TTM_PL_SYSTEM) + return ttm_bo_move_ttm(bo, ctx, new_mem); + if (old_mem->mem_type == AMDGPU_PL_GDS || old_mem->mem_type == AMDGPU_PL_GWS || old_mem->mem_type == AMDGPU_PL_OA || From 51e50e542204329e36e248de14f4c7a466d2f677 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 24 Sep 2020 15:18:04 +1000 Subject: [PATCH 034/235] drm/radeon/ttm: handle ttm moves properly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The core move code currently handles use_tt moves, for radeon this was being handled also in the driver, but not using the same paths. If moving between TT/SYSTEM (all the use_tt paths on radeon) use the core move function. Eventually the core will be flipped over to calling the driver. Reviewed-by: Christian König Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20200924051845.397177-5-airlied@gmail.com --- drivers/gpu/drm/radeon/radeon_ttm.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index ea9ffa6198da..df5cedb2b632 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -316,14 +316,16 @@ static int radeon_bo_move(struct ttm_buffer_object *bo, bool evict, ttm_bo_move_null(bo, new_mem); return 0; } - if ((old_mem->mem_type == TTM_PL_TT && - new_mem->mem_type == TTM_PL_SYSTEM) || - (old_mem->mem_type == TTM_PL_SYSTEM && - new_mem->mem_type == TTM_PL_TT)) { - /* bind is enough */ + if (old_mem->mem_type == TTM_PL_SYSTEM && + new_mem->mem_type == TTM_PL_TT) { ttm_bo_move_null(bo, new_mem); return 0; } + + if (old_mem->mem_type == TTM_PL_TT && + new_mem->mem_type == TTM_PL_SYSTEM) + return ttm_bo_move_ttm(bo, ctx, new_mem); + if (!rdev->ring[radeon_copy_ring_index(rdev)].ready || rdev->asic->copy.copy == NULL) { /* use memcpy */ From fb4f3c92780da18f89d4e05c06b5f697b8b0a05a Mon Sep 17 00:00:00 2001 From: Yannick Fertre Date: Fri, 18 Sep 2020 13:47:36 +0200 Subject: [PATCH 035/235] drm/panel: rm68200: allow using non-continuous dsi clock The panel is able to work when dsi clock is non-continuous, thus the system power consumption can be reduced using such feature. Add MIPI_DSI_CLOCK_NON_CONTINUOUS to panel's mode_flags. Signed-off-by: Antonio Borneo Signed-off-by: Yannick Fertre Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200918114736.11322-1-yannick.fertre@st.com --- drivers/gpu/drm/panel/panel-raydium-rm68200.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panel/panel-raydium-rm68200.c b/drivers/gpu/drm/panel/panel-raydium-rm68200.c index f908eeafb1af..2b9e48b0a491 100644 --- a/drivers/gpu/drm/panel/panel-raydium-rm68200.c +++ b/drivers/gpu/drm/panel/panel-raydium-rm68200.c @@ -391,7 +391,7 @@ static int rm68200_probe(struct mipi_dsi_device *dsi) dsi->lanes = 2; dsi->format = MIPI_DSI_FMT_RGB888; dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | - MIPI_DSI_MODE_LPM; + MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS; drm_panel_init(&ctx->panel, dev, &rm68200_drm_funcs, DRM_MODE_CONNECTOR_DSI); From 61c523b932ae68d90c96ef60ae78d31d88f60f06 Mon Sep 17 00:00:00 2001 From: Xiaofei Tan Date: Thu, 17 Sep 2020 17:19:20 +0800 Subject: [PATCH 036/235] fbdev: mx3fb: remove unused variable 'irq' Remove the variable 'irq' that is set but never used. Signed-off-by: Xiaofei Tan Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/1600334360-4214-1-git-send-email-tanxiaofei@huawei.com --- drivers/video/fbdev/mx3fb.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/video/fbdev/mx3fb.c b/drivers/video/fbdev/mx3fb.c index 603731a5a72e..894617ddabcb 100644 --- a/drivers/video/fbdev/mx3fb.c +++ b/drivers/video/fbdev/mx3fb.c @@ -1428,7 +1428,6 @@ static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan) struct device *dev = mx3fb->dev; struct mx3fb_platform_data *mx3fb_pdata = dev_get_platdata(dev); const char *name = mx3fb_pdata->name; - unsigned int irq; struct fb_info *fbi; struct mx3fb_info *mx3fbi; const struct fb_videomode *mode; @@ -1441,7 +1440,6 @@ static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan) } ichan->client = mx3fb; - irq = ichan->eof_irq; if (ichan->dma_chan.chan_id != IDMAC_SDC_0) return -EINVAL; From a34ebe7e6d999fbf64fc567c1f0221a9b28551b0 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 22 Sep 2020 09:42:42 +0200 Subject: [PATCH 037/235] drm/panel: otm8009a: remove hack to force commands in HS The panel is able to receive commands in LP. The current hack to force backlight commands in HS was due to workaround an incorrect settings on DSI controller that prevents sending LP commands while video out was active. Remove the hack that forces HS commands. Changes in v2: - Added my signed-off Signed-off-by: Antonio Borneo Signed-off-by: Yannick Fertre Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200922074242.28719-1-yannick.fertre@st.com --- .../gpu/drm/panel/panel-orisetech-otm8009a.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c index b6e377aa1131..09ac255b102a 100644 --- a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c +++ b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c @@ -99,20 +99,6 @@ static void otm8009a_dcs_write_buf(struct otm8009a *ctx, const void *data, dev_warn(ctx->dev, "mipi dsi dcs write buffer failed\n"); } -static void otm8009a_dcs_write_buf_hs(struct otm8009a *ctx, const void *data, - size_t len) -{ - struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); - - /* data will be sent in dsi hs mode (ie. no lpm) */ - dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; - - otm8009a_dcs_write_buf(ctx, data, len); - - /* restore back the dsi lpm mode */ - dsi->mode_flags |= MIPI_DSI_MODE_LPM; -} - #define dcs_write_seq(ctx, seq...) \ ({ \ static const u8 d[] = { seq }; \ @@ -400,7 +386,7 @@ static int otm8009a_backlight_update_status(struct backlight_device *bd) */ data[0] = MIPI_DCS_SET_DISPLAY_BRIGHTNESS; data[1] = bd->props.brightness; - otm8009a_dcs_write_buf_hs(ctx, data, ARRAY_SIZE(data)); + otm8009a_dcs_write_buf(ctx, data, ARRAY_SIZE(data)); /* set Brightness Control & Backlight on */ data[1] = 0x24; @@ -412,7 +398,7 @@ static int otm8009a_backlight_update_status(struct backlight_device *bd) /* Update Brightness Control & Backlight */ data[0] = MIPI_DCS_WRITE_CONTROL_DISPLAY; - otm8009a_dcs_write_buf_hs(ctx, data, ARRAY_SIZE(data)); + otm8009a_dcs_write_buf(ctx, data, ARRAY_SIZE(data)); return 0; } From 880ee3b7615e7cc087f659cb80ce22f5db56f9a2 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 22 Sep 2020 09:42:53 +0200 Subject: [PATCH 038/235] drm/panel: otm8009a: allow using non-continuous dsi clock The panel is able to work when dsi clock is non-continuous, thus the system power consumption can be reduced using such feature. Add MIPI_DSI_CLOCK_NON_CONTINUOUS to panel's mode_flags. Changes in v2: - Added my signed-off Signed-off-by: Antonio Borneo Signed-off-by: Yannick Fertre Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200922074253.28810-1-yannick.fertre@st.com --- drivers/gpu/drm/panel/panel-orisetech-otm8009a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c index 09ac255b102a..f80b44a8a700 100644 --- a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c +++ b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c @@ -438,7 +438,7 @@ static int otm8009a_probe(struct mipi_dsi_device *dsi) dsi->lanes = 2; dsi->format = MIPI_DSI_FMT_RGB888; dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | - MIPI_DSI_MODE_LPM; + MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS; drm_panel_init(&ctx->panel, dev, &otm8009a_drm_funcs, DRM_MODE_CONNECTOR_DSI); From 4eb4d99dfe3018d86f4529112aa7082f43b6996a Mon Sep 17 00:00:00 2001 From: Tian Tao Date: Tue, 22 Sep 2020 20:44:29 +0800 Subject: [PATCH 039/235] drm/hisilicon: Support i2c driver algorithms for bit-shift adapters Adding driver implementation to support i2c driver algorithms for bit-shift adapters, so hibmc will using the interface provided by drm to read edid. Signed-off-by: Tian Tao Reviewed-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/1600778670-60370-2-git-send-email-tiantao6@hisilicon.com --- drivers/gpu/drm/hisilicon/hibmc/Makefile | 2 +- .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 25 ++++- .../gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c | 99 +++++++++++++++++++ 3 files changed, 124 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile b/drivers/gpu/drm/hisilicon/hibmc/Makefile index f99132715597..684ef794eb7c 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/Makefile +++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o hibmc_ttm.o +hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o hibmc_ttm.o hibmc_drm_i2c.o obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc-drm.o diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h index 197485e2fe0b..87d2aad0bb5e 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h @@ -14,11 +14,23 @@ #ifndef HIBMC_DRM_DRV_H #define HIBMC_DRM_DRV_H +#include +#include +#include + +#include #include #include struct drm_device; +struct hibmc_connector { + struct drm_connector base; + + struct i2c_adapter adapter; + struct i2c_algo_bit_data bit_data; +}; + struct hibmc_drm_private { /* hw */ void __iomem *mmio; @@ -31,10 +43,20 @@ struct hibmc_drm_private { struct drm_plane primary_plane; struct drm_crtc crtc; struct drm_encoder encoder; - struct drm_connector connector; + struct hibmc_connector connector; bool mode_config_initialized; }; +static inline struct hibmc_connector *to_hibmc_connector(struct drm_connector *connector) +{ + return container_of(connector, struct hibmc_connector, base); +} + +static inline struct hibmc_drm_private *to_hibmc_drm_private(struct drm_device *dev) +{ + return dev->dev_private; +} + void hibmc_set_power_mode(struct hibmc_drm_private *priv, unsigned int power_mode); void hibmc_set_current_gate(struct hibmc_drm_private *priv, @@ -47,6 +69,7 @@ int hibmc_mm_init(struct hibmc_drm_private *hibmc); void hibmc_mm_fini(struct hibmc_drm_private *hibmc); int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev, struct drm_mode_create_dumb *args); +int hibmc_ddc_create(struct drm_device *drm_dev, struct hibmc_connector *connector); extern const struct drm_mode_config_funcs hibmc_mode_funcs; diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c new file mode 100644 index 000000000000..86d712090d87 --- /dev/null +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* Hisilicon Hibmc SoC drm driver + * + * Based on the bochs drm driver. + * + * Copyright (c) 2016 Huawei Limited. + * + * Author: + * Tian Tao + */ + +#include +#include + +#include +#include + +#include "hibmc_drm_drv.h" + +#define GPIO_DATA 0x0802A0 +#define GPIO_DATA_DIRECTION 0x0802A4 + +#define I2C_SCL_MASK BIT(0) +#define I2C_SDA_MASK BIT(1) + +static void hibmc_set_i2c_signal(void *data, u32 mask, int value) +{ + struct hibmc_connector *hibmc_connector = data; + struct hibmc_drm_private *priv = to_hibmc_drm_private(hibmc_connector->base.dev); + u32 tmp_dir = readl(priv->mmio + GPIO_DATA_DIRECTION); + + if (value) { + tmp_dir &= ~mask; + writel(tmp_dir, priv->mmio + GPIO_DATA_DIRECTION); + } else { + u32 tmp_data = readl(priv->mmio + GPIO_DATA); + + tmp_data &= ~mask; + writel(tmp_data, priv->mmio + GPIO_DATA); + + tmp_dir |= mask; + writel(tmp_dir, priv->mmio + GPIO_DATA_DIRECTION); + } +} + +static int hibmc_get_i2c_signal(void *data, u32 mask) +{ + struct hibmc_connector *hibmc_connector = data; + struct hibmc_drm_private *priv = to_hibmc_drm_private(hibmc_connector->base.dev); + u32 tmp_dir = readl(priv->mmio + GPIO_DATA_DIRECTION); + + if ((tmp_dir & mask) != mask) { + tmp_dir &= ~mask; + writel(tmp_dir, priv->mmio + GPIO_DATA_DIRECTION); + } + + return (readl(priv->mmio + GPIO_DATA) & mask) ? 1 : 0; +} + +static void hibmc_ddc_setsda(void *data, int state) +{ + hibmc_set_i2c_signal(data, I2C_SDA_MASK, state); +} + +static void hibmc_ddc_setscl(void *data, int state) +{ + hibmc_set_i2c_signal(data, I2C_SCL_MASK, state); +} + +static int hibmc_ddc_getsda(void *data) +{ + return hibmc_get_i2c_signal(data, I2C_SDA_MASK); +} + +static int hibmc_ddc_getscl(void *data) +{ + return hibmc_get_i2c_signal(data, I2C_SCL_MASK); +} + +int hibmc_ddc_create(struct drm_device *drm_dev, + struct hibmc_connector *connector) +{ + connector->adapter.owner = THIS_MODULE; + connector->adapter.class = I2C_CLASS_DDC; + snprintf(connector->adapter.name, I2C_NAME_SIZE, "HIS i2c bit bus"); + connector->adapter.dev.parent = &drm_dev->pdev->dev; + i2c_set_adapdata(&connector->adapter, connector); + connector->adapter.algo_data = &connector->bit_data; + + connector->bit_data.udelay = 20; + connector->bit_data.timeout = usecs_to_jiffies(2000); + connector->bit_data.data = connector; + connector->bit_data.setsda = hibmc_ddc_setsda; + connector->bit_data.setscl = hibmc_ddc_setscl; + connector->bit_data.getsda = hibmc_ddc_getsda; + connector->bit_data.getscl = hibmc_ddc_getscl; + + return i2c_bit_add_bus(&connector->adapter); +} From a0d078d06e516184e2f575f3803935697b5e3ac6 Mon Sep 17 00:00:00 2001 From: Tian Tao Date: Tue, 22 Sep 2020 20:44:30 +0800 Subject: [PATCH 040/235] drm/hisilicon: Features to support reading resolutions from EDID Use drm_get_edid to get the resolution, if that fails, set it to a fixed resolution. Rewrite the desrtoy callback function to release resources. Signed-off-by: Tian Tao Reviewed-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/1600778670-60370-3-git-send-email-tiantao6@hisilicon.com --- .../gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 38 +++++++++++++++++-- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c index 376a05ddbc2f..c6999ed702aa 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c @@ -21,12 +21,24 @@ static int hibmc_connector_get_modes(struct drm_connector *connector) { int count; + void *edid; + struct hibmc_connector *hibmc_connector = to_hibmc_connector(connector); + + edid = drm_get_edid(connector, &hibmc_connector->adapter); + if (edid) { + drm_connector_update_edid_property(connector, edid); + count = drm_add_edid_modes(connector, edid); + if (count) + goto out; + } count = drm_add_modes_noedid(connector, connector->dev->mode_config.max_width, connector->dev->mode_config.max_height); drm_set_preferred_mode(connector, 1024, 768); +out: + kfree(edid); return count; } @@ -36,6 +48,14 @@ static enum drm_mode_status hibmc_connector_mode_valid(struct drm_connector *con return MODE_OK; } +static void hibmc_connector_destroy(struct drm_connector *connector) +{ + struct hibmc_connector *hibmc_connector = to_hibmc_connector(connector); + + i2c_del_adapter(&hibmc_connector->adapter); + drm_connector_cleanup(connector); +} + static const struct drm_connector_helper_funcs hibmc_connector_helper_funcs = { .get_modes = hibmc_connector_get_modes, @@ -44,7 +64,7 @@ static const struct drm_connector_helper_funcs static const struct drm_connector_funcs hibmc_connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = drm_connector_cleanup, + .destroy = hibmc_connector_destroy, .reset = drm_atomic_helper_connector_reset, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, @@ -77,10 +97,17 @@ static const struct drm_encoder_funcs hibmc_encoder_funcs = { int hibmc_vdac_init(struct hibmc_drm_private *priv) { struct drm_device *dev = priv->dev; + struct hibmc_connector *hibmc_connector = &priv->connector; struct drm_encoder *encoder = &priv->encoder; - struct drm_connector *connector = &priv->connector; + struct drm_connector *connector = &hibmc_connector->base; int ret; + ret = hibmc_ddc_create(dev, hibmc_connector); + if (ret) { + drm_err(dev, "failed to create ddc: %d\n", ret); + return ret; + } + encoder->possible_crtcs = 0x1; ret = drm_encoder_init(dev, encoder, &hibmc_encoder_funcs, DRM_MODE_ENCODER_DAC, NULL); @@ -91,12 +118,15 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv) drm_encoder_helper_add(encoder, &hibmc_encoder_helper_funcs); - ret = drm_connector_init(dev, connector, &hibmc_connector_funcs, - DRM_MODE_CONNECTOR_VGA); + ret = drm_connector_init_with_ddc(dev, connector, + &hibmc_connector_funcs, + DRM_MODE_CONNECTOR_VGA, + &hibmc_connector->adapter); if (ret) { drm_err(dev, "failed to init connector: %d\n", ret); return ret; } + drm_connector_helper_add(connector, &hibmc_connector_helper_funcs); drm_connector_attach_encoder(connector, encoder); From 246cb7e49a70e5c4b71caed5df518693c345bab7 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 23 Sep 2020 12:21:38 +0200 Subject: [PATCH 041/235] drm/amdgpu: Introduce GEM object functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GEM object functions deprecate several similar callback interfaces in struct drm_driver. This patch replaces the per-driver callbacks with per-instance callbacks in amdgpu. The only exception is gem_prime_mmap, which is non-trivial to convert. v3: * remove amdgpu_object.c from patch (Christian) v2: * move object-function instance to amdgpu_gem.c (Christian) * set callbacks in amdgpu_gem_object_create() (Christian) Signed-off-by: Thomas Zimmermann Reviewed-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20200923102159.24084-2-tzimmermann@suse.de --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 6 ------ drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 23 ++++++++++++++++++----- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h | 5 ----- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 3ded6f43f982..f359ffb77aa5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -1497,19 +1497,13 @@ static struct drm_driver kms_driver = { .lastclose = amdgpu_driver_lastclose_kms, .irq_handler = amdgpu_irq_handler, .ioctls = amdgpu_ioctls_kms, - .gem_free_object_unlocked = amdgpu_gem_object_free, - .gem_open_object = amdgpu_gem_object_open, - .gem_close_object = amdgpu_gem_object_close, .dumb_create = amdgpu_mode_dumb_create, .dumb_map_offset = amdgpu_mode_dumb_mmap, .fops = &amdgpu_driver_kms_fops, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_prime_export = amdgpu_gem_prime_export, .gem_prime_import = amdgpu_gem_prime_import, - .gem_prime_vmap = amdgpu_gem_prime_vmap, - .gem_prime_vunmap = amdgpu_gem_prime_vunmap, .gem_prime_mmap = amdgpu_gem_prime_mmap, .name = DRIVER_NAME, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index 59b52804622d..be08a63ef58c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -36,9 +36,12 @@ #include "amdgpu.h" #include "amdgpu_display.h" +#include "amdgpu_dma_buf.h" #include "amdgpu_xgmi.h" -void amdgpu_gem_object_free(struct drm_gem_object *gobj) +static const struct drm_gem_object_funcs amdgpu_gem_object_funcs; + +static void amdgpu_gem_object_free(struct drm_gem_object *gobj) { struct amdgpu_bo *robj = gem_to_amdgpu_bo(gobj); @@ -87,6 +90,7 @@ retry: return r; } *obj = &bo->tbo.base; + (*obj)->funcs = &amdgpu_gem_object_funcs; return 0; } @@ -119,8 +123,8 @@ void amdgpu_gem_force_release(struct amdgpu_device *adev) * Call from drm_gem_handle_create which appear in both new and open ioctl * case. */ -int amdgpu_gem_object_open(struct drm_gem_object *obj, - struct drm_file *file_priv) +static int amdgpu_gem_object_open(struct drm_gem_object *obj, + struct drm_file *file_priv) { struct amdgpu_bo *abo = gem_to_amdgpu_bo(obj); struct amdgpu_device *adev = amdgpu_ttm_adev(abo->tbo.bdev); @@ -152,8 +156,8 @@ int amdgpu_gem_object_open(struct drm_gem_object *obj, return 0; } -void amdgpu_gem_object_close(struct drm_gem_object *obj, - struct drm_file *file_priv) +static void amdgpu_gem_object_close(struct drm_gem_object *obj, + struct drm_file *file_priv) { struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); @@ -211,6 +215,15 @@ out_unlock: ttm_eu_backoff_reservation(&ticket, &list); } +static const struct drm_gem_object_funcs amdgpu_gem_object_funcs = { + .free = amdgpu_gem_object_free, + .open = amdgpu_gem_object_open, + .close = amdgpu_gem_object_close, + .export = amdgpu_gem_prime_export, + .vmap = amdgpu_gem_prime_vmap, + .vunmap = amdgpu_gem_prime_vunmap, +}; + /* * GEM ioctls. */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h index e0f025dd1b14..637bf51dbf06 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h @@ -33,11 +33,6 @@ #define AMDGPU_GEM_DOMAIN_MAX 0x3 #define gem_to_amdgpu_bo(gobj) container_of((gobj), struct amdgpu_bo, tbo.base) -void amdgpu_gem_object_free(struct drm_gem_object *obj); -int amdgpu_gem_object_open(struct drm_gem_object *obj, - struct drm_file *file_priv); -void amdgpu_gem_object_close(struct drm_gem_object *obj, - struct drm_file *file_priv); unsigned long amdgpu_gem_timeout(uint64_t timeout_ns); /* From ad01dd0376afbd7a39d78da543f5a048d4ae14c9 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 23 Sep 2020 12:21:39 +0200 Subject: [PATCH 042/235] drm/armada: Introduce GEM object functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GEM object functions deprecate several similar callback interfaces in struct drm_driver. This patch replaces the per-driver callbacks with per-instance callbacks in armada. Signed-off-by: Thomas Zimmermann Acked-by: Russell King Acked-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20200923102159.24084-3-tzimmermann@suse.de --- drivers/gpu/drm/armada/armada_drv.c | 3 --- drivers/gpu/drm/armada/armada_gem.c | 12 +++++++++++- drivers/gpu/drm/armada/armada_gem.h | 2 -- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c index 980d3f1f8f16..22247cfce80b 100644 --- a/drivers/gpu/drm/armada/armada_drv.c +++ b/drivers/gpu/drm/armada/armada_drv.c @@ -37,13 +37,10 @@ DEFINE_DRM_GEM_FOPS(armada_drm_fops); static struct drm_driver armada_drm_driver = { .lastclose = drm_fb_helper_lastclose, - .gem_free_object_unlocked = armada_gem_free_object, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_prime_export = armada_gem_prime_export, .gem_prime_import = armada_gem_prime_import, .dumb_create = armada_gem_dumb_create, - .gem_vm_ops = &armada_gem_vm_ops, .major = 1, .minor = 0, .name = "armada-drm", diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c index ecf8a55e93d9..c343fbefe47c 100644 --- a/drivers/gpu/drm/armada/armada_gem.c +++ b/drivers/gpu/drm/armada/armada_gem.c @@ -25,7 +25,7 @@ static vm_fault_t armada_gem_vm_fault(struct vm_fault *vmf) return vmf_insert_pfn(vmf->vma, vmf->address, pfn); } -const struct vm_operations_struct armada_gem_vm_ops = { +static const struct vm_operations_struct armada_gem_vm_ops = { .fault = armada_gem_vm_fault, .open = drm_gem_vm_open, .close = drm_gem_vm_close, @@ -184,6 +184,12 @@ armada_gem_map_object(struct drm_device *dev, struct armada_gem_object *dobj) return dobj->addr; } +static const struct drm_gem_object_funcs armada_gem_object_funcs = { + .free = armada_gem_free_object, + .export = armada_gem_prime_export, + .vm_ops = &armada_gem_vm_ops, +}; + struct armada_gem_object * armada_gem_alloc_private_object(struct drm_device *dev, size_t size) { @@ -195,6 +201,8 @@ armada_gem_alloc_private_object(struct drm_device *dev, size_t size) if (!obj) return NULL; + obj->obj.funcs = &armada_gem_object_funcs; + drm_gem_private_object_init(dev, &obj->obj, size); DRM_DEBUG_DRIVER("alloc private obj %p size %zu\n", obj, size); @@ -214,6 +222,8 @@ static struct armada_gem_object *armada_gem_alloc_object(struct drm_device *dev, if (!obj) return NULL; + obj->obj.funcs = &armada_gem_object_funcs; + if (drm_gem_object_init(dev, &obj->obj, size)) { kfree(obj); return NULL; diff --git a/drivers/gpu/drm/armada/armada_gem.h b/drivers/gpu/drm/armada/armada_gem.h index de04cc2c8f0e..ffcc7e8dd351 100644 --- a/drivers/gpu/drm/armada/armada_gem.h +++ b/drivers/gpu/drm/armada/armada_gem.h @@ -21,8 +21,6 @@ struct armada_gem_object { void *update_data; }; -extern const struct vm_operations_struct armada_gem_vm_ops; - #define drm_to_armada_gem(o) container_of(o, struct armada_gem_object, obj) void armada_gem_free_object(struct drm_gem_object *); From a77306278f2c7cc3fc91fecf8a53d686b0d12431 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 23 Sep 2020 12:21:40 +0200 Subject: [PATCH 043/235] drm/etnaviv: Introduce GEM object functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GEM object functions deprecate several similar callback interfaces in struct drm_driver. This patch replaces the per-driver callbacks with per-instance callbacks in etnaviv. The only exception is gem_prime_mmap, which is non-trivial to convert. Signed-off-by: Thomas Zimmermann Reviewed-by: Daniel Vetter Acked-by: Lucas Stach Acked-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20200923102159.24084-4-tzimmermann@suse.de --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 13 ------------- drivers/gpu/drm/etnaviv/etnaviv_drv.h | 1 - drivers/gpu/drm/etnaviv/etnaviv_gem.c | 19 ++++++++++++++++++- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index a9a3afaef9a1..aa270b79e585 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -468,12 +468,6 @@ static const struct drm_ioctl_desc etnaviv_ioctls[] = { ETNA_IOCTL(PM_QUERY_SIG, pm_query_sig, DRM_RENDER_ALLOW), }; -static const struct vm_operations_struct vm_ops = { - .fault = etnaviv_gem_fault, - .open = drm_gem_vm_open, - .close = drm_gem_vm_close, -}; - static const struct file_operations fops = { .owner = THIS_MODULE, .open = drm_open, @@ -490,16 +484,9 @@ static struct drm_driver etnaviv_drm_driver = { .driver_features = DRIVER_GEM | DRIVER_RENDER, .open = etnaviv_open, .postclose = etnaviv_postclose, - .gem_free_object_unlocked = etnaviv_gem_free_object, - .gem_vm_ops = &vm_ops, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_prime_pin = etnaviv_gem_prime_pin, - .gem_prime_unpin = etnaviv_gem_prime_unpin, - .gem_prime_get_sg_table = etnaviv_gem_prime_get_sg_table, .gem_prime_import_sg_table = etnaviv_gem_prime_import_sg_table, - .gem_prime_vmap = etnaviv_gem_prime_vmap, - .gem_prime_vunmap = etnaviv_gem_prime_vunmap, .gem_prime_mmap = etnaviv_gem_prime_mmap, #ifdef CONFIG_DEBUG_FS .debugfs_init = etnaviv_debugfs_init, diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnaviv/etnaviv_drv.h index 4d8dc9236e5f..914f0867ff71 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h @@ -49,7 +49,6 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, struct drm_file *file); int etnaviv_gem_mmap(struct file *filp, struct vm_area_struct *vma); -vm_fault_t etnaviv_gem_fault(struct vm_fault *vmf); int etnaviv_gem_mmap_offset(struct drm_gem_object *obj, u64 *offset); struct sg_table *etnaviv_gem_prime_get_sg_table(struct drm_gem_object *obj); void *etnaviv_gem_prime_vmap(struct drm_gem_object *obj); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c index ea19f1d27275..312e9d58d5a7 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c @@ -171,7 +171,7 @@ int etnaviv_gem_mmap(struct file *filp, struct vm_area_struct *vma) return obj->ops->mmap(obj, vma); } -vm_fault_t etnaviv_gem_fault(struct vm_fault *vmf) +static vm_fault_t etnaviv_gem_fault(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; struct drm_gem_object *obj = vma->vm_private_data; @@ -561,6 +561,22 @@ void etnaviv_gem_obj_add(struct drm_device *dev, struct drm_gem_object *obj) mutex_unlock(&priv->gem_lock); } +static const struct vm_operations_struct vm_ops = { + .fault = etnaviv_gem_fault, + .open = drm_gem_vm_open, + .close = drm_gem_vm_close, +}; + +static const struct drm_gem_object_funcs etnaviv_gem_object_funcs = { + .free = etnaviv_gem_free_object, + .pin = etnaviv_gem_prime_pin, + .unpin = etnaviv_gem_prime_unpin, + .get_sg_table = etnaviv_gem_prime_get_sg_table, + .vmap = etnaviv_gem_prime_vmap, + .vunmap = etnaviv_gem_prime_vunmap, + .vm_ops = &vm_ops, +}; + static int etnaviv_gem_new_impl(struct drm_device *dev, u32 size, u32 flags, const struct etnaviv_gem_ops *ops, struct drm_gem_object **obj) { @@ -595,6 +611,7 @@ static int etnaviv_gem_new_impl(struct drm_device *dev, u32 size, u32 flags, INIT_LIST_HEAD(&etnaviv_obj->vram_list); *obj = &etnaviv_obj->base; + (*obj)->funcs = &etnaviv_gem_object_funcs; return 0; } From a64325a1d76a9e15425c7747dfecea7c5631c82d Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 23 Sep 2020 12:21:41 +0200 Subject: [PATCH 044/235] drm/exynos: Introduce GEM object functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GEM object functions deprecate several similar callback interfaces in struct drm_driver. This patch replaces the per-driver callbacks with per-instance callbacks in exynos. The only exception is gem_prime_mmap, which is non-trivial to convert. Signed-off-by: Thomas Zimmermann Reviewed-by: Daniel Vetter Acked-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20200923102159.24084-5-tzimmermann@suse.de --- drivers/gpu/drm/exynos/exynos_drm_drv.c | 10 ---------- drivers/gpu/drm/exynos/exynos_drm_gem.c | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index dbd80f1e4c78..fe46680ca208 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -75,11 +75,6 @@ static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file) file->driver_priv = NULL; } -static const struct vm_operations_struct exynos_drm_gem_vm_ops = { - .open = drm_gem_vm_open, - .close = drm_gem_vm_close, -}; - static const struct drm_ioctl_desc exynos_ioctls[] = { DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CREATE, exynos_drm_gem_create_ioctl, DRM_RENDER_ALLOW), @@ -124,16 +119,11 @@ static struct drm_driver exynos_drm_driver = { .open = exynos_drm_open, .lastclose = drm_fb_helper_lastclose, .postclose = exynos_drm_postclose, - .gem_free_object_unlocked = exynos_drm_gem_free_object, - .gem_vm_ops = &exynos_drm_gem_vm_ops, .dumb_create = exynos_drm_gem_dumb_create, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, .gem_prime_import = exynos_drm_gem_prime_import, - .gem_prime_get_sg_table = exynos_drm_gem_prime_get_sg_table, .gem_prime_import_sg_table = exynos_drm_gem_prime_import_sg_table, - .gem_prime_vmap = exynos_drm_gem_prime_vmap, - .gem_prime_vunmap = exynos_drm_gem_prime_vunmap, .gem_prime_mmap = exynos_drm_gem_prime_mmap, .ioctls = exynos_ioctls, .num_ioctls = ARRAY_SIZE(exynos_ioctls), diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index efa476858db5..69a5cf28b4ae 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -129,6 +129,19 @@ void exynos_drm_gem_destroy(struct exynos_drm_gem *exynos_gem) kfree(exynos_gem); } +static const struct vm_operations_struct exynos_drm_gem_vm_ops = { + .open = drm_gem_vm_open, + .close = drm_gem_vm_close, +}; + +static const struct drm_gem_object_funcs exynos_drm_gem_object_funcs = { + .free = exynos_drm_gem_free_object, + .get_sg_table = exynos_drm_gem_prime_get_sg_table, + .vmap = exynos_drm_gem_prime_vmap, + .vunmap = exynos_drm_gem_prime_vunmap, + .vm_ops = &exynos_drm_gem_vm_ops, +}; + static struct exynos_drm_gem *exynos_drm_gem_init(struct drm_device *dev, unsigned long size) { @@ -143,6 +156,8 @@ static struct exynos_drm_gem *exynos_drm_gem_init(struct drm_device *dev, exynos_gem->size = size; obj = &exynos_gem->base; + obj->funcs = &exynos_drm_gem_object_funcs; + ret = drm_gem_object_init(dev, obj, size); if (ret < 0) { DRM_DEV_ERROR(dev->dev, "failed to initialize gem object\n"); From 7cd467d0fc661768c5d36cdb864c7115357c16ee Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 23 Sep 2020 12:21:42 +0200 Subject: [PATCH 045/235] drm/gma500: Introduce GEM object functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GEM object functions deprecate several similar callback interfaces in struct drm_driver. This patch replaces the per-driver callbacks with per-instance callbacks in gma500. Signed-off-by: Thomas Zimmermann Reviewed-by: Daniel Vetter Acked-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20200923102159.24084-6-tzimmermann@suse.de --- drivers/gpu/drm/gma500/framebuffer.c | 2 ++ drivers/gpu/drm/gma500/gem.c | 18 ++++++++++++++++-- drivers/gpu/drm/gma500/gem.h | 3 +++ drivers/gpu/drm/gma500/psb_drv.c | 9 --------- drivers/gpu/drm/gma500/psb_drv.h | 2 -- 5 files changed, 21 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index 54d9876b5305..5ede24fb44ae 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c @@ -24,6 +24,7 @@ #include #include "framebuffer.h" +#include "gem.h" #include "gtt.h" #include "psb_drv.h" #include "psb_intel_drv.h" @@ -285,6 +286,7 @@ static struct gtt_range *psbfb_alloc(struct drm_device *dev, int aligned_size) /* Begin by trying to use stolen memory backing */ backing = psb_gtt_alloc_range(dev, aligned_size, "fb", 1, PAGE_SIZE); if (backing) { + backing->gem.funcs = &psb_gem_object_funcs; drm_gem_private_object_init(dev, &backing->gem, aligned_size); return backing; } diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c index f9c4b1d76f56..8f07de83b6fb 100644 --- a/drivers/gpu/drm/gma500/gem.c +++ b/drivers/gpu/drm/gma500/gem.c @@ -18,7 +18,9 @@ #include "psb_drv.h" -void psb_gem_free_object(struct drm_gem_object *obj) +static vm_fault_t psb_gem_fault(struct vm_fault *vmf); + +static void psb_gem_free_object(struct drm_gem_object *obj) { struct gtt_range *gtt = container_of(obj, struct gtt_range, gem); @@ -36,6 +38,17 @@ int psb_gem_get_aperture(struct drm_device *dev, void *data, return -EINVAL; } +static const struct vm_operations_struct psb_gem_vm_ops = { + .fault = psb_gem_fault, + .open = drm_gem_vm_open, + .close = drm_gem_vm_close, +}; + +const struct drm_gem_object_funcs psb_gem_object_funcs = { + .free = psb_gem_free_object, + .vm_ops = &psb_gem_vm_ops, +}; + /** * psb_gem_create - create a mappable object * @file: the DRM file of the client @@ -63,6 +76,7 @@ int psb_gem_create(struct drm_file *file, struct drm_device *dev, u64 size, dev_err(dev->dev, "no memory for %lld byte GEM object\n", size); return -ENOSPC; } + r->gem.funcs = &psb_gem_object_funcs; /* Initialize the extra goodies GEM needs to do all the hard work */ if (drm_gem_object_init(dev, &r->gem, size) != 0) { psb_gtt_free_range(dev, r); @@ -123,7 +137,7 @@ int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev, * vma->vm_private_data points to the GEM object that is backing this * mapping. */ -vm_fault_t psb_gem_fault(struct vm_fault *vmf) +static vm_fault_t psb_gem_fault(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; struct drm_gem_object *obj; diff --git a/drivers/gpu/drm/gma500/gem.h b/drivers/gpu/drm/gma500/gem.h index 4a74dc623b6b..3741a711b9fd 100644 --- a/drivers/gpu/drm/gma500/gem.h +++ b/drivers/gpu/drm/gma500/gem.h @@ -8,6 +8,9 @@ #ifndef _GEM_H #define _GEM_H +extern const struct drm_gem_object_funcs psb_gem_object_funcs; + extern int psb_gem_create(struct drm_file *file, struct drm_device *dev, u64 size, u32 *handlep, int stolen, u32 align); + #endif diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index 34b4aae9a15e..b13376a6fb91 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c @@ -480,12 +480,6 @@ static const struct dev_pm_ops psb_pm_ops = { .runtime_idle = psb_runtime_idle, }; -static const struct vm_operations_struct psb_gem_vm_ops = { - .fault = psb_gem_fault, - .open = drm_gem_vm_open, - .close = drm_gem_vm_close, -}; - static const struct file_operations psb_gem_fops = { .owner = THIS_MODULE, .open = drm_open, @@ -507,9 +501,6 @@ static struct drm_driver driver = { .irq_uninstall = psb_irq_uninstall, .irq_handler = psb_irq_handler, - .gem_free_object_unlocked = psb_gem_free_object, - .gem_vm_ops = &psb_gem_vm_ops, - .dumb_create = psb_gem_dumb_create, .ioctls = psb_ioctls, .fops = &psb_gem_fops, diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h index 956926341316..c71a5a4e912c 100644 --- a/drivers/gpu/drm/gma500/psb_drv.h +++ b/drivers/gpu/drm/gma500/psb_drv.h @@ -735,12 +735,10 @@ extern const struct drm_connector_helper_funcs extern const struct drm_connector_funcs psb_intel_lvds_connector_funcs; /* gem.c */ -extern void psb_gem_free_object(struct drm_gem_object *obj); extern int psb_gem_get_aperture(struct drm_device *dev, void *data, struct drm_file *file); extern int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev, struct drm_mode_create_dumb *args); -extern vm_fault_t psb_gem_fault(struct vm_fault *vmf); /* psb_device.c */ extern const struct psb_ops psb_chip_ops; From 10012620ea653e46004756b6a02c9fa509382438 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 23 Sep 2020 12:21:43 +0200 Subject: [PATCH 046/235] drm/i915: Introduce GEM object functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GEM object functions deprecate several similar callback interfaces in struct drm_driver. This patch replaces the per-driver callbacks with per-instance callbacks in i915. v2: * move object-function instance to i915_gem_object.c (Jani) Signed-off-by: Thomas Zimmermann Reviewed-by: Tvrtko Ursulin Acked-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20200923102159.24084-7-tzimmermann@suse.de --- drivers/gpu/drm/i915/gem/i915_gem_object.c | 21 ++++++++++++++++--- drivers/gpu/drm/i915/gem/i915_gem_object.h | 3 --- drivers/gpu/drm/i915/i915_drv.c | 4 ---- .../gpu/drm/i915/selftests/mock_gem_device.c | 3 --- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c index c8421fd9d2dc..3389ac972d16 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c @@ -39,9 +39,18 @@ static struct i915_global_object { struct kmem_cache *slab_objects; } global; +static const struct drm_gem_object_funcs i915_gem_object_funcs; + struct drm_i915_gem_object *i915_gem_object_alloc(void) { - return kmem_cache_zalloc(global.slab_objects, GFP_KERNEL); + struct drm_i915_gem_object *obj; + + obj = kmem_cache_zalloc(global.slab_objects, GFP_KERNEL); + if (!obj) + return NULL; + obj->base.funcs = &i915_gem_object_funcs; + + return obj; } void i915_gem_object_free(struct drm_i915_gem_object *obj) @@ -101,7 +110,7 @@ void i915_gem_object_set_cache_coherency(struct drm_i915_gem_object *obj, !(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE); } -void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file) +static void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file) { struct drm_i915_gem_object *obj = to_intel_bo(gem); struct drm_i915_file_private *fpriv = file->driver_priv; @@ -264,7 +273,7 @@ static void __i915_gem_free_work(struct work_struct *work) i915_gem_flush_free_objects(i915); } -void i915_gem_free_object(struct drm_gem_object *gem_obj) +static void i915_gem_free_object(struct drm_gem_object *gem_obj) { struct drm_i915_gem_object *obj = to_intel_bo(gem_obj); struct drm_i915_private *i915 = to_i915(obj->base.dev); @@ -403,6 +412,12 @@ int __init i915_global_objects_init(void) return 0; } +static const struct drm_gem_object_funcs i915_gem_object_funcs = { + .free = i915_gem_free_object, + .close = i915_gem_close_object, + .export = i915_gem_prime_export, +}; + #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) #include "selftests/huge_gem_object.c" #include "selftests/huge_pages.c" diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index d46db8d8f38e..eaf3d4147be0 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -38,9 +38,6 @@ void __i915_gem_object_release_shmem(struct drm_i915_gem_object *obj, int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, int align); -void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file); -void i915_gem_free_object(struct drm_gem_object *obj); - void i915_gem_flush_free_objects(struct drm_i915_private *i915); struct sg_table * diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 00292a849c34..d580d86a75d4 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1853,12 +1853,8 @@ static struct drm_driver driver = { .lastclose = i915_driver_lastclose, .postclose = i915_driver_postclose, - .gem_close_object = i915_gem_close_object, - .gem_free_object_unlocked = i915_gem_free_object, - .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_prime_export = i915_gem_prime_export, .gem_prime_import = i915_gem_prime_import, .dumb_create = i915_gem_dumb_create, diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c index c207d2239791..cf81ba84ae0b 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c @@ -85,9 +85,6 @@ static struct drm_driver mock_driver = { .name = "mock", .driver_features = DRIVER_GEM, .release = mock_device_release, - - .gem_close_object = i915_gem_close_object, - .gem_free_object_unlocked = i915_gem_free_object, }; static void release_dev(struct device *dev) From 80cf656c25b6febea689c49a4bcec98ed8776d64 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 23 Sep 2020 12:21:44 +0200 Subject: [PATCH 047/235] drm/imx/dcss: Initialize DRM driver instance with CMA helper macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The i.MX DCSS driver uses CMA helpers with default callback functions. Initialize the driver structure with the rsp CMA helper macro. The driver is being converted to use GEM object functions as part of this change. Two callbacks, .gem_prime_export and .gem_prime_import, were initialized to their default implementations, so they are just kept empty now. Signed-off-by: Thomas Zimmermann Reviewed-by: Laurentiu Palcu Acked-by: Christian König Reported-by: kernel test robot Link: https://patchwork.freedesktop.org/patch/msgid/20200923102159.24084-8-tzimmermann@suse.de --- drivers/gpu/drm/imx/dcss/dcss-kms.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/gpu/drm/imx/dcss/dcss-kms.c b/drivers/gpu/drm/imx/dcss/dcss-kms.c index 135a62366ab8..b72e5cef7e40 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-kms.c +++ b/drivers/gpu/drm/imx/dcss/dcss-kms.c @@ -28,19 +28,7 @@ static const struct drm_mode_config_funcs dcss_drm_mode_config_funcs = { static struct drm_driver dcss_kms_driver = { .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, - .gem_free_object_unlocked = drm_gem_cma_free_object, - .gem_vm_ops = &drm_gem_cma_vm_ops, - .dumb_create = drm_gem_cma_dumb_create, - - .prime_handle_to_fd = drm_gem_prime_handle_to_fd, - .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_prime_import = drm_gem_prime_import, - .gem_prime_export = drm_gem_prime_export, - .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, - .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table, - .gem_prime_vmap = drm_gem_cma_prime_vmap, - .gem_prime_vunmap = drm_gem_cma_prime_vunmap, - .gem_prime_mmap = drm_gem_cma_prime_mmap, + DRM_GEM_CMA_DRIVER_OPS, .fops = &dcss_cma_fops, .name = "imx-dcss", .desc = "i.MX8MQ Display Subsystem", From 84274de61a3c2d860238142cdd7e55803f4b29e4 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 23 Sep 2020 12:21:45 +0200 Subject: [PATCH 048/235] drm/mediatek: Introduce GEM object functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GEM object functions deprecate several similar callback interfaces in struct drm_driver. This patch replaces the per-driver callbacks with per-instance callbacks in mediatek. The only exception is gem_prime_mmap, which is non-trivial to convert. Signed-off-by: Thomas Zimmermann Reviewed-by: Daniel Vetter Acked-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20200923102159.24084-9-tzimmermann@suse.de --- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 5 ----- drivers/gpu/drm/mediatek/mtk_drm_gem.c | 11 +++++++++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index 040a8f393fe2..2f8d0043fca7 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -301,18 +301,13 @@ struct drm_gem_object *mtk_drm_gem_prime_import(struct drm_device *dev, static struct drm_driver mtk_drm_driver = { .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, - .gem_free_object_unlocked = mtk_drm_gem_free_object, - .gem_vm_ops = &drm_gem_cma_vm_ops, .dumb_create = mtk_drm_gem_dumb_create, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, .gem_prime_import = mtk_drm_gem_prime_import, - .gem_prime_get_sg_table = mtk_gem_prime_get_sg_table, .gem_prime_import_sg_table = mtk_gem_prime_import_sg_table, .gem_prime_mmap = mtk_drm_gem_mmap_buf, - .gem_prime_vmap = mtk_drm_gem_prime_vmap, - .gem_prime_vunmap = mtk_drm_gem_prime_vunmap, .fops = &mtk_drm_fops, .name = DRIVER_NAME, diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c index 6190cc3b7b0d..591b90410e4a 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c @@ -8,11 +8,20 @@ #include #include #include +#include #include #include "mtk_drm_drv.h" #include "mtk_drm_gem.h" +static const struct drm_gem_object_funcs mtk_drm_gem_object_funcs = { + .free = mtk_drm_gem_free_object, + .get_sg_table = mtk_gem_prime_get_sg_table, + .vmap = mtk_drm_gem_prime_vmap, + .vunmap = mtk_drm_gem_prime_vunmap, + .vm_ops = &drm_gem_cma_vm_ops, +}; + static struct mtk_drm_gem_obj *mtk_drm_gem_init(struct drm_device *dev, unsigned long size) { @@ -25,6 +34,8 @@ static struct mtk_drm_gem_obj *mtk_drm_gem_init(struct drm_device *dev, if (!mtk_gem_obj) return ERR_PTR(-ENOMEM); + mtk_gem_obj->base.funcs = &mtk_drm_gem_object_funcs; + ret = drm_gem_object_init(dev, &mtk_gem_obj->base, size); if (ret < 0) { DRM_ERROR("failed to initialize gem object\n"); From 3c9edd9c85f53e047dad867da63e54e78e6f7b6d Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 23 Sep 2020 12:21:46 +0200 Subject: [PATCH 049/235] drm/msm: Introduce GEM object funcs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GEM object functions deprecate several similar callback interfaces in struct drm_driver. This patch replaces the per-driver callbacks with per-instance callbacks in msm. The only exception is gem_prime_mmap, which is non-trivial to convert. Signed-off-by: Thomas Zimmermann Reviewed-by: Daniel Vetter Acked-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20200923102159.24084-10-tzimmermann@suse.de --- drivers/gpu/drm/msm/msm_drv.c | 13 ------------- drivers/gpu/drm/msm/msm_drv.h | 1 - drivers/gpu/drm/msm/msm_gem.c | 19 ++++++++++++++++++- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 79333842f70a..5952767ea478 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -978,12 +978,6 @@ static const struct drm_ioctl_desc msm_ioctls[] = { DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_QUERY, msm_ioctl_submitqueue_query, DRM_RENDER_ALLOW), }; -static const struct vm_operations_struct vm_ops = { - .fault = msm_gem_fault, - .open = drm_gem_vm_open, - .close = drm_gem_vm_close, -}; - static const struct file_operations fops = { .owner = THIS_MODULE, .open = drm_open, @@ -1009,18 +1003,11 @@ static struct drm_driver msm_driver = { .irq_preinstall = msm_irq_preinstall, .irq_postinstall = msm_irq_postinstall, .irq_uninstall = msm_irq_uninstall, - .gem_free_object_unlocked = msm_gem_free_object, - .gem_vm_ops = &vm_ops, .dumb_create = msm_gem_dumb_create, .dumb_map_offset = msm_gem_dumb_map_offset, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_prime_pin = msm_gem_prime_pin, - .gem_prime_unpin = msm_gem_prime_unpin, - .gem_prime_get_sg_table = msm_gem_prime_get_sg_table, .gem_prime_import_sg_table = msm_gem_prime_import_sg_table, - .gem_prime_vmap = msm_gem_prime_vmap, - .gem_prime_vunmap = msm_gem_prime_vunmap, .gem_prime_mmap = msm_gem_prime_mmap, #ifdef CONFIG_DEBUG_FS .debugfs_init = msm_debugfs_init, diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index af259b0573ea..7bcea10be81f 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -269,7 +269,6 @@ void msm_gem_shrinker_cleanup(struct drm_device *dev); int msm_gem_mmap_obj(struct drm_gem_object *obj, struct vm_area_struct *vma); int msm_gem_mmap(struct file *filp, struct vm_area_struct *vma); -vm_fault_t msm_gem_fault(struct vm_fault *vmf); uint64_t msm_gem_mmap_offset(struct drm_gem_object *obj); int msm_gem_get_iova(struct drm_gem_object *obj, struct msm_gem_address_space *aspace, uint64_t *iova); diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index b4553caaa196..de915ff6f4b4 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -247,7 +247,7 @@ int msm_gem_mmap(struct file *filp, struct vm_area_struct *vma) return msm_gem_mmap_obj(vma->vm_private_data, vma); } -vm_fault_t msm_gem_fault(struct vm_fault *vmf) +static vm_fault_t msm_gem_fault(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; struct drm_gem_object *obj = vma->vm_private_data; @@ -994,6 +994,22 @@ int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file, return ret; } +static const struct vm_operations_struct vm_ops = { + .fault = msm_gem_fault, + .open = drm_gem_vm_open, + .close = drm_gem_vm_close, +}; + +static const struct drm_gem_object_funcs msm_gem_object_funcs = { + .free = msm_gem_free_object, + .pin = msm_gem_prime_pin, + .unpin = msm_gem_prime_unpin, + .get_sg_table = msm_gem_prime_get_sg_table, + .vmap = msm_gem_prime_vmap, + .vunmap = msm_gem_prime_vunmap, + .vm_ops = &vm_ops, +}; + static int msm_gem_new_impl(struct drm_device *dev, uint32_t size, uint32_t flags, struct drm_gem_object **obj) @@ -1024,6 +1040,7 @@ static int msm_gem_new_impl(struct drm_device *dev, INIT_LIST_HEAD(&msm_obj->vmas); *obj = &msm_obj->base; + (*obj)->funcs = &msm_gem_object_funcs; return 0; } From ed853f6c3fbc9d83a987801a36e563abafaff86e Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 23 Sep 2020 12:21:47 +0200 Subject: [PATCH 050/235] drm/nouveau: Introduce GEM object functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GEM object functions deprecate several similar callback interfaces in struct drm_driver. This patch replaces the per-driver callbacks with per-instance callbacks in nouveau. Signed-off-by: Thomas Zimmermann Reviewed-by: Daniel Vetter Acked-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20200923102159.24084-11-tzimmermann@suse.de --- drivers/gpu/drm/nouveau/nouveau_drm.c | 9 --------- drivers/gpu/drm/nouveau/nouveau_gem.c | 13 +++++++++++++ drivers/gpu/drm/nouveau/nouveau_gem.h | 2 ++ drivers/gpu/drm/nouveau/nouveau_prime.c | 2 ++ 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 42fc5c813a9b..72640bca1617 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -1207,16 +1207,7 @@ driver_stub = { .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_prime_pin = nouveau_gem_prime_pin, - .gem_prime_unpin = nouveau_gem_prime_unpin, - .gem_prime_get_sg_table = nouveau_gem_prime_get_sg_table, .gem_prime_import_sg_table = nouveau_gem_prime_import_sg_table, - .gem_prime_vmap = nouveau_gem_prime_vmap, - .gem_prime_vunmap = nouveau_gem_prime_vunmap, - - .gem_free_object_unlocked = nouveau_gem_object_del, - .gem_open_object = nouveau_gem_object_open, - .gem_close_object = nouveau_gem_object_close, .dumb_create = nouveau_display_dumb_create, .dumb_map_offset = nouveau_display_dumb_map_offset, diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 5945c663381d..9a421c3949de 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -169,6 +169,17 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv) ttm_bo_unreserve(&nvbo->bo); } +const struct drm_gem_object_funcs nouveau_gem_object_funcs = { + .free = nouveau_gem_object_del, + .open = nouveau_gem_object_open, + .close = nouveau_gem_object_close, + .pin = nouveau_gem_prime_pin, + .unpin = nouveau_gem_prime_unpin, + .get_sg_table = nouveau_gem_prime_get_sg_table, + .vmap = nouveau_gem_prime_vmap, + .vunmap = nouveau_gem_prime_vunmap, +}; + int nouveau_gem_new(struct nouveau_cli *cli, u64 size, int align, uint32_t domain, uint32_t tile_mode, uint32_t tile_flags, @@ -186,6 +197,8 @@ nouveau_gem_new(struct nouveau_cli *cli, u64 size, int align, uint32_t domain, if (IS_ERR(nvbo)) return PTR_ERR(nvbo); + nvbo->bo.base.funcs = &nouveau_gem_object_funcs; + /* Initialize the embedded gem-object. We return a single gem-reference * to the caller, instead of a normal nouveau_bo ttm reference. */ ret = drm_gem_object_init(drm->dev, &nvbo->bo.base, size); diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.h b/drivers/gpu/drm/nouveau/nouveau_gem.h index 978e07591990..b35c180322e2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.h +++ b/drivers/gpu/drm/nouveau/nouveau_gem.h @@ -5,6 +5,8 @@ #include "nouveau_drv.h" #include "nouveau_bo.h" +extern const struct drm_gem_object_funcs nouveau_gem_object_funcs; + static inline struct nouveau_bo * nouveau_gem_object(struct drm_gem_object *gem) { diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c b/drivers/gpu/drm/nouveau/nouveau_prime.c index b2ecb91f8ddc..a8264aebf3d4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_prime.c +++ b/drivers/gpu/drm/nouveau/nouveau_prime.c @@ -77,6 +77,8 @@ struct drm_gem_object *nouveau_gem_prime_import_sg_table(struct drm_device *dev, nvbo->valid_domains = NOUVEAU_GEM_DOMAIN_GART; + nvbo->bo.base.funcs = &nouveau_gem_object_funcs; + /* Initialize the embedded gem-object. We return a single gem-reference * to the caller, instead of a normal nouveau_bo ttm reference. */ ret = drm_gem_object_init(dev, &nvbo->bo.base, size); From c5ca5e029fa64b7a6024457c4ca2a8e5372dabc7 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 23 Sep 2020 12:21:48 +0200 Subject: [PATCH 051/235] drm/omapdrm: Introduce GEM object functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GEM object functions deprecate several similar callback interfaces in struct drm_driver. This patch replaces the per-driver callbacks with per-instance callbacks in omapdrm. v2: * make omap_gem_free_object() static (Tomi) Signed-off-by: Thomas Zimmermann Reviewed-by: Laurent Pinchart Reviewed-by: Tomi Valkeinen Acked-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20200923102159.24084-12-tzimmermann@suse.de --- drivers/gpu/drm/omapdrm/omap_drv.c | 9 --------- drivers/gpu/drm/omapdrm/omap_gem.c | 18 ++++++++++++++++-- drivers/gpu/drm/omapdrm/omap_gem.h | 2 -- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index 53d5e184ee77..2e598b8b72af 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -521,12 +521,6 @@ static int dev_open(struct drm_device *dev, struct drm_file *file) return 0; } -static const struct vm_operations_struct omap_gem_vm_ops = { - .fault = omap_gem_fault, - .open = drm_gem_vm_open, - .close = drm_gem_vm_close, -}; - static const struct file_operations omapdriver_fops = { .owner = THIS_MODULE, .open = drm_open, @@ -549,10 +543,7 @@ static struct drm_driver omap_drm_driver = { #endif .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_prime_export = omap_gem_prime_export, .gem_prime_import = omap_gem_prime_import, - .gem_free_object_unlocked = omap_gem_free_object, - .gem_vm_ops = &omap_gem_vm_ops, .dumb_create = omap_gem_dumb_create, .dumb_map_offset = omap_gem_dumb_map_offset, .ioctls = ioctls, diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index d0d12d5dd76c..979d53a93c2b 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -487,7 +487,7 @@ static vm_fault_t omap_gem_fault_2d(struct drm_gem_object *obj, * vma->vm_private_data points to the GEM object that is backing this * mapping. */ -vm_fault_t omap_gem_fault(struct vm_fault *vmf) +static vm_fault_t omap_gem_fault(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; struct drm_gem_object *obj = vma->vm_private_data; @@ -1089,7 +1089,7 @@ void omap_gem_describe_objects(struct list_head *list, struct seq_file *m) * Constructor & Destructor */ -void omap_gem_free_object(struct drm_gem_object *obj) +static void omap_gem_free_object(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; struct omap_drm_private *priv = dev->dev_private; @@ -1169,6 +1169,18 @@ static bool omap_gem_validate_flags(struct drm_device *dev, u32 flags) return true; } +static const struct vm_operations_struct omap_gem_vm_ops = { + .fault = omap_gem_fault, + .open = drm_gem_vm_open, + .close = drm_gem_vm_close, +}; + +static const struct drm_gem_object_funcs omap_gem_object_funcs = { + .free = omap_gem_free_object, + .export = omap_gem_prime_export, + .vm_ops = &omap_gem_vm_ops, +}; + /* GEM buffer object constructor */ struct drm_gem_object *omap_gem_new(struct drm_device *dev, union omap_gem_size gsize, u32 flags) @@ -1236,6 +1248,8 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev, size = PAGE_ALIGN(gsize.bytes); } + obj->funcs = &omap_gem_object_funcs; + /* Initialize the GEM object. */ if (!(flags & OMAP_BO_MEM_SHMEM)) { drm_gem_private_object_init(dev, obj, size); diff --git a/drivers/gpu/drm/omapdrm/omap_gem.h b/drivers/gpu/drm/omapdrm/omap_gem.h index 729b7812a815..eda9b4839c30 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.h +++ b/drivers/gpu/drm/omapdrm/omap_gem.h @@ -48,7 +48,6 @@ struct drm_gem_object *omap_gem_new_dmabuf(struct drm_device *dev, size_t size, struct sg_table *sgt); int omap_gem_new_handle(struct drm_device *dev, struct drm_file *file, union omap_gem_size gsize, u32 flags, u32 *handle); -void omap_gem_free_object(struct drm_gem_object *obj); void *omap_gem_vaddr(struct drm_gem_object *obj); /* Dumb Buffers Interface */ @@ -69,7 +68,6 @@ struct dma_buf *omap_gem_prime_export(struct drm_gem_object *obj, int flags); struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev, struct dma_buf *buffer); -vm_fault_t omap_gem_fault(struct vm_fault *vmf); int omap_gem_roll(struct drm_gem_object *obj, u32 roll); void omap_gem_cpu_sync_page(struct drm_gem_object *obj, int pgoff); void omap_gem_dma_sync_buffer(struct drm_gem_object *obj, From 4889d684fd5a59b9b5b01f3e2d8d9f1f34d99e55 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 23 Sep 2020 12:21:49 +0200 Subject: [PATCH 052/235] drm/pl111: Introduce GEM object functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GEM object functions deprecate several similar callback interfaces in struct drm_driver. This patch replaces the per-driver callbacks with per-instance callbacks in pl111. The only exception is gem_prime_mmap, which is non-trivial to convert. v2: * use drm_gem_cma_create_object_default_funcs() (Eric) Signed-off-by: Thomas Zimmermann Reviewed-by: Eric Anholt Acked-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20200923102159.24084-13-tzimmermann@suse.de --- drivers/gpu/drm/pl111/pl111_drv.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c index 46b0d1c4a16c..ecef8a2383d2 100644 --- a/drivers/gpu/drm/pl111/pl111_drv.c +++ b/drivers/gpu/drm/pl111/pl111_drv.c @@ -224,15 +224,12 @@ static struct drm_driver pl111_drm_driver = { .major = 1, .minor = 0, .patchlevel = 0, + .gem_create_object = drm_gem_cma_create_object_default_funcs, .dumb_create = drm_gem_cma_dumb_create, - .gem_free_object_unlocked = drm_gem_cma_free_object, - .gem_vm_ops = &drm_gem_cma_vm_ops, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, .gem_prime_import_sg_table = pl111_gem_import_sg_table, - .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, .gem_prime_mmap = drm_gem_cma_prime_mmap, - .gem_prime_vmap = drm_gem_cma_prime_vmap, #if defined(CONFIG_DEBUG_FS) .debugfs_init = pl111_debugfs_init, From 552f9d60f6cc5bc53007b0d82c1d0696fcf51a33 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 23 Sep 2020 12:21:50 +0200 Subject: [PATCH 053/235] drm/radeon: Introduce GEM object functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GEM object functions deprecate several similar callback interfaces in struct drm_driver. This patch replaces the per-driver callbacks with per-instance callbacks in radeon. v2: * move object-function instance to radeon_gem.c (Christian) * set callbacks in radeon_gem_object_create() (Christian) Signed-off-by: Thomas Zimmermann Reviewed-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20200923102159.24084-14-tzimmermann@suse.de --- drivers/gpu/drm/radeon/radeon_drv.c | 23 +-------------------- drivers/gpu/drm/radeon/radeon_gem.c | 31 +++++++++++++++++++++++++---- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 4cd30613fa1d..65061c949aee 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -124,13 +124,6 @@ void radeon_driver_irq_preinstall_kms(struct drm_device *dev); int radeon_driver_irq_postinstall_kms(struct drm_device *dev); void radeon_driver_irq_uninstall_kms(struct drm_device *dev); irqreturn_t radeon_driver_irq_handler_kms(int irq, void *arg); -void radeon_gem_object_free(struct drm_gem_object *obj); -int radeon_gem_object_open(struct drm_gem_object *obj, - struct drm_file *file_priv); -void radeon_gem_object_close(struct drm_gem_object *obj, - struct drm_file *file_priv); -struct dma_buf *radeon_gem_prime_export(struct drm_gem_object *gobj, - int flags); extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, unsigned int crtc, unsigned int flags, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, @@ -145,14 +138,9 @@ int radeon_mode_dumb_mmap(struct drm_file *filp, int radeon_mode_dumb_create(struct drm_file *file_priv, struct drm_device *dev, struct drm_mode_create_dumb *args); -struct sg_table *radeon_gem_prime_get_sg_table(struct drm_gem_object *obj); struct drm_gem_object *radeon_gem_prime_import_sg_table(struct drm_device *dev, struct dma_buf_attachment *, struct sg_table *sg); -int radeon_gem_prime_pin(struct drm_gem_object *obj); -void radeon_gem_prime_unpin(struct drm_gem_object *obj); -void *radeon_gem_prime_vmap(struct drm_gem_object *obj); -void radeon_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr); /* atpx handler */ #if defined(CONFIG_VGA_SWITCHEROO) @@ -550,7 +538,7 @@ long radeon_drm_ioctl(struct file *filp, } ret = drm_ioctl(filp, cmd, arg); - + pm_runtime_mark_last_busy(dev->dev); pm_runtime_put_autosuspend(dev->dev); return ret; @@ -609,22 +597,13 @@ static struct drm_driver kms_driver = { .irq_uninstall = radeon_driver_irq_uninstall_kms, .irq_handler = radeon_driver_irq_handler_kms, .ioctls = radeon_ioctls_kms, - .gem_free_object_unlocked = radeon_gem_object_free, - .gem_open_object = radeon_gem_object_open, - .gem_close_object = radeon_gem_object_close, .dumb_create = radeon_mode_dumb_create, .dumb_map_offset = radeon_mode_dumb_mmap, .fops = &radeon_driver_kms_fops, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_prime_export = radeon_gem_prime_export, - .gem_prime_pin = radeon_gem_prime_pin, - .gem_prime_unpin = radeon_gem_prime_unpin, - .gem_prime_get_sg_table = radeon_gem_prime_get_sg_table, .gem_prime_import_sg_table = radeon_gem_prime_import_sg_table, - .gem_prime_vmap = radeon_gem_prime_vmap, - .gem_prime_vunmap = radeon_gem_prime_vunmap, .name = DRIVER_NAME, .desc = DRIVER_DESC, diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index e5c4271e64ed..0ccd7213e41f 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -35,7 +35,17 @@ #include "radeon.h" -void radeon_gem_object_free(struct drm_gem_object *gobj) +struct dma_buf *radeon_gem_prime_export(struct drm_gem_object *gobj, + int flags); +struct sg_table *radeon_gem_prime_get_sg_table(struct drm_gem_object *obj); +int radeon_gem_prime_pin(struct drm_gem_object *obj); +void radeon_gem_prime_unpin(struct drm_gem_object *obj); +void *radeon_gem_prime_vmap(struct drm_gem_object *obj); +void radeon_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr); + +static const struct drm_gem_object_funcs radeon_gem_object_funcs; + +static void radeon_gem_object_free(struct drm_gem_object *gobj) { struct radeon_bo *robj = gem_to_radeon_bo(gobj); @@ -85,6 +95,7 @@ retry: return r; } *obj = &robj->tbo.base; + (*obj)->funcs = &radeon_gem_object_funcs; robj->pid = task_pid_nr(current); mutex_lock(&rdev->gem.mutex); @@ -146,7 +157,7 @@ void radeon_gem_fini(struct radeon_device *rdev) * Call from drm_gem_handle_create which appear in both new and open ioctl * case. */ -int radeon_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_priv) +static int radeon_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_priv) { struct radeon_bo *rbo = gem_to_radeon_bo(obj); struct radeon_device *rdev = rbo->rdev; @@ -176,8 +187,8 @@ int radeon_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_pri return 0; } -void radeon_gem_object_close(struct drm_gem_object *obj, - struct drm_file *file_priv) +static void radeon_gem_object_close(struct drm_gem_object *obj, + struct drm_file *file_priv) { struct radeon_bo *rbo = gem_to_radeon_bo(obj); struct radeon_device *rdev = rbo->rdev; @@ -216,6 +227,18 @@ static int radeon_gem_handle_lockup(struct radeon_device *rdev, int r) return r; } +static const struct drm_gem_object_funcs radeon_gem_object_funcs = { + .free = radeon_gem_object_free, + .open = radeon_gem_object_open, + .close = radeon_gem_object_close, + .export = radeon_gem_prime_export, + .pin = radeon_gem_prime_pin, + .unpin = radeon_gem_prime_unpin, + .get_sg_table = radeon_gem_prime_get_sg_table, + .vmap = radeon_gem_prime_vmap, + .vunmap = radeon_gem_prime_vunmap, +}; + /* * GEM ioctls. */ From 0d590af3140d0f84c537a9ad252aecc780ed7aa5 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 23 Sep 2020 12:21:51 +0200 Subject: [PATCH 054/235] drm/rockchip: Convert to drm_gem_object_funcs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GEM object functions deprecate several similar callback interfaces in struct drm_driver. This patch replaces the per-driver callbacks with per-instance callbacks in rockchip. The only exception is gem_prime_mmap, which is non-trivial to convert. v3: * update documentation Signed-off-by: Thomas Zimmermann Reviewed-by: Daniel Vetter Acked-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20200923102159.24084-15-tzimmermann@suse.de --- drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 5 ----- drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 12 +++++++++++- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index 0f3eb392fe39..b7654f5e4225 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -212,15 +212,10 @@ static const struct file_operations rockchip_drm_driver_fops = { static struct drm_driver rockchip_drm_driver = { .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, .lastclose = drm_fb_helper_lastclose, - .gem_vm_ops = &drm_gem_cma_vm_ops, - .gem_free_object_unlocked = rockchip_gem_free_object, .dumb_create = rockchip_gem_dumb_create, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_prime_get_sg_table = rockchip_gem_prime_get_sg_table, .gem_prime_import_sg_table = rockchip_gem_prime_import_sg_table, - .gem_prime_vmap = rockchip_gem_prime_vmap, - .gem_prime_vunmap = rockchip_gem_prime_vunmap, .gem_prime_mmap = rockchip_gem_mmap_buf, .fops = &rockchip_drm_driver_fops, .name = DRIVER_NAME, diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c index 0055d86576f7..bb3578469b03 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c @@ -296,6 +296,14 @@ static void rockchip_gem_release_object(struct rockchip_gem_object *rk_obj) kfree(rk_obj); } +static const struct drm_gem_object_funcs rockchip_gem_object_funcs = { + .free = rockchip_gem_free_object, + .get_sg_table = rockchip_gem_prime_get_sg_table, + .vmap = rockchip_gem_prime_vmap, + .vunmap = rockchip_gem_prime_vunmap, + .vm_ops = &drm_gem_cma_vm_ops, +}; + static struct rockchip_gem_object * rockchip_gem_alloc_object(struct drm_device *drm, unsigned int size) { @@ -310,6 +318,8 @@ static struct rockchip_gem_object * obj = &rk_obj->base; + obj->funcs = &rockchip_gem_object_funcs; + drm_gem_object_init(drm, obj, size); return rk_obj; @@ -338,7 +348,7 @@ err_free_rk_obj: } /* - * rockchip_gem_free_object - (struct drm_driver)->gem_free_object_unlocked + * rockchip_gem_free_object - (struct drm_gem_object_funcs)->free * callback function */ void rockchip_gem_free_object(struct drm_gem_object *obj) From dd311c6fe8af1b176165b828a35553af16f9710c Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 23 Sep 2020 12:21:52 +0200 Subject: [PATCH 055/235] drm/tegra: Introduce GEM object functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GEM object functions deprecate several similar callback interfaces in struct drm_driver. This patch replaces the per-driver callbacks with per-instance callbacks in tegra. Signed-off-by: Thomas Zimmermann Acked-by: Thierry Reding Acked-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20200923102159.24084-16-tzimmermann@suse.de --- drivers/gpu/drm/tegra/drm.c | 4 ---- drivers/gpu/drm/tegra/gem.c | 8 ++++++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index ba9d1c3e7cac..f0f581cd345e 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -858,12 +858,8 @@ static struct drm_driver tegra_drm_driver = { .debugfs_init = tegra_debugfs_init, #endif - .gem_free_object_unlocked = tegra_bo_free_object, - .gem_vm_ops = &tegra_bo_vm_ops, - .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_prime_export = tegra_gem_prime_export, .gem_prime_import = tegra_gem_prime_import, .dumb_create = tegra_bo_dumb_create, diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index 47e2935b8c68..d481dea4738d 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -231,6 +231,12 @@ static int tegra_bo_iommu_unmap(struct tegra_drm *tegra, struct tegra_bo *bo) return 0; } +static const struct drm_gem_object_funcs tegra_gem_object_funcs = { + .free = tegra_bo_free_object, + .export = tegra_gem_prime_export, + .vm_ops = &tegra_bo_vm_ops, +}; + static struct tegra_bo *tegra_bo_alloc_object(struct drm_device *drm, size_t size) { @@ -241,6 +247,8 @@ static struct tegra_bo *tegra_bo_alloc_object(struct drm_device *drm, if (!bo) return ERR_PTR(-ENOMEM); + bo->gem.funcs = &tegra_gem_object_funcs; + host1x_bo_init(&bo->base, &tegra_bo_ops); size = round_up(size, PAGE_SIZE); From dd60202237a021d6c076546e79a08fcac863327b Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 23 Sep 2020 12:21:53 +0200 Subject: [PATCH 056/235] drm/vc4: Introduce GEM object functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GEM object functions deprecate several similar callback interfaces in struct drm_driver. This patch replaces the per-driver callbacks with per-instance callbacks in vc4. The only exception is gem_prime_mmap, which is non-trivial to convert. Signed-off-by: Thomas Zimmermann Reviewed-by: Eric Anholt Acked-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20200923102159.24084-17-tzimmermann@suse.de --- drivers/gpu/drm/vc4/vc4_bo.c | 21 ++++++++++++++++++++- drivers/gpu/drm/vc4/vc4_drv.c | 12 ------------ drivers/gpu/drm/vc4/vc4_drv.h | 1 - 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c index 74ceebd62fbc..f432278173cd 100644 --- a/drivers/gpu/drm/vc4/vc4_bo.c +++ b/drivers/gpu/drm/vc4/vc4_bo.c @@ -21,6 +21,8 @@ #include "vc4_drv.h" #include "uapi/drm/vc4_drm.h" +static vm_fault_t vc4_fault(struct vm_fault *vmf); + static const char * const bo_type_names[] = { "kernel", "V3D", @@ -374,6 +376,21 @@ out: return bo; } +static const struct vm_operations_struct vc4_vm_ops = { + .fault = vc4_fault, + .open = drm_gem_vm_open, + .close = drm_gem_vm_close, +}; + +static const struct drm_gem_object_funcs vc4_gem_object_funcs = { + .free = vc4_free_object, + .export = vc4_prime_export, + .get_sg_table = drm_gem_cma_prime_get_sg_table, + .vmap = vc4_prime_vmap, + .vunmap = drm_gem_cma_prime_vunmap, + .vm_ops = &vc4_vm_ops, +}; + /** * vc4_gem_create_object - Implementation of driver->gem_create_object. * @dev: DRM device @@ -400,6 +417,8 @@ struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size) vc4->bo_labels[VC4_BO_TYPE_KERNEL].size_allocated += size; mutex_unlock(&vc4->bo_lock); + bo->base.base.funcs = &vc4_gem_object_funcs; + return &bo->base.base; } @@ -684,7 +703,7 @@ struct dma_buf * vc4_prime_export(struct drm_gem_object *obj, int flags) return dmabuf; } -vm_fault_t vc4_fault(struct vm_fault *vmf) +static vm_fault_t vc4_fault(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; struct drm_gem_object *obj = vma->vm_private_data; diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index f1a5fd5dab6f..d27eaa2d0cfe 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -140,12 +140,6 @@ static void vc4_close(struct drm_device *dev, struct drm_file *file) kfree(vc4file); } -static const struct vm_operations_struct vc4_vm_ops = { - .fault = vc4_fault, - .open = drm_gem_vm_open, - .close = drm_gem_vm_close, -}; - static const struct file_operations vc4_drm_fops = { .owner = THIS_MODULE, .open = drm_open, @@ -195,16 +189,10 @@ static struct drm_driver vc4_drm_driver = { #endif .gem_create_object = vc4_create_object, - .gem_free_object_unlocked = vc4_free_object, - .gem_vm_ops = &vc4_vm_ops, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_prime_export = vc4_prime_export, - .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, .gem_prime_import_sg_table = vc4_prime_import_sg_table, - .gem_prime_vmap = vc4_prime_vmap, - .gem_prime_vunmap = drm_gem_cma_prime_vunmap, .gem_prime_mmap = vc4_prime_mmap, .dumb_create = vc4_dumb_create, diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 8c8d96b6289f..a22478a35199 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -799,7 +799,6 @@ int vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int vc4_label_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); -vm_fault_t vc4_fault(struct vm_fault *vmf); int vc4_mmap(struct file *filp, struct vm_area_struct *vma); int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); struct drm_gem_object *vc4_prime_import_sg_table(struct drm_device *dev, From dff29810a8d5a457ecc6f5067a891c3878229e8e Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 23 Sep 2020 12:21:54 +0200 Subject: [PATCH 057/235] drm/vgem: Introduce GEM object functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GEM object functions deprecate several similar callback interfaces in struct drm_driver. This patch replaces the per-driver callbacks with per-instance callbacks in vgem. The only exception is gem_prime_mmap, which is non-trivial to convert. Signed-off-by: Thomas Zimmermann Reviewed-by: Melissa Wen Acked-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20200923102159.24084-18-tzimmermann@suse.de --- drivers/gpu/drm/vgem/vgem_drv.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c index cb884c890065..fa54a6d1403d 100644 --- a/drivers/gpu/drm/vgem/vgem_drv.c +++ b/drivers/gpu/drm/vgem/vgem_drv.c @@ -50,6 +50,8 @@ #define DRIVER_MAJOR 1 #define DRIVER_MINOR 0 +static const struct drm_gem_object_funcs vgem_gem_object_funcs; + static struct vgem_device { struct drm_device drm; struct platform_device *platform; @@ -167,6 +169,8 @@ static struct drm_vgem_gem_object *__vgem_gem_create(struct drm_device *dev, if (!obj) return ERR_PTR(-ENOMEM); + obj->base.funcs = &vgem_gem_object_funcs; + ret = drm_gem_object_init(dev, &obj->base, roundup(size, PAGE_SIZE)); if (ret) { kfree(obj); @@ -401,12 +405,20 @@ static int vgem_prime_mmap(struct drm_gem_object *obj, return 0; } +static const struct drm_gem_object_funcs vgem_gem_object_funcs = { + .free = vgem_gem_free_object, + .pin = vgem_prime_pin, + .unpin = vgem_prime_unpin, + .get_sg_table = vgem_prime_get_sg_table, + .vmap = vgem_prime_vmap, + .vunmap = vgem_prime_vunmap, + .vm_ops = &vgem_gem_vm_ops, +}; + static struct drm_driver vgem_driver = { .driver_features = DRIVER_GEM | DRIVER_RENDER, .open = vgem_open, .postclose = vgem_postclose, - .gem_free_object_unlocked = vgem_gem_free_object, - .gem_vm_ops = &vgem_gem_vm_ops, .ioctls = vgem_ioctls, .num_ioctls = ARRAY_SIZE(vgem_ioctls), .fops = &vgem_driver_fops, @@ -415,13 +427,8 @@ static struct drm_driver vgem_driver = { .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_prime_pin = vgem_prime_pin, - .gem_prime_unpin = vgem_prime_unpin, .gem_prime_import = vgem_prime_import, .gem_prime_import_sg_table = vgem_prime_import_sg_table, - .gem_prime_get_sg_table = vgem_prime_get_sg_table, - .gem_prime_vmap = vgem_prime_vmap, - .gem_prime_vunmap = vgem_prime_vunmap, .gem_prime_mmap = vgem_prime_mmap, .name = DRIVER_NAME, From c6069a02fa554302b93274c6d75d14251200de18 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 23 Sep 2020 12:21:55 +0200 Subject: [PATCH 058/235] drm/virtgpu: Set PRIME export function in struct drm_gem_object_funcs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GEM object functions deprecate several similar callback interfaces in struct drm_driver. This patch replaces virtgpu's per-driver PRIME export function with a per-object function. Signed-off-by: Thomas Zimmermann Reviewed-by: Daniel Vetter Acked-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20200923102159.24084-19-tzimmermann@suse.de --- drivers/gpu/drm/virtio/virtgpu_drv.c | 1 - drivers/gpu/drm/virtio/virtgpu_object.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index b039f493bda9..1f8d6ed11d21 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -203,7 +203,6 @@ static struct drm_driver driver = { .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, .gem_prime_mmap = drm_gem_prime_mmap, - .gem_prime_export = virtgpu_gem_prime_export, .gem_prime_import = virtgpu_gem_prime_import, .gem_prime_import_sg_table = virtgpu_gem_prime_import_sg_table, diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index 842f8b61aa89..4f7d7ea8194c 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -108,6 +108,7 @@ static const struct drm_gem_object_funcs virtio_gpu_shmem_funcs = { .close = virtio_gpu_gem_object_close, .print_info = drm_gem_shmem_print_info, + .export = virtgpu_gem_prime_export, .pin = drm_gem_shmem_pin, .unpin = drm_gem_shmem_unpin, .get_sg_table = drm_gem_shmem_get_sg_table, From b76b85b7c2e28a0e73dbd2d4cf4da7c933858924 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 23 Sep 2020 12:21:56 +0200 Subject: [PATCH 059/235] drm/vkms: Introduce GEM object functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GEM object functions deprecate several similar callback interfaces in struct drm_driver. This patch replaces the per-driver callbacks with per-instance callbacks in vkms. Signed-off-by: Thomas Zimmermann Reviewed-by: Melissa Wen Acked-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20200923102159.24084-20-tzimmermann@suse.de --- drivers/gpu/drm/vkms/vkms_drv.c | 8 -------- drivers/gpu/drm/vkms/vkms_gem.c | 13 +++++++++++++ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index cb0b6230c22c..726801ab44d4 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -51,12 +51,6 @@ static const struct file_operations vkms_driver_fops = { .release = drm_release, }; -static const struct vm_operations_struct vkms_gem_vm_ops = { - .fault = vkms_gem_fault, - .open = drm_gem_vm_open, - .close = drm_gem_vm_close, -}; - static void vkms_release(struct drm_device *dev) { struct vkms_device *vkms = container_of(dev, struct vkms_device, drm); @@ -98,8 +92,6 @@ static struct drm_driver vkms_driver = { .release = vkms_release, .fops = &vkms_driver_fops, .dumb_create = vkms_dumb_create, - .gem_vm_ops = &vkms_gem_vm_ops, - .gem_free_object_unlocked = vkms_gem_free_object, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, .gem_prime_import_sg_table = vkms_prime_import_sg_table, diff --git a/drivers/gpu/drm/vkms/vkms_gem.c b/drivers/gpu/drm/vkms/vkms_gem.c index a017fc59905e..19a0e260a4df 100644 --- a/drivers/gpu/drm/vkms/vkms_gem.c +++ b/drivers/gpu/drm/vkms/vkms_gem.c @@ -7,6 +7,17 @@ #include "vkms_drv.h" +static const struct vm_operations_struct vkms_gem_vm_ops = { + .fault = vkms_gem_fault, + .open = drm_gem_vm_open, + .close = drm_gem_vm_close, +}; + +static const struct drm_gem_object_funcs vkms_gem_object_funcs = { + .free = vkms_gem_free_object, + .vm_ops = &vkms_gem_vm_ops, +}; + static struct vkms_gem_object *__vkms_gem_create(struct drm_device *dev, u64 size) { @@ -17,6 +28,8 @@ static struct vkms_gem_object *__vkms_gem_create(struct drm_device *dev, if (!obj) return ERR_PTR(-ENOMEM); + obj->gem.funcs = &vkms_gem_object_funcs; + size = roundup(size, PAGE_SIZE); ret = drm_gem_object_init(dev, &obj->gem, size); if (ret) { From 1adda8b8f12c22705e7f86c120499d806d09af6a Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 23 Sep 2020 12:21:57 +0200 Subject: [PATCH 060/235] drm/xen: Introduce GEM object functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GEM object functions deprecate several similar callback interfaces in struct drm_driver. This patch replaces the per-driver callbacks with per-instance callbacks in xen. The only exception is gem_prime_mmap, which is non-trivial to convert. v2: * convert xen_drm_drv_free_object_unlocked() to static callback (Oleksandr) Signed-off-by: Thomas Zimmermann Acked-by: Oleksandr Andrushchenko Acked-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20200923102159.24084-21-tzimmermann@suse.de --- drivers/gpu/drm/xen/xen_drm_front.c | 44 ++++++++++--------------- drivers/gpu/drm/xen/xen_drm_front.h | 2 ++ drivers/gpu/drm/xen/xen_drm_front_gem.c | 15 +++++++++ 3 files changed, 34 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/xen/xen_drm_front.c b/drivers/gpu/drm/xen/xen_drm_front.c index cc93a8c9547b..98b6d2ba088a 100644 --- a/drivers/gpu/drm/xen/xen_drm_front.c +++ b/drivers/gpu/drm/xen/xen_drm_front.c @@ -381,6 +381,23 @@ void xen_drm_front_on_frame_done(struct xen_drm_front_info *front_info, fb_cookie); } +void xen_drm_front_gem_object_free(struct drm_gem_object *obj) +{ + struct xen_drm_front_drm_info *drm_info = obj->dev->dev_private; + int idx; + + if (drm_dev_enter(obj->dev, &idx)) { + xen_drm_front_dbuf_destroy(drm_info->front_info, + xen_drm_front_dbuf_to_cookie(obj)); + drm_dev_exit(idx); + } else { + dbuf_free(&drm_info->front_info->dbuf_list, + xen_drm_front_dbuf_to_cookie(obj)); + } + + xen_drm_front_gem_free_object_unlocked(obj); +} + static int xen_drm_drv_dumb_create(struct drm_file *filp, struct drm_device *dev, struct drm_mode_create_dumb *args) @@ -435,23 +452,6 @@ fail: return ret; } -static void xen_drm_drv_free_object_unlocked(struct drm_gem_object *obj) -{ - struct xen_drm_front_drm_info *drm_info = obj->dev->dev_private; - int idx; - - if (drm_dev_enter(obj->dev, &idx)) { - xen_drm_front_dbuf_destroy(drm_info->front_info, - xen_drm_front_dbuf_to_cookie(obj)); - drm_dev_exit(idx); - } else { - dbuf_free(&drm_info->front_info->dbuf_list, - xen_drm_front_dbuf_to_cookie(obj)); - } - - xen_drm_front_gem_free_object_unlocked(obj); -} - static void xen_drm_drv_release(struct drm_device *dev) { struct xen_drm_front_drm_info *drm_info = dev->dev_private; @@ -483,22 +483,12 @@ static const struct file_operations xen_drm_dev_fops = { .mmap = xen_drm_front_gem_mmap, }; -static const struct vm_operations_struct xen_drm_drv_vm_ops = { - .open = drm_gem_vm_open, - .close = drm_gem_vm_close, -}; - static struct drm_driver xen_drm_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .release = xen_drm_drv_release, - .gem_vm_ops = &xen_drm_drv_vm_ops, - .gem_free_object_unlocked = xen_drm_drv_free_object_unlocked, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, .gem_prime_import_sg_table = xen_drm_front_gem_import_sg_table, - .gem_prime_get_sg_table = xen_drm_front_gem_get_sg_table, - .gem_prime_vmap = xen_drm_front_gem_prime_vmap, - .gem_prime_vunmap = xen_drm_front_gem_prime_vunmap, .gem_prime_mmap = xen_drm_front_gem_prime_mmap, .dumb_create = xen_drm_drv_dumb_create, .fops = &xen_drm_dev_fops, diff --git a/drivers/gpu/drm/xen/xen_drm_front.h b/drivers/gpu/drm/xen/xen_drm_front.h index 54486d89650e..cefafe859aba 100644 --- a/drivers/gpu/drm/xen/xen_drm_front.h +++ b/drivers/gpu/drm/xen/xen_drm_front.h @@ -160,4 +160,6 @@ int xen_drm_front_page_flip(struct xen_drm_front_info *front_info, void xen_drm_front_on_frame_done(struct xen_drm_front_info *front_info, int conn_idx, u64 fb_cookie); +void xen_drm_front_gem_object_free(struct drm_gem_object *obj); + #endif /* __XEN_DRM_FRONT_H_ */ diff --git a/drivers/gpu/drm/xen/xen_drm_front_gem.c b/drivers/gpu/drm/xen/xen_drm_front_gem.c index a8aefaa38bd3..f3830a0d1808 100644 --- a/drivers/gpu/drm/xen/xen_drm_front_gem.c +++ b/drivers/gpu/drm/xen/xen_drm_front_gem.c @@ -57,6 +57,19 @@ static void gem_free_pages_array(struct xen_gem_object *xen_obj) xen_obj->pages = NULL; } +static const struct vm_operations_struct xen_drm_drv_vm_ops = { + .open = drm_gem_vm_open, + .close = drm_gem_vm_close, +}; + +static const struct drm_gem_object_funcs xen_drm_front_gem_object_funcs = { + .free = xen_drm_front_gem_object_free, + .get_sg_table = xen_drm_front_gem_get_sg_table, + .vmap = xen_drm_front_gem_prime_vmap, + .vunmap = xen_drm_front_gem_prime_vunmap, + .vm_ops = &xen_drm_drv_vm_ops, +}; + static struct xen_gem_object *gem_create_obj(struct drm_device *dev, size_t size) { @@ -67,6 +80,8 @@ static struct xen_gem_object *gem_create_obj(struct drm_device *dev, if (!xen_obj) return ERR_PTR(-ENOMEM); + xen_obj->base.funcs = &xen_drm_front_gem_object_funcs; + ret = drm_gem_object_init(dev, &xen_obj->base, size); if (ret < 0) { kfree(xen_obj); From c85dce1b2e7e5037ef9f01bc64a26e40c92a9e79 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 23 Sep 2020 12:21:58 +0200 Subject: [PATCH 061/235] drm/xlnx: Initialize DRM driver instance with CMA helper macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The xlnx driver uses CMA helpers with default callback functions. Initialize the driver structure with the rsp CMA helper macro. The driver is being converted to use GEM object functions as part of this change. Two callbacks, .dumb_destroy and .gem_prime_import, were initialized to their default implementations, so they are just kept empty now. v2: * initialize with DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE (Laurent) Signed-off-by: Thomas Zimmermann Reviewed-by: Laurent Pinchart Reviewed-by: Hyun Kwon Acked-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20200923102159.24084-22-tzimmermann@suse.de --- drivers/gpu/drm/xlnx/zynqmp_dpsub.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c index 8e69303aad3f..f3ffc3703a0e 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c +++ b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c @@ -80,19 +80,7 @@ static struct drm_driver zynqmp_dpsub_drm_driver = { .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, - .prime_handle_to_fd = drm_gem_prime_handle_to_fd, - .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_prime_export = drm_gem_prime_export, - .gem_prime_import = drm_gem_prime_import, - .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, - .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table, - .gem_prime_vmap = drm_gem_cma_prime_vmap, - .gem_prime_vunmap = drm_gem_cma_prime_vunmap, - .gem_prime_mmap = drm_gem_cma_prime_mmap, - .gem_free_object_unlocked = drm_gem_cma_free_object, - .gem_vm_ops = &drm_gem_cma_vm_ops, - .dumb_create = zynqmp_dpsub_dumb_create, - .dumb_destroy = drm_gem_dumb_destroy, + DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE(zynqmp_dpsub_dumb_create), .fops = &zynqmp_dpsub_drm_fops, From d693def4fd1c23f1ca5aed1afb9993b3a2069ad2 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 23 Sep 2020 12:21:59 +0200 Subject: [PATCH 062/235] drm: Remove obsolete GEM and PRIME callbacks from struct drm_driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Several GEM and PRIME callbacks have been deprecated in favor of per-instance GEM object functions. Remove the callbacks as they are now unused. The only exception is .gem_prime_mmap, which is still in use by several drivers. What is also gone is gem_vm_ops in struct drm_driver. All drivers now use struct drm_gem_object_funcs.vm_ops instead. While at it, the patch also improves error handling around calls to .free and .get_sg_table callbacks. v3: * restore default call to drm_gem_prime_export() in drm_gem_prime_handle_to_fd() * return -ENOSYS if get_sg_table is not set * drop all checks for obj->funcs * clean up TODO list and documentation v2: * update related TODO item (Sam) Signed-off-by: Thomas Zimmermann Acked-by: Daniel Vetter Acked-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20200923102159.24084-23-tzimmermann@suse.de --- Documentation/gpu/drm-mm.rst | 4 +- Documentation/gpu/todo.rst | 9 +-- drivers/gpu/drm/drm_gem.c | 53 ++++++----------- drivers/gpu/drm/drm_gem_cma_helper.c | 8 +-- drivers/gpu/drm/drm_prime.c | 14 ++--- include/drm/drm_drv.h | 85 ++-------------------------- include/drm/drm_gem.h | 2 +- 7 files changed, 38 insertions(+), 137 deletions(-) diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst index 9abee1589c1e..21be6deadc12 100644 --- a/Documentation/gpu/drm-mm.rst +++ b/Documentation/gpu/drm-mm.rst @@ -182,11 +182,11 @@ acquired and release by calling drm_gem_object_get() and drm_gem_object_put() respectively. When the last reference to a GEM object is released the GEM core calls -the :c:type:`struct drm_driver ` gem_free_object_unlocked +the :c:type:`struct drm_gem_object_funcs ` free operation. That operation is mandatory for GEM-enabled drivers and must free the GEM object and all associated resources. -void (\*gem_free_object) (struct drm_gem_object \*obj); Drivers are +void (\*free) (struct drm_gem_object \*obj); Drivers are responsible for freeing all GEM object resources. This includes the resources created by the GEM core, which need to be released with drm_gem_object_release(). diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index b0ea17da8ff6..3751ac976c3e 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -149,7 +149,7 @@ have to keep track of that lock and either call ``unreference`` or ``unreference_locked`` depending upon context. Core GEM doesn't have a need for ``struct_mutex`` any more since kernel 4.8, -and there's a ``gem_free_object_unlocked`` callback for any drivers which are +and there's a GEM object ``free`` callback for any drivers which are entirely ``struct_mutex`` free. For drivers that need ``struct_mutex`` it should be replaced with a driver- @@ -289,11 +289,8 @@ struct drm_gem_object_funcs --------------------------- GEM objects can now have a function table instead of having the callbacks on the -DRM driver struct. This is now the preferred way and drivers can be moved over. - -We also need a 2nd version of the CMA define that doesn't require the -vmapping to be present (different hook for prime importing). Plus this needs to -be rolled out to all drivers using their own implementations, too. +DRM driver struct. This is now the preferred way. Callbacks in drivers have been +converted, except for struct drm_driver.gem_prime_mmap. Level: Intermediate diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 19d73868490e..1da67d34e55d 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -247,12 +247,9 @@ drm_gem_object_release_handle(int id, void *ptr, void *data) { struct drm_file *file_priv = data; struct drm_gem_object *obj = ptr; - struct drm_device *dev = obj->dev; - if (obj->funcs && obj->funcs->close) + if (obj->funcs->close) obj->funcs->close(obj, file_priv); - else if (dev->driver->gem_close_object) - dev->driver->gem_close_object(obj, file_priv); drm_gem_remove_prime_handles(obj, file_priv); drm_vma_node_revoke(&obj->vma_node, file_priv); @@ -403,14 +400,10 @@ drm_gem_handle_create_tail(struct drm_file *file_priv, if (ret) goto err_remove; - if (obj->funcs && obj->funcs->open) { + if (obj->funcs->open) { ret = obj->funcs->open(obj, file_priv); if (ret) goto err_revoke; - } else if (dev->driver->gem_open_object) { - ret = dev->driver->gem_open_object(obj, file_priv); - if (ret) - goto err_revoke; } *handlep = handle; @@ -982,12 +975,11 @@ drm_gem_object_free(struct kref *kref) { struct drm_gem_object *obj = container_of(kref, struct drm_gem_object, refcount); - struct drm_device *dev = obj->dev; - if (obj->funcs) - obj->funcs->free(obj); - else if (dev->driver->gem_free_object_unlocked) - dev->driver->gem_free_object_unlocked(obj); + if (WARN_ON(!obj->funcs->free)) + return; + + obj->funcs->free(obj); } EXPORT_SYMBOL(drm_gem_object_free); @@ -1049,9 +1041,9 @@ EXPORT_SYMBOL(drm_gem_vm_close); * @obj_size: the object size to be mapped, in bytes * @vma: VMA for the area to be mapped * - * Set up the VMA to prepare mapping of the GEM object using the gem_vm_ops - * provided by the driver. Depending on their requirements, drivers can either - * provide a fault handler in their gem_vm_ops (in which case any accesses to + * Set up the VMA to prepare mapping of the GEM object using the GEM object's + * vm_ops. Depending on their requirements, GEM objects can either + * provide a fault handler in their vm_ops (in which case any accesses to * the object will be trapped, to perform migration, GTT binding, surface * register allocation, or performance monitoring), or mmap the buffer memory * synchronously after calling drm_gem_mmap_obj. @@ -1065,12 +1057,11 @@ EXPORT_SYMBOL(drm_gem_vm_close); * callers must verify access restrictions before calling this helper. * * Return 0 or success or -EINVAL if the object size is smaller than the VMA - * size, or if no gem_vm_ops are provided. + * size, or if no vm_ops are provided. */ int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size, struct vm_area_struct *vma) { - struct drm_device *dev = obj->dev; int ret; /* Check for valid size. */ @@ -1085,7 +1076,7 @@ int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size, */ drm_gem_object_get(obj); - if (obj->funcs && obj->funcs->mmap) { + if (obj->funcs->mmap) { ret = obj->funcs->mmap(obj, vma); if (ret) { drm_gem_object_put(obj); @@ -1093,10 +1084,8 @@ int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size, } WARN_ON(!(vma->vm_flags & VM_DONTEXPAND)); } else { - if (obj->funcs && obj->funcs->vm_ops) + if (obj->funcs->vm_ops) vma->vm_ops = obj->funcs->vm_ops; - else if (dev->driver->gem_vm_ops) - vma->vm_ops = dev->driver->gem_vm_ops; else { drm_gem_object_put(obj); return -EINVAL; @@ -1198,36 +1187,30 @@ void drm_gem_print_info(struct drm_printer *p, unsigned int indent, drm_printf_indent(p, indent, "imported=%s\n", obj->import_attach ? "yes" : "no"); - if (obj->funcs && obj->funcs->print_info) + if (obj->funcs->print_info) obj->funcs->print_info(p, indent, obj); } int drm_gem_pin(struct drm_gem_object *obj) { - if (obj->funcs && obj->funcs->pin) + if (obj->funcs->pin) return obj->funcs->pin(obj); - else if (obj->dev->driver->gem_prime_pin) - return obj->dev->driver->gem_prime_pin(obj); else return 0; } void drm_gem_unpin(struct drm_gem_object *obj) { - if (obj->funcs && obj->funcs->unpin) + if (obj->funcs->unpin) obj->funcs->unpin(obj); - else if (obj->dev->driver->gem_prime_unpin) - obj->dev->driver->gem_prime_unpin(obj); } void *drm_gem_vmap(struct drm_gem_object *obj) { void *vaddr; - if (obj->funcs && obj->funcs->vmap) + if (obj->funcs->vmap) vaddr = obj->funcs->vmap(obj); - else if (obj->dev->driver->gem_prime_vmap) - vaddr = obj->dev->driver->gem_prime_vmap(obj); else vaddr = ERR_PTR(-EOPNOTSUPP); @@ -1242,10 +1225,8 @@ void drm_gem_vunmap(struct drm_gem_object *obj, void *vaddr) if (!vaddr) return; - if (obj->funcs && obj->funcs->vunmap) + if (obj->funcs->vunmap) obj->funcs->vunmap(obj, vaddr); - else if (obj->dev->driver->gem_prime_vunmap) - obj->dev->driver->gem_prime_vunmap(obj, vaddr); } /** diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c index 822edeadbab3..1e5b389c435c 100644 --- a/drivers/gpu/drm/drm_gem_cma_helper.c +++ b/drivers/gpu/drm/drm_gem_cma_helper.c @@ -171,7 +171,7 @@ drm_gem_cma_create_with_handle(struct drm_file *file_priv, * GEM object state and frees the memory used to store the object itself. * If the buffer is imported and the virtual address is set, it is released. * Drivers using the CMA helpers should set this as their - * &drm_driver.gem_free_object_unlocked callback. + * &drm_gem_object_funcs.free callback. */ void drm_gem_cma_free_object(struct drm_gem_object *gem_obj) { @@ -419,7 +419,7 @@ EXPORT_SYMBOL(drm_gem_cma_print_info); * * This function exports a scatter/gather table suitable for PRIME usage by * calling the standard DMA mapping API. Drivers using the CMA helpers should - * set this as their &drm_driver.gem_prime_get_sg_table callback. + * set this as their &drm_gem_object_funcs.get_sg_table callback. * * Returns: * A pointer to the scatter/gather table of pinned pages or NULL on failure. @@ -542,7 +542,7 @@ EXPORT_SYMBOL_GPL(drm_gem_cma_prime_mmap); * virtual address space. Since the CMA buffers are already mapped into the * kernel virtual address space this simply returns the cached virtual * address. Drivers using the CMA helpers should set this as their DRM - * driver's &drm_driver.gem_prime_vmap callback. + * driver's &drm_gem_object_funcs.vmap callback. * * Returns: * The kernel virtual address of the CMA GEM object's backing store. @@ -564,7 +564,7 @@ EXPORT_SYMBOL_GPL(drm_gem_cma_prime_vmap); * This function removes a buffer exported via DRM PRIME from the kernel's * virtual address space. This is a no-op because CMA buffers cannot be * unmapped from kernel space. Drivers using the CMA helpers should set this - * as their &drm_driver.gem_prime_vunmap callback. + * as their &drm_gem_object_funcs.vunmap callback. */ void drm_gem_cma_prime_vunmap(struct drm_gem_object *obj, void *vaddr) { diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 8a6a3c99b7d8..194784a5b344 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -386,8 +386,6 @@ static struct dma_buf *export_and_register_object(struct drm_device *dev, if (obj->funcs && obj->funcs->export) dmabuf = obj->funcs->export(obj, flags); - else if (dev->driver->gem_prime_export) - dmabuf = dev->driver->gem_prime_export(obj, flags); else dmabuf = drm_gem_prime_export(obj, flags); if (IS_ERR(dmabuf)) { @@ -419,7 +417,7 @@ static struct dma_buf *export_and_register_object(struct drm_device *dev, * This is the PRIME export function which must be used mandatorily by GEM * drivers to ensure correct lifetime management of the underlying GEM object. * The actual exporting from GEM object to a dma-buf is done through the - * &drm_driver.gem_prime_export driver callback. + * &drm_gem_object_funcs.export callback. */ int drm_gem_prime_handle_to_fd(struct drm_device *dev, struct drm_file *file_priv, uint32_t handle, @@ -621,10 +619,12 @@ struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach, if (WARN_ON(dir == DMA_NONE)) return ERR_PTR(-EINVAL); - if (obj->funcs) - sgt = obj->funcs->get_sg_table(obj); - else - sgt = obj->dev->driver->gem_prime_get_sg_table(obj); + if (WARN_ON(!obj->funcs->get_sg_table)) + return ERR_PTR(-ENOSYS); + + sgt = obj->funcs->get_sg_table(obj); + if (IS_ERR(sgt)) + return sgt; if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir, DMA_ATTR_SKIP_CPU_SYNC)) { diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index e57d0440f00f..023076255a7f 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -36,10 +36,12 @@ struct drm_file; struct drm_gem_object; struct drm_master; struct drm_minor; +struct dma_buf; struct dma_buf_attachment; struct drm_display_mode; struct drm_mode_create_dumb; struct drm_printer; +struct sg_table; /** * enum drm_driver_feature - feature flags @@ -326,32 +328,6 @@ struct drm_driver { */ void (*debugfs_init)(struct drm_minor *minor); - /** - * @gem_free_object_unlocked: deconstructor for drm_gem_objects - * - * This is deprecated and should not be used by new drivers. Use - * &drm_gem_object_funcs.free instead. - */ - void (*gem_free_object_unlocked) (struct drm_gem_object *obj); - - /** - * @gem_open_object: - * - * This callback is deprecated in favour of &drm_gem_object_funcs.open. - * - * Driver hook called upon gem handle creation - */ - int (*gem_open_object) (struct drm_gem_object *, struct drm_file *); - - /** - * @gem_close_object: - * - * This callback is deprecated in favour of &drm_gem_object_funcs.close. - * - * Driver hook called upon gem handle release - */ - void (*gem_close_object) (struct drm_gem_object *, struct drm_file *); - /** * @gem_create_object: constructor for gem objects * @@ -360,6 +336,7 @@ struct drm_driver { */ struct drm_gem_object *(*gem_create_object)(struct drm_device *dev, size_t size); + /** * @prime_handle_to_fd: * @@ -382,14 +359,7 @@ struct drm_driver { */ int (*prime_fd_to_handle)(struct drm_device *dev, struct drm_file *file_priv, int prime_fd, uint32_t *handle); - /** - * @gem_prime_export: - * - * Export hook for GEM drivers. Deprecated in favour of - * &drm_gem_object_funcs.export. - */ - struct dma_buf * (*gem_prime_export)(struct drm_gem_object *obj, - int flags); + /** * @gem_prime_import: * @@ -399,29 +369,6 @@ struct drm_driver { */ struct drm_gem_object * (*gem_prime_import)(struct drm_device *dev, struct dma_buf *dma_buf); - - /** - * @gem_prime_pin: - * - * Deprecated hook in favour of &drm_gem_object_funcs.pin. - */ - int (*gem_prime_pin)(struct drm_gem_object *obj); - - /** - * @gem_prime_unpin: - * - * Deprecated hook in favour of &drm_gem_object_funcs.unpin. - */ - void (*gem_prime_unpin)(struct drm_gem_object *obj); - - - /** - * @gem_prime_get_sg_table: - * - * Deprecated hook in favour of &drm_gem_object_funcs.get_sg_table. - */ - struct sg_table *(*gem_prime_get_sg_table)(struct drm_gem_object *obj); - /** * @gem_prime_import_sg_table: * @@ -432,22 +379,6 @@ struct drm_driver { struct drm_device *dev, struct dma_buf_attachment *attach, struct sg_table *sgt); - /** - * @gem_prime_vmap: - * - * Deprecated vmap hook for GEM drivers. Please use - * &drm_gem_object_funcs.vmap instead. - */ - void *(*gem_prime_vmap)(struct drm_gem_object *obj); - - /** - * @gem_prime_vunmap: - * - * Deprecated vunmap hook for GEM drivers. Please use - * &drm_gem_object_funcs.vunmap instead. - */ - void (*gem_prime_vunmap)(struct drm_gem_object *obj, void *vaddr); - /** * @gem_prime_mmap: * @@ -522,14 +453,6 @@ struct drm_driver { struct drm_device *dev, uint32_t handle); - /** - * @gem_vm_ops: Driver private ops for this object - * - * For GEM drivers this is deprecated in favour of - * &drm_gem_object_funcs.vm_ops. - */ - const struct vm_operations_struct *gem_vm_ops; - /** @major: driver major number */ int major; /** @minor: driver minor number */ diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h index 337a48321705..c38dd35da00b 100644 --- a/include/drm/drm_gem.h +++ b/include/drm/drm_gem.h @@ -272,7 +272,7 @@ struct drm_gem_object { * attachment point for the device. This is invariant over the lifetime * of a gem object. * - * The &drm_driver.gem_free_object_unlocked callback is responsible for + * The &drm_gem_object_funcs.free callback is responsible for * cleaning up the dma_buf attachment and references acquired at import * time. * From 7faa92dfdf426db40740f59fcdfce48e5cfb7210 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 22 Sep 2020 16:56:58 +0200 Subject: [PATCH 063/235] drm/vram-helper: Integrate drm_gem_vram_init() into drm_gem_vram_create() The drm_gem_vram_create() function is the only caller of the internal helper drm_gem_vram_init(). Streamline the code by putting all code into the create function. v2: * rebased onto latest drm-tip * fixed typo in commit message (Sam) Signed-off-by: Thomas Zimmermann Reviewed-by: Daniel Vetter Acked-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200922145700.25413-2-tzimmermann@suse.de --- drivers/gpu/drm/drm_gem_vram_helper.c | 77 ++++++++++----------------- 1 file changed, 29 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c b/drivers/gpu/drm/drm_gem_vram_helper.c index 171ea57b0311..59f2efd50b05 100644 --- a/drivers/gpu/drm/drm_gem_vram_helper.c +++ b/drivers/gpu/drm/drm_gem_vram_helper.c @@ -167,52 +167,6 @@ static void drm_gem_vram_placement(struct drm_gem_vram_object *gbo, } } -/* - * Note that on error, drm_gem_vram_init will free the buffer object. - */ - -static int drm_gem_vram_init(struct drm_device *dev, - struct drm_gem_vram_object *gbo, - size_t size, unsigned long pg_align) -{ - struct drm_vram_mm *vmm = dev->vram_mm; - struct ttm_bo_device *bdev; - int ret; - size_t acc_size; - - if (WARN_ONCE(!vmm, "VRAM MM not initialized")) { - kfree(gbo); - return -EINVAL; - } - bdev = &vmm->bdev; - - gbo->bo.base.funcs = &drm_gem_vram_object_funcs; - - ret = drm_gem_object_init(dev, &gbo->bo.base, size); - if (ret) { - kfree(gbo); - return ret; - } - - acc_size = ttm_bo_dma_acc_size(bdev, size, sizeof(*gbo)); - - gbo->bo.bdev = bdev; - drm_gem_vram_placement(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM | - DRM_GEM_VRAM_PL_FLAG_SYSTEM); - - ret = ttm_bo_init(bdev, &gbo->bo, size, ttm_bo_type_device, - &gbo->placement, pg_align, false, acc_size, - NULL, NULL, ttm_buffer_object_destroy); - if (ret) - /* - * A failing ttm_bo_init will call ttm_buffer_object_destroy - * to release gbo->bo.base and kfree gbo. - */ - return ret; - - return 0; -} - /** * drm_gem_vram_create() - Creates a VRAM-backed GEM object * @dev: the DRM device @@ -228,7 +182,13 @@ struct drm_gem_vram_object *drm_gem_vram_create(struct drm_device *dev, unsigned long pg_align) { struct drm_gem_vram_object *gbo; + struct drm_vram_mm *vmm = dev->vram_mm; + struct ttm_bo_device *bdev; int ret; + size_t acc_size; + + if (WARN_ONCE(!vmm, "VRAM MM not initialized")) + return ERR_PTR(-EINVAL); if (dev->driver->gem_create_object) { struct drm_gem_object *gem = @@ -242,8 +202,29 @@ struct drm_gem_vram_object *drm_gem_vram_create(struct drm_device *dev, return ERR_PTR(-ENOMEM); } - ret = drm_gem_vram_init(dev, gbo, size, pg_align); - if (ret < 0) + gbo->bo.base.funcs = &drm_gem_vram_object_funcs; + + ret = drm_gem_object_init(dev, &gbo->bo.base, size); + if (ret) { + kfree(gbo); + return ERR_PTR(ret); + } + + bdev = &vmm->bdev; + acc_size = ttm_bo_dma_acc_size(bdev, size, sizeof(*gbo)); + + gbo->bo.bdev = bdev; + drm_gem_vram_placement(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM | + DRM_GEM_VRAM_PL_FLAG_SYSTEM); + + /* + * A failing ttm_bo_init will call ttm_buffer_object_destroy + * to release gbo->bo.base and kfree gbo. + */ + ret = ttm_bo_init(bdev, &gbo->bo, size, ttm_bo_type_device, + &gbo->placement, pg_align, false, acc_size, + NULL, NULL, ttm_buffer_object_destroy); + if (ret) return ERR_PTR(ret); return gbo; From 4d92d7d76dd582fc1212b25a9380acc6123535cb Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 22 Sep 2020 16:56:59 +0200 Subject: [PATCH 064/235] drm/vram-helper: Set object function iff they are not provided by driver Don't override the GEM object functions unconditionally. If the driver sets the GEM functions, VRAM helpers will not set them. The idea has been taken from SHMEM helpers. v2: * updated the commit message (Sam) * document the new feature for drm_gem_vram_create() Signed-off-by: Thomas Zimmermann Reviewed-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20200922145700.25413-3-tzimmermann@suse.de --- drivers/gpu/drm/drm_gem_vram_helper.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c b/drivers/gpu/drm/drm_gem_vram_helper.c index 59f2efd50b05..64c6392b69da 100644 --- a/drivers/gpu/drm/drm_gem_vram_helper.c +++ b/drivers/gpu/drm/drm_gem_vram_helper.c @@ -173,6 +173,12 @@ static void drm_gem_vram_placement(struct drm_gem_vram_object *gbo, * @size: the buffer size in bytes * @pg_align: the buffer's alignment in multiples of the page size * + * GEM objects are allocated by calling struct drm_driver.gem_create_object, + * if set. Otherwise kzalloc() will be used. Drivers can set their own GEM + * object functions in struct drm_driver.gem_create_object. If no functions + * are set, the new GEM object will use the default functions from GEM VRAM + * helpers. + * * Returns: * A new instance of &struct drm_gem_vram_object on success, or * an ERR_PTR()-encoded error code otherwise. @@ -182,6 +188,7 @@ struct drm_gem_vram_object *drm_gem_vram_create(struct drm_device *dev, unsigned long pg_align) { struct drm_gem_vram_object *gbo; + struct drm_gem_object *gem; struct drm_vram_mm *vmm = dev->vram_mm; struct ttm_bo_device *bdev; int ret; @@ -191,8 +198,7 @@ struct drm_gem_vram_object *drm_gem_vram_create(struct drm_device *dev, return ERR_PTR(-EINVAL); if (dev->driver->gem_create_object) { - struct drm_gem_object *gem = - dev->driver->gem_create_object(dev, size); + gem = dev->driver->gem_create_object(dev, size); if (!gem) return ERR_PTR(-ENOMEM); gbo = drm_gem_vram_of_gem(gem); @@ -200,11 +206,13 @@ struct drm_gem_vram_object *drm_gem_vram_create(struct drm_device *dev, gbo = kzalloc(sizeof(*gbo), GFP_KERNEL); if (!gbo) return ERR_PTR(-ENOMEM); + gem = &gbo->bo.base; } - gbo->bo.base.funcs = &drm_gem_vram_object_funcs; + if (!gem->funcs) + gem->funcs = &drm_gem_vram_object_funcs; - ret = drm_gem_object_init(dev, &gbo->bo.base, size); + ret = drm_gem_object_init(dev, gem, size); if (ret) { kfree(gbo); return ERR_PTR(ret); From 8bde6c0d4e7374fedeca959af42ad6819c792e08 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 22 Sep 2020 16:57:00 +0200 Subject: [PATCH 065/235] drm/vram-helper: Don't put new BOs into VRAM Most drivers that use VRAM helpers have only a few MiB of framebuffer memory available. To reduce fragmentation, new BOs are now put into system memory by default. Only pin operations are allowed to move BOs into VRAM. v2: * rebased onto latest drm-tip Signed-off-by: Thomas Zimmermann Reviewed-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20200922145700.25413-4-tzimmermann@suse.de --- drivers/gpu/drm/drm_gem_vram_helper.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c b/drivers/gpu/drm/drm_gem_vram_helper.c index 64c6392b69da..3fe4b326e18e 100644 --- a/drivers/gpu/drm/drm_gem_vram_helper.c +++ b/drivers/gpu/drm/drm_gem_vram_helper.c @@ -222,8 +222,7 @@ struct drm_gem_vram_object *drm_gem_vram_create(struct drm_device *dev, acc_size = ttm_bo_dma_acc_size(bdev, size, sizeof(*gbo)); gbo->bo.bdev = bdev; - drm_gem_vram_placement(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM | - DRM_GEM_VRAM_PL_FLAG_SYSTEM); + drm_gem_vram_placement(gbo, DRM_GEM_VRAM_PL_FLAG_SYSTEM); /* * A failing ttm_bo_init will call ttm_buffer_object_destroy From 06f4277463ba695287829e0b52d9b82be44f99bf Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 18 Sep 2020 12:09:04 +0200 Subject: [PATCH 066/235] fbdev: simplify fb_getput_cmap() This function is one of the remaining users of compat_alloc_user_space() and copy_in_user(). Clean it up by copying to a local data structure copy instead, which also leads to more readable code. Signed-off-by: Arnd Bergmann Acked-by: Daniel Vetter Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200918100926.1447563-1-arnd@arndb.de --- drivers/video/fbdev/core/fbmem.c | 44 ++++++++++++++------------------ 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index 8268bbee8cae..9e5c78e00995 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1215,36 +1215,30 @@ struct fb_cmap32 { static int fb_getput_cmap(struct fb_info *info, unsigned int cmd, unsigned long arg) { - struct fb_cmap_user __user *cmap; - struct fb_cmap32 __user *cmap32; - __u32 data; - int err; + struct fb_cmap32 cmap32; + struct fb_cmap cmap_from; + struct fb_cmap_user cmap; - cmap = compat_alloc_user_space(sizeof(*cmap)); - cmap32 = compat_ptr(arg); - - if (copy_in_user(&cmap->start, &cmap32->start, 2 * sizeof(__u32))) + if (copy_from_user(&cmap32, compat_ptr(arg), sizeof(cmap32))) return -EFAULT; - if (get_user(data, &cmap32->red) || - put_user(compat_ptr(data), &cmap->red) || - get_user(data, &cmap32->green) || - put_user(compat_ptr(data), &cmap->green) || - get_user(data, &cmap32->blue) || - put_user(compat_ptr(data), &cmap->blue) || - get_user(data, &cmap32->transp) || - put_user(compat_ptr(data), &cmap->transp)) - return -EFAULT; + cmap = (struct fb_cmap_user) { + .start = cmap32.start, + .len = cmap32.len, + .red = compat_ptr(cmap32.red), + .green = compat_ptr(cmap32.green), + .blue = compat_ptr(cmap32.blue), + .transp = compat_ptr(cmap32.transp), + }; - err = do_fb_ioctl(info, cmd, (unsigned long) cmap); + if (cmd == FBIOPUTCMAP) + return fb_set_user_cmap(&cmap, info); - if (!err) { - if (copy_in_user(&cmap32->start, - &cmap->start, - 2 * sizeof(__u32))) - err = -EFAULT; - } - return err; + lock_fb_info(info); + cmap_from = info->cmap; + unlock_fb_info(info); + + return fb_cmap_to_user(&cmap_from, &cmap); } static int do_fscreeninfo_to_user(struct fb_fix_screeninfo *fix, From 3f6195d10fffb85dd09833a75c793cb5be7f74e2 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 18 Sep 2020 12:09:05 +0200 Subject: [PATCH 067/235] fbdev: sbuslib: remove unused FBIOSCURSOR32 helper No driver implements FBIOSCURSOR, so this function has no purpose and can be removed. Apparently it was added in linux-2.1.44 to handle compatibility for drivers/sbus/char/sunfb.c but lost its purpose when that driver got rewritten in linux-2.5.63. Signed-off-by: Arnd Bergmann Acked-by: Daniel Vetter Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200918100926.1447563-2-arnd@arndb.de --- drivers/video/fbdev/sbuslib.c | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/drivers/video/fbdev/sbuslib.c b/drivers/video/fbdev/sbuslib.c index 01a7110e61a7..f728db9bcff8 100644 --- a/drivers/video/fbdev/sbuslib.c +++ b/drivers/video/fbdev/sbuslib.c @@ -214,32 +214,6 @@ static int fbiogetputcmap(struct fb_info *info, unsigned int cmd, unsigned long (unsigned long)p); } -static int fbiogscursor(struct fb_info *info, unsigned long arg) -{ - struct fbcursor __user *p = compat_alloc_user_space(sizeof(*p)); - struct fbcursor32 __user *argp = (void __user *)arg; - compat_uptr_t addr; - int ret; - - ret = copy_in_user(p, argp, - 2 * sizeof (short) + 2 * sizeof(struct fbcurpos)); - ret |= copy_in_user(&p->size, &argp->size, sizeof(struct fbcurpos)); - ret |= copy_in_user(&p->cmap, &argp->cmap, 2 * sizeof(int)); - ret |= get_user(addr, &argp->cmap.red); - ret |= put_user(compat_ptr(addr), &p->cmap.red); - ret |= get_user(addr, &argp->cmap.green); - ret |= put_user(compat_ptr(addr), &p->cmap.green); - ret |= get_user(addr, &argp->cmap.blue); - ret |= put_user(compat_ptr(addr), &p->cmap.blue); - ret |= get_user(addr, &argp->mask); - ret |= put_user(compat_ptr(addr), &p->mask); - ret |= get_user(addr, &argp->image); - ret |= put_user(compat_ptr(addr), &p->image); - if (ret) - return -EFAULT; - return info->fbops->fb_ioctl(info, FBIOSCURSOR, (unsigned long)p); -} - int sbusfb_compat_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) { switch (cmd) { @@ -248,6 +222,7 @@ int sbusfb_compat_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar case FBIOGATTR: case FBIOSVIDEO: case FBIOGVIDEO: + case FBIOSCURSOR32: case FBIOGCURSOR32: /* This is not implemented yet. Later it should be converted... */ case FBIOSCURPOS: @@ -258,8 +233,6 @@ int sbusfb_compat_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar return fbiogetputcmap(info, cmd, arg); case FBIOGETCMAP32: return fbiogetputcmap(info, cmd, arg); - case FBIOSCURSOR32: - return fbiogscursor(info, arg); default: return -ENOIOCTLCMD; } From ca6cf78322d1b84744dd2772546c0e8f8707c0ad Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 18 Sep 2020 12:09:06 +0200 Subject: [PATCH 068/235] fbdev: sbuslib: remove compat_alloc_user_space usage This is one of the last users of compat_alloc_user_space() and copy_in_user(). The actual handler is implemented in the same file and could be shared, but as I couldn't test this properly I leave the native case alone and just make a straight copy of it for the compat case, with a minimum set of modifications. Signed-off-by: Arnd Bergmann Acked-by: Daniel Vetter Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200918100926.1447563-3-arnd@arndb.de --- drivers/video/fbdev/sbuslib.c | 95 ++++++++++++++++++++++++++--------- 1 file changed, 70 insertions(+), 25 deletions(-) diff --git a/drivers/video/fbdev/sbuslib.c b/drivers/video/fbdev/sbuslib.c index f728db9bcff8..7f79db827b07 100644 --- a/drivers/video/fbdev/sbuslib.c +++ b/drivers/video/fbdev/sbuslib.c @@ -192,28 +192,6 @@ int sbusfb_ioctl_helper(unsigned long cmd, unsigned long arg, EXPORT_SYMBOL(sbusfb_ioctl_helper); #ifdef CONFIG_COMPAT -static int fbiogetputcmap(struct fb_info *info, unsigned int cmd, unsigned long arg) -{ - struct fbcmap32 __user *argp = (void __user *)arg; - struct fbcmap __user *p = compat_alloc_user_space(sizeof(*p)); - u32 addr; - int ret; - - ret = copy_in_user(p, argp, 2 * sizeof(int)); - ret |= get_user(addr, &argp->red); - ret |= put_user(compat_ptr(addr), &p->red); - ret |= get_user(addr, &argp->green); - ret |= put_user(compat_ptr(addr), &p->green); - ret |= get_user(addr, &argp->blue); - ret |= put_user(compat_ptr(addr), &p->blue); - if (ret) - return -EFAULT; - return info->fbops->fb_ioctl(info, - (cmd == FBIOPUTCMAP32) ? - FBIOPUTCMAP_SPARC : FBIOGETCMAP_SPARC, - (unsigned long)p); -} - int sbusfb_compat_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) { switch (cmd) { @@ -230,9 +208,76 @@ int sbusfb_compat_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar case FBIOGCURMAX: return info->fbops->fb_ioctl(info, cmd, arg); case FBIOPUTCMAP32: - return fbiogetputcmap(info, cmd, arg); - case FBIOGETCMAP32: - return fbiogetputcmap(info, cmd, arg); + case FBIOPUTCMAP_SPARC: { + struct fbcmap32 c; + struct fb_cmap cmap; + u16 red, green, blue; + u8 red8, green8, blue8; + unsigned char __user *ured; + unsigned char __user *ugreen; + unsigned char __user *ublue; + unsigned int i; + + if (copy_from_user(&c, compat_ptr(arg), sizeof(c))) + return -EFAULT; + ured = compat_ptr(c.red); + ugreen = compat_ptr(c.green); + ublue = compat_ptr(c.blue); + + cmap.len = 1; + cmap.red = &red; + cmap.green = &green; + cmap.blue = &blue; + cmap.transp = NULL; + for (i = 0; i < c.count; i++) { + int err; + + if (get_user(red8, &ured[i]) || + get_user(green8, &ugreen[i]) || + get_user(blue8, &ublue[i])) + return -EFAULT; + + red = red8 << 8; + green = green8 << 8; + blue = blue8 << 8; + + cmap.start = c.index + i; + err = fb_set_cmap(&cmap, info); + if (err) + return err; + } + return 0; + } + case FBIOGETCMAP32: { + struct fbcmap32 c; + unsigned char __user *ured; + unsigned char __user *ugreen; + unsigned char __user *ublue; + struct fb_cmap *cmap = &info->cmap; + unsigned int index, i; + u8 red, green, blue; + + if (copy_from_user(&c, compat_ptr(arg), sizeof(c))) + return -EFAULT; + index = c.index; + ured = compat_ptr(c.red); + ugreen = compat_ptr(c.green); + ublue = compat_ptr(c.blue); + + if (index > cmap->len || c.count > cmap->len - index) + return -EINVAL; + + for (i = 0; i < c.count; i++) { + red = cmap->red[index + i] >> 8; + green = cmap->green[index + i] >> 8; + blue = cmap->blue[index + i] >> 8; + if (put_user(red, &ured[i]) || + put_user(green, &ugreen[i]) || + put_user(blue, &ublue[i])) + return -EFAULT; + } + return 0; + } default: return -ENOIOCTLCMD; } From 33700f6f7d9f6b4e1e6df933ef7fd388889c662c Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Sat, 26 Sep 2020 19:04:55 +0200 Subject: [PATCH 069/235] drm/ingenic: Reset pixclock rate when parent clock rate changes Old Ingenic SoCs can overclock very well, up to +50% of their nominal clock rate, whithout requiring overvolting or anything like that, just by changing the rate of the main PLL. Unfortunately, all clocks on the system are derived from that PLL, and when the PLL rate is updated, so is our pixel clock. To counter that issue, we make sure that the panel is in VBLANK before the rate change happens, and we will then re-set the pixel clock rate afterwards, once the PLL has been changed, to be as close as possible to the pixel rate requested by the encoder. v2: Add comment about mutex usage Signed-off-by: Paul Cercueil Reviewed-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200926170501.1109197-2-paul@crapouillou.net --- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 61 ++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index 937d080f5d06..eadfe3a20bf1 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -71,6 +72,21 @@ struct ingenic_drm { bool panel_is_sharp; bool no_vblank; + + /* + * clk_mutex is used to synchronize the pixel clock rate update with + * the VBLANK. When the pixel clock's parent clock needs to be updated, + * clock_nb's notifier function will lock the mutex, then wait until the + * next VBLANK. At that point, the parent clock's rate can be updated, + * and the mutex is then unlocked. If an atomic commit happens in the + * meantime, it will lock on the mutex, effectively waiting until the + * clock update process finishes. Finally, the pixel clock's rate will + * be recomputed when the mutex has been released, in the pending atomic + * commit, or a future one. + */ + struct mutex clk_mutex; + bool update_clk_rate; + struct notifier_block clock_nb; }; static const u32 ingenic_drm_primary_formats[] = { @@ -119,6 +135,29 @@ static inline struct ingenic_drm *drm_crtc_get_priv(struct drm_crtc *crtc) return container_of(crtc, struct ingenic_drm, crtc); } +static inline struct ingenic_drm *drm_nb_get_priv(struct notifier_block *nb) +{ + return container_of(nb, struct ingenic_drm, clock_nb); +} + +static int ingenic_drm_update_pixclk(struct notifier_block *nb, + unsigned long action, + void *data) +{ + struct ingenic_drm *priv = drm_nb_get_priv(nb); + + switch (action) { + case PRE_RATE_CHANGE: + mutex_lock(&priv->clk_mutex); + priv->update_clk_rate = true; + drm_crtc_wait_one_vblank(&priv->crtc); + return NOTIFY_OK; + default: + mutex_unlock(&priv->clk_mutex); + return NOTIFY_OK; + } +} + static void ingenic_drm_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state *state) { @@ -284,8 +323,14 @@ static void ingenic_drm_crtc_atomic_flush(struct drm_crtc *crtc, if (drm_atomic_crtc_needs_modeset(state)) { ingenic_drm_crtc_update_timings(priv, &state->mode); + priv->update_clk_rate = true; + } + if (priv->update_clk_rate) { + mutex_lock(&priv->clk_mutex); clk_set_rate(priv->pix_clk, state->adjusted_mode.clock * 1000); + priv->update_clk_rate = false; + mutex_unlock(&priv->clk_mutex); } if (event) { @@ -1044,16 +1089,28 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) if (soc_info->has_osd) regmap_write(priv->map, JZ_REG_LCD_OSDC, JZ_LCD_OSDC_OSDEN); + mutex_init(&priv->clk_mutex); + priv->clock_nb.notifier_call = ingenic_drm_update_pixclk; + + parent_clk = clk_get_parent(priv->pix_clk); + ret = clk_notifier_register(parent_clk, &priv->clock_nb); + if (ret) { + dev_err(dev, "Unable to register clock notifier\n"); + goto err_devclk_disable; + } + ret = drm_dev_register(drm, 0); if (ret) { dev_err(dev, "Failed to register DRM driver\n"); - goto err_devclk_disable; + goto err_clk_notifier_unregister; } drm_fbdev_generic_setup(drm, 32); return 0; +err_clk_notifier_unregister: + clk_notifier_unregister(parent_clk, &priv->clock_nb); err_devclk_disable: if (priv->lcd_clk) clk_disable_unprepare(priv->lcd_clk); @@ -1075,7 +1132,9 @@ static int compare_of(struct device *dev, void *data) static void ingenic_drm_unbind(struct device *dev) { struct ingenic_drm *priv = dev_get_drvdata(dev); + struct clk *parent_clk = clk_get_parent(priv->pix_clk); + clk_notifier_unregister(parent_clk, &priv->clock_nb); if (priv->lcd_clk) clk_disable_unprepare(priv->lcd_clk); clk_disable_unprepare(priv->pix_clk); From 1677d31c226683236dd80f49e2eea0e6cee08a51 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Sat, 26 Sep 2020 19:04:56 +0200 Subject: [PATCH 070/235] drm/ingenic: Add support for reserved memory Add support for static memory reserved from Device Tree. Since we're using GEM buffers backed by CMA, it is interesting to have an option to specify the CMA area where the GEM buffers will be allocated. v2: Don't abort probe if reserved memory cannot be obtained. The driver will still work fine provided the kernel configuration is sane. Signed-off-by: Paul Cercueil Reviewed-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200926170501.1109197-3-paul@crapouillou.net --- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index eadfe3a20bf1..d34e76f5f57d 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -837,6 +838,11 @@ static void ingenic_drm_unbind_all(void *d) component_unbind_all(priv->dev, &priv->drm); } +static void __maybe_unused ingenic_drm_release_rmem(void *d) +{ + of_reserved_mem_device_release(d); +} + static int ingenic_drm_bind(struct device *dev, bool has_components) { struct platform_device *pdev = to_platform_device(dev); @@ -858,6 +864,19 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) return -EINVAL; } + if (IS_ENABLED(CONFIG_OF_RESERVED_MEM)) { + ret = of_reserved_mem_device_init(dev); + + if (ret && ret != -ENODEV) + dev_warn(dev, "Failed to get reserved memory: %d\n", ret); + + if (!ret) { + ret = devm_add_action_or_reset(dev, ingenic_drm_release_rmem, dev); + if (ret) + return ret; + } + } + priv = devm_drm_dev_alloc(dev, &ingenic_drm_driver_data, struct ingenic_drm, drm); if (IS_ERR(priv)) From 174d8e52a60f196cfbdec299688cf14f124c8b67 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Sat, 26 Sep 2020 19:04:57 +0200 Subject: [PATCH 071/235] drm/ingenic: Alloc F0 and F1 DMA descriptors at once Instead of calling dmam_alloc_coherent() once for each 4-bit DMA hardware descriptor, we can have them both in a physical memory page, as long as they are aligned to 16 bytes. This reduces memory consumption, and will make it easier to add more DMA descriptors in the future. Note that the old code would not create the F0 descriptor on SoCs that don't support multiple planes. We don't care, because: - we don't use more memory by allocating two descriptors instead of a single one; - the only SoC that does not support multiple planes (JZ4740) still has two independent DMA channels, for an unknown reason. Signed-off-by: Paul Cercueil Reviewed-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200926170501.1109197-4-paul@crapouillou.net --- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 51 +++++++++++++---------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index d34e76f5f57d..e8d47549ff2e 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -45,7 +45,12 @@ struct ingenic_dma_hwdesc { u32 addr; u32 id; u32 cmd; -} __packed; +} __aligned(16); + +struct ingenic_dma_hwdescs { + struct ingenic_dma_hwdesc hwdesc_f0; + struct ingenic_dma_hwdesc hwdesc_f1; +}; struct jz_soc_info { bool needs_dev_clk; @@ -68,8 +73,8 @@ struct ingenic_drm { struct clk *lcd_clk, *pix_clk; const struct jz_soc_info *soc_info; - struct ingenic_dma_hwdesc *dma_hwdesc_f0, *dma_hwdesc_f1; - dma_addr_t dma_hwdesc_phys_f0, dma_hwdesc_phys_f1; + struct ingenic_dma_hwdescs *dma_hwdescs; + dma_addr_t dma_hwdescs_phys; bool panel_is_sharp; bool no_vblank; @@ -546,9 +551,9 @@ static void ingenic_drm_plane_atomic_update(struct drm_plane *plane, cpp = state->fb->format->cpp[0]; if (priv->soc_info->has_osd && plane->type == DRM_PLANE_TYPE_OVERLAY) - hwdesc = priv->dma_hwdesc_f0; + hwdesc = &priv->dma_hwdescs->hwdesc_f0; else - hwdesc = priv->dma_hwdesc_f1; + hwdesc = &priv->dma_hwdescs->hwdesc_f1; hwdesc->addr = addr; hwdesc->cmd = JZ_LCD_CMD_EOF_IRQ | (width * height * cpp / 4); @@ -856,6 +861,7 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) void __iomem *base; long parent_rate; unsigned int i, clone_mask = 0; + dma_addr_t dma_hwdesc_phys_f0, dma_hwdesc_phys_f1; int ret, irq; soc_info = of_device_get_match_data(dev); @@ -930,26 +936,25 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) return PTR_ERR(priv->pix_clk); } - priv->dma_hwdesc_f1 = dmam_alloc_coherent(dev, sizeof(*priv->dma_hwdesc_f1), - &priv->dma_hwdesc_phys_f1, - GFP_KERNEL); - if (!priv->dma_hwdesc_f1) + priv->dma_hwdescs = dmam_alloc_coherent(dev, + sizeof(*priv->dma_hwdescs), + &priv->dma_hwdescs_phys, + GFP_KERNEL); + if (!priv->dma_hwdescs) return -ENOMEM; - priv->dma_hwdesc_f1->next = priv->dma_hwdesc_phys_f1; - priv->dma_hwdesc_f1->id = 0xf1; - if (priv->soc_info->has_osd) { - priv->dma_hwdesc_f0 = dmam_alloc_coherent(dev, - sizeof(*priv->dma_hwdesc_f0), - &priv->dma_hwdesc_phys_f0, - GFP_KERNEL); - if (!priv->dma_hwdesc_f0) - return -ENOMEM; + /* Configure DMA hwdesc for foreground0 plane */ + dma_hwdesc_phys_f0 = priv->dma_hwdescs_phys + + offsetof(struct ingenic_dma_hwdescs, hwdesc_f0); + priv->dma_hwdescs->hwdesc_f0.next = dma_hwdesc_phys_f0; + priv->dma_hwdescs->hwdesc_f0.id = 0xf0; - priv->dma_hwdesc_f0->next = priv->dma_hwdesc_phys_f0; - priv->dma_hwdesc_f0->id = 0xf0; - } + /* Configure DMA hwdesc for foreground1 plane */ + dma_hwdesc_phys_f1 = priv->dma_hwdescs_phys + + offsetof(struct ingenic_dma_hwdescs, hwdesc_f1); + priv->dma_hwdescs->hwdesc_f1.next = dma_hwdesc_phys_f1; + priv->dma_hwdescs->hwdesc_f1.id = 0xf1; if (soc_info->has_osd) priv->ipu_plane = drm_plane_from_index(drm, 0); @@ -1101,8 +1106,8 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) } /* Set address of our DMA descriptor chain */ - regmap_write(priv->map, JZ_REG_LCD_DA0, priv->dma_hwdesc_phys_f0); - regmap_write(priv->map, JZ_REG_LCD_DA1, priv->dma_hwdesc_phys_f1); + regmap_write(priv->map, JZ_REG_LCD_DA0, dma_hwdesc_phys_f0); + regmap_write(priv->map, JZ_REG_LCD_DA1, dma_hwdesc_phys_f1); /* Enable OSD if available */ if (soc_info->has_osd) From 3d705fb0dc43a91095de3ebc30914e50b0e20b2f Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Sat, 26 Sep 2020 19:04:58 +0200 Subject: [PATCH 072/235] drm/ingenic: Support handling different pixel formats in F0/F1 planes Until now the ingenic-drm driver supported the same pixel formats on the F0 and F1 planes, and across all SoCs. However, the F0 plane does support paletted 8bpp, while the F1 plane doesn't. Furthermore, the three SoCs currently supported all have different pixel formats available; 24bpp was added in JZ4725B, 30bpp was added in JZ4770. Prepare the inclusion of paletted 8bpp, 24bpp and 30bpp support by having separate pixel format lists for F0 and F1 planes. Signed-off-by: Paul Cercueil Reviewed-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200926170501.1109197-5-paul@crapouillou.net --- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 57 +++++++++++++++++++---- 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index e8d47549ff2e..567facfb7217 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -56,6 +56,8 @@ struct jz_soc_info { bool needs_dev_clk; bool has_osd; unsigned int max_width, max_height; + const u32 *formats_f0, *formats_f1; + unsigned int num_formats_f0, num_formats_f1; }; struct ingenic_drm { @@ -95,12 +97,6 @@ struct ingenic_drm { struct notifier_block clock_nb; }; -static const u32 ingenic_drm_primary_formats[] = { - DRM_FORMAT_XRGB1555, - DRM_FORMAT_RGB565, - DRM_FORMAT_XRGB8888, -}; - static bool ingenic_drm_cached_gem_buf; module_param_named(cached_gem_buffers, ingenic_drm_cached_gem_buf, bool, 0400); MODULE_PARM_DESC(cached_gem_buffers, @@ -963,8 +959,8 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) ret = drm_universal_plane_init(drm, &priv->f1, 1, &ingenic_drm_primary_plane_funcs, - ingenic_drm_primary_formats, - ARRAY_SIZE(ingenic_drm_primary_formats), + priv->soc_info->formats_f1, + priv->soc_info->num_formats_f1, NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) { dev_err(dev, "Failed to register plane: %i\n", ret); @@ -988,8 +984,8 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) ret = drm_universal_plane_init(drm, &priv->f0, 1, &ingenic_drm_primary_plane_funcs, - ingenic_drm_primary_formats, - ARRAY_SIZE(ingenic_drm_primary_formats), + priv->soc_info->formats_f0, + priv->soc_info->num_formats_f0, NULL, DRM_PLANE_TYPE_OVERLAY, NULL); if (ret) { @@ -1204,11 +1200,44 @@ static int ingenic_drm_remove(struct platform_device *pdev) return 0; } +static const u32 jz4740_formats[] = { + DRM_FORMAT_XRGB1555, + DRM_FORMAT_RGB565, + DRM_FORMAT_XRGB8888, +}; + +static const u32 jz4725b_formats_f1[] = { + DRM_FORMAT_XRGB1555, + DRM_FORMAT_RGB565, + DRM_FORMAT_XRGB8888, +}; + +static const u32 jz4725b_formats_f0[] = { + DRM_FORMAT_XRGB1555, + DRM_FORMAT_RGB565, + DRM_FORMAT_XRGB8888, +}; + +static const u32 jz4770_formats_f1[] = { + DRM_FORMAT_XRGB1555, + DRM_FORMAT_RGB565, + DRM_FORMAT_XRGB8888, +}; + +static const u32 jz4770_formats_f0[] = { + DRM_FORMAT_XRGB1555, + DRM_FORMAT_RGB565, + DRM_FORMAT_XRGB8888, +}; + static const struct jz_soc_info jz4740_soc_info = { .needs_dev_clk = true, .has_osd = false, .max_width = 800, .max_height = 600, + .formats_f1 = jz4740_formats, + .num_formats_f1 = ARRAY_SIZE(jz4740_formats), + /* JZ4740 has only one plane */ }; static const struct jz_soc_info jz4725b_soc_info = { @@ -1216,6 +1245,10 @@ static const struct jz_soc_info jz4725b_soc_info = { .has_osd = true, .max_width = 800, .max_height = 600, + .formats_f1 = jz4725b_formats_f1, + .num_formats_f1 = ARRAY_SIZE(jz4725b_formats_f1), + .formats_f0 = jz4725b_formats_f0, + .num_formats_f0 = ARRAY_SIZE(jz4725b_formats_f0), }; static const struct jz_soc_info jz4770_soc_info = { @@ -1223,6 +1256,10 @@ static const struct jz_soc_info jz4770_soc_info = { .has_osd = true, .max_width = 1280, .max_height = 720, + .formats_f1 = jz4770_formats_f1, + .num_formats_f1 = ARRAY_SIZE(jz4770_formats_f1), + .formats_f0 = jz4770_formats_f0, + .num_formats_f0 = ARRAY_SIZE(jz4770_formats_f0), }; static const struct of_device_id ingenic_drm_of_match[] = { From bb85760572ca24a76c3de644ce45cfb69f5a731a Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Sat, 26 Sep 2020 19:05:00 +0200 Subject: [PATCH 073/235] drm/ingenic: Add support for 30-bit modes Starting from the JZ4760 SoC, the primary and overlay planes support 30-bit pixel modes (10 bits per color component). Add support for these in the ingenic-drm driver. Signed-off-by: Paul Cercueil Reviewed-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200926170501.1109197-7-paul@crapouillou.net --- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 8 ++++++++ drivers/gpu/drm/ingenic/ingenic-drm.h | 1 + 2 files changed, 9 insertions(+) diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index 567facfb7217..b5681379ade5 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -458,6 +458,9 @@ void ingenic_drm_plane_config(struct device *dev, case DRM_FORMAT_XRGB8888: ctrl |= JZ_LCD_OSDCTRL_BPP_18_24; break; + case DRM_FORMAT_XRGB2101010: + ctrl |= JZ_LCD_OSDCTRL_BPP_30; + break; } regmap_update_bits(priv->map, JZ_REG_LCD_OSDCTRL, @@ -473,6 +476,9 @@ void ingenic_drm_plane_config(struct device *dev, case DRM_FORMAT_XRGB8888: ctrl |= JZ_LCD_CTRL_BPP_18_24; break; + case DRM_FORMAT_XRGB2101010: + ctrl |= JZ_LCD_CTRL_BPP_30; + break; } regmap_update_bits(priv->map, JZ_REG_LCD_CTRL, @@ -1222,12 +1228,14 @@ static const u32 jz4770_formats_f1[] = { DRM_FORMAT_XRGB1555, DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888, + DRM_FORMAT_XRGB2101010, }; static const u32 jz4770_formats_f0[] = { DRM_FORMAT_XRGB1555, DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888, + DRM_FORMAT_XRGB2101010, }; static const struct jz_soc_info jz4740_soc_info = { diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.h b/drivers/gpu/drm/ingenic/ingenic-drm.h index df99f0f75d39..f05e18e6b6fa 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm.h +++ b/drivers/gpu/drm/ingenic/ingenic-drm.h @@ -124,6 +124,7 @@ #define JZ_LCD_CTRL_BPP_8 0x3 #define JZ_LCD_CTRL_BPP_15_16 0x4 #define JZ_LCD_CTRL_BPP_18_24 0x5 +#define JZ_LCD_CTRL_BPP_30 0x7 #define JZ_LCD_CTRL_BPP_MASK (JZ_LCD_CTRL_RGB555 | 0x7) #define JZ_LCD_CMD_SOF_IRQ BIT(31) From dba09e834f4ee6121346f2a7d40b7ee96d0b4b77 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Sat, 26 Sep 2020 19:05:01 +0200 Subject: [PATCH 074/235] drm/ingenic: Add support for 24-bit modes Starting from the JZ4725B SoC, the primary and overlay planes support 24-bit pixel modes (8 bits per color component, without dummy byte). Add support for these in the ingenic-drm driver. Signed-off-by: Paul Cercueil Reviewed-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200926170501.1109197-8-paul@crapouillou.net --- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 8 ++++++++ drivers/gpu/drm/ingenic/ingenic-drm.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index b5681379ade5..589fc0c60716 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -455,6 +455,9 @@ void ingenic_drm_plane_config(struct device *dev, case DRM_FORMAT_RGB565: ctrl |= JZ_LCD_OSDCTRL_BPP_15_16; break; + case DRM_FORMAT_RGB888: + ctrl |= JZ_LCD_OSDCTRL_BPP_24_COMP; + break; case DRM_FORMAT_XRGB8888: ctrl |= JZ_LCD_OSDCTRL_BPP_18_24; break; @@ -473,6 +476,9 @@ void ingenic_drm_plane_config(struct device *dev, case DRM_FORMAT_RGB565: ctrl |= JZ_LCD_CTRL_BPP_15_16; break; + case DRM_FORMAT_RGB888: + ctrl |= JZ_LCD_CTRL_BPP_24_COMP; + break; case DRM_FORMAT_XRGB8888: ctrl |= JZ_LCD_CTRL_BPP_18_24; break; @@ -1227,6 +1233,7 @@ static const u32 jz4725b_formats_f0[] = { static const u32 jz4770_formats_f1[] = { DRM_FORMAT_XRGB1555, DRM_FORMAT_RGB565, + DRM_FORMAT_RGB888, DRM_FORMAT_XRGB8888, DRM_FORMAT_XRGB2101010, }; @@ -1234,6 +1241,7 @@ static const u32 jz4770_formats_f1[] = { static const u32 jz4770_formats_f0[] = { DRM_FORMAT_XRGB1555, DRM_FORMAT_RGB565, + DRM_FORMAT_RGB888, DRM_FORMAT_XRGB8888, DRM_FORMAT_XRGB2101010, }; diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.h b/drivers/gpu/drm/ingenic/ingenic-drm.h index f05e18e6b6fa..ee3a892c0383 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm.h +++ b/drivers/gpu/drm/ingenic/ingenic-drm.h @@ -124,6 +124,7 @@ #define JZ_LCD_CTRL_BPP_8 0x3 #define JZ_LCD_CTRL_BPP_15_16 0x4 #define JZ_LCD_CTRL_BPP_18_24 0x5 +#define JZ_LCD_CTRL_BPP_24_COMP 0x6 #define JZ_LCD_CTRL_BPP_30 0x7 #define JZ_LCD_CTRL_BPP_MASK (JZ_LCD_CTRL_RGB555 | 0x7) @@ -146,6 +147,7 @@ #define JZ_LCD_OSDCTRL_CHANGE BIT(3) #define JZ_LCD_OSDCTRL_BPP_15_16 0x4 #define JZ_LCD_OSDCTRL_BPP_18_24 0x5 +#define JZ_LCD_OSDCTRL_BPP_24_COMP 0x6 #define JZ_LCD_OSDCTRL_BPP_30 0x7 #define JZ_LCD_OSDCTRL_BPP_MASK (JZ_LCD_OSDCTRL_RGB555 | 0x7) From 686d4b4b99afe791b0ee3f272843048b155fe53f Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Sun, 27 Sep 2020 21:36:45 +0200 Subject: [PATCH 075/235] drm/ingenic: Add support for paletted 8bpp On JZ4725B and newer, the F0 plane supports paletted 8bpp with a 256-entry palette. Add support for it. v3: Only accept a full 256-entry palette. Signed-off-by: Paul Cercueil Reviewed-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200927193645.262612-2-paul@crapouillou.net --- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 66 +++++++++++++++++++++-- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index 589fc0c60716..0225dc1f5eb8 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,8 @@ struct ingenic_dma_hwdesc { struct ingenic_dma_hwdescs { struct ingenic_dma_hwdesc hwdesc_f0; struct ingenic_dma_hwdesc hwdesc_f1; + struct ingenic_dma_hwdesc hwdesc_pal; + u16 palette[256] __aligned(16); }; struct jz_soc_info { @@ -249,6 +252,12 @@ static int ingenic_drm_crtc_atomic_check(struct drm_crtc *crtc, struct ingenic_drm *priv = drm_crtc_get_priv(crtc); struct drm_plane_state *f1_state, *f0_state, *ipu_state = NULL; + if (state->gamma_lut && + drm_color_lut_size(state->gamma_lut) != ARRAY_SIZE(priv->dma_hwdescs->palette)) { + dev_dbg(priv->dev, "Invalid palette size\n"); + return -EINVAL; + } + if (drm_atomic_crtc_needs_modeset(state) && priv->soc_info->has_osd) { f1_state = drm_atomic_get_plane_state(state->state, &priv->f1); if (IS_ERR(f1_state)) @@ -470,6 +479,9 @@ void ingenic_drm_plane_config(struct device *dev, JZ_LCD_OSDCTRL_BPP_MASK, ctrl); } else { switch (fourcc) { + case DRM_FORMAT_C8: + ctrl |= JZ_LCD_CTRL_BPP_8; + break; case DRM_FORMAT_XRGB1555: ctrl |= JZ_LCD_CTRL_RGB555; fallthrough; @@ -541,16 +553,34 @@ void ingenic_drm_sync_data(struct device *dev, } } +static void ingenic_drm_update_palette(struct ingenic_drm *priv, + const struct drm_color_lut *lut) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(priv->dma_hwdescs->palette); i++) { + u16 color = drm_color_lut_extract(lut[i].red, 5) << 11 + | drm_color_lut_extract(lut[i].green, 6) << 5 + | drm_color_lut_extract(lut[i].blue, 5); + + priv->dma_hwdescs->palette[i] = color; + } +} + static void ingenic_drm_plane_atomic_update(struct drm_plane *plane, struct drm_plane_state *oldstate) { struct ingenic_drm *priv = drm_device_get_priv(plane->dev); struct drm_plane_state *state = plane->state; + struct drm_crtc_state *crtc_state; struct ingenic_dma_hwdesc *hwdesc; - unsigned int width, height, cpp; + unsigned int width, height, cpp, offset; dma_addr_t addr; + u32 fourcc; if (state && state->fb) { + crtc_state = state->crtc->state; + ingenic_drm_sync_data(priv->dev, oldstate, state); addr = drm_fb_cma_get_gem_addr(state->fb, state, 0); @@ -566,9 +596,23 @@ static void ingenic_drm_plane_atomic_update(struct drm_plane *plane, hwdesc->addr = addr; hwdesc->cmd = JZ_LCD_CMD_EOF_IRQ | (width * height * cpp / 4); - if (drm_atomic_crtc_needs_modeset(state->crtc->state)) - ingenic_drm_plane_config(priv->dev, plane, - state->fb->format->format); + if (drm_atomic_crtc_needs_modeset(crtc_state)) { + fourcc = state->fb->format->format; + + ingenic_drm_plane_config(priv->dev, plane, fourcc); + + if (fourcc == DRM_FORMAT_C8) + offset = offsetof(struct ingenic_dma_hwdescs, hwdesc_pal); + else + offset = offsetof(struct ingenic_dma_hwdescs, hwdesc_f0); + + priv->dma_hwdescs->hwdesc_f0.next = priv->dma_hwdescs_phys + offset; + + crtc_state->color_mgmt_changed = fourcc == DRM_FORMAT_C8; + } + + if (crtc_state->color_mgmt_changed) + ingenic_drm_update_palette(priv, crtc_state->gamma_lut->data); } } @@ -964,6 +1008,15 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) priv->dma_hwdescs->hwdesc_f1.next = dma_hwdesc_phys_f1; priv->dma_hwdescs->hwdesc_f1.id = 0xf1; + /* Configure DMA hwdesc for palette */ + priv->dma_hwdescs->hwdesc_pal.next = priv->dma_hwdescs_phys + + offsetof(struct ingenic_dma_hwdescs, hwdesc_f0); + priv->dma_hwdescs->hwdesc_pal.id = 0xc0; + priv->dma_hwdescs->hwdesc_pal.addr = priv->dma_hwdescs_phys + + offsetof(struct ingenic_dma_hwdescs, palette); + priv->dma_hwdescs->hwdesc_pal.cmd = JZ_LCD_CMD_ENABLE_PAL + | (sizeof(priv->dma_hwdescs->palette) / 4); + if (soc_info->has_osd) priv->ipu_plane = drm_plane_from_index(drm, 0); @@ -990,6 +1043,9 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) return ret; } + drm_crtc_enable_color_mgmt(&priv->crtc, 0, false, + ARRAY_SIZE(priv->dma_hwdescs->palette)); + if (soc_info->has_osd) { drm_plane_helper_add(&priv->f0, &ingenic_drm_plane_helper_funcs); @@ -1225,6 +1281,7 @@ static const u32 jz4725b_formats_f1[] = { }; static const u32 jz4725b_formats_f0[] = { + DRM_FORMAT_C8, DRM_FORMAT_XRGB1555, DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888, @@ -1239,6 +1296,7 @@ static const u32 jz4770_formats_f1[] = { }; static const u32 jz4770_formats_f0[] = { + DRM_FORMAT_C8, DRM_FORMAT_XRGB1555, DRM_FORMAT_RGB565, DRM_FORMAT_RGB888, From 0b5aebec2bbfb112140122732e7d10788127f682 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 25 Sep 2020 12:40:03 +0200 Subject: [PATCH 076/235] drm/ttm: move SG flag check into ttm_bo_vm_reserve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just check earlier if a BO can be page faulted in the first place. Signed-off-by: Christian König Reviewed-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/392321/ --- drivers/gpu/drm/ttm/ttm_bo_vm.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index 98a006fc30a5..991ef132e108 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -157,6 +157,15 @@ vm_fault_t ttm_bo_vm_reserve(struct ttm_buffer_object *bo, return VM_FAULT_NOPAGE; } + /* + * Refuse to fault imported pages. This should be handled + * (if at all) by redirecting mmap to the exporter. + */ + if (bo->ttm && (bo->ttm->page_flags & TTM_PAGE_FLAG_SG)) { + dma_resv_unlock(bo->base.resv); + return VM_FAULT_SIGBUS; + } + return 0; } EXPORT_SYMBOL(ttm_bo_vm_reserve); @@ -281,13 +290,6 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf, vm_fault_t ret = VM_FAULT_NOPAGE; unsigned long address = vmf->address; - /* - * Refuse to fault imported pages. This should be handled - * (if at all) by redirecting mmap to the exporter. - */ - if (bo->ttm && (bo->ttm->page_flags & TTM_PAGE_FLAG_SG)) - return VM_FAULT_SIGBUS; - if (bdev->driver->fault_reserve_notify) { struct dma_fence *moving = dma_fence_get(bo->moving); From 8e0310f0ff04ea311190f83cc0d18a656fe65d26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 25 Sep 2020 14:17:09 +0200 Subject: [PATCH 077/235] drm/radeon: stop using TTMs fault callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We already implemented the fault handler ourself, just open code what is necessary here. Signed-off-by: Christian König Reviewed-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/392322/ --- drivers/gpu/drm/radeon/radeon_object.c | 22 +++++++++++-------- drivers/gpu/drm/radeon/radeon_object.h | 2 +- drivers/gpu/drm/radeon/radeon_ttm.c | 29 ++++++++++++++++++-------- 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 689426dd8480..8c285eb118f9 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -775,7 +775,7 @@ void radeon_bo_move_notify(struct ttm_buffer_object *bo, radeon_update_memory_usage(rbo, new_mem->mem_type, 1); } -int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo) +vm_fault_t radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo) { struct ttm_operation_ctx ctx = { false, false }; struct radeon_device *rdev; @@ -798,7 +798,7 @@ int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo) /* Can't move a pinned BO to visible VRAM */ if (rbo->tbo.pin_count > 0) - return -EINVAL; + return VM_FAULT_SIGBUS; /* hurrah the memory is not visible ! */ radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_VRAM); @@ -812,16 +812,20 @@ int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo) r = ttm_bo_validate(bo, &rbo->placement, &ctx); if (unlikely(r == -ENOMEM)) { radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT); - return ttm_bo_validate(bo, &rbo->placement, &ctx); - } else if (unlikely(r != 0)) { - return r; + r = ttm_bo_validate(bo, &rbo->placement, &ctx); + } else if (likely(!r)) { + offset = bo->mem.start << PAGE_SHIFT; + /* this should never happen */ + if ((offset + size) > rdev->mc.visible_vram_size) + return VM_FAULT_SIGBUS; } - offset = bo->mem.start << PAGE_SHIFT; - /* this should never happen */ - if ((offset + size) > rdev->mc.visible_vram_size) - return -EINVAL; + if (unlikely(r == -EBUSY || r == -ERESTARTSYS)) + return VM_FAULT_NOPAGE; + else if (unlikely(r)) + return VM_FAULT_SIGBUS; + ttm_bo_move_to_lru_tail_unlocked(bo); return 0; } diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index 27cfb64057fe..d606e9a935e3 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h @@ -163,7 +163,7 @@ extern int radeon_bo_check_tiling(struct radeon_bo *bo, bool has_moved, extern void radeon_bo_move_notify(struct ttm_buffer_object *bo, bool evict, struct ttm_resource *new_mem); -extern int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo); +extern vm_fault_t radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo); extern int radeon_bo_get_surface_reg(struct radeon_bo *bo); extern void radeon_bo_fence(struct radeon_bo *bo, struct radeon_fence *fence, bool shared); diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index df5cedb2b632..63e38b05a5bc 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -803,7 +803,6 @@ static struct ttm_bo_driver radeon_bo_driver = { .move = &radeon_bo_move, .verify_access = &radeon_verify_access, .move_notify = &radeon_bo_move_notify, - .fault_reserve_notify = &radeon_bo_fault_reserve_notify, .io_mem_reserve = &radeon_ttm_io_mem_reserve, }; @@ -904,17 +903,29 @@ void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size) static vm_fault_t radeon_ttm_fault(struct vm_fault *vmf) { - struct ttm_buffer_object *bo; - struct radeon_device *rdev; + struct ttm_buffer_object *bo = vmf->vma->vm_private_data; + struct radeon_device *rdev = radeon_get_rdev(bo->bdev); vm_fault_t ret; - bo = (struct ttm_buffer_object *)vmf->vma->vm_private_data; - if (bo == NULL) - return VM_FAULT_NOPAGE; - - rdev = radeon_get_rdev(bo->bdev); down_read(&rdev->pm.mclk_lock); - ret = ttm_bo_vm_fault(vmf); + + ret = ttm_bo_vm_reserve(bo, vmf); + if (ret) + goto unlock_mclk; + + ret = radeon_bo_fault_reserve_notify(bo); + if (ret) + goto unlock_resv; + + ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot, + TTM_BO_VM_NUM_PREFAULT, 1); + if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) + goto unlock_mclk; + +unlock_resv: + dma_resv_unlock(bo->base.resv); + +unlock_mclk: up_read(&rdev->pm.mclk_lock); return ret; } From d3ef581afa5e6a65cc3a40de2e62901f17b8cebc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 25 Sep 2020 15:21:49 +0200 Subject: [PATCH 078/235] drm/amdgpu: stop using TTMs fault callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement the fault handler ourself using the provided TTM functions. Signed-off-by: Christian König Reviewed-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/392324/ --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 20 +++++------ drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 40 +++++++++++++++++++--- 3 files changed, 46 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 63e9c5793c30..80bc7177cd45 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -1341,19 +1341,14 @@ void amdgpu_bo_release_notify(struct ttm_buffer_object *bo) * Returns: * 0 for success or a negative error code on failure. */ -int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo) +vm_fault_t amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo) { struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); struct ttm_operation_ctx ctx = { false, false }; - struct amdgpu_bo *abo; + struct amdgpu_bo *abo = ttm_to_amdgpu_bo(bo); unsigned long offset, size; int r; - if (!amdgpu_bo_is_amdgpu_bo(bo)) - return 0; - - abo = ttm_to_amdgpu_bo(bo); - /* Remember that this BO was accessed by the CPU */ abo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; @@ -1367,7 +1362,7 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo) /* Can't move a pinned BO to visible VRAM */ if (abo->tbo.pin_count > 0) - return -EINVAL; + return VM_FAULT_SIGBUS; /* hurrah the memory is not visible ! */ atomic64_inc(&adev->num_vram_cpu_page_faults); @@ -1379,15 +1374,18 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo) abo->placement.busy_placement = &abo->placements[1]; r = ttm_bo_validate(bo, &abo->placement, &ctx); - if (unlikely(r != 0)) - return r; + if (unlikely(r == -EBUSY || r == -ERESTARTSYS)) + return VM_FAULT_NOPAGE; + else if (unlikely(r)) + return VM_FAULT_SIGBUS; offset = bo->mem.start << PAGE_SHIFT; /* this should never happen */ if (bo->mem.mem_type == TTM_PL_VRAM && (offset + size) > adev->gmc.visible_vram_size) - return -EINVAL; + return VM_FAULT_SIGBUS; + ttm_bo_move_to_lru_tail_unlocked(bo); return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h index e91750e43448..132e5f955180 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h @@ -284,7 +284,7 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict, struct ttm_resource *new_mem); void amdgpu_bo_release_notify(struct ttm_buffer_object *bo); -int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo); +vm_fault_t amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo); void amdgpu_bo_fence(struct amdgpu_bo *bo, struct dma_fence *fence, bool shared); int amdgpu_bo_sync_wait_resv(struct amdgpu_device *adev, struct dma_resv *resv, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index d3bd2fd448be..399961035ae6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -1708,7 +1708,6 @@ static struct ttm_bo_driver amdgpu_bo_driver = { .verify_access = &amdgpu_verify_access, .move_notify = &amdgpu_bo_move_notify, .release_notify = &amdgpu_bo_release_notify, - .fault_reserve_notify = &amdgpu_bo_fault_reserve_notify, .io_mem_reserve = &amdgpu_ttm_io_mem_reserve, .io_mem_pfn = amdgpu_ttm_io_mem_pfn, .access_memory = &amdgpu_ttm_access_memory, @@ -2088,15 +2087,48 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable) adev->mman.buffer_funcs_enabled = enable; } +static vm_fault_t amdgpu_ttm_fault(struct vm_fault *vmf) +{ + struct ttm_buffer_object *bo = vmf->vma->vm_private_data; + vm_fault_t ret; + + ret = ttm_bo_vm_reserve(bo, vmf); + if (ret) + return ret; + + ret = amdgpu_bo_fault_reserve_notify(bo); + if (ret) + goto unlock; + + ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot, + TTM_BO_VM_NUM_PREFAULT, 1); + if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) + return ret; + +unlock: + dma_resv_unlock(bo->base.resv); + return ret; +} + +static struct vm_operations_struct amdgpu_ttm_vm_ops = { + .fault = amdgpu_ttm_fault, + .open = ttm_bo_vm_open, + .close = ttm_bo_vm_close, + .access = ttm_bo_vm_access +}; + int amdgpu_mmap(struct file *filp, struct vm_area_struct *vma) { struct drm_file *file_priv = filp->private_data; struct amdgpu_device *adev = drm_to_adev(file_priv->minor->dev); + int r; - if (adev == NULL) - return -EINVAL; + r = ttm_bo_mmap(filp, vma, &adev->mman.bdev); + if (unlikely(r != 0)) + return r; - return ttm_bo_mmap(filp, vma, &adev->mman.bdev); + vma->vm_ops = &amdgpu_ttm_vm_ops; + return 0; } int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset, From 76fe313adde2db165aea82699aca215ea6e9b11b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 25 Sep 2020 15:42:04 +0200 Subject: [PATCH 079/235] drm/nouveau: stop using TTMs fault callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We already implemented the fault handler ourself, just open code what is necessary here. Signed-off-by: Christian König Reviewed-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/392323/ --- drivers/gpu/drm/nouveau/nouveau_bo.c | 54 ++++++++++++++------------- drivers/gpu/drm/nouveau/nouveau_bo.h | 1 + drivers/gpu/drm/nouveau/nouveau_ttm.c | 10 +++-- 3 files changed, 35 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 8d51cfca07c8..1d4b16c0e353 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1226,8 +1226,7 @@ nouveau_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_resource *reg) mutex_unlock(&drm->ttm.io_reserve_mutex); } -static int -nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo) +vm_fault_t nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo) { struct nouveau_drm *drm = nouveau_bdev(bo->bdev); struct nouveau_bo *nvbo = nouveau_bo(bo); @@ -1243,34 +1242,38 @@ nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo) !nvbo->kind) return 0; - if (bo->mem.mem_type == TTM_PL_SYSTEM) { - nouveau_bo_placement_set(nvbo, NOUVEAU_GEM_DOMAIN_GART, - 0); + if (bo->mem.mem_type != TTM_PL_SYSTEM) + return 0; - ret = nouveau_bo_validate(nvbo, false, false); - if (ret) - return ret; + nouveau_bo_placement_set(nvbo, NOUVEAU_GEM_DOMAIN_GART, 0); + + } else { + /* make sure bo is in mappable vram */ + if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA || + bo->mem.start + bo->mem.num_pages < mappable) + return 0; + + for (i = 0; i < nvbo->placement.num_placement; ++i) { + nvbo->placements[i].fpfn = 0; + nvbo->placements[i].lpfn = mappable; } - return 0; + + for (i = 0; i < nvbo->placement.num_busy_placement; ++i) { + nvbo->busy_placements[i].fpfn = 0; + nvbo->busy_placements[i].lpfn = mappable; + } + + nouveau_bo_placement_set(nvbo, NOUVEAU_GEM_DOMAIN_VRAM, 0); } - /* make sure bo is in mappable vram */ - if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA || - bo->mem.start + bo->mem.num_pages < mappable) - return 0; + ret = nouveau_bo_validate(nvbo, false, false); + if (unlikely(ret == -EBUSY || ret == -ERESTARTSYS)) + return VM_FAULT_NOPAGE; + else if (unlikely(ret)) + return VM_FAULT_SIGBUS; - for (i = 0; i < nvbo->placement.num_placement; ++i) { - nvbo->placements[i].fpfn = 0; - nvbo->placements[i].lpfn = mappable; - } - - for (i = 0; i < nvbo->placement.num_busy_placement; ++i) { - nvbo->busy_placements[i].fpfn = 0; - nvbo->busy_placements[i].lpfn = mappable; - } - - nouveau_bo_placement_set(nvbo, NOUVEAU_GEM_DOMAIN_VRAM, 0); - return nouveau_bo_validate(nvbo, false, false); + ttm_bo_move_to_lru_tail_unlocked(bo); + return 0; } static int @@ -1381,7 +1384,6 @@ struct ttm_bo_driver nouveau_bo_driver = { .move_notify = nouveau_bo_move_ntfy, .move = nouveau_bo_move, .verify_access = nouveau_bo_verify_access, - .fault_reserve_notify = &nouveau_ttm_fault_reserve_notify, .io_mem_reserve = &nouveau_ttm_io_mem_reserve, .io_mem_free = &nouveau_ttm_io_mem_free, }; diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.h b/drivers/gpu/drm/nouveau/nouveau_bo.h index ff68ded8d590..641ef6298a0e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.h +++ b/drivers/gpu/drm/nouveau/nouveau_bo.h @@ -89,6 +89,7 @@ void nouveau_bo_placement_set(struct nouveau_bo *, u32 type, u32 busy); void nouveau_bo_wr16(struct nouveau_bo *, unsigned index, u16 val); u32 nouveau_bo_rd32(struct nouveau_bo *, unsigned index); void nouveau_bo_wr32(struct nouveau_bo *, unsigned index, u32 val); +vm_fault_t nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo); void nouveau_bo_fence(struct nouveau_bo *, struct nouveau_fence *, bool exclusive); int nouveau_bo_validate(struct nouveau_bo *, bool interruptible, bool no_wait_gpu); diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index 427341753441..edf3bb89a47f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -134,17 +134,19 @@ static vm_fault_t nouveau_ttm_fault(struct vm_fault *vmf) if (ret) return ret; - nouveau_bo_del_io_reserve_lru(bo); + ret = nouveau_ttm_fault_reserve_notify(bo); + if (ret) + goto error_unlock; + nouveau_bo_del_io_reserve_lru(bo); prot = vm_get_page_prot(vma->vm_flags); ret = ttm_bo_vm_fault_reserved(vmf, prot, TTM_BO_VM_NUM_PREFAULT, 1); + nouveau_bo_add_io_reserve_lru(bo); if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) return ret; - nouveau_bo_add_io_reserve_lru(bo); - +error_unlock: dma_resv_unlock(bo->base.resv); - return ret; } From 45e241f8c5d7798e63a0c79b49d39fc9d38e8f59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 25 Sep 2020 15:45:19 +0200 Subject: [PATCH 080/235] drm/ttm: remove fault callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Another one bites the dust. Signed-off-by: Christian König Reviewed-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/392325/ --- drivers/gpu/drm/ttm/ttm_bo_vm.c | 22 ---------------------- include/drm/ttm/ttm_bo_driver.h | 3 --- 2 files changed, 25 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index 991ef132e108..87ee8f0ca08e 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -290,28 +290,6 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf, vm_fault_t ret = VM_FAULT_NOPAGE; unsigned long address = vmf->address; - if (bdev->driver->fault_reserve_notify) { - struct dma_fence *moving = dma_fence_get(bo->moving); - - err = bdev->driver->fault_reserve_notify(bo); - switch (err) { - case 0: - break; - case -EBUSY: - case -ERESTARTSYS: - dma_fence_put(moving); - return VM_FAULT_NOPAGE; - default: - dma_fence_put(moving); - return VM_FAULT_SIGBUS; - } - - if (bo->moving != moving) { - ttm_bo_move_to_lru_tail_unlocked(bo); - } - dma_fence_put(moving); - } - /* * Wait for buffer data in transit, due to a pipelined * move. diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index 864afa8f6f18..9897a16c0a9d 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -190,9 +190,6 @@ struct ttm_bo_driver { void (*move_notify)(struct ttm_buffer_object *bo, bool evict, struct ttm_resource *new_mem); - /* notify the driver we are taking a fault on this BO - * and have reserved it */ - int (*fault_reserve_notify)(struct ttm_buffer_object *bo); /** * notify the driver that we're about to swap out this bo From ca876a1d30e51fd1b1d1283b9a7b0988ffb30f03 Mon Sep 17 00:00:00 2001 From: Tian Tao Date: Fri, 25 Sep 2020 15:48:06 +0800 Subject: [PATCH 081/235] drm/hisilicon: Deleted the drm_device declaration drm_framebuffer.h already declares struct drm_device, so there's no need to declare it in hibmc_drm_drv.h v2: fixed spelling errors in commit message. v3: rewrite the commit message. Signed-off-by: Tian Tao Acked-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/1601020086-43652-1-git-send-email-tiantao6@hisilicon.com --- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h index 87d2aad0bb5e..6a635027f758 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h @@ -22,8 +22,6 @@ #include #include -struct drm_device; - struct hibmc_connector { struct drm_connector base; From 8f7db83e6abf863c6a2cfddbe7086f1e3251fdbf Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 28 Sep 2020 10:16:43 +0200 Subject: [PATCH 082/235] drm/rockchip: Include for drm_gem_cm_vm_ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Include to get drm_gem_cma_vm_ops. Fallout from the recent conversion to GEM object functions. Signed-off-by: Thomas Zimmermann Reviewed-by: Sam Ravnborg Reported-by: kernel test robot Fixes: 0d590af3140d ("drm/rockchip: Convert to drm_gem_object_funcs") Cc: Thomas Zimmermann Cc: Daniel Vetter Cc: Christian König Cc: Sandy Huang Cc: "Heiko Stübner" Cc: dri-devel@lists.freedesktop.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-rockchip@lists.infradead.org Link: https://patchwork.freedesktop.org/patch/msgid/20200928081643.8575-1-tzimmermann@suse.de --- drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c index bb3578469b03..6da15faf0192 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c @@ -10,6 +10,7 @@ #include #include +#include #include #include From 30172efbfb842cd898e34fea8694ed250200eaab Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Wed, 23 Sep 2020 17:31:56 -0700 Subject: [PATCH 083/235] drm/virtio: blob prep: refactor getting pages and attaching backing Useful for upcoming blob resources. Signed-off-by: Gurchetan Singh Acked-by: Tomeu Vizoso Link: http://patchwork.freedesktop.org/patch/msgid/20200924003214.662-1-gurchetansingh@chromium.org Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_object.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index 4f7d7ea8194c..74cfe47ad46b 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -229,21 +229,21 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, goto err_put_objs; } - if (params->virgl) { - virtio_gpu_cmd_resource_create_3d(vgdev, bo, params, - objs, fence); - } else { - virtio_gpu_cmd_create_resource(vgdev, bo, params, - objs, fence); - } - ret = virtio_gpu_object_shmem_init(vgdev, bo, &ents, &nents); if (ret != 0) { virtio_gpu_free_object(&shmem_obj->base); return ret; } - virtio_gpu_object_attach(vgdev, bo, ents, nents); + if (params->virgl) { + virtio_gpu_cmd_resource_create_3d(vgdev, bo, params, + objs, fence); + virtio_gpu_object_attach(vgdev, bo, ents, nents); + } else { + virtio_gpu_cmd_create_resource(vgdev, bo, params, + objs, fence); + virtio_gpu_object_attach(vgdev, bo, ents, nents); + } *bo_ptr = bo; return 0; From 0ce0729656382da069d64d21ab4bed5434f79559 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Wed, 23 Sep 2020 17:31:57 -0700 Subject: [PATCH 084/235] drm/virtio: blob prep: make CPU responses more generic RESOURCE_MAP_BLOB / RESOURCE_UNMAP_BLOB can use this. Signed-off-by: Gurchetan Singh Acked-by: Tomeu Vizoso Link: http://patchwork.freedesktop.org/patch/msgid/20200924003214.662-2-gurchetansingh@chromium.org Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_drv.h | 6 +++--- drivers/gpu/drm/virtio/virtgpu_prime.c | 6 +++--- drivers/gpu/drm/virtio/virtgpu_vq.c | 10 +++++----- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 55c34b4fc3e9..272abe177ded 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -49,9 +49,9 @@ #define DRIVER_MINOR 1 #define DRIVER_PATCHLEVEL 0 -#define UUID_INITIALIZING 0 -#define UUID_INITIALIZED 1 -#define UUID_INITIALIZATION_FAILED 2 +#define STATE_INITIALIZING 0 +#define STATE_OK 1 +#define STATE_ERR 2 struct virtio_gpu_object_params { uint32_t format; diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c index acd14ef73d56..3552db128ba3 100644 --- a/drivers/gpu/drm/virtio/virtgpu_prime.c +++ b/drivers/gpu/drm/virtio/virtgpu_prime.c @@ -34,8 +34,8 @@ static int virtgpu_virtio_get_uuid(struct dma_buf *buf, struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj); struct virtio_gpu_device *vgdev = obj->dev->dev_private; - wait_event(vgdev->resp_wq, bo->uuid_state != UUID_INITIALIZING); - if (bo->uuid_state != UUID_INITIALIZED) + wait_event(vgdev->resp_wq, bo->uuid_state != STATE_INITIALIZING); + if (bo->uuid_state != STATE_OK) return -ENODEV; uuid_copy(uuid, &bo->uuid); @@ -81,7 +81,7 @@ struct dma_buf *virtgpu_gem_prime_export(struct drm_gem_object *obj, return ERR_PTR(ret); virtio_gpu_notify(vgdev); } else { - bo->uuid_state = UUID_INITIALIZATION_FAILED; + bo->uuid_state = STATE_ERR; } exp_info.ops = &virtgpu_dmabuf_ops.ops; diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index a7550044b8b2..55529ed97d9c 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -1127,14 +1127,14 @@ static void virtio_gpu_cmd_resource_uuid_cb(struct virtio_gpu_device *vgdev, uint32_t resp_type = le32_to_cpu(resp->hdr.type); spin_lock(&vgdev->resource_export_lock); - WARN_ON(obj->uuid_state != UUID_INITIALIZING); + WARN_ON(obj->uuid_state != STATE_INITIALIZING); if (resp_type == VIRTIO_GPU_RESP_OK_RESOURCE_UUID && - obj->uuid_state == UUID_INITIALIZING) { + obj->uuid_state == STATE_INITIALIZING) { memcpy(&obj->uuid.b, resp->uuid, sizeof(obj->uuid.b)); - obj->uuid_state = UUID_INITIALIZED; + obj->uuid_state = STATE_OK; } else { - obj->uuid_state = UUID_INITIALIZATION_FAILED; + obj->uuid_state = STATE_ERR; } spin_unlock(&vgdev->resource_export_lock); @@ -1153,7 +1153,7 @@ virtio_gpu_cmd_resource_assign_uuid(struct virtio_gpu_device *vgdev, resp_buf = kzalloc(sizeof(*resp_buf), GFP_KERNEL); if (!resp_buf) { spin_lock(&vgdev->resource_export_lock); - bo->uuid_state = UUID_INITIALIZATION_FAILED; + bo->uuid_state = STATE_ERR; spin_unlock(&vgdev->resource_export_lock); virtio_gpu_array_put_free(objs); return -ENOMEM; From ff886cbdcc44334b5f876721cf65428aa955948b Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 23 Sep 2020 17:31:58 -0700 Subject: [PATCH 085/235] virtio-gpu api: blob resources A blob resource is a container for: - VIRTIO_GPU_BLOB_MEM_GUEST: a guest memory allocation (referred to as a "guest-only blob resource") - VIRTIO_GPU_BLOB_MEM_HOST3D: a host3d memory allocation (referred to as a "host-only blob resource") - VIRTIO_GPU_BLOB_MEM_HOST3D_GUEST: a guest + host3d memory allocation (referred to as a "default blob resource"). The memory properties of the blob resource must be described by `blob_mem`. For default and guest only blob resources set, `nents` guest system pages are assigned to the resource. For default blob resources, these guest pages are used for transfer operations. Attach/detach is also possible to allow swap-in/swap-out, but isn't required since it may not be applicable to future blob mem types (shared guest/guest vram). Host allocations depend on whether the 3D is supported. If 3D is not supported, the only valid field for `blob_mem` is VIRTIO_GPU_BLOB_MEM_GUEST. If 3D is supported, the virtio-gpu resource is created from the context local object identified by the `blob_id`. The actual host allocation done by the CMD_SUBMIT_3D. Userspace must specify if the blob resource is intended to be used for userspace mapping, sharing between virtio-gpu contexts and/or sharing between virtio devices. This is done via `blob_flags`. For 3D hosts, both VIRTIO_GPU_CMD_TRANSFER_TO_HOST_3D and VIRTIO_GPU_CMD_TRANSFER_FROM_HOST_3D may be used to update the host resource. There is no restriction on the image/buffer view the guest/host userspace has on the blob resource. VIRTIO_GPU_CMD_SET_SCANOUT_BLOB / VIRTIO_GPU_CMD_RESOURCE_FLUSH may be used with blob resources as well. The modifier is intentionally left out of SCANOUT_BLOB, and auxilary blobs are also left out as a simplification. The use case for blob resources is zero-copy, needed for coherent memory in virglrenderer. Host only blob resources are not mappable without the feature described in the next patch, but are shareable. Future work: - Emulated coherent `blob_mem` type for QEMU/vhost-user - A `blob_mem` type for guest-only resources imported in cache-coherent FOSS GPU/display drivers. - Display integration involving the blob model using seamless Wayland windows. Signed-off-by: Gerd Hoffmann Acked-by: Tomeu Vizoso Acked-by: Chia-I Wu Acked-by: Lingfeng Yang Link: http://patchwork.freedesktop.org/patch/msgid/20200924003214.662-3-gurchetansingh@chromium.org Co-developed-by: Gurchetan Singh Signed-off-by: Gurchetan Singh --- include/uapi/linux/virtio_gpu.h | 43 +++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h index 747a5c5cc4e6..4ddf2fe342ed 100644 --- a/include/uapi/linux/virtio_gpu.h +++ b/include/uapi/linux/virtio_gpu.h @@ -55,6 +55,11 @@ */ #define VIRTIO_GPU_F_RESOURCE_UUID 2 +/* + * VIRTIO_GPU_CMD_RESOURCE_CREATE_BLOB + */ +#define VIRTIO_GPU_F_RESOURCE_BLOB 3 + enum virtio_gpu_ctrl_type { VIRTIO_GPU_UNDEFINED = 0, @@ -71,6 +76,8 @@ enum virtio_gpu_ctrl_type { VIRTIO_GPU_CMD_GET_CAPSET, VIRTIO_GPU_CMD_GET_EDID, VIRTIO_GPU_CMD_RESOURCE_ASSIGN_UUID, + VIRTIO_GPU_CMD_RESOURCE_CREATE_BLOB, + VIRTIO_GPU_CMD_SET_SCANOUT_BLOB, /* 3d commands */ VIRTIO_GPU_CMD_CTX_CREATE = 0x0200, @@ -359,4 +366,40 @@ struct virtio_gpu_resp_resource_uuid { __u8 uuid[16]; }; +/* VIRTIO_GPU_CMD_RESOURCE_CREATE_BLOB */ +struct virtio_gpu_resource_create_blob { + struct virtio_gpu_ctrl_hdr hdr; + __le32 resource_id; +#define VIRTIO_GPU_BLOB_MEM_GUEST 0x0001 +#define VIRTIO_GPU_BLOB_MEM_HOST3D 0x0002 +#define VIRTIO_GPU_BLOB_MEM_HOST3D_GUEST 0x0003 + +#define VIRTIO_GPU_BLOB_FLAG_USE_MAPPABLE 0x0001 +#define VIRTIO_GPU_BLOB_FLAG_USE_SHAREABLE 0x0002 +#define VIRTIO_GPU_BLOB_FLAG_USE_CROSS_DEVICE 0x0004 + /* zero is invalid blob mem */ + __le32 blob_mem; + __le32 blob_flags; + __le64 blob_id; + __le64 size; + __le32 nr_entries; + /* + * sizeof(nr_entries * virtio_gpu_mem_entry) bytes follow + */ +}; + +/* VIRTIO_GPU_CMD_SET_SCANOUT_BLOB */ +struct virtio_gpu_set_scanout_blob { + struct virtio_gpu_ctrl_hdr hdr; + struct virtio_gpu_rect r; + __le32 scanout_id; + __le32 resource_id; + __le32 width; + __le32 height; + __le32 format; + __le32 padding; + __le32 strides[4]; + __le32 offsets[4]; +}; + #endif From e5cd6cbe025570f6135f48538cb450254f8fbdd3 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 23 Sep 2020 17:31:59 -0700 Subject: [PATCH 086/235] virtio-gpu api: host visible feature This patch adds a new virtgpu feature that allows directly mapping host allocated resources. This is based on virtio shared memory regions, which allows querying for memory regions using PCI transport. Each shared memory region has an associated "shmid", the meaning of which is device specific. For virtio-gpu, we can define the shared memory region with id VIRTIO_GPU_SHM_ID_HOST_VISIBLE to be the "host visible memory region". The presence of the host visible memory region means the following hypercalls are supported: 1) VIRTIO_GPU_CMD_RESOURCE_MAP_BLOB This hypercall tells the host to inject the host resource's mapping in an offset into virtio-gpu's PCI address space. This is typically done via KVM_SET_USER_MEMORY_REGION on Linux hosts. On success, VIRTIO_GPU_RESP_OK_MAP_INFO is returned, which specifies the host buffer's caching type and possibly in the future performance hints about the buffer.. 2) VIRTIO_GPU_CMD_RESOURCE_UNMAP_BLOB This hypercall tells the host to remove the host resource's mapping from the guest VM. Signed-off-by: Gerd Hoffmann Acked-by: Tomeu Vizoso Acked-by: Lingfeng Yang Link: http://patchwork.freedesktop.org/patch/msgid/20200924003214.662-4-gurchetansingh@chromium.org Co-developed-by: Gurchetan Singh Signed-off-by: Gurchetan Singh --- include/uapi/linux/virtio_gpu.h | 35 +++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h index 4ddf2fe342ed..fa2ae4a1da5f 100644 --- a/include/uapi/linux/virtio_gpu.h +++ b/include/uapi/linux/virtio_gpu.h @@ -88,6 +88,8 @@ enum virtio_gpu_ctrl_type { VIRTIO_GPU_CMD_TRANSFER_TO_HOST_3D, VIRTIO_GPU_CMD_TRANSFER_FROM_HOST_3D, VIRTIO_GPU_CMD_SUBMIT_3D, + VIRTIO_GPU_CMD_RESOURCE_MAP_BLOB, + VIRTIO_GPU_CMD_RESOURCE_UNMAP_BLOB, /* cursor commands */ VIRTIO_GPU_CMD_UPDATE_CURSOR = 0x0300, @@ -100,6 +102,7 @@ enum virtio_gpu_ctrl_type { VIRTIO_GPU_RESP_OK_CAPSET, VIRTIO_GPU_RESP_OK_EDID, VIRTIO_GPU_RESP_OK_RESOURCE_UUID, + VIRTIO_GPU_RESP_OK_MAP_INFO, /* error responses */ VIRTIO_GPU_RESP_ERR_UNSPEC = 0x1200, @@ -110,6 +113,11 @@ enum virtio_gpu_ctrl_type { VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER, }; +enum virtio_gpu_shm_id { + VIRTIO_GPU_SHM_ID_UNDEFINED = 0, + VIRTIO_GPU_SHM_ID_HOST_VISIBLE = 1 +}; + #define VIRTIO_GPU_FLAG_FENCE (1 << 0) struct virtio_gpu_ctrl_hdr { @@ -402,4 +410,31 @@ struct virtio_gpu_set_scanout_blob { __le32 offsets[4]; }; +/* VIRTIO_GPU_CMD_RESOURCE_MAP_BLOB */ +struct virtio_gpu_resource_map_blob { + struct virtio_gpu_ctrl_hdr hdr; + __le32 resource_id; + __le32 padding; + __le64 offset; +}; + +/* VIRTIO_GPU_RESP_OK_MAP_INFO */ +#define VIRTIO_GPU_MAP_CACHE_MASK 0x0f +#define VIRTIO_GPU_MAP_CACHE_NONE 0x00 +#define VIRTIO_GPU_MAP_CACHE_CACHED 0x01 +#define VIRTIO_GPU_MAP_CACHE_UNCACHED 0x02 +#define VIRTIO_GPU_MAP_CACHE_WC 0x03 +struct virtio_gpu_resp_map_info { + struct virtio_gpu_ctrl_hdr hdr; + __u32 map_info; + __u32 padding; +}; + +/* VIRTIO_GPU_CMD_RESOURCE_UNMAP_BLOB */ +struct virtio_gpu_resource_unmap_blob { + struct virtio_gpu_ctrl_hdr hdr; + __le32 resource_id; + __le32 padding; +}; + #endif From eda3e1018f786f8f3db93001fb2da757b193ed1a Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Wed, 23 Sep 2020 17:32:00 -0700 Subject: [PATCH 087/235] drm/virtgpu api: blob resources This makes blob resources available to guest userspace. They are needed for GL4.5, Vulkan and zero-copy virtio-gpu. For Mesa, blob resources have been tested with Piglit's ARB_buffer_storage tests and apitraces. Apitraces of GL4.5 games show we're between 70% to 80% of host performance on Iris, based on a apitrace of a 2013 GL4.5 game: 11.204 FPS (guest) 15.947 FPS (host) This is still better than the status quo, when said game was unplayable with Virgl due to an inefficient GL4.3 fallback. But there's still room for improvement if we want to match HW-assisted virtualization. For Vulkan, blob resources have been tested with dEQP.vk.memory* and running Vulkan applications in production with the "Cuttlefish" virtual Android device. This has been done with Lingfeng Yang's "gfxstream" Vulkan implementation, which virtualizes Vulkan across many Google products. Signed-off-by: Gurchetan Singh Acked-by: Tomeu Vizoso Acked-by: Chia-I Wu Acked-by: Lingfeng Yang Link: http://patchwork.freedesktop.org/patch/msgid/20200924003214.662-5-gurchetansingh@chromium.org Signed-off-by: Gerd Hoffmann --- include/uapi/drm/virtgpu_drm.h | 37 +++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/include/uapi/drm/virtgpu_drm.h b/include/uapi/drm/virtgpu_drm.h index f06a789f34cd..bb224f604c9e 100644 --- a/include/uapi/drm/virtgpu_drm.h +++ b/include/uapi/drm/virtgpu_drm.h @@ -46,6 +46,7 @@ extern "C" { #define DRM_VIRTGPU_TRANSFER_TO_HOST 0x07 #define DRM_VIRTGPU_WAIT 0x08 #define DRM_VIRTGPU_GET_CAPS 0x09 +#define DRM_VIRTGPU_RESOURCE_CREATE_BLOB 0x0a #define VIRTGPU_EXECBUF_FENCE_FD_IN 0x01 #define VIRTGPU_EXECBUF_FENCE_FD_OUT 0x02 @@ -71,6 +72,7 @@ struct drm_virtgpu_execbuffer { #define VIRTGPU_PARAM_3D_FEATURES 1 /* do we have 3D features in the hw */ #define VIRTGPU_PARAM_CAPSET_QUERY_FIX 2 /* do we have the capset fix */ +#define VIRTGPU_PARAM_RESOURCE_BLOB 3 /* DRM_VIRTGPU_RESOURCE_CREATE_BLOB */ struct drm_virtgpu_getparam { __u64 param; @@ -100,7 +102,7 @@ struct drm_virtgpu_resource_info { __u32 bo_handle; __u32 res_handle; __u32 size; - __u32 stride; + __u32 blob_mem; }; struct drm_virtgpu_3d_box { @@ -117,6 +119,8 @@ struct drm_virtgpu_3d_transfer_to_host { struct drm_virtgpu_3d_box box; __u32 level; __u32 offset; + __u32 stride; + __u32 layer_stride; }; struct drm_virtgpu_3d_transfer_from_host { @@ -124,6 +128,8 @@ struct drm_virtgpu_3d_transfer_from_host { struct drm_virtgpu_3d_box box; __u32 level; __u32 offset; + __u32 stride; + __u32 layer_stride; }; #define VIRTGPU_WAIT_NOWAIT 1 /* like it */ @@ -140,6 +146,31 @@ struct drm_virtgpu_get_caps { __u32 pad; }; +struct drm_virtgpu_resource_create_blob { +#define VIRTGPU_BLOB_MEM_GUEST 0x0001 +#define VIRTGPU_BLOB_MEM_HOST3D 0x0002 +#define VIRTGPU_BLOB_MEM_HOST3D_GUEST 0x0003 + +#define VIRTGPU_BLOB_FLAG_USE_MAPPABLE 0x0001 +#define VIRTGPU_BLOB_FLAG_USE_SHAREABLE 0x0002 +#define VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE 0x0004 + /* zero is invalid blob_mem */ + __u32 blob_mem; + __u32 blob_flags; + __u32 bo_handle; + __u32 res_handle; + __u64 size; + + /* + * for 3D contexts with VIRTGPU_BLOB_MEM_HOST3D_GUEST and + * VIRTGPU_BLOB_MEM_HOST3D otherwise, must be zero. + */ + __u32 pad; + __u32 cmd_size; + __u64 cmd; + __u64 blob_id; +}; + #define DRM_IOCTL_VIRTGPU_MAP \ DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_MAP, struct drm_virtgpu_map) @@ -175,6 +206,10 @@ struct drm_virtgpu_get_caps { DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_GET_CAPS, \ struct drm_virtgpu_get_caps) +#define DRM_IOCTL_VIRTGPU_RESOURCE_CREATE_BLOB \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_RESOURCE_CREATE_BLOB, \ + struct drm_virtgpu_resource_create_blob) + #if defined(__cplusplus) } #endif From 7a571c76ddce5928f872cdfd707ba5c7193e088c Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Wed, 23 Sep 2020 17:32:01 -0700 Subject: [PATCH 088/235] drm/virtgpu api: host visible feature This exposes the host visible feature to userspace. Without it, it is an error to specify BLOB_MEM_HOST3D with BLOG_FLAG_USE_MAPPABLE. Signed-off-by: Gurchetan Singh Acked-by: Tomeu Vizoso Acked-by: Lingfeng Yang Link: http://patchwork.freedesktop.org/patch/msgid/20200924003214.662-6-gurchetansingh@chromium.org Signed-off-by: Gerd Hoffmann --- include/uapi/drm/virtgpu_drm.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uapi/drm/virtgpu_drm.h b/include/uapi/drm/virtgpu_drm.h index bb224f604c9e..e1b1518f9acc 100644 --- a/include/uapi/drm/virtgpu_drm.h +++ b/include/uapi/drm/virtgpu_drm.h @@ -73,6 +73,7 @@ struct drm_virtgpu_execbuffer { #define VIRTGPU_PARAM_3D_FEATURES 1 /* do we have 3D features in the hw */ #define VIRTGPU_PARAM_CAPSET_QUERY_FIX 2 /* do we have the capset fix */ #define VIRTGPU_PARAM_RESOURCE_BLOB 3 /* DRM_VIRTGPU_RESOURCE_CREATE_BLOB */ +#define VIRTGPU_PARAM_HOST_VISIBLE 4 /* Host blob resources are mappable */ struct drm_virtgpu_getparam { __u64 param; From bf36dea17623b65cfbbe6219bfea1326255a89b6 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Wed, 23 Sep 2020 17:32:02 -0700 Subject: [PATCH 089/235] drm/virtgpu api: cross-device feature This feature was recently added to virtio-gpu, lets make it userspace queryable. It's an error to use BLOB_FLAG_USE_CROSS_DEVICE when this feature is not present. Signed-off-by: Gurchetan Singh Acked-by: Tomeu Vizoso Link: http://patchwork.freedesktop.org/patch/msgid/20200924003214.662-7-gurchetansingh@chromium.org Signed-off-by: Gerd Hoffmann --- include/uapi/drm/virtgpu_drm.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uapi/drm/virtgpu_drm.h b/include/uapi/drm/virtgpu_drm.h index e1b1518f9acc..b9ec26e9c646 100644 --- a/include/uapi/drm/virtgpu_drm.h +++ b/include/uapi/drm/virtgpu_drm.h @@ -74,6 +74,7 @@ struct drm_virtgpu_execbuffer { #define VIRTGPU_PARAM_CAPSET_QUERY_FIX 2 /* do we have the capset fix */ #define VIRTGPU_PARAM_RESOURCE_BLOB 3 /* DRM_VIRTGPU_RESOURCE_CREATE_BLOB */ #define VIRTGPU_PARAM_HOST_VISIBLE 4 /* Host blob resources are mappable */ +#define VIRTGPU_PARAM_CROSS_DEVICE 5 /* Cross virtio-device resource sharing */ struct drm_virtgpu_getparam { __u64 param; From 6815cfe602d03df1b3029081e1c4fb81a224d9fb Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 23 Sep 2020 17:32:03 -0700 Subject: [PATCH 090/235] drm/virtio: implement blob resources: probe for the feature. Let's proble for VIRTIO_GPU_F_RESOURCE_BLOB. Signed-off-by: Gerd Hoffmann Signed-off-by: Gurchetan Singh Acked-by: Tomeu Vizoso Link: http://patchwork.freedesktop.org/patch/msgid/20200924003214.662-8-gurchetansingh@chromium.org --- drivers/gpu/drm/virtio/virtgpu_debugfs.c | 1 + drivers/gpu/drm/virtio/virtgpu_drv.c | 1 + drivers/gpu/drm/virtio/virtgpu_drv.h | 1 + drivers/gpu/drm/virtio/virtgpu_kms.c | 10 +++++++--- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_debugfs.c b/drivers/gpu/drm/virtio/virtgpu_debugfs.c index d5b0c543bd6d..6b9b8376613f 100644 --- a/drivers/gpu/drm/virtio/virtgpu_debugfs.c +++ b/drivers/gpu/drm/virtio/virtgpu_debugfs.c @@ -49,6 +49,7 @@ static int virtio_gpu_features(struct seq_file *m, void *data) virtio_add_bool(m, "edid", vgdev->has_edid); virtio_add_bool(m, "indirect", vgdev->has_indirect); virtio_add_bool(m, "resource uuid", vgdev->has_resource_assign_uuid); + virtio_add_bool(m, "blob resources", vgdev->has_resource_blob); virtio_add_int(m, "cap sets", vgdev->num_capsets); virtio_add_int(m, "scanouts", vgdev->num_scanouts); return 0; diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index 1f8d6ed11d21..86330f1ade72 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -166,6 +166,7 @@ static unsigned int features[] = { #endif VIRTIO_GPU_F_EDID, VIRTIO_GPU_F_RESOURCE_UUID, + VIRTIO_GPU_F_RESOURCE_BLOB, }; static struct virtio_driver virtio_gpu_driver = { .feature_table = features, diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 272abe177ded..b53478a6a3c0 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -208,6 +208,7 @@ struct virtio_gpu_device { bool has_edid; bool has_indirect; bool has_resource_assign_uuid; + bool has_resource_blob; struct work_struct config_changed_work; diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index eed57a931309..0678e56100da 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -152,10 +152,14 @@ int virtio_gpu_init(struct drm_device *dev) if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_RESOURCE_UUID)) { vgdev->has_resource_assign_uuid = true; } + if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_RESOURCE_BLOB)) { + vgdev->has_resource_blob = true; + } - DRM_INFO("features: %cvirgl %cedid\n", - vgdev->has_virgl_3d ? '+' : '-', - vgdev->has_edid ? '+' : '-'); + DRM_INFO("features: %cvirgl %cedid %cresource_blob\n", + vgdev->has_virgl_3d ? '+' : '-', + vgdev->has_edid ? '+' : '-', + vgdev->has_resource_blob ? '+' : '-'); ret = virtio_find_vqs(vgdev->vdev, 2, vqs, callbacks, names, NULL); if (ret) { From 6076a9711dc535f1deca8014949beb7fcae8de34 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 23 Sep 2020 17:32:04 -0700 Subject: [PATCH 091/235] drm/virtio: implement blob resources: probe for host visible region The availability of the host visible region means host 3D allocations can be directly mapped in the guest. Signed-off-by: Gerd Hoffmann Acked-by: Tomeu Vizoso Link: http://patchwork.freedesktop.org/patch/msgid/20200924003214.662-9-gurchetansingh@chromium.org Co-developed-by: Gurchetan Singh Signed-off-by: Gurchetan Singh --- drivers/gpu/drm/virtio/virtgpu_debugfs.c | 5 +++++ drivers/gpu/drm/virtio/virtgpu_drv.h | 2 ++ drivers/gpu/drm/virtio/virtgpu_kms.c | 20 ++++++++++++++++++-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_debugfs.c b/drivers/gpu/drm/virtio/virtgpu_debugfs.c index 6b9b8376613f..a2cdd267914a 100644 --- a/drivers/gpu/drm/virtio/virtgpu_debugfs.c +++ b/drivers/gpu/drm/virtio/virtgpu_debugfs.c @@ -52,6 +52,11 @@ static int virtio_gpu_features(struct seq_file *m, void *data) virtio_add_bool(m, "blob resources", vgdev->has_resource_blob); virtio_add_int(m, "cap sets", vgdev->num_capsets); virtio_add_int(m, "scanouts", vgdev->num_scanouts); + if (vgdev->host_visible_region.len) { + seq_printf(m, "%-16s : 0x%lx +0x%lx\n", "host visible region", + (unsigned long)vgdev->host_visible_region.addr, + (unsigned long)vgdev->host_visible_region.len); + } return 0; } diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index b53478a6a3c0..391637f0b362 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -209,6 +209,8 @@ struct virtio_gpu_device { bool has_indirect; bool has_resource_assign_uuid; bool has_resource_blob; + bool has_host_visible; + struct virtio_shm_region host_visible_region; struct work_struct config_changed_work; diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index 0678e56100da..e17d3f5a0b54 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -155,11 +155,27 @@ int virtio_gpu_init(struct drm_device *dev) if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_RESOURCE_BLOB)) { vgdev->has_resource_blob = true; } + if (virtio_get_shm_region(vgdev->vdev, &vgdev->host_visible_region, + VIRTIO_GPU_SHM_ID_HOST_VISIBLE)) { + if (!devm_request_mem_region(&vgdev->vdev->dev, + vgdev->host_visible_region.addr, + vgdev->host_visible_region.len, + dev_name(&vgdev->vdev->dev))) { + DRM_ERROR("Could not reserve host visible region\n"); + goto err_vqs; + } - DRM_INFO("features: %cvirgl %cedid %cresource_blob\n", + DRM_INFO("Host memory window: 0x%lx +0x%lx\n", + (unsigned long)vgdev->host_visible_region.addr, + (unsigned long)vgdev->host_visible_region.len); + vgdev->has_host_visible = true; + } + + DRM_INFO("features: %cvirgl %cedid %cresource_blob %chost_visible\n", vgdev->has_virgl_3d ? '+' : '-', vgdev->has_edid ? '+' : '-', - vgdev->has_resource_blob ? '+' : '-'); + vgdev->has_resource_blob ? '+' : '-', + vgdev->has_host_visible ? '+' : '-'); ret = virtio_find_vqs(vgdev->vdev, 2, vqs, callbacks, names, NULL); if (ret) { From f895c70713721da661588b3004424974d6125fe8 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Wed, 23 Sep 2020 17:32:05 -0700 Subject: [PATCH 092/235] drm/virtio: implement blob resources: expose virtio_gpu_resource_id_get VRAM object will need it. Signed-off-by: Gurchetan Singh Acked-by: Tomeu Vizoso Link: http://patchwork.freedesktop.org/patch/msgid/20200924003214.662-10-gurchetansingh@chromium.org Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_drv.h | 2 ++ drivers/gpu/drm/virtio/virtgpu_object.c | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 391637f0b362..674a525df9bc 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -384,6 +384,8 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, bool virtio_gpu_is_shmem(struct virtio_gpu_object *bo); +int virtio_gpu_resource_id_get(struct virtio_gpu_device *vgdev, + uint32_t *resid); /* virtgpu_prime.c */ struct dma_buf *virtgpu_gem_prime_export(struct drm_gem_object *obj, int flags); diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index 74cfe47ad46b..e397060c1adc 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -31,8 +31,7 @@ static int virtio_gpu_virglrenderer_workaround = 1; module_param_named(virglhack, virtio_gpu_virglrenderer_workaround, int, 0400); -static int virtio_gpu_resource_id_get(struct virtio_gpu_device *vgdev, - uint32_t *resid) +int virtio_gpu_resource_id_get(struct virtio_gpu_device *vgdev, uint32_t *resid) { if (virtio_gpu_virglrenderer_workaround) { /* From 5c824604e5601a7150e434931243ee9e820fb473 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Wed, 23 Sep 2020 17:32:06 -0700 Subject: [PATCH 093/235] drm/virtio: implement blob resources: add new fields to internal structs Useful for upcoming blob resources. Signed-off-by: Gurchetan Singh Acked-by: Tomeu Vizoso Link: http://patchwork.freedesktop.org/patch/msgid/20200924003214.662-11-gurchetansingh@chromium.org Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_drv.h | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 674a525df9bc..bddf06b8fb68 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -54,13 +54,16 @@ #define STATE_ERR 2 struct virtio_gpu_object_params { - uint32_t format; - uint32_t width; - uint32_t height; unsigned long size; bool dumb; /* 3d */ bool virgl; + bool blob; + + /* classic resources only */ + uint32_t format; + uint32_t width; + uint32_t height; uint32_t target; uint32_t bind; uint32_t depth; @@ -68,6 +71,12 @@ struct virtio_gpu_object_params { uint32_t last_level; uint32_t nr_samples; uint32_t flags; + + /* blob resources only */ + uint32_t ctx_id; + uint32_t blob_mem; + uint32_t blob_flags; + uint64_t blob_id; }; struct virtio_gpu_object { @@ -75,6 +84,8 @@ struct virtio_gpu_object { uint32_t hw_res_handle; bool dumb; bool created; + bool host3d_blob, guest_blob; + uint32_t blob_mem, blob_flags; int uuid_state; uuid_t uuid; From 16845c5d540929d2f4dc845f11fbbb238e69170a Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 23 Sep 2020 17:32:07 -0700 Subject: [PATCH 094/235] drm/virtio: implement blob resources: implement vram object A virtio-gpu vram object is based on range-based allocation. No guest shmemfs backing, so we call drm_gem_private_object_init. This is for host memory without any guest backing (atleast initially). Signed-off-by: Gerd Hoffmann Acked-by: Tomeu Vizoso Link: http://patchwork.freedesktop.org/patch/msgid/20200924003214.662-12-gurchetansingh@chromium.org Co-developed-by: Gurchetan Singh Signed-off-by: Gurchetan Singh --- drivers/gpu/drm/virtio/Makefile | 2 +- drivers/gpu/drm/virtio/virtgpu_debugfs.c | 20 ++- drivers/gpu/drm/virtio/virtgpu_drv.h | 26 +++- drivers/gpu/drm/virtio/virtgpu_kms.c | 8 ++ drivers/gpu/drm/virtio/virtgpu_object.c | 12 ++ drivers/gpu/drm/virtio/virtgpu_vq.c | 66 +++++++++ drivers/gpu/drm/virtio/virtgpu_vram.c | 162 +++++++++++++++++++++++ 7 files changed, 293 insertions(+), 3 deletions(-) create mode 100644 drivers/gpu/drm/virtio/virtgpu_vram.c diff --git a/drivers/gpu/drm/virtio/Makefile b/drivers/gpu/drm/virtio/Makefile index 92aa2b3d349d..b99fa4a73b68 100644 --- a/drivers/gpu/drm/virtio/Makefile +++ b/drivers/gpu/drm/virtio/Makefile @@ -3,7 +3,7 @@ # Makefile for the drm device driver. This driver provides support for the # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. -virtio-gpu-y := virtgpu_drv.o virtgpu_kms.o virtgpu_gem.o \ +virtio-gpu-y := virtgpu_drv.o virtgpu_kms.o virtgpu_gem.o virtgpu_vram.o \ virtgpu_display.o virtgpu_vq.o \ virtgpu_fence.o virtgpu_object.o virtgpu_debugfs.o virtgpu_plane.o \ virtgpu_ioctl.o virtgpu_prime.o virtgpu_trace_points.o diff --git a/drivers/gpu/drm/virtio/virtgpu_debugfs.c b/drivers/gpu/drm/virtio/virtgpu_debugfs.c index a2cdd267914a..f336a8fa6666 100644 --- a/drivers/gpu/drm/virtio/virtgpu_debugfs.c +++ b/drivers/gpu/drm/virtio/virtgpu_debugfs.c @@ -42,7 +42,7 @@ static void virtio_add_int(struct seq_file *m, const char *name, static int virtio_gpu_features(struct seq_file *m, void *data) { - struct drm_info_node *node = (struct drm_info_node *) m->private; + struct drm_info_node *node = (struct drm_info_node *)m->private; struct virtio_gpu_device *vgdev = node->minor->dev->dev_private; virtio_add_bool(m, "virgl", vgdev->has_virgl_3d); @@ -72,9 +72,27 @@ virtio_gpu_debugfs_irq_info(struct seq_file *m, void *data) return 0; } +static int +virtio_gpu_debugfs_host_visible_mm(struct seq_file *m, void *data) +{ + struct drm_info_node *node = (struct drm_info_node *)m->private; + struct virtio_gpu_device *vgdev = node->minor->dev->dev_private; + struct drm_printer p; + + if (!vgdev->has_host_visible) { + seq_puts(m, "Host allocations not visible to guest\n"); + return 0; + } + + p = drm_seq_file_printer(m); + drm_mm_print(&vgdev->host_visible_mm, &p); + return 0; +} + static struct drm_info_list virtio_gpu_debugfs_list[] = { { "virtio-gpu-features", virtio_gpu_features }, { "virtio-gpu-irq-fence", virtio_gpu_debugfs_irq_info, 0, NULL }, + { "virtio-gpu-host-visible-mm", virtio_gpu_debugfs_host_visible_mm }, }; #define VIRTIO_GPU_DEBUGFS_ENTRIES ARRAY_SIZE(virtio_gpu_debugfs_list) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index bddf06b8fb68..7c9cf6960a92 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -99,9 +99,19 @@ struct virtio_gpu_object_shmem { uint32_t mapped; }; +struct virtio_gpu_object_vram { + struct virtio_gpu_object base; + uint32_t map_state; + uint32_t map_info; + struct drm_mm_node vram_node; +}; + #define to_virtio_gpu_shmem(virtio_gpu_object) \ container_of((virtio_gpu_object), struct virtio_gpu_object_shmem, base) +#define to_virtio_gpu_vram(virtio_gpu_object) \ + container_of((virtio_gpu_object), struct virtio_gpu_object_vram, base) + struct virtio_gpu_object_array { struct ww_acquire_ctx ticket; struct list_head next; @@ -222,6 +232,7 @@ struct virtio_gpu_device { bool has_resource_blob; bool has_host_visible; struct virtio_shm_region host_visible_region; + struct drm_mm host_visible_mm; struct work_struct config_changed_work; @@ -233,8 +244,10 @@ struct virtio_gpu_device { uint32_t num_capsets; struct list_head cap_cache; - /* protects resource state when exporting */ + /* protects uuid state when exporting */ spinlock_t resource_export_lock; + /* protects map state and host_visible_mm */ + spinlock_t host_visible_lock; }; struct virtio_gpu_fpriv { @@ -365,6 +378,12 @@ int virtio_gpu_cmd_resource_assign_uuid(struct virtio_gpu_device *vgdev, struct virtio_gpu_object_array *objs); +int virtio_gpu_cmd_map(struct virtio_gpu_device *vgdev, + struct virtio_gpu_object_array *objs, uint64_t offset); + +void virtio_gpu_cmd_unmap(struct virtio_gpu_device *vgdev, + struct virtio_gpu_object *bo); + /* virtgpu_display.c */ int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev); void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev); @@ -411,4 +430,9 @@ struct drm_gem_object *virtgpu_gem_prime_import_sg_table( /* virtgpu_debugfs.c */ void virtio_gpu_debugfs_init(struct drm_minor *minor); +/* virtgpu_vram.c */ +bool virtio_gpu_is_vram(struct virtio_gpu_object *bo); +int virtio_gpu_vram_create(struct virtio_gpu_device *vgdev, + struct virtio_gpu_object_params *params, + struct virtio_gpu_object **bo_ptr); #endif diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index e17d3f5a0b54..b4ec479c32cd 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -121,6 +121,7 @@ int virtio_gpu_init(struct drm_device *dev) spin_lock_init(&vgdev->display_info_lock); spin_lock_init(&vgdev->resource_export_lock); + spin_lock_init(&vgdev->host_visible_lock); ida_init(&vgdev->ctx_id_ida); ida_init(&vgdev->resource_ida); init_waitqueue_head(&vgdev->resp_wq); @@ -169,6 +170,9 @@ int virtio_gpu_init(struct drm_device *dev) (unsigned long)vgdev->host_visible_region.addr, (unsigned long)vgdev->host_visible_region.len); vgdev->has_host_visible = true; + drm_mm_init(&vgdev->host_visible_mm, + (unsigned long)vgdev->host_visible_region.addr, + (unsigned long)vgdev->host_visible_region.len); } DRM_INFO("features: %cvirgl %cedid %cresource_blob %chost_visible\n", @@ -262,6 +266,10 @@ void virtio_gpu_release(struct drm_device *dev) virtio_gpu_modeset_fini(vgdev); virtio_gpu_free_vbufs(vgdev); virtio_gpu_cleanup_cap_cache(vgdev); + + if (vgdev->has_host_visible) + drm_mm_takedown(&vgdev->host_visible_mm); + kfree(vgdev->capsets); kfree(vgdev); } diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index e397060c1adc..6b05a31682ae 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -84,6 +84,18 @@ void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo) } drm_gem_shmem_free_object(&bo->base.base); + } else if (virtio_gpu_is_vram(bo)) { + struct virtio_gpu_object_vram *vram = to_virtio_gpu_vram(bo); + + spin_lock(&vgdev->host_visible_lock); + if (drm_mm_node_allocated(&vram->vram_node)) + drm_mm_remove_node(&vram->vram_node); + + spin_unlock(&vgdev->host_visible_lock); + + drm_gem_free_mmap_offset(&vram->base.base.base); + drm_gem_object_release(&vram->base.base.base); + kfree(vram); } } diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 55529ed97d9c..41fd253d357e 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -1171,3 +1171,69 @@ virtio_gpu_cmd_resource_assign_uuid(struct virtio_gpu_device *vgdev, virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); return 0; } + +static void virtio_gpu_cmd_resource_map_cb(struct virtio_gpu_device *vgdev, + struct virtio_gpu_vbuffer *vbuf) +{ + struct virtio_gpu_object *bo = + gem_to_virtio_gpu_obj(vbuf->objs->objs[0]); + struct virtio_gpu_resp_map_info *resp = + (struct virtio_gpu_resp_map_info *)vbuf->resp_buf; + struct virtio_gpu_object_vram *vram = to_virtio_gpu_vram(bo); + uint32_t resp_type = le32_to_cpu(resp->hdr.type); + + spin_lock(&vgdev->host_visible_lock); + + if (resp_type == VIRTIO_GPU_RESP_OK_MAP_INFO) { + vram->map_info = resp->map_info; + vram->map_state = STATE_OK; + } else { + vram->map_state = STATE_ERR; + } + + spin_unlock(&vgdev->host_visible_lock); + wake_up_all(&vgdev->resp_wq); +} + +int virtio_gpu_cmd_map(struct virtio_gpu_device *vgdev, + struct virtio_gpu_object_array *objs, uint64_t offset) +{ + struct virtio_gpu_resource_map_blob *cmd_p; + struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(objs->objs[0]); + struct virtio_gpu_vbuffer *vbuf; + struct virtio_gpu_resp_map_info *resp_buf; + + resp_buf = kzalloc(sizeof(*resp_buf), GFP_KERNEL); + if (!resp_buf) { + virtio_gpu_array_put_free(objs); + return -ENOMEM; + } + + cmd_p = virtio_gpu_alloc_cmd_resp + (vgdev, virtio_gpu_cmd_resource_map_cb, &vbuf, sizeof(*cmd_p), + sizeof(struct virtio_gpu_resp_map_info), resp_buf); + memset(cmd_p, 0, sizeof(*cmd_p)); + + cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_MAP_BLOB); + cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle); + cmd_p->offset = cpu_to_le64(offset); + vbuf->objs = objs; + + virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); + return 0; +} + +void virtio_gpu_cmd_unmap(struct virtio_gpu_device *vgdev, + struct virtio_gpu_object *bo) +{ + struct virtio_gpu_resource_unmap_blob *cmd_p; + struct virtio_gpu_vbuffer *vbuf; + + cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p)); + memset(cmd_p, 0, sizeof(*cmd_p)); + + cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_UNMAP_BLOB); + cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle); + + virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); +} diff --git a/drivers/gpu/drm/virtio/virtgpu_vram.c b/drivers/gpu/drm/virtio/virtgpu_vram.c new file mode 100644 index 000000000000..087945fcd230 --- /dev/null +++ b/drivers/gpu/drm/virtio/virtgpu_vram.c @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "virtgpu_drv.h" + +static void virtio_gpu_vram_free(struct drm_gem_object *obj) +{ + struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj); + struct virtio_gpu_device *vgdev = obj->dev->dev_private; + struct virtio_gpu_object_vram *vram = to_virtio_gpu_vram(bo); + bool unmap; + + if (bo->created) { + spin_lock(&vgdev->host_visible_lock); + unmap = drm_mm_node_allocated(&vram->vram_node); + spin_unlock(&vgdev->host_visible_lock); + + if (unmap) + virtio_gpu_cmd_unmap(vgdev, bo); + + virtio_gpu_cmd_unref_resource(vgdev, bo); + virtio_gpu_notify(vgdev); + return; + } +} + +static const struct vm_operations_struct virtio_gpu_vram_vm_ops = { + .open = drm_gem_vm_open, + .close = drm_gem_vm_close, +}; + +static int virtio_gpu_vram_mmap(struct drm_gem_object *obj, + struct vm_area_struct *vma) +{ + int ret; + struct virtio_gpu_device *vgdev = obj->dev->dev_private; + struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj); + struct virtio_gpu_object_vram *vram = to_virtio_gpu_vram(bo); + unsigned long vm_size = vma->vm_end - vma->vm_start; + + if (!(bo->blob_flags & VIRTGPU_BLOB_FLAG_USE_MAPPABLE)) + return -EINVAL; + + wait_event(vgdev->resp_wq, vram->map_state != STATE_INITIALIZING); + if (vram->map_state != STATE_OK) + return -EINVAL; + + vma->vm_pgoff -= drm_vma_node_start(&obj->vma_node); + vma->vm_flags |= VM_MIXEDMAP | VM_DONTEXPAND; + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); + vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); + vma->vm_ops = &virtio_gpu_vram_vm_ops; + + if (vram->map_info == VIRTIO_GPU_MAP_CACHE_WC) + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + else if (vram->map_info == VIRTIO_GPU_MAP_CACHE_UNCACHED) + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + /* Partial mappings of GEM buffers don't happen much in practice. */ + if (vm_size != vram->vram_node.size) + return -EINVAL; + + ret = io_remap_pfn_range(vma, vma->vm_start, + vram->vram_node.start >> PAGE_SHIFT, + vm_size, vma->vm_page_prot); + return ret; +} + +static const struct drm_gem_object_funcs virtio_gpu_vram_funcs = { + .open = virtio_gpu_gem_object_open, + .close = virtio_gpu_gem_object_close, + .free = virtio_gpu_vram_free, + .mmap = virtio_gpu_vram_mmap, +}; + +bool virtio_gpu_is_vram(struct virtio_gpu_object *bo) +{ + return bo->base.base.funcs == &virtio_gpu_vram_funcs; +} + +static int virtio_gpu_vram_map(struct virtio_gpu_object *bo) +{ + int ret; + uint64_t offset; + struct virtio_gpu_object_array *objs; + struct virtio_gpu_device *vgdev = bo->base.base.dev->dev_private; + struct virtio_gpu_object_vram *vram = to_virtio_gpu_vram(bo); + + if (!vgdev->has_host_visible) + return -EINVAL; + + spin_lock(&vgdev->host_visible_lock); + ret = drm_mm_insert_node(&vgdev->host_visible_mm, &vram->vram_node, + bo->base.base.size); + spin_unlock(&vgdev->host_visible_lock); + + if (ret) + return ret; + + objs = virtio_gpu_array_alloc(1); + if (!objs) { + ret = -ENOMEM; + goto err_remove_node; + } + + virtio_gpu_array_add_obj(objs, &bo->base.base); + /*TODO: Add an error checking helper function in drm_mm.h */ + offset = vram->vram_node.start - vgdev->host_visible_region.addr; + + ret = virtio_gpu_cmd_map(vgdev, objs, offset); + if (ret) { + virtio_gpu_array_put_free(objs); + goto err_remove_node; + } + + return 0; + +err_remove_node: + spin_lock(&vgdev->host_visible_lock); + drm_mm_remove_node(&vram->vram_node); + spin_unlock(&vgdev->host_visible_lock); + return ret; +} + +int virtio_gpu_vram_create(struct virtio_gpu_device *vgdev, + struct virtio_gpu_object_params *params, + struct virtio_gpu_object **bo_ptr) +{ + struct drm_gem_object *obj; + struct virtio_gpu_object_vram *vram; + int ret; + + vram = kzalloc(sizeof(*vram), GFP_KERNEL); + if (!vram) + return -ENOMEM; + + obj = &vram->base.base.base; + obj->funcs = &virtio_gpu_vram_funcs; + drm_gem_private_object_init(vgdev->ddev, obj, params->size); + + /* Create fake offset */ + ret = drm_gem_create_mmap_offset(obj); + if (ret) { + kfree(vram); + return ret; + } + + ret = virtio_gpu_resource_id_get(vgdev, &vram->base.hw_res_handle); + if (ret) { + kfree(vram); + return ret; + } + + if (params->blob_flags & VIRTGPU_BLOB_FLAG_USE_MAPPABLE) { + ret = virtio_gpu_vram_map(&vram->base); + if (ret) { + virtio_gpu_vram_free(obj); + return ret; + } + } + + *bo_ptr = &vram->base; + return 0; +} From c7a6ac4f60bc54a0a45de76a3a258685024c9293 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Wed, 23 Sep 2020 17:32:08 -0700 Subject: [PATCH 095/235] drm/virtio: implement blob resources: hypercall interface This implements the blob hypercall interface. Signed-off-by: Gurchetan Singh Acked-by: Tomeu Vizoso Link: http://patchwork.freedesktop.org/patch/msgid/20200924003214.662-13-gurchetansingh@chromium.org Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_drv.h | 15 +++++++ drivers/gpu/drm/virtio/virtgpu_vq.c | 65 ++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 7c9cf6960a92..e1143a00017c 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -384,6 +385,20 @@ int virtio_gpu_cmd_map(struct virtio_gpu_device *vgdev, void virtio_gpu_cmd_unmap(struct virtio_gpu_device *vgdev, struct virtio_gpu_object *bo); +void +virtio_gpu_cmd_resource_create_blob(struct virtio_gpu_device *vgdev, + struct virtio_gpu_object *bo, + struct virtio_gpu_object_params *params, + struct virtio_gpu_mem_entry *ents, + uint32_t nents); +void +virtio_gpu_cmd_set_scanout_blob(struct virtio_gpu_device *vgdev, + uint32_t scanout_id, + struct virtio_gpu_object *bo, + struct drm_framebuffer *fb, + uint32_t width, uint32_t height, + uint32_t x, uint32_t y); + /* virtgpu_display.c */ int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev); void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev); diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 41fd253d357e..e71c8eec0b91 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -1237,3 +1237,68 @@ void virtio_gpu_cmd_unmap(struct virtio_gpu_device *vgdev, virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); } + +void +virtio_gpu_cmd_resource_create_blob(struct virtio_gpu_device *vgdev, + struct virtio_gpu_object *bo, + struct virtio_gpu_object_params *params, + struct virtio_gpu_mem_entry *ents, + uint32_t nents) +{ + struct virtio_gpu_resource_create_blob *cmd_p; + struct virtio_gpu_vbuffer *vbuf; + + cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p)); + memset(cmd_p, 0, sizeof(*cmd_p)); + + cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_CREATE_BLOB); + cmd_p->hdr.ctx_id = cpu_to_le32(params->ctx_id); + cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle); + cmd_p->blob_mem = cpu_to_le32(params->blob_mem); + cmd_p->blob_flags = cpu_to_le32(params->blob_flags); + cmd_p->blob_id = cpu_to_le64(params->blob_id); + cmd_p->size = cpu_to_le64(params->size); + cmd_p->nr_entries = cpu_to_le32(nents); + + vbuf->data_buf = ents; + vbuf->data_size = sizeof(*ents) * nents; + + virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); + bo->created = true; +} + +void virtio_gpu_cmd_set_scanout_blob(struct virtio_gpu_device *vgdev, + uint32_t scanout_id, + struct virtio_gpu_object *bo, + struct drm_framebuffer *fb, + uint32_t width, uint32_t height, + uint32_t x, uint32_t y) +{ + uint32_t i; + struct virtio_gpu_set_scanout_blob *cmd_p; + struct virtio_gpu_vbuffer *vbuf; + uint32_t format = virtio_gpu_translate_format(fb->format->format); + + cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p)); + memset(cmd_p, 0, sizeof(*cmd_p)); + + cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_SET_SCANOUT_BLOB); + cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle); + cmd_p->scanout_id = cpu_to_le32(scanout_id); + + cmd_p->format = cpu_to_le32(format); + cmd_p->width = cpu_to_le32(fb->width); + cmd_p->height = cpu_to_le32(fb->height); + + for (i = 0; i < 4; i++) { + cmd_p->strides[i] = cpu_to_le32(fb->pitches[i]); + cmd_p->offsets[i] = cpu_to_le32(fb->offsets[i]); + } + + cmd_p->r.width = cpu_to_le32(width); + cmd_p->r.height = cpu_to_le32(height); + cmd_p->r.x = cpu_to_le32(x); + cmd_p->r.y = cpu_to_le32(y); + + virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); +} From 0b0f1afe6cff06cf51a1435aa0089ce335df00b5 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Wed, 23 Sep 2020 17:32:09 -0700 Subject: [PATCH 096/235] drm/virtio: implement blob resources: blob display integration SCANOUT_BLOB forwards the DRM framebuffer metadata to the host. The modifier is intentionally left out -- it may be possible to query the host for that. We also assume one blob resource per DRM framebuffer. That too is an intentional simplification. Signed-off-by: Gurchetan Singh Acked-by: Tomeu Vizoso Link: http://patchwork.freedesktop.org/patch/msgid/20200924003214.662-14-gurchetansingh@chromium.org Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_plane.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index 6a311cd93440..42ac08ed1442 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -174,12 +174,23 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane, plane->state->src_h >> 16, plane->state->src_x >> 16, plane->state->src_y >> 16); - virtio_gpu_cmd_set_scanout(vgdev, output->index, - bo->hw_res_handle, - plane->state->src_w >> 16, - plane->state->src_h >> 16, - plane->state->src_x >> 16, - plane->state->src_y >> 16); + + if (bo->host3d_blob || bo->guest_blob) { + virtio_gpu_cmd_set_scanout_blob + (vgdev, output->index, bo, + plane->state->fb, + plane->state->src_w >> 16, + plane->state->src_h >> 16, + plane->state->src_x >> 16, + plane->state->src_y >> 16); + } else { + virtio_gpu_cmd_set_scanout(vgdev, output->index, + bo->hw_res_handle, + plane->state->src_w >> 16, + plane->state->src_h >> 16, + plane->state->src_x >> 16, + plane->state->src_y >> 16); + } } virtio_gpu_cmd_resource_flush(vgdev, bo->hw_res_handle, From 1e2554f49e41d3f6509c6a633e5e4dd48d93ffb9 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Wed, 23 Sep 2020 17:32:10 -0700 Subject: [PATCH 097/235] drm/virtio: implement blob resources: refactor UUID code somewhat For upcoming blob resources, userspace can specify that the resource will be used for cross-device sharing. This is mainly for exportable blobs that will only shared with the virtgpu display but not across devices. Signed-off-by: Gurchetan Singh Acked-by: Tomeu Vizoso Link: http://patchwork.freedesktop.org/patch/msgid/20200924003214.662-15-gurchetansingh@chromium.org Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_drv.h | 2 ++ drivers/gpu/drm/virtio/virtgpu_prime.c | 40 ++++++++++++++++++-------- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index e1143a00017c..bbbe28f8b943 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -432,6 +432,8 @@ bool virtio_gpu_is_shmem(struct virtio_gpu_object *bo); int virtio_gpu_resource_id_get(struct virtio_gpu_device *vgdev, uint32_t *resid); /* virtgpu_prime.c */ +int virtio_gpu_resource_assign_uuid(struct virtio_gpu_device *vgdev, + struct virtio_gpu_object *bo); struct dma_buf *virtgpu_gem_prime_export(struct drm_gem_object *obj, int flags); struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev, diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c index 3552db128ba3..1ef1e2f22633 100644 --- a/drivers/gpu/drm/virtio/virtgpu_prime.c +++ b/drivers/gpu/drm/virtio/virtgpu_prime.c @@ -59,6 +59,24 @@ const struct virtio_dma_buf_ops virtgpu_dmabuf_ops = { .get_uuid = virtgpu_virtio_get_uuid, }; +int virtio_gpu_resource_assign_uuid(struct virtio_gpu_device *vgdev, + struct virtio_gpu_object *bo) +{ + int ret; + struct virtio_gpu_object_array *objs; + + objs = virtio_gpu_array_alloc(1); + if (!objs) + return -ENOMEM; + + virtio_gpu_array_add_obj(objs, &bo->base.base); + ret = virtio_gpu_cmd_resource_assign_uuid(vgdev, objs); + if (ret) + return ret; + + return 0; +} + struct dma_buf *virtgpu_gem_prime_export(struct drm_gem_object *obj, int flags) { @@ -66,22 +84,20 @@ struct dma_buf *virtgpu_gem_prime_export(struct drm_gem_object *obj, struct drm_device *dev = obj->dev; struct virtio_gpu_device *vgdev = dev->dev_private; struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj); - struct virtio_gpu_object_array *objs; int ret = 0; + bool blob = bo->host3d_blob || bo->guest_blob; DEFINE_DMA_BUF_EXPORT_INFO(exp_info); - if (vgdev->has_resource_assign_uuid) { - objs = virtio_gpu_array_alloc(1); - if (!objs) - return ERR_PTR(-ENOMEM); - virtio_gpu_array_add_obj(objs, &bo->base.base); + if (!blob) { + if (vgdev->has_resource_assign_uuid) { + ret = virtio_gpu_resource_assign_uuid(vgdev, bo); + if (ret) + return ERR_PTR(ret); - ret = virtio_gpu_cmd_resource_assign_uuid(vgdev, objs); - if (ret) - return ERR_PTR(ret); - virtio_gpu_notify(vgdev); - } else { - bo->uuid_state = STATE_ERR; + virtio_gpu_notify(vgdev); + } else { + bo->uuid_state = STATE_ERR; + } } exp_info.ops = &virtgpu_dmabuf_ops.ops; From 50c3d1938ee380e2d24714ea7058d2d3fc2662de Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Wed, 23 Sep 2020 17:32:11 -0700 Subject: [PATCH 098/235] drm/virtio: implement blob resources: fix stride discrepancy The old transfer ioctls may work on blob resources, and there is no TRANSFER_BLOB hypercall now for simplicity. The guest may have a image view on the blob resources such that the stride is not equal to width * bytes_per_pixel. For host-only blobs, we can repurpose the transfer ioctls to synchronize caches as well. For guest-only blobs, these operations are undefined for now so leave them out. Also, with seamless Wayland integration between guest/host looking increasingly attractive, it also makes sense to keep track of one value for stride. Signed-off-by: Gurchetan Singh Acked-by: Tomeu Vizoso Link: http://patchwork.freedesktop.org/patch/msgid/20200924003214.662-16-gurchetansingh@chromium.org Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_drv.h | 4 +++ drivers/gpu/drm/virtio/virtgpu_ioctl.c | 35 +++++++++++++++++++++++--- drivers/gpu/drm/virtio/virtgpu_vq.c | 14 +++++++++-- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index bbbe28f8b943..ad16cef9a39b 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -351,12 +351,16 @@ void virtio_gpu_cmd_submit(struct virtio_gpu_device *vgdev, void virtio_gpu_cmd_transfer_from_host_3d(struct virtio_gpu_device *vgdev, uint32_t ctx_id, uint64_t offset, uint32_t level, + uint32_t stride, + uint32_t layer_stride, struct drm_virtgpu_3d_box *box, struct virtio_gpu_object_array *objs, struct virtio_gpu_fence *fence); void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev, uint32_t ctx_id, uint64_t offset, uint32_t level, + uint32_t stride, + uint32_t layer_stride, struct drm_virtgpu_3d_box *box, struct virtio_gpu_object_array *objs, struct virtio_gpu_fence *fence); diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c index c8da7adc6b30..0bf789f2bfde 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -312,6 +312,7 @@ static int virtio_gpu_transfer_from_host_ioctl(struct drm_device *dev, struct virtio_gpu_device *vgdev = dev->dev_private; struct virtio_gpu_fpriv *vfpriv = file->driver_priv; struct drm_virtgpu_3d_transfer_from_host *args = data; + struct virtio_gpu_object *bo; struct virtio_gpu_object_array *objs; struct virtio_gpu_fence *fence; int ret; @@ -325,6 +326,17 @@ static int virtio_gpu_transfer_from_host_ioctl(struct drm_device *dev, if (objs == NULL) return -ENOENT; + bo = gem_to_virtio_gpu_obj(objs->objs[0]); + if (bo->guest_blob && !bo->host3d_blob) { + ret = -EINVAL; + goto err_put_free; + } + + if (!bo->host3d_blob && (args->stride || args->layer_stride)) { + ret = -EINVAL; + goto err_put_free; + } + ret = virtio_gpu_array_lock_resv(objs); if (ret != 0) goto err_put_free; @@ -334,9 +346,10 @@ static int virtio_gpu_transfer_from_host_ioctl(struct drm_device *dev, ret = -ENOMEM; goto err_unlock; } + virtio_gpu_cmd_transfer_from_host_3d - (vgdev, vfpriv->ctx_id, offset, args->level, - &args->box, objs, fence); + (vgdev, vfpriv->ctx_id, offset, args->level, args->stride, + args->layer_stride, &args->box, objs, fence); dma_fence_put(&fence->f); virtio_gpu_notify(vgdev); return 0; @@ -354,6 +367,7 @@ static int virtio_gpu_transfer_to_host_ioctl(struct drm_device *dev, void *data, struct virtio_gpu_device *vgdev = dev->dev_private; struct virtio_gpu_fpriv *vfpriv = file->driver_priv; struct drm_virtgpu_3d_transfer_to_host *args = data; + struct virtio_gpu_object *bo; struct virtio_gpu_object_array *objs; struct virtio_gpu_fence *fence; int ret; @@ -363,6 +377,12 @@ static int virtio_gpu_transfer_to_host_ioctl(struct drm_device *dev, void *data, if (objs == NULL) return -ENOENT; + bo = gem_to_virtio_gpu_obj(objs->objs[0]); + if (bo->guest_blob && !bo->host3d_blob) { + ret = -EINVAL; + goto err_put_free; + } + if (!vgdev->has_virgl_3d) { virtio_gpu_cmd_transfer_to_host_2d (vgdev, offset, @@ -370,6 +390,12 @@ static int virtio_gpu_transfer_to_host_ioctl(struct drm_device *dev, void *data, objs, NULL); } else { virtio_gpu_create_context(dev, file); + + if (!bo->host3d_blob && (args->stride || args->layer_stride)) { + ret = -EINVAL; + goto err_put_free; + } + ret = virtio_gpu_array_lock_resv(objs); if (ret != 0) goto err_put_free; @@ -381,8 +407,9 @@ static int virtio_gpu_transfer_to_host_ioctl(struct drm_device *dev, void *data, virtio_gpu_cmd_transfer_to_host_3d (vgdev, - vfpriv ? vfpriv->ctx_id : 0, offset, - args->level, &args->box, objs, fence); + vfpriv ? vfpriv->ctx_id : 0, offset, args->level, + args->stride, args->layer_stride, &args->box, objs, + fence); dma_fence_put(&fence->f); } virtio_gpu_notify(vgdev); diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index e71c8eec0b91..6434b9fb38a6 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -1017,6 +1017,8 @@ virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev, void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev, uint32_t ctx_id, uint64_t offset, uint32_t level, + uint32_t stride, + uint32_t layer_stride, struct drm_virtgpu_3d_box *box, struct virtio_gpu_object_array *objs, struct virtio_gpu_fence *fence) @@ -1025,12 +1027,14 @@ void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev, struct virtio_gpu_transfer_host_3d *cmd_p; struct virtio_gpu_vbuffer *vbuf; bool use_dma_api = !virtio_has_dma_quirk(vgdev->vdev); - struct virtio_gpu_object_shmem *shmem = to_virtio_gpu_shmem(bo); - if (use_dma_api) + if (virtio_gpu_is_shmem(bo) && use_dma_api) { + struct virtio_gpu_object_shmem *shmem = to_virtio_gpu_shmem(bo); + dma_sync_sg_for_device(vgdev->vdev->dev.parent, shmem->pages->sgl, shmem->pages->nents, DMA_TO_DEVICE); + } cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p)); memset(cmd_p, 0, sizeof(*cmd_p)); @@ -1043,6 +1047,8 @@ void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev, convert_to_hw_box(&cmd_p->box, box); cmd_p->offset = cpu_to_le64(offset); cmd_p->level = cpu_to_le32(level); + cmd_p->stride = cpu_to_le32(stride); + cmd_p->layer_stride = cpu_to_le32(layer_stride); virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence); } @@ -1050,6 +1056,8 @@ void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev, void virtio_gpu_cmd_transfer_from_host_3d(struct virtio_gpu_device *vgdev, uint32_t ctx_id, uint64_t offset, uint32_t level, + uint32_t stride, + uint32_t layer_stride, struct drm_virtgpu_3d_box *box, struct virtio_gpu_object_array *objs, struct virtio_gpu_fence *fence) @@ -1069,6 +1077,8 @@ void virtio_gpu_cmd_transfer_from_host_3d(struct virtio_gpu_device *vgdev, convert_to_hw_box(&cmd_p->box, box); cmd_p->offset = cpu_to_le64(offset); cmd_p->level = cpu_to_le32(level); + cmd_p->stride = cpu_to_le32(stride); + cmd_p->layer_stride = cpu_to_le32(layer_stride); virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence); } From 4429b5de01ad974219ca81a98f152c53c3d34f9b Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Wed, 23 Sep 2020 17:32:12 -0700 Subject: [PATCH 099/235] drm/virtio: implement blob resources: report blob mem to userspace The stride field has never been used, so repurpose it to be "blob_mem". This way, userspace can know the memory properties of the blob if it's passed between userspace processes and no suitable userspace API exists to transmit that knowledge. Signed-off-by: Gurchetan Singh Acked-by: Tomeu Vizoso Link: http://patchwork.freedesktop.org/patch/msgid/20200924003214.662-17-gurchetansingh@chromium.org Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_ioctl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c index 0bf789f2bfde..b0c9dd171ad8 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -301,6 +301,9 @@ static int virtio_gpu_resource_info_ioctl(struct drm_device *dev, void *data, ri->size = qobj->base.base.size; ri->res_handle = qobj->hw_res_handle; + if (qobj->host3d_blob || qobj->guest_blob) + ri->blob_mem = qobj->blob_mem; + drm_gem_object_put(gobj); return 0; } From 897b4d1acaf56314652c6a8e75d9f86b5e45638d Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 23 Sep 2020 17:32:13 -0700 Subject: [PATCH 100/235] drm/virtio: implement blob resources: resource create blob ioctl Implement resource create blob as specified. Signed-off-by: Gerd Hoffmann Acked-by: Tomeu Vizoso Link: http://patchwork.freedesktop.org/patch/msgid/20200924003214.662-18-gurchetansingh@chromium.org Co-developed-by: Gurchetan Singh Signed-off-by: Gurchetan Singh --- drivers/gpu/drm/virtio/virtgpu_drv.h | 4 +- drivers/gpu/drm/virtio/virtgpu_ioctl.c | 136 ++++++++++++++++++++++++ drivers/gpu/drm/virtio/virtgpu_object.c | 5 +- drivers/gpu/drm/virtio/virtgpu_vram.c | 2 + 4 files changed, 144 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index ad16cef9a39b..3c0e17212c33 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -257,8 +257,8 @@ struct virtio_gpu_fpriv { struct mutex context_lock; }; -/* virtgpu_ioctl.c */ -#define DRM_VIRTIO_NUM_IOCTLS 10 +/* virtio_ioctl.c */ +#define DRM_VIRTIO_NUM_IOCTLS 11 extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS]; void virtio_gpu_create_context(struct drm_device *dev, struct drm_file *file); diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c index b0c9dd171ad8..3ede098c1d28 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -34,6 +34,10 @@ #include "virtgpu_drv.h" +#define VIRTGPU_BLOB_FLAG_USE_MASK (VIRTGPU_BLOB_FLAG_USE_MAPPABLE | \ + VIRTGPU_BLOB_FLAG_USE_SHAREABLE | \ + VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE) + void virtio_gpu_create_context(struct drm_device *dev, struct drm_file *file) { struct virtio_gpu_device *vgdev = dev->dev_private; @@ -521,6 +525,134 @@ copy_exit: return 0; } +static int verify_blob(struct virtio_gpu_device *vgdev, + struct virtio_gpu_fpriv *vfpriv, + struct virtio_gpu_object_params *params, + struct drm_virtgpu_resource_create_blob *rc_blob, + bool *guest_blob, bool *host3d_blob) +{ + if (!vgdev->has_resource_blob) + return -EINVAL; + + if ((rc_blob->blob_flags & ~VIRTGPU_BLOB_FLAG_USE_MASK) || + !rc_blob->blob_flags) + return -EINVAL; + + if (rc_blob->blob_flags & VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE) { + if (!vgdev->has_resource_assign_uuid) + return -EINVAL; + } + + switch (rc_blob->blob_mem) { + case VIRTGPU_BLOB_MEM_GUEST: + *guest_blob = true; + break; + case VIRTGPU_BLOB_MEM_HOST3D_GUEST: + *guest_blob = true; + fallthrough; + case VIRTGPU_BLOB_MEM_HOST3D: + *host3d_blob = true; + break; + default: + return -EINVAL; + } + + if (*host3d_blob) { + if (!vgdev->has_virgl_3d) + return -EINVAL; + + /* Must be dword aligned. */ + if (rc_blob->cmd_size % 4 != 0) + return -EINVAL; + + params->ctx_id = vfpriv->ctx_id; + params->blob_id = rc_blob->blob_id; + } else { + if (rc_blob->blob_id != 0) + return -EINVAL; + + if (rc_blob->cmd_size != 0) + return -EINVAL; + } + + params->blob_mem = rc_blob->blob_mem; + params->size = rc_blob->size; + params->blob = true; + params->blob_flags = rc_blob->blob_flags; + return 0; +} + +static int virtio_gpu_resource_create_blob(struct drm_device *dev, + void *data, struct drm_file *file) +{ + int ret = 0; + uint32_t handle = 0; + bool guest_blob = false; + bool host3d_blob = false; + struct drm_gem_object *obj; + struct virtio_gpu_object *bo; + struct virtio_gpu_object_params params = { 0 }; + struct virtio_gpu_device *vgdev = dev->dev_private; + struct virtio_gpu_fpriv *vfpriv = file->driver_priv; + struct drm_virtgpu_resource_create_blob *rc_blob = data; + + if (verify_blob(vgdev, vfpriv, ¶ms, rc_blob, + &guest_blob, &host3d_blob)) + return -EINVAL; + + if (vgdev->has_virgl_3d) + virtio_gpu_create_context(dev, file); + + if (rc_blob->cmd_size) { + void *buf; + + buf = memdup_user(u64_to_user_ptr(rc_blob->cmd), + rc_blob->cmd_size); + + if (IS_ERR(buf)) + return PTR_ERR(buf); + + virtio_gpu_cmd_submit(vgdev, buf, rc_blob->cmd_size, + vfpriv->ctx_id, NULL, NULL); + } + + if (guest_blob) + ret = virtio_gpu_object_create(vgdev, ¶ms, &bo, NULL); + else if (!guest_blob && host3d_blob) + ret = virtio_gpu_vram_create(vgdev, ¶ms, &bo); + else + return -EINVAL; + + if (ret < 0) + return ret; + + bo->guest_blob = guest_blob; + bo->host3d_blob = host3d_blob; + bo->blob_mem = rc_blob->blob_mem; + bo->blob_flags = rc_blob->blob_flags; + + obj = &bo->base.base; + if (params.blob_flags & VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE) { + ret = virtio_gpu_resource_assign_uuid(vgdev, bo); + if (ret) { + drm_gem_object_release(obj); + return ret; + } + } + + ret = drm_gem_handle_create(file, obj, &handle); + if (ret) { + drm_gem_object_release(obj); + return ret; + } + drm_gem_object_put(obj); + + rc_blob->res_handle = bo->hw_res_handle; + rc_blob->bo_handle = handle; + + return 0; +} + struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS] = { DRM_IOCTL_DEF_DRV(VIRTGPU_MAP, virtio_gpu_map_ioctl, DRM_RENDER_ALLOW), @@ -553,4 +685,8 @@ struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS] = { DRM_IOCTL_DEF_DRV(VIRTGPU_GET_CAPS, virtio_gpu_get_caps_ioctl, DRM_RENDER_ALLOW), + + DRM_IOCTL_DEF_DRV(VIRTGPU_RESOURCE_CREATE_BLOB, + virtio_gpu_resource_create_blob, + DRM_RENDER_ALLOW), }; diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index 6b05a31682ae..50cbc36c3b82 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -246,7 +246,10 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, return ret; } - if (params->virgl) { + if (params->blob) { + virtio_gpu_cmd_resource_create_blob(vgdev, bo, params, + ents, nents); + } else if (params->virgl) { virtio_gpu_cmd_resource_create_3d(vgdev, bo, params, objs, fence); virtio_gpu_object_attach(vgdev, bo, ents, nents); diff --git a/drivers/gpu/drm/virtio/virtgpu_vram.c b/drivers/gpu/drm/virtio/virtgpu_vram.c index 087945fcd230..23c21bc4d01e 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vram.c +++ b/drivers/gpu/drm/virtio/virtgpu_vram.c @@ -149,6 +149,8 @@ int virtio_gpu_vram_create(struct virtio_gpu_device *vgdev, return ret; } + virtio_gpu_cmd_resource_create_blob(vgdev, &vram->base, params, NULL, + 0); if (params->blob_flags & VIRTGPU_BLOB_FLAG_USE_MAPPABLE) { ret = virtio_gpu_vram_map(&vram->base); if (ret) { From 378f257d583072b3a6ae0a2fa73fbd6497686dac Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Wed, 23 Sep 2020 17:32:14 -0700 Subject: [PATCH 101/235] drm/virtio: advertise features to userspace New api changes are now available to userspace. Also, the comparison to true is redundant, so remove it. Signed-off-by: Gurchetan Singh Acked-by: Tomeu Vizoso Link: http://patchwork.freedesktop.org/patch/msgid/20200924003214.662-19-gurchetansingh@chromium.org Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_ioctl.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c index 3ede098c1d28..5417f365d1a3 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -212,11 +212,20 @@ static int virtio_gpu_getparam_ioctl(struct drm_device *dev, void *data, switch (param->param) { case VIRTGPU_PARAM_3D_FEATURES: - value = vgdev->has_virgl_3d == true ? 1 : 0; + value = vgdev->has_virgl_3d ? 1 : 0; break; case VIRTGPU_PARAM_CAPSET_QUERY_FIX: value = 1; break; + case VIRTGPU_PARAM_RESOURCE_BLOB: + value = vgdev->has_resource_blob ? 1 : 0; + break; + case VIRTGPU_PARAM_HOST_VISIBLE: + value = vgdev->has_host_visible ? 1 : 0; + break; + case VIRTGPU_PARAM_CROSS_DEVICE: + value = vgdev->has_resource_assign_uuid ? 1 : 0; + break; default: return -EINVAL; } From 79b4d4d26bd256a0c7e3ce74c13a64797d98d1ac Mon Sep 17 00:00:00 2001 From: Qinglang Miao Date: Mon, 21 Sep 2020 21:10:22 +0800 Subject: [PATCH 102/235] drm/qxl: simplify the return expression of qxl_plane_prepare_fb() Simplify the return expression. Signed-off-by: Qinglang Miao Link: http://patchwork.freedesktop.org/patch/msgid/20200921131022.91649-1-miaoqinglang@huawei.com Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/qxl/qxl_display.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 6063f3a15329..65de1f69af58 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -768,7 +768,6 @@ static int qxl_plane_prepare_fb(struct drm_plane *plane, struct drm_gem_object *obj; struct qxl_bo *user_bo; struct qxl_surface surf; - int ret; if (!new_state->fb) return 0; @@ -804,11 +803,7 @@ static int qxl_plane_prepare_fb(struct drm_plane *plane, } } - ret = qxl_bo_pin(user_bo); - if (ret) - return ret; - - return 0; + return qxl_bo_pin(user_bo); } static void qxl_plane_cleanup_fb(struct drm_plane *plane, From 01fd30da0474d5528d96a154cb50ce3b0352fd19 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Fri, 25 Sep 2020 13:55:58 +0200 Subject: [PATCH 103/235] dma-buf: Add struct dma-buf-map for storing struct dma_buf.vaddr_ptr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The new type struct dma_buf_map represents a mapping of dma-buf memory into kernel space. It contains a flag, is_iomem, that signals users to access the mapped memory with I/O operations instead of regular loads and stores. It was assumed that DMA buffer memory can be accessed with regular load and store operations. Some architectures, such as sparc64, require the use of I/O operations to access dma-map buffers that are located in I/O memory. Providing struct dma_buf_map allows drivers to implement this. This was specifically a problem when refreshing the graphics framebuffer on such systems. [1] As the first step, struct dma_buf stores an instance of struct dma_buf_map internally. Afterwards, dma-buf's vmap and vunmap interfaces are be converted. Finally, affected drivers can be fixed. v3: * moved documentation into separate patch * test for NULL pointers with ! [1] https://lore.kernel.org/dri-devel/20200725191012.GA434957@ravnborg.org/ Signed-off-by: Thomas Zimmermann Reviewed-by: Christian König Reviewed-by: Daniel Vetter Acked-by: Sumit Semwal Acked-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200925115601.23955-2-tzimmermann@suse.de --- drivers/dma-buf/dma-buf.c | 14 +++---- include/linux/dma-buf-map.h | 82 +++++++++++++++++++++++++++++++++++++ include/linux/dma-buf.h | 3 +- 3 files changed, 91 insertions(+), 8 deletions(-) create mode 100644 include/linux/dma-buf-map.h diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 58564d82a3a2..5e849ca241a0 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -1207,12 +1207,12 @@ void *dma_buf_vmap(struct dma_buf *dmabuf) mutex_lock(&dmabuf->lock); if (dmabuf->vmapping_counter) { dmabuf->vmapping_counter++; - BUG_ON(!dmabuf->vmap_ptr); - ptr = dmabuf->vmap_ptr; + BUG_ON(dma_buf_map_is_null(&dmabuf->vmap_ptr)); + ptr = dmabuf->vmap_ptr.vaddr; goto out_unlock; } - BUG_ON(dmabuf->vmap_ptr); + BUG_ON(dma_buf_map_is_set(&dmabuf->vmap_ptr)); ptr = dmabuf->ops->vmap(dmabuf); if (WARN_ON_ONCE(IS_ERR(ptr))) @@ -1220,7 +1220,7 @@ void *dma_buf_vmap(struct dma_buf *dmabuf) if (!ptr) goto out_unlock; - dmabuf->vmap_ptr = ptr; + dmabuf->vmap_ptr.vaddr = ptr; dmabuf->vmapping_counter = 1; out_unlock: @@ -1239,15 +1239,15 @@ void dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr) if (WARN_ON(!dmabuf)) return; - BUG_ON(!dmabuf->vmap_ptr); + BUG_ON(dma_buf_map_is_null(&dmabuf->vmap_ptr)); BUG_ON(dmabuf->vmapping_counter == 0); - BUG_ON(dmabuf->vmap_ptr != vaddr); + BUG_ON(!dma_buf_map_is_vaddr(&dmabuf->vmap_ptr, vaddr)); mutex_lock(&dmabuf->lock); if (--dmabuf->vmapping_counter == 0) { if (dmabuf->ops->vunmap) dmabuf->ops->vunmap(dmabuf, vaddr); - dmabuf->vmap_ptr = NULL; + dma_buf_map_clear(&dmabuf->vmap_ptr); } mutex_unlock(&dmabuf->lock); } diff --git a/include/linux/dma-buf-map.h b/include/linux/dma-buf-map.h new file mode 100644 index 000000000000..00143c88feb6 --- /dev/null +++ b/include/linux/dma-buf-map.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Pointer to dma-buf-mapped memory, plus helpers. + */ + +#ifndef __DMA_BUF_MAP_H__ +#define __DMA_BUF_MAP_H__ + +#include + +/** + * struct dma_buf_map - Pointer to vmap'ed dma-buf memory. + * @vaddr_iomem: The buffer's address if in I/O memory + * @vaddr: The buffer's address if in system memory + * @is_iomem: True if the dma-buf memory is located in I/O + * memory, or false otherwise. + */ +struct dma_buf_map { + union { + void __iomem *vaddr_iomem; + void *vaddr; + }; + bool is_iomem; +}; + +/* API transition helper */ +static inline bool dma_buf_map_is_vaddr(const struct dma_buf_map *map, const void *vaddr) +{ + return !map->is_iomem && (map->vaddr == vaddr); +} + +/** + * dma_buf_map_is_null - Tests for a dma-buf mapping to be NULL + * @map: The dma-buf mapping structure + * + * Depending on the state of struct dma_buf_map.is_iomem, tests if the + * mapping is NULL. + * + * Returns: + * True if the mapping is NULL, or false otherwise. + */ +static inline bool dma_buf_map_is_null(const struct dma_buf_map *map) +{ + if (map->is_iomem) + return !map->vaddr_iomem; + return !map->vaddr; +} + +/** + * dma_buf_map_is_set - Tests is the dma-buf mapping has been set + * @map: The dma-buf mapping structure + * + * Depending on the state of struct dma_buf_map.is_iomem, tests if the + * mapping has been set. + * + * Returns: + * True if the mapping is been set, or false otherwise. + */ +static inline bool dma_buf_map_is_set(const struct dma_buf_map *map) +{ + return !dma_buf_map_is_null(map); +} + +/** + * dma_buf_map_clear - Clears a dma-buf mapping structure + * @map: The dma-buf mapping structure + * + * Clears all fields to zero; including struct dma_buf_map.is_iomem. So + * mapping structures that were set to point to I/O memory are reset for + * system memory. Pointers are cleared to NULL. This is the default. + */ +static inline void dma_buf_map_clear(struct dma_buf_map *map) +{ + if (map->is_iomem) { + map->vaddr_iomem = NULL; + map->is_iomem = false; + } else { + map->vaddr = NULL; + } +} + +#endif /* __DMA_BUF_MAP_H__ */ diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index 957b398d30e5..fcc2ddfb6d18 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -13,6 +13,7 @@ #ifndef __DMA_BUF_H__ #define __DMA_BUF_H__ +#include #include #include #include @@ -309,7 +310,7 @@ struct dma_buf { const struct dma_buf_ops *ops; struct mutex lock; unsigned vmapping_counter; - void *vmap_ptr; + struct dma_buf_map vmap_ptr; const char *exp_name; const char *name; spinlock_t name_lock; From 6619ccf1bb1d0ebb071f758111efa83918b216fc Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Fri, 25 Sep 2020 13:55:59 +0200 Subject: [PATCH 104/235] dma-buf: Use struct dma_buf_map in dma_buf_vmap() interfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch updates dma_buf_vmap() and dma-buf's vmap callback to use struct dma_buf_map. The interfaces used to return a buffer address. This address now gets stored in an instance of the structure that is given as an additional argument. The functions return an errno code on errors. Users of the functions are updated accordingly. This is only an interface change. It is currently expected that dma-buf memory can be accessed with system memory load/store operations. v3: * update fastrpc driver (kernel test robot) v2: * always clear map parameter in dma_buf_vmap() (Daniel) * include dma-buf-heaps and i915 selftests (kernel test robot) Signed-off-by: Thomas Zimmermann Acked-by: Sumit Semwal Acked-by: Christian König Acked-by: Daniel Vetter Acked-by: Tomasz Figa Acked-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200925115601.23955-3-tzimmermann@suse.de --- drivers/dma-buf/dma-buf.c | 28 +++++++++++-------- drivers/dma-buf/heaps/heap-helpers.c | 8 ++++-- drivers/gpu/drm/drm_gem_cma_helper.c | 13 +++++---- drivers/gpu/drm/drm_gem_shmem_helper.c | 14 ++++++---- drivers/gpu/drm/drm_prime.c | 9 ++++-- drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c | 8 +++++- drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c | 11 ++++++-- .../drm/i915/gem/selftests/i915_gem_dmabuf.c | 12 ++++++-- .../gpu/drm/i915/gem/selftests/mock_dmabuf.c | 10 +++++-- drivers/gpu/drm/tegra/gem.c | 18 ++++++++---- .../common/videobuf2/videobuf2-dma-contig.c | 14 +++++++--- .../media/common/videobuf2/videobuf2-dma-sg.c | 16 +++++++---- .../common/videobuf2/videobuf2-vmalloc.c | 15 +++++++--- drivers/misc/fastrpc.c | 6 ++-- include/drm/drm_prime.h | 3 +- include/linux/dma-buf-map.h | 13 +++++++++ include/linux/dma-buf.h | 6 ++-- 17 files changed, 143 insertions(+), 61 deletions(-) diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 5e849ca241a0..61bd24d21b38 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -1186,46 +1186,50 @@ EXPORT_SYMBOL_GPL(dma_buf_mmap); * dma_buf_vmap - Create virtual mapping for the buffer object into kernel * address space. Same restrictions as for vmap and friends apply. * @dmabuf: [in] buffer to vmap + * @map: [out] returns the vmap pointer * * This call may fail due to lack of virtual mapping address space. * These calls are optional in drivers. The intended use for them * is for mapping objects linear in kernel space for high use objects. * Please attempt to use kmap/kunmap before thinking about these interfaces. * - * Returns NULL on error. + * Returns 0 on success, or a negative errno code otherwise. */ -void *dma_buf_vmap(struct dma_buf *dmabuf) +int dma_buf_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map) { - void *ptr; + struct dma_buf_map ptr; + int ret = 0; + + dma_buf_map_clear(map); if (WARN_ON(!dmabuf)) - return NULL; + return -EINVAL; if (!dmabuf->ops->vmap) - return NULL; + return -EINVAL; mutex_lock(&dmabuf->lock); if (dmabuf->vmapping_counter) { dmabuf->vmapping_counter++; BUG_ON(dma_buf_map_is_null(&dmabuf->vmap_ptr)); - ptr = dmabuf->vmap_ptr.vaddr; + *map = dmabuf->vmap_ptr; goto out_unlock; } BUG_ON(dma_buf_map_is_set(&dmabuf->vmap_ptr)); - ptr = dmabuf->ops->vmap(dmabuf); - if (WARN_ON_ONCE(IS_ERR(ptr))) - ptr = NULL; - if (!ptr) + ret = dmabuf->ops->vmap(dmabuf, &ptr); + if (WARN_ON_ONCE(ret)) goto out_unlock; - dmabuf->vmap_ptr.vaddr = ptr; + dmabuf->vmap_ptr = ptr; dmabuf->vmapping_counter = 1; + *map = dmabuf->vmap_ptr; + out_unlock: mutex_unlock(&dmabuf->lock); - return ptr; + return ret; } EXPORT_SYMBOL_GPL(dma_buf_vmap); diff --git a/drivers/dma-buf/heaps/heap-helpers.c b/drivers/dma-buf/heaps/heap-helpers.c index 9f964ca3f59c..27e54d9c120c 100644 --- a/drivers/dma-buf/heaps/heap-helpers.c +++ b/drivers/dma-buf/heaps/heap-helpers.c @@ -236,7 +236,7 @@ static int dma_heap_dma_buf_end_cpu_access(struct dma_buf *dmabuf, return 0; } -static void *dma_heap_dma_buf_vmap(struct dma_buf *dmabuf) +static int dma_heap_dma_buf_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map) { struct heap_helper_buffer *buffer = dmabuf->priv; void *vaddr; @@ -245,7 +245,11 @@ static void *dma_heap_dma_buf_vmap(struct dma_buf *dmabuf) vaddr = dma_heap_buffer_vmap_get(buffer); mutex_unlock(&buffer->lock); - return vaddr; + if (!vaddr) + return -ENOMEM; + dma_buf_map_set_vaddr(map, vaddr); + + return 0; } static void dma_heap_dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr) diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c index 1e5b389c435c..eb412e45f896 100644 --- a/drivers/gpu/drm/drm_gem_cma_helper.c +++ b/drivers/gpu/drm/drm_gem_cma_helper.c @@ -634,22 +634,23 @@ drm_gem_cma_prime_import_sg_table_vmap(struct drm_device *dev, { struct drm_gem_cma_object *cma_obj; struct drm_gem_object *obj; - void *vaddr; + struct dma_buf_map map; + int ret; - vaddr = dma_buf_vmap(attach->dmabuf); - if (!vaddr) { + ret = dma_buf_vmap(attach->dmabuf, &map); + if (ret) { DRM_ERROR("Failed to vmap PRIME buffer\n"); - return ERR_PTR(-ENOMEM); + return ERR_PTR(ret); } obj = drm_gem_cma_prime_import_sg_table(dev, attach, sgt); if (IS_ERR(obj)) { - dma_buf_vunmap(attach->dmabuf, vaddr); + dma_buf_vunmap(attach->dmabuf, map.vaddr); return obj; } cma_obj = to_drm_gem_cma_obj(obj); - cma_obj->vaddr = vaddr; + cma_obj->vaddr = map.vaddr; return obj; } diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c index 0a952f27c184..ad10a57cfece 100644 --- a/drivers/gpu/drm/drm_gem_shmem_helper.c +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c @@ -261,13 +261,16 @@ EXPORT_SYMBOL(drm_gem_shmem_unpin); static void *drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem) { struct drm_gem_object *obj = &shmem->base; - int ret; + struct dma_buf_map map; + int ret = 0; if (shmem->vmap_use_count++ > 0) return shmem->vaddr; if (obj->import_attach) { - shmem->vaddr = dma_buf_vmap(obj->import_attach->dmabuf); + ret = dma_buf_vmap(obj->import_attach->dmabuf, &map); + if (!ret) + shmem->vaddr = map.vaddr; } else { pgprot_t prot = PAGE_KERNEL; @@ -279,11 +282,12 @@ static void *drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem) prot = pgprot_writecombine(prot); shmem->vaddr = vmap(shmem->pages, obj->size >> PAGE_SHIFT, VM_MAP, prot); + if (!shmem->vaddr) + ret = -ENOMEM; } - if (!shmem->vaddr) { - DRM_DEBUG_KMS("Failed to vmap pages\n"); - ret = -ENOMEM; + if (ret) { + DRM_DEBUG_KMS("Failed to vmap pages, error %d\n", ret); goto err_put_pages; } diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 194784a5b344..2d75e58d21fe 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -662,22 +662,25 @@ EXPORT_SYMBOL(drm_gem_unmap_dma_buf); /** * drm_gem_dmabuf_vmap - dma_buf vmap implementation for GEM * @dma_buf: buffer to be mapped + * @map: the virtual address of the buffer * * Sets up a kernel virtual mapping. This can be used as the &dma_buf_ops.vmap * callback. Calls into &drm_gem_object_funcs.vmap for device specific handling. * * Returns the kernel virtual address or NULL on failure. */ -void *drm_gem_dmabuf_vmap(struct dma_buf *dma_buf) +int drm_gem_dmabuf_vmap(struct dma_buf *dma_buf, struct dma_buf_map *map) { struct drm_gem_object *obj = dma_buf->priv; void *vaddr; vaddr = drm_gem_vmap(obj); if (IS_ERR(vaddr)) - vaddr = NULL; + return PTR_ERR(vaddr); - return vaddr; + dma_buf_map_set_vaddr(map, vaddr); + + return 0; } EXPORT_SYMBOL(drm_gem_dmabuf_vmap); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c index 4aa3426a9ba4..80a9fc143bbb 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c @@ -85,9 +85,15 @@ static void etnaviv_gem_prime_release(struct etnaviv_gem_object *etnaviv_obj) static void *etnaviv_gem_prime_vmap_impl(struct etnaviv_gem_object *etnaviv_obj) { + struct dma_buf_map map; + int ret; + lockdep_assert_held(&etnaviv_obj->lock); - return dma_buf_vmap(etnaviv_obj->base.import_attach->dmabuf); + ret = dma_buf_vmap(etnaviv_obj->base.import_attach->dmabuf, &map); + if (ret) + return NULL; + return map.vaddr; } static int etnaviv_gem_prime_mmap_obj(struct etnaviv_gem_object *etnaviv_obj, diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c index 27fddc22a7c6..77b363d3000b 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c @@ -82,11 +82,18 @@ static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment, i915_gem_object_unpin_pages(obj); } -static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf) +static int i915_gem_dmabuf_vmap(struct dma_buf *dma_buf, struct dma_buf_map *map) { struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf); + void *vaddr; - return i915_gem_object_pin_map(obj, I915_MAP_WB); + vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB); + if (IS_ERR(vaddr)) + return PTR_ERR(vaddr); + + dma_buf_map_set_vaddr(map, vaddr); + + return 0; } static void i915_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr) diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c index 0845ce1ae37c..3aad7643b0b7 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c @@ -82,6 +82,7 @@ static int igt_dmabuf_import(void *arg) struct drm_i915_gem_object *obj; struct dma_buf *dmabuf; void *obj_map, *dma_map; + struct dma_buf_map map; u32 pattern[] = { 0, 0xaa, 0xcc, 0x55, 0xff }; int err, i; @@ -110,7 +111,8 @@ static int igt_dmabuf_import(void *arg) goto out_obj; } - dma_map = dma_buf_vmap(dmabuf); + err = dma_buf_vmap(dmabuf, &map); + dma_map = err ? NULL : map.vaddr; if (!dma_map) { pr_err("dma_buf_vmap failed\n"); err = -ENOMEM; @@ -163,6 +165,7 @@ static int igt_dmabuf_import_ownership(void *arg) struct drm_i915_private *i915 = arg; struct drm_i915_gem_object *obj; struct dma_buf *dmabuf; + struct dma_buf_map map; void *ptr; int err; @@ -170,7 +173,8 @@ static int igt_dmabuf_import_ownership(void *arg) if (IS_ERR(dmabuf)) return PTR_ERR(dmabuf); - ptr = dma_buf_vmap(dmabuf); + err = dma_buf_vmap(dmabuf, &map); + ptr = err ? NULL : map.vaddr; if (!ptr) { pr_err("dma_buf_vmap failed\n"); err = -ENOMEM; @@ -212,6 +216,7 @@ static int igt_dmabuf_export_vmap(void *arg) struct drm_i915_private *i915 = arg; struct drm_i915_gem_object *obj; struct dma_buf *dmabuf; + struct dma_buf_map map; void *ptr; int err; @@ -228,7 +233,8 @@ static int igt_dmabuf_export_vmap(void *arg) } i915_gem_object_put(obj); - ptr = dma_buf_vmap(dmabuf); + err = dma_buf_vmap(dmabuf, &map); + ptr = err ? NULL : map.vaddr; if (!ptr) { pr_err("dma_buf_vmap failed\n"); err = -ENOMEM; diff --git a/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c b/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c index debaf7b18ab5..dcae46441f7d 100644 --- a/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c +++ b/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c @@ -62,11 +62,17 @@ static void mock_dmabuf_release(struct dma_buf *dma_buf) kfree(mock); } -static void *mock_dmabuf_vmap(struct dma_buf *dma_buf) +static int mock_dmabuf_vmap(struct dma_buf *dma_buf, struct dma_buf_map *map) { struct mock_dmabuf *mock = to_mock(dma_buf); + void *vaddr; - return vm_map_ram(mock->pages, mock->npages, 0); + vaddr = vm_map_ram(mock->pages, mock->npages, 0); + if (!vaddr) + return -ENOMEM; + dma_buf_map_set_vaddr(map, vaddr); + + return 0; } static void mock_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr) diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index d481dea4738d..2b6e06c7a2c5 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -132,14 +132,18 @@ static void tegra_bo_unpin(struct device *dev, struct sg_table *sgt) static void *tegra_bo_mmap(struct host1x_bo *bo) { struct tegra_bo *obj = host1x_to_tegra_bo(bo); + struct dma_buf_map map; + int ret; - if (obj->vaddr) + if (obj->vaddr) { return obj->vaddr; - else if (obj->gem.import_attach) - return dma_buf_vmap(obj->gem.import_attach->dmabuf); - else + } else if (obj->gem.import_attach) { + ret = dma_buf_vmap(obj->gem.import_attach->dmabuf, &map); + return ret ? NULL : map.vaddr; + } else { return vmap(obj->pages, obj->num_pages, VM_MAP, pgprot_writecombine(PAGE_KERNEL)); + } } static void tegra_bo_munmap(struct host1x_bo *bo, void *addr) @@ -649,12 +653,14 @@ static int tegra_gem_prime_mmap(struct dma_buf *buf, struct vm_area_struct *vma) return __tegra_gem_mmap(gem, vma); } -static void *tegra_gem_prime_vmap(struct dma_buf *buf) +static int tegra_gem_prime_vmap(struct dma_buf *buf, struct dma_buf_map *map) { struct drm_gem_object *gem = buf->priv; struct tegra_bo *bo = to_tegra_bo(gem); - return bo->vaddr; + dma_buf_map_set_vaddr(map, bo->vaddr); + + return 0; } static void tegra_gem_prime_vunmap(struct dma_buf *buf, void *vaddr) diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c index ec3446cc45b8..11428287bdf3 100644 --- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c +++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c @@ -81,9 +81,13 @@ static void *vb2_dc_cookie(void *buf_priv) static void *vb2_dc_vaddr(void *buf_priv) { struct vb2_dc_buf *buf = buf_priv; + struct dma_buf_map map; + int ret; - if (!buf->vaddr && buf->db_attach) - buf->vaddr = dma_buf_vmap(buf->db_attach->dmabuf); + if (!buf->vaddr && buf->db_attach) { + ret = dma_buf_vmap(buf->db_attach->dmabuf, &map); + buf->vaddr = ret ? NULL : map.vaddr; + } return buf->vaddr; } @@ -365,11 +369,13 @@ vb2_dc_dmabuf_ops_end_cpu_access(struct dma_buf *dbuf, return 0; } -static void *vb2_dc_dmabuf_ops_vmap(struct dma_buf *dbuf) +static int vb2_dc_dmabuf_ops_vmap(struct dma_buf *dbuf, struct dma_buf_map *map) { struct vb2_dc_buf *buf = dbuf->priv; - return buf->vaddr; + dma_buf_map_set_vaddr(map, buf->vaddr); + + return 0; } static int vb2_dc_dmabuf_ops_mmap(struct dma_buf *dbuf, diff --git a/drivers/media/common/videobuf2/videobuf2-dma-sg.c b/drivers/media/common/videobuf2/videobuf2-dma-sg.c index 0a40e00f0d7e..c51170e9c1b9 100644 --- a/drivers/media/common/videobuf2/videobuf2-dma-sg.c +++ b/drivers/media/common/videobuf2/videobuf2-dma-sg.c @@ -300,14 +300,18 @@ static void vb2_dma_sg_put_userptr(void *buf_priv) static void *vb2_dma_sg_vaddr(void *buf_priv) { struct vb2_dma_sg_buf *buf = buf_priv; + struct dma_buf_map map; + int ret; BUG_ON(!buf); if (!buf->vaddr) { - if (buf->db_attach) - buf->vaddr = dma_buf_vmap(buf->db_attach->dmabuf); - else + if (buf->db_attach) { + ret = dma_buf_vmap(buf->db_attach->dmabuf, &map); + buf->vaddr = ret ? NULL : map.vaddr; + } else { buf->vaddr = vm_map_ram(buf->pages, buf->num_pages, -1); + } } /* add offset in case userptr is not page-aligned */ @@ -489,11 +493,13 @@ vb2_dma_sg_dmabuf_ops_end_cpu_access(struct dma_buf *dbuf, return 0; } -static void *vb2_dma_sg_dmabuf_ops_vmap(struct dma_buf *dbuf) +static int vb2_dma_sg_dmabuf_ops_vmap(struct dma_buf *dbuf, struct dma_buf_map *map) { struct vb2_dma_sg_buf *buf = dbuf->priv; - return vb2_dma_sg_vaddr(buf); + dma_buf_map_set_vaddr(map, buf->vaddr); + + return 0; } static int vb2_dma_sg_dmabuf_ops_mmap(struct dma_buf *dbuf, diff --git a/drivers/media/common/videobuf2/videobuf2-vmalloc.c b/drivers/media/common/videobuf2/videobuf2-vmalloc.c index c66fda4a65e4..7b68e2379c65 100644 --- a/drivers/media/common/videobuf2/videobuf2-vmalloc.c +++ b/drivers/media/common/videobuf2/videobuf2-vmalloc.c @@ -318,11 +318,13 @@ static void vb2_vmalloc_dmabuf_ops_release(struct dma_buf *dbuf) vb2_vmalloc_put(dbuf->priv); } -static void *vb2_vmalloc_dmabuf_ops_vmap(struct dma_buf *dbuf) +static int vb2_vmalloc_dmabuf_ops_vmap(struct dma_buf *dbuf, struct dma_buf_map *map) { struct vb2_vmalloc_buf *buf = dbuf->priv; - return buf->vaddr; + dma_buf_map_set_vaddr(map, buf->vaddr); + + return 0; } static int vb2_vmalloc_dmabuf_ops_mmap(struct dma_buf *dbuf, @@ -374,10 +376,15 @@ static struct dma_buf *vb2_vmalloc_get_dmabuf(void *buf_priv, unsigned long flag static int vb2_vmalloc_map_dmabuf(void *mem_priv) { struct vb2_vmalloc_buf *buf = mem_priv; + struct dma_buf_map map; + int ret; - buf->vaddr = dma_buf_vmap(buf->dbuf); + ret = dma_buf_vmap(buf->dbuf, &map); + if (ret) + return -EFAULT; + buf->vaddr = map.vaddr; - return buf->vaddr ? 0 : -EFAULT; + return 0; } static void vb2_vmalloc_unmap_dmabuf(void *mem_priv) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 7939c55daceb..b39e198533f0 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -581,11 +581,13 @@ static void fastrpc_dma_buf_detatch(struct dma_buf *dmabuf, kfree(a); } -static void *fastrpc_vmap(struct dma_buf *dmabuf) +static int fastrpc_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map) { struct fastrpc_buf *buf = dmabuf->priv; - return buf->virt; + dma_buf_map_set_vaddr(map, buf->virt); + + return 0; } static int fastrpc_mmap(struct dma_buf *dmabuf, diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h index bf141e74a1c2..3ee22639ff77 100644 --- a/include/drm/drm_prime.h +++ b/include/drm/drm_prime.h @@ -54,6 +54,7 @@ struct device; struct dma_buf_export_info; struct dma_buf; struct dma_buf_attachment; +struct dma_buf_map; enum dma_data_direction; @@ -82,7 +83,7 @@ struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach, void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach, struct sg_table *sgt, enum dma_data_direction dir); -void *drm_gem_dmabuf_vmap(struct dma_buf *dma_buf); +int drm_gem_dmabuf_vmap(struct dma_buf *dma_buf, struct dma_buf_map *map); void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr); int drm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); diff --git a/include/linux/dma-buf-map.h b/include/linux/dma-buf-map.h index 00143c88feb6..5ae732d373eb 100644 --- a/include/linux/dma-buf-map.h +++ b/include/linux/dma-buf-map.h @@ -23,6 +23,19 @@ struct dma_buf_map { bool is_iomem; }; +/** + * dma_buf_map_set_vaddr - Sets a dma-buf mapping structure to an address in system memory + * @map: The dma-buf mapping structure + * @vaddr: A system-memory address + * + * Sets the address and clears the I/O-memory flag. + */ +static inline void dma_buf_map_set_vaddr(struct dma_buf_map *map, void *vaddr) +{ + map->vaddr = vaddr; + map->is_iomem = false; +} + /* API transition helper */ static inline bool dma_buf_map_is_vaddr(const struct dma_buf_map *map, const void *vaddr) { diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index fcc2ddfb6d18..7237997cfa38 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -266,7 +266,7 @@ struct dma_buf_ops { */ int (*mmap)(struct dma_buf *, struct vm_area_struct *vma); - void *(*vmap)(struct dma_buf *); + int (*vmap)(struct dma_buf *dmabuf, struct dma_buf_map *map); void (*vunmap)(struct dma_buf *, void *vaddr); }; @@ -503,6 +503,6 @@ int dma_buf_end_cpu_access(struct dma_buf *dma_buf, int dma_buf_mmap(struct dma_buf *, struct vm_area_struct *, unsigned long); -void *dma_buf_vmap(struct dma_buf *); -void dma_buf_vunmap(struct dma_buf *, void *vaddr); +int dma_buf_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map); +void dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr); #endif /* __DMA_BUF_H__ */ From 20e76f1a70596590dec32a5d1f598fba04859526 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Fri, 25 Sep 2020 13:56:00 +0200 Subject: [PATCH 105/235] dma-buf: Use struct dma_buf_map in dma_buf_vunmap() interfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch updates dma_buf_vunmap() and dma-buf's vunmap callback to use struct dma_buf_map. The interfaces used to receive a buffer address. This address is now given in an instance of the structure. Users of the functions are updated accordingly. This is only an interface change. It is currently expected that dma-buf memory can be accessed with system memory load/store operations. v2: * include dma-buf-heaps and i915 selftests (kernel test robot) * initialize cma_obj before using it in drm_gem_cma_free_object() (kernel test robot) Signed-off-by: Thomas Zimmermann Acked-by: Sumit Semwal Acked-by: Christian König Acked-by: Daniel Vetter Acked-by: Tomasz Figa Acked-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200925115601.23955-4-tzimmermann@suse.de --- drivers/dma-buf/dma-buf.c | 8 ++--- drivers/dma-buf/heaps/heap-helpers.c | 2 +- drivers/gpu/drm/drm_gem_cma_helper.c | 9 +++--- drivers/gpu/drm/drm_gem_shmem_helper.c | 3 +- drivers/gpu/drm/drm_prime.c | 6 ++-- drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c | 5 +-- drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c | 2 +- .../drm/i915/gem/selftests/i915_gem_dmabuf.c | 6 ++-- .../gpu/drm/i915/gem/selftests/mock_dmabuf.c | 4 +-- drivers/gpu/drm/tegra/gem.c | 5 +-- .../common/videobuf2/videobuf2-dma-contig.c | 3 +- .../media/common/videobuf2/videobuf2-dma-sg.c | 3 +- .../common/videobuf2/videobuf2-vmalloc.c | 6 ++-- include/drm/drm_prime.h | 2 +- include/linux/dma-buf-map.h | 32 +++++++++++++++++-- include/linux/dma-buf.h | 4 +-- 16 files changed, 66 insertions(+), 34 deletions(-) diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 61bd24d21b38..a6ba4d598f0e 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -1236,21 +1236,21 @@ EXPORT_SYMBOL_GPL(dma_buf_vmap); /** * dma_buf_vunmap - Unmap a vmap obtained by dma_buf_vmap. * @dmabuf: [in] buffer to vunmap - * @vaddr: [in] vmap to vunmap + * @map: [in] vmap pointer to vunmap */ -void dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr) +void dma_buf_vunmap(struct dma_buf *dmabuf, struct dma_buf_map *map) { if (WARN_ON(!dmabuf)) return; BUG_ON(dma_buf_map_is_null(&dmabuf->vmap_ptr)); BUG_ON(dmabuf->vmapping_counter == 0); - BUG_ON(!dma_buf_map_is_vaddr(&dmabuf->vmap_ptr, vaddr)); + BUG_ON(!dma_buf_map_is_equal(&dmabuf->vmap_ptr, map)); mutex_lock(&dmabuf->lock); if (--dmabuf->vmapping_counter == 0) { if (dmabuf->ops->vunmap) - dmabuf->ops->vunmap(dmabuf, vaddr); + dmabuf->ops->vunmap(dmabuf, map); dma_buf_map_clear(&dmabuf->vmap_ptr); } mutex_unlock(&dmabuf->lock); diff --git a/drivers/dma-buf/heaps/heap-helpers.c b/drivers/dma-buf/heaps/heap-helpers.c index 27e54d9c120c..e9fb2818f2d4 100644 --- a/drivers/dma-buf/heaps/heap-helpers.c +++ b/drivers/dma-buf/heaps/heap-helpers.c @@ -252,7 +252,7 @@ static int dma_heap_dma_buf_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map return 0; } -static void dma_heap_dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr) +static void dma_heap_dma_buf_vunmap(struct dma_buf *dmabuf, struct dma_buf_map *map) { struct heap_helper_buffer *buffer = dmabuf->priv; diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c index eb412e45f896..5e9d29961307 100644 --- a/drivers/gpu/drm/drm_gem_cma_helper.c +++ b/drivers/gpu/drm/drm_gem_cma_helper.c @@ -175,13 +175,12 @@ drm_gem_cma_create_with_handle(struct drm_file *file_priv, */ void drm_gem_cma_free_object(struct drm_gem_object *gem_obj) { - struct drm_gem_cma_object *cma_obj; - - cma_obj = to_drm_gem_cma_obj(gem_obj); + struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(gem_obj); + struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(cma_obj->vaddr); if (gem_obj->import_attach) { if (cma_obj->vaddr) - dma_buf_vunmap(gem_obj->import_attach->dmabuf, cma_obj->vaddr); + dma_buf_vunmap(gem_obj->import_attach->dmabuf, &map); drm_prime_gem_destroy(gem_obj, cma_obj->sgt); } else if (cma_obj->vaddr) { dma_free_wc(gem_obj->dev->dev, cma_obj->base.size, @@ -645,7 +644,7 @@ drm_gem_cma_prime_import_sg_table_vmap(struct drm_device *dev, obj = drm_gem_cma_prime_import_sg_table(dev, attach, sgt); if (IS_ERR(obj)) { - dma_buf_vunmap(attach->dmabuf, map.vaddr); + dma_buf_vunmap(attach->dmabuf, &map); return obj; } diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c index ad10a57cfece..3c2e8cde69a8 100644 --- a/drivers/gpu/drm/drm_gem_shmem_helper.c +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c @@ -337,6 +337,7 @@ EXPORT_SYMBOL(drm_gem_shmem_vmap); static void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem) { struct drm_gem_object *obj = &shmem->base; + struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(shmem->vaddr); if (WARN_ON_ONCE(!shmem->vmap_use_count)) return; @@ -345,7 +346,7 @@ static void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem) return; if (obj->import_attach) - dma_buf_vunmap(obj->import_attach->dmabuf, shmem->vaddr); + dma_buf_vunmap(obj->import_attach->dmabuf, &map); else vunmap(shmem->vaddr); diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 2d75e58d21fe..4910c446db83 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -687,16 +687,16 @@ EXPORT_SYMBOL(drm_gem_dmabuf_vmap); /** * drm_gem_dmabuf_vunmap - dma_buf vunmap implementation for GEM * @dma_buf: buffer to be unmapped - * @vaddr: the virtual address of the buffer + * @map: the virtual address of the buffer * * Releases a kernel virtual mapping. This can be used as the * &dma_buf_ops.vunmap callback. Calls into &drm_gem_object_funcs.vunmap for device specific handling. */ -void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr) +void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, struct dma_buf_map *map) { struct drm_gem_object *obj = dma_buf->priv; - drm_gem_vunmap(obj, vaddr); + drm_gem_vunmap(obj, map->vaddr); } EXPORT_SYMBOL(drm_gem_dmabuf_vunmap); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c index 80a9fc143bbb..135fbff6fecf 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c @@ -70,9 +70,10 @@ void etnaviv_gem_prime_unpin(struct drm_gem_object *obj) static void etnaviv_gem_prime_release(struct etnaviv_gem_object *etnaviv_obj) { + struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(etnaviv_obj->vaddr); + if (etnaviv_obj->vaddr) - dma_buf_vunmap(etnaviv_obj->base.import_attach->dmabuf, - etnaviv_obj->vaddr); + dma_buf_vunmap(etnaviv_obj->base.import_attach->dmabuf, &map); /* Don't drop the pages for imported dmabuf, as they are not * ours, just free the array we allocated: diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c index 77b363d3000b..fec0e1e3dc3e 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c @@ -96,7 +96,7 @@ static int i915_gem_dmabuf_vmap(struct dma_buf *dma_buf, struct dma_buf_map *map return 0; } -static void i915_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr) +static void i915_gem_dmabuf_vunmap(struct dma_buf *dma_buf, struct dma_buf_map *map) { struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf); diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c index 3aad7643b0b7..b6d43880b0c1 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c @@ -152,7 +152,7 @@ static int igt_dmabuf_import(void *arg) err = 0; out_dma_map: - dma_buf_vunmap(dmabuf, dma_map); + dma_buf_vunmap(dmabuf, &map); out_obj: i915_gem_object_put(obj); out_dmabuf: @@ -182,7 +182,7 @@ static int igt_dmabuf_import_ownership(void *arg) } memset(ptr, 0xc5, PAGE_SIZE); - dma_buf_vunmap(dmabuf, ptr); + dma_buf_vunmap(dmabuf, &map); obj = to_intel_bo(i915_gem_prime_import(&i915->drm, dmabuf)); if (IS_ERR(obj)) { @@ -250,7 +250,7 @@ static int igt_dmabuf_export_vmap(void *arg) memset(ptr, 0xc5, dmabuf->size); err = 0; - dma_buf_vunmap(dmabuf, ptr); + dma_buf_vunmap(dmabuf, &map); out: dma_buf_put(dmabuf); return err; diff --git a/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c b/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c index dcae46441f7d..7dfef531f6d4 100644 --- a/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c +++ b/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c @@ -75,11 +75,11 @@ static int mock_dmabuf_vmap(struct dma_buf *dma_buf, struct dma_buf_map *map) return 0; } -static void mock_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr) +static void mock_dmabuf_vunmap(struct dma_buf *dma_buf, struct dma_buf_map *map) { struct mock_dmabuf *mock = to_mock(dma_buf); - vm_unmap_ram(vaddr, mock->npages); + vm_unmap_ram(map->vaddr, mock->npages); } static int mock_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma) diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index 2b6e06c7a2c5..5df577682878 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -149,11 +149,12 @@ static void *tegra_bo_mmap(struct host1x_bo *bo) static void tegra_bo_munmap(struct host1x_bo *bo, void *addr) { struct tegra_bo *obj = host1x_to_tegra_bo(bo); + struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(addr); if (obj->vaddr) return; else if (obj->gem.import_attach) - dma_buf_vunmap(obj->gem.import_attach->dmabuf, addr); + dma_buf_vunmap(obj->gem.import_attach->dmabuf, &map); else vunmap(addr); } @@ -663,7 +664,7 @@ static int tegra_gem_prime_vmap(struct dma_buf *buf, struct dma_buf_map *map) return 0; } -static void tegra_gem_prime_vunmap(struct dma_buf *buf, void *vaddr) +static void tegra_gem_prime_vunmap(struct dma_buf *buf, struct dma_buf_map *map) { } diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c index 11428287bdf3..a1eb8279b113 100644 --- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c +++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c @@ -648,6 +648,7 @@ static void vb2_dc_unmap_dmabuf(void *mem_priv) { struct vb2_dc_buf *buf = mem_priv; struct sg_table *sgt = buf->dma_sgt; + struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(buf->vaddr); if (WARN_ON(!buf->db_attach)) { pr_err("trying to unpin a not attached buffer\n"); @@ -660,7 +661,7 @@ static void vb2_dc_unmap_dmabuf(void *mem_priv) } if (buf->vaddr) { - dma_buf_vunmap(buf->db_attach->dmabuf, buf->vaddr); + dma_buf_vunmap(buf->db_attach->dmabuf, &map); buf->vaddr = NULL; } dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir); diff --git a/drivers/media/common/videobuf2/videobuf2-dma-sg.c b/drivers/media/common/videobuf2/videobuf2-dma-sg.c index c51170e9c1b9..d5157e903e27 100644 --- a/drivers/media/common/videobuf2/videobuf2-dma-sg.c +++ b/drivers/media/common/videobuf2/videobuf2-dma-sg.c @@ -580,6 +580,7 @@ static void vb2_dma_sg_unmap_dmabuf(void *mem_priv) { struct vb2_dma_sg_buf *buf = mem_priv; struct sg_table *sgt = buf->dma_sgt; + struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(buf->vaddr); if (WARN_ON(!buf->db_attach)) { pr_err("trying to unpin a not attached buffer\n"); @@ -592,7 +593,7 @@ static void vb2_dma_sg_unmap_dmabuf(void *mem_priv) } if (buf->vaddr) { - dma_buf_vunmap(buf->db_attach->dmabuf, buf->vaddr); + dma_buf_vunmap(buf->db_attach->dmabuf, &map); buf->vaddr = NULL; } dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir); diff --git a/drivers/media/common/videobuf2/videobuf2-vmalloc.c b/drivers/media/common/videobuf2/videobuf2-vmalloc.c index 7b68e2379c65..11ba0eb1315b 100644 --- a/drivers/media/common/videobuf2/videobuf2-vmalloc.c +++ b/drivers/media/common/videobuf2/videobuf2-vmalloc.c @@ -390,17 +390,19 @@ static int vb2_vmalloc_map_dmabuf(void *mem_priv) static void vb2_vmalloc_unmap_dmabuf(void *mem_priv) { struct vb2_vmalloc_buf *buf = mem_priv; + struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(buf->vaddr); - dma_buf_vunmap(buf->dbuf, buf->vaddr); + dma_buf_vunmap(buf->dbuf, &map); buf->vaddr = NULL; } static void vb2_vmalloc_detach_dmabuf(void *mem_priv) { struct vb2_vmalloc_buf *buf = mem_priv; + struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(buf->vaddr); if (buf->vaddr) - dma_buf_vunmap(buf->dbuf, buf->vaddr); + dma_buf_vunmap(buf->dbuf, &map); kfree(buf); } diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h index 3ee22639ff77..093f760cc131 100644 --- a/include/drm/drm_prime.h +++ b/include/drm/drm_prime.h @@ -84,7 +84,7 @@ void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach, struct sg_table *sgt, enum dma_data_direction dir); int drm_gem_dmabuf_vmap(struct dma_buf *dma_buf, struct dma_buf_map *map); -void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr); +void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, struct dma_buf_map *map); int drm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); int drm_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma); diff --git a/include/linux/dma-buf-map.h b/include/linux/dma-buf-map.h index 5ae732d373eb..c173a4abf4ba 100644 --- a/include/linux/dma-buf-map.h +++ b/include/linux/dma-buf-map.h @@ -23,6 +23,16 @@ struct dma_buf_map { bool is_iomem; }; +/** + * DMA_BUF_MAP_INIT_VADDR - Initializes struct dma_buf_map to an address in system memory + * @vaddr: A system-memory address + */ +#define DMA_BUF_MAP_INIT_VADDR(vaddr_) \ + { \ + .vaddr = (vaddr_), \ + .is_iomem = false, \ + } + /** * dma_buf_map_set_vaddr - Sets a dma-buf mapping structure to an address in system memory * @map: The dma-buf mapping structure @@ -36,10 +46,26 @@ static inline void dma_buf_map_set_vaddr(struct dma_buf_map *map, void *vaddr) map->is_iomem = false; } -/* API transition helper */ -static inline bool dma_buf_map_is_vaddr(const struct dma_buf_map *map, const void *vaddr) +/** + * dma_buf_map_is_equal - Compares two dma-buf mapping structures for equality + * @lhs: The dma-buf mapping structure + * @rhs: A dma-buf mapping structure to compare with + * + * Two dma-buf mapping structures are equal if they both refer to the same type of memory + * and to the same address within that memory. + * + * Returns: + * True is both structures are equal, or false otherwise. + */ +static inline bool dma_buf_map_is_equal(const struct dma_buf_map *lhs, + const struct dma_buf_map *rhs) { - return !map->is_iomem && (map->vaddr == vaddr); + if (lhs->is_iomem != rhs->is_iomem) + return false; + else if (lhs->is_iomem) + return lhs->vaddr_iomem == rhs->vaddr_iomem; + else + return lhs->vaddr == rhs->vaddr; } /** diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index 7237997cfa38..cf77cc15f4ba 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -267,7 +267,7 @@ struct dma_buf_ops { int (*mmap)(struct dma_buf *, struct vm_area_struct *vma); int (*vmap)(struct dma_buf *dmabuf, struct dma_buf_map *map); - void (*vunmap)(struct dma_buf *, void *vaddr); + void (*vunmap)(struct dma_buf *dmabuf, struct dma_buf_map *map); }; /** @@ -504,5 +504,5 @@ int dma_buf_end_cpu_access(struct dma_buf *dma_buf, int dma_buf_mmap(struct dma_buf *, struct vm_area_struct *, unsigned long); int dma_buf_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map); -void dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr); +void dma_buf_vunmap(struct dma_buf *dmabuf, struct dma_buf_map *map); #endif /* __DMA_BUF_H__ */ From ccc22d41bd9acec58cdc7c3b012e1887aba40af4 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Fri, 25 Sep 2020 13:56:01 +0200 Subject: [PATCH 106/235] dma-buf: Document struct dma_buf_map MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds struct dma_buf_map and its helpers to the documentation. A short tutorial is included. v3: * update documentation in a separate patch * expand docs (Daniel) * carry-over acks from patch 1 Signed-off-by: Thomas Zimmermann Reviewed-by: Christian König Reviewed-by: Daniel Vetter Acked-by: Sumit Semwal Link: https://patchwork.freedesktop.org/patch/msgid/20200925115601.23955-5-tzimmermann@suse.de --- Documentation/driver-api/dma-buf.rst | 9 ++++ include/linux/dma-buf-map.h | 72 ++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/Documentation/driver-api/dma-buf.rst b/Documentation/driver-api/dma-buf.rst index 13ea0cc0a3fa..6dbcc4714b0b 100644 --- a/Documentation/driver-api/dma-buf.rst +++ b/Documentation/driver-api/dma-buf.rst @@ -115,6 +115,15 @@ Kernel Functions and Structures Reference .. kernel-doc:: include/linux/dma-buf.h :internal: +Buffer Mapping Helpers +~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: include/linux/dma-buf-map.h + :doc: overview + +.. kernel-doc:: include/linux/dma-buf-map.h + :internal: + Reservation Objects ------------------- diff --git a/include/linux/dma-buf-map.h b/include/linux/dma-buf-map.h index c173a4abf4ba..fd1aba545fdf 100644 --- a/include/linux/dma-buf-map.h +++ b/include/linux/dma-buf-map.h @@ -8,6 +8,78 @@ #include +/** + * DOC: overview + * + * Calling dma-buf's vmap operation returns a pointer to the buffer's memory. + * Depending on the location of the buffer, users may have to access it with + * I/O operations or memory load/store operations. For example, copying to + * system memory could be done with memcpy(), copying to I/O memory would be + * done with memcpy_toio(). + * + * .. code-block:: c + * + * void *vaddr = ...; // pointer to system memory + * memcpy(vaddr, src, len); + * + * void *vaddr_iomem = ...; // pointer to I/O memory + * memcpy_toio(vaddr, _iomem, src, len); + * + * When using dma-buf's vmap operation, the returned pointer is encoded as + * :c:type:`struct dma_buf_map `. + * :c:type:`struct dma_buf_map ` stores the buffer's address in + * system or I/O memory and a flag that signals the required method of + * accessing the buffer. Use the returned instance and the helper functions + * to access the buffer's memory in the correct way. + * + * Open-coding access to :c:type:`struct dma_buf_map ` is + * considered bad style. Rather then accessing its fields directly, use one + * of the provided helper functions, or implement your own. For example, + * instances of :c:type:`struct dma_buf_map ` can be initialized + * statically with DMA_BUF_MAP_INIT_VADDR(), or at runtime with + * dma_buf_map_set_vaddr(). These helpers will set an address in system memory. + * + * .. code-block:: c + * + * struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(0xdeadbeaf); + * + * dma_buf_map_set_vaddr(&map. 0xdeadbeaf); + * + * Test if a mapping is valid with either dma_buf_map_is_set() or + * dma_buf_map_is_null(). + * + * .. code-block:: c + * + * if (dma_buf_map_is_set(&map) != dma_buf_map_is_null(&map)) + * // always true + * + * Instances of :c:type:`struct dma_buf_map ` can be compared + * for equality with dma_buf_map_is_equal(). Mappings the point to different + * memory spaces, system or I/O, are never equal. That's even true if both + * spaces are located in the same address space, both mappings contain the + * same address value, or both mappings refer to NULL. + * + * .. code-block:: c + * + * struct dma_buf_map sys_map; // refers to system memory + * struct dma_buf_map io_map; // refers to I/O memory + * + * if (dma_buf_map_is_equal(&sys_map, &io_map)) + * // always false + * + * Instances of struct dma_buf_map do not have to be cleaned up, but + * can be cleared to NULL with dma_buf_map_clear(). Cleared mappings + * always refer to system memory. + * + * The type :c:type:`struct dma_buf_map ` and its helpers are + * actually independent from the dma-buf infrastructure. When sharing buffers + * among devices, drivers have to know the location of the memory to access + * the buffers in a safe way. :c:type:`struct dma_buf_map ` + * solves this problem for dma-buf and its users. If other drivers or + * sub-systems require similar functionality, the type could be generalized + * and moved to a more prominent header file. + */ + /** * struct dma_buf_map - Pointer to vmap'ed dma-buf memory. * @vaddr_iomem: The buffer's address if in I/O memory From 369a7210c12775afec57769efbe462f0feda2c60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 29 Sep 2020 13:21:26 +0200 Subject: [PATCH 107/235] drm/qxl: fix usage of ttm_bo_init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to use ttm_bo_init_reserved here to make sure that the BO is pinned before it becomes visible on the LRU. Signed-off-by: Christian König Reviewed-by: Daniel Vetter Reviewed-by: Gerd Hoffmann Tested-by: Gerd Hoffmann Link: https://patchwork.freedesktop.org/patch/392561/?series=82199&rev=1 --- drivers/gpu/drm/qxl/qxl_object.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c index d3635e3e3267..c8b67e7a3f02 100644 --- a/drivers/gpu/drm/qxl/qxl_object.c +++ b/drivers/gpu/drm/qxl/qxl_object.c @@ -106,6 +106,7 @@ int qxl_bo_create(struct qxl_device *qdev, struct qxl_surface *surf, struct qxl_bo **bo_ptr) { + struct ttm_operation_ctx ctx = { !kernel, false }; struct qxl_bo *bo; enum ttm_bo_type type; int r; @@ -134,9 +135,9 @@ int qxl_bo_create(struct qxl_device *qdev, qxl_ttm_placement_from_domain(bo, domain); - r = ttm_bo_init(&qdev->mman.bdev, &bo->tbo, size, type, - &bo->placement, 0, !kernel, size, - NULL, NULL, &qxl_ttm_bo_destroy); + r = ttm_bo_init_reserved(&qdev->mman.bdev, &bo->tbo, size, type, + &bo->placement, 0, &ctx, size, + NULL, NULL, &qxl_ttm_bo_destroy); if (unlikely(r != 0)) { if (r != -ERESTARTSYS) dev_err(qdev->ddev.dev, @@ -146,6 +147,7 @@ int qxl_bo_create(struct qxl_device *qdev, } if (pinned) ttm_bo_pin(&bo->tbo); + ttm_bo_unreserve(&bo->tbo); *bo_ptr = bo; return 0; } From cbdbdd8ab22b4bf2571f313ea627cfc3a04cb02f Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 29 Sep 2020 17:03:33 +0200 Subject: [PATCH 108/235] drm: update todo.rst - debugfs cleanup has moved forward thanks to the cleanup Wambui has done Acked-by: Melissa Wen Reviewed-by: Greg Kroah-Hartman Cc: Wambui Karuga Cc: Greg Kroah-Hartman Cc: Melissa Wen Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20200929150333.3441576-1-daniel.vetter@ffwll.ch --- Documentation/gpu/todo.rst | 3 --- 1 file changed, 3 deletions(-) diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 3751ac976c3e..700637e25ecd 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -515,9 +515,6 @@ There's a bunch of issues with it: this (together with the drm_minor->drm_device move) would allow us to remove debugfs_init. -- Drop the return code and error checking from all debugfs functions. Greg KH is - working on this already. - Contact: Daniel Vetter Level: Intermediate From c7a399271de0a3f9a81e4f84c52f0c3bfe3ae117 Mon Sep 17 00:00:00 2001 From: Tian Tao Date: Mon, 28 Sep 2020 16:49:38 +0800 Subject: [PATCH 109/235] drm/hisilicon: Using the to_hibmc_drm_private to convert Using the to_hibmc_drm_private to convert over all uses of dev_private, and fix a little formatting issue. v2: fixed the commit message. Signed-off-by: Tian Tao Reviewed-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/1601282978-45534-1-git-send-email-tiantao6@hisilicon.com --- .../gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 22 +++++++++---------- .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 5 ++--- .../gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 4 ++-- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c index 4d57ec688f82..a98f9936eec2 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c @@ -105,7 +105,7 @@ static void hibmc_plane_atomic_update(struct drm_plane *plane, u32 reg; s64 gpu_addr = 0; unsigned int line_l; - struct hibmc_drm_private *priv = plane->dev->dev_private; + struct hibmc_drm_private *priv = to_hibmc_drm_private(plane->dev); struct drm_gem_vram_object *gbo; if (!state->fb) @@ -159,7 +159,7 @@ static const struct drm_plane_helper_funcs hibmc_plane_helper_funcs = { static void hibmc_crtc_dpms(struct drm_crtc *crtc, int dpms) { - struct hibmc_drm_private *priv = crtc->dev->dev_private; + struct hibmc_drm_private *priv = to_hibmc_drm_private(crtc->dev); unsigned int reg; reg = readl(priv->mmio + HIBMC_CRT_DISP_CTL); @@ -175,7 +175,7 @@ static void hibmc_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) { unsigned int reg; - struct hibmc_drm_private *priv = crtc->dev->dev_private; + struct hibmc_drm_private *priv = to_hibmc_drm_private(crtc->dev); hibmc_set_power_mode(priv, HIBMC_PW_MODE_CTL_MODE_MODE0); @@ -194,7 +194,7 @@ static void hibmc_crtc_atomic_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) { unsigned int reg; - struct hibmc_drm_private *priv = crtc->dev->dev_private; + struct hibmc_drm_private *priv = to_hibmc_drm_private(crtc->dev); hibmc_crtc_dpms(crtc, HIBMC_CRT_DPMS_OFF); drm_crtc_vblank_off(crtc); @@ -254,7 +254,7 @@ static unsigned int format_pll_reg(void) static void set_vclock_hisilicon(struct drm_device *dev, unsigned long pll) { u32 val; - struct hibmc_drm_private *priv = dev->dev_private; + struct hibmc_drm_private *priv = to_hibmc_drm_private(dev); val = readl(priv->mmio + CRT_PLL1_HS); val &= ~(CRT_PLL1_HS_OUTER_BYPASS(1)); @@ -315,7 +315,7 @@ static unsigned int display_ctrl_adjust(struct drm_device *dev, unsigned long x, y; u32 pll1; /* bit[31:0] of PLL */ u32 pll2; /* bit[63:32] of PLL */ - struct hibmc_drm_private *priv = dev->dev_private; + struct hibmc_drm_private *priv = to_hibmc_drm_private(dev); x = mode->hdisplay; y = mode->vdisplay; @@ -363,7 +363,7 @@ static void hibmc_crtc_mode_set_nofb(struct drm_crtc *crtc) unsigned int val; struct drm_display_mode *mode = &crtc->state->mode; struct drm_device *dev = crtc->dev; - struct hibmc_drm_private *priv = dev->dev_private; + struct hibmc_drm_private *priv = to_hibmc_drm_private(dev); int width = mode->hsync_end - mode->hsync_start; int height = mode->vsync_end - mode->vsync_start; @@ -397,7 +397,7 @@ static void hibmc_crtc_atomic_begin(struct drm_crtc *crtc, { unsigned int reg; struct drm_device *dev = crtc->dev; - struct hibmc_drm_private *priv = dev->dev_private; + struct hibmc_drm_private *priv = to_hibmc_drm_private(dev); hibmc_set_power_mode(priv, HIBMC_PW_MODE_CTL_MODE_MODE0); @@ -427,7 +427,7 @@ static void hibmc_crtc_atomic_flush(struct drm_crtc *crtc, static int hibmc_crtc_enable_vblank(struct drm_crtc *crtc) { - struct hibmc_drm_private *priv = crtc->dev->dev_private; + struct hibmc_drm_private *priv = to_hibmc_drm_private(crtc->dev); writel(HIBMC_RAW_INTERRUPT_EN_VBLANK(1), priv->mmio + HIBMC_RAW_INTERRUPT_EN); @@ -437,7 +437,7 @@ static int hibmc_crtc_enable_vblank(struct drm_crtc *crtc) static void hibmc_crtc_disable_vblank(struct drm_crtc *crtc) { - struct hibmc_drm_private *priv = crtc->dev->dev_private; + struct hibmc_drm_private *priv = to_hibmc_drm_private(crtc->dev); writel(HIBMC_RAW_INTERRUPT_EN_VBLANK(0), priv->mmio + HIBMC_RAW_INTERRUPT_EN); @@ -445,7 +445,7 @@ static void hibmc_crtc_disable_vblank(struct drm_crtc *crtc) static void hibmc_crtc_load_lut(struct drm_crtc *crtc) { - struct hibmc_drm_private *priv = crtc->dev->dev_private; + struct hibmc_drm_private *priv = to_hibmc_drm_private(crtc->dev); void __iomem *mmio = priv->mmio; u16 *r, *g, *b; unsigned int reg; diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index 085d1b2fa8c0..5632bcea791e 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -29,8 +29,7 @@ DEFINE_DRM_GEM_FOPS(hibmc_fops); static irqreturn_t hibmc_drm_interrupt(int irq, void *arg) { struct drm_device *dev = (struct drm_device *)arg; - struct hibmc_drm_private *priv = - (struct hibmc_drm_private *)dev->dev_private; + struct hibmc_drm_private *priv = to_hibmc_drm_private(dev); u32 status; status = readl(priv->mmio + HIBMC_RAW_INTERRUPT); @@ -244,7 +243,7 @@ static int hibmc_hw_init(struct hibmc_drm_private *priv) static int hibmc_unload(struct drm_device *dev) { - struct hibmc_drm_private *priv = dev->dev_private; + struct hibmc_drm_private *priv = to_hibmc_drm_private(dev); drm_atomic_helper_shutdown(dev); diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c index c6999ed702aa..74e26c27d878 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c @@ -43,7 +43,7 @@ out: } static enum drm_mode_status hibmc_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) + struct drm_display_mode *mode) { return MODE_OK; } @@ -76,7 +76,7 @@ static void hibmc_encoder_mode_set(struct drm_encoder *encoder, { u32 reg; struct drm_device *dev = encoder->dev; - struct hibmc_drm_private *priv = dev->dev_private; + struct hibmc_drm_private *priv = to_hibmc_drm_private(dev); reg = readl(priv->mmio + HIBMC_DISPLAY_CONTROL_HISILE); reg |= HIBMC_DISPLAY_CONTROL_FPVDDEN(1); From 4f8cc7a64af4c14ff222c2f9bab4f1ad2ddeb881 Mon Sep 17 00:00:00 2001 From: Tian Tao Date: Tue, 29 Sep 2020 08:45:26 +0800 Subject: [PATCH 110/235] drm/hisilicon: Delete the unused macro The macro PADDING is no longer used. Delete it. Signed-off-by: Tian Tao Reviewed-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/1601340326-14049-1-git-send-email-tiantao6@hisilicon.com --- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c index a98f9936eec2..a3a9e0a73a08 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c @@ -52,8 +52,6 @@ static const struct hibmc_dislay_pll_config hibmc_pll_table[] = { {1920, 1200, CRT_PLL1_HS_193MHZ, CRT_PLL2_HS_193MHZ}, }; -#define PADDING(align, data) (((data) + (align) - 1) & (~((align) - 1))) - static int hibmc_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) { From 91e515c2f0f68d4ce137c9182eb03af4858f362e Mon Sep 17 00:00:00 2001 From: Alistair Delva Date: Tue, 29 Sep 2020 14:53:33 -0700 Subject: [PATCH 111/235] virtio-gpu api: fix 64/32 compat issue with blob implementation We encountered this issue when booting blob with a 32-bit kernel. The implementation doesn't match v6 of the virtio-spec change, so fix this. Fixes: ff886cbdcc44 ("virtio-gpu api: blob resources") Signed-off-by: Alistair Delva Link: http://patchwork.freedesktop.org/patch/msgid/20200929215333.1241-1-gurchetansingh@chromium.org Signed-off-by: Gerd Hoffmann --- include/uapi/linux/virtio_gpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h index fa2ae4a1da5f..0ec6b610402c 100644 --- a/include/uapi/linux/virtio_gpu.h +++ b/include/uapi/linux/virtio_gpu.h @@ -388,9 +388,9 @@ struct virtio_gpu_resource_create_blob { /* zero is invalid blob mem */ __le32 blob_mem; __le32 blob_flags; + __le32 nr_entries; __le64 blob_id; __le64 size; - __le32 nr_entries; /* * sizeof(nr_entries * virtio_gpu_mem_entry) bytes follow */ From 291e8cdd6bc57658035239315d27f3f971ec062b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 24 Sep 2020 13:25:30 +0200 Subject: [PATCH 112/235] MAINTAINERS: mark FRAMEBUFFER LAYER as Orphan It has been a fun ride since 2017 but unfortunately I don't have enough time to look after it properly anymore. Reviewed-by: Daniel Vetter Acked-by: Sam Ravnborg Signed-off-by: Bartlomiej Zolnierkiewicz Link: https://patchwork.freedesktop.org/patch/msgid/7b709254-9412-8473-250c-0c4e006259b3@samsung.com --- MAINTAINERS | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 10992f6541bd..1c4dc5c42c3d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6875,10 +6875,9 @@ F: drivers/net/wan/dlci.c F: drivers/net/wan/sdla.c FRAMEBUFFER LAYER -M: Bartlomiej Zolnierkiewicz L: dri-devel@lists.freedesktop.org L: linux-fbdev@vger.kernel.org -S: Maintained +S: Orphan Q: http://patchwork.kernel.org/project/linux-fbdev/list/ T: git git://anongit.freedesktop.org/drm/drm-misc F: Documentation/fb/ From 3c4641d4e75618fa1b5501b9ae9c19f765d75725 Mon Sep 17 00:00:00 2001 From: Qinglang Miao Date: Mon, 21 Sep 2020 21:10:19 +0800 Subject: [PATCH 113/235] drm/panfrost: simplify the return expression of cz_ih_hw_init() Simplify the return expression. Signed-off-by: Qinglang Miao Reviewed-by: Philipp Zabel Reviewed-by: Steven Price Signed-off-by: Steven Price Link: https://patchwork.freedesktop.org/patch/msgid/20200921131019.91558-1-miaoqinglang@huawei.com --- drivers/gpu/drm/panfrost/panfrost_device.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c index e6896733838a..ea8d31863c50 100644 --- a/drivers/gpu/drm/panfrost/panfrost_device.c +++ b/drivers/gpu/drm/panfrost/panfrost_device.c @@ -18,19 +18,13 @@ static int panfrost_reset_init(struct panfrost_device *pfdev) { - int err; - pfdev->rstc = devm_reset_control_array_get(pfdev->dev, false, true); if (IS_ERR(pfdev->rstc)) { dev_err(pfdev->dev, "get reset failed %ld\n", PTR_ERR(pfdev->rstc)); return PTR_ERR(pfdev->rstc); } - err = reset_control_deassert(pfdev->rstc); - if (err) - return err; - - return 0; + return reset_control_deassert(pfdev->rstc); } static void panfrost_reset_fini(struct panfrost_device *pfdev) From 0c5036590bde1407a6250ea027e836815353820f Mon Sep 17 00:00:00 2001 From: Qinglang Miao Date: Mon, 21 Sep 2020 21:10:21 +0800 Subject: [PATCH 114/235] drm/panfrost: simplify the return expression of panfrost_devfreq_target() Simplify the return expression. Signed-off-by: Qinglang Miao Reviewed-by: Steven Price Signed-off-by: Steven Price Link: https://patchwork.freedesktop.org/patch/msgid/20200921131021.91604-1-miaoqinglang@huawei.com --- drivers/gpu/drm/panfrost/panfrost_devfreq.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c index 8ab025d0035f..913eaa6d0bc6 100644 --- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c +++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c @@ -29,18 +29,13 @@ static int panfrost_devfreq_target(struct device *dev, unsigned long *freq, u32 flags) { struct dev_pm_opp *opp; - int err; opp = devfreq_recommended_opp(dev, freq, flags); if (IS_ERR(opp)) return PTR_ERR(opp); dev_pm_opp_put(opp); - err = dev_pm_opp_set_rate(dev, *freq); - if (err) - return err; - - return 0; + return dev_pm_opp_set_rate(dev, *freq); } static void panfrost_devfreq_reset(struct panfrost_devfreq *pfdevfreq) From bd1fbef7bd752d127996445da8b0453c93fa25dc Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 2 Oct 2020 09:56:20 +0200 Subject: [PATCH 115/235] drm/atomic: Make the kerneldoc a bit clearer Crank up the warning a notch and point at the right set of locking functions for atomic drivers. Acked-by: Maxime Ripard Signed-off-by: Daniel Vetter Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann Cc: David Airlie Cc: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20201002075620.4157591-1-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_atomic.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 58527f151984..2ba729eec451 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1613,11 +1613,11 @@ static void __drm_state_dump(struct drm_device *dev, struct drm_printer *p, * to dmesg in case of error irq's. (Hint, you probably want to * ratelimit this!) * - * The caller must drm_modeset_lock_all(), or if this is called - * from error irq handler, it should not be enabled by default. - * (Ie. if you are debugging errors you might not care that this - * is racey. But calling this without all modeset locks held is - * not inherently safe.) + * The caller must wrap this drm_modeset_lock_all_ctx() and + * drm_modeset_drop_locks(). If this is called from error irq handler, it should + * not be enabled by default - if you are debugging errors you might + * not care that this is racey, but calling this without all modeset locks held + * is inherently unsafe. */ void drm_state_dump(struct drm_device *dev, struct drm_printer *p) { From 21271d41a67c2ffb9afe1b0741dd042acff7a0f8 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Sun, 4 Oct 2020 16:17:58 +0200 Subject: [PATCH 116/235] Revert "gpu/drm: ingenic: Add option to mmap GEM buffers cached" This reverts commit 37054fc81443 ("gpu/drm: ingenic: Add option to mmap GEM buffers cached") At the very moment this commit was created, the DMA API it relied on was modified in the DMA tree, which caused the driver to break in linux-next. Revert it for now, and it will be resubmitted later to work with the new DMA API. Signed-off-by: Paul Cercueil Acked-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20201004141758.1013317-1-paul@crapouillou.net --- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 114 +--------------------- drivers/gpu/drm/ingenic/ingenic-drm.h | 4 - drivers/gpu/drm/ingenic/ingenic-ipu.c | 12 +-- 3 files changed, 4 insertions(+), 126 deletions(-) diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index 0225dc1f5eb8..7d8b0ad52979 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -9,8 +9,6 @@ #include #include #include -#include -#include #include #include #include @@ -24,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -100,11 +97,6 @@ struct ingenic_drm { struct notifier_block clock_nb; }; -static bool ingenic_drm_cached_gem_buf; -module_param_named(cached_gem_buffers, ingenic_drm_cached_gem_buf, bool, 0400); -MODULE_PARM_DESC(cached_gem_buffers, - "Enable fully cached GEM buffers [default=false]"); - static bool ingenic_drm_writeable_reg(struct device *dev, unsigned int reg) { switch (reg) { @@ -402,8 +394,6 @@ static int ingenic_drm_plane_atomic_check(struct drm_plane *plane, plane->state->fb->format->format != state->fb->format->format)) crtc_state->mode_changed = true; - drm_atomic_helper_check_plane_damage(state->state, state); - return 0; } @@ -521,38 +511,6 @@ void ingenic_drm_plane_config(struct device *dev, } } -void ingenic_drm_sync_data(struct device *dev, - struct drm_plane_state *old_state, - struct drm_plane_state *state) -{ - const struct drm_format_info *finfo = state->fb->format; - struct ingenic_drm *priv = dev_get_drvdata(dev); - struct drm_atomic_helper_damage_iter iter; - unsigned int offset, i; - struct drm_rect clip; - dma_addr_t paddr; - void *addr; - - if (!ingenic_drm_cached_gem_buf) - return; - - drm_atomic_helper_damage_iter_init(&iter, old_state, state); - - drm_atomic_for_each_plane_damage(&iter, &clip) { - for (i = 0; i < finfo->num_planes; i++) { - paddr = drm_fb_cma_get_gem_addr(state->fb, state, i); - addr = phys_to_virt(paddr); - - /* Ignore x1/x2 values, invalidate complete lines */ - offset = clip.y1 * state->fb->pitches[i]; - - dma_cache_sync(priv->dev, addr + offset, - (clip.y2 - clip.y1) * state->fb->pitches[i], - DMA_TO_DEVICE); - } - } -} - static void ingenic_drm_update_palette(struct ingenic_drm *priv, const struct drm_color_lut *lut) { @@ -581,8 +539,6 @@ static void ingenic_drm_plane_atomic_update(struct drm_plane *plane, if (state && state->fb) { crtc_state = state->crtc->state; - ingenic_drm_sync_data(priv->dev, oldstate, state); - addr = drm_fb_cma_get_gem_addr(state->fb, state, 0); width = state->src_w >> 16; height = state->src_h >> 16; @@ -752,69 +708,7 @@ static void ingenic_drm_disable_vblank(struct drm_crtc *crtc) regmap_update_bits(priv->map, JZ_REG_LCD_CTRL, JZ_LCD_CTRL_EOF_IRQ, 0); } -static struct drm_framebuffer * -ingenic_drm_gem_fb_create(struct drm_device *dev, struct drm_file *file, - const struct drm_mode_fb_cmd2 *mode_cmd) -{ - if (ingenic_drm_cached_gem_buf) - return drm_gem_fb_create_with_dirty(dev, file, mode_cmd); - - return drm_gem_fb_create(dev, file, mode_cmd); -} - -static int ingenic_drm_gem_mmap(struct drm_gem_object *obj, - struct vm_area_struct *vma) -{ - struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(obj); - struct device *dev = cma_obj->base.dev->dev; - unsigned long attrs; - int ret; - - if (ingenic_drm_cached_gem_buf) - attrs = DMA_ATTR_NON_CONSISTENT; - else - attrs = DMA_ATTR_WRITE_COMBINE; - - /* - * Clear the VM_PFNMAP flag that was set by drm_gem_mmap(), and set the - * vm_pgoff (used as a fake buffer offset by DRM) to 0 as we want to map - * the whole buffer. - */ - vma->vm_flags &= ~VM_PFNMAP; - vma->vm_pgoff = 0; - vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); - - ret = dma_mmap_attrs(dev, vma, cma_obj->vaddr, cma_obj->paddr, - vma->vm_end - vma->vm_start, attrs); - if (ret) - drm_gem_vm_close(vma); - - return ret; -} - -static int ingenic_drm_gem_cma_mmap(struct file *filp, - struct vm_area_struct *vma) -{ - int ret; - - ret = drm_gem_mmap(filp, vma); - if (ret) - return ret; - - return ingenic_drm_gem_mmap(vma->vm_private_data, vma); -} - -static const struct file_operations ingenic_drm_fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .unlocked_ioctl = drm_ioctl, - .compat_ioctl = drm_compat_ioctl, - .poll = drm_poll, - .read = drm_read, - .llseek = noop_llseek, - .mmap = ingenic_drm_gem_cma_mmap, -}; +DEFINE_DRM_GEM_CMA_FOPS(ingenic_drm_fops); static struct drm_driver ingenic_drm_driver_data = { .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, @@ -878,7 +772,7 @@ static const struct drm_encoder_helper_funcs ingenic_drm_encoder_helper_funcs = }; static const struct drm_mode_config_funcs ingenic_drm_mode_config_funcs = { - .fb_create = ingenic_drm_gem_fb_create, + .fb_create = drm_gem_fb_create, .output_poll_changed = drm_fb_helper_output_poll_changed, .atomic_check = drm_atomic_helper_check, .atomic_commit = drm_atomic_helper_commit, @@ -1032,8 +926,6 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) return ret; } - drm_plane_enable_fb_damage_clips(&priv->f1); - drm_crtc_helper_add(&priv->crtc, &ingenic_drm_crtc_helper_funcs); ret = drm_crtc_init_with_planes(drm, &priv->crtc, &priv->f1, @@ -1062,8 +954,6 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) return ret; } - drm_plane_enable_fb_damage_clips(&priv->f0); - if (IS_ENABLED(CONFIG_DRM_INGENIC_IPU) && has_components) { ret = component_bind_all(dev, drm); if (ret) { diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.h b/drivers/gpu/drm/ingenic/ingenic-drm.h index ee3a892c0383..9b48ce02803d 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm.h +++ b/drivers/gpu/drm/ingenic/ingenic-drm.h @@ -171,10 +171,6 @@ void ingenic_drm_plane_config(struct device *dev, struct drm_plane *plane, u32 fourcc); void ingenic_drm_plane_disable(struct device *dev, struct drm_plane *plane); -void ingenic_drm_sync_data(struct device *dev, - struct drm_plane_state *old_state, - struct drm_plane_state *state); - extern struct platform_driver *ingenic_ipu_driver_ptr; #endif /* DRIVERS_GPU_DRM_INGENIC_INGENIC_DRM_H */ diff --git a/drivers/gpu/drm/ingenic/ingenic-ipu.c b/drivers/gpu/drm/ingenic/ingenic-ipu.c index 38c83e8cc6a5..fc8c6e970ee3 100644 --- a/drivers/gpu/drm/ingenic/ingenic-ipu.c +++ b/drivers/gpu/drm/ingenic/ingenic-ipu.c @@ -20,7 +20,6 @@ #include #include -#include #include #include #include @@ -317,8 +316,6 @@ static void ingenic_ipu_plane_atomic_update(struct drm_plane *plane, JZ_IPU_CTRL_CHIP_EN | JZ_IPU_CTRL_LCDC_SEL); } - ingenic_drm_sync_data(ipu->master, oldstate, state); - /* New addresses will be committed in vblank handler... */ ipu->addr_y = drm_fb_cma_get_gem_addr(state->fb, state, 0); if (finfo->num_planes > 1) @@ -537,7 +534,7 @@ static int ingenic_ipu_plane_atomic_check(struct drm_plane *plane, if (!state->crtc || !crtc_state->mode.hdisplay || !crtc_state->mode.vdisplay) - goto out_check_damage; + return 0; /* Plane must be fully visible */ if (state->crtc_x < 0 || state->crtc_y < 0 || @@ -554,7 +551,7 @@ static int ingenic_ipu_plane_atomic_check(struct drm_plane *plane, return -EINVAL; if (!osd_changed(state, plane->state)) - goto out_check_damage; + return 0; crtc_state->mode_changed = true; @@ -581,9 +578,6 @@ static int ingenic_ipu_plane_atomic_check(struct drm_plane *plane, ipu->denom_w = denom_w; ipu->denom_h = denom_h; -out_check_damage: - drm_atomic_helper_check_plane_damage(state->state, state); - return 0; } @@ -765,8 +759,6 @@ static int ingenic_ipu_bind(struct device *dev, struct device *master, void *d) return err; } - drm_plane_enable_fb_damage_clips(plane); - /* * Sharpness settings range is [0,32] * 0 : nearest-neighbor From 6468f234d32d1f2bafc42c3b655108683089b1f8 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 16 Sep 2020 16:10:08 +0300 Subject: [PATCH 117/235] dt-bindings: display: ti,am65x-dss: add missing properties to dt-schema Add assigned-clocks, assigned-clock-parents and dma-coherent optional properties. Signed-off-by: Tomi Valkeinen Reviewed-by: Rob Herring Link: https://patchwork.freedesktop.org/patch/msgid/20200916131009.221252-2-tomi.valkeinen@ti.com --- .../devicetree/bindings/display/ti/ti,am65x-dss.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml index 4f9185462ed3..4dc30738ee57 100644 --- a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml +++ b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml @@ -55,6 +55,14 @@ properties: - const: vp1 - const: vp2 + assigned-clocks: + minItems: 1 + maxItems: 3 + + assigned-clock-parents: + minItems: 1 + maxItems: 3 + interrupts: maxItems: 1 @@ -62,6 +70,9 @@ properties: maxItems: 1 description: phandle to the associated power domain + dma-coherent: + type: boolean + ports: type: object description: From a10563c89a721a39cd30dac2d283679ef46e4cad Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 16 Sep 2020 16:10:09 +0300 Subject: [PATCH 118/235] dt-bindings: display: ti,j721e-dss: add missing properties to dt-schema Add assigned-clocks, assigned-clock-parents and dma-coherent optional properties. Signed-off-by: Tomi Valkeinen Reviewed-by: Rob Herring Link: https://patchwork.freedesktop.org/patch/msgid/20200916131009.221252-3-tomi.valkeinen@ti.com --- .../devicetree/bindings/display/ti/ti,j721e-dss.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Documentation/devicetree/bindings/display/ti/ti,j721e-dss.yaml b/Documentation/devicetree/bindings/display/ti/ti,j721e-dss.yaml index 173730d56334..c9a947d55fa4 100644 --- a/Documentation/devicetree/bindings/display/ti/ti,j721e-dss.yaml +++ b/Documentation/devicetree/bindings/display/ti/ti,j721e-dss.yaml @@ -77,6 +77,14 @@ properties: - const: vp3 - const: vp4 + assigned-clocks: + minItems: 1 + maxItems: 5 + + assigned-clock-parents: + minItems: 1 + maxItems: 5 + interrupts: items: - description: common_m DSS Master common @@ -95,6 +103,9 @@ properties: maxItems: 1 description: phandle to the associated power domain + dma-coherent: + type: boolean + ports: type: object description: From 01370532b72e954989a3175eabe47f90fc6d2a6b Mon Sep 17 00:00:00 2001 From: Gowtham Tammana Date: Wed, 26 Aug 2020 16:44:09 +0300 Subject: [PATCH 119/235] drm/tidss: Add prepare_fb to the plane helper funcs drm_gem_fb_prepare_fb() extracts fence and attaches to plane state. The fence info is needed if implicit fencing is used. Add this as prepare_fb function pointer to plane helper funcs. Signed-off-by: Gowtham Tammana Signed-off-by: Tomi Valkeinen Reviewed-by: Laurent Pinchart Link: https://patchwork.freedesktop.org/patch/msgid/20200826134409.473554-1-tomi.valkeinen@ti.com --- drivers/gpu/drm/tidss/tidss_plane.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/tidss/tidss_plane.c b/drivers/gpu/drm/tidss/tidss_plane.c index 43e72d0b2d84..35067ae674ea 100644 --- a/drivers/gpu/drm/tidss/tidss_plane.c +++ b/drivers/gpu/drm/tidss/tidss_plane.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "tidss_crtc.h" #include "tidss_dispc.h" @@ -150,6 +151,7 @@ static void drm_plane_destroy(struct drm_plane *plane) } static const struct drm_plane_helper_funcs tidss_plane_helper_funcs = { + .prepare_fb = drm_gem_fb_prepare_fb, .atomic_check = tidss_plane_atomic_check, .atomic_update = tidss_plane_atomic_update, .atomic_disable = tidss_plane_atomic_disable, From 170fb58ee329bcfa8dc4c0c5eab0ea5af7fb7f3b Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Fri, 2 Oct 2020 08:55:18 +0200 Subject: [PATCH 120/235] drm/sched: Avoid infinite waits in the drm_sched_entity_destroy() path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we don't initialize the entity to idle and the entity is never scheduled before being destroyed we end up with an infinite wait in the destroy path. v2: - Add Steven's R-b Signed-off-by: Boris Brezillon Reviewed-by: Steven Price Reviewed-by: Christian König Signed-off-by: Christian König Link: https://patchwork.freedesktop.org/patch/393486/ --- drivers/gpu/drm/scheduler/sched_entity.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index 146380118962..f8ec277a6aa8 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c @@ -73,6 +73,9 @@ int drm_sched_entity_init(struct drm_sched_entity *entity, init_completion(&entity->entity_idle); + /* We start in an idle state. */ + complete(&entity->entity_idle); + spin_lock_init(&entity->rq_lock); spsc_queue_init(&entity->job_queue); From 4e19d51ca5b28a1d435a844c7b2a8e1b1b6fa237 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Sat, 3 Oct 2020 12:39:28 -0700 Subject: [PATCH 121/235] drm/gma500: fix double free of gma_connector clang static analysis reports this problem: cdv_intel_dp.c:2101:2: warning: Attempt to free released memory kfree(gma_connector); ^~~~~~~~~~~~~~~~~~~~ In cdv_intel_dp_init() when the call to cdv_intel_edp_panel_vdd_off() fails, the handler calls cdv_intel_dp_destroy(connector) which does the first free of gma_connector. So adjust the goto label and skip the second free. Fixes: d112a8163f83 ("gma500/cdv: Add eDP support") Signed-off-by: Tom Rix Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20201003193928.18869-1-trix@redhat.com --- drivers/gpu/drm/gma500/cdv_intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/gma500/cdv_intel_dp.c b/drivers/gpu/drm/gma500/cdv_intel_dp.c index 50016a754172..bfd9a15d63b1 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_dp.c +++ b/drivers/gpu/drm/gma500/cdv_intel_dp.c @@ -2082,7 +2082,7 @@ cdv_intel_dp_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev DRM_INFO("failed to retrieve link info, disabling eDP\n"); drm_encoder_cleanup(encoder); cdv_intel_dp_destroy(connector); - goto err_priv; + goto err_connector; } else { DRM_DEBUG_KMS("DPCD: Rev=%x LN_Rate=%x LN_CNT=%x LN_DOWNSP=%x\n", intel_dp->dpcd[0], intel_dp->dpcd[1], From f3d52908f6baffc21ba45058103d0226ca5cb073 Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Sun, 4 Oct 2020 22:06:53 +0200 Subject: [PATCH 122/235] drm: bridge: dw-hdmi: Constify dw_hdmi_i2s_ops The only usage of dw_hdmi_i2s_ops is to assign its address to the ops field in the hdmi_codec_pdata struct, which is a const pointer. Make it const to allow the compiler to put it in read-only memory. Signed-off-by: Rikard Falkeborn Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20201004200653.14702-1-rikard.falkeborn@gmail.com --- drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c index 9fef6413741d..feb04f127b55 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c @@ -170,7 +170,7 @@ static int dw_hdmi_i2s_hook_plugged_cb(struct device *dev, void *data, return dw_hdmi_set_plugged_cb(hdmi, fn, codec_dev); } -static struct hdmi_codec_ops dw_hdmi_i2s_ops = { +static const struct hdmi_codec_ops dw_hdmi_i2s_ops = { .hw_params = dw_hdmi_i2s_hw_params, .audio_startup = dw_hdmi_i2s_audio_startup, .audio_shutdown = dw_hdmi_i2s_audio_shutdown, From dac4ec775aa1cae4ac6d37ae135c862636541e78 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 30 Sep 2020 13:40:42 +0200 Subject: [PATCH 123/235] drm/bridge: tc358764: restore connector support This patch restores DRM connector registration in the TC358764 bridge driver and restores usage of the old drm_panel_* API, thus allows dynamic panel registration. This fixes panel operation on Exynos5250-based Arndale board. This is equivalent to the revert of the following commits: 1644127f83bc "drm/bridge: tc358764: add drm_panel_bridge support" 385ca38da29c "drm/bridge: tc358764: drop drm_connector_(un)register" and removal of the calls to drm_panel_attach()/drm_panel_detach(), which were no-ops and has been removed in meanwhile. Signed-off-by: Marek Szyprowski Reviewed-by: Andrzej Hajda Signed-off-by: Andrzej Hajda Link: https://patchwork.freedesktop.org/patch/msgid/20200930114042.5806-1-m.szyprowski@samsung.com --- drivers/gpu/drm/bridge/tc358764.c | 107 +++++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/bridge/tc358764.c b/drivers/gpu/drm/bridge/tc358764.c index d89394bc5aa4..c1e35bdf9232 100644 --- a/drivers/gpu/drm/bridge/tc358764.c +++ b/drivers/gpu/drm/bridge/tc358764.c @@ -153,9 +153,10 @@ static const char * const tc358764_supplies[] = { struct tc358764 { struct device *dev; struct drm_bridge bridge; + struct drm_connector connector; struct regulator_bulk_data supplies[ARRAY_SIZE(tc358764_supplies)]; struct gpio_desc *gpio_reset; - struct drm_bridge *panel_bridge; + struct drm_panel *panel; int error; }; @@ -209,6 +210,12 @@ static inline struct tc358764 *bridge_to_tc358764(struct drm_bridge *bridge) return container_of(bridge, struct tc358764, bridge); } +static inline +struct tc358764 *connector_to_tc358764(struct drm_connector *connector) +{ + return container_of(connector, struct tc358764, connector); +} + static int tc358764_init(struct tc358764 *ctx) { u32 v = 0; @@ -271,11 +278,43 @@ static void tc358764_reset(struct tc358764 *ctx) usleep_range(1000, 2000); } +static int tc358764_get_modes(struct drm_connector *connector) +{ + struct tc358764 *ctx = connector_to_tc358764(connector); + + return drm_panel_get_modes(ctx->panel, connector); +} + +static const +struct drm_connector_helper_funcs tc358764_connector_helper_funcs = { + .get_modes = tc358764_get_modes, +}; + +static const struct drm_connector_funcs tc358764_connector_funcs = { + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = drm_connector_cleanup, + .reset = drm_atomic_helper_connector_reset, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, +}; + +static void tc358764_disable(struct drm_bridge *bridge) +{ + struct tc358764 *ctx = bridge_to_tc358764(bridge); + int ret = drm_panel_disable(bridge_to_tc358764(bridge)->panel); + + if (ret < 0) + dev_err(ctx->dev, "error disabling panel (%d)\n", ret); +} + static void tc358764_post_disable(struct drm_bridge *bridge) { struct tc358764 *ctx = bridge_to_tc358764(bridge); int ret; + ret = drm_panel_unprepare(ctx->panel); + if (ret < 0) + dev_err(ctx->dev, "error unpreparing panel (%d)\n", ret); tc358764_reset(ctx); usleep_range(10000, 15000); ret = regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); @@ -296,28 +335,71 @@ static void tc358764_pre_enable(struct drm_bridge *bridge) ret = tc358764_init(ctx); if (ret < 0) dev_err(ctx->dev, "error initializing bridge (%d)\n", ret); + ret = drm_panel_prepare(ctx->panel); + if (ret < 0) + dev_err(ctx->dev, "error preparing panel (%d)\n", ret); +} + +static void tc358764_enable(struct drm_bridge *bridge) +{ + struct tc358764 *ctx = bridge_to_tc358764(bridge); + int ret = drm_panel_enable(ctx->panel); + + if (ret < 0) + dev_err(ctx->dev, "error enabling panel (%d)\n", ret); } static int tc358764_attach(struct drm_bridge *bridge, enum drm_bridge_attach_flags flags) { struct tc358764 *ctx = bridge_to_tc358764(bridge); + struct drm_device *drm = bridge->dev; + int ret; - return drm_bridge_attach(bridge->encoder, ctx->panel_bridge, - bridge, flags); + if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) { + DRM_ERROR("Fix bridge driver to make connector optional!"); + return -EINVAL; + } + + ctx->connector.polled = DRM_CONNECTOR_POLL_HPD; + ret = drm_connector_init(drm, &ctx->connector, + &tc358764_connector_funcs, + DRM_MODE_CONNECTOR_LVDS); + if (ret) { + DRM_ERROR("Failed to initialize connector\n"); + return ret; + } + + drm_connector_helper_add(&ctx->connector, + &tc358764_connector_helper_funcs); + drm_connector_attach_encoder(&ctx->connector, bridge->encoder); + ctx->connector.funcs->reset(&ctx->connector); + drm_connector_register(&ctx->connector); + + return 0; +} + +static void tc358764_detach(struct drm_bridge *bridge) +{ + struct tc358764 *ctx = bridge_to_tc358764(bridge); + + drm_connector_unregister(&ctx->connector); + ctx->panel = NULL; + drm_connector_put(&ctx->connector); } static const struct drm_bridge_funcs tc358764_bridge_funcs = { + .disable = tc358764_disable, .post_disable = tc358764_post_disable, + .enable = tc358764_enable, .pre_enable = tc358764_pre_enable, .attach = tc358764_attach, + .detach = tc358764_detach, }; static int tc358764_parse_dt(struct tc358764 *ctx) { - struct drm_bridge *panel_bridge; struct device *dev = ctx->dev; - struct drm_panel *panel; int ret; ctx->gpio_reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); @@ -326,16 +408,12 @@ static int tc358764_parse_dt(struct tc358764 *ctx) return PTR_ERR(ctx->gpio_reset); } - ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL); - if (ret) - return ret; + ret = drm_of_find_panel_or_bridge(ctx->dev->of_node, 1, 0, &ctx->panel, + NULL); + if (ret && ret != -EPROBE_DEFER) + dev_err(dev, "cannot find panel (%d)\n", ret); - panel_bridge = devm_drm_panel_bridge_add(dev, panel); - if (IS_ERR(panel_bridge)) - return PTR_ERR(panel_bridge); - - ctx->panel_bridge = panel_bridge; - return 0; + return ret; } static int tc358764_configure_regulators(struct tc358764 *ctx) @@ -381,7 +459,6 @@ static int tc358764_probe(struct mipi_dsi_device *dsi) return ret; ctx->bridge.funcs = &tc358764_bridge_funcs; - ctx->bridge.type = DRM_MODE_CONNECTOR_LVDS; ctx->bridge.of_node = dev->of_node; drm_bridge_add(&ctx->bridge); From 12b68474e6d550ccbe7c47b8e293b6ef05cea3eb Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 24 Sep 2020 15:18:05 +1000 Subject: [PATCH 124/235] drm/nouveau/ttm: handle ttm moves properly. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The idea is to flip the core over to calling the driver always, so add support for moves here. Signed-off-by: Dave Airlie Acked-by: Christian König Reviewed-by: Ben Skeggs Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20200924051845.397177-6-airlied@gmail.com --- drivers/gpu/drm/nouveau/nouveau_bo.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 1d4b16c0e353..c7f42c4a9395 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1057,6 +1057,18 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, goto out; } + if (old_reg->mem_type == TTM_PL_SYSTEM && + new_reg->mem_type == TTM_PL_TT) { + ttm_bo_move_null(bo, new_reg); + goto out; + } + + if (old_reg->mem_type == TTM_PL_TT && + new_reg->mem_type == TTM_PL_SYSTEM) { + ret = ttm_bo_move_ttm(bo, ctx, new_reg); + goto out; + } + /* Hardware assisted copy. */ if (drm->ttm.move) { if (new_reg->mem_type == TTM_PL_SYSTEM) From 8117713d7804d168f91edebcb498067664c38e6e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 24 Sep 2020 15:18:28 +1000 Subject: [PATCH 125/235] drm/nouveau/ttm: memcpy waits for bo already no need for driver to wait here. Signed-off-by: Dave Airlie Reviewed-by: Ben Skeggs Link: https://patchwork.freedesktop.org/patch/msgid/20200924051845.397177-29-airlied@gmail.com --- drivers/gpu/drm/nouveau/nouveau_bo.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index c7f42c4a9395..0c0ca44a6802 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1085,9 +1085,7 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, } /* Fallback to software copy. */ - ret = ttm_bo_wait_ctx(bo, ctx); - if (ret == 0) - ret = ttm_bo_move_memcpy(bo, ctx, new_reg); + ret = ttm_bo_move_memcpy(bo, ctx, new_reg); out: if (drm->client.device.info.family < NV_DEVICE_INFO_V0_TESLA) { From 881c4117957bc39390930f8344c600858a72179b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 6 Oct 2020 10:06:40 +1000 Subject: [PATCH 126/235] drm/qxl: drop unused code (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v2: drop the wrapper struct Acked-by: Christian König Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20201006000644.1005758-2-airlied@gmail.com --- drivers/gpu/drm/qxl/qxl_ttm.c | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c index 2c35ca4270c6..669bceb58205 100644 --- a/drivers/gpu/drm/qxl/qxl_ttm.c +++ b/drivers/gpu/drm/qxl/qxl_ttm.c @@ -98,19 +98,11 @@ int qxl_ttm_io_mem_reserve(struct ttm_bo_device *bdev, /* * TTM backend functions. */ -struct qxl_ttm_tt { - struct ttm_tt ttm; - struct qxl_device *qdev; - u64 offset; -}; static int qxl_ttm_backend_bind(struct ttm_bo_device *bdev, struct ttm_tt *ttm, struct ttm_resource *bo_mem) { - struct qxl_ttm_tt *gtt = (void *)ttm; - - gtt->offset = (unsigned long)(bo_mem->start << PAGE_SHIFT); if (!ttm->num_pages) { WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n", ttm->num_pages, bo_mem, ttm); @@ -128,29 +120,24 @@ static void qxl_ttm_backend_unbind(struct ttm_bo_device *bdev, static void qxl_ttm_backend_destroy(struct ttm_bo_device *bdev, struct ttm_tt *ttm) { - struct qxl_ttm_tt *gtt = (void *)ttm; - ttm_tt_destroy_common(bdev, ttm); - ttm_tt_fini(>t->ttm); - kfree(gtt); + ttm_tt_fini(ttm); + kfree(ttm); } static struct ttm_tt *qxl_ttm_tt_create(struct ttm_buffer_object *bo, uint32_t page_flags) { - struct qxl_device *qdev; - struct qxl_ttm_tt *gtt; + struct ttm_tt *ttm; - qdev = qxl_get_qdev(bo->bdev); - gtt = kzalloc(sizeof(struct qxl_ttm_tt), GFP_KERNEL); - if (gtt == NULL) + ttm = kzalloc(sizeof(struct ttm_tt), GFP_KERNEL); + if (ttm == NULL) return NULL; - gtt->qdev = qdev; - if (ttm_tt_init(>t->ttm, bo, page_flags)) { - kfree(gtt); + if (ttm_tt_init(ttm, bo, page_flags)) { + kfree(ttm); return NULL; } - return >t->ttm; + return ttm; } static int qxl_bo_move(struct ttm_buffer_object *bo, bool evict, From 279a3010218d517284641b7dac2d65c0ecef78ab Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 6 Oct 2020 10:06:41 +1000 Subject: [PATCH 127/235] drm/vmwgfx: move null mem checks outside move notifies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both fns checked mem == NULL, just move the check outside. Acked-by: Christian König Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20201006000644.1005758-3-airlied@gmail.com --- drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 3 --- drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c | 2 ++ 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c index 9a66ba254326..263d76ae43f0 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c @@ -1192,9 +1192,6 @@ void vmw_bo_move_notify(struct ttm_buffer_object *bo, { struct vmw_buffer_object *vbo; - if (mem == NULL) - return; - /* Make sure @bo is embedded in a struct vmw_buffer_object? */ if (bo->destroy != vmw_bo_bo_free && bo->destroy != vmw_user_bo_destroy) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 5e922d9d5f2c..00b535831a7a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c @@ -867,7 +867,7 @@ void vmw_query_move_notify(struct ttm_buffer_object *bo, mutex_lock(&dev_priv->binding_mutex); dx_query_mob = container_of(bo, struct vmw_buffer_object, base); - if (mem == NULL || !dx_query_mob || !dx_query_mob->dx_query_ctx) { + if (!dx_query_mob || !dx_query_mob->dx_query_ctx) { mutex_unlock(&dev_priv->binding_mutex); return; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c index fc68f54df46a..2f88d2d79f9a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c @@ -707,6 +707,8 @@ static void vmw_move_notify(struct ttm_buffer_object *bo, bool evict, struct ttm_resource *mem) { + if (!mem) + return; vmw_bo_move_notify(bo, mem); vmw_query_move_notify(bo, mem); } From bcff5d3e3bab979d820bbabd3f0be13ae6ce6cf5 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 6 Oct 2020 10:06:42 +1000 Subject: [PATCH 128/235] drm/vmwgfx: add a move callback. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This just copies the fallback to vmwgfx, I'm going to iterate on this a bit until it's not the same as the fallback path. Acked-by: Christian König Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20201006000644.1005758-4-airlied@gmail.com --- drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c index 2f88d2d79f9a..7b5fd5288870 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c @@ -725,6 +725,24 @@ static void vmw_swap_notify(struct ttm_buffer_object *bo) (void) ttm_bo_wait(bo, false, false); } +static int vmw_move(struct ttm_buffer_object *bo, + bool evict, + struct ttm_operation_ctx *ctx, + struct ttm_resource *new_mem) +{ + struct ttm_resource_manager *old_man = ttm_manager_type(bo->bdev, bo->mem.mem_type); + struct ttm_resource_manager *new_man = ttm_manager_type(bo->bdev, new_mem->mem_type); + + if (old_man->use_tt && new_man->use_tt) { + if (bo->mem.mem_type == TTM_PL_SYSTEM) { + ttm_bo_assign_mem(bo, new_mem); + return 0; + } + return ttm_bo_move_ttm(bo, ctx, new_mem); + } else { + return ttm_bo_move_memcpy(bo, ctx, new_mem); + } +} struct ttm_bo_driver vmw_bo_driver = { .ttm_tt_create = &vmw_ttm_tt_create, @@ -735,7 +753,7 @@ struct ttm_bo_driver vmw_bo_driver = { .ttm_tt_destroy = &vmw_ttm_destroy, .eviction_valuable = ttm_bo_eviction_valuable, .evict_flags = vmw_evict_flags, - .move = NULL, + .move = vmw_move, .verify_access = vmw_verify_access, .move_notify = vmw_move_notify, .swap_notify = vmw_swap_notify, From 2b8283ff1a60d201e92f0d48c4918a035dbe82fe Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 6 Oct 2020 10:06:43 +1000 Subject: [PATCH 129/235] drm/vram_helper: implement a ttm move callback. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will always do memcpy moves. Acked-by: Christian König Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20201006000644.1005758-5-airlied@gmail.com --- drivers/gpu/drm/drm_gem_vram_helper.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c b/drivers/gpu/drm/drm_gem_vram_helper.c index 3fe4b326e18e..3213429f8444 100644 --- a/drivers/gpu/drm/drm_gem_vram_helper.c +++ b/drivers/gpu/drm/drm_gem_vram_helper.c @@ -588,6 +588,14 @@ static void drm_gem_vram_bo_driver_move_notify(struct drm_gem_vram_object *gbo, kmap->virtual = NULL; } +static int drm_gem_vram_bo_driver_move(struct drm_gem_vram_object *gbo, + bool evict, + struct ttm_operation_ctx *ctx, + struct ttm_resource *new_mem) +{ + return ttm_bo_move_memcpy(&gbo->bo, ctx, new_mem); +} + /* * Helpers for struct drm_gem_object_funcs */ @@ -950,6 +958,18 @@ static void bo_driver_move_notify(struct ttm_buffer_object *bo, drm_gem_vram_bo_driver_move_notify(gbo, evict, new_mem); } +static int bo_driver_move(struct ttm_buffer_object *bo, + bool evict, + struct ttm_operation_ctx *ctx, + struct ttm_resource *new_mem) +{ + struct drm_gem_vram_object *gbo; + + gbo = drm_gem_vram_of_bo(bo); + + return drm_gem_vram_bo_driver_move(gbo, evict, ctx, new_mem); +} + static int bo_driver_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_resource *mem) { @@ -974,6 +994,7 @@ static struct ttm_bo_driver bo_driver = { .ttm_tt_destroy = bo_driver_ttm_tt_destroy, .eviction_valuable = ttm_bo_eviction_valuable, .evict_flags = bo_driver_evict_flags, + .move = bo_driver_move, .move_notify = bo_driver_move_notify, .io_mem_reserve = bo_driver_io_mem_reserve, }; From 8e6cb56b67fe2a57c0da8f8dea93dfab863d8935 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 6 Oct 2020 10:06:44 +1000 Subject: [PATCH 130/235] drm/ttm: make move callback compulstory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All drivers should have a move callback now so make it compulsory. Reviewed-by: Christian König Reviewed-by: Ben Skeggs Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20201006000644.1005758-6-airlied@gmail.com --- drivers/gpu/drm/ttm/ttm_bo.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index e11e8eaa6602..88d215de9ae1 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -270,18 +270,7 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, if (bdev->driver->move_notify) bdev->driver->move_notify(bo, evict, mem); - if (old_man->use_tt && new_man->use_tt) { - if (bo->mem.mem_type == TTM_PL_SYSTEM) { - ttm_bo_assign_mem(bo, mem); - ret = 0; - } else - ret = ttm_bo_move_ttm(bo, ctx, mem); - } else if (bdev->driver->move) { - ret = bdev->driver->move(bo, evict, ctx, mem); - } else { - ret = ttm_bo_move_memcpy(bo, ctx, mem); - } - + ret = bdev->driver->move(bo, evict, ctx, mem); if (ret) { if (bdev->driver->move_notify) { swap(*mem, bo->mem); From 1e17792de06fe74daf44a97a8dff7d357c783acc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 29 Sep 2020 17:33:17 +0200 Subject: [PATCH 131/235] drm/ttm: remove TTM_PAGE_FLAG_WRITE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not used any more. Signed-off-by: Christian König Reviewed-by: Michael J. Ruhl Link: https://patchwork.freedesktop.org/patch/393429/ --- include/drm/ttm/ttm_tt.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/drm/ttm/ttm_tt.h b/include/drm/ttm/ttm_tt.h index 91691240a509..5d1835d44084 100644 --- a/include/drm/ttm/ttm_tt.h +++ b/include/drm/ttm/ttm_tt.h @@ -34,7 +34,6 @@ struct ttm_resource; struct ttm_buffer_object; struct ttm_operation_ctx; -#define TTM_PAGE_FLAG_WRITE (1 << 3) #define TTM_PAGE_FLAG_SWAPPED (1 << 4) #define TTM_PAGE_FLAG_ZERO_ALLOC (1 << 6) #define TTM_PAGE_FLAG_DMA32 (1 << 7) From 3b53d304856b85ee2357264dfd39730b9c1674f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 29 Sep 2020 17:32:35 +0200 Subject: [PATCH 132/235] drm/ttm: cleanup ttm_handle_caching_state_failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove unused parameters, shorten the function name. Signed-off-by: Christian König Reviewed-by: Michael J. Ruhl Link: https://patchwork.freedesktop.org/patch/393431/ --- drivers/gpu/drm/ttm/ttm_page_alloc.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index 14660f723f71..6bd59c66cc49 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c @@ -466,11 +466,11 @@ static int ttm_set_pages_caching(struct page **pages, * any pages that have changed their caching state already put them to the * pool. */ -static void ttm_handle_caching_state_failure(struct list_head *pages, - int ttm_flags, enum ttm_caching_state cstate, - struct page **failed_pages, unsigned cpages) +static void ttm_handle_caching_failure(struct page **failed_pages, + unsigned cpages) { unsigned i; + /* Failed pages have to be freed */ for (i = 0; i < cpages; ++i) { list_del(&failed_pages[i]->lru); @@ -516,9 +516,8 @@ static int ttm_alloc_new_pages(struct list_head *pages, gfp_t gfp_flags, r = ttm_set_pages_caching(caching_array, cstate, cpages); if (r) - ttm_handle_caching_state_failure(pages, - ttm_flags, cstate, - caching_array, cpages); + ttm_handle_caching_failure(caching_array, + cpages); } r = -ENOMEM; goto out; @@ -541,9 +540,8 @@ static int ttm_alloc_new_pages(struct list_head *pages, gfp_t gfp_flags, r = ttm_set_pages_caching(caching_array, cstate, cpages); if (r) { - ttm_handle_caching_state_failure(pages, - ttm_flags, cstate, - caching_array, cpages); + ttm_handle_caching_failure(caching_array, + cpages); goto out; } cpages = 0; @@ -554,9 +552,7 @@ static int ttm_alloc_new_pages(struct list_head *pages, gfp_t gfp_flags, if (cpages) { r = ttm_set_pages_caching(caching_array, cstate, cpages); if (r) - ttm_handle_caching_state_failure(pages, - ttm_flags, cstate, - caching_array, cpages); + ttm_handle_caching_failure(caching_array, cpages); } out: kfree(caching_array); From 4ce032d64c2a30cf5b23c57b3328d5d2dab99a1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 1 Oct 2020 15:21:00 +0200 Subject: [PATCH 133/235] drm/ttm: nuke ttm_bo_evict_mm and rename mgr function v3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make it more clear what the resource manager function does and nuke the wrapper function. v2: nuke the wrapper v3: fix typo in radeon, rebased Signed-off-by: Christian König Reviewed-by: Daniel Vetter (v2) Link: https://patchwork.freedesktop.org/patch/393914/ --- drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 5 ++++- drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 6 +++++- drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 2 +- drivers/gpu/drm/nouveau/nouveau_drm.c | 5 ++++- drivers/gpu/drm/nouveau/nouveau_ttm.c | 4 ++-- drivers/gpu/drm/qxl/qxl_object.c | 10 ++++++++-- drivers/gpu/drm/radeon/radeon_object.c | 6 +++++- drivers/gpu/drm/ttm/ttm_bo.c | 18 ----------------- drivers/gpu/drm/ttm/ttm_range_manager.c | 2 +- drivers/gpu/drm/ttm/ttm_resource.c | 10 +++++----- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 12 ++++++++--- drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_thp.c | 2 +- include/drm/ttm/ttm_bo_api.h | 20 ------------------- include/drm/ttm/ttm_resource.h | 4 ++-- 16 files changed, 49 insertions(+), 61 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c index abe0c2729e1c..a5e08dc54e4a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c @@ -1319,6 +1319,7 @@ static int amdgpu_debugfs_evict_gtt(struct seq_file *m, void *data) struct drm_info_node *node = (struct drm_info_node *)m->private; struct drm_device *dev = node->minor->dev; struct amdgpu_device *adev = drm_to_adev(dev); + struct ttm_resource_manager *man; int r; r = pm_runtime_get_sync(dev->dev); @@ -1327,7 +1328,9 @@ static int amdgpu_debugfs_evict_gtt(struct seq_file *m, void *data) return r; } - seq_printf(m, "(%d)\n", ttm_bo_evict_mm(&adev->mman.bdev, TTM_PL_TT)); + man = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT); + r = ttm_resource_manager_evict_all(&adev->mman.bdev, man); + seq_printf(m, "(%d)\n", r); pm_runtime_mark_last_busy(dev->dev); pm_runtime_put_autosuspend(dev->dev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c index f203e4a6a3f2..1721739def84 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c @@ -136,7 +136,7 @@ void amdgpu_gtt_mgr_fini(struct amdgpu_device *adev) ttm_resource_manager_set_used(man, false); - ret = ttm_resource_manager_force_list_clean(&adev->mman.bdev, man); + ret = ttm_resource_manager_evict_all(&adev->mman.bdev, man); if (ret) return; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 80bc7177cd45..8b96e7aaeff1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -1029,6 +1029,8 @@ void amdgpu_bo_unpin(struct amdgpu_bo *bo) */ int amdgpu_bo_evict_vram(struct amdgpu_device *adev) { + struct ttm_resource_manager *man; + /* late 2.6.33 fix IGP hibernate - we need pm ops to do this correct */ #ifndef CONFIG_HIBERNATION if (adev->flags & AMD_IS_APU) { @@ -1036,7 +1038,9 @@ int amdgpu_bo_evict_vram(struct amdgpu_device *adev) return 0; } #endif - return ttm_bo_evict_mm(&adev->mman.bdev, TTM_PL_VRAM); + + man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM); + return ttm_resource_manager_evict_all(&adev->mman.bdev, man); } static const char *amdgpu_vram_names[] = { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c index 01c1171afbe0..7747be644dd0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c @@ -212,7 +212,7 @@ void amdgpu_vram_mgr_fini(struct amdgpu_device *adev) ttm_resource_manager_set_used(man, false); - ret = ttm_resource_manager_force_list_clean(&adev->mman.bdev, man); + ret = ttm_resource_manager_evict_all(&adev->mman.bdev, man); if (ret) return; diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 72640bca1617..d141a5f004af 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -820,6 +820,7 @@ static int nouveau_do_suspend(struct drm_device *dev, bool runtime) { struct nouveau_drm *drm = nouveau_drm(dev); + struct ttm_resource_manager *man; int ret; nouveau_svm_suspend(drm); @@ -836,7 +837,9 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime) } NV_DEBUG(drm, "evicting buffers...\n"); - ttm_bo_evict_mm(&drm->ttm.bdev, TTM_PL_VRAM); + + man = ttm_manager_type(&drm->ttm.bdev, TTM_PL_VRAM); + ttm_resource_manager_evict_all(&drm->ttm.bdev, man); NV_DEBUG(drm, "waiting for kernel channels to go idle...\n"); if (drm->cechan) { diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index edf3bb89a47f..04b95277c73a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -222,7 +222,7 @@ nouveau_ttm_fini_vram(struct nouveau_drm *drm) if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) { ttm_resource_manager_set_used(man, false); - ttm_resource_manager_force_list_clean(&drm->ttm.bdev, man); + ttm_resource_manager_evict_all(&drm->ttm.bdev, man); ttm_resource_manager_cleanup(man); ttm_set_driver_manager(&drm->ttm.bdev, TTM_PL_VRAM, NULL); kfree(man); @@ -267,7 +267,7 @@ nouveau_ttm_fini_gtt(struct nouveau_drm *drm) ttm_range_man_fini(&drm->ttm.bdev, TTM_PL_TT); else { ttm_resource_manager_set_used(man, false); - ttm_resource_manager_force_list_clean(&drm->ttm.bdev, man); + ttm_resource_manager_evict_all(&drm->ttm.bdev, man); ttm_resource_manager_cleanup(man); ttm_set_driver_manager(&drm->ttm.bdev, TTM_PL_TT, NULL); kfree(man); diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c index c8b67e7a3f02..940e99354f49 100644 --- a/drivers/gpu/drm/qxl/qxl_object.c +++ b/drivers/gpu/drm/qxl/qxl_object.c @@ -351,10 +351,16 @@ int qxl_bo_check_id(struct qxl_device *qdev, struct qxl_bo *bo) int qxl_surf_evict(struct qxl_device *qdev) { - return ttm_bo_evict_mm(&qdev->mman.bdev, TTM_PL_PRIV); + struct ttm_resource_manager *man; + + man = ttm_manager_type(&qdev->mman.bdev, TTM_PL_PRIV); + return ttm_resource_manager_evict_all(&qdev->mman.bdev, man); } int qxl_vram_evict(struct qxl_device *qdev) { - return ttm_bo_evict_mm(&qdev->mman.bdev, TTM_PL_VRAM); + struct ttm_resource_manager *man; + + man = ttm_manager_type(&qdev->mman.bdev, TTM_PL_VRAM); + return ttm_resource_manager_evict_all(&qdev->mman.bdev, man); } diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 8c285eb118f9..ad0e6e9ef922 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -402,6 +402,9 @@ void radeon_bo_unpin(struct radeon_bo *bo) int radeon_bo_evict_vram(struct radeon_device *rdev) { + struct ttm_bo_device *bdev = &rdev->mman.bdev; + struct ttm_resource_manager *man; + /* late 2.6.33 fix IGP hibernate - we need pm ops to do this correct */ #ifndef CONFIG_HIBERNATION if (rdev->flags & RADEON_IS_IGP) { @@ -410,7 +413,8 @@ int radeon_bo_evict_vram(struct radeon_device *rdev) return 0; } #endif - return ttm_bo_evict_mm(&rdev->mman.bdev, TTM_PL_VRAM); + man = ttm_manager_type(bdev, TTM_PL_VRAM); + return ttm_resource_manager_evict_all(bdev, man); } void radeon_bo_force_delete(struct radeon_device *rdev) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 88d215de9ae1..6eb151dd840d 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1249,24 +1249,6 @@ size_t ttm_bo_dma_acc_size(struct ttm_bo_device *bdev, } EXPORT_SYMBOL(ttm_bo_dma_acc_size); -int ttm_bo_evict_mm(struct ttm_bo_device *bdev, unsigned mem_type) -{ - struct ttm_resource_manager *man = ttm_manager_type(bdev, mem_type); - - if (mem_type == 0 || mem_type >= TTM_NUM_MEM_TYPES) { - pr_err("Illegal memory manager memory type %u\n", mem_type); - return -EINVAL; - } - - if (!man) { - pr_err("Memory type %u has not been initialized\n", mem_type); - return 0; - } - - return ttm_resource_manager_force_list_clean(bdev, man); -} -EXPORT_SYMBOL(ttm_bo_evict_mm); - static void ttm_bo_global_kobj_release(struct kobject *kobj) { struct ttm_bo_global *glob = diff --git a/drivers/gpu/drm/ttm/ttm_range_manager.c b/drivers/gpu/drm/ttm/ttm_range_manager.c index 1da0e277c511..ea77919569a2 100644 --- a/drivers/gpu/drm/ttm/ttm_range_manager.c +++ b/drivers/gpu/drm/ttm/ttm_range_manager.c @@ -149,7 +149,7 @@ int ttm_range_man_fini(struct ttm_bo_device *bdev, ttm_resource_manager_set_used(man, false); - ret = ttm_resource_manager_force_list_clean(bdev, man); + ret = ttm_resource_manager_evict_all(bdev, man); if (ret) return ret; diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c index b325b9264203..4ebc043e2867 100644 --- a/drivers/gpu/drm/ttm/ttm_resource.c +++ b/drivers/gpu/drm/ttm/ttm_resource.c @@ -75,16 +75,16 @@ void ttm_resource_manager_init(struct ttm_resource_manager *man, EXPORT_SYMBOL(ttm_resource_manager_init); /* - * ttm_resource_manager_force_list_clean + * ttm_resource_manager_evict_all * * @bdev - device to use * @man - manager to use * - * Force all the objects out of a memory manager until clean. + * Evict all the objects out of a memory manager until it is empty. * Part of memory manager cleanup sequence. */ -int ttm_resource_manager_force_list_clean(struct ttm_bo_device *bdev, - struct ttm_resource_manager *man) +int ttm_resource_manager_evict_all(struct ttm_bo_device *bdev, + struct ttm_resource_manager *man) { struct ttm_operation_ctx ctx = { .interruptible = false, @@ -126,7 +126,7 @@ int ttm_resource_manager_force_list_clean(struct ttm_bo_device *bdev, return 0; } -EXPORT_SYMBOL(ttm_resource_manager_force_list_clean); +EXPORT_SYMBOL(ttm_resource_manager_evict_all); /** * ttm_resource_manager_debug diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index bdb7a5e96560..10a054d25485 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -468,7 +468,10 @@ out_no_query_bo: if (dev_priv->cman) vmw_cmdbuf_remove_pool(dev_priv->cman); if (dev_priv->has_mob) { - (void) ttm_bo_evict_mm(&dev_priv->bdev, VMW_PL_MOB); + struct ttm_resource_manager *man; + + man = ttm_manager_type(&dev_priv->bdev, VMW_PL_MOB); + ttm_resource_manager_evict_all(&dev_priv->bdev, man); vmw_otables_takedown(dev_priv); } if (dev_priv->cman) @@ -501,7 +504,10 @@ static void vmw_release_device_early(struct vmw_private *dev_priv) vmw_cmdbuf_remove_pool(dev_priv->cman); if (dev_priv->has_mob) { - ttm_bo_evict_mm(&dev_priv->bdev, VMW_PL_MOB); + struct ttm_resource_manager *man; + + man = ttm_manager_type(&dev_priv->bdev, VMW_PL_MOB); + ttm_resource_manager_evict_all(&dev_priv->bdev, man); vmw_otables_takedown(dev_priv); } } @@ -1257,7 +1263,7 @@ void vmw_svga_disable(struct vmw_private *dev_priv) if (ttm_resource_manager_used(man)) { ttm_resource_manager_set_used(man, false); spin_unlock(&dev_priv->svga_lock); - if (ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM)) + if (ttm_resource_manager_evict_all(&dev_priv->bdev, man)) DRM_ERROR("Failed evicting VRAM buffers.\n"); vmw_write(dev_priv, SVGA_REG_ENABLE, SVGA_REG_ENABLE_HIDE | diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c index db64c3a90285..9e8a3e337b96 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c @@ -143,7 +143,7 @@ void vmw_gmrid_man_fini(struct vmw_private *dev_priv, int type) ttm_resource_manager_set_used(man, false); - ttm_resource_manager_force_list_clean(&dev_priv->bdev, man); + ttm_resource_manager_evict_all(&dev_priv->bdev, man); ttm_resource_manager_cleanup(man); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_thp.c b/drivers/gpu/drm/vmwgfx/vmwgfx_thp.c index 63fe7da4cbf4..328d332a55e2 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_thp.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_thp.c @@ -149,7 +149,7 @@ void vmw_thp_fini(struct vmw_private *dev_priv) ttm_resource_manager_set_used(man, false); - ret = ttm_resource_manager_force_list_clean(&dev_priv->bdev, man); + ret = ttm_resource_manager_evict_all(&dev_priv->bdev, man); if (ret) return; spin_lock(&rman->lock); diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index c96a25d571c8..6f5ced7d83fe 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -448,26 +448,6 @@ int ttm_bo_init(struct ttm_bo_device *bdev, struct ttm_buffer_object *bo, struct sg_table *sg, struct dma_resv *resv, void (*destroy) (struct ttm_buffer_object *)); -/** - * ttm_bo_evict_mm - * - * @bdev: Pointer to a ttm_bo_device struct. - * @mem_type: The memory type. - * - * Evicts all buffers on the lru list of the memory type. - * This is normally part of a VT switch or an - * out-of-memory-space-due-to-fragmentation handler. - * The caller must make sure that there are no other processes - * currently validating buffers, and can do that by taking the - * struct ttm_bo_device::ttm_lock in write mode. - * - * Returns: - * -EINVAL: Invalid or uninitialized memory type. - * -ERESTARTSYS: The call was interrupted by a signal while waiting to - * evict a buffer. - */ -int ttm_bo_evict_mm(struct ttm_bo_device *bdev, unsigned mem_type); - /** * ttm_kmap_obj_virtual * diff --git a/include/drm/ttm/ttm_resource.h b/include/drm/ttm/ttm_resource.h index 0e172d94a0c1..1b2f56163c6c 100644 --- a/include/drm/ttm/ttm_resource.h +++ b/include/drm/ttm/ttm_resource.h @@ -228,8 +228,8 @@ void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource *res); void ttm_resource_manager_init(struct ttm_resource_manager *man, unsigned long p_size); -int ttm_resource_manager_force_list_clean(struct ttm_bo_device *bdev, - struct ttm_resource_manager *man); +int ttm_resource_manager_evict_all(struct ttm_bo_device *bdev, + struct ttm_resource_manager *man); void ttm_resource_manager_debug(struct ttm_resource_manager *man, struct drm_printer *p); From 4561b366c70e312698361154bdfe1e04f596056b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 1 Oct 2020 16:17:55 +0200 Subject: [PATCH 134/235] drm/ttm: drop glob parameter from ttm_bo_swapout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We can always access the global state. Signed-off-by: Christian König Acked-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/393499/ --- drivers/gpu/drm/ttm/ttm_bo.c | 5 +++-- drivers/gpu/drm/ttm/ttm_memory.c | 2 +- include/drm/ttm/ttm_bo_api.h | 3 +-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 6eb151dd840d..96adee10857b 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1432,8 +1432,9 @@ EXPORT_SYMBOL(ttm_bo_wait); * A buffer object shrink method that tries to swap out the first * buffer object on the bo_global::swap_lru list. */ -int ttm_bo_swapout(struct ttm_bo_global *glob, struct ttm_operation_ctx *ctx) +int ttm_bo_swapout(struct ttm_operation_ctx *ctx) { + struct ttm_bo_global *glob = &ttm_bo_glob; struct ttm_buffer_object *bo; int ret = -EBUSY; bool locked; @@ -1531,7 +1532,7 @@ void ttm_bo_swapout_all(void) .no_wait_gpu = false }; - while (ttm_bo_swapout(&ttm_bo_glob, &ctx) == 0); + while (ttm_bo_swapout(&ctx) == 0); } EXPORT_SYMBOL(ttm_bo_swapout_all); diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c index 89d50f38c0f2..69cf622e79e5 100644 --- a/drivers/gpu/drm/ttm/ttm_memory.c +++ b/drivers/gpu/drm/ttm/ttm_memory.c @@ -275,7 +275,7 @@ static void ttm_shrink(struct ttm_mem_global *glob, bool from_wq, while (ttm_zones_above_swap_target(glob, from_wq, extra)) { spin_unlock(&glob->lock); - ret = ttm_bo_swapout(&ttm_bo_glob, ctx); + ret = ttm_bo_swapout(ctx); spin_lock(&glob->lock); if (unlikely(ret != 0)) break; diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 6f5ced7d83fe..11c59d6d72d5 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -541,8 +541,7 @@ ssize_t ttm_bo_io(struct ttm_bo_device *bdev, struct file *filp, const char __user *wbuf, char __user *rbuf, size_t count, loff_t *f_pos, bool write); -int ttm_bo_swapout(struct ttm_bo_global *glob, - struct ttm_operation_ctx *ctx); +int ttm_bo_swapout(struct ttm_operation_ctx *ctx); void ttm_bo_swapout_all(void); /** From d7c59750f274acb0aace9b09692eda282a5b01e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 1 Oct 2020 16:22:42 +0200 Subject: [PATCH 135/235] drm/vmwgfx: move ttm_bo_swapout_all into vmwgfx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is the sole user of this. Signed-off-by: Christian König Acked-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/393498/ --- drivers/gpu/drm/ttm/ttm_bo.c | 11 ----------- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 6 +++++- include/drm/ttm/ttm_bo_api.h | 1 - 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 96adee10857b..3732dcb58aad 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1525,17 +1525,6 @@ out: } EXPORT_SYMBOL(ttm_bo_swapout); -void ttm_bo_swapout_all(void) -{ - struct ttm_operation_ctx ctx = { - .interruptible = false, - .no_wait_gpu = false - }; - - while (ttm_bo_swapout(&ctx) == 0); -} -EXPORT_SYMBOL(ttm_bo_swapout_all); - void ttm_bo_tt_destroy(struct ttm_buffer_object *bo) { if (bo->ttm == NULL) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 10a054d25485..4860370740e0 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -1370,6 +1370,10 @@ static int vmw_pm_freeze(struct device *kdev) struct pci_dev *pdev = to_pci_dev(kdev); struct drm_device *dev = pci_get_drvdata(pdev); struct vmw_private *dev_priv = vmw_priv(dev); + struct ttm_operation_ctx ctx = { + .interruptible = false, + .no_wait_gpu = false + }; int ret; /* @@ -1390,7 +1394,7 @@ static int vmw_pm_freeze(struct device *kdev) vmw_execbuf_release_pinned_bo(dev_priv); vmw_resource_evict_all(dev_priv); vmw_release_device_early(dev_priv); - ttm_bo_swapout_all(); + while (ttm_bo_swapout(&ctx) == 0); if (dev_priv->enable_fb) vmw_fifo_resource_dec(dev_priv); if (atomic_read(&dev_priv->num_fifo_resources) != 0) { diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 11c59d6d72d5..37102e45e496 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -542,7 +542,6 @@ ssize_t ttm_bo_io(struct ttm_bo_device *bdev, struct file *filp, size_t count, loff_t *f_pos, bool write); int ttm_bo_swapout(struct ttm_operation_ctx *ctx); -void ttm_bo_swapout_all(void); /** * ttm_bo_uses_embedded_gem_object - check if the given bo uses the From 72dc6e3b948c40bd1d78c7cf1b9d32c92a756328 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 7 Oct 2020 10:51:29 +0200 Subject: [PATCH 136/235] drm/ttm: remove ttm_bo_unmap_virtual_locked declaration v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit That was missed during the cleanup. v2: fix comment in vmwgfx as well Signed-off-by: Christian König Reviewed-by: Michael J. Ruhl Link: https://patchwork.freedesktop.org/patch/394092/ --- drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c | 2 +- include/drm/ttm/ttm_bo_driver.h | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c b/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c index d4d66532f9c9..0b76b3d17d4c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c @@ -206,7 +206,7 @@ static void vmw_bo_dirty_pre_unmap(struct vmw_buffer_object *vbo, * @start: First page of the range within the buffer object. * @end: Last page of the range within the buffer object + 1. * - * This is similar to ttm_bo_unmap_virtual_locked() except it takes a subrange. + * This is similar to ttm_bo_unmap_virtual() except it takes a subrange. */ void vmw_bo_dirty_unmap(struct vmw_buffer_object *vbo, pgoff_t start, pgoff_t end) diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index 9897a16c0a9d..b58dedce7079 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -449,15 +449,6 @@ int ttm_bo_device_init(struct ttm_bo_device *bdev, */ void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo); -/** - * ttm_bo_unmap_virtual - * - * @bo: tear down the virtual mappings for this BO - * - * The caller must take ttm_mem_io_lock before calling this function. - */ -void ttm_bo_unmap_virtual_locked(struct ttm_buffer_object *bo); - /** * ttm_bo_reserve: * From 955a341f33b75b8baa6536b283e08e73f3a989da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 29 Sep 2020 17:39:57 +0200 Subject: [PATCH 137/235] drm/ttm: move ttm_set_memory.h out of include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is not something drivers should use. Signed-off-by: Christian König Reviewed-by: Michael J. Ruhl Link: https://patchwork.freedesktop.org/patch/393430/ --- drivers/gpu/drm/ttm/ttm_page_alloc.c | 3 ++- drivers/gpu/drm/ttm/ttm_page_alloc_dma.c | 3 ++- {include => drivers/gpu}/drm/ttm/ttm_set_memory.h | 0 3 files changed, 4 insertions(+), 2 deletions(-) rename {include => drivers/gpu}/drm/ttm/ttm_set_memory.h (100%) diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index 6bd59c66cc49..111031cbb6df 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c @@ -47,7 +47,8 @@ #include #include -#include + +#include "ttm_set_memory.h" #define NUM_PAGES_TO_ALLOC (PAGE_SIZE/sizeof(struct page *)) #define SMALL_ALLOCATION 16 diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c index 5e2df11685e7..1045a5c26ee3 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c @@ -49,7 +49,8 @@ #include #include #include -#include + +#include "ttm_set_memory.h" #define NUM_PAGES_TO_ALLOC (PAGE_SIZE/sizeof(struct page *)) #define SMALL_ALLOCATION 4 diff --git a/include/drm/ttm/ttm_set_memory.h b/drivers/gpu/drm/ttm/ttm_set_memory.h similarity index 100% rename from include/drm/ttm/ttm_set_memory.h rename to drivers/gpu/drm/ttm/ttm_set_memory.h From 5a3884320a5753395e7167a74f4be257d490a578 Mon Sep 17 00:00:00 2001 From: Melissa Wen Date: Tue, 6 Oct 2020 19:30:06 -0300 Subject: [PATCH 138/235] drm/vkms: update todo Drop issues already resolved in vkms: - CRC API Improvements to [1] add igt test to check extreme alpha values and [2] alpha blending; - [3] prime buffer sharing; - [4] writeback support; On the other hand, we also found or thought about other improvements since the last update of this document: - better support for IGT tests - improvements to writeback support - syzbot report Finally, we reorder items by the assumed complexity. [1] https://patchwork.freedesktop.org/series/55944/ [2] https://patchwork.freedesktop.org/series/80823/ [3] https://patchwork.freedesktop.org/series/63212/ [4] https://patchwork.freedesktop.org/series/81177/ v2: - Link to syzbot dashboard Cc: Daniel Vetter Cc: Rodrigo Siqueira Cc: Haneen Mohammed Signed-off-by: Melissa Wen Acked-by: Daniel Vetter Reviewed-by: Rodrigo Siqueira Link: https://patchwork.freedesktop.org/patch/msgid/20201006223006.gu55pjtuaigkh6il@smtp.gmail.com --- Documentation/gpu/vkms.rst | 107 ++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 50 deletions(-) diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst index 61586fc861bb..13bab1d93bb3 100644 --- a/Documentation/gpu/vkms.rst +++ b/Documentation/gpu/vkms.rst @@ -10,36 +10,24 @@ TODO ==== -CRC API Improvements --------------------- +If you want to do any of the items listed below, please share your interest +with VKMS maintainers. -- Optimize CRC computation ``compute_crc()`` and plane blending ``blend()`` +IGT better support +------------------ -- Use the alpha value to blend vaddr_src with vaddr_dst instead of - overwriting it in ``blend()``. +- Investigate: (1) test cases on kms_plane that are failing due to timeout on + capturing CRC; (2) when running kms_flip test cases in sequence, some + successful individual test cases are failing randomly. -- Add igt test to check cleared alpha value for XRGB plane format. - -- Add igt test to check extreme alpha values i.e. fully opaque and fully - transparent (intermediate values are affected by hw-specific rounding modes). - -Runtime Configuration ---------------------- - -We want to be able to reconfigure vkms instance without having to reload the -module. Use/Test-cases: - -- Hotplug/hotremove connectors on the fly (to be able to test DP MST handling of - compositors). - -- Configure planes/crtcs/connectors (we'd need some code to have more than 1 of - them first). - -- Change output configuration: Plug/unplug screens, change EDID, allow changing - the refresh rate. - -The currently proposed solution is to expose vkms configuration through -configfs. All existing module options should be supported through configfs too. +- VKMS already has support for vblanks simulated via hrtimers, which can be + tested with kms_flip test; in some way, we can say that VKMS already mimics + the real hardware vblank. However, we also have virtual hardware that does + not support vblank interrupt and completes page_flip events right away; in + this case, compositor developers may end up creating a busy loop on virtual + hardware. It would be useful to support Virtual Hardware behavior in VKMS + because this can help compositor developers to test their features in + multiple scenarios. Add Plane Features ------------------ @@ -55,33 +43,49 @@ There's lots of plane features we could add support for: - Additional buffer formats, especially YUV formats for video like NV12. Low/high bpp RGB formats would also be interesting. -- Async updates (currently only possible on cursor plane using the legacy cursor - api). +- Async updates (currently only possible on cursor plane using the legacy + cursor api). -For all of these, we also want to review the igt test coverage and make sure all -relevant igt testcases work on vkms. - -Writeback support ------------------ - -Currently vkms only computes a CRC for each frame. Once we have additional plane -features, we could write back the entire composited frame, and expose it as: - -- Writeback connector. This is useful for testing compositors if you don't have - hardware with writeback support. - -- As a v4l device. This is useful for debugging compositors on special vkms - configurations, so that developers see what's really going on. +For all of these, we also want to review the igt test coverage and make sure +all relevant igt testcases work on vkms. Prime Buffer Sharing -------------------- -We already have vgem, which is a gem driver for testing rendering, similar to -how vkms is for testing the modeset side. Adding buffer sharing support to vkms -allows us to test them together, to test synchronization and lots of other -features. Also, this allows compositors to test whether they work correctly on -SoC chips, where the display and rendering is very often split between 2 -drivers. +- Syzbot report - WARNING in vkms_gem_free_object: + https://syzkaller.appspot.com/bug?extid=e7ad70d406e74d8fc9d0 + +Runtime Configuration +--------------------- + +We want to be able to reconfigure vkms instance without having to reload the +module. Use/Test-cases: + +- Hotplug/hotremove connectors on the fly (to be able to test DP MST handling + of compositors). + +- Configure planes/crtcs/connectors (we'd need some code to have more than 1 of + them first). + +- Change output configuration: Plug/unplug screens, change EDID, allow changing + the refresh rate. + +The currently proposed solution is to expose vkms configuration through +configfs. All existing module options should be supported through configfs +too. + +Writeback support +----------------- + +- The writeback and CRC capture operations share the use of composer_enabled + boolean to ensure vblanks. Probably, when these operations work together, + composer_enabled needs to refcounting the composer state to proper work. + +- Add support for cloned writeback outputs and related test cases using a + cloned output in the IGT kms_writeback. + +- As a v4l device. This is useful for debugging compositors on special vkms + configurations, so that developers see what's really going on. Output Features --------------- @@ -93,7 +97,10 @@ Output Features - Add support for link status, so that compositors can validate their runtime fallbacks when e.g. a Display Port link goes bad. -- All the hotplug handling describe under "Runtime Configuration". +CRC API Improvements +-------------------- + +- Optimize CRC computation ``compute_crc()`` and plane blending ``blend()`` Atomic Check using eBPF ----------------------- From a76fa3540fc33de4718b386aea37ed4a7236d253 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 7 Oct 2020 15:30:35 +0200 Subject: [PATCH 139/235] drm/fb-helper: Add locking to sysrq handling We didn't take the kernel_fb_helper_lock mutex, which protects that code. While at it, simplify the code - inline the function (originally shared with kgdb I think) - drop the error tracking and all the complications - drop the pointless early out, it served nothing Acked-by: Thomas Zimmermann Signed-off-by: Daniel Vetter Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann Cc: David Airlie Cc: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20201007133036.1541639-1-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_fb_helper.c | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 8697554ccd41..c2f72bb6afb1 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -281,18 +281,12 @@ int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper) EXPORT_SYMBOL(drm_fb_helper_restore_fbdev_mode_unlocked); #ifdef CONFIG_MAGIC_SYSRQ -/* - * restore fbcon display for all kms driver's using this helper, used for sysrq - * and panic handling. - */ -static bool drm_fb_helper_force_kernel_mode(void) +/* emergency restore, don't bother with error reporting */ +static void drm_fb_helper_restore_work_fn(struct work_struct *ignored) { - bool ret, error = false; struct drm_fb_helper *helper; - if (list_empty(&kernel_fb_helper_list)) - return false; - + mutex_lock(&kernel_fb_helper_lock); list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) { struct drm_device *dev = helper->dev; @@ -300,22 +294,12 @@ static bool drm_fb_helper_force_kernel_mode(void) continue; mutex_lock(&helper->lock); - ret = drm_client_modeset_commit_locked(&helper->client); - if (ret) - error = true; + drm_client_modeset_commit_locked(&helper->client); mutex_unlock(&helper->lock); } - return error; + mutex_unlock(&kernel_fb_helper_lock); } -static void drm_fb_helper_restore_work_fn(struct work_struct *ignored) -{ - bool ret; - - ret = drm_fb_helper_force_kernel_mode(); - if (ret == true) - DRM_ERROR("Failed to restore crtc configuration\n"); -} static DECLARE_WORK(drm_fb_helper_restore_work, drm_fb_helper_restore_work_fn); static void drm_fb_helper_sysrq(int dummy1) From fb6473a48b635c55d04eb94e579eede52ef39550 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 25 Sep 2020 10:46:50 +0200 Subject: [PATCH 140/235] drm/atomic: document and enforce rules around "spurious" EBUSY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When doing an atomic modeset with ALLOW_MODESET drivers are allowed to pull in arbitrary other resources, including CRTCs (e.g. when reconfiguring global resources). But in nonblocking mode userspace has then no idea this happened, which can lead to spurious EBUSY calls, both: - when that other CRTC is currently busy doing a page_flip the ALLOW_MODESET commit can fail with an EBUSY - on the other CRTC a normal atomic flip can fail with EBUSY because of the additional commit inserted by the kernel without userspace's knowledge For blocking commits this isn't a problem, because everyone else will just block until all the CRTC are reconfigured. Only thing userspace can notice is the dropped frames without any reason for why frames got dropped. Consensus is that we need new uapi to handle this properly, but no one has any idea what exactly the new uapi should look like. Since this has been shipping for years already compositors need to deal no matter what, so as a first step just try to enforce this across drivers better with some checks. v2: Add comments and a WARN_ON to enforce this only when allowed - we don't want to silently convert page flips into blocking plane updates just because the driver is buggy. v3: Fix inverted WARN_ON (Pekka). v4: Drop the uapi changes, only add a WARN_ON for now to enforce some rules for drivers. v5: Make the WARNING more informative (Daniel) v6: Add unconditional debug output for compositor hackers to figure out what's going on when they get an EBUSY (Daniel) v7: Fix up old/new_crtc_state confusion for real (Pekka/Ville) Acked-by: Pekka Paalanen Reviewed-by: Daniel Stone References: https://lists.freedesktop.org/archives/dri-devel/2018-July/182281.html Bugzilla: https://gitlab.freedesktop.org/wayland/weston/issues/24#note_9568 Cc: Daniel Stone Cc: Pekka Paalanen Cc: Simon Ser Cc: Ville Syrjälä Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20200925084651.3250104-1-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_atomic.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 2ba729eec451..b2d20eb6c807 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -281,6 +281,10 @@ EXPORT_SYMBOL(__drm_atomic_state_free); * needed. It will also grab the relevant CRTC lock to make sure that the state * is consistent. * + * WARNING: Drivers may only add new CRTC states to a @state if + * drm_atomic_state.allow_modeset is set, or if it's a driver-internal commit + * not created by userspace through an IOCTL call. + * * Returns: * * Either the allocated state or the error code encoded into the pointer. When @@ -1262,10 +1266,15 @@ int drm_atomic_check_only(struct drm_atomic_state *state) struct drm_crtc_state *new_crtc_state; struct drm_connector *conn; struct drm_connector_state *conn_state; + unsigned requested_crtc = 0; + unsigned affected_crtc = 0; int i, ret = 0; DRM_DEBUG_ATOMIC("checking %p\n", state); + for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) + requested_crtc |= drm_crtc_mask(crtc); + for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { ret = drm_atomic_plane_check(old_plane_state, new_plane_state); if (ret) { @@ -1313,6 +1322,26 @@ int drm_atomic_check_only(struct drm_atomic_state *state) } } + for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) + affected_crtc |= drm_crtc_mask(crtc); + + /* + * For commits that allow modesets drivers can add other CRTCs to the + * atomic commit, e.g. when they need to reallocate global resources. + * This can cause spurious EBUSY, which robs compositors of a very + * effective sanity check for their drawing loop. Therefor only allow + * drivers to add unrelated CRTC states for modeset commits. + * + * FIXME: Should add affected_crtc mask to the ATOMIC IOCTL as an output + * so compositors know what's going on. + */ + if (affected_crtc != requested_crtc) { + DRM_DEBUG_ATOMIC("driver added CRTC to commit: requested 0x%x, affected 0x%0x\n", + requested_crtc, affected_crtc); + WARN(!state->allow_modeset, "adding CRTC not allowed without modesets: requested 0x%x, affected 0x%0x\n", + requested_crtc, affected_crtc); + } + return 0; } EXPORT_SYMBOL(drm_atomic_check_only); From 9073d4ed8da47ce53f5447a18ff39cd64d4aee71 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 25 Sep 2020 10:46:51 +0200 Subject: [PATCH 141/235] drm/atomic: debug output for EBUSY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hopefully we'll have the drm crash recorder RSN, but meanwhile compositors would like to know a bit better why they get an EBUSY. v2: Move misplaced hunk to the right patch (Pekka) Acked-by: Pekka Paalanen Reviewed-by: Daniel Stone Cc: Sean Paul Cc: Daniel Stone Cc: Pekka Paalanen Cc: Simon Ser Cc: Ville Syrjälä Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20200925084651.3250104-2-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_atomic_helper.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index f9170b4b22e7..a430b001c47d 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1736,8 +1736,11 @@ int drm_atomic_helper_async_check(struct drm_device *dev, * overridden by a previous synchronous update's state. */ if (old_plane_state->commit && - !try_wait_for_completion(&old_plane_state->commit->hw_done)) + !try_wait_for_completion(&old_plane_state->commit->hw_done)) { + DRM_DEBUG_ATOMIC("[PLANE:%d:%s] inflight previous commit preventing async commit\n", + plane->base.id, plane->name); return -EBUSY; + } return funcs->atomic_async_check(plane, new_plane_state); } @@ -1955,6 +1958,9 @@ static int stall_checks(struct drm_crtc *crtc, bool nonblock) * commit with nonblocking ones. */ if (!completed && nonblock) { spin_unlock(&crtc->commit_lock); + DRM_DEBUG_ATOMIC("[CRTC:%d:%s] busy with a previous commit\n", + crtc->base.id, crtc->name); + return -EBUSY; } } else if (i == 1) { @@ -2129,8 +2135,12 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state, /* Userspace is not allowed to get ahead of the previous * commit with nonblocking ones. */ if (nonblock && old_conn_state->commit && - !try_wait_for_completion(&old_conn_state->commit->flip_done)) + !try_wait_for_completion(&old_conn_state->commit->flip_done)) { + DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] busy with a previous commit\n", + conn->base.id, conn->name); + return -EBUSY; + } /* Always track connectors explicitly for e.g. link retraining. */ commit = crtc_or_fake_commit(state, new_conn_state->crtc ?: old_conn_state->crtc); @@ -2144,8 +2154,12 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state, /* Userspace is not allowed to get ahead of the previous * commit with nonblocking ones. */ if (nonblock && old_plane_state->commit && - !try_wait_for_completion(&old_plane_state->commit->flip_done)) + !try_wait_for_completion(&old_plane_state->commit->flip_done)) { + DRM_DEBUG_ATOMIC("[PLANE:%d:%s] busy with a previous commit\n", + plane->base.id, plane->name); + return -EBUSY; + } /* Always track planes explicitly for async pageflip support. */ commit = crtc_or_fake_commit(state, new_plane_state->crtc ?: old_plane_state->crtc); From 1a11a88cfd9a97e13be8bc880c4795f9844fbbec Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Fri, 2 Oct 2020 14:25:06 +0200 Subject: [PATCH 142/235] drm/panfrost: Fix job timeout handling If more than two jobs end up timeout-ing concurrently, only one of them (the one attached to the scheduler acquiring the lock) is fully handled. The other one remains in a dangling state where it's no longer part of the scheduling queue, but still blocks something in scheduler, leading to repetitive timeouts when new jobs are queued. Let's make sure all bad jobs are properly handled by the thread acquiring the lock. v3: - Add Steven's R-b - Don't take the sched_lock when stopping the schedulers v2: - Fix the subject prefix - Stop the scheduler before returning from panfrost_job_timedout() - Call cancel_delayed_work_sync() after drm_sched_stop() to make sure no timeout handlers are in flight when we reset the GPU (Steven Price) - Make sure we release the reset lock before restarting the schedulers (Steven Price) Fixes: f3ba91228e8e ("drm/panfrost: Add initial panfrost driver") Cc: Signed-off-by: Boris Brezillon Reviewed-by: Steven Price Signed-off-by: Steven Price Link: https://patchwork.freedesktop.org/patch/msgid/20201002122506.1374183-1-boris.brezillon@collabora.com --- drivers/gpu/drm/panfrost/panfrost_job.c | 62 +++++++++++++++++++++---- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c index 30e7b7196dab..d0469e944143 100644 --- a/drivers/gpu/drm/panfrost/panfrost_job.c +++ b/drivers/gpu/drm/panfrost/panfrost_job.c @@ -25,7 +25,8 @@ struct panfrost_queue_state { struct drm_gpu_scheduler sched; - + bool stopped; + struct mutex lock; u64 fence_context; u64 emit_seqno; }; @@ -369,6 +370,24 @@ void panfrost_job_enable_interrupts(struct panfrost_device *pfdev) job_write(pfdev, JOB_INT_MASK, irq_mask); } +static bool panfrost_scheduler_stop(struct panfrost_queue_state *queue, + struct drm_sched_job *bad) +{ + bool stopped = false; + + mutex_lock(&queue->lock); + if (!queue->stopped) { + drm_sched_stop(&queue->sched, bad); + if (bad) + drm_sched_increase_karma(bad); + queue->stopped = true; + stopped = true; + } + mutex_unlock(&queue->lock); + + return stopped; +} + static void panfrost_job_timedout(struct drm_sched_job *sched_job) { struct panfrost_job *job = to_panfrost_job(sched_job); @@ -392,19 +411,39 @@ static void panfrost_job_timedout(struct drm_sched_job *sched_job) job_read(pfdev, JS_TAIL_LO(js)), sched_job); + /* Scheduler is already stopped, nothing to do. */ + if (!panfrost_scheduler_stop(&pfdev->js->queue[js], sched_job)) + return; + if (!mutex_trylock(&pfdev->reset_lock)) return; for (i = 0; i < NUM_JOB_SLOTS; i++) { struct drm_gpu_scheduler *sched = &pfdev->js->queue[i].sched; - drm_sched_stop(sched, sched_job); - if (js != i) - /* Ensure any timeouts on other slots have finished */ + /* + * If the queue is still active, make sure we wait for any + * pending timeouts. + */ + if (!pfdev->js->queue[i].stopped) cancel_delayed_work_sync(&sched->work_tdr); - } - drm_sched_increase_karma(sched_job); + /* + * If the scheduler was not already stopped, there's a tiny + * chance a timeout has expired just before we stopped it, and + * drm_sched_stop() does not flush pending works. Let's flush + * them now so the timeout handler doesn't get called in the + * middle of a reset. + */ + if (panfrost_scheduler_stop(&pfdev->js->queue[i], NULL)) + cancel_delayed_work_sync(&sched->work_tdr); + + /* + * Now that we cancelled the pending timeouts, we can safely + * reset the stopped state. + */ + pfdev->js->queue[i].stopped = false; + } spin_lock_irqsave(&pfdev->js->job_lock, flags); for (i = 0; i < NUM_JOB_SLOTS; i++) { @@ -421,11 +460,11 @@ static void panfrost_job_timedout(struct drm_sched_job *sched_job) for (i = 0; i < NUM_JOB_SLOTS; i++) drm_sched_resubmit_jobs(&pfdev->js->queue[i].sched); + mutex_unlock(&pfdev->reset_lock); + /* restart scheduler after GPU is usable again */ for (i = 0; i < NUM_JOB_SLOTS; i++) drm_sched_start(&pfdev->js->queue[i].sched, true); - - mutex_unlock(&pfdev->reset_lock); } static const struct drm_sched_backend_ops panfrost_sched_ops = { @@ -558,6 +597,7 @@ int panfrost_job_open(struct panfrost_file_priv *panfrost_priv) int ret, i; for (i = 0; i < NUM_JOB_SLOTS; i++) { + mutex_init(&js->queue[i].lock); sched = &js->queue[i].sched; ret = drm_sched_entity_init(&panfrost_priv->sched_entity[i], DRM_SCHED_PRIORITY_NORMAL, &sched, @@ -570,10 +610,14 @@ int panfrost_job_open(struct panfrost_file_priv *panfrost_priv) void panfrost_job_close(struct panfrost_file_priv *panfrost_priv) { + struct panfrost_device *pfdev = panfrost_priv->pfdev; + struct panfrost_job_slot *js = pfdev->js; int i; - for (i = 0; i < NUM_JOB_SLOTS; i++) + for (i = 0; i < NUM_JOB_SLOTS; i++) { drm_sched_entity_destroy(&panfrost_priv->sched_entity[i]); + mutex_destroy(&js->queue[i].lock); + } } int panfrost_job_is_idle(struct panfrost_device *pfdev) From 82e1b93ad8b95a1667708164220ed137d6f3adfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 8 Oct 2020 10:03:22 +0200 Subject: [PATCH 143/235] dma-buf: use struct_size macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of manually calculating the structure size. Signed-off-by: Christian König Reviewed-by: Gustavo A. R. Silva Reviewed-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/394252/ --- drivers/dma-buf/dma-resv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c index 1c8f2581cb09..bb5a42b10c29 100644 --- a/drivers/dma-buf/dma-resv.c +++ b/drivers/dma-buf/dma-resv.c @@ -63,7 +63,7 @@ static struct dma_resv_list *dma_resv_list_alloc(unsigned int shared_max) { struct dma_resv_list *list; - list = kmalloc(offsetof(typeof(*list), shared[shared_max]), GFP_KERNEL); + list = kmalloc(struct_size(list, shared, shared_max), GFP_KERNEL); if (!list) return NULL; From 696029eb36c08d7b60097cae44a6269bfa68b51c Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Wed, 16 Sep 2020 18:04:13 +0930 Subject: [PATCH 144/235] drm/aspeed: Add sysfs for output settings These settings are used by an ASPEED BMC to determine when the host is trying to drive the display over PCIe (vga_pw) and to switch the output between PCIe and the internal graphics device (dac_mux). The valid values for the dac mux are: 00: VGA mode (default, aka PCIe) 01: Graphics CRT (aka BMC internal graphics, this driver) 10: Pass through mode from video input port A 11: Pass through mode from video input port B Values for the read-only vga password register are: 1: Host driving the display 0: Host not driving the display Signed-off-by: Joel Stanley Reviewed-by: Andrew Jeffery Link: https://patchwork.freedesktop.org/patch/msgid/20200916083413.777307-1-joel@jms.id.au --- drivers/gpu/drm/aspeed/aspeed_gfx_drv.c | 71 +++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c index 2b424b2b85cc..2552573cacb2 100644 --- a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c +++ b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c @@ -212,6 +212,69 @@ static const struct of_device_id aspeed_gfx_match[] = { { } }; +#define ASPEED_SCU_VGA0 0x50 +#define ASPEED_SCU_MISC_CTRL 0x2c + +static ssize_t dac_mux_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aspeed_gfx *priv = dev_get_drvdata(dev); + u32 val; + int rc; + + rc = kstrtou32(buf, 0, &val); + if (rc) + return rc; + + if (val > 3) + return -EINVAL; + + rc = regmap_update_bits(priv->scu, ASPEED_SCU_MISC_CTRL, 0x30000, val << 16); + if (rc < 0) + return 0; + + return count; +} + +static ssize_t dac_mux_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct aspeed_gfx *priv = dev_get_drvdata(dev); + u32 reg; + int rc; + + rc = regmap_read(priv->scu, ASPEED_SCU_MISC_CTRL, ®); + if (rc) + return rc; + + return sprintf(buf, "%u\n", (reg >> 16) & 0x3); +} +static DEVICE_ATTR_RW(dac_mux); + +static ssize_t +vga_pw_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct aspeed_gfx *priv = dev_get_drvdata(dev); + u32 reg; + int rc; + + rc = regmap_read(priv->scu, ASPEED_SCU_VGA0, ®); + if (rc) + return rc; + + return sprintf(buf, "%u\n", reg & 1); +} +static DEVICE_ATTR_RO(vga_pw); + +static struct attribute *aspeed_sysfs_entries[] = { + &dev_attr_vga_pw.attr, + &dev_attr_dac_mux.attr, + NULL, +}; + +static struct attribute_group aspeed_sysfs_attr_group = { + .attrs = aspeed_sysfs_entries, +}; + static int aspeed_gfx_probe(struct platform_device *pdev) { struct aspeed_gfx *priv; @@ -226,6 +289,12 @@ static int aspeed_gfx_probe(struct platform_device *pdev) if (ret) return ret; + dev_set_drvdata(&pdev->dev, priv); + + ret = sysfs_create_group(&pdev->dev.kobj, &aspeed_sysfs_attr_group); + if (ret) + return ret; + ret = drm_dev_register(&priv->drm, 0); if (ret) goto err_unload; @@ -234,6 +303,7 @@ static int aspeed_gfx_probe(struct platform_device *pdev) return 0; err_unload: + sysfs_remove_group(&pdev->dev.kobj, &aspeed_sysfs_attr_group); aspeed_gfx_unload(&priv->drm); return ret; @@ -243,6 +313,7 @@ static int aspeed_gfx_remove(struct platform_device *pdev) { struct drm_device *drm = platform_get_drvdata(pdev); + sysfs_remove_group(&pdev->dev.kobj, &aspeed_sysfs_attr_group); drm_dev_unregister(drm); aspeed_gfx_unload(drm); From c76eb35587f556f48dc380ce7964e3254cba916d Mon Sep 17 00:00:00 2001 From: Ondrej Jirman Date: Sun, 23 Feb 2020 00:51:52 +0100 Subject: [PATCH 145/235] drm: aspeed: Fix GENMASK misuse Arguments to GENMASK should be msb >= lsb. Signed-off-by: Ondrej Jirman Reviewed-by: Andrew Jeffery Signed-off-by: Joel Stanley Link: https://patchwork.freedesktop.org/patch/msgid/20200222235152.242816-1-megous@megous.com --- drivers/gpu/drm/aspeed/aspeed_gfx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx.h b/drivers/gpu/drm/aspeed/aspeed_gfx.h index e7ca95827ae8..f1e7e56abc02 100644 --- a/drivers/gpu/drm/aspeed/aspeed_gfx.h +++ b/drivers/gpu/drm/aspeed/aspeed_gfx.h @@ -75,7 +75,7 @@ int aspeed_gfx_create_output(struct drm_device *drm); /* CTRL2 */ #define CRT_CTRL_DAC_EN BIT(0) #define CRT_CTRL_VBLANK_LINE(x) (((x) << 20) & CRT_CTRL_VBLANK_LINE_MASK) -#define CRT_CTRL_VBLANK_LINE_MASK GENMASK(20, 31) +#define CRT_CTRL_VBLANK_LINE_MASK GENMASK(31, 20) /* CRT_HORIZ0 */ #define CRT_H_TOTAL(x) (x) From 351f950db4ab28c321a1bd4b92e4bb03e34c4703 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 8 Oct 2020 14:44:08 +0200 Subject: [PATCH 146/235] drm/atomic: Pass the full state to CRTC atomic enable/disable If the CRTC driver ever needs to access the full DRM state, it can't do so at atomic_enable / atomic_disable time since drm_atomic_helper_swap_state will have cleared the pointer from the struct drm_crtc_state to the struct drm_atomic_state before calling those hooks. In order to allow that, let's pass the full DRM state to atomic_enable and atomic_disable. The conversion was done using the coccinelle script below, built tested on all the drivers and actually tested on vc4. virtual report @@ struct drm_crtc_helper_funcs *FUNCS; identifier dev, state; identifier crtc, crtc_state; @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *state) { <... - FUNCS->atomic_disable(crtc, crtc_state); + FUNCS->atomic_disable(crtc, state); ...> } @@ struct drm_crtc_helper_funcs *FUNCS; identifier dev, state; identifier crtc, crtc_state; @@ drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, struct drm_atomic_state *state) { <... - FUNCS->atomic_enable(crtc, crtc_state); + FUNCS->atomic_enable(crtc, state); ...> } @@ identifier crtc, old_state; @@ struct drm_crtc_helper_funcs { ... - void (*atomic_enable)(struct drm_crtc *crtc, struct drm_crtc_state *old_state); + void (*atomic_enable)(struct drm_crtc *crtc, struct drm_atomic_state *state); ... - void (*atomic_disable)(struct drm_crtc *crtc, struct drm_crtc_state *old_state); + void (*atomic_disable)(struct drm_crtc *crtc, struct drm_atomic_state *state); ... } @ crtc_atomic_func @ identifier helpers; identifier func; @@ ( static struct drm_crtc_helper_funcs helpers = { ..., .atomic_enable = func, ..., }; | static struct drm_crtc_helper_funcs helpers = { ..., .atomic_disable = func, ..., }; ) @ ignores_old_state @ identifier crtc_atomic_func.func; identifier crtc, old_state; @@ void func(struct drm_crtc *crtc, struct drm_crtc_state *old_state) { ... when != old_state } @ adds_old_state depends on crtc_atomic_func && !ignores_old_state @ identifier crtc_atomic_func.func; identifier crtc, old_state; @@ void func(struct drm_crtc *crtc, struct drm_crtc_state *old_state) { + struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, crtc); ... } @ depends on crtc_atomic_func @ identifier crtc_atomic_func.func; expression E; type T; @@ void func(...) { ... - T state = E; + T crtc_state = E; <+... - state + crtc_state ...+> } @ depends on crtc_atomic_func @ identifier crtc_atomic_func.func; type T; @@ void func(...) { ... - T state; + T crtc_state; <+... - state + crtc_state ...+> } @ depends on crtc_atomic_func @ identifier crtc_atomic_func.func; identifier old_state; identifier crtc; @@ void func(struct drm_crtc *crtc, - struct drm_crtc_state *old_state + struct drm_atomic_state *state ) { ... } @ include depends on adds_old_state @ @@ #include @ no_include depends on !include && adds_old_state @ @@ + #include #include Signed-off-by: Maxime Ripard Acked-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/845aa10ef171fc0ea060495efef142a0c13f7870.1602161031.git-series.maxime@cerno.tech --- drivers/gpu/drm/arc/arcpgu_crtc.c | 4 ++-- drivers/gpu/drm/arm/display/komeda/komeda_crtc.c | 8 ++++++-- drivers/gpu/drm/arm/hdlcd_crtc.c | 4 ++-- drivers/gpu/drm/arm/malidp_crtc.c | 6 ++++-- drivers/gpu/drm/armada/armada_crtc.c | 8 ++++++-- drivers/gpu/drm/ast/ast_mode.c | 6 ++++-- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | 4 ++-- drivers/gpu/drm/drm_atomic_helper.c | 4 ++-- drivers/gpu/drm/drm_simple_kms_helper.c | 4 ++-- drivers/gpu/drm/exynos/exynos_drm_crtc.c | 4 ++-- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c | 6 ++++-- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 4 ++-- drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 4 ++-- drivers/gpu/drm/imx/dcss/dcss-crtc.c | 9 +++++++-- drivers/gpu/drm/imx/ipuv3-crtc.c | 6 ++++-- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 4 ++-- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 4 ++-- drivers/gpu/drm/meson/meson_crtc.c | 8 ++++---- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 7 +++++-- drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c | 4 ++-- drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 4 ++-- drivers/gpu/drm/mxsfb/mxsfb_kms.c | 4 ++-- drivers/gpu/drm/omapdrm/omap_crtc.c | 4 ++-- drivers/gpu/drm/qxl/qxl_display.c | 4 ++-- drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 6 ++++-- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 6 ++++-- drivers/gpu/drm/sti/sti_crtc.c | 4 ++-- drivers/gpu/drm/stm/ltdc.c | 4 ++-- drivers/gpu/drm/sun4i/sun4i_crtc.c | 4 ++-- drivers/gpu/drm/tegra/dc.c | 8 ++++---- drivers/gpu/drm/tidss/tidss_crtc.c | 6 ++++-- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 4 ++-- drivers/gpu/drm/vboxvideo/vbox_mode.c | 4 ++-- drivers/gpu/drm/vc4/vc4_crtc.c | 8 ++++++-- drivers/gpu/drm/vc4/vc4_txp.c | 9 +++++++-- drivers/gpu/drm/virtio/virtgpu_display.c | 4 ++-- drivers/gpu/drm/vkms/vkms_crtc.c | 4 ++-- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 4 ++-- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 4 ++-- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 4 ++-- drivers/gpu/drm/xlnx/zynqmp_disp.c | 6 ++++-- drivers/gpu/drm/zte/zx_vou.c | 4 ++-- include/drm/drm_modeset_helper_vtables.h | 13 ++----------- 43 files changed, 131 insertions(+), 99 deletions(-) diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c index be7c29cec318..042d7b54a6de 100644 --- a/drivers/gpu/drm/arc/arcpgu_crtc.c +++ b/drivers/gpu/drm/arc/arcpgu_crtc.c @@ -116,7 +116,7 @@ static void arc_pgu_crtc_mode_set_nofb(struct drm_crtc *crtc) } static void arc_pgu_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc); @@ -127,7 +127,7 @@ static void arc_pgu_crtc_atomic_enable(struct drm_crtc *crtc, } static void arc_pgu_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc); diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c index f33418d6e1a0..a4bbf56a7fc1 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c @@ -273,8 +273,10 @@ komeda_crtc_do_flush(struct drm_crtc *crtc, static void komeda_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old) + struct drm_atomic_state *state) { + struct drm_crtc_state *old = drm_atomic_get_old_crtc_state(state, + crtc); pm_runtime_get_sync(crtc->dev->dev); komeda_crtc_prepare(to_kcrtc(crtc)); drm_crtc_vblank_on(crtc); @@ -319,8 +321,10 @@ komeda_crtc_flush_and_wait_for_flip_done(struct komeda_crtc *kcrtc, static void komeda_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old) + struct drm_atomic_state *state) { + struct drm_crtc_state *old = drm_atomic_get_old_crtc_state(state, + crtc); struct komeda_crtc *kcrtc = to_kcrtc(crtc); struct komeda_crtc_state *old_st = to_kcrtc_st(old); struct komeda_pipeline *master = kcrtc->master; diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index af67fefed38d..84ac10d59485 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c @@ -168,7 +168,7 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc) } static void hdlcd_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); @@ -179,7 +179,7 @@ static void hdlcd_crtc_atomic_enable(struct drm_crtc *crtc, } static void hdlcd_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); diff --git a/drivers/gpu/drm/arm/malidp_crtc.c b/drivers/gpu/drm/arm/malidp_crtc.c index 587d94798f5c..49766eb7a554 100644 --- a/drivers/gpu/drm/arm/malidp_crtc.c +++ b/drivers/gpu/drm/arm/malidp_crtc.c @@ -46,7 +46,7 @@ static enum drm_mode_status malidp_crtc_mode_valid(struct drm_crtc *crtc, } static void malidp_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct malidp_drm *malidp = crtc_to_malidp_device(crtc); struct malidp_hw_device *hwdev = malidp->dev; @@ -70,8 +70,10 @@ static void malidp_crtc_atomic_enable(struct drm_crtc *crtc, } static void malidp_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { + struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, + crtc); struct malidp_drm *malidp = crtc_to_malidp_device(crtc); struct malidp_hw_device *hwdev = malidp->dev; int err; diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index a887b6a5f8bd..e0fbfc9ce386 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -467,8 +467,10 @@ static void armada_drm_crtc_atomic_flush(struct drm_crtc *crtc, } static void armada_drm_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { + struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, + crtc); struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); struct drm_pending_vblank_event *event; @@ -503,8 +505,10 @@ static void armada_drm_crtc_atomic_disable(struct drm_crtc *crtc, } static void armada_drm_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { + struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, + crtc); struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name); diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 0a1e1cf57e19..bd03a8a67e3a 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -793,7 +793,7 @@ ast_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *old_c static void ast_crtc_helper_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { struct drm_device *dev = crtc->dev; struct ast_private *ast = to_ast_private(dev); @@ -816,8 +816,10 @@ ast_crtc_helper_atomic_enable(struct drm_crtc *crtc, static void ast_crtc_helper_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { + struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, + crtc); struct drm_device *dev = crtc->dev; struct ast_private *ast = to_ast_private(dev); diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c index ce246b96330b..2b3888df22f8 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c @@ -165,7 +165,7 @@ atmel_hlcdc_crtc_mode_valid(struct drm_crtc *c, } static void atmel_hlcdc_crtc_atomic_disable(struct drm_crtc *c, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct drm_device *dev = c->dev; struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c); @@ -200,7 +200,7 @@ static void atmel_hlcdc_crtc_atomic_disable(struct drm_crtc *c, } static void atmel_hlcdc_crtc_atomic_enable(struct drm_crtc *c, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct drm_device *dev = c->dev; struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c); diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index a430b001c47d..a7bcb4b4586c 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1093,7 +1093,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) if (new_crtc_state->enable && funcs->prepare) funcs->prepare(crtc); else if (funcs->atomic_disable) - funcs->atomic_disable(crtc, old_crtc_state); + funcs->atomic_disable(crtc, old_state); else if (funcs->disable) funcs->disable(crtc); else if (funcs->dpms) @@ -1358,7 +1358,7 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, DRM_DEBUG_ATOMIC("enabling [CRTC:%d:%s]\n", crtc->base.id, crtc->name); if (funcs->atomic_enable) - funcs->atomic_enable(crtc, old_crtc_state); + funcs->atomic_enable(crtc, old_state); else if (funcs->commit) funcs->commit(crtc); } diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c b/drivers/gpu/drm/drm_simple_kms_helper.c index 74946690aba4..fa87b63e152a 100644 --- a/drivers/gpu/drm/drm_simple_kms_helper.c +++ b/drivers/gpu/drm/drm_simple_kms_helper.c @@ -99,7 +99,7 @@ static int drm_simple_kms_crtc_check(struct drm_crtc *crtc, } static void drm_simple_kms_crtc_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct drm_plane *plane; struct drm_simple_display_pipe *pipe; @@ -113,7 +113,7 @@ static void drm_simple_kms_crtc_enable(struct drm_crtc *crtc, } static void drm_simple_kms_crtc_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct drm_simple_display_pipe *pipe; diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 1c03485676ef..35f1d1dbb126 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -19,7 +19,7 @@ #include "exynos_drm_plane.h" static void exynos_drm_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); @@ -30,7 +30,7 @@ static void exynos_drm_crtc_atomic_enable(struct drm_crtc *crtc, } static void exynos_drm_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c index b9ca81a6f80f..7a9e89cfdf9c 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c @@ -43,8 +43,10 @@ static void fsl_dcu_drm_crtc_atomic_flush(struct drm_crtc *crtc, } static void fsl_dcu_drm_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { + struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, + crtc); struct drm_device *dev = crtc->dev; struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; @@ -62,7 +64,7 @@ static void fsl_dcu_drm_crtc_atomic_disable(struct drm_crtc *crtc, } static void fsl_dcu_drm_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct drm_device *dev = crtc->dev; struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c index a3a9e0a73a08..8478a84ceb23 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c @@ -170,7 +170,7 @@ static void hibmc_crtc_dpms(struct drm_crtc *crtc, int dpms) } static void hibmc_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { unsigned int reg; struct hibmc_drm_private *priv = to_hibmc_drm_private(crtc->dev); @@ -189,7 +189,7 @@ static void hibmc_crtc_atomic_enable(struct drm_crtc *crtc, } static void hibmc_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { unsigned int reg; struct hibmc_drm_private *priv = to_hibmc_drm_private(crtc->dev); diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c index e1108c1735ad..cfe8ff596d55 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c @@ -436,7 +436,7 @@ static void ade_dump_regs(void __iomem *base) { } #endif static void ade_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct kirin_crtc *kcrtc = to_kirin_crtc(crtc); struct ade_hw_ctx *ctx = kcrtc->hw_ctx; @@ -459,7 +459,7 @@ static void ade_crtc_atomic_enable(struct drm_crtc *crtc, } static void ade_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct kirin_crtc *kcrtc = to_kirin_crtc(crtc); struct ade_hw_ctx *ctx = kcrtc->hw_ctx; diff --git a/drivers/gpu/drm/imx/dcss/dcss-crtc.c b/drivers/gpu/drm/imx/dcss/dcss-crtc.c index 36abff0890b2..8f570eb5f471 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-crtc.c +++ b/drivers/gpu/drm/imx/dcss/dcss-crtc.c @@ -3,6 +3,7 @@ * Copyright 2019 NXP. */ +#include #include #include #include @@ -77,8 +78,10 @@ static void dcss_crtc_atomic_flush(struct drm_crtc *crtc, } static void dcss_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { + struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, + crtc); struct dcss_crtc *dcss_crtc = container_of(crtc, struct dcss_crtc, base); struct dcss_dev *dcss = dcss_crtc->base.dev->dev_private; @@ -111,8 +114,10 @@ static void dcss_crtc_atomic_enable(struct drm_crtc *crtc, } static void dcss_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { + struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, + crtc); struct dcss_crtc *dcss_crtc = container_of(crtc, struct dcss_crtc, base); struct dcss_dev *dcss = dcss_crtc->base.dev->dev_private; diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c index d412fc265395..7ecc27c41a6a 100644 --- a/drivers/gpu/drm/imx/ipuv3-crtc.c +++ b/drivers/gpu/drm/imx/ipuv3-crtc.c @@ -47,7 +47,7 @@ static inline struct ipu_crtc *to_ipu_crtc(struct drm_crtc *crtc) } static void ipu_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); @@ -79,8 +79,10 @@ static void ipu_crtc_disable_planes(struct ipu_crtc *ipu_crtc, } static void ipu_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { + struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, + crtc); struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index 7d8b0ad52979..2329754af116 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -156,7 +156,7 @@ static int ingenic_drm_update_pixclk(struct notifier_block *nb, } static void ingenic_drm_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *state) + struct drm_atomic_state *state) { struct ingenic_drm *priv = drm_crtc_get_priv(crtc); @@ -170,7 +170,7 @@ static void ingenic_drm_crtc_atomic_enable(struct drm_crtc *crtc, } static void ingenic_drm_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *state) + struct drm_atomic_state *state) { struct ingenic_drm *priv = drm_crtc_get_priv(crtc); unsigned int var; diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index 3fc5511330b9..6fc818049f2d 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -517,7 +517,7 @@ void mtk_drm_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane, } static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0]; @@ -542,7 +542,7 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc, } static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0]; diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c index 2854272dc2d9..247ce085886b 100644 --- a/drivers/gpu/drm/meson/meson_crtc.c +++ b/drivers/gpu/drm/meson/meson_crtc.c @@ -82,7 +82,7 @@ static const struct drm_crtc_funcs meson_crtc_funcs = { }; static void meson_g12a_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct meson_crtc *meson_crtc = to_meson_crtc(crtc); struct drm_crtc_state *crtc_state = crtc->state; @@ -118,7 +118,7 @@ static void meson_g12a_crtc_atomic_enable(struct drm_crtc *crtc, } static void meson_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct meson_crtc *meson_crtc = to_meson_crtc(crtc); struct drm_crtc_state *crtc_state = crtc->state; @@ -146,7 +146,7 @@ static void meson_crtc_atomic_enable(struct drm_crtc *crtc, } static void meson_g12a_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct meson_crtc *meson_crtc = to_meson_crtc(crtc); struct meson_drm *priv = meson_crtc->priv; @@ -171,7 +171,7 @@ static void meson_g12a_crtc_atomic_disable(struct drm_crtc *crtc, } static void meson_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct meson_crtc *meson_crtc = to_meson_crtc(crtc); struct meson_drm *priv = meson_crtc->priv; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index c2729f71e2fa..5ba9b49dfa7a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -752,8 +753,10 @@ static struct drm_crtc_state *dpu_crtc_duplicate_state(struct drm_crtc *crtc) } static void dpu_crtc_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { + struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, + crtc); struct dpu_crtc *dpu_crtc; struct dpu_crtc_state *cstate; struct drm_encoder *encoder; @@ -823,7 +826,7 @@ static void dpu_crtc_disable(struct drm_crtc *crtc, } static void dpu_crtc_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { struct dpu_crtc *dpu_crtc; struct drm_encoder *encoder; diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c index a0253297bc76..6b03ceeb5ba1 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c @@ -264,7 +264,7 @@ static void mdp4_crtc_mode_set_nofb(struct drm_crtc *crtc) } static void mdp4_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); struct mdp4_kms *mdp4_kms = get_kms(crtc); @@ -284,7 +284,7 @@ static void mdp4_crtc_atomic_disable(struct drm_crtc *crtc, } static void mdp4_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); struct mdp4_kms *mdp4_kms = get_kms(crtc); diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c index c39dad151bb6..747dd8a7aa6e 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c @@ -483,7 +483,7 @@ static u32 mdp5_crtc_get_vblank_counter(struct drm_crtc *crtc) } static void mdp5_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state); @@ -529,7 +529,7 @@ static void mdp5_crtc_vblank_on(struct drm_crtc *crtc) } static void mdp5_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state); diff --git a/drivers/gpu/drm/mxsfb/mxsfb_kms.c b/drivers/gpu/drm/mxsfb/mxsfb_kms.c index b721b8b262ce..956f631997f2 100644 --- a/drivers/gpu/drm/mxsfb/mxsfb_kms.c +++ b/drivers/gpu/drm/mxsfb/mxsfb_kms.c @@ -302,7 +302,7 @@ static void mxsfb_crtc_atomic_flush(struct drm_crtc *crtc, } static void mxsfb_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct mxsfb_drm_private *mxsfb = to_mxsfb_drm_private(crtc->dev); struct drm_device *drm = mxsfb->drm; @@ -326,7 +326,7 @@ static void mxsfb_crtc_atomic_enable(struct drm_crtc *crtc, } static void mxsfb_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct mxsfb_drm_private *mxsfb = to_mxsfb_drm_private(crtc->dev); struct drm_device *drm = mxsfb->drm; diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 328a4a74f534..fef3b0032fd8 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -436,7 +436,7 @@ static void omap_crtc_arm_event(struct drm_crtc *crtc) } static void omap_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct omap_drm_private *priv = crtc->dev->dev_private; struct omap_crtc *omap_crtc = to_omap_crtc(crtc); @@ -462,7 +462,7 @@ static void omap_crtc_atomic_enable(struct drm_crtc *crtc, } static void omap_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct omap_drm_private *priv = crtc->dev->dev_private; struct omap_crtc *omap_crtc = to_omap_crtc(crtc); diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 65de1f69af58..45fd76e04bdc 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -444,13 +444,13 @@ static const struct drm_framebuffer_funcs qxl_fb_funcs = { }; static void qxl_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { qxl_crtc_update_monitors_config(crtc, "enable"); } static void qxl_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { qxl_crtc_update_monitors_config(crtc, "disable"); } diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index fe86a3e67757..4c360a255849 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c @@ -710,7 +710,7 @@ static int rcar_du_crtc_atomic_check(struct drm_crtc *crtc, } static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); struct rcar_du_crtc_state *rstate = to_rcar_crtc_state(crtc->state); @@ -748,8 +748,10 @@ static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc, } static void rcar_du_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { + struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, + crtc); struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); struct rcar_du_crtc_state *rstate = to_rcar_crtc_state(old_state); struct rcar_du_device *rcdu = rcrtc->dev; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index c80f7d9fd13f..47835715b44b 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -693,7 +693,7 @@ static void rockchip_drm_set_win_enabled(struct drm_crtc *crtc, bool enabled) } static void vop_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct vop *vop = to_vop(crtc); @@ -1260,8 +1260,10 @@ static void vop_crtc_atomic_begin(struct drm_crtc *crtc, } static void vop_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { + struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, + crtc); struct vop *vop = to_vop(crtc); const struct vop_data *vop_data = vop->data; struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state); diff --git a/drivers/gpu/drm/sti/sti_crtc.c b/drivers/gpu/drm/sti/sti_crtc.c index 6f37c104c46f..5726746f6d18 100644 --- a/drivers/gpu/drm/sti/sti_crtc.c +++ b/drivers/gpu/drm/sti/sti_crtc.c @@ -23,7 +23,7 @@ #include "sti_vtg.h" static void sti_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct sti_mixer *mixer = to_sti_mixer(crtc); @@ -35,7 +35,7 @@ static void sti_crtc_atomic_enable(struct drm_crtc *crtc, } static void sti_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct sti_mixer *mixer = to_sti_mixer(crtc); diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c index 6e28f707092f..e9af92d4a74b 100644 --- a/drivers/gpu/drm/stm/ltdc.c +++ b/drivers/gpu/drm/stm/ltdc.c @@ -420,7 +420,7 @@ static void ltdc_crtc_update_clut(struct drm_crtc *crtc) } static void ltdc_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct ltdc_device *ldev = crtc_to_ltdc(crtc); struct drm_device *ddev = crtc->dev; @@ -442,7 +442,7 @@ static void ltdc_crtc_atomic_enable(struct drm_crtc *crtc, } static void ltdc_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct ltdc_device *ldev = crtc_to_ltdc(crtc); struct drm_device *ddev = crtc->dev; diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c b/drivers/gpu/drm/sun4i/sun4i_crtc.c index 3a153648b369..999deb64bd70 100644 --- a/drivers/gpu/drm/sun4i/sun4i_crtc.c +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c @@ -101,7 +101,7 @@ static void sun4i_crtc_atomic_flush(struct drm_crtc *crtc, } static void sun4i_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct drm_encoder *encoder = sun4i_crtc_get_encoder(crtc); struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc); @@ -122,7 +122,7 @@ static void sun4i_crtc_atomic_disable(struct drm_crtc *crtc, } static void sun4i_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct drm_encoder *encoder = sun4i_crtc_get_encoder(crtc); struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc); diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 424ad60b4f38..52acc2f8f798 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -1742,7 +1742,7 @@ static int tegra_dc_wait_idle(struct tegra_dc *dc, unsigned long timeout) } static void tegra_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct tegra_dc *dc = to_tegra_dc(crtc); u32 value; @@ -1799,10 +1799,10 @@ static void tegra_crtc_atomic_disable(struct drm_crtc *crtc, } static void tegra_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct drm_display_mode *mode = &crtc->state->adjusted_mode; - struct tegra_dc_state *state = to_dc_state(crtc->state); + struct tegra_dc_state *crtc_state = to_dc_state(crtc->state); struct tegra_dc *dc = to_tegra_dc(crtc); u32 value; int err; @@ -1882,7 +1882,7 @@ static void tegra_crtc_atomic_enable(struct drm_crtc *crtc, tegra_dc_writel(dc, 0, DC_DISP_BORDER_COLOR); /* apply PLL and pixel clock changes */ - tegra_dc_commit_state(dc, state); + tegra_dc_commit_state(dc, crtc_state); /* program display mode */ tegra_dc_set_timings(dc, mode); diff --git a/drivers/gpu/drm/tidss/tidss_crtc.c b/drivers/gpu/drm/tidss/tidss_crtc.c index 3c5744a91d4a..848b9c7b553d 100644 --- a/drivers/gpu/drm/tidss/tidss_crtc.c +++ b/drivers/gpu/drm/tidss/tidss_crtc.c @@ -212,8 +212,10 @@ static void tidss_crtc_atomic_flush(struct drm_crtc *crtc, } static void tidss_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { + struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, + crtc); struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); struct drm_device *ddev = crtc->dev; struct tidss_device *tidss = to_tidss(ddev); @@ -255,7 +257,7 @@ static void tidss_crtc_atomic_enable(struct drm_crtc *crtc, } static void tidss_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); struct drm_device *ddev = crtc->dev; diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 518220bd092a..cf4ead0dc2e3 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -484,7 +484,7 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc) } static void tilcdc_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { tilcdc_crtc_enable(crtc); } @@ -532,7 +532,7 @@ static void tilcdc_crtc_disable(struct drm_crtc *crtc) } static void tilcdc_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { tilcdc_crtc_disable(crtc); } diff --git a/drivers/gpu/drm/vboxvideo/vbox_mode.c b/drivers/gpu/drm/vboxvideo/vbox_mode.c index 4fcc0a542b8a..931c55126148 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_mode.c +++ b/drivers/gpu/drm/vboxvideo/vbox_mode.c @@ -213,12 +213,12 @@ static void vbox_crtc_set_base_and_mode(struct drm_crtc *crtc, } static void vbox_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { } static void vbox_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { } diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index a393f93390a2..72141bb24aa5 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -472,8 +472,10 @@ int vc4_crtc_disable_at_boot(struct drm_crtc *crtc) } static void vc4_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { + struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, + crtc); struct vc4_crtc_state *old_vc4_state = to_vc4_crtc_state(old_state); struct drm_device *dev = crtc->dev; @@ -499,8 +501,10 @@ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc, } static void vc4_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { + struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, + crtc); struct drm_device *dev = crtc->dev; struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc); diff --git a/drivers/gpu/drm/vc4/vc4_txp.c b/drivers/gpu/drm/vc4/vc4_txp.c index 849dcafbfff1..e0e0b72ea65c 100644 --- a/drivers/gpu/drm/vc4/vc4_txp.c +++ b/drivers/gpu/drm/vc4/vc4_txp.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -401,15 +402,19 @@ static int vc4_txp_atomic_check(struct drm_crtc *crtc, } static void vc4_txp_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { + struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, + crtc); drm_crtc_vblank_on(crtc); vc4_hvs_atomic_enable(crtc, old_state); } static void vc4_txp_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { + struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, + crtc); struct drm_device *dev = crtc->dev; /* Disable vblank irq handling before crtc is disabled. */ diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index f84b7e61311b..48b3194ee051 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -95,12 +95,12 @@ static void virtio_gpu_crtc_mode_set_nofb(struct drm_crtc *crtc) } static void virtio_gpu_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { } static void virtio_gpu_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct drm_device *dev = crtc->dev; struct virtio_gpu_device *vgdev = dev->dev_private; diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c index 09c012d54d58..e43e4e1b268a 100644 --- a/drivers/gpu/drm/vkms/vkms_crtc.c +++ b/drivers/gpu/drm/vkms/vkms_crtc.c @@ -214,13 +214,13 @@ static int vkms_crtc_atomic_check(struct drm_crtc *crtc, } static void vkms_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { drm_crtc_vblank_on(crtc); } static void vkms_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { drm_crtc_vblank_off(crtc); } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index c4017c7a24db..9d1de5b5cc6a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -214,7 +214,7 @@ static void vmw_ldu_crtc_mode_set_nofb(struct drm_crtc *crtc) * CRTC, it makes more sense to do those at plane update time. */ static void vmw_ldu_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { } @@ -224,7 +224,7 @@ static void vmw_ldu_crtc_atomic_enable(struct drm_crtc *crtc, * @crtc: CRTC to be turned off */ static void vmw_ldu_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index 0a53d189fceb..4bdad2f2d130 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -279,7 +279,7 @@ static void vmw_sou_crtc_helper_prepare(struct drm_crtc *crtc) * This is called after a mode set has been completed. */ static void vmw_sou_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { } @@ -289,7 +289,7 @@ static void vmw_sou_crtc_atomic_enable(struct drm_crtc *crtc, * @crtc: CRTC to be turned off */ static void vmw_sou_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct vmw_private *dev_priv; struct vmw_screen_object_unit *sou; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index cf3aafd00837..5b04ec047ef3 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c @@ -408,12 +408,12 @@ static void vmw_stdu_crtc_helper_prepare(struct drm_crtc *crtc) } static void vmw_stdu_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { } static void vmw_stdu_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct vmw_private *dev_priv; struct vmw_screen_target_display_unit *stdu; diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c index 98bd48f13fd1..0b3bd62e7631 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_disp.c +++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c @@ -1449,7 +1449,7 @@ static int zynqmp_disp_crtc_setup_clock(struct drm_crtc *crtc, static void zynqmp_disp_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { struct zynqmp_disp *disp = crtc_to_disp(crtc); struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode; @@ -1480,8 +1480,10 @@ zynqmp_disp_crtc_atomic_enable(struct drm_crtc *crtc, static void zynqmp_disp_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { + struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, + crtc); struct zynqmp_disp *disp = crtc_to_disp(crtc); struct drm_plane_state *old_plane_state; diff --git a/drivers/gpu/drm/zte/zx_vou.c b/drivers/gpu/drm/zte/zx_vou.c index 5259ff2825f9..d2a529eba3c9 100644 --- a/drivers/gpu/drm/zte/zx_vou.c +++ b/drivers/gpu/drm/zte/zx_vou.c @@ -350,7 +350,7 @@ static inline void vou_chn_set_update(struct zx_crtc *zcrtc) } static void zx_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct drm_display_mode *mode = &crtc->state->adjusted_mode; bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE; @@ -455,7 +455,7 @@ static void zx_crtc_atomic_enable(struct drm_crtc *crtc, } static void zx_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct zx_crtc *zcrtc = to_zx_crtc(crtc); const struct zx_crtc_bits *bits = zcrtc->bits; diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index 4efec30f8bad..bde42988c4b5 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h @@ -417,14 +417,10 @@ struct drm_crtc_helper_funcs { * @atomic_enable must be the inverse of @atomic_disable for atomic * drivers. * - * Drivers can use the @old_crtc_state input parameter if the operations - * needed to enable the CRTC don't depend solely on the new state but - * also on the transition between the old state and the new state. - * * This function is optional. */ void (*atomic_enable)(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state); + struct drm_atomic_state *state); /** * @atomic_disable: @@ -441,15 +437,10 @@ struct drm_crtc_helper_funcs { * need to implement it if there's no need to disable anything at the * CRTC level. * - * Comparing to @disable, this one provides the additional input - * parameter @old_crtc_state which could be used to access the old - * state. Atomic drivers should consider to use this one instead - * of @disable. - * * This function is optional. */ void (*atomic_disable)(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state); + struct drm_atomic_state *state); /** * @get_scanout_position: From 178c72350d39d69448ac7b0e5be2dfbaef6d6d6d Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Fri, 22 May 2020 15:52:29 +0200 Subject: [PATCH 147/235] drm/aspeed: Set driver CMA functions with DRM_GEM_CMA_DRIVER_OPS DRM_GEM_CMA_DRIVER_OPS sets the functions in struct drm_driver to their defaults. No functional changes are made. Signed-off-by: Thomas Zimmermann Reviewed-by: Joel Stanley Acked-by: Emil Velikov Signed-off-by: Joel Stanley Link: https://patchwork.freedesktop.org/patch/msgid/20200603083132.4610-5-tzimmermann@suse.de --- drivers/gpu/drm/aspeed/aspeed_gfx_drv.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c index 2552573cacb2..771ad71cd340 100644 --- a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c +++ b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c @@ -193,12 +193,7 @@ DEFINE_DRM_GEM_CMA_FOPS(fops); static struct drm_driver aspeed_gfx_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, - .gem_create_object = drm_gem_cma_create_object_default_funcs, - .dumb_create = drm_gem_cma_dumb_create, - .prime_handle_to_fd = drm_gem_prime_handle_to_fd, - .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table, - .gem_prime_mmap = drm_gem_prime_mmap, + DRM_GEM_CMA_DRIVER_OPS, .fops = &fops, .name = "aspeed-gfx-drm", .desc = "ASPEED GFX DRM", From ec5722adb8b23d851a77412004e8faae4f83dfd0 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 24 Jun 2020 13:01:31 +0000 Subject: [PATCH 148/235] drm/fourcc: document modifier uniqueness requirements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There have suggestions to bake pitch alignment, address alignment, contiguous memory or other placement (hidden VRAM, GTT/BAR, etc) constraints into modifiers. Last time this was brought up it seemed like the consensus was to not allow this. Document this in drm_fourcc.h. There are several reasons for this. - Encoding all of these constraints in the modifiers would explode the search space pretty quickly (we only have 64 bits to work with). - Modifiers need to be unambiguous: a buffer can only have a single modifier. - Modifier users aren't expected to parse modifiers (except drivers). v2: add paragraph about aliases (Daniel) v3: fix unrelated changes sent with the patch v4: disambiguate users between driver and higher-level programs (Brian, Daniel) v5: fix AFBC example (Brian, Daniel) v6: remove duplicated paragraph (Daniel) Signed-off-by: Simon Ser Reviewed-by: Daniel Vetter Reviewed-by: Brian Starkey Cc: Daniel Stone Cc: Bas Nieuwenhuizen Cc: Dave Airlie Cc: Marek Olšák Cc: Alex Deucher Cc: Neil Armstrong Cc: Michel Dänzer Link: https://patchwork.freedesktop.org/patch/msgid/MGwgeXojKNdNXjCxuMhRlwcJM4vdYph_WJcMeGPPGMcRKtHV41XAXlh2tCc-pPJZCAhS3gwbWMWTd8f03NBA2ZYKfr0QxLhcPivpopr5c6M=@emersion.fr --- include/uapi/drm/drm_fourcc.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index 82f327801267..6f0628eb13a6 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -58,6 +58,30 @@ extern "C" { * may preserve meaning - such as number of planes - from the fourcc code, * whereas others may not. * + * Modifiers must uniquely encode buffer layout. In other words, a buffer must + * match only a single modifier. A modifier must not be a subset of layouts of + * another modifier. For instance, it's incorrect to encode pitch alignment in + * a modifier: a buffer may match a 64-pixel aligned modifier and a 32-pixel + * aligned modifier. That said, modifiers can have implicit minimal + * requirements. + * + * For modifiers where the combination of fourcc code and modifier can alias, + * a canonical pair needs to be defined and used by all drivers. Preferred + * combinations are also encouraged where all combinations might lead to + * confusion and unnecessarily reduced interoperability. An example for the + * latter is AFBC, where the ABGR layouts are preferred over ARGB layouts. + * + * There are two kinds of modifier users: + * + * - Kernel and user-space drivers: for drivers it's important that modifiers + * don't alias, otherwise two drivers might support the same format but use + * different aliases, preventing them from sharing buffers in an efficient + * format. + * - Higher-level programs interfacing with KMS/GBM/EGL/Vulkan/etc: these users + * see modifiers as opaque tokens they can check for equality and intersect. + * These users musn't need to know to reason about the modifier value + * (i.e. they are not expected to extract information out of the modifier). + * * Vendors should document their modifier usage in as much detail as * possible, to ensure maximum compatibility across devices, drivers and * applications. From b3a753f54adcd7cea01a427aa971ea4d9e0652ce Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Sat, 10 Oct 2020 20:00:58 +0300 Subject: [PATCH 149/235] drm/tilcdc: Do not keep vblank interrupts enabled all the time END_OF_FRAME interrupts have been enabled all the time since the beginning of this driver. It is about time to add this feature. Signed-off-by: Jyri Sarha Reviewed-by: Tomi Valkeinen Reviewed-by: Laurent Pinchart Link: https://patchwork.freedesktop.org/patch/msgid/fb87adebaffe8c7cb4fe7e909a45d47af08d7c6e.1602349100.git.jsarha@ti.com --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 36 +++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index cf4ead0dc2e3..0fd3dafe6404 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -147,12 +147,9 @@ static void tilcdc_crtc_enable_irqs(struct drm_device *dev) tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_V1_SYNC_LOST_INT_ENA | LCDC_V1_FRAME_DONE_INT_ENA | LCDC_V1_UNDERFLOW_INT_ENA); - tilcdc_set(dev, LCDC_DMA_CTRL_REG, - LCDC_V1_END_OF_FRAME_INT_ENA); } else { tilcdc_write(dev, LCDC_INT_ENABLE_SET_REG, LCDC_V2_UNDERFLOW_INT_ENA | - LCDC_V2_END_OF_FRAME0_INT_ENA | LCDC_FRAME_DONE | LCDC_SYNC_LOST); } } @@ -678,11 +675,44 @@ static int tilcdc_crtc_atomic_check(struct drm_crtc *crtc, static int tilcdc_crtc_enable_vblank(struct drm_crtc *crtc) { + struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); + struct drm_device *dev = crtc->dev; + struct tilcdc_drm_private *priv = dev->dev_private; + unsigned long flags; + + spin_lock_irqsave(&tilcdc_crtc->irq_lock, flags); + + tilcdc_clear_irqstatus(dev, LCDC_END_OF_FRAME0); + + if (priv->rev == 1) + tilcdc_set(dev, LCDC_DMA_CTRL_REG, + LCDC_V1_END_OF_FRAME_INT_ENA); + else + tilcdc_set(dev, LCDC_INT_ENABLE_SET_REG, + LCDC_V2_END_OF_FRAME0_INT_ENA); + + spin_unlock_irqrestore(&tilcdc_crtc->irq_lock, flags); + return 0; } static void tilcdc_crtc_disable_vblank(struct drm_crtc *crtc) { + struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); + struct drm_device *dev = crtc->dev; + struct tilcdc_drm_private *priv = dev->dev_private; + unsigned long flags; + + spin_lock_irqsave(&tilcdc_crtc->irq_lock, flags); + + if (priv->rev == 1) + tilcdc_clear(dev, LCDC_DMA_CTRL_REG, + LCDC_V1_END_OF_FRAME_INT_ENA); + else + tilcdc_clear(dev, LCDC_INT_ENABLE_SET_REG, + LCDC_V2_END_OF_FRAME0_INT_ENA); + + spin_unlock_irqrestore(&tilcdc_crtc->irq_lock, flags); } static void tilcdc_crtc_reset(struct drm_crtc *crtc) From 882bceffa8ca7ac7d504affca5810852a7a0a449 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Sat, 10 Oct 2020 20:00:59 +0300 Subject: [PATCH 150/235] drm/tilcdc: Remove tilcdc_crtc_max_width(), use private data We already have a private data member for maximum display width so let's use it and get rid of the redundant tilcdc_crtc_max_width(). The LCDC version probing is moved to before reading the device tree properties so that the version information is available when private data maximum width is initialized, if "max-width" property is not found. Signed-off-by: Jyri Sarha Reviewed-by: Tomi Valkeinen Link: https://patchwork.freedesktop.org/patch/msgid/73683d2ce151cffb811a756595b02892eeac3d84.1602349100.git.jsarha@ti.com --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 16 +----------- drivers/gpu/drm/tilcdc/tilcdc_drv.c | 38 +++++++++++++++------------- drivers/gpu/drm/tilcdc/tilcdc_drv.h | 7 ++--- 3 files changed, 26 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 0fd3dafe6404..da2ab2aa3577 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -754,20 +754,6 @@ static const struct drm_crtc_funcs tilcdc_crtc_funcs = { .disable_vblank = tilcdc_crtc_disable_vblank, }; -int tilcdc_crtc_max_width(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct tilcdc_drm_private *priv = dev->dev_private; - int max_width = 0; - - if (priv->rev == 1) - max_width = 1024; - else if (priv->rev == 2) - max_width = 2048; - - return max_width; -} - static enum drm_mode_status tilcdc_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode) @@ -780,7 +766,7 @@ tilcdc_crtc_mode_valid(struct drm_crtc *crtc, * check to see if the width is within the range that * the LCD Controller physically supports */ - if (mode->hdisplay > tilcdc_crtc_max_width(crtc)) + if (mode->hdisplay > priv->max_width) return MODE_VIRTUAL_X; /* width must be multiple of 16 */ diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 4f5fc3e87383..c5f82e693f1a 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -105,7 +105,7 @@ static void modeset_init(struct drm_device *dev) dev->mode_config.min_width = 0; dev->mode_config.min_height = 0; - dev->mode_config.max_width = tilcdc_crtc_max_width(priv->crtc); + dev->mode_config.max_width = priv->max_width; dev->mode_config.max_height = 2048; dev->mode_config.funcs = &mode_config_funcs; } @@ -218,22 +218,6 @@ static int tilcdc_init(struct drm_driver *ddrv, struct device *dev) goto init_failed; } - if (of_property_read_u32(node, "max-bandwidth", &priv->max_bandwidth)) - priv->max_bandwidth = TILCDC_DEFAULT_MAX_BANDWIDTH; - - DBG("Maximum Bandwidth Value %d", priv->max_bandwidth); - - if (of_property_read_u32(node, "max-width", &priv->max_width)) - priv->max_width = TILCDC_DEFAULT_MAX_WIDTH; - - DBG("Maximum Horizontal Pixel Width Value %dpixels", priv->max_width); - - if (of_property_read_u32(node, "max-pixelclock", - &priv->max_pixelclock)) - priv->max_pixelclock = TILCDC_DEFAULT_MAX_PIXELCLOCK; - - DBG("Maximum Pixel Clock Value %dKHz", priv->max_pixelclock); - pm_runtime_enable(dev); /* Determine LCD IP Version */ @@ -287,6 +271,26 @@ static int tilcdc_init(struct drm_driver *ddrv, struct device *dev) } } + if (of_property_read_u32(node, "max-bandwidth", &priv->max_bandwidth)) + priv->max_bandwidth = TILCDC_DEFAULT_MAX_BANDWIDTH; + + DBG("Maximum Bandwidth Value %d", priv->max_bandwidth); + + if (of_property_read_u32(node, "max-width", &priv->max_width)) { + if (priv->rev == 1) + priv->max_width = TILCDC_DEFAULT_MAX_WIDTH_V1; + else + priv->max_width = TILCDC_DEFAULT_MAX_WIDTH_V2; + } + + DBG("Maximum Horizontal Pixel Width Value %dpixels", priv->max_width); + + if (of_property_read_u32(node, "max-pixelclock", + &priv->max_pixelclock)) + priv->max_pixelclock = TILCDC_DEFAULT_MAX_PIXELCLOCK; + + DBG("Maximum Pixel Clock Value %dKHz", priv->max_pixelclock); + ret = tilcdc_crtc_create(ddev); if (ret < 0) { dev_err(dev, "failed to create crtc\n"); diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h index 18815e75ca4f..d29806ca8817 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h @@ -28,8 +28,10 @@ struct drm_plane; /* Defaulting to pixel clock defined on AM335x */ #define TILCDC_DEFAULT_MAX_PIXELCLOCK 126000 -/* Defaulting to max width as defined on AM335x */ -#define TILCDC_DEFAULT_MAX_WIDTH 2048 +/* Maximum display width for LCDC V1 */ +#define TILCDC_DEFAULT_MAX_WIDTH_V1 1024 +/* ... and for LCDC V2 found on AM335x: */ +#define TILCDC_DEFAULT_MAX_WIDTH_V2 2048 /* * This may need some tweaking, but want to allow at least 1280x1024@60 * with optimized DDR & EMIF settings tweaked 1920x1080@24 appears to @@ -158,7 +160,6 @@ void tilcdc_crtc_set_panel_info(struct drm_crtc *crtc, const struct tilcdc_panel_info *info); void tilcdc_crtc_set_simulate_vesa_sync(struct drm_crtc *crtc, bool simulate_vesa_sync); -int tilcdc_crtc_max_width(struct drm_crtc *crtc); void tilcdc_crtc_shutdown(struct drm_crtc *crtc); int tilcdc_crtc_update_fb(struct drm_crtc *crtc, struct drm_framebuffer *fb, From bf296b35489b46780b73b74ad984d06750ed5479 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 11 Oct 2020 16:01:31 -0700 Subject: [PATCH 151/235] drm/aspeed: Fix Kconfig warning & subsequent build errors Kernel test robot reported build errors (undefined references) that didn't make much sense. After reproducing them, there is also a Kconfig warning that is the root cause of the build errors, so fix that Kconfig problem. Fixes this Kconfig warning: WARNING: unmet direct dependencies detected for CMA Depends on [n]: MMU [=n] Selected by [m]: - DRM_ASPEED_GFX [=m] && HAS_IOMEM [=y] && DRM [=m] && OF [=y] && (COMPILE_TEST [=y] || ARCH_ASPEED) && HAVE_DMA_CONTIGUOUS [=y] and these dependent build errors: (.text+0x10c8c): undefined reference to `start_isolate_page_range' microblaze-linux-ld: (.text+0x10f14): undefined reference to `test_pages_isolated' microblaze-linux-ld: (.text+0x10fd0): undefined reference to `undo_isolate_page_range' Fixes: 76356a966e33 ("drm: aspeed: Clean up Kconfig options") Reported-by: kernel test robot Signed-off-by: Randy Dunlap Reviewed-by: Joel Stanley Cc: Joel Stanley Cc: Andrew Jeffery Cc: Daniel Vetter Cc: Michal Simek Cc: Andrew Morton Cc: Mike Rapoport Cc: linux-mm@kvack.org Cc: linux-aspeed@lists.ozlabs.org Cc: linux-arm-kernel@lists.infradead.org Cc: David Airlie Cc: dri-devel@lists.freedesktop.org Signed-off-by: Joel Stanley Link: https://patchwork.freedesktop.org/patch/msgid/20201011230131.4922-1-rdunlap@infradead.org Signed-off-by: Joel Stanley --- drivers/gpu/drm/aspeed/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/aspeed/Kconfig b/drivers/gpu/drm/aspeed/Kconfig index 018383cfcfa7..5e95bcea43e9 100644 --- a/drivers/gpu/drm/aspeed/Kconfig +++ b/drivers/gpu/drm/aspeed/Kconfig @@ -3,6 +3,7 @@ config DRM_ASPEED_GFX tristate "ASPEED BMC Display Controller" depends on DRM && OF depends on (COMPILE_TEST || ARCH_ASPEED) + depends on MMU select DRM_KMS_HELPER select DRM_KMS_CMA_HELPER select DMA_CMA if HAVE_DMA_CONTIGUOUS From a4e45e5d3097c2213802823794f845acb51e8bc7 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Fri, 9 Oct 2020 09:49:52 +0200 Subject: [PATCH 152/235] MAINTAINERS: Add myself as a maintainer for vc4 Eric isn't working on vc4 anymore and I've been working on it, as well as merging patches for it, recently so let's make it official so I don't miss patches. Signed-off-by: Maxime Ripard Reviewed-by: Eric Anholt Link: https://patchwork.freedesktop.org/patch/msgid/20201009074952.11345-1-maxime@cerno.tech --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 1c4dc5c42c3d..399b44bd35e6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5919,6 +5919,7 @@ F: include/uapi/drm/v3d_drm.h DRM DRIVERS FOR VC4 M: Eric Anholt +M: Maxime Ripard S: Supported T: git git://github.com/anholt/linux T: git git://anongit.freedesktop.org/drm/drm-misc From 8bca49e43fb5994bd2a03f3f114cf89bc6f87a14 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 22 Apr 2020 15:51:55 +0300 Subject: [PATCH 153/235] drm: shmobile: Reduce include dependencies This file doesn't need anything provided by . All it needs are some types, which are provided by . Drop unneeded completely. Signed-off-by: Andy Shevchenko Reviewed-by: Laurent Pinchart Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20200422125201.37618-1-andriy.shevchenko@linux.intel.com --- include/linux/platform_data/shmob_drm.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/linux/platform_data/shmob_drm.h b/include/linux/platform_data/shmob_drm.h index fe815d7d9f58..d661399b217d 100644 --- a/include/linux/platform_data/shmob_drm.h +++ b/include/linux/platform_data/shmob_drm.h @@ -10,8 +10,6 @@ #ifndef __SHMOB_DRM_H__ #define __SHMOB_DRM_H__ -#include - #include enum shmob_drm_clk_source { From 412ae84cb4dd2bd1cccbeb996fee47cf4d80a3ad Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 13 Oct 2020 16:27:14 +0300 Subject: [PATCH 154/235] drm/virtio: Use UUID API for importing the UUID There is import_uuid() function which imports u8 array to the uuid_t. Use it instead of open coding variant. This allows to hide the uuid_t internals. Reviewed-by: David Stevens Signed-off-by: Andy Shevchenko Link: http://patchwork.freedesktop.org/patch/msgid/20201013132714.70973-1-andriy.shevchenko@linux.intel.com Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_vq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 6434b9fb38a6..c1824f536936 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -1141,7 +1141,7 @@ static void virtio_gpu_cmd_resource_uuid_cb(struct virtio_gpu_device *vgdev, if (resp_type == VIRTIO_GPU_RESP_OK_RESOURCE_UUID && obj->uuid_state == STATE_INITIALIZING) { - memcpy(&obj->uuid.b, resp->uuid, sizeof(obj->uuid.b)); + import_uuid(&obj->uuid, resp->uuid); obj->uuid_state = STATE_OK; } else { obj->uuid_state = STATE_ERR; From 9528a02430dfd4e8931578cee572203fc262c63b Mon Sep 17 00:00:00 2001 From: Sumit Semwal Date: Wed, 2 Sep 2020 12:14:06 +0530 Subject: [PATCH 155/235] dt-bindings: display: panel: Add bindings for Novatek nt36672a Novatek nt36672a is a display driver IC that can drive DSI panel. It is also present in the Tianma video mode panel, which is a FHD+ panel with a resolution of 1080x2246 and 6.18 inches size. It is found in some of the Poco F1 phones. This patch adds the display driver for the IC, with support added for this tianma fhd video mode panel. Signed-off-by: Sumit Semwal Reviewed-by: Rob Herring Reviewed-by: Bjorn Andersson Reviewed-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200902064407.30712-2-sumit.semwal@linaro.org --- .../display/panel/novatek,nt36672a.yaml | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml diff --git a/Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml b/Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml new file mode 100644 index 000000000000..d2170de6b723 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml @@ -0,0 +1,87 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/novatek,nt36672a.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Novatek NT36672A based DSI display Panels + +maintainers: + - Sumit Semwal + +description: | + The nt36672a IC from Novatek is a generic DSI Panel IC used to drive dsi + panels. + Right now, support is added only for a Tianma FHD+ LCD display panel with a + resolution of 1080x2246. It is a video mode DSI panel. + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: + items: + - enum: + - tianma,fhd-video + - const: novatek,nt36672a + description: This indicates the panel manufacturer of the panel that is + in turn using the NT36672A panel driver. This compatible string + determines how the NT36672A panel driver is configured for the indicated + panel. The novatek,nt36672a compatible shall always be provided as a fallback. + + reset-gpios: + description: phandle of gpio for reset line - This should be 8mA, gpio + can be configured using mux, pinctrl, pinctrl-names (active high) + + vddio-supply: + description: phandle of the regulator that provides the supply voltage + Power IC supply + + vddpos-supply: + description: phandle of the positive boost supply regulator + + vddneg-supply: + description: phandle of the negative boost supply regulator + + reg: true + port: true + +required: + - compatible + - reg + - vddi0-supply + - vddpos-supply + - vddneg-supply + - reset-gpios + - port + +unevaluatedProperties: false + +examples: + - |+ + #include + + dsi0 { + #address-cells = <1>; + #size-cells = <0>; + + panel@0 { + compatible = "tianma,fhd-video", "novatek,nt36672a"; + reg = <0>; + vddi0-supply = <&vreg_l14a_1p88>; + vddpos-supply = <&lab>; + vddneg-supply = <&ibb>; + + reset-gpios = <&tlmm 6 GPIO_ACTIVE_HIGH>; + + #address-cells = <1>; + #size-cells = <0>; + port { + tianma_nt36672a_in_0: endpoint { + remote-endpoint = <&dsi0_out>; + }; + }; + }; + }; + +... From 070c7fa58bce986eb7a504390dd429edcb068f44 Mon Sep 17 00:00:00 2001 From: Sumit Semwal Date: Wed, 2 Sep 2020 12:14:07 +0530 Subject: [PATCH 156/235] drm: panel: Add novatek nt36672a panel driver Novatek NT36672a is a generic DSI IC that drives command and video mode panels. Add the driver for it. Right now adding support for some Poco F1 phones that have an LCD panel from Tianma connected with this IC, with a resolution of 1080x2246 that operates in DSI video mode. During testing, Benni Steini helped us fix the reset sequence timing (from 10ms to 20ms), to get the bootanimation to work on Android. With current AOSP, we need to increase it to 200ms - this seems to be a safe high value to avoid a white screen occasionally. Signed-off-by: Sumit Semwal Cc: Benni Steini Reviewed-by: Bjorn Andersson Reviewed-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200902064407.30712-3-sumit.semwal@linaro.org --- MAINTAINERS | 7 + drivers/gpu/drm/panel/Kconfig | 10 + drivers/gpu/drm/panel/Makefile | 1 + .../gpu/drm/panel/panel-novatek-nt36672a.c | 711 ++++++++++++++++++ 4 files changed, 729 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-novatek-nt36672a.c diff --git a/MAINTAINERS b/MAINTAINERS index 399b44bd35e6..e11425948ced 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5542,6 +5542,13 @@ T: git git://anongit.freedesktop.org/drm/drm-misc F: Documentation/devicetree/bindings/display/panel/novatek,nt35510.yaml F: drivers/gpu/drm/panel/panel-novatek-nt35510.c +DRM DRIVER FOR NOVATEK NT36672A PANELS +M: Sumit Semwal +S: Maintained +T: git git://anongit.freedesktop.org/drm/drm-misc +F: Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml +F: drivers/gpu/drm/panel/panel-novatek-nt36672a.c + DRM DRIVER FOR NVIDIA GEFORCE/QUADRO GPUS M: Ben Skeggs L: dri-devel@lists.freedesktop.org diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index b9dbedf8f15e..1bf6c4d62c92 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -208,6 +208,16 @@ config DRM_PANEL_NOVATEK_NT35510 around the Novatek NT35510 display controller, such as some Hydis panels. +config DRM_PANEL_NOVATEK_NT36672A + tristate "Novatek NT36672A DSI panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for the panels built + around the Novatek NT36672A display controller, such as some + Tianma panels used in a few Xiaomi Poco F1 mobile phones. + config DRM_PANEL_NOVATEK_NT39016 tristate "Novatek NT39016 RGB/SPI panel" depends on OF && SPI diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 2ba560bca61d..2509e0bd6a57 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35510) += panel-novatek-nt35510.o +obj-$(CONFIG_DRM_PANEL_NOVATEK_NT36672A) += panel-novatek-nt36672a.o obj-$(CONFIG_DRM_PANEL_NOVATEK_NT39016) += panel-novatek-nt39016.o obj-$(CONFIG_DRM_PANEL_MANTIX_MLAF057WE51) += panel-mantix-mlaf057we51.o obj-$(CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO) += panel-olimex-lcd-olinuxino.o diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36672a.c b/drivers/gpu/drm/panel/panel-novatek-nt36672a.c new file mode 100644 index 000000000000..533cd3934b8b --- /dev/null +++ b/drivers/gpu/drm/panel/panel-novatek-nt36672a.c @@ -0,0 +1,711 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Linaro Ltd + * Author: Sumit Semwal + * + * This driver is for the DSI interface to panels using the NT36672A display driver IC + * from Novatek. + * Currently supported are the Tianma FHD+ panels found in some Xiaomi phones, including + * some variants of the Poco F1 phone. + * + * Panels using the Novatek NT37762A IC should add appropriate configuration per-panel and + * use this driver. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include