mb/google/brya/var/orisa: Update Type C DisplayPort HPD Configuration
[coreboot2.git] / src / commonlib / storage / sdhci_adma.c
blob9ad949edcdfd648dc2dbcfa1bb53ee6f111056b1
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3 * Secure Digital (SD) Host Controller interface DMA support code
4 */
6 #include <commonlib/sdhci.h>
7 #include <commonlib/storage.h>
8 #include <console/console.h>
9 #include <delay.h>
10 #include <endian.h>
11 #include <stdlib.h>
12 #include <string.h>
14 #include "sdhci.h"
15 #include "sd_mmc.h"
16 #include "storage.h"
18 static void sdhci_alloc_adma_descs(struct sdhci_ctrlr *sdhci_ctrlr,
19 u32 need_descriptors)
21 if (sdhci_ctrlr->adma_descs) {
22 if (sdhci_ctrlr->adma_desc_count < need_descriptors) {
23 /* Previously allocated array is too small */
24 free(sdhci_ctrlr->adma_descs);
25 sdhci_ctrlr->adma_desc_count = 0;
26 sdhci_ctrlr->adma_descs = NULL;
30 /* use dma_malloc() to make sure we get the coherent/uncached memory */
31 if (!sdhci_ctrlr->adma_descs) {
32 sdhci_ctrlr->adma_descs = malloc(need_descriptors
33 * sizeof(*sdhci_ctrlr->adma_descs));
34 if (sdhci_ctrlr->adma_descs == NULL)
35 die("fail to malloc adma_descs\n");
36 sdhci_ctrlr->adma_desc_count = need_descriptors;
39 memset(sdhci_ctrlr->adma_descs, 0, sizeof(*sdhci_ctrlr->adma_descs)
40 * need_descriptors);
43 static void sdhci_alloc_adma64_descs(struct sdhci_ctrlr *sdhci_ctrlr,
44 u32 need_descriptors)
46 if (sdhci_ctrlr->adma64_descs) {
47 if (sdhci_ctrlr->adma_desc_count < need_descriptors) {
48 /* Previously allocated array is too small */
49 free(sdhci_ctrlr->adma64_descs);
50 sdhci_ctrlr->adma_desc_count = 0;
51 sdhci_ctrlr->adma64_descs = NULL;
55 /* use dma_malloc() to make sure we get the coherent/uncached memory */
56 if (!sdhci_ctrlr->adma64_descs) {
57 sdhci_ctrlr->adma64_descs = malloc(need_descriptors
58 * sizeof(*sdhci_ctrlr->adma64_descs));
59 if (sdhci_ctrlr->adma64_descs == NULL)
60 die("fail to malloc adma64_descs\n");
62 sdhci_ctrlr->adma_desc_count = need_descriptors;
65 memset(sdhci_ctrlr->adma64_descs, 0, sizeof(*sdhci_ctrlr->adma64_descs)
66 * need_descriptors);
69 int sdhci_setup_adma(struct sdhci_ctrlr *sdhci_ctrlr, struct mmc_data *data)
71 int i, togo, need_descriptors;
72 int dma64;
73 char *buffer_data;
74 u16 attributes;
76 togo = data->blocks * data->blocksize;
77 if (!togo) {
78 sdhc_error("%s: MmcData corrupted: %d blocks of %d bytes\n",
79 __func__, data->blocks, data->blocksize);
80 return -1;
83 need_descriptors = 1 + togo / SDHCI_MAX_PER_DESCRIPTOR;
84 dma64 = sdhci_ctrlr->sd_mmc_ctrlr.caps & DRVR_CAP_DMA_64BIT;
85 if (dma64)
86 sdhci_alloc_adma64_descs(sdhci_ctrlr, need_descriptors);
87 else
88 sdhci_alloc_adma_descs(sdhci_ctrlr, need_descriptors);
89 buffer_data = data->dest;
91 /* Now set up the descriptor chain. */
92 for (i = 0; togo; i++) {
93 unsigned int desc_length;
95 if (togo < SDHCI_MAX_PER_DESCRIPTOR)
96 desc_length = togo;
97 else
98 desc_length = SDHCI_MAX_PER_DESCRIPTOR;
99 togo -= desc_length;
101 attributes = SDHCI_ADMA_VALID | SDHCI_ACT_TRAN;
102 if (togo == 0)
103 attributes |= SDHCI_ADMA_END;
105 if (dma64) {
106 sdhci_ctrlr->adma64_descs[i].addr =
107 (uintptr_t)buffer_data;
108 sdhci_ctrlr->adma64_descs[i].addr_hi = 0;
109 sdhci_ctrlr->adma64_descs[i].length = desc_length;
110 sdhci_ctrlr->adma64_descs[i].attributes = attributes;
112 } else {
113 sdhci_ctrlr->adma_descs[i].addr =
114 (uintptr_t)buffer_data;
115 sdhci_ctrlr->adma_descs[i].length = desc_length;
116 sdhci_ctrlr->adma_descs[i].attributes = attributes;
119 buffer_data += desc_length;
122 if (dma64)
123 sdhci_writel(sdhci_ctrlr, (uintptr_t)sdhci_ctrlr->adma64_descs,
124 SDHCI_ADMA_ADDRESS);
125 else
126 sdhci_writel(sdhci_ctrlr, (uintptr_t)sdhci_ctrlr->adma_descs,
127 SDHCI_ADMA_ADDRESS);
129 return 0;
132 int sdhci_complete_adma(struct sdhci_ctrlr *sdhci_ctrlr,
133 struct mmc_command *cmd)
135 int retry;
136 u32 stat = 0, mask;
138 mask = SDHCI_INT_RESPONSE | SDHCI_INT_ERROR;
140 retry = 10000; /* Command should be done in way less than 10 ms. */
141 while (--retry) {
142 stat = sdhci_readl(sdhci_ctrlr, SDHCI_INT_STATUS);
143 if (stat & mask)
144 break;
145 udelay(1);
148 sdhci_writel(sdhci_ctrlr, SDHCI_INT_RESPONSE, SDHCI_INT_STATUS);
150 if (retry && !(stat & SDHCI_INT_ERROR)) {
151 /* Command OK, let's wait for data transfer completion. */
152 mask = SDHCI_INT_DATA_END |
153 SDHCI_INT_ERROR | SDHCI_INT_ADMA_ERROR;
155 /* Transfer should take 10 seconds tops. */
156 retry = 10 * 1000 * 1000;
157 while (--retry) {
158 stat = sdhci_readl(sdhci_ctrlr, SDHCI_INT_STATUS);
159 if (stat & mask)
160 break;
161 udelay(1);
164 sdhci_writel(sdhci_ctrlr, stat, SDHCI_INT_STATUS);
165 if (retry && !(stat & SDHCI_INT_ERROR)) {
166 sdhci_cmd_done(sdhci_ctrlr, cmd);
167 return 0;
171 sdhc_error("%s: transfer error, stat %#x, adma error %#x, retry %d\n",
172 __func__, stat, sdhci_readl(sdhci_ctrlr, SDHCI_ADMA_ERROR),
173 retry);
175 sdhci_reset(sdhci_ctrlr, SDHCI_RESET_CMD);
176 sdhci_reset(sdhci_ctrlr, SDHCI_RESET_DATA);
178 if (stat & SDHCI_INT_TIMEOUT)
179 return CARD_TIMEOUT;
180 return CARD_COMM_ERR;