diff --git a/arch/arm/boot/dts/broadcom/bcm2712-rpi-5-b.dts b/arch/arm/boot/dts/broadcom/bcm2712-rpi-5-b.dts index 1a4a0e55ea369c..b5fcab16a20263 100644 --- a/arch/arm/boot/dts/broadcom/bcm2712-rpi-5-b.dts +++ b/arch/arm/boot/dts/broadcom/bcm2712-rpi-5-b.dts @@ -359,7 +359,7 @@ dpi_16bit_gpio2: &rp1_dpi_16bit_gpio2 { }; sd-uhs-sdr50; sd-uhs-ddr50; sd-uhs-sdr104; - //broken-cd; + cd-gpios = <&gio_aon 5 GPIO_ACTIVE_LOW>; //no-1-8-v; status = "okay"; }; @@ -396,7 +396,7 @@ dpi_16bit_gpio2: &rp1_dpi_16bit_gpio2 { }; }; emmc_sd_pulls: emmc_sd_pulls { - function = "emmc_dat0", "emmc_dat1", "emmc_dat2", "emmc_dat3"; + pins = "emmc_cmd", "emmc_dat0", "emmc_dat1", "emmc_dat2", "emmc_dat3"; bias-pull-up; }; }; diff --git a/drivers/mmc/host/sdhci-brcmstb.c b/drivers/mmc/host/sdhci-brcmstb.c index aae8c91b867b84..f619c5e67c8822 100644 --- a/drivers/mmc/host/sdhci-brcmstb.c +++ b/drivers/mmc/host/sdhci-brcmstb.c @@ -38,7 +38,8 @@ #define SDIO_CFG_SD_PIN_SEL 0x44 #define SDIO_CFG_SD_PIN_SEL_MASK 0x3 -#define SDIO_CFG_SD_PIN_SEL_CARD BIT(1) +#define SDIO_CFG_SD_PIN_SEL_SD BIT(1) +#define SDIO_CFG_SD_PIN_SEL_MMC BIT(0) #define SDIO_CFG_MAX_50MHZ_MODE 0x1ac #define SDIO_CFG_MAX_50MHZ_MODE_STRAP_OVERRIDE BIT(31) @@ -102,6 +103,42 @@ static void sdhci_brcmstb_hs400es(struct mmc_host *mmc, struct mmc_ios *ios) writel(reg, host->ioaddr + SDHCI_VENDOR); } +static void sdhci_bcm2712_set_clock(struct sdhci_host *host, unsigned int clock) +{ + u16 clk; + u32 reg; + bool is_emmc_rate = false; + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_brcmstb_priv *brcmstb_priv = sdhci_pltfm_priv(pltfm_host); + + host->mmc->actual_clock = 0; + + sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); + + switch (host->mmc->ios.timing) { + case MMC_TIMING_MMC_HS400: + case MMC_TIMING_MMC_HS200: + case MMC_TIMING_MMC_DDR52: + case MMC_TIMING_MMC_HS: + is_emmc_rate = true; + break; + } + + reg = readl(brcmstb_priv->cfg_regs + SDIO_CFG_SD_PIN_SEL); + reg &= ~SDIO_CFG_SD_PIN_SEL_MASK; + if (is_emmc_rate) + reg |= SDIO_CFG_SD_PIN_SEL_MMC; + else + reg |= SDIO_CFG_SD_PIN_SEL_SD; + writel(reg, brcmstb_priv->cfg_regs + SDIO_CFG_SD_PIN_SEL); + + if (clock == 0) + return; + + clk = sdhci_calc_clk(host, clock, &host->mmc->actual_clock); + sdhci_enable_clk(host, clk); +} + static void sdhci_brcmstb_set_clock(struct sdhci_host *host, unsigned int clock) { u16 clk; @@ -161,22 +198,16 @@ static void sdhci_brcmstb_cfginit_2712(struct sdhci_host *host) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_brcmstb_priv *brcmstb_priv = sdhci_pltfm_priv(pltfm_host); - bool want_dll = false; u32 uhs_mask = (MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104); u32 hsemmc_mask = (MMC_CAP2_HS200_1_8V_SDR | MMC_CAP2_HS200_1_2V_SDR | MMC_CAP2_HS400_1_8V | MMC_CAP2_HS400_1_2V); u32 reg; - if (!(host->quirks2 & SDHCI_QUIRK2_NO_1_8_V)) { - if((host->mmc->caps & uhs_mask) || (host->mmc->caps2 & hsemmc_mask)) - want_dll = true; - } - /* - * If we want a speed that requires tuning, - * then select the delay line PHY as the clock source. - */ - if (want_dll) { + * If we support a speed that requires tuning, + * then select the delay line PHY as the clock source. + */ + if ((host->mmc->caps & uhs_mask) || (host->mmc->caps2 & hsemmc_mask)) { reg = readl(brcmstb_priv->cfg_regs + SDIO_CFG_MAX_50MHZ_MODE); reg &= ~SDIO_CFG_MAX_50MHZ_MODE_ENABLE; reg |= SDIO_CFG_MAX_50MHZ_MODE_STRAP_OVERRIDE; @@ -190,12 +221,6 @@ static void sdhci_brcmstb_cfginit_2712(struct sdhci_host *host) reg &= ~SDIO_CFG_CTRL_SDCD_N_TEST_LEV; reg |= SDIO_CFG_CTRL_SDCD_N_TEST_EN; writel(reg, brcmstb_priv->cfg_regs + SDIO_CFG_CTRL); - } else { - /* Enable card detection line */ - reg = readl(brcmstb_priv->cfg_regs + SDIO_CFG_SD_PIN_SEL); - reg &= ~SDIO_CFG_SD_PIN_SEL_MASK; - reg |= SDIO_CFG_SD_PIN_SEL_CARD; - writel(reg, brcmstb_priv->cfg_regs + SDIO_CFG_SD_PIN_SEL); } } @@ -330,7 +355,7 @@ static struct sdhci_ops sdhci_brcmstb_ops = { }; static struct sdhci_ops sdhci_brcmstb_ops_2712 = { - .set_clock = sdhci_set_clock, + .set_clock = sdhci_bcm2712_set_clock, .set_power = sdhci_brcmstb_set_power, .set_bus_width = sdhci_set_bus_width, .reset = sdhci_reset, diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2712.c b/drivers/pinctrl/bcm/pinctrl-bcm2712.c index b39cc52b0aede8..80a6aea8d6c96b 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2712.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2712.c @@ -416,6 +416,17 @@ static const struct pin_regs bcm2712_d0_gpio_pin_regs[] = { GPIO_REGS(33, 3, 1, 6, 0), GPIO_REGS(34, 3, 2, 6, 1), GPIO_REGS(35, 3, 3, 6, 2), + EMMC_REGS(36, 6, 3), /* EMMC_CMD */ + EMMC_REGS(37, 6, 4), /* EMMC_DS */ + EMMC_REGS(38, 6, 5), /* EMMC_CLK */ + EMMC_REGS(39, 6, 6), /* EMMC_DAT0 */ + EMMC_REGS(40, 6, 7), /* EMMC_DAT1 */ + EMMC_REGS(41, 6, 8), /* EMMC_DAT2 */ + EMMC_REGS(42, 6, 9), /* EMMC_DAT3 */ + EMMC_REGS(43, 6, 10), /* EMMC_DAT4 */ + EMMC_REGS(44, 6, 11), /* EMMC_DAT5 */ + EMMC_REGS(45, 6, 12), /* EMMC_DAT6 */ + EMMC_REGS(46, 6, 13), /* EMMC_DAT7 */ }; static struct pin_regs bcm2712_d0_aon_gpio_pin_regs[] = { @@ -468,6 +479,17 @@ static const struct pinctrl_pin_desc bcm2712_d0_gpio_pins[] = { GPIO_PIN(33), GPIO_PIN(34), GPIO_PIN(35), + PINCTRL_PIN(36, "emmc_cmd"), + PINCTRL_PIN(37, "emmc_ds"), + PINCTRL_PIN(38, "emmc_clk"), + PINCTRL_PIN(39, "emmc_dat0"), + PINCTRL_PIN(40, "emmc_dat1"), + PINCTRL_PIN(41, "emmc_dat2"), + PINCTRL_PIN(42, "emmc_dat3"), + PINCTRL_PIN(43, "emmc_dat4"), + PINCTRL_PIN(44, "emmc_dat5"), + PINCTRL_PIN(45, "emmc_dat6"), + PINCTRL_PIN(46, "emmc_dat7"), }; static struct pinctrl_pin_desc bcm2712_d0_aon_gpio_pins[] = {