From: Daniel Vetter daniel.vetter@ffwll.ch
[ Upstream commit 18d0952a838ba559655b0cd9cf85097ad63d9bca ]
The issue we have is that the crc worker might fall behind. We've tried to handle this by tracking both the earliest frame for which it still needs to compute a crc, and the last one. Plus when the crtc_state changes, we have a new work item, which are all run in order due to the ordered workqueue we allocate for each vkms crtc.
Trouble is there's been a few small issues in the current code: - we need to capture frame_end in the vblank hrtimer, not in the worker. The worker might run much later, and then we generate a lot of crc for which there's already a different worker queued up. - frame number might be 0, so create a new crc_pending boolean to track this without confusion. - we need to atomically grab frame_start/end and clear it, so do that all in one go. This is not going to create a new race, because if we race with the hrtimer then our work will be re-run. - only race that can happen is the following: 1. worker starts 2. hrtimer runs and updates frame_end 3. worker grabs frame_start/end, already reading the new frame_end, and clears crc_pending 4. hrtimer calls queue_work() 5. worker completes 6. worker gets re-run, crc_pending is false Explain this case a bit better by rewording the comment.
v2: Demote warning level output to debug when we fail to requeue, this is expected under high load when the crc worker can't quite keep up.
Cc: Shayenne Moura shayenneluzmoura@gmail.com Cc: Rodrigo Siqueira rodrigosiqueiramelo@gmail.com Cc: Haneen Mohammed hamohammed.sa@gmail.com Cc: Daniel Vetter daniel@ffwll.ch Signed-off-by: Daniel Vetter daniel.vetter@intel.com Reviewed-by: Rodrigo Siqueira rodrigosiqueiramelo@gmail.com Tested-by: Rodrigo Siqueira rodrigosiqueiramelo@gmail.com Signed-off-by: Rodrigo Siqueira rodrigosiqueiramelo@gmail.com Link: https://patchwork.freedesktop.org/patch/msgid/20190606222751.32567-2-daniel.... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vkms/vkms_crc.c | 27 +++++++++++++-------------- drivers/gpu/drm/vkms/vkms_crtc.c | 9 +++++++-- drivers/gpu/drm/vkms/vkms_drv.h | 2 ++ 3 files changed, 22 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_crc.c b/drivers/gpu/drm/vkms/vkms_crc.c index e66ff25c008e6..e9fb4ebb789fd 100644 --- a/drivers/gpu/drm/vkms/vkms_crc.c +++ b/drivers/gpu/drm/vkms/vkms_crc.c @@ -166,16 +166,24 @@ void vkms_crc_work_handle(struct work_struct *work) struct drm_plane *plane; u32 crc32 = 0; u64 frame_start, frame_end; + bool crc_pending; unsigned long flags;
spin_lock_irqsave(&out->state_lock, flags); frame_start = crtc_state->frame_start; frame_end = crtc_state->frame_end; + crc_pending = crtc_state->crc_pending; + crtc_state->frame_start = 0; + crtc_state->frame_end = 0; + crtc_state->crc_pending = false; spin_unlock_irqrestore(&out->state_lock, flags);
- /* _vblank_handle() hasn't updated frame_start yet */ - if (!frame_start || frame_start == frame_end) - goto out; + /* + * We raced with the vblank hrtimer and previous work already computed + * the crc, nothing to do. + */ + if (!crc_pending) + return;
drm_for_each_plane(plane, &vdev->drm) { struct vkms_plane_state *vplane_state; @@ -196,20 +204,11 @@ void vkms_crc_work_handle(struct work_struct *work) if (primary_crc) crc32 = _vkms_get_crc(primary_crc, cursor_crc);
- frame_end = drm_crtc_accurate_vblank_count(crtc); - - /* queue_work can fail to schedule crc_work; add crc for - * missing frames + /* + * The worker can fall behind the vblank hrtimer, make sure we catch up. */ while (frame_start <= frame_end) drm_crtc_add_crc_entry(crtc, true, frame_start++, &crc32); - -out: - /* to avoid using the same value for frame number again */ - spin_lock_irqsave(&out->state_lock, flags); - crtc_state->frame_end = frame_end; - crtc_state->frame_start = 0; - spin_unlock_irqrestore(&out->state_lock, flags); }
static const char * const pipe_crc_sources[] = {"auto"}; diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c index 4d11292bc6f38..f392fa13015b8 100644 --- a/drivers/gpu/drm/vkms/vkms_crtc.c +++ b/drivers/gpu/drm/vkms/vkms_crtc.c @@ -30,13 +30,18 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer) * has read the data */ spin_lock(&output->state_lock); - if (!state->frame_start) + if (!state->crc_pending) state->frame_start = frame; + else + DRM_DEBUG_DRIVER("crc worker falling behind, frame_start: %llu, frame_end: %llu\n", + state->frame_start, frame); + state->frame_end = frame; + state->crc_pending = true; spin_unlock(&output->state_lock);
ret = queue_work(output->crc_workq, &state->crc_work); if (!ret) - DRM_WARN("failed to queue vkms_crc_work_handle"); + DRM_DEBUG_DRIVER("vkms_crc_work_handle already queued\n"); }
spin_unlock(&output->lock); diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index b92c30c66a6f2..2b37eb1062d34 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -48,6 +48,8 @@ struct vkms_plane_state { struct vkms_crtc_state { struct drm_crtc_state base; struct work_struct crc_work; + + bool crc_pending; u64 frame_start; u64 frame_end; };
From: Linus Walleij linus.walleij@linaro.org
[ Upstream commit ca5be902a87ddccc88144f2dea21b5f0814391ef ]
We need to handle the case when of_drm_find_bridge() returns NULL.
Reported-by: Dan Carpenter dan.carpenter@oracle.com Acked-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20190618115245.13915-1-linus.w... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/mcde/mcde_drv.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c index baf63fb6850a4..a810568c76df7 100644 --- a/drivers/gpu/drm/mcde/mcde_drv.c +++ b/drivers/gpu/drm/mcde/mcde_drv.c @@ -319,7 +319,7 @@ static int mcde_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct drm_device *drm; struct mcde *mcde; - struct component_match *match; + struct component_match *match = NULL; struct resource *res; u32 pid; u32 val; @@ -485,6 +485,10 @@ static int mcde_probe(struct platform_device *pdev) } put_device(p); } + if (!match) { + dev_err(dev, "no matching components\n"); + return -ENODEV; + } if (IS_ERR(match)) { dev_err(dev, "could not create component match\n"); ret = PTR_ERR(match);
From: Andrey Smirnov andrew.smirnov@gmail.com
[ Upstream commit e0655feaec62d5139b6b13a7b1bbb1ab8f1c2d83 ]
According to the datasheet tc358767 can transfer up to 16 bytes via its AUX channel, so the artificial limit of 8 appears to be too low. However only up to 15-bytes seem to be actually supported and trying to use 16-byte transfers results in transfers failing sporadically (with bogus status in case of I2C transfers), so limit it to 15.
Signed-off-by: Andrey Smirnov andrew.smirnov@gmail.com Reviewed-by: Andrzej Hajda a.hajda@samsung.com Reviewed-by: Tomi Valkeinen tomi.valkeinen@ti.com Cc: Andrzej Hajda a.hajda@samsung.com Cc: Laurent Pinchart Laurent.pinchart@ideasonboard.com Cc: Tomi Valkeinen tomi.valkeinen@ti.com Cc: Andrey Gusakov andrey.gusakov@cogentembedded.com Cc: Philipp Zabel p.zabel@pengutronix.de Cc: Cory Tusar cory.tusar@zii.aero Cc: Chris Healy cphealy@gmail.com Cc: Lucas Stach l.stach@pengutronix.de Cc: dri-devel@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Andrzej Hajda a.hajda@samsung.com Link: https://patchwork.freedesktop.org/patch/msgid/20190619052716.16831-9-andrew.... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/tc358767.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c index 13ade28a36a8a..b3a7d5f1250c8 100644 --- a/drivers/gpu/drm/bridge/tc358767.c +++ b/drivers/gpu/drm/bridge/tc358767.c @@ -313,7 +313,7 @@ static ssize_t tc_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) { struct tc_data *tc = aux_to_tc(aux); - size_t size = min_t(size_t, 8, msg->size); + size_t size = min_t(size_t, DP_AUX_MAX_PAYLOAD_BYTES - 1, msg->size); u8 request = msg->request & ~DP_AUX_I2C_MOT; u8 *buf = msg->buffer; u32 tmp = 0;
From: Matt Redfearn matt.redfearn@thinci.com
[ Upstream commit 83f35bc3a852f1c3892c7474998c5cec707c7ba3 ]
In contrast to all of the DSI panel drivers in drivers/gpu/drm/panel which attach to the DSI host via mipi_dsi_attach() at probe time, the ADV7533 bridge device does not. Instead it defers this to the point that the upstream device connects to its bridge via drm_bridge_attach(). The generic Synopsys MIPI DSI host driver does not register it's own drm_bridge until the MIPI DSI has attached. But it does not call drm_bridge_attach() on the downstream device until the upstream device has attached. This leads to a chicken and the egg failure and the DRM pipeline does not complete. Since all other mipi_dsi_device drivers call mipi_dsi_attach() in probe(), make the adv7533 mipi_dsi_device do the same. This ensures that the Synopsys MIPI DSI host registers it's bridge such that it is available for the upstream device to connect to.
Signed-off-by: Matt Redfearn matt.redfearn@thinci.com Signed-off-by: Andrzej Hajda a.hajda@samsung.com Link: https://patchwork.freedesktop.org/patch/msgid/20190627151740.2277-1-matt.red... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index f6d2681f69273..98bccace8c1c0 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -874,9 +874,6 @@ static int adv7511_bridge_attach(struct drm_bridge *bridge) &adv7511_connector_helper_funcs); drm_connector_attach_encoder(&adv->connector, bridge->encoder);
- if (adv->type == ADV7533) - ret = adv7533_attach_dsi(adv); - if (adv->i2c_main->irq) regmap_write(adv->regmap, ADV7511_REG_INT_ENABLE(0), ADV7511_INT0_HPD); @@ -1222,8 +1219,17 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) drm_bridge_add(&adv7511->bridge);
adv7511_audio_init(dev, adv7511); + + if (adv7511->type == ADV7533) { + ret = adv7533_attach_dsi(adv7511); + if (ret) + goto err_remove_bridge; + } + return 0;
+err_remove_bridge: + drm_bridge_remove(&adv7511->bridge); err_unregister_cec: i2c_unregister_device(adv7511->i2c_cec); if (adv7511->cec_clk)
From: Daniel Vetter daniel.vetter@ffwll.ch
[ Upstream commit 4f5368b5541a902f6596558b05f5c21a9770dd32 ]
Only dynamic mode objects, i.e. those which are refcounted and have a free callback, can be added while the overall drm_device is visible to userspace. All others must be added before drm_dev_register and removed after drm_dev_unregister.
Small issue around drivers still using the load/unload callbacks, we need to make sure we set dev->registered so that load/unload code in these callbacks doesn't trigger false warnings. Only a small adjustement in drm_dev_register was needed.
Motivated by some irc discussions about object ids of dynamic objects like blobs become invalid, and me going on a bit an audit spree.
Reviewed-by: Sean Paul sean@poorly.run Signed-off-by: Daniel Vetter daniel.vetter@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20190614061723.1173-1-daniel.v... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_drv.c | 4 ++-- drivers/gpu/drm/drm_mode_object.c | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 9d00947ca447f..e652305d8f98a 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -978,14 +978,14 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags) if (ret) goto err_minors;
- dev->registered = true; - if (dev->driver->load) { ret = dev->driver->load(dev, flags); if (ret) goto err_minors; }
+ dev->registered = true; + if (drm_core_check_feature(dev, DRIVER_MODESET)) drm_modeset_register_all(dev);
diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c index 1c6e511359624..c355ba8e6d5dd 100644 --- a/drivers/gpu/drm/drm_mode_object.c +++ b/drivers/gpu/drm/drm_mode_object.c @@ -42,6 +42,8 @@ int __drm_mode_object_add(struct drm_device *dev, struct drm_mode_object *obj, { int ret;
+ WARN_ON(dev->registered && !obj_free_cb); + mutex_lock(&dev->mode_config.idr_mutex); ret = idr_alloc(&dev->mode_config.object_idr, register_obj ? obj : NULL, 1, 0, GFP_KERNEL); @@ -102,6 +104,8 @@ void drm_mode_object_register(struct drm_device *dev, void drm_mode_object_unregister(struct drm_device *dev, struct drm_mode_object *object) { + WARN_ON(dev->registered && !object->free_cb); + mutex_lock(&dev->mode_config.idr_mutex); if (object->id) { idr_remove(&dev->mode_config.object_idr, object->id);
From: Rodrigo Siqueira rodrigosiqueiramelo@gmail.com
[ Upstream commit e9d85f731de06a35d2ae6cdcf7d0e037c98ef41a ]
When vkms invoke drm_universal_plane_init(), it sets 0 for possible_crtcs parameter which means that planes can't be attached to any CRTC. It currently works due to some safeguard in the drm_crtc file; however, it is possible to identify the problem by trying to append a second connector. This patch fixes this issue by modifying vkms_plane_init() to accept an index parameter which makes the code a little bit more flexible and avoid set zero to possible_crtcs.
Signed-off-by: Rodrigo Siqueira rodrigosiqueiramelo@gmail.com Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch Link: https://patchwork.freedesktop.org/patch/msgid/d67849c62a8d8ace1a0af455998b58... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vkms/vkms_drv.c | 2 +- drivers/gpu/drm/vkms/vkms_drv.h | 4 ++-- drivers/gpu/drm/vkms/vkms_output.c | 6 +++--- drivers/gpu/drm/vkms/vkms_plane.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index 738dd6206d85b..92296bd8f6233 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -92,7 +92,7 @@ static int vkms_modeset_init(struct vkms_device *vkmsdev) dev->mode_config.max_height = YRES_MAX; dev->mode_config.preferred_depth = 24;
- return vkms_output_init(vkmsdev); + return vkms_output_init(vkmsdev, 0); }
static int __init vkms_init(void) diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index 2b37eb1062d34..2fee10a00051e 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -107,10 +107,10 @@ bool vkms_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, int *max_error, ktime_t *vblank_time, bool in_vblank_irq);
-int vkms_output_init(struct vkms_device *vkmsdev); +int vkms_output_init(struct vkms_device *vkmsdev, int index);
struct drm_plane *vkms_plane_init(struct vkms_device *vkmsdev, - enum drm_plane_type type); + enum drm_plane_type type, int index);
/* Gem stuff */ struct drm_gem_object *vkms_gem_create(struct drm_device *dev, diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c index 56fb5c2a2315c..fb1941a6522cf 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -35,7 +35,7 @@ static const struct drm_connector_helper_funcs vkms_conn_helper_funcs = { .get_modes = vkms_conn_get_modes, };
-int vkms_output_init(struct vkms_device *vkmsdev) +int vkms_output_init(struct vkms_device *vkmsdev, int index) { struct vkms_output *output = &vkmsdev->output; struct drm_device *dev = &vkmsdev->drm; @@ -45,12 +45,12 @@ int vkms_output_init(struct vkms_device *vkmsdev) struct drm_plane *primary, *cursor = NULL; int ret;
- primary = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_PRIMARY); + primary = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_PRIMARY, index); if (IS_ERR(primary)) return PTR_ERR(primary);
if (enable_cursor) { - cursor = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_CURSOR); + cursor = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_CURSOR, index); if (IS_ERR(cursor)) { ret = PTR_ERR(cursor); goto err_cursor; diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index 0fceb62584225..18c630cfc485a 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -176,7 +176,7 @@ static const struct drm_plane_helper_funcs vkms_primary_helper_funcs = { };
struct drm_plane *vkms_plane_init(struct vkms_device *vkmsdev, - enum drm_plane_type type) + enum drm_plane_type type, int index) { struct drm_device *dev = &vkmsdev->drm; const struct drm_plane_helper_funcs *funcs; @@ -198,7 +198,7 @@ struct drm_plane *vkms_plane_init(struct vkms_device *vkmsdev, funcs = &vkms_primary_helper_funcs; }
- ret = drm_universal_plane_init(dev, plane, 0, + ret = drm_universal_plane_init(dev, plane, 1 << index, &vkms_plane_funcs, formats, nformats, NULL, type, NULL);
From: Lucas Stach l.stach@pengutronix.de
[ Upstream commit f8c6bfc612b56f02e1b8fae699dff12738aaf889 ]
The horizontal blanking periods are too short, as the values are specified for a single LVDS channel. Since this panel is dual LVDS they need to be doubled. With this change the panel reaches its nominal vrefresh rate of 60Fps, instead of the 64Fps with the current wrong blanking.
Philipp Zabel added: The datasheet specifies 960 active clocks + 40/128/160 clocks blanking on each of the two LVDS channels (min/typical/max), so doubled this is now correct.
Signed-off-by: Lucas Stach l.stach@pengutronix.de Reviewed-by: Philipp Zabel p.zabel@pengutronix.de Reviewed-by: Sam Ravnborg sam@ravnborg.org Signed-off-by: Sam Ravnborg sam@ravnborg.org Link: https://patchwork.freedesktop.org/patch/msgid/1562764060.23869.12.camel@peng... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/panel/panel-simple.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 5a93c4edf1e43..ee6900eb39069 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -724,9 +724,9 @@ static const struct panel_desc auo_g133han01 = { static const struct display_timing auo_g185han01_timings = { .pixelclock = { 120000000, 144000000, 175000000 }, .hactive = { 1920, 1920, 1920 }, - .hfront_porch = { 18, 60, 74 }, - .hback_porch = { 12, 44, 54 }, - .hsync_len = { 10, 24, 32 }, + .hfront_porch = { 36, 120, 148 }, + .hback_porch = { 24, 88, 108 }, + .hsync_len = { 20, 48, 64 }, .vactive = { 1080, 1080, 1080 }, .vfront_porch = { 6, 10, 40 }, .vback_porch = { 2, 5, 20 },
From: Anthony Koo anthony.koo@amd.com
[ Upstream commit 88eac241a1fc500ce5274a09ddc4bd5fc2b5adb6 ]
[Why] Specifically to one panel, TCON is able to accept active video signal quickly, but the Source Driver requires 2-3 frames of extra time.
It is a Panel issue since TCON needs to take care of all Sink requirements including Source Driver. But in this case it does not.
Customer is asking to add fixed T7 delay as panel workaround.
[How] Add monitor specific patch to add T7 delay
Signed-off-by: Anthony Koo anthony.koo@amd.com Reviewed-by: Charlene Liu Charlene.Liu@amd.com Acked-by: Leo Li sunpeng.li@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c | 4 ++++ drivers/gpu/drm/amd/display/dc/dc_types.h | 1 + 2 files changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c index 2d019e1f61352..a9135764e5806 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c @@ -160,6 +160,10 @@ bool edp_receiver_ready_T7(struct dc_link *link) break; udelay(25); //MAx T7 is 50ms } while (++tries < 300); + + if (link->local_sink->edid_caps.panel_patch.extra_t7_ms > 0) + udelay(link->local_sink->edid_caps.panel_patch.extra_t7_ms * 1000); + return result; }
diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index 6eabb6491a3df..ce6d73d21ccae 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -202,6 +202,7 @@ struct dc_panel_patch { unsigned int dppowerup_delay; unsigned int extra_t12_ms; unsigned int extra_delay_backlight_off; + unsigned int extra_t7_ms; };
struct dc_edid_caps {
From: Nikola Cornij nikola.cornij@amd.com
[ Upstream commit 75c35000235f3662f2810e9a59b0c8eed045432e ]
[why] DSC should be powered-on only on as-needed basis, i.e. if the mode requires it
[how] Loop over all the DSCs at driver init time and power-gate each
Signed-off-by: Nikola Cornij nikola.cornij@amd.com Reviewed-by: Nevenko Stupar Nevenko.Stupar@amd.com Acked-by: Leo Li sunpeng.li@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c index d810c8940129b..2627e0a98a96a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -585,6 +585,10 @@ static void dcn20_init_hw(struct dc *dc) } }
+ /* Power gate DSCs */ + for (i = 0; i < res_pool->res_cap->num_dsc; i++) + dcn20_dsc_pg_control(hws, res_pool->dscs[i]->inst, false); + /* Blank pixel data with OPP DPG */ for (i = 0; i < dc->res_pool->timing_generator_count; i++) { struct timing_generator *tg = dc->res_pool->timing_generators[i];
From: Su Sung Chung Su.Chung@amd.com
[ Upstream commit 18b401874aee10c80b5745c9b93280dae5a59809 ]
[why] dcn20_clk_mgr_construct was not initializing pp_smu, and PME call gets filtered out by the null check
[how] initialize pp_smu dcn20_clk_mgr_construct
Signed-off-by: Su Sung Chung Su.Chung@amd.com Reviewed-by: Eric Yang eric.yang2@amd.com Acked-by: Leo Li sunpeng.li@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c index 50bfb5921de07..2ab0f97719b5a 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c @@ -348,6 +348,8 @@ void dcn20_clk_mgr_construct(
clk_mgr->base.dprefclk_khz = 700000; // 700 MHz planned if VCO is 3.85 GHz, will be retrieved
+ clk_mgr->pp_smu = pp_smu; + if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) { dcn2_funcs.update_clocks = dcn2_update_clocks_fpga; clk_mgr->dentist_vco_freq_khz = 3850000;
From: Nikola Cornij nikola.cornij@amd.com
[ Upstream commit d68a74541735e030dea56f72746cd26d19986f41 ]
[why] As a fail-safe, in case 'set FEC_READY' DPCD write fails, a HW shadow register should be cleared and the internal FEC stat should be set to 'not ready'. This is to make sure HW settings will be consistent with FEC_READY state on the RX.
Signed-off-by: Nikola Cornij nikola.cornij@amd.com Reviewed-by: Joshua Aberback Joshua.Aberback@amd.com Acked-by: Chris Park Chris.Park@amd.com Acked-by: Leo Li sunpeng.li@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 2c7aaed907b91..0bf85a7a2cd31 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -3033,6 +3033,8 @@ void dp_set_fec_ready(struct dc_link *link, bool ready) link_enc->funcs->fec_set_ready(link_enc, true); link->fec_state = dc_link_fec_ready; } else { + link->link_enc->funcs->fec_set_ready(link->link_enc, false); + link->fec_state = dc_link_fec_not_ready; dm_error("dpcd write failed to set fec_ready"); } } else if (link->fec_state == dc_link_fec_ready && !ready) {
From: Nicholas Kazlauskas nicholas.kazlauskas@amd.com
[ Upstream commit 21ffcc94d5b3dc024fedac700f1e7f9dacf4ab4f ]
[Why] DC configures the GSL group for the pipe when pipe_split is enabled and we're switching flip types (buffered <-> immediate flip) on DCN2.
In order to record what GSL group the pipe is using DC stores it in the pipe's stream_res. DM is not aware of this internal grouping, nor is DC resource.
So when DM creates a dc_state context and passes it to DC the current GSL group is lost - DM never knew about it in the first place.
After 3 immediate flips we run out of GSL groups and we're no longer able to correctly perform *any* flip for multi-pipe scenarios.
[How] The gsl_group needs to be copied to the new context.
DM has no insight into GSL grouping and could even potentially create a brand new context without referencing current hardware state. So this makes the most sense to have happen in DC.
There are two places where DC can apply a new context: - dc_commit_state - dc_commit_updates_for_stream
But what's shared between both of these is apply_ctx_for_surface.
This logic only matters for DCN2, so it can be placed in dcn20_apply_ctx_for_surface. Before doing any locking (where the GSL group is setup) we can copy over the GSL groups before committing the new context.
Signed-off-by: Nicholas Kazlauskas nicholas.kazlauskas@amd.com Reviewed-by: Hersen Wu hersen.wu@amd.com Acked-by: Leo Li sunpeng.li@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c index 2627e0a98a96a..f8abe98a576be 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -1319,6 +1319,18 @@ static void dcn20_apply_ctx_for_surface( if (!top_pipe_to_program) return;
+ /* Carry over GSL groups in case the context is changing. */ + for (i = 0; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; + struct pipe_ctx *old_pipe_ctx = + &dc->current_state->res_ctx.pipe_ctx[i]; + + if (pipe_ctx->stream == stream && + pipe_ctx->stream == old_pipe_ctx->stream) + pipe_ctx->stream_res.gsl_group = + old_pipe_ctx->stream_res.gsl_group; + } + tg = top_pipe_to_program->stream_res.tg;
interdependent_update = top_pipe_to_program->plane_state &&
From: Marko Kohtala marko.kohtala@okoko.fi
[ Upstream commit dd9782834dd9dde3624ff1acea8859f3d3e792d4 ]
The page_offset was only applied to the end of the page range. This caused the display updates to cause a scrolling effect on the display because the amount of data written to the display did not match the range display expected.
Fixes: 301bc0675b67 ("video: ssd1307fb: Make use of horizontal addressing mode") Signed-off-by: Marko Kohtala marko.kohtala@okoko.fi Cc: Mark Rutland mark.rutland@arm.com Cc: Rob Herring robh+dt@kernel.org Cc: Daniel Vetter daniel@ffwll.ch Cc: David Airlie airlied@linux.ie Cc: Michal Vokáč michal.vokac@ysoft.com Signed-off-by: Bartlomiej Zolnierkiewicz b.zolnierkie@samsung.com Link: https://patchwork.freedesktop.org/patch/msgid/20190618074111.9309-4-marko.ko... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/video/fbdev/ssd1307fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c index b674948e3bb8f..3f28e1b5d4221 100644 --- a/drivers/video/fbdev/ssd1307fb.c +++ b/drivers/video/fbdev/ssd1307fb.c @@ -432,7 +432,7 @@ static int ssd1307fb_init(struct ssd1307fb_par *par) if (ret < 0) return ret;
- ret = ssd1307fb_write_cmd(par->client, 0x0); + ret = ssd1307fb_write_cmd(par->client, par->page_offset); if (ret < 0) return ret;
From: Noralf Trønnes noralf@tronnes.org
[ Upstream commit 3389669ac5ea598562673c04971d7bb0fab0e9f1 ]
The mipi_dbi helper is missing a dependency on DRM_KMS_HELPER and putting that in revealed this problem:
drivers/video/fbdev/Kconfig:12:error: recursive dependency detected! drivers/video/fbdev/Kconfig:12: symbol FB is selected by DRM_KMS_FB_HELPER drivers/gpu/drm/Kconfig:75: symbol DRM_KMS_FB_HELPER depends on DRM_KMS_HELPER drivers/gpu/drm/Kconfig:69: symbol DRM_KMS_HELPER is selected by TINYDRM_MIPI_DBI drivers/gpu/drm/tinydrm/Kconfig:11: symbol TINYDRM_MIPI_DBI is selected by TINYDRM_HX8357D drivers/gpu/drm/tinydrm/Kconfig:15: symbol TINYDRM_HX8357D depends on BACKLIGHT_CLASS_DEVICE drivers/video/backlight/Kconfig:144: symbol BACKLIGHT_CLASS_DEVICE is selected by FB_BACKLIGHT drivers/video/fbdev/Kconfig:187: symbol FB_BACKLIGHT depends on FB
A symbol that selects DRM_KMS_HELPER can not depend on BACKLIGHT_CLASS_DEVICE. The reason for this is that DRM_KMS_FB_HELPER selects FB instead of depending on it.
The tinydrm drivers have somehow gotten away with depending on BACKLIGHT_CLASS_DEVICE because DRM_TINYDRM selects DRM_KMS_HELPER and the drivers depend on that symbol.
An audit shows that all DRM drivers that select DRM_KMS_HELPER and use BACKLIGHT_CLASS_DEVICE, selects it: DRM_TILCDC, DRM_GMA500, DRM_SHMOBILE, DRM_NOUVEAU, DRM_FSL_DCU, DRM_I915, DRM_RADEON, DRM_AMDGPU, DRM_PARADE_PS8622
Documentation/kbuild/kconfig-language.txt has a note regarding select: 1. 'select should be used with care since it doesn't visit dependencies.' This is not a problem since BACKLIGHT_CLASS_DEVICE doesn't have any dependencies. 2. 'In general use select only for non-visible symbols' BACKLIGHT_CLASS_DEVICE is user visible.
The real solution to this would be to have DRM_KMS_FB_HELPER depend on the user visible symbol FB. That is a can of worms I'm not willing to tackle. I fear that such a change will result in me handling difficult fallouts for the next weeks. So I'm following DRM suite here.
Signed-off-by: Noralf Trønnes noralf@tronnes.org Reviewed-by: David Lechner david@lechnology.com Link: https://patchwork.freedesktop.org/patch/msgid/20190722104312.16184-7-noralf@... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/tinydrm/Kconfig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/tinydrm/Kconfig b/drivers/gpu/drm/tinydrm/Kconfig index 87819c82bcce8..f2f0739d1035d 100644 --- a/drivers/gpu/drm/tinydrm/Kconfig +++ b/drivers/gpu/drm/tinydrm/Kconfig @@ -14,8 +14,8 @@ config TINYDRM_MIPI_DBI config TINYDRM_HX8357D tristate "DRM support for HX8357D display panels" depends on DRM_TINYDRM && SPI - depends on BACKLIGHT_CLASS_DEVICE select TINYDRM_MIPI_DBI + select BACKLIGHT_CLASS_DEVICE help DRM driver for the following HX8357D panels: * YX350HV15-T 3.5" 340x350 TFT (Adafruit 3.5") @@ -35,8 +35,8 @@ config TINYDRM_ILI9225 config TINYDRM_ILI9341 tristate "DRM support for ILI9341 display panels" depends on DRM_TINYDRM && SPI - depends on BACKLIGHT_CLASS_DEVICE select TINYDRM_MIPI_DBI + select BACKLIGHT_CLASS_DEVICE help DRM driver for the following Ilitek ILI9341 panels: * YX240QV29-T 2.4" 240x320 TFT (Adafruit 2.4") @@ -46,8 +46,8 @@ config TINYDRM_ILI9341 config TINYDRM_MI0283QT tristate "DRM support for MI0283QT" depends on DRM_TINYDRM && SPI - depends on BACKLIGHT_CLASS_DEVICE select TINYDRM_MIPI_DBI + select BACKLIGHT_CLASS_DEVICE help DRM driver for the Multi-Inno MI0283QT display panel If M is selected the module will be called mi0283qt. @@ -78,8 +78,8 @@ config TINYDRM_ST7586 config TINYDRM_ST7735R tristate "DRM support for Sitronix ST7735R display panels" depends on DRM_TINYDRM && SPI - depends on BACKLIGHT_CLASS_DEVICE select TINYDRM_MIPI_DBI + select BACKLIGHT_CLASS_DEVICE help DRM driver Sitronix ST7735R with one of the following LCDs: * JD-T18003-T01 1.8" 128x160 TFT
From: Ahmad Fatoum a.fatoum@pengutronix.de
[ Upstream commit 8fabc9c3109a71b3577959a05408153ae69ccd8d ]
To properly synchronize with other devices the fence from the GEM object backing the framebuffer needs to be attached to the atomic state, so the commit work can wait on fence signaling.
Signed-off-by: Ahmad Fatoum a.fatoum@pengutronix.de Signed-off-by: Lucas Stach l.stach@pengutronix.de Acked-by: Philippe Cornu philippe.cornu@st.com Tested-by: Philippe Cornu philippe.cornu@st.com Signed-off-by: Benjamin Gaignard benjamin.gaignard@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20190712084228.8338-1-l.stach@... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/stm/ltdc.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c index 2fe6c4a8d9155..3ab4fbf8eb0d1 100644 --- a/drivers/gpu/drm/stm/ltdc.c +++ b/drivers/gpu/drm/stm/ltdc.c @@ -26,6 +26,7 @@ #include <drm/drm_fb_cma_helper.h> #include <drm/drm_fourcc.h> #include <drm/drm_gem_cma_helper.h> +#include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_of.h> #include <drm/drm_plane_helper.h> #include <drm/drm_probe_helper.h> @@ -922,6 +923,7 @@ static const struct drm_plane_funcs ltdc_plane_funcs = { };
static const struct drm_plane_helper_funcs ltdc_plane_helper_funcs = { + .prepare_fb = drm_gem_fb_prepare_fb, .atomic_check = ltdc_plane_atomic_check, .atomic_update = ltdc_plane_atomic_update, .atomic_disable = ltdc_plane_atomic_disable,
From: Olivier Moysan olivier.moysan@st.com
[ Upstream commit 365d28c92f8cd3d3860f8dd057a8c136e24b3698 ]
Add devm_clk_get call to retrieve reference to master clock.
Fixes: ff5781634c41 ("drm/bridge: sii902x: Implement HDMI audio support")
Signed-off-by: Olivier Moysan olivier.moysan@st.com Reviewed-by: Jyri Sarha jsarha@ti.com Acked-by: Andrzej Hajda <a.hajda@samsung.com Signed-off-by: Benjamin Gaignard benjamin.gaignard@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/1563811560-29589-2-git-send-em... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/sii902x.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c index dd7aa466b2805..36acc256e67e3 100644 --- a/drivers/gpu/drm/bridge/sii902x.c +++ b/drivers/gpu/drm/bridge/sii902x.c @@ -750,6 +750,7 @@ static int sii902x_audio_codec_init(struct sii902x *sii902x, sii902x->audio.i2s_fifo_sequence[i] |= audio_fifo_id[i] | i2s_lane_id[lanes[i]] | SII902X_TPI_I2S_FIFO_ENABLE;
+ sii902x->audio.mclk = devm_clk_get(dev, "mclk"); if (IS_ERR(sii902x->audio.mclk)) { dev_err(dev, "%s: No clock (audio mclk) found: %ld\n", __func__, PTR_ERR(sii902x->audio.mclk));
From: Navid Emamdoost navid.emamdoost@gmail.com
[ Upstream commit afd6d4f5a52c16e1483328ac074abb1cde92c29f ]
The following function calls may fail and return NULL, so the null check is added. of_graph_get_next_endpoint of_graph_get_remote_port_parent of_graph_get_remote_port
Update: Thanks to Sam Ravnborg, for suggession on the use of goto to avoid leaking endpoint.
Signed-off-by: Navid Emamdoost navid.emamdoost@gmail.com Signed-off-by: Sam Ravnborg sam@ravnborg.org Link: https://patchwork.freedesktop.org/patch/msgid/20190724195534.9303-1-navid.em... Signed-off-by: Sasha Levin sashal@kernel.org --- .../gpu/drm/panel/panel-raspberrypi-touchscreen.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c index 28c0620dfe0f9..b5b14aa059ea7 100644 --- a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c +++ b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c @@ -399,7 +399,13 @@ static int rpi_touchscreen_probe(struct i2c_client *i2c,
/* Look up the DSI host. It needs to probe before we do. */ endpoint = of_graph_get_next_endpoint(dev->of_node, NULL); + if (!endpoint) + return -ENODEV; + dsi_host_node = of_graph_get_remote_port_parent(endpoint); + if (!dsi_host_node) + goto error; + host = of_find_mipi_dsi_host_by_node(dsi_host_node); of_node_put(dsi_host_node); if (!host) { @@ -408,6 +414,9 @@ static int rpi_touchscreen_probe(struct i2c_client *i2c, }
info.node = of_graph_get_remote_port(endpoint); + if (!info.node) + goto error; + of_node_put(endpoint);
ts->dsi = mipi_dsi_device_register_full(host, &info); @@ -428,6 +437,10 @@ static int rpi_touchscreen_probe(struct i2c_client *i2c, return ret;
return 0; + +error: + of_node_put(endpoint); + return -ENODEV; }
static int rpi_touchscreen_remove(struct i2c_client *i2c)
From: Sean Paul seanpaul@chromium.org
[ Upstream commit ad309284a52be47c8b3126c9376358bf381861bc ]
Once we start shutting off the link during PSR, we're going to want fast training to work. If the display doesn't support fast training, don't enable psr.
Changes in v2: - None Changes in v3: - None Changes in v4: - None Changes in v5: - None
Link to v1: https://patchwork.freedesktop.org/patch/msgid/20190228210939.83386-3-sean@po... Link to v2: https://patchwork.freedesktop.org/patch/msgid/20190326204509.96515-2-sean@po... Link to v3: https://patchwork.freedesktop.org/patch/msgid/20190502194956.218441-9-sean@p... Link to v4: https://patchwork.freedesktop.org/patch/msgid/20190508160920.144739-8-sean@p...
Cc: Zain Wang wzz@rock-chips.com Cc: Tomasz Figa tfiga@chromium.org Tested-by: Heiko Stuebner heiko@sntech.de Reviewed-by: Heiko Stuebner heiko@sntech.de Signed-off-by: Sean Paul seanpaul@chromium.org Link: https://patchwork.freedesktop.org/patch/msgid/20190611160844.257498-8-sean@p... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 3f7f4880be091..37bd541166a5e 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -1035,16 +1035,17 @@ static int analogix_dp_commit(struct analogix_dp_device *dp) if (ret) return ret;
+ /* Check whether panel supports fast training */ + ret = analogix_dp_fast_link_train_detection(dp); + if (ret) + dp->psr_enable = false; + if (dp->psr_enable) { ret = analogix_dp_enable_sink_psr(dp); if (ret) return ret; }
- /* Check whether panel supports fast training */ - ret = analogix_dp_fast_link_train_detection(dp); - if (ret) - dp->psr_enable = false;
return ret; }
From: Andrey Grodzovsky andrey.grodzovsky@amd.com
[ Upstream commit e4c4073b0139d055d43a9568690fc560aab4fa5c ]
HW requires for caching to be unset for scanout BO mappings when the BO placement is in GTT memory. Usually the flag to unset is passed from user mode but for FB mode this was missing.
v2: Keep all BO placement logic in amdgpu_display_supported_domains
Suggested-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Andrey Grodzovsky andrey.grodzovsky@amd.com Reviewed-by: Alex Deucher alexander.deucher@amd.com Tested-by: Shirish S shirish.s@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 7 +++---- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 3 ++- 2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c index eb3569b46c1e1..430c56f9544a1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c @@ -139,14 +139,14 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev, mode_cmd->pitches[0] = amdgpu_align_pitch(adev, mode_cmd->width, cpp, fb_tiled); domain = amdgpu_display_supported_domains(adev); - height = ALIGN(mode_cmd->height, 8); size = mode_cmd->pitches[0] * height; aligned_size = ALIGN(size, PAGE_SIZE); ret = amdgpu_gem_object_create(adev, aligned_size, 0, domain, AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | - AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS | - AMDGPU_GEM_CREATE_VRAM_CLEARED, + AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS | + AMDGPU_GEM_CREATE_VRAM_CLEARED | + AMDGPU_GEM_CREATE_CPU_GTT_USWC, ttm_bo_type_kernel, NULL, &gobj); if (ret) { pr_err("failed to allocate framebuffer (%d)\n", aligned_size); @@ -168,7 +168,6 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev, dev_err(adev->dev, "FB failed to set tiling flags\n"); }
- ret = amdgpu_bo_pin(abo, domain); if (ret) { amdgpu_bo_unreserve(abo); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index 939f8305511b8..fb291366d5ade 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -747,7 +747,8 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv, struct amdgpu_device *adev = dev->dev_private; struct drm_gem_object *gobj; uint32_t handle; - u64 flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; + u64 flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | + AMDGPU_GEM_CREATE_CPU_GTT_USWC; u32 domain; int r;
From: Nathan Chancellor natechancellor@gmail.com
[ Upstream commit d196bbbc28fab82624f7686f8b0da8e8644b6e6a ]
clang warns:
drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_pp_smu.c:336:8: warning: implicit conversion from enumeration type 'enum smu_clk_type' to different enumeration type 'enum amd_pp_clock_type' [-Wenum-conversion] dc_to_smu_clock_type(clk_type), ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_pp_smu.c:421:14: warning: implicit conversion from enumeration type 'enum amd_pp_clock_type' to different enumeration type 'enum smu_clk_type' [-Wenum-conversion] dc_to_pp_clock_type(clk_type), ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
There are functions to properly convert between all of these types, use them so there are no longer any warnings.
Fixes: a43913ea50a5 ("drm/amd/powerplay: add function get_clock_by_type_with_latency for navi10") Fixes: e5e4e22391c2 ("drm/amd/powerplay: add interface to get clock by type with latency for display (v2)") Link: https://github.com/ClangBuiltLinux/linux/issues/586 Signed-off-by: Nathan Chancellor natechancellor@gmail.com Reviewed-by: Leo Li sunpeng.li@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c index 592fa499c9f86..9594c154664fc 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c @@ -334,7 +334,7 @@ bool dm_pp_get_clock_levels_by_type( } } else if (adev->smu.funcs && adev->smu.funcs->get_clock_by_type) { if (smu_get_clock_by_type(&adev->smu, - dc_to_smu_clock_type(clk_type), + dc_to_pp_clock_type(clk_type), &pp_clks)) { get_default_clock_levels(clk_type, dc_clks); return true; @@ -419,7 +419,7 @@ bool dm_pp_get_clock_levels_by_type_with_latency( return false; } else if (adev->smu.ppt_funcs && adev->smu.ppt_funcs->get_clock_by_type_with_latency) { if (smu_get_clock_by_type_with_latency(&adev->smu, - dc_to_pp_clock_type(clk_type), + dc_to_smu_clock_type(clk_type), &pp_clks)) return false; }
From: KyleMahlkuch kmahlkuc@linux.vnet.ibm.com
[ Upstream commit 6f7fe9a93e6c09bf988c5059403f5f88e17e21e6 ]
During kexec some adapters hit an EEH since they are not properly shut down in the radeon_pci_shutdown() function. Adding radeon_suspend_kms() fixes this issue.
Signed-off-by: KyleMahlkuch kmahlkuc@linux.vnet.ibm.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/radeon/radeon_drv.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index a6cbe11f79c61..15d7bebe17294 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -349,11 +349,19 @@ radeon_pci_remove(struct pci_dev *pdev) static void radeon_pci_shutdown(struct pci_dev *pdev) { + struct drm_device *ddev = pci_get_drvdata(pdev); + /* if we are running in a VM, make sure the device * torn down properly on reboot/shutdown */ if (radeon_device_is_virtual()) radeon_pci_remove(pdev); + + /* Some adapters need to be suspended before a + * shutdown occurs in order to prevent an error + * during kexec. + */ + radeon_suspend_kms(ddev, true, true, false); }
static int radeon_pmops_suspend(struct device *dev)
From: Jia-Ju Bai baijiaju1990@gmail.com
[ Upstream commit f3eb9b8f67bc28783eddc142ad805ebdc53d6339 ]
In radeon_connector_set_property(), there is an if statement on line 743 to check whether connector->encoder is NULL: if (connector->encoder)
When connector->encoder is NULL, it is used on line 755: if (connector->encoder->crtc)
Thus, a possible null-pointer dereference may occur.
To fix this bug, connector->encoder is checked before being used.
This bug is found by a static analysis tool STCheck written by us.
Signed-off-by: Jia-Ju Bai baijiaju1990@gmail.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/radeon/radeon_connectors.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index c60d1a44d22a2..b684cd719612b 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -752,7 +752,7 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct
radeon_encoder->output_csc = val;
- if (connector->encoder->crtc) { + if (connector->encoder && connector->encoder->crtc) { struct drm_crtc *crtc = connector->encoder->crtc; struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
From: Anthony Koo Anthony.Koo@amd.com
[ Upstream commit 1cbcfc975164f397b449efb17f59d81a703090db ]
[Why] When endpoint is at the boundary of a region, such as at 2^0=1 we find that the last segment has a sharp slope and some points are clipped at the top.
[How] If end point is 1, which is exactly at the 2^0 region boundary, we need to program an additional region beyond this point.
Signed-off-by: Anthony Koo Anthony.Koo@amd.com Reviewed-by: Aric Cyr Aric.Cyr@amd.com Acked-by: Leo Li sunpeng.li@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c index 7469333a2c8a5..8166fdbacd732 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c @@ -357,9 +357,10 @@ bool cm_helper_translate_curve_to_hw_format( seg_distr[7] = 4; seg_distr[8] = 4; seg_distr[9] = 4; + seg_distr[10] = 1;
region_start = -10; - region_end = 0; + region_end = 1; }
for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++)
From: Bayan Zabihiyan bayan.zabihiyan@amd.com
[ Upstream commit a463b263032f7c98c5912207db43be1aa34a6438 ]
[Why] The math on deciding on how many "frames to insert" sometimes sent us over the max refresh rate. Also integer overflow can occur if we have high refresh rates.
[How] Instead of clipping the frame duration such that it doesn’t go below the min, just remove a frame from the number of frames to insert. + Use unsigned long long for intermediate calculations to prevent integer overflow.
Signed-off-by: Bayan Zabihiyan bayan.zabihiyan@amd.com Reviewed-by: Aric Cyr Aric.Cyr@amd.com Acked-by: Leo Li sunpeng.li@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../amd/display/modules/freesync/freesync.c | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c index 7c20171a3b6da..a53666ff6cf89 100644 --- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c +++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c @@ -435,6 +435,12 @@ static void apply_below_the_range(struct core_freesync *core_freesync, /* Either we've calculated the number of frames to insert, * or we need to insert min duration frames */ + if (last_render_time_in_us / frames_to_insert < + in_out_vrr->min_duration_in_us){ + frames_to_insert -= (frames_to_insert > 1) ? + 1 : 0; + } + if (frames_to_insert > 0) inserted_frame_duration_in_us = last_render_time_in_us / frames_to_insert; @@ -887,8 +893,8 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync, struct core_freesync *core_freesync = NULL; unsigned long long nominal_field_rate_in_uhz = 0; unsigned int refresh_range = 0; - unsigned int min_refresh_in_uhz = 0; - unsigned int max_refresh_in_uhz = 0; + unsigned long long min_refresh_in_uhz = 0; + unsigned long long max_refresh_in_uhz = 0;
if (mod_freesync == NULL) return; @@ -915,7 +921,7 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync, min_refresh_in_uhz = nominal_field_rate_in_uhz;
if (!vrr_settings_require_update(core_freesync, - in_config, min_refresh_in_uhz, max_refresh_in_uhz, + in_config, (unsigned int)min_refresh_in_uhz, (unsigned int)max_refresh_in_uhz, in_out_vrr)) return;
@@ -931,15 +937,15 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync, return;
} else { - in_out_vrr->min_refresh_in_uhz = min_refresh_in_uhz; + in_out_vrr->min_refresh_in_uhz = (unsigned int)min_refresh_in_uhz; in_out_vrr->max_duration_in_us = calc_duration_in_us_from_refresh_in_uhz( - min_refresh_in_uhz); + (unsigned int)min_refresh_in_uhz);
- in_out_vrr->max_refresh_in_uhz = max_refresh_in_uhz; + in_out_vrr->max_refresh_in_uhz = (unsigned int)max_refresh_in_uhz; in_out_vrr->min_duration_in_us = calc_duration_in_us_from_refresh_in_uhz( - max_refresh_in_uhz); + (unsigned int)max_refresh_in_uhz);
refresh_range = in_out_vrr->max_refresh_in_uhz - in_out_vrr->min_refresh_in_uhz; @@ -950,17 +956,18 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync, in_out_vrr->fixed.ramping_active = in_config->ramping;
in_out_vrr->btr.btr_enabled = in_config->btr; + if (in_out_vrr->max_refresh_in_uhz < 2 * in_out_vrr->min_refresh_in_uhz) in_out_vrr->btr.btr_enabled = false; + in_out_vrr->btr.btr_active = false; in_out_vrr->btr.inserted_duration_in_us = 0; in_out_vrr->btr.frames_to_insert = 0; in_out_vrr->btr.frame_counter = 0; in_out_vrr->btr.mid_point_in_us = - in_out_vrr->min_duration_in_us + - (in_out_vrr->max_duration_in_us - - in_out_vrr->min_duration_in_us) / 2; + (in_out_vrr->min_duration_in_us + + in_out_vrr->max_duration_in_us) / 2;
if (in_out_vrr->state == VRR_STATE_UNSUPPORTED) { in_out_vrr->adjust.v_total_min = stream->timing.v_total;
From: Lewis Huang Lewis.Huang@amd.com
[ Upstream commit e5382701c3520b3ed66169a6e4aa6ce5df8c56e0 ]
[Why] The vm config will be clear to 0 when system enter S4. It will cause hubbub didn't know how to fetch data when system resume. The flip always pending because earliest_inuse_address and request_address are different.
[How] Reprogram VM config when system resume
Signed-off-by: Lewis Huang Lewis.Huang@amd.com Reviewed-by: Jun Lei Jun.Lei@amd.com Acked-by: Eric Yang eric.yang2@amd.com Acked-by: Leo Li sunpeng.li@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/core/dc.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index cbc480a333764..730f97ba8dbbe 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -2187,6 +2187,14 @@ void dc_set_power_state( dc_resource_state_construct(dc, dc->current_state);
dc->hwss.init_hw(dc); + +#ifdef CONFIG_DRM_AMD_DC_DCN2_0 + if (dc->hwss.init_sys_ctx != NULL && + dc->vm_pa_config.valid) { + dc->hwss.init_sys_ctx(dc->hwseq, dc, &dc->vm_pa_config); + } +#endif + break; default: ASSERT(dc->current_state->stream_count == 0);
From: Nicholas Kazlauskas nicholas.kazlauskas@amd.com
[ Upstream commit e40837afb9b011757e17e9f71d97853ca574bcff ]
[Why] These are needed to send back DRM vblank events in the case where VRR is on. Without the interrupt enabled we're deferring the events into the vblank queue and userspace is left waiting forever to get back the events they need.
Found using igt@kms_vrr - the test fails immediately due to vblank timeout.
[How] Register them the same way we're handling it for DCN1.
This fixes igt@kms_vrr for DCN2.
Signed-off-by: Nicholas Kazlauskas nicholas.kazlauskas@amd.com Reviewed-by: David Francis David.Francis@amd.com Acked-by: Leo Li sunpeng.li@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../display/dc/irq/dcn20/irq_service_dcn20.c | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c b/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c index 3cc0f2a1f77cc..5db29bf582d31 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c @@ -167,6 +167,11 @@ static const struct irq_source_info_funcs vblank_irq_info_funcs = { .ack = NULL };
+static const struct irq_source_info_funcs vupdate_no_lock_irq_info_funcs = { + .set = NULL, + .ack = NULL +}; + #undef BASE_INNER #define BASE_INNER(seg) DCN_BASE__INST0_SEG ## seg
@@ -221,12 +226,15 @@ static const struct irq_source_info_funcs vblank_irq_info_funcs = { .funcs = &pflip_irq_info_funcs\ }
-#define vupdate_int_entry(reg_num)\ +/* vupdate_no_lock_int_entry maps to DC_IRQ_SOURCE_VUPDATEx, to match semantic + * of DCE's DC_IRQ_SOURCE_VUPDATEx. + */ +#define vupdate_no_lock_int_entry(reg_num)\ [DC_IRQ_SOURCE_VUPDATE1 + reg_num] = {\ IRQ_REG_ENTRY(OTG, reg_num,\ - OTG_GLOBAL_SYNC_STATUS, VUPDATE_INT_EN,\ - OTG_GLOBAL_SYNC_STATUS, VUPDATE_EVENT_CLEAR),\ - .funcs = &vblank_irq_info_funcs\ + OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_INT_EN,\ + OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_EVENT_CLEAR),\ + .funcs = &vupdate_no_lock_irq_info_funcs\ }
#define vblank_int_entry(reg_num)\ @@ -333,12 +341,12 @@ irq_source_info_dcn20[DAL_IRQ_SOURCES_NUMBER] = { dc_underflow_int_entry(6), [DC_IRQ_SOURCE_DMCU_SCP] = dummy_irq_entry(), [DC_IRQ_SOURCE_VBIOS_SW] = dummy_irq_entry(), - vupdate_int_entry(0), - vupdate_int_entry(1), - vupdate_int_entry(2), - vupdate_int_entry(3), - vupdate_int_entry(4), - vupdate_int_entry(5), + vupdate_no_lock_int_entry(0), + vupdate_no_lock_int_entry(1), + vupdate_no_lock_int_entry(2), + vupdate_no_lock_int_entry(3), + vupdate_no_lock_int_entry(4), + vupdate_no_lock_int_entry(5), vblank_int_entry(0), vblank_int_entry(1), vblank_int_entry(2),
From: Ahzo Ahzo@tutanota.com
[ Upstream commit f659bb6dae58c113805f92822e4c16ddd3156b79 ]
This fixes screen corruption/flickering on 75 Hz displays.
v2: make print statement debug only (Alex)
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102646 Reviewed-by: Evan Quan evan.quan@amd.com Signed-off-by: Ahzo Ahzo@tutanota.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c index 487aeee1cf8a5..3c1084de5d59f 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c @@ -4068,6 +4068,11 @@ static int smu7_program_display_gap(struct pp_hwmgr *hwmgr)
data->frame_time_x2 = frame_time_in_us * 2 / 100;
+ if (data->frame_time_x2 < 280) { + pr_debug("%s: enforce minimal VBITimeout: %d -> 280\n", __func__, data->frame_time_x2); + data->frame_time_x2 = 280; + } + display_gap2 = pre_vbi_time_in_us * (ref_clock / 100);
cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCG_DISPLAY_GAP_CNTL2, display_gap2);
From: Xiaojie Yuan xiaojie.yuan@amd.com
[ Upstream commit 9e48495017342c5d445b25eedd86d6fd884a6496 ]
v2: set num_types based on num_instances
navi1x has 2 sdma engines but commit "e7b58d03b678 drm/amdgpu: reorganize sdma v4 code to support more instances" changes the max number of sdma irq types (AMDGPU_SDMA_IRQ_LAST) from 2 to 8 which causes amdgpu_irq_gpu_reset_resume_helper() to recover irq of sdma engines with following logic:
(enable irq for sdma0) * 1 time (enable irq for sdma1) * 1 time (disable irq for sdma1) * 6 times
as a result, after gpu reset, interrupt for sdma1 is lost.
Signed-off-by: Xiaojie Yuan xiaojie.yuan@amd.com Reviewed-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c index 3747c3f1f0cc8..15c371fac469e 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c @@ -1583,7 +1583,8 @@ static const struct amdgpu_irq_src_funcs sdma_v5_0_illegal_inst_irq_funcs = {
static void sdma_v5_0_set_irq_funcs(struct amdgpu_device *adev) { - adev->sdma.trap_irq.num_types = AMDGPU_SDMA_IRQ_LAST; + adev->sdma.trap_irq.num_types = AMDGPU_SDMA_IRQ_INSTANCE0 + + adev->sdma.num_instances; adev->sdma.trap_irq.funcs = &sdma_v5_0_trap_irq_funcs; adev->sdma.illegal_inst_irq.funcs = &sdma_v5_0_illegal_inst_irq_funcs; }
From: Ben Skeggs bskeggs@redhat.com
[ Upstream commit 1e339ab2ac3c769c1b06b9fb7d532f8495ebc56d ]
On Turing, an input LUT is required to transform inputs in fixed-point formats to FP16 for the internal display pipe. We provide an identity mapping whenever a window is enabled for this reason.
HW has error checks to ensure when the input is already FP16, that the input LUT is also disabled.
Signed-off-by: Ben Skeggs bskeggs@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/nouveau/dispnv50/wndw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index 283ff690350ea..50303ec194bbc 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -320,7 +320,9 @@ nv50_wndw_atomic_check_lut(struct nv50_wndw *wndw, asyh->wndw.olut &= ~BIT(wndw->id); }
- if (!ilut && wndw->func->ilut_identity) { + if (!ilut && wndw->func->ilut_identity && + asyw->state.fb->format->format != DRM_FORMAT_XBGR16161616F && + asyw->state.fb->format->format != DRM_FORMAT_ABGR16161616F) { static struct drm_property_blob dummy = {}; ilut = &dummy; }
From: Mark Menzynski mmenzyns@redhat.com
[ Upstream commit a1af2afbd244089560794c260b2d4326a86e39b6 ]
Some, mostly Fermi, vbioses appear to have zero max voltage. That causes Nouveau to not parse voltage entries, thus users not being able to set higher clocks.
When changing this value Nvidia driver still appeared to ignore it, and I wasn't able to find out why, thus the code is ignoring the value if it is zero.
CC: Maarten Lankhorst maarten.lankhorst@linux.intel.com Signed-off-by: Mark Menzynski mmenzyns@redhat.com Reviewed-by: Karol Herbst kherbst@redhat.com Signed-off-by: Ben Skeggs bskeggs@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/nouveau/nvkm/subdev/bios/volt.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/volt.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/volt.c index 7143ea4611aa3..33a9fb5ac5585 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/volt.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/volt.c @@ -96,6 +96,8 @@ nvbios_volt_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, info->min = min(info->base, info->base + info->step * info->vidmask); info->max = nvbios_rd32(bios, volt + 0x0e); + if (!info->max) + info->max = max(info->base, info->base + info->step * info->vidmask); break; case 0x50: info->min = nvbios_rd32(bios, volt + 0x0a);
From: Charlene Liu charlene.liu@amd.com
[ Upstream commit b5a41620bb88efb9fb31a4fa5e652e3d5bead7d4 ]
[Description] port spdif fix to staging: spdif hardwired to afmt inst 1. spdif func pointer spdif resource allocation (reserve last audio endpoint for spdif only)
Signed-off-by: Charlene Liu charlene.liu@amd.com Reviewed-by: Dmytro Laktyushkin Dmytro.Laktyushkin@amd.com Acked-by: Bhawanpreet Lakha Bhawanpreet.Lakha@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../gpu/drm/amd/display/dc/core/dc_resource.c | 17 ++++++++--------- drivers/gpu/drm/amd/display/dc/dce/dce_audio.c | 4 ++-- 2 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 2ceaab4fb5deb..68db60e4caf32 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -265,12 +265,10 @@ bool resource_construct( DC_ERR("DC: failed to create audio!\n"); return false; } - if (!aud->funcs->endpoint_valid(aud)) { aud->funcs->destroy(&aud); break; } - pool->audios[i] = aud; pool->audio_count++; } @@ -1659,24 +1657,25 @@ static struct audio *find_first_free_audio( const struct resource_pool *pool, enum engine_id id) { - int i; - for (i = 0; i < pool->audio_count; i++) { + int i, available_audio_count; + + available_audio_count = pool->audio_count; + + for (i = 0; i < available_audio_count; i++) { if ((res_ctx->is_audio_acquired[i] == false) && (res_ctx->is_stream_enc_acquired[i] == true)) { /*we have enough audio endpoint, find the matching inst*/ if (id != i) continue; - return pool->audios[i]; } }
- /* use engine id to find free audio */ - if ((id < pool->audio_count) && (res_ctx->is_audio_acquired[id] == false)) { + /* use engine id to find free audio */ + if ((id < available_audio_count) && (res_ctx->is_audio_acquired[id] == false)) { return pool->audios[id]; } - /*not found the matching one, first come first serve*/ - for (i = 0; i < pool->audio_count; i++) { + for (i = 0; i < available_audio_count; i++) { if (res_ctx->is_audio_acquired[i] == false) { return pool->audios[i]; } diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c index 4a10a5d22c90b..5de9623bdf66b 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c @@ -613,6 +613,8 @@ void dce_aud_az_configure(
AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1, value); + DC_LOG_HW_AUDIO("\n\tAUDIO:az_configure: index: %u data, 0x%x, displayName %s: \n", + audio->inst, value, audio_info->display_name);
/* *write the port ID: @@ -922,7 +924,6 @@ static const struct audio_funcs funcs = { .az_configure = dce_aud_az_configure, .destroy = dce_aud_destroy, }; - void dce_aud_destroy(struct audio **audio) { struct dce_audio *aud = DCE_AUD(*audio); @@ -953,7 +954,6 @@ struct audio *dce_audio_create( audio->regs = reg; audio->shifts = shifts; audio->masks = masks; - return &audio->base; }
From: Kevin Wang kevin1.wang@amd.com
[ Upstream commit 706feb26f890e1b8297b5d14975160de361edf4f ]
fix other navi asic set peak performance level error. because the navi10_ppt.c will handle navi12 14 asic, it will use navi10 peak value to set other asic, it is not correct.
after patch: only navi10 use custom peak value, other asic will used default value.
Signed-off-by: Kevin Wang kevin1.wang@amd.com Reviewed-by: Evan Quan evan.quan@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c index b81c7e715dc94..9aaf2deff6e94 100644 --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c @@ -1627,6 +1627,10 @@ static int navi10_set_peak_clock_by_device(struct smu_context *smu) static int navi10_set_performance_level(struct smu_context *smu, enum amd_dpm_forced_level level) { int ret = 0; + struct amdgpu_device *adev = smu->adev; + + if (adev->asic_type != CHIP_NAVI10) + return -EINVAL;
switch (level) { case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
From: Zi Yu Liao ziyu.liao@amd.com
[ Upstream commit 89cb5614736b9b5d3b833ca2237d10da6b4b0395 ]
[why] With Scatter Gather enabled, HUBP underflows during MPO enabled video playback. hubp_init has a register write that fixes this problem, but the register is cleared when HUBP gets power gated.
[how] Make a call to hubp_init during enable_plane, so that the fix can be applied after HUBP powers back on again.
Signed-off-by: Zi Yu Liao ziyu.liao@amd.com Reviewed-by: Tony Cheng Tony.Cheng@amd.com Acked-by: Bhawanpreet Lakha Bhawanpreet.Lakha@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c index f8abe98a576be..8fdb53a44bfb3 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -1110,6 +1110,9 @@ void dcn20_enable_plane( /* enable DCFCLK current DCHUB */ pipe_ctx->plane_res.hubp->funcs->hubp_clk_cntl(pipe_ctx->plane_res.hubp, true);
+ /* initialize HUBP on power up */ + pipe_ctx->plane_res.hubp->funcs->hubp_init(pipe_ctx->plane_res.hubp); + /* make sure OPP_PIPE_CLOCK_EN = 1 */ pipe_ctx->stream_res.opp->funcs->opp_pipe_clock_control( pipe_ctx->stream_res.opp,
From: Yogesh Mohan Marimuthu yogesh.mohanmarimuthu@amd.com
[ Upstream commit 1e7f100ce8c0640634b794604880d9204480c9f1 ]
[Why] In newer hardware MANUAL_FLOW_CONTROL is not a trigger bit. Due to this front porch is fixed and in these hardware freesync does not work.
[How] Change the programming to generate a pulse so that the event will be triggered, front porch will be cut short and freesync will work.
Signed-off-by: Yogesh Mohan Marimuthu yogesh.mohanmarimuthu@amd.com Reviewed-by: Anthony Koo Anthony.Koo@amd.com Acked-by: Bhawanpreet Lakha Bhawanpreet.Lakha@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c index a546c2bc9129c..e365f2dd7f9a9 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c @@ -824,6 +824,9 @@ void optc1_program_manual_trigger(struct timing_generator *optc)
REG_SET(OTG_MANUAL_FLOW_CONTROL, 0, MANUAL_FLOW_CONTROL, 1); + + REG_SET(OTG_MANUAL_FLOW_CONTROL, 0, + MANUAL_FLOW_CONTROL, 0); }
From: Jean Delvare jdelvare@suse.de
[ Upstream commit 77efe48a729588527afb4d5811b9e0acb29f5e51 ]
Comparing adev->family with CHIP constants is not correct. adev->family can only be compared with AMDGPU_FAMILY constants and adev->asic_type is the struct member to compare with CHIP constants. They are separate identification spaces.
Signed-off-by: Jean Delvare jdelvare@suse.de Fixes: 62a37553414a ("drm/amdgpu: add si implementation v10") Cc: Ken Wang Qingqing.Wang@amd.com Cc: Alex Deucher alexander.deucher@amd.com Cc: "Christian König" christian.koenig@amd.com Cc: "David (ChunMing) Zhou" David1.Zhou@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/si.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c index 4d74453f3cfbd..602397016b641 100644 --- a/drivers/gpu/drm/amd/amdgpu/si.c +++ b/drivers/gpu/drm/amd/amdgpu/si.c @@ -1881,7 +1881,7 @@ static void si_program_aspm(struct amdgpu_device *adev) if (orig != data) si_pif_phy1_wreg(adev,PB1_PIF_PWRDOWN_1, data);
- if ((adev->family != CHIP_OLAND) && (adev->family != CHIP_HAINAN)) { + if ((adev->asic_type != CHIP_OLAND) && (adev->asic_type != CHIP_HAINAN)) { orig = data = si_pif_phy0_rreg(adev,PB0_PIF_PWRDOWN_0); data &= ~PLL_RAMP_UP_TIME_0_MASK; if (orig != data) @@ -1930,14 +1930,14 @@ static void si_program_aspm(struct amdgpu_device *adev)
orig = data = si_pif_phy0_rreg(adev,PB0_PIF_CNTL); data &= ~LS2_EXIT_TIME_MASK; - if ((adev->family == CHIP_OLAND) || (adev->family == CHIP_HAINAN)) + if ((adev->asic_type == CHIP_OLAND) || (adev->asic_type == CHIP_HAINAN)) data |= LS2_EXIT_TIME(5); if (orig != data) si_pif_phy0_wreg(adev,PB0_PIF_CNTL, data);
orig = data = si_pif_phy1_rreg(adev,PB1_PIF_CNTL); data &= ~LS2_EXIT_TIME_MASK; - if ((adev->family == CHIP_OLAND) || (adev->family == CHIP_HAINAN)) + if ((adev->asic_type == CHIP_OLAND) || (adev->asic_type == CHIP_HAINAN)) data |= LS2_EXIT_TIME(5); if (orig != data) si_pif_phy1_wreg(adev,PB1_PIF_CNTL, data);
From: Chris Wilson chris@chris-wilson.co.uk
[ Upstream commit d3c6dd1fb30d3853c2012549affe75c930f4a2f9 ]
During release of the syncpt, we remove it from the list of syncpt and the tree, but only if it is not already been removed. However, during signaling, we first remove the syncpt from the list. So, if we concurrently free and signal the syncpt, the free may decide that it is not part of the tree and immediately free itself -- meanwhile the signaler goes on to use the now freed datastructure.
In particular, we get struck by commit 0e2f733addbf ("dma-buf: make dma_fence structure a bit smaller v2") as the cb_list is immediately clobbered by the kfree_rcu.
v2: Avoid calling into timeline_fence_release() from under the spinlock
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=111381 Fixes: d3862e44daa7 ("dma-buf/sw-sync: Fix locking around sync_timeline lists") References: 0e2f733addbf ("dma-buf: make dma_fence structure a bit smaller v2") Signed-off-by: Chris Wilson chris@chris-wilson.co.uk Cc: Sumit Semwal sumit.semwal@linaro.org Cc: Sean Paul seanpaul@chromium.org Cc: Gustavo Padovan gustavo@padovan.org Cc: Christian König christian.koenig@amd.com Cc: stable@vger.kernel.org # v4.14+ Acked-by: Christian König christian.koenig@amd.com Link: https://patchwork.freedesktop.org/patch/msgid/20190812154247.20508-1-chris@c... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma-buf/sw_sync.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c index 051f6c2873c7a..6713cfb1995c6 100644 --- a/drivers/dma-buf/sw_sync.c +++ b/drivers/dma-buf/sw_sync.c @@ -132,17 +132,14 @@ static void timeline_fence_release(struct dma_fence *fence) { struct sync_pt *pt = dma_fence_to_sync_pt(fence); struct sync_timeline *parent = dma_fence_parent(fence); + unsigned long flags;
+ spin_lock_irqsave(fence->lock, flags); if (!list_empty(&pt->link)) { - unsigned long flags; - - spin_lock_irqsave(fence->lock, flags); - if (!list_empty(&pt->link)) { - list_del(&pt->link); - rb_erase(&pt->node, &parent->pt_tree); - } - spin_unlock_irqrestore(fence->lock, flags); + list_del(&pt->link); + rb_erase(&pt->node, &parent->pt_tree); } + spin_unlock_irqrestore(fence->lock, flags);
sync_timeline_put(parent); dma_fence_free(fence); @@ -265,7 +262,8 @@ static struct sync_pt *sync_pt_create(struct sync_timeline *obj, p = &parent->rb_left; } else { if (dma_fence_get_rcu(&other->base)) { - dma_fence_put(&pt->base); + sync_timeline_put(obj); + kfree(pt); pt = other; goto unlock; }
From: Jani Nikula jani.nikula@intel.com
[ Upstream commit ade925995b172f1d7410d1c665b2f47c5e99bef0 ]
The module is drm_kms_helper, not drm_kms_firmware.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=204549 Reported-by: Göran Uddeborg goeran@uddeborg.se Fixes: ac6c35a4d8c7 ("drm: add backwards compatibility support for drm_kms_helper.edid_firmware") Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch Signed-off-by: Jani Nikula jani.nikula@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20190821094312.5514-1-jani.nik... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_kms_helper_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_kms_helper_common.c b/drivers/gpu/drm/drm_kms_helper_common.c index d9a5ac81949e2..221a8528c9937 100644 --- a/drivers/gpu/drm/drm_kms_helper_common.c +++ b/drivers/gpu/drm/drm_kms_helper_common.c @@ -40,7 +40,7 @@ MODULE_LICENSE("GPL and additional rights"); /* Backward compatibility for drm_kms_helper.edid_firmware */ static int edid_firmware_set(const char *val, const struct kernel_param *kp) { - DRM_NOTE("drm_kms_firmware.edid_firmware is deprecated, please use drm.edid_firmware instead.\n"); + DRM_NOTE("drm_kms_helper.edid_firmware is deprecated, please use drm.edid_firmware instead.\n");
return __drm_set_edid_firmware_path(val); }
dri-devel@lists.freedesktop.org