summaryrefslogtreecommitdiff
path: root/src/mainboard/digitallogic/msm800sev/irq_tables.c
blob: 9236e529e51174fd42c58e03b38472b918d89d04 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#if 0
/* This file was generated by getpir.c, do not modify! 
   (but if you do, please run checkpir on it to verify)
 * Contains the IRQ Routing Table dumped directly from your memory, which BIOS sets up
 *
 * Documentation at : http://www.microsoft.com/hwdev/busbios/PCIIRQ.HTM
*/

#include <arch/pirq_routing.h>

#define ID_SLOT_PCI_NET		1			// ThinCan ethernet
#define ID_SLOT_PCI_RSVD1	2           // reserved entry 1
#define ID_SLOT_PCI_RSVD3	3           // reserved entry 2
#define ID_SLOT_PCI_RSVD2	4			// reserved entry 3
#define ID_EMBED_PCI		0xff		// onboard PCI device

// CS5535 PCI INT[A-D] Interrupt Routing lines.
#define NO_CONNECT			0			// not used
#define CS_PCI_INTA			1			// PCI INTA
#define CS_PCI_INTB			2			// PCI INTB
#define CS_PCI_INTC			3			// PCI INTC
#define CS_PCI_INTD			4			// PCI INTD

// IRQ bitmap reference line	FEDCBA9876543210
//								0000110000100000b
#define PCI_IRQ					0xc20	// PCI allowed IRQs here

const struct irq_routing_table intel_irq_routing_table = 
{
	PIRQ_SIGNATURE,  /* u32 signature */
	PIRQ_VERSION,    /* u16 version   */
	32+16*6,		/* there can be total 2 devices on the bus */
	0x00,		 /* Where the interrupt router lies (bus) */
	(0x12<<3)|0x0,   /* Where the interrupt router lies (dev) */
	0x0800,			/* IRQs devoted exclusively to PCI usage */
	0x1022,			/* Vendor */
	0x208f,			/* Device */
	0x00000000,		/* Crap (miniport) */
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
	0xdf,         /*  u8 checksum , this hase to set to some value that would give 0 after the sum of all bytes for this structure (including checksum) */
	{
		/* bus,     dev|fn,   {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap},  slot, rfu */
		// Geode GX3 Host Bridge and VGA Graphics
		{0, 0x01<<3, {{CS_PCI_INTA, PCI_IRQ}, {NO_CONNECT, PCI_IRQ}, {NO_CONNECT, PCI_IRQ}, {NO_CONNECT, PCI_IRQ}}, ID_EMBED_PCI, 0x0},
		// Realtek RTL8100/8139 Network Controller
		{0, 0x0d<<3, {{CS_PCI_INTB, PCI_IRQ}, {CS_PCI_INTC, PCI_IRQ}, {CS_PCI_INTD, PCI_IRQ}, {CS_PCI_INTA, PCI_IRQ}}, ID_SLOT_PCI_NET, 0x0},
		// Reserved for future extensions
		{0, 0x0c<<3, {{CS_PCI_INTA, PCI_IRQ}, {CS_PCI_INTB, PCI_IRQ}, {CS_PCI_INTC, PCI_IRQ}, {CS_PCI_INTD, PCI_IRQ}}, ID_SLOT_PCI_RSVD1, 0x0},
		// Geode CS5535/CS5536 IO Companion: USB controllers, IDE, Audio.
		{0, 0x0f<<3, {{CS_PCI_INTA, PCI_IRQ}, {CS_PCI_INTB, PCI_IRQ}, {CS_PCI_INTC, PCI_IRQ}, {CS_PCI_INTD, PCI_IRQ}}, ID_EMBED_PCI, 0x0},
		// Reserved for future extensions
		{0, 0x0e<<3, {{CS_PCI_INTC, PCI_IRQ}, {CS_PCI_INTD, PCI_IRQ}, {CS_PCI_INTA, PCI_IRQ}, {CS_PCI_INTB, PCI_IRQ}}, ID_SLOT_PCI_RSVD2, 0x0},
		// Reserved for future extensions
		{0, 0x0b<<3, {{CS_PCI_INTD, PCI_IRQ}, {CS_PCI_INTA, PCI_IRQ}, {CS_PCI_INTB, PCI_IRQ}, {CS_PCI_INTC, PCI_IRQ}}, ID_SLOT_PCI_RSVD3, 0x0}
	}
};

unsigned long write_pirq_routing_table(unsigned long addr)
{
        return copy_pirq_routing_table(addr);
}
#endif
/*
* This file is part of the LinuxBIOS project.
*
* Copyright (C) 2007 Advanced Micro Devices
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA      02110-1301 USA
*/

#include <arch/pirq_routing.h>
#include <console/console.h>
#include <arch/io.h>
#include <arch/pirq_routing.h>
#include "../../../southbridge/amd/cs5536/cs5536.h"

/* Platform IRQs */
#define PIRQA 11
#define PIRQB 5
#define PIRQC 10
#define PIRQD 10

/* Map */
#define M_PIRQA (1 << PIRQA)  /* Bitmap of supported IRQs */
#define M_PIRQB (1 << PIRQB)  /* Bitmap of supported IRQs */
#define M_PIRQC (1 << PIRQC)  /* Bitmap of supported IRQs */
#define M_PIRQD (1 << PIRQD)  /* Bitmap of supported IRQs */

/* Link */
#define L_PIRQA  1 /* Means Slot INTx# Connects To Chipset INTA# */
#define L_PIRQB  2 /* Means Slot INTx# Connects To Chipset INTB# */
#define L_PIRQC  3 /* Means Slot INTx# Connects To Chipset INTC# */
#define L_PIRQD  4 /* Means Slot INTx# Connects To Chipset INTD# */

const struct irq_routing_table intel_irq_routing_table = {
       PIRQ_SIGNATURE, /* u32 signature */
       PIRQ_VERSION,   /* u16 version   */
       32+16*IRQ_SLOT_COUNT,           /* there can be total 6 devices on the bus */
       0x00,                   /* Where the interrupt router lies (bus) */
       (0x0F<<3)|0x0,  /* Where the interrupt router lies (dev) */
       0x00,                   /* IRQs devoted exclusively to PCI usage */
       0x100B,                 /* Vendor */
       0x002B,                 /* Device */
       0,                              /* Crap (miniport) */
       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
       0x00,                   /*      u8 checksum , this has to set to some value that would give 0 after the sum of all bytes for this structure (including checksum) */
       {
               /* If you change the number of entries, change the IRQ_SLOT_COUNT above! */
               /* bus,         dev|fn,          {link, bitmap},         {link, bitmap},         {link, bitmap},         {link, bitmap},  slot, rfu */
               {0x00,(0x01<<3)|0x0, {{L_PIRQA, M_PIRQA},        {0x00, 0x00},           {0x00, 0x00},           {0x00, 0x00}},    0x0, 0x0},    /* cpu */
               {0x00,(0x0F<<3)|0x0, {{L_PIRQA, M_PIRQA}, {L_PIRQB, M_PIRQB}, {L_PIRQC, M_PIRQC}, {L_PIRQD, M_PIRQD}}, 0x0, 0x0},        /* chipset */
               {0x00,(0x0C<<3)|0x0, {{L_PIRQB, M_PIRQB}, {L_PIRQC, M_PIRQC}, {L_PIRQD, M_PIRQD}, {L_PIRQA, M_PIRQA}}, 0x1, 0x0},        /* slot1 */
               {0x00,(0x0D<<3)|0x0, {{L_PIRQC, M_PIRQC}, {L_PIRQD, M_PIRQD}, {L_PIRQA, M_PIRQA}, {L_PIRQB, M_PIRQB}}, 0x2, 0x0},        /* slot2 */
               {0x00,(0x0A<<3)|0x0, {{L_PIRQD, M_PIRQD}, {L_PIRQA, M_PIRQA}, {L_PIRQB, M_PIRQB}, {L_PIRQC, M_PIRQC}}, 0x3, 0x0},        /* slot3 */
               {0x00,(0x0B<<3)|0x0, {{L_PIRQA, M_PIRQA}, {L_PIRQB, M_PIRQB}, {L_PIRQC, M_PIRQC}, {L_PIRQD, M_PIRQD}}, 0x4, 0x0},        /* slot4 */
       }
};



unsigned long write_pirq_routing_table(unsigned long addr){
       int i, j, k, num_entries;
       unsigned int pirq[4];
       uint16_t chipset_irq_map;
       uint32_t pciAddr, pirtable_end;
       struct irq_routing_table *pirq_tbl;

       pirtable_end = copy_pirq_routing_table(addr);

       /* Set up chipset IRQ steering */
       pciAddr = 0x80000000 | (CHIPSET_DEV_NUM << 11) | 0x5C;
       chipset_irq_map = (PIRQD << 12 | PIRQC << 8 | PIRQB << 4 | PIRQA);
       printk_debug("%s(%08X, %04X)\n", __FUNCTION__, pciAddr, chipset_irq_map);
       outl(pciAddr & ~3, 0xCF8);
       outl(chipset_irq_map, 0xCFC);

       pirq_tbl = (struct irq_routing_table *)(addr);
       num_entries = (pirq_tbl->size - 32)/16;

       /* Set PCI IRQs */
       for (i=0; i < num_entries; i++){
               printk_debug("PIR Entry %d Dev/Fn: %X Slot: %d\n", i, pirq_tbl->slots[i].devfn, pirq_tbl->slots[i].slot);
               for (j = 0; j < 4; j++){
               printk_debug("INT: %c bitmap: %x ", 'A'+j, pirq_tbl->slots[i].irq[j].bitmap);
                       for (k = 0; (!((pirq_tbl->slots[i].irq[j].bitmap >> k) & 1)) && (pirq_tbl->slots[i].irq[j].bitmap != 0); k++); /* finds lsb in bitmap to IRQ# */
                       pirq[j] = k;
                       printk_debug("PIRQ: %d\n", k);
               }
               pci_assign_irqs(pirq_tbl->slots[i].bus, pirq_tbl->slots[i].devfn, pirq);        /* bus, device, slots IRQs for {A,B,C,D} */
       }

       /* put the PIR table in memory and checksum */
       return pirtable_end;
}