/* * Special configuration registers directly in the first few words * in I/O space.
*/ #define FTPCI_IOSIZE 0x00 #define FTPCI_PROT 0x04 /* AHB protection */ #define FTPCI_CTRL 0x08 /* PCI control signal */ #define FTPCI_SOFTRST 0x10 /* Soft reset counter and response error enable */ #define FTPCI_CONFIG 0x28 /* PCI configuration command register */ #define FTPCI_DATA 0x2C
#define FARADAY_PCI_STATUS_CMD 0x04 /* Status and command */ #define FARADAY_PCI_PMC 0x40 /* Power management control */ #define FARADAY_PCI_PMCSR 0x44 /* Power management status */ #define FARADAY_PCI_CTRL1 0x48 /* Control register 1 */ #define FARADAY_PCI_CTRL2 0x4C /* Control register 2 */ #define FARADAY_PCI_MEM1_BASE_SIZE 0x50 /* Memory base and size #1 */ #define FARADAY_PCI_MEM2_BASE_SIZE 0x54 /* Memory base and size #2 */ #define FARADAY_PCI_MEM3_BASE_SIZE 0x58 /* Memory base and size #3 */
/* * Memory configs: * Bit 31..20 defines the PCI side memory base * Bit 19..16 (4 bits) defines the size per below
*/ #define FARADAY_PCI_MEMBASE_MASK 0xfff00000 #define FARADAY_PCI_MEMSIZE_1MB 0x0 #define FARADAY_PCI_MEMSIZE_2MB 0x1 #define FARADAY_PCI_MEMSIZE_4MB 0x2 #define FARADAY_PCI_MEMSIZE_8MB 0x3 #define FARADAY_PCI_MEMSIZE_16MB 0x4 #define FARADAY_PCI_MEMSIZE_32MB 0x5 #define FARADAY_PCI_MEMSIZE_64MB 0x6 #define FARADAY_PCI_MEMSIZE_128MB 0x7 #define FARADAY_PCI_MEMSIZE_256MB 0x8 #define FARADAY_PCI_MEMSIZE_512MB 0x9 #define FARADAY_PCI_MEMSIZE_1GB 0xa #define FARADAY_PCI_MEMSIZE_2GB 0xb #define FARADAY_PCI_MEMSIZE_SHIFT 16
/* * The DMA base is set to 0x0 for all memory segments, it reflects the * fact that the memory of the host system starts at 0x0.
*/ #define FARADAY_PCI_DMA_MEM1_BASE 0x00000000 #define FARADAY_PCI_DMA_MEM2_BASE 0x00000000 #define FARADAY_PCI_DMA_MEM3_BASE 0x00000000
/** * struct faraday_pci_variant - encodes IP block differences * @cascaded_irq: this host has cascaded IRQs from an interrupt controller * embedded in the host bridge.
*/ struct faraday_pci_variant { bool cascaded_irq;
};
switch (mem_size) { case SZ_1M:
outval = FARADAY_PCI_MEMSIZE_1MB; break; case SZ_2M:
outval = FARADAY_PCI_MEMSIZE_2MB; break; case SZ_4M:
outval = FARADAY_PCI_MEMSIZE_4MB; break; case SZ_8M:
outval = FARADAY_PCI_MEMSIZE_8MB; break; case SZ_16M:
outval = FARADAY_PCI_MEMSIZE_16MB; break; case SZ_32M:
outval = FARADAY_PCI_MEMSIZE_32MB; break; case SZ_64M:
outval = FARADAY_PCI_MEMSIZE_64MB; break; case SZ_128M:
outval = FARADAY_PCI_MEMSIZE_128MB; break; case SZ_256M:
outval = FARADAY_PCI_MEMSIZE_256MB; break; case SZ_512M:
outval = FARADAY_PCI_MEMSIZE_512MB; break; case SZ_1G:
outval = FARADAY_PCI_MEMSIZE_1GB; break; case SZ_2G:
outval = FARADAY_PCI_MEMSIZE_2GB; break; default: return -EINVAL;
}
outval <<= FARADAY_PCI_MEMSIZE_SHIFT;
/* This is probably not good */ if (mem_base & ~(FARADAY_PCI_MEMBASE_MASK))
pr_warn("truncated PCI memory base\n"); /* Translate to bridge side address space */
outval |= (mem_base & FARADAY_PCI_MEMBASE_MASK);
pr_debug("Translated pci base @%pap, size %pap to config %08x\n",
&mem_base, &mem_size, outval);
*val = outval; return 0;
}
staticint faraday_raw_pci_read_config(struct faraday_pci *p, int bus_number, unsignedint fn, int config, int size,
u32 *value)
{
writel(PCI_CONF1_ADDRESS(bus_number, PCI_SLOT(fn),
PCI_FUNC(fn), config),
p->base + FTPCI_CONFIG);
staticint faraday_raw_pci_write_config(struct faraday_pci *p, int bus_number, unsignedint fn, int config, int size,
u32 value)
{ int ret = PCIBIOS_SUCCESSFUL;
/* All PCI IRQs cascade off this one */
irq = of_irq_get(intc, 0); if (irq <= 0) {
dev_err(p->dev, "failed to get parent IRQ\n");
of_node_put(intc); return irq ?: -EINVAL;
}
resource_list_for_each_entry(entry, &bridge->dma_ranges) {
u64 pci_addr = entry->res->start - entry->offset;
u64 end = entry->res->end - entry->offset; int ret;
ret = faraday_res_to_memcfg(pci_addr,
resource_size(entry->res), &val); if (ret) {
dev_err(dev, "DMA range %d: illegal MEM resource size\n", i); return -EINVAL;
}
if ((rate == 33000000) && (val & PCI_STATUS_66MHZ_CAPABLE)) {
dev_info(dev, "33MHz bus is 66MHz capable\n");
max_bus_speed = PCI_SPEED_66MHz;
ret = clk_set_rate(p->bus_clk, 66000000); if (ret)
dev_err(dev, "failed to set bus clock\n");
} else {
dev_info(dev, "33MHz only bus\n");
max_bus_speed = PCI_SPEED_33MHz;
}
/* Bumping the clock may fail so read back the rate */
rate = clk_get_rate(p->bus_clk); if (rate == 33000000)
cur_bus_speed = PCI_SPEED_33MHz; if (rate == 66000000)
cur_bus_speed = PCI_SPEED_66MHz;
}
ret = faraday_pci_parse_map_dma_ranges(p); if (ret) return ret;
ret = pci_scan_root_bus_bridge(host); if (ret) {
dev_err(dev, "failed to scan host: %d\n", ret); return ret;
}
p->bus = host->bus;
p->bus->max_bus_speed = max_bus_speed;
p->bus->cur_bus_speed = cur_bus_speed;
/* * We encode bridge variants here, we have at least two so it doesn't * hurt to have infrastructure to encompass future variants as well.
*/ staticconststruct faraday_pci_variant faraday_regular = {
.cascaded_irq = true,
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.