Module Name: src Committed By: jkunz Date: Sun Dec 16 19:45:52 UTC 2012
Modified Files: src/sys/arch/arm/imx: imx23_ssp.c src/sys/arch/evbarm/conf: IMX23_OLINUXINO Log Message: Contribution from Petri Laakso: Initial support for SD card controller. iMX233-OLinuXino can now boot and run from its own SD card. To generate a diff of this commit: cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/imx/imx23_ssp.c cvs rdiff -u -r1.1 -r1.2 src/sys/arch/evbarm/conf/IMX23_OLINUXINO Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/imx/imx23_ssp.c diff -u src/sys/arch/arm/imx/imx23_ssp.c:1.1 src/sys/arch/arm/imx/imx23_ssp.c:1.2 --- src/sys/arch/arm/imx/imx23_ssp.c:1.1 Tue Nov 20 19:06:14 2012 +++ src/sys/arch/arm/imx/imx23_ssp.c Sun Dec 16 19:45:52 2012 @@ -1,4 +1,4 @@ -/* $Id: imx23_ssp.c,v 1.1 2012/11/20 19:06:14 jkunz Exp $ */ +/* $Id: imx23_ssp.c,v 1.2 2012/12/16 19:45:52 jkunz Exp $ */ /* * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -33,15 +33,10 @@ #include <sys/types.h> #include <sys/bus.h> #include <sys/cdefs.h> -#include <sys/cpu.h> #include <sys/device.h> #include <sys/errno.h> #include <sys/systm.h> -#include <arm/pic/picvar.h> - -#include <arm/imx/imx23_apbdma.h> -#include <arm/imx/imx23_icollreg.h> #include <arm/imx/imx23_sspreg.h> #include <arm/imx/imx23var.h> @@ -50,7 +45,7 @@ #include <dev/sdmmc/sdmmcvar.h> /* - * SD/MMC host controller driver for i.MX233. + * SD/MMC host controller driver for i.MX23. */ struct issp_softc { @@ -65,7 +60,11 @@ static int issp_match(device_t, cfdata_t static void issp_attach(device_t, device_t, void *); static int issp_activate(device_t, enum devact); -/* sdmmc chip function prototypes. */ +static void issp_reset(struct issp_softc *); +static void issp_init(struct issp_softc *); +static uint32_t issp_set_sck(struct issp_softc *, uint32_t target); + +/* sdmmc(4) driver chip function prototypes. */ static int issp_host_reset(sdmmc_chipset_handle_t); static uint32_t issp_host_ocr(sdmmc_chipset_handle_t); static int issp_host_maxblklen(sdmmc_chipset_handle_t); @@ -80,23 +79,6 @@ static void issp_exec_command(sdmmc_chip static void issp_card_enable_intr(sdmmc_chipset_handle_t, int); static void issp_card_intr_ack(sdmmc_chipset_handle_t); -/* Used from the above callbacks. */ -static void issp_reset(struct issp_softc *); -static void issp_init(struct issp_softc *); -static uint32_t issp_set_sck(struct issp_softc *, uint32_t target); - -#define SSP_SOFT_RST_LOOP 455 /* At least 1 us ... */ - -CFATTACH_DECL3_NEW(ssp, - sizeof(struct issp_softc), - issp_match, - issp_attach, - NULL, - issp_activate, - NULL, - NULL, - 0); - static struct sdmmc_chip_functions issp_functions = { .host_reset = issp_host_reset, .host_ocr = issp_host_ocr, @@ -112,22 +94,45 @@ static struct sdmmc_chip_functions issp_ .card_intr_ack = issp_card_intr_ack }; -#define SSP_READ(sc, reg) \ +CFATTACH_DECL3_NEW(ssp, + sizeof(struct issp_softc), + issp_match, + issp_attach, + NULL, + issp_activate, + NULL, + NULL, + 0); + +#define SSP_SOFT_RST_LOOP 455 /* At least 1 us ... */ + +#define SSP_RD(sc, reg) \ bus_space_read_4(sc->sc_iot, sc->sc_hdl, (reg)) -#define SSP_WRITE(sc, reg, val) \ +#define SSP_WR(sc, reg, val) \ bus_space_write_4(sc->sc_iot, sc->sc_hdl, (reg), (val)) -#define SSP_CLK 96000000 /* CLK_SSP from PLL is 96 MHz */ -#define SSP_CLK_MIN 2 /* 2 kHz */ -#define SSP_CLK_MAX 48000 /* 48 MHz */ -/* SSP_CMD_TIMEOUT is calculated as (1.0/SSP_SCK)*(SSP_CMD_TIMEOUT*4096) */ -#define SSP_CMD_TIMEOUT 0xffff /* 2.8 seconds. */ -#define SSP_STATUS_ERR (HW_SSP_STATUS_RESP_CRC_ERR | \ +#define SSP_CLK 96000000 /* CLK_SSP from PLL is 96 MHz */ +#define SSP_CLK_MIN 400 /* 400 kHz */ +#define SSP_CLK_MAX 48000 /* 48 MHz */ + +#define SSP_BUSY (HW_SSP_STATUS_CMD_BUSY | \ + HW_SSP_STATUS_DATA_BUSY | \ + HW_SSP_STATUS_BUSY) + +#define SSP_RUN_ERR (HW_SSP_STATUS_RESP_CRC_ERR | \ HW_SSP_STATUS_RESP_ERR | \ HW_SSP_STATUS_RESP_TIMEOUT | \ HW_SSP_STATUS_DATA_CRC_ERR | \ HW_SSP_STATUS_TIMEOUT) +#define BLKIO_NONE 0 +#define BLKIO_RD 1 +#define BLKIO_WR 2 + +#define BUS_WIDTH_1_BIT 0x0 +#define BUS_WIDTH_4_BIT 0x1 +#define BUS_WIDTH_8_BIT 0x2 + static int issp_match(device_t parent, cfdata_t match, void *aux) { @@ -145,25 +150,18 @@ issp_match(device_t parent, cfdata_t mat static void issp_attach(device_t parent, device_t self, void *aux) { - static int issp_attached = 0; struct issp_softc *sc = device_private(self); - struct apb_softc *scp = device_private(parent); + struct apb_softc *sc_parent = device_private(parent); struct apb_attach_args *aa = aux; struct sdmmcbus_attach_args saa; - - + static int issp_attached = 0; + if (issp_attached) return; -//XXX: - if (scp == NULL) - printf("ISSP_ATTACH: scp == NULL\n"); - if (scp->dmac == NULL) - printf("ISSP_ATTACH: scp->dmac == NULL\n"); - sc->sc_dev = self; sc->sc_iot = aa->aa_iot; - sc->dmac = scp->dmac; + sc->dmac = sc_parent->dmac; if (bus_space_map(sc->sc_iot, aa->aa_addr, aa->aa_size, 0, &(sc->sc_hdl))) { @@ -172,9 +170,9 @@ issp_attach(device_t parent, device_t se } issp_reset(sc); - issp_init(sc); + issp_init(sc); - uint32_t issp_vers = SSP_READ(sc, HW_SSP_VERSION); + uint32_t issp_vers = SSP_RD(sc, HW_SSP_VERSION); aprint_normal(": SSP Block v%" __PRIuBIT ".%" __PRIuBIT "\n", __SHIFTOUT(issp_vers, HW_SSP_VERSION_MAJOR), __SHIFTOUT(issp_vers, HW_SSP_VERSION_MINOR)); @@ -186,7 +184,8 @@ issp_attach(device_t parent, device_t se saa.saa_dmat = aa->aa_dmat; saa.saa_clkmin = SSP_CLK_MIN; saa.saa_clkmax = SSP_CLK_MAX; - saa.saa_caps = SMC_CAPS_4BIT_MODE | SMC_CAPS_DMA; + /* Add SMC_CAPS_DMA capability when DMA funtionality is implemented. */ + saa.saa_caps = SMC_CAPS_4BIT_MODE | SMC_CAPS_SINGLE_ONLY; sc->sc_sdmmc = config_found(sc->sc_dev, &saa, NULL); if (sc->sc_sdmmc == NULL) { @@ -228,7 +227,6 @@ issp_host_ocr(sdmmc_chipset_handle_t sch static int issp_host_maxblklen(sdmmc_chipset_handle_t sch) { - /* XXX: This value was made up. */ return 512; } @@ -242,10 +240,10 @@ issp_card_detect(sdmmc_chipset_handle_t /* struct issp_softc *sc = sch; * * In the perfect world I'll just: - * return SSP_READ(sc, HW_SSP_STATUS) & HW_SSP_STATUS_CARD_DETECT; + * return SSP_RD(sc, HW_SSP_STATUS) & HW_SSP_STATUS_CARD_DETECT; * and call it a day. * - * But on i.MX233 OLinuXino MAXI, SSP1_DETECT is not used for the SD + * But on i.MX23 OLinuXino MAXI, SSP1_DETECT is not used for the SD * card detection but SSP1_DATA3 is, as Tsvetan put it: * * < Tsvetan> if you want to know if SD card is inserted watch @@ -258,7 +256,7 @@ issp_card_detect(sdmmc_chipset_handle_t * #if BOARDTYPE == MAXI (Possibly MINI & MICRO) * return GPIO_READ(PIN_125) & PIN_125 * #else - * return SSP_READ(sc, STATUS) & CARD_DETECT; + * return SSP_RD(sc, STATUS) & CARD_DETECT; * #endif * Until GPIO functionality is not present I am just going to */ @@ -273,9 +271,9 @@ issp_write_protect(sdmmc_chipset_handle_ } static int -issp_bus_power(sdmmc_chipset_handle_t sch, uint32_t power) +issp_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr) { - /* i.MX233 does not support setting bus power. */ + /* i.MX23 SSP does not support setting bus power. */ return 0; } @@ -285,9 +283,13 @@ issp_bus_clock(sdmmc_chipset_handle_t sc struct issp_softc *sc = sch; uint32_t sck; - aprint_normal_dev(sc->sc_dev, "requested clock %d Hz", clock * 1000); sck = issp_set_sck(sc, clock * 1000); - aprint_normal(", got %d Hz\n", sck); + + /* Notify user if we didn't get exact clock rate from SSP that was + * requested. */ + if (sck != clock * 1000) + aprint_normal_dev(sc->sc_dev, "requested clock %dHz, " + "but got %dHz\n", clock * 1000, sck); return 0; } @@ -295,8 +297,29 @@ issp_bus_clock(sdmmc_chipset_handle_t sc static int issp_bus_width(sdmmc_chipset_handle_t sch, int width) { - /* Return error if other than 4-bit width is requested. */ - return width - 4; + struct issp_softc *sc = sch; + uint32_t reg; + + reg = SSP_RD(sc, HW_SSP_CTRL0); + reg &= ~(HW_SSP_CTRL0_BUS_WIDTH); + + switch(width) { + case(1): + reg |= __SHIFTIN(BUS_WIDTH_1_BIT, HW_SSP_CTRL0_BUS_WIDTH); + break; + case(4): + reg |= __SHIFTIN(BUS_WIDTH_4_BIT, HW_SSP_CTRL0_BUS_WIDTH); + break; + case(8): + reg |= __SHIFTIN(BUS_WIDTH_8_BIT, HW_SSP_CTRL0_BUS_WIDTH); + break; + default: + return 1; + } + + SSP_WR(sc, HW_SSP_CTRL0, reg); + + return 0; } static int @@ -311,60 +334,130 @@ issp_exec_command(sdmmc_chipset_handle_t { struct issp_softc *sc = sch; uint32_t reg; + uint32_t do_blkio; + uint32_t i; + + do_blkio = 0; - /* Set excepted response type. */ - SSP_WRITE(sc, HW_SSP_CTRL0_CLR, + /* Wait until SSP done. (data I/O error + retry...) */ + while (SSP_RD(sc, HW_SSP_STATUS) & SSP_BUSY) + ; + + /* Set expected response type. */ + SSP_WR(sc, HW_SSP_CTRL0_CLR, HW_SSP_CTRL0_GET_RESP | HW_SSP_CTRL0_LONG_RESP); if (ISSET(cmd->c_flags, SCF_RSP_PRESENT)) { - SSP_WRITE(sc, HW_SSP_CTRL0_SET, HW_SSP_CTRL0_GET_RESP); + SSP_WR(sc, HW_SSP_CTRL0_SET, HW_SSP_CTRL0_GET_RESP); if (ISSET(cmd->c_flags, SCF_RSP_136)) - SSP_WRITE(sc, HW_SSP_CTRL0_SET, HW_SSP_CTRL0_LONG_RESP); + SSP_WR(sc, HW_SSP_CTRL0_SET, HW_SSP_CTRL0_LONG_RESP); } /* If CMD does not need CRC validation, tell it to SSP. */ if (ISSET(cmd->c_flags, SCF_RSP_CRC)) - SSP_WRITE(sc, HW_SSP_CTRL0_CLR, HW_SSP_CTRL0_IGNORE_CRC); + SSP_WR(sc, HW_SSP_CTRL0_CLR, HW_SSP_CTRL0_IGNORE_CRC); else - SSP_WRITE(sc, HW_SSP_CTRL0_SET, HW_SSP_CTRL0_IGNORE_CRC); + SSP_WR(sc, HW_SSP_CTRL0_SET, HW_SSP_CTRL0_IGNORE_CRC); /* Set command. */ - SSP_WRITE(sc, HW_SSP_CMD0_CLR, HW_SSP_CMD0_CMD); - SSP_WRITE(sc, HW_SSP_CMD0_SET, + SSP_WR(sc, HW_SSP_CMD0_CLR, HW_SSP_CMD0_CMD); + SSP_WR(sc, HW_SSP_CMD0_SET, __SHIFTIN(cmd->c_opcode, HW_SSP_CMD0_CMD)); /* Set command argument. */ - SSP_WRITE(sc, HW_SSP_CMD1, cmd->c_arg); + SSP_WR(sc, HW_SSP_CMD1, cmd->c_arg); + + /* Is data to be transferred? */ + if (cmd->c_datalen > 0 && cmd->c_data != NULL) { + SSP_WR(sc, HW_SSP_CTRL0_SET, HW_SSP_CTRL0_DATA_XFER); + /* Transfer XFER_COUNT of 8-bit words. */ + SSP_WR(sc, HW_SSP_CTRL0_CLR, HW_SSP_CTRL0_XFER_COUNT); + SSP_WR(sc, HW_SSP_CTRL0_SET, + __SHIFTIN(cmd->c_datalen, HW_SSP_CTRL0_XFER_COUNT)); + + /* XXX: why 8CYC? Bit is never cleaned. */ + SSP_WR(sc, HW_SSP_CMD0_SET, HW_SSP_CMD0_APPEND_8CYC); + + if (ISSET(cmd->c_flags, SCF_CMD_READ)) { + /* Read mode. */ + do_blkio |= BLKIO_RD; + SSP_WR(sc, HW_SSP_CTRL0_SET, HW_SSP_CTRL0_READ); + } else { + /* Write mode. */ + do_blkio |= BLKIO_WR; + SSP_WR(sc, HW_SSP_CTRL0_CLR, HW_SSP_CTRL0_READ); + } + } else { + /* No data to be transferred. */ + SSP_WR(sc, HW_SSP_CTRL0_CLR, HW_SSP_CTRL0_DATA_XFER); + } /* Run the command. */ - SSP_WRITE(sc, HW_SSP_CTRL0_SET, HW_SSP_CTRL0_RUN); + SSP_WR(sc, HW_SSP_CTRL0_SET, HW_SSP_CTRL0_RUN); - /* Wait until SSP has processed the command. */ - while (SSP_READ(sc, HW_SSP_STATUS) & - (HW_SSP_STATUS_CMD_BUSY | HW_SSP_STATUS_BUSY)) - ; - - /* Check if the command ran without errors. */ - reg = SSP_READ(sc, HW_SSP_STATUS); - - if (reg & SSP_STATUS_ERR) - cmd->c_error = reg & SSP_STATUS_ERR; + if (ISSET(do_blkio, BLKIO_RD)) { + for (i = 0; i < cmd->c_datalen / 4; i++) { + /* Wait until data arrives to FIFO. */ + while (SSP_RD(sc, HW_SSP_STATUS) + & HW_SSP_STATUS_FIFO_EMPTY) { + /* Abort if error while waiting. */ + if (SSP_RD(sc, HW_SSP_STATUS) & SSP_RUN_ERR) { + aprint_normal_dev(sc->sc_dev, + "RD_ERR: %x\n", + SSP_RD(sc, HW_SSP_STATUS)); + cmd->c_error = 1; + goto pioerr; + } + } + *((uint32_t *)cmd->c_data+i) = SSP_RD(sc, HW_SSP_DATA); + } + } else if (ISSET(do_blkio, BLKIO_WR)) { + for (i = 0; i < (cmd->c_datalen / 4); i++) { + while (SSP_RD(sc, HW_SSP_STATUS) + & HW_SSP_STATUS_FIFO_FULL) { + /* Abort if error while waiting. */ + if (SSP_RD(sc, HW_SSP_STATUS) & SSP_RUN_ERR) { + aprint_normal_dev(sc->sc_dev, + "WR_ERR: %x\n", + SSP_RD(sc, HW_SSP_STATUS)); + cmd->c_error = 1; + goto pioerr; + } + } + SSP_WR(sc, HW_SSP_DATA, *((uint32_t *)cmd->c_data+i)); + } + } + + /* Wait until SSP is done. */ + while (SSP_RD(sc, HW_SSP_STATUS) & SSP_BUSY) + ; + + /* Check if the command ran successfully. */ + reg = SSP_RD(sc, HW_SSP_STATUS); + if (reg & SSP_RUN_ERR) + cmd->c_error = reg & SSP_RUN_ERR; /* Read response if such was requested. */ if (ISSET(cmd->c_flags, SCF_RSP_PRESENT)) { - cmd->c_resp[0] = SSP_READ(sc, HW_SSP_SDRESP0); + cmd->c_resp[0] = SSP_RD(sc, HW_SSP_SDRESP0); if (ISSET(cmd->c_flags, SCF_RSP_136)) { - cmd->c_resp[1] = SSP_READ(sc, HW_SSP_SDRESP1); - cmd->c_resp[2] = SSP_READ(sc, HW_SSP_SDRESP2); - cmd->c_resp[3] = SSP_READ(sc, HW_SSP_SDRESP3); + cmd->c_resp[1] = SSP_RD(sc, HW_SSP_SDRESP1); + cmd->c_resp[2] = SSP_RD(sc, HW_SSP_SDRESP2); + cmd->c_resp[3] = SSP_RD(sc, HW_SSP_SDRESP3); + /* + * Remove CRC7 + LSB by rotating all bits right by 8 to + * make sdmmc __bitfield() happy. + */ + cmd->c_resp[0] >>= 8; /* Remove CRC7 + LSB. */ + cmd->c_resp[0] |= (0x000000FF & cmd->c_resp[1]) << 24; + cmd->c_resp[1] >>= 8; + cmd->c_resp[1] |= (0x000000FF & cmd->c_resp[2]) << 24; + cmd->c_resp[2] >>= 8; + cmd->c_resp[2] |= (0x000000FF & cmd->c_resp[3]) << 24; + cmd->c_resp[3] >>= 8; } } - -/* - apbdma_dmamem_alloc() - apbdma_do_dma() - wait_until_done() -*/ +pioerr: return; } @@ -374,7 +467,7 @@ issp_card_enable_intr(sdmmc_chipset_hand struct issp_softc *sc = sch; aprint_normal_dev(sc->sc_dev, - "issp_card_enable_intr NOT IMPLEMENTED!\n"); + "issp_card_enable_intr NOT IMPLEMENTED!\n"); return; } @@ -392,7 +485,7 @@ issp_card_intr_ack(sdmmc_chipset_handle_ /* * Reset the SSP block. * - * Inspired by i.MX233 RM "39.3.10 Correct Way to Soft Reset a Block" + * Inspired by i.MX23 RM "39.3.10 Correct Way to Soft Reset a Block" */ static void issp_reset(struct issp_softc *sc) @@ -402,65 +495,77 @@ issp_reset(struct issp_softc *sc) /* Prepare for soft-reset by making sure that SFTRST is not currently * asserted. Also clear CLKGATE so we can wait for its assertion below. */ - SSP_WRITE(sc, HW_SSP_CTRL0_CLR, HW_SSP_CTRL0_SFTRST); + SSP_WR(sc, HW_SSP_CTRL0_CLR, HW_SSP_CTRL0_SFTRST); /* Wait at least a microsecond for SFTRST to deassert. */ loop = 0; - while ((SSP_READ(sc, HW_SSP_CTRL0) & HW_SSP_CTRL0_SFTRST) || + while ((SSP_RD(sc, HW_SSP_CTRL0) & HW_SSP_CTRL0_SFTRST) || (loop < SSP_SOFT_RST_LOOP)) loop++; /* Clear CLKGATE so we can wait for its assertion below. */ - SSP_WRITE(sc, HW_SSP_CTRL0_CLR, HW_SSP_CTRL0_CLKGATE); + SSP_WR(sc, HW_SSP_CTRL0_CLR, HW_SSP_CTRL0_CLKGATE); /* Soft-reset the block. */ - SSP_WRITE(sc, HW_SSP_CTRL0_SET, HW_SSP_CTRL0_SFTRST); + SSP_WR(sc, HW_SSP_CTRL0_SET, HW_SSP_CTRL0_SFTRST); /* Wait until clock is in the gated state. */ - while (!(SSP_READ(sc, HW_SSP_CTRL0) & HW_SSP_CTRL0_CLKGATE)); + while (!(SSP_RD(sc, HW_SSP_CTRL0) & HW_SSP_CTRL0_CLKGATE)); /* Bring block out of reset. */ - SSP_WRITE(sc, HW_SSP_CTRL0_CLR, HW_SSP_CTRL0_SFTRST); + SSP_WR(sc, HW_SSP_CTRL0_CLR, HW_SSP_CTRL0_SFTRST); loop = 0; - while ((SSP_READ(sc, HW_SSP_CTRL0) & HW_SSP_CTRL0_SFTRST) || + while ((SSP_RD(sc, HW_SSP_CTRL0) & HW_SSP_CTRL0_SFTRST) || (loop < SSP_SOFT_RST_LOOP)) loop++; - SSP_WRITE(sc, HW_SSP_CTRL0_CLR, HW_SSP_CTRL0_CLKGATE); - + SSP_WR(sc, HW_SSP_CTRL0_CLR, HW_SSP_CTRL0_CLKGATE); + /* Wait until clock is in the NON-gated state. */ - while (SSP_READ(sc, HW_SSP_CTRL0) & HW_SSP_CTRL0_CLKGATE); + while (SSP_RD(sc, HW_SSP_CTRL0) & HW_SSP_CTRL0_CLKGATE); return; } + /* - * Initialize common options. + * DATA_TIMEOUT is calculated as: + * (1 / SSP_CLK) * (DATA_TIMEOUT * 4096) + */ +#define DATA_TIMEOUT 0x4240 /* 723ms */ + +/* + * Initialize SSP controller to SD/MMC mode. */ static void issp_init(struct issp_softc *sc) { uint32_t reg; - /* Initialize SD/MMC controller. */ - reg = SSP_READ(sc, HW_SSP_CTRL0); + /* Initial data bus width is 1-bit. */ + reg = SSP_RD(sc, HW_SSP_CTRL0); reg &= ~(HW_SSP_CTRL0_BUS_WIDTH); - reg |= __SHIFTIN(0x1, HW_SSP_CTRL0_BUS_WIDTH) | HW_SSP_CTRL0_ENABLE; - SSP_WRITE(sc, HW_SSP_CTRL0, reg); + reg |= __SHIFTIN(BUS_WIDTH_1_BIT, HW_SSP_CTRL0_BUS_WIDTH) | + HW_SSP_CTRL0_WAIT_FOR_IRQ | HW_SSP_CTRL0_ENABLE; + SSP_WR(sc, HW_SSP_CTRL0, reg); - reg = SSP_READ(sc, HW_SSP_CTRL1); + /* Set data timeout. */ + reg = SSP_RD(sc, HW_SSP_TIMING); + reg &= ~(HW_SSP_TIMING_TIMEOUT); + reg |= __SHIFTIN(DATA_TIMEOUT, HW_SSP_TIMING_TIMEOUT); + + /* Set initial clock rate to minimum. */ + issp_set_sck(sc, SSP_CLK_MIN * 1000); + + SSP_WR(sc, HW_SSP_TIMING, reg); + /* Enable SD/MMC mode and use use 8-bits per word. */ + reg = SSP_RD(sc, HW_SSP_CTRL1); reg &= ~(HW_SSP_CTRL1_WORD_LENGTH | HW_SSP_CTRL1_SSP_MODE); reg |= HW_SSP_CTRL1_POLARITY | __SHIFTIN(0x7, HW_SSP_CTRL1_WORD_LENGTH) | __SHIFTIN(0x3, HW_SSP_CTRL1_SSP_MODE); - SSP_WRITE(sc, HW_SSP_CTRL1, reg); - - /* Set command timeout. */ - reg = SSP_READ(sc, HW_SSP_TIMING); - reg &= ~(HW_SSP_TIMING_TIMEOUT); - reg |= __SHIFTIN(SSP_CMD_TIMEOUT, HW_SSP_TIMING_TIMEOUT); - SSP_WRITE(sc, HW_SSP_TIMING, reg); + SSP_WR(sc, HW_SSP_CTRL1, reg); return; } @@ -499,11 +604,11 @@ issp_set_sck(struct issp_softc *sc, uint } } out: - reg = SSP_READ(sc, HW_SSP_TIMING); + reg = SSP_RD(sc, HW_SSP_TIMING); reg &= ~(HW_SSP_TIMING_CLOCK_DIVIDE | HW_SSP_TIMING_CLOCK_RATE); reg |= __SHIFTIN(div, HW_SSP_TIMING_CLOCK_DIVIDE) | __SHIFTIN(rate, HW_SSP_TIMING_CLOCK_RATE); - SSP_WRITE(sc, HW_SSP_TIMING, reg); + SSP_WR(sc, HW_SSP_TIMING, reg); - return SSP_CLK / (d * (1 + r)); + return SSP_CLK / (div * (1 + rate)); } Index: src/sys/arch/evbarm/conf/IMX23_OLINUXINO diff -u src/sys/arch/evbarm/conf/IMX23_OLINUXINO:1.1 src/sys/arch/evbarm/conf/IMX23_OLINUXINO:1.2 --- src/sys/arch/evbarm/conf/IMX23_OLINUXINO:1.1 Tue Nov 20 19:08:45 2012 +++ src/sys/arch/evbarm/conf/IMX23_OLINUXINO Sun Dec 16 19:45:52 2012 @@ -1,4 +1,4 @@ -# $Id: IMX23_OLINUXINO,v 1.1 2012/11/20 19:08:45 jkunz Exp $ +# $Id: IMX23_OLINUXINO,v 1.2 2012/12/16 19:45:52 jkunz Exp $ # # IMX23_OLINUXINO -- Olimex i.MX23 OLinuXino kernel configuration file. # @@ -7,7 +7,7 @@ include "arch/evbarm/conf/std.imx23_olin maxusers 8 -config netbsd root on ? type ? +config netbsd root on ld0a type ? # The main bus device mainbus0 at root @@ -25,9 +25,9 @@ apbh0 at mainbus? base 0x80000000 size icoll0 at apbh? addr 0x80000000 size 0x2000 irq -1 # Synchronous serial port for SD/MMC -#ssp0 at apbh? addr 0x80010000 size 0x2000 irq 15 -#sdmmc* at ssp? -#ld* at sdmmc? +ssp0 at apbh? addr 0x80010000 size 0x2000 irq 15 +sdmmc* at ssp? +ld* at sdmmc? # APBX bus apbx0 at mainbus? base 0x80040000 size 0x00040000 @@ -47,11 +47,7 @@ options MEMSIZE=64 options DDB options HZ=100 -options MEMORY_DISK_HOOKS -options MEMORY_DISK_IS_ROOT -options MEMORY_DISK_ROOT_SIZE=12288 # 6 megs -options MEMORY_DISK_RBFLAGS=RB_SINGLE - -pseudo-device md - file-system FFS +file-system EXT2FS +file-system MSDOSFS +