From patchwork Thu Jan 26 12:37:28 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Peres X-Patchwork-Id: 9539185 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 9D520604A0 for ; Thu, 26 Jan 2017 12:37:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 84B1B27F93 for ; Thu, 26 Jan 2017 12:37:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7885A2819A; Thu, 26 Jan 2017 12:37:44 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 0BF1627F93 for ; Thu, 26 Jan 2017 12:37:44 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2A4F96EB6A; Thu, 26 Jan 2017 12:37:42 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by gabe.freedesktop.org (Postfix) with ESMTPS id 0F6DB6EB69 for ; Thu, 26 Jan 2017 12:37:41 +0000 (UTC) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga105.jf.intel.com with ESMTP; 26 Jan 2017 04:37:40 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.33,289,1477983600"; d="scan'208";a="35752938" Received: from linux.intel.com ([10.54.29.200]) by orsmga002.jf.intel.com with ESMTP; 26 Jan 2017 04:37:40 -0800 Received: from mperes_DESK.fi.intel.com (mperes_desk.fi.intel.com [10.237.72.154]) by linux.intel.com (Postfix) with ESMTP id 4244D6A4006; Thu, 26 Jan 2017 04:36:42 -0800 (PST) From: Martin Peres To: xorg-devel@lists.x.org Subject: [RFC PATCH xserver] modesetting: re-set the crtc's mode when link-status goes BAD Date: Thu, 26 Jan 2017 14:37:28 +0200 Message-Id: <20170126123728.5680-1-martin.peres@linux.intel.com> X-Mailer: git-send-email 2.11.0 Cc: Manasi Navare , dri-devel@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Despite all the careful planing of the kernel, a link may become insufficient to handle the currently-set mode. At this point, the kernel should mark this particular configuration as being broken and potentially prune the mode before setting the offending connector's link-status to BAD and send the userspace a hotplug event. This may happen right after a modeset or later on. When available, we should use the link-status information to reset the wanted mode. Signed-off-by: Martin Peres --- WARNING: The patches have not been merged in the kernel yet, so this patch is merely an RFC. This patch is the result of discussions happening mostly in DRI-devel and Intel-GFX on how to handle link training failures. I would advise reading the thread [0] first and then this thread [1] which explain in great length why this is needed and why the selected approach seems to be the best. The relevant kernel patches + this patch are enough to pass the relevant DisplayPort compliance tests, provided that the Desktop Environment or another program ([2]?) provides the initial modesetting on hotplug. Would this patch be acceptable to you? Any comments or suggestions? [0] https://lists.freedesktop.org/archives/dri-devel/2016-November/123366.html [1] https://lists.freedesktop.org/archives/dri-devel/2016-November/124736.html [2] https://cgit.freedesktop.org/~mperes/auto-randr/ hw/xfree86/drivers/modesetting/drmmode_display.c | 51 ++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c index 6e755e9482..3144620c67 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.c +++ b/hw/xfree86/drivers/modesetting/drmmode_display.c @@ -2262,6 +2262,10 @@ drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn) } #ifdef CONFIG_UDEV_KMS + +#define DRM_MODE_LINK_STATUS_GOOD 0 +#define DRM_MODE_LINK_STATUS_BAD 1 + static void drmmode_handle_uevents(int fd, void *closure) { @@ -2281,6 +2285,49 @@ drmmode_handle_uevents(int fd, void *closure) if (!found) return; + /* Try to re-set the mode on all the connectors with a BAD link-state: + * This may happen if a link degrades and a new modeset is necessary, using + * different link-training parameters. If the kernel found that the current + * mode is not achievable anymore, it should have pruned the mode before + * sending the hotplug event. Try to re-set the currently-set mode to keep + * the display alive, this will fail if the mode has been pruned. + * In any case, we will send randr events for the Desktop Environment to + * deal with it, if it wants to. + */ + for (i = 0; i < config->num_output; i++) { + xf86OutputPtr output = config->output[i]; + drmmode_output_private_ptr drmmode_output = output->driver_private; + uint32_t con_id = drmmode_output->mode_output->connector_id; + drmModeConnectorPtr koutput; + + /* Get an updated view of the properties for the current connector and + * look for the link-status property + */ + koutput = drmModeGetConnectorCurrent(drmmode->fd, con_id); + for (j = 0; koutput && j < koutput->count_props; j++) { + drmModePropertyPtr props; + props = drmModeGetProperty(drmmode->fd, koutput->props[j]); + if (props && props->flags & DRM_MODE_PROP_ENUM && + !strcmp(props->name, "link-status") && + koutput->prop_values[j] == DRM_MODE_LINK_STATUS_BAD) { + xf86CrtcPtr crtc = output->crtc; + if (!crtc) + continue; + + /* the connector got a link failure, re-set the current mode */ + drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation, + crtc->x, crtc->y); + + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "hotplug event: connector %u's link-state is BAD, " + "tried resetting the current mode. You may be left" + "with a black screen if this fails...\n", con_id); + } + drmModeFreeProperty(props); + } + drmModeFreeConnector(koutput); + } + mode_res = drmModeGetResources(drmmode->fd); if (!mode_res) goto out; @@ -2345,6 +2392,10 @@ out_free_res: out: RRGetInfo(xf86ScrnToScreen(scrn), TRUE); } + +#undef DRM_MODE_LINK_STATUS_BAD +#undef DRM_MODE_LINK_STATUS_GOOD + #endif void