From patchwork Wed Oct 18 04:36:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?U2hhd24gU3VuZyAo5a6L5a2d6KyZKQ==?= X-Patchwork-Id: 154639 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:2908:b0:403:3b70:6f57 with SMTP id ib8csp4561667vqb; Tue, 17 Oct 2023 21:38:32 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFIDWaIqN9rhtj0CMemAIHISfgOGIEUMhlsSnoxoNLFTZNI5R697q9rCM1o0sn79Hq/Hqxg X-Received: by 2002:a05:6a20:ceaa:b0:13f:65ca:52a2 with SMTP id if42-20020a056a20ceaa00b0013f65ca52a2mr3984897pzb.5.1697603912253; Tue, 17 Oct 2023 21:38:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1697603912; cv=none; d=google.com; s=arc-20160816; b=uMqQKCHJiz+LOpt0VbVgnL7yPpFcG8YYaO196IZ7hBwJ8DqpUiLNyF9vvywPMIULA7 u8a5Lf5e4nlhNZjlCo0G7Ac8pbExH0EZe0qKyIWt8eYbYIqo1uGuHrxchTSncCkPYK+x yjIVpepnF8jHqXVNUp7eGSOCu/LbjM5GWbrizGcqa2yjnGYG6DwFciz12LyYEBcWaenH ZvdTjwG5IZmNEVV8Viq779Zo9AE0uR5f+KVS9pvMQi0kZblZLo1Holfe3yveOj832VBS 9slLeTChUydJeAQ2EmWSkjKR1FVDbW7MDeDEDnLhUs5NjRawTkLqSl3sN3KkKNd+NUyL xguw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=gbjXlNeTaWOAgDiP7qRRiuPNtFIqTcPeM3WN/tA9eQc=; fh=fv4tbCKTXdNtjEvV4h1+g1nnsRjdLHbhnCNyWnoFRfI=; b=voNJh56pWjLVvwqp99SjZg3XvNAZBj7UV1ybDmP+JJQgkQaeZTEBnLIxR93UZwKbgP lm0Rn53i+NytDEf0x61GlUVkTx2W6MS97QuzRep6D9sK1qI8noC3pKxsq9+ZuR7eXxCP T12nkbO5lpyvJuqtKUP6HzJnf6yG2+lHocgkl+rPs9M7I6dH++R9vvJ0z+TUfnOmiCmY h6/L/pBUvLNQOg9fHZCGtsCiwdNf3d6xyZF09f3K3q4+gg0eF340a0Bb4G6EQvuT/j7t VvTEjnbG8Z2fF6rxPqvufbOUx1jkwFaCf/6q+yTeSv06ZJ0ucQy3wXWgBC13UwRdQon5 oHjQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@mediatek.com header.s=dk header.b=ryoyhtcA; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=mediatek.com Received: from snail.vger.email (snail.vger.email. [23.128.96.37]) by mx.google.com with ESMTPS id e10-20020a17090301ca00b001bdf71d52b0si3731417plh.456.2023.10.17.21.38.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 17 Oct 2023 21:38:32 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) client-ip=23.128.96.37; Authentication-Results: mx.google.com; dkim=pass header.i=@mediatek.com header.s=dk header.b=ryoyhtcA; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=mediatek.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id 2A5B280DEA45; Tue, 17 Oct 2023 21:38:30 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235225AbjJREiW (ORCPT + 23 others); Wed, 18 Oct 2023 00:38:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42500 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234920AbjJREhL (ORCPT ); Wed, 18 Oct 2023 00:37:11 -0400 Received: from mailgw01.mediatek.com (unknown [60.244.123.138]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D861212B; Tue, 17 Oct 2023 21:37:04 -0700 (PDT) X-UUID: f7f560946d6f11eea33bb35ae8d461a2-20231018 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=gbjXlNeTaWOAgDiP7qRRiuPNtFIqTcPeM3WN/tA9eQc=; b=ryoyhtcAHbLBDDANTvUppiSI1ByEbt9C68EBbUX65/c9Ho5QarPp1+S1dSpMFb3f2yNTvXKkjrkrf9imdXgnfPMqjm8/kK9ZGh0TSceFgdZlE412pF+n4Bb5VfosbbeOJEV+vAaJ3WRj5tHA/RnqLNG/FH1NIivWTrT1NjnpDmE=; X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.32,REQID:73db61d0-2d51-4da6-9096-b620122767fa,IP:0,U RL:0,TC:0,Content:-25,EDM:0,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTIO N:release,TS:-25 X-CID-META: VersionHash:5f78ec9,CLOUDID:1d392a15-4929-4845-9571-38c601e9c3c9,B ulkID:nil,BulkQuantity:0,Recheck:0,SF:102,TC:nil,Content:0,EDM:-3,IP:nil,U RL:11|1,File:nil,Bulk:nil,QS:nil,BEC:nil,COL:0,OSI:0,OSA:0,AV:0,LES:1,SPR: NO,DKR:0,DKP:0,BRR:0,BRE:0 X-CID-BVR: 0 X-CID-BAS: 0,_,0,_ X-CID-FACTOR: TF_CID_SPAM_SNR,TF_CID_SPAM_ULN X-UUID: f7f560946d6f11eea33bb35ae8d461a2-20231018 Received: from mtkmbs14n1.mediatek.inc [(172.21.101.75)] by mailgw01.mediatek.com (envelope-from ) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 1464819507; Wed, 18 Oct 2023 12:36:56 +0800 Received: from mtkmbs11n1.mediatek.inc (172.21.101.185) by mtkmbs11n1.mediatek.inc (172.21.101.185) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.26; Wed, 18 Oct 2023 12:36:55 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkmbs11n1.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.1118.26 via Frontend Transport; Wed, 18 Oct 2023 12:36:55 +0800 From: Hsiao Chien Sung To: AngeloGioacchino Del Regno , CK Hu , Krzysztof Kozlowski , Matthias Brugger , Rob Herring CC: Chun-Kuang Hu , Philipp Zabel , David Airlie , Daniel Vetter , Fei Shao , Sean Paul , Johnson Wang , "Nancy . Lin" , Moudy Ho , Hsiao Chien Sung , "Jason-JH . Lin" , Nathan Lu , , , , , Subject: [PATCH v9 22/23] drm/mediatek: Power on devices in OVL adaptor when atomic enable Date: Wed, 18 Oct 2023 12:36:49 +0800 Message-ID: <20231018043650.22532-23-shawn.sung@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20231018043650.22532-1-shawn.sung@mediatek.com> References: <20231018043650.22532-1-shawn.sung@mediatek.com> MIME-Version: 1.0 X-MTK: N X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL,SPF_HELO_PASS,SPF_PASS,UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Tue, 17 Oct 2023 21:38:31 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1780066720087474452 X-GMAIL-MSGID: 1780066720087474452 Different from OVL, OVL adaptor is a pseudo device so we didn't define it in the device tree, consequently, pm_runtime_resume_and_get() called by .atomic_enable() powers on no device in OVL adaptor and leads to power outage in the corresponding IOMMU. To resolve the issue, we implement a function to power on the RDMAs in OVL adaptor, and the system will make sure the IOMMU is powered on as well because of the device link (iommus) in the RDMA nodes in DTS. Signed-off-by: Hsiao Chien Sung Reviewed-by: AngeloGioacchino Del Regno --- drivers/gpu/drm/mediatek/mtk_disp_drv.h | 4 ++ .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c | 63 +++++++++++++++++++ drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 28 +++------ drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 2 + drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 ++++++ drivers/gpu/drm/mediatek/mtk_mdp_rdma.c | 16 +++++ 6 files changed, 112 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h index e2b602037ac3..c44f5b31bab5 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h @@ -109,6 +109,8 @@ void mtk_ovl_adaptor_connect(struct device *dev, struct device *mmsys_dev, unsigned int next); void mtk_ovl_adaptor_disconnect(struct device *dev, struct device *mmsys_dev, unsigned int next); +int mtk_ovl_adaptor_power_on(struct device *dev); +void mtk_ovl_adaptor_power_off(struct device *dev); int mtk_ovl_adaptor_clk_enable(struct device *dev); void mtk_ovl_adaptor_clk_disable(struct device *dev); void mtk_ovl_adaptor_config(struct device *dev, unsigned int w, @@ -150,6 +152,8 @@ void mtk_rdma_disable_vblank(struct device *dev); const u32 *mtk_rdma_get_formats(struct device *dev); size_t mtk_rdma_get_num_formats(struct device *dev); +int mtk_mdp_rdma_power_on(struct device *dev); +void mtk_mdp_rdma_power_off(struct device *dev); int mtk_mdp_rdma_clk_enable(struct device *dev); void mtk_mdp_rdma_clk_disable(struct device *dev); void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt *cmdq_pkt); diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c index 753a7f829173..35bbce35b7b5 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c @@ -98,6 +98,8 @@ static const struct mtk_ddp_comp_funcs padding = { }; static const struct mtk_ddp_comp_funcs rdma = { + .power_on = mtk_mdp_rdma_power_on, + .power_off = mtk_mdp_rdma_power_off, .clk_enable = mtk_mdp_rdma_clk_enable, .clk_disable = mtk_mdp_rdma_clk_disable, }; @@ -241,6 +243,67 @@ void mtk_ovl_adaptor_stop(struct device *dev) } } +/** + * power_off - Power off the devices in OVL adaptor + * @dev: Device to be powered off + * @num: Number of the devices to be powered off + * + * Calls the .power_off() ovl_adaptor component callback if it is present. + */ +static inline void power_off(struct device *dev, unsigned int num) +{ + int i; + struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev); + + if (num > OVL_ADAPTOR_ID_MAX) + num = OVL_ADAPTOR_ID_MAX; + + for (i = num - 1; i >= 0; i--) { + if (!ovl_adaptor->ovl_adaptor_comp[i] || + !comp_matches[i].funcs->power_off) + continue; + + comp_matches[i].funcs->power_off(ovl_adaptor->ovl_adaptor_comp[i]); + } +} + +/** + * mtk_ovl_adaptor_power_on - Power on the devices in OVL adaptor + * @dev: Device to be powered on + * + * Different from OVL, OVL adaptor is a pseudo device so + * we didn't define it in the device tree, pm_runtime_resume_and_get() + * called by .atomic_enable() power on no device in OVL adaptor, + * we have to implement a function to do the job instead. + * + * Return: Zero for success or negative number for failure. + */ +int mtk_ovl_adaptor_power_on(struct device *dev) +{ + int i, ret; + struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev); + + for (i = 0; i < OVL_ADAPTOR_ID_MAX; i++) { + if (!ovl_adaptor->ovl_adaptor_comp[i] || + !comp_matches[i].funcs->power_on) + continue; + + ret = comp_matches[i].funcs->power_on(ovl_adaptor->ovl_adaptor_comp[i]); + if (ret < 0) { + dev_err(ovl_adaptor->ovl_adaptor_comp[i], + "Failed to power on: %d\n", ret); + power_off(dev, i); + return ret; + } + } + return 0; +} + +void mtk_ovl_adaptor_power_off(struct device *dev) +{ + power_off(dev, OVL_ADAPTOR_ID_MAX); +} + int mtk_ovl_adaptor_clk_enable(struct device *dev) { int i; diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index a0b2ba3cbcdb..c7edd80be428 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -362,22 +361,16 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc, struct drm_atomic drm_connector_list_iter_end(&conn_iter); } - ret = pm_runtime_resume_and_get(crtc->dev->dev); - if (ret < 0) { - DRM_ERROR("Failed to enable power domain: %d\n", ret); - return ret; - } - ret = mtk_mutex_prepare(mtk_crtc->mutex); if (ret < 0) { DRM_ERROR("Failed to enable mutex clock: %d\n", ret); - goto err_pm_runtime_put; + goto error; } ret = mtk_crtc_ddp_clk_enable(mtk_crtc); if (ret < 0) { DRM_ERROR("Failed to enable component clocks: %d\n", ret); - goto err_mutex_unprepare; + goto error; } for (i = 0; i < mtk_crtc->ddp_comp_nr - 1; i++) { @@ -426,16 +419,13 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc, struct drm_atomic return 0; -err_mutex_unprepare: +error: mtk_mutex_unprepare(mtk_crtc->mutex); -err_pm_runtime_put: - pm_runtime_put(crtc->dev->dev); return ret; } static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc) { - struct drm_device *drm = mtk_crtc->base.dev; struct drm_crtc *crtc = &mtk_crtc->base; int i; @@ -465,8 +455,6 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc) mtk_crtc_ddp_clk_disable(mtk_crtc); mtk_mutex_unprepare(mtk_crtc->mutex); - pm_runtime_put(drm->dev); - if (crtc->state->event && !crtc->state->active) { spin_lock_irq(&crtc->dev->event_lock); drm_crtc_send_vblank_event(crtc, crtc->state->event); @@ -774,7 +762,7 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc, return; } - ret = pm_runtime_resume_and_get(comp->dev); + ret = mtk_ddp_comp_power_on(comp); if (ret < 0) { DRM_DEV_ERROR(comp->dev, "Failed to enable power domain: %d\n", ret); return; @@ -782,7 +770,7 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc, ret = mtk_crtc_ddp_hw_init(mtk_crtc, state); if (ret) { - pm_runtime_put(comp->dev); + mtk_ddp_comp_power_off(comp); return; } @@ -795,7 +783,7 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc, { struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0]; - int i, ret; + int i; DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id); if (!mtk_crtc->enabled) @@ -825,9 +813,7 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc, drm_crtc_vblank_off(crtc); mtk_crtc_ddp_hw_fini(mtk_crtc); - ret = pm_runtime_put(comp->dev); - if (ret < 0) - DRM_DEV_ERROR(comp->dev, "Failed to disable power domain: %d\n", ret); + mtk_ddp_comp_power_off(comp); mtk_crtc->enabled = false; } diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c index 10402e07a4a7..9940909c7435 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c @@ -396,6 +396,8 @@ static const struct mtk_ddp_comp_funcs ddp_ufoe = { }; static const struct mtk_ddp_comp_funcs ddp_ovl_adaptor = { + .power_on = mtk_ovl_adaptor_power_on, + .power_off = mtk_ovl_adaptor_power_off, .clk_enable = mtk_ovl_adaptor_clk_enable, .clk_disable = mtk_ovl_adaptor_clk_disable, .config = mtk_ovl_adaptor_config, diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h index 1c1d670cfe41..2597dd7ac0d2 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h @@ -7,6 +7,7 @@ #define MTK_DRM_DDP_COMP_H #include +#include #include #include #include @@ -46,6 +47,8 @@ enum mtk_ddp_comp_type { struct mtk_ddp_comp; struct cmdq_pkt; struct mtk_ddp_comp_funcs { + int (*power_on)(struct device *dev); + void (*power_off)(struct device *dev); int (*clk_enable)(struct device *dev); void (*clk_disable)(struct device *dev); void (*config)(struct device *dev, unsigned int w, @@ -91,6 +94,23 @@ struct mtk_ddp_comp { int encoder_index; }; +static inline int mtk_ddp_comp_power_on(struct mtk_ddp_comp *comp) +{ + if (comp->funcs && comp->funcs->power_on) + return comp->funcs->power_on(comp->dev); + else + return pm_runtime_resume_and_get(comp->dev); + return 0; +} + +static inline void mtk_ddp_comp_power_off(struct mtk_ddp_comp *comp) +{ + if (comp->funcs && comp->funcs->power_off) + comp->funcs->power_off(comp->dev); + else + pm_runtime_put(comp->dev); +} + static inline int mtk_ddp_comp_clk_enable(struct mtk_ddp_comp *comp) { if (comp->funcs && comp->funcs->clk_enable) diff --git a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c index cb36a961786f..8feeb6dce217 100644 --- a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c +++ b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c @@ -243,6 +243,22 @@ size_t mtk_mdp_rdma_get_num_formats(struct device *dev) return ARRAY_SIZE(formats); } +int mtk_mdp_rdma_power_on(struct device *dev) +{ + int ret = pm_runtime_resume_and_get(dev); + + if (ret < 0) { + dev_err(dev, "Failed to power on: %d\n", ret); + return ret; + } + return 0; +} + +void mtk_mdp_rdma_power_off(struct device *dev) +{ + pm_runtime_put(dev); +} + int mtk_mdp_rdma_clk_enable(struct device *dev) { struct mtk_mdp_rdma *rdma = dev_get_drvdata(dev);