0001
0002
0003
0004
0005
0006 #include <linux/init.h>
0007 #include <linux/delay.h>
0008 #include <linux/smp.h>
0009 #include <linux/kernel_stat.h>
0010 #include <linux/sched.h>
0011 #include <linux/sched/task_stack.h>
0012
0013 #include <asm/mmu_context.h>
0014 #include <asm/io.h>
0015 #include <asm/fw/cfe/cfe_api.h>
0016 #include <asm/sibyte/sb1250.h>
0017 #include <asm/sibyte/bcm1480_regs.h>
0018 #include <asm/sibyte/bcm1480_int.h>
0019
0020
0021
0022
0023
0024
0025 static void *mailbox_0_set_regs[] = {
0026 IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
0027 IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
0028 IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
0029 IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
0030 };
0031
0032 static void *mailbox_0_clear_regs[] = {
0033 IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
0034 IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
0035 IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
0036 IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
0037 };
0038
0039 static void *mailbox_0_regs[] = {
0040 IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
0041 IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
0042 IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
0043 IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
0044 };
0045
0046
0047
0048
0049 void bcm1480_smp_init(void)
0050 {
0051 unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
0052 STATUSF_IP1 | STATUSF_IP0;
0053
0054
0055 change_c0_status(ST0_IM, imask);
0056 }
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 static void bcm1480_send_ipi_single(int cpu, unsigned int action)
0068 {
0069 __raw_writeq((((u64)action)<< 48), mailbox_0_set_regs[cpu]);
0070 }
0071
0072 static void bcm1480_send_ipi_mask(const struct cpumask *mask,
0073 unsigned int action)
0074 {
0075 unsigned int i;
0076
0077 for_each_cpu(i, mask)
0078 bcm1480_send_ipi_single(i, action);
0079 }
0080
0081
0082
0083
0084 static void bcm1480_init_secondary(void)
0085 {
0086 extern void bcm1480_smp_init(void);
0087
0088 bcm1480_smp_init();
0089 }
0090
0091
0092
0093
0094
0095 static void bcm1480_smp_finish(void)
0096 {
0097 extern void sb1480_clockevent_init(void);
0098
0099 sb1480_clockevent_init();
0100 local_irq_enable();
0101 }
0102
0103
0104
0105
0106
0107 static int bcm1480_boot_secondary(int cpu, struct task_struct *idle)
0108 {
0109 int retval;
0110
0111 retval = cfe_cpu_start(cpu_logical_map(cpu), &smp_bootstrap,
0112 __KSTK_TOS(idle),
0113 (unsigned long)task_thread_info(idle), 0);
0114 if (retval != 0)
0115 printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);
0116 return retval;
0117 }
0118
0119
0120
0121
0122
0123
0124
0125
0126 static void __init bcm1480_smp_setup(void)
0127 {
0128 int i, num;
0129
0130 init_cpu_possible(cpumask_of(0));
0131 __cpu_number_map[0] = 0;
0132 __cpu_logical_map[0] = 0;
0133
0134 for (i = 1, num = 0; i < NR_CPUS; i++) {
0135 if (cfe_cpu_stop(i) == 0) {
0136 set_cpu_possible(i, true);
0137 __cpu_number_map[i] = ++num;
0138 __cpu_logical_map[num] = i;
0139 }
0140 }
0141 printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num);
0142 }
0143
0144 static void __init bcm1480_prepare_cpus(unsigned int max_cpus)
0145 {
0146 }
0147
0148 const struct plat_smp_ops bcm1480_smp_ops = {
0149 .send_ipi_single = bcm1480_send_ipi_single,
0150 .send_ipi_mask = bcm1480_send_ipi_mask,
0151 .init_secondary = bcm1480_init_secondary,
0152 .smp_finish = bcm1480_smp_finish,
0153 .boot_secondary = bcm1480_boot_secondary,
0154 .smp_setup = bcm1480_smp_setup,
0155 .prepare_cpus = bcm1480_prepare_cpus,
0156 };
0157
0158 void bcm1480_mailbox_interrupt(void)
0159 {
0160 int cpu = smp_processor_id();
0161 int irq = K_BCM1480_INT_MBOX_0_0;
0162 unsigned int action;
0163
0164 kstat_incr_irq_this_cpu(irq);
0165
0166 action = (__raw_readq(mailbox_0_regs[cpu]) >> 48) & 0xffff;
0167
0168
0169 __raw_writeq(((u64)action)<<48, mailbox_0_clear_regs[cpu]);
0170
0171 if (action & SMP_RESCHEDULE_YOURSELF)
0172 scheduler_ipi();
0173
0174 if (action & SMP_CALL_FUNCTION) {
0175 irq_enter();
0176 generic_smp_call_function_interrupt();
0177 irq_exit();
0178 }
0179 }