Index: head/sys/arm/broadcom/bcm2835/bcm2835_sdhost.c =================================================================== --- head/sys/arm/broadcom/bcm2835/bcm2835_sdhost.c (nonexistent) +++ head/sys/arm/broadcom/bcm2835/bcm2835_sdhost.c (revision 335779) @@ -0,0 +1,1301 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2018 Klaus P. Ohrhallinger + * All rights reserved. + * + * Based on bcm2835_sdhci.c: + * Copyright (c) 2012 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 +__FBSDID("$FreeBSD$"); + +/* + * pin 48-53 - card slot + * pin 34-39 - radio module + * + * alt-0 - rubbish SDHCI (0x7e202000) aka sdhost + * alt-3 - advanced SDHCI (0x7e300000) aka sdhci/mmc/sdio + * + * driving card slot with mmc: + * + * sdhost_pins { + * brcm,pins = <0x30 0x31 0x32 0x33 0x34 0x35>; + * brcm,function = <0x7>; + * brcm,pull = <0x0 0x2 0x2 0x2 0x2 0x2>; + * phandle = <0x17>; + * }; + * sdio_pins { + * brcm,pins = <0x22 0x23 0x24 0x25 0x26 0x27>; + * brcm,function = <0x4>; + * brcm,pull = <0x0 0x2 0x2 0x2 0x2 0x2>; + * phandle = <0x18>; + * }; + * + * driving card slot with sdhost: + * + * sdhost_pins { + * brcm,pins = <0x30 0x31 0x32 0x33 0x34 0x35>; + * brcm,function = <0x4>; + * brcm,pull = <0x0 0x2 0x2 0x2 0x2 0x2>; + * phandle = <0x17>; + * }; + * sdio_pins { + * brcm,pins = <0x22 0x23 0x24 0x25 0x26 0x27>; + * brcm,function = <0x7>; + * brcm,pull = <0x0 0x2 0x2 0x2 0x2 0x2>; + * phandle = <0x18>; + * }; + * + */ + +#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 "bcm2835_dma.h" +#include +#include "bcm2835_vcbus.h" + + +/* #define SDHOST_DEBUG */ + + +/* Registers */ +#define HC_COMMAND 0x00 /* Command and flags */ +#define HC_ARGUMENT 0x04 +#define HC_TIMEOUTCOUNTER 0x08 +#define HC_CLOCKDIVISOR 0x0c +#define HC_RESPONSE_0 0x10 +#define HC_RESPONSE_1 0x14 +#define HC_RESPONSE_2 0x18 +#define HC_RESPONSE_3 0x1c +#define HC_HOSTSTATUS 0x20 +#define HC_POWER 0x30 +#define HC_DEBUG 0x34 +#define HC_HOSTCONFIG 0x38 +#define HC_BLOCKSIZE 0x3c +#define HC_DATAPORT 0x40 +#define HC_BLOCKCOUNT 0x50 + +/* Flags for HC_COMMAND register */ +#define HC_CMD_ENABLE 0x8000 +#define HC_CMD_FAILED 0x4000 +#define HC_CMD_BUSY 0x0800 +#define HC_CMD_RESPONSE_NONE 0x0400 +#define HC_CMD_RESPONSE_LONG 0x0200 +#define HC_CMD_WRITE 0x0080 +#define HC_CMD_READ 0x0040 +#define HC_CMD_COMMAND_MASK 0x003f + +#define HC_CLOCKDIVISOR_MAXVAL 0x07ff + +/* Flags for HC_HOSTSTATUS register */ +#define HC_HSTST_HAVEDATA 0x0001 +#define HC_HSTST_ERROR_FIFO 0x0008 +#define HC_HSTST_ERROR_CRC7 0x0010 +#define HC_HSTST_ERROR_CRC16 0x0020 +#define HC_HSTST_TIMEOUT_CMD 0x0040 +#define HC_HSTST_TIMEOUT_DATA 0x0080 +#define HC_HSTST_INT_BLOCK 0x0200 +#define HC_HSTST_INT_BUSY 0x0400 + +#define HC_HSTST_RESET 0xffff + +#define HC_HSTST_MASK_ERROR_DATA (HC_HSTST_ERROR_FIFO | \ + HC_HSTST_ERROR_CRC7 | HC_HSTST_ERROR_CRC16 | HC_HSTST_TIMEOUT_DATA) + +#define HC_HSTST_MASK_ERROR_ALL (HC_HSTST_MASK_ERROR_DATA | \ + HC_HSTST_TIMEOUT_CMD) + +/* Flags for HC_HOSTCONFIG register */ +#define HC_HSTCF_INTBUS_WIDE 0x0002 +#define HC_HSTCF_EXTBUS_4BIT 0x0004 +#define HC_HSTCF_SLOW_CARD 0x0008 +#define HC_HSTCF_INT_DATA 0x0010 +#define HC_HSTCF_INT_BLOCK 0x0100 +#define HC_HSTCF_INT_BUSY 0x0400 + +/* Flags for HC_DEBUG register */ +#define HC_DBG_FIFO_THRESH_WRITE_SHIFT 9 +#define HC_DBG_FIFO_THRESH_READ_SHIFT 14 +#define HC_DBG_FIFO_THRESH_MASK 0x001f + +/* Settings */ +#define HC_FIFO_SIZE 16 +#define HC_FIFO_THRESH_READ 4 +#define HC_FIFO_THRESH_WRITE 4 + +#define HC_TIMEOUT_DEFAULT 0x00f00000 + +#define BCM2835_DEFAULT_SDHCI_FREQ 50 + +static int bcm2835_sdhost_debug = 0; + +#ifdef SDHOST_DEBUG + +TUNABLE_INT("hw.bcm2835.sdhost.debug", &bcm2835_sdhost_debug); +SYSCTL_INT(_hw_sdhci, OID_AUTO, bcm2835_sdhost_debug, CTLFLAG_RWTUN, + &bcm2835_sdhost_debug, 0, "bcm2835-sdhost Debug level"); + +#define dprintf(fmt, args...) \ + do { \ + if (bcm2835_sdhost_debug > 0) \ + printf(fmt,##args); \ + } while (0) +#else + +#define dprintf(fmt, args...) + +#endif /* ! SDHOST_DEBUG */ + +static struct ofw_compat_data compat_data[] = { + {"brcm,bcm2835-sdhost", 1}, + {NULL, 0} +}; + +struct bcm_sdhost_softc { + device_t sc_dev; + struct resource * sc_mem_res; + struct resource * sc_irq_res; + bus_space_tag_t sc_bst; + bus_space_handle_t sc_bsh; + void * sc_intrhand; + struct mmc_request * sc_req; + struct sdhci_slot sc_slot; + + struct mtx mtx; + + char cmdbusy; + char mmc_app_cmd; + + u_int32_t sdhci_int_status; + u_int32_t sdhci_signal_enable; + u_int32_t sdhci_present_state; + u_int32_t sdhci_blocksize; + u_int32_t sdhci_blockcount; + + u_int32_t sdcard_rca; +}; + +static int bcm_sdhost_probe(device_t); +static int bcm_sdhost_attach(device_t); +static int bcm_sdhost_detach(device_t); +static void bcm_sdhost_intr(void *); + +static int bcm_sdhost_get_ro(device_t, device_t); + + +static inline uint32_t +RD4(struct bcm_sdhost_softc *sc, bus_size_t off) +{ + uint32_t val; + + val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, off); + + return (val); +} + +static inline void +WR4(struct bcm_sdhost_softc *sc, bus_size_t off, uint32_t val) +{ + + bus_space_write_4(sc->sc_bst, sc->sc_bsh, off, val); +} + +static inline uint16_t +RD2(struct bcm_sdhost_softc *sc, bus_size_t off) +{ + uint32_t val; + + val = RD4(sc, off & ~3); + + return ((val >> (off & 3)*8) & 0xffff); +} + +static inline uint8_t +RD1(struct bcm_sdhost_softc *sc, bus_size_t off) +{ + uint32_t val; + + val = RD4(sc, off & ~3); + + return ((val >> (off & 3)*8) & 0xff); +} + +static inline void +WR2(struct bcm_sdhost_softc *sc, bus_size_t off, uint16_t val) +{ + uint32_t val32; + + val32 = RD4(sc, off & ~3); + val32 &= ~(0xffff << (off & 3)*8); + val32 |= (val << (off & 3)*8); + WR4(sc, off & ~3, val32); +} + +static inline void +WR1(struct bcm_sdhost_softc *sc, bus_size_t off, uint8_t val) +{ + uint32_t val32; + + val32 = RD4(sc, off & ~3); + val32 &= ~(0xff << (off & 3)*8); + val32 |= (val << (off & 3)*8); + WR4(sc, off & ~3, val32); +} + +static void +bcm_sdhost_print_regs(struct bcm_sdhost_softc *sc, struct sdhci_slot *slot, + int line, int error) +{ + + if (bcm2835_sdhost_debug > 0 || error > 0) { + + printf("%s: sc=%p slot=%p\n", + __func__, sc, slot); + printf("HC_COMMAND: 0x%08x\n", + RD4(sc, HC_COMMAND)); + printf("HC_ARGUMENT: 0x%08x\n", + RD4(sc, HC_ARGUMENT)); + printf("HC_TIMEOUTCOUNTER: 0x%08x\n", + RD4(sc, HC_TIMEOUTCOUNTER)); + printf("HC_CLOCKDIVISOR: 0x%08x\n", + RD4(sc, HC_CLOCKDIVISOR)); + printf("HC_RESPONSE_0: 0x%08x\n", + RD4(sc, HC_RESPONSE_0)); + printf("HC_RESPONSE_1: 0x%08x\n", + RD4(sc, HC_RESPONSE_1)); + printf("HC_RESPONSE_2: 0x%08x\n", + RD4(sc, HC_RESPONSE_2)); + printf("HC_RESPONSE_3: 0x%08x\n", + RD4(sc, HC_RESPONSE_3)); + printf("HC_HOSTSTATUS: 0x%08x\n", + RD4(sc, HC_HOSTSTATUS)); + printf("HC_POWER: 0x%08x\n", + RD4(sc, HC_POWER)); + printf("HC_DEBUG: 0x%08x\n", + RD4(sc, HC_DEBUG)); + printf("HC_HOSTCONFIG: 0x%08x\n", + RD4(sc, HC_HOSTCONFIG)); + printf("HC_BLOCKSIZE: 0x%08x\n", + RD4(sc, HC_BLOCKSIZE)); + printf("HC_BLOCKCOUNT: 0x%08x\n", + RD4(sc, HC_BLOCKCOUNT)); + + } else { + + /* + printf("%04d | HC_COMMAND: 0x%08x HC_ARGUMENT: 0x%08x " + "HC_HOSTSTATUS: 0x%08x HC_HOSTCONFIG: 0x%08x\n", + line, RD4(sc, HC_COMMAND), RD4(sc, HC_ARGUMENT), + RD4(sc, HC_HOSTSTATUS), RD4(sc, HC_HOSTCONFIG)); + */ + } +} + +static void +bcm_sdhost_reset(device_t dev, struct sdhci_slot *slot) +{ + struct bcm_sdhost_softc *sc = device_get_softc(dev); + u_int32_t dbg; + + WR4(sc, HC_POWER, 0); + + WR4(sc, HC_COMMAND, 0); + WR4(sc, HC_ARGUMENT, 0); + WR4(sc, HC_TIMEOUTCOUNTER, HC_TIMEOUT_DEFAULT); + WR4(sc, HC_CLOCKDIVISOR, 0); + WR4(sc, HC_HOSTSTATUS, HC_HSTST_RESET); + WR4(sc, HC_HOSTCONFIG, 0); + WR4(sc, HC_BLOCKSIZE, 0); + WR4(sc, HC_BLOCKCOUNT, 0); + + dbg = RD4(sc, HC_DEBUG); + dbg &= ~( (HC_DBG_FIFO_THRESH_MASK << HC_DBG_FIFO_THRESH_READ_SHIFT) | + (HC_DBG_FIFO_THRESH_MASK << HC_DBG_FIFO_THRESH_WRITE_SHIFT) ); + dbg |= (HC_FIFO_THRESH_READ << HC_DBG_FIFO_THRESH_READ_SHIFT) | + (HC_FIFO_THRESH_WRITE << HC_DBG_FIFO_THRESH_WRITE_SHIFT); + WR4(sc, HC_DEBUG, dbg); + + DELAY(250000); + + WR4(sc, HC_POWER, 1); + + DELAY(250000); + + sc->sdhci_present_state = SDHCI_CARD_PRESENT | SDHCI_CARD_STABLE | + SDHCI_WRITE_PROTECT; + + WR4(sc, HC_CLOCKDIVISOR, HC_CLOCKDIVISOR_MAXVAL); + WR4(sc, HC_HOSTCONFIG, HC_HSTCF_INT_BUSY); +} + +static int +bcm_sdhost_probe(device_t dev) +{ + + dprintf("%s:\n", __func__); + + 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, "Broadcom 2708 SDHOST controller"); + + return (BUS_PROBE_DEFAULT); +} + +static int +bcm_sdhost_attach(device_t dev) +{ + struct bcm_sdhost_softc *sc = device_get_softc(dev); + int rid, err; + u_int default_freq; + + dprintf("%s: dev=%p sc=%p unit=%d\n", + __func__, dev, sc, device_get_unit(dev)); + + mtx_init(&sc->mtx, "BCM SDHOST mtx", "bcm_sdhost", + MTX_DEF | MTX_RECURSE); + + sc->sc_dev = dev; + sc->sc_req = NULL; + + sc->cmdbusy = 0; + sc->mmc_app_cmd = 0; + sc->sdhci_int_status = 0; + sc->sdhci_signal_enable = 0; + sc->sdhci_present_state = 0; + sc->sdhci_blocksize = 0; + sc->sdhci_blockcount = 0; + + sc->sdcard_rca = 0; + + default_freq = 50; + err = 0; + + if (bootverbose) + device_printf(dev, "SDHCI frequency: %dMHz\n", default_freq); + + rid = 0; + sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (!sc->sc_mem_res) { + device_printf(dev, "cannot allocate memory window\n"); + err = ENXIO; + goto fail; + } + + sc->sc_bst = rman_get_bustag(sc->sc_mem_res); + sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res); + + bcm_sdhost_reset(dev, &sc->sc_slot); + + bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 0); + + rid = 0; + sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_ACTIVE); + if (!sc->sc_irq_res) { + device_printf(dev, "cannot allocate interrupt\n"); + err = ENXIO; + goto fail; + } + + if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, + NULL, bcm_sdhost_intr, sc, &sc->sc_intrhand)) { + device_printf(dev, "cannot setup interrupt handler\n"); + err = ENXIO; + goto fail; + } + + sc->sc_slot.caps = 0; + sc->sc_slot.caps |= SDHCI_CAN_VDD_330; + sc->sc_slot.caps |= SDHCI_CAN_DO_HISPD; + sc->sc_slot.caps |= (default_freq << SDHCI_CLOCK_BASE_SHIFT); + + sc->sc_slot.quirks = 0; + sc->sc_slot.quirks |= SDHCI_QUIRK_MISSING_CAPS; + sc->sc_slot.quirks |= SDHCI_QUIRK_DONT_SHIFT_RESPONSE; + + sc->sc_slot.opt = 0; + + /* XXX ? + sc->slot->timeout_clk = ...; + */ + + sdhci_init_slot(dev, &sc->sc_slot, 0); + + bus_generic_probe(dev); + bus_generic_attach(dev); + + sdhci_start_slot(&sc->sc_slot); + + return (0); + + fail: + if (sc->sc_intrhand) + bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand); + if (sc->sc_irq_res) + bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); + if (sc->sc_mem_res) + bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); + + return (err); +} + +static int +bcm_sdhost_detach(device_t dev) +{ + + dprintf("%s:\n", __func__); + + return (EBUSY); +} + +/* + * rv 0 --> command finished + * rv 1 --> command timed out + */ +static inline int +bcm_sdhost_waitcommand(struct bcm_sdhost_softc *sc) +{ + int timeout = 1000; + + mtx_assert(&sc->mtx, MA_OWNED); + + while ((RD4(sc, HC_COMMAND) & HC_CMD_ENABLE) && --timeout > 0) { + DELAY(100); + } + + return ((timeout > 0) ? 0 : 1); +} + +static int +bcm_sdhost_waitcommand_status(struct bcm_sdhost_softc *sc) +{ + u_int32_t cdst; + int i; + + /* wait for card to change status from + * ''prg'' to ''trn'' + * card status: sd specs p. 103 + */ + i = 0; + do { + DELAY(1000); + WR4(sc, HC_ARGUMENT, sc->sdcard_rca << 16); + WR4(sc, HC_COMMAND, + MMC_SEND_STATUS | HC_CMD_ENABLE); + bcm_sdhost_waitcommand(sc); + cdst = RD4(sc, HC_RESPONSE_0); + dprintf("%s: card status %08x (cs %d)\n", + __func__, cdst, (cdst & 0x0e00) >> 9); + if (i++ > 100) { + printf("%s: giving up, " + "card status %08x (cs %d)\n", + __func__, cdst, + (cdst & 0x0e00) >> 9); + return (1); + break; + } + } while (((cdst & 0x0e00) >> 9) != 4); + + return (0); +} + +static void +bcm_sdhost_intr(void *arg) +{ + struct bcm_sdhost_softc *sc = arg; + struct sdhci_slot *slot = &sc->sc_slot; + uint32_t hstst; + uint32_t cmd; + + mtx_lock(&sc->mtx); + + hstst = RD4(sc, HC_HOSTSTATUS); + cmd = RD4(sc, HC_COMMAND); + if (hstst & HC_HSTST_HAVEDATA) { + if (cmd & HC_CMD_READ) { + sc->sdhci_present_state |= SDHCI_DATA_AVAILABLE; + sc->sdhci_int_status |= SDHCI_INT_DATA_AVAIL; + } else if (cmd & HC_CMD_WRITE) { + sc->sdhci_present_state |= SDHCI_SPACE_AVAILABLE; + sc->sdhci_int_status |= SDHCI_INT_SPACE_AVAIL; + } else { + panic("%s: hstst & HC_HSTST_HAVEDATA but no " + "HC_CMD_READ or HC_CMD_WRITE: cmd=%0x8 " + "hstst=%08x\n", __func__, cmd, hstst); + } + } else { + sc->sdhci_present_state &= + ~(SDHCI_DATA_AVAILABLE|SDHCI_SPACE_AVAILABLE); + sc->sdhci_int_status &= + ~(SDHCI_INT_DATA_AVAIL|SDHCI_INT_SPACE_AVAIL); + } + + if (hstst & HC_HSTST_MASK_ERROR_ALL) { + printf("%s: ERROR: HC_HOSTSTATUS: %08x\n", __func__, hstst); + bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 1); + sc->sdhci_int_status |= SDHCI_INT_ERROR; + } else { + sc->sdhci_int_status &= ~SDHCI_INT_ERROR; + } + + dprintf("%s: hstst=%08x offset=%08lx sdhci_present_state=%08x " + "sdhci_int_status=%08x\n", __func__, hstst, slot->offset, + sc->sdhci_present_state, sc->sdhci_int_status); + + sdhci_generic_intr(&sc->sc_slot); + + sc->sdhci_int_status &= + ~(SDHCI_INT_ERROR|SDHCI_INT_DATA_AVAIL|SDHCI_INT_DATA_END); + sc->sdhci_present_state &= ~SDHCI_DATA_AVAILABLE; + + if ((hstst & HC_HSTST_HAVEDATA) && + (sc->sdhci_blocksize * sc->sdhci_blockcount == slot->offset)) { + dprintf("%s: offset=%08lx sdhci_blocksize=%08x " + "sdhci_blockcount=%08x\n", __func__, slot->offset, + sc->sdhci_blocksize, sc->sdhci_blockcount); + sc->sdhci_int_status &= + ~(SDHCI_INT_DATA_AVAIL|SDHCI_INT_SPACE_AVAIL); + sc->sdhci_int_status |= SDHCI_INT_DATA_END; + sdhci_generic_intr(&sc->sc_slot); + sc->sdhci_int_status &= ~SDHCI_INT_DATA_END; + + if ((cmd & HC_CMD_COMMAND_MASK) == MMC_READ_MULTIPLE_BLOCK || + (cmd & HC_CMD_COMMAND_MASK) == MMC_WRITE_MULTIPLE_BLOCK) { + WR4(sc, HC_ARGUMENT, 0x00000000); + WR4(sc, HC_COMMAND, + MMC_STOP_TRANSMISSION | HC_CMD_ENABLE); + + if (bcm_sdhost_waitcommand(sc)) { + printf("%s: timeout #1\n", __func__); + bcm_sdhost_print_regs(sc, &sc->sc_slot, + __LINE__, 1); + } + } + + if (cmd & HC_CMD_WRITE) { + if (bcm_sdhost_waitcommand_status(sc) != 0) + sc->sdhci_int_status |= SDHCI_INT_ERROR; + } + + slot->data_done = 1; + + sc->sdhci_int_status |= SDHCI_INT_RESPONSE; + sdhci_generic_intr(&sc->sc_slot); + sc->sdhci_int_status &= ~(SDHCI_INT_RESPONSE|SDHCI_INT_ERROR); + } + + /* this resets the interrupt */ + WR4(sc, HC_HOSTSTATUS, + (HC_HSTST_INT_BUSY|HC_HSTST_INT_BLOCK|HC_HSTST_HAVEDATA)); + + mtx_unlock(&sc->mtx); +} + +static int +bcm_sdhost_get_ro(device_t bus, device_t child) +{ + + dprintf("%s:\n", __func__); + + return (0); +} + +static bool +bcm_sdhost_get_card_present(device_t dev, struct sdhci_slot *slot) +{ + + dprintf("%s:\n", __func__); + + return (1); +} + +static void +bcm_sdhost_command(device_t dev, struct sdhci_slot *slot, uint16_t val) +{ + struct bcm_sdhost_softc *sc = device_get_softc(dev); + struct mmc_data *data = slot->curcmd->data; + uint16_t val2; + uint8_t opcode; + uint8_t flags; + + mtx_assert(&sc->mtx, MA_OWNED); + + if (RD4(sc, HC_COMMAND) & HC_CMD_ENABLE) { + panic("%s: HC_CMD_ENABLE on entry\n", __func__); + } + + if (sc->cmdbusy == 1) + panic("%s: cmdbusy\n", __func__); + + sc->cmdbusy = 1; + + val2 = ((val >> 8) & HC_CMD_COMMAND_MASK) | HC_CMD_ENABLE; + + opcode = val >> 8; + flags = val & 0xff; + + if (opcode == MMC_APP_CMD) + sc->mmc_app_cmd = 1; + + if ((flags & SDHCI_CMD_RESP_MASK) == SDHCI_CMD_RESP_LONG) + val2 |= HC_CMD_RESPONSE_LONG; + else if ((flags & SDHCI_CMD_RESP_MASK) == SDHCI_CMD_RESP_SHORT_BUSY) + /* XXX XXX when enabled, cmd 7 (select card) blocks forever */ + ;/*val2 |= HC_CMD_BUSY; */ + else if ((flags & SDHCI_CMD_RESP_MASK) == SDHCI_CMD_RESP_SHORT) + ; + else + val2 |= HC_CMD_RESPONSE_NONE; + + if (val2 & HC_CMD_BUSY) + sc->sdhci_present_state |= + SDHCI_CMD_INHIBIT | SDHCI_DAT_INHIBIT; + + if (data != NULL && data->flags & MMC_DATA_READ) + val2 |= HC_CMD_READ; + else if (data != NULL && data->flags & MMC_DATA_WRITE) + val2 |= HC_CMD_WRITE; + + dprintf("%s: SDHCI_COMMAND_FLAGS --> HC_COMMAND %04x --> %04x\n", + __func__, val, val2); + + if (opcode == MMC_READ_MULTIPLE_BLOCK || + opcode == MMC_WRITE_MULTIPLE_BLOCK) { + u_int32_t save_sdarg; + + dprintf("%s: issuing MMC_SET_BLOCK_COUNT: CMD %08x ARG %08x\n", + __func__, MMC_SET_BLOCK_COUNT | HC_CMD_ENABLE, + sc->sdhci_blockcount); + + save_sdarg = RD4(sc, HC_ARGUMENT); + WR4(sc, HC_ARGUMENT, sc->sdhci_blockcount); + WR4(sc, HC_COMMAND, MMC_SET_BLOCK_COUNT | HC_CMD_ENABLE); + + /* Seems to always return timeout */ + + if (bcm_sdhost_waitcommand(sc)) { + printf("%s: timeout #2\n", __func__); + bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 1); + } else { + bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 0); + } + WR4(sc, HC_ARGUMENT, save_sdarg); + + } else if (opcode == MMC_SELECT_CARD) { + sc->sdcard_rca = (RD4(sc, HC_ARGUMENT) >> 16); + } + + /* actually issuing the command */ + WR4(sc, HC_COMMAND, val2); + + if (val2 & HC_CMD_READ || val2 & HC_CMD_WRITE) { + u_int8_t hstcfg; + + hstcfg = RD4(sc, HC_HOSTCONFIG); + hstcfg |= (HC_HSTCF_INT_BUSY | HC_HSTCF_INT_DATA); + WR4(sc, HC_HOSTCONFIG, hstcfg); + slot->data_done = 0; + + if (bcm_sdhost_waitcommand(sc)) { + printf("%s: timeout #3\n", __func__); + bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 1); + } + + } else if (opcode == MMC_ERASE) { + if (bcm_sdhost_waitcommand_status(sc) != 0) { + printf("%s: timeout #4\n", __func__); + bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 1); + } + slot->data_done = 1; + sc->sdhci_present_state &= + ~(SDHCI_CMD_INHIBIT | SDHCI_DAT_INHIBIT); + + } else { + if (bcm_sdhost_waitcommand(sc)) { + printf("%s: timeout #5\n", __func__); + bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 1); + } + slot->data_done = 1; + sc->sdhci_present_state &= + ~(SDHCI_CMD_INHIBIT | SDHCI_DAT_INHIBIT); + } + + bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 0); + + if (RD4(sc, HC_HOSTSTATUS) & HC_HSTST_TIMEOUT_CMD) + slot->curcmd->error = MMC_ERR_TIMEOUT; + else if (RD4(sc, HC_COMMAND) & HC_CMD_FAILED) + slot->curcmd->error = MMC_ERR_FAILED; + + dprintf("%s: curcmd->flags=%d data_done=%d\n", + __func__, slot->curcmd->flags, slot->data_done); + + if (val2 & HC_CMD_RESPONSE_NONE) + slot->curcmd->error = 0; + + if (sc->mmc_app_cmd == 1 && opcode != MMC_APP_CMD) + sc->mmc_app_cmd = 0; + + if (RD4(sc, HC_COMMAND) & HC_CMD_ENABLE) { + bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 1); + panic("%s: still HC_CMD_ENABLE on exit\n", __func__); + } + + sc->cmdbusy = 0; + + if (!(val2 & HC_CMD_READ || val2 & HC_CMD_WRITE)) + sc->sdhci_int_status |= SDHCI_INT_RESPONSE; + + /* HACK, so sdhci_finish_command() does not + * have to be exported + */ + mtx_unlock(&slot->mtx); + sdhci_generic_intr(slot); + mtx_lock(&slot->mtx); + sc->sdhci_int_status &= ~SDHCI_INT_RESPONSE; +} + +static uint8_t +bcm_sdhost_read_1(device_t dev, struct sdhci_slot *slot, bus_size_t off) +{ + struct bcm_sdhost_softc *sc = device_get_softc(dev); + uint32_t val1, val2; + + mtx_lock(&sc->mtx); + + switch (off) { + case SDHCI_HOST_CONTROL: + val1 = RD4(sc, HC_HOSTCONFIG); + val2 = 0; + if (val1 & HC_HSTCF_EXTBUS_4BIT) + val2 |= SDHCI_CTRL_4BITBUS; + dprintf("%s: SDHCI_HOST_CONTROL --> HC_HOSTCONFIG val2 %02x\n", + __func__, val2); + break; + case SDHCI_POWER_CONTROL: + val1 = RD1(sc, HC_POWER); + val2 = (val1 == 1) ? 0x0f : 0; + dprintf("%s: SDHCI_POWER_CONTROL --> HC_POWER val2 %02x\n", + __func__, val2); + break; + case SDHCI_BLOCK_GAP_CONTROL: + dprintf("%s: SDHCI_BLOCK_GAP_CONTROL\n", __func__); + val2 = 0; + break; + case SDHCI_WAKE_UP_CONTROL: + dprintf("%s: SDHCI_WAKE_UP_CONTROL\n", __func__); + val2 = 0; + break; + case SDHCI_TIMEOUT_CONTROL: + dprintf("%s: SDHCI_TIMEOUT_CONTROL\n", __func__); + val2 = 0; + break; + case SDHCI_SOFTWARE_RESET: + dprintf("%s: SDHCI_SOFTWARE_RESET\n", __func__); + val2 = 0; + break; + case SDHCI_ADMA_ERR: + dprintf("%s: SDHCI_ADMA_ERR\n", __func__); + val2 = 0; + break; + default: + dprintf("%s: UNKNOWN off=%08lx\n", __func__, off); + val2 = 0; + break; + } + + mtx_unlock(&sc->mtx); + + return (val2); +} + +static uint16_t +bcm_sdhost_read_2(device_t dev, struct sdhci_slot *slot, bus_size_t off) +{ + struct bcm_sdhost_softc *sc = device_get_softc(dev); + uint32_t val2, val; /* = RD4(sc, off & ~3); */ + + mtx_lock(&sc->mtx); + + switch (off) { + case SDHCI_BLOCK_SIZE: + val2 = sc->sdhci_blocksize; + dprintf("%s: SDHCI_BLOCK_SIZE --> HC_BLOCKSIZE %08x\n", + __func__, val2); + break; + case SDHCI_BLOCK_COUNT: + val2 = sc->sdhci_blockcount; + dprintf("%s: SDHCI_BLOCK_COUNT --> HC_BLOCKCOUNT %08x\n", + __func__, val2); + break; + case SDHCI_TRANSFER_MODE: + dprintf("%s: SDHCI_TRANSFER_MODE\n", __func__); + val2 = 0; + break; + case SDHCI_CLOCK_CONTROL: + val = RD4(sc, HC_CLOCKDIVISOR); + val2 = (val << SDHCI_DIVIDER_SHIFT) | + SDHCI_CLOCK_CARD_EN | SDHCI_CLOCK_INT_EN | + SDHCI_CLOCK_INT_STABLE; + dprintf("%s: SDHCI_CLOCK_CONTROL %04x --> %04x\n", + __func__, val, val2); + break; + case SDHCI_ACMD12_ERR: + dprintf("%s: SDHCI_ACMD12_ERR\n", __func__); + val2 = 0; + break; + case SDHCI_HOST_CONTROL2: + dprintf("%s: SDHCI_HOST_CONTROL2\n", __func__); + val2 = 0; + break; + case SDHCI_SLOT_INT_STATUS: + dprintf("%s: SDHCI_SLOT_INT_STATUS\n", __func__); + val2 = 0; + break; + case SDHCI_HOST_VERSION: + dprintf("%s: SDHCI_HOST_VERSION\n", __func__); + val2 = 0; + break; + default: + dprintf("%s: UNKNOWN off=%08lx\n", __func__, off); + val2 = 0; + break; + } + + mtx_unlock(&sc->mtx); + + return (val2); +} + +static uint32_t +bcm_sdhost_read_4(device_t dev, struct sdhci_slot *slot, bus_size_t off) +{ + struct bcm_sdhost_softc *sc = device_get_softc(dev); + uint32_t val2; + + mtx_lock(&sc->mtx); + + switch (off) { + case SDHCI_DMA_ADDRESS: + dprintf("%s: SDHCI_DMA_ADDRESS\n", __func__); + val2 = 0; + break; + case SDHCI_ARGUMENT: + dprintf("%s: SDHCI_ARGUMENT\n", __func__); + val2 = (RD4(sc, HC_COMMAND) << 16) | + (RD4(sc, HC_ARGUMENT) & 0x0000ffff); + break; + case SDHCI_RESPONSE + 0: + val2 = RD4(sc, HC_RESPONSE_0); + dprintf("%s: SDHCI_RESPONSE+0 %08x\n", __func__, val2); + break; + case SDHCI_RESPONSE + 4: + val2 = RD4(sc, HC_RESPONSE_1); + dprintf("%s: SDHCI_RESPONSE+4 %08x\n", __func__, val2); + break; + case SDHCI_RESPONSE + 8: + val2 = RD4(sc, HC_RESPONSE_2); + dprintf("%s: SDHCI_RESPONSE+8 %08x\n", __func__, val2); + break; + case SDHCI_RESPONSE + 12: + val2 = RD4(sc, HC_RESPONSE_3); + dprintf("%s: SDHCI_RESPONSE+12 %08x\n", __func__, val2); + break; + case SDHCI_BUFFER: + dprintf("%s: SDHCI_BUFFER\n", __func__); + val2 = 0; + break; + case SDHCI_PRESENT_STATE: + dprintf("%s: SDHCI_PRESENT_STATE %08x\n", + __func__, sc->sdhci_present_state); + val2 = sc->sdhci_present_state; + break; + case SDHCI_INT_STATUS: + dprintf("%s: SDHCI_INT_STATUS %08x\n", + __func__, sc->sdhci_int_status); + val2 = sc->sdhci_int_status; + break; + case SDHCI_INT_ENABLE: + dprintf("%s: SDHCI_INT_ENABLE\n", __func__); + val2 = 0; + break; + case SDHCI_SIGNAL_ENABLE: + dprintf("%s: SDHCI_SIGNAL_ENABLE %08x\n", + __func__, sc->sdhci_signal_enable); + val2 = sc->sdhci_signal_enable; + break; + case SDHCI_CAPABILITIES: + val2 = 0; + break; + case SDHCI_CAPABILITIES2: + dprintf("%s: SDHCI_CAPABILITIES2\n", __func__); + val2 = 0; + break; + case SDHCI_MAX_CURRENT: + dprintf("%s: SDHCI_MAX_CURRENT\n", __func__); + val2 = 0; + break; + case SDHCI_ADMA_ADDRESS_LO: + dprintf("%s: SDHCI_ADMA_ADDRESS_LO\n", __func__); + val2 = 0; + break; + default: + dprintf("%s: UNKNOWN off=%08lx\n", __func__, off); + val2 = 0; + break; + } + + mtx_unlock(&sc->mtx); + + return (val2); +} + +static void +bcm_sdhost_read_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off, + uint32_t *data, bus_size_t count) +{ + struct bcm_sdhost_softc *sc = device_get_softc(dev); + bus_size_t i; + bus_size_t avail; + uint32_t edm; + + mtx_lock(&sc->mtx); + + dprintf("%s: off=%08lx count=%08lx\n", __func__, off, count); + + for (i = 0; i < count;) { + edm = RD4(sc, HC_DEBUG); + avail = ((edm >> 4) & 0x1f); + if (i + avail > count) { + if (i >= count) + return; + else + avail = count - i; + } + if (avail > 0) + bus_space_read_multi_4(sc->sc_bst, sc->sc_bsh, + HC_DATAPORT, data + i, avail); + i += avail; + DELAY(1); + } + + mtx_unlock(&sc->mtx); +} + +static void +bcm_sdhost_write_1(device_t dev, struct sdhci_slot *slot, + bus_size_t off, uint8_t val) +{ + struct bcm_sdhost_softc *sc = device_get_softc(dev); + uint32_t val2; + + mtx_lock(&sc->mtx); + + switch (off) { + case SDHCI_HOST_CONTROL: + val2 = RD4(sc, HC_HOSTCONFIG); + val2 |= HC_HSTCF_INT_BUSY; + val2 |= HC_HSTCF_INTBUS_WIDE | HC_HSTCF_SLOW_CARD; + if (val & SDHCI_CTRL_4BITBUS) + val2 |= HC_HSTCF_EXTBUS_4BIT; + dprintf("%s: SDHCI_HOST_CONTROL --> HC_HOSTC %04x --> %04x\n", + __func__, val, val2); + WR4(sc, HC_HOSTCONFIG, val2); + break; + case SDHCI_POWER_CONTROL: + val2 = (val != 0) ? 1 : 0; + dprintf("%s: SDHCI_POWER_CONTROL --> HC_POWER %02x --> %02x\n", + __func__, val, val2); + WR1(sc, HC_POWER, val2); + break; + case SDHCI_BLOCK_GAP_CONTROL: + dprintf("%s: SDHCI_BLOCK_GAP_CONTROL val=%02x\n", + __func__, val); + break; + case SDHCI_TIMEOUT_CONTROL: + dprintf("%s: SDHCI_TIMEOUT_CONTROL val=%02x\n", + __func__, val); + break; + case SDHCI_SOFTWARE_RESET: + dprintf("%s: SDHCI_SOFTWARE_RESET val=%02x\n", + __func__, val); + break; + case SDHCI_ADMA_ERR: + dprintf("%s: SDHCI_ADMA_ERR val=%02x\n", + __func__, val); + break; + default: + dprintf("%s: UNKNOWN off=%08lx val=%08x\n", + __func__, off, val); + break; + } + + mtx_unlock(&sc->mtx); +} + +static void +bcm_sdhost_write_2(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint16_t val) +{ + struct bcm_sdhost_softc *sc = device_get_softc(dev); + uint16_t val2; + + mtx_lock(&sc->mtx); + + switch (off) { + case SDHCI_BLOCK_SIZE: + dprintf("%s: SDHCI_BLOCK_SIZE val=%04x\n" , + __func__, val); + sc->sdhci_blocksize = val; + WR2(sc, HC_BLOCKSIZE, val); + break; + + case SDHCI_BLOCK_COUNT: + dprintf("%s: SDHCI_BLOCK_COUNT val=%04x\n" , + __func__, val); + sc->sdhci_blockcount = val; + WR2(sc, HC_BLOCKCOUNT, val); + break; + + case SDHCI_TRANSFER_MODE: + dprintf("%s: SDHCI_TRANSFER_MODE val=%04x\n" , + __func__, val); + break; + + case SDHCI_COMMAND_FLAGS: + bcm_sdhost_command(dev, slot, val); + break; + + case SDHCI_CLOCK_CONTROL: + val2 = (val & ~SDHCI_DIVIDER_MASK) >> SDHCI_DIVIDER_SHIFT; + /* get crc16 errors with cdiv=0 */ + if (val2 == 0) + val2 = 1; + dprintf("%s: SDHCI_CLOCK_CONTROL %04x --> SCDIV %04x\n", + __func__, val, val2); + WR4(sc, HC_CLOCKDIVISOR, val2); + break; + + case SDHCI_ACMD12_ERR: + dprintf("%s: SDHCI_ACMD12_ERR val=%04x\n" , + __func__, val); + break; + + case SDHCI_HOST_CONTROL2: + dprintf("%s: SDHCI_HOST_CONTROL2 val=%04x\n" , + __func__, val); + break; + + case SDHCI_SLOT_INT_STATUS: + dprintf("%s: SDHCI_SLOT_INT_STATUS val=%04x\n" , + __func__, val); + break; + + default: + dprintf("%s: UNKNOWN off=%08lx val=%04x\n", + __func__, off, val); + break; + } + + mtx_unlock(&sc->mtx); +} + +static void +bcm_sdhost_write_4(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint32_t val) +{ + struct bcm_sdhost_softc *sc = device_get_softc(dev); + uint32_t val2; + uint32_t hstcfg; + + mtx_lock(&sc->mtx); + + switch (off) { + case SDHCI_ARGUMENT: + val2 = val; + dprintf("%s: SDHCI_ARGUMENT --> HC_ARGUMENT val=%08x\n", + __func__, val); + WR4(sc, HC_ARGUMENT, val2); + break; + case SDHCI_INT_STATUS: + dprintf("%s: SDHCI_INT_STATUS val=%08x\n", + __func__, val); + sc->sdhci_int_status = val; + break; + case SDHCI_INT_ENABLE: + dprintf("%s: SDHCI_INT_ENABLE val=%08x\n" , + __func__, val); + break; + case SDHCI_SIGNAL_ENABLE: + sc->sdhci_signal_enable = val; + hstcfg = RD4(sc, HC_HOSTCONFIG); + if (val != 0) + hstcfg &= ~(HC_HSTCF_INT_BLOCK | HC_HSTCF_INT_DATA); + else + hstcfg |= (HC_HSTCF_INT_BUSY|HC_HSTCF_INT_BLOCK| + HC_HSTCF_INT_DATA); + hstcfg |= HC_HSTCF_INT_BUSY; + dprintf("%s: SDHCI_SIGNAL_ENABLE --> HC_HOSTC %08x --> %08x\n" , + __func__, val, hstcfg); + WR4(sc, HC_HOSTCONFIG, hstcfg); + break; + case SDHCI_CAPABILITIES: + dprintf("%s: SDHCI_CAPABILITIES val=%08x\n", + __func__, val); + break; + case SDHCI_CAPABILITIES2: + dprintf("%s: SDHCI_CAPABILITIES2 val=%08x\n", + __func__, val); + break; + case SDHCI_MAX_CURRENT: + dprintf("%s: SDHCI_MAX_CURRENT val=%08x\n", + __func__, val); + break; + case SDHCI_ADMA_ADDRESS_LO: + dprintf("%s: SDHCI_ADMA_ADDRESS_LO val=%08x\n", + __func__, val); + break; + default: + dprintf("%s: UNKNOWN off=%08lx val=%08x\n", + __func__, off, val); + break; + } + + mtx_unlock(&sc->mtx); +} + +static void +bcm_sdhost_write_multi_4(device_t dev, struct sdhci_slot *slot, + bus_size_t off, uint32_t *data, bus_size_t count) +{ + struct bcm_sdhost_softc *sc = device_get_softc(dev); + bus_size_t i; + bus_size_t space; + uint32_t edm; + + mtx_lock(&sc->mtx); + + dprintf("%s: off=%08lx count=%02lx\n", __func__, off, count); + + for (i = 0; i < count;) { + edm = RD4(sc, HC_DEBUG); + space = HC_FIFO_SIZE - ((edm >> 4) & 0x1f); + if (i + space > count) { + if (i >= count) + return; + else + space = count - i; + } + if (space > 0) + bus_space_write_multi_4(sc->sc_bst, sc->sc_bsh, + HC_DATAPORT, data + i, space); + i += space; + DELAY(1); + } + + /* wait until FIFO is really empty */ + while (((RD4(sc, HC_DEBUG) >> 4) & 0x1f) > 0) + DELAY(1); + + mtx_unlock(&sc->mtx); +} + +static device_method_t bcm_sdhost_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, bcm_sdhost_probe), + DEVMETHOD(device_attach, bcm_sdhost_attach), + DEVMETHOD(device_detach, bcm_sdhost_detach), + + /* Bus interface */ + DEVMETHOD(bus_read_ivar, sdhci_generic_read_ivar), + DEVMETHOD(bus_write_ivar, sdhci_generic_write_ivar), + + /* MMC bridge interface */ + DEVMETHOD(mmcbr_update_ios, sdhci_generic_update_ios), + DEVMETHOD(mmcbr_request, sdhci_generic_request), + DEVMETHOD(mmcbr_get_ro, bcm_sdhost_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, bcm_sdhost_read_1), + DEVMETHOD(sdhci_read_2, bcm_sdhost_read_2), + DEVMETHOD(sdhci_read_4, bcm_sdhost_read_4), + DEVMETHOD(sdhci_read_multi_4, bcm_sdhost_read_multi_4), + DEVMETHOD(sdhci_write_1, bcm_sdhost_write_1), + DEVMETHOD(sdhci_write_2, bcm_sdhost_write_2), + DEVMETHOD(sdhci_write_4, bcm_sdhost_write_4), + DEVMETHOD(sdhci_write_multi_4, bcm_sdhost_write_multi_4), + DEVMETHOD(sdhci_get_card_present,bcm_sdhost_get_card_present), + + DEVMETHOD_END +}; + +static devclass_t bcm_sdhost_devclass; + +static driver_t bcm_sdhost_driver = { + "sdhost_bcm", + bcm_sdhost_methods, + sizeof(struct bcm_sdhost_softc), +}; + +DRIVER_MODULE(sdhost_bcm, simplebus, bcm_sdhost_driver, bcm_sdhost_devclass, + NULL, NULL); +MODULE_DEPEND(sdhost_bcm, sdhci, 1, 1, 1); +#ifndef MMCCAM +MMC_DECLARE_BRIDGE(sdhost_bcm); +#endif Property changes on: head/sys/arm/broadcom/bcm2835/bcm2835_sdhost.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/arm/broadcom/bcm2835/files.bcm283x =================================================================== --- head/sys/arm/broadcom/bcm2835/files.bcm283x (revision 335778) +++ head/sys/arm/broadcom/bcm2835/files.bcm283x (revision 335779) @@ -1,45 +1,46 @@ # $FreeBSD$ arm/broadcom/bcm2835/bcm2835_bsc.c optional bcm2835_bsc arm/broadcom/bcm2835/bcm2835_cpufreq.c standard arm/broadcom/bcm2835/bcm2835_dma.c standard arm/broadcom/bcm2835/bcm2835_fb.c optional sc arm/broadcom/bcm2835/bcm2835_fbd.c optional vt arm/broadcom/bcm2835/bcm2835_ft5406.c optional evdev bcm2835_ft5406 arm/broadcom/bcm2835/bcm2835_gpio.c optional gpio arm/broadcom/bcm2835/bcm2835_intr.c standard arm/broadcom/bcm2835/bcm2835_machdep.c optional platform arm/broadcom/bcm2835/bcm2835_mbox.c standard arm/broadcom/bcm2835/bcm2835_rng.c optional random arm/broadcom/bcm2835/bcm2835_sdhci.c optional sdhci +arm/broadcom/bcm2835/bcm2835_sdhost.c optional sdhci arm/broadcom/bcm2835/bcm2835_spi.c optional bcm2835_spi arm/broadcom/bcm2835/bcm2835_vcio.c standard arm/broadcom/bcm2835/bcm2835_wdog.c standard arm/broadcom/bcm2835/bcm283x_dwc_fdt.c optional dwcotg fdt kern/kern_clocksource.c standard dev/mbox/mbox_if.m standard arm/broadcom/bcm2835/bcm2835_audio.c optional sound vchiq \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" # VideoCore driver contrib/vchiq/interface/compat/vchi_bsd.c optional vchiq \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c optional vchiq \ compile-with "${NORMAL_C} -Wno-unused -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_arm.c optional vchiq \ compile-with "${NORMAL_C} -Wno-unused -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_connected.c optional vchiq \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_core.c optional vchiq \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_kern_lib.c optional vchiq \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_kmod.c optional vchiq \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_shim.c optional vchiq \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_util.c optional vchiq \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" Index: head/sys/conf/files.arm64 =================================================================== --- head/sys/conf/files.arm64 (revision 335778) +++ head/sys/conf/files.arm64 (revision 335779) @@ -1,262 +1,263 @@ # $FreeBSD$ cloudabi32_vdso.o optional compat_cloudabi32 \ dependency "$S/contrib/cloudabi/cloudabi_vdso_armv6_on_64bit.S" \ compile-with "${CC} -x assembler-with-cpp -m32 -shared -nostdinc -nostdlib -Wl,-T$S/compat/cloudabi/cloudabi_vdso.lds $S/contrib/cloudabi/cloudabi_vdso_armv6_on_64bit.S -o ${.TARGET}" \ no-obj no-implicit-rule \ clean "cloudabi32_vdso.o" # cloudabi32_vdso_blob.o optional compat_cloudabi32 \ dependency "cloudabi32_vdso.o" \ compile-with "${OBJCOPY} --input-target binary --output-target elf64-littleaarch64 --binary-architecture aarch64 cloudabi32_vdso.o ${.TARGET}" \ no-implicit-rule \ clean "cloudabi32_vdso_blob.o" # cloudabi64_vdso.o optional compat_cloudabi64 \ dependency "$S/contrib/cloudabi/cloudabi_vdso_aarch64.S" \ compile-with "${CC} -x assembler-with-cpp -shared -nostdinc -nostdlib -Wl,-T$S/compat/cloudabi/cloudabi_vdso.lds $S/contrib/cloudabi/cloudabi_vdso_aarch64.S -o ${.TARGET}" \ no-obj no-implicit-rule \ clean "cloudabi64_vdso.o" # cloudabi64_vdso_blob.o optional compat_cloudabi64 \ dependency "cloudabi64_vdso.o" \ compile-with "${OBJCOPY} --input-target binary --output-target elf64-littleaarch64 --binary-architecture aarch64 cloudabi64_vdso.o ${.TARGET}" \ no-implicit-rule \ clean "cloudabi64_vdso_blob.o" # # Allwinner common files arm/allwinner/a10_ehci.c optional ehci aw_ehci fdt arm/allwinner/aw_gpio.c optional gpio aw_gpio fdt arm/allwinner/aw_mmc.c optional mmc aw_mmc fdt | mmccam aw_mmc fdt arm/allwinner/aw_nmi.c optional aw_nmi fdt \ compile-with "${NORMAL_C} -I$S/gnu/dts/include" arm/allwinner/aw_rsb.c optional aw_rsb fdt arm/allwinner/aw_rtc.c optional aw_rtc fdt arm/allwinner/aw_sid.c optional aw_sid fdt arm/allwinner/aw_spi.c optional aw_spi fdt arm/allwinner/aw_thermal.c optional aw_thermal fdt arm/allwinner/aw_usbphy.c optional ehci aw_usbphy fdt arm/allwinner/aw_wdog.c optional aw_wdog fdt arm/allwinner/axp81x.c optional axp81x fdt arm/allwinner/if_awg.c optional awg ext_resources syscon fdt # Allwinner clock driver arm/allwinner/clkng/aw_ccung.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_nkmp.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_nm.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_prediv_mux.c optional aw_ccu fdt arm/allwinner/clkng/ccu_a64.c optional soc_allwinner_a64 aw_ccu fdt arm/allwinner/clkng/ccu_h3.c optional soc_allwinner_h5 aw_ccu fdt arm/allwinner/clkng/ccu_sun8i_r.c optional aw_ccu fdt # Allwinner padconf files arm/allwinner/a64/a64_padconf.c optional soc_allwinner_a64 fdt arm/allwinner/a64/a64_r_padconf.c optional soc_allwinner_a64 fdt arm/allwinner/h3/h3_padconf.c optional soc_allwinner_h5 fdt arm/allwinner/h3/h3_r_padconf.c optional soc_allwinner_h5 fdt arm/annapurna/alpine/alpine_ccu.c optional al_ccu fdt arm/annapurna/alpine/alpine_nb_service.c optional al_nb_service fdt arm/annapurna/alpine/alpine_pci.c optional al_pci fdt arm/annapurna/alpine/alpine_pci_msix.c optional al_pci fdt arm/annapurna/alpine/alpine_serdes.c optional al_serdes fdt \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" arm/arm/generic_timer.c standard arm/arm/gic.c standard arm/arm/gic_acpi.c optional acpi arm/arm/gic_fdt.c optional fdt arm/arm/pmu.c standard arm/arm/physmem.c standard arm/broadcom/bcm2835/bcm2835_audio.c optional sound vchiq fdt \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" arm/broadcom/bcm2835/bcm2835_bsc.c optional bcm2835_bsc soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2835_cpufreq.c optional soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2835_dma.c optional soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2835_fbd.c optional vt soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2835_ft5406.c optional evdev bcm2835_ft5406 soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2835_gpio.c optional gpio soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2835_intr.c optional soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2835_mbox.c optional soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2835_rng.c optional random soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2835_sdhci.c optional sdhci soc_brcm_bcm2837 fdt +arm/broadcom/bcm2835/bcm2835_sdhost.c optional sdhci soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2835_spi.c optional bcm2835_spi soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2835_vcio.c optional soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2835_wdog.c optional soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2836.c optional soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm283x_dwc_fdt.c optional dwcotg fdt soc_brcm_bcm2837 arm/mv/armada38x/armada38x_rtc.c optional mv_rtc fdt arm64/acpica/acpi_machdep.c optional acpi arm64/acpica/OsdEnvironment.c optional acpi arm64/acpica/acpi_wakeup.c optional acpi arm64/acpica/pci_cfgreg.c optional acpi pci arm64/arm64/autoconf.c standard arm64/arm64/bus_machdep.c standard arm64/arm64/bus_space_asm.S standard arm64/arm64/busdma_bounce.c standard arm64/arm64/busdma_machdep.c standard arm64/arm64/bzero.S standard arm64/arm64/clock.c standard arm64/arm64/copyinout.S standard arm64/arm64/copystr.c standard arm64/arm64/cpu_errata.c standard arm64/arm64/cpufunc_asm.S standard arm64/arm64/db_disasm.c optional ddb arm64/arm64/db_interface.c optional ddb arm64/arm64/db_trace.c optional ddb arm64/arm64/debug_monitor.c optional ddb arm64/arm64/disassem.c optional ddb arm64/arm64/dump_machdep.c standard arm64/arm64/efirt_machdep.c optional efirt arm64/arm64/elf32_machdep.c optional compat_freebsd32 arm64/arm64/elf_machdep.c standard arm64/arm64/exception.S standard arm64/arm64/freebsd32_machdep.c optional compat_freebsd32 arm64/arm64/gicv3_its.c optional intrng fdt arm64/arm64/gic_v3.c standard arm64/arm64/gic_v3_acpi.c optional acpi arm64/arm64/gic_v3_fdt.c optional fdt arm64/arm64/identcpu.c standard arm64/arm64/in_cksum.c optional inet | inet6 arm64/arm64/locore.S standard no-obj arm64/arm64/machdep.c standard arm64/arm64/mem.c standard arm64/arm64/memcpy.S standard arm64/arm64/memmove.S standard arm64/arm64/minidump_machdep.c standard arm64/arm64/mp_machdep.c optional smp arm64/arm64/nexus.c standard arm64/arm64/ofw_machdep.c optional fdt arm64/arm64/pmap.c standard arm64/arm64/stack_machdep.c optional ddb | stack arm64/arm64/support.S standard arm64/arm64/swtch.S standard arm64/arm64/sys_machdep.c standard arm64/arm64/trap.c standard arm64/arm64/uio_machdep.c standard arm64/arm64/uma_machdep.c standard arm64/arm64/undefined.c standard arm64/arm64/unwind.c optional ddb | kdtrace_hooks | stack arm64/arm64/vfp.c standard arm64/arm64/vm_machdep.c standard arm64/cavium/thunder_pcie_fdt.c optional soc_cavm_thunderx pci fdt arm64/cavium/thunder_pcie_pem.c optional soc_cavm_thunderx pci arm64/cavium/thunder_pcie_pem_fdt.c optional soc_cavm_thunderx pci fdt arm64/cavium/thunder_pcie_common.c optional soc_cavm_thunderx pci arm64/cloudabi32/cloudabi32_sysvec.c optional compat_cloudabi32 arm64/cloudabi64/cloudabi64_sysvec.c optional compat_cloudabi64 arm64/coresight/coresight.c standard arm64/coresight/coresight_if.m standard arm64/coresight/coresight-cmd.c standard arm64/coresight/coresight-cpu-debug.c standard arm64/coresight/coresight-dynamic-replicator.c standard arm64/coresight/coresight-etm4x.c standard arm64/coresight/coresight-funnel.c standard arm64/coresight/coresight-tmc.c standard arm64/qualcomm/qcom_gcc.c optional qcom_gcc fdt contrib/vchiq/interface/compat/vchi_bsd.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -Wno-unused -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_arm.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -Wno-unused -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_connected.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_core.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_kern_lib.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_kmod.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_shim.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_util.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" crypto/armv8/armv8_crypto.c optional armv8crypto armv8_crypto_wrap.o optional armv8crypto \ dependency "$S/crypto/armv8/armv8_crypto_wrap.c" \ compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc:N-mgeneral-regs-only} ${WERROR} ${NO_WCAST_QUAL} ${PROF} -march=armv8-a+crypto ${.IMPSRC}" \ no-implicit-rule \ clean "armv8_crypto_wrap.o" crypto/blowfish/bf_enc.c optional crypto | ipsec | ipsec_support crypto/des/des_enc.c optional crypto | ipsec | ipsec_support | netsmb dev/acpica/acpi_bus_if.m optional acpi dev/acpica/acpi_if.m optional acpi dev/acpica/acpi_pci_link.c optional acpi pci dev/acpica/acpi_pcib.c optional acpi pci dev/ahci/ahci_generic.c optional ahci dev/axgbe/if_axgbe.c optional axgbe dev/axgbe/xgbe-desc.c optional axgbe dev/axgbe/xgbe-dev.c optional axgbe dev/axgbe/xgbe-drv.c optional axgbe dev/axgbe/xgbe-mdio.c optional axgbe dev/cpufreq/cpufreq_dt.c optional cpufreq fdt dev/iicbus/twsi/a10_twsi.c optional twsi fdt dev/iicbus/twsi/twsi.c optional twsi fdt dev/hwpmc/hwpmc_arm64.c optional hwpmc dev/hwpmc/hwpmc_arm64_md.c optional hwpmc dev/mbox/mbox_if.m optional soc_brcm_bcm2837 dev/mmc/host/dwmmc.c optional dwmmc fdt dev/mmc/host/dwmmc_hisi.c optional dwmmc fdt soc_hisi_hi6220 dev/mmc/host/dwmmc_rockchip.c optional dwmmc fdt soc_rockchip_rk3328 dev/neta/if_mvneta_fdt.c optional neta fdt dev/neta/if_mvneta.c optional neta mdio mii dev/ofw/ofw_cpu.c optional fdt dev/ofw/ofwpci.c optional fdt pci dev/pci/pci_host_generic.c optional pci dev/pci/pci_host_generic_acpi.c optional pci acpi dev/pci/pci_host_generic_fdt.c optional pci fdt dev/psci/psci.c standard dev/psci/psci_arm64.S standard dev/psci/smccc.c standard dev/uart/uart_cpu_arm64.c optional uart dev/uart/uart_dev_mu.c optional uart uart_mu dev/uart/uart_dev_pl011.c optional uart pl011 dev/usb/controller/dwc_otg_hisi.c optional dwcotg fdt soc_hisi_hi6220 dev/usb/controller/ehci_mv.c optional ehci_mv fdt dev/usb/controller/generic_ehci.c optional ehci acpi dev/usb/controller/generic_ohci.c optional ohci fdt dev/usb/controller/generic_usb_if.m optional ohci fdt dev/usb/controller/xhci_mv.c optional xhci_mv fdt dev/vnic/mrml_bridge.c optional vnic fdt dev/vnic/nic_main.c optional vnic pci dev/vnic/nicvf_main.c optional vnic pci pci_iov dev/vnic/nicvf_queues.c optional vnic pci pci_iov dev/vnic/thunder_bgx_fdt.c optional vnic fdt dev/vnic/thunder_bgx.c optional vnic pci dev/vnic/thunder_mdio_fdt.c optional vnic fdt dev/vnic/thunder_mdio.c optional vnic dev/vnic/lmac_if.m optional inet | inet6 | vnic kern/kern_clocksource.c standard kern/msi_if.m optional intrng kern/pic_if.m optional intrng kern/subr_devmap.c standard kern/subr_intr.c optional intrng libkern/bcmp.c standard libkern/ffs.c standard libkern/ffsl.c standard libkern/ffsll.c standard libkern/fls.c standard libkern/flsl.c standard libkern/flsll.c standard libkern/memset.c standard libkern/arm64/crc32c_armv8.S standard cddl/contrib/opensolaris/common/atomic/aarch64/opensolaris_atomic.S optional zfs | dtrace compile-with "${CDDL_C}" cddl/dev/dtrace/aarch64/dtrace_asm.S optional dtrace compile-with "${DTRACE_S}" cddl/dev/dtrace/aarch64/dtrace_subr.c optional dtrace compile-with "${DTRACE_C}" cddl/dev/fbt/aarch64/fbt_isa.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}" arm64/rockchip/rk_i2c.c optional rk_i2c fdt soc_rockchip_rk3328 arm64/rockchip/rk_grf.c optional fdt soc_rockchip_rk3328 arm64/rockchip/rk_pinctrl.c optional fdt soc_rockchip_rk3328 arm64/rockchip/rk_gpio.c optional fdt soc_rockchip_rk3328 arm64/rockchip/clk/rk_cru.c optional fdt soc_rockchip_rk3328 arm64/rockchip/clk/rk_clk_armclk.c optional fdt soc_rockchip_rk3328 arm64/rockchip/clk/rk_clk_composite.c optional fdt soc_rockchip_rk3328 arm64/rockchip/clk/rk_clk_gate.c optional fdt soc_rockchip_rk3328 arm64/rockchip/clk/rk_clk_mux.c optional fdt soc_rockchip_rk3328 arm64/rockchip/clk/rk_clk_pll.c optional fdt soc_rockchip_rk3328 arm64/rockchip/clk/rk3328_cru.c optional fdt soc_rockchip_rk3328 arm64/rockchip/if_dwc_rk.c optional dwc_rk fdt soc_rockchip_rk3328 dev/dwc/if_dwc.c optional dwc_rk dev/dwc/if_dwc_if.m optional dwc_rk