Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp3995392pxu; Wed, 9 Dec 2020 06:01:39 -0800 (PST) X-Google-Smtp-Source: ABdhPJzrfnatqS1wHUE/su7wAekaZlfUlMrdo63FVPhXYwemf5+SHwGWR5j/CvEZ8WsYTN2i2IBD X-Received: by 2002:a17:906:608:: with SMTP id s8mr2187142ejb.371.1607522499020; Wed, 09 Dec 2020 06:01:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1607522499; cv=none; d=google.com; s=arc-20160816; b=lXD6Tgw4l1g2uRII552aRXPPtoDCSfo0N4jEbfaAddZoJtWgdzQTPVqyGGPmk7NSRo heyWlpIxfE+mJBWB81EjkXmmGtHOvL/ARHljxS0ogM//TGxaJdi7FtYF2HhcoPcdVKov S4X6rV3kHUVWVfLlbDMS3K8amxvZNlDFHWUn/yxGbG+VaE/WUJY6qliD3y9r3/W7EsbE ywXjcPQPYVTHrkWY9NYG/ICR0BjB2pVBZeu4Wv4a3z/P0XorLwn+JwVJN+/jPnJtSVY1 aBMpnrEYeH6jNNlyEupCs9uN/U9X2VwjezeaL4c37da2BS3INInC5QoZSTuZq78PVzxJ jitg== 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; bh=psFJj2UN2LHTwK51NPZlk752GhjRLQYPdxkzMfHtg58=; b=kvMh7mqCsSENl6bkcjBKaTG6fmbtRobsB4eC1KzPgLnb42pwxvsAHqz0rgVVHnvzti uUvGjlQPz+9bcOVEH78GDUJPitqooNxQkkig3SaMMNoF6HfjKrzR+eNiUaQKsxEHVQMt 2qiTCWkXqRQkaAj33qKrJXNEcW3iJVkPYUvLPEX/4S5By8sfWoHwyVHHNAw0WRjbJpe8 A0ofloyChGqRwhi9wEasZzrt6hwXMmL3MuD87K3Y4xatBT0ZR9lktqPX+TFRuBqlLHQ4 6rZvQUZ9hSo9Q/RdW0qEtWUNZj7tIwdp7NmevnRIUrHA2KHl++Q42wGeC2mOl47Jlokz pxRw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=mediatek.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id u18si756943ejx.722.2020.12.09.06.01.12; Wed, 09 Dec 2020 06:01:39 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=mediatek.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728849AbgLIIHf (ORCPT + 99 others); Wed, 9 Dec 2020 03:07:35 -0500 Received: from mailgw02.mediatek.com ([210.61.82.184]:46613 "EHLO mailgw02.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1727981AbgLIIEc (ORCPT ); Wed, 9 Dec 2020 03:04:32 -0500 X-UUID: b9491d2b9ee94bebbdbf3eb32ffd14ea-20201209 X-UUID: b9491d2b9ee94bebbdbf3eb32ffd14ea-20201209 Received: from mtkcas07.mediatek.inc [(172.21.101.84)] by mailgw02.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.14 Build 0819 with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 494253228; Wed, 09 Dec 2020 16:04:06 +0800 Received: from MTKCAS06.mediatek.inc (172.21.101.30) by mtkmbs07n1.mediatek.inc (172.21.101.16) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 9 Dec 2020 16:04:01 +0800 Received: from localhost.localdomain (10.17.3.153) by MTKCAS06.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Wed, 9 Dec 2020 16:04:04 +0800 From: Yong Wu To: Joerg Roedel , Matthias Brugger , Rob Herring , Will Deacon , Robin Murphy CC: Krzysztof Kozlowski , Evan Green , Tomasz Figa , , , , , , , , , Nicolas Boichat , , Subject: [PATCH v5 18/27] iommu/mediatek: Add power-domain operation Date: Wed, 9 Dec 2020 16:00:53 +0800 Message-ID: <20201209080102.26626-19-yong.wu@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20201209080102.26626-1-yong.wu@mediatek.com> References: <20201209080102.26626-1-yong.wu@mediatek.com> MIME-Version: 1.0 Content-Type: text/plain X-MTK: N Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In the previous SoC, the M4U HW is in the EMI power domain which is always on. the latest M4U is in the display power domain which may be turned on/off, thus we have to add pm_runtime interface for it. When the engine work, the engine always enable the power and clocks for smi-larb/smi-common, then the M4U's power will always be powered on automatically via the device link with smi-common. Note: we don't enable the M4U power in iommu_map/unmap for tlb flush. If its power already is on, of course it is ok. if the power is off, the main tlb will be reset while M4U power on, thus the tlb flush while m4u power off is unnecessary, just skip it. There will be one case that pm runctime status is not expected when tlb flush. After boot, the display may call dma_alloc_attrs before it call pm_runtime_get(disp-dev), then the m4u's pm status is not active inside the dma_alloc_attrs. Since it only happens after boot, the tlb is clean at that time, I also think this is ok. Signed-off-by: Yong Wu --- drivers/iommu/mtk_iommu.c | 41 +++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index 6fe3ee2b2bf5..0e9c03cbab32 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -184,6 +184,8 @@ static void mtk_iommu_tlb_flush_all(void *cookie) struct mtk_iommu_data *data = cookie; for_each_m4u(data) { + if (!pm_runtime_active(data->dev)) + continue; writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0, data->base + data->plat_data->inv_sel_reg); writel_relaxed(F_ALL_INVLD, data->base + REG_MMU_INVALIDATE); @@ -200,6 +202,10 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size, u32 tmp; for_each_m4u(data) { + /* skip tlb flush when pm is not active. */ + if (!pm_runtime_active(data->dev)) + continue; + spin_lock_irqsave(&data->tlb_lock, flags); writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0, data->base + data->plat_data->inv_sel_reg); @@ -384,6 +390,8 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain, { struct mtk_iommu_data *data = dev_iommu_priv_get(dev); struct mtk_iommu_domain *dom = to_mtk_domain(domain); + struct device *m4udev = data->dev; + bool pm_enabled = pm_runtime_enabled(m4udev); int ret; if (!data) @@ -391,12 +399,25 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain, /* Update the pgtable base address register of the M4U HW */ if (!data->m4u_dom) { + if (pm_enabled) { + ret = pm_runtime_get_sync(m4udev); + if (ret < 0) { + pm_runtime_put_noidle(m4udev); + return ret; + } + } ret = mtk_iommu_hw_init(data); - if (ret) + if (ret) { + if (pm_enabled) + pm_runtime_put(m4udev); return ret; + } data->m4u_dom = dom; writel(dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK, data->base + REG_MMU_PT_BASE_ADDR); + + if (pm_enabled) + pm_runtime_put(m4udev); } mtk_iommu_config(data, dev, true); @@ -747,10 +768,13 @@ static int mtk_iommu_probe(struct platform_device *pdev) if (dev->pm_domain) { struct device_link *link; + pm_runtime_enable(dev); + link = device_link_add(data->smicomm_dev, dev, DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME); if (!link) { dev_err(dev, "Unable link %s.\n", dev_name(data->smicomm_dev)); + pm_runtime_disable(dev); return -EINVAL; } } @@ -785,8 +809,10 @@ static int mtk_iommu_probe(struct platform_device *pdev) out_sysfs_remove: iommu_device_sysfs_remove(&data->iommu); out_link_remove: - if (dev->pm_domain) + if (dev->pm_domain) { device_link_remove(data->smicomm_dev, dev); + pm_runtime_disable(dev); + } return ret; } @@ -801,8 +827,10 @@ static int mtk_iommu_remove(struct platform_device *pdev) bus_set_iommu(&platform_bus_type, NULL); clk_disable_unprepare(data->bclk); - if (pdev->dev.pm_domain) + if (pdev->dev.pm_domain) { device_link_remove(data->smicomm_dev, &pdev->dev); + pm_runtime_disable(&pdev->dev); + } devm_free_irq(&pdev->dev, data->irq, data); component_master_del(&pdev->dev, &mtk_iommu_com_ops); return 0; @@ -834,6 +862,9 @@ static int __maybe_unused mtk_iommu_runtime_resume(struct device *dev) void __iomem *base = data->base; int ret; + /* Avoid first resume to affect the default value of registers below. */ + if (!m4u_dom) + return 0; ret = clk_prepare_enable(data->bclk); if (ret) { dev_err(data->dev, "Failed to enable clk(%d) in resume\n", ret); @@ -847,9 +878,7 @@ static int __maybe_unused mtk_iommu_runtime_resume(struct device *dev) writel_relaxed(reg->int_main_control, base + REG_MMU_INT_MAIN_CONTROL); writel_relaxed(reg->ivrp_paddr, base + REG_MMU_IVRP_PADDR); writel_relaxed(reg->vld_pa_rng, base + REG_MMU_VLD_PA_RNG); - if (m4u_dom) - writel(m4u_dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK, - base + REG_MMU_PT_BASE_ADDR); + writel(m4u_dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK, base + REG_MMU_PT_BASE_ADDR); return 0; } -- 2.18.0