aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/sdhci-st.c
diff options
context:
space:
mode:
authorPeter Griffin <peter.griffin@linaro.org>2015-04-10 05:40:26 -0400
committerUlf Hansson <ulf.hansson@linaro.org>2015-04-10 06:55:40 -0400
commit2053812f6e1af0b8c3d18d4d6d9f356b0c0d0039 (patch)
treed8154f1bcba0a932edfc271f976d232a88e85be8 /drivers/mmc/host/sdhci-st.c
parentbfa448041fb51311e32f0fd6342619b8c5672175 (diff)
mmc: sdhci-st: Add st_mmcss_cconfig function to configure mmcss glue registers.
STiH407 family SoC's have glue registers in the flashSS subsystem which are used to configure the Arasan HC. This patch configures these glue registers according to what has been specified in the DT. Signed-off-by: Peter Griffin <peter.griffin@linaro.org> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com> Acked-by: Maxime Coquelin <maxime.coquelin@st.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc/host/sdhci-st.c')
-rw-r--r--drivers/mmc/host/sdhci-st.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci-st.c b/drivers/mmc/host/sdhci-st.c
index 1fbea9af7ae4..10989edb5100 100644
--- a/drivers/mmc/host/sdhci-st.c
+++ b/drivers/mmc/host/sdhci-st.c
@@ -138,6 +138,87 @@ static inline void st_mmcss_set_static_delay(void __iomem *ioaddr)
138 ioaddr + ST_TOP_MMC_TX_CLK_DLY); 138 ioaddr + ST_TOP_MMC_TX_CLK_DLY);
139} 139}
140 140
141/**
142 * st_mmcss_cconfig: configure the Arasan HC inside the flashSS.
143 * @np: dt device node.
144 * @host: sdhci host
145 * Description: this function is to configure the Arasan host controller.
146 * On some ST SoCs, i.e. STiH407 family, the MMC devices inside a dedicated
147 * flashSS sub-system which needs to be configured to be compliant to eMMC 4.5
148 * or eMMC4.3. This has to be done before registering the sdhci host.
149 */
150static void st_mmcss_cconfig(struct device_node *np, struct sdhci_host *host)
151{
152 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
153 struct mmc_host *mhost = host->mmc;
154 u32 cconf2, cconf3, cconf4, cconf5;
155
156 if (!of_device_is_compatible(np, "st,sdhci-stih407"))
157 return;
158
159 cconf2 = ST_MMC_CCONFIG_2_DEFAULT;
160 cconf3 = ST_MMC_CCONFIG_3_DEFAULT;
161 cconf4 = ST_MMC_CCONFIG_4_DEFAULT;
162 cconf5 = ST_MMC_CCONFIG_5_DEFAULT;
163
164 writel_relaxed(ST_MMC_CCONFIG_1_DEFAULT,
165 host->ioaddr + ST_MMC_CCONFIG_REG_1);
166
167 /* Set clock frequency, default to 50MHz if max-frequency is not
168 * provided */
169
170 switch (mhost->f_max) {
171 case 200000000:
172 clk_set_rate(pltfm_host->clk, mhost->f_max);
173 cconf2 |= BASE_CLK_FREQ_200;
174 break;
175 case 100000000:
176 clk_set_rate(pltfm_host->clk, mhost->f_max);
177 cconf2 |= BASE_CLK_FREQ_100;
178 break;
179 default:
180 clk_set_rate(pltfm_host->clk, 50000000);
181 cconf2 |= BASE_CLK_FREQ_50;
182 }
183
184 writel_relaxed(cconf2, host->ioaddr + ST_MMC_CCONFIG_REG_2);
185
186 if (mhost->caps & MMC_CAP_NONREMOVABLE)
187 cconf3 |= ST_MMC_CCONFIG_EMMC_SLOT_TYPE;
188 else
189 /* CARD _D ET_CTRL */
190 writel_relaxed(ST_MMC_GP_OUTPUT_CD,
191 host->ioaddr + ST_MMC_GP_OUTPUT);
192
193 if (mhost->caps & MMC_CAP_UHS_SDR50) {
194 /* use 1.8V */
195 cconf3 |= ST_MMC_CCONFIG_1P8_VOLT;
196 cconf4 |= ST_MMC_CCONFIG_SDR50;
197 /* Use tuning */
198 cconf5 |= ST_MMC_CCONFIG_TUNING_FOR_SDR50;
199 /* Max timeout for retuning */
200 cconf5 |= RETUNING_TIMER_CNT_MAX;
201 }
202
203 if (mhost->caps & MMC_CAP_UHS_SDR104) {
204 /*
205 * SDR104 implies the HC can support HS200 mode, so
206 * it's mandatory to use 1.8V
207 */
208 cconf3 |= ST_MMC_CCONFIG_1P8_VOLT;
209 cconf4 |= ST_MMC_CCONFIG_SDR104;
210 /* Max timeout for retuning */
211 cconf5 |= RETUNING_TIMER_CNT_MAX;
212 }
213
214 if (mhost->caps & MMC_CAP_UHS_DDR50)
215 cconf4 |= ST_MMC_CCONFIG_DDR50;
216
217 writel_relaxed(cconf3, host->ioaddr + ST_MMC_CCONFIG_REG_3);
218 writel_relaxed(cconf4, host->ioaddr + ST_MMC_CCONFIG_REG_4);
219 writel_relaxed(cconf5, host->ioaddr + ST_MMC_CCONFIG_REG_5);
220}
221
141static inline void st_mmcss_set_dll(void __iomem *ioaddr) 222static inline void st_mmcss_set_dll(void __iomem *ioaddr)
142{ 223{
143 if (!ioaddr) 224 if (!ioaddr)
@@ -214,6 +295,7 @@ static const struct sdhci_pltfm_data sdhci_st_pdata = {
214 295
215static int sdhci_st_probe(struct platform_device *pdev) 296static int sdhci_st_probe(struct platform_device *pdev)
216{ 297{
298 struct device_node *np = pdev->dev.of_node;
217 struct sdhci_host *host; 299 struct sdhci_host *host;
218 struct st_mmc_platform_data *pdata; 300 struct st_mmc_platform_data *pdata;
219 struct sdhci_pltfm_host *pltfm_host; 301 struct sdhci_pltfm_host *pltfm_host;
@@ -266,6 +348,9 @@ static int sdhci_st_probe(struct platform_device *pdev)
266 pltfm_host->priv = pdata; 348 pltfm_host->priv = pdata;
267 pltfm_host->clk = clk; 349 pltfm_host->clk = clk;
268 350
351 /* Configure the Arasan HC inside the flashSS */
352 st_mmcss_cconfig(np, host);
353
269 ret = sdhci_add_host(host); 354 ret = sdhci_add_host(host);
270 if (ret) { 355 if (ret) {
271 dev_err(&pdev->dev, "Failed sdhci_add_host\n"); 356 dev_err(&pdev->dev, "Failed sdhci_add_host\n");
@@ -333,12 +418,15 @@ static int sdhci_st_resume(struct device *dev)
333 struct sdhci_host *host = dev_get_drvdata(dev); 418 struct sdhci_host *host = dev_get_drvdata(dev);
334 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 419 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
335 struct st_mmc_platform_data *pdata = pltfm_host->priv; 420 struct st_mmc_platform_data *pdata = pltfm_host->priv;
421 struct device_node *np = dev->of_node;
336 422
337 clk_prepare_enable(pltfm_host->clk); 423 clk_prepare_enable(pltfm_host->clk);
338 424
339 if (pdata->rstc) 425 if (pdata->rstc)
340 reset_control_deassert(pdata->rstc); 426 reset_control_deassert(pdata->rstc);
341 427
428 st_mmcss_cconfig(np, host);
429
342 return sdhci_resume_host(host); 430 return sdhci_resume_host(host);
343} 431}
344#endif 432#endif