Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (C) 2001,2002,2004 Broadcom Corporation
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  * These are routines for dealing with the bcm1480 smp capabilities
0022  * independent of board/firmware
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  * SMP init and finish on secondary CPUs
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     /* Set interrupt mask, but don't enable */
0055     change_c0_status(ST0_IM, imask);
0056 }
0057 
0058 /*
0059  * These are routines for dealing with the sb1250 smp capabilities
0060  * independent of board/firmware
0061  */
0062 
0063 /*
0064  * Simple enough; everything is set up, so just poke the appropriate mailbox
0065  * register, and we should be set
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  * Code to run on secondary just after probing the CPU
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  * Do any tidying up before marking online and running the idle
0093  * loop
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  * Setup the PC, SP, and GP of a secondary processor and start it
0105  * running!
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  * Use CFE to find out how many CPUs are available, setting up
0121  * cpu_possible_mask and the logical/physical mappings.
0122  * XXXKW will the boot CPU ever not be physical 0?
0123  *
0124  * Common setup before any secondaries are started
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     /* Load the mailbox register to figure out what we're supposed to do */
0166     action = (__raw_readq(mailbox_0_regs[cpu]) >> 48) & 0xffff;
0167 
0168     /* Clear the mailbox to clear the interrupt */
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 }