1 // SPDX-License-Identifier: GPL-2.0-only
4 * Copyright (c) 2011, The Linux Foundation. All rights reserved.
7 #include <linux/of_dma.h>
8 #include <linux/bitops.h>
9 #include <linux/mmc/host.h>
10 #include <linux/mmc/card.h>
14 #define DML_CONFIG 0x00
15 #define PRODUCER_CRCI_MSK GENMASK(1, 0)
16 #define PRODUCER_CRCI_DISABLE 0
17 #define PRODUCER_CRCI_X_SEL BIT(0)
18 #define PRODUCER_CRCI_Y_SEL BIT(1)
19 #define CONSUMER_CRCI_MSK GENMASK(3, 2)
20 #define CONSUMER_CRCI_DISABLE 0
21 #define CONSUMER_CRCI_X_SEL BIT(2)
22 #define CONSUMER_CRCI_Y_SEL BIT(3)
23 #define PRODUCER_TRANS_END_EN BIT(4)
24 #define BYPASS BIT(16)
25 #define DIRECT_MODE BIT(17)
26 #define INFINITE_CONS_TRANS BIT(18)
28 #define DML_SW_RESET 0x08
29 #define DML_PRODUCER_START 0x0c
30 #define DML_CONSUMER_START 0x10
31 #define DML_PRODUCER_PIPE_LOGICAL_SIZE 0x14
32 #define DML_CONSUMER_PIPE_LOGICAL_SIZE 0x18
33 #define DML_PIPE_ID 0x1c
34 #define PRODUCER_PIPE_ID_SHFT 0
35 #define PRODUCER_PIPE_ID_MSK GENMASK(4, 0)
36 #define CONSUMER_PIPE_ID_SHFT 16
37 #define CONSUMER_PIPE_ID_MSK GENMASK(20, 16)
39 #define DML_PRODUCER_BAM_BLOCK_SIZE 0x24
40 #define DML_PRODUCER_BAM_TRANS_SIZE 0x28
42 /* other definitions */
43 #define PRODUCER_PIPE_LOGICAL_SIZE 4096
44 #define CONSUMER_PIPE_LOGICAL_SIZE 4096
46 #define DML_OFFSET 0x800
48 static int qcom_dma_start(struct mmci_host
*host
, unsigned int *datactrl
)
51 void __iomem
*base
= host
->base
+ DML_OFFSET
;
52 struct mmc_data
*data
= host
->data
;
53 int ret
= mmci_dmae_start(host
, datactrl
);
58 if (data
->flags
& MMC_DATA_READ
) {
59 /* Read operation: configure DML for producer operation */
60 /* Set producer CRCI-x and disable consumer CRCI */
61 config
= readl_relaxed(base
+ DML_CONFIG
);
62 config
= (config
& ~PRODUCER_CRCI_MSK
) | PRODUCER_CRCI_X_SEL
;
63 config
= (config
& ~CONSUMER_CRCI_MSK
) | CONSUMER_CRCI_DISABLE
;
64 writel_relaxed(config
, base
+ DML_CONFIG
);
66 /* Set the Producer BAM block size */
67 writel_relaxed(data
->blksz
, base
+ DML_PRODUCER_BAM_BLOCK_SIZE
);
69 /* Set Producer BAM Transaction size */
70 writel_relaxed(data
->blocks
* data
->blksz
,
71 base
+ DML_PRODUCER_BAM_TRANS_SIZE
);
72 /* Set Producer Transaction End bit */
73 config
= readl_relaxed(base
+ DML_CONFIG
);
74 config
|= PRODUCER_TRANS_END_EN
;
75 writel_relaxed(config
, base
+ DML_CONFIG
);
76 /* Trigger producer */
77 writel_relaxed(1, base
+ DML_PRODUCER_START
);
79 /* Write operation: configure DML for consumer operation */
80 /* Set consumer CRCI-x and disable producer CRCI*/
81 config
= readl_relaxed(base
+ DML_CONFIG
);
82 config
= (config
& ~CONSUMER_CRCI_MSK
) | CONSUMER_CRCI_X_SEL
;
83 config
= (config
& ~PRODUCER_CRCI_MSK
) | PRODUCER_CRCI_DISABLE
;
84 writel_relaxed(config
, base
+ DML_CONFIG
);
85 /* Clear Producer Transaction End bit */
86 config
= readl_relaxed(base
+ DML_CONFIG
);
87 config
&= ~PRODUCER_TRANS_END_EN
;
88 writel_relaxed(config
, base
+ DML_CONFIG
);
89 /* Trigger consumer */
90 writel_relaxed(1, base
+ DML_CONSUMER_START
);
93 /* make sure the dml is configured before dma is triggered */
98 static int of_get_dml_pipe_index(struct device_node
*np
, const char *name
)
101 struct of_phandle_args dma_spec
;
103 index
= of_property_match_string(np
, "dma-names", name
);
108 if (of_parse_phandle_with_args(np
, "dmas", "#dma-cells", index
,
112 if (dma_spec
.args_count
)
113 return dma_spec
.args
[0];
118 /* Initialize the dml hardware connected to SD Card controller */
119 static int qcom_dma_setup(struct mmci_host
*host
)
123 int consumer_id
, producer_id
;
124 struct device_node
*np
= host
->mmc
->parent
->of_node
;
126 if (mmci_dmae_setup(host
))
129 consumer_id
= of_get_dml_pipe_index(np
, "tx");
130 producer_id
= of_get_dml_pipe_index(np
, "rx");
132 if (producer_id
< 0 || consumer_id
< 0) {
133 mmci_dmae_release(host
);
137 base
= host
->base
+ DML_OFFSET
;
139 /* Reset the DML block */
140 writel_relaxed(1, base
+ DML_SW_RESET
);
142 /* Disable the producer and consumer CRCI */
143 config
= (PRODUCER_CRCI_DISABLE
| CONSUMER_CRCI_DISABLE
);
145 * Disable the bypass mode. Bypass mode will only be used
146 * if data transfer is to happen in PIO mode and don't
147 * want the BAM interface to connect with SDCC-DML.
151 * Disable direct mode as we don't DML to MASTER the AHB bus.
152 * BAM connected with DML should MASTER the AHB bus.
154 config
&= ~DIRECT_MODE
;
156 * Disable infinite mode transfer as we won't be doing any
157 * infinite size data transfers. All data transfer will be
158 * of finite data size.
160 config
&= ~INFINITE_CONS_TRANS
;
161 writel_relaxed(config
, base
+ DML_CONFIG
);
164 * Initialize the logical BAM pipe size for producer
167 writel_relaxed(PRODUCER_PIPE_LOGICAL_SIZE
,
168 base
+ DML_PRODUCER_PIPE_LOGICAL_SIZE
);
169 writel_relaxed(CONSUMER_PIPE_LOGICAL_SIZE
,
170 base
+ DML_CONSUMER_PIPE_LOGICAL_SIZE
);
172 /* Initialize Producer/consumer pipe id */
173 writel_relaxed(producer_id
| (consumer_id
<< CONSUMER_PIPE_ID_SHFT
),
176 /* Make sure dml initialization is finished */
182 static u32
qcom_get_dctrl_cfg(struct mmci_host
*host
)
184 return MCI_DPSM_ENABLE
| (host
->data
->blksz
<< 4);
187 static struct mmci_host_ops qcom_variant_ops
= {
188 .prep_data
= mmci_dmae_prep_data
,
189 .unprep_data
= mmci_dmae_unprep_data
,
190 .get_datactrl_cfg
= qcom_get_dctrl_cfg
,
191 .get_next_data
= mmci_dmae_get_next_data
,
192 .dma_setup
= qcom_dma_setup
,
193 .dma_release
= mmci_dmae_release
,
194 .dma_start
= qcom_dma_start
,
195 .dma_finalize
= mmci_dmae_finalize
,
196 .dma_error
= mmci_dmae_error
,
199 void qcom_variant_init(struct mmci_host
*host
)
201 host
->ops
= &qcom_variant_ops
;