1 /* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> 7 */ 8 9 #include <linux/types.h> 10 #include <linux/pci.h> 11 #include <linux/kernel.h> 12 #include <linux/init.h> 13 #include <linux/delay.h> 14 #include <linux/clk.h> 15 #include <asm/bootinfo.h> 16 17 #include <bcm63xx_reset.h> 18 19 #include "pci-bcm63xx.h" 20 21 /* 22 * Allow PCI to be disabled at runtime depending on board nvram 23 * configuration 24 */ 25 int bcm63xx_pci_enabled; 26 27 static struct resource bcm_pci_mem_resource = { 28 .name = "bcm63xx PCI memory space", 29 .start = BCM_PCI_MEM_BASE_PA, 30 .end = BCM_PCI_MEM_END_PA, 31 .flags = IORESOURCE_MEM 32 }; 33 34 static struct resource bcm_pci_io_resource = { 35 .name = "bcm63xx PCI IO space", 36 .start = BCM_PCI_IO_BASE_PA, 37 #ifdef CONFIG_CARDBUS 38 .end = BCM_PCI_IO_HALF_PA, 39 #else 40 .end = BCM_PCI_IO_END_PA, 41 #endif 42 .flags = IORESOURCE_IO 43 }; 44 45 struct pci_controller bcm63xx_controller = { 46 .pci_ops = &bcm63xx_pci_ops, 47 .io_resource = &bcm_pci_io_resource, 48 .mem_resource = &bcm_pci_mem_resource, 49 }; 50 51 /* 52 * We handle cardbus via a fake Cardbus bridge, memory and io spaces 53 * have to be clearly separated from PCI one since we have different 54 * memory decoder. 55 */ 56 #ifdef CONFIG_CARDBUS 57 static struct resource bcm_cb_mem_resource = { 58 .name = "bcm63xx Cardbus memory space", 59 .start = BCM_CB_MEM_BASE_PA, 60 .end = BCM_CB_MEM_END_PA, 61 .flags = IORESOURCE_MEM 62 }; 63 64 static struct resource bcm_cb_io_resource = { 65 .name = "bcm63xx Cardbus IO space", 66 .start = BCM_PCI_IO_HALF_PA + 1, 67 .end = BCM_PCI_IO_END_PA, 68 .flags = IORESOURCE_IO 69 }; 70 71 struct pci_controller bcm63xx_cb_controller = { 72 .pci_ops = &bcm63xx_cb_ops, 73 .io_resource = &bcm_cb_io_resource, 74 .mem_resource = &bcm_cb_mem_resource, 75 }; 76 #endif 77 78 static struct resource bcm_pcie_mem_resource = { 79 .name = "bcm63xx PCIe memory space", 80 .start = BCM_PCIE_MEM_BASE_PA, 81 .end = BCM_PCIE_MEM_END_PA, 82 .flags = IORESOURCE_MEM, 83 }; 84 85 static struct resource bcm_pcie_io_resource = { 86 .name = "bcm63xx PCIe IO space", 87 .start = 0, 88 .end = 0, 89 .flags = 0, 90 }; 91 92 struct pci_controller bcm63xx_pcie_controller = { 93 .pci_ops = &bcm63xx_pcie_ops, 94 .io_resource = &bcm_pcie_io_resource, 95 .mem_resource = &bcm_pcie_mem_resource, 96 }; 97 98 static u32 bcm63xx_int_cfg_readl(u32 reg) 99 { 100 u32 tmp; 101 102 tmp = reg & MPI_PCICFGCTL_CFGADDR_MASK; 103 tmp |= MPI_PCICFGCTL_WRITEEN_MASK; 104 bcm_mpi_writel(tmp, MPI_PCICFGCTL_REG); 105 iob(); 106 return bcm_mpi_readl(MPI_PCICFGDATA_REG); 107 } 108 109 static void bcm63xx_int_cfg_writel(u32 val, u32 reg) 110 { 111 u32 tmp; 112 113 tmp = reg & MPI_PCICFGCTL_CFGADDR_MASK; 114 tmp |= MPI_PCICFGCTL_WRITEEN_MASK; 115 bcm_mpi_writel(tmp, MPI_PCICFGCTL_REG); 116 bcm_mpi_writel(val, MPI_PCICFGDATA_REG); 117 } 118 119 void __iomem *pci_iospace_start; 120 121 static void __init bcm63xx_reset_pcie(void) 122 { 123 u32 val; 124 u32 reg; 125 126 /* enable SERDES */ 127 if (BCMCPU_IS_6328()) 128 reg = MISC_SERDES_CTRL_6328_REG; 129 else 130 reg = MISC_SERDES_CTRL_6362_REG; 131 132 val = bcm_misc_readl(reg); 133 val |= SERDES_PCIE_EN | SERDES_PCIE_EXD_EN; 134 bcm_misc_writel(val, reg); 135 136 /* reset the PCIe core */ 137 bcm63xx_core_set_reset(BCM63XX_RESET_PCIE, 1); 138 bcm63xx_core_set_reset(BCM63XX_RESET_PCIE_EXT, 1); 139 mdelay(10); 140 141 bcm63xx_core_set_reset(BCM63XX_RESET_PCIE, 0); 142 mdelay(10); 143 144 bcm63xx_core_set_reset(BCM63XX_RESET_PCIE_EXT, 0); 145 mdelay(200); 146 } 147 148 static struct clk *pcie_clk; 149 150 static int __init bcm63xx_register_pcie(void) 151 { 152 u32 val; 153 154 /* enable clock */ 155 pcie_clk = clk_get(NULL, "pcie"); 156 if (IS_ERR_OR_NULL(pcie_clk)) 157 return -ENODEV; 158 159 clk_prepare_enable(pcie_clk); 160 161 bcm63xx_reset_pcie(); 162 163 /* configure the PCIe bridge */ 164 val = bcm_pcie_readl(PCIE_BRIDGE_OPT1_REG); 165 val |= OPT1_RD_BE_OPT_EN; 166 val |= OPT1_RD_REPLY_BE_FIX_EN; 167 val |= OPT1_PCIE_BRIDGE_HOLE_DET_EN; 168 val |= OPT1_L1_INT_STATUS_MASK_POL; 169 bcm_pcie_writel(val, PCIE_BRIDGE_OPT1_REG); 170 171 /* setup the interrupts */ 172 val = bcm_pcie_readl(PCIE_BRIDGE_RC_INT_MASK_REG); 173 val |= PCIE_RC_INT_A | PCIE_RC_INT_B | PCIE_RC_INT_C | PCIE_RC_INT_D; 174 bcm_pcie_writel(val, PCIE_BRIDGE_RC_INT_MASK_REG); 175 176 val = bcm_pcie_readl(PCIE_BRIDGE_OPT2_REG); 177 /* enable credit checking and error checking */ 178 val |= OPT2_TX_CREDIT_CHK_EN; 179 val |= OPT2_UBUS_UR_DECODE_DIS; 180 181 /* set device bus/func for the pcie device */ 182 val |= (PCIE_BUS_DEVICE << OPT2_CFG_TYPE1_BUS_NO_SHIFT); 183 val |= OPT2_CFG_TYPE1_BD_SEL; 184 bcm_pcie_writel(val, PCIE_BRIDGE_OPT2_REG); 185 186 /* setup class code as bridge */ 187 val = bcm_pcie_readl(PCIE_IDVAL3_REG); 188 val &= ~IDVAL3_CLASS_CODE_MASK; 189 val |= PCI_CLASS_BRIDGE_PCI_NORMAL; 190 bcm_pcie_writel(val, PCIE_IDVAL3_REG); 191 192 /* disable bar1 size */ 193 val = bcm_pcie_readl(PCIE_CONFIG2_REG); 194 val &= ~CONFIG2_BAR1_SIZE_MASK; 195 bcm_pcie_writel(val, PCIE_CONFIG2_REG); 196 197 /* set bar0 to little endian */ 198 val = (BCM_PCIE_MEM_BASE_PA >> 20) << BASEMASK_BASE_SHIFT; 199 val |= (BCM_PCIE_MEM_BASE_PA >> 20) << BASEMASK_MASK_SHIFT; 200 val |= BASEMASK_REMAP_EN; 201 bcm_pcie_writel(val, PCIE_BRIDGE_BAR0_BASEMASK_REG); 202 203 val = (BCM_PCIE_MEM_BASE_PA >> 20) << REBASE_ADDR_BASE_SHIFT; 204 bcm_pcie_writel(val, PCIE_BRIDGE_BAR0_REBASE_ADDR_REG); 205 206 register_pci_controller(&bcm63xx_pcie_controller); 207 208 return 0; 209 } 210 211 static int __init bcm63xx_register_pci(void) 212 { 213 unsigned int mem_size; 214 u32 val; 215 /* 216 * configuration access are done through IO space, remap 4 217 * first bytes to access it from CPU. 218 * 219 * this means that no io access from CPU should happen while 220 * we do a configuration cycle, but there's no way we can add 221 * a spinlock for each io access, so this is currently kind of 222 * broken on SMP. 223 */ 224 pci_iospace_start = ioremap(BCM_PCI_IO_BASE_PA, 4); 225 if (!pci_iospace_start) 226 return -ENOMEM; 227 228 /* setup local bus to PCI access (PCI memory) */ 229 val = BCM_PCI_MEM_BASE_PA & MPI_L2P_BASE_MASK; 230 bcm_mpi_writel(val, MPI_L2PMEMBASE1_REG); 231 bcm_mpi_writel(~(BCM_PCI_MEM_SIZE - 1), MPI_L2PMEMRANGE1_REG); 232 bcm_mpi_writel(val | MPI_L2PREMAP_ENABLED_MASK, MPI_L2PMEMREMAP1_REG); 233 234 /* set Cardbus IDSEL (type 0 cfg access on primary bus for 235 * this IDSEL will be done on Cardbus instead) */ 236 val = bcm_pcmcia_readl(PCMCIA_C1_REG); 237 val &= ~PCMCIA_C1_CBIDSEL_MASK; 238 val |= (CARDBUS_PCI_IDSEL << PCMCIA_C1_CBIDSEL_SHIFT); 239 bcm_pcmcia_writel(val, PCMCIA_C1_REG); 240 241 #ifdef CONFIG_CARDBUS 242 /* setup local bus to PCI access (Cardbus memory) */ 243 val = BCM_CB_MEM_BASE_PA & MPI_L2P_BASE_MASK; 244 bcm_mpi_writel(val, MPI_L2PMEMBASE2_REG); 245 bcm_mpi_writel(~(BCM_CB_MEM_SIZE - 1), MPI_L2PMEMRANGE2_REG); 246 val |= MPI_L2PREMAP_ENABLED_MASK | MPI_L2PREMAP_IS_CARDBUS_MASK; 247 bcm_mpi_writel(val, MPI_L2PMEMREMAP2_REG); 248 #else 249 /* disable second access windows */ 250 bcm_mpi_writel(0, MPI_L2PMEMREMAP2_REG); 251 #endif 252 253 /* setup local bus to PCI access (IO memory), we have only 1 254 * IO window for both PCI and cardbus, but it cannot handle 255 * both at the same time, assume standard PCI for now, if 256 * cardbus card has IO zone, PCI fixup will change window to 257 * cardbus */ 258 val = BCM_PCI_IO_BASE_PA & MPI_L2P_BASE_MASK; 259 bcm_mpi_writel(val, MPI_L2PIOBASE_REG); 260 bcm_mpi_writel(~(BCM_PCI_IO_SIZE - 1), MPI_L2PIORANGE_REG); 261 bcm_mpi_writel(val | MPI_L2PREMAP_ENABLED_MASK, MPI_L2PIOREMAP_REG); 262 263 /* enable PCI related GPIO pins */ 264 bcm_mpi_writel(MPI_LOCBUSCTL_EN_PCI_GPIO_MASK, MPI_LOCBUSCTL_REG); 265 266 /* setup PCI to local bus access, used by PCI device to target 267 * local RAM while bus mastering */ 268 bcm63xx_int_cfg_writel(0, PCI_BASE_ADDRESS_3); 269 if (BCMCPU_IS_3368() || BCMCPU_IS_6358() || BCMCPU_IS_6368()) 270 val = MPI_SP0_REMAP_ENABLE_MASK; 271 else 272 val = 0; 273 bcm_mpi_writel(val, MPI_SP0_REMAP_REG); 274 275 bcm63xx_int_cfg_writel(0x0, PCI_BASE_ADDRESS_4); 276 bcm_mpi_writel(0, MPI_SP1_REMAP_REG); 277 278 mem_size = bcm63xx_get_memory_size(); 279 280 /* 6348 before rev b0 exposes only 16 MB of RAM memory through 281 * PCI, throw a warning if we have more memory */ 282 if (BCMCPU_IS_6348() && (bcm63xx_get_cpu_rev() & 0xf0) == 0xa0) { 283 if (mem_size > (16 * 1024 * 1024)) 284 printk(KERN_WARNING "bcm63xx: this CPU " 285 "revision cannot handle more than 16MB " 286 "of RAM for PCI bus mastering\n"); 287 } else { 288 /* setup sp0 range to local RAM size */ 289 bcm_mpi_writel(~(mem_size - 1), MPI_SP0_RANGE_REG); 290 bcm_mpi_writel(0, MPI_SP1_RANGE_REG); 291 } 292 293 /* change host bridge retry counter to infinite number of 294 * retry, needed for some broadcom wifi cards with Silicon 295 * Backplane bus where access to srom seems very slow */ 296 val = bcm63xx_int_cfg_readl(BCMPCI_REG_TIMERS); 297 val &= ~REG_TIMER_RETRY_MASK; 298 bcm63xx_int_cfg_writel(val, BCMPCI_REG_TIMERS); 299 300 /* enable memory decoder and bus mastering */ 301 val = bcm63xx_int_cfg_readl(PCI_COMMAND); 302 val |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); 303 bcm63xx_int_cfg_writel(val, PCI_COMMAND); 304 305 /* enable read prefetching & disable byte swapping for bus 306 * mastering transfers */ 307 val = bcm_mpi_readl(MPI_PCIMODESEL_REG); 308 val &= ~MPI_PCIMODESEL_BAR1_NOSWAP_MASK; 309 val &= ~MPI_PCIMODESEL_BAR2_NOSWAP_MASK; 310 val &= ~MPI_PCIMODESEL_PREFETCH_MASK; 311 val |= (8 << MPI_PCIMODESEL_PREFETCH_SHIFT); 312 bcm_mpi_writel(val, MPI_PCIMODESEL_REG); 313 314 /* enable pci interrupt */ 315 val = bcm_mpi_readl(MPI_LOCINT_REG); 316 val |= MPI_LOCINT_MASK(MPI_LOCINT_EXT_PCI_INT); 317 bcm_mpi_writel(val, MPI_LOCINT_REG); 318 319 register_pci_controller(&bcm63xx_controller); 320 321 #ifdef CONFIG_CARDBUS 322 register_pci_controller(&bcm63xx_cb_controller); 323 #endif 324 325 /* mark memory space used for IO mapping as reserved */ 326 request_mem_region(BCM_PCI_IO_BASE_PA, BCM_PCI_IO_SIZE, 327 "bcm63xx PCI IO space"); 328 return 0; 329 } 330 331 332 static int __init bcm63xx_pci_init(void) 333 { 334 if (!bcm63xx_pci_enabled) 335 return -ENODEV; 336 337 switch (bcm63xx_get_cpu_id()) { 338 case BCM6328_CPU_ID: 339 case BCM6362_CPU_ID: 340 return bcm63xx_register_pcie(); 341 case BCM3368_CPU_ID: 342 case BCM6348_CPU_ID: 343 case BCM6358_CPU_ID: 344 case BCM6368_CPU_ID: 345 return bcm63xx_register_pci(); 346 default: 347 return -ENODEV; 348 } 349 } 350 351 arch_initcall(bcm63xx_pci_init); 352
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.