338 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2// Copyright (C) 2013 Broadcom Corporation3 4#include <linux/kernel.h>5#include <linux/module.h>6#include <linux/delay.h>7#include <linux/highmem.h>8#include <linux/platform_device.h>9#include <linux/mmc/host.h>10#include <linux/io.h>11#include <linux/clk.h>12#include <linux/regulator/consumer.h>13#include <linux/of.h>14#include <linux/mmc/slot-gpio.h>15 16#include "sdhci-pltfm.h"17#include "sdhci.h"18 19#define SDHCI_SOFT_RESET 0x0100000020#define KONA_SDHOST_CORECTRL 0x800021#define KONA_SDHOST_CD_PINCTRL 0x0000000822#define KONA_SDHOST_STOP_HCLK 0x0000000423#define KONA_SDHOST_RESET 0x0000000224#define KONA_SDHOST_EN 0x0000000125 26#define KONA_SDHOST_CORESTAT 0x800427#define KONA_SDHOST_WP 0x0000000228#define KONA_SDHOST_CD_SW 0x0000000129 30#define KONA_SDHOST_COREIMR 0x800831#define KONA_SDHOST_IP 0x0000000132 33#define KONA_SDHOST_COREISR 0x800C34#define KONA_SDHOST_COREIMSR 0x801035#define KONA_SDHOST_COREDBG1 0x801436#define KONA_SDHOST_COREGPO_MASK 0x801837 38#define SD_DETECT_GPIO_DEBOUNCE_128MS 12839 40#define KONA_MMC_AUTOSUSPEND_DELAY (50)41 42struct sdhci_bcm_kona_dev {43 struct mutex write_lock; /* protect back to back writes */44};45 46 47static int sdhci_bcm_kona_sd_reset(struct sdhci_host *host)48{49 unsigned int val;50 unsigned long timeout;51 52 /* This timeout should be sufficent for core to reset */53 timeout = jiffies + msecs_to_jiffies(100);54 55 /* reset the host using the top level reset */56 val = sdhci_readl(host, KONA_SDHOST_CORECTRL);57 val |= KONA_SDHOST_RESET;58 sdhci_writel(host, val, KONA_SDHOST_CORECTRL);59 60 while (!(sdhci_readl(host, KONA_SDHOST_CORECTRL) & KONA_SDHOST_RESET)) {61 if (time_is_before_jiffies(timeout)) {62 pr_err("Error: sd host is stuck in reset!!!\n");63 return -EFAULT;64 }65 }66 67 /* bring the host out of reset */68 val = sdhci_readl(host, KONA_SDHOST_CORECTRL);69 val &= ~KONA_SDHOST_RESET;70 71 /*72 * Back-to-Back register write needs a delay of 1ms at bootup (min 10uS)73 * Back-to-Back writes to same register needs delay when SD bus clock74 * is very low w.r.t AHB clock, mainly during boot-time and during card75 * insert-removal.76 */77 usleep_range(1000, 5000);78 sdhci_writel(host, val, KONA_SDHOST_CORECTRL);79 80 return 0;81}82 83static void sdhci_bcm_kona_sd_init(struct sdhci_host *host)84{85 unsigned int val;86 87 /* enable the interrupt from the IP core */88 val = sdhci_readl(host, KONA_SDHOST_COREIMR);89 val |= KONA_SDHOST_IP;90 sdhci_writel(host, val, KONA_SDHOST_COREIMR);91 92 /* Enable the AHB clock gating module to the host */93 val = sdhci_readl(host, KONA_SDHOST_CORECTRL);94 val |= KONA_SDHOST_EN;95 96 /*97 * Back-to-Back register write needs a delay of 1ms at bootup (min 10uS)98 * Back-to-Back writes to same register needs delay when SD bus clock99 * is very low w.r.t AHB clock, mainly during boot-time and during card100 * insert-removal.101 */102 usleep_range(1000, 5000);103 sdhci_writel(host, val, KONA_SDHOST_CORECTRL);104}105 106/*107 * Software emulation of the SD card insertion/removal. Set insert=1 for insert108 * and insert=0 for removal. The card detection is done by GPIO. For Broadcom109 * IP to function properly the bit 0 of CORESTAT register needs to be set/reset110* to generate the CD IRQ handled in sdhci.c111 */112static int sdhci_bcm_kona_sd_card_emulate(struct sdhci_host *host, int insert)113{114 struct sdhci_pltfm_host *pltfm_priv = sdhci_priv(host);115 struct sdhci_bcm_kona_dev *kona_dev = sdhci_pltfm_priv(pltfm_priv);116 u32 val;117 118 /*119 * Back-to-Back register write needs a delay of min 10uS.120 * Back-to-Back writes to same register needs delay when SD bus clock121 * is very low w.r.t AHB clock, mainly during boot-time and during card122 * insert-removal.123 * We keep 20uS124 */125 mutex_lock(&kona_dev->write_lock);126 udelay(20);127 val = sdhci_readl(host, KONA_SDHOST_CORESTAT);128 129 if (insert) {130 int ret;131 132 ret = mmc_gpio_get_ro(host->mmc);133 if (ret >= 0)134 val = (val & ~KONA_SDHOST_WP) |135 ((ret) ? KONA_SDHOST_WP : 0);136 137 val |= KONA_SDHOST_CD_SW;138 sdhci_writel(host, val, KONA_SDHOST_CORESTAT);139 } else {140 val &= ~KONA_SDHOST_CD_SW;141 sdhci_writel(host, val, KONA_SDHOST_CORESTAT);142 }143 mutex_unlock(&kona_dev->write_lock);144 145 return 0;146}147 148/*149 * SD card interrupt event callback150 */151static void sdhci_bcm_kona_card_event(struct sdhci_host *host)152{153 if (mmc_gpio_get_cd(host->mmc) > 0) {154 dev_dbg(mmc_dev(host->mmc),155 "card inserted\n");156 sdhci_bcm_kona_sd_card_emulate(host, 1);157 } else {158 dev_dbg(mmc_dev(host->mmc),159 "card removed\n");160 sdhci_bcm_kona_sd_card_emulate(host, 0);161 }162}163 164static void sdhci_bcm_kona_init_74_clocks(struct sdhci_host *host,165 u8 power_mode)166{167 /*168 * JEDEC and SD spec specify supplying 74 continuous clocks to169 * device after power up. With minimum bus (100KHz) that170 * translates to 740us171 */172 if (power_mode != MMC_POWER_OFF)173 udelay(740);174}175 176static const struct sdhci_ops sdhci_bcm_kona_ops = {177 .set_clock = sdhci_set_clock,178 .get_max_clock = sdhci_pltfm_clk_get_max_clock,179 .get_timeout_clock = sdhci_pltfm_clk_get_max_clock,180 .platform_send_init_74_clocks = sdhci_bcm_kona_init_74_clocks,181 .set_bus_width = sdhci_set_bus_width,182 .reset = sdhci_reset,183 .set_uhs_signaling = sdhci_set_uhs_signaling,184 .card_event = sdhci_bcm_kona_card_event,185};186 187static const struct sdhci_pltfm_data sdhci_pltfm_data_kona = {188 .ops = &sdhci_bcm_kona_ops,189 .quirks = SDHCI_QUIRK_NO_CARD_NO_RESET |190 SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | SDHCI_QUIRK_32BIT_DMA_ADDR |191 SDHCI_QUIRK_32BIT_DMA_SIZE | SDHCI_QUIRK_32BIT_ADMA_SIZE |192 SDHCI_QUIRK_FORCE_BLK_SZ_2048 |193 SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,194};195 196static const struct of_device_id sdhci_bcm_kona_of_match[] = {197 { .compatible = "brcm,kona-sdhci"},198 { .compatible = "bcm,kona-sdhci"}, /* deprecated name */199 {}200};201MODULE_DEVICE_TABLE(of, sdhci_bcm_kona_of_match);202 203static int sdhci_bcm_kona_probe(struct platform_device *pdev)204{205 struct sdhci_bcm_kona_dev *kona_dev = NULL;206 struct sdhci_pltfm_host *pltfm_priv;207 struct device *dev = &pdev->dev;208 struct sdhci_host *host;209 int ret;210 211 ret = 0;212 213 host = sdhci_pltfm_init(pdev, &sdhci_pltfm_data_kona,214 sizeof(*kona_dev));215 if (IS_ERR(host))216 return PTR_ERR(host);217 218 dev_dbg(dev, "%s: inited. IOADDR=%p\n", __func__, host->ioaddr);219 220 pltfm_priv = sdhci_priv(host);221 222 kona_dev = sdhci_pltfm_priv(pltfm_priv);223 mutex_init(&kona_dev->write_lock);224 225 ret = mmc_of_parse(host->mmc);226 if (ret)227 goto err_pltfm_free;228 229 if (!host->mmc->f_max) {230 dev_err(&pdev->dev, "Missing max-freq for SDHCI cfg\n");231 ret = -ENXIO;232 goto err_pltfm_free;233 }234 235 /* Get and enable the core clock */236 pltfm_priv->clk = devm_clk_get(dev, NULL);237 if (IS_ERR(pltfm_priv->clk)) {238 dev_err(dev, "Failed to get core clock\n");239 ret = PTR_ERR(pltfm_priv->clk);240 goto err_pltfm_free;241 }242 243 ret = clk_set_rate(pltfm_priv->clk, host->mmc->f_max);244 if (ret) {245 dev_err(dev, "Failed to set rate core clock\n");246 goto err_pltfm_free;247 }248 249 ret = clk_prepare_enable(pltfm_priv->clk);250 if (ret) {251 dev_err(dev, "Failed to enable core clock\n");252 goto err_pltfm_free;253 }254 255 dev_dbg(dev, "non-removable=%c\n",256 mmc_card_is_removable(host->mmc) ? 'N' : 'Y');257 dev_dbg(dev, "cd_gpio %c, wp_gpio %c\n",258 (mmc_gpio_get_cd(host->mmc) != -ENOSYS) ? 'Y' : 'N',259 (mmc_gpio_get_ro(host->mmc) != -ENOSYS) ? 'Y' : 'N');260 261 if (!mmc_card_is_removable(host->mmc))262 host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;263 264 dev_dbg(dev, "is_8bit=%c\n",265 (host->mmc->caps & MMC_CAP_8_BIT_DATA) ? 'Y' : 'N');266 267 ret = sdhci_bcm_kona_sd_reset(host);268 if (ret)269 goto err_clk_disable;270 271 sdhci_bcm_kona_sd_init(host);272 273 ret = sdhci_add_host(host);274 if (ret)275 goto err_reset;276 277 /* if device is eMMC, emulate card insert right here */278 if (!mmc_card_is_removable(host->mmc)) {279 ret = sdhci_bcm_kona_sd_card_emulate(host, 1);280 if (ret) {281 dev_err(dev,282 "unable to emulate card insertion\n");283 goto err_remove_host;284 }285 }286 /*287 * Since the card detection GPIO interrupt is configured to be288 * edge sensitive, check the initial GPIO value here, emulate289 * only if the card is present290 */291 if (mmc_gpio_get_cd(host->mmc) > 0)292 sdhci_bcm_kona_sd_card_emulate(host, 1);293 294 dev_dbg(dev, "initialized properly\n");295 return 0;296 297err_remove_host:298 sdhci_remove_host(host, 0);299 300err_reset:301 sdhci_bcm_kona_sd_reset(host);302 303err_clk_disable:304 clk_disable_unprepare(pltfm_priv->clk);305 306err_pltfm_free:307 sdhci_pltfm_free(pdev);308 309 dev_err(dev, "Probing of sdhci-pltfm failed: %d\n", ret);310 return ret;311}312 313static void sdhci_bcm_kona_remove(struct platform_device *pdev)314{315 struct sdhci_host *host = platform_get_drvdata(pdev);316 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);317 struct clk *clk = pltfm_host->clk;318 319 sdhci_pltfm_remove(pdev);320 clk_disable_unprepare(clk);321}322 323static struct platform_driver sdhci_bcm_kona_driver = {324 .driver = {325 .name = "sdhci-kona",326 .probe_type = PROBE_PREFER_ASYNCHRONOUS,327 .pm = &sdhci_pltfm_pmops,328 .of_match_table = sdhci_bcm_kona_of_match,329 },330 .probe = sdhci_bcm_kona_probe,331 .remove_new = sdhci_bcm_kona_remove,332};333module_platform_driver(sdhci_bcm_kona_driver);334 335MODULE_DESCRIPTION("SDHCI driver for Broadcom Kona platform");336MODULE_AUTHOR("Broadcom");337MODULE_LICENSE("GPL v2");338