From 4ee48cc5586bf519df19894273002aa8ef7b70ad Mon Sep 17 00:00:00 2001 From: Biju Das Date: Thu, 23 Jul 2020 12:10:54 +0100 Subject: drm: of: Fix double-free bug Fix double-free bug in the error path. Fixes: 6529007522de ("drm: of: Add drm_of_lvds_get_dual_link_pixel_order") Reported-by: Pavel Machek Signed-off-by: Biju Das Reviewed-by: Laurent Pinchart Cc: stable@vger.kernel.org Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/1595502654-40595-1-git-send-email-biju.das.jz@bp.renesas.com --- drivers/gpu/drm/drm_of.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c index b50b44e76279..8fc3f67e3e76 100644 --- a/drivers/gpu/drm/drm_of.c +++ b/drivers/gpu/drm/drm_of.c @@ -322,10 +322,8 @@ static int drm_of_lvds_get_remote_pixels_type( * configurations by passing the endpoints explicitly to * drm_of_lvds_get_dual_link_pixel_order(). */ - if (!current_pt || pixels_type != current_pt) { - of_node_put(remote_port); + if (!current_pt || pixels_type != current_pt) return -EINVAL; - } } return pixels_type; -- cgit v1.2.3 From f10761c9df96a882438faa09dcd25261281d69ca Mon Sep 17 00:00:00 2001 From: Laurentiu Palcu Date: Mon, 20 Jul 2020 15:42:27 +0300 Subject: drm/bridge/adv7511: set the bridge type properly After the drm_bridge_connector_init() helper function has been added, the ADV driver has been changed accordingly. However, the 'type' field of the bridge structure was left unset, which makes the helper function always return -EINVAL. Signed-off-by: Laurentiu Palcu Reviewed-by: Laurent Pinchart Reviewed-by: Vinod Koul Tested-by: Vinod Koul # tested on DragonBoard 410c Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200720124228.12552-1-laurentiu.palcu@oss.nxp.com --- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 87b58c1acff4..648eb23d0784 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -1224,6 +1224,7 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) adv7511->bridge.funcs = &adv7511_bridge_funcs; adv7511->bridge.of_node = dev->of_node; + adv7511->bridge.type = DRM_MODE_CONNECTOR_HDMIA; drm_bridge_add(&adv7511->bridge); -- cgit v1.2.3 From 667d73d72f3188909914c60e97a1db33edc21971 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Thu, 16 Jul 2020 13:21:22 -0700 Subject: drm: panel: simple: Delay HPD checking on boe_nv133fhm_n61 for 15 ms On boe_nv133fhm_n62 (and presumably on boe_nv133fhm_n61) a scope shows a small spike on the HPD line right when you power the panel on. The picture looks something like this: +-------------------------------------- | | | Power ---+ +--- | ++ | +----+| | HPD -----+ +---------------------------+ So right when power is applied there's a little bump in HPD and then there's small spike right before it goes low. The total time of the little bump plus the spike was measured on one panel as being 8 ms long. The total time for the HPD to go high on the same panel was 51.2 ms, though the datasheet only promises it is < 200 ms. When asked about this glitch, BOE indicated that it was expected and persisted until the TCON has been initialized. If this was a real hotpluggable DP panel then this wouldn't matter a whole lot. We'd debounce the HPD signal for a really long time and so the little blip wouldn't hurt. However, this is not a hotpluggable DP panel and the the debouncing logic isn't needed and just shows down the time needed to get the display working. This is why the code in panel_simple_prepare() doesn't do debouncing and just waits for HPD to go high once. Unfortunately if we get unlucky and happen to poll the HPD line right at the spike we can try talking to the panel before it's ready. Let's handle this situation by putting in a 15 ms prepare delay and decreasing the "hpd absent delay" by 15 ms. That means: * If you don't have HPD hooked up at all you've still got the hardcoded 200 ms delay. * If you've got HPD hooked up you will always wait at least 15 ms before checking HPD. The only case where this could be bad is if the panel is sharing a voltage rail with something else in the system and was already turned on long before the panel came up. In such a case we'll be delaying 15 ms for no reason, but it's not a huge delay and I don't see any other good solution to handle that case. Even though the delay was measured as 8 ms, 15 ms was chosen to give a bit of margin. Signed-off-by: Douglas Anderson Reviewed-by: Bjorn Andersson Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200716132120.1.I01e738cd469b61fc9b28b3ef1c6541a4f48b11bf@changeid --- drivers/gpu/drm/panel/panel-simple.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 5178f87d6574..4aeb960ccf15 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -1250,7 +1250,21 @@ static const struct panel_desc boe_nv133fhm_n61 = { .height = 165, }, .delay = { - .hpd_absent_delay = 200, + /* + * When power is first given to the panel there's a short + * spike on the HPD line. It was explained that this spike + * was until the TCON data download was complete. On + * one system this was measured at 8 ms. We'll put 15 ms + * in the prepare delay just to be safe and take it away + * from the hpd_absent_delay (which would otherwise be 200 ms) + * to handle this. That means: + * - If HPD isn't hooked up you still have 200 ms delay. + * - If HPD is hooked up we won't try to look at it for the + * first 15 ms. + */ + .prepare = 15, + .hpd_absent_delay = 185, + .unprepare = 500, }, .bus_format = MEDIA_BUS_FMT_RGB888_1X24, -- cgit v1.2.3 From d76acc9fcddeda53b985b029c890976a87fcc3fc Mon Sep 17 00:00:00 2001 From: Jitao Shi Date: Tue, 14 Jul 2020 20:33:32 +0800 Subject: drm/panel: Fix auo, kd101n80-45na horizontal noise on edges of panel Fine tune the HBP and HFP to avoid the dot noise on the left and right edges. Signed-off-by: Jitao Shi Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200714123332.37609-1-jitao.shi@mediatek.com --- drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c index 46fe1805c588..2649469070aa 100644 --- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c +++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c @@ -615,9 +615,9 @@ static const struct panel_desc boe_tv101wum_nl6_desc = { static const struct drm_display_mode auo_kd101n80_45na_default_mode = { .clock = 157000, .hdisplay = 1200, - .hsync_start = 1200 + 80, - .hsync_end = 1200 + 80 + 24, - .htotal = 1200 + 80 + 24 + 36, + .hsync_start = 1200 + 60, + .hsync_end = 1200 + 60 + 24, + .htotal = 1200 + 60 + 24 + 56, .vdisplay = 1920, .vsync_start = 1920 + 16, .vsync_end = 1920 + 16 + 4, -- cgit v1.2.3 From 07c08f5210e08dd6d4e0c3f8df2cf1c7de6d4ea4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Sat, 18 Jul 2020 20:26:37 +0200 Subject: drm/bridge: nwl-dsi: Drop DRM_BRIDGE_ATTACH_NO_CONNECTOR check. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't create a connector but let panel_bridge handle that so there's no point in rejecting DRM_BRIDGE_ATTACH_NO_CONNECTOR. Signed-off-by: Guido Günther Reviewed-by: Laurent Pinchart Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/8b6545b991afce6add0a24f5f5d116778b0cb763.1595096667.git.agx@sigxcpu.org --- drivers/gpu/drm/bridge/nwl-dsi.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c index b14d725bf609..c7bc194bbce3 100644 --- a/drivers/gpu/drm/bridge/nwl-dsi.c +++ b/drivers/gpu/drm/bridge/nwl-dsi.c @@ -917,11 +917,6 @@ static int nwl_dsi_bridge_attach(struct drm_bridge *bridge, struct drm_panel *panel; int ret; - if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) { - DRM_ERROR("Fix bridge driver to make connector optional!"); - return -EINVAL; - } - ret = drm_of_find_panel_or_bridge(dsi->dev->of_node, 1, 0, &panel, &panel_bridge); if (ret) -- cgit v1.2.3 From aa7bf898d4bf921f61fab078040e8baec3f28126 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 19 Jul 2020 01:33:22 +0200 Subject: drm/mcde: Fix stability issue Whenever a display update was sent, apart from updating the memory base address, we called mcde_display_send_one_frame() which also sent a command to the display requesting the TE IRQ and enabling the FIFO. When continuous updates are running this is wrong: we need to only send this to start the flow to the display on the very first update. This lead to the display pipeline locking up and crashing. Check if the flow is already running and in that case do not call mcde_display_send_one_frame(). This fixes crashes on the Samsung GT-S7710 (Skomer). Signed-off-by: Linus Walleij Acked-by: Sam Ravnborg Acked-by: Stephan Gerhold Cc: Stephan Gerhold Cc: stable@vger.kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20200718233323.3407670-1-linus.walleij@linaro.org --- drivers/gpu/drm/mcde/mcde_display.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/mcde/mcde_display.c b/drivers/gpu/drm/mcde/mcde_display.c index 08802e5177f6..4d2290f88edb 100644 --- a/drivers/gpu/drm/mcde/mcde_display.c +++ b/drivers/gpu/drm/mcde/mcde_display.c @@ -1060,9 +1060,14 @@ static void mcde_display_update(struct drm_simple_display_pipe *pipe, */ if (fb) { mcde_set_extsrc(mcde, drm_fb_cma_get_gem_addr(fb, pstate, 0)); - if (!mcde->video_mode) - /* Send a single frame using software sync */ - mcde_display_send_one_frame(mcde); + if (!mcde->video_mode) { + /* + * Send a single frame using software sync if the flow + * is not active yet. + */ + if (mcde->flow_active == 0) + mcde_display_send_one_frame(mcde); + } dev_info_once(mcde->dev, "sent first display update\n"); } else { /* -- cgit v1.2.3 From 2a1658bf922ffd9b7907e270a7d9cdc9643fc45d Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Thu, 9 Jul 2020 21:30:16 +0200 Subject: drm/drm_fb_helper: fix fbdev with sparc64 Recent kernels have been reported to panic using the bochs_drm framebuffer under qemu-system-sparc64 which was bisected to commit 7a0483ac4ffc ("drm/bochs: switch to generic drm fbdev emulation"). The backtrace indicates that the shadow framebuffer copy in drm_fb_helper_dirty_blit_real() is trying to access the real framebuffer using a virtual address rather than use an IO access typically implemented using a physical (ASI_PHYS) access on SPARC. The fix is to replace the memcpy with memcpy_toio() from io.h. memcpy_toio() uses writeb() where the original fbdev code used sbus_memcpy_toio(). The latter uses sbus_writeb(). The difference between writeb() and sbus_memcpy_toio() is that writeb() writes bytes in little-endian, where sbus_writeb() writes bytes in big-endian. As endian does not matter for byte writes they are the same. So we can safely use memcpy_toio() here. Note that this only fixes bochs, in general fbdev helpers still have issues with mixing up system memory and __iomem space. Fixing that will require a lot more work. v3: - Improved changelog (Daniel) - Added FIXME to fbdev_use_iomem (Daniel) v2: - Added missing __iomem cast (kernel test robot) - Made changelog readable and fix typos (Mark) - Add flag to select iomem - and set it in the bochs driver Signed-off-by: Sam Ravnborg Reported-by: Mark Cave-Ayland Reported-by: kernel test robot Tested-by: Mark Cave-Ayland Reviewed-by: Daniel Vetter Cc: Mark Cave-Ayland Cc: Thomas Zimmermann Cc: Gerd Hoffmann Cc: "David S. Miller" Cc: sparclinux@vger.kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20200709193016.291267-1-sam@ravnborg.org Link: https://patchwork.freedesktop.org/patch/msgid/20200725191012.GA434957@ravnborg.org --- drivers/gpu/drm/bochs/bochs_kms.c | 1 + drivers/gpu/drm/drm_fb_helper.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c index 05d8373888e8..079f46f5cdb6 100644 --- a/drivers/gpu/drm/bochs/bochs_kms.c +++ b/drivers/gpu/drm/bochs/bochs_kms.c @@ -146,6 +146,7 @@ int bochs_kms_init(struct bochs_device *bochs) bochs->dev->mode_config.preferred_depth = 24; bochs->dev->mode_config.prefer_shadow = 0; bochs->dev->mode_config.prefer_shadow_fbdev = 1; + bochs->dev->mode_config.fbdev_use_iomem = true; bochs->dev->mode_config.quirk_addfb_prefer_host_byte_order = true; bochs->dev->mode_config.funcs = &bochs_mode_funcs; diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 5609e164805f..89cfd68ef400 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -399,7 +399,11 @@ static void drm_fb_helper_dirty_blit_real(struct drm_fb_helper *fb_helper, unsigned int y; for (y = clip->y1; y < clip->y2; y++) { - memcpy(dst, src, len); + if (!fb_helper->dev->mode_config.fbdev_use_iomem) + memcpy(dst, src, len); + else + memcpy_toio((void __iomem *)dst, src, len); + src += fb->pitches[0]; dst += fb->pitches[0]; } -- cgit v1.2.3 From 900ab59e2621053b009f707f80b2c19ce0af5dee Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Fri, 3 Jul 2020 16:13:41 +0200 Subject: drm/dbi: Fix SPI Type 1 (9-bit) transfer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function mipi_dbi_spi1_transfer() will transfer its payload as 9-bit data, the 9th (MSB) bit being the data/command bit. In order to do that, it unpacks the 8-bit values into 16-bit values, then sets the 9th bit if the byte corresponds to data, clears it otherwise. The 7 MSB are padding. The array of now 16-bit values is then passed to the SPI core for transfer. This function was broken since its introduction, as the length of the SPI transfer was set to the payload size before its conversion, but the payload doubled in size due to the 8-bit -> 16-bit conversion. Fixes: 02dd95fe3169 ("drm/tinydrm: Add MIPI DBI support") Cc: # 5.4+ Signed-off-by: Paul Cercueil Reviewed-by: Sam Ravnborg Reviewed-by: Noralf Trønnes Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200703141341.1266263-1-paul@crapouillou.net --- drivers/gpu/drm/drm_mipi_dbi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c index bb27c82757f1..bf7888ad9ad4 100644 --- a/drivers/gpu/drm/drm_mipi_dbi.c +++ b/drivers/gpu/drm/drm_mipi_dbi.c @@ -923,7 +923,7 @@ static int mipi_dbi_spi1_transfer(struct mipi_dbi *dbi, int dc, } } - tr.len = chunk; + tr.len = chunk * 2; len -= chunk; ret = spi_sync(spi, &m); -- cgit v1.2.3 From 8490d6a7e0a0a6fab5c2d82d57a3937306660864 Mon Sep 17 00:00:00 2001 From: Steve Cohen Date: Mon, 20 Jul 2020 18:30:50 -0400 Subject: drm: hold gem reference until object is no longer accessed A use-after-free in drm_gem_open_ioctl can happen if the GEM object handle is closed between the idr lookup and retrieving the size from said object since a local reference is not being held at that point. Hold the local reference while the object can still be accessed to fix this and plug the potential security hole. Signed-off-by: Steve Cohen Cc: stable@vger.kernel.org Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/1595284250-31580-1-git-send-email-cohens@codeaurora.org --- drivers/gpu/drm/drm_gem.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 7bf628e13023..ee2058ad482c 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -871,9 +871,6 @@ err: * @file_priv: drm file-private structure * * Open an object using the global name, returning a handle and the size. - * - * This handle (of course) holds a reference to the object, so the object - * will not go away until the handle is deleted. */ int drm_gem_open_ioctl(struct drm_device *dev, void *data, @@ -898,14 +895,15 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data, /* drm_gem_handle_create_tail unlocks dev->object_name_lock. */ ret = drm_gem_handle_create_tail(file_priv, obj, &handle); - drm_gem_object_put_unlocked(obj); if (ret) - return ret; + goto err; args->handle = handle; args->size = obj->size; - return 0; +err: + drm_gem_object_put_unlocked(obj); + return ret; } /** -- cgit v1.2.3