Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F171850538
D6868.id19017.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
28 KB
Referenced Files
None
Subscribers
None
D6868.id19017.diff
View Options
Index: sys/arm/allwinner/a10_mmc.h
===================================================================
--- sys/arm/allwinner/a10_mmc.h
+++ sys/arm/allwinner/a10_mmc.h
@@ -29,117 +29,119 @@
#ifndef _A10_MMC_H_
#define _A10_MMC_H_
-#define A10_MMC_GCTRL 0x00 /* Global Control Register */
-#define A10_MMC_CLKCR 0x04 /* Clock Control Register */
-#define A10_MMC_TIMEOUT 0x08 /* Timeout Register */
-#define A10_MMC_WIDTH 0x0C /* Bus Width Register */
-#define A10_MMC_BLKSZ 0x10 /* Block Size Register */
-#define A10_MMC_BCNTR 0x14 /* Byte Count Register */
+#define A10_MMC_GCTL 0x00 /* Control Register */
+#define A10_MMC_CKCR 0x04 /* Clock Control Register */
+#define A10_MMC_TMOR 0x08 /* Timeout Register */
+#define A10_MMC_BWDR 0x0C /* Bus Width Register */
+#define A10_MMC_BKSR 0x10 /* Block Size Register */
+#define A10_MMC_BYCR 0x14 /* Byte Count Register */
#define A10_MMC_CMDR 0x18 /* Command Register */
-#define A10_MMC_CARG 0x1C /* Argument Register */
+#define A10_MMC_CAGR 0x1C /* Argument Register */
#define A10_MMC_RESP0 0x20 /* Response Register 0 */
#define A10_MMC_RESP1 0x24 /* Response Register 1 */
#define A10_MMC_RESP2 0x28 /* Response Register 2 */
#define A10_MMC_RESP3 0x2C /* Response Register 3 */
-#define A10_MMC_IMASK 0x30 /* Interrupt Mask Register */
-#define A10_MMC_MISTA 0x34 /* Masked Interrupt Status Register */
-#define A10_MMC_RINTR 0x38 /* Raw Interrupt Status Register */
-#define A10_MMC_STAS 0x3C /* Status Register */
-#define A10_MMC_FTRGL 0x40 /* FIFO Threshold Watermark Register */
+#define A10_MMC_IMKR 0x30 /* Interrupt Mask Register */
+#define A10_MMC_MISR 0x34 /* Masked Interrupt Status Register */
+#define A10_MMC_RISR 0x38 /* Raw Interrupt Status Register */
+#define A10_MMC_STAR 0x3C /* Status Register */
+#define A10_MMC_FWLR 0x40 /* FIFO Threshold Watermark Register */
#define A10_MMC_FUNS 0x44 /* Function Select Register */
-#define A10_MMC_CBCR 0x48 /* CIU Byte Count Register */
-#define A10_MMC_BBCR 0x4C /* BIU Byte Count Register */
-#define A10_MMC_DBGC 0x50 /* Debug Enable Register */
#define A10_MMC_DMAC 0x80 /* IDMAC Control Register */
#define A10_MMC_DLBA 0x84 /* IDMAC Desc List Base Address Reg */
#define A10_MMC_IDST 0x88 /* IDMAC Status Register */
#define A10_MMC_IDIE 0x8C /* IDMAC Interrupt Enable Register */
-#define A10_MMC_CHDA 0x90
-#define A10_MMC_CBDA 0x94
-#define A10_MMC_FIFO 0x100 /* FIFO Access Address (A10/A20) */
-#define A31_MMC_FIFO 0x200 /* FIFO Access Address (A31) */
+#define A10_MMC_FIFO 0x100 /* FIFO Access Address (A10/A20) */
+#define A31_MMC_FIFO 0x200 /* FIFO Access Address (A31) */
-/* A10_MMC_GCTRL */
-#define A10_MMC_SOFT_RESET (1U << 0)
-#define A10_MMC_FIFO_RESET (1U << 1)
-#define A10_MMC_DMA_RESET (1U << 2)
-#define A10_MMC_INT_ENABLE (1U << 4)
-#define A10_MMC_DMA_ENABLE (1U << 5)
-#define A10_MMC_DEBOUNCE_ENABLE (1U << 8)
-#define A10_MMC_DDR_MODE (1U << 10)
-#define A10_MMC_ACCESS_BY_AHB (1U << 31)
+/* A10_MMC_GCTL */
+#define A10_MMC_CTRL_SOFT_RST (1U << 0)
+#define A10_MMC_CTRL_FIFO_RST (1U << 1)
+#define A10_MMC_CTRL_DMA_RST (1U << 2)
+#define A10_MMC_CTRL_INT_ENB (1U << 4)
+#define A10_MMC_CTRL_DMA_ENB (1U << 5)
+#define A10_MMC_CTRL_CD_DBC_ENB (1U << 8)
+#define A10_MMC_CTRL_DDR_MOD_SEL (1U << 10)
+#define A10_MMC_CTRL_FIFO_AC_MOD (1U << 31)
#define A10_MMC_RESET \
- (A10_MMC_SOFT_RESET | A10_MMC_FIFO_RESET | A10_MMC_DMA_RESET)
+ (A10_MMC_CTRL_SOFT_RST | A10_MMC_CTRL_FIFO_RST | A10_MMC_CTRL_DMA_RST)
-/* A10_MMC_CLKCR */
-#define A10_MMC_CARD_CLK_ON (1U << 16)
-#define A10_MMC_LOW_POWER_ON (1U << 17)
-#define A10_MMC_CLKCR_DIV 0xff
+/* A10_MMC_CKCR */
+#define A10_MMC_CKCR_CCLK_ENB (1U << 16)
+#define A10_MMC_CKCR_CCLK_CTRL (1U << 17)
+#define A10_MMC_CKCR_CCLK_DIV 0xff
-/* A10_MMC_WIDTH */
-#define A10_MMC_WIDTH1 0
-#define A10_MMC_WIDTH4 1
-#define A10_MMC_WIDTH8 2
+/* A10_MMC_TMOR */
+#define A10_MMC_TMOR_RTO_LMT_SHIFT(x) x /* Response timeout limit */
+#define A10_MMC_TMOR_RTO_LMT_MASK 0xff
+#define A10_MMC_TMOR_DTO_LMT_SHIFT(x) (x << 8) /* Data timeout limit */
+#define A10_MMC_TMOR_DTO_LMT_MASK 0xffffff
+
+/* A10_MMC_BWDR */
+#define A10_MMC_BWDR1 0
+#define A10_MMC_BWDR4 1
+#define A10_MMC_BWDR8 2
/* A10_MMC_CMDR */
-#define A10_MMC_RESP_EXP (1U << 6)
-#define A10_MMC_LONG_RESP (1U << 7)
-#define A10_MMC_CHECK_RESP_CRC (1U << 8)
-#define A10_MMC_DATA_EXP (1U << 9)
-#define A10_MMC_WRITE (1U << 10)
-#define A10_MMC_SEQ_MODE (1U << 11)
-#define A10_MMC_SEND_AUTOSTOP (1U << 12)
-#define A10_MMC_WAIT_PREOVER (1U << 13)
-#define A10_MMC_STOP_ABORT_CMD (1U << 14)
-#define A10_MMC_SEND_INIT_SEQ (1U << 15)
-#define A10_MMC_UPCLK_ONLY (1U << 21)
-#define A10_MMC_RDCEATADEV (1U << 22)
-#define A10_MMC_CCS_EXP (1U << 23)
-#define A10_MMC_ENB_BOOT (1U << 24)
-#define A10_MMC_ALT_BOOT_OPT (1U << 25)
-#define A10_MMC_BOOT_ACK_EXP (1U << 26)
-#define A10_MMC_DISABLE_BOOT (1U << 27)
-#define A10_MMC_VOL_SWITCH (1U << 28)
-#define A10_MMC_START (1U << 31)
+#define A10_MMC_CMDR_RESP_RCV (1U << 6)
+#define A10_MMC_CMDR_LONG_RESP (1U << 7)
+#define A10_MMC_CMDR_CHK_RESP_CRC (1U << 8)
+#define A10_MMC_CMDR_DATA_TRANS (1U << 9)
+#define A10_MMC_CMDR_DIR_WRITE (1U << 10)
+#define A10_MMC_CMDR_TRANS_MODE_STREAM (1U << 11)
+#define A10_MMC_CMDR_STOP_CMD_FLAG (1U << 12)
+#define A10_MMC_CMDR_WAIT_PRE_OVER (1U << 13)
+#define A10_MMC_CMDR_STOP_ABT_CMD (1U << 14)
+#define A10_MMC_CMDR_SEND_INIT_SEQ (1U << 15)
+#define A10_MMC_CMDR_PRG_CLK (1U << 21)
+#define A10_MMC_CMDR_RD_CEDATA_DEV (1U << 22)
+#define A10_MMC_CMDR_CCS_EXP (1U << 23)
+#define A10_MMC_CMDR_BOOT_MOD_SHIFT 24
+#define A10_MMC_CMDR_BOOT_MOD_NORMAL 0
+#define A10_MMC_CMDR_BOOT_MOD_MANDATORY 1
+#define A10_MMC_CMDR_BOOT_MOD_ALT 2
+#define A10_MMC_CMDR_EXP_BOOT_ACK (1U << 26)
+#define A10_MMC_CMDR_BOOT_ABT (1U << 27)
+#define A10_MMC_CMDR_VOL_SW (1U << 28)
+#define A10_MMC_CMDR_LOAD (1U << 31)
-/* A10_MMC_IMASK and A10_MMC_RINTR */
-#define A10_MMC_RESP_ERR (1U << 1)
-#define A10_MMC_CMD_DONE (1U << 2)
-#define A10_MMC_DATA_OVER (1U << 3)
-#define A10_MMC_TX_DATA_REQ (1U << 4)
-#define A10_MMC_RX_DATA_REQ (1U << 5)
-#define A10_MMC_RESP_CRC_ERR (1U << 6)
-#define A10_MMC_DATA_CRC_ERR (1U << 7)
-#define A10_MMC_RESP_TIMEOUT (1U << 8)
-#define A10_MMC_ACK_RECV (1U << 8)
-#define A10_MMC_DATA_TIMEOUT (1U << 9)
-#define A10_MMC_BOOT_START (1U << 9)
-#define A10_MMC_DATA_STARVE (1U << 10)
-#define A10_MMC_VOL_CHG_DONE (1U << 10)
-#define A10_MMC_FIFO_RUN_ERR (1U << 11)
-#define A10_MMC_HARDW_LOCKED (1U << 12)
-#define A10_MMC_START_BIT_ERR (1U << 13)
-#define A10_MMC_AUTOCMD_DONE (1U << 14)
-#define A10_MMC_END_BIT_ERR (1U << 15)
-#define A10_MMC_SDIO_INT (1U << 16)
-#define A10_MMC_CARD_INSERT (1U << 30)
-#define A10_MMC_CARD_REMOVE (1U << 31)
+/* A10_MMC_IMKR and A10_MMC_RISR */
+#define A10_MMC_INT_RESP_ERR (1U << 1)
+#define A10_MMC_INT_CMD_DONE (1U << 2)
+#define A10_MMC_INT_DATA_OVER (1U << 3)
+#define A10_MMC_INT_TX_DATA_REQ (1U << 4)
+#define A10_MMC_INT_RX_DATA_REQ (1U << 5)
+#define A10_MMC_INT_RESP_CRC_ERR (1U << 6)
+#define A10_MMC_INT_DATA_CRC_ERR (1U << 7)
+#define A10_MMC_INT_RESP_TIMEOUT (1U << 8)
+#define A10_MMC_INT_BOOT_ACK_RECV (1U << 8)
+#define A10_MMC_INT_DATA_TIMEOUT (1U << 9)
+#define A10_MMC_INT_BOOT_START (1U << 9)
+#define A10_MMC_INT_DATA_STARVE (1U << 10)
+#define A10_MMC_INT_VOL_CHG_DONE (1U << 10)
+#define A10_MMC_INT_FIFO_RUN_ERR (1U << 11)
+#define A10_MMC_INT_CMD_BUSY (1U << 12)
+#define A10_MMC_INT_DATA_START_ERR (1U << 13)
+#define A10_MMC_INT_AUTO_STOP_DONE (1U << 14)
+#define A10_MMC_INT_DATA_END_BIT_ERR (1U << 15)
+#define A10_MMC_INT_SDIO (1U << 16)
+#define A10_MMC_INT_CARD_INSERT (1U << 30)
+#define A10_MMC_INT_CARD_REMOVE (1U << 31)
#define A10_MMC_INT_ERR_BIT \
- (A10_MMC_RESP_ERR | A10_MMC_RESP_CRC_ERR | \
- A10_MMC_DATA_CRC_ERR | A10_MMC_RESP_TIMEOUT | \
- A10_MMC_FIFO_RUN_ERR | A10_MMC_HARDW_LOCKED | \
- A10_MMC_START_BIT_ERR | A10_MMC_END_BIT_ERR)
+ (A10_MMC_INT_RESP_ERR | A10_MMC_INT_RESP_CRC_ERR | \
+ A10_MMC_INT_DATA_CRC_ERR | A10_MMC_INT_RESP_TIMEOUT | \
+ A10_MMC_INT_FIFO_RUN_ERR | A10_MMC_INT_CMD_BUSY | \
+ A10_MMC_INT_DATA_START_ERR | A10_MMC_INT_DATA_END_BIT_ERR)
-/* A10_MMC_STAS */
-#define A10_MMC_RX_WLFLAG (1U << 0)
-#define A10_MMC_TX_WLFLAG (1U << 1)
-#define A10_MMC_FIFO_EMPTY (1U << 2)
-#define A10_MMC_FIFO_FULL (1U << 3)
-#define A10_MMC_CARD_PRESENT (1U << 8)
-#define A10_MMC_CARD_DATA_BUSY (1U << 9)
-#define A10_MMC_DATA_FSM_BUSY (1U << 10)
-#define A10_MMC_DMA_REQ (1U << 31)
-#define A10_MMC_FIFO_SIZE 16
+/* A10_MMC_STAR */
+#define A10_MMC_STAR_FIFO_RX_LEVEL (1U << 0)
+#define A10_MMC_STAR_FIFO_TX_LEVEL (1U << 1)
+#define A10_MMC_STAR_FIFO_EMPTY (1U << 2)
+#define A10_MMC_STAR_FIFO_FULL (1U << 3)
+#define A10_MMC_STAR_CARD_PRESENT (1U << 8)
+#define A10_MMC_STAR_CARD_BUSY (1U << 9)
+#define A10_MMC_STAR_FSM_BUSY (1U << 10)
+#define A10_MMC_STAR_DMA_REQ (1U << 31)
/* A10_MMC_FUNS */
#define A10_MMC_CE_ATA_ON (0xceaaU << 16)
@@ -151,52 +153,51 @@
#define A10_MMC_CE_ATA_DEV_INT_ENB (1U << 10)
/* IDMA CONTROLLER BUS MOD BIT FIELD */
-#define A10_MMC_IDMAC_SOFT_RST (1U << 0)
-#define A10_MMC_IDMAC_FIX_BURST (1U << 1)
-#define A10_MMC_IDMAC_IDMA_ON (1U << 7)
-#define A10_MMC_IDMAC_REFETCH_DES (1U << 31)
+#define A10_MMC_DMAC_IDMAC_SOFT_RST (1U << 0)
+#define A10_MMC_DMAC_IDMAC_FIX_BURST (1U << 1)
+#define A10_MMC_DMAC_IDMAC_IDMA_ON (1U << 7)
+#define A10_MMC_DMAC_IDMAC_REFETCH_DES (1U << 31)
/* A10_MMC_IDST */
-#define A10_MMC_IDMAC_TRANSMIT_INT (1U << 0)
-#define A10_MMC_IDMAC_RECEIVE_INT (1U << 1)
-#define A10_MMC_IDMAC_FATAL_BUS_ERR (1U << 2)
-#define A10_MMC_IDMAC_DES_INVALID (1U << 4)
-#define A10_MMC_IDMAC_CARD_ERR_SUM (1U << 5)
-#define A10_MMC_IDMAC_NORMAL_INT_SUM (1U << 8)
-#define A10_MMC_IDMAC_ABNORMAL_INT_SUM (1U << 9)
-#define A10_MMC_IDMAC_HOST_ABT_INTX (1U << 10)
-#define A10_MMC_IDMAC_HOST_ABT_INRX (1U << 10)
-#define A10_MMC_IDMAC_IDLE (0U << 13)
-#define A10_MMC_IDMAC_SUSPEND (1U << 13)
-#define A10_MMC_IDMAC_DESC_RD (2U << 13)
-#define A10_MMC_IDMAC_DESC_CHECK (3U << 13)
-#define A10_MMC_IDMAC_RD_REQ_WAIT (4U << 13)
-#define A10_MMC_IDMAC_WR_REQ_WAIT (5U << 13)
-#define A10_MMC_IDMAC_RD (6U << 13)
-#define A10_MMC_IDMAC_WR (7U << 13)
-#define A10_MMC_IDMAC_DESC_CLOSE (8U << 13)
-#define A10_MMC_IDMAC_ERROR \
- (A10_MMC_IDMAC_FATAL_BUS_ERR | A10_MMC_IDMAC_CARD_ERR_SUM | \
- A10_MMC_IDMAC_DES_INVALID | A10_MMC_IDMAC_ABNORMAL_INT_SUM)
-#define A10_MMC_IDMAC_COMPLETE \
- (A10_MMC_IDMAC_TRANSMIT_INT | A10_MMC_IDMAC_RECEIVE_INT)
+#define A10_MMC_IDST_TX_INT (1U << 0)
+#define A10_MMC_IDST_RX_INT (1U << 1)
+#define A10_MMC_IDST_FATAL_BERR_INT (1U << 2)
+#define A10_MMC_IDST_DES_UNAVL_INT (1U << 4)
+#define A10_MMC_IDST_ERR_FLAG_SUM (1U << 5)
+#define A10_MMC_IDST_NOR_INT_SUM (1U << 8)
+#define A10_MMC_IDST_ABN_INT_SUM (1U << 9)
+#define A10_MMC_IDST_HOST_ABT_INTX (1U << 10)
+#define A10_MMC_IDST_HOST_ABT_INRX (1U << 10)
+#define A10_MMC_IDST_IDLE (0U << 13)
+#define A10_MMC_IDST_SUSPEND (1U << 13)
+#define A10_MMC_IDST_DESC_RD (2U << 13)
+#define A10_MMC_IDST_DESC_CHECK (3U << 13)
+#define A10_MMC_IDST_RD_REQ_WAIT (4U << 13)
+#define A10_MMC_IDST_WR_REQ_WAIT (5U << 13)
+#define A10_MMC_IDST_RD (6U << 13)
+#define A10_MMC_IDST_WR (7U << 13)
+#define A10_MMC_IDST_DESC_CLOSE (8U << 13)
+#define A10_MMC_IDST_ERROR \
+ (A10_MMC_IDST_FATAL_BERR_INT | A10_MMC_IDST_ERR_FLAG_SUM | \
+ A10_MMC_IDST_DES_UNAVL_INT | A10_MMC_IDST_ABN_INT_SUM)
+#define A10_MMC_IDST_COMPLETE \
+ (A10_MMC_IDST_TX_INT | A10_MMC_IDST_RX_INT)
/* The DMA descriptor table. */
struct a10_mmc_dma_desc {
uint32_t config;
-#define A10_MMC_DMA_CONFIG_DIC (1U << 1)
-#define A10_MMC_DMA_CONFIG_LD (1U << 2)
-#define A10_MMC_DMA_CONFIG_FD (1U << 3)
-#define A10_MMC_DMA_CONFIG_CH (1U << 4)
-#define A10_MMC_DMA_CONFIG_ER (1U << 5)
-#define A10_MMC_DMA_CONFIG_CES (1U << 30)
-#define A10_MMC_DMA_CONFIG_OWN (1U << 31)
+#define A10_MMC_DMA_CONFIG_DIC (1U << 1) /* Disable Interrupt Completion */
+#define A10_MMC_DMA_CONFIG_LD (1U << 2) /* Last DES */
+#define A10_MMC_DMA_CONFIG_FD (1U << 3) /* First DES */
+#define A10_MMC_DMA_CONFIG_CH (1U << 4) /* CHAIN MOD */
+#define A10_MMC_DMA_CONFIG_ER (1U << 5) /* End of Ring (undocumented register) */
+#define A10_MMC_DMA_CONFIG_CES (1U << 30) /* Card Error Summary */
+#define A10_MMC_DMA_CONFIG_OWN (1U << 31) /* DES Own Flag */
uint32_t buf_size;
uint32_t buf_addr;
uint32_t next;
};
-/* DMA descriptors and data buffers must be aligned to 32-bits */
-#define A10_MMC_DMA_ALIGN 4
+#define A10_MMC_DMA_ALIGN 4
#endif /* _A10_MMC_H_ */
Index: sys/arm/allwinner/a10_mmc.c
===================================================================
--- sys/arm/allwinner/a10_mmc.c
+++ sys/arm/allwinner/a10_mmc.c
@@ -48,7 +48,6 @@
#include <dev/mmc/mmcreg.h>
#include <dev/mmc/mmcbrvar.h>
-#include <arm/allwinner/allwinner_machdep.h>
#include <arm/allwinner/a10_mmc.h>
#include <dev/extres/clk/clk.h>
#include <dev/extres/hwreset/hwreset.h>
@@ -56,16 +55,12 @@
#define A10_MMC_MEMRES 0
#define A10_MMC_IRQRES 1
#define A10_MMC_RESSZ 2
-#define A10_MMC_DMA_SEGS 16
+#define A10_MMC_DMA_SEGS ((MAXPHYS / PAGE_SIZE) + 1)
#define A10_MMC_DMA_MAX_SIZE 0x2000
#define A10_MMC_DMA_FTRGLEVEL 0x20070008
#define CARD_ID_FREQUENCY 400000
-static int a10_mmc_pio_mode = 0;
-
-TUNABLE_INT("hw.a10.mmc.pio_mode", &a10_mmc_pio_mode);
-
static struct ofw_compat_data compat_data[] = {
{"allwinner,sun4i-a10-mmc", 1},
{"allwinner,sun5i-a13-mmc", 1},
@@ -73,14 +68,11 @@
};
struct a10_mmc_softc {
- bus_space_handle_t a10_bsh;
- bus_space_tag_t a10_bst;
device_t a10_dev;
clk_t a10_clk_ahb;
clk_t a10_clk_mmc;
hwreset_t a10_rst_ahb;
int a10_bus_busy;
- int a10_id;
int a10_resid;
int a10_timeout;
struct callout a10_timeoutc;
@@ -91,7 +83,6 @@
uint32_t a10_intr;
uint32_t a10_intr_wait;
void * a10_intrhand;
- bus_size_t a10_fifo_reg;
/* Fields required for DMA access. */
bus_addr_t a10_dma_desc_phys;
@@ -100,7 +91,6 @@
void * a10_dma_desc;
bus_dmamap_t a10_dma_buf_map;
bus_dma_tag_t a10_dma_buf_tag;
- int a10_dma_inuse;
int a10_dma_map_err;
};
@@ -127,9 +117,9 @@
#define A10_MMC_LOCK(_sc) mtx_lock(&(_sc)->a10_mtx)
#define A10_MMC_UNLOCK(_sc) mtx_unlock(&(_sc)->a10_mtx)
#define A10_MMC_READ_4(_sc, _reg) \
- bus_space_read_4((_sc)->a10_bst, (_sc)->a10_bsh, _reg)
+ bus_read_4((_sc)->a10_res[A10_MMC_MEMRES], _reg)
#define A10_MMC_WRITE_4(_sc, _reg, _value) \
- bus_space_write_4((_sc)->a10_bst, (_sc)->a10_bsh, _reg, _value)
+ bus_write_4((_sc)->a10_res[A10_MMC_MEMRES], _reg, _value)
static int
a10_mmc_probe(device_t dev)
@@ -160,17 +150,10 @@
sc = device_get_softc(dev);
sc->a10_dev = dev;
sc->a10_req = NULL;
- sc->a10_id = device_get_unit(dev);
- if (sc->a10_id > 3) {
- device_printf(dev, "only 4 hosts are supported (0-3)\n");
- return (ENXIO);
- }
if (bus_alloc_resources(dev, a10_mmc_res_spec, sc->a10_res) != 0) {
device_printf(dev, "cannot allocate device resources\n");
return (ENXIO);
}
- sc->a10_bst = rman_get_bustag(sc->a10_res[A10_MMC_MEMRES]);
- sc->a10_bsh = rman_get_bushandle(sc->a10_res[A10_MMC_MEMRES]);
if (bus_setup_intr(dev, sc->a10_res[A10_MMC_IRQRES],
INTR_TYPE_MISC | INTR_MPSAFE, NULL, a10_mmc_intr, sc,
&sc->a10_intrhand)) {
@@ -182,31 +165,12 @@
MTX_DEF);
callout_init_mtx(&sc->a10_timeoutc, &sc->a10_mtx, 0);
-#if defined(__arm__)
- /*
- * Later chips use a different FIFO offset. Unfortunately the FDT
- * uses the same compatible string for old and new implementations.
- */
- switch (allwinner_soc_family()) {
- case ALLWINNERSOC_SUN4I:
- case ALLWINNERSOC_SUN5I:
- case ALLWINNERSOC_SUN7I:
- sc->a10_fifo_reg = A10_MMC_FIFO;
- break;
- default:
- sc->a10_fifo_reg = A31_MMC_FIFO;
- break;
- }
-#else /* __aarch64__ */
- sc->a10_fifo_reg = A31_MMC_FIFO;
-#endif
-
/* De-assert reset */
if (hwreset_get_by_ofw_name(dev, 0, "ahb", &sc->a10_rst_ahb) == 0) {
error = hwreset_deassert(sc->a10_rst_ahb);
if (error != 0) {
device_printf(dev, "cannot de-assert reset\n");
- return (error);
+ goto fail;
}
}
@@ -250,13 +214,10 @@
goto fail;
}
- if (a10_mmc_pio_mode == 0 && a10_mmc_setup_dma(sc) != 0) {
+ if (a10_mmc_setup_dma(sc) != 0) {
device_printf(sc->a10_dev, "Couldn't setup DMA!\n");
- a10_mmc_pio_mode = 1;
+ goto fail;
}
- if (bootverbose)
- device_printf(sc->a10_dev, "DMA status: %s\n",
- a10_mmc_pio_mode ? "disabled" : "enabled");
if (OF_getencprop(node, "bus-width", &bus_width, sizeof(uint32_t)) <= 0)
bus_width = 4;
@@ -369,7 +330,6 @@
return;
dma_desc = sc->a10_dma_desc;
- /* Note nsegs is guaranteed to be zero if err is non-zero. */
for (i = 0; i < nsegs; i++) {
dma_desc[i].buf_size = segs[i].ds_len;
dma_desc[i].buf_addr = segs[i].ds_addr;
@@ -386,7 +346,7 @@
A10_MMC_DMA_CONFIG_ER;
dma_desc[i].next = 0;
}
- }
+ }
}
static int
@@ -401,13 +361,12 @@
if (cmd->data->len > A10_MMC_DMA_MAX_SIZE * A10_MMC_DMA_SEGS)
return (EFBIG);
error = bus_dmamap_load(sc->a10_dma_buf_tag, sc->a10_dma_buf_map,
- cmd->data->data, cmd->data->len, a10_dma_cb, sc, BUS_DMA_NOWAIT);
+ cmd->data->data, cmd->data->len, a10_dma_cb, sc, 0);
if (error)
return (error);
if (sc->a10_dma_map_err)
return (sc->a10_dma_map_err);
- sc->a10_dma_inuse = 1;
if (cmd->data->flags & MMC_DATA_WRITE)
sync_op = BUS_DMASYNC_PREWRITE;
else
@@ -415,27 +374,32 @@
bus_dmamap_sync(sc->a10_dma_buf_tag, sc->a10_dma_buf_map, sync_op);
bus_dmamap_sync(sc->a10_dma_tag, sc->a10_dma_map, BUS_DMASYNC_PREWRITE);
- val = A10_MMC_READ_4(sc, A10_MMC_IMASK);
- val &= ~(A10_MMC_RX_DATA_REQ | A10_MMC_TX_DATA_REQ);
- A10_MMC_WRITE_4(sc, A10_MMC_IMASK, val);
- val = A10_MMC_READ_4(sc, A10_MMC_GCTRL);
- val &= ~A10_MMC_ACCESS_BY_AHB;
- val |= A10_MMC_DMA_ENABLE;
- A10_MMC_WRITE_4(sc, A10_MMC_GCTRL, val);
- val |= A10_MMC_DMA_RESET;
- A10_MMC_WRITE_4(sc, A10_MMC_GCTRL, val);
- A10_MMC_WRITE_4(sc, A10_MMC_DMAC, A10_MMC_IDMAC_SOFT_RST);
+ /* Enable DMA */
+ val = A10_MMC_READ_4(sc, A10_MMC_GCTL);
+ val &= ~A10_MMC_CTRL_FIFO_AC_MOD;
+ val |= A10_MMC_CTRL_DMA_ENB;
+ A10_MMC_WRITE_4(sc, A10_MMC_GCTL, val);
+
+ /* Reset DMA */
+ val |= A10_MMC_CTRL_DMA_RST;
+ A10_MMC_WRITE_4(sc, A10_MMC_GCTL, val);
+
+ A10_MMC_WRITE_4(sc, A10_MMC_DMAC, A10_MMC_DMAC_IDMAC_SOFT_RST);
A10_MMC_WRITE_4(sc, A10_MMC_DMAC,
- A10_MMC_IDMAC_IDMA_ON | A10_MMC_IDMAC_FIX_BURST);
- val = A10_MMC_READ_4(sc, A10_MMC_IDIE);
- val &= ~(A10_MMC_IDMAC_RECEIVE_INT | A10_MMC_IDMAC_TRANSMIT_INT);
+ A10_MMC_DMAC_IDMAC_IDMA_ON | A10_MMC_DMAC_IDMAC_FIX_BURST);
+
+ /* Enable RX or TX DMA interrupt */
if (cmd->data->flags & MMC_DATA_WRITE)
- val |= A10_MMC_IDMAC_TRANSMIT_INT;
+ val |= A10_MMC_IDST_TX_INT;
else
- val |= A10_MMC_IDMAC_RECEIVE_INT;
+ val |= A10_MMC_IDST_RX_INT;
A10_MMC_WRITE_4(sc, A10_MMC_IDIE, val);
+
+ /* Set DMA descritptor list address */
A10_MMC_WRITE_4(sc, A10_MMC_DLBA, sc->a10_dma_desc_phys);
- A10_MMC_WRITE_4(sc, A10_MMC_FTRGL, A10_MMC_DMA_FTRGLEVEL);
+
+ /* FIFO trigger level */
+ A10_MMC_WRITE_4(sc, A10_MMC_FWLR, A10_MMC_DMA_FTRGLEVEL);
return (0);
}
@@ -445,11 +409,11 @@
{
int timeout;
- A10_MMC_WRITE_4(sc, A10_MMC_GCTRL,
- A10_MMC_READ_4(sc, A10_MMC_GCTRL) | A10_MMC_RESET);
+ A10_MMC_WRITE_4(sc, A10_MMC_GCTL,
+ A10_MMC_READ_4(sc, A10_MMC_GCTL) | A10_MMC_RESET);
timeout = 1000;
while (--timeout > 0) {
- if ((A10_MMC_READ_4(sc, A10_MMC_GCTRL) & A10_MMC_RESET) == 0)
+ if ((A10_MMC_READ_4(sc, A10_MMC_GCTL) & A10_MMC_RESET) == 0)
break;
DELAY(100);
}
@@ -457,18 +421,20 @@
return (ETIMEDOUT);
/* Set the timeout. */
- A10_MMC_WRITE_4(sc, A10_MMC_TIMEOUT, 0xffffffff);
+ A10_MMC_WRITE_4(sc, A10_MMC_TMOR,
+ A10_MMC_TMOR_DTO_LMT_SHIFT(A10_MMC_TMOR_DTO_LMT_MASK) |
+ A10_MMC_TMOR_RTO_LMT_SHIFT(A10_MMC_TMOR_RTO_LMT_MASK));
/* Clear pending interrupts. */
- A10_MMC_WRITE_4(sc, A10_MMC_RINTR, 0xffffffff);
+ A10_MMC_WRITE_4(sc, A10_MMC_RISR, 0xffffffff);
A10_MMC_WRITE_4(sc, A10_MMC_IDST, 0xffffffff);
/* Unmask interrupts. */
- A10_MMC_WRITE_4(sc, A10_MMC_IMASK,
- A10_MMC_CMD_DONE | A10_MMC_INT_ERR_BIT |
- A10_MMC_DATA_OVER | A10_MMC_AUTOCMD_DONE);
+ A10_MMC_WRITE_4(sc, A10_MMC_IMKR,
+ A10_MMC_INT_CMD_DONE | A10_MMC_INT_ERR_BIT |
+ A10_MMC_INT_DATA_OVER | A10_MMC_INT_AUTO_STOP_DONE);
/* Enable interrupts and AHB access. */
- A10_MMC_WRITE_4(sc, A10_MMC_GCTRL,
- A10_MMC_READ_4(sc, A10_MMC_GCTRL) | A10_MMC_INT_ENABLE);
+ A10_MMC_WRITE_4(sc, A10_MMC_GCTL,
+ A10_MMC_READ_4(sc, A10_MMC_GCTL) | A10_MMC_CTRL_INT_ENB);
return (0);
}
@@ -485,18 +451,12 @@
a10_mmc_reset(sc);
a10_mmc_update_clock(sc);
}
- if (sc->a10_dma_inuse == 0) {
- /* Reset the FIFO. */
- A10_MMC_WRITE_4(sc, A10_MMC_GCTRL,
- A10_MMC_READ_4(sc, A10_MMC_GCTRL) | A10_MMC_FIFO_RESET);
- }
req = sc->a10_req;
callout_stop(&sc->a10_timeoutc);
sc->a10_req = NULL;
sc->a10_intr = 0;
sc->a10_resid = 0;
- sc->a10_dma_inuse = 0;
sc->a10_dma_map_err = 0;
sc->a10_intr_wait = 0;
req->done(req);
@@ -511,8 +471,8 @@
timeout = 1000;
while (--timeout > 0) {
- status = A10_MMC_READ_4(sc, A10_MMC_STAS);
- if ((status & A10_MMC_CARD_DATA_BUSY) == 0)
+ status = A10_MMC_READ_4(sc, A10_MMC_STAR);
+ if ((status & A10_MMC_STAR_CARD_BUSY) == 0)
break;
DELAY(1000);
}
@@ -552,28 +512,6 @@
"Spurious timeout - no active request\n");
}
-static int
-a10_mmc_pio_transfer(struct a10_mmc_softc *sc, struct mmc_data *data)
-{
- int i, write;
- uint32_t bit, *buf;
-
- buf = (uint32_t *)data->data;
- write = (data->flags & MMC_DATA_WRITE) ? 1 : 0;
- bit = write ? A10_MMC_FIFO_FULL : A10_MMC_FIFO_EMPTY;
- for (i = sc->a10_resid; i < (data->len >> 2); i++) {
- if ((A10_MMC_READ_4(sc, A10_MMC_STAS) & bit))
- return (1);
- if (write)
- A10_MMC_WRITE_4(sc, sc->a10_fifo_reg, buf[i]);
- else
- buf[i] = A10_MMC_READ_4(sc, sc->a10_fifo_reg);
- sc->a10_resid = i + 1;
- }
-
- return (0);
-}
-
static void
a10_mmc_intr(void *arg)
{
@@ -584,9 +522,9 @@
sc = (struct a10_mmc_softc *)arg;
A10_MMC_LOCK(sc);
- rint = A10_MMC_READ_4(sc, A10_MMC_RINTR);
+ rint = A10_MMC_READ_4(sc, A10_MMC_RISR);
idst = A10_MMC_READ_4(sc, A10_MMC_IDST);
- imask = A10_MMC_READ_4(sc, A10_MMC_IMASK);
+ imask = A10_MMC_READ_4(sc, A10_MMC_IMKR);
if (idst == 0 && imask == 0 && rint == 0) {
A10_MMC_UNLOCK(sc);
return;
@@ -603,14 +541,14 @@
}
if (rint & A10_MMC_INT_ERR_BIT) {
device_printf(sc->a10_dev, "error rint: 0x%08X\n", rint);
- if (rint & A10_MMC_RESP_TIMEOUT)
+ if (rint & A10_MMC_INT_RESP_TIMEOUT)
sc->a10_req->cmd->error = MMC_ERR_TIMEOUT;
else
sc->a10_req->cmd->error = MMC_ERR_FAILED;
a10_mmc_req_done(sc);
goto end;
}
- if (idst & A10_MMC_IDMAC_ERROR) {
+ if (idst & A10_MMC_IDST_ERROR) {
device_printf(sc->a10_dev, "error idst: 0x%08x\n", idst);
sc->a10_req->cmd->error = MMC_ERR_FAILED;
a10_mmc_req_done(sc);
@@ -619,8 +557,7 @@
sc->a10_intr |= rint;
data = sc->a10_req->cmd->data;
- if (data != NULL && sc->a10_dma_inuse == 1 &&
- (idst & A10_MMC_IDMAC_COMPLETE)) {
+ if (data != NULL && (idst & A10_MMC_IDST_COMPLETE) != 0) {
if (data->flags & MMC_DATA_WRITE)
sync_op = BUS_DMASYNC_POSTWRITE;
else
@@ -631,16 +568,13 @@
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->a10_dma_buf_tag, sc->a10_dma_buf_map);
sc->a10_resid = data->len >> 2;
- } else if (data != NULL && sc->a10_dma_inuse == 0 &&
- (rint & (A10_MMC_DATA_OVER | A10_MMC_RX_DATA_REQ |
- A10_MMC_TX_DATA_REQ)) != 0)
- a10_mmc_pio_transfer(sc, data);
+ }
if ((sc->a10_intr & sc->a10_intr_wait) == sc->a10_intr_wait)
a10_mmc_req_ok(sc);
end:
A10_MMC_WRITE_4(sc, A10_MMC_IDST, idst);
- A10_MMC_WRITE_4(sc, A10_MMC_RINTR, rint);
+ A10_MMC_WRITE_4(sc, A10_MMC_RISR, rint);
A10_MMC_UNLOCK(sc);
}
@@ -650,7 +584,8 @@
int blksz;
struct a10_mmc_softc *sc;
struct mmc_command *cmd;
- uint32_t cmdreg, val;
+ uint32_t cmdreg;
+ int err;
sc = device_get_softc(bus);
A10_MMC_LOCK(sc);
@@ -660,48 +595,39 @@
}
sc->a10_req = req;
cmd = req->cmd;
- cmdreg = A10_MMC_START;
+ cmdreg = A10_MMC_CMDR_LOAD;
if (cmd->opcode == MMC_GO_IDLE_STATE)
- cmdreg |= A10_MMC_SEND_INIT_SEQ;
+ cmdreg |= A10_MMC_CMDR_SEND_INIT_SEQ;
if (cmd->flags & MMC_RSP_PRESENT)
- cmdreg |= A10_MMC_RESP_EXP;
+ cmdreg |= A10_MMC_CMDR_RESP_RCV;
if (cmd->flags & MMC_RSP_136)
- cmdreg |= A10_MMC_LONG_RESP;
+ cmdreg |= A10_MMC_CMDR_LONG_RESP;
if (cmd->flags & MMC_RSP_CRC)
- cmdreg |= A10_MMC_CHECK_RESP_CRC;
+ cmdreg |= A10_MMC_CMDR_CHK_RESP_CRC;
sc->a10_intr = 0;
sc->a10_resid = 0;
- sc->a10_intr_wait = A10_MMC_CMD_DONE;
+ sc->a10_intr_wait = A10_MMC_INT_CMD_DONE;
cmd->error = MMC_ERR_NONE;
if (cmd->data != NULL) {
- sc->a10_intr_wait |= A10_MMC_DATA_OVER;
- cmdreg |= A10_MMC_DATA_EXP | A10_MMC_WAIT_PREOVER;
+ sc->a10_intr_wait |= A10_MMC_INT_DATA_OVER;
+ cmdreg |= A10_MMC_CMDR_DATA_TRANS | A10_MMC_CMDR_WAIT_PRE_OVER;
if (cmd->data->flags & MMC_DATA_MULTI) {
- cmdreg |= A10_MMC_SEND_AUTOSTOP;
- sc->a10_intr_wait |= A10_MMC_AUTOCMD_DONE;
+ cmdreg |= A10_MMC_CMDR_STOP_CMD_FLAG;
+ sc->a10_intr_wait |= A10_MMC_INT_AUTO_STOP_DONE;
}
if (cmd->data->flags & MMC_DATA_WRITE)
- cmdreg |= A10_MMC_WRITE;
+ cmdreg |= A10_MMC_CMDR_DIR_WRITE;
blksz = min(cmd->data->len, MMC_SECTOR_SIZE);
- A10_MMC_WRITE_4(sc, A10_MMC_BLKSZ, blksz);
- A10_MMC_WRITE_4(sc, A10_MMC_BCNTR, cmd->data->len);
-
- if (a10_mmc_pio_mode == 0)
- a10_mmc_prepare_dma(sc);
- /* Enable PIO access if sc->a10_dma_inuse is not set. */
- if (sc->a10_dma_inuse == 0) {
- val = A10_MMC_READ_4(sc, A10_MMC_GCTRL);
- val &= ~A10_MMC_DMA_ENABLE;
- val |= A10_MMC_ACCESS_BY_AHB;
- A10_MMC_WRITE_4(sc, A10_MMC_GCTRL, val);
- val = A10_MMC_READ_4(sc, A10_MMC_IMASK);
- val |= A10_MMC_RX_DATA_REQ | A10_MMC_TX_DATA_REQ;
- A10_MMC_WRITE_4(sc, A10_MMC_IMASK, val);
- }
+ A10_MMC_WRITE_4(sc, A10_MMC_BKSR, blksz);
+ A10_MMC_WRITE_4(sc, A10_MMC_BYCR, cmd->data->len);
+
+ err = a10_mmc_prepare_dma(sc);
+ if (err != 0)
+ device_printf(sc->a10_dev, "prepare_dma failed: %d\n", err);
}
- A10_MMC_WRITE_4(sc, A10_MMC_CARG, cmd->arg);
+ A10_MMC_WRITE_4(sc, A10_MMC_CAGR, cmd->arg);
A10_MMC_WRITE_4(sc, A10_MMC_CMDR, cmdreg | cmd->opcode);
callout_reset(&sc->a10_timeoutc, sc->a10_timeout * hz,
a10_mmc_timeout, sc);
@@ -816,18 +742,18 @@
uint32_t cmdreg;
int retry;
- cmdreg = A10_MMC_START | A10_MMC_UPCLK_ONLY |
- A10_MMC_WAIT_PREOVER;
+ cmdreg = A10_MMC_CMDR_LOAD | A10_MMC_CMDR_PRG_CLK |
+ A10_MMC_CMDR_WAIT_PRE_OVER;
A10_MMC_WRITE_4(sc, A10_MMC_CMDR, cmdreg);
retry = 0xfffff;
while (--retry > 0) {
- if ((A10_MMC_READ_4(sc, A10_MMC_CMDR) & A10_MMC_START) == 0) {
- A10_MMC_WRITE_4(sc, A10_MMC_RINTR, 0xffffffff);
+ if ((A10_MMC_READ_4(sc, A10_MMC_CMDR) & A10_MMC_CMDR_LOAD) == 0) {
+ A10_MMC_WRITE_4(sc, A10_MMC_RISR, 0xffffffff);
return (0);
}
DELAY(10);
}
- A10_MMC_WRITE_4(sc, A10_MMC_RINTR, 0xffffffff);
+ A10_MMC_WRITE_4(sc, A10_MMC_RISR, 0xffffffff);
device_printf(sc->a10_dev, "timeout updating clock\n");
return (ETIMEDOUT);
@@ -842,11 +768,11 @@
uint32_t clkcr;
sc = device_get_softc(bus);
- clkcr = A10_MMC_READ_4(sc, A10_MMC_CLKCR);
- if (clkcr & A10_MMC_CARD_CLK_ON) {
+ clkcr = A10_MMC_READ_4(sc, A10_MMC_CKCR);
+ if (clkcr & A10_MMC_CKCR_CCLK_ENB) {
/* Disable clock. */
- clkcr &= ~A10_MMC_CARD_CLK_ON;
- A10_MMC_WRITE_4(sc, A10_MMC_CLKCR, clkcr);
+ clkcr &= ~A10_MMC_CKCR_CCLK_ENB;
+ A10_MMC_WRITE_4(sc, A10_MMC_CKCR, clkcr);
error = a10_mmc_update_clock(sc);
if (error != 0)
return (error);
@@ -855,8 +781,8 @@
ios = &sc->a10_host.ios;
if (ios->clock) {
/* Reset the divider. */
- clkcr &= ~A10_MMC_CLKCR_DIV;
- A10_MMC_WRITE_4(sc, A10_MMC_CLKCR, clkcr);
+ clkcr &= ~A10_MMC_CKCR_CCLK_DIV;
+ A10_MMC_WRITE_4(sc, A10_MMC_CKCR, clkcr);
error = a10_mmc_update_clock(sc);
if (error != 0)
return (error);
@@ -872,8 +798,8 @@
}
/* Enable clock. */
- clkcr |= A10_MMC_CARD_CLK_ON;
- A10_MMC_WRITE_4(sc, A10_MMC_CLKCR, clkcr);
+ clkcr |= A10_MMC_CKCR_CCLK_ENB;
+ A10_MMC_WRITE_4(sc, A10_MMC_CKCR, clkcr);
error = a10_mmc_update_clock(sc);
if (error != 0)
return (error);
@@ -882,13 +808,13 @@
/* Set the bus width. */
switch (ios->bus_width) {
case bus_width_1:
- A10_MMC_WRITE_4(sc, A10_MMC_WIDTH, A10_MMC_WIDTH1);
+ A10_MMC_WRITE_4(sc, A10_MMC_BWDR, A10_MMC_BWDR1);
break;
case bus_width_4:
- A10_MMC_WRITE_4(sc, A10_MMC_WIDTH, A10_MMC_WIDTH4);
+ A10_MMC_WRITE_4(sc, A10_MMC_BWDR, A10_MMC_BWDR4);
break;
case bus_width_8:
- A10_MMC_WRITE_4(sc, A10_MMC_WIDTH, A10_MMC_WIDTH8);
+ A10_MMC_WRITE_4(sc, A10_MMC_BWDR, A10_MMC_BWDR8);
break;
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Sep 15, 1:49 AM (4 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
38935415
Default Alt Text
D6868.id19017.diff (28 KB)
Attached To
Mode
D6868: Allwinner MMC cleanup
Attached
Detach File
Event Timeline
Log In to Comment