1 |
1275 |
phoenix |
/*
|
2 |
|
|
* linux/arch/sh/kernel/pci-bigsur.c
|
3 |
|
|
*
|
4 |
|
|
* By Dustin McIntire (dustin@sensoria.com) (c)2001
|
5 |
|
|
|
6 |
|
|
* May be copied or modified under the terms of the GNU General Public
|
7 |
|
|
* License. See linux/COPYING for more information.
|
8 |
|
|
*
|
9 |
|
|
* PCI initialization for the Hitachi Big Sur Evaluation Board
|
10 |
|
|
*/
|
11 |
|
|
|
12 |
|
|
#include <linux/config.h>
|
13 |
|
|
#include <linux/kernel.h>
|
14 |
|
|
#include <linux/types.h>
|
15 |
|
|
#include <linux/init.h>
|
16 |
|
|
#include <linux/delay.h>
|
17 |
|
|
#include <linux/pci.h>
|
18 |
|
|
|
19 |
|
|
#include <asm/io.h>
|
20 |
|
|
#include <asm/pci-sh7751.h>
|
21 |
|
|
#include <asm/bigsur.h>
|
22 |
|
|
|
23 |
|
|
#define PCI_REG(reg) (SH7751_PCIREG_BASE+reg)
|
24 |
|
|
|
25 |
|
|
/*
|
26 |
|
|
* Initialize the Big Sur PCI interface
|
27 |
|
|
* Setup hardware to be Central Funtion
|
28 |
|
|
* Copy the BSR regs to the PCI interface
|
29 |
|
|
* Setup PCI windows into local RAM
|
30 |
|
|
*/
|
31 |
|
|
int __init pcibios_init_platform(void) {
|
32 |
|
|
u32 reg;
|
33 |
|
|
u32 word;
|
34 |
|
|
|
35 |
|
|
PCIDBG(1,"PCI: bigsur_pci_init called\n");
|
36 |
|
|
/* Set the BCR's to enable PCI access */
|
37 |
|
|
reg = inl(SH7751_BCR1);
|
38 |
|
|
reg |= 0x80000;
|
39 |
|
|
outl(reg, SH7751_BCR1);
|
40 |
|
|
|
41 |
|
|
/* Setup the host hardware */
|
42 |
|
|
if(inl(PCI_REG(SH7751_PCICONF0)) !=
|
43 |
|
|
(u32)((SH7751_DEVICE_ID <<16) | (SH7751_VENDOR_ID))) {
|
44 |
|
|
printk("PCI: Unkown PCI host bridge.\n");
|
45 |
|
|
return 0;
|
46 |
|
|
}
|
47 |
|
|
printk("PCI: SH7751 PCI host bridge found.\n");
|
48 |
|
|
|
49 |
|
|
/* Turn the clocks back on (not done in reset)*/
|
50 |
|
|
outl(0, PCI_REG(SH7751_PCICLKR));
|
51 |
|
|
/* Clear Powerdown IRQ's (not done in reset) */
|
52 |
|
|
word = SH7751_PCIPINT_D3 | SH7751_PCIPINT_D0;
|
53 |
|
|
outl(word, PCI_REG(SH7751_PCICLKR));
|
54 |
|
|
|
55 |
|
|
/* toggle PCI reset pin */
|
56 |
|
|
word = SH7751_PCICR_PREFIX | SH7751_PCICR_PRST;
|
57 |
|
|
outl(word,PCI_REG(SH7751_PCICR));
|
58 |
|
|
/* Wait for a long time... not 1 sec. but long enough */
|
59 |
|
|
mdelay(100);
|
60 |
|
|
word = SH7751_PCICR_PREFIX;
|
61 |
|
|
outl(word,PCI_REG(SH7751_PCICR));
|
62 |
|
|
|
63 |
|
|
/* set the command/status bits to:
|
64 |
|
|
* Wait Cycle Control + Parity Enable + Bus Master +
|
65 |
|
|
* Mem space enable
|
66 |
|
|
*/
|
67 |
|
|
word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER |
|
68 |
|
|
SH7751_PCICONF1_BUM | SH7751_PCICONF1_MES;
|
69 |
|
|
outl(word, PCI_REG(SH7751_PCICONF1));
|
70 |
|
|
|
71 |
|
|
/* define this host as the host bridge */
|
72 |
|
|
word = SH7751_PCI_HOST_BRIDGE << 24;
|
73 |
|
|
outl(word, PCI_REG(SH7751_PCICONF2));
|
74 |
|
|
|
75 |
|
|
/* Set IO and Mem windows to local address
|
76 |
|
|
* Make PCI and local address the same for easy 1 to 1 mapping
|
77 |
|
|
* Window0 = BIGSUR_LSR0_SIZE @ non-cached CS3 base = SDRAM
|
78 |
|
|
* Window1 = BIGSUR_LSR1_SIZE @ cached CS3 base = SDRAM
|
79 |
|
|
*/
|
80 |
|
|
word = BIGSUR_LSR0_SIZE - 1;
|
81 |
|
|
outl(word, PCI_REG(SH7751_PCILSR0));
|
82 |
|
|
word = BIGSUR_LSR1_SIZE - 1;
|
83 |
|
|
outl(word, PCI_REG(SH7751_PCILSR1));
|
84 |
|
|
/* Set the values on window 0 PCI config registers */
|
85 |
|
|
word = P2SEGADDR(SH7751_CS3_BASE_ADDR);
|
86 |
|
|
outl(word, PCI_REG(SH7751_PCILAR0));
|
87 |
|
|
outl(word, PCI_REG(SH7751_PCICONF5));
|
88 |
|
|
/* Set the values on window 1 PCI config registers */
|
89 |
|
|
word = PHYSADDR(SH7751_CS3_BASE_ADDR);
|
90 |
|
|
outl(word, PCI_REG(SH7751_PCILAR1));
|
91 |
|
|
outl(word, PCI_REG(SH7751_PCICONF6));
|
92 |
|
|
|
93 |
|
|
/* Set the local 16MB PCI memory space window to
|
94 |
|
|
* the lowest PCI mapped address
|
95 |
|
|
*/
|
96 |
|
|
word = PCIBIOS_MIN_MEM & SH7751_PCIMBR_MASK;
|
97 |
|
|
PCIDBG(2,"PCI: Setting upper bits of Memory window to 0x%x\n", word);
|
98 |
|
|
outl(word , PCI_REG(SH7751_PCIMBR));
|
99 |
|
|
|
100 |
|
|
/* Map IO space into PCI IO window
|
101 |
|
|
* The IO window is 64K-PCIBIOS_MIN_IO in size
|
102 |
|
|
* IO addresses will be translated to the
|
103 |
|
|
* PCI IO window base address
|
104 |
|
|
*/
|
105 |
|
|
PCIDBG(3,"PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", PCIBIOS_MIN_IO,
|
106 |
|
|
(64*1024), SH7751_PCI_IO_BASE+PCIBIOS_MIN_IO);
|
107 |
|
|
bigsur_port_map(PCIBIOS_MIN_IO, (64*1024), SH7751_PCI_IO_BASE+PCIBIOS_MIN_IO,0);
|
108 |
|
|
|
109 |
|
|
/* Make sure the MSB's of IO window are set to access PCI space correctly */
|
110 |
|
|
word = PCIBIOS_MIN_IO & SH7751_PCIIOBR_MASK;
|
111 |
|
|
PCIDBG(2,"PCI: Setting upper bits of IO window to 0x%x\n", word);
|
112 |
|
|
outl(word, PCI_REG(SH7751_PCIIOBR));
|
113 |
|
|
|
114 |
|
|
/* Set PCI WCRx, BCRx's, copy from BSC locations */
|
115 |
|
|
word = inl(SH7751_BCR1);
|
116 |
|
|
/* check BCR for SDRAM in area 3 */
|
117 |
|
|
if(((word >> 3) & 1) == 0) {
|
118 |
|
|
printk("PCI: Area 3 is not configured for SDRAM. BCR1=0x%x\n", word);
|
119 |
|
|
return 0;
|
120 |
|
|
}
|
121 |
|
|
outl(word, PCI_REG(SH7751_PCIBCR1));
|
122 |
|
|
word = (u16)inw(SH7751_BCR2);
|
123 |
|
|
/* check BCR2 for 32bit SDRAM interface*/
|
124 |
|
|
if(((word >> 6) & 0x3) != 0x3) {
|
125 |
|
|
printk("PCI: Area 3 is not 32 bit SDRAM. BCR2=0x%x\n", word);
|
126 |
|
|
return 0;
|
127 |
|
|
}
|
128 |
|
|
outl(word, PCI_REG(SH7751_PCIBCR2));
|
129 |
|
|
/* configure the wait control registers */
|
130 |
|
|
word = inl(SH7751_WCR1);
|
131 |
|
|
outl(word, PCI_REG(SH7751_PCIWCR1));
|
132 |
|
|
word = inl(SH7751_WCR2);
|
133 |
|
|
outl(word, PCI_REG(SH7751_PCIWCR2));
|
134 |
|
|
word = inl(SH7751_WCR3);
|
135 |
|
|
outl(word, PCI_REG(SH7751_PCIWCR3));
|
136 |
|
|
word = inl(SH7751_MCR);
|
137 |
|
|
outl(word, PCI_REG(SH7751_PCIMCR));
|
138 |
|
|
|
139 |
|
|
/* NOTE: I'm ignoring the PCI error IRQs for now..
|
140 |
|
|
* TODO: add support for the internal error interrupts and
|
141 |
|
|
* DMA interrupts...
|
142 |
|
|
*/
|
143 |
|
|
|
144 |
|
|
/* SH7751 init done, set central function init complete */
|
145 |
|
|
word = SH7751_PCICR_PREFIX | SH7751_PCICR_CFIN;
|
146 |
|
|
outl(word,PCI_REG(SH7751_PCICR));
|
147 |
|
|
PCIDBG(2,"PCI: bigsur_pci_init finished\n");
|
148 |
|
|
|
149 |
|
|
return 1;
|
150 |
|
|
}
|
151 |
|
|
|
152 |
|
|
int pcibios_map_platform_irq(u8 slot, u8 pin)
|
153 |
|
|
{
|
154 |
|
|
/* The Big Sur can be used in a CPCI chassis, but the SH7751 PCI interface is on the
|
155 |
|
|
* wrong end of the board so that it can also support a V320 CPI interface chip...
|
156 |
|
|
* Therefor the IRQ mapping is somewhat use dependent... I'l assume a linear map for
|
157 |
|
|
* now, i.e. INTA=slot0,pin0... INTD=slot3,pin0...
|
158 |
|
|
*/
|
159 |
|
|
int irq = (slot + pin-1)%4 + BIGSUR_SH7751_PCI_IRQ_BASE;
|
160 |
|
|
PCIDBG(2,"PCI: Mapping Big Sur IRQ for slot %d, pin %c to irq %d\n", slot, pin-1+'A', irq);
|
161 |
|
|
return irq;
|
162 |
|
|
|
163 |
|
|
}
|