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

1     /*
2      * linux/arch/sh/kernel/pci-7751se.c
3      *
4      * Author:  Ian DaSilva (idasilva@mvista.com)
5      *
6      * Highly leveraged from pci-bigsur.c, written by Dustin McIntire.
7      *
8      * May be copied or modified under the terms of the GNU General Public
9      * License.  See linux/COPYING for more information.
10      *
11      * PCI initialization for the Hitachi SH7751 Solution Engine board (MS7751SE01)
12      */
13     
14     #include <linux/config.h>
15     #include <linux/kernel.h>
16     #include <linux/types.h>
17     #include <linux/init.h>
18     #include <linux/delay.h>
19     #include <linux/pci.h>
20     
21     #include <asm/io.h>
22     #include <asm/pci-sh7751.h>
23     
24     #define PCIMCR_MRSET_OFF	0xBFFFFFFF
25     #define PCIMCR_RFSH_OFF		0xFFFFFFFB
26     
27     /*
28      * Only long word accesses of the PCIC's internal local registers and the
29      * configuration registers from the CPU is supported.
30      */
31     #define PCIC_WRITE(x,v) writel((v), PCI_REG(x))
32     #define PCIC_READ(x) readl(PCI_REG(x))
33     
34     /*
35      * Description:  This function sets up and initializes the pcic, sets
36      * up the BARS, maps the DRAM into the address space etc, etc.
37      */
38     int __init pcibios_init_platform(void)
39     {
40        unsigned long data;
41        unsigned long bcr1, wcr1, wcr2, wcr3, mcr;
42        unsigned short bcr2;
43     
44        /*
45         * Initialize the slave bus controller on the pcic.  The values used
46         * here should not be hardcoded, but they should be taken from the bsc
47         * on the processor, to make this function as generic as possible.
48         * (i.e. Another sbc may usr different SDRAM timing settings -- in order
49         * for the pcic to work, its settings need to be exactly the same.)
50         */
51        bcr1 = (*(volatile unsigned long*)(SH7751_BCR1));
52        bcr2 = (*(volatile unsigned short*)(SH7751_BCR2));
53        wcr1 = (*(volatile unsigned long*)(SH7751_WCR1));
54        wcr2 = (*(volatile unsigned long*)(SH7751_WCR2));
55        wcr3 = (*(volatile unsigned long*)(SH7751_WCR3));
56        mcr = (*(volatile unsigned long*)(SH7751_MCR));
57     
58        bcr1 = bcr1 | 0x00080000;  /* Enable Bit 19, BREQEN */
59        (*(volatile unsigned long*)(SH7751_BCR1)) = bcr1;   
60     
61        bcr1 = bcr1 | 0x40080000;  /* Enable Bit 19 BREQEN, set PCIC to slave */
62        PCIC_WRITE(SH7751_PCIBCR1, bcr1);	 /* PCIC BCR1 */
63        PCIC_WRITE(SH7751_PCIBCR2, bcr2);     /* PCIC BCR2 */
64        PCIC_WRITE(SH7751_PCIWCR1, wcr1);     /* PCIC WCR1 */
65        PCIC_WRITE(SH7751_PCIWCR2, wcr2);     /* PCIC WCR2 */
66        PCIC_WRITE(SH7751_PCIWCR3, wcr3);     /* PCIC WCR3 */
67        mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF;
68        PCIC_WRITE(SH7751_PCIMCR, mcr);      /* PCIC MCR */
69     
70     
71        /* Enable all interrupts, so we know what to fix */
72        PCIC_WRITE(SH7751_PCIINTM, 0x0000c3ff);
73        PCIC_WRITE(SH7751_PCIAINTM, 0x0000380f);
74     
75        /* Set up standard PCI config registers */
76        PCIC_WRITE(SH7751_PCICONF1, 	0xF39000C7); /* Bus Master, Mem & I/O access */
77        PCIC_WRITE(SH7751_PCICONF2, 	0x00000000); /* PCI Class code & Revision ID */
78        PCIC_WRITE(SH7751_PCICONF4, 	0xab000001); /* PCI I/O address (local regs) */
79        PCIC_WRITE(SH7751_PCICONF5, 	0x0c000000); /* PCI MEM address (local RAM)  */
80        PCIC_WRITE(SH7751_PCICONF6, 	0xd0000000); /* PCI MEM address (unused)     */
81        PCIC_WRITE(SH7751_PCICONF11, 0x35051054); /* PCI Subsystem ID & Vendor ID */
82        PCIC_WRITE(SH7751_PCILSR0, 0x03f00000);   /* MEM (full 64M exposed)       */
83        PCIC_WRITE(SH7751_PCILSR1, 0x00000000);   /* MEM (unused)                 */
84        PCIC_WRITE(SH7751_PCILAR0, 0x0c000000);   /* MEM (direct map from PCI)    */
85        PCIC_WRITE(SH7751_PCILAR1, 0x00000000);   /* MEM (unused)                 */
86     
87        /* Now turn it on... */
88        PCIC_WRITE(SH7751_PCICR, 0xa5000001);
89     
90        /*
91         * Set PCIMBR and PCIIOBR here, assuming a single window
92         * (16M MEM, 256K IO) is enough.  If a larger space is
93         * needed, the readx/writex and inx/outx functions will
94         * have to do more (e.g. setting registers for each call).
95         */
96     
97        /*
98         * Set the MBR so PCI address is one-to-one with window,
99         * meaning all calls go straight through... use ifdef to
100         * catch erroneous assumption.
101         */
102     #if PCIBIOS_MIN_MEM != SH7751_PCI_MEMORY_BASE
103     #error One-to-one assumption for PCI memory mapping is wrong!?!?!?
104     #endif   
105        PCIC_WRITE(SH7751_PCIMBR, PCIBIOS_MIN_MEM);
106     
107        /* Set IOBR for window containing area specified in pci.h */
108        PCIC_WRITE(SH7751_PCIIOBR, (PCIBIOS_MIN_IO & SH7751_PCIIOBR_MASK));
109     
110        /* All done, may as well say so... */
111        printk("SH7751 PCI: Finished initialization of the PCI controller\n");
112     
113        return 1;
114     }
115     
116     int __init pcibios_map_platform_irq(u8 slot, u8 pin)
117     {
118             switch (slot) {
119             case 0: return 13;
120             case 1: return 13; 	/* AMD Ethernet controller */
121             case 2: return -1;
122             case 3: return -1;
123             case 4: return -1;
124             default:
125                     printk("PCI: Bad IRQ mapping request for slot %d\n", slot);
126                     return -1;
127             }
128     }
129