Skip to content

Commit 35683dd

Browse files
committed
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie: "This has two main sets of fixes: - A bunch of Exynos fixes, mainly for their MIC component. - vblank regression fixes from Mario, apparantly some changes in 4.4 caused some vblank breakage on radeon/nouveau, this set fixes all the issues seen. There is also a revert of one of the MST changse, that I was overzealous in including, that broke 30" MST monitors, and two qxl fixes" * 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: drm/qxl: fix erroneous return value drm/nouveau/display: Enable vblank irqs after display engine is on again. drm/radeon/pm: Handle failure of drm_vblank_get. drm: Fix treatment of drm_vblank_offdelay in drm_vblank_on() (v2) drm: Fix drm_vblank_pre/post_modeset regression from Linux 4.4 drm: Prevent vblank counter bumps > 1 with active vblank clients. (v2) drm: No-Op redundant calls to drm_vblank_off() (v2) drm/qxl: use kmalloc_array to alloc reloc_info in qxl_process_single_command Revert "drm/dp/mst: change MST detection scheme" drm/exynos/decon: fix disable clocks order drm/exynos: fix incorrect cpu address for dma_mmap_attrs() drm/exynos: exynos5433_decon: fix wrong state in decon_vblank_enable drm/exynos: exynos5433_decon: fix wrong state assignment in decon_enable drm/exynos: dsi: restore support for drm bridge drm/exynos: mic: make all functions static drm/exynos: mic: convert to component framework drm/exynos: mic: use devm_clk interface drm/exynos: fix types for compilation on 64bit architectures drm/exynos: ipp: fix incorrect format specifiers in debug messages drm/exynos: depend on ARCH_EXYNOS for DRM_EXYNOS
2 parents a9f70bd + dada168 commit 35683dd

18 files changed

+178
-93
lines changed

drivers/gpu/drm/drm_dp_mst_topology.c

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,11 +1159,13 @@ static void drm_dp_add_port(struct drm_dp_mst_branch *mstb,
11591159
drm_dp_put_port(port);
11601160
goto out;
11611161
}
1162-
1163-
drm_mode_connector_set_tile_property(port->connector);
1164-
1162+
if (port->port_num >= DP_MST_LOGICAL_PORT_0) {
1163+
port->cached_edid = drm_get_edid(port->connector, &port->aux.ddc);
1164+
drm_mode_connector_set_tile_property(port->connector);
1165+
}
11651166
(*mstb->mgr->cbs->register_connector)(port->connector);
11661167
}
1168+
11671169
out:
11681170
/* put reference to this port */
11691171
drm_dp_put_port(port);
@@ -1188,8 +1190,8 @@ static void drm_dp_update_port(struct drm_dp_mst_branch *mstb,
11881190
port->ddps = conn_stat->displayport_device_plug_status;
11891191

11901192
if (old_ddps != port->ddps) {
1191-
dowork = true;
11921193
if (port->ddps) {
1194+
dowork = true;
11931195
} else {
11941196
port->available_pbn = 0;
11951197
}
@@ -1294,13 +1296,8 @@ static void drm_dp_check_and_send_link_address(struct drm_dp_mst_topology_mgr *m
12941296
if (port->input)
12951297
continue;
12961298

1297-
if (!port->ddps) {
1298-
if (port->cached_edid) {
1299-
kfree(port->cached_edid);
1300-
port->cached_edid = NULL;
1301-
}
1299+
if (!port->ddps)
13021300
continue;
1303-
}
13041301

13051302
if (!port->available_pbn)
13061303
drm_dp_send_enum_path_resources(mgr, mstb, port);
@@ -1311,12 +1308,6 @@ static void drm_dp_check_and_send_link_address(struct drm_dp_mst_topology_mgr *m
13111308
drm_dp_check_and_send_link_address(mgr, mstb_child);
13121309
drm_dp_put_mst_branch_device(mstb_child);
13131310
}
1314-
} else if (port->pdt == DP_PEER_DEVICE_SST_SINK ||
1315-
port->pdt == DP_PEER_DEVICE_DP_LEGACY_CONV) {
1316-
if (!port->cached_edid) {
1317-
port->cached_edid =
1318-
drm_get_edid(port->connector, &port->aux.ddc);
1319-
}
13201311
}
13211312
}
13221313
}
@@ -1336,8 +1327,6 @@ static void drm_dp_mst_link_probe_work(struct work_struct *work)
13361327
drm_dp_check_and_send_link_address(mgr, mstb);
13371328
drm_dp_put_mst_branch_device(mstb);
13381329
}
1339-
1340-
(*mgr->cbs->hotplug)(mgr);
13411330
}
13421331

13431332
static bool drm_dp_validate_guid(struct drm_dp_mst_topology_mgr *mgr,
@@ -1597,6 +1586,7 @@ static void drm_dp_send_link_address(struct drm_dp_mst_topology_mgr *mgr,
15971586
for (i = 0; i < txmsg->reply.u.link_addr.nports; i++) {
15981587
drm_dp_add_port(mstb, mgr->dev, &txmsg->reply.u.link_addr.ports[i]);
15991588
}
1589+
(*mgr->cbs->hotplug)(mgr);
16001590
}
16011591
} else {
16021592
mstb->link_address_sent = false;
@@ -2293,6 +2283,8 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
22932283
drm_dp_update_port(mstb, &msg.u.conn_stat);
22942284

22952285
DRM_DEBUG_KMS("Got CSN: pn: %d ldps:%d ddps: %d mcs: %d ip: %d pdt: %d\n", msg.u.conn_stat.port_number, msg.u.conn_stat.legacy_device_plug_status, msg.u.conn_stat.displayport_device_plug_status, msg.u.conn_stat.message_capability_status, msg.u.conn_stat.input_port, msg.u.conn_stat.peer_device_type);
2286+
(*mgr->cbs->hotplug)(mgr);
2287+
22962288
} else if (msg.req_type == DP_RESOURCE_STATUS_NOTIFY) {
22972289
drm_dp_send_up_ack_reply(mgr, mgr->mst_primary, msg.req_type, seqno, false);
22982290
if (!mstb)
@@ -2379,6 +2371,10 @@ enum drm_connector_status drm_dp_mst_detect_port(struct drm_connector *connector
23792371

23802372
case DP_PEER_DEVICE_SST_SINK:
23812373
status = connector_status_connected;
2374+
/* for logical ports - cache the EDID */
2375+
if (port->port_num >= 8 && !port->cached_edid) {
2376+
port->cached_edid = drm_get_edid(connector, &port->aux.ddc);
2377+
}
23822378
break;
23832379
case DP_PEER_DEVICE_DP_LEGACY_CONV:
23842380
if (port->ldps)
@@ -2433,7 +2429,10 @@ struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_
24332429

24342430
if (port->cached_edid)
24352431
edid = drm_edid_duplicate(port->cached_edid);
2436-
2432+
else {
2433+
edid = drm_get_edid(connector, &port->aux.ddc);
2434+
drm_mode_connector_set_tile_property(connector);
2435+
}
24372436
port->has_audio = drm_detect_monitor_audio(edid);
24382437
drm_dp_put_port(port);
24392438
return edid;

drivers/gpu/drm/drm_irq.c

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,64 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe,
224224
diff = (flags & DRM_CALLED_FROM_VBLIRQ) != 0;
225225
}
226226

227+
/*
228+
* Within a drm_vblank_pre_modeset - drm_vblank_post_modeset
229+
* interval? If so then vblank irqs keep running and it will likely
230+
* happen that the hardware vblank counter is not trustworthy as it
231+
* might reset at some point in that interval and vblank timestamps
232+
* are not trustworthy either in that interval. Iow. this can result
233+
* in a bogus diff >> 1 which must be avoided as it would cause
234+
* random large forward jumps of the software vblank counter.
235+
*/
236+
if (diff > 1 && (vblank->inmodeset & 0x2)) {
237+
DRM_DEBUG_VBL("clamping vblank bump to 1 on crtc %u: diffr=%u"
238+
" due to pre-modeset.\n", pipe, diff);
239+
diff = 1;
240+
}
241+
242+
/*
243+
* FIMXE: Need to replace this hack with proper seqlocks.
244+
*
245+
* Restrict the bump of the software vblank counter to a safe maximum
246+
* value of +1 whenever there is the possibility that concurrent readers
247+
* of vblank timestamps could be active at the moment, as the current
248+
* implementation of the timestamp caching and updating is not safe
249+
* against concurrent readers for calls to store_vblank() with a bump
250+
* of anything but +1. A bump != 1 would very likely return corrupted
251+
* timestamps to userspace, because the same slot in the cache could
252+
* be concurrently written by store_vblank() and read by one of those
253+
* readers without the read-retry logic detecting the collision.
254+
*
255+
* Concurrent readers can exist when we are called from the
256+
* drm_vblank_off() or drm_vblank_on() functions and other non-vblank-
257+
* irq callers. However, all those calls to us are happening with the
258+
* vbl_lock locked to prevent drm_vblank_get(), so the vblank refcount
259+
* can't increase while we are executing. Therefore a zero refcount at
260+
* this point is safe for arbitrary counter bumps if we are called
261+
* outside vblank irq, a non-zero count is not 100% safe. Unfortunately
262+
* we must also accept a refcount of 1, as whenever we are called from
263+
* drm_vblank_get() -> drm_vblank_enable() the refcount will be 1 and
264+
* we must let that one pass through in order to not lose vblank counts
265+
* during vblank irq off - which would completely defeat the whole
266+
* point of this routine.
267+
*
268+
* Whenever we are called from vblank irq, we have to assume concurrent
269+
* readers exist or can show up any time during our execution, even if
270+
* the refcount is currently zero, as vblank irqs are usually only
271+
* enabled due to the presence of readers, and because when we are called
272+
* from vblank irq we can't hold the vbl_lock to protect us from sudden
273+
* bumps in vblank refcount. Therefore also restrict bumps to +1 when
274+
* called from vblank irq.
275+
*/
276+
if ((diff > 1) && (atomic_read(&vblank->refcount) > 1 ||
277+
(flags & DRM_CALLED_FROM_VBLIRQ))) {
278+
DRM_DEBUG_VBL("clamping vblank bump to 1 on crtc %u: diffr=%u "
279+
"refcount %u, vblirq %u\n", pipe, diff,
280+
atomic_read(&vblank->refcount),
281+
(flags & DRM_CALLED_FROM_VBLIRQ) != 0);
282+
diff = 1;
283+
}
284+
227285
DRM_DEBUG_VBL("updating vblank count on crtc %u:"
228286
" current=%u, diff=%u, hw=%u hw_last=%u\n",
229287
pipe, vblank->count, diff, cur_vblank, vblank->last);
@@ -1316,7 +1374,13 @@ void drm_vblank_off(struct drm_device *dev, unsigned int pipe)
13161374
spin_lock_irqsave(&dev->event_lock, irqflags);
13171375

13181376
spin_lock(&dev->vbl_lock);
1319-
vblank_disable_and_save(dev, pipe);
1377+
DRM_DEBUG_VBL("crtc %d, vblank enabled %d, inmodeset %d\n",
1378+
pipe, vblank->enabled, vblank->inmodeset);
1379+
1380+
/* Avoid redundant vblank disables without previous drm_vblank_on(). */
1381+
if (drm_core_check_feature(dev, DRIVER_ATOMIC) || !vblank->inmodeset)
1382+
vblank_disable_and_save(dev, pipe);
1383+
13201384
wake_up(&vblank->queue);
13211385

13221386
/*
@@ -1418,6 +1482,9 @@ void drm_vblank_on(struct drm_device *dev, unsigned int pipe)
14181482
return;
14191483

14201484
spin_lock_irqsave(&dev->vbl_lock, irqflags);
1485+
DRM_DEBUG_VBL("crtc %d, vblank enabled %d, inmodeset %d\n",
1486+
pipe, vblank->enabled, vblank->inmodeset);
1487+
14211488
/* Drop our private "prevent drm_vblank_get" refcount */
14221489
if (vblank->inmodeset) {
14231490
atomic_dec(&vblank->refcount);
@@ -1430,8 +1497,7 @@ void drm_vblank_on(struct drm_device *dev, unsigned int pipe)
14301497
* re-enable interrupts if there are users left, or the
14311498
* user wishes vblank interrupts to be enabled all the time.
14321499
*/
1433-
if (atomic_read(&vblank->refcount) != 0 ||
1434-
(!dev->vblank_disable_immediate && drm_vblank_offdelay == 0))
1500+
if (atomic_read(&vblank->refcount) != 0 || drm_vblank_offdelay == 0)
14351501
WARN_ON(drm_vblank_enable(dev, pipe));
14361502
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
14371503
}
@@ -1526,6 +1592,7 @@ void drm_vblank_post_modeset(struct drm_device *dev, unsigned int pipe)
15261592
if (vblank->inmodeset) {
15271593
spin_lock_irqsave(&dev->vbl_lock, irqflags);
15281594
dev->vblank_disable_allowed = true;
1595+
drm_reset_vblank_timestamp(dev, pipe);
15291596
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
15301597

15311598
if (vblank->inmodeset & 0x2)

drivers/gpu/drm/exynos/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
config DRM_EXYNOS
22
tristate "DRM Support for Samsung SoC EXYNOS Series"
3-
depends on OF && DRM && (PLAT_SAMSUNG || ARCH_MULTIPLATFORM)
3+
depends on OF && DRM && (ARCH_S3C64XX || ARCH_EXYNOS || ARCH_MULTIPLATFORM)
44
select DRM_KMS_HELPER
55
select DRM_KMS_FB_HELPER
66
select FB_CFB_FILLRECT

drivers/gpu/drm/exynos/exynos5433_drm_decon.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ static int decon_enable_vblank(struct exynos_drm_crtc *crtc)
9393
if (test_bit(BIT_SUSPENDED, &ctx->flags))
9494
return -EPERM;
9595

96-
if (test_and_set_bit(BIT_IRQS_ENABLED, &ctx->flags)) {
96+
if (!test_and_set_bit(BIT_IRQS_ENABLED, &ctx->flags)) {
9797
val = VIDINTCON0_INTEN;
9898
if (ctx->out_type == IFTYPE_I80)
9999
val |= VIDINTCON0_FRAMEDONE;
@@ -402,8 +402,6 @@ static void decon_enable(struct exynos_drm_crtc *crtc)
402402
decon_enable_vblank(ctx->crtc);
403403

404404
decon_commit(ctx->crtc);
405-
406-
set_bit(BIT_SUSPENDED, &ctx->flags);
407405
}
408406

409407
static void decon_disable(struct exynos_drm_crtc *crtc)
@@ -582,9 +580,9 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
582580
static int exynos5433_decon_suspend(struct device *dev)
583581
{
584582
struct decon_context *ctx = dev_get_drvdata(dev);
585-
int i;
583+
int i = ARRAY_SIZE(decon_clks_name);
586584

587-
for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++)
585+
while (--i >= 0)
588586
clk_disable_unprepare(ctx->clks[i]);
589587

590588
return 0;

drivers/gpu/drm/exynos/exynos_drm_dsi.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1782,6 +1782,7 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
17821782

17831783
bridge = of_drm_find_bridge(dsi->bridge_node);
17841784
if (bridge) {
1785+
encoder->bridge = bridge;
17851786
drm_bridge_attach(drm_dev, bridge);
17861787
}
17871788

drivers/gpu/drm/exynos/exynos_drm_fbdev.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ static int exynos_drm_fb_mmap(struct fb_info *info,
5050
if (vm_size > exynos_gem->size)
5151
return -EINVAL;
5252

53-
ret = dma_mmap_attrs(helper->dev->dev, vma, exynos_gem->pages,
53+
ret = dma_mmap_attrs(helper->dev->dev, vma, exynos_gem->cookie,
5454
exynos_gem->dma_addr, exynos_gem->size,
5555
&exynos_gem->dma_attrs);
5656
if (ret < 0) {

drivers/gpu/drm/exynos/exynos_drm_fimc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1723,7 +1723,7 @@ static int fimc_probe(struct platform_device *pdev)
17231723
goto err_put_clk;
17241724
}
17251725

1726-
DRM_DEBUG_KMS("id[%d]ippdrv[0x%x]\n", ctx->id, (int)ippdrv);
1726+
DRM_DEBUG_KMS("id[%d]ippdrv[%p]\n", ctx->id, ippdrv);
17271727

17281728
spin_lock_init(&ctx->lock);
17291729
platform_set_drvdata(pdev, ctx);

drivers/gpu/drm/exynos/exynos_drm_g2d.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,7 +1166,7 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data,
11661166
goto err_free_event;
11671167
}
11681168

1169-
cmd = (struct drm_exynos_g2d_cmd *)(uint32_t)req->cmd;
1169+
cmd = (struct drm_exynos_g2d_cmd *)(unsigned long)req->cmd;
11701170

11711171
if (copy_from_user(cmdlist->data + cmdlist->last,
11721172
(void __user *)cmd,
@@ -1184,7 +1184,8 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data,
11841184
if (req->cmd_buf_nr) {
11851185
struct drm_exynos_g2d_cmd *cmd_buf;
11861186

1187-
cmd_buf = (struct drm_exynos_g2d_cmd *)(uint32_t)req->cmd_buf;
1187+
cmd_buf = (struct drm_exynos_g2d_cmd *)
1188+
(unsigned long)req->cmd_buf;
11881189

11891190
if (copy_from_user(cmdlist->data + cmdlist->last,
11901191
(void __user *)cmd_buf,

drivers/gpu/drm/exynos/exynos_drm_gem.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ static struct exynos_drm_gem *exynos_drm_gem_init(struct drm_device *dev,
218218
return ERR_PTR(ret);
219219
}
220220

221-
DRM_DEBUG_KMS("created file object = 0x%x\n", (unsigned int)obj->filp);
221+
DRM_DEBUG_KMS("created file object = %p\n", obj->filp);
222222

223223
return exynos_gem;
224224
}
@@ -335,7 +335,7 @@ static int exynos_drm_gem_mmap_buffer(struct exynos_drm_gem *exynos_gem,
335335
if (vm_size > exynos_gem->size)
336336
return -EINVAL;
337337

338-
ret = dma_mmap_attrs(drm_dev->dev, vma, exynos_gem->pages,
338+
ret = dma_mmap_attrs(drm_dev->dev, vma, exynos_gem->cookie,
339339
exynos_gem->dma_addr, exynos_gem->size,
340340
&exynos_gem->dma_attrs);
341341
if (ret < 0) {

drivers/gpu/drm/exynos/exynos_drm_gsc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1723,7 +1723,7 @@ static int gsc_probe(struct platform_device *pdev)
17231723
return ret;
17241724
}
17251725

1726-
DRM_DEBUG_KMS("id[%d]ippdrv[0x%x]\n", ctx->id, (int)ippdrv);
1726+
DRM_DEBUG_KMS("id[%d]ippdrv[%p]\n", ctx->id, ippdrv);
17271727

17281728
mutex_init(&ctx->lock);
17291729
platform_set_drvdata(pdev, ctx);

0 commit comments

Comments
 (0)