1 #include <linux/kernel.h>
2 #include <linux/string.h>
16 #define PSYCHO_IMAP_A_SLOT0 0x0c00UL
17 #define PSYCHO_IMAP_B_SLOT0 0x0c20UL
18 static unsigned long psycho_pcislot_imap_offset(
unsigned long ino)
20 unsigned int bus = (ino & 0x10) >> 4;
21 unsigned int slot = (ino & 0x0c) >> 2;
24 return PSYCHO_IMAP_A_SLOT0 + (slot * 8);
26 return PSYCHO_IMAP_B_SLOT0 + (slot * 8);
29 #define PSYCHO_OBIO_IMAP_BASE 0x1000UL
31 #define PSYCHO_ONBOARD_IRQ_BASE 0x20
32 #define psycho_onboard_imap_offset(__ino) \
33 (PSYCHO_OBIO_IMAP_BASE + (((__ino) & 0x1f) << 3))
35 #define PSYCHO_ICLR_A_SLOT0 0x1400UL
36 #define PSYCHO_ICLR_SCSI 0x1800UL
38 #define psycho_iclr_offset(ino) \
39 ((ino & 0x20) ? (PSYCHO_ICLR_SCSI + (((ino) & 0x1f) << 3)) : \
40 (PSYCHO_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3)))
46 unsigned long controller_regs = (
unsigned long) _data;
47 unsigned long imap, iclr;
48 unsigned long imap_off, iclr_off;
52 if (ino < PSYCHO_ONBOARD_IRQ_BASE) {
54 imap_off = psycho_pcislot_imap_offset(ino);
57 imap_off = psycho_onboard_imap_offset(ino);
61 imap = controller_regs + imap_off;
63 iclr_off = psycho_iclr_offset(ino);
64 iclr = controller_regs + iclr_off;
66 if ((ino & 0x20) == 0)
67 inofixup = ino & 0x03;
77 dp->irq_trans->irq_build = psycho_irq_build;
83 #define sabre_read(__reg) \
85 __asm__ __volatile__("ldxa [%1] %2, %0" \
87 : "r" (__reg), "i" (ASI_PHYS_BYPASS_EC_E) \
92 struct sabre_irq_data {
93 unsigned long controller_regs;
94 unsigned int pci_first_busno;
96 #define SABRE_CONFIGSPACE 0x001000000UL
97 #define SABRE_WRSYNC 0x1c20UL
99 #define SABRE_CONFIG_BASE(CONFIG_SPACE) \
100 (CONFIG_SPACE | (1UL << 24))
101 #define SABRE_CONFIG_ENCODE(BUS, DEVFN, REG) \
102 (((unsigned long)(BUS) << 16) | \
103 ((unsigned long)(DEVFN) << 8) | \
104 ((unsigned long)(REG)))
113 static void sabre_wsync_handler(
unsigned int ino,
void *_arg1,
void *_arg2)
115 unsigned int phys_hi = (
unsigned int) (
unsigned long) _arg1;
116 struct sabre_irq_data *
irq_data = _arg2;
117 unsigned long controller_regs = irq_data->controller_regs;
118 unsigned long sync_reg = controller_regs +
SABRE_WRSYNC;
123 config_space = SABRE_CONFIG_BASE(config_space);
125 bus = (phys_hi >> 16) & 0xff;
126 devfn = (phys_hi >> 8) & 0xff;
128 config_space |= SABRE_CONFIG_ENCODE(bus, devfn, 0x00);
130 __asm__ __volatile__(
"membar #Sync\n\t"
131 "lduha [%1] %2, %0\n\t"
134 :
"r" ((
u16 *) config_space),
138 sabre_read(sync_reg);
141 #define SABRE_IMAP_A_SLOT0 0x0c00UL
142 #define SABRE_IMAP_B_SLOT0 0x0c20UL
143 #define SABRE_ICLR_A_SLOT0 0x1400UL
144 #define SABRE_ICLR_B_SLOT0 0x1480UL
145 #define SABRE_ICLR_SCSI 0x1800UL
146 #define SABRE_ICLR_ETH 0x1808UL
147 #define SABRE_ICLR_BPP 0x1810UL
148 #define SABRE_ICLR_AU_REC 0x1818UL
149 #define SABRE_ICLR_AU_PLAY 0x1820UL
150 #define SABRE_ICLR_PFAIL 0x1828UL
151 #define SABRE_ICLR_KMS 0x1830UL
152 #define SABRE_ICLR_FLPY 0x1838UL
153 #define SABRE_ICLR_SHW 0x1840UL
154 #define SABRE_ICLR_KBD 0x1848UL
155 #define SABRE_ICLR_MS 0x1850UL
156 #define SABRE_ICLR_SER 0x1858UL
157 #define SABRE_ICLR_UE 0x1870UL
158 #define SABRE_ICLR_CE 0x1878UL
159 #define SABRE_ICLR_PCIERR 0x1880UL
161 static unsigned long sabre_pcislot_imap_offset(
unsigned long ino)
163 unsigned int bus = (ino & 0x10) >> 4;
164 unsigned int slot = (ino & 0x0c) >> 2;
172 #define SABRE_OBIO_IMAP_BASE 0x1000UL
173 #define SABRE_ONBOARD_IRQ_BASE 0x20
174 #define sabre_onboard_imap_offset(__ino) \
175 (SABRE_OBIO_IMAP_BASE + (((__ino) & 0x1f) << 3))
177 #define sabre_iclr_offset(ino) \
178 ((ino & 0x20) ? (SABRE_ICLR_SCSI + (((ino) & 0x1f) << 3)) : \
179 (SABRE_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3)))
181 static int sabre_device_needs_wsync(
struct device_node *dp)
184 const char *parent_model, *parent_compat;
206 (!
strcmp(parent_model,
"SUNW,sabre") ||
207 !
strcmp(parent_model,
"SUNW,simba")))
213 (!
strcmp(parent_compat,
"pci108e,a000") ||
214 !
strcmp(parent_compat,
"pci108e,a001")))
220 static unsigned int sabre_irq_build(
struct device_node *dp,
224 struct sabre_irq_data *irq_data = _data;
225 unsigned long controller_regs = irq_data->controller_regs;
227 unsigned long imap, iclr;
228 unsigned long imap_off, iclr_off;
233 if (ino < SABRE_ONBOARD_IRQ_BASE) {
235 imap_off = sabre_pcislot_imap_offset(ino);
238 imap_off = sabre_onboard_imap_offset(ino);
242 imap = controller_regs + imap_off;
244 iclr_off = sabre_iclr_offset(ino);
245 iclr = controller_regs + iclr_off;
247 if ((ino & 0x20) == 0)
248 inofixup = ino & 0x03;
258 if (regs && sabre_device_needs_wsync(dp)) {
271 struct sabre_irq_data *irq_data;
275 dp->irq_trans->irq_build = sabre_irq_build;
280 irq_data->controller_regs = regs[0].
phys_addr;
283 irq_data->pci_first_busno = busrange[0];
285 dp->irq_trans->
data = irq_data;
291 #define SCHIZO_IMAP_BASE 0x1000UL
292 #define SCHIZO_ICLR_BASE 0x1400UL
294 static unsigned long schizo_imap_offset(
unsigned long ino)
296 return SCHIZO_IMAP_BASE + (ino * 8
UL);
299 static unsigned long schizo_iclr_offset(
unsigned long ino)
301 return SCHIZO_ICLR_BASE + (ino * 8
UL);
304 static unsigned long schizo_ino_to_iclr(
unsigned long pbm_regs,
308 return pbm_regs + schizo_iclr_offset(ino);
311 static unsigned long schizo_ino_to_imap(
unsigned long pbm_regs,
314 return pbm_regs + schizo_imap_offset(ino);
317 #define schizo_read(__reg) \
319 __asm__ __volatile__("ldxa [%1] %2, %0" \
321 : "r" (__reg), "i" (ASI_PHYS_BYPASS_EC_E) \
325 #define schizo_write(__reg, __val) \
326 __asm__ __volatile__("stxa %0, [%1] %2" \
328 : "r" (__val), "r" (__reg), \
329 "i" (ASI_PHYS_BYPASS_EC_E) \
332 static void tomatillo_wsync_handler(
unsigned int ino,
void *_arg1,
void *_arg2)
334 unsigned long sync_reg = (
unsigned long) _arg2;
339 schizo_write(sync_reg, mask);
344 val = schizo_read(sync_reg);
349 printk(
"tomatillo_wsync_handler: DMA won't sync [%llx:%llx]\n",
354 static unsigned char cacheline[64]
357 __asm__ __volatile__(
"rd %%fprs, %0\n\t"
359 "wr %1, 0x0, %%fprs\n\t"
360 "stda %%f0, [%5] %6\n\t"
361 "wr %0, 0x0, %%fprs\n\t"
363 :
"=&r" (mask),
"=&r" (val)
364 :
"0" (mask),
"1" (val),
365 "i" (
FPRS_FEF),
"r" (&cacheline[0]),
370 struct schizo_irq_data {
371 unsigned long pbm_regs;
372 unsigned long sync_reg;
377 static unsigned int schizo_irq_build(
struct device_node *dp,
381 struct schizo_irq_data *irq_data = _data;
382 unsigned long pbm_regs = irq_data->pbm_regs;
383 unsigned long imap, iclr;
391 imap = schizo_ino_to_imap(pbm_regs, ino);
392 iclr = schizo_ino_to_iclr(pbm_regs, ino);
405 is_tomatillo = (irq_data->sync_reg != 0
UL);
408 if (irq_data->portid & 1)
409 ign_fixup = (1 << 6);
416 tomatillo_wsync_handler,
417 ((irq_data->chip_version <= 4) ?
418 (
void *) 1 : (
void *) 0),
419 (
void *) irq_data->sync_reg);
429 struct schizo_irq_data *irq_data;
432 dp->irq_trans->irq_build = schizo_irq_build;
437 dp->irq_trans->
data = irq_data;
443 irq_data->sync_reg = 0
UL;
450 __schizo_irq_trans_init(dp, 0);
455 __schizo_irq_trans_init(dp, 1);
458 static unsigned int pci_sun4v_irq_build(
struct device_node *dp,
462 u32 devhandle = (
u32) (
unsigned long) _data;
472 dp->irq_trans->irq_build = pci_sun4v_irq_build;
475 dp->irq_trans->
data = (
void *) (
unsigned long)
479 struct fire_irq_data {
480 unsigned long pbm_regs;
484 #define FIRE_IMAP_BASE 0x001000
485 #define FIRE_ICLR_BASE 0x001400
487 static unsigned long fire_imap_offset(
unsigned long ino)
489 return FIRE_IMAP_BASE + (ino * 8
UL);
492 static unsigned long fire_iclr_offset(
unsigned long ino)
494 return FIRE_ICLR_BASE + (ino * 8
UL);
497 static unsigned long fire_ino_to_iclr(
unsigned long pbm_regs,
500 return pbm_regs + fire_iclr_offset(ino);
503 static unsigned long fire_ino_to_imap(
unsigned long pbm_regs,
506 return pbm_regs + fire_imap_offset(ino);
509 static unsigned int fire_irq_build(
struct device_node *dp,
513 struct fire_irq_data *irq_data = _data;
514 unsigned long pbm_regs = irq_data->pbm_regs;
515 unsigned long imap, iclr;
516 unsigned long int_ctrlr;
521 imap = fire_ino_to_imap(pbm_regs, ino);
522 iclr = fire_ino_to_iclr(pbm_regs, ino);
526 upa_writeq(int_ctrlr, imap);
536 ino |= (irq_data->portid << 6);
544 struct fire_irq_data *irq_data;
547 dp->irq_trans->irq_build = fire_irq_build;
552 dp->irq_trans->
data = irq_data;
564 #define SYSIO_IMAP_SLOT0 0x2c00UL
565 #define SYSIO_IMAP_SLOT1 0x2c08UL
566 #define SYSIO_IMAP_SLOT2 0x2c10UL
567 #define SYSIO_IMAP_SLOT3 0x2c18UL
568 #define SYSIO_IMAP_SCSI 0x3000UL
569 #define SYSIO_IMAP_ETH 0x3008UL
570 #define SYSIO_IMAP_BPP 0x3010UL
571 #define SYSIO_IMAP_AUDIO 0x3018UL
572 #define SYSIO_IMAP_PFAIL 0x3020UL
573 #define SYSIO_IMAP_KMS 0x3028UL
574 #define SYSIO_IMAP_FLPY 0x3030UL
575 #define SYSIO_IMAP_SHW 0x3038UL
576 #define SYSIO_IMAP_KBD 0x3040UL
577 #define SYSIO_IMAP_MS 0x3048UL
578 #define SYSIO_IMAP_SER 0x3050UL
579 #define SYSIO_IMAP_TIM0 0x3060UL
580 #define SYSIO_IMAP_TIM1 0x3068UL
581 #define SYSIO_IMAP_UE 0x3070UL
582 #define SYSIO_IMAP_CE 0x3078UL
583 #define SYSIO_IMAP_SBERR 0x3080UL
584 #define SYSIO_IMAP_PMGMT 0x3088UL
585 #define SYSIO_IMAP_GFX 0x3090UL
586 #define SYSIO_IMAP_EUPA 0x3098UL
588 #define bogon ((unsigned long) -1)
589 static unsigned long sysio_irq_offsets[] = {
631 #define NUM_SYSIO_OFFSETS ARRAY_SIZE(sysio_irq_offsets)
636 #define SYSIO_ICLR_UNUSED0 0x3400UL
637 #define SYSIO_ICLR_SLOT0 0x3408UL
638 #define SYSIO_ICLR_SLOT1 0x3448UL
639 #define SYSIO_ICLR_SLOT2 0x3488UL
640 #define SYSIO_ICLR_SLOT3 0x34c8UL
641 static unsigned long sysio_imap_to_iclr(
unsigned long imap)
647 static unsigned int sbus_of_build_irq(
struct device_node *dp,
651 unsigned long reg_base = (
unsigned long) _data;
653 unsigned long imap, iclr;
664 ino += (sbus_slot * 8);
666 imap = sysio_irq_offsets[
ino];
667 if (imap == ((
unsigned long)-1)) {
668 prom_printf(
"get_irq_translations: Bad SYSIO INO[%x]\n",
679 iclr = sysio_imap_to_iclr(imap);
681 sbus_level = ino & 0x7;
699 iclr += ((
unsigned long)sbus_level - 1
UL) * 8
UL;
701 return build_irq(sbus_level, iclr, imap);
709 dp->irq_trans->irq_build = sbus_of_build_irq;
712 dp->irq_trans->
data = (
void *) (
unsigned long) regs->
phys_addr;
717 static unsigned int central_build_irq(
struct device_node *dp,
724 unsigned long imap, iclr;
731 }
else if (!
strcmp(dp->
name,
"clock-board")) {
744 tmp = upa_readl(imap);
746 upa_writel(tmp, imap);
754 dp->irq_trans->irq_build = central_build_irq;
766 {
"SUNW,sabre", sabre_irq_trans_init },
767 {
"pci108e,a000", sabre_irq_trans_init },
768 {
"pci108e,a001", sabre_irq_trans_init },
769 {
"SUNW,psycho", psycho_irq_trans_init },
770 {
"pci108e,8000", psycho_irq_trans_init },
771 {
"SUNW,schizo", schizo_irq_trans_init },
772 {
"pci108e,8001", schizo_irq_trans_init },
773 {
"SUNW,schizo+", schizo_irq_trans_init },
774 {
"pci108e,8002", schizo_irq_trans_init },
775 {
"SUNW,tomatillo", tomatillo_irq_trans_init },
776 {
"pci108e,a801", tomatillo_irq_trans_init },
777 {
"SUNW,sun4v-pci", pci_sun4v_irq_trans_init },
778 {
"pciex108e,80f0", fire_irq_trans_init },
782 static unsigned int sun4v_vdev_irq_build(
struct device_node *dp,
786 u32 devhandle = (
u32) (
unsigned long) _data;
796 dp->irq_trans->irq_build = sun4v_vdev_irq_build;
799 dp->irq_trans->
data = (
void *) (
unsigned long)
815 for (i = 0; i <
ARRAY_SIZE(pci_irq_trans_table); i++) {
828 sbus_irq_trans_init(dp);
834 central_irq_trans_init(dp);
839 sun4v_vdev_irq_trans_init(dp);