15 #include <linux/kernel.h>
17 #include <linux/pci.h>
19 #include <linux/string.h>
21 #include <linux/capability.h>
22 #include <linux/sched.h>
23 #include <linux/errno.h>
28 #include <linux/ctype.h>
30 #include <asm/processor.h>
31 #include <asm/sections.h>
32 #include <asm/byteorder.h>
47 #define DEBUG_PCI_CFG 0
50 #define TRACE_CFG_WR(size, val, bus, dev, func, offset) \
51 pr_info("CFG WR %d-byte VAL %#x to bus %d dev %d func %d addr %u\n", \
52 size, val, bus, dev, func, offset & 0xFFF);
53 #define TRACE_CFG_RD(size, val, bus, dev, func, offset) \
54 pr_info("CFG RD %d-byte VAL %#x from bus %d dev %d func %d addr %u\n", \
55 size, val, bus, dev, func, offset & 0xFFF);
57 #define TRACE_CFG_WR(...)
58 #define TRACE_CFG_RD(...)
78 #define DEFAULT_RC_DELAY 10
81 #define MAX_RC_DELAY 20
92 static int num_ep_controllers;
94 static struct pci_ops tile_cfg_ops;
97 static struct cpumask intr_cpus_map;
116 static int tile_irq_cpu(
int irq)
122 count = cpumask_weight(&intr_cpus_map);
124 pr_warning(
"intr_cpus_map empty, interrupts will be"
125 " delievered to dataplane tiles\n");
140 static int __devinit tile_pcie_open(
int trio_index)
157 pr_err(
"PCI: ASID alloc failure on TRIO %d, give up\n",
159 goto asid_alloc_failure;
164 #ifdef USE_SHARED_PCIE_CONFIG_REGION
172 pr_err(
"PCI: CFG PIO alloc failure on TRIO %d, give up\n",
174 goto pio_alloc_failure;
186 pr_err(
"PCI: CFG PIO init failure on TRIO %d, give up\n",
188 goto pio_alloc_failure;
195 #ifdef USE_SHARED_PCIE_CONFIG_REGION
204 tilegx_legacy_irq_ack(
struct irq_data *
d)
206 __insn_mtspr(SPR_IPI_EVENT_RESET_K, 1
UL << d->
irq);
210 tilegx_legacy_irq_mask(
struct irq_data *
d)
212 __insn_mtspr(SPR_IPI_MASK_SET_K, 1
UL << d->
irq);
216 tilegx_legacy_irq_unmask(
struct irq_data *
d)
218 __insn_mtspr(SPR_IPI_MASK_RESET_K, 1
UL << d->
irq);
221 static struct irq_chip tilegx_legacy_irq_chip = {
222 .name =
"tilegx_legacy_irq",
223 .irq_ack = tilegx_legacy_irq_ack,
224 .irq_mask = tilegx_legacy_irq_mask,
225 .irq_unmask = tilegx_legacy_irq_unmask,
238 trio_handle_level_irq(
unsigned int irq,
struct irq_desc *
desc)
243 int mac = controller->mac;
244 unsigned int reg_offset;
275 cpumask_copy(&intr_cpus_map, cpu_online_mask);
278 for (i = 0; i < 4; i++) {
285 pr_err(
"PCI: no free irq vectors, failed for %d\n", i);
289 controller->irq_intx_table[
i] = irq;
292 cpu = tile_irq_cpu(irq);
297 irq, controller->mac, i);
299 pr_err(
"PCI: MAC intx config failed for %d\n", i);
307 irq_set_chip_and_handler(irq, &tilegx_legacy_irq_chip,
308 trio_handle_level_irq);
316 for (j = 0; j <
i; j++)
330 int num_trio_shims = 0;
335 pr_info(
"PCI: disabled by boot argument\n");
339 pr_info(
"PCI: Searching for controllers...\n");
347 ret = tile_pcie_open(i);
354 if (num_trio_shims == 0 || sim_is_simulator())
374 pr_err(
"PCI: PCIE_GET_PORT_PROPERTY failure, error %d,"
375 " on TRIO %d\n", ret, i);
385 num_ep_controllers++;
425 controller->
ops = &tile_cfg_ops;
434 controller->mem_offset = TILE_PCI_MEM_START +
435 (i * TILE_PCI_BAR_WINDOW_TOP);
436 controller->mem_space.start = controller->mem_offset +
437 TILE_PCI_BAR_WINDOW_TOP - TILE_PCI_BAR_WINDOW_SIZE;
438 controller->mem_space.end = controller->mem_offset +
439 TILE_PCI_BAR_WINDOW_TOP - 1;
441 snprintf(controller->mem_space_name,
442 sizeof(controller->mem_space_name),
443 "PCI mem domain %d", i);
444 controller->mem_space.name = controller->mem_space_name;
458 return controller->irq_intx_table[pin - 1];
469 unsigned int reg_offset;
474 mac = controller->mac;
538 pr_err(
"PCI: PCIE_CONFIGURE_MAC_MPS_MRS failure, "
539 "MAC %d on TRIO %d\n",
540 mac, controller->trio_index);
546 unsigned long delay = 0;
547 unsigned long trio_index;
579 pr_info(
"Delaying PCIe RC link training for %u sec"
580 " on MAC %lu on TRIO %lu\n", rc_delay[trio_index][mac],
618 pr_err(
"PCI: MAC map failure on TRIO %d\n", i);
641 unsigned int reg_offset;
642 unsigned int class_code_revision;
647 if (trio_context->
fd < 0)
650 trio_index = controller->trio_index;
651 mac = controller->mac;
689 if (rc_delay[trio_index][mac])
690 msleep(rc_delay[trio_index][mac] * 1000);
694 pr_err(
"PCI: PCIE_FORCE_LINK_UP failure, "
695 "MAC %d on TRIO %d\n", mac, trio_index);
697 pr_info(
"PCI: Found PCI controller #%d on TRIO %d MAC %d\n", i,
698 trio_index, controller->mac);
720 if (!port_status.
dl_up) {
721 pr_err(
"PCI: link is down, MAC %d on TRIO %d\n",
772 class_code_revision =
775 class_code_revision = (class_code_revision & 0xff ) |
779 reg_offset, class_code_revision);
781 #ifdef USE_SHARED_PCIE_CONFIG_REGION
787 (((
unsigned long long)mac) <<
797 pr_err(
"PCI: PCI CFG PIO alloc failure for mac %d "
798 "on TRIO %d, give up\n", mac, trio_index);
812 pr_err(
"PCI: PCI CFG PIO init failure for mac %d "
813 "on TRIO %d, give up\n", mac, trio_index);
819 (((
unsigned long long)mac) <<
828 pr_err(
"PCI: PIO map failure for mac %d on TRIO %d\n",
837 if (tile_init_irqs(controller)) {
838 pr_err(
"PCI: IRQs init failure for mac %d on TRIO %d\n",
850 controller->mem_offset);
887 if (root_bus ==
NULL)
891 fixup_read_and_payload_sizes(controller);
917 pr_err(
"PCI: no memory resources on TRIO %d mac %d\n",
918 controller->trio_index, controller->mac);
927 pr_err(
"PCI: MEM PIO alloc failure on TRIO %d mac %d, "
928 "give up\n", controller->trio_index,
934 controller->pio_mem_index =
ret;
941 controller->pio_mem_index,
946 pr_err(
"PCI: MEM PIO init failure on TRIO %d mac %d, "
947 "give up\n", controller->trio_index,
961 unsigned long nr_pages = end_pfn - start_pfn;
966 pr_err(
"PCI: Mem-Map alloc failure on TRIO %d "
967 "mac %d for MC %d, give up\n",
968 controller->trio_index,
971 goto alloc_mem_map_failed;
974 controller->mem_maps[
j] =
ret;
989 controller->mem_maps[j],
995 TILE_PCI_MEM_MAP_BASE_OFFSET,
999 pr_err(
"PCI: Mem-Map init failure on TRIO %d "
1000 "mac %d for MC %d, give up\n",
1001 controller->trio_index,
1002 controller->mac, j);
1004 goto alloc_mem_map_failed;
1008 alloc_mem_map_failed:
1029 if (!
strcmp(str,
"off")) {
1051 pcibios_fixup_final(
struct pci_dev *pdev)
1054 set_dma_offset(&pdev->
dev, TILE_PCI_MEM_MAP_BASE_OFFSET);
1055 pdev->
dev.archdata.max_direct_dma_addr =
1056 TILE_PCI_MAX_DIRECT_DMA_ADDRESS;
1073 end = phys_addr + size - 1;
1091 for (j = 1; j < 3; j++) {
1097 if ((start >= bar_start) && (end <= bar_end)) {
1106 if (controller ==
NULL)
1110 trio_fd = controller->trio->fd;
1113 start = phys_addr - controller->mem_offset;
1158 int config_type = 1;
1167 if (pci_is_root_bus(bus)) {
1173 unsigned int reg_offset;
1175 reg_offset = ((offset & 0xFFF) <<
1191 goto invalid_device;
1205 goto invalid_device;
1211 cfg_addr.
reg_addr = (offset & 0xFFF);
1212 cfg_addr.
fn =
function;
1213 cfg_addr.
dev = device;
1215 cfg_addr.
type = config_type;
1244 TRACE_CFG_RD(size, *val, busnum, device,
function, offset);
1283 int busnum = bus->
number & 0xff;
1286 int config_type = 1;
1298 if (pci_is_root_bus(bus)) {
1304 unsigned int reg_offset;
1306 reg_offset = ((offset & 0xFFF) <<
1322 goto invalid_device;
1336 goto invalid_device;
1342 cfg_addr.
reg_addr = (offset & 0xFFF);
1343 cfg_addr.
fn =
function;
1344 cfg_addr.
dev = device;
1346 cfg_addr.
type = config_type;
1361 TRACE_CFG_WR(size, val_32, busnum, device,
function, offset);
1366 TRACE_CFG_WR(size, val_16, busnum, device,
function, offset);
1371 TRACE_CFG_WR(size, val_8, busnum, device,
function, offset);
1384 static struct pci_ops tile_cfg_ops = {
1385 .read = tile_cfg_read,
1386 .write = tile_cfg_write,
1405 __insn_mtspr(SPR_IPI_EVENT_RESET_K, 1
UL << d->
irq);
1409 tilegx_msi_mask(
struct irq_data *d)
1412 __insn_mtspr(SPR_IPI_MASK_SET_K, 1
UL << d->
irq);
1416 tilegx_msi_unmask(
struct irq_data *d)
1418 __insn_mtspr(SPR_IPI_MASK_RESET_K, 1
UL << d->
irq);
1422 static struct irq_chip tilegx_msi_chip = {
1423 .name =
"tilegx_msi",
1424 .irq_startup = tilegx_msi_startup,
1425 .irq_ack = tilegx_msi_ack,
1426 .irq_mask = tilegx_msi_mask,
1427 .irq_unmask = tilegx_msi_unmask,
1458 "64-bit MSI message address not supported, "
1459 "falling back to legacy interrupts.\n");
1466 controller = irq_get_handler_data(default_irq);
1470 trio_context = controller->trio;
1479 "%s Mem-Map alloc failure. "
1480 "Failed to initialize MSI interrupts. "
1481 "Falling back to legacy interrupts.\n",
1485 goto msi_mem_map_alloc_failure;
1489 cpu = tile_irq_cpu(irq);
1495 mem_map_base = MEM_MAP_INTR_REGIONS_BASE +
1496 mem_map * MEM_MAP_INTR_REGION_SIZE;
1497 mem_map_limit = mem_map_base + MEM_MAP_INTR_REGION_SIZE - 1;
1501 mem_map, mem_map_base, mem_map_limit,
1502 trio_context->
asid);
1504 dev_printk(
KERN_INFO, &pdev->
dev,
"HV MSI config failed.\n");
1506 goto hv_msi_config_failure;
1524 hv_msi_config_failure:
1526 msi_mem_map_alloc_failure: