2 * Low-Level PCI Support for the SH7780
4 * Copyright (C) 2005 - 2009 Paul Mundt
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
10 #include <linux/types.h>
11 #include <linux/kernel.h>
12 #include <linux/init.h>
13 #include <linux/pci.h>
14 #include <linux/errno.h>
15 #include <linux/delay.h>
18 static struct resource sh7785_io_resource
= {
20 .start
= SH7780_PCI_IO_BASE
,
21 .end
= SH7780_PCI_IO_BASE
+ SH7780_PCI_IO_SIZE
- 1,
22 .flags
= IORESOURCE_IO
25 static struct resource sh7785_mem_resource
= {
27 .start
= SH7780_PCI_MEMORY_BASE
,
28 .end
= SH7780_PCI_MEMORY_BASE
+ SH7780_PCI_MEM_SIZE
- 1,
29 .flags
= IORESOURCE_MEM
32 static struct pci_channel sh7780_pci_controller
= {
33 .pci_ops
= &sh4_pci_ops
,
34 .mem_resource
= &sh7785_mem_resource
,
35 .mem_offset
= 0x00000000,
36 .io_resource
= &sh7785_io_resource
,
37 .io_offset
= 0x00000000,
38 .io_map_base
= SH7780_PCI_IO_BASE
,
41 static struct sh4_pci_address_map sh7780_pci_map
= {
43 #if defined(CONFIG_32BIT)
44 .base
= SH7780_32BIT_DDR_BASE_ADDR
,
47 .base
= SH7780_CS0_BASE_ADDR
,
53 static int __init
sh7780_pci_init(void)
55 struct pci_channel
*chan
= &sh7780_pci_controller
;
57 const char *type
= NULL
;
61 printk(KERN_NOTICE
"PCI: Starting intialization.\n");
63 chan
->reg_base
= 0xfe040000;
65 /* Enable CPU access to the PCIC registers. */
66 __raw_writel(PCIECR_ENBL
, PCIECR
);
68 id
= __raw_readw(chan
->reg_base
+ SH7780_PCIVID
);
69 if (id
!= SH7780_VENDOR_ID
) {
70 printk(KERN_ERR
"PCI: Unknown vendor ID 0x%04x.\n", id
);
74 id
= __raw_readw(chan
->reg_base
+ SH7780_PCIDID
);
75 type
= (id
== SH7763_DEVICE_ID
) ? "SH7763" :
76 (id
== SH7780_DEVICE_ID
) ? "SH7780" :
77 (id
== SH7781_DEVICE_ID
) ? "SH7781" :
78 (id
== SH7785_DEVICE_ID
) ? "SH7785" :
80 if (unlikely(!type
)) {
81 printk(KERN_ERR
"PCI: Found an unsupported Renesas host "
82 "controller, device id 0x%04x.\n", id
);
86 printk(KERN_NOTICE
"PCI: Found a Renesas %s host "
87 "controller, revision %d.\n", type
,
88 __raw_readb(chan
->reg_base
+ SH7780_PCIRID
));
90 if ((ret
= sh4_pci_check_direct(chan
)) != 0)
94 * Set the class and sub-class codes.
96 __raw_writeb(PCI_CLASS_BRIDGE_HOST
>> 8,
97 chan
->reg_base
+ SH7780_PCIBCC
);
98 __raw_writeb(PCI_CLASS_BRIDGE_HOST
& 0xff,
99 chan
->reg_base
+ SH7780_PCISUB
);
102 * Set IO and Mem windows to local address
103 * Make PCI and local address the same for easy 1 to 1 mapping
105 pci_write_reg(chan
, sh7780_pci_map
.window0
.size
- 0xfffff, SH4_PCILSR0
);
106 /* Set the values on window 0 PCI config registers */
107 pci_write_reg(chan
, sh7780_pci_map
.window0
.base
, SH4_PCILAR0
);
108 pci_write_reg(chan
, sh7780_pci_map
.window0
.base
, SH7780_PCIMBAR0
);
110 pci_write_reg(chan
, 0x0000380f, SH4_PCIAINTM
);
112 /* Set up standard PCI config registers */
113 __raw_writew(0xFB00, chan
->reg_base
+ SH7780_PCISTATUS
);
114 __raw_writew(0x0047, chan
->reg_base
+ SH7780_PCICMD
);
115 __raw_writew(0x1912, chan
->reg_base
+ SH7780_PCISVID
);
116 __raw_writew(0x0001, chan
->reg_base
+ SH7780_PCISID
);
118 __raw_writeb(0x00, chan
->reg_base
+ SH7780_PCIPIF
);
120 /* Apply any last-minute PCIC fixups */
121 pci_fixup_pcic(chan
);
123 pci_write_reg(chan
, 0xfd000000, SH7780_PCIMBR0
);
124 pci_write_reg(chan
, 0x00fc0000, SH7780_PCIMBMR0
);
127 pci_write_reg(chan
, 0xc0000000, SH7780_PCIMBR2
);
128 pci_write_reg(chan
, 0x20000000 - SH7780_PCI_IO_SIZE
, SH7780_PCIMBMR2
);
131 /* Set IOBR for windows containing area specified in pci.h */
132 pci_write_reg(chan
, chan
->io_resource
->start
& ~(SH7780_PCI_IO_SIZE
-1),
134 pci_write_reg(chan
, ((SH7780_PCI_IO_SIZE
-1) & (7<<18)),
137 /* SH7780 init done, set central function init complete */
138 /* use round robin mode to stop a device starving/overruning */
139 word
= SH4_PCICR_PREFIX
| SH4_PCICR_CFIN
| SH4_PCICR_FTO
;
140 pci_write_reg(chan
, word
, SH4_PCICR
);
142 register_pci_controller(chan
);
146 arch_initcall(sh7780_pci_init
);