Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pcie.c
Go to the documentation of this file.
1 /*
2  * PCI-E support for CNS3xxx
3  *
4  * Copyright 2008 Cavium Networks
5  * Richard Liu <[email protected]>
6  * Copyright 2010 MontaVista Software, LLC.
7  * Anton Vorontsov <[email protected]>
8  *
9  * This file is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License, Version 2, as
11  * published by the Free Software Foundation.
12  */
13 
14 #include <linux/init.h>
15 #include <linux/kernel.h>
16 #include <linux/bug.h>
17 #include <linux/pci.h>
18 #include <linux/io.h>
19 #include <linux/ioport.h>
20 #include <linux/interrupt.h>
21 #include <linux/ptrace.h>
22 #include <asm/mach/map.h>
23 #include <mach/cns3xxx.h>
24 #include "core.h"
25 
31 };
32 
33 struct cns3xxx_pcie {
35  unsigned int irqs[2];
36  struct resource res_io;
37  struct resource res_mem;
38  struct hw_pci hw_pci;
39 
40  bool linked;
41 };
42 
43 static struct cns3xxx_pcie cns3xxx_pcie[]; /* forward decl. */
44 
45 static struct cns3xxx_pcie *sysdata_to_cnspci(void *sysdata)
46 {
47  struct pci_sys_data *root = sysdata;
48 
49  return &cns3xxx_pcie[root->domain];
50 }
51 
52 static struct cns3xxx_pcie *pdev_to_cnspci(const struct pci_dev *dev)
53 {
54  return sysdata_to_cnspci(dev->sysdata);
55 }
56 
57 static struct cns3xxx_pcie *pbus_to_cnspci(struct pci_bus *bus)
58 {
59  return sysdata_to_cnspci(bus->sysdata);
60 }
61 
62 static void __iomem *cns3xxx_pci_cfg_base(struct pci_bus *bus,
63  unsigned int devfn, int where)
64 {
65  struct cns3xxx_pcie *cnspci = pbus_to_cnspci(bus);
66  int busno = bus->number;
67  int slot = PCI_SLOT(devfn);
68  int offset;
70  void __iomem *base;
71 
72  /* If there is no link, just show the CNS PCI bridge. */
73  if (!cnspci->linked && (busno > 0 || slot > 0))
74  return NULL;
75 
76  /*
77  * The CNS PCI bridge doesn't fit into the PCI hierarchy, though
78  * we still want to access it. For this to work, we must place
79  * the first device on the same bus as the CNS PCI bridge.
80  */
81  if (busno == 0) {
82  if (slot > 1)
83  return NULL;
84  type = slot;
85  } else {
86  type = CNS3XXX_CFG1_TYPE;
87  }
88 
89  base = (void __iomem *)cnspci->cfg_bases[type].virtual;
90  offset = ((busno & 0xf) << 20) | (devfn << 12) | (where & 0xffc);
91 
92  return base + offset;
93 }
94 
95 static int cns3xxx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
96  int where, int size, u32 *val)
97 {
98  u32 v;
99  void __iomem *base;
100  u32 mask = (0x1ull << (size * 8)) - 1;
101  int shift = (where % 4) * 8;
102 
103  base = cns3xxx_pci_cfg_base(bus, devfn, where);
104  if (!base) {
105  *val = 0xffffffff;
106  return PCIBIOS_SUCCESSFUL;
107  }
108 
109  v = __raw_readl(base);
110 
111  if (bus->number == 0 && devfn == 0 &&
112  (where & 0xffc) == PCI_CLASS_REVISION) {
113  /*
114  * RC's class is 0xb, but Linux PCI driver needs 0x604
115  * for a PCIe bridge. So we must fixup the class code
116  * to 0x604 here.
117  */
118  v &= 0xff;
119  v |= 0x604 << 16;
120  }
121 
122  *val = (v >> shift) & mask;
123 
124  return PCIBIOS_SUCCESSFUL;
125 }
126 
127 static int cns3xxx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
128  int where, int size, u32 val)
129 {
130  u32 v;
131  void __iomem *base;
132  u32 mask = (0x1ull << (size * 8)) - 1;
133  int shift = (where % 4) * 8;
134 
135  base = cns3xxx_pci_cfg_base(bus, devfn, where);
136  if (!base)
137  return PCIBIOS_SUCCESSFUL;
138 
139  v = __raw_readl(base);
140 
141  v &= ~(mask << shift);
142  v |= (val & mask) << shift;
143 
144  __raw_writel(v, base);
145 
146  return PCIBIOS_SUCCESSFUL;
147 }
148 
149 static int cns3xxx_pci_setup(int nr, struct pci_sys_data *sys)
150 {
151  struct cns3xxx_pcie *cnspci = sysdata_to_cnspci(sys);
152  struct resource *res_io = &cnspci->res_io;
153  struct resource *res_mem = &cnspci->res_mem;
154 
156  request_resource(&iomem_resource, res_mem));
157 
158  pci_add_resource_offset(&sys->resources, res_io, sys->io_offset);
159  pci_add_resource_offset(&sys->resources, res_mem, sys->mem_offset);
160 
161  return 1;
162 }
163 
164 static struct pci_ops cns3xxx_pcie_ops = {
165  .read = cns3xxx_pci_read_config,
166  .write = cns3xxx_pci_write_config,
167 };
168 
169 static int cns3xxx_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
170 {
171  struct cns3xxx_pcie *cnspci = pdev_to_cnspci(dev);
172  int irq = cnspci->irqs[slot];
173 
174  pr_info("PCIe map irq: %04d:%02x:%02x.%02x slot %d, pin %d, irq: %d\n",
175  pci_domain_nr(dev->bus), dev->bus->number, PCI_SLOT(dev->devfn),
176  PCI_FUNC(dev->devfn), slot, pin, irq);
177 
178  return irq;
179 }
180 
181 static struct cns3xxx_pcie cns3xxx_pcie[] = {
182  [0] = {
183  .cfg_bases = {
184  [CNS3XXX_HOST_TYPE] = {
185  .virtual = CNS3XXX_PCIE0_HOST_BASE_VIRT,
187  .length = SZ_16M,
188  .type = MT_DEVICE,
189  },
190  [CNS3XXX_CFG0_TYPE] = {
191  .virtual = CNS3XXX_PCIE0_CFG0_BASE_VIRT,
193  .length = SZ_16M,
194  .type = MT_DEVICE,
195  },
196  [CNS3XXX_CFG1_TYPE] = {
197  .virtual = CNS3XXX_PCIE0_CFG1_BASE_VIRT,
199  .length = SZ_16M,
200  .type = MT_DEVICE,
201  },
202  },
203  .res_io = {
204  .name = "PCIe0 I/O space",
205  .start = CNS3XXX_PCIE0_IO_BASE,
206  .end = CNS3XXX_PCIE0_IO_BASE + SZ_16M - 1,
207  .flags = IORESOURCE_IO,
208  },
209  .res_mem = {
210  .name = "PCIe0 non-prefetchable",
211  .start = CNS3XXX_PCIE0_MEM_BASE,
212  .end = CNS3XXX_PCIE0_MEM_BASE + SZ_16M - 1,
213  .flags = IORESOURCE_MEM,
214  },
216  .hw_pci = {
217  .domain = 0,
218  .nr_controllers = 1,
219  .ops = &cns3xxx_pcie_ops,
220  .setup = cns3xxx_pci_setup,
221  .map_irq = cns3xxx_pcie_map_irq,
222  },
223  },
224  [1] = {
225  .cfg_bases = {
226  [CNS3XXX_HOST_TYPE] = {
227  .virtual = CNS3XXX_PCIE1_HOST_BASE_VIRT,
229  .length = SZ_16M,
230  .type = MT_DEVICE,
231  },
232  [CNS3XXX_CFG0_TYPE] = {
233  .virtual = CNS3XXX_PCIE1_CFG0_BASE_VIRT,
235  .length = SZ_16M,
236  .type = MT_DEVICE,
237  },
238  [CNS3XXX_CFG1_TYPE] = {
239  .virtual = CNS3XXX_PCIE1_CFG1_BASE_VIRT,
241  .length = SZ_16M,
242  .type = MT_DEVICE,
243  },
244  },
245  .res_io = {
246  .name = "PCIe1 I/O space",
247  .start = CNS3XXX_PCIE1_IO_BASE,
248  .end = CNS3XXX_PCIE1_IO_BASE + SZ_16M - 1,
249  .flags = IORESOURCE_IO,
250  },
251  .res_mem = {
252  .name = "PCIe1 non-prefetchable",
253  .start = CNS3XXX_PCIE1_MEM_BASE,
254  .end = CNS3XXX_PCIE1_MEM_BASE + SZ_16M - 1,
255  .flags = IORESOURCE_MEM,
256  },
258  .hw_pci = {
259  .domain = 1,
260  .nr_controllers = 1,
261  .ops = &cns3xxx_pcie_ops,
262  .setup = cns3xxx_pci_setup,
263  .map_irq = cns3xxx_pcie_map_irq,
264  },
265  },
266 };
267 
268 static void __init cns3xxx_pcie_check_link(struct cns3xxx_pcie *cnspci)
269 {
270  int port = cnspci->hw_pci.domain;
271  u32 reg;
272  unsigned long time;
273 
274  reg = __raw_readl(MISC_PCIE_CTRL(port));
275  /*
276  * Enable Application Request to 1, it will exit L1 automatically,
277  * but when chip back, it will use another clock, still can use 0x1.
278  */
279  reg |= 0x3;
280  __raw_writel(reg, MISC_PCIE_CTRL(port));
281 
282  pr_info("PCIe: Port[%d] Enable PCIe LTSSM\n", port);
283  pr_info("PCIe: Port[%d] Check data link layer...", port);
284 
285  time = jiffies;
286  while (1) {
287  reg = __raw_readl(MISC_PCIE_PM_DEBUG(port));
288  if (reg & 0x1) {
289  pr_info("Link up.\n");
290  cnspci->linked = 1;
291  break;
292  } else if (time_after(jiffies, time + 50)) {
293  pr_info("Device not found.\n");
294  break;
295  }
296  }
297 }
298 
299 static void __init cns3xxx_pcie_hw_init(struct cns3xxx_pcie *cnspci)
300 {
301  int port = cnspci->hw_pci.domain;
302  struct pci_sys_data sd = {
303  .domain = port,
304  };
305  struct pci_bus bus = {
306  .number = 0,
307  .ops = &cns3xxx_pcie_ops,
308  .sysdata = &sd,
309  };
310  u32 io_base = cnspci->res_io.start >> 16;
311  u32 mem_base = cnspci->res_mem.start >> 16;
312  u32 host_base = cnspci->cfg_bases[CNS3XXX_HOST_TYPE].pfn;
313  u32 cfg0_base = cnspci->cfg_bases[CNS3XXX_CFG0_TYPE].pfn;
314  u32 devfn = 0;
315  u8 tmp8;
316  u16 pos;
317  u16 dc;
318 
319  host_base = (__pfn_to_phys(host_base) - 1) >> 16;
320  cfg0_base = (__pfn_to_phys(cfg0_base) - 1) >> 16;
321 
322  pci_bus_write_config_byte(&bus, devfn, PCI_PRIMARY_BUS, 0);
323  pci_bus_write_config_byte(&bus, devfn, PCI_SECONDARY_BUS, 1);
324  pci_bus_write_config_byte(&bus, devfn, PCI_SUBORDINATE_BUS, 1);
325 
326  pci_bus_read_config_byte(&bus, devfn, PCI_PRIMARY_BUS, &tmp8);
327  pci_bus_read_config_byte(&bus, devfn, PCI_SECONDARY_BUS, &tmp8);
328  pci_bus_read_config_byte(&bus, devfn, PCI_SUBORDINATE_BUS, &tmp8);
329 
330  pci_bus_write_config_word(&bus, devfn, PCI_MEMORY_BASE, mem_base);
331  pci_bus_write_config_word(&bus, devfn, PCI_MEMORY_LIMIT, host_base);
332  pci_bus_write_config_word(&bus, devfn, PCI_IO_BASE_UPPER16, io_base);
333  pci_bus_write_config_word(&bus, devfn, PCI_IO_LIMIT_UPPER16, cfg0_base);
334 
335  if (!cnspci->linked)
336  return;
337 
338  /* Set Device Max_Read_Request_Size to 128 byte */
339  devfn = PCI_DEVFN(1, 0);
340  pos = pci_bus_find_capability(&bus, devfn, PCI_CAP_ID_EXP);
341  pci_bus_read_config_word(&bus, devfn, pos + PCI_EXP_DEVCTL, &dc);
342  dc &= ~(0x3 << 12); /* Clear Device Control Register [14:12] */
343  pci_bus_write_config_word(&bus, devfn, pos + PCI_EXP_DEVCTL, dc);
344  pci_bus_read_config_word(&bus, devfn, pos + PCI_EXP_DEVCTL, &dc);
345  if (!(dc & (0x3 << 12)))
346  pr_info("PCIe: Set Device Max_Read_Request_Size to 128 byte\n");
347 
348  /* Disable PCIe0 Interrupt Mask INTA to INTD */
349  __raw_writel(~0x3FFF, MISC_PCIE_INT_MASK(port));
350 }
351 
352 static int cns3xxx_pcie_abort_handler(unsigned long addr, unsigned int fsr,
353  struct pt_regs *regs)
354 {
355  if (fsr & (1 << 10))
356  regs->ARM_pc += 4;
357  return 0;
358 }
359 
360 static int __init cns3xxx_pcie_init(void)
361 {
362  int i;
363 
364  pcibios_min_io = 0;
365  pcibios_min_mem = 0;
366 
367  hook_fault_code(16 + 6, cns3xxx_pcie_abort_handler, SIGBUS, 0,
368  "imprecise external abort");
369 
370  for (i = 0; i < ARRAY_SIZE(cns3xxx_pcie); i++) {
371  iotable_init(cns3xxx_pcie[i].cfg_bases,
372  ARRAY_SIZE(cns3xxx_pcie[i].cfg_bases));
375  cns3xxx_pcie_check_link(&cns3xxx_pcie[i]);
376  cns3xxx_pcie_hw_init(&cns3xxx_pcie[i]);
377  pci_common_init(&cns3xxx_pcie[i].hw_pci);
378  }
379 
381 
382  return 0;
383 }
384 device_initcall(cns3xxx_pcie_init);