From 3a8a5aba142a44eaeba0cb0ec1b4a8f177b5e59a Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 26 Nov 2019 11:15:27 +0100 Subject: drm/mgag200: Extract device type from flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a conversion function that extracts the device type from the PCI id-table flags. Allows for storing additional information in the other flag bits. Signed-off-by: Thomas Zimmermann Fixes: 81da87f63a1e ("drm: Replace drm_gem_vram_push_to_system() with kunmap + unpin") Reviewed-by: Daniel Vetter Cc: John Donnelly Cc: Gerd Hoffmann Cc: Dave Airlie Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: David Airlie Cc: Sam Ravnborg Cc: Emil Velikov Cc: "Y.C. Chen" Cc: Laurent Pinchart Cc: "José Roberto de Souza" Cc: Andrzej Pietrasiewicz Cc: dri-devel@lists.freedesktop.org Cc: # v5.3+ Link: https://patchwork.freedesktop.org/patch/msgid/20191126101529.20356-2-tzimmermann@suse.de --- drivers/gpu/drm/mgag200/mgag200_drv.h | 7 +++++++ drivers/gpu/drm/mgag200/mgag200_main.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index 0ea9a525e57d..976404634092 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -150,6 +150,8 @@ enum mga_type { G200_EW3, }; +#define MGAG200_TYPE_MASK (0x000000ff) + #define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B) struct mga_device { @@ -181,6 +183,11 @@ struct mga_device { u32 unique_rev_id; }; +static inline enum mga_type +mgag200_type_from_driver_data(kernel_ulong_t driver_data) +{ + return (enum mga_type)(driver_data & MGAG200_TYPE_MASK); +} /* mgag200_mode.c */ int mgag200_modeset_init(struct mga_device *mdev); void mgag200_modeset_fini(struct mga_device *mdev); diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c index 5f74aabcd3df..517c5693ad69 100644 --- a/drivers/gpu/drm/mgag200/mgag200_main.c +++ b/drivers/gpu/drm/mgag200/mgag200_main.c @@ -94,7 +94,7 @@ static int mgag200_device_init(struct drm_device *dev, struct mga_device *mdev = dev->dev_private; int ret, option; - mdev->type = flags; + mdev->type = mgag200_type_from_driver_data(flags); /* Hardcode the number of CRTCs to 1 */ mdev->num_crtc = 1; -- cgit v1.2.3 From d6d437d97d54c85a1a93967b2745e31dff03365a Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 26 Nov 2019 11:15:28 +0100 Subject: drm/mgag200: Store flags from PCI driver data in device structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The flags field in struct mga_device has been unused so far. We now use it to store flag bits from the PCI driver. Signed-off-by: Thomas Zimmermann Reviewed-by: Daniel Vetter Fixes: 81da87f63a1e ("drm: Replace drm_gem_vram_push_to_system() with kunmap + unpin") Cc: John Donnelly Cc: Gerd Hoffmann Cc: Dave Airlie Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: David Airlie Cc: Sam Ravnborg Cc: "Y.C. Chen" Cc: Neil Armstrong Cc: Thomas Gleixner Cc: "José Roberto de Souza" Cc: Andrzej Pietrasiewicz Cc: dri-devel@lists.freedesktop.org Cc: # v5.3+ Link: https://patchwork.freedesktop.org/patch/msgid/20191126101529.20356-3-tzimmermann@suse.de --- drivers/gpu/drm/mgag200/mgag200_drv.h | 8 ++++++++ drivers/gpu/drm/mgag200/mgag200_main.c | 1 + 2 files changed, 9 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index 976404634092..4b4f9ce74a84 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -151,6 +151,7 @@ enum mga_type { }; #define MGAG200_TYPE_MASK (0x000000ff) +#define MGAG200_FLAG_MASK (0x00ffff00) #define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B) @@ -188,6 +189,13 @@ mgag200_type_from_driver_data(kernel_ulong_t driver_data) { return (enum mga_type)(driver_data & MGAG200_TYPE_MASK); } + +static inline unsigned long +mgag200_flags_from_driver_data(kernel_ulong_t driver_data) +{ + return driver_data & MGAG200_FLAG_MASK; +} + /* mgag200_mode.c */ int mgag200_modeset_init(struct mga_device *mdev); void mgag200_modeset_fini(struct mga_device *mdev); diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c index 517c5693ad69..e1bc5b0aa774 100644 --- a/drivers/gpu/drm/mgag200/mgag200_main.c +++ b/drivers/gpu/drm/mgag200/mgag200_main.c @@ -94,6 +94,7 @@ static int mgag200_device_init(struct drm_device *dev, struct mga_device *mdev = dev->dev_private; int ret, option; + mdev->flags = mgag200_flags_from_driver_data(flags); mdev->type = mgag200_type_from_driver_data(flags); /* Hardcode the number of CRTCs to 1 */ -- cgit v1.2.3 From 1591fadf857cdbaf2baa55e421af99a61354713c Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 26 Nov 2019 11:15:29 +0100 Subject: drm/mgag200: Add workaround for HW that does not support 'startadd' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's at least one system that does not interpret the value of the device's 'startadd' field correctly, which leads to incorrectly displayed scanout buffers. Always placing the active scanout buffer at offset 0 works around the problem. Signed-off-by: Thomas Zimmermann Reported-by: John Donnelly Tested-by: John Donnelly Reviewed-by: Daniel Vetter Fixes: 81da87f63a1e ("drm: Replace drm_gem_vram_push_to_system() with kunmap + unpin") Cc: Gerd Hoffmann Cc: Dave Airlie Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: David Airlie Cc: Sam Ravnborg Cc: "Y.C. Chen" Cc: Neil Armstrong Cc: Thomas Gleixner Cc: "José Roberto de Souza" Cc: Andrzej Pietrasiewicz Cc: dri-devel@lists.freedesktop.org Cc: # v5.3+ Link: https://gitlab.freedesktop.org/drm/misc/issues/7 Link: https://patchwork.freedesktop.org/patch/msgid/20191126101529.20356-4-tzimmermann@suse.de --- drivers/gpu/drm/mgag200/mgag200_drv.c | 36 ++++++++++++++++++++++++++++++++++- drivers/gpu/drm/mgag200/mgag200_drv.h | 3 +++ 2 files changed, 38 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index 397f8b0a9af8..d43951caeea0 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -30,6 +30,8 @@ module_param_named(modeset, mgag200_modeset, int, 0400); static struct drm_driver driver; static const struct pci_device_id pciidlist[] = { + { PCI_VENDOR_ID_MATROX, 0x522, PCI_VENDOR_ID_SUN, 0x4852, 0, 0, + G200_SE_A | MGAG200_FLAG_HW_BUG_NO_STARTADD}, { PCI_VENDOR_ID_MATROX, 0x522, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_A }, { PCI_VENDOR_ID_MATROX, 0x524, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_B }, { PCI_VENDOR_ID_MATROX, 0x530, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EV }, @@ -60,6 +62,35 @@ static void mga_pci_remove(struct pci_dev *pdev) DEFINE_DRM_GEM_FOPS(mgag200_driver_fops); +static bool mgag200_pin_bo_at_0(const struct mga_device *mdev) +{ + return mdev->flags & MGAG200_FLAG_HW_BUG_NO_STARTADD; +} + +int mgag200_driver_dumb_create(struct drm_file *file, + struct drm_device *dev, + struct drm_mode_create_dumb *args) +{ + struct mga_device *mdev = dev->dev_private; + unsigned long pg_align; + + if (WARN_ONCE(!dev->vram_mm, "VRAM MM not initialized")) + return -EINVAL; + + pg_align = 0ul; + + /* + * Aligning scanout buffers to the size of the video ram forces + * placement at offset 0. Works around a bug where HW does not + * respect 'startadd' field. + */ + if (mgag200_pin_bo_at_0(mdev)) + pg_align = PFN_UP(mdev->mc.vram_size); + + return drm_gem_vram_fill_create_dumb(file, dev, &dev->vram_mm->bdev, + pg_align, false, args); +} + static struct drm_driver driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET, .load = mgag200_driver_load, @@ -71,7 +102,10 @@ static struct drm_driver driver = { .major = DRIVER_MAJOR, .minor = DRIVER_MINOR, .patchlevel = DRIVER_PATCHLEVEL, - DRM_GEM_VRAM_DRIVER + .debugfs_init = drm_vram_mm_debugfs_init, + .dumb_create = mgag200_driver_dumb_create, + .dumb_map_offset = drm_gem_vram_driver_dumb_mmap_offset, + .gem_prime_mmap = drm_gem_prime_mmap, }; static struct pci_driver mgag200_pci_driver = { diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index 4b4f9ce74a84..aa32aad222c2 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -150,6 +150,9 @@ enum mga_type { G200_EW3, }; +/* HW does not handle 'startadd' field correct. */ +#define MGAG200_FLAG_HW_BUG_NO_STARTADD (1ul << 8) + #define MGAG200_TYPE_MASK (0x000000ff) #define MGAG200_FLAG_MASK (0x00ffff00) -- cgit v1.2.3 From d6d07ca19c045924f2b9cac14cb277cc34f85d43 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Mon, 2 Dec 2019 05:36:50 -0800 Subject: drm/dp_mst: Fix build on systems with STACKTRACE_SUPPORT=n On systems with STACKTRACE_SUPPORT=n, we get: WARNING: unmet direct dependencies detected for STACKTRACE Depends on [n]: STACKTRACE_SUPPORT Selected by [y]: - STACKDEPOT [=y] and build errors such as: m68k-linux-ld: kernel/stacktrace.o: in function `stack_trace_save': (.text+0x11c): undefined reference to `save_stack_trace' Add the missing deendency on STACKTRACE_SUPPORT. Fixes: 12a280c72868 ("drm/dp_mst: Add topology ref history tracking for debugging") Cc: Lyude Paul Cc: Sean Paul Signed-off-by: Guenter Roeck Signed-off-by: Lyude Paul Link: https://patchwork.freedesktop.org/patch/msgid/20191202133650.11964-1-linux@roeck-us.net --- drivers/gpu/drm/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 617d9c3a86c3..58e9772c2586 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -95,6 +95,7 @@ config DRM_KMS_FB_HELPER config DRM_DEBUG_DP_MST_TOPOLOGY_REFS bool "Enable refcount backtrace history in the DP MST helpers" + depends on STACKTRACE_SUPPORT select STACKDEPOT depends on DRM_KMS_HELPER depends on DEBUG_KERNEL -- cgit v1.2.3 From d9c148cfaf0a99296ad7c92fb8b65952196053ec Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 14 Nov 2019 10:03:43 +0200 Subject: drm/omap: fix dma_addr refcounting cec4fa7511ef7a73eb635834e9d85b25a5b47a98 ("drm/omap: use refcount API to track the number of users of dma_addr") changed omap_gem.c to use refcounting API to track dma_addr uses. However, the driver only tracks the refcounts for non-contiguous buffers, and the patch didn't fully take this in account. After the patch, the driver always decreased refcount in omap_gem_unpin, instead of decreasing the refcount only for non-contiguous buffers. This leads to refcounting mismatch. As for the contiguous cases the refcount is never increased, fix this issue by returning from omap_gem_unpin if the buffer being unpinned is contiguous. Signed-off-by: Tomi Valkeinen Link: https://patchwork.freedesktop.org/patch/msgid/20191114080343.30704-1-tomi.valkeinen@ti.com Fixes: cec4fa7511ef ("drm/omap: use refcount API to track the number of users of dma_addr") Reviewed-by: Laurent Pinchart --- drivers/gpu/drm/omapdrm/omap_gem.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index e518d93ca6df..d08ae95ecc0a 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -843,9 +843,13 @@ fail: */ static void omap_gem_unpin_locked(struct drm_gem_object *obj) { + struct omap_drm_private *priv = obj->dev->dev_private; struct omap_gem_object *omap_obj = to_omap_bo(obj); int ret; + if (omap_gem_is_contiguous(omap_obj) || !priv->has_dmm) + return; + if (refcount_dec_and_test(&omap_obj->dma_addr_cnt)) { ret = tiler_unpin(omap_obj->block); if (ret) { -- cgit v1.2.3 From e5a6ca27eb72c67533ddfc11c06df84beaa167fa Mon Sep 17 00:00:00 2001 From: Wayne Lin Date: Tue, 3 Dec 2019 12:24:23 +0800 Subject: drm/dp_mst: Correct the bug in drm_dp_update_payload_part1() [Why] If the payload_state is DP_PAYLOAD_DELETE_LOCAL in series, current code doesn't delete the payload at current index and just move the index to next one after shuffling payloads. [How] Drop the i++ increasing part in for loop head and decide whether to increase the index or not according to payload_state of current payload. Changes since v1: * Refine the code to have it easy reading * Amend the commit message to meet the way code is modified now. Signed-off-by: Wayne Lin Reviewed-by: Lyude Paul Fixes: 706246c761dd ("drm/dp_mst: Refactor drm_dp_update_payload_part1()") Cc: Daniel Vetter Cc: Juston Li Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Sean Paul Cc: David Airlie Cc: Daniel Vetter Cc: dri-devel@lists.freedesktop.org Cc: # v5.1+ [Added cc for stable] Signed-off-by: Lyude Paul Link: https://patchwork.freedesktop.org/patch/msgid/20191203042423.5961-1-Wayne.Lin@amd.com --- drivers/gpu/drm/drm_dp_mst_topology.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index ae5809a1f19a..273dd80fabf3 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -3176,9 +3176,11 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) drm_dp_mst_topology_put_port(port); } - for (i = 0; i < mgr->max_payloads; i++) { - if (mgr->payloads[i].payload_state != DP_PAYLOAD_DELETE_LOCAL) + for (i = 0; i < mgr->max_payloads; /* do nothing */) { + if (mgr->payloads[i].payload_state != DP_PAYLOAD_DELETE_LOCAL) { + i++; continue; + } DRM_DEBUG_KMS("removing payload %d\n", i); for (j = i; j < mgr->max_payloads - 1; j++) { -- cgit v1.2.3