MIPS: Netlogic: Introduce support for multi-node
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 12/15 MIPS: Netlogic: Introduce support for multi-node
Upto 4 Netlogic XLP SoCs can be connected over ICI links to form a coherent multi-node system. Each SoC has its own set of on-chip devices including PIC. To support this, add a per SoC stucture and use it for the PIC and SYS block addresses instead of using global variables.
--- arch/mips/include/asm/netlogic/common.h | 42 +++++++++++++++++--- arch/mips/include/asm/netlogic/mips-extns.h | 5 +++ arch/mips/include/asm/netlogic/xlp-hal/pic.h | 1 - arch/mips/include/asm/netlogic/xlp-hal/sys.h | 1 - arch/mips/include/asm/netlogic/xlr/pic.h | 2 - arch/mips/netlogic/common/irq.c | 55 +++++++++++++++++--------- arch/mips/netlogic/common/smp.c | 47 +++++++++++++--------- arch/mips/netlogic/xlp/nlm_hal.c | 29 +++++++------- arch/mips/netlogic/xlp/setup.c | 17 ++++---- arch/mips/netlogic/xlp/wakeup.c | 22 +++++++---- arch/mips/netlogic/xlr/setup.c | 20 ++++++---- arch/mips/netlogic/xlr/wakeup.c | 20 +++++++++- 12 files changed, 175 insertions(+), 86 deletions(-)
arch/mips/include/asm/netlogic/common.h +37 -5
@@ -46,10 +46,10 @@#ifndef __ASSEMBLY__#include <linux/cpumask.h> +#include <linux/spinlock.h> +#include <asm/irq.h> struct irq_desc ; -extern struct plat_smp_ops nlm_smp_ops; -extern char nlm_reset_entry[], nlm_reset_entry_end[];void nlm_smp_function_ipi_handler (unsigned int irq,struct irq_desc *desc);void nlm_smp_resched_ipi_handler (unsigned int irq,struct irq_desc *desc);void nlm_smp_irq_init (void );
@@ -70,10 +70,42 @@ nlm_set_nmi_handler(void *handler)* Misc. */ unsigned int nlm_get_cpu_frequency (void ); +void nlm_node_init (int node); +extern struct plat_smp_ops nlm_smp_ops; +extern char nlm_reset_entry[], nlm_reset_entry_end[]; -extern unsigned long nlm_common_ebase; -extern int nlm_threads_per_core; -extern uint32_t nlm_coremask; +extern unsigned int nlm_threads_per_core;extern cpumask_t nlm_cpumask; + +struct nlm_soc_info { +unsigned long coremask;/* cores enabled on the soc */ +unsigned long ebase; +uint64_t irqmask; +uint64_t sysbase;/* only for XLP */ +uint64_t picbase; +spinlock_t piclock; +}; + +#define NLM_CORES_PER_NODE 8 +#define NLM_THREADS_PER_CORE 4 +#define NLM_CPUS_PER_NODE (NLM_CORES_PER_NODE * NLM_THREADS_PER_CORE) +#define nlm_get_node (i) (&nlm_nodes[i]) +#define NLM_NR_NODES 1 +#define nlm_current_node () (&nlm_nodes[0]) + +struct irq_data ; +uint64_t nlm_pci_irqmask (int node); +void nlm_set_pic_extra_ack (int node,int irq,void (*xack)(struct irq_data *)); + +/* +* The NR_IRQs is divided between nodes, each of them has a separate irq space +*/ +static inline int nlm_irq_to_xirq (int node,int irq) +{ +return node *NR_IRQS /NLM_NR_NODES + irq; +} + +extern struct nlm_soc_info nlm_nodes[NLM_NR_NODES ]; +extern int nlm_cpu_ready[];#endif #endif /* _NETLOGIC_COMMON_H_ */
arch/mips/include/asm/netlogic/mips-extns.h +5 -0
@@ -73,4 +73,9 @@ static inline int hard_smp_processor_id(void) return __read_32bit_c0_register($15, 1) & 0x3ff; } +static inline int nlm_nodeid (void ) +{ +return (__read_32bit_c0_register ($15,1 ) >>5 ) &0x3 ; +} +#endif /*_ASM_NLM_MIPS_EXTS_H */
arch/mips/include/asm/netlogic/xlp-hal/pic.h +0 -1
@@ -381,7 +381,6 @@ nlm_pic_init_irt(uint64_t base, int irt, int irq, int hwt)nlm_pic_write_irt_direct (base, irt,0 ,0 ,0 , irq, hwt); } -extern uint64_t nlm_pic_base;int nlm_irq_to_irt (int irq);int nlm_irt_to_irq (int irt);
arch/mips/include/asm/netlogic/xlp-hal/sys.h +0 -1
@@ -124,6 +124,5 @@#define nlm_get_sys_pcibase (node) nlm_pcicfg_base(XLP_IO_SYS_OFFSET(node))#define nlm_get_sys_regbase (node) (nlm_get_sys_pcibase(node) + XLP_IO_PCI_HDRSZ) -extern uint64_t nlm_sys_base;#endif #endif
arch/mips/include/asm/netlogic/xlr/pic.h +0 -2
@@ -258,7 +258,5 @@ nlm_pic_init_irt(uint64_t base, int irt, int irq, int hwt)nlm_write_reg (base,PIC_IRT_1 (irt), (1 <<30 ) | (1 <<6 ) | irq); } - -extern uint64_t nlm_pic_base;#endif #endif /* _ASM_NLM_XLR_PIC_H */
arch/mips/netlogic/common/irq.c +36 -19
138 lines not on this page · raw message
arch/mips/netlogic/common/smp.c +29 -18
108 lines not on this page · raw message
arch/mips/netlogic/xlp/nlm_hal.c +15 -14
@@ -40,23 +40,23 @@#include <asm/mipsregs.h> #include <asm/time.h> +#include <asm/netlogic/common.h> #include <asm/netlogic/haldefs.h> #include <asm/netlogic/xlp-hal/iomap.h> #include <asm/netlogic/xlp-hal/xlp.h> #include <asm/netlogic/xlp-hal/pic.h> #include <asm/netlogic/xlp-hal/sys.h> -/* These addresses are computed by the nlm_hal_init() */ -uint64_t nlm_io_base; -uint64_t nlm_sys_base; -uint64_t nlm_pic_base; -/* Main initialization */ -void nlm_hal_init (void ) +void nlm_node_init (int node) { - nlm_io_base =CKSEG1ADDR (XLP_DEFAULT_IO_BASE ); - nlm_sys_base =nlm_get_sys_regbase (0 );/* node 0 */ - nlm_pic_base =nlm_get_pic_regbase (0 );/* node 0 */ +struct nlm_soc_info *nodep; + + nodep =nlm_get_node (node); + nodep->sysbase =nlm_get_sys_regbase (node); + nodep->picbase =nlm_get_pic_regbase (node); + nodep->ebase =read_c0_ebase () & (~((1 <<12 ) -1 )); +spin_lock_init (&nodep->piclock); }int nlm_irq_to_irt (int irq)
@@ -138,14 +138,15 @@ int nlm_irt_to_irq(int irt) } } -unsigned int nlm_get_core_frequency (int core) +unsigned int nlm_get_core_frequency (int node,int core) {unsigned int pll_divf, pll_divr, dfs_div, ext_div;unsigned int rstval, dfsval, denom; -uint64_t num; +uint64_t num, sysbase; - rstval =nlm_read_sys_reg (nlm_sys_base,SYS_POWER_ON_RESET_CFG ); - dfsval =nlm_read_sys_reg (nlm_sys_base,SYS_CORE_DFS_DIV_VALUE ); + sysbase =nlm_get_node (node)->sysbase; + rstval =nlm_read_sys_reg (sysbase,SYS_POWER_ON_RESET_CFG ); + dfsval =nlm_read_sys_reg (sysbase,SYS_CORE_DFS_DIV_VALUE ); pll_divf = ((rstval >>10 ) &0x7f ) +1 ; pll_divr = ((rstval >>8 ) &0x3 ) +1 ; ext_div = ((rstval >>30 ) &0x3 ) +1 ;
@@ -159,5 +160,5 @@ unsigned int nlm_get_core_frequency(int core)unsigned int nlm_get_cpu_frequency (void ) { -return nlm_get_core_frequency (0 ); +return nlm_get_core_frequency (0 ,0 ); }
arch/mips/netlogic/xlp/setup.c +8 -9
@@ -52,17 +52,17 @@#include <asm/netlogic/xlp-hal/xlp.h> #include <asm/netlogic/xlp-hal/sys.h> -unsigned long nlm_common_ebase =0x0 ; - -/* default to uniprocessor */ -uint32_t nlm_coremask =1 ; +uint64_t nlm_io_base; +struct nlm_soc_info nlm_nodes[NLM_NR_NODES ];cpumask_t nlm_cpumask =CPU_MASK_CPU0 ; -int nlm_threads_per_core =1 ; +unsigned int nlm_threads_per_core;extern u32 __dtb_start[];static void nlm_linux_exit (void ) { -nlm_write_sys_reg (nlm_sys_base,SYS_CHIP_RESET ,1 ); +uint64_t sysbase =nlm_get_node (0 )->sysbase; + +nlm_write_sys_reg (sysbase,SYS_CHIP_RESET ,1 );for ( ; ; )cpu_wait (); }
@@ -110,10 +110,9 @@ void xlp_mmu_init(void)void __init prom_init (void ) { + nlm_io_base =CKSEG1ADDR (XLP_DEFAULT_IO_BASE );xlp_mmu_init (); -nlm_hal_init (); - - nlm_common_ebase =read_c0_ebase () & (~((1 <<12 ) -1 )); +nlm_node_init (0 );#ifdef CONFIG_SMP cpumask_setall (&nlm_cpumask);
arch/mips/netlogic/xlp/wakeup.c +14 -8
@@ -79,32 +79,38 @@ static int xlp_wakeup_core(uint64_t sysbase, int core)static void xlp_enable_secondary_cores (const cpumask_t *wakeup_mask) { -uint64_t syspcibase, sysbase; +struct nlm_soc_info *nodep; +uint64_t syspcibase;uint32_t syscoremask; -int core, n; +int core, n, cpu; -for (n =0 ; n <4 ; n++) { +for (n =0 ; n <NLM_NR_NODES ; n++) { syspcibase =nlm_get_sys_pcibase (n);if (nlm_read_reg (syspcibase,0 ) ==0xffffffff )break ;/* read cores in reset from SYS and account for boot cpu */ - sysbase =nlm_get_sys_regbase (n); - syscoremask =nlm_read_sys_reg (sysbase,SYS_CPU_RESET ); +nlm_node_init (n); + nodep =nlm_get_node (n); + syscoremask =nlm_read_sys_reg (nodep->sysbase,SYS_CPU_RESET );if (n ==0 ) syscoremask |=1 ; -for (core =0 ; core <8 ; core++) { +for (core =0 ; core <NLM_CORES_PER_NODE ; core++) {/* see if the core exists */ if ((syscoremask & (1 << core)) ==0 )continue ;/* see if at least the first thread is enabled */ -if (!cpumask_test_cpu ((n *8 + core) *4 , wakeup_mask)) + cpu = (n *NLM_CORES_PER_NODE + core) + *NLM_THREADS_PER_CORE ; +if (!cpumask_test_cpu (cpu, wakeup_mask))continue ;/* wake up the core */ -if (!xlp_wakeup_core (sysbase, core)) +if (xlp_wakeup_core (nodep->sysbase, core)) + nodep->coremask |=1u << core; +else pr_err ("Failed to enable core %d\n" , core); } }
arch/mips/netlogic/xlr/setup.c +13 -7
@@ -51,14 +51,11 @@#include <asm/netlogic/xlr/gpio.h> uint64_t nlm_io_base =DEFAULT_NETLOGIC_IO_BASE ; -uint64_t nlm_pic_base;struct psb_info nlm_prom_info; -unsigned long nlm_common_ebase =0x0 ; -/* default to uniprocessor */ -uint32_t nlm_coremask =1 ; -int nlm_threads_per_core =1 ; +unsigned int nlm_threads_per_core =1 ; +struct nlm_soc_info nlm_nodes[NLM_NR_NODES ];cpumask_t nlm_cpumask =CPU_MASK_CPU0 ;static void __init nlm_early_serial_setup (void )
@@ -177,6 +174,16 @@ static void prom_add_memory(void) } } +static void nlm_init_node (void ) +{ +struct nlm_soc_info *nodep; + + nodep =nlm_current_node (); + nodep->picbase =nlm_mmio_base (NETLOGIC_IO_PIC_OFFSET ); + nodep->ebase =read_c0_ebase () & (~((1 <<12 ) -1 )); +spin_lock_init (&nodep->piclock); +} +void __init prom_init (void ) {int i, *argv, *envp;/* passed as 32 bit ptrs */
@@ -188,11 +195,10 @@ void __init prom_init(void) prom_infop = (struct psb_info *)(long )(int )fw_arg3; nlm_prom_info = *prom_infop; - nlm_pic_base =nlm_mmio_base (NETLOGIC_IO_PIC_OFFSET ); +nlm_init_node ();nlm_early_serial_setup ();build_arcs_cmdline (argv); - nlm_common_ebase =read_c0_ebase () & (~((1 <<12 ) -1 ));prom_add_memory ();#ifdef CONFIG_SMP
arch/mips/netlogic/xlr/wakeup.c +18 -2
@@ -50,18 +50,34 @@int __cpuinit xlr_wakeup_secondary_cpus (void ) { -unsigned int i, boot_cpu; +struct nlm_soc_info *nodep; +unsigned int i, j, boot_cpu;/* * In case of RMI boot, hit with NMI to get the cores * from bootloader to linux code. */ + nodep =nlm_get_node (0 ); boot_cpu =hard_smp_processor_id ();nlm_set_nmi_handler (nlm_rmiboot_preboot);for (i =0 ; i <NR_CPUS ; i++) {if (i == boot_cpu || !cpumask_test_cpu (i, &nlm_cpumask))continue ; -nlm_pic_send_ipi (nlm_pic_base, i,1 ,1 );/* send NMI */ +nlm_pic_send_ipi (nodep->picbase, i,1 ,1 );/* send NMI */ + } + +/* Fill up the coremask early */ + nodep->coremask =1 ; +for (i =1 ; i <NLM_CORES_PER_NODE ; i++) { +for (j =1000000 ; j >0 ; j--) { +if (nlm_cpu_ready[i *NLM_THREADS_PER_CORE ]) +break ; +udelay (10 ); + } +if (j !=0 ) + nodep->coremask |= (1u << i); +else +pr_err ("Failed to wakeup core %d\n" , i); }return 0 ;
Signature · 1 line
1.7.9.5
Quoted 7 lines · Jayachandran C
Upto 4 Netlogic XLP SoCs can be connected over ICI links to form a coherent multi-node system. Each SoC has its own set of on-chip devices including PIC. To support this, add a per SoC stucture and use it for the PIC and SYS block addresses instead of using global variables.
Signed-off-by Jayachandran C <[email protected]>
This is an older version of the patch, please ignore. I have marked it superceded in patchwork as well.
JC.