cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

imx6q-cpufreq.c (14975B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) 2013 Freescale Semiconductor, Inc.
      4 */
      5
      6#include <linux/clk.h>
      7#include <linux/cpu.h>
      8#include <linux/cpufreq.h>
      9#include <linux/err.h>
     10#include <linux/module.h>
     11#include <linux/nvmem-consumer.h>
     12#include <linux/of.h>
     13#include <linux/of_address.h>
     14#include <linux/pm_opp.h>
     15#include <linux/platform_device.h>
     16#include <linux/regulator/consumer.h>
     17
     18#define PU_SOC_VOLTAGE_NORMAL	1250000
     19#define PU_SOC_VOLTAGE_HIGH	1275000
     20#define FREQ_1P2_GHZ		1200000000
     21
     22static struct regulator *arm_reg;
     23static struct regulator *pu_reg;
     24static struct regulator *soc_reg;
     25
     26enum IMX6_CPUFREQ_CLKS {
     27	ARM,
     28	PLL1_SYS,
     29	STEP,
     30	PLL1_SW,
     31	PLL2_PFD2_396M,
     32	/* MX6UL requires two more clks */
     33	PLL2_BUS,
     34	SECONDARY_SEL,
     35};
     36#define IMX6Q_CPUFREQ_CLK_NUM		5
     37#define IMX6UL_CPUFREQ_CLK_NUM		7
     38
     39static int num_clks;
     40static struct clk_bulk_data clks[] = {
     41	{ .id = "arm" },
     42	{ .id = "pll1_sys" },
     43	{ .id = "step" },
     44	{ .id = "pll1_sw" },
     45	{ .id = "pll2_pfd2_396m" },
     46	{ .id = "pll2_bus" },
     47	{ .id = "secondary_sel" },
     48};
     49
     50static struct device *cpu_dev;
     51static struct cpufreq_frequency_table *freq_table;
     52static unsigned int max_freq;
     53static unsigned int transition_latency;
     54
     55static u32 *imx6_soc_volt;
     56static u32 soc_opp_count;
     57
     58static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
     59{
     60	struct dev_pm_opp *opp;
     61	unsigned long freq_hz, volt, volt_old;
     62	unsigned int old_freq, new_freq;
     63	bool pll1_sys_temp_enabled = false;
     64	int ret;
     65
     66	new_freq = freq_table[index].frequency;
     67	freq_hz = new_freq * 1000;
     68	old_freq = clk_get_rate(clks[ARM].clk) / 1000;
     69
     70	opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);
     71	if (IS_ERR(opp)) {
     72		dev_err(cpu_dev, "failed to find OPP for %ld\n", freq_hz);
     73		return PTR_ERR(opp);
     74	}
     75
     76	volt = dev_pm_opp_get_voltage(opp);
     77	dev_pm_opp_put(opp);
     78
     79	volt_old = regulator_get_voltage(arm_reg);
     80
     81	dev_dbg(cpu_dev, "%u MHz, %ld mV --> %u MHz, %ld mV\n",
     82		old_freq / 1000, volt_old / 1000,
     83		new_freq / 1000, volt / 1000);
     84
     85	/* scaling up?  scale voltage before frequency */
     86	if (new_freq > old_freq) {
     87		if (!IS_ERR(pu_reg)) {
     88			ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
     89			if (ret) {
     90				dev_err(cpu_dev, "failed to scale vddpu up: %d\n", ret);
     91				return ret;
     92			}
     93		}
     94		ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], 0);
     95		if (ret) {
     96			dev_err(cpu_dev, "failed to scale vddsoc up: %d\n", ret);
     97			return ret;
     98		}
     99		ret = regulator_set_voltage_tol(arm_reg, volt, 0);
    100		if (ret) {
    101			dev_err(cpu_dev,
    102				"failed to scale vddarm up: %d\n", ret);
    103			return ret;
    104		}
    105	}
    106
    107	/*
    108	 * The setpoints are selected per PLL/PDF frequencies, so we need to
    109	 * reprogram PLL for frequency scaling.  The procedure of reprogramming
    110	 * PLL1 is as below.
    111	 * For i.MX6UL, it has a secondary clk mux, the cpu frequency change
    112	 * flow is slightly different from other i.MX6 OSC.
    113	 * The cpu frequeny change flow for i.MX6(except i.MX6UL) is as below:
    114	 *  - Enable pll2_pfd2_396m_clk and reparent pll1_sw_clk to it
    115	 *  - Reprogram pll1_sys_clk and reparent pll1_sw_clk back to it
    116	 *  - Disable pll2_pfd2_396m_clk
    117	 */
    118	if (of_machine_is_compatible("fsl,imx6ul") ||
    119	    of_machine_is_compatible("fsl,imx6ull")) {
    120		/*
    121		 * When changing pll1_sw_clk's parent to pll1_sys_clk,
    122		 * CPU may run at higher than 528MHz, this will lead to
    123		 * the system unstable if the voltage is lower than the
    124		 * voltage of 528MHz, so lower the CPU frequency to one
    125		 * half before changing CPU frequency.
    126		 */
    127		clk_set_rate(clks[ARM].clk, (old_freq >> 1) * 1000);
    128		clk_set_parent(clks[PLL1_SW].clk, clks[PLL1_SYS].clk);
    129		if (freq_hz > clk_get_rate(clks[PLL2_PFD2_396M].clk))
    130			clk_set_parent(clks[SECONDARY_SEL].clk,
    131				       clks[PLL2_BUS].clk);
    132		else
    133			clk_set_parent(clks[SECONDARY_SEL].clk,
    134				       clks[PLL2_PFD2_396M].clk);
    135		clk_set_parent(clks[STEP].clk, clks[SECONDARY_SEL].clk);
    136		clk_set_parent(clks[PLL1_SW].clk, clks[STEP].clk);
    137		if (freq_hz > clk_get_rate(clks[PLL2_BUS].clk)) {
    138			clk_set_rate(clks[PLL1_SYS].clk, new_freq * 1000);
    139			clk_set_parent(clks[PLL1_SW].clk, clks[PLL1_SYS].clk);
    140		}
    141	} else {
    142		clk_set_parent(clks[STEP].clk, clks[PLL2_PFD2_396M].clk);
    143		clk_set_parent(clks[PLL1_SW].clk, clks[STEP].clk);
    144		if (freq_hz > clk_get_rate(clks[PLL2_PFD2_396M].clk)) {
    145			clk_set_rate(clks[PLL1_SYS].clk, new_freq * 1000);
    146			clk_set_parent(clks[PLL1_SW].clk, clks[PLL1_SYS].clk);
    147		} else {
    148			/* pll1_sys needs to be enabled for divider rate change to work. */
    149			pll1_sys_temp_enabled = true;
    150			clk_prepare_enable(clks[PLL1_SYS].clk);
    151		}
    152	}
    153
    154	/* Ensure the arm clock divider is what we expect */
    155	ret = clk_set_rate(clks[ARM].clk, new_freq * 1000);
    156	if (ret) {
    157		int ret1;
    158
    159		dev_err(cpu_dev, "failed to set clock rate: %d\n", ret);
    160		ret1 = regulator_set_voltage_tol(arm_reg, volt_old, 0);
    161		if (ret1)
    162			dev_warn(cpu_dev,
    163				 "failed to restore vddarm voltage: %d\n", ret1);
    164		return ret;
    165	}
    166
    167	/* PLL1 is only needed until after ARM-PODF is set. */
    168	if (pll1_sys_temp_enabled)
    169		clk_disable_unprepare(clks[PLL1_SYS].clk);
    170
    171	/* scaling down?  scale voltage after frequency */
    172	if (new_freq < old_freq) {
    173		ret = regulator_set_voltage_tol(arm_reg, volt, 0);
    174		if (ret)
    175			dev_warn(cpu_dev,
    176				 "failed to scale vddarm down: %d\n", ret);
    177		ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], 0);
    178		if (ret)
    179			dev_warn(cpu_dev, "failed to scale vddsoc down: %d\n", ret);
    180		if (!IS_ERR(pu_reg)) {
    181			ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
    182			if (ret)
    183				dev_warn(cpu_dev, "failed to scale vddpu down: %d\n", ret);
    184		}
    185	}
    186
    187	return 0;
    188}
    189
    190static int imx6q_cpufreq_init(struct cpufreq_policy *policy)
    191{
    192	policy->clk = clks[ARM].clk;
    193	cpufreq_generic_init(policy, freq_table, transition_latency);
    194	policy->suspend_freq = max_freq;
    195
    196	return 0;
    197}
    198
    199static struct cpufreq_driver imx6q_cpufreq_driver = {
    200	.flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK |
    201		 CPUFREQ_IS_COOLING_DEV,
    202	.verify = cpufreq_generic_frequency_table_verify,
    203	.target_index = imx6q_set_target,
    204	.get = cpufreq_generic_get,
    205	.init = imx6q_cpufreq_init,
    206	.register_em = cpufreq_register_em_with_opp,
    207	.name = "imx6q-cpufreq",
    208	.attr = cpufreq_generic_attr,
    209	.suspend = cpufreq_generic_suspend,
    210};
    211
    212#define OCOTP_CFG3			0x440
    213#define OCOTP_CFG3_SPEED_SHIFT		16
    214#define OCOTP_CFG3_SPEED_1P2GHZ		0x3
    215#define OCOTP_CFG3_SPEED_996MHZ		0x2
    216#define OCOTP_CFG3_SPEED_852MHZ		0x1
    217
    218static int imx6q_opp_check_speed_grading(struct device *dev)
    219{
    220	struct device_node *np;
    221	void __iomem *base;
    222	u32 val;
    223	int ret;
    224
    225	if (of_find_property(dev->of_node, "nvmem-cells", NULL)) {
    226		ret = nvmem_cell_read_u32(dev, "speed_grade", &val);
    227		if (ret)
    228			return ret;
    229	} else {
    230		np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ocotp");
    231		if (!np)
    232			return -ENOENT;
    233
    234		base = of_iomap(np, 0);
    235		of_node_put(np);
    236		if (!base) {
    237			dev_err(dev, "failed to map ocotp\n");
    238			return -EFAULT;
    239		}
    240
    241		/*
    242		 * SPEED_GRADING[1:0] defines the max speed of ARM:
    243		 * 2b'11: 1200000000Hz;
    244		 * 2b'10: 996000000Hz;
    245		 * 2b'01: 852000000Hz; -- i.MX6Q Only, exclusive with 996MHz.
    246		 * 2b'00: 792000000Hz;
    247		 * We need to set the max speed of ARM according to fuse map.
    248		 */
    249		val = readl_relaxed(base + OCOTP_CFG3);
    250		iounmap(base);
    251	}
    252
    253	val >>= OCOTP_CFG3_SPEED_SHIFT;
    254	val &= 0x3;
    255
    256	if (val < OCOTP_CFG3_SPEED_996MHZ)
    257		if (dev_pm_opp_disable(dev, 996000000))
    258			dev_warn(dev, "failed to disable 996MHz OPP\n");
    259
    260	if (of_machine_is_compatible("fsl,imx6q") ||
    261	    of_machine_is_compatible("fsl,imx6qp")) {
    262		if (val != OCOTP_CFG3_SPEED_852MHZ)
    263			if (dev_pm_opp_disable(dev, 852000000))
    264				dev_warn(dev, "failed to disable 852MHz OPP\n");
    265		if (val != OCOTP_CFG3_SPEED_1P2GHZ)
    266			if (dev_pm_opp_disable(dev, 1200000000))
    267				dev_warn(dev, "failed to disable 1.2GHz OPP\n");
    268	}
    269
    270	return 0;
    271}
    272
    273#define OCOTP_CFG3_6UL_SPEED_696MHZ	0x2
    274#define OCOTP_CFG3_6ULL_SPEED_792MHZ	0x2
    275#define OCOTP_CFG3_6ULL_SPEED_900MHZ	0x3
    276
    277static int imx6ul_opp_check_speed_grading(struct device *dev)
    278{
    279	u32 val;
    280	int ret = 0;
    281
    282	if (of_find_property(dev->of_node, "nvmem-cells", NULL)) {
    283		ret = nvmem_cell_read_u32(dev, "speed_grade", &val);
    284		if (ret)
    285			return ret;
    286	} else {
    287		struct device_node *np;
    288		void __iomem *base;
    289
    290		np = of_find_compatible_node(NULL, NULL, "fsl,imx6ul-ocotp");
    291		if (!np)
    292			np = of_find_compatible_node(NULL, NULL,
    293						     "fsl,imx6ull-ocotp");
    294		if (!np)
    295			return -ENOENT;
    296
    297		base = of_iomap(np, 0);
    298		of_node_put(np);
    299		if (!base) {
    300			dev_err(dev, "failed to map ocotp\n");
    301			return -EFAULT;
    302		}
    303
    304		val = readl_relaxed(base + OCOTP_CFG3);
    305		iounmap(base);
    306	}
    307
    308	/*
    309	 * Speed GRADING[1:0] defines the max speed of ARM:
    310	 * 2b'00: Reserved;
    311	 * 2b'01: 528000000Hz;
    312	 * 2b'10: 696000000Hz on i.MX6UL, 792000000Hz on i.MX6ULL;
    313	 * 2b'11: 900000000Hz on i.MX6ULL only;
    314	 * We need to set the max speed of ARM according to fuse map.
    315	 */
    316	val >>= OCOTP_CFG3_SPEED_SHIFT;
    317	val &= 0x3;
    318
    319	if (of_machine_is_compatible("fsl,imx6ul")) {
    320		if (val != OCOTP_CFG3_6UL_SPEED_696MHZ)
    321			if (dev_pm_opp_disable(dev, 696000000))
    322				dev_warn(dev, "failed to disable 696MHz OPP\n");
    323	}
    324
    325	if (of_machine_is_compatible("fsl,imx6ull")) {
    326		if (val != OCOTP_CFG3_6ULL_SPEED_792MHZ)
    327			if (dev_pm_opp_disable(dev, 792000000))
    328				dev_warn(dev, "failed to disable 792MHz OPP\n");
    329
    330		if (val != OCOTP_CFG3_6ULL_SPEED_900MHZ)
    331			if (dev_pm_opp_disable(dev, 900000000))
    332				dev_warn(dev, "failed to disable 900MHz OPP\n");
    333	}
    334
    335	return ret;
    336}
    337
    338static int imx6q_cpufreq_probe(struct platform_device *pdev)
    339{
    340	struct device_node *np;
    341	struct dev_pm_opp *opp;
    342	unsigned long min_volt, max_volt;
    343	int num, ret;
    344	const struct property *prop;
    345	const __be32 *val;
    346	u32 nr, i, j;
    347
    348	cpu_dev = get_cpu_device(0);
    349	if (!cpu_dev) {
    350		pr_err("failed to get cpu0 device\n");
    351		return -ENODEV;
    352	}
    353
    354	np = of_node_get(cpu_dev->of_node);
    355	if (!np) {
    356		dev_err(cpu_dev, "failed to find cpu0 node\n");
    357		return -ENOENT;
    358	}
    359
    360	if (of_machine_is_compatible("fsl,imx6ul") ||
    361	    of_machine_is_compatible("fsl,imx6ull"))
    362		num_clks = IMX6UL_CPUFREQ_CLK_NUM;
    363	else
    364		num_clks = IMX6Q_CPUFREQ_CLK_NUM;
    365
    366	ret = clk_bulk_get(cpu_dev, num_clks, clks);
    367	if (ret)
    368		goto put_node;
    369
    370	arm_reg = regulator_get(cpu_dev, "arm");
    371	pu_reg = regulator_get_optional(cpu_dev, "pu");
    372	soc_reg = regulator_get(cpu_dev, "soc");
    373	if (PTR_ERR(arm_reg) == -EPROBE_DEFER ||
    374			PTR_ERR(soc_reg) == -EPROBE_DEFER ||
    375			PTR_ERR(pu_reg) == -EPROBE_DEFER) {
    376		ret = -EPROBE_DEFER;
    377		dev_dbg(cpu_dev, "regulators not ready, defer\n");
    378		goto put_reg;
    379	}
    380	if (IS_ERR(arm_reg) || IS_ERR(soc_reg)) {
    381		dev_err(cpu_dev, "failed to get regulators\n");
    382		ret = -ENOENT;
    383		goto put_reg;
    384	}
    385
    386	ret = dev_pm_opp_of_add_table(cpu_dev);
    387	if (ret < 0) {
    388		dev_err(cpu_dev, "failed to init OPP table: %d\n", ret);
    389		goto put_reg;
    390	}
    391
    392	if (of_machine_is_compatible("fsl,imx6ul") ||
    393	    of_machine_is_compatible("fsl,imx6ull")) {
    394		ret = imx6ul_opp_check_speed_grading(cpu_dev);
    395	} else {
    396		ret = imx6q_opp_check_speed_grading(cpu_dev);
    397	}
    398	if (ret) {
    399		if (ret != -EPROBE_DEFER)
    400			dev_err(cpu_dev, "failed to read ocotp: %d\n",
    401				ret);
    402		goto out_free_opp;
    403	}
    404
    405	num = dev_pm_opp_get_opp_count(cpu_dev);
    406	if (num < 0) {
    407		ret = num;
    408		dev_err(cpu_dev, "no OPP table is found: %d\n", ret);
    409		goto out_free_opp;
    410	}
    411
    412	ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
    413	if (ret) {
    414		dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
    415		goto out_free_opp;
    416	}
    417
    418	/* Make imx6_soc_volt array's size same as arm opp number */
    419	imx6_soc_volt = devm_kcalloc(cpu_dev, num, sizeof(*imx6_soc_volt),
    420				     GFP_KERNEL);
    421	if (imx6_soc_volt == NULL) {
    422		ret = -ENOMEM;
    423		goto free_freq_table;
    424	}
    425
    426	prop = of_find_property(np, "fsl,soc-operating-points", NULL);
    427	if (!prop || !prop->value)
    428		goto soc_opp_out;
    429
    430	/*
    431	 * Each OPP is a set of tuples consisting of frequency and
    432	 * voltage like <freq-kHz vol-uV>.
    433	 */
    434	nr = prop->length / sizeof(u32);
    435	if (nr % 2 || (nr / 2) < num)
    436		goto soc_opp_out;
    437
    438	for (j = 0; j < num; j++) {
    439		val = prop->value;
    440		for (i = 0; i < nr / 2; i++) {
    441			unsigned long freq = be32_to_cpup(val++);
    442			unsigned long volt = be32_to_cpup(val++);
    443			if (freq_table[j].frequency == freq) {
    444				imx6_soc_volt[soc_opp_count++] = volt;
    445				break;
    446			}
    447		}
    448	}
    449
    450soc_opp_out:
    451	/* use fixed soc opp volt if no valid soc opp info found in dtb */
    452	if (soc_opp_count != num) {
    453		dev_warn(cpu_dev, "can NOT find valid fsl,soc-operating-points property in dtb, use default value!\n");
    454		for (j = 0; j < num; j++)
    455			imx6_soc_volt[j] = PU_SOC_VOLTAGE_NORMAL;
    456		if (freq_table[num - 1].frequency * 1000 == FREQ_1P2_GHZ)
    457			imx6_soc_volt[num - 1] = PU_SOC_VOLTAGE_HIGH;
    458	}
    459
    460	if (of_property_read_u32(np, "clock-latency", &transition_latency))
    461		transition_latency = CPUFREQ_ETERNAL;
    462
    463	/*
    464	 * Calculate the ramp time for max voltage change in the
    465	 * VDDSOC and VDDPU regulators.
    466	 */
    467	ret = regulator_set_voltage_time(soc_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);
    468	if (ret > 0)
    469		transition_latency += ret * 1000;
    470	if (!IS_ERR(pu_reg)) {
    471		ret = regulator_set_voltage_time(pu_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);
    472		if (ret > 0)
    473			transition_latency += ret * 1000;
    474	}
    475
    476	/*
    477	 * OPP is maintained in order of increasing frequency, and
    478	 * freq_table initialised from OPP is therefore sorted in the
    479	 * same order.
    480	 */
    481	max_freq = freq_table[--num].frequency;
    482	opp = dev_pm_opp_find_freq_exact(cpu_dev,
    483				  freq_table[0].frequency * 1000, true);
    484	min_volt = dev_pm_opp_get_voltage(opp);
    485	dev_pm_opp_put(opp);
    486	opp = dev_pm_opp_find_freq_exact(cpu_dev, max_freq * 1000, true);
    487	max_volt = dev_pm_opp_get_voltage(opp);
    488	dev_pm_opp_put(opp);
    489
    490	ret = regulator_set_voltage_time(arm_reg, min_volt, max_volt);
    491	if (ret > 0)
    492		transition_latency += ret * 1000;
    493
    494	ret = cpufreq_register_driver(&imx6q_cpufreq_driver);
    495	if (ret) {
    496		dev_err(cpu_dev, "failed register driver: %d\n", ret);
    497		goto free_freq_table;
    498	}
    499
    500	of_node_put(np);
    501	return 0;
    502
    503free_freq_table:
    504	dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
    505out_free_opp:
    506	dev_pm_opp_of_remove_table(cpu_dev);
    507put_reg:
    508	if (!IS_ERR(arm_reg))
    509		regulator_put(arm_reg);
    510	if (!IS_ERR(pu_reg))
    511		regulator_put(pu_reg);
    512	if (!IS_ERR(soc_reg))
    513		regulator_put(soc_reg);
    514
    515	clk_bulk_put(num_clks, clks);
    516put_node:
    517	of_node_put(np);
    518
    519	return ret;
    520}
    521
    522static int imx6q_cpufreq_remove(struct platform_device *pdev)
    523{
    524	cpufreq_unregister_driver(&imx6q_cpufreq_driver);
    525	dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
    526	dev_pm_opp_of_remove_table(cpu_dev);
    527	regulator_put(arm_reg);
    528	if (!IS_ERR(pu_reg))
    529		regulator_put(pu_reg);
    530	regulator_put(soc_reg);
    531
    532	clk_bulk_put(num_clks, clks);
    533
    534	return 0;
    535}
    536
    537static struct platform_driver imx6q_cpufreq_platdrv = {
    538	.driver = {
    539		.name	= "imx6q-cpufreq",
    540	},
    541	.probe		= imx6q_cpufreq_probe,
    542	.remove		= imx6q_cpufreq_remove,
    543};
    544module_platform_driver(imx6q_cpufreq_platdrv);
    545
    546MODULE_ALIAS("platform:imx6q-cpufreq");
    547MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
    548MODULE_DESCRIPTION("Freescale i.MX6Q cpufreq driver");
    549MODULE_LICENSE("GPL");