1ccb6e6a1ffa4cb689c5bc2152d92daa90cdeb1a
[openwrt/staging/ansuel.git] /
1 From c6187bb277ed61836b3dd6da913d2a6d107f93e4 Mon Sep 17 00:00:00 2001
2 From: Jonathan Bell <jonathan@raspberrypi.com>
3 Date: Fri, 9 Feb 2024 13:47:23 +0000
4 Subject: [PATCH 0891/1085] drivers: mmc: sdhci-brcmstb: fix usage of
5 SD_PIN_SEL on BCM2712
6
7 The SDIO_CFG register SD_PIN_SEL conflates two settings - whether eMMC
8 HS or SD UHS timings are applied to the interface, and whether or not
9 the card-detect line is functional. SD_PIN_SEL can only be changed when
10 the SD clock isn't running, so add a bcm2712-specific clock setup.
11
12 Toggling SD_PIN_SEL at runtime means the integrated card-detect feature
13 can't be used, so this controller needs a cd-gpios property.
14
15 Also fix conditionals for usage of the delay-line PHY - no-1-8-v will
16 imply no bits set in hsemmc_mask or uhs_mask, so remove it.
17
18 Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
19 ---
20 drivers/mmc/host/sdhci-brcmstb.c | 61 ++++++++++++++++++++++----------
21 1 file changed, 43 insertions(+), 18 deletions(-)
22
23 --- a/drivers/mmc/host/sdhci-brcmstb.c
24 +++ b/drivers/mmc/host/sdhci-brcmstb.c
25 @@ -38,7 +38,8 @@
26
27 #define SDIO_CFG_SD_PIN_SEL 0x44
28 #define SDIO_CFG_SD_PIN_SEL_MASK 0x3
29 -#define SDIO_CFG_SD_PIN_SEL_CARD BIT(1)
30 +#define SDIO_CFG_SD_PIN_SEL_SD BIT(1)
31 +#define SDIO_CFG_SD_PIN_SEL_MMC BIT(0)
32
33 #define SDIO_CFG_MAX_50MHZ_MODE 0x1ac
34 #define SDIO_CFG_MAX_50MHZ_MODE_STRAP_OVERRIDE BIT(31)
35 @@ -102,6 +103,42 @@ static void sdhci_brcmstb_hs400es(struct
36 writel(reg, host->ioaddr + SDHCI_VENDOR);
37 }
38
39 +static void sdhci_bcm2712_set_clock(struct sdhci_host *host, unsigned int clock)
40 +{
41 + u16 clk;
42 + u32 reg;
43 + bool is_emmc_rate = false;
44 + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
45 + struct sdhci_brcmstb_priv *brcmstb_priv = sdhci_pltfm_priv(pltfm_host);
46 +
47 + host->mmc->actual_clock = 0;
48 +
49 + sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
50 +
51 + switch (host->mmc->ios.timing) {
52 + case MMC_TIMING_MMC_HS400:
53 + case MMC_TIMING_MMC_HS200:
54 + case MMC_TIMING_MMC_DDR52:
55 + case MMC_TIMING_MMC_HS:
56 + is_emmc_rate = true;
57 + break;
58 + }
59 +
60 + reg = readl(brcmstb_priv->cfg_regs + SDIO_CFG_SD_PIN_SEL);
61 + reg &= ~SDIO_CFG_SD_PIN_SEL_MASK;
62 + if (is_emmc_rate)
63 + reg |= SDIO_CFG_SD_PIN_SEL_MMC;
64 + else
65 + reg |= SDIO_CFG_SD_PIN_SEL_SD;
66 + writel(reg, brcmstb_priv->cfg_regs + SDIO_CFG_SD_PIN_SEL);
67 +
68 + if (clock == 0)
69 + return;
70 +
71 + clk = sdhci_calc_clk(host, clock, &host->mmc->actual_clock);
72 + sdhci_enable_clk(host, clk);
73 +}
74 +
75 static void sdhci_brcmstb_set_clock(struct sdhci_host *host, unsigned int clock)
76 {
77 u16 clk;
78 @@ -161,22 +198,16 @@ static void sdhci_brcmstb_cfginit_2712(s
79 {
80 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
81 struct sdhci_brcmstb_priv *brcmstb_priv = sdhci_pltfm_priv(pltfm_host);
82 - bool want_dll = false;
83 u32 uhs_mask = (MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104);
84 u32 hsemmc_mask = (MMC_CAP2_HS200_1_8V_SDR | MMC_CAP2_HS200_1_2V_SDR |
85 MMC_CAP2_HS400_1_8V | MMC_CAP2_HS400_1_2V);
86 u32 reg;
87
88 - if (!(host->quirks2 & SDHCI_QUIRK2_NO_1_8_V)) {
89 - if((host->mmc->caps & uhs_mask) || (host->mmc->caps2 & hsemmc_mask))
90 - want_dll = true;
91 - }
92 -
93 /*
94 - * If we want a speed that requires tuning,
95 - * then select the delay line PHY as the clock source.
96 - */
97 - if (want_dll) {
98 + * If we support a speed that requires tuning,
99 + * then select the delay line PHY as the clock source.
100 + */
101 + if ((host->mmc->caps & uhs_mask) || (host->mmc->caps2 & hsemmc_mask)) {
102 reg = readl(brcmstb_priv->cfg_regs + SDIO_CFG_MAX_50MHZ_MODE);
103 reg &= ~SDIO_CFG_MAX_50MHZ_MODE_ENABLE;
104 reg |= SDIO_CFG_MAX_50MHZ_MODE_STRAP_OVERRIDE;
105 @@ -190,12 +221,6 @@ static void sdhci_brcmstb_cfginit_2712(s
106 reg &= ~SDIO_CFG_CTRL_SDCD_N_TEST_LEV;
107 reg |= SDIO_CFG_CTRL_SDCD_N_TEST_EN;
108 writel(reg, brcmstb_priv->cfg_regs + SDIO_CFG_CTRL);
109 - } else {
110 - /* Enable card detection line */
111 - reg = readl(brcmstb_priv->cfg_regs + SDIO_CFG_SD_PIN_SEL);
112 - reg &= ~SDIO_CFG_SD_PIN_SEL_MASK;
113 - reg |= SDIO_CFG_SD_PIN_SEL_CARD;
114 - writel(reg, brcmstb_priv->cfg_regs + SDIO_CFG_SD_PIN_SEL);
115 }
116 }
117
118 @@ -330,7 +355,7 @@ static struct sdhci_ops sdhci_brcmstb_op
119 };
120
121 static struct sdhci_ops sdhci_brcmstb_ops_2712 = {
122 - .set_clock = sdhci_set_clock,
123 + .set_clock = sdhci_bcm2712_set_clock,
124 .set_power = sdhci_brcmstb_set_power,
125 .set_bus_width = sdhci_set_bus_width,
126 .reset = sdhci_reset,