1 /* 2 * Low-Level PCI Support for the SH7780 3 * 4 * Dustin McIntire (dustin@sensoria.com) 5 * Derived from arch/i386/kernel/pci-*.c which bore the message: 6 * (c) 1999--2000 Martin Mares <mj@ucw.cz> 7 * 8 * Ported to the new API by Paul Mundt <lethal@linux-sh.org> 9 * With cleanup by Paul van Gool <pvangool@mimotech.com> 10 * 11 * May be copied or modified under the terms of the GNU General Public 12 * License. See linux/COPYING for more information. 13 * 14 */ 15 #undef DEBUG 16 17 #include <linux/types.h> 18 #include <linux/kernel.h> 19 #include <linux/init.h> 20 #include <linux/pci.h> 21 #include <linux/errno.h> 22 #include <linux/delay.h> 23 #include "pci-sh4.h" 24 25 int __init sh7780_pci_init(struct pci_channel *chan) 26 { 27 unsigned int id; 28 const char *type = NULL; 29 int ret; 30 31 printk(KERN_NOTICE "PCI: Starting intialization.\n"); 32 33 chan->reg_base = 0xfe040000; 34 chan->io_base = 0xfe200000; 35 36 /* Enable CPU access to the PCIC registers. */ 37 __raw_writel(PCIECR_ENBL, PCIECR); 38 39 id = __raw_readw(chan->reg_base + SH7780_PCIVID); 40 if (id != SH7780_VENDOR_ID) { 41 printk(KERN_ERR "PCI: Unknown vendor ID 0x%04x.\n", id); 42 return -ENODEV; 43 } 44 45 id = __raw_readw(chan->reg_base + SH7780_PCIDID); 46 type = (id == SH7763_DEVICE_ID) ? "SH7763" : 47 (id == SH7780_DEVICE_ID) ? "SH7780" : 48 (id == SH7781_DEVICE_ID) ? "SH7781" : 49 (id == SH7785_DEVICE_ID) ? "SH7785" : 50 NULL; 51 if (unlikely(!type)) { 52 printk(KERN_ERR "PCI: Found an unsupported Renesas host " 53 "controller, device id 0x%04x.\n", id); 54 return -EINVAL; 55 } 56 57 printk(KERN_NOTICE "PCI: Found a Renesas %s host " 58 "controller, revision %d.\n", type, 59 __raw_readb(chan->reg_base + SH7780_PCIRID)); 60 61 if ((ret = sh4_pci_check_direct(chan)) != 0) 62 return ret; 63 64 /* 65 * Platform specific initialization (BSC registers, and memory space 66 * mapping) will be called via the platform defined function 67 * pcibios_init_platform(). 68 */ 69 return pcibios_init_platform(); 70 } 71 72 extern u8 pci_cache_line_size; 73 74 int __init sh7780_pcic_init(struct pci_channel *chan, 75 struct sh4_pci_address_map *map) 76 { 77 u32 word; 78 79 /* 80 * Set the class and sub-class codes. 81 */ 82 __raw_writeb(PCI_CLASS_BRIDGE_HOST >> 8, 83 chan->reg_base + SH7780_PCIBCC); 84 __raw_writeb(PCI_CLASS_BRIDGE_HOST & 0xff, 85 chan->reg_base + SH7780_PCISUB); 86 87 pci_cache_line_size = pci_read_reg(chan, SH7780_PCICLS) / 4; 88 89 /* set the command/status bits to: 90 * Wait Cycle Control + Parity Enable + Bus Master + 91 * Mem space enable 92 */ 93 pci_write_reg(chan, 0x00000046, SH7780_PCICMD); 94 95 /* Set IO and Mem windows to local address 96 * Make PCI and local address the same for easy 1 to 1 mapping 97 */ 98 pci_write_reg(chan, map->window0.size - 0xfffff, SH4_PCILSR0); 99 pci_write_reg(chan, map->window1.size - 0xfffff, SH4_PCILSR1); 100 /* Set the values on window 0 PCI config registers */ 101 pci_write_reg(chan, map->window0.base, SH4_PCILAR0); 102 pci_write_reg(chan, map->window0.base, SH7780_PCIMBAR0); 103 /* Set the values on window 1 PCI config registers */ 104 pci_write_reg(chan, map->window1.base, SH4_PCILAR1); 105 pci_write_reg(chan, map->window1.base, SH7780_PCIMBAR1); 106 107 /* Apply any last-minute PCIC fixups */ 108 pci_fixup_pcic(chan); 109 110 /* SH7780 init done, set central function init complete */ 111 /* use round robin mode to stop a device starving/overruning */ 112 word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO; 113 pci_write_reg(chan, word, SH4_PCICR); 114 115 return 0; 116 } 117