diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2013-02-21 06:51:33 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2013-02-21 06:51:33 -0500 |
commit | 8bfc245f9ad7bd4e461179e4e7852ef99b8b6144 (patch) | |
tree | 0ad091f645fbc8318634599d278966a53d3922ee /arch/mips/netlogic | |
parent | 612663a974065c3445e641d046769fe4c55a6438 (diff) | |
parent | 535237cecab2b078114be712c67e89a0db61965f (diff) |
Merge branch 'mips-next-3.9' of git://git.linux-mips.org/pub/scm/john/linux-john into mips-for-linux-next
Diffstat (limited to 'arch/mips/netlogic')
-rw-r--r-- | arch/mips/netlogic/common/irq.c | 41 | ||||
-rw-r--r-- | arch/mips/netlogic/common/smp.c | 8 | ||||
-rw-r--r-- | arch/mips/netlogic/common/smpboot.S | 6 | ||||
-rw-r--r-- | arch/mips/netlogic/common/time.c | 56 | ||||
-rw-r--r-- | arch/mips/netlogic/xlp/wakeup.c | 35 | ||||
-rw-r--r-- | arch/mips/netlogic/xlr/fmn-config.c | 2 | ||||
-rw-r--r-- | arch/mips/netlogic/xlr/platform.c | 2 | ||||
-rw-r--r-- | arch/mips/netlogic/xlr/setup.c | 2 |
8 files changed, 111 insertions, 41 deletions
diff --git a/arch/mips/netlogic/common/irq.c b/arch/mips/netlogic/common/irq.c index 780832e391ff..9f84c60bf535 100644 --- a/arch/mips/netlogic/common/irq.c +++ b/arch/mips/netlogic/common/irq.c | |||
@@ -105,21 +105,23 @@ static void xlp_pic_disable(struct irq_data *d) | |||
105 | static void xlp_pic_mask_ack(struct irq_data *d) | 105 | static void xlp_pic_mask_ack(struct irq_data *d) |
106 | { | 106 | { |
107 | struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d); | 107 | struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d); |
108 | uint64_t mask = 1ull << pd->picirq; | ||
109 | 108 | ||
110 | write_c0_eirr(mask); /* ack by writing EIRR */ | 109 | clear_c0_eimr(pd->picirq); |
110 | ack_c0_eirr(pd->picirq); | ||
111 | } | 111 | } |
112 | 112 | ||
113 | static void xlp_pic_unmask(struct irq_data *d) | 113 | static void xlp_pic_unmask(struct irq_data *d) |
114 | { | 114 | { |
115 | struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d); | 115 | struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d); |
116 | 116 | ||
117 | if (!pd) | 117 | BUG_ON(!pd); |
118 | return; | ||
119 | 118 | ||
120 | if (pd->extra_ack) | 119 | if (pd->extra_ack) |
121 | pd->extra_ack(d); | 120 | pd->extra_ack(d); |
122 | 121 | ||
122 | /* re-enable the intr on this cpu */ | ||
123 | set_c0_eimr(pd->picirq); | ||
124 | |||
123 | /* Ack is a single write, no need to lock */ | 125 | /* Ack is a single write, no need to lock */ |
124 | nlm_pic_ack(pd->node->picbase, pd->irt); | 126 | nlm_pic_ack(pd->node->picbase, pd->irt); |
125 | } | 127 | } |
@@ -134,32 +136,17 @@ static struct irq_chip xlp_pic = { | |||
134 | 136 | ||
135 | static void cpuintr_disable(struct irq_data *d) | 137 | static void cpuintr_disable(struct irq_data *d) |
136 | { | 138 | { |
137 | uint64_t eimr; | 139 | clear_c0_eimr(d->irq); |
138 | uint64_t mask = 1ull << d->irq; | ||
139 | |||
140 | eimr = read_c0_eimr(); | ||
141 | write_c0_eimr(eimr & ~mask); | ||
142 | } | 140 | } |
143 | 141 | ||
144 | static void cpuintr_enable(struct irq_data *d) | 142 | static void cpuintr_enable(struct irq_data *d) |
145 | { | 143 | { |
146 | uint64_t eimr; | 144 | set_c0_eimr(d->irq); |
147 | uint64_t mask = 1ull << d->irq; | ||
148 | |||
149 | eimr = read_c0_eimr(); | ||
150 | write_c0_eimr(eimr | mask); | ||
151 | } | 145 | } |
152 | 146 | ||
153 | static void cpuintr_ack(struct irq_data *d) | 147 | static void cpuintr_ack(struct irq_data *d) |
154 | { | 148 | { |
155 | uint64_t mask = 1ull << d->irq; | 149 | ack_c0_eirr(d->irq); |
156 | |||
157 | write_c0_eirr(mask); | ||
158 | } | ||
159 | |||
160 | static void cpuintr_nop(struct irq_data *d) | ||
161 | { | ||
162 | WARN(d->irq >= PIC_IRQ_BASE, "Bad irq %d", d->irq); | ||
163 | } | 150 | } |
164 | 151 | ||
165 | /* | 152 | /* |
@@ -170,9 +157,9 @@ struct irq_chip nlm_cpu_intr = { | |||
170 | .name = "XLP-CPU-INTR", | 157 | .name = "XLP-CPU-INTR", |
171 | .irq_enable = cpuintr_enable, | 158 | .irq_enable = cpuintr_enable, |
172 | .irq_disable = cpuintr_disable, | 159 | .irq_disable = cpuintr_disable, |
173 | .irq_mask = cpuintr_nop, | 160 | .irq_mask = cpuintr_disable, |
174 | .irq_ack = cpuintr_nop, | 161 | .irq_ack = cpuintr_ack, |
175 | .irq_eoi = cpuintr_ack, | 162 | .irq_eoi = cpuintr_enable, |
176 | }; | 163 | }; |
177 | 164 | ||
178 | static void __init nlm_init_percpu_irqs(void) | 165 | static void __init nlm_init_percpu_irqs(void) |
@@ -230,7 +217,7 @@ static void nlm_init_node_irqs(int node) | |||
230 | nlm_setup_pic_irq(node, i, i, irt); | 217 | nlm_setup_pic_irq(node, i, i, irt); |
231 | /* set interrupts to first cpu in node */ | 218 | /* set interrupts to first cpu in node */ |
232 | nlm_pic_init_irt(nodep->picbase, irt, i, | 219 | nlm_pic_init_irt(nodep->picbase, irt, i, |
233 | node * NLM_CPUS_PER_NODE); | 220 | node * NLM_CPUS_PER_NODE, 0); |
234 | irqmask |= (1ull << i); | 221 | irqmask |= (1ull << i); |
235 | } | 222 | } |
236 | nodep->irqmask = irqmask; | 223 | nodep->irqmask = irqmask; |
@@ -265,7 +252,7 @@ asmlinkage void plat_irq_dispatch(void) | |||
265 | int i, node; | 252 | int i, node; |
266 | 253 | ||
267 | node = nlm_nodeid(); | 254 | node = nlm_nodeid(); |
268 | eirr = read_c0_eirr() & read_c0_eimr(); | 255 | eirr = read_c0_eirr_and_eimr(); |
269 | 256 | ||
270 | i = __ilog2_u64(eirr); | 257 | i = __ilog2_u64(eirr); |
271 | if (i == -1) | 258 | if (i == -1) |
diff --git a/arch/mips/netlogic/common/smp.c b/arch/mips/netlogic/common/smp.c index a080d9ee3cd7..2bb95dcfe20a 100644 --- a/arch/mips/netlogic/common/smp.c +++ b/arch/mips/netlogic/common/smp.c | |||
@@ -84,15 +84,19 @@ void nlm_send_ipi_mask(const struct cpumask *mask, unsigned int action) | |||
84 | /* IRQ_IPI_SMP_FUNCTION Handler */ | 84 | /* IRQ_IPI_SMP_FUNCTION Handler */ |
85 | void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc) | 85 | void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc) |
86 | { | 86 | { |
87 | write_c0_eirr(1ull << irq); | 87 | clear_c0_eimr(irq); |
88 | ack_c0_eirr(irq); | ||
88 | smp_call_function_interrupt(); | 89 | smp_call_function_interrupt(); |
90 | set_c0_eimr(irq); | ||
89 | } | 91 | } |
90 | 92 | ||
91 | /* IRQ_IPI_SMP_RESCHEDULE handler */ | 93 | /* IRQ_IPI_SMP_RESCHEDULE handler */ |
92 | void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc) | 94 | void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc) |
93 | { | 95 | { |
94 | write_c0_eirr(1ull << irq); | 96 | clear_c0_eimr(irq); |
97 | ack_c0_eirr(irq); | ||
95 | scheduler_ipi(); | 98 | scheduler_ipi(); |
99 | set_c0_eimr(irq); | ||
96 | } | 100 | } |
97 | 101 | ||
98 | /* | 102 | /* |
diff --git a/arch/mips/netlogic/common/smpboot.S b/arch/mips/netlogic/common/smpboot.S index 280ff5855ef7..026517488584 100644 --- a/arch/mips/netlogic/common/smpboot.S +++ b/arch/mips/netlogic/common/smpboot.S | |||
@@ -69,6 +69,12 @@ | |||
69 | #endif | 69 | #endif |
70 | mtcr t1, t0 | 70 | mtcr t1, t0 |
71 | 71 | ||
72 | li t0, ICU_DEFEATURE | ||
73 | mfcr t1, t0 | ||
74 | ori t1, 0x1000 /* Enable Icache partitioning */ | ||
75 | mtcr t1, t0 | ||
76 | |||
77 | |||
72 | #ifdef XLP_AX_WORKAROUND | 78 | #ifdef XLP_AX_WORKAROUND |
73 | li t0, SCHED_DEFEATURE | 79 | li t0, SCHED_DEFEATURE |
74 | lui t1, 0x0100 /* Disable BRU accepting ALU ops */ | 80 | lui t1, 0x0100 /* Disable BRU accepting ALU ops */ |
diff --git a/arch/mips/netlogic/common/time.c b/arch/mips/netlogic/common/time.c index bd3e498157ff..5c56555380bb 100644 --- a/arch/mips/netlogic/common/time.c +++ b/arch/mips/netlogic/common/time.c | |||
@@ -35,17 +35,73 @@ | |||
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | 36 | ||
37 | #include <asm/time.h> | 37 | #include <asm/time.h> |
38 | #include <asm/cpu-features.h> | ||
39 | |||
38 | #include <asm/netlogic/interrupt.h> | 40 | #include <asm/netlogic/interrupt.h> |
39 | #include <asm/netlogic/common.h> | 41 | #include <asm/netlogic/common.h> |
42 | #include <asm/netlogic/haldefs.h> | ||
43 | #include <asm/netlogic/common.h> | ||
44 | |||
45 | #if defined(CONFIG_CPU_XLP) | ||
46 | #include <asm/netlogic/xlp-hal/iomap.h> | ||
47 | #include <asm/netlogic/xlp-hal/xlp.h> | ||
48 | #include <asm/netlogic/xlp-hal/pic.h> | ||
49 | #elif defined(CONFIG_CPU_XLR) | ||
50 | #include <asm/netlogic/xlr/iomap.h> | ||
51 | #include <asm/netlogic/xlr/pic.h> | ||
52 | #include <asm/netlogic/xlr/xlr.h> | ||
53 | #else | ||
54 | #error "Unknown CPU" | ||
55 | #endif | ||
40 | 56 | ||
41 | unsigned int __cpuinit get_c0_compare_int(void) | 57 | unsigned int __cpuinit get_c0_compare_int(void) |
42 | { | 58 | { |
43 | return IRQ_TIMER; | 59 | return IRQ_TIMER; |
44 | } | 60 | } |
45 | 61 | ||
62 | static cycle_t nlm_get_pic_timer(struct clocksource *cs) | ||
63 | { | ||
64 | uint64_t picbase = nlm_get_node(0)->picbase; | ||
65 | |||
66 | return ~nlm_pic_read_timer(picbase, PIC_CLOCK_TIMER); | ||
67 | } | ||
68 | |||
69 | static cycle_t nlm_get_pic_timer32(struct clocksource *cs) | ||
70 | { | ||
71 | uint64_t picbase = nlm_get_node(0)->picbase; | ||
72 | |||
73 | return ~nlm_pic_read_timer32(picbase, PIC_CLOCK_TIMER); | ||
74 | } | ||
75 | |||
76 | static struct clocksource csrc_pic = { | ||
77 | .name = "PIC", | ||
78 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
79 | }; | ||
80 | |||
81 | static void nlm_init_pic_timer(void) | ||
82 | { | ||
83 | uint64_t picbase = nlm_get_node(0)->picbase; | ||
84 | |||
85 | nlm_pic_set_timer(picbase, PIC_CLOCK_TIMER, ~0ULL, 0, 0); | ||
86 | if (current_cpu_data.cputype == CPU_XLR) { | ||
87 | csrc_pic.mask = CLOCKSOURCE_MASK(32); | ||
88 | csrc_pic.read = nlm_get_pic_timer32; | ||
89 | } else { | ||
90 | csrc_pic.mask = CLOCKSOURCE_MASK(64); | ||
91 | csrc_pic.read = nlm_get_pic_timer; | ||
92 | } | ||
93 | csrc_pic.rating = 1000; | ||
94 | clocksource_register_hz(&csrc_pic, PIC_CLK_HZ); | ||
95 | } | ||
96 | |||
46 | void __init plat_time_init(void) | 97 | void __init plat_time_init(void) |
47 | { | 98 | { |
99 | nlm_init_pic_timer(); | ||
48 | mips_hpt_frequency = nlm_get_cpu_frequency(); | 100 | mips_hpt_frequency = nlm_get_cpu_frequency(); |
101 | if (current_cpu_type() == CPU_XLR) | ||
102 | preset_lpj = mips_hpt_frequency / (3 * HZ); | ||
103 | else | ||
104 | preset_lpj = mips_hpt_frequency / (2 * HZ); | ||
49 | pr_info("MIPS counter frequency [%ld]\n", | 105 | pr_info("MIPS counter frequency [%ld]\n", |
50 | (unsigned long)mips_hpt_frequency); | 106 | (unsigned long)mips_hpt_frequency); |
51 | } | 107 | } |
diff --git a/arch/mips/netlogic/xlp/wakeup.c b/arch/mips/netlogic/xlp/wakeup.c index cb9010642ac3..abb3e08cc052 100644 --- a/arch/mips/netlogic/xlp/wakeup.c +++ b/arch/mips/netlogic/xlp/wakeup.c | |||
@@ -51,7 +51,7 @@ | |||
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 | ||
54 | static int xlp_wakeup_core(uint64_t sysbase, int core) | 54 | static int xlp_wakeup_core(uint64_t sysbase, int node, int core) |
55 | { | 55 | { |
56 | uint32_t coremask, value; | 56 | uint32_t coremask, value; |
57 | int count; | 57 | int count; |
@@ -82,36 +82,51 @@ static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask) | |||
82 | struct nlm_soc_info *nodep; | 82 | struct nlm_soc_info *nodep; |
83 | uint64_t syspcibase; | 83 | uint64_t syspcibase; |
84 | uint32_t syscoremask; | 84 | uint32_t syscoremask; |
85 | int core, n, cpu; | 85 | int core, n, cpu, count, val; |
86 | 86 | ||
87 | for (n = 0; n < NLM_NR_NODES; n++) { | 87 | for (n = 0; n < NLM_NR_NODES; n++) { |
88 | syspcibase = nlm_get_sys_pcibase(n); | 88 | syspcibase = nlm_get_sys_pcibase(n); |
89 | if (nlm_read_reg(syspcibase, 0) == 0xffffffff) | 89 | if (nlm_read_reg(syspcibase, 0) == 0xffffffff) |
90 | break; | 90 | break; |
91 | 91 | ||
92 | /* read cores in reset from SYS and account for boot cpu */ | 92 | /* read cores in reset from SYS */ |
93 | nlm_node_init(n); | 93 | if (n != 0) |
94 | nlm_node_init(n); | ||
94 | nodep = nlm_get_node(n); | 95 | nodep = nlm_get_node(n); |
95 | syscoremask = nlm_read_sys_reg(nodep->sysbase, SYS_CPU_RESET); | 96 | syscoremask = nlm_read_sys_reg(nodep->sysbase, SYS_CPU_RESET); |
96 | if (n == 0) | 97 | /* The boot cpu */ |
98 | if (n == 0) { | ||
97 | syscoremask |= 1; | 99 | syscoremask |= 1; |
100 | nodep->coremask = 1; | ||
101 | } | ||
98 | 102 | ||
99 | for (core = 0; core < NLM_CORES_PER_NODE; core++) { | 103 | for (core = 0; core < NLM_CORES_PER_NODE; core++) { |
104 | /* we will be on node 0 core 0 */ | ||
105 | if (n == 0 && core == 0) | ||
106 | continue; | ||
107 | |||
100 | /* see if the core exists */ | 108 | /* see if the core exists */ |
101 | if ((syscoremask & (1 << core)) == 0) | 109 | if ((syscoremask & (1 << core)) == 0) |
102 | continue; | 110 | continue; |
103 | 111 | ||
104 | /* see if at least the first thread is enabled */ | 112 | /* see if at least the first hw thread is enabled */ |
105 | cpu = (n * NLM_CORES_PER_NODE + core) | 113 | cpu = (n * NLM_CORES_PER_NODE + core) |
106 | * NLM_THREADS_PER_CORE; | 114 | * NLM_THREADS_PER_CORE; |
107 | if (!cpumask_test_cpu(cpu, wakeup_mask)) | 115 | if (!cpumask_test_cpu(cpu, wakeup_mask)) |
108 | continue; | 116 | continue; |
109 | 117 | ||
110 | /* wake up the core */ | 118 | /* wake up the core */ |
111 | if (xlp_wakeup_core(nodep->sysbase, core)) | 119 | if (!xlp_wakeup_core(nodep->sysbase, n, core)) |
112 | nodep->coremask |= 1u << core; | 120 | continue; |
113 | else | 121 | |
114 | pr_err("Failed to enable core %d\n", core); | 122 | /* core is up */ |
123 | nodep->coremask |= 1u << core; | ||
124 | |||
125 | /* spin until the first hw thread sets its ready */ | ||
126 | count = 0x20000000; | ||
127 | do { | ||
128 | val = *(volatile int *)&nlm_cpu_ready[cpu]; | ||
129 | } while (val == 0 && --count > 0); | ||
115 | } | 130 | } |
116 | } | 131 | } |
117 | } | 132 | } |
diff --git a/arch/mips/netlogic/xlr/fmn-config.c b/arch/mips/netlogic/xlr/fmn-config.c index f5bddf95bf24..ed3bf0e3f309 100644 --- a/arch/mips/netlogic/xlr/fmn-config.c +++ b/arch/mips/netlogic/xlr/fmn-config.c | |||
@@ -216,6 +216,8 @@ void xlr_board_info_setup(void) | |||
216 | case PRID_IMP_NETLOGIC_XLS404B: | 216 | case PRID_IMP_NETLOGIC_XLS404B: |
217 | case PRID_IMP_NETLOGIC_XLS408B: | 217 | case PRID_IMP_NETLOGIC_XLS408B: |
218 | case PRID_IMP_NETLOGIC_XLS416B: | 218 | case PRID_IMP_NETLOGIC_XLS416B: |
219 | case PRID_IMP_NETLOGIC_XLS608B: | ||
220 | case PRID_IMP_NETLOGIC_XLS616B: | ||
219 | setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0, | 221 | setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0, |
220 | FMN_STNID_GMAC0_TX3, 8, 8, 32); | 222 | FMN_STNID_GMAC0_TX3, 8, 8, 32); |
221 | setup_fmn_cc(&gmac[1], FMN_STNID_GMAC1_FR_0, | 223 | setup_fmn_cc(&gmac[1], FMN_STNID_GMAC1_FR_0, |
diff --git a/arch/mips/netlogic/xlr/platform.c b/arch/mips/netlogic/xlr/platform.c index e287277d32b0..7b96a91f4773 100644 --- a/arch/mips/netlogic/xlr/platform.c +++ b/arch/mips/netlogic/xlr/platform.c | |||
@@ -64,7 +64,7 @@ void nlm_xlr_uart_out(struct uart_port *p, int offset, int value) | |||
64 | .iotype = UPIO_MEM32, \ | 64 | .iotype = UPIO_MEM32, \ |
65 | .flags = (UPF_SKIP_TEST | \ | 65 | .flags = (UPF_SKIP_TEST | \ |
66 | UPF_FIXED_TYPE | UPF_BOOT_AUTOCONF),\ | 66 | UPF_FIXED_TYPE | UPF_BOOT_AUTOCONF),\ |
67 | .uartclk = PIC_CLKS_PER_SEC, \ | 67 | .uartclk = PIC_CLK_HZ, \ |
68 | .type = PORT_16550A, \ | 68 | .type = PORT_16550A, \ |
69 | .serial_in = nlm_xlr_uart_in, \ | 69 | .serial_in = nlm_xlr_uart_in, \ |
70 | .serial_out = nlm_xlr_uart_out, \ | 70 | .serial_out = nlm_xlr_uart_out, \ |
diff --git a/arch/mips/netlogic/xlr/setup.c b/arch/mips/netlogic/xlr/setup.c index f088efb8fe4c..e3e094100e3e 100644 --- a/arch/mips/netlogic/xlr/setup.c +++ b/arch/mips/netlogic/xlr/setup.c | |||
@@ -70,7 +70,7 @@ static void __init nlm_early_serial_setup(void) | |||
70 | s.iotype = UPIO_MEM32; | 70 | s.iotype = UPIO_MEM32; |
71 | s.regshift = 2; | 71 | s.regshift = 2; |
72 | s.irq = PIC_UART_0_IRQ; | 72 | s.irq = PIC_UART_0_IRQ; |
73 | s.uartclk = PIC_CLKS_PER_SEC; | 73 | s.uartclk = PIC_CLK_HZ; |
74 | s.serial_in = nlm_xlr_uart_in; | 74 | s.serial_in = nlm_xlr_uart_in; |
75 | s.serial_out = nlm_xlr_uart_out; | 75 | s.serial_out = nlm_xlr_uart_out; |
76 | s.mapbase = uart_base; | 76 | s.mapbase = uart_base; |