linux/arch/arm/mach-tegra/platsmp.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 *  linux/arch/arm/mach-tegra/platsmp.c
   4 *
   5 *  Copyright (C) 2002 ARM Ltd.
   6 *  All Rights Reserved
   7 *
   8 *  Copyright (C) 2009 Palm
   9 *  All Rights Reserved
  10 */
  11
  12#include <linux/clk/tegra.h>
  13#include <linux/delay.h>
  14#include <linux/device.h>
  15#include <linux/errno.h>
  16#include <linux/init.h>
  17#include <linux/io.h>
  18#include <linux/jiffies.h>
  19#include <linux/smp.h>
  20
  21#include <soc/tegra/flowctrl.h>
  22#include <soc/tegra/fuse.h>
  23#include <soc/tegra/pmc.h>
  24
  25#include <asm/cacheflush.h>
  26#include <asm/mach-types.h>
  27#include <asm/smp_plat.h>
  28#include <asm/smp_scu.h>
  29
  30#include "common.h"
  31#include "iomap.h"
  32#include "reset.h"
  33
  34static cpumask_t tegra_cpu_init_mask;
  35
  36static void tegra_secondary_init(unsigned int cpu)
  37{
  38        cpumask_set_cpu(cpu, &tegra_cpu_init_mask);
  39}
  40
  41
  42static int tegra20_boot_secondary(unsigned int cpu, struct task_struct *idle)
  43{
  44        cpu = cpu_logical_map(cpu);
  45
  46        /*
  47         * Force the CPU into reset. The CPU must remain in reset when
  48         * the flow controller state is cleared (which will cause the
  49         * flow controller to stop driving reset if the CPU has been
  50         * power-gated via the flow controller). This will have no
  51         * effect on first boot of the CPU since it should already be
  52         * in reset.
  53         */
  54        tegra_put_cpu_in_reset(cpu);
  55
  56        /*
  57         * Unhalt the CPU. If the flow controller was used to
  58         * power-gate the CPU this will cause the flow controller to
  59         * stop driving reset. The CPU will remain in reset because the
  60         * clock and reset block is now driving reset.
  61         */
  62        flowctrl_write_cpu_halt(cpu, 0);
  63
  64        tegra_enable_cpu_clock(cpu);
  65        flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */
  66        tegra_cpu_out_of_reset(cpu);
  67        return 0;
  68}
  69
  70static int tegra30_boot_secondary(unsigned int cpu, struct task_struct *idle)
  71{
  72        int ret;
  73        unsigned long timeout;
  74
  75        cpu = cpu_logical_map(cpu);
  76        tegra_put_cpu_in_reset(cpu);
  77        flowctrl_write_cpu_halt(cpu, 0);
  78
  79        /*
  80         * The power up sequence of cold boot CPU and warm boot CPU
  81         * was different.
  82         *
  83         * For warm boot CPU that was resumed from CPU hotplug, the
  84         * power will be resumed automatically after un-halting the
  85         * flow controller of the warm boot CPU. We need to wait for
  86         * the confirmaiton that the CPU is powered then removing
  87         * the IO clamps.
  88         * For cold boot CPU, do not wait. After the cold boot CPU be
  89         * booted, it will run to tegra_secondary_init() and set
  90         * tegra_cpu_init_mask which influences what tegra30_boot_secondary()
  91         * next time around.
  92         */
  93        if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) {
  94                timeout = jiffies + msecs_to_jiffies(50);
  95                do {
  96                        if (tegra_pmc_cpu_is_powered(cpu))
  97                                goto remove_clamps;
  98                        udelay(10);
  99                } while (time_before(jiffies, timeout));
 100        }
 101
 102        /*
 103         * The power status of the cold boot CPU is power gated as
 104         * default. To power up the cold boot CPU, the power should
 105         * be un-gated by un-toggling the power gate register
 106         * manually.
 107         */
 108        ret = tegra_pmc_cpu_power_on(cpu);
 109        if (ret)
 110                return ret;
 111
 112remove_clamps:
 113        /* CPU partition is powered. Enable the CPU clock. */
 114        tegra_enable_cpu_clock(cpu);
 115        udelay(10);
 116
 117        /* Remove I/O clamps. */
 118        ret = tegra_pmc_cpu_remove_clamping(cpu);
 119        if (ret)
 120                return ret;
 121
 122        udelay(10);
 123
 124        flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */
 125        tegra_cpu_out_of_reset(cpu);
 126        return 0;
 127}
 128
 129static int tegra114_boot_secondary(unsigned int cpu, struct task_struct *idle)
 130{
 131        int ret = 0;
 132
 133        cpu = cpu_logical_map(cpu);
 134
 135        if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) {
 136                /*
 137                 * Warm boot flow
 138                 * The flow controller in charge of the power state and
 139                 * control for each CPU.
 140                 */
 141                /* set SCLK as event trigger for flow controller */
 142                flowctrl_write_cpu_csr(cpu, 1);
 143                flowctrl_write_cpu_halt(cpu,
 144                                FLOW_CTRL_WAITEVENT | FLOW_CTRL_SCLK_RESUME);
 145        } else {
 146                /*
 147                 * Cold boot flow
 148                 * The CPU is powered up by toggling PMC directly. It will
 149                 * also initial power state in flow controller. After that,
 150                 * the CPU's power state is maintained by flow controller.
 151                 */
 152                ret = tegra_pmc_cpu_power_on(cpu);
 153        }
 154
 155        return ret;
 156}
 157
 158static int tegra_boot_secondary(unsigned int cpu,
 159                                          struct task_struct *idle)
 160{
 161        if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_get_chip_id() == TEGRA20)
 162                return tegra20_boot_secondary(cpu, idle);
 163        if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_get_chip_id() == TEGRA30)
 164                return tegra30_boot_secondary(cpu, idle);
 165        if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_get_chip_id() == TEGRA114)
 166                return tegra114_boot_secondary(cpu, idle);
 167        if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_get_chip_id() == TEGRA124)
 168                return tegra114_boot_secondary(cpu, idle);
 169
 170        return -EINVAL;
 171}
 172
 173static void __init tegra_smp_prepare_cpus(unsigned int max_cpus)
 174{
 175        /* Always mark the boot CPU (CPU0) as initialized. */
 176        cpumask_set_cpu(0, &tegra_cpu_init_mask);
 177
 178        if (scu_a9_has_base())
 179                scu_enable(IO_ADDRESS(scu_a9_get_base()));
 180}
 181
 182const struct smp_operations tegra_smp_ops __initconst = {
 183        .smp_prepare_cpus       = tegra_smp_prepare_cpus,
 184        .smp_secondary_init     = tegra_secondary_init,
 185        .smp_boot_secondary     = tegra_boot_secondary,
 186#ifdef CONFIG_HOTPLUG_CPU
 187        .cpu_kill               = tegra_cpu_kill,
 188        .cpu_die                = tegra_cpu_die,
 189#endif
 190};
 191