File: /usr/src/linux/arch/sh/kernel/pci-bigsur.c

1     /*
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     }
164