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