summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--target/linux/brcm47xx-2.6/files/drivers/ssb/core.c2
-rw-r--r--target/linux/brcm47xx-2.6/files/drivers/ssb/driver_chipcommon/chipcommon.c29
-rw-r--r--target/linux/brcm47xx-2.6/files/drivers/ssb/driver_mips/mips.c11
-rw-r--r--target/linux/brcm47xx-2.6/files/drivers/ssb/driver_pci/pcicore.c3
-rw-r--r--target/linux/brcm47xx-2.6/files/include/linux/ssb/ssb_driver_chipcommon.h2
5 files changed, 40 insertions, 7 deletions
diff --git a/target/linux/brcm47xx-2.6/files/drivers/ssb/core.c b/target/linux/brcm47xx-2.6/files/drivers/ssb/core.c
index a3fbaca9d..2ee13d2d3 100644
--- a/target/linux/brcm47xx-2.6/files/drivers/ssb/core.c
+++ b/target/linux/brcm47xx-2.6/files/drivers/ssb/core.c
@@ -235,6 +235,7 @@ static int ssb_attach_queued_buses(void)
int i, err;
list_for_each_entry_safe(bus, n, &attach_queue, list) {
+ ssb_pcicore_init(&bus->pcicore);
for (i = 0; i < bus->nr_devices; i++) {
dev = &(bus->devices[i]);
@@ -350,7 +351,6 @@ static int ssb_bus_register(struct ssb_bus *bus,
/* Initialize basic system devices (if available) */
ssb_chipcommon_init(&bus->chipco);
ssb_mipscore_init(&bus->mipscore);
- ssb_pcicore_init(&bus->pcicore);
/* Queue it for attach */
list_add_tail(&bus->list, &attach_queue);
diff --git a/target/linux/brcm47xx-2.6/files/drivers/ssb/driver_chipcommon/chipcommon.c b/target/linux/brcm47xx-2.6/files/drivers/ssb/driver_chipcommon/chipcommon.c
index 6d3412b58..a17910947 100644
--- a/target/linux/brcm47xx-2.6/files/drivers/ssb/driver_chipcommon/chipcommon.c
+++ b/target/linux/brcm47xx-2.6/files/drivers/ssb/driver_chipcommon/chipcommon.c
@@ -266,6 +266,35 @@ void ssb_chipco_resume(struct ssb_chipcommon *cc)
chipco_powercontrol_init(cc);
}
+void ssb_chipco_get_clockcpu(struct ssb_chipcommon *cc, u32 chip_id, u32 *rate,
+ u32 *plltype, u32 *n, u32 *m)
+{
+ *rate = 0;
+ *n = chipco_read32(cc, SSB_CHIPCO_CLOCK_N);
+ *plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT);
+ switch (*plltype) {
+ case SSB_PLLTYPE_2:
+ case SSB_PLLTYPE_4:
+ case SSB_PLLTYPE_6:
+ case SSB_PLLTYPE_7:
+ *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_MIPS);
+ break;
+ case SSB_PLLTYPE_5:
+ *rate = 200000000;
+ break;
+ case SSB_PLLTYPE_3:
+ /* 5350 uses m2 to control mips */
+ *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_M2);
+ break;
+ default:
+ *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_SB);
+ break;
+ }
+
+ if (*rate == 0 && chip_id == 0x5365)
+ *rate = 200000000;
+}
+
void ssb_chipco_get_clockcontrol(struct ssb_chipcommon *cc,
u32 *plltype, u32 *n, u32 *m)
{
diff --git a/target/linux/brcm47xx-2.6/files/drivers/ssb/driver_mips/mips.c b/target/linux/brcm47xx-2.6/files/drivers/ssb/driver_mips/mips.c
index 65916b17b..7b3880ab0 100644
--- a/target/linux/brcm47xx-2.6/files/drivers/ssb/driver_mips/mips.c
+++ b/target/linux/brcm47xx-2.6/files/drivers/ssb/driver_mips/mips.c
@@ -215,15 +215,14 @@ u32 ssb_cpu_clock(struct ssb_mipscore *mcore)
if (bus->extif.dev) {
ssb_extif_get_clockcontrol(&bus->extif, &pll_type, &n, &m);
} else if (bus->chipco.dev) {
- if (bus->chip_id == 0x5365)
- /* FIXME: is this override really necessary? */
- return 200000000;
-
- ssb_chipco_get_clockcontrol(&bus->chipco, &pll_type, &n, &m);
+ ssb_chipco_get_clockcpu(&bus->chipco, bus->chip_id, &rate,
+ &pll_type, &n, &m);
} else
return 0;
- rate = ssb_calc_clock_rate(pll_type, n, m);
+ if (rate == 0)
+ rate = ssb_calc_clock_rate(pll_type, n, m);
+
if (pll_type == SSB_PLLTYPE_6)
rate *= 2;
diff --git a/target/linux/brcm47xx-2.6/files/drivers/ssb/driver_pci/pcicore.c b/target/linux/brcm47xx-2.6/files/drivers/ssb/driver_pci/pcicore.c
index 9800ce66e..e02583495 100644
--- a/target/linux/brcm47xx-2.6/files/drivers/ssb/driver_pci/pcicore.c
+++ b/target/linux/brcm47xx-2.6/files/drivers/ssb/driver_pci/pcicore.c
@@ -303,6 +303,8 @@ static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc)
udelay(150);
val |= SSB_PCICORE_CTL_RST; /* Deassert RST# */
pcicore_write32(pc, SSB_PCICORE_CTL, val);
+ val = SSB_PCICORE_ARBCTL_INTERN;
+ pcicore_write32(pc, SSB_PCICORE_ARBCTL, val);
udelay(1);
//TODO cardbus mode
@@ -329,6 +331,7 @@ static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc)
* The following needs change, if we want to port hostmode
* to non-MIPS platform. */
set_io_port_base((unsigned long)ioremap_nocache(SSB_PCI_MEM, 0x04000000));
+ mdelay(300);
register_pci_controller(&ssb_pcicore_controller);
}
diff --git a/target/linux/brcm47xx-2.6/files/include/linux/ssb/ssb_driver_chipcommon.h b/target/linux/brcm47xx-2.6/files/include/linux/ssb/ssb_driver_chipcommon.h
index ba0b8702c..e0c0e61b8 100644
--- a/target/linux/brcm47xx-2.6/files/include/linux/ssb/ssb_driver_chipcommon.h
+++ b/target/linux/brcm47xx-2.6/files/include/linux/ssb/ssb_driver_chipcommon.h
@@ -364,6 +364,8 @@ extern void ssb_chipcommon_init(struct ssb_chipcommon *cc);
extern void ssb_chipco_suspend(struct ssb_chipcommon *cc, pm_message_t state);
extern void ssb_chipco_resume(struct ssb_chipcommon *cc);
+extern void ssb_chipco_get_clockcpu(struct ssb_chipcommon *cc, u32 chip_id,
+ u32 *rate, u32 *plltype, u32 *n, u32 *m);
extern void ssb_chipco_get_clockcontrol(struct ssb_chipcommon *cc,
u32 *plltype, u32 *n, u32 *m);
extern void ssb_chipco_timing_init(struct ssb_chipcommon *cc,