Пример #1
0
int
a10_clk_sata_activate(void)
{
	struct a10_ccm_softc *sc = a10_ccm_sc;
	uint32_t ocfg, ncfg;
	int k;

	if (sc == NULL)
		return (ENXIO);

	/*
	 * SATA needs PLL6 to be a 100MHz clock.
	 */
	ocfg = ccm_read_4(sc, CCM_PLL6_CFG);
	k = SHIFTOUT(ocfg, CCM_PLL_CFG_FACTOR_K);

	/*
	 * Output freq is 24MHz * n * k / m / 6.
	 * To get to 100MHz, k & m must be equal and n must be 25.
	 */
	ncfg = ocfg;
	ncfg &= ~(CCM_PLL_CFG_FACTOR_M | CCM_PLL_CFG_FACTOR_N);
	ncfg &= ~(CCM_PLL_CFG_BYPASS);

	ncfg |= SHIFTIN(k, CCM_PLL_CFG_FACTOR_M);
	ncfg |= SHIFTIN(25, CCM_PLL_CFG_FACTOR_N);

	ncfg |= CCM_PLL_CFG_ENABLE | CCM_PLL6_CFG_SATA_CLK_EN;
	if (ncfg != ocfg)
		ccm_write_4(sc, CCM_PLL6_CFG, ncfg);

	/*
	 * Make sure it's enabled for the AHB.
	 */
	ncfg = ccm_read_4(sc, CCM_AHB_GATING0);
	ncfg |= CCM_AHB_GATING_SATA;
	ccm_write_4(sc, CCM_AHB_GATING0, ncfg);
	DELAY(1000);

	/*
	 * Now turn it on (forcing it to use PLL6).
	 */
	ccm_write_4(sc, CCM_SATA_CLK, CCM_CLK_ENABLE);

	return (0);
}
Пример #2
0
/*
 * Receive data packet
 */
static int
ngfrm_rcvdata(hook_p hook, item_p item)
{
	struct	ctxinfo *const ctxp = NG_HOOK_PRIVATE(hook);
	int     error = 0;
	int     dlci;
	sc_p    sc;
	int     alen;
	char   *data;
	struct mbuf *m;

	/* Data doesn't come in from just anywhere (e.g debug hook) */
	if (ctxp == NULL) {
		error = ENETDOWN;
		goto bad;
	}

	/* If coming from downstream, decode it to a channel */
	dlci = ctxp->dlci;
	if (dlci == -1)
		return (ngfrm_decode(NG_HOOK_NODE(hook), item));

	NGI_GET_M(item, m);
	/* Derive the softc we will need */
	sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));

	/* If there is no live channel, throw it away */
	if ((sc->downstream.hook == NULL)
	    || ((ctxp->flags & CHAN_ACTIVE) == 0)) {
		error = ENETDOWN;
		goto bad;
	}

	/* Store the DLCI on the front of the packet */
	alen = sc->addrlen;
	if (alen == 0)
		alen = 2;	/* default value for transmit */
	M_PREPEND(m, alen, M_DONTWAIT);
	if (m == NULL) {
		error = ENOBUFS;
		goto bad;
	}
	data = mtod(m, char *);

	/*
	 * Shift the lowest bits into the address field untill we are done.
	 * First byte is MSBits of addr so work backwards.
	 */
	switch (alen) {
	case 2:
		data[0] = data[1] = '\0';
		SHIFTOUT(makeup + 1, data[1], dlci);
		SHIFTOUT(makeup + 0, data[0], dlci);
		data[1] |= BYTEX_EA;
		break;
	case 3:
		data[0] = data[1] = data[2] = '\0';
		SHIFTOUT(makeup + 3, data[2], dlci);	/* 3 and 2 is correct */
		SHIFTOUT(makeup + 1, data[1], dlci);
		SHIFTOUT(makeup + 0, data[0], dlci);
		data[2] |= BYTEX_EA;
		break;
	case 4:
		data[0] = data[1] = data[2] = data[3] = '\0';
		SHIFTOUT(makeup + 3, data[3], dlci);
		SHIFTOUT(makeup + 2, data[2], dlci);
		SHIFTOUT(makeup + 1, data[1], dlci);
		SHIFTOUT(makeup + 0, data[0], dlci);
		data[3] |= BYTEX_EA;
		break;
	default:
		panic(__func__);
	}

	/* Send it */
	NG_FWD_NEW_DATA(error, item, sc->downstream.hook, m);
	return (error);

bad:
	NG_FREE_ITEM(item);
	NG_FREE_M(m);
	return (error);
}