mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-05-13 17:39:19 +08:00
at91_mci: Port to RTEMS and adapt for atsam.
This commit is contained in:
parent
ea5880a3cc
commit
ec29b2a0c2
@ -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 */
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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',
|
||||
|
@ -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',
|
||||
|
@ -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.
|
||||
*/
|
||||
|
0
rtemsbsd/include/rtems/bsd/local/opt_at91.h
Normal file
0
rtemsbsd/include/rtems/bsd/local/opt_at91.h
Normal file
Loading…
x
Reference in New Issue
Block a user