Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pci-vr41xx.c
Go to the documentation of this file.
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 <[email protected]>
6  * Copyright (C) 2004-2008 Yoichi Yuasa <[email protected]>
7  * Copyright (C) 2004 by Ralf Baechle ([email protected])
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. <[email protected]>
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 
39 extern struct pci_ops vr41xx_pci_ops;
40 
41 static 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 
46 static 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 
52 static 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 
57 static 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 
63 static struct pci_mailbox_address pci_mailbox = {
64  .base_address = PCI_MAILBOX_BASE_ADDRESS,
65 };
66 
67 static struct pci_target_address_window pci_target_window1 = {
68  .base_address = PCI_TARGET_WINDOW1_BASE_ADDRESS,
69 };
70 
71 static 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 
78 static 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 
85 static 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 
99 static 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 
106 {
107  vr41xx_pci_controller_unit_setup = *setup;
108 }
109 
110 static int __init vr41xx_pciu_init(void)
111 {
113  struct pci_master_address_conversion *master;
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) {
128  return -EBUSY;
129  }
130 
131  /* Disable PCI interrupt */
133 
134  /* Supply VTClock to PCIU */
136 
137  /* Dummy write, waiting for supply of VTClock. */
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)
148  else if ((vtclock / 2) < pci_clock_max)
150  else if (current_cpu_data.processor_id >= PRID_VR4131_REV2_1 &&
151  (vtclock / 3) < pci_clock_max)
153  else if ((vtclock / 4) < pci_clock_max)
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 */
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 
229  else
231 
232  if (current_cpu_type() == CPU_VR4122)
234 
236 
237  if (setup->mailbox != NULL) {
238  mailbox = setup->mailbox;
239  val = MBADD(mailbox->base_address) | TYPE_32BITSPACE |
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 |
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 |
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) {
268  val |= PAPC_ALTERNATE_0;
269  break;
271  val |= PAPC_ALTERNATE_B;
272  break;
273  default:
274  val |= PAPC_FAIR;
275  break;
276  }
277 
279  val |= TKYGNT_ENABLE;
280 
281  pciu_write(PCIAPCNTREG, val);
282 
286 
287  /* Clear bus error */
289 
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);
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 
320 arch_initcall(vr41xx_pciu_init);