Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b0327ffa authored by Arend van Spriel's avatar Arend van Spriel Committed by John W. Linville
Browse files

brcm80211: smac: use bcma core access functions in nicpci.c



Code in nicpci.c now uses the PCI(E) core as provided by the BCMA
bus driver to configure that core.

Reviewed-by: default avatarPieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: default avatarAlwin Beukers <alwin@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarFranky Lin <frankyl@broadcom.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent a8779e4a
Loading
Loading
Loading
Loading
+3 −8
Original line number Diff line number Diff line
@@ -633,8 +633,7 @@ ai_buscore_setup(struct si_info *sii, u32 savewin, uint *origidx)

	/* fixup necessary chip/core configurations */
	if (!sii->pch) {
		sii->pch = pcicore_init(&sii->pub, sii->pcibus,
					sii->curmap + PCI_16KB0_PCIREGS_OFFSET);
		sii->pch = pcicore_init(&sii->pub, sii->icbus->drv_pci.core);
		if (sii->pch == NULL)
			return false;
	}
@@ -1385,7 +1384,7 @@ void ai_pci_setup(struct si_pub *sih, uint coremask)
	}

	if (PCI(sih)) {
		pcicore_pci_setup(sii->pch, regs);
		pcicore_pci_setup(sii->pch);

		/* switch back to previous core */
		ai_setcoreidx(sih, idx);
@@ -1408,11 +1407,7 @@ int ai_pci_fixcfg(struct si_pub *sih)

	/* check 'pi' is correct and fix it if not */
	regs = ai_setcore(&sii->pub, ai_get_buscoretype(sih), 0);
	if (ai_get_buscoretype(sih) == PCIE_CORE_ID)
		pcicore_fixcfg_pcie(sii->pch,
				    (struct sbpcieregs __iomem *)regs);
	else if (ai_get_buscoretype(sih) == PCI_CORE_ID)
		pcicore_fixcfg_pci(sii->pch, (struct sbpciregs __iomem *)regs);
	pcicore_fixcfg(sii->pch);

	/* restore the original index */
	ai_setcoreidx(&sii->pub, origidx);
+84 −95
Original line number Diff line number Diff line
@@ -139,6 +139,9 @@
#define SRSH_PI_MASK	0xf000	/* bit 15:12 */
#define SRSH_PI_SHIFT	12	/* bit 15:12 */

#define PCIREGOFFS(field)	offsetof(struct sbpciregs, field)
#define PCIEREGOFFS(field)	offsetof(struct sbpcieregs, field)

/* Sonics side: PCI core and host control registers */
struct sbpciregs {
	u32 control;		/* PCI control */
@@ -205,11 +208,7 @@ struct sbpcieregs {
};

struct pcicore_info {
	union {
		struct sbpcieregs __iomem *pcieregs;
		struct sbpciregs __iomem *pciregs;
	} regs;			/* Memory mapped register to the core */

	struct bcma_device *core;
	struct si_pub *sih;	/* System interconnect handle */
	struct pci_dev *dev;
	u8 pciecap_lcreg_offset;/* PCIE capability LCreg offset
@@ -238,8 +237,7 @@ static void pr28829_delay(void)
/* Initialize the PCI core.
 * It's caller's responsibility to make sure that this is done only once
 */
struct pcicore_info *pcicore_init(struct si_pub *sih, struct pci_dev *pdev,
				  void __iomem *regs)
struct pcicore_info *pcicore_init(struct si_pub *sih, struct bcma_device *core)
{
	struct pcicore_info *pi;

@@ -249,17 +247,15 @@ struct pcicore_info *pcicore_init(struct si_pub *sih, struct pci_dev *pdev,
		return NULL;

	pi->sih = sih;
	pi->dev = pdev;
	pi->dev = core->bus->host_pci;
	pi->core = core;

	if (ai_get_buscoretype(sih) == PCIE_CORE_ID) {
	if (core->id.id == PCIE_CORE_ID) {
		u8 cap_ptr;
		pi->regs.pcieregs = regs;
		cap_ptr = pcicore_find_pci_capability(pi->dev, PCI_CAP_ID_EXP,
						      NULL, NULL);
		pi->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET;
	} else
		pi->regs.pciregs = regs;

	}
	return pi;
}

@@ -334,37 +330,37 @@ pcicore_find_pci_capability(struct pci_dev *dev, u8 req_cap_id,

/* ***** Register Access API */
static uint
pcie_readreg(struct sbpcieregs __iomem *pcieregs, uint addrtype, uint offset)
pcie_readreg(struct bcma_device *core, uint addrtype, uint offset)
{
	uint retval = 0xFFFFFFFF;

	switch (addrtype) {
	case PCIE_CONFIGREGS:
		W_REG(&pcieregs->configaddr, offset);
		(void)R_REG((&pcieregs->configaddr));
		retval = R_REG(&pcieregs->configdata);
		bcma_write32(core, PCIEREGOFFS(configaddr), offset);
		(void)bcma_read32(core, PCIEREGOFFS(configaddr));
		retval = bcma_read32(core, PCIEREGOFFS(configdata));
		break;
	case PCIE_PCIEREGS:
		W_REG(&pcieregs->pcieindaddr, offset);
		(void)R_REG(&pcieregs->pcieindaddr);
		retval = R_REG(&pcieregs->pcieinddata);
		bcma_write32(core, PCIEREGOFFS(pcieindaddr), offset);
		(void)bcma_read32(core, PCIEREGOFFS(pcieindaddr));
		retval = bcma_read32(core, PCIEREGOFFS(pcieinddata));
		break;
	}

	return retval;
}

static uint pcie_writereg(struct sbpcieregs __iomem *pcieregs, uint addrtype,
static uint pcie_writereg(struct bcma_device *core, uint addrtype,
			  uint offset, uint val)
{
	switch (addrtype) {
	case PCIE_CONFIGREGS:
		W_REG((&pcieregs->configaddr), offset);
		W_REG((&pcieregs->configdata), val);
		bcma_write32(core, PCIEREGOFFS(configaddr), offset);
		bcma_write32(core, PCIEREGOFFS(configdata), val);
		break;
	case PCIE_PCIEREGS:
		W_REG((&pcieregs->pcieindaddr), offset);
		W_REG((&pcieregs->pcieinddata), val);
		bcma_write32(core, PCIEREGOFFS(pcieindaddr), offset);
		bcma_write32(core, PCIEREGOFFS(pcieinddata), val);
		break;
	default:
		break;
@@ -374,7 +370,6 @@ static uint pcie_writereg(struct sbpcieregs __iomem *pcieregs, uint addrtype,

static bool pcie_mdiosetblock(struct pcicore_info *pi, uint blk)
{
	struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
	uint mdiodata, i = 0;
	uint pcie_serdes_spinwait = 200;

@@ -382,12 +377,13 @@ static bool pcie_mdiosetblock(struct pcicore_info *pi, uint blk)
		    (MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
		    (MDIODATA_BLK_ADDR << MDIODATA_REGADDR_SHF) |
		    (blk << 4));
	W_REG(&pcieregs->mdiodata, mdiodata);
	bcma_write32(pi->core, PCIEREGOFFS(mdiodata), mdiodata);

	pr28829_delay();
	/* retry till the transaction is complete */
	while (i < pcie_serdes_spinwait) {
		if (R_REG(&pcieregs->mdiocontrol) & MDIOCTL_ACCESS_DONE)
		if (bcma_read32(pi->core, PCIEREGOFFS(mdiocontrol)) &
		    MDIOCTL_ACCESS_DONE)
			break;

		udelay(1000);
@@ -404,13 +400,13 @@ static int
pcie_mdioop(struct pcicore_info *pi, uint physmedia, uint regaddr, bool write,
	    uint *val)
{
	struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
	uint mdiodata;
	uint i = 0;
	uint pcie_serdes_spinwait = 10;

	/* enable mdio access to SERDES */
	W_REG(&pcieregs->mdiocontrol, MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);
	bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol),
		     MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);

	if (pi->sih->buscorerev >= 10) {
		/* new serdes is slower in rw,
@@ -432,20 +428,22 @@ pcie_mdioop(struct pcicore_info *pi, uint physmedia, uint regaddr, bool write,
		mdiodata |= (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA |
			     *val);

	W_REG(&pcieregs->mdiodata, mdiodata);
	bcma_write32(pi->core, PCIEREGOFFS(mdiodata), mdiodata);

	pr28829_delay();

	/* retry till the transaction is complete */
	while (i < pcie_serdes_spinwait) {
		if (R_REG(&pcieregs->mdiocontrol) & MDIOCTL_ACCESS_DONE) {
		if (bcma_read32(pi->core, PCIEREGOFFS(mdiocontrol)) &
		    MDIOCTL_ACCESS_DONE) {
			if (!write) {
				pr28829_delay();
				*val = (R_REG(&pcieregs->mdiodata) &
				*val = (bcma_read32(pi->core,
						    PCIEREGOFFS(mdiodata)) &
					MDIODATA_MASK);
			}
			/* Disable mdio access to SERDES */
			W_REG(&pcieregs->mdiocontrol, 0);
			bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol), 0);
			return 0;
		}
		udelay(1000);
@@ -453,7 +451,7 @@ pcie_mdioop(struct pcicore_info *pi, uint physmedia, uint regaddr, bool write,
	}

	/* Timed out. Disable mdio access to SERDES. */
	W_REG(&pcieregs->mdiocontrol, 0);
	bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol), 0);
	return 1;
}

@@ -502,19 +500,18 @@ static void pcie_extendL1timer(struct pcicore_info *pi, bool extend)
{
	u32 w;
	struct si_pub *sih = pi->sih;
	struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;

	if (ai_get_buscoretype(sih) != PCIE_CORE_ID ||
	    ai_get_buscorerev(sih) < 7)
		return;

	w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
	w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
	if (extend)
		w |= PCIE_ASPMTIMER_EXTEND;
	else
		w &= ~PCIE_ASPMTIMER_EXTEND;
	pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w);
	w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
	pcie_writereg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w);
	w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
}

/* centralized clkreq control policy */
@@ -565,7 +562,7 @@ static void pcie_war_polarity(struct pcicore_info *pi)
	if (pi->pcie_polarity != 0)
		return;

	w = pcie_readreg(pi->regs.pcieregs, PCIE_PCIEREGS, PCIE_PLP_STATUSREG);
	w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_PLP_STATUSREG);

	/* Detect the current polarity at attach and force that polarity and
	 * disable changing the polarity
@@ -584,18 +581,15 @@ static void pcie_war_polarity(struct pcicore_info *pi)
 */
static void pcie_war_aspm_clkreq(struct pcicore_info *pi)
{
	struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
	struct si_pub *sih = pi->sih;
	u16 val16;
	u16 __iomem *reg16;
	u32 w;

	if (!PCIE_ASPM(sih))
		return;

	/* bypass this on QT or VSIM */
	reg16 = &pcieregs->sprom[SRSH_ASPM_OFFSET];
	val16 = R_REG(reg16);
	val16 = bcma_read16(pi->core, PCIEREGOFFS(sprom[SRSH_ASPM_OFFSET]));

	val16 &= ~SRSH_ASPM_ENB;
	if (pi->pcie_war_aspm_ovr == PCIE_ASPM_ENAB)
@@ -605,15 +599,15 @@ static void pcie_war_aspm_clkreq(struct pcicore_info *pi)
	else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L0s_ENAB)
		val16 |= SRSH_ASPM_L0s_ENB;

	W_REG(reg16, val16);
	bcma_write16(pi->core, PCIEREGOFFS(sprom[SRSH_ASPM_OFFSET]), val16);

	pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w);
	w &= ~PCIE_ASPM_ENAB;
	w |= pi->pcie_war_aspm_ovr;
	pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w);

	reg16 = &pcieregs->sprom[SRSH_CLKREQ_OFFSET_REV5];
	val16 = R_REG(reg16);
	val16 = bcma_read16(pi->core,
			    PCIEREGOFFS(sprom[SRSH_CLKREQ_OFFSET_REV5]));

	if (pi->pcie_war_aspm_ovr != PCIE_ASPM_DISAB) {
		val16 |= SRSH_CLKREQ_ENB;
@@ -621,7 +615,8 @@ static void pcie_war_aspm_clkreq(struct pcicore_info *pi)
	} else
		val16 &= ~SRSH_CLKREQ_ENB;

	W_REG(reg16, val16);
	bcma_write16(pi->core, PCIEREGOFFS(sprom[SRSH_CLKREQ_OFFSET_REV5]),
		     val16);
}

/* Apply the polarity determined at the start */
@@ -645,16 +640,15 @@ static void pcie_war_serdes(struct pcicore_info *pi)
/* Needs to happen when coming out of 'standby'/'hibernate' */
static void pcie_misc_config_fixup(struct pcicore_info *pi)
{
	struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
	u16 val16;
	u16 __iomem *reg16;

	reg16 = &pcieregs->sprom[SRSH_PCIE_MISC_CONFIG];
	val16 = R_REG(reg16);
	val16 = bcma_read16(pi->core,
			    PCIEREGOFFS(sprom[SRSH_PCIE_MISC_CONFIG]));

	if ((val16 & SRSH_L23READY_EXIT_NOPERST) == 0) {
		val16 |= SRSH_L23READY_EXIT_NOPERST;
		W_REG(reg16, val16);
		bcma_write16(pi->core,
			     PCIEREGOFFS(sprom[SRSH_PCIE_MISC_CONFIG]), val16);
	}
}

@@ -662,37 +656,32 @@ static void pcie_misc_config_fixup(struct pcicore_info *pi)
/* Needs to happen when coming out of 'standby'/'hibernate' */
static void pcie_war_noplldown(struct pcicore_info *pi)
{
	struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
	u16 __iomem *reg16;

	/* turn off serdes PLL down */
	ai_cc_reg(pi->sih, offsetof(struct chipcregs, chipcontrol),
		  CHIPCTRL_4321_PLL_DOWN, CHIPCTRL_4321_PLL_DOWN);

	/* clear srom shadow backdoor */
	reg16 = &pcieregs->sprom[SRSH_BD_OFFSET];
	W_REG(reg16, 0);
	bcma_write16(pi->core, PCIEREGOFFS(sprom[SRSH_BD_OFFSET]), 0);
}

/* Needs to happen when coming out of 'standby'/'hibernate' */
static void pcie_war_pci_setup(struct pcicore_info *pi)
{
	struct si_pub *sih = pi->sih;
	struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
	u32 w;

	if (ai_get_buscorerev(sih) == 0 || ai_get_buscorerev(sih) == 1) {
		w = pcie_readreg(pcieregs, PCIE_PCIEREGS,
		w = pcie_readreg(pi->core, PCIE_PCIEREGS,
				 PCIE_TLP_WORKAROUNDSREG);
		w |= 0x8;
		pcie_writereg(pcieregs, PCIE_PCIEREGS,
		pcie_writereg(pi->core, PCIE_PCIEREGS,
			      PCIE_TLP_WORKAROUNDSREG, w);
	}

	if (ai_get_buscorerev(sih) == 1) {
		w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG);
		w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_LCREG);
		w |= 0x40;
		pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG, w);
		pcie_writereg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_LCREG, w);
	}

	if (ai_get_buscorerev(sih) == 0) {
@@ -701,11 +690,11 @@ static void pcie_war_pci_setup(struct pcicore_info *pi)
		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466);
	} else if (PCIE_ASPM(sih)) {
		/* Change the L1 threshold for better performance */
		w = pcie_readreg(pcieregs, PCIE_PCIEREGS,
		w = pcie_readreg(pi->core, PCIE_PCIEREGS,
				 PCIE_DLLP_PMTHRESHREG);
		w &= ~PCIE_L1THRESHOLDTIME_MASK;
		w |= PCIE_L1THRESHOLD_WARVAL << PCIE_L1THRESHOLDTIME_SHIFT;
		pcie_writereg(pcieregs, PCIE_PCIEREGS,
		pcie_writereg(pi->core, PCIE_PCIEREGS,
			      PCIE_DLLP_PMTHRESHREG, w);

		pcie_war_serdes(pi);
@@ -794,45 +783,45 @@ void pcicore_down(struct pcicore_info *pi, int state)
}

/* precondition: current core is sii->buscoretype */
static void pcicore_fixcfg(struct pcicore_info *pi, u16 __iomem *reg16)
void pcicore_fixcfg(struct pcicore_info *pi)
{
	struct si_info *sii = (struct si_info *)(pi->sih);
	struct bcma_device *core = pi->core;
	u16 val16;
	uint pciidx;
	uint regoff;

	pciidx = ai_coreidx(&sii->pub);
	val16 = R_REG(reg16);
	if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (u16)pciidx) {
		val16 = (u16)(pciidx << SRSH_PI_SHIFT) |
			(val16 & ~SRSH_PI_MASK);
		W_REG(reg16, val16);
	}
}
	switch (pi->core->id.id) {
	case BCMA_CORE_PCI:
		regoff = PCIREGOFFS(sprom[SRSH_PI_OFFSET]);
		break;

void
pcicore_fixcfg_pci(struct pcicore_info *pi, struct sbpciregs __iomem *pciregs)
{
	pcicore_fixcfg(pi, &pciregs->sprom[SRSH_PI_OFFSET]);
	case BCMA_CORE_PCIE:
		regoff = PCIEREGOFFS(sprom[SRSH_PI_OFFSET]);
		break;

	default:
		return;
	}

void pcicore_fixcfg_pcie(struct pcicore_info *pi,
			 struct sbpcieregs __iomem *pcieregs)
{
	pcicore_fixcfg(pi, &pcieregs->sprom[SRSH_PI_OFFSET]);
	val16 = bcma_read16(pi->core, regoff);
	if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) !=
	    (u16)core->core_index) {
		val16 = ((u16)core->core_index << SRSH_PI_SHIFT) |
			(val16 & ~SRSH_PI_MASK);
		bcma_write16(pi->core, regoff, val16);
	}
}

/* precondition: current core is pci core */
void
pcicore_pci_setup(struct pcicore_info *pi, struct sbpciregs __iomem *pciregs)
pcicore_pci_setup(struct pcicore_info *pi)
{
	u32 w;

	OR_REG(&pciregs->sbtopci2, SBTOPCI_PREF | SBTOPCI_BURST);

	if (ai_get_buscorerev(pi->sih) >= 11) {
		OR_REG(&pciregs->sbtopci2, SBTOPCI_RC_READMULTI);
		w = R_REG(&pciregs->clkrun);
		W_REG(&pciregs->clkrun, w | PCI_CLKRUN_DSBL);
		w = R_REG(&pciregs->clkrun);
	bcma_set32(pi->core, PCIREGOFFS(sbtopci2),
		   SBTOPCI_PREF | SBTOPCI_BURST);

	if (pi->core->id.rev >= 11) {
		bcma_set32(pi->core, PCIREGOFFS(sbtopci2),
			   SBTOPCI_RC_READMULTI);
		bcma_set32(pi->core, PCIREGOFFS(clkrun), PCI_CLKRUN_DSBL);
		(void)bcma_read32(pi->core, PCIREGOFFS(clkrun));
	}
}
+3 −8
Original line number Diff line number Diff line
@@ -62,8 +62,7 @@ struct sbpciregs;
struct sbpcieregs;

extern struct pcicore_info *pcicore_init(struct si_pub *sih,
					 struct pci_dev *pdev,
					 void __iomem *regs);
					 struct bcma_device *core);
extern void pcicore_deinit(struct pcicore_info *pch);
extern void pcicore_attach(struct pcicore_info *pch, int state);
extern void pcicore_hwup(struct pcicore_info *pch);
@@ -72,11 +71,7 @@ extern void pcicore_sleep(struct pcicore_info *pch);
extern void pcicore_down(struct pcicore_info *pch, int state);
extern u8 pcicore_find_pci_capability(struct pci_dev *dev, u8 req_cap_id,
				      unsigned char *buf, u32 *buflen);
extern void pcicore_fixcfg_pci(struct pcicore_info *pch,
			       struct sbpciregs __iomem *pciregs);
extern void pcicore_fixcfg_pcie(struct pcicore_info *pch,
				struct sbpcieregs __iomem *pciregs);
extern void pcicore_pci_setup(struct pcicore_info *pch,
			      struct sbpciregs __iomem *pciregs);
extern void pcicore_fixcfg(struct pcicore_info *pch);
extern void pcicore_pci_setup(struct pcicore_info *pch);

#endif /* _BRCM_NICPCI_H_ */