示例#1
0
static bool pcie_mdiosetblock(struct pcicore_info *pi, uint blk)
{
	uint mdiodata, i = 0;
	uint pcie_serdes_spinwait = 200;

	mdiodata = (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA |
		    (MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
		    (MDIODATA_BLK_ADDR << MDIODATA_REGADDR_SHF) |
		    (blk << 4));
	bcma_write32(pi->core, PCIEREGOFFS(mdiodata), mdiodata);

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

		udelay(1000);
		i++;
	}

	if (i >= pcie_serdes_spinwait)
		return false;

	return true;
}
示例#2
0
static uint pcie_writereg(struct bcma_device *core, uint addrtype,
			  uint offset, uint val)
{
	switch (addrtype) {
	case PCIE_CONFIGREGS:
		bcma_write32(core, PCIEREGOFFS(configaddr), offset);
		bcma_write32(core, PCIEREGOFFS(configdata), val);
		break;
	case PCIE_PCIEREGS:
		bcma_write32(core, PCIEREGOFFS(pcieindaddr), offset);
		bcma_write32(core, PCIEREGOFFS(pcieinddata), val);
		break;
	default:
		break;
	}
	return 0;
}
示例#3
0
static int
pcie_mdioop(struct pcicore_info *pi, uint physmedia, uint regaddr, bool write,
	    uint *val)
{
	uint mdiodata;
	uint i = 0;
	uint pcie_serdes_spinwait = 10;

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

	if (ai_get_buscorerev(pi->sih) >= 10) {
		/* new serdes is slower in rw,
		 * using two layers of reg address mapping
		 */
		if (!pcie_mdiosetblock(pi, physmedia))
			return 1;
		mdiodata = ((MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
			    (regaddr << MDIODATA_REGADDR_SHF));
		pcie_serdes_spinwait *= 20;
	} else {
		mdiodata = ((physmedia << MDIODATA_DEVADDR_SHF_OLD) |
			    (regaddr << MDIODATA_REGADDR_SHF_OLD));
	}

	if (!write)
		mdiodata |= (MDIODATA_START | MDIODATA_READ | MDIODATA_TA);
	else
		mdiodata |= (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA |
			     *val);

	bcma_write32(pi->core, PCIEREGOFFS(mdiodata), mdiodata);

	pr28829_delay();

	/* retry till the transaction is complete */
	while (i < pcie_serdes_spinwait) {
		if (bcma_read32(pi->core, PCIEREGOFFS(mdiocontrol)) &
		    MDIOCTL_ACCESS_DONE) {
			if (!write) {
				pr28829_delay();
				*val = (bcma_read32(pi->core,
						    PCIEREGOFFS(mdiodata)) &
					MDIODATA_MASK);
			}
			/* Disable mdio access to SERDES */
			bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol), 0);
			return 0;
		}
		udelay(1000);
		i++;
	}

	/* Timed out. Disable mdio access to SERDES. */
	bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol), 0);
	return 1;
}
static int
pcie_mdioop(struct pcicore_info *pi, uint physmedia, uint regaddr, bool write,
            uint *val)
{
    uint mdiodata;
    uint i = 0;
    uint pcie_serdes_spinwait = 10;


    bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol),
                 MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);

    if (ai_get_buscorerev(pi->sih) >= 10) {
        if (!pcie_mdiosetblock(pi, physmedia))
            return 1;
        mdiodata = ((MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
                    (regaddr << MDIODATA_REGADDR_SHF));
        pcie_serdes_spinwait *= 20;
    } else {
        mdiodata = ((physmedia << MDIODATA_DEVADDR_SHF_OLD) |
                    (regaddr << MDIODATA_REGADDR_SHF_OLD));
    }

    if (!write)
        mdiodata |= (MDIODATA_START | MDIODATA_READ | MDIODATA_TA);
    else
        mdiodata |= (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA |
                     *val);

    bcma_write32(pi->core, PCIEREGOFFS(mdiodata), mdiodata);

    pr28829_delay();


    while (i < pcie_serdes_spinwait) {
        if (bcma_read32(pi->core, PCIEREGOFFS(mdiocontrol)) &
                MDIOCTL_ACCESS_DONE) {
            if (!write) {
                pr28829_delay();
                *val = (bcma_read32(pi->core,
                                    PCIEREGOFFS(mdiodata)) &
                        MDIODATA_MASK);
            }

            bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol), 0);
            return 0;
        }
        udelay(1000);
        i++;
    }


    bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol), 0);
    return 1;
}
示例#5
0
/* ***** Register Access API */
static uint
pcie_readreg(struct bcma_device *core, uint addrtype, uint offset)
{
	uint retval = 0xFFFFFFFF;

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

	return retval;
}