Exemple #1
0
static int
extpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
{
	uint32 addr, *reg = NULL, val;
	int ret = 0;

	if (pci_disabled ||
	    !(addr = config_cmd(sbh, bus, dev, func, off)) ||
	    !(reg = (uint32 *) REG_MAP(addr, len)) ||
	    BUSPROBE(val, reg))
		val = 0xffffffff;

	val >>= 8 * (off & 3);
	if (len == 4)
		*((uint32 *) buf) = val;
	else if (len == 2)
		*((uint16 *) buf) = (uint16) val;
	else if (len == 1)
		*((uint8 *) buf) = (uint8) val;
	else
		ret = -1;

	if (reg)
		REG_UNMAP(reg);

	return ret;
}
/* generic kernel variant of si_attach() */
si_t *
si_kattach(osl_t *osh)
{
	static bool ksii_attached = FALSE;

	if (!ksii_attached) {
		void *regs = REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE);

		if (si_doattach(&ksii, BCM4710_DEVICE_ID, osh, regs,
		                SI_BUS, NULL,
		                osh != SI_OSH ? &ksii.vars : NULL,
		                osh != SI_OSH ? &ksii.varsz : NULL) == NULL) {
			if (NULL != ksii.common_info)
				MFREE(osh, ksii.common_info, sizeof(si_common_info_t));
			SI_ERROR(("si_kattach: si_doattach failed\n"));
			REG_UNMAP(regs);
			return NULL;
		}
		REG_UNMAP(regs);

		/* save ticks normalized to ms for si_watchdog_ms() */
		if (PMUCTL_ENAB(&ksii.pub)) {
			/* based on 32KHz ILP clock */
			wd_msticks = 32;
		} else {
			wd_msticks = ALP_CLOCK / 1000;
		}

		ksii_attached = TRUE;
		SI_MSG(("si_kattach done. ccrev = %d, wd_msticks = %d\n",
		        ksii.pub.ccrev, wd_msticks));
	}

	return &ksii.pub;
}
Exemple #3
0
static int
extpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
{
	uint32 addr, *reg = NULL, val;
	int ret = 0;

	if (pci_disabled ||
	    !(addr = config_cmd(sbh, bus, dev, func, off)) ||
	    !(reg = (uint32 *) REG_MAP(addr, len)) ||
	    BUSPROBE(val, reg))
		goto done;

	if (len == 4)
		val = *((uint32 *) buf);
	else if (len == 2) {
		val &= ~(0xffff << (8 * (off & 3)));
		val |= *((uint16 *) buf) << (8 * (off & 3));
	} else if (len == 1) {
		val &= ~(0xff << (8 * (off & 3)));
		val |= *((uint8 *) buf) << (8 * (off & 3));
	} else
		ret = -1;

	W_REG(reg, val);

 done:
	if (reg)
		REG_UNMAP(reg);

	return ret;
}
Exemple #4
0
/* Get access to the RoboSwitch */
void *
robo_attach(void *sih)
{
    robo_info_t *robo;
    si_info_t *sii;
    nssrabregs_t *regs;      /* pointer to chip registers */
	struct si_pub *sii_pub = NULL;
	uint32	base_addr;

    sii = SI_INFO((si_t*)sih);

    /* Allocate private state */
    if (!(robo = MALLOC(sii->osh, sizeof(robo_info_t)))) {
        SRAB_ERR(("robo_attach: out of memory"));
        return NULL;
    } else {
        robo_sbh = (void *)robo;
    }
    bzero((char *) robo, sizeof(robo_info_t));

    robo->sbh = sih;
	sii_pub = &sii->pub;

	if (sii_pub->chip == BCM53020_CHIP_ID) {
		base_addr = NSP_CCB_SRAB_BASE;
	} else {
		base_addr = CCB_SRAB_BASE;
	}
    if ((regs = (void*)REG_MAP(base_addr, CORE_SIZE)) == NULL) {
        SRAB_ERR(("robo_attach: can't get base address"));
        return NULL;
    }
/*    printk("%d: robo_attach: regs=0x%x\n",__LINE__,(uint32)regs);*/
    robo->regs = regs;

#ifdef _KERNEL_
    /* Initialize lock */
    spin_lock_init(&robo->lock);
#endif
    return robo;
}
Exemple #5
0
static void __init sb_extif_serial_init(sb_t * sbh, void *regs,
					sb_serial_init_fn add)
{
	osl_t *osh = sb_osh(sbh);
	extifregs_t *eir = (extifregs_t *) regs;
	sbconfig_t *sb;
	ulong base;
	uint irq;
	int i, n;

	/* Determine external UART register base */
	sb = (sbconfig_t *) ((ulong) eir + SBCONFIGOFF);
	base = EXTIF_CFGIF_BASE(sb_base(R_REG(osh, &sb->sbadmatch1)));

	/* Determine IRQ */
	irq = sb_irq(sbh);

	/* Disable GPIO interrupt initially */
	W_REG(osh, &eir->gpiointpolarity, 0);
	W_REG(osh, &eir->gpiointmask, 0);

	/* Search for external UARTs */
	n = 2;
	for (i = 0; i < 2; i++) {
		regs = (void *)REG_MAP(base + (i * 8), 8);
		if (serial_exists(osh, regs)) {
			/* Set GPIO 1 to be the external UART IRQ */
			W_REG(osh, &eir->gpiointmask, 2);
			/* XXXDetermine external UART clock */
			if (add)
				add(regs, irq, 13500000, 0);
		}
	}

	/* Add internal UART if enabled */
	if (R_REG(osh, &eir->corecontrol) & CC_UE)
		if (add)
			add((void *)&eir->uartdata, irq, sb_clock(sbh), 2);
}
uint32 *
spi_reg_map(osl_t *osh, uintptr addr, int size)
{
	return (uint32 *)REG_MAP(addr, size);
}
static si_info_t *
si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs,
                       uint bustype, void *sdh, char **vars, uint *varsz)
{
	struct si_pub *sih = &sii->pub;
	uint32 w, savewin;
	chipcregs_t *cc;
	char *pvars = NULL;
	uint origidx;

	ASSERT(GOODREGS(regs));

	bzero((uchar*)sii, sizeof(si_info_t));


	{
		if (NULL == (common_info_alloced = (void *)MALLOC(osh, sizeof(si_common_info_t)))) {
			SI_ERROR(("si_doattach: malloc failed! malloced %dbytes\n", MALLOCED(osh)));
			return (NULL);
		}
		bzero((uchar*)(common_info_alloced), sizeof(si_common_info_t));
	}
	sii->common_info = (si_common_info_t *)common_info_alloced;
	sii->common_info->attach_count++;

	savewin = 0;

	sih->buscoreidx = BADIDX;

	sii->curmap = regs;
	sii->sdh = sdh;
	sii->osh = osh;


	/* find Chipcommon address */
	if (bustype == PCI_BUS) {
		savewin = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32));
		if (!GOODCOREADDR(savewin, SI_ENUM_BASE))
			savewin = SI_ENUM_BASE;
		OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, SI_ENUM_BASE);
		cc = (chipcregs_t *)regs;
	} else
	if ((bustype == SDIO_BUS) || (bustype == SPI_BUS)) {
		cc = (chipcregs_t *)sii->curmap;
	} else {
		cc = (chipcregs_t *)REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE);
	}

	sih->bustype = bustype;
	if (bustype != BUSTYPE(bustype)) {
		SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n",
			bustype, BUSTYPE(bustype)));
		return NULL;
	}

	/* bus/core/clk setup for register access */
	if (!si_buscore_prep(sii, bustype, devid, sdh)) {
		SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n", bustype));
		return NULL;
	}

	/* ChipID recognition.
	 *   We assume we can read chipid at offset 0 from the regs arg.
	 *   If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon),
	 *   some way of recognizing them needs to be added here.
	 */
	w = R_REG(osh, &cc->chipid);
	sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
	/* Might as wll fill in chip id rev & pkg */
	sih->chip = w & CID_ID_MASK;
	sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
	sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
	if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && (sih->chippkg != BCM4329_289PIN_PKG_ID))
		sih->chippkg = BCM4329_182PIN_PKG_ID;
	sih->issim = IS_SIM(sih->chippkg);

	/* scan for cores */
	if (CHIPTYPE(sii->pub.socitype) == SOCI_SB) {
		SI_MSG(("Found chip type SB (0x%08x)\n", w));
		sb_scan(&sii->pub, regs, devid);
	} else if (CHIPTYPE(sii->pub.socitype) == SOCI_AI) {
		SI_MSG(("Found chip type AI (0x%08x)\n", w));
		/* pass chipc address instead of original core base */
		ai_scan(&sii->pub, (void *)cc, devid);
	} else {
		SI_ERROR(("Found chip of unkown type (0x%08x)\n", w));
		return NULL;
	}
	/* no cores found, bail out */
	if (sii->numcores == 0) {
		SI_ERROR(("si_doattach: could not find any cores\n"));
		return NULL;
	}
	/* bus/core/clk setup */
	origidx = SI_CC_IDX;
	if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) {
		SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
		return NULL;
	}

	pvars = NULL;



		if (sii->pub.ccrev >= 20) {
			cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
			W_REG(osh, &cc->gpiopullup, 0);
			W_REG(osh, &cc->gpiopulldown, 0);
			si_setcoreidx(sih, origidx);
		}

		/* Skip PMU initialization from the Dongle Host.
		 * Firmware will take care of it when it comes up.
		 */



	return (sii);
}
Exemple #8
0
/*
 * Initializes UART access. The callback function will be called once
 * per found UART.
 */
void
BCMINITFN(sb_serial_init)(sb_t *sbh, void (*add)(void *regs, uint irq, uint baud_base,
                                                 uint reg_shift))
{
	osl_t *osh;
	void *regs;
	ulong base;
	uint irq;
	int i, n;

	osh = sb_osh(sbh);

	if ((regs = sb_setcore(sbh, SB_EXTIF, 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(osh, &sb->sbadmatch1)));

		/* Determine IRQ */
		irq = sb_irq(sbh);

		/* Disable GPIO interrupt initially */
		W_REG(osh, &eir->gpiointpolarity, 0);
		W_REG(osh, &eir->gpiointmask, 0);

		/* Search for external UARTs */
		n = 2;
		for (i = 0; i < 2; i++) {
			regs = (void *) REG_MAP(base + (i * 8), 8);
			if (serial_exists(osh, regs)) {
				/* Set GPIO 1 to be the external UART IRQ */
				W_REG(osh, &eir->gpiointmask, 2);
				/* XXXDetermine external UART clock */
				if (add)
					add(regs, irq, 13500000, 0);
			}
		}

		/* Add internal UART if enabled */
		if (R_REG(osh, &eir->corecontrol) & CC_UE)
			if (add)
				add((void *) &eir->uartdata, irq, sb_clock(sbh), 2);
	} else if ((regs = sb_setcore(sbh, SB_CC, 0))) {
		chipcregs_t *cc = (chipcregs_t *) regs;
		uint32 rev, cap, pll, baud_base, div;

		/* Default value */
		div = 48;

		/* Determine core revision and capabilities */
		rev = sb_corerev(sbh);
		cap = R_REG(osh, &cc->capabilities);
		pll = cap & CAP_PLL_MASK;

		/* Determine IRQ */
		irq = sb_irq(sbh);

		if (pll == PLL_TYPE1) {
			/* PLL clock */
			baud_base = sb_clock_rate(pll,
			                          R_REG(osh, &cc->clockcontrol_n),
			                          R_REG(osh, &cc->clockcontrol_m2));
			div = 1;
		} else {
			/* 5354 chip common uart uses a constant clock
			 * frequency of 25MHz */
			if (sb_corerev(sbh) == 20) {
				/* Set the override bit so we don't divide it */
				W_REG(osh, &cc->corecontrol, CC_UARTCLKO);
				baud_base = 25000000;
			} else if (rev >= 11 && rev != 15) {
				/* Fixed ALP clock */
				baud_base = sb_alp_clock(sbh);
				div = 1;
				/* Set the override bit so we don't divide it */
				W_REG(osh, &cc->corecontrol, CC_UARTCLKO);
			} else if (rev >= 3) {
				/* Internal backplane clock */
				baud_base = sb_clock(sbh);
				div = 2;	/* Minimum divisor */
				W_REG(osh, &cc->clkdiv,
				      ((R_REG(osh, &cc->clkdiv) & ~CLKD_UART) | div));
			} else {
				/* Fixed internal backplane clock */
				baud_base = 88000000;
				div = 48;
			}

			/* Clock source depends on strapping if UartClkOverride is unset */
			if ((rev > 0) &&
			    ((R_REG(osh, &cc->corecontrol) & CC_UARTCLKO) == 0)) {
				if ((cap & CAP_UCLKSEL) == CAP_UINTCLK) {
					/* Internal divided backplane clock */
					baud_base /= div;
				} else {
					/* Assume external clock of 1.8432 MHz */
					baud_base = 1843200;
				}
			}
		}

		/* Add internal UARTs */
		n = cap & CAP_UARTS_MASK;
		for (i = 0; i < n; i++) {
			/* Register offset changed after revision 0 */
			if (rev)
				regs = (void *)((ulong) &cc->uart0data + (i * 256));
			else
				regs = (void *)((ulong) &cc->uart0data + (i * 8));

			if (add)
				add(regs, irq, baud_base, 0);
		}
	}
}
Exemple #9
0
uint32 *
sdstd_reg_map(osl_t *osh, int32 addr, int size)
{
	return (uint32 *)REG_MAP(addr, size);
}