Linux Audio

Check our new training course

Loading...
v6.8
  1/*
  2 * Broadcom specific AMBA
  3 * Broadcom MIPS32 74K core driver
  4 *
  5 * Copyright 2009, Broadcom Corporation
  6 * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
  7 * Copyright 2010, Bernhard Loos <bernhardloos@googlemail.com>
  8 * Copyright 2011, Hauke Mehrtens <hauke@hauke-m.de>
  9 *
 10 * Licensed under the GNU/GPL. See COPYING for details.
 11 */
 12
 13#include "bcma_private.h"
 14
 15#include <linux/bcma/bcma.h>
 16
 17#include <linux/serial.h>
 18#include <linux/serial_core.h>
 19#include <linux/serial_reg.h>
 20#include <linux/time.h>
 21#ifdef CONFIG_BCM47XX
 22#include <linux/bcm47xx_nvram.h>
 23#endif
 24
 25enum bcma_boot_dev {
 26	BCMA_BOOT_DEV_UNK = 0,
 27	BCMA_BOOT_DEV_ROM,
 28	BCMA_BOOT_DEV_PARALLEL,
 29	BCMA_BOOT_DEV_SERIAL,
 30	BCMA_BOOT_DEV_NAND,
 31};
 32
 33/* The 47162a0 hangs when reading MIPS DMP registers */
 34static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev)
 35{
 36	return dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM47162 &&
 37	       dev->bus->chipinfo.rev == 0 && dev->id.id == BCMA_CORE_MIPS_74K;
 38}
 39
 40/* The 5357b0 hangs when reading USB20H DMP registers */
 41static inline bool bcma_core_mips_bcm5357b0_quirk(struct bcma_device *dev)
 42{
 43	return (dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM5357 ||
 44		dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM4749) &&
 45	       dev->bus->chipinfo.pkg == 11 &&
 46	       dev->id.id == BCMA_CORE_USB20_HOST;
 47}
 48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 49static u32 bcma_core_mips_irqflag(struct bcma_device *dev)
 50{
 51	u32 flag;
 52
 53	if (bcma_core_mips_bcm47162a0_quirk(dev))
 54		return dev->core_index;
 55	if (bcma_core_mips_bcm5357b0_quirk(dev))
 56		return dev->core_index;
 57	flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30);
 58
 59	if (flag)
 60		return flag & 0x1F;
 61	else
 62		return 0x3f;
 63}
 64
 65/* Get the MIPS IRQ assignment for a specified device.
 66 * If unassigned, 0 is returned.
 67 * If disabled, 5 is returned.
 68 * If not supported, 6 is returned.
 69 */
 70unsigned int bcma_core_mips_irq(struct bcma_device *dev)
 71{
 72	struct bcma_device *mdev = dev->bus->drv_mips.core;
 73	u32 irqflag;
 74	unsigned int irq;
 75
 76	irqflag = bcma_core_mips_irqflag(dev);
 77	if (irqflag == 0x3f)
 78		return 6;
 79
 80	for (irq = 0; irq <= 4; irq++)
 81		if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) &
 82		    (1 << irqflag))
 83			return irq;
 84
 85	return 5;
 86}
 87
 88static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
 89{
 90	unsigned int oldirq = bcma_core_mips_irq(dev);
 91	struct bcma_bus *bus = dev->bus;
 92	struct bcma_device *mdev = bus->drv_mips.core;
 93	u32 irqflag;
 94
 95	irqflag = bcma_core_mips_irqflag(dev);
 96	BUG_ON(oldirq == 6);
 97
 98	dev->irq = irq + 2;
 99
100	/* clear the old irq */
101	if (oldirq == 0)
102		bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
103			    bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) &
104			    ~(1 << irqflag));
105	else if (oldirq != 5)
106		bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(oldirq), 0);
107
108	/* assign the new one */
109	if (irq == 0) {
110		bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
111			    bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) |
112			    (1 << irqflag));
113	} else {
114		u32 irqinitmask = bcma_read32(mdev,
115					      BCMA_MIPS_MIPS74K_INTMASK(irq));
116		if (irqinitmask) {
117			struct bcma_device *core;
118
119			/* backplane irq line is in use, find out who uses
120			 * it and set user to irq 0
121			 */
122			list_for_each_entry(core, &bus->cores, list) {
123				if ((1 << bcma_core_mips_irqflag(core)) ==
124				    irqinitmask) {
125					bcma_core_mips_set_irq(core, 0);
126					break;
127				}
128			}
129		}
130		bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq),
131			     1 << irqflag);
132	}
133
134	bcma_debug(bus, "set_irq: core 0x%04x, irq %d => %d\n",
135		   dev->id.id, oldirq <= 4 ? oldirq + 2 : 0, irq + 2);
136}
137
138static void bcma_core_mips_set_irq_name(struct bcma_bus *bus, unsigned int irq,
139					u16 coreid, u8 unit)
140{
141	struct bcma_device *core;
142
143	core = bcma_find_core_unit(bus, coreid, unit);
144	if (!core) {
145		bcma_warn(bus,
146			  "Can not find core (id: 0x%x, unit %i) for IRQ configuration.\n",
147			  coreid, unit);
148		return;
149	}
150
151	bcma_core_mips_set_irq(core, irq);
152}
153
154static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq)
155{
156	int i;
157	static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
158	char interrupts[25];
159	char *ints = interrupts;
160
161	for (i = 0; i < ARRAY_SIZE(irq_name); i++)
162		ints += sprintf(ints, " %s%c",
163				irq_name[i], i == irq ? '*' : ' ');
164
165	bcma_debug(dev->bus, "core 0x%04x, irq:%s\n", dev->id.id, interrupts);
166}
167
168static void bcma_core_mips_dump_irq(struct bcma_bus *bus)
169{
170	struct bcma_device *core;
171
172	list_for_each_entry(core, &bus->cores, list) {
173		bcma_core_mips_print_irq(core, bcma_core_mips_irq(core));
174	}
175}
176
177u32 bcma_cpu_clock(struct bcma_drv_mips *mcore)
178{
179	struct bcma_bus *bus = mcore->core->bus;
180
181	if (bus->drv_cc.capabilities & BCMA_CC_CAP_PMU)
182		return bcma_pmu_get_cpu_clock(&bus->drv_cc);
183
184	bcma_err(bus, "No PMU available, need this to get the cpu clock\n");
185	return 0;
186}
187EXPORT_SYMBOL(bcma_cpu_clock);
188
189static enum bcma_boot_dev bcma_boot_dev(struct bcma_bus *bus)
190{
191	struct bcma_drv_cc *cc = &bus->drv_cc;
192	u8 cc_rev = cc->core->id.rev;
193
194	if (cc_rev == 42) {
195		struct bcma_device *core;
196
197		core = bcma_find_core(bus, BCMA_CORE_NS_ROM);
198		if (core) {
199			switch (bcma_aread32(core, BCMA_IOST) &
200				BCMA_NS_ROM_IOST_BOOT_DEV_MASK) {
201			case BCMA_NS_ROM_IOST_BOOT_DEV_NOR:
202				return BCMA_BOOT_DEV_SERIAL;
203			case BCMA_NS_ROM_IOST_BOOT_DEV_NAND:
204				return BCMA_BOOT_DEV_NAND;
205			case BCMA_NS_ROM_IOST_BOOT_DEV_ROM:
206			default:
207				return BCMA_BOOT_DEV_ROM;
208			}
209		}
210	} else {
211		if (cc_rev == 38) {
212			if (cc->status & BCMA_CC_CHIPST_5357_NAND_BOOT)
213				return BCMA_BOOT_DEV_NAND;
214			else if (cc->status & BIT(5))
215				return BCMA_BOOT_DEV_ROM;
216		}
217
218		if ((cc->capabilities & BCMA_CC_CAP_FLASHT) ==
219		    BCMA_CC_FLASHT_PARA)
220			return BCMA_BOOT_DEV_PARALLEL;
221		else
222			return BCMA_BOOT_DEV_SERIAL;
223	}
224
225	return BCMA_BOOT_DEV_SERIAL;
226}
227
228static void bcma_core_mips_nvram_init(struct bcma_drv_mips *mcore)
229{
230	struct bcma_bus *bus = mcore->core->bus;
231	enum bcma_boot_dev boot_dev;
232
233	/* Determine flash type this SoC boots from */
234	boot_dev = bcma_boot_dev(bus);
235	switch (boot_dev) {
236	case BCMA_BOOT_DEV_PARALLEL:
237	case BCMA_BOOT_DEV_SERIAL:
238#ifdef CONFIG_BCM47XX
239		bcm47xx_nvram_init_from_mem(BCMA_SOC_FLASH2,
240					    BCMA_SOC_FLASH2_SZ);
241#endif
242		break;
243	case BCMA_BOOT_DEV_NAND:
244#ifdef CONFIG_BCM47XX
245		bcm47xx_nvram_init_from_mem(BCMA_SOC_FLASH1,
246					    BCMA_SOC_FLASH1_SZ);
247#endif
248		break;
249	default:
250		break;
251	}
252}
253
254void bcma_core_mips_early_init(struct bcma_drv_mips *mcore)
255{
256	struct bcma_bus *bus = mcore->core->bus;
257
258	if (mcore->early_setup_done)
259		return;
260
261	bcma_chipco_serial_init(&bus->drv_cc);
262	bcma_core_mips_nvram_init(mcore);
263
264	mcore->early_setup_done = true;
265}
266
267static void bcma_fix_i2s_irqflag(struct bcma_bus *bus)
268{
269	struct bcma_device *cpu, *pcie, *i2s;
270
271	/* Fixup the interrupts in 4716/4748 for i2s core (2010 Broadcom SDK)
272	 * (IRQ flags > 7 are ignored when setting the interrupt masks)
273	 */
274	if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4716 &&
275	    bus->chipinfo.id != BCMA_CHIP_ID_BCM4748)
276		return;
277
278	cpu = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
279	pcie = bcma_find_core(bus, BCMA_CORE_PCIE);
280	i2s = bcma_find_core(bus, BCMA_CORE_I2S);
281	if (cpu && pcie && i2s &&
282	    bcma_aread32(cpu, BCMA_MIPS_OOBSELINA74) == 0x08060504 &&
283	    bcma_aread32(pcie, BCMA_MIPS_OOBSELINA74) == 0x08060504 &&
284	    bcma_aread32(i2s, BCMA_MIPS_OOBSELOUTA30) == 0x88) {
285		bcma_awrite32(cpu, BCMA_MIPS_OOBSELINA74, 0x07060504);
286		bcma_awrite32(pcie, BCMA_MIPS_OOBSELINA74, 0x07060504);
287		bcma_awrite32(i2s, BCMA_MIPS_OOBSELOUTA30, 0x87);
288		bcma_debug(bus,
289			   "Moved i2s interrupt to oob line 7 instead of 8\n");
290	}
291}
292
293void bcma_core_mips_init(struct bcma_drv_mips *mcore)
294{
295	struct bcma_bus *bus;
296	struct bcma_device *core;
297	bus = mcore->core->bus;
298
299	if (mcore->setup_done)
300		return;
301
302	bcma_debug(bus, "Initializing MIPS core...\n");
303
304	bcma_core_mips_early_init(mcore);
305
306	bcma_fix_i2s_irqflag(bus);
307
308	switch (bus->chipinfo.id) {
309	case BCMA_CHIP_ID_BCM4716:
310	case BCMA_CHIP_ID_BCM4748:
311		bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0);
312		bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0);
313		bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_USB20_HOST, 0);
314		bcma_core_mips_set_irq_name(bus, 4, BCMA_CORE_PCIE, 0);
315		bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0);
316		bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_I2S, 0);
317		break;
318	case BCMA_CHIP_ID_BCM5356:
319	case BCMA_CHIP_ID_BCM47162:
320	case BCMA_CHIP_ID_BCM53572:
321		bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0);
322		bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0);
323		bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0);
324		break;
325	case BCMA_CHIP_ID_BCM5357:
326	case BCMA_CHIP_ID_BCM4749:
327		bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0);
328		bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0);
329		bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_USB20_HOST, 0);
330		bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0);
331		bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_I2S, 0);
332		break;
333	case BCMA_CHIP_ID_BCM4706:
334		bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_PCIE, 0);
335		bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_4706_MAC_GBIT,
336					    0);
337		bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_PCIE, 1);
338		bcma_core_mips_set_irq_name(bus, 4, BCMA_CORE_USB20_HOST, 0);
339		bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_4706_CHIPCOMMON,
340					    0);
341		break;
342	default:
343		list_for_each_entry(core, &bus->cores, list) {
344			core->irq = bcma_core_irq(core, 0);
345		}
346		bcma_err(bus,
347			 "Unknown device (0x%x) found, can not configure IRQs\n",
348			 bus->chipinfo.id);
349	}
350	bcma_debug(bus, "IRQ reconfiguration done\n");
351	bcma_core_mips_dump_irq(bus);
352
353	mcore->setup_done = true;
354}
v4.6
  1/*
  2 * Broadcom specific AMBA
  3 * Broadcom MIPS32 74K core driver
  4 *
  5 * Copyright 2009, Broadcom Corporation
  6 * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
  7 * Copyright 2010, Bernhard Loos <bernhardloos@googlemail.com>
  8 * Copyright 2011, Hauke Mehrtens <hauke@hauke-m.de>
  9 *
 10 * Licensed under the GNU/GPL. See COPYING for details.
 11 */
 12
 13#include "bcma_private.h"
 14
 15#include <linux/bcma/bcma.h>
 16
 17#include <linux/serial.h>
 18#include <linux/serial_core.h>
 19#include <linux/serial_reg.h>
 20#include <linux/time.h>
 21#ifdef CONFIG_BCM47XX
 22#include <linux/bcm47xx_nvram.h>
 23#endif
 24
 25enum bcma_boot_dev {
 26	BCMA_BOOT_DEV_UNK = 0,
 27	BCMA_BOOT_DEV_ROM,
 28	BCMA_BOOT_DEV_PARALLEL,
 29	BCMA_BOOT_DEV_SERIAL,
 30	BCMA_BOOT_DEV_NAND,
 31};
 32
 33/* The 47162a0 hangs when reading MIPS DMP registers registers */
 34static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev)
 35{
 36	return dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM47162 &&
 37	       dev->bus->chipinfo.rev == 0 && dev->id.id == BCMA_CORE_MIPS_74K;
 38}
 39
 40/* The 5357b0 hangs when reading USB20H DMP registers */
 41static inline bool bcma_core_mips_bcm5357b0_quirk(struct bcma_device *dev)
 42{
 43	return (dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM5357 ||
 44		dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM4749) &&
 45	       dev->bus->chipinfo.pkg == 11 &&
 46	       dev->id.id == BCMA_CORE_USB20_HOST;
 47}
 48
 49static inline u32 mips_read32(struct bcma_drv_mips *mcore,
 50			      u16 offset)
 51{
 52	return bcma_read32(mcore->core, offset);
 53}
 54
 55static inline void mips_write32(struct bcma_drv_mips *mcore,
 56				u16 offset,
 57				u32 value)
 58{
 59	bcma_write32(mcore->core, offset, value);
 60}
 61
 62static const u32 ipsflag_irq_mask[] = {
 63	0,
 64	BCMA_MIPS_IPSFLAG_IRQ1,
 65	BCMA_MIPS_IPSFLAG_IRQ2,
 66	BCMA_MIPS_IPSFLAG_IRQ3,
 67	BCMA_MIPS_IPSFLAG_IRQ4,
 68};
 69
 70static const u32 ipsflag_irq_shift[] = {
 71	0,
 72	BCMA_MIPS_IPSFLAG_IRQ1_SHIFT,
 73	BCMA_MIPS_IPSFLAG_IRQ2_SHIFT,
 74	BCMA_MIPS_IPSFLAG_IRQ3_SHIFT,
 75	BCMA_MIPS_IPSFLAG_IRQ4_SHIFT,
 76};
 77
 78static u32 bcma_core_mips_irqflag(struct bcma_device *dev)
 79{
 80	u32 flag;
 81
 82	if (bcma_core_mips_bcm47162a0_quirk(dev))
 83		return dev->core_index;
 84	if (bcma_core_mips_bcm5357b0_quirk(dev))
 85		return dev->core_index;
 86	flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30);
 87
 88	if (flag)
 89		return flag & 0x1F;
 90	else
 91		return 0x3f;
 92}
 93
 94/* Get the MIPS IRQ assignment for a specified device.
 95 * If unassigned, 0 is returned.
 96 * If disabled, 5 is returned.
 97 * If not supported, 6 is returned.
 98 */
 99unsigned int bcma_core_mips_irq(struct bcma_device *dev)
100{
101	struct bcma_device *mdev = dev->bus->drv_mips.core;
102	u32 irqflag;
103	unsigned int irq;
104
105	irqflag = bcma_core_mips_irqflag(dev);
106	if (irqflag == 0x3f)
107		return 6;
108
109	for (irq = 0; irq <= 4; irq++)
110		if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) &
111		    (1 << irqflag))
112			return irq;
113
114	return 5;
115}
116
117static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
118{
119	unsigned int oldirq = bcma_core_mips_irq(dev);
120	struct bcma_bus *bus = dev->bus;
121	struct bcma_device *mdev = bus->drv_mips.core;
122	u32 irqflag;
123
124	irqflag = bcma_core_mips_irqflag(dev);
125	BUG_ON(oldirq == 6);
126
127	dev->irq = irq + 2;
128
129	/* clear the old irq */
130	if (oldirq == 0)
131		bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
132			    bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) &
133			    ~(1 << irqflag));
134	else if (oldirq != 5)
135		bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(oldirq), 0);
136
137	/* assign the new one */
138	if (irq == 0) {
139		bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
140			    bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) |
141			    (1 << irqflag));
142	} else {
143		u32 irqinitmask = bcma_read32(mdev,
144					      BCMA_MIPS_MIPS74K_INTMASK(irq));
145		if (irqinitmask) {
146			struct bcma_device *core;
147
148			/* backplane irq line is in use, find out who uses
149			 * it and set user to irq 0
150			 */
151			list_for_each_entry(core, &bus->cores, list) {
152				if ((1 << bcma_core_mips_irqflag(core)) ==
153				    irqinitmask) {
154					bcma_core_mips_set_irq(core, 0);
155					break;
156				}
157			}
158		}
159		bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq),
160			     1 << irqflag);
161	}
162
163	bcma_debug(bus, "set_irq: core 0x%04x, irq %d => %d\n",
164		   dev->id.id, oldirq <= 4 ? oldirq + 2 : 0, irq + 2);
165}
166
167static void bcma_core_mips_set_irq_name(struct bcma_bus *bus, unsigned int irq,
168					u16 coreid, u8 unit)
169{
170	struct bcma_device *core;
171
172	core = bcma_find_core_unit(bus, coreid, unit);
173	if (!core) {
174		bcma_warn(bus,
175			  "Can not find core (id: 0x%x, unit %i) for IRQ configuration.\n",
176			  coreid, unit);
177		return;
178	}
179
180	bcma_core_mips_set_irq(core, irq);
181}
182
183static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq)
184{
185	int i;
186	static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
187	printk(KERN_DEBUG KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id);
188	for (i = 0; i <= 6; i++)
189		printk(" %s%s", irq_name[i], i == irq ? "*" : " ");
190	printk("\n");
 
 
 
 
191}
192
193static void bcma_core_mips_dump_irq(struct bcma_bus *bus)
194{
195	struct bcma_device *core;
196
197	list_for_each_entry(core, &bus->cores, list) {
198		bcma_core_mips_print_irq(core, bcma_core_mips_irq(core));
199	}
200}
201
202u32 bcma_cpu_clock(struct bcma_drv_mips *mcore)
203{
204	struct bcma_bus *bus = mcore->core->bus;
205
206	if (bus->drv_cc.capabilities & BCMA_CC_CAP_PMU)
207		return bcma_pmu_get_cpu_clock(&bus->drv_cc);
208
209	bcma_err(bus, "No PMU available, need this to get the cpu clock\n");
210	return 0;
211}
212EXPORT_SYMBOL(bcma_cpu_clock);
213
214static enum bcma_boot_dev bcma_boot_dev(struct bcma_bus *bus)
215{
216	struct bcma_drv_cc *cc = &bus->drv_cc;
217	u8 cc_rev = cc->core->id.rev;
218
219	if (cc_rev == 42) {
220		struct bcma_device *core;
221
222		core = bcma_find_core(bus, BCMA_CORE_NS_ROM);
223		if (core) {
224			switch (bcma_aread32(core, BCMA_IOST) &
225				BCMA_NS_ROM_IOST_BOOT_DEV_MASK) {
226			case BCMA_NS_ROM_IOST_BOOT_DEV_NOR:
227				return BCMA_BOOT_DEV_SERIAL;
228			case BCMA_NS_ROM_IOST_BOOT_DEV_NAND:
229				return BCMA_BOOT_DEV_NAND;
230			case BCMA_NS_ROM_IOST_BOOT_DEV_ROM:
231			default:
232				return BCMA_BOOT_DEV_ROM;
233			}
234		}
235	} else {
236		if (cc_rev == 38) {
237			if (cc->status & BCMA_CC_CHIPST_5357_NAND_BOOT)
238				return BCMA_BOOT_DEV_NAND;
239			else if (cc->status & BIT(5))
240				return BCMA_BOOT_DEV_ROM;
241		}
242
243		if ((cc->capabilities & BCMA_CC_CAP_FLASHT) ==
244		    BCMA_CC_FLASHT_PARA)
245			return BCMA_BOOT_DEV_PARALLEL;
246		else
247			return BCMA_BOOT_DEV_SERIAL;
248	}
249
250	return BCMA_BOOT_DEV_SERIAL;
251}
252
253static void bcma_core_mips_nvram_init(struct bcma_drv_mips *mcore)
254{
255	struct bcma_bus *bus = mcore->core->bus;
256	enum bcma_boot_dev boot_dev;
257
258	/* Determine flash type this SoC boots from */
259	boot_dev = bcma_boot_dev(bus);
260	switch (boot_dev) {
261	case BCMA_BOOT_DEV_PARALLEL:
262	case BCMA_BOOT_DEV_SERIAL:
263#ifdef CONFIG_BCM47XX
264		bcm47xx_nvram_init_from_mem(BCMA_SOC_FLASH2,
265					    BCMA_SOC_FLASH2_SZ);
266#endif
267		break;
268	case BCMA_BOOT_DEV_NAND:
269#ifdef CONFIG_BCM47XX
270		bcm47xx_nvram_init_from_mem(BCMA_SOC_FLASH1,
271					    BCMA_SOC_FLASH1_SZ);
272#endif
273		break;
274	default:
275		break;
276	}
277}
278
279void bcma_core_mips_early_init(struct bcma_drv_mips *mcore)
280{
 
 
281	if (mcore->early_setup_done)
282		return;
283
 
284	bcma_core_mips_nvram_init(mcore);
285
286	mcore->early_setup_done = true;
287}
288
289static void bcma_fix_i2s_irqflag(struct bcma_bus *bus)
290{
291	struct bcma_device *cpu, *pcie, *i2s;
292
293	/* Fixup the interrupts in 4716/4748 for i2s core (2010 Broadcom SDK)
294	 * (IRQ flags > 7 are ignored when setting the interrupt masks)
295	 */
296	if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4716 &&
297	    bus->chipinfo.id != BCMA_CHIP_ID_BCM4748)
298		return;
299
300	cpu = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
301	pcie = bcma_find_core(bus, BCMA_CORE_PCIE);
302	i2s = bcma_find_core(bus, BCMA_CORE_I2S);
303	if (cpu && pcie && i2s &&
304	    bcma_aread32(cpu, BCMA_MIPS_OOBSELINA74) == 0x08060504 &&
305	    bcma_aread32(pcie, BCMA_MIPS_OOBSELINA74) == 0x08060504 &&
306	    bcma_aread32(i2s, BCMA_MIPS_OOBSELOUTA30) == 0x88) {
307		bcma_awrite32(cpu, BCMA_MIPS_OOBSELINA74, 0x07060504);
308		bcma_awrite32(pcie, BCMA_MIPS_OOBSELINA74, 0x07060504);
309		bcma_awrite32(i2s, BCMA_MIPS_OOBSELOUTA30, 0x87);
310		bcma_debug(bus,
311			   "Moved i2s interrupt to oob line 7 instead of 8\n");
312	}
313}
314
315void bcma_core_mips_init(struct bcma_drv_mips *mcore)
316{
317	struct bcma_bus *bus;
318	struct bcma_device *core;
319	bus = mcore->core->bus;
320
321	if (mcore->setup_done)
322		return;
323
324	bcma_debug(bus, "Initializing MIPS core...\n");
325
326	bcma_core_mips_early_init(mcore);
327
328	bcma_fix_i2s_irqflag(bus);
329
330	switch (bus->chipinfo.id) {
331	case BCMA_CHIP_ID_BCM4716:
332	case BCMA_CHIP_ID_BCM4748:
333		bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0);
334		bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0);
335		bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_USB20_HOST, 0);
336		bcma_core_mips_set_irq_name(bus, 4, BCMA_CORE_PCIE, 0);
337		bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0);
338		bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_I2S, 0);
339		break;
340	case BCMA_CHIP_ID_BCM5356:
341	case BCMA_CHIP_ID_BCM47162:
342	case BCMA_CHIP_ID_BCM53572:
343		bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0);
344		bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0);
345		bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0);
346		break;
347	case BCMA_CHIP_ID_BCM5357:
348	case BCMA_CHIP_ID_BCM4749:
349		bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0);
350		bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0);
351		bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_USB20_HOST, 0);
352		bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0);
353		bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_I2S, 0);
354		break;
355	case BCMA_CHIP_ID_BCM4706:
356		bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_PCIE, 0);
357		bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_4706_MAC_GBIT,
358					    0);
359		bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_PCIE, 1);
360		bcma_core_mips_set_irq_name(bus, 4, BCMA_CORE_USB20_HOST, 0);
361		bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_4706_CHIPCOMMON,
362					    0);
363		break;
364	default:
365		list_for_each_entry(core, &bus->cores, list) {
366			core->irq = bcma_core_irq(core, 0);
367		}
368		bcma_err(bus,
369			 "Unknown device (0x%x) found, can not configure IRQs\n",
370			 bus->chipinfo.id);
371	}
372	bcma_debug(bus, "IRQ reconfiguration done\n");
373	bcma_core_mips_dump_irq(bus);
374
375	mcore->setup_done = true;
376}