pci-sh7751.c (5343B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Low-Level PCI Support for the SH7751 4 * 5 * Copyright (C) 2003 - 2009 Paul Mundt 6 * Copyright (C) 2001 Dustin McIntire 7 * 8 * With cleanup by Paul van Gool <pvangool@mimotech.com>, 2003. 9 */ 10#include <linux/init.h> 11#include <linux/pci.h> 12#include <linux/types.h> 13#include <linux/errno.h> 14#include <linux/io.h> 15#include "pci-sh4.h" 16#include <asm/addrspace.h> 17#include <linux/sizes.h> 18 19static int __init __area_sdram_check(struct pci_channel *chan, 20 unsigned int area) 21{ 22 unsigned long word; 23 24 word = __raw_readl(SH7751_BCR1); 25 /* check BCR for SDRAM in area */ 26 if (((word >> area) & 1) == 0) { 27 printk("PCI: Area %d is not configured for SDRAM. BCR1=0x%lx\n", 28 area, word); 29 return 0; 30 } 31 pci_write_reg(chan, word, SH4_PCIBCR1); 32 33 word = __raw_readw(SH7751_BCR2); 34 /* check BCR2 for 32bit SDRAM interface*/ 35 if (((word >> (area << 1)) & 0x3) != 0x3) { 36 printk("PCI: Area %d is not 32 bit SDRAM. BCR2=0x%lx\n", 37 area, word); 38 return 0; 39 } 40 pci_write_reg(chan, word, SH4_PCIBCR2); 41 42 return 1; 43} 44 45static struct resource sh7751_pci_resources[] = { 46 { 47 .name = "SH7751_IO", 48 .start = 0x1000, 49 .end = SZ_4M - 1, 50 .flags = IORESOURCE_IO 51 }, { 52 .name = "SH7751_mem", 53 .start = SH7751_PCI_MEMORY_BASE, 54 .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, 55 .flags = IORESOURCE_MEM 56 }, 57}; 58 59static struct pci_channel sh7751_pci_controller = { 60 .pci_ops = &sh4_pci_ops, 61 .resources = sh7751_pci_resources, 62 .nr_resources = ARRAY_SIZE(sh7751_pci_resources), 63 .mem_offset = 0x00000000, 64 .io_offset = 0x00000000, 65 .io_map_base = SH7751_PCI_IO_BASE, 66}; 67 68static struct sh4_pci_address_map sh7751_pci_map = { 69 .window0 = { 70 .base = SH7751_CS3_BASE_ADDR, 71 .size = 0x04000000, 72 }, 73}; 74 75static int __init sh7751_pci_init(void) 76{ 77 struct pci_channel *chan = &sh7751_pci_controller; 78 unsigned int id; 79 u32 word, reg; 80 81 printk(KERN_NOTICE "PCI: Starting initialization.\n"); 82 83 chan->reg_base = 0xfe200000; 84 85 /* check for SH7751/SH7751R hardware */ 86 id = pci_read_reg(chan, SH7751_PCICONF0); 87 if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) && 88 id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) { 89 pr_debug("PCI: This is not an SH7751(R) (%x)\n", id); 90 return -ENODEV; 91 } 92 93 /* Set the BCR's to enable PCI access */ 94 reg = __raw_readl(SH7751_BCR1); 95 reg |= 0x80000; 96 __raw_writel(reg, SH7751_BCR1); 97 98 /* Turn the clocks back on (not done in reset)*/ 99 pci_write_reg(chan, 0, SH4_PCICLKR); 100 /* Clear Powerdown IRQ's (not done in reset) */ 101 word = SH4_PCIPINT_D3 | SH4_PCIPINT_D0; 102 pci_write_reg(chan, word, SH4_PCIPINT); 103 104 /* set the command/status bits to: 105 * Wait Cycle Control + Parity Enable + Bus Master + 106 * Mem space enable 107 */ 108 word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER | 109 SH7751_PCICONF1_BUM | SH7751_PCICONF1_MES; 110 pci_write_reg(chan, word, SH7751_PCICONF1); 111 112 /* define this host as the host bridge */ 113 word = PCI_BASE_CLASS_BRIDGE << 24; 114 pci_write_reg(chan, word, SH7751_PCICONF2); 115 116 /* Set IO and Mem windows to local address 117 * Make PCI and local address the same for easy 1 to 1 mapping 118 */ 119 word = sh7751_pci_map.window0.size - 1; 120 pci_write_reg(chan, word, SH4_PCILSR0); 121 /* Set the values on window 0 PCI config registers */ 122 word = P2SEGADDR(sh7751_pci_map.window0.base); 123 pci_write_reg(chan, word, SH4_PCILAR0); 124 pci_write_reg(chan, word, SH7751_PCICONF5); 125 126 /* Set the local 16MB PCI memory space window to 127 * the lowest PCI mapped address 128 */ 129 word = chan->resources[1].start & SH4_PCIMBR_MASK; 130 pr_debug("PCI: Setting upper bits of Memory window to 0x%x\n", word); 131 pci_write_reg(chan, word , SH4_PCIMBR); 132 133 /* Make sure the MSB's of IO window are set to access PCI space 134 * correctly */ 135 word = chan->resources[0].start & SH4_PCIIOBR_MASK; 136 pr_debug("PCI: Setting upper bits of IO window to 0x%x\n", word); 137 pci_write_reg(chan, word, SH4_PCIIOBR); 138 139 /* Set PCI WCRx, BCRx's, copy from BSC locations */ 140 141 /* check BCR for SDRAM in specified area */ 142 switch (sh7751_pci_map.window0.base) { 143 case SH7751_CS0_BASE_ADDR: word = __area_sdram_check(chan, 0); break; 144 case SH7751_CS1_BASE_ADDR: word = __area_sdram_check(chan, 1); break; 145 case SH7751_CS2_BASE_ADDR: word = __area_sdram_check(chan, 2); break; 146 case SH7751_CS3_BASE_ADDR: word = __area_sdram_check(chan, 3); break; 147 case SH7751_CS4_BASE_ADDR: word = __area_sdram_check(chan, 4); break; 148 case SH7751_CS5_BASE_ADDR: word = __area_sdram_check(chan, 5); break; 149 case SH7751_CS6_BASE_ADDR: word = __area_sdram_check(chan, 6); break; 150 } 151 152 if (!word) 153 return -1; 154 155 /* configure the wait control registers */ 156 word = __raw_readl(SH7751_WCR1); 157 pci_write_reg(chan, word, SH4_PCIWCR1); 158 word = __raw_readl(SH7751_WCR2); 159 pci_write_reg(chan, word, SH4_PCIWCR2); 160 word = __raw_readl(SH7751_WCR3); 161 pci_write_reg(chan, word, SH4_PCIWCR3); 162 word = __raw_readl(SH7751_MCR); 163 pci_write_reg(chan, word, SH4_PCIMCR); 164 165 /* NOTE: I'm ignoring the PCI error IRQs for now.. 166 * TODO: add support for the internal error interrupts and 167 * DMA interrupts... 168 */ 169 170 pci_fixup_pcic(chan); 171 172 /* SH7751 init done, set central function init complete */ 173 /* use round robin mode to stop a device starving/overruning */ 174 word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_ARBM; 175 pci_write_reg(chan, word, SH4_PCICR); 176 177 return register_pci_controller(chan); 178} 179arch_initcall(sh7751_pci_init);