Beispiel #1
0
/*
 *  nae_gmac_mdio_write -Write sgmac mii PHY register.
 *
 *  Input parameters:
 *         bus          - bus number, nae has two external gmac bus: 0 and 1
 *         phyaddr      - PHY to use
 *         regidx       - register within the PHY
 *         val          - data to write to register
 *
 *  Return value:
 *         0 - success
 */
int
nlm_gmac_mdio_write(uint64_t nae_base, int bus, int block,
    int intf_type, int phyaddr, int regidx, uint16_t val)
{
	uint32_t mdio_ld_cmd;
	uint32_t ctrlval;

	mdio_ld_cmd = nlm_read_nae_reg(nae_base, NAE_REG(block, intf_type,
	    (EXT_G0_MDIO_CTRL + bus * 4)));
	if (mdio_ld_cmd & EXT_G_MDIO_CMD_LCD) {
		nlm_write_nae_reg(nae_base,
		    NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)), 
		    (mdio_ld_cmd & ~EXT_G_MDIO_CMD_LCD));
		while(nlm_read_nae_reg(nae_base,
		    NAE_REG(block, intf_type,
		    (EXT_G0_MDIO_RD_STAT + bus * 4))) &
		    EXT_G_MDIO_STAT_MBSY);
	}

	/* load data into ctrl data reg */
	nlm_write_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL_DATA+bus*4)), 
	    val);

	ctrlval = EXT_G_MDIO_CMD_SP		|
	    (phyaddr << EXT_G_MDIO_PHYADDR_POS)	|
	    (regidx << EXT_G_MDIO_REGADDR_POS);
	if (nlm_is_xlp8xx_ax() || nlm_is_xlp8xx_b0() || nlm_is_xlp3xx_ax())
	    	ctrlval |= EXT_G_MDIO_DIV;
	else
		ctrlval |= EXT_G_MDIO_DIV_WITH_HW_DIV64;

	nlm_write_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)), 
	    ctrlval);

	nlm_write_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)), 
	    ctrlval | EXT_G_MDIO_CMD_LCD);
	DELAY(1000);

	/* poll master busy bit until it is not busy */
	while(nlm_read_nae_reg(nae_base,
	    NAE_REG(block, intf_type,
	    (EXT_G0_MDIO_RD_STAT + bus * 4))) & EXT_G_MDIO_STAT_MBSY);

	nlm_write_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)), 
	    ctrlval);

	return (0);
}
Beispiel #2
0
/* Internal MDIO WRITE Routines */
int
nlm_int_gmac_mdio_write(uint64_t nae_base, int bus, int block,
    int intf_type, int phyaddr, int regidx, uint16_t val)
{
	uint32_t mdio_ld_cmd;
	uint32_t ctrlval;

	ctrlval = INT_MDIO_CTRL_SMP		|
	    (phyaddr << INT_MDIO_CTRL_PHYADDR_POS) |
	    (regidx << INT_MDIO_CTRL_DEVTYPE_POS) |
	    (1 << INT_MDIO_CTRL_OP_POS)		|
	    (1 << INT_MDIO_CTRL_ST_POS)		|
	    (7 << INT_MDIO_CTRL_XDIV_POS)	|
	    (2 << INT_MDIO_CTRL_TA_POS)		|
	    (1 << INT_MDIO_CTRL_MIIM_POS)	|
	    (1 << INT_MDIO_CTRL_MCDIV_POS);

	mdio_ld_cmd = nlm_read_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)));
	if (mdio_ld_cmd & INT_MDIO_CTRL_CMD_LOAD) {
		nlm_write_nae_reg(nae_base,
		    NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus*4)),
		    (mdio_ld_cmd & ~INT_MDIO_CTRL_CMD_LOAD));
	}

	/* load data into ctrl data reg */
	nlm_write_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (INT_MDIO_CTRL_DATA + bus * 4)),
	    val);

	nlm_write_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
	    ctrlval);

	nlm_write_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
	    ctrlval | (1 << INT_MDIO_CTRL_LOAD_POS));

	/* poll master busy bit until it is not busy */
	while(nlm_read_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (INT_MDIO_RD_STAT + bus * 4))) &
	    INT_MDIO_STAT_MBSY) {
	}

	nlm_write_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
	    ctrlval);

	return (0);
}
Beispiel #3
0
/* Internal MDIO READ/WRITE Routines */
int
nlm_int_gmac_mdio_read(uint64_t nae_base, int bus, int block,
    int intf_type, int phyaddr, int regidx)
{
	uint32_t mdio_ld_cmd;
	uint32_t ctrlval;

	ctrlval = INT_MDIO_CTRL_SMP 		|
	    (phyaddr << INT_MDIO_CTRL_PHYADDR_POS) |
	    (regidx << INT_MDIO_CTRL_DEVTYPE_POS) |
	    (2 << INT_MDIO_CTRL_OP_POS)		|
	    (1 << INT_MDIO_CTRL_ST_POS)		|
	    (7 << INT_MDIO_CTRL_XDIV_POS) 	|
	    (2 << INT_MDIO_CTRL_TA_POS)		|
	    (2 << INT_MDIO_CTRL_MIIM_POS) 	|
	    (1 << INT_MDIO_CTRL_MCDIV_POS);

	mdio_ld_cmd = nlm_read_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)));
	if (mdio_ld_cmd & INT_MDIO_CTRL_CMD_LOAD) {
		nlm_write_nae_reg(nae_base,
		    NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus*4)),
		    (mdio_ld_cmd & ~INT_MDIO_CTRL_CMD_LOAD));
	}

	nlm_write_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
	    ctrlval);

	/* Toggle Load Cmd Bit */
	nlm_write_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
	    ctrlval | (1 << INT_MDIO_CTRL_LOAD_POS));

	/* poll master busy bit until it is not busy */
	while(nlm_read_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (INT_MDIO_RD_STAT + bus * 4))) &
	    INT_MDIO_STAT_MBSY) {
	}

	nlm_write_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
	    ctrlval);

	/* Read the data back */
	return nlm_read_nae_reg(nae_base,
	    NAE_REG(block, intf_type, (INT_MDIO_RD_STAT + bus * 4)));
}
Beispiel #4
0
void
nlm_xaui_pcs_init(uint64_t nae_base, int xaui_cplx_mask)
{
	int block, lane_ctrl, reg;
	int cplx_lane_enable;
	int lane_enable = 0;
	uint32_t regval;

	cplx_lane_enable = LM_XAUI |
	    (LM_XAUI << 4) |
	    (LM_XAUI << 8) |
	    (LM_XAUI << 12);

	if (xaui_cplx_mask == 0)
		return;

	/* write 0x2 to enable SGMII for all lane */
	block = 7;

	if (xaui_cplx_mask & 0x3) { /* Complexes 0, 1 */
		lane_enable = nlm_read_nae_reg(nae_base,
		    NAE_REG(block, LANE_CFG, LANE_CFG_CPLX_0_1));
		if (xaui_cplx_mask & 0x1) { /* Complex 0 */
			lane_enable &= ~(0xFFFF);
			lane_enable |= cplx_lane_enable;
		}
		if (xaui_cplx_mask & 0x2) { /* Complex 1 */
			lane_enable &= ~(0xFFFF<<16);
			lane_enable |= (cplx_lane_enable << 16);
		}
		nlm_write_nae_reg(nae_base,
		    NAE_REG(block, LANE_CFG, LANE_CFG_CPLX_0_1),
		    lane_enable);
	}
	lane_enable = 0;
	if (xaui_cplx_mask & 0xc) { /* Complexes 2, 3 */
		lane_enable = nlm_read_nae_reg(nae_base,
		    NAE_REG(block, LANE_CFG, LANE_CFG_CPLX_2_3));
		if (xaui_cplx_mask & 0x4) { /* Complex 2 */
			lane_enable &= ~(0xFFFF);
			lane_enable |= cplx_lane_enable;
		}
		if (xaui_cplx_mask & 0x8) { /* Complex 3 */
			lane_enable &= ~(0xFFFF<<16);
			lane_enable |= (cplx_lane_enable << 16);
		}
		nlm_write_nae_reg(nae_base,
		    NAE_REG(block, LANE_CFG, LANE_CFG_CPLX_2_3),
		    lane_enable);
	}

	/* Bring txpll out of reset */
	for (block = 0; block < 4; block++) {
		if ((xaui_cplx_mask & (1 << block)) == 0)
			continue;

		for (lane_ctrl = PHY_LANE_0_CTRL;
		    lane_ctrl <= PHY_LANE_3_CTRL; lane_ctrl++) {
			if (!nlm_is_xlp8xx_ax())
				xlp_nae_lane_reset_txpll(nae_base,
				    block, lane_ctrl, PHYMODE_XAUI);
			else
				xlp_ax_nae_lane_reset_txpll(nae_base, block,
				    lane_ctrl, PHYMODE_XAUI);
		}
	}

	/* Wait for Rx & TX clock stable */
	for (block = 0; block < 4; block++) {
		if ((xaui_cplx_mask & (1 << block)) == 0)
			continue;

		for (lane_ctrl = PHY_LANE_0_CTRL;
		    lane_ctrl <= PHY_LANE_3_CTRL; lane_ctrl++) {

			reg = NAE_REG(block, PHY, lane_ctrl - 4);
			/* Wait for TX clock to be set */
			do {
				regval = nlm_read_nae_reg(nae_base, reg);
			} while ((regval & LANE_TX_CLK) == 0);

			/* Wait for RX clock to be set */
			do {
				regval = nlm_read_nae_reg(nae_base, reg);
			} while ((regval & LANE_RX_CLK) == 0);

			/* Wait for XAUI Lane fault to be cleared */
			do {
				regval = nlm_read_nae_reg(nae_base, reg);
			} while ((regval & XAUI_LANE_FAULT) != 0);
		}
	}
}