Skip to content

Commit fb44132

Browse files
committed
Merge git://git.denx.de/u-boot-mmc
2 parents 1612128 + 2f516e4 commit fb44132

File tree

14 files changed

+836
-33
lines changed

14 files changed

+836
-33
lines changed

configs/odroid-xu3_defconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ CONFIG_CMD_CACHE=y
2222
CONFIG_CMD_TIME=y
2323
CONFIG_CMD_PMIC=y
2424
CONFIG_CMD_EXT4_WRITE=y
25+
CONFIG_CMD_REGULATOR=y
2526
CONFIG_ENV_IS_IN_MMC=y
2627
CONFIG_ADC=y
2728
CONFIG_ADC_EXYNOS=y
@@ -35,6 +36,7 @@ CONFIG_SMC911X_BASE=0x5000000
3536
CONFIG_DM_PMIC=y
3637
CONFIG_PMIC_S2MPS11=y
3738
CONFIG_DM_REGULATOR=y
39+
CONFIG_DM_REGULATOR_S2MPS11=y
3840
CONFIG_USB=y
3941
CONFIG_DM_USB=y
4042
CONFIG_USB_XHCI_HCD=y

drivers/core/read.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010
#include <mapmem.h>
1111
#include <dm/of_access.h>
1212

13+
int dev_read_u32(struct udevice *dev, const char *propname, u32 *outp)
14+
{
15+
return ofnode_read_u32(dev_ofnode(dev), propname, outp);
16+
}
17+
1318
int dev_read_u32_default(struct udevice *dev, const char *propname, int def)
1419
{
1520
return ofnode_read_u32_default(dev_ofnode(dev), propname, def);

drivers/mmc/Kconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ config MMC_WRITE
1717
help
1818
Enable write access to MMC and SD Cards
1919

20+
config MMC_BROKEN_CD
21+
bool "Poll for broken card detection case"
22+
help
23+
If card detection feature is broken, just poll to detect.
24+
2025
config DM_MMC
2126
bool "Enable MMC controllers using Driver Model"
2227
depends on DM

drivers/mmc/fsl_esdhc.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,14 +528,19 @@ static int esdhc_send_cmd_common(struct fsl_esdhc_priv *priv, struct mmc *mmc,
528528

529529
static void set_sysctl(struct fsl_esdhc_priv *priv, struct mmc *mmc, uint clock)
530530
{
531+
struct fsl_esdhc *regs = priv->esdhc_regs;
531532
int div = 1;
532533
#ifdef ARCH_MXC
534+
#ifdef CONFIG_MX53
535+
/* For i.MX53 eSDHCv3, SYSCTL.SDCLKFS may not be set to 0. */
536+
int pre_div = (regs == (struct fsl_esdhc *)MMC_SDHC3_BASE_ADDR) ? 2 : 1;
537+
#else
533538
int pre_div = 1;
539+
#endif
534540
#else
535541
int pre_div = 2;
536542
#endif
537543
int ddr_pre_div = mmc->ddr_mode ? 2 : 1;
538-
struct fsl_esdhc *regs = priv->esdhc_regs;
539544
int sdhc_clk = priv->sdhc_clk;
540545
uint clk;
541546

drivers/mmc/mmc-uclass.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,13 +140,12 @@ int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg)
140140
cfg->host_caps |= MMC_MODE_1BIT;
141141
break;
142142
default:
143-
debug("warning: %s invalid bus-width property. using 1-bit\n",
144-
dev_read_name(dev));
145-
cfg->host_caps |= MMC_MODE_1BIT;
146-
break;
143+
dev_err(dev, "Invalid \"bus-width\" value %u!\n", val);
144+
return -EINVAL;
147145
}
148146

149-
cfg->f_max = dev_read_u32_default(dev, "max-frequency", 52000000);
147+
/* f_max is obtained from the optional "max-frequency" property */
148+
dev_read_u32(dev, "max-frequency", &cfg->f_max);
150149

151150
if (dev_read_bool(dev, "cap-sd-highspeed"))
152151
cfg->host_caps |= MMC_CAP(SD_HS);

drivers/mmc/mmc.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,11 +1501,13 @@ static int mmc_set_ios(struct mmc *mmc)
15011501

15021502
int mmc_set_clock(struct mmc *mmc, uint clock, bool disable)
15031503
{
1504-
if (clock > mmc->cfg->f_max)
1505-
clock = mmc->cfg->f_max;
1504+
if (!disable) {
1505+
if (clock > mmc->cfg->f_max)
1506+
clock = mmc->cfg->f_max;
15061507

1507-
if (clock < mmc->cfg->f_min)
1508-
clock = mmc->cfg->f_min;
1508+
if (clock < mmc->cfg->f_min)
1509+
clock = mmc->cfg->f_min;
1510+
}
15091511

15101512
mmc->clock = clock;
15111513
mmc->clk_disable = disable;
@@ -2449,7 +2451,7 @@ static int mmc_power_on(struct mmc *mmc)
24492451

24502452
static int mmc_power_off(struct mmc *mmc)
24512453
{
2452-
mmc_set_clock(mmc, 1, true);
2454+
mmc_set_clock(mmc, 0, true);
24532455
#if CONFIG_IS_ENABLED(DM_MMC) && CONFIG_IS_ENABLED(DM_REGULATOR)
24542456
if (mmc->vmmc_supply) {
24552457
int ret = regulator_set_enable(mmc->vmmc_supply, false);
@@ -2491,8 +2493,12 @@ int mmc_start_init(struct mmc *mmc)
24912493
mmc->host_caps = mmc->cfg->host_caps | MMC_CAP(SD_LEGACY) |
24922494
MMC_CAP(MMC_LEGACY) | MMC_MODE_1BIT;
24932495

2496+
#if !defined(CONFIG_MMC_BROKEN_CD)
24942497
/* we pretend there's no card when init is NULL */
24952498
no_card = mmc_getcd(mmc) == 0;
2499+
#else
2500+
no_card = 0;
2501+
#endif
24962502
#if !CONFIG_IS_ENABLED(DM_MMC)
24972503
no_card = no_card || (mmc->cfg->ops->init == NULL);
24982504
#endif

drivers/mmc/sdhci-cadence.c

Lines changed: 95 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <common.h>
99
#include <dm.h>
10+
#include <linux/bitfield.h>
1011
#include <linux/io.h>
1112
#include <linux/iopoll.h>
1213
#include <linux/sizes.h>
@@ -19,15 +20,14 @@
1920
#define SDHCI_CDNS_HRS04_ACK BIT(26)
2021
#define SDHCI_CDNS_HRS04_RD BIT(25)
2122
#define SDHCI_CDNS_HRS04_WR BIT(24)
22-
#define SDHCI_CDNS_HRS04_RDATA_SHIFT 16
23-
#define SDHCI_CDNS_HRS04_WDATA_SHIFT 8
24-
#define SDHCI_CDNS_HRS04_ADDR_SHIFT 0
23+
#define SDHCI_CDNS_HRS04_RDATA GENMASK(23, 16)
24+
#define SDHCI_CDNS_HRS04_WDATA GENMASK(15, 8)
25+
#define SDHCI_CDNS_HRS04_ADDR GENMASK(5, 0)
2526

2627
#define SDHCI_CDNS_HRS06 0x18 /* eMMC control */
2728
#define SDHCI_CDNS_HRS06_TUNE_UP BIT(15)
28-
#define SDHCI_CDNS_HRS06_TUNE_SHIFT 8
29-
#define SDHCI_CDNS_HRS06_TUNE_MASK 0x3f
30-
#define SDHCI_CDNS_HRS06_MODE_MASK 0x7
29+
#define SDHCI_CDNS_HRS06_TUNE GENMASK(13, 8)
30+
#define SDHCI_CDNS_HRS06_MODE GENMASK(2, 0)
3131
#define SDHCI_CDNS_HRS06_MODE_SD 0x0
3232
#define SDHCI_CDNS_HRS06_MODE_MMC_SDR 0x2
3333
#define SDHCI_CDNS_HRS06_MODE_MMC_DDR 0x3
@@ -52,6 +52,13 @@
5252
#define SDHCI_CDNS_PHY_DLY_HSMMC 0x0c
5353
#define SDHCI_CDNS_PHY_DLY_STROBE 0x0d
5454

55+
/*
56+
* The tuned val register is 6 bit-wide, but not the whole of the range is
57+
* available. The range 0-42 seems to be available (then 43 wraps around to 0)
58+
* but I am not quite sure if it is official. Use only 0 to 39 for safety.
59+
*/
60+
#define SDHCI_CDNS_MAX_TUNING_LOOP 40
61+
5562
struct sdhci_cdns_plat {
5663
struct mmc_config cfg;
5764
struct mmc mmc;
@@ -84,8 +91,8 @@ static int sdhci_cdns_write_phy_reg(struct sdhci_cdns_plat *plat,
8491
u32 tmp;
8592
int ret;
8693

87-
tmp = (data << SDHCI_CDNS_HRS04_WDATA_SHIFT) |
88-
(addr << SDHCI_CDNS_HRS04_ADDR_SHIFT);
94+
tmp = FIELD_PREP(SDHCI_CDNS_HRS04_WDATA, data) |
95+
FIELD_PREP(SDHCI_CDNS_HRS04_ADDR, addr);
8996
writel(tmp, reg);
9097

9198
tmp |= SDHCI_CDNS_HRS04_WR;
@@ -135,32 +142,93 @@ static void sdhci_cdns_set_control_reg(struct sdhci_host *host)
135142
* The mode should be decided by MMC_TIMING_* like Linux, but
136143
* U-Boot does not support timing. Use the clock frequency instead.
137144
*/
138-
if (clock <= 26000000)
145+
if (clock <= 26000000) {
139146
mode = SDHCI_CDNS_HRS06_MODE_SD; /* use this for Legacy */
140-
else if (clock <= 52000000) {
147+
} else if (clock <= 52000000) {
141148
if (mmc->ddr_mode)
142149
mode = SDHCI_CDNS_HRS06_MODE_MMC_DDR;
143150
else
144151
mode = SDHCI_CDNS_HRS06_MODE_MMC_SDR;
145152
} else {
146-
/*
147-
* REVISIT:
148-
* The IP supports HS200/HS400, revisit once U-Boot support it
149-
*/
150-
printf("unsupported frequency %d\n", clock);
151-
return;
153+
if (mmc->ddr_mode)
154+
mode = SDHCI_CDNS_HRS06_MODE_MMC_HS400;
155+
else
156+
mode = SDHCI_CDNS_HRS06_MODE_MMC_HS200;
152157
}
153158

154159
tmp = readl(plat->hrs_addr + SDHCI_CDNS_HRS06);
155-
tmp &= ~SDHCI_CDNS_HRS06_MODE_MASK;
156-
tmp |= mode;
160+
tmp &= ~SDHCI_CDNS_HRS06_MODE;
161+
tmp |= FIELD_PREP(SDHCI_CDNS_HRS06_MODE, mode);
157162
writel(tmp, plat->hrs_addr + SDHCI_CDNS_HRS06);
158163
}
159164

160165
static const struct sdhci_ops sdhci_cdns_ops = {
161166
.set_control_reg = sdhci_cdns_set_control_reg,
162167
};
163168

169+
static int sdhci_cdns_set_tune_val(struct sdhci_cdns_plat *plat,
170+
unsigned int val)
171+
{
172+
void __iomem *reg = plat->hrs_addr + SDHCI_CDNS_HRS06;
173+
u32 tmp;
174+
175+
if (WARN_ON(!FIELD_FIT(SDHCI_CDNS_HRS06_TUNE, val)))
176+
return -EINVAL;
177+
178+
tmp = readl(reg);
179+
tmp &= ~SDHCI_CDNS_HRS06_TUNE;
180+
tmp |= FIELD_PREP(SDHCI_CDNS_HRS06_TUNE, val);
181+
tmp |= SDHCI_CDNS_HRS06_TUNE_UP;
182+
writel(tmp, reg);
183+
184+
return readl_poll_timeout(reg, tmp, !(tmp & SDHCI_CDNS_HRS06_TUNE_UP),
185+
1);
186+
}
187+
188+
static int __maybe_unused sdhci_cdns_execute_tuning(struct udevice *dev,
189+
unsigned int opcode)
190+
{
191+
struct sdhci_cdns_plat *plat = dev_get_platdata(dev);
192+
struct mmc *mmc = &plat->mmc;
193+
int cur_streak = 0;
194+
int max_streak = 0;
195+
int end_of_streak = 0;
196+
int i;
197+
198+
/*
199+
* This handler only implements the eMMC tuning that is specific to
200+
* this controller. The tuning for SD timing should be handled by the
201+
* SDHCI core.
202+
*/
203+
if (!IS_MMC(mmc))
204+
return -ENOTSUPP;
205+
206+
if (WARN_ON(opcode != MMC_CMD_SEND_TUNING_BLOCK_HS200))
207+
return -EINVAL;
208+
209+
for (i = 0; i < SDHCI_CDNS_MAX_TUNING_LOOP; i++) {
210+
if (sdhci_cdns_set_tune_val(plat, i) ||
211+
mmc_send_tuning(mmc, opcode, NULL)) { /* bad */
212+
cur_streak = 0;
213+
} else { /* good */
214+
cur_streak++;
215+
if (cur_streak > max_streak) {
216+
max_streak = cur_streak;
217+
end_of_streak = i;
218+
}
219+
}
220+
}
221+
222+
if (!max_streak) {
223+
dev_err(dev, "no tuning point found\n");
224+
return -EIO;
225+
}
226+
227+
return sdhci_cdns_set_tune_val(plat, end_of_streak - max_streak / 2);
228+
}
229+
230+
static struct dm_mmc_ops sdhci_cdns_mmc_ops;
231+
164232
static int sdhci_cdns_bind(struct udevice *dev)
165233
{
166234
struct sdhci_cdns_plat *plat = dev_get_platdata(dev);
@@ -189,6 +257,14 @@ static int sdhci_cdns_probe(struct udevice *dev)
189257
host->ioaddr = plat->hrs_addr + SDHCI_CDNS_SRS_BASE;
190258
host->ops = &sdhci_cdns_ops;
191259
host->quirks |= SDHCI_QUIRK_WAIT_SEND_CMD;
260+
sdhci_cdns_mmc_ops = sdhci_ops;
261+
#ifdef MMC_SUPPORTS_TUNING
262+
sdhci_cdns_mmc_ops.execute_tuning = sdhci_cdns_execute_tuning;
263+
#endif
264+
265+
ret = mmc_of_parse(dev, &plat->cfg);
266+
if (ret)
267+
return ret;
192268

193269
ret = sdhci_cdns_phy_init(plat, gd->fdt_blob, dev_of_offset(dev));
194270
if (ret)
@@ -219,5 +295,5 @@ U_BOOT_DRIVER(sdhci_cdns) = {
219295
.probe = sdhci_cdns_probe,
220296
.priv_auto_alloc_size = sizeof(struct sdhci_host),
221297
.platdata_auto_alloc_size = sizeof(struct sdhci_cdns_plat),
222-
.ops = &sdhci_ops,
298+
.ops = &sdhci_cdns_mmc_ops,
223299
};

drivers/mmc/sdhci.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data,
8686
do {
8787
stat = sdhci_readl(host, SDHCI_INT_STATUS);
8888
if (stat & SDHCI_INT_ERROR) {
89-
printf("%s: Error detected in status(0x%X)!\n",
90-
__func__, stat);
89+
pr_debug("%s: Error detected in status(0x%X)!\n",
90+
__func__, stat);
9191
return -EIO;
9292
}
9393
if (!transfer_done && (stat & rdy)) {
@@ -594,7 +594,7 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
594594
if (host->quirks & SDHCI_QUIRK_BROKEN_VOLTAGE)
595595
cfg->voltages |= host->voltages;
596596

597-
cfg->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT;
597+
cfg->host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT;
598598

599599
/* Since Host Controller Version3.0 */
600600
if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {

drivers/power/pmic/s2mps11.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@
1515

1616
DECLARE_GLOBAL_DATA_PTR;
1717

18+
static const struct pmic_child_info pmic_children_info[] = {
19+
{ .prefix = S2MPS11_OF_LDO_PREFIX, .driver = S2MPS11_LDO_DRIVER },
20+
{ .prefix = S2MPS11_OF_BUCK_PREFIX, .driver = S2MPS11_BUCK_DRIVER },
21+
{ },
22+
};
23+
1824
static int s2mps11_reg_count(struct udevice *dev)
1925
{
2026
return S2MPS11_REG_COUNT;
@@ -43,6 +49,27 @@ static int s2mps11_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
4349
return ret;
4450
}
4551

52+
static int s2mps11_probe(struct udevice *dev)
53+
{
54+
ofnode regulators_node;
55+
int children;
56+
57+
regulators_node = dev_read_subnode(dev, "voltage-regulators");
58+
if (!ofnode_valid(regulators_node)) {
59+
debug("%s: %s regulators subnode not found!", __func__,
60+
dev->name);
61+
return -ENXIO;
62+
}
63+
64+
debug("%s: '%s' - found regulators subnode\n", __func__, dev->name);
65+
66+
children = pmic_bind_children(dev, regulators_node, pmic_children_info);
67+
if (!children)
68+
debug("%s: %s - no child found\n", __func__, dev->name);
69+
70+
return 0;
71+
}
72+
4673
static struct dm_pmic_ops s2mps11_ops = {
4774
.reg_count = s2mps11_reg_count,
4875
.read = s2mps11_read,
@@ -59,4 +86,5 @@ U_BOOT_DRIVER(pmic_s2mps11) = {
5986
.id = UCLASS_PMIC,
6087
.of_match = s2mps11_ids,
6188
.ops = &s2mps11_ops,
89+
.probe = s2mps11_probe,
6290
};

drivers/power/regulator/Kconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,14 @@ config REGULATOR_RK8XX
101101
by the PMIC device. This driver is controlled by a device tree node
102102
which includes voltage limits.
103103

104+
config DM_REGULATOR_S2MPS11
105+
bool "Enable driver for S2MPS11 regulator"
106+
depends on DM_REGULATOR && PMIC_S2MPS11
107+
---help---
108+
This enables implementation of driver-model regulator uclass
109+
features for REGULATOR S2MPS11.
110+
The driver implements get/set api for: value and enable.
111+
104112
config REGULATOR_S5M8767
105113
bool "Enable support for S5M8767 regulator"
106114
depends on DM_REGULATOR && PMIC_S5M8767

0 commit comments

Comments
 (0)