Skip to content

Commit a41368e

Browse files
P33Mpopcornmix
authored andcommitted
drivers: mmc: sdhci-brcmstb: fix usage of SD_PIN_SEL on BCM2712
The SDIO_CFG register SD_PIN_SEL conflates two settings - whether eMMC HS or SD UHS timings are applied to the interface, and whether or not the card-detect line is functional. SD_PIN_SEL can only be changed when the SD clock isn't running, so add a bcm2712-specific clock setup. Toggling SD_PIN_SEL at runtime means the integrated card-detect feature can't be used, so this controller needs a cd-gpios property. Also fix conditionals for usage of the delay-line PHY - no-1-8-v will imply no bits set in hsemmc_mask or uhs_mask, so remove it. Signed-off-by: Jonathan Bell <[email protected]>
1 parent d5d0f98 commit a41368e

File tree

1 file changed

+43
-18
lines changed

1 file changed

+43
-18
lines changed

drivers/mmc/host/sdhci-brcmstb.c

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040

4141
#define SDIO_CFG_SD_PIN_SEL 0x44
4242
#define SDIO_CFG_SD_PIN_SEL_MASK 0x3
43-
#define SDIO_CFG_SD_PIN_SEL_CARD BIT(1)
43+
#define SDIO_CFG_SD_PIN_SEL_SD BIT(1)
44+
#define SDIO_CFG_SD_PIN_SEL_MMC BIT(0)
4445

4546
#define SDIO_CFG_MAX_50MHZ_MODE 0x1ac
4647
#define SDIO_CFG_MAX_50MHZ_MODE_STRAP_OVERRIDE BIT(31)
@@ -148,6 +149,42 @@ static void sdhci_brcmstb_hs400es(struct mmc_host *mmc, struct mmc_ios *ios)
148149
writel(reg, host->ioaddr + SDHCI_VENDOR);
149150
}
150151

152+
static void sdhci_bcm2712_set_clock(struct sdhci_host *host, unsigned int clock)
153+
{
154+
u16 clk;
155+
u32 reg;
156+
bool is_emmc_rate = false;
157+
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
158+
struct sdhci_brcmstb_priv *brcmstb_priv = sdhci_pltfm_priv(pltfm_host);
159+
160+
host->mmc->actual_clock = 0;
161+
162+
sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
163+
164+
switch (host->mmc->ios.timing) {
165+
case MMC_TIMING_MMC_HS400:
166+
case MMC_TIMING_MMC_HS200:
167+
case MMC_TIMING_MMC_DDR52:
168+
case MMC_TIMING_MMC_HS:
169+
is_emmc_rate = true;
170+
break;
171+
}
172+
173+
reg = readl(brcmstb_priv->cfg_regs + SDIO_CFG_SD_PIN_SEL);
174+
reg &= ~SDIO_CFG_SD_PIN_SEL_MASK;
175+
if (is_emmc_rate)
176+
reg |= SDIO_CFG_SD_PIN_SEL_MMC;
177+
else
178+
reg |= SDIO_CFG_SD_PIN_SEL_SD;
179+
writel(reg, brcmstb_priv->cfg_regs + SDIO_CFG_SD_PIN_SEL);
180+
181+
if (clock == 0)
182+
return;
183+
184+
clk = sdhci_calc_clk(host, clock, &host->mmc->actual_clock);
185+
sdhci_enable_clk(host, clk);
186+
}
187+
151188
static void sdhci_brcmstb_set_clock(struct sdhci_host *host, unsigned int clock)
152189
{
153190
u16 clk;
@@ -207,22 +244,16 @@ static void sdhci_brcmstb_cfginit_2712(struct sdhci_host *host)
207244
{
208245
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
209246
struct sdhci_brcmstb_priv *brcmstb_priv = sdhci_pltfm_priv(pltfm_host);
210-
bool want_dll = false;
211247
u32 uhs_mask = (MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104);
212248
u32 hsemmc_mask = (MMC_CAP2_HS200_1_8V_SDR | MMC_CAP2_HS200_1_2V_SDR |
213249
MMC_CAP2_HS400_1_8V | MMC_CAP2_HS400_1_2V);
214250
u32 reg;
215251

216-
if (!(host->quirks2 & SDHCI_QUIRK2_NO_1_8_V)) {
217-
if((host->mmc->caps & uhs_mask) || (host->mmc->caps2 & hsemmc_mask))
218-
want_dll = true;
219-
}
220-
221252
/*
222-
* If we want a speed that requires tuning,
223-
* then select the delay line PHY as the clock source.
224-
*/
225-
if (want_dll) {
253+
* If we support a speed that requires tuning,
254+
* then select the delay line PHY as the clock source.
255+
*/
256+
if ((host->mmc->caps & uhs_mask) || (host->mmc->caps2 & hsemmc_mask)) {
226257
reg = readl(brcmstb_priv->cfg_regs + SDIO_CFG_MAX_50MHZ_MODE);
227258
reg &= ~SDIO_CFG_MAX_50MHZ_MODE_ENABLE;
228259
reg |= SDIO_CFG_MAX_50MHZ_MODE_STRAP_OVERRIDE;
@@ -236,12 +267,6 @@ static void sdhci_brcmstb_cfginit_2712(struct sdhci_host *host)
236267
reg &= ~SDIO_CFG_CTRL_SDCD_N_TEST_LEV;
237268
reg |= SDIO_CFG_CTRL_SDCD_N_TEST_EN;
238269
writel(reg, brcmstb_priv->cfg_regs + SDIO_CFG_CTRL);
239-
} else {
240-
/* Enable card detection line */
241-
reg = readl(brcmstb_priv->cfg_regs + SDIO_CFG_SD_PIN_SEL);
242-
reg &= ~SDIO_CFG_SD_PIN_SEL_MASK;
243-
reg |= SDIO_CFG_SD_PIN_SEL_CARD;
244-
writel(reg, brcmstb_priv->cfg_regs + SDIO_CFG_SD_PIN_SEL);
245270
}
246271
}
247272

@@ -376,7 +401,7 @@ static struct sdhci_ops sdhci_brcmstb_ops = {
376401
};
377402

378403
static struct sdhci_ops sdhci_brcmstb_ops_2712 = {
379-
.set_clock = sdhci_set_clock,
404+
.set_clock = sdhci_bcm2712_set_clock,
380405
.set_power = sdhci_brcmstb_set_power,
381406
.set_bus_width = sdhci_set_bus_width,
382407
.reset = sdhci_reset,

0 commit comments

Comments
 (0)