^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * SDHCI Controller driver for TI's OMAP SoCs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2017 Texas Instruments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author: Kishon Vijay Abraham I <kishon@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/mmc/mmc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/mmc/slot-gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/pinctrl/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/sys_soc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/thermal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "sdhci-pltfm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define SDHCI_OMAP_CON 0x12c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define CON_DW8 BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define CON_DMA_MASTER BIT(20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define CON_DDR BIT(19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define CON_CLKEXTFREE BIT(16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define CON_PADEN BIT(15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define CON_CTPL BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define CON_INIT BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define CON_OD BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define SDHCI_OMAP_DLL 0x0134
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define DLL_SWT BIT(20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define DLL_FORCE_SR_C_SHIFT 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define DLL_FORCE_SR_C_MASK (0x7f << DLL_FORCE_SR_C_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define DLL_FORCE_VALUE BIT(12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define DLL_CALIB BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define SDHCI_OMAP_CMD 0x20c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define SDHCI_OMAP_PSTATE 0x0224
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define PSTATE_DLEV_DAT0 BIT(20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define PSTATE_DATI BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define SDHCI_OMAP_HCTL 0x228
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define HCTL_SDBP BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define HCTL_SDVS_SHIFT 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define HCTL_SDVS_MASK (0x7 << HCTL_SDVS_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define HCTL_SDVS_33 (0x7 << HCTL_SDVS_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define HCTL_SDVS_30 (0x6 << HCTL_SDVS_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define HCTL_SDVS_18 (0x5 << HCTL_SDVS_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define SDHCI_OMAP_SYSCTL 0x22c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define SYSCTL_CEN BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define SYSCTL_CLKD_SHIFT 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define SYSCTL_CLKD_MASK 0x3ff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define SDHCI_OMAP_STAT 0x230
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define SDHCI_OMAP_IE 0x234
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define INT_CC_EN BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define SDHCI_OMAP_ISE 0x238
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define SDHCI_OMAP_AC12 0x23c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define AC12_V1V8_SIGEN BIT(19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define AC12_SCLK_SEL BIT(23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define SDHCI_OMAP_CAPA 0x240
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define CAPA_VS33 BIT(24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define CAPA_VS30 BIT(25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define CAPA_VS18 BIT(26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define SDHCI_OMAP_CAPA2 0x0244
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define CAPA2_TSDR50 BIT(13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define SDHCI_OMAP_TIMEOUT 1 /* 1 msec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define SYSCTL_CLKD_MAX 0x3FF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define IOV_1V8 1800000 /* 180000 uV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define IOV_3V0 3000000 /* 300000 uV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define IOV_3V3 3300000 /* 330000 uV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define MAX_PHASE_DELAY 0x7C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /* sdhci-omap controller flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define SDHCI_OMAP_REQUIRE_IODELAY BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define SDHCI_OMAP_SPECIAL_RESET BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct sdhci_omap_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) u32 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) u8 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct sdhci_omap_host {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) char *version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct regulator *pbias;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) bool pbias_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct sdhci_host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) u8 bus_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) u8 power_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) u8 timing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) u8 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct pinctrl *pinctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct pinctrl_state **pinctrl_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) bool is_tuning;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /* Omap specific context save */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) u32 con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) u32 hctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) u32 sysctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) u32 capa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) u32 ie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) u32 ise;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static void sdhci_omap_start_clock(struct sdhci_omap_host *omap_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static void sdhci_omap_stop_clock(struct sdhci_omap_host *omap_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static inline u32 sdhci_omap_readl(struct sdhci_omap_host *host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return readl(host->base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static inline void sdhci_omap_writel(struct sdhci_omap_host *host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) unsigned int offset, u32 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) writel(data, host->base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static int sdhci_omap_set_pbias(struct sdhci_omap_host *omap_host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) bool power_on, unsigned int iov)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct device *dev = omap_host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (IS_ERR(omap_host->pbias))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (power_on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) ret = regulator_set_voltage(omap_host->pbias, iov, iov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) dev_err(dev, "pbias set voltage failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (omap_host->pbias_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) ret = regulator_enable(omap_host->pbias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) dev_err(dev, "pbias reg enable fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) omap_host->pbias_enabled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (!omap_host->pbias_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) ret = regulator_disable(omap_host->pbias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) dev_err(dev, "pbias reg disable fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) omap_host->pbias_enabled = false;
^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) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static int sdhci_omap_enable_iov(struct sdhci_omap_host *omap_host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) unsigned int iov)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct sdhci_host *host = omap_host->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct mmc_host *mmc = host->mmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) ret = sdhci_omap_set_pbias(omap_host, false, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (!IS_ERR(mmc->supply.vqmmc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) ret = regulator_set_voltage(mmc->supply.vqmmc, iov, iov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) dev_err(mmc_dev(mmc), "vqmmc set voltage failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) ret = sdhci_omap_set_pbias(omap_host, true, iov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static void sdhci_omap_conf_bus_power(struct sdhci_omap_host *omap_host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) unsigned char signal_voltage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) ktime_t timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) reg &= ~HCTL_SDVS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (signal_voltage == MMC_SIGNAL_VOLTAGE_330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) reg |= HCTL_SDVS_33;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) reg |= HCTL_SDVS_18;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) reg |= HCTL_SDBP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /* wait 1ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) timeout = ktime_add_ms(ktime_get(), SDHCI_OMAP_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) bool timedout = ktime_after(ktime_get(), timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL) & HCTL_SDBP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (WARN_ON(timedout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) usleep_range(5, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static void sdhci_omap_enable_sdio_irq(struct mmc_host *mmc, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct sdhci_host *host = mmc_priv(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) reg |= (CON_CTPL | CON_CLKEXTFREE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) reg &= ~(CON_CTPL | CON_CLKEXTFREE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) sdhci_enable_sdio_irq(mmc, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static inline void sdhci_omap_set_dll(struct sdhci_omap_host *omap_host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_DLL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) reg |= DLL_FORCE_VALUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) reg &= ~DLL_FORCE_SR_C_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) reg |= (count << DLL_FORCE_SR_C_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) sdhci_omap_writel(omap_host, SDHCI_OMAP_DLL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) reg |= DLL_CALIB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) sdhci_omap_writel(omap_host, SDHCI_OMAP_DLL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) for (i = 0; i < 1000; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_DLL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (reg & DLL_CALIB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) reg &= ~DLL_CALIB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) sdhci_omap_writel(omap_host, SDHCI_OMAP_DLL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static void sdhci_omap_disable_tuning(struct sdhci_omap_host *omap_host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) reg &= ~AC12_SCLK_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) sdhci_omap_writel(omap_host, SDHCI_OMAP_AC12, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_DLL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) reg &= ~(DLL_FORCE_VALUE | DLL_SWT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) sdhci_omap_writel(omap_host, SDHCI_OMAP_DLL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static int sdhci_omap_execute_tuning(struct mmc_host *mmc, u32 opcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct sdhci_host *host = mmc_priv(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct thermal_zone_device *thermal_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct device *dev = omap_host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct mmc_ios *ios = &mmc->ios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) u32 start_window = 0, max_window = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) bool single_point_failure = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) bool dcrc_was_enabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) u8 cur_match, prev_match = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) u32 length = 0, max_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) u32 phase_delay = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) int temperature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /* clock tuning is not needed for upto 52MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (ios->clock <= 52000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (ios->timing == MMC_TIMING_UHS_SDR50 && !(reg & CAPA2_TSDR50))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) thermal_dev = thermal_zone_get_zone_by_name("cpu_thermal");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (IS_ERR(thermal_dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) dev_err(dev, "Unable to get thermal zone for tuning\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return PTR_ERR(thermal_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) ret = thermal_zone_get_temp(thermal_dev, &temperature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_DLL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) reg |= DLL_SWT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) sdhci_omap_writel(omap_host, SDHCI_OMAP_DLL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) * OMAP5/DRA74X/DRA72x Errata i802:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) * DCRC error interrupts (MMCHS_STAT[21] DCRC=0x1) can occur
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * during the tuning procedure. So disable it during the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) * tuning procedure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (host->ier & SDHCI_INT_DATA_CRC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) host->ier &= ~SDHCI_INT_DATA_CRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) dcrc_was_enabled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) omap_host->is_tuning = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * Stage 1: Search for a maximum pass window ignoring any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * any single point failures. If the tuning value ends up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * near it, move away from it in stage 2 below
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) while (phase_delay <= MAX_PHASE_DELAY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) sdhci_omap_set_dll(omap_host, phase_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) cur_match = !mmc_send_tuning(mmc, opcode, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (cur_match) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (prev_match) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) length++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) } else if (single_point_failure) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) /* ignore single point failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) length++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) start_window = phase_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) length = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) single_point_failure = prev_match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (length > max_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) max_window = start_window;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) max_len = length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) prev_match = cur_match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) phase_delay += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (!max_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) dev_err(dev, "Unable to find match\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) goto tuning_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) * Assign tuning value as a ratio of maximum pass window based
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) * on temperature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (temperature < -20000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) phase_delay = min(max_window + 4 * (max_len - 1) - 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) max_window +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) DIV_ROUND_UP(13 * max_len, 16) * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) else if (temperature < 20000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) phase_delay = max_window + DIV_ROUND_UP(9 * max_len, 16) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) else if (temperature < 40000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) phase_delay = max_window + DIV_ROUND_UP(8 * max_len, 16) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) else if (temperature < 70000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) phase_delay = max_window + DIV_ROUND_UP(7 * max_len, 16) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) else if (temperature < 90000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) phase_delay = max_window + DIV_ROUND_UP(5 * max_len, 16) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) else if (temperature < 120000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) phase_delay = max_window + DIV_ROUND_UP(4 * max_len, 16) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) phase_delay = max_window + DIV_ROUND_UP(3 * max_len, 16) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * Stage 2: Search for a single point failure near the chosen tuning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * value in two steps. First in the +3 to +10 range and then in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * +2 to -10 range. If found, move away from it in the appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * direction by the appropriate amount depending on the temperature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) for (i = 3; i <= 10; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) sdhci_omap_set_dll(omap_host, phase_delay + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (mmc_send_tuning(mmc, opcode, NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (temperature < 10000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) phase_delay += i + 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) else if (temperature < 20000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) phase_delay += i - 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) else if (temperature < 70000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) phase_delay += i - 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) phase_delay += i - 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) goto single_failure_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) for (i = 2; i >= -10; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) sdhci_omap_set_dll(omap_host, phase_delay + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (mmc_send_tuning(mmc, opcode, NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (temperature < 10000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) phase_delay += i + 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) else if (temperature < 20000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) phase_delay += i + 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) else if (temperature < 70000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) phase_delay += i + 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) else if (temperature < 90000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) phase_delay += i + 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) phase_delay += i + 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) goto single_failure_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) single_failure_found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (!(reg & AC12_SCLK_SEL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) goto tuning_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) sdhci_omap_set_dll(omap_host, phase_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) omap_host->is_tuning = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) goto ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) tuning_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) omap_host->is_tuning = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) dev_err(dev, "Tuning failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) sdhci_omap_disable_tuning(omap_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) /* Reenable forbidden interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (dcrc_was_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) host->ier |= SDHCI_INT_DATA_CRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) static int sdhci_omap_card_busy(struct mmc_host *mmc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) u32 reg, ac12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) int ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) struct sdhci_host *host = mmc_priv(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) struct sdhci_pltfm_host *pltfm_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) struct sdhci_omap_host *omap_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) u32 ier = host->ier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) pltfm_host = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) omap_host = sdhci_pltfm_priv(pltfm_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) ac12 = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) reg &= ~CON_CLKEXTFREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (ac12 & AC12_V1V8_SIGEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) reg |= CON_CLKEXTFREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) reg |= CON_PADEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) disable_irq(host->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) ier |= SDHCI_INT_CARD_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) sdhci_writel(host, ier, SDHCI_INT_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) * Delay is required for PSTATE to correctly reflect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) * DLEV/CLEV values after PADEN is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) usleep_range(50, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_PSTATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if ((reg & PSTATE_DATI) || !(reg & PSTATE_DLEV_DAT0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) reg &= ~(CON_CLKEXTFREE | CON_PADEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) enable_irq(host->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) static int sdhci_omap_start_signal_voltage_switch(struct mmc_host *mmc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) struct mmc_ios *ios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) unsigned int iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) struct sdhci_host *host = mmc_priv(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct sdhci_pltfm_host *pltfm_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) struct sdhci_omap_host *omap_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) pltfm_host = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) omap_host = sdhci_pltfm_priv(pltfm_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) dev = omap_host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (!(reg & CAPA_VS33))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) sdhci_omap_conf_bus_power(omap_host, ios->signal_voltage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) reg &= ~AC12_V1V8_SIGEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) sdhci_omap_writel(omap_host, SDHCI_OMAP_AC12, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) iov = IOV_3V3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) } else if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (!(reg & CAPA_VS18))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) sdhci_omap_conf_bus_power(omap_host, ios->signal_voltage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) reg |= AC12_V1V8_SIGEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) sdhci_omap_writel(omap_host, SDHCI_OMAP_AC12, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) iov = IOV_1V8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) ret = sdhci_omap_enable_iov(omap_host, iov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) dev_err(dev, "failed to switch IO voltage to %dmV\n", iov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) dev_dbg(dev, "IO voltage switched to %dmV\n", iov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) static void sdhci_omap_set_timing(struct sdhci_omap_host *omap_host, u8 timing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) struct pinctrl_state *pinctrl_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) struct device *dev = omap_host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (!(omap_host->flags & SDHCI_OMAP_REQUIRE_IODELAY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (omap_host->timing == timing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) sdhci_omap_stop_clock(omap_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) pinctrl_state = omap_host->pinctrl_state[timing];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) ret = pinctrl_select_state(omap_host->pinctrl, pinctrl_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) dev_err(dev, "failed to select pinctrl state\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) sdhci_omap_start_clock(omap_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) omap_host->timing = timing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) static void sdhci_omap_set_power_mode(struct sdhci_omap_host *omap_host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) u8 power_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (omap_host->bus_mode == MMC_POWER_OFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) sdhci_omap_disable_tuning(omap_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) omap_host->power_mode = power_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) static void sdhci_omap_set_bus_mode(struct sdhci_omap_host *omap_host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) unsigned int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (omap_host->bus_mode == mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (mode == MMC_BUSMODE_OPENDRAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) reg |= CON_OD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) reg &= ~CON_OD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) omap_host->bus_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) static void sdhci_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) struct sdhci_host *host = mmc_priv(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) struct sdhci_pltfm_host *pltfm_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) struct sdhci_omap_host *omap_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) pltfm_host = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) omap_host = sdhci_pltfm_priv(pltfm_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) sdhci_omap_set_bus_mode(omap_host, ios->bus_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) sdhci_omap_set_timing(omap_host, ios->timing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) sdhci_set_ios(mmc, ios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) sdhci_omap_set_power_mode(omap_host, ios->power_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) static u16 sdhci_omap_calc_divisor(struct sdhci_pltfm_host *host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) unsigned int clock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) u16 dsor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) dsor = DIV_ROUND_UP(clk_get_rate(host->clk), clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) if (dsor > SYSCTL_CLKD_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) dsor = SYSCTL_CLKD_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return dsor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) static void sdhci_omap_start_clock(struct sdhci_omap_host *omap_host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) reg |= SYSCTL_CEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) static void sdhci_omap_stop_clock(struct sdhci_omap_host *omap_host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) reg &= ~SYSCTL_CEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) static void sdhci_omap_set_clock(struct sdhci_host *host, unsigned int clock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) unsigned long clkdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) sdhci_omap_stop_clock(omap_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (!clock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) clkdiv = sdhci_omap_calc_divisor(pltfm_host, clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) clkdiv = (clkdiv & SYSCTL_CLKD_MASK) << SYSCTL_CLKD_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) sdhci_enable_clk(host, clkdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) sdhci_omap_start_clock(omap_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) static void sdhci_omap_set_power(struct sdhci_host *host, unsigned char mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) unsigned short vdd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) struct mmc_host *mmc = host->mmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (!IS_ERR(mmc->supply.vmmc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) static int sdhci_omap_enable_dma(struct sdhci_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) reg &= ~CON_DMA_MASTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) /* Switch to DMA slave mode when using external DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) if (!host->use_external_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) reg |= CON_DMA_MASTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) static unsigned int sdhci_omap_get_min_clock(struct sdhci_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) return clk_get_rate(pltfm_host->clk) / SYSCTL_CLKD_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) static void sdhci_omap_set_bus_width(struct sdhci_host *host, int width)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if (width == MMC_BUS_WIDTH_8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) reg |= CON_DW8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) reg &= ~CON_DW8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) sdhci_set_bus_width(host, width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) static void sdhci_omap_init_74_clocks(struct sdhci_host *host, u8 power_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) ktime_t timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (omap_host->power_mode == power_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (power_mode != MMC_POWER_ON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) disable_irq(host->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) reg |= CON_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) sdhci_omap_writel(omap_host, SDHCI_OMAP_CMD, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) /* wait 1ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) timeout = ktime_add_ms(ktime_get(), SDHCI_OMAP_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) bool timedout = ktime_after(ktime_get(), timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) if (sdhci_omap_readl(omap_host, SDHCI_OMAP_STAT) & INT_CC_EN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) if (WARN_ON(timedout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) usleep_range(5, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) reg &= ~CON_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) sdhci_omap_writel(omap_host, SDHCI_OMAP_STAT, INT_CC_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) enable_irq(host->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) static void sdhci_omap_set_uhs_signaling(struct sdhci_host *host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) unsigned int timing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) sdhci_omap_stop_clock(omap_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (timing == MMC_TIMING_UHS_DDR50 || timing == MMC_TIMING_MMC_DDR52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) reg |= CON_DDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) reg &= ~CON_DDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) sdhci_set_uhs_signaling(host, timing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) sdhci_omap_start_clock(omap_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) #define MMC_TIMEOUT_US 20000 /* 20000 micro Sec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) static void sdhci_omap_reset(struct sdhci_host *host, u8 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) unsigned long limit = MMC_TIMEOUT_US;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) unsigned long i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) /* Don't reset data lines during tuning operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if (omap_host->is_tuning)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) mask &= ~SDHCI_RESET_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if (omap_host->flags & SDHCI_OMAP_SPECIAL_RESET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) while ((!(sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) (i++ < limit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) while ((sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) (i++ < limit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) if (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) dev_err(mmc_dev(host->mmc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) "Timeout waiting on controller reset in %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) sdhci_reset(host, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) #define CMD_ERR_MASK (SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) SDHCI_INT_TIMEOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) #define CMD_MASK (CMD_ERR_MASK | SDHCI_INT_RESPONSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) static u32 sdhci_omap_irq(struct sdhci_host *host, u32 intmask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (omap_host->is_tuning && host->cmd && !host->data_early &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) (intmask & CMD_ERR_MASK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) * Since we are not resetting data lines during tuning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) * operation, data error or data complete interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) * might still arrive. Mark this request as a failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) * but still wait for the data interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) if (intmask & SDHCI_INT_TIMEOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) host->cmd->error = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) host->cmd->error = -EILSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) host->cmd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) * Sometimes command error interrupts and command complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) * interrupt will arrive together. Clear all command related
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) * interrupts here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) sdhci_writel(host, intmask & CMD_MASK, SDHCI_INT_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) intmask &= ~CMD_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) return intmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) static void sdhci_omap_set_timeout(struct sdhci_host *host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) struct mmc_command *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) if (cmd->opcode == MMC_ERASE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) sdhci_set_data_timeout_irq(host, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) __sdhci_set_timeout(host, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) static struct sdhci_ops sdhci_omap_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) .set_clock = sdhci_omap_set_clock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) .set_power = sdhci_omap_set_power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) .enable_dma = sdhci_omap_enable_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) .get_max_clock = sdhci_pltfm_clk_get_max_clock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) .get_min_clock = sdhci_omap_get_min_clock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) .set_bus_width = sdhci_omap_set_bus_width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) .platform_send_init_74_clocks = sdhci_omap_init_74_clocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) .reset = sdhci_omap_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) .set_uhs_signaling = sdhci_omap_set_uhs_signaling,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) .irq = sdhci_omap_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) .set_timeout = sdhci_omap_set_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) static int sdhci_omap_set_capabilities(struct sdhci_omap_host *omap_host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) struct device *dev = omap_host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) struct regulator *vqmmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) vqmmc = regulator_get(dev, "vqmmc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) if (IS_ERR(vqmmc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) ret = PTR_ERR(vqmmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) goto reg_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) /* voltage capabilities might be set by boot loader, clear it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) reg &= ~(CAPA_VS18 | CAPA_VS30 | CAPA_VS33);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) if (regulator_is_supported_voltage(vqmmc, IOV_3V3, IOV_3V3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) reg |= CAPA_VS33;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) if (regulator_is_supported_voltage(vqmmc, IOV_1V8, IOV_1V8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) reg |= CAPA_VS18;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) sdhci_omap_writel(omap_host, SDHCI_OMAP_CAPA, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) reg_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) regulator_put(vqmmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) static const struct sdhci_pltfm_data sdhci_omap_pdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) SDHCI_QUIRK_NO_HISPD_BIT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) .quirks2 = SDHCI_QUIRK2_ACMD23_BROKEN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) SDHCI_QUIRK2_RSP_136_HAS_CRC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) SDHCI_QUIRK2_DISABLE_HW_TIMEOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) .ops = &sdhci_omap_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) static const struct sdhci_omap_data k2g_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) .offset = 0x200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) static const struct sdhci_omap_data am335_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) .offset = 0x200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) .flags = SDHCI_OMAP_SPECIAL_RESET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) static const struct sdhci_omap_data am437_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) .offset = 0x200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) .flags = SDHCI_OMAP_SPECIAL_RESET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) static const struct sdhci_omap_data dra7_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) .offset = 0x200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) .flags = SDHCI_OMAP_REQUIRE_IODELAY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) static const struct of_device_id omap_sdhci_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) { .compatible = "ti,dra7-sdhci", .data = &dra7_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) { .compatible = "ti,k2g-sdhci", .data = &k2g_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) { .compatible = "ti,am335-sdhci", .data = &am335_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) { .compatible = "ti,am437-sdhci", .data = &am437_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) MODULE_DEVICE_TABLE(of, omap_sdhci_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) static struct pinctrl_state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) *sdhci_omap_iodelay_pinctrl_state(struct sdhci_omap_host *omap_host, char *mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) u32 *caps, u32 capmask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) struct device *dev = omap_host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) char *version = omap_host->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) struct pinctrl_state *pinctrl_state = ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) char str[20];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) if (!(*caps & capmask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) goto ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) if (version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) snprintf(str, 20, "%s-%s", mode, version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) pinctrl_state = pinctrl_lookup_state(omap_host->pinctrl, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) if (IS_ERR(pinctrl_state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) pinctrl_state = pinctrl_lookup_state(omap_host->pinctrl, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (IS_ERR(pinctrl_state)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) dev_err(dev, "no pinctrl state for %s mode", mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) *caps &= ~capmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) return pinctrl_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) static int sdhci_omap_config_iodelay_pinctrl_state(struct sdhci_omap_host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) *omap_host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) struct device *dev = omap_host->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) struct sdhci_host *host = omap_host->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) struct mmc_host *mmc = host->mmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) u32 *caps = &mmc->caps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) u32 *caps2 = &mmc->caps2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) struct pinctrl_state *state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) struct pinctrl_state **pinctrl_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (!(omap_host->flags & SDHCI_OMAP_REQUIRE_IODELAY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) pinctrl_state = devm_kcalloc(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) MMC_TIMING_MMC_HS200 + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) sizeof(*pinctrl_state),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) if (!pinctrl_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) omap_host->pinctrl = devm_pinctrl_get(omap_host->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) if (IS_ERR(omap_host->pinctrl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) dev_err(dev, "Cannot get pinctrl\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) return PTR_ERR(omap_host->pinctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) state = pinctrl_lookup_state(omap_host->pinctrl, "default");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) if (IS_ERR(state)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) dev_err(dev, "no pinctrl state for default mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) return PTR_ERR(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) pinctrl_state[MMC_TIMING_LEGACY] = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) state = sdhci_omap_iodelay_pinctrl_state(omap_host, "sdr104", caps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) MMC_CAP_UHS_SDR104);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) if (!IS_ERR(state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) pinctrl_state[MMC_TIMING_UHS_SDR104] = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) state = sdhci_omap_iodelay_pinctrl_state(omap_host, "ddr50", caps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) MMC_CAP_UHS_DDR50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) if (!IS_ERR(state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) pinctrl_state[MMC_TIMING_UHS_DDR50] = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) state = sdhci_omap_iodelay_pinctrl_state(omap_host, "sdr50", caps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) MMC_CAP_UHS_SDR50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) if (!IS_ERR(state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) pinctrl_state[MMC_TIMING_UHS_SDR50] = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) state = sdhci_omap_iodelay_pinctrl_state(omap_host, "sdr25", caps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) MMC_CAP_UHS_SDR25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (!IS_ERR(state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) pinctrl_state[MMC_TIMING_UHS_SDR25] = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) state = sdhci_omap_iodelay_pinctrl_state(omap_host, "sdr12", caps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) MMC_CAP_UHS_SDR12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) if (!IS_ERR(state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) pinctrl_state[MMC_TIMING_UHS_SDR12] = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) state = sdhci_omap_iodelay_pinctrl_state(omap_host, "ddr_1_8v", caps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) MMC_CAP_1_8V_DDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) if (!IS_ERR(state)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) pinctrl_state[MMC_TIMING_MMC_DDR52] = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) state = sdhci_omap_iodelay_pinctrl_state(omap_host, "ddr_3_3v",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) caps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) MMC_CAP_3_3V_DDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) if (!IS_ERR(state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) pinctrl_state[MMC_TIMING_MMC_DDR52] = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) state = sdhci_omap_iodelay_pinctrl_state(omap_host, "hs", caps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) MMC_CAP_SD_HIGHSPEED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) if (!IS_ERR(state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) pinctrl_state[MMC_TIMING_SD_HS] = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) state = sdhci_omap_iodelay_pinctrl_state(omap_host, "hs", caps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) MMC_CAP_MMC_HIGHSPEED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) if (!IS_ERR(state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) pinctrl_state[MMC_TIMING_MMC_HS] = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) state = sdhci_omap_iodelay_pinctrl_state(omap_host, "hs200_1_8v", caps2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) MMC_CAP2_HS200_1_8V_SDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) if (!IS_ERR(state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) pinctrl_state[MMC_TIMING_MMC_HS200] = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) omap_host->pinctrl_state = pinctrl_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) static const struct soc_device_attribute sdhci_omap_soc_devices[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) .machine = "DRA7[45]*",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) .revision = "ES1.[01]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) /* sentinel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) static int sdhci_omap_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) u32 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) struct sdhci_host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) struct sdhci_pltfm_host *pltfm_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) struct sdhci_omap_host *omap_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) struct mmc_host *mmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) const struct of_device_id *match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) struct sdhci_omap_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) const struct soc_device_attribute *soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) struct resource *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) match = of_match_device(omap_sdhci_match, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) if (!match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) data = (struct sdhci_omap_data *)match->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) if (!data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) dev_err(dev, "no sdhci omap data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) offset = data->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) if (!regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) host = sdhci_pltfm_init(pdev, &sdhci_omap_pdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) sizeof(*omap_host));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if (IS_ERR(host)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) dev_err(dev, "Failed sdhci_pltfm_init\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) return PTR_ERR(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) pltfm_host = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) omap_host = sdhci_pltfm_priv(pltfm_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) omap_host->host = host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) omap_host->base = host->ioaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) omap_host->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) omap_host->power_mode = MMC_POWER_UNDEFINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) omap_host->timing = MMC_TIMING_LEGACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) omap_host->flags = data->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) host->ioaddr += offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) host->mapbase = regs->start + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) mmc = host->mmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) sdhci_get_of_property(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) ret = mmc_of_parse(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) goto err_pltfm_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) soc = soc_device_match(sdhci_omap_soc_devices);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) if (soc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) omap_host->version = "rev11";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) if (!strcmp(dev_name(dev), "4809c000.mmc"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) mmc->f_max = 96000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) if (!strcmp(dev_name(dev), "480b4000.mmc"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) mmc->f_max = 48000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) if (!strcmp(dev_name(dev), "480ad000.mmc"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) mmc->f_max = 48000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) if (!mmc_can_gpio_ro(mmc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) mmc->caps2 |= MMC_CAP2_NO_WRITE_PROTECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) pltfm_host->clk = devm_clk_get(dev, "fck");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) if (IS_ERR(pltfm_host->clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) ret = PTR_ERR(pltfm_host->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) goto err_pltfm_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) ret = clk_set_rate(pltfm_host->clk, mmc->f_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) dev_err(dev, "failed to set clock to %d\n", mmc->f_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) goto err_pltfm_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) omap_host->pbias = devm_regulator_get_optional(dev, "pbias");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) if (IS_ERR(omap_host->pbias)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) ret = PTR_ERR(omap_host->pbias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) if (ret != -ENODEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) goto err_pltfm_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) dev_dbg(dev, "unable to get pbias regulator %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) omap_host->pbias_enabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) * omap_device_pm_domain has callbacks to enable the main
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) * functional clock, interface clock and also configure the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) * SYSCONFIG register of omap devices. The callback will be invoked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) * as part of pm_runtime_get_sync.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) pm_runtime_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) ret = pm_runtime_get_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) dev_err(dev, "pm_runtime_get_sync failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) pm_runtime_put_noidle(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) goto err_rpm_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) ret = sdhci_omap_set_capabilities(omap_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) dev_err(dev, "failed to set system capabilities\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) goto err_put_sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) host->mmc_host_ops.start_signal_voltage_switch =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) sdhci_omap_start_signal_voltage_switch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) host->mmc_host_ops.set_ios = sdhci_omap_set_ios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) host->mmc_host_ops.card_busy = sdhci_omap_card_busy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) host->mmc_host_ops.execute_tuning = sdhci_omap_execute_tuning;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) host->mmc_host_ops.enable_sdio_irq = sdhci_omap_enable_sdio_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) /* Switch to external DMA only if there is the "dmas" property */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if (of_find_property(dev->of_node, "dmas", NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) sdhci_switch_external_dma(host, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) /* R1B responses is required to properly manage HW busy detection. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) mmc->caps |= MMC_CAP_NEED_RSP_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) ret = sdhci_setup_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) goto err_put_sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) ret = sdhci_omap_config_iodelay_pinctrl_state(omap_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) goto err_cleanup_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) ret = __sdhci_add_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) goto err_cleanup_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) err_cleanup_host:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) sdhci_cleanup_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) err_put_sync:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) pm_runtime_put_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) err_rpm_disable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) pm_runtime_disable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) err_pltfm_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) sdhci_pltfm_free(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) static int sdhci_omap_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) struct sdhci_host *host = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) sdhci_remove_host(host, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) pm_runtime_put_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) pm_runtime_disable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) sdhci_pltfm_free(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) static void sdhci_omap_context_save(struct sdhci_omap_host *omap_host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) omap_host->con = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) omap_host->hctl = sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) omap_host->sysctl = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) omap_host->capa = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) omap_host->ie = sdhci_omap_readl(omap_host, SDHCI_OMAP_IE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) omap_host->ise = sdhci_omap_readl(omap_host, SDHCI_OMAP_ISE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) /* Order matters here, HCTL must be restored in two phases */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) static void sdhci_omap_context_restore(struct sdhci_omap_host *omap_host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, omap_host->hctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) sdhci_omap_writel(omap_host, SDHCI_OMAP_CAPA, omap_host->capa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, omap_host->hctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, omap_host->sysctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, omap_host->con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) sdhci_omap_writel(omap_host, SDHCI_OMAP_IE, omap_host->ie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) sdhci_omap_writel(omap_host, SDHCI_OMAP_ISE, omap_host->ise);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) static int __maybe_unused sdhci_omap_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) struct sdhci_host *host = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) sdhci_suspend_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) sdhci_omap_context_save(omap_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) pinctrl_pm_select_idle_state(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) pm_runtime_force_suspend(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) static int __maybe_unused sdhci_omap_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) struct sdhci_host *host = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) pm_runtime_force_resume(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) pinctrl_pm_select_default_state(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) sdhci_omap_context_restore(omap_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) sdhci_resume_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) static SIMPLE_DEV_PM_OPS(sdhci_omap_dev_pm_ops, sdhci_omap_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) sdhci_omap_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) static struct platform_driver sdhci_omap_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) .probe = sdhci_omap_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) .remove = sdhci_omap_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) .name = "sdhci-omap",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) .probe_type = PROBE_PREFER_ASYNCHRONOUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) .pm = &sdhci_omap_dev_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) .of_match_table = omap_sdhci_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) module_platform_driver(sdhci_omap_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) MODULE_DESCRIPTION("SDHCI driver for OMAP SoCs");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) MODULE_AUTHOR("Texas Instruments Inc.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) MODULE_ALIAS("platform:sdhci_omap");