From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 04BA6C433EF for ; Thu, 5 May 2022 11:53:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1358941AbiEEL46 (ORCPT ); Thu, 5 May 2022 07:56:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60634 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1358670AbiEEL43 (ORCPT ); Thu, 5 May 2022 07:56:29 -0400 Received: from mailgw02.mediatek.com (unknown [210.61.82.184]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C72815469C; Thu, 5 May 2022 04:52:48 -0700 (PDT) X-UUID: 1143234bec89487d9d41e1daf9675a83-20220505 X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.4,REQID:5c8e7b02-c2d2-47e7-ae2e-d3711975558f,OB:10,L OB:10,IP:0,URL:0,TC:0,Content:-20,EDM:0,RT:0,SF:95,FILE:0,RULE:Release_Ham ,ACTION:release,TS:75 X-CID-INFO: VERSION:1.1.4,REQID:5c8e7b02-c2d2-47e7-ae2e-d3711975558f,OB:10,LOB :10,IP:0,URL:0,TC:0,Content:-20,EDM:0,RT:0,SF:95,FILE:0,RULE:Spam_GS981B3D ,ACTION:quarantine,TS:75 X-CID-META: VersionHash:faefae9,CLOUDID:0f94b1b2-56b5-4c9e-8d83-0070b288eb6a,C OID:8e0daa05eee3,Recheck:0,SF:28|17|19|48,TC:nil,Content:0,EDM:-3,File:nil ,QS:0,BEC:nil X-UUID: 1143234bec89487d9d41e1daf9675a83-20220505 Received: from mtkcas10.mediatek.inc [(172.21.101.39)] by mailgw02.mediatek.com (envelope-from ) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 686251714; Thu, 05 May 2022 19:52:36 +0800 Received: from mtkmbs07n1.mediatek.inc (172.21.101.16) by mtkmbs11n2.mediatek.inc (172.21.101.187) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.2.792.3; Thu, 5 May 2022 19:52:35 +0800 Received: from mtkcas10.mediatek.inc (172.21.101.39) by mtkmbs07n1.mediatek.inc (172.21.101.16) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 5 May 2022 19:52:35 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas10.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 5 May 2022 19:52:34 +0800 From: Rex-BC Chen To: , , , , CC: , , , , , , , , , , , Rex-BC Chen Subject: [PATCH v6 06/10] cpufreq: mediatek: Link CCI device to CPU Date: Thu, 5 May 2022 19:52:22 +0800 Message-ID: <20220505115226.20130-7-rex-bc.chen@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20220505115226.20130-1-rex-bc.chen@mediatek.com> References: <20220505115226.20130-1-rex-bc.chen@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 some MediaTek SoCs, like MT8183, CPU and CCI share the same power supplies. Cpufreq needs to check if CCI devfreq exists and wait until CCI devfreq ready before scaling frequency. Before CCI devfreq is ready, we record the voltage when booting to kernel and use the max(cpu target voltage, booting voltage) to prevent cpufreq adjust to the lower voltage which will cause the CCI crash because of high frequency and low voltage. - Add is_ccifreq_ready() to link CCI device to CPI, and CPU will start DVFS when CCI is ready. - Add platform data for MT8183. Signed-off-by: Jia-Wei Chang Signed-off-by: Rex-BC Chen Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Kevin Hilman --- drivers/cpufreq/mediatek-cpufreq.c | 82 +++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c index 06d80ee06bbf..5fd3c88c2a82 100644 --- a/drivers/cpufreq/mediatek-cpufreq.c +++ b/drivers/cpufreq/mediatek-cpufreq.c @@ -22,6 +22,7 @@ struct mtk_cpufreq_platform_data { int proc_max_volt; int sram_min_volt; int sram_max_volt; + bool ccifreq_supported; }; /* @@ -38,6 +39,7 @@ struct mtk_cpufreq_platform_data { struct mtk_cpu_dvfs_info { struct cpumask cpus; struct device *cpu_dev; + struct device *cci_dev; struct regulator *proc_reg; struct regulator *sram_reg; struct clk *cpu_clk; @@ -45,6 +47,7 @@ struct mtk_cpu_dvfs_info { struct list_head list_head; int intermediate_voltage; bool need_voltage_tracking; + int vproc_on_boot; int pre_vproc; /* Avoid race condition for regulators between notify and policy */ struct mutex reg_lock; @@ -53,6 +56,7 @@ struct mtk_cpu_dvfs_info { unsigned long opp_freq; const struct mtk_cpufreq_platform_data *soc_data; int vtrack_max; + bool ccifreq_bound; }; static struct platform_device *cpufreq_pdev; @@ -171,6 +175,28 @@ static int mtk_cpufreq_set_voltage(struct mtk_cpu_dvfs_info *info, int vproc) return ret; } +static bool is_ccifreq_ready(struct mtk_cpu_dvfs_info *info) +{ + struct device_link *sup_link; + + if (info->ccifreq_bound) + return true; + + sup_link = device_link_add(info->cpu_dev, info->cci_dev, + DL_FLAG_AUTOREMOVE_CONSUMER); + if (!sup_link) { + dev_err(info->cpu_dev, "cpu%d: sup_link is NULL\n", info->opp_cpu); + return false; + } + + if (sup_link->supplier->links.status != DL_DEV_DRIVER_BOUND) + return false; + + info->ccifreq_bound = true; + + return true; +} + static int mtk_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index) { @@ -210,6 +236,14 @@ static int mtk_cpufreq_set_target(struct cpufreq_policy *policy, vproc = dev_pm_opp_get_voltage(opp); dev_pm_opp_put(opp); + /* + * If MediaTek cci is supported but is not ready, we will use the value + * of max(target cpu voltage, booting voltage) to prevent high freqeuncy + * low voltage crash. + */ + if (info->soc_data->ccifreq_supported && !is_ccifreq_ready(info)) + vproc = max(vproc, info->vproc_on_boot); + /* * If the new voltage or the intermediate voltage is higher than the * current voltage, scale up voltage first. @@ -331,6 +365,23 @@ static int mtk_cpufreq_opp_notifier(struct notifier_block *nb, return notifier_from_errno(ret); } +static struct device *of_get_cci(struct device *cpu_dev) +{ + struct device_node *np; + struct platform_device *pdev; + + np = of_parse_phandle(cpu_dev->of_node, "mediatek,cci", 0); + if (IS_ERR_OR_NULL(np)) + return NULL; + + pdev = of_find_device_by_node(np); + of_node_put(np); + if (IS_ERR_OR_NULL(pdev)) + return NULL; + + return &pdev->dev; +} + static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu) { struct device *cpu_dev; @@ -345,6 +396,16 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu) } info->cpu_dev = cpu_dev; + info->ccifreq_bound = false; + if (info->soc_data->ccifreq_supported) { + info->cci_dev = of_get_cci(info->cpu_dev); + if (IS_ERR_OR_NULL(info->cci_dev)) { + ret = PTR_ERR(info->cci_dev); + dev_err(cpu_dev, "cpu%d: failed to get cci device\n", cpu); + return -ENODEV; + } + } + info->cpu_clk = clk_get(cpu_dev, "cpu"); if (IS_ERR(info->cpu_clk)) { ret = PTR_ERR(info->cpu_clk); @@ -408,6 +469,15 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu) if (ret) goto out_disable_mux_clock; + if (info->soc_data->ccifreq_supported) { + info->vproc_on_boot = regulator_get_voltage(info->proc_reg); + if (info->vproc_on_boot < 0) { + dev_err(info->cpu_dev, + "invalid Vproc value: %d\n", info->vproc_on_boot); + goto out_disable_inter_clock; + } + } + /* Search a safe voltage for intermediate frequency. */ rate = clk_get_rate(info->inter_clk); opp = dev_pm_opp_find_freq_ceil(cpu_dev, &rate); @@ -616,6 +686,16 @@ static const struct mtk_cpufreq_platform_data mt2701_platform_data = { .proc_max_volt = 1150000, .sram_min_volt = 0, .sram_max_volt = 1150000, + .ccifreq_supported = false, +}; + +static const struct mtk_cpufreq_platform_data mt8183_platform_data = { + .min_volt_shift = 100000, + .max_volt_shift = 200000, + .proc_max_volt = 1150000, + .sram_min_volt = 0, + .sram_max_volt = 1150000, + .ccifreq_supported = true, }; /* List of machines supported by this driver */ @@ -628,7 +708,7 @@ static const struct of_device_id mtk_cpufreq_machines[] __initconst = { { .compatible = "mediatek,mt817x", .data = &mt2701_platform_data }, { .compatible = "mediatek,mt8173", .data = &mt2701_platform_data }, { .compatible = "mediatek,mt8176", .data = &mt2701_platform_data }, - { .compatible = "mediatek,mt8183", .data = &mt2701_platform_data }, + { .compatible = "mediatek,mt8183", .data = &mt8183_platform_data }, { .compatible = "mediatek,mt8365", .data = &mt2701_platform_data }, { .compatible = "mediatek,mt8516", .data = &mt2701_platform_data }, { } -- 2.18.0 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 29EE7C433FE for ; Thu, 5 May 2022 12:06:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=4HFYMcU7AYlWbjVcleBuovKlTFL5tQn54ZdEgNjwbiU=; b=Bx3Iq8t90sf6Y0 Z7AGl1hFdAJjWafv6kZAs9LJCRKFgcv4M2W2BRHScPfYobNdcXwxQBWvjRsXekIQLTjB1ix2QvbKY u3qcVqk2m9WKD5dXm8QjL5p71JN6WyA72r4XImIhpq0sU0NJEH06WadrAPUMcR0CSbNiV2V5IJr2u +BSmdkL0zM0oRFqZlsynqoRehcRL8LBmysBqz8oX91Us93Pic6syxrTm1RdUAIGhneHc+JUNj8Rbq op5whDFnoElBghowzsw0rUxw7FwP+xq2ztR0dZKLzKk6xq08wN1nOTYYQ7Ft/xg7BNx1uXHEWOeFd m1df/9gMLxyMflbAJLCQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nmaFd-00Fg4N-DB; Thu, 05 May 2022 12:06:33 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nmaC4-00Fdp1-1y; Thu, 05 May 2022 12:02:53 +0000 X-UUID: 5ce2052297504f688547a333cf27f6e1-20220505 X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.4, REQID:9d95cc02-545a-4e29-98cb-17c0095834f1, OB:0, LO B:0,IP:0,URL:0,TC:0,Content:-20,EDM:0,RT:0,SF:0,FILE:0,RULE:Release_Ham,AC TION:release,TS:-20 X-CID-META: VersionHash:faefae9, CLOUDID:9bc8b1b2-56b5-4c9e-8d83-0070b288eb6a, C OID:IGNORED,Recheck:0,SF:nil,TC:nil,Content:0,EDM:-3,File:nil,QS:0,BEC:nil X-UUID: 5ce2052297504f688547a333cf27f6e1-20220505 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 40620851; Thu, 05 May 2022 05:02:38 -0700 Received: from mtkmbs07n1.mediatek.inc (172.21.101.16) by MTKMBS62N1.mediatek.inc (172.29.193.41) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 5 May 2022 04:52:38 -0700 Received: from mtkcas10.mediatek.inc (172.21.101.39) by mtkmbs07n1.mediatek.inc (172.21.101.16) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 5 May 2022 19:52:35 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas10.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 5 May 2022 19:52:34 +0800 From: Rex-BC Chen To: , , , , CC: , , , , , , , , , , , Rex-BC Chen Subject: [PATCH v6 06/10] cpufreq: mediatek: Link CCI device to CPU Date: Thu, 5 May 2022 19:52:22 +0800 Message-ID: <20220505115226.20130-7-rex-bc.chen@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20220505115226.20130-1-rex-bc.chen@mediatek.com> References: <20220505115226.20130-1-rex-bc.chen@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220505_050252_161929_0FCA7E68 X-CRM114-Status: GOOD ( 21.93 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org In some MediaTek SoCs, like MT8183, CPU and CCI share the same power supplies. Cpufreq needs to check if CCI devfreq exists and wait until CCI devfreq ready before scaling frequency. Before CCI devfreq is ready, we record the voltage when booting to kernel and use the max(cpu target voltage, booting voltage) to prevent cpufreq adjust to the lower voltage which will cause the CCI crash because of high frequency and low voltage. - Add is_ccifreq_ready() to link CCI device to CPI, and CPU will start DVFS when CCI is ready. - Add platform data for MT8183. Signed-off-by: Jia-Wei Chang Signed-off-by: Rex-BC Chen Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Kevin Hilman --- drivers/cpufreq/mediatek-cpufreq.c | 82 +++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c index 06d80ee06bbf..5fd3c88c2a82 100644 --- a/drivers/cpufreq/mediatek-cpufreq.c +++ b/drivers/cpufreq/mediatek-cpufreq.c @@ -22,6 +22,7 @@ struct mtk_cpufreq_platform_data { int proc_max_volt; int sram_min_volt; int sram_max_volt; + bool ccifreq_supported; }; /* @@ -38,6 +39,7 @@ struct mtk_cpufreq_platform_data { struct mtk_cpu_dvfs_info { struct cpumask cpus; struct device *cpu_dev; + struct device *cci_dev; struct regulator *proc_reg; struct regulator *sram_reg; struct clk *cpu_clk; @@ -45,6 +47,7 @@ struct mtk_cpu_dvfs_info { struct list_head list_head; int intermediate_voltage; bool need_voltage_tracking; + int vproc_on_boot; int pre_vproc; /* Avoid race condition for regulators between notify and policy */ struct mutex reg_lock; @@ -53,6 +56,7 @@ struct mtk_cpu_dvfs_info { unsigned long opp_freq; const struct mtk_cpufreq_platform_data *soc_data; int vtrack_max; + bool ccifreq_bound; }; static struct platform_device *cpufreq_pdev; @@ -171,6 +175,28 @@ static int mtk_cpufreq_set_voltage(struct mtk_cpu_dvfs_info *info, int vproc) return ret; } +static bool is_ccifreq_ready(struct mtk_cpu_dvfs_info *info) +{ + struct device_link *sup_link; + + if (info->ccifreq_bound) + return true; + + sup_link = device_link_add(info->cpu_dev, info->cci_dev, + DL_FLAG_AUTOREMOVE_CONSUMER); + if (!sup_link) { + dev_err(info->cpu_dev, "cpu%d: sup_link is NULL\n", info->opp_cpu); + return false; + } + + if (sup_link->supplier->links.status != DL_DEV_DRIVER_BOUND) + return false; + + info->ccifreq_bound = true; + + return true; +} + static int mtk_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index) { @@ -210,6 +236,14 @@ static int mtk_cpufreq_set_target(struct cpufreq_policy *policy, vproc = dev_pm_opp_get_voltage(opp); dev_pm_opp_put(opp); + /* + * If MediaTek cci is supported but is not ready, we will use the value + * of max(target cpu voltage, booting voltage) to prevent high freqeuncy + * low voltage crash. + */ + if (info->soc_data->ccifreq_supported && !is_ccifreq_ready(info)) + vproc = max(vproc, info->vproc_on_boot); + /* * If the new voltage or the intermediate voltage is higher than the * current voltage, scale up voltage first. @@ -331,6 +365,23 @@ static int mtk_cpufreq_opp_notifier(struct notifier_block *nb, return notifier_from_errno(ret); } +static struct device *of_get_cci(struct device *cpu_dev) +{ + struct device_node *np; + struct platform_device *pdev; + + np = of_parse_phandle(cpu_dev->of_node, "mediatek,cci", 0); + if (IS_ERR_OR_NULL(np)) + return NULL; + + pdev = of_find_device_by_node(np); + of_node_put(np); + if (IS_ERR_OR_NULL(pdev)) + return NULL; + + return &pdev->dev; +} + static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu) { struct device *cpu_dev; @@ -345,6 +396,16 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu) } info->cpu_dev = cpu_dev; + info->ccifreq_bound = false; + if (info->soc_data->ccifreq_supported) { + info->cci_dev = of_get_cci(info->cpu_dev); + if (IS_ERR_OR_NULL(info->cci_dev)) { + ret = PTR_ERR(info->cci_dev); + dev_err(cpu_dev, "cpu%d: failed to get cci device\n", cpu); + return -ENODEV; + } + } + info->cpu_clk = clk_get(cpu_dev, "cpu"); if (IS_ERR(info->cpu_clk)) { ret = PTR_ERR(info->cpu_clk); @@ -408,6 +469,15 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu) if (ret) goto out_disable_mux_clock; + if (info->soc_data->ccifreq_supported) { + info->vproc_on_boot = regulator_get_voltage(info->proc_reg); + if (info->vproc_on_boot < 0) { + dev_err(info->cpu_dev, + "invalid Vproc value: %d\n", info->vproc_on_boot); + goto out_disable_inter_clock; + } + } + /* Search a safe voltage for intermediate frequency. */ rate = clk_get_rate(info->inter_clk); opp = dev_pm_opp_find_freq_ceil(cpu_dev, &rate); @@ -616,6 +686,16 @@ static const struct mtk_cpufreq_platform_data mt2701_platform_data = { .proc_max_volt = 1150000, .sram_min_volt = 0, .sram_max_volt = 1150000, + .ccifreq_supported = false, +}; + +static const struct mtk_cpufreq_platform_data mt8183_platform_data = { + .min_volt_shift = 100000, + .max_volt_shift = 200000, + .proc_max_volt = 1150000, + .sram_min_volt = 0, + .sram_max_volt = 1150000, + .ccifreq_supported = true, }; /* List of machines supported by this driver */ @@ -628,7 +708,7 @@ static const struct of_device_id mtk_cpufreq_machines[] __initconst = { { .compatible = "mediatek,mt817x", .data = &mt2701_platform_data }, { .compatible = "mediatek,mt8173", .data = &mt2701_platform_data }, { .compatible = "mediatek,mt8176", .data = &mt2701_platform_data }, - { .compatible = "mediatek,mt8183", .data = &mt2701_platform_data }, + { .compatible = "mediatek,mt8183", .data = &mt8183_platform_data }, { .compatible = "mediatek,mt8365", .data = &mt2701_platform_data }, { .compatible = "mediatek,mt8516", .data = &mt2701_platform_data }, { } -- 2.18.0 _______________________________________________ Linux-mediatek mailing list Linux-mediatek@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-mediatek From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0F32DC433EF for ; Thu, 5 May 2022 12:07:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=YihqSXTFIw4mvMEQKzWcst84k0txsRUHA3sIN1vPAHI=; b=UnvlrXnD+/0v8I nNTMHc3wbrHvVwEhMYCWLxvhdxlpNe0p/Io8smCpEyEjQOrG/XcNzWD3d1S+VHQGwb38myPufuZ0A MSxvnZejfDeXMf/hl5de1EAWjoWJYjyOCFjhSXHkOVhVBxo2/9o0+gGeWEstf8sb9A9sYiXH9Q2Hg +QdSzd2cVOWl/Ml9l/CCNZcKJadViRnssU7dTfgzctNJ8+F1O1Q4hLtxSUcxIGeUiqXYN/hMR8YjQ LrBI5VVPgZ3X/B4idzQ9uepqbBHStIbLVdirjQYhYsgf9g/kO6jw9kS7RSKQIpCwONN9AZjs59+VZ XETE7NsDxhTCS8CrATzg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nmaFK-00Ffsp-Vo; Thu, 05 May 2022 12:06:15 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nmaC4-00Fdp1-1y; Thu, 05 May 2022 12:02:53 +0000 X-UUID: 5ce2052297504f688547a333cf27f6e1-20220505 X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.4, REQID:9d95cc02-545a-4e29-98cb-17c0095834f1, OB:0, LO B:0,IP:0,URL:0,TC:0,Content:-20,EDM:0,RT:0,SF:0,FILE:0,RULE:Release_Ham,AC TION:release,TS:-20 X-CID-META: VersionHash:faefae9, CLOUDID:9bc8b1b2-56b5-4c9e-8d83-0070b288eb6a, C OID:IGNORED,Recheck:0,SF:nil,TC:nil,Content:0,EDM:-3,File:nil,QS:0,BEC:nil X-UUID: 5ce2052297504f688547a333cf27f6e1-20220505 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 40620851; Thu, 05 May 2022 05:02:38 -0700 Received: from mtkmbs07n1.mediatek.inc (172.21.101.16) by MTKMBS62N1.mediatek.inc (172.29.193.41) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 5 May 2022 04:52:38 -0700 Received: from mtkcas10.mediatek.inc (172.21.101.39) by mtkmbs07n1.mediatek.inc (172.21.101.16) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 5 May 2022 19:52:35 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas10.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 5 May 2022 19:52:34 +0800 From: Rex-BC Chen To: , , , , CC: , , , , , , , , , , , Rex-BC Chen Subject: [PATCH v6 06/10] cpufreq: mediatek: Link CCI device to CPU Date: Thu, 5 May 2022 19:52:22 +0800 Message-ID: <20220505115226.20130-7-rex-bc.chen@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20220505115226.20130-1-rex-bc.chen@mediatek.com> References: <20220505115226.20130-1-rex-bc.chen@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220505_050252_161929_0FCA7E68 X-CRM114-Status: GOOD ( 21.93 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org In some MediaTek SoCs, like MT8183, CPU and CCI share the same power supplies. Cpufreq needs to check if CCI devfreq exists and wait until CCI devfreq ready before scaling frequency. Before CCI devfreq is ready, we record the voltage when booting to kernel and use the max(cpu target voltage, booting voltage) to prevent cpufreq adjust to the lower voltage which will cause the CCI crash because of high frequency and low voltage. - Add is_ccifreq_ready() to link CCI device to CPI, and CPU will start DVFS when CCI is ready. - Add platform data for MT8183. Signed-off-by: Jia-Wei Chang Signed-off-by: Rex-BC Chen Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Kevin Hilman --- drivers/cpufreq/mediatek-cpufreq.c | 82 +++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c index 06d80ee06bbf..5fd3c88c2a82 100644 --- a/drivers/cpufreq/mediatek-cpufreq.c +++ b/drivers/cpufreq/mediatek-cpufreq.c @@ -22,6 +22,7 @@ struct mtk_cpufreq_platform_data { int proc_max_volt; int sram_min_volt; int sram_max_volt; + bool ccifreq_supported; }; /* @@ -38,6 +39,7 @@ struct mtk_cpufreq_platform_data { struct mtk_cpu_dvfs_info { struct cpumask cpus; struct device *cpu_dev; + struct device *cci_dev; struct regulator *proc_reg; struct regulator *sram_reg; struct clk *cpu_clk; @@ -45,6 +47,7 @@ struct mtk_cpu_dvfs_info { struct list_head list_head; int intermediate_voltage; bool need_voltage_tracking; + int vproc_on_boot; int pre_vproc; /* Avoid race condition for regulators between notify and policy */ struct mutex reg_lock; @@ -53,6 +56,7 @@ struct mtk_cpu_dvfs_info { unsigned long opp_freq; const struct mtk_cpufreq_platform_data *soc_data; int vtrack_max; + bool ccifreq_bound; }; static struct platform_device *cpufreq_pdev; @@ -171,6 +175,28 @@ static int mtk_cpufreq_set_voltage(struct mtk_cpu_dvfs_info *info, int vproc) return ret; } +static bool is_ccifreq_ready(struct mtk_cpu_dvfs_info *info) +{ + struct device_link *sup_link; + + if (info->ccifreq_bound) + return true; + + sup_link = device_link_add(info->cpu_dev, info->cci_dev, + DL_FLAG_AUTOREMOVE_CONSUMER); + if (!sup_link) { + dev_err(info->cpu_dev, "cpu%d: sup_link is NULL\n", info->opp_cpu); + return false; + } + + if (sup_link->supplier->links.status != DL_DEV_DRIVER_BOUND) + return false; + + info->ccifreq_bound = true; + + return true; +} + static int mtk_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index) { @@ -210,6 +236,14 @@ static int mtk_cpufreq_set_target(struct cpufreq_policy *policy, vproc = dev_pm_opp_get_voltage(opp); dev_pm_opp_put(opp); + /* + * If MediaTek cci is supported but is not ready, we will use the value + * of max(target cpu voltage, booting voltage) to prevent high freqeuncy + * low voltage crash. + */ + if (info->soc_data->ccifreq_supported && !is_ccifreq_ready(info)) + vproc = max(vproc, info->vproc_on_boot); + /* * If the new voltage or the intermediate voltage is higher than the * current voltage, scale up voltage first. @@ -331,6 +365,23 @@ static int mtk_cpufreq_opp_notifier(struct notifier_block *nb, return notifier_from_errno(ret); } +static struct device *of_get_cci(struct device *cpu_dev) +{ + struct device_node *np; + struct platform_device *pdev; + + np = of_parse_phandle(cpu_dev->of_node, "mediatek,cci", 0); + if (IS_ERR_OR_NULL(np)) + return NULL; + + pdev = of_find_device_by_node(np); + of_node_put(np); + if (IS_ERR_OR_NULL(pdev)) + return NULL; + + return &pdev->dev; +} + static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu) { struct device *cpu_dev; @@ -345,6 +396,16 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu) } info->cpu_dev = cpu_dev; + info->ccifreq_bound = false; + if (info->soc_data->ccifreq_supported) { + info->cci_dev = of_get_cci(info->cpu_dev); + if (IS_ERR_OR_NULL(info->cci_dev)) { + ret = PTR_ERR(info->cci_dev); + dev_err(cpu_dev, "cpu%d: failed to get cci device\n", cpu); + return -ENODEV; + } + } + info->cpu_clk = clk_get(cpu_dev, "cpu"); if (IS_ERR(info->cpu_clk)) { ret = PTR_ERR(info->cpu_clk); @@ -408,6 +469,15 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu) if (ret) goto out_disable_mux_clock; + if (info->soc_data->ccifreq_supported) { + info->vproc_on_boot = regulator_get_voltage(info->proc_reg); + if (info->vproc_on_boot < 0) { + dev_err(info->cpu_dev, + "invalid Vproc value: %d\n", info->vproc_on_boot); + goto out_disable_inter_clock; + } + } + /* Search a safe voltage for intermediate frequency. */ rate = clk_get_rate(info->inter_clk); opp = dev_pm_opp_find_freq_ceil(cpu_dev, &rate); @@ -616,6 +686,16 @@ static const struct mtk_cpufreq_platform_data mt2701_platform_data = { .proc_max_volt = 1150000, .sram_min_volt = 0, .sram_max_volt = 1150000, + .ccifreq_supported = false, +}; + +static const struct mtk_cpufreq_platform_data mt8183_platform_data = { + .min_volt_shift = 100000, + .max_volt_shift = 200000, + .proc_max_volt = 1150000, + .sram_min_volt = 0, + .sram_max_volt = 1150000, + .ccifreq_supported = true, }; /* List of machines supported by this driver */ @@ -628,7 +708,7 @@ static const struct of_device_id mtk_cpufreq_machines[] __initconst = { { .compatible = "mediatek,mt817x", .data = &mt2701_platform_data }, { .compatible = "mediatek,mt8173", .data = &mt2701_platform_data }, { .compatible = "mediatek,mt8176", .data = &mt2701_platform_data }, - { .compatible = "mediatek,mt8183", .data = &mt2701_platform_data }, + { .compatible = "mediatek,mt8183", .data = &mt8183_platform_data }, { .compatible = "mediatek,mt8365", .data = &mt2701_platform_data }, { .compatible = "mediatek,mt8516", .data = &mt2701_platform_data }, { } -- 2.18.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel