dm: core: Create a new header file for 'compat' features
[oweals/u-boot.git] / drivers / mmc / mmc-uclass.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2015 Google, Inc
4  * Written by Simon Glass <sjg@chromium.org>
5  */
6
7 #include <common.h>
8 #include <mmc.h>
9 #include <dm.h>
10 #include <dm/device-internal.h>
11 #include <dm/device_compat.h>
12 #include <dm/lists.h>
13 #include <linux/compat.h>
14 #include "mmc_private.h"
15
16 int dm_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
17                     struct mmc_data *data)
18 {
19         struct mmc *mmc = mmc_get_mmc_dev(dev);
20         struct dm_mmc_ops *ops = mmc_get_ops(dev);
21         int ret;
22
23         mmmc_trace_before_send(mmc, cmd);
24         if (ops->send_cmd)
25                 ret = ops->send_cmd(dev, cmd, data);
26         else
27                 ret = -ENOSYS;
28         mmmc_trace_after_send(mmc, cmd, ret);
29
30         return ret;
31 }
32
33 int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
34 {
35         return dm_mmc_send_cmd(mmc->dev, cmd, data);
36 }
37
38 int dm_mmc_set_ios(struct udevice *dev)
39 {
40         struct dm_mmc_ops *ops = mmc_get_ops(dev);
41
42         if (!ops->set_ios)
43                 return -ENOSYS;
44         return ops->set_ios(dev);
45 }
46
47 int mmc_set_ios(struct mmc *mmc)
48 {
49         return dm_mmc_set_ios(mmc->dev);
50 }
51
52 int dm_mmc_wait_dat0(struct udevice *dev, int state, int timeout_us)
53 {
54         struct dm_mmc_ops *ops = mmc_get_ops(dev);
55
56         if (!ops->wait_dat0)
57                 return -ENOSYS;
58         return ops->wait_dat0(dev, state, timeout_us);
59 }
60
61 int mmc_wait_dat0(struct mmc *mmc, int state, int timeout_us)
62 {
63         return dm_mmc_wait_dat0(mmc->dev, state, timeout_us);
64 }
65
66 int dm_mmc_get_wp(struct udevice *dev)
67 {
68         struct dm_mmc_ops *ops = mmc_get_ops(dev);
69
70         if (!ops->get_wp)
71                 return -ENOSYS;
72         return ops->get_wp(dev);
73 }
74
75 int mmc_getwp(struct mmc *mmc)
76 {
77         return dm_mmc_get_wp(mmc->dev);
78 }
79
80 int dm_mmc_get_cd(struct udevice *dev)
81 {
82         struct dm_mmc_ops *ops = mmc_get_ops(dev);
83
84         if (!ops->get_cd)
85                 return -ENOSYS;
86         return ops->get_cd(dev);
87 }
88
89 int mmc_getcd(struct mmc *mmc)
90 {
91         return dm_mmc_get_cd(mmc->dev);
92 }
93
94 #ifdef MMC_SUPPORTS_TUNING
95 int dm_mmc_execute_tuning(struct udevice *dev, uint opcode)
96 {
97         struct dm_mmc_ops *ops = mmc_get_ops(dev);
98
99         if (!ops->execute_tuning)
100                 return -ENOSYS;
101         return ops->execute_tuning(dev, opcode);
102 }
103
104 int mmc_execute_tuning(struct mmc *mmc, uint opcode)
105 {
106         return dm_mmc_execute_tuning(mmc->dev, opcode);
107 }
108 #endif
109
110 #if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT)
111 int dm_mmc_set_enhanced_strobe(struct udevice *dev)
112 {
113         struct dm_mmc_ops *ops = mmc_get_ops(dev);
114
115         if (ops->set_enhanced_strobe)
116                 return ops->set_enhanced_strobe(dev);
117
118         return -ENOTSUPP;
119 }
120
121 int mmc_set_enhanced_strobe(struct mmc *mmc)
122 {
123         return dm_mmc_set_enhanced_strobe(mmc->dev);
124 }
125 #endif
126
127 int dm_mmc_host_power_cycle(struct udevice *dev)
128 {
129         struct dm_mmc_ops *ops = mmc_get_ops(dev);
130
131         if (ops->host_power_cycle)
132                 return ops->host_power_cycle(dev);
133         return 0;
134 }
135
136 int mmc_host_power_cycle(struct mmc *mmc)
137 {
138         return dm_mmc_host_power_cycle(mmc->dev);
139 }
140
141 int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg)
142 {
143         int val;
144
145         val = dev_read_u32_default(dev, "bus-width", 1);
146
147         switch (val) {
148         case 0x8:
149                 cfg->host_caps |= MMC_MODE_8BIT;
150                 /* fall through */
151         case 0x4:
152                 cfg->host_caps |= MMC_MODE_4BIT;
153                 /* fall through */
154         case 0x1:
155                 cfg->host_caps |= MMC_MODE_1BIT;
156                 break;
157         default:
158                 dev_err(dev, "Invalid \"bus-width\" value %u!\n", val);
159                 return -EINVAL;
160         }
161
162         /* f_max is obtained from the optional "max-frequency" property */
163         dev_read_u32(dev, "max-frequency", &cfg->f_max);
164
165         if (dev_read_bool(dev, "cap-sd-highspeed"))
166                 cfg->host_caps |= MMC_CAP(SD_HS);
167         if (dev_read_bool(dev, "cap-mmc-highspeed"))
168                 cfg->host_caps |= MMC_CAP(MMC_HS);
169         if (dev_read_bool(dev, "sd-uhs-sdr12"))
170                 cfg->host_caps |= MMC_CAP(UHS_SDR12);
171         if (dev_read_bool(dev, "sd-uhs-sdr25"))
172                 cfg->host_caps |= MMC_CAP(UHS_SDR25);
173         if (dev_read_bool(dev, "sd-uhs-sdr50"))
174                 cfg->host_caps |= MMC_CAP(UHS_SDR50);
175         if (dev_read_bool(dev, "sd-uhs-sdr104"))
176                 cfg->host_caps |= MMC_CAP(UHS_SDR104);
177         if (dev_read_bool(dev, "sd-uhs-ddr50"))
178                 cfg->host_caps |= MMC_CAP(UHS_DDR50);
179         if (dev_read_bool(dev, "mmc-ddr-1_8v"))
180                 cfg->host_caps |= MMC_CAP(MMC_DDR_52);
181         if (dev_read_bool(dev, "mmc-ddr-1_2v"))
182                 cfg->host_caps |= MMC_CAP(MMC_DDR_52);
183         if (dev_read_bool(dev, "mmc-hs200-1_8v"))
184                 cfg->host_caps |= MMC_CAP(MMC_HS_200);
185         if (dev_read_bool(dev, "mmc-hs200-1_2v"))
186                 cfg->host_caps |= MMC_CAP(MMC_HS_200);
187         if (dev_read_bool(dev, "mmc-hs400-1_8v"))
188                 cfg->host_caps |= MMC_CAP(MMC_HS_400);
189         if (dev_read_bool(dev, "mmc-hs400-1_2v"))
190                 cfg->host_caps |= MMC_CAP(MMC_HS_400);
191         if (dev_read_bool(dev, "mmc-hs400-enhanced-strobe"))
192                 cfg->host_caps |= MMC_CAP(MMC_HS_400_ES);
193
194         if (dev_read_bool(dev, "non-removable")) {
195                 cfg->host_caps |= MMC_CAP_NONREMOVABLE;
196         } else {
197                 if (dev_read_bool(dev, "cd-inverted"))
198                         cfg->host_caps |= MMC_CAP_CD_ACTIVE_HIGH;
199                 if (dev_read_bool(dev, "broken-cd"))
200                         cfg->host_caps |= MMC_CAP_NEEDS_POLL;
201         }
202
203         if (dev_read_bool(dev, "no-1-8-v")) {
204                 cfg->host_caps &= ~(UHS_CAPS | MMC_MODE_HS200 |
205                                     MMC_MODE_HS400 | MMC_MODE_HS400_ES);
206         }
207
208         return 0;
209 }
210
211 struct mmc *mmc_get_mmc_dev(struct udevice *dev)
212 {
213         struct mmc_uclass_priv *upriv;
214
215         if (!device_active(dev))
216                 return NULL;
217         upriv = dev_get_uclass_priv(dev);
218         return upriv->mmc;
219 }
220
221 #if CONFIG_IS_ENABLED(BLK)
222 struct mmc *find_mmc_device(int dev_num)
223 {
224         struct udevice *dev, *mmc_dev;
225         int ret;
226
227         ret = blk_find_device(IF_TYPE_MMC, dev_num, &dev);
228
229         if (ret) {
230 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
231                 printf("MMC Device %d not found\n", dev_num);
232 #endif
233                 return NULL;
234         }
235
236         mmc_dev = dev_get_parent(dev);
237
238         struct mmc *mmc = mmc_get_mmc_dev(mmc_dev);
239
240         return mmc;
241 }
242
243 int get_mmc_num(void)
244 {
245         return max((blk_find_max_devnum(IF_TYPE_MMC) + 1), 0);
246 }
247
248 int mmc_get_next_devnum(void)
249 {
250         return blk_find_max_devnum(IF_TYPE_MMC);
251 }
252
253 struct blk_desc *mmc_get_blk_desc(struct mmc *mmc)
254 {
255         struct blk_desc *desc;
256         struct udevice *dev;
257
258         device_find_first_child(mmc->dev, &dev);
259         if (!dev)
260                 return NULL;
261         desc = dev_get_uclass_platdata(dev);
262
263         return desc;
264 }
265
266 void mmc_do_preinit(void)
267 {
268         struct udevice *dev;
269         struct uclass *uc;
270         int ret;
271
272         ret = uclass_get(UCLASS_MMC, &uc);
273         if (ret)
274                 return;
275         uclass_foreach_dev(dev, uc) {
276                 struct mmc *m = mmc_get_mmc_dev(dev);
277
278                 if (!m)
279                         continue;
280 #ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
281                 mmc_set_preinit(m, 1);
282 #endif
283                 if (m->preinit)
284                         mmc_start_init(m);
285         }
286 }
287
288 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
289 void print_mmc_devices(char separator)
290 {
291         struct udevice *dev;
292         char *mmc_type;
293         bool first = true;
294
295         for (uclass_first_device(UCLASS_MMC, &dev);
296              dev;
297              uclass_next_device(&dev), first = false) {
298                 struct mmc *m = mmc_get_mmc_dev(dev);
299
300                 if (!first) {
301                         printf("%c", separator);
302                         if (separator != '\n')
303                                 puts(" ");
304                 }
305                 if (m->has_init)
306                         mmc_type = IS_SD(m) ? "SD" : "eMMC";
307                 else
308                         mmc_type = NULL;
309
310                 printf("%s: %d", m->cfg->name, mmc_get_blk_desc(m)->devnum);
311                 if (mmc_type)
312                         printf(" (%s)", mmc_type);
313         }
314
315         printf("\n");
316 }
317
318 #else
319 void print_mmc_devices(char separator) { }
320 #endif
321
322 int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg)
323 {
324         struct blk_desc *bdesc;
325         struct udevice *bdev;
326         int ret, devnum = -1;
327
328         if (!mmc_get_ops(dev))
329                 return -ENOSYS;
330 #ifndef CONFIG_SPL_BUILD
331         /* Use the fixed index with aliase node's index */
332         ret = dev_read_alias_seq(dev, &devnum);
333         debug("%s: alias ret=%d, devnum=%d\n", __func__, ret, devnum);
334 #endif
335
336         ret = blk_create_devicef(dev, "mmc_blk", "blk", IF_TYPE_MMC,
337                         devnum, 512, 0, &bdev);
338         if (ret) {
339                 debug("Cannot create block device\n");
340                 return ret;
341         }
342         bdesc = dev_get_uclass_platdata(bdev);
343         mmc->cfg = cfg;
344         mmc->priv = dev;
345
346         /* the following chunk was from mmc_register() */
347
348         /* Setup dsr related values */
349         mmc->dsr_imp = 0;
350         mmc->dsr = 0xffffffff;
351         /* Setup the universal parts of the block interface just once */
352         bdesc->removable = 1;
353
354         /* setup initial part type */
355         bdesc->part_type = cfg->part_type;
356         mmc->dev = dev;
357
358         return 0;
359 }
360
361 int mmc_unbind(struct udevice *dev)
362 {
363         struct udevice *bdev;
364
365         device_find_first_child(dev, &bdev);
366         if (bdev) {
367                 device_remove(bdev, DM_REMOVE_NORMAL);
368                 device_unbind(bdev);
369         }
370
371         return 0;
372 }
373
374 static int mmc_select_hwpart(struct udevice *bdev, int hwpart)
375 {
376         struct udevice *mmc_dev = dev_get_parent(bdev);
377         struct mmc *mmc = mmc_get_mmc_dev(mmc_dev);
378         struct blk_desc *desc = dev_get_uclass_platdata(bdev);
379         int ret;
380
381         if (desc->hwpart == hwpart)
382                 return 0;
383
384         if (mmc->part_config == MMCPART_NOAVAILABLE)
385                 return -EMEDIUMTYPE;
386
387         ret = mmc_switch_part(mmc, hwpart);
388         if (!ret)
389                 blkcache_invalidate(desc->if_type, desc->devnum);
390
391         return ret;
392 }
393
394 static int mmc_blk_probe(struct udevice *dev)
395 {
396         struct udevice *mmc_dev = dev_get_parent(dev);
397         struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc_dev);
398         struct mmc *mmc = upriv->mmc;
399         int ret;
400
401         ret = mmc_init(mmc);
402         if (ret) {
403                 debug("%s: mmc_init() failed (err=%d)\n", __func__, ret);
404                 return ret;
405         }
406
407         return 0;
408 }
409
410 #if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
411     CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
412     CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
413 static int mmc_blk_remove(struct udevice *dev)
414 {
415         struct udevice *mmc_dev = dev_get_parent(dev);
416         struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc_dev);
417         struct mmc *mmc = upriv->mmc;
418
419         return mmc_deinit(mmc);
420 }
421 #endif
422
423 static const struct blk_ops mmc_blk_ops = {
424         .read   = mmc_bread,
425 #if CONFIG_IS_ENABLED(MMC_WRITE)
426         .write  = mmc_bwrite,
427         .erase  = mmc_berase,
428 #endif
429         .select_hwpart  = mmc_select_hwpart,
430 };
431
432 U_BOOT_DRIVER(mmc_blk) = {
433         .name           = "mmc_blk",
434         .id             = UCLASS_BLK,
435         .ops            = &mmc_blk_ops,
436         .probe          = mmc_blk_probe,
437 #if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
438     CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
439     CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
440         .remove         = mmc_blk_remove,
441         .flags          = DM_FLAG_OS_PREPARE,
442 #endif
443 };
444 #endif /* CONFIG_BLK */
445
446
447 UCLASS_DRIVER(mmc) = {
448         .id             = UCLASS_MMC,
449         .name           = "mmc",
450         .flags          = DM_UC_FLAG_SEQ_ALIAS,
451         .per_device_auto_alloc_size = sizeof(struct mmc_uclass_priv),
452 };