root/arch/arm/mach-imx/src.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. imx_src_reset_module
  2. imx_enable_cpu
  3. imx_set_cpu_jump
  4. imx_get_cpu_arg
  5. imx_set_cpu_arg
  6. imx_src_init

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Copyright 2011 Freescale Semiconductor, Inc.
   4  * Copyright 2011 Linaro Ltd.
   5  */
   6 
   7 #include <linux/init.h>
   8 #include <linux/io.h>
   9 #include <linux/of.h>
  10 #include <linux/of_address.h>
  11 #include <linux/reset-controller.h>
  12 #include <linux/smp.h>
  13 #include <asm/smp_plat.h>
  14 #include "common.h"
  15 
  16 #define SRC_SCR                         0x000
  17 #define SRC_GPR1                        0x020
  18 #define BP_SRC_SCR_WARM_RESET_ENABLE    0
  19 #define BP_SRC_SCR_SW_GPU_RST           1
  20 #define BP_SRC_SCR_SW_VPU_RST           2
  21 #define BP_SRC_SCR_SW_IPU1_RST          3
  22 #define BP_SRC_SCR_SW_OPEN_VG_RST       4
  23 #define BP_SRC_SCR_SW_IPU2_RST          12
  24 #define BP_SRC_SCR_CORE1_RST            14
  25 #define BP_SRC_SCR_CORE1_ENABLE         22
  26 
  27 static void __iomem *src_base;
  28 static DEFINE_SPINLOCK(scr_lock);
  29 
  30 static const int sw_reset_bits[5] = {
  31         BP_SRC_SCR_SW_GPU_RST,
  32         BP_SRC_SCR_SW_VPU_RST,
  33         BP_SRC_SCR_SW_IPU1_RST,
  34         BP_SRC_SCR_SW_OPEN_VG_RST,
  35         BP_SRC_SCR_SW_IPU2_RST
  36 };
  37 
  38 static int imx_src_reset_module(struct reset_controller_dev *rcdev,
  39                 unsigned long sw_reset_idx)
  40 {
  41         unsigned long timeout;
  42         unsigned long flags;
  43         int bit;
  44         u32 val;
  45 
  46         if (!src_base)
  47                 return -ENODEV;
  48 
  49         if (sw_reset_idx >= ARRAY_SIZE(sw_reset_bits))
  50                 return -EINVAL;
  51 
  52         bit = 1 << sw_reset_bits[sw_reset_idx];
  53 
  54         spin_lock_irqsave(&scr_lock, flags);
  55         val = readl_relaxed(src_base + SRC_SCR);
  56         val |= bit;
  57         writel_relaxed(val, src_base + SRC_SCR);
  58         spin_unlock_irqrestore(&scr_lock, flags);
  59 
  60         timeout = jiffies + msecs_to_jiffies(1000);
  61         while (readl(src_base + SRC_SCR) & bit) {
  62                 if (time_after(jiffies, timeout))
  63                         return -ETIME;
  64                 cpu_relax();
  65         }
  66 
  67         return 0;
  68 }
  69 
  70 static const struct reset_control_ops imx_src_ops = {
  71         .reset = imx_src_reset_module,
  72 };
  73 
  74 static struct reset_controller_dev imx_reset_controller = {
  75         .ops = &imx_src_ops,
  76         .nr_resets = ARRAY_SIZE(sw_reset_bits),
  77 };
  78 
  79 void imx_enable_cpu(int cpu, bool enable)
  80 {
  81         u32 mask, val;
  82 
  83         cpu = cpu_logical_map(cpu);
  84         mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1);
  85         spin_lock(&scr_lock);
  86         val = readl_relaxed(src_base + SRC_SCR);
  87         val = enable ? val | mask : val & ~mask;
  88         val |= 1 << (BP_SRC_SCR_CORE1_RST + cpu - 1);
  89         writel_relaxed(val, src_base + SRC_SCR);
  90         spin_unlock(&scr_lock);
  91 }
  92 
  93 void imx_set_cpu_jump(int cpu, void *jump_addr)
  94 {
  95         cpu = cpu_logical_map(cpu);
  96         writel_relaxed(__pa_symbol(jump_addr),
  97                        src_base + SRC_GPR1 + cpu * 8);
  98 }
  99 
 100 u32 imx_get_cpu_arg(int cpu)
 101 {
 102         cpu = cpu_logical_map(cpu);
 103         return readl_relaxed(src_base + SRC_GPR1 + cpu * 8 + 4);
 104 }
 105 
 106 void imx_set_cpu_arg(int cpu, u32 arg)
 107 {
 108         cpu = cpu_logical_map(cpu);
 109         writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4);
 110 }
 111 
 112 void __init imx_src_init(void)
 113 {
 114         struct device_node *np;
 115         u32 val;
 116 
 117         np = of_find_compatible_node(NULL, NULL, "fsl,imx51-src");
 118         if (!np)
 119                 return;
 120         src_base = of_iomap(np, 0);
 121         WARN_ON(!src_base);
 122 
 123         imx_reset_controller.of_node = np;
 124         if (IS_ENABLED(CONFIG_RESET_CONTROLLER))
 125                 reset_controller_register(&imx_reset_controller);
 126 
 127         /*
 128          * force warm reset sources to generate cold reset
 129          * for a more reliable restart
 130          */
 131         spin_lock(&scr_lock);
 132         val = readl_relaxed(src_base + SRC_SCR);
 133         val &= ~(1 << BP_SRC_SCR_WARM_RESET_ENABLE);
 134         writel_relaxed(val, src_base + SRC_SCR);
 135         spin_unlock(&scr_lock);
 136 }

/* [<][>][^][v][top][bottom][index][help] */