int set_ddr_laws(u64 start, u64 sz, enum law_trgt_if id) { immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; law83xx_t *ecm = &immap->sysconf.ddrlaw[0]; u64 start_align, law_sz; int law_sz_enc; if (start == 0) start_align = 1ull << (LAW_SIZE_2G + 1); else start_align = 1ull << (ffs64(start) - 1); law_sz = min(start_align, sz); law_sz_enc = __ilog2_u64(law_sz) - 1; /* * Set up LAWBAR for all of DDR. */ ecm->bar = start & 0xfffff000; ecm->ar = (LAWAR_EN | (id << 20) | (LAWAR_SIZE & law_sz_enc)); debug("DDR:bar=0x%08x\n", ecm->bar); debug("DDR:ar=0x%08x\n", ecm->ar); /* recalculate size based on what was actually covered by the law */ law_sz = 1ull << __ilog2_u64(law_sz); /* do we still have anything to map */ sz = sz - law_sz; if (sz) { start += law_sz; start_align = 1ull << (ffs64(start) - 1); law_sz = min(start_align, sz); law_sz_enc = __ilog2_u64(law_sz) - 1; ecm = &immap->sysconf.ddrlaw[1]; ecm->bar = start & 0xfffff000; ecm->ar = (LAWAR_EN | (id << 20) | (LAWAR_SIZE & law_sz_enc)); debug("DDR:bar=0x%08x\n", ecm->bar); debug("DDR:ar=0x%08x\n", ecm->ar); } else { return 0; } /* do we still have anything to map */ sz = sz - law_sz; if (sz) return 1; return 0; }
void fsl_pci_init(struct pci_controller *hose, u32 cfg_addr, u32 cfg_data) { u16 temp16; u32 temp32; int enabled, r, inbound = 0; u16 ltssm; u8 temp8, pcie_cap; volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *)cfg_addr; struct pci_region *reg = hose->regions + hose->region_count; pci_dev_t dev = PCI_BDF(hose->first_busno, 0, 0); /* Initialize ATMU registers based on hose regions and flags */ volatile pot_t *po = &pci->pot[1]; /* skip 0 */ volatile pit_t *pi = &pci->pit[2]; /* ranges from: 3 to 1 */ u64 out_hi = 0, out_lo = -1ULL; u32 pcicsrbar, pcicsrbar_sz; #ifdef DEBUG int neg_link_w; #endif pci_setup_indirect(hose, cfg_addr, cfg_data); /* Handle setup of outbound windows first */ for (r = 0; r < hose->region_count; r++) { unsigned long flags = hose->regions[r].flags; u32 sz = (__ilog2_u64((u64)hose->regions[r].size) - 1); flags &= PCI_REGION_SYS_MEMORY|PCI_REGION_TYPE; if (flags != PCI_REGION_SYS_MEMORY) { u64 start = hose->regions[r].bus_start; u64 end = start + hose->regions[r].size; out_be32(&po->powbar, hose->regions[r].phys_start >> 12); out_be32(&po->potar, start >> 12); #ifdef CONFIG_SYS_PCI_64BIT out_be32(&po->potear, start >> 44); #else out_be32(&po->potear, 0); #endif if (hose->regions[r].flags & PCI_REGION_IO) { out_be32(&po->powar, POWAR_EN | sz | POWAR_IO_READ | POWAR_IO_WRITE); } else { out_be32(&po->powar, POWAR_EN | sz | POWAR_MEM_READ | POWAR_MEM_WRITE); out_lo = min(start, out_lo); out_hi = max(end, out_hi); } po++; } }
/* use up to 2 LAWs for DDR, used the last available LAWs */ int set_ddr_laws(u64 start, u64 sz, enum law_trgt_if id) { u64 start_align, law_sz; int law_sz_enc; if (start == 0) start_align = 1ull << (LAW_SIZE_32G + 1); else start_align = 1ull << (ffs64(start) - 1); law_sz = min(start_align, sz); law_sz_enc = __ilog2_u64(law_sz) - 1; if (set_last_law(start, law_sz_enc, id) < 0) return -1; /* recalculate size based on what was actually covered by the law */ law_sz = 1ull << __ilog2_u64(law_sz); /* do we still have anything to map */ sz = sz - law_sz; if (sz) { start += law_sz; start_align = 1ull << (ffs64(start) - 1); law_sz = min(start_align, sz); law_sz_enc = __ilog2_u64(law_sz) - 1; if (set_last_law(start, law_sz_enc, id) < 0) return -1; } else { return 0; } /* do we still have anything to map */ sz = sz - law_sz; if (sz) return 1; return 0; }
asmlinkage void plat_irq_dispatch(void) { uint64_t eirr; int i; eirr = read_c0_eirr() & read_c0_eimr(); if (eirr & (1 << IRQ_TIMER)) { do_IRQ(IRQ_TIMER); return; } i = __ilog2_u64(eirr); if (i == -1) return; do_IRQ(i); }
/* Setup one inbound ATMU window. * * We let the caller decide what the window size should be */ static void set_inbound_window(volatile pit_t *pi, struct pci_region *r, u64 size) { u32 sz = (__ilog2_u64(size) - 1); u32 flag = PIWAR_EN | PIWAR_LOCAL | PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP; out_be32(&pi->pitar, r->phys_start >> 12); out_be32(&pi->piwbar, r->bus_start >> 12); #ifdef CONFIG_SYS_PCI_64BIT out_be32(&pi->piwbear, r->bus_start >> 44); #else out_be32(&pi->piwbear, 0); #endif if (r->flags & PCI_REGION_PREFETCH) flag |= PIWAR_PF; out_be32(&pi->piwar, flag | sz); }
void fsl_pci_init(struct pci_controller *hose) { u16 temp16; u32 temp32; int busno = hose->first_busno; int enabled; u16 ltssm; u8 temp8; int r; int bridge; int inbound = 0; volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) hose->cfg_addr; pci_dev_t dev = PCI_BDF(busno,0,0); /* Initialize ATMU registers based on hose regions and flags */ volatile pot_t *po = &pci->pot[1]; /* skip 0 */ volatile pit_t *pi = &pci->pit[0]; /* ranges from: 3 to 1 */ #ifdef DEBUG int neg_link_w; #endif for (r=0; r<hose->region_count; r++) { u32 sz = (__ilog2_u64((u64)hose->regions[r].size) - 1); if (hose->regions[r].flags & PCI_REGION_SYS_MEMORY) { /* inbound */ u32 flag = PIWAR_EN | PIWAR_LOCAL | PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP; pi->pitar = (hose->regions[r].phys_start >> 12); pi->piwbar = (hose->regions[r].bus_start >> 12); #ifdef CONFIG_SYS_PCI_64BIT pi->piwbear = (hose->regions[r].bus_start >> 44); #else pi->piwbear = 0; #endif if (hose->regions[r].flags & PCI_REGION_PREFETCH) flag |= PIWAR_PF; pi->piwar = flag | sz; pi++; inbound = hose->regions[r].size > 0; } else { /* Outbound */
static int fsl_pci_setup_inbound_windows(struct pci_controller *hose, u64 out_lo, u8 pcie_cap, volatile pit_t *pi) { struct pci_region *r = hose->regions + hose->region_count; u64 sz = min((u64)gd->ram_size, (1ull << 32)); phys_addr_t phys_start = CONFIG_SYS_PCI_MEMORY_PHYS; pci_addr_t bus_start = CONFIG_SYS_PCI_MEMORY_BUS; pci_size_t pci_sz; /* we have no space available for inbound memory mapping */ if (bus_start > out_lo) { printf ("no space for inbound mapping of memory\n"); return 0; } /* limit size */ if ((bus_start + sz) > out_lo) { sz = out_lo - bus_start; debug ("limiting size to %llx\n", sz); } pci_sz = 1ull << __ilog2_u64(sz); /* * we can overlap inbound/outbound windows on PCI-E since RX & TX * links a separate */ if ((pcie_cap == PCI_CAP_ID_EXP) && (pci_sz < sz)) { debug ("R0 bus_start: %llx phys_start: %llx size: %llx\n", (u64)bus_start, (u64)phys_start, (u64)sz); pci_set_region(r, bus_start, phys_start, sz, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY | PCI_REGION_PREFETCH); /* if we aren't an exact power of two match, pci_sz is smaller * round it up to the next power of two. We report the actual * size to pci region tracking. */ if (pci_sz != sz) sz = 2ull << __ilog2_u64(sz); set_inbound_window(pi--, r++, sz); sz = 0; /* make sure we dont set the R2 window */ } else { debug ("R0 bus_start: %llx phys_start: %llx size: %llx\n", (u64)bus_start, (u64)phys_start, (u64)pci_sz); pci_set_region(r, bus_start, phys_start, pci_sz, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY | PCI_REGION_PREFETCH); set_inbound_window(pi--, r++, pci_sz); sz -= pci_sz; bus_start += pci_sz; phys_start += pci_sz; pci_sz = 1ull << __ilog2_u64(sz); if (sz) { debug ("R1 bus_start: %llx phys_start: %llx size: %llx\n", (u64)bus_start, (u64)phys_start, (u64)pci_sz); pci_set_region(r, bus_start, phys_start, pci_sz, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY | PCI_REGION_PREFETCH); set_inbound_window(pi--, r++, pci_sz); sz -= pci_sz; bus_start += pci_sz; phys_start += pci_sz; } } #if defined(CONFIG_PHYS_64BIT) && defined(CONFIG_SYS_PCI_64BIT) /* * On 64-bit capable systems, set up a mapping for all of DRAM * in high pci address space. */ pci_sz = 1ull << __ilog2_u64(gd->ram_size); /* round up to the next largest power of two */ if (gd->ram_size > pci_sz) pci_sz = 1ull << (__ilog2_u64(gd->ram_size) + 1); debug ("R64 bus_start: %llx phys_start: %llx size: %llx\n", (u64)CONFIG_SYS_PCI64_MEMORY_BUS, (u64)CONFIG_SYS_PCI_MEMORY_PHYS, (u64)pci_sz); pci_set_region(r, CONFIG_SYS_PCI64_MEMORY_BUS, CONFIG_SYS_PCI_MEMORY_PHYS, pci_sz, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY | PCI_REGION_PREFETCH); set_inbound_window(pi--, r++, pci_sz); #else pci_sz = 1ull << __ilog2_u64(sz); if (sz) { debug ("R2 bus_start: %llx phys_start: %llx size: %llx\n", (u64)bus_start, (u64)phys_start, (u64)pci_sz); pci_set_region(r, bus_start, phys_start, pci_sz, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY | PCI_REGION_PREFETCH); sz -= pci_sz; bus_start += pci_sz; phys_start += pci_sz; set_inbound_window(pi--, r++, pci_sz); } #endif #ifdef CONFIG_PHYS_64BIT if (sz && (((u64)gd->ram_size) < (1ull << 32))) printf("Was not able to map all of memory via " "inbound windows -- %lld remaining\n", sz); #endif hose->region_count = r - hose->regions; return 1; }
int fsl_pci_setup_inbound_windows(struct pci_region *r) { struct pci_region *rgn_base = r; u64 sz = min((u64)gd->ram_size, (1ull << 32) - 1); phys_addr_t phys_start = CONFIG_SYS_PCI_MEMORY_PHYS; pci_addr_t bus_start = CONFIG_SYS_PCI_MEMORY_BUS; pci_size_t pci_sz = 1ull << __ilog2_u64(sz); debug ("R0 bus_start: %llx phys_start: %llx size: %llx\n", (u64)bus_start, (u64)phys_start, (u64)pci_sz); pci_set_region(r++, bus_start, phys_start, pci_sz, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY | PCI_REGION_PREFETCH); sz -= pci_sz; bus_start += pci_sz; phys_start += pci_sz; pci_sz = 1ull << __ilog2_u64(sz); if (sz) { debug ("R1 bus_start: %llx phys_start: %llx size: %llx\n", (u64)bus_start, (u64)phys_start, (u64)pci_sz); pci_set_region(r++, bus_start, phys_start, pci_sz, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY | PCI_REGION_PREFETCH); sz -= pci_sz; bus_start += pci_sz; phys_start += pci_sz; } #if defined(CONFIG_PHYS_64BIT) && defined(CONFIG_SYS_PCI_64BIT) /* * On 64-bit capable systems, set up a mapping for all of DRAM * in high pci address space. */ pci_sz = 1ull << __ilog2_u64(gd->ram_size); /* round up to the next largest power of two */ if (gd->ram_size > pci_sz) pci_sz = 1ull << (__ilog2_u64(gd->ram_size) + 1); debug ("R64 bus_start: %llx phys_start: %llx size: %llx\n", (u64)CONFIG_SYS_PCI64_MEMORY_BUS, (u64)CONFIG_SYS_PCI_MEMORY_PHYS, (u64)pci_sz); pci_set_region(r++, CONFIG_SYS_PCI64_MEMORY_BUS, CONFIG_SYS_PCI_MEMORY_PHYS, pci_sz, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY | PCI_REGION_PREFETCH); #else pci_sz = 1ull << __ilog2_u64(sz); if (sz) { debug ("R2 bus_start: %llx phys_start: %llx size: %llx\n", (u64)bus_start, (u64)phys_start, (u64)pci_sz); pci_set_region(r++, bus_start, phys_start, pci_sz, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY | PCI_REGION_PREFETCH); sz -= pci_sz; bus_start += pci_sz; phys_start += pci_sz; } #endif #ifdef CONFIG_PHYS_64BIT if (sz && (((u64)gd->ram_size) < (1ull << 32))) printf("Was not able to map all of memory via " "inbound windows -- %lld remaining\n", sz); #endif return r - rgn_base; }