lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Wed, 13 Feb 2019 15:59:32 +0000
From:   Anson Huang <anson.huang@....com>
To:     "robh+dt@...nel.org" <robh+dt@...nel.org>,
        "mark.rutland@....com" <mark.rutland@....com>,
        "shawnguo@...nel.org" <shawnguo@...nel.org>,
        "s.hauer@...gutronix.de" <s.hauer@...gutronix.de>,
        "kernel@...gutronix.de" <kernel@...gutronix.de>,
        "festevam@...il.com" <festevam@...il.com>,
        "mturquette@...libre.com" <mturquette@...libre.com>,
        "sboyd@...nel.org" <sboyd@...nel.org>,
        Aisheng Dong <aisheng.dong@....com>,
        Daniel Baluta <daniel.baluta@....com>,
        "devicetree@...r.kernel.org" <devicetree@...r.kernel.org>,
        "linux-arm-kernel@...ts.infradead.org" 
        <linux-arm-kernel@...ts.infradead.org>,
        "linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
        "linux-clk@...r.kernel.org" <linux-clk@...r.kernel.org>,
        "viresh.kumar@...aro.org" <viresh.kumar@...aro.org>
CC:     dl-linux-imx <linux-imx@....com>
Subject: [PATCH V3 2/2] clk: imx: scu: add cpu frequency scaling support

On NXP's i.MX SoCs with system controller inside, CPU frequency
scaling can ONLY be done by system controller firmware, and it
can ONLY be requested from secure mode, so Linux kernel has to
call ARM SMC to trap to ARM-Trusted-Firmware to request system
controller firmware to do CPU frequency scaling.

This patch adds i.MX system controller CPU frequency scaling support,
it reuses cpufreq-dt driver and implement the CPU frequency scaling
inside SCU clock driver.

Signed-off-by: Anson Huang <Anson.Huang@....com>
---
Changes since V2:
	- remove ifdef CONFIG_CPUFREQ_DT as it is NOT that critical and has mistake in V2;
	- put the CPU clock check and SMC call in a separate function.
--
 drivers/clk/imx/clk-scu.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c
index 7ccf7ed..885bf33 100644
--- a/drivers/clk/imx/clk-scu.c
+++ b/drivers/clk/imx/clk-scu.c
@@ -4,14 +4,30 @@
  *   Dong Aisheng <aisheng.dong@....com>
  */
 
+#include <linux/arm-smccc.h>
 #include <linux/clk-provider.h>
 #include <linux/err.h>
 #include <linux/slab.h>
 
 #include "clk-scu.h"
 
+#define IMX_SIP_CPUFREQ			0xC2000001
+#define IMX_SIP_SET_CPUFREQ		0x00
+
 static struct imx_sc_ipc *ccm_ipc_handle;
 
+struct imx_sc_cpufreq {
+	const char *clk_name;
+	u32 cluster_id;
+};
+
+static const struct imx_sc_cpufreq imx_sc_cpufreq_data[] = {
+	{
+		.clk_name = "a35_clk",
+		.cluster_id = 0,
+	},
+};
+
 /*
  * struct clk_scu - Description of one SCU clock
  * @hw: the common clk_hw
@@ -145,6 +161,39 @@ static long clk_scu_round_rate(struct clk_hw *hw, unsigned long rate,
 	return rate;
 }
 
+static bool clk_scu_atf_set_cpu_rate(struct clk_hw *hw, unsigned long rate)
+{
+	struct clk_scu *clk = to_clk_scu(hw);
+	struct arm_smccc_res res;
+	unsigned int cluster_id;
+	int i;
+
+	/* CPU frequency scaling can ONLY be done by ARM-Trusted-Firmware */
+	if (clk->clk_type == IMX_SC_PM_CLK_CPU) {
+		for (i = 0; i < ARRAY_SIZE(imx_sc_cpufreq_data); i++) {
+			if (!strcmp(clk_hw_get_name(hw),
+				imx_sc_cpufreq_data[i].clk_name)) {
+				cluster_id = imx_sc_cpufreq_data[i].cluster_id;
+				break;
+			}
+		}
+
+		/*
+		 * As some other clock types have same value as
+		 * IMX_SC_PM_CLK_CPU, so we need to double check
+		 * the clock being scaled is indeed CPU clock which
+		 * matches the table we define.
+		 */
+		if (i < ARRAY_SIZE(imx_sc_cpufreq_data)) {
+			arm_smccc_smc(IMX_SIP_CPUFREQ, IMX_SIP_SET_CPUFREQ,
+				cluster_id, rate, 0, 0, 0, 0, &res);
+			return true;
+		}
+	}
+
+	return false;
+}
+
 /*
  * clk_scu_set_rate - Set rate for a SCU clock
  * @hw: clock to change rate for
@@ -161,6 +210,10 @@ static int clk_scu_set_rate(struct clk_hw *hw, unsigned long rate,
 	struct imx_sc_msg_req_set_clock_rate msg;
 	struct imx_sc_rpc_msg *hdr = &msg.hdr;
 
+	/* check if it is CPU frequency scaling */
+	if (clk_scu_atf_set_cpu_rate(hw, rate))
+		return 0;
+
 	hdr->ver = IMX_SC_RPC_VERSION;
 	hdr->svc = IMX_SC_RPC_SVC_PM;
 	hdr->func = IMX_SC_PM_FUNC_SET_CLOCK_RATE;
-- 
2.7.4

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ