summaryrefslogtreecommitdiff
path: root/include/dwmmc.h
diff options
context:
space:
mode:
authorSam Protsenko <[email protected]>2024-08-07 22:14:16 -0500
committerMinkyu Kang <[email protected]>2024-08-19 16:09:06 +0900
commite760a245e2c5463a91fd86b122a35aed91326232 (patch)
tree51696c6a65d5b816e6efed8cd5fdb19227f7a7bd /include/dwmmc.h
parent61f47c81a9fa695e975c359f4d8c7ade286c0c49 (diff)
mmc: dw_mmc: Add support for 64-bit IDMAC
Some DW MMC blocks (e.g. those on modern Exynos chips) support 64-bit DMA addressing mode. 64-bit DW MMC variants differ from their 32-bit counterparts: - the register layout is a bit different (because there are additional IDMAC registers present for storing upper part of 64-bit addresses) - DMA descriptor structure is bigger and different from 32-bit one Introduce all necessary changes to enable support for 64-bit DMA capable DW MMC blocks. Next changes were made: 1. Check which DMA address mode is supported in current IP-core version. HCON register (bit 27) indicates whether it's 32-bit or 64-bit addressing. Add boolean .dma_64bit_address field to struct dwmci_host and store the result there. dwmci_init_dma() function is introduced for doing so, which is called on driver's init. 2. Add 64-bit DMA descriptor (struct dwmci_idmac64) and use it in dwmci_prepare_desc() in case if .dma_64bit_address field is true. A new dwmci_set_idma_desc64() function was added for populating that descriptor. 3. Add registers for 64-bit DMA capable blocks. To make the access to IDMAC registers universal between 32-bit / 64-bit cases, a new struct dwmci_idmac_regs (and corresponding host->regs field) was introduced, which abstracts the hardware by being set to appropriate offset constants on init. All direct calls to IDMAC registers were correspondingly replaced by accessing host->regs. 4. Allocate and use 64-bit DMA descriptors buffer in case when IDMAC is 64-bit capable. Extract all the code (except for the IDMAC descriptors buffer allocation) from dwmci_send_cmd() to dwmci_send_cmd_common(), so that it's possible to keep IDMAC buffer (either 32-bit or 64-bit) on stack during send_cmd routine. The insights for this implementation were taken from Linux kernel DW MMC driver. Signed-off-by: Sam Protsenko <[email protected]> Signed-off-by: Minkyu Kang <[email protected]>
Diffstat (limited to 'include/dwmmc.h')
-rw-r--r--include/dwmmc.h39
1 files changed, 38 insertions, 1 deletions
diff --git a/include/dwmmc.h b/include/dwmmc.h
index 7e4acf096dc..de18fda68ac 100644
--- a/include/dwmmc.h
+++ b/include/dwmmc.h
@@ -44,12 +44,22 @@
#define DWMCI_UHS_REG 0x074
#define DWMCI_BMOD 0x080
#define DWMCI_PLDMND 0x084
+#define DWMCI_DATA 0x200
+/* Registers to support IDMAC 32-bit address mode */
#define DWMCI_DBADDR 0x088
#define DWMCI_IDSTS 0x08C
#define DWMCI_IDINTEN 0x090
#define DWMCI_DSCADDR 0x094
#define DWMCI_BUFADDR 0x098
-#define DWMCI_DATA 0x200
+/* Registers to support IDMAC 64-bit address mode */
+#define DWMCI_DBADDRL 0x088
+#define DWMCI_DBADDRU 0x08c
+#define DWMCI_IDSTS64 0x090
+#define DWMCI_IDINTEN64 0x094
+#define DWMCI_DSCADDRL 0x098
+#define DWMCI_DSCADDRU 0x09c
+#define DWMCI_BUFADDRL 0x0a0
+#define DWMCI_BUFADDRU 0x0a4
/* Interrupt Mask register */
#define DWMCI_INTMSK_ALL 0xffffffff
@@ -143,6 +153,29 @@
#define DWMCI_QUIRK_DISABLE_SMU (1 << 0)
/**
+ * struct dwmci_idmac_regs - Offsets of IDMAC registers
+ *
+ * @dbaddrl: Descriptor base address, lower 32 bits
+ * @dbaddru: Descriptor base address, upper 32 bits
+ * @idsts: Internal DMA status
+ * @idinten: Internal DMA interrupt enable
+ * @dscaddrl: IDMAC descriptor address, lower 32 bits
+ * @dscaddru: IDMAC descriptor address, upper 32 bits
+ * @bufaddrl: Current data buffer address, lower 32 bits
+ * @bufaddru: Current data buffer address, upper 32 bits
+ */
+struct dwmci_idmac_regs {
+ u32 dbaddrl;
+ u32 dbaddru;
+ u32 idsts;
+ u32 idinten;
+ u32 dscaddrl;
+ u32 dscaddru;
+ u32 bufaddrl;
+ u32 bufaddru;
+};
+
+/**
* struct dwmci_host - Information about a designware MMC host
*
* @name: Device name
@@ -157,6 +190,8 @@
* @fifoth_val: Value for FIFOTH register (or 0 to leave unset)
* @mmc: Pointer to generic MMC structure for this device
* @priv: Private pointer for use by controller
+ * @dma_64bit_address: Whether DMA supports 64-bit address mode or not
+ * @regs: Registers that can vary for different DW MMC block versions
*/
struct dwmci_host {
const char *name;
@@ -196,6 +231,8 @@ struct dwmci_host {
/* use fifo mode to read and write data */
bool fifo_mode;
+ bool dma_64bit_address;
+ const struct dwmci_idmac_regs *regs;
};
static inline void dwmci_writel(struct dwmci_host *host, int reg, u32 val)