1/* 2 * pci-vr41xx.c, PCI Control Unit routines for the NEC VR4100 series. 3 * 4 * Copyright (C) 2001-2003 MontaVista Software Inc. 5 * Author: Yoichi Yuasa <source@mvista.com> 6 * Copyright (C) 2004-2008 Yoichi Yuasa <yuasa@linux-mips.org> 7 * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 */ 23/* 24 * Changes: 25 * MontaVista Software Inc. <source@mvista.com> 26 * - New creation, NEC VR4122 and VR4131 are supported. 27 */ 28#include <linux/init.h> 29#include <linux/pci.h> 30#include <linux/types.h> 31 32#include <asm/cpu.h> 33#include <asm/io.h> 34#include <asm/vr41xx/pci.h> 35#include <asm/vr41xx/vr41xx.h> 36 37#include "pci-vr41xx.h" 38 39extern struct pci_ops vr41xx_pci_ops; 40 41static void __iomem *pciu_base; 42 43#define pciu_read(offset) readl(pciu_base + (offset)) 44#define pciu_write(offset, value) writel((value), pciu_base + (offset)) 45 46static struct pci_master_address_conversion pci_master_memory1 = { 47 .bus_base_address = PCI_MASTER_MEM1_BUS_BASE_ADDRESS, 48 .address_mask = PCI_MASTER_MEM1_ADDRESS_MASK, 49 .pci_base_address = PCI_MASTER_MEM1_PCI_BASE_ADDRESS, 50}; 51 52static struct pci_target_address_conversion pci_target_memory1 = { 53 .address_mask = PCI_TARGET_MEM1_ADDRESS_MASK, 54 .bus_base_address = PCI_TARGET_MEM1_BUS_BASE_ADDRESS, 55}; 56 57static struct pci_master_address_conversion pci_master_io = { 58 .bus_base_address = PCI_MASTER_IO_BUS_BASE_ADDRESS, 59 .address_mask = PCI_MASTER_IO_ADDRESS_MASK, 60 .pci_base_address = PCI_MASTER_IO_PCI_BASE_ADDRESS, 61}; 62 63static struct pci_mailbox_address pci_mailbox = { 64 .base_address = PCI_MAILBOX_BASE_ADDRESS, 65}; 66 67static struct pci_target_address_window pci_target_window1 = { 68 .base_address = PCI_TARGET_WINDOW1_BASE_ADDRESS, 69}; 70 71static struct resource pci_mem_resource = { 72 .name = "PCI Memory resources", 73 .start = PCI_MEM_RESOURCE_START, 74 .end = PCI_MEM_RESOURCE_END, 75 .flags = IORESOURCE_MEM, 76}; 77 78static struct resource pci_io_resource = { 79 .name = "PCI I/O resources", 80 .start = PCI_IO_RESOURCE_START, 81 .end = PCI_IO_RESOURCE_END, 82 .flags = IORESOURCE_IO, 83}; 84 85static struct pci_controller_unit_setup vr41xx_pci_controller_unit_setup = { 86 .master_memory1 = &pci_master_memory1, 87 .target_memory1 = &pci_target_memory1, 88 .master_io = &pci_master_io, 89 .exclusive_access = CANNOT_LOCK_FROM_DEVICE, 90 .wait_time_limit_from_irdy_to_trdy = 0, 91 .mailbox = &pci_mailbox, 92 .target_window1 = &pci_target_window1, 93 .master_latency_timer = 0x80, 94 .retry_limit = 0, 95 .arbiter_priority_control = PCI_ARBITRATION_MODE_FAIR, 96 .take_away_gnt_mode = PCI_TAKE_AWAY_GNT_DISABLE, 97}; 98 99static struct pci_controller vr41xx_pci_controller = { 100 .pci_ops = &vr41xx_pci_ops, 101 .mem_resource = &pci_mem_resource, 102 .io_resource = &pci_io_resource, 103}; 104 105void __init vr41xx_pciu_setup(struct pci_controller_unit_setup *setup) 106{ 107 vr41xx_pci_controller_unit_setup = *setup; 108} 109 110static int __init vr41xx_pciu_init(void) 111{ 112 struct pci_controller_unit_setup *setup; 113 struct pci_master_address_conversion *master; 114 struct pci_target_address_conversion *target; 115 struct pci_mailbox_address *mailbox; 116 struct pci_target_address_window *window; 117 unsigned long vtclock, pci_clock_max; 118 uint32_t val; 119 120 setup = &vr41xx_pci_controller_unit_setup; 121 122 if (request_mem_region(PCIU_BASE, PCIU_SIZE, "PCIU") == NULL) 123 return -EBUSY; 124 125 pciu_base = ioremap(PCIU_BASE, PCIU_SIZE); 126 if (pciu_base == NULL) { 127 release_mem_region(PCIU_BASE, PCIU_SIZE); 128 return -EBUSY; 129 } 130 131 /* Disable PCI interrupt */ 132 vr41xx_disable_pciint(); 133 134 /* Supply VTClock to PCIU */ 135 vr41xx_supply_clock(PCIU_CLOCK); 136 137 /* Dummy write, waiting for supply of VTClock. */ 138 vr41xx_disable_pciint(); 139 140 /* Select PCI clock */ 141 if (setup->pci_clock_max != 0) 142 pci_clock_max = setup->pci_clock_max; 143 else 144 pci_clock_max = PCI_CLOCK_MAX; 145 vtclock = vr41xx_get_vtclock_frequency(); 146 if (vtclock < pci_clock_max) 147 pciu_write(PCICLKSELREG, EQUAL_VTCLOCK); 148 else if ((vtclock / 2) < pci_clock_max) 149 pciu_write(PCICLKSELREG, HALF_VTCLOCK); 150 else if (current_cpu_data.processor_id >= PRID_VR4131_REV2_1 && 151 (vtclock / 3) < pci_clock_max) 152 pciu_write(PCICLKSELREG, ONE_THIRD_VTCLOCK); 153 else if ((vtclock / 4) < pci_clock_max) 154 pciu_write(PCICLKSELREG, QUARTER_VTCLOCK); 155 else { 156 printk(KERN_ERR "PCI Clock is over 33MHz.\n"); 157 iounmap(pciu_base); 158 return -EINVAL; 159 } 160 161 /* Supply PCI clock by PCI bus */ 162 vr41xx_supply_clock(PCI_CLOCK); 163 164 if (setup->master_memory1 != NULL) { 165 master = setup->master_memory1; 166 val = IBA(master->bus_base_address) | 167 MASTER_MSK(master->address_mask) | 168 WINEN | 169 PCIA(master->pci_base_address); 170 pciu_write(PCIMMAW1REG, val); 171 } else { 172 val = pciu_read(PCIMMAW1REG); 173 val &= ~WINEN; 174 pciu_write(PCIMMAW1REG, val); 175 } 176 177 if (setup->master_memory2 != NULL) { 178 master = setup->master_memory2; 179 val = IBA(master->bus_base_address) | 180 MASTER_MSK(master->address_mask) | 181 WINEN | 182 PCIA(master->pci_base_address); 183 pciu_write(PCIMMAW2REG, val); 184 } else { 185 val = pciu_read(PCIMMAW2REG); 186 val &= ~WINEN; 187 pciu_write(PCIMMAW2REG, val); 188 } 189 190 if (setup->target_memory1 != NULL) { 191 target = setup->target_memory1; 192 val = TARGET_MSK(target->address_mask) | 193 WINEN | 194 ITA(target->bus_base_address); 195 pciu_write(PCITAW1REG, val); 196 } else { 197 val = pciu_read(PCITAW1REG); 198 val &= ~WINEN; 199 pciu_write(PCITAW1REG, val); 200 } 201 202 if (setup->target_memory2 != NULL) { 203 target = setup->target_memory2; 204 val = TARGET_MSK(target->address_mask) | 205 WINEN | 206 ITA(target->bus_base_address); 207 pciu_write(PCITAW2REG, val); 208 } else { 209 val = pciu_read(PCITAW2REG); 210 val &= ~WINEN; 211 pciu_write(PCITAW2REG, val); 212 } 213 214 if (setup->master_io != NULL) { 215 master = setup->master_io; 216 val = IBA(master->bus_base_address) | 217 MASTER_MSK(master->address_mask) | 218 WINEN | 219 PCIIA(master->pci_base_address); 220 pciu_write(PCIMIOAWREG, val); 221 } else { 222 val = pciu_read(PCIMIOAWREG); 223 val &= ~WINEN; 224 pciu_write(PCIMIOAWREG, val); 225 } 226 227 if (setup->exclusive_access == CANNOT_LOCK_FROM_DEVICE) 228 pciu_write(PCIEXACCREG, UNLOCK); 229 else 230 pciu_write(PCIEXACCREG, 0); 231 232 if (current_cpu_type() == CPU_VR4122) 233 pciu_write(PCITRDYVREG, TRDYV(setup->wait_time_limit_from_irdy_to_trdy)); 234 235 pciu_write(LATTIMEREG, MLTIM(setup->master_latency_timer)); 236 237 if (setup->mailbox != NULL) { 238 mailbox = setup->mailbox; 239 val = MBADD(mailbox->base_address) | TYPE_32BITSPACE | 240 MSI_MEMORY | PREF_APPROVAL; 241 pciu_write(MAILBAREG, val); 242 } 243 244 if (setup->target_window1) { 245 window = setup->target_window1; 246 val = PMBA(window->base_address) | TYPE_32BITSPACE | 247 MSI_MEMORY | PREF_APPROVAL; 248 pciu_write(PCIMBA1REG, val); 249 } 250 251 if (setup->target_window2) { 252 window = setup->target_window2; 253 val = PMBA(window->base_address) | TYPE_32BITSPACE | 254 MSI_MEMORY | PREF_APPROVAL; 255 pciu_write(PCIMBA2REG, val); 256 } 257 258 val = pciu_read(RETVALREG); 259 val &= ~RTYVAL_MASK; 260 val |= RTYVAL(setup->retry_limit); 261 pciu_write(RETVALREG, val); 262 263 val = pciu_read(PCIAPCNTREG); 264 val &= ~(TKYGNT | PAPC); 265 266 switch (setup->arbiter_priority_control) { 267 case PCI_ARBITRATION_MODE_ALTERNATE_0: 268 val |= PAPC_ALTERNATE_0; 269 break; 270 case PCI_ARBITRATION_MODE_ALTERNATE_B: 271 val |= PAPC_ALTERNATE_B; 272 break; 273 default: 274 val |= PAPC_FAIR; 275 break; 276 } 277 278 if (setup->take_away_gnt_mode == PCI_TAKE_AWAY_GNT_ENABLE) 279 val |= TKYGNT_ENABLE; 280 281 pciu_write(PCIAPCNTREG, val); 282 283 pciu_write(COMMANDREG, PCI_COMMAND_IO | PCI_COMMAND_MEMORY | 284 PCI_COMMAND_MASTER | PCI_COMMAND_PARITY | 285 PCI_COMMAND_SERR); 286 287 /* Clear bus error */ 288 pciu_read(BUSERRADREG); 289 290 pciu_write(PCIENREG, PCIU_CONFIG_DONE); 291 292 if (setup->mem_resource != NULL) 293 vr41xx_pci_controller.mem_resource = setup->mem_resource; 294 295 if (setup->io_resource != NULL) { 296 vr41xx_pci_controller.io_resource = setup->io_resource; 297 } else { 298 set_io_port_base(IO_PORT_BASE); 299 ioport_resource.start = IO_PORT_RESOURCE_START; 300 ioport_resource.end = IO_PORT_RESOURCE_END; 301 } 302 303 if (setup->master_io) { 304 void __iomem *io_map_base; 305 struct resource *res = vr41xx_pci_controller.io_resource; 306 master = setup->master_io; 307 io_map_base = ioremap(master->bus_base_address, 308 resource_size(res)); 309 if (!io_map_base) 310 return -EBUSY; 311 312 vr41xx_pci_controller.io_map_base = (unsigned long)io_map_base; 313 } 314 315 register_pci_controller(&vr41xx_pci_controller); 316 317 return 0; 318} 319 320arch_initcall(vr41xx_pciu_init); 321