/*
 * Sonics Silicon Backplane
 * Bus scanning
 *
 * Copyright (C) 2005-2007 Michael Buesch <m@bues.ch>
 * Copyright (C) 2005 Martin Langer <martin-langer@gmx.de>
 * Copyright (C) 2005 Stefano Brivio <st3@riseup.net>
 * Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org>
 * Copyright (C) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
 * Copyright (C) 2006 Broadcom Corporation.
 *
 * Licensed under the GNU/GPL. See COPYING for details.
 */

#include <linux/ssb/ssb.h>
#include <linux/ssb/ssb_regs.h>
#include <linux/pci.h>
#include <linux/io.h>

#include <pcmcia/cistpl.h>
#include <pcmcia/ds.h>

#include "ssb_private.h"


const char *ssb_core_name(u16 coreid)
{
	switch (coreid) {
	case SSB_DEV_CHIPCOMMON:
		return "ChipCommon";
	case SSB_DEV_ILINE20:
		return "ILine 20";
	case SSB_DEV_SDRAM:
		return "SDRAM";
	case SSB_DEV_PCI:
		return "PCI";
	case SSB_DEV_MIPS:
		return "MIPS";
	case SSB_DEV_ETHERNET:
		return "Fast Ethernet";
	case SSB_DEV_V90:
		return "V90";
	case SSB_DEV_USB11_HOSTDEV:
		return "USB 1.1 Hostdev";
	case SSB_DEV_ADSL:
		return "ADSL";
	case SSB_DEV_ILINE100:
		return "ILine 100";
	case SSB_DEV_IPSEC:
		return "IPSEC";
	case SSB_DEV_PCMCIA:
		return "PCMCIA";
	case SSB_DEV_INTERNAL_MEM:
		return "Internal Memory";
	case SSB_DEV_MEMC_SDRAM:
		return "MEMC SDRAM";
	case SSB_DEV_EXTIF:
		return "EXTIF";
	case SSB_DEV_80211:
		return "IEEE 802.11";
	case SSB_DEV_MIPS_3302:
		return "MIPS 3302";
	case SSB_DEV_USB11_HOST:
		return "USB 1.1 Host";
	case SSB_DEV_USB11_DEV:
		return "USB 1.1 Device";
	case SSB_DEV_USB20_HOST:
		return "USB 2.0 Host";
	case SSB_DEV_USB20_DEV:
		return "USB 2.0 Device";
	case SSB_DEV_SDIO_HOST:
		return "SDIO Host";
	case SSB_DEV_ROBOSWITCH:
		return "Roboswitch";
	case SSB_DEV_PARA_ATA:
		return "PATA";
	case SSB_DEV_SATA_XORDMA:
		return "SATA XOR-DMA";
	case SSB_DEV_ETHERNET_GBIT:
		return "GBit Ethernet";
	case SSB_DEV_PCIE:
		return "PCI-E";
	case SSB_DEV_MIMO_PHY:
		return "MIMO PHY";
	case SSB_DEV_SRAM_CTRLR:
		return "SRAM Controller";
	case SSB_DEV_MINI_MACPHY:
		return "Mini MACPHY";
	case SSB_DEV_ARM_1176:
		return "ARM 1176";
	case SSB_DEV_ARM_7TDMI:
		return "ARM 7TDMI";
	case SSB_DEV_ARM_CM3:
		return "ARM Cortex M3";
	}
	return "UNKNOWN";
}

static u16 pcidev_to_chipid(struct pci_dev *pci_dev)
{
	u16 chipid_fallback = 0;

	switch (pci_dev->device) {
	case 0x4301:
		chipid_fallback = 0x4301;
		break;
	case 0x4305 ... 0x4307:
		chipid_fallback = 0x4307;
		break;
	case 0x4403:
		chipid_fallback = 0x4402;
		break;
	case 0x4610 ... 0x4615:
		chipid_fallback = 0x4610;
		break;
	case 0x4710 ... 0x4715:
		chipid_fallback = 0x4710;
		break;
	case 0x4320 ... 0x4325:
		chipid_fallback = 0x4309;
		break;
	case PCI_DEVICE_ID_BCM4401:
	case PCI_DEVICE_ID_BCM4401B0:
	case PCI_DEVICE_ID_BCM4401B1:
		chipid_fallback = 0x4401;
		break;
	default:
		ssb_err("PCI-ID not in fallback list\n");
	}

	return chipid_fallback;
}

static u8 chipid_to_nrcores(u16 chipid)
{
	switch (chipid) {
	case 0x5365:
		return 7;
	case 0x4306:
		return 6;
	case 0x4310:
		return 8;
	case 0x4307:
	case 0x4301:
		return 5;
	case 0x4401:
	case 0x4402:
		return 3;
	case 0x4710:
	case 0x4610:
	case 0x4704:
		return 9;
	default:
		ssb_err("CHIPID not in nrcores fallback list\n");
	}

	return 1;
}

static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx,
		       u16 offset)
{
	u32 lo, hi;

	switch (bus->bustype) {
	case SSB_BUSTYPE_SSB:
		offset += current_coreidx * SSB_CORE_SIZE;
		break;
	case SSB_BUSTYPE_PCI:
		break;
	case SSB_BUSTYPE_PCMCIA:
		if (offset >= 0x800) {
			ssb_pcmcia_switch_segment(bus, 1);
			offset -= 0x800;
		} else
			ssb_pcmcia_switch_segment(bus, 0);
		lo = readw(bus->mmio + offset);
		hi = readw(bus->mmio + offset + 2);
		return lo | (hi << 16);
	case SSB_BUSTYPE_SDIO:
		offset += current_coreidx * SSB_CORE_SIZE;
		return ssb_sdio_scan_read32(bus, offset);
	}
	return readl(bus->mmio + offset);
}

static int scan_switchcore(struct ssb_bus *bus, u8 coreidx)
{
	switch (bus->bustype) {
	case SSB_BUSTYPE_SSB:
		break;
	case SSB_BUSTYPE_PCI:
		return ssb_pci_switch_coreidx(bus, coreidx);
	case SSB_BUSTYPE_PCMCIA:
		return ssb_pcmcia_switch_coreidx(bus, coreidx);
	case SSB_BUSTYPE_SDIO:
		return ssb_sdio_scan_switch_coreidx(bus, coreidx);
	}
	return 0;
}

void ssb_iounmap(struct ssb_bus *bus)
{
	switch (bus->bustype) {
	case SSB_BUSTYPE_SSB:
	case SSB_BUSTYPE_PCMCIA:
		iounmap(bus->mmio);
		break;
	case SSB_BUSTYPE_PCI:
#ifdef CONFIG_SSB_PCIHOST
		pci_iounmap(bus->host_pci, bus->mmio);
#else
		SSB_BUG_ON(1); /* Can't reach this code. */
#endif
		break;
	case SSB_BUSTYPE_SDIO:
		break;
	}
	bus->mmio = NULL;
	bus->mapped_device = NULL;
}

static void __iomem *ssb_ioremap(struct ssb_bus *bus,
				 unsigned long baseaddr)
{
	void __iomem *mmio = NULL;

	switch (bus->bustype) {
	case SSB_BUSTYPE_SSB:
		/* Only map the first core for now. */
		/* fallthrough... */
	case SSB_BUSTYPE_PCMCIA:
		mmio = ioremap(baseaddr, SSB_CORE_SIZE);
		break;
	case SSB_BUSTYPE_PCI:
#ifdef CONFIG_SSB_PCIHOST
		mmio = pci_iomap(bus->host_pci, 0, ~0UL);
#else
		SSB_BUG_ON(1); /* Can't reach this code. */
#endif
		break;
	case SSB_BUSTYPE_SDIO:
		/* Nothing to ioremap in the SDIO case, just fake it */
		mmio = (void __iomem *)baseaddr;
		break;
	}

	return mmio;
}

static int we_support_multiple_80211_cores(struct ssb_bus *bus)
{
	/* More than one 802.11 core is only supported by special chips.
	 * There are chips with two 802.11 cores, but with dangling
	 * pins on the second core. Be careful and reject them here.
	 */

#ifdef CONFIG_SSB_PCIHOST
	if (bus->bustype == SSB_BUSTYPE_PCI) {
		if (bus->host_pci->vendor == PCI_VENDOR_ID_BROADCOM &&
		    ((bus->host_pci->device == 0x4313) ||
		     (bus->host_pci->device == 0x431A) ||
		     (bus->host_pci->device == 0x4321) ||
		     (bus->host_pci->device == 0x4324)))
			return 1;
	}
#endif /* CONFIG_SSB_PCIHOST */
	return 0;
}

int ssb_bus_scan(struct ssb_bus *bus,
		 unsigned long baseaddr)
{
	int err = -ENOMEM;
	void __iomem *mmio;
	u32 idhi, cc, rev, tmp;
	int dev_i, i;
	struct ssb_device *dev;
	int nr_80211_cores = 0;

	mmio = ssb_ioremap(bus, baseaddr);
	if (!mmio)
		goto out;
	bus->mmio = mmio;

	err = scan_switchcore(bus, 0); /* Switch to first core */
	if (err)
		goto err_unmap;

	idhi = scan_read32(bus, 0, SSB_IDHIGH);
	cc = (idhi & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT;
	rev = (idhi & SSB_IDHIGH_RCLO);
	rev |= (idhi & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT;

	bus->nr_devices = 0;
	if (cc == SSB_DEV_CHIPCOMMON) {
		tmp = scan_read32(bus, 0, SSB_CHIPCO_CHIPID);

		bus->chip_id = (tmp & SSB_CHIPCO_IDMASK);
		bus->chip_rev = (tmp & SSB_CHIPCO_REVMASK) >>
				SSB_CHIPCO_REVSHIFT;
		bus->chip_package = (tmp & SSB_CHIPCO_PACKMASK) >>
				    SSB_CHIPCO_PACKSHIFT;
		if (rev >= 4) {
			bus->nr_devices = (tmp & SSB_CHIPCO_NRCORESMASK) >>
					  SSB_CHIPCO_NRCORESSHIFT;
		}
		tmp = scan_read32(bus, 0, SSB_CHIPCO_CAP);
		bus->chipco.capabilities = tmp;
	} else {
		if (bus->bustype == SSB_BUSTYPE_PCI) {
			bus->chip_id = pcidev_to_chipid(bus->host_pci);
			bus->chip_rev = bus->host_pci->revision;
			bus->chip_package = 0;
		} else {
			bus->chip_id = 0x4710;
			bus->chip_rev = 0;
			bus->chip_package = 0;
		}
	}
	ssb_info("Found chip with id 0x%04X, rev 0x%02X and package 0x%02X\n",
		 bus->chip_id, bus->chip_rev, bus->chip_package);
	if (!bus->nr_devices)
		bus->nr_devices = chipid_to_nrcores(bus->chip_id);
	if (bus->nr_devices > ARRAY_SIZE(bus->devices)) {
		ssb_err("More than %d ssb cores found (%d)\n",
			SSB_MAX_NR_CORES, bus->nr_devices);
		goto err_unmap;
	}
	if (bus->bustype == SSB_BUSTYPE_SSB) {
		/* Now that we know the number of cores,
		 * remap the whole IO space for all cores.
		 */
		err = -ENOMEM;
		iounmap(mmio);
		mmio = ioremap(baseaddr, SSB_CORE_SIZE * bus->nr_devices);
		if (!mmio)
			goto out;
		bus->mmio = mmio;
	}

	/* Fetch basic information about each core/device */
	for (i = 0, dev_i = 0; i < bus->nr_devices; i++) {
		err = scan_switchcore(bus, i);
		if (err)
			goto err_unmap;
		dev = &(bus->devices[dev_i]);

		idhi = scan_read32(bus, i, SSB_IDHIGH);
		dev->id.coreid = (idhi & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT;
		dev->id.revision = (idhi & SSB_IDHIGH_RCLO);
		dev->id.revision |= (idhi & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT;
		dev->id.vendor = (idhi & SSB_IDHIGH_VC) >> SSB_IDHIGH_VC_SHIFT;
		dev->core_index = i;
		dev->bus = bus;
		dev->ops = bus->ops;

		printk(KERN_DEBUG PFX
			    "Core %d found: %s "
			    "(cc 0x%03X, rev 0x%02X, vendor 0x%04X)\n",
			    i, ssb_core_name(dev->id.coreid),
			    dev->id.coreid, dev->id.revision, dev->id.vendor);

		switch (dev->id.coreid) {
		case SSB_DEV_80211:
			nr_80211_cores++;
			if (nr_80211_cores > 1) {
				if (!we_support_multiple_80211_cores(bus)) {
					ssb_dbg("Ignoring additional 802.11 core\n");
					continue;
				}
			}
			break;
		case SSB_DEV_EXTIF:
#ifdef CONFIG_SSB_DRIVER_EXTIF
			if (bus->extif.dev) {
				ssb_warn("WARNING: Multiple EXTIFs found\n");
				break;
			}
			bus->extif.dev = dev;
#endif /* CONFIG_SSB_DRIVER_EXTIF */
			break;
		case SSB_DEV_CHIPCOMMON:
			if (bus->chipco.dev) {
				ssb_warn("WARNING: Multiple ChipCommon found\n");
				break;
			}
			bus->chipco.dev = dev;
			break;
		case SSB_DEV_MIPS:
		case SSB_DEV_MIPS_3302:
#ifdef CONFIG_SSB_DRIVER_MIPS
			if (bus->mipscore.dev) {
				ssb_warn("WARNING: Multiple MIPS cores found\n");
				break;
			}
			bus->mipscore.dev = dev;
#endif /* CONFIG_SSB_DRIVER_MIPS */
			break;
		case SSB_DEV_PCI:
		case SSB_DEV_PCIE:
#ifdef CONFIG_SSB_DRIVER_PCICORE
			if (bus->bustype == SSB_BUSTYPE_PCI) {
				/* Ignore PCI cores on PCI-E cards.
				 * Ignore PCI-E cores on PCI cards. */
				if (dev->id.coreid == SSB_DEV_PCI) {
					if (pci_is_pcie(bus->host_pci))
						continue;
				} else {
					if (!pci_is_pcie(bus->host_pci))
						continue;
				}
			}
			if (bus->pcicore.dev) {
				ssb_warn("WARNING: Multiple PCI(E) cores found\n");
				break;
			}
			bus->pcicore.dev = dev;
#endif /* CONFIG_SSB_DRIVER_PCICORE */
			break;
		case SSB_DEV_ETHERNET:
			if (bus->bustype == SSB_BUSTYPE_PCI) {
				if (bus->host_pci->vendor == PCI_VENDOR_ID_BROADCOM &&
				    (bus->host_pci->device & 0xFF00) == 0x4300) {
					/* This is a dangling ethernet core on a
					 * wireless device. Ignore it. */
					continue;
				}
			}
			break;
		default:
			break;
		}

		dev_i++;
	}
	bus->nr_devices = dev_i;

	err = 0;
out:
	return err;
err_unmap:
	ssb_iounmap(bus);
	goto out;
}
