Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * CPU idle driver for Tegra CPUs
0004  *
0005  * Copyright (c) 2010-2013, NVIDIA Corporation.
0006  * Copyright (c) 2011 Google, Inc.
0007  * Author: Colin Cross <ccross@android.com>
0008  *         Gary King <gking@nvidia.com>
0009  *
0010  * Rework for 3.3 by Peter De Schrijver <pdeschrijver@nvidia.com>
0011  *
0012  * Tegra20/124 driver unification by Dmitry Osipenko <digetx@gmail.com>
0013  */
0014 
0015 #define pr_fmt(fmt) "tegra-cpuidle: " fmt
0016 
0017 #include <linux/atomic.h>
0018 #include <linux/cpuidle.h>
0019 #include <linux/cpumask.h>
0020 #include <linux/cpu_pm.h>
0021 #include <linux/delay.h>
0022 #include <linux/errno.h>
0023 #include <linux/platform_device.h>
0024 #include <linux/types.h>
0025 
0026 #include <linux/clk/tegra.h>
0027 #include <linux/firmware/trusted_foundations.h>
0028 
0029 #include <soc/tegra/cpuidle.h>
0030 #include <soc/tegra/flowctrl.h>
0031 #include <soc/tegra/fuse.h>
0032 #include <soc/tegra/irq.h>
0033 #include <soc/tegra/pm.h>
0034 #include <soc/tegra/pmc.h>
0035 
0036 #include <asm/cpuidle.h>
0037 #include <asm/firmware.h>
0038 #include <asm/smp_plat.h>
0039 #include <asm/suspend.h>
0040 
0041 enum tegra_state {
0042     TEGRA_C1,
0043     TEGRA_C7,
0044     TEGRA_CC6,
0045     TEGRA_STATE_COUNT,
0046 };
0047 
0048 static atomic_t tegra_idle_barrier;
0049 static atomic_t tegra_abort_flag;
0050 
0051 static void tegra_cpuidle_report_cpus_state(void)
0052 {
0053     unsigned long cpu, lcpu, csr;
0054 
0055     for_each_cpu(lcpu, cpu_possible_mask) {
0056         cpu = cpu_logical_map(lcpu);
0057         csr = flowctrl_read_cpu_csr(cpu);
0058 
0059         pr_err("cpu%lu: online=%d flowctrl_csr=0x%08lx\n",
0060                cpu, cpu_online(lcpu), csr);
0061     }
0062 }
0063 
0064 static int tegra_cpuidle_wait_for_secondary_cpus_parking(void)
0065 {
0066     unsigned int retries = 3;
0067 
0068     while (retries--) {
0069         unsigned int delay_us = 10;
0070         unsigned int timeout_us = 500 * 1000 / delay_us;
0071 
0072         /*
0073          * The primary CPU0 core shall wait for the secondaries
0074          * shutdown in order to power-off CPU's cluster safely.
0075          * The timeout value depends on the current CPU frequency,
0076          * it takes about 40-150us in average and over 1000us in
0077          * a worst case scenario.
0078          */
0079         do {
0080             if (tegra_cpu_rail_off_ready())
0081                 return 0;
0082 
0083             udelay(delay_us);
0084 
0085         } while (timeout_us--);
0086 
0087         pr_err("secondary CPU taking too long to park\n");
0088 
0089         tegra_cpuidle_report_cpus_state();
0090     }
0091 
0092     pr_err("timed out waiting secondaries to park\n");
0093 
0094     return -ETIMEDOUT;
0095 }
0096 
0097 static void tegra_cpuidle_unpark_secondary_cpus(void)
0098 {
0099     unsigned int cpu, lcpu;
0100 
0101     for_each_cpu(lcpu, cpu_online_mask) {
0102         cpu = cpu_logical_map(lcpu);
0103 
0104         if (cpu > 0) {
0105             tegra_enable_cpu_clock(cpu);
0106             tegra_cpu_out_of_reset(cpu);
0107             flowctrl_write_cpu_halt(cpu, 0);
0108         }
0109     }
0110 }
0111 
0112 static int tegra_cpuidle_cc6_enter(unsigned int cpu)
0113 {
0114     int ret;
0115 
0116     if (cpu > 0) {
0117         ret = cpu_suspend(cpu, tegra_pm_park_secondary_cpu);
0118     } else {
0119         ret = tegra_cpuidle_wait_for_secondary_cpus_parking();
0120         if (!ret)
0121             ret = tegra_pm_enter_lp2();
0122 
0123         tegra_cpuidle_unpark_secondary_cpus();
0124     }
0125 
0126     return ret;
0127 }
0128 
0129 static int tegra_cpuidle_c7_enter(void)
0130 {
0131     int err;
0132 
0133     err = call_firmware_op(prepare_idle, TF_PM_MODE_LP2_NOFLUSH_L2);
0134     if (err && err != -ENOSYS)
0135         return err;
0136 
0137     return cpu_suspend(0, tegra30_pm_secondary_cpu_suspend);
0138 }
0139 
0140 static int tegra_cpuidle_coupled_barrier(struct cpuidle_device *dev)
0141 {
0142     if (tegra_pending_sgi()) {
0143         /*
0144          * CPU got local interrupt that will be lost after GIC's
0145          * shutdown because GIC driver doesn't save/restore the
0146          * pending SGI state across CPU cluster PM.  Abort and retry
0147          * next time.
0148          */
0149         atomic_set(&tegra_abort_flag, 1);
0150     }
0151 
0152     cpuidle_coupled_parallel_barrier(dev, &tegra_idle_barrier);
0153 
0154     if (atomic_read(&tegra_abort_flag)) {
0155         cpuidle_coupled_parallel_barrier(dev, &tegra_idle_barrier);
0156         atomic_set(&tegra_abort_flag, 0);
0157         return -EINTR;
0158     }
0159 
0160     return 0;
0161 }
0162 
0163 static int tegra_cpuidle_state_enter(struct cpuidle_device *dev,
0164                      int index, unsigned int cpu)
0165 {
0166     int err;
0167 
0168     /*
0169      * CC6 state is the "CPU cluster power-off" state.  In order to
0170      * enter this state, at first the secondary CPU cores need to be
0171      * parked into offline mode, then the last CPU should clean out
0172      * remaining dirty cache lines into DRAM and trigger Flow Controller
0173      * logic that turns off the cluster's power domain (which includes
0174      * CPU cores, GIC and L2 cache).
0175      */
0176     if (index == TEGRA_CC6) {
0177         err = tegra_cpuidle_coupled_barrier(dev);
0178         if (err)
0179             return err;
0180     }
0181 
0182     local_fiq_disable();
0183     RCU_NONIDLE(tegra_pm_set_cpu_in_lp2());
0184     cpu_pm_enter();
0185 
0186     switch (index) {
0187     case TEGRA_C7:
0188         err = tegra_cpuidle_c7_enter();
0189         break;
0190 
0191     case TEGRA_CC6:
0192         err = tegra_cpuidle_cc6_enter(cpu);
0193         break;
0194 
0195     default:
0196         err = -EINVAL;
0197         break;
0198     }
0199 
0200     cpu_pm_exit();
0201     RCU_NONIDLE(tegra_pm_clear_cpu_in_lp2());
0202     local_fiq_enable();
0203 
0204     return err ?: index;
0205 }
0206 
0207 static int tegra_cpuidle_adjust_state_index(int index, unsigned int cpu)
0208 {
0209     /*
0210      * On Tegra30 CPU0 can't be power-gated separately from secondary
0211      * cores because it gates the whole CPU cluster.
0212      */
0213     if (cpu > 0 || index != TEGRA_C7 || tegra_get_chip_id() != TEGRA30)
0214         return index;
0215 
0216     /* put CPU0 into C1 if C7 is requested and secondaries are online */
0217     if (!IS_ENABLED(CONFIG_PM_SLEEP) || num_online_cpus() > 1)
0218         index = TEGRA_C1;
0219     else
0220         index = TEGRA_CC6;
0221 
0222     return index;
0223 }
0224 
0225 static int tegra_cpuidle_enter(struct cpuidle_device *dev,
0226                    struct cpuidle_driver *drv,
0227                    int index)
0228 {
0229     unsigned int cpu = cpu_logical_map(dev->cpu);
0230     int ret;
0231 
0232     index = tegra_cpuidle_adjust_state_index(index, cpu);
0233     if (dev->states_usage[index].disable)
0234         return -1;
0235 
0236     if (index == TEGRA_C1)
0237         ret = arm_cpuidle_simple_enter(dev, drv, index);
0238     else
0239         ret = tegra_cpuidle_state_enter(dev, index, cpu);
0240 
0241     if (ret < 0) {
0242         if (ret != -EINTR || index != TEGRA_CC6)
0243             pr_err_once("failed to enter state %d err: %d\n",
0244                     index, ret);
0245         index = -1;
0246     } else {
0247         index = ret;
0248     }
0249 
0250     return index;
0251 }
0252 
0253 static int tegra114_enter_s2idle(struct cpuidle_device *dev,
0254                  struct cpuidle_driver *drv,
0255                  int index)
0256 {
0257     tegra_cpuidle_enter(dev, drv, index);
0258 
0259     return 0;
0260 }
0261 
0262 /*
0263  * The previous versions of Tegra CPUIDLE driver used a different "legacy"
0264  * terminology for naming of the idling states, while this driver uses the
0265  * new terminology.
0266  *
0267  * Mapping of the old terms into the new ones:
0268  *
0269  * Old | New
0270  * ---------
0271  * LP3 | C1 (CPU core clock gating)
0272  * LP2 | C7 (CPU core power gating)
0273  * LP2 | CC6    (CPU cluster power gating)
0274  *
0275  * Note that that the older CPUIDLE driver versions didn't explicitly
0276  * differentiate the LP2 states because these states either used the same
0277  * code path or because CC6 wasn't supported.
0278  */
0279 static struct cpuidle_driver tegra_idle_driver = {
0280     .name = "tegra_idle",
0281     .states = {
0282         [TEGRA_C1] = ARM_CPUIDLE_WFI_STATE_PWR(600),
0283         [TEGRA_C7] = {
0284             .enter          = tegra_cpuidle_enter,
0285             .exit_latency       = 2000,
0286             .target_residency   = 2200,
0287             .power_usage        = 100,
0288             .flags          = CPUIDLE_FLAG_TIMER_STOP,
0289             .name           = "C7",
0290             .desc           = "CPU core powered off",
0291         },
0292         [TEGRA_CC6] = {
0293             .enter          = tegra_cpuidle_enter,
0294             .exit_latency       = 5000,
0295             .target_residency   = 10000,
0296             .power_usage        = 0,
0297             .flags          = CPUIDLE_FLAG_TIMER_STOP |
0298                           CPUIDLE_FLAG_COUPLED,
0299             .name           = "CC6",
0300             .desc           = "CPU cluster powered off",
0301         },
0302     },
0303     .state_count = TEGRA_STATE_COUNT,
0304     .safe_state_index = TEGRA_C1,
0305 };
0306 
0307 static inline void tegra_cpuidle_disable_state(enum tegra_state state)
0308 {
0309     cpuidle_driver_state_disabled(&tegra_idle_driver, state, true);
0310 }
0311 
0312 /*
0313  * Tegra20 HW appears to have a bug such that PCIe device interrupts, whether
0314  * they are legacy IRQs or MSI, are lost when CC6 is enabled.  To work around
0315  * this, simply disable CC6 if the PCI driver and DT node are both enabled.
0316  */
0317 void tegra_cpuidle_pcie_irqs_in_use(void)
0318 {
0319     struct cpuidle_state *state_cc6 = &tegra_idle_driver.states[TEGRA_CC6];
0320 
0321     if ((state_cc6->flags & CPUIDLE_FLAG_UNUSABLE) ||
0322         tegra_get_chip_id() != TEGRA20)
0323         return;
0324 
0325     pr_info("disabling CC6 state, since PCIe IRQs are in use\n");
0326     tegra_cpuidle_disable_state(TEGRA_CC6);
0327 }
0328 
0329 static void tegra_cpuidle_setup_tegra114_c7_state(void)
0330 {
0331     struct cpuidle_state *s = &tegra_idle_driver.states[TEGRA_C7];
0332 
0333     s->enter_s2idle = tegra114_enter_s2idle;
0334     s->target_residency = 1000;
0335     s->exit_latency = 500;
0336 }
0337 
0338 static int tegra_cpuidle_probe(struct platform_device *pdev)
0339 {
0340     if (tegra_pmc_get_suspend_mode() == TEGRA_SUSPEND_NOT_READY)
0341         return -EPROBE_DEFER;
0342 
0343     /* LP2 could be disabled in device-tree */
0344     if (tegra_pmc_get_suspend_mode() < TEGRA_SUSPEND_LP2)
0345         tegra_cpuidle_disable_state(TEGRA_CC6);
0346 
0347     /*
0348      * Required suspend-resume functionality, which is provided by the
0349      * Tegra-arch core and PMC driver, is unavailable if PM-sleep option
0350      * is disabled.
0351      */
0352     if (!IS_ENABLED(CONFIG_PM_SLEEP)) {
0353         tegra_cpuidle_disable_state(TEGRA_C7);
0354         tegra_cpuidle_disable_state(TEGRA_CC6);
0355     }
0356 
0357     /*
0358      * Generic WFI state (also known as C1 or LP3) and the coupled CPU
0359      * cluster power-off (CC6 or LP2) states are common for all Tegra SoCs.
0360      */
0361     switch (tegra_get_chip_id()) {
0362     case TEGRA20:
0363         /* Tegra20 isn't capable to power-off individual CPU cores */
0364         tegra_cpuidle_disable_state(TEGRA_C7);
0365         break;
0366 
0367     case TEGRA30:
0368         break;
0369 
0370     case TEGRA114:
0371     case TEGRA124:
0372         tegra_cpuidle_setup_tegra114_c7_state();
0373 
0374         /* coupled CC6 (LP2) state isn't implemented yet */
0375         tegra_cpuidle_disable_state(TEGRA_CC6);
0376         break;
0377 
0378     default:
0379         return -EINVAL;
0380     }
0381 
0382     return cpuidle_register(&tegra_idle_driver, cpu_possible_mask);
0383 }
0384 
0385 static struct platform_driver tegra_cpuidle_driver = {
0386     .probe = tegra_cpuidle_probe,
0387     .driver = {
0388         .name = "tegra-cpuidle",
0389     },
0390 };
0391 builtin_platform_driver(tegra_cpuidle_driver);