0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/kernel.h>
0009 #include <linux/io.h>
0010 #include <linux/spinlock.h>
0011 #include <linux/reset/bcm63xx_pmb.h>
0012 #include <linux/of.h>
0013 #include <linux/of_address.h>
0014
0015 #include "bcm63xx_smp.h"
0016
0017
0018 #define CORE_PWR_CTRL_SHIFT 0
0019 #define CORE_PWR_CTRL_MASK 0x3
0020 #define PLL_PWR_ON BIT(8)
0021 #define PLL_LDO_PWR_ON BIT(9)
0022 #define PLL_CLAMP_ON BIT(10)
0023 #define CPU_RESET_N(x) BIT(13 + (x))
0024 #define NEON_RESET_N BIT(15)
0025 #define PWR_CTRL_STATUS_SHIFT 28
0026 #define PWR_CTRL_STATUS_MASK 0x3
0027 #define PWR_DOWN_SHIFT 30
0028 #define PWR_DOWN_MASK 0x3
0029
0030
0031 #define MEM_PWR_OK BIT(0)
0032 #define MEM_PWR_ON BIT(1)
0033 #define MEM_CLAMP_ON BIT(2)
0034 #define MEM_PWR_OK_STATUS BIT(4)
0035 #define MEM_PWR_ON_STATUS BIT(5)
0036 #define MEM_PDA_SHIFT 8
0037 #define MEM_PDA_MASK 0xf
0038 #define MEM_PDA_CPU_MASK 0x1
0039 #define MEM_PDA_NEON_MASK 0xf
0040 #define CLAMP_ON BIT(15)
0041 #define PWR_OK_SHIFT 16
0042 #define PWR_OK_MASK 0xf
0043 #define PWR_ON_SHIFT 20
0044 #define PWR_CPU_MASK 0x03
0045 #define PWR_NEON_MASK 0x01
0046 #define PWR_ON_MASK 0xf
0047 #define PWR_OK_STATUS_SHIFT 24
0048 #define PWR_OK_STATUS_MASK 0xf
0049 #define PWR_ON_STATUS_SHIFT 28
0050 #define PWR_ON_STATUS_MASK 0xf
0051
0052 #define ARM_CONTROL 0x30
0053 #define ARM_PWR_CONTROL_BASE 0x34
0054 #define ARM_PWR_CONTROL(x) (ARM_PWR_CONTROL_BASE + (x) * 0x4)
0055 #define ARM_NEON_L2 0x3c
0056
0057
0058
0059
0060 static int bpcm_wr_rd_mask(void __iomem *master,
0061 unsigned int addr, u32 off, u32 *val,
0062 u32 shift, u32 mask, u32 cond)
0063 {
0064 int ret;
0065
0066 ret = bpcm_wr(master, addr, off, *val);
0067 if (ret)
0068 return ret;
0069
0070 do {
0071 ret = bpcm_rd(master, addr, off, val);
0072 if (ret)
0073 return ret;
0074
0075 cpu_relax();
0076 } while (((*val >> shift) & mask) != cond);
0077
0078 return ret;
0079 }
0080
0081
0082
0083
0084 static DEFINE_SPINLOCK(pmb_lock);
0085
0086 static int bcm63xx_pmb_get_resources(struct device_node *dn,
0087 void __iomem **base,
0088 unsigned int *cpu,
0089 unsigned int *addr)
0090 {
0091 struct of_phandle_args args;
0092 int ret;
0093
0094 *cpu = of_get_cpu_hwid(dn, 0);
0095 if (*cpu == ~0U) {
0096 pr_err("CPU is missing a reg node\n");
0097 return -ENODEV;
0098 }
0099
0100 ret = of_parse_phandle_with_args(dn, "resets", "#reset-cells",
0101 0, &args);
0102 if (ret) {
0103 pr_err("CPU is missing a resets phandle\n");
0104 return ret;
0105 }
0106
0107 if (args.args_count != 2) {
0108 pr_err("reset-controller does not conform to reset-cells\n");
0109 return -EINVAL;
0110 }
0111
0112 *base = of_iomap(args.np, 0);
0113 if (!*base) {
0114 pr_err("failed remapping PMB register\n");
0115 return -ENOMEM;
0116 }
0117
0118
0119 *addr = args.args[0];
0120
0121 return 0;
0122 }
0123
0124 int bcm63xx_pmb_power_on_cpu(struct device_node *dn)
0125 {
0126 void __iomem *base;
0127 unsigned int cpu, addr;
0128 unsigned long flags;
0129 u32 val, ctrl;
0130 int ret;
0131
0132 ret = bcm63xx_pmb_get_resources(dn, &base, &cpu, &addr);
0133 if (ret)
0134 return ret;
0135
0136
0137 WARN_ON(cpu > 1);
0138
0139 spin_lock_irqsave(&pmb_lock, flags);
0140
0141
0142
0143
0144
0145 ret = bpcm_rd(base, addr, ARM_CONTROL, &ctrl);
0146 if (ret)
0147 goto out;
0148
0149 if (ctrl & CPU_RESET_N(cpu)) {
0150 pr_info("PMB: CPU%d is already powered on\n", cpu);
0151 ret = 0;
0152 goto out;
0153 }
0154
0155
0156 ret = bpcm_rd(base, addr, ARM_PWR_CONTROL(cpu), &val);
0157 if (ret)
0158 goto out;
0159
0160 val |= (PWR_CPU_MASK << PWR_ON_SHIFT);
0161
0162 ret = bpcm_wr_rd_mask(base, addr, ARM_PWR_CONTROL(cpu), &val,
0163 PWR_ON_STATUS_SHIFT, PWR_CPU_MASK, PWR_CPU_MASK);
0164 if (ret)
0165 goto out;
0166
0167 val |= (PWR_CPU_MASK << PWR_OK_SHIFT);
0168
0169 ret = bpcm_wr_rd_mask(base, addr, ARM_PWR_CONTROL(cpu), &val,
0170 PWR_OK_STATUS_SHIFT, PWR_CPU_MASK, PWR_CPU_MASK);
0171 if (ret)
0172 goto out;
0173
0174 val &= ~CLAMP_ON;
0175
0176 ret = bpcm_wr(base, addr, ARM_PWR_CONTROL(cpu), val);
0177 if (ret)
0178 goto out;
0179
0180
0181 val &= ~(MEM_PDA_MASK << MEM_PDA_SHIFT);
0182
0183 ret = bpcm_wr(base, addr, ARM_PWR_CONTROL(cpu), val);
0184 if (ret)
0185 goto out;
0186
0187 val |= MEM_PWR_ON;
0188
0189 ret = bpcm_wr_rd_mask(base, addr, ARM_PWR_CONTROL(cpu), &val,
0190 0, MEM_PWR_ON_STATUS, MEM_PWR_ON_STATUS);
0191 if (ret)
0192 goto out;
0193
0194 val |= MEM_PWR_OK;
0195
0196 ret = bpcm_wr_rd_mask(base, addr, ARM_PWR_CONTROL(cpu), &val,
0197 0, MEM_PWR_OK_STATUS, MEM_PWR_OK_STATUS);
0198 if (ret)
0199 goto out;
0200
0201 val &= ~MEM_CLAMP_ON;
0202
0203 ret = bpcm_wr(base, addr, ARM_PWR_CONTROL(cpu), val);
0204 if (ret)
0205 goto out;
0206
0207
0208 ctrl |= CPU_RESET_N(cpu);
0209
0210 ret = bpcm_wr(base, addr, ARM_CONTROL, ctrl);
0211 out:
0212 spin_unlock_irqrestore(&pmb_lock, flags);
0213 iounmap(base);
0214 return ret;
0215 }