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
+