From patchwork Tue Sep 9 06:28:13 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Airlie X-Patchwork-Id: 4866331 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id AFF26C033A for ; Tue, 9 Sep 2014 06:28:36 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0FCEC200ED for ; Tue, 9 Sep 2014 06:28:35 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 2BED120160 for ; Tue, 9 Sep 2014 06:28:34 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3E8F76E3A4; Mon, 8 Sep 2014 23:28:33 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by gabe.freedesktop.org (Postfix) with ESMTP id 197B26E3AB; Mon, 8 Sep 2014 23:28:32 -0700 (PDT) Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s896SVwJ029341 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 9 Sep 2014 02:28:31 -0400 Received: from tyrion-bne-redhat-com.bne.redhat.com (dhcp-41-68.bne.redhat.com [10.64.41.68]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s896SIP0023257; Tue, 9 Sep 2014 02:28:30 -0400 From: Dave Airlie To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Date: Tue, 9 Sep 2014 16:28:13 +1000 Message-Id: <1410244096-9854-9-git-send-email-airlied@gmail.com> In-Reply-To: <1410244096-9854-1-git-send-email-airlied@gmail.com> References: <1410244096-9854-1-git-send-email-airlied@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 Subject: [Intel-gfx] [PATCH 08/11] drm/crtc: attempt to set tiled modes from userspace X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-6.7 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Dave Airlie So when userspace asks us to set a mode on a tiled crtc, split it up and find the actual modes and attempt to set them. Also disable crtcs when no longer in tiled group. Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc.c | 51 ++++++++++++++++++++++++++++++++--- drivers/gpu/drm/drm_dp_mst_topology.c | 6 +++++ include/drm/drm_crtc.h | 8 ++++++ 3 files changed, 61 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 99fa259..628f3af 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -764,6 +764,9 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, crtc->funcs = funcs; crtc->invert_dimensions = false; + INIT_LIST_HEAD(&crtc->tile_crtc_list); + crtc->tile_master = NULL; + drm_modeset_lock_all(dev); drm_modeset_lock_init(&crtc->mutex); /* dropped by _unlock_all(): */ @@ -2520,7 +2523,7 @@ static int drm_mode_setcrtc_tiled(struct drm_mode_set *orig_set) list_for_each_entry(crtc2, &dev->mode_config.crtc_list, head) { if (crtc2 == orig_set->crtc) continue; - if (crtc2->enabled) + if (crtc2->enabled && !crtc2->tile_master) continue; pick_crtc = crtc2; break; @@ -2583,14 +2586,26 @@ static int drm_mode_setcrtc_tiled(struct drm_mode_set *orig_set) set[1].x = orig_set->x + ((pick_conn[1]->tile_h_loc == 1) ? pick_conn[0]->tile_h_size + 1 : 0); set[1].y = orig_set->y + ((pick_conn[1]->tile_v_loc == 1) ? pick_conn[0]->tile_v_size + 1 : 0); + if (set[1].crtc->tile_master) { + list_del(&set[1].crtc->tile); + set[1].crtc->tile_master = NULL; + } + list_add_tail(&set[1].crtc->tile, &set[0].crtc->tile_crtc_list); + set[1].crtc->tile_master = set[0].crtc; /* find a mode to use on each head */ set[0].mode = pick_modes[0]; set[1].mode = pick_modes[1]; ret = drm_mode_set_config_internal(&set[0]); - ret = drm_mode_set_config_internal(&set[1]); + if (!ret) { + ret = drm_mode_set_config_internal(&set[1]); + } + if (ret) { + set[1].crtc->tile_master = NULL; + list_del(&set[1].crtc->tile); + } return ret; } /** @@ -2637,6 +2652,15 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, } DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); + if (crtc->tile_master) { + if (crtc_req->mode_valid) + ret = -EBUSY; + else + ret = 0; + DRM_DEBUG_KMS("[CRTC:%d] refused due to tile %d\n", crtc->base.id, ret); + goto out; + } + if (crtc_req->mode_valid) { /* If we have a mode we need a framebuffer. */ /* If we pass -1, set the mode with the currently bound fb */ @@ -2748,9 +2772,25 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, if (num_tiles > 1) { ret = drm_mode_setcrtc_tiled(&set); - } else - ret = drm_mode_set_config_internal(&set); + } else { + if (!list_empty(&crtc->tile_crtc_list)) { + struct drm_crtc *tile_crtc, *t; + + list_for_each_entry_safe(tile_crtc, t, &crtc->tile_crtc_list, tile) { + struct drm_mode_set set2; + + tile_crtc->tile_master = NULL; + list_del(&tile_crtc->tile); + DRM_DEBUG_KMS("disabling crtc %p due to no longer needing tiling %p\n", tile_crtc, tile_crtc->primary); + memset(&set2, 0, sizeof(struct drm_mode_set)); + set2.crtc = tile_crtc; + set2.fb = NULL; + ret = drm_mode_set_config_internal(&set2); + } + } + ret = drm_mode_set_config_internal(&set); + } out: if (fb) drm_framebuffer_unreference(fb); @@ -4226,6 +4266,9 @@ static int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj, int ret = -EINVAL; struct drm_connector *connector = obj_to_connector(obj); + if (connector->has_tile && connector->tile_is_single_monitor && + (connector->tile_h_loc || connector->tile_v_loc)) + return 0; /* Do DPMS ourselves */ if (property == connector->dev->mode_config.dpms_property) { if (connector->funcs->dpms) diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 08b7140..ca5eee6 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -2190,6 +2190,12 @@ enum drm_connector_status drm_dp_mst_detect_port(struct drm_connector *connector if (port->port_num >= 8 && !port->cached_edid) { port->cached_edid = drm_get_edid(connector, &port->aux.ddc); } + + if (connector->has_tile && connector->tile_group_id == 0) + connector->tile_group_id = port->parent->conn_base_id; + if (connector->has_tile && (connector->tile_h_loc || connector->tile_v_loc)) + status = connector_status_disconnected; + break; case DP_PEER_DEVICE_DP_LEGACY_CONV: if (port->ldps) diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 67c06bd..6041acd 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -375,6 +375,14 @@ struct drm_crtc { void *helper_private; struct drm_object_properties properties; + + /* crtcs this one is using for tiling */ + struct list_head tile_crtc_list; + + /* tile list entry */ + struct list_head tile; + + struct drm_crtc *tile_master; };