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); }
/* * 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); }