int pci_fixup_pcic(struct pci_channel *chan) { unsigned long bcr1, mcr; bcr1 = __raw_readl(SH7751_BCR1); bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ pci_write_reg(chan, bcr1, SH4_PCIBCR1); /* Enable all interrupts, so we known what to fix */ pci_write_reg(chan, 0x0000c3ff, SH4_PCIINTM); pci_write_reg(chan, 0x0000380f, SH4_PCIAINTM); pci_write_reg(chan, 0xfb900047, SH7751_PCICONF1); pci_write_reg(chan, 0xab000001, SH7751_PCICONF4); mcr = __raw_readl(SH7751_MCR); mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; pci_write_reg(chan, mcr, SH4_PCIMCR); pci_write_reg(chan, 0x0c000000, SH7751_PCICONF5); pci_write_reg(chan, 0xd0000000, SH7751_PCICONF6); pci_write_reg(chan, 0x0c000000, SH4_PCILAR0); pci_write_reg(chan, 0x00000000, SH4_PCILAR1); return 0; }
static void rcar_rmw32(struct rcar_pcie *pcie, int where, u32 mask, u32 data) { int shift = 8 * (where & 3); u32 val = pci_read_reg(pcie, where & ~3); val &= ~(mask << shift); val |= data << shift; pci_write_reg(pcie, val, where & ~3); }
int pci_fixup_pcic(struct pci_channel *chan) { unsigned long bcr1, mcr; bcr1 = __raw_readl(SH7751_BCR1); bcr1 |= 0x40080000; pci_write_reg(chan, bcr1, SH4_PCIBCR1); mcr = __raw_readl(SH7751_MCR); mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; pci_write_reg(chan, mcr, SH4_PCIMCR); pci_write_reg(chan, 0x0c000000, SH7751_PCICONF5); pci_write_reg(chan, 0xd0000000, SH7751_PCICONF6); pci_write_reg(chan, 0x0c000000, SH4_PCILAR0); pci_write_reg(chan, 0x00000000, SH4_PCILAR1); return 0; }
/* Serialization is provided by 'pci_lock' in drivers/pci/access.c */ static int rcar_pcie_config_access(struct rcar_pcie *pcie, unsigned char access_type, struct pci_bus *bus, unsigned int devfn, int where, u32 *data) { int dev, func, reg, index; dev = PCI_SLOT(devfn); func = PCI_FUNC(devfn); reg = where & ~3; index = reg / 4; /* * While each channel has its own memory-mapped extended config * space, it's generally only accessible when in endpoint mode. * When in root complex mode, the controller is unable to target * itself with either type 0 or type 1 accesses, and indeed, any * controller initiated target transfer to its own config space * result in a completer abort. * * Each channel effectively only supports a single device, but as * the same channel <-> device access works for any PCI_SLOT() * value, we cheat a bit here and bind the controller's config * space to devfn 0 in order to enable self-enumeration. In this * case the regular ECAR/ECDR path is sidelined and the mangled * config access itself is initiated as an internal bus transaction. */ if (pci_is_root_bus(bus)) { if (dev != 0) return PCIBIOS_DEVICE_NOT_FOUND; if (access_type == PCI_ACCESS_READ) { *data = pci_read_reg(pcie, PCICONF(index)); } else { /* Keep an eye out for changes to the root bus number */ if (pci_is_root_bus(bus) && (reg == PCI_PRIMARY_BUS)) pcie->root_bus_nr = *data & 0xff; pci_write_reg(pcie, *data, PCICONF(index)); } return PCIBIOS_SUCCESSFUL; } if (pcie->root_bus_nr < 0) return PCIBIOS_DEVICE_NOT_FOUND; /* Clear errors */ pci_write_reg(pcie, pci_read_reg(pcie, PCIEERRFR), PCIEERRFR); /* Set the PIO address */ pci_write_reg(pcie, PCIE_CONF_BUS(bus->number) | PCIE_CONF_DEV(dev) | PCIE_CONF_FUNC(func) | reg, PCIECAR); /* Enable the configuration access */ if (bus->parent->number == pcie->root_bus_nr) pci_write_reg(pcie, CONFIG_SEND_ENABLE | TYPE0, PCIECCTLR); else pci_write_reg(pcie, CONFIG_SEND_ENABLE | TYPE1, PCIECCTLR); /* Check for errors */ if (pci_read_reg(pcie, PCIEERRFR) & UNSUPPORTED_REQUEST) return PCIBIOS_DEVICE_NOT_FOUND; /* Check for master and target aborts */ if (rcar_read_conf(pcie, RCONF(PCI_STATUS)) & (PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT)) return PCIBIOS_DEVICE_NOT_FOUND; if (access_type == PCI_ACCESS_READ) *data = pci_read_reg(pcie, PCIECDR); else pci_write_reg(pcie, *data, PCIECDR); /* Disable the configuration access */ pci_write_reg(pcie, 0, PCIECCTLR); return PCIBIOS_SUCCESSFUL; }
static int sh7786_pcie_config_access(unsigned char access_type, struct pci_bus *bus, unsigned int devfn, int where, u32 *data) { struct pci_channel *chan = bus->sysdata; int dev, func, type, reg; dev = PCI_SLOT(devfn); func = PCI_FUNC(devfn); type = !!bus->parent; reg = where & ~3; if (bus->number > 255 || dev > 31 || func > 7) return PCIBIOS_FUNC_NOT_SUPPORTED; /* * While each channel has its own memory-mapped extended config * space, it's generally only accessible when in endpoint mode. * When in root complex mode, the controller is unable to target * itself with either type 0 or type 1 accesses, and indeed, any * controller initiated target transfer to its own config space * result in a completer abort. * * Each channel effectively only supports a single device, but as * the same channel <-> device access works for any PCI_SLOT() * value, we cheat a bit here and bind the controller's config * space to devfn 0 in order to enable self-enumeration. In this * case the regular PAR/PDR path is sidelined and the mangled * config access itself is initiated as a SuperHyway transaction. */ if (pci_is_root_bus(bus)) { if (dev == 0) { if (access_type == PCI_ACCESS_READ) *data = pci_read_reg(chan, PCI_REG(reg)); else pci_write_reg(chan, *data, PCI_REG(reg)); return PCIBIOS_SUCCESSFUL; } else if (dev > 1) return PCIBIOS_DEVICE_NOT_FOUND; } /* Clear errors */ pci_write_reg(chan, pci_read_reg(chan, SH4A_PCIEERRFR), SH4A_PCIEERRFR); /* Set the PIO address */ pci_write_reg(chan, (bus->number << 24) | (dev << 19) | (func << 16) | reg, SH4A_PCIEPAR); /* Enable the configuration access */ pci_write_reg(chan, (1 << 31) | (type << 8), SH4A_PCIEPCTLR); /* Check for errors */ if (pci_read_reg(chan, SH4A_PCIEERRFR) & 0x10) return PCIBIOS_DEVICE_NOT_FOUND; /* Check for master and target aborts */ if (pci_read_reg(chan, SH4A_PCIEPCICONF1) & ((1 << 29) | (1 << 28))) return PCIBIOS_DEVICE_NOT_FOUND; if (access_type == PCI_ACCESS_READ) *data = pci_read_reg(chan, SH4A_PCIEPDR); else pci_write_reg(chan, *data, SH4A_PCIEPDR); /* Disable the configuration access */ pci_write_reg(chan, 0, SH4A_PCIEPCTLR); return PCIBIOS_SUCCESSFUL; }
int pci_fixup_pcic(void) { ctrl_outl(0x00000001, SH7780_PCI_VCR2); /* Enable all interrupts, so we know what to fix */ pci_write_reg(0x0000C3FF, SH7780_PCIIMR); pci_write_reg(0x0000380F, SH7780_PCIAINTM); /* Set up standard PCI config registers */ ctrl_outw(0xFB00, PCI_REG(SH7780_PCISTATUS)); ctrl_outw(0x0047, PCI_REG(SH7780_PCICMD)); ctrl_outb( 0x00, PCI_REG(SH7780_PCIPIF)); ctrl_outb( 0x00, PCI_REG(SH7780_PCISUB)); ctrl_outb( 0x06, PCI_REG(SH7780_PCIBCC)); ctrl_outw(0x1912, PCI_REG(SH7780_PCISVID)); ctrl_outw(0x0001, PCI_REG(SH7780_PCISID)); pci_write_reg(0x08000000, SH7780_PCIMBAR0); /* PCI */ pci_write_reg(0x08000000, SH7780_PCILAR0); /* SHwy */ pci_write_reg(0x07F00001, SH7780_PCILSR); /* size 128M w/ MBAR */ pci_write_reg(0x00000000, SH7780_PCIMBAR1); pci_write_reg(0x00000000, SH7780_PCILAR1); pci_write_reg(0x00000000, SH7780_PCILSR1); pci_write_reg(0xAB000801, SH7780_PCIIBAR); /* * Set the MBR so PCI address is one-to-one with window, * meaning all calls go straight through... use ifdef to * catch erroneous assumption. */ pci_write_reg(0xFD000000 , SH7780_PCIMBR0); pci_write_reg(0x00FC0000 , SH7780_PCIMBMR0); /* 16M */ /* Set IOBR for window containing area specified in pci.h */ pci_write_reg(PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE-1), SH7780_PCIIOBR); pci_write_reg((SH7780_PCI_IO_SIZE-1) & (7 << 18), SH7780_PCIIOBMR); pci_write_reg(0xA5000C01, SH7780_PCICR); return 0; }
int pci_fixup_pcic(void) { pci_write_reg(0x000043ff, SH4_PCIINTM); pci_write_reg(0x0000380f, SH4_PCIAINTM); pci_write_reg(0xfbb00047, SH7780_PCICMD); pci_write_reg(0x00000000, SH7780_PCIIBAR); pci_write_reg(0x00011912, SH7780_PCISVID); pci_write_reg(0x08000000, SH7780_PCICSCR0); pci_write_reg(0x0000001b, SH7780_PCICSAR0); pci_write_reg(0xfd000000, SH7780_PCICSCR1); pci_write_reg(0x0000000f, SH7780_PCICSAR1); pci_write_reg(0xfd000000, SH7780_PCIMBR0); pci_write_reg(0x00fc0000, SH7780_PCIMBMR0); #ifdef CONFIG_32BIT pci_write_reg(0xc0000000, SH7780_PCIMBR2); pci_write_reg(0x20000000 - SH7780_PCI_IO_SIZE, SH7780_PCIMBMR2); #endif /* Set IOBR for windows containing area specified in pci.h */ pci_write_reg((PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE - 1)), SH7780_PCIIOBR); pci_write_reg(((SH7780_PCI_IO_SIZE-1) & (7<<18)), SH7780_PCIIOBMR); return 0; }
static int __init sh7780_pci_init(void) { struct pci_channel *chan = &sh7780_pci_controller; unsigned int id; const char *type = NULL; int ret; u32 word; printk(KERN_NOTICE "PCI: Starting intialization.\n"); chan->reg_base = 0xfe040000; /* Enable CPU access to the PCIC registers. */ __raw_writel(PCIECR_ENBL, PCIECR); id = __raw_readw(chan->reg_base + SH7780_PCIVID); if (id != SH7780_VENDOR_ID) { printk(KERN_ERR "PCI: Unknown vendor ID 0x%04x.\n", id); return -ENODEV; } id = __raw_readw(chan->reg_base + SH7780_PCIDID); type = (id == SH7763_DEVICE_ID) ? "SH7763" : (id == SH7780_DEVICE_ID) ? "SH7780" : (id == SH7781_DEVICE_ID) ? "SH7781" : (id == SH7785_DEVICE_ID) ? "SH7785" : NULL; if (unlikely(!type)) { printk(KERN_ERR "PCI: Found an unsupported Renesas host " "controller, device id 0x%04x.\n", id); return -EINVAL; } printk(KERN_NOTICE "PCI: Found a Renesas %s host " "controller, revision %d.\n", type, __raw_readb(chan->reg_base + SH7780_PCIRID)); if ((ret = sh4_pci_check_direct(chan)) != 0) return ret; /* * Set the class and sub-class codes. */ __raw_writeb(PCI_CLASS_BRIDGE_HOST >> 8, chan->reg_base + SH7780_PCIBCC); __raw_writeb(PCI_CLASS_BRIDGE_HOST & 0xff, chan->reg_base + SH7780_PCISUB); /* * Set IO and Mem windows to local address * Make PCI and local address the same for easy 1 to 1 mapping */ pci_write_reg(chan, sh7780_pci_map.window0.size - 0xfffff, SH4_PCILSR0); /* Set the values on window 0 PCI config registers */ pci_write_reg(chan, sh7780_pci_map.window0.base, SH4_PCILAR0); pci_write_reg(chan, sh7780_pci_map.window0.base, SH7780_PCIMBAR0); pci_write_reg(chan, 0x0000380f, SH4_PCIAINTM); /* Set up standard PCI config registers */ __raw_writew(0xFB00, chan->reg_base + SH7780_PCISTATUS); __raw_writew(0x0047, chan->reg_base + SH7780_PCICMD); __raw_writew(0x1912, chan->reg_base + SH7780_PCISVID); __raw_writew(0x0001, chan->reg_base + SH7780_PCISID); __raw_writeb(0x00, chan->reg_base + SH7780_PCIPIF); /* Apply any last-minute PCIC fixups */ pci_fixup_pcic(chan); pci_write_reg(chan, 0xfd000000, SH7780_PCIMBR0); pci_write_reg(chan, 0x00fc0000, SH7780_PCIMBMR0); #ifdef CONFIG_32BIT pci_write_reg(chan, 0xc0000000, SH7780_PCIMBR2); pci_write_reg(chan, 0x20000000 - SH7780_PCI_IO_SIZE, SH7780_PCIMBMR2); #endif /* Set IOBR for windows containing area specified in pci.h */ pci_write_reg(chan, chan->io_resource->start & ~(SH7780_PCI_IO_SIZE-1), SH7780_PCIIOBR); pci_write_reg(chan, ((SH7780_PCI_IO_SIZE-1) & (7<<18)), SH7780_PCIIOBMR); /* SH7780 init done, set central function init complete */ /* use round robin mode to stop a device starving/overruning */ word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO; pci_write_reg(chan, word, SH4_PCICR); register_pci_controller(chan); return 0; }
int __init sh7780_pcic_init(struct sh4_pci_address_map *map) { u32 word; /* * This code is unused for some boards as it is done in the * bootloader and doing it here means the MAC addresses loaded * by the bootloader get lost. */ if (!(map->flags & SH4_PCIC_NO_RESET)) { /* toggle PCI reset pin */ word = SH4_PCICR_PREFIX | SH4_PCICR_PRST; pci_write_reg(word, SH4_PCICR); /* Wait for a long time... not 1 sec. but long enough */ mdelay(100); word = SH4_PCICR_PREFIX; pci_write_reg(word, SH4_PCICR); } /* set the command/status bits to: * Wait Cycle Control + Parity Enable + Bus Master + * Mem space enable */ pci_write_reg(0x00000046, SH7780_PCICMD); /* define this host as the host bridge */ word = PCI_BASE_CLASS_BRIDGE << 24; pci_write_reg(word, SH7780_PCIRID); /* Set IO and Mem windows to local address * Make PCI and local address the same for easy 1 to 1 mapping * Window0 = map->window0.size @ non-cached area base = SDRAM * Window1 = map->window1.size @ cached area base = SDRAM */ word = ((map->window0.size - 1) & 0x1ff00001) | 0x01; pci_write_reg(0x07f00001, SH4_PCILSR0); word = ((map->window1.size - 1) & 0x1ff00001) | 0x01; pci_write_reg(0x00000001, SH4_PCILSR1); /* Set the values on window 0 PCI config registers */ word = P2SEGADDR(map->window0.base); pci_write_reg(0xa8000000, SH4_PCILAR0); pci_write_reg(0x08000000, SH7780_PCIMBAR0); /* Set the values on window 1 PCI config registers */ word = P2SEGADDR(map->window1.base); pci_write_reg(0x00000000, SH4_PCILAR1); pci_write_reg(0x00000000, SH7780_PCIMBAR1); /* Map IO space into PCI IO window * The IO window is 64K-PCIBIOS_MIN_IO in size * IO addresses will be translated to the * PCI IO window base address */ pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", PCIBIOS_MIN_IO, (64 << 10), SH7780_PCI_IO_BASE + PCIBIOS_MIN_IO); /* NOTE: I'm ignoring the PCI error IRQs for now.. * TODO: add support for the internal error interrupts and * DMA interrupts... */ /* Apply any last-minute PCIC fixups */ pci_fixup_pcic(); /* SH7780 init done, set central function init complete */ /* use round robin mode to stop a device starving/overruning */ word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO; pci_write_reg(word, SH4_PCICR); return 1; }