1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2022-05-16     shelton      first version
9  */
10 
11 #ifndef _DRV_SDIO_H
12 #define _DRV_SDIO_H
13 #include <rtthread.h>
14 #include "rtdevice.h"
15 #include <rthw.h>
16 #include <string.h>
17 #include <drivers/dev_mmcsd_core.h>
18 #include <drivers/dev_sdio.h>
19 #include "drv_common.h"
20 
21 #define SDCARD_INSTANCE_TYPE                   sdio_type
22 
23 #define SDCARD_INSTANCE                        SDIO1
24 
25 #define SDIO_BUFF_SIZE                         4096
26 #define SDIO_ALIGN_LEN                         32
27 
28 #ifndef SDIO_BASE_ADDRESS
29 #define SDIO_BASE_ADDRESS                      SDIO1_BASE
30 #endif
31 
32 #ifndef SDIO_CLOCK_FREQ
33 #define SDIO_CLOCK_FREQ                        (48U * 1000 * 1000)
34 #endif
35 
36 #ifndef SDIO_BUFF_SIZE
37 #define SDIO_BUFF_SIZE                         (4096)
38 #endif
39 
40 #ifndef SDIO_ALIGN_LEN
41 #define SDIO_ALIGN_LEN                         (32)
42 #endif
43 
44 #ifndef SDIO_MAX_FREQ
45 #define SDIO_MAX_FREQ                          (24 * 1000 * 1000)
46 #endif
47 
48 #define HW_SDIO_IT_CCRCFAIL                    (0x01U << 0)
49 #define HW_SDIO_IT_DCRCFAIL                    (0x01U << 1)
50 #define HW_SDIO_IT_CTIMEOUT                    (0x01U << 2)
51 #define HW_SDIO_IT_DTIMEOUT                    (0x01U << 3)
52 #define HW_SDIO_IT_TXUNDERR                    (0x01U << 4)
53 #define HW_SDIO_IT_RXOVERR                     (0x01U << 5)
54 #define HW_SDIO_IT_CMDREND                     (0x01U << 6)
55 #define HW_SDIO_IT_CMDSENT                     (0x01U << 7)
56 #define HW_SDIO_IT_DATAEND                     (0x01U << 8)
57 #define HW_SDIO_IT_STBITERR                    (0x01U << 9)
58 #define HW_SDIO_IT_DBCKEND                     (0x01U << 10)
59 #define HW_SDIO_IT_CMDACT                      (0x01U << 11)
60 #define HW_SDIO_IT_TXACT                       (0x01U << 12)
61 #define HW_SDIO_IT_RXACT                       (0x01U << 13)
62 #define HW_SDIO_IT_TXFIFOHE                    (0x01U << 14)
63 #define HW_SDIO_IT_RXFIFOHF                    (0x01U << 15)
64 #define HW_SDIO_IT_TXFIFOF                     (0x01U << 16)
65 #define HW_SDIO_IT_RXFIFOF                     (0x01U << 17)
66 #define HW_SDIO_IT_TXFIFOE                     (0x01U << 18)
67 #define HW_SDIO_IT_RXFIFOE                     (0x01U << 19)
68 #define HW_SDIO_IT_TXDAVL                      (0x01U << 20)
69 #define HW_SDIO_IT_RXDAVL                      (0x01U << 21)
70 #define HW_SDIO_IT_SDIOIT                      (0x01U << 22)
71 
72 #define HW_SDIO_ERRORS \
73     (HW_SDIO_IT_CCRCFAIL | HW_SDIO_IT_CTIMEOUT | \
74      HW_SDIO_IT_DCRCFAIL | HW_SDIO_IT_DTIMEOUT | \
75      HW_SDIO_IT_RXOVERR  | HW_SDIO_IT_TXUNDERR)
76 
77 #define HW_SDIO_POWER_OFF                      (0x00U)
78 #define HW_SDIO_POWER_UP                       (0x02U)
79 #define HW_SDIO_POWER_ON                       (0x03U)
80 
81 #define HW_SDIO_FLOW_ENABLE                    (0x01U << 14)
82 #define HW_SDIO_BUSWIDE_1B                     (0x00U << 11)
83 #define HW_SDIO_BUSWIDE_4B                     (0x01U << 11)
84 #define HW_SDIO_BUSWIDE_8B                     (0x02U << 11)
85 #define HW_SDIO_BYPASS_ENABLE                  (0x01U << 10)
86 #define HW_SDIO_IDLE_ENABLE                    (0x01U << 9)
87 #define HW_SDIO_CLK_ENABLE                     (0x01U << 8)
88 
89 #define HW_SDIO_SUSPEND_CMD                    (0x01U << 11)
90 #define HW_SDIO_CPSM_ENABLE                    (0x01U << 10)
91 #define HW_SDIO_WAIT_END                       (0x01U << 9)
92 #define HW_SDIO_WAIT_INT                       (0x01U << 8)
93 #define HW_SDIO_RESPONSE_NO                    (0x00U << 6)
94 #define HW_SDIO_RESPONSE_SHORT                 (0x01U << 6)
95 #define HW_SDIO_RESPONSE_LONG                  (0x03U << 6)
96 
97 #define HW_SDIO_DATA_LEN_MASK                  (0x01FFFFFFU)
98 
99 #define HW_SDIO_IO_ENABLE                      (0x01U << 11)
100 #define HW_SDIO_RWMOD_CK                       (0x01U << 10)
101 #define HW_SDIO_RWSTOP_ENABLE                  (0x01U << 9)
102 #define HW_SDIO_RWSTART_ENABLE                 (0x01U << 8)
103 #define HW_SDIO_DBLOCKSIZE_1                   (0x00U << 4)
104 #define HW_SDIO_DBLOCKSIZE_2                   (0x01U << 4)
105 #define HW_SDIO_DBLOCKSIZE_4                   (0x02U << 4)
106 #define HW_SDIO_DBLOCKSIZE_8                   (0x03U << 4)
107 #define HW_SDIO_DBLOCKSIZE_16                  (0x04U << 4)
108 #define HW_SDIO_DBLOCKSIZE_32                  (0x05U << 4)
109 #define HW_SDIO_DBLOCKSIZE_64                  (0x06U << 4)
110 #define HW_SDIO_DBLOCKSIZE_128                 (0x07U << 4)
111 #define HW_SDIO_DBLOCKSIZE_256                 (0x08U << 4)
112 #define HW_SDIO_DBLOCKSIZE_512                 (0x09U << 4)
113 #define HW_SDIO_DBLOCKSIZE_1024                (0x0AU << 4)
114 #define HW_SDIO_DBLOCKSIZE_2048                (0x0BU << 4)
115 #define HW_SDIO_DBLOCKSIZE_4096                (0x0CU << 4)
116 #define HW_SDIO_DBLOCKSIZE_8192                (0x0DU << 4)
117 #define HW_SDIO_DBLOCKSIZE_16384               (0x0EU << 4)
118 #define HW_SDIO_DMA_ENABLE                     (0x01U << 3)
119 #define HW_SDIO_STREAM_ENABLE                  (0x01U << 2)
120 #define HW_SDIO_TO_HOST                        (0x01U << 1)
121 #define HW_SDIO_DPSM_ENABLE                    (0x01U << 0)
122 
123 #define HW_SDIO_DATATIMEOUT                    (0xF0000000U)
124 
125 struct at32_sdio
126 {
127     volatile rt_uint32_t power;
128     volatile rt_uint32_t clkcr;
129     volatile rt_uint32_t arg;
130     volatile rt_uint32_t cmd;
131     volatile rt_uint32_t respcmd;
132     volatile rt_uint32_t resp1;
133     volatile rt_uint32_t resp2;
134     volatile rt_uint32_t resp3;
135     volatile rt_uint32_t resp4;
136     volatile rt_uint32_t dtimer;
137     volatile rt_uint32_t dlen;
138     volatile rt_uint32_t dctrl;
139     volatile rt_uint32_t dcount;
140     volatile rt_uint32_t sta;
141     volatile rt_uint32_t icr;
142     volatile rt_uint32_t mask;
143     volatile rt_uint32_t reserved0[2];
144     volatile rt_uint32_t fifocnt;
145     volatile rt_uint32_t reserved1[13];
146     volatile rt_uint32_t fifo;
147 };
148 
149 typedef rt_err_t (*dma_txconfig)(rt_uint32_t *src, rt_uint32_t *dst, int size);
150 typedef rt_err_t (*dma_rxconfig)(rt_uint32_t *src, rt_uint32_t *dst, int size);
151 typedef rt_uint32_t (*sdio_clk_get)(struct at32_sdio *hw_sdio);
152 
153 #if defined (SOC_SERIES_AT32F435) || defined (SOC_SERIES_AT32F437) || \
154     defined (SOC_SERIES_AT32F455) || defined (SOC_SERIES_AT32F456) || \
155     defined (SOC_SERIES_AT32F457)
156 #define SDIO_BUS_CONFIG                                  \
157     {                                                    \
158         .sdio_x = SDIO1,                                 \
159         .dma_rx.dma_x = DMA2,                            \
160         .dma_tx.dma_x = DMA2,                            \
161         .dma_rx.dma_crm = CRM_DMA2_PERIPH_CLOCK,         \
162         .dma_tx.dma_crm = CRM_DMA2_PERIPH_CLOCK,         \
163         .dma_rx.dma_channel = DMA2_CHANNEL4,             \
164         .dma_tx.dma_channel = DMA2_CHANNEL4,             \
165         .dma_rx.dma_irq = DMA2_Channel4_IRQn,            \
166         .dma_tx.dma_irq = DMA2_Channel4_IRQn,            \
167         .dma_rx.dmamux_channel = DMA2MUX_CHANNEL4,       \
168         .dma_tx.dmamux_channel = DMA2MUX_CHANNEL4,       \
169         .dma_rx.dmamux_id = DMAMUX_DMAREQ_ID_SDIO1,      \
170         .dma_tx.dmamux_id = DMAMUX_DMAREQ_ID_SDIO1,      \
171     }
172 #else
173 #define SDIO_BUS_CONFIG                                  \
174     {                                                    \
175         .sdio_x = SDIO1,                                 \
176         .dma_rx.dma_crm = CRM_DMA2_PERIPH_CLOCK,         \
177         .dma_tx.dma_crm = CRM_DMA2_PERIPH_CLOCK,         \
178         .dma_rx.dma_channel = DMA2_CHANNEL4,             \
179         .dma_rx.dma_irq = DMA2_Channel4_5_IRQn,          \
180         .dma_tx.dma_channel = DMA2_CHANNEL4,             \
181         .dma_tx.dma_irq = DMA2_Channel4_5_IRQn,          \
182     }
183 #endif
184 
185 struct dma_config {
186     dma_type *dma_x;
187     dma_channel_type *dma_channel;
188 #if defined (SOC_SERIES_AT32F435) || defined (SOC_SERIES_AT32F437) || \
189     defined (SOC_SERIES_AT32F455) || defined (SOC_SERIES_AT32F456) || \
190     defined (SOC_SERIES_AT32F457)
191     dmamux_channel_type *dmamux_channel;
192     dmamux_requst_id_sel_type dmamux_id;
193 #endif
194     crm_periph_clock_type dma_crm;
195     IRQn_Type dma_irq;
196 };
197 
198 struct at32_sdio_des
199 {
200     struct at32_sdio *hw_sdio;
201     dma_txconfig txconfig;
202     dma_rxconfig rxconfig;
203     sdio_clk_get clk_get;
204 };
205 
206 struct at32_sdio_config
207 {
208     SDCARD_INSTANCE_TYPE *sdio_x;
209     struct dma_config dma_rx, dma_tx;
210 };
211 
212 /* at32 sdio dirver class */
213 struct at32_sdio_class
214 {
215     struct at32_sdio_des *des;
216     const struct at32_sdio_config *cfg;
217     struct rt_mmcsd_host host;
218     struct
219     {
220         dma_channel_type* handle_rx;
221         dma_channel_type* handle_tx;
222     } dma;
223 };
224 
225 extern void at32_mmcsd_change(void);
226 
227 #endif
228