From patchwork Fri Nov 18 02:03:48 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dhinakaran Pandiyan X-Patchwork-Id: 9435653 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 BE1AC60471 for ; Fri, 18 Nov 2016 02:04:46 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AE65F28335 for ; Fri, 18 Nov 2016 02:04:46 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A2E202972B; Fri, 18 Nov 2016 02:04:46 +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 CA12D28335 for ; Fri, 18 Nov 2016 02:04:45 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 632456E8B5; Fri, 18 Nov 2016 02:04:44 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id 8C6BB6E8AD; Fri, 18 Nov 2016 02:04:34 +0000 (UTC) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga102.fm.intel.com with ESMTP; 17 Nov 2016 18:04:34 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.31,655,1473145200"; d="scan'208"; a="1060926633" Received: from nuc-skylake.jf.intel.com ([10.54.75.23]) by orsmga001.jf.intel.com with ESMTP; 17 Nov 2016 18:04:34 -0800 From: Dhinakaran Pandiyan To: intel-gfx@lists.freedesktop.org Date: Thu, 17 Nov 2016 18:03:48 -0800 Message-Id: <1479434628-2373-4-git-send-email-dhinakaran.pandiyan@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1479434628-2373-1-git-send-email-dhinakaran.pandiyan@intel.com> References: <1479434628-2373-1-git-send-email-dhinakaran.pandiyan@intel.com> Cc: daniel.vetter@ffwll.ch, dri-devel@lists.freedesktop.org, Dhinakaran Pandiyan Subject: [Intel-gfx] [PATCH 3/3] drm/dp/mst: Track available time slots in DP Multi-Stream Transport Packet X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 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-Virus-Scanned: ClamAV using ClamSMTP The avail_slots member in struct drm_dp_mst_topology_mgr does not really track the available time slots in a MTP(Multi-Stream Transport Packet). It is assigned an initial value when the topology manager is setup but not updated after that. So, let's use avail_slots to store the number of unallocated slots out of the total 64. The value will be updated when vcpi allocation or reset happens. Since vcpi allocation and deallocation can happen simultaneously, the struct drm_dp_mst_topology_mgr.lock mutex is used to protect it from concurrent accesses. Signed-off-by: Dhinakaran Pandiyan --- drivers/gpu/drm/drm_dp_mst_topology.c | 55 ++++++++++++++++++++++++++--------- drivers/gpu/drm/i915/intel_dp_mst.c | 5 +++- include/drm/drm_dp_mst_helper.h | 2 +- 3 files changed, 47 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 26dfd99..19e2250 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -2040,7 +2040,9 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms } mgr->total_pbn = 64 * mgr->pbn_div; mgr->total_slots = 64; - mgr->avail_slots = mgr->total_slots; + + /* 1 slot out of the 64 time slots is used for MTP header */ + mgr->avail_slots = mgr->total_slots - 1; /* add initial branch device at LCT 1 */ mstb = drm_dp_add_mst_branch_device(1, NULL); @@ -2465,34 +2467,52 @@ EXPORT_SYMBOL(drm_dp_mst_get_edid); * @pbn: payload bandwidth to convert into slots. */ int drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, - int pbn) + struct drm_dp_mst_port *port, int pbn) { - int num_slots; + int req_slots, curr_slots, new_slots, ret; + + req_slots = DIV_ROUND_UP(pbn, mgr->pbn_div); + curr_slots = drm_dp_mst_get_vcpi_slots(mgr, port); - num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div); + if (req_slots <= curr_slots) + return req_slots; - if (num_slots > mgr->avail_slots) - return -ENOSPC; - return num_slots; + new_slots = req_slots - curr_slots; + mutex_lock(&mgr->lock); + if (new_slots <= mgr->avail_slots) { + ret = req_slots; + } else { + DRM_DEBUG_KMS("not enough vcpi slots, req=%d avail=%d\n", req_slots, mgr->avail_slots); + ret = -ENOSPC; + } + mutex_unlock(&mgr->lock); + + return ret; } EXPORT_SYMBOL(drm_dp_find_vcpi_slots); static int drm_dp_init_vcpi(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_vcpi *vcpi, int pbn) { - int num_slots; + int req_slots; int ret; - num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div); + req_slots = DIV_ROUND_UP(pbn, mgr->pbn_div); - if (num_slots > mgr->avail_slots) - return -ENOSPC; + mutex_lock(&mgr->lock); + if (req_slots > mgr->avail_slots) { + ret = -ENOSPC; + goto out; + } vcpi->pbn = pbn; - vcpi->aligned_pbn = num_slots * mgr->pbn_div; - vcpi->num_slots = num_slots; + vcpi->aligned_pbn = req_slots * mgr->pbn_div; + vcpi->num_slots = req_slots; ret = drm_dp_mst_assign_payload_id(mgr, vcpi); + +out: + mutex_unlock(&mgr->lock); if (ret < 0) return ret; return 0; @@ -2530,6 +2550,10 @@ bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp DRM_DEBUG_KMS("initing vcpi for %d %d\n", pbn, port->vcpi.num_slots); *slots = port->vcpi.num_slots; + mutex_lock(&mgr->lock); + mgr->avail_slots -= port->vcpi.num_slots; + mutex_unlock(&mgr->lock); + drm_dp_put_port(port); return true; out: @@ -2562,6 +2586,11 @@ void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm port = drm_dp_get_validated_port_ref(mgr, port); if (!port) return; + + mutex_lock(&mgr->lock); + mgr->avail_slots += port->vcpi.num_slots; + mutex_unlock(&mgr->lock); + port->vcpi.num_slots = 0; drm_dp_put_port(port); } diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 4280a83..bad9300 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -42,6 +42,8 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, int lane_count, slots; const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; int mst_pbn; + struct intel_connector *connector = + to_intel_connector(conn_state->connector); pipe_config->dp_encoder_is_mst = true; pipe_config->has_pch_encoder = false; @@ -62,7 +64,8 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, mst_pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock, bpp); pipe_config->pbn = mst_pbn; - slots = drm_dp_find_vcpi_slots(&intel_dp->mst_mgr, mst_pbn); + slots = drm_dp_find_vcpi_slots(&intel_dp->mst_mgr, connector->port, + mst_pbn); if (slots < 0) { DRM_ERROR("not enough available time slots for pbn=%d", mst_pbn); return false; diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index 0032076..5c55528 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h @@ -590,7 +590,7 @@ void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr, int drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, - int pbn); + struct drm_dp_mst_port *port, int pbn); int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr);