1 // SPDX-License-Identifier: GPL-2.0
3 * linux/arch/alpha/kernel/sys_marvel.c
8 #include <linux/kernel.h>
9 #include <linux/types.h>
11 #include <linux/sched.h>
12 #include <linux/pci.h>
13 #include <linux/init.h>
14 #include <linux/bitops.h>
16 #include <asm/ptrace.h>
19 #include <asm/mmu_context.h>
21 #include <asm/pgtable.h>
22 #include <asm/core_marvel.h>
23 #include <asm/hwrpb.h>
24 #include <asm/tlbflush.h>
31 #include "machvec_impl.h"
33 #if NR_IRQS < MARVEL_NR_IRQS
34 # error NR_IRQS < MARVEL_NR_IRQS !!!
42 io7_device_interrupt(unsigned long vector
)
48 * Vector is 0x800 + (interrupt)
50 * where (interrupt) is:
52 * ...16|15 14|13 4|3 0
53 * -----+-----+--------+---
58 * 0x0800 - 0x0ff0 - 0x0800 + (LSI id << 4)
59 * 0x1000 - 0x2ff0 - 0x1000 + (MSI_DAT<8:0> << 4)
62 irq
= ((vector
& 0xffff) - 0x800) >> 4;
64 irq
+= 16; /* offset for legacy */
65 irq
&= MARVEL_IRQ_VEC_IRQ_MASK
; /* not too many bits */
66 irq
|= pid
<< MARVEL_IRQ_VEC_PE_SHIFT
; /* merge the pid */
71 static volatile unsigned long *
72 io7_get_irq_ctl(unsigned int irq
, struct io7
**pio7
)
74 volatile unsigned long *ctl
;
78 pid
= irq
>> MARVEL_IRQ_VEC_PE_SHIFT
;
80 if (!(io7
= marvel_find_io7(pid
))) {
82 "%s for nonexistent io7 -- vec %x, pid %d\n",
87 irq
&= MARVEL_IRQ_VEC_IRQ_MASK
; /* isolate the vector */
88 irq
-= 16; /* subtract legacy bias */
92 "%s for invalid irq -- pid %d adjusted irq %x\n",
97 ctl
= &io7
->csrs
->PO7_LSI_CTL
[irq
& 0xff].csr
; /* assume LSI */
98 if (irq
>= 0x80) /* MSI */
99 ctl
= &io7
->csrs
->PO7_MSI_CTL
[((irq
- 0x80) >> 5) & 0x0f].csr
;
101 if (pio7
) *pio7
= io7
;
106 io7_enable_irq(struct irq_data
*d
)
108 volatile unsigned long *ctl
;
109 unsigned int irq
= d
->irq
;
112 ctl
= io7_get_irq_ctl(irq
, &io7
);
114 printk(KERN_ERR
"%s: get_ctl failed for irq %x\n",
119 raw_spin_lock(&io7
->irq_lock
);
123 raw_spin_unlock(&io7
->irq_lock
);
127 io7_disable_irq(struct irq_data
*d
)
129 volatile unsigned long *ctl
;
130 unsigned int irq
= d
->irq
;
133 ctl
= io7_get_irq_ctl(irq
, &io7
);
135 printk(KERN_ERR
"%s: get_ctl failed for irq %x\n",
140 raw_spin_lock(&io7
->irq_lock
);
141 *ctl
&= ~(1UL << 24);
144 raw_spin_unlock(&io7
->irq_lock
);
148 marvel_irq_noop(struct irq_data
*d
)
153 static struct irq_chip marvel_legacy_irq_type
= {
155 .irq_mask
= marvel_irq_noop
,
156 .irq_unmask
= marvel_irq_noop
,
159 static struct irq_chip io7_lsi_irq_type
= {
161 .irq_unmask
= io7_enable_irq
,
162 .irq_mask
= io7_disable_irq
,
163 .irq_mask_ack
= io7_disable_irq
,
166 static struct irq_chip io7_msi_irq_type
= {
168 .irq_unmask
= io7_enable_irq
,
169 .irq_mask
= io7_disable_irq
,
170 .irq_ack
= marvel_irq_noop
,
174 io7_redirect_irq(struct io7
*io7
,
175 volatile unsigned long *csr
,
181 val
&= ~(0x1ffUL
<< 24); /* clear the target pid */
182 val
|= ((unsigned long)where
<< 24); /* set the new target pid */
190 io7_redirect_one_lsi(struct io7
*io7
, unsigned int which
, unsigned int where
)
195 * LSI_CTL has target PID @ 14
197 val
= io7
->csrs
->PO7_LSI_CTL
[which
].csr
;
198 val
&= ~(0x1ffUL
<< 14); /* clear the target pid */
199 val
|= ((unsigned long)where
<< 14); /* set the new target pid */
201 io7
->csrs
->PO7_LSI_CTL
[which
].csr
= val
;
203 io7
->csrs
->PO7_LSI_CTL
[which
].csr
;
207 io7_redirect_one_msi(struct io7
*io7
, unsigned int which
, unsigned int where
)
212 * MSI_CTL has target PID @ 14
214 val
= io7
->csrs
->PO7_MSI_CTL
[which
].csr
;
215 val
&= ~(0x1ffUL
<< 14); /* clear the target pid */
216 val
|= ((unsigned long)where
<< 14); /* set the new target pid */
218 io7
->csrs
->PO7_MSI_CTL
[which
].csr
= val
;
220 io7
->csrs
->PO7_MSI_CTL
[which
].csr
;
224 init_one_io7_lsi(struct io7
*io7
, unsigned int which
, unsigned int where
)
227 * LSI_CTL has target PID @ 14
229 io7
->csrs
->PO7_LSI_CTL
[which
].csr
= ((unsigned long)where
<< 14);
231 io7
->csrs
->PO7_LSI_CTL
[which
].csr
;
235 init_one_io7_msi(struct io7
*io7
, unsigned int which
, unsigned int where
)
238 * MSI_CTL has target PID @ 14
240 io7
->csrs
->PO7_MSI_CTL
[which
].csr
= ((unsigned long)where
<< 14);
242 io7
->csrs
->PO7_MSI_CTL
[which
].csr
;
246 init_io7_irqs(struct io7
*io7
,
247 struct irq_chip
*lsi_ops
,
248 struct irq_chip
*msi_ops
)
250 long base
= (io7
->pe
<< MARVEL_IRQ_VEC_PE_SHIFT
) + 16;
253 printk("Initializing interrupts for IO7 at PE %u - base %lx\n",
257 * Where should interrupts from this IO7 go?
259 * They really should be sent to the local CPU to avoid having to
260 * traverse the mesh, but if it's not an SMP kernel, they have to
261 * go to the boot CPU. Send them all to the boot CPU for now,
262 * as each secondary starts, it can redirect it's local device
265 printk(" Interrupts reported to CPU at PE %u\n", boot_cpuid
);
267 raw_spin_lock(&io7
->irq_lock
);
269 /* set up the error irqs */
270 io7_redirect_irq(io7
, &io7
->csrs
->HLT_CTL
.csr
, boot_cpuid
);
271 io7_redirect_irq(io7
, &io7
->csrs
->HPI_CTL
.csr
, boot_cpuid
);
272 io7_redirect_irq(io7
, &io7
->csrs
->CRD_CTL
.csr
, boot_cpuid
);
273 io7_redirect_irq(io7
, &io7
->csrs
->STV_CTL
.csr
, boot_cpuid
);
274 io7_redirect_irq(io7
, &io7
->csrs
->HEI_CTL
.csr
, boot_cpuid
);
276 /* Set up the lsi irqs. */
277 for (i
= 0; i
< 128; ++i
) {
278 irq_set_chip_and_handler(base
+ i
, lsi_ops
, handle_level_irq
);
279 irq_set_status_flags(i
, IRQ_LEVEL
);
282 /* Disable the implemented irqs in hardware. */
283 for (i
= 0; i
< 0x60; ++i
)
284 init_one_io7_lsi(io7
, i
, boot_cpuid
);
286 init_one_io7_lsi(io7
, 0x74, boot_cpuid
);
287 init_one_io7_lsi(io7
, 0x75, boot_cpuid
);
290 /* Set up the msi irqs. */
291 for (i
= 128; i
< (128 + 512); ++i
) {
292 irq_set_chip_and_handler(base
+ i
, msi_ops
, handle_level_irq
);
293 irq_set_status_flags(i
, IRQ_LEVEL
);
296 for (i
= 0; i
< 16; ++i
)
297 init_one_io7_msi(io7
, i
, boot_cpuid
);
299 raw_spin_unlock(&io7
->irq_lock
);
303 marvel_init_irq(void)
306 struct io7
*io7
= NULL
;
308 /* Reserve the legacy irqs. */
309 for (i
= 0; i
< 16; ++i
) {
310 irq_set_chip_and_handler(i
, &marvel_legacy_irq_type
,
314 /* Init the io7 irqs. */
315 for (io7
= NULL
; (io7
= marvel_next_io7(io7
)) != NULL
; )
316 init_io7_irqs(io7
, &io7_lsi_irq_type
, &io7_msi_irq_type
);
320 marvel_map_irq(const struct pci_dev
*cdev
, u8 slot
, u8 pin
)
322 struct pci_dev
*dev
= (struct pci_dev
*)cdev
;
323 struct pci_controller
*hose
= dev
->sysdata
;
324 struct io7_port
*io7_port
= hose
->sysdata
;
325 struct io7
*io7
= io7_port
->io7
;
326 int msi_loc
, msi_data_off
;
332 pci_read_config_byte(dev
, PCI_INTERRUPT_LINE
, &intline
);
335 msi_loc
= dev
->msi_cap
;
338 pci_read_config_word(dev
, msi_loc
+ PCI_MSI_FLAGS
, &msg_ctl
);
340 if (msg_ctl
& PCI_MSI_FLAGS_ENABLE
) {
341 msi_data_off
= PCI_MSI_DATA_32
;
342 if (msg_ctl
& PCI_MSI_FLAGS_64BIT
)
343 msi_data_off
= PCI_MSI_DATA_64
;
344 pci_read_config_word(dev
, msi_loc
+ msi_data_off
, &msg_dat
);
346 irq
= msg_dat
& 0x1ff; /* we use msg_data<8:0> */
347 irq
+= 0x80; /* offset for lsi */
350 printk("PCI:%d:%d:%d (hose %d) is using MSI\n",
352 PCI_SLOT(dev
->devfn
),
353 PCI_FUNC(dev
->devfn
),
355 printk(" %d message(s) from 0x%04x\n",
356 1 << ((msg_ctl
& PCI_MSI_FLAGS_QSIZE
) >> 4),
358 printk(" reporting on %d IRQ(s) from %d (0x%x)\n",
359 1 << ((msg_ctl
& PCI_MSI_FLAGS_QSIZE
) >> 4),
360 (irq
+ 16) | (io7
->pe
<< MARVEL_IRQ_VEC_PE_SHIFT
),
361 (irq
+ 16) | (io7
->pe
<< MARVEL_IRQ_VEC_PE_SHIFT
));
365 pci_write_config_word(dev
, msi_loc
+ PCI_MSI_FLAGS
,
366 msg_ctl
& ~PCI_MSI_FLAGS_ENABLE
);
367 pci_read_config_byte(dev
, PCI_INTERRUPT_LINE
, &intline
);
370 printk(" forcing LSI interrupt on irq %d [0x%x]\n", irq
, irq
);
374 irq
+= 16; /* offset for legacy */
375 irq
|= io7
->pe
<< MARVEL_IRQ_VEC_PE_SHIFT
; /* merge the pid */
381 marvel_init_pci(void)
385 marvel_register_error_handlers();
387 /* Indicate that we trust the console to configure things properly */
388 pci_set_flags(PCI_PROBE_ONLY
);
390 locate_and_init_vga(NULL
);
392 /* Clear any io7 errors. */
393 for (io7
= NULL
; (io7
= marvel_next_io7(io7
)) != NULL
; )
394 io7_clear_errors(io7
);
398 marvel_init_rtc(void)
404 marvel_smp_callin(void)
406 int cpuid
= hard_smp_processor_id();
407 struct io7
*io7
= marvel_find_io7(cpuid
);
414 * There is a local IO7 - redirect all of its interrupts here.
416 printk("Redirecting IO7 interrupts to local CPU at PE %u\n", cpuid
);
418 /* Redirect the error IRQS here. */
419 io7_redirect_irq(io7
, &io7
->csrs
->HLT_CTL
.csr
, cpuid
);
420 io7_redirect_irq(io7
, &io7
->csrs
->HPI_CTL
.csr
, cpuid
);
421 io7_redirect_irq(io7
, &io7
->csrs
->CRD_CTL
.csr
, cpuid
);
422 io7_redirect_irq(io7
, &io7
->csrs
->STV_CTL
.csr
, cpuid
);
423 io7_redirect_irq(io7
, &io7
->csrs
->HEI_CTL
.csr
, cpuid
);
425 /* Redirect the implemented LSIs here. */
426 for (i
= 0; i
< 0x60; ++i
)
427 io7_redirect_one_lsi(io7
, i
, cpuid
);
429 io7_redirect_one_lsi(io7
, 0x74, cpuid
);
430 io7_redirect_one_lsi(io7
, 0x75, cpuid
);
432 /* Redirect the MSIs here. */
433 for (i
= 0; i
< 16; ++i
)
434 io7_redirect_one_msi(io7
, i
, cpuid
);
440 struct alpha_machine_vector marvel_ev7_mv __initmv
= {
441 .vector_name
= "MARVEL/EV7",
444 .rtc_boot_cpu_only
= 1,
446 .machine_check
= marvel_machine_check
,
447 .max_isa_dma_address
= ALPHA_MAX_ISA_DMA_ADDRESS
,
448 .min_io_address
= DEFAULT_IO_BASE
,
449 .min_mem_address
= DEFAULT_MEM_BASE
,
450 .pci_dac_offset
= IO7_DAC_OFFSET
,
452 .nr_irqs
= MARVEL_NR_IRQS
,
453 .device_interrupt
= io7_device_interrupt
,
455 .agp_info
= marvel_agp_info
,
457 .smp_callin
= marvel_smp_callin
,
458 .init_arch
= marvel_init_arch
,
459 .init_irq
= marvel_init_irq
,
460 .init_rtc
= marvel_init_rtc
,
461 .init_pci
= marvel_init_pci
,
462 .kill_arch
= marvel_kill_arch
,
463 .pci_map_irq
= marvel_map_irq
,
464 .pci_swizzle
= common_swizzle
,
466 .pa_to_nid
= marvel_pa_to_nid
,
467 .cpuid_to_nid
= marvel_cpuid_to_nid
,
468 .node_mem_start
= marvel_node_mem_start
,
469 .node_mem_size
= marvel_node_mem_size
,