Lines Matching +full:pci +full:- +full:fnc
1 // SPDX-License-Identifier: GPL-2.0
3 * Support for Faraday Technology FTPC100 PCI Controller
7 * Based on the out-of-tree OpenWRT patch for Cortina Gemini:
10 * Based on SL2312 PCI controller code
22 #include <linux/pci.h>
31 #include "../pci.h"
39 #define FTPCI_CTRL 0x08 /* PCI control signal */
41 #define FTPCI_CONFIG 0x28 /* PCI configuration command register */
80 * Bit 31..20 defines the PCI side memory base
106 /* Defines for PCI configuration command register */
114 * struct faraday_pci_variant - encodes IP block differences
173 return -EINVAL; in faraday_res_to_memcfg()
179 pr_warn("truncated PCI memory base\n"); in faraday_res_to_memcfg()
182 pr_debug("Translated pci base @%pap, size %pap to config %08x\n", in faraday_res_to_memcfg()
198 p->base + FTPCI_CONFIG); in faraday_raw_pci_read_config()
200 *value = readl(p->base + FTPCI_DATA); in faraday_raw_pci_read_config()
213 struct faraday_pci *p = bus->sysdata; in faraday_pci_read_config()
215 dev_dbg(&bus->dev, in faraday_pci_read_config()
216 "[read] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n", in faraday_pci_read_config()
219 return faraday_raw_pci_read_config(p, bus->number, fn, config, size, value); in faraday_pci_read_config()
233 p->base + FTPCI_CONFIG); in faraday_raw_pci_write_config()
237 writel(value, p->base + FTPCI_DATA); in faraday_raw_pci_write_config()
240 writew(value, p->base + FTPCI_DATA + (config & 3)); in faraday_raw_pci_write_config()
243 writeb(value, p->base + FTPCI_DATA + (config & 3)); in faraday_raw_pci_write_config()
255 struct faraday_pci *p = bus->sysdata; in faraday_pci_write_config()
257 dev_dbg(&bus->dev, in faraday_pci_write_config()
258 "[write] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n", in faraday_pci_write_config()
261 return faraday_raw_pci_write_config(p, bus->number, fn, config, size, in faraday_pci_write_config()
317 generic_handle_irq(irq_find_mapping(p->irqdomain, i)); in faraday_pci_irq_handler()
324 .name = "PCI",
334 irq_set_chip_data(irq, domain->host_data); in faraday_pci_irq_map()
345 struct device_node *intc = of_get_next_child(p->dev->of_node, NULL); in faraday_pci_setup_cascaded_irq()
350 dev_err(p->dev, "missing child interrupt-controller node\n"); in faraday_pci_setup_cascaded_irq()
351 return -EINVAL; in faraday_pci_setup_cascaded_irq()
354 /* All PCI IRQs cascade off this one */ in faraday_pci_setup_cascaded_irq()
357 dev_err(p->dev, "failed to get parent IRQ\n"); in faraday_pci_setup_cascaded_irq()
359 return irq ?: -EINVAL; in faraday_pci_setup_cascaded_irq()
362 p->irqdomain = irq_domain_add_linear(intc, PCI_NUM_INTX, in faraday_pci_setup_cascaded_irq()
365 if (!p->irqdomain) { in faraday_pci_setup_cascaded_irq()
366 dev_err(p->dev, "failed to create Gemini PCI IRQ domain\n"); in faraday_pci_setup_cascaded_irq()
367 return -EINVAL; in faraday_pci_setup_cascaded_irq()
373 irq_create_mapping(p->irqdomain, i); in faraday_pci_setup_cascaded_irq()
380 struct device *dev = p->dev; in faraday_pci_parse_map_dma_ranges()
391 resource_list_for_each_entry(entry, &bridge->dma_ranges) { in faraday_pci_parse_map_dma_ranges()
392 u64 pci_addr = entry->res->start - entry->offset; in faraday_pci_parse_map_dma_ranges()
393 u64 end = entry->res->end - entry->offset; in faraday_pci_parse_map_dma_ranges()
397 resource_size(entry->res), &val); in faraday_pci_parse_map_dma_ranges()
401 return -EINVAL; in faraday_pci_parse_map_dma_ranges()
404 dev_info(dev, "DMA MEM%d BASE: 0x%016llx -> 0x%016llx config %08x\n", in faraday_pci_parse_map_dma_ranges()
410 dev_err(dev, "ignore extraneous dma-range %d\n", i); in faraday_pci_parse_map_dma_ranges()
422 struct device *dev = &pdev->dev; in faraday_pci_probe()
437 return -ENOMEM; in faraday_pci_probe()
439 host->ops = &faraday_pci_ops; in faraday_pci_probe()
441 host->sysdata = p; in faraday_pci_probe()
442 p->dev = dev; in faraday_pci_probe()
448 p->bus_clk = devm_clk_get_enabled(dev, "PCICLK"); in faraday_pci_probe()
449 if (IS_ERR(p->bus_clk)) in faraday_pci_probe()
450 return PTR_ERR(p->bus_clk); in faraday_pci_probe()
452 p->base = devm_platform_ioremap_resource(pdev, 0); in faraday_pci_probe()
453 if (IS_ERR(p->base)) in faraday_pci_probe()
454 return PTR_ERR(p->base); in faraday_pci_probe()
456 win = resource_list_first_type(&host->windows, IORESOURCE_IO); in faraday_pci_probe()
458 io = win->res; in faraday_pci_probe()
459 if (!faraday_res_to_memcfg(io->start - win->offset, in faraday_pci_probe()
462 writel(val, p->base + FTPCI_IOSIZE); in faraday_pci_probe()
465 return -EINVAL; in faraday_pci_probe()
470 val = readl(p->base + FTPCI_CTRL); in faraday_pci_probe()
474 writel(val, p->base + FTPCI_CTRL); in faraday_pci_probe()
477 if (variant->cascaded_irq) { in faraday_pci_probe()
486 if (!IS_ERR(p->bus_clk)) { in faraday_pci_probe()
492 rate = clk_get_rate(p->bus_clk); in faraday_pci_probe()
497 ret = clk_set_rate(p->bus_clk, 66000000); in faraday_pci_probe()
506 rate = clk_get_rate(p->bus_clk); in faraday_pci_probe()
522 p->bus = host->bus; in faraday_pci_probe()
523 p->bus->max_bus_speed = max_bus_speed; in faraday_pci_probe()
524 p->bus->cur_bus_speed = cur_bus_speed; in faraday_pci_probe()
526 pci_bus_assign_resources(p->bus); in faraday_pci_probe()
527 pci_bus_add_devices(p->bus); in faraday_pci_probe()
550 .compatible = "faraday,ftpci100-dual",