static int __init pcie_init()

in drivers/pci/pcie-sh7786.c [302:481]


static int __init pcie_init(struct sh7786_pcie_port *port)
{
	struct pci_channel *chan = port->hose;
	unsigned int data;
	phys_addr_t memstart, memend;
	int ret, i, win;

	/* Begin initialization */
	pcie_reset(port);

	/*
	 * Initial header for port config space is type 1, set the device
	 * class to match. Hardware takes care of propagating the IDSETR
	 * settings, so there is no need to bother with a quirk.
	 */
	pci_write_reg(chan, PCI_CLASS_BRIDGE_PCI << 16, SH4A_PCIEIDSETR1);

	/* Initialize default capabilities. */
	data = pci_read_reg(chan, SH4A_PCIEEXPCAP0);
	data &= ~(PCI_EXP_FLAGS_TYPE << 16);

	if (port->endpoint)
		data |= PCI_EXP_TYPE_ENDPOINT << 20;
	else
		data |= PCI_EXP_TYPE_ROOT_PORT << 20;

	data |= PCI_CAP_ID_EXP;
	pci_write_reg(chan, data, SH4A_PCIEEXPCAP0);

	/* Enable data link layer active state reporting */
	pci_write_reg(chan, PCI_EXP_LNKCAP_DLLLARC, SH4A_PCIEEXPCAP3);

	/* Enable extended sync and ASPM L0s support */
	data = pci_read_reg(chan, SH4A_PCIEEXPCAP4);
	data &= ~PCI_EXP_LNKCTL_ASPMC;
	data |= PCI_EXP_LNKCTL_ES | 1;
	pci_write_reg(chan, data, SH4A_PCIEEXPCAP4);

	/* Write out the physical slot number */
	data = pci_read_reg(chan, SH4A_PCIEEXPCAP5);
	data &= ~PCI_EXP_SLTCAP_PSN;
	data |= (port->index + 1) << 19;
	pci_write_reg(chan, data, SH4A_PCIEEXPCAP5);

	/* Set the completion timer timeout to the maximum 32ms. */
	data = pci_read_reg(chan, SH4A_PCIETLCTLR);
	data &= ~0x3f00;
	data |= 0x32 << 8;
	pci_write_reg(chan, data, SH4A_PCIETLCTLR);

	/*
	 * Set fast training sequences to the maximum 255,
	 * and enable MAC data scrambling.
	 */
	data = pci_read_reg(chan, SH4A_PCIEMACCTLR);
	data &= ~PCIEMACCTLR_SCR_DIS;
	data |= (0xff << 16);
	pci_write_reg(chan, data, SH4A_PCIEMACCTLR);

	memstart = __pa(memory_start);
	memend   = __pa(memory_end);
	memsize = roundup_pow_of_two(memend - memstart);

	/*
	 * The start address must be aligned on its size. So we round
	 * it down, and then recalculate the size so that it covers
	 * the entire memory.
	 */
	memstart = ALIGN_DOWN(memstart, memsize);
	memsize = roundup_pow_of_two(memend - memstart);

	/*
	 * If there's more than 512MB of memory, we need to roll over to
	 * LAR1/LAMR1.
	 */
	if (memsize > SZ_512M) {
		pci_write_reg(chan, memstart + SZ_512M, SH4A_PCIELAR1);
		pci_write_reg(chan, ((memsize - SZ_512M) - SZ_256) | 1,
			      SH4A_PCIELAMR1);
		memsize = SZ_512M;
	} else {
		/*
		 * Otherwise just zero it out and disable it.
		 */
		pci_write_reg(chan, 0, SH4A_PCIELAR1);
		pci_write_reg(chan, 0, SH4A_PCIELAMR1);
	}

	/*
	 * LAR0/LAMR0 covers up to the first 512MB, which is enough to
	 * cover all of lowmem on most platforms.
	 */
	pci_write_reg(chan, memstart, SH4A_PCIELAR0);
	pci_write_reg(chan, (memsize - SZ_256) | 1, SH4A_PCIELAMR0);

	/* Finish initialization */
	data = pci_read_reg(chan, SH4A_PCIETCTLR);
	data |= 0x1;
	pci_write_reg(chan, data, SH4A_PCIETCTLR);

	/* Let things settle down a bit.. */
	mdelay(100);

	/* Enable DL_Active Interrupt generation */
	data = pci_read_reg(chan, SH4A_PCIEDLINTENR);
	data |= PCIEDLINTENR_DLL_ACT_ENABLE;
	pci_write_reg(chan, data, SH4A_PCIEDLINTENR);

	/* Disable MAC data scrambling. */
	data = pci_read_reg(chan, SH4A_PCIEMACCTLR);
	data |= PCIEMACCTLR_SCR_DIS | (0xff << 16);
	pci_write_reg(chan, data, SH4A_PCIEMACCTLR);

	/*
	 * This will timeout if we don't have a link, but we permit the
	 * port to register anyways in order to support hotplug on future
	 * hardware.
	 */
	ret = pci_wait_for_irq(chan, MASK_INT_TX_CTRL);

	data = pci_read_reg(chan, SH4A_PCIEPCICONF1);
	data &= ~(PCI_STATUS_DEVSEL_MASK << 16);
	data |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
		(PCI_STATUS_CAP_LIST | PCI_STATUS_DEVSEL_FAST) << 16;
	pci_write_reg(chan, data, SH4A_PCIEPCICONF1);

	pci_write_reg(chan, 0x80888000, SH4A_PCIETXVC0DCTLR);
	pci_write_reg(chan, 0x00222000, SH4A_PCIERXVC0DCTLR);

	wmb();

	if (ret == 0) {
		data = pci_read_reg(chan, SH4A_PCIEMACSR);
		printk(KERN_NOTICE "PCI: PCIe#%d x%d link detected\n",
		       port->index, (data >> 20) & 0x3f);
	} else
		printk(KERN_NOTICE "PCI: PCIe#%d link down\n",
		       port->index);

	for (i = win = 0; i < chan->nr_resources; i++) {
		struct resource *res = chan->resources + i;
		resource_size_t size;
		u32 mask;

		/*
		 * We can't use the 32-bit mode windows in legacy 29-bit
		 * mode, so just skip them entirely.
		 */
		if ((res->flags & IORESOURCE_MEM_32BIT) && __in_29bit_mode())
			res->flags |= IORESOURCE_DISABLED;

		if (res->flags & IORESOURCE_DISABLED)
			continue;

		pci_write_reg(chan, 0x00000000, SH4A_PCIEPTCTLR(win));

		/*
		 * The PAMR mask is calculated in units of 256kB, which
		 * keeps things pretty simple.
		 */
		size = resource_size(res);
		mask = (roundup_pow_of_two(size) / SZ_256K) - 1;
		pci_write_reg(chan, mask << 18, SH4A_PCIEPAMR(win));

		pci_write_reg(chan, upper_32_bits(res->start),
			      SH4A_PCIEPARH(win));
		pci_write_reg(chan, lower_32_bits(res->start),
			      SH4A_PCIEPARL(win));

		mask = MASK_PARE;
		if (res->flags & IORESOURCE_IO)
			mask |= MASK_SPC;

		pci_write_reg(chan, mask, SH4A_PCIEPTCTLR(win));

		win++;
	}

	return 0;
}