From patchwork Wed Feb 19 17:42:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Drew Davenport X-Patchwork-Id: 11392121 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BEF8892A for ; Wed, 19 Feb 2020 17:43:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9667A24673 for ; Wed, 19 Feb 2020 17:43:12 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="S0BybC/L" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726712AbgBSRnK (ORCPT ); Wed, 19 Feb 2020 12:43:10 -0500 Received: from mail-il1-f194.google.com ([209.85.166.194]:36864 "EHLO mail-il1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726605AbgBSRnK (ORCPT ); Wed, 19 Feb 2020 12:43:10 -0500 Received: by mail-il1-f194.google.com with SMTP id v13so21296350iln.4 for ; Wed, 19 Feb 2020 09:43:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=8VamPOzOFp0h6bF9coMhzVUXDhZEhY+KJ39znRhBSOQ=; b=S0BybC/LcwM+sMXNhjhATGff7wWVLyrPSQrUSaCM5vM2OcxdjgEZnxw+EsfMo7Tlbx 4629wCbGvAbknrmn7sFJSA8n3p/qLh69icwvTKlbfJk3ku4Uws/koWFDUyJkeuCuh88r HZXS5ScmU41sVch/O2LCdfnkeqI81iLkm1LNk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=8VamPOzOFp0h6bF9coMhzVUXDhZEhY+KJ39znRhBSOQ=; b=T+l+rR1XVwTi4UpirqPwUxBOzAqY3ZxLxDh0BlfjzpWVwhBva0ACRymXtmtTShxbCx 8k6Yvg4ybT+V03+z4BrbzFegkeyvKXerKB89bsl4BXKFweQ8a7sKfj3WLJts8eOhg0OR lEahoNtRe18lNpAqhXNdfHxxc58OBJ4ue8EHVYxa2w/Ek2iy0rlBA1E/DQcJtWfkXhDY +60Y1pjVfP2yIkbbyUO7kCzMtFR1mRg8O7N4/wk2k3WIcWfQvVKA9hHd/BF9bnaOi4k4 3xNIxlby7en40UikT1P5xTpD1yae4fsu2nxbrhsyFb15enZy+68A78oSHmDMUt3Y3dcl AgEg== X-Gm-Message-State: APjAAAXENMj/lwdyH2OAKFpe0X65j6vN+JBKJt1yrmluAYx2pD1Zy/UT LQRSk7DaLrTpSPEH82Bx7f0low== X-Google-Smtp-Source: APXvYqwevqK6J8wLASlbM0W/NAsY85ngNqbvK6WaR5nDhBNGalMr/6g1gnP6s1SYxdqDux5vi2L1OA== X-Received: by 2002:a92:3989:: with SMTP id h9mr23430181ilf.156.1582134189162; Wed, 19 Feb 2020 09:43:09 -0800 (PST) Received: from ddavenport4.bld.corp.google.com ([2620:15c:183:0:92f:a80a:519d:f777]) by smtp.gmail.com with ESMTPSA id a21sm60355ioh.29.2020.02.19.09.43.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 19 Feb 2020 09:43:08 -0800 (PST) From: Drew Davenport To: dri-devel@lists.freedesktop.org Cc: Drew Davenport , Alexios Zavras , Daniel Vetter , David Airlie , Greg Kroah-Hartman , Rob Clark , Sean Paul , Stephen Boyd , Thomas Gleixner , freedreno@lists.freedesktop.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/4] drm/msm/dpu: Remove unused function arguments Date: Wed, 19 Feb 2020 10:42:24 -0700 Message-Id: <20200219104148.1.I0183a464f2788d41e6902f3535941f69c594b4c1@changeid> X-Mailer: git-send-email 2.24.1 MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Several functions arguments in the resource manager are unused, so remove them. Signed-off-by: Drew Davenport Reviewed-by: Stephen Boyd --- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 37 ++++++++++---------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index 23f5b1433b357..dea1dba441fe7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -144,8 +144,7 @@ static int _dpu_rm_hw_blk_create( const struct dpu_mdss_cfg *cat, void __iomem *mmio, enum dpu_hw_blk_type type, - uint32_t id, - const void *hw_catalog_info) + uint32_t id) { struct dpu_rm_hw_blk *blk; void *hw; @@ -223,7 +222,7 @@ int dpu_rm_init(struct dpu_rm *rm, } rc = _dpu_rm_hw_blk_create(rm, cat, mmio, DPU_HW_BLK_LM, - cat->mixer[i].id, &cat->mixer[i]); + cat->mixer[i].id); if (rc) { DPU_ERROR("failed: lm hw not available\n"); goto fail; @@ -244,7 +243,7 @@ int dpu_rm_init(struct dpu_rm *rm, for (i = 0; i < cat->pingpong_count; i++) { rc = _dpu_rm_hw_blk_create(rm, cat, mmio, DPU_HW_BLK_PINGPONG, - cat->pingpong[i].id, &cat->pingpong[i]); + cat->pingpong[i].id); if (rc) { DPU_ERROR("failed: pp hw not available\n"); goto fail; @@ -258,7 +257,7 @@ int dpu_rm_init(struct dpu_rm *rm, } rc = _dpu_rm_hw_blk_create(rm, cat, mmio, DPU_HW_BLK_INTF, - cat->intf[i].id, &cat->intf[i]); + cat->intf[i].id); if (rc) { DPU_ERROR("failed: intf hw not available\n"); goto fail; @@ -267,7 +266,7 @@ int dpu_rm_init(struct dpu_rm *rm, for (i = 0; i < cat->ctl_count; i++) { rc = _dpu_rm_hw_blk_create(rm, cat, mmio, DPU_HW_BLK_CTL, - cat->ctl[i].id, &cat->ctl[i]); + cat->ctl[i].id); if (rc) { DPU_ERROR("failed: ctl hw not available\n"); goto fail; @@ -293,7 +292,6 @@ static bool _dpu_rm_needs_split_display(const struct msm_display_topology *top) * pingpong * @rm: dpu resource manager handle * @enc_id: encoder id requesting for allocation - * @reqs: proposed use case requirements * @lm: proposed layer mixer, function checks if lm, and all other hardwired * blocks connected to the lm (pp) is available and appropriate * @pp: output parameter, pingpong block attached to the layer mixer. @@ -305,7 +303,6 @@ static bool _dpu_rm_needs_split_display(const struct msm_display_topology *top) static bool _dpu_rm_check_lm_and_get_connected_blks( struct dpu_rm *rm, uint32_t enc_id, - struct dpu_rm_requirements *reqs, struct dpu_rm_hw_blk *lm, struct dpu_rm_hw_blk **pp, struct dpu_rm_hw_blk *primary_lm) @@ -384,7 +381,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, uint32_t enc_id, lm[lm_count] = iter_i.blk; if (!_dpu_rm_check_lm_and_get_connected_blks( - rm, enc_id, reqs, lm[lm_count], + rm, enc_id, lm[lm_count], &pp[lm_count], NULL)) continue; @@ -399,7 +396,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, uint32_t enc_id, continue; if (!_dpu_rm_check_lm_and_get_connected_blks( - rm, enc_id, reqs, iter_j.blk, + rm, enc_id, iter_j.blk, &pp[lm_count], iter_i.blk)) continue; @@ -480,20 +477,19 @@ static int _dpu_rm_reserve_ctls( static int _dpu_rm_reserve_intf( struct dpu_rm *rm, uint32_t enc_id, - uint32_t id, - enum dpu_hw_blk_type type) + uint32_t id) { struct dpu_rm_hw_iter iter; int ret = 0; /* Find the block entry in the rm, and note the reservation */ - dpu_rm_init_hw_iter(&iter, 0, type); + dpu_rm_init_hw_iter(&iter, 0, DPU_HW_BLK_INTF); while (_dpu_rm_get_hw_locked(rm, &iter)) { if (iter.blk->id != id) continue; if (RESERVED_BY_OTHER(iter.blk, enc_id)) { - DPU_ERROR("type %d id %d already reserved\n", type, id); + DPU_ERROR("intf id %d already reserved\n", id); return -ENAVAIL; } @@ -504,7 +500,7 @@ static int _dpu_rm_reserve_intf( /* Shouldn't happen since intfs are fixed at probe */ if (!iter.hw) { - DPU_ERROR("couldn't find type %d id %d\n", type, id); + DPU_ERROR("couldn't find intf id %d\n", id); return -EINVAL; } @@ -523,8 +519,7 @@ static int _dpu_rm_reserve_intf_related_hw( if (hw_res->intfs[i] == INTF_MODE_NONE) continue; id = i + INTF_0; - ret = _dpu_rm_reserve_intf(rm, enc_id, id, - DPU_HW_BLK_INTF); + ret = _dpu_rm_reserve_intf(rm, enc_id, id); if (ret) return ret; } @@ -535,7 +530,6 @@ static int _dpu_rm_reserve_intf_related_hw( static int _dpu_rm_make_reservation( struct dpu_rm *rm, struct drm_encoder *enc, - struct drm_crtc_state *crtc_state, struct dpu_rm_requirements *reqs) { int ret; @@ -560,9 +554,7 @@ static int _dpu_rm_make_reservation( } static int _dpu_rm_populate_requirements( - struct dpu_rm *rm, struct drm_encoder *enc, - struct drm_crtc_state *crtc_state, struct dpu_rm_requirements *reqs, struct msm_display_topology req_topology) { @@ -621,14 +613,13 @@ int dpu_rm_reserve( mutex_lock(&rm->rm_lock); - ret = _dpu_rm_populate_requirements(rm, enc, crtc_state, &reqs, - topology); + ret = _dpu_rm_populate_requirements(enc, &reqs, topology); if (ret) { DPU_ERROR("failed to populate hw requirements\n"); goto end; } - ret = _dpu_rm_make_reservation(rm, enc, crtc_state, &reqs); + ret = _dpu_rm_make_reservation(rm, enc, &reqs); if (ret) { DPU_ERROR("failed to reserve hw resources: %d\n", ret); _dpu_rm_release_reservation(rm, enc->base.id); From patchwork Wed Feb 19 17:42:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Drew Davenport X-Patchwork-Id: 11392123 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4F4FF159A for ; Wed, 19 Feb 2020 17:43:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 145572467A for ; Wed, 19 Feb 2020 17:43:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="F/hABZcd" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726751AbgBSRnL (ORCPT ); Wed, 19 Feb 2020 12:43:11 -0500 Received: from mail-il1-f194.google.com ([209.85.166.194]:41300 "EHLO mail-il1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726593AbgBSRnL (ORCPT ); Wed, 19 Feb 2020 12:43:11 -0500 Received: by mail-il1-f194.google.com with SMTP id f10so21275826ils.8 for ; Wed, 19 Feb 2020 09:43:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=IzyYw7B/gnmIiB8zBgCiB2Gye+qMEp8YKV0TJCS5+hg=; b=F/hABZcd0qPX7fTkWV56QcOC9FPPjKmFYJxDk0XYJXUVCyTP6/V4MpaQ47ii0GRgjO 4S9GjZHqh4AeEzq3w47QIsiPwxG6azMNHn8sKHfwEWqQyhsnZBq0/Pk8bAZeLi5fitx8 c+8prxe6MwoCVnQLm0ekg7g4tEUMKOHQZauhc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=IzyYw7B/gnmIiB8zBgCiB2Gye+qMEp8YKV0TJCS5+hg=; b=FJJSqRG/3SQHpLWz/1UDK87qwEgqZhDJA/Gq+Fc8az20IhSeuj26dFB4yK/FDnP/bT rCROToFZocWtzWptBCvzAlEDltVYGNzwvkUS2lY4JtEMAHFAPmSp1IuwWiP/6IgsdCvg 7e6v1k2yiVINMr1LJo1yZzuHcxNeNzYrbkZ3FAODnoYigBu8gN3yyKLD4DLj2SXmrL3H 0nnKJ/Uo42Uxr9ydEAvDHqQFHxan3b9YBoA7/p/KycARat+XTPwCQRpIGh1Kx2G1UBbl hTbcP5dGOeBCAUs73XKVcos4TMYGxOTcen6T4s14iaMCPv130KBOUS7KceB3OKgxRyQV GqKw== X-Gm-Message-State: APjAAAVXQuyCJwsSfA7aVO0PtH0BJq5KIu2/sYK1d3Qddt4QQ8WvXaNw Ag+7Y9RbwghnZj/5dN3Xu5e9kw== X-Google-Smtp-Source: APXvYqzthAMDzr5smPDrx1dpnJ413pLiDkLKKDjmBc3Nbhrrt2gKclr4BD/f1dBzCWuuLp/uCACndQ== X-Received: by 2002:a05:6e02:8e2:: with SMTP id n2mr26249882ilt.167.1582134190104; Wed, 19 Feb 2020 09:43:10 -0800 (PST) Received: from ddavenport4.bld.corp.google.com ([2620:15c:183:0:92f:a80a:519d:f777]) by smtp.gmail.com with ESMTPSA id a21sm60355ioh.29.2020.02.19.09.43.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 19 Feb 2020 09:43:09 -0800 (PST) From: Drew Davenport To: dri-devel@lists.freedesktop.org Cc: Drew Davenport , Alexios Zavras , Allison Randal , Daniel Vetter , David Airlie , Fritz Koenig , Greg Kroah-Hartman , Jeykumar Sankaran , Kalyan Thota , Rob Clark , Sean Paul , Shubhashree Dhar , Stephen Boyd , Thomas Gleixner , freedreno@lists.freedesktop.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, zhengbin Subject: [PATCH 2/4] drm/msm/dpu: Refactor rm iterator Date: Wed, 19 Feb 2020 10:42:25 -0700 Message-Id: <20200219104148.2.I2c848e8f8ab1bcd4042d8ebcf35de737cceec5fe@changeid> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200219104148.1.I0183a464f2788d41e6902f3535941f69c594b4c1@changeid> References: <20200219104148.1.I0183a464f2788d41e6902f3535941f69c594b4c1@changeid> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Make iterator implementation private, and add function to query resources assigned to an encoder. Signed-off-by: Drew Davenport --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 59 ++++++++----------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h | 10 ++++ .../gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h | 10 ++++ drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 31 +++++++++- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 47 ++------------- 5 files changed, 76 insertions(+), 81 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index f8ac3bf60fd60..6cadeff456f09 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -957,11 +957,11 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, struct drm_connector *conn = NULL, *conn_iter; struct drm_crtc *drm_crtc; struct dpu_crtc_state *cstate; - struct dpu_rm_hw_iter hw_iter; struct msm_display_topology topology; - struct dpu_hw_ctl *hw_ctl[MAX_CHANNELS_PER_ENC] = { NULL }; - struct dpu_hw_mixer *hw_lm[MAX_CHANNELS_PER_ENC] = { NULL }; - int num_lm = 0, num_ctl = 0; + struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC]; + struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC]; + struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC]; + int num_lm, num_ctl, num_pp; int i, j, ret; if (!drm_enc) { @@ -1005,42 +1005,31 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, return; } - dpu_rm_init_hw_iter(&hw_iter, drm_enc->base.id, DPU_HW_BLK_PINGPONG); - for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { - dpu_enc->hw_pp[i] = NULL; - if (!dpu_rm_get_hw(&dpu_kms->rm, &hw_iter)) - break; - dpu_enc->hw_pp[i] = (struct dpu_hw_pingpong *) hw_iter.hw; - } - - dpu_rm_init_hw_iter(&hw_iter, drm_enc->base.id, DPU_HW_BLK_CTL); - for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { - if (!dpu_rm_get_hw(&dpu_kms->rm, &hw_iter)) - break; - hw_ctl[i] = (struct dpu_hw_ctl *)hw_iter.hw; - num_ctl++; - } + num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, drm_enc->base.id, + DPU_HW_BLK_PINGPONG, hw_pp, ARRAY_SIZE(hw_pp)); + num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, drm_enc->base.id, + DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl)); + num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, drm_enc->base.id, + DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm)); - dpu_rm_init_hw_iter(&hw_iter, drm_enc->base.id, DPU_HW_BLK_LM); - for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { - if (!dpu_rm_get_hw(&dpu_kms->rm, &hw_iter)) - break; - hw_lm[i] = (struct dpu_hw_mixer *)hw_iter.hw; - num_lm++; - } + for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) + dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i]) + : NULL; cstate = to_dpu_crtc_state(drm_crtc->state); for (i = 0; i < num_lm; i++) { int ctl_idx = (i < num_ctl) ? i : (num_ctl-1); - cstate->mixers[i].hw_lm = hw_lm[i]; - cstate->mixers[i].lm_ctl = hw_ctl[ctl_idx]; + cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]); + cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]); } cstate->num_mixers = num_lm; for (i = 0; i < dpu_enc->num_phys_encs; i++) { + int num_blk; + struct dpu_hw_blk *hw_blk[MAX_CHANNELS_PER_ENC]; struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; if (!dpu_enc->hw_pp[i]) { @@ -1056,17 +1045,15 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, } phys->hw_pp = dpu_enc->hw_pp[i]; - phys->hw_ctl = hw_ctl[i]; + phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]); - dpu_rm_init_hw_iter(&hw_iter, drm_enc->base.id, - DPU_HW_BLK_INTF); - for (j = 0; j < MAX_CHANNELS_PER_ENC; j++) { + num_blk = dpu_rm_get_assigned_resources(&dpu_kms->rm, + drm_enc->base.id, DPU_HW_BLK_INTF, hw_blk, + ARRAY_SIZE(hw_blk)); + for (j = 0; j < num_blk; j++) { struct dpu_hw_intf *hw_intf; - if (!dpu_rm_get_hw(&dpu_kms->rm, &hw_iter)) - break; - - hw_intf = (struct dpu_hw_intf *)hw_iter.hw; + hw_intf = to_dpu_hw_intf(hw_blk[i]); if (hw_intf->idx == phys->intf_idx) phys->hw_intf = hw_intf; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h index 85468981632de..0ead64d3f63d9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h @@ -89,6 +89,16 @@ struct dpu_hw_intf { struct dpu_hw_intf_ops ops; }; +/** + * to_dpu_hw_intf - convert base object dpu_hw_base to container + * @hw: Pointer to base hardware block + * return: Pointer to hardware block container + */ +static inline struct dpu_hw_intf *to_dpu_hw_intf(struct dpu_hw_blk *hw) +{ + return container_of(hw, struct dpu_hw_intf, base); +} + /** * dpu_hw_intf_init(): Initializes the intf driver for the passed * interface idx. diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h index 3d6f46b1db308..d73cb73e938b6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h @@ -96,6 +96,16 @@ struct dpu_hw_pingpong { struct dpu_hw_pingpong_ops ops; }; +/** + * to_dpu_hw_pingpong - convert base object dpu_hw_base to container + * @hw: Pointer to base hardware block + * return: Pointer to hardware block container + */ +static inline struct dpu_hw_pingpong *to_dpu_hw_pingpong(struct dpu_hw_blk *hw) +{ + return container_of(hw, struct dpu_hw_pingpong, base); +} + /** * dpu_hw_pingpong_init - initializes the pingpong driver for the passed * pingpong idx. diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index dea1dba441fe7..779df26dc81ae 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -40,7 +40,21 @@ struct dpu_rm_hw_blk { struct dpu_hw_blk *hw; }; -void dpu_rm_init_hw_iter( +/** + * struct dpu_rm_hw_iter - iterator for use with dpu_rm + * @hw: dpu_hw object requested, or NULL on failure + * @blk: dpu_rm internal block representation. Clients ignore. Used as iterator. + * @enc_id: DRM ID of Encoder client wishes to search for, or 0 for Any Encoder + * @type: Hardware Block Type client wishes to search for. + */ +struct dpu_rm_hw_iter { + void *hw; + struct dpu_rm_hw_blk *blk; + uint32_t enc_id; + enum dpu_hw_blk_type type; +}; + +static void dpu_rm_init_hw_iter( struct dpu_rm_hw_iter *iter, uint32_t enc_id, enum dpu_hw_blk_type type) @@ -83,7 +97,7 @@ static bool _dpu_rm_get_hw_locked(struct dpu_rm *rm, struct dpu_rm_hw_iter *i) return false; } -bool dpu_rm_get_hw(struct dpu_rm *rm, struct dpu_rm_hw_iter *i) +static bool dpu_rm_get_hw(struct dpu_rm *rm, struct dpu_rm_hw_iter *i) { bool ret; @@ -635,3 +649,16 @@ int dpu_rm_reserve( return ret; } + +int dpu_rm_get_assigned_resources(struct dpu_rm *rm, uint32_t enc_id, + enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size) +{ + struct dpu_rm_hw_iter hw_iter; + int num_blks = 0; + + dpu_rm_init_hw_iter(&hw_iter, enc_id, type); + while (num_blks < blks_size && dpu_rm_get_hw(rm, &hw_iter)) + blks[num_blks++] = hw_iter.blk->hw; + + return num_blks; +} diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h index 9c580a0170946..982b91e272275 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h @@ -24,26 +24,6 @@ struct dpu_rm { struct mutex rm_lock; }; -/** - * struct dpu_rm_hw_blk - resource manager internal structure - * forward declaration for single iterator definition without void pointer - */ -struct dpu_rm_hw_blk; - -/** - * struct dpu_rm_hw_iter - iterator for use with dpu_rm - * @hw: dpu_hw object requested, or NULL on failure - * @blk: dpu_rm internal block representation. Clients ignore. Used as iterator. - * @enc_id: DRM ID of Encoder client wishes to search for, or 0 for Any Encoder - * @type: Hardware Block Type client wishes to search for. - */ -struct dpu_rm_hw_iter { - void *hw; - struct dpu_rm_hw_blk *blk; - uint32_t enc_id; - enum dpu_hw_blk_type type; -}; - /** * dpu_rm_init - Read hardware catalog and create reservation tracking objects * for all HW blocks. @@ -93,28 +73,9 @@ int dpu_rm_reserve(struct dpu_rm *rm, void dpu_rm_release(struct dpu_rm *rm, struct drm_encoder *enc); /** - * dpu_rm_init_hw_iter - setup given iterator for new iteration over hw list - * using dpu_rm_get_hw - * @iter: iter object to initialize - * @enc_id: DRM ID of Encoder client wishes to search for, or 0 for Any Encoder - * @type: Hardware Block Type client wishes to search for. + * Get hw resources of the given type that are assigned to this encoder. */ -void dpu_rm_init_hw_iter( - struct dpu_rm_hw_iter *iter, - uint32_t enc_id, - enum dpu_hw_blk_type type); -/** - * dpu_rm_get_hw - retrieve reserved hw object given encoder and hw type - * Meant to do a single pass through the hardware list to iteratively - * retrieve hardware blocks of a given type for a given encoder. - * Initialize an iterator object. - * Set hw block type of interest. Set encoder id of interest, 0 for any. - * Function returns first hw of type for that encoder. - * Subsequent calls will return the next reserved hw of that type in-order. - * Iterator HW pointer will be null on failure to find hw. - * @rm: DPU Resource Manager handle - * @iter: iterator object - * @Return: true on match found, false on no match found - */ -bool dpu_rm_get_hw(struct dpu_rm *rm, struct dpu_rm_hw_iter *iter); +int dpu_rm_get_assigned_resources(struct dpu_rm *rm, uint32_t enc_id, + enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size); #endif /* __DPU_RM_H__ */ + From patchwork Wed Feb 19 17:42:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Drew Davenport X-Patchwork-Id: 11392131 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4EF9A17F0 for ; Wed, 19 Feb 2020 17:43:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 194B32467B for ; Wed, 19 Feb 2020 17:43:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="I4J/FtPk" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726681AbgBSRnR (ORCPT ); Wed, 19 Feb 2020 12:43:17 -0500 Received: from mail-io1-f65.google.com ([209.85.166.65]:40367 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726760AbgBSRnN (ORCPT ); Wed, 19 Feb 2020 12:43:13 -0500 Received: by mail-io1-f65.google.com with SMTP id x1so1490264iop.7 for ; Wed, 19 Feb 2020 09:43:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=0+mwmVZpHHv6ErN+IN9HcD1iU1ojAAuKQ5EpxfPcQ/U=; b=I4J/FtPkKoK7vOTjtT7HNr7ZH71J0LZ5Nmi8aBpoDBqn45pteWndjHxbHRF2CIMAz1 Peljw+2hFXe1xNa/mp+11bQ4O3HWTb7VT7usaCQdxNZgYoow1k/DYUUpy6sfV9UqoxQz jOgLkx+tse5+8p3B+OXw9oZTlZdsmwH0r7VsU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=0+mwmVZpHHv6ErN+IN9HcD1iU1ojAAuKQ5EpxfPcQ/U=; b=Sdog7sf3lDuSaYjjJ14ldW6/KDfpNVKUIkyQcb3ziNqwu77c9QIXAm2zM6ROVaV+uF j5dQjNEfdYKuyaA6kNf2dDo8PJ+mAQKtVLoIoxKuhhJcRL6hOtvRIGhtGWb6CzwrUjvC GDNY0ZkYY8g+Pl1aByou/hiTYEUAhCFORVUI1aQ4pfIgIYq88U/eSF6TTso/W8dCvbN2 K9VLaJLxvko/zmlW31qhpY3bTjy6F3LA2BPfhdy8kY1E+dQo3zCL5IUGW/mdKmyp664v dG57xHjcSWI9IgJZqme/ZhGFc1cvtS2lZU+N62H3UIuKumcKI9HlYhehLI1s8ENM6xzh 2Ndw== X-Gm-Message-State: APjAAAXS7Xk0+7tOLcuW9APY9CZLB1BowWRXjaxAjD1KF8s/q9bYg2yS EUQmerX/Q7lHlKpHpAOPV6cM8w== X-Google-Smtp-Source: APXvYqwZjuFkNHgIcXl5KmZUb7DNcdAn9d4AOzRZ5ZoIRX8aF76C2pqlyJOWGW4icoMw2OX4oVtDJg== X-Received: by 2002:a6b:fc02:: with SMTP id r2mr19698205ioh.183.1582134191326; Wed, 19 Feb 2020 09:43:11 -0800 (PST) Received: from ddavenport4.bld.corp.google.com ([2620:15c:183:0:92f:a80a:519d:f777]) by smtp.gmail.com with ESMTPSA id a21sm60355ioh.29.2020.02.19.09.43.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 19 Feb 2020 09:43:10 -0800 (PST) From: Drew Davenport To: dri-devel@lists.freedesktop.org Cc: Drew Davenport , Alexios Zavras , Allison Randal , Daniel Vetter , David Airlie , Greg Kroah-Hartman , Rob Clark , Sean Paul , Stephen Boyd , Thomas Gleixner , freedreno@lists.freedesktop.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 3/4] drm/msm/dpu: Refactor resource manager Date: Wed, 19 Feb 2020 10:42:26 -0700 Message-Id: <20200219104148.3.I8c1f8bbe0cb01e69b5ee66ccf3aa1ee0c9c32bef@changeid> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200219104148.1.I0183a464f2788d41e6902f3535941f69c594b4c1@changeid> References: <20200219104148.1.I0183a464f2788d41e6902f3535941f69c594b4c1@changeid> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Track hardware resource objects in arrays rather than a list and remove the resource manager's iterator idiom. Separate the mapping of hardware resources to an encoder ID into a different array. Use an implicit mapping between the hardware blocks' ids, which are 1-based, and array indices in these arrays to replace iteration with index lookups in several places. Signed-off-by: Drew Davenport --- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 553 +++++++++++-------------- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 22 +- 2 files changed, 255 insertions(+), 320 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index 779df26dc81ae..f1483b00b7423 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -12,8 +12,12 @@ #include "dpu_encoder.h" #include "dpu_trace.h" -#define RESERVED_BY_OTHER(h, r) \ - ((h)->enc_id && (h)->enc_id != r) + +static inline bool reserved_by_other(uint32_t *res_map, int idx, + uint32_t enc_id) +{ + return res_map[idx] && res_map[idx] != enc_id; +} /** * struct dpu_rm_requirements - Reservation requirements parameter bundle @@ -25,126 +29,40 @@ struct dpu_rm_requirements { struct dpu_encoder_hw_resources hw_res; }; - -/** - * struct dpu_rm_hw_blk - hardware block tracking list member - * @list: List head for list of all hardware blocks tracking items - * @id: Hardware ID number, within it's own space, ie. LM_X - * @enc_id: Encoder id to which this blk is binded - * @hw: Pointer to the hardware register access object for this block - */ -struct dpu_rm_hw_blk { - struct list_head list; - uint32_t id; - uint32_t enc_id; - struct dpu_hw_blk *hw; -}; - -/** - * struct dpu_rm_hw_iter - iterator for use with dpu_rm - * @hw: dpu_hw object requested, or NULL on failure - * @blk: dpu_rm internal block representation. Clients ignore. Used as iterator. - * @enc_id: DRM ID of Encoder client wishes to search for, or 0 for Any Encoder - * @type: Hardware Block Type client wishes to search for. - */ -struct dpu_rm_hw_iter { - void *hw; - struct dpu_rm_hw_blk *blk; - uint32_t enc_id; - enum dpu_hw_blk_type type; -}; - -static void dpu_rm_init_hw_iter( - struct dpu_rm_hw_iter *iter, - uint32_t enc_id, - enum dpu_hw_blk_type type) -{ - memset(iter, 0, sizeof(*iter)); - iter->enc_id = enc_id; - iter->type = type; -} - -static bool _dpu_rm_get_hw_locked(struct dpu_rm *rm, struct dpu_rm_hw_iter *i) +int dpu_rm_destroy(struct dpu_rm *rm) { - struct list_head *blk_list; + int i; - if (!rm || !i || i->type >= DPU_HW_BLK_MAX) { - DPU_ERROR("invalid rm\n"); - return false; - } + for (i = 0; i < ARRAY_SIZE(rm->pingpong_blks); i++) { + struct dpu_hw_pingpong *hw; - i->hw = NULL; - blk_list = &rm->hw_blks[i->type]; - - if (i->blk && (&i->blk->list == blk_list)) { - DPU_DEBUG("attempt resume iteration past last\n"); - return false; + if (rm->pingpong_blks[i]) { + hw = to_dpu_hw_pingpong(rm->pingpong_blks[i]); + dpu_hw_pingpong_destroy(hw); + } } + for (i = 0; i < ARRAY_SIZE(rm->mixer_blks); i++) { + struct dpu_hw_mixer *hw; - i->blk = list_prepare_entry(i->blk, blk_list, list); - - list_for_each_entry_continue(i->blk, blk_list, list) { - if (i->enc_id == i->blk->enc_id) { - i->hw = i->blk->hw; - DPU_DEBUG("found type %d id %d for enc %d\n", - i->type, i->blk->id, i->enc_id); - return true; + if (rm->mixer_blks[i]) { + hw = to_dpu_hw_mixer(rm->mixer_blks[i]); + dpu_hw_lm_destroy(hw); } } + for (i = 0; i < ARRAY_SIZE(rm->ctl_blks); i++) { + struct dpu_hw_ctl *hw; - DPU_DEBUG("no match, type %d for enc %d\n", i->type, i->enc_id); - - return false; -} - -static bool dpu_rm_get_hw(struct dpu_rm *rm, struct dpu_rm_hw_iter *i) -{ - bool ret; - - mutex_lock(&rm->rm_lock); - ret = _dpu_rm_get_hw_locked(rm, i); - mutex_unlock(&rm->rm_lock); - - return ret; -} - -static void _dpu_rm_hw_destroy(enum dpu_hw_blk_type type, void *hw) -{ - switch (type) { - case DPU_HW_BLK_LM: - dpu_hw_lm_destroy(hw); - break; - case DPU_HW_BLK_CTL: - dpu_hw_ctl_destroy(hw); - break; - case DPU_HW_BLK_PINGPONG: - dpu_hw_pingpong_destroy(hw); - break; - case DPU_HW_BLK_INTF: - dpu_hw_intf_destroy(hw); - break; - case DPU_HW_BLK_SSPP: - /* SSPPs are not managed by the resource manager */ - case DPU_HW_BLK_TOP: - /* Top is a singleton, not managed in hw_blks list */ - case DPU_HW_BLK_MAX: - default: - DPU_ERROR("unsupported block type %d\n", type); - break; + if (rm->ctl_blks[i]) { + hw = to_dpu_hw_ctl(rm->ctl_blks[i]); + dpu_hw_ctl_destroy(hw); + } } -} + for (i = 0; i < ARRAY_SIZE(rm->intf_blks); i++) { + struct dpu_hw_intf *hw; -int dpu_rm_destroy(struct dpu_rm *rm) -{ - struct dpu_rm_hw_blk *hw_cur, *hw_nxt; - enum dpu_hw_blk_type type; - - for (type = 0; type < DPU_HW_BLK_MAX; type++) { - list_for_each_entry_safe(hw_cur, hw_nxt, &rm->hw_blks[type], - list) { - list_del(&hw_cur->list); - _dpu_rm_hw_destroy(type, hw_cur->hw); - kfree(hw_cur); + if (rm->intf_blks[i]) { + hw = to_dpu_hw_intf(rm->intf_blks[i]); + dpu_hw_intf_destroy(hw); } } @@ -153,65 +71,11 @@ int dpu_rm_destroy(struct dpu_rm *rm) return 0; } -static int _dpu_rm_hw_blk_create( - struct dpu_rm *rm, - const struct dpu_mdss_cfg *cat, - void __iomem *mmio, - enum dpu_hw_blk_type type, - uint32_t id) -{ - struct dpu_rm_hw_blk *blk; - void *hw; - - switch (type) { - case DPU_HW_BLK_LM: - hw = dpu_hw_lm_init(id, mmio, cat); - break; - case DPU_HW_BLK_CTL: - hw = dpu_hw_ctl_init(id, mmio, cat); - break; - case DPU_HW_BLK_PINGPONG: - hw = dpu_hw_pingpong_init(id, mmio, cat); - break; - case DPU_HW_BLK_INTF: - hw = dpu_hw_intf_init(id, mmio, cat); - break; - case DPU_HW_BLK_SSPP: - /* SSPPs are not managed by the resource manager */ - case DPU_HW_BLK_TOP: - /* Top is a singleton, not managed in hw_blks list */ - case DPU_HW_BLK_MAX: - default: - DPU_ERROR("unsupported block type %d\n", type); - return -EINVAL; - } - - if (IS_ERR_OR_NULL(hw)) { - DPU_ERROR("failed hw object creation: type %d, err %ld\n", - type, PTR_ERR(hw)); - return -EFAULT; - } - - blk = kzalloc(sizeof(*blk), GFP_KERNEL); - if (!blk) { - _dpu_rm_hw_destroy(type, hw); - return -ENOMEM; - } - - blk->id = id; - blk->hw = hw; - blk->enc_id = 0; - list_add_tail(&blk->list, &rm->hw_blks[type]); - - return 0; -} - int dpu_rm_init(struct dpu_rm *rm, struct dpu_mdss_cfg *cat, void __iomem *mmio) { int rc, i; - enum dpu_hw_blk_type type; if (!rm || !cat || !mmio) { DPU_ERROR("invalid kms\n"); @@ -223,11 +87,9 @@ int dpu_rm_init(struct dpu_rm *rm, mutex_init(&rm->rm_lock); - for (type = 0; type < DPU_HW_BLK_MAX; type++) - INIT_LIST_HEAD(&rm->hw_blks[type]); - /* Interrogate HW catalog and create tracking items for hw blocks */ for (i = 0; i < cat->mixer_count; i++) { + struct dpu_hw_mixer *hw; const struct dpu_lm_cfg *lm = &cat->mixer[i]; if (lm->pingpong == PINGPONG_MAX) { @@ -235,12 +97,17 @@ int dpu_rm_init(struct dpu_rm *rm, continue; } - rc = _dpu_rm_hw_blk_create(rm, cat, mmio, DPU_HW_BLK_LM, - cat->mixer[i].id); - if (rc) { - DPU_ERROR("failed: lm hw not available\n"); + if (lm->id < LM_0 || lm->id >= LM_MAX) { + DPU_ERROR("skip mixer %d with invalid id\n", lm->id); + continue; + } + hw = dpu_hw_lm_init(lm->id, mmio, cat); + if (IS_ERR_OR_NULL(hw)) { + rc = PTR_ERR(hw); + DPU_ERROR("failed lm object creation: err %ld\n", rc); goto fail; } + rm->mixer_blks[lm->id - LM_0] = &hw->base; if (!rm->lm_max_width) { rm->lm_max_width = lm->sblk->maxwidth; @@ -256,35 +123,59 @@ int dpu_rm_init(struct dpu_rm *rm, } for (i = 0; i < cat->pingpong_count; i++) { - rc = _dpu_rm_hw_blk_create(rm, cat, mmio, DPU_HW_BLK_PINGPONG, - cat->pingpong[i].id); - if (rc) { - DPU_ERROR("failed: pp hw not available\n"); + struct dpu_hw_pingpong *hw; + const struct dpu_pingpong_cfg *pp = &cat->pingpong[i]; + + if (pp->id < PINGPONG_0 || pp->id >= PINGPONG_MAX) { + DPU_ERROR("skip pingpong %d with invalid id\n", pp->id); + continue; + } + hw = dpu_hw_pingpong_init(pp->id, mmio, cat); + if (IS_ERR_OR_NULL(hw)) { + rc = PTR_ERR(hw); + DPU_ERROR("failed pingpong object creation: err %ld\n", + rc); goto fail; } + rm->pingpong_blks[pp->id - PINGPONG_0] = &hw->base; } for (i = 0; i < cat->intf_count; i++) { - if (cat->intf[i].type == INTF_NONE) { + struct dpu_hw_intf *hw; + const struct dpu_intf_cfg *intf = &cat->intf[i]; + + if (intf->type == INTF_NONE) { DPU_DEBUG("skip intf %d with type none\n", i); continue; } - - rc = _dpu_rm_hw_blk_create(rm, cat, mmio, DPU_HW_BLK_INTF, - cat->intf[i].id); - if (rc) { - DPU_ERROR("failed: intf hw not available\n"); + if (intf->id < INTF_0 || intf->id >= INTF_MAX) { + DPU_ERROR("skip intf %d with invalid id\n", intf->id); + continue; + } + hw = dpu_hw_intf_init(intf->id, mmio, cat); + if (IS_ERR_OR_NULL(hw)) { + rc = PTR_ERR(hw); + DPU_ERROR("failed intf object creation: err %ld\n", rc); goto fail; } + rm->intf_blks[intf->id - INTF_0] = &hw->base; } for (i = 0; i < cat->ctl_count; i++) { - rc = _dpu_rm_hw_blk_create(rm, cat, mmio, DPU_HW_BLK_CTL, - cat->ctl[i].id); - if (rc) { - DPU_ERROR("failed: ctl hw not available\n"); + struct dpu_hw_ctl *hw; + const struct dpu_ctl_cfg *ctl = &cat->ctl[i]; + + if (ctl->id < CTL_0 || ctl->id >= CTL_MAX) { + DPU_ERROR("skip ctl %d with invalid id\n", ctl->id); + continue; + } + hw = dpu_hw_ctl_init(ctl->id, mmio, cat); + if (IS_ERR_OR_NULL(hw)) { + rc = PTR_ERR(hw); + DPU_ERROR("failed ctl object creation: err %ld\n", rc); goto fail; } + rm->ctl_blks[ctl->id - CTL_0] = &hw->base; } return 0; @@ -292,7 +183,7 @@ int dpu_rm_init(struct dpu_rm *rm, fail: dpu_rm_destroy(rm); - return rc; + return rc ? rc : -EFAULT; } static bool _dpu_rm_needs_split_display(const struct msm_display_topology *top) @@ -300,72 +191,69 @@ static bool _dpu_rm_needs_split_display(const struct msm_display_topology *top) return top->num_intf > 1; } +/** + * _dpu_rm_check_lm_peer - check if a mixer is a peer of the primary + * @rm: dpu resource manager handle + * @primary_idx: index of primary mixer in rm->mixer_blks[] + * @peer_idx: index of other mixer in rm->mixer_blks[] + * @Return: true if rm->mixer_blks[peer_idx] is a peer of + * rm->mixer_blks[primary_idx] + */ +static bool _dpu_rm_check_lm_peer(struct dpu_rm *rm, int primary_idx, + int peer_idx) +{ + const struct dpu_lm_cfg *prim_lm_cfg; + const struct dpu_lm_cfg *peer_cfg; + + prim_lm_cfg = to_dpu_hw_mixer(rm->mixer_blks[primary_idx])->cap; + peer_cfg = to_dpu_hw_mixer(rm->mixer_blks[peer_idx])->cap; + + if (!test_bit(peer_cfg->id, &prim_lm_cfg->lm_pair_mask)) { + DPU_DEBUG("lm %d not peer of lm %d\n", peer_cfg->id, + peer_cfg->id); + return false; + } + return true; +} + /** * _dpu_rm_check_lm_and_get_connected_blks - check if proposed layer mixer meets * proposed use case requirements, incl. hardwired dependent blocks like * pingpong * @rm: dpu resource manager handle * @enc_id: encoder id requesting for allocation - * @lm: proposed layer mixer, function checks if lm, and all other hardwired - * blocks connected to the lm (pp) is available and appropriate - * @pp: output parameter, pingpong block attached to the layer mixer. - * NULL if pp was not available, or not matching requirements. - * @primary_lm: if non-null, this function check if lm is compatible primary_lm - * as well as satisfying all other requirements + * @lm_idx: index of proposed layer mixer in rm->mixer_blks[], function checks + * if lm, and all other hardwired blocks connected to the lm (pp) is + * available and appropriate + * @pp_idx: output parameter, index of pingpong block attached to the layer + * mixer in rm->pongpong_blks[]. * @Return: true if lm matches all requirements, false otherwise */ -static bool _dpu_rm_check_lm_and_get_connected_blks( - struct dpu_rm *rm, - uint32_t enc_id, - struct dpu_rm_hw_blk *lm, - struct dpu_rm_hw_blk **pp, - struct dpu_rm_hw_blk *primary_lm) +static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm, + uint32_t enc_id, int lm_idx, int *pp_idx) { - const struct dpu_lm_cfg *lm_cfg = to_dpu_hw_mixer(lm->hw)->cap; - struct dpu_rm_hw_iter iter; - - *pp = NULL; - - DPU_DEBUG("check lm %d pp %d\n", - lm_cfg->id, lm_cfg->pingpong); - - /* Check if this layer mixer is a peer of the proposed primary LM */ - if (primary_lm) { - const struct dpu_lm_cfg *prim_lm_cfg = - to_dpu_hw_mixer(primary_lm->hw)->cap; - - if (!test_bit(lm_cfg->id, &prim_lm_cfg->lm_pair_mask)) { - DPU_DEBUG("lm %d not peer of lm %d\n", lm_cfg->id, - prim_lm_cfg->id); - return false; - } - } + const struct dpu_lm_cfg *lm_cfg; + int idx; /* Already reserved? */ - if (RESERVED_BY_OTHER(lm, enc_id)) { - DPU_DEBUG("lm %d already reserved\n", lm_cfg->id); + if (reserved_by_other(rm->mixer_to_enc_id, lm_idx, enc_id)) { + DPU_DEBUG("lm %d already reserved\n", lm_idx + LM_0); return false; } - dpu_rm_init_hw_iter(&iter, 0, DPU_HW_BLK_PINGPONG); - while (_dpu_rm_get_hw_locked(rm, &iter)) { - if (iter.blk->id == lm_cfg->pingpong) { - *pp = iter.blk; - break; - } - } - - if (!*pp) { + lm_cfg = to_dpu_hw_mixer(rm->mixer_blks[lm_idx])->cap; + idx = lm_cfg->pingpong - PINGPONG_0; + if (idx < 0 || idx >= ARRAY_SIZE(rm->pingpong_blks)) { DPU_ERROR("failed to get pp on lm %d\n", lm_cfg->pingpong); return false; } - if (RESERVED_BY_OTHER(*pp, enc_id)) { - DPU_DEBUG("lm %d pp %d already reserved\n", lm->id, - (*pp)->id); + if (reserved_by_other(rm->pingpong_to_enc_id, idx, enc_id)) { + DPU_DEBUG("lm %d pp %d already reserved\n", lm_cfg->id, + lm_cfg->pingpong); return false; } - + *pp_idx = idx; return true; } @@ -373,11 +261,9 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, uint32_t enc_id, struct dpu_rm_requirements *reqs) { - struct dpu_rm_hw_blk *lm[MAX_BLOCKS]; - struct dpu_rm_hw_blk *pp[MAX_BLOCKS]; - struct dpu_rm_hw_iter iter_i, iter_j; - int lm_count = 0; - int i, rc = 0; + int lm_idx[MAX_BLOCKS]; + int pp_idx[MAX_BLOCKS]; + int i, j, lm_count = 0; if (!reqs->topology.num_lm) { DPU_ERROR("invalid number of lm: %d\n", reqs->topology.num_lm); @@ -385,36 +271,39 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, uint32_t enc_id, } /* Find a primary mixer */ - dpu_rm_init_hw_iter(&iter_i, 0, DPU_HW_BLK_LM); - while (lm_count != reqs->topology.num_lm && - _dpu_rm_get_hw_locked(rm, &iter_i)) { - memset(&lm, 0, sizeof(lm)); - memset(&pp, 0, sizeof(pp)); + for (i = 0; i < ARRAY_SIZE(rm->mixer_blks) && + lm_count < reqs->topology.num_lm; i++) { + if (!rm->mixer_blks[i]) + continue; lm_count = 0; - lm[lm_count] = iter_i.blk; + lm_idx[lm_count] = i; if (!_dpu_rm_check_lm_and_get_connected_blks( - rm, enc_id, lm[lm_count], - &pp[lm_count], NULL)) + rm, enc_id, i, &pp_idx[lm_count])) { continue; + } ++lm_count; /* Valid primary mixer found, find matching peers */ - dpu_rm_init_hw_iter(&iter_j, 0, DPU_HW_BLK_LM); + for (j = i + 1; j < ARRAY_SIZE(rm->mixer_blks) && + lm_count < reqs->topology.num_lm; j++) { + if (!rm->mixer_blks[j]) + continue; - while (lm_count != reqs->topology.num_lm && - _dpu_rm_get_hw_locked(rm, &iter_j)) { - if (iter_i.blk == iter_j.blk) + if (!_dpu_rm_check_lm_peer(rm, i, j)) { + DPU_DEBUG("lm %d not peer of lm %d\n", LM_0 + j, + LM_0 + i); continue; + } if (!_dpu_rm_check_lm_and_get_connected_blks( - rm, enc_id, iter_j.blk, - &pp[lm_count], iter_i.blk)) + rm, enc_id, j, &pp_idx[lm_count])) { continue; + } - lm[lm_count] = iter_j.blk; + lm_idx[lm_count] = j; ++lm_count; } } @@ -424,17 +313,15 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, uint32_t enc_id, return -ENAVAIL; } - for (i = 0; i < ARRAY_SIZE(lm); i++) { - if (!lm[i]) - break; - - lm[i]->enc_id = enc_id; - pp[i]->enc_id = enc_id; + for (i = 0; i < lm_count; i++) { + rm->mixer_to_enc_id[lm_idx[i]] = enc_id; + rm->pingpong_to_enc_id[pp_idx[i]] = enc_id; - trace_dpu_rm_reserve_lms(lm[i]->id, enc_id, pp[i]->id); + trace_dpu_rm_reserve_lms(lm_idx[i] + LM_0, enc_id, + pp_idx[i] + PINGPONG_0); } - return rc; + return 0; } static int _dpu_rm_reserve_ctls( @@ -442,47 +329,48 @@ static int _dpu_rm_reserve_ctls( uint32_t enc_id, const struct msm_display_topology *top) { - struct dpu_rm_hw_blk *ctls[MAX_BLOCKS]; - struct dpu_rm_hw_iter iter; - int i = 0, num_ctls = 0; - bool needs_split_display = false; - - memset(&ctls, 0, sizeof(ctls)); + int ctl_idx[MAX_BLOCKS]; + int i = 0, j, num_ctls; + bool needs_split_display; /* each hw_intf needs its own hw_ctrl to program its control path */ num_ctls = top->num_intf; needs_split_display = _dpu_rm_needs_split_display(top); - dpu_rm_init_hw_iter(&iter, 0, DPU_HW_BLK_CTL); - while (_dpu_rm_get_hw_locked(rm, &iter)) { - const struct dpu_hw_ctl *ctl = to_dpu_hw_ctl(iter.blk->hw); - unsigned long features = ctl->caps->features; + for (j = 0; j < ARRAY_SIZE(rm->ctl_blks); j++) { + const struct dpu_hw_ctl *ctl; + unsigned long features; bool has_split_display; - if (RESERVED_BY_OTHER(iter.blk, enc_id)) + if (!rm->ctl_blks[j]) + continue; + if (reserved_by_other(rm->ctl_to_enc_id, j, enc_id)) continue; + ctl = to_dpu_hw_ctl(rm->ctl_blks[j]); + features = ctl->caps->features; has_split_display = BIT(DPU_CTL_SPLIT_DISPLAY) & features; - DPU_DEBUG("ctl %d caps 0x%lX\n", iter.blk->id, features); + DPU_DEBUG("ctl %d caps 0x%lX\n", rm->ctl_blks[j]->id, features); if (needs_split_display != has_split_display) continue; - ctls[i] = iter.blk; - DPU_DEBUG("ctl %d match\n", iter.blk->id); + ctl_idx[i] = j; + DPU_DEBUG("ctl %d match\n", j + CTL_0); if (++i == num_ctls) break; + } if (i != num_ctls) return -ENAVAIL; - for (i = 0; i < ARRAY_SIZE(ctls) && i < num_ctls; i++) { - ctls[i]->enc_id = enc_id; - trace_dpu_rm_reserve_ctls(ctls[i]->id, enc_id); + for (i = 0; i < ARRAY_SIZE(ctl_idx) && i < num_ctls; i++) { + rm->ctl_to_enc_id[ctl_idx[i]] = enc_id; + trace_dpu_rm_reserve_ctls(i + CTL_0, enc_id); } return 0; @@ -493,32 +381,20 @@ static int _dpu_rm_reserve_intf( uint32_t enc_id, uint32_t id) { - struct dpu_rm_hw_iter iter; - int ret = 0; - - /* Find the block entry in the rm, and note the reservation */ - dpu_rm_init_hw_iter(&iter, 0, DPU_HW_BLK_INTF); - while (_dpu_rm_get_hw_locked(rm, &iter)) { - if (iter.blk->id != id) - continue; - - if (RESERVED_BY_OTHER(iter.blk, enc_id)) { - DPU_ERROR("intf id %d already reserved\n", id); - return -ENAVAIL; - } + int idx = id - INTF_0; - iter.blk->enc_id = enc_id; - trace_dpu_rm_reserve_intf(iter.blk->id, enc_id); - break; - } - - /* Shouldn't happen since intfs are fixed at probe */ - if (!iter.hw) { + if (!rm->intf_blks[idx]) { DPU_ERROR("couldn't find intf id %d\n", id); return -EINVAL; } - return ret; + if (reserved_by_other(rm->intf_to_enc_id, idx, enc_id)) { + DPU_ERROR("intf id %d already reserved\n", id); + return -ENAVAIL; + } + + rm->intf_to_enc_id[idx] = enc_id; + return 0; } static int _dpu_rm_reserve_intf_related_hw( @@ -583,22 +459,29 @@ static int _dpu_rm_populate_requirements( return 0; } -static void _dpu_rm_release_reservation(struct dpu_rm *rm, uint32_t enc_id) +static void _dpu_rm_clear_mapping(uint32_t *res_mapping, int cnt, + uint32_t enc_id) { - struct dpu_rm_hw_blk *blk; - enum dpu_hw_blk_type type; - - for (type = 0; type < DPU_HW_BLK_MAX; type++) { - list_for_each_entry(blk, &rm->hw_blks[type], list) { - if (blk->enc_id == enc_id) { - blk->enc_id = 0; - DPU_DEBUG("rel enc %d %d %d\n", enc_id, - type, blk->id); - } - } + int i; + + for (i = 0; i < cnt; i++) { + if (res_mapping[i] == enc_id) + res_mapping[i] = 0; } } +static void _dpu_rm_release_reservation(struct dpu_rm *rm, uint32_t enc_id) +{ + _dpu_rm_clear_mapping(rm->pingpong_to_enc_id, + ARRAY_SIZE(rm->pingpong_to_enc_id), enc_id); + _dpu_rm_clear_mapping(rm->mixer_to_enc_id, + ARRAY_SIZE(rm->mixer_to_enc_id), enc_id); + _dpu_rm_clear_mapping(rm->ctl_to_enc_id, + ARRAY_SIZE(rm->ctl_to_enc_id), enc_id); + _dpu_rm_clear_mapping(rm->intf_to_enc_id, + ARRAY_SIZE(rm->intf_to_enc_id), enc_id); +} + void dpu_rm_release(struct dpu_rm *rm, struct drm_encoder *enc) { mutex_lock(&rm->rm_lock); @@ -653,12 +536,48 @@ int dpu_rm_reserve( int dpu_rm_get_assigned_resources(struct dpu_rm *rm, uint32_t enc_id, enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size) { - struct dpu_rm_hw_iter hw_iter; - int num_blks = 0; + struct dpu_hw_blk **hw_blks; + uint32_t *hw_to_enc_id; + int i, num_blks, max_blks; + + switch (type) { + case DPU_HW_BLK_PINGPONG: + hw_blks = rm->pingpong_blks; + hw_to_enc_id = rm->pingpong_to_enc_id; + max_blks = ARRAY_SIZE(rm->pingpong_blks); + break; + case DPU_HW_BLK_LM: + hw_blks = rm->mixer_blks; + hw_to_enc_id = rm->mixer_to_enc_id; + max_blks = ARRAY_SIZE(rm->mixer_blks); + break; + case DPU_HW_BLK_CTL: + hw_blks = rm->ctl_blks; + hw_to_enc_id = rm->ctl_to_enc_id; + max_blks = ARRAY_SIZE(rm->ctl_blks); + break; + case DPU_HW_BLK_INTF: + hw_blks = rm->intf_blks; + hw_to_enc_id = rm->intf_to_enc_id; + max_blks = ARRAY_SIZE(rm->intf_blks); + break; + default: + DPU_ERROR("blk type %d not managed by rm\n", type); + return 0; + } - dpu_rm_init_hw_iter(&hw_iter, enc_id, type); - while (num_blks < blks_size && dpu_rm_get_hw(rm, &hw_iter)) - blks[num_blks++] = hw_iter.blk->hw; + num_blks = 0; + for (i = 0; i < max_blks; i++) { + if (hw_to_enc_id[i] != enc_id) + continue; + + if (num_blks == blks_size) { + DPU_ERROR("More than %d resources assigned to enc %d\n", + blks_size, enc_id); + break; + } + blks[num_blks++] = hw_blks[i]; + } return num_blks; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h index 982b91e272275..9c8a436ba6cc1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h @@ -11,15 +11,31 @@ #include "msm_kms.h" #include "dpu_hw_top.h" + /** * struct dpu_rm - DPU dynamic hardware resource manager - * @hw_blks: array of lists of hardware resources present in the system, one - * list per type of hardware block + * @pingpong_blks: array of pingpong hardware resources + * @mixer_blks: array of layer mixer hardware resources + * @ctl_blks: array of ctl hardware resources + * @intf_blks: array of intf hardware resources + * @pingpong_to_enc_id: mapping of pingpong hardware resources to an encoder ID + * @mixer_to_enc_id: mapping of mixer hardware resources to an encoder ID + * @ctl_to_enc_id: mapping of ctl hardware resources to an encoder ID + * @intf_to_enc_id: mapping of intf hardware resources to an encoder ID * @lm_max_width: cached layer mixer maximum width * @rm_lock: resource manager mutex */ struct dpu_rm { - struct list_head hw_blks[DPU_HW_BLK_MAX]; + struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0]; + struct dpu_hw_blk *mixer_blks[LM_MAX - LM_0]; + struct dpu_hw_blk *ctl_blks[CTL_MAX - CTL_0]; + struct dpu_hw_blk *intf_blks[INTF_MAX - INTF_0]; + + uint32_t pingpong_to_enc_id[PINGPONG_MAX - PINGPONG_0]; + uint32_t mixer_to_enc_id[LM_MAX - LM_0]; + uint32_t ctl_to_enc_id[CTL_MAX - CTL_0]; + uint32_t intf_to_enc_id[INTF_MAX - INTF_0]; + uint32_t lm_max_width; struct mutex rm_lock; }; From patchwork Wed Feb 19 17:42:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Drew Davenport X-Patchwork-Id: 11392129 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1097292A for ; Wed, 19 Feb 2020 17:43:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C2A462467B for ; Wed, 19 Feb 2020 17:43:17 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="DXFOIbw8" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726677AbgBSRnQ (ORCPT ); Wed, 19 Feb 2020 12:43:16 -0500 Received: from mail-io1-f67.google.com ([209.85.166.67]:33046 "EHLO mail-io1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726762AbgBSRnN (ORCPT ); Wed, 19 Feb 2020 12:43:13 -0500 Received: by mail-io1-f67.google.com with SMTP id z8so1524517ioh.0 for ; Wed, 19 Feb 2020 09:43:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=mrXEj2PJlu+l+Mv8TBp0HHGrRMadtJAnNxexO0DUVkQ=; b=DXFOIbw8AOp+RLHzW2iEmJc5no7yLEskToWfJkoBPA7KtvH/UqUbu6FWbN7Nm7GM14 8x8FYnt9NHII+BBNNHviKpn9WHCpIXMRFIQvf698bdnECiTeUsJ5MHwesnqKL4L16dBm ZLmQosXDSkcKkSCAjoqyfwFuhqTSBJy/XlMug= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=mrXEj2PJlu+l+Mv8TBp0HHGrRMadtJAnNxexO0DUVkQ=; b=SBPwanMOyduJi5rl4g1/HrIVG+kGgKiTqu/ys/hnetSeSoUU8k12h2WoQa6UPUKyeU QjZHCvLZ05487pYa6BVMDXi4j2ATDmNjV0knqjAWY5JWeIov9nK/eTkGlJbPZI23VMOw tOQ0XMmMLAU0Zmk3JK132olfVo6Igcst9zihH0GCDXuKI+00k1wd2fmu0TxXjqTawYTE cQM9wEEbxW6Xr0ml/3EPvKQCLoMdsFYsI5hRPPKT0v4M7H98UiZeokK6C74Au0P7eCLX bZE+aFvs30BNCjBdnHEOCQLTTC3gJFGNbXH7dNCdlkMCpx96W9dhw7myl7AqYtr4eIhg rrOQ== X-Gm-Message-State: APjAAAULMA4T/6P6NKj8Gyq6Q1tgSUsyH9n/I5IWh+t5ZNcX7o86QYub +ybAR+0xPHNwX/HSwpkaPlmhNA== X-Google-Smtp-Source: APXvYqwDV5cpXJAFaWfwW5wKVw9A/fLU/gk0gZceL+S5v8n/JjtdysekiBtB9B4VT04H/8uYmAkBUg== X-Received: by 2002:a05:6602:2209:: with SMTP id n9mr6235488ion.62.1582134192441; Wed, 19 Feb 2020 09:43:12 -0800 (PST) Received: from ddavenport4.bld.corp.google.com ([2620:15c:183:0:92f:a80a:519d:f777]) by smtp.gmail.com with ESMTPSA id a21sm60355ioh.29.2020.02.19.09.43.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 19 Feb 2020 09:43:11 -0800 (PST) From: Drew Davenport To: dri-devel@lists.freedesktop.org Cc: Drew Davenport , Alexios Zavras , Allison Randal , Daniel Vetter , David Airlie , Fritz Koenig , Greg Kroah-Hartman , Jani Nikula , Jeykumar Sankaran , Jordan Crouse , Kalyan Thota , Rob Clark , Sam Ravnborg , Sean Paul , Stephen Boyd , Thomas Gleixner , freedreno@lists.freedesktop.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, zhengbin Subject: [PATCH 4/4] drm/msm/dpu: Track resources in global state Date: Wed, 19 Feb 2020 10:42:27 -0700 Message-Id: <20200219104148.4.I1c945b56a579b35955bea6c26e88086c6e91a17a@changeid> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200219104148.1.I0183a464f2788d41e6902f3535941f69c594b4c1@changeid> References: <20200219104148.1.I0183a464f2788d41e6902f3535941f69c594b4c1@changeid> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Move mapping of resources to encoder ids from the resource manager to a new dpu_global_state struct. Store this struct in global atomic state. Before this patch, atomic test would be performed by modifying global state (resource manager), and backing out any changes if the test fails. By using drm atomic global state, this is not necessary as any changes to the global state will be discarded if the test fails. Signed-off-by: Drew Davenport --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 65 +++++------ drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 84 ++++++++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 26 +++++ drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 121 ++++++++++---------- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 22 ++-- 5 files changed, 207 insertions(+), 111 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 6cadeff456f09..5afde2e7fef08 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -164,7 +164,6 @@ enum dpu_enc_rc_states { * clks and resources after IDLE_TIMEOUT time. * @vsync_event_work: worker to handle vsync event for autorefresh * @topology: topology of the display - * @mode_set_complete: flag to indicate modeset completion * @idle_timeout: idle timeout duration in milliseconds */ struct dpu_encoder_virt { @@ -202,7 +201,6 @@ struct dpu_encoder_virt { struct delayed_work delayed_off_work; struct kthread_work vsync_event_work; struct msm_display_topology topology; - bool mode_set_complete; u32 idle_timeout; }; @@ -563,6 +561,7 @@ static int dpu_encoder_virt_atomic_check( const struct drm_display_mode *mode; struct drm_display_mode *adj_mode; struct msm_display_topology topology; + struct dpu_global_state *global_state; int i = 0; int ret = 0; @@ -579,6 +578,7 @@ static int dpu_encoder_virt_atomic_check( dpu_kms = to_dpu_kms(priv->kms); mode = &crtc_state->mode; adj_mode = &crtc_state->adjusted_mode; + global_state = dpu_kms_get_existing_global_state(dpu_kms); trace_dpu_enc_atomic_check(DRMID(drm_enc)); /* @@ -610,17 +610,15 @@ static int dpu_encoder_virt_atomic_check( topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode); - /* Reserve dynamic resources now. Indicating AtomicTest phase */ + /* Reserve dynamic resources now. */ if (!ret) { /* * Avoid reserving resources when mode set is pending. Topology * info may not be available to complete reservation. */ - if (drm_atomic_crtc_needs_modeset(crtc_state) - && dpu_enc->mode_set_complete) { - ret = dpu_rm_reserve(&dpu_kms->rm, drm_enc, crtc_state, - topology, true); - dpu_enc->mode_set_complete = false; + if (drm_atomic_crtc_needs_modeset(crtc_state)) { + ret = dpu_rm_reserve(&dpu_kms->rm, global_state, + drm_enc, crtc_state, topology); } } @@ -957,12 +955,13 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, struct drm_connector *conn = NULL, *conn_iter; struct drm_crtc *drm_crtc; struct dpu_crtc_state *cstate; + struct dpu_global_state *global_state; struct msm_display_topology topology; struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC]; struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC]; struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC]; int num_lm, num_ctl, num_pp; - int i, j, ret; + int i, j; if (!drm_enc) { DPU_ERROR("invalid encoder\n"); @@ -976,6 +975,12 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, dpu_kms = to_dpu_kms(priv->kms); connector_list = &dpu_kms->dev->mode_config.connector_list; + global_state = dpu_kms_get_existing_global_state(dpu_kms); + if (IS_ERR_OR_NULL(global_state)) { + DPU_ERROR("Failed to get global state"); + return; + } + trace_dpu_enc_mode_set(DRMID(drm_enc)); list_for_each_entry(conn_iter, connector_list, head) @@ -996,21 +1001,14 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode); - /* Reserve dynamic resources now. Indicating non-AtomicTest phase */ - ret = dpu_rm_reserve(&dpu_kms->rm, drm_enc, drm_crtc->state, - topology, false); - if (ret) { - DPU_ERROR_ENC(dpu_enc, - "failed to reserve hw resources, %d\n", ret); - return; - } - - num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, drm_enc->base.id, - DPU_HW_BLK_PINGPONG, hw_pp, ARRAY_SIZE(hw_pp)); - num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, drm_enc->base.id, - DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl)); - num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, drm_enc->base.id, - DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm)); + /* Query resource that have been reserved in atomic check step. */ + num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, + drm_enc->base.id, DPU_HW_BLK_PINGPONG, hw_pp, + ARRAY_SIZE(hw_pp)); + num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, + drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl)); + num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, + drm_enc->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm)); for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i]) @@ -1035,21 +1033,21 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, if (!dpu_enc->hw_pp[i]) { DPU_ERROR_ENC(dpu_enc, "no pp block assigned at idx: %d\n", i); - goto error; + return; } if (!hw_ctl[i]) { DPU_ERROR_ENC(dpu_enc, "no ctl block assigned at idx: %d\n", i); - goto error; + return; } phys->hw_pp = dpu_enc->hw_pp[i]; phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]); num_blk = dpu_rm_get_assigned_resources(&dpu_kms->rm, - drm_enc->base.id, DPU_HW_BLK_INTF, hw_blk, - ARRAY_SIZE(hw_blk)); + global_state, drm_enc->base.id, DPU_HW_BLK_INTF, + hw_blk, ARRAY_SIZE(hw_blk)); for (j = 0; j < num_blk; j++) { struct dpu_hw_intf *hw_intf; @@ -1061,18 +1059,13 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, if (!phys->hw_intf) { DPU_ERROR_ENC(dpu_enc, "no intf block assigned at idx: %d\n", i); - goto error; + return; } phys->connector = conn->state->connector; if (phys->ops.mode_set) phys->ops.mode_set(phys, mode, adj_mode); } - - dpu_enc->mode_set_complete = true; - -error: - dpu_rm_release(&dpu_kms->rm, drm_enc); } static void _dpu_encoder_virt_enable_helper(struct drm_encoder *drm_enc) @@ -1169,6 +1162,7 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc) struct dpu_encoder_virt *dpu_enc = NULL; struct msm_drm_private *priv; struct dpu_kms *dpu_kms; + struct dpu_global_state *global_state; int i = 0; if (!drm_enc) { @@ -1187,6 +1181,7 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc) priv = drm_enc->dev->dev_private; dpu_kms = to_dpu_kms(priv->kms); + global_state = dpu_kms_get_existing_global_state(dpu_kms); trace_dpu_enc_disable(DRMID(drm_enc)); @@ -1216,7 +1211,7 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc) DPU_DEBUG_ENC(dpu_enc, "encoder disabled\n"); - dpu_rm_release(&dpu_kms->rm, drm_enc); + dpu_rm_release(global_state, drm_enc); mutex_unlock(&dpu_enc->enc_lock); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index cb08fafb1dc14..59d42ff9da645 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -228,6 +228,85 @@ static int dpu_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor) } #endif +/* Global/shared object state funcs */ + +/* + * This is a helper that returns the private state currently in operation. + * Note that this would return the "old_state" if called in the atomic check + * path, and the "new_state" after the atomic swap has been done. + */ +struct dpu_global_state * +dpu_kms_get_existing_global_state(struct dpu_kms *dpu_kms) +{ + return to_dpu_global_state(dpu_kms->global_state.state); +} + +/* + * This acquires the modeset lock set aside for global state, creates + * a new duplicated private object state. + */ +struct dpu_global_state *dpu_kms_get_global_state(struct drm_atomic_state *s) +{ + struct msm_drm_private *priv = s->dev->dev_private; + struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms); + struct drm_private_state *priv_state; + int ret; + + ret = drm_modeset_lock(&dpu_kms->global_state_lock, s->acquire_ctx); + if (ret) + return ERR_PTR(ret); + + priv_state = drm_atomic_get_private_obj_state(s, + &dpu_kms->global_state); + if (IS_ERR(priv_state)) + return ERR_CAST(priv_state); + + return to_dpu_global_state(priv_state); +} + +static struct drm_private_state * +dpu_kms_global_duplicate_state(struct drm_private_obj *obj) +{ + struct dpu_global_state *state; + + state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL); + if (!state) + return NULL; + + __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base); + + return &state->base; +} + +static void dpu_kms_global_destroy_state(struct drm_private_obj *obj, + struct drm_private_state *state) +{ + struct dpu_global_state *dpu_state = to_dpu_global_state(state); + + kfree(dpu_state); +} + +static const struct drm_private_state_funcs dpu_kms_global_state_funcs = { + .atomic_duplicate_state = dpu_kms_global_duplicate_state, + .atomic_destroy_state = dpu_kms_global_destroy_state, +}; + +static int dpu_kms_global_obj_init(struct dpu_kms *dpu_kms) +{ + struct dpu_global_state *state; + + drm_modeset_lock_init(&dpu_kms->global_state_lock); + + state = kzalloc(sizeof(*state), GFP_KERNEL); + if (!state) + return -ENOMEM; + + drm_atomic_private_obj_init(dpu_kms->dev, &dpu_kms->global_state, + &state->base, + &dpu_kms_global_state_funcs); + return 0; +} + static int dpu_kms_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc) { return dpu_crtc_vblank(crtc, true); @@ -770,6 +849,11 @@ static int dpu_kms_hw_init(struct msm_kms *kms) dpu_kms = to_dpu_kms(kms); dev = dpu_kms->dev; + + rc = dpu_kms_global_obj_init(dpu_kms); + if (rc) + return rc; + priv = dev->dev_private; atomic_set(&dpu_kms->bandwidth_ref, 0); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index c6169e7df19de..211f5de99a441 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -111,6 +111,13 @@ struct dpu_kms { struct dpu_core_perf perf; + /* + * Global private object state, Do not access directly, use + * dpu_kms_global_get_state() + */ + struct drm_modeset_lock global_state_lock; + struct drm_private_obj global_state; + struct dpu_rm rm; bool rm_init; @@ -139,6 +146,25 @@ struct vsync_info { #define to_dpu_kms(x) container_of(x, struct dpu_kms, base) +#define to_dpu_global_state(x) container_of(x, struct dpu_global_state, base) + +/* Global private object state for tracking resources that are shared across + * multiple kms objects (planes/crtcs/etc). + */ +struct dpu_global_state { + struct drm_private_state base; + + uint32_t pingpong_to_enc_id[PINGPONG_MAX - PINGPONG_0]; + uint32_t mixer_to_enc_id[LM_MAX - LM_0]; + uint32_t ctl_to_enc_id[CTL_MAX - CTL_0]; + uint32_t intf_to_enc_id[INTF_MAX - INTF_0]; +}; + +struct dpu_global_state + *dpu_kms_get_existing_global_state(struct dpu_kms *dpu_kms); +struct dpu_global_state + *__must_check dpu_kms_get_global_state(struct drm_atomic_state *s); + /** * Debugfs functions - extra helper functions for debugfs support * diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index f1483b00b7423..bc940f9b12d7e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -66,8 +66,6 @@ int dpu_rm_destroy(struct dpu_rm *rm) } } - mutex_destroy(&rm->rm_lock); - return 0; } @@ -85,8 +83,6 @@ int dpu_rm_init(struct dpu_rm *rm, /* Clear, setup lists */ memset(rm, 0, sizeof(*rm)); - mutex_init(&rm->rm_lock); - /* Interrogate HW catalog and create tracking items for hw blocks */ for (i = 0; i < cat->mixer_count; i++) { struct dpu_hw_mixer *hw; @@ -230,13 +226,14 @@ static bool _dpu_rm_check_lm_peer(struct dpu_rm *rm, int primary_idx, * @Return: true if lm matches all requirements, false otherwise */ static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm, + struct dpu_global_state *global_state, uint32_t enc_id, int lm_idx, int *pp_idx) { const struct dpu_lm_cfg *lm_cfg; int idx; /* Already reserved? */ - if (reserved_by_other(rm->mixer_to_enc_id, lm_idx, enc_id)) { + if (reserved_by_other(global_state->mixer_to_enc_id, lm_idx, enc_id)) { DPU_DEBUG("lm %d already reserved\n", lm_idx + LM_0); return false; } @@ -248,7 +245,7 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm, return false; } - if (reserved_by_other(rm->pingpong_to_enc_id, idx, enc_id)) { + if (reserved_by_other(global_state->pingpong_to_enc_id, idx, enc_id)) { DPU_DEBUG("lm %d pp %d already reserved\n", lm_cfg->id, lm_cfg->pingpong); return false; @@ -257,7 +254,9 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm, return true; } -static int _dpu_rm_reserve_lms(struct dpu_rm *rm, uint32_t enc_id, +static int _dpu_rm_reserve_lms(struct dpu_rm *rm, + struct dpu_global_state *global_state, + uint32_t enc_id, struct dpu_rm_requirements *reqs) { @@ -279,8 +278,8 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, uint32_t enc_id, lm_count = 0; lm_idx[lm_count] = i; - if (!_dpu_rm_check_lm_and_get_connected_blks( - rm, enc_id, i, &pp_idx[lm_count])) { + if (!_dpu_rm_check_lm_and_get_connected_blks(rm, global_state, + enc_id, i, &pp_idx[lm_count])) { continue; } @@ -298,8 +297,9 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, uint32_t enc_id, continue; } - if (!_dpu_rm_check_lm_and_get_connected_blks( - rm, enc_id, j, &pp_idx[lm_count])) { + if (!_dpu_rm_check_lm_and_get_connected_blks(rm, + global_state, enc_id, j, + &pp_idx[lm_count])) { continue; } @@ -314,8 +314,8 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, uint32_t enc_id, } for (i = 0; i < lm_count; i++) { - rm->mixer_to_enc_id[lm_idx[i]] = enc_id; - rm->pingpong_to_enc_id[pp_idx[i]] = enc_id; + global_state->mixer_to_enc_id[lm_idx[i]] = enc_id; + global_state->pingpong_to_enc_id[pp_idx[i]] = enc_id; trace_dpu_rm_reserve_lms(lm_idx[i] + LM_0, enc_id, pp_idx[i] + PINGPONG_0); @@ -326,6 +326,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, uint32_t enc_id, static int _dpu_rm_reserve_ctls( struct dpu_rm *rm, + struct dpu_global_state *global_state, uint32_t enc_id, const struct msm_display_topology *top) { @@ -345,7 +346,7 @@ static int _dpu_rm_reserve_ctls( if (!rm->ctl_blks[j]) continue; - if (reserved_by_other(rm->ctl_to_enc_id, j, enc_id)) + if (reserved_by_other(global_state->ctl_to_enc_id, j, enc_id)) continue; ctl = to_dpu_hw_ctl(rm->ctl_blks[j]); @@ -369,7 +370,7 @@ static int _dpu_rm_reserve_ctls( return -ENAVAIL; for (i = 0; i < ARRAY_SIZE(ctl_idx) && i < num_ctls; i++) { - rm->ctl_to_enc_id[ctl_idx[i]] = enc_id; + global_state->ctl_to_enc_id[ctl_idx[i]] = enc_id; trace_dpu_rm_reserve_ctls(i + CTL_0, enc_id); } @@ -378,27 +379,34 @@ static int _dpu_rm_reserve_ctls( static int _dpu_rm_reserve_intf( struct dpu_rm *rm, + struct dpu_global_state *global_state, uint32_t enc_id, uint32_t id) { int idx = id - INTF_0; + if (idx < 0 || idx >= ARRAY_SIZE(rm->intf_blks)) { + DPU_ERROR("invalid intf id: %d", id); + return -EINVAL; + } + if (!rm->intf_blks[idx]) { DPU_ERROR("couldn't find intf id %d\n", id); return -EINVAL; } - if (reserved_by_other(rm->intf_to_enc_id, idx, enc_id)) { + if (reserved_by_other(global_state->intf_to_enc_id, idx, enc_id)) { DPU_ERROR("intf id %d already reserved\n", id); return -ENAVAIL; } - rm->intf_to_enc_id[idx] = enc_id; + global_state->intf_to_enc_id[idx] = enc_id; return 0; } static int _dpu_rm_reserve_intf_related_hw( struct dpu_rm *rm, + struct dpu_global_state *global_state, uint32_t enc_id, struct dpu_encoder_hw_resources *hw_res) { @@ -409,7 +417,7 @@ static int _dpu_rm_reserve_intf_related_hw( if (hw_res->intfs[i] == INTF_MODE_NONE) continue; id = i + INTF_0; - ret = _dpu_rm_reserve_intf(rm, enc_id, id); + ret = _dpu_rm_reserve_intf(rm, global_state, enc_id, id); if (ret) return ret; } @@ -419,24 +427,27 @@ static int _dpu_rm_reserve_intf_related_hw( static int _dpu_rm_make_reservation( struct dpu_rm *rm, + struct dpu_global_state *global_state, struct drm_encoder *enc, struct dpu_rm_requirements *reqs) { int ret; - ret = _dpu_rm_reserve_lms(rm, enc->base.id, reqs); + ret = _dpu_rm_reserve_lms(rm, global_state, enc->base.id, reqs); if (ret) { DPU_ERROR("unable to find appropriate mixers\n"); return ret; } - ret = _dpu_rm_reserve_ctls(rm, enc->base.id, &reqs->topology); + ret = _dpu_rm_reserve_ctls(rm, global_state, enc->base.id, + &reqs->topology); if (ret) { DPU_ERROR("unable to find appropriate CTL\n"); return ret; } - ret = _dpu_rm_reserve_intf_related_hw(rm, enc->base.id, &reqs->hw_res); + ret = _dpu_rm_reserve_intf_related_hw(rm, global_state, enc->base.id, + &reqs->hw_res); if (ret) return ret; @@ -470,33 +481,25 @@ static void _dpu_rm_clear_mapping(uint32_t *res_mapping, int cnt, } } -static void _dpu_rm_release_reservation(struct dpu_rm *rm, uint32_t enc_id) -{ - _dpu_rm_clear_mapping(rm->pingpong_to_enc_id, - ARRAY_SIZE(rm->pingpong_to_enc_id), enc_id); - _dpu_rm_clear_mapping(rm->mixer_to_enc_id, - ARRAY_SIZE(rm->mixer_to_enc_id), enc_id); - _dpu_rm_clear_mapping(rm->ctl_to_enc_id, - ARRAY_SIZE(rm->ctl_to_enc_id), enc_id); - _dpu_rm_clear_mapping(rm->intf_to_enc_id, - ARRAY_SIZE(rm->intf_to_enc_id), enc_id); -} - -void dpu_rm_release(struct dpu_rm *rm, struct drm_encoder *enc) +void dpu_rm_release(struct dpu_global_state *global_state, + struct drm_encoder *enc) { - mutex_lock(&rm->rm_lock); - - _dpu_rm_release_reservation(rm, enc->base.id); - - mutex_unlock(&rm->rm_lock); + _dpu_rm_clear_mapping(global_state->pingpong_to_enc_id, + ARRAY_SIZE(global_state->pingpong_to_enc_id), enc->base.id); + _dpu_rm_clear_mapping(global_state->mixer_to_enc_id, + ARRAY_SIZE(global_state->mixer_to_enc_id), enc->base.id); + _dpu_rm_clear_mapping(global_state->ctl_to_enc_id, + ARRAY_SIZE(global_state->ctl_to_enc_id), enc->base.id); + _dpu_rm_clear_mapping(global_state->intf_to_enc_id, + ARRAY_SIZE(global_state->intf_to_enc_id), enc->base.id); } int dpu_rm_reserve( struct dpu_rm *rm, + struct dpu_global_state *global_state, struct drm_encoder *enc, struct drm_crtc_state *crtc_state, - struct msm_display_topology topology, - bool test_only) + struct msm_display_topology topology) { struct dpu_rm_requirements reqs; int ret; @@ -505,35 +508,31 @@ int dpu_rm_reserve( if (!drm_atomic_crtc_needs_modeset(crtc_state)) return 0; - DRM_DEBUG_KMS("reserving hw for enc %d crtc %d test_only %d\n", - enc->base.id, crtc_state->crtc->base.id, test_only); + if (IS_ERR(global_state)) { + DPU_ERROR("failed to global state\n"); + return PTR_ERR(global_state); + } - mutex_lock(&rm->rm_lock); + DRM_DEBUG_KMS("reserving hw for enc %d crtc %d\n", + enc->base.id, crtc_state->crtc->base.id); ret = _dpu_rm_populate_requirements(enc, &reqs, topology); if (ret) { DPU_ERROR("failed to populate hw requirements\n"); - goto end; + return ret; } - ret = _dpu_rm_make_reservation(rm, enc, &reqs); - if (ret) { + ret = _dpu_rm_make_reservation(rm, global_state, enc, &reqs); + if (ret) DPU_ERROR("failed to reserve hw resources: %d\n", ret); - _dpu_rm_release_reservation(rm, enc->base.id); - } else if (test_only) { - /* test_only: test the reservation and then undo */ - DPU_DEBUG("test_only: discard test [enc: %d]\n", - enc->base.id); - _dpu_rm_release_reservation(rm, enc->base.id); - } -end: - mutex_unlock(&rm->rm_lock); + return ret; } -int dpu_rm_get_assigned_resources(struct dpu_rm *rm, uint32_t enc_id, +int dpu_rm_get_assigned_resources(struct dpu_rm *rm, + struct dpu_global_state *global_state, uint32_t enc_id, enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size) { struct dpu_hw_blk **hw_blks; @@ -543,22 +542,22 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm, uint32_t enc_id, switch (type) { case DPU_HW_BLK_PINGPONG: hw_blks = rm->pingpong_blks; - hw_to_enc_id = rm->pingpong_to_enc_id; + hw_to_enc_id = global_state->pingpong_to_enc_id; max_blks = ARRAY_SIZE(rm->pingpong_blks); break; case DPU_HW_BLK_LM: hw_blks = rm->mixer_blks; - hw_to_enc_id = rm->mixer_to_enc_id; + hw_to_enc_id = global_state->mixer_to_enc_id; max_blks = ARRAY_SIZE(rm->mixer_blks); break; case DPU_HW_BLK_CTL: hw_blks = rm->ctl_blks; - hw_to_enc_id = rm->ctl_to_enc_id; + hw_to_enc_id = global_state->ctl_to_enc_id; max_blks = ARRAY_SIZE(rm->ctl_blks); break; case DPU_HW_BLK_INTF: hw_blks = rm->intf_blks; - hw_to_enc_id = rm->intf_to_enc_id; + hw_to_enc_id = global_state->intf_to_enc_id; max_blks = ARRAY_SIZE(rm->intf_blks); break; default: diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h index 9c8a436ba6cc1..6d2b04f306f09 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h @@ -11,6 +11,7 @@ #include "msm_kms.h" #include "dpu_hw_top.h" +struct dpu_global_state; /** * struct dpu_rm - DPU dynamic hardware resource manager @@ -18,10 +19,6 @@ * @mixer_blks: array of layer mixer hardware resources * @ctl_blks: array of ctl hardware resources * @intf_blks: array of intf hardware resources - * @pingpong_to_enc_id: mapping of pingpong hardware resources to an encoder ID - * @mixer_to_enc_id: mapping of mixer hardware resources to an encoder ID - * @ctl_to_enc_id: mapping of ctl hardware resources to an encoder ID - * @intf_to_enc_id: mapping of intf hardware resources to an encoder ID * @lm_max_width: cached layer mixer maximum width * @rm_lock: resource manager mutex */ @@ -31,13 +28,7 @@ struct dpu_rm { struct dpu_hw_blk *ctl_blks[CTL_MAX - CTL_0]; struct dpu_hw_blk *intf_blks[INTF_MAX - INTF_0]; - uint32_t pingpong_to_enc_id[PINGPONG_MAX - PINGPONG_0]; - uint32_t mixer_to_enc_id[LM_MAX - LM_0]; - uint32_t ctl_to_enc_id[CTL_MAX - CTL_0]; - uint32_t intf_to_enc_id[INTF_MAX - INTF_0]; - uint32_t lm_max_width; - struct mutex rm_lock; }; /** @@ -70,14 +61,13 @@ int dpu_rm_destroy(struct dpu_rm *rm); * @drm_enc: DRM Encoder handle * @crtc_state: Proposed Atomic DRM CRTC State handle * @topology: Pointer to topology info for the display - * @test_only: Atomic-Test phase, discard results (unless property overrides) * @Return: 0 on Success otherwise -ERROR */ int dpu_rm_reserve(struct dpu_rm *rm, + struct dpu_global_state *global_state, struct drm_encoder *drm_enc, struct drm_crtc_state *crtc_state, - struct msm_display_topology topology, - bool test_only); + struct msm_display_topology topology); /** * dpu_rm_reserve - Given the encoder for the display chain, release any @@ -86,12 +76,14 @@ int dpu_rm_reserve(struct dpu_rm *rm, * @enc: DRM Encoder handle * @Return: 0 on Success otherwise -ERROR */ -void dpu_rm_release(struct dpu_rm *rm, struct drm_encoder *enc); +void dpu_rm_release(struct dpu_global_state *global_state, + struct drm_encoder *enc); /** * Get hw resources of the given type that are assigned to this encoder. */ -int dpu_rm_get_assigned_resources(struct dpu_rm *rm, uint32_t enc_id, +int dpu_rm_get_assigned_resources(struct dpu_rm *rm, + struct dpu_global_state *global_state, uint32_t enc_id, enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size); #endif /* __DPU_RM_H__ */