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

regulators-tegra20.c (14287B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * Voltage regulators coupler for NVIDIA Tegra20
      4 * Copyright (C) 2019 GRATE-DRIVER project
      5 *
      6 * Voltage constraints borrowed from downstream kernel sources
      7 * Copyright (C) 2010-2011 NVIDIA Corporation
      8 */
      9
     10#define pr_fmt(fmt)	"tegra voltage-coupler: " fmt
     11
     12#include <linux/init.h>
     13#include <linux/kernel.h>
     14#include <linux/of.h>
     15#include <linux/reboot.h>
     16#include <linux/regulator/coupler.h>
     17#include <linux/regulator/driver.h>
     18#include <linux/regulator/machine.h>
     19#include <linux/suspend.h>
     20
     21#include <soc/tegra/fuse.h>
     22#include <soc/tegra/pmc.h>
     23
     24struct tegra_regulator_coupler {
     25	struct regulator_coupler coupler;
     26	struct regulator_dev *core_rdev;
     27	struct regulator_dev *cpu_rdev;
     28	struct regulator_dev *rtc_rdev;
     29	struct notifier_block reboot_notifier;
     30	struct notifier_block suspend_notifier;
     31	int core_min_uV, cpu_min_uV;
     32	bool sys_reboot_mode_req;
     33	bool sys_reboot_mode;
     34	bool sys_suspend_mode_req;
     35	bool sys_suspend_mode;
     36};
     37
     38static inline struct tegra_regulator_coupler *
     39to_tegra_coupler(struct regulator_coupler *coupler)
     40{
     41	return container_of(coupler, struct tegra_regulator_coupler, coupler);
     42}
     43
     44static int tegra20_core_limit(struct tegra_regulator_coupler *tegra,
     45			      struct regulator_dev *core_rdev)
     46{
     47	int core_min_uV = 0;
     48	int core_max_uV;
     49	int core_cur_uV;
     50	int err;
     51
     52	/*
     53	 * Tegra20 SoC has critical DVFS-capable devices that are
     54	 * permanently-active or active at a boot time, like EMC
     55	 * (DRAM controller) or Display controller for example.
     56	 *
     57	 * The voltage of a CORE SoC power domain shall not be dropped below
     58	 * a minimum level, which is determined by device's clock rate.
     59	 * This means that we can't fully allow CORE voltage scaling until
     60	 * the state of all DVFS-critical CORE devices is synced.
     61	 */
     62	if (tegra_pmc_core_domain_state_synced() && !tegra->sys_reboot_mode) {
     63		pr_info_once("voltage state synced\n");
     64		return 0;
     65	}
     66
     67	if (tegra->core_min_uV > 0)
     68		return tegra->core_min_uV;
     69
     70	core_cur_uV = regulator_get_voltage_rdev(core_rdev);
     71	if (core_cur_uV < 0)
     72		return core_cur_uV;
     73
     74	core_max_uV = max(core_cur_uV, 1200000);
     75
     76	err = regulator_check_voltage(core_rdev, &core_min_uV, &core_max_uV);
     77	if (err)
     78		return err;
     79
     80	/*
     81	 * Limit minimum CORE voltage to a value left from bootloader or,
     82	 * if it's unreasonably low value, to the most common 1.2v or to
     83	 * whatever maximum value defined via board's device-tree.
     84	 */
     85	tegra->core_min_uV = core_max_uV;
     86
     87	pr_info("core voltage initialized to %duV\n", tegra->core_min_uV);
     88
     89	return tegra->core_min_uV;
     90}
     91
     92static int tegra20_core_rtc_max_spread(struct regulator_dev *core_rdev,
     93				       struct regulator_dev *rtc_rdev)
     94{
     95	struct coupling_desc *c_desc = &core_rdev->coupling_desc;
     96	struct regulator_dev *rdev;
     97	int max_spread;
     98	unsigned int i;
     99
    100	for (i = 1; i < c_desc->n_coupled; i++) {
    101		max_spread = core_rdev->constraints->max_spread[i - 1];
    102		rdev = c_desc->coupled_rdevs[i];
    103
    104		if (rdev == rtc_rdev && max_spread)
    105			return max_spread;
    106	}
    107
    108	pr_err_once("rtc-core max-spread is undefined in device-tree\n");
    109
    110	return 150000;
    111}
    112
    113static int tegra20_cpu_nominal_uV(void)
    114{
    115	switch (tegra_sku_info.soc_speedo_id) {
    116	case 0:
    117		return 1100000;
    118	case 1:
    119		return 1025000;
    120	default:
    121		return 1125000;
    122	}
    123}
    124
    125static int tegra20_core_nominal_uV(void)
    126{
    127	switch (tegra_sku_info.soc_speedo_id) {
    128	default:
    129		return 1225000;
    130	case 2:
    131		return 1300000;
    132	}
    133}
    134
    135static int tegra20_core_rtc_update(struct tegra_regulator_coupler *tegra,
    136				   struct regulator_dev *core_rdev,
    137				   struct regulator_dev *rtc_rdev,
    138				   int cpu_uV, int cpu_min_uV)
    139{
    140	int core_min_uV, core_max_uV = INT_MAX;
    141	int rtc_min_uV, rtc_max_uV = INT_MAX;
    142	int core_target_uV;
    143	int rtc_target_uV;
    144	int max_spread;
    145	int core_uV;
    146	int rtc_uV;
    147	int err;
    148
    149	/*
    150	 * RTC and CORE voltages should be no more than 170mV from each other,
    151	 * CPU should be below RTC and CORE by at least 120mV. This applies
    152	 * to all Tegra20 SoC's.
    153	 */
    154	max_spread = tegra20_core_rtc_max_spread(core_rdev, rtc_rdev);
    155
    156	/*
    157	 * The core voltage scaling is currently not hooked up in drivers,
    158	 * hence we will limit the minimum core voltage to a reasonable value.
    159	 * This should be good enough for the time being.
    160	 */
    161	core_min_uV = tegra20_core_limit(tegra, core_rdev);
    162	if (core_min_uV < 0)
    163		return core_min_uV;
    164
    165	err = regulator_check_voltage(core_rdev, &core_min_uV, &core_max_uV);
    166	if (err)
    167		return err;
    168
    169	err = regulator_check_consumers(core_rdev, &core_min_uV, &core_max_uV,
    170					PM_SUSPEND_ON);
    171	if (err)
    172		return err;
    173
    174	/* prepare voltage level for suspend */
    175	if (tegra->sys_suspend_mode)
    176		core_min_uV = clamp(tegra20_core_nominal_uV(),
    177				    core_min_uV, core_max_uV);
    178
    179	core_uV = regulator_get_voltage_rdev(core_rdev);
    180	if (core_uV < 0)
    181		return core_uV;
    182
    183	core_min_uV = max(cpu_min_uV + 125000, core_min_uV);
    184	if (core_min_uV > core_max_uV)
    185		return -EINVAL;
    186
    187	if (cpu_uV + 120000 > core_uV)
    188		pr_err("core-cpu voltage constraint violated: %d %d\n",
    189		       core_uV, cpu_uV + 120000);
    190
    191	rtc_uV = regulator_get_voltage_rdev(rtc_rdev);
    192	if (rtc_uV < 0)
    193		return rtc_uV;
    194
    195	if (cpu_uV + 120000 > rtc_uV)
    196		pr_err("rtc-cpu voltage constraint violated: %d %d\n",
    197		       rtc_uV, cpu_uV + 120000);
    198
    199	if (abs(core_uV - rtc_uV) > 170000)
    200		pr_err("core-rtc voltage constraint violated: %d %d\n",
    201		       core_uV, rtc_uV);
    202
    203	rtc_min_uV = max(cpu_min_uV + 125000, core_min_uV - max_spread);
    204
    205	err = regulator_check_voltage(rtc_rdev, &rtc_min_uV, &rtc_max_uV);
    206	if (err)
    207		return err;
    208
    209	while (core_uV != core_min_uV || rtc_uV != rtc_min_uV) {
    210		if (core_uV < core_min_uV) {
    211			core_target_uV = min(core_uV + max_spread, core_min_uV);
    212			core_target_uV = min(rtc_uV + max_spread, core_target_uV);
    213		} else {
    214			core_target_uV = max(core_uV - max_spread, core_min_uV);
    215			core_target_uV = max(rtc_uV - max_spread, core_target_uV);
    216		}
    217
    218		if (core_uV == core_target_uV)
    219			goto update_rtc;
    220
    221		err = regulator_set_voltage_rdev(core_rdev,
    222						 core_target_uV,
    223						 core_max_uV,
    224						 PM_SUSPEND_ON);
    225		if (err)
    226			return err;
    227
    228		core_uV = core_target_uV;
    229update_rtc:
    230		if (rtc_uV < rtc_min_uV) {
    231			rtc_target_uV = min(rtc_uV + max_spread, rtc_min_uV);
    232			rtc_target_uV = min(core_uV + max_spread, rtc_target_uV);
    233		} else {
    234			rtc_target_uV = max(rtc_uV - max_spread, rtc_min_uV);
    235			rtc_target_uV = max(core_uV - max_spread, rtc_target_uV);
    236		}
    237
    238		if (rtc_uV == rtc_target_uV)
    239			continue;
    240
    241		err = regulator_set_voltage_rdev(rtc_rdev,
    242						 rtc_target_uV,
    243						 rtc_max_uV,
    244						 PM_SUSPEND_ON);
    245		if (err)
    246			return err;
    247
    248		rtc_uV = rtc_target_uV;
    249	}
    250
    251	return 0;
    252}
    253
    254static int tegra20_core_voltage_update(struct tegra_regulator_coupler *tegra,
    255				       struct regulator_dev *cpu_rdev,
    256				       struct regulator_dev *core_rdev,
    257				       struct regulator_dev *rtc_rdev)
    258{
    259	int cpu_uV;
    260
    261	cpu_uV = regulator_get_voltage_rdev(cpu_rdev);
    262	if (cpu_uV < 0)
    263		return cpu_uV;
    264
    265	return tegra20_core_rtc_update(tegra, core_rdev, rtc_rdev,
    266				       cpu_uV, cpu_uV);
    267}
    268
    269static int tegra20_cpu_voltage_update(struct tegra_regulator_coupler *tegra,
    270				      struct regulator_dev *cpu_rdev,
    271				      struct regulator_dev *core_rdev,
    272				      struct regulator_dev *rtc_rdev)
    273{
    274	int cpu_min_uV_consumers = 0;
    275	int cpu_max_uV = INT_MAX;
    276	int cpu_min_uV = 0;
    277	int cpu_uV;
    278	int err;
    279
    280	err = regulator_check_voltage(cpu_rdev, &cpu_min_uV, &cpu_max_uV);
    281	if (err)
    282		return err;
    283
    284	err = regulator_check_consumers(cpu_rdev, &cpu_min_uV, &cpu_max_uV,
    285					PM_SUSPEND_ON);
    286	if (err)
    287		return err;
    288
    289	err = regulator_check_consumers(cpu_rdev, &cpu_min_uV_consumers,
    290					&cpu_max_uV, PM_SUSPEND_ON);
    291	if (err)
    292		return err;
    293
    294	cpu_uV = regulator_get_voltage_rdev(cpu_rdev);
    295	if (cpu_uV < 0)
    296		return cpu_uV;
    297
    298	/* store boot voltage level */
    299	if (!tegra->cpu_min_uV)
    300		tegra->cpu_min_uV = cpu_uV;
    301
    302	/*
    303	 * CPU's regulator may not have any consumers, hence the voltage
    304	 * must not be changed in that case because CPU simply won't
    305	 * survive the voltage drop if it's running on a higher frequency.
    306	 */
    307	if (!cpu_min_uV_consumers)
    308		cpu_min_uV = cpu_uV;
    309
    310	/* restore boot voltage level */
    311	if (tegra->sys_reboot_mode)
    312		cpu_min_uV = max(cpu_min_uV, tegra->cpu_min_uV);
    313
    314	/* prepare voltage level for suspend */
    315	if (tegra->sys_suspend_mode)
    316		cpu_min_uV = clamp(tegra20_cpu_nominal_uV(),
    317				   cpu_min_uV, cpu_max_uV);
    318
    319	if (cpu_min_uV > cpu_uV) {
    320		err = tegra20_core_rtc_update(tegra, core_rdev, rtc_rdev,
    321					      cpu_uV, cpu_min_uV);
    322		if (err)
    323			return err;
    324
    325		err = regulator_set_voltage_rdev(cpu_rdev, cpu_min_uV,
    326						 cpu_max_uV, PM_SUSPEND_ON);
    327		if (err)
    328			return err;
    329	} else if (cpu_min_uV < cpu_uV)  {
    330		err = regulator_set_voltage_rdev(cpu_rdev, cpu_min_uV,
    331						 cpu_max_uV, PM_SUSPEND_ON);
    332		if (err)
    333			return err;
    334
    335		err = tegra20_core_rtc_update(tegra, core_rdev, rtc_rdev,
    336					      cpu_uV, cpu_min_uV);
    337		if (err)
    338			return err;
    339	}
    340
    341	return 0;
    342}
    343
    344static int tegra20_regulator_balance_voltage(struct regulator_coupler *coupler,
    345					     struct regulator_dev *rdev,
    346					     suspend_state_t state)
    347{
    348	struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
    349	struct regulator_dev *core_rdev = tegra->core_rdev;
    350	struct regulator_dev *cpu_rdev = tegra->cpu_rdev;
    351	struct regulator_dev *rtc_rdev = tegra->rtc_rdev;
    352
    353	if ((core_rdev != rdev && cpu_rdev != rdev && rtc_rdev != rdev) ||
    354	    state != PM_SUSPEND_ON) {
    355		pr_err("regulators are not coupled properly\n");
    356		return -EINVAL;
    357	}
    358
    359	tegra->sys_reboot_mode = READ_ONCE(tegra->sys_reboot_mode_req);
    360	tegra->sys_suspend_mode = READ_ONCE(tegra->sys_suspend_mode_req);
    361
    362	if (rdev == cpu_rdev)
    363		return tegra20_cpu_voltage_update(tegra, cpu_rdev,
    364						  core_rdev, rtc_rdev);
    365
    366	if (rdev == core_rdev)
    367		return tegra20_core_voltage_update(tegra, cpu_rdev,
    368						   core_rdev, rtc_rdev);
    369
    370	pr_err("changing %s voltage not permitted\n", rdev_get_name(rtc_rdev));
    371
    372	return -EPERM;
    373}
    374
    375static int tegra20_regulator_prepare_suspend(struct tegra_regulator_coupler *tegra,
    376					     bool sys_suspend_mode)
    377{
    378	int err;
    379
    380	if (!tegra->core_rdev || !tegra->rtc_rdev || !tegra->cpu_rdev)
    381		return 0;
    382
    383	/*
    384	 * All power domains are enabled early during resume from suspend
    385	 * by GENPD core.  Domains like VENC may require a higher voltage
    386	 * when enabled during resume from suspend.  This also prepares
    387	 * hardware for resuming from LP0.
    388	 */
    389
    390	WRITE_ONCE(tegra->sys_suspend_mode_req, sys_suspend_mode);
    391
    392	err = regulator_sync_voltage_rdev(tegra->cpu_rdev);
    393	if (err)
    394		return err;
    395
    396	err = regulator_sync_voltage_rdev(tegra->core_rdev);
    397	if (err)
    398		return err;
    399
    400	return 0;
    401}
    402
    403static int tegra20_regulator_suspend(struct notifier_block *notifier,
    404				     unsigned long mode, void *arg)
    405{
    406	struct tegra_regulator_coupler *tegra;
    407	int ret = 0;
    408
    409	tegra = container_of(notifier, struct tegra_regulator_coupler,
    410			     suspend_notifier);
    411
    412	switch (mode) {
    413	case PM_HIBERNATION_PREPARE:
    414	case PM_RESTORE_PREPARE:
    415	case PM_SUSPEND_PREPARE:
    416		ret = tegra20_regulator_prepare_suspend(tegra, true);
    417		break;
    418
    419	case PM_POST_HIBERNATION:
    420	case PM_POST_RESTORE:
    421	case PM_POST_SUSPEND:
    422		ret = tegra20_regulator_prepare_suspend(tegra, false);
    423		break;
    424	}
    425
    426	if (ret)
    427		pr_err("failed to prepare regulators: %d\n", ret);
    428
    429	return notifier_from_errno(ret);
    430}
    431
    432static int tegra20_regulator_prepare_reboot(struct tegra_regulator_coupler *tegra,
    433					    bool sys_reboot_mode)
    434{
    435	int err;
    436
    437	if (!tegra->core_rdev || !tegra->rtc_rdev || !tegra->cpu_rdev)
    438		return 0;
    439
    440	WRITE_ONCE(tegra->sys_reboot_mode_req, true);
    441
    442	/*
    443	 * Some devices use CPU soft-reboot method and in this case we
    444	 * should ensure that voltages are sane for the reboot by restoring
    445	 * the minimum boot levels.
    446	 */
    447	err = regulator_sync_voltage_rdev(tegra->cpu_rdev);
    448	if (err)
    449		return err;
    450
    451	err = regulator_sync_voltage_rdev(tegra->core_rdev);
    452	if (err)
    453		return err;
    454
    455	WRITE_ONCE(tegra->sys_reboot_mode_req, sys_reboot_mode);
    456
    457	return 0;
    458}
    459
    460static int tegra20_regulator_reboot(struct notifier_block *notifier,
    461				    unsigned long event, void *cmd)
    462{
    463	struct tegra_regulator_coupler *tegra;
    464	int ret;
    465
    466	if (event != SYS_RESTART)
    467		return NOTIFY_DONE;
    468
    469	tegra = container_of(notifier, struct tegra_regulator_coupler,
    470			     reboot_notifier);
    471
    472	ret = tegra20_regulator_prepare_reboot(tegra, true);
    473
    474	return notifier_from_errno(ret);
    475}
    476
    477static int tegra20_regulator_attach(struct regulator_coupler *coupler,
    478				    struct regulator_dev *rdev)
    479{
    480	struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
    481	struct device_node *np = rdev->dev.of_node;
    482
    483	if (of_property_read_bool(np, "nvidia,tegra-core-regulator") &&
    484	    !tegra->core_rdev) {
    485		tegra->core_rdev = rdev;
    486		return 0;
    487	}
    488
    489	if (of_property_read_bool(np, "nvidia,tegra-rtc-regulator") &&
    490	    !tegra->rtc_rdev) {
    491		tegra->rtc_rdev = rdev;
    492		return 0;
    493	}
    494
    495	if (of_property_read_bool(np, "nvidia,tegra-cpu-regulator") &&
    496	    !tegra->cpu_rdev) {
    497		tegra->cpu_rdev = rdev;
    498		return 0;
    499	}
    500
    501	return -EINVAL;
    502}
    503
    504static int tegra20_regulator_detach(struct regulator_coupler *coupler,
    505				    struct regulator_dev *rdev)
    506{
    507	struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
    508
    509	/*
    510	 * We don't expect regulators to be decoupled during reboot,
    511	 * this may race with the reboot handler and shouldn't ever
    512	 * happen in practice.
    513	 */
    514	if (WARN_ON_ONCE(system_state > SYSTEM_RUNNING))
    515		return -EPERM;
    516
    517	if (tegra->core_rdev == rdev) {
    518		tegra->core_rdev = NULL;
    519		return 0;
    520	}
    521
    522	if (tegra->rtc_rdev == rdev) {
    523		tegra->rtc_rdev = NULL;
    524		return 0;
    525	}
    526
    527	if (tegra->cpu_rdev == rdev) {
    528		tegra->cpu_rdev = NULL;
    529		return 0;
    530	}
    531
    532	return -EINVAL;
    533}
    534
    535static struct tegra_regulator_coupler tegra20_coupler = {
    536	.coupler = {
    537		.attach_regulator = tegra20_regulator_attach,
    538		.detach_regulator = tegra20_regulator_detach,
    539		.balance_voltage = tegra20_regulator_balance_voltage,
    540	},
    541	.reboot_notifier.notifier_call = tegra20_regulator_reboot,
    542	.suspend_notifier.notifier_call = tegra20_regulator_suspend,
    543};
    544
    545static int __init tegra_regulator_coupler_init(void)
    546{
    547	int err;
    548
    549	if (!of_machine_is_compatible("nvidia,tegra20"))
    550		return 0;
    551
    552	err = register_reboot_notifier(&tegra20_coupler.reboot_notifier);
    553	WARN_ON(err);
    554
    555	err = register_pm_notifier(&tegra20_coupler.suspend_notifier);
    556	WARN_ON(err);
    557
    558	return regulator_coupler_register(&tegra20_coupler.coupler);
    559}
    560arch_initcall(tegra_regulator_coupler_init);