at91_mci: Port to RTEMS and adapt for atsam.

This commit is contained in:
Christian Mauderer 2017-11-07 16:17:55 +01:00 committed by Sebastian Huber
parent ea5880a3cc
commit ec29b2a0c2
6 changed files with 308 additions and 2 deletions

View File

@ -32,7 +32,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <rtems/bsd/sys/param.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/endian.h>
@ -65,6 +65,19 @@ __FBSDID("$FreeBSD$");
#include <rtems/bsd/local/opt_at91.h>
#ifdef __rtems__
#include <bsp.h>
#endif /* __rtems__ */
#if defined(__rtems) && defined(LIBBSP_ARM_ATSAM_BSP_H)
#ifdef __rtems__
#include <libchip/chip.h>
#define AT91_MCI_HAS_4WIRE 1
uint32_t at91_master_clock = BOARD_MCK;
static sXdmad *pXdmad = &XDMAD_Instance;
#endif /* __rtems__ */
/*
* About running the MCI bus above 25MHz
*
@ -159,6 +172,14 @@ struct at91_mci_softc {
uint32_t bbuf_len[BBCOUNT]; /* len currently queued for bounce buf */
uint32_t bbuf_curidx; /* which bbuf is the active DMA buffer */
uint32_t xfer_offset; /* offset so far into caller's buf */
#ifdef __rtems__
uint32_t xdma_tx_channel;
uint32_t xdma_rx_channel;
uint8_t xdma_tx_perid;
uint8_t xdma_rx_perid;
sXdmadCfg xdma_tx_cfg;
sXdmadCfg xdma_rx_cfg;
#endif /* __rtems__ */
};
/* bus entry points */
@ -171,6 +192,10 @@ static void at91_mci_intr(void *);
static int at91_mci_activate(device_t dev);
static void at91_mci_deactivate(device_t dev);
static int at91_mci_is_mci1rev2xx(void);
#ifdef __rtems__
static void at91_mci_read_done(struct at91_mci_softc *sc, uint32_t sr);
static void at91_mci_write_done(struct at91_mci_softc *sc, uint32_t sr);
#endif /* __rtems__ */
#define AT91_MCI_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
#define AT91_MCI_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
@ -241,6 +266,7 @@ at91_mci_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
static void
at91_mci_pdc_disable(struct at91_mci_softc *sc)
{
#ifndef __rtems__
WR4(sc, PDC_PTCR, PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS);
WR4(sc, PDC_RPR, 0);
WR4(sc, PDC_RCR, 0);
@ -250,6 +276,12 @@ at91_mci_pdc_disable(struct at91_mci_softc *sc)
WR4(sc, PDC_TCR, 0);
WR4(sc, PDC_TNPR, 0);
WR4(sc, PDC_TNCR, 0);
#else /* __rtems__ */
/* On SAMV71 there is no PDC but a DMAC */
XDMAD_StopTransfer(pXdmad, sc->xdma_rx_channel);
XDMAD_StopTransfer(pXdmad, sc->xdma_tx_channel);
WR4(sc, MCI_DMA, 0);
#endif /* __rtems__ */
}
/*
@ -271,7 +303,11 @@ static void at91_mci_reset(struct at91_mci_softc *sc)
/* save current state */
imr = RD4(sc, MCI_IMR);
#ifndef __rtems__
mr = RD4(sc, MCI_MR) & 0x7fff;
#else /* __rtems__ */
mr = RD4(sc, MCI_MR);
#endif /* __rtems__ */
sdcr = RD4(sc, MCI_SDCR);
dtor = RD4(sc, MCI_DTOR);
@ -305,7 +341,12 @@ at91_mci_init(device_t dev)
WR4(sc, MCI_CR, MCI_CR_MCIDIS | MCI_CR_SWRST); /* device into reset */
WR4(sc, MCI_IDR, 0xffffffff); /* Turn off interrupts */
WR4(sc, MCI_DTOR, MCI_DTOR_DTOMUL_1M | 1);
#ifndef __rtems__
val = MCI_MR_PDCMODE;
#else /* __rtems__ */
val = 0;
val |= MCI_MR_RDPROOF | MCI_MR_WRPROOF;
#endif /* __rtems__ */
val |= 0x34a; /* PWSDIV = 3; CLKDIV = 74 */
// if (sc->sc_cap & CAP_MCI1_REV2XX)
// val |= MCI_MR_RDPROOF | MCI_MR_WRPROOF;
@ -358,13 +399,22 @@ at91_mci_attach(device_t dev)
device_t child;
int err, i;
#ifdef __rtems__
#ifdef LIBBSP_ARM_ATSAM_BSP_H
PMC_EnablePeripheral(ID_HSMCI);
sc->xdma_tx_channel = XDMAD_ALLOC_FAILED;
sc->xdma_rx_channel = XDMAD_ALLOC_FAILED;
#endif /* LIBBSP_ARM_ATSAM_BSP_H */
#endif /* __rtems__ */
sctx = device_get_sysctl_ctx(dev);
soid = device_get_sysctl_tree(dev);
sc->dev = dev;
sc->sc_cap = 0;
#ifndef __rtems__
if (at91_is_rm92())
sc->sc_cap |= CAP_NEEDS_BYTESWAP;
#endif /* __rtems__ */
/*
* MCI1 Rev 2 controllers need some workarounds, flag if so.
*/
@ -375,6 +425,57 @@ at91_mci_attach(device_t dev)
if (err)
goto out;
#ifdef __rtems__
eXdmadRC rc;
/* Prepare some configurations so they don't have to be fetched on every
* setup */
sc->xdma_rx_perid = XDMAIF_Get_ChannelNumber(ID_HSMCI,
XDMAD_TRANSFER_RX);
sc->xdma_tx_perid = XDMAIF_Get_ChannelNumber(ID_HSMCI,
XDMAD_TRANSFER_TX);
memset(&sc->xdma_rx_cfg, 0, sizeof(sc->xdma_rx_cfg));
sc->xdma_rx_cfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
XDMAC_CC_MBSIZE_SINGLE | XDMAC_CC_DSYNC_PER2MEM |
XDMAC_CC_SWREQ_HWR_CONNECTED | XDMAC_CC_MEMSET_NORMAL_MODE |
XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_WORD |
XDMAC_CC_SIF_AHB_IF1 | XDMAC_CC_DIF_AHB_IF1 |
XDMAC_CC_SAM_FIXED_AM | XDMAC_CC_DAM_INCREMENTED_AM |
XDMAC_CC_PERID(
XDMAIF_Get_ChannelNumber(ID_HSMCI,XDMAD_TRANSFER_RX));
memset(&sc->xdma_tx_cfg, 0, sizeof(sc->xdma_tx_cfg));
sc->xdma_tx_cfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
XDMAC_CC_MBSIZE_SINGLE | XDMAC_CC_DSYNC_MEM2PER |
XDMAC_CC_SWREQ_HWR_CONNECTED | XDMAC_CC_MEMSET_NORMAL_MODE |
XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_WORD |
XDMAC_CC_SIF_AHB_IF1 | XDMAC_CC_DIF_AHB_IF1 |
XDMAC_CC_SAM_INCREMENTED_AM | XDMAC_CC_DAM_FIXED_AM |
XDMAC_CC_PERID(
XDMAIF_Get_ChannelNumber(ID_HSMCI,XDMAD_TRANSFER_TX));
sc->xdma_tx_channel = XDMAD_AllocateChannel(pXdmad,
XDMAD_TRANSFER_MEMORY, ID_HSMCI);
if (sc->xdma_tx_channel == XDMAD_ALLOC_FAILED)
goto out;
/* FIXME: The two DMA channels are not really necessary for the driver.
* But the XDMAD interface does not allow to allocate one and use it
* into two directions. The current (2017-07-11) implementation of
* the XDMAD interface should work with it. So we might could try it. */
sc->xdma_rx_channel = XDMAD_AllocateChannel(pXdmad, ID_HSMCI,
XDMAD_TRANSFER_MEMORY);
if (sc->xdma_rx_channel == XDMAD_ALLOC_FAILED)
goto out;
rc = XDMAD_PrepareChannel(pXdmad, sc->xdma_rx_channel);
if (rc != XDMAD_OK)
goto out;
rc = XDMAD_PrepareChannel(pXdmad, sc->xdma_tx_channel);
if (rc != XDMAD_OK)
goto out;
#endif /* __rtems__ */
AT91_MCI_LOCK_INIT(sc);
at91_mci_fini(dev);
@ -527,6 +628,14 @@ at91_mci_deactivate(device_t dev)
bus_release_resource(dev, SYS_RES_IRQ,
rman_get_rid(sc->irq_res), sc->irq_res);
sc->irq_res = NULL;
#ifdef __rtems__
if (sc->xdma_rx_channel != XDMAD_ALLOC_FAILED) {
XDMAD_FreeChannel(pXdmad, sc->xdma_rx_channel);
}
if (sc->xdma_tx_channel != XDMAD_ALLOC_FAILED) {
XDMAD_FreeChannel(pXdmad, sc->xdma_tx_channel);
}
#endif /* __rtems__ */
return;
}
@ -534,6 +643,7 @@ static int
at91_mci_is_mci1rev2xx(void)
{
#ifndef __rtems__
switch (soc_info.type) {
case AT91_T_SAM9260:
case AT91_T_SAM9263:
@ -545,6 +655,10 @@ at91_mci_is_mci1rev2xx(void)
default:
return (0);
}
#else /* __rtems__ */
/* Currently only supports the SAM V71 */
return (1);
#endif /* __rtems__ */
}
static int
@ -598,10 +712,81 @@ at91_mci_update_ios(device_t brdev, device_t reqdev)
return (0);
}
#ifdef __rtems__
static LinkedListDescriporView1 dma_desc[MAX_BLOCKS];
static void
at91_mci_setup_xdma(struct at91_mci_softc *sc, bool read, uint32_t block_size,
uint32_t number_blocks, bus_addr_t paddr, uint32_t len)
{
sXdmadCfg *xdma_cfg;
uint32_t xdma_channel;
const uint32_t xdma_cndc = XDMAC_CNDC_NDVIEW_NDV1 |
XDMAC_CNDC_NDE_DSCR_FETCH_EN |
XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED |
XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED;
const uint32_t sa_rdr = (uint32_t)(sc->mem_res->r_bushandle + MCI_RDR);
const uint32_t da_tdr = (uint32_t)(sc->mem_res->r_bushandle + MCI_TDR);
const uint32_t xdma_interrupt = XDMAC_CIE_BIE | XDMAC_CIE_DIE |
XDMAC_CIE_FIE | XDMAC_CIE_RBIE | XDMAC_CIE_WBIE | XDMAC_CIE_ROIE;
eXdmadRC rc;
size_t i;
if (read) {
xdma_cfg = &sc->xdma_rx_cfg;
xdma_channel = sc->xdma_rx_channel;
} else {
xdma_cfg = &sc->xdma_tx_cfg;
xdma_channel = sc->xdma_tx_channel;
}
for (i = 0; i < number_blocks; ++i) {
if (read) {
dma_desc[i].mbr_sa = sa_rdr;
dma_desc[i].mbr_da = ((uint32_t)paddr) + i * block_size;
} else {
dma_desc[i].mbr_sa = ((uint32_t)paddr) + i * block_size;
dma_desc[i].mbr_da = da_tdr;
}
dma_desc[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 |
XDMA_UBC_NDEN_UPDATED | (block_size/4);
if (i == number_blocks - 1) {
dma_desc[i].mbr_ubc |= XDMA_UBC_NDE_FETCH_DIS;
dma_desc[i].mbr_nda = 0;
} else {
dma_desc[i].mbr_ubc |= XDMA_UBC_NDE_FETCH_EN;
dma_desc[i].mbr_nda = (uint32_t) &dma_desc[i+1];
}
}
rc = XDMAD_ConfigureTransfer(pXdmad, xdma_channel, xdma_cfg, xdma_cndc,
(uint32_t)dma_desc, xdma_interrupt);
if (rc != XDMAD_OK)
panic("Could not configure XDMA: %d.", rc);
/* FIXME: Is that correct? */
if (read) {
rtems_cache_invalidate_multiple_data_lines(paddr, len);
} else {
rtems_cache_flush_multiple_data_lines(paddr, len);
}
rtems_cache_flush_multiple_data_lines(dma_desc, sizeof(dma_desc));
rc = XDMAD_StartTransfer(pXdmad, xdma_channel);
if (rc != XDMAD_OK)
panic("Could not start XDMA: %d.", rc);
}
#endif /* __rtems__ */
static void
at91_mci_start_cmd(struct at91_mci_softc *sc, struct mmc_command *cmd)
{
uint32_t cmdr, mr;
#ifdef __rtems__
uint32_t number_blocks;
uint32_t block_size;
#endif /* __rtems__ */
struct mmc_data *data;
sc->curcmd = cmd;
@ -694,11 +879,22 @@ at91_mci_start_cmd(struct at91_mci_softc *sc, struct mmc_command *cmd)
* smaller blocks are possible, but never larger.
*/
#ifndef __rtems__
WR4(sc, PDC_PTCR, PDC_PTCR_RXTDIS | PDC_PTCR_TXTDIS);
mr = RD4(sc,MCI_MR) & ~MCI_MR_BLKLEN;
mr |= min(data->len, 512) << 16;
WR4(sc, MCI_MR, mr | MCI_MR_PDCMODE|MCI_MR_PDCPADV);
#else /* __rtems__ */
mr = RD4(sc,MCI_MR);
WR4(sc, MCI_MR, mr | MCI_MR_PDCPADV);
WR4(sc, MCI_DMA, MCI_DMA_DMAEN | MCI_DMA_CHKSIZE_1);
block_size = min(data->len, 512);
number_blocks = data->len / block_size;
WR4(sc, MCI_BLKR, block_size << 16 | number_blocks);
#endif /* __rtems__ */
/*
* Set up DMA.
@ -743,9 +939,14 @@ at91_mci_start_cmd(struct at91_mci_softc *sc, struct mmc_command *cmd)
panic("IO read size exceeds MAXDATA\n");
if (data->flags & MMC_DATA_READ) {
#ifndef __rtems__
if (remaining > 2048) // XXX
len = remaining / 2;
else
#else
/* FIXME: This reduces performance. Set up DMA in two
* parts instead like done on AT91. */
#endif /* __rtems__ */
len = remaining;
err = bus_dmamap_load(sc->dmatag, sc->bbuf_map[0],
sc->bbuf_vaddr[0], len, at91_mci_getaddr,
@ -754,6 +955,7 @@ at91_mci_start_cmd(struct at91_mci_softc *sc, struct mmc_command *cmd)
panic("IO read dmamap_load failed\n");
bus_dmamap_sync(sc->dmatag, sc->bbuf_map[0],
BUS_DMASYNC_PREREAD);
#ifndef __rtems__
WR4(sc, PDC_RPR, paddr);
WR4(sc, PDC_RCR, len / 4);
sc->bbuf_len[0] = len;
@ -775,6 +977,16 @@ at91_mci_start_cmd(struct at91_mci_softc *sc, struct mmc_command *cmd)
remaining -= len;
}
WR4(sc, PDC_PTCR, PDC_PTCR_RXTEN);
#else /* __rtems__ */
at91_mci_setup_xdma(sc, true, block_size,
number_blocks, paddr, len);
sc->bbuf_len[0] = len;
remaining -= len;
sc->bbuf_len[1] = 0;
if (remaining != 0)
panic("Still rx-data left. This should never happen.");
#endif /* __rtems__ */
} else {
len = min(BBSIZE, remaining);
at91_bswap_buf(sc, sc->bbuf_vaddr[0], data->data, len);
@ -785,6 +997,7 @@ at91_mci_start_cmd(struct at91_mci_softc *sc, struct mmc_command *cmd)
panic("IO write dmamap_load failed\n");
bus_dmamap_sync(sc->dmatag, sc->bbuf_map[0],
BUS_DMASYNC_PREWRITE);
#ifndef __rtems__
/*
* Erratum workaround: PDC transfer length on a write
* must not be smaller than 12 bytes (3 words); only
@ -813,6 +1026,17 @@ at91_mci_start_cmd(struct at91_mci_softc *sc, struct mmc_command *cmd)
remaining -= len;
}
/* do not enable PDC xfer until CMDRDY asserted */
#else /* __rtems__ */
at91_mci_setup_xdma(sc, false, block_size,
number_blocks, paddr, len);
sc->bbuf_len[0] = len;
remaining -= len;
sc->bbuf_len[1] = 0;
if (remaining != 0)
panic("Still tx-data left. This should never happen.");
#endif /* __rtems__ */
}
data->xfer_len = 0; /* XXX what's this? appears to be unused. */
}
@ -921,8 +1145,10 @@ at91_mci_read_done(struct at91_mci_softc *sc, uint32_t sr)
* operation, otherwise we wait for another ENDRX for the next bufer.
*/
#ifndef __rtems__
bus_dmamap_sync(sc->dmatag, sc->bbuf_map[curidx], BUS_DMASYNC_POSTREAD);
bus_dmamap_unload(sc->dmatag, sc->bbuf_map[curidx]);
#endif /* __rtems__ */
at91_bswap_buf(sc, dataptr + sc->xfer_offset, sc->bbuf_vaddr[curidx], len);
@ -947,7 +1173,11 @@ at91_mci_read_done(struct at91_mci_softc *sc, uint32_t sr)
at91_mci_next_operation(sc);
} else {
WR4(sc, PDC_RNCR, 0);
#ifndef __rtems__
WR4(sc, MCI_IER, MCI_SR_ERROR | MCI_SR_ENDRX);
#else /* __rtems__ */
WR4(sc, MCI_IER, MCI_SR_ERROR | MCI_SR_XFRDONE);
#endif /* __rtems__ */
}
}
@ -1142,12 +1372,16 @@ at91_mci_cmdrdy(struct at91_mci_softc *sc, uint32_t sr)
*/
if (cmd->data) {
uint32_t ier;
#ifndef __rtems__
if (cmd->data->flags & MMC_DATA_READ) {
ier = MCI_SR_ENDRX;
} else {
ier = MCI_SR_TXBUFE;
WR4(sc, PDC_PTCR, PDC_PTCR_TXTEN);
}
#else /* __rtems__ */
ier = MCI_SR_XFRDONE;
#endif /* __rtems__ */
WR4(sc, MCI_IER, MCI_SR_ERROR | ier);
return;
}
@ -1209,6 +1443,7 @@ at91_mci_intr(void *arg)
}
at91_mci_next_operation(sc);
} else {
#ifndef __rtems__
if (isr & MCI_SR_TXBUFE) {
// printf("TXBUFE\n");
/*
@ -1233,6 +1468,19 @@ at91_mci_intr(void *arg)
// printf("ENDRX\n");
at91_mci_read_done(sc, sr);
}
#else /* __rtems__ */
if (isr & MCI_SR_XFRDONE) {
struct mmc_command *cmd = sc->curcmd;
if (cmd->data->flags & MMC_DATA_READ) {
at91_mci_read_done(sc, sr);
} else {
if (sr & MCI_SR_BLKE)
isr |= MCI_SR_BLKE;
else
WR4(sc, MCI_IER, MCI_SR_BLKE);
}
}
#endif /* __rtems__ */
if (isr & MCI_SR_NOTBUSY) {
// printf("NOTBUSY\n");
at91_mci_notbusy(sc);
@ -1395,6 +1643,7 @@ static driver_t at91_mci_driver = {
static devclass_t at91_mci_devclass;
#ifndef __rtems__
#ifdef FDT
DRIVER_MODULE(at91_mci, simplebus, at91_mci_driver, at91_mci_devclass, NULL,
NULL);
@ -1404,5 +1653,9 @@ DRIVER_MODULE(at91_mci, atmelarm, at91_mci_driver, at91_mci_devclass, NULL,
#endif
MMC_DECLARE_BRIDGE(at91_mci);
#else /* __rtems__ */
DRIVER_MODULE(at91_mci, nexus, at91_mci_driver, at91_mci_devclass, NULL, NULL);
#endif /* __rtems__ */
DRIVER_MODULE(mmc, at91_mci, mmc_driver, mmc_devclass, NULL, NULL);
MODULE_DEPEND(at91_mci, mmc, 1, 1, 1);
#endif /* __rtems__ && LIBBSP_ARM_ATSAM_BSP_H */

View File

@ -37,6 +37,9 @@
#define MCI_SDCR 0x0c /* MCI SD Card Register */
#define MCI_ARGR 0x10 /* MCI Argument Register */
#define MCI_CMDR 0x14 /* MCI Command Register */
#ifdef __rtems__
#define MCI_BLKR 0x18 /* MCI Block Register */
#endif /* __rtems__ */
#define MCI_RSPR 0x20 /* MCI Response Registers - 4 of them */
#define MCI_RDR 0x30 /* MCI Receive Data Register */
#define MCI_TDR 0x34 /* MCI Transmit Data Register */
@ -44,6 +47,9 @@
#define MCI_IER 0x44 /* MCI Interrupt Enable Register */
#define MCI_IDR 0x48 /* MCI Interrupt Disable Register */
#define MCI_IMR 0x4c /* MCI Interrupt Mask Register */
#ifdef __rtems__
#define MCI_DMA 0x50 /* MCI DMA Control Register */
#endif /* __rtems__ */
/* -------- MCI_CR : (MCI Offset: 0x0) MCI Control Register -------- */
#define MCI_CR_MCIEN (0x1u << 0) /* (MCI) Multimedia Interface Enable */
@ -59,6 +65,7 @@
#define MCI_MR_PDCFBYTE (0x1u << 13) /* (MCI) PDC Force Byte Transfer */
#define MCI_MR_PDCPADV (0x1u << 14) /* (MCI) PDC Padding Value */
#define MCI_MR_PDCMODE (0x1u << 15) /* (MCI) PDC Oriented Mode */
#define MCI_MR_CLKODD (0x1u << 16) /* (MCI) Clock Divider is Odd */
#define MCI_MR_BLKLEN 0x3fff0000ul /* (MCI) Data Block Length */
/* -------- MCI_DTOR : (MCI Offset: 0x8) MCI Data Timeout Register -------- */
#define MCI_DTOR_DTOCYC (0xfu << 0) /* (MCI) Data Timeout Cycle Number */
@ -97,6 +104,11 @@
#define MCI_CMDR_TRTYP_BLOCK (0x0u << 19) /* (MCI) Block Transfer type */
#define MCI_CMDR_TRTYP_MULTIPLE (0x1u << 19) /* (MCI) Multiple Block transfer type */
#define MCI_CMDR_TRTYP_STREAM (0x2u << 19) /* (MCI) Stream transfer type */
#ifdef __rtems__
/* -------- MCI_BLKR : (MCI Offset: 0x18) MCI Block Register -------- */
#define MCI_BLKR_BCNT (0xFFFFu << 0)
#define MCI_BLKR_BLKLEN (0xFFFFu << 16)
#endif /* __rtems__ */
/* -------- MCI_SR : (MCI Offset: 0x40) MCI Status Register -------- */
#define MCI_SR_CMDRDY (0x1u << 0) /* (MCI) Command Ready flag */
#define MCI_SR_RXRDY (0x1u << 1) /* (MCI) RX Ready flag */
@ -117,6 +129,19 @@
#define MCI_SR_DTOE (0x1u << 22) /* (MCI) Data timeout Error flag */
#define MCI_SR_OVRE (0x1u << 30) /* (MCI) Overrun flag */
#define MCI_SR_UNRE (0x1u << 31) /* (MCI) Underrun flag */
#ifdef __rtems__
#define MCI_SR_XFRDONE (0x1u << 27) /* (MCI) Underrun flag */
#endif /* __rtems__ */
#ifdef __rtems__
/* -------- MCI_DMA : (MCI Offset: 0x50) MCI DMA Control Register -------- */
#define MCI_DMA_DMAEN (0x1u << 8)
#define MCI_DMA_CHKSIZE (0x7u << 4)
#define MCI_DMA_CHKSIZE_1 (0x0u << 4)
#define MCI_DMA_CHKSIZE_2 (0x1u << 4)
#define MCI_DMA_CHKSIZE_4 (0x2u << 4)
#define MCI_DMA_CHKSIZE_8 (0x3u << 4)
#define MCI_DMA_CHKSIZE_16 (0x4u << 4)
#endif /* __rtems__ */
/* TXRDY,DTIP,ENDTX,TXBUFE,RTOE */

View File

@ -483,6 +483,10 @@ def mmc(mm):
mod = builder.Module('mmc')
mod.addKernelSpaceHeaderFiles(
[
'sys/arm/at91/at91_mcireg.h',
'sys/arm/at91/at91_pdcreg.h',
'sys/arm/at91/at91reg.h',
'sys/arm/at91/at91var.h',
'sys/dev/mmc/bridge.h',
'sys/dev/mmc/mmcbrvar.h',
'sys/dev/mmc/mmc_ioctl.h',
@ -490,10 +494,12 @@ def mmc(mm):
'sys/dev/mmc/mmcreg.h',
'sys/dev/mmc/mmc_subr.h',
'sys/dev/mmc/mmcvar.h',
'sys/sys/watchdog.h',
]
)
mod.addKernelSpaceSourceFiles(
[
'sys/arm/at91/at91_mci.c',
'sys/dev/mmc/mmc.c',
'sys/dev/mmc/mmcsd.c',
'sys/dev/mmc/mmc_subr.c',

View File

@ -1685,7 +1685,8 @@ def build(bld):
source = objs09_source)
libbsd_use += ["objs09"]
source = ['freebsd/sys/arm/lpc/if_lpe.c',
source = ['freebsd/sys/arm/at91/at91_mci.c',
'freebsd/sys/arm/lpc/if_lpe.c',
'freebsd/sys/arm/lpc/lpc_pwr.c',
'freebsd/sys/arm/ti/am335x/am335x_musb.c',
'freebsd/sys/arm/ti/am335x/am335x_prcm.c',

View File

@ -230,6 +230,27 @@ extern "C" {
RTEMS_BSD_DEFINE_NEXUS_DEVICE(dw_mmc, 0, 0, NULL)
#endif /* RTEMS_BSD_DRIVER_DWC_MMC */
/*
* Atmel Media Card Interface (MCI).
*/
#if !defined(RTEMS_BSD_DRIVER_AT91_MCI0)
#define RTEMS_BSD_DRIVER_AT91_MCI0(_base, _irq) \
static const rtems_bsd_device_resource at91_mci0_res[] = { \
{ \
.type = RTEMS_BSD_RES_MEMORY, \
.start_request = 0, \
.start_actual = (_base) \
}, { \
.type = RTEMS_BSD_RES_IRQ, \
.start_request = 0, \
.start_actual = (_irq) \
} \
}; \
RTEMS_BSD_DEFINE_NEXUS_DEVICE(at91_mci, 0, \
RTEMS_ARRAY_SIZE(at91_mci0_res), \
&at91_mci0_res[0])
#endif /* RTEMS_BSD_DRIVER_DWC0 */
/*
* MMC Driver.
*/