Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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");