1 /* 2 * Low-Level PCI Support for the SH7780 3 * 4 * Copyright (C) 2005 - 2009 Paul Mundt 5 * 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 8 * for more details. 9 */ 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> 16 #include "pci-sh4.h" 17 18 extern u8 pci_cache_line_size; 19 20 static struct resource sh7785_io_resource = { 21 .name = "SH7785_IO", 22 .start = SH7780_PCI_IO_BASE, 23 .end = SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1, 24 .flags = IORESOURCE_IO 25 }; 26 27 static struct resource sh7785_mem_resource = { 28 .name = "SH7785_mem", 29 .start = SH7780_PCI_MEMORY_BASE, 30 .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1, 31 .flags = IORESOURCE_MEM 32 }; 33 34 static struct pci_channel sh7780_pci_controller = { 35 .pci_ops = &sh4_pci_ops, 36 .mem_resource = &sh7785_mem_resource, 37 .mem_offset = 0x00000000, 38 .io_resource = &sh7785_io_resource, 39 .io_offset = 0x00000000, 40 }; 41 42 static struct sh4_pci_address_map sh7780_pci_map = { 43 .window0 = { 44 #if defined(CONFIG_32BIT) 45 .base = SH7780_32BIT_DDR_BASE_ADDR, 46 .size = 0x40000000, 47 #else 48 .base = SH7780_CS0_BASE_ADDR, 49 .size = 0x20000000, 50 #endif 51 }, 52 }; 53 54 static int __init sh7780_pci_init(void) 55 { 56 struct pci_channel *chan = &sh7780_pci_controller; 57 unsigned int id; 58 const char *type = NULL; 59 int ret; 60 u32 word; 61 62 printk(KERN_NOTICE "PCI: Starting intialization.\n"); 63 64 chan->reg_base = 0xfe040000; 65 chan->io_base = 0xfe200000; 66 67 /* Enable CPU access to the PCIC registers. */ 68 __raw_writel(PCIECR_ENBL, PCIECR); 69 70 id = __raw_readw(chan->reg_base + SH7780_PCIVID); 71 if (id != SH7780_VENDOR_ID) { 72 printk(KERN_ERR "PCI: Unknown vendor ID 0x%04x.\n", id); 73 return -ENODEV; 74 } 75 76 id = __raw_readw(chan->reg_base + SH7780_PCIDID); 77 type = (id == SH7763_DEVICE_ID) ? "SH7763" : 78 (id == SH7780_DEVICE_ID) ? "SH7780" : 79 (id == SH7781_DEVICE_ID) ? "SH7781" : 80 (id == SH7785_DEVICE_ID) ? "SH7785" : 81 NULL; 82 if (unlikely(!type)) { 83 printk(KERN_ERR "PCI: Found an unsupported Renesas host " 84 "controller, device id 0x%04x.\n", id); 85 return -EINVAL; 86 } 87 88 printk(KERN_NOTICE "PCI: Found a Renesas %s host " 89 "controller, revision %d.\n", type, 90 __raw_readb(chan->reg_base + SH7780_PCIRID)); 91 92 if ((ret = sh4_pci_check_direct(chan)) != 0) 93 return ret; 94 95 /* 96 * Set the class and sub-class codes. 97 */ 98 __raw_writeb(PCI_CLASS_BRIDGE_HOST >> 8, 99 chan->reg_base + SH7780_PCIBCC); 100 __raw_writeb(PCI_CLASS_BRIDGE_HOST & 0xff, 101 chan->reg_base + SH7780_PCISUB); 102 103 pci_cache_line_size = pci_read_reg(chan, SH7780_PCICLS) / 4; 104 105 /* 106 * Set IO and Mem windows to local address 107 * Make PCI and local address the same for easy 1 to 1 mapping 108 */ 109 pci_write_reg(chan, sh7780_pci_map.window0.size - 0xfffff, SH4_PCILSR0); 110 /* Set the values on window 0 PCI config registers */ 111 pci_write_reg(chan, sh7780_pci_map.window0.base, SH4_PCILAR0); 112 pci_write_reg(chan, sh7780_pci_map.window0.base, SH7780_PCIMBAR0); 113 114 pci_write_reg(chan, 0x0000380f, SH4_PCIAINTM); 115 116 /* Set up standard PCI config registers */ 117 __raw_writew(0xFB00, chan->reg_base + SH7780_PCISTATUS); 118 __raw_writew(0x0047, chan->reg_base + SH7780_PCICMD); 119 __raw_writew(0x1912, chan->reg_base + SH7780_PCISVID); 120 __raw_writew(0x0001, chan->reg_base + SH7780_PCISID); 121 122 __raw_writeb(0x00, chan->reg_base + SH7780_PCIPIF); 123 124 /* Apply any last-minute PCIC fixups */ 125 pci_fixup_pcic(chan); 126 127 pci_write_reg(chan, 0xfd000000, SH7780_PCIMBR0); 128 pci_write_reg(chan, 0x00fc0000, SH7780_PCIMBMR0); 129 130 #ifdef CONFIG_32BIT 131 pci_write_reg(chan, 0xc0000000, SH7780_PCIMBR2); 132 pci_write_reg(chan, 0x20000000 - SH7780_PCI_IO_SIZE, SH7780_PCIMBMR2); 133 #endif 134 135 /* Set IOBR for windows containing area specified in pci.h */ 136 pci_write_reg(chan, chan->io_resource->start & ~(SH7780_PCI_IO_SIZE-1), 137 SH7780_PCIIOBR); 138 pci_write_reg(chan, ((SH7780_PCI_IO_SIZE-1) & (7<<18)), 139 SH7780_PCIIOBMR); 140 141 /* SH7780 init done, set central function init complete */ 142 /* use round robin mode to stop a device starving/overruning */ 143 word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO; 144 pci_write_reg(chan, word, SH4_PCICR); 145 146 __set_io_port_base(SH7780_PCI_IO_BASE); 147 148 register_pci_controller(chan); 149 150 return 0; 151 } 152 arch_initcall(sh7780_pci_init); 153