Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp1253029pxk; Thu, 10 Sep 2020 10:41:03 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwB8CFLE/XQl+T9bXyv8fh9VNRUEmjsiiOMbRTj7fWuutuMx0PVrae9qSvH1l+uGsaNIZdt X-Received: by 2002:a17:906:556:: with SMTP id k22mr9791080eja.369.1599759663213; Thu, 10 Sep 2020 10:41:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1599759663; cv=none; d=google.com; s=arc-20160816; b=UTP1+J/OS8qLgkEIufaMdP6usJCUOZ5v7QOc5a63EMKr/vr25k+IwSYAUy/Fnp7aYF zVBQDryUYpN5S8vj0Xw2YUowe8Zc3GsZoCbolsZubQiCg1lhAlCGccsf0QBEmwtxtpg+ +sjWeKSMpyQqey3N5vTJg+eLewiozq1wrKcmABoZhhNIiZvY0EQwlasu1UYmq+2rMjqV 9nXJ9sRjxfUrWwa/AWgd2kjk4wWVVjAH6hqitdm5C8GQ3G7pGBOzwl01mKvBu001bukb W/w8x4K3nbLBCVAtJ9knE4BH8RkV4IKPLLtl4mQcgepQSBWhtlqV+A+fcb2YPG6D/UgC eE6g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=VKnV4uO7QUAu3J7woAFqvNCPOYRaQx4SYQkGaxvoYmM=; b=xqM0TxlGGnA289SjXwsLGut7Y7tOjk9/JO/EelLnzSKnOWxBELYyNTyf/woJQZe0Lr zApdd6MokXRWgyX1/X3AVRsdrm6FJLxGNGnHPNhsDRxdoZydsP0QfLsJeCtIHc9z71tf 5rpBj5ARtYZOHgkGje4XjHG13GWh9xqiOU/ymAP03grbTD2Td+AYvBlvzGjj/17XvEN4 mniP5QSAfFtS1lgMRnEuaP3nwu6zQKnwXwzv/8f4gJ5fFMLTC1xBfR4qtY8YB1WIjemy mTVoWi12x0DvCivKwlkUljlc/JwTKWmeKSxCKAuo89YrceIXw+WlNsHYpxJtVGKAI4SR PQIg== 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=collabora.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id ck10si3941821ejb.167.2020.09.10.10.40.40; Thu, 10 Sep 2020 10:41:03 -0700 (PDT) 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=collabora.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727099AbgIJRfk (ORCPT + 99 others); Thu, 10 Sep 2020 13:35:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56068 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727797AbgIJR2s (ORCPT ); Thu, 10 Sep 2020 13:28:48 -0400 Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E2A4CC061757 for ; Thu, 10 Sep 2020 10:28:47 -0700 (PDT) Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: eballetbo) with ESMTPSA id CB2F829BB11 From: Enric Balletbo i Serra To: linux-kernel@vger.kernel.org Cc: Collabora Kernel ML , fparent@baylibre.com, matthias.bgg@gmail.com, drinkcat@chromium.org, hsinyi@chromium.org, weiyi.lu@mediatek.com, Matthias Brugger , linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org Subject: [PATCH 08/12] soc: mediatek: pm-domains: Add subsystem clocks Date: Thu, 10 Sep 2020 19:28:22 +0200 Message-Id: <20200910172826.3074357-9-enric.balletbo@collabora.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200910172826.3074357-1-enric.balletbo@collabora.com> References: <20200910172826.3074357-1-enric.balletbo@collabora.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Matthias Brugger For the bus protection operations, some subsystem clocks need to be enabled before releasing the protection. This patch identifies the subsystem clocks by it's name. Suggested-by: Weiyi Lu [Adapted the patch to the mtk-pm-domains driver] Signed-off-by: Matthias Brugger Signed-off-by: Enric Balletbo i Serra --- drivers/soc/mediatek/mtk-pm-domains.c | 82 +++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 12 deletions(-) diff --git a/drivers/soc/mediatek/mtk-pm-domains.c b/drivers/soc/mediatek/mtk-pm-domains.c index 0802eccc3a0b..52a93a87e313 100644 --- a/drivers/soc/mediatek/mtk-pm-domains.c +++ b/drivers/soc/mediatek/mtk-pm-domains.c @@ -3,6 +3,7 @@ * Copyright (c) 2020 Collabora Ltd. */ #include +#include #include #include #include @@ -81,6 +82,8 @@ struct scpsys_bus_prot_data { bool bus_prot_reg_update; }; +#define MAX_SUBSYS_CLKS 10 + /** * struct scpsys_domain_data - scp domain data for power on/off flow * @sta_mask: The mask for power on/off status bit. @@ -107,6 +110,8 @@ struct scpsys_domain { struct scpsys *scpsys; int num_clks; struct clk_bulk_data *clks; + int num_subsys_clks; + struct clk_bulk_data *subsys_clks; struct regmap *infracfg; struct regmap *smi; }; @@ -309,16 +314,22 @@ static int scpsys_power_on(struct generic_pm_domain *genpd) val |= PWR_RST_B_BIT; writel(val, ctl_addr); + ret = clk_bulk_enable(pd->num_subsys_clks, pd->subsys_clks); + if (ret) + goto err_pwr_ack; + ret = scpsys_sram_enable(pd, ctl_addr); if (ret < 0) - goto err_pwr_ack; + goto err_sram; ret = scpsys_bus_protect_disable(pd); if (ret < 0) - goto err_pwr_ack; + goto err_sram; return 0; +err_sram: + clk_bulk_disable(pd->num_subsys_clks, pd->subsys_clks); err_pwr_ack: clk_bulk_disable(pd->num_clks, pd->clks); dev_err(scpsys->dev, "Failed to power on domain %s\n", genpd->name); @@ -342,6 +353,8 @@ static int scpsys_power_off(struct generic_pm_domain *genpd) if (ret < 0) return ret; + clk_bulk_disable(pd->num_subsys_clks, pd->subsys_clks); + /* subsys power off */ val = readl(ctl_addr); val |= PWR_ISO_BIT; @@ -374,8 +387,11 @@ static int scpsys_add_one_domain(struct scpsys *scpsys, struct device_node *node { const struct scpsys_domain_data *domain_data; struct scpsys_domain *pd; - int i, ret; + int i, ret, num_clks; u32 id; + int clk_ind = 0; + struct property *prop; + const char *clk_name; ret = of_property_read_u32(node, "reg", &id); if (ret) { @@ -410,28 +426,60 @@ static int scpsys_add_one_domain(struct scpsys *scpsys, struct device_node *node if (IS_ERR(pd->smi)) pd->smi = NULL; - pd->num_clks = of_clk_get_parent_count(node); - if (pd->num_clks > 0) { + num_clks = of_clk_get_parent_count(node); + if (num_clks > 0) { + /* Calculate number of subsys_clks */ + of_property_for_each_string(node, "clock-names", prop, clk_name) { + char *subsys; + + subsys = strchr(clk_name, '-'); + if (subsys) + pd->num_subsys_clks++; + else + pd->num_clks++; + } + pd->clks = devm_kcalloc(scpsys->dev, pd->num_clks, sizeof(*pd->clks), GFP_KERNEL); if (!pd->clks) return -ENOMEM; - } else { - pd->num_clks = 0; + + pd->subsys_clks = devm_kcalloc(scpsys->dev, pd->num_subsys_clks, + sizeof(*pd->subsys_clks), GFP_KERNEL); + if (!pd->subsys_clks) + return -ENOMEM; } for (i = 0; i < pd->num_clks; i++) { - pd->clks[i].clk = of_clk_get(node, i); - if (IS_ERR(pd->clks[i].clk)) { - ret = PTR_ERR(pd->clks[i].clk); + struct clk *clk = of_clk_get(node, i); + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); dev_err(scpsys->dev, "%pOFn: failed to get clk at index %d: %d\n", node, i, ret); - return ret; + goto err_put_clocks; + } + + pd->clks[clk_ind++].clk = clk; + } + + for (i = 0; i < pd->num_subsys_clks; i++) { + struct clk *clk = of_clk_get(node, i + clk_ind); + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + dev_err(scpsys->dev, "%pOFn: failed to get clk at index %d: %d\n", node, + i + clk_ind, ret); + goto err_put_subsys_clocks; } + + pd->subsys_clks[i].clk = clk; } + ret = clk_bulk_prepare(pd->num_subsys_clks, pd->subsys_clks); + if (ret) + goto err_put_subsys_clocks; + ret = clk_bulk_prepare(pd->num_clks, pd->clks); if (ret) - goto err_put_clocks; + goto err_unprepare_subsys_clocks; /* * Initially turn on all domains to make the domains usable @@ -456,6 +504,12 @@ static int scpsys_add_one_domain(struct scpsys *scpsys, struct device_node *node err_unprepare_clocks: clk_bulk_unprepare(pd->num_clks, pd->clks); +err_unprepare_subsys_clocks: + clk_bulk_unprepare(pd->num_subsys_clks, pd->subsys_clks); +err_put_subsys_clocks: + clk_bulk_put(pd->num_subsys_clks, pd->subsys_clks); + devm_kfree(scpsys->dev, pd->subsys_clks); + pd->num_subsys_clks = 0; err_put_clocks: clk_bulk_put(pd->num_clks, pd->clks); devm_kfree(scpsys->dev, pd->clks); @@ -537,6 +591,10 @@ static void scpsys_remove_one_domain(struct scpsys_domain *pd) clk_bulk_unprepare(pd->num_clks, pd->clks); clk_bulk_put(pd->num_clks, pd->clks); pd->num_clks = 0; + + clk_bulk_unprepare(pd->num_subsys_clks, pd->subsys_clks); + clk_bulk_put(pd->num_subsys_clks, pd->subsys_clks); + pd->num_subsys_clks = 0; } static void scpsys_domain_cleanup(struct scpsys *scpsys) -- 2.28.0