diff options
Diffstat (limited to 'arch/mips/netlogic')
-rw-r--r-- | arch/mips/netlogic/Kconfig | 9 | ||||
-rw-r--r-- | arch/mips/netlogic/common/irq.c | 10 | ||||
-rw-r--r-- | arch/mips/netlogic/common/reset.S | 22 | ||||
-rw-r--r-- | arch/mips/netlogic/common/smp.c | 25 | ||||
-rw-r--r-- | arch/mips/netlogic/common/time.c | 1 | ||||
-rw-r--r-- | arch/mips/netlogic/xlp/ahci-init.c | 2 | ||||
-rw-r--r-- | arch/mips/netlogic/xlp/dt.c | 10 | ||||
-rw-r--r-- | arch/mips/netlogic/xlp/nlm_hal.c | 57 | ||||
-rw-r--r-- | arch/mips/netlogic/xlp/setup.c | 7 | ||||
-rw-r--r-- | arch/mips/netlogic/xlp/usb-init-xlp2.c | 10 | ||||
-rw-r--r-- | arch/mips/netlogic/xlp/wakeup.c | 10 |
11 files changed, 110 insertions, 53 deletions
diff --git a/arch/mips/netlogic/Kconfig b/arch/mips/netlogic/Kconfig index 0823321c10e0..fb00606e352d 100644 --- a/arch/mips/netlogic/Kconfig +++ b/arch/mips/netlogic/Kconfig @@ -41,6 +41,15 @@ config DT_XLP_GVP pointer to the kernel. The corresponding DTS file is at arch/mips/netlogic/dts/xlp_gvp.dts +config DT_XLP_RVP + bool "Built-in device tree for XLP RVP boards" + default y + help + Add an FDT blob for XLP RVP board into the kernel. + This DTB will be used if the firmware does not pass in a DTB + pointer to the kernel. The corresponding DTS file is at + arch/mips/netlogic/dts/xlp_rvp.dts + config NLM_MULTINODE bool "Support for multi-chip boards" depends on NLM_XLP_BOARD diff --git a/arch/mips/netlogic/common/irq.c b/arch/mips/netlogic/common/irq.c index c100b9afa0ab..5f5d18b0e94d 100644 --- a/arch/mips/netlogic/common/irq.c +++ b/arch/mips/netlogic/common/irq.c @@ -230,16 +230,16 @@ static void nlm_init_node_irqs(int node) } } -void nlm_smp_irq_init(int hwcpuid) +void nlm_smp_irq_init(int hwtid) { - int node, cpu; + int cpu, node; - node = nlm_cpuid_to_node(hwcpuid); - cpu = hwcpuid % nlm_threads_per_node(); + cpu = hwtid % nlm_threads_per_node(); + node = hwtid / nlm_threads_per_node(); if (cpu == 0 && node != 0) nlm_init_node_irqs(node); - write_c0_eimr(nlm_current_node()->irqmask); + write_c0_eimr(nlm_get_node(node)->irqmask); } asmlinkage void plat_irq_dispatch(void) diff --git a/arch/mips/netlogic/common/reset.S b/arch/mips/netlogic/common/reset.S index 701c4bcb9e47..edbab9b8691f 100644 --- a/arch/mips/netlogic/common/reset.S +++ b/arch/mips/netlogic/common/reset.S @@ -60,7 +60,7 @@ li t0, LSU_DEFEATURE mfcr t1, t0 - lui t2, 0xc080 /* SUE, Enable Unaligned Access, L2HPE */ + lui t2, 0x4080 /* Enable Unaligned Access, L2HPE */ or t1, t1, t2 mtcr t1, t0 @@ -235,6 +235,26 @@ EXPORT(nlm_boot_siblings) mfc0 v0, CP0_EBASE, 1 andi v0, 0x3ff /* v0 <- node/core */ + /* + * Errata: to avoid potential live lock, setup IFU_BRUB_RESERVE + * when running 4 threads per core + */ + andi v1, v0, 0x3 /* v1 <- thread id */ + bnez v1, 2f + nop + + /* thread 0 of each core. */ + li t0, CKSEG1ADDR(RESET_DATA_PHYS) + lw t1, BOOT_THREAD_MODE(t0) /* t1 <- thread mode */ + subu t1, 0x3 /* 4-thread per core mode? */ + bnez t1, 2f + nop + + li t0, IFU_BRUB_RESERVE + li t1, 0x55 + mtcr t1, t0 + _ehb +2: beqz v0, 4f /* boot cpu (cpuid == 0)? */ nop diff --git a/arch/mips/netlogic/common/smp.c b/arch/mips/netlogic/common/smp.c index e743bdd6e20c..dc3e327fbbac 100644 --- a/arch/mips/netlogic/common/smp.c +++ b/arch/mips/netlogic/common/smp.c @@ -59,17 +59,17 @@ void nlm_send_ipi_single(int logical_cpu, unsigned int action) { - int cpu, node; + unsigned int hwtid; uint64_t picbase; - cpu = cpu_logical_map(logical_cpu); - node = nlm_cpuid_to_node(cpu); - picbase = nlm_get_node(node)->picbase; + /* node id is part of hwtid, and needed for send_ipi */ + hwtid = cpu_logical_map(logical_cpu); + picbase = nlm_get_node(nlm_hwtid_to_node(hwtid))->picbase; if (action & SMP_CALL_FUNCTION) - nlm_pic_send_ipi(picbase, cpu, IRQ_IPI_SMP_FUNCTION, 0); + nlm_pic_send_ipi(picbase, hwtid, IRQ_IPI_SMP_FUNCTION, 0); if (action & SMP_RESCHEDULE_YOURSELF) - nlm_pic_send_ipi(picbase, cpu, IRQ_IPI_SMP_RESCHEDULE, 0); + nlm_pic_send_ipi(picbase, hwtid, IRQ_IPI_SMP_RESCHEDULE, 0); } void nlm_send_ipi_mask(const struct cpumask *mask, unsigned int action) @@ -120,6 +120,7 @@ static void nlm_init_secondary(void) hwtid = hard_smp_processor_id(); current_cpu_data.core = hwtid / NLM_THREADS_PER_CORE; + current_cpu_data.package = nlm_nodeid(); nlm_percpu_init(hwtid); nlm_smp_irq_init(hwtid); } @@ -145,16 +146,18 @@ static cpumask_t phys_cpu_present_mask; void nlm_boot_secondary(int logical_cpu, struct task_struct *idle) { - int cpu, node; + uint64_t picbase; + int hwtid; + + hwtid = cpu_logical_map(logical_cpu); + picbase = nlm_get_node(nlm_hwtid_to_node(hwtid))->picbase; - cpu = cpu_logical_map(logical_cpu); - node = nlm_cpuid_to_node(logical_cpu); nlm_next_sp = (unsigned long)__KSTK_TOS(idle); nlm_next_gp = (unsigned long)task_thread_info(idle); /* barrier for sp/gp store above */ __sync(); - nlm_pic_send_ipi(nlm_get_node(node)->picbase, cpu, 1, 1); /* NMI */ + nlm_pic_send_ipi(picbase, hwtid, 1, 1); /* NMI */ } void __init nlm_smp_setup(void) @@ -182,7 +185,7 @@ void __init nlm_smp_setup(void) __cpu_number_map[i] = num_cpus; __cpu_logical_map[num_cpus] = i; set_cpu_possible(num_cpus, true); - node = nlm_cpuid_to_node(i); + node = nlm_hwtid_to_node(i); cpumask_set_cpu(num_cpus, &nlm_get_node(node)->cpumask); ++num_cpus; } diff --git a/arch/mips/netlogic/common/time.c b/arch/mips/netlogic/common/time.c index 0c0a1a606f73..5873c83e65be 100644 --- a/arch/mips/netlogic/common/time.c +++ b/arch/mips/netlogic/common/time.c @@ -40,7 +40,6 @@ #include <asm/netlogic/interrupt.h> #include <asm/netlogic/common.h> #include <asm/netlogic/haldefs.h> -#include <asm/netlogic/common.h> #if defined(CONFIG_CPU_XLP) #include <asm/netlogic/xlp-hal/iomap.h> diff --git a/arch/mips/netlogic/xlp/ahci-init.c b/arch/mips/netlogic/xlp/ahci-init.c index a9d0fae02103..92be1a3258b1 100644 --- a/arch/mips/netlogic/xlp/ahci-init.c +++ b/arch/mips/netlogic/xlp/ahci-init.c @@ -151,7 +151,7 @@ static void nlm_sata_firmware_init(int node) static int __init nlm_ahci_init(void) { int node = 0; - int chip = read_c0_prid() & PRID_REV_MASK; + int chip = read_c0_prid() & PRID_IMP_MASK; if (chip == PRID_IMP_NETLOGIC_XLP3XX) nlm_sata_firmware_init(node); diff --git a/arch/mips/netlogic/xlp/dt.c b/arch/mips/netlogic/xlp/dt.c index 7cc46032b28e..a625bdb6d6aa 100644 --- a/arch/mips/netlogic/xlp/dt.c +++ b/arch/mips/netlogic/xlp/dt.c @@ -41,17 +41,21 @@ #include <asm/prom.h> -extern u32 __dtb_xlp_evp_begin[], __dtb_xlp_svp_begin[], - __dtb_xlp_fvp_begin[], __dtb_xlp_gvp_begin[]; +extern u32 __dtb_xlp_evp_begin[], __dtb_xlp_svp_begin[], __dtb_xlp_fvp_begin[], + __dtb_xlp_gvp_begin[], __dtb_xlp_rvp_begin[]; static void *xlp_fdt_blob; void __init *xlp_dt_init(void *fdtp) { if (!fdtp) { switch (current_cpu_data.processor_id & PRID_IMP_MASK) { +#ifdef CONFIG_DT_XLP_RVP + case PRID_IMP_NETLOGIC_XLP5XX: + fdtp = __dtb_xlp_rvp_begin; + break; +#endif #ifdef CONFIG_DT_XLP_GVP case PRID_IMP_NETLOGIC_XLP9XX: - case PRID_IMP_NETLOGIC_XLP5XX: fdtp = __dtb_xlp_gvp_begin; break; #endif diff --git a/arch/mips/netlogic/xlp/nlm_hal.c b/arch/mips/netlogic/xlp/nlm_hal.c index bc24beb3a426..a8f4144a0297 100644 --- a/arch/mips/netlogic/xlp/nlm_hal.c +++ b/arch/mips/netlogic/xlp/nlm_hal.c @@ -71,10 +71,20 @@ static int xlp9xx_irq_to_irt(int irq) switch (irq) { case PIC_GPIO_IRQ: return 12; + case PIC_I2C_0_IRQ: + return 125; + case PIC_I2C_1_IRQ: + return 126; + case PIC_I2C_2_IRQ: + return 127; + case PIC_I2C_3_IRQ: + return 128; case PIC_9XX_XHCI_0_IRQ: return 114; case PIC_9XX_XHCI_1_IRQ: return 115; + case PIC_9XX_XHCI_2_IRQ: + return 116; case PIC_UART_0_IRQ: return 133; case PIC_UART_1_IRQ: @@ -170,16 +180,23 @@ static int xlp_irq_to_irt(int irq) } if (devoff != 0) { + uint32_t val; + pcibase = nlm_pcicfg_base(devoff); - irt = nlm_read_reg(pcibase, XLP_PCI_IRTINFO_REG) & 0xffff; - /* HW weirdness, I2C IRT entry has to be fixed up */ - switch (irq) { - case PIC_I2C_1_IRQ: - irt = irt + 1; break; - case PIC_I2C_2_IRQ: - irt = irt + 2; break; - case PIC_I2C_3_IRQ: - irt = irt + 3; break; + val = nlm_read_reg(pcibase, XLP_PCI_IRTINFO_REG); + if (val == 0xffffffff) { + irt = -1; + } else { + irt = val & 0xffff; + /* HW weirdness, I2C IRT entry has to be fixed up */ + switch (irq) { + case PIC_I2C_1_IRQ: + irt = irt + 1; break; + case PIC_I2C_2_IRQ: + irt = irt + 2; break; + case PIC_I2C_3_IRQ: + irt = irt + 3; break; + } } } else if (irq >= PIC_PCIE_LINK_LEGACY_IRQ(0) && irq <= PIC_PCIE_LINK_LEGACY_IRQ(3)) { @@ -325,7 +342,7 @@ static unsigned int nlm_xlp2_get_pic_frequency(int node) /* Find the clock source PLL device for PIC */ if (cpu_xlp9xx) { reg_select = nlm_read_sys_reg(clockbase, - SYS_9XX_CLK_DEV_SEL) & 0x3; + SYS_9XX_CLK_DEV_SEL_REG) & 0x3; switch (reg_select) { case 0: ctrl_val0 = nlm_read_sys_reg(clockbase, @@ -354,7 +371,7 @@ static unsigned int nlm_xlp2_get_pic_frequency(int node) } } else { reg_select = (nlm_read_sys_reg(sysbase, - SYS_CLK_DEV_SEL) >> 22) & 0x3; + SYS_CLK_DEV_SEL_REG) >> 22) & 0x3; switch (reg_select) { case 0: ctrl_val0 = nlm_read_sys_reg(sysbase, @@ -410,7 +427,7 @@ static unsigned int nlm_xlp2_get_pic_frequency(int node) fdiv = fdiv/(1 << 13); pll_out_freq_num = ((ref_clk >> 1) * (6 + mdiv)) + fdiv; - pll_out_freq_den = (1 << vco_post_div) * pll_post_div * 3; + pll_out_freq_den = (1 << vco_post_div) * pll_post_div * ref_div; if (pll_out_freq_den > 0) do_div(pll_out_freq_num, pll_out_freq_den); @@ -418,10 +435,10 @@ static unsigned int nlm_xlp2_get_pic_frequency(int node) /* PIC post divider, which happens after PLL */ if (cpu_xlp9xx) pic_div = nlm_read_sys_reg(clockbase, - SYS_9XX_CLK_DEV_DIV) & 0x3; + SYS_9XX_CLK_DEV_DIV_REG) & 0x3; else pic_div = (nlm_read_sys_reg(sysbase, - SYS_CLK_DEV_DIV) >> 22) & 0x3; + SYS_CLK_DEV_DIV_REG) >> 22) & 0x3; do_div(pll_out_freq_num, 1 << pic_div); return pll_out_freq_num; @@ -442,19 +459,21 @@ unsigned int nlm_get_cpu_frequency(void) /* * Fills upto 8 pairs of entries containing the DRAM map of a node - * if n < 0, get dram map for all nodes + * if node < 0, get dram map for all nodes */ -int xlp_get_dram_map(int n, uint64_t *dram_map) +int nlm_get_dram_map(int node, uint64_t *dram_map, int nentries) { uint64_t bridgebase, base, lim; uint32_t val; unsigned int barreg, limreg, xlatreg; - int i, node, rv; + int i, n, rv; /* Look only at mapping on Node 0, we don't handle crazy configs */ bridgebase = nlm_get_bridge_regbase(0); rv = 0; for (i = 0; i < 8; i++) { + if (rv + 1 >= nentries) + break; if (cpu_is_xlp9xx()) { barreg = BRIDGE_9XX_DRAM_BAR(i); limreg = BRIDGE_9XX_DRAM_LIMIT(i); @@ -464,10 +483,10 @@ int xlp_get_dram_map(int n, uint64_t *dram_map) limreg = BRIDGE_DRAM_LIMIT(i); xlatreg = BRIDGE_DRAM_NODE_TRANSLN(i); } - if (n >= 0) { + if (node >= 0) { /* node specified, get node mapping of BAR */ val = nlm_read_bridge_reg(bridgebase, xlatreg); - node = (val >> 1) & 0x3; + n = (val >> 1) & 0x3; if (n != node) continue; } diff --git a/arch/mips/netlogic/xlp/setup.c b/arch/mips/netlogic/xlp/setup.c index 4fdd9fd29d1d..f743fd9da323 100644 --- a/arch/mips/netlogic/xlp/setup.c +++ b/arch/mips/netlogic/xlp/setup.c @@ -51,7 +51,6 @@ uint64_t nlm_io_base; struct nlm_soc_info nlm_nodes[NLM_NR_NODES]; cpumask_t nlm_cpumask = CPU_MASK_CPU0; unsigned int nlm_threads_per_core; -unsigned int xlp_cores_per_node; static void nlm_linux_exit(void) { @@ -82,7 +81,7 @@ static void __init xlp_init_mem_from_bars(void) uint64_t map[16]; int i, n; - n = xlp_get_dram_map(-1, map); /* -1: info for all nodes */ + n = nlm_get_dram_map(-1, map, ARRAY_SIZE(map)); /* -1 : all nodes */ for (i = 0; i < n; i += 2) { /* exclude 0x1000_0000-0x2000_0000, u-boot device */ if (map[i] <= 0x10000000 && map[i+1] > 0x10000000) @@ -163,10 +162,6 @@ void __init prom_init(void) void *reset_vec; nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE); - if (cpu_is_xlp9xx()) - xlp_cores_per_node = 32; - else - xlp_cores_per_node = 8; nlm_init_boot_cpu(); xlp_mmu_init(); nlm_node_init(0); diff --git a/arch/mips/netlogic/xlp/usb-init-xlp2.c b/arch/mips/netlogic/xlp/usb-init-xlp2.c index 17ade1ce5dfd..2524939a5e3a 100644 --- a/arch/mips/netlogic/xlp/usb-init-xlp2.c +++ b/arch/mips/netlogic/xlp/usb-init-xlp2.c @@ -128,6 +128,9 @@ static void xlp9xx_usb_ack(struct irq_data *data) case PIC_9XX_XHCI_1_IRQ: port_addr = nlm_xlpii_get_usb_regbase(node, 2); break; + case PIC_9XX_XHCI_2_IRQ: + port_addr = nlm_xlpii_get_usb_regbase(node, 3); + break; default: pr_err("No matching USB irq %d node %d!\n", irq, node); return; @@ -222,14 +225,16 @@ static int __init nlm_platform_xlpii_usb_init(void) } /* XLP 9XX, multi-node */ - pr_info("Initializing 9XX USB Interface\n"); + pr_info("Initializing 9XX/5XX USB Interface\n"); for (node = 0; node < NLM_NR_NODES; node++) { if (!nlm_node_present(node)) continue; nlm_xlpii_usb_hw_reset(node, 1); nlm_xlpii_usb_hw_reset(node, 2); + nlm_xlpii_usb_hw_reset(node, 3); nlm_set_pic_extra_ack(node, PIC_9XX_XHCI_0_IRQ, xlp9xx_usb_ack); nlm_set_pic_extra_ack(node, PIC_9XX_XHCI_1_IRQ, xlp9xx_usb_ack); + nlm_set_pic_extra_ack(node, PIC_9XX_XHCI_2_IRQ, xlp9xx_usb_ack); } return 0; } @@ -253,6 +258,9 @@ static void nlm_xlp9xx_usb_fixup_final(struct pci_dev *dev) case 0x22: dev->irq = nlm_irq_to_xirq(node, PIC_9XX_XHCI_1_IRQ); break; + case 0x23: + dev->irq = nlm_irq_to_xirq(node, PIC_9XX_XHCI_2_IRQ); + break; } } diff --git a/arch/mips/netlogic/xlp/wakeup.c b/arch/mips/netlogic/xlp/wakeup.c index e5f44d2605a8..87d7846af2d0 100644 --- a/arch/mips/netlogic/xlp/wakeup.c +++ b/arch/mips/netlogic/xlp/wakeup.c @@ -99,7 +99,7 @@ static int wait_for_cpus(int cpu, int bootcpu) do { notready = nlm_threads_per_core; for (i = 0; i < nlm_threads_per_core; i++) - if (cpu_ready[cpu + i] || cpu == bootcpu) + if (cpu_ready[cpu + i] || (cpu + i) == bootcpu) --notready; } while (notready != 0 && --count > 0); @@ -111,7 +111,7 @@ static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask) struct nlm_soc_info *nodep; uint64_t syspcibase, fusebase; uint32_t syscoremask, mask, fusemask; - int core, n, cpu; + int core, n, cpu, ncores; for (n = 0; n < NLM_NR_NODES; n++) { if (n != 0) { @@ -168,7 +168,8 @@ static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask) syscoremask = (1 << hweight32(~fusemask & mask)) - 1; pr_info("Node %d - SYS/FUSE coremask %x\n", n, syscoremask); - for (core = 0; core < nlm_cores_per_node(); core++) { + ncores = nlm_cores_per_node(); + for (core = 0; core < ncores; core++) { /* we will be on node 0 core 0 */ if (n == 0 && core == 0) continue; @@ -178,8 +179,7 @@ static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask) continue; /* see if at least the first hw thread is enabled */ - cpu = (n * nlm_cores_per_node() + core) - * NLM_THREADS_PER_CORE; + cpu = (n * ncores + core) * NLM_THREADS_PER_CORE; if (!cpumask_test_cpu(cpu, wakeup_mask)) continue; |