Skip to content
This repository was archived by the owner on Feb 9, 2023. It is now read-only.

Commit 8961ca4

Browse files
committed
Merge tag 'drm-fixes-for-v4.16-rc3' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie: "A bunch of fixes for rc3: Exynos: - fixes for using monotonic timestamps - register definitions - removal of unused file ipu-v3L - minor changes - make some register arrays const+static - fix some leaks meson: - fix for vsync atomic: - fix for memory leak EDID parser: - add quirks for some more non-desktop devices - 6-bit panel fix. drm_mm: - fix a bug in the core drm mm hole handling cirrus: - fix lut loading regression Lastly there is a deadlock fix around runtime suspend for secondary GPUs. There was a deadlock between one thread trying to wait for a workqueue job to finish in the runtime suspend path, and the workqueue job it was waiting for in turn waiting for a runtime_get_sync to return. The fixes avoids it by not doing the runtime sync in the workqueue as then we always wait for all those tasks to complete before we runtime suspend" * tag 'drm-fixes-for-v4.16-rc3' of git://people.freedesktop.org/~airlied/linux: (25 commits) drm/tve200: fix kernel-doc documentation comment include drm/edid: quirk Sony PlayStation VR headset as non-desktop drm/edid: quirk Windows Mixed Reality headsets as non-desktop drm/edid: quirk Oculus Rift headsets as non-desktop drm/meson: fix vsync buffer update drm: Handle unexpected holes in color-eviction drm: exynos: Use proper macro definition for HDMI_I2S_PIN_SEL_1 drm/exynos: remove exynos_drm_rotator.h drm/exynos: g2d: Delete an error message for a failed memory allocation in two functions drm/exynos: fix comparison to bitshift when dealing with a mask drm/exynos: g2d: use monotonic timestamps drm/edid: Add 6 bpc quirk for CPT panel in Asus UX303LA gpu: ipu-csi: add 10/12-bit grayscale support to mbus_code_to_bus_cfg gpu: ipu-cpmem: add 16-bit grayscale support to ipu_cpmem_set_image gpu: ipu-v3: prg: fix device node leak in ipu_prg_lookup_by_phandle gpu: ipu-v3: pre: fix device node leak in ipu_pre_lookup_by_phandle drm/amdgpu: Fix deadlock on runtime suspend drm/radeon: Fix deadlock on runtime suspend drm/nouveau: Fix deadlock on runtime suspend drm: Allow determining if current task is output poll worker ...
2 parents 0f9da84 + b17800e commit 8961ca4

26 files changed

Lines changed: 261 additions & 107 deletions

Documentation/gpu/tve200.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
==================================
44

55
.. kernel-doc:: drivers/gpu/drm/tve200/tve200_drv.c
6-
:doc: Faraday TV Encoder 200
6+
:doc: Faraday TV Encoder TVE200 DRM Driver

drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -736,9 +736,11 @@ amdgpu_connector_lvds_detect(struct drm_connector *connector, bool force)
736736
enum drm_connector_status ret = connector_status_disconnected;
737737
int r;
738738

739-
r = pm_runtime_get_sync(connector->dev->dev);
740-
if (r < 0)
741-
return connector_status_disconnected;
739+
if (!drm_kms_helper_is_poll_worker()) {
740+
r = pm_runtime_get_sync(connector->dev->dev);
741+
if (r < 0)
742+
return connector_status_disconnected;
743+
}
742744

743745
if (encoder) {
744746
struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
@@ -757,8 +759,12 @@ amdgpu_connector_lvds_detect(struct drm_connector *connector, bool force)
757759
/* check acpi lid status ??? */
758760

759761
amdgpu_connector_update_scratch_regs(connector, ret);
760-
pm_runtime_mark_last_busy(connector->dev->dev);
761-
pm_runtime_put_autosuspend(connector->dev->dev);
762+
763+
if (!drm_kms_helper_is_poll_worker()) {
764+
pm_runtime_mark_last_busy(connector->dev->dev);
765+
pm_runtime_put_autosuspend(connector->dev->dev);
766+
}
767+
762768
return ret;
763769
}
764770

@@ -868,9 +874,11 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force)
868874
enum drm_connector_status ret = connector_status_disconnected;
869875
int r;
870876

871-
r = pm_runtime_get_sync(connector->dev->dev);
872-
if (r < 0)
873-
return connector_status_disconnected;
877+
if (!drm_kms_helper_is_poll_worker()) {
878+
r = pm_runtime_get_sync(connector->dev->dev);
879+
if (r < 0)
880+
return connector_status_disconnected;
881+
}
874882

875883
encoder = amdgpu_connector_best_single_encoder(connector);
876884
if (!encoder)
@@ -924,8 +932,10 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force)
924932
amdgpu_connector_update_scratch_regs(connector, ret);
925933

926934
out:
927-
pm_runtime_mark_last_busy(connector->dev->dev);
928-
pm_runtime_put_autosuspend(connector->dev->dev);
935+
if (!drm_kms_helper_is_poll_worker()) {
936+
pm_runtime_mark_last_busy(connector->dev->dev);
937+
pm_runtime_put_autosuspend(connector->dev->dev);
938+
}
929939

930940
return ret;
931941
}
@@ -988,9 +998,11 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)
988998
enum drm_connector_status ret = connector_status_disconnected;
989999
bool dret = false, broken_edid = false;
9901000

991-
r = pm_runtime_get_sync(connector->dev->dev);
992-
if (r < 0)
993-
return connector_status_disconnected;
1001+
if (!drm_kms_helper_is_poll_worker()) {
1002+
r = pm_runtime_get_sync(connector->dev->dev);
1003+
if (r < 0)
1004+
return connector_status_disconnected;
1005+
}
9941006

9951007
if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) {
9961008
ret = connector->status;
@@ -1115,8 +1127,10 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)
11151127
amdgpu_connector_update_scratch_regs(connector, ret);
11161128

11171129
exit:
1118-
pm_runtime_mark_last_busy(connector->dev->dev);
1119-
pm_runtime_put_autosuspend(connector->dev->dev);
1130+
if (!drm_kms_helper_is_poll_worker()) {
1131+
pm_runtime_mark_last_busy(connector->dev->dev);
1132+
pm_runtime_put_autosuspend(connector->dev->dev);
1133+
}
11201134

11211135
return ret;
11221136
}
@@ -1359,9 +1373,11 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force)
13591373
struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector);
13601374
int r;
13611375

1362-
r = pm_runtime_get_sync(connector->dev->dev);
1363-
if (r < 0)
1364-
return connector_status_disconnected;
1376+
if (!drm_kms_helper_is_poll_worker()) {
1377+
r = pm_runtime_get_sync(connector->dev->dev);
1378+
if (r < 0)
1379+
return connector_status_disconnected;
1380+
}
13651381

13661382
if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) {
13671383
ret = connector->status;
@@ -1429,8 +1445,10 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force)
14291445

14301446
amdgpu_connector_update_scratch_regs(connector, ret);
14311447
out:
1432-
pm_runtime_mark_last_busy(connector->dev->dev);
1433-
pm_runtime_put_autosuspend(connector->dev->dev);
1448+
if (!drm_kms_helper_is_poll_worker()) {
1449+
pm_runtime_mark_last_busy(connector->dev->dev);
1450+
pm_runtime_put_autosuspend(connector->dev->dev);
1451+
}
14341452

14351453
return ret;
14361454
}

drivers/gpu/drm/cirrus/cirrus_mode.c

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -294,30 +294,15 @@ static void cirrus_crtc_prepare(struct drm_crtc *crtc)
294294
{
295295
}
296296

297-
/*
298-
* This is called after a mode is programmed. It should reverse anything done
299-
* by the prepare function
300-
*/
301-
static void cirrus_crtc_commit(struct drm_crtc *crtc)
302-
{
303-
}
304-
305-
/*
306-
* The core can pass us a set of gamma values to program. We actually only
307-
* use this for 8-bit mode so can't perform smooth fades on deeper modes,
308-
* but it's a requirement that we provide the function
309-
*/
310-
static int cirrus_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
311-
u16 *blue, uint32_t size,
312-
struct drm_modeset_acquire_ctx *ctx)
297+
static void cirrus_crtc_load_lut(struct drm_crtc *crtc)
313298
{
314299
struct drm_device *dev = crtc->dev;
315300
struct cirrus_device *cdev = dev->dev_private;
316301
u16 *r, *g, *b;
317302
int i;
318303

319304
if (!crtc->enabled)
320-
return 0;
305+
return;
321306

322307
r = crtc->gamma_store;
323308
g = r + crtc->gamma_size;
@@ -330,6 +315,27 @@ static int cirrus_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
330315
WREG8(PALETTE_DATA, *g++ >> 8);
331316
WREG8(PALETTE_DATA, *b++ >> 8);
332317
}
318+
}
319+
320+
/*
321+
* This is called after a mode is programmed. It should reverse anything done
322+
* by the prepare function
323+
*/
324+
static void cirrus_crtc_commit(struct drm_crtc *crtc)
325+
{
326+
cirrus_crtc_load_lut(crtc);
327+
}
328+
329+
/*
330+
* The core can pass us a set of gamma values to program. We actually only
331+
* use this for 8-bit mode so can't perform smooth fades on deeper modes,
332+
* but it's a requirement that we provide the function
333+
*/
334+
static int cirrus_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
335+
u16 *blue, uint32_t size,
336+
struct drm_modeset_acquire_ctx *ctx)
337+
{
338+
cirrus_crtc_load_lut(crtc);
333339

334340
return 0;
335341
}

drivers/gpu/drm/drm_atomic_helper.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1878,6 +1878,8 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
18781878
new_crtc_state->event->base.completion = &commit->flip_done;
18791879
new_crtc_state->event->base.completion_release = release_crtc_commit;
18801880
drm_crtc_commit_get(commit);
1881+
1882+
commit->abort_completion = true;
18811883
}
18821884

18831885
for_each_oldnew_connector_in_state(state, conn, old_conn_state, new_conn_state, i) {
@@ -3421,8 +3423,21 @@ EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state);
34213423
void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state)
34223424
{
34233425
if (state->commit) {
3426+
/*
3427+
* In the event that a non-blocking commit returns
3428+
* -ERESTARTSYS before the commit_tail work is queued, we will
3429+
* have an extra reference to the commit object. Release it, if
3430+
* the event has not been consumed by the worker.
3431+
*
3432+
* state->event may be freed, so we can't directly look at
3433+
* state->event->base.completion.
3434+
*/
3435+
if (state->event && state->commit->abort_completion)
3436+
drm_crtc_commit_put(state->commit);
3437+
34243438
kfree(state->commit->event);
34253439
state->commit->event = NULL;
3440+
34263441
drm_crtc_commit_put(state->commit);
34273442
}
34283443

drivers/gpu/drm/drm_edid.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ static const struct edid_quirk {
113113
/* AEO model 0 reports 8 bpc, but is a 6 bpc panel */
114114
{ "AEO", 0, EDID_QUIRK_FORCE_6BPC },
115115

116+
/* CPT panel of Asus UX303LA reports 8 bpc, but is a 6 bpc panel */
117+
{ "CPT", 0x17df, EDID_QUIRK_FORCE_6BPC },
118+
116119
/* Belinea 10 15 55 */
117120
{ "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 },
118121
{ "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 },
@@ -162,6 +165,24 @@ static const struct edid_quirk {
162165

163166
/* HTC Vive VR Headset */
164167
{ "HVR", 0xaa01, EDID_QUIRK_NON_DESKTOP },
168+
169+
/* Oculus Rift DK1, DK2, and CV1 VR Headsets */
170+
{ "OVR", 0x0001, EDID_QUIRK_NON_DESKTOP },
171+
{ "OVR", 0x0003, EDID_QUIRK_NON_DESKTOP },
172+
{ "OVR", 0x0004, EDID_QUIRK_NON_DESKTOP },
173+
174+
/* Windows Mixed Reality Headsets */
175+
{ "ACR", 0x7fce, EDID_QUIRK_NON_DESKTOP },
176+
{ "HPN", 0x3515, EDID_QUIRK_NON_DESKTOP },
177+
{ "LEN", 0x0408, EDID_QUIRK_NON_DESKTOP },
178+
{ "LEN", 0xb800, EDID_QUIRK_NON_DESKTOP },
179+
{ "FUJ", 0x1970, EDID_QUIRK_NON_DESKTOP },
180+
{ "DEL", 0x7fce, EDID_QUIRK_NON_DESKTOP },
181+
{ "SEC", 0x144a, EDID_QUIRK_NON_DESKTOP },
182+
{ "AUS", 0xc102, EDID_QUIRK_NON_DESKTOP },
183+
184+
/* Sony PlayStation VR Headset */
185+
{ "SNY", 0x0704, EDID_QUIRK_NON_DESKTOP },
165186
};
166187

167188
/*

drivers/gpu/drm/drm_mm.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -836,9 +836,24 @@ struct drm_mm_node *drm_mm_scan_color_evict(struct drm_mm_scan *scan)
836836
if (!mm->color_adjust)
837837
return NULL;
838838

839-
hole = list_first_entry(&mm->hole_stack, typeof(*hole), hole_stack);
840-
hole_start = __drm_mm_hole_node_start(hole);
841-
hole_end = hole_start + hole->hole_size;
839+
/*
840+
* The hole found during scanning should ideally be the first element
841+
* in the hole_stack list, but due to side-effects in the driver it
842+
* may not be.
843+
*/
844+
list_for_each_entry(hole, &mm->hole_stack, hole_stack) {
845+
hole_start = __drm_mm_hole_node_start(hole);
846+
hole_end = hole_start + hole->hole_size;
847+
848+
if (hole_start <= scan->hit_start &&
849+
hole_end >= scan->hit_end)
850+
break;
851+
}
852+
853+
/* We should only be called after we found the hole previously */
854+
DRM_MM_BUG_ON(&hole->hole_stack == &mm->hole_stack);
855+
if (unlikely(&hole->hole_stack == &mm->hole_stack))
856+
return NULL;
842857

843858
DRM_MM_BUG_ON(hole_start > scan->hit_start);
844859
DRM_MM_BUG_ON(hole_end < scan->hit_end);

drivers/gpu/drm/drm_probe_helper.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,26 @@ static void output_poll_execute(struct work_struct *work)
653653
schedule_delayed_work(delayed_work, DRM_OUTPUT_POLL_PERIOD);
654654
}
655655

656+
/**
657+
* drm_kms_helper_is_poll_worker - is %current task an output poll worker?
658+
*
659+
* Determine if %current task is an output poll worker. This can be used
660+
* to select distinct code paths for output polling versus other contexts.
661+
*
662+
* One use case is to avoid a deadlock between the output poll worker and
663+
* the autosuspend worker wherein the latter waits for polling to finish
664+
* upon calling drm_kms_helper_poll_disable(), while the former waits for
665+
* runtime suspend to finish upon calling pm_runtime_get_sync() in a
666+
* connector ->detect hook.
667+
*/
668+
bool drm_kms_helper_is_poll_worker(void)
669+
{
670+
struct work_struct *work = current_work();
671+
672+
return work && work->func == output_poll_execute;
673+
}
674+
EXPORT_SYMBOL(drm_kms_helper_is_poll_worker);
675+
656676
/**
657677
* drm_kms_helper_poll_disable - disable output polling
658678
* @dev: drm_device

drivers/gpu/drm/exynos/exynos_drm_g2d.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,6 @@ static int g2d_init_cmdlist(struct g2d_data *g2d)
286286

287287
node = kcalloc(G2D_CMDLIST_NUM, sizeof(*node), GFP_KERNEL);
288288
if (!node) {
289-
dev_err(dev, "failed to allocate memory\n");
290289
ret = -ENOMEM;
291290
goto err;
292291
}
@@ -926,17 +925,17 @@ static void g2d_finish_event(struct g2d_data *g2d, u32 cmdlist_no)
926925
struct drm_device *drm_dev = g2d->subdrv.drm_dev;
927926
struct g2d_runqueue_node *runqueue_node = g2d->runqueue_node;
928927
struct drm_exynos_pending_g2d_event *e;
929-
struct timeval now;
928+
struct timespec64 now;
930929

931930
if (list_empty(&runqueue_node->event_list))
932931
return;
933932

934933
e = list_first_entry(&runqueue_node->event_list,
935934
struct drm_exynos_pending_g2d_event, base.link);
936935

937-
do_gettimeofday(&now);
936+
ktime_get_ts64(&now);
938937
e->event.tv_sec = now.tv_sec;
939-
e->event.tv_usec = now.tv_usec;
938+
e->event.tv_usec = now.tv_nsec / NSEC_PER_USEC;
940939
e->event.cmdlist_no = cmdlist_no;
941940

942941
drm_send_event(drm_dev, &e->base);
@@ -1358,10 +1357,9 @@ int exynos_g2d_exec_ioctl(struct drm_device *drm_dev, void *data,
13581357
return -EFAULT;
13591358

13601359
runqueue_node = kmem_cache_alloc(g2d->runqueue_slab, GFP_KERNEL);
1361-
if (!runqueue_node) {
1362-
dev_err(dev, "failed to allocate memory\n");
1360+
if (!runqueue_node)
13631361
return -ENOMEM;
1364-
}
1362+
13651363
run_cmdlist = &runqueue_node->run_cmdlist;
13661364
event_list = &runqueue_node->event_list;
13671365
INIT_LIST_HEAD(run_cmdlist);

drivers/gpu/drm/exynos/exynos_drm_rotator.h

Lines changed: 0 additions & 19 deletions
This file was deleted.

drivers/gpu/drm/exynos/exynos_hdmi.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,10 +1068,13 @@ static void hdmi_audio_config(struct hdmi_context *hdata)
10681068
/* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
10691069
hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
10701070
| HDMI_I2S_SEL_LRCK(6));
1071-
hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(1)
1072-
| HDMI_I2S_SEL_SDATA2(4));
1071+
1072+
hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(3)
1073+
| HDMI_I2S_SEL_SDATA0(4));
1074+
10731075
hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
10741076
| HDMI_I2S_SEL_SDATA2(2));
1077+
10751078
hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
10761079

10771080
/* I2S_CON_1 & 2 */

0 commit comments

Comments
 (0)