18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * Broadcom specific AMBA
38c2ecf20Sopenharmony_ci * Broadcom MIPS32 74K core driver
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright 2009, Broadcom Corporation
68c2ecf20Sopenharmony_ci * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
78c2ecf20Sopenharmony_ci * Copyright 2010, Bernhard Loos <bernhardloos@googlemail.com>
88c2ecf20Sopenharmony_ci * Copyright 2011, Hauke Mehrtens <hauke@hauke-m.de>
98c2ecf20Sopenharmony_ci *
108c2ecf20Sopenharmony_ci * Licensed under the GNU/GPL. See COPYING for details.
118c2ecf20Sopenharmony_ci */
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#include "bcma_private.h"
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#include <linux/bcma/bcma.h>
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#include <linux/serial.h>
188c2ecf20Sopenharmony_ci#include <linux/serial_core.h>
198c2ecf20Sopenharmony_ci#include <linux/serial_reg.h>
208c2ecf20Sopenharmony_ci#include <linux/time.h>
218c2ecf20Sopenharmony_ci#ifdef CONFIG_BCM47XX
228c2ecf20Sopenharmony_ci#include <linux/bcm47xx_nvram.h>
238c2ecf20Sopenharmony_ci#endif
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_cienum bcma_boot_dev {
268c2ecf20Sopenharmony_ci	BCMA_BOOT_DEV_UNK = 0,
278c2ecf20Sopenharmony_ci	BCMA_BOOT_DEV_ROM,
288c2ecf20Sopenharmony_ci	BCMA_BOOT_DEV_PARALLEL,
298c2ecf20Sopenharmony_ci	BCMA_BOOT_DEV_SERIAL,
308c2ecf20Sopenharmony_ci	BCMA_BOOT_DEV_NAND,
318c2ecf20Sopenharmony_ci};
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci/* The 47162a0 hangs when reading MIPS DMP registers registers */
348c2ecf20Sopenharmony_cistatic inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev)
358c2ecf20Sopenharmony_ci{
368c2ecf20Sopenharmony_ci	return dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM47162 &&
378c2ecf20Sopenharmony_ci	       dev->bus->chipinfo.rev == 0 && dev->id.id == BCMA_CORE_MIPS_74K;
388c2ecf20Sopenharmony_ci}
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci/* The 5357b0 hangs when reading USB20H DMP registers */
418c2ecf20Sopenharmony_cistatic inline bool bcma_core_mips_bcm5357b0_quirk(struct bcma_device *dev)
428c2ecf20Sopenharmony_ci{
438c2ecf20Sopenharmony_ci	return (dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM5357 ||
448c2ecf20Sopenharmony_ci		dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM4749) &&
458c2ecf20Sopenharmony_ci	       dev->bus->chipinfo.pkg == 11 &&
468c2ecf20Sopenharmony_ci	       dev->id.id == BCMA_CORE_USB20_HOST;
478c2ecf20Sopenharmony_ci}
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_cistatic inline u32 mips_read32(struct bcma_drv_mips *mcore,
508c2ecf20Sopenharmony_ci			      u16 offset)
518c2ecf20Sopenharmony_ci{
528c2ecf20Sopenharmony_ci	return bcma_read32(mcore->core, offset);
538c2ecf20Sopenharmony_ci}
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_cistatic inline void mips_write32(struct bcma_drv_mips *mcore,
568c2ecf20Sopenharmony_ci				u16 offset,
578c2ecf20Sopenharmony_ci				u32 value)
588c2ecf20Sopenharmony_ci{
598c2ecf20Sopenharmony_ci	bcma_write32(mcore->core, offset, value);
608c2ecf20Sopenharmony_ci}
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_cistatic u32 bcma_core_mips_irqflag(struct bcma_device *dev)
638c2ecf20Sopenharmony_ci{
648c2ecf20Sopenharmony_ci	u32 flag;
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci	if (bcma_core_mips_bcm47162a0_quirk(dev))
678c2ecf20Sopenharmony_ci		return dev->core_index;
688c2ecf20Sopenharmony_ci	if (bcma_core_mips_bcm5357b0_quirk(dev))
698c2ecf20Sopenharmony_ci		return dev->core_index;
708c2ecf20Sopenharmony_ci	flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30);
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci	if (flag)
738c2ecf20Sopenharmony_ci		return flag & 0x1F;
748c2ecf20Sopenharmony_ci	else
758c2ecf20Sopenharmony_ci		return 0x3f;
768c2ecf20Sopenharmony_ci}
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci/* Get the MIPS IRQ assignment for a specified device.
798c2ecf20Sopenharmony_ci * If unassigned, 0 is returned.
808c2ecf20Sopenharmony_ci * If disabled, 5 is returned.
818c2ecf20Sopenharmony_ci * If not supported, 6 is returned.
828c2ecf20Sopenharmony_ci */
838c2ecf20Sopenharmony_ciunsigned int bcma_core_mips_irq(struct bcma_device *dev)
848c2ecf20Sopenharmony_ci{
858c2ecf20Sopenharmony_ci	struct bcma_device *mdev = dev->bus->drv_mips.core;
868c2ecf20Sopenharmony_ci	u32 irqflag;
878c2ecf20Sopenharmony_ci	unsigned int irq;
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci	irqflag = bcma_core_mips_irqflag(dev);
908c2ecf20Sopenharmony_ci	if (irqflag == 0x3f)
918c2ecf20Sopenharmony_ci		return 6;
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci	for (irq = 0; irq <= 4; irq++)
948c2ecf20Sopenharmony_ci		if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) &
958c2ecf20Sopenharmony_ci		    (1 << irqflag))
968c2ecf20Sopenharmony_ci			return irq;
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ci	return 5;
998c2ecf20Sopenharmony_ci}
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_cistatic void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
1028c2ecf20Sopenharmony_ci{
1038c2ecf20Sopenharmony_ci	unsigned int oldirq = bcma_core_mips_irq(dev);
1048c2ecf20Sopenharmony_ci	struct bcma_bus *bus = dev->bus;
1058c2ecf20Sopenharmony_ci	struct bcma_device *mdev = bus->drv_mips.core;
1068c2ecf20Sopenharmony_ci	u32 irqflag;
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci	irqflag = bcma_core_mips_irqflag(dev);
1098c2ecf20Sopenharmony_ci	BUG_ON(oldirq == 6);
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci	dev->irq = irq + 2;
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ci	/* clear the old irq */
1148c2ecf20Sopenharmony_ci	if (oldirq == 0)
1158c2ecf20Sopenharmony_ci		bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
1168c2ecf20Sopenharmony_ci			    bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) &
1178c2ecf20Sopenharmony_ci			    ~(1 << irqflag));
1188c2ecf20Sopenharmony_ci	else if (oldirq != 5)
1198c2ecf20Sopenharmony_ci		bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(oldirq), 0);
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ci	/* assign the new one */
1228c2ecf20Sopenharmony_ci	if (irq == 0) {
1238c2ecf20Sopenharmony_ci		bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
1248c2ecf20Sopenharmony_ci			    bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) |
1258c2ecf20Sopenharmony_ci			    (1 << irqflag));
1268c2ecf20Sopenharmony_ci	} else {
1278c2ecf20Sopenharmony_ci		u32 irqinitmask = bcma_read32(mdev,
1288c2ecf20Sopenharmony_ci					      BCMA_MIPS_MIPS74K_INTMASK(irq));
1298c2ecf20Sopenharmony_ci		if (irqinitmask) {
1308c2ecf20Sopenharmony_ci			struct bcma_device *core;
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_ci			/* backplane irq line is in use, find out who uses
1338c2ecf20Sopenharmony_ci			 * it and set user to irq 0
1348c2ecf20Sopenharmony_ci			 */
1358c2ecf20Sopenharmony_ci			list_for_each_entry(core, &bus->cores, list) {
1368c2ecf20Sopenharmony_ci				if ((1 << bcma_core_mips_irqflag(core)) ==
1378c2ecf20Sopenharmony_ci				    irqinitmask) {
1388c2ecf20Sopenharmony_ci					bcma_core_mips_set_irq(core, 0);
1398c2ecf20Sopenharmony_ci					break;
1408c2ecf20Sopenharmony_ci				}
1418c2ecf20Sopenharmony_ci			}
1428c2ecf20Sopenharmony_ci		}
1438c2ecf20Sopenharmony_ci		bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq),
1448c2ecf20Sopenharmony_ci			     1 << irqflag);
1458c2ecf20Sopenharmony_ci	}
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci	bcma_debug(bus, "set_irq: core 0x%04x, irq %d => %d\n",
1488c2ecf20Sopenharmony_ci		   dev->id.id, oldirq <= 4 ? oldirq + 2 : 0, irq + 2);
1498c2ecf20Sopenharmony_ci}
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_cistatic void bcma_core_mips_set_irq_name(struct bcma_bus *bus, unsigned int irq,
1528c2ecf20Sopenharmony_ci					u16 coreid, u8 unit)
1538c2ecf20Sopenharmony_ci{
1548c2ecf20Sopenharmony_ci	struct bcma_device *core;
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci	core = bcma_find_core_unit(bus, coreid, unit);
1578c2ecf20Sopenharmony_ci	if (!core) {
1588c2ecf20Sopenharmony_ci		bcma_warn(bus,
1598c2ecf20Sopenharmony_ci			  "Can not find core (id: 0x%x, unit %i) for IRQ configuration.\n",
1608c2ecf20Sopenharmony_ci			  coreid, unit);
1618c2ecf20Sopenharmony_ci		return;
1628c2ecf20Sopenharmony_ci	}
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ci	bcma_core_mips_set_irq(core, irq);
1658c2ecf20Sopenharmony_ci}
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_cistatic void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq)
1688c2ecf20Sopenharmony_ci{
1698c2ecf20Sopenharmony_ci	int i;
1708c2ecf20Sopenharmony_ci	static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
1718c2ecf20Sopenharmony_ci	char interrupts[25];
1728c2ecf20Sopenharmony_ci	char *ints = interrupts;
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(irq_name); i++)
1758c2ecf20Sopenharmony_ci		ints += sprintf(ints, " %s%c",
1768c2ecf20Sopenharmony_ci				irq_name[i], i == irq ? '*' : ' ');
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci	bcma_debug(dev->bus, "core 0x%04x, irq:%s\n", dev->id.id, interrupts);
1798c2ecf20Sopenharmony_ci}
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_cistatic void bcma_core_mips_dump_irq(struct bcma_bus *bus)
1828c2ecf20Sopenharmony_ci{
1838c2ecf20Sopenharmony_ci	struct bcma_device *core;
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ci	list_for_each_entry(core, &bus->cores, list) {
1868c2ecf20Sopenharmony_ci		bcma_core_mips_print_irq(core, bcma_core_mips_irq(core));
1878c2ecf20Sopenharmony_ci	}
1888c2ecf20Sopenharmony_ci}
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ciu32 bcma_cpu_clock(struct bcma_drv_mips *mcore)
1918c2ecf20Sopenharmony_ci{
1928c2ecf20Sopenharmony_ci	struct bcma_bus *bus = mcore->core->bus;
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_ci	if (bus->drv_cc.capabilities & BCMA_CC_CAP_PMU)
1958c2ecf20Sopenharmony_ci		return bcma_pmu_get_cpu_clock(&bus->drv_cc);
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_ci	bcma_err(bus, "No PMU available, need this to get the cpu clock\n");
1988c2ecf20Sopenharmony_ci	return 0;
1998c2ecf20Sopenharmony_ci}
2008c2ecf20Sopenharmony_ciEXPORT_SYMBOL(bcma_cpu_clock);
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_cistatic enum bcma_boot_dev bcma_boot_dev(struct bcma_bus *bus)
2038c2ecf20Sopenharmony_ci{
2048c2ecf20Sopenharmony_ci	struct bcma_drv_cc *cc = &bus->drv_cc;
2058c2ecf20Sopenharmony_ci	u8 cc_rev = cc->core->id.rev;
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_ci	if (cc_rev == 42) {
2088c2ecf20Sopenharmony_ci		struct bcma_device *core;
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_ci		core = bcma_find_core(bus, BCMA_CORE_NS_ROM);
2118c2ecf20Sopenharmony_ci		if (core) {
2128c2ecf20Sopenharmony_ci			switch (bcma_aread32(core, BCMA_IOST) &
2138c2ecf20Sopenharmony_ci				BCMA_NS_ROM_IOST_BOOT_DEV_MASK) {
2148c2ecf20Sopenharmony_ci			case BCMA_NS_ROM_IOST_BOOT_DEV_NOR:
2158c2ecf20Sopenharmony_ci				return BCMA_BOOT_DEV_SERIAL;
2168c2ecf20Sopenharmony_ci			case BCMA_NS_ROM_IOST_BOOT_DEV_NAND:
2178c2ecf20Sopenharmony_ci				return BCMA_BOOT_DEV_NAND;
2188c2ecf20Sopenharmony_ci			case BCMA_NS_ROM_IOST_BOOT_DEV_ROM:
2198c2ecf20Sopenharmony_ci			default:
2208c2ecf20Sopenharmony_ci				return BCMA_BOOT_DEV_ROM;
2218c2ecf20Sopenharmony_ci			}
2228c2ecf20Sopenharmony_ci		}
2238c2ecf20Sopenharmony_ci	} else {
2248c2ecf20Sopenharmony_ci		if (cc_rev == 38) {
2258c2ecf20Sopenharmony_ci			if (cc->status & BCMA_CC_CHIPST_5357_NAND_BOOT)
2268c2ecf20Sopenharmony_ci				return BCMA_BOOT_DEV_NAND;
2278c2ecf20Sopenharmony_ci			else if (cc->status & BIT(5))
2288c2ecf20Sopenharmony_ci				return BCMA_BOOT_DEV_ROM;
2298c2ecf20Sopenharmony_ci		}
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ci		if ((cc->capabilities & BCMA_CC_CAP_FLASHT) ==
2328c2ecf20Sopenharmony_ci		    BCMA_CC_FLASHT_PARA)
2338c2ecf20Sopenharmony_ci			return BCMA_BOOT_DEV_PARALLEL;
2348c2ecf20Sopenharmony_ci		else
2358c2ecf20Sopenharmony_ci			return BCMA_BOOT_DEV_SERIAL;
2368c2ecf20Sopenharmony_ci	}
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci	return BCMA_BOOT_DEV_SERIAL;
2398c2ecf20Sopenharmony_ci}
2408c2ecf20Sopenharmony_ci
2418c2ecf20Sopenharmony_cistatic void bcma_core_mips_nvram_init(struct bcma_drv_mips *mcore)
2428c2ecf20Sopenharmony_ci{
2438c2ecf20Sopenharmony_ci	struct bcma_bus *bus = mcore->core->bus;
2448c2ecf20Sopenharmony_ci	enum bcma_boot_dev boot_dev;
2458c2ecf20Sopenharmony_ci
2468c2ecf20Sopenharmony_ci	/* Determine flash type this SoC boots from */
2478c2ecf20Sopenharmony_ci	boot_dev = bcma_boot_dev(bus);
2488c2ecf20Sopenharmony_ci	switch (boot_dev) {
2498c2ecf20Sopenharmony_ci	case BCMA_BOOT_DEV_PARALLEL:
2508c2ecf20Sopenharmony_ci	case BCMA_BOOT_DEV_SERIAL:
2518c2ecf20Sopenharmony_ci#ifdef CONFIG_BCM47XX
2528c2ecf20Sopenharmony_ci		bcm47xx_nvram_init_from_mem(BCMA_SOC_FLASH2,
2538c2ecf20Sopenharmony_ci					    BCMA_SOC_FLASH2_SZ);
2548c2ecf20Sopenharmony_ci#endif
2558c2ecf20Sopenharmony_ci		break;
2568c2ecf20Sopenharmony_ci	case BCMA_BOOT_DEV_NAND:
2578c2ecf20Sopenharmony_ci#ifdef CONFIG_BCM47XX
2588c2ecf20Sopenharmony_ci		bcm47xx_nvram_init_from_mem(BCMA_SOC_FLASH1,
2598c2ecf20Sopenharmony_ci					    BCMA_SOC_FLASH1_SZ);
2608c2ecf20Sopenharmony_ci#endif
2618c2ecf20Sopenharmony_ci		break;
2628c2ecf20Sopenharmony_ci	default:
2638c2ecf20Sopenharmony_ci		break;
2648c2ecf20Sopenharmony_ci	}
2658c2ecf20Sopenharmony_ci}
2668c2ecf20Sopenharmony_ci
2678c2ecf20Sopenharmony_civoid bcma_core_mips_early_init(struct bcma_drv_mips *mcore)
2688c2ecf20Sopenharmony_ci{
2698c2ecf20Sopenharmony_ci	struct bcma_bus *bus = mcore->core->bus;
2708c2ecf20Sopenharmony_ci
2718c2ecf20Sopenharmony_ci	if (mcore->early_setup_done)
2728c2ecf20Sopenharmony_ci		return;
2738c2ecf20Sopenharmony_ci
2748c2ecf20Sopenharmony_ci	bcma_chipco_serial_init(&bus->drv_cc);
2758c2ecf20Sopenharmony_ci	bcma_core_mips_nvram_init(mcore);
2768c2ecf20Sopenharmony_ci
2778c2ecf20Sopenharmony_ci	mcore->early_setup_done = true;
2788c2ecf20Sopenharmony_ci}
2798c2ecf20Sopenharmony_ci
2808c2ecf20Sopenharmony_cistatic void bcma_fix_i2s_irqflag(struct bcma_bus *bus)
2818c2ecf20Sopenharmony_ci{
2828c2ecf20Sopenharmony_ci	struct bcma_device *cpu, *pcie, *i2s;
2838c2ecf20Sopenharmony_ci
2848c2ecf20Sopenharmony_ci	/* Fixup the interrupts in 4716/4748 for i2s core (2010 Broadcom SDK)
2858c2ecf20Sopenharmony_ci	 * (IRQ flags > 7 are ignored when setting the interrupt masks)
2868c2ecf20Sopenharmony_ci	 */
2878c2ecf20Sopenharmony_ci	if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4716 &&
2888c2ecf20Sopenharmony_ci	    bus->chipinfo.id != BCMA_CHIP_ID_BCM4748)
2898c2ecf20Sopenharmony_ci		return;
2908c2ecf20Sopenharmony_ci
2918c2ecf20Sopenharmony_ci	cpu = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
2928c2ecf20Sopenharmony_ci	pcie = bcma_find_core(bus, BCMA_CORE_PCIE);
2938c2ecf20Sopenharmony_ci	i2s = bcma_find_core(bus, BCMA_CORE_I2S);
2948c2ecf20Sopenharmony_ci	if (cpu && pcie && i2s &&
2958c2ecf20Sopenharmony_ci	    bcma_aread32(cpu, BCMA_MIPS_OOBSELINA74) == 0x08060504 &&
2968c2ecf20Sopenharmony_ci	    bcma_aread32(pcie, BCMA_MIPS_OOBSELINA74) == 0x08060504 &&
2978c2ecf20Sopenharmony_ci	    bcma_aread32(i2s, BCMA_MIPS_OOBSELOUTA30) == 0x88) {
2988c2ecf20Sopenharmony_ci		bcma_awrite32(cpu, BCMA_MIPS_OOBSELINA74, 0x07060504);
2998c2ecf20Sopenharmony_ci		bcma_awrite32(pcie, BCMA_MIPS_OOBSELINA74, 0x07060504);
3008c2ecf20Sopenharmony_ci		bcma_awrite32(i2s, BCMA_MIPS_OOBSELOUTA30, 0x87);
3018c2ecf20Sopenharmony_ci		bcma_debug(bus,
3028c2ecf20Sopenharmony_ci			   "Moved i2s interrupt to oob line 7 instead of 8\n");
3038c2ecf20Sopenharmony_ci	}
3048c2ecf20Sopenharmony_ci}
3058c2ecf20Sopenharmony_ci
3068c2ecf20Sopenharmony_civoid bcma_core_mips_init(struct bcma_drv_mips *mcore)
3078c2ecf20Sopenharmony_ci{
3088c2ecf20Sopenharmony_ci	struct bcma_bus *bus;
3098c2ecf20Sopenharmony_ci	struct bcma_device *core;
3108c2ecf20Sopenharmony_ci	bus = mcore->core->bus;
3118c2ecf20Sopenharmony_ci
3128c2ecf20Sopenharmony_ci	if (mcore->setup_done)
3138c2ecf20Sopenharmony_ci		return;
3148c2ecf20Sopenharmony_ci
3158c2ecf20Sopenharmony_ci	bcma_debug(bus, "Initializing MIPS core...\n");
3168c2ecf20Sopenharmony_ci
3178c2ecf20Sopenharmony_ci	bcma_core_mips_early_init(mcore);
3188c2ecf20Sopenharmony_ci
3198c2ecf20Sopenharmony_ci	bcma_fix_i2s_irqflag(bus);
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_ci	switch (bus->chipinfo.id) {
3228c2ecf20Sopenharmony_ci	case BCMA_CHIP_ID_BCM4716:
3238c2ecf20Sopenharmony_ci	case BCMA_CHIP_ID_BCM4748:
3248c2ecf20Sopenharmony_ci		bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0);
3258c2ecf20Sopenharmony_ci		bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0);
3268c2ecf20Sopenharmony_ci		bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_USB20_HOST, 0);
3278c2ecf20Sopenharmony_ci		bcma_core_mips_set_irq_name(bus, 4, BCMA_CORE_PCIE, 0);
3288c2ecf20Sopenharmony_ci		bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0);
3298c2ecf20Sopenharmony_ci		bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_I2S, 0);
3308c2ecf20Sopenharmony_ci		break;
3318c2ecf20Sopenharmony_ci	case BCMA_CHIP_ID_BCM5356:
3328c2ecf20Sopenharmony_ci	case BCMA_CHIP_ID_BCM47162:
3338c2ecf20Sopenharmony_ci	case BCMA_CHIP_ID_BCM53572:
3348c2ecf20Sopenharmony_ci		bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0);
3358c2ecf20Sopenharmony_ci		bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0);
3368c2ecf20Sopenharmony_ci		bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0);
3378c2ecf20Sopenharmony_ci		break;
3388c2ecf20Sopenharmony_ci	case BCMA_CHIP_ID_BCM5357:
3398c2ecf20Sopenharmony_ci	case BCMA_CHIP_ID_BCM4749:
3408c2ecf20Sopenharmony_ci		bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0);
3418c2ecf20Sopenharmony_ci		bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0);
3428c2ecf20Sopenharmony_ci		bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_USB20_HOST, 0);
3438c2ecf20Sopenharmony_ci		bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0);
3448c2ecf20Sopenharmony_ci		bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_I2S, 0);
3458c2ecf20Sopenharmony_ci		break;
3468c2ecf20Sopenharmony_ci	case BCMA_CHIP_ID_BCM4706:
3478c2ecf20Sopenharmony_ci		bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_PCIE, 0);
3488c2ecf20Sopenharmony_ci		bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_4706_MAC_GBIT,
3498c2ecf20Sopenharmony_ci					    0);
3508c2ecf20Sopenharmony_ci		bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_PCIE, 1);
3518c2ecf20Sopenharmony_ci		bcma_core_mips_set_irq_name(bus, 4, BCMA_CORE_USB20_HOST, 0);
3528c2ecf20Sopenharmony_ci		bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_4706_CHIPCOMMON,
3538c2ecf20Sopenharmony_ci					    0);
3548c2ecf20Sopenharmony_ci		break;
3558c2ecf20Sopenharmony_ci	default:
3568c2ecf20Sopenharmony_ci		list_for_each_entry(core, &bus->cores, list) {
3578c2ecf20Sopenharmony_ci			core->irq = bcma_core_irq(core, 0);
3588c2ecf20Sopenharmony_ci		}
3598c2ecf20Sopenharmony_ci		bcma_err(bus,
3608c2ecf20Sopenharmony_ci			 "Unknown device (0x%x) found, can not configure IRQs\n",
3618c2ecf20Sopenharmony_ci			 bus->chipinfo.id);
3628c2ecf20Sopenharmony_ci	}
3638c2ecf20Sopenharmony_ci	bcma_debug(bus, "IRQ reconfiguration done\n");
3648c2ecf20Sopenharmony_ci	bcma_core_mips_dump_irq(bus);
3658c2ecf20Sopenharmony_ci
3668c2ecf20Sopenharmony_ci	mcore->setup_done = true;
3678c2ecf20Sopenharmony_ci}
368