From 532249b5072aacee71b437b5be6de44840dc6e00 Mon Sep 17 00:00:00 2001 From: nbd Date: Sun, 14 Oct 2007 02:47:36 +0000 Subject: sync ssb with upstream git-svn-id: svn://svn.openwrt.org/openwrt/trunk@9302 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../files/drivers/ssb/driver_mipscore.c | 138 ++++++++------------- 1 file changed, 52 insertions(+), 86 deletions(-) (limited to 'target/linux/generic-2.6/files/drivers/ssb/driver_mipscore.c') diff --git a/target/linux/generic-2.6/files/drivers/ssb/driver_mipscore.c b/target/linux/generic-2.6/files/drivers/ssb/driver_mipscore.c index 67d10178b..3d3dd32bf 100644 --- a/target/linux/generic-2.6/files/drivers/ssb/driver_mipscore.c +++ b/target/linux/generic-2.6/files/drivers/ssb/driver_mipscore.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include "ssb_private.h" @@ -117,51 +117,10 @@ static void set_irq(struct ssb_device *dev, unsigned int irq) ssb_write32(mdev, SSB_IPSFLAG, irqflag); } -/* XXX: leave here or move into separate extif driver? */ -static int ssb_extif_serial_init(struct ssb_device *dev, struct ssb_serial_ports *ports) -{ - -} - - static void ssb_mips_serial_init(struct ssb_mipscore *mcore) { struct ssb_bus *bus = mcore->dev->bus; - //TODO if (EXTIF available -#if 0 - extifregs_t *eir = (extifregs_t *) regs; - sbconfig_t *sb; - - /* Determine external UART register base */ - sb = (sbconfig_t *)((ulong) eir + SBCONFIGOFF); - base = EXTIF_CFGIF_BASE(sb_base(R_REG(&sb->sbadmatch1))); - - /* Determine IRQ */ - irq = sb_irq(sbh); - - /* Disable GPIO interrupt initially */ - W_REG(&eir->gpiointpolarity, 0); - W_REG(&eir->gpiointmask, 0); - - /* Search for external UARTs */ - n = 2; - for (i = 0; i < 2; i++) { - regs = (void *) REG_MAP(base + (i * 8), 8); - if (BCMINIT(serial_exists)(regs)) { - /* Set GPIO 1 to be the external UART IRQ */ - W_REG(&eir->gpiointmask, 2); - if (add) - add(regs, irq, 13500000, 0); - } - } - - /* Add internal UART if enabled */ - if (R_REG(&eir->corecontrol) & CC_UE) - if (add) - add((void *) &eir->uartdata, irq, sb_clock(sbh), 2); - -#endif if (bus->extif.dev) mcore->nr_serial_ports = ssb_extif_serial_init(&bus->extif, mcore->serial_ports); else if (bus->chipco.dev) @@ -174,23 +133,47 @@ static void ssb_mips_flash_detect(struct ssb_mipscore *mcore) { struct ssb_bus *bus = mcore->dev->bus; + mcore->flash_buswidth = 2; if (bus->chipco.dev) { mcore->flash_window = 0x1c000000; - mcore->flash_window_size = 0x800000; + mcore->flash_window_size = 0x02000000; + if ((ssb_read32(bus->chipco.dev, SSB_CHIPCO_FLASH_CFG) + & SSB_CHIPCO_CFG_DS16) == 0) + mcore->flash_buswidth = 1; } else { mcore->flash_window = 0x1fc00000; - mcore->flash_window_size = 0x400000; + mcore->flash_window_size = 0x00400000; } } - -static void ssb_cpu_clock(struct ssb_mipscore *mcore) +u32 ssb_cpu_clock(struct ssb_mipscore *mcore) { + struct ssb_bus *bus = mcore->dev->bus; + u32 pll_type, n, m, rate = 0; + + if (bus->extif.dev) { + ssb_extif_get_clockcontrol(&bus->extif, &pll_type, &n, &m); + } else if (bus->chipco.dev) { + ssb_chipco_get_clockcpu(&bus->chipco, &pll_type, &n, &m); + } else + return 0; + + if ((pll_type == SSB_PLLTYPE_5) || (bus->chip_id == 0x5365)) { + rate = 200000000; + } else { + rate = ssb_calc_clock_rate(pll_type, n, m); + } + + if (pll_type == SSB_PLLTYPE_6) { + rate *= 2; + } + + return rate; } void ssb_mipscore_init(struct ssb_mipscore *mcore) { - struct ssb_bus *bus = mcore->dev->bus; + struct ssb_bus *bus; struct ssb_device *dev; unsigned long hz, ns; unsigned int irq, i; @@ -200,56 +183,39 @@ void ssb_mipscore_init(struct ssb_mipscore *mcore) ssb_dprintk(KERN_INFO PFX "Initializing MIPS core...\n"); + bus = mcore->dev->bus; hz = ssb_clockspeed(bus); if (!hz) hz = 100000000; ns = 1000000000 / hz; -//TODO -#if 0 - if (have EXTIF) { - /* Initialize extif so we can get to the LEDs and external UART */ - W_REG(&eir->prog_config, CF_EN); - - /* Set timing for the flash */ - tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */ - tmp = tmp | (CEIL(40, ns) << FW_W1_SHIFT); /* W1 = 40nS */ - tmp = tmp | CEIL(120, ns); /* W0 = 120nS */ - W_REG(&eir->prog_waitcount, tmp); /* 0x01020a0c for a 100Mhz clock */ - - /* Set programmable interface timing for external uart */ - tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */ - tmp = tmp | (CEIL(20, ns) << FW_W2_SHIFT); /* W2 = 20nS */ - tmp = tmp | (CEIL(100, ns) << FW_W1_SHIFT); /* W1 = 100nS */ - tmp = tmp | CEIL(120, ns); /* W0 = 120nS */ - W_REG(&eir->prog_waitcount, tmp); - } - else... chipcommon -#endif - if (bus->chipco.dev) + if (bus->extif.dev) + ssb_extif_timing_init(&bus->extif, ns); + else if (bus->chipco.dev) ssb_chipco_timing_init(&bus->chipco, ns); /* Assign IRQs to all cores on the bus, start with irq line 2, because serial usually takes 1 */ for (irq = 2, i = 0; i < bus->nr_devices; i++) { dev = &(bus->devices[i]); dev->irq = ssb_mips_irq(dev) + 2; - switch(dev->id.coreid) { - case SSB_DEV_USB11_HOST: - /* shouldn't need a separate irq line for non-4710, most of them have a proper - * external usb controller on the pci */ - if ((bus->chip_id == 0x4710) && (irq <= 4)) { - set_irq(dev, irq++); - break; - } - case SSB_DEV_PCI: - case SSB_DEV_ETHERNET: - case SSB_DEV_80211: - case SSB_DEV_USB20_HOST: - /* These devices get their own IRQ line if available, the rest goes on IRQ0 */ - if (irq <= 4) { - set_irq(dev, irq++); - break; - } + switch (dev->id.coreid) { + case SSB_DEV_USB11_HOST: + /* shouldn't need a separate irq line for non-4710, most of them have a proper + * external usb controller on the pci */ + if ((bus->chip_id == 0x4710) && (irq <= 4)) { + set_irq(dev, irq++); + break; + } + /* fallthrough */ + case SSB_DEV_PCI: + case SSB_DEV_ETHERNET: + case SSB_DEV_80211: + case SSB_DEV_USB20_HOST: + /* These devices get their own IRQ line if available, the rest goes on IRQ0 */ + if (irq <= 4) { + set_irq(dev, irq++); + break; + } } } -- cgit v1.2.3