xref: /rk3399_rockchip-uboot/drivers/mmc/mmc-uclass.c (revision d8db5367cf2573bd2878866cf70446102183652c)
1 /*
2  * Copyright (C) 2015 Google, Inc
3  * Written by Simon Glass <sjg@chromium.org>
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 
8 #include <common.h>
9 #include <mmc.h>
10 #include <dm.h>
11 #include <dm/device-internal.h>
12 #include <dm/lists.h>
13 #include <dm/root.h>
14 #include "mmc_private.h"
15 
16 DECLARE_GLOBAL_DATA_PTR;
17 
18 int dm_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
19 		    struct mmc_data *data)
20 {
21 	struct mmc *mmc = mmc_get_mmc_dev(dev);
22 	struct dm_mmc_ops *ops = mmc_get_ops(dev);
23 	int ret, retry_time = 3;
24 
25 retry:
26 	mmmc_trace_before_send(mmc, cmd);
27 	if (ops->send_cmd)
28 		ret = ops->send_cmd(dev, cmd, data);
29 	else
30 		ret = -ENOSYS;
31 	mmmc_trace_after_send(mmc, cmd, ret);
32 
33 	if (ret && cmd->cmdidx != SD_CMD_SEND_IF_COND
34 	    && cmd->cmdidx != MMC_CMD_APP_CMD) {
35 		if (retry_time-- > 0)
36 			goto retry;
37 		printf("MMC error: The cmd index is %d, ret is %d.....\n", cmd->cmdidx, ret);
38 	}
39 
40 	return ret;
41 }
42 
43 #ifdef CONFIG_SPL_BLK_READ_PREPARE
44 int dm_mmc_send_cmd_prepare(struct udevice *dev, struct mmc_cmd *cmd,
45 			    struct mmc_data *data)
46 {
47 	struct mmc *mmc = mmc_get_mmc_dev(dev);
48 	struct dm_mmc_ops *ops = mmc_get_ops(dev);
49 	int ret;
50 
51 	mmmc_trace_before_send(mmc, cmd);
52 	if (ops->send_cmd_prepare)
53 		ret = ops->send_cmd_prepare(dev, cmd, data);
54 	else
55 		ret = -ENOSYS;
56 	mmmc_trace_after_send(mmc, cmd, ret);
57 	if (ret && cmd->cmdidx != SD_CMD_SEND_IF_COND
58 	    && cmd->cmdidx != MMC_CMD_APP_CMD)
59 		printf("MMC error: The cmd index is %d, ret is %d\n", cmd->cmdidx, ret);
60 
61 	return ret;
62 }
63 #endif
64 
65 int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
66 {
67 	return dm_mmc_send_cmd(mmc->dev, cmd, data);
68 }
69 
70 #ifdef CONFIG_SPL_BLK_READ_PREPARE
71 int mmc_send_cmd_prepare(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
72 {
73 	return dm_mmc_send_cmd_prepare(mmc->dev, cmd, data);
74 }
75 #endif
76 
77 bool mmc_card_busy(struct mmc *mmc)
78 {
79 	struct dm_mmc_ops *ops = mmc_get_ops(mmc->dev);
80 
81 	if (!ops->card_busy)
82 		return -ENOSYS;
83 	return ops->card_busy(mmc->dev);
84 }
85 
86 bool mmc_can_card_busy(struct mmc *mmc)
87 {
88 	struct dm_mmc_ops *ops = mmc_get_ops(mmc->dev);
89 
90 	return !!ops->card_busy;
91 }
92 
93 int dm_mmc_set_ios(struct udevice *dev)
94 {
95 	struct dm_mmc_ops *ops = mmc_get_ops(dev);
96 
97 	if (!ops->set_ios)
98 		return -ENOSYS;
99 	return ops->set_ios(dev);
100 }
101 
102 int mmc_set_ios(struct mmc *mmc)
103 {
104 	return dm_mmc_set_ios(mmc->dev);
105 }
106 
107 int dm_mmc_get_wp(struct udevice *dev)
108 {
109 	struct dm_mmc_ops *ops = mmc_get_ops(dev);
110 
111 	if (!ops->get_wp)
112 		return -ENOSYS;
113 	return ops->get_wp(dev);
114 }
115 
116 int mmc_getwp(struct mmc *mmc)
117 {
118 	return dm_mmc_get_wp(mmc->dev);
119 }
120 
121 int dm_mmc_get_cd(struct udevice *dev)
122 {
123 	struct dm_mmc_ops *ops = mmc_get_ops(dev);
124 
125 	if (!ops->get_cd)
126 		return -ENOSYS;
127 	return ops->get_cd(dev);
128 }
129 
130 int mmc_getcd(struct mmc *mmc)
131 {
132 	return dm_mmc_get_cd(mmc->dev);
133 }
134 
135 struct mmc *mmc_get_mmc_dev(struct udevice *dev)
136 {
137 	struct mmc_uclass_priv *upriv;
138 
139 	if (!device_active(dev))
140 		return NULL;
141 	upriv = dev_get_uclass_priv(dev);
142 	return upriv->mmc;
143 }
144 
145 #if CONFIG_IS_ENABLED(BLK)
146 struct mmc *find_mmc_device(int dev_num)
147 {
148 	struct udevice *dev, *mmc_dev;
149 	int ret;
150 
151 	ret = blk_find_device(IF_TYPE_MMC, dev_num, &dev);
152 
153 	if (ret) {
154 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
155 		printf("MMC Device %d not found\n", dev_num);
156 #endif
157 		return NULL;
158 	}
159 
160 	mmc_dev = dev_get_parent(dev);
161 
162 	struct mmc *mmc = mmc_get_mmc_dev(mmc_dev);
163 
164 	return mmc;
165 }
166 
167 int get_mmc_num(void)
168 {
169 	return max((blk_find_max_devnum(IF_TYPE_MMC) + 1), 0);
170 }
171 
172 int mmc_get_next_devnum(void)
173 {
174 	return blk_find_max_devnum(IF_TYPE_MMC);
175 }
176 
177 struct blk_desc *mmc_get_blk_desc(struct mmc *mmc)
178 {
179 	struct blk_desc *desc;
180 	struct udevice *dev;
181 
182 	device_find_first_child(mmc->dev, &dev);
183 	if (!dev)
184 		return NULL;
185 	desc = dev_get_uclass_platdata(dev);
186 
187 	return desc;
188 }
189 
190 void mmc_do_preinit(void)
191 {
192 	struct udevice *dev;
193 	struct uclass *uc;
194 	int ret;
195 
196 	ret = uclass_get(UCLASS_MMC, &uc);
197 	if (ret)
198 		return;
199 	uclass_foreach_dev(dev, uc) {
200 		struct mmc *m = mmc_get_mmc_dev(dev);
201 
202 		if (!m)
203 			continue;
204 #ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
205 		mmc_set_preinit(m, 1);
206 #endif
207 		if (m->preinit)
208 			mmc_start_init(m);
209 	}
210 }
211 
212 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
213 void print_mmc_devices(char separator)
214 {
215 	struct udevice *dev;
216 	char *mmc_type;
217 	bool first = true;
218 
219 	for (uclass_first_device(UCLASS_MMC, &dev);
220 	     dev;
221 	     uclass_next_device(&dev), first = false) {
222 		struct mmc *m = mmc_get_mmc_dev(dev);
223 
224 		if (!first) {
225 			printf("%c", separator);
226 			if (separator != '\n')
227 				puts(" ");
228 		}
229 		if (m->has_init)
230 			mmc_type = IS_SD(m) ? "SD" : "eMMC";
231 		else
232 			mmc_type = NULL;
233 
234 		printf("%s: %d", m->cfg->name, mmc_get_blk_desc(m)->devnum);
235 		if (mmc_type)
236 			printf(" (%s)", mmc_type);
237 	}
238 
239 	printf("\n");
240 }
241 
242 #else
243 void print_mmc_devices(char separator) { }
244 #endif
245 
246 int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg)
247 {
248 	struct blk_desc *bdesc;
249 	struct udevice *bdev;
250 	int ret, devnum = -1;
251 
252 	if (!mmc_get_ops(dev))
253 		return -ENOSYS;
254 	/* Use the fixed index with aliase node's index */
255 	ret = dev_read_alias_seq(dev, &devnum);
256 	debug("%s: alias ret=%d, devnum=%d\n", __func__, ret, devnum);
257 
258 	ret = blk_create_devicef(dev, "mmc_blk", "blk", IF_TYPE_MMC,
259 			devnum, 512, 0, &bdev);
260 	if (ret) {
261 		debug("Cannot create block device\n");
262 		return ret;
263 	}
264 	bdesc = dev_get_uclass_platdata(bdev);
265 	mmc->cfg = cfg;
266 	mmc->priv = dev;
267 
268 	/* the following chunk was from mmc_register() */
269 
270 	/* Setup dsr related values */
271 	mmc->dsr_imp = 0;
272 	mmc->dsr = 0xffffffff;
273 	/* Setup the universal parts of the block interface just once */
274 	bdesc->removable = 1;
275 
276 	/* setup initial part type */
277 	bdesc->part_type = cfg->part_type;
278 	mmc->dev = dev;
279 
280 	return 0;
281 }
282 
283 int mmc_unbind(struct udevice *dev)
284 {
285 	struct udevice *bdev;
286 
287 	device_find_first_child(dev, &bdev);
288 	if (bdev) {
289 		device_remove(bdev, DM_REMOVE_NORMAL);
290 		device_unbind(bdev);
291 	}
292 
293 	return 0;
294 }
295 
296 static int mmc_select_hwpart(struct udevice *bdev, int hwpart)
297 {
298 	struct udevice *mmc_dev = dev_get_parent(bdev);
299 	struct mmc *mmc = mmc_get_mmc_dev(mmc_dev);
300 	struct blk_desc *desc = dev_get_uclass_platdata(bdev);
301 
302 	if (desc->hwpart == hwpart)
303 		return 0;
304 
305 	if (mmc->part_config == MMCPART_NOAVAILABLE)
306 		return -EMEDIUMTYPE;
307 
308 	return mmc_switch_part(mmc, hwpart);
309 }
310 
311 static int mmc_blk_probe(struct udevice *dev)
312 {
313 	struct udevice *mmc_dev = dev_get_parent(dev);
314 	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc_dev);
315 	struct mmc *mmc = upriv->mmc;
316 	int ret;
317 
318 	ret = mmc_init(mmc);
319 	if (ret) {
320 		debug("%s: mmc_init() failed (err=%d)\n", __func__, ret);
321 		return ret;
322 	}
323 
324 	return 0;
325 }
326 
327 static const struct blk_ops mmc_blk_ops = {
328 	.read	= mmc_bread,
329 #if CONFIG_IS_ENABLED(MMC_WRITE)
330 	.write	= mmc_bwrite,
331 	.erase	= mmc_berase,
332 #endif
333 	.select_hwpart	= mmc_select_hwpart,
334 };
335 
336 U_BOOT_DRIVER(mmc_blk) = {
337 	.name		= "mmc_blk",
338 	.id		= UCLASS_BLK,
339 	.ops		= &mmc_blk_ops,
340 	.probe		= mmc_blk_probe,
341 };
342 #endif /* CONFIG_BLK */
343 
344 U_BOOT_DRIVER(mmc) = {
345 	.name	= "mmc",
346 	.id	= UCLASS_MMC,
347 };
348 
349 UCLASS_DRIVER(mmc) = {
350 	.id		= UCLASS_MMC,
351 	.name		= "mmc",
352 	.flags		= DM_UC_FLAG_SEQ_ALIAS,
353 	.per_device_auto_alloc_size = sizeof(struct mmc_uclass_priv),
354 };
355