diff --git a/sys/arm/allwinner/aw_syscon.c b/sys/arm/allwinner/aw_syscon.c index 3f6e8260c2c9..6a880a9b617e 100644 --- a/sys/arm/allwinner/aw_syscon.c +++ b/sys/arm/allwinner/aw_syscon.c @@ -1,82 +1,82 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2018 Kyle Evans * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Allwinner syscon driver */ #include #include #include #include #include #include #include #include #include #include -#include -#include +#include +#include static struct ofw_compat_data compat_data[] = { {"allwinner,sun50i-a64-system-controller", 1}, {"allwinner,sun50i-a64-system-control", 1}, {"allwinner,sun8i-a83t-system-controller", 1}, {"allwinner,sun8i-h3-system-controller", 1}, {"allwinner,sun8i-h3-system-control", 1}, {"allwinner,sun50i-h5-system-control", 1}, {NULL, 0} }; static int aw_syscon_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "Allwinner syscon"); return (BUS_PROBE_DEFAULT); } static device_method_t aw_syscon_methods[] = { DEVMETHOD(device_probe, aw_syscon_probe), DEVMETHOD_END }; DEFINE_CLASS_1(aw_syscon, aw_syscon_driver, aw_syscon_methods, sizeof(struct syscon_generic_softc), syscon_generic_driver); /* aw_syscon needs to attach prior to if_awg */ EARLY_DRIVER_MODULE(aw_syscon, simplebus, aw_syscon_driver, 0, 0, BUS_PASS_SCHEDULER + BUS_PASS_ORDER_LAST); MODULE_VERSION(aw_syscon, 1); diff --git a/sys/arm/allwinner/if_awg.c b/sys/arm/allwinner/if_awg.c index 9834be083870..29a75e5a4d9b 100644 --- a/sys/arm/allwinner/if_awg.c +++ b/sys/arm/allwinner/if_awg.c @@ -1,2018 +1,2018 @@ /*- * Copyright (c) 2016 Jared McNeill * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Allwinner Gigabit Ethernet MAC (EMAC) controller */ #include "opt_device_polling.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include "syscon_if.h" #include "miibus_if.h" #include "gpio_if.h" #define RD4(sc, reg) bus_read_4((sc)->res[_RES_EMAC], (reg)) #define WR4(sc, reg, val) bus_write_4((sc)->res[_RES_EMAC], (reg), (val)) #define AWG_LOCK(sc) mtx_lock(&(sc)->mtx) #define AWG_UNLOCK(sc) mtx_unlock(&(sc)->mtx); #define AWG_ASSERT_LOCKED(sc) mtx_assert(&(sc)->mtx, MA_OWNED) #define AWG_ASSERT_UNLOCKED(sc) mtx_assert(&(sc)->mtx, MA_NOTOWNED) #define DESC_ALIGN 4 #define TX_DESC_COUNT 1024 #define TX_DESC_SIZE (sizeof(struct emac_desc) * TX_DESC_COUNT) #define RX_DESC_COUNT 256 #define RX_DESC_SIZE (sizeof(struct emac_desc) * RX_DESC_COUNT) #define DESC_OFF(n) ((n) * sizeof(struct emac_desc)) #define TX_NEXT(n) (((n) + 1) & (TX_DESC_COUNT - 1)) #define TX_SKIP(n, o) (((n) + (o)) & (TX_DESC_COUNT - 1)) #define RX_NEXT(n) (((n) + 1) & (RX_DESC_COUNT - 1)) #define TX_MAX_SEGS 20 #define SOFT_RST_RETRY 1000 #define MII_BUSY_RETRY 1000 #define MDIO_FREQ 2500000 #define BURST_LEN_DEFAULT 8 #define RX_TX_PRI_DEFAULT 0 #define PAUSE_TIME_DEFAULT 0x400 #define TX_INTERVAL_DEFAULT 64 #define RX_BATCH_DEFAULT 64 /* syscon EMAC clock register */ #define EMAC_CLK_REG 0x30 #define EMAC_CLK_EPHY_ADDR (0x1f << 20) /* H3 */ #define EMAC_CLK_EPHY_ADDR_SHIFT 20 #define EMAC_CLK_EPHY_LED_POL (1 << 17) /* H3 */ #define EMAC_CLK_EPHY_SHUTDOWN (1 << 16) /* H3 */ #define EMAC_CLK_EPHY_SELECT (1 << 15) /* H3 */ #define EMAC_CLK_RMII_EN (1 << 13) #define EMAC_CLK_ETXDC (0x7 << 10) #define EMAC_CLK_ETXDC_SHIFT 10 #define EMAC_CLK_ERXDC (0x1f << 5) #define EMAC_CLK_ERXDC_SHIFT 5 #define EMAC_CLK_PIT (0x1 << 2) #define EMAC_CLK_PIT_MII (0 << 2) #define EMAC_CLK_PIT_RGMII (1 << 2) #define EMAC_CLK_SRC (0x3 << 0) #define EMAC_CLK_SRC_MII (0 << 0) #define EMAC_CLK_SRC_EXT_RGMII (1 << 0) #define EMAC_CLK_SRC_RGMII (2 << 0) /* Burst length of RX and TX DMA transfers */ static int awg_burst_len = BURST_LEN_DEFAULT; TUNABLE_INT("hw.awg.burst_len", &awg_burst_len); /* RX / TX DMA priority. If 1, RX DMA has priority over TX DMA. */ static int awg_rx_tx_pri = RX_TX_PRI_DEFAULT; TUNABLE_INT("hw.awg.rx_tx_pri", &awg_rx_tx_pri); /* Pause time field in the transmitted control frame */ static int awg_pause_time = PAUSE_TIME_DEFAULT; TUNABLE_INT("hw.awg.pause_time", &awg_pause_time); /* Request a TX interrupt every descriptors */ static int awg_tx_interval = TX_INTERVAL_DEFAULT; TUNABLE_INT("hw.awg.tx_interval", &awg_tx_interval); /* Maximum number of mbufs to send to if_input */ static int awg_rx_batch = RX_BATCH_DEFAULT; TUNABLE_INT("hw.awg.rx_batch", &awg_rx_batch); enum awg_type { EMAC_A83T = 1, EMAC_H3, EMAC_A64, }; static struct ofw_compat_data compat_data[] = { { "allwinner,sun8i-a83t-emac", EMAC_A83T }, { "allwinner,sun8i-h3-emac", EMAC_H3 }, { "allwinner,sun50i-a64-emac", EMAC_A64 }, { NULL, 0 } }; struct awg_bufmap { bus_dmamap_t map; struct mbuf *mbuf; }; struct awg_txring { bus_dma_tag_t desc_tag; bus_dmamap_t desc_map; struct emac_desc *desc_ring; bus_addr_t desc_ring_paddr; bus_dma_tag_t buf_tag; struct awg_bufmap buf_map[TX_DESC_COUNT]; u_int cur, next, queued; u_int segs; }; struct awg_rxring { bus_dma_tag_t desc_tag; bus_dmamap_t desc_map; struct emac_desc *desc_ring; bus_addr_t desc_ring_paddr; bus_dma_tag_t buf_tag; struct awg_bufmap buf_map[RX_DESC_COUNT]; bus_dmamap_t buf_spare_map; u_int cur; }; enum { _RES_EMAC, _RES_IRQ, _RES_SYSCON, _RES_NITEMS }; struct awg_softc { struct resource *res[_RES_NITEMS]; struct mtx mtx; if_t ifp; device_t dev; device_t miibus; struct callout stat_ch; void *ih; u_int mdc_div_ratio_m; int link; int if_flags; enum awg_type type; struct syscon *syscon; struct awg_txring tx; struct awg_rxring rx; }; static struct resource_spec awg_spec[] = { { SYS_RES_MEMORY, 0, RF_ACTIVE }, { SYS_RES_IRQ, 0, RF_ACTIVE }, { SYS_RES_MEMORY, 1, RF_ACTIVE | RF_OPTIONAL }, { -1, 0 } }; static void awg_txeof(struct awg_softc *sc); static void awg_start_locked(struct awg_softc *sc); static void awg_tick(void *softc); static int awg_parse_delay(device_t dev, uint32_t *tx_delay, uint32_t *rx_delay); static uint32_t syscon_read_emac_clk_reg(device_t dev); static void syscon_write_emac_clk_reg(device_t dev, uint32_t val); static phandle_t awg_get_phy_node(device_t dev); static bool awg_has_internal_phy(device_t dev); /* * MII functions */ static int awg_miibus_readreg(device_t dev, int phy, int reg) { struct awg_softc *sc; int retry, val; sc = device_get_softc(dev); val = 0; WR4(sc, EMAC_MII_CMD, (sc->mdc_div_ratio_m << MDC_DIV_RATIO_M_SHIFT) | (phy << PHY_ADDR_SHIFT) | (reg << PHY_REG_ADDR_SHIFT) | MII_BUSY); for (retry = MII_BUSY_RETRY; retry > 0; retry--) { if ((RD4(sc, EMAC_MII_CMD) & MII_BUSY) == 0) { val = RD4(sc, EMAC_MII_DATA); break; } DELAY(10); } if (retry == 0) device_printf(dev, "phy read timeout, phy=%d reg=%d\n", phy, reg); return (val); } static int awg_miibus_writereg(device_t dev, int phy, int reg, int val) { struct awg_softc *sc; int retry; sc = device_get_softc(dev); WR4(sc, EMAC_MII_DATA, val); WR4(sc, EMAC_MII_CMD, (sc->mdc_div_ratio_m << MDC_DIV_RATIO_M_SHIFT) | (phy << PHY_ADDR_SHIFT) | (reg << PHY_REG_ADDR_SHIFT) | MII_WR | MII_BUSY); for (retry = MII_BUSY_RETRY; retry > 0; retry--) { if ((RD4(sc, EMAC_MII_CMD) & MII_BUSY) == 0) break; DELAY(10); } if (retry == 0) device_printf(dev, "phy write timeout, phy=%d reg=%d\n", phy, reg); return (0); } static void awg_miibus_statchg(device_t dev) { struct awg_softc *sc; struct mii_data *mii; uint32_t val; sc = device_get_softc(dev); AWG_ASSERT_LOCKED(sc); if ((if_getdrvflags(sc->ifp) & IFF_DRV_RUNNING) == 0) return; mii = device_get_softc(sc->miibus); if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == (IFM_ACTIVE | IFM_AVALID)) { switch (IFM_SUBTYPE(mii->mii_media_active)) { case IFM_1000_T: case IFM_1000_SX: case IFM_100_TX: case IFM_10_T: sc->link = 1; break; default: sc->link = 0; break; } } else sc->link = 0; if (sc->link == 0) return; val = RD4(sc, EMAC_BASIC_CTL_0); val &= ~(BASIC_CTL_SPEED | BASIC_CTL_DUPLEX); if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T || IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX) val |= BASIC_CTL_SPEED_1000 << BASIC_CTL_SPEED_SHIFT; else if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) val |= BASIC_CTL_SPEED_100 << BASIC_CTL_SPEED_SHIFT; else val |= BASIC_CTL_SPEED_10 << BASIC_CTL_SPEED_SHIFT; if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) val |= BASIC_CTL_DUPLEX; WR4(sc, EMAC_BASIC_CTL_0, val); val = RD4(sc, EMAC_RX_CTL_0); val &= ~RX_FLOW_CTL_EN; if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0) val |= RX_FLOW_CTL_EN; WR4(sc, EMAC_RX_CTL_0, val); val = RD4(sc, EMAC_TX_FLOW_CTL); val &= ~(PAUSE_TIME|TX_FLOW_CTL_EN); if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0) val |= TX_FLOW_CTL_EN; if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) val |= awg_pause_time << PAUSE_TIME_SHIFT; WR4(sc, EMAC_TX_FLOW_CTL, val); } /* * Media functions */ static void awg_media_status(if_t ifp, struct ifmediareq *ifmr) { struct awg_softc *sc; struct mii_data *mii; sc = if_getsoftc(ifp); mii = device_get_softc(sc->miibus); AWG_LOCK(sc); mii_pollstat(mii); ifmr->ifm_active = mii->mii_media_active; ifmr->ifm_status = mii->mii_media_status; AWG_UNLOCK(sc); } static int awg_media_change(if_t ifp) { struct awg_softc *sc; struct mii_data *mii; int error; sc = if_getsoftc(ifp); mii = device_get_softc(sc->miibus); AWG_LOCK(sc); error = mii_mediachg(mii); AWG_UNLOCK(sc); return (error); } /* * Core functions */ /* Bit Reversal - http://aggregate.org/MAGIC/#Bit%20Reversal */ static uint32_t bitrev32(uint32_t x) { x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1)); x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2)); x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4)); x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8)); return (x >> 16) | (x << 16); } static u_int awg_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt) { uint32_t crc, hashreg, hashbit, *hash = arg; crc = ether_crc32_le(LLADDR(sdl), ETHER_ADDR_LEN) & 0x7f; crc = bitrev32(~crc) >> 26; hashreg = (crc >> 5); hashbit = (crc & 0x1f); hash[hashreg] |= (1 << hashbit); return (1); } static void awg_setup_rxfilter(struct awg_softc *sc) { uint32_t val, hash[2], machi, maclo; uint8_t *eaddr; if_t ifp; AWG_ASSERT_LOCKED(sc); ifp = sc->ifp; val = 0; hash[0] = hash[1] = 0; if (if_getflags(ifp) & IFF_PROMISC) val |= DIS_ADDR_FILTER; else if (if_getflags(ifp) & IFF_ALLMULTI) { val |= RX_ALL_MULTICAST; hash[0] = hash[1] = ~0; } else if (if_foreach_llmaddr(ifp, awg_hash_maddr, hash) > 0) val |= HASH_MULTICAST; /* Write our unicast address */ eaddr = if_getlladdr(ifp); machi = (eaddr[5] << 8) | eaddr[4]; maclo = (eaddr[3] << 24) | (eaddr[2] << 16) | (eaddr[1] << 8) | (eaddr[0] << 0); WR4(sc, EMAC_ADDR_HIGH(0), machi); WR4(sc, EMAC_ADDR_LOW(0), maclo); /* Multicast hash filters */ WR4(sc, EMAC_RX_HASH_0, hash[1]); WR4(sc, EMAC_RX_HASH_1, hash[0]); /* RX frame filter config */ WR4(sc, EMAC_RX_FRM_FLT, val); } static void awg_setup_core(struct awg_softc *sc) { uint32_t val; AWG_ASSERT_LOCKED(sc); /* Configure DMA burst length and priorities */ val = awg_burst_len << BASIC_CTL_BURST_LEN_SHIFT; if (awg_rx_tx_pri) val |= BASIC_CTL_RX_TX_PRI; WR4(sc, EMAC_BASIC_CTL_1, val); } static void awg_enable_mac(struct awg_softc *sc, bool enable) { uint32_t tx, rx; AWG_ASSERT_LOCKED(sc); tx = RD4(sc, EMAC_TX_CTL_0); rx = RD4(sc, EMAC_RX_CTL_0); if (enable) { tx |= TX_EN; rx |= RX_EN | CHECK_CRC; } else { tx &= ~TX_EN; rx &= ~(RX_EN | CHECK_CRC); } WR4(sc, EMAC_TX_CTL_0, tx); WR4(sc, EMAC_RX_CTL_0, rx); } static void awg_get_eaddr(device_t dev, uint8_t *eaddr) { struct awg_softc *sc; uint32_t maclo, machi, rnd; u_char rootkey[16]; uint32_t rootkey_size; sc = device_get_softc(dev); machi = RD4(sc, EMAC_ADDR_HIGH(0)) & 0xffff; maclo = RD4(sc, EMAC_ADDR_LOW(0)); rootkey_size = sizeof(rootkey); if (maclo == 0xffffffff && machi == 0xffff) { /* MAC address in hardware is invalid, create one */ if (aw_sid_get_fuse(AW_SID_FUSE_ROOTKEY, rootkey, &rootkey_size) == 0 && (rootkey[3] | rootkey[12] | rootkey[13] | rootkey[14] | rootkey[15]) != 0) { /* MAC address is derived from the root key in SID */ maclo = (rootkey[13] << 24) | (rootkey[12] << 16) | (rootkey[3] << 8) | 0x02; machi = (rootkey[15] << 8) | rootkey[14]; } else { /* Create one */ rnd = arc4random(); maclo = 0x00f2 | (rnd & 0xffff0000); machi = rnd & 0xffff; } } eaddr[0] = maclo & 0xff; eaddr[1] = (maclo >> 8) & 0xff; eaddr[2] = (maclo >> 16) & 0xff; eaddr[3] = (maclo >> 24) & 0xff; eaddr[4] = machi & 0xff; eaddr[5] = (machi >> 8) & 0xff; } /* * DMA functions */ static void awg_enable_dma_intr(struct awg_softc *sc) { /* Enable interrupts */ WR4(sc, EMAC_INT_EN, RX_INT_EN | TX_INT_EN | TX_BUF_UA_INT_EN); } static void awg_disable_dma_intr(struct awg_softc *sc) { /* Disable interrupts */ WR4(sc, EMAC_INT_EN, 0); } static void awg_init_dma(struct awg_softc *sc) { uint32_t val; AWG_ASSERT_LOCKED(sc); /* Enable interrupts */ #ifdef DEVICE_POLLING if ((if_getcapenable(sc->ifp) & IFCAP_POLLING) == 0) awg_enable_dma_intr(sc); else awg_disable_dma_intr(sc); #else awg_enable_dma_intr(sc); #endif /* Enable transmit DMA */ val = RD4(sc, EMAC_TX_CTL_1); WR4(sc, EMAC_TX_CTL_1, val | TX_DMA_EN | TX_MD | TX_NEXT_FRAME); /* Enable receive DMA */ val = RD4(sc, EMAC_RX_CTL_1); WR4(sc, EMAC_RX_CTL_1, val | RX_DMA_EN | RX_MD); } static void awg_stop_dma(struct awg_softc *sc) { uint32_t val; AWG_ASSERT_LOCKED(sc); /* Stop transmit DMA and flush data in the TX FIFO */ val = RD4(sc, EMAC_TX_CTL_1); val &= ~TX_DMA_EN; val |= FLUSH_TX_FIFO; WR4(sc, EMAC_TX_CTL_1, val); /* Disable interrupts */ awg_disable_dma_intr(sc); /* Disable transmit DMA */ val = RD4(sc, EMAC_TX_CTL_1); WR4(sc, EMAC_TX_CTL_1, val & ~TX_DMA_EN); /* Disable receive DMA */ val = RD4(sc, EMAC_RX_CTL_1); WR4(sc, EMAC_RX_CTL_1, val & ~RX_DMA_EN); } static int awg_encap(struct awg_softc *sc, struct mbuf **mp) { bus_dmamap_t map; bus_dma_segment_t segs[TX_MAX_SEGS]; int error, nsegs, cur, first, last, i; u_int csum_flags; uint32_t flags, status; struct mbuf *m; cur = first = sc->tx.cur; map = sc->tx.buf_map[first].map; m = *mp; error = bus_dmamap_load_mbuf_sg(sc->tx.buf_tag, map, m, segs, &nsegs, BUS_DMA_NOWAIT); if (error == EFBIG) { m = m_collapse(m, M_NOWAIT, TX_MAX_SEGS); if (m == NULL) { device_printf(sc->dev, "awg_encap: m_collapse failed\n"); m_freem(*mp); *mp = NULL; return (ENOMEM); } *mp = m; error = bus_dmamap_load_mbuf_sg(sc->tx.buf_tag, map, m, segs, &nsegs, BUS_DMA_NOWAIT); if (error != 0) { m_freem(*mp); *mp = NULL; } } if (error != 0) { device_printf(sc->dev, "awg_encap: bus_dmamap_load_mbuf_sg failed\n"); return (error); } if (nsegs == 0) { m_freem(*mp); *mp = NULL; return (EIO); } if (sc->tx.queued + nsegs > TX_DESC_COUNT) { bus_dmamap_unload(sc->tx.buf_tag, map); return (ENOBUFS); } bus_dmamap_sync(sc->tx.buf_tag, map, BUS_DMASYNC_PREWRITE); flags = TX_FIR_DESC; status = 0; if ((m->m_pkthdr.csum_flags & CSUM_IP) != 0) { if ((m->m_pkthdr.csum_flags & (CSUM_TCP|CSUM_UDP)) != 0) csum_flags = TX_CHECKSUM_CTL_FULL; else csum_flags = TX_CHECKSUM_CTL_IP; flags |= (csum_flags << TX_CHECKSUM_CTL_SHIFT); } for (i = 0; i < nsegs; i++) { sc->tx.segs++; if (i == nsegs - 1) { flags |= TX_LAST_DESC; /* * Can only request TX completion * interrupt on last descriptor. */ if (sc->tx.segs >= awg_tx_interval) { sc->tx.segs = 0; flags |= TX_INT_CTL; } } sc->tx.desc_ring[cur].addr = htole32((uint32_t)segs[i].ds_addr); sc->tx.desc_ring[cur].size = htole32(flags | segs[i].ds_len); sc->tx.desc_ring[cur].status = htole32(status); flags &= ~TX_FIR_DESC; /* * Setting of the valid bit in the first descriptor is * deferred until the whole chain is fully set up. */ status = TX_DESC_CTL; ++sc->tx.queued; cur = TX_NEXT(cur); } sc->tx.cur = cur; /* Store mapping and mbuf in the last segment */ last = TX_SKIP(cur, TX_DESC_COUNT - 1); sc->tx.buf_map[first].map = sc->tx.buf_map[last].map; sc->tx.buf_map[last].map = map; sc->tx.buf_map[last].mbuf = m; /* * The whole mbuf chain has been DMA mapped, * fix the first descriptor. */ sc->tx.desc_ring[first].status = htole32(TX_DESC_CTL); return (0); } static void awg_clean_txbuf(struct awg_softc *sc, int index) { struct awg_bufmap *bmap; --sc->tx.queued; bmap = &sc->tx.buf_map[index]; if (bmap->mbuf != NULL) { bus_dmamap_sync(sc->tx.buf_tag, bmap->map, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->tx.buf_tag, bmap->map); m_freem(bmap->mbuf); bmap->mbuf = NULL; } } static void awg_setup_rxdesc(struct awg_softc *sc, int index, bus_addr_t paddr) { uint32_t status, size; status = RX_DESC_CTL; size = MCLBYTES - 1; sc->rx.desc_ring[index].addr = htole32((uint32_t)paddr); sc->rx.desc_ring[index].size = htole32(size); sc->rx.desc_ring[index].status = htole32(status); } static void awg_reuse_rxdesc(struct awg_softc *sc, int index) { sc->rx.desc_ring[index].status = htole32(RX_DESC_CTL); } static int awg_newbuf_rx(struct awg_softc *sc, int index) { struct mbuf *m; bus_dma_segment_t seg; bus_dmamap_t map; int nsegs; m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (m == NULL) return (ENOBUFS); m->m_pkthdr.len = m->m_len = m->m_ext.ext_size; m_adj(m, ETHER_ALIGN); if (bus_dmamap_load_mbuf_sg(sc->rx.buf_tag, sc->rx.buf_spare_map, m, &seg, &nsegs, BUS_DMA_NOWAIT) != 0) { m_freem(m); return (ENOBUFS); } if (sc->rx.buf_map[index].mbuf != NULL) { bus_dmamap_sync(sc->rx.buf_tag, sc->rx.buf_map[index].map, BUS_DMASYNC_POSTREAD); bus_dmamap_unload(sc->rx.buf_tag, sc->rx.buf_map[index].map); } map = sc->rx.buf_map[index].map; sc->rx.buf_map[index].map = sc->rx.buf_spare_map; sc->rx.buf_spare_map = map; bus_dmamap_sync(sc->rx.buf_tag, sc->rx.buf_map[index].map, BUS_DMASYNC_PREREAD); sc->rx.buf_map[index].mbuf = m; awg_setup_rxdesc(sc, index, seg.ds_addr); return (0); } static void awg_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) { if (error != 0) return; *(bus_addr_t *)arg = segs[0].ds_addr; } static int awg_setup_dma(device_t dev) { struct awg_softc *sc; int error, i; sc = device_get_softc(dev); /* Setup TX ring */ error = bus_dma_tag_create( bus_get_dma_tag(dev), /* Parent tag */ DESC_ALIGN, 0, /* alignment, boundary */ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ TX_DESC_SIZE, 1, /* maxsize, nsegs */ TX_DESC_SIZE, /* maxsegsize */ 0, /* flags */ NULL, NULL, /* lockfunc, lockarg */ &sc->tx.desc_tag); if (error != 0) { device_printf(dev, "cannot create TX descriptor ring tag\n"); return (error); } error = bus_dmamem_alloc(sc->tx.desc_tag, (void **)&sc->tx.desc_ring, BUS_DMA_COHERENT | BUS_DMA_WAITOK | BUS_DMA_ZERO, &sc->tx.desc_map); if (error != 0) { device_printf(dev, "cannot allocate TX descriptor ring\n"); return (error); } error = bus_dmamap_load(sc->tx.desc_tag, sc->tx.desc_map, sc->tx.desc_ring, TX_DESC_SIZE, awg_dmamap_cb, &sc->tx.desc_ring_paddr, 0); if (error != 0) { device_printf(dev, "cannot load TX descriptor ring\n"); return (error); } for (i = 0; i < TX_DESC_COUNT; i++) sc->tx.desc_ring[i].next = htole32(sc->tx.desc_ring_paddr + DESC_OFF(TX_NEXT(i))); error = bus_dma_tag_create( bus_get_dma_tag(dev), /* Parent tag */ 1, 0, /* alignment, boundary */ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ MCLBYTES, TX_MAX_SEGS, /* maxsize, nsegs */ MCLBYTES, /* maxsegsize */ 0, /* flags */ NULL, NULL, /* lockfunc, lockarg */ &sc->tx.buf_tag); if (error != 0) { device_printf(dev, "cannot create TX buffer tag\n"); return (error); } sc->tx.queued = 0; for (i = 0; i < TX_DESC_COUNT; i++) { error = bus_dmamap_create(sc->tx.buf_tag, 0, &sc->tx.buf_map[i].map); if (error != 0) { device_printf(dev, "cannot create TX buffer map\n"); return (error); } } /* Setup RX ring */ error = bus_dma_tag_create( bus_get_dma_tag(dev), /* Parent tag */ DESC_ALIGN, 0, /* alignment, boundary */ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ RX_DESC_SIZE, 1, /* maxsize, nsegs */ RX_DESC_SIZE, /* maxsegsize */ 0, /* flags */ NULL, NULL, /* lockfunc, lockarg */ &sc->rx.desc_tag); if (error != 0) { device_printf(dev, "cannot create RX descriptor ring tag\n"); return (error); } error = bus_dmamem_alloc(sc->rx.desc_tag, (void **)&sc->rx.desc_ring, BUS_DMA_COHERENT | BUS_DMA_WAITOK | BUS_DMA_ZERO, &sc->rx.desc_map); if (error != 0) { device_printf(dev, "cannot allocate RX descriptor ring\n"); return (error); } error = bus_dmamap_load(sc->rx.desc_tag, sc->rx.desc_map, sc->rx.desc_ring, RX_DESC_SIZE, awg_dmamap_cb, &sc->rx.desc_ring_paddr, 0); if (error != 0) { device_printf(dev, "cannot load RX descriptor ring\n"); return (error); } error = bus_dma_tag_create( bus_get_dma_tag(dev), /* Parent tag */ 1, 0, /* alignment, boundary */ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ MCLBYTES, 1, /* maxsize, nsegs */ MCLBYTES, /* maxsegsize */ 0, /* flags */ NULL, NULL, /* lockfunc, lockarg */ &sc->rx.buf_tag); if (error != 0) { device_printf(dev, "cannot create RX buffer tag\n"); return (error); } error = bus_dmamap_create(sc->rx.buf_tag, 0, &sc->rx.buf_spare_map); if (error != 0) { device_printf(dev, "cannot create RX buffer spare map\n"); return (error); } for (i = 0; i < RX_DESC_COUNT; i++) { sc->rx.desc_ring[i].next = htole32(sc->rx.desc_ring_paddr + DESC_OFF(RX_NEXT(i))); error = bus_dmamap_create(sc->rx.buf_tag, 0, &sc->rx.buf_map[i].map); if (error != 0) { device_printf(dev, "cannot create RX buffer map\n"); return (error); } sc->rx.buf_map[i].mbuf = NULL; error = awg_newbuf_rx(sc, i); if (error != 0) { device_printf(dev, "cannot create RX buffer\n"); return (error); } } bus_dmamap_sync(sc->rx.desc_tag, sc->rx.desc_map, BUS_DMASYNC_PREWRITE); /* Write transmit and receive descriptor base address registers */ WR4(sc, EMAC_TX_DMA_LIST, sc->tx.desc_ring_paddr); WR4(sc, EMAC_RX_DMA_LIST, sc->rx.desc_ring_paddr); return (0); } static void awg_dma_start_tx(struct awg_softc *sc) { uint32_t val; AWG_ASSERT_LOCKED(sc); /* Start and run TX DMA */ val = RD4(sc, EMAC_TX_CTL_1); WR4(sc, EMAC_TX_CTL_1, val | TX_DMA_START); } /* * if_ functions */ static void awg_start_locked(struct awg_softc *sc) { struct mbuf *m; if_t ifp; int cnt, err; AWG_ASSERT_LOCKED(sc); if (!sc->link) return; ifp = sc->ifp; if ((if_getdrvflags(ifp) & (IFF_DRV_RUNNING|IFF_DRV_OACTIVE)) != IFF_DRV_RUNNING) return; for (cnt = 0; ; cnt++) { m = if_dequeue(ifp); if (m == NULL) break; err = awg_encap(sc, &m); if (err != 0) { if (err == ENOBUFS) if_setdrvflagbits(ifp, IFF_DRV_OACTIVE, 0); if (m != NULL) if_sendq_prepend(ifp, m); break; } bpf_mtap_if(ifp, m); } if (cnt != 0) { bus_dmamap_sync(sc->tx.desc_tag, sc->tx.desc_map, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); awg_dma_start_tx(sc); } } static void awg_start(if_t ifp) { struct awg_softc *sc; sc = if_getsoftc(ifp); AWG_LOCK(sc); awg_start_locked(sc); AWG_UNLOCK(sc); } static void awg_init_locked(struct awg_softc *sc) { struct mii_data *mii; if_t ifp; mii = device_get_softc(sc->miibus); ifp = sc->ifp; AWG_ASSERT_LOCKED(sc); if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) return; awg_setup_rxfilter(sc); awg_setup_core(sc); awg_enable_mac(sc, true); awg_init_dma(sc); if_setdrvflagbits(ifp, IFF_DRV_RUNNING, IFF_DRV_OACTIVE); mii_mediachg(mii); callout_reset(&sc->stat_ch, hz, awg_tick, sc); } static void awg_init(void *softc) { struct awg_softc *sc; sc = softc; AWG_LOCK(sc); awg_init_locked(sc); AWG_UNLOCK(sc); } static void awg_stop(struct awg_softc *sc) { if_t ifp; uint32_t val; int i; AWG_ASSERT_LOCKED(sc); ifp = sc->ifp; callout_stop(&sc->stat_ch); awg_stop_dma(sc); awg_enable_mac(sc, false); sc->link = 0; /* Finish handling transmitted buffers */ awg_txeof(sc); /* Release any untransmitted buffers. */ for (i = sc->tx.next; sc->tx.queued > 0; i = TX_NEXT(i)) { val = le32toh(sc->tx.desc_ring[i].status); if ((val & TX_DESC_CTL) != 0) break; awg_clean_txbuf(sc, i); } sc->tx.next = i; for (; sc->tx.queued > 0; i = TX_NEXT(i)) { sc->tx.desc_ring[i].status = 0; awg_clean_txbuf(sc, i); } sc->tx.cur = sc->tx.next; bus_dmamap_sync(sc->tx.desc_tag, sc->tx.desc_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); /* Setup RX buffers for reuse */ bus_dmamap_sync(sc->rx.desc_tag, sc->rx.desc_map, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); for (i = sc->rx.cur; ; i = RX_NEXT(i)) { val = le32toh(sc->rx.desc_ring[i].status); if ((val & RX_DESC_CTL) != 0) break; awg_reuse_rxdesc(sc, i); } sc->rx.cur = i; bus_dmamap_sync(sc->rx.desc_tag, sc->rx.desc_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); if_setdrvflagbits(ifp, 0, IFF_DRV_RUNNING | IFF_DRV_OACTIVE); } static int awg_ioctl(if_t ifp, u_long cmd, caddr_t data) { struct awg_softc *sc; struct mii_data *mii; struct ifreq *ifr; int flags, mask, error; sc = if_getsoftc(ifp); mii = device_get_softc(sc->miibus); ifr = (struct ifreq *)data; error = 0; switch (cmd) { case SIOCSIFFLAGS: AWG_LOCK(sc); if (if_getflags(ifp) & IFF_UP) { if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) { flags = if_getflags(ifp) ^ sc->if_flags; if ((flags & (IFF_PROMISC|IFF_ALLMULTI)) != 0) awg_setup_rxfilter(sc); } else awg_init_locked(sc); } else { if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) awg_stop(sc); } sc->if_flags = if_getflags(ifp); AWG_UNLOCK(sc); break; case SIOCADDMULTI: case SIOCDELMULTI: if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) { AWG_LOCK(sc); awg_setup_rxfilter(sc); AWG_UNLOCK(sc); } break; case SIOCSIFMEDIA: case SIOCGIFMEDIA: error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd); break; case SIOCSIFCAP: mask = ifr->ifr_reqcap ^ if_getcapenable(ifp); #ifdef DEVICE_POLLING if (mask & IFCAP_POLLING) { if ((ifr->ifr_reqcap & IFCAP_POLLING) != 0) { error = ether_poll_register(awg_poll, ifp); if (error != 0) break; AWG_LOCK(sc); awg_disable_dma_intr(sc); if_setcapenablebit(ifp, IFCAP_POLLING, 0); AWG_UNLOCK(sc); } else { error = ether_poll_deregister(ifp); AWG_LOCK(sc); awg_enable_dma_intr(sc); if_setcapenablebit(ifp, 0, IFCAP_POLLING); AWG_UNLOCK(sc); } } #endif if (mask & IFCAP_VLAN_MTU) if_togglecapenable(ifp, IFCAP_VLAN_MTU); if (mask & IFCAP_RXCSUM) if_togglecapenable(ifp, IFCAP_RXCSUM); if (mask & IFCAP_TXCSUM) if_togglecapenable(ifp, IFCAP_TXCSUM); if ((if_getcapenable(ifp) & IFCAP_TXCSUM) != 0) if_sethwassistbits(ifp, CSUM_IP | CSUM_UDP | CSUM_TCP, 0); else if_sethwassistbits(ifp, 0, CSUM_IP | CSUM_UDP | CSUM_TCP); break; default: error = ether_ioctl(ifp, cmd, data); break; } return (error); } /* * Interrupts functions */ static int awg_rxintr(struct awg_softc *sc) { if_t ifp; struct mbuf *m, *mh, *mt; int error, index, len, cnt, npkt; uint32_t status; ifp = sc->ifp; mh = mt = NULL; cnt = 0; npkt = 0; bus_dmamap_sync(sc->rx.desc_tag, sc->rx.desc_map, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); for (index = sc->rx.cur; ; index = RX_NEXT(index)) { status = le32toh(sc->rx.desc_ring[index].status); if ((status & RX_DESC_CTL) != 0) break; len = (status & RX_FRM_LEN) >> RX_FRM_LEN_SHIFT; if (len == 0) { if ((status & (RX_NO_ENOUGH_BUF_ERR | RX_OVERFLOW_ERR)) != 0) if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); awg_reuse_rxdesc(sc, index); continue; } m = sc->rx.buf_map[index].mbuf; error = awg_newbuf_rx(sc, index); if (error != 0) { if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1); awg_reuse_rxdesc(sc, index); continue; } m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = len; m->m_len = len; if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); if ((if_getcapenable(ifp) & IFCAP_RXCSUM) != 0 && (status & RX_FRM_TYPE) != 0) { m->m_pkthdr.csum_flags = CSUM_IP_CHECKED; if ((status & RX_HEADER_ERR) == 0) m->m_pkthdr.csum_flags |= CSUM_IP_VALID; if ((status & RX_PAYLOAD_ERR) == 0) { m->m_pkthdr.csum_flags |= CSUM_DATA_VALID | CSUM_PSEUDO_HDR; m->m_pkthdr.csum_data = 0xffff; } } m->m_nextpkt = NULL; if (mh == NULL) mh = m; else mt->m_nextpkt = m; mt = m; ++cnt; ++npkt; if (cnt == awg_rx_batch) { AWG_UNLOCK(sc); if_input(ifp, mh); AWG_LOCK(sc); mh = mt = NULL; cnt = 0; } } if (index != sc->rx.cur) { bus_dmamap_sync(sc->rx.desc_tag, sc->rx.desc_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); } if (mh != NULL) { AWG_UNLOCK(sc); if_input(ifp, mh); AWG_LOCK(sc); } sc->rx.cur = index; return (npkt); } static void awg_txeof(struct awg_softc *sc) { struct emac_desc *desc; uint32_t status, size; if_t ifp; int i, prog; AWG_ASSERT_LOCKED(sc); bus_dmamap_sync(sc->tx.desc_tag, sc->tx.desc_map, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); ifp = sc->ifp; prog = 0; for (i = sc->tx.next; sc->tx.queued > 0; i = TX_NEXT(i)) { desc = &sc->tx.desc_ring[i]; status = le32toh(desc->status); if ((status & TX_DESC_CTL) != 0) break; size = le32toh(desc->size); if (size & TX_LAST_DESC) { if ((status & (TX_HEADER_ERR | TX_PAYLOAD_ERR)) != 0) if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); else if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); } prog++; awg_clean_txbuf(sc, i); } if (prog > 0) { sc->tx.next = i; if_setdrvflagbits(ifp, 0, IFF_DRV_OACTIVE); } } static void awg_intr(void *arg) { struct awg_softc *sc; uint32_t val; sc = arg; AWG_LOCK(sc); val = RD4(sc, EMAC_INT_STA); WR4(sc, EMAC_INT_STA, val); if (val & RX_INT) awg_rxintr(sc); if (val & TX_INT) awg_txeof(sc); if (val & (TX_INT | TX_BUF_UA_INT)) { if (!if_sendq_empty(sc->ifp)) awg_start_locked(sc); } AWG_UNLOCK(sc); } #ifdef DEVICE_POLLING static int awg_poll(if_t ifp, enum poll_cmd cmd, int count) { struct awg_softc *sc; uint32_t val; int rx_npkts; sc = if_getsoftc(ifp); rx_npkts = 0; AWG_LOCK(sc); if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0) { AWG_UNLOCK(sc); return (0); } rx_npkts = awg_rxintr(sc); awg_txeof(sc); if (!if_sendq_empty(ifp)) awg_start_locked(sc); if (cmd == POLL_AND_CHECK_STATUS) { val = RD4(sc, EMAC_INT_STA); if (val != 0) WR4(sc, EMAC_INT_STA, val); } AWG_UNLOCK(sc); return (rx_npkts); } #endif /* * syscon functions */ static uint32_t syscon_read_emac_clk_reg(device_t dev) { struct awg_softc *sc; sc = device_get_softc(dev); if (sc->syscon != NULL) return (SYSCON_READ_4(sc->syscon, EMAC_CLK_REG)); else if (sc->res[_RES_SYSCON] != NULL) return (bus_read_4(sc->res[_RES_SYSCON], 0)); return (0); } static void syscon_write_emac_clk_reg(device_t dev, uint32_t val) { struct awg_softc *sc; sc = device_get_softc(dev); if (sc->syscon != NULL) SYSCON_WRITE_4(sc->syscon, EMAC_CLK_REG, val); else if (sc->res[_RES_SYSCON] != NULL) bus_write_4(sc->res[_RES_SYSCON], 0, val); } /* * PHY functions */ static phandle_t awg_get_phy_node(device_t dev) { phandle_t node; pcell_t phy_handle; node = ofw_bus_get_node(dev); if (OF_getencprop(node, "phy-handle", (void *)&phy_handle, sizeof(phy_handle)) <= 0) return (0); return (OF_node_from_xref(phy_handle)); } static bool awg_has_internal_phy(device_t dev) { phandle_t node, phy_node; node = ofw_bus_get_node(dev); /* Legacy binding */ if (OF_hasprop(node, "allwinner,use-internal-phy")) return (true); phy_node = awg_get_phy_node(dev); return (phy_node != 0 && ofw_bus_node_is_compatible(OF_parent(phy_node), "allwinner,sun8i-h3-mdio-internal") != 0); } static int awg_parse_delay(device_t dev, uint32_t *tx_delay, uint32_t *rx_delay) { phandle_t node; uint32_t delay; if (tx_delay == NULL || rx_delay == NULL) return (EINVAL); *tx_delay = *rx_delay = 0; node = ofw_bus_get_node(dev); if (OF_getencprop(node, "tx-delay", &delay, sizeof(delay)) >= 0) *tx_delay = delay; else if (OF_getencprop(node, "allwinner,tx-delay-ps", &delay, sizeof(delay)) >= 0) { if ((delay % 100) != 0) { device_printf(dev, "tx-delay-ps is not a multiple of 100\n"); return (EDOM); } *tx_delay = delay / 100; } if (*tx_delay > 7) { device_printf(dev, "tx-delay out of range\n"); return (ERANGE); } if (OF_getencprop(node, "rx-delay", &delay, sizeof(delay)) >= 0) *rx_delay = delay; else if (OF_getencprop(node, "allwinner,rx-delay-ps", &delay, sizeof(delay)) >= 0) { if ((delay % 100) != 0) { device_printf(dev, "rx-delay-ps is not within documented domain\n"); return (EDOM); } *rx_delay = delay / 100; } if (*rx_delay > 31) { device_printf(dev, "rx-delay out of range\n"); return (ERANGE); } return (0); } static int awg_setup_phy(device_t dev) { struct awg_softc *sc; clk_t clk_tx, clk_tx_parent; const char *tx_parent_name; char *phy_type; phandle_t node; uint32_t reg, tx_delay, rx_delay; int error; bool use_syscon; sc = device_get_softc(dev); node = ofw_bus_get_node(dev); use_syscon = false; if (OF_getprop_alloc(node, "phy-mode", (void **)&phy_type) == 0) return (0); if (sc->syscon != NULL || sc->res[_RES_SYSCON] != NULL) use_syscon = true; if (bootverbose) device_printf(dev, "PHY type: %s, conf mode: %s\n", phy_type, use_syscon ? "reg" : "clk"); if (use_syscon) { /* * Abstract away writing to syscon for devices like the pine64. * For the pine64, we get dtb from U-Boot and it still uses the * legacy setup of specifying syscon register in emac node * rather than as its own node and using an xref in emac. * These abstractions can go away once U-Boot dts is up-to-date. */ reg = syscon_read_emac_clk_reg(dev); reg &= ~(EMAC_CLK_PIT | EMAC_CLK_SRC | EMAC_CLK_RMII_EN); if (strncmp(phy_type, "rgmii", 5) == 0) reg |= EMAC_CLK_PIT_RGMII | EMAC_CLK_SRC_RGMII; else if (strcmp(phy_type, "rmii") == 0) reg |= EMAC_CLK_RMII_EN; else reg |= EMAC_CLK_PIT_MII | EMAC_CLK_SRC_MII; /* * Fail attach if we fail to parse either of the delay * parameters. If we don't have the proper delay to write to * syscon, then awg likely won't function properly anyways. * Lack of delay is not an error! */ error = awg_parse_delay(dev, &tx_delay, &rx_delay); if (error != 0) goto fail; /* Default to 0 and we'll increase it if we need to. */ reg &= ~(EMAC_CLK_ETXDC | EMAC_CLK_ERXDC); if (tx_delay > 0) reg |= (tx_delay << EMAC_CLK_ETXDC_SHIFT); if (rx_delay > 0) reg |= (rx_delay << EMAC_CLK_ERXDC_SHIFT); if (sc->type == EMAC_H3) { if (awg_has_internal_phy(dev)) { reg |= EMAC_CLK_EPHY_SELECT; reg &= ~EMAC_CLK_EPHY_SHUTDOWN; if (OF_hasprop(node, "allwinner,leds-active-low")) reg |= EMAC_CLK_EPHY_LED_POL; else reg &= ~EMAC_CLK_EPHY_LED_POL; /* Set internal PHY addr to 1 */ reg &= ~EMAC_CLK_EPHY_ADDR; reg |= (1 << EMAC_CLK_EPHY_ADDR_SHIFT); } else { reg &= ~EMAC_CLK_EPHY_SELECT; } } if (bootverbose) device_printf(dev, "EMAC clock: 0x%08x\n", reg); syscon_write_emac_clk_reg(dev, reg); } else { if (strncmp(phy_type, "rgmii", 5) == 0) tx_parent_name = "emac_int_tx"; else tx_parent_name = "mii_phy_tx"; /* Get the TX clock */ error = clk_get_by_ofw_name(dev, 0, "tx", &clk_tx); if (error != 0) { device_printf(dev, "cannot get tx clock\n"); goto fail; } /* Find the desired parent clock based on phy-mode property */ error = clk_get_by_name(dev, tx_parent_name, &clk_tx_parent); if (error != 0) { device_printf(dev, "cannot get clock '%s'\n", tx_parent_name); goto fail; } /* Set TX clock parent */ error = clk_set_parent_by_clk(clk_tx, clk_tx_parent); if (error != 0) { device_printf(dev, "cannot set tx clock parent\n"); goto fail; } /* Enable TX clock */ error = clk_enable(clk_tx); if (error != 0) { device_printf(dev, "cannot enable tx clock\n"); goto fail; } } error = 0; fail: OF_prop_free(phy_type); return (error); } static int awg_setup_extres(device_t dev) { struct awg_softc *sc; phandle_t node, phy_node; hwreset_t rst_ahb, rst_ephy; clk_t clk_ahb, clk_ephy; regulator_t reg; uint64_t freq; int error, div; sc = device_get_softc(dev); rst_ahb = rst_ephy = NULL; clk_ahb = clk_ephy = NULL; reg = NULL; node = ofw_bus_get_node(dev); phy_node = awg_get_phy_node(dev); if (phy_node == 0 && OF_hasprop(node, "phy-handle")) { error = ENXIO; device_printf(dev, "cannot get phy handle\n"); goto fail; } /* Get AHB clock and reset resources */ error = hwreset_get_by_ofw_name(dev, 0, "stmmaceth", &rst_ahb); if (error != 0) error = hwreset_get_by_ofw_name(dev, 0, "ahb", &rst_ahb); if (error != 0) { device_printf(dev, "cannot get ahb reset\n"); goto fail; } if (hwreset_get_by_ofw_name(dev, 0, "ephy", &rst_ephy) != 0) if (phy_node == 0 || hwreset_get_by_ofw_idx(dev, phy_node, 0, &rst_ephy) != 0) rst_ephy = NULL; error = clk_get_by_ofw_name(dev, 0, "stmmaceth", &clk_ahb); if (error != 0) error = clk_get_by_ofw_name(dev, 0, "ahb", &clk_ahb); if (error != 0) { device_printf(dev, "cannot get ahb clock\n"); goto fail; } if (clk_get_by_ofw_name(dev, 0, "ephy", &clk_ephy) != 0) if (phy_node == 0 || clk_get_by_ofw_index(dev, phy_node, 0, &clk_ephy) != 0) clk_ephy = NULL; if (OF_hasprop(node, "syscon") && syscon_get_by_ofw_property(dev, node, "syscon", &sc->syscon) != 0) { device_printf(dev, "cannot get syscon driver handle\n"); goto fail; } /* Configure PHY for MII or RGMII mode */ if (awg_setup_phy(dev) != 0) goto fail; /* Enable clocks */ error = clk_enable(clk_ahb); if (error != 0) { device_printf(dev, "cannot enable ahb clock\n"); goto fail; } if (clk_ephy != NULL) { error = clk_enable(clk_ephy); if (error != 0) { device_printf(dev, "cannot enable ephy clock\n"); goto fail; } } /* De-assert reset */ error = hwreset_deassert(rst_ahb); if (error != 0) { device_printf(dev, "cannot de-assert ahb reset\n"); goto fail; } if (rst_ephy != NULL) { /* * The ephy reset is left de-asserted by U-Boot. Assert it * here to make sure that we're in a known good state going * into the PHY reset. */ hwreset_assert(rst_ephy); error = hwreset_deassert(rst_ephy); if (error != 0) { device_printf(dev, "cannot de-assert ephy reset\n"); goto fail; } } /* Enable PHY regulator if applicable */ if (regulator_get_by_ofw_property(dev, 0, "phy-supply", ®) == 0) { error = regulator_enable(reg); if (error != 0) { device_printf(dev, "cannot enable PHY regulator\n"); goto fail; } } /* Determine MDC clock divide ratio based on AHB clock */ error = clk_get_freq(clk_ahb, &freq); if (error != 0) { device_printf(dev, "cannot get AHB clock frequency\n"); goto fail; } div = freq / MDIO_FREQ; if (div <= 16) sc->mdc_div_ratio_m = MDC_DIV_RATIO_M_16; else if (div <= 32) sc->mdc_div_ratio_m = MDC_DIV_RATIO_M_32; else if (div <= 64) sc->mdc_div_ratio_m = MDC_DIV_RATIO_M_64; else if (div <= 128) sc->mdc_div_ratio_m = MDC_DIV_RATIO_M_128; else { device_printf(dev, "cannot determine MDC clock divide ratio\n"); error = ENXIO; goto fail; } if (bootverbose) device_printf(dev, "AHB frequency %ju Hz, MDC div: 0x%x\n", (uintmax_t)freq, sc->mdc_div_ratio_m); return (0); fail: if (reg != NULL) regulator_release(reg); if (clk_ephy != NULL) clk_release(clk_ephy); if (clk_ahb != NULL) clk_release(clk_ahb); if (rst_ephy != NULL) hwreset_release(rst_ephy); if (rst_ahb != NULL) hwreset_release(rst_ahb); return (error); } #ifdef AWG_DEBUG static void awg_dump_regs(device_t dev) { static const struct { const char *name; u_int reg; } regs[] = { { "BASIC_CTL_0", EMAC_BASIC_CTL_0 }, { "BASIC_CTL_1", EMAC_BASIC_CTL_1 }, { "INT_STA", EMAC_INT_STA }, { "INT_EN", EMAC_INT_EN }, { "TX_CTL_0", EMAC_TX_CTL_0 }, { "TX_CTL_1", EMAC_TX_CTL_1 }, { "TX_FLOW_CTL", EMAC_TX_FLOW_CTL }, { "TX_DMA_LIST", EMAC_TX_DMA_LIST }, { "RX_CTL_0", EMAC_RX_CTL_0 }, { "RX_CTL_1", EMAC_RX_CTL_1 }, { "RX_DMA_LIST", EMAC_RX_DMA_LIST }, { "RX_FRM_FLT", EMAC_RX_FRM_FLT }, { "RX_HASH_0", EMAC_RX_HASH_0 }, { "RX_HASH_1", EMAC_RX_HASH_1 }, { "MII_CMD", EMAC_MII_CMD }, { "ADDR_HIGH0", EMAC_ADDR_HIGH(0) }, { "ADDR_LOW0", EMAC_ADDR_LOW(0) }, { "TX_DMA_STA", EMAC_TX_DMA_STA }, { "TX_DMA_CUR_DESC", EMAC_TX_DMA_CUR_DESC }, { "TX_DMA_CUR_BUF", EMAC_TX_DMA_CUR_BUF }, { "RX_DMA_STA", EMAC_RX_DMA_STA }, { "RX_DMA_CUR_DESC", EMAC_RX_DMA_CUR_DESC }, { "RX_DMA_CUR_BUF", EMAC_RX_DMA_CUR_BUF }, { "RGMII_STA", EMAC_RGMII_STA }, }; struct awg_softc *sc; unsigned int n; sc = device_get_softc(dev); for (n = 0; n < nitems(regs); n++) device_printf(dev, " %-20s %08x\n", regs[n].name, RD4(sc, regs[n].reg)); } #endif #define GPIO_ACTIVE_LOW 1 static int awg_phy_reset(device_t dev) { pcell_t gpio_prop[4], delay_prop[3]; phandle_t node, gpio_node; device_t gpio; uint32_t pin, flags; uint32_t pin_value; node = ofw_bus_get_node(dev); if (OF_getencprop(node, "allwinner,reset-gpio", gpio_prop, sizeof(gpio_prop)) <= 0) return (0); if (OF_getencprop(node, "allwinner,reset-delays-us", delay_prop, sizeof(delay_prop)) <= 0) return (ENXIO); gpio_node = OF_node_from_xref(gpio_prop[0]); if ((gpio = OF_device_from_xref(gpio_prop[0])) == NULL) return (ENXIO); if (GPIO_MAP_GPIOS(gpio, node, gpio_node, nitems(gpio_prop) - 1, gpio_prop + 1, &pin, &flags) != 0) return (ENXIO); pin_value = GPIO_PIN_LOW; if (OF_hasprop(node, "allwinner,reset-active-low")) pin_value = GPIO_PIN_HIGH; if (flags & GPIO_ACTIVE_LOW) pin_value = !pin_value; GPIO_PIN_SETFLAGS(gpio, pin, GPIO_PIN_OUTPUT); GPIO_PIN_SET(gpio, pin, pin_value); DELAY(delay_prop[0]); GPIO_PIN_SET(gpio, pin, !pin_value); DELAY(delay_prop[1]); GPIO_PIN_SET(gpio, pin, pin_value); DELAY(delay_prop[2]); return (0); } static int awg_reset(device_t dev) { struct awg_softc *sc; int retry; sc = device_get_softc(dev); /* Reset PHY if necessary */ if (awg_phy_reset(dev) != 0) { device_printf(dev, "failed to reset PHY\n"); return (ENXIO); } /* Soft reset all registers and logic */ WR4(sc, EMAC_BASIC_CTL_1, BASIC_CTL_SOFT_RST); /* Wait for soft reset bit to self-clear */ for (retry = SOFT_RST_RETRY; retry > 0; retry--) { if ((RD4(sc, EMAC_BASIC_CTL_1) & BASIC_CTL_SOFT_RST) == 0) break; DELAY(10); } if (retry == 0) { device_printf(dev, "soft reset timed out\n"); #ifdef AWG_DEBUG awg_dump_regs(dev); #endif return (ETIMEDOUT); } return (0); } /* * Stats */ static void awg_tick(void *softc) { struct awg_softc *sc; struct mii_data *mii; if_t ifp; int link; sc = softc; ifp = sc->ifp; mii = device_get_softc(sc->miibus); AWG_ASSERT_LOCKED(sc); if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0) return; link = sc->link; mii_tick(mii); if (sc->link && !link) awg_start_locked(sc); callout_reset(&sc->stat_ch, hz, awg_tick, sc); } /* * Probe/attach functions */ static int awg_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "Allwinner Gigabit Ethernet"); return (BUS_PROBE_DEFAULT); } static int awg_attach(device_t dev) { uint8_t eaddr[ETHER_ADDR_LEN]; struct awg_softc *sc; int error; sc = device_get_softc(dev); sc->dev = dev; sc->type = ofw_bus_search_compatible(dev, compat_data)->ocd_data; if (bus_alloc_resources(dev, awg_spec, sc->res) != 0) { device_printf(dev, "cannot allocate resources for device\n"); return (ENXIO); } mtx_init(&sc->mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF); callout_init_mtx(&sc->stat_ch, &sc->mtx, 0); /* Setup clocks and regulators */ error = awg_setup_extres(dev); if (error != 0) return (error); /* Read MAC address before resetting the chip */ awg_get_eaddr(dev, eaddr); /* Soft reset EMAC core */ error = awg_reset(dev); if (error != 0) return (error); /* Setup DMA descriptors */ error = awg_setup_dma(dev); if (error != 0) return (error); /* Install interrupt handler */ error = bus_setup_intr(dev, sc->res[_RES_IRQ], INTR_TYPE_NET | INTR_MPSAFE, NULL, awg_intr, sc, &sc->ih); if (error != 0) { device_printf(dev, "cannot setup interrupt handler\n"); return (error); } /* Setup ethernet interface */ sc->ifp = if_alloc(IFT_ETHER); if_setsoftc(sc->ifp, sc); if_initname(sc->ifp, device_get_name(dev), device_get_unit(dev)); if_setflags(sc->ifp, IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST); if_setstartfn(sc->ifp, awg_start); if_setioctlfn(sc->ifp, awg_ioctl); if_setinitfn(sc->ifp, awg_init); if_setsendqlen(sc->ifp, TX_DESC_COUNT - 1); if_setsendqready(sc->ifp); if_sethwassist(sc->ifp, CSUM_IP | CSUM_UDP | CSUM_TCP); if_setcapabilities(sc->ifp, IFCAP_VLAN_MTU | IFCAP_HWCSUM); if_setcapenable(sc->ifp, if_getcapabilities(sc->ifp)); #ifdef DEVICE_POLLING if_setcapabilitiesbit(sc->ifp, IFCAP_POLLING, 0); #endif /* Attach MII driver */ error = mii_attach(dev, &sc->miibus, sc->ifp, awg_media_change, awg_media_status, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, MIIF_DOPAUSE); if (error != 0) { device_printf(dev, "cannot attach PHY\n"); return (error); } /* Attach ethernet interface */ ether_ifattach(sc->ifp, eaddr); return (0); } static device_method_t awg_methods[] = { /* Device interface */ DEVMETHOD(device_probe, awg_probe), DEVMETHOD(device_attach, awg_attach), /* MII interface */ DEVMETHOD(miibus_readreg, awg_miibus_readreg), DEVMETHOD(miibus_writereg, awg_miibus_writereg), DEVMETHOD(miibus_statchg, awg_miibus_statchg), DEVMETHOD_END }; static driver_t awg_driver = { "awg", awg_methods, sizeof(struct awg_softc), }; DRIVER_MODULE(awg, simplebus, awg_driver, 0, 0); DRIVER_MODULE(miibus, awg, miibus_driver, 0, 0); MODULE_DEPEND(awg, ether, 1, 1, 1); MODULE_DEPEND(awg, miibus, 1, 1, 1); MODULE_DEPEND(awg, aw_sid, 1, 1, 1); SIMPLEBUS_PNP_INFO(compat_data); diff --git a/sys/arm/mv/clk/a37x0_xtal.c b/sys/arm/mv/clk/a37x0_xtal.c index 67a791b8d34a..195c26259e63 100644 --- a/sys/arm/mv/clk/a37x0_xtal.c +++ b/sys/arm/mv/clk/a37x0_xtal.c @@ -1,144 +1,144 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2021 Semihalf. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include -#include +#include #include #include #include "syscon_if.h" #define BIT(x) (1 << (x)) #define NB_GPIO1_PIN_LT_L 0x8 #define NB_GPIO1_MPP1_9 BIT(9) struct a37x0_xtal_softc { device_t dev; struct clkdom *clkdom; }; static int a37x0_xtal_attach(device_t dev); static int a37x0_xtal_detach(device_t dev); static int a37x0_xtal_probe(device_t dev); static device_method_t a37x0_xtal_methods [] = { DEVMETHOD(device_probe, a37x0_xtal_probe), DEVMETHOD(device_attach, a37x0_xtal_attach), DEVMETHOD(device_detach, a37x0_xtal_detach), DEVMETHOD_END }; static driver_t a37x0_xtal_driver = { "a37x0-xtal", a37x0_xtal_methods, sizeof(struct a37x0_xtal_softc) }; EARLY_DRIVER_MODULE(a37x0_xtal, simplebus, a37x0_xtal_driver, 0, 0, BUS_PASS_TIMER + BUS_PASS_ORDER_EARLY); static int a37x0_xtal_attach(device_t dev) { struct a37x0_xtal_softc *sc; struct clk_fixed_def def; struct syscon *syscon; uint32_t reg; int error; sc = device_get_softc(dev); def.clkdef.name = "armada-3700-xtal"; def.clkdef.parent_names = NULL; def.clkdef.parent_cnt = 0; def.clkdef.id = 1; def.mult = 0; def.div = 0; if (SYSCON_GET_HANDLE(dev, &syscon) != 0 || syscon == NULL){ device_printf(dev, "Cannot get syscon driver handle\n"); return (ENXIO); } reg = SYSCON_READ_4(syscon, NB_GPIO1_PIN_LT_L); if (reg & NB_GPIO1_MPP1_9) def.freq = 40000000; else def.freq = 25000000; sc->clkdom = clkdom_create(dev); error = clknode_fixed_register(sc->clkdom, &def); if (error){ device_printf(dev, "Cannot register clock node\n"); return (ENXIO); } error = clkdom_finit(sc->clkdom); if (error){ device_printf(dev, "Cannot finalize clock domain initialization\n"); return (ENXIO); } if (bootverbose) clkdom_dump(sc->clkdom); return (0); } static int a37x0_xtal_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (!ofw_bus_is_compatible(dev, "marvell,armada-3700-xtal-clock")) return (ENXIO); device_set_desc(dev, "Marvell Armada 3700 Oscillator"); return (BUS_PROBE_DEFAULT); } static int a37x0_xtal_detach(device_t dev) { return (EBUSY); } diff --git a/sys/arm/mv/mv_ap806_clock.c b/sys/arm/mv/mv_ap806_clock.c index f41f5e09c4dd..6d15d5687088 100644 --- a/sys/arm/mv/mv_ap806_clock.c +++ b/sys/arm/mv/mv_ap806_clock.c @@ -1,226 +1,226 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2018 Rubicon Communications, LLC (Netgate) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include #include #include "syscon_if.h" static struct clk_fixed_def ap806_clk_cluster_0 = { .clkdef.id = 0, .clkdef.name = "ap806-cpu-cluster-0", .freq = 0, }; static struct clk_fixed_def ap806_clk_cluster_1 = { .clkdef.id = 1, .clkdef.name = "ap806-cpu-cluster-1", .freq = 0, }; static struct clk_fixed_def ap806_clk_fixed = { .clkdef.id = 2, .clkdef.name = "ap806-fixed", .freq = 1200000000, }; /* Thoses are the only exported clocks AFAICT */ static const char *mss_parents[] = {"ap806-fixed"}; static struct clk_fixed_def ap806_clk_mss = { .clkdef.id = 3, .clkdef.name = "ap806-mss", .clkdef.parent_names = mss_parents, .clkdef.parent_cnt = 1, .mult = 1, .div = 6, }; static const char *sdio_parents[] = {"ap806-fixed"}; static struct clk_fixed_def ap806_clk_sdio = { .clkdef.id = 4, .clkdef.name = "ap806-sdio", .clkdef.parent_names = sdio_parents, .clkdef.parent_cnt = 1, .mult = 1, .div = 3, }; struct mv_ap806_clock_softc { device_t dev; struct syscon *syscon; }; static struct ofw_compat_data compat_data[] = { {"marvell,ap806-clock", 1}, {NULL, 0} }; #define RD4(sc, reg) SYSCON_READ_4((sc)->syscon, (reg)) #define WR4(sc, reg, val) SYSCON_WRITE_4((sc)->syscon, (reg), (val)) static int mv_ap806_clock_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "Marvell AP806 Clock Controller"); return (BUS_PROBE_DEFAULT); } static int mv_ap806_clock_attach(device_t dev) { struct mv_ap806_clock_softc *sc; struct clkdom *clkdom; uint64_t clock_freq; uint32_t reg; sc = device_get_softc(dev); sc->dev = dev; if (SYSCON_GET_HANDLE(sc->dev, &sc->syscon) != 0 || sc->syscon == NULL) { device_printf(dev, "cannot get syscon for device\n"); return (ENXIO); } reg = RD4(sc, 0x400); switch (reg & 0x1f) { case 0x0: case 0x1: clock_freq = 2000000000; break; case 0x4: clock_freq = 1600000000; break; case 0x6: clock_freq = 1800000000; break; case 0x7: clock_freq = 1800000000; break; case 0xb: clock_freq = 1600000000; break; case 0xd: clock_freq = 1600000000; break; case 0x13: clock_freq = 1000000000; break; case 0x14: clock_freq = 1333000000; break; case 0x17: clock_freq = 1333000000; break; case 0x19: clock_freq = 1200000000; break; case 0x1a: clock_freq = 1400000000; break; case 0x1b: clock_freq = 600000000; break; case 0x1c: clock_freq = 800000000; break; case 0x1d: clock_freq = 1000000000; break; default: device_printf(dev, "Cannot guess clock freq with reg %x\n", reg & 0x1f); return (ENXIO); break; }; ap806_clk_cluster_0.freq = clock_freq; ap806_clk_cluster_1.freq = clock_freq; clkdom = clkdom_create(dev); clknode_fixed_register(clkdom, &ap806_clk_cluster_0); clknode_fixed_register(clkdom, &ap806_clk_cluster_1); clknode_fixed_register(clkdom, &ap806_clk_fixed); clknode_fixed_register(clkdom, &ap806_clk_mss); clknode_fixed_register(clkdom, &ap806_clk_sdio); clkdom_finit(clkdom); if (bootverbose) clkdom_dump(clkdom); return (0); } static int mv_ap806_clock_detach(device_t dev) { return (EBUSY); } static device_method_t mv_ap806_clock_methods[] = { /* Device interface */ DEVMETHOD(device_probe, mv_ap806_clock_probe), DEVMETHOD(device_attach, mv_ap806_clock_attach), DEVMETHOD(device_detach, mv_ap806_clock_detach), DEVMETHOD_END }; static driver_t mv_ap806_clock_driver = { "mv_ap806_clock", mv_ap806_clock_methods, sizeof(struct mv_ap806_clock_softc), }; EARLY_DRIVER_MODULE(mv_ap806_clock, simplebus, mv_ap806_clock_driver, 0, 0, BUS_PASS_RESOURCE + BUS_PASS_ORDER_LATE); diff --git a/sys/arm/mv/mv_cp110_clock.c b/sys/arm/mv/mv_cp110_clock.c index 45f8476df5b3..9edc01e95074 100644 --- a/sys/arm/mv/mv_cp110_clock.c +++ b/sys/arm/mv/mv_cp110_clock.c @@ -1,363 +1,363 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2018 Rubicon Communications, LLC (Netgate) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include #include #include #include "clkdev_if.h" #include "syscon_if.h" /* Clocks */ static struct clk_fixed_def cp110_clk_pll_0 = { .clkdef.id = CP110_PLL_0, .freq = 1000000000, }; static const char *clk_parents_0[] = {"cp110-pll0-0"}; static const char *clk_parents_1[] = {"cp110-pll0-1"}; static struct clk_fixed_def cp110_clk_ppv2_core = { .clkdef.id = CP110_PPV2_CORE, .clkdef.parent_cnt = 1, .mult = 1, .div = 3, }; static struct clk_fixed_def cp110_clk_x2core = { .clkdef.id = CP110_X2CORE, .clkdef.parent_cnt = 1, .mult = 1, .div = 2, }; static const char *core_parents_0[] = {"cp110-x2core-0"}; static const char *core_parents_1[] = {"cp110-x2core-1"}; static struct clk_fixed_def cp110_clk_core = { .clkdef.id = CP110_CORE, .clkdef.parent_cnt = 1, .mult = 1, .div = 2, }; static struct clk_fixed_def cp110_clk_sdio = { .clkdef.id = CP110_SDIO, .clkdef.parent_cnt = 1, .mult = 2, .div = 5, }; /* Gates */ static struct cp110_gate cp110_gates[] = { CCU_GATE(CP110_GATE_AUDIO, "cp110-gate-audio", 0) CCU_GATE(CP110_GATE_COMM_UNIT, "cp110-gate-comm_unit", 1) /* CCU_GATE(CP110_GATE_NAND, "cp110-gate-nand", 2) */ CCU_GATE(CP110_GATE_PPV2, "cp110-gate-ppv2", 3) CCU_GATE(CP110_GATE_SDIO, "cp110-gate-sdio", 4) CCU_GATE(CP110_GATE_MG, "cp110-gate-mg", 5) CCU_GATE(CP110_GATE_MG_CORE, "cp110-gate-mg_core", 6) CCU_GATE(CP110_GATE_XOR1, "cp110-gate-xor1", 7) CCU_GATE(CP110_GATE_XOR0, "cp110-gate-xor0", 8) CCU_GATE(CP110_GATE_GOP_DP, "cp110-gate-gop_dp", 9) CCU_GATE(CP110_GATE_PCIE_X1_0, "cp110-gate-pcie_x10", 11) CCU_GATE(CP110_GATE_PCIE_X1_1, "cp110-gate-pcie_x11", 12) CCU_GATE(CP110_GATE_PCIE_X4, "cp110-gate-pcie_x4", 13) CCU_GATE(CP110_GATE_PCIE_XOR, "cp110-gate-pcie_xor", 14) CCU_GATE(CP110_GATE_SATA, "cp110-gate-sata", 15) CCU_GATE(CP110_GATE_SATA_USB, "cp110-gate-sata_usb", 16) CCU_GATE(CP110_GATE_MAIN, "cp110-gate-main", 17) CCU_GATE(CP110_GATE_SDMMC_GOP, "cp110-gate-sdmmc_gop", 18) CCU_GATE(CP110_GATE_SLOW_IO, "cp110-gate-slow_io", 21) CCU_GATE(CP110_GATE_USB3H0, "cp110-gate-usb3h0", 22) CCU_GATE(CP110_GATE_USB3H1, "cp110-gate-usb3h1", 23) CCU_GATE(CP110_GATE_USB3DEV, "cp110-gate-usb3dev", 24) CCU_GATE(CP110_GATE_EIP150, "cp110-gate-eip150", 25) CCU_GATE(CP110_GATE_EIP197, "cp110-gate-eip197", 26) }; struct mv_cp110_clock_softc { device_t dev; struct syscon *syscon; struct mtx mtx; }; static struct ofw_compat_data compat_data[] = { {"marvell,cp110-clock", 1}, {NULL, 0} }; #define RD4(sc, reg) SYSCON_READ_4((sc)->syscon, (reg)) #define WR4(sc, reg, val) SYSCON_WRITE_4((sc)->syscon, (reg), (val)) static char * mv_cp110_clock_name(device_t dev, const char *name) { char *clkname = NULL; int unit; unit = device_get_unit(dev); if (asprintf(&clkname, M_DEVBUF, "%s-%d", name, unit) <= 0) panic("Cannot generate unique clock name for %s\n", name); return (clkname); } static int mv_cp110_clock_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "Marvell CP110 Clock Controller"); return (BUS_PROBE_DEFAULT); } static int cp110_ofw_map(struct clkdom *clkdom, uint32_t ncells, phandle_t *cells, struct clknode **clk) { int id = 0; if (ncells != 2) return (ENXIO); id = cells[1]; if (cells[0] == 1) id += CP110_MAX_CLOCK; *clk = clknode_find_by_id(clkdom, id); return (0); } static int mv_cp110_clock_attach(device_t dev) { struct mv_cp110_clock_softc *sc; struct clkdom *clkdom; struct clk_gate_def def; char *pll0_name; int unit, i; sc = device_get_softc(dev); sc->dev = dev; if (SYSCON_GET_HANDLE(sc->dev, &sc->syscon) != 0 || sc->syscon == NULL) { device_printf(dev, "cannot get syscon for device\n"); return (ENXIO); } unit = device_get_unit(dev); if (unit > 1) { device_printf(dev, "Bogus cp110-system-controller unit %d\n", unit); return (ENXIO); } mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF); clkdom = clkdom_create(dev); clkdom_set_ofw_mapper(clkdom, cp110_ofw_map); pll0_name = mv_cp110_clock_name(dev, "cp110-pll0"); cp110_clk_pll_0.clkdef.name = pll0_name; clknode_fixed_register(clkdom, &cp110_clk_pll_0); cp110_clk_ppv2_core.clkdef.name = mv_cp110_clock_name(dev, "cp110-ppv2"); cp110_clk_ppv2_core.clkdef.parent_names = (unit == 0) ? clk_parents_0 : clk_parents_1; clknode_fixed_register(clkdom, &cp110_clk_ppv2_core); cp110_clk_x2core.clkdef.name = mv_cp110_clock_name(dev, "cp110-x2core"); cp110_clk_x2core.clkdef.parent_names = (unit == 0) ? clk_parents_0 : clk_parents_1; clknode_fixed_register(clkdom, &cp110_clk_x2core); cp110_clk_core.clkdef.name = mv_cp110_clock_name(dev, "cp110-core"); cp110_clk_core.clkdef.parent_names = (unit == 0) ? core_parents_0 : core_parents_1; clknode_fixed_register(clkdom, &cp110_clk_core); /* NAND missing */ cp110_clk_sdio.clkdef.name = mv_cp110_clock_name(dev, "cp110-sdio"); cp110_clk_sdio.clkdef.parent_names = (unit == 0) ? clk_parents_0 : clk_parents_1; clknode_fixed_register(clkdom, &cp110_clk_sdio); for (i = 0; i < nitems(cp110_gates); i++) { if (cp110_gates[i].name == NULL) continue; memset(&def, 0, sizeof(def)); def.clkdef.id = CP110_MAX_CLOCK + i; def.clkdef.name = mv_cp110_clock_name(dev, cp110_gates[i].name); def.clkdef.parent_cnt = 1; def.offset = CP110_CLOCK_GATING_OFFSET; def.shift = cp110_gates[i].shift; def.mask = 1; def.on_value = 1; def.off_value = 0; switch (i) { case CP110_GATE_MG: case CP110_GATE_GOP_DP: case CP110_GATE_PPV2: def.clkdef.parent_names = &cp110_clk_ppv2_core.clkdef.name; break; case CP110_GATE_SDIO: def.clkdef.parent_names = &cp110_clk_sdio.clkdef.name; break; case CP110_GATE_MAIN: case CP110_GATE_PCIE_XOR: case CP110_GATE_PCIE_X4: case CP110_GATE_EIP150: case CP110_GATE_EIP197: def.clkdef.parent_names = &cp110_clk_x2core.clkdef.name; break; default: def.clkdef.parent_names = &cp110_clk_core.clkdef.name; break; } clknode_gate_register(clkdom, &def); } clkdom_finit(clkdom); if (bootverbose) clkdom_dump(clkdom); return (0); } static int mv_cp110_clock_detach(device_t dev) { return (EBUSY); } static int mv_cp110_clock_write_4(device_t dev, bus_addr_t addr, uint32_t val) { struct mv_cp110_clock_softc *sc; sc = device_get_softc(dev); WR4(sc, addr, val); return (0); } static int mv_cp110_clock_read_4(device_t dev, bus_addr_t addr, uint32_t *val) { struct mv_cp110_clock_softc *sc; sc = device_get_softc(dev); *val = RD4(sc, addr); return (0); } static int mv_cp110_clock_modify_4(device_t dev, bus_addr_t addr, uint32_t clr, uint32_t set) { struct mv_cp110_clock_softc *sc; uint32_t reg; sc = device_get_softc(dev); reg = RD4(sc, addr); reg &= ~clr; reg |= set; WR4(sc, addr, reg); return (0); } static void mv_cp110_clock_device_lock(device_t dev) { struct mv_cp110_clock_softc *sc; sc = device_get_softc(dev); mtx_lock(&sc->mtx); } static void mv_cp110_clock_device_unlock(device_t dev) { struct mv_cp110_clock_softc *sc; sc = device_get_softc(dev); mtx_unlock(&sc->mtx); } static device_method_t mv_cp110_clock_methods[] = { /* Device interface */ DEVMETHOD(device_probe, mv_cp110_clock_probe), DEVMETHOD(device_attach, mv_cp110_clock_attach), DEVMETHOD(device_detach, mv_cp110_clock_detach), /* clkdev interface */ DEVMETHOD(clkdev_write_4, mv_cp110_clock_write_4), DEVMETHOD(clkdev_read_4, mv_cp110_clock_read_4), DEVMETHOD(clkdev_modify_4, mv_cp110_clock_modify_4), DEVMETHOD(clkdev_device_lock, mv_cp110_clock_device_lock), DEVMETHOD(clkdev_device_unlock, mv_cp110_clock_device_unlock), DEVMETHOD_END }; static driver_t mv_cp110_clock_driver = { "mv_cp110_clock", mv_cp110_clock_methods, sizeof(struct mv_cp110_clock_softc), }; EARLY_DRIVER_MODULE(mv_cp110_clock, simplebus, mv_cp110_clock_driver, 0, 0, BUS_PASS_RESOURCE + BUS_PASS_ORDER_LATE); diff --git a/sys/arm/mv/mv_cp110_icu_bus.c b/sys/arm/mv/mv_cp110_icu_bus.c index 43429292c9f1..75c0bee75414 100644 --- a/sys/arm/mv/mv_cp110_icu_bus.c +++ b/sys/arm/mv/mv_cp110_icu_bus.c @@ -1,74 +1,74 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2019 Michal Meloun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include -#include +#include #include static struct ofw_compat_data compat_data[] = { {"marvell,cp110-icu", 1}, {NULL, 0} }; static int mv_cp110_icu_bus_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "Marvell Interrupt Consolidation Unit Bus"); return (BUS_PROBE_DEFAULT); } static device_method_t mv_cp110_icu_bus_methods[] = { DEVMETHOD(device_probe, mv_cp110_icu_bus_probe), DEVMETHOD_END }; DEFINE_CLASS_1(mv_cp110_icu_bus, mv_cp110_icu_bus_driver, mv_cp110_icu_bus_methods, sizeof(struct simple_mfd_softc), simple_mfd_driver); EARLY_DRIVER_MODULE(mv_cp110_icu_bus, simplebus, mv_cp110_icu_bus_driver, 0, 0, BUS_PASS_INTERRUPT); MODULE_VERSION(mv_cp110_icu_bus, 1); diff --git a/sys/arm/mv/mv_thermal.c b/sys/arm/mv/mv_thermal.c index 8004fdd38289..9240666ec726 100644 --- a/sys/arm/mv/mv_thermal.c +++ b/sys/arm/mv/mv_thermal.c @@ -1,367 +1,367 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2018 Rubicon Communications, LLC (Netgate) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include #include #include "syscon_if.h" #define CONTROL0 0 /* Offset in config->regs[] array */ #define CONTROL0_TSEN_START (1 << 0) #define CONTROL0_TSEN_RESET (1 << 1) #define CONTROL0_TSEN_EN (1 << 2) #define CONTROL0_CHANNEL_SHIFT 13 #define CONTROL0_CHANNEL_MASK 0xF #define CONTROL0_OSR_SHIFT 24 #define CONTROL0_OSR_MAX 3 /* OSR = 512 * 4uS = ~2mS */ #define CONTROL0_MODE_SHIFT 30 #define CONTROL0_MODE_EXTERNAL 0x2 #define CONTROL0_MODE_MASK 0x3 #define CONTROL1 1 /* Offset in config->regs[] array */ /* This doesn't seems to work */ #define CONTROL1_TSEN_SENS_SHIFT 21 #define CONTROL1_TSEN_SENS_MASK 0x7 #define STATUS 2 /* Offset in config->regs[] array */ #define STATUS_TEMP_MASK 0x3FF enum mv_thermal_type { MV_AP806 = 1, MV_CP110, }; struct mv_thermal_config { enum mv_thermal_type type; int regs[3]; int ncpus; int64_t calib_mul; int64_t calib_add; int64_t calib_div; uint32_t valid_mask; bool signed_value; }; struct mv_thermal_softc { device_t dev; struct syscon *syscon; struct mtx mtx; struct mv_thermal_config *config; int cur_sensor; }; static struct mv_thermal_config mv_ap806_config = { .type = MV_AP806, .regs = {0x84, 0x88, 0x8C}, .ncpus = 4, .calib_mul = 423, .calib_add = -150000, .calib_div = 100, .valid_mask = (1 << 16), .signed_value = true, }; static struct mv_thermal_config mv_cp110_config = { .type = MV_CP110, .regs = {0x70, 0x74, 0x78}, .calib_mul = 2000096, .calib_add = 1172499100, .calib_div = 420100, .valid_mask = (1 << 10), .signed_value = false, }; static struct ofw_compat_data compat_data[] = { {"marvell,armada-ap806-thermal", (uintptr_t) &mv_ap806_config}, {"marvell,armada-cp110-thermal", (uintptr_t) &mv_cp110_config}, {NULL, 0} }; #define RD4(sc, reg) \ SYSCON_READ_4((sc)->syscon, sc->config->regs[reg]) #define WR4(sc, reg, val) \ SYSCON_WRITE_4((sc)->syscon, sc->config->regs[reg], (val)) static inline int32_t sign_extend(uint32_t value, int index) { uint8_t shift; shift = 31 - index; return ((int32_t)(value << shift) >> shift); } static int mv_thermal_wait_sensor(struct mv_thermal_softc *sc) { uint32_t reg; uint32_t timeout; timeout = 100000; while (--timeout > 0) { reg = RD4(sc, STATUS); if ((reg & sc->config->valid_mask) == sc->config->valid_mask) break; DELAY(100); } if (timeout == 0) { return (ETIMEDOUT); } return (0); } static int mv_thermal_select_sensor(struct mv_thermal_softc *sc, int sensor) { uint32_t reg; if (sc->cur_sensor == sensor) return (0); /* Stop the current reading and reset the module */ reg = RD4(sc, CONTROL0); reg &= ~(CONTROL0_TSEN_START | CONTROL0_TSEN_EN); WR4(sc, CONTROL0, reg); /* Switch to the selected sensor */ /* * NOTE : Datasheet says to use CONTROL1 for selecting * but when doing so the sensors >0 are never ready * Do what Linux does using undocumented bits in CONTROL0 */ /* This reset automatically to the sensor 0 */ reg &= ~(CONTROL0_MODE_MASK << CONTROL0_MODE_SHIFT); if (sensor) { /* Select external sensor */ reg |= CONTROL0_MODE_EXTERNAL << CONTROL0_MODE_SHIFT; reg &= ~(CONTROL0_CHANNEL_MASK << CONTROL0_CHANNEL_SHIFT); reg |= (sensor - 1) << CONTROL0_CHANNEL_SHIFT; } WR4(sc, CONTROL0, reg); sc->cur_sensor = sensor; /* Start the reading */ reg = RD4(sc, CONTROL0); reg |= CONTROL0_TSEN_START | CONTROL0_TSEN_EN; WR4(sc, CONTROL0, reg); return (mv_thermal_wait_sensor(sc)); } static int mv_thermal_read_sensor(struct mv_thermal_softc *sc, int sensor, int *temp) { uint32_t reg; int64_t sample, rv; rv = mv_thermal_select_sensor(sc, sensor); if (rv != 0) return (rv); reg = RD4(sc, STATUS) & STATUS_TEMP_MASK; if (sc->config->signed_value) sample = sign_extend(reg, fls(STATUS_TEMP_MASK) - 1); else sample = reg; *temp = ((sample * sc->config->calib_mul) - sc->config->calib_add) / sc->config->calib_div; return (0); } static int ap806_init(struct mv_thermal_softc *sc) { uint32_t reg; /* Start the temp capture/conversion */ reg = RD4(sc, CONTROL0); reg &= ~CONTROL0_TSEN_RESET; reg |= CONTROL0_TSEN_START | CONTROL0_TSEN_EN; /* Sample every ~2ms */ reg |= CONTROL0_OSR_MAX << CONTROL0_OSR_SHIFT; WR4(sc, CONTROL0, reg); /* Since we just started the module wait for the sensor to be ready */ mv_thermal_wait_sensor(sc); return (0); } static int cp110_init(struct mv_thermal_softc *sc) { uint32_t reg; reg = RD4(sc, CONTROL1); reg &= (1 << 7); reg |= (1 << 8); WR4(sc, CONTROL1, reg); /* Sample every ~2ms */ reg = RD4(sc, CONTROL0); reg |= CONTROL0_OSR_MAX << CONTROL0_OSR_SHIFT; WR4(sc, CONTROL0, reg); return (0); } static int mv_thermal_sysctl(SYSCTL_HANDLER_ARGS) { struct mv_thermal_softc *sc; device_t dev = arg1; int sensor = arg2; int val = 0; sc = device_get_softc(dev); mtx_lock(&(sc)->mtx); if (mv_thermal_read_sensor(sc, sensor, &val) == 0) { /* Convert to Kelvin */ val = val + 2732; } else { device_printf(dev, "Timeout waiting for sensor\n"); } mtx_unlock(&(sc)->mtx); return sysctl_handle_opaque(oidp, &val, sizeof(val), req); } static int mv_thermal_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "Marvell Thermal Sensor Controller"); return (BUS_PROBE_DEFAULT); } static int mv_thermal_attach(device_t dev) { struct mv_thermal_softc *sc; struct sysctl_ctx_list *ctx; struct sysctl_oid_list *oid; char name[255]; char desc[255]; int i; sc = device_get_softc(dev); sc->dev = dev; sc->config = (struct mv_thermal_config *) ofw_bus_search_compatible(dev, compat_data)->ocd_data; mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF); if (SYSCON_GET_HANDLE(sc->dev, &sc->syscon) != 0 || sc->syscon == NULL) { device_printf(dev, "cannot get syscon for device\n"); return (ENXIO); } sc->cur_sensor = -1; switch (sc->config->type) { case MV_AP806: ap806_init(sc); break; case MV_CP110: cp110_init(sc); break; } ctx = device_get_sysctl_ctx(dev); oid = SYSCTL_CHILDREN(device_get_sysctl_tree(dev)); /* There is always at least one sensor */ SYSCTL_ADD_PROC(ctx, oid, OID_AUTO, "internal", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_NEEDGIANT, dev, 0, mv_thermal_sysctl, "IK", "Internal Temperature"); for (i = 0; i < sc->config->ncpus; i++) { snprintf(name, sizeof(name), "cpu%d", i); snprintf(desc, sizeof(desc), "CPU%d Temperature", i); SYSCTL_ADD_PROC(ctx, oid, OID_AUTO, name, CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_NEEDGIANT, dev, i + 1, mv_thermal_sysctl, "IK", desc); } return (0); } static int mv_thermal_detach(device_t dev) { return (0); } static device_method_t mv_thermal_methods[] = { /* Device interface */ DEVMETHOD(device_probe, mv_thermal_probe), DEVMETHOD(device_attach, mv_thermal_attach), DEVMETHOD(device_detach, mv_thermal_detach), DEVMETHOD_END }; static driver_t mv_thermal_driver = { "mv_thermal", mv_thermal_methods, sizeof(struct mv_thermal_softc), }; DRIVER_MODULE(mv_thermal, simplebus, mv_thermal_driver, 0, 0); diff --git a/sys/arm/mv/mvebu_gpio.c b/sys/arm/mv/mvebu_gpio.c index 001369bb3a02..a2001589867c 100644 --- a/sys/arm/mv/mvebu_gpio.c +++ b/sys/arm/mv/mvebu_gpio.c @@ -1,872 +1,872 @@ /*- * Copyright (c) 2020 Michal Meloun * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include /* * ARMADA 8040 GPIO driver. */ #include "opt_platform.h" #include #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include #include #include #include #include "pic_if.h" #include "syscon_if.h" #define GPIO_LOCK(_sc) mtx_lock(&(_sc)->mtx) #define GPIO_UNLOCK(_sc) mtx_unlock(&(_sc)->mtx) #define GPIO_LOCK_INIT(_sc) mtx_init(&_sc->mtx, \ device_get_nameunit(_sc->dev), "mvebu_gpio", MTX_DEF) #define GPIO_LOCK_DESTROY(_sc) mtx_destroy(&_sc->mtx); #define GPIO_ASSERT_LOCKED(_sc) mtx_assert(&_sc->mtx, MA_OWNED); #define GPIO_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->mtx, MA_NOTOWNED); #define GPIO_DATA_OUT 0x00 #define GPIO_CONTROL 0x04 #define GPIO_BLINK_ENA 0x08 #define GPIO_DATA_IN_POL 0x0C #define GPIO_DATA_IN 0x10 #define GPIO_INT_CAUSE 0x14 #define GPIO_INT_MASK 0x18 #define GPIO_INT_LEVEL_MASK 0x1C #define GPIO_CONTROL_SET 0x28 #define GPIO_CONTROL_CLR 0x2C #define GPIO_DATA_SET 0x30 #define GPIO_DATA_CLR 0x34 #define GPIO_BIT(_p) ((_p) % 32) #define GPIO_REGNUM(_p) ((_p) / 32) #define MV_GPIO_MAX_NIRQS 4 #define MV_GPIO_MAX_NPINS 32 struct mvebu_gpio_irqsrc { struct intr_irqsrc isrc; u_int irq; bool is_level; bool is_inverted; }; struct mvebu_gpio_softc; struct mvebu_gpio_irq_cookie { struct mvebu_gpio_softc *sc; int bank_num; }; struct mvebu_gpio_softc { device_t dev; device_t busdev; struct mtx mtx; struct syscon *syscon; uint32_t offset; struct resource *irq_res[MV_GPIO_MAX_NIRQS]; void *irq_ih[MV_GPIO_MAX_NIRQS]; struct mvebu_gpio_irq_cookie irq_cookies[MV_GPIO_MAX_NIRQS]; int gpio_npins; struct gpio_pin gpio_pins[MV_GPIO_MAX_NPINS]; struct mvebu_gpio_irqsrc *isrcs; }; static struct ofw_compat_data compat_data[] = { {"marvell,armada-8k-gpio", 1}, {NULL, 0} }; /* -------------------------------------------------------------------------- * * GPIO * */ static inline void gpio_write(struct mvebu_gpio_softc *sc, bus_size_t reg, struct gpio_pin *pin, uint32_t val) { int bit; bit = GPIO_BIT(pin->gp_pin); SYSCON_WRITE_4(sc->syscon, sc->offset + GPIO_REGNUM(pin->gp_pin) + reg, (val & 1) << bit); } static inline uint32_t gpio_read(struct mvebu_gpio_softc *sc, bus_size_t reg, struct gpio_pin *pin) { int bit; uint32_t val; bit = GPIO_BIT(pin->gp_pin); val = SYSCON_READ_4(sc->syscon, sc->offset + GPIO_REGNUM(pin->gp_pin) + reg); return (val >> bit) & 1; } static inline void gpio_modify(struct mvebu_gpio_softc *sc, bus_size_t reg, struct gpio_pin *pin, uint32_t val) { int bit; bit = GPIO_BIT(pin->gp_pin); SYSCON_MODIFY_4(sc->syscon, sc->offset + GPIO_REGNUM(pin->gp_pin) + reg, 1 << bit, (val & 1) << bit); } static void mvebu_gpio_pin_configure(struct mvebu_gpio_softc *sc, struct gpio_pin *pin, unsigned int flags) { if ((flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) == 0) return; /* Manage input/output */ pin->gp_flags &= ~(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT); if (flags & GPIO_PIN_OUTPUT) { pin->gp_flags |= GPIO_PIN_OUTPUT; gpio_write(sc, GPIO_CONTROL_CLR, pin, 1); } else { pin->gp_flags |= GPIO_PIN_INPUT; gpio_write(sc, GPIO_CONTROL_SET, pin, 1); } } static device_t mvebu_gpio_get_bus(device_t dev) { struct mvebu_gpio_softc *sc; sc = device_get_softc(dev); return (sc->busdev); } static int mvebu_gpio_pin_max(device_t dev, int *maxpin) { struct mvebu_gpio_softc *sc; sc = device_get_softc(dev); *maxpin = sc->gpio_npins - 1; return (0); } static int mvebu_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) { struct mvebu_gpio_softc *sc; sc = device_get_softc(dev); if (pin >= sc->gpio_npins) return (EINVAL); *caps = sc->gpio_pins[pin].gp_caps; return (0); } static int mvebu_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) { struct mvebu_gpio_softc *sc; sc = device_get_softc(dev); if (pin >= sc->gpio_npins) return (EINVAL); *flags = sc->gpio_pins[pin].gp_flags; return (0); } static int mvebu_gpio_pin_getname(device_t dev, uint32_t pin, char *name) { struct mvebu_gpio_softc *sc; sc = device_get_softc(dev); if (pin >= sc->gpio_npins) return (EINVAL); memcpy(name, sc->gpio_pins[pin].gp_name, GPIOMAXNAME); return (0); } static int mvebu_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) { struct mvebu_gpio_softc *sc; sc = device_get_softc(dev); if (pin >= sc->gpio_npins) return (EINVAL); mvebu_gpio_pin_configure(sc, &sc->gpio_pins[pin], flags); return (0); } static int mvebu_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) { struct mvebu_gpio_softc *sc; sc = device_get_softc(dev); if (pin >= sc->gpio_npins) return (EINVAL); if (value != 0) gpio_write(sc, GPIO_DATA_SET, &sc->gpio_pins[pin], 1); else gpio_write(sc, GPIO_DATA_CLR, &sc->gpio_pins[pin], 1); return (0); } static int mvebu_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) { struct mvebu_gpio_softc *sc; sc = device_get_softc(dev); if (pin >= sc->gpio_npins) return (EINVAL); GPIO_LOCK(sc); *val = gpio_read(sc, GPIO_DATA_IN, &sc->gpio_pins[pin]); *val ^= gpio_read(sc, GPIO_DATA_IN_POL, &sc->gpio_pins[pin]); GPIO_UNLOCK(sc); return (0); } static int mvebu_gpio_pin_toggle(device_t dev, uint32_t pin) { struct mvebu_gpio_softc *sc; uint32_t val; sc = device_get_softc(dev); if (pin >= sc->gpio_npins) return (EINVAL); GPIO_LOCK(sc); mvebu_gpio_pin_get(sc->dev, pin, &val); if (val != 0) gpio_write(sc, GPIO_DATA_CLR, &sc->gpio_pins[pin], 1); else gpio_write(sc, GPIO_DATA_SET, &sc->gpio_pins[pin], 1); GPIO_UNLOCK(sc); return (0); } /* -------------------------------------------------------------------------- * * Interrupts * */ static inline void intr_modify(struct mvebu_gpio_softc *sc, bus_addr_t reg, struct mvebu_gpio_irqsrc *mgi, uint32_t val) { int bit; bit = GPIO_BIT(mgi->irq); SYSCON_MODIFY_4(sc->syscon, sc->offset + GPIO_REGNUM(mgi->irq) + reg, 1 << bit, (val & 1) << bit); } static inline void mvebu_gpio_isrc_mask(struct mvebu_gpio_softc *sc, struct mvebu_gpio_irqsrc *mgi, uint32_t val) { if (mgi->is_level) intr_modify(sc, GPIO_INT_LEVEL_MASK, mgi, val); else intr_modify(sc, GPIO_INT_MASK, mgi, val); } static inline void mvebu_gpio_isrc_eoi(struct mvebu_gpio_softc *sc, struct mvebu_gpio_irqsrc *mgi) { int bit; if (!mgi->is_level) { bit = GPIO_BIT(mgi->irq); SYSCON_WRITE_4(sc->syscon, sc->offset + GPIO_REGNUM(mgi->irq) + GPIO_INT_CAUSE, ~(1 << bit)); } } static int mvebu_gpio_pic_attach(struct mvebu_gpio_softc *sc) { int rv; uint32_t irq; const char *name; sc->isrcs = malloc(sizeof(*sc->isrcs) * sc->gpio_npins, M_DEVBUF, M_WAITOK | M_ZERO); name = device_get_nameunit(sc->dev); for (irq = 0; irq < sc->gpio_npins; irq++) { sc->isrcs[irq].irq = irq; sc->isrcs[irq].is_level = false; sc->isrcs[irq].is_inverted = false; rv = intr_isrc_register(&sc->isrcs[irq].isrc, sc->dev, 0, "%s,%u", name, irq); if (rv != 0) return (rv); /* XXX deregister ISRCs */ } if (intr_pic_register(sc->dev, OF_xref_from_node(ofw_bus_get_node(sc->dev))) == NULL) return (ENXIO); return (0); } static int mvebu_gpio_pic_detach(struct mvebu_gpio_softc *sc) { /* * There has not been established any procedure yet * how to detach PIC from living system correctly. */ device_printf(sc->dev, "%s: not implemented yet\n", __func__); return (EBUSY); } static void mvebu_gpio_pic_disable_intr(device_t dev, struct intr_irqsrc *isrc) { struct mvebu_gpio_softc *sc; struct mvebu_gpio_irqsrc *mgi; sc = device_get_softc(dev); mgi = (struct mvebu_gpio_irqsrc *)isrc; mvebu_gpio_isrc_mask(sc, mgi, 0); } static void mvebu_gpio_pic_enable_intr(device_t dev, struct intr_irqsrc *isrc) { struct mvebu_gpio_softc *sc; struct mvebu_gpio_irqsrc *mgi; sc = device_get_softc(dev); mgi = (struct mvebu_gpio_irqsrc *)isrc; mvebu_gpio_isrc_mask(sc, mgi, 1); } static int mvebu_gpio_pic_map_fdt(struct mvebu_gpio_softc *sc, u_int ncells, pcell_t *cells, u_int *irqp, bool *invertedp, bool *levelp) { bool inverted, level; /* * The first cell is the interrupt number. * The second cell is used to specify flags: * bits[3:0] trigger type and level flags: * 1 = low-to-high edge triggered. * 2 = high-to-low edge triggered. * 4 = active high level-sensitive. * 8 = active low level-sensitive. */ if (ncells != 2 || cells[0] >= sc->gpio_npins) return (EINVAL); switch (cells[1]) { case 1: inverted = false; level = false; break; case 2: inverted = true; level = false; break; case 4: inverted = false; level = true; break; case 8: inverted = true; level = true; break; default: return (EINVAL); } *irqp = cells[0]; if (invertedp != NULL) *invertedp = inverted; if (levelp != NULL) *levelp = level; return (0); } static int mvebu_gpio_pic_map_gpio(struct mvebu_gpio_softc *sc, u_int gpio_pin_num, u_int gpio_pin_flags, u_int intr_mode, u_int *irqp, bool *invertedp, bool *levelp) { bool inverted, level; if (gpio_pin_num >= sc->gpio_npins) return (EINVAL); switch (intr_mode) { case GPIO_INTR_LEVEL_LOW: inverted = true; level = true; break; case GPIO_INTR_LEVEL_HIGH: inverted = false; level = true; break; case GPIO_INTR_CONFORM: case GPIO_INTR_EDGE_RISING: inverted = false; level = false; break; case GPIO_INTR_EDGE_FALLING: inverted = true; level = false; break; default: return (EINVAL); } *irqp = gpio_pin_num; if (invertedp != NULL) *invertedp = inverted; if (levelp != NULL) *levelp = level; return (0); } static int mvebu_gpio_pic_map_intr(device_t dev, struct intr_map_data *data, struct intr_irqsrc **isrcp) { int rv; u_int irq; struct mvebu_gpio_softc *sc; sc = device_get_softc(dev); if (data->type == INTR_MAP_DATA_FDT) { struct intr_map_data_fdt *daf; daf = (struct intr_map_data_fdt *)data; rv = mvebu_gpio_pic_map_fdt(sc, daf->ncells, daf->cells, &irq, NULL, NULL); } else if (data->type == INTR_MAP_DATA_GPIO) { struct intr_map_data_gpio *dag; dag = (struct intr_map_data_gpio *)data; rv = mvebu_gpio_pic_map_gpio(sc, dag->gpio_pin_num, dag->gpio_pin_flags, dag->gpio_intr_mode, &irq, NULL, NULL); } else return (ENOTSUP); if (rv == 0) *isrcp = &sc->isrcs[irq].isrc; return (rv); } static void mvebu_gpio_pic_post_filter(device_t dev, struct intr_irqsrc *isrc) { struct mvebu_gpio_softc *sc; struct mvebu_gpio_irqsrc *mgi; sc = device_get_softc(dev); mgi = (struct mvebu_gpio_irqsrc *)isrc; if (mgi->is_level) mvebu_gpio_isrc_eoi(sc, mgi); } static void mvebu_gpio_pic_post_ithread(device_t dev, struct intr_irqsrc *isrc) { struct mvebu_gpio_softc *sc; struct mvebu_gpio_irqsrc *mgi; sc = device_get_softc(dev); mgi = (struct mvebu_gpio_irqsrc *)isrc; mvebu_gpio_isrc_mask(sc, mgi, 1); } static void mvebu_gpio_pic_pre_ithread(device_t dev, struct intr_irqsrc *isrc) { struct mvebu_gpio_softc *sc; struct mvebu_gpio_irqsrc *mgi; sc = device_get_softc(dev); mgi = (struct mvebu_gpio_irqsrc *)isrc; mvebu_gpio_isrc_mask(sc, mgi, 0); if (mgi->is_level) mvebu_gpio_isrc_eoi(sc, mgi); } static int mvebu_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc, struct resource *res, struct intr_map_data *data) { u_int irq; bool inverted, level; int rv; struct mvebu_gpio_softc *sc; struct mvebu_gpio_irqsrc *mgi; sc = device_get_softc(dev); mgi = (struct mvebu_gpio_irqsrc *)isrc; if (data == NULL) return (ENOTSUP); /* Get and check config for an interrupt. */ if (data->type == INTR_MAP_DATA_FDT) { struct intr_map_data_fdt *daf; daf = (struct intr_map_data_fdt *)data; rv = mvebu_gpio_pic_map_fdt(sc, daf->ncells, daf->cells, &irq, &inverted, &level); } else if (data->type == INTR_MAP_DATA_GPIO) { struct intr_map_data_gpio *dag; dag = (struct intr_map_data_gpio *)data; rv = mvebu_gpio_pic_map_gpio(sc, dag->gpio_pin_num, dag->gpio_pin_flags, dag->gpio_intr_mode, &irq, &inverted, &level); } else return (ENOTSUP); if (rv != 0) return (EINVAL); /* * If this is a setup for another handler, * only check that its configuration match. */ if (isrc->isrc_handlers != 0) return ( mgi->is_level == level && mgi->is_inverted == inverted ? 0 : EINVAL); mgi->is_level = level; mgi->is_inverted = inverted; GPIO_LOCK(sc); intr_modify(sc, GPIO_DATA_IN_POL, mgi, inverted ? 1 : 0); mvebu_gpio_pic_enable_intr(dev, isrc); GPIO_UNLOCK(sc); return (0); } static int mvebu_gpio_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc, struct resource *res, struct intr_map_data *data) { struct mvebu_gpio_softc *sc; struct mvebu_gpio_irqsrc *mgi; sc = device_get_softc(dev); mgi = (struct mvebu_gpio_irqsrc *)isrc; if (isrc->isrc_handlers == 0) mvebu_gpio_isrc_mask(sc, mgi, 0); return (0); } /* -------------------------------------------------------------------------- * * Bus * */ static int mvebu_gpio_intr(void *arg) { u_int i, lvl, edge; struct mvebu_gpio_softc *sc; struct trapframe *tf; struct mvebu_gpio_irqsrc *mgi; struct mvebu_gpio_irq_cookie *cookie; cookie = (struct mvebu_gpio_irq_cookie *)arg; sc = cookie->sc; tf = curthread->td_intr_frame; for (i = 0; i < sc->gpio_npins; i++) { lvl = gpio_read(sc, GPIO_DATA_IN, &sc->gpio_pins[i]); lvl &= gpio_read(sc, GPIO_INT_LEVEL_MASK, &sc->gpio_pins[i]); edge = gpio_read(sc, GPIO_DATA_IN, &sc->gpio_pins[i]); edge &= gpio_read(sc, GPIO_INT_LEVEL_MASK, &sc->gpio_pins[i]); if (edge == 0 && lvl == 0) continue; mgi = &sc->isrcs[i]; if (!mgi->is_level) mvebu_gpio_isrc_eoi(sc, mgi); if (intr_isrc_dispatch(&mgi->isrc, tf) != 0) { mvebu_gpio_isrc_mask(sc, mgi, 0); if (mgi->is_level) mvebu_gpio_isrc_eoi(sc, mgi); device_printf(sc->dev, "Stray irq %u disabled\n", mgi->irq); } } return (FILTER_HANDLED); } static int mvebu_gpio_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "Marvell Integrated GPIO Controller"); return (0); } static int mvebu_gpio_detach(device_t dev) { struct mvebu_gpio_softc *sc; int i; sc = device_get_softc(dev); KASSERT(mtx_initialized(&sc->mtx), ("gpio mutex not initialized")); for (i = 0; i < MV_GPIO_MAX_NIRQS; i++) { if (sc->irq_ih[i] != NULL) bus_teardown_intr(dev, sc->irq_res[i], sc->irq_ih[i]); } if (sc->isrcs != NULL) mvebu_gpio_pic_detach(sc); gpiobus_detach_bus(dev); for (i = 0; i < MV_GPIO_MAX_NIRQS; i++) { if (sc->irq_res[i] != NULL) bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res[i]); } GPIO_LOCK_DESTROY(sc); return(0); } static int mvebu_gpio_attach(device_t dev) { struct mvebu_gpio_softc *sc; phandle_t node; struct gpio_pin *pin; pcell_t pincnt; int i, rv, rid; sc = device_get_softc(dev); sc->dev = dev; node = ofw_bus_get_node(dev); GPIO_LOCK_INIT(sc); pincnt = 0; rv = OF_getencprop(node, "ngpios", &pincnt, sizeof(pcell_t)); if (rv < 0) { device_printf(dev, "ERROR: no pin-count or ngpios entry found!\n"); return (ENXIO); } sc->gpio_npins = MIN(pincnt, MV_GPIO_MAX_NPINS); if (bootverbose) device_printf(dev, "%d pins available\n", sc->gpio_npins); rv = OF_getencprop(node, "offset", &sc->offset, sizeof(sc->offset)); if (rv == -1) { device_printf(dev, "ERROR: no 'offset' property found!\n"); return (ENXIO); } if (SYSCON_GET_HANDLE(sc->dev, &sc->syscon) != 0 || sc->syscon == NULL) { device_printf(dev, "ERROR: cannot get syscon handle!\n"); return (ENXIO); } /* Allocate interrupts. */ for (i = 0; i < MV_GPIO_MAX_NIRQS; i++) { sc->irq_cookies[i].sc = sc; sc->irq_cookies[i].bank_num = i; rid = i; sc->irq_res[i] = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); if (sc->irq_res[i] == NULL) break; if ((bus_setup_intr(dev, sc->irq_res[i], INTR_TYPE_MISC | INTR_MPSAFE, mvebu_gpio_intr, NULL, &sc->irq_cookies[i], &sc->irq_ih[i]))) { device_printf(dev, "WARNING: unable to register interrupt handler\n"); mvebu_gpio_detach(dev); return (ENXIO); } } /* Init GPIO pins */ for (i = 0; i < sc->gpio_npins; i++) { pin = sc->gpio_pins + i; pin->gp_pin = i; if (sc->irq_res[0] != NULL) pin->gp_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_INTR_LEVEL_LOW | GPIO_INTR_LEVEL_HIGH | GPIO_INTR_EDGE_RISING | GPIO_INTR_EDGE_FALLING; else pin->gp_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT; pin->gp_flags = gpio_read(sc, GPIO_CONTROL, &sc->gpio_pins[i]) == 0 ? GPIO_PIN_OUTPUT : GPIO_PIN_INPUT; snprintf(pin->gp_name, GPIOMAXNAME, "gpio%d", i); /* Init HW */ gpio_modify(sc, GPIO_INT_MASK, pin, 0); gpio_modify(sc, GPIO_INT_LEVEL_MASK, pin, 0); gpio_modify(sc, GPIO_INT_CAUSE, pin, 0); gpio_modify(sc, GPIO_DATA_IN_POL, pin, 0); gpio_modify(sc, GPIO_BLINK_ENA, pin, 0); } if (sc->irq_res[0] != NULL) { rv = mvebu_gpio_pic_attach(sc); if (rv != 0) { device_printf(dev, "WARNING: unable to attach PIC\n"); mvebu_gpio_detach(dev); return (rv); } } sc->busdev = gpiobus_attach_bus(dev); if (sc->busdev == NULL) { mvebu_gpio_detach(dev); return (ENXIO); } return (bus_generic_attach(dev)); } static int mvebu_gpio_map_gpios(device_t dev, phandle_t pdev, phandle_t gparent, int gcells, pcell_t *gpios, uint32_t *pin, uint32_t *flags) { if (gcells != 2) return (ERANGE); *pin = gpios[0]; *flags= gpios[1]; return (0); } static phandle_t mvebu_gpio_get_node(device_t bus, device_t dev) { /* We only have one child, the GPIO bus, which needs our own node. */ return (ofw_bus_get_node(bus)); } static device_method_t mvebu_gpio_methods[] = { DEVMETHOD(device_probe, mvebu_gpio_probe), DEVMETHOD(device_attach, mvebu_gpio_attach), DEVMETHOD(device_detach, mvebu_gpio_detach), /* Interrupt controller interface */ DEVMETHOD(pic_disable_intr, mvebu_gpio_pic_disable_intr), DEVMETHOD(pic_enable_intr, mvebu_gpio_pic_enable_intr), DEVMETHOD(pic_map_intr, mvebu_gpio_pic_map_intr), DEVMETHOD(pic_setup_intr, mvebu_gpio_pic_setup_intr), DEVMETHOD(pic_teardown_intr, mvebu_gpio_pic_teardown_intr), DEVMETHOD(pic_post_filter, mvebu_gpio_pic_post_filter), DEVMETHOD(pic_post_ithread, mvebu_gpio_pic_post_ithread), DEVMETHOD(pic_pre_ithread, mvebu_gpio_pic_pre_ithread), /* GPIO protocol */ DEVMETHOD(gpio_get_bus, mvebu_gpio_get_bus), DEVMETHOD(gpio_pin_max, mvebu_gpio_pin_max), DEVMETHOD(gpio_pin_getname, mvebu_gpio_pin_getname), DEVMETHOD(gpio_pin_getflags, mvebu_gpio_pin_getflags), DEVMETHOD(gpio_pin_getcaps, mvebu_gpio_pin_getcaps), DEVMETHOD(gpio_pin_setflags, mvebu_gpio_pin_setflags), DEVMETHOD(gpio_pin_get, mvebu_gpio_pin_get), DEVMETHOD(gpio_pin_set, mvebu_gpio_pin_set), DEVMETHOD(gpio_pin_toggle, mvebu_gpio_pin_toggle), DEVMETHOD(gpio_map_gpios, mvebu_gpio_map_gpios), /* ofw_bus interface */ DEVMETHOD(ofw_bus_get_node, mvebu_gpio_get_node), DEVMETHOD_END }; static DEFINE_CLASS_0(gpio, mvebu_gpio_driver, mvebu_gpio_methods, sizeof(struct mvebu_gpio_softc)); EARLY_DRIVER_MODULE(mvebu_gpio, simplebus, mvebu_gpio_driver, NULL, NULL, BUS_PASS_TIMER + BUS_PASS_ORDER_LAST); diff --git a/sys/arm/mv/mvebu_pinctrl.c b/sys/arm/mv/mvebu_pinctrl.c index 658a4b615cf7..7e9ecda1a67a 100644 --- a/sys/arm/mv/mvebu_pinctrl.c +++ b/sys/arm/mv/mvebu_pinctrl.c @@ -1,229 +1,229 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2018 Rubicon Communications, LLC (Netgate) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include #include #include #include "syscon_if.h" #define PINS_PER_REG 8 #define BITS_PER_PIN 4 #define PINS_MASK 0xf #define MAX_PIN_FUNC 5 struct mv_pins { const char *name; const char *functions[MAX_PIN_FUNC]; }; struct mv_padconf { const struct mv_pins *pins; size_t npins; }; const static struct mv_pins ap806_pins[] = { {"mpp0", {"gpio", "sdio", NULL, "spi0"}}, {"mpp1", {"gpio", "sdio", NULL, "spi0"}}, {"mpp2", {"gpio", "sdio", NULL, "spi0"}}, {"mpp3", {"gpio", "sdio", NULL, "spi0"}}, {"mpp4", {"gpio", "sdio", NULL, "i2c0"}}, {"mpp5", {"gpio", "sdio", NULL, "i2c0"}}, {"mpp6", {"gpio", "sdio", NULL, NULL}}, {"mpp7", {"gpio", "sdio", NULL, "uart1"}}, {"mpp8", {"gpio", "sdio", NULL, "uart1"}}, {"mpp9", {"gpio", "sdio", NULL, "spi0"}}, {"mpp10", {"gpio", "sdio", NULL, NULL}}, {"mpp11", {"gpio", NULL, NULL, "uart0"}}, {"mpp12", {"gpio", "sdio", "sdio", NULL}}, {"mpp13", {"gpio", NULL, NULL}}, {"mpp14", {"gpio", NULL, NULL}}, {"mpp15", {"gpio", NULL, NULL}}, {"mpp16", {"gpio", NULL, NULL}}, {"mpp17", {"gpio", NULL, NULL}}, {"mpp18", {"gpio", NULL, NULL}}, {"mpp19", {"gpio", NULL, NULL, "uart0", "sdio"}}, }; const struct mv_padconf ap806_padconf = { .npins = nitems(ap806_pins), .pins = ap806_pins, }; struct mv_pinctrl_softc { device_t dev; struct syscon *syscon; struct mv_padconf *padconf; }; static struct ofw_compat_data compat_data[] = { {"marvell,ap806-pinctrl", (uintptr_t)&ap806_padconf}, {NULL, 0} }; #define RD4(sc, reg) SYSCON_READ_4((sc)->syscon, (reg)) #define WR4(sc, reg, val) SYSCON_WRITE_4((sc)->syscon, (reg), (val)) static void mv_pinctrl_configure_pin(struct mv_pinctrl_softc *sc, uint32_t pin, uint32_t function) { uint32_t offset, shift, reg; offset = (pin / PINS_PER_REG) * BITS_PER_PIN; shift = (pin % PINS_PER_REG) * BITS_PER_PIN; reg = RD4(sc, offset); reg &= ~(PINS_MASK << shift); reg |= function << shift; WR4(sc, offset, reg); } static int mv_pinctrl_configure_pins(device_t dev, phandle_t cfgxref) { struct mv_pinctrl_softc *sc; phandle_t node; char *function; const char **pins; int i, pin_num, pin_func, npins; sc = device_get_softc(dev); node = OF_node_from_xref(cfgxref); if (OF_getprop_alloc(node, "marvell,function", (void **)&function) == -1) return (ENOMEM); npins = ofw_bus_string_list_to_array(node, "marvell,pins", &pins); if (npins == -1) return (ENOMEM); for (i = 0; i < npins; i++) { for (pin_num = 0; pin_num < sc->padconf->npins; pin_num++) { if (strcmp(pins[i], sc->padconf->pins[pin_num].name) == 0) break; } if (pin_num == sc->padconf->npins) continue; for (pin_func = 0; pin_func < MAX_PIN_FUNC; pin_func++) if (sc->padconf->pins[pin_num].functions[pin_func] && strcmp(function, sc->padconf->pins[pin_num].functions[pin_func]) == 0) break; if (pin_func == MAX_PIN_FUNC) continue; mv_pinctrl_configure_pin(sc, pin_num, pin_func); } OF_prop_free(pins); return (0); } static int mv_pinctrl_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "Marvell Pinctrl controller"); return (BUS_PROBE_DEFAULT); } static int mv_pinctrl_attach(device_t dev) { struct mv_pinctrl_softc *sc; sc = device_get_softc(dev); sc->dev = dev; sc->padconf = (struct mv_padconf *) ofw_bus_search_compatible(dev,compat_data)->ocd_data; if (SYSCON_GET_HANDLE(sc->dev, &sc->syscon) != 0 || sc->syscon == NULL) { device_printf(dev, "cannot get syscon for device\n"); return (ENXIO); } fdt_pinctrl_register(dev, "marvell,pins"); fdt_pinctrl_configure_tree(dev); return (0); } static int mv_pinctrl_detach(device_t dev) { return (EBUSY); } static device_method_t mv_pinctrl_methods[] = { /* Device interface */ DEVMETHOD(device_probe, mv_pinctrl_probe), DEVMETHOD(device_attach, mv_pinctrl_attach), DEVMETHOD(device_detach, mv_pinctrl_detach), /* fdt_pinctrl interface */ DEVMETHOD(fdt_pinctrl_configure,mv_pinctrl_configure_pins), DEVMETHOD_END }; static driver_t mv_pinctrl_driver = { "mv_pinctrl", mv_pinctrl_methods, sizeof(struct mv_pinctrl_softc), }; EARLY_DRIVER_MODULE(mv_pinctrl, simplebus, mv_pinctrl_driver, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE); diff --git a/sys/arm/ti/am335x/am335x_musb.c b/sys/arm/ti/am335x/am335x_musb.c index b24f12990640..93cb7cef41b9 100644 --- a/sys/arm/ti/am335x/am335x_musb.c +++ b/sys/arm/ti/am335x/am335x_musb.c @@ -1,457 +1,457 @@ /*- * Copyright (c) 2013 Oleksandr Tymoshenko * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define USB_DEBUG_VAR usbssdebug #include #include #include #include #include #include #include #include -#include +#include #include "syscon_if.h" #define USBCTRL_REV 0x00 #define USBCTRL_CTRL 0x14 #define USBCTRL_STAT 0x18 #define USBCTRL_IRQ_STAT0 0x30 #define IRQ_STAT0_RXSHIFT 16 #define IRQ_STAT0_TXSHIFT 0 #define USBCTRL_IRQ_STAT1 0x34 #define IRQ_STAT1_DRVVBUS (1 << 8) #define USBCTRL_INTEN_SET0 0x38 #define USBCTRL_INTEN_SET1 0x3C #define USBCTRL_INTEN_USB_ALL 0x1ff #define USBCTRL_INTEN_USB_SOF (1 << 3) #define USBCTRL_INTEN_CLR0 0x40 #define USBCTRL_INTEN_CLR1 0x44 #define USBCTRL_UTMI 0xE0 #define USBCTRL_UTMI_FSDATAEXT (1 << 1) #define USBCTRL_MODE 0xE8 #define USBCTRL_MODE_IDDIG (1 << 8) #define USBCTRL_MODE_IDDIGMUX (1 << 7) /* USBSS resource + 2 MUSB ports */ #define RES_USBCORE 0 #define RES_USBCTRL 1 #define USB_WRITE4(sc, idx, reg, val) do { \ bus_write_4((sc)->sc_mem_res[idx], (reg), (val)); \ } while (0) #define USB_READ4(sc, idx, reg) bus_read_4((sc)->sc_mem_res[idx], (reg)) #define USBCTRL_WRITE4(sc, reg, val) \ USB_WRITE4((sc), RES_USBCTRL, (reg), (val)) #define USBCTRL_READ4(sc, reg) \ USB_READ4((sc), RES_USBCTRL, (reg)) static struct resource_spec am335x_musbotg_mem_spec[] = { { SYS_RES_MEMORY, 0, RF_ACTIVE }, { SYS_RES_MEMORY, 1, RF_ACTIVE }, { -1, 0, 0 } }; #ifdef USB_DEBUG static int usbssdebug = 0; static SYSCTL_NODE(_hw_usb, OID_AUTO, am335x_usbss, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "AM335x USBSS"); SYSCTL_INT(_hw_usb_am335x_usbss, OID_AUTO, debug, CTLFLAG_RW, &usbssdebug, 0, "Debug level"); #endif static device_probe_t musbotg_probe; static device_attach_t musbotg_attach; static device_detach_t musbotg_detach; struct musbotg_super_softc { struct musbotg_softc sc_otg; struct resource *sc_mem_res[2]; int sc_irq_rid; struct syscon *syscon; }; static void musbotg_vbus_poll(struct musbotg_super_softc *sc) { uint32_t stat; if (sc->sc_otg.sc_mode == MUSB2_DEVICE_MODE) musbotg_vbus_interrupt(&sc->sc_otg, 1); else { stat = USBCTRL_READ4(sc, USBCTRL_STAT); musbotg_vbus_interrupt(&sc->sc_otg, stat & 1); } } /* * Arg to musbotg_clocks_on and musbot_clocks_off is * a uint32_t * pointing to the SCM register offset. */ static uint32_t USB_CTRL[] = {SCM_USB_CTRL0, SCM_USB_CTRL1}; static void musbotg_clocks_on(void *arg) { struct musbotg_softc *sc; struct musbotg_super_softc *ssc; uint32_t reg; sc = arg; ssc = sc->sc_platform_data; reg = SYSCON_READ_4(ssc->syscon, USB_CTRL[sc->sc_id]); reg &= ~3; /* Enable power */ reg |= 1 << 19; /* VBUS detect enable */ reg |= 1 << 20; /* Session end enable */ SYSCON_WRITE_4(ssc->syscon, USB_CTRL[sc->sc_id], reg); } static void musbotg_clocks_off(void *arg) { struct musbotg_softc *sc; struct musbotg_super_softc *ssc; uint32_t reg; sc = arg; ssc = sc->sc_platform_data; /* Disable power to PHY */ reg = SYSCON_READ_4(ssc->syscon, USB_CTRL[sc->sc_id]); SYSCON_WRITE_4(ssc->syscon, USB_CTRL[sc->sc_id], reg | 3); } static void musbotg_ep_int_set(struct musbotg_softc *sc, int ep, int on) { struct musbotg_super_softc *ssc = sc->sc_platform_data; uint32_t epmask; epmask = ((1 << ep) << IRQ_STAT0_RXSHIFT); epmask |= ((1 << ep) << IRQ_STAT0_TXSHIFT); if (on) USBCTRL_WRITE4(ssc, USBCTRL_INTEN_SET0, epmask); else USBCTRL_WRITE4(ssc, USBCTRL_INTEN_CLR0, epmask); } static void musbotg_wrapper_interrupt(void *arg) { struct musbotg_softc *sc = arg; struct musbotg_super_softc *ssc = sc->sc_platform_data; uint32_t stat, stat0, stat1; stat = USBCTRL_READ4(ssc, USBCTRL_STAT); stat0 = USBCTRL_READ4(ssc, USBCTRL_IRQ_STAT0); stat1 = USBCTRL_READ4(ssc, USBCTRL_IRQ_STAT1); if (stat0) USBCTRL_WRITE4(ssc, USBCTRL_IRQ_STAT0, stat0); if (stat1) USBCTRL_WRITE4(ssc, USBCTRL_IRQ_STAT1, stat1); DPRINTFN(4, "port%d: stat0=%08x stat1=%08x, stat=%08x\n", sc->sc_id, stat0, stat1, stat); if (stat1 & IRQ_STAT1_DRVVBUS) musbotg_vbus_interrupt(sc, stat & 1); musbotg_interrupt(arg, ((stat0 >> 16) & 0xffff), stat0 & 0xffff, stat1 & 0xff); } static int musbotg_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (!ofw_bus_is_compatible(dev, "ti,musb-am33xx")) return (ENXIO); device_set_desc(dev, "TI AM33xx integrated USB OTG controller"); return (BUS_PROBE_DEFAULT); } static int musbotg_attach(device_t dev) { struct musbotg_super_softc *sc = device_get_softc(dev); char mode[16]; int err; uint32_t reg; phandle_t opp_table; clk_t clk_usbotg_fck; sc->sc_otg.sc_id = device_get_unit(dev); /* FIXME: The devicetree needs to be updated to get a handle to the gate * usbotg_fck@47c. see TRM 8.1.12.2 CM_WKUP CM_CLKDCOLDO_DPLL_PER. */ err = clk_get_by_name(dev, "usbotg_fck@47c", &clk_usbotg_fck); if (err) { device_printf(dev, "Can not find usbotg_fck@47c\n"); return (ENXIO); } err = clk_enable(clk_usbotg_fck); if (err) { device_printf(dev, "Can not enable usbotg_fck@47c\n"); return (ENXIO); } /* FIXME: For now; Go and kidnap syscon from opp-table */ opp_table = OF_finddevice("/opp-table"); if (opp_table == -1) { device_printf(dev, "Cant find /opp-table\n"); return (ENXIO); } if (!OF_hasprop(opp_table, "syscon")) { device_printf(dev, "/opp-table missing syscon property\n"); return (ENXIO); } err = syscon_get_by_ofw_property(dev, opp_table, "syscon", &sc->syscon); if (err) { device_printf(dev, "Failed to get syscon\n"); return (ENXIO); } /* Request the memory resources */ err = bus_alloc_resources(dev, am335x_musbotg_mem_spec, sc->sc_mem_res); if (err) { device_printf(dev, "Error: could not allocate mem resources\n"); return (ENXIO); } /* Request the IRQ resources */ sc->sc_otg.sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->sc_irq_rid, RF_ACTIVE); if (sc->sc_otg.sc_irq_res == NULL) { device_printf(dev, "Error: could not allocate irq resources\n"); return (ENXIO); } /* setup MUSB OTG USB controller interface softc */ sc->sc_otg.sc_clocks_on = &musbotg_clocks_on; sc->sc_otg.sc_clocks_off = &musbotg_clocks_off; sc->sc_otg.sc_clocks_arg = &sc->sc_otg; sc->sc_otg.sc_ep_int_set = musbotg_ep_int_set; /* initialise some bus fields */ sc->sc_otg.sc_bus.parent = dev; sc->sc_otg.sc_bus.devices = sc->sc_otg.sc_devices; sc->sc_otg.sc_bus.devices_max = MUSB2_MAX_DEVICES; sc->sc_otg.sc_bus.dma_bits = 32; /* get all DMA memory */ if (usb_bus_mem_alloc_all(&sc->sc_otg.sc_bus, USB_GET_DMA_TAG(dev), NULL)) { device_printf(dev, "Failed allocate bus mem for musb\n"); return (ENOMEM); } sc->sc_otg.sc_io_res = sc->sc_mem_res[RES_USBCORE]; sc->sc_otg.sc_io_tag = rman_get_bustag(sc->sc_otg.sc_io_res); sc->sc_otg.sc_io_hdl = rman_get_bushandle(sc->sc_otg.sc_io_res); sc->sc_otg.sc_io_size = rman_get_size(sc->sc_otg.sc_io_res); sc->sc_otg.sc_bus.bdev = device_add_child(dev, "usbus", -1); if (!(sc->sc_otg.sc_bus.bdev)) { device_printf(dev, "No busdev for musb\n"); goto error; } device_set_ivars(sc->sc_otg.sc_bus.bdev, &sc->sc_otg.sc_bus); err = bus_setup_intr(dev, sc->sc_otg.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, NULL, (driver_intr_t *)musbotg_wrapper_interrupt, &sc->sc_otg, &sc->sc_otg.sc_intr_hdl); if (err) { sc->sc_otg.sc_intr_hdl = NULL; device_printf(dev, "Failed to setup interrupt for musb\n"); goto error; } sc->sc_otg.sc_platform_data = sc; if (OF_getprop(ofw_bus_get_node(dev), "dr_mode", mode, sizeof(mode)) > 0) { if (strcasecmp(mode, "host") == 0) sc->sc_otg.sc_mode = MUSB2_HOST_MODE; else sc->sc_otg.sc_mode = MUSB2_DEVICE_MODE; } else { /* Beaglebone defaults: USB0 device, USB1 HOST. */ if (sc->sc_otg.sc_id == 0) sc->sc_otg.sc_mode = MUSB2_DEVICE_MODE; else sc->sc_otg.sc_mode = MUSB2_HOST_MODE; } /* * software-controlled function */ if (sc->sc_otg.sc_mode == MUSB2_HOST_MODE) { reg = USBCTRL_READ4(sc, USBCTRL_MODE); reg |= USBCTRL_MODE_IDDIGMUX; reg &= ~USBCTRL_MODE_IDDIG; USBCTRL_WRITE4(sc, USBCTRL_MODE, reg); USBCTRL_WRITE4(sc, USBCTRL_UTMI, USBCTRL_UTMI_FSDATAEXT); } else { reg = USBCTRL_READ4(sc, USBCTRL_MODE); reg |= USBCTRL_MODE_IDDIGMUX; reg |= USBCTRL_MODE_IDDIG; USBCTRL_WRITE4(sc, USBCTRL_MODE, reg); } reg = USBCTRL_INTEN_USB_ALL & ~USBCTRL_INTEN_USB_SOF; USBCTRL_WRITE4(sc, USBCTRL_INTEN_SET1, reg); USBCTRL_WRITE4(sc, USBCTRL_INTEN_CLR0, 0xffffffff); err = musbotg_init(&sc->sc_otg); if (!err) err = device_probe_and_attach(sc->sc_otg.sc_bus.bdev); if (err) goto error; /* poll VBUS one time */ musbotg_vbus_poll(sc); return (0); error: musbotg_detach(dev); return (ENXIO); } static int musbotg_detach(device_t dev) { struct musbotg_super_softc *sc = device_get_softc(dev); /* during module unload there are lots of children leftover */ device_delete_children(dev); if (sc->sc_otg.sc_irq_res && sc->sc_otg.sc_intr_hdl) { /* * only call musbotg_uninit() after musbotg_init() */ musbotg_uninit(&sc->sc_otg); bus_teardown_intr(dev, sc->sc_otg.sc_irq_res, sc->sc_otg.sc_intr_hdl); sc->sc_otg.sc_intr_hdl = NULL; } usb_bus_mem_free_all(&sc->sc_otg.sc_bus, NULL); /* Free resources if any */ if (sc->sc_mem_res[0]) bus_release_resources(dev, am335x_musbotg_mem_spec, sc->sc_mem_res); if (sc->sc_otg.sc_irq_res) bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irq_rid, sc->sc_otg.sc_irq_res); return (0); } static device_method_t musbotg_methods[] = { /* Device interface */ DEVMETHOD(device_probe, musbotg_probe), DEVMETHOD(device_attach, musbotg_attach), DEVMETHOD(device_detach, musbotg_detach), DEVMETHOD(device_suspend, bus_generic_suspend), DEVMETHOD(device_resume, bus_generic_resume), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD_END }; static driver_t musbotg_driver = { .name = "musbotg", .methods = musbotg_methods, .size = sizeof(struct musbotg_super_softc), }; DRIVER_MODULE(musbotg, ti_sysc, musbotg_driver, 0, 0); MODULE_DEPEND(musbotg, ti_sysc, 1, 1, 1); MODULE_DEPEND(musbotg, ti_am3359_cppi41, 1, 1, 1); MODULE_DEPEND(usbss, usb, 1, 1, 1); diff --git a/sys/arm/ti/am335x/am335x_pwmss.c b/sys/arm/ti/am335x/am335x_pwmss.c index c4a045503b1e..8766c706b807 100644 --- a/sys/arm/ti/am335x/am335x_pwmss.c +++ b/sys/arm/ti/am335x/am335x_pwmss.c @@ -1,175 +1,175 @@ /*- * Copyright (c) 2013 Oleksandr Tymoshenko * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include "syscon_if.h" #include "am335x_pwm.h" #include "am335x_scm.h" #define PWMSS_IDVER 0x00 #define PWMSS_SYSCONFIG 0x04 #define PWMSS_CLKCONFIG 0x08 #define CLKCONFIG_EPWMCLK_EN (1 << 8) #define PWMSS_CLKSTATUS 0x0C /* TRM chapter 2 memory map table 2-3 + VER register location */ #define PWMSS_REV_0 0x0000 #define PWMSS_REV_1 0x2000 #define PWMSS_REV_2 0x4000 static device_probe_t am335x_pwmss_probe; static device_attach_t am335x_pwmss_attach; static device_detach_t am335x_pwmss_detach; struct am335x_pwmss_softc { struct simplebus_softc sc_simplebus; device_t sc_dev; struct syscon *syscon; }; static device_method_t am335x_pwmss_methods[] = { DEVMETHOD(device_probe, am335x_pwmss_probe), DEVMETHOD(device_attach, am335x_pwmss_attach), DEVMETHOD(device_detach, am335x_pwmss_detach), DEVMETHOD_END }; static int am335x_pwmss_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (!ofw_bus_is_compatible(dev, "ti,am33xx-pwmss")) return (ENXIO); device_set_desc(dev, "AM335x PWM"); return (BUS_PROBE_DEFAULT); } static int am335x_pwmss_attach(device_t dev) { struct am335x_pwmss_softc *sc; uint32_t reg, id; uint64_t rev_address; phandle_t node, opp_table; sc = device_get_softc(dev); sc->sc_dev = dev; /* FIXME: For now; Go and kidnap syscon from opp-table */ opp_table = OF_finddevice("/opp-table"); if (opp_table == -1) { device_printf(dev, "Cant find /opp-table\n"); return (ENXIO); } if (!OF_hasprop(opp_table, "syscon")) { device_printf(dev, "/opp-table doesnt have required syscon property\n"); return (ENXIO); } if (syscon_get_by_ofw_property(dev, opp_table, "syscon", &sc->syscon) != 0) { device_printf(dev, "Failed to get syscon\n"); return (ENXIO); } ti_sysc_clock_enable(device_get_parent(dev)); rev_address = ti_sysc_get_rev_address(device_get_parent(dev)); switch (rev_address) { case PWMSS_REV_0: id = 0; break; case PWMSS_REV_1: id = 1; break; case PWMSS_REV_2: id = 2; break; } reg = SYSCON_READ_4(sc->syscon, SCM_PWMSS_CTRL); reg |= (1 << id); SYSCON_WRITE_4(sc->syscon, SCM_PWMSS_CTRL, reg); node = ofw_bus_get_node(dev); if (node == -1) return (ENXIO); simplebus_init(dev, node); /* * Allow devices to identify. */ bus_generic_probe(dev); /* * Now walk the OFW tree and attach top-level devices. */ for (node = OF_child(node); node > 0; node = OF_peer(node)) simplebus_add_device(dev, node, 0, NULL, -1, NULL); return (bus_generic_attach(dev)); } static int am335x_pwmss_detach(device_t dev) { return (0); } DEFINE_CLASS_1(am335x_pwmss, am335x_pwmss_driver, am335x_pwmss_methods, sizeof(struct am335x_pwmss_softc), simplebus_driver); DRIVER_MODULE(am335x_pwmss, simplebus, am335x_pwmss_driver, 0, 0); MODULE_VERSION(am335x_pwmss, 1); MODULE_DEPEND(am335x_pwmss, ti_sysc, 1, 1, 1); diff --git a/sys/arm/ti/am335x/am335x_scm.c b/sys/arm/ti/am335x/am335x_scm.c index 1a4fd0ed6325..214a9dfdf18b 100644 --- a/sys/arm/ti/am335x/am335x_scm.c +++ b/sys/arm/ti/am335x/am335x_scm.c @@ -1,193 +1,193 @@ /*- * Copyright (c) 2016 Rubicon Communications, LLC (Netgate) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include -#include +#include #include "syscon_if.h" #define TZ_ZEROC 2731 struct am335x_scm_softc { int sc_last_temp; struct sysctl_oid *sc_temp_oid; struct syscon *syscon; }; static int am335x_scm_temp_sysctl(SYSCTL_HANDLER_ARGS) { device_t dev; int i, temp; struct am335x_scm_softc *sc; uint32_t reg; dev = (device_t)arg1; sc = device_get_softc(dev); /* Read the temperature and convert to Kelvin. */ for(i = 50; i > 0; i--) { reg = SYSCON_READ_4(sc->syscon, SCM_BGAP_CTRL); if ((reg & SCM_BGAP_EOCZ) == 0) break; DELAY(50); } if ((reg & SCM_BGAP_EOCZ) == 0) { sc->sc_last_temp = (reg >> SCM_BGAP_TEMP_SHIFT) & SCM_BGAP_TEMP_MASK; sc->sc_last_temp *= 10; } temp = sc->sc_last_temp + TZ_ZEROC; return (sysctl_handle_int(oidp, &temp, 0, req)); } static void am335x_scm_identify(driver_t *driver, device_t parent) { device_t child; /* AM335x only. */ if (ti_chip() != CHIP_AM335X) return; /* Make sure we attach only once. */ if (device_find_child(parent, "am335x_scm", -1) != NULL) return; child = device_add_child(parent, "am335x_scm", -1); if (child == NULL) device_printf(parent, "cannot add ti_scm child\n"); } static int am335x_scm_probe(device_t dev) { /* Just allow the first one */ if (strcmp(device_get_nameunit(dev), "am335x_scm0") != 0) return (ENXIO); device_set_desc(dev, "AM335x Control Module Extension"); return (BUS_PROBE_DEFAULT); } static int am335x_scm_attach(device_t dev) { struct am335x_scm_softc *sc; struct sysctl_ctx_list *ctx; struct sysctl_oid_list *tree; uint32_t reg; phandle_t opp_table; int err; sc = device_get_softc(dev); /* FIXME: For now; Go and kidnap syscon from opp-table */ opp_table = OF_finddevice("/opp-table"); if (opp_table == -1) { device_printf(dev, "Cant find /opp-table\n"); return (ENXIO); } if (!OF_hasprop(opp_table, "syscon")) { device_printf(dev, "/opp-table missing syscon property\n"); return (ENXIO); } err = syscon_get_by_ofw_property(dev, opp_table, "syscon", &sc->syscon); if (err) { device_printf(dev, "Failed to get syscon\n"); return (ENXIO); } /* Reset the digital outputs. */ SYSCON_WRITE_4(sc->syscon, SCM_BGAP_CTRL, 0); reg = SYSCON_READ_4(sc->syscon, SCM_BGAP_CTRL); DELAY(500); /* Set continuous mode. */ SYSCON_WRITE_4(sc->syscon, SCM_BGAP_CTRL, SCM_BGAP_CONTCONV); reg = SYSCON_READ_4(sc->syscon, SCM_BGAP_CTRL); DELAY(500); /* Start the ADC conversion. */ reg = SCM_BGAP_CLRZ | SCM_BGAP_CONTCONV | SCM_BGAP_SOC; SYSCON_WRITE_4(sc->syscon, SCM_BGAP_CTRL, reg); /* Temperature sysctl. */ ctx = device_get_sysctl_ctx(dev); tree = SYSCTL_CHILDREN(device_get_sysctl_tree(dev)); sc->sc_temp_oid = SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "temperature", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, dev, 0, am335x_scm_temp_sysctl, "IK", "Current temperature"); return (0); } static int am335x_scm_detach(device_t dev) { struct am335x_scm_softc *sc; sc = device_get_softc(dev); /* Remove temperature sysctl. */ if (sc->sc_temp_oid != NULL) sysctl_remove_oid(sc->sc_temp_oid, 1, 0); /* Stop the bandgap ADC. */ SYSCON_WRITE_4(sc->syscon, SCM_BGAP_CTRL, SCM_BGAP_BGOFF); return (0); } static device_method_t am335x_scm_methods[] = { DEVMETHOD(device_identify, am335x_scm_identify), DEVMETHOD(device_probe, am335x_scm_probe), DEVMETHOD(device_attach, am335x_scm_attach), DEVMETHOD(device_detach, am335x_scm_detach), DEVMETHOD_END }; static driver_t am335x_scm_driver = { "am335x_scm", am335x_scm_methods, sizeof(struct am335x_scm_softc), }; DRIVER_MODULE(am335x_scm, ti_scm, am335x_scm_driver, 0, 0); MODULE_VERSION(am335x_scm, 1); MODULE_DEPEND(am335x_scm, ti_scm_syscon, 1, 1, 1); diff --git a/sys/arm/ti/cpsw/if_cpsw.c b/sys/arm/ti/cpsw/if_cpsw.c index 223d24019cb8..c2651c33e1b1 100644 --- a/sys/arm/ti/cpsw/if_cpsw.c +++ b/sys/arm/ti/cpsw/if_cpsw.c @@ -1,3021 +1,3021 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2012 Damjan Marion * Copyright (c) 2016 Rubicon Communications, LLC (Netgate) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * TI Common Platform Ethernet Switch (CPSW) Driver * Found in TI8148 "DaVinci" and AM335x "Sitara" SoCs. * * This controller is documented in the AM335x Technical Reference * Manual, in the TMS320DM814x DaVinci Digital Video Processors TRM * and in the TMS320C6452 3 Port Switch Ethernet Subsystem TRM. * * It is basically a single Ethernet port (port 0) wired internally to * a 3-port store-and-forward switch connected to two independent * "sliver" controllers (port 1 and port 2). You can operate the * controller in a variety of different ways by suitably configuring * the slivers and the Address Lookup Engine (ALE) that routes packets * between the ports. * * This code was developed and tested on a BeagleBone with * an AM335x SoC. */ #include #include "opt_cpsw.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include "syscon_if.h" #include #include #include #include #include #include #ifdef CPSW_ETHERSWITCH #include #include "etherswitch_if.h" #endif #include "if_cpswreg.h" #include "if_cpswvar.h" #include "miibus_if.h" /* Device probe/attach/detach. */ static int cpsw_probe(device_t); static int cpsw_attach(device_t); static int cpsw_detach(device_t); static int cpswp_probe(device_t); static int cpswp_attach(device_t); static int cpswp_detach(device_t); static phandle_t cpsw_get_node(device_t, device_t); /* Device Init/shutdown. */ static int cpsw_shutdown(device_t); static void cpswp_init(void *); static void cpswp_init_locked(void *); static void cpswp_stop_locked(struct cpswp_softc *); /* Device Suspend/Resume. */ static int cpsw_suspend(device_t); static int cpsw_resume(device_t); /* Ioctl. */ static int cpswp_ioctl(if_t, u_long command, caddr_t data); static int cpswp_miibus_readreg(device_t, int phy, int reg); static int cpswp_miibus_writereg(device_t, int phy, int reg, int value); static void cpswp_miibus_statchg(device_t); /* Send/Receive packets. */ static void cpsw_intr_rx(void *arg); static struct mbuf *cpsw_rx_dequeue(struct cpsw_softc *); static void cpsw_rx_enqueue(struct cpsw_softc *); static void cpswp_start(if_t); static void cpsw_intr_tx(void *); static void cpswp_tx_enqueue(struct cpswp_softc *); static int cpsw_tx_dequeue(struct cpsw_softc *); /* Misc interrupts and watchdog. */ static void cpsw_intr_rx_thresh(void *); static void cpsw_intr_misc(void *); static void cpswp_tick(void *); static void cpswp_ifmedia_sts(if_t, struct ifmediareq *); static int cpswp_ifmedia_upd(if_t); static void cpsw_tx_watchdog(void *); /* ALE support */ static void cpsw_ale_read_entry(struct cpsw_softc *, uint16_t, uint32_t *); static void cpsw_ale_write_entry(struct cpsw_softc *, uint16_t, uint32_t *); static int cpsw_ale_mc_entry_set(struct cpsw_softc *, uint8_t, int, uint8_t *); static void cpsw_ale_dump_table(struct cpsw_softc *); static int cpsw_ale_update_vlan_table(struct cpsw_softc *, int, int, int, int, int); static int cpswp_ale_update_addresses(struct cpswp_softc *, int); /* Statistics and sysctls. */ static void cpsw_add_sysctls(struct cpsw_softc *); static void cpsw_stats_collect(struct cpsw_softc *); static int cpsw_stats_sysctl(SYSCTL_HANDLER_ARGS); #ifdef CPSW_ETHERSWITCH static etherswitch_info_t *cpsw_getinfo(device_t); static int cpsw_getport(device_t, etherswitch_port_t *); static int cpsw_setport(device_t, etherswitch_port_t *); static int cpsw_getconf(device_t, etherswitch_conf_t *); static int cpsw_getvgroup(device_t, etherswitch_vlangroup_t *); static int cpsw_setvgroup(device_t, etherswitch_vlangroup_t *); static int cpsw_readreg(device_t, int); static int cpsw_writereg(device_t, int, int); static int cpsw_readphy(device_t, int, int); static int cpsw_writephy(device_t, int, int, int); #endif /* * Arbitrary limit on number of segments in an mbuf to be transmitted. * Packets with more segments than this will be defragmented before * they are queued. */ #define CPSW_TXFRAGS 16 /* Shared resources. */ static device_method_t cpsw_methods[] = { /* Device interface */ DEVMETHOD(device_probe, cpsw_probe), DEVMETHOD(device_attach, cpsw_attach), DEVMETHOD(device_detach, cpsw_detach), DEVMETHOD(device_shutdown, cpsw_shutdown), DEVMETHOD(device_suspend, cpsw_suspend), DEVMETHOD(device_resume, cpsw_resume), /* Bus interface */ DEVMETHOD(bus_add_child, device_add_child_ordered), /* OFW methods */ DEVMETHOD(ofw_bus_get_node, cpsw_get_node), #ifdef CPSW_ETHERSWITCH /* etherswitch interface */ DEVMETHOD(etherswitch_getinfo, cpsw_getinfo), DEVMETHOD(etherswitch_readreg, cpsw_readreg), DEVMETHOD(etherswitch_writereg, cpsw_writereg), DEVMETHOD(etherswitch_readphyreg, cpsw_readphy), DEVMETHOD(etherswitch_writephyreg, cpsw_writephy), DEVMETHOD(etherswitch_getport, cpsw_getport), DEVMETHOD(etherswitch_setport, cpsw_setport), DEVMETHOD(etherswitch_getvgroup, cpsw_getvgroup), DEVMETHOD(etherswitch_setvgroup, cpsw_setvgroup), DEVMETHOD(etherswitch_getconf, cpsw_getconf), #endif DEVMETHOD_END }; static driver_t cpsw_driver = { "cpswss", cpsw_methods, sizeof(struct cpsw_softc), }; DRIVER_MODULE(cpswss, simplebus, cpsw_driver, 0, 0); /* Port/Slave resources. */ static device_method_t cpswp_methods[] = { /* Device interface */ DEVMETHOD(device_probe, cpswp_probe), DEVMETHOD(device_attach, cpswp_attach), DEVMETHOD(device_detach, cpswp_detach), /* MII interface */ DEVMETHOD(miibus_readreg, cpswp_miibus_readreg), DEVMETHOD(miibus_writereg, cpswp_miibus_writereg), DEVMETHOD(miibus_statchg, cpswp_miibus_statchg), DEVMETHOD_END }; static driver_t cpswp_driver = { "cpsw", cpswp_methods, sizeof(struct cpswp_softc), }; #ifdef CPSW_ETHERSWITCH DRIVER_MODULE(etherswitch, cpswss, etherswitch_driver, 0, 0); MODULE_DEPEND(cpswss, etherswitch, 1, 1, 1); #endif DRIVER_MODULE(cpsw, cpswss, cpswp_driver, 0, 0); DRIVER_MODULE(miibus, cpsw, miibus_driver, 0, 0); MODULE_DEPEND(cpsw, ether, 1, 1, 1); MODULE_DEPEND(cpsw, miibus, 1, 1, 1); #ifdef CPSW_ETHERSWITCH static struct cpsw_vlangroups cpsw_vgroups[CPSW_VLANS]; #endif static uint32_t slave_mdio_addr[] = { 0x4a100200, 0x4a100300 }; static struct resource_spec irq_res_spec[] = { { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE }, { SYS_RES_IRQ, 1, RF_ACTIVE | RF_SHAREABLE }, { SYS_RES_IRQ, 2, RF_ACTIVE | RF_SHAREABLE }, { SYS_RES_IRQ, 3, RF_ACTIVE | RF_SHAREABLE }, { -1, 0 } }; static struct { void (*cb)(void *); } cpsw_intr_cb[] = { { cpsw_intr_rx_thresh }, { cpsw_intr_rx }, { cpsw_intr_tx }, { cpsw_intr_misc }, }; /* Number of entries here must match size of stats * array in struct cpswp_softc. */ static struct cpsw_stat { int reg; char *oid; } cpsw_stat_sysctls[CPSW_SYSCTL_COUNT] = { {0x00, "GoodRxFrames"}, {0x04, "BroadcastRxFrames"}, {0x08, "MulticastRxFrames"}, {0x0C, "PauseRxFrames"}, {0x10, "RxCrcErrors"}, {0x14, "RxAlignErrors"}, {0x18, "OversizeRxFrames"}, {0x1c, "RxJabbers"}, {0x20, "ShortRxFrames"}, {0x24, "RxFragments"}, {0x30, "RxOctets"}, {0x34, "GoodTxFrames"}, {0x38, "BroadcastTxFrames"}, {0x3c, "MulticastTxFrames"}, {0x40, "PauseTxFrames"}, {0x44, "DeferredTxFrames"}, {0x48, "CollisionsTxFrames"}, {0x4c, "SingleCollisionTxFrames"}, {0x50, "MultipleCollisionTxFrames"}, {0x54, "ExcessiveCollisions"}, {0x58, "LateCollisions"}, {0x5c, "TxUnderrun"}, {0x60, "CarrierSenseErrors"}, {0x64, "TxOctets"}, {0x68, "RxTx64OctetFrames"}, {0x6c, "RxTx65to127OctetFrames"}, {0x70, "RxTx128to255OctetFrames"}, {0x74, "RxTx256to511OctetFrames"}, {0x78, "RxTx512to1024OctetFrames"}, {0x7c, "RxTx1024upOctetFrames"}, {0x80, "NetOctets"}, {0x84, "RxStartOfFrameOverruns"}, {0x88, "RxMiddleOfFrameOverruns"}, {0x8c, "RxDmaOverruns"} }; /* * Basic debug support. */ static void cpsw_debugf_head(const char *funcname) { int t = (int)(time_second % (24 * 60 * 60)); printf("%02d:%02d:%02d %s ", t / (60 * 60), (t / 60) % 60, t % 60, funcname); } static void cpsw_debugf(const char *fmt, ...) { va_list ap; va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); printf("\n"); } #define CPSW_DEBUGF(_sc, a) do { \ if ((_sc)->debug) { \ cpsw_debugf_head(__func__); \ cpsw_debugf a; \ } \ } while (0) /* * Locking macros */ #define CPSW_TX_LOCK(sc) do { \ mtx_assert(&(sc)->rx.lock, MA_NOTOWNED); \ mtx_lock(&(sc)->tx.lock); \ } while (0) #define CPSW_TX_UNLOCK(sc) mtx_unlock(&(sc)->tx.lock) #define CPSW_TX_LOCK_ASSERT(sc) mtx_assert(&(sc)->tx.lock, MA_OWNED) #define CPSW_RX_LOCK(sc) do { \ mtx_assert(&(sc)->tx.lock, MA_NOTOWNED); \ mtx_lock(&(sc)->rx.lock); \ } while (0) #define CPSW_RX_UNLOCK(sc) mtx_unlock(&(sc)->rx.lock) #define CPSW_RX_LOCK_ASSERT(sc) mtx_assert(&(sc)->rx.lock, MA_OWNED) #define CPSW_PORT_LOCK(_sc) do { \ mtx_assert(&(_sc)->lock, MA_NOTOWNED); \ mtx_lock(&(_sc)->lock); \ } while (0) #define CPSW_PORT_UNLOCK(_sc) mtx_unlock(&(_sc)->lock) #define CPSW_PORT_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->lock, MA_OWNED) /* * Read/Write macros */ #define cpsw_read_4(_sc, _reg) bus_read_4((_sc)->mem_res, (_reg)) #define cpsw_write_4(_sc, _reg, _val) \ bus_write_4((_sc)->mem_res, (_reg), (_val)) #define cpsw_cpdma_bd_offset(i) (CPSW_CPPI_RAM_OFFSET + ((i)*16)) #define cpsw_cpdma_bd_paddr(sc, slot) \ BUS_SPACE_PHYSADDR(sc->mem_res, slot->bd_offset) #define cpsw_cpdma_read_bd(sc, slot, val) \ bus_read_region_4(sc->mem_res, slot->bd_offset, (uint32_t *) val, 4) #define cpsw_cpdma_write_bd(sc, slot, val) \ bus_write_region_4(sc->mem_res, slot->bd_offset, (uint32_t *) val, 4) #define cpsw_cpdma_write_bd_next(sc, slot, next_slot) \ cpsw_write_4(sc, slot->bd_offset, cpsw_cpdma_bd_paddr(sc, next_slot)) #define cpsw_cpdma_write_bd_flags(sc, slot, val) \ bus_write_2(sc->mem_res, slot->bd_offset + 14, val) #define cpsw_cpdma_read_bd_flags(sc, slot) \ bus_read_2(sc->mem_res, slot->bd_offset + 14) #define cpsw_write_hdp_slot(sc, queue, slot) \ cpsw_write_4(sc, (queue)->hdp_offset, cpsw_cpdma_bd_paddr(sc, slot)) #define CP_OFFSET (CPSW_CPDMA_TX_CP(0) - CPSW_CPDMA_TX_HDP(0)) #define cpsw_read_cp(sc, queue) \ cpsw_read_4(sc, (queue)->hdp_offset + CP_OFFSET) #define cpsw_write_cp(sc, queue, val) \ cpsw_write_4(sc, (queue)->hdp_offset + CP_OFFSET, (val)) #define cpsw_write_cp_slot(sc, queue, slot) \ cpsw_write_cp(sc, queue, cpsw_cpdma_bd_paddr(sc, slot)) #if 0 /* XXX temporary function versions for debugging. */ static void cpsw_write_hdp_slotX(struct cpsw_softc *sc, struct cpsw_queue *queue, struct cpsw_slot *slot) { uint32_t reg = queue->hdp_offset; uint32_t v = cpsw_cpdma_bd_paddr(sc, slot); CPSW_DEBUGF(("HDP <=== 0x%08x (was 0x%08x)", v, cpsw_read_4(sc, reg))); cpsw_write_4(sc, reg, v); } static void cpsw_write_cp_slotX(struct cpsw_softc *sc, struct cpsw_queue *queue, struct cpsw_slot *slot) { uint32_t v = cpsw_cpdma_bd_paddr(sc, slot); CPSW_DEBUGF(("CP <=== 0x%08x (expecting 0x%08x)", v, cpsw_read_cp(sc, queue))); cpsw_write_cp(sc, queue, v); } #endif /* * Expanded dump routines for verbose debugging. */ static void cpsw_dump_slot(struct cpsw_softc *sc, struct cpsw_slot *slot) { static const char *flags[] = {"SOP", "EOP", "Owner", "EOQ", "TDownCmplt", "PassCRC", "Long", "Short", "MacCtl", "Overrun", "PktErr1", "PortEn/PktErr0", "RxVlanEncap", "Port2", "Port1", "Port0"}; struct cpsw_cpdma_bd bd; const char *sep; int i; cpsw_cpdma_read_bd(sc, slot, &bd); printf("BD Addr : 0x%08x Next : 0x%08x\n", cpsw_cpdma_bd_paddr(sc, slot), bd.next); printf(" BufPtr: 0x%08x BufLen: 0x%08x\n", bd.bufptr, bd.buflen); printf(" BufOff: 0x%08x PktLen: 0x%08x\n", bd.bufoff, bd.pktlen); printf(" Flags: "); sep = ""; for (i = 0; i < 16; ++i) { if (bd.flags & (1 << (15 - i))) { printf("%s%s", sep, flags[i]); sep = ","; } } printf("\n"); if (slot->mbuf) { printf(" Ether: %14D\n", (char *)(slot->mbuf->m_data), " "); printf(" Packet: %16D\n", (char *)(slot->mbuf->m_data) + 14, " "); } } #define CPSW_DUMP_SLOT(cs, slot) do { \ IF_DEBUG(sc) { \ cpsw_dump_slot(sc, slot); \ } \ } while (0) static void cpsw_dump_queue(struct cpsw_softc *sc, struct cpsw_slots *q) { struct cpsw_slot *slot; int i = 0; int others = 0; STAILQ_FOREACH(slot, q, next) { if (i > CPSW_TXFRAGS) ++others; else cpsw_dump_slot(sc, slot); ++i; } if (others) printf(" ... and %d more.\n", others); printf("\n"); } #define CPSW_DUMP_QUEUE(sc, q) do { \ IF_DEBUG(sc) { \ cpsw_dump_queue(sc, q); \ } \ } while (0) static void cpsw_init_slots(struct cpsw_softc *sc) { struct cpsw_slot *slot; int i; STAILQ_INIT(&sc->avail); /* Put the slot descriptors onto the global avail list. */ for (i = 0; i < nitems(sc->_slots); i++) { slot = &sc->_slots[i]; slot->bd_offset = cpsw_cpdma_bd_offset(i); STAILQ_INSERT_TAIL(&sc->avail, slot, next); } } static int cpsw_add_slots(struct cpsw_softc *sc, struct cpsw_queue *queue, int requested) { const int max_slots = nitems(sc->_slots); struct cpsw_slot *slot; int i; if (requested < 0) requested = max_slots; for (i = 0; i < requested; ++i) { slot = STAILQ_FIRST(&sc->avail); if (slot == NULL) return (0); if (bus_dmamap_create(sc->mbuf_dtag, 0, &slot->dmamap)) { device_printf(sc->dev, "failed to create dmamap\n"); return (ENOMEM); } STAILQ_REMOVE_HEAD(&sc->avail, next); STAILQ_INSERT_TAIL(&queue->avail, slot, next); ++queue->avail_queue_len; ++queue->queue_slots; } return (0); } static void cpsw_free_slot(struct cpsw_softc *sc, struct cpsw_slot *slot) { int error __diagused; if (slot->dmamap) { if (slot->mbuf) bus_dmamap_unload(sc->mbuf_dtag, slot->dmamap); error = bus_dmamap_destroy(sc->mbuf_dtag, slot->dmamap); KASSERT(error == 0, ("Mapping still active")); slot->dmamap = NULL; } if (slot->mbuf) { m_freem(slot->mbuf); slot->mbuf = NULL; } } static void cpsw_reset(struct cpsw_softc *sc) { int i; callout_stop(&sc->watchdog.callout); /* Reset RMII/RGMII wrapper. */ cpsw_write_4(sc, CPSW_WR_SOFT_RESET, 1); while (cpsw_read_4(sc, CPSW_WR_SOFT_RESET) & 1) ; /* Disable TX and RX interrupts for all cores. */ for (i = 0; i < 3; ++i) { cpsw_write_4(sc, CPSW_WR_C_RX_THRESH_EN(i), 0x00); cpsw_write_4(sc, CPSW_WR_C_TX_EN(i), 0x00); cpsw_write_4(sc, CPSW_WR_C_RX_EN(i), 0x00); cpsw_write_4(sc, CPSW_WR_C_MISC_EN(i), 0x00); } /* Reset CPSW subsystem. */ cpsw_write_4(sc, CPSW_SS_SOFT_RESET, 1); while (cpsw_read_4(sc, CPSW_SS_SOFT_RESET) & 1) ; /* Reset Sliver port 1 and 2 */ for (i = 0; i < 2; i++) { /* Reset */ cpsw_write_4(sc, CPSW_SL_SOFT_RESET(i), 1); while (cpsw_read_4(sc, CPSW_SL_SOFT_RESET(i)) & 1) ; } /* Reset DMA controller. */ cpsw_write_4(sc, CPSW_CPDMA_SOFT_RESET, 1); while (cpsw_read_4(sc, CPSW_CPDMA_SOFT_RESET) & 1) ; /* Disable TX & RX DMA */ cpsw_write_4(sc, CPSW_CPDMA_TX_CONTROL, 0); cpsw_write_4(sc, CPSW_CPDMA_RX_CONTROL, 0); /* Clear all queues. */ for (i = 0; i < 8; i++) { cpsw_write_4(sc, CPSW_CPDMA_TX_HDP(i), 0); cpsw_write_4(sc, CPSW_CPDMA_RX_HDP(i), 0); cpsw_write_4(sc, CPSW_CPDMA_TX_CP(i), 0); cpsw_write_4(sc, CPSW_CPDMA_RX_CP(i), 0); } /* Clear all interrupt Masks */ cpsw_write_4(sc, CPSW_CPDMA_RX_INTMASK_CLEAR, 0xFFFFFFFF); cpsw_write_4(sc, CPSW_CPDMA_TX_INTMASK_CLEAR, 0xFFFFFFFF); } static void cpsw_init(struct cpsw_softc *sc) { struct cpsw_slot *slot; uint32_t reg; /* Disable the interrupt pacing. */ reg = cpsw_read_4(sc, CPSW_WR_INT_CONTROL); reg &= ~(CPSW_WR_INT_PACE_EN | CPSW_WR_INT_PRESCALE_MASK); cpsw_write_4(sc, CPSW_WR_INT_CONTROL, reg); /* Clear ALE */ cpsw_write_4(sc, CPSW_ALE_CONTROL, CPSW_ALE_CTL_CLEAR_TBL); /* Enable ALE */ reg = CPSW_ALE_CTL_ENABLE; if (sc->dualemac) reg |= CPSW_ALE_CTL_VLAN_AWARE; cpsw_write_4(sc, CPSW_ALE_CONTROL, reg); /* Set Host Port Mapping. */ cpsw_write_4(sc, CPSW_PORT_P0_CPDMA_TX_PRI_MAP, 0x76543210); cpsw_write_4(sc, CPSW_PORT_P0_CPDMA_RX_CH_MAP, 0); /* Initialize ALE: set host port to forwarding(3). */ cpsw_write_4(sc, CPSW_ALE_PORTCTL(0), ALE_PORTCTL_INGRESS | ALE_PORTCTL_FORWARD); cpsw_write_4(sc, CPSW_SS_PTYPE, 0); /* Enable statistics for ports 0, 1 and 2 */ cpsw_write_4(sc, CPSW_SS_STAT_PORT_EN, 7); /* Turn off flow control. */ cpsw_write_4(sc, CPSW_SS_FLOW_CONTROL, 0); /* Make IP hdr aligned with 4 */ cpsw_write_4(sc, CPSW_CPDMA_RX_BUFFER_OFFSET, 2); /* Initialize RX Buffer Descriptors */ cpsw_write_4(sc, CPSW_CPDMA_RX_PENDTHRESH(0), 0); cpsw_write_4(sc, CPSW_CPDMA_RX_FREEBUFFER(0), 0); /* Enable TX & RX DMA */ cpsw_write_4(sc, CPSW_CPDMA_TX_CONTROL, 1); cpsw_write_4(sc, CPSW_CPDMA_RX_CONTROL, 1); /* Enable Interrupts for core 0 */ cpsw_write_4(sc, CPSW_WR_C_RX_THRESH_EN(0), 0xFF); cpsw_write_4(sc, CPSW_WR_C_RX_EN(0), 0xFF); cpsw_write_4(sc, CPSW_WR_C_TX_EN(0), 0xFF); cpsw_write_4(sc, CPSW_WR_C_MISC_EN(0), 0x1F); /* Enable host Error Interrupt */ cpsw_write_4(sc, CPSW_CPDMA_DMA_INTMASK_SET, 3); /* Enable interrupts for RX and TX on Channel 0 */ cpsw_write_4(sc, CPSW_CPDMA_RX_INTMASK_SET, CPSW_CPDMA_RX_INT(0) | CPSW_CPDMA_RX_INT_THRESH(0)); cpsw_write_4(sc, CPSW_CPDMA_TX_INTMASK_SET, 1); /* Initialze MDIO - ENABLE, PREAMBLE=0, FAULTENB, CLKDIV=0xFF */ /* TODO Calculate MDCLK=CLK/(CLKDIV+1) */ cpsw_write_4(sc, MDIOCONTROL, MDIOCTL_ENABLE | MDIOCTL_FAULTENB | 0xff); /* Select MII in GMII_SEL, Internal Delay mode */ //ti_scm_reg_write_4(0x650, 0); /* Initialize active queues. */ slot = STAILQ_FIRST(&sc->tx.active); if (slot != NULL) cpsw_write_hdp_slot(sc, &sc->tx, slot); slot = STAILQ_FIRST(&sc->rx.active); if (slot != NULL) cpsw_write_hdp_slot(sc, &sc->rx, slot); cpsw_rx_enqueue(sc); cpsw_write_4(sc, CPSW_CPDMA_RX_FREEBUFFER(0), sc->rx.active_queue_len); cpsw_write_4(sc, CPSW_CPDMA_RX_PENDTHRESH(0), CPSW_TXFRAGS); /* Activate network interface. */ sc->rx.running = 1; sc->tx.running = 1; sc->watchdog.timer = 0; callout_init(&sc->watchdog.callout, 0); callout_reset(&sc->watchdog.callout, hz, cpsw_tx_watchdog, sc); } /* * * Device Probe, Attach, Detach. * */ static int cpsw_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (!ofw_bus_is_compatible(dev, "ti,cpsw")) return (ENXIO); device_set_desc(dev, "3-port Switch Ethernet Subsystem"); return (BUS_PROBE_DEFAULT); } static int cpsw_intr_attach(struct cpsw_softc *sc) { int i; for (i = 0; i < CPSW_INTR_COUNT; i++) { if (bus_setup_intr(sc->dev, sc->irq_res[i], INTR_TYPE_NET | INTR_MPSAFE, NULL, cpsw_intr_cb[i].cb, sc, &sc->ih_cookie[i]) != 0) { return (-1); } } return (0); } static void cpsw_intr_detach(struct cpsw_softc *sc) { int i; for (i = 0; i < CPSW_INTR_COUNT; i++) { if (sc->ih_cookie[i]) { bus_teardown_intr(sc->dev, sc->irq_res[i], sc->ih_cookie[i]); } } } static int cpsw_get_fdt_data(struct cpsw_softc *sc, int port) { char *name; int len, phy, vlan; pcell_t phy_id[3], vlan_id; phandle_t child; unsigned long mdio_child_addr; /* Find any slave with phy-handle/phy_id */ phy = -1; vlan = -1; for (child = OF_child(sc->node); child != 0; child = OF_peer(child)) { if (OF_getprop_alloc(child, "name", (void **)&name) < 0) continue; if (sscanf(name, "slave@%lx", &mdio_child_addr) != 1) { OF_prop_free(name); continue; } OF_prop_free(name); if (mdio_child_addr != slave_mdio_addr[port] && mdio_child_addr != (slave_mdio_addr[port] & 0xFFF)) continue; if (fdt_get_phyaddr(child, NULL, &phy, NULL) != 0){ /* Users with old DTB will have phy_id instead */ phy = -1; len = OF_getproplen(child, "phy_id"); if (len / sizeof(pcell_t) == 2) { /* Get phy address from fdt */ if (OF_getencprop(child, "phy_id", phy_id, len) > 0) phy = phy_id[1]; } } len = OF_getproplen(child, "dual_emac_res_vlan"); if (len / sizeof(pcell_t) == 1) { /* Get phy address from fdt */ if (OF_getencprop(child, "dual_emac_res_vlan", &vlan_id, len) > 0) { vlan = vlan_id; } } break; } if (phy == -1) return (ENXIO); sc->port[port].phy = phy; sc->port[port].vlan = vlan; return (0); } static int cpsw_attach(device_t dev) { int error, i; struct cpsw_softc *sc; uint32_t reg; sc = device_get_softc(dev); sc->dev = dev; sc->node = ofw_bus_get_node(dev); getbinuptime(&sc->attach_uptime); if (OF_getencprop(sc->node, "active_slave", &sc->active_slave, sizeof(sc->active_slave)) <= 0) { sc->active_slave = 0; } if (sc->active_slave > 1) sc->active_slave = 1; if (OF_hasprop(sc->node, "dual_emac")) sc->dualemac = 1; for (i = 0; i < CPSW_PORTS; i++) { if (!sc->dualemac && i != sc->active_slave) continue; if (cpsw_get_fdt_data(sc, i) != 0) { device_printf(dev, "failed to get PHY address from FDT\n"); return (ENXIO); } } /* Initialize mutexes */ mtx_init(&sc->tx.lock, device_get_nameunit(dev), "cpsw TX lock", MTX_DEF); mtx_init(&sc->rx.lock, device_get_nameunit(dev), "cpsw RX lock", MTX_DEF); /* Allocate IRQ resources */ error = bus_alloc_resources(dev, irq_res_spec, sc->irq_res); if (error) { device_printf(dev, "could not allocate IRQ resources\n"); cpsw_detach(dev); return (ENXIO); } sc->mem_rid = 0; sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid, RF_ACTIVE); if (sc->mem_res == NULL) { device_printf(sc->dev, "failed to allocate memory resource\n"); cpsw_detach(dev); return (ENXIO); } reg = cpsw_read_4(sc, CPSW_SS_IDVER); device_printf(dev, "CPSW SS Version %d.%d (%d)\n", (reg >> 8 & 0x7), reg & 0xFF, (reg >> 11) & 0x1F); cpsw_add_sysctls(sc); /* Allocate a busdma tag and DMA safe memory for mbufs. */ error = bus_dma_tag_create( bus_get_dma_tag(sc->dev), /* parent */ 1, 0, /* alignment, boundary */ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filtfunc, filtfuncarg */ MCLBYTES, CPSW_TXFRAGS, /* maxsize, nsegments */ MCLBYTES, 0, /* maxsegsz, flags */ NULL, NULL, /* lockfunc, lockfuncarg */ &sc->mbuf_dtag); /* dmatag */ if (error) { device_printf(dev, "bus_dma_tag_create failed\n"); cpsw_detach(dev); return (error); } /* Allocate a NULL buffer for padding. */ sc->nullpad = malloc(ETHER_MIN_LEN, M_DEVBUF, M_WAITOK | M_ZERO); cpsw_init_slots(sc); /* Allocate slots to TX and RX queues. */ STAILQ_INIT(&sc->rx.avail); STAILQ_INIT(&sc->rx.active); STAILQ_INIT(&sc->tx.avail); STAILQ_INIT(&sc->tx.active); // For now: 128 slots to TX, rest to RX. // XXX TODO: start with 32/64 and grow dynamically based on demand. if (cpsw_add_slots(sc, &sc->tx, 128) || cpsw_add_slots(sc, &sc->rx, -1)) { device_printf(dev, "failed to allocate dmamaps\n"); cpsw_detach(dev); return (ENOMEM); } device_printf(dev, "Initial queue size TX=%d RX=%d\n", sc->tx.queue_slots, sc->rx.queue_slots); sc->tx.hdp_offset = CPSW_CPDMA_TX_HDP(0); sc->rx.hdp_offset = CPSW_CPDMA_RX_HDP(0); if (cpsw_intr_attach(sc) == -1) { device_printf(dev, "failed to setup interrupts\n"); cpsw_detach(dev); return (ENXIO); } #ifdef CPSW_ETHERSWITCH for (i = 0; i < CPSW_VLANS; i++) cpsw_vgroups[i].vid = -1; #endif /* Reset the controller. */ cpsw_reset(sc); cpsw_init(sc); for (i = 0; i < CPSW_PORTS; i++) { if (!sc->dualemac && i != sc->active_slave) continue; sc->port[i].dev = device_add_child(dev, "cpsw", i); if (sc->port[i].dev == NULL) { cpsw_detach(dev); return (ENXIO); } } bus_generic_probe(dev); bus_generic_attach(dev); return (0); } static int cpsw_detach(device_t dev) { struct cpsw_softc *sc; int error, i; bus_generic_detach(dev); sc = device_get_softc(dev); for (i = 0; i < CPSW_PORTS; i++) { if (sc->port[i].dev) device_delete_child(dev, sc->port[i].dev); } if (device_is_attached(dev)) { callout_stop(&sc->watchdog.callout); callout_drain(&sc->watchdog.callout); } /* Stop and release all interrupts */ cpsw_intr_detach(sc); /* Free dmamaps and mbufs */ for (i = 0; i < nitems(sc->_slots); ++i) cpsw_free_slot(sc, &sc->_slots[i]); /* Free null padding buffer. */ if (sc->nullpad) free(sc->nullpad, M_DEVBUF); /* Free DMA tag */ if (sc->mbuf_dtag) { error = bus_dma_tag_destroy(sc->mbuf_dtag); KASSERT(error == 0, ("Unable to destroy DMA tag")); } /* Free IO memory handler */ if (sc->mem_res != NULL) bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem_res); bus_release_resources(dev, irq_res_spec, sc->irq_res); /* Destroy mutexes */ mtx_destroy(&sc->rx.lock); mtx_destroy(&sc->tx.lock); /* Detach the switch device, if present. */ error = bus_generic_detach(dev); if (error != 0) return (error); return (device_delete_children(dev)); } static phandle_t cpsw_get_node(device_t bus, device_t dev) { /* Share controller node with port device. */ return (ofw_bus_get_node(bus)); } static int cpswp_probe(device_t dev) { if (device_get_unit(dev) > 1) { device_printf(dev, "Only two ports are supported.\n"); return (ENXIO); } device_set_desc(dev, "Ethernet Switch Port"); return (BUS_PROBE_DEFAULT); } static int cpswp_attach(device_t dev) { int error; if_t ifp; struct cpswp_softc *sc; uint32_t reg; uint8_t mac_addr[ETHER_ADDR_LEN]; phandle_t opp_table; struct syscon *syscon; sc = device_get_softc(dev); sc->dev = dev; sc->pdev = device_get_parent(dev); sc->swsc = device_get_softc(sc->pdev); sc->unit = device_get_unit(dev); sc->phy = sc->swsc->port[sc->unit].phy; sc->vlan = sc->swsc->port[sc->unit].vlan; if (sc->swsc->dualemac && sc->vlan == -1) sc->vlan = sc->unit + 1; if (sc->unit == 0) { sc->physel = MDIOUSERPHYSEL0; sc->phyaccess = MDIOUSERACCESS0; } else { sc->physel = MDIOUSERPHYSEL1; sc->phyaccess = MDIOUSERACCESS1; } mtx_init(&sc->lock, device_get_nameunit(dev), "cpsw port lock", MTX_DEF); /* Allocate network interface */ ifp = sc->ifp = if_alloc(IFT_ETHER); if (ifp == NULL) { cpswp_detach(dev); return (ENXIO); } if_initname(ifp, device_get_name(sc->dev), sc->unit); if_setsoftc(ifp, sc); if_setflags(ifp, IFF_SIMPLEX | IFF_MULTICAST | IFF_BROADCAST); if_setcapenable(ifp, if_getcapabilities(ifp)); if_setinitfn(ifp, cpswp_init); if_setstartfn(ifp, cpswp_start); if_setioctlfn(ifp, cpswp_ioctl); if_setsendqlen(ifp, sc->swsc->tx.queue_slots); if_setsendqready(ifp); /* FIXME: For now; Go and kidnap syscon from opp-table */ /* ti,cpsw actually have an optional syscon reference but only for am33xx?? */ opp_table = OF_finddevice("/opp-table"); if (opp_table == -1) { device_printf(dev, "Cant find /opp-table\n"); cpswp_detach(dev); return (ENXIO); } if (!OF_hasprop(opp_table, "syscon")) { device_printf(dev, "/opp-table doesnt have required syscon property\n"); cpswp_detach(dev); return (ENXIO); } if (syscon_get_by_ofw_property(dev, opp_table, "syscon", &syscon) != 0) { device_printf(dev, "Failed to get syscon\n"); cpswp_detach(dev); return (ENXIO); } /* Get high part of MAC address from control module (mac_id[0|1]_hi) */ reg = SYSCON_READ_4(syscon, SCM_MAC_ID0_HI + sc->unit * 8); mac_addr[0] = reg & 0xFF; mac_addr[1] = (reg >> 8) & 0xFF; mac_addr[2] = (reg >> 16) & 0xFF; mac_addr[3] = (reg >> 24) & 0xFF; /* Get low part of MAC address from control module (mac_id[0|1]_lo) */ reg = SYSCON_READ_4(syscon, SCM_MAC_ID0_LO + sc->unit * 8); mac_addr[4] = reg & 0xFF; mac_addr[5] = (reg >> 8) & 0xFF; error = mii_attach(dev, &sc->miibus, ifp, cpswp_ifmedia_upd, cpswp_ifmedia_sts, BMSR_DEFCAPMASK, sc->phy, MII_OFFSET_ANY, 0); if (error) { device_printf(dev, "attaching PHYs failed\n"); cpswp_detach(dev); return (error); } sc->mii = device_get_softc(sc->miibus); /* Select PHY and enable interrupts */ cpsw_write_4(sc->swsc, sc->physel, MDIO_PHYSEL_LINKINTENB | (sc->phy & 0x1F)); ether_ifattach(sc->ifp, mac_addr); callout_init(&sc->mii_callout, 0); return (0); } static int cpswp_detach(device_t dev) { struct cpswp_softc *sc; sc = device_get_softc(dev); CPSW_DEBUGF(sc->swsc, ("")); if (device_is_attached(dev)) { ether_ifdetach(sc->ifp); CPSW_PORT_LOCK(sc); cpswp_stop_locked(sc); CPSW_PORT_UNLOCK(sc); callout_drain(&sc->mii_callout); } bus_generic_detach(dev); if_free(sc->ifp); mtx_destroy(&sc->lock); return (0); } /* * * Init/Shutdown. * */ static int cpsw_ports_down(struct cpsw_softc *sc) { struct cpswp_softc *psc; if_t ifp1, ifp2; if (!sc->dualemac) return (1); psc = device_get_softc(sc->port[0].dev); ifp1 = psc->ifp; psc = device_get_softc(sc->port[1].dev); ifp2 = psc->ifp; if ((if_getflags(ifp1) & IFF_UP) == 0 && (if_getflags(ifp2) & IFF_UP) == 0) return (1); return (0); } static void cpswp_init(void *arg) { struct cpswp_softc *sc = arg; CPSW_DEBUGF(sc->swsc, ("")); CPSW_PORT_LOCK(sc); cpswp_init_locked(arg); CPSW_PORT_UNLOCK(sc); } static void cpswp_init_locked(void *arg) { #ifdef CPSW_ETHERSWITCH int i; #endif struct cpswp_softc *sc = arg; if_t ifp; uint32_t reg; CPSW_DEBUGF(sc->swsc, ("")); CPSW_PORT_LOCK_ASSERT(sc); ifp = sc->ifp; if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) != 0) return; getbinuptime(&sc->init_uptime); if (!sc->swsc->rx.running && !sc->swsc->tx.running) { /* Reset the controller. */ cpsw_reset(sc->swsc); cpsw_init(sc->swsc); } /* Set Slave Mapping. */ cpsw_write_4(sc->swsc, CPSW_SL_RX_PRI_MAP(sc->unit), 0x76543210); cpsw_write_4(sc->swsc, CPSW_PORT_P_TX_PRI_MAP(sc->unit + 1), 0x33221100); cpsw_write_4(sc->swsc, CPSW_SL_RX_MAXLEN(sc->unit), 0x5f2); /* Enable MAC RX/TX modules. */ /* TODO: Docs claim that IFCTL_B and IFCTL_A do the same thing? */ /* Huh? Docs call bit 0 "Loopback" some places, "FullDuplex" others. */ reg = cpsw_read_4(sc->swsc, CPSW_SL_MACCONTROL(sc->unit)); reg |= CPSW_SL_MACTL_GMII_ENABLE; cpsw_write_4(sc->swsc, CPSW_SL_MACCONTROL(sc->unit), reg); /* Initialize ALE: set port to forwarding, initialize addrs */ cpsw_write_4(sc->swsc, CPSW_ALE_PORTCTL(sc->unit + 1), ALE_PORTCTL_INGRESS | ALE_PORTCTL_FORWARD); cpswp_ale_update_addresses(sc, 1); if (sc->swsc->dualemac) { /* Set Port VID. */ cpsw_write_4(sc->swsc, CPSW_PORT_P_VLAN(sc->unit + 1), sc->vlan & 0xfff); cpsw_ale_update_vlan_table(sc->swsc, sc->vlan, (1 << (sc->unit + 1)) | (1 << 0), /* Member list */ (1 << (sc->unit + 1)) | (1 << 0), /* Untagged egress */ (1 << (sc->unit + 1)) | (1 << 0), 0); /* mcast reg flood */ #ifdef CPSW_ETHERSWITCH for (i = 0; i < CPSW_VLANS; i++) { if (cpsw_vgroups[i].vid != -1) continue; cpsw_vgroups[i].vid = sc->vlan; break; } #endif } mii_mediachg(sc->mii); callout_reset(&sc->mii_callout, hz, cpswp_tick, sc); if_setdrvflagbits(ifp, IFF_DRV_RUNNING, 0); if_setdrvflagbits(ifp, 0, IFF_DRV_OACTIVE); } static int cpsw_shutdown(device_t dev) { struct cpsw_softc *sc; struct cpswp_softc *psc; int i; sc = device_get_softc(dev); CPSW_DEBUGF(sc, ("")); for (i = 0; i < CPSW_PORTS; i++) { if (!sc->dualemac && i != sc->active_slave) continue; psc = device_get_softc(sc->port[i].dev); CPSW_PORT_LOCK(psc); cpswp_stop_locked(psc); CPSW_PORT_UNLOCK(psc); } return (0); } static void cpsw_rx_teardown(struct cpsw_softc *sc) { int i = 0; CPSW_RX_LOCK(sc); CPSW_DEBUGF(sc, ("starting RX teardown")); sc->rx.teardown = 1; cpsw_write_4(sc, CPSW_CPDMA_RX_TEARDOWN, 0); CPSW_RX_UNLOCK(sc); while (sc->rx.running) { if (++i > 10) { device_printf(sc->dev, "Unable to cleanly shutdown receiver\n"); return; } DELAY(200); } if (!sc->rx.running) CPSW_DEBUGF(sc, ("finished RX teardown (%d retries)", i)); } static void cpsw_tx_teardown(struct cpsw_softc *sc) { int i = 0; CPSW_TX_LOCK(sc); CPSW_DEBUGF(sc, ("starting TX teardown")); /* Start the TX queue teardown if queue is not empty. */ if (STAILQ_FIRST(&sc->tx.active) != NULL) cpsw_write_4(sc, CPSW_CPDMA_TX_TEARDOWN, 0); else sc->tx.teardown = 1; cpsw_tx_dequeue(sc); while (sc->tx.running && ++i < 10) { DELAY(200); cpsw_tx_dequeue(sc); } if (sc->tx.running) { device_printf(sc->dev, "Unable to cleanly shutdown transmitter\n"); } CPSW_DEBUGF(sc, ("finished TX teardown (%d retries, %d idle buffers)", i, sc->tx.active_queue_len)); CPSW_TX_UNLOCK(sc); } static void cpswp_stop_locked(struct cpswp_softc *sc) { if_t ifp; uint32_t reg; ifp = sc->ifp; CPSW_DEBUGF(sc->swsc, ("")); CPSW_PORT_LOCK_ASSERT(sc); if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0) return; /* Disable interface */ if_setdrvflagbits(ifp, 0, IFF_DRV_RUNNING); if_setdrvflagbits(ifp, IFF_DRV_OACTIVE, 0); /* Stop ticker */ callout_stop(&sc->mii_callout); /* Tear down the RX/TX queues. */ if (cpsw_ports_down(sc->swsc)) { cpsw_rx_teardown(sc->swsc); cpsw_tx_teardown(sc->swsc); } /* Stop MAC RX/TX modules. */ reg = cpsw_read_4(sc->swsc, CPSW_SL_MACCONTROL(sc->unit)); reg &= ~CPSW_SL_MACTL_GMII_ENABLE; cpsw_write_4(sc->swsc, CPSW_SL_MACCONTROL(sc->unit), reg); if (cpsw_ports_down(sc->swsc)) { /* Capture stats before we reset controller. */ cpsw_stats_collect(sc->swsc); cpsw_reset(sc->swsc); cpsw_init(sc->swsc); } } /* * Suspend/Resume. */ static int cpsw_suspend(device_t dev) { struct cpsw_softc *sc; struct cpswp_softc *psc; int i; sc = device_get_softc(dev); CPSW_DEBUGF(sc, ("")); for (i = 0; i < CPSW_PORTS; i++) { if (!sc->dualemac && i != sc->active_slave) continue; psc = device_get_softc(sc->port[i].dev); CPSW_PORT_LOCK(psc); cpswp_stop_locked(psc); CPSW_PORT_UNLOCK(psc); } return (0); } static int cpsw_resume(device_t dev) { struct cpsw_softc *sc; sc = device_get_softc(dev); CPSW_DEBUGF(sc, ("UNIMPLEMENTED")); return (0); } /* * * IOCTL * */ static void cpsw_set_promisc(struct cpswp_softc *sc, int set) { uint32_t reg; /* * Enabling promiscuous mode requires ALE_BYPASS to be enabled. * That disables the ALE forwarding logic and causes every * packet to be sent only to the host port. In bypass mode, * the ALE processes host port transmit packets the same as in * normal mode. */ reg = cpsw_read_4(sc->swsc, CPSW_ALE_CONTROL); reg &= ~CPSW_ALE_CTL_BYPASS; if (set) reg |= CPSW_ALE_CTL_BYPASS; cpsw_write_4(sc->swsc, CPSW_ALE_CONTROL, reg); } static void cpsw_set_allmulti(struct cpswp_softc *sc, int set) { if (set) { printf("All-multicast mode unimplemented\n"); } } static int cpswp_ioctl(if_t ifp, u_long command, caddr_t data) { struct cpswp_softc *sc; struct ifreq *ifr; int error; uint32_t changed; error = 0; sc = if_getsoftc(ifp); ifr = (struct ifreq *)data; switch (command) { case SIOCSIFCAP: changed = if_getcapenable(ifp) ^ ifr->ifr_reqcap; if (changed & IFCAP_HWCSUM) { if ((ifr->ifr_reqcap & changed) & IFCAP_HWCSUM) if_setcapenablebit(ifp, IFCAP_HWCSUM, 0); else if_setcapenablebit(ifp, 0, IFCAP_HWCSUM); } error = 0; break; case SIOCSIFFLAGS: CPSW_PORT_LOCK(sc); if (if_getflags(ifp) & IFF_UP) { if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) { changed = if_getflags(ifp) ^ sc->if_flags; CPSW_DEBUGF(sc->swsc, ("SIOCSIFFLAGS: UP & RUNNING (changed=0x%x)", changed)); if (changed & IFF_PROMISC) cpsw_set_promisc(sc, if_getflags(ifp) & IFF_PROMISC); if (changed & IFF_ALLMULTI) cpsw_set_allmulti(sc, if_getflags(ifp) & IFF_ALLMULTI); } else { CPSW_DEBUGF(sc->swsc, ("SIOCSIFFLAGS: starting up")); cpswp_init_locked(sc); } } else if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) { CPSW_DEBUGF(sc->swsc, ("SIOCSIFFLAGS: shutting down")); cpswp_stop_locked(sc); } sc->if_flags = if_getflags(ifp); CPSW_PORT_UNLOCK(sc); break; case SIOCADDMULTI: cpswp_ale_update_addresses(sc, 0); break; case SIOCDELMULTI: /* Ugh. DELMULTI doesn't provide the specific address being removed, so the best we can do is remove everything and rebuild it all. */ cpswp_ale_update_addresses(sc, 1); break; case SIOCGIFMEDIA: case SIOCSIFMEDIA: error = ifmedia_ioctl(ifp, ifr, &sc->mii->mii_media, command); break; default: error = ether_ioctl(ifp, command, data); } return (error); } /* * * MIIBUS * */ static int cpswp_miibus_ready(struct cpsw_softc *sc, uint32_t reg) { uint32_t r, retries = CPSW_MIIBUS_RETRIES; while (--retries) { r = cpsw_read_4(sc, reg); if ((r & MDIO_PHYACCESS_GO) == 0) return (1); DELAY(CPSW_MIIBUS_DELAY); } return (0); } static int cpswp_miibus_readreg(device_t dev, int phy, int reg) { struct cpswp_softc *sc; uint32_t cmd, r; sc = device_get_softc(dev); if (!cpswp_miibus_ready(sc->swsc, sc->phyaccess)) { device_printf(dev, "MDIO not ready to read\n"); return (0); } /* Set GO, reg, phy */ cmd = MDIO_PHYACCESS_GO | (reg & 0x1F) << 21 | (phy & 0x1F) << 16; cpsw_write_4(sc->swsc, sc->phyaccess, cmd); if (!cpswp_miibus_ready(sc->swsc, sc->phyaccess)) { device_printf(dev, "MDIO timed out during read\n"); return (0); } r = cpsw_read_4(sc->swsc, sc->phyaccess); if ((r & MDIO_PHYACCESS_ACK) == 0) { device_printf(dev, "Failed to read from PHY.\n"); r = 0; } return (r & 0xFFFF); } static int cpswp_miibus_writereg(device_t dev, int phy, int reg, int value) { struct cpswp_softc *sc; uint32_t cmd; sc = device_get_softc(dev); if (!cpswp_miibus_ready(sc->swsc, sc->phyaccess)) { device_printf(dev, "MDIO not ready to write\n"); return (0); } /* Set GO, WRITE, reg, phy, and value */ cmd = MDIO_PHYACCESS_GO | MDIO_PHYACCESS_WRITE | (reg & 0x1F) << 21 | (phy & 0x1F) << 16 | (value & 0xFFFF); cpsw_write_4(sc->swsc, sc->phyaccess, cmd); if (!cpswp_miibus_ready(sc->swsc, sc->phyaccess)) { device_printf(dev, "MDIO timed out during write\n"); return (0); } return (0); } static void cpswp_miibus_statchg(device_t dev) { struct cpswp_softc *sc; uint32_t mac_control, reg; sc = device_get_softc(dev); CPSW_DEBUGF(sc->swsc, ("")); reg = CPSW_SL_MACCONTROL(sc->unit); mac_control = cpsw_read_4(sc->swsc, reg); mac_control &= ~(CPSW_SL_MACTL_GIG | CPSW_SL_MACTL_IFCTL_A | CPSW_SL_MACTL_IFCTL_B | CPSW_SL_MACTL_FULLDUPLEX); switch(IFM_SUBTYPE(sc->mii->mii_media_active)) { case IFM_1000_SX: case IFM_1000_LX: case IFM_1000_CX: case IFM_1000_T: mac_control |= CPSW_SL_MACTL_GIG; break; case IFM_100_TX: mac_control |= CPSW_SL_MACTL_IFCTL_A; break; } if (sc->mii->mii_media_active & IFM_FDX) mac_control |= CPSW_SL_MACTL_FULLDUPLEX; cpsw_write_4(sc->swsc, reg, mac_control); } /* * * Transmit/Receive Packets. * */ static void cpsw_intr_rx(void *arg) { struct cpsw_softc *sc; if_t ifp; struct mbuf *received, *next; sc = (struct cpsw_softc *)arg; CPSW_RX_LOCK(sc); if (sc->rx.teardown) { sc->rx.running = 0; sc->rx.teardown = 0; cpsw_write_cp(sc, &sc->rx, 0xfffffffc); } received = cpsw_rx_dequeue(sc); cpsw_rx_enqueue(sc); cpsw_write_4(sc, CPSW_CPDMA_CPDMA_EOI_VECTOR, 1); CPSW_RX_UNLOCK(sc); while (received != NULL) { next = received->m_nextpkt; received->m_nextpkt = NULL; ifp = received->m_pkthdr.rcvif; if_input(ifp, received); if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); received = next; } } static struct mbuf * cpsw_rx_dequeue(struct cpsw_softc *sc) { int nsegs, port, removed; struct cpsw_cpdma_bd bd; struct cpsw_slot *last, *slot; struct cpswp_softc *psc; struct mbuf *m, *m0, *mb_head, *mb_tail; uint16_t m0_flags; nsegs = 0; m0 = NULL; last = NULL; mb_head = NULL; mb_tail = NULL; removed = 0; /* Pull completed packets off hardware RX queue. */ while ((slot = STAILQ_FIRST(&sc->rx.active)) != NULL) { cpsw_cpdma_read_bd(sc, slot, &bd); /* * Stop on packets still in use by hardware, but do not stop * on packets with the teardown complete flag, they will be * discarded later. */ if ((bd.flags & (CPDMA_BD_OWNER | CPDMA_BD_TDOWNCMPLT)) == CPDMA_BD_OWNER) break; last = slot; ++removed; STAILQ_REMOVE_HEAD(&sc->rx.active, next); STAILQ_INSERT_TAIL(&sc->rx.avail, slot, next); bus_dmamap_sync(sc->mbuf_dtag, slot->dmamap, BUS_DMASYNC_POSTREAD); bus_dmamap_unload(sc->mbuf_dtag, slot->dmamap); m = slot->mbuf; slot->mbuf = NULL; if (bd.flags & CPDMA_BD_TDOWNCMPLT) { CPSW_DEBUGF(sc, ("RX teardown is complete")); m_freem(m); sc->rx.running = 0; sc->rx.teardown = 0; break; } port = (bd.flags & CPDMA_BD_PORT_MASK) - 1; KASSERT(port >= 0 && port <= 1, ("patcket received with invalid port: %d", port)); psc = device_get_softc(sc->port[port].dev); /* Set up mbuf */ m->m_data += bd.bufoff; m->m_len = bd.buflen; if (bd.flags & CPDMA_BD_SOP) { m->m_pkthdr.len = bd.pktlen; m->m_pkthdr.rcvif = psc->ifp; m->m_flags |= M_PKTHDR; m0_flags = bd.flags; m0 = m; } nsegs++; m->m_next = NULL; m->m_nextpkt = NULL; if (bd.flags & CPDMA_BD_EOP && m0 != NULL) { if (m0_flags & CPDMA_BD_PASS_CRC) m_adj(m0, -ETHER_CRC_LEN); m0_flags = 0; m0 = NULL; if (nsegs > sc->rx.longest_chain) sc->rx.longest_chain = nsegs; nsegs = 0; } if ((if_getcapenable(psc->ifp) & IFCAP_RXCSUM) != 0) { /* check for valid CRC by looking into pkt_err[5:4] */ if ((bd.flags & (CPDMA_BD_SOP | CPDMA_BD_PKT_ERR_MASK)) == CPDMA_BD_SOP) { m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED; m->m_pkthdr.csum_flags |= CSUM_IP_VALID; m->m_pkthdr.csum_data = 0xffff; } } if (STAILQ_FIRST(&sc->rx.active) != NULL && (bd.flags & (CPDMA_BD_EOP | CPDMA_BD_EOQ)) == (CPDMA_BD_EOP | CPDMA_BD_EOQ)) { cpsw_write_hdp_slot(sc, &sc->rx, STAILQ_FIRST(&sc->rx.active)); sc->rx.queue_restart++; } /* Add mbuf to packet list to be returned. */ if (mb_tail != NULL && (bd.flags & CPDMA_BD_SOP)) { mb_tail->m_nextpkt = m; } else if (mb_tail != NULL) { mb_tail->m_next = m; } else if (mb_tail == NULL && (bd.flags & CPDMA_BD_SOP) == 0) { if (bootverbose) printf( "%s: %s: discanding fragment packet w/o header\n", __func__, if_name(psc->ifp)); m_freem(m); continue; } else { mb_head = m; } mb_tail = m; } if (removed != 0) { cpsw_write_cp_slot(sc, &sc->rx, last); sc->rx.queue_removes += removed; sc->rx.avail_queue_len += removed; sc->rx.active_queue_len -= removed; if (sc->rx.avail_queue_len > sc->rx.max_avail_queue_len) sc->rx.max_avail_queue_len = sc->rx.avail_queue_len; CPSW_DEBUGF(sc, ("Removed %d received packet(s) from RX queue", removed)); } return (mb_head); } static void cpsw_rx_enqueue(struct cpsw_softc *sc) { bus_dma_segment_t seg[1]; struct cpsw_cpdma_bd bd; struct cpsw_slot *first_new_slot, *last_old_slot, *next, *slot; int error, nsegs, added = 0; /* Register new mbufs with hardware. */ first_new_slot = NULL; last_old_slot = STAILQ_LAST(&sc->rx.active, cpsw_slot, next); while ((slot = STAILQ_FIRST(&sc->rx.avail)) != NULL) { if (first_new_slot == NULL) first_new_slot = slot; if (slot->mbuf == NULL) { slot->mbuf = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (slot->mbuf == NULL) { device_printf(sc->dev, "Unable to fill RX queue\n"); break; } slot->mbuf->m_len = slot->mbuf->m_pkthdr.len = slot->mbuf->m_ext.ext_size; } error = bus_dmamap_load_mbuf_sg(sc->mbuf_dtag, slot->dmamap, slot->mbuf, seg, &nsegs, BUS_DMA_NOWAIT); KASSERT(nsegs == 1, ("More than one segment (nsegs=%d)", nsegs)); KASSERT(error == 0, ("DMA error (error=%d)", error)); if (error != 0 || nsegs != 1) { device_printf(sc->dev, "%s: Can't prep RX buf for DMA (nsegs=%d, error=%d)\n", __func__, nsegs, error); bus_dmamap_unload(sc->mbuf_dtag, slot->dmamap); m_freem(slot->mbuf); slot->mbuf = NULL; break; } bus_dmamap_sync(sc->mbuf_dtag, slot->dmamap, BUS_DMASYNC_PREREAD); /* Create and submit new rx descriptor. */ if ((next = STAILQ_NEXT(slot, next)) != NULL) bd.next = cpsw_cpdma_bd_paddr(sc, next); else bd.next = 0; bd.bufptr = seg->ds_addr; bd.bufoff = 0; bd.buflen = MCLBYTES - 1; bd.pktlen = bd.buflen; bd.flags = CPDMA_BD_OWNER; cpsw_cpdma_write_bd(sc, slot, &bd); ++added; STAILQ_REMOVE_HEAD(&sc->rx.avail, next); STAILQ_INSERT_TAIL(&sc->rx.active, slot, next); } if (added == 0 || first_new_slot == NULL) return; CPSW_DEBUGF(sc, ("Adding %d buffers to RX queue", added)); /* Link new entries to hardware RX queue. */ if (last_old_slot == NULL) { /* Start a fresh queue. */ cpsw_write_hdp_slot(sc, &sc->rx, first_new_slot); } else { /* Add buffers to end of current queue. */ cpsw_cpdma_write_bd_next(sc, last_old_slot, first_new_slot); } sc->rx.queue_adds += added; sc->rx.avail_queue_len -= added; sc->rx.active_queue_len += added; cpsw_write_4(sc, CPSW_CPDMA_RX_FREEBUFFER(0), added); if (sc->rx.active_queue_len > sc->rx.max_active_queue_len) sc->rx.max_active_queue_len = sc->rx.active_queue_len; } static void cpswp_start(if_t ifp) { struct cpswp_softc *sc; sc = if_getsoftc(ifp); if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0 || sc->swsc->tx.running == 0) { return; } CPSW_TX_LOCK(sc->swsc); cpswp_tx_enqueue(sc); cpsw_tx_dequeue(sc->swsc); CPSW_TX_UNLOCK(sc->swsc); } static void cpsw_intr_tx(void *arg) { struct cpsw_softc *sc; sc = (struct cpsw_softc *)arg; CPSW_TX_LOCK(sc); if (cpsw_read_4(sc, CPSW_CPDMA_TX_CP(0)) == 0xfffffffc) cpsw_write_cp(sc, &sc->tx, 0xfffffffc); cpsw_tx_dequeue(sc); cpsw_write_4(sc, CPSW_CPDMA_CPDMA_EOI_VECTOR, 2); CPSW_TX_UNLOCK(sc); } static void cpswp_tx_enqueue(struct cpswp_softc *sc) { bus_dma_segment_t segs[CPSW_TXFRAGS]; struct cpsw_cpdma_bd bd; struct cpsw_slot *first_new_slot, *last, *last_old_slot, *next, *slot; struct mbuf *m0; int error, nsegs, seg, added = 0, padlen; /* Pull pending packets from IF queue and prep them for DMA. */ last = NULL; first_new_slot = NULL; last_old_slot = STAILQ_LAST(&sc->swsc->tx.active, cpsw_slot, next); while ((slot = STAILQ_FIRST(&sc->swsc->tx.avail)) != NULL) { m0 = if_dequeue(sc->ifp); if (m0 == NULL) break; slot->mbuf = m0; padlen = ETHER_MIN_LEN - ETHER_CRC_LEN - m0->m_pkthdr.len; if (padlen < 0) padlen = 0; else if (padlen > 0) m_append(slot->mbuf, padlen, sc->swsc->nullpad); /* Create mapping in DMA memory */ error = bus_dmamap_load_mbuf_sg(sc->swsc->mbuf_dtag, slot->dmamap, slot->mbuf, segs, &nsegs, BUS_DMA_NOWAIT); /* If the packet is too fragmented, try to simplify. */ if (error == EFBIG || (error == 0 && nsegs > sc->swsc->tx.avail_queue_len)) { bus_dmamap_unload(sc->swsc->mbuf_dtag, slot->dmamap); m0 = m_defrag(slot->mbuf, M_NOWAIT); if (m0 == NULL) { device_printf(sc->dev, "Can't defragment packet; dropping\n"); m_freem(slot->mbuf); } else { CPSW_DEBUGF(sc->swsc, ("Requeueing defragmented packet")); if_sendq_prepend(sc->ifp, m0); } slot->mbuf = NULL; continue; } if (error != 0) { device_printf(sc->dev, "%s: Can't setup DMA (error=%d), dropping packet\n", __func__, error); bus_dmamap_unload(sc->swsc->mbuf_dtag, slot->dmamap); m_freem(slot->mbuf); slot->mbuf = NULL; break; } bus_dmamap_sync(sc->swsc->mbuf_dtag, slot->dmamap, BUS_DMASYNC_PREWRITE); CPSW_DEBUGF(sc->swsc, ("Queueing TX packet: %d segments + %d pad bytes", nsegs, padlen)); if (first_new_slot == NULL) first_new_slot = slot; /* Link from the previous descriptor. */ if (last != NULL) cpsw_cpdma_write_bd_next(sc->swsc, last, slot); slot->ifp = sc->ifp; /* If there is only one segment, the for() loop * gets skipped and the single buffer gets set up * as both SOP and EOP. */ if (nsegs > 1) { next = STAILQ_NEXT(slot, next); bd.next = cpsw_cpdma_bd_paddr(sc->swsc, next); } else bd.next = 0; /* Start by setting up the first buffer. */ bd.bufptr = segs[0].ds_addr; bd.bufoff = 0; bd.buflen = segs[0].ds_len; bd.pktlen = m_length(slot->mbuf, NULL); bd.flags = CPDMA_BD_SOP | CPDMA_BD_OWNER; if (sc->swsc->dualemac) { bd.flags |= CPDMA_BD_TO_PORT; bd.flags |= ((sc->unit + 1) & CPDMA_BD_PORT_MASK); } for (seg = 1; seg < nsegs; ++seg) { /* Save the previous buffer (which isn't EOP) */ cpsw_cpdma_write_bd(sc->swsc, slot, &bd); STAILQ_REMOVE_HEAD(&sc->swsc->tx.avail, next); STAILQ_INSERT_TAIL(&sc->swsc->tx.active, slot, next); slot = STAILQ_FIRST(&sc->swsc->tx.avail); /* Setup next buffer (which isn't SOP) */ if (nsegs > seg + 1) { next = STAILQ_NEXT(slot, next); bd.next = cpsw_cpdma_bd_paddr(sc->swsc, next); } else bd.next = 0; bd.bufptr = segs[seg].ds_addr; bd.bufoff = 0; bd.buflen = segs[seg].ds_len; bd.pktlen = 0; bd.flags = CPDMA_BD_OWNER; } /* Save the final buffer. */ bd.flags |= CPDMA_BD_EOP; cpsw_cpdma_write_bd(sc->swsc, slot, &bd); STAILQ_REMOVE_HEAD(&sc->swsc->tx.avail, next); STAILQ_INSERT_TAIL(&sc->swsc->tx.active, slot, next); last = slot; added += nsegs; if (nsegs > sc->swsc->tx.longest_chain) sc->swsc->tx.longest_chain = nsegs; BPF_MTAP(sc->ifp, m0); } if (first_new_slot == NULL) return; /* Attach the list of new buffers to the hardware TX queue. */ if (last_old_slot != NULL && (cpsw_cpdma_read_bd_flags(sc->swsc, last_old_slot) & CPDMA_BD_EOQ) == 0) { /* Add buffers to end of current queue. */ cpsw_cpdma_write_bd_next(sc->swsc, last_old_slot, first_new_slot); } else { /* Start a fresh queue. */ cpsw_write_hdp_slot(sc->swsc, &sc->swsc->tx, first_new_slot); } sc->swsc->tx.queue_adds += added; sc->swsc->tx.avail_queue_len -= added; sc->swsc->tx.active_queue_len += added; if (sc->swsc->tx.active_queue_len > sc->swsc->tx.max_active_queue_len) { sc->swsc->tx.max_active_queue_len = sc->swsc->tx.active_queue_len; } CPSW_DEBUGF(sc->swsc, ("Queued %d TX packet(s)", added)); } static int cpsw_tx_dequeue(struct cpsw_softc *sc) { struct cpsw_slot *slot, *last_removed_slot = NULL; struct cpsw_cpdma_bd bd; uint32_t flags, removed = 0; /* Pull completed buffers off the hardware TX queue. */ slot = STAILQ_FIRST(&sc->tx.active); while (slot != NULL) { flags = cpsw_cpdma_read_bd_flags(sc, slot); /* TearDown complete is only marked on the SOP for the packet. */ if ((flags & (CPDMA_BD_SOP | CPDMA_BD_TDOWNCMPLT)) == (CPDMA_BD_SOP | CPDMA_BD_TDOWNCMPLT)) { sc->tx.teardown = 1; } if ((flags & (CPDMA_BD_SOP | CPDMA_BD_OWNER)) == (CPDMA_BD_SOP | CPDMA_BD_OWNER) && sc->tx.teardown == 0) break; /* Hardware is still using this packet. */ bus_dmamap_sync(sc->mbuf_dtag, slot->dmamap, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->mbuf_dtag, slot->dmamap); m_freem(slot->mbuf); slot->mbuf = NULL; if (slot->ifp) { if (sc->tx.teardown == 0) if_inc_counter(slot->ifp, IFCOUNTER_OPACKETS, 1); else if_inc_counter(slot->ifp, IFCOUNTER_OQDROPS, 1); } /* Dequeue any additional buffers used by this packet. */ while (slot != NULL && slot->mbuf == NULL) { STAILQ_REMOVE_HEAD(&sc->tx.active, next); STAILQ_INSERT_TAIL(&sc->tx.avail, slot, next); ++removed; last_removed_slot = slot; slot = STAILQ_FIRST(&sc->tx.active); } cpsw_write_cp_slot(sc, &sc->tx, last_removed_slot); /* Restart the TX queue if necessary. */ cpsw_cpdma_read_bd(sc, last_removed_slot, &bd); if (slot != NULL && bd.next != 0 && (bd.flags & (CPDMA_BD_EOP | CPDMA_BD_OWNER | CPDMA_BD_EOQ)) == (CPDMA_BD_EOP | CPDMA_BD_EOQ)) { cpsw_write_hdp_slot(sc, &sc->tx, slot); sc->tx.queue_restart++; break; } } if (removed != 0) { sc->tx.queue_removes += removed; sc->tx.active_queue_len -= removed; sc->tx.avail_queue_len += removed; if (sc->tx.avail_queue_len > sc->tx.max_avail_queue_len) sc->tx.max_avail_queue_len = sc->tx.avail_queue_len; CPSW_DEBUGF(sc, ("TX removed %d completed packet(s)", removed)); } if (sc->tx.teardown && STAILQ_EMPTY(&sc->tx.active)) { CPSW_DEBUGF(sc, ("TX teardown is complete")); sc->tx.teardown = 0; sc->tx.running = 0; } return (removed); } /* * * Miscellaneous interrupts. * */ static void cpsw_intr_rx_thresh(void *arg) { struct cpsw_softc *sc; if_t ifp; struct mbuf *received, *next; sc = (struct cpsw_softc *)arg; CPSW_RX_LOCK(sc); received = cpsw_rx_dequeue(sc); cpsw_rx_enqueue(sc); cpsw_write_4(sc, CPSW_CPDMA_CPDMA_EOI_VECTOR, 0); CPSW_RX_UNLOCK(sc); while (received != NULL) { next = received->m_nextpkt; received->m_nextpkt = NULL; ifp = received->m_pkthdr.rcvif; if_input(ifp, received); if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); received = next; } } static void cpsw_intr_misc_host_error(struct cpsw_softc *sc) { uint32_t intstat; uint32_t dmastat; int txerr, rxerr, txchan, rxchan; printf("\n\n"); device_printf(sc->dev, "HOST ERROR: PROGRAMMING ERROR DETECTED BY HARDWARE\n"); printf("\n\n"); intstat = cpsw_read_4(sc, CPSW_CPDMA_DMA_INTSTAT_MASKED); device_printf(sc->dev, "CPSW_CPDMA_DMA_INTSTAT_MASKED=0x%x\n", intstat); dmastat = cpsw_read_4(sc, CPSW_CPDMA_DMASTATUS); device_printf(sc->dev, "CPSW_CPDMA_DMASTATUS=0x%x\n", dmastat); txerr = (dmastat >> 20) & 15; txchan = (dmastat >> 16) & 7; rxerr = (dmastat >> 12) & 15; rxchan = (dmastat >> 8) & 7; switch (txerr) { case 0: break; case 1: printf("SOP error on TX channel %d\n", txchan); break; case 2: printf("Ownership bit not set on SOP buffer on TX channel %d\n", txchan); break; case 3: printf("Zero Next Buffer but not EOP on TX channel %d\n", txchan); break; case 4: printf("Zero Buffer Pointer on TX channel %d\n", txchan); break; case 5: printf("Zero Buffer Length on TX channel %d\n", txchan); break; case 6: printf("Packet length error on TX channel %d\n", txchan); break; default: printf("Unknown error on TX channel %d\n", txchan); break; } if (txerr != 0) { printf("CPSW_CPDMA_TX%d_HDP=0x%x\n", txchan, cpsw_read_4(sc, CPSW_CPDMA_TX_HDP(txchan))); printf("CPSW_CPDMA_TX%d_CP=0x%x\n", txchan, cpsw_read_4(sc, CPSW_CPDMA_TX_CP(txchan))); cpsw_dump_queue(sc, &sc->tx.active); } switch (rxerr) { case 0: break; case 2: printf("Ownership bit not set on RX channel %d\n", rxchan); break; case 4: printf("Zero Buffer Pointer on RX channel %d\n", rxchan); break; case 5: printf("Zero Buffer Length on RX channel %d\n", rxchan); break; case 6: printf("Buffer offset too big on RX channel %d\n", rxchan); break; default: printf("Unknown RX error on RX channel %d\n", rxchan); break; } if (rxerr != 0) { printf("CPSW_CPDMA_RX%d_HDP=0x%x\n", rxchan, cpsw_read_4(sc,CPSW_CPDMA_RX_HDP(rxchan))); printf("CPSW_CPDMA_RX%d_CP=0x%x\n", rxchan, cpsw_read_4(sc, CPSW_CPDMA_RX_CP(rxchan))); cpsw_dump_queue(sc, &sc->rx.active); } printf("\nALE Table\n"); cpsw_ale_dump_table(sc); // XXX do something useful here?? panic("CPSW HOST ERROR INTERRUPT"); // Suppress this interrupt in the future. cpsw_write_4(sc, CPSW_CPDMA_DMA_INTMASK_CLEAR, intstat); printf("XXX HOST ERROR INTERRUPT SUPPRESSED\n"); // The watchdog will probably reset the controller // in a little while. It will probably fail again. } static void cpsw_intr_misc(void *arg) { struct cpsw_softc *sc = arg; uint32_t stat = cpsw_read_4(sc, CPSW_WR_C_MISC_STAT(0)); if (stat & CPSW_WR_C_MISC_EVNT_PEND) CPSW_DEBUGF(sc, ("Time sync event interrupt unimplemented")); if (stat & CPSW_WR_C_MISC_STAT_PEND) cpsw_stats_collect(sc); if (stat & CPSW_WR_C_MISC_HOST_PEND) cpsw_intr_misc_host_error(sc); if (stat & CPSW_WR_C_MISC_MDIOLINK) { cpsw_write_4(sc, MDIOLINKINTMASKED, cpsw_read_4(sc, MDIOLINKINTMASKED)); } if (stat & CPSW_WR_C_MISC_MDIOUSER) { CPSW_DEBUGF(sc, ("MDIO operation completed interrupt unimplemented")); } cpsw_write_4(sc, CPSW_CPDMA_CPDMA_EOI_VECTOR, 3); } /* * * Periodic Checks and Watchdog. * */ static void cpswp_tick(void *msc) { struct cpswp_softc *sc = msc; /* Check for media type change */ mii_tick(sc->mii); if (sc->media_status != sc->mii->mii_media.ifm_media) { printf("%s: media type changed (ifm_media=%x)\n", __func__, sc->mii->mii_media.ifm_media); cpswp_ifmedia_upd(sc->ifp); } /* Schedule another timeout one second from now */ callout_reset(&sc->mii_callout, hz, cpswp_tick, sc); } static void cpswp_ifmedia_sts(if_t ifp, struct ifmediareq *ifmr) { struct cpswp_softc *sc; struct mii_data *mii; sc = if_getsoftc(ifp); CPSW_DEBUGF(sc->swsc, ("")); CPSW_PORT_LOCK(sc); mii = sc->mii; mii_pollstat(mii); ifmr->ifm_active = mii->mii_media_active; ifmr->ifm_status = mii->mii_media_status; CPSW_PORT_UNLOCK(sc); } static int cpswp_ifmedia_upd(if_t ifp) { struct cpswp_softc *sc; sc = if_getsoftc(ifp); CPSW_DEBUGF(sc->swsc, ("")); CPSW_PORT_LOCK(sc); mii_mediachg(sc->mii); sc->media_status = sc->mii->mii_media.ifm_media; CPSW_PORT_UNLOCK(sc); return (0); } static void cpsw_tx_watchdog_full_reset(struct cpsw_softc *sc) { struct cpswp_softc *psc; int i; cpsw_debugf_head("CPSW watchdog"); device_printf(sc->dev, "watchdog timeout\n"); printf("CPSW_CPDMA_TX%d_HDP=0x%x\n", 0, cpsw_read_4(sc, CPSW_CPDMA_TX_HDP(0))); printf("CPSW_CPDMA_TX%d_CP=0x%x\n", 0, cpsw_read_4(sc, CPSW_CPDMA_TX_CP(0))); cpsw_dump_queue(sc, &sc->tx.active); for (i = 0; i < CPSW_PORTS; i++) { if (!sc->dualemac && i != sc->active_slave) continue; psc = device_get_softc(sc->port[i].dev); CPSW_PORT_LOCK(psc); cpswp_stop_locked(psc); CPSW_PORT_UNLOCK(psc); } } static void cpsw_tx_watchdog(void *msc) { struct cpsw_softc *sc; sc = msc; CPSW_TX_LOCK(sc); if (sc->tx.active_queue_len == 0 || !sc->tx.running) { sc->watchdog.timer = 0; /* Nothing to do. */ } else if (sc->tx.queue_removes > sc->tx.queue_removes_at_last_tick) { sc->watchdog.timer = 0; /* Stuff done while we weren't looking. */ } else if (cpsw_tx_dequeue(sc) > 0) { sc->watchdog.timer = 0; /* We just did something. */ } else { /* There was something to do but it didn't get done. */ ++sc->watchdog.timer; if (sc->watchdog.timer > 5) { sc->watchdog.timer = 0; ++sc->watchdog.resets; cpsw_tx_watchdog_full_reset(sc); } } sc->tx.queue_removes_at_last_tick = sc->tx.queue_removes; CPSW_TX_UNLOCK(sc); /* Schedule another timeout one second from now */ callout_reset(&sc->watchdog.callout, hz, cpsw_tx_watchdog, sc); } /* * * ALE support routines. * */ static void cpsw_ale_read_entry(struct cpsw_softc *sc, uint16_t idx, uint32_t *ale_entry) { cpsw_write_4(sc, CPSW_ALE_TBLCTL, idx & 1023); ale_entry[0] = cpsw_read_4(sc, CPSW_ALE_TBLW0); ale_entry[1] = cpsw_read_4(sc, CPSW_ALE_TBLW1); ale_entry[2] = cpsw_read_4(sc, CPSW_ALE_TBLW2); } static void cpsw_ale_write_entry(struct cpsw_softc *sc, uint16_t idx, uint32_t *ale_entry) { cpsw_write_4(sc, CPSW_ALE_TBLW0, ale_entry[0]); cpsw_write_4(sc, CPSW_ALE_TBLW1, ale_entry[1]); cpsw_write_4(sc, CPSW_ALE_TBLW2, ale_entry[2]); cpsw_write_4(sc, CPSW_ALE_TBLCTL, 1 << 31 | (idx & 1023)); } static void cpsw_ale_remove_all_mc_entries(struct cpsw_softc *sc) { int i; uint32_t ale_entry[3]; /* First four entries are link address and broadcast. */ for (i = 10; i < CPSW_MAX_ALE_ENTRIES; i++) { cpsw_ale_read_entry(sc, i, ale_entry); if ((ALE_TYPE(ale_entry) == ALE_TYPE_ADDR || ALE_TYPE(ale_entry) == ALE_TYPE_VLAN_ADDR) && ALE_MCAST(ale_entry) == 1) { /* MCast link addr */ ale_entry[0] = ale_entry[1] = ale_entry[2] = 0; cpsw_ale_write_entry(sc, i, ale_entry); } } } static int cpsw_ale_mc_entry_set(struct cpsw_softc *sc, uint8_t portmap, int vlan, uint8_t *mac) { int free_index = -1, matching_index = -1, i; uint32_t ale_entry[3], ale_type; /* Find a matching entry or a free entry. */ for (i = 10; i < CPSW_MAX_ALE_ENTRIES; i++) { cpsw_ale_read_entry(sc, i, ale_entry); /* Entry Type[61:60] is 0 for free entry */ if (free_index < 0 && ALE_TYPE(ale_entry) == 0) free_index = i; if ((((ale_entry[1] >> 8) & 0xFF) == mac[0]) && (((ale_entry[1] >> 0) & 0xFF) == mac[1]) && (((ale_entry[0] >>24) & 0xFF) == mac[2]) && (((ale_entry[0] >>16) & 0xFF) == mac[3]) && (((ale_entry[0] >> 8) & 0xFF) == mac[4]) && (((ale_entry[0] >> 0) & 0xFF) == mac[5])) { matching_index = i; break; } } if (matching_index < 0) { if (free_index < 0) return (ENOMEM); i = free_index; } if (vlan != -1) ale_type = ALE_TYPE_VLAN_ADDR << 28 | vlan << 16; else ale_type = ALE_TYPE_ADDR << 28; /* Set MAC address */ ale_entry[0] = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5]; ale_entry[1] = mac[0] << 8 | mac[1]; /* Entry type[61:60] and Mcast fwd state[63:62] is fw(3). */ ale_entry[1] |= ALE_MCAST_FWD | ale_type; /* Set portmask [68:66] */ ale_entry[2] = (portmap & 7) << 2; cpsw_ale_write_entry(sc, i, ale_entry); return 0; } static void cpsw_ale_dump_table(struct cpsw_softc *sc) { int i; uint32_t ale_entry[3]; for (i = 0; i < CPSW_MAX_ALE_ENTRIES; i++) { cpsw_ale_read_entry(sc, i, ale_entry); switch (ALE_TYPE(ale_entry)) { case ALE_TYPE_VLAN: printf("ALE[%4u] %08x %08x %08x ", i, ale_entry[2], ale_entry[1], ale_entry[0]); printf("type: %u ", ALE_TYPE(ale_entry)); printf("vlan: %u ", ALE_VLAN(ale_entry)); printf("untag: %u ", ALE_VLAN_UNTAG(ale_entry)); printf("reg flood: %u ", ALE_VLAN_REGFLOOD(ale_entry)); printf("unreg flood: %u ", ALE_VLAN_UNREGFLOOD(ale_entry)); printf("members: %u ", ALE_VLAN_MEMBERS(ale_entry)); printf("\n"); break; case ALE_TYPE_ADDR: case ALE_TYPE_VLAN_ADDR: printf("ALE[%4u] %08x %08x %08x ", i, ale_entry[2], ale_entry[1], ale_entry[0]); printf("type: %u ", ALE_TYPE(ale_entry)); printf("mac: %02x:%02x:%02x:%02x:%02x:%02x ", (ale_entry[1] >> 8) & 0xFF, (ale_entry[1] >> 0) & 0xFF, (ale_entry[0] >>24) & 0xFF, (ale_entry[0] >>16) & 0xFF, (ale_entry[0] >> 8) & 0xFF, (ale_entry[0] >> 0) & 0xFF); printf(ALE_MCAST(ale_entry) ? "mcast " : "ucast "); if (ALE_TYPE(ale_entry) == ALE_TYPE_VLAN_ADDR) printf("vlan: %u ", ALE_VLAN(ale_entry)); printf("port: %u ", ALE_PORTS(ale_entry)); printf("\n"); break; } } printf("\n"); } static u_int cpswp_set_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt) { struct cpswp_softc *sc = arg; uint32_t portmask; if (sc->swsc->dualemac) portmask = 1 << (sc->unit + 1) | 1 << 0; else portmask = 7; cpsw_ale_mc_entry_set(sc->swsc, portmask, sc->vlan, LLADDR(sdl)); return (1); } static int cpswp_ale_update_addresses(struct cpswp_softc *sc, int purge) { uint8_t *mac; uint32_t ale_entry[3], ale_type, portmask; if (sc->swsc->dualemac) { ale_type = ALE_TYPE_VLAN_ADDR << 28 | sc->vlan << 16; portmask = 1 << (sc->unit + 1) | 1 << 0; } else { ale_type = ALE_TYPE_ADDR << 28; portmask = 7; } /* * Route incoming packets for our MAC address to Port 0 (host). * For simplicity, keep this entry at table index 0 for port 1 and * at index 2 for port 2 in the ALE. */ mac = LLADDR((struct sockaddr_dl *)if_getifaddr(sc->ifp)->ifa_addr); ale_entry[0] = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5]; ale_entry[1] = ale_type | mac[0] << 8 | mac[1]; /* addr entry + mac */ ale_entry[2] = 0; /* port = 0 */ cpsw_ale_write_entry(sc->swsc, 0 + 2 * sc->unit, ale_entry); /* Set outgoing MAC Address for slave port. */ cpsw_write_4(sc->swsc, CPSW_PORT_P_SA_HI(sc->unit + 1), mac[3] << 24 | mac[2] << 16 | mac[1] << 8 | mac[0]); cpsw_write_4(sc->swsc, CPSW_PORT_P_SA_LO(sc->unit + 1), mac[5] << 8 | mac[4]); /* Keep the broadcast address at table entry 1 (or 3). */ ale_entry[0] = 0xffffffff; /* Lower 32 bits of MAC */ /* ALE_MCAST_FWD, Addr type, upper 16 bits of Mac */ ale_entry[1] = ALE_MCAST_FWD | ale_type | 0xffff; ale_entry[2] = portmask << 2; cpsw_ale_write_entry(sc->swsc, 1 + 2 * sc->unit, ale_entry); /* SIOCDELMULTI doesn't specify the particular address being removed, so we have to remove all and rebuild. */ if (purge) cpsw_ale_remove_all_mc_entries(sc->swsc); /* Set other multicast addrs desired. */ if_foreach_llmaddr(sc->ifp, cpswp_set_maddr, sc); return (0); } static int cpsw_ale_update_vlan_table(struct cpsw_softc *sc, int vlan, int ports, int untag, int mcregflood, int mcunregflood) { int free_index, i, matching_index; uint32_t ale_entry[3]; free_index = matching_index = -1; /* Find a matching entry or a free entry. */ for (i = 5; i < CPSW_MAX_ALE_ENTRIES; i++) { cpsw_ale_read_entry(sc, i, ale_entry); /* Entry Type[61:60] is 0 for free entry */ if (free_index < 0 && ALE_TYPE(ale_entry) == 0) free_index = i; if (ALE_VLAN(ale_entry) == vlan) { matching_index = i; break; } } if (matching_index < 0) { if (free_index < 0) return (-1); i = free_index; } ale_entry[0] = (untag & 7) << 24 | (mcregflood & 7) << 16 | (mcunregflood & 7) << 8 | (ports & 7); ale_entry[1] = ALE_TYPE_VLAN << 28 | vlan << 16; ale_entry[2] = 0; cpsw_ale_write_entry(sc, i, ale_entry); return (0); } /* * * Statistics and Sysctls. * */ #if 0 static void cpsw_stats_dump(struct cpsw_softc *sc) { int i; uint32_t r; for (i = 0; i < CPSW_SYSCTL_COUNT; ++i) { r = cpsw_read_4(sc, CPSW_STATS_OFFSET + cpsw_stat_sysctls[i].reg); CPSW_DEBUGF(sc, ("%s: %ju + %u = %ju", cpsw_stat_sysctls[i].oid, (intmax_t)sc->shadow_stats[i], r, (intmax_t)sc->shadow_stats[i] + r)); } } #endif static void cpsw_stats_collect(struct cpsw_softc *sc) { int i; uint32_t r; CPSW_DEBUGF(sc, ("Controller shadow statistics updated.")); for (i = 0; i < CPSW_SYSCTL_COUNT; ++i) { r = cpsw_read_4(sc, CPSW_STATS_OFFSET + cpsw_stat_sysctls[i].reg); sc->shadow_stats[i] += r; cpsw_write_4(sc, CPSW_STATS_OFFSET + cpsw_stat_sysctls[i].reg, r); } } static int cpsw_stats_sysctl(SYSCTL_HANDLER_ARGS) { struct cpsw_softc *sc; struct cpsw_stat *stat; uint64_t result; sc = (struct cpsw_softc *)arg1; stat = &cpsw_stat_sysctls[oidp->oid_number]; result = sc->shadow_stats[oidp->oid_number]; result += cpsw_read_4(sc, CPSW_STATS_OFFSET + stat->reg); return (sysctl_handle_64(oidp, &result, 0, req)); } static int cpsw_stat_attached(SYSCTL_HANDLER_ARGS) { struct cpsw_softc *sc; struct bintime t; unsigned result; sc = (struct cpsw_softc *)arg1; getbinuptime(&t); bintime_sub(&t, &sc->attach_uptime); result = t.sec; return (sysctl_handle_int(oidp, &result, 0, req)); } static int cpsw_intr_coalesce(SYSCTL_HANDLER_ARGS) { int error; struct cpsw_softc *sc; uint32_t ctrl, intr_per_ms; sc = (struct cpsw_softc *)arg1; error = sysctl_handle_int(oidp, &sc->coal_us, 0, req); if (error != 0 || req->newptr == NULL) return (error); ctrl = cpsw_read_4(sc, CPSW_WR_INT_CONTROL); ctrl &= ~(CPSW_WR_INT_PACE_EN | CPSW_WR_INT_PRESCALE_MASK); if (sc->coal_us == 0) { /* Disable the interrupt pace hardware. */ cpsw_write_4(sc, CPSW_WR_INT_CONTROL, ctrl); cpsw_write_4(sc, CPSW_WR_C_RX_IMAX(0), 0); cpsw_write_4(sc, CPSW_WR_C_TX_IMAX(0), 0); return (0); } if (sc->coal_us > CPSW_WR_C_IMAX_US_MAX) sc->coal_us = CPSW_WR_C_IMAX_US_MAX; if (sc->coal_us < CPSW_WR_C_IMAX_US_MIN) sc->coal_us = CPSW_WR_C_IMAX_US_MIN; intr_per_ms = 1000 / sc->coal_us; /* Just to make sure... */ if (intr_per_ms > CPSW_WR_C_IMAX_MAX) intr_per_ms = CPSW_WR_C_IMAX_MAX; if (intr_per_ms < CPSW_WR_C_IMAX_MIN) intr_per_ms = CPSW_WR_C_IMAX_MIN; /* Set the prescale to produce 4us pulses from the 125 Mhz clock. */ ctrl |= (125 * 4) & CPSW_WR_INT_PRESCALE_MASK; /* Enable the interrupt pace hardware. */ cpsw_write_4(sc, CPSW_WR_C_RX_IMAX(0), intr_per_ms); cpsw_write_4(sc, CPSW_WR_C_TX_IMAX(0), intr_per_ms); ctrl |= CPSW_WR_INT_C0_RX_PULSE | CPSW_WR_INT_C0_TX_PULSE; cpsw_write_4(sc, CPSW_WR_INT_CONTROL, ctrl); return (0); } static int cpsw_stat_uptime(SYSCTL_HANDLER_ARGS) { struct cpsw_softc *swsc; struct cpswp_softc *sc; struct bintime t; unsigned result; swsc = arg1; sc = device_get_softc(swsc->port[arg2].dev); if (if_getdrvflags(sc->ifp) & IFF_DRV_RUNNING) { getbinuptime(&t); bintime_sub(&t, &sc->init_uptime); result = t.sec; } else result = 0; return (sysctl_handle_int(oidp, &result, 0, req)); } static void cpsw_add_queue_sysctls(struct sysctl_ctx_list *ctx, struct sysctl_oid *node, struct cpsw_queue *queue) { struct sysctl_oid_list *parent; parent = SYSCTL_CHILDREN(node); SYSCTL_ADD_INT(ctx, parent, OID_AUTO, "totalBuffers", CTLFLAG_RD, &queue->queue_slots, 0, "Total buffers currently assigned to this queue"); SYSCTL_ADD_INT(ctx, parent, OID_AUTO, "activeBuffers", CTLFLAG_RD, &queue->active_queue_len, 0, "Buffers currently registered with hardware controller"); SYSCTL_ADD_INT(ctx, parent, OID_AUTO, "maxActiveBuffers", CTLFLAG_RD, &queue->max_active_queue_len, 0, "Max value of activeBuffers since last driver reset"); SYSCTL_ADD_INT(ctx, parent, OID_AUTO, "availBuffers", CTLFLAG_RD, &queue->avail_queue_len, 0, "Buffers allocated to this queue but not currently " "registered with hardware controller"); SYSCTL_ADD_INT(ctx, parent, OID_AUTO, "maxAvailBuffers", CTLFLAG_RD, &queue->max_avail_queue_len, 0, "Max value of availBuffers since last driver reset"); SYSCTL_ADD_UINT(ctx, parent, OID_AUTO, "totalEnqueued", CTLFLAG_RD, &queue->queue_adds, 0, "Total buffers added to queue"); SYSCTL_ADD_UINT(ctx, parent, OID_AUTO, "totalDequeued", CTLFLAG_RD, &queue->queue_removes, 0, "Total buffers removed from queue"); SYSCTL_ADD_UINT(ctx, parent, OID_AUTO, "queueRestart", CTLFLAG_RD, &queue->queue_restart, 0, "Total times the queue has been restarted"); SYSCTL_ADD_UINT(ctx, parent, OID_AUTO, "longestChain", CTLFLAG_RD, &queue->longest_chain, 0, "Max buffers used for a single packet"); } static void cpsw_add_watchdog_sysctls(struct sysctl_ctx_list *ctx, struct sysctl_oid *node, struct cpsw_softc *sc) { struct sysctl_oid_list *parent; parent = SYSCTL_CHILDREN(node); SYSCTL_ADD_INT(ctx, parent, OID_AUTO, "resets", CTLFLAG_RD, &sc->watchdog.resets, 0, "Total number of watchdog resets"); } static void cpsw_add_sysctls(struct cpsw_softc *sc) { struct sysctl_ctx_list *ctx; struct sysctl_oid *stats_node, *queue_node, *node; struct sysctl_oid_list *parent, *stats_parent, *queue_parent; struct sysctl_oid_list *ports_parent, *port_parent; char port[16]; int i; ctx = device_get_sysctl_ctx(sc->dev); parent = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)); SYSCTL_ADD_INT(ctx, parent, OID_AUTO, "debug", CTLFLAG_RW, &sc->debug, 0, "Enable switch debug messages"); SYSCTL_ADD_PROC(ctx, parent, OID_AUTO, "attachedSecs", CTLTYPE_UINT | CTLFLAG_RD | CTLFLAG_NEEDGIANT, sc, 0, cpsw_stat_attached, "IU", "Time since driver attach"); SYSCTL_ADD_PROC(ctx, parent, OID_AUTO, "intr_coalesce_us", CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, sc, 0, cpsw_intr_coalesce, "IU", "minimum time between interrupts"); node = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "ports", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "CPSW Ports Statistics"); ports_parent = SYSCTL_CHILDREN(node); for (i = 0; i < CPSW_PORTS; i++) { if (!sc->dualemac && i != sc->active_slave) continue; port[0] = '0' + i; port[1] = '\0'; node = SYSCTL_ADD_NODE(ctx, ports_parent, OID_AUTO, port, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "CPSW Port Statistics"); port_parent = SYSCTL_CHILDREN(node); SYSCTL_ADD_PROC(ctx, port_parent, OID_AUTO, "uptime", CTLTYPE_UINT | CTLFLAG_RD | CTLFLAG_NEEDGIANT, sc, i, cpsw_stat_uptime, "IU", "Seconds since driver init"); } stats_node = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "stats", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "CPSW Statistics"); stats_parent = SYSCTL_CHILDREN(stats_node); for (i = 0; i < CPSW_SYSCTL_COUNT; ++i) { SYSCTL_ADD_PROC(ctx, stats_parent, i, cpsw_stat_sysctls[i].oid, CTLTYPE_U64 | CTLFLAG_RD | CTLFLAG_NEEDGIANT, sc, 0, cpsw_stats_sysctl, "IU", cpsw_stat_sysctls[i].oid); } queue_node = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "queue", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "CPSW Queue Statistics"); queue_parent = SYSCTL_CHILDREN(queue_node); node = SYSCTL_ADD_NODE(ctx, queue_parent, OID_AUTO, "tx", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "TX Queue Statistics"); cpsw_add_queue_sysctls(ctx, node, &sc->tx); node = SYSCTL_ADD_NODE(ctx, queue_parent, OID_AUTO, "rx", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "RX Queue Statistics"); cpsw_add_queue_sysctls(ctx, node, &sc->rx); node = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "watchdog", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Watchdog Statistics"); cpsw_add_watchdog_sysctls(ctx, node, sc); } #ifdef CPSW_ETHERSWITCH static etherswitch_info_t etherswitch_info = { .es_nports = CPSW_PORTS + 1, .es_nvlangroups = CPSW_VLANS, .es_name = "TI Common Platform Ethernet Switch (CPSW)", .es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q, }; static etherswitch_info_t * cpsw_getinfo(device_t dev) { return (ðerswitch_info); } static int cpsw_getport(device_t dev, etherswitch_port_t *p) { int err; struct cpsw_softc *sc; struct cpswp_softc *psc; struct ifmediareq *ifmr; uint32_t reg; if (p->es_port < 0 || p->es_port > CPSW_PORTS) return (ENXIO); err = 0; sc = device_get_softc(dev); if (p->es_port == CPSW_CPU_PORT) { p->es_flags |= ETHERSWITCH_PORT_CPU; ifmr = &p->es_ifmr; ifmr->ifm_current = ifmr->ifm_active = IFM_ETHER | IFM_1000_T | IFM_FDX; ifmr->ifm_mask = 0; ifmr->ifm_status = IFM_ACTIVE | IFM_AVALID; ifmr->ifm_count = 0; } else { psc = device_get_softc(sc->port[p->es_port - 1].dev); err = ifmedia_ioctl(psc->ifp, &p->es_ifr, &psc->mii->mii_media, SIOCGIFMEDIA); } reg = cpsw_read_4(sc, CPSW_PORT_P_VLAN(p->es_port)); p->es_pvid = reg & ETHERSWITCH_VID_MASK; reg = cpsw_read_4(sc, CPSW_ALE_PORTCTL(p->es_port)); if (reg & ALE_PORTCTL_DROP_UNTAGGED) p->es_flags |= ETHERSWITCH_PORT_DROPUNTAGGED; if (reg & ALE_PORTCTL_INGRESS) p->es_flags |= ETHERSWITCH_PORT_INGRESS; return (err); } static int cpsw_setport(device_t dev, etherswitch_port_t *p) { struct cpsw_softc *sc; struct cpswp_softc *psc; struct ifmedia *ifm; uint32_t reg; if (p->es_port < 0 || p->es_port > CPSW_PORTS) return (ENXIO); sc = device_get_softc(dev); if (p->es_pvid != 0) { cpsw_write_4(sc, CPSW_PORT_P_VLAN(p->es_port), p->es_pvid & ETHERSWITCH_VID_MASK); } reg = cpsw_read_4(sc, CPSW_ALE_PORTCTL(p->es_port)); if (p->es_flags & ETHERSWITCH_PORT_DROPUNTAGGED) reg |= ALE_PORTCTL_DROP_UNTAGGED; else reg &= ~ALE_PORTCTL_DROP_UNTAGGED; if (p->es_flags & ETHERSWITCH_PORT_INGRESS) reg |= ALE_PORTCTL_INGRESS; else reg &= ~ALE_PORTCTL_INGRESS; cpsw_write_4(sc, CPSW_ALE_PORTCTL(p->es_port), reg); /* CPU port does not allow media settings. */ if (p->es_port == CPSW_CPU_PORT) return (0); psc = device_get_softc(sc->port[p->es_port - 1].dev); ifm = &psc->mii->mii_media; return (ifmedia_ioctl(psc->ifp, &p->es_ifr, ifm, SIOCSIFMEDIA)); } static int cpsw_getconf(device_t dev, etherswitch_conf_t *conf) { /* Return the VLAN mode. */ conf->cmd = ETHERSWITCH_CONF_VLAN_MODE; conf->vlan_mode = ETHERSWITCH_VLAN_DOT1Q; return (0); } static int cpsw_getvgroup(device_t dev, etherswitch_vlangroup_t *vg) { int i, vid; uint32_t ale_entry[3]; struct cpsw_softc *sc; sc = device_get_softc(dev); if (vg->es_vlangroup >= CPSW_VLANS) return (EINVAL); vg->es_vid = 0; vid = cpsw_vgroups[vg->es_vlangroup].vid; if (vid == -1) return (0); for (i = 0; i < CPSW_MAX_ALE_ENTRIES; i++) { cpsw_ale_read_entry(sc, i, ale_entry); if (ALE_TYPE(ale_entry) != ALE_TYPE_VLAN) continue; if (vid != ALE_VLAN(ale_entry)) continue; vg->es_fid = 0; vg->es_vid = ALE_VLAN(ale_entry) | ETHERSWITCH_VID_VALID; vg->es_member_ports = ALE_VLAN_MEMBERS(ale_entry); vg->es_untagged_ports = ALE_VLAN_UNTAG(ale_entry); } return (0); } static void cpsw_remove_vlan(struct cpsw_softc *sc, int vlan) { int i; uint32_t ale_entry[3]; for (i = 0; i < CPSW_MAX_ALE_ENTRIES; i++) { cpsw_ale_read_entry(sc, i, ale_entry); if (ALE_TYPE(ale_entry) != ALE_TYPE_VLAN) continue; if (vlan != ALE_VLAN(ale_entry)) continue; ale_entry[0] = ale_entry[1] = ale_entry[2] = 0; cpsw_ale_write_entry(sc, i, ale_entry); break; } } static int cpsw_setvgroup(device_t dev, etherswitch_vlangroup_t *vg) { int i; struct cpsw_softc *sc; sc = device_get_softc(dev); for (i = 0; i < CPSW_VLANS; i++) { /* Is this Vlan ID in use by another vlangroup ? */ if (vg->es_vlangroup != i && cpsw_vgroups[i].vid == vg->es_vid) return (EINVAL); } if (vg->es_vid == 0) { if (cpsw_vgroups[vg->es_vlangroup].vid == -1) return (0); cpsw_remove_vlan(sc, cpsw_vgroups[vg->es_vlangroup].vid); cpsw_vgroups[vg->es_vlangroup].vid = -1; vg->es_untagged_ports = 0; vg->es_member_ports = 0; vg->es_vid = 0; return (0); } vg->es_vid &= ETHERSWITCH_VID_MASK; vg->es_member_ports &= CPSW_PORTS_MASK; vg->es_untagged_ports &= CPSW_PORTS_MASK; if (cpsw_vgroups[vg->es_vlangroup].vid != -1 && cpsw_vgroups[vg->es_vlangroup].vid != vg->es_vid) return (EINVAL); cpsw_vgroups[vg->es_vlangroup].vid = vg->es_vid; cpsw_ale_update_vlan_table(sc, vg->es_vid, vg->es_member_ports, vg->es_untagged_ports, vg->es_member_ports, 0); return (0); } static int cpsw_readreg(device_t dev, int addr) { /* Not supported. */ return (0); } static int cpsw_writereg(device_t dev, int addr, int value) { /* Not supported. */ return (0); } static int cpsw_readphy(device_t dev, int phy, int reg) { /* Not supported. */ return (0); } static int cpsw_writephy(device_t dev, int phy, int reg, int data) { /* Not supported. */ return (0); } #endif diff --git a/sys/arm/ti/ti_scm_syscon.c b/sys/arm/ti/ti_scm_syscon.c index af77bc54f150..7286be7b8f2c 100644 --- a/sys/arm/ti/ti_scm_syscon.c +++ b/sys/arm/ti/ti_scm_syscon.c @@ -1,290 +1,290 @@ /*- * Copyright (c) 2019 Emmanuel Vadot * * Copyright (c) 2020 Oskar Holmlund * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* Based on sys/arm/ti/ti_sysc.c */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "syscon_if.h" -#include +#include #include "clkdev_if.h" #include #if 0 #define DPRINTF(dev, msg...) device_printf(dev, msg) #else #define DPRINTF(dev, msg...) #endif MALLOC_DECLARE(M_SYSCON); struct ti_scm_syscon_softc { struct simplebus_softc sc_simplebus; device_t dev; struct syscon * syscon; struct resource * res[1]; bus_space_tag_t bst; bus_space_handle_t bsh; struct mtx mtx; }; static struct resource_spec ti_scm_syscon_res_spec[] = { { SYS_RES_MEMORY, 0, RF_ACTIVE | RF_SHAREABLE }, { -1, 0 } }; /* Device */ static struct ofw_compat_data compat_data[] = { { "syscon", 1 }, { NULL, 0 } }; /* --- dev/extres/syscon syscon_method_t interface --- */ static int ti_scm_syscon_write_4(struct syscon *syscon, bus_size_t offset, uint32_t val) { struct ti_scm_syscon_softc *sc; sc = device_get_softc(syscon->pdev); DPRINTF(sc->dev, "offset=%lx write %x\n", offset, val); mtx_lock(&sc->mtx); bus_space_write_4(sc->bst, sc->bsh, offset, val); mtx_unlock(&sc->mtx); return (0); } static uint32_t ti_scm_syscon_read_4(struct syscon *syscon, bus_size_t offset) { struct ti_scm_syscon_softc *sc; uint32_t val; sc = device_get_softc(syscon->pdev); mtx_lock(&sc->mtx); val = bus_space_read_4(sc->bst, sc->bsh, offset); mtx_unlock(&sc->mtx); DPRINTF(sc->dev, "offset=%lx Read %x\n", offset, val); return (val); } static int ti_scm_syscon_modify_4(struct syscon *syscon, bus_size_t offset, uint32_t clr, uint32_t set) { struct ti_scm_syscon_softc *sc; uint32_t reg; sc = device_get_softc(syscon->pdev); mtx_lock(&sc->mtx); reg = bus_space_read_4(sc->bst, sc->bsh, offset); reg &= ~clr; reg |= set; bus_space_write_4(sc->bst, sc->bsh, offset, reg); mtx_unlock(&sc->mtx); DPRINTF(sc->dev, "offset=%lx reg: %x (clr %x set %x)\n", offset, reg, clr, set); return (0); } static syscon_method_t ti_scm_syscon_reg_methods[] = { SYSCONMETHOD(syscon_read_4, ti_scm_syscon_read_4), SYSCONMETHOD(syscon_write_4, ti_scm_syscon_write_4), SYSCONMETHOD(syscon_modify_4, ti_scm_syscon_modify_4), SYSCONMETHOD_END }; DEFINE_CLASS_1(ti_scm_syscon_reg, ti_scm_syscon_reg_class, ti_scm_syscon_reg_methods, 0, syscon_class); /* device interface */ static int ti_scm_syscon_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (!ti_soc_is_supported()) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "TI OMAP Control Module Syscon"); return(BUS_PROBE_DEFAULT); } static int ti_scm_syscon_attach(device_t dev) { struct ti_scm_syscon_softc *sc; phandle_t node, child; sc = device_get_softc(dev); sc->dev = dev; if (bus_alloc_resources(dev, ti_scm_syscon_res_spec, sc->res)) { device_printf(sc->dev, "Cant allocate resources\n"); return (ENXIO); } sc->dev = dev; sc->bst = rman_get_bustag(sc->res[0]); sc->bsh = rman_get_bushandle(sc->res[0]); mtx_init(&sc->mtx, device_get_nameunit(sc->dev), NULL, MTX_DEF); node = ofw_bus_get_node(sc->dev); /* dev/extres/syscon interface */ sc->syscon = syscon_create_ofw_node(dev, &ti_scm_syscon_reg_class, node); if (sc->syscon == NULL) { device_printf(dev, "Failed to create/register syscon\n"); return (ENXIO); } simplebus_init(sc->dev, node); bus_generic_probe(sc->dev); for (child = OF_child(node); child != 0; child = OF_peer(child)) { simplebus_add_device(sc->dev, child, 0, NULL, -1, NULL); } return (bus_generic_attach(sc->dev)); } /* syscon interface */ static int ti_scm_syscon_get_handle(device_t dev, struct syscon **syscon) { struct ti_scm_syscon_softc *sc; sc = device_get_softc(dev); *syscon = sc->syscon; if (*syscon == NULL) return (ENODEV); return (0); } /* clkdev interface */ static int ti_scm_syscon_clk_write_4(device_t dev, bus_addr_t addr, uint32_t val) { struct ti_scm_syscon_softc *sc; sc = device_get_softc(dev); DPRINTF(sc->dev, "offset=%lx write %x\n", addr, val); bus_space_write_4(sc->bst, sc->bsh, addr, val); return (0); } static int ti_scm_syscon_clk_read_4(device_t dev, bus_addr_t addr, uint32_t *val) { struct ti_scm_syscon_softc *sc; sc = device_get_softc(dev); *val = bus_space_read_4(sc->bst, sc->bsh, addr); DPRINTF(sc->dev, "offset=%lx Read %x\n", addr, *val); return (0); } static int ti_scm_syscon_clk_modify_4(device_t dev, bus_addr_t addr, uint32_t clr, uint32_t set) { struct ti_scm_syscon_softc *sc; uint32_t reg; sc = device_get_softc(dev); reg = bus_space_read_4(sc->bst, sc->bsh, addr); reg &= ~clr; reg |= set; bus_space_write_4(sc->bst, sc->bsh, addr, reg); DPRINTF(sc->dev, "offset=%lx reg: %x (clr %x set %x)\n", addr, reg, clr, set); return (0); } static void ti_scm_syscon_clk_device_lock(device_t dev) { struct ti_scm_syscon_softc *sc; sc = device_get_softc(dev); mtx_lock(&sc->mtx); } static void ti_scm_syscon_clk_device_unlock(device_t dev) { struct ti_scm_syscon_softc *sc; sc = device_get_softc(dev); mtx_unlock(&sc->mtx); } static device_method_t ti_scm_syscon_methods[] = { DEVMETHOD(device_probe, ti_scm_syscon_probe), DEVMETHOD(device_attach, ti_scm_syscon_attach), /* syscon interface */ DEVMETHOD(syscon_get_handle, ti_scm_syscon_get_handle), /* clkdev interface */ DEVMETHOD(clkdev_write_4, ti_scm_syscon_clk_write_4), DEVMETHOD(clkdev_read_4, ti_scm_syscon_clk_read_4), DEVMETHOD(clkdev_modify_4, ti_scm_syscon_clk_modify_4), DEVMETHOD(clkdev_device_lock, ti_scm_syscon_clk_device_lock), DEVMETHOD(clkdev_device_unlock, ti_scm_syscon_clk_device_unlock), DEVMETHOD_END }; DEFINE_CLASS_1(ti_scm_syscon, ti_scm_syscon_driver, ti_scm_syscon_methods, sizeof(struct ti_scm_syscon_softc), simplebus_driver); EARLY_DRIVER_MODULE(ti_scm_syscon, simplebus, ti_scm_syscon_driver, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE); MODULE_VERSION(ti_scm_syscon, 1); MODULE_DEPEND(ti_scm_syscon, ti_scm, 1, 1, 1); diff --git a/sys/arm64/rockchip/rk3328_codec.c b/sys/arm64/rockchip/rk3328_codec.c index ff6f2a3da881..91d73ee4ca34 100644 --- a/sys/arm64/rockchip/rk3328_codec.c +++ b/sys/arm64/rockchip/rk3328_codec.c @@ -1,605 +1,605 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2020 Oleksandr Tymoshenko * Copyright (c) 2018 Jared McNeill * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include "syscon_if.h" #include "opt_snd.h" #include #include #include "audio_dai_if.h" #include "mixer_if.h" #define RKCODEC_MIXER_DEVS (1 << SOUND_MIXER_VOLUME) #define GRF_SOC_CON2 0x0408 #define SOC_CON2_I2S_ACODEC_EN (1 << 14) #define SOC_CON2_I2S_ACODEC_EN_MASK ((1 << 14) << 16) #define GRF_SOC_CON10 0x0428 #define SOC_CON10_GPIOMUT (1 << 1) #define SOC_CON10_GPIOMUT_MASK ((1 << 1) << 16) #define SOC_CON10_GPIOMUT_EN (1 << 0) #define SOC_CON10_GPIOMUT_EN_MASK ((1 << 0) << 16) #define CODEC_RESET 0x00 #define RESET_DIG_CORE_RST (1 << 1) #define RESET_SYS_RST (1 << 0) #define CODEC_DAC_INIT_CTRL1 0x0c #define DAC_INIT_CTRL1_DIRECTION_IN (0 << 5) #define DAC_INIT_CTRL1_DIRECTION_OUT (1 << 5) #define DAC_INIT_CTRL1_DAC_I2S_MODE_SLAVE (0 << 4) #define DAC_INIT_CTRL1_DAC_I2S_MODE_MASTER (1 << 4) #define DAC_INIT_CTRL1_MODE_MASK (3 << 4) #define CODEC_DAC_INIT_CTRL2 0x10 #define DAC_INIT_CTRL2_DAC_VDL_16BITS (0 << 5) #define DAC_INIT_CTRL2_DAC_VDL_20BITS (1 << 5) #define DAC_INIT_CTRL2_DAC_VDL_24BITS (2 << 5) #define DAC_INIT_CTRL2_DAC_VDL_32BITS (3 << 5) #define DAC_INIT_CTRL2_DAC_VDL_MASK (3 << 5) #define DAC_INIT_CTRL2_DAC_MODE_RJM (0 << 3) #define DAC_INIT_CTRL2_DAC_MODE_LJM (1 << 3) #define DAC_INIT_CTRL2_DAC_MODE_I2S (2 << 3) #define DAC_INIT_CTRL2_DAC_MODE_PCM (3 << 3) #define DAC_INIT_CTRL2_DAC_MODE_MASK (3 << 3) #define CODEC_DAC_INIT_CTRL3 0x14 #define DAC_INIT_CTRL3_WL_16BITS (0 << 2) #define DAC_INIT_CTRL3_WL_20BITS (1 << 2) #define DAC_INIT_CTRL3_WL_24BITS (2 << 2) #define DAC_INIT_CTRL3_WL_32BITS (3 << 2) #define DAC_INIT_CTRL3_WL_MASK (3 << 2) #define DAC_INIT_CTRL3_RST_MASK (1 << 1) #define DAC_INIT_CTRL3_RST_DIS (1 << 1) #define DAC_INIT_CTRL3_DAC_BCP_REVERSAL (1 << 0) #define DAC_INIT_CTRL3_DAC_BCP_NORMAL (0 << 0) #define DAC_INIT_CTRL3_DAC_BCP_MASK (1 << 0) #define CODEC_DAC_PRECHARGE_CTRL 0x88 #define DAC_PRECHARGE_CTRL_DAC_CHARGE_PRECHARGE (1 << 7) #define DAC_PRECHARGE_CTRL_DAC_CHARGE_CURRENT_I (1 << 0) #define DAC_PRECHARGE_CTRL_DAC_CHARGE_CURRENT_ALL (0x7f) #define CODEC_DAC_PWR_CTRL 0x8c #define DAC_PWR_CTRL_DAC_PWR (1 << 6) #define DAC_PWR_CTRL_DACL_PATH_REFV (1 << 5) #define DAC_PWR_CTRL_HPOUTL_ZERO_CROSSING (1 << 4) #define DAC_PWR_CTRL_DACR_PATH_REFV (1 << 1) #define DAC_PWR_CTRL_HPOUTR_ZERO_CROSSING (1 << 0) #define CODEC_DAC_CLK_CTRL 0x90 #define DAC_CLK_CTRL_DACL_REFV_ON (1 << 7) #define DAC_CLK_CTRL_DACL_CLK_ON (1 << 6) #define DAC_CLK_CTRL_DACL_ON (1 << 5) #define DAC_CLK_CTRL_DACL_INIT_ON (1 << 4) #define DAC_CLK_CTRL_DACR_REFV_ON (1 << 3) #define DAC_CLK_CTRL_DACR_CLK_ON (1 << 2) #define DAC_CLK_CTRL_DACR_ON (1 << 1) #define DAC_CLK_CTRL_DACR_INIT_ON (1 << 0) #define CODEC_HPMIX_CTRL 0x94 #define HPMIX_CTRL_HPMIXL_EN (1 << 6) #define HPMIX_CTRL_HPMIXL_INIT_EN (1 << 5) #define HPMIX_CTRL_HPMIXL_INIT2_EN (1 << 4) #define HPMIX_CTRL_HPMIXR_EN (1 << 2) #define HPMIX_CTRL_HPMIXR_INIT_EN (1 << 1) #define HPMIX_CTRL_HPMIXR_INIT2_EN (1 << 0) #define CODEC_DAC_SELECT 0x98 #define DAC_SELECT_DACL_SELECT (1 << 4) #define DAC_SELECT_DACR_SELECT (1 << 0) #define CODEC_HPOUT_CTRL 0x9c #define HPOUT_CTRL_HPOUTL_EN (1 << 7) #define HPOUT_CTRL_HPOUTL_INIT_EN (1 << 6) #define HPOUT_CTRL_HPOUTL_UNMUTE (1 << 5) #define HPOUT_CTRL_HPOUTR_EN (1 << 4) #define HPOUT_CTRL_HPOUTR_INIT_EN (1 << 3) #define HPOUT_CTRL_HPOUTR_UNMUTE (1 << 2) #define CODEC_HPOUTL_GAIN_CTRL 0xa0 #define CODEC_HPOUTR_GAIN_CTRL 0xa4 #define CODEC_HPOUT_POP_CTRL 0xa8 #define HPOUT_POP_CTRL_HPOUTR_POP (1 << 5) #define HPOUT_POP_CTRL_HPOUTR_POP_XCHARGE (1 << 4) #define HPOUT_POP_CTRL_HPOUTL_POP (1 << 1) #define HPOUT_POP_CTRL_HPOUTL_POP_XCHARGE (1 << 0) #define DEFAULT_RATE (48000 * 256) static struct ofw_compat_data compat_data[] = { { "rockchip,rk3328-codec", 1}, { NULL, 0 } }; struct rkcodec_softc { device_t dev; struct resource *res; struct mtx mtx; clk_t mclk; clk_t pclk; struct syscon *grf; u_int regaddr; /* address for the sysctl */ }; #define RKCODEC_LOCK(sc) mtx_lock(&(sc)->mtx) #define RKCODEC_UNLOCK(sc) mtx_unlock(&(sc)->mtx) #define RKCODEC_READ(sc, reg) bus_read_4((sc)->res, (reg)) #define RKCODEC_WRITE(sc, reg, val) bus_write_4((sc)->res, (reg), (val)) static int rkcodec_probe(device_t dev); static int rkcodec_attach(device_t dev); static int rkcodec_detach(device_t dev); static void rkcodec_set_power(struct rkcodec_softc *sc, bool poweron) { uint32_t val; val = RKCODEC_READ(sc, CODEC_DAC_PRECHARGE_CTRL); if (poweron) val |= DAC_PRECHARGE_CTRL_DAC_CHARGE_PRECHARGE; else val &= ~(DAC_PRECHARGE_CTRL_DAC_CHARGE_PRECHARGE); RKCODEC_WRITE(sc, CODEC_DAC_PRECHARGE_CTRL, val); DELAY(10000); val = RKCODEC_READ(sc, CODEC_DAC_PRECHARGE_CTRL); if (poweron) val |= DAC_PRECHARGE_CTRL_DAC_CHARGE_CURRENT_ALL; else val &= ~(DAC_PRECHARGE_CTRL_DAC_CHARGE_CURRENT_ALL); RKCODEC_WRITE(sc, CODEC_DAC_PRECHARGE_CTRL, val); } static void rkcodec_set_mute(struct rkcodec_softc *sc, bool muted) { uint32_t val; val = SOC_CON10_GPIOMUT_MASK; if (!muted) val |= SOC_CON10_GPIOMUT; SYSCON_WRITE_4(sc->grf, GRF_SOC_CON10, val); } static void rkcodec_reset(struct rkcodec_softc *sc) { RKCODEC_WRITE(sc, CODEC_RESET, 0); DELAY(10000); RKCODEC_WRITE(sc, CODEC_RESET, RESET_DIG_CORE_RST | RESET_SYS_RST); } static int rkcodec_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) return (ENXIO); device_set_desc(dev, "Rockchip RK3328 CODEC"); return (BUS_PROBE_DEFAULT); } static int rkcodec_attach(device_t dev) { struct rkcodec_softc *sc; int error, rid; phandle_t node; uint32_t val; sc = device_get_softc(dev); sc->dev = dev; mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF); rid = 0; sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (!sc->res) { device_printf(dev, "could not allocate resource for device\n"); error = ENXIO; goto fail; } node = ofw_bus_get_node(dev); if (syscon_get_by_ofw_property(dev, node, "rockchip,grf", &sc->grf) != 0) { device_printf(dev, "cannot get rockchip,grf handle\n"); return (ENXIO); } val = SOC_CON2_I2S_ACODEC_EN | SOC_CON2_I2S_ACODEC_EN_MASK; SYSCON_WRITE_4(sc->grf, GRF_SOC_CON2, val); val = 0 | SOC_CON10_GPIOMUT_EN_MASK; SYSCON_WRITE_4(sc->grf, GRF_SOC_CON10, val); error = clk_get_by_ofw_name(dev, 0, "pclk", &sc->pclk); if (error != 0) { device_printf(dev, "could not get pclk clock\n"); goto fail; } error = clk_get_by_ofw_name(dev, 0, "mclk", &sc->mclk); if (error != 0) { device_printf(dev, "could not get mclk clock\n"); goto fail; } error = clk_enable(sc->pclk); if (error != 0) { device_printf(sc->dev, "could not enable pclk clock\n"); goto fail; } error = clk_enable(sc->mclk); if (error != 0) { device_printf(sc->dev, "could not enable mclk clock\n"); goto fail; } #if 0 error = clk_set_freq(sc->mclk, DEFAULT_RATE, 0); if (error != 0) { device_printf(sc->dev, "could not set frequency for mclk clock\n"); goto fail; } #endif /* TODO: handle mute-gpios */ rkcodec_reset(sc); rkcodec_set_power(sc, true); val = RKCODEC_READ(sc, CODEC_DAC_PWR_CTRL); val |= DAC_PWR_CTRL_DAC_PWR; RKCODEC_WRITE(sc, CODEC_DAC_PWR_CTRL, val); DELAY(1000); val |= DAC_PWR_CTRL_DACL_PATH_REFV | DAC_PWR_CTRL_DACR_PATH_REFV; RKCODEC_WRITE(sc, CODEC_DAC_PWR_CTRL, val); DELAY(1000); val |= DAC_PWR_CTRL_HPOUTL_ZERO_CROSSING | DAC_PWR_CTRL_HPOUTR_ZERO_CROSSING; RKCODEC_WRITE(sc, CODEC_DAC_PWR_CTRL, val); DELAY(1000); val = RKCODEC_READ(sc, CODEC_HPOUT_POP_CTRL); val |= HPOUT_POP_CTRL_HPOUTR_POP | HPOUT_POP_CTRL_HPOUTL_POP; val &= ~(HPOUT_POP_CTRL_HPOUTR_POP_XCHARGE | HPOUT_POP_CTRL_HPOUTL_POP_XCHARGE); RKCODEC_WRITE(sc, CODEC_HPOUT_POP_CTRL, val); DELAY(1000); val = RKCODEC_READ(sc, CODEC_HPMIX_CTRL); val |= HPMIX_CTRL_HPMIXL_EN | HPMIX_CTRL_HPMIXR_EN; RKCODEC_WRITE(sc, CODEC_HPMIX_CTRL, val); DELAY(1000); val |= HPMIX_CTRL_HPMIXL_INIT_EN | HPMIX_CTRL_HPMIXR_INIT_EN; RKCODEC_WRITE(sc, CODEC_HPMIX_CTRL, val); DELAY(1000); val = RKCODEC_READ(sc, CODEC_HPOUT_CTRL); val |= HPOUT_CTRL_HPOUTL_EN | HPOUT_CTRL_HPOUTR_EN; RKCODEC_WRITE(sc, CODEC_HPOUT_CTRL, val); DELAY(1000); val |= HPOUT_CTRL_HPOUTL_INIT_EN | HPOUT_CTRL_HPOUTR_INIT_EN; RKCODEC_WRITE(sc, CODEC_HPOUT_CTRL, val); DELAY(1000); val = RKCODEC_READ(sc, CODEC_DAC_CLK_CTRL); val |= DAC_CLK_CTRL_DACL_REFV_ON | DAC_CLK_CTRL_DACR_REFV_ON; RKCODEC_WRITE(sc, CODEC_DAC_CLK_CTRL, val); DELAY(1000); val |= DAC_CLK_CTRL_DACL_CLK_ON | DAC_CLK_CTRL_DACR_CLK_ON; RKCODEC_WRITE(sc, CODEC_DAC_CLK_CTRL, val); DELAY(1000); val |= DAC_CLK_CTRL_DACL_ON | DAC_CLK_CTRL_DACR_ON; RKCODEC_WRITE(sc, CODEC_DAC_CLK_CTRL, val); DELAY(1000); val |= DAC_CLK_CTRL_DACL_INIT_ON | DAC_CLK_CTRL_DACR_INIT_ON; RKCODEC_WRITE(sc, CODEC_DAC_CLK_CTRL, val); DELAY(1000); val = RKCODEC_READ(sc, CODEC_DAC_SELECT); val |= DAC_SELECT_DACL_SELECT | DAC_SELECT_DACR_SELECT; RKCODEC_WRITE(sc, CODEC_DAC_SELECT, val); DELAY(1000); val = RKCODEC_READ(sc, CODEC_HPMIX_CTRL); val |= HPMIX_CTRL_HPMIXL_INIT2_EN | HPMIX_CTRL_HPMIXR_INIT2_EN; RKCODEC_WRITE(sc, CODEC_HPMIX_CTRL, val); DELAY(1000); val = RKCODEC_READ(sc, CODEC_HPOUT_CTRL); val |= HPOUT_CTRL_HPOUTL_UNMUTE | HPOUT_CTRL_HPOUTR_UNMUTE; RKCODEC_WRITE(sc, CODEC_HPOUT_CTRL, val); DELAY(1000); RKCODEC_WRITE(sc, CODEC_HPOUTL_GAIN_CTRL, 0x18); RKCODEC_WRITE(sc, CODEC_HPOUTR_GAIN_CTRL, 0x18); DELAY(1000); rkcodec_set_mute(sc, false); node = ofw_bus_get_node(dev); OF_device_register_xref(OF_xref_from_node(node), dev); return (0); fail: rkcodec_detach(dev); return (error); } static int rkcodec_detach(device_t dev) { struct rkcodec_softc *sc; sc = device_get_softc(dev); if (sc->res) bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->res); mtx_destroy(&sc->mtx); return (0); } static int rkcodec_mixer_init(struct snd_mixer *m) { mix_setdevs(m, RKCODEC_MIXER_DEVS); return (0); } static int rkcodec_mixer_uninit(struct snd_mixer *m) { return (0); } static int rkcodec_mixer_reinit(struct snd_mixer *m) { return (0); } static int rkcodec_mixer_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right) { struct rkcodec_softc *sc; struct mtx *mixer_lock; uint8_t do_unlock; sc = device_get_softc(mix_getdevinfo(m)); mixer_lock = mixer_get_lock(m); if (mtx_owned(mixer_lock)) { do_unlock = 0; } else { do_unlock = 1; mtx_lock(mixer_lock); } right = left; RKCODEC_LOCK(sc); switch(dev) { case SOUND_MIXER_VOLUME: printf("[%s] %s:%d\n", __func__, __FILE__, __LINE__); break; case SOUND_MIXER_MIC: printf("[%s] %s:%d\n", __func__, __FILE__, __LINE__); break; default: break; } RKCODEC_UNLOCK(sc); if (do_unlock) { mtx_unlock(mixer_lock); } return (left | (right << 8)); } static unsigned rkcodec_mixer_setrecsrc(struct snd_mixer *m, unsigned src) { return (0); } static kobj_method_t rkcodec_mixer_methods[] = { KOBJMETHOD(mixer_init, rkcodec_mixer_init), KOBJMETHOD(mixer_uninit, rkcodec_mixer_uninit), KOBJMETHOD(mixer_reinit, rkcodec_mixer_reinit), KOBJMETHOD(mixer_set, rkcodec_mixer_set), KOBJMETHOD(mixer_setrecsrc, rkcodec_mixer_setrecsrc), KOBJMETHOD_END }; MIXER_DECLARE(rkcodec_mixer); static int rkcodec_dai_init(device_t dev, uint32_t format) { struct rkcodec_softc *sc; int fmt, pol, clk; uint32_t ctrl1, ctrl2, ctrl3; sc = device_get_softc(dev); fmt = AUDIO_DAI_FORMAT_FORMAT(format); pol = AUDIO_DAI_FORMAT_POLARITY(format); clk = AUDIO_DAI_FORMAT_CLOCK(format); ctrl1 = RKCODEC_READ(sc, CODEC_DAC_INIT_CTRL1); ctrl2 = RKCODEC_READ(sc, CODEC_DAC_INIT_CTRL2); ctrl3 = RKCODEC_READ(sc, CODEC_DAC_INIT_CTRL3); ctrl3 &= ~(DAC_INIT_CTRL3_DAC_BCP_MASK); switch (pol) { case AUDIO_DAI_POLARITY_IB_NF: ctrl3 |= DAC_INIT_CTRL3_DAC_BCP_REVERSAL; break; case AUDIO_DAI_POLARITY_NB_NF: ctrl3 |= DAC_INIT_CTRL3_DAC_BCP_NORMAL; break; default: return (EINVAL); } ctrl1 &= ~(DAC_INIT_CTRL1_MODE_MASK); switch (clk) { case AUDIO_DAI_CLOCK_CBM_CFM: ctrl1 |= DAC_INIT_CTRL1_DIRECTION_OUT | DAC_INIT_CTRL1_DAC_I2S_MODE_SLAVE; break; case AUDIO_DAI_CLOCK_CBS_CFS: ctrl1 |= DAC_INIT_CTRL1_DIRECTION_IN | DAC_INIT_CTRL1_DAC_I2S_MODE_SLAVE; break; default: return (EINVAL); } ctrl2 &= ~(DAC_INIT_CTRL2_DAC_VDL_MASK | DAC_INIT_CTRL2_DAC_MODE_MASK); ctrl2 |= DAC_INIT_CTRL2_DAC_VDL_16BITS; ctrl3 &= ~(DAC_INIT_CTRL3_WL_MASK); ctrl3 |= DAC_INIT_CTRL3_WL_32BITS; switch (fmt) { case AUDIO_DAI_FORMAT_I2S: ctrl2 |= DAC_INIT_CTRL2_DAC_MODE_I2S; break; case AUDIO_DAI_FORMAT_LJ: ctrl2 |= DAC_INIT_CTRL2_DAC_MODE_LJM; break; case AUDIO_DAI_FORMAT_RJ: ctrl2 |= DAC_INIT_CTRL2_DAC_MODE_RJM; break; default: return EINVAL; } ctrl3 &= ~(DAC_INIT_CTRL3_RST_MASK); ctrl3 |= DAC_INIT_CTRL3_RST_DIS; RKCODEC_WRITE(sc, CODEC_DAC_INIT_CTRL1, ctrl1); RKCODEC_WRITE(sc, CODEC_DAC_INIT_CTRL2, ctrl2); RKCODEC_WRITE(sc, CODEC_DAC_INIT_CTRL3, ctrl3); return (0); } static int rkcodec_dai_trigger(device_t dev, int go, int pcm_dir) { // struct rkcodec_softc *sc = device_get_softc(dev); if ((pcm_dir != PCMDIR_PLAY) && (pcm_dir != PCMDIR_REC)) return (EINVAL); switch (go) { case PCMTRIG_START: if (pcm_dir == PCMDIR_PLAY) { printf("[%s] %s:%d\n", __func__, __FILE__, __LINE__); } else if (pcm_dir == PCMDIR_REC) { printf("[%s] %s:%d\n", __func__, __FILE__, __LINE__); } break; case PCMTRIG_STOP: case PCMTRIG_ABORT: if (pcm_dir == PCMDIR_PLAY) { printf("[%s] %s:%d\n", __func__, __FILE__, __LINE__); } else if (pcm_dir == PCMDIR_REC) { printf("[%s] %s:%d\n", __func__, __FILE__, __LINE__); } break; } return (0); } static int rkcodec_dai_setup_mixer(device_t dev, device_t pcmdev) { mixer_init(pcmdev, &rkcodec_mixer_class, dev); return (0); } static device_method_t rkcodec_methods[] = { /* Device interface */ DEVMETHOD(device_probe, rkcodec_probe), DEVMETHOD(device_attach, rkcodec_attach), DEVMETHOD(device_detach, rkcodec_detach), DEVMETHOD(audio_dai_init, rkcodec_dai_init), DEVMETHOD(audio_dai_setup_mixer, rkcodec_dai_setup_mixer), DEVMETHOD(audio_dai_trigger, rkcodec_dai_trigger), DEVMETHOD_END }; static driver_t rkcodec_driver = { "rk3328codec", rkcodec_methods, sizeof(struct rkcodec_softc), }; DRIVER_MODULE(rkcodec, simplebus, rkcodec_driver, 0, 0); SIMPLEBUS_PNP_INFO(compat_data); diff --git a/sys/arm64/rockchip/rk3399_emmcphy.c b/sys/arm64/rockchip/rk3399_emmcphy.c index 8799dcb06b5d..97b2123e89fd 100644 --- a/sys/arm64/rockchip/rk3399_emmcphy.c +++ b/sys/arm64/rockchip/rk3399_emmcphy.c @@ -1,337 +1,337 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2019 Ganbold Tsagaankhuu * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Rockchip RK3399 eMMC PHY */ #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include #include "syscon_if.h" #define GRF_EMMCPHY_BASE 0xf780 #define GRF_EMMCPHY_CON0 (GRF_EMMCPHY_BASE + 0x00) #define PHYCTRL_FRQSEL (1 << 13) | (1 << 12) #define PHYCTRL_FRQSEL_200M 0 #define PHYCTRL_FRQSEL_50M 1 #define PHYCTRL_FRQSEL_100M 2 #define PHYCTRL_FRQSEL_150M 3 #define PHYCTRL_OTAPDLYENA (1 << 11) #define PHYCTRL_OTAPDLYSEL (1 << 10) | (1 << 9) | (1 << 8) | (1 << 7) #define PHYCTRL_ITAPCHGWIN (1 << 6) #define PHYCTRL_ITAPDLYSEL (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | \ (1 << 1) #define PHYCTRL_ITAPDLYENA (1 << 0) #define GRF_EMMCPHY_CON1 (GRF_EMMCPHY_BASE + 0x04) #define PHYCTRL_CLKBUFSEL (1 << 8) | (1 << 7) | (1 << 6) #define PHYCTRL_SELDLYTXCLK (1 << 5) #define PHYCTRL_SELDLYRXCLK (1 << 4) #define PHYCTRL_STRBSEL 0xf #define GRF_EMMCPHY_CON2 (GRF_EMMCPHY_BASE + 0x08) #define PHYCTRL_REN_STRB (1 << 9) #define PHYCTRL_REN_CMD (1 << 8) #define PHYCTRL_REN_DAT 0xff #define GRF_EMMCPHY_CON3 (GRF_EMMCPHY_BASE + 0x0c) #define PHYCTRL_PU_STRB (1 << 9) #define PHYCTRL_PU_CMD (1 << 8) #define PHYCTRL_PU_DAT 0xff #define GRF_EMMCPHY_CON4 (GRF_EMMCPHY_BASE + 0x10) #define PHYCTRL_OD_RELEASE_CMD (1 << 9) #define PHYCTRL_OD_RELEASE_STRB (1 << 8) #define PHYCTRL_OD_RELEASE_DAT 0xff #define GRF_EMMCPHY_CON5 (GRF_EMMCPHY_BASE + 0x14) #define PHYCTRL_ODEN_STRB (1 << 9) #define PHYCTRL_ODEN_CMD (1 << 8) #define PHYCTRL_ODEN_DAT 0xff #define GRF_EMMCPHY_CON6 (GRF_EMMCPHY_BASE + 0x18) #define PHYCTRL_DLL_TRM_ICP (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) #define PHYCTRL_EN_RTRIM (1 << 8) #define PHYCTRL_RETRIM (1 << 7) #define PHYCTRL_DR_TY (1 << 6) | (1 << 5) | (1 << 4) #define PHYCTRL_RETENB (1 << 3) #define PHYCTRL_RETEN (1 << 2) #define PHYCTRL_ENDLL (1 << 1) #define PHYCTRL_PDB (1 << 0) #define GRF_EMMCPHY_STATUS (GRF_EMMCPHY_BASE + 0x20) #define PHYCTRL_CALDONE (1 << 6) #define PHYCTRL_DLLRDY (1 << 5) #define PHYCTRL_RTRIM (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1) #define PHYCTRL_EXR_NINST (1 << 0) static struct ofw_compat_data compat_data[] = { { "rockchip,rk3399-emmc-phy", 1 }, { NULL, 0 } }; struct rk_emmcphy_softc { struct syscon *syscon; struct rk_emmcphy_conf *phy_conf; clk_t clk; }; #define LOWEST_SET_BIT(mask) ((((mask) - 1) & (mask)) ^ (mask)) #define SHIFTIN(x, mask) ((x) * LOWEST_SET_BIT(mask)) /* Phy class and methods. */ static int rk_emmcphy_enable(struct phynode *phynode, bool enable); static phynode_method_t rk_emmcphy_phynode_methods[] = { PHYNODEMETHOD(phynode_enable, rk_emmcphy_enable), PHYNODEMETHOD_END }; DEFINE_CLASS_1(rk_emmcphy_phynode, rk_emmcphy_phynode_class, rk_emmcphy_phynode_methods, 0, phynode_class); static int rk_emmcphy_enable(struct phynode *phynode, bool enable) { struct rk_emmcphy_softc *sc; device_t dev; intptr_t phy; uint64_t rate, frqsel; uint32_t mask, val; int error; dev = phynode_get_device(phynode); phy = phynode_get_id(phynode); sc = device_get_softc(dev); if (bootverbose) device_printf(dev, "Phy id: %ld\n", phy); if (phy != 0) { device_printf(dev, "Unknown phy: %ld\n", phy); return (ERANGE); } if (enable) { /* Drive strength */ mask = PHYCTRL_DR_TY; val = SHIFTIN(0, PHYCTRL_DR_TY); SYSCON_WRITE_4(sc->syscon, GRF_EMMCPHY_CON6, (mask << 16) | val); /* Enable output tap delay */ mask = PHYCTRL_OTAPDLYENA | PHYCTRL_OTAPDLYSEL; val = PHYCTRL_OTAPDLYENA | SHIFTIN(4, PHYCTRL_OTAPDLYSEL); SYSCON_WRITE_4(sc->syscon, GRF_EMMCPHY_CON0, (mask << 16) | val); } /* Power down PHY and disable DLL before making changes */ mask = PHYCTRL_ENDLL | PHYCTRL_PDB; val = 0; SYSCON_WRITE_4(sc->syscon, GRF_EMMCPHY_CON6, (mask << 16) | val); if (enable == false) return (0); sc->phy_conf = (struct rk_emmcphy_conf *)ofw_bus_search_compatible(dev, compat_data)->ocd_data; /* Get clock */ error = clk_get_by_ofw_name(dev, 0, "emmcclk", &sc->clk); if (error != 0) { device_printf(dev, "cannot get emmcclk clock, continue\n"); sc->clk = NULL; } else device_printf(dev, "got emmcclk clock\n"); if (sc->clk) { error = clk_get_freq(sc->clk, &rate); if (error != 0) { device_printf(dev, "cannot get clock frequency\n"); return (ENXIO); } } else rate = 0; if (rate != 0) { if (rate < 75000000) frqsel = PHYCTRL_FRQSEL_50M; else if (rate < 125000000) frqsel = PHYCTRL_FRQSEL_100M; else if (rate < 175000000) frqsel = PHYCTRL_FRQSEL_150M; else frqsel = PHYCTRL_FRQSEL_200M; } else frqsel = PHYCTRL_FRQSEL_200M; DELAY(3); /* Power up PHY */ mask = PHYCTRL_PDB; val = PHYCTRL_PDB; SYSCON_WRITE_4(sc->syscon, GRF_EMMCPHY_CON6, (mask << 16) | val); /* Wait for calibration */ DELAY(10); val = SYSCON_READ_4(sc->syscon, GRF_EMMCPHY_STATUS); if ((val & PHYCTRL_CALDONE) == 0) { device_printf(dev, "PHY calibration did not complete\n"); return (ENXIO); } /* Set DLL frequency */ mask = PHYCTRL_FRQSEL; val = SHIFTIN(frqsel, PHYCTRL_FRQSEL); SYSCON_WRITE_4(sc->syscon, GRF_EMMCPHY_CON0, (mask << 16) | val); /* Enable DLL */ mask = PHYCTRL_ENDLL; val = PHYCTRL_ENDLL; SYSCON_WRITE_4(sc->syscon, GRF_EMMCPHY_CON6, (mask << 16) | val); if (rate != 0) { /* * Rockchip RK3399 TRM V1.3 Part2.pdf says in page 698: * After the DLL control loop reaches steady state a DLL * ready signal is generated by the DLL circuits * 'phyctrl_dllrdy'. * The time from 'phyctrl_endll' to DLL ready signal * 'phyctrl_dllrdy' varies with the clock frequency. * At 200MHz clock frequency the DLL ready delay is 2.56us, * at 100MHz clock frequency the DLL ready delay is 5.112us and * at 50 MHz clock frequency the DLL ready delay is 10.231us. * We could use safe values for wait, 12us, 8us, 6us and 4us * respectively. * However due to some unknown reason it is not working and * DLL seems to take extra long time to lock. * So we will use more safe value 50ms here. */ /* Wait for DLL ready */ DELAY(50000); val = SYSCON_READ_4(sc->syscon, GRF_EMMCPHY_STATUS); if ((val & PHYCTRL_DLLRDY) == 0) { device_printf(dev, "DLL loop failed to lock\n"); return (ENXIO); } } return (0); } static int rk_emmcphy_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "Rockchip RK3399 eMMC PHY"); return (BUS_PROBE_DEFAULT); } static int rk_emmcphy_attach(device_t dev) { struct phynode_init_def phy_init; struct phynode *phynode; struct rk_emmcphy_softc *sc; phandle_t node; phandle_t xnode; pcell_t handle; intptr_t phy; sc = device_get_softc(dev); node = ofw_bus_get_node(dev); if (OF_getencprop(node, "clocks", (void *)&handle, sizeof(handle)) <= 0) { device_printf(dev, "cannot get clocks handle\n"); return (ENXIO); } xnode = OF_node_from_xref(handle); if (OF_hasprop(xnode, "arasan,soc-ctl-syscon") && syscon_get_by_ofw_property(dev, xnode, "arasan,soc-ctl-syscon", &sc->syscon) != 0) { device_printf(dev, "cannot get grf driver handle\n"); return (ENXIO); } if (sc->syscon == NULL) { device_printf(dev, "failed to get syscon\n"); return (ENXIO); } /* Create and register phy */ bzero(&phy_init, sizeof(phy_init)); phy_init.id = 0; phy_init.ofw_node = ofw_bus_get_node(dev); phynode = phynode_create(dev, &rk_emmcphy_phynode_class, &phy_init); if (phynode == NULL) { device_printf(dev, "failed to create eMMC PHY\n"); return (ENXIO); } if (phynode_register(phynode) == NULL) { device_printf(dev, "failed to register eMMC PHY\n"); return (ENXIO); } if (bootverbose) { phy = phynode_get_id(phynode); device_printf(dev, "Attached phy id: %ld\n", phy); } return (0); } static device_method_t rk_emmcphy_methods[] = { /* Device interface */ DEVMETHOD(device_probe, rk_emmcphy_probe), DEVMETHOD(device_attach, rk_emmcphy_attach), DEVMETHOD_END }; static driver_t rk_emmcphy_driver = { "rk_emmcphy", rk_emmcphy_methods, sizeof(struct rk_emmcphy_softc) }; EARLY_DRIVER_MODULE(rk_emmcphy, simplebus, rk_emmcphy_driver, 0, 0, BUS_PASS_SUPPORTDEV + BUS_PASS_ORDER_MIDDLE); MODULE_VERSION(rk_emmcphy, 1); diff --git a/sys/arm64/rockchip/rk3568_combphy.c b/sys/arm64/rockchip/rk3568_combphy.c index 1f9c0003b531..c5d35fa0b8e2 100644 --- a/sys/arm64/rockchip/rk3568_combphy.c +++ b/sys/arm64/rockchip/rk3568_combphy.c @@ -1,469 +1,469 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2021, 2022 Soren Schmidt * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include #include #include "syscon_if.h" #include "phydev_if.h" #include "phynode_if.h" static struct ofw_compat_data compat_data[] = { {"rockchip,rk3568-naneng-combphy", 1}, {NULL, 0} }; struct rk3568_combphy_softc { device_t dev; phandle_t node; struct resource *mem; struct phynode *phynode; struct syscon *pipe_grf; struct syscon *pipe_phy_grf; clk_t ref_clk; clk_t apb_clk; clk_t pipe_clk; hwreset_t phy_reset; int mode; }; #define PHYREG6 0x14 #define PHYREG6_PLL_DIV_MASK 0xc0 #define PHYREG6_PLL_DIV_2 (1 << 6) #define PHYREG7 0x18 #define PHYREG7_TX_RTERM_50OHM (8 << 4) #define PHYREG7_RX_RTERM_44OHM (15 << 0) #define PHYREG8 0x1c #define PHYREG8_SSC_EN 0x10 #define PHYREG11 0x28 #define PHYREG11_SU_TRIM_0_7 0xf0 #define PHYREG12 0x2c #define PHYREG12_PLL_LPF_ADJ_VALUE 4 #define PHYREG15 0x38 #define PHYREG15_CTLE_EN 0x01 #define PHYREG15_SSC_CNT_MASK 0xc0 #define PHYREG15_SSC_CNT_VALUE (1 << 6) #define PHYREG16 0x3c #define PHYREG16_SSC_CNT_VALUE 0x5f #define PHYREG18 0x44 #define PHYREG18_PLL_LOOP 0x32 #define PHYREG32 0x7c #define PHYREG32_SSC_MASK 0xf0 #define PHYREG32_SSC_UPWARD (0 << 4) #define PHYREG32_SSC_DOWNWARD (1 << 4) #define PHYREG32_SSC_OFFSET_500PPM (1 << 6) #define PHYREG33 0x80 #define PHYREG33_PLL_KVCO_MASK 0x1c #define PHYREG33_PLL_KVCO_VALUE (2 << 2) #define PIPE_MASK_ALL (0xffff << 16) #define PIPE_PHY_GRF_PIPE_CON0 0x00 #define PIPE_DATABUSWIDTH_MASK 0x3 #define PIPE_DATABUSWIDTH_32BIT 0 #define PIPE_DATABUSWIDTH_16BIT 1 #define PIPE_PHYMODE_MASK (3 << 2) #define PIPE_PHYMODE_PCIE (0 << 2) #define PIPE_PHYMODE_USB3 (1 << 2) #define PIPE_PHYMODE_SATA (2 << 2) #define PIPE_RATE_MASK (3 << 4) #define PIPE_RATE_PCIE_2_5GBPS (0 << 4) #define PIPE_RATE_PCIE_5GBPS (1 << 4) #define PIPE_RATE_USB3_5GBPS (0 << 4) #define PIPE_RATE_SATA_1GBPS5 (0 << 4) #define PIPE_RATE_SATA_3GBPS (1 << 4) #define PIPE_RATE_SATA_6GBPS (2 << 4) #define PIPE_MAC_PCLKREQ_N (1 << 8) #define PIPE_L1SUB_ENTREQ (1 << 9) #define PIPE_RXTERM (1 << 12) #define PIPE_PHY_GRF_PIPE_CON1 0x04 #define PHY_CLK_SEL_MASK (3 << 13) #define PHY_CLK_SEL_24M (0 << 13) #define PHY_CLK_SEL_25M (1 << 13) #define PHY_CLK_SEL_100M (2 << 13) #define PIPE_PHY_GRF_PIPE_CON2 0x08 #define SEL_PIPE_TXCOMPLIANCE_I (1 << 15) #define SEL_PIPE_TXELECIDLE (1 << 12) #define SEL_PIPE_RXTERM (1 << 8) #define SEL_PIPE_BYPASS_CODEC (1 << 7) #define SEL_PIPE_PIPE_EBUF (1 << 6) #define SEL_PIPE_PIPE_PHYMODE (1 << 1) #define SEL_PIPE_DATABUSWIDTH (1 << 0) #define PIPE_PHY_GRF_PIPE_CON3 0x0c #define PIPE_SEL_MASK (3 << 13) #define PIPE_SEL_PCIE (0 << 13) #define PIPE_SEL_USB3 (1 << 13) #define PIPE_SEL_SATA (2 << 13) #define PIPE_CLK_REF_SRC_I_MASK (3 << 8) #define PIPE_CLK_REF_SRC_I_PLL_CKREF_INNER (2 << 8) #define PIPE_RXELECIDLE (1 << 10) #define PIPE_FROM_PCIE_IO (1 << 11) #define PIPE_GRF_PIPE_CON0 0x00 #define SATA2_PHY_SPDMODE_1GBPS5 (0 << 12) #define SATA2_PHY_SPDMODE_3GBPS (1 << 12) #define SATA2_PHY_SPDMODE_6GBPS (2 << 12) #define SATA1_PHY_SPDMODE_1GBPS5 (0 << 8) #define SATA1_PHY_SPDMODE_3GBPS (1 << 8) #define SATA1_PHY_SPDMODE_6GBPS (2 << 8) #define SATA0_PHY_SPDMODE_1GBPS5 (0 << 4) #define SATA0_PHY_SPDMODE_3GBPS (1 << 4) #define SATA0_PHY_SPDMODE_6GBPS (2 << 4) #define PIPE_GRF_SATA_CON0 0x10 #define PIPE_GRF_SATA_CON1 0x14 #define PIPE_GRF_SATA_CON2 0x18 #define PIPE_GRF_XPCS_CON0 0x40 /* PHY class and methods */ static int rk3568_combphy_enable(struct phynode *phynode, bool enable) { device_t dev = phynode_get_device(phynode); struct rk3568_combphy_softc *sc = device_get_softc(dev); uint64_t rate; if (enable == false) return (0); switch (sc->mode) { case PHY_TYPE_SATA: device_printf(dev, "configuring for SATA"); /* tx_rterm 50 ohm & rx_rterm 44 ohm */ bus_write_4(sc->mem, PHYREG7, PHYREG7_TX_RTERM_50OHM | PHYREG7_RX_RTERM_44OHM); /* Adaptive CTLE */ bus_write_4(sc->mem, PHYREG15, bus_read_4(sc->mem, PHYREG15) | PHYREG15_CTLE_EN); /* config grf_pipe for PCIe */ SYSCON_WRITE_4(sc->pipe_phy_grf, PIPE_PHY_GRF_PIPE_CON3, PIPE_MASK_ALL | PIPE_SEL_SATA | PIPE_RXELECIDLE | 0x7); SYSCON_WRITE_4(sc->pipe_phy_grf, PIPE_PHY_GRF_PIPE_CON2, PIPE_MASK_ALL | SEL_PIPE_TXCOMPLIANCE_I | SEL_PIPE_DATABUSWIDTH | 0xc3); SYSCON_WRITE_4(sc->pipe_phy_grf, PIPE_PHY_GRF_PIPE_CON0, PIPE_MASK_ALL | PIPE_RXTERM | PIPE_DATABUSWIDTH_16BIT | PIPE_RATE_SATA_3GBPS | PIPE_PHYMODE_SATA); SYSCON_WRITE_4(sc->pipe_grf, PIPE_GRF_PIPE_CON0, PIPE_MASK_ALL | SATA0_PHY_SPDMODE_6GBPS | SATA1_PHY_SPDMODE_6GBPS | SATA2_PHY_SPDMODE_6GBPS); break; case PHY_TYPE_PCIE: device_printf(dev, "configuring for PCIe"); /* Set SSC downward spread spectrum */ bus_write_4(sc->mem, PHYREG32, (bus_read_4(sc->mem, PHYREG32) & PHYREG32_SSC_MASK) | PHYREG32_SSC_DOWNWARD); /* config grf_pipe for PCIe */ SYSCON_WRITE_4(sc->pipe_phy_grf, PIPE_PHY_GRF_PIPE_CON3, PIPE_MASK_ALL | PIPE_SEL_PCIE | PIPE_CLK_REF_SRC_I_PLL_CKREF_INNER); SYSCON_WRITE_4(sc->pipe_phy_grf, PIPE_PHY_GRF_PIPE_CON2, PIPE_MASK_ALL | SEL_PIPE_RXTERM | SEL_PIPE_DATABUSWIDTH); SYSCON_WRITE_4(sc->pipe_phy_grf, PIPE_PHY_GRF_PIPE_CON0, PIPE_MASK_ALL | PIPE_RXTERM | PIPE_DATABUSWIDTH_32BIT | PIPE_RATE_PCIE_2_5GBPS | PIPE_PHYMODE_PCIE); break; case PHY_TYPE_USB3: device_printf(dev, "configuring for USB3"); /* Set SSC downward spread spectrum */ bus_write_4(sc->mem, PHYREG32, (bus_read_4(sc->mem, PHYREG32) & PHYREG32_SSC_MASK) | PHYREG32_SSC_DOWNWARD); /* Adaptive CTLE */ bus_write_4(sc->mem, PHYREG15, bus_read_4(sc->mem, PHYREG15) | PHYREG15_CTLE_EN); /* Set PLL KVCO fine tuning signals */ bus_write_4(sc->mem, PHYREG33, (bus_read_4(sc->mem, PHYREG33) & PHYREG33_PLL_KVCO_MASK) | PHYREG33_PLL_KVCO_VALUE); /* Enable controlling random jitter. */ bus_write_4(sc->mem, PHYREG12, PHYREG12_PLL_LPF_ADJ_VALUE); /* Set PLL input clock divider 1/2 */ bus_write_4(sc->mem, PHYREG6, (bus_read_4(sc->mem, PHYREG6) & PHYREG6_PLL_DIV_MASK) | PHYREG6_PLL_DIV_2); /* Set PLL loop divider */ bus_write_4(sc->mem, PHYREG18, PHYREG18_PLL_LOOP); /* Set PLL LPF R1 to su_trim[0:7] */ bus_write_4(sc->mem, PHYREG11, PHYREG11_SU_TRIM_0_7); /* config grf_pipe for USB3 */ SYSCON_WRITE_4(sc->pipe_phy_grf, PIPE_PHY_GRF_PIPE_CON3, PIPE_MASK_ALL | PIPE_SEL_USB3); SYSCON_WRITE_4(sc->pipe_phy_grf, PIPE_PHY_GRF_PIPE_CON2, PIPE_MASK_ALL); SYSCON_WRITE_4(sc->pipe_phy_grf, PIPE_PHY_GRF_PIPE_CON0, PIPE_MASK_ALL | PIPE_DATABUSWIDTH_16BIT | PIPE_PHYMODE_USB3 | PIPE_RATE_USB3_5GBPS); break; default: printf("Unsupported mode=%d\n", sc->mode); return (-1); } clk_get_freq(sc->ref_clk, &rate); printf(" ref_clk=%lu\n", rate); switch (rate) { case 24000000: SYSCON_WRITE_4(sc->pipe_phy_grf, PIPE_PHY_GRF_PIPE_CON1, (PHY_CLK_SEL_MASK << 16) | PHY_CLK_SEL_24M); if (sc->mode == PHY_TYPE_USB3 || sc->mode == PHY_TYPE_SATA) { /* Adaptive CTLE */ bus_write_4(sc->mem, PHYREG15, (bus_read_4(sc->mem, PHYREG15) & PHYREG15_SSC_CNT_MASK) | PHYREG15_SSC_CNT_VALUE); /* SSC control period */ bus_write_4(sc->mem, PHYREG16, PHYREG16_SSC_CNT_VALUE); } break; case 25000000: SYSCON_WRITE_4(sc->pipe_phy_grf, PIPE_PHY_GRF_PIPE_CON1, (PHY_CLK_SEL_MASK << 16) | PHY_CLK_SEL_25M); break; case 100000000: SYSCON_WRITE_4(sc->pipe_phy_grf, PIPE_PHY_GRF_PIPE_CON1, (PHY_CLK_SEL_MASK << 16) | PHY_CLK_SEL_100M); if (sc->mode == PHY_TYPE_PCIE) { /* Set PLL KVCO fine tuning signals */ bus_write_4(sc->mem, PHYREG33, (bus_read_4(sc->mem, PHYREG33) & PHYREG33_PLL_KVCO_MASK) | PHYREG33_PLL_KVCO_VALUE); /* Enable controlling random jitter. */ bus_write_4(sc->mem, PHYREG12, PHYREG12_PLL_LPF_ADJ_VALUE); /* Set PLL input clock divider 1/2 */ bus_write_4(sc->mem, PHYREG6, (bus_read_4(sc->mem, PHYREG6) & PHYREG6_PLL_DIV_MASK) | PHYREG6_PLL_DIV_2); /* Set PLL loop divider */ bus_write_4(sc->mem, PHYREG18, PHYREG18_PLL_LOOP); /* Set PLL LPF R1 to su_trim[0:7] */ bus_write_4(sc->mem, PHYREG11, PHYREG11_SU_TRIM_0_7); } if (sc->mode == PHY_TYPE_SATA) { /* Set SSC downward spread spectrum */ bus_write_4(sc->mem, PHYREG32, (bus_read_4(sc->mem, PHYREG32) & ~0x000000f0) | PHYREG32_SSC_DOWNWARD | PHYREG32_SSC_OFFSET_500PPM); } break; default: device_printf(dev, "unknown ref rate=%lu\n", rate); break; } if (OF_hasprop(sc->node, "rockchip,ext-refclk")) { device_printf(dev, "UNSUPPORTED rockchip,ext-refclk\n"); } if (OF_hasprop(sc->node, "rockchip,enable-ssc")) { device_printf(dev, "setting rockchip,enable-ssc\n"); bus_write_4(sc->mem, PHYREG8, bus_read_4(sc->mem, PHYREG8) | PHYREG8_SSC_EN); } if (hwreset_deassert(sc->phy_reset)) device_printf(dev, "phy_reset failed to clear\n"); return (0); } static phynode_method_t rk3568_combphy_phynode_methods[] = { PHYNODEMETHOD(phynode_enable, rk3568_combphy_enable), PHYNODEMETHOD_END }; DEFINE_CLASS_1(rk3568_combphy_phynode, rk3568_combphy_phynode_class, rk3568_combphy_phynode_methods, 0, phynode_class); /* Device class and methods */ static int rk3568_combphy_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "RockChip combo PHY"); return (BUS_PROBE_DEFAULT); } static int rk3568_combphy_attach(device_t dev) { struct rk3568_combphy_softc *sc = device_get_softc(dev); struct phynode_init_def phy_init; struct phynode *phynode; int rid = 0; sc->dev = dev; sc->node = ofw_bus_get_node(dev); /* Get memory resource */ if (!(sc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE))) { device_printf(dev, "Cannot allocate memory resources\n"); return (ENXIO); } /* Get syncons handles */ if (OF_hasprop(sc->node, "rockchip,pipe-grf") && syscon_get_by_ofw_property(dev, sc->node, "rockchip,pipe-grf", &sc->pipe_grf)) return (ENXIO); if (OF_hasprop(sc->node, "rockchip,pipe-phy-grf") && syscon_get_by_ofw_property(dev, sc->node, "rockchip,pipe-phy-grf", &sc->pipe_phy_grf)) return (ENXIO); /* Get & enable clocks */ if (clk_get_by_ofw_name(dev, 0, "ref", &sc->ref_clk)) { device_printf(dev, "getting ref failed\n"); return (ENXIO); } if (clk_enable(sc->ref_clk)) device_printf(dev, "enable ref failed\n"); if (clk_get_by_ofw_name(dev, 0, "apb", &sc->apb_clk)) { device_printf(dev, "getting apb failed\n"); return (ENXIO); } if (clk_enable(sc->apb_clk)) device_printf(dev, "enable apb failed\n"); if (clk_get_by_ofw_name(dev, 0, "pipe", &sc->pipe_clk)) { device_printf(dev, "getting pipe failed\n"); return (ENXIO); } if (clk_enable(sc->pipe_clk)) device_printf(dev, "enable pipe failed\n"); /* get & assert reset */ if (hwreset_get_by_ofw_idx(dev, sc->node, 0, &sc->phy_reset)) { device_printf(dev, "Cannot get reset\n"); return (ENXIO); } hwreset_assert(sc->phy_reset); bzero(&phy_init, sizeof(phy_init)); phy_init.id = 0; phy_init.ofw_node = sc->node; if (!(phynode = phynode_create(dev, &rk3568_combphy_phynode_class, &phy_init))) { device_printf(dev, "failed to create combphy PHY\n"); return (ENXIO); } if (!phynode_register(phynode)) { device_printf(dev, "failed to register combphy PHY\n"); return (ENXIO); } sc->phynode = phynode; sc->mode = 0; return (0); } static int rk3568_combphy_map(device_t dev, phandle_t xref, int ncells, pcell_t *cells, intptr_t *id) { struct rk3568_combphy_softc *sc = device_get_softc(dev); if (phydev_default_ofw_map(dev, xref, ncells, cells, id)) return (ERANGE); /* Store the phy mode that is handed to us in id */ sc->mode = *id; /* Set our id to 0 so the std phy_get_*() works as usual */ *id = 0; return (0); } static device_method_t rk3568_combphy_methods[] = { DEVMETHOD(device_probe, rk3568_combphy_probe), DEVMETHOD(device_attach, rk3568_combphy_attach), DEVMETHOD(phydev_map, rk3568_combphy_map), DEVMETHOD_END }; DEFINE_CLASS_1(rk3568_combphy, rk3568_combphy_driver, rk3568_combphy_methods, sizeof(struct simple_mfd_softc), simple_mfd_driver); EARLY_DRIVER_MODULE(rk3568_combphy, simplebus, rk3568_combphy_driver, 0, 0, BUS_PASS_RESOURCE + BUS_PASS_ORDER_LATE); diff --git a/sys/arm64/rockchip/rk3568_pciephy.c b/sys/arm64/rockchip/rk3568_pciephy.c index 83ee77decdb9..fc6156e596ed 100644 --- a/sys/arm64/rockchip/rk3568_pciephy.c +++ b/sys/arm64/rockchip/rk3568_pciephy.c @@ -1,263 +1,263 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2021, 2022 Soren Schmidt * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include #include #include "syscon_if.h" #include "phydev_if.h" #include "phynode_if.h" #define GRF_PCIE30PHY_CON1 0x04 #define GRF_PCIE30PHY_CON4 0x10 #define GRF_PCIE30PHY_CON5 0x14 #define GRF_PCIE30PHY_CON6 0x18 #define GRF_BIFURCATION_LANE_1 0 #define GRF_BIFURCATION_LANE_2 1 #define GRF_PCIE30PHY_WR_EN (0xf << 16) #define GRF_PCIE30PHY_CON9 0x24 #define GRF_PCIE30PHY_DA_OCM_MASK (1 << (15 + 16)) #define GRF_PCIE30PHY_DA_OCM ((1 << 15) | GRF_PCIE30PHY_DA_OCM_MASK) #define GRF_PCIE30PHY_STATUS0 0x80 #define SRAM_INIT_DONE (1 << 14) static struct ofw_compat_data compat_data[] = { {"rockchip,rk3568-pcie3-phy", 1}, {NULL, 0} }; struct rk3568_pciephy_softc { device_t dev; phandle_t node; struct resource *mem; struct phynode *phynode; struct syscon *phy_grf; clk_t refclk_m; clk_t refclk_n; clk_t pclk; hwreset_t phy_reset; }; static void rk3568_pciephy_bifurcate(device_t dev, int control, uint32_t lane) { struct rk3568_pciephy_softc *sc = device_get_softc(dev); switch (lane) { case 0: SYSCON_WRITE_4(sc->phy_grf, control, GRF_PCIE30PHY_WR_EN); return; case 1: SYSCON_WRITE_4(sc->phy_grf, control, GRF_PCIE30PHY_WR_EN | GRF_BIFURCATION_LANE_1); break; case 2: SYSCON_WRITE_4(sc->phy_grf, control, GRF_PCIE30PHY_WR_EN | GRF_BIFURCATION_LANE_2); break; default: device_printf(dev, "Illegal lane %d\n", lane); return; } if (bootverbose) device_printf(dev, "lane %d @ pcie3x%d\n", lane, (control == GRF_PCIE30PHY_CON5) ? 1 : 2); } /* PHY class and methods */ static int rk3568_pciephy_enable(struct phynode *phynode, bool enable) { device_t dev = phynode_get_device(phynode); struct rk3568_pciephy_softc *sc = device_get_softc(dev); int count; if (enable) { /* Pull PHY out of reset */ hwreset_deassert(sc->phy_reset); /* Poll for SRAM loaded and ready */ for (count = 100; count; count--) { if (SYSCON_READ_4(sc->phy_grf, GRF_PCIE30PHY_STATUS0) & SRAM_INIT_DONE) break; DELAY(10000); if (count == 0) { device_printf(dev, "SRAM init timeout!\n"); return (ENXIO); } } } return (0); } static phynode_method_t rk3568_pciephy_phynode_methods[] = { PHYNODEMETHOD(phynode_enable, rk3568_pciephy_enable), PHYNODEMETHOD_END }; DEFINE_CLASS_1(rk3568_pciephy_phynode, rk3568_pciephy_phynode_class, rk3568_pciephy_phynode_methods, 0, phynode_class); /* Device class and methods */ static int rk3568_pciephy_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "RockChip PCIe PHY"); return (BUS_PROBE_DEFAULT); } static int rk3568_pciephy_attach(device_t dev) { struct rk3568_pciephy_softc *sc = device_get_softc(dev); struct phynode_init_def phy_init; struct phynode *phynode; uint32_t data_lanes[2] = { 0, 0 }; int rid = 0; sc->dev = dev; sc->node = ofw_bus_get_node(dev); /* Get memory resource */ if (!(sc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE))) { device_printf(dev, "Cannot allocate memory resources\n"); return (ENXIO); } /* Get syncons handle */ if (OF_hasprop(sc->node, "rockchip,phy-grf") && syscon_get_by_ofw_property(dev, sc->node, "rockchip,phy-grf", &sc->phy_grf)) return (ENXIO); /* Get & enable clocks */ if (clk_get_by_ofw_name(dev, 0, "refclk_m", &sc->refclk_m)) { device_printf(dev, "getting refclk_m failed\n"); return (ENXIO); } if (clk_enable(sc->refclk_m)) device_printf(dev, "enable refclk_m failed\n"); if (clk_get_by_ofw_name(dev, 0, "refclk_n", &sc->refclk_n)) { device_printf(dev, "getting refclk_n failed\n"); return (ENXIO); } if (clk_enable(sc->refclk_n)) device_printf(dev, "enable refclk_n failed\n"); if (clk_get_by_ofw_name(dev, 0, "pclk", &sc->pclk)) { device_printf(dev, "getting pclk failed\n"); return (ENXIO); } if (clk_enable(sc->pclk)) device_printf(dev, "enable pclk failed\n"); /* Get & assert reset */ if (hwreset_get_by_ofw_idx(dev, sc->node, 0, &sc->phy_reset)) { device_printf(dev, "Cannot get reset\n"); } else hwreset_assert(sc->phy_reset); /* Set RC/EP mode not implemented yet (RC mode only) */ /* Set bifurcation according to "data-lanes" entry */ if (OF_hasprop(sc->node, "data-lanes")) { OF_getencprop(sc->node, "data-lanes", data_lanes, sizeof(data_lanes)); } else if (bootverbose) device_printf(dev, "lane 1 & 2 @pcie3x2\n"); /* Deassert PCIe PMA output clamp mode */ SYSCON_WRITE_4(sc->phy_grf, GRF_PCIE30PHY_CON9, GRF_PCIE30PHY_DA_OCM); /* Configure PHY HW accordingly */ rk3568_pciephy_bifurcate(dev, GRF_PCIE30PHY_CON5, data_lanes[0]); rk3568_pciephy_bifurcate(dev, GRF_PCIE30PHY_CON6, data_lanes[1]); if (data_lanes[0] || data_lanes[1]) SYSCON_WRITE_4(sc->phy_grf, GRF_PCIE30PHY_CON1, GRF_PCIE30PHY_DA_OCM); else SYSCON_WRITE_4(sc->phy_grf, GRF_PCIE30PHY_CON1, GRF_PCIE30PHY_DA_OCM_MASK); bzero(&phy_init, sizeof(phy_init)); phy_init.id = PHY_NONE; phy_init.ofw_node = sc->node; if (!(phynode = phynode_create(dev, &rk3568_pciephy_phynode_class, &phy_init))) { device_printf(dev, "failed to create pciephy PHY\n"); return (ENXIO); } if (!phynode_register(phynode)) { device_printf(dev, "failed to register pciephy PHY\n"); return (ENXIO); } sc->phynode = phynode; return (0); } static device_method_t rk3568_pciephy_methods[] = { DEVMETHOD(device_probe, rk3568_pciephy_probe), DEVMETHOD(device_attach, rk3568_pciephy_attach), DEVMETHOD_END }; DEFINE_CLASS_1(rk3568_pciephy, rk3568_pciephy_driver, rk3568_pciephy_methods, sizeof(struct simple_mfd_softc), simple_mfd_driver); EARLY_DRIVER_MODULE(rk3568_pciephy, simplebus, rk3568_pciephy_driver, 0, 0, BUS_PASS_RESOURCE + BUS_PASS_ORDER_LATE); diff --git a/sys/arm64/rockchip/rk_grf.c b/sys/arm64/rockchip/rk_grf.c index e2ee9a89b832..7e4911c1b048 100644 --- a/sys/arm64/rockchip/rk_grf.c +++ b/sys/arm64/rockchip/rk_grf.c @@ -1,82 +1,82 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2018 Emmanuel Vadot * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include -#include +#include #include static struct ofw_compat_data compat_data[] = { {"rockchip,rk3288-grf", 1}, {"rockchip,rk3328-grf", 1}, {"rockchip,rk3399-grf", 1}, {"rockchip,rk3399-pmugrf", 1}, {"rockchip,rk3568-grf", 1}, {"rockchip,rk3568-pmugrf", 1}, {"rockchip,rk3568-usb2phy-grf", 1}, {"rockchip,rk3566-pipe-grf", 1}, {"rockchip,rk3568-pipe-grf", 1}, {"rockchip,rk3568-pipe-phy-grf", 1}, {"rockchip,rk3568-pcie3-phy-grf", 1}, {NULL, 0} }; static int rk_grf_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "RockChip General Register Files"); return (BUS_PROBE_DEFAULT); } static device_method_t rk_grf_methods[] = { DEVMETHOD(device_probe, rk_grf_probe), DEVMETHOD_END }; DEFINE_CLASS_1(rk_grf, rk_grf_driver, rk_grf_methods, sizeof(struct simple_mfd_softc), simple_mfd_driver); EARLY_DRIVER_MODULE(rk_grf, simplebus, rk_grf_driver, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE); MODULE_VERSION(rk_grf, 1); diff --git a/sys/arm64/rockchip/rk_i2s.c b/sys/arm64/rockchip/rk_i2s.c index 3f7cd71eda27..6d3db56919d7 100644 --- a/sys/arm64/rockchip/rk_i2s.c +++ b/sys/arm64/rockchip/rk_i2s.c @@ -1,651 +1,651 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2019 Oleksandr Tymoshenko * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include "syscon_if.h" #include "opt_snd.h" #include #include #include "audio_dai_if.h" #define AUDIO_BUFFER_SIZE 48000 * 4 #define I2S_TXCR 0x0000 #define I2S_CSR_2 (0 << 15) #define I2S_CSR_4 (1 << 15) #define I2S_CSR_6 (2 << 15) #define I2S_CSR_8 (3 << 15) #define I2S_TXCR_IBM_NORMAL (0 << 9) #define I2S_TXCR_IBM_LJ (1 << 9) #define I2S_TXCR_IBM_RJ (2 << 9) #define I2S_TXCR_PBM_NODELAY (0 << 7) #define I2S_TXCR_PBM_1 (1 << 7) #define I2S_TXCR_PBM_2 (2 << 7) #define I2S_TXCR_PBM_3 (3 << 7) #define I2S_TXCR_TFS_I2S (0 << 5) #define I2S_TXCR_TFS_PCM (1 << 5) #define I2S_TXCR_VDW_16 (0xf << 0) #define I2S_RXCR 0x0004 #define I2S_RXCR_IBM_NORMAL (0 << 9) #define I2S_RXCR_IBM_LJ (1 << 9) #define I2S_RXCR_IBM_RJ (2 << 9) #define I2S_RXCR_PBM_NODELAY (0 << 7) #define I2S_RXCR_PBM_1 (1 << 7) #define I2S_RXCR_PBM_2 (2 << 7) #define I2S_RXCR_PBM_3 (3 << 7) #define I2S_RXCR_TFS_I2S (0 << 5) #define I2S_RXCR_TFS_PCM (1 << 5) #define I2S_RXCR_VDW_16 (0xf << 0) #define I2S_CKR 0x0008 #define I2S_CKR_MSS_MASK (1 << 27) #define I2S_CKR_MSS_MASTER (0 << 27) #define I2S_CKR_MSS_SLAVE (1 << 27) #define I2S_CKR_CKP (1 << 26) #define I2S_CKR_MDIV(n) (((n) - 1) << 16) #define I2S_CKR_MDIV_MASK (0xff << 16) #define I2S_CKR_RSD(n) (((n) - 1) << 8) #define I2S_CKR_RSD_MASK (0xff << 8) #define I2S_CKR_TSD(n) (((n) - 1) << 0) #define I2S_CKR_TSD_MASK (0xff << 0) #define I2S_TXFIFOLR 0x000c #define TXFIFO0LR_MASK 0x3f #define I2S_DMACR 0x0010 #define I2S_DMACR_RDE_ENABLE (1 << 24) #define I2S_DMACR_RDL(n) ((n) << 16) #define I2S_DMACR_TDE_ENABLE (1 << 8) #define I2S_DMACR_TDL(n) ((n) << 0) #define I2S_INTCR 0x0014 #define I2S_INTCR_RFT(n) (((n) - 1) << 20) #define I2S_INTCR_TFT(n) (((n) - 1) << 4) #define I2S_INTCR_RXFIE (1 << 16) #define I2S_INTCR_TXUIC (1 << 2) #define I2S_INTCR_TXEIE (1 << 0) #define I2S_INTSR 0x0018 #define I2S_INTSR_RXFI (1 << 16) #define I2S_INTSR_TXUI (1 << 1) #define I2S_INTSR_TXEI (1 << 0) #define I2S_XFER 0x001c #define I2S_XFER_RXS_START (1 << 1) #define I2S_XFER_TXS_START (1 << 0) #define I2S_CLR 0x0020 #define I2S_CLR_RXC (1 << 1) #define I2S_CLR_TXC (1 << 0) #define I2S_TXDR 0x0024 #define I2S_RXDR 0x0028 #define I2S_RXFIFOLR 0x002c #define RXFIFO0LR_MASK 0x3f /* syscon */ #define GRF_SOC_CON8 0xe220 #define I2S_IO_DIRECTION_MASK 7 #define I2S_IO_DIRECTION_SHIFT 11 #define I2S_IO_8CH_OUT_2CH_IN 0 #define I2S_IO_6CH_OUT_4CH_IN 4 #define I2S_IO_4CH_OUT_6CH_IN 6 #define I2S_IO_2CH_OUT_8CH_IN 7 #define DIV_ROUND_CLOSEST(n,d) (((n) + (d) / 2) / (d)) #define RK_I2S_SAMPLING_RATE 48000 #define FIFO_SIZE 32 static struct ofw_compat_data compat_data[] = { { "rockchip,rk3066-i2s", 1 }, { "rockchip,rk3399-i2s", 1 }, { NULL, 0 } }; static struct resource_spec rk_i2s_spec[] = { { SYS_RES_MEMORY, 0, RF_ACTIVE }, { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE }, { -1, 0 } }; struct rk_i2s_softc { device_t dev; struct resource *res[2]; struct mtx mtx; clk_t clk; clk_t hclk; void * intrhand; struct syscon *grf; /* pointers to playback/capture buffers */ uint32_t play_ptr; uint32_t rec_ptr; }; #define RK_I2S_LOCK(sc) mtx_lock(&(sc)->mtx) #define RK_I2S_UNLOCK(sc) mtx_unlock(&(sc)->mtx) #define RK_I2S_READ_4(sc, reg) bus_read_4((sc)->res[0], (reg)) #define RK_I2S_WRITE_4(sc, reg, val) bus_write_4((sc)->res[0], (reg), (val)) static int rk_i2s_probe(device_t dev); static int rk_i2s_attach(device_t dev); static int rk_i2s_detach(device_t dev); static uint32_t sc_fmt[] = { SND_FORMAT(AFMT_S16_LE, 2, 0), 0 }; static struct pcmchan_caps rk_i2s_caps = {RK_I2S_SAMPLING_RATE, RK_I2S_SAMPLING_RATE, sc_fmt, 0}; static int rk_i2s_init(struct rk_i2s_softc *sc) { uint32_t val; int error; clk_set_freq(sc->clk, RK_I2S_SAMPLING_RATE * 256, CLK_SET_ROUND_DOWN); error = clk_enable(sc->clk); if (error != 0) { device_printf(sc->dev, "cannot enable i2s_clk clock\n"); return (ENXIO); } val = I2S_INTCR_TFT(FIFO_SIZE/2); val |= I2S_INTCR_RFT(FIFO_SIZE/2); RK_I2S_WRITE_4(sc, I2S_INTCR, val); if (sc->grf && ofw_bus_is_compatible(sc->dev, "rockchip,rk3399-i2s")) { val = (I2S_IO_2CH_OUT_8CH_IN << I2S_IO_DIRECTION_SHIFT); val |= (I2S_IO_DIRECTION_MASK << I2S_IO_DIRECTION_SHIFT) << 16; SYSCON_WRITE_4(sc->grf, GRF_SOC_CON8, val); #if 0 // HACK: enable IO domain val = (1 << 1); val |= (1 << 1) << 16; SYSCON_WRITE_4(sc->grf, 0xe640, val); #endif } RK_I2S_WRITE_4(sc, I2S_XFER, 0); return (0); } static int rk_i2s_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) return (ENXIO); device_set_desc(dev, "Rockchip I2S"); return (BUS_PROBE_DEFAULT); } static int rk_i2s_attach(device_t dev) { struct rk_i2s_softc *sc; int error; phandle_t node; sc = device_get_softc(dev); sc->dev = dev; mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF); if (bus_alloc_resources(dev, rk_i2s_spec, sc->res) != 0) { device_printf(dev, "cannot allocate resources for device\n"); error = ENXIO; goto fail; } error = clk_get_by_ofw_name(dev, 0, "i2s_hclk", &sc->hclk); if (error != 0) { device_printf(dev, "cannot get i2s_hclk clock\n"); goto fail; } error = clk_get_by_ofw_name(dev, 0, "i2s_clk", &sc->clk); if (error != 0) { device_printf(dev, "cannot get i2s_clk clock\n"); goto fail; } /* Activate the module clock. */ error = clk_enable(sc->hclk); if (error != 0) { device_printf(dev, "cannot enable i2s_hclk clock\n"); goto fail; } node = ofw_bus_get_node(dev); if (OF_hasprop(node, "rockchip,grf") && syscon_get_by_ofw_property(dev, node, "rockchip,grf", &sc->grf) != 0) { device_printf(dev, "cannot get grf driver handle\n"); return (ENXIO); } rk_i2s_init(sc); OF_device_register_xref(OF_xref_from_node(node), dev); return (0); fail: rk_i2s_detach(dev); return (error); } static int rk_i2s_detach(device_t dev) { struct rk_i2s_softc *i2s; i2s = device_get_softc(dev); if (i2s->hclk != NULL) clk_release(i2s->hclk); if (i2s->clk) clk_release(i2s->clk); if (i2s->intrhand != NULL) bus_teardown_intr(i2s->dev, i2s->res[1], i2s->intrhand); bus_release_resources(dev, rk_i2s_spec, i2s->res); mtx_destroy(&i2s->mtx); return (0); } static int rk_i2s_dai_init(device_t dev, uint32_t format) { uint32_t val, txcr, rxcr; struct rk_i2s_softc *sc; int fmt, pol, clk; sc = device_get_softc(dev); fmt = AUDIO_DAI_FORMAT_FORMAT(format); pol = AUDIO_DAI_FORMAT_POLARITY(format); clk = AUDIO_DAI_FORMAT_CLOCK(format); /* Set format */ val = RK_I2S_READ_4(sc, I2S_CKR); val &= ~(I2S_CKR_MSS_MASK); switch (clk) { case AUDIO_DAI_CLOCK_CBM_CFM: val |= I2S_CKR_MSS_MASTER; break; case AUDIO_DAI_CLOCK_CBS_CFS: val |= I2S_CKR_MSS_SLAVE; break; default: return (EINVAL); } switch (pol) { case AUDIO_DAI_POLARITY_IB_NF: val |= I2S_CKR_CKP; break; case AUDIO_DAI_POLARITY_NB_NF: val &= ~I2S_CKR_CKP; break; default: return (EINVAL); } RK_I2S_WRITE_4(sc, I2S_CKR, val); txcr = I2S_TXCR_VDW_16 | I2S_CSR_2; rxcr = I2S_RXCR_VDW_16 | I2S_CSR_2; switch (fmt) { case AUDIO_DAI_FORMAT_I2S: txcr |= I2S_TXCR_IBM_NORMAL; rxcr |= I2S_RXCR_IBM_NORMAL; break; case AUDIO_DAI_FORMAT_LJ: txcr |= I2S_TXCR_IBM_LJ; rxcr |= I2S_RXCR_IBM_LJ; break; case AUDIO_DAI_FORMAT_RJ: txcr |= I2S_TXCR_IBM_RJ; rxcr |= I2S_RXCR_IBM_RJ; break; case AUDIO_DAI_FORMAT_DSPA: txcr |= I2S_TXCR_TFS_PCM; rxcr |= I2S_RXCR_TFS_PCM; txcr |= I2S_TXCR_PBM_1; rxcr |= I2S_RXCR_PBM_1; break; case AUDIO_DAI_FORMAT_DSPB: txcr |= I2S_TXCR_TFS_PCM; rxcr |= I2S_RXCR_TFS_PCM; txcr |= I2S_TXCR_PBM_2; rxcr |= I2S_RXCR_PBM_2; break; default: return EINVAL; } RK_I2S_WRITE_4(sc, I2S_TXCR, txcr); RK_I2S_WRITE_4(sc, I2S_RXCR, rxcr); RK_I2S_WRITE_4(sc, I2S_XFER, 0); return (0); } static int rk_i2s_dai_intr(device_t dev, struct snd_dbuf *play_buf, struct snd_dbuf *rec_buf) { struct rk_i2s_softc *sc; uint32_t status; uint32_t level; uint32_t val = 0x00; int ret = 0; sc = device_get_softc(dev); RK_I2S_LOCK(sc); status = RK_I2S_READ_4(sc, I2S_INTSR); if (status & I2S_INTSR_TXEI) { level = RK_I2S_READ_4(sc, I2S_TXFIFOLR) & TXFIFO0LR_MASK; uint8_t *samples; uint32_t count, size, readyptr, written; count = sndbuf_getready(play_buf); if (count > FIFO_SIZE - 1) count = FIFO_SIZE - 1; size = sndbuf_getsize(play_buf); readyptr = sndbuf_getreadyptr(play_buf); samples = (uint8_t*)sndbuf_getbuf(play_buf); written = 0; for (; level < count; level++) { val = (samples[readyptr++ % size] << 0); val |= (samples[readyptr++ % size] << 8); val |= (samples[readyptr++ % size] << 16); val |= (samples[readyptr++ % size] << 24); written += 4; RK_I2S_WRITE_4(sc, I2S_TXDR, val); } sc->play_ptr += written; sc->play_ptr %= size; ret |= AUDIO_DAI_PLAY_INTR; } if (status & I2S_INTSR_RXFI) { level = RK_I2S_READ_4(sc, I2S_RXFIFOLR) & RXFIFO0LR_MASK; uint8_t *samples; uint32_t count, size, freeptr, recorded; count = sndbuf_getfree(rec_buf); size = sndbuf_getsize(rec_buf); freeptr = sndbuf_getfreeptr(rec_buf); samples = (uint8_t*)sndbuf_getbuf(rec_buf); recorded = 0; if (level > count / 4) level = count / 4; for (; level > 0; level--) { val = RK_I2S_READ_4(sc, I2S_RXDR); samples[freeptr++ % size] = val & 0xff; samples[freeptr++ % size] = (val >> 8) & 0xff; samples[freeptr++ % size] = (val >> 16) & 0xff; samples[freeptr++ % size] = (val >> 24) & 0xff; recorded += 4; } sc->rec_ptr += recorded; sc->rec_ptr %= size; ret |= AUDIO_DAI_REC_INTR; } RK_I2S_UNLOCK(sc); return (ret); } static struct pcmchan_caps * rk_i2s_dai_get_caps(device_t dev) { return (&rk_i2s_caps); } static int rk_i2s_dai_trigger(device_t dev, int go, int pcm_dir) { struct rk_i2s_softc *sc = device_get_softc(dev); uint32_t val; uint32_t clear_bit; if ((pcm_dir != PCMDIR_PLAY) && (pcm_dir != PCMDIR_REC)) return (EINVAL); switch (go) { case PCMTRIG_START: val = RK_I2S_READ_4(sc, I2S_INTCR); if (pcm_dir == PCMDIR_PLAY) val |= I2S_INTCR_TXEIE; else if (pcm_dir == PCMDIR_REC) val |= I2S_INTCR_RXFIE; RK_I2S_WRITE_4(sc, I2S_INTCR, val); val = I2S_XFER_TXS_START | I2S_XFER_RXS_START; RK_I2S_WRITE_4(sc, I2S_XFER, val); break; case PCMTRIG_STOP: case PCMTRIG_ABORT: val = RK_I2S_READ_4(sc, I2S_INTCR); if (pcm_dir == PCMDIR_PLAY) val &= ~I2S_INTCR_TXEIE; else if (pcm_dir == PCMDIR_REC) val &= ~I2S_INTCR_RXFIE; RK_I2S_WRITE_4(sc, I2S_INTCR, val); /* * If there is no other activity going on, stop transfers */ if ((val & (I2S_INTCR_TXEIE | I2S_INTCR_RXFIE)) == 0) { RK_I2S_WRITE_4(sc, I2S_XFER, 0); if (pcm_dir == PCMDIR_PLAY) clear_bit = I2S_CLR_TXC; else if (pcm_dir == PCMDIR_REC) clear_bit = I2S_CLR_RXC; else return (EINVAL); val = RK_I2S_READ_4(sc, I2S_CLR); val |= clear_bit; RK_I2S_WRITE_4(sc, I2S_CLR, val); while ((RK_I2S_READ_4(sc, I2S_CLR) & clear_bit) != 0) DELAY(1); } RK_I2S_LOCK(sc); if (pcm_dir == PCMDIR_PLAY) sc->play_ptr = 0; else sc->rec_ptr = 0; RK_I2S_UNLOCK(sc); break; } return (0); } static uint32_t rk_i2s_dai_get_ptr(device_t dev, int pcm_dir) { struct rk_i2s_softc *sc; uint32_t ptr; sc = device_get_softc(dev); RK_I2S_LOCK(sc); if (pcm_dir == PCMDIR_PLAY) ptr = sc->play_ptr; else ptr = sc->rec_ptr; RK_I2S_UNLOCK(sc); return ptr; } static int rk_i2s_dai_setup_intr(device_t dev, driver_intr_t intr_handler, void *intr_arg) { struct rk_i2s_softc *sc = device_get_softc(dev); if (bus_setup_intr(dev, sc->res[1], INTR_TYPE_MISC | INTR_MPSAFE, NULL, intr_handler, intr_arg, &sc->intrhand)) { device_printf(dev, "cannot setup interrupt handler\n"); return (ENXIO); } return (0); } static uint32_t rk_i2s_dai_set_chanformat(device_t dev, uint32_t format) { return (0); } static int rk_i2s_dai_set_sysclk(device_t dev, unsigned int rate, int dai_dir) { struct rk_i2s_softc *sc; int error; sc = device_get_softc(dev); error = clk_disable(sc->clk); if (error != 0) { device_printf(sc->dev, "could not disable i2s_clk clock\n"); return (error); } error = clk_set_freq(sc->clk, rate, CLK_SET_ROUND_DOWN); if (error != 0) device_printf(sc->dev, "could not set i2s_clk freq\n"); error = clk_enable(sc->clk); if (error != 0) { device_printf(sc->dev, "could not enable i2s_clk clock\n"); return (error); } return (0); } static uint32_t rk_i2s_dai_set_chanspeed(device_t dev, uint32_t speed) { struct rk_i2s_softc *sc; int error; uint32_t val; uint32_t bus_clock_div, lr_clock_div; uint64_t bus_clk_freq; uint64_t clk_freq; sc = device_get_softc(dev); /* Set format */ val = RK_I2S_READ_4(sc, I2S_CKR); if ((val & I2S_CKR_MSS_SLAVE) == 0) { error = clk_get_freq(sc->clk, &clk_freq); if (error != 0) { device_printf(sc->dev, "failed to get clk frequency: err=%d\n", error); return (error); } bus_clk_freq = 2 * 32 * speed; bus_clock_div = DIV_ROUND_CLOSEST(clk_freq, bus_clk_freq); lr_clock_div = bus_clk_freq / speed; val &= ~(I2S_CKR_MDIV_MASK | I2S_CKR_RSD_MASK | I2S_CKR_TSD_MASK); val |= I2S_CKR_MDIV(bus_clock_div); val |= I2S_CKR_RSD(lr_clock_div); val |= I2S_CKR_TSD(lr_clock_div); RK_I2S_WRITE_4(sc, I2S_CKR, val); } return (speed); } static device_method_t rk_i2s_methods[] = { /* Device interface */ DEVMETHOD(device_probe, rk_i2s_probe), DEVMETHOD(device_attach, rk_i2s_attach), DEVMETHOD(device_detach, rk_i2s_detach), DEVMETHOD(audio_dai_init, rk_i2s_dai_init), DEVMETHOD(audio_dai_setup_intr, rk_i2s_dai_setup_intr), DEVMETHOD(audio_dai_set_sysclk, rk_i2s_dai_set_sysclk), DEVMETHOD(audio_dai_set_chanspeed, rk_i2s_dai_set_chanspeed), DEVMETHOD(audio_dai_set_chanformat, rk_i2s_dai_set_chanformat), DEVMETHOD(audio_dai_intr, rk_i2s_dai_intr), DEVMETHOD(audio_dai_get_caps, rk_i2s_dai_get_caps), DEVMETHOD(audio_dai_trigger, rk_i2s_dai_trigger), DEVMETHOD(audio_dai_get_ptr, rk_i2s_dai_get_ptr), DEVMETHOD_END }; static driver_t rk_i2s_driver = { "i2s", rk_i2s_methods, sizeof(struct rk_i2s_softc), }; DRIVER_MODULE(rk_i2s, simplebus, rk_i2s_driver, 0, 0); SIMPLEBUS_PNP_INFO(compat_data); diff --git a/sys/arm64/rockchip/rk_iodomain.c b/sys/arm64/rockchip/rk_iodomain.c index e872ee5a45ed..ed61b99481f2 100644 --- a/sys/arm64/rockchip/rk_iodomain.c +++ b/sys/arm64/rockchip/rk_iodomain.c @@ -1,301 +1,301 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2019 Emmanuel Vadot * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include #include #include #include #include #include #include -#include +#include #include #include "syscon_if.h" #define RK3288_GRF_IO_VSEL 0x380 #define RK3399_GRF_IO_VSEL 0xe640 #define RK3399_PMUGRF_SOC_CON0 0x180 #define RK3568_PMUGRF_IO_VSEL0 0x0140 #define RK3568_PMUGRF_IO_VSEL1 0x0144 #define RK3568_PMUGRF_IO_VSEL2 0x0148 #define MAX_1V8 1850000 enum rk_iodomain_type { RK3328 = 1, RK3399, RK3568, }; struct rk_iodomain_supply { char *name; uint32_t bit; }; struct rk_iodomain_softc; struct rk_iodomain_conf { struct rk_iodomain_supply *supply; int nsupply; uint32_t grf_reg; void (*init)(struct rk_iodomain_softc *sc); enum rk_iodomain_type type; }; struct rk_iodomain_softc { device_t dev; struct syscon *grf; phandle_t node; struct rk_iodomain_conf *conf; }; static struct rk_iodomain_supply rk3288_supply[] = { {"lcdc-supply", 0}, {"dvp-supply", 1}, {"flash0-supply", 2}, {"flash1-supply", 3}, {"wifi-supply", 4}, {"bb-supply", 5}, {"audio-supply", 6}, {"sdcard-supply", 7}, {"gpio30-supply", 8}, {"gpio1830-supply", 9}, }; static struct rk_iodomain_conf rk3288_conf = { .supply = rk3288_supply, .nsupply = nitems(rk3288_supply), .grf_reg = RK3288_GRF_IO_VSEL, .type = RK3328, }; static struct rk_iodomain_supply rk3399_supply[] = { {"bt656-supply", 0}, {"audio-supply", 1}, {"sdmmc-supply", 2}, {"gpio1830-supply", 3}, }; static struct rk_iodomain_conf rk3399_conf = { .supply = rk3399_supply, .nsupply = nitems(rk3399_supply), .grf_reg = RK3399_GRF_IO_VSEL, .type = RK3399, }; static struct rk_iodomain_supply rk3399_pmu_supply[] = { {"pmu1830-supply", 9}, }; static void rk3399_pmu_init(struct rk_iodomain_softc *sc); static struct rk_iodomain_conf rk3399_pmu_conf = { .supply = rk3399_pmu_supply, .nsupply = nitems(rk3399_pmu_supply), .grf_reg = RK3399_PMUGRF_SOC_CON0, .init = rk3399_pmu_init, .type = RK3399, }; static struct rk_iodomain_supply rk3568_pmu_supply[] = { {"pmuio1-supply", 0}, {"pmuio2-supply", 1}, {"vccio1-supply", 1}, {"vccio2-supply", 2}, {"vccio3-supply", 3}, {"vccio4-supply", 4}, {"vccio5-supply", 5}, {"vccio6-supply", 6}, {"vccio7-supply", 7}, }; static struct rk_iodomain_conf rk3568_pmu_conf = { .supply = rk3568_pmu_supply, .nsupply = nitems(rk3568_pmu_supply), .type = RK3568, }; static struct ofw_compat_data compat_data[] = { {"rockchip,rk3288-io-voltage-domain", (uintptr_t)&rk3288_conf}, {"rockchip,rk3399-io-voltage-domain", (uintptr_t)&rk3399_conf}, {"rockchip,rk3399-pmu-io-voltage-domain", (uintptr_t)&rk3399_pmu_conf}, {"rockchip,rk3568-pmu-io-voltage-domain", (uintptr_t)&rk3568_pmu_conf}, {NULL, 0} }; static void rk3399_pmu_init(struct rk_iodomain_softc *sc) { SYSCON_WRITE_4(sc->grf, RK3399_PMUGRF_SOC_CON0, (1 << 8) | (1 << (8 + 16))); /* set pmu1830_volsel */ } static int rk_iodomain_set(struct rk_iodomain_softc *sc) { regulator_t supply; uint32_t reg = 0; uint32_t mask = 0; int uvolt, i; for (i = 0; i < sc->conf->nsupply; i++) { if (regulator_get_by_ofw_property(sc->dev, sc->node, sc->conf->supply[i].name, &supply) != 0) { device_printf(sc->dev, "Cannot get property for regulator %s\n", sc->conf->supply[i].name); return (ENXIO); } if (regulator_get_voltage(supply, &uvolt) != 0) { device_printf(sc->dev, "Cannot get current voltage for regulator %s\n", sc->conf->supply[i].name); return (ENXIO); } if (sc->conf->type != RK3568) { /* RK3328 and RK3399 iodomain */ mask |= (1 << sc->conf->supply[i].bit) << 16; if (uvolt == 1800000) reg |= (1 << sc->conf->supply[i].bit); else if (uvolt != 3000000) device_printf(sc->dev, "%s regulator is at %duV, ignoring\n", sc->conf->supply[i].name, uvolt); } else { /* RK3568 iodomain */ if (bootverbose) { device_printf(sc->dev, "Setting regulator %s voltage=%duV\n", sc->conf->supply[i].name, uvolt); } switch(i) { case 0: /* pmuio1 */ break; case 1: /* pmuio2 */ SYSCON_WRITE_4(sc->grf, RK3568_PMUGRF_IO_VSEL2, (1 << (sc->conf->supply[i].bit + 16)) | (uvolt > MAX_1V8 ? 0 : 1 << sc->conf->supply[i].bit)); SYSCON_WRITE_4(sc->grf, RK3568_PMUGRF_IO_VSEL2, (1 << (sc->conf->supply[i].bit + 4 + 16)) | (uvolt > MAX_1V8 ? 1 << (sc->conf->supply[i].bit + 4) : 0)); case 3: /* vccio2 */ break; case 2: /* vccio1 */ case 4: /* vccio3 */ case 5: /* vccio4 */ case 6: /* vccio5 */ case 7: /* vccio6 */ case 8: /* vccio7 */ SYSCON_WRITE_4(sc->grf, RK3568_PMUGRF_IO_VSEL0, (1 << (sc->conf->supply[i].bit + 16)) | (uvolt > MAX_1V8 ? 0 : 1 << sc->conf->supply[i].bit)); SYSCON_WRITE_4(sc->grf, RK3568_PMUGRF_IO_VSEL1, (1 << (sc->conf->supply[i].bit + 16)) | (uvolt > MAX_1V8 ? 1 << sc->conf->supply[i].bit : 0)); break; default: device_printf(sc->dev, "Index out of range\n"); } } } if (sc->conf->type != RK3568) SYSCON_WRITE_4(sc->grf, sc->conf->grf_reg, reg | mask); if (sc->conf->init != NULL) sc->conf->init(sc); return (0); } static int rk_iodomain_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "RockChip IO Voltage Domain"); return (BUS_PROBE_DEFAULT); } static int rk_iodomain_attach(device_t dev) { struct rk_iodomain_softc *sc; int rv; sc = device_get_softc(dev); sc->dev = dev; sc->node = ofw_bus_get_node(dev); rv = syscon_get_handle_default(dev, &sc->grf); if (rv != 0) { device_printf(dev, "Cannot get grf handle\n"); return (ENXIO); } sc->conf = (struct rk_iodomain_conf *)ofw_bus_search_compatible(dev, compat_data)->ocd_data; rv = rk_iodomain_set(sc); return (rv); } static int rk_iodomain_detach(device_t dev) { return (0); } static device_method_t rk_iodomain_methods[] = { /* Device interface */ DEVMETHOD(device_probe, rk_iodomain_probe), DEVMETHOD(device_attach, rk_iodomain_attach), DEVMETHOD(device_detach, rk_iodomain_detach), DEVMETHOD_END }; static driver_t rk_iodomain_driver = { "rk_iodomain", rk_iodomain_methods, sizeof(struct rk_iodomain_softc), }; EARLY_DRIVER_MODULE(rk_iodomain, simplebus, rk_iodomain_driver, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LAST); diff --git a/sys/arm64/rockchip/rk_otp.c b/sys/arm64/rockchip/rk_otp.c index 1d8191ff1f90..7b8935106534 100644 --- a/sys/arm64/rockchip/rk_otp.c +++ b/sys/arm64/rockchip/rk_otp.c @@ -1,191 +1,191 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2022 Soren Schmidt * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include -#include +#include #include #include "rk_otp.h" #include "rk_otp_if.h" #define OTPC_SBPI_CTRL 0x0020 #define SBPI_ENABLE_MASK 0x00010000 #define SBPI_ENABLE 1 #define SBPI_DAP_ADDR_MASK 0xff000000 #define SBPI_DAP_ADDR 0x02 #define SBPI_DAP_ADDR_SHIFT 8 #define OTPC_SBPI_CMD_VALID_PRE 0x0024 #define SBPI_CMD_VALID_MASK 0xffff0000 #define OTPC_SBPI_INT_STATUS 0x0304 #define OTPC_SBPI_DONE 2 #define OTPC_USER_DONE 4 #define OTPC_USER_CTRL 0x0100 #define OTPC_USER_MASK 0xffff0000 #define OTPC_USER 1 #define OTPC_USER_ADDR 0x0104 #define OTPC_USER_ADDR_MASK 0xffff0000 #define OTPC_USER_ENABLE 0x0108 #define OTPC_USER_FSM_ENABLE_MASK 0xffff0000 #define OTPC_USER_FSM_ENABLE 1 #define OTPC_USER_Q 0x0124 #define OTPC_SBPI_CMD0_OFFSET 0x1000 #define SBPI_DAP_CMD_WRF 0xc0 #define SBPI_DAP_REG_ECC 0x3a #define OTPC_SBPI_CMD1_OFFSET 0x1004 #define SBPI_ECC_ENABLE 0x00 #define SBPI_ECC_DISABLE 0x09 static struct ofw_compat_data compat_data[] = { {"rockchip,rk3568-otp", 1}, {NULL, 0} }; static struct rk_otp_softc { struct resource *mem; } rk_otp_sc; static int rk_otp_wait(struct rk_otp_softc *sc, uint32_t status) { int retry = 10000; while (!(bus_read_4(sc->mem, OTPC_SBPI_INT_STATUS) & status)) { DELAY(10); if (--retry == 0) return (ETIMEDOUT); } /* clear status */ bus_write_4(sc->mem, OTPC_SBPI_INT_STATUS, status); return (0); } static int rk_otp_ecc(struct rk_otp_softc *sc, int enable) { bus_write_4(sc->mem, OTPC_SBPI_CTRL, SBPI_DAP_ADDR_MASK | (SBPI_DAP_ADDR << SBPI_DAP_ADDR_SHIFT)); bus_write_4(sc->mem, OTPC_SBPI_CMD_VALID_PRE, SBPI_CMD_VALID_MASK | 0x1); bus_write_4(sc->mem, OTPC_SBPI_CMD0_OFFSET, SBPI_DAP_CMD_WRF | SBPI_DAP_REG_ECC); if (enable) bus_write_4(sc->mem, OTPC_SBPI_CMD1_OFFSET, SBPI_ECC_ENABLE); else bus_write_4(sc->mem, OTPC_SBPI_CMD1_OFFSET, SBPI_ECC_DISABLE); bus_write_4(sc->mem, OTPC_SBPI_CTRL, SBPI_ENABLE_MASK | SBPI_ENABLE); return (rk_otp_wait(sc, OTPC_SBPI_DONE)); } int rk_otp_read(device_t dev, uint8_t *buffer, int offset, int size) { struct rk_otp_softc *sc = &rk_otp_sc; int error; /* if not initialized just error out */ if (!sc->mem) return (ENXIO); if ((error = rk_otp_ecc(sc, 1))) { device_printf(dev, "timeout waiting for OTP ECC status\n"); return (error); } bus_write_4(sc->mem, OTPC_USER_CTRL, OTPC_USER | OTPC_USER_MASK); DELAY(5); while (size--) { bus_write_4(sc->mem, OTPC_USER_ADDR, offset++ | OTPC_USER_ADDR_MASK); bus_write_4(sc->mem, OTPC_USER_ENABLE, OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK); if ((error = rk_otp_wait(sc, OTPC_USER_DONE))) { device_printf(dev, "timeout waiting for OTP data\n"); break; } *buffer++ = bus_read_4(sc->mem, OTPC_USER_Q); } bus_write_4(sc->mem, OTPC_USER_CTRL, OTPC_USER_MASK); return (error); } static int rk_otp_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "RockChip OTP"); return (BUS_PROBE_DEFAULT); } static int rk_otp_attach(device_t dev) { struct rk_otp_softc *sc = &rk_otp_sc; int rid = 0; sc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (!sc->mem) { device_printf(dev, "Cannot allocate memory resources\n"); return (ENXIO); } return (0); } static device_method_t rk_otp_methods[] = { /* Device interface */ DEVMETHOD(device_probe, rk_otp_probe), DEVMETHOD(device_attach, rk_otp_attach), DEVMETHOD_END }; DEFINE_CLASS_1(rk_otp, rk_otp_driver, rk_otp_methods, sizeof(struct simple_mfd_softc), simple_mfd_driver); EARLY_DRIVER_MODULE(rk_otp, simplebus, rk_otp_driver, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE); diff --git a/sys/arm64/rockchip/rk_pcie_phy.c b/sys/arm64/rockchip/rk_pcie_phy.c index 7e9077d33eb8..cfaf26e8fbb3 100644 --- a/sys/arm64/rockchip/rk_pcie_phy.c +++ b/sys/arm64/rockchip/rk_pcie_phy.c @@ -1,365 +1,365 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2019 Michal Meloun * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Rockchip PHY TYPEC */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include #include "syscon_if.h" #define GRF_HIWORD_SHIFT 16 #define GRF_SOC_CON_5_PCIE 0xE214 #define CON_5_PCIE_IDLE_OFF(x) (1 <<(((x) & 0x3) + 3)) #define GRF_SOC_CON8 0xE220 #define GRF_SOC_STATUS1 0xE2A4 /* PHY config registers - write */ #define PHY_CFG_CLK_TEST 0x10 #define CLK_TEST_SEPE_RATE (1 << 3) #define PHY_CFG_CLK_SCC 0x12 #define CLK_SCC_PLL_100M (1 << 3) /* PHY config registers - read */ #define PHY_CFG_PLL_LOCK 0x10 #define CLK_PLL_LOCKED (1 << 1) #define PHY_CFG_SCC_LOCK 0x12 #define CLK_SCC_100M_GATE (1 << 2) #define STATUS1_PLL_LOCKED (1 << 9) static struct ofw_compat_data compat_data[] = { {"rockchip,rk3399-pcie-phy", 1}, {NULL, 0} }; struct rk_pcie_phy_softc { device_t dev; struct syscon *syscon; struct mtx mtx; clk_t clk_ref; hwreset_t hwreset_phy; int enable_count; }; #define PHY_LOCK(_sc) mtx_lock(&(_sc)->mtx) #define PHY_UNLOCK(_sc) mtx_unlock(&(_sc)->mtx) #define PHY_LOCK_INIT(_sc) mtx_init(&(_sc)->mtx, \ device_get_nameunit(_sc->dev), "rk_pcie_phyc", MTX_DEF) #define PHY_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->mtx); #define PHY_ASSERT_LOCKED(_sc) mtx_assert(&(_sc)->mtx, MA_OWNED); #define PHY_ASSERT_UNLOCKED(_sc) mtx_assert(&(_sc)->mtx, MA_NOTOWNED); #define RD4(sc, reg) SYSCON_READ_4((sc)->syscon, (reg)) #define WR4(sc, reg, mask, val) \ SYSCON_WRITE_4((sc)->syscon, (reg), ((mask) << GRF_HIWORD_SHIFT) | (val)) #define MAX_LANE 4 static void cfg_write(struct rk_pcie_phy_softc *sc, uint32_t reg, uint32_t data) { /* setup register address and data first */ WR4(sc, GRF_SOC_CON8, 0x7FF, (reg & 0x3F) << 1 | (data & 0x0F) << 7); /* dummy readback for sync */ RD4(sc, GRF_SOC_CON8); /* Do write pulse */ WR4(sc, GRF_SOC_CON8, 1, 1); RD4(sc, GRF_SOC_CON8); DELAY(10); WR4(sc, GRF_SOC_CON8, 1, 0); RD4(sc, GRF_SOC_CON8); DELAY(10); } static uint32_t cfg_read(struct rk_pcie_phy_softc *sc, uint32_t reg) { uint32_t val; WR4(sc, GRF_SOC_CON8, 0x3FF, reg << 1); RD4(sc, GRF_SOC_CON8); DELAY(10); val = RD4(sc, GRF_SOC_STATUS1); return ((val >> 8) & 0x0f); } static int rk_pcie_phy_up(struct rk_pcie_phy_softc *sc, int id) { uint32_t val; int i, rv; PHY_LOCK(sc); sc->enable_count++; if (sc->enable_count != 1) { PHY_UNLOCK(sc); return (0); } rv = hwreset_deassert(sc->hwreset_phy); if (rv != 0) { device_printf(sc->dev, "Cannot deassert 'phy' reset\n"); PHY_UNLOCK(sc); return (rv); } /* Un-idle all lanes */ for (i = 0; i < MAX_LANE; i++) WR4(sc, GRF_SOC_CON_5_PCIE, CON_5_PCIE_IDLE_OFF(i), 0); /* Wait for PLL lock */ for (i = 100; i > 0; i--) { val = cfg_read(sc, PHY_CFG_PLL_LOCK); if (val & CLK_PLL_LOCKED) break; DELAY(1000); } if (i <= 0) { device_printf(sc->dev, "PLL lock timeouted, 0x%02X\n", val); PHY_UNLOCK(sc); return (ETIMEDOUT); } /* Switch PLL to stable 5GHz, rate adjustment is done by divider */ cfg_write(sc, PHY_CFG_CLK_TEST, CLK_TEST_SEPE_RATE); /* Enable 100MHz output for PCIe ref clock */ cfg_write(sc, PHY_CFG_CLK_SCC, CLK_SCC_PLL_100M); /* Wait for ungating of ref clock */ for (i = 100; i > 0; i--) { val = cfg_read(sc, PHY_CFG_SCC_LOCK); if ((val & CLK_SCC_100M_GATE) == 0) break; DELAY(1000); } if (i <= 0) { device_printf(sc->dev, "PLL output enable timeouted\n"); PHY_UNLOCK(sc); return (ETIMEDOUT); } /* Wait for PLL relock (to 5GHz) */ for (i = 100; i > 0; i--) { val = cfg_read(sc, PHY_CFG_PLL_LOCK); if (val & CLK_PLL_LOCKED) break; DELAY(1000); } if (i <= 0) { device_printf(sc->dev, "PLL relock timeouted\n"); PHY_UNLOCK(sc); return (ETIMEDOUT); } PHY_UNLOCK(sc); return (rv); } static int rk_pcie_phy_down(struct rk_pcie_phy_softc *sc, int id) { int rv; PHY_LOCK(sc); rv = 0; if (sc->enable_count <= 0) panic("unpaired enable/disable"); sc->enable_count--; /* Idle given lane */ WR4(sc, GRF_SOC_CON_5_PCIE, CON_5_PCIE_IDLE_OFF(id), CON_5_PCIE_IDLE_OFF(id)); if (sc->enable_count == 0) { rv = hwreset_assert(sc->hwreset_phy); if (rv != 0) device_printf(sc->dev, "Cannot assert 'phy' reset\n"); } PHY_UNLOCK(sc); return (rv); } static int rk_pcie_phy_enable(struct phynode *phynode, bool enable) { struct rk_pcie_phy_softc *sc; device_t dev; intptr_t phy; int rv; dev = phynode_get_device(phynode); phy = phynode_get_id(phynode); sc = device_get_softc(dev); if (enable) rv = rk_pcie_phy_up(sc, (int)phy); else rv = rk_pcie_phy_down(sc, (int) phy); return (rv); } /* Phy class and methods. */ static phynode_method_t rk_pcie_phy_phynode_methods[] = { PHYNODEMETHOD(phynode_enable, rk_pcie_phy_enable), PHYNODEMETHOD_END }; DEFINE_CLASS_1( rk_pcie_phy_phynode, rk_pcie_phy_phynode_class, rk_pcie_phy_phynode_methods, 0, phynode_class); static int rk_pcie_phy_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "Rockchip RK3399 PCIe PHY"); return (BUS_PROBE_DEFAULT); } static int rk_pcie_phy_attach(device_t dev) { struct rk_pcie_phy_softc *sc; struct phynode_init_def phy_init; struct phynode *phynode; phandle_t node; int i, rv; sc = device_get_softc(dev); sc->dev = dev; node = ofw_bus_get_node(dev); PHY_LOCK_INIT(sc); if (SYSCON_GET_HANDLE(sc->dev, &sc->syscon) != 0 || sc->syscon == NULL) { device_printf(dev, "cannot get syscon for device\n"); rv = ENXIO; goto fail; } rv = clk_set_assigned(dev, ofw_bus_get_node(dev)); if (rv != 0 && rv != ENOENT) { device_printf(dev, "clk_set_assigned failed: %d\n", rv); rv = ENXIO; goto fail; } rv = clk_get_by_ofw_name(sc->dev, 0, "refclk", &sc->clk_ref); if (rv != 0) { device_printf(sc->dev, "Cannot get 'refclk' clock\n"); rv = ENXIO; goto fail; } rv = hwreset_get_by_ofw_name(sc->dev, 0, "phy", &sc->hwreset_phy); if (rv != 0) { device_printf(sc->dev, "Cannot get 'phy' reset\n"); rv = ENXIO; goto fail; } rv = hwreset_assert(sc->hwreset_phy); if (rv != 0) { device_printf(sc->dev, "Cannot assert 'phy' reset\n"); rv = ENXIO; goto fail; } rv = clk_enable(sc->clk_ref); if (rv != 0) { device_printf(sc->dev, "Cannot enable 'ref' clock\n"); rv = ENXIO; goto fail; } for (i = 0; i < MAX_LANE; i++) { phy_init.id = i; phy_init.ofw_node = node; phynode = phynode_create(dev, &rk_pcie_phy_phynode_class, &phy_init); if (phynode == NULL) { device_printf(dev, "Cannot create phy[%d]\n", i); rv = ENXIO; goto fail; } if (phynode_register(phynode) == NULL) { device_printf(dev, "Cannot register phy[%d]\n", i); rv = ENXIO; goto fail; } } return (0); fail: return (rv); } static device_method_t rk_pcie_phy_methods[] = { /* Device interface */ DEVMETHOD(device_probe, rk_pcie_phy_probe), DEVMETHOD(device_attach, rk_pcie_phy_attach), DEVMETHOD_END }; DEFINE_CLASS_0(rk_pcie_phy, rk_pcie_phy_driver, rk_pcie_phy_methods, sizeof(struct rk_pcie_phy_softc)); EARLY_DRIVER_MODULE(rk_pcie_phy, simplebus, rk_pcie_phy_driver, NULL, NULL, BUS_PASS_SUPPORTDEV + BUS_PASS_ORDER_MIDDLE); diff --git a/sys/arm64/rockchip/rk_pinctrl.c b/sys/arm64/rockchip/rk_pinctrl.c index 1c873292b852..4892b0bf236c 100644 --- a/sys/arm64/rockchip/rk_pinctrl.c +++ b/sys/arm64/rockchip/rk_pinctrl.c @@ -1,1570 +1,1570 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2018 Emmanuel Vadot * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include "gpio_if.h" #include "syscon_if.h" #include "fdt_pinctrl_if.h" struct rk_pinctrl_pin_drive { uint32_t bank; uint32_t subbank; uint32_t offset; uint32_t value; uint32_t ma; }; struct rk_pinctrl_bank { uint32_t bank; uint32_t subbank; uint32_t offset; uint32_t nbits; }; struct rk_pinctrl_pin_fixup { uint32_t bank; uint32_t subbank; uint32_t pin; uint32_t reg; uint32_t bit; uint32_t mask; }; struct rk_pinctrl_gpio { uint32_t bank; char *gpio_name; device_t gpio_dev; }; struct rk_pinctrl_softc; struct rk_pinctrl_conf { struct rk_pinctrl_bank *iomux_conf; uint32_t iomux_nbanks; struct rk_pinctrl_pin_fixup *pin_fixup; uint32_t npin_fixup; struct rk_pinctrl_pin_drive *pin_drive; uint32_t npin_drive; struct rk_pinctrl_gpio *gpio_bank; uint32_t ngpio_bank; uint32_t (*get_pd_offset)(struct rk_pinctrl_softc *, uint32_t); struct syscon *(*get_syscon)(struct rk_pinctrl_softc *, uint32_t); int (*parse_bias)(phandle_t, int); int (*resolv_bias_value)(int, int); int (*get_bias_value)(int, int); }; struct rk_pinctrl_softc { struct simplebus_softc simplebus_sc; device_t dev; struct syscon *grf; struct syscon *pmu; struct rk_pinctrl_conf *conf; struct mtx mtx; }; #define RK_PINCTRL_LOCK(_sc) mtx_lock_spin(&(_sc)->mtx) #define RK_PINCTRL_UNLOCK(_sc) mtx_unlock_spin(&(_sc)->mtx) #define RK_PINCTRL_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->mtx, MA_OWNED) #define RK_IOMUX(_bank, _subbank, _offset, _nbits) \ { \ .bank = _bank, \ .subbank = _subbank, \ .offset = _offset, \ .nbits = _nbits, \ } #define RK_PINFIX(_bank, _pin, _reg, _bit, _mask) \ { \ .bank = _bank, \ .pin = _pin, \ .reg = _reg, \ .bit = _bit, \ .mask = _mask, \ } #define RK_PINDRIVE(_bank, _subbank, _offset, _value, _ma) \ { \ .bank = _bank, \ .subbank = _subbank, \ .offset = _offset, \ .value = _value, \ .ma = _ma, \ } #define RK_GPIO(_bank, _name) \ { \ .bank = _bank, \ .gpio_name = _name, \ } static struct rk_pinctrl_gpio rk3288_gpio_bank[] = { RK_GPIO(0, "gpio0"), RK_GPIO(1, "gpio1"), RK_GPIO(2, "gpio2"), RK_GPIO(3, "gpio3"), RK_GPIO(4, "gpio4"), RK_GPIO(5, "gpio5"), RK_GPIO(6, "gpio6"), RK_GPIO(7, "gpio7"), RK_GPIO(8, "gpio8"), }; static struct rk_pinctrl_bank rk3288_iomux_bank[] = { /* bank sub offs nbits */ /* PMU */ RK_IOMUX(0, 0, 0x0084, 2), RK_IOMUX(0, 1, 0x0088, 2), RK_IOMUX(0, 2, 0x008C, 2), /* GFR */ RK_IOMUX(1, 3, 0x000C, 2), RK_IOMUX(2, 0, 0x0010, 2), RK_IOMUX(2, 1, 0x0014, 2), RK_IOMUX(2, 2, 0x0018, 2), RK_IOMUX(2, 3, 0x001C, 2), RK_IOMUX(3, 0, 0x0020, 2), RK_IOMUX(3, 1, 0x0024, 2), RK_IOMUX(3, 2, 0x0028, 2), RK_IOMUX(3, 3, 0x002C, 4), RK_IOMUX(4, 0, 0x0034, 4), RK_IOMUX(4, 1, 0x003C, 4), RK_IOMUX(4, 2, 0x0044, 2), RK_IOMUX(4, 3, 0x0048, 2), /* 5,0 - Empty */ RK_IOMUX(5, 1, 0x0050, 2), RK_IOMUX(5, 2, 0x0054, 2), /* 5,3 - Empty */ RK_IOMUX(6, 0, 0x005C, 2), RK_IOMUX(6, 1, 0x0060, 2), RK_IOMUX(6, 2, 0x0064, 2), /* 6,3 - Empty */ RK_IOMUX(7, 0, 0x006C, 2), RK_IOMUX(7, 1, 0x0070, 2), RK_IOMUX(7, 2, 0x0074, 4), /* 7,3 - Empty */ RK_IOMUX(8, 0, 0x0080, 2), RK_IOMUX(8, 1, 0x0084, 2), /* 8,2 - Empty */ /* 8,3 - Empty */ }; static struct rk_pinctrl_pin_fixup rk3288_pin_fixup[] = { }; static struct rk_pinctrl_pin_drive rk3288_pin_drive[] = { /* bank sub offs val ma */ /* GPIO0A (PMU)*/ RK_PINDRIVE(0, 0, 0x070, 0, 2), RK_PINDRIVE(0, 0, 0x070, 1, 4), RK_PINDRIVE(0, 0, 0x070, 2, 8), RK_PINDRIVE(0, 0, 0x070, 3, 12), /* GPIO0B (PMU)*/ RK_PINDRIVE(0, 1, 0x074, 0, 2), RK_PINDRIVE(0, 1, 0x074, 1, 4), RK_PINDRIVE(0, 1, 0x074, 2, 8), RK_PINDRIVE(0, 1, 0x074, 3, 12), /* GPIO0C (PMU)*/ RK_PINDRIVE(0, 2, 0x078, 0, 2), RK_PINDRIVE(0, 2, 0x078, 1, 4), RK_PINDRIVE(0, 2, 0x078, 2, 8), RK_PINDRIVE(0, 2, 0x078, 3, 12), /* GPIO1D */ RK_PINDRIVE(1, 3, 0x1CC, 0, 2), RK_PINDRIVE(1, 3, 0x1CC, 1, 4), RK_PINDRIVE(1, 3, 0x1CC, 2, 8), RK_PINDRIVE(1, 3, 0x1CC, 3, 12), /* GPIO2A */ RK_PINDRIVE(2, 0, 0x1D0, 0, 2), RK_PINDRIVE(2, 0, 0x1D0, 1, 4), RK_PINDRIVE(2, 0, 0x1D0, 2, 8), RK_PINDRIVE(2, 0, 0x1D0, 3, 12), /* GPIO2B */ RK_PINDRIVE(2, 1, 0x1D4, 0, 2), RK_PINDRIVE(2, 1, 0x1D4, 1, 4), RK_PINDRIVE(2, 1, 0x1D4, 2, 8), RK_PINDRIVE(2, 1, 0x1D4, 3, 12), /* GPIO2C */ RK_PINDRIVE(2, 2, 0x1D8, 0, 2), RK_PINDRIVE(2, 2, 0x1D8, 1, 4), RK_PINDRIVE(2, 2, 0x1D8, 2, 8), RK_PINDRIVE(2, 2, 0x1D8, 3, 12), /* GPIO2D */ RK_PINDRIVE(2, 3, 0x1DC, 0, 2), RK_PINDRIVE(2, 3, 0x1DC, 1, 4), RK_PINDRIVE(2, 3, 0x1DC, 2, 8), RK_PINDRIVE(2, 3, 0x1DC, 3, 12), /* GPIO3A */ RK_PINDRIVE(3, 0, 0x1E0, 0, 2), RK_PINDRIVE(3, 0, 0x1E0, 1, 4), RK_PINDRIVE(3, 0, 0x1E0, 2, 8), RK_PINDRIVE(3, 0, 0x1E0, 3, 12), /* GPIO3B */ RK_PINDRIVE(3, 1, 0x1E4, 0, 2), RK_PINDRIVE(3, 1, 0x1E4, 1, 4), RK_PINDRIVE(3, 1, 0x1E4, 2, 8), RK_PINDRIVE(3, 1, 0x1E4, 3, 12), /* GPIO3C */ RK_PINDRIVE(3, 2, 0x1E8, 0, 2), RK_PINDRIVE(3, 2, 0x1E8, 1, 4), RK_PINDRIVE(3, 2, 0x1E8, 2, 8), RK_PINDRIVE(3, 2, 0x1E8, 3, 12), /* GPIO3D */ RK_PINDRIVE(3, 3, 0x1EC, 0, 2), RK_PINDRIVE(3, 3, 0x1EC, 1, 4), RK_PINDRIVE(3, 3, 0x1EC, 2, 8), RK_PINDRIVE(3, 3, 0x1EC, 3, 12), /* GPIO4A */ RK_PINDRIVE(4, 0, 0x1F0, 0, 2), RK_PINDRIVE(4, 0, 0x1F0, 1, 4), RK_PINDRIVE(4, 0, 0x1F0, 2, 8), RK_PINDRIVE(4, 0, 0x1F0, 3, 12), /* GPIO4B */ RK_PINDRIVE(4, 1, 0x1F4, 0, 2), RK_PINDRIVE(4, 1, 0x1F4, 1, 4), RK_PINDRIVE(4, 1, 0x1F4, 2, 8), RK_PINDRIVE(4, 1, 0x1F4, 3, 12), /* GPIO4C */ RK_PINDRIVE(4, 2, 0x1F8, 0, 2), RK_PINDRIVE(4, 2, 0x1F8, 1, 4), RK_PINDRIVE(4, 2, 0x1F8, 2, 8), RK_PINDRIVE(4, 2, 0x1F8, 3, 12), /* GPIO4D */ RK_PINDRIVE(4, 3, 0x1FC, 0, 2), RK_PINDRIVE(4, 3, 0x1FC, 1, 4), RK_PINDRIVE(4, 3, 0x1FC, 2, 8), RK_PINDRIVE(4, 3, 0x1FC, 3, 12), /* GPIO5B */ RK_PINDRIVE(5, 1, 0x204, 0, 2), RK_PINDRIVE(5, 1, 0x204, 1, 4), RK_PINDRIVE(5, 1, 0x204, 2, 8), RK_PINDRIVE(5, 1, 0x204, 3, 12), /* GPIO5C */ RK_PINDRIVE(5, 2, 0x208, 0, 2), RK_PINDRIVE(5, 2, 0x208, 1, 4), RK_PINDRIVE(5, 2, 0x208, 2, 8), RK_PINDRIVE(5, 2, 0x208, 3, 12), /* GPIO6A */ RK_PINDRIVE(6, 0, 0x210, 0, 2), RK_PINDRIVE(6, 0, 0x210, 1, 4), RK_PINDRIVE(6, 0, 0x210, 2, 8), RK_PINDRIVE(6, 0, 0x210, 3, 12), /* GPIO6B */ RK_PINDRIVE(6, 1, 0x214, 0, 2), RK_PINDRIVE(6, 1, 0x214, 1, 4), RK_PINDRIVE(6, 1, 0x214, 2, 8), RK_PINDRIVE(6, 1, 0x214, 3, 12), /* GPIO6C */ RK_PINDRIVE(6, 2, 0x218, 0, 2), RK_PINDRIVE(6, 2, 0x218, 1, 4), RK_PINDRIVE(6, 2, 0x218, 2, 8), RK_PINDRIVE(6, 2, 0x218, 3, 12), /* GPIO7A */ RK_PINDRIVE(7, 0, 0x220, 0, 2), RK_PINDRIVE(7, 0, 0x220, 1, 4), RK_PINDRIVE(7, 0, 0x220, 2, 8), RK_PINDRIVE(7, 0, 0x220, 3, 12), /* GPIO7B */ RK_PINDRIVE(7, 1, 0x224, 0, 2), RK_PINDRIVE(7, 1, 0x224, 1, 4), RK_PINDRIVE(7, 1, 0x224, 2, 8), RK_PINDRIVE(7, 1, 0x224, 3, 12), /* GPIO7C */ RK_PINDRIVE(7, 2, 0x228, 0, 2), RK_PINDRIVE(7, 2, 0x228, 1, 4), RK_PINDRIVE(7, 2, 0x228, 2, 8), RK_PINDRIVE(7, 2, 0x228, 3, 12), /* GPIO8A */ RK_PINDRIVE(8, 0, 0x230, 0, 2), RK_PINDRIVE(8, 0, 0x230, 1, 4), RK_PINDRIVE(8, 0, 0x230, 2, 8), RK_PINDRIVE(8, 0, 0x230, 3, 12), /* GPIO8B */ RK_PINDRIVE(8, 1, 0x234, 0, 2), RK_PINDRIVE(8, 1, 0x234, 1, 4), RK_PINDRIVE(8, 1, 0x234, 2, 8), RK_PINDRIVE(8, 1, 0x234, 3, 12), }; static uint32_t rk3288_get_pd_offset(struct rk_pinctrl_softc *sc, uint32_t bank) { if (bank == 0) return (0x064); /* PMU */ return (0x130); } static struct syscon * rk3288_get_syscon(struct rk_pinctrl_softc *sc, uint32_t bank) { if (bank == 0) return (sc->pmu); return (sc->grf); } static int rk3288_parse_bias(phandle_t node, int bank) { if (OF_hasprop(node, "bias-disable")) return (0); if (OF_hasprop(node, "bias-pull-up")) return (1); if (OF_hasprop(node, "bias-pull-down")) return (2); return (-1); } static int rk3288_resolv_bias_value(int bank, int bias) { int rv = 0; if (bias == 1) rv = GPIO_PIN_PULLUP; else if (bias == 2) rv = GPIO_PIN_PULLDOWN; return (rv); } static int rk3288_get_bias_value(int bank, int bias) { int rv = 0; if (bias & GPIO_PIN_PULLUP) rv = 1; else if (bias & GPIO_PIN_PULLDOWN) rv = 2; return (rv); } struct rk_pinctrl_conf rk3288_conf = { .iomux_conf = rk3288_iomux_bank, .iomux_nbanks = nitems(rk3288_iomux_bank), .pin_fixup = rk3288_pin_fixup, .npin_fixup = nitems(rk3288_pin_fixup), .pin_drive = rk3288_pin_drive, .npin_drive = nitems(rk3288_pin_drive), .gpio_bank = rk3288_gpio_bank, .ngpio_bank = nitems(rk3288_gpio_bank), .get_pd_offset = rk3288_get_pd_offset, .get_syscon = rk3288_get_syscon, .parse_bias = rk3288_parse_bias, .resolv_bias_value = rk3288_resolv_bias_value, .get_bias_value = rk3288_get_bias_value, }; static struct rk_pinctrl_gpio rk3328_gpio_bank[] = { RK_GPIO(0, "gpio0"), RK_GPIO(1, "gpio1"), RK_GPIO(2, "gpio2"), RK_GPIO(3, "gpio3"), }; static struct rk_pinctrl_bank rk3328_iomux_bank[] = { /* bank sub offs nbits */ RK_IOMUX(0, 0, 0x0000, 2), RK_IOMUX(0, 1, 0x0004, 2), RK_IOMUX(0, 2, 0x0008, 2), RK_IOMUX(0, 3, 0x000C, 2), RK_IOMUX(1, 0, 0x0010, 2), RK_IOMUX(1, 1, 0x0014, 2), RK_IOMUX(1, 2, 0x0018, 2), RK_IOMUX(1, 3, 0x001C, 2), RK_IOMUX(2, 0, 0x0020, 2), RK_IOMUX(2, 1, 0x0024, 3), RK_IOMUX(2, 2, 0x002c, 3), RK_IOMUX(2, 3, 0x0034, 2), RK_IOMUX(3, 0, 0x0038, 3), RK_IOMUX(3, 1, 0x0040, 3), RK_IOMUX(3, 2, 0x0048, 2), RK_IOMUX(3, 3, 0x004c, 2), }; static struct rk_pinctrl_pin_fixup rk3328_pin_fixup[] = { /* bank pin reg bit mask */ RK_PINFIX(2, 12, 0x24, 8, 0x300), RK_PINFIX(2, 15, 0x28, 0, 0x7), RK_PINFIX(2, 23, 0x30, 14, 0x6000), }; static struct rk_pinctrl_pin_drive rk3328_pin_drive[] = { /* bank sub offs val ma */ RK_PINDRIVE(0, 0, 0x200, 0, 2), RK_PINDRIVE(0, 0, 0x200, 1, 4), RK_PINDRIVE(0, 0, 0x200, 2, 8), RK_PINDRIVE(0, 0, 0x200, 3, 12), RK_PINDRIVE(0, 1, 0x204, 0, 2), RK_PINDRIVE(0, 1, 0x204, 1, 4), RK_PINDRIVE(0, 1, 0x204, 2, 8), RK_PINDRIVE(0, 1, 0x204, 3, 12), RK_PINDRIVE(0, 2, 0x208, 0, 2), RK_PINDRIVE(0, 2, 0x208, 1, 4), RK_PINDRIVE(0, 2, 0x208, 2, 8), RK_PINDRIVE(0, 2, 0x208, 3, 12), RK_PINDRIVE(0, 3, 0x20C, 0, 2), RK_PINDRIVE(0, 3, 0x20C, 1, 4), RK_PINDRIVE(0, 3, 0x20C, 2, 8), RK_PINDRIVE(0, 3, 0x20C, 3, 12), RK_PINDRIVE(1, 0, 0x210, 0, 2), RK_PINDRIVE(1, 0, 0x210, 1, 4), RK_PINDRIVE(1, 0, 0x210, 2, 8), RK_PINDRIVE(1, 0, 0x210, 3, 12), RK_PINDRIVE(1, 1, 0x214, 0, 2), RK_PINDRIVE(1, 1, 0x214, 1, 4), RK_PINDRIVE(1, 1, 0x214, 2, 8), RK_PINDRIVE(1, 1, 0x214, 3, 12), RK_PINDRIVE(1, 2, 0x218, 0, 2), RK_PINDRIVE(1, 2, 0x218, 1, 4), RK_PINDRIVE(1, 2, 0x218, 2, 8), RK_PINDRIVE(1, 2, 0x218, 3, 12), RK_PINDRIVE(1, 3, 0x21C, 0, 2), RK_PINDRIVE(1, 3, 0x21C, 1, 4), RK_PINDRIVE(1, 3, 0x21C, 2, 8), RK_PINDRIVE(1, 3, 0x21C, 3, 12), RK_PINDRIVE(2, 0, 0x220, 0, 2), RK_PINDRIVE(2, 0, 0x220, 1, 4), RK_PINDRIVE(2, 0, 0x220, 2, 8), RK_PINDRIVE(2, 0, 0x220, 3, 12), RK_PINDRIVE(2, 1, 0x224, 0, 2), RK_PINDRIVE(2, 1, 0x224, 1, 4), RK_PINDRIVE(2, 1, 0x224, 2, 8), RK_PINDRIVE(2, 1, 0x224, 3, 12), RK_PINDRIVE(2, 2, 0x228, 0, 2), RK_PINDRIVE(2, 2, 0x228, 1, 4), RK_PINDRIVE(2, 2, 0x228, 2, 8), RK_PINDRIVE(2, 2, 0x228, 3, 12), RK_PINDRIVE(2, 3, 0x22C, 0, 2), RK_PINDRIVE(2, 3, 0x22C, 1, 4), RK_PINDRIVE(2, 3, 0x22C, 2, 8), RK_PINDRIVE(2, 3, 0x22C, 3, 12), RK_PINDRIVE(3, 0, 0x230, 0, 2), RK_PINDRIVE(3, 0, 0x230, 1, 4), RK_PINDRIVE(3, 0, 0x230, 2, 8), RK_PINDRIVE(3, 0, 0x230, 3, 12), RK_PINDRIVE(3, 1, 0x234, 0, 2), RK_PINDRIVE(3, 1, 0x234, 1, 4), RK_PINDRIVE(3, 1, 0x234, 2, 8), RK_PINDRIVE(3, 1, 0x234, 3, 12), RK_PINDRIVE(3, 2, 0x238, 0, 2), RK_PINDRIVE(3, 2, 0x238, 1, 4), RK_PINDRIVE(3, 2, 0x238, 2, 8), RK_PINDRIVE(3, 2, 0x238, 3, 12), RK_PINDRIVE(3, 3, 0x23C, 0, 2), RK_PINDRIVE(3, 3, 0x23C, 1, 4), RK_PINDRIVE(3, 3, 0x23C, 2, 8), RK_PINDRIVE(3, 3, 0x23C, 3, 12), }; static uint32_t rk3328_get_pd_offset(struct rk_pinctrl_softc *sc, uint32_t bank) { return (0x100); } static struct syscon * rk3328_get_syscon(struct rk_pinctrl_softc *sc, uint32_t bank) { return (sc->grf); } struct rk_pinctrl_conf rk3328_conf = { .iomux_conf = rk3328_iomux_bank, .iomux_nbanks = nitems(rk3328_iomux_bank), .pin_fixup = rk3328_pin_fixup, .npin_fixup = nitems(rk3328_pin_fixup), .pin_drive = rk3328_pin_drive, .npin_drive = nitems(rk3328_pin_drive), .gpio_bank = rk3328_gpio_bank, .ngpio_bank = nitems(rk3328_gpio_bank), .get_pd_offset = rk3328_get_pd_offset, .get_syscon = rk3328_get_syscon, .parse_bias = rk3288_parse_bias, .resolv_bias_value = rk3288_resolv_bias_value, .get_bias_value = rk3288_get_bias_value, }; static struct rk_pinctrl_gpio rk3399_gpio_bank[] = { RK_GPIO(0, "gpio0"), RK_GPIO(1, "gpio1"), RK_GPIO(2, "gpio2"), RK_GPIO(3, "gpio3"), RK_GPIO(4, "gpio4"), }; static struct rk_pinctrl_bank rk3399_iomux_bank[] = { /* bank sub offs nbits */ RK_IOMUX(0, 0, 0x0000, 2), RK_IOMUX(0, 1, 0x0004, 2), RK_IOMUX(0, 2, 0x0008, 2), RK_IOMUX(0, 3, 0x000C, 2), RK_IOMUX(1, 0, 0x0010, 2), RK_IOMUX(1, 1, 0x0014, 2), RK_IOMUX(1, 2, 0x0018, 2), RK_IOMUX(1, 3, 0x001C, 2), RK_IOMUX(2, 0, 0xE000, 2), RK_IOMUX(2, 1, 0xE004, 2), RK_IOMUX(2, 2, 0xE008, 2), RK_IOMUX(2, 3, 0xE00C, 2), RK_IOMUX(3, 0, 0xE010, 2), RK_IOMUX(3, 1, 0xE014, 2), RK_IOMUX(3, 2, 0xE018, 2), RK_IOMUX(3, 3, 0xE01C, 2), RK_IOMUX(4, 0, 0xE020, 2), RK_IOMUX(4, 1, 0xE024, 2), RK_IOMUX(4, 2, 0xE028, 2), RK_IOMUX(4, 3, 0xE02C, 2), }; static struct rk_pinctrl_pin_fixup rk3399_pin_fixup[] = {}; static struct rk_pinctrl_pin_drive rk3399_pin_drive[] = { /* bank sub offs val ma */ /* GPIO0A */ RK_PINDRIVE(0, 0, 0x80, 0, 5), RK_PINDRIVE(0, 0, 0x80, 1, 10), RK_PINDRIVE(0, 0, 0x80, 2, 15), RK_PINDRIVE(0, 0, 0x80, 3, 20), /* GPIOB */ RK_PINDRIVE(0, 1, 0x88, 0, 5), RK_PINDRIVE(0, 1, 0x88, 1, 10), RK_PINDRIVE(0, 1, 0x88, 2, 15), RK_PINDRIVE(0, 1, 0x88, 3, 20), /* GPIO1A */ RK_PINDRIVE(1, 0, 0xA0, 0, 3), RK_PINDRIVE(1, 0, 0xA0, 1, 6), RK_PINDRIVE(1, 0, 0xA0, 2, 9), RK_PINDRIVE(1, 0, 0xA0, 3, 12), /* GPIO1B */ RK_PINDRIVE(1, 1, 0xA8, 0, 3), RK_PINDRIVE(1, 1, 0xA8, 1, 6), RK_PINDRIVE(1, 1, 0xA8, 2, 9), RK_PINDRIVE(1, 1, 0xA8, 3, 12), /* GPIO1C */ RK_PINDRIVE(1, 2, 0xB0, 0, 3), RK_PINDRIVE(1, 2, 0xB0, 1, 6), RK_PINDRIVE(1, 2, 0xB0, 2, 9), RK_PINDRIVE(1, 2, 0xB0, 3, 12), /* GPIO1D */ RK_PINDRIVE(1, 3, 0xB8, 0, 3), RK_PINDRIVE(1, 3, 0xB8, 1, 6), RK_PINDRIVE(1, 3, 0xB8, 2, 9), RK_PINDRIVE(1, 3, 0xB8, 3, 12), }; static uint32_t rk3399_get_pd_offset(struct rk_pinctrl_softc *sc, uint32_t bank) { if (bank < 2) return (0x40); return (0xE040); } static struct syscon * rk3399_get_syscon(struct rk_pinctrl_softc *sc, uint32_t bank) { if (bank < 2) return (sc->pmu); return (sc->grf); } static int rk3399_parse_bias(phandle_t node, int bank) { int pullup, pulldown; if (OF_hasprop(node, "bias-disable")) return (0); switch (bank) { case 0: case 2: pullup = 3; pulldown = 1; break; case 1: case 3: case 4: pullup = 1; pulldown = 2; break; } if (OF_hasprop(node, "bias-pull-up")) return (pullup); if (OF_hasprop(node, "bias-pull-down")) return (pulldown); return (-1); } static int rk3399_resolv_bias_value(int bank, int bias) { int rv = 0; switch (bank) { case 0: case 2: if (bias == 3) rv = GPIO_PIN_PULLUP; else if (bias == 1) rv = GPIO_PIN_PULLDOWN; break; case 1: case 3: case 4: if (bias == 1) rv = GPIO_PIN_PULLUP; else if (bias == 2) rv = GPIO_PIN_PULLDOWN; break; } return (rv); } static int rk3399_get_bias_value(int bank, int bias) { int rv = 0; switch (bank) { case 0: case 2: if (bias & GPIO_PIN_PULLUP) rv = 3; else if (bias & GPIO_PIN_PULLDOWN) rv = 1; break; case 1: case 3: case 4: if (bias & GPIO_PIN_PULLUP) rv = 1; else if (bias & GPIO_PIN_PULLDOWN) rv = 2; break; } return (rv); } struct rk_pinctrl_conf rk3399_conf = { .iomux_conf = rk3399_iomux_bank, .iomux_nbanks = nitems(rk3399_iomux_bank), .pin_fixup = rk3399_pin_fixup, .npin_fixup = nitems(rk3399_pin_fixup), .pin_drive = rk3399_pin_drive, .npin_drive = nitems(rk3399_pin_drive), .gpio_bank = rk3399_gpio_bank, .ngpio_bank = nitems(rk3399_gpio_bank), .get_pd_offset = rk3399_get_pd_offset, .get_syscon = rk3399_get_syscon, .parse_bias = rk3399_parse_bias, .resolv_bias_value = rk3399_resolv_bias_value, .get_bias_value = rk3399_get_bias_value, }; #define GRF_IOFUNC_SEL0 0x0300 #define GMAC1_IOMUX_SEL_M0 0x01000000 #define GMAC1_IOMUX_SEL_M1 0x01000100 static struct rk_pinctrl_gpio rk3568_gpio_bank[] = { RK_GPIO(0, "gpio0"), RK_GPIO(1, "gpio1"), RK_GPIO(2, "gpio2"), RK_GPIO(3, "gpio3"), RK_GPIO(4, "gpio4"), }; static struct rk_pinctrl_bank rk3568_iomux_bank[] = { /* bank sub offs nbits */ RK_IOMUX(0, 0, 0x0000, 4), /* PMU_GRF */ RK_IOMUX(0, 1, 0x0008, 4), RK_IOMUX(0, 2, 0x0010, 4), RK_IOMUX(0, 3, 0x0018, 4), RK_IOMUX(1, 0, 0x0000, 4), /* SYS_GRF */ RK_IOMUX(1, 1, 0x0008, 4), RK_IOMUX(1, 2, 0x0010, 4), RK_IOMUX(1, 3, 0x0018, 4), RK_IOMUX(2, 0, 0x0020, 4), RK_IOMUX(2, 1, 0x0028, 4), RK_IOMUX(2, 2, 0x0030, 4), RK_IOMUX(2, 3, 0x0038, 4), RK_IOMUX(3, 0, 0x0040, 4), RK_IOMUX(3, 1, 0x0048, 4), RK_IOMUX(3, 2, 0x0050, 4), RK_IOMUX(3, 3, 0x0058, 4), RK_IOMUX(4, 0, 0x0060, 4), RK_IOMUX(4, 1, 0x0068, 4), RK_IOMUX(4, 2, 0x0070, 4), RK_IOMUX(4, 3, 0x0078, 4), }; static struct rk_pinctrl_pin_fixup rk3568_pin_fixup[] = {}; static struct rk_pinctrl_pin_drive rk3568_pin_drive[] = { /* bank sub offs val ma */ /* GPIO0A */ RK_PINDRIVE(0, 0, 0x0020, 0, 2), RK_PINDRIVE(0, 0, 0x0020, 1, 4), RK_PINDRIVE(0, 0, 0x0020, 2, 8), RK_PINDRIVE(0, 0, 0x0020, 3, 12), /* GPIO0B */ RK_PINDRIVE(0, 1, 0x0024, 0, 2), RK_PINDRIVE(0, 1, 0x0024, 1, 4), RK_PINDRIVE(0, 1, 0x0024, 2, 8), RK_PINDRIVE(0, 1, 0x0024, 3, 12), /* GPIO0C */ RK_PINDRIVE(0, 1, 0x0028, 0, 2), RK_PINDRIVE(0, 1, 0x0028, 1, 4), RK_PINDRIVE(0, 1, 0x0028, 2, 8), RK_PINDRIVE(0, 1, 0x0028, 3, 12), /* GPIO0D */ RK_PINDRIVE(0, 1, 0x002c, 0, 2), RK_PINDRIVE(0, 1, 0x002c, 1, 4), RK_PINDRIVE(0, 1, 0x002c, 2, 8), RK_PINDRIVE(0, 1, 0x002c, 3, 12), /* GPIO1A */ RK_PINDRIVE(1, 0, 0x0080, 0, 2), RK_PINDRIVE(1, 0, 0x0080, 1, 4), RK_PINDRIVE(1, 0, 0x0080, 2, 8), RK_PINDRIVE(1, 0, 0x0080, 3, 12), /* GPIO1B */ RK_PINDRIVE(1, 1, 0x0084, 0, 2), RK_PINDRIVE(1, 1, 0x0084, 1, 4), RK_PINDRIVE(1, 1, 0x0084, 2, 8), RK_PINDRIVE(1, 1, 0x0084, 3, 12), /* GPIO1C */ RK_PINDRIVE(1, 2, 0x0088, 0, 2), RK_PINDRIVE(1, 2, 0x0088, 1, 4), RK_PINDRIVE(1, 2, 0x0088, 2, 8), RK_PINDRIVE(1, 2, 0x0088, 3, 12), /* GPIO1D */ RK_PINDRIVE(1, 3, 0x008c, 0, 2), RK_PINDRIVE(1, 3, 0x008c, 1, 4), RK_PINDRIVE(1, 3, 0x008c, 2, 8), RK_PINDRIVE(1, 3, 0x008c, 3, 12), /* GPIO2A */ RK_PINDRIVE(2, 0, 0x0090, 0, 2), RK_PINDRIVE(2, 0, 0x0090, 1, 4), RK_PINDRIVE(2, 0, 0x0090, 2, 8), RK_PINDRIVE(2, 0, 0x0090, 3, 12), /* GPIO2B */ RK_PINDRIVE(2, 1, 0x0094, 0, 2), RK_PINDRIVE(2, 1, 0x0094, 1, 4), RK_PINDRIVE(2, 1, 0x0094, 2, 8), RK_PINDRIVE(2, 1, 0x0094, 3, 12), /* GPIO2C */ RK_PINDRIVE(2, 2, 0x0098, 0, 2), RK_PINDRIVE(2, 2, 0x0098, 1, 4), RK_PINDRIVE(2, 2, 0x0098, 2, 8), RK_PINDRIVE(2, 2, 0x0098, 3, 12), /* GPIO2D */ RK_PINDRIVE(2, 3, 0x009c, 0, 2), RK_PINDRIVE(2, 3, 0x009c, 1, 4), RK_PINDRIVE(2, 3, 0x009c, 2, 8), RK_PINDRIVE(2, 3, 0x009c, 3, 12), /* GPIO3A */ RK_PINDRIVE(3, 0, 0x00a0, 0, 2), RK_PINDRIVE(3, 0, 0x00a0, 1, 4), RK_PINDRIVE(3, 0, 0x00a0, 2, 8), RK_PINDRIVE(3, 0, 0x00a0, 3, 12), /* GPIO3B */ RK_PINDRIVE(3, 1, 0x00a4, 0, 2), RK_PINDRIVE(3, 1, 0x00a4, 1, 4), RK_PINDRIVE(3, 1, 0x00a4, 2, 8), RK_PINDRIVE(3, 1, 0x00a4, 3, 12), /* GPIO3C */ RK_PINDRIVE(3, 2, 0x00a8, 0, 2), RK_PINDRIVE(3, 2, 0x00a8, 1, 4), RK_PINDRIVE(3, 2, 0x00a8, 2, 8), RK_PINDRIVE(3, 2, 0x00a8, 3, 12), /* GPIO3D */ RK_PINDRIVE(3, 3, 0x00ac, 0, 2), RK_PINDRIVE(3, 3, 0x00ac, 1, 4), RK_PINDRIVE(3, 3, 0x00ac, 2, 8), RK_PINDRIVE(3, 3, 0x00ac, 3, 12), /* GPIO4A */ RK_PINDRIVE(4, 0, 0x00b0, 0, 2), RK_PINDRIVE(4, 0, 0x00b0, 1, 4), RK_PINDRIVE(4, 0, 0x00b0, 2, 8), RK_PINDRIVE(4, 0, 0x00b0, 3, 12), /* GPIO4B */ RK_PINDRIVE(4, 1, 0x00b4, 0, 2), RK_PINDRIVE(4, 1, 0x00b4, 1, 4), RK_PINDRIVE(4, 1, 0x00b4, 2, 8), RK_PINDRIVE(4, 1, 0x00b4, 3, 12), /* GPIO4C */ RK_PINDRIVE(4, 2, 0x00b8, 0, 2), RK_PINDRIVE(4, 2, 0x00b8, 1, 4), RK_PINDRIVE(4, 2, 0x00b8, 2, 8), RK_PINDRIVE(4, 2, 0x00b8, 3, 12), /* GPIO4D */ RK_PINDRIVE(4, 3, 0x00bc, 0, 2), RK_PINDRIVE(4, 3, 0x00bc, 1, 4), RK_PINDRIVE(4, 3, 0x00bc, 2, 8), RK_PINDRIVE(4, 3, 0x00bc, 3, 12), }; static uint32_t rk3568_get_pd_offset(struct rk_pinctrl_softc *sc, uint32_t bank) { if (bank == 0) return (0x20); /* * Registers start at 0x80, but bank index starts at 1. Return 0x70 * so later calculations get the correct offset. */ return (0x70); } static struct syscon * rk3568_get_syscon(struct rk_pinctrl_softc *sc, uint32_t bank) { if (bank) return (sc->grf); else return (sc->pmu); } static int rk3568_parse_bias(phandle_t node, int bank) { if (OF_hasprop(node, "bias-disable")) return (0); if (OF_hasprop(node, "bias-pull-up")) return (1); if (OF_hasprop(node, "bias-pull-down")) return (2); return (-1); } static int rk3568_resolv_bias_value(int bank, int bias) { if (bias == 1) return (GPIO_PIN_PULLUP); if (bias == 2) return (GPIO_PIN_PULLDOWN); return (0); } static int rk3568_get_bias_value(int bank, int bias) { if (bias & GPIO_PIN_PULLUP) return (1); if (bias & GPIO_PIN_PULLDOWN) return (2); return (0); } struct rk_pinctrl_conf rk3568_conf = { .iomux_conf = rk3568_iomux_bank, .iomux_nbanks = nitems(rk3568_iomux_bank), .pin_fixup = rk3568_pin_fixup, .npin_fixup = nitems(rk3568_pin_fixup), .pin_drive = rk3568_pin_drive, .npin_drive = nitems(rk3568_pin_drive), .gpio_bank = rk3568_gpio_bank, .ngpio_bank = nitems(rk3568_gpio_bank), .get_pd_offset = rk3568_get_pd_offset, .get_syscon = rk3568_get_syscon, .parse_bias = rk3568_parse_bias, .resolv_bias_value = rk3568_resolv_bias_value, .get_bias_value = rk3568_get_bias_value, }; static struct ofw_compat_data compat_data[] = { {"rockchip,rk3288-pinctrl", (uintptr_t)&rk3288_conf}, {"rockchip,rk3328-pinctrl", (uintptr_t)&rk3328_conf}, {"rockchip,rk3399-pinctrl", (uintptr_t)&rk3399_conf}, {"rockchip,rk3568-pinctrl", (uintptr_t)&rk3568_conf}, {NULL, 0} }; static int rk_pinctrl_parse_drive(struct rk_pinctrl_softc *sc, phandle_t node, uint32_t bank, uint32_t subbank, uint32_t *drive, uint32_t *offset) { uint32_t value; int i; if (OF_getencprop(node, "drive-strength", &value, sizeof(value)) != 0) return (-1); /* Map to the correct drive value */ for (i = 0; i < sc->conf->npin_drive; i++) { if (sc->conf->pin_drive[i].bank != bank && sc->conf->pin_drive[i].subbank != subbank) continue; if (sc->conf->pin_drive[i].ma == value) { *drive = sc->conf->pin_drive[i].value; return (0); } } return (-1); } static void rk_pinctrl_get_fixup(struct rk_pinctrl_softc *sc, uint32_t bank, uint32_t pin, uint32_t *reg, uint32_t *mask, uint32_t *bit) { int i; for (i = 0; i < sc->conf->npin_fixup; i++) if (sc->conf->pin_fixup[i].bank == bank && sc->conf->pin_fixup[i].pin == pin) { *reg = sc->conf->pin_fixup[i].reg; *mask = sc->conf->pin_fixup[i].mask; *bit = sc->conf->pin_fixup[i].bit; return; } } static int rk_pinctrl_handle_io(struct rk_pinctrl_softc *sc, phandle_t node, uint32_t bank, uint32_t pin) { bool have_cfg, have_direction, have_value; uint32_t direction_value, pin_value; struct rk_pinctrl_gpio *gpio; int i, rv; have_cfg = false; have_direction = false; have_value = false; /* Get (subset of) GPIO pin properties. */ if (OF_hasprop(node, "output-disable")) { have_cfg = true; have_direction = true; direction_value = GPIO_PIN_INPUT; } if (OF_hasprop(node, "output-enable")) { have_cfg = true; have_direction = true; direction_value = GPIO_PIN_OUTPUT; } if (OF_hasprop(node, "output-low")) { have_cfg = true; have_direction = true; direction_value = GPIO_PIN_OUTPUT; have_value = true; pin_value = 0; } if (OF_hasprop(node, "output-high")) { have_cfg = true; have_direction = true; direction_value = GPIO_PIN_OUTPUT; have_value = true; pin_value = 1; } if (!have_cfg) return (0); /* Find gpio */ gpio = NULL; for(i = 0; i < sc->conf->ngpio_bank; i++) { if (bank == sc->conf->gpio_bank[i].bank) { gpio = sc->conf->gpio_bank + i; break; } } if (gpio == NULL) { device_printf(sc->dev, "Cannot find GPIO bank %d\n", bank); return (ENXIO); } if (gpio->gpio_dev == NULL) { device_printf(sc->dev, "No GPIO subdevice found for bank %d\n", bank); return (ENXIO); } rv = 0; if (have_value) { rv = GPIO_PIN_SET(gpio->gpio_dev, pin, pin_value); if (rv != 0) { device_printf(sc->dev, "Cannot set GPIO value: %d\n", rv); return (rv); } } if (have_direction) { rv = GPIO_PIN_SETFLAGS(gpio->gpio_dev, pin, direction_value); if (rv != 0) { device_printf(sc->dev, "Cannot set GPIO direction: %d\n", rv); return (rv); } } return (0); } static void rk_pinctrl_configure_pin(struct rk_pinctrl_softc *sc, uint32_t *pindata) { phandle_t pin_conf; struct syscon *syscon; uint32_t bank, subbank, pin, function, bias; uint32_t bit, mask, reg, drive; int i, rv; bank = pindata[0]; pin = pindata[1]; function = pindata[2]; pin_conf = OF_node_from_xref(pindata[3]); subbank = pin / 8; for (i = 0; i < sc->conf->iomux_nbanks; i++) if (sc->conf->iomux_conf[i].bank == bank && sc->conf->iomux_conf[i].subbank == subbank) break; if (i == sc->conf->iomux_nbanks) { device_printf(sc->dev, "Unknown pin %d in bank %d\n", pin, bank); return; } /* Find syscon */ syscon = sc->conf->get_syscon(sc, bank); /* Setup GPIO properties first */ rv = rk_pinctrl_handle_io(sc, pin_conf, bank, pin); /* Then pin pull-up/down */ bias = sc->conf->parse_bias(pin_conf, bank); if (bias >= 0) { reg = sc->conf->get_pd_offset(sc, bank); reg += bank * 0x10 + ((pin / 8) * 0x4); bit = (pin % 8) * 2; mask = (0x3 << bit); SYSCON_MODIFY_4(syscon, reg, mask, bias << bit | (mask << 16)); } /* Then drive strength */ if (ofw_bus_node_is_compatible(ofw_bus_get_node(sc->dev), "rockchip,rk3568-pinctrl")) { uint32_t value; if (OF_getencprop(pin_conf, "drive-strength", &value, sizeof(value)) == 0) { if (bank) reg = 0x01c0 + (bank * 0x40) + (pin / 2 * 4); else reg = 0x0070 + (pin / 2 * 4); drive = ((1 << (value + 1)) - 1) << (pin % 2); mask = 0x3f << (pin % 2);; SYSCON_WRITE_4(syscon, reg, drive | (mask << 16)); } } else { rv = rk_pinctrl_parse_drive(sc, pin_conf, bank, subbank, &drive, ®); if (rv == 0) { bit = (pin % 8) * 2; mask = (0x3 << bit); SYSCON_MODIFY_4(syscon, reg, mask, drive << bit | (mask << 16)); } } /* Finally set the pin function */ reg = sc->conf->iomux_conf[i].offset; switch (sc->conf->iomux_conf[i].nbits) { case 4: if ((pin % 8) >= 4) reg += 0x4; bit = (pin % 4) * 4; mask = (0xF << bit); break; case 3: if ((pin % 8) >= 5) reg += 4; bit = (pin % 8 % 5) * 3; mask = (0x7 << bit); break; case 2: bit = (pin % 8) * 2; mask = (0x3 << bit); break; default: device_printf(sc->dev, "Unknown pin stride width %d in bank %d\n", sc->conf->iomux_conf[i].nbits, bank); return; } rk_pinctrl_get_fixup(sc, bank, pin, ®, &mask, &bit); /* * NOTE: not all syscon registers uses hi-word write mask, thus * register modify method should be used. * XXXX We should not pass write mask to syscon register * without hi-word write mask. */ SYSCON_MODIFY_4(syscon, reg, mask, function << bit | (mask << 16)); /* RK3568 specific pin mux for various functionalities */ if (ofw_bus_node_is_compatible(ofw_bus_get_node(sc->dev), "rockchip,rk3568-pinctrl")) { if (bank == 3 && pin == 9 && function == 3) SYSCON_WRITE_4(sc->grf, GRF_IOFUNC_SEL0, GMAC1_IOMUX_SEL_M0); if (bank == 4 && pin == 7 && function == 3) SYSCON_WRITE_4(sc->grf, GRF_IOFUNC_SEL0, GMAC1_IOMUX_SEL_M1); } } static int rk_pinctrl_configure_pins(device_t dev, phandle_t cfgxref) { struct rk_pinctrl_softc *sc; phandle_t node; uint32_t *pins; int i, npins; sc = device_get_softc(dev); node = OF_node_from_xref(cfgxref); npins = OF_getencprop_alloc_multi(node, "rockchip,pins", sizeof(*pins), (void **)&pins); if (npins <= 0) return (ENOENT); for (i = 0; i != npins; i += 4) rk_pinctrl_configure_pin(sc, pins + i); return (0); } static int rk_pinctrl_is_gpio_locked(struct rk_pinctrl_softc *sc, struct syscon *syscon, int bank, uint32_t pin, bool *is_gpio) { uint32_t subbank, bit, mask, reg; uint32_t pinfunc; int i; RK_PINCTRL_LOCK_ASSERT(sc); subbank = pin / 8; *is_gpio = false; for (i = 0; i < sc->conf->iomux_nbanks; i++) if (sc->conf->iomux_conf[i].bank == bank && sc->conf->iomux_conf[i].subbank == subbank) break; if (i == sc->conf->iomux_nbanks) { device_printf(sc->dev, "Unknown pin %d in bank %d\n", pin, bank); return (EINVAL); } syscon = sc->conf->get_syscon(sc, bank); /* Parse pin function */ reg = sc->conf->iomux_conf[i].offset; switch (sc->conf->iomux_conf[i].nbits) { case 4: if ((pin % 8) >= 4) reg += 0x4; bit = (pin % 4) * 4; mask = (0xF << bit); break; case 3: if ((pin % 8) >= 5) reg += 4; bit = (pin % 8 % 5) * 3; mask = (0x7 << bit); break; case 2: bit = (pin % 8) * 2; mask = (0x3 << bit); break; default: device_printf(sc->dev, "Unknown pin stride width %d in bank %d\n", sc->conf->iomux_conf[i].nbits, bank); return (EINVAL); } rk_pinctrl_get_fixup(sc, bank, pin, ®, &mask, &bit); reg = SYSCON_READ_4(syscon, reg); pinfunc = (reg & mask) >> bit; /* Test if the pin is in gpio mode */ if (pinfunc == 0) *is_gpio = true; return (0); } static int rk_pinctrl_get_bank(struct rk_pinctrl_softc *sc, device_t gpio, int *bank) { int i; for (i = 0; i < sc->conf->ngpio_bank; i++) { if (sc->conf->gpio_bank[i].gpio_dev == gpio) break; } if (i == sc->conf->ngpio_bank) return (EINVAL); *bank = i; return (0); } static int rk_pinctrl_is_gpio(device_t pinctrl, device_t gpio, uint32_t pin, bool *is_gpio) { struct rk_pinctrl_softc *sc; struct syscon *syscon; int bank; int rv; sc = device_get_softc(pinctrl); RK_PINCTRL_LOCK(sc); rv = rk_pinctrl_get_bank(sc, gpio, &bank); if (rv != 0) goto done; syscon = sc->conf->get_syscon(sc, bank); rv = rk_pinctrl_is_gpio_locked(sc, syscon, bank, pin, is_gpio); done: RK_PINCTRL_UNLOCK(sc); return (rv); } static int rk_pinctrl_get_flags(device_t pinctrl, device_t gpio, uint32_t pin, uint32_t *flags) { struct rk_pinctrl_softc *sc; struct syscon *syscon; uint32_t reg, bit; uint32_t bias; int bank; int rv = 0; bool is_gpio; sc = device_get_softc(pinctrl); RK_PINCTRL_LOCK(sc); rv = rk_pinctrl_get_bank(sc, gpio, &bank); if (rv != 0) goto done; syscon = sc->conf->get_syscon(sc, bank); rv = rk_pinctrl_is_gpio_locked(sc, syscon, bank, pin, &is_gpio); if (rv != 0) goto done; if (!is_gpio) { rv = EINVAL; goto done; } /* Get the pullup/pulldown configuration */ reg = sc->conf->get_pd_offset(sc, bank); reg += bank * 0x10 + ((pin / 8) * 0x4); bit = (pin % 8) * 2; reg = SYSCON_READ_4(syscon, reg); reg = (reg >> bit) & 0x3; bias = sc->conf->resolv_bias_value(bank, reg); *flags = bias; done: RK_PINCTRL_UNLOCK(sc); return (rv); } static int rk_pinctrl_set_flags(device_t pinctrl, device_t gpio, uint32_t pin, uint32_t flags) { struct rk_pinctrl_softc *sc; struct syscon *syscon; uint32_t bit, mask, reg; uint32_t bias; int bank; int rv = 0; bool is_gpio; sc = device_get_softc(pinctrl); RK_PINCTRL_LOCK(sc); rv = rk_pinctrl_get_bank(sc, gpio, &bank); if (rv != 0) goto done; syscon = sc->conf->get_syscon(sc, bank); rv = rk_pinctrl_is_gpio_locked(sc, syscon, bank, pin, &is_gpio); if (rv != 0) goto done; if (!is_gpio) { rv = EINVAL; goto done; } /* Get the pullup/pulldown configuration */ reg = sc->conf->get_pd_offset(sc, bank); reg += bank * 0x10 + ((pin / 8) * 0x4); bit = (pin % 8) * 2; mask = (0x3 << bit); bias = sc->conf->get_bias_value(bank, flags); SYSCON_MODIFY_4(syscon, reg, mask, bias << bit | (mask << 16)); done: RK_PINCTRL_UNLOCK(sc); return (rv); } static int rk_pinctrl_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "RockChip Pinctrl controller"); return (BUS_PROBE_DEFAULT); } static int rk_pinctrl_attach(device_t dev) { struct rk_pinctrl_softc *sc; phandle_t node; device_t cdev; int rv, gpio_unit; sc = device_get_softc(dev); sc->dev = dev; node = ofw_bus_get_node(dev); if (OF_hasprop(node, "rockchip,grf") && syscon_get_by_ofw_property(dev, node, "rockchip,grf", &sc->grf) != 0) { device_printf(dev, "cannot get grf driver handle\n"); return (ENXIO); } /* RK3568,RK3399,RK3288 have banks in PMU. RK3328 doesn't have a PMU. */ if (ofw_bus_node_is_compatible(node, "rockchip,rk3568-pinctrl") || ofw_bus_node_is_compatible(node, "rockchip,rk3399-pinctrl") || ofw_bus_node_is_compatible(node, "rockchip,rk3288-pinctrl")) { if (OF_hasprop(node, "rockchip,pmu") && syscon_get_by_ofw_property(dev, node, "rockchip,pmu", &sc->pmu) != 0) { device_printf(dev, "cannot get pmu driver handle\n"); return (ENXIO); } } mtx_init(&sc->mtx, "rk pinctrl", "pinctrl", MTX_SPIN); sc->conf = (struct rk_pinctrl_conf *)ofw_bus_search_compatible(dev, compat_data)->ocd_data; fdt_pinctrl_register(dev, "rockchip,pins"); simplebus_init(dev, node); bus_generic_probe(dev); /* Attach child devices */ for (node = OF_child(node), gpio_unit = 0; node > 0; node = OF_peer(node)) { if (!ofw_bus_node_is_compatible(node, "rockchip,gpio-bank")) continue; cdev = simplebus_add_device(dev, node, 0, NULL, -1, NULL); if (cdev == NULL) { device_printf(dev, " Cannot add GPIO subdevice\n"); gpio_unit += 1; continue; } rv = device_probe_and_attach(cdev); if (rv != 0) { device_printf(sc->dev, "Cannot attach GPIO subdevice\n"); gpio_unit += 1; continue; } sc->conf->gpio_bank[gpio_unit].gpio_dev = cdev; gpio_unit += 1; } fdt_pinctrl_configure_tree(dev); return (bus_generic_attach(dev)); } static int rk_pinctrl_detach(device_t dev) { return (EBUSY); } static device_method_t rk_pinctrl_methods[] = { /* Device interface */ DEVMETHOD(device_probe, rk_pinctrl_probe), DEVMETHOD(device_attach, rk_pinctrl_attach), DEVMETHOD(device_detach, rk_pinctrl_detach), /* fdt_pinctrl interface */ DEVMETHOD(fdt_pinctrl_configure, rk_pinctrl_configure_pins), DEVMETHOD(fdt_pinctrl_is_gpio, rk_pinctrl_is_gpio), DEVMETHOD(fdt_pinctrl_get_flags, rk_pinctrl_get_flags), DEVMETHOD(fdt_pinctrl_set_flags, rk_pinctrl_set_flags), DEVMETHOD_END }; DEFINE_CLASS_1(rk_pinctrl, rk_pinctrl_driver, rk_pinctrl_methods, sizeof(struct rk_pinctrl_softc), simplebus_driver); EARLY_DRIVER_MODULE(rk_pinctrl, simplebus, rk_pinctrl_driver, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE); MODULE_VERSION(rk_pinctrl, 1); diff --git a/sys/arm64/rockchip/rk_pmu.c b/sys/arm64/rockchip/rk_pmu.c index 92a1fbae9413..0e5b9380d66d 100644 --- a/sys/arm64/rockchip/rk_pmu.c +++ b/sys/arm64/rockchip/rk_pmu.c @@ -1,73 +1,73 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2019 Michal Meloun * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include -#include +#include #include static struct ofw_compat_data compat_data[] = { {"rockchip,rk3288-pmu", 1}, {NULL, 0} }; static int rk_pmu_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "RockChip Power Management Unit"); return (BUS_PROBE_DEFAULT); } static device_method_t rk_pmu_methods[] = { DEVMETHOD(device_probe, rk_pmu_probe), DEVMETHOD_END }; DEFINE_CLASS_1(rk_pmu, rk_pmu_driver, rk_pmu_methods, sizeof(struct simple_mfd_softc), simple_mfd_driver); EARLY_DRIVER_MODULE(rk_pmu, simplebus, rk_pmu_driver, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE); MODULE_VERSION(rk_pmu, 1); diff --git a/sys/arm64/rockchip/rk_tsadc.c b/sys/arm64/rockchip/rk_tsadc.c index ff5fd722d0f0..a8a64b69d7d3 100644 --- a/sys/arm64/rockchip/rk_tsadc.c +++ b/sys/arm64/rockchip/rk_tsadc.c @@ -1,880 +1,880 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2019 Michal Meloun * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include /* * Thermometer and thermal zones driver for RockChip SoCs. * Calibration data are taken from Linux, because this part of SoC * is undocumented in TRM. */ #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include #include #include "syscon_if.h" #include "rk_tsadc_if.h" /* Version of HW */ #define TSADC_V2 1 #define TSADC_V3 2 #define TSADC_V7 3 /* Global registers */ #define TSADC_USER_CON 0x000 #define TSADC_AUTO_CON 0x004 #define TSADC_AUTO_CON_POL_HI (1 << 8) #define TSADC_AUTO_SRC_EN(x) (1 << (4 + (x))) #define TSADC_AUTO_Q_SEL (1 << 1) /* V3 only */ #define TSADC_AUTO_CON_AUTO (1 << 0) #define TSADC_INT_EN 0x008 #define TSADC_INT_EN_2CRU_EN_SRC(x) (1 << (8 + (x))) #define TSADC_INT_EN_2GPIO_EN_SRC(x) (1 << (4 + (x))) #define TSADC_INT_PD 0x00c #define TSADC_DATA(x) (0x20 + (x) * 0x04) #define TSADC_COMP_INT(x) (0x30 + (x) * 0x04) #define TSADC_COMP_INT_SRC_EN(x) (1 << (0 + (x))) #define TSADC_COMP_SHUT(x) (0x40 + (x) * 0x04) #define TSADC_HIGHT_INT_DEBOUNCE 0x060 #define TSADC_HIGHT_TSHUT_DEBOUNCE 0x064 #define TSADC_AUTO_PERIOD 0x068 #define TSADC_AUTO_PERIOD_HT 0x06c #define TSADC_COMP0_LOW_INT 0x080 /* V3 only */ #define TSADC_COMP1_LOW_INT 0x084 /* V3 only */ /* V3 GFR registers */ #define GRF_SARADC_TESTBIT 0x0e644 #define GRF_SARADC_TESTBIT_ON (0x10001 << 2) #define GRF_TSADC_TESTBIT_L 0x0e648 #define GRF_TSADC_VCM_EN_L (0x10001 << 7) #define GRF_TSADC_TESTBIT_H 0x0e64c #define GRF_TSADC_VCM_EN_H (0x10001 << 7) #define GRF_TSADC_TESTBIT_H_ON (0x10001 << 2) /* V7 GRF register */ #define GRF_TSADC_CON 0x0600 #define GRF_TSADC_ANA_REG0 (0x10001 << 0) #define GRF_TSADC_ANA_REG1 (0x10001 << 1) #define GRF_TSADC_ANA_REG2 (0x10001 << 2) #define GRF_TSADC_TSEN (0x10001 << 8) #define WR4(_sc, _r, _v) bus_write_4((_sc)->mem_res, (_r), (_v)) #define RD4(_sc, _r) bus_read_4((_sc)->mem_res, (_r)) static struct sysctl_ctx_list tsadc_sysctl_ctx; struct tsensor { char *name; int id; int channel; }; struct rk_calib_entry { uint32_t raw; int temp; }; struct tsadc_calib_info { struct rk_calib_entry *table; int nentries; }; struct tsadc_conf { int version; int q_sel_ntc; int shutdown_temp; int shutdown_mode; int shutdown_pol; struct tsensor *tsensors; int ntsensors; struct tsadc_calib_info calib_info; }; struct tsadc_softc { device_t dev; struct resource *mem_res; struct resource *irq_res; void *irq_ih; clk_t tsadc_clk; clk_t apb_pclk_clk; hwreset_array_t hwreset; struct syscon *grf; struct tsadc_conf *conf; int shutdown_temp; int shutdown_mode; int shutdown_pol; int alarm_temp; }; static struct rk_calib_entry rk3288_calib_data[] = { {3800, -40000}, {3792, -35000}, {3783, -30000}, {3774, -25000}, {3765, -20000}, {3756, -15000}, {3747, -10000}, {3737, -5000}, {3728, 0}, {3718, 5000}, {3708, 10000}, {3698, 15000}, {3688, 20000}, {3678, 25000}, {3667, 30000}, {3656, 35000}, {3645, 40000}, {3634, 45000}, {3623, 50000}, {3611, 55000}, {3600, 60000}, {3588, 65000}, {3575, 70000}, {3563, 75000}, {3550, 80000}, {3537, 85000}, {3524, 90000}, {3510, 95000}, {3496, 100000}, {3482, 105000}, {3467, 110000}, {3452, 115000}, {3437, 120000}, {3421, 125000}, }; struct tsensor rk3288_tsensors[] = { { .channel = 0, .id = 2, .name = "reserved"}, { .channel = 1, .id = 0, .name = "CPU"}, { .channel = 2, .id = 1, .name = "GPU"}, }; struct tsadc_conf rk3288_tsadc_conf = { .version = TSADC_V2, .q_sel_ntc = 0, .shutdown_temp = 95000, .shutdown_mode = 1, /* GPIO */ .shutdown_pol = 0, /* Low */ .tsensors = rk3288_tsensors, .ntsensors = nitems(rk3288_tsensors), .calib_info = { .table = rk3288_calib_data, .nentries = nitems(rk3288_calib_data), } }; static struct rk_calib_entry rk3328_calib_data[] = { {296, -40000}, {304, -35000}, {313, -30000}, {331, -20000}, {340, -15000}, {349, -10000}, {359, -5000}, {368, 0}, {378, 5000}, {388, 10000}, {398, 15000}, {408, 20000}, {418, 25000}, {429, 30000}, {440, 35000}, {451, 40000}, {462, 45000}, {473, 50000}, {485, 55000}, {496, 60000}, {508, 65000}, {521, 70000}, {533, 75000}, {546, 80000}, {559, 85000}, {572, 90000}, {586, 95000}, {600, 100000}, {614, 105000}, {629, 110000}, {644, 115000}, {659, 120000}, {675, 125000}, }; static struct tsensor rk3328_tsensors[] = { { .channel = 0, .id = 0, .name = "CPU"}, }; static struct tsadc_conf rk3328_tsadc_conf = { .version = TSADC_V2, .q_sel_ntc = 1, .shutdown_temp = 95000, .shutdown_mode = 0, /* CRU */ .shutdown_pol = 0, /* Low */ .tsensors = rk3328_tsensors, .ntsensors = nitems(rk3328_tsensors), .calib_info = { .table = rk3328_calib_data, .nentries = nitems(rk3328_calib_data), } }; static struct rk_calib_entry rk3399_calib_data[] = { {402, -40000}, {410, -35000}, {419, -30000}, {427, -25000}, {436, -20000}, {444, -15000}, {453, -10000}, {461, -5000}, {470, 0}, {478, 5000}, {487, 10000}, {496, 15000}, {504, 20000}, {513, 25000}, {521, 30000}, {530, 35000}, {538, 40000}, {547, 45000}, {555, 50000}, {564, 55000}, {573, 60000}, {581, 65000}, {590, 70000}, {599, 75000}, {607, 80000}, {616, 85000}, {624, 90000}, {633, 95000}, {642, 100000}, {650, 105000}, {659, 110000}, {668, 115000}, {677, 120000}, {685, 125000}, }; static struct tsensor rk3399_tsensors[] = { { .channel = 0, .id = 0, .name = "CPU"}, { .channel = 1, .id = 1, .name = "GPU"}, }; static struct tsadc_conf rk3399_tsadc_conf = { .version = TSADC_V3, .q_sel_ntc = 1, .shutdown_temp = 95000, .shutdown_mode = 1, /* GPIO */ .shutdown_pol = 0, /* Low */ .tsensors = rk3399_tsensors, .ntsensors = nitems(rk3399_tsensors), .calib_info = { .table = rk3399_calib_data, .nentries = nitems(rk3399_calib_data), } }; static struct rk_calib_entry rk3568_calib_data[] = { {0, -40000}, {1584, -40000}, {1620, -35000}, {1652, -30000}, {1688, -25000}, {1720, -20000}, {1756, -15000}, {1788, -10000}, {1824, -5000}, {1856, 0}, {1892, 5000}, {1924, 10000}, {1956, 15000}, {1992, 20000}, {2024, 25000}, {2060, 30000}, {2092, 35000}, {2128, 40000}, {2160, 45000}, {2196, 50000}, {2228, 55000}, {2264, 60000}, {2300, 65000}, {2332, 70000}, {2368, 75000}, {2400, 80000}, {2436, 85000}, {2468, 90000}, {2500, 95000}, {2536, 100000}, {2572, 105000}, {2604, 110000}, {2636, 115000}, {2672, 120000}, {2704, 125000}, }; static struct tsensor rk3568_tsensors[] = { { .channel = 0, .id = 0, .name = "CPU"}, { .channel = 1, .id = 1, .name = "GPU"}, }; static struct tsadc_conf rk3568_tsadc_conf = { .version = TSADC_V7, .q_sel_ntc = 1, .shutdown_temp = 95000, .shutdown_mode = 1, /* GPIO */ .shutdown_pol = 0, /* Low */ .tsensors = rk3568_tsensors, .ntsensors = nitems(rk3568_tsensors), .calib_info = { .table = rk3568_calib_data, .nentries = nitems(rk3568_calib_data), } }; static struct ofw_compat_data compat_data[] = { {"rockchip,rk3288-tsadc", (uintptr_t)&rk3288_tsadc_conf}, {"rockchip,rk3328-tsadc", (uintptr_t)&rk3328_tsadc_conf}, {"rockchip,rk3399-tsadc", (uintptr_t)&rk3399_tsadc_conf}, {"rockchip,rk3568-tsadc", (uintptr_t)&rk3568_tsadc_conf}, {NULL, 0} }; static uint32_t tsadc_temp_to_raw(struct tsadc_softc *sc, int temp) { struct rk_calib_entry *tbl; int denom, ntbl, raw, i; tbl = sc->conf->calib_info.table; ntbl = sc->conf->calib_info.nentries; if (temp <= tbl[0].temp) return (tbl[0].raw); if (temp >= tbl[ntbl - 1].temp) return (tbl[ntbl - 1].raw); for (i = 1; i < (ntbl - 1); i++) { /* Exact match */ if (temp == tbl[i].temp) return (tbl[i].raw); if (temp < tbl[i].temp) break; } /* * Translated value is between i and i - 1 table entries. * Do linear interpolation for it. */ raw = (int)tbl[i - 1].raw - (int)tbl[i].raw; raw *= temp - tbl[i - 1].temp; denom = tbl[i - 1].temp - tbl[i].temp; raw = tbl[i - 1].raw + raw / denom; return (raw); } static int tsadc_raw_to_temp(struct tsadc_softc *sc, uint32_t raw) { struct rk_calib_entry *tbl; int denom, ntbl, temp, i; bool descending; tbl = sc->conf->calib_info.table; ntbl = sc->conf->calib_info.nentries; descending = tbl[0].raw > tbl[1].raw; if (descending) { /* Raw column is in descending order. */ if (raw >= tbl[0].raw) return (tbl[0].temp); if (raw <= tbl[ntbl - 1].raw) return (tbl[ntbl - 1].temp); for (i = ntbl - 2; i > 0; i--) { /* Exact match */ if (raw == tbl[i].raw) return (tbl[i].temp); if (raw < tbl[i].raw) break; } } else { /* Raw column is in ascending order. */ if (raw <= tbl[0].raw) return (tbl[0].temp); if (raw >= tbl[ntbl - 1].raw) return (tbl[ntbl - 1].temp); for (i = 1; i < (ntbl - 1); i++) { /* Exact match */ if (raw == tbl[i].raw) return (tbl[i].temp); if (raw < tbl[i].raw) break; } } /* * Translated value is between i and i - 1 table entries. * Do linear interpolation for it. */ temp = (int)tbl[i - 1].temp - (int)tbl[i].temp; temp *= raw - tbl[i - 1].raw; denom = tbl[i - 1].raw - tbl[i].raw; temp = tbl[i - 1].temp + temp / denom; return (temp); } static void tsadc_init_tsensor(struct tsadc_softc *sc, struct tsensor *sensor) { uint32_t val; /* Shutdown mode */ val = RD4(sc, TSADC_INT_EN); if (sc->shutdown_mode != 0) { /* Signal shutdown of GPIO pin */ val &= ~TSADC_INT_EN_2CRU_EN_SRC(sensor->channel); val |= TSADC_INT_EN_2GPIO_EN_SRC(sensor->channel); } else { val |= TSADC_INT_EN_2CRU_EN_SRC(sensor->channel); val &= ~TSADC_INT_EN_2GPIO_EN_SRC(sensor->channel); } WR4(sc, TSADC_INT_EN, val); /* Shutdown temperature */ val = tsadc_raw_to_temp(sc, sc->shutdown_temp); WR4(sc, TSADC_COMP_SHUT(sensor->channel), val); val = RD4(sc, TSADC_AUTO_CON); val |= TSADC_AUTO_SRC_EN(sensor->channel); WR4(sc, TSADC_AUTO_CON, val); /* Alarm temperature */ val = tsadc_temp_to_raw(sc, sc->alarm_temp); WR4(sc, TSADC_COMP_INT(sensor->channel), val); val = RD4(sc, TSADC_INT_EN); val |= TSADC_COMP_INT_SRC_EN(sensor->channel); WR4(sc, TSADC_INT_EN, val); } static void tsadc_init(struct tsadc_softc *sc) { uint32_t val; /* Common part */ val = 0; /* XXX Is this right? */ if (sc->shutdown_pol != 0) val |= TSADC_AUTO_CON_POL_HI; else val &= ~TSADC_AUTO_CON_POL_HI; if (sc->conf->q_sel_ntc) val |= TSADC_AUTO_Q_SEL; WR4(sc, TSADC_AUTO_CON, val); switch (sc->conf->version) { case TSADC_V2: /* V2 init */ WR4(sc, TSADC_AUTO_PERIOD, 250); /* 250 ms */ WR4(sc, TSADC_AUTO_PERIOD_HT, 50); /* 50 ms */ WR4(sc, TSADC_HIGHT_INT_DEBOUNCE, 4); WR4(sc, TSADC_HIGHT_TSHUT_DEBOUNCE, 4); break; case TSADC_V3: /* V3 init */ if (sc->grf == NULL) { /* Errata: adjust interleave to working value */ WR4(sc, TSADC_USER_CON, 13 << 6); /* 13 clks */ } else { SYSCON_WRITE_4(sc->grf, GRF_TSADC_TESTBIT_L, GRF_TSADC_VCM_EN_L); SYSCON_WRITE_4(sc->grf, GRF_TSADC_TESTBIT_H, GRF_TSADC_VCM_EN_H); DELAY(30); /* 15 usec min */ SYSCON_WRITE_4(sc->grf, GRF_SARADC_TESTBIT, GRF_SARADC_TESTBIT_ON); SYSCON_WRITE_4(sc->grf, GRF_TSADC_TESTBIT_H, GRF_TSADC_TESTBIT_H_ON); DELAY(180); /* 90 usec min */ } WR4(sc, TSADC_AUTO_PERIOD, 1875); /* 2.5 ms */ WR4(sc, TSADC_AUTO_PERIOD_HT, 1875); /* 2.5 ms */ WR4(sc, TSADC_HIGHT_INT_DEBOUNCE, 4); WR4(sc, TSADC_HIGHT_TSHUT_DEBOUNCE, 4); break; case TSADC_V7: /* V7 init */ WR4(sc, TSADC_USER_CON, 0xfc0); /* 97us, at least 90us */ WR4(sc, TSADC_AUTO_PERIOD, 1622); /* 2.5ms */ WR4(sc, TSADC_HIGHT_INT_DEBOUNCE, 4); WR4(sc, TSADC_AUTO_PERIOD_HT, 1622); /* 2.5ms */ WR4(sc, TSADC_HIGHT_TSHUT_DEBOUNCE, 4); if (sc->grf) { SYSCON_WRITE_4(sc->grf, GRF_TSADC_CON, GRF_TSADC_TSEN); DELAY(15); /* 10 usec min */ SYSCON_WRITE_4(sc->grf, GRF_TSADC_CON, GRF_TSADC_ANA_REG0); SYSCON_WRITE_4(sc->grf, GRF_TSADC_CON, GRF_TSADC_ANA_REG1); SYSCON_WRITE_4(sc->grf, GRF_TSADC_CON, GRF_TSADC_ANA_REG2); DELAY(100); /* 90 usec min */ } break; } } static int tsadc_read_temp(struct tsadc_softc *sc, struct tsensor *sensor, int *temp) { uint32_t val; val = RD4(sc, TSADC_DATA(sensor->channel)); *temp = tsadc_raw_to_temp(sc, val); #ifdef DEBUG device_printf(sc->dev, "%s: Sensor(id: %d, ch: %d), val: %d temp: %d\n", __func__, sensor->id, sensor->channel, val, *temp); device_printf(sc->dev, "%s: user_con=0x%08x auto_con=0x%08x " "comp_int=0x%08x comp_shut=0x%08x\n", __func__, RD4(sc, TSADC_USER_CON), RD4(sc, TSADC_AUTO_CON), RD4(sc, TSADC_COMP_INT(sensor->channel)), RD4(sc, TSADC_COMP_SHUT(sensor->channel))); #endif return (0); } static int tsadc_get_temp(device_t dev, device_t cdev, uintptr_t id, int *val) { struct tsadc_softc *sc; int i, rv; sc = device_get_softc(dev); if (id >= sc->conf->ntsensors) return (ERANGE); for (i = 0; i < sc->conf->ntsensors; i++) { if (sc->conf->tsensors->id == id) { rv =tsadc_read_temp(sc, sc->conf->tsensors + id, val); return (rv); } } return (ERANGE); } static int tsadc_sysctl_temperature(SYSCTL_HANDLER_ARGS) { struct tsadc_softc *sc; int val; int rv; int id; /* Write request */ if (req->newptr != NULL) return (EINVAL); sc = arg1; id = arg2; if (id >= sc->conf->ntsensors) return (ERANGE); rv = tsadc_read_temp(sc, sc->conf->tsensors + id, &val); if (rv != 0) return (rv); val = val / 100; val += 2731; rv = sysctl_handle_int(oidp, &val, 0, req); return (rv); } static int tsadc_init_sysctl(struct tsadc_softc *sc) { int i; struct sysctl_oid *oid, *tmp; sysctl_ctx_init(&tsadc_sysctl_ctx); /* create node for hw.temp */ oid = SYSCTL_ADD_NODE(&tsadc_sysctl_ctx, SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, "temperature", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, ""); if (oid == NULL) return (ENXIO); /* Add sensors */ for (i = sc->conf->ntsensors - 1; i >= 0; i--) { tmp = SYSCTL_ADD_PROC(&tsadc_sysctl_ctx, SYSCTL_CHILDREN(oid), OID_AUTO, sc->conf->tsensors[i].name, CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_NEEDGIANT, sc, i, tsadc_sysctl_temperature, "IK", "SoC Temperature"); if (tmp == NULL) return (ENXIO); } return (0); } static int tsadc_intr(void *arg) { struct tsadc_softc *sc; uint32_t val; sc = (struct tsadc_softc *)arg; val = RD4(sc, TSADC_INT_PD); WR4(sc, TSADC_INT_PD, val); /* XXX Handle shutdown and alarm interrupts. */ if (val & 0x00F0) { device_printf(sc->dev, "Alarm: device temperature " "is above of shutdown level.\n"); } else if (val & 0x000F) { device_printf(sc->dev, "Alarm: device temperature " "is above of alarm level.\n"); } return (FILTER_HANDLED); } static int tsadc_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "RockChip temperature sensors"); return (BUS_PROBE_DEFAULT); } static int tsadc_attach(device_t dev) { struct tsadc_softc *sc; phandle_t node; uint32_t val; int i, rid, rv; sc = device_get_softc(dev); sc->dev = dev; node = ofw_bus_get_node(sc->dev); sc->conf = (struct tsadc_conf *) ofw_bus_search_compatible(dev, compat_data)->ocd_data; sc->alarm_temp = 90000; rid = 0; sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (sc->mem_res == NULL) { device_printf(dev, "Cannot allocate memory resources\n"); goto fail; } rid = 0; sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); if (sc->irq_res == NULL) { device_printf(dev, "Cannot allocate IRQ resources\n"); goto fail; } if ((bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE, tsadc_intr, NULL, sc, &sc->irq_ih))) { device_printf(dev, "WARNING: unable to register interrupt handler\n"); goto fail; } /* FDT resources */ rv = hwreset_array_get_ofw(dev, 0, &sc->hwreset); if (rv != 0) { device_printf(dev, "Cannot get resets\n"); goto fail; } rv = clk_get_by_ofw_name(dev, 0, "tsadc", &sc->tsadc_clk); if (rv != 0) { device_printf(dev, "Cannot get 'tsadc' clock: %d\n", rv); goto fail; } rv = clk_get_by_ofw_name(dev, 0, "apb_pclk", &sc->apb_pclk_clk); if (rv != 0) { device_printf(dev, "Cannot get 'apb_pclk' clock: %d\n", rv); goto fail; } /* grf is optional */ rv = syscon_get_by_ofw_property(dev, node, "rockchip,grf", &sc->grf); if (rv != 0 && rv != ENOENT) { device_printf(dev, "Cannot get 'grf' syscon: %d\n", rv); goto fail; } rv = OF_getencprop(node, "rockchip,hw-tshut-temp", &sc->shutdown_temp, sizeof(sc->shutdown_temp)); if (rv <= 0) sc->shutdown_temp = sc->conf->shutdown_temp; rv = OF_getencprop(node, "rockchip,hw-tshut-mode", &sc->shutdown_mode, sizeof(sc->shutdown_mode)); if (rv <= 0) sc->shutdown_mode = sc->conf->shutdown_mode; rv = OF_getencprop(node, "rockchip,hw-tshut-polarity", &sc->shutdown_pol, sizeof(sc->shutdown_pol)); if (rv <= 0) sc->shutdown_pol = sc->conf->shutdown_pol; /* Wakeup controller */ rv = hwreset_array_assert(sc->hwreset); if (rv != 0) { device_printf(dev, "Cannot assert reset\n"); goto fail; } /* Set the assigned clocks parent and freq */ rv = clk_set_assigned(sc->dev, node); if (rv != 0 && rv != ENOENT) { device_printf(dev, "clk_set_assigned failed\n"); goto fail; } rv = clk_enable(sc->tsadc_clk); if (rv != 0) { device_printf(dev, "Cannot enable 'tsadc_clk' clock: %d\n", rv); goto fail; } rv = clk_enable(sc->apb_pclk_clk); if (rv != 0) { device_printf(dev, "Cannot enable 'apb_pclk' clock: %d\n", rv); goto fail; } rv = hwreset_array_deassert(sc->hwreset); if (rv != 0) { device_printf(dev, "Cannot deassert reset\n"); goto fail; } tsadc_init(sc); for (i = 0; i < sc->conf->ntsensors; i++) tsadc_init_tsensor(sc, sc->conf->tsensors + i); /* Enable auto mode */ val = RD4(sc, TSADC_AUTO_CON); val |= TSADC_AUTO_CON_AUTO; WR4(sc, TSADC_AUTO_CON, val); rv = tsadc_init_sysctl(sc); if (rv != 0) { device_printf(sc->dev, "Cannot initialize sysctls\n"); goto fail_sysctl; } OF_device_register_xref(OF_xref_from_node(node), dev); return (bus_generic_attach(dev)); fail_sysctl: sysctl_ctx_free(&tsadc_sysctl_ctx); fail: if (sc->irq_ih != NULL) bus_teardown_intr(dev, sc->irq_res, sc->irq_ih); if (sc->tsadc_clk != NULL) clk_release(sc->tsadc_clk); if (sc->apb_pclk_clk != NULL) clk_release(sc->apb_pclk_clk); if (sc->hwreset != NULL) hwreset_array_release(sc->hwreset); if (sc->irq_res != NULL) bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res); if (sc->mem_res != NULL) bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res); return (ENXIO); } static int tsadc_detach(device_t dev) { struct tsadc_softc *sc; sc = device_get_softc(dev); if (sc->irq_ih != NULL) bus_teardown_intr(dev, sc->irq_res, sc->irq_ih); sysctl_ctx_free(&tsadc_sysctl_ctx); if (sc->tsadc_clk != NULL) clk_release(sc->tsadc_clk); if (sc->apb_pclk_clk != NULL) clk_release(sc->apb_pclk_clk); if (sc->hwreset != NULL) hwreset_array_release(sc->hwreset); if (sc->irq_res != NULL) bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res); if (sc->mem_res != NULL) bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res); return (ENXIO); } static device_method_t rk_tsadc_methods[] = { /* Device interface */ DEVMETHOD(device_probe, tsadc_probe), DEVMETHOD(device_attach, tsadc_attach), DEVMETHOD(device_detach, tsadc_detach), /* TSADC interface */ DEVMETHOD(rk_tsadc_get_temperature, tsadc_get_temp), DEVMETHOD_END }; static DEFINE_CLASS_0(rk_tsadc, rk_tsadc_driver, rk_tsadc_methods, sizeof(struct tsadc_softc)); EARLY_DRIVER_MODULE(rk_tsadc, simplebus, rk_tsadc_driver, NULL, NULL, BUS_PASS_TIMER + BUS_PASS_ORDER_LAST); diff --git a/sys/arm64/rockchip/rk_typec_phy.c b/sys/arm64/rockchip/rk_typec_phy.c index df29d514cf37..07b3ed9d93c8 100644 --- a/sys/arm64/rockchip/rk_typec_phy.c +++ b/sys/arm64/rockchip/rk_typec_phy.c @@ -1,470 +1,470 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2019 Emmanuel Vadot * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Rockchip PHY TYPEC */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include #include "syscon_if.h" #define GRF_USB3OTG_BASE(x) (0x2430 + (0x10 * x)) #define GRF_USB3OTG_CON0(x) (GRF_USB3OTG_BASE(x) + 0x0) #define GRF_USB3OTG_CON1(x) (GRF_USB3OTG_BASE(x) + 0x4) #define USB3OTG_CON1_U3_DIS (1 << 0) #define GRF_USB3PHY_BASE(x) (0x0e580 + (0xc * (x))) #define GRF_USB3PHY_CON0(x) (GRF_USB3PHY_BASE(x) + 0x0) #define USB3PHY_CON0_USB2_ONLY (1 << 3) #define GRF_USB3PHY_CON1(x) (GRF_USB3PHY_BASE(x) + 0x4) #define GRF_USB3PHY_CON2(x) (GRF_USB3PHY_BASE(x) + 0x8) #define GRF_USB3PHY_STATUS0 0x0e5c0 #define GRF_USB3PHY_STATUS1 0x0e5c4 #define CMN_PLL0_VCOCAL_INIT (0x84 << 2) #define CMN_PLL0_VCOCAL_ITER (0x85 << 2) #define CMN_PLL0_INTDIV (0x94 << 2) #define CMN_PLL0_FRACDIV (0x95 << 2) #define CMN_PLL0_HIGH_THR (0x96 << 2) #define CMN_PLL0_DSM_DIAG (0x97 << 2) #define CMN_PLL0_SS_CTRL1 (0x98 << 2) #define CMN_PLL0_SS_CTRL2 (0x99 << 2) #define CMN_DIAG_PLL0_FBH_OVRD (0x1c0 << 2) #define CMN_DIAG_PLL0_FBL_OVRD (0x1c1 << 2) #define CMN_DIAG_PLL0_OVRD (0x1c2 << 2) #define CMN_DIAG_PLL0_V2I_TUNE (0x1c5 << 2) #define CMN_DIAG_PLL0_CP_TUNE (0x1c6 << 2) #define CMN_DIAG_PLL0_LF_PROG (0x1c7 << 2) #define CMN_DIAG_HSCLK_SEL (0x1e0 << 2) #define CMN_DIAG_HSCLK_SEL_PLL_CONFIG 0x30 #define CMN_DIAG_HSCLK_SEL_PLL_MASK 0x33 #define TX_TXCC_MGNFS_MULT_000(lane) ((0x4050 | ((lane) << 9)) << 2) #define XCVR_DIAG_BIDI_CTRL(lane) ((0x40e8 | ((lane) << 9)) << 2) #define XCVR_DIAG_LANE_FCM_EN_MGN(lane) ((0x40f2 | ((lane) << 9)) << 2) #define TX_PSC_A0(lane) ((0x4100 | ((lane) << 9)) << 2) #define TX_PSC_A1(lane) ((0x4101 | ((lane) << 9)) << 2) #define TX_PSC_A2(lane) ((0x4102 | ((lane) << 9)) << 2) #define TX_PSC_A3(lane) ((0x4103 | ((lane) << 9)) << 2) #define TX_RCVDET_EN_TMR(lane) ((0x4122 | ((lane) << 9)) << 2) #define TX_RCVDET_ST_TMR(lane) ((0x4123 | ((lane) << 9)) << 2) #define RX_PSC_A0(lane) ((0x8000 | ((lane) << 9)) << 2) #define RX_PSC_A1(lane) ((0x8001 | ((lane) << 9)) << 2) #define RX_PSC_A2(lane) ((0x8002 | ((lane) << 9)) << 2) #define RX_PSC_A3(lane) ((0x8003 | ((lane) << 9)) << 2) #define RX_PSC_CAL(lane) ((0x8006 | ((lane) << 9)) << 2) #define RX_PSC_RDY(lane) ((0x8007 | ((lane) << 9)) << 2) #define RX_SIGDET_HL_FILT_TMR(lane) ((0x8090 | ((lane) << 9)) << 2) #define RX_REE_CTRL_DATA_MASK(lane) ((0x81bb | ((lane) << 9)) << 2) #define RX_DIAG_SIGDET_TUNE(lane) ((0x81dc | ((lane) << 9)) << 2) #define PMA_LANE_CFG (0xc000 << 2) #define PIN_ASSIGN_D_F 0x5100 #define DP_MODE_CTL (0xc008 << 2) #define DP_MODE_ENTER_A2 0xc104 #define PMA_CMN_CTRL1 (0xc800 << 2) #define PMA_CMN_CTRL1_READY (1 << 0) static struct ofw_compat_data compat_data[] = { { "rockchip,rk3399-typec-phy", 1 }, { NULL, 0 } }; static struct resource_spec rk_typec_phy_spec[] = { { SYS_RES_MEMORY, 0, RF_ACTIVE }, { -1, 0 } }; struct rk_typec_phy_softc { device_t dev; struct resource *res; struct syscon *grf; clk_t tcpdcore; clk_t tcpdphy_ref; hwreset_t rst_uphy; hwreset_t rst_pipe; hwreset_t rst_tcphy; int mode; int phy_ctrl_id; }; #define RK_TYPEC_PHY_READ(sc, reg) bus_read_4(sc->res, (reg)) #define RK_TYPEC_PHY_WRITE(sc, reg, val) bus_write_4(sc->res, (reg), (val)) /* Phy class and methods. */ static int rk_typec_phy_enable(struct phynode *phynode, bool enable); static int rk_typec_phy_get_mode(struct phynode *phy, int *mode); static int rk_typec_phy_set_mode(struct phynode *phy, int mode); static phynode_method_t rk_typec_phy_phynode_methods[] = { PHYNODEMETHOD(phynode_enable, rk_typec_phy_enable), PHYNODEMETHOD(phynode_usb_get_mode, rk_typec_phy_get_mode), PHYNODEMETHOD(phynode_usb_set_mode, rk_typec_phy_set_mode), PHYNODEMETHOD_END }; DEFINE_CLASS_1(rk_typec_phy_phynode, rk_typec_phy_phynode_class, rk_typec_phy_phynode_methods, sizeof(struct phynode_usb_sc), phynode_usb_class); enum RK3399_USBPHY { RK3399_TYPEC_PHY_DP = 0, RK3399_TYPEC_PHY_USB3, }; static void rk_typec_phy_set_usb2_only(struct rk_typec_phy_softc *sc, bool usb2only) { uint32_t reg; /* Disable usb3tousb2 only */ reg = SYSCON_READ_4(sc->grf, GRF_USB3PHY_CON0(sc->phy_ctrl_id)); if (usb2only) reg |= USB3PHY_CON0_USB2_ONLY; else reg &= ~USB3PHY_CON0_USB2_ONLY; /* Write Mask */ reg |= (USB3PHY_CON0_USB2_ONLY) << 16; SYSCON_WRITE_4(sc->grf, GRF_USB3PHY_CON0(sc->phy_ctrl_id), reg); /* Enable the USB3 Super Speed port */ reg = SYSCON_READ_4(sc->grf, GRF_USB3OTG_CON1(sc->phy_ctrl_id)); if (usb2only) reg |= USB3OTG_CON1_U3_DIS; else reg &= ~USB3OTG_CON1_U3_DIS; /* Write Mask */ reg |= (USB3OTG_CON1_U3_DIS) << 16; SYSCON_WRITE_4(sc->grf, GRF_USB3OTG_CON1(sc->phy_ctrl_id), reg); } static int rk_typec_phy_enable(struct phynode *phynode, bool enable) { struct rk_typec_phy_softc *sc; device_t dev; intptr_t phy; uint32_t reg; int err, retry; dev = phynode_get_device(phynode); phy = phynode_get_id(phynode); sc = device_get_softc(dev); if (phy != RK3399_TYPEC_PHY_USB3) return (ERANGE); rk_typec_phy_set_usb2_only(sc, false); err = clk_enable(sc->tcpdcore); if (err != 0) { device_printf(dev, "Could not enable clock %s\n", clk_get_name(sc->tcpdcore)); return (ENXIO); } err = clk_enable(sc->tcpdphy_ref); if (err != 0) { device_printf(dev, "Could not enable clock %s\n", clk_get_name(sc->tcpdphy_ref)); clk_disable(sc->tcpdcore); return (ENXIO); } hwreset_deassert(sc->rst_tcphy); /* 24M configuration, magic values from rockchip */ RK_TYPEC_PHY_WRITE(sc, PMA_CMN_CTRL1, 0x830); for (int i = 0; i < 4; i++) { RK_TYPEC_PHY_WRITE(sc, XCVR_DIAG_LANE_FCM_EN_MGN(i), 0x90); RK_TYPEC_PHY_WRITE(sc, TX_RCVDET_EN_TMR(i), 0x960); RK_TYPEC_PHY_WRITE(sc, TX_RCVDET_ST_TMR(i), 0x30); } reg = RK_TYPEC_PHY_READ(sc, CMN_DIAG_HSCLK_SEL); reg &= ~CMN_DIAG_HSCLK_SEL_PLL_MASK; reg |= CMN_DIAG_HSCLK_SEL_PLL_CONFIG; RK_TYPEC_PHY_WRITE(sc, CMN_DIAG_HSCLK_SEL, reg); /* PLL configuration, magic values from rockchip */ RK_TYPEC_PHY_WRITE(sc, CMN_PLL0_VCOCAL_INIT, 0xf0); RK_TYPEC_PHY_WRITE(sc, CMN_PLL0_VCOCAL_ITER, 0x18); RK_TYPEC_PHY_WRITE(sc, CMN_PLL0_INTDIV, 0xd0); RK_TYPEC_PHY_WRITE(sc, CMN_PLL0_FRACDIV, 0x4a4a); RK_TYPEC_PHY_WRITE(sc, CMN_PLL0_HIGH_THR, 0x34); RK_TYPEC_PHY_WRITE(sc, CMN_PLL0_SS_CTRL1, 0x1ee); RK_TYPEC_PHY_WRITE(sc, CMN_PLL0_SS_CTRL2, 0x7f03); RK_TYPEC_PHY_WRITE(sc, CMN_PLL0_DSM_DIAG, 0x20); RK_TYPEC_PHY_WRITE(sc, CMN_DIAG_PLL0_OVRD, 0); RK_TYPEC_PHY_WRITE(sc, CMN_DIAG_PLL0_FBH_OVRD, 0); RK_TYPEC_PHY_WRITE(sc, CMN_DIAG_PLL0_FBL_OVRD, 0); RK_TYPEC_PHY_WRITE(sc, CMN_DIAG_PLL0_V2I_TUNE, 0x7); RK_TYPEC_PHY_WRITE(sc, CMN_DIAG_PLL0_CP_TUNE, 0x45); RK_TYPEC_PHY_WRITE(sc, CMN_DIAG_PLL0_LF_PROG, 0x8); /* Configure the TX and RX line, magic values from rockchip */ RK_TYPEC_PHY_WRITE(sc, TX_PSC_A0(0), 0x7799); RK_TYPEC_PHY_WRITE(sc, TX_PSC_A1(0), 0x7798); RK_TYPEC_PHY_WRITE(sc, TX_PSC_A2(0), 0x5098); RK_TYPEC_PHY_WRITE(sc, TX_PSC_A3(0), 0x5098); RK_TYPEC_PHY_WRITE(sc, TX_TXCC_MGNFS_MULT_000(0), 0x0); RK_TYPEC_PHY_WRITE(sc, XCVR_DIAG_BIDI_CTRL(0), 0xbf); RK_TYPEC_PHY_WRITE(sc, RX_PSC_A0(1), 0xa6fd); RK_TYPEC_PHY_WRITE(sc, RX_PSC_A1(1), 0xa6fd); RK_TYPEC_PHY_WRITE(sc, RX_PSC_A2(1), 0xa410); RK_TYPEC_PHY_WRITE(sc, RX_PSC_A3(1), 0x2410); RK_TYPEC_PHY_WRITE(sc, RX_PSC_CAL(1), 0x23ff); RK_TYPEC_PHY_WRITE(sc, RX_SIGDET_HL_FILT_TMR(1), 0x13); RK_TYPEC_PHY_WRITE(sc, RX_REE_CTRL_DATA_MASK(1), 0x03e7); RK_TYPEC_PHY_WRITE(sc, RX_DIAG_SIGDET_TUNE(1), 0x1004); RK_TYPEC_PHY_WRITE(sc, RX_PSC_RDY(1), 0x2010); RK_TYPEC_PHY_WRITE(sc, XCVR_DIAG_BIDI_CTRL(1), 0xfb); RK_TYPEC_PHY_WRITE(sc, PMA_LANE_CFG, PIN_ASSIGN_D_F); RK_TYPEC_PHY_WRITE(sc, DP_MODE_CTL, DP_MODE_ENTER_A2); hwreset_deassert(sc->rst_uphy); for (retry = 10000; retry > 0; retry--) { reg = RK_TYPEC_PHY_READ(sc, PMA_CMN_CTRL1); if (reg & PMA_CMN_CTRL1_READY) break; DELAY(10); } if (retry == 0) { device_printf(sc->dev, "Timeout waiting for PMA\n"); return (ENXIO); } hwreset_deassert(sc->rst_pipe); return (0); } static int rk_typec_phy_get_mode(struct phynode *phynode, int *mode) { struct rk_typec_phy_softc *sc; intptr_t phy; device_t dev; dev = phynode_get_device(phynode); phy = phynode_get_id(phynode); sc = device_get_softc(dev); if (phy != RK3399_TYPEC_PHY_USB3) return (ERANGE); *mode = sc->mode; return (0); } static int rk_typec_phy_set_mode(struct phynode *phynode, int mode) { struct rk_typec_phy_softc *sc; intptr_t phy; device_t dev; dev = phynode_get_device(phynode); phy = phynode_get_id(phynode); sc = device_get_softc(dev); if (phy != RK3399_TYPEC_PHY_USB3) return (ERANGE); sc->mode = mode; return (0); } static int rk_typec_phy_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "Rockchip RK3399 PHY TYPEC"); return (BUS_PROBE_DEFAULT); } static int rk_typec_phy_attach(device_t dev) { struct rk_typec_phy_softc *sc; struct phynode_init_def phy_init; struct phynode *phynode; phandle_t node, usb3; phandle_t reg_prop[4]; sc = device_get_softc(dev); sc->dev = dev; node = ofw_bus_get_node(dev); /* * Find out which phy we are. * There is not property for this so we need to know the * address to use the correct GRF registers. */ if (OF_getencprop(node, "reg", reg_prop, sizeof(reg_prop)) <= 0) { device_printf(dev, "Cannot guess phy controller id\n"); return (ENXIO); } switch (reg_prop[1]) { case 0xff7c0000: sc->phy_ctrl_id = 0; break; case 0xff800000: sc->phy_ctrl_id = 1; break; default: device_printf(dev, "Unknown address %x for typec-phy\n", reg_prop[1]); return (ENXIO); } if (bus_alloc_resources(dev, rk_typec_phy_spec, &sc->res) != 0) { device_printf(dev, "cannot allocate resources for device\n"); goto fail; } if (syscon_get_by_ofw_property(dev, node, "rockchip,grf", &sc->grf) != 0) { device_printf(dev, "Cannot get syscon handle\n"); goto fail; } if (clk_get_by_ofw_name(dev, 0, "tcpdcore", &sc->tcpdcore) != 0) { device_printf(dev, "Cannot get tcpdcore clock\n"); goto fail; } if (clk_get_by_ofw_name(dev, 0, "tcpdphy-ref", &sc->tcpdphy_ref) != 0) { device_printf(dev, "Cannot get tcpdphy-ref clock\n"); goto fail; } if (hwreset_get_by_ofw_name(dev, 0, "uphy", &sc->rst_uphy) != 0) { device_printf(dev, "Cannot get uphy reset\n"); goto fail; } if (hwreset_get_by_ofw_name(dev, 0, "uphy-pipe", &sc->rst_pipe) != 0) { device_printf(dev, "Cannot get uphy-pipe reset\n"); goto fail; } if (hwreset_get_by_ofw_name(dev, 0, "uphy-tcphy", &sc->rst_tcphy) != 0) { device_printf(dev, "Cannot get uphy-tcphy reset\n"); goto fail; } /* * Make sure that the module is asserted * We need to deassert in a certain order when we enable the phy */ hwreset_assert(sc->rst_uphy); hwreset_assert(sc->rst_pipe); hwreset_assert(sc->rst_tcphy); /* Set the assigned clocks parent and freq */ if (clk_set_assigned(dev, node) != 0) { device_printf(dev, "clk_set_assigned failed\n"); goto fail; } /* Only usb3 port is supported right now */ usb3 = ofw_bus_find_child(node, "usb3-port"); if (usb3 == 0) { device_printf(dev, "Cannot find usb3-port child node\n"); goto fail; } /* If the child isn't enable attach the driver * but do not register the PHY. */ if (!ofw_bus_node_status_okay(usb3)) return (0); phy_init.id = RK3399_TYPEC_PHY_USB3; phy_init.ofw_node = usb3; phynode = phynode_create(dev, &rk_typec_phy_phynode_class, &phy_init); if (phynode == NULL) { device_printf(dev, "failed to create phy usb3-port\n"); goto fail; } if (phynode_register(phynode) == NULL) { device_printf(dev, "failed to register phy usb3-port\n"); goto fail; } OF_device_register_xref(OF_xref_from_node(usb3), dev); return (0); fail: bus_release_resources(dev, rk_typec_phy_spec, &sc->res); return (ENXIO); } static device_method_t rk_typec_phy_methods[] = { /* Device interface */ DEVMETHOD(device_probe, rk_typec_phy_probe), DEVMETHOD(device_attach, rk_typec_phy_attach), DEVMETHOD_END }; static driver_t rk_typec_phy_driver = { "rk_typec_phy", rk_typec_phy_methods, sizeof(struct rk_typec_phy_softc) }; EARLY_DRIVER_MODULE(rk_typec_phy, simplebus, rk_typec_phy_driver, 0, 0, BUS_PASS_SUPPORTDEV + BUS_PASS_ORDER_MIDDLE); MODULE_VERSION(rk_typec_phy, 1); diff --git a/sys/arm64/rockchip/rk_usb2phy.c b/sys/arm64/rockchip/rk_usb2phy.c index ec8a4ba89e37..3f6c0b19f10a 100644 --- a/sys/arm64/rockchip/rk_usb2phy.c +++ b/sys/arm64/rockchip/rk_usb2phy.c @@ -1,430 +1,430 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2019 Emmanuel Vadot * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Rockchip USB2PHY */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include "clkdev_if.h" #include "syscon_if.h" struct rk_usb2phy_reg { uint32_t offset; uint32_t enable_mask; uint32_t disable_mask; }; struct rk_usb2phy_regs { struct rk_usb2phy_reg clk_ctl; }; struct rk_usb2phy_regs rk3399_regs = { .clk_ctl = { .offset = 0x0000, /* bit 4 put pll in suspend */ .enable_mask = 0x100000, .disable_mask = 0x100010, } }; struct rk_usb2phy_regs rk3568_regs = { .clk_ctl = { .offset = 0x0008, .enable_mask = 0x100000, /* bit 4 put pll in suspend */ .disable_mask = 0x100010, } }; static struct ofw_compat_data compat_data[] = { { "rockchip,rk3399-usb2phy", (uintptr_t)&rk3399_regs }, { "rockchip,rk3568-usb2phy", (uintptr_t)&rk3568_regs }, { NULL, 0 } }; struct rk_usb2phy_softc { device_t dev; struct syscon *grf; regulator_t phy_supply; clk_t clk; int mode; }; /* Phy class and methods. */ static int rk_usb2phy_enable(struct phynode *phynode, bool enable); static int rk_usb2phy_get_mode(struct phynode *phy, int *mode); static int rk_usb2phy_set_mode(struct phynode *phy, int mode); static phynode_method_t rk_usb2phy_phynode_methods[] = { PHYNODEMETHOD(phynode_enable, rk_usb2phy_enable), PHYNODEMETHOD(phynode_usb_get_mode, rk_usb2phy_get_mode), PHYNODEMETHOD(phynode_usb_set_mode, rk_usb2phy_set_mode), PHYNODEMETHOD_END }; DEFINE_CLASS_1(rk_usb2phy_phynode, rk_usb2phy_phynode_class, rk_usb2phy_phynode_methods, sizeof(struct phynode_usb_sc), phynode_usb_class); enum RK_USBPHY { RK_USBPHY_HOST = 0, RK_USBPHY_OTG, }; static int rk_usb2phy_enable(struct phynode *phynode, bool enable) { struct rk_usb2phy_softc *sc; device_t dev; intptr_t phy; int error; dev = phynode_get_device(phynode); phy = phynode_get_id(phynode); sc = device_get_softc(dev); if (phy != RK_USBPHY_HOST) return (ERANGE); if (sc->phy_supply) { if (enable) error = regulator_enable(sc->phy_supply); else error = regulator_disable(sc->phy_supply); if (error != 0) { device_printf(dev, "Cannot %sable the regulator\n", enable ? "En" : "Dis"); goto fail; } } return (0); fail: return (ENXIO); } static int rk_usb2phy_get_mode(struct phynode *phynode, int *mode) { struct rk_usb2phy_softc *sc; intptr_t phy; device_t dev; dev = phynode_get_device(phynode); phy = phynode_get_id(phynode); sc = device_get_softc(dev); if (phy != RK_USBPHY_HOST) return (ERANGE); *mode = sc->mode; return (0); } static int rk_usb2phy_set_mode(struct phynode *phynode, int mode) { struct rk_usb2phy_softc *sc; intptr_t phy; device_t dev; dev = phynode_get_device(phynode); phy = phynode_get_id(phynode); sc = device_get_softc(dev); if (phy != RK_USBPHY_HOST) return (ERANGE); sc->mode = mode; return (0); } /* Clock class and method */ struct rk_usb2phy_clk_sc { device_t clkdev; struct syscon *grf; struct rk_usb2phy_regs *regs; }; static int rk_usb2phy_clk_init(struct clknode *clk, device_t dev) { clknode_init_parent_idx(clk, 0); return (0); } static int rk_usb2phy_clk_set_gate(struct clknode *clk, bool enable) { struct rk_usb2phy_clk_sc *sc; sc = clknode_get_softc(clk); if (enable) SYSCON_WRITE_4(sc->grf, sc->regs->clk_ctl.offset, sc->regs->clk_ctl.enable_mask); else SYSCON_WRITE_4(sc->grf, sc->regs->clk_ctl.offset, sc->regs->clk_ctl.disable_mask); return (0); } static int rk_usb2phy_clk_recalc(struct clknode *clk, uint64_t *freq) { *freq = 480000000; return (0); } static clknode_method_t rk_usb2phy_clk_clknode_methods[] = { /* Device interface */ CLKNODEMETHOD(clknode_init, rk_usb2phy_clk_init), CLKNODEMETHOD(clknode_set_gate, rk_usb2phy_clk_set_gate), CLKNODEMETHOD(clknode_recalc_freq, rk_usb2phy_clk_recalc), CLKNODEMETHOD_END }; DEFINE_CLASS_1(rk_usb2phy_clk_clknode, rk_usb2phy_clk_clknode_class, rk_usb2phy_clk_clknode_methods, sizeof(struct rk_usb2phy_clk_sc), clknode_class); static int rk_usb2phy_clk_ofw_map(struct clkdom *clkdom, uint32_t ncells, phandle_t *cells, struct clknode **clk) { if (ncells != 0) return (ERANGE); *clk = clknode_find_by_id(clkdom, 0); if (*clk == NULL) return (ENXIO); return (0); } static int rk_usb2phy_export_clock(struct rk_usb2phy_softc *devsc) { struct clknode_init_def def; struct rk_usb2phy_clk_sc *sc; const char **clknames; struct clkdom *clkdom; struct clknode *clk; clk_t clk_parent; phandle_t node; phandle_t regs[2]; int i, nclocks, ncells, error; node = ofw_bus_get_node(devsc->dev); error = ofw_bus_parse_xref_list_get_length(node, "clocks", "#clock-cells", &ncells); if (error != 0 || ncells != 1) { device_printf(devsc->dev, "couldn't find parent clock\n"); return (ENXIO); } nclocks = ofw_bus_string_list_to_array(node, "clock-output-names", &clknames); if (nclocks != 1) return (ENXIO); clkdom = clkdom_create(devsc->dev); clkdom_set_ofw_mapper(clkdom, rk_usb2phy_clk_ofw_map); memset(&def, 0, sizeof(def)); def.id = 0; def.name = clknames[0]; def.parent_names = malloc(sizeof(char *) * ncells, M_OFWPROP, M_WAITOK); for (i = 0; i < ncells; i++) { error = clk_get_by_ofw_index(devsc->dev, 0, i, &clk_parent); if (error != 0) { device_printf(devsc->dev, "cannot get clock %d\n", error); return (ENXIO); } def.parent_names[i] = clk_get_name(clk_parent); clk_release(clk_parent); } def.parent_cnt = ncells; clk = clknode_create(clkdom, &rk_usb2phy_clk_clknode_class, &def); if (clk == NULL) { device_printf(devsc->dev, "cannot create clknode\n"); return (ENXIO); } sc = clknode_get_softc(clk); sc->clkdev = device_get_parent(devsc->dev); sc->grf = devsc->grf; sc->regs = (struct rk_usb2phy_regs *)ofw_bus_search_compatible(devsc->dev, compat_data)->ocd_data; if (sc->regs->clk_ctl.offset == 0) { OF_getencprop(node, "reg", regs, sizeof(regs)); sc->regs->clk_ctl.offset = regs[0]; } clknode_register(clkdom, clk); if (clkdom_finit(clkdom) != 0) { device_printf(devsc->dev, "cannot finalize clkdom initialization\n"); return (ENXIO); } if (bootverbose) clkdom_dump(clkdom); return (0); } static int rk_usb2phy_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "Rockchip USB2PHY"); return (BUS_PROBE_DEFAULT); } static int rk_usb2phy_attach(device_t dev) { struct rk_usb2phy_softc *sc; struct phynode_init_def phy_init; struct phynode *phynode; phandle_t node, host; int err; sc = device_get_softc(dev); sc->dev = dev; node = ofw_bus_get_node(dev); if (OF_hasprop(node, "rockchip,usbgrf")) { if (syscon_get_by_ofw_property(dev, node, "rockchip,usbgrf", &sc->grf)) { device_printf(dev, "Cannot get syscon handle\n"); return (ENXIO); } } else { if (syscon_get_handle_default(dev, &sc->grf)) { device_printf(dev, "Cannot get syscon handle\n"); return (ENXIO); } } if (clk_get_by_ofw_name(dev, 0, "phyclk", &sc->clk) != 0) { device_printf(dev, "Cannot get clock\n"); return (ENXIO); } err = clk_enable(sc->clk); if (err != 0) { device_printf(dev, "Could not enable clock %s\n", clk_get_name(sc->clk)); return (ENXIO); } err = rk_usb2phy_export_clock(sc); if (err != 0) return (err); /* Only host is supported right now */ host = ofw_bus_find_child(node, "host-port"); if (host == 0) { device_printf(dev, "Cannot find host-port child node\n"); return (ENXIO); } if (!ofw_bus_node_status_okay(host)) { device_printf(dev, "host-port isn't okay\n"); return (0); } regulator_get_by_ofw_property(dev, host, "phy-supply", &sc->phy_supply); phy_init.id = RK_USBPHY_HOST; phy_init.ofw_node = host; phynode = phynode_create(dev, &rk_usb2phy_phynode_class, &phy_init); if (phynode == NULL) { device_printf(dev, "failed to create host USB2PHY\n"); return (ENXIO); } if (phynode_register(phynode) == NULL) { device_printf(dev, "failed to register host USB2PHY\n"); return (ENXIO); } OF_device_register_xref(OF_xref_from_node(host), dev); return (0); } static device_method_t rk_usb2phy_methods[] = { /* Device interface */ DEVMETHOD(device_probe, rk_usb2phy_probe), DEVMETHOD(device_attach, rk_usb2phy_attach), DEVMETHOD_END }; static driver_t rk_usb2phy_driver = { "rk_usb2phy", rk_usb2phy_methods, sizeof(struct rk_usb2phy_softc) }; EARLY_DRIVER_MODULE(rk_usb2phy, simplebus, rk_usb2phy_driver, 0, 0, BUS_PASS_SUPPORTDEV + BUS_PASS_ORDER_MIDDLE); MODULE_VERSION(rk_usb2phy, 1); diff --git a/sys/arm64/rockchip/rk_usbphy.c b/sys/arm64/rockchip/rk_usbphy.c index f91c8167df62..f9acbdff6d79 100644 --- a/sys/arm64/rockchip/rk_usbphy.c +++ b/sys/arm64/rockchip/rk_usbphy.c @@ -1,300 +1,300 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2019 Michal Meloun * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include #include -#include +#include #include #include "phynode_if.h" #include "phynode_usb_if.h" #include "syscon_if.h" /* Phy registers */ #define UOC_CON0 0x00 #define UOC_CON0_SIDDQ (1 << 13) #define UOC_CON0_DISABLE (1 << 4) #define UOC_CON0_COMMON_ON_N (1 << 0) #define UOC_CON2 0x08 #define UOC_CON2_SOFT_CON_SEL (1 << 2) #define UOC_CON3 0x0c #define WR4(_sc, _r, _v) bus_write_4((_sc)->mem_res, (_r), (_v)) #define RD4(_sc, _r) bus_read_4((_sc)->mem_res, (_r)) static struct ofw_compat_data compat_data[] = { {"rockchip,rk3288-usb-phy", 1}, {NULL, 0}, }; struct rk_usbphy_softc { device_t dev; }; struct rk_phynode_sc { struct phynode_usb_sc usb_sc; uint32_t base; int mode; clk_t clk; hwreset_t hwreset; regulator_t supply_vbus; struct syscon *syscon; }; static int rk_phynode_phy_enable(struct phynode *phy, bool enable) { struct rk_phynode_sc *sc; int rv; sc = phynode_get_softc(phy); rv = SYSCON_MODIFY_4(sc->syscon, sc->base + UOC_CON0, UOC_CON0_SIDDQ << 16 | UOC_CON0_SIDDQ, enable ? 0 : UOC_CON0_SIDDQ); return (rv); } static int rk_phynode_get_mode(struct phynode *phynode, int *mode) { struct rk_phynode_sc *sc; sc = phynode_get_softc(phynode); *mode = sc->mode; return (0); } static int rk_phynode_set_mode(struct phynode *phynode, int mode) { struct rk_phynode_sc *sc; sc = phynode_get_softc(phynode); sc->mode = mode; return (0); } /* Phy controller class and methods. */ static phynode_method_t rk_phynode_methods[] = { PHYNODEUSBMETHOD(phynode_enable, rk_phynode_phy_enable), PHYNODEMETHOD(phynode_usb_get_mode, rk_phynode_get_mode), PHYNODEMETHOD(phynode_usb_set_mode, rk_phynode_set_mode), PHYNODEUSBMETHOD_END }; DEFINE_CLASS_1(rk_phynode, rk_phynode_class, rk_phynode_methods, sizeof(struct rk_phynode_sc), phynode_usb_class); static int rk_usbphy_init_phy(struct rk_usbphy_softc *sc, phandle_t node) { struct phynode *phynode; struct phynode_init_def phy_init; struct rk_phynode_sc *phy_sc; int rv; uint32_t base; clk_t clk; hwreset_t hwreset; regulator_t supply_vbus; struct syscon *syscon; clk = NULL; hwreset = NULL; supply_vbus = NULL; rv = OF_getencprop(node, "reg", &base, sizeof(base)); if (rv <= 0) { device_printf(sc->dev, "cannot get 'reg' property.\n"); goto fail; } /* FDT resources. All are optional. */ rv = clk_get_by_ofw_name(sc->dev, node, "phyclk", &clk); if (rv != 0 && rv != ENOENT) { device_printf(sc->dev, "cannot get 'phyclk' clock.\n"); goto fail; } rv = hwreset_get_by_ofw_name(sc->dev, node, "phy-reset", &hwreset); if (rv != 0 && rv != ENOENT) { device_printf(sc->dev, "Cannot get 'phy-reset' reset\n"); goto fail; } rv = regulator_get_by_ofw_property(sc->dev, node, "vbus-supply", &supply_vbus); if (rv != 0 && rv != ENOENT) { device_printf(sc->dev, "Cannot get 'vbus' regulator.\n"); goto fail; } rv = SYSCON_GET_HANDLE(sc->dev, &syscon); if (rv != 0) { device_printf(sc->dev, "Cannot get parent syscon\n"); goto fail; } /* Init HW resources */ if (hwreset != NULL) { rv = hwreset_assert(hwreset); if (rv != 0) { device_printf(sc->dev, "Cannot assert reset\n"); goto fail; } } if (clk != NULL) { rv = clk_enable(clk); if (rv != 0) { device_printf(sc->dev, "Cannot enable 'phyclk' clock.\n"); goto fail; } } if (hwreset != NULL) { rv = hwreset_deassert(hwreset); if (rv != 0) { device_printf(sc->dev, "Cannot deassert reset\n"); goto fail; } } /* Create and register phy. */ bzero(&phy_init, sizeof(phy_init)); phy_init.id = 1; phy_init.ofw_node = node; phynode = phynode_create(sc->dev, &rk_phynode_class, &phy_init); if (phynode == NULL) { device_printf(sc->dev, "Cannot create phy.\n"); return (ENXIO); } phy_sc = phynode_get_softc(phynode); phy_sc->base = base; phy_sc->clk = clk; phy_sc->hwreset = hwreset; phy_sc->supply_vbus = supply_vbus; phy_sc->syscon = syscon; if (phynode_register(phynode) == NULL) { device_printf(sc->dev, "Cannot register phy.\n"); return (ENXIO); } /* XXX It breaks boot */ /* rk_phynode_phy_enable(phynode, 1); */ return (0); fail: if (supply_vbus != NULL) regulator_release(supply_vbus); if (clk != NULL) clk_release(clk); if (hwreset != NULL) hwreset_release(hwreset); return (ENXIO); } static int rk_usbphy_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "RockChip USB Phy"); return (BUS_PROBE_DEFAULT); } static int rk_usbphy_attach(device_t dev) { struct rk_usbphy_softc *sc; phandle_t node, child; int rv; sc = device_get_softc(dev); sc->dev = dev; node = ofw_bus_get_node(sc->dev); /* Attach child devices */ for (child = OF_child(node); child > 0; child = OF_peer(child)) { rv = rk_usbphy_init_phy(sc, child); if (rv != 0) goto fail; } return (bus_generic_attach(dev)); fail: return (ENXIO); } static int rk_usbphy_detach(device_t dev) { return (0); } static device_method_t rk_usbphy_methods[] = { /* Device interface */ DEVMETHOD(device_probe, rk_usbphy_probe), DEVMETHOD(device_attach, rk_usbphy_attach), DEVMETHOD(device_detach, rk_usbphy_detach), DEVMETHOD_END }; static DEFINE_CLASS_0(rk_usbphy, rk_usbphy_driver, rk_usbphy_methods, sizeof(struct rk_usbphy_softc)); EARLY_DRIVER_MODULE(rk_usbphy, simplebus, rk_usbphy_driver, NULL, NULL, BUS_PASS_TIMER + BUS_PASS_ORDER_LAST); diff --git a/sys/conf/files b/sys/conf/files index f63f844e7942..6a089de5bb98 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,5240 +1,5240 @@ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and # dependency lines other than the first are silently ignored. # acpi_quirks.h optional acpi \ dependency "$S/tools/acpi_quirks2h.awk $S/dev/acpica/acpi_quirks" \ compile-with "${AWK} -f $S/tools/acpi_quirks2h.awk $S/dev/acpica/acpi_quirks" \ no-obj no-implicit-rule before-depend \ clean "acpi_quirks.h" bhnd_nvram_map.h optional bhnd \ dependency "$S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/tools/nvram_map_gen.awk $S/dev/bhnd/nvram/nvram_map" \ compile-with "sh $S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/nvram/nvram_map -h" \ no-obj no-implicit-rule before-depend \ clean "bhnd_nvram_map.h" bhnd_nvram_map_data.h optional bhnd \ dependency "$S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/tools/nvram_map_gen.awk $S/dev/bhnd/nvram/nvram_map" \ compile-with "sh $S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/nvram/nvram_map -d" \ no-obj no-implicit-rule before-depend \ clean "bhnd_nvram_map_data.h" fdt_static_dtb.h optional fdt fdt_dtb_static \ compile-with "sh -c 'MACHINE=${MACHINE} $S/tools/fdt/make_dtbh.sh ${FDT_DTS_FILE} ${.CURDIR}'" \ dependency "${FDT_DTS_FILE:T:R}.dtb" \ no-obj no-implicit-rule before-depend \ clean "fdt_static_dtb.h" feeder_eq_gen.h optional sound \ dependency "$S/tools/sound/feeder_eq_mkfilter.awk" \ compile-with "${AWK} -f $S/tools/sound/feeder_eq_mkfilter.awk -- ${FEEDER_EQ_PRESETS} > feeder_eq_gen.h" \ no-obj no-implicit-rule before-depend \ clean "feeder_eq_gen.h" feeder_rate_gen.h optional sound \ dependency "$S/tools/sound/feeder_rate_mkfilter.awk" \ compile-with "${AWK} -f $S/tools/sound/feeder_rate_mkfilter.awk -- ${FEEDER_RATE_PRESETS} > feeder_rate_gen.h" \ no-obj no-implicit-rule before-depend \ clean "feeder_rate_gen.h" font.h optional sc_dflt_font \ compile-with "uudecode < ${SRCTOP}/share/syscons/fonts/${SC_DFLT_FONT}-8x16.fnt && file2c 'u_char dflt_font_16[16*256] = {' '};' < ${SC_DFLT_FONT}-8x16 > font.h && uudecode < ${SRCTOP}/share/syscons/fonts/${SC_DFLT_FONT}-8x14.fnt && file2c 'u_char dflt_font_14[14*256] = {' '};' < ${SC_DFLT_FONT}-8x14 >> font.h && uudecode < ${SRCTOP}/share/syscons/fonts/${SC_DFLT_FONT}-8x8.fnt && file2c 'u_char dflt_font_8[8*256] = {' '};' < ${SC_DFLT_FONT}-8x8 >> font.h" \ no-obj no-implicit-rule before-depend \ clean "font.h ${SC_DFLT_FONT}-8x14 ${SC_DFLT_FONT}-8x16 ${SC_DFLT_FONT}-8x8" snd_fxdiv_gen.h optional sound \ dependency "$S/tools/sound/snd_fxdiv_gen.awk" \ compile-with "${AWK} -f $S/tools/sound/snd_fxdiv_gen.awk -- > snd_fxdiv_gen.h" \ no-obj no-implicit-rule before-depend \ clean "snd_fxdiv_gen.h" miidevs.h optional miibus | mii \ dependency "$S/tools/miidevs2h.awk $S/dev/mii/miidevs" \ compile-with "${AWK} -f $S/tools/miidevs2h.awk $S/dev/mii/miidevs" \ no-obj no-implicit-rule before-depend \ clean "miidevs.h" kbdmuxmap.h optional kbdmux_dflt_keymap \ compile-with "${KEYMAP} -L ${KBDMUX_DFLT_KEYMAP} | ${KEYMAP_FIX} > ${.TARGET}" \ no-obj no-implicit-rule before-depend \ clean "kbdmuxmap.h" teken_state.h optional sc | vt \ dependency "$S/teken/gensequences $S/teken/sequences" \ compile-with "${AWK} -f $S/teken/gensequences $S/teken/sequences > teken_state.h" \ no-obj no-implicit-rule before-depend \ clean "teken_state.h" ukbdmap.h optional ukbd_dflt_keymap \ compile-with "${KEYMAP} -L ${UKBD_DFLT_KEYMAP} | ${KEYMAP_FIX} > ${.TARGET}" \ no-obj no-implicit-rule before-depend \ clean "ukbdmap.h" usbdevs.h optional usb | hid \ dependency "$S/tools/usbdevs2h.awk $S/dev/usb/usbdevs" \ compile-with "${AWK} -f $S/tools/usbdevs2h.awk $S/dev/usb/usbdevs -h" \ no-obj no-implicit-rule before-depend \ clean "usbdevs.h" usbdevs_data.h optional usb \ dependency "$S/tools/usbdevs2h.awk $S/dev/usb/usbdevs" \ compile-with "${AWK} -f $S/tools/usbdevs2h.awk $S/dev/usb/usbdevs -d" \ no-obj no-implicit-rule before-depend \ clean "usbdevs_data.h" sdiodevs.h optional mmccam \ dependency "$S/tools/sdiodevs2h.awk $S/dev/sdio/sdiodevs" \ compile-with "${AWK} -f $S/tools/sdiodevs2h.awk $S/dev/sdio/sdiodevs -h" \ no-obj no-implicit-rule before-depend \ clean "sdiodevs.h" sdiodevs_data.h optional mmccam \ dependency "$S/tools/sdiodevs2h.awk $S/dev/sdio/sdiodevs" \ compile-with "${AWK} -f $S/tools/sdiodevs2h.awk $S/dev/sdio/sdiodevs -d" \ no-obj no-implicit-rule before-depend \ clean "sdiodevs_data.h" cam/cam.c optional scbus cam/cam_compat.c optional scbus cam/cam_iosched.c optional scbus cam/cam_periph.c optional scbus cam/cam_queue.c optional scbus cam/cam_sim.c optional scbus cam/cam_xpt.c optional scbus cam/ata/ata_all.c optional scbus cam/ata/ata_xpt.c optional scbus cam/ata/ata_pmp.c optional scbus cam/nvme/nvme_all.c optional scbus cam/nvme/nvme_da.c optional nda | da cam/nvme/nvme_xpt.c optional scbus cam/scsi/scsi_xpt.c optional scbus cam/scsi/scsi_all.c optional scbus cam/scsi/scsi_cd.c optional cd cam/scsi/scsi_ch.c optional ch cam/ata/ata_da.c optional ada | da cam/ctl/ctl.c optional ctl cam/ctl/ctl_backend.c optional ctl cam/ctl/ctl_backend_block.c optional ctl cam/ctl/ctl_backend_ramdisk.c optional ctl cam/ctl/ctl_cmd_table.c optional ctl cam/ctl/ctl_frontend.c optional ctl cam/ctl/ctl_frontend_cam_sim.c optional ctl cam/ctl/ctl_frontend_ioctl.c optional ctl cam/ctl/ctl_frontend_iscsi.c optional ctl cfiscsi cam/ctl/ctl_ha.c optional ctl cam/ctl/ctl_scsi_all.c optional ctl cam/ctl/ctl_tpc.c optional ctl cam/ctl/ctl_tpc_local.c optional ctl cam/ctl/ctl_error.c optional ctl cam/ctl/ctl_util.c optional ctl cam/ctl/scsi_ctl.c optional ctl cam/mmc/mmc_xpt.c optional scbus mmccam cam/mmc/mmc_sim.c optional scbus mmccam cam/mmc/mmc_sim_if.m optional scbus mmccam cam/mmc/mmc_da.c optional scbus mmccam da cam/scsi/scsi_da.c optional da cam/scsi/scsi_pass.c optional pass cam/scsi/scsi_pt.c optional pt cam/scsi/scsi_sa.c optional sa cam/scsi/scsi_enc.c optional ses cam/scsi/scsi_enc_ses.c optional ses cam/scsi/scsi_enc_safte.c optional ses cam/scsi/scsi_sg.c optional sg cam/scsi/scsi_targ_bh.c optional targbh cam/scsi/scsi_target.c optional targ cam/scsi/smp_all.c optional scbus # shared between zfs and dtrace cddl/compat/opensolaris/kern/opensolaris.c optional dtrace compile-with "${CDDL_C}" cddl/compat/opensolaris/kern/opensolaris_proc.c optional zfs | dtrace compile-with "${CDDL_C}" contrib/openzfs/module/os/freebsd/spl/spl_misc.c optional zfs | dtrace compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_cmn_err.c optional zfs | dtrace compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_taskq.c optional zfs | dtrace compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_kmem.c optional zfs | dtrace compile-with "${ZFS_C}" #zfs solaris portability layer contrib/openzfs/module/os/freebsd/spl/acl_common.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/callb.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/list.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_acl.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_dtrace.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_kstat.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_policy.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_procfs_list.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_string.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_sunddi.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_sysevent.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_uio.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_vfs.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_vm.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_zlib.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_zone.c optional zfs compile-with "${ZFS_C}" # zfs specific #zfs avl contrib/openzfs/module/avl/avl.c optional zfs compile-with "${ZFS_C}" # zfs lua support contrib/openzfs/module/lua/lapi.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lauxlib.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lbaselib.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lcode.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lcompat.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lcorolib.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lctype.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/ldebug.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/ldo.c optional zfs compile-with "${ZFS_C} ${NO_WINFINITE_RECURSION}" contrib/openzfs/module/lua/lfunc.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lgc.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/llex.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lmem.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lobject.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lopcodes.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lparser.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lstate.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lstring.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lstrlib.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/ltable.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/ltablib.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/ltm.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lvm.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lzio.c optional zfs compile-with "${ZFS_C}" # zfs nvpair support contrib/openzfs/module/nvpair/fnvpair.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/nvpair/nvpair.c optional zfs compile-with "${ZFS_RPC_C} ${NO_WSTRINGOP_OVERREAD}" contrib/openzfs/module/nvpair/nvpair_alloc_fixed.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/nvpair/nvpair_alloc_spl.c optional zfs compile-with "${ZFS_C}" #zfs platform compatibility code contrib/openzfs/module/os/freebsd/zfs/abd_os.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/arc_os.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/crypto_os.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/dmu_os.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/event_os.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/hkdf.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/kmod_core.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/spa_os.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/sysctl_os.c optional zfs compile-with "${ZFS_C} -include $S/modules/zfs/zfs_config.h" contrib/openzfs/module/os/freebsd/zfs/vdev_file.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/vdev_label_os.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/vdev_geom.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zfs_acl.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zfs_debug.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zfs_dir.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zfs_file_os.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zfs_ioctl_compat.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zfs_ioctl_os.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zfs_racct.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zfs_znode.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zio_crypt.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zvol_os.c optional zfs compile-with "${ZFS_C}" #zfs unicode support contrib/openzfs/module/unicode/uconv.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/unicode/u8_textprep.c optional zfs compile-with "${ZFS_C}" #zfs checksums / zcommon contrib/openzfs/module/zcommon/cityhash.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zcommon/zfeature_common.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zcommon/zfs_comutil.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zcommon/zfs_deleg.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zcommon/zfs_fletcher.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zcommon/zfs_fletcher_superscalar.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zcommon/zfs_fletcher_superscalar4.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zcommon/zfs_namecheck.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zcommon/zfs_prop.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zcommon/zpool_prop.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zcommon/zprop_common.c optional zfs compile-with "${ZFS_C}" # zfs edon-r hash support contrib/openzfs/module/icp/algs/edonr/edonr.c optional zfs compile-with "${ZFS_C}" # zfs blake3 hash support contrib/openzfs/module/icp/algs/blake3/blake3.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/icp/algs/blake3/blake3_generic.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/icp/algs/blake3/blake3_impl.c optional zfs compile-with "${ZFS_C}" # zfs sha2 hash support contrib/openzfs/module/icp/algs/sha2/sha2_generic.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/icp/algs/sha2/sha256_impl.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/icp/algs/sha2/sha512_impl.c optional zfs compile-with "${ZFS_C}" #zfs core common code contrib/openzfs/module/zfs/abd.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/aggsum.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/arc.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/blake3_zfs.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/blkptr.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/bplist.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/bpobj.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/bptree.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/brt.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/btree.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/bqueue.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dbuf.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dbuf_stats.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dataset_kstats.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/ddt.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/ddt_zap.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dmu.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dmu_diff.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dmu_object.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dmu_objset.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dmu_recv.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dmu_redact.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dmu_send.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dmu_traverse.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dmu_tx.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dmu_zfetch.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dnode.c optional zfs compile-with "${ZFS_C} ${NO_WUNUSED_BUT_SET_VARIABLE}" \ warning "kernel contains CDDL licensed ZFS filesystem" contrib/openzfs/module/zfs/dnode_sync.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dsl_bookmark.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dsl_crypt.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dsl_dataset.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dsl_deadlist.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dsl_deleg.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dsl_destroy.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dsl_dir.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dsl_pool.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dsl_prop.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dsl_scan.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dsl_synctask.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dsl_userhold.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/edonr_zfs.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/fm.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/gzip.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/lzjb.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/lz4.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/lz4_zfs.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/metaslab.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/mmp.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/multilist.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/objlist.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/pathname.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/range_tree.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/refcount.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/rrwlock.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/sa.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/sha2_zfs.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/skein_zfs.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/spa.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/spa_checkpoint.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/spa_config.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/spa_errlog.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/spa_history.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/spa_log_spacemap.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/spa_misc.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/spa_stats.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/space_map.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/space_reftree.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/txg.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/uberblock.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/unique.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_draid.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_draid_rand.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_indirect.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_indirect_births.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_indirect_mapping.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_initialize.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_label.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_mirror.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_missing.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_queue.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_raidz.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_raidz_math.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_raidz_math_scalar.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_rebuild.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_removal.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_root.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_trim.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zap.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zap_leaf.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zap_micro.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zcp.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zcp_get.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zcp_global.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zcp_iter.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zcp_set.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zcp_synctask.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfeature.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfs_byteswap.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfs_chksum.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfs_fm.c optional zfs compile-with "${ZFS_C} ${NO_WUNUSED_BUT_SET_VARIABLE}" contrib/openzfs/module/zfs/zfs_fuid.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfs_impl.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfs_ioctl.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfs_log.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfs_onexit.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfs_quota.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfs_ratelimit.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfs_replay.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfs_rlock.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfs_sa.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfs_vnops.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zstd/zfs_zstd.c optional zfs zstdio compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zil.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zio.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zio_checksum.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zio_compress.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zio_inject.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zle.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zrlock.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zthr.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zvol.c optional zfs compile-with "${ZFS_C}" # dtrace specific cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c optional dtrace compile-with "${DTRACE_C}" \ warning "kernel contains CDDL licensed DTRACE" cddl/contrib/opensolaris/uts/common/dtrace/dtrace_xoroshiro128_plus.c optional dtrace compile-with "${DTRACE_C}" cddl/dev/dtmalloc/dtmalloc.c optional dtmalloc | dtraceall compile-with "${CDDL_C}" cddl/dev/profile/profile.c optional dtrace_profile | dtraceall compile-with "${CDDL_C}" cddl/dev/sdt/sdt.c optional dtrace_sdt | dtraceall compile-with "${CDDL_C}" cddl/dev/fbt/fbt.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}" cddl/dev/systrace/systrace.c optional dtrace_systrace | dtraceall compile-with "${CDDL_C}" cddl/dev/prototype.c optional dtrace_prototype | dtraceall compile-with "${CDDL_C}" fs/nfsclient/nfs_clkdtrace.c optional dtnfscl nfscl | dtraceall nfscl compile-with "${CDDL_C}" compat/freebsd32/freebsd32_abort2.c optional compat_freebsd32 compat/freebsd32/freebsd32_capability.c optional compat_freebsd32 compat/freebsd32/freebsd32_ioctl.c optional compat_freebsd32 compat/freebsd32/freebsd32_misc.c optional compat_freebsd32 compat/freebsd32/freebsd32_syscalls.c optional compat_freebsd32 compat/freebsd32/freebsd32_sysent.c optional compat_freebsd32 contrib/ck/src/ck_array.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_barrier_centralized.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_barrier_combining.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_barrier_dissemination.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_barrier_mcs.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_barrier_tournament.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_epoch.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_hp.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_hs.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_ht.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_rhs.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/dev/acpica/common/ahids.c optional acpi acpi_debug contrib/dev/acpica/common/ahuuids.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbcmds.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbconvert.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbdisply.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbexec.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbhistry.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbinput.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbmethod.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbnames.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbobject.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbstats.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbtest.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbutils.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbxface.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmbuffer.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmcstyle.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmdeferred.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmnames.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmopcode.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmresrc.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmresrcl.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmresrcl2.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmresrcs.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmutils.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmwalk.c optional acpi acpi_debug contrib/dev/acpica/components/dispatcher/dsargs.c optional acpi contrib/dev/acpica/components/dispatcher/dscontrol.c optional acpi contrib/dev/acpica/components/dispatcher/dsdebug.c optional acpi contrib/dev/acpica/components/dispatcher/dsfield.c optional acpi contrib/dev/acpica/components/dispatcher/dsinit.c optional acpi contrib/dev/acpica/components/dispatcher/dsmethod.c optional acpi contrib/dev/acpica/components/dispatcher/dsmthdat.c optional acpi contrib/dev/acpica/components/dispatcher/dsobject.c optional acpi contrib/dev/acpica/components/dispatcher/dsopcode.c optional acpi contrib/dev/acpica/components/dispatcher/dspkginit.c optional acpi contrib/dev/acpica/components/dispatcher/dsutils.c optional acpi contrib/dev/acpica/components/dispatcher/dswexec.c optional acpi contrib/dev/acpica/components/dispatcher/dswload.c optional acpi contrib/dev/acpica/components/dispatcher/dswload2.c optional acpi contrib/dev/acpica/components/dispatcher/dswscope.c optional acpi contrib/dev/acpica/components/dispatcher/dswstate.c optional acpi contrib/dev/acpica/components/events/evevent.c optional acpi contrib/dev/acpica/components/events/evglock.c optional acpi contrib/dev/acpica/components/events/evgpe.c optional acpi contrib/dev/acpica/components/events/evgpeblk.c optional acpi contrib/dev/acpica/components/events/evgpeinit.c optional acpi contrib/dev/acpica/components/events/evgpeutil.c optional acpi contrib/dev/acpica/components/events/evhandler.c optional acpi contrib/dev/acpica/components/events/evmisc.c optional acpi contrib/dev/acpica/components/events/evregion.c optional acpi contrib/dev/acpica/components/events/evrgnini.c optional acpi contrib/dev/acpica/components/events/evsci.c optional acpi contrib/dev/acpica/components/events/evxface.c optional acpi contrib/dev/acpica/components/events/evxfevnt.c optional acpi contrib/dev/acpica/components/events/evxfgpe.c optional acpi contrib/dev/acpica/components/events/evxfregn.c optional acpi contrib/dev/acpica/components/executer/exconcat.c optional acpi contrib/dev/acpica/components/executer/exconfig.c optional acpi contrib/dev/acpica/components/executer/exconvrt.c optional acpi contrib/dev/acpica/components/executer/excreate.c optional acpi contrib/dev/acpica/components/executer/exdebug.c optional acpi contrib/dev/acpica/components/executer/exdump.c optional acpi contrib/dev/acpica/components/executer/exfield.c optional acpi contrib/dev/acpica/components/executer/exfldio.c optional acpi contrib/dev/acpica/components/executer/exmisc.c optional acpi contrib/dev/acpica/components/executer/exmutex.c optional acpi contrib/dev/acpica/components/executer/exnames.c optional acpi contrib/dev/acpica/components/executer/exoparg1.c optional acpi contrib/dev/acpica/components/executer/exoparg2.c optional acpi contrib/dev/acpica/components/executer/exoparg3.c optional acpi contrib/dev/acpica/components/executer/exoparg6.c optional acpi contrib/dev/acpica/components/executer/exprep.c optional acpi contrib/dev/acpica/components/executer/exregion.c optional acpi contrib/dev/acpica/components/executer/exresnte.c optional acpi contrib/dev/acpica/components/executer/exresolv.c optional acpi contrib/dev/acpica/components/executer/exresop.c optional acpi contrib/dev/acpica/components/executer/exserial.c optional acpi contrib/dev/acpica/components/executer/exstore.c optional acpi contrib/dev/acpica/components/executer/exstoren.c optional acpi contrib/dev/acpica/components/executer/exstorob.c optional acpi contrib/dev/acpica/components/executer/exsystem.c optional acpi contrib/dev/acpica/components/executer/extrace.c optional acpi contrib/dev/acpica/components/executer/exutils.c optional acpi contrib/dev/acpica/components/hardware/hwacpi.c optional acpi contrib/dev/acpica/components/hardware/hwesleep.c optional acpi contrib/dev/acpica/components/hardware/hwgpe.c optional acpi contrib/dev/acpica/components/hardware/hwpci.c optional acpi contrib/dev/acpica/components/hardware/hwregs.c optional acpi contrib/dev/acpica/components/hardware/hwsleep.c optional acpi contrib/dev/acpica/components/hardware/hwtimer.c optional acpi contrib/dev/acpica/components/hardware/hwvalid.c optional acpi contrib/dev/acpica/components/hardware/hwxface.c optional acpi contrib/dev/acpica/components/hardware/hwxfsleep.c optional acpi contrib/dev/acpica/components/namespace/nsaccess.c optional acpi \ compile-with "${NORMAL_C} ${NO_WUNUSED_BUT_SET_VARIABLE}" contrib/dev/acpica/components/namespace/nsalloc.c optional acpi contrib/dev/acpica/components/namespace/nsarguments.c optional acpi contrib/dev/acpica/components/namespace/nsconvert.c optional acpi contrib/dev/acpica/components/namespace/nsdump.c optional acpi contrib/dev/acpica/components/namespace/nseval.c optional acpi contrib/dev/acpica/components/namespace/nsinit.c optional acpi contrib/dev/acpica/components/namespace/nsload.c optional acpi contrib/dev/acpica/components/namespace/nsnames.c optional acpi contrib/dev/acpica/components/namespace/nsobject.c optional acpi contrib/dev/acpica/components/namespace/nsparse.c optional acpi contrib/dev/acpica/components/namespace/nspredef.c optional acpi contrib/dev/acpica/components/namespace/nsprepkg.c optional acpi contrib/dev/acpica/components/namespace/nsrepair.c optional acpi contrib/dev/acpica/components/namespace/nsrepair2.c optional acpi contrib/dev/acpica/components/namespace/nssearch.c optional acpi contrib/dev/acpica/components/namespace/nsutils.c optional acpi contrib/dev/acpica/components/namespace/nswalk.c optional acpi contrib/dev/acpica/components/namespace/nsxfeval.c optional acpi contrib/dev/acpica/components/namespace/nsxfname.c optional acpi contrib/dev/acpica/components/namespace/nsxfobj.c optional acpi contrib/dev/acpica/components/parser/psargs.c optional acpi contrib/dev/acpica/components/parser/psloop.c optional acpi contrib/dev/acpica/components/parser/psobject.c optional acpi contrib/dev/acpica/components/parser/psopcode.c optional acpi contrib/dev/acpica/components/parser/psopinfo.c optional acpi contrib/dev/acpica/components/parser/psparse.c optional acpi contrib/dev/acpica/components/parser/psscope.c optional acpi contrib/dev/acpica/components/parser/pstree.c optional acpi contrib/dev/acpica/components/parser/psutils.c optional acpi contrib/dev/acpica/components/parser/pswalk.c optional acpi contrib/dev/acpica/components/parser/psxface.c optional acpi contrib/dev/acpica/components/resources/rsaddr.c optional acpi contrib/dev/acpica/components/resources/rscalc.c optional acpi contrib/dev/acpica/components/resources/rscreate.c optional acpi contrib/dev/acpica/components/resources/rsdump.c optional acpi acpi_debug contrib/dev/acpica/components/resources/rsdumpinfo.c optional acpi contrib/dev/acpica/components/resources/rsinfo.c optional acpi contrib/dev/acpica/components/resources/rsio.c optional acpi contrib/dev/acpica/components/resources/rsirq.c optional acpi contrib/dev/acpica/components/resources/rslist.c optional acpi contrib/dev/acpica/components/resources/rsmemory.c optional acpi contrib/dev/acpica/components/resources/rsmisc.c optional acpi contrib/dev/acpica/components/resources/rsserial.c optional acpi contrib/dev/acpica/components/resources/rsutils.c optional acpi contrib/dev/acpica/components/resources/rsxface.c optional acpi contrib/dev/acpica/components/tables/tbdata.c optional acpi contrib/dev/acpica/components/tables/tbfadt.c optional acpi contrib/dev/acpica/components/tables/tbfind.c optional acpi contrib/dev/acpica/components/tables/tbinstal.c optional acpi contrib/dev/acpica/components/tables/tbprint.c optional acpi contrib/dev/acpica/components/tables/tbutils.c optional acpi contrib/dev/acpica/components/tables/tbxface.c optional acpi contrib/dev/acpica/components/tables/tbxfload.c optional acpi contrib/dev/acpica/components/tables/tbxfroot.c optional acpi contrib/dev/acpica/components/utilities/utaddress.c optional acpi contrib/dev/acpica/components/utilities/utalloc.c optional acpi contrib/dev/acpica/components/utilities/utascii.c optional acpi contrib/dev/acpica/components/utilities/utbuffer.c optional acpi contrib/dev/acpica/components/utilities/utcache.c optional acpi contrib/dev/acpica/components/utilities/utcksum.c optional acpi contrib/dev/acpica/components/utilities/utcopy.c optional acpi contrib/dev/acpica/components/utilities/utdebug.c optional acpi contrib/dev/acpica/components/utilities/utdecode.c optional acpi contrib/dev/acpica/components/utilities/utdelete.c optional acpi contrib/dev/acpica/components/utilities/uterror.c optional acpi contrib/dev/acpica/components/utilities/uteval.c optional acpi contrib/dev/acpica/components/utilities/utexcep.c optional acpi contrib/dev/acpica/components/utilities/utglobal.c optional acpi contrib/dev/acpica/components/utilities/uthex.c optional acpi contrib/dev/acpica/components/utilities/utids.c optional acpi contrib/dev/acpica/components/utilities/utinit.c optional acpi contrib/dev/acpica/components/utilities/utlock.c optional acpi contrib/dev/acpica/components/utilities/utmath.c optional acpi contrib/dev/acpica/components/utilities/utmisc.c optional acpi contrib/dev/acpica/components/utilities/utmutex.c optional acpi contrib/dev/acpica/components/utilities/utnonansi.c optional acpi contrib/dev/acpica/components/utilities/utobject.c optional acpi contrib/dev/acpica/components/utilities/utosi.c optional acpi contrib/dev/acpica/components/utilities/utownerid.c optional acpi contrib/dev/acpica/components/utilities/utpredef.c optional acpi contrib/dev/acpica/components/utilities/utresdecode.c optional acpi acpi_debug contrib/dev/acpica/components/utilities/utresrc.c optional acpi contrib/dev/acpica/components/utilities/utstate.c optional acpi contrib/dev/acpica/components/utilities/utstring.c optional acpi contrib/dev/acpica/components/utilities/utstrsuppt.c optional acpi contrib/dev/acpica/components/utilities/utstrtoul64.c optional acpi contrib/dev/acpica/components/utilities/utuuid.c optional acpi acpi_debug contrib/dev/acpica/components/utilities/utxface.c optional acpi contrib/dev/acpica/components/utilities/utxferror.c optional acpi contrib/dev/acpica/components/utilities/utxfinit.c optional acpi contrib/dev/acpica/os_specific/service_layers/osgendbg.c optional acpi acpi_debug netpfil/ipfilter/netinet/fil.c optional ipfilter inet \ compile-with "${NORMAL_C} ${NO_WSELF_ASSIGN} -Wno-unused -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_auth.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_fil_freebsd.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_frag.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_log.c optional ipfilter inet \ compile-with "${NORMAL_C} -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_nat.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_proxy.c optional ipfilter inet \ compile-with "${NORMAL_C} ${NO_WSELF_ASSIGN} -Wno-unused -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_state.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_lookup.c optional ipfilter inet \ compile-with "${NORMAL_C} ${NO_WSELF_ASSIGN} -Wno-unused -Wno-error -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_pool.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_htable.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/netpfil/ipfilter ${NO_WTAUTOLOGICAL_POINTER_COMPARE}" netpfil/ipfilter/netinet/ip_sync.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/mlfk_ipl.c optional ipfilter inet \ compile-with "${NORMAL_C} -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_nat6.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_rules.c optional ipfilter inet \ compile-with "${NORMAL_C} -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_scan.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_dstlist.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/radix_ipf.c optional ipfilter inet \ compile-with "${NORMAL_C} -I$S/netpfil/ipfilter" contrib/libfdt/fdt.c optional fdt contrib/libfdt/fdt_ro.c optional fdt contrib/libfdt/fdt_rw.c optional fdt contrib/libfdt/fdt_strerror.c optional fdt contrib/libfdt/fdt_sw.c optional fdt contrib/libfdt/fdt_wip.c optional fdt contrib/libnv/cnvlist.c standard contrib/libnv/dnvlist.c standard contrib/libnv/nvlist.c standard contrib/libnv/bsd_nvpair.c standard # xz dev/xz/xz_mod.c optional xz \ compile-with "${NORMAL_C} -DXZ_USE_CRC64 -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/" contrib/xz-embedded/linux/lib/xz/xz_crc32.c optional xz \ compile-with "${NORMAL_C} -DXZ_USE_CRC64 -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/" contrib/xz-embedded/linux/lib/xz/xz_crc64.c optional xz \ compile-with "${NORMAL_C} -DXZ_USE_CRC64 -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/" contrib/xz-embedded/linux/lib/xz/xz_dec_bcj.c optional xz \ compile-with "${NORMAL_C} -DXZ_USE_CRC64 -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/" contrib/xz-embedded/linux/lib/xz/xz_dec_lzma2.c optional xz \ compile-with "${NORMAL_C} -DXZ_USE_CRC64 -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/" contrib/xz-embedded/linux/lib/xz/xz_dec_stream.c optional xz \ compile-with "${NORMAL_C} -DXZ_USE_CRC64 -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/" # Zstd contrib/zstd/lib/freebsd/zstd_kmalloc.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/common/zstd_common.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/common/fse_decompress.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/common/entropy_common.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/common/error_private.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/common/xxhash.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/zstd_compress.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/zstd_compress_literals.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/zstd_compress_sequences.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/zstd_compress_superblock.c optional zstdio compile-with "${ZSTD_C} ${NO_WUNUSED_BUT_SET_VARIABLE}" contrib/zstd/lib/compress/fse_compress.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/hist.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/huf_compress.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/zstd_double_fast.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/zstd_fast.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/zstd_lazy.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/zstd_ldm.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/zstd_opt.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/decompress/zstd_ddict.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/decompress/zstd_decompress.c optional zstdio compile-with ${ZSTD_C} # See comment in sys/conf/kern.pre.mk contrib/zstd/lib/decompress/zstd_decompress_block.c optional zstdio \ compile-with "${ZSTD_C} ${ZSTD_DECOMPRESS_BLOCK_FLAGS}" contrib/zstd/lib/decompress/huf_decompress.c optional zstdio compile-with "${ZSTD_C} ${NO_WBITWISE_INSTEAD_OF_LOGICAL}" # Blake 2 contrib/libb2/blake2b-ref.c optional crypto | !random_loadable random_fenestrasx \ compile-with "${NORMAL_C} -I$S/crypto/blake2 -Wno-cast-qual -DSUFFIX=_ref -Wno-unused-function" contrib/libb2/blake2s-ref.c optional crypto \ compile-with "${NORMAL_C} -I$S/crypto/blake2 -Wno-cast-qual -DSUFFIX=_ref -Wno-unused-function" crypto/blake2/blake2-sw.c optional crypto \ compile-with "${NORMAL_C} -I$S/crypto/blake2 -Wno-cast-qual" crypto/camellia/camellia.c optional crypto crypto/camellia/camellia-api.c optional crypto crypto/chacha20/chacha.c standard crypto/chacha20/chacha-sw.c optional crypto crypto/chacha20_poly1305.c optional crypto crypto/curve25519.c optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include -I$S/crypto/libsodium" crypto/des/des_ecb.c optional netsmb crypto/des/des_setkey.c optional netsmb crypto/openssl/ossl.c optional ossl crypto/openssl/ossl_aes.c optional ossl crypto/openssl/ossl_chacha20.c optional ossl crypto/openssl/ossl_poly1305.c optional ossl crypto/openssl/ossl_sha1.c optional ossl crypto/openssl/ossl_sha256.c optional ossl crypto/openssl/ossl_sha512.c optional ossl crypto/rc4/rc4.c optional netgraph_mppc_encryption crypto/rijndael/rijndael-alg-fst.c optional crypto | ekcd | geom_bde | \ !random_loadable | wlan_ccmp crypto/rijndael/rijndael-api-fst.c optional ekcd | geom_bde | !random_loadable crypto/rijndael/rijndael-api.c optional crypto | wlan_ccmp crypto/sha1.c optional carp | crypto | ether | \ netgraph_mppc_encryption | sctp crypto/sha2/sha256c.c optional crypto | ekcd | geom_bde | \ !random_loadable | sctp | zfs crypto/sha2/sha512c.c optional crypto | geom_bde | zfs crypto/skein/skein.c optional crypto | zfs crypto/skein/skein_block.c optional crypto | zfs crypto/siphash/siphash.c optional inet | inet6 | wg crypto/siphash/siphash_test.c optional inet | inet6 | wg ddb/db_access.c optional ddb ddb/db_break.c optional ddb ddb/db_capture.c optional ddb ddb/db_command.c optional ddb ddb/db_examine.c optional ddb ddb/db_expr.c optional ddb ddb/db_input.c optional ddb ddb/db_lex.c optional ddb ddb/db_main.c optional ddb ddb/db_output.c optional ddb ddb/db_print.c optional ddb ddb/db_ps.c optional ddb ddb/db_run.c optional ddb ddb/db_script.c optional ddb ddb/db_sym.c optional ddb ddb/db_thread.c optional ddb ddb/db_textdump.c optional ddb ddb/db_variables.c optional ddb ddb/db_watch.c optional ddb ddb/db_write_cmd.c optional ddb dev/aac/aac.c optional aac dev/aac/aac_cam.c optional aacp aac dev/aac/aac_debug.c optional aac dev/aac/aac_disk.c optional aac dev/aac/aac_pci.c optional aac pci dev/aacraid/aacraid.c optional aacraid dev/aacraid/aacraid_cam.c optional aacraid scbus dev/aacraid/aacraid_debug.c optional aacraid dev/aacraid/aacraid_pci.c optional aacraid pci dev/acpi_support/acpi_wmi.c optional acpi_wmi acpi dev/acpi_support/acpi_asus.c optional acpi_asus acpi dev/acpi_support/acpi_asus_wmi.c optional acpi_asus_wmi acpi dev/acpi_support/acpi_fujitsu.c optional acpi_fujitsu acpi dev/acpi_support/acpi_hp.c optional acpi_hp acpi dev/acpi_support/acpi_ibm.c optional acpi_ibm acpi dev/acpi_support/acpi_panasonic.c optional acpi_panasonic acpi dev/acpi_support/acpi_sony.c optional acpi_sony acpi dev/acpi_support/acpi_toshiba.c optional acpi_toshiba acpi dev/acpi_support/atk0110.c optional aibs acpi dev/acpica/Osd/OsdDebug.c optional acpi dev/acpica/Osd/OsdHardware.c optional acpi dev/acpica/Osd/OsdInterrupt.c optional acpi dev/acpica/Osd/OsdMemory.c optional acpi dev/acpica/Osd/OsdSchedule.c optional acpi dev/acpica/Osd/OsdStream.c optional acpi dev/acpica/Osd/OsdSynch.c optional acpi dev/acpica/Osd/OsdTable.c optional acpi dev/acpica/acpi.c optional acpi dev/acpica/acpi_acad.c optional acpi dev/acpica/acpi_apei.c optional acpi dev/acpica/acpi_battery.c optional acpi dev/acpica/acpi_button.c optional acpi dev/acpica/acpi_cmbat.c optional acpi dev/acpica/acpi_cpu.c optional acpi dev/acpica/acpi_ec.c optional acpi dev/acpica/acpi_ged.c optional acpi_ged acpi dev/acpica/acpi_isab.c optional acpi isa dev/acpica/acpi_lid.c optional acpi dev/acpica/acpi_package.c optional acpi dev/acpica/acpi_perf.c optional acpi dev/acpica/acpi_powerres.c optional acpi dev/acpica/acpi_quirk.c optional acpi dev/acpica/acpi_resource.c optional acpi dev/acpica/acpi_container.c optional acpi dev/acpica/acpi_smbat.c optional acpi dev/acpica/acpi_thermal.c optional acpi dev/acpica/acpi_throttle.c optional acpi dev/acpica/acpi_video.c optional acpi_video acpi dev/acpica/acpi_dock.c optional acpi_dock acpi dev/adlink/adlink.c optional adlink dev/ae/if_ae.c optional ae pci dev/age/if_age.c optional age pci dev/agp/agp.c optional agp pci dev/agp/agp_if.m optional agp pci dev/ahci/ahci.c optional ahci dev/ahci/ahciem.c optional ahci dev/ahci/ahci_pci.c optional ahci pci dev/aic7xxx/ahc_isa.c optional ahc isa dev/aic7xxx/ahc_pci.c optional ahc pci \ compile-with "${NORMAL_C} ${NO_WCONSTANT_CONVERSION}" dev/aic7xxx/ahd_pci.c optional ahd pci \ compile-with "${NORMAL_C} ${NO_WCONSTANT_CONVERSION}" dev/aic7xxx/aic7770.c optional ahc dev/aic7xxx/aic79xx.c optional ahd pci dev/aic7xxx/aic79xx_osm.c optional ahd pci dev/aic7xxx/aic79xx_pci.c optional ahd pci dev/aic7xxx/aic79xx_reg_print.c optional ahd pci ahd_reg_pretty_print dev/aic7xxx/aic7xxx.c optional ahc dev/aic7xxx/aic7xxx_93cx6.c optional ahc dev/aic7xxx/aic7xxx_osm.c optional ahc dev/aic7xxx/aic7xxx_pci.c optional ahc pci dev/aic7xxx/aic7xxx_reg_print.c optional ahc ahc_reg_pretty_print dev/al_eth/al_eth.c optional al_eth fdt \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" dev/al_eth/al_init_eth_lm.c optional al_eth fdt \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" dev/al_eth/al_init_eth_kr.c optional al_eth fdt \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" contrib/alpine-hal/al_hal_iofic.c optional al_iofic \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" contrib/alpine-hal/al_hal_serdes_25g.c optional al_serdes \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" contrib/alpine-hal/al_hal_serdes_hssp.c optional al_serdes \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" contrib/alpine-hal/al_hal_udma_config.c optional al_udma \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" contrib/alpine-hal/al_hal_udma_debug.c optional al_udma \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" contrib/alpine-hal/al_hal_udma_iofic.c optional al_udma \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" contrib/alpine-hal/al_hal_udma_main.c optional al_udma \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" contrib/alpine-hal/al_serdes.c optional al_serdes \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" contrib/alpine-hal/eth/al_hal_eth_kr.c optional al_eth \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" contrib/alpine-hal/eth/al_hal_eth_main.c optional al_eth \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" dev/alc/if_alc.c optional alc pci dev/ale/if_ale.c optional ale pci dev/alpm/alpm.c optional alpm pci dev/altera/avgen/altera_avgen.c optional altera_avgen dev/altera/avgen/altera_avgen_fdt.c optional altera_avgen fdt dev/altera/avgen/altera_avgen_nexus.c optional altera_avgen dev/altera/msgdma/msgdma.c optional altera_msgdma xdma dev/altera/sdcard/altera_sdcard.c optional altera_sdcard dev/altera/sdcard/altera_sdcard_disk.c optional altera_sdcard dev/altera/sdcard/altera_sdcard_io.c optional altera_sdcard dev/altera/sdcard/altera_sdcard_fdt.c optional altera_sdcard fdt dev/altera/sdcard/altera_sdcard_nexus.c optional altera_sdcard dev/altera/softdma/softdma.c optional altera_softdma xdma fdt dev/altera/pio/pio.c optional altera_pio dev/altera/pio/pio_if.m optional altera_pio dev/amdpm/amdpm.c optional amdpm pci | nfpm pci dev/amdsmb/amdsmb.c optional amdsmb pci # dev/ata/ata_if.m optional ata | atacore dev/ata/ata-all.c optional ata | atacore dev/ata/ata-dma.c optional ata | atacore dev/ata/ata-lowlevel.c optional ata | atacore dev/ata/ata-sata.c optional ata | atacore dev/ata/ata-isa.c optional ata isa | ataisa dev/ata/ata-pci.c optional ata pci | atapci dev/ata/chipsets/ata-acard.c optional ata pci | ataacard dev/ata/chipsets/ata-acerlabs.c optional ata pci | ataacerlabs dev/ata/chipsets/ata-amd.c optional ata pci | ataamd dev/ata/chipsets/ata-ati.c optional ata pci | ataati dev/ata/chipsets/ata-cenatek.c optional ata pci | atacenatek dev/ata/chipsets/ata-cypress.c optional ata pci | atacypress dev/ata/chipsets/ata-cyrix.c optional ata pci | atacyrix dev/ata/chipsets/ata-highpoint.c optional ata pci | atahighpoint dev/ata/chipsets/ata-intel.c optional ata pci | ataintel dev/ata/chipsets/ata-ite.c optional ata pci | ataite dev/ata/chipsets/ata-jmicron.c optional ata pci | atajmicron dev/ata/chipsets/ata-marvell.c optional ata pci | atamarvell dev/ata/chipsets/ata-micron.c optional ata pci | atamicron dev/ata/chipsets/ata-national.c optional ata pci | atanational dev/ata/chipsets/ata-netcell.c optional ata pci | atanetcell dev/ata/chipsets/ata-nvidia.c optional ata pci | atanvidia dev/ata/chipsets/ata-promise.c optional ata pci | atapromise dev/ata/chipsets/ata-serverworks.c optional ata pci | ataserverworks dev/ata/chipsets/ata-siliconimage.c optional ata pci | atasiliconimage | ataati dev/ata/chipsets/ata-sis.c optional ata pci | atasis dev/ata/chipsets/ata-via.c optional ata pci | atavia # dev/ath/if_ath.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_alq.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_beacon.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_btcoex.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_btcoex_mci.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_debug.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_descdma.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_keycache.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_ioctl.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_led.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_lna_div.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_pci.c optional ath pci \ compile-with "${ATH_C}" dev/ath/if_ath_tx.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_tx_edma.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_tx_ht.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_tdma.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_sysctl.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_rx.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_rx_edma.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_spectral.c optional ath \ compile-with "${ATH_C}" dev/ath/ah_osdep.c optional ath \ compile-with "${ATH_C}" # dev/ath/ath_hal/ah.c optional ath \ compile-with "${ATH_C}" dev/ath/ath_hal/ah_eeprom_v1.c optional ath_hal | ath_ar5210 \ compile-with "${ATH_C}" dev/ath/ath_hal/ah_eeprom_v3.c optional ath_hal | ath_ar5211 | ath_ar5212 \ compile-with "${ATH_C}" dev/ath/ath_hal/ah_eeprom_v14.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 \ compile-with "${ATH_C}" dev/ath/ath_hal/ah_eeprom_v4k.c \ optional ath_hal | ath_ar9285 \ compile-with "${ATH_C}" dev/ath/ath_hal/ah_eeprom_9287.c \ optional ath_hal | ath_ar9287 \ compile-with "${ATH_C}" dev/ath/ath_hal/ah_regdomain.c optional ath \ compile-with "${ATH_C} ${NO_WSHIFT_COUNT_NEGATIVE} ${NO_WSHIFT_COUNT_OVERFLOW}" # ar5210 dev/ath/ath_hal/ar5210/ar5210_attach.c optional ath_hal | ath_ar5210 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_beacon.c optional ath_hal | ath_ar5210 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_interrupts.c optional ath_hal | ath_ar5210 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_keycache.c optional ath_hal | ath_ar5210 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_misc.c optional ath_hal | ath_ar5210 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_phy.c optional ath_hal | ath_ar5210 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_power.c optional ath_hal | ath_ar5210 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_recv.c optional ath_hal | ath_ar5210 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_reset.c optional ath_hal | ath_ar5210 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_xmit.c optional ath_hal | ath_ar5210 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" # ar5211 dev/ath/ath_hal/ar5211/ar5211_attach.c optional ath_hal | ath_ar5211 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_beacon.c optional ath_hal | ath_ar5211 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_interrupts.c optional ath_hal | ath_ar5211 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_keycache.c optional ath_hal | ath_ar5211 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_misc.c optional ath_hal | ath_ar5211 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_phy.c optional ath_hal | ath_ar5211 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_power.c optional ath_hal | ath_ar5211 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_recv.c optional ath_hal | ath_ar5211 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_reset.c optional ath_hal | ath_ar5211 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_xmit.c optional ath_hal | ath_ar5211 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" # ar5212 dev/ath/ath_hal/ar5212/ar5212_ani.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_attach.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_beacon.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_eeprom.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_gpio.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_interrupts.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_keycache.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_misc.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_phy.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_power.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_recv.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_reset.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_rfgain.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_xmit.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" # ar5416 (depends on ar5212) dev/ath/ath_hal/ar5416/ar5416_ani.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_attach.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_beacon.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_btcoex.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_cal.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_cal_iq.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_cal_adcgain.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_cal_adcdc.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_eeprom.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_gpio.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_interrupts.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_keycache.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_misc.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_phy.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_power.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_radar.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_recv.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_reset.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_spectral.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_xmit.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" # ar9160 (depends on ar5416) dev/ath/ath_hal/ar9001/ar9160_attach.c optional ath_hal | ath_ar9160 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" # ar9280 (depends on ar5416) dev/ath/ath_hal/ar9002/ar9280_attach.c optional ath_hal | ath_ar9280 | \ ath_ar9285 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9280_olc.c optional ath_hal | ath_ar9280 | \ ath_ar9285 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" # ar9285 (depends on ar5416 and ar9280) dev/ath/ath_hal/ar9002/ar9285_attach.c optional ath_hal | ath_ar9285 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9285_btcoex.c optional ath_hal | ath_ar9285 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9285_reset.c optional ath_hal | ath_ar9285 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9285_cal.c optional ath_hal | ath_ar9285 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9285_phy.c optional ath_hal | ath_ar9285 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9285_diversity.c optional ath_hal | ath_ar9285 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" # ar9287 (depends on ar5416) dev/ath/ath_hal/ar9002/ar9287_attach.c optional ath_hal | ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9287_reset.c optional ath_hal | ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9287_cal.c optional ath_hal | ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9287_olc.c optional ath_hal | ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" # ar9300 contrib/dev/ath/ath_hal/ar9300/ar9300_ani.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_attach.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_beacon.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_eeprom.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal ${NO_WCONSTANT_CONVERSION}" contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_gpio.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_interrupts.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_keycache.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_mci.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_misc.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_paprd.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_phy.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_power.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_radar.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_radio.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_recv.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_recv_ds.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal ${NO_WSOMETIMES_UNINITIALIZED} -Wno-unused-function" contrib/dev/ath/ath_hal/ar9300/ar9300_stub.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_stub_funcs.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_spectral.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_timer.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_xmit.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_xmit_ds.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" # rf backends dev/ath/ath_hal/ar5212/ar2316.c optional ath_rf2316 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar2317.c optional ath_rf2317 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar2413.c optional ath_hal | ath_rf2413 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar2425.c optional ath_hal | ath_rf2425 | ath_rf2417 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5111.c optional ath_hal | ath_rf5111 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5112.c optional ath_hal | ath_rf5112 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5413.c optional ath_hal | ath_rf5413 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar2133.c optional ath_hal | ath_ar5416 | \ ath_ar9130 | ath_ar9160 | ath_ar9280 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9280.c optional ath_hal | ath_ar9280 | ath_ar9285 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9285.c optional ath_hal | ath_ar9285 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9287.c optional ath_hal | ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" # ath rate control algorithms dev/ath/ath_rate/amrr/amrr.c optional ath_rate_amrr \ compile-with "${ATH_C}" dev/ath/ath_rate/onoe/onoe.c optional ath_rate_onoe \ compile-with "${ATH_C}" dev/ath/ath_rate/sample/sample.c optional ath_rate_sample \ compile-with "${ATH_C}" # ath DFS modules dev/ath/ath_dfs/null/dfs_null.c optional ath \ compile-with "${ATH_C}" # dev/backlight/backlight_if.m optional backlight | compat_linuxkpi dev/backlight/backlight.c optional backlight | compat_linuxkpi dev/bce/if_bce.c optional bce dev/bfe/if_bfe.c optional bfe dev/bge/if_bge.c optional bge dev/bhnd/bhnd.c optional bhnd dev/bhnd/bhnd_erom.c optional bhnd dev/bhnd/bhnd_erom_if.m optional bhnd dev/bhnd/bhnd_subr.c optional bhnd dev/bhnd/bhnd_bus_if.m optional bhnd dev/bhnd/bhndb/bhnd_bhndb.c optional bhndb bhnd dev/bhnd/bhndb/bhndb.c optional bhndb bhnd dev/bhnd/bhndb/bhndb_bus_if.m optional bhndb bhnd dev/bhnd/bhndb/bhndb_hwdata.c optional bhndb bhnd dev/bhnd/bhndb/bhndb_if.m optional bhndb bhnd dev/bhnd/bhndb/bhndb_pci.c optional bhndb_pci bhndb bhnd pci dev/bhnd/bhndb/bhndb_pci_hwdata.c optional bhndb_pci bhndb bhnd pci dev/bhnd/bhndb/bhndb_pci_sprom.c optional bhndb_pci bhndb bhnd pci dev/bhnd/bhndb/bhndb_subr.c optional bhndb bhnd dev/bhnd/bcma/bcma.c optional bcma bhnd dev/bhnd/bcma/bcma_bhndb.c optional bcma bhnd bhndb dev/bhnd/bcma/bcma_erom.c optional bcma bhnd dev/bhnd/bcma/bcma_subr.c optional bcma bhnd dev/bhnd/cores/chipc/bhnd_chipc_if.m optional bhnd dev/bhnd/cores/chipc/bhnd_sprom_chipc.c optional bhnd dev/bhnd/cores/chipc/bhnd_pmu_chipc.c optional bhnd dev/bhnd/cores/chipc/chipc.c optional bhnd dev/bhnd/cores/chipc/chipc_cfi.c optional bhnd cfi dev/bhnd/cores/chipc/chipc_gpio.c optional bhnd gpio dev/bhnd/cores/chipc/chipc_slicer.c optional bhnd cfi | bhnd spibus dev/bhnd/cores/chipc/chipc_spi.c optional bhnd spibus dev/bhnd/cores/chipc/chipc_subr.c optional bhnd dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl.c optional bhnd dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl_if.m optional bhnd dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl_hostb_if.m optional bhnd dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl_subr.c optional bhnd dev/bhnd/cores/pci/bhnd_pci.c optional bhnd pci dev/bhnd/cores/pci/bhnd_pci_hostb.c optional bhndb bhnd pci dev/bhnd/cores/pci/bhnd_pcib.c optional bhnd_pcib bhnd pci dev/bhnd/cores/pcie2/bhnd_pcie2.c optional bhnd pci dev/bhnd/cores/pcie2/bhnd_pcie2_hostb.c optional bhndb bhnd pci dev/bhnd/cores/pcie2/bhnd_pcie2b.c optional bhnd_pcie2b bhnd pci dev/bhnd/cores/pmu/bhnd_pmu.c optional bhnd dev/bhnd/cores/pmu/bhnd_pmu_core.c optional bhnd dev/bhnd/cores/pmu/bhnd_pmu_if.m optional bhnd dev/bhnd/cores/pmu/bhnd_pmu_subr.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data_bcm.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data_bcmraw.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data_btxt.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data_sprom.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data_sprom_subr.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data_tlv.c optional bhnd dev/bhnd/nvram/bhnd_nvram_if.m optional bhnd dev/bhnd/nvram/bhnd_nvram_io.c optional bhnd dev/bhnd/nvram/bhnd_nvram_iobuf.c optional bhnd dev/bhnd/nvram/bhnd_nvram_ioptr.c optional bhnd dev/bhnd/nvram/bhnd_nvram_iores.c optional bhnd dev/bhnd/nvram/bhnd_nvram_plist.c optional bhnd dev/bhnd/nvram/bhnd_nvram_store.c optional bhnd dev/bhnd/nvram/bhnd_nvram_store_subr.c optional bhnd dev/bhnd/nvram/bhnd_nvram_subr.c optional bhnd dev/bhnd/nvram/bhnd_nvram_value.c optional bhnd dev/bhnd/nvram/bhnd_nvram_value_fmts.c optional bhnd dev/bhnd/nvram/bhnd_nvram_value_prf.c optional bhnd dev/bhnd/nvram/bhnd_nvram_value_subr.c optional bhnd dev/bhnd/nvram/bhnd_sprom.c optional bhnd dev/bhnd/siba/siba.c optional siba bhnd dev/bhnd/siba/siba_bhndb.c optional siba bhnd bhndb dev/bhnd/siba/siba_erom.c optional siba bhnd dev/bhnd/siba/siba_subr.c optional siba bhnd # dev/bnxt/bnxt_hwrm.c optional bnxt iflib pci dev/bnxt/bnxt_mgmt.c optional bnxt iflib pci dev/bnxt/bnxt_sysctl.c optional bnxt iflib pci dev/bnxt/bnxt_txrx.c optional bnxt iflib pci dev/bnxt/if_bnxt.c optional bnxt iflib pci dev/bwi/bwimac.c optional bwi dev/bwi/bwiphy.c optional bwi dev/bwi/bwirf.c optional bwi dev/bwi/if_bwi.c optional bwi dev/bwi/if_bwi_pci.c optional bwi pci dev/bwn/if_bwn.c optional bwn bhnd dev/bwn/if_bwn_pci.c optional bwn pci bhnd bhndb bhndb_pci dev/bwn/if_bwn_phy_common.c optional bwn bhnd dev/bwn/if_bwn_phy_g.c optional bwn bhnd dev/bwn/if_bwn_phy_lp.c optional bwn bhnd dev/bwn/if_bwn_phy_n.c optional bwn bhnd dev/bwn/if_bwn_util.c optional bwn bhnd dev/cadence/if_cgem.c optional cgem fdt dev/cardbus/card_if.m standard dev/cardbus/cardbus.c optional cardbus dev/cardbus/cardbus_cis.c optional cardbus dev/cardbus/cardbus_device.c optional cardbus dev/cardbus/power_if.m standard dev/cas/if_cas.c optional cas dev/cfi/cfi_bus_fdt.c optional cfi fdt dev/cfi/cfi_bus_nexus.c optional cfi dev/cfi/cfi_core.c optional cfi dev/cfi/cfi_dev.c optional cfi dev/cfi/cfi_disk.c optional cfid dev/chromebook_platform/chromebook_platform.c optional chromebook_platform dev/ciss/ciss.c optional ciss dev/clk/clk.c optional clk dev/clk/clkdev_if.m optional clk dev/clk/clknode_if.m optional clk dev/clk/clk_bus.c optional clk fdt dev/clk/clk_div.c optional clk dev/clk/clk_fixed.c optional clk dev/clk/clk_gate.c optional clk dev/clk/clk_link.c optional clk dev/clk/clk_mux.c optional clk dev/cpufreq/ichss.c optional cpufreq pci dev/cxgb/cxgb_main.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/cxgb_sge.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_mc5.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_vsc7323.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_vsc8211.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_ael1002.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_aq100x.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_mv88e1xxx.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_xgmac.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_t3_hw.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_tn1010.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/sys/uipc_mvec.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/cxgb_t3fw.c optional cxgb cxgb_t3fw \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgbe/t4_clip.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_filter.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_if.m optional cxgbe pci dev/cxgbe/t4_iov.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_mp_ring.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_main.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_netmap.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_sched.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_sge.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_smt.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_l2t.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_tracer.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_vf.c optional cxgbev pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/common/t4_hw.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/common/t4vf_hw.c optional cxgbev pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/crypto/t6_kern_tls.c optional cxgbe pci kern_tls \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/crypto/t4_keyctx.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/cudbg/cudbg_common.c optional cxgbe \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/cudbg/cudbg_flash_utils.c optional cxgbe \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/cudbg/cudbg_lib.c optional cxgbe \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/cudbg/cudbg_wtp.c optional cxgbe \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/cudbg/fastlz.c optional cxgbe \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/cudbg/fastlz_api.c optional cxgbe \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" t4fw_cfg.c optional cxgbe \ compile-with "${AWK} -f $S/tools/fw_stub.awk t4fw_cfg.fw:t4fw_cfg t4fw_cfg_uwire.fw:t4fw_cfg_uwire t4fw.fw:t4fw -mt4fw_cfg -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "t4fw_cfg.c" t4fw_cfg.fwo optional cxgbe \ dependency "t4fw_cfg.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t4fw_cfg.fwo" t4fw_cfg.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t4fw_cfg.txt" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t4fw_cfg.fw" t4fw_cfg_uwire.fwo optional cxgbe \ dependency "t4fw_cfg_uwire.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t4fw_cfg_uwire.fwo" t4fw_cfg_uwire.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t4fw_cfg_uwire.txt" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t4fw_cfg_uwire.fw" t4fw.fwo optional cxgbe \ dependency "t4fw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t4fw.fwo" t4fw.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t4fw-1.27.5.0.bin" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t4fw.fw" t5fw_cfg.c optional cxgbe \ compile-with "${AWK} -f $S/tools/fw_stub.awk t5fw_cfg.fw:t5fw_cfg t5fw_cfg_uwire.fw:t5fw_cfg_uwire t5fw.fw:t5fw -mt5fw_cfg -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "t5fw_cfg.c" t5fw_cfg.fwo optional cxgbe \ dependency "t5fw_cfg.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t5fw_cfg.fwo" t5fw_cfg.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t5fw_cfg.txt" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t5fw_cfg.fw" t5fw_cfg_uwire.fwo optional cxgbe \ dependency "t5fw_cfg_uwire.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t5fw_cfg_uwire.fwo" t5fw_cfg_uwire.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t5fw_cfg_uwire.txt" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t5fw_cfg_uwire.fw" t5fw.fwo optional cxgbe \ dependency "t5fw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t5fw.fwo" t5fw.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t5fw-1.27.5.0.bin" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t5fw.fw" t6fw_cfg.c optional cxgbe \ compile-with "${AWK} -f $S/tools/fw_stub.awk t6fw_cfg.fw:t6fw_cfg t6fw_cfg_uwire.fw:t6fw_cfg_uwire t6fw.fw:t6fw -mt6fw_cfg -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "t6fw_cfg.c" t6fw_cfg.fwo optional cxgbe \ dependency "t6fw_cfg.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t6fw_cfg.fwo" t6fw_cfg.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t6fw_cfg.txt" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t6fw_cfg.fw" t6fw_cfg_uwire.fwo optional cxgbe \ dependency "t6fw_cfg_uwire.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t6fw_cfg_uwire.fwo" t6fw_cfg_uwire.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t6fw_cfg_uwire.txt" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t6fw_cfg_uwire.fw" t6fw.fwo optional cxgbe \ dependency "t6fw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t6fw.fwo" t6fw.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t6fw-1.27.5.0.bin" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t6fw.fw" dev/cxgbe/crypto/t4_crypto.c optional ccr \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cyapa/cyapa.c optional cyapa iicbus dev/dc/if_dc.c optional dc pci dev/dc/dcphy.c optional dc pci dev/dc/pnphy.c optional dc pci dev/dcons/dcons.c optional dcons dev/dcons/dcons_crom.c optional dcons_crom dev/dcons/dcons_os.c optional dcons dev/dialog/da9063/da9063_if.m optional da9063_pmic dev/dialog/da9063/da9063_iic.c optional da9063_pmic iicbus fdt dev/dialog/da9063/da9063_rtc.c optional da9063_rtc fdt dev/drm2/drm_agpsupport.c optional drm2 dev/drm2/drm_auth.c optional drm2 dev/drm2/drm_bufs.c optional drm2 dev/drm2/drm_buffer.c optional drm2 dev/drm2/drm_context.c optional drm2 dev/drm2/drm_crtc.c optional drm2 dev/drm2/drm_crtc_helper.c optional drm2 dev/drm2/drm_dma.c optional drm2 dev/drm2/drm_dp_helper.c optional drm2 dev/drm2/drm_dp_iic_helper.c optional drm2 dev/drm2/drm_drv.c optional drm2 dev/drm2/drm_edid.c optional drm2 dev/drm2/drm_fb_helper.c optional drm2 dev/drm2/drm_fops.c optional drm2 dev/drm2/drm_gem.c optional drm2 dev/drm2/drm_gem_names.c optional drm2 dev/drm2/drm_global.c optional drm2 dev/drm2/drm_hashtab.c optional drm2 dev/drm2/drm_ioctl.c optional drm2 dev/drm2/drm_irq.c optional drm2 dev/drm2/drm_linux_list_sort.c optional drm2 dev/drm2/drm_lock.c optional drm2 dev/drm2/drm_memory.c optional drm2 dev/drm2/drm_mm.c optional drm2 dev/drm2/drm_modes.c optional drm2 dev/drm2/drm_pci.c optional drm2 dev/drm2/drm_platform.c optional drm2 dev/drm2/drm_scatter.c optional drm2 dev/drm2/drm_stub.c optional drm2 dev/drm2/drm_sysctl.c optional drm2 dev/drm2/drm_vm.c optional drm2 dev/drm2/drm_os_freebsd.c optional drm2 dev/drm2/ttm/ttm_agp_backend.c optional drm2 dev/drm2/ttm/ttm_lock.c optional drm2 dev/drm2/ttm/ttm_object.c optional drm2 dev/drm2/ttm/ttm_tt.c optional drm2 dev/drm2/ttm/ttm_bo_util.c optional drm2 dev/drm2/ttm/ttm_bo.c optional drm2 dev/drm2/ttm/ttm_bo_manager.c optional drm2 dev/drm2/ttm/ttm_execbuf_util.c optional drm2 dev/drm2/ttm/ttm_memory.c optional drm2 dev/drm2/ttm/ttm_page_alloc.c optional drm2 dev/drm2/ttm/ttm_bo_vm.c optional drm2 dev/efidev/efidev.c optional efirt dev/efidev/efirt.c optional efirt dev/efidev/efirtc.c optional efirt dev/e1000/if_em.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/em_txrx.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/igb_txrx.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_80003es2lan.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_82540.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_82541.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_82542.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_82543.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_82571.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_82575.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_ich8lan.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_i210.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_api.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_base.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_mac.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_manage.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_nvm.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_phy.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_vf.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_mbx.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_osdep.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/et/if_et.c optional et dev/ena/ena.c optional ena \ compile-with "${NORMAL_C} -I$S/contrib" dev/ena/ena_datapath.c optional ena \ compile-with "${NORMAL_C} -I$S/contrib" dev/ena/ena_netmap.c optional ena \ compile-with "${NORMAL_C} -I$S/contrib" dev/ena/ena_rss.c optional ena \ compile-with "${NORMAL_C} -I$S/contrib" dev/ena/ena_sysctl.c optional ena \ compile-with "${NORMAL_C} -I$S/contrib" contrib/ena-com/ena_com.c optional ena contrib/ena-com/ena_eth_com.c optional ena dev/etherswitch/arswitch/arswitch.c optional arswitch dev/etherswitch/arswitch/arswitch_reg.c optional arswitch dev/etherswitch/arswitch/arswitch_phy.c optional arswitch dev/etherswitch/arswitch/arswitch_8216.c optional arswitch dev/etherswitch/arswitch/arswitch_8226.c optional arswitch dev/etherswitch/arswitch/arswitch_8316.c optional arswitch dev/etherswitch/arswitch/arswitch_8327.c optional arswitch dev/etherswitch/arswitch/arswitch_vlans.c optional arswitch dev/etherswitch/etherswitch.c optional etherswitch dev/etherswitch/etherswitch_if.m optional etherswitch dev/etherswitch/ip17x/ip17x.c optional ip17x dev/etherswitch/ip17x/ip175c.c optional ip17x dev/etherswitch/ip17x/ip175d.c optional ip17x dev/etherswitch/ip17x/ip17x_phy.c optional ip17x dev/etherswitch/ip17x/ip17x_vlans.c optional ip17x dev/etherswitch/miiproxy.c optional miiproxy dev/etherswitch/rtl8366/rtl8366rb.c optional rtl8366rb dev/etherswitch/e6000sw/e6000sw.c optional e6000sw fdt dev/etherswitch/e6000sw/e6060sw.c optional e6060sw dev/etherswitch/infineon/adm6996fc.c optional adm6996fc dev/etherswitch/micrel/ksz8995ma.c optional ksz8995ma dev/etherswitch/ukswitch/ukswitch.c optional ukswitch dev/evdev/cdev.c optional evdev dev/evdev/evdev.c optional evdev dev/evdev/evdev_mt.c optional evdev dev/evdev/evdev_utils.c optional evdev dev/evdev/uinput.c optional evdev uinput dev/exca/exca.c optional cbb -dev/extres/syscon/syscon.c optional syscon -dev/extres/syscon/syscon_generic.c optional syscon fdt -dev/extres/syscon/syscon_if.m optional syscon -dev/extres/syscon/syscon_power.c optional syscon syscon_power dev/fb/fbd.c optional fbd | vt dev/fb/fb_if.m standard dev/fb/splash.c optional sc splash dev/fdt/fdt_clock.c optional fdt fdt_clock dev/fdt/fdt_clock_if.m optional fdt fdt_clock dev/fdt/fdt_common.c optional fdt dev/fdt/fdt_pinctrl.c optional fdt fdt_pinctrl dev/fdt/fdt_pinctrl_if.m optional fdt fdt_pinctrl dev/fdt/fdt_slicer.c optional fdt cfi | fdt mx25l | fdt n25q | fdt at45d dev/fdt/fdt_static_dtb.S optional fdt fdt_dtb_static \ dependency "${FDT_DTS_FILE:T:R}.dtb" dev/fdt/simplebus.c optional fdt dev/fdt/simple_mfd.c optional syscon fdt dev/filemon/filemon.c optional filemon dev/firewire/firewire.c optional firewire dev/firewire/fwcrom.c optional firewire dev/firewire/fwdev.c optional firewire dev/firewire/fwdma.c optional firewire dev/firewire/fwmem.c optional firewire dev/firewire/fwohci.c optional firewire dev/firewire/fwohci_pci.c optional firewire pci dev/firewire/if_fwe.c optional fwe dev/firewire/if_fwip.c optional fwip dev/firewire/sbp.c optional sbp dev/firewire/sbp_targ.c optional sbp_targ dev/flash/at45d.c optional at45d dev/flash/cqspi.c optional cqspi fdt xdma dev/flash/mx25l.c optional mx25l dev/flash/n25q.c optional n25q fdt dev/flash/qspi_if.m optional cqspi fdt | n25q fdt dev/fxp/if_fxp.c optional fxp dev/fxp/inphy.c optional fxp dev/gem/if_gem.c optional gem dev/gem/if_gem_pci.c optional gem pci dev/gve/gve_adminq.c optional gve dev/gve/gve_main.c optional gve dev/gve/gve_qpl.c optional gve dev/gve/gve_rx.c optional gve dev/gve/gve_sysctl.c optional gve dev/gve/gve_tx.c optional gve dev/gve/gve_utils.c optional gve dev/goldfish/goldfish_rtc.c optional goldfish_rtc fdt dev/gpio/dwgpio/dwgpio.c optional gpio dwgpio fdt dev/gpio/dwgpio/dwgpio_bus.c optional gpio dwgpio fdt dev/gpio/dwgpio/dwgpio_if.m optional gpio dwgpio fdt dev/gpio/gpiobacklight.c optional gpiobacklight fdt dev/gpio/gpiokeys.c optional gpiokeys fdt dev/gpio/gpiokeys_codes.c optional gpiokeys fdt dev/gpio/gpiobus.c optional gpio \ dependency "gpiobus_if.h" dev/gpio/gpioc.c optional gpio \ dependency "gpio_if.h" dev/gpio/gpioiic.c optional gpioiic dev/gpio/gpioled.c optional gpioled !fdt dev/gpio/gpioled_fdt.c optional gpioled fdt dev/gpio/gpiomdio.c optional gpiomdio mii_bitbang dev/gpio/gpiopower.c optional gpiopower fdt dev/gpio/gpioregulator.c optional gpioregulator fdt dev/gpio/gpiospi.c optional gpiospi dev/gpio/gpioths.c optional gpioths dev/gpio/gpio_if.m optional gpio dev/gpio/gpiobus_if.m optional gpio dev/gpio/gpiopps.c optional gpiopps fdt dev/gpio/ofw_gpiobus.c optional fdt gpio dev/hid/bcm5974.c optional bcm5974 dev/hid/hconf.c optional hconf dev/hid/hcons.c optional hcons dev/hid/hgame.c optional hgame dev/hid/hid.c optional hid dev/hid/hid_if.m optional hid dev/hid/hidbus.c optional hidbus dev/hid/hidmap.c optional hidmap dev/hid/hidquirk.c optional hid dev/hid/hidraw.c optional hidraw dev/hid/hkbd.c optional hkbd dev/hid/hms.c optional hms dev/hid/hmt.c optional hmt hconf dev/hid/hpen.c optional hpen dev/hid/hsctrl.c optional hsctrl dev/hid/ietp.c optional ietp dev/hid/ps4dshock.c optional ps4dshock dev/hid/xb360gp.c optional xb360gp dev/hifn/hifn7751.c optional hifn dev/hptiop/hptiop.c optional hptiop scbus dev/hwpmc/hwpmc_logging.c optional hwpmc dev/hwpmc/hwpmc_mod.c optional hwpmc dev/hwpmc/hwpmc_soft.c optional hwpmc dev/hwreset/hwreset.c optional hwreset dev/hwreset/hwreset_array.c optional hwreset dev/hwreset/hwreset_if.m optional hwreset dev/ichiic/ig4_acpi.c optional ig4 acpi iicbus dev/ichiic/ig4_iic.c optional ig4 iicbus dev/ichiic/ig4_pci.c optional ig4 pci iicbus dev/ichsmb/ichsmb.c optional ichsmb dev/ichsmb/ichsmb_pci.c optional ichsmb pci dev/ida/ida.c optional ida dev/ida/ida_disk.c optional ida dev/ida/ida_pci.c optional ida pci dev/iicbus/acpi_iicbus.c optional acpi iicbus | acpi compat_linuxkpi dev/iicbus/icee.c optional icee dev/iicbus/if_ic.c optional ic dev/iicbus/iic.c optional iic dev/iicbus/iic_recover_bus.c optional iicbus | compat_linuxkpi dev/iicbus/iicbb.c optional iicbb | compat_linuxkpi dev/iicbus/iicbb_if.m optional iicbb | compat_linuxkpi dev/iicbus/iicbus.c optional iicbus | compat_linuxkpi dev/iicbus/iicbus_if.m optional iicbus | compat_linuxkpi dev/iicbus/iichid.c optional iichid acpi hid iicbus dev/iicbus/iiconf.c optional iicbus | compat_linuxkpi dev/iicbus/iicsmb.c optional iicsmb \ dependency "iicbus_if.h" dev/iicbus/adc/ad7418.c optional ad7418 dev/iicbus/adc/ads111x.c optional ads111x dev/iicbus/adc/pcf8591.c optional pcf8591 dev/iicbus/controller/opencores/iicoc.c optional iicoc dev/iicbus/controller/opencores/iicoc_fdt.c optional iicoc fdt dev/iicbus/controller/opencores/iicoc_pci.c optional iicoc pci dev/iicbus/mux/iicmux.c optional iicmux dev/iicbus/mux/iicmux_if.m optional iicmux dev/iicbus/mux/iic_gpiomux.c optional iic_gpiomux fdt dev/iicbus/mux/ltc430x.c optional ltc430x dev/iicbus/mux/pca954x.c optional pca954x iicbus iicmux dev/iicbus/ofw_iicbus.c optional fdt iicbus dev/iicbus/ofw_iicbus_if.m optional fdt iicbus dev/iicbus/rtc/ds1307.c optional ds1307 dev/iicbus/rtc/ds13rtc.c optional ds13rtc | ds133x | ds1374 dev/iicbus/rtc/ds1672.c optional ds1672 dev/iicbus/rtc/ds3231.c optional ds3231 dev/iicbus/rtc/isl12xx.c optional isl12xx dev/iicbus/rtc/nxprtc.c optional nxprtc | pcf8563 dev/iicbus/rtc/pcf85063.c optional pcf85063 iicbus fdt dev/iicbus/rtc/rtc8583.c optional rtc8583 dev/iicbus/rtc/rv3032.c optional rv3032 iicbus fdt dev/iicbus/rtc/rx8803.c optional rx8803 iicbus fdt dev/iicbus/rtc/s35390a.c optional s35390a dev/iicbus/sensor/htu21.c optional htu21 dev/iicbus/sensor/lm75.c optional lm75 dev/iicbus/sensor/max44009.c optional max44009 dev/iicbus/gpio/pcf8574.c optional pcf8574 dev/iicbus/gpio/tca64xx.c optional tca64xx fdt gpio dev/iicbus/pmic/fan53555.c optional fan53555 fdt | tcs4525 fdt dev/iicbus/pmic/silergy/sy8106a.c optional sy8106a fdt dev/iicbus/pmic/silergy/syr827.c optional syr827 fdt dev/igc/if_igc.c optional igc iflib pci dev/igc/igc_api.c optional igc iflib pci dev/igc/igc_base.c optional igc iflib pci dev/igc/igc_i225.c optional igc iflib pci dev/igc/igc_mac.c optional igc iflib pci dev/igc/igc_nvm.c optional igc iflib pci dev/igc/igc_phy.c optional igc iflib pci dev/igc/igc_txrx.c optional igc iflib pci dev/intpm/intpm.c optional intpm pci # XXX Work around clang warning, until maintainer approves fix. dev/ips/ips.c optional ips \ compile-with "${NORMAL_C} ${NO_WSOMETIMES_UNINITIALIZED}" dev/ips/ips_commands.c optional ips dev/ips/ips_disk.c optional ips dev/ips/ips_ioctl.c optional ips dev/ips/ips_pci.c optional ips pci dev/ipw/if_ipw.c optional ipw ipwbssfw.c optional ipwbssfw | ipwfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk ipw_bss.fw:ipw_bss:130 -lintel_ipw -mipw_bss -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "ipwbssfw.c" ipw_bss.fwo optional ipwbssfw | ipwfw \ dependency "ipw_bss.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "ipw_bss.fwo" ipw_bss.fw optional ipwbssfw | ipwfw \ dependency "$S/contrib/dev/ipw/ipw2100-1.3.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "ipw_bss.fw" ipwibssfw.c optional ipwibssfw | ipwfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk ipw_ibss.fw:ipw_ibss:130 -lintel_ipw -mipw_ibss -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "ipwibssfw.c" ipw_ibss.fwo optional ipwibssfw | ipwfw \ dependency "ipw_ibss.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "ipw_ibss.fwo" ipw_ibss.fw optional ipwibssfw | ipwfw \ dependency "$S/contrib/dev/ipw/ipw2100-1.3-i.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "ipw_ibss.fw" ipwmonitorfw.c optional ipwmonitorfw | ipwfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk ipw_monitor.fw:ipw_monitor:130 -lintel_ipw -mipw_monitor -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "ipwmonitorfw.c" ipw_monitor.fwo optional ipwmonitorfw | ipwfw \ dependency "ipw_monitor.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "ipw_monitor.fwo" ipw_monitor.fw optional ipwmonitorfw | ipwfw \ dependency "$S/contrib/dev/ipw/ipw2100-1.3-p.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "ipw_monitor.fw" dev/iscsi/icl.c optional iscsi dev/iscsi/icl_conn_if.m optional cfiscsi | iscsi dev/iscsi/icl_soft.c optional iscsi dev/iscsi/icl_soft_proxy.c optional iscsi dev/iscsi/iscsi.c optional iscsi scbus dev/ismt/ismt.c optional ismt dev/isl/isl.c optional isl iicbus dev/isp/isp.c optional isp dev/isp/isp_freebsd.c optional isp dev/isp/isp_library.c optional isp dev/isp/isp_pci.c optional isp pci dev/isp/isp_target.c optional isp dev/ispfw/ispfw.c optional ispfw dev/iwi/if_iwi.c optional iwi iwibssfw.c optional iwibssfw | iwifw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwi_bss.fw:iwi_bss:300 -lintel_iwi -miwi_bss -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwibssfw.c" iwi_bss.fwo optional iwibssfw | iwifw \ dependency "iwi_bss.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwi_bss.fwo" iwi_bss.fw optional iwibssfw | iwifw \ dependency "$S/contrib/dev/iwi/ipw2200-bss.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwi_bss.fw" iwiibssfw.c optional iwiibssfw | iwifw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwi_ibss.fw:iwi_ibss:300 -lintel_iwi -miwi_ibss -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwiibssfw.c" iwi_ibss.fwo optional iwiibssfw | iwifw \ dependency "iwi_ibss.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwi_ibss.fwo" iwi_ibss.fw optional iwiibssfw | iwifw \ dependency "$S/contrib/dev/iwi/ipw2200-ibss.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwi_ibss.fw" iwimonitorfw.c optional iwimonitorfw | iwifw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwi_monitor.fw:iwi_monitor:300 -lintel_iwi -miwi_monitor -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwimonitorfw.c" iwi_monitor.fwo optional iwimonitorfw | iwifw \ dependency "iwi_monitor.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwi_monitor.fwo" iwi_monitor.fw optional iwimonitorfw | iwifw \ dependency "$S/contrib/dev/iwi/ipw2200-sniffer.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwi_monitor.fw" dev/iwm/if_iwm.c optional iwm dev/iwm/if_iwm_7000.c optional iwm dev/iwm/if_iwm_8000.c optional iwm dev/iwm/if_iwm_9000.c optional iwm dev/iwm/if_iwm_9260.c optional iwm dev/iwm/if_iwm_binding.c optional iwm dev/iwm/if_iwm_fw.c optional iwm dev/iwm/if_iwm_led.c optional iwm dev/iwm/if_iwm_mac_ctxt.c optional iwm dev/iwm/if_iwm_notif_wait.c optional iwm dev/iwm/if_iwm_pcie_trans.c optional iwm dev/iwm/if_iwm_phy_ctxt.c optional iwm dev/iwm/if_iwm_phy_db.c optional iwm dev/iwm/if_iwm_power.c optional iwm dev/iwm/if_iwm_scan.c optional iwm dev/iwm/if_iwm_sf.c optional iwm dev/iwm/if_iwm_sta.c optional iwm dev/iwm/if_iwm_time_event.c optional iwm dev/iwm/if_iwm_util.c optional iwm iwm3160fw.c optional iwm3160fw | iwmfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwm3160.fw:iwm3160fw -miwm3160fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwm3160fw.c" iwm3160fw.fwo optional iwm3160fw | iwmfw \ dependency "iwm3160.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwm3160fw.fwo" iwm3160.fw optional iwm3160fw | iwmfw \ dependency "$S/contrib/dev/iwm/iwm-3160-17.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm3160.fw" iwm3168fw.c optional iwm3168fw | iwmfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwm3168.fw:iwm3168fw -miwm3168fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwm3168fw.c" iwm3168fw.fwo optional iwm3168fw | iwmfw \ dependency "iwm3168.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwm3168fw.fwo" iwm3168.fw optional iwm3168fw | iwmfw \ dependency "$S/contrib/dev/iwm/iwm-3168-22.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm3168.fw" iwm7260fw.c optional iwm7260fw | iwmfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwm7260.fw:iwm7260fw -miwm7260fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwm7260fw.c" iwm7260fw.fwo optional iwm7260fw | iwmfw \ dependency "iwm7260.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwm7260fw.fwo" iwm7260.fw optional iwm7260fw | iwmfw \ dependency "$S/contrib/dev/iwm/iwm-7260-17.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm7260.fw" iwm7265fw.c optional iwm7265fw | iwmfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwm7265.fw:iwm7265fw -miwm7265fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwm7265fw.c" iwm7265fw.fwo optional iwm7265fw | iwmfw \ dependency "iwm7265.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwm7265fw.fwo" iwm7265.fw optional iwm7265fw | iwmfw \ dependency "$S/contrib/dev/iwm/iwm-7265-17.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm7265.fw" iwm7265Dfw.c optional iwm7265Dfw | iwmfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwm7265D.fw:iwm7265Dfw -miwm7265Dfw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwm7265Dfw.c" iwm7265Dfw.fwo optional iwm7265Dfw | iwmfw \ dependency "iwm7265D.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwm7265Dfw.fwo" iwm7265D.fw optional iwm7265Dfw | iwmfw \ dependency "$S/contrib/dev/iwm/iwm-7265D-17.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm7265D.fw" iwm8000Cfw.c optional iwm8000Cfw | iwmfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwm8000C.fw:iwm8000Cfw -miwm8000Cfw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwm8000Cfw.c" iwm8000Cfw.fwo optional iwm8000Cfw | iwmfw \ dependency "iwm8000C.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwm8000Cfw.fwo" iwm8000C.fw optional iwm8000Cfw | iwmfw \ dependency "$S/contrib/dev/iwm/iwm-8000C-16.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm8000C.fw" iwm8265.fw optional iwm8265fw | iwmfw \ dependency "$S/contrib/dev/iwm/iwm-8265-22.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm8265.fw" iwm8265fw.c optional iwm8265fw | iwmfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwm8265.fw:iwm8265fw -miwm8265fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwm8265fw.c" iwm8265fw.fwo optional iwm8265fw | iwmfw \ dependency "iwm8265.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwm8265fw.fwo" dev/iwn/if_iwn.c optional iwn iwn1000fw.c optional iwn1000fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn1000.fw:iwn1000fw -miwn1000fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn1000fw.c" iwn1000fw.fwo optional iwn1000fw | iwnfw \ dependency "iwn1000.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn1000fw.fwo" iwn1000.fw optional iwn1000fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-1000-39.31.5.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn1000.fw" iwn100fw.c optional iwn100fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn100.fw:iwn100fw -miwn100fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn100fw.c" iwn100fw.fwo optional iwn100fw | iwnfw \ dependency "iwn100.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn100fw.fwo" iwn100.fw optional iwn100fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-100-39.31.5.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn100.fw" iwn105fw.c optional iwn105fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn105.fw:iwn105fw -miwn105fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn105fw.c" iwn105fw.fwo optional iwn105fw | iwnfw \ dependency "iwn105.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn105fw.fwo" iwn105.fw optional iwn105fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-105-6-18.168.6.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn105.fw" iwn135fw.c optional iwn135fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn135.fw:iwn135fw -miwn135fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn135fw.c" iwn135fw.fwo optional iwn135fw | iwnfw \ dependency "iwn135.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn135fw.fwo" iwn135.fw optional iwn135fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-135-6-18.168.6.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn135.fw" iwn2000fw.c optional iwn2000fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn2000.fw:iwn2000fw -miwn2000fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn2000fw.c" iwn2000fw.fwo optional iwn2000fw | iwnfw \ dependency "iwn2000.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn2000fw.fwo" iwn2000.fw optional iwn2000fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-2000-18.168.6.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn2000.fw" iwn2030fw.c optional iwn2030fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn2030.fw:iwn2030fw -miwn2030fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn2030fw.c" iwn2030fw.fwo optional iwn2030fw | iwnfw \ dependency "iwn2030.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn2030fw.fwo" iwn2030.fw optional iwn2030fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwnwifi-2030-18.168.6.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn2030.fw" iwn4965fw.c optional iwn4965fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn4965.fw:iwn4965fw -miwn4965fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn4965fw.c" iwn4965fw.fwo optional iwn4965fw | iwnfw \ dependency "iwn4965.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn4965fw.fwo" iwn4965.fw optional iwn4965fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-4965-228.61.2.24.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn4965.fw" iwn5000fw.c optional iwn5000fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn5000.fw:iwn5000fw -miwn5000fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn5000fw.c" iwn5000fw.fwo optional iwn5000fw | iwnfw \ dependency "iwn5000.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn5000fw.fwo" iwn5000.fw optional iwn5000fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-5000-8.83.5.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn5000.fw" iwn5150fw.c optional iwn5150fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn5150.fw:iwn5150fw -miwn5150fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn5150fw.c" iwn5150fw.fwo optional iwn5150fw | iwnfw \ dependency "iwn5150.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn5150fw.fwo" iwn5150.fw optional iwn5150fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-5150-8.24.2.2.fw.uu"\ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn5150.fw" iwn6000fw.c optional iwn6000fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn6000.fw:iwn6000fw -miwn6000fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn6000fw.c" iwn6000fw.fwo optional iwn6000fw | iwnfw \ dependency "iwn6000.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn6000fw.fwo" iwn6000.fw optional iwn6000fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-6000-9.221.4.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn6000.fw" iwn6000g2afw.c optional iwn6000g2afw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn6000g2a.fw:iwn6000g2afw -miwn6000g2afw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn6000g2afw.c" iwn6000g2afw.fwo optional iwn6000g2afw | iwnfw \ dependency "iwn6000g2a.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn6000g2afw.fwo" iwn6000g2a.fw optional iwn6000g2afw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-6000g2a-18.168.6.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn6000g2a.fw" iwn6000g2bfw.c optional iwn6000g2bfw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn6000g2b.fw:iwn6000g2bfw -miwn6000g2bfw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn6000g2bfw.c" iwn6000g2bfw.fwo optional iwn6000g2bfw | iwnfw \ dependency "iwn6000g2b.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn6000g2bfw.fwo" iwn6000g2b.fw optional iwn6000g2bfw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-6000g2b-18.168.6.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn6000g2b.fw" iwn6050fw.c optional iwn6050fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn6050.fw:iwn6050fw -miwn6050fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn6050fw.c" iwn6050fw.fwo optional iwn6050fw | iwnfw \ dependency "iwn6050.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn6050fw.fwo" iwn6050.fw optional iwn6050fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-6050-41.28.5.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn6050.fw" dev/ixgbe/if_ix.c optional ix inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe -DSMP" dev/ixgbe/if_ixv.c optional ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe -DSMP" dev/ixgbe/if_bypass.c optional ix inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/if_fdir.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/if_sriov.c optional ix inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ix_txrx.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_osdep.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_phy.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_api.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_common.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_mbx.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_vf.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_82598.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_82599.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_x540.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_x550.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_dcb.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_dcb_82598.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_dcb_82599.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/jedec_dimm/jedec_dimm.c optional jedec_dimm smbus dev/jme/if_jme.c optional jme pci dev/kbd/kbd.c optional atkbd | pckbd | sc | ukbd | vt | hkbd dev/kbdmux/kbdmux.c optional kbdmux dev/ksyms/ksyms.c optional ksyms dev/le/am7990.c optional le dev/le/am79900.c optional le dev/le/if_le_pci.c optional le pci dev/le/lance.c optional le dev/led/led.c standard dev/lge/if_lge.c optional lge dev/liquidio/base/cn23xx_pf_device.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/base/lio_console.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/base/lio_ctrl.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/base/lio_device.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/base/lio_droq.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/base/lio_mem_ops.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/base/lio_request_manager.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/base/lio_response_manager.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/lio_core.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/lio_ioctl.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/lio_main.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/lio_rss.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/lio_rxtx.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/lio_sysctl.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" lio.c optional lio \ compile-with "${AWK} -f $S/tools/fw_stub.awk lio_23xx_nic.bin.fw:lio_23xx_nic.bin -mlio_23xx_nic.bin -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "lio.c" lio_23xx_nic.bin.fw.fwo optional lio \ dependency "lio_23xx_nic.bin.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "lio_23xx_nic.bin.fw.fwo" lio_23xx_nic.bin.fw optional lio \ dependency "$S/contrib/dev/liquidio/lio_23xx_nic.bin.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "lio_23xx_nic.bin.fw" dev/malo/if_malo.c optional malo dev/malo/if_malohal.c optional malo dev/malo/if_malo_pci.c optional malo pci dev/md/md.c optional md dev/mdio/mdio_if.m optional miiproxy | mdio dev/mdio/mdio.c optional miiproxy | mdio dev/mem/memdev.c optional mem dev/mem/memutil.c optional mem dev/mfi/mfi.c optional mfi dev/mfi/mfi_debug.c optional mfi dev/mfi/mfi_pci.c optional mfi pci dev/mfi/mfi_disk.c optional mfi dev/mfi/mfi_syspd.c optional mfi dev/mfi/mfi_tbolt.c optional mfi dev/mfi/mfi_cam.c optional mfip scbus dev/mii/acphy.c optional miibus | acphy dev/mii/amphy.c optional miibus | amphy dev/mii/atphy.c optional miibus | atphy dev/mii/axphy.c optional miibus | axphy dev/mii/bmtphy.c optional miibus | bmtphy dev/mii/brgphy.c optional miibus | brgphy dev/mii/ciphy.c optional miibus | ciphy dev/mii/dp83822phy.c optional miibus | dp83822phy dev/mii/dp83867phy.c optional miibus | dp83867phy dev/mii/e1000phy.c optional miibus | e1000phy dev/mii/gentbi.c optional miibus | gentbi dev/mii/icsphy.c optional miibus | icsphy dev/mii/ip1000phy.c optional miibus | ip1000phy dev/mii/jmphy.c optional miibus | jmphy dev/mii/lxtphy.c optional miibus | lxtphy dev/mii/mcommphy.c optional miibus | mcommphy dev/mii/micphy.c optional miibus fdt | micphy fdt dev/mii/mii.c optional miibus | mii dev/mii/mii_bitbang.c optional miibus | mii_bitbang dev/mii/mii_physubr.c optional miibus | mii dev/mii/mii_fdt.c optional miibus fdt | mii fdt dev/mii/miibus_if.m optional miibus | mii dev/mii/mv88e151x.c optional miibus | mv88e151x dev/mii/nsgphy.c optional miibus | nsgphy dev/mii/nsphy.c optional miibus | nsphy dev/mii/nsphyter.c optional miibus | nsphyter dev/mii/pnaphy.c optional miibus | pnaphy dev/mii/qsphy.c optional miibus | qsphy dev/mii/rdcphy.c optional miibus | rdcphy dev/mii/rgephy.c optional miibus | rgephy dev/mii/rlphy.c optional miibus | rlphy dev/mii/rlswitch.c optional rlswitch dev/mii/smcphy.c optional miibus | smcphy dev/mii/smscphy.c optional miibus | smscphy dev/mii/tdkphy.c optional miibus | tdkphy dev/mii/truephy.c optional miibus | truephy dev/mii/ukphy.c optional miibus | mii dev/mii/ukphy_subr.c optional miibus | mii dev/mii/vscphy.c optional miibus | vscphy dev/mii/xmphy.c optional miibus | xmphy dev/mlxfw/mlxfw_fsm.c optional mlxfw \ compile-with "${MLXFW_C}" dev/mlxfw/mlxfw_mfa2.c optional mlxfw \ compile-with "${MLXFW_C}" dev/mlxfw/mlxfw_mfa2_tlv_multi.c optional mlxfw \ compile-with "${MLXFW_C}" dev/mlx/mlx.c optional mlx dev/mlx/mlx_disk.c optional mlx dev/mlx/mlx_pci.c optional mlx pci dev/mmc/mmc_subr.c optional mmc | mmcsd !mmccam dev/mmc/mmc.c optional mmc !mmccam dev/mmc/mmcbr_if.m standard dev/mmc/mmcbus_if.m standard dev/mmc/mmcsd.c optional mmcsd !mmccam dev/mmc/mmc_fdt_helpers.c optional mmc regulator clk fdt | mmccam regulator clk fdt dev/mmc/mmc_helpers.c optional mmc gpio regulator clk | mmccam gpio regulator clk dev/mmc/mmc_pwrseq.c optional mmc clk regulator fdt | mmccam clk regulator fdt dev/mmc/mmc_pwrseq_if.m optional mmc clk regulator fdt | mmccam clk regulator fdt dev/mmcnull/mmcnull.c optional mmcnull dev/mpr/mpr.c optional mpr dev/mpr/mpr_config.c optional mpr # XXX Work around clang warning, until maintainer approves fix. dev/mpr/mpr_mapping.c optional mpr \ compile-with "${NORMAL_C} ${NO_WSOMETIMES_UNINITIALIZED}" dev/mpr/mpr_pci.c optional mpr pci dev/mpr/mpr_sas.c optional mpr \ compile-with "${NORMAL_C} ${NO_WUNNEEDED_INTERNAL_DECL}" dev/mpr/mpr_sas_lsi.c optional mpr dev/mpr/mpr_table.c optional mpr dev/mpr/mpr_user.c optional mpr dev/mps/mps.c optional mps dev/mps/mps_config.c optional mps # XXX Work around clang warning, until maintainer approves fix. dev/mps/mps_mapping.c optional mps \ compile-with "${NORMAL_C} ${NO_WSOMETIMES_UNINITIALIZED}" dev/mps/mps_pci.c optional mps pci dev/mps/mps_sas.c optional mps \ compile-with "${NORMAL_C} ${NO_WUNNEEDED_INTERNAL_DECL}" dev/mps/mps_sas_lsi.c optional mps dev/mps/mps_table.c optional mps dev/mps/mps_user.c optional mps dev/mpt/mpt.c optional mpt dev/mpt/mpt_cam.c optional mpt dev/mpt/mpt_debug.c optional mpt dev/mpt/mpt_pci.c optional mpt pci dev/mpt/mpt_raid.c optional mpt dev/mpt/mpt_user.c optional mpt dev/mrsas/mrsas.c optional mrsas dev/mrsas/mrsas_cam.c optional mrsas dev/mrsas/mrsas_ioctl.c optional mrsas dev/mrsas/mrsas_fp.c optional mrsas dev/msk/if_msk.c optional msk dev/mvs/mvs.c optional mvs dev/mvs/mvs_if.m optional mvs dev/mvs/mvs_pci.c optional mvs pci dev/mwl/if_mwl.c optional mwl dev/mwl/if_mwl_pci.c optional mwl pci dev/mwl/mwlhal.c optional mwl mwlfw.c optional mwlfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk mw88W8363.fw:mw88W8363fw mwlboot.fw:mwlboot -mmwl -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "mwlfw.c" mw88W8363.fwo optional mwlfw \ dependency "mw88W8363.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "mw88W8363.fwo" mw88W8363.fw optional mwlfw \ dependency "$S/contrib/dev/mwl/mw88W8363.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "mw88W8363.fw" mwlboot.fwo optional mwlfw \ dependency "mwlboot.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "mwlboot.fwo" mwlboot.fw optional mwlfw \ dependency "$S/contrib/dev/mwl/mwlboot.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "mwlboot.fw" dev/mxge/if_mxge.c optional mxge pci dev/mxge/mxge_eth_z8e.c optional mxge pci dev/mxge/mxge_ethp_z8e.c optional mxge pci dev/mxge/mxge_rss_eth_z8e.c optional mxge pci dev/mxge/mxge_rss_ethp_z8e.c optional mxge pci dev/my/if_my.c optional my dev/netmap/if_ptnet.c optional netmap inet dev/netmap/netmap.c optional netmap dev/netmap/netmap_bdg.c optional netmap dev/netmap/netmap_freebsd.c optional netmap dev/netmap/netmap_generic.c optional netmap dev/netmap/netmap_kloop.c optional netmap dev/netmap/netmap_legacy.c optional netmap dev/netmap/netmap_mbq.c optional netmap dev/netmap/netmap_mem2.c optional netmap dev/netmap/netmap_monitor.c optional netmap dev/netmap/netmap_null.c optional netmap dev/netmap/netmap_offloadings.c optional netmap dev/netmap/netmap_pipe.c optional netmap dev/netmap/netmap_vale.c optional netmap # compile-with "${NORMAL_C} -Wconversion -Wextra" dev/nfsmb/nfsmb.c optional nfsmb pci dev/nge/if_nge.c optional nge dev/nmdm/nmdm.c optional nmdm dev/null/null.c standard dev/nvd/nvd.c optional nvd nvme dev/nvme/nvme.c optional nvme dev/nvme/nvme_ahci.c optional nvme ahci dev/nvme/nvme_ctrlr.c optional nvme dev/nvme/nvme_ctrlr_cmd.c optional nvme dev/nvme/nvme_ns.c optional nvme dev/nvme/nvme_ns_cmd.c optional nvme dev/nvme/nvme_pci.c optional nvme pci dev/nvme/nvme_qpair.c optional nvme dev/nvme/nvme_sim.c optional nvme scbus dev/nvme/nvme_sysctl.c optional nvme dev/nvme/nvme_test.c optional nvme dev/nvme/nvme_util.c optional nvme dev/nvmem/nvmem.c optional nvmem fdt dev/nvmem/nvmem_if.m optional nvmem dev/oce/oce_hw.c optional oce pci dev/oce/oce_if.c optional oce pci dev/oce/oce_mbox.c optional oce pci dev/oce/oce_queue.c optional oce pci dev/oce/oce_sysctl.c optional oce pci dev/oce/oce_util.c optional oce pci dev/ocs_fc/ocs_gendump.c optional ocs_fc pci dev/ocs_fc/ocs_pci.c optional ocs_fc pci dev/ocs_fc/ocs_ioctl.c optional ocs_fc pci dev/ocs_fc/ocs_os.c optional ocs_fc pci dev/ocs_fc/ocs_utils.c optional ocs_fc pci dev/ocs_fc/ocs_hw.c optional ocs_fc pci dev/ocs_fc/ocs_hw_queues.c optional ocs_fc pci dev/ocs_fc/sli4.c optional ocs_fc pci dev/ocs_fc/ocs_sm.c optional ocs_fc pci dev/ocs_fc/ocs_device.c optional ocs_fc pci dev/ocs_fc/ocs_xport.c optional ocs_fc pci dev/ocs_fc/ocs_domain.c optional ocs_fc pci dev/ocs_fc/ocs_sport.c optional ocs_fc pci dev/ocs_fc/ocs_els.c optional ocs_fc pci dev/ocs_fc/ocs_fabric.c optional ocs_fc pci dev/ocs_fc/ocs_io.c optional ocs_fc pci dev/ocs_fc/ocs_node.c optional ocs_fc pci dev/ocs_fc/ocs_scsi.c optional ocs_fc pci dev/ocs_fc/ocs_unsol.c optional ocs_fc pci dev/ocs_fc/ocs_ddump.c optional ocs_fc pci dev/ocs_fc/ocs_mgmt.c optional ocs_fc pci dev/ocs_fc/ocs_cam.c optional ocs_fc pci dev/ofw/ofw_bus_if.m optional fdt dev/ofw/ofw_bus_subr.c optional fdt dev/ofw/ofw_cpu.c optional fdt dev/ofw/ofw_fdt.c optional fdt dev/ofw/ofw_firmware.c optional fdt dev/ofw/ofw_if.m optional fdt dev/ofw/ofw_graph.c optional fdt dev/ofw/ofw_subr.c optional fdt dev/ofw/ofwbus.c optional fdt dev/ofw/openfirm.c optional fdt dev/ofw/openfirmio.c optional fdt dev/ow/ow.c optional ow \ dependency "owll_if.h" \ dependency "own_if.h" dev/ow/owll_if.m optional ow dev/ow/own_if.m optional ow dev/ow/ow_temp.c optional ow_temp dev/ow/owc_gpiobus.c optional owc gpio dev/pbio/pbio.c optional pbio isa dev/pccbb/pccbb.c optional cbb dev/pccbb/pccbb_pci.c optional cbb pci dev/pcf/pcf.c optional pcf dev/pci/fixup_pci.c optional pci dev/pci/hostb_pci.c optional pci dev/pci/ignore_pci.c optional pci dev/pci/isa_pci.c optional pci isa dev/pci/pci.c optional pci dev/pci/pci_if.m standard dev/pci/pci_iov.c optional pci pci_iov dev/pci/pci_iov_if.m standard dev/pci/pci_iov_schema.c optional pci pci_iov dev/pci/pci_pci.c optional pci dev/pci/pci_subr.c optional pci dev/pci/pci_user.c optional pci dev/pci/pcib_if.m standard dev/pci/pcib_support.c standard dev/pci/vga_pci.c optional pci dev/phy/phy.c optional phy dev/phy/phydev_if.m optional phy fdt dev/phy/phynode_if.m optional phy dev/phy/phy_usb.c optional phy dev/phy/phynode_usb_if.m optional phy dev/pms/freebsd/driver/ini/src/agtiapi.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sadisc.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/mpi.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/saframe.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sahw.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sainit.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/saint.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sampicmd.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sampirsp.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/saphy.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/saport.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sasata.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sasmp.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sassp.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/satimer.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sautil.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/saioctlcmd.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/mpidebug.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/discovery/dm/dminit.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/discovery/dm/dmsmp.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/discovery/dm/dmdisc.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/discovery/dm/dmport.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/discovery/dm/dmtimer.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/discovery/dm/dmmisc.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sat/src/sminit.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sat/src/smmisc.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sat/src/smsat.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sat/src/smsatcb.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sat/src/smsathw.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sat/src/smtimer.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdinit.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdmisc.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdesgl.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdport.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdint.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdioctl.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdhw.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/ossacmnapi.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tddmcmnapi.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdsmcmnapi.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdtimers.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sas/ini/itdio.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sas/ini/itdcb.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sas/ini/itdinit.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sas/ini/itddisc.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sata/host/sat.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sata/host/ossasat.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sata/host/sathw.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/ppbus/if_plip.c optional plip dev/ppbus/lpbb.c optional lpbb dev/ppbus/lpt.c optional lpt dev/ppbus/pcfclock.c optional pcfclock dev/ppbus/ppb_1284.c optional ppbus dev/ppbus/ppb_base.c optional ppbus dev/ppbus/ppb_msq.c optional ppbus dev/ppbus/ppbconf.c optional ppbus dev/ppbus/ppbus_if.m optional ppbus dev/ppbus/ppi.c optional ppi dev/ppbus/pps.c optional pps dev/ppc/ppc.c optional ppc dev/ppc/ppc_acpi.c optional ppc acpi dev/ppc/ppc_isa.c optional ppc isa dev/ppc/ppc_pci.c optional ppc pci dev/ppc/ppc_puc.c optional ppc puc dev/proto/proto_bus_isa.c optional proto acpi | proto isa dev/proto/proto_bus_pci.c optional proto pci dev/proto/proto_busdma.c optional proto dev/proto/proto_core.c optional proto dev/pst/pst-iop.c optional pst dev/pst/pst-pci.c optional pst pci dev/pst/pst-raid.c optional pst dev/pty/pty.c optional pty dev/puc/puc.c optional puc dev/puc/puc_cfg.c optional puc dev/puc/puc_pci.c optional puc pci dev/pwm/pwmc.c optional pwm | pwmc dev/pwm/pwmbus.c optional pwm | pwmbus dev/pwm/pwmbus_if.m optional pwm | pwmbus dev/pwm/ofw_pwm.c optional pwm fdt | pwmbus fdt dev/pwm/ofw_pwmbus.c optional pwm fdt | pwmbus fdt dev/pwm/pwm_backlight.c optional pwm pwm_backlight fdt backlight dev/quicc/quicc_core.c optional quicc dev/ral/rt2560.c optional ral dev/ral/rt2661.c optional ral dev/ral/rt2860.c optional ral dev/ral/if_ral_pci.c optional ral pci rt2561fw.c optional rt2561fw | ralfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rt2561.fw:rt2561fw -mrt2561 -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rt2561fw.c" rt2561fw.fwo optional rt2561fw | ralfw \ dependency "rt2561.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rt2561fw.fwo" rt2561.fw optional rt2561fw | ralfw \ dependency "$S/contrib/dev/ral/rt2561.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rt2561.fw" rt2561sfw.c optional rt2561sfw | ralfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rt2561s.fw:rt2561sfw -mrt2561s -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rt2561sfw.c" rt2561sfw.fwo optional rt2561sfw | ralfw \ dependency "rt2561s.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rt2561sfw.fwo" rt2561s.fw optional rt2561sfw | ralfw \ dependency "$S/contrib/dev/ral/rt2561s.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rt2561s.fw" rt2661fw.c optional rt2661fw | ralfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rt2661.fw:rt2661fw -mrt2661 -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rt2661fw.c" rt2661fw.fwo optional rt2661fw | ralfw \ dependency "rt2661.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rt2661fw.fwo" rt2661.fw optional rt2661fw | ralfw \ dependency "$S/contrib/dev/ral/rt2661.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rt2661.fw" rt2860fw.c optional rt2860fw | ralfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rt2860.fw:rt2860fw -mrt2860 -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rt2860fw.c" rt2860fw.fwo optional rt2860fw | ralfw \ dependency "rt2860.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rt2860fw.fwo" rt2860.fw optional rt2860fw | ralfw \ dependency "$S/contrib/dev/ral/rt2860.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rt2860.fw" dev/random/random_infra.c standard dev/random/random_harvestq.c standard dev/random/randomdev.c optional !random_loadable dev/random/fenestrasX/fx_brng.c optional !random_loadable random_fenestrasx dev/random/fenestrasX/fx_main.c optional !random_loadable random_fenestrasx \ compile-with "${NORMAL_C} -I$S/crypto/blake2" dev/random/fenestrasX/fx_pool.c optional !random_loadable random_fenestrasx \ compile-with "${NORMAL_C} -I$S/crypto/blake2" dev/random/fenestrasX/fx_rng.c optional !random_loadable random_fenestrasx \ compile-with "${NORMAL_C} -I$S/crypto/blake2" dev/random/fortuna.c optional !random_loadable !random_fenestrasx dev/random/hash.c optional !random_loadable dev/rccgpio/rccgpio.c optional rccgpio gpio dev/re/if_re.c optional re dev/regulator/regdev_if.m optional regulator fdt dev/regulator/regnode_if.m optional regulator dev/regulator/regulator.c optional regulator dev/regulator/regulator_bus.c optional regulator fdt dev/regulator/regulator_fixed.c optional regulator dev/rl/if_rl.c optional rl pci dev/rndtest/rndtest.c optional rndtest # dev/rtsx/rtsx.c optional rtsx pci # dev/rtwn/if_rtwn.c optional rtwn dev/rtwn/if_rtwn_beacon.c optional rtwn dev/rtwn/if_rtwn_calib.c optional rtwn dev/rtwn/if_rtwn_cam.c optional rtwn dev/rtwn/if_rtwn_efuse.c optional rtwn dev/rtwn/if_rtwn_fw.c optional rtwn dev/rtwn/if_rtwn_rx.c optional rtwn dev/rtwn/if_rtwn_task.c optional rtwn dev/rtwn/if_rtwn_tx.c optional rtwn # dev/rtwn/pci/rtwn_pci_attach.c optional rtwn_pci pci dev/rtwn/pci/rtwn_pci_reg.c optional rtwn_pci pci dev/rtwn/pci/rtwn_pci_rx.c optional rtwn_pci pci dev/rtwn/pci/rtwn_pci_tx.c optional rtwn_pci pci # dev/rtwn/usb/rtwn_usb_attach.c optional rtwn_usb dev/rtwn/usb/rtwn_usb_ep.c optional rtwn_usb dev/rtwn/usb/rtwn_usb_reg.c optional rtwn_usb dev/rtwn/usb/rtwn_usb_rx.c optional rtwn_usb dev/rtwn/usb/rtwn_usb_tx.c optional rtwn_usb # RTL8188E dev/rtwn/rtl8188e/r88e_beacon.c optional rtwn dev/rtwn/rtl8188e/r88e_calib.c optional rtwn dev/rtwn/rtl8188e/r88e_chan.c optional rtwn dev/rtwn/rtl8188e/r88e_fw.c optional rtwn dev/rtwn/rtl8188e/r88e_init.c optional rtwn dev/rtwn/rtl8188e/r88e_led.c optional rtwn dev/rtwn/rtl8188e/r88e_tx.c optional rtwn dev/rtwn/rtl8188e/r88e_rf.c optional rtwn dev/rtwn/rtl8188e/r88e_rom.c optional rtwn dev/rtwn/rtl8188e/r88e_rx.c optional rtwn dev/rtwn/rtl8188e/pci/r88ee_attach.c optional rtwn_pci pci dev/rtwn/rtl8188e/pci/r88ee_init.c optional rtwn_pci pci dev/rtwn/rtl8188e/pci/r88ee_rx.c optional rtwn_pci pci dev/rtwn/rtl8188e/usb/r88eu_attach.c optional rtwn_usb dev/rtwn/rtl8188e/usb/r88eu_init.c optional rtwn_usb # RTL8192C dev/rtwn/rtl8192c/r92c_attach.c optional rtwn dev/rtwn/rtl8192c/r92c_beacon.c optional rtwn dev/rtwn/rtl8192c/r92c_calib.c optional rtwn dev/rtwn/rtl8192c/r92c_chan.c optional rtwn dev/rtwn/rtl8192c/r92c_fw.c optional rtwn dev/rtwn/rtl8192c/r92c_init.c optional rtwn dev/rtwn/rtl8192c/r92c_llt.c optional rtwn dev/rtwn/rtl8192c/r92c_rf.c optional rtwn dev/rtwn/rtl8192c/r92c_rom.c optional rtwn dev/rtwn/rtl8192c/r92c_rx.c optional rtwn dev/rtwn/rtl8192c/r92c_tx.c optional rtwn dev/rtwn/rtl8192c/pci/r92ce_attach.c optional rtwn_pci pci dev/rtwn/rtl8192c/pci/r92ce_calib.c optional rtwn_pci pci dev/rtwn/rtl8192c/pci/r92ce_fw.c optional rtwn_pci pci dev/rtwn/rtl8192c/pci/r92ce_init.c optional rtwn_pci pci dev/rtwn/rtl8192c/pci/r92ce_led.c optional rtwn_pci pci dev/rtwn/rtl8192c/pci/r92ce_rx.c optional rtwn_pci pci dev/rtwn/rtl8192c/pci/r92ce_tx.c optional rtwn_pci pci dev/rtwn/rtl8192c/usb/r92cu_attach.c optional rtwn_usb dev/rtwn/rtl8192c/usb/r92cu_init.c optional rtwn_usb dev/rtwn/rtl8192c/usb/r92cu_led.c optional rtwn_usb dev/rtwn/rtl8192c/usb/r92cu_rx.c optional rtwn_usb dev/rtwn/rtl8192c/usb/r92cu_tx.c optional rtwn_usb # RTL8192E dev/rtwn/rtl8192e/r92e_chan.c optional rtwn dev/rtwn/rtl8192e/r92e_fw.c optional rtwn dev/rtwn/rtl8192e/r92e_init.c optional rtwn dev/rtwn/rtl8192e/r92e_led.c optional rtwn dev/rtwn/rtl8192e/r92e_rf.c optional rtwn dev/rtwn/rtl8192e/r92e_rom.c optional rtwn dev/rtwn/rtl8192e/r92e_rx.c optional rtwn dev/rtwn/rtl8192e/usb/r92eu_attach.c optional rtwn_usb dev/rtwn/rtl8192e/usb/r92eu_init.c optional rtwn_usb # RTL8812A dev/rtwn/rtl8812a/r12a_beacon.c optional rtwn dev/rtwn/rtl8812a/r12a_calib.c optional rtwn dev/rtwn/rtl8812a/r12a_caps.c optional rtwn dev/rtwn/rtl8812a/r12a_chan.c optional rtwn dev/rtwn/rtl8812a/r12a_fw.c optional rtwn dev/rtwn/rtl8812a/r12a_init.c optional rtwn dev/rtwn/rtl8812a/r12a_led.c optional rtwn dev/rtwn/rtl8812a/r12a_rf.c optional rtwn dev/rtwn/rtl8812a/r12a_rom.c optional rtwn dev/rtwn/rtl8812a/r12a_rx.c optional rtwn dev/rtwn/rtl8812a/r12a_tx.c optional rtwn dev/rtwn/rtl8812a/usb/r12au_attach.c optional rtwn_usb dev/rtwn/rtl8812a/usb/r12au_init.c optional rtwn_usb dev/rtwn/rtl8812a/usb/r12au_rx.c optional rtwn_usb dev/rtwn/rtl8812a/usb/r12au_tx.c optional rtwn_usb # RTL8821A dev/rtwn/rtl8821a/r21a_beacon.c optional rtwn dev/rtwn/rtl8821a/r21a_calib.c optional rtwn dev/rtwn/rtl8821a/r21a_chan.c optional rtwn dev/rtwn/rtl8821a/r21a_fw.c optional rtwn dev/rtwn/rtl8821a/r21a_init.c optional rtwn dev/rtwn/rtl8821a/r21a_led.c optional rtwn dev/rtwn/rtl8821a/r21a_rom.c optional rtwn dev/rtwn/rtl8821a/r21a_rx.c optional rtwn dev/rtwn/rtl8821a/usb/r21au_attach.c optional rtwn_usb dev/rtwn/rtl8821a/usb/r21au_dfs.c optional rtwn_usb dev/rtwn/rtl8821a/usb/r21au_init.c optional rtwn_usb rtwn-rtl8188eefw.c optional rtwn-rtl8188eefw | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8188eefw.fw:rtwn-rtl8188eefw:111 -mrtwn-rtl8188eefw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rtwn-rtl8188eefw.c" rtwn-rtl8188eefw.fwo optional rtwn-rtl8188eefw | rtwnfw \ dependency "rtwn-rtl8188eefw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8188eefw.fwo" rtwn-rtl8188eefw.fw optional rtwn-rtl8188eefw | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8188eefw.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8188eefw.fw" rtwn-rtl8188eufw.c optional rtwn-rtl8188eufw | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8188eufw.fw:rtwn-rtl8188eufw:111 -mrtwn-rtl8188eufw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rtwn-rtl8188eufw.c" rtwn-rtl8188eufw.fwo optional rtwn-rtl8188eufw | rtwnfw \ dependency "rtwn-rtl8188eufw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8188eufw.fwo" rtwn-rtl8188eufw.fw optional rtwn-rtl8188eufw | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8188eufw.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8188eufw.fw" rtwn-rtl8192cfwE.c optional rtwn-rtl8192cfwE | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8192cfwE.fw:rtwn-rtl8192cfwE:111 -mrtwn-rtl8192cfwE -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rtwn-rtl8192cfwE.c" rtwn-rtl8192cfwE.fwo optional rtwn-rtl8192cfwE | rtwnfw \ dependency "rtwn-rtl8192cfwE.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8192cfwE.fwo" rtwn-rtl8192cfwE.fw optional rtwn-rtl8192cfwE | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8192cfwE.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8192cfwE.fw" rtwn-rtl8192cfwE_B.c optional rtwn-rtl8192cfwE_B | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8192cfwE_B.fw:rtwn-rtl8192cfwE_B:111 -mrtwn-rtl8192cfwE_B -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rtwn-rtl8192cfwE_B.c" rtwn-rtl8192cfwE_B.fwo optional rtwn-rtl8192cfwE_B | rtwnfw \ dependency "rtwn-rtl8192cfwE_B.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8192cfwE_B.fwo" rtwn-rtl8192cfwE_B.fw optional rtwn-rtl8192cfwE_B | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8192cfwE_B.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8192cfwE_B.fw" rtwn-rtl8192cfwT.c optional rtwn-rtl8192cfwT | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8192cfwT.fw:rtwn-rtl8192cfwT:111 -mrtwn-rtl8192cfwT -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rtwn-rtl8192cfwT.c" rtwn-rtl8192cfwT.fwo optional rtwn-rtl8192cfwT | rtwnfw \ dependency "rtwn-rtl8192cfwT.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8192cfwT.fwo" rtwn-rtl8192cfwT.fw optional rtwn-rtl8192cfwT | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8192cfwT.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8192cfwT.fw" rtwn-rtl8192cfwU.c optional rtwn-rtl8192cfwU | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8192cfwU.fw:rtwn-rtl8192cfwU:111 -mrtwn-rtl8192cfwU -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rtwn-rtl8192cfwU.c" rtwn-rtl8192cfwU.fwo optional rtwn-rtl8192cfwU | rtwnfw \ dependency "rtwn-rtl8192cfwU.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8192cfwU.fwo" rtwn-rtl8192cfwU.fw optional rtwn-rtl8192cfwU | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8192cfwU.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8192cfwU.fw" rtwn-rtl8192eufw.c optional rtwn-rtl8192eufw | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8192eufw.fw:rtwn-rtl8192eufw:111 -mrtwn-rtl8192eufw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rtwn-rtl8192eufw.c" rtwn-rtl8192eufw.fwo optional rtwn-rtl8192eufw | rtwnfw \ dependency "rtwn-rtl8192eufw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8192eufw.fwo" rtwn-rtl8192eufw.fw optional rtwn-rtl8192eufw | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8192eufw.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8192eufw.fw" rtwn-rtl8812aufw.c optional rtwn-rtl8812aufw | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8812aufw.fw:rtwn-rtl8812aufw:111 -mrtwn-rtl8812aufw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rtwn-rtl8812aufw.c" rtwn-rtl8812aufw.fwo optional rtwn-rtl8812aufw | rtwnfw \ dependency "rtwn-rtl8812aufw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8812aufw.fwo" rtwn-rtl8812aufw.fw optional rtwn-rtl8812aufw | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8812aufw.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8812aufw.fw" rtwn-rtl8821aufw.c optional rtwn-rtl8821aufw | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8821aufw.fw:rtwn-rtl8821aufw:111 -mrtwn-rtl8821aufw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rtwn-rtl8821aufw.c" rtwn-rtl8821aufw.fwo optional rtwn-rtl8821aufw | rtwnfw \ dependency "rtwn-rtl8821aufw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8821aufw.fwo" rtwn-rtl8821aufw.fw optional rtwn-rtl8821aufw | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8821aufw.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8821aufw.fw" dev/safe/safe.c optional safe dev/scc/scc_if.m optional scc dev/scc/scc_bfe_quicc.c optional scc quicc dev/scc/scc_core.c optional scc dev/scc/scc_dev_quicc.c optional scc quicc dev/scc/scc_dev_z8530.c optional scc dev/sdhci/sdhci.c optional sdhci dev/sdhci/sdhci_fdt.c optional sdhci fdt regulator clk dev/sdhci/sdhci_fdt_gpio.c optional sdhci fdt gpio dev/sdhci/sdhci_fsl_fdt.c optional sdhci fdt gpio regulator clk dev/sdhci/sdhci_if.m optional sdhci dev/sdhci/sdhci_acpi.c optional sdhci acpi dev/sdhci/sdhci_pci.c optional sdhci pci dev/sdio/sdio_if.m optional mmccam dev/sdio/sdio_subr.c optional mmccam dev/sdio/sdiob.c optional mmccam dev/sff/sff_if.m optional sff dev/sff/sfp_fdt.c optional sff fdt dev/sge/if_sge.c optional sge pci dev/siis/siis.c optional siis pci dev/sis/if_sis.c optional sis pci dev/sk/if_sk.c optional sk pci dev/smbios/smbios.c optional smbios dev/smbus/smb.c optional smb dev/smbus/smbconf.c optional smbus dev/smbus/smbus.c optional smbus dev/smbus/smbus_if.m optional smbus dev/smc/if_smc.c optional smc dev/smc/if_smc_acpi.c optional smc acpi dev/smc/if_smc_fdt.c optional smc fdt dev/snp/snp.c optional snp dev/sound/clone.c optional sound dev/sound/unit.c optional sound dev/sound/pci/als4000.c optional snd_als4000 pci dev/sound/pci/atiixp.c optional snd_atiixp pci dev/sound/pci/cmi.c optional snd_cmi pci dev/sound/pci/cs4281.c optional snd_cs4281 pci dev/sound/pci/csa.c optional snd_csa pci dev/sound/pci/csapcm.c optional snd_csa pci dev/sound/pci/emu10k1.c optional snd_emu10k1 pci dev/sound/pci/emu10kx.c optional snd_emu10kx pci dev/sound/pci/emu10kx-pcm.c optional snd_emu10kx pci dev/sound/pci/emu10kx-midi.c optional snd_emu10kx pci dev/sound/pci/envy24.c optional snd_envy24 pci dev/sound/pci/envy24ht.c optional snd_envy24ht pci dev/sound/pci/es137x.c optional snd_es137x pci dev/sound/pci/fm801.c optional snd_fm801 pci dev/sound/pci/ich.c optional snd_ich pci dev/sound/pci/maestro3.c optional snd_maestro3 pci dev/sound/pci/neomagic.c optional snd_neomagic pci dev/sound/pci/solo.c optional snd_solo pci dev/sound/pci/spicds.c optional snd_spicds pci dev/sound/pci/t4dwave.c optional snd_t4dwave pci dev/sound/pci/via8233.c optional snd_via8233 pci dev/sound/pci/via82c686.c optional snd_via82c686 pci dev/sound/pci/vibes.c optional snd_vibes pci dev/sound/pci/hda/hdaa.c optional snd_hda pci dev/sound/pci/hda/hdaa_patches.c optional snd_hda pci dev/sound/pci/hda/hdac.c optional snd_hda pci dev/sound/pci/hda/hdac_if.m optional snd_hda pci dev/sound/pci/hda/hdacc.c optional snd_hda pci dev/sound/pci/hdspe.c optional snd_hdspe pci dev/sound/pci/hdspe-pcm.c optional snd_hdspe pci dev/sound/pcm/ac97.c optional sound dev/sound/pcm/ac97_if.m optional sound dev/sound/pcm/ac97_patch.c optional sound dev/sound/pcm/buffer.c optional sound \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/channel.c optional sound dev/sound/pcm/channel_if.m optional sound dev/sound/pcm/dsp.c optional sound dev/sound/pcm/feeder.c optional sound dev/sound/pcm/feeder_chain.c optional sound dev/sound/pcm/feeder_eq.c optional sound \ dependency "feeder_eq_gen.h" \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/feeder_if.m optional sound dev/sound/pcm/feeder_format.c optional sound \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/feeder_matrix.c optional sound \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/feeder_mixer.c optional sound \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/feeder_rate.c optional sound \ dependency "feeder_rate_gen.h" \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/feeder_volume.c optional sound \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/mixer.c optional sound dev/sound/pcm/mixer_if.m optional sound dev/sound/pcm/sndstat.c optional sound dev/sound/pcm/sound.c optional sound dev/sound/pcm/vchan.c optional sound dev/sound/usb/uaudio.c optional snd_uaudio usb dev/sound/usb/uaudio_pcm.c optional snd_uaudio usb dev/sound/midi/midi.c optional sound dev/sound/midi/mpu401.c optional sound dev/sound/midi/mpu_if.m optional sound dev/sound/midi/mpufoi_if.m optional sound dev/sound/midi/sequencer.c optional sound dev/sound/midi/synth_if.m optional sound dev/spibus/acpi_spibus.c optional acpi spibus dev/spibus/ofw_spibus.c optional fdt spibus dev/spibus/spibus.c optional spibus \ dependency "spibus_if.h" dev/spibus/spigen.c optional spigen dev/spibus/spibus_if.m optional spibus dev/ste/if_ste.c optional ste pci dev/stge/if_stge.c optional stge dev/sym/sym_hipd.c optional sym \ dependency "$S/dev/sym/sym_{conf,defs}.h" +dev/syscon/syscon.c optional syscon +dev/syscon/syscon_generic.c optional syscon fdt +dev/syscon/syscon_if.m optional syscon +dev/syscon/syscon_power.c optional syscon syscon_power dev/syscons/blank/blank_saver.c optional blank_saver dev/syscons/daemon/daemon_saver.c optional daemon_saver dev/syscons/dragon/dragon_saver.c optional dragon_saver dev/syscons/fade/fade_saver.c optional fade_saver dev/syscons/fire/fire_saver.c optional fire_saver dev/syscons/green/green_saver.c optional green_saver dev/syscons/logo/logo.c optional logo_saver dev/syscons/logo/logo_saver.c optional logo_saver dev/syscons/rain/rain_saver.c optional rain_saver dev/syscons/schistory.c optional sc dev/syscons/scmouse.c optional sc dev/syscons/scterm.c optional sc dev/syscons/scterm-dumb.c optional sc !SC_NO_TERM_DUMB dev/syscons/scterm-sc.c optional sc !SC_NO_TERM_SC dev/syscons/scterm-teken.c optional sc !SC_NO_TERM_TEKEN dev/syscons/scvidctl.c optional sc dev/syscons/scvtb.c optional sc dev/syscons/snake/snake_saver.c optional snake_saver dev/syscons/star/star_saver.c optional star_saver dev/syscons/syscons.c optional sc dev/syscons/sysmouse.c optional sc dev/syscons/warp/warp_saver.c optional warp_saver dev/tcp_log/tcp_log_dev.c optional tcp_blackbox inet | tcp_blackbox inet6 dev/tdfx/tdfx_pci.c optional tdfx pci dev/ti/if_ti.c optional ti pci dev/tws/tws.c optional tws dev/tws/tws_cam.c optional tws dev/tws/tws_hdm.c optional tws dev/tws/tws_services.c optional tws dev/tws/tws_user.c optional tws dev/uart/uart_bus_acpi.c optional uart acpi dev/uart/uart_bus_fdt.c optional uart fdt dev/uart/uart_bus_isa.c optional uart isa dev/uart/uart_bus_pci.c optional uart pci dev/uart/uart_bus_puc.c optional uart puc dev/uart/uart_bus_scc.c optional uart scc dev/uart/uart_core.c optional uart dev/uart/uart_cpu_acpi.c optional uart acpi dev/uart/uart_dbg.c optional uart gdb dev/uart/uart_dev_imx.c optional uart uart_imx fdt dev/uart/uart_dev_msm.c optional uart uart_msm fdt dev/uart/uart_dev_mvebu.c optional uart uart_mvebu fdt dev/uart/uart_dev_ns8250.c optional uart uart_ns8250 | uart uart_snps dev/uart/uart_dev_pl011.c optional uart pl011 dev/uart/uart_dev_quicc.c optional uart quicc dev/uart/uart_dev_snps.c optional uart uart_snps fdt dev/uart/uart_dev_z8530.c optional uart uart_z8530 | uart scc dev/uart/uart_if.m optional uart dev/uart/uart_subr.c optional uart dev/uart/uart_tty.c optional uart # # USB controller drivers # dev/usb/controller/musb_otg.c optional musb dev/usb/controller/dwc_otg.c optional dwcotg dev/usb/controller/dwc_otg_fdt.c optional dwcotg fdt dev/usb/controller/dwc_otg_acpi.c optional dwcotg acpi dev/usb/controller/ehci.c optional ehci dev/usb/controller/ehci_msm.c optional ehci_msm fdt dev/usb/controller/ehci_pci.c optional ehci pci dev/usb/controller/ohci.c optional ohci dev/usb/controller/ohci_pci.c optional ohci pci dev/usb/controller/uhci.c optional uhci dev/usb/controller/uhci_pci.c optional uhci pci dev/usb/controller/xhci.c optional xhci dev/usb/controller/xhci_pci.c optional xhci pci dev/usb/controller/saf1761_otg.c optional saf1761otg dev/usb/controller/saf1761_otg_fdt.c optional saf1761otg fdt dev/usb/controller/uss820dci.c optional uss820dci dev/usb/controller/usb_controller.c optional usb # # USB storage drivers # dev/usb/storage/cfumass.c optional cfumass ctl dev/usb/storage/umass.c optional umass dev/usb/storage/urio.c optional urio dev/usb/storage/ustorage_fs.c optional usfs # # USB core # dev/usb/usb_busdma.c optional usb dev/usb/usb_core.c optional usb dev/usb/usb_debug.c optional usb dev/usb/usb_dev.c optional usb dev/usb/usb_device.c optional usb dev/usb/usb_dynamic.c optional usb dev/usb/usb_error.c optional usb dev/usb/usb_fdt_support.c optional usb fdt dev/usb/usb_generic.c optional usb dev/usb/usb_handle_request.c optional usb dev/usb/usb_hid.c optional usb dev/usb/usb_hub.c optional usb dev/usb/usb_hub_acpi.c optional uacpi acpi dev/usb/usb_if.m optional usb dev/usb/usb_lookup.c optional usb dev/usb/usb_mbuf.c optional usb dev/usb/usb_msctest.c optional usb dev/usb/usb_parse.c optional usb dev/usb/usb_pf.c optional usb dev/usb/usb_process.c optional usb dev/usb/usb_request.c optional usb dev/usb/usb_transfer.c optional usb dev/usb/usb_util.c optional usb # # USB network drivers # dev/usb/net/if_aue.c optional aue dev/usb/net/if_axe.c optional axe dev/usb/net/if_axge.c optional axge dev/usb/net/if_cdce.c optional cdce dev/usb/net/if_cdceem.c optional cdceem dev/usb/net/if_cue.c optional cue dev/usb/net/if_ipheth.c optional ipheth dev/usb/net/if_kue.c optional kue dev/usb/net/if_mos.c optional mos dev/usb/net/if_muge.c optional muge dev/usb/net/if_rue.c optional rue dev/usb/net/if_smsc.c optional smsc dev/usb/net/if_udav.c optional udav dev/usb/net/if_ure.c optional ure dev/usb/net/if_usie.c optional usie dev/usb/net/if_urndis.c optional urndis dev/usb/net/ruephy.c optional rue dev/usb/net/usb_ethernet.c optional uether | aue | axe | axge | cdce | \ cdceem | cue | ipheth | kue | mos | \ rue | smsc | udav | ure | urndis | muge dev/usb/net/uhso.c optional uhso # # USB WLAN drivers # dev/usb/wlan/if_rsu.c optional rsu rsu-rtl8712fw.c optional rsu-rtl8712fw | rsufw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rsu-rtl8712fw.fw:rsu-rtl8712fw:120 -mrsu-rtl8712fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rsu-rtl8712fw.c" rsu-rtl8712fw.fwo optional rsu-rtl8712fw | rsufw \ dependency "rsu-rtl8712fw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rsu-rtl8712fw.fwo" rsu-rtl8712fw.fw optional rsu-rtl8712.fw | rsufw \ dependency "$S/contrib/dev/rsu/rsu-rtl8712fw.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rsu-rtl8712fw.fw" dev/usb/wlan/if_rum.c optional rum dev/usb/wlan/if_run.c optional run runfw.c optional runfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk run.fw:runfw -mrunfw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "runfw.c" runfw.fwo optional runfw \ dependency "run.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "runfw.fwo" run.fw optional runfw \ dependency "$S/contrib/dev/run/rt2870.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "run.fw" dev/usb/wlan/if_uath.c optional uath dev/usb/wlan/if_upgt.c optional upgt dev/usb/wlan/if_ural.c optional ural dev/usb/wlan/if_urtw.c optional urtw dev/usb/wlan/if_zyd.c optional zyd # # USB serial and parallel port drivers # dev/usb/serial/u3g.c optional u3g dev/usb/serial/uark.c optional uark dev/usb/serial/ubsa.c optional ubsa dev/usb/serial/ubser.c optional ubser dev/usb/serial/uchcom.c optional uchcom dev/usb/serial/ucycom.c optional ucycom dev/usb/serial/ufoma.c optional ufoma dev/usb/serial/uftdi.c optional uftdi dev/usb/serial/ugensa.c optional ugensa dev/usb/serial/uipaq.c optional uipaq dev/usb/serial/ulpt.c optional ulpt dev/usb/serial/umcs.c optional umcs dev/usb/serial/umct.c optional umct dev/usb/serial/umodem.c optional umodem dev/usb/serial/umoscom.c optional umoscom dev/usb/serial/uplcom.c optional uplcom dev/usb/serial/uslcom.c optional uslcom dev/usb/serial/uvisor.c optional uvisor dev/usb/serial/uvscom.c optional uvscom dev/usb/serial/usb_serial.c optional ucom | u3g | uark | ubsa | ubser | \ uchcom | ucycom | ufoma | uftdi | \ ugensa | uipaq | umcs | umct | \ umodem | umoscom | uplcom | usie | \ uslcom | uvisor | uvscom # # USB misc drivers # dev/usb/misc/cp2112.c optional cp2112 dev/usb/misc/udbp.c optional udbp dev/usb/misc/ugold.c optional ugold dev/usb/misc/uled.c optional uled # # USB input drivers # dev/usb/input/atp.c optional atp dev/usb/input/uep.c optional uep dev/usb/input/uhid.c optional uhid dev/usb/input/uhid_snes.c optional uhid_snes dev/usb/input/ukbd.c optional ukbd dev/usb/input/ums.c optional ums dev/usb/input/usbhid.c optional usbhid dev/usb/input/wmt.c optional wmt dev/usb/input/wsp.c optional wsp # # USB quirks # dev/usb/quirk/usb_quirk.c optional usb # # USB templates # dev/usb/template/usb_template.c optional usb_template dev/usb/template/usb_template_audio.c optional usb_template dev/usb/template/usb_template_cdce.c optional usb_template dev/usb/template/usb_template_kbd.c optional usb_template dev/usb/template/usb_template_modem.c optional usb_template dev/usb/template/usb_template_mouse.c optional usb_template dev/usb/template/usb_template_msc.c optional usb_template dev/usb/template/usb_template_mtp.c optional usb_template dev/usb/template/usb_template_phone.c optional usb_template dev/usb/template/usb_template_serialnet.c optional usb_template dev/usb/template/usb_template_midi.c optional usb_template dev/usb/template/usb_template_multi.c optional usb_template dev/usb/template/usb_template_cdceem.c optional usb_template # # USB video drivers # dev/usb/video/udl.c optional udl # # USB END # dev/videomode/videomode.c optional videomode dev/videomode/edid.c optional videomode dev/videomode/pickmode.c optional videomode dev/videomode/vesagtf.c optional videomode dev/veriexec/verified_exec.c optional mac_veriexec dev/vge/if_vge.c optional vge dev/viapm/viapm.c optional viapm pci dev/virtio/virtio.c optional virtio dev/virtio/virtqueue.c optional virtio dev/virtio/virtio_bus_if.m optional virtio dev/virtio/virtio_if.m optional virtio dev/virtio/pci/virtio_pci.c optional virtio_pci dev/virtio/pci/virtio_pci_if.m optional virtio_pci dev/virtio/pci/virtio_pci_legacy.c optional virtio_pci dev/virtio/pci/virtio_pci_modern.c optional virtio_pci dev/virtio/mmio/virtio_mmio.c optional virtio_mmio dev/virtio/mmio/virtio_mmio_acpi.c optional virtio_mmio acpi dev/virtio/mmio/virtio_mmio_cmdline.c optional virtio_mmio dev/virtio/mmio/virtio_mmio_fdt.c optional virtio_mmio fdt dev/virtio/mmio/virtio_mmio_if.m optional virtio_mmio dev/virtio/network/if_vtnet.c optional vtnet dev/virtio/block/virtio_blk.c optional virtio_blk dev/virtio/balloon/virtio_balloon.c optional virtio_balloon dev/virtio/gpu/virtio_gpu.c optional virtio_gpu dev/virtio/scsi/virtio_scsi.c optional virtio_scsi dev/virtio/random/virtio_random.c optional virtio_random dev/virtio/console/virtio_console.c optional virtio_console dev/vkbd/vkbd.c optional vkbd dev/vmgenc/vmgenc_acpi.c optional acpi dev/vmware/vmxnet3/if_vmx.c optional vmx dev/vmware/vmci/vmci.c optional vmci dev/vmware/vmci/vmci_datagram.c optional vmci dev/vmware/vmci/vmci_doorbell.c optional vmci dev/vmware/vmci/vmci_driver.c optional vmci dev/vmware/vmci/vmci_event.c optional vmci dev/vmware/vmci/vmci_hashtable.c optional vmci dev/vmware/vmci/vmci_kernel_if.c optional vmci dev/vmware/vmci/vmci_qpair.c optional vmci dev/vmware/vmci/vmci_queue_pair.c optional vmci dev/vmware/vmci/vmci_resource.c optional vmci dev/vmware/pvscsi/pvscsi.c optional pvscsi dev/vr/if_vr.c optional vr pci dev/vt/colors/vt_termcolors.c optional vt dev/vt/font/vt_font_default.c optional vt dev/vt/font/vt_mouse_cursor.c optional vt dev/vt/hw/efifb/efifb.c optional vt_efifb dev/vt/hw/simplefb/simplefb.c optional vt_simplefb fdt dev/vt/hw/vbefb/vbefb.c optional vt_vbefb dev/vt/hw/fb/vt_fb.c optional vt dev/vt/hw/vga/vt_vga.c optional vt vt_vga dev/vt/logo/logo_freebsd.c optional vt splash dev/vt/logo/logo_beastie.c optional vt splash dev/vt/vt_buf.c optional vt dev/vt/vt_consolectl.c optional vt dev/vt/vt_core.c optional vt dev/vt/vt_cpulogos.c optional vt splash dev/vt/vt_font.c optional vt dev/vt/vt_sysmouse.c optional vt dev/vte/if_vte.c optional vte pci dev/watchdog/watchdog.c standard dev/wg/if_wg.c optional wg \ compile-with "${NORMAL_C} -include $S/dev/wg/compat.h" dev/wg/wg_cookie.c optional wg \ compile-with "${NORMAL_C} -include $S/dev/wg/compat.h" dev/wg/wg_crypto.c optional wg \ compile-with "${NORMAL_C} -include $S/dev/wg/compat.h" dev/wg/wg_noise.c optional wg \ compile-with "${NORMAL_C} -include $S/dev/wg/compat.h" dev/wpi/if_wpi.c optional wpi pci wpifw.c optional wpifw \ compile-with "${AWK} -f $S/tools/fw_stub.awk wpi.fw:wpifw:153229 -mwpi -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "wpifw.c" wpifw.fwo optional wpifw \ dependency "wpi.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "wpifw.fwo" wpi.fw optional wpifw \ dependency "$S/contrib/dev/wpi/iwlwifi-3945-15.32.2.9.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "wpi.fw" dev/xdma/controller/pl330.c optional xdma pl330 fdt dev/xdma/xdma.c optional xdma dev/xdma/xdma_bank.c optional xdma dev/xdma/xdma_bio.c optional xdma dev/xdma/xdma_fdt_test.c optional xdma xdma_test fdt dev/xdma/xdma_if.m optional xdma dev/xdma/xdma_iommu.c optional xdma dev/xdma/xdma_mbuf.c optional xdma dev/xdma/xdma_queue.c optional xdma dev/xdma/xdma_sg.c optional xdma dev/xdma/xdma_sglist.c optional xdma dev/xen/balloon/balloon.c optional xenhvm dev/xen/blkfront/blkfront.c optional xenhvm dev/xen/blkback/blkback.c optional xenhvm dev/xen/bus/xen_intr.c optional xenhvm dev/xen/bus/xenpv.c optional xenhvm dev/xen/console/xen_console.c optional xenhvm dev/xen/control/control.c optional xenhvm dev/xen/cpu/xen_acpi_cpu.c optional xenhvm acpi dev/xen/efi/pvefi.c optional xenhvm xenefi efirt dev/xen/grant_table/grant_table.c optional xenhvm dev/xen/netback/netback.c optional xenhvm dev/xen/netfront/netfront.c optional xenhvm dev/xen/timer/xen_timer.c optional xenhvm xentimer dev/xen/xenpci/xenpci.c optional xenpci dev/xen/xenstore/xenstore.c optional xenhvm dev/xen/xenstore/xenstore_dev.c optional xenhvm dev/xen/xenstore/xenstored_dev.c optional xenhvm dev/xen/evtchn/evtchn_dev.c optional xenhvm dev/xen/privcmd/privcmd.c optional xenhvm dev/xen/gntdev/gntdev.c optional xenhvm dev/xen/debug/debug.c optional xenhvm dev/xl/if_xl.c optional xl pci dev/xl/xlphy.c optional xl pci fs/autofs/autofs.c optional autofs fs/autofs/autofs_vfsops.c optional autofs fs/autofs/autofs_vnops.c optional autofs fs/deadfs/dead_vnops.c standard fs/devfs/devfs_devs.c standard fs/devfs/devfs_dir.c standard fs/devfs/devfs_rule.c standard fs/devfs/devfs_vfsops.c standard fs/devfs/devfs_vnops.c standard fs/fdescfs/fdesc_vfsops.c optional fdescfs fs/fdescfs/fdesc_vnops.c optional fdescfs fs/fifofs/fifo_vnops.c standard fs/cuse/cuse.c optional cuse fs/fuse/fuse_device.c optional fusefs fs/fuse/fuse_file.c optional fusefs fs/fuse/fuse_internal.c optional fusefs fs/fuse/fuse_io.c optional fusefs fs/fuse/fuse_ipc.c optional fusefs fs/fuse/fuse_main.c optional fusefs fs/fuse/fuse_node.c optional fusefs fs/fuse/fuse_vfsops.c optional fusefs fs/fuse/fuse_vnops.c optional fusefs fs/mntfs/mntfs_vnops.c standard fs/msdosfs/msdosfs_conv.c optional msdosfs fs/msdosfs/msdosfs_denode.c optional msdosfs fs/msdosfs/msdosfs_fat.c optional msdosfs fs/msdosfs/msdosfs_iconv.c optional msdosfs_iconv fs/msdosfs/msdosfs_lookup.c optional msdosfs fs/msdosfs/msdosfs_vfsops.c optional msdosfs fs/msdosfs/msdosfs_vnops.c optional msdosfs fs/nfs/nfs_commonkrpc.c optional nfscl | nfslockd | nfsd fs/nfs/nfs_commonsubs.c optional nfscl | nfslockd | nfsd fs/nfs/nfs_commonport.c optional nfscl | nfslockd | nfsd fs/nfs/nfs_commonacl.c optional nfscl | nfslockd | nfsd fs/nfsclient/nfs_clcomsubs.c optional nfscl fs/nfsclient/nfs_clsubs.c optional nfscl fs/nfsclient/nfs_clstate.c optional nfscl fs/nfsclient/nfs_clkrpc.c optional nfscl fs/nfsclient/nfs_clrpcops.c optional nfscl fs/nfsclient/nfs_clvnops.c optional nfscl fs/nfsclient/nfs_clnode.c optional nfscl fs/nfsclient/nfs_clvfsops.c optional nfscl fs/nfsclient/nfs_clport.c optional nfscl fs/nfsclient/nfs_clbio.c optional nfscl fs/nfsclient/nfs_clnfsiod.c optional nfscl fs/nfsserver/nfs_fha_new.c optional nfsd inet fs/nfsserver/nfs_nfsdsocket.c optional nfsd inet fs/nfsserver/nfs_nfsdsubs.c optional nfsd inet fs/nfsserver/nfs_nfsdstate.c optional nfsd inet fs/nfsserver/nfs_nfsdkrpc.c optional nfsd inet fs/nfsserver/nfs_nfsdserv.c optional nfsd inet fs/nfsserver/nfs_nfsdport.c optional nfsd inet fs/nfsserver/nfs_nfsdcache.c optional nfsd inet fs/nullfs/null_subr.c optional nullfs fs/nullfs/null_vfsops.c optional nullfs fs/nullfs/null_vnops.c optional nullfs fs/procfs/procfs.c optional procfs fs/procfs/procfs_dbregs.c optional procfs fs/procfs/procfs_fpregs.c optional procfs fs/procfs/procfs_map.c optional procfs fs/procfs/procfs_mem.c optional procfs fs/procfs/procfs_note.c optional procfs fs/procfs/procfs_osrel.c optional procfs fs/procfs/procfs_regs.c optional procfs fs/procfs/procfs_rlimit.c optional procfs fs/procfs/procfs_status.c optional procfs fs/procfs/procfs_type.c optional procfs fs/pseudofs/pseudofs.c optional pseudofs fs/pseudofs/pseudofs_fileno.c optional pseudofs fs/pseudofs/pseudofs_vncache.c optional pseudofs fs/pseudofs/pseudofs_vnops.c optional pseudofs fs/smbfs/smbfs_io.c optional smbfs fs/smbfs/smbfs_node.c optional smbfs fs/smbfs/smbfs_smb.c optional smbfs fs/smbfs/smbfs_subr.c optional smbfs fs/smbfs/smbfs_vfsops.c optional smbfs fs/smbfs/smbfs_vnops.c optional smbfs fs/tarfs/tarfs_io.c optional tarfs compile-with "${NORMAL_C} -I$S/contrib/zstd/lib/freebsd" fs/tarfs/tarfs_subr.c optional tarfs fs/tarfs/tarfs_vfsops.c optional tarfs fs/tarfs/tarfs_vnops.c optional tarfs fs/udf/osta.c optional udf fs/udf/udf_iconv.c optional udf_iconv fs/udf/udf_vfsops.c optional udf fs/udf/udf_vnops.c optional udf fs/unionfs/union_subr.c optional unionfs fs/unionfs/union_vfsops.c optional unionfs fs/unionfs/union_vnops.c optional unionfs fs/tmpfs/tmpfs_vnops.c optional tmpfs fs/tmpfs/tmpfs_fifoops.c optional tmpfs fs/tmpfs/tmpfs_vfsops.c optional tmpfs fs/tmpfs/tmpfs_subr.c optional tmpfs gdb/gdb_cons.c optional gdb gdb/gdb_main.c optional gdb gdb/gdb_packet.c optional gdb gdb/netgdb.c optional ddb debugnet gdb netgdb inet geom/bde/g_bde.c optional geom_bde geom/bde/g_bde_crypt.c optional geom_bde geom/bde/g_bde_lock.c optional geom_bde geom/bde/g_bde_work.c optional geom_bde geom/cache/g_cache.c optional geom_cache geom/concat/g_concat.c optional geom_concat geom/eli/g_eli.c optional geom_eli geom/eli/g_eli_crypto.c optional geom_eli geom/eli/g_eli_ctl.c optional geom_eli geom/eli/g_eli_hmac.c optional geom_eli geom/eli/g_eli_integrity.c optional geom_eli geom/eli/g_eli_key.c optional geom_eli geom/eli/g_eli_key_cache.c optional geom_eli geom/eli/g_eli_privacy.c optional geom_eli geom/eli/pkcs5v2.c optional geom_eli geom/gate/g_gate.c optional geom_gate geom/geom_bsd_enc.c optional geom_part_bsd geom/geom_ccd.c optional ccd | geom_ccd geom/geom_ctl.c standard geom/geom_dev.c standard geom/geom_disk.c standard geom/geom_dump.c standard geom/geom_event.c standard geom/geom_flashmap.c optional fdt cfi | fdt mx25l | mmcsd | fdt n25q | fdt at45d geom/geom_io.c standard geom/geom_kern.c standard geom/geom_map.c optional geom_map geom/geom_redboot.c optional geom_redboot geom/geom_slice.c standard geom/geom_subr.c standard geom/geom_vfs.c standard geom/journal/g_journal.c optional geom_journal geom/journal/g_journal_ufs.c optional geom_journal geom/label/g_label.c optional geom_label | geom_label_gpt geom/label/g_label_ext2fs.c optional geom_label geom/label/g_label_flashmap.c optional geom_label geom/label/g_label_iso9660.c optional geom_label geom/label/g_label_msdosfs.c optional geom_label geom/label/g_label_ntfs.c optional geom_label geom/label/g_label_reiserfs.c optional geom_label geom/label/g_label_ufs.c optional geom_label geom/label/g_label_gpt.c optional geom_label | geom_label_gpt geom/label/g_label_disk_ident.c optional geom_label geom/linux_lvm/g_linux_lvm.c optional geom_linux_lvm geom/mirror/g_mirror.c optional geom_mirror geom/mirror/g_mirror_ctl.c optional geom_mirror geom/mountver/g_mountver.c optional geom_mountver geom/multipath/g_multipath.c optional geom_multipath geom/nop/g_nop.c optional geom_nop geom/part/g_part.c standard geom/part/g_part_if.m standard geom/part/g_part_apm.c optional geom_part_apm geom/part/g_part_bsd.c optional geom_part_bsd geom/part/g_part_bsd64.c optional geom_part_bsd64 geom/part/g_part_ebr.c optional geom_part_ebr geom/part/g_part_gpt.c optional geom_part_gpt geom/part/g_part_ldm.c optional geom_part_ldm geom/part/g_part_mbr.c optional geom_part_mbr geom/raid/g_raid.c optional geom_raid geom/raid/g_raid_ctl.c optional geom_raid geom/raid/g_raid_md_if.m optional geom_raid geom/raid/g_raid_tr_if.m optional geom_raid geom/raid/md_ddf.c optional geom_raid geom/raid/md_intel.c optional geom_raid geom/raid/md_jmicron.c optional geom_raid geom/raid/md_nvidia.c optional geom_raid geom/raid/md_promise.c optional geom_raid geom/raid/md_sii.c optional geom_raid geom/raid/tr_concat.c optional geom_raid geom/raid/tr_raid0.c optional geom_raid geom/raid/tr_raid1.c optional geom_raid geom/raid/tr_raid1e.c optional geom_raid geom/raid/tr_raid5.c optional geom_raid geom/raid3/g_raid3.c optional geom_raid3 geom/raid3/g_raid3_ctl.c optional geom_raid3 geom/shsec/g_shsec.c optional geom_shsec geom/stripe/g_stripe.c optional geom_stripe geom/union/g_union.c optional geom_union geom/uzip/g_uzip.c optional geom_uzip geom/uzip/g_uzip_lzma.c optional geom_uzip geom/uzip/g_uzip_wrkthr.c optional geom_uzip geom/uzip/g_uzip_zlib.c optional geom_uzip geom/uzip/g_uzip_zstd.c optional geom_uzip zstdio \ compile-with "${NORMAL_C} -I$S/contrib/zstd/lib/freebsd" geom/vinum/geom_vinum.c optional geom_vinum geom/vinum/geom_vinum_create.c optional geom_vinum geom/vinum/geom_vinum_drive.c optional geom_vinum geom/vinum/geom_vinum_plex.c optional geom_vinum geom/vinum/geom_vinum_volume.c optional geom_vinum geom/vinum/geom_vinum_subr.c optional geom_vinum geom/vinum/geom_vinum_raid5.c optional geom_vinum geom/vinum/geom_vinum_share.c optional geom_vinum geom/vinum/geom_vinum_list.c optional geom_vinum geom/vinum/geom_vinum_rm.c optional geom_vinum geom/vinum/geom_vinum_init.c optional geom_vinum geom/vinum/geom_vinum_state.c optional geom_vinum geom/vinum/geom_vinum_rename.c optional geom_vinum geom/vinum/geom_vinum_move.c optional geom_vinum geom/vinum/geom_vinum_events.c optional geom_vinum geom/virstor/binstream.c optional geom_virstor geom/virstor/g_virstor.c optional geom_virstor geom/virstor/g_virstor_md.c optional geom_virstor geom/zero/g_zero.c optional geom_zero fs/ext2fs/ext2_acl.c optional ext2fs fs/ext2fs/ext2_alloc.c optional ext2fs fs/ext2fs/ext2_balloc.c optional ext2fs fs/ext2fs/ext2_bmap.c optional ext2fs fs/ext2fs/ext2_csum.c optional ext2fs fs/ext2fs/ext2_extattr.c optional ext2fs fs/ext2fs/ext2_extents.c optional ext2fs fs/ext2fs/ext2_inode.c optional ext2fs fs/ext2fs/ext2_inode_cnv.c optional ext2fs fs/ext2fs/ext2_hash.c optional ext2fs fs/ext2fs/ext2_htree.c optional ext2fs fs/ext2fs/ext2_lookup.c optional ext2fs fs/ext2fs/ext2_subr.c optional ext2fs fs/ext2fs/ext2_vfsops.c optional ext2fs fs/ext2fs/ext2_vnops.c optional ext2fs # isa/isa_if.m standard isa/isa_common.c optional isa isa/isahint.c optional isa isa/pnp.c optional isa isapnp isa/pnpparse.c optional isa isapnp fs/cd9660/cd9660_bmap.c optional cd9660 fs/cd9660/cd9660_lookup.c optional cd9660 fs/cd9660/cd9660_node.c optional cd9660 fs/cd9660/cd9660_rrip.c optional cd9660 fs/cd9660/cd9660_util.c optional cd9660 fs/cd9660/cd9660_vfsops.c optional cd9660 fs/cd9660/cd9660_vnops.c optional cd9660 fs/cd9660/cd9660_iconv.c optional cd9660_iconv gnu/gcov/gcc_4_7.c optional gcov \ warning "kernel contains GPL licensed gcov support" gnu/gcov/gcov_fs.c optional gcov lindebugfs \ compile-with "${LINUXKPI_C}" gnu/gcov/gcov_subr.c optional gcov kern/bus_if.m standard kern/clock_if.m standard kern/cpufreq_if.m standard kern/device_if.m standard kern/imgact_binmisc.c optional imgact_binmisc kern/imgact_elf.c standard kern/imgact_elf32.c optional compat_freebsd32 kern/imgact_shell.c standard kern/init_main.c standard kern/init_sysent.c standard kern/ksched.c optional _kposix_priority_scheduling kern/kern_acct.c standard kern/kern_alq.c optional alq kern/kern_boottrace.c standard kern/kern_clock.c standard kern/kern_clocksource.c standard kern/kern_condvar.c standard kern/kern_conf.c standard kern/kern_cons.c standard kern/kern_cpu.c standard kern/kern_cpuset.c standard kern/kern_context.c standard kern/kern_descrip.c standard kern/kern_devctl.c standard kern/kern_dtrace.c optional kdtrace_hooks kern/kern_dump.c standard kern/kern_environment.c standard kern/kern_et.c standard kern/kern_event.c standard kern/kern_exec.c standard kern/kern_exit.c standard kern/kern_fail.c standard kern/kern_ffclock.c standard kern/kern_fork.c standard kern/kern_hhook.c standard kern/kern_idle.c standard kern/kern_intr.c standard kern/kern_jail.c standard kern/kern_kcov.c optional kcov \ compile-with "${NORMAL_C:N-fsanitize*} ${NORMAL_C:M-fsanitize=kernel-memory}" kern/kern_khelp.c standard kern/kern_kthread.c standard kern/kern_ktr.c optional ktr kern/kern_ktrace.c standard kern/kern_linker.c standard kern/kern_lock.c standard kern/kern_lockf.c standard kern/kern_lockstat.c optional kdtrace_hooks kern/kern_loginclass.c standard kern/kern_malloc.c standard kern/kern_mbuf.c standard kern/kern_membarrier.c standard kern/kern_mib.c standard kern/kern_module.c standard kern/kern_mtxpool.c standard kern/kern_mutex.c standard kern/kern_ntptime.c standard kern/kern_osd.c standard kern/kern_physio.c standard kern/kern_pmc.c standard kern/kern_poll.c optional device_polling kern/kern_priv.c standard kern/kern_proc.c standard kern/kern_procctl.c standard kern/kern_prot.c standard kern/kern_racct.c optional racct kern/kern_rangelock.c standard kern/kern_rctl.c standard kern/kern_resource.c standard kern/kern_rmlock.c standard kern/kern_rwlock.c standard kern/kern_sdt.c optional kdtrace_hooks kern/kern_sema.c standard kern/kern_sendfile.c standard kern/kern_sharedpage.c standard kern/kern_shutdown.c standard kern/kern_sig.c standard kern/kern_switch.c standard kern/kern_sx.c standard kern/kern_synch.c standard kern/kern_syscalls.c standard kern/kern_sysctl.c standard kern/kern_tc.c standard kern/kern_thr.c standard kern/kern_thread.c standard kern/kern_time.c standard kern/kern_timeout.c standard kern/kern_tslog.c optional tslog kern/kern_ubsan.c optional kubsan kern/kern_umtx.c standard kern/kern_uuid.c standard kern/kern_vnodedumper.c standard kern/kern_xxx.c standard kern/link_elf.c standard kern/linker_if.m standard kern/md4c.c optional netsmb kern/md5c.c standard kern/p1003_1b.c standard kern/posix4_mib.c standard kern/sched_4bsd.c optional sched_4bsd kern/sched_ule.c optional sched_ule kern/serdev_if.m standard kern/stack_protector.c standard \ compile-with "${NORMAL_C:N-fstack-protector*}" kern/subr_acl_nfs4.c optional ufs_acl | zfs kern/subr_acl_posix1e.c optional ufs_acl kern/subr_asan.c optional kasan \ compile-with "${NORMAL_C:N-fsanitize*:N-fstack-protector*}" kern/subr_autoconf.c standard kern/subr_blist.c standard kern/subr_boot.c standard kern/subr_bus.c standard kern/subr_bus_dma.c standard kern/subr_bufring.c standard kern/subr_capability.c standard kern/subr_clock.c standard kern/subr_compressor.c standard \ compile-with "${NORMAL_C} -I$S/contrib/zstd/lib/freebsd" kern/subr_coverage.c optional coverage \ compile-with "${NORMAL_C:N-fsanitize*}" kern/subr_counter.c standard kern/subr_csan.c optional kcsan \ compile-with "${NORMAL_C:N-fsanitize*:N-fstack-protector*}" kern/subr_devstat.c standard kern/subr_disk.c standard kern/subr_early.c standard kern/subr_epoch.c standard kern/subr_eventhandler.c standard kern/subr_fattime.c standard kern/subr_firmware.c optional firmware kern/subr_filter.c standard kern/subr_gtaskqueue.c standard kern/subr_hash.c standard kern/subr_hints.c standard kern/subr_kdb.c standard kern/subr_kobj.c standard kern/subr_lock.c standard kern/subr_log.c standard kern/subr_mchain.c optional libmchain kern/subr_memdesc.c standard kern/subr_module.c standard kern/subr_msan.c optional kmsan \ compile-with "${NORMAL_C:N-fsanitize*:N-fno-sanitize*:N-fstack-protector*}" kern/subr_msgbuf.c standard kern/subr_param.c standard kern/subr_pcpu.c standard kern/subr_pctrie.c standard kern/subr_pidctrl.c standard kern/subr_power.c standard kern/subr_prf.c standard kern/subr_prng.c standard kern/subr_prof.c standard kern/subr_rangeset.c standard kern/subr_rman.c standard kern/subr_rtc.c standard kern/subr_sbuf.c standard kern/subr_scanf.c standard kern/subr_sglist.c standard kern/subr_sleepqueue.c standard kern/subr_smp.c standard kern/subr_smr.c standard kern/subr_stack.c optional ddb | stack | ktr kern/subr_stats.c optional stats kern/subr_taskqueue.c standard kern/subr_terminal.c optional vt kern/subr_trap.c standard kern/subr_turnstile.c standard kern/subr_uio.c standard kern/subr_unit.c standard kern/subr_vmem.c standard kern/subr_witness.c optional witness kern/sys_capability.c standard kern/sys_eventfd.c standard kern/sys_generic.c standard kern/sys_getrandom.c standard kern/sys_pipe.c standard kern/sys_procdesc.c standard kern/sys_process.c standard kern/sys_socket.c standard kern/sys_timerfd.c standard kern/syscalls.c standard kern/sysv_ipc.c standard kern/sysv_msg.c optional sysvmsg kern/sysv_sem.c optional sysvsem kern/sysv_shm.c optional sysvshm kern/tty.c standard kern/tty_compat.c optional compat_43tty kern/tty_info.c standard kern/tty_inq.c standard kern/tty_outq.c standard kern/tty_pts.c standard kern/tty_tty.c standard kern/tty_ttydisc.c standard kern/uipc_accf.c standard kern/uipc_debug.c optional ddb kern/uipc_domain.c standard kern/uipc_ktls.c optional kern_tls kern/uipc_mbuf.c standard kern/uipc_mbuf2.c standard kern/uipc_mbufhash.c standard kern/uipc_mqueue.c optional p1003_1b_mqueue kern/uipc_sem.c optional p1003_1b_semaphores kern/uipc_shm.c standard kern/uipc_sockbuf.c standard kern/uipc_socket.c standard kern/uipc_syscalls.c standard kern/uipc_usrreq.c standard kern/vfs_acl.c standard kern/vfs_aio.c standard kern/vfs_bio.c standard kern/vfs_cache.c standard kern/vfs_cluster.c standard kern/vfs_default.c standard kern/vfs_export.c standard kern/vfs_extattr.c standard kern/vfs_hash.c standard kern/vfs_init.c standard kern/vfs_lookup.c standard kern/vfs_mount.c standard kern/vfs_mountroot.c standard kern/vfs_subr.c standard kern/vfs_syscalls.c standard kern/vfs_vnops.c standard # # Kernel GSS-API # gssd.h optional kgssapi \ dependency "$S/kgssapi/gssd.x" \ compile-with "RPCGEN_CPP='${CPP}' rpcgen -hM $S/kgssapi/gssd.x | grep -v pthread.h > gssd.h" \ no-obj no-implicit-rule before-depend local \ clean "gssd.h" gssd_xdr.c optional kgssapi \ dependency "$S/kgssapi/gssd.x gssd.h" \ compile-with "RPCGEN_CPP='${CPP}' rpcgen -c $S/kgssapi/gssd.x -o gssd_xdr.c" \ no-ctfconvert no-implicit-rule before-depend local \ clean "gssd_xdr.c" gssd_clnt.c optional kgssapi \ dependency "$S/kgssapi/gssd.x gssd.h" \ compile-with "RPCGEN_CPP='${CPP}' rpcgen -lM $S/kgssapi/gssd.x | grep -v string.h > gssd_clnt.c" \ no-ctfconvert no-implicit-rule before-depend local \ clean "gssd_clnt.c" kgssapi/gss_accept_sec_context.c optional kgssapi kgssapi/gss_add_oid_set_member.c optional kgssapi kgssapi/gss_acquire_cred.c optional kgssapi kgssapi/gss_canonicalize_name.c optional kgssapi kgssapi/gss_create_empty_oid_set.c optional kgssapi kgssapi/gss_delete_sec_context.c optional kgssapi kgssapi/gss_display_status.c optional kgssapi kgssapi/gss_export_name.c optional kgssapi kgssapi/gss_get_mic.c optional kgssapi kgssapi/gss_init_sec_context.c optional kgssapi kgssapi/gss_impl.c optional kgssapi kgssapi/gss_import_name.c optional kgssapi kgssapi/gss_ip_to_dns.c optional kgssapi kgssapi/gss_names.c optional kgssapi kgssapi/gss_pname_to_uid.c optional kgssapi kgssapi/gss_release_buffer.c optional kgssapi kgssapi/gss_release_cred.c optional kgssapi kgssapi/gss_release_name.c optional kgssapi kgssapi/gss_release_oid_set.c optional kgssapi kgssapi/gss_set_cred_option.c optional kgssapi kgssapi/gss_test_oid_set_member.c optional kgssapi kgssapi/gss_unwrap.c optional kgssapi kgssapi/gss_verify_mic.c optional kgssapi kgssapi/gss_wrap.c optional kgssapi kgssapi/gss_wrap_size_limit.c optional kgssapi kgssapi/gssd_prot.c optional kgssapi kgssapi/krb5/krb5_mech.c optional kgssapi kgssapi/krb5/kcrypto.c optional kgssapi kgssapi/krb5/kcrypto_aes.c optional kgssapi kgssapi/kgss_if.m optional kgssapi kgssapi/gsstest.c optional kgssapi_debug # These files in libkern/ are those needed by all architectures. Some # of the files in libkern/ are only needed on some architectures, e.g., # libkern/divdi3.c is needed by i386 but not alpha. Also, some of these # routines may be optimized for a particular platform. In either case, # the file should be moved to conf/files. from here. # libkern/arc4random.c standard libkern/arc4random_uniform.c standard libkern/asprintf.c standard libkern/bcd.c standard libkern/bsearch.c standard libkern/crc16.c standard libkern/explicit_bzero.c standard libkern/fnmatch.c standard libkern/gsb_crc32.c standard libkern/iconv.c optional libiconv libkern/iconv_converter_if.m optional libiconv libkern/iconv_ucs.c optional libiconv libkern/iconv_xlat.c optional libiconv libkern/iconv_xlat16.c optional libiconv libkern/inet_aton.c standard libkern/inet_ntoa.c standard libkern/inet_ntop.c standard libkern/inet_pton.c standard libkern/jenkins_hash.c standard libkern/murmur3_32.c standard libkern/memcchr.c standard libkern/memchr.c standard libkern/memmem.c optional gdb libkern/qsort.c standard libkern/qsort_r.c standard libkern/random.c standard libkern/scanc.c standard libkern/strcasecmp.c standard libkern/strcasestr.c standard libkern/strcat.c standard libkern/strchr.c standard libkern/strchrnul.c standard libkern/strcpy.c standard libkern/strcspn.c standard libkern/strdup.c standard libkern/strndup.c standard libkern/strlcat.c standard libkern/strlcpy.c standard libkern/strncat.c standard libkern/strncpy.c standard libkern/strnlen.c standard libkern/strnstr.c standard libkern/strrchr.c standard libkern/strsep.c standard libkern/strspn.c standard libkern/strstr.c standard libkern/strtol.c standard libkern/strtoq.c standard libkern/strtoul.c standard libkern/strtouq.c standard libkern/strvalid.c standard libkern/timingsafe_bcmp.c standard contrib/zlib/adler32.c optional crypto | geom_uzip | \ mxge | ddb_ctf | gzio | zfs | zlib \ compile-with "${ZLIB_C}" contrib/zlib/compress.c optional crypto | geom_uzip | \ mxge | ddb_ctf | gzio | zfs | zlib \ compile-with "${ZLIB_C}" contrib/zlib/crc32.c optional crypto | geom_uzip | \ mxge | ddb_ctf | gzio | zfs | zlib \ compile-with "${ZLIB_C}" contrib/zlib/deflate.c optional crypto | geom_uzip | \ mxge | ddb_ctf | gzio | zfs | zlib \ compile-with "${ZLIB_C}" contrib/zlib/inffast.c optional crypto | geom_uzip | \ mxge | ddb_ctf | gzio | zfs | zlib \ compile-with "${ZLIB_C}" contrib/zlib/inflate.c optional crypto | geom_uzip | \ mxge | ddb_ctf | gzio | zfs | zlib \ compile-with "${ZLIB_C}" contrib/zlib/inftrees.c optional crypto | geom_uzip | \ mxge | ddb_ctf | gzio | zfs | zlib \ compile-with "${ZLIB_C}" contrib/zlib/trees.c optional crypto | geom_uzip | \ mxge | ddb_ctf | gzio | zfs | zlib \ compile-with "${ZLIB_C}" contrib/zlib/uncompr.c optional crypto | geom_uzip | \ mxge | ddb_ctf | gzio | zfs | zlib \ compile-with "${ZLIB_C}" contrib/zlib/zutil.c optional crypto | geom_uzip | \ mxge | ddb_ctf | gzio | zfs | zlib \ compile-with "${ZLIB_C}" dev/zlib/zlib_mod.c optional crypto | geom_uzip | \ mxge | ddb_ctf | gzio | zfs | zlib dev/zlib/zcalloc.c optional crypto | geom_uzip | \ mxge | ddb_ctf | gzio | zfs | zlib net/altq/altq_cbq.c optional altq net/altq/altq_codel.c optional altq net/altq/altq_hfsc.c optional altq net/altq/altq_fairq.c optional altq net/altq/altq_priq.c optional altq net/altq/altq_red.c optional altq net/altq/altq_rio.c optional altq net/altq/altq_rmclass.c optional altq net/altq/altq_subr.c optional altq net/bpf.c standard net/bpf_buffer.c optional bpf net/bpf_jitter.c optional bpf_jitter net/bpf_filter.c optional bpf | netgraph_bpf net/bpf_zerocopy.c optional bpf net/bridgestp.c optional bridge | if_bridge net/ieee8023ad_lacp.c optional lagg net/if.c standard net/ifq.c standard net/if_bridge.c optional bridge inet | if_bridge inet net/if_clone.c standard net/if_dead.c standard net/if_disc.c optional disc net/if_edsc.c optional edsc net/if_enc.c optional enc inet | enc inet6 net/if_epair.c optional epair net/if_ethersubr.c optional ether net/if_fwsubr.c optional fwip net/if_gif.c optional gif inet | gif inet6 | \ netgraph_gif inet | netgraph_gif inet6 net/if_gre.c optional gre inet | gre inet6 net/if_ipsec.c optional inet ipsec | inet6 ipsec net/if_lagg.c optional lagg net/if_loop.c optional loop net/if_llatbl.c standard net/if_me.c optional me inet net/if_media.c standard net/if_mib.c standard net/if_ovpn.c optional ovpn inet | ovpn inet6 net/if_stf.c optional stf inet inet6 net/if_tuntap.c optional tuntap net/if_vlan.c optional vlan net/if_vxlan.c optional vxlan inet | vxlan inet6 net/ifdi_if.m optional ether pci iflib net/iflib.c optional ether pci iflib net/mp_ring.c optional ether iflib net/mppcc.c optional netgraph_mppc_compression net/mppcd.c optional netgraph_mppc_compression net/netisr.c standard net/debugnet.c optional inet debugnet net/debugnet_inet.c optional inet debugnet net/pfil.c optional ether | inet net/radix.c standard net/route.c standard net/route/nhgrp.c optional route_mpath net/route/nhgrp_ctl.c optional route_mpath net/route/nhop.c standard net/route/nhop_ctl.c standard net/route/nhop_utils.c standard net/route/fib_algo.c optional fib_algo net/route/route_ctl.c standard net/route/route_ddb.c optional ddb net/route/route_helpers.c standard net/route/route_ifaddrs.c standard net/route/route_rtentry.c standard net/route/route_subscription.c standard net/route/route_tables.c standard net/route/route_temporal.c standard net/rss_config.c optional inet rss | inet6 rss net/rtsock.c standard net/slcompress.c optional netgraph_vjc net/toeplitz.c optional inet rss | inet6 rss | route_mpath net/vnet.c optional vimage net80211/ieee80211.c optional wlan net80211/ieee80211_acl.c optional wlan wlan_acl net80211/ieee80211_action.c optional wlan net80211/ieee80211_adhoc.c optional wlan \ compile-with "${NORMAL_C} -Wno-unused-function" net80211/ieee80211_ageq.c optional wlan net80211/ieee80211_amrr.c optional wlan | wlan_amrr net80211/ieee80211_crypto.c optional wlan \ compile-with "${NORMAL_C} -Wno-unused-function" net80211/ieee80211_crypto_ccmp.c optional wlan wlan_ccmp net80211/ieee80211_crypto_none.c optional wlan net80211/ieee80211_crypto_tkip.c optional wlan wlan_tkip net80211/ieee80211_crypto_wep.c optional wlan wlan_wep net80211/ieee80211_ddb.c optional wlan ddb net80211/ieee80211_dfs.c optional wlan net80211/ieee80211_freebsd.c optional wlan net80211/ieee80211_hostap.c optional wlan \ compile-with "${NORMAL_C} -Wno-unused-function" net80211/ieee80211_ht.c optional wlan net80211/ieee80211_hwmp.c optional wlan ieee80211_support_mesh net80211/ieee80211_input.c optional wlan net80211/ieee80211_ioctl.c optional wlan net80211/ieee80211_mesh.c optional wlan ieee80211_support_mesh \ compile-with "${NORMAL_C} -Wno-unused-function" net80211/ieee80211_monitor.c optional wlan net80211/ieee80211_node.c optional wlan net80211/ieee80211_output.c optional wlan net80211/ieee80211_phy.c optional wlan net80211/ieee80211_power.c optional wlan net80211/ieee80211_proto.c optional wlan net80211/ieee80211_radiotap.c optional wlan net80211/ieee80211_ratectl.c optional wlan net80211/ieee80211_ratectl_none.c optional wlan net80211/ieee80211_regdomain.c optional wlan net80211/ieee80211_rssadapt.c optional wlan wlan_rssadapt net80211/ieee80211_scan.c optional wlan net80211/ieee80211_scan_sta.c optional wlan net80211/ieee80211_sta.c optional wlan \ compile-with "${NORMAL_C} -Wno-unused-function" net80211/ieee80211_superg.c optional wlan ieee80211_support_superg net80211/ieee80211_scan_sw.c optional wlan net80211/ieee80211_tdma.c optional wlan ieee80211_support_tdma net80211/ieee80211_vht.c optional wlan net80211/ieee80211_wds.c optional wlan net80211/ieee80211_xauth.c optional wlan wlan_xauth net80211/ieee80211_alq.c optional wlan ieee80211_alq netgraph/bluetooth/common/ng_bluetooth.c optional netgraph_bluetooth netgraph/bluetooth/drivers/ubt/ng_ubt.c optional netgraph_bluetooth_ubt usb netgraph/bluetooth/drivers/ubt/ng_ubt_intel.c optional netgraph_bluetooth_ubt usb netgraph/bluetooth/drivers/ubtbcmfw/ubtbcmfw.c optional netgraph_bluetooth_ubtbcmfw usb netgraph/bluetooth/hci/ng_hci_cmds.c optional netgraph_bluetooth_hci netgraph/bluetooth/hci/ng_hci_evnt.c optional netgraph_bluetooth_hci netgraph/bluetooth/hci/ng_hci_main.c optional netgraph_bluetooth_hci netgraph/bluetooth/hci/ng_hci_misc.c optional netgraph_bluetooth_hci netgraph/bluetooth/hci/ng_hci_ulpi.c optional netgraph_bluetooth_hci netgraph/bluetooth/l2cap/ng_l2cap_cmds.c optional netgraph_bluetooth_l2cap netgraph/bluetooth/l2cap/ng_l2cap_evnt.c optional netgraph_bluetooth_l2cap netgraph/bluetooth/l2cap/ng_l2cap_llpi.c optional netgraph_bluetooth_l2cap netgraph/bluetooth/l2cap/ng_l2cap_main.c optional netgraph_bluetooth_l2cap netgraph/bluetooth/l2cap/ng_l2cap_misc.c optional netgraph_bluetooth_l2cap netgraph/bluetooth/l2cap/ng_l2cap_ulpi.c optional netgraph_bluetooth_l2cap netgraph/bluetooth/socket/ng_btsocket.c optional netgraph_bluetooth_socket netgraph/bluetooth/socket/ng_btsocket_hci_raw.c optional netgraph_bluetooth_socket netgraph/bluetooth/socket/ng_btsocket_l2cap.c optional netgraph_bluetooth_socket netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c optional netgraph_bluetooth_socket netgraph/bluetooth/socket/ng_btsocket_rfcomm.c optional netgraph_bluetooth_socket netgraph/bluetooth/socket/ng_btsocket_sco.c optional netgraph_bluetooth_socket netgraph/netflow/netflow.c optional netgraph_netflow netgraph/netflow/netflow_v9.c optional netgraph_netflow netgraph/netflow/ng_netflow.c optional netgraph_netflow netgraph/ng_UI.c optional netgraph_UI netgraph/ng_async.c optional netgraph_async netgraph/ng_base.c optional netgraph netgraph/ng_bpf.c optional netgraph_bpf netgraph/ng_bridge.c optional netgraph_bridge netgraph/ng_car.c optional netgraph_car netgraph/ng_checksum.c optional netgraph_checksum netgraph/ng_cisco.c optional netgraph_cisco netgraph/ng_deflate.c optional netgraph_deflate netgraph/ng_device.c optional netgraph_device netgraph/ng_echo.c optional netgraph_echo netgraph/ng_eiface.c optional netgraph_eiface netgraph/ng_ether.c optional netgraph_ether netgraph/ng_ether_echo.c optional netgraph_ether_echo netgraph/ng_frame_relay.c optional netgraph_frame_relay netgraph/ng_gif.c optional netgraph_gif inet6 | netgraph_gif inet netgraph/ng_gif_demux.c optional netgraph_gif_demux netgraph/ng_hole.c optional netgraph_hole netgraph/ng_iface.c optional netgraph_iface netgraph/ng_ip_input.c optional netgraph_ip_input netgraph/ng_ipfw.c optional netgraph_ipfw inet ipfirewall netgraph/ng_ksocket.c optional netgraph_ksocket netgraph/ng_l2tp.c optional netgraph_l2tp netgraph/ng_lmi.c optional netgraph_lmi netgraph/ng_macfilter.c optional netgraph_macfilter netgraph/ng_mppc.c optional netgraph_mppc_compression | \ netgraph_mppc_encryption netgraph/ng_nat.c optional netgraph_nat inet libalias netgraph/ng_one2many.c optional netgraph_one2many netgraph/ng_parse.c optional netgraph netgraph/ng_patch.c optional netgraph_patch netgraph/ng_pipe.c optional netgraph_pipe netgraph/ng_ppp.c optional netgraph_ppp netgraph/ng_pppoe.c optional netgraph_pppoe netgraph/ng_pptpgre.c optional netgraph_pptpgre netgraph/ng_pred1.c optional netgraph_pred1 netgraph/ng_rfc1490.c optional netgraph_rfc1490 netgraph/ng_socket.c optional netgraph_socket netgraph/ng_split.c optional netgraph_split netgraph/ng_tag.c optional netgraph_tag netgraph/ng_tcpmss.c optional netgraph_tcpmss netgraph/ng_tee.c optional netgraph_tee netgraph/ng_tty.c optional netgraph_tty netgraph/ng_vjc.c optional netgraph_vjc netgraph/ng_vlan.c optional netgraph_vlan netgraph/ng_vlan_rotate.c optional netgraph_vlan_rotate netinet/accf_data.c optional accept_filter_data inet netinet/accf_dns.c optional accept_filter_dns inet netinet/accf_http.c optional accept_filter_http inet netinet/if_ether.c optional inet ether netinet/igmp.c optional inet netinet/in.c optional inet netinet/in_cksum.c optional inet | inet6 netinet/in_debug.c optional inet ddb netinet/in_kdtrace.c optional inet | inet6 netinet/ip_carp.c optional inet carp | inet6 carp netinet/in_fib.c optional inet netinet/in_fib_algo.c optional inet fib_algo netinet/in_gif.c optional gif inet | netgraph_gif inet netinet/ip_gre.c optional gre inet netinet/ip_id.c optional inet netinet/in_jail.c optional inet netinet/in_mcast.c optional inet netinet/in_pcb.c optional inet | inet6 netinet/in_prot.c optional inet | inet6 netinet/in_proto.c optional inet | inet6 netinet/in_rmx.c optional inet netinet/in_rss.c optional inet rss netinet/ip_divert.c optional ipdivert inet | ipdivert inet6 netinet/ip_ecn.c optional inet | inet6 netinet/ip_encap.c optional inet | inet6 netinet/ip_fastfwd.c optional inet netinet/ip_icmp.c optional inet | inet6 netinet/ip_input.c optional inet netinet/ip_mroute.c optional mrouting inet netinet/ip_options.c optional inet netinet/ip_output.c optional inet netinet/ip_reass.c optional inet netinet/raw_ip.c optional inet | inet6 netinet/cc/cc.c optional cc_newreno inet | cc_vegas inet | \ cc_htcp inet | cc_hd inet | cc_dctcp inet | cc_cubic inet | \ cc_chd inet | cc_cdg inet | cc_newreno inet6 | cc_vegas inet6 | \ cc_htcp inet6 | cc_hd inet6 |cc_dctcp inet6 | cc_cubic inet6 | \ cc_chd inet6 | cc_cdg inet6 netinet/cc/cc_cdg.c optional inet cc_cdg tcp_hhook netinet/cc/cc_chd.c optional inet cc_chd tcp_hhook netinet/cc/cc_cubic.c optional inet cc_cubic | inet6 cc_cubic netinet/cc/cc_dctcp.c optional inet cc_dctcp | inet6 cc_dctcp netinet/cc/cc_hd.c optional inet cc_hd tcp_hhook netinet/cc/cc_htcp.c optional inet cc_htcp | inet6 cc_htcp netinet/cc/cc_newreno.c optional inet cc_newreno | inet6 cc_newreno netinet/cc/cc_vegas.c optional inet cc_vegas tcp_hhook netinet/khelp/h_ertt.c optional inet tcp_hhook netinet/sctp_asconf.c optional inet sctp | inet6 sctp netinet/sctp_auth.c optional inet sctp | inet6 sctp netinet/sctp_bsd_addr.c optional inet sctp | inet6 sctp netinet/sctp_cc_functions.c optional inet sctp | inet6 sctp netinet/sctp_crc32.c optional inet | inet6 netinet/sctp_indata.c optional inet sctp | inet6 sctp netinet/sctp_input.c optional inet sctp | inet6 sctp netinet/sctp_kdtrace.c optional inet sctp | inet6 sctp netinet/sctp_module.c optional inet sctp | inet6 sctp netinet/sctp_output.c optional inet sctp | inet6 sctp netinet/sctp_pcb.c optional inet sctp | inet6 sctp netinet/sctp_peeloff.c optional inet sctp | inet6 sctp netinet/sctp_ss_functions.c optional inet sctp | inet6 sctp netinet/sctp_syscalls.c optional inet sctp | inet6 sctp netinet/sctp_sysctl.c optional inet sctp | inet6 sctp netinet/sctp_timer.c optional inet sctp | inet6 sctp netinet/sctp_usrreq.c optional inet sctp | inet6 sctp netinet/sctputil.c optional inet sctp | inet6 sctp netinet/siftr.c optional inet siftr alq | inet6 siftr alq netinet/tcp_ecn.c optional inet | inet6 netinet/tcp_fastopen.c optional inet tcp_rfc7413 | inet6 tcp_rfc7413 netinet/tcp_hostcache.c optional inet | inet6 netinet/tcp_input.c optional inet | inet6 netinet/tcp_log_buf.c optional tcp_blackbox inet | tcp_blackbox inet6 netinet/tcp_lro.c optional inet | inet6 netinet/tcp_lro_hpts.c optional tcphpts inet | tcphpts inet6 netinet/tcp_output.c optional inet | inet6 netinet/tcp_offload.c optional tcp_offload inet | tcp_offload inet6 netinet/tcp_hpts.c optional tcphpts inet | tcphpts inet6 netinet/tcp_ratelimit.c optional ratelimit inet | ratelimit inet6 netinet/tcp_pcap.c optional inet tcppcap | inet6 tcppcap \ compile-with "${NORMAL_C} ${NO_WNONNULL}" netinet/tcp_reass.c optional inet | inet6 netinet/tcp_sack.c optional inet | inet6 netinet/tcp_stacks/bbr.c optional inet tcphpts tcp_bbr | inet6 tcphpts tcp_bbr \ compile-with "${NORMAL_C} -DMODNAME=tcp_bbr -DSTACKNAME=bbr" netinet/tcp_stacks/rack.c optional inet tcphpts tcp_rack | inet6 tcphpts tcp_rack \ compile-with "${NORMAL_C} -DMODNAME=tcp_rack -DSTACKNAME=rack" netinet/tcp_stacks/rack_bbr_common.c optional inet tcphpts tcp_bbr | inet tcphpts tcp_rack | inet6 tcphpts tcp_bbr | inet6 tcphpts tcp_rack netinet/tcp_stacks/sack_filter.c optional inet tcphpts tcp_bbr | inet tcphpts tcp_rack | inet6 tcphpts tcp_bbr | inet6 tcphpts tcp_rack netinet/tcp_stacks/tailq_hash.c optional inet tcphpts tcp_bbr | inet tcphpts tcp_rack | inet6 tcphpts tcp_bbr | inet6 tcphpts tcp_rack netinet/tcp_stats.c optional stats inet | stats inet6 netinet/tcp_subr.c optional inet | inet6 netinet/tcp_syncache.c optional inet | inet6 netinet/tcp_timer.c optional inet | inet6 netinet/tcp_timewait.c optional inet | inet6 netinet/tcp_usrreq.c optional inet | inet6 netinet/udp_usrreq.c optional inet | inet6 netinet/libalias/alias.c optional libalias inet | netgraph_nat inet netinet/libalias/alias_db.c optional libalias inet | netgraph_nat inet netinet/libalias/alias_mod.c optional libalias | netgraph_nat netinet/libalias/alias_proxy.c optional libalias inet | netgraph_nat inet netinet/libalias/alias_util.c optional libalias inet | netgraph_nat inet netinet/libalias/alias_sctp.c optional libalias inet | netgraph_nat inet netinet/netdump/netdump_client.c optional inet debugnet netdump netinet6/dest6.c optional inet6 netinet6/frag6.c optional inet6 netinet6/icmp6.c optional inet6 netinet6/in6.c optional inet6 netinet6/in6_cksum.c optional inet6 netinet6/in6_fib.c optional inet6 netinet6/in6_fib_algo.c optional inet6 fib_algo netinet6/in6_gif.c optional gif inet6 | netgraph_gif inet6 netinet6/in6_ifattach.c optional inet6 netinet6/in6_jail.c optional inet6 netinet6/in6_mcast.c optional inet6 netinet6/in6_pcb.c optional inet6 netinet6/in6_proto.c optional inet6 netinet6/in6_rmx.c optional inet6 netinet6/in6_rss.c optional inet6 rss netinet6/in6_src.c optional inet6 netinet6/ip6_fastfwd.c optional inet6 netinet6/ip6_forward.c optional inet6 netinet6/ip6_gre.c optional gre inet6 netinet6/ip6_id.c optional inet6 netinet6/ip6_input.c optional inet6 netinet6/ip6_mroute.c optional mrouting inet6 netinet6/ip6_output.c optional inet6 netinet6/mld6.c optional inet6 netinet6/nd6.c optional inet6 netinet6/nd6_nbr.c optional inet6 netinet6/nd6_rtr.c optional inet6 netinet6/raw_ip6.c optional inet6 netinet6/route6.c optional inet6 netinet6/scope6.c optional inet6 netinet6/sctp6_usrreq.c optional inet6 sctp netinet6/udp6_usrreq.c optional inet6 netipsec/ipsec.c optional ipsec inet | ipsec inet6 netipsec/ipsec_input.c optional ipsec inet | ipsec inet6 netipsec/ipsec_mbuf.c optional ipsec inet | ipsec inet6 netipsec/ipsec_mod.c optional ipsec inet | ipsec inet6 netipsec/ipsec_output.c optional ipsec inet | ipsec inet6 netipsec/ipsec_pcb.c optional ipsec inet | ipsec inet6 | \ ipsec_support inet | ipsec_support inet6 netipsec/key.c optional ipsec inet | ipsec inet6 | \ ipsec_support inet | ipsec_support inet6 netipsec/key_debug.c optional ipsec inet | ipsec inet6 | \ ipsec_support inet | ipsec_support inet6 netipsec/keysock.c optional ipsec inet | ipsec inet6 | \ ipsec_support inet | ipsec_support inet6 netipsec/subr_ipsec.c optional ipsec inet | ipsec inet6 | \ ipsec_support inet | ipsec_support inet6 netipsec/udpencap.c optional ipsec inet netipsec/xform_ah.c optional ipsec inet | ipsec inet6 netipsec/xform_esp.c optional ipsec inet | ipsec inet6 netipsec/xform_ipcomp.c optional ipsec inet | ipsec inet6 netipsec/xform_tcp.c optional ipsec inet tcp_signature | \ ipsec inet6 tcp_signature | ipsec_support inet tcp_signature | \ ipsec_support inet6 tcp_signature netlink/netlink_generic_kpi.c standard netlink/netlink_glue.c standard netlink/netlink_message_parser.c standard netlink/netlink_domain.c optional netlink netlink/netlink_generic.c optional netlink netlink/netlink_io.c optional netlink netlink/netlink_message_writer.c optional netlink netlink/netlink_module.c optional netlink netlink/netlink_route.c optional netlink netlink/route/iface_drivers.c optional netlink netlink/route/iface.c optional netlink netlink/route/neigh.c optional netlink netlink/route/nexthop.c optional netlink netlink/route/rt.c optional netlink netpfil/ipfw/dn_aqm_codel.c optional inet dummynet netpfil/ipfw/dn_aqm_pie.c optional inet dummynet netpfil/ipfw/dn_heap.c optional inet dummynet netpfil/ipfw/dn_sched_fifo.c optional inet dummynet netpfil/ipfw/dn_sched_fq_codel.c optional inet dummynet netpfil/ipfw/dn_sched_fq_pie.c optional inet dummynet netpfil/ipfw/dn_sched_prio.c optional inet dummynet netpfil/ipfw/dn_sched_qfq.c optional inet dummynet netpfil/ipfw/dn_sched_rr.c optional inet dummynet netpfil/ipfw/dn_sched_wf2q.c optional inet dummynet netpfil/ipfw/ip_dummynet.c optional inet dummynet netpfil/ipfw/ip_dn_io.c optional inet dummynet netpfil/ipfw/ip_dn_glue.c optional inet dummynet netpfil/ipfw/ip_fw2.c optional inet ipfirewall netpfil/ipfw/ip_fw_bpf.c optional inet ipfirewall netpfil/ipfw/ip_fw_dynamic.c optional inet ipfirewall \ compile-with "${NORMAL_C} -I$S/contrib/ck/include" netpfil/ipfw/ip_fw_eaction.c optional inet ipfirewall netpfil/ipfw/ip_fw_log.c optional inet ipfirewall netpfil/ipfw/ip_fw_pfil.c optional inet ipfirewall netpfil/ipfw/ip_fw_sockopt.c optional inet ipfirewall netpfil/ipfw/ip_fw_table.c optional inet ipfirewall netpfil/ipfw/ip_fw_table_algo.c optional inet ipfirewall netpfil/ipfw/ip_fw_table_value.c optional inet ipfirewall netpfil/ipfw/ip_fw_iface.c optional inet ipfirewall netpfil/ipfw/ip_fw_nat.c optional inet ipfirewall_nat netpfil/ipfw/nat64/ip_fw_nat64.c optional inet inet6 ipfirewall \ ipfirewall_nat64 netpfil/ipfw/nat64/nat64clat.c optional inet inet6 ipfirewall \ ipfirewall_nat64 netpfil/ipfw/nat64/nat64clat_control.c optional inet inet6 ipfirewall \ ipfirewall_nat64 netpfil/ipfw/nat64/nat64lsn.c optional inet inet6 ipfirewall \ ipfirewall_nat64 compile-with "${NORMAL_C} -I$S/contrib/ck/include" netpfil/ipfw/nat64/nat64lsn_control.c optional inet inet6 ipfirewall \ ipfirewall_nat64 compile-with "${NORMAL_C} -I$S/contrib/ck/include" netpfil/ipfw/nat64/nat64stl.c optional inet inet6 ipfirewall \ ipfirewall_nat64 netpfil/ipfw/nat64/nat64stl_control.c optional inet inet6 ipfirewall \ ipfirewall_nat64 netpfil/ipfw/nat64/nat64_translate.c optional inet inet6 ipfirewall \ ipfirewall_nat64 netpfil/ipfw/nptv6/ip_fw_nptv6.c optional inet inet6 ipfirewall \ ipfirewall_nptv6 netpfil/ipfw/nptv6/nptv6.c optional inet inet6 ipfirewall \ ipfirewall_nptv6 netpfil/ipfw/pmod/ip_fw_pmod.c optional inet ipfirewall_pmod netpfil/ipfw/pmod/tcpmod.c optional inet ipfirewall_pmod netpfil/pf/if_pflog.c optional pflog pf inet netpfil/pf/if_pfsync.c optional pfsync pf inet netpfil/pf/pf.c optional pf inet netpfil/pf/pf_if.c optional pf inet netpfil/pf/pf_ioctl.c optional pf inet netpfil/pf/pf_lb.c optional pf inet netpfil/pf/pf_norm.c optional pf inet netpfil/pf/pf_nl.c optional pf inet netpfil/pf/pf_nv.c optional pf inet netpfil/pf/pf_osfp.c optional pf inet netpfil/pf/pf_ruleset.c optional pf inet netpfil/pf/pf_syncookies.c optional pf inet netpfil/pf/pf_table.c optional pf inet netpfil/pf/pfsync_nv.c optional pfsync pf inet netpfil/pf/in4_cksum.c optional pf inet netsmb/smb_conn.c optional netsmb netsmb/smb_crypt.c optional netsmb netsmb/smb_dev.c optional netsmb netsmb/smb_iod.c optional netsmb netsmb/smb_rq.c optional netsmb netsmb/smb_smb.c optional netsmb netsmb/smb_subr.c optional netsmb netsmb/smb_trantcp.c optional netsmb netsmb/smb_usr.c optional netsmb nfs/bootp_subr.c optional bootp nfscl nfs/krpc_subr.c optional bootp nfscl nfs/nfs_diskless.c optional nfscl nfs_root nfs/nfs_nfssvc.c optional nfscl | nfslockd | nfsd nlm/nlm_advlock.c optional nfslockd | nfsd nlm/nlm_prot_clnt.c optional nfslockd | nfsd nlm/nlm_prot_impl.c optional nfslockd | nfsd nlm/nlm_prot_server.c optional nfslockd | nfsd nlm/nlm_prot_svc.c optional nfslockd | nfsd nlm/nlm_prot_xdr.c optional nfslockd | nfsd nlm/sm_inter_xdr.c optional nfslockd | nfsd # Linux Kernel Programming Interface compat/linuxkpi/common/src/linux_80211.c optional compat_linuxkpi wlan \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_80211_macops.c optional compat_linuxkpi wlan \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_kmod.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_acpi.c optional compat_linuxkpi acpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_compat.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_current.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_devres.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_dmi.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_domain.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_firmware.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_fpu.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_hrtimer.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_i2c.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_i2cbb.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_interrupt.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_kobject.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_kthread.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_lock.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_mhi.c optional compat_linuxkpi wlan \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_netdev.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_page.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_pci.c optional compat_linuxkpi pci \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_tasklet.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_idr.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_radix.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_rcu.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C} -I$S/contrib/ck/include" compat/linuxkpi/common/src/linux_schedule.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_shmemfs.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_shrinker.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_skbuff.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_slab.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_usb.c optional compat_linuxkpi usb \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_work.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_xarray.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/lkpi_iic_if.m optional compat_linuxkpi compat/linuxkpi/common/src/linux_seq_file.c optional compat_linuxkpi | lindebugfs \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_simple_attr.c optional compat_linuxkpi | lindebugfs \ compile-with "${LINUXKPI_C}" compat/lindebugfs/lindebugfs.c optional lindebugfs \ compile-with "${LINUXKPI_C}" # OpenFabrics Enterprise Distribution (Infiniband) net/if_infiniband.c optional ofed | lagg ofed/drivers/infiniband/core/ib_addr.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_agent.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_cache.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_cm.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_cma.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_core_uverbs.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_cq.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_device.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_fmr_pool.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_iwcm.c optional ofed \ compile-with "${OFED_C} ${NO_WUNUSED_BUT_SET_VARIABLE}" ofed/drivers/infiniband/core/ib_iwpm_msg.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_iwpm_util.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_mad.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_mad_rmpp.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_multicast.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_packer.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_rdma_core.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_roce_gid_mgmt.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_sa_query.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_smi.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_sysfs.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_ucm.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_ucma.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_ud_header.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_umem.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_user_mad.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_cmd.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_ioctl.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_main.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_marshall.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_std_types.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_std_types_async_fd.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_std_types_counters.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_std_types_cq.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_std_types_device.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_std_types_dm.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_std_types_flow_action.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_std_types_mr.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_uapi.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_verbs.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/ulp/ipoib/ipoib_cm.c optional ipoib \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" #ofed/drivers/infiniband/ulp/ipoib/ipoib_fs.c optional ipoib \ # compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" ofed/drivers/infiniband/ulp/ipoib/ipoib_ib.c optional ipoib \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c optional ipoib \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" ofed/drivers/infiniband/ulp/ipoib/ipoib_multicast.c optional ipoib \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" ofed/drivers/infiniband/ulp/ipoib/ipoib_verbs.c optional ipoib \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" #ofed/drivers/infiniband/ulp/ipoib/ipoib_vlan.c optional ipoib \ # compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" ofed/drivers/infiniband/ulp/sdp/sdp_bcopy.c optional sdp inet \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/sdp/" ofed/drivers/infiniband/ulp/sdp/sdp_main.c optional sdp inet \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/sdp/" ofed/drivers/infiniband/ulp/sdp/sdp_rx.c optional sdp inet \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/sdp/ ${NO_WUNUSED_BUT_SET_VARIABLE}" ofed/drivers/infiniband/ulp/sdp/sdp_cma.c optional sdp inet \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/sdp/" ofed/drivers/infiniband/ulp/sdp/sdp_tx.c optional sdp inet \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/sdp/ ${NO_WUNUSED_BUT_SET_VARIABLE}" dev/irdma/icrdma.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/irdma_cm.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/irdma_ctrl.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/irdma_hmc.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/irdma_hw.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/icrdma_hw.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/fbsd_kcompat.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/irdma_kcompat.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/irdma_pble.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/irdma_puda.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/irdma_uda.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/irdma_uk.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/irdma_utils.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/irdma_verbs.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/irdma_ws.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/mthca/mthca_allocator.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_av.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_catas.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_cmd.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_cq.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_eq.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_mad.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_main.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_mcg.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_memfree.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_mr.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_pd.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_profile.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_provider.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_qp.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_reset.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_srq.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_uar.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_alias_GUID.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_mcg.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_sysfs.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_cm.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_ah.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_cq.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_doorbell.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_mad.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_main.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_mr.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_qp.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_srq.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_wc.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_alloc.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_catas.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_cmd.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_cq.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_eq.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_fw.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_fw_qos.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_icm.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_intf.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_main.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_mcg.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_mr.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_pd.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_port.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_profile.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_qp.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_reset.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_sense.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_srq.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_resource_tracker.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_cq.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_main.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_netdev.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_port.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_resources.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_rx.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_tx.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_ah.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_cong.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_cq.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_devx.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_doorbell.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_gsi.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_mad.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_main.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_mem.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_mr.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_qp.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_srq.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_virt.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_alloc.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_cmd.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_cq.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_diag_cnt.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_diagnostics.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_eq.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_eswitch.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_fc_cmd.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_fs_cmd.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_fs_counters.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_fs_tcp.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_fs_tree.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_fw.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_fwdump.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_health.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_mad.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_main.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_mcg.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_mpfs.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_mr.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_pagealloc.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_pd.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_port.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_qp.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_rl.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_srq.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_tls.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_transobj.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_uar.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_vport.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_vsc.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_wq.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_lib/mlx5_gid.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_dim.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_ethtool.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_main.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_tx.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_flow_table.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_hw_tls.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_hw_tls_rx.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_iq.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_rx.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_rl.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_txrx.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_port_buffer.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" # crypto support opencrypto/cbc_mac.c optional crypto opencrypto/criov.c optional crypto opencrypto/crypto.c optional crypto opencrypto/cryptodev.c optional cryptodev opencrypto/cryptodev_if.m optional crypto opencrypto/cryptosoft.c optional crypto opencrypto/cryptodeflate.c optional crypto opencrypto/gmac.c optional crypto opencrypto/gfmult.c optional crypto opencrypto/ktls_ocf.c optional kern_tls opencrypto/rmd160.c optional crypto opencrypto/xform_aes_cbc.c optional crypto opencrypto/xform_aes_icm.c optional crypto opencrypto/xform_aes_xts.c optional crypto opencrypto/xform_cbc_mac.c optional crypto opencrypto/xform_chacha20_poly1305.c optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include -I$S/crypto/libsodium" opencrypto/xform_cml.c optional crypto opencrypto/xform_deflate.c optional crypto opencrypto/xform_gmac.c optional crypto opencrypto/xform_null.c optional crypto opencrypto/xform_poly1305.c optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include -I$S/crypto/libsodium" opencrypto/xform_rmd160.c optional crypto opencrypto/xform_sha1.c optional crypto opencrypto/xform_sha2.c optional crypto contrib/libsodium/src/libsodium/crypto_core/ed25519/ref10/ed25519_ref10.c \ optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include/sodium -I$S/crypto/libsodium -Wno-unused-function" contrib/libsodium/src/libsodium/crypto_core/hchacha20/core_hchacha20.c \ optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include/sodium -I$S/crypto/libsodium" contrib/libsodium/src/libsodium/crypto_onetimeauth/poly1305/onetimeauth_poly1305.c \ optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include/sodium -I$S/crypto/libsodium" contrib/libsodium/src/libsodium/crypto_onetimeauth/poly1305/donna/poly1305_donna.c \ optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include/sodium -I$S/crypto/libsodium" contrib/libsodium/src/libsodium/crypto_scalarmult/curve25519/scalarmult_curve25519.c \ optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include/sodium -I$S/crypto/libsodium" contrib/libsodium/src/libsodium/crypto_scalarmult/curve25519/ref10/x25519_ref10.c \ optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include/sodium -I$S/crypto/libsodium -Wno-unused-function" contrib/libsodium/src/libsodium/crypto_stream/chacha20/stream_chacha20.c \ optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include/sodium -I$S/crypto/libsodium" contrib/libsodium/src/libsodium/crypto_stream/chacha20/ref/chacha20_ref.c \ optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include/sodium -I$S/crypto/libsodium" contrib/libsodium/src/libsodium/crypto_verify/sodium/verify.c \ optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include/sodium -I$S/crypto/libsodium" crypto/libsodium/randombytes.c optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include -I$S/crypto/libsodium" crypto/libsodium/utils.c optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include -I$S/crypto/libsodium" rpc/auth_none.c optional krpc | nfslockd | nfscl | nfsd rpc/auth_unix.c optional krpc | nfslockd | nfscl | nfsd rpc/authunix_prot.c optional krpc | nfslockd | nfscl | nfsd rpc/clnt_bck.c optional krpc | nfslockd | nfscl | nfsd rpc/clnt_dg.c optional krpc | nfslockd | nfscl | nfsd rpc/clnt_rc.c optional krpc | nfslockd | nfscl | nfsd rpc/clnt_vc.c optional krpc | nfslockd | nfscl | nfsd rpc/getnetconfig.c optional krpc | nfslockd | nfscl | nfsd rpc/replay.c optional krpc | nfslockd | nfscl | nfsd rpc/rpc_callmsg.c optional krpc | nfslockd | nfscl | nfsd rpc/rpc_generic.c optional krpc | nfslockd | nfscl | nfsd rpc/rpc_prot.c optional krpc | nfslockd | nfscl | nfsd rpc/rpcb_clnt.c optional krpc | nfslockd | nfscl | nfsd rpc/rpcb_prot.c optional krpc | nfslockd | nfscl | nfsd rpc/svc.c optional krpc | nfslockd | nfscl | nfsd rpc/svc_auth.c optional krpc | nfslockd | nfscl | nfsd rpc/svc_auth_unix.c optional krpc | nfslockd | nfscl | nfsd rpc/svc_dg.c optional krpc | nfslockd | nfscl | nfsd rpc/svc_generic.c optional krpc | nfslockd | nfscl | nfsd rpc/svc_vc.c optional krpc | nfslockd | nfscl | nfsd # # Kernel RPC-over-TLS # rpctlscd.h optional krpc | nfslockd | nfscl | nfsd \ dependency "$S/rpc/rpcsec_tls/rpctlscd.x" \ compile-with "RPCGEN_CPP='${CPP}' rpcgen -hM $S/rpc/rpcsec_tls/rpctlscd.x | grep -v pthread.h > rpctlscd.h" \ no-obj no-implicit-rule before-depend local \ clean "rpctlscd.h" rpctlscd_xdr.c optional krpc | nfslockd | nfscl | nfsd \ dependency "$S/rpc/rpcsec_tls/rpctlscd.x rpctlscd.h" \ compile-with "RPCGEN_CPP='${CPP}' rpcgen -c $S/rpc/rpcsec_tls/rpctlscd.x -o rpctlscd_xdr.c" no-ctfconvert \ no-implicit-rule before-depend local \ clean "rpctlscd_xdr.c" rpctlscd_clnt.c optional krpc | nfslockd | nfscl | nfsd \ dependency "$S/rpc/rpcsec_tls/rpctlscd.x rpctlscd.h" \ compile-with "RPCGEN_CPP='${CPP}' rpcgen -lM $S/rpc/rpcsec_tls/rpctlscd.x | grep -v string.h > rpctlscd_clnt.c" no-ctfconvert \ no-implicit-rule before-depend local \ clean "rpctlscd_clnt.c" rpctlssd.h optional krpc | nfslockd | nfscl | nfsd \ dependency "$S/rpc/rpcsec_tls/rpctlssd.x" \ compile-with "RPCGEN_CPP='${CPP}' rpcgen -hM $S/rpc/rpcsec_tls/rpctlssd.x | grep -v pthread.h > rpctlssd.h" \ no-obj no-implicit-rule before-depend local \ clean "rpctlssd.h" rpctlssd_xdr.c optional krpc | nfslockd | nfscl | nfsd \ dependency "$S/rpc/rpcsec_tls/rpctlssd.x rpctlssd.h" \ compile-with "RPCGEN_CPP='${CPP}' rpcgen -c $S/rpc/rpcsec_tls/rpctlssd.x -o rpctlssd_xdr.c" no-ctfconvert \ no-implicit-rule before-depend local \ clean "rpctlssd_xdr.c" rpctlssd_clnt.c optional krpc | nfslockd | nfscl | nfsd \ dependency "$S/rpc/rpcsec_tls/rpctlssd.x rpctlssd.h" \ compile-with "RPCGEN_CPP='${CPP}' rpcgen -lM $S/rpc/rpcsec_tls/rpctlssd.x | grep -v string.h > rpctlssd_clnt.c" no-ctfconvert \ no-implicit-rule before-depend local \ clean "rpctlssd_clnt.c" rpc/rpcsec_tls/rpctls_impl.c optional krpc | nfslockd | nfscl | nfsd rpc/rpcsec_tls/auth_tls.c optional krpc | nfslockd | nfscl | nfsd rpc/rpcsec_gss/rpcsec_gss.c optional krpc kgssapi | nfslockd kgssapi | nfscl kgssapi | nfsd kgssapi rpc/rpcsec_gss/rpcsec_gss_conf.c optional krpc kgssapi | nfslockd kgssapi | nfscl kgssapi | nfsd kgssapi rpc/rpcsec_gss/rpcsec_gss_misc.c optional krpc kgssapi | nfslockd kgssapi | nfscl kgssapi | nfsd kgssapi rpc/rpcsec_gss/rpcsec_gss_prot.c optional krpc kgssapi | nfslockd kgssapi | nfscl kgssapi | nfsd kgssapi rpc/rpcsec_gss/svc_rpcsec_gss.c optional krpc kgssapi | nfslockd kgssapi | nfscl kgssapi | nfsd kgssapi security/audit/audit.c optional audit security/audit/audit_arg.c optional audit security/audit/audit_bsm.c optional audit security/audit/audit_bsm_db.c optional audit security/audit/audit_bsm_klib.c optional audit security/audit/audit_dtrace.c optional dtaudit audit | dtraceall audit compile-with "${CDDL_C}" security/audit/audit_pipe.c optional audit security/audit/audit_syscalls.c standard security/audit/audit_trigger.c optional audit security/audit/audit_worker.c optional audit security/audit/bsm_domain.c optional audit security/audit/bsm_errno.c optional audit security/audit/bsm_fcntl.c optional audit security/audit/bsm_socket_type.c optional audit security/audit/bsm_token.c optional audit security/mac/mac_audit.c optional mac audit security/mac/mac_cred.c optional mac security/mac/mac_kdb.c optional mac security/mac/mac_framework.c optional mac security/mac/mac_inet.c optional mac inet | mac inet6 security/mac/mac_inet6.c optional mac inet6 security/mac/mac_label.c optional mac security/mac/mac_net.c optional mac security/mac/mac_pipe.c optional mac security/mac/mac_posix_sem.c optional mac security/mac/mac_posix_shm.c optional mac security/mac/mac_priv.c optional mac security/mac/mac_process.c optional mac security/mac/mac_socket.c optional mac security/mac/mac_syscalls.c standard security/mac/mac_system.c optional mac security/mac/mac_sysv_msg.c optional mac security/mac/mac_sysv_sem.c optional mac security/mac/mac_sysv_shm.c optional mac security/mac/mac_vfs.c optional mac security/mac_biba/mac_biba.c optional mac_biba security/mac_ddb/mac_ddb.c optional mac_ddb security/mac_bsdextended/mac_bsdextended.c optional mac_bsdextended security/mac_bsdextended/ugidfw_system.c optional mac_bsdextended security/mac_bsdextended/ugidfw_vnode.c optional mac_bsdextended security/mac_ifoff/mac_ifoff.c optional mac_ifoff security/mac_ipacl/mac_ipacl.c optional mac_ipacl security/mac_lomac/mac_lomac.c optional mac_lomac security/mac_mls/mac_mls.c optional mac_mls security/mac_none/mac_none.c optional mac_none security/mac_ntpd/mac_ntpd.c optional mac_ntpd security/mac_partition/mac_partition.c optional mac_partition security/mac_portacl/mac_portacl.c optional mac_portacl security/mac_priority/mac_priority.c optional mac_priority security/mac_seeotheruids/mac_seeotheruids.c optional mac_seeotheruids security/mac_stub/mac_stub.c optional mac_stub security/mac_test/mac_test.c optional mac_test security/mac_grantbylabel/mac_grantbylabel.c optional mac_grantbylabel security/mac_veriexec/mac_veriexec.c optional mac_veriexec security/mac_veriexec/veriexec_fingerprint.c optional mac_veriexec security/mac_veriexec/veriexec_metadata.c optional mac_veriexec security/mac_veriexec_parser/mac_veriexec_parser.c optional mac_veriexec mac_veriexec_parser security/mac_veriexec/mac_veriexec_rmd160.c optional mac_veriexec_rmd160 security/mac_veriexec/mac_veriexec_sha1.c optional mac_veriexec_sha1 security/mac_veriexec/mac_veriexec_sha256.c optional mac_veriexec_sha256 security/mac_veriexec/mac_veriexec_sha384.c optional mac_veriexec_sha384 security/mac_veriexec/mac_veriexec_sha512.c optional mac_veriexec_sha512 teken/teken.c optional sc !SC_NO_TERM_TEKEN | vt ufs/ffs/ffs_alloc.c optional ffs ufs/ffs/ffs_balloc.c optional ffs ufs/ffs/ffs_inode.c optional ffs ufs/ffs/ffs_snapshot.c optional ffs ufs/ffs/ffs_softdep.c optional ffs ufs/ffs/ffs_subr.c optional ffs | geom_label ufs/ffs/ffs_tables.c optional ffs | geom_label ufs/ffs/ffs_vfsops.c optional ffs ufs/ffs/ffs_vnops.c optional ffs ufs/ffs/ffs_rawread.c optional ffs directio ufs/ffs/ffs_suspend.c optional ffs ufs/ufs/ufs_acl.c optional ffs ufs/ufs/ufs_bmap.c optional ffs ufs/ufs/ufs_dirhash.c optional ffs ufs/ufs/ufs_extattr.c optional ffs ufs/ufs/ufs_gjournal.c optional ffs UFS_GJOURNAL ufs/ufs/ufs_inode.c optional ffs ufs/ufs/ufs_lookup.c optional ffs ufs/ufs/ufs_quota.c optional ffs ufs/ufs/ufs_vfsops.c optional ffs ufs/ufs/ufs_vnops.c optional ffs vm/device_pager.c standard vm/phys_pager.c standard vm/redzone.c optional DEBUG_REDZONE vm/sg_pager.c standard vm/swap_pager.c standard vm/uma_core.c standard vm/uma_dbg.c standard vm/memguard.c optional DEBUG_MEMGUARD vm/vm_domainset.c standard vm/vm_fault.c standard vm/vm_glue.c standard vm/vm_init.c standard vm/vm_kern.c standard vm/vm_map.c standard vm/vm_meter.c standard vm/vm_mmap.c standard vm/vm_object.c standard vm/vm_page.c standard vm/vm_pageout.c standard vm/vm_pager.c standard vm/vm_phys.c standard vm/vm_radix.c standard vm/vm_reserv.c standard vm/vm_swapout.c optional !NO_SWAPPING vm/vm_swapout_dummy.c optional NO_SWAPPING vm/vm_unix.c standard vm/vnode_pager.c standard xen/features.c optional xenhvm xen/xen_common.c optional xenhvm xen/xenbus/xenbus_if.m optional xenhvm xen/xenbus/xenbus.c optional xenhvm xen/xenbus/xenbusb_if.m optional xenhvm xen/xenbus/xenbusb.c optional xenhvm xen/xenbus/xenbusb_front.c optional xenhvm xen/xenbus/xenbusb_back.c optional xenhvm xen/xenmem/xenmem_if.m optional xenhvm xdr/xdr.c optional xdr | krpc | nfslockd | nfscl | nfsd xdr/xdr_array.c optional xdr | krpc | nfslockd | nfscl | nfsd xdr/xdr_mbuf.c optional xdr | krpc | nfslockd | nfscl | nfsd xdr/xdr_mem.c optional xdr | krpc | nfslockd | nfscl | nfsd xdr/xdr_reference.c optional xdr | krpc | nfslockd | nfscl | nfsd xdr/xdr_sizeof.c optional xdr | krpc | nfslockd | nfscl | nfsd diff --git a/sys/dev/clk/rockchip/rk_clk_composite.c b/sys/dev/clk/rockchip/rk_clk_composite.c index 2b6c889913b8..14f3229df5dd 100644 --- a/sys/dev/clk/rockchip/rk_clk_composite.c +++ b/sys/dev/clk/rockchip/rk_clk_composite.c @@ -1,334 +1,334 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2018 Emmanuel Vadot * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include -#include +#include #include #include "clkdev_if.h" #include "syscon_if.h" struct rk_clk_composite_sc { uint32_t muxdiv_offset; uint32_t mux_shift; uint32_t mux_width; uint32_t mux_mask; uint32_t div_shift; uint32_t div_width; uint32_t div_mask; uint32_t flags; struct syscon *grf; }; #define WRITE4(_clk, off, val) \ rk_clk_composite_write_4(_clk, off, val) #define READ4(_clk, off, val) \ rk_clk_composite_read_4(_clk, off, val) #define DEVICE_LOCK(_clk) \ CLKDEV_DEVICE_LOCK(clknode_get_device(_clk)) #define DEVICE_UNLOCK(_clk) \ CLKDEV_DEVICE_UNLOCK(clknode_get_device(_clk)) #define RK_CLK_COMPOSITE_MASK_SHIFT 16 #if 0 #define dprintf(format, arg...) \ printf("%s:(%s)" format, __func__, clknode_get_name(clk), arg) #else #define dprintf(format, arg...) #endif static void rk_clk_composite_read_4(struct clknode *clk, bus_addr_t addr, uint32_t *val) { struct rk_clk_composite_sc *sc; sc = clknode_get_softc(clk); if (sc->grf) *val = SYSCON_READ_4(sc->grf, addr); else CLKDEV_READ_4(clknode_get_device(clk), addr, val); } static void rk_clk_composite_write_4(struct clknode *clk, bus_addr_t addr, uint32_t val) { struct rk_clk_composite_sc *sc; sc = clknode_get_softc(clk); if (sc->grf) SYSCON_WRITE_4(sc->grf, addr, val | (0xffff << 16)); else CLKDEV_WRITE_4(clknode_get_device(clk), addr, val); } static struct syscon * rk_clk_composite_get_grf(struct clknode *clk) { device_t dev; phandle_t node; struct syscon *grf; grf = NULL; dev = clknode_get_device(clk); node = ofw_bus_get_node(dev); if (OF_hasprop(node, "rockchip,grf") && syscon_get_by_ofw_property(dev, node, "rockchip,grf", &grf) != 0) { return (NULL); } return (grf); } static int rk_clk_composite_init(struct clknode *clk, device_t dev) { struct rk_clk_composite_sc *sc; uint32_t val, idx; sc = clknode_get_softc(clk); if ((sc->flags & RK_CLK_COMPOSITE_GRF) != 0) { sc->grf = rk_clk_composite_get_grf(clk); if (sc->grf == NULL) panic("clock %s has GRF flag set but no syscon is available", clknode_get_name(clk)); } idx = 0; if ((sc->flags & RK_CLK_COMPOSITE_HAVE_MUX) != 0) { DEVICE_LOCK(clk); READ4(clk, sc->muxdiv_offset, &val); DEVICE_UNLOCK(clk); idx = (val & sc->mux_mask) >> sc->mux_shift; } clknode_init_parent_idx(clk, idx); return (0); } static int rk_clk_composite_set_mux(struct clknode *clk, int index) { struct rk_clk_composite_sc *sc; uint32_t val = 0; sc = clknode_get_softc(clk); if ((sc->flags & RK_CLK_COMPOSITE_HAVE_MUX) == 0) return (0); dprintf("Set mux to %d\n", index); DEVICE_LOCK(clk); val |= (index << sc->mux_shift); val |= sc->mux_mask << RK_CLK_COMPOSITE_MASK_SHIFT; dprintf("Write: muxdiv_offset=%x, val=%x\n", sc->muxdiv_offset, val); WRITE4(clk, sc->muxdiv_offset, val); DEVICE_UNLOCK(clk); return (0); } static int rk_clk_composite_recalc(struct clknode *clk, uint64_t *freq) { struct rk_clk_composite_sc *sc; uint32_t reg, div; sc = clknode_get_softc(clk); DEVICE_LOCK(clk); READ4(clk, sc->muxdiv_offset, ®); dprintf("Read: muxdiv_offset=%x, val=%x\n", sc->muxdiv_offset, reg); DEVICE_UNLOCK(clk); div = ((reg & sc->div_mask) >> sc->div_shift); if (sc->flags & RK_CLK_COMPOSITE_DIV_EXP) div = 1 << div; else div += 1; dprintf("parent_freq=%ju, div=%u\n", *freq, div); *freq = *freq / div; dprintf("Final freq=%ju\n", *freq); return (0); } static uint32_t rk_clk_composite_find_best(struct rk_clk_composite_sc *sc, uint64_t fparent, uint64_t freq, uint32_t *reg) { uint64_t best, cur; uint32_t best_div, best_div_reg; uint32_t div, div_reg; best = 0; best_div = 0; best_div_reg = 0; for (div_reg = 0; div_reg <= ((sc->div_mask >> sc->div_shift) + 1); div_reg++) { if (sc->flags == RK_CLK_COMPOSITE_DIV_EXP) div = 1 << div_reg; else div = div_reg + 1; cur = fparent / div; if ((freq - cur) < (freq - best)) { best = cur; best_div = div; best_div_reg = div_reg; break; } } *reg = best_div_reg; return (best_div); } static int rk_clk_composite_set_freq(struct clknode *clk, uint64_t fparent, uint64_t *fout, int flags, int *stop) { struct rk_clk_composite_sc *sc; struct clknode *p_clk; const char **p_names; uint64_t best, cur; uint32_t div, div_reg, best_div, best_div_reg, val; int p_idx, best_parent; sc = clknode_get_softc(clk); dprintf("Finding best parent/div for target freq of %ju\n", *fout); p_names = clknode_get_parent_names(clk); for (best_div = 0, best = 0, p_idx = 0; p_idx != clknode_get_parents_num(clk); p_idx++) { p_clk = clknode_find_by_name(p_names[p_idx]); clknode_get_freq(p_clk, &fparent); dprintf("Testing with parent %s (%d) at freq %ju\n", clknode_get_name(p_clk), p_idx, fparent); div = rk_clk_composite_find_best(sc, fparent, *fout, &div_reg); cur = fparent / div; if ((*fout - cur) < (*fout - best)) { best = cur; best_div = div; best_div_reg = div_reg; best_parent = p_idx; dprintf("Best parent so far %s (%d) with best freq at " "%ju\n", clknode_get_name(p_clk), p_idx, best); } } *stop = 1; if (best_div == 0) return (ERANGE); if ((best < *fout) && ((flags & CLK_SET_ROUND_DOWN) == 0)) return (ERANGE); if ((best > *fout) && ((flags & CLK_SET_ROUND_UP) == 0)) { return (ERANGE); } if ((flags & CLK_SET_DRYRUN) != 0) { *fout = best; return (0); } p_idx = clknode_get_parent_idx(clk); if (p_idx != best_parent) { dprintf("Switching parent index from %d to %d\n", p_idx, best_parent); clknode_set_parent_by_idx(clk, best_parent); } dprintf("Setting divider to %d (reg: %d)\n", best_div, best_div_reg); dprintf(" div_mask: 0x%X, div_shift: %d\n", sc->div_mask, sc->div_shift); DEVICE_LOCK(clk); val = best_div_reg << sc->div_shift; val |= sc->div_mask << RK_CLK_COMPOSITE_MASK_SHIFT; dprintf("Write: muxdiv_offset=%x, val=%x\n", sc->muxdiv_offset, val); WRITE4(clk, sc->muxdiv_offset, val); DEVICE_UNLOCK(clk); *fout = best; return (0); } static clknode_method_t rk_clk_composite_clknode_methods[] = { /* Device interface */ CLKNODEMETHOD(clknode_init, rk_clk_composite_init), CLKNODEMETHOD(clknode_set_mux, rk_clk_composite_set_mux), CLKNODEMETHOD(clknode_recalc_freq, rk_clk_composite_recalc), CLKNODEMETHOD(clknode_set_freq, rk_clk_composite_set_freq), CLKNODEMETHOD_END }; DEFINE_CLASS_1(rk_clk_composite_clknode, rk_clk_composite_clknode_class, rk_clk_composite_clknode_methods, sizeof(struct rk_clk_composite_sc), clknode_class); int rk_clk_composite_register(struct clkdom *clkdom, struct rk_clk_composite_def *clkdef) { struct clknode *clk; struct rk_clk_composite_sc *sc; clk = clknode_create(clkdom, &rk_clk_composite_clknode_class, &clkdef->clkdef); if (clk == NULL) return (1); sc = clknode_get_softc(clk); sc->muxdiv_offset = clkdef->muxdiv_offset; sc->mux_shift = clkdef->mux_shift; sc->mux_width = clkdef->mux_width; sc->mux_mask = ((1 << clkdef->mux_width) - 1) << sc->mux_shift; sc->div_shift = clkdef->div_shift; sc->div_width = clkdef->div_width; sc->div_mask = ((1 << clkdef->div_width) - 1) << sc->div_shift; sc->flags = clkdef->flags; clknode_register(clkdom, clk); return (0); } diff --git a/sys/dev/clk/rockchip/rk_clk_mux.c b/sys/dev/clk/rockchip/rk_clk_mux.c index fba57f794d16..97c1ad6f2f1c 100644 --- a/sys/dev/clk/rockchip/rk_clk_mux.c +++ b/sys/dev/clk/rockchip/rk_clk_mux.c @@ -1,239 +1,239 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright 2016 Michal Meloun * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include -#include +#include #include #include #include "clkdev_if.h" #include "syscon_if.h" #define WR4(_clk, off, val) \ CLKDEV_WRITE_4(clknode_get_device(_clk), off, val) #define RD4(_clk, off, val) \ CLKDEV_READ_4(clknode_get_device(_clk), off, val) #define MD4(_clk, off, clr, set ) \ CLKDEV_MODIFY_4(clknode_get_device(_clk), off, clr, set) #define DEVICE_LOCK(_clk) \ CLKDEV_DEVICE_LOCK(clknode_get_device(_clk)) #define DEVICE_UNLOCK(_clk) \ CLKDEV_DEVICE_UNLOCK(clknode_get_device(_clk)) #if 0 #define dprintf(format, arg...) \ printf("%s:(%s)" format, __func__, clknode_get_name(clk), arg) #else #define dprintf(format, arg...) #endif static int rk_clk_mux_init(struct clknode *clk, device_t dev); static int rk_clk_mux_set_mux(struct clknode *clk, int idx); static int rk_clk_mux_set_freq(struct clknode *clk, uint64_t fparent, uint64_t *fout, int flags, int *stop); struct rk_clk_mux_sc { uint32_t offset; uint32_t shift; uint32_t mask; int mux_flags; struct syscon *grf; }; static clknode_method_t rk_clk_mux_methods[] = { /* Device interface */ CLKNODEMETHOD(clknode_init, rk_clk_mux_init), CLKNODEMETHOD(clknode_set_mux, rk_clk_mux_set_mux), CLKNODEMETHOD(clknode_set_freq, rk_clk_mux_set_freq), CLKNODEMETHOD_END }; DEFINE_CLASS_1(rk_clk_mux, rk_clk_mux_class, rk_clk_mux_methods, sizeof(struct rk_clk_mux_sc), clknode_class); static struct syscon * rk_clk_mux_get_grf(struct clknode *clk) { device_t dev; phandle_t node; struct syscon *grf; grf = NULL; dev = clknode_get_device(clk); node = ofw_bus_get_node(dev); if (OF_hasprop(node, "rockchip,grf") && syscon_get_by_ofw_property(dev, node, "rockchip,grf", &grf) != 0) { return (NULL); } return (grf); } static int rk_clk_mux_init(struct clknode *clk, device_t dev) { uint32_t reg; struct rk_clk_mux_sc *sc; int rv; sc = clknode_get_softc(clk); if ((sc->mux_flags & RK_CLK_MUX_GRF) != 0) { sc->grf = rk_clk_mux_get_grf(clk); if (sc->grf == NULL) panic("clock %s has GRF flag set but no syscon is available", clknode_get_name(clk)); } DEVICE_LOCK(clk); if (sc->grf) { reg = SYSCON_READ_4(sc->grf, sc->offset); rv = 0; } else rv = RD4(clk, sc->offset, ®); DEVICE_UNLOCK(clk); if (rv != 0) { return (rv); } reg = (reg >> sc->shift) & sc->mask; clknode_init_parent_idx(clk, reg); return(0); } static int rk_clk_mux_set_mux(struct clknode *clk, int idx) { uint32_t reg; struct rk_clk_mux_sc *sc; int rv; sc = clknode_get_softc(clk); DEVICE_LOCK(clk); if (sc->grf) rv = SYSCON_MODIFY_4(sc->grf, sc->offset, sc->mask << sc->shift, ((idx & sc->mask) << sc->shift) | RK_CLK_MUX_MASK); else rv = MD4(clk, sc->offset, sc->mask << sc->shift, ((idx & sc->mask) << sc->shift) | RK_CLK_MUX_MASK); if (rv != 0) { DEVICE_UNLOCK(clk); return (rv); } if (sc->grf == NULL) RD4(clk, sc->offset, ®); DEVICE_UNLOCK(clk); return(0); } static int rk_clk_mux_set_freq(struct clknode *clk, uint64_t fparent, uint64_t *fout, int flags, int *stop) { struct rk_clk_mux_sc *sc; struct clknode *p_clk, *p_best_clk; const char **p_names; int p_idx, best_parent; int rv; sc = clknode_get_softc(clk); if ((sc->mux_flags & RK_CLK_MUX_GRF) != 0) { *stop = 1; return (ENOTSUP); } if ((sc->mux_flags & RK_CLK_MUX_REPARENT) == 0) { *stop = 0; return (0); } dprintf("Finding best parent for target freq of %ju\n", *fout); p_names = clknode_get_parent_names(clk); for (p_idx = 0; p_idx != clknode_get_parents_num(clk); p_idx++) { p_clk = clknode_find_by_name(p_names[p_idx]); dprintf("Testing with parent %s (%d)\n", clknode_get_name(p_clk), p_idx); rv = clknode_set_freq(p_clk, *fout, flags | CLK_SET_DRYRUN, 0); dprintf("Testing with parent %s (%d) rv=%d\n", clknode_get_name(p_clk), p_idx, rv); if (rv == 0) { best_parent = p_idx; p_best_clk = p_clk; *stop = 1; } } if (!*stop) return (0); if ((flags & CLK_SET_DRYRUN) != 0) return (0); p_idx = clknode_get_parent_idx(clk); if (p_idx != best_parent) { dprintf("Switching parent index from %d to %d\n", p_idx, best_parent); clknode_set_parent_by_idx(clk, best_parent); } clknode_set_freq(p_best_clk, *fout, flags, 0); clknode_get_freq(p_best_clk, fout); return (0); } int rk_clk_mux_register(struct clkdom *clkdom, struct rk_clk_mux_def *clkdef) { struct clknode *clk; struct rk_clk_mux_sc *sc; clk = clknode_create(clkdom, &rk_clk_mux_class, &clkdef->clkdef); if (clk == NULL) return (1); sc = clknode_get_softc(clk); sc->offset = clkdef->offset; sc->shift = clkdef->shift; sc->mask = (1 << clkdef->width) - 1; sc->mux_flags = clkdef->mux_flags; clknode_register(clkdom, clk); return (0); } diff --git a/sys/dev/dwc/if_dwc_rk.c b/sys/dev/dwc/if_dwc_rk.c index fca9f879247b..83f2bad167fb 100644 --- a/sys/dev/dwc/if_dwc_rk.c +++ b/sys/dev/dwc/if_dwc_rk.c @@ -1,636 +1,636 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2018 Emmanuel Vadot * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include #include #include "if_dwc_if.h" #include "syscon_if.h" #define RK3328_GRF_MAC_CON0 0x0900 #define MAC_CON0_GMAC2IO_TX_DL_CFG_MASK 0x7F #define MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT 0 #define MAC_CON0_GMAC2IO_RX_DL_CFG_MASK 0x7F #define MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT 7 #define RK3328_GRF_MAC_CON1 0x0904 #define MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA (1 << 0) #define MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA (1 << 1) #define MAC_CON1_GMAC2IO_GMII_CLK_SEL_MASK (3 << 11) #define MAC_CON1_GMAC2IO_GMII_CLK_SEL_125 (0 << 11) #define MAC_CON1_GMAC2IO_GMII_CLK_SEL_25 (3 << 11) #define MAC_CON1_GMAC2IO_GMII_CLK_SEL_2_5 (2 << 11) #define MAC_CON1_GMAC2IO_RMII_MODE_MASK (1 << 9) #define MAC_CON1_GMAC2IO_RMII_MODE (1 << 9) #define MAC_CON1_GMAC2IO_INTF_SEL_MASK (7 << 4) #define MAC_CON1_GMAC2IO_INTF_RMII (4 << 4) #define MAC_CON1_GMAC2IO_INTF_RGMII (1 << 4) #define MAC_CON1_GMAC2IO_RMII_CLK_SEL_MASK (1 << 7) #define MAC_CON1_GMAC2IO_RMII_CLK_SEL_25 (1 << 7) #define MAC_CON1_GMAC2IO_RMII_CLK_SEL_2_5 (0 << 7) #define MAC_CON1_GMAC2IO_MAC_SPEED_MASK (1 << 2) #define MAC_CON1_GMAC2IO_MAC_SPEED_100 (1 << 2) #define MAC_CON1_GMAC2IO_MAC_SPEED_10 (0 << 2) #define RK3328_GRF_MAC_CON2 0x0908 #define RK3328_GRF_MACPHY_CON0 0x0B00 #define MACPHY_CON0_CLK_50M_MASK (1 << 14) #define MACPHY_CON0_CLK_50M (1 << 14) #define MACPHY_CON0_RMII_MODE_MASK (3 << 6) #define MACPHY_CON0_RMII_MODE (1 << 6) #define RK3328_GRF_MACPHY_CON1 0x0B04 #define MACPHY_CON1_RMII_MODE_MASK (1 << 9) #define MACPHY_CON1_RMII_MODE (1 << 9) #define RK3328_GRF_MACPHY_CON2 0x0B08 #define RK3328_GRF_MACPHY_CON3 0x0B0C #define RK3328_GRF_MACPHY_STATUS 0x0B10 #define RK3399_GRF_SOC_CON5 0xc214 #define SOC_CON5_GMAC_CLK_SEL_MASK (3 << 4) #define SOC_CON5_GMAC_CLK_SEL_125 (0 << 4) #define SOC_CON5_GMAC_CLK_SEL_25 (3 << 4) #define SOC_CON5_GMAC_CLK_SEL_2_5 (2 << 4) #define RK3399_GRF_SOC_CON6 0xc218 #define SOC_CON6_GMAC_TXCLK_DLY_ENA (1 << 7) #define SOC_CON6_TX_DL_CFG_MASK 0x7F #define SOC_CON6_TX_DL_CFG_SHIFT 0 #define SOC_CON6_RX_DL_CFG_MASK 0x7F #define SOC_CON6_GMAC_RXCLK_DLY_ENA (1 << 15) #define SOC_CON6_RX_DL_CFG_SHIFT 8 struct if_dwc_rk_softc; typedef void (*if_dwc_rk_set_delaysfn_t)(struct if_dwc_rk_softc *); typedef int (*if_dwc_rk_set_speedfn_t)(struct if_dwc_rk_softc *, int); typedef void (*if_dwc_rk_set_phy_modefn_t)(struct if_dwc_rk_softc *); typedef void (*if_dwc_rk_phy_powerupfn_t)(struct if_dwc_rk_softc *); struct if_dwc_rk_ops { if_dwc_rk_set_delaysfn_t set_delays; if_dwc_rk_set_speedfn_t set_speed; if_dwc_rk_set_phy_modefn_t set_phy_mode; if_dwc_rk_phy_powerupfn_t phy_powerup; }; struct if_dwc_rk_softc { struct dwc_softc base; uint32_t tx_delay; uint32_t rx_delay; bool integrated_phy; bool clock_in; phandle_t phy_node; struct syscon *grf; struct if_dwc_rk_ops *ops; /* Common clocks */ clk_t mac_clk_rx; clk_t mac_clk_tx; clk_t aclk_mac; clk_t pclk_mac; clk_t clk_stmmaceth; clk_t clk_mac_speed; /* RMII clocks */ clk_t clk_mac_ref; clk_t clk_mac_refout; /* PHY clock */ clk_t clk_phy; }; static void rk3328_set_delays(struct if_dwc_rk_softc *sc); static int rk3328_set_speed(struct if_dwc_rk_softc *sc, int speed); static void rk3328_set_phy_mode(struct if_dwc_rk_softc *sc); static void rk3328_phy_powerup(struct if_dwc_rk_softc *sc); static void rk3399_set_delays(struct if_dwc_rk_softc *sc); static int rk3399_set_speed(struct if_dwc_rk_softc *sc, int speed); static struct if_dwc_rk_ops rk3288_ops = { }; static struct if_dwc_rk_ops rk3328_ops = { .set_delays = rk3328_set_delays, .set_speed = rk3328_set_speed, .set_phy_mode = rk3328_set_phy_mode, .phy_powerup = rk3328_phy_powerup, }; static struct if_dwc_rk_ops rk3399_ops = { .set_delays = rk3399_set_delays, .set_speed = rk3399_set_speed, }; static struct ofw_compat_data compat_data[] = { {"rockchip,rk3288-gmac", (uintptr_t)&rk3288_ops}, {"rockchip,rk3328-gmac", (uintptr_t)&rk3328_ops}, {"rockchip,rk3399-gmac", (uintptr_t)&rk3399_ops}, {NULL, 0} }; static void rk3328_set_delays(struct if_dwc_rk_softc *sc) { uint32_t reg; uint32_t tx, rx; if (!mii_contype_is_rgmii(sc->base.phy_mode)) return; reg = SYSCON_READ_4(sc->grf, RK3328_GRF_MAC_CON0); tx = ((reg >> MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT) & MAC_CON0_GMAC2IO_TX_DL_CFG_MASK); rx = ((reg >> MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT) & MAC_CON0_GMAC2IO_RX_DL_CFG_MASK); reg = SYSCON_READ_4(sc->grf, RK3328_GRF_MAC_CON1); if (bootverbose) { device_printf(sc->base.dev, "current delays settings: tx=%u(%s) rx=%u(%s)\n", tx, ((reg & MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA) ? "enabled" : "disabled"), rx, ((reg & MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA) ? "enabled" : "disabled")); device_printf(sc->base.dev, "setting new RK3328 RX/TX delays: %d/%d\n", sc->tx_delay, sc->rx_delay); } reg = (MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA | MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA) << 16; reg |= (MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA | MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA); SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON1, reg); reg = 0xffff << 16; reg |= ((sc->tx_delay & MAC_CON0_GMAC2IO_TX_DL_CFG_MASK) << MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT); reg |= ((sc->rx_delay & MAC_CON0_GMAC2IO_TX_DL_CFG_MASK) << MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT); SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON0, reg); } static int rk3328_set_speed(struct if_dwc_rk_softc *sc, int speed) { uint32_t reg; switch (sc->base.phy_mode) { case MII_CONTYPE_RGMII: case MII_CONTYPE_RGMII_ID: case MII_CONTYPE_RGMII_RXID: case MII_CONTYPE_RGMII_TXID: switch (speed) { case IFM_1000_T: case IFM_1000_SX: reg = MAC_CON1_GMAC2IO_GMII_CLK_SEL_125; break; case IFM_100_TX: reg = MAC_CON1_GMAC2IO_GMII_CLK_SEL_25; break; case IFM_10_T: reg = MAC_CON1_GMAC2IO_GMII_CLK_SEL_2_5; break; default: device_printf(sc->base.dev, "unsupported RGMII media %u\n", speed); return (-1); } SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON1, ((MAC_CON1_GMAC2IO_GMII_CLK_SEL_MASK << 16) | reg)); break; case MII_CONTYPE_RMII: switch (speed) { case IFM_100_TX: reg = MAC_CON1_GMAC2IO_RMII_CLK_SEL_25 | MAC_CON1_GMAC2IO_MAC_SPEED_100; break; case IFM_10_T: reg = MAC_CON1_GMAC2IO_RMII_CLK_SEL_2_5 | MAC_CON1_GMAC2IO_MAC_SPEED_10; break; default: device_printf(sc->base.dev, "unsupported RMII media %u\n", speed); return (-1); } SYSCON_WRITE_4(sc->grf, sc->integrated_phy ? RK3328_GRF_MAC_CON2 : RK3328_GRF_MAC_CON1, reg | ((MAC_CON1_GMAC2IO_RMII_CLK_SEL_MASK | MAC_CON1_GMAC2IO_MAC_SPEED_MASK) << 16)); break; } return (0); } static void rk3328_set_phy_mode(struct if_dwc_rk_softc *sc) { switch (sc->base.phy_mode) { case MII_CONTYPE_RGMII: case MII_CONTYPE_RGMII_ID: case MII_CONTYPE_RGMII_RXID: case MII_CONTYPE_RGMII_TXID: SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON1, ((MAC_CON1_GMAC2IO_INTF_SEL_MASK | MAC_CON1_GMAC2IO_RMII_MODE_MASK) << 16) | MAC_CON1_GMAC2IO_INTF_RGMII); break; case MII_CONTYPE_RMII: SYSCON_WRITE_4(sc->grf, sc->integrated_phy ? RK3328_GRF_MAC_CON2 : RK3328_GRF_MAC_CON1, ((MAC_CON1_GMAC2IO_INTF_SEL_MASK | MAC_CON1_GMAC2IO_RMII_MODE_MASK) << 16) | MAC_CON1_GMAC2IO_INTF_RMII | MAC_CON1_GMAC2IO_RMII_MODE); break; } } static void rk3328_phy_powerup(struct if_dwc_rk_softc *sc) { SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON1, (MACPHY_CON1_RMII_MODE_MASK << 16) | MACPHY_CON1_RMII_MODE); } static void rk3399_set_delays(struct if_dwc_rk_softc *sc) { uint32_t reg, tx, rx; if (!mii_contype_is_rgmii(sc->base.phy_mode)) return; reg = SYSCON_READ_4(sc->grf, RK3399_GRF_SOC_CON6); tx = ((reg >> SOC_CON6_TX_DL_CFG_SHIFT) & SOC_CON6_TX_DL_CFG_MASK); rx = ((reg >> SOC_CON6_RX_DL_CFG_SHIFT) & SOC_CON6_RX_DL_CFG_MASK); if (bootverbose) { device_printf(sc->base.dev, "current delays settings: tx=%u(%s) rx=%u(%s)\n", tx, ((reg & SOC_CON6_GMAC_TXCLK_DLY_ENA) ? "enabled" : "disabled"), rx, ((reg & SOC_CON6_GMAC_RXCLK_DLY_ENA) ? "enabled" : "disabled")); device_printf(sc->base.dev, "setting new RK3399 RX/TX delays: %d/%d\n", sc->rx_delay, sc->tx_delay); } reg = 0xFFFF << 16; reg |= ((sc->tx_delay & SOC_CON6_TX_DL_CFG_MASK) << SOC_CON6_TX_DL_CFG_SHIFT); reg |= ((sc->rx_delay & SOC_CON6_RX_DL_CFG_MASK) << SOC_CON6_RX_DL_CFG_SHIFT); reg |= SOC_CON6_GMAC_TXCLK_DLY_ENA | SOC_CON6_GMAC_RXCLK_DLY_ENA; SYSCON_WRITE_4(sc->grf, RK3399_GRF_SOC_CON6, reg); } static int rk3399_set_speed(struct if_dwc_rk_softc *sc, int speed) { uint32_t reg; switch (speed) { case IFM_1000_T: case IFM_1000_SX: reg = SOC_CON5_GMAC_CLK_SEL_125; break; case IFM_100_TX: reg = SOC_CON5_GMAC_CLK_SEL_25; break; case IFM_10_T: reg = SOC_CON5_GMAC_CLK_SEL_2_5; break; default: device_printf(sc->base.dev, "unsupported media %u\n", speed); return (-1); } SYSCON_WRITE_4(sc->grf, RK3399_GRF_SOC_CON5, ((SOC_CON5_GMAC_CLK_SEL_MASK << 16) | reg)); return (0); } static int if_dwc_rk_sysctl_delays(SYSCTL_HANDLER_ARGS) { struct if_dwc_rk_softc *sc; int rv; uint32_t rxtx; sc = arg1; rxtx = ((sc->rx_delay << 8) | sc->tx_delay); rv = sysctl_handle_int(oidp, &rxtx, 0, req); if (rv != 0 || req->newptr == NULL) return (rv); sc->tx_delay = rxtx & 0xff; sc->rx_delay = (rxtx >> 8) & 0xff; if (sc->ops->set_delays) sc->ops->set_delays(sc); return (0); } static int if_dwc_rk_init_sysctl(struct if_dwc_rk_softc *sc) { struct sysctl_oid *child; struct sysctl_ctx_list *ctx_list; ctx_list = device_get_sysctl_ctx(sc->base.dev); child = device_get_sysctl_tree(sc->base.dev); SYSCTL_ADD_PROC(ctx_list, SYSCTL_CHILDREN(child), OID_AUTO, "delays", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, sc, 0, if_dwc_rk_sysctl_delays, "", "RGMII RX/TX delays: ((rx << 8) | tx)"); return (0); } static int if_dwc_rk_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "Rockchip Gigabit Ethernet Controller"); return (BUS_PROBE_DEFAULT); } static int if_dwc_rk_init_clocks(device_t dev) { struct if_dwc_rk_softc *sc; sc = device_get_softc(dev); /* Enable clocks */ if (clk_get_by_ofw_name(dev, 0, "mac_clk_tx", &sc->mac_clk_tx) != 0) { device_printf(sc->base.dev, "could not get mac_clk_tx clock\n"); sc->mac_clk_tx = NULL; } if (clk_get_by_ofw_name(dev, 0, "aclk_mac", &sc->aclk_mac) != 0) { device_printf(sc->base.dev, "could not get aclk_mac clock\n"); sc->aclk_mac = NULL; } if (clk_get_by_ofw_name(dev, 0, "pclk_mac", &sc->pclk_mac) != 0) { device_printf(sc->base.dev, "could not get pclk_mac clock\n"); sc->pclk_mac = NULL; } /* Optional clock */ clk_get_by_ofw_name(dev, 0, "clk_mac_speed", &sc->clk_mac_speed); if (sc->base.phy_mode == MII_CONTYPE_RMII) { if (clk_get_by_ofw_name(dev, 0, "mac_clk_rx", &sc->mac_clk_rx) != 0) { device_printf(sc->base.dev, "could not get mac_clk_rx clock\n"); sc->mac_clk_rx = NULL; } if (clk_get_by_ofw_name(dev, 0, "clk_mac_ref", &sc->clk_mac_ref) != 0) { device_printf(sc->base.dev, "could not get clk_mac_ref clock\n"); sc->clk_mac_ref = NULL; } if (!sc->clock_in) { if (clk_get_by_ofw_name(dev, 0, "clk_mac_refout", &sc->clk_mac_refout) != 0) { device_printf(sc->base.dev, "could not get clk_mac_refout clock\n"); sc->clk_mac_refout = NULL; } clk_set_freq(sc->clk_stmmaceth, 50000000, 0); } } if ((sc->phy_node != 0) && sc->integrated_phy) { if (clk_get_by_ofw_index(dev, sc->phy_node, 0, &sc->clk_phy) != 0) { device_printf(sc->base.dev, "could not get PHY clock\n"); sc->clk_phy = NULL; } if (sc->clk_phy) { clk_set_freq(sc->clk_phy, 50000000, 0); } } if (sc->base.phy_mode == MII_CONTYPE_RMII) { if (sc->mac_clk_rx) clk_enable(sc->mac_clk_rx); if (sc->clk_mac_ref) clk_enable(sc->clk_mac_ref); if (sc->clk_mac_refout) clk_enable(sc->clk_mac_refout); } if (sc->clk_phy) clk_enable(sc->clk_phy); if (sc->aclk_mac) clk_enable(sc->aclk_mac); if (sc->pclk_mac) clk_enable(sc->pclk_mac); if (sc->mac_clk_tx) clk_enable(sc->mac_clk_tx); if (sc->clk_mac_speed) clk_enable(sc->clk_mac_speed); DELAY(50); return (0); } static int if_dwc_rk_init(device_t dev) { struct if_dwc_rk_softc *sc; phandle_t node; uint32_t rx, tx; int err; pcell_t phy_handle; char *clock_in_out; hwreset_t phy_reset; regulator_t phy_supply; sc = device_get_softc(dev); node = ofw_bus_get_node(dev); sc->ops = (struct if_dwc_rk_ops *)ofw_bus_search_compatible(dev, compat_data)->ocd_data; if (OF_hasprop(node, "rockchip,grf") && syscon_get_by_ofw_property(dev, node, "rockchip,grf", &sc->grf) != 0) { device_printf(dev, "cannot get grf driver handle\n"); return (ENXIO); } if (OF_getencprop(node, "tx_delay", &tx, sizeof(tx)) <= 0) tx = 0x30; if (OF_getencprop(node, "rx_delay", &rx, sizeof(rx)) <= 0) rx = 0x10; sc->tx_delay = tx; sc->rx_delay = rx; sc->clock_in = true; if (OF_getprop_alloc(node, "clock_in_out", (void **)&clock_in_out)) { if (strcmp(clock_in_out, "input") == 0) sc->clock_in = true; else sc->clock_in = false; OF_prop_free(clock_in_out); } if (OF_getencprop(node, "phy-handle", (void *)&phy_handle, sizeof(phy_handle)) > 0) sc->phy_node = OF_node_from_xref(phy_handle); if (sc->phy_node) sc->integrated_phy = OF_hasprop(sc->phy_node, "phy-is-integrated"); if (sc->integrated_phy) device_printf(sc->base.dev, "PHY is integrated\n"); if_dwc_rk_init_clocks(dev); if (sc->ops->set_phy_mode) sc->ops->set_phy_mode(sc); if (sc->ops->set_delays) sc->ops->set_delays(sc); /* * this also sets delays if tunable is defined */ err = if_dwc_rk_init_sysctl(sc); if (err != 0) return (err); if (regulator_get_by_ofw_property(sc->base.dev, 0, "phy-supply", &phy_supply) == 0) { if (regulator_enable(phy_supply)) { device_printf(sc->base.dev, "cannot enable 'phy' regulator\n"); } } else device_printf(sc->base.dev, "no phy-supply property\n"); /* Power up */ if (sc->integrated_phy) { if (sc->ops->phy_powerup) sc->ops->phy_powerup(sc); SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON0, (MACPHY_CON0_CLK_50M_MASK << 16) | MACPHY_CON0_CLK_50M); SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON0, (MACPHY_CON0_RMII_MODE_MASK << 16) | MACPHY_CON0_RMII_MODE); SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON2, 0xffff1234); SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON3, 0x003f0035); if (hwreset_get_by_ofw_idx(dev, sc->phy_node, 0, &phy_reset) == 0) { hwreset_assert(phy_reset); DELAY(20); hwreset_deassert(phy_reset); DELAY(20); } } return (0); } static int if_dwc_rk_mii_clk(device_t dev) { struct if_dwc_rk_softc *sc; uint64_t freq; int rv; sc = device_get_softc(dev); if ((rv = clk_get_freq(sc->pclk_mac, &freq)) != 0) return (-rv); freq = freq / 1000 / 1000; if (freq >= 60 && freq <= 100) return (GMAC_MII_CLK_60_100M_DIV42); else if (freq >= 100 && freq <= 150) return (GMAC_MII_CLK_100_150M_DIV62); else if (freq >= 20 && freq <= 35) return (GMAC_MII_CLK_25_35M_DIV16); else if (freq >= 35 && freq <= 60) return (GMAC_MII_CLK_35_60M_DIV26); else if (freq >= 150 && freq <= 250) return (GMAC_MII_CLK_150_250M_DIV102); else if (freq >= 250 && freq <= 300) return (GMAC_MII_CLK_250_300M_DIV124); return (-ERANGE); } static int if_dwc_rk_set_speed(device_t dev, int speed) { struct if_dwc_rk_softc *sc; sc = device_get_softc(dev); if (sc->ops->set_speed) return sc->ops->set_speed(sc, speed); return (0); } static device_method_t if_dwc_rk_methods[] = { DEVMETHOD(device_probe, if_dwc_rk_probe), DEVMETHOD(if_dwc_init, if_dwc_rk_init), DEVMETHOD(if_dwc_mii_clk, if_dwc_rk_mii_clk), DEVMETHOD(if_dwc_set_speed, if_dwc_rk_set_speed), DEVMETHOD_END }; extern driver_t dwc_driver; DEFINE_CLASS_1(dwc, dwc_rk_driver, if_dwc_rk_methods, sizeof(struct if_dwc_rk_softc), dwc_driver); DRIVER_MODULE(dwc_rk, simplebus, dwc_rk_driver, 0, 0); MODULE_DEPEND(dwc_rk, dwc, 1, 1, 1); diff --git a/sys/dev/eqos/if_eqos_fdt.c b/sys/dev/eqos/if_eqos_fdt.c index 114f83f3bf37..1d2aa53d158c 100644 --- a/sys/dev/eqos/if_eqos_fdt.c +++ b/sys/dev/eqos/if_eqos_fdt.c @@ -1,307 +1,307 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2022 Soren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Id: eqos_fdt.c 1049 2022-12-03 14:25:46Z sos $ */ #include "opt_platform.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include #include "if_eqos_if.h" #include "syscon_if.h" #include "gpio_if.h" #include "rk_otp_if.h" #define RK356XGMAC0 0xfe2a0000 #define RK356XGMAC1 0xfe010000 #define RK3588GMAC0 0xfe1b0000 #define RK3588GMAC1 0xfe1c0000 #define EQOS_GRF_GMAC0 0x0380 #define EQOS_GRF_GMAC1 0x0388 #define EQOS_CON0_OFFSET 0 #define EQOS_CON1_OFFSET 4 #define EQOS_GMAC_PHY_INTF_SEL_RGMII 0x00fc0010 #define EQOS_GMAC_PHY_INTF_SEL_RMII 0x00fc0040 #define EQOS_GMAC_RXCLK_DLY_ENABLE 0x00020002 #define EQOS_GMAC_RXCLK_DLY_DISABLE 0x00020000 #define EQOS_GMAC_TXCLK_DLY_ENABLE 0x00010001 #define EQOS_GMAC_TXCLK_DLY_DISABLE 0x00010000 #define EQOS_GMAC_CLK_RX_DL_CFG(val) (0x7f000000 | val << 8) #define EQOS_GMAC_CLK_TX_DL_CFG(val) (0x007f0000 | val) #define WR4(sc, o, v) bus_write_4(sc->res[EQOS_RES_MEM], (o), (v)) static const struct ofw_compat_data compat_data[] = { {"snps,dwmac-4.20a", 1}, { NULL, 0 } }; static int eqos_phy_reset(device_t dev) { pcell_t gpio_prop[4]; pcell_t delay_prop[3]; phandle_t node, gpio_node; device_t gpio; uint32_t pin, flags; uint32_t pin_value; node = ofw_bus_get_node(dev); if (OF_getencprop(node, "snps,reset-gpio", gpio_prop, sizeof(gpio_prop)) <= 0) return (0); if (OF_getencprop(node, "snps,reset-delays-us", delay_prop, sizeof(delay_prop)) <= 0) { device_printf(dev, "Wrong property for snps,reset-delays-us"); return (ENXIO); } gpio_node = OF_node_from_xref(gpio_prop[0]); if ((gpio = OF_device_from_xref(gpio_prop[0])) == NULL) { device_printf(dev, "Can't find gpio controller for phy reset\n"); return (ENXIO); } if (GPIO_MAP_GPIOS(gpio, node, gpio_node, nitems(gpio_prop) - 1, gpio_prop + 1, &pin, &flags) != 0) { device_printf(dev, "Can't map gpio for phy reset\n"); return (ENXIO); } pin_value = GPIO_PIN_LOW; if (OF_hasprop(node, "snps,reset-active-low")) pin_value = GPIO_PIN_HIGH; GPIO_PIN_SETFLAGS(gpio, pin, GPIO_PIN_OUTPUT); GPIO_PIN_SET(gpio, pin, pin_value); DELAY(delay_prop[0]); GPIO_PIN_SET(gpio, pin, !pin_value); DELAY(delay_prop[1]); GPIO_PIN_SET(gpio, pin, pin_value); DELAY(delay_prop[2]); return (0); } static int eqos_fdt_init(device_t dev) { struct eqos_softc *sc = device_get_softc(dev); phandle_t node = ofw_bus_get_node(dev); hwreset_t eqos_reset; regulator_t eqos_supply; uint32_t rx_delay, tx_delay; uint8_t buffer[16]; clk_t stmmaceth, mac_clk_rx, mac_clk_tx, aclk_mac, pclk_mac; uint64_t freq; int error; if (OF_hasprop(node, "rockchip,grf") && syscon_get_by_ofw_property(dev, node, "rockchip,grf", &sc->grf)) { device_printf(dev, "cannot get grf driver handle\n"); return (ENXIO); } /* figure out if gmac0 or gmac1 offset */ switch (rman_get_start(sc->res[EQOS_RES_MEM])) { case RK356XGMAC0: /* RK356X gmac0 */ sc->grf_offset = EQOS_GRF_GMAC0; break; case RK356XGMAC1: /* RK356X gmac1 */ sc->grf_offset = EQOS_GRF_GMAC1; break; case RK3588GMAC0: /* RK3588 gmac0 */ case RK3588GMAC1: /* RK3588 gmac1 */ default: device_printf(dev, "Unknown eqos address\n"); return (ENXIO); } if (hwreset_get_by_ofw_idx(dev, node, 0, &eqos_reset)) { device_printf(dev, "cannot get reset\n"); return (ENXIO); } hwreset_assert(eqos_reset); error = clk_set_assigned(dev, ofw_bus_get_node(dev)); if (error != 0) { device_printf(dev, "clk_set_assigned failed\n"); return (error); } if (clk_get_by_ofw_name(dev, 0, "stmmaceth", &stmmaceth) == 0) { error = clk_enable(stmmaceth); if (error != 0) { device_printf(dev, "could not enable main clock\n"); return (error); } if (bootverbose) { clk_get_freq(stmmaceth, &freq); device_printf(dev, "MAC clock(%s) freq: %jd\n", clk_get_name(stmmaceth), (intmax_t)freq); } } else { device_printf(dev, "could not find clock stmmaceth\n"); } if (clk_get_by_ofw_name(dev, 0, "mac_clk_rx", &mac_clk_rx) != 0) { device_printf(dev, "could not get mac_clk_rx clock\n"); mac_clk_rx = NULL; } if (clk_get_by_ofw_name(dev, 0, "mac_clk_tx", &mac_clk_tx) != 0) { device_printf(dev, "could not get mac_clk_tx clock\n"); mac_clk_tx = NULL; } if (clk_get_by_ofw_name(dev, 0, "aclk_mac", &aclk_mac) != 0) { device_printf(dev, "could not get aclk_mac clock\n"); aclk_mac = NULL; } if (clk_get_by_ofw_name(dev, 0, "pclk_mac", &pclk_mac) != 0) { device_printf(dev, "could not get pclk_mac clock\n"); pclk_mac = NULL; } if (aclk_mac) clk_enable(aclk_mac); if (pclk_mac) clk_enable(pclk_mac); if (mac_clk_tx) clk_enable(mac_clk_tx); sc->csr_clock = 125000000; sc->csr_clock_range = GMAC_MAC_MDIO_ADDRESS_CR_100_150; if (OF_getencprop(node, "tx_delay", &tx_delay, sizeof(tx_delay)) <= 0) tx_delay = 0x30; if (OF_getencprop(node, "rx_delay", &rx_delay, sizeof(rx_delay)) <= 0) rx_delay = 0x10; SYSCON_WRITE_4(sc->grf, sc->grf_offset + EQOS_CON0_OFFSET, EQOS_GMAC_CLK_RX_DL_CFG(rx_delay) | EQOS_GMAC_CLK_TX_DL_CFG(tx_delay)); SYSCON_WRITE_4(sc->grf, sc->grf_offset + EQOS_CON1_OFFSET, EQOS_GMAC_PHY_INTF_SEL_RGMII | EQOS_GMAC_RXCLK_DLY_ENABLE | EQOS_GMAC_TXCLK_DLY_ENABLE); if (!regulator_get_by_ofw_property(dev, 0, "phy-supply", &eqos_supply)) { if (regulator_enable(eqos_supply)) device_printf(dev, "cannot enable 'phy' regulator\n"); } else device_printf(dev, "no phy-supply property\n"); if (eqos_phy_reset(dev)) return (ENXIO); if (eqos_reset) hwreset_deassert(eqos_reset); /* set the MAC address if we have OTP data handy */ if (!RK_OTP_READ(dev, buffer, 0, sizeof(buffer))) { uint32_t mac; mac = hash32_buf(buffer, sizeof(buffer), HASHINIT); WR4(sc, GMAC_MAC_ADDRESS0_LOW, htobe32((mac & 0xffffff00) | 0x22)); mac = hash32_buf(buffer, sizeof(buffer), mac); WR4(sc, GMAC_MAC_ADDRESS0_HIGH, htobe16((mac & 0x0000ffff) + (device_get_unit(dev) << 8))); } return (0); } static int eqos_fdt_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "DesignWare EQOS Gigabit ethernet"); return (BUS_PROBE_DEFAULT); } static device_method_t eqos_fdt_methods[] = { /* Device interface */ DEVMETHOD(device_probe, eqos_fdt_probe), /* EQOS interface */ DEVMETHOD(if_eqos_init, eqos_fdt_init), DEVMETHOD_END }; DEFINE_CLASS_1(eqos, eqos_fdt_driver, eqos_fdt_methods, sizeof(struct eqos_softc), eqos_driver); DRIVER_MODULE(eqos, simplebus, eqos_fdt_driver, 0, 0); MODULE_DEPEND(eqos, ether, 1, 1, 1); MODULE_DEPEND(eqos, miibus, 1, 1, 1); diff --git a/sys/dev/fdt/simple_mfd.c b/sys/dev/fdt/simple_mfd.c index 2bed3e552760..3ca7578d234d 100644 --- a/sys/dev/fdt/simple_mfd.c +++ b/sys/dev/fdt/simple_mfd.c @@ -1,322 +1,322 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2018 Rubicon Communications, LLC (Netgate) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include device_t simple_mfd_add_device(device_t dev, phandle_t node, u_int order, const char *name, int unit, struct simplebus_devinfo *di); struct simplebus_devinfo *simple_mfd_setup_dinfo(device_t dev, phandle_t node, struct simplebus_devinfo *di); #include "syscon_if.h" -#include +#include MALLOC_DECLARE(M_SYSCON); static uint32_t simple_mfd_syscon_read_4(struct syscon *syscon, bus_size_t offset); static int simple_mfd_syscon_write_4(struct syscon *syscon, bus_size_t offset, uint32_t val); static int simple_mfd_syscon_modify_4(struct syscon *syscon, bus_size_t offset, uint32_t clear_bits, uint32_t set_bits); #define SYSCON_LOCK(_sc) mtx_lock_spin(&(_sc)->mtx) #define SYSCON_UNLOCK(_sc) mtx_unlock_spin(&(_sc)->mtx) #define SYSCON_LOCK_INIT(_sc) mtx_init(&(_sc)->mtx, \ device_get_nameunit((_sc)->dev), "syscon", MTX_SPIN) #define SYSCON_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->mtx); #define SYSCON_ASSERT_LOCKED(_sc) mtx_assert(&(_sc)->mtx, MA_OWNED); #define SYSCON_ASSERT_UNLOCKED(_sc) mtx_assert(&(_sc)->mtx, MA_NOTOWNED); static syscon_method_t simple_mfd_syscon_methods[] = { SYSCONMETHOD(syscon_unlocked_read_4, simple_mfd_syscon_read_4), SYSCONMETHOD(syscon_unlocked_write_4, simple_mfd_syscon_write_4), SYSCONMETHOD(syscon_unlocked_modify_4, simple_mfd_syscon_modify_4), SYSCONMETHOD_END }; DEFINE_CLASS_1(simple_mfd_syscon, simple_mfd_syscon_class, simple_mfd_syscon_methods, 0, syscon_class); static uint32_t simple_mfd_syscon_read_4(struct syscon *syscon, bus_size_t offset) { struct simple_mfd_softc *sc; uint32_t val; sc = device_get_softc(syscon->pdev); SYSCON_ASSERT_LOCKED(sc); val = bus_read_4(sc->mem_res, offset); return (val); } static int simple_mfd_syscon_write_4(struct syscon *syscon, bus_size_t offset, uint32_t val) { struct simple_mfd_softc *sc; sc = device_get_softc(syscon->pdev); SYSCON_ASSERT_LOCKED(sc); bus_write_4(sc->mem_res, offset, val); return (0); } static int simple_mfd_syscon_modify_4(struct syscon *syscon, bus_size_t offset, uint32_t clear_bits, uint32_t set_bits) { struct simple_mfd_softc *sc; uint32_t val; sc = device_get_softc(syscon->pdev); SYSCON_ASSERT_LOCKED(sc); val = bus_read_4(sc->mem_res, offset); val &= ~clear_bits; val |= set_bits; bus_write_4(sc->mem_res, offset, val); return (0); } static int simple_mfd_syscon_get_handle(device_t dev, struct syscon **syscon) { struct simple_mfd_softc *sc; sc = device_get_softc(dev); *syscon = sc->syscon; if (*syscon == NULL) return (ENODEV); return (0); } static void simple_mfd_syscon_lock(device_t dev) { struct simple_mfd_softc *sc; sc = device_get_softc(dev); SYSCON_LOCK(sc); } static void simple_mfd_syscon_unlock(device_t dev) { struct simple_mfd_softc *sc; sc = device_get_softc(dev); SYSCON_UNLOCK(sc); } static int simple_mfd_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (!ofw_bus_is_compatible(dev, "simple-mfd")) return (ENXIO); device_set_desc(dev, "Simple MFD (Multi-Functions Device)"); return (BUS_PROBE_GENERIC); } static int simple_mfd_attach(device_t dev) { struct simple_mfd_softc *sc; phandle_t node, child; device_t cdev; int rid; sc = device_get_softc(dev); node = ofw_bus_get_node(dev); sc->dev = dev; rid = 0; /* Parse address-cells and size-cells from the parent node as a fallback */ if (OF_getencprop(node, "#address-cells", &sc->sc.acells, sizeof(sc->sc.acells)) == -1) { if (OF_getencprop(OF_parent(node), "#address-cells", &sc->sc.acells, sizeof(sc->sc.acells)) == -1) { sc->sc.acells = 2; } } if (OF_getencprop(node, "#size-cells", &sc->sc.scells, sizeof(sc->sc.scells)) == -1) { if (OF_getencprop(OF_parent(node), "#size-cells", &sc->sc.scells, sizeof(sc->sc.scells)) == -1) { sc->sc.scells = 1; } } /* If the node has a ranges prop, parse it so children mapping will be done correctly */ if (OF_hasprop(node, "ranges")) { if (simplebus_fill_ranges(node, &sc->sc) < 0) { device_printf(dev, "could not get ranges\n"); return (ENXIO); } } /* Attach child devices */ for (child = OF_child(node); child > 0; child = OF_peer(child)) { cdev = simple_mfd_add_device(dev, child, 0, NULL, -1, NULL); if (cdev != NULL) device_probe_and_attach(cdev); } if (ofw_bus_is_compatible(dev, "syscon")) { sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (sc->mem_res == NULL) { device_printf(dev, "Cannot allocate memory resource\n"); return (ENXIO); } SYSCON_LOCK_INIT(sc); sc->syscon = syscon_create_ofw_node(dev, &simple_mfd_syscon_class, ofw_bus_get_node(dev)); if (sc->syscon == NULL) { device_printf(dev, "Failed to create/register syscon\n"); return (ENXIO); } } return (bus_generic_attach(dev)); } static int simple_mfd_detach(device_t dev) { struct simple_mfd_softc *sc; sc = device_get_softc(dev); if (ofw_bus_is_compatible(dev, "syscon")) { if (sc->syscon != NULL) { syscon_unregister(sc->syscon); free(sc->syscon, M_SYSCON); } SYSCON_LOCK_DESTROY(sc); if (sc->mem_res != NULL) bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res); } return (0); } struct simplebus_devinfo * simple_mfd_setup_dinfo(device_t dev, phandle_t node, struct simplebus_devinfo *di) { struct simplebus_softc *sc; struct simplebus_devinfo *ndi; sc = device_get_softc(dev); if (di == NULL) ndi = malloc(sizeof(*ndi), M_DEVBUF, M_WAITOK | M_ZERO); else ndi = di; if (ofw_bus_gen_setup_devinfo(&ndi->obdinfo, node) != 0) { if (di == NULL) free(ndi, M_DEVBUF); return (NULL); } /* reg resources is from the parent but interrupts is on the node itself */ resource_list_init(&ndi->rl); ofw_bus_reg_to_rl(dev, OF_parent(node), sc->acells, sc->scells, &ndi->rl); ofw_bus_intr_to_rl(dev, node, &ndi->rl, NULL); return (ndi); } device_t simple_mfd_add_device(device_t dev, phandle_t node, u_int order, const char *name, int unit, struct simplebus_devinfo *di) { struct simplebus_devinfo *ndi; device_t cdev; if ((ndi = simple_mfd_setup_dinfo(dev, node, di)) == NULL) return (NULL); cdev = device_add_child_ordered(dev, order, name, unit); if (cdev == NULL) { device_printf(dev, "<%s>: device_add_child failed\n", ndi->obdinfo.obd_name); resource_list_free(&ndi->rl); ofw_bus_gen_destroy_devinfo(&ndi->obdinfo); if (di == NULL) free(ndi, M_DEVBUF); return (NULL); } device_set_ivars(cdev, ndi); return(cdev); } static device_method_t simple_mfd_methods[] = { /* syscon interface */ DEVMETHOD(syscon_get_handle, simple_mfd_syscon_get_handle), DEVMETHOD(syscon_device_lock, simple_mfd_syscon_lock), DEVMETHOD(syscon_device_unlock, simple_mfd_syscon_unlock), /* Device interface */ DEVMETHOD(device_probe, simple_mfd_probe), DEVMETHOD(device_attach, simple_mfd_attach), DEVMETHOD(device_detach, simple_mfd_detach), DEVMETHOD_END }; DEFINE_CLASS_1(simple_mfd, simple_mfd_driver, simple_mfd_methods, sizeof(struct simple_mfd_softc), simplebus_driver); EARLY_DRIVER_MODULE(simple_mfd, simplebus, simple_mfd_driver, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_LATE); MODULE_VERSION(simple_mfd, 1); diff --git a/sys/dev/qcom_dwc3/qcom_dwc3.c b/sys/dev/qcom_dwc3/qcom_dwc3.c index cd58b9ef7705..5fc93b871ad1 100644 --- a/sys/dev/qcom_dwc3/qcom_dwc3.c +++ b/sys/dev/qcom_dwc3/qcom_dwc3.c @@ -1,174 +1,174 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2021 Adrian Chadd * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Qualcomm DWC3 glue */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include static struct ofw_compat_data compat_data[] = { { "qcom,dwc3", 1}, { NULL, 0 } }; struct qcom_dwc3_softc { struct simplebus_softc sc; device_t dev; clk_t clk_master; clk_t clk_sleep; clk_t clk_mock_utmi; int type; }; static int qcom_dwc3_probe(device_t dev) { phandle_t node; if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); /* Binding says that we need a child node for the actual dwc3 controller */ node = ofw_bus_get_node(dev); if (OF_child(node) <= 0) return (ENXIO); device_set_desc(dev, "Qualcomm DWC3"); return (BUS_PROBE_DEFAULT); } static int qcom_dwc3_attach(device_t dev) { struct qcom_dwc3_softc *sc; device_t cdev; phandle_t node, child; int err; sc = device_get_softc(dev); sc->dev = dev; node = ofw_bus_get_node(dev); sc->type = ofw_bus_search_compatible(dev, compat_data)->ocd_data; /* Mandatory clocks */ if (clk_get_by_ofw_name(dev, 0, "master", &sc->clk_master) != 0) { device_printf(dev, "Cannot get master clock\n"); return (ENXIO); } if (clk_get_by_ofw_name(dev, 0, "sleep", &sc->clk_sleep) != 0) { device_printf(dev, "Cannot get sleep clock\n"); return (ENXIO); } if (clk_get_by_ofw_name(dev, 0, "mock_utmi", &sc->clk_mock_utmi) != 0) { device_printf(dev, "Cannot get mock_utmi clock\n"); return (ENXIO); } /* * TODO: when we support optional reset blocks, take things * out of reset (well, put them into reset, then take out of reset.) */ /* * Now, iterate over the clocks and enable them. */ err = clk_enable(sc->clk_master); if (err != 0) { device_printf(dev, "Could not enable clock %s\n", clk_get_name(sc->clk_master)); return (ENXIO); } err = clk_enable(sc->clk_sleep); if (err != 0) { device_printf(dev, "Could not enable clock %s\n", clk_get_name(sc->clk_sleep)); return (ENXIO); } err = clk_enable(sc->clk_mock_utmi); if (err != 0) { device_printf(dev, "Could not enable clock %s\n", clk_get_name(sc->clk_mock_utmi)); return (ENXIO); } /* * Rest is glue code. */ simplebus_init(dev, node); if (simplebus_fill_ranges(node, &sc->sc) < 0) { device_printf(dev, "could not get ranges\n"); return (ENXIO); } for (child = OF_child(node); child > 0; child = OF_peer(child)) { cdev = simplebus_add_device(dev, child, 0, NULL, -1, NULL); if (cdev != NULL) device_probe_and_attach(cdev); } return (bus_generic_attach(dev)); } static device_method_t qcom_dwc3_methods[] = { /* Device interface */ DEVMETHOD(device_probe, qcom_dwc3_probe), DEVMETHOD(device_attach, qcom_dwc3_attach), /* XXX TODO suspend */ /* XXX TODO resume */ DEVMETHOD_END }; DEFINE_CLASS_1(qcom_dwc3, qcom_dwc3_driver, qcom_dwc3_methods, sizeof(struct qcom_dwc3_softc), simplebus_driver); DRIVER_MODULE(qcom_dwc3, simplebus, qcom_dwc3_driver, 0, 0); diff --git a/sys/dev/sdhci/sdhci_fdt.c b/sys/dev/sdhci/sdhci_fdt.c index 3914c96b5165..e7dda316539c 100644 --- a/sys/dev/sdhci/sdhci_fdt.c +++ b/sys/dev/sdhci/sdhci_fdt.c @@ -1,724 +1,724 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2012 Thomas Skibo * Copyright (c) 2008 Alexander Motin * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Generic driver to attach sdhci controllers on simplebus. * Derived mainly from sdhci_pci.c */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include #include #include #include "mmcbr_if.h" #include "sdhci_if.h" #include "opt_mmccam.h" #include "clkdev_if.h" #include "syscon_if.h" #define MAX_SLOTS 6 #define SDHCI_FDT_ARMADA38X 1 #define SDHCI_FDT_XLNX_ZY7 2 #define SDHCI_FDT_QUALCOMM 3 #define SDHCI_FDT_RK3399 4 #define SDHCI_FDT_RK3568 5 #define SDHCI_FDT_XLNX_ZMP 6 #define RK3399_GRF_EMMCCORE_CON0 0xf000 #define RK3399_CORECFG_BASECLKFREQ 0xff00 #define RK3399_CORECFG_TIMEOUTCLKUNIT (1 << 7) #define RK3399_CORECFG_TUNINGCOUNT 0x3f #define RK3399_GRF_EMMCCORE_CON11 0xf02c #define RK3399_CORECFG_CLOCKMULTIPLIER 0xff #define RK3568_EMMC_HOST_CTRL 0x0508 #define RK3568_EMMC_EMMC_CTRL 0x052c #define RK3568_EMMC_ATCTRL 0x0540 #define RK3568_EMMC_DLL_CTRL 0x0800 #define DLL_CTRL_SRST 0x00000001 #define DLL_CTRL_START 0x00000002 #define DLL_CTRL_START_POINT_DEFAULT 0x00050000 #define DLL_CTRL_INCREMENT_DEFAULT 0x00000200 #define RK3568_EMMC_DLL_RXCLK 0x0804 #define DLL_RXCLK_DELAY_ENABLE 0x08000000 #define DLL_RXCLK_NO_INV 0x20000000 #define RK3568_EMMC_DLL_TXCLK 0x0808 #define DLL_TXCLK_DELAY_ENABLE 0x08000000 #define DLL_TXCLK_TAPNUM_DEFAULT 0x00000008 #define DLL_TXCLK_TAPNUM_FROM_SW 0x01000000 #define RK3568_EMMC_DLL_STRBIN 0x080c #define DLL_STRBIN_DELAY_ENABLE 0x08000000 #define DLL_STRBIN_TAPNUM_DEFAULT 0x00000008 #define DLL_STRBIN_TAPNUM_FROM_SW 0x01000000 #define RK3568_EMMC_DLL_STATUS0 0x0840 #define DLL_STATUS0_DLL_LOCK 0x00000100 #define DLL_STATUS0_DLL_TIMEOUT 0x00000200 #define LOWEST_SET_BIT(mask) ((((mask) - 1) & (mask)) ^ (mask)) #define SHIFTIN(x, mask) ((x) * LOWEST_SET_BIT(mask)) static struct ofw_compat_data compat_data[] = { { "marvell,armada-380-sdhci", SDHCI_FDT_ARMADA38X }, { "qcom,sdhci-msm-v4", SDHCI_FDT_QUALCOMM }, { "rockchip,rk3399-sdhci-5.1", SDHCI_FDT_RK3399 }, { "xlnx,zy7_sdhci", SDHCI_FDT_XLNX_ZY7 }, { "rockchip,rk3568-dwcmshc", SDHCI_FDT_RK3568 }, { "xlnx,zynqmp-8.9a", SDHCI_FDT_XLNX_ZMP }, { NULL, 0 } }; struct sdhci_fdt_softc { device_t dev; /* Controller device */ u_int quirks; /* Chip specific quirks */ u_int caps; /* If we override SDHCI_CAPABILITIES */ uint32_t max_clk; /* Max possible freq */ uint8_t sdma_boundary; /* If we override the SDMA boundary */ struct resource *irq_res; /* IRQ resource */ void *intrhand; /* Interrupt handle */ int num_slots; /* Number of slots on this controller*/ struct sdhci_slot slots[MAX_SLOTS]; struct resource *mem_res[MAX_SLOTS]; /* Memory resource */ bool wp_inverted; /* WP pin is inverted */ bool wp_disabled; /* WP pin is not supported */ bool no_18v; /* No 1.8V support */ clk_t clk_xin; /* xin24m fixed clock */ clk_t clk_ahb; /* ahb clock */ clk_t clk_core; /* core clock */ phy_t phy; /* phy to be used */ struct syscon *syscon; /* Handle to the syscon */ }; struct sdhci_exported_clocks_sc { device_t clkdev; }; static int sdhci_exported_clocks_init(struct clknode *clk, device_t dev) { clknode_init_parent_idx(clk, 0); return (0); } static clknode_method_t sdhci_exported_clocks_clknode_methods[] = { /* Device interface */ CLKNODEMETHOD(clknode_init, sdhci_exported_clocks_init), CLKNODEMETHOD_END }; DEFINE_CLASS_1(sdhci_exported_clocks_clknode, sdhci_exported_clocks_clknode_class, sdhci_exported_clocks_clknode_methods, sizeof(struct sdhci_exported_clocks_sc), clknode_class); static int sdhci_clock_ofw_map(struct clkdom *clkdom, uint32_t ncells, phandle_t *cells, struct clknode **clk) { int id = 1; /* Our clock id starts at 1 */ if (ncells != 0) id = cells[1]; *clk = clknode_find_by_id(clkdom, id); if (*clk == NULL) return (ENXIO); return (0); } static void sdhci_export_clocks(struct sdhci_fdt_softc *sc) { struct clknode_init_def def; struct sdhci_exported_clocks_sc *clksc; struct clkdom *clkdom; struct clknode *clk; bus_addr_t paddr; bus_size_t psize; const char **clknames; phandle_t node; int i, nclocks, ncells, error; node = ofw_bus_get_node(sc->dev); if (ofw_reg_to_paddr(node, 0, &paddr, &psize, NULL) != 0) { device_printf(sc->dev, "cannot parse 'reg' property\n"); return; } error = ofw_bus_parse_xref_list_get_length(node, "clocks", "#clock-cells", &ncells); if (error != 0 || ncells != 2) { device_printf(sc->dev, "couldn't find parent clocks\n"); return; } nclocks = ofw_bus_string_list_to_array(node, "clock-output-names", &clknames); /* No clocks to export */ if (nclocks <= 0) return; clkdom = clkdom_create(sc->dev); clkdom_set_ofw_mapper(clkdom, sdhci_clock_ofw_map); for (i = 0; i < nclocks; i++) { memset(&def, 0, sizeof(def)); def.id = i + 1; /* Exported clock IDs starts at 1 */ def.name = clknames[i]; def.parent_names = malloc(sizeof(char *) * 1, M_OFWPROP, M_WAITOK); def.parent_names[0] = clk_get_name(sc->clk_xin); def.parent_cnt = 1; clk = clknode_create(clkdom, &sdhci_exported_clocks_clknode_class, &def); if (clk == NULL) { device_printf(sc->dev, "cannot create clknode\n"); return; } clksc = clknode_get_softc(clk); clksc->clkdev = device_get_parent(sc->dev); clknode_register(clkdom, clk); } if (clkdom_finit(clkdom) != 0) { device_printf(sc->dev, "cannot finalize clkdom initialization\n"); return; } if (bootverbose) clkdom_dump(clkdom); } static int sdhci_init_clocks(device_t dev) { struct sdhci_fdt_softc *sc = device_get_softc(dev); int error; /* Get and activate clocks */ error = clk_get_by_ofw_name(dev, 0, "clk_xin", &sc->clk_xin); if (error != 0) { device_printf(dev, "cannot get xin clock\n"); return (ENXIO); } error = clk_enable(sc->clk_xin); if (error != 0) { device_printf(dev, "cannot enable xin clock\n"); return (ENXIO); } error = clk_get_by_ofw_name(dev, 0, "clk_ahb", &sc->clk_ahb); if (error != 0) { device_printf(dev, "cannot get ahb clock\n"); return (ENXIO); } error = clk_enable(sc->clk_ahb); if (error != 0) { device_printf(dev, "cannot enable ahb clock\n"); return (ENXIO); } return (0); } static int sdhci_init_phy(struct sdhci_fdt_softc *sc) { int error; /* Enable PHY */ error = phy_get_by_ofw_name(sc->dev, 0, "phy_arasan", &sc->phy); if (error == ENOENT) return (0); if (error != 0) { device_printf(sc->dev, "Could not get phy\n"); return (ENXIO); } error = phy_enable(sc->phy); if (error != 0) { device_printf(sc->dev, "Could not enable phy\n"); return (ENXIO); } return (0); } static int sdhci_get_syscon(struct sdhci_fdt_softc *sc) { phandle_t node; /* Get syscon */ node = ofw_bus_get_node(sc->dev); if (OF_hasprop(node, "arasan,soc-ctl-syscon") && syscon_get_by_ofw_property(sc->dev, node, "arasan,soc-ctl-syscon", &sc->syscon) != 0) { device_printf(sc->dev, "cannot get syscon handle\n"); return (ENXIO); } return (0); } static int sdhci_init_rk3399(device_t dev) { struct sdhci_fdt_softc *sc = device_get_softc(dev); uint64_t freq; uint32_t mask, val; int error; error = clk_get_freq(sc->clk_xin, &freq); if (error != 0) { device_printf(dev, "cannot get xin clock frequency\n"); return (ENXIO); } /* Disable clock multiplier */ mask = RK3399_CORECFG_CLOCKMULTIPLIER; val = 0; SYSCON_WRITE_4(sc->syscon, RK3399_GRF_EMMCCORE_CON11, (mask << 16) | val); /* Set base clock frequency */ mask = RK3399_CORECFG_BASECLKFREQ; val = SHIFTIN((freq + (1000000 / 2)) / 1000000, RK3399_CORECFG_BASECLKFREQ); SYSCON_WRITE_4(sc->syscon, RK3399_GRF_EMMCCORE_CON0, (mask << 16) | val); return (0); } static uint8_t sdhci_fdt_read_1(device_t dev, struct sdhci_slot *slot, bus_size_t off) { struct sdhci_fdt_softc *sc = device_get_softc(dev); return (bus_read_1(sc->mem_res[slot->num], off)); } static void sdhci_fdt_write_1(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint8_t val) { struct sdhci_fdt_softc *sc = device_get_softc(dev); bus_write_1(sc->mem_res[slot->num], off, val); } static uint16_t sdhci_fdt_read_2(device_t dev, struct sdhci_slot *slot, bus_size_t off) { struct sdhci_fdt_softc *sc = device_get_softc(dev); return (bus_read_2(sc->mem_res[slot->num], off)); } static void sdhci_fdt_write_2(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint16_t val) { struct sdhci_fdt_softc *sc = device_get_softc(dev); bus_write_2(sc->mem_res[slot->num], off, val); } static uint32_t sdhci_fdt_read_4(device_t dev, struct sdhci_slot *slot, bus_size_t off) { struct sdhci_fdt_softc *sc = device_get_softc(dev); uint32_t val32; val32 = bus_read_4(sc->mem_res[slot->num], off); if (off == SDHCI_CAPABILITIES && sc->no_18v) val32 &= ~SDHCI_CAN_VDD_180; return (val32); } static void sdhci_fdt_write_4(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint32_t val) { struct sdhci_fdt_softc *sc = device_get_softc(dev); bus_write_4(sc->mem_res[slot->num], off, val); } static void sdhci_fdt_read_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint32_t *data, bus_size_t count) { struct sdhci_fdt_softc *sc = device_get_softc(dev); bus_read_multi_4(sc->mem_res[slot->num], off, data, count); } static void sdhci_fdt_write_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint32_t *data, bus_size_t count) { struct sdhci_fdt_softc *sc = device_get_softc(dev); bus_write_multi_4(sc->mem_res[slot->num], off, data, count); } static void sdhci_fdt_intr(void *arg) { struct sdhci_fdt_softc *sc = (struct sdhci_fdt_softc *)arg; int i; for (i = 0; i < sc->num_slots; i++) sdhci_generic_intr(&sc->slots[i]); } static int sdhci_fdt_get_ro(device_t bus, device_t dev) { struct sdhci_fdt_softc *sc = device_get_softc(bus); if (sc->wp_disabled) return (false); return (sdhci_generic_get_ro(bus, dev) ^ sc->wp_inverted); } static int sdhci_fdt_set_clock(device_t dev, struct sdhci_slot *slot, int clock) { struct sdhci_fdt_softc *sc = device_get_softc(dev); int32_t val; int i; if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == SDHCI_FDT_RK3568) { if (clock == 400000) clock = 375000; if (clock) { clk_set_freq(sc->clk_core, clock, 0); if (clock <= 52000000) { bus_write_4(sc->mem_res[slot->num], RK3568_EMMC_DLL_CTRL, 0x0); bus_write_4(sc->mem_res[slot->num], RK3568_EMMC_DLL_RXCLK, DLL_RXCLK_NO_INV); bus_write_4(sc->mem_res[slot->num], RK3568_EMMC_DLL_TXCLK, 0x0); bus_write_4(sc->mem_res[slot->num], RK3568_EMMC_DLL_STRBIN, 0x0); return (clock); } bus_write_4(sc->mem_res[slot->num], RK3568_EMMC_DLL_CTRL, DLL_CTRL_START); DELAY(1000); bus_write_4(sc->mem_res[slot->num], RK3568_EMMC_DLL_CTRL, 0); bus_write_4(sc->mem_res[slot->num], RK3568_EMMC_DLL_CTRL, DLL_CTRL_START_POINT_DEFAULT | DLL_CTRL_INCREMENT_DEFAULT | DLL_CTRL_START); for (i = 0; i < 500; i++) { val = bus_read_4(sc->mem_res[slot->num], RK3568_EMMC_DLL_STATUS0); if (val & DLL_STATUS0_DLL_LOCK && !(val & DLL_STATUS0_DLL_TIMEOUT)) break; DELAY(1000); } bus_write_4(sc->mem_res[slot->num], RK3568_EMMC_ATCTRL, (0x1 << 16 | 0x2 << 17 | 0x3 << 19)); bus_write_4(sc->mem_res[slot->num], RK3568_EMMC_DLL_RXCLK, DLL_RXCLK_DELAY_ENABLE | DLL_RXCLK_NO_INV); bus_write_4(sc->mem_res[slot->num], RK3568_EMMC_DLL_TXCLK, DLL_TXCLK_DELAY_ENABLE | DLL_TXCLK_TAPNUM_DEFAULT|DLL_TXCLK_TAPNUM_FROM_SW); bus_write_4(sc->mem_res[slot->num], RK3568_EMMC_DLL_STRBIN, DLL_STRBIN_DELAY_ENABLE | DLL_STRBIN_TAPNUM_DEFAULT | DLL_STRBIN_TAPNUM_FROM_SW); } } return (clock); } static int sdhci_fdt_probe(device_t dev) { struct sdhci_fdt_softc *sc = device_get_softc(dev); phandle_t node; pcell_t cid; sc->quirks = 0; sc->num_slots = 1; sc->max_clk = 0; if (!ofw_bus_status_okay(dev)) return (ENXIO); switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) { case SDHCI_FDT_ARMADA38X: sc->quirks = SDHCI_QUIRK_BROKEN_AUTO_STOP; device_set_desc(dev, "ARMADA38X SDHCI controller"); break; case SDHCI_FDT_QUALCOMM: sc->quirks = SDHCI_QUIRK_ALL_SLOTS_NON_REMOVABLE | SDHCI_QUIRK_BROKEN_SDMA_BOUNDARY; sc->sdma_boundary = SDHCI_BLKSZ_SDMA_BNDRY_4K; device_set_desc(dev, "Qualcomm FDT SDHCI controller"); break; case SDHCI_FDT_RK3399: device_set_desc(dev, "Rockchip RK3399 fdt SDHCI controller"); break; case SDHCI_FDT_XLNX_ZY7: sc->quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK; device_set_desc(dev, "Zynq-7000 generic fdt SDHCI controller"); break; case SDHCI_FDT_RK3568: device_set_desc(dev, "Rockchip RK3568 fdt SDHCI controller"); break; case SDHCI_FDT_XLNX_ZMP: device_set_desc(dev, "ZynqMP generic fdt SDHCI controller"); break; default: return (ENXIO); } node = ofw_bus_get_node(dev); /* Allow dts to patch quirks, slots, and max-frequency. */ if ((OF_getencprop(node, "quirks", &cid, sizeof(cid))) > 0) sc->quirks = cid; if ((OF_getencprop(node, "num-slots", &cid, sizeof(cid))) > 0) sc->num_slots = cid; if ((OF_getencprop(node, "max-frequency", &cid, sizeof(cid))) > 0) sc->max_clk = cid; if (OF_hasprop(node, "no-1-8-v")) sc->no_18v = true; if (OF_hasprop(node, "wp-inverted")) sc->wp_inverted = true; if (OF_hasprop(node, "disable-wp")) sc->wp_disabled = true; return (0); } static int sdhci_fdt_attach(device_t dev) { struct sdhci_fdt_softc *sc = device_get_softc(dev); struct sdhci_slot *slot; int err, slots, rid, i, compat; sc->dev = dev; /* Allocate IRQ. */ rid = 0; sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); if (sc->irq_res == NULL) { device_printf(dev, "Can't allocate IRQ\n"); return (ENOMEM); } compat = ofw_bus_search_compatible(dev, compat_data)->ocd_data; switch (compat) { case SDHCI_FDT_RK3399: case SDHCI_FDT_XLNX_ZMP: err = sdhci_init_clocks(dev); if (err != 0) { device_printf(dev, "Cannot init clocks\n"); return (err); } sdhci_export_clocks(sc); if ((err = sdhci_init_phy(sc)) != 0) { device_printf(dev, "Cannot init phy\n"); return (err); } if ((err = sdhci_get_syscon(sc)) != 0) { device_printf(dev, "Cannot get syscon handle\n"); return (err); } if (compat == SDHCI_FDT_RK3399) { err = sdhci_init_rk3399(dev); if (err != 0) { device_printf(dev, "Cannot init RK3399 SDHCI\n"); return (err); } } break; case SDHCI_FDT_RK3568: /* setup & enable clocks */ if (clk_get_by_ofw_name(dev, 0, "core", &sc->clk_core)) { device_printf(dev, "cannot get core clock\n"); return (ENXIO); } clk_enable(sc->clk_core); break; default: break; } /* Scan all slots. */ slots = sc->num_slots; /* number of slots determined in probe(). */ sc->num_slots = 0; for (i = 0; i < slots; i++) { slot = &sc->slots[sc->num_slots]; /* Allocate memory. */ rid = 0; sc->mem_res[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (sc->mem_res[i] == NULL) { device_printf(dev, "Can't allocate memory for slot %d\n", i); continue; } slot->quirks = sc->quirks; slot->caps = sc->caps; slot->max_clk = sc->max_clk; slot->sdma_boundary = sc->sdma_boundary; if (sdhci_init_slot(dev, slot, i) != 0) continue; sc->num_slots++; } device_printf(dev, "%d slot(s) allocated\n", sc->num_slots); /* Activate the interrupt */ err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE, NULL, sdhci_fdt_intr, sc, &sc->intrhand); if (err) { device_printf(dev, "Cannot setup IRQ\n"); return (err); } /* Process cards detection. */ for (i = 0; i < sc->num_slots; i++) sdhci_start_slot(&sc->slots[i]); return (0); } static int sdhci_fdt_detach(device_t dev) { struct sdhci_fdt_softc *sc = device_get_softc(dev); int i; bus_generic_detach(dev); bus_teardown_intr(dev, sc->irq_res, sc->intrhand); bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(sc->irq_res), sc->irq_res); for (i = 0; i < sc->num_slots; i++) { sdhci_cleanup_slot(&sc->slots[i]); bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->mem_res[i]), sc->mem_res[i]); } return (0); } static device_method_t sdhci_fdt_methods[] = { /* device_if */ DEVMETHOD(device_probe, sdhci_fdt_probe), DEVMETHOD(device_attach, sdhci_fdt_attach), DEVMETHOD(device_detach, sdhci_fdt_detach), /* Bus interface */ DEVMETHOD(bus_read_ivar, sdhci_generic_read_ivar), DEVMETHOD(bus_write_ivar, sdhci_generic_write_ivar), /* mmcbr_if */ DEVMETHOD(mmcbr_update_ios, sdhci_generic_update_ios), DEVMETHOD(mmcbr_request, sdhci_generic_request), DEVMETHOD(mmcbr_get_ro, sdhci_fdt_get_ro), DEVMETHOD(mmcbr_acquire_host, sdhci_generic_acquire_host), DEVMETHOD(mmcbr_release_host, sdhci_generic_release_host), /* SDHCI registers accessors */ DEVMETHOD(sdhci_read_1, sdhci_fdt_read_1), DEVMETHOD(sdhci_read_2, sdhci_fdt_read_2), DEVMETHOD(sdhci_read_4, sdhci_fdt_read_4), DEVMETHOD(sdhci_read_multi_4, sdhci_fdt_read_multi_4), DEVMETHOD(sdhci_write_1, sdhci_fdt_write_1), DEVMETHOD(sdhci_write_2, sdhci_fdt_write_2), DEVMETHOD(sdhci_write_4, sdhci_fdt_write_4), DEVMETHOD(sdhci_write_multi_4, sdhci_fdt_write_multi_4), DEVMETHOD(sdhci_set_clock, sdhci_fdt_set_clock), DEVMETHOD_END }; static driver_t sdhci_fdt_driver = { "sdhci_fdt", sdhci_fdt_methods, sizeof(struct sdhci_fdt_softc), }; DRIVER_MODULE(sdhci_fdt, simplebus, sdhci_fdt_driver, NULL, NULL); SDHCI_DEPEND(sdhci_fdt); #ifndef MMCCAM MMC_DECLARE_BRIDGE(sdhci_fdt); #endif diff --git a/sys/dev/sdhci/sdhci_fsl_fdt.c b/sys/dev/sdhci/sdhci_fsl_fdt.c index 12ce8c13342c..c04bdefb1382 100644 --- a/sys/dev/sdhci/sdhci_fsl_fdt.c +++ b/sys/dev/sdhci/sdhci_fsl_fdt.c @@ -1,1562 +1,1562 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2020 - 2021 Alstom Group. * Copyright (c) 2020 - 2021 Semihalf. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* eSDHC controller driver for NXP QorIQ Layerscape SoCs. */ #include #include #include #include #include #include #include #include #include #include -#include +#include #include #include #include #include #include #include #include #include "mmcbr_if.h" #include "sdhci_if.h" #include "syscon_if.h" #define RD4 (sc->read) #define WR4 (sc->write) #define SDHCI_FSL_PRES_STATE 0x24 #define SDHCI_FSL_PRES_SDSTB (1 << 3) #define SDHCI_FSL_PRES_COMPAT_MASK 0x000f0f07 #define SDHCI_FSL_PROT_CTRL 0x28 #define SDHCI_FSL_PROT_CTRL_WIDTH_1BIT (0 << 1) #define SDHCI_FSL_PROT_CTRL_WIDTH_4BIT (1 << 1) #define SDHCI_FSL_PROT_CTRL_WIDTH_8BIT (2 << 1) #define SDHCI_FSL_PROT_CTRL_WIDTH_MASK (3 << 1) #define SDHCI_FSL_PROT_CTRL_BYTE_SWAP (0 << 4) #define SDHCI_FSL_PROT_CTRL_BYTE_NATIVE (2 << 4) #define SDHCI_FSL_PROT_CTRL_BYTE_MASK (3 << 4) #define SDHCI_FSL_PROT_CTRL_DMA_MASK (3 << 8) #define SDHCI_FSL_PROT_CTRL_VOLT_SEL (1 << 10) #define SDHCI_FSL_IRQSTAT 0x30 #define SDHCI_FSL_IRQSTAT_BRR (1 << 5) #define SDHCI_FSL_IRQSTAT_CINTSEN (1 << 8) #define SDHCI_FSL_IRQSTAT_RTE (1 << 12) #define SDHCI_FSL_IRQSTAT_TNE (1 << 26) #define SDHCI_FSL_SYS_CTRL 0x2c #define SDHCI_FSL_CLK_IPGEN (1 << 0) #define SDHCI_FSL_CLK_SDCLKEN (1 << 3) #define SDHCI_FSL_CLK_DIVIDER_MASK 0x000000f0 #define SDHCI_FSL_CLK_DIVIDER_SHIFT 4 #define SDHCI_FSL_CLK_PRESCALE_MASK 0x0000ff00 #define SDHCI_FSL_CLK_PRESCALE_SHIFT 8 #define SDHCI_FSL_WTMK_LVL 0x44 #define SDHCI_FSL_WTMK_RD_512B (0 << 0) #define SDHCI_FSL_WTMK_WR_512B (0 << 15) #define SDHCI_FSL_AUTOCERR 0x3C #define SDHCI_FSL_AUTOCERR_UHMS_HS200 (3 << 16) #define SDHCI_FSL_AUTOCERR_UHMS (7 << 16) #define SDHCI_FSL_AUTOCERR_EXTN (1 << 22) #define SDHCI_FSL_AUTOCERR_SMPCLKSEL (1 << 23) #define SDHCI_FSL_AUTOCERR_UHMS_SHIFT 16 #define SDHCI_FSL_HOST_VERSION 0xfc #define SDHCI_FSL_VENDOR_V23 0x13 #define SDHCI_FSL_CAPABILITIES2 0x114 #define SDHCI_FSL_TBCTL 0x120 #define SDHCI_FSL_TBSTAT 0x124 #define SDHCI_FSL_TBCTL_TBEN (1 << 2) #define SDHCI_FSL_TBCTL_HS400_EN (1 << 4) #define SDHCI_FSL_TBCTL_SAMP_CMD_DQS (1 << 5) #define SDHCI_FSL_TBCTL_HS400_WND_ADJ (1 << 6) #define SDHCI_FSL_TBCTL_TB_MODE_MASK 0x3 #define SDHCI_FSL_TBCTL_MODE_1 0 #define SDHCI_FSL_TBCTL_MODE_2 1 #define SDHCI_FSL_TBCTL_MODE_3 2 #define SDHCI_FSL_TBCTL_MODE_SW 3 #define SDHCI_FSL_TBPTR 0x128 #define SDHCI_FSL_TBPTR_WND_START_SHIFT 8 #define SDHCI_FSL_TBPTR_WND_MASK 0x7F #define SDHCI_FSL_SDCLKCTL 0x144 #define SDHCI_FSL_SDCLKCTL_CMD_CLK_CTL (1 << 15) #define SDHCI_FSL_SDCLKCTL_LPBK_CLK_SEL (1 << 31) #define SDHCI_FSL_SDTIMINGCTL 0x148 #define SDHCI_FSL_SDTIMINGCTL_FLW_CTL (1 << 15) #define SDHCI_FSL_DLLCFG0 0x160 #define SDHCI_FSL_DLLCFG0_FREQ_SEL (1 << 27) #define SDHCI_FSL_DLLCFG0_RESET (1 << 30) #define SDHCI_FSL_DLLCFG0_EN (1 << 31) #define SDHCI_FSL_DLLCFG1 0x164 #define SDHCI_FSL_DLLCFG1_PULSE_STRETCH (1 << 31) #define SDHCI_FSL_DLLSTAT0 0x170 #define SDHCI_FSL_DLLSTAT0_SLV_STS (1 << 27) #define SDHCI_FSL_ESDHC_CTRL 0x40c #define SDHCI_FSL_ESDHC_CTRL_SNOOP (1 << 6) #define SDHCI_FSL_ESDHC_CTRL_FAF (1 << 18) #define SDHCI_FSL_ESDHC_CTRL_CLK_DIV2 (1 << 19) #define SCFG_SDHCIOVSELCR 0x408 #define SCFG_SDHCIOVSELCR_TGLEN (1 << 0) #define SCFG_SDHCIOVSELCR_VS (1 << 31) #define SCFG_SDHCIOVSELCR_VSELVAL_MASK (3 << 1) #define SCFG_SDHCIOVSELCR_VSELVAL_1_8 0x0 #define SCFG_SDHCIOVSELCR_VSELVAL_3_3 0x2 #define SDHCI_FSL_CAN_VDD_MASK \ (SDHCI_CAN_VDD_180 | SDHCI_CAN_VDD_300 | SDHCI_CAN_VDD_330) /* Some platforms do not detect pulse width correctly. */ #define SDHCI_FSL_UNRELIABLE_PULSE_DET (1 << 0) /* On some platforms switching voltage to 1.8V is not supported */ #define SDHCI_FSL_UNSUPP_1_8V (1 << 1) /* Hardware tuning can fail, fallback to SW tuning in that case. */ #define SDHCI_FSL_TUNING_ERRATUM_TYPE1 (1 << 2) /* * Pointer window might not be set properly on some platforms. * Check window and perform SW tuning. */ #define SDHCI_FSL_TUNING_ERRATUM_TYPE2 (1 << 3) /* * In HS400 mode only 4, 8, 12 clock dividers can be used. * Use the smallest value, bigger than requested in that case. */ #define SDHCI_FSL_HS400_LIMITED_CLK_DIV (1 << 4) /* * Some SoCs don't have a fixed regulator. Switching voltage * requires special routine including syscon registers. */ #define SDHCI_FSL_MISSING_VCCQ_REG (1 << 5) /* * HS400 tuning is done in HS200 mode, but it has to be done using * the target frequency. In order to apply the errata above we need to * know the target mode during tuning procedure. Use this flag for just that. */ #define SDHCI_FSL_HS400_FLAG (1 << 0) #define SDHCI_FSL_MAX_RETRIES 20000 /* DELAY(10) * this = 200ms */ struct sdhci_fsl_fdt_softc { device_t dev; const struct sdhci_fsl_fdt_soc_data *soc_data; struct resource *mem_res; struct resource *irq_res; void *irq_cookie; uint32_t baseclk_hz; uint32_t maxclk_hz; struct sdhci_fdt_gpio *gpio; struct sdhci_slot slot; bool slot_init_done; uint32_t cmd_and_mode; uint16_t sdclk_bits; struct mmc_helper fdt_helper; uint32_t div_ratio; uint8_t vendor_ver; uint32_t flags; uint32_t (* read)(struct sdhci_fsl_fdt_softc *, bus_size_t); void (* write)(struct sdhci_fsl_fdt_softc *, bus_size_t, uint32_t); }; struct sdhci_fsl_fdt_soc_data { int quirks; int baseclk_div; uint8_t errata; char *syscon_compat; }; static const struct sdhci_fsl_fdt_soc_data sdhci_fsl_fdt_ls1012a_soc_data = { .quirks = 0, .baseclk_div = 1, .errata = SDHCI_FSL_MISSING_VCCQ_REG | SDHCI_FSL_TUNING_ERRATUM_TYPE2, .syscon_compat = "fsl,ls1012a-scfg", }; static const struct sdhci_fsl_fdt_soc_data sdhci_fsl_fdt_ls1028a_soc_data = { .quirks = SDHCI_QUIRK_DONT_SET_HISPD_BIT | SDHCI_QUIRK_BROKEN_AUTO_STOP | SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK, .baseclk_div = 2, .errata = SDHCI_FSL_UNRELIABLE_PULSE_DET | SDHCI_FSL_HS400_LIMITED_CLK_DIV, }; static const struct sdhci_fsl_fdt_soc_data sdhci_fsl_fdt_ls1046a_soc_data = { .quirks = SDHCI_QUIRK_DONT_SET_HISPD_BIT | SDHCI_QUIRK_BROKEN_AUTO_STOP, .baseclk_div = 2, .errata = SDHCI_FSL_MISSING_VCCQ_REG | SDHCI_FSL_TUNING_ERRATUM_TYPE2, .syscon_compat = "fsl,ls1046a-scfg", }; static const struct sdhci_fsl_fdt_soc_data sdhci_fsl_fdt_lx2160a_soc_data = { .quirks = 0, .baseclk_div = 2, .errata = SDHCI_FSL_UNRELIABLE_PULSE_DET | SDHCI_FSL_HS400_LIMITED_CLK_DIV, }; static const struct sdhci_fsl_fdt_soc_data sdhci_fsl_fdt_gen_data = { .quirks = 0, .baseclk_div = 1, }; static const struct ofw_compat_data sdhci_fsl_fdt_compat_data[] = { {"fsl,ls1012a-esdhc", (uintptr_t)&sdhci_fsl_fdt_ls1012a_soc_data}, {"fsl,ls1028a-esdhc", (uintptr_t)&sdhci_fsl_fdt_ls1028a_soc_data}, {"fsl,ls1046a-esdhc", (uintptr_t)&sdhci_fsl_fdt_ls1046a_soc_data}, {"fsl,esdhc", (uintptr_t)&sdhci_fsl_fdt_gen_data}, {NULL, 0} }; static uint32_t read_be(struct sdhci_fsl_fdt_softc *sc, bus_size_t off) { return (be32toh(bus_read_4(sc->mem_res, off))); } static void write_be(struct sdhci_fsl_fdt_softc *sc, bus_size_t off, uint32_t val) { bus_write_4(sc->mem_res, off, htobe32(val)); } static uint32_t read_le(struct sdhci_fsl_fdt_softc *sc, bus_size_t off) { return (bus_read_4(sc->mem_res, off)); } static void write_le(struct sdhci_fsl_fdt_softc *sc, bus_size_t off, uint32_t val) { bus_write_4(sc->mem_res, off, val); } static uint16_t sdhci_fsl_fdt_get_clock(struct sdhci_fsl_fdt_softc *sc) { uint16_t val; val = sc->sdclk_bits | SDHCI_CLOCK_INT_EN; if (RD4(sc, SDHCI_FSL_PRES_STATE) & SDHCI_FSL_PRES_SDSTB) val |= SDHCI_CLOCK_INT_STABLE; if (RD4(sc, SDHCI_FSL_SYS_CTRL) & SDHCI_FSL_CLK_SDCLKEN) val |= SDHCI_CLOCK_CARD_EN; return (val); } /* * Calculate clock prescaler and divisor values based on the following formula: * `frequency = base clock / (prescaler * divisor)`. */ #define SDHCI_FSL_FDT_CLK_DIV(sc, base, freq, pre, div) \ do { \ (pre) = (sc)->vendor_ver < SDHCI_FSL_VENDOR_V23 ? 2 : 1;\ while ((freq) < (base) / ((pre) * 16) && (pre) < 256) \ (pre) <<= 1; \ /* div/pre can't both be set to 1, according to PM. */ \ (div) = ((pre) == 1 ? 2 : 1); \ while ((freq) < (base) / ((pre) * (div)) && (div) < 16) \ ++(div); \ } while (0) static void fsl_sdhc_fdt_set_clock(struct sdhci_fsl_fdt_softc *sc, struct sdhci_slot *slot, uint16_t val) { uint32_t prescale, div, val32, div_ratio; sc->sdclk_bits = val & SDHCI_DIVIDERS_MASK; val32 = RD4(sc, SDHCI_CLOCK_CONTROL); if ((val & SDHCI_CLOCK_CARD_EN) == 0) { WR4(sc, SDHCI_CLOCK_CONTROL, val32 & ~SDHCI_FSL_CLK_SDCLKEN); return; } /* * Ignore dividers provided by core in `sdhci_set_clock` and calculate * them anew with higher accuracy. */ SDHCI_FSL_FDT_CLK_DIV(sc, sc->baseclk_hz, slot->clock, prescale, div); div_ratio = prescale * div; /* * According to limited clock division erratum, clock dividers in hs400 * can be only 4, 8 or 12 */ if ((sc->soc_data->errata & SDHCI_FSL_HS400_LIMITED_CLK_DIV) && (sc->slot.host.ios.timing == bus_timing_mmc_hs400 || (sc->flags & SDHCI_FSL_HS400_FLAG))) { if (div_ratio <= 4) { prescale = 4; div = 1; } else if (div_ratio <= 8) { prescale = 4; div = 2; } else if (div_ratio <= 12) { prescale = 4; div = 3; } else { device_printf(sc->dev, "Unsupported clock divider.\n"); } } sc->div_ratio = prescale * div; if (bootverbose) device_printf(sc->dev, "Desired SD/MMC freq: %d, actual: %d; base %d prescale %d divisor %d\n", slot->clock, sc->baseclk_hz / (prescale * div), sc->baseclk_hz, prescale, div); prescale >>= 1; div -= 1; val32 &= ~(SDHCI_FSL_CLK_DIVIDER_MASK | SDHCI_FSL_CLK_PRESCALE_MASK); val32 |= div << SDHCI_FSL_CLK_DIVIDER_SHIFT; val32 |= prescale << SDHCI_FSL_CLK_PRESCALE_SHIFT; val32 |= SDHCI_FSL_CLK_IPGEN | SDHCI_FSL_CLK_SDCLKEN; WR4(sc, SDHCI_CLOCK_CONTROL, val32); } static uint8_t sdhci_fsl_fdt_read_1(device_t dev, struct sdhci_slot *slot, bus_size_t off) { struct sdhci_fsl_fdt_softc *sc; uint32_t wrk32, val32; sc = device_get_softc(dev); switch (off) { case SDHCI_HOST_CONTROL: wrk32 = RD4(sc, SDHCI_FSL_PROT_CTRL); val32 = wrk32 & (SDHCI_CTRL_LED | SDHCI_CTRL_CARD_DET | SDHCI_CTRL_FORCE_CARD); if (wrk32 & SDHCI_FSL_PROT_CTRL_WIDTH_4BIT) val32 |= SDHCI_CTRL_4BITBUS; else if (wrk32 & SDHCI_FSL_PROT_CTRL_WIDTH_8BIT) val32 |= SDHCI_CTRL_8BITBUS; return (val32); case SDHCI_POWER_CONTROL: return (SDHCI_POWER_ON | SDHCI_POWER_300); default: break; } return ((RD4(sc, off & ~3) >> (off & 3) * 8) & UINT8_MAX); } static uint16_t sdhci_fsl_fdt_read_2(device_t dev, struct sdhci_slot *slot, bus_size_t off) { struct sdhci_fsl_fdt_softc *sc; uint32_t val32; sc = device_get_softc(dev); switch (off) { case SDHCI_CLOCK_CONTROL: return (sdhci_fsl_fdt_get_clock(sc)); case SDHCI_HOST_VERSION: return (RD4(sc, SDHCI_FSL_HOST_VERSION) & UINT16_MAX); case SDHCI_TRANSFER_MODE: return (sc->cmd_and_mode & UINT16_MAX); case SDHCI_COMMAND_FLAGS: return (sc->cmd_and_mode >> 16); case SDHCI_SLOT_INT_STATUS: /* * eSDHC hardware manages only a single slot. * Synthesize a slot interrupt status register for slot 1 below. */ val32 = RD4(sc, SDHCI_INT_STATUS); val32 &= RD4(sc, SDHCI_SIGNAL_ENABLE); return (!!val32); default: return ((RD4(sc, off & ~3) >> (off & 3) * 8) & UINT16_MAX); } } static uint32_t sdhci_fsl_fdt_read_4(device_t dev, struct sdhci_slot *slot, bus_size_t off) { struct sdhci_fsl_fdt_softc *sc; uint32_t wrk32, val32; sc = device_get_softc(dev); if (off == SDHCI_BUFFER) return (bus_read_4(sc->mem_res, off)); if (off == SDHCI_CAPABILITIES2) off = SDHCI_FSL_CAPABILITIES2; val32 = RD4(sc, off); if (off == SDHCI_PRESENT_STATE) { wrk32 = val32; val32 &= SDHCI_FSL_PRES_COMPAT_MASK; val32 |= (wrk32 >> 4) & SDHCI_STATE_DAT_MASK; val32 |= (wrk32 << 1) & SDHCI_STATE_CMD; } return (val32); } static void sdhci_fsl_fdt_read_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint32_t *data, bus_size_t count) { struct sdhci_fsl_fdt_softc *sc; sc = device_get_softc(dev); bus_read_multi_4(sc->mem_res, off, data, count); } static void sdhci_fsl_fdt_write_1(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint8_t val) { struct sdhci_fsl_fdt_softc *sc; uint32_t val32; sc = device_get_softc(dev); switch (off) { case SDHCI_HOST_CONTROL: val32 = RD4(sc, SDHCI_FSL_PROT_CTRL); val32 &= ~SDHCI_FSL_PROT_CTRL_WIDTH_MASK; val32 |= (val & SDHCI_CTRL_LED); if (val & SDHCI_CTRL_8BITBUS) val32 |= SDHCI_FSL_PROT_CTRL_WIDTH_8BIT; else /* Bus width is 1-bit when this flag is not set. */ val32 |= (val & SDHCI_CTRL_4BITBUS); /* Enable SDMA by masking out this field. */ val32 &= ~SDHCI_FSL_PROT_CTRL_DMA_MASK; val32 &= ~(SDHCI_CTRL_CARD_DET | SDHCI_CTRL_FORCE_CARD); val32 |= (val & (SDHCI_CTRL_CARD_DET | SDHCI_CTRL_FORCE_CARD)); WR4(sc, SDHCI_FSL_PROT_CTRL, val32); return; case SDHCI_POWER_CONTROL: return; default: val32 = RD4(sc, off & ~3); val32 &= ~(UINT8_MAX << (off & 3) * 8); val32 |= (val << (off & 3) * 8); WR4(sc, off & ~3, val32); return; } } static void sdhci_fsl_fdt_write_2(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint16_t val) { struct sdhci_fsl_fdt_softc *sc; uint32_t val32; sc = device_get_softc(dev); switch (off) { case SDHCI_CLOCK_CONTROL: fsl_sdhc_fdt_set_clock(sc, slot, val); return; /* * eSDHC hardware combines command and mode into a single * register. Cache it here, so that command isn't written * until after mode. */ case SDHCI_TRANSFER_MODE: sc->cmd_and_mode = val; return; case SDHCI_COMMAND_FLAGS: sc->cmd_and_mode = (sc->cmd_and_mode & UINT16_MAX) | (val << 16); WR4(sc, SDHCI_TRANSFER_MODE, sc->cmd_and_mode); sc->cmd_and_mode = 0; return; case SDHCI_HOST_CONTROL2: /* * Switching to HS400 requires a special procedure, * which is done in sdhci_fsl_fdt_set_uhs_timing. */ if ((val & SDHCI_CTRL2_UHS_MASK) == SDHCI_CTRL2_MMC_HS400) val &= ~SDHCI_CTRL2_MMC_HS400; default: val32 = RD4(sc, off & ~3); val32 &= ~(UINT16_MAX << (off & 3) * 8); val32 |= ((val & UINT16_MAX) << (off & 3) * 8); WR4(sc, off & ~3, val32); return; } } static void sdhci_fsl_fdt_write_4(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint32_t val) { struct sdhci_fsl_fdt_softc *sc; sc = device_get_softc(dev); switch (off) { case SDHCI_BUFFER: bus_write_4(sc->mem_res, off, val); return; /* * eSDHC hardware lacks support for the SDMA buffer boundary * feature and instead generates SDHCI_INT_DMA_END interrupts * after each completed DMA data transfer. * Since this duplicates the SDHCI_INT_DATA_END functionality, * mask out the unneeded SDHCI_INT_DMA_END interrupt. */ case SDHCI_INT_ENABLE: case SDHCI_SIGNAL_ENABLE: val &= ~SDHCI_INT_DMA_END; /* FALLTHROUGH. */ default: WR4(sc, off, val); return; } } static void sdhci_fsl_fdt_write_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint32_t *data, bus_size_t count) { struct sdhci_fsl_fdt_softc *sc; sc = device_get_softc(dev); bus_write_multi_4(sc->mem_res, off, data, count); } static void sdhci_fsl_fdt_irq(void *arg) { struct sdhci_fsl_fdt_softc *sc; sc = arg; sdhci_generic_intr(&sc->slot); return; } static int sdhci_fsl_fdt_update_ios(device_t brdev, device_t reqdev) { int err; struct sdhci_fsl_fdt_softc *sc; struct mmc_ios *ios; struct sdhci_slot *slot; err = sdhci_generic_update_ios(brdev, reqdev); if (err != 0) return (err); sc = device_get_softc(brdev); slot = device_get_ivars(reqdev); ios = &slot->host.ios; switch (ios->power_mode) { case power_on: break; case power_off: if (bootverbose) device_printf(sc->dev, "Powering down sd/mmc\n"); if (sc->fdt_helper.vmmc_supply) regulator_disable(sc->fdt_helper.vmmc_supply); if (sc->fdt_helper.vqmmc_supply) regulator_disable(sc->fdt_helper.vqmmc_supply); break; case power_up: if (bootverbose) device_printf(sc->dev, "Powering up sd/mmc\n"); if (sc->fdt_helper.vmmc_supply) regulator_enable(sc->fdt_helper.vmmc_supply); if (sc->fdt_helper.vqmmc_supply) regulator_enable(sc->fdt_helper.vqmmc_supply); break; }; return (0); } static int sdhci_fsl_fdt_switch_syscon_voltage(device_t dev, struct sdhci_fsl_fdt_softc *sc, enum mmc_vccq vccq) { struct syscon *syscon; phandle_t syscon_node; uint32_t reg; if (sc->soc_data->syscon_compat == NULL) { device_printf(dev, "Empty syscon compat string.\n"); return (ENXIO); } syscon_node = ofw_bus_find_compatible(OF_finddevice("/"), sc->soc_data->syscon_compat); if (syscon_get_by_ofw_node(dev, syscon_node, &syscon) != 0) { device_printf(dev, "Could not find syscon node.\n"); return (ENXIO); } reg = SYSCON_READ_4(syscon, SCFG_SDHCIOVSELCR); reg &= ~SCFG_SDHCIOVSELCR_VSELVAL_MASK; reg |= SCFG_SDHCIOVSELCR_TGLEN; switch (vccq) { case vccq_180: reg |= SCFG_SDHCIOVSELCR_VSELVAL_1_8; SYSCON_WRITE_4(syscon, SCFG_SDHCIOVSELCR, reg); DELAY(5000); reg = SYSCON_READ_4(syscon, SCFG_SDHCIOVSELCR); reg |= SCFG_SDHCIOVSELCR_VS; break; case vccq_330: reg |= SCFG_SDHCIOVSELCR_VSELVAL_3_3; SYSCON_WRITE_4(syscon, SCFG_SDHCIOVSELCR, reg); DELAY(5000); reg = SYSCON_READ_4(syscon, SCFG_SDHCIOVSELCR); reg &= ~SCFG_SDHCIOVSELCR_VS; break; default: device_printf(dev, "Unsupported voltage requested.\n"); return (ENXIO); } SYSCON_WRITE_4(syscon, SCFG_SDHCIOVSELCR, reg); return (0); } static int sdhci_fsl_fdt_switch_vccq(device_t brdev, device_t reqdev) { struct sdhci_fsl_fdt_softc *sc; struct sdhci_slot *slot; regulator_t vqmmc_supply; uint32_t val_old, val; int uvolt, err = 0; sc = device_get_softc(brdev); slot = device_get_ivars(reqdev); val_old = val = RD4(sc, SDHCI_FSL_PROT_CTRL); switch (slot->host.ios.vccq) { case vccq_180: if (sc->soc_data->errata & SDHCI_FSL_UNSUPP_1_8V) return (EOPNOTSUPP); val |= SDHCI_FSL_PROT_CTRL_VOLT_SEL; uvolt = 1800000; break; case vccq_330: val &= ~SDHCI_FSL_PROT_CTRL_VOLT_SEL; uvolt = 3300000; break; default: return (EOPNOTSUPP); } WR4(sc, SDHCI_FSL_PROT_CTRL, val); if (sc->soc_data->errata & SDHCI_FSL_MISSING_VCCQ_REG) { err = sdhci_fsl_fdt_switch_syscon_voltage(brdev, sc, slot->host.ios.vccq); if (err != 0) goto vccq_fail; } vqmmc_supply = sc->fdt_helper.vqmmc_supply; /* * Even though we expect to find a fixed regulator in this controller * family, let's play safe. */ if (vqmmc_supply != NULL) { err = regulator_set_voltage(vqmmc_supply, uvolt, uvolt); if (err != 0) goto vccq_fail; } return (0); vccq_fail: device_printf(sc->dev, "Cannot set vqmmc to %d<->%d\n", uvolt, uvolt); WR4(sc, SDHCI_FSL_PROT_CTRL, val_old); return (err); } static int sdhci_fsl_fdt_get_ro(device_t bus, device_t child) { struct sdhci_fsl_fdt_softc *sc; sc = device_get_softc(bus); return (sdhci_fdt_gpio_get_readonly(sc->gpio)); } static bool sdhci_fsl_fdt_get_card_present(device_t dev, struct sdhci_slot *slot) { struct sdhci_fsl_fdt_softc *sc; sc = device_get_softc(dev); return (sdhci_fdt_gpio_get_present(sc->gpio)); } static uint32_t sdhci_fsl_fdt_vddrange_to_mask(device_t dev, uint32_t *vdd_ranges, int len) { uint32_t vdd_min, vdd_max; uint32_t vdd_mask = 0; int i; /* Ranges are organized as pairs of values. */ if ((len % 2) != 0) { device_printf(dev, "Invalid voltage range\n"); return (0); } len = len / 2; for (i = 0; i < len; i++) { vdd_min = vdd_ranges[2 * i]; vdd_max = vdd_ranges[2 * i + 1]; if (vdd_min > vdd_max || vdd_min < 1650 || vdd_min > 3600 || vdd_max < 1650 || vdd_max > 3600) { device_printf(dev, "Voltage range %d - %d is out of bounds\n", vdd_min, vdd_max); return (0); } if (vdd_min <= 1800 && vdd_max >= 1800) vdd_mask |= SDHCI_CAN_VDD_180; if (vdd_min <= 3000 && vdd_max >= 3000) vdd_mask |= SDHCI_CAN_VDD_300; if (vdd_min <= 3300 && vdd_max >= 3300) vdd_mask |= SDHCI_CAN_VDD_330; } return (vdd_mask); } static void sdhci_fsl_fdt_of_parse(device_t dev) { struct sdhci_fsl_fdt_softc *sc; phandle_t node; pcell_t *voltage_ranges; uint32_t vdd_mask = 0; ssize_t num_ranges; sc = device_get_softc(dev); node = ofw_bus_get_node(dev); /* Call mmc_fdt_parse in order to get mmc related properties. */ mmc_fdt_parse(dev, node, &sc->fdt_helper, &sc->slot.host); sc->slot.caps = sdhci_fsl_fdt_read_4(dev, &sc->slot, SDHCI_CAPABILITIES) & ~(SDHCI_CAN_DO_SUSPEND); sc->slot.caps2 = sdhci_fsl_fdt_read_4(dev, &sc->slot, SDHCI_CAPABILITIES2); /* Parse the "voltage-ranges" dts property. */ num_ranges = OF_getencprop_alloc(node, "voltage-ranges", (void **) &voltage_ranges); if (num_ranges <= 0) return; vdd_mask = sdhci_fsl_fdt_vddrange_to_mask(dev, voltage_ranges, num_ranges / sizeof(uint32_t)); OF_prop_free(voltage_ranges); /* Overwrite voltage caps only if we got something from dts. */ if (vdd_mask != 0 && (vdd_mask != (sc->slot.caps & SDHCI_FSL_CAN_VDD_MASK))) { sc->slot.caps &= ~(SDHCI_FSL_CAN_VDD_MASK); sc->slot.caps |= vdd_mask; sc->slot.quirks |= SDHCI_QUIRK_MISSING_CAPS; } } static int sdhci_fsl_poll_register(struct sdhci_fsl_fdt_softc *sc, uint32_t reg, uint32_t mask, int value) { int retries; retries = SDHCI_FSL_MAX_RETRIES; while ((RD4(sc, reg) & mask) != value) { if (!retries--) return (ENXIO); DELAY(10); } return (0); } static int sdhci_fsl_fdt_attach(device_t dev) { struct sdhci_fsl_fdt_softc *sc; struct mmc_host *host; uint32_t val, buf_order; uintptr_t ocd_data; uint64_t clk_hz; phandle_t node; int rid, ret; clk_t clk; node = ofw_bus_get_node(dev); sc = device_get_softc(dev); ocd_data = ofw_bus_search_compatible(dev, sdhci_fsl_fdt_compat_data)->ocd_data; sc->dev = dev; sc->flags = 0; host = &sc->slot.host; rid = 0; /* * LX2160A needs its own soc_data in order to apply SoC * specific quriks. Since the controller is identified * only with a generic compatible string we need to do this dance here. */ if (ofw_bus_node_is_compatible(OF_finddevice("/"), "fsl,lx2160a")) sc->soc_data = &sdhci_fsl_fdt_lx2160a_soc_data; else sc->soc_data = (struct sdhci_fsl_fdt_soc_data *)ocd_data; sc->slot.quirks = sc->soc_data->quirks; sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (sc->mem_res == NULL) { device_printf(dev, "Could not allocate resources for controller\n"); return (ENOMEM); } rid = 0; sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); if (sc->irq_res == NULL) { device_printf(dev, "Could not allocate irq resources for controller\n"); ret = ENOMEM; goto err_free_mem; } ret = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_BIO | INTR_MPSAFE, NULL, sdhci_fsl_fdt_irq, sc, &sc->irq_cookie); if (ret != 0) { device_printf(dev, "Could not setup IRQ handler\n"); goto err_free_irq_res; } ret = clk_get_by_ofw_index(dev, node, 0, &clk); if (ret != 0) { device_printf(dev, "Parent clock not found\n"); goto err_free_irq; } ret = clk_get_freq(clk, &clk_hz); if (ret != 0) { device_printf(dev, "Could not get parent clock frequency\n"); goto err_free_irq; } sc->baseclk_hz = clk_hz / sc->soc_data->baseclk_div; /* Figure out eSDHC block endianness before we touch any HW regs. */ if (OF_hasprop(node, "little-endian")) { sc->read = read_le; sc->write = write_le; buf_order = SDHCI_FSL_PROT_CTRL_BYTE_NATIVE; } else { sc->read = read_be; sc->write = write_be; buf_order = SDHCI_FSL_PROT_CTRL_BYTE_SWAP; } sc->vendor_ver = (RD4(sc, SDHCI_FSL_HOST_VERSION) & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT; sdhci_fsl_fdt_of_parse(dev); sc->maxclk_hz = host->f_max ? host->f_max : sc->baseclk_hz; /* * Setting this register affects byte order in SDHCI_BUFFER only. * If the eSDHC block is connected over a big-endian bus, the data * read from/written to the buffer will be already byte swapped. * In such a case, setting SDHCI_FSL_PROT_CTRL_BYTE_SWAP will convert * the byte order again, resulting in a native byte order. * The read/write callbacks accommodate for this behavior. */ val = RD4(sc, SDHCI_FSL_PROT_CTRL); val &= ~SDHCI_FSL_PROT_CTRL_BYTE_MASK; WR4(sc, SDHCI_FSL_PROT_CTRL, val | buf_order); /* * Gate the SD clock and set its source to * peripheral clock / baseclk_div. The frequency in baseclk_hz is set * to match this. */ val = RD4(sc, SDHCI_CLOCK_CONTROL); WR4(sc, SDHCI_CLOCK_CONTROL, val & ~SDHCI_FSL_CLK_SDCLKEN); val = RD4(sc, SDHCI_FSL_ESDHC_CTRL); WR4(sc, SDHCI_FSL_ESDHC_CTRL, val | SDHCI_FSL_ESDHC_CTRL_CLK_DIV2); sc->slot.max_clk = sc->maxclk_hz; sc->gpio = sdhci_fdt_gpio_setup(dev, &sc->slot); /* * Set the buffer watermark level to 128 words (512 bytes) for both * read and write. The hardware has a restriction that when the read or * write ready status is asserted, that means you can read exactly the * number of words set in the watermark register before you have to * re-check the status and potentially wait for more data. The main * sdhci driver provides no hook for doing status checking on less than * a full block boundary, so we set the watermark level to be a full * block. Reads and writes where the block size is less than the * watermark size will work correctly too, no need to change the * watermark for different size blocks. However, 128 is the maximum * allowed for the watermark, so PIO is limitted to 512 byte blocks. */ WR4(sc, SDHCI_FSL_WTMK_LVL, SDHCI_FSL_WTMK_WR_512B | SDHCI_FSL_WTMK_RD_512B); ret = sdhci_init_slot(dev, &sc->slot, 0); if (ret != 0) goto err_free_gpio; sc->slot_init_done = true; sdhci_start_slot(&sc->slot); return (bus_generic_attach(dev)); err_free_gpio: sdhci_fdt_gpio_teardown(sc->gpio); err_free_irq: bus_teardown_intr(dev, sc->irq_res, sc->irq_cookie); err_free_irq_res: bus_free_resource(dev, SYS_RES_IRQ, sc->irq_res); err_free_mem: bus_free_resource(dev, SYS_RES_MEMORY, sc->mem_res); return (ret); } static int sdhci_fsl_fdt_detach(device_t dev) { struct sdhci_fsl_fdt_softc *sc; sc = device_get_softc(dev); if (sc->slot_init_done) sdhci_cleanup_slot(&sc->slot); if (sc->gpio != NULL) sdhci_fdt_gpio_teardown(sc->gpio); if (sc->irq_cookie != NULL) bus_teardown_intr(dev, sc->irq_res, sc->irq_cookie); if (sc->irq_res != NULL) bus_free_resource(dev, SYS_RES_IRQ, sc->irq_res); if (sc->mem_res != NULL) bus_free_resource(dev, SYS_RES_MEMORY, sc->mem_res); return (0); } static int sdhci_fsl_fdt_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (!ofw_bus_search_compatible(dev, sdhci_fsl_fdt_compat_data)->ocd_data) return (ENXIO); device_set_desc(dev, "NXP QorIQ Layerscape eSDHC controller"); return (BUS_PROBE_DEFAULT); } static int sdhci_fsl_fdt_read_ivar(device_t bus, device_t child, int which, uintptr_t *result) { struct sdhci_slot *slot = device_get_ivars(child); if (which == MMCBR_IVAR_MAX_DATA && (slot->opt & SDHCI_HAVE_DMA)) { /* * In the absence of SDMA buffer boundary functionality, * limit the maximum data length per read/write command * to bounce buffer size. */ *result = howmany(slot->sdma_bbufsz, 512); return (0); } return (sdhci_generic_read_ivar(bus, child, which, result)); } static int sdhci_fsl_fdt_write_ivar(device_t bus, device_t child, int which, uintptr_t value) { struct sdhci_fsl_fdt_softc *sc; struct sdhci_slot *slot = device_get_ivars(child); uint32_t prescale, div; /* Don't depend on clock resolution limits from sdhci core. */ if (which == MMCBR_IVAR_CLOCK) { if (value == 0) { slot->host.ios.clock = 0; return (0); } sc = device_get_softc(bus); SDHCI_FSL_FDT_CLK_DIV(sc, sc->baseclk_hz, value, prescale, div); slot->host.ios.clock = sc->baseclk_hz / (prescale * div); return (0); } return (sdhci_generic_write_ivar(bus, child, which, value)); } static void sdhci_fsl_fdt_reset(device_t dev, struct sdhci_slot *slot, uint8_t mask) { struct sdhci_fsl_fdt_softc *sc; uint32_t val; sdhci_generic_reset(dev, slot, mask); if (!(mask & SDHCI_RESET_ALL)) return; sc = device_get_softc(dev); /* Some registers have to be cleared by hand. */ if (slot->version >= SDHCI_SPEC_300) { val = RD4(sc, SDHCI_FSL_TBCTL); val &= ~SDHCI_FSL_TBCTL_TBEN; WR4(sc, SDHCI_FSL_TBCTL, val); } /* * Pulse width detection is not reliable on some boards. Perform * workaround by clearing register's bit according to errata. */ if (sc->soc_data->errata & SDHCI_FSL_UNRELIABLE_PULSE_DET) { val = RD4(sc, SDHCI_FSL_DLLCFG1); val &= ~SDHCI_FSL_DLLCFG1_PULSE_STRETCH; WR4(sc, SDHCI_FSL_DLLCFG1, val); } sc->flags = 0; } static void sdhci_fsl_switch_tuning_block(device_t dev, bool enable) { struct sdhci_fsl_fdt_softc *sc; uint32_t reg; sc = device_get_softc(dev); reg = RD4(sc, SDHCI_FSL_TBCTL); if (enable) reg |= SDHCI_FSL_TBCTL_TBEN; else reg &= ~SDHCI_FSL_TBCTL_TBEN; WR4(sc, SDHCI_FSL_TBCTL, reg); } static int sdhci_fsl_sw_tuning(struct sdhci_fsl_fdt_softc *sc, device_t bus, device_t child, bool hs400, uint32_t wnd_start, uint32_t wnd_end) { uint32_t reg; int error; if (sc->soc_data->errata & SDHCI_FSL_TUNING_ERRATUM_TYPE1 || abs(wnd_start - wnd_end) <= (4 * sc->div_ratio + 2)) { wnd_start = 5 * sc->div_ratio; wnd_end = 3 * sc->div_ratio; } else { wnd_start = 8 * sc->div_ratio; wnd_end = 4 * sc->div_ratio; } reg = RD4(sc, SDHCI_FSL_TBPTR); reg &= ~SDHCI_FSL_TBPTR_WND_MASK; reg &= ~(SDHCI_FSL_TBPTR_WND_MASK << SDHCI_FSL_TBPTR_WND_START_SHIFT); reg |= wnd_start << SDHCI_FSL_TBPTR_WND_START_SHIFT; reg |= wnd_end; WR4(sc, SDHCI_FSL_TBPTR, reg); /* * Normally those are supposed to be set in sdhci_execute_tuning. * However in our case we need a small delay between setting the two. */ reg = RD4(sc, SDHCI_FSL_AUTOCERR); reg |= SDHCI_FSL_AUTOCERR_EXTN; WR4(sc, SDHCI_FSL_AUTOCERR, reg); DELAY(10); reg |= SDHCI_FSL_AUTOCERR_SMPCLKSEL; WR4(sc, SDHCI_FSL_AUTOCERR, reg); reg = RD4(sc, SDHCI_FSL_TBCTL); reg &= ~SDHCI_FSL_TBCTL_TB_MODE_MASK; reg |= SDHCI_FSL_TBCTL_MODE_SW; WR4(sc, SDHCI_FSL_TBCTL, reg); error = sdhci_generic_tune(bus, child, hs400); if (error != 0) { device_printf(bus, "Failed to execute generic tune while performing software tuning.\n"); } return (error); } static int sdhci_fsl_fdt_tune(device_t bus, device_t child, bool hs400) { struct sdhci_fsl_fdt_softc *sc; uint32_t wnd_start, wnd_end; uint32_t clk_divider, reg; struct sdhci_slot *slot; int error; sc = device_get_softc(bus); slot = device_get_ivars(child); if (sc->slot.host.ios.timing == bus_timing_uhs_sdr50 && !(slot->opt & SDHCI_SDR50_NEEDS_TUNING)) return (0); /* * For tuning mode SD clock divider must be within 3 to 16. * We also need to match the frequency to whatever mode is used. * For that reason we're just bailing if the dividers don't match * that requirement. */ clk_divider = sc->baseclk_hz / slot->clock; if (clk_divider < 3 || clk_divider > 16) return (ENXIO); if (hs400) sc->flags |= SDHCI_FSL_HS400_FLAG; /* Disable clock. */ fsl_sdhc_fdt_set_clock(sc, slot, sc->sdclk_bits); /* Wait for PRSSTAT[SDSTB] to be set by hardware. */ error = sdhci_fsl_poll_register(sc, SDHCI_FSL_PRES_STATE, SDHCI_FSL_PRES_SDSTB, SDHCI_FSL_PRES_SDSTB); if (error != 0) device_printf(bus, "Timeout while waiting for clock to stabilize.\n"); /* Flush async IO. */ reg = RD4(sc, SDHCI_FSL_ESDHC_CTRL); reg |= SDHCI_FSL_ESDHC_CTRL_FAF; WR4(sc, SDHCI_FSL_ESDHC_CTRL, reg); /* Wait for ESDHC[FAF] to be cleared by hardware. */ error = sdhci_fsl_poll_register(sc, SDHCI_FSL_ESDHC_CTRL, SDHCI_FSL_ESDHC_CTRL_FAF, 0); if (error) device_printf(bus, "Timeout while waiting for hardware.\n"); /* * Set TBCTL[TB_EN] register and program valid tuning mode. * According to RM MODE_3 means that: * "eSDHC takes care of the re-tuning during data transfer * (auto re-tuning).". * Tuning mode can only be changed while the clock is disabled. */ reg = RD4(sc, SDHCI_FSL_TBCTL); reg &= ~SDHCI_FSL_TBCTL_TB_MODE_MASK; reg |= SDHCI_FSL_TBCTL_TBEN | SDHCI_FSL_TBCTL_MODE_3; WR4(sc, SDHCI_FSL_TBCTL, reg); /* Enable clock. */ fsl_sdhc_fdt_set_clock(sc, slot, SDHCI_CLOCK_CARD_EN | sc->sdclk_bits); /* Wait for clock to stabilize. */ error = sdhci_fsl_poll_register(sc, SDHCI_FSL_PRES_STATE, SDHCI_FSL_PRES_SDSTB, SDHCI_FSL_PRES_SDSTB); if (error) device_printf(bus, "Timeout while waiting for clock to stabilize.\n"); /* Perform hardware tuning. */ error = sdhci_generic_tune(bus, child, hs400); reg = RD4(sc, SDHCI_FSL_TBPTR); wnd_start = reg >> SDHCI_FSL_TBPTR_WND_START_SHIFT; wnd_start &= SDHCI_FSL_TBPTR_WND_MASK; wnd_end = reg & SDHCI_FSL_TBPTR_WND_MASK; /* * For erratum type2 affected platforms, the controller can erroneously * declare that the tuning was successful. Verify the tuning window to * make sure that we're fine. */ if (error == 0 && sc->soc_data->errata & SDHCI_FSL_TUNING_ERRATUM_TYPE2 && abs(wnd_start - wnd_end) > (4 * sc->div_ratio + 2)) { error = EIO; } /* If hardware tuning failed, try software tuning. */ if (error != 0 && (sc->soc_data->errata & (SDHCI_FSL_TUNING_ERRATUM_TYPE1 | SDHCI_FSL_TUNING_ERRATUM_TYPE2))) { error = sdhci_fsl_sw_tuning(sc, bus, child, hs400, wnd_start, wnd_end); if (error != 0) device_printf(bus, "Software tuning failed.\n"); } if (error != 0) { sdhci_fsl_switch_tuning_block(bus, false); return (error); } if (hs400) { reg = RD4(sc, SDHCI_FSL_SDTIMINGCTL); reg |= SDHCI_FSL_SDTIMINGCTL_FLW_CTL; WR4(sc, SDHCI_FSL_SDTIMINGCTL, reg); } return (0); } static int sdhci_fsl_fdt_retune(device_t bus, device_t child, bool reset) { struct sdhci_slot *slot; struct sdhci_fsl_fdt_softc *sc; slot = device_get_ivars(child); sc = device_get_softc(bus); if (!(slot->opt & SDHCI_TUNING_ENABLED)) return (0); /* HS400 must be tuned in HS200 mode. */ if (slot->host.ios.timing == bus_timing_mmc_hs400) return (EINVAL); /* * Only re-tuning with full reset is supported. * The controller is normally put in "mode 3", which means that * periodic re-tuning is done automatically. See comment in * sdhci_fsl_fdt_tune for details. * Because of that re-tuning should only be triggered as a result * of a CRC error. */ if (!reset) return (ENOTSUP); return (sdhci_fsl_fdt_tune(bus, child, sc->flags & SDHCI_FSL_HS400_FLAG)); } static void sdhci_fsl_disable_hs400_mode(device_t dev, struct sdhci_fsl_fdt_softc *sc) { uint32_t reg; int error; /* Check if HS400 is enabled right now. */ reg = RD4(sc, SDHCI_FSL_TBCTL); if ((reg & SDHCI_FSL_TBCTL_HS400_EN) == 0) return; reg = RD4(sc, SDHCI_FSL_SDTIMINGCTL); reg &= ~SDHCI_FSL_SDTIMINGCTL_FLW_CTL; WR4(sc, SDHCI_FSL_SDTIMINGCTL, reg); reg = RD4(sc, SDHCI_FSL_SDCLKCTL); reg &= ~SDHCI_FSL_SDCLKCTL_CMD_CLK_CTL; WR4(sc, SDHCI_FSL_SDCLKCTL, reg); fsl_sdhc_fdt_set_clock(sc, &sc->slot, sc->sdclk_bits); error = sdhci_fsl_poll_register(sc, SDHCI_FSL_PRES_STATE, SDHCI_FSL_PRES_SDSTB, SDHCI_FSL_PRES_SDSTB); if (error != 0) device_printf(dev, "Internal clock never stabilized.\n"); reg = RD4(sc, SDHCI_FSL_TBCTL); reg &= ~SDHCI_FSL_TBCTL_HS400_EN; WR4(sc, SDHCI_FSL_TBCTL, reg); fsl_sdhc_fdt_set_clock(sc, &sc->slot, SDHCI_CLOCK_CARD_EN | sc->sdclk_bits); error = sdhci_fsl_poll_register(sc, SDHCI_FSL_PRES_STATE, SDHCI_FSL_PRES_SDSTB, SDHCI_FSL_PRES_SDSTB); if (error != 0) device_printf(dev, "Internal clock never stabilized.\n"); reg = RD4(sc, SDHCI_FSL_DLLCFG0); reg &= ~(SDHCI_FSL_DLLCFG0_EN | SDHCI_FSL_DLLCFG0_FREQ_SEL); WR4(sc, SDHCI_FSL_DLLCFG0, reg); reg = RD4(sc, SDHCI_FSL_TBCTL); reg &= ~SDHCI_FSL_TBCTL_HS400_WND_ADJ; WR4(sc, SDHCI_FSL_TBCTL, reg); sdhci_fsl_switch_tuning_block(dev, false); } static void sdhci_fsl_enable_hs400_mode(device_t dev, struct sdhci_slot *slot, struct sdhci_fsl_fdt_softc *sc) { uint32_t reg; int error; sdhci_fsl_switch_tuning_block(dev, true); fsl_sdhc_fdt_set_clock(sc, slot, sc->sdclk_bits); error = sdhci_fsl_poll_register(sc, SDHCI_FSL_PRES_STATE, SDHCI_FSL_PRES_SDSTB, SDHCI_FSL_PRES_SDSTB); if (error != 0) device_printf(dev, "Timeout while waiting for clock to stabilize.\n"); reg = RD4(sc, SDHCI_FSL_TBCTL); reg |= SDHCI_FSL_TBCTL_HS400_EN; WR4(sc, SDHCI_FSL_TBCTL, reg); reg = RD4(sc, SDHCI_FSL_SDCLKCTL); reg |= SDHCI_FSL_SDCLKCTL_CMD_CLK_CTL; WR4(sc, SDHCI_FSL_SDCLKCTL, reg); fsl_sdhc_fdt_set_clock(sc, slot, SDHCI_CLOCK_CARD_EN | sc->sdclk_bits); error = sdhci_fsl_poll_register(sc, SDHCI_FSL_PRES_STATE, SDHCI_FSL_PRES_SDSTB, SDHCI_FSL_PRES_SDSTB); if (error != 0) device_printf(dev, "Timeout while waiting for clock to stabilize.\n"); reg = RD4(sc, SDHCI_FSL_DLLCFG0); reg |= SDHCI_FSL_DLLCFG0_EN | SDHCI_FSL_DLLCFG0_RESET | SDHCI_FSL_DLLCFG0_FREQ_SEL; WR4(sc, SDHCI_FSL_DLLCFG0, reg); /* * The reset bit is not a self clearing one. * Give it some time and clear it manually. */ DELAY(100); reg &= ~SDHCI_FSL_DLLCFG0_RESET; WR4(sc, SDHCI_FSL_DLLCFG0, reg); error = sdhci_fsl_poll_register(sc, SDHCI_FSL_DLLSTAT0, SDHCI_FSL_DLLSTAT0_SLV_STS, SDHCI_FSL_DLLSTAT0_SLV_STS); if (error != 0) device_printf(dev, "Timeout while waiting for DLL0.\n"); reg = RD4(sc, SDHCI_FSL_TBCTL); reg |= SDHCI_FSL_TBCTL_HS400_WND_ADJ; WR4(sc, SDHCI_FSL_TBCTL, reg); fsl_sdhc_fdt_set_clock(sc, slot, sc->sdclk_bits); error = sdhci_fsl_poll_register(sc, SDHCI_FSL_PRES_STATE, SDHCI_FSL_PRES_SDSTB, SDHCI_FSL_PRES_SDSTB); if (error != 0) device_printf(dev, "timeout while waiting for clock to stabilize.\n"); reg = RD4(sc, SDHCI_FSL_ESDHC_CTRL); reg |= SDHCI_FSL_ESDHC_CTRL_FAF; WR4(sc, SDHCI_FSL_ESDHC_CTRL, reg); error = sdhci_fsl_poll_register(sc, SDHCI_FSL_ESDHC_CTRL, SDHCI_FSL_ESDHC_CTRL_FAF, 0); if (error != 0) device_printf(dev, "Timeout while waiting for hardware.\n"); fsl_sdhc_fdt_set_clock(sc, slot, SDHCI_CLOCK_CARD_EN | sc->sdclk_bits); error = sdhci_fsl_poll_register(sc, SDHCI_FSL_PRES_STATE, SDHCI_FSL_PRES_SDSTB, SDHCI_FSL_PRES_SDSTB); if (error != 0) device_printf(dev, "Timeout while waiting for clock to stabilize.\n"); } static void sdhci_fsl_fdt_set_uhs_timing(device_t dev, struct sdhci_slot *slot) { struct sdhci_fsl_fdt_softc *sc; const struct mmc_ios *ios; uint32_t mode, reg; sc = device_get_softc(dev); ios = &slot->host.ios; mode = 0; /* * When we switch to HS400 this function is called twice. * First after the timing is set, and then after the clock * is changed to the target frequency. * The controller can be switched to HS400 only after the latter * is done. */ if (slot->host.ios.timing == bus_timing_mmc_hs400 && ios->clock > SD_SDR50_MAX) sdhci_fsl_enable_hs400_mode(dev, slot, sc); else if (slot->host.ios.timing < bus_timing_mmc_hs400) { sdhci_fsl_disable_hs400_mode(dev, sc); /* * Switching to HS400 requires a custom procedure executed in * sdhci_fsl_enable_hs400_mode in case above. * For all other modes we just need to set the corresponding flag. */ reg = RD4(sc, SDHCI_FSL_AUTOCERR); reg &= ~SDHCI_FSL_AUTOCERR_UHMS; if (ios->clock > SD_SDR50_MAX) mode = SDHCI_CTRL2_UHS_SDR104; else if (ios->clock > SD_SDR25_MAX) mode = SDHCI_CTRL2_UHS_SDR50; else if (ios->clock > SD_SDR12_MAX) { if (ios->timing == bus_timing_uhs_ddr50 || ios->timing == bus_timing_mmc_ddr52) mode = SDHCI_CTRL2_UHS_DDR50; else mode = SDHCI_CTRL2_UHS_SDR25; } else if (ios->clock > SD_MMC_CARD_ID_FREQUENCY) mode = SDHCI_CTRL2_UHS_SDR12; reg |= mode << SDHCI_FSL_AUTOCERR_UHMS_SHIFT; WR4(sc, SDHCI_FSL_AUTOCERR, reg); } } static const device_method_t sdhci_fsl_fdt_methods[] = { /* Device interface. */ DEVMETHOD(device_probe, sdhci_fsl_fdt_probe), DEVMETHOD(device_attach, sdhci_fsl_fdt_attach), DEVMETHOD(device_detach, sdhci_fsl_fdt_detach), /* Bus interface. */ DEVMETHOD(bus_read_ivar, sdhci_fsl_fdt_read_ivar), DEVMETHOD(bus_write_ivar, sdhci_fsl_fdt_write_ivar), /* MMC bridge interface. */ DEVMETHOD(mmcbr_request, sdhci_generic_request), DEVMETHOD(mmcbr_get_ro, sdhci_fsl_fdt_get_ro), DEVMETHOD(mmcbr_acquire_host, sdhci_generic_acquire_host), DEVMETHOD(mmcbr_release_host, sdhci_generic_release_host), DEVMETHOD(mmcbr_switch_vccq, sdhci_fsl_fdt_switch_vccq), DEVMETHOD(mmcbr_update_ios, sdhci_fsl_fdt_update_ios), DEVMETHOD(mmcbr_tune, sdhci_fsl_fdt_tune), DEVMETHOD(mmcbr_retune, sdhci_fsl_fdt_retune), /* SDHCI accessors. */ DEVMETHOD(sdhci_read_1, sdhci_fsl_fdt_read_1), DEVMETHOD(sdhci_read_2, sdhci_fsl_fdt_read_2), DEVMETHOD(sdhci_read_4, sdhci_fsl_fdt_read_4), DEVMETHOD(sdhci_read_multi_4, sdhci_fsl_fdt_read_multi_4), DEVMETHOD(sdhci_write_1, sdhci_fsl_fdt_write_1), DEVMETHOD(sdhci_write_2, sdhci_fsl_fdt_write_2), DEVMETHOD(sdhci_write_4, sdhci_fsl_fdt_write_4), DEVMETHOD(sdhci_write_multi_4, sdhci_fsl_fdt_write_multi_4), DEVMETHOD(sdhci_get_card_present, sdhci_fsl_fdt_get_card_present), DEVMETHOD(sdhci_reset, sdhci_fsl_fdt_reset), DEVMETHOD(sdhci_set_uhs_timing, sdhci_fsl_fdt_set_uhs_timing), DEVMETHOD_END }; static driver_t sdhci_fsl_fdt_driver = { "sdhci_fsl_fdt", sdhci_fsl_fdt_methods, sizeof(struct sdhci_fsl_fdt_softc), }; DRIVER_MODULE(sdhci_fsl_fdt, simplebus, sdhci_fsl_fdt_driver, NULL, NULL); SDHCI_DEPEND(sdhci_fsl_fdt); #ifndef MMCCAM MMC_DECLARE_BRIDGE(sdhci_fsl_fdt); #endif diff --git a/sys/dev/extres/syscon/syscon.c b/sys/dev/syscon/syscon.c similarity index 100% rename from sys/dev/extres/syscon/syscon.c rename to sys/dev/syscon/syscon.c diff --git a/sys/dev/extres/syscon/syscon.h b/sys/dev/syscon/syscon.h similarity index 100% rename from sys/dev/extres/syscon/syscon.h rename to sys/dev/syscon/syscon.h diff --git a/sys/dev/extres/syscon/syscon_generic.c b/sys/dev/syscon/syscon_generic.c similarity index 100% rename from sys/dev/extres/syscon/syscon_generic.c rename to sys/dev/syscon/syscon_generic.c diff --git a/sys/dev/extres/syscon/syscon_generic.h b/sys/dev/syscon/syscon_generic.h similarity index 100% rename from sys/dev/extres/syscon/syscon_generic.h rename to sys/dev/syscon/syscon_generic.h diff --git a/sys/dev/extres/syscon/syscon_if.m b/sys/dev/syscon/syscon_if.m similarity index 100% rename from sys/dev/extres/syscon/syscon_if.m rename to sys/dev/syscon/syscon_if.m diff --git a/sys/dev/extres/syscon/syscon_power.c b/sys/dev/syscon/syscon_power.c similarity index 100% rename from sys/dev/extres/syscon/syscon_power.c rename to sys/dev/syscon/syscon_power.c diff --git a/sys/dev/usb/controller/dwc3/rk_dwc3.c b/sys/dev/usb/controller/dwc3/rk_dwc3.c index b3345fb4a67b..f53f446a29f3 100644 --- a/sys/dev/usb/controller/dwc3/rk_dwc3.c +++ b/sys/dev/usb/controller/dwc3/rk_dwc3.c @@ -1,198 +1,198 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2019 Emmanuel Vadot * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Rockchip DWC3 glue */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include enum rk_dwc3_type { RK3399 = 1, }; static struct ofw_compat_data compat_data[] = { { "rockchip,rk3399-dwc3", RK3399 }, { NULL, 0 } }; struct rk_dwc3_softc { struct simplebus_softc sc; device_t dev; clk_t clk_ref; clk_t clk_suspend; clk_t clk_bus; clk_t clk_axi_perf; clk_t clk_usb3; clk_t clk_grf; hwreset_t rst_usb3; enum rk_dwc3_type type; }; static int rk_dwc3_probe(device_t dev) { phandle_t node; if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); /* Binding says that we need a child node for the actual dwc3 controller */ node = ofw_bus_get_node(dev); if (OF_child(node) <= 0) return (ENXIO); device_set_desc(dev, "Rockchip RK3399 DWC3"); return (BUS_PROBE_DEFAULT); } static int rk_dwc3_attach(device_t dev) { struct rk_dwc3_softc *sc; device_t cdev; phandle_t node, child; int err; sc = device_get_softc(dev); sc->dev = dev; node = ofw_bus_get_node(dev); sc->type = ofw_bus_search_compatible(dev, compat_data)->ocd_data; /* Mandatory clocks */ if (clk_get_by_ofw_name(dev, 0, "ref_clk", &sc->clk_ref) != 0) { device_printf(dev, "Cannot get ref_clk clock\n"); return (ENXIO); } err = clk_enable(sc->clk_ref); if (err != 0) { device_printf(dev, "Could not enable clock %s\n", clk_get_name(sc->clk_ref)); return (ENXIO); } if (clk_get_by_ofw_name(dev, 0, "suspend_clk", &sc->clk_suspend) != 0) { device_printf(dev, "Cannot get suspend_clk clock\n"); return (ENXIO); } err = clk_enable(sc->clk_suspend); if (err != 0) { device_printf(dev, "Could not enable clock %s\n", clk_get_name(sc->clk_suspend)); return (ENXIO); } if (clk_get_by_ofw_name(dev, 0, "bus_clk", &sc->clk_bus) != 0) { device_printf(dev, "Cannot get bus_clk clock\n"); return (ENXIO); } err = clk_enable(sc->clk_bus); if (err != 0) { device_printf(dev, "Could not enable clock %s\n", clk_get_name(sc->clk_bus)); return (ENXIO); } if (clk_get_by_ofw_name(dev, 0, "grf_clk", &sc->clk_grf) == 0) { err = clk_enable(sc->clk_grf); if (err != 0) { device_printf(dev, "Could not enable clock %s\n", clk_get_name(sc->clk_grf)); return (ENXIO); } } /* Optional clocks */ if (clk_get_by_ofw_name(dev, 0, "aclk_usb3_rksoc_axi_perf", &sc->clk_axi_perf) == 0) { err = clk_enable(sc->clk_axi_perf); if (err != 0) { device_printf(dev, "Could not enable clock %s\n", clk_get_name(sc->clk_axi_perf)); return (ENXIO); } } if (clk_get_by_ofw_name(dev, 0, "aclk_usb3", &sc->clk_usb3) == 0) { err = clk_enable(sc->clk_usb3); if (err != 0) { device_printf(dev, "Could not enable clock %s\n", clk_get_name(sc->clk_usb3)); return (ENXIO); } } /* Put module out of reset */ if (hwreset_get_by_ofw_name(dev, node, "usb3-otg", &sc->rst_usb3) == 0) { if (hwreset_deassert(sc->rst_usb3) != 0) { device_printf(dev, "Cannot deassert reset\n"); return (ENXIO); } } simplebus_init(dev, node); if (simplebus_fill_ranges(node, &sc->sc) < 0) { device_printf(dev, "could not get ranges\n"); return (ENXIO); } for (child = OF_child(node); child > 0; child = OF_peer(child)) { cdev = simplebus_add_device(dev, child, 0, NULL, -1, NULL); if (cdev != NULL) device_probe_and_attach(cdev); } return (bus_generic_attach(dev)); } static device_method_t rk_dwc3_methods[] = { /* Device interface */ DEVMETHOD(device_probe, rk_dwc3_probe), DEVMETHOD(device_attach, rk_dwc3_attach), DEVMETHOD_END }; DEFINE_CLASS_1(rk_dwc3, rk_dwc3_driver, rk_dwc3_methods, sizeof(struct rk_dwc3_softc), simplebus_driver); DRIVER_MODULE(rk_dwc3, simplebus, rk_dwc3_driver, 0, 0); diff --git a/sys/dev/usb/controller/xlnx_dwc3.c b/sys/dev/usb/controller/xlnx_dwc3.c index 9b9d10e81ad8..b0680db97d22 100644 --- a/sys/dev/usb/controller/xlnx_dwc3.c +++ b/sys/dev/usb/controller/xlnx_dwc3.c @@ -1,149 +1,149 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2022 Beckhoff Automation GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Xilinx DWC3 glue */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include static struct ofw_compat_data compat_data[] = { { "xlnx,zynqmp-dwc3", 1 }, { NULL, 0 } }; struct xlnx_dwc3_softc { struct simplebus_softc sc; device_t dev; hwreset_t rst_crst; hwreset_t rst_hibrst; hwreset_t rst_apbrst; }; static int xlnx_dwc3_probe(device_t dev) { phandle_t node; if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); /* Binding says that we need a child node for the actual dwc3 controller */ node = ofw_bus_get_node(dev); if (OF_child(node) <= 0) return (ENXIO); device_set_desc(dev, "Xilinx ZYNQMP DWC3"); return (BUS_PROBE_DEFAULT); } static int xlnx_dwc3_attach(device_t dev) { struct xlnx_dwc3_softc *sc; device_t cdev; phandle_t node, child; sc = device_get_softc(dev); sc->dev = dev; node = ofw_bus_get_node(dev); /* * Put module out of reset * Based on the bindings this should be mandatory to have * but reality shows that they aren't always there. * This is the case on the DTB in the AVnet Ultra96 */ if (hwreset_get_by_ofw_name(dev, node, "usb_crst", &sc->rst_crst) == 0) { if (hwreset_deassert(sc->rst_crst) != 0) { device_printf(dev, "Cannot deassert reset\n"); return (ENXIO); } } if (hwreset_get_by_ofw_name(dev, node, "usb_hibrst", &sc->rst_hibrst) == 0) { if (hwreset_deassert(sc->rst_hibrst) != 0) { device_printf(dev, "Cannot deassert reset\n"); return (ENXIO); } } if (hwreset_get_by_ofw_name(dev, node, "usb_apbrst", &sc->rst_apbrst) == 0) { if (hwreset_deassert(sc->rst_apbrst) != 0) { device_printf(dev, "Cannot deassert reset\n"); return (ENXIO); } } simplebus_init(dev, node); if (simplebus_fill_ranges(node, &sc->sc) < 0) { device_printf(dev, "could not get ranges\n"); return (ENXIO); } for (child = OF_child(node); child > 0; child = OF_peer(child)) { cdev = simplebus_add_device(dev, child, 0, NULL, -1, NULL); if (cdev != NULL) device_probe_and_attach(cdev); } return (bus_generic_attach(dev)); } static device_method_t xlnx_dwc3_methods[] = { /* Device interface */ DEVMETHOD(device_probe, xlnx_dwc3_probe), DEVMETHOD(device_attach, xlnx_dwc3_attach), DEVMETHOD_END }; DEFINE_CLASS_1(xlnx_dwc3, xlnx_dwc3_driver, xlnx_dwc3_methods, sizeof(struct xlnx_dwc3_softc), simplebus_driver); DRIVER_MODULE(xlnx_dwc3, simplebus, xlnx_dwc3_driver, 0, 0); diff --git a/sys/riscv/riscv/riscv_syscon.c b/sys/riscv/riscv/riscv_syscon.c index 7442b982f2ab..3dac114edd4f 100644 --- a/sys/riscv/riscv/riscv_syscon.c +++ b/sys/riscv/riscv/riscv_syscon.c @@ -1,80 +1,80 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2018 Kyle Evans * Copyright (c) 2020 Jessica Clarke * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * RISC-V syscon driver. Used as a generic interface by QEMU's virt machine for * describing the SiFive test finisher as a power and reset controller. */ #include #include #include #include #include #include #include #include #include #include -#include -#include +#include +#include static struct ofw_compat_data compat_data[] = { {"sifive,test0", 1}, {"sifive,test1", 1}, {NULL, 0} }; static int riscv_syscon_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "RISC-V syscon"); return (BUS_PROBE_DEFAULT); } static device_method_t riscv_syscon_methods[] = { DEVMETHOD(device_probe, riscv_syscon_probe), DEVMETHOD_END }; DEFINE_CLASS_1(riscv_syscon, riscv_syscon_driver, riscv_syscon_methods, sizeof(struct syscon_generic_softc), syscon_generic_driver); /* riscv_syscon needs to attach prior to syscon_power */ EARLY_DRIVER_MODULE(riscv_syscon, simplebus, riscv_syscon_driver, 0, 0, BUS_PASS_SCHEDULER + BUS_PASS_ORDER_LAST); MODULE_VERSION(riscv_syscon, 1);