aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/netlogic/xlp
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/netlogic/xlp')
-rw-r--r--arch/mips/netlogic/xlp/nlm_hal.c67
-rw-r--r--arch/mips/netlogic/xlp/setup.c50
-rw-r--r--arch/mips/netlogic/xlp/wakeup.c83
3 files changed, 98 insertions, 102 deletions
diff --git a/arch/mips/netlogic/xlp/nlm_hal.c b/arch/mips/netlogic/xlp/nlm_hal.c
index 6c65ac701912..529e74742d9f 100644
--- a/arch/mips/netlogic/xlp/nlm_hal.c
+++ b/arch/mips/netlogic/xlp/nlm_hal.c
@@ -40,23 +40,23 @@
40#include <asm/mipsregs.h> 40#include <asm/mipsregs.h>
41#include <asm/time.h> 41#include <asm/time.h>
42 42
43#include <asm/netlogic/common.h>
43#include <asm/netlogic/haldefs.h> 44#include <asm/netlogic/haldefs.h>
44#include <asm/netlogic/xlp-hal/iomap.h> 45#include <asm/netlogic/xlp-hal/iomap.h>
45#include <asm/netlogic/xlp-hal/xlp.h> 46#include <asm/netlogic/xlp-hal/xlp.h>
46#include <asm/netlogic/xlp-hal/pic.h> 47#include <asm/netlogic/xlp-hal/pic.h>
47#include <asm/netlogic/xlp-hal/sys.h> 48#include <asm/netlogic/xlp-hal/sys.h>
48 49
49/* These addresses are computed by the nlm_hal_init() */
50uint64_t nlm_io_base;
51uint64_t nlm_sys_base;
52uint64_t nlm_pic_base;
53
54/* Main initialization */ 50/* Main initialization */
55void nlm_hal_init(void) 51void nlm_node_init(int node)
56{ 52{
57 nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE); 53 struct nlm_soc_info *nodep;
58 nlm_sys_base = nlm_get_sys_regbase(0); /* node 0 */ 54
59 nlm_pic_base = nlm_get_pic_regbase(0); /* node 0 */ 55 nodep = nlm_get_node(node);
56 nodep->sysbase = nlm_get_sys_regbase(node);
57 nodep->picbase = nlm_get_pic_regbase(node);
58 nodep->ebase = read_c0_ebase() & (~((1 << 12) - 1));
59 spin_lock_init(&nodep->piclock);
60} 60}
61 61
62int nlm_irq_to_irt(int irq) 62int nlm_irq_to_irt(int irq)
@@ -100,52 +100,15 @@ int nlm_irq_to_irt(int irq)
100 } 100 }
101} 101}
102 102
103int nlm_irt_to_irq(int irt) 103unsigned int nlm_get_core_frequency(int node, int core)
104{
105 switch (irt) {
106 case PIC_IRT_UART_0_INDEX:
107 return PIC_UART_0_IRQ;
108 case PIC_IRT_UART_1_INDEX:
109 return PIC_UART_1_IRQ;
110 case PIC_IRT_PCIE_LINK_0_INDEX:
111 return PIC_PCIE_LINK_0_IRQ;
112 case PIC_IRT_PCIE_LINK_1_INDEX:
113 return PIC_PCIE_LINK_1_IRQ;
114 case PIC_IRT_PCIE_LINK_2_INDEX:
115 return PIC_PCIE_LINK_2_IRQ;
116 case PIC_IRT_PCIE_LINK_3_INDEX:
117 return PIC_PCIE_LINK_3_IRQ;
118 case PIC_IRT_EHCI_0_INDEX:
119 return PIC_EHCI_0_IRQ;
120 case PIC_IRT_EHCI_1_INDEX:
121 return PIC_EHCI_1_IRQ;
122 case PIC_IRT_OHCI_0_INDEX:
123 return PIC_OHCI_0_IRQ;
124 case PIC_IRT_OHCI_1_INDEX:
125 return PIC_OHCI_1_IRQ;
126 case PIC_IRT_OHCI_2_INDEX:
127 return PIC_OHCI_2_IRQ;
128 case PIC_IRT_OHCI_3_INDEX:
129 return PIC_OHCI_3_IRQ;
130 case PIC_IRT_MMC_INDEX:
131 return PIC_MMC_IRQ;
132 case PIC_IRT_I2C_0_INDEX:
133 return PIC_I2C_0_IRQ;
134 case PIC_IRT_I2C_1_INDEX:
135 return PIC_I2C_1_IRQ;
136 default:
137 return -1;
138 }
139}
140
141unsigned int nlm_get_core_frequency(int core)
142{ 104{
143 unsigned int pll_divf, pll_divr, dfs_div, ext_div; 105 unsigned int pll_divf, pll_divr, dfs_div, ext_div;
144 unsigned int rstval, dfsval, denom; 106 unsigned int rstval, dfsval, denom;
145 uint64_t num; 107 uint64_t num, sysbase;
146 108
147 rstval = nlm_read_sys_reg(nlm_sys_base, SYS_POWER_ON_RESET_CFG); 109 sysbase = nlm_get_node(node)->sysbase;
148 dfsval = nlm_read_sys_reg(nlm_sys_base, SYS_CORE_DFS_DIV_VALUE); 110 rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG);
111 dfsval = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIV_VALUE);
149 pll_divf = ((rstval >> 10) & 0x7f) + 1; 112 pll_divf = ((rstval >> 10) & 0x7f) + 1;
150 pll_divr = ((rstval >> 8) & 0x3) + 1; 113 pll_divr = ((rstval >> 8) & 0x3) + 1;
151 ext_div = ((rstval >> 30) & 0x3) + 1; 114 ext_div = ((rstval >> 30) & 0x3) + 1;
@@ -159,5 +122,5 @@ unsigned int nlm_get_core_frequency(int core)
159 122
160unsigned int nlm_get_cpu_frequency(void) 123unsigned int nlm_get_cpu_frequency(void)
161{ 124{
162 return nlm_get_core_frequency(0); 125 return nlm_get_core_frequency(0, 0);
163} 126}
diff --git a/arch/mips/netlogic/xlp/setup.c b/arch/mips/netlogic/xlp/setup.c
index d8997098defd..4894d62043ac 100644
--- a/arch/mips/netlogic/xlp/setup.c
+++ b/arch/mips/netlogic/xlp/setup.c
@@ -52,26 +52,40 @@
52#include <asm/netlogic/xlp-hal/xlp.h> 52#include <asm/netlogic/xlp-hal/xlp.h>
53#include <asm/netlogic/xlp-hal/sys.h> 53#include <asm/netlogic/xlp-hal/sys.h>
54 54
55unsigned long nlm_common_ebase = 0x0; 55uint64_t nlm_io_base;
56 56struct nlm_soc_info nlm_nodes[NLM_NR_NODES];
57/* default to uniprocessor */ 57cpumask_t nlm_cpumask = CPU_MASK_CPU0;
58uint32_t nlm_coremask = 1, nlm_cpumask = 1; 58unsigned int nlm_threads_per_core;
59int nlm_threads_per_core = 1;
60extern u32 __dtb_start[]; 59extern u32 __dtb_start[];
61 60
62static void nlm_linux_exit(void) 61static void nlm_linux_exit(void)
63{ 62{
64 nlm_write_sys_reg(nlm_sys_base, SYS_CHIP_RESET, 1); 63 uint64_t sysbase = nlm_get_node(0)->sysbase;
64
65 nlm_write_sys_reg(sysbase, SYS_CHIP_RESET, 1);
65 for ( ; ; ) 66 for ( ; ; )
66 cpu_wait(); 67 cpu_wait();
67} 68}
68 69
69void __init plat_mem_setup(void) 70void __init plat_mem_setup(void)
70{ 71{
72 void *fdtp;
73
71 panic_timeout = 5; 74 panic_timeout = 5;
72 _machine_restart = (void (*)(char *))nlm_linux_exit; 75 _machine_restart = (void (*)(char *))nlm_linux_exit;
73 _machine_halt = nlm_linux_exit; 76 _machine_halt = nlm_linux_exit;
74 pm_power_off = nlm_linux_exit; 77 pm_power_off = nlm_linux_exit;
78
79 /*
80 * If no FDT pointer is passed in, use the built-in FDT.
81 * device_tree_init() does not handle CKSEG0 pointers in
82 * 64-bit, so convert pointer.
83 */
84 fdtp = (void *)(long)fw_arg0;
85 if (!fdtp)
86 fdtp = __dtb_start;
87 fdtp = phys_to_virt(__pa(fdtp));
88 early_init_devtree(fdtp);
75} 89}
76 90
77const char *get_system_type(void) 91const char *get_system_type(void)
@@ -94,27 +108,19 @@ void xlp_mmu_init(void)
94 (13 + (ffz(PM_DEFAULT_MASK >> 13) / 2))); 108 (13 + (ffz(PM_DEFAULT_MASK >> 13) / 2)));
95} 109}
96 110
97void __init prom_init(void) 111void nlm_percpu_init(int hwcpuid)
98{ 112{
99 void *fdtp; 113}
100 114
115void __init prom_init(void)
116{
117 nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE);
101 xlp_mmu_init(); 118 xlp_mmu_init();
102 nlm_hal_init(); 119 nlm_node_init(0);
103
104 /*
105 * If no FDT pointer is passed in, use the built-in FDT.
106 * device_tree_init() does not handle CKSEG0 pointers in
107 * 64-bit, so convert pointer.
108 */
109 fdtp = (void *)(long)fw_arg0;
110 if (!fdtp)
111 fdtp = __dtb_start;
112 fdtp = phys_to_virt(__pa(fdtp));
113 early_init_devtree(fdtp);
114 120
115 nlm_common_ebase = read_c0_ebase() & (~((1 << 12) - 1));
116#ifdef CONFIG_SMP 121#ifdef CONFIG_SMP
117 nlm_wakeup_secondary_cpus(0xffffffff); 122 cpumask_setall(&nlm_cpumask);
123 nlm_wakeup_secondary_cpus();
118 124
119 /* update TLB size after waking up threads */ 125 /* update TLB size after waking up threads */
120 current_cpu_data.tlbsize = ((read_c0_config6() >> 16) & 0xffff) + 1; 126 current_cpu_data.tlbsize = ((read_c0_config6() >> 16) & 0xffff) + 1;
diff --git a/arch/mips/netlogic/xlp/wakeup.c b/arch/mips/netlogic/xlp/wakeup.c
index 44d923ff3846..cb9010642ac3 100644
--- a/arch/mips/netlogic/xlp/wakeup.c
+++ b/arch/mips/netlogic/xlp/wakeup.c
@@ -51,45 +51,72 @@
51#include <asm/netlogic/xlp-hal/xlp.h> 51#include <asm/netlogic/xlp-hal/xlp.h>
52#include <asm/netlogic/xlp-hal/sys.h> 52#include <asm/netlogic/xlp-hal/sys.h>
53 53
54static void xlp_enable_secondary_cores(void) 54static int xlp_wakeup_core(uint64_t sysbase, int core)
55{ 55{
56 uint32_t core, value, coremask, syscoremask; 56 uint32_t coremask, value;
57 int count; 57 int count;
58 58
59 /* read cores in reset from SYS block */ 59 coremask = (1 << core);
60 syscoremask = nlm_read_sys_reg(nlm_sys_base, SYS_CPU_RESET);
61 60
62 /* update user specified */ 61 /* Enable CPU clock */
63 nlm_coremask = nlm_coremask & (syscoremask | 1); 62 value = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIS_CTRL);
63 value &= ~coremask;
64 nlm_write_sys_reg(sysbase, SYS_CORE_DFS_DIS_CTRL, value);
64 65
65 for (core = 1; core < 8; core++) { 66 /* Remove CPU Reset */
66 coremask = 1 << core; 67 value = nlm_read_sys_reg(sysbase, SYS_CPU_RESET);
67 if ((nlm_coremask & coremask) == 0) 68 value &= ~coremask;
68 continue; 69 nlm_write_sys_reg(sysbase, SYS_CPU_RESET, value);
69 70
70 /* Enable CPU clock */ 71 /* Poll for CPU to mark itself coherent */
71 value = nlm_read_sys_reg(nlm_sys_base, SYS_CORE_DFS_DIS_CTRL); 72 count = 100000;
72 value &= ~coremask; 73 do {
73 nlm_write_sys_reg(nlm_sys_base, SYS_CORE_DFS_DIS_CTRL, value); 74 value = nlm_read_sys_reg(sysbase, SYS_CPU_NONCOHERENT_MODE);
75 } while ((value & coremask) != 0 && --count > 0);
74 76
75 /* Remove CPU Reset */ 77 return count != 0;
76 value = nlm_read_sys_reg(nlm_sys_base, SYS_CPU_RESET); 78}
77 value &= ~coremask; 79
78 nlm_write_sys_reg(nlm_sys_base, SYS_CPU_RESET, value); 80static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask)
81{
82 struct nlm_soc_info *nodep;
83 uint64_t syspcibase;
84 uint32_t syscoremask;
85 int core, n, cpu;
86
87 for (n = 0; n < NLM_NR_NODES; n++) {
88 syspcibase = nlm_get_sys_pcibase(n);
89 if (nlm_read_reg(syspcibase, 0) == 0xffffffff)
90 break;
91
92 /* read cores in reset from SYS and account for boot cpu */
93 nlm_node_init(n);
94 nodep = nlm_get_node(n);
95 syscoremask = nlm_read_sys_reg(nodep->sysbase, SYS_CPU_RESET);
96 if (n == 0)
97 syscoremask |= 1;
98
99 for (core = 0; core < NLM_CORES_PER_NODE; core++) {
100 /* see if the core exists */
101 if ((syscoremask & (1 << core)) == 0)
102 continue;
79 103
80 /* Poll for CPU to mark itself coherent */ 104 /* see if at least the first thread is enabled */
81 count = 100000; 105 cpu = (n * NLM_CORES_PER_NODE + core)
82 do { 106 * NLM_THREADS_PER_CORE;
83 value = nlm_read_sys_reg(nlm_sys_base, 107 if (!cpumask_test_cpu(cpu, wakeup_mask))
84 SYS_CPU_NONCOHERENT_MODE); 108 continue;
85 } while ((value & coremask) != 0 && count-- > 0);
86 109
87 if (count == 0) 110 /* wake up the core */
88 pr_err("Failed to enable core %d\n", core); 111 if (xlp_wakeup_core(nodep->sysbase, core))
112 nodep->coremask |= 1u << core;
113 else
114 pr_err("Failed to enable core %d\n", core);
115 }
89 } 116 }
90} 117}
91 118
92void xlp_wakeup_secondary_cpus(void) 119void xlp_wakeup_secondary_cpus()
93{ 120{
94 /* 121 /*
95 * In case of u-boot, the secondaries are in reset 122 * In case of u-boot, the secondaries are in reset
@@ -98,5 +125,5 @@ void xlp_wakeup_secondary_cpus(void)
98 xlp_boot_core0_siblings(); 125 xlp_boot_core0_siblings();
99 126
100 /* now get other cores out of reset */ 127 /* now get other cores out of reset */
101 xlp_enable_secondary_cores(); 128 xlp_enable_secondary_cores(&nlm_cpumask);
102} 129}