2 * Broadcom specific AMBA
3 * Broadcom MIPS32 74K core driver
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>
10 * Licensed under the GNU/GPL. See COPYING for details.
13 #include "bcma_private.h"
15 #include <linux/bcma/bcma.h>
17 #include <linux/serial.h>
18 #include <linux/serial_core.h>
19 #include <linux/serial_reg.h>
20 #include <linux/time.h>
22 /* The 47162a0 hangs when reading MIPS DMP registers registers */
23 static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device
*dev
)
25 return dev
->bus
->chipinfo
.id
== 47162 && dev
->bus
->chipinfo
.rev
== 0 &&
26 dev
->id
.id
== BCMA_CORE_MIPS_74K
;
29 /* The 5357b0 hangs when reading USB20H DMP registers */
30 static inline bool bcma_core_mips_bcm5357b0_quirk(struct bcma_device
*dev
)
32 return (dev
->bus
->chipinfo
.id
== 0x5357 ||
33 dev
->bus
->chipinfo
.id
== 0x4749) &&
34 dev
->bus
->chipinfo
.pkg
== 11 &&
35 dev
->id
.id
== BCMA_CORE_USB20_HOST
;
38 static inline u32
mips_read32(struct bcma_drv_mips
*mcore
,
41 return bcma_read32(mcore
->core
, offset
);
44 static inline void mips_write32(struct bcma_drv_mips
*mcore
,
48 bcma_write32(mcore
->core
, offset
, value
);
51 static const u32 ipsflag_irq_mask
[] = {
53 BCMA_MIPS_IPSFLAG_IRQ1
,
54 BCMA_MIPS_IPSFLAG_IRQ2
,
55 BCMA_MIPS_IPSFLAG_IRQ3
,
56 BCMA_MIPS_IPSFLAG_IRQ4
,
59 static const u32 ipsflag_irq_shift
[] = {
61 BCMA_MIPS_IPSFLAG_IRQ1_SHIFT
,
62 BCMA_MIPS_IPSFLAG_IRQ2_SHIFT
,
63 BCMA_MIPS_IPSFLAG_IRQ3_SHIFT
,
64 BCMA_MIPS_IPSFLAG_IRQ4_SHIFT
,
67 static u32
bcma_core_mips_irqflag(struct bcma_device
*dev
)
71 if (bcma_core_mips_bcm47162a0_quirk(dev
))
72 return dev
->core_index
;
73 if (bcma_core_mips_bcm5357b0_quirk(dev
))
74 return dev
->core_index
;
75 flag
= bcma_aread32(dev
, BCMA_MIPS_OOBSELOUTA30
);
80 /* Get the MIPS IRQ assignment for a specified device.
81 * If unassigned, 0 is returned.
83 unsigned int bcma_core_mips_irq(struct bcma_device
*dev
)
85 struct bcma_device
*mdev
= dev
->bus
->drv_mips
.core
;
89 irqflag
= bcma_core_mips_irqflag(dev
);
91 for (irq
= 1; irq
<= 4; irq
++)
92 if (bcma_read32(mdev
, BCMA_MIPS_MIPS74K_INTMASK(irq
)) &
98 EXPORT_SYMBOL(bcma_core_mips_irq
);
100 static void bcma_core_mips_set_irq(struct bcma_device
*dev
, unsigned int irq
)
102 unsigned int oldirq
= bcma_core_mips_irq(dev
);
103 struct bcma_bus
*bus
= dev
->bus
;
104 struct bcma_device
*mdev
= bus
->drv_mips
.core
;
107 irqflag
= bcma_core_mips_irqflag(dev
);
112 /* clear the old irq */
114 bcma_write32(mdev
, BCMA_MIPS_MIPS74K_INTMASK(0),
115 bcma_read32(mdev
, BCMA_MIPS_MIPS74K_INTMASK(0)) &
118 bcma_write32(mdev
, BCMA_MIPS_MIPS74K_INTMASK(irq
), 0);
120 /* assign the new one */
122 bcma_write32(mdev
, BCMA_MIPS_MIPS74K_INTMASK(0),
123 bcma_read32(mdev
, BCMA_MIPS_MIPS74K_INTMASK(0)) |
126 u32 oldirqflag
= bcma_read32(mdev
,
127 BCMA_MIPS_MIPS74K_INTMASK(irq
));
129 struct bcma_device
*core
;
131 /* backplane irq line is in use, find out who uses
132 * it and set user to irq 0
134 list_for_each_entry_reverse(core
, &bus
->cores
, list
) {
135 if ((1 << bcma_core_mips_irqflag(core
)) ==
137 bcma_core_mips_set_irq(core
, 0);
142 bcma_write32(mdev
, BCMA_MIPS_MIPS74K_INTMASK(irq
),
146 pr_info("set_irq: core 0x%04x, irq %d => %d\n",
147 dev
->id
.id
, oldirq
+ 2, irq
+ 2);
150 static void bcma_core_mips_print_irq(struct bcma_device
*dev
, unsigned int irq
)
153 static const char *irq_name
[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
154 printk(KERN_INFO KBUILD_MODNAME
": core 0x%04x, irq :", dev
->id
.id
);
155 for (i
= 0; i
<= 6; i
++)
156 printk(" %s%s", irq_name
[i
], i
== irq
? "*" : " ");
160 static void bcma_core_mips_dump_irq(struct bcma_bus
*bus
)
162 struct bcma_device
*core
;
164 list_for_each_entry_reverse(core
, &bus
->cores
, list
) {
165 bcma_core_mips_print_irq(core
, bcma_core_mips_irq(core
));
169 u32
bcma_cpu_clock(struct bcma_drv_mips
*mcore
)
171 struct bcma_bus
*bus
= mcore
->core
->bus
;
173 if (bus
->drv_cc
.capabilities
& BCMA_CC_CAP_PMU
)
174 return bcma_pmu_get_clockcpu(&bus
->drv_cc
);
176 pr_err("No PMU available, need this to get the cpu clock\n");
179 EXPORT_SYMBOL(bcma_cpu_clock
);
181 static void bcma_core_mips_flash_detect(struct bcma_drv_mips
*mcore
)
183 struct bcma_bus
*bus
= mcore
->core
->bus
;
185 switch (bus
->drv_cc
.capabilities
& BCMA_CC_CAP_FLASHT
) {
186 case BCMA_CC_FLASHT_STSER
:
187 case BCMA_CC_FLASHT_ATSER
:
188 pr_err("Serial flash not supported.\n");
190 case BCMA_CC_FLASHT_PARA
:
191 pr_info("found parallel flash.\n");
192 bus
->drv_cc
.pflash
.window
= 0x1c000000;
193 bus
->drv_cc
.pflash
.window_size
= 0x02000000;
195 if ((bcma_read32(bus
->drv_cc
.core
, BCMA_CC_FLASH_CFG
) &
196 BCMA_CC_FLASH_CFG_DS
) == 0)
197 bus
->drv_cc
.pflash
.buswidth
= 1;
199 bus
->drv_cc
.pflash
.buswidth
= 2;
202 pr_err("flash not supported.\n");
206 void bcma_core_mips_init(struct bcma_drv_mips
*mcore
)
208 struct bcma_bus
*bus
;
209 struct bcma_device
*core
;
210 bus
= mcore
->core
->bus
;
212 pr_info("Initializing MIPS core...\n");
214 if (!mcore
->setup_done
)
215 mcore
->assigned_irqs
= 1;
217 /* Assign IRQs to all cores on the bus */
218 list_for_each_entry_reverse(core
, &bus
->cores
, list
) {
223 mips_irq
= bcma_core_mips_irq(core
);
227 core
->irq
= mips_irq
+ 2;
230 switch (core
->id
.id
) {
233 case BCMA_CORE_ETHERNET
:
234 case BCMA_CORE_ETHERNET_GBIT
:
235 case BCMA_CORE_MAC_GBIT
:
236 case BCMA_CORE_80211
:
237 case BCMA_CORE_USB20_HOST
:
238 /* These devices get their own IRQ line if available,
239 * the rest goes on IRQ0
241 if (mcore
->assigned_irqs
<= 4)
242 bcma_core_mips_set_irq(core
,
243 mcore
->assigned_irqs
++);
247 pr_info("IRQ reconfiguration done\n");
248 bcma_core_mips_dump_irq(bus
);
250 if (mcore
->setup_done
)
253 bcma_chipco_serial_init(&bus
->drv_cc
);
254 bcma_core_mips_flash_detect(mcore
);
255 mcore
->setup_done
= true;