• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "himci.h"
17 #include "himci_proc.h"
18 
19 #define HDF_LOG_TAG himci_adapter
20 
21 #define HIMCI_PIN_NUM 6
22 #define HIMCI_VOLT_SWITCH_TIMEOUT 10
23 #define HIMCI_PHASE_DLL_START_ELEMENT 2
24 
HimciDumpRegs(struct HimciHost * host)25 static void HimciDumpRegs(struct HimciHost *host)
26 {
27     HDF_LOGE(": =========== DUMP (host%u) REGISTER===========", host->id);
28     HDF_LOGE(": CTRL : 0x%08x | PWREN:  0x%04x",
29         HIMCI_READL((uintptr_t)host->base + MMC_CTRL), HIMCI_READL((uintptr_t)host->base + MMC_PWREN));
30     HDF_LOGE(": CLKDIV : 0x%08x | CLKENA:  0x%04x",
31         HIMCI_READL((uintptr_t)host->base + MMC_CLKDIV), HIMCI_READL((uintptr_t)host->base + MMC_CLKENA));
32     HDF_LOGE(": TMOUT : 0x%08x | CTYPE:  0x%04x",
33         HIMCI_READL((uintptr_t)host->base + MMC_TMOUT), HIMCI_READL((uintptr_t)host->base + MMC_CTYPE));
34     HDF_LOGE(": BLKSIZ : 0x%08x | BYTCNT:  0x%04x",
35         HIMCI_READL((uintptr_t)host->base + MMC_BLKSIZ), HIMCI_READL((uintptr_t)host->base + MMC_BYTCNT));
36     HDF_LOGE(": CMD : 0x%08x | CMDARG:  0x%04x",
37         HIMCI_READL((uintptr_t)host->base + MMC_CMD), HIMCI_READL((uintptr_t)host->base + MMC_CMDARG));
38     HDF_LOGE(": RESP0 : 0x%08x | RESP1:  0x%04x",
39         HIMCI_READL((uintptr_t)host->base + MMC_RESP0), HIMCI_READL((uintptr_t)host->base + MMC_RESP1));
40     HDF_LOGE(": RESP2 : 0x%08x | RESP3:  0x%04x",
41         HIMCI_READL((uintptr_t)host->base + MMC_RESP2), HIMCI_READL((uintptr_t)host->base + MMC_RESP3));
42     HDF_LOGE(": RINTSTS : 0x%08x | STATUS:  0x%04x",
43         HIMCI_READL((uintptr_t)host->base + MMC_RINTSTS), HIMCI_READL((uintptr_t)host->base + MMC_STATUS));
44     HDF_LOGE(": BMOD : 0x%08x | IDSTS:  0x%04x",
45         HIMCI_READL((uintptr_t)host->base + MMC_BMOD), HIMCI_READL((uintptr_t)host->base + MMC_IDSTS));
46     HDF_LOGE(": IDINTEN : 0x%08x | CARDTHRCTL : 0x%08x",
47         HIMCI_READL((uintptr_t)host->base + MMC_IDINTEN), HIMCI_READL((uintptr_t)host->base + MMC_CARDTHRCTL));
48     HDF_LOGE(": DDR_REG:  0x%04x | ENABLE_SHIFT : 0x%08x",
49         HIMCI_READL((uintptr_t)host->base + MMC_EMMC_DDR_REG), HIMCI_READL((uintptr_t)host->base + MMC_ENABLE_SHIFT));
50     HDF_LOGE(": =============================================");
51 }
52 
HimciSetEmmcDrvCap(struct MmcCntlr * cntlr)53 static void HimciSetEmmcDrvCap(struct MmcCntlr *cntlr)
54 {
55     uint32_t i, j, val;
56     uint32_t *pinDrvCap = NULL;
57     /*  clk   cmd   data0  data1  data2  data3 */
58     uint32_t emmcHs200Drv[] = { 0x2b0, 0x1c0, 0x1c0, 0x1c0, 0x1c0, 0x1c0 };
59     uint32_t emmcHsDrv[] = { 0x6b0, 0x5e0, 0x5e0, 0x5e0, 0x5e0, 0x5e0 };
60     uint32_t emmcDsDrv[] = { 0x6b0, 0x5f0, 0x5f0, 0x5f0, 0x5f0, 0x5f0 };
61     uint32_t emmcDs400kDrv[] = { 0x6c0, 0x5f0, 0x5f0, 0x5f0, 0x5f0, 0x5f0 };
62 
63     if (cntlr->curDev->workPara.timing == BUS_TIMING_MMC_HS200) {
64         pinDrvCap = emmcHs200Drv;
65     } else if (cntlr->curDev->workPara.timing == BUS_TIMING_MMC_HS) {
66         pinDrvCap = emmcHsDrv;
67     } else {
68         if (cntlr->curDev->workPara.clock == 400000) {
69             pinDrvCap = emmcDs400kDrv;
70         } else {
71             pinDrvCap = emmcDsDrv;
72         }
73     }
74 
75     for (i = REG_CTRL_EMMC_START, j = 0; j < HIMCI_PIN_NUM; i = i + REG_CTRL_NUM, j++) {
76         val = HIMCI_READL(i);
77         /*
78          * [10]:SR
79          * [9]:internel pull down
80          * [8]:internel pull up
81          */
82         val = val & (~(0x7f0));
83         val |= pinDrvCap[j];
84         HIMCI_WRITEL(val, i);
85     }
86 }
87 
HimciSetSdDrvCap(struct MmcCntlr * cntlr)88 static void HimciSetSdDrvCap(struct MmcCntlr *cntlr)
89 {
90     uint32_t i, j, val;
91     uint32_t *pinDrvCap = NULL;
92     /*  clk   cmd   data0  data1  data2  data3 */
93     uint32_t sdSdr104Drv[] = { 0x290, 0x1c0, 0x1c0, 0x1c0, 0x1c0, 0x1c0 };
94     uint32_t sdSdr50Drv[] = { 0x290, 0x1c0, 0x1c0, 0x1c0, 0x1c0, 0x1c0 };
95     uint32_t sdSdr25Drv[] = { 0x6b0, 0x5d0, 0x5d0, 0x5d0, 0x5d0, 0x5d0 };
96     uint32_t sdSdr12Drv[] = { 0x6b0, 0x5e0, 0x5e0, 0x5e0, 0x5e0, 0x5e0 };
97     uint32_t sdHsDrv[] = { 0x6d0, 0x5f0, 0x5f0, 0x5f0, 0x5f0, 0x5f0 };
98     uint32_t sdDsDrv[] = { 0x6b0, 0x5e0, 0x5e0, 0x5e0, 0x5e0, 0x5e0 };
99 
100     if (cntlr->curDev->workPara.timing == BUS_TIMING_UHS_SDR104) {
101         pinDrvCap = sdSdr104Drv;
102     } else if (cntlr->curDev->workPara.timing == BUS_TIMING_UHS_SDR50) {
103         pinDrvCap = sdSdr50Drv;
104     } else if (cntlr->curDev->workPara.timing == BUS_TIMING_UHS_SDR25) {
105         pinDrvCap = sdSdr25Drv;
106     } else if (cntlr->curDev->workPara.timing == BUS_TIMING_UHS_SDR12) {
107         pinDrvCap = sdSdr12Drv;
108     } else if (cntlr->curDev->workPara.timing == BUS_TIMING_SD_HS) {
109         pinDrvCap = sdHsDrv;
110     } else {
111         pinDrvCap = sdDsDrv;
112     }
113 
114     for (i = REG_CTRL_SD_START, j = 0; j < HIMCI_PIN_NUM; i = i + REG_CTRL_NUM, j++) {
115         val = HIMCI_READL(i);
116         /*
117          * [10]:SR
118          * [9]:internel pull down
119          * [8]:internel pull up
120          */
121         val = val & (~(0x7f0));
122         val |= pinDrvCap[j];
123         HIMCI_WRITEL(val, i);
124     }
125 }
126 
HimciSetSdioDrvCap(struct MmcCntlr * cntlr)127 static void HimciSetSdioDrvCap(struct MmcCntlr *cntlr)
128 {
129     uint32_t i, j, val;
130     uint32_t *pinDrvCap = NULL;
131     /*  clk   cmd   data0  data1  data2  data3 */
132     uint32_t sdioSdr104Drv[] = { 0x290, 0x1c0, 0x1c0, 0x1c0, 0x1c0, 0x1c0 };
133     uint32_t sdioSdr50Drv[] = { 0x290, 0x1c0, 0x1c0, 0x1c0, 0x1c0, 0x1c0 };
134     uint32_t sdioSdr25Drv[] = { 0x6b0, 0x5d0, 0x5d0, 0x5d0, 0x5d0, 0x5d0 };
135     uint32_t sdioSdr12Drv[] = { 0x6b0, 0x5e0, 0x5e0, 0x5e0, 0x5e0, 0x5e0 };
136     uint32_t sdioHsDrv[] = { 0x6d0, 0x5f0, 0x5f0, 0x5f0, 0x5f0, 0x5f0 };
137     uint32_t sdioDsDrv[] = { 0x6b0, 0x5e0, 0x5e0, 0x5e0, 0x5e0, 0x5e0 };
138 
139     if (cntlr->curDev->workPara.timing == BUS_TIMING_UHS_SDR104) {
140         pinDrvCap = sdioSdr104Drv;
141     } else if (cntlr->curDev->workPara.timing == BUS_TIMING_UHS_SDR50) {
142         pinDrvCap = sdioSdr50Drv;
143     } else if (cntlr->curDev->workPara.timing == BUS_TIMING_UHS_SDR25) {
144         pinDrvCap = sdioSdr25Drv;
145     } else if (cntlr->curDev->workPara.timing == BUS_TIMING_UHS_SDR12) {
146         pinDrvCap = sdioSdr12Drv;
147     } else if (cntlr->curDev->workPara.timing == BUS_TIMING_SD_HS) {
148         pinDrvCap = sdioHsDrv;
149     } else {
150         pinDrvCap = sdioDsDrv;
151     }
152 
153     for (i = REG_CTRL_SDIO_START, j = 0; j < HIMCI_PIN_NUM; i = i + REG_CTRL_NUM, j++) {
154         val = HIMCI_READL(i);
155         /*
156          * [10]:SR
157          * [9]:internel pull down
158          * [8]:internel pull up
159          */
160         val = val & (~(0x7f0));
161         val |= pinDrvCap[j];
162         HIMCI_WRITEL(val, i);
163     }
164 }
165 
HimciSetDrvCap(struct MmcCntlr * cntlr)166 static void HimciSetDrvCap(struct MmcCntlr *cntlr)
167 {
168     if (cntlr == NULL) {
169         return;
170     }
171 
172     if (cntlr->devType == MMC_DEV_EMMC) {
173         HimciSetEmmcDrvCap(cntlr);
174     } else if (cntlr->devType == MMC_DEV_SD) {
175         HimciSetSdDrvCap(cntlr);
176     } else {
177         HimciSetSdioDrvCap(cntlr);
178     }
179 }
180 
HimciClkDiv(struct HimciHost * host,uint32_t clock)181 static uint32_t HimciClkDiv(struct HimciHost *host, uint32_t clock)
182 {
183     uint32_t clkDiv = 0;
184     uint32_t val, hostClk, debounce;
185     uint32_t regs[] = { PERI_CRG82, PERI_CRG88, PERI_CRG85 };
186 
187     val = HIMCI_READL(regs[host->id]);
188     val &= ~(HIMCI_CLK_SEL_MASK);
189     if (clock >= HIMCI_MMC_FREQ_150M) {
190         hostClk = HIMCI_MMC_FREQ_150M;
191         debounce = DEBOUNCE_E;
192     } else if (clock >= HIMCI_MMC_FREQ_100M) {
193         hostClk = HIMCI_MMC_FREQ_100M;
194         val |= HIMCI_CLK_SEL_100M;
195         debounce = DEBOUNCE_H;
196     } else if (clock >= HIMCI_MMC_FREQ_50M) {
197         hostClk = HIMCI_MMC_FREQ_50M;
198         val |= HIMCI_CLK_SEL_50M;
199         debounce = DEBOUNCE_M;
200     } else if (clock >= HIMCI_MMC_FREQ_25M) {
201         hostClk = HIMCI_MMC_FREQ_25M;
202         val |= HIMCI_CLK_SEL_25M;
203         debounce = DEBOUNCE_L;
204     } else {
205         if (clock > (HIMCI_MMC_FREQ_150M / CLK_DIVIDER)) {
206             hostClk = HIMCI_MMC_FREQ_150M;
207             debounce = DEBOUNCE_E;
208         } else if (clock > (HIMCI_MMC_FREQ_100M / CLK_DIVIDER)) {
209             val |= HIMCI_CLK_SEL_100M;
210             hostClk = HIMCI_MMC_FREQ_100M;
211             debounce = DEBOUNCE_H;
212         } else if (clock > (HIMCI_MMC_FREQ_50M / CLK_DIVIDER)) {
213             val |= HIMCI_CLK_SEL_50M;
214             hostClk = HIMCI_MMC_FREQ_50M;
215             debounce = DEBOUNCE_M;
216         } else {
217             val |= HIMCI_CLK_SEL_25M;
218             hostClk = HIMCI_MMC_FREQ_25M;
219             debounce = DEBOUNCE_L;
220         }
221         clkDiv = hostClk / (clock * 2);
222         if (hostClk % (clock * 2) > 0) {
223             clkDiv++;
224         }
225         if (clkDiv > MAX_CLKDIV_VAL) {
226             clkDiv = MAX_CLKDIV_VAL;
227         }
228     }
229     HIMCI_WRITEL(debounce, (uintptr_t)host->base + MMC_DEBNCE);
230     HIMCI_WRITEL(val, regs[host->id]);
231     HIMCI_WRITEL(clkDiv, (uintptr_t)host->base + MMC_CLKDIV);
232 
233     return hostClk;
234 }
235 
HimciDmaReset(struct HimciHost * host)236 static void HimciDmaReset(struct HimciHost *host)
237 {
238     uint32_t val;
239 
240     val = HIMCI_READL((uintptr_t)host->base + MMC_BMOD);
241     val |= BMOD_SWR;
242     HIMCI_WRITEL(val, (uintptr_t)host->base + MMC_BMOD);
243 
244     val = HIMCI_READL((uintptr_t)host->base + MMC_CTRL);
245     val |= CTRL_RESET | FIFO_RESET | DMA_RESET;
246     HIMCI_WRITEL(val, (uintptr_t)host->base + MMC_CTRL);
247 
248     OsalUDelay(1);
249     HIMCI_WRITEL(ALL_INT_CLR, (uintptr_t)host->base + MMC_RINTSTS);
250 }
251 
HimciDmaStart(struct HimciHost * host)252 static void HimciDmaStart(struct HimciHost *host)
253 {
254     uint32_t val;
255 
256     HIMCI_WRITEL(host->dmaPaddr, (uintptr_t)host->base + MMC_DBADDR);
257     val = HIMCI_READL((uintptr_t)host->base + MMC_BMOD);
258     val |= BMOD_DMA_EN;
259     HIMCI_WRITEL(val, (uintptr_t)host->base + MMC_BMOD);
260 }
261 
HimciDmaStop(struct HimciHost * host)262 static void HimciDmaStop(struct HimciHost *host)
263 {
264     uint32_t val;
265 
266     val = HIMCI_READL((uintptr_t)host->base + MMC_BMOD);
267     val &= (~BMOD_DMA_EN);
268     HIMCI_WRITEL(val, (uintptr_t)host->base + MMC_BMOD);
269 }
270 
HimciDmaCacheClean(void * addr,uint32_t size)271 static void HimciDmaCacheClean(void *addr, uint32_t size)
272 {
273     addr = (void *)(uintptr_t)DMA_TO_VMM_ADDR((paddr_t)(uintptr_t)addr);
274     uint32_t start = (uintptr_t)addr & ~(CACHE_ALIGNED_SIZE - 1);
275     uint32_t end = (uintptr_t)addr + size;
276 
277     end = ALIGN(end, CACHE_ALIGNED_SIZE);
278     DCacheFlushRange(start, end);
279 }
280 
HimciDmaCacheInv(void * addr,uint32_t size)281 static void HimciDmaCacheInv(void *addr, uint32_t size)
282 {
283     addr = (void *)(uintptr_t)DMA_TO_VMM_ADDR((paddr_t)(uintptr_t)addr);
284     uint32_t start = (uintptr_t)addr & ~(CACHE_ALIGNED_SIZE - 1);
285     uint32_t end = (uintptr_t)addr + size;
286 
287     end = ALIGN(end, CACHE_ALIGNED_SIZE);
288     DCacheInvRange(start, end);
289 }
290 
HimciIsMultiBlock(struct MmcCmd * cmd)291 static bool HimciIsMultiBlock(struct MmcCmd *cmd)
292 {
293     if (cmd->cmdCode == WRITE_MULTIPLE_BLOCK || cmd->cmdCode == READ_MULTIPLE_BLOCK) {
294         return true;
295     }
296     if (cmd->data->blockNum > 1) {
297         return true;
298     }
299     return false;
300 }
301 
HimciNeedAutoStop(struct MmcCntlr * cntlr)302 static bool HimciNeedAutoStop(struct MmcCntlr *cntlr)
303 {
304     if (cntlr->curDev->type == MMC_DEV_SDIO) {
305         return false;
306     }
307 
308     if (((cntlr->curDev->type == MMC_DEV_SD || cntlr->curDev->type == MMC_DEV_COMBO) &&
309         MmcCntlrSdSupportCmd23(cntlr) == false) ||
310         (cntlr->curDev->type == MMC_DEV_EMMC && MmcCntlrEmmcSupportCmd23(cntlr) == false)) {
311         return true;
312     }
313     if (cntlr->caps.bits.cmd23 > 0) {
314         /* both host and device support cmd23. */
315         return false;
316     }
317 
318     /* the device support cmd23 but host doesn't support cmd23 */
319     return true;
320 }
321 
HimciFillCmdReg(union HimciCmdRegArg * reg,struct MmcCmd * cmd)322 static int32_t HimciFillCmdReg(union HimciCmdRegArg *reg, struct MmcCmd *cmd)
323 {
324     if (cmd->cmdCode == STOP_TRANSMISSION) {
325         reg->bits.stopAbortCmd = 1;
326         reg->bits.waitDataComplete = 0;
327     } else {
328         reg->bits.stopAbortCmd = 0;
329         reg->bits.waitDataComplete = 1;
330     }
331 
332     switch (MMC_RESP_TYPE(cmd)) {
333         case MMC_RESP_NONE:
334             reg->bits.rspExpect = 0;
335             reg->bits.rspLen = 0;
336             reg->bits.checkRspCrc = 0;
337             break;
338         case MMC_RESP_R1:
339         case MMC_RESP_R1B:
340             reg->bits.rspExpect = 1;
341             reg->bits.rspLen = 0;
342             reg->bits.checkRspCrc = 1;
343             break;
344         case MMC_RESP_R2:
345             reg->bits.rspExpect = 1;
346             reg->bits.rspLen = 1;
347             reg->bits.checkRspCrc = 1;
348             break;
349         case MMC_RESP_R3:
350         case MMC_RESP_R1 & (~RESP_CRC):
351             reg->bits.rspExpect = 1;
352             reg->bits.rspLen = 0;
353             reg->bits.checkRspCrc = 0;
354             break;
355         default:
356             cmd->returnError = HDF_ERR_INVALID_PARAM;
357             HDF_LOGE("unhandled response type 0x%x", MMC_RESP_TYPE(cmd));
358             return HDF_ERR_INVALID_PARAM;
359     }
360 
361     reg->bits.sendInitialization = 0;
362     if (cmd->cmdCode == GO_IDLE_STATE) {
363         reg->bits.sendInitialization = 1;
364     }
365     /* CMD 11 check switch voltage */
366     reg->bits.voltSwitch = 0;
367     if (cmd->cmdCode == SD_CMD_SWITCH_VOLTAGE) {
368         reg->bits.voltSwitch = 1;
369     }
370 
371     reg->bits.cardNumber = 0;
372     reg->bits.cmdIndex = cmd->cmdCode;
373     reg->bits.startCmd = 1;
374     reg->bits.updateClkRegOnly = 0;
375     return HDF_SUCCESS;
376 }
377 
HimciUpdateCmdReg(union HimciCmdRegArg * reg,struct HimciHost * host)378 static int32_t HimciUpdateCmdReg(union HimciCmdRegArg *reg, struct HimciHost *host)
379 {
380     struct MmcCmd *cmd = host->cmd;
381     struct MmcData *data = cmd->data;
382 
383     if (data != NULL) {
384         reg->bits.dataTransferExpected = 1;
385         if ((data->dataFlags & (DATA_WRITE | DATA_READ)) > 0) {
386             reg->bits.transferMode = 0;
387         }
388         if ((data->dataFlags & DATA_STREAM) > 0) {
389             reg->bits.transferMode = 1;
390         }
391         if ((data->dataFlags & DATA_WRITE) > 0) {
392             reg->bits.readWrite = 1;
393         } else if ((data->dataFlags & DATA_READ) > 0) {
394             reg->bits.readWrite = 0;
395         }
396         reg->bits.sendAutoStop = 0;
397         if (HimciIsMultiBlock(cmd) == true && HimciNeedAutoStop(host->mmc) == true) {
398             reg->bits.sendAutoStop = 1;
399         }
400     } else {
401         reg->bits.dataTransferExpected = 0;
402         reg->bits.transferMode = 0;
403         reg->bits.readWrite = 0;
404     }
405 
406     if (HimciFillCmdReg(reg, cmd) != HDF_SUCCESS) {
407         return HDF_FAILURE;
408     }
409     return HDF_SUCCESS;
410 }
411 
HimciExecCmd(struct HimciHost * host)412 static int32_t HimciExecCmd(struct HimciHost *host)
413 {
414     union HimciCmdRegArg cmdRegs;
415     int32_t ret;
416     struct MmcCmd *cmd = host->cmd;
417 
418     HIMCI_WRITEL(cmd->argument, (uintptr_t)host->base + MMC_CMDARG);
419     cmdRegs.arg = HIMCI_READL((uintptr_t)host->base + MMC_CMD);
420     ret = HimciUpdateCmdReg(&cmdRegs, host);
421     if (ret != HDF_SUCCESS) {
422         return ret;
423     }
424     HIMCI_WRITEL(cmdRegs.arg, (uintptr_t)host->base + MMC_CMD);
425     return HDF_SUCCESS;
426 }
427 
HimciWaitCmd(struct HimciHost * host)428 static int32_t HimciWaitCmd(struct HimciHost *host)
429 {
430     int32_t reties = 0;
431     uint32_t val;
432     unsigned long flags = 0;
433 
434     while (true) {
435         /*
436          * Check if CMD start_cmd bit is clear.
437          * start_cmd = 0 means MMC Host controller has loaded registers and next command can be loaded in.
438          */
439         val = HIMCI_READL((uintptr_t)host->base + MMC_CMD);
440         if ((val & START_CMD) == 0) {
441             break;
442         }
443         /* Check if Raw_Intr_Status HLE bit is set. */
444         HIMCI_IRQ_LOCK(&flags);
445         val = HIMCI_READL((uintptr_t)host->base + MMC_RINTSTS);
446         if ((val & HLE_INT_STATUS) > 0) {
447             val |= HLE_INT_STATUS;
448             HIMCI_WRITEL(val, (uintptr_t)host->base + MMC_RINTSTS);
449             HIMCI_IRQ_UNLOCK(flags);
450             HDF_LOGE("host%u: Other CMD is running! please operate cmd again!", host->id);
451             return HDF_MMC_ERR_OTHER_CMD_IS_RUNNING;
452         }
453         HIMCI_IRQ_UNLOCK(flags);
454         OsalUDelay(100);
455 
456         /* Check if number of retries for this are over. */
457         reties++;
458         if (reties >= HIMCI_MAX_RETRY_COUNT) {
459             if (host->cmd != NULL) {
460                 HDF_LOGE("wait cmd[%u] complete is timeout!", host->cmd->cmdCode);
461             } else {
462                 HDF_LOGE("timeout!");
463             }
464             return HDF_FAILURE;
465         }
466     }
467     return HDF_SUCCESS;
468 }
469 
HimciCmdDone(struct HimciHost * host)470 static void HimciCmdDone(struct HimciHost *host)
471 {
472     uint32_t i;
473     struct MmcCmd *cmd = host->cmd;
474 
475     if ((cmd->respType & RESP_PRESENT) == 0) {
476         return;
477     }
478 
479     if (MMC_RESP_TYPE(cmd) != MMC_RESP_R2) {
480         cmd->resp[0] = HIMCI_READL((uintptr_t)host->base + MMC_RESP0);
481         return;
482     }
483 
484     for (i = 0; i < MMC_CMD_RESP_SIZE; i++) {
485         cmd->resp[i] = HIMCI_READL((uintptr_t)host->base + MMC_RESP3 - i * 0x4);
486         /* R2 must delay some time here when use UHI card. */
487         OsalUDelay(1000);
488     }
489 }
490 
HimciDataSync(struct HimciHost * host,struct MmcData * data)491 static void HimciDataSync(struct HimciHost *host, struct MmcData *data)
492 {
493     uint32_t sgPhyAddr, sgLength, i;
494 
495     if ((data->dataFlags & DATA_READ) > 0) {
496         for (i = 0; i < host->dmaSgNum; i++) {
497             sgLength = HIMCI_SG_DMA_LEN(&host->sg[i]);
498             sgPhyAddr = HIMCI_SG_DMA_ADDRESS(&host->sg[i]);
499             HimciDmaCacheInv((void *)(uintptr_t)sgPhyAddr, sgLength);
500         }
501     }
502 }
503 
HimciDataDone(struct HimciHost * host,uint32_t state)504 static void HimciDataDone(struct HimciHost *host, uint32_t state)
505 {
506     struct MmcData *data = NULL;
507 
508     if (host->cmd == NULL) {
509         return;
510     }
511     if (host->cmd->data == NULL) {
512         return;
513     }
514 
515     data = host->cmd->data;
516     if ((state & (HTO_INT_STATUS | DRTO_INT_STATUS | RTO_INT_STATUS)) > 0) {
517         data->returnError = HDF_ERR_TIMEOUT;
518     } else if ((state & (EBE_INT_STATUS | SBE_INT_STATUS | FRUN_INT_STATUS | DCRC_INT_STATUS)) > 0) {
519         data->returnError = HDF_MMC_ERR_ILLEGAL_SEQ;
520     }
521 }
522 
HimciWaitCmdComplete(struct HimciHost * host)523 static void HimciWaitCmdComplete(struct HimciHost *host)
524 {
525     struct MmcCmd *cmd = host->cmd;
526     uint32_t timeout, status;
527     unsigned long flags = 0;
528 
529     if (host->isTuning == true) {
530         timeout = HIMCI_TUNINT_REQ_TIMEOUT;
531     } else {
532         timeout = HIMCI_REQUEST_TIMEOUT;
533     }
534 
535     HIMCI_IRQ_LOCK(&flags);
536     host->waitForEvent = true;
537     HIMCI_IRQ_UNLOCK(flags);
538 
539     status = HIMCI_EVENT_WAIT(&host->himciEvent, (HIMCI_PEND_DTO_M | HIMCI_PEND_ACCIDENT), timeout);
540     if (status == LOS_ERRNO_EVENT_READ_TIMEOUT || status == HIMCI_PEND_ACCIDENT) {
541         if (status == HIMCI_PEND_ACCIDENT) {
542             cmd->returnError = HDF_ERR_IO;
543         } else {
544             cmd->returnError = HDF_ERR_TIMEOUT;
545             if (host->isTuning == false) {
546                 HimciDumpRegs(host);
547                 HDF_LOGE("host%u cmd%u(arg 0x%x) timeout!", host->id, cmd->cmdCode, cmd->argument);
548             }
549         }
550         if (host->cmd->data != NULL) {
551             HimciDmaStop(host);
552             HimciDataDone(host, 0);
553         }
554     } else if (host->cmd->data != NULL) {
555         HimciDataSync(host, host->cmd->data);
556     }
557 
558     HIMCI_IRQ_LOCK(&flags);
559     host->waitForEvent = false;
560     HIMCI_IRQ_UNLOCK(flags);
561     HimciCmdDone(host);
562 }
563 
HimciCardPlugged(struct MmcCntlr * cntlr)564 static bool HimciCardPlugged(struct MmcCntlr *cntlr)
565 {
566     unsigned int status;
567     struct HimciHost *host = NULL;
568 
569     if ((cntlr == NULL) || (cntlr->priv == NULL)) {
570         return false;
571     }
572 
573     if (cntlr->devType == MMC_DEV_SDIO || cntlr->devType == MMC_DEV_EMMC) {
574         return true;
575     }
576 
577     host = (struct HimciHost *)cntlr->priv;
578     status = HIMCI_READL((uintptr_t)host->base + MMC_CDETECT);
579     if ((status & CARD_UNPLUGED) == 0) {
580         return true;
581     }
582     return false;
583 }
584 
HimciSendCmd23(struct HimciHost * host,uint32_t blockNum)585 static int32_t HimciSendCmd23(struct HimciHost *host, uint32_t blockNum)
586 {
587     int32_t ret;
588     struct MmcCmd cmd = {0};
589 
590     cmd.cmdCode = SET_BLOCK_COUNT;
591     cmd.argument = blockNum;
592     host->cmd = &cmd;
593     ret = HimciExecCmd(host);
594     if (ret != HDF_SUCCESS) {
595         host->cmd = NULL;
596         HDF_LOGE("cmd23 failed, ret = %d!", ret);
597         return ret;
598     }
599 
600     HimciWaitCmdComplete(host);
601     host->cmd = NULL;
602     return cmd.returnError;
603 }
604 
HimciFifoReset(struct HimciHost * host)605 static int32_t HimciFifoReset(struct HimciHost *host)
606 {
607     uint32_t i;
608 
609     HIMCI_SETL(host, MMC_CTRL, FIFO_RESET);
610     for (i = 0; i < HIMCI_MAX_RETRY_COUNT; i++) {
611         if ((HIMCI_READL((uintptr_t)host->base + MMC_CTRL) & FIFO_RESET) == 0) {
612             return HDF_SUCCESS;
613         }
614     }
615     return HDF_ERR_TIMEOUT;
616 }
617 
HimciFillDmaSg(struct HimciHost * host,struct MmcData * data)618 static int32_t HimciFillDmaSg(struct HimciHost *host, struct MmcData *data)
619 {
620     uint32_t len = data->blockNum * data->blockSize;
621     int32_t ret;
622 
623     if (len == 0) {
624         return HDF_ERR_INVALID_PARAM;
625     }
626 
627     if (data->scatter != NULL && data->dataBuffer == NULL) {
628         host->sg = data->scatter;
629         host->dmaSgNum = data->scatterLen;
630         return HDF_SUCCESS;
631     }
632     if (data->dataBuffer == NULL) {
633         return HDF_ERR_INVALID_PARAM;
634     }
635 
636     host->alignedBuff = (uint8_t *)OsalMemAllocAlign(CACHE_ALIGNED_SIZE, ALIGN(len, CACHE_ALIGNED_SIZE));
637     if (host->alignedBuff == NULL) {
638         HDF_LOGE("HimciFillDmaSg: alloc fail.");
639         return HDF_ERR_MALLOC_FAIL;
640     }
641 
642     ret = memcpy_s(host->alignedBuff, len, data->dataBuffer, len);
643     if (ret != EOK) {
644         HDF_LOGE("memcpy_s fail ret = %d.", ret);
645         OsalMemFree(host->alignedBuff);
646         host->alignedBuff = NULL;
647         return HDF_FAILURE;
648     }
649     host->buffLen = len;
650     sg_init_one(&host->dmaSg, (const void *)host->alignedBuff, len);
651     host->dmaSgNum = 1;
652     host->sg = &host->dmaSg;
653     return HDF_SUCCESS;
654 }
655 
HimciClearDmaSg(struct HimciHost * host,struct MmcData * data)656 static void HimciClearDmaSg(struct HimciHost *host, struct MmcData *data)
657 {
658     uint32_t len;
659 
660     if (data == NULL) {
661         return;
662     }
663 
664     len = data->blockNum * data->blockSize;
665     if (host->alignedBuff != NULL && data->dataBuffer != NULL && len > 0 && host->buffLen > 0) {
666         if ((data->dataFlags & DATA_READ) > 0) {
667             if (memcpy_s(data->dataBuffer, len, host->alignedBuff, host->buffLen) != EOK) {
668                 HDF_LOGE("%s: memcpy_s failed!", __func__);
669             }
670         }
671     }
672     if (host->alignedBuff != NULL) {
673         OsalMemFree(host->alignedBuff);
674         host->alignedBuff = NULL;
675     }
676     host->dmaSgNum = 0;
677     host->buffLen = 0;
678     host->sg = NULL;
679 }
680 
HimciSetupData(struct HimciHost * host,struct MmcData * data)681 static int32_t HimciSetupData(struct HimciHost *host, struct MmcData *data)
682 {
683     int32_t ret;
684     uint32_t sgPhyAddr, sgLength, i;
685     uint32_t desCnt = 0;
686     uint32_t maximum = HIMCI_PAGE_SIZE / sizeof(struct HimciDes);
687     struct HimciDes *des = NULL;
688     uint32_t dmaDir = DMA_TO_DEVICE;
689 
690     if ((data->dataFlags & DATA_READ) > 0) {
691         dmaDir = DMA_FROM_DEVICE;
692     }
693 
694     des = (struct HimciDes *)host->dmaVaddr;
695     for (i = 0; (i < host->dmaSgNum) && (desCnt < maximum); i++) {
696         sgLength = HIMCI_SG_DMA_LEN(&host->sg[i]);
697         sgPhyAddr = HIMCI_SG_DMA_ADDRESS(&host->sg[i]);
698         if ((sgPhyAddr & (CACHE_ALIGNED_SIZE - 1)) != 0) {
699             HDF_LOGE("host%u:sg_phyaddr:0x%x sg_length:0x%x.", host->id, sgPhyAddr, sgLength);
700             return HDF_FAILURE;
701         }
702         if (dmaDir == DMA_TO_DEVICE) {
703             HimciDmaCacheClean((void *)(uintptr_t)sgPhyAddr, sgLength);
704         } else {
705             HimciDmaCacheInv((void *)(uintptr_t)sgPhyAddr, sgLength);
706         }
707         while (sgLength && (desCnt < maximum)) {
708             des[desCnt].dmaDesCtrl = DMA_DES_OWN | DMA_DES_NEXT_DES;
709             des[desCnt].dmaDesBufAddr = sgPhyAddr;
710             /* idmac_des_next_addr is paddr for dma */
711             des[desCnt].dmaDesNextAddr = host->dmaPaddr + (desCnt + 1) * sizeof(struct HimciDes);
712             if (sgLength >= HIMCI_DMA_MAX_BUFF_SIZE) {
713                 des[desCnt].dmaDesBufSize = HIMCI_DMA_MAX_BUFF_SIZE;
714                 sgLength -= HIMCI_DMA_MAX_BUFF_SIZE;
715                 sgPhyAddr += HIMCI_DMA_MAX_BUFF_SIZE;
716             } else {
717                 /* data alignment */
718                 des[desCnt].dmaDesBufSize = sgLength;
719                 sgLength = 0;
720             }
721             desCnt++;
722         }
723     }
724     des[0].dmaDesCtrl |= DMA_DES_FIRST_DES;
725     des[desCnt - 1].dmaDesCtrl |= DMA_DES_LAST_DES;
726     des[desCnt - 1].dmaDesNextAddr = 0;
727 
728     HimciDmaCacheClean((void *)(uintptr_t)host->dmaPaddr, HIMCI_PAGE_SIZE);
729 
730     desCnt = data->blockSize * data->blockNum;
731     HIMCI_WRITEL(desCnt, (uintptr_t)host->base + MMC_BYTCNT);
732     HIMCI_WRITEL(data->blockSize, (uintptr_t)host->base + MMC_BLKSIZ);
733 
734     ret = HimciFifoReset(host);
735     if (ret != HDF_SUCCESS) {
736         return ret;
737     }
738     HimciDmaStart(host);
739     return HDF_SUCCESS;
740 }
741 
HimciWaitCardComplete(struct HimciHost * host)742 static bool HimciWaitCardComplete(struct HimciHost *host)
743 {
744     uint64_t timeout;
745     uint32_t cycle, busy;
746 
747     timeout = LOS_TickCountGet() + HIMCI_CARD_COMPLETE_TIMEOUT;
748     do {
749         for (cycle = 0; cycle < HIMCI_MAX_RETRY_COUNT; cycle++) {
750             busy = HIMCI_READL((uintptr_t)host->base + MMC_STATUS);
751             if ((busy & DATA_BUSY) == 0) {
752                 return true;
753             }
754         }
755         if (HimciCardPlugged(host->mmc) == false) {
756             HDF_LOGE("card is unplugged.");
757             return false;
758         }
759         LOS_Schedule();
760     } while (LOS_TickCountGet() < timeout);
761 
762     return false;
763 }
764 
HimciCmdDatePrepare(struct MmcCntlr * cntlr,struct MmcCmd * cmd,struct HimciHost * host)765 static int32_t HimciCmdDatePrepare(struct MmcCntlr *cntlr, struct MmcCmd *cmd, struct HimciHost *host)
766 {
767     int32_t ret;
768     host->cmd = cmd;
769     if (cmd->data != NULL) {
770         if (HimciIsMultiBlock(cmd) == true && HimciNeedAutoStop(cntlr) == false) {
771             ret = HimciSendCmd23(host, cmd->data->blockNum);
772             if (ret != HDF_SUCCESS) {
773                 cmd->returnError = ret;
774                 return ret;
775             }
776         }
777         host->cmd = cmd;
778         ret = HimciFillDmaSg(host, cmd->data);
779         if (ret != HDF_SUCCESS) {
780             return ret;
781         }
782         ret = HimciSetupData(host, cmd->data);
783         if (ret != HDF_SUCCESS) {
784             cmd->data->returnError = ret;
785             HDF_LOGE("setup data fail, err = %d.", ret);
786             return ret;
787         }
788     } else {
789         HIMCI_WRITEL(0, (uintptr_t)host->base + MMC_BYTCNT);
790         HIMCI_WRITEL(0, (uintptr_t)host->base + MMC_BLKSIZ);
791     }
792     return HDF_SUCCESS;
793 }
794 
HimciDoRequest(struct MmcCntlr * cntlr,struct MmcCmd * cmd)795 static int32_t HimciDoRequest(struct MmcCntlr *cntlr, struct MmcCmd *cmd)
796 {
797     struct HimciHost *host = NULL;
798     int32_t ret = HDF_SUCCESS;
799 
800     if ((cntlr == NULL) || (cntlr->priv == NULL) || (cmd == NULL)) {
801         return HDF_ERR_INVALID_OBJECT;
802     }
803 
804     host = (struct HimciHost *)cntlr->priv;
805     (void)OsalMutexLock(&host->mutex);
806     if (HimciCardPlugged(cntlr) == false) {
807         cmd->returnError = HDF_PLT_ERR_NO_DEV;
808         goto _END;
809     }
810 
811     if (HimciWaitCardComplete(host) == false) {
812         HDF_LOGE("card is busy, can not send cmd.");
813         cmd->returnError = HDF_ERR_TIMEOUT;
814         goto _END;
815     }
816 
817     if (HimciCmdDatePrepare(cntlr, cmd, host) !=  HDF_SUCCESS) {
818         goto _END;
819     }
820 
821     ret = HimciExecCmd(host);
822     if (ret != HDF_SUCCESS) {
823         cmd->returnError = ret;
824         HimciDmaStop(host);
825         HDF_LOGE("cmd%u exec fail, err = %d!", cmd->cmdCode, ret);
826         goto _END;
827     }
828     HimciWaitCmdComplete(host);
829 
830 _END:
831     HimciClearDmaSg(host, cmd->data);
832     host->cmd = NULL;
833     (void)OsalMutexUnlock(&host->mutex);
834     return ret;
835 }
836 
HimciControlClock(struct HimciHost * host,bool enableClk)837 static void HimciControlClock(struct HimciHost *host, bool enableClk)
838 {
839     uint32_t value;
840     union HimciCmdRegArg cmdArg;
841 
842     value = HIMCI_READL((uintptr_t)host->base + MMC_CLKENA);
843     if (enableClk == true) {
844         value |= CCLK_ENABLE;
845         /* Do not set/clear CCLK_LOW_POWER here,or the cmd18 will timeout. */
846     } else {
847         value &= (~CCLK_ENABLE);
848     }
849     if (host->mmc->devType == MMC_DEV_SDIO) {
850         value &= (~CCLK_LOW_POWER);
851     }
852     HIMCI_WRITEL(value, (uintptr_t)host->base + MMC_CLKENA);
853 
854     cmdArg.arg = HIMCI_READL((uintptr_t)host->base + MMC_CMD);
855     cmdArg.bits.startCmd = 1;
856     cmdArg.bits.cardNumber = 0;
857     cmdArg.bits.cmdIndex = 0;
858     cmdArg.bits.dataTransferExpected = 0;
859     cmdArg.bits.useHoldReg = 1;
860     cmdArg.bits.updateClkRegOnly = 1;
861     HIMCI_WRITEL(cmdArg.arg, (uintptr_t)host->base + MMC_CMD);
862 
863     if (HimciWaitCmd(host) != HDF_SUCCESS) {
864         HDF_LOGE("dis/enable clk is err!");
865     }
866 }
867 
HimciSetCClk(struct HimciHost * host,uint32_t clock)868 static void HimciSetCClk(struct HimciHost *host, uint32_t clock)
869 {
870     uint32_t clk = 0;
871     union HimciCmdRegArg cmdArg;
872     struct MmcCntlr *mmc = host->mmc;
873     struct MmcDevice *dev = mmc->curDev;
874 
875     (void)OsalMutexLock(&host->mutex);
876     if (host->id < MMC_CNTLR_NR_MAX) {
877         clk = HimciClkDiv(host, clock);
878     }
879     (void)OsalMutexUnlock(&host->mutex);
880     dev->workPara.clock = clk;
881 
882     cmdArg.arg = HIMCI_READL((uintptr_t)host->base + MMC_CMD);
883     cmdArg.bits.startCmd = 1;
884     cmdArg.bits.cardNumber = 0;
885     cmdArg.bits.updateClkRegOnly = 1;
886     cmdArg.bits.cmdIndex = 0;
887     cmdArg.bits.dataTransferExpected = 0;
888     HIMCI_WRITEL(cmdArg.arg, (uintptr_t)host->base + MMC_CMD);
889 
890     if (HimciWaitCmd(host) != HDF_SUCCESS) {
891         HDF_LOGE("host%u: set card clk divider is failed!", host->id);
892     }
893 }
894 
HimciSetClock(struct MmcCntlr * cntlr,uint32_t clock)895 static int32_t HimciSetClock(struct MmcCntlr *cntlr, uint32_t clock)
896 {
897     struct HimciHost *host = NULL;
898     uint32_t curClock = clock;
899 
900     if ((cntlr == NULL) || (cntlr->priv == NULL)) {
901         return HDF_ERR_INVALID_OBJECT;
902     }
903     /* can not greater than max of host. */
904     if (curClock > cntlr->freqMax) {
905         curClock = cntlr->freqMax;
906     }
907 
908     host = (struct HimciHost *)cntlr->priv;
909     HimciControlClock(host, false);
910     if (curClock > 0) {
911         HimciSetCClk(host, curClock);
912         HimciControlClock(host, true);
913     }
914     return HDF_SUCCESS;
915 }
916 
HimciControlPower(struct HimciHost * host,enum HimciPowerStatus status,bool forceEnable)917 static void HimciControlPower(struct HimciHost *host, enum HimciPowerStatus status, bool forceEnable)
918 {
919     uint32_t value;
920 
921     if (host->powerStatus != status || forceEnable == true) {
922         value = HIMCI_READL((uintptr_t)host->base + MMC_PWREN);
923         if (status == HOST_POWER_OFF) {
924             value &= (~POWER_ENABLE);
925         } else {
926             value |= POWER_ENABLE;
927         }
928         HIMCI_WRITEL(value, (uintptr_t)host->base + MMC_PWREN);
929         OsalMDelay(50);
930         host->powerStatus = status;
931     }
932 }
933 
HimciSetPowerMode(struct MmcCntlr * cntlr,enum MmcPowerMode mode)934 static int32_t HimciSetPowerMode(struct MmcCntlr *cntlr, enum MmcPowerMode mode)
935 {
936     struct HimciHost *host = NULL;
937     uint32_t value;
938     if ((cntlr == NULL) || (cntlr->priv == NULL)) {
939         return HDF_ERR_INVALID_OBJECT;
940     }
941 
942     host = (struct HimciHost *)cntlr->priv;
943     if (mode == MMC_POWER_MODE_POWER_OFF) {
944         value = HIMCI_READL((uintptr_t)host->base + MMC_UHS_REG);
945         value &= (~HI_SDXC_CTRL_VDD_180);
946         HIMCI_WRITEL(value, (uintptr_t)host->base + MMC_UHS_REG);
947         HimciControlPower(host, HOST_POWER_OFF, false);
948     } else {
949         HimciControlPower(host, HOST_POWER_ON, true);
950     }
951     return HDF_SUCCESS;
952 }
953 
HimciSetBusWidth(struct MmcCntlr * cntlr,enum MmcBusWidth width)954 static int32_t HimciSetBusWidth(struct MmcCntlr *cntlr, enum MmcBusWidth width)
955 {
956     struct HimciHost *host = NULL;
957     uint32_t value;
958 
959     if ((cntlr == NULL) || (cntlr->priv == NULL)) {
960         return HDF_ERR_INVALID_OBJECT;
961     }
962 
963     host = (struct HimciHost *)cntlr->priv;
964     value = HIMCI_READL((uintptr_t)host->base + MMC_CTYPE);
965     value &= (~(CARD_WIDTH_0 | CARD_WIDTH_1));
966 
967     if (width == BUS_WIDTH8) {
968         value |= CARD_WIDTH_0;
969         HIMCI_WRITEL(value, (uintptr_t)host->base + MMC_CTYPE);
970     } else if (width == BUS_WIDTH4) {
971         value |= CARD_WIDTH_1;
972         HIMCI_WRITEL(value, (uintptr_t)host->base + MMC_CTYPE);
973     } else {
974         HIMCI_WRITEL(value, (uintptr_t)host->base + MMC_CTYPE);
975     }
976     return HDF_SUCCESS;
977 }
978 
HimciCfgPhase(struct HimciHost * host,enum MmcBusTiming timing)979 static void HimciCfgPhase(struct HimciHost *host, enum MmcBusTiming timing)
980 {
981     uint32_t value;
982     uint32_t phase;
983     struct MmcDevice *dev = host->mmc->curDev;
984 
985     if (dev->type == MMC_DEV_EMMC) {
986         if (timing == BUS_TIMING_MMC_HS200) {
987             phase = DRV_PHASE_135 | SMP_PHASE_0;
988         } else if (timing == BUS_TIMING_MMC_HS) {
989             phase = DRV_PHASE_180 | SMP_PHASE_45;
990         } else {
991             phase = DRV_PHASE_180 | SMP_PHASE_0;
992         }
993     } else {
994         if (timing == BUS_TIMING_UHS_SDR104) {
995             phase = DRV_PHASE_135 | SMP_PHASE_0;
996         } else if (timing == BUS_TIMING_UHS_SDR50) {
997             phase = DRV_PHASE_90 | SMP_PHASE_0;
998         } else if (timing == BUS_TIMING_UHS_SDR25) {
999             phase = DRV_PHASE_180 | SMP_PHASE_45;
1000         } else if (timing == BUS_TIMING_SD_HS) {
1001             phase = DRV_PHASE_135 | SMP_PHASE_45;
1002         } else {
1003             phase = DRV_PHASE_180 | SMP_PHASE_0;
1004         }
1005     }
1006     value = HIMCI_READL((uintptr_t)host->base + MMC_UHS_REG_EXT);
1007     value &= ~CLK_SMPL_PHS_MASK;
1008     value &= ~CLK_DRV_PHS_MASK;
1009     value |= phase;
1010     HIMCI_WRITEL(value, (uintptr_t)host->base + MMC_UHS_REG_EXT);
1011 }
1012 
HimciSetBusTiming(struct MmcCntlr * cntlr,enum MmcBusTiming timing)1013 static int32_t HimciSetBusTiming(struct MmcCntlr *cntlr, enum MmcBusTiming timing)
1014 {
1015     struct HimciHost *host = NULL;
1016     uint32_t value;
1017 
1018     if ((cntlr == NULL) || (cntlr->priv == NULL)) {
1019         return HDF_ERR_INVALID_OBJECT;
1020     }
1021 
1022     host = (struct HimciHost *)cntlr->priv;
1023     value = HIMCI_READL((uintptr_t)host->base + MMC_UHS_REG);
1024     /* speed mode check ,if it is DDR50 set DDR mode */
1025     if (timing == BUS_TIMING_UHS_DDR50) {
1026         if ((value & HI_SDXC_CTRL_DDR_REG) == 0) {
1027             value |= HI_SDXC_CTRL_DDR_REG;
1028         }
1029     } else {
1030         if ((value & HI_SDXC_CTRL_DDR_REG) > 0) {
1031             value &= (~HI_SDXC_CTRL_DDR_REG);
1032         }
1033     }
1034     HIMCI_WRITEL(value, (uintptr_t)host->base + MMC_UHS_REG);
1035     HimciCfgPhase(host, timing);
1036     return HDF_SUCCESS;
1037 }
1038 
HimciSetSdioIrq(struct MmcCntlr * cntlr,bool enable)1039 static int32_t HimciSetSdioIrq(struct MmcCntlr *cntlr, bool enable)
1040 {
1041     struct HimciHost *host = NULL;
1042     uint32_t value;
1043     unsigned long flags = 0;
1044 
1045     if ((cntlr == NULL) || (cntlr->priv == NULL)) {
1046         return HDF_ERR_INVALID_OBJECT;
1047     }
1048 
1049     host = (struct HimciHost *)cntlr->priv;
1050     HIMCI_IRQ_LOCK(&flags);
1051     value = HIMCI_READL((uintptr_t)host->base + MMC_INTMASK);
1052     if (enable == true) {
1053         value |= SDIO_INT_MASK;
1054     } else {
1055         value &= (~SDIO_INT_MASK);
1056     }
1057     HIMCI_WRITEL(value, (uintptr_t)host->base + MMC_INTMASK);
1058     HIMCI_IRQ_UNLOCK(flags);
1059     return HDF_SUCCESS;
1060 }
1061 
HimciHardwareReset(struct MmcCntlr * cntlr)1062 static int32_t HimciHardwareReset(struct MmcCntlr *cntlr)
1063 {
1064     uint32_t val;
1065     struct HimciHost *host = NULL;
1066 
1067     if ((cntlr == NULL) || (cntlr->priv == NULL)) {
1068         return HDF_ERR_INVALID_OBJECT;
1069     }
1070 
1071     host = (struct HimciHost *)cntlr->priv;
1072     val = HIMCI_READL((uintptr_t)host->base + MMC_CARD_RSTN);
1073     val &= (~CARD_RESET);
1074     HIMCI_WRITEL(val, (uintptr_t)host->base + MMC_CARD_RSTN);
1075 
1076     /* For eMMC, minimum is 1us but give it 10us for good measure */
1077     OsalUDelay(10);
1078     val = HIMCI_READL((uintptr_t)host->base + MMC_CARD_RSTN);
1079     val |= CARD_RESET;
1080     HIMCI_WRITEL(val, (uintptr_t)host->base + MMC_CARD_RSTN);
1081     OsalUDelay(300);
1082     return HDF_SUCCESS;
1083 }
1084 
HimciSetEnhanceStrobe(struct MmcCntlr * cntlr,bool enable)1085 static int32_t HimciSetEnhanceStrobe(struct MmcCntlr *cntlr, bool enable)
1086 {
1087     (void)cntlr;
1088     (void)enable;
1089     return HDF_SUCCESS;
1090 }
1091 
HimciVoltageSwitchTo3v3(struct MmcCntlr * cntlr,struct HimciHost * host)1092 static int32_t HimciVoltageSwitchTo3v3(struct MmcCntlr *cntlr, struct HimciHost *host)
1093 {
1094     uint32_t ctrl;
1095 
1096     HIMCI_CLEARL(host, MMC_UHS_REG, HI_SDXC_CTRL_VDD_180);
1097     OsalMSleep(10);
1098     ctrl = HIMCI_READL((uintptr_t)host->base + MMC_UHS_REG);
1099     if ((ctrl & HI_SDXC_CTRL_VDD_180) > 0) {
1100         HDF_LOGE("host%u: Switching to 3.3V failed\n", host->id);
1101         return HDF_ERR_IO;
1102     }
1103     HimciSetDrvCap(cntlr);
1104     return HDF_SUCCESS;
1105 }
1106 
HimciVoltageSwitchTo1v8(struct MmcCntlr * cntlr,struct HimciHost * host)1107 static int32_t HimciVoltageSwitchTo1v8(struct MmcCntlr *cntlr, struct HimciHost *host)
1108 {
1109     uint32_t ctrl;
1110 
1111     ctrl = HIMCI_READL((uintptr_t)host->base + MMC_UHS_REG);
1112     if ((ctrl & HI_SDXC_CTRL_VDD_180) > 0) {
1113         return HDF_SUCCESS;
1114     }
1115 
1116     HimciControlClock(host, false);
1117     HIMCI_SETL(host, MMC_UHS_REG, HI_SDXC_CTRL_VDD_180);
1118     OsalMSleep(10);
1119     ctrl = HIMCI_READL((uintptr_t)host->base + MMC_UHS_REG);
1120     if ((ctrl & HI_SDXC_CTRL_VDD_180) > 0) {
1121         HimciControlClock(host, true);
1122         OsalMSleep(10);
1123         if (host->mmc->caps2.bits.hs200Sdr1v8 || host->mmc->caps2.bits.hs200Sdr1v2) {
1124             /* emmc needn't to check the int status. */
1125             return HDF_SUCCESS;
1126         }
1127         /* If CMD11 return CMD down, then the card was successfully switched to 1.8V signaling. */
1128         ctrl = HIMCI_EVENT_WAIT(&host->himciEvent, HIMCI_PEND_DTO_M, HIMCI_VOLT_SWITCH_TIMEOUT);
1129         if ((ctrl & HIMCI_PEND_DTO_M) > 0) {
1130             /* config Pin drive capability */
1131             HimciSetDrvCap(cntlr);
1132             return HDF_SUCCESS;
1133         }
1134     }
1135 
1136     ctrl &= (~HI_SDXC_CTRL_VDD_180);
1137     HIMCI_WRITEL(ctrl, (uintptr_t)host->base + MMC_UHS_REG);
1138     OsalMSleep(10);
1139     HimciControlPower(host, HOST_POWER_OFF, false);
1140     OsalMSleep(10);
1141     HimciControlPower(host, HOST_POWER_ON, false);
1142     HimciControlClock(host, false);
1143     OsalMSleep(1);
1144     HimciControlClock(host, true);
1145     ctrl = HIMCI_EVENT_WAIT(&host->himciEvent, HIMCI_PEND_DTO_M, 10);
1146     if ((ctrl & HIMCI_PEND_DTO_M) > 0) {
1147         /* config Pin drive capability */
1148         HimciSetDrvCap(cntlr);
1149         return HDF_SUCCESS;
1150     }
1151 
1152     HDF_LOGD("Switching to 1.8V failed, retrying with S18R set to 0.");
1153     return HDF_FAILURE;
1154 }
1155 
HimciSwitchVoltage(struct MmcCntlr * cntlr,enum MmcVolt volt)1156 static int32_t HimciSwitchVoltage(struct MmcCntlr *cntlr, enum MmcVolt volt)
1157 {
1158     struct HimciHost *host = NULL;
1159 
1160     if ((cntlr == NULL) || (cntlr->priv == NULL)) {
1161         return HDF_ERR_INVALID_OBJECT;
1162     }
1163 
1164     host = (struct HimciHost *)cntlr->priv;
1165     if (volt == VOLT_3V3) {
1166         return HimciVoltageSwitchTo3v3(cntlr, host);
1167     } else if (volt == VOLT_1V8) {
1168         return HimciVoltageSwitchTo1v8(cntlr, host);
1169     }
1170     return HDF_SUCCESS;
1171 }
1172 
HimciDevReadOnly(struct MmcCntlr * cntlr)1173 static bool HimciDevReadOnly(struct MmcCntlr *cntlr)
1174 {
1175     struct HimciHost *host = NULL;
1176     uint32_t val;
1177 
1178     if ((cntlr == NULL) || (cntlr->priv == NULL)) {
1179         return false;
1180     }
1181 
1182     host = (struct HimciHost *)cntlr->priv;
1183     val = HIMCI_READL((uintptr_t)host->base + MMC_WRTPRT);
1184     if ((val & CARD_READONLY) > 0) {
1185         return true;
1186     }
1187     return false;
1188 }
1189 
HimciDevBusy(struct MmcCntlr * cntlr)1190 static bool HimciDevBusy(struct MmcCntlr *cntlr)
1191 {
1192     (void)cntlr;
1193     return false;
1194 }
1195 
HimciEdgeTuningEnable(struct HimciHost * host)1196 static void HimciEdgeTuningEnable(struct HimciHost *host)
1197 {
1198     uint32_t val;
1199     uint32_t regs[] = { PERI_CRG83, PERI_CRG89, PERI_CRG86 };
1200 
1201     if (host->id >= MMC_CNTLR_NR_MAX) {
1202         HDF_LOGE("host%u id error", host->id);
1203         return;
1204     }
1205 
1206     HIMCI_WRITEL((HIMCI_SAP_DLL_SOFT_RESET | HIMCI_SAP_DLL_DEVICE_DELAY_ENABLE), regs[host->id]);
1207 
1208     val = HIMCI_READL((uintptr_t)host->base + MMC_TUNING_CTRL);
1209     val |= HW_TUNING_EN;
1210     HIMCI_WRITEL(val, (uintptr_t)host->base + MMC_TUNING_CTRL);
1211 }
1212 
HimciSetSapPhase(struct HimciHost * host,uint32_t phase)1213 static void HimciSetSapPhase(struct HimciHost *host, uint32_t phase)
1214 {
1215     uint32_t val;
1216 
1217     val = HIMCI_READL((uintptr_t)host->base + MMC_UHS_REG_EXT);
1218     val &= ~CLK_SMPL_PHS_MASK;
1219     val |= (phase << CLK_SMPL_PHS_OFFSET);
1220     HIMCI_WRITEL(val, (uintptr_t)host->base + MMC_UHS_REG_EXT);
1221 }
1222 
HimciEdgeTuningDisable(struct HimciHost * host)1223 static void HimciEdgeTuningDisable(struct HimciHost *host)
1224 {
1225     uint32_t val;
1226     uint32_t regs[] = { PERI_CRG83, PERI_CRG89, PERI_CRG86 };
1227 
1228     if (host->id >= MMC_CNTLR_NR_MAX) {
1229         HDF_LOGE("host%u id error", host->id);
1230         return;
1231     }
1232 
1233     val = HIMCI_READL(regs[host->id]);
1234     val |= HIMCI_SAP_DLL_MODE_DLLSSEL;
1235     HIMCI_WRITEL(val, regs[host->id]);
1236 
1237     val = HIMCI_READL((uintptr_t)host->base + MMC_TUNING_CTRL);
1238     val &= ~HW_TUNING_EN;
1239     HIMCI_WRITEL(val, (uintptr_t)host->base + MMC_TUNING_CTRL);
1240 }
1241 
HimciSendTuning(struct MmcCntlr * cntlr,uint32_t opcode)1242 static int32_t HimciSendTuning(struct MmcCntlr *cntlr, uint32_t opcode)
1243 {
1244     int32_t err;
1245     uint32_t result;
1246     struct HimciHost *host = (struct HimciHost *)cntlr->priv;
1247 
1248     (void)OsalMutexLock(&host->mutex);
1249     HimciControlClock(host, false);
1250     HimciDmaReset(host);
1251     HimciControlClock(host, true);
1252     (void)OsalMutexUnlock(&host->mutex);
1253 
1254     err = MmcSendTuning(cntlr, opcode, true);
1255     (void)MmcStopTransmission(cntlr, true, &result);
1256     (void)MmcSendStatus(cntlr, &result);
1257     return err;
1258 }
1259 
HimciSysReset(struct HimciHost * host)1260 static void HimciSysReset(struct HimciHost *host)
1261 {
1262     uint32_t value;
1263 
1264     value = HIMCI_READL((uintptr_t)host->base + MMC_BMOD);
1265     value |= BMOD_SWR;
1266     HIMCI_WRITEL(value, (uintptr_t)host->base + MMC_BMOD);
1267     OsalUDelay(10);
1268 
1269     value = HIMCI_READL((uintptr_t)host->base + MMC_BMOD);
1270     value |= (BURST_INCR | BURST_16);
1271     HIMCI_WRITEL(value, (uintptr_t)host->base + MMC_BMOD);
1272 
1273     value = HIMCI_READL((uintptr_t)host->base + MMC_CTRL);
1274     value |=  (CTRL_RESET | FIFO_RESET | DMA_RESET);
1275     HIMCI_WRITEL(value, (uintptr_t)host->base + MMC_CTRL);
1276 }
1277 
HimciTuningFeedback(struct MmcCntlr * cntlr)1278 static void HimciTuningFeedback(struct MmcCntlr *cntlr)
1279 {
1280     struct HimciHost *host = (struct HimciHost *)cntlr->priv;
1281 
1282     (void)OsalMutexLock(&host->mutex);
1283     HimciControlClock(host, false);
1284     OsalMDelay(1);
1285     HimciSysReset(host);
1286     OsalMDelay(1);
1287     HIMCI_WRITEL(ALL_INT_CLR, (uintptr_t)host->base + MMC_RINTSTS);
1288     HimciControlClock(host, true);
1289     OsalMDelay(1);
1290     (void)OsalMutexUnlock(&host->mutex);
1291 }
1292 
HimciGetSapDllTaps(struct HimciHost * host)1293 static uint32_t HimciGetSapDllTaps(struct HimciHost *host)
1294 {
1295     uint32_t val;
1296     uint32_t regs[] = { PERI_CRG84, PERI_CRG90, PERI_CRG87 };
1297 
1298     if (host->id >= MMC_CNTLR_NR_MAX) {
1299         HDF_LOGE("host%u id error", host->id);
1300         return 0;
1301     }
1302 
1303     val = HIMCI_READL(regs[host->id]);
1304     return (val & 0xff);
1305 }
1306 
HimciSetDllElement(struct HimciHost * host,uint32_t element)1307 static void HimciSetDllElement(struct HimciHost *host, uint32_t element)
1308 {
1309     uint32_t val;
1310     uint32_t regs[] = { PERI_CRG83, PERI_CRG89, PERI_CRG86 };
1311 
1312     if (host->id >= MMC_CNTLR_NR_MAX) {
1313         HDF_LOGE("host%u id error", host->id);
1314         return;
1315     }
1316 
1317     val = HIMCI_READL(regs[host->id]);
1318     val &= ~(0xFF << HIMCI_SAP_DLL_ELEMENT_SHIFT);
1319     val |= (element << HIMCI_SAP_DLL_ELEMENT_SHIFT);
1320     HIMCI_WRITEL(val, regs[host->id]);
1321 }
1322 
HimciEdgedllModeATuning(struct HimciHost * host,struct HimciTuneParam * param,uint32_t phaseDllElements)1323 static void HimciEdgedllModeATuning(struct HimciHost *host, struct HimciTuneParam *param,
1324     uint32_t phaseDllElements)
1325 {
1326     uint32_t index, ele, phaseOffset;
1327     int32_t prevErr = HDF_SUCCESS;
1328     int32_t err;
1329 
1330     if (host == NULL || param == NULL) {
1331         return;
1332     }
1333 
1334     phaseOffset = param->edgeP2f * phaseDllElements;
1335     for (index = param->edgeP2f; index < param->edgeF2p; index++) {
1336         HimciSetSapPhase(host, index);
1337         for (ele = HIMCI_PHASE_DLL_START_ELEMENT; ele <= phaseDllElements; ele++) {
1338             HimciSetDllElement(host, ele);
1339             err = HimciSendTuning(host->mmc, param->cmdCode);
1340             if (prevErr == HDF_SUCCESS && err != HDF_SUCCESS && (param->endp == param->endpInit)) {
1341                 param->endp = phaseOffset + ele;
1342             }
1343 
1344             if (err != HDF_SUCCESS) {
1345                 param->startp = phaseOffset + ele;
1346             }
1347             prevErr = err;
1348             err = HDF_SUCCESS;
1349         }
1350         phaseOffset += phaseDllElements;
1351     }
1352 }
1353 
HimciEdgedllModeBTuning(struct HimciHost * host,struct HimciTuneParam * param,uint32_t phaseDllElements)1354 static void HimciEdgedllModeBTuning(struct HimciHost *host, struct HimciTuneParam *param,
1355     uint32_t phaseDllElements)
1356 {
1357     uint32_t index, ele, phaseOffset;
1358     int32_t prevErr = HDF_SUCCESS;
1359     int32_t err;
1360 
1361     if (host == NULL || param == NULL) {
1362         return;
1363     }
1364 
1365     phaseOffset = param->edgeP2f * phaseDllElements;
1366     for (index = param->edgeP2f; index < HIMCI_PHASE_SCALE; index++) {
1367         HimciSetSapPhase(host, index);
1368         for (ele = HIMCI_PHASE_DLL_START_ELEMENT; ele <= phaseDllElements; ele++) {
1369             HimciSetDllElement(host, ele);
1370             err = HimciSendTuning(host->mmc, param->cmdCode);
1371             if (prevErr == HDF_SUCCESS && err != HDF_SUCCESS && (param->endp == param->endpInit)) {
1372                 param->endp = phaseOffset + ele;
1373             }
1374             if (err != HDF_SUCCESS) {
1375                 param->startp = phaseOffset + ele;
1376             }
1377             prevErr = err;
1378             err = HDF_SUCCESS;
1379         }
1380         phaseOffset += phaseDllElements;
1381     }
1382 
1383     phaseOffset = 0;
1384     for (index = 0; index < param->edgeF2p; index++) {
1385         HimciSetSapPhase(host, index);
1386         for (ele = HIMCI_PHASE_DLL_START_ELEMENT; ele <= phaseDllElements; ele++) {
1387             HimciSetDllElement(host, ele);
1388             err = HimciSendTuning(host->mmc, param->cmdCode);
1389             if (prevErr == HDF_SUCCESS && err != HDF_SUCCESS && (param->endp == param->endpInit)) {
1390                 param->endp = phaseOffset + ele;
1391             }
1392             if (err != HDF_SUCCESS) {
1393                 param->startp = phaseOffset + ele;
1394             }
1395             prevErr = err;
1396             err = HDF_SUCCESS;
1397         }
1398         phaseOffset += phaseDllElements;
1399     }
1400 }
1401 
HimciEdgedllModeTuning(struct HimciHost * host,uint32_t cmdCode,uint32_t edgeP2f,uint32_t edgeF2p)1402 static int32_t HimciEdgedllModeTuning(struct HimciHost *host,
1403     uint32_t cmdCode, uint32_t edgeP2f, uint32_t edgeF2p)
1404 {
1405     uint32_t index, ele, phaseOffset, totalPhases, phaseDllElements;
1406     struct HimciTuneParam param = {0};
1407 
1408     phaseDllElements = HimciGetSapDllTaps(host) / HIMCI_PHASE_SCALE;
1409     totalPhases = phaseDllElements * HIMCI_PHASE_SCALE;
1410     /*
1411      *  EdgeMode A:
1412      * |<---- totalphases(ele) ---->|
1413      *       _____________
1414      * ______|||||||||||||||_______
1415      * edge_p2f       edge_f2p
1416      * (endp)         (startp)
1417      *
1418      * EdgeMode B:
1419      * |<---- totalphases(ele) ---->|
1420      * ________           _________
1421      * ||||||||||_________|||||||||||
1422      * edge_f2p     edge_p2f
1423      * (startp)     (endp)
1424      *
1425      * BestPhase:
1426      * if(endp < startp)
1427      * endp = endp + totalphases;
1428      * Best = ((startp + endp) / 2) % totalphases
1429      */
1430     param.cmdCode = cmdCode;
1431     param.edgeF2p = edgeF2p;
1432     param.edgeP2f = edgeP2f;
1433     param.endpInit = edgeP2f * phaseDllElements;
1434     param.startp = edgeF2p * phaseDllElements;
1435     param.endp = param.endpInit;
1436     if (edgeF2p >= edgeP2f) {
1437         HimciEdgedllModeATuning(host, &param, phaseDllElements);
1438     } else {
1439         HimciEdgedllModeBTuning(host, &param, phaseDllElements);
1440     }
1441 
1442     if (param.endp <= param.startp) {
1443         param.endp += totalPhases;
1444     }
1445     if (totalPhases == 0) {
1446         HDF_LOGE("host%u:total phases is zero.", host->id);
1447         return HDF_FAILURE;
1448     }
1449     phaseOffset = ((param.startp + param.endp) / 2) % totalPhases;
1450     index = (phaseOffset / phaseDllElements);
1451     ele = (phaseOffset % phaseDllElements);
1452     ele = ((ele > HIMCI_PHASE_DLL_START_ELEMENT) ? ele : HIMCI_PHASE_DLL_START_ELEMENT);
1453     HimciSetSapPhase(host, index);
1454     HimciSetDllElement(host, ele);
1455     HIMCI_WRITEL(ALL_INT_CLR, (uintptr_t)host->base + MMC_RINTSTS);
1456     return HDF_SUCCESS;
1457 }
1458 
HimciTune(struct MmcCntlr * cntlr,uint32_t cmdCode)1459 static int32_t HimciTune(struct MmcCntlr *cntlr, uint32_t cmdCode)
1460 {
1461     struct HimciHost *host = NULL;
1462     uint32_t index, val;
1463     bool found = false;
1464     bool prevFound = false;
1465     uint32_t edgeP2f = 0;
1466     uint32_t phaseNum = HIMCI_PHASE_SCALE;
1467     uint32_t edgeF2p = HIMCI_PHASE_SCALE;
1468     int32_t err;
1469 
1470     if ((cntlr == NULL) || (cntlr->priv == NULL)) {
1471         return HDF_ERR_INVALID_OBJECT;
1472     }
1473 
1474     host = (struct HimciHost *)cntlr->priv;
1475     host->isTuning = true;
1476     HimciEdgeTuningEnable(host);
1477     for (index = 0; index < HIMCI_PHASE_SCALE; index++) {
1478         found = true;
1479         HimciSetSapPhase(host, index);
1480         err = HimciSendTuning(cntlr, cmdCode);
1481         if (err == HDF_SUCCESS) {
1482             val = HIMCI_READL((uintptr_t)host->base + MMC_TUNING_CTRL);
1483             found = ((val & FOUND_EDGE) == FOUND_EDGE);
1484         }
1485 
1486         if (prevFound == true && found == false) {
1487             edgeF2p = index;
1488         } else if (prevFound == false && found == true) {
1489             edgeP2f = index;
1490         }
1491 
1492         if ((edgeP2f != 0) && (edgeF2p != phaseNum)) {
1493             break;
1494         }
1495         prevFound = found;
1496     }
1497 
1498     if ((edgeP2f == 0) && (edgeF2p == phaseNum)) {
1499         host->isTuning = false;
1500         return HDF_FAILURE;
1501     }
1502 
1503     index = (edgeF2p + phaseNum + edgeP2f) / 2 % phaseNum;
1504     if (edgeF2p < edgeP2f) {
1505         index = (edgeF2p + edgeP2f) / 2 % phaseNum;
1506     }
1507     HimciSetSapPhase(host, index);
1508     err = HimciSendTuning(cntlr, cmdCode);
1509     HimciEdgeTuningDisable(host);
1510 
1511     err = HimciEdgedllModeTuning(host, cmdCode, edgeP2f, edgeF2p);
1512     HimciTuningFeedback(cntlr);
1513     if (err == HDF_SUCCESS) {
1514         (void)HimciSendTuning(cntlr, cmdCode);
1515     }
1516 
1517     host->isTuning = false;
1518     return HDF_SUCCESS;
1519 }
1520 
HimciClockCfg(uint32_t devId)1521 static void HimciClockCfg(uint32_t devId)
1522 {
1523     uint32_t val;
1524     uint32_t regs[] = { PERI_CRG82, PERI_CRG88, PERI_CRG85 };
1525 
1526     if (devId < MMC_CNTLR_NR_MAX) {
1527         val = HIMCI_READL((uintptr_t)regs[devId]);
1528         val |= HIMCI_CLK_SEL_100M;
1529         val |= HIMCI_CKEN;
1530         HIMCI_WRITEL(val, (uintptr_t)regs[devId]);
1531     }
1532 }
1533 
HimciSoftReset(uint32_t devId)1534 static void HimciSoftReset(uint32_t devId)
1535 {
1536     uint32_t regs[] = { PERI_CRG82, PERI_CRG88, PERI_CRG85 };
1537     uint32_t val;
1538 
1539     if (devId < MMC_CNTLR_NR_MAX) {
1540         val = HIMCI_READL((uintptr_t)regs[devId]);
1541         OsalUDelay(1000);
1542         val |= HIMCI_RESET;
1543         HIMCI_WRITEL(val, (uintptr_t)regs[devId]);
1544         val &= ~HIMCI_RESET;
1545         HIMCI_WRITEL(val, (uintptr_t)regs[devId]);
1546     }
1547 }
1548 
HimciSysCtrlInit(struct HimciHost * host)1549 static void HimciSysCtrlInit(struct HimciHost *host)
1550 {
1551     HIMCI_TASK_LOCK();
1552     HimciClockCfg(host->id);
1553     HimciSoftReset(host->id);
1554     HIMCI_TASK_UNLOCK();
1555 }
1556 
HimciHostRegistersInit(struct HimciHost * host)1557 static void HimciHostRegistersInit(struct HimciHost *host)
1558 {
1559     uint32_t value;
1560 
1561     HimciSysReset(host);
1562     HimciControlPower(host, HOST_POWER_OFF, true);
1563     /* host power on */
1564     HimciControlPower(host, HOST_POWER_ON, true);
1565 
1566     /*
1567      * Walkaround: controller config gpio
1568      * the value of this register should be 0x80a400,
1569      * but the reset value is 0xa400.
1570      */
1571     value = HIMCI_READL((uintptr_t)host->base + MMC_GPIO);
1572     value |= DTO_FIX_ENABLE;
1573     HIMCI_WRITEL(value, (uintptr_t)host->base + MMC_GPIO);
1574 
1575     value = ((DRV_PHASE_SHIFT << CLK_DRV_PHS_OFFSET)
1576            | (SMPL_PHASE_SHIFT << CLK_SMPL_PHS_OFFSET));
1577     HIMCI_WRITEL(value, (uintptr_t)host->base + MMC_UHS_REG_EXT);
1578 
1579     HIMCI_WRITEL((READ_THRESHOLD_SIZE | BUSY_CLEAR_INT_ENABLE), (uintptr_t)host->base + MMC_CARDTHRCTL);
1580 
1581     /* clear MMC host intr */
1582     HIMCI_WRITEL(ALL_INT_CLR, (uintptr_t)host->base + MMC_RINTSTS);
1583 
1584     /*
1585      * data transfer over(DTO) interrupt comes after ACD
1586      * we'd use DTO with or without auto_cmd is enabled.
1587      */
1588     value = ALL_INT_MASK & (~(ACD_INT_STATUS | RXDR_INT_STATUS | TXDR_INT_STATUS | SDIO_INT_MASK));
1589     HIMCI_WRITEL(value, (uintptr_t)host->base + MMC_INTMASK);
1590     HIMCI_WRITEL(DEBNCE_MS, (uintptr_t)host->base + MMC_DEBNCE);
1591 
1592     /* enable inner DMA mode and close intr of MMC host controler */
1593     value = HIMCI_READL((uintptr_t)host->base + MMC_CTRL);
1594     value |= USE_INTERNAL_DMA | INTR_EN;
1595     HIMCI_WRITEL(value, (uintptr_t)host->base + MMC_CTRL);
1596 
1597     /* set timeout param */
1598     HIMCI_WRITEL(DATA_TIMEOUT | RESPONSE_TIMEOUT, (uintptr_t)host->base + MMC_TMOUT);
1599 
1600     /* set FIFO param */
1601     value = BURST_SIZE | RX_WMARK | TX_WMARK;
1602     HIMCI_WRITEL(value, (uintptr_t)host->base + MMC_FIFOTH);
1603 }
1604 
HimciRescanSdioDev(struct MmcCntlr * cntlr)1605 static int32_t HimciRescanSdioDev(struct MmcCntlr *cntlr)
1606 {
1607     struct HimciHost *host = NULL;
1608 
1609     if ((cntlr == NULL) || (cntlr->priv == NULL)) {
1610         return HDF_ERR_INVALID_OBJECT;
1611     }
1612 
1613     host = (struct HimciHost *)cntlr->priv;
1614     if (host->waitForEvent == true) {
1615         (void)HIMCI_EVENT_SIGNAL(&host->himciEvent, HIMCI_PEND_ACCIDENT);
1616     }
1617 
1618     return MmcCntlrAddSdioRescanMsgToQueue(cntlr);
1619 }
1620 
HimciSystemInit(struct MmcCntlr * cntlr)1621 static int32_t HimciSystemInit(struct MmcCntlr *cntlr)
1622 {
1623     struct HimciHost *host = NULL;
1624 
1625     if ((cntlr == NULL) || (cntlr->priv == NULL)) {
1626         return HDF_ERR_INVALID_OBJECT;
1627     }
1628 
1629     host = (struct HimciHost *)cntlr->priv;
1630     HimciSysCtrlInit(host);
1631     HimciHostRegistersInit(host);
1632     return HDF_SUCCESS;
1633 }
1634 
1635 static struct MmcCntlrOps g_himciHostOps = {
1636     .request = HimciDoRequest,
1637     .setClock = HimciSetClock,
1638     .setPowerMode = HimciSetPowerMode,
1639     .setBusWidth = HimciSetBusWidth,
1640     .setBusTiming = HimciSetBusTiming,
1641     .setSdioIrq = HimciSetSdioIrq,
1642     .hardwareReset = HimciHardwareReset,
1643     .systemInit = HimciSystemInit,
1644     .setEnhanceStrobe = HimciSetEnhanceStrobe,
1645     .switchVoltage = HimciSwitchVoltage,
1646     .devReadOnly = HimciDevReadOnly,
1647     .devPlugged = HimciCardPlugged,
1648     .devBusy = HimciDevBusy,
1649     .tune = HimciTune,
1650     .rescanSdioDev = HimciRescanSdioDev,
1651 };
1652 
HimciCmdIrq(struct HimciHost * host,uint32_t state)1653 static uint32_t HimciCmdIrq(struct HimciHost *host, uint32_t state)
1654 {
1655     struct MmcCmd *cmd = host->cmd;
1656     struct MmcData *data = NULL;
1657     uint32_t writeEvent = 0;
1658     uint32_t mask;
1659     int32_t error = HDF_SUCCESS;
1660 
1661     if ((state & RTO_INT_STATUS) > 0) {
1662         error = HDF_ERR_TIMEOUT;
1663     } else if ((state & (RCRC_INT_STATUS | RE_INT_STATUS)) > 0) {
1664         error = HDF_MMC_ERR_ILLEGAL_SEQ;
1665     }
1666 
1667     mask = (CD_INT_STATUS | VOLT_SWITCH_INT_STATUS);
1668     if (cmd != NULL) {
1669         data = cmd->data;
1670     }
1671     if (data == NULL && (state & mask) > 0) {
1672         writeEvent = 1;
1673     }
1674 
1675     /*
1676      * If there is a response timeout(RTO) error,
1677      * then the DWC_mobile_storage does not attempt any data transfer and
1678      * the "data Transfer Over" bit is never set.
1679      */
1680     mask = (CD_INT_STATUS | RTO_INT_STATUS);
1681     if ((state & mask) == mask) {
1682         writeEvent = 1;
1683     }
1684     if (cmd != NULL) {
1685         cmd->returnError = error;
1686     }
1687     return writeEvent;
1688 }
1689 
HimciDataIrq(struct HimciHost * host,struct MmcData * data,uint32_t state)1690 static uint32_t HimciDataIrq(struct HimciHost *host, struct MmcData *data, uint32_t state)
1691 {
1692     uint32_t writeEvent = 0;
1693 
1694     if (host == NULL || data == NULL) {
1695         return writeEvent;
1696     }
1697 
1698     if ((data->dataFlags & DATA_READ) == 0) {
1699         if ((state & SBE_INT_STATUS) > 0) {
1700             HimciDmaStop(host);
1701             HimciDataDone(host, state & (~SBE_INT_STATUS));
1702             writeEvent++;
1703         }
1704     } else {
1705         HimciDmaStop(host);
1706         HimciDataDone(host, state);
1707         writeEvent++;
1708     }
1709     return writeEvent;
1710 }
1711 
HimciIrqHandler(uint32_t irq,void * data)1712 static uint32_t HimciIrqHandler(uint32_t irq, void *data)
1713 {
1714     struct HimciHost *host = (struct HimciHost *)data;
1715     struct MmcCmd *cmd = NULL;
1716     uint32_t writeEvent = 0;
1717     uint32_t state;
1718     (void)irq;
1719 
1720     if (host == NULL) {
1721         HDF_LOGE("HimciIrqHandler: data is null!");
1722         return HDF_SUCCESS;
1723     }
1724     state = HIMCI_READL((uintptr_t)host->base + MMC_RINTSTS);
1725     HIMCI_WRITEL(state, (uintptr_t)host->base + MMC_RINTSTS);
1726     if ((state & SDIO_INT_STATUS) > 0) {
1727         HIMCI_CLEARL(host, MMC_INTMASK, SDIO_INT_MASK);
1728         (void)MmcCntlrNotifySdioIrqThread(host->mmc);
1729     }
1730 
1731     if ((state & CARD_DETECT_INT_STATUS) > 0) {
1732         (void)MmcCntlrAddPlugMsgToQueue(host->mmc);
1733         if (host->waitForEvent == true) {
1734             (void)HIMCI_EVENT_SIGNAL(&host->himciEvent, HIMCI_PEND_ACCIDENT);
1735             return HDF_SUCCESS;
1736         }
1737     }
1738 
1739     cmd = host->cmd;
1740     if (cmd == NULL) {
1741         return HDF_SUCCESS;
1742     }
1743 
1744     if ((state & CMD_INT_MASK) > 0) {
1745         writeEvent += HimciCmdIrq(host, state);
1746     }
1747 
1748     if ((state & DATA_INT_MASK) > 0) {
1749         /*
1750          * SBE_INT_STATUS:
1751          * Busy Clear Interrupt when data is written to the card
1752          * In this case, we'd wait for it.
1753          * Error in data start bit when data is read from a card
1754          * In this case, we don't need to wait for it. if it's triggered, something is wrong
1755          */
1756         if (cmd->data != NULL) {
1757             writeEvent += HimciDataIrq(host, cmd->data, state);
1758         } else {
1759             writeEvent += HimciCmdIrq(host, state);
1760         }
1761     }
1762     if (writeEvent != 0) {
1763         (void)HIMCI_EVENT_SIGNAL(&host->himciEvent, HIMCI_PEND_DTO_M);
1764     }
1765     return HDF_SUCCESS;
1766 }
1767 
HimciHostInit(struct HimciHost * host,struct MmcCntlr * cntlr)1768 static int32_t HimciHostInit(struct HimciHost *host, struct MmcCntlr *cntlr)
1769 {
1770     int32_t ret;
1771 
1772     host->id = (uint32_t)cntlr->index;
1773     host->dmaVaddr = (uint32_t *)LOS_DmaMemAlloc(&host->dmaPaddr, HIMCI_PAGE_SIZE, CACHE_ALIGNED_SIZE, DMA_CACHE);
1774     if (host->dmaVaddr == NULL) {
1775         HDF_LOGE("HimciHostInit: no mem for himci dma!");
1776         return HDF_ERR_MALLOC_FAIL;
1777     }
1778 
1779     if (HIMCI_EVENT_INIT(&host->himciEvent) != HDF_SUCCESS) {
1780         HDF_LOGE("HimciHostInit: himciEvent init fail!");
1781         return HDF_FAILURE;
1782     }
1783     if (OsalMutexInit(&host->mutex) != HDF_SUCCESS) {
1784         HDF_LOGE("HimciHostInit: init mutex lock fail!");
1785         return HDF_FAILURE;
1786     }
1787 
1788     HimciSysCtrlInit(host);
1789     HimciHostRegistersInit(host);
1790 
1791     ret = OsalRegisterIrq(host->irqNum, 0, HimciIrqHandler, "MMC_IRQ", host);
1792     if (ret != HDF_SUCCESS) {
1793         HDF_LOGE("HimciHostInit: request irq for himci is err.");
1794         return HDF_FAILURE;
1795     }
1796     return HDF_SUCCESS;
1797 }
1798 
HimciHostParse(struct HimciHost * host,struct HdfDeviceObject * obj)1799 static int32_t HimciHostParse(struct HimciHost *host, struct HdfDeviceObject *obj)
1800 {
1801     const struct DeviceResourceNode *node = NULL;
1802     struct DeviceResourceIface *drsOps = NULL;
1803     int32_t ret;
1804     uint32_t regBase, regSize;
1805 
1806     if (obj == NULL || host == NULL) {
1807         HDF_LOGE("%s: input param is NULL.", __func__);
1808         return HDF_FAILURE;
1809     }
1810 
1811     node = obj->property;
1812     if (node == NULL) {
1813         HDF_LOGE("%s: drs node is NULL.", __func__);
1814         return HDF_FAILURE;
1815     }
1816     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
1817     if (drsOps == NULL || drsOps->GetUint32 == NULL) {
1818         HDF_LOGE("%s: invalid drs ops fail!", __func__);
1819         return HDF_FAILURE;
1820     }
1821 
1822     ret = drsOps->GetUint32(node, "regBasePhy", &regBase, 0);
1823     if (ret != HDF_SUCCESS) {
1824         HDF_LOGE("%s: read regBasePhy fail!", __func__);
1825         return ret;
1826     }
1827 
1828     ret = drsOps->GetUint32(node, "regSize", &regSize, 0);
1829     if (ret != HDF_SUCCESS) {
1830         HDF_LOGE("%s: read regSize fail!", __func__);
1831         return ret;
1832     }
1833 
1834     host->base = OsalIoRemap(regBase, regSize);
1835     if (host->base == NULL) {
1836         HDF_LOGE("%s: ioremap regBase fail!", __func__);
1837         return HDF_ERR_IO;
1838     }
1839 
1840     ret = drsOps->GetUint32(node, "irqNum", &(host->irqNum), 0);
1841     if (ret != HDF_SUCCESS) {
1842         HDF_LOGE("%s: read irqNum fail!", __func__);
1843     }
1844     return ret;
1845 }
1846 
HimciDeleteHost(struct HimciHost * host)1847 static void HimciDeleteHost(struct HimciHost *host)
1848 {
1849     struct MmcCntlr *cntlr = NULL;
1850 
1851     if (host == NULL) {
1852         return;
1853     }
1854 
1855     cntlr = host->mmc;
1856     if (cntlr != NULL) {
1857         if (cntlr->curDev != NULL) {
1858             MmcDeviceRemove(cntlr->curDev);
1859             OsalMemFree(cntlr->curDev);
1860             cntlr->curDev = NULL;
1861         }
1862         MmcCntlrRemove(cntlr);
1863         cntlr->hdfDevObj = NULL;
1864         cntlr->priv = NULL;
1865         cntlr->ops = NULL;
1866         OsalMemFree(cntlr);
1867         host->mmc = NULL;
1868     }
1869 
1870     OsalUnregisterIrq(host->irqNum, host);
1871     if (host->dmaVaddr != NULL) {
1872         LOS_DmaMemFree(host->dmaVaddr);
1873     }
1874     if (host->base != NULL) {
1875         OsalIoUnmap(host->base);
1876     }
1877 
1878     (void)HIMCI_EVENT_DELETE(&host->himciEvent);
1879     (void)OsalMutexDestroy(&host->mutex);
1880     OsalMemFree(host);
1881 }
1882 
HimciMmcBind(struct HdfDeviceObject * obj)1883 static int32_t HimciMmcBind(struct HdfDeviceObject *obj)
1884 {
1885     struct MmcCntlr *cntlr = NULL;
1886     struct HimciHost *host = NULL;
1887     int32_t ret;
1888 
1889     if (obj == NULL) {
1890         HDF_LOGE("HimciMmcBind: Fail, device is NULL.");
1891         return HDF_ERR_INVALID_OBJECT;
1892     }
1893     cntlr = (struct MmcCntlr *)OsalMemCalloc(sizeof(struct MmcCntlr));
1894     if (cntlr == NULL) {
1895         HDF_LOGE("HimciMmcBind: no mem for MmcCntlr.");
1896         return HDF_ERR_MALLOC_FAIL;
1897     }
1898     host = (struct HimciHost *)OsalMemCalloc(sizeof(struct HimciHost));
1899     if (host == NULL) {
1900         HDF_LOGE("HimciMmcBind: no mem for HimciHost.");
1901         OsalMemFree(cntlr);
1902         return HDF_ERR_MALLOC_FAIL;
1903     }
1904 
1905     host->mmc = cntlr;
1906     cntlr->priv = (void *)host;
1907     cntlr->ops = &g_himciHostOps;
1908     cntlr->hdfDevObj = obj;
1909     obj->service = &cntlr->service;
1910     /* init cntlr. */
1911     ret = MmcCntlrParse(cntlr, obj);
1912     if (ret != HDF_SUCCESS) {
1913         goto _ERR;
1914     }
1915     /* init host. */
1916     ret = HimciHostParse(host, obj);
1917     if (ret != HDF_SUCCESS) {
1918         goto _ERR;
1919     }
1920     ret = HimciHostInit(host, cntlr);
1921     if (ret != HDF_SUCCESS) {
1922         goto _ERR;
1923     }
1924     ret = MmcCntlrAdd(cntlr, true);
1925     if (ret != HDF_SUCCESS) {
1926         goto _ERR;
1927     }
1928 
1929     /* add card detect msg to queue. */
1930     (void)MmcCntlrAddDetectMsgToQueue(cntlr);
1931     HDF_LOGI("%s: mmc bind success.", __func__);
1932     return HDF_SUCCESS;
1933 _ERR:
1934     HimciDeleteHost(host);
1935     HDF_LOGE("HimciMmcBind: fail, err = %d.", ret);
1936     return ret;
1937 }
1938 
HimciMmcInit(struct HdfDeviceObject * obj)1939 static int32_t HimciMmcInit(struct HdfDeviceObject *obj)
1940 {
1941     static bool procInit = false;
1942 
1943     (void)obj;
1944     if (procInit == false) {
1945         if (ProcMciInit() == HDF_SUCCESS) {
1946             procInit = true;
1947         }
1948     }
1949     HDF_LOGI("%s: mmc init success.", __func__);
1950     return HDF_SUCCESS;
1951 }
1952 
HimciMmcRelease(struct HdfDeviceObject * obj)1953 static void HimciMmcRelease(struct HdfDeviceObject *obj)
1954 {
1955     struct MmcCntlr *cntlr = NULL;
1956 
1957     HDF_LOGI("%s: enter", __func__);
1958     if (obj == NULL) {
1959         return;
1960     }
1961 
1962     cntlr = (struct MmcCntlr *)obj->service;
1963     if (cntlr == NULL) {
1964         return;
1965     }
1966     HimciDeleteHost((struct HimciHost *)cntlr->priv);
1967 }
1968 
1969 struct HdfDriverEntry g_mmcDriverEntry = {
1970     .moduleVersion = 1,
1971     .Bind = HimciMmcBind,
1972     .Init = HimciMmcInit,
1973     .Release = HimciMmcRelease,
1974     .moduleName = "hi3516_mmc_driver",
1975 };
1976 HDF_INIT(g_mmcDriverEntry);
1977