brintos

brintos / linux-shallow public Read only

0
0
Text · 17.7 KiB · a8d2525 Raw
698 lines · c
1/*2 * Sonics Silicon Backplane3 * Broadcom ChipCommon core driver4 *5 * Copyright 2005, Broadcom Corporation6 * Copyright 2006, 2007, Michael Buesch <m@bues.ch>7 * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de>8 *9 * Licensed under the GNU/GPL. See COPYING for details.10 */11 12#include "ssb_private.h"13 14#include <linux/ssb/ssb.h>15#include <linux/ssb/ssb_regs.h>16#include <linux/export.h>17#include <linux/pci.h>18#include <linux/bcm47xx_wdt.h>19 20 21/* Clock sources */22enum ssb_clksrc {23	/* PCI clock */24	SSB_CHIPCO_CLKSRC_PCI,25	/* Crystal slow clock oscillator */26	SSB_CHIPCO_CLKSRC_XTALOS,27	/* Low power oscillator */28	SSB_CHIPCO_CLKSRC_LOPWROS,29};30 31 32static inline u32 chipco_write32_masked(struct ssb_chipcommon *cc, u16 offset,33					u32 mask, u32 value)34{35	value &= mask;36	value |= chipco_read32(cc, offset) & ~mask;37	chipco_write32(cc, offset, value);38 39	return value;40}41 42void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc,43			      enum ssb_clkmode mode)44{45	struct ssb_device *ccdev = cc->dev;46	struct ssb_bus *bus;47	u32 tmp;48 49	if (!ccdev)50		return;51	bus = ccdev->bus;52 53	/* We support SLOW only on 6..9 */54	if (ccdev->id.revision >= 10 && mode == SSB_CLKMODE_SLOW)55		mode = SSB_CLKMODE_DYNAMIC;56 57	if (cc->capabilities & SSB_CHIPCO_CAP_PMU)58		return; /* PMU controls clockmode, separated function needed */59	WARN_ON(ccdev->id.revision >= 20);60 61	/* chipcommon cores prior to rev6 don't support dynamic clock control */62	if (ccdev->id.revision < 6)63		return;64 65	/* ChipCommon cores rev10+ need testing */66	if (ccdev->id.revision >= 10)67		return;68 69	if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL))70		return;71 72	switch (mode) {73	case SSB_CLKMODE_SLOW: /* For revs 6..9 only */74		tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);75		tmp |= SSB_CHIPCO_SLOWCLKCTL_FSLOW;76		chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);77		break;78	case SSB_CLKMODE_FAST:79		if (ccdev->id.revision < 10) {80			ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */81			tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);82			tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;83			tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL;84			chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);85		} else {86			chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL,87				(chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) |88				 SSB_CHIPCO_SYSCLKCTL_FORCEHT));89			/* udelay(150); TODO: not available in early init */90		}91		break;92	case SSB_CLKMODE_DYNAMIC:93		if (ccdev->id.revision < 10) {94			tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);95			tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;96			tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL;97			tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL;98			if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) !=99			    SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL)100				tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL;101			chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);102 103			/* For dynamic control, we have to release our xtal_pu104			 * "force on" */105			if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL)106				ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0);107		} else {108			chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL,109				(chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) &110				 ~SSB_CHIPCO_SYSCLKCTL_FORCEHT));111		}112		break;113	default:114		WARN_ON(1);115	}116}117 118/* Get the Slow Clock Source */119static enum ssb_clksrc chipco_pctl_get_slowclksrc(struct ssb_chipcommon *cc)120{121	struct ssb_bus *bus = cc->dev->bus;122	u32 tmp;123 124	if (cc->dev->id.revision < 6) {125		if (bus->bustype == SSB_BUSTYPE_SSB ||126		    bus->bustype == SSB_BUSTYPE_PCMCIA)127			return SSB_CHIPCO_CLKSRC_XTALOS;128		if (bus->bustype == SSB_BUSTYPE_PCI) {129			pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT, &tmp);130			if (tmp & 0x10)131				return SSB_CHIPCO_CLKSRC_PCI;132			return SSB_CHIPCO_CLKSRC_XTALOS;133		}134	}135	if (cc->dev->id.revision < 10) {136		tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);137		tmp &= 0x7;138		if (tmp == 0)139			return SSB_CHIPCO_CLKSRC_LOPWROS;140		if (tmp == 1)141			return SSB_CHIPCO_CLKSRC_XTALOS;142		if (tmp == 2)143			return SSB_CHIPCO_CLKSRC_PCI;144	}145 146	return SSB_CHIPCO_CLKSRC_XTALOS;147}148 149/* Get maximum or minimum (depending on get_max flag) slowclock frequency. */150static int chipco_pctl_clockfreqlimit(struct ssb_chipcommon *cc, int get_max)151{152	int limit;153	enum ssb_clksrc clocksrc;154	int divisor = 1;155	u32 tmp;156 157	clocksrc = chipco_pctl_get_slowclksrc(cc);158	if (cc->dev->id.revision < 6) {159		switch (clocksrc) {160		case SSB_CHIPCO_CLKSRC_PCI:161			divisor = 64;162			break;163		case SSB_CHIPCO_CLKSRC_XTALOS:164			divisor = 32;165			break;166		default:167			WARN_ON(1);168		}169	} else if (cc->dev->id.revision < 10) {170		switch (clocksrc) {171		case SSB_CHIPCO_CLKSRC_LOPWROS:172			break;173		case SSB_CHIPCO_CLKSRC_XTALOS:174		case SSB_CHIPCO_CLKSRC_PCI:175			tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);176			divisor = (tmp >> 16) + 1;177			divisor *= 4;178			break;179		}180	} else {181		tmp = chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL);182		divisor = (tmp >> 16) + 1;183		divisor *= 4;184	}185 186	switch (clocksrc) {187	case SSB_CHIPCO_CLKSRC_LOPWROS:188		if (get_max)189			limit = 43000;190		else191			limit = 25000;192		break;193	case SSB_CHIPCO_CLKSRC_XTALOS:194		if (get_max)195			limit = 20200000;196		else197			limit = 19800000;198		break;199	case SSB_CHIPCO_CLKSRC_PCI:200		if (get_max)201			limit = 34000000;202		else203			limit = 25000000;204		break;205	}206	limit /= divisor;207 208	return limit;209}210 211static void chipco_powercontrol_init(struct ssb_chipcommon *cc)212{213	struct ssb_bus *bus = cc->dev->bus;214 215	if (bus->chip_id == 0x4321) {216		if (bus->chip_rev == 0)217			chipco_write32(cc, SSB_CHIPCO_CHIPCTL, 0x3A4);218		else if (bus->chip_rev == 1)219			chipco_write32(cc, SSB_CHIPCO_CHIPCTL, 0xA4);220	}221 222	if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL))223		return;224 225	if (cc->dev->id.revision >= 10) {226		/* Set Idle Power clock rate to 1Mhz */227		chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL,228			       (chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) &229				0x0000FFFF) | 0x00040000);230	} else {231		int maxfreq;232 233		maxfreq = chipco_pctl_clockfreqlimit(cc, 1);234		chipco_write32(cc, SSB_CHIPCO_PLLONDELAY,235			       (maxfreq * 150 + 999999) / 1000000);236		chipco_write32(cc, SSB_CHIPCO_FREFSELDELAY,237			       (maxfreq * 15 + 999999) / 1000000);238	}239}240 241/* https://bcm-v4.sipsolutions.net/802.11/PmuFastPwrupDelay */242static u16 pmu_fast_powerup_delay(struct ssb_chipcommon *cc)243{244	struct ssb_bus *bus = cc->dev->bus;245 246	switch (bus->chip_id) {247	case 0x4312:248	case 0x4322:249	case 0x4328:250		return 7000;251	case 0x4325:252		/* TODO: */253	default:254		return 15000;255	}256}257 258/* https://bcm-v4.sipsolutions.net/802.11/ClkctlFastPwrupDelay */259static void calc_fast_powerup_delay(struct ssb_chipcommon *cc)260{261	struct ssb_bus *bus = cc->dev->bus;262	int minfreq;263	unsigned int tmp;264	u32 pll_on_delay;265 266	if (bus->bustype != SSB_BUSTYPE_PCI)267		return;268 269	if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {270		cc->fast_pwrup_delay = pmu_fast_powerup_delay(cc);271		return;272	}273 274	if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL))275		return;276 277	minfreq = chipco_pctl_clockfreqlimit(cc, 0);278	pll_on_delay = chipco_read32(cc, SSB_CHIPCO_PLLONDELAY);279	tmp = (((pll_on_delay + 2) * 1000000) + (minfreq - 1)) / minfreq;280	WARN_ON(tmp & ~0xFFFF);281 282	cc->fast_pwrup_delay = tmp;283}284 285static u32 ssb_chipco_alp_clock(struct ssb_chipcommon *cc)286{287	if (cc->capabilities & SSB_CHIPCO_CAP_PMU)288		return ssb_pmu_get_alp_clock(cc);289 290	return 20000000;291}292 293static u32 ssb_chipco_watchdog_get_max_timer(struct ssb_chipcommon *cc)294{295	u32 nb;296 297	if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {298		if (cc->dev->id.revision < 26)299			nb = 16;300		else301			nb = (cc->dev->id.revision >= 37) ? 32 : 24;302	} else {303		nb = 28;304	}305	if (nb == 32)306		return 0xffffffff;307	else308		return (1 << nb) - 1;309}310 311u32 ssb_chipco_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, u32 ticks)312{313	struct ssb_chipcommon *cc = bcm47xx_wdt_get_drvdata(wdt);314 315	if (cc->dev->bus->bustype != SSB_BUSTYPE_SSB)316		return 0;317 318	return ssb_chipco_watchdog_timer_set(cc, ticks);319}320 321u32 ssb_chipco_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms)322{323	struct ssb_chipcommon *cc = bcm47xx_wdt_get_drvdata(wdt);324	u32 ticks;325 326	if (cc->dev->bus->bustype != SSB_BUSTYPE_SSB)327		return 0;328 329	ticks = ssb_chipco_watchdog_timer_set(cc, cc->ticks_per_ms * ms);330	return ticks / cc->ticks_per_ms;331}332 333static int ssb_chipco_watchdog_ticks_per_ms(struct ssb_chipcommon *cc)334{335	struct ssb_bus *bus = cc->dev->bus;336 337	if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {338			/* based on 32KHz ILP clock */339			return 32;340	} else {341		if (cc->dev->id.revision < 18)342			return ssb_clockspeed(bus) / 1000;343		else344			return ssb_chipco_alp_clock(cc) / 1000;345	}346}347 348void ssb_chipcommon_init(struct ssb_chipcommon *cc)349{350	if (!cc->dev)351		return; /* We don't have a ChipCommon */352 353	spin_lock_init(&cc->gpio_lock);354 355	if (cc->dev->id.revision >= 11)356		cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT);357	dev_dbg(cc->dev->dev, "chipcommon status is 0x%x\n", cc->status);358 359	if (cc->dev->id.revision >= 20) {360		chipco_write32(cc, SSB_CHIPCO_GPIOPULLUP, 0);361		chipco_write32(cc, SSB_CHIPCO_GPIOPULLDOWN, 0);362	}363 364	ssb_pmu_init(cc);365	chipco_powercontrol_init(cc);366	ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);367	calc_fast_powerup_delay(cc);368 369	if (cc->dev->bus->bustype == SSB_BUSTYPE_SSB) {370		cc->ticks_per_ms = ssb_chipco_watchdog_ticks_per_ms(cc);371		cc->max_timer_ms = ssb_chipco_watchdog_get_max_timer(cc) / cc->ticks_per_ms;372	}373}374 375void ssb_chipco_suspend(struct ssb_chipcommon *cc)376{377	if (!cc->dev)378		return;379	ssb_chipco_set_clockmode(cc, SSB_CLKMODE_SLOW);380}381 382void ssb_chipco_resume(struct ssb_chipcommon *cc)383{384	if (!cc->dev)385		return;386	chipco_powercontrol_init(cc);387	ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);388}389 390/* Get the processor clock */391void ssb_chipco_get_clockcpu(struct ssb_chipcommon *cc,392                             u32 *plltype, u32 *n, u32 *m)393{394	*n = chipco_read32(cc, SSB_CHIPCO_CLOCK_N);395	*plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT);396	switch (*plltype) {397	case SSB_PLLTYPE_2:398	case SSB_PLLTYPE_4:399	case SSB_PLLTYPE_6:400	case SSB_PLLTYPE_7:401		*m = chipco_read32(cc, SSB_CHIPCO_CLOCK_MIPS);402		break;403	case SSB_PLLTYPE_3:404		/* 5350 uses m2 to control mips */405		*m = chipco_read32(cc, SSB_CHIPCO_CLOCK_M2);406		break;407	default:408		*m = chipco_read32(cc, SSB_CHIPCO_CLOCK_SB);409		break;410	}411}412 413/* Get the bus clock */414void ssb_chipco_get_clockcontrol(struct ssb_chipcommon *cc,415				 u32 *plltype, u32 *n, u32 *m)416{417	*n = chipco_read32(cc, SSB_CHIPCO_CLOCK_N);418	*plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT);419	switch (*plltype) {420	case SSB_PLLTYPE_6: /* 100/200 or 120/240 only */421		*m = chipco_read32(cc, SSB_CHIPCO_CLOCK_MIPS);422		break;423	case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */424		if (cc->dev->bus->chip_id != 0x5365) {425			*m = chipco_read32(cc, SSB_CHIPCO_CLOCK_M2);426			break;427		}428		fallthrough;429	default:430		*m = chipco_read32(cc, SSB_CHIPCO_CLOCK_SB);431	}432}433 434void ssb_chipco_timing_init(struct ssb_chipcommon *cc,435			    unsigned long ns)436{437	struct ssb_device *dev = cc->dev;438	struct ssb_bus *bus = dev->bus;439	u32 tmp;440 441	/* set register for external IO to control LED. */442	chipco_write32(cc, SSB_CHIPCO_PROG_CFG, 0x11);443	tmp = DIV_ROUND_UP(10, ns) << SSB_PROG_WCNT_3_SHIFT;		/* Waitcount-3 = 10ns */444	tmp |= DIV_ROUND_UP(40, ns) << SSB_PROG_WCNT_1_SHIFT;	/* Waitcount-1 = 40ns */445	tmp |= DIV_ROUND_UP(240, ns);				/* Waitcount-0 = 240ns */446	chipco_write32(cc, SSB_CHIPCO_PROG_WAITCNT, tmp);	/* 0x01020a0c for a 100Mhz clock */447 448	/* Set timing for the flash */449	tmp = DIV_ROUND_UP(10, ns) << SSB_FLASH_WCNT_3_SHIFT;	/* Waitcount-3 = 10nS */450	tmp |= DIV_ROUND_UP(10, ns) << SSB_FLASH_WCNT_1_SHIFT;	/* Waitcount-1 = 10nS */451	tmp |= DIV_ROUND_UP(120, ns);				/* Waitcount-0 = 120nS */452	if ((bus->chip_id == 0x5365) ||453	    (dev->id.revision < 9))454		chipco_write32(cc, SSB_CHIPCO_FLASH_WAITCNT, tmp);455	if ((bus->chip_id == 0x5365) ||456	    (dev->id.revision < 9) ||457	    ((bus->chip_id == 0x5350) && (bus->chip_rev == 0)))458		chipco_write32(cc, SSB_CHIPCO_PCMCIA_MEMWAIT, tmp);459 460	if (bus->chip_id == 0x5350) {461		/* Enable EXTIF */462		tmp = DIV_ROUND_UP(10, ns) << SSB_PROG_WCNT_3_SHIFT;	  /* Waitcount-3 = 10ns */463		tmp |= DIV_ROUND_UP(20, ns) << SSB_PROG_WCNT_2_SHIFT;  /* Waitcount-2 = 20ns */464		tmp |= DIV_ROUND_UP(100, ns) << SSB_PROG_WCNT_1_SHIFT; /* Waitcount-1 = 100ns */465		tmp |= DIV_ROUND_UP(120, ns);			  /* Waitcount-0 = 120ns */466		chipco_write32(cc, SSB_CHIPCO_PROG_WAITCNT, tmp); /* 0x01020a0c for a 100Mhz clock */467	}468}469 470/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */471u32 ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks)472{473	u32 maxt;474	enum ssb_clkmode clkmode;475 476	maxt = ssb_chipco_watchdog_get_max_timer(cc);477	if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {478		if (ticks == 1)479			ticks = 2;480		else if (ticks > maxt)481			ticks = maxt;482		chipco_write32(cc, SSB_CHIPCO_PMU_WATCHDOG, ticks);483	} else {484		clkmode = ticks ? SSB_CLKMODE_FAST : SSB_CLKMODE_DYNAMIC;485		ssb_chipco_set_clockmode(cc, clkmode);486		if (ticks > maxt)487			ticks = maxt;488		/* instant NMI */489		chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks);490	}491	return ticks;492}493 494void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value)495{496	chipco_write32_masked(cc, SSB_CHIPCO_IRQMASK, mask, value);497}498 499u32 ssb_chipco_irq_status(struct ssb_chipcommon *cc, u32 mask)500{501	return chipco_read32(cc, SSB_CHIPCO_IRQSTAT) & mask;502}503 504u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc, u32 mask)505{506	return chipco_read32(cc, SSB_CHIPCO_GPIOIN) & mask;507}508 509u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value)510{511	unsigned long flags;512	u32 res = 0;513 514	spin_lock_irqsave(&cc->gpio_lock, flags);515	res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value);516	spin_unlock_irqrestore(&cc->gpio_lock, flags);517 518	return res;519}520 521u32 ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value)522{523	unsigned long flags;524	u32 res = 0;525 526	spin_lock_irqsave(&cc->gpio_lock, flags);527	res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value);528	spin_unlock_irqrestore(&cc->gpio_lock, flags);529 530	return res;531}532 533u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc, u32 mask, u32 value)534{535	unsigned long flags;536	u32 res = 0;537 538	spin_lock_irqsave(&cc->gpio_lock, flags);539	res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value);540	spin_unlock_irqrestore(&cc->gpio_lock, flags);541 542	return res;543}544EXPORT_SYMBOL(ssb_chipco_gpio_control);545 546u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value)547{548	unsigned long flags;549	u32 res = 0;550 551	spin_lock_irqsave(&cc->gpio_lock, flags);552	res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOIRQ, mask, value);553	spin_unlock_irqrestore(&cc->gpio_lock, flags);554 555	return res;556}557 558u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc, u32 mask, u32 value)559{560	unsigned long flags;561	u32 res = 0;562 563	spin_lock_irqsave(&cc->gpio_lock, flags);564	res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPOL, mask, value);565	spin_unlock_irqrestore(&cc->gpio_lock, flags);566 567	return res;568}569 570u32 ssb_chipco_gpio_pullup(struct ssb_chipcommon *cc, u32 mask, u32 value)571{572	unsigned long flags;573	u32 res = 0;574 575	if (cc->dev->id.revision < 20)576		return 0xffffffff;577 578	spin_lock_irqsave(&cc->gpio_lock, flags);579	res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPULLUP, mask, value);580	spin_unlock_irqrestore(&cc->gpio_lock, flags);581 582	return res;583}584 585u32 ssb_chipco_gpio_pulldown(struct ssb_chipcommon *cc, u32 mask, u32 value)586{587	unsigned long flags;588	u32 res = 0;589 590	if (cc->dev->id.revision < 20)591		return 0xffffffff;592 593	spin_lock_irqsave(&cc->gpio_lock, flags);594	res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPULLDOWN, mask, value);595	spin_unlock_irqrestore(&cc->gpio_lock, flags);596 597	return res;598}599 600#ifdef CONFIG_SSB_SERIAL601int ssb_chipco_serial_init(struct ssb_chipcommon *cc,602			   struct ssb_serial_port *ports)603{604	struct ssb_bus *bus = cc->dev->bus;605	int nr_ports = 0;606	u32 plltype;607	unsigned int irq;608	u32 baud_base, div;609	u32 i, n;610	unsigned int ccrev = cc->dev->id.revision;611 612	plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT);613	irq = ssb_mips_irq(cc->dev);614 615	if (plltype == SSB_PLLTYPE_1) {616		/* PLL clock */617		baud_base = ssb_calc_clock_rate(plltype,618						chipco_read32(cc, SSB_CHIPCO_CLOCK_N),619						chipco_read32(cc, SSB_CHIPCO_CLOCK_M2));620		div = 1;621	} else {622		if (ccrev == 20) {623			/* BCM5354 uses constant 25MHz clock */624			baud_base = 25000000;625			div = 48;626			/* Set the override bit so we don't divide it */627			chipco_write32(cc, SSB_CHIPCO_CORECTL,628				       chipco_read32(cc, SSB_CHIPCO_CORECTL)629				       | SSB_CHIPCO_CORECTL_UARTCLK0);630		} else if ((ccrev >= 11) && (ccrev != 15)) {631			baud_base = ssb_chipco_alp_clock(cc);632			div = 1;633			if (ccrev >= 21) {634				/* Turn off UART clock before switching clocksource. */635				chipco_write32(cc, SSB_CHIPCO_CORECTL,636					       chipco_read32(cc, SSB_CHIPCO_CORECTL)637					       & ~SSB_CHIPCO_CORECTL_UARTCLKEN);638			}639			/* Set the override bit so we don't divide it */640			chipco_write32(cc, SSB_CHIPCO_CORECTL,641				       chipco_read32(cc, SSB_CHIPCO_CORECTL)642				       | SSB_CHIPCO_CORECTL_UARTCLK0);643			if (ccrev >= 21) {644				/* Re-enable the UART clock. */645				chipco_write32(cc, SSB_CHIPCO_CORECTL,646					       chipco_read32(cc, SSB_CHIPCO_CORECTL)647					       | SSB_CHIPCO_CORECTL_UARTCLKEN);648			}649		} else if (ccrev >= 3) {650			/* Internal backplane clock */651			baud_base = ssb_clockspeed(bus);652			div = chipco_read32(cc, SSB_CHIPCO_CLKDIV)653			      & SSB_CHIPCO_CLKDIV_UART;654		} else {655			/* Fixed internal backplane clock */656			baud_base = 88000000;657			div = 48;658		}659 660		/* Clock source depends on strapping if UartClkOverride is unset */661		if ((ccrev > 0) &&662		    !(chipco_read32(cc, SSB_CHIPCO_CORECTL) & SSB_CHIPCO_CORECTL_UARTCLK0)) {663			if ((cc->capabilities & SSB_CHIPCO_CAP_UARTCLK) ==664			    SSB_CHIPCO_CAP_UARTCLK_INT) {665				/* Internal divided backplane clock */666				baud_base /= div;667			} else {668				/* Assume external clock of 1.8432 MHz */669				baud_base = 1843200;670			}671		}672	}673 674	/* Determine the registers of the UARTs */675	n = (cc->capabilities & SSB_CHIPCO_CAP_NRUART);676	for (i = 0; i < n; i++) {677		void __iomem *cc_mmio;678		void __iomem *uart_regs;679 680		cc_mmio = cc->dev->bus->mmio + (cc->dev->core_index * SSB_CORE_SIZE);681		uart_regs = cc_mmio + SSB_CHIPCO_UART0_DATA;682		/* Offset changed at after rev 0 */683		if (ccrev == 0)684			uart_regs += (i * 8);685		else686			uart_regs += (i * 256);687 688		nr_ports++;689		ports[i].regs = uart_regs;690		ports[i].irq = irq;691		ports[i].baud_base = baud_base;692		ports[i].reg_shift = 0;693	}694 695	return nr_ports;696}697#endif /* CONFIG_SSB_SERIAL */698