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