File Index
Files and directories
Sign in
FILE

sdhci_am654.c

File preview with syntax highlighting.

linux-6.19.14/drivers/mmc/host/sdhci_am654.c C
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * sdhci_am654.c - SDHCI driver for TI's AM654 SOCs
   4 *
   5 * Copyright (C) 2018 Texas Instruments Incorporated - https://www.ti.com
   6 *
   7 */
   8#include <linux/clk.h>
   9#include <linux/iopoll.h>
  10#include <linux/of.h>
  11#include <linux/module.h>
  12#include <linux/pm_runtime.h>
  13#include <linux/property.h>
  14#include <linux/regmap.h>
  15#include <linux/sys_soc.h>
  16
  17#include "cqhci.h"
  18#include "sdhci-cqhci.h"
  19#include "sdhci-pltfm.h"
  20
  21/* CTL_CFG Registers */
  22#define CTL_CFG_2		0x14
  23#define CTL_CFG_3		0x18
  24
  25#define SLOTTYPE_MASK		GENMASK(31, 30)
  26#define SLOTTYPE_EMBEDDED	BIT(30)
  27#define TUNINGFORSDR50_MASK	BIT(13)
  28
  29/* PHY Registers */
  30#define PHY_CTRL1	0x100
  31#define PHY_CTRL2	0x104
  32#define PHY_CTRL3	0x108
  33#define PHY_CTRL4	0x10C
  34#define PHY_CTRL5	0x110
  35#define PHY_CTRL6	0x114
  36#define PHY_STAT1	0x130
  37#define PHY_STAT2	0x134
  38
  39#define IOMUX_ENABLE_SHIFT	31
  40#define IOMUX_ENABLE_MASK	BIT(IOMUX_ENABLE_SHIFT)
  41#define OTAPDLYENA_SHIFT	20
  42#define OTAPDLYENA_MASK		BIT(OTAPDLYENA_SHIFT)
  43#define OTAPDLYSEL_SHIFT	12
  44#define OTAPDLYSEL_MASK		GENMASK(15, 12)
  45#define STRBSEL_SHIFT		24
  46#define STRBSEL_4BIT_MASK	GENMASK(27, 24)
  47#define STRBSEL_8BIT_MASK	GENMASK(31, 24)
  48#define SEL50_SHIFT		8
  49#define SEL50_MASK		BIT(SEL50_SHIFT)
  50#define SEL100_SHIFT		9
  51#define SEL100_MASK		BIT(SEL100_SHIFT)
  52#define FREQSEL_SHIFT		8
  53#define FREQSEL_MASK		GENMASK(10, 8)
  54#define CLKBUFSEL_SHIFT		0
  55#define CLKBUFSEL_MASK		GENMASK(2, 0)
  56#define DLL_TRIM_ICP_SHIFT	4
  57#define DLL_TRIM_ICP_MASK	GENMASK(7, 4)
  58#define DR_TY_SHIFT		20
  59#define DR_TY_MASK		GENMASK(22, 20)
  60#define ENDLL_SHIFT		1
  61#define ENDLL_MASK		BIT(ENDLL_SHIFT)
  62#define DLLRDY_SHIFT		0
  63#define DLLRDY_MASK		BIT(DLLRDY_SHIFT)
  64#define PDB_SHIFT		0
  65#define PDB_MASK		BIT(PDB_SHIFT)
  66#define CALDONE_SHIFT		1
  67#define CALDONE_MASK		BIT(CALDONE_SHIFT)
  68#define RETRIM_SHIFT		17
  69#define RETRIM_MASK		BIT(RETRIM_SHIFT)
  70#define SELDLYTXCLK_SHIFT	17
  71#define SELDLYTXCLK_MASK	BIT(SELDLYTXCLK_SHIFT)
  72#define SELDLYRXCLK_SHIFT	16
  73#define SELDLYRXCLK_MASK	BIT(SELDLYRXCLK_SHIFT)
  74#define ITAPDLYSEL_SHIFT	0
  75#define ITAPDLYSEL_MASK		GENMASK(4, 0)
  76#define ITAPDLYENA_SHIFT	8
  77#define ITAPDLYENA_MASK		BIT(ITAPDLYENA_SHIFT)
  78#define ITAPCHGWIN_SHIFT	9
  79#define ITAPCHGWIN_MASK		BIT(ITAPCHGWIN_SHIFT)
  80
  81#define DRIVER_STRENGTH_50_OHM	0x0
  82#define DRIVER_STRENGTH_33_OHM	0x1
  83#define DRIVER_STRENGTH_66_OHM	0x2
  84#define DRIVER_STRENGTH_100_OHM	0x3
  85#define DRIVER_STRENGTH_40_OHM	0x4
  86
  87#define CLOCK_TOO_SLOW_HZ	50000000
  88#define SDHCI_AM654_AUTOSUSPEND_DELAY	-1
  89#define RETRY_TUNING_MAX	10
  90
  91/* Command Queue Host Controller Interface Base address */
  92#define SDHCI_AM654_CQE_BASE_ADDR 0x200
  93
  94static const struct regmap_config sdhci_am654_regmap_config = {
  95	.reg_bits = 32,
  96	.val_bits = 32,
  97	.reg_stride = 4,
  98};
  99
 100struct timing_data {
 101	const char *otap_binding;
 102	const char *itap_binding;
 103	u32 capability;
 104};
 105
 106static const struct timing_data td[] = {
 107	[MMC_TIMING_LEGACY]	= {"ti,otap-del-sel-legacy",
 108				   "ti,itap-del-sel-legacy",
 109				   0},
 110	[MMC_TIMING_MMC_HS]	= {"ti,otap-del-sel-mmc-hs",
 111				   "ti,itap-del-sel-mmc-hs",
 112				   MMC_CAP_MMC_HIGHSPEED},
 113	[MMC_TIMING_SD_HS]	= {"ti,otap-del-sel-sd-hs",
 114				   "ti,itap-del-sel-sd-hs",
 115				   MMC_CAP_SD_HIGHSPEED},
 116	[MMC_TIMING_UHS_SDR12]	= {"ti,otap-del-sel-sdr12",
 117				   "ti,itap-del-sel-sdr12",
 118				   MMC_CAP_UHS_SDR12},
 119	[MMC_TIMING_UHS_SDR25]	= {"ti,otap-del-sel-sdr25",
 120				   "ti,itap-del-sel-sdr25",
 121				   MMC_CAP_UHS_SDR25},
 122	[MMC_TIMING_UHS_SDR50]	= {"ti,otap-del-sel-sdr50",
 123				   NULL,
 124				   MMC_CAP_UHS_SDR50},
 125	[MMC_TIMING_UHS_SDR104]	= {"ti,otap-del-sel-sdr104",
 126				   NULL,
 127				   MMC_CAP_UHS_SDR104},
 128	[MMC_TIMING_UHS_DDR50]	= {"ti,otap-del-sel-ddr50",
 129				   NULL,
 130				   MMC_CAP_UHS_DDR50},
 131	[MMC_TIMING_MMC_DDR52]	= {"ti,otap-del-sel-ddr52",
 132				   "ti,itap-del-sel-ddr52",
 133				   MMC_CAP_DDR},
 134	[MMC_TIMING_MMC_HS200]	= {"ti,otap-del-sel-hs200",
 135				   NULL,
 136				   MMC_CAP2_HS200},
 137	[MMC_TIMING_MMC_HS400]	= {"ti,otap-del-sel-hs400",
 138				   NULL,
 139				   MMC_CAP2_HS400},
 140};
 141
 142struct sdhci_am654_data {
 143	struct regmap *base;
 144	u32 otap_del_sel[ARRAY_SIZE(td)];
 145	u32 itap_del_sel[ARRAY_SIZE(td)];
 146	u32 itap_del_ena[ARRAY_SIZE(td)];
 147	int clkbuf_sel;
 148	int trm_icp;
 149	int drv_strength;
 150	int strb_sel;
 151	u32 flags;
 152	u32 quirks;
 153	bool dll_enable;
 154	u32 tuning_loop;
 155
 156#define SDHCI_AM654_QUIRK_FORCE_CDTEST BIT(0)
 157#define SDHCI_AM654_QUIRK_SUPPRESS_V1P8_ENA BIT(1)
 158#define SDHCI_AM654_QUIRK_DISABLE_HS400 BIT(2)
 159};
 160
 161struct window {
 162	u8 start;
 163	u8 end;
 164	u8 length;
 165};
 166
 167struct sdhci_am654_driver_data {
 168	const struct sdhci_pltfm_data *pdata;
 169	u32 flags;
 170	u32 quirks;
 171#define IOMUX_PRESENT	(1 << 0)
 172#define FREQSEL_2_BIT	(1 << 1)
 173#define STRBSEL_4_BIT	(1 << 2)
 174#define DLL_PRESENT	(1 << 3)
 175#define DLL_CALIB	(1 << 4)
 176};
 177
 178static void sdhci_am654_setup_dll(struct sdhci_host *host, unsigned int clock)
 179{
 180	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 181	struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
 182	int sel50, sel100, freqsel;
 183	u32 mask, val;
 184	int ret;
 185
 186	/* Disable delay chain mode */
 187	regmap_update_bits(sdhci_am654->base, PHY_CTRL5,
 188			   SELDLYTXCLK_MASK | SELDLYRXCLK_MASK, 0);
 189
 190	if (sdhci_am654->flags & FREQSEL_2_BIT) {
 191		switch (clock) {
 192		case 200000000:
 193			sel50 = 0;
 194			sel100 = 0;
 195			break;
 196		case 100000000:
 197			sel50 = 0;
 198			sel100 = 1;
 199			break;
 200		default:
 201			sel50 = 1;
 202			sel100 = 0;
 203		}
 204
 205		/* Configure PHY DLL frequency */
 206		mask = SEL50_MASK | SEL100_MASK;
 207		val = (sel50 << SEL50_SHIFT) | (sel100 << SEL100_SHIFT);
 208		regmap_update_bits(sdhci_am654->base, PHY_CTRL5, mask, val);
 209
 210	} else {
 211		switch (clock) {
 212		case 200000000:
 213			freqsel = 0x0;
 214			break;
 215		default:
 216			freqsel = 0x4;
 217		}
 218
 219		regmap_update_bits(sdhci_am654->base, PHY_CTRL5, FREQSEL_MASK,
 220				   freqsel << FREQSEL_SHIFT);
 221	}
 222	/* Configure DLL TRIM */
 223	mask = DLL_TRIM_ICP_MASK;
 224	val = sdhci_am654->trm_icp << DLL_TRIM_ICP_SHIFT;
 225
 226	/* Configure DLL driver strength */
 227	mask |= DR_TY_MASK;
 228	val |= sdhci_am654->drv_strength << DR_TY_SHIFT;
 229	regmap_update_bits(sdhci_am654->base, PHY_CTRL1, mask, val);
 230
 231	/* Enable DLL */
 232	regmap_update_bits(sdhci_am654->base, PHY_CTRL1, ENDLL_MASK,
 233			   0x1 << ENDLL_SHIFT);
 234	/*
 235	 * Poll for DLL ready. Use a one second timeout.
 236	 * Works in all experiments done so far
 237	 */
 238	ret = regmap_read_poll_timeout(sdhci_am654->base, PHY_STAT1, val,
 239				       val & DLLRDY_MASK, 1000, 1000000);
 240	if (ret) {
 241		dev_err(mmc_dev(host->mmc), "DLL failed to relock\n");
 242		return;
 243	}
 244}
 245
 246static void sdhci_am654_write_itapdly(struct sdhci_am654_data *sdhci_am654,
 247				      u32 itapdly, u32 enable)
 248{
 249	/* Set ITAPCHGWIN before writing to ITAPDLY */
 250	regmap_update_bits(sdhci_am654->base, PHY_CTRL4, ITAPCHGWIN_MASK,
 251			   1 << ITAPCHGWIN_SHIFT);
 252	regmap_update_bits(sdhci_am654->base, PHY_CTRL4, ITAPDLYENA_MASK,
 253			   enable << ITAPDLYENA_SHIFT);
 254	regmap_update_bits(sdhci_am654->base, PHY_CTRL4, ITAPDLYSEL_MASK,
 255			   itapdly << ITAPDLYSEL_SHIFT);
 256	regmap_update_bits(sdhci_am654->base, PHY_CTRL4, ITAPCHGWIN_MASK, 0);
 257}
 258
 259static void sdhci_am654_setup_delay_chain(struct sdhci_am654_data *sdhci_am654,
 260					  unsigned char timing)
 261{
 262	u32 mask, val;
 263
 264	regmap_update_bits(sdhci_am654->base, PHY_CTRL1, ENDLL_MASK, 0);
 265
 266	val = 1 << SELDLYTXCLK_SHIFT | 1 << SELDLYRXCLK_SHIFT;
 267	mask = SELDLYTXCLK_MASK | SELDLYRXCLK_MASK;
 268	regmap_update_bits(sdhci_am654->base, PHY_CTRL5, mask, val);
 269
 270	sdhci_am654_write_itapdly(sdhci_am654, sdhci_am654->itap_del_sel[timing],
 271				  sdhci_am654->itap_del_ena[timing]);
 272}
 273
 274static void sdhci_am654_set_clock(struct sdhci_host *host, unsigned int clock)
 275{
 276	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 277	struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
 278	unsigned char timing = host->mmc->ios.timing;
 279	u32 otap_del_sel;
 280	u32 mask, val;
 281
 282	regmap_update_bits(sdhci_am654->base, PHY_CTRL1, ENDLL_MASK, 0);
 283
 284	sdhci_set_clock(host, clock);
 285
 286	/* Setup Output TAP delay */
 287	otap_del_sel = sdhci_am654->otap_del_sel[timing];
 288
 289	mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
 290	val = (0x1 << OTAPDLYENA_SHIFT) |
 291	      (otap_del_sel << OTAPDLYSEL_SHIFT);
 292
 293	/* Write to STRBSEL for HS400 speed mode */
 294	if (timing == MMC_TIMING_MMC_HS400) {
 295		if (sdhci_am654->flags & STRBSEL_4_BIT)
 296			mask |= STRBSEL_4BIT_MASK;
 297		else
 298			mask |= STRBSEL_8BIT_MASK;
 299
 300		val |= sdhci_am654->strb_sel << STRBSEL_SHIFT;
 301	}
 302
 303	regmap_update_bits(sdhci_am654->base, PHY_CTRL4, mask, val);
 304
 305	if (timing > MMC_TIMING_UHS_SDR25 && clock >= CLOCK_TOO_SLOW_HZ) {
 306		sdhci_am654_setup_dll(host, clock);
 307		sdhci_am654->dll_enable = true;
 308
 309		if (timing == MMC_TIMING_MMC_HS400) {
 310			sdhci_am654->itap_del_ena[timing] = 0x1;
 311			sdhci_am654->itap_del_sel[timing] = sdhci_am654->itap_del_sel[timing - 1];
 312		}
 313
 314		sdhci_am654_write_itapdly(sdhci_am654, sdhci_am654->itap_del_sel[timing],
 315					  sdhci_am654->itap_del_ena[timing]);
 316	} else {
 317		sdhci_am654_setup_delay_chain(sdhci_am654, timing);
 318		sdhci_am654->dll_enable = false;
 319	}
 320
 321	regmap_update_bits(sdhci_am654->base, PHY_CTRL5, CLKBUFSEL_MASK,
 322			   sdhci_am654->clkbuf_sel);
 323}
 324
 325static void sdhci_j721e_4bit_set_clock(struct sdhci_host *host,
 326				       unsigned int clock)
 327{
 328	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 329	struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
 330	unsigned char timing = host->mmc->ios.timing;
 331	u32 otap_del_sel;
 332	u32 itap_del_ena;
 333	u32 itap_del_sel;
 334	u32 mask, val;
 335
 336	/* Setup Output TAP delay */
 337	otap_del_sel = sdhci_am654->otap_del_sel[timing];
 338
 339	mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
 340	val = (0x1 << OTAPDLYENA_SHIFT) |
 341	      (otap_del_sel << OTAPDLYSEL_SHIFT);
 342
 343	/* Setup Input TAP delay */
 344	itap_del_ena = sdhci_am654->itap_del_ena[timing];
 345	itap_del_sel = sdhci_am654->itap_del_sel[timing];
 346
 347	mask |= ITAPDLYENA_MASK | ITAPDLYSEL_MASK;
 348	val |= (itap_del_ena << ITAPDLYENA_SHIFT) |
 349	       (itap_del_sel << ITAPDLYSEL_SHIFT);
 350
 351	regmap_update_bits(sdhci_am654->base, PHY_CTRL4, ITAPCHGWIN_MASK,
 352			   1 << ITAPCHGWIN_SHIFT);
 353	regmap_update_bits(sdhci_am654->base, PHY_CTRL4, mask, val);
 354	regmap_update_bits(sdhci_am654->base, PHY_CTRL4, ITAPCHGWIN_MASK, 0);
 355	regmap_update_bits(sdhci_am654->base, PHY_CTRL5, CLKBUFSEL_MASK,
 356			   sdhci_am654->clkbuf_sel);
 357
 358	sdhci_set_clock(host, clock);
 359}
 360
 361static int sdhci_am654_start_signal_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios)
 362{
 363	struct sdhci_host *host = mmc_priv(mmc);
 364	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 365	struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
 366	int ret;
 367
 368	if ((sdhci_am654->quirks & SDHCI_AM654_QUIRK_SUPPRESS_V1P8_ENA) &&
 369	    ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
 370		if (!IS_ERR(mmc->supply.vqmmc)) {
 371			ret = mmc_regulator_set_vqmmc(mmc, ios);
 372			if (ret < 0) {
 373				pr_err("%s: Switching to 1.8V signalling voltage failed,\n",
 374				       mmc_hostname(mmc));
 375				return -EIO;
 376			}
 377		}
 378		return 0;
 379	}
 380
 381	return sdhci_start_signal_voltage_switch(mmc, ios);
 382}
 383
 384static u8 sdhci_am654_write_power_on(struct sdhci_host *host, u8 val, int reg)
 385{
 386	writeb(val, host->ioaddr + reg);
 387	usleep_range(1000, 10000);
 388	return readb(host->ioaddr + reg);
 389}
 390
 391#define MAX_POWER_ON_TIMEOUT	1500000 /* us */
 392static void sdhci_am654_write_b(struct sdhci_host *host, u8 val, int reg)
 393{
 394	unsigned char timing = host->mmc->ios.timing;
 395	u8 pwr;
 396	int ret;
 397
 398	if (reg == SDHCI_HOST_CONTROL) {
 399		switch (timing) {
 400		/*
 401		 * According to the data manual, HISPD bit
 402		 * should not be set in these speed modes.
 403		 */
 404		case MMC_TIMING_SD_HS:
 405		case MMC_TIMING_MMC_HS:
 406			val &= ~SDHCI_CTRL_HISPD;
 407		}
 408	}
 409
 410	writeb(val, host->ioaddr + reg);
 411	if (reg == SDHCI_POWER_CONTROL && (val & SDHCI_POWER_ON)) {
 412		/*
 413		 * Power on will not happen until the card detect debounce
 414		 * timer expires. Wait at least 1.5 seconds for the power on
 415		 * bit to be set
 416		 */
 417		ret = read_poll_timeout(sdhci_am654_write_power_on, pwr,
 418					pwr & SDHCI_POWER_ON, 0,
 419					MAX_POWER_ON_TIMEOUT, false, host, val,
 420					reg);
 421		if (ret)
 422			dev_info(mmc_dev(host->mmc), "Power on failed\n");
 423	}
 424}
 425
 426static void sdhci_am654_reset(struct sdhci_host *host, u8 mask)
 427{
 428	u8 ctrl;
 429	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 430	struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
 431
 432	sdhci_and_cqhci_reset(host, mask);
 433
 434	if (sdhci_am654->quirks & SDHCI_AM654_QUIRK_FORCE_CDTEST) {
 435		ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
 436		ctrl |= SDHCI_CTRL_CDTEST_INS | SDHCI_CTRL_CDTEST_EN;
 437		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 438	}
 439}
 440
 441static int sdhci_am654_execute_tuning(struct mmc_host *mmc, u32 opcode)
 442{
 443	struct sdhci_host *host = mmc_priv(mmc);
 444	int err = sdhci_execute_tuning(mmc, opcode);
 445
 446	if (err)
 447		return err;
 448	/*
 449	 * Tuning data remains in the buffer after tuning.
 450	 * Do a command and data reset to get rid of it
 451	 */
 452	sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
 453
 454	return 0;
 455}
 456
 457static u32 sdhci_am654_cqhci_irq(struct sdhci_host *host, u32 intmask)
 458{
 459	int cmd_error = 0;
 460	int data_error = 0;
 461
 462	if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
 463		return intmask;
 464
 465	cqhci_irq(host->mmc, intmask, cmd_error, data_error);
 466
 467	return 0;
 468}
 469
 470#define ITAPDLY_LENGTH 32
 471#define ITAPDLY_LAST_INDEX (ITAPDLY_LENGTH - 1)
 472
 473static int sdhci_am654_calculate_itap(struct sdhci_host *host, struct window
 474			  *fail_window, u8 num_fails, bool circular_buffer)
 475{
 476	u8 itap = 0, start_fail = 0, end_fail = 0, pass_length = 0;
 477	u8 first_fail_start = 0, last_fail_end = 0;
 478	struct device *dev = mmc_dev(host->mmc);
 479	struct window pass_window = {0, 0, 0};
 480	int prev_fail_end = -1;
 481	u8 i;
 482
 483	if (!num_fails) {
 484		/* Retry tuning */
 485		dev_dbg(dev, "No failing region found, retry tuning\n");
 486		return -1;
 487	}
 488
 489	if (fail_window->length == ITAPDLY_LENGTH) {
 490		/* Retry tuning */
 491		dev_dbg(dev, "No passing itapdly, retry tuning\n");
 492		return -1;
 493	}
 494
 495	first_fail_start = fail_window->start;
 496	last_fail_end = fail_window[num_fails - 1].end;
 497
 498	for (i = 0; i < num_fails; i++) {
 499		start_fail = fail_window[i].start;
 500		end_fail = fail_window[i].end;
 501		pass_length = start_fail - (prev_fail_end + 1);
 502
 503		if (pass_length > pass_window.length) {
 504			pass_window.start = prev_fail_end + 1;
 505			pass_window.length = pass_length;
 506		}
 507		prev_fail_end = end_fail;
 508	}
 509
 510	if (!circular_buffer)
 511		pass_length = ITAPDLY_LAST_INDEX - last_fail_end;
 512	else
 513		pass_length = ITAPDLY_LAST_INDEX - last_fail_end + first_fail_start;
 514
 515	if (pass_length > pass_window.length) {
 516		pass_window.start = last_fail_end + 1;
 517		pass_window.length = pass_length;
 518	}
 519
 520	if (!circular_buffer)
 521		itap = pass_window.start + (pass_window.length >> 1);
 522	else
 523		itap = (pass_window.start + (pass_window.length >> 1)) % ITAPDLY_LENGTH;
 524
 525	return (itap > ITAPDLY_LAST_INDEX) ? ITAPDLY_LAST_INDEX >> 1 : itap;
 526}
 527
 528static int sdhci_am654_do_tuning(struct sdhci_host *host,
 529				 u32 opcode)
 530{
 531	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 532	struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
 533	unsigned char timing = host->mmc->ios.timing;
 534	struct window fail_window[ITAPDLY_LENGTH];
 535	struct device *dev = mmc_dev(host->mmc);
 536	u8 curr_pass, itap;
 537	u8 fail_index = 0;
 538	u8 prev_pass = 1;
 539
 540	memset(fail_window, 0, sizeof(fail_window));
 541
 542	/* Enable ITAPDLY */
 543	sdhci_am654->itap_del_ena[timing] = 0x1;
 544
 545	for (itap = 0; itap < ITAPDLY_LENGTH; itap++) {
 546		sdhci_am654_write_itapdly(sdhci_am654, itap, sdhci_am654->itap_del_ena[timing]);
 547
 548		curr_pass = !mmc_send_tuning(host->mmc, opcode, NULL);
 549
 550		if (!curr_pass && prev_pass)
 551			fail_window[fail_index].start = itap;
 552
 553		if (!curr_pass) {
 554			fail_window[fail_index].end = itap;
 555			fail_window[fail_index].length++;
 556			dev_dbg(dev, "Failed itapdly=%d\n", itap);
 557		}
 558
 559		if (curr_pass && !prev_pass)
 560			fail_index++;
 561
 562		prev_pass = curr_pass;
 563	}
 564
 565	if (fail_window[fail_index].length != 0)
 566		fail_index++;
 567
 568	return sdhci_am654_calculate_itap(host, fail_window, fail_index,
 569					 sdhci_am654->dll_enable);
 570}
 571
 572static int sdhci_am654_platform_execute_tuning(struct sdhci_host *host,
 573					       u32 opcode)
 574{
 575	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 576	struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
 577	unsigned char timing = host->mmc->ios.timing;
 578	struct device *dev = mmc_dev(host->mmc);
 579	int itapdly;
 580
 581	do {
 582		itapdly = sdhci_am654_do_tuning(host, opcode);
 583		if (itapdly >= 0)
 584			break;
 585	} while (++sdhci_am654->tuning_loop < RETRY_TUNING_MAX);
 586
 587	if (itapdly < 0) {
 588		dev_err(dev, "Failed to find itapdly, fail tuning\n");
 589		return -1;
 590	}
 591
 592	dev_dbg(dev, "Passed tuning, final itapdly=%d\n", itapdly);
 593	sdhci_am654_write_itapdly(sdhci_am654, itapdly, sdhci_am654->itap_del_ena[timing]);
 594	/* Save ITAPDLY */
 595	sdhci_am654->itap_del_sel[timing] = itapdly;
 596
 597	return 0;
 598}
 599
 600static const struct sdhci_ops sdhci_am654_ops = {
 601	.platform_execute_tuning = sdhci_am654_platform_execute_tuning,
 602	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 603	.get_timeout_clock = sdhci_pltfm_clk_get_max_clock,
 604	.set_uhs_signaling = sdhci_set_uhs_signaling,
 605	.set_bus_width = sdhci_set_bus_width,
 606	.set_power = sdhci_set_power_and_bus_voltage,
 607	.set_clock = sdhci_am654_set_clock,
 608	.write_b = sdhci_am654_write_b,
 609	.irq = sdhci_am654_cqhci_irq,
 610	.reset = sdhci_and_cqhci_reset,
 611};
 612
 613static const struct sdhci_pltfm_data sdhci_am654_pdata = {
 614	.ops = &sdhci_am654_ops,
 615	.quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
 616	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
 617		   SDHCI_QUIRK2_DISABLE_HW_TIMEOUT,
 618};
 619
 620static const struct sdhci_am654_driver_data sdhci_am654_sr1_drvdata = {
 621	.pdata = &sdhci_am654_pdata,
 622	.flags = IOMUX_PRESENT | FREQSEL_2_BIT | STRBSEL_4_BIT | DLL_PRESENT |
 623		 DLL_CALIB,
 624};
 625
 626static const struct sdhci_am654_driver_data sdhci_am654_drvdata = {
 627	.pdata = &sdhci_am654_pdata,
 628	.flags = IOMUX_PRESENT | FREQSEL_2_BIT | STRBSEL_4_BIT | DLL_PRESENT,
 629};
 630
 631static const struct sdhci_ops sdhci_j721e_8bit_ops = {
 632	.platform_execute_tuning = sdhci_am654_platform_execute_tuning,
 633	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 634	.get_timeout_clock = sdhci_pltfm_clk_get_max_clock,
 635	.set_uhs_signaling = sdhci_set_uhs_signaling,
 636	.set_bus_width = sdhci_set_bus_width,
 637	.set_power = sdhci_set_power_and_bus_voltage,
 638	.set_clock = sdhci_am654_set_clock,
 639	.write_b = sdhci_am654_write_b,
 640	.irq = sdhci_am654_cqhci_irq,
 641	.reset = sdhci_and_cqhci_reset,
 642};
 643
 644static const struct sdhci_pltfm_data sdhci_j721e_8bit_pdata = {
 645	.ops = &sdhci_j721e_8bit_ops,
 646	.quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
 647	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
 648		   SDHCI_QUIRK2_DISABLE_HW_TIMEOUT,
 649};
 650
 651static const struct sdhci_am654_driver_data sdhci_j721e_8bit_drvdata = {
 652	.pdata = &sdhci_j721e_8bit_pdata,
 653	.flags = DLL_PRESENT | DLL_CALIB,
 654};
 655
 656static const struct sdhci_ops sdhci_j721e_4bit_ops = {
 657	.platform_execute_tuning = sdhci_am654_platform_execute_tuning,
 658	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 659	.get_timeout_clock = sdhci_pltfm_clk_get_max_clock,
 660	.set_uhs_signaling = sdhci_set_uhs_signaling,
 661	.set_bus_width = sdhci_set_bus_width,
 662	.set_power = sdhci_set_power_and_bus_voltage,
 663	.set_clock = sdhci_j721e_4bit_set_clock,
 664	.write_b = sdhci_am654_write_b,
 665	.irq = sdhci_am654_cqhci_irq,
 666	.reset = sdhci_am654_reset,
 667};
 668
 669static const struct sdhci_pltfm_data sdhci_j721e_4bit_pdata = {
 670	.ops = &sdhci_j721e_4bit_ops,
 671	.quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
 672	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
 673		   SDHCI_QUIRK2_DISABLE_HW_TIMEOUT,
 674};
 675
 676static const struct sdhci_am654_driver_data sdhci_j721e_4bit_drvdata = {
 677	.pdata = &sdhci_j721e_4bit_pdata,
 678	.flags = IOMUX_PRESENT,
 679};
 680
 681static const struct sdhci_am654_driver_data sdhci_am62_4bit_drvdata = {
 682	.pdata = &sdhci_j721e_4bit_pdata,
 683	.flags = IOMUX_PRESENT,
 684	.quirks = SDHCI_AM654_QUIRK_SUPPRESS_V1P8_ENA,
 685};
 686
 687static const struct soc_device_attribute sdhci_am654_devices[] = {
 688	{ .family = "AM65X",
 689	  .revision = "SR1.0",
 690	  .data = &sdhci_am654_sr1_drvdata
 691	},
 692	{/* sentinel */}
 693};
 694
 695static void sdhci_am654_dumpregs(struct mmc_host *mmc)
 696{
 697	sdhci_dumpregs(mmc_priv(mmc));
 698}
 699
 700static const struct cqhci_host_ops sdhci_am654_cqhci_ops = {
 701	.enable		= sdhci_cqe_enable,
 702	.disable	= sdhci_cqe_disable,
 703	.dumpregs	= sdhci_am654_dumpregs,
 704};
 705
 706static int sdhci_am654_cqe_add_host(struct sdhci_host *host)
 707{
 708	struct cqhci_host *cq_host;
 709
 710	cq_host = devm_kzalloc(mmc_dev(host->mmc), sizeof(struct cqhci_host),
 711			       GFP_KERNEL);
 712	if (!cq_host)
 713		return -ENOMEM;
 714
 715	cq_host->mmio = host->ioaddr + SDHCI_AM654_CQE_BASE_ADDR;
 716	cq_host->quirks |= CQHCI_QUIRK_SHORT_TXFR_DESC_SZ;
 717	cq_host->caps |= CQHCI_TASK_DESC_SZ_128;
 718	cq_host->ops = &sdhci_am654_cqhci_ops;
 719
 720	host->mmc->caps2 |= MMC_CAP2_CQE;
 721
 722	return cqhci_init(cq_host, host->mmc, 1);
 723}
 724
 725static int sdhci_am654_get_otap_delay(struct sdhci_host *host,
 726				      struct sdhci_am654_data *sdhci_am654)
 727{
 728	struct device *dev = mmc_dev(host->mmc);
 729	int i;
 730	int ret;
 731
 732	for (i = MMC_TIMING_LEGACY; i <= MMC_TIMING_MMC_HS400; i++) {
 733
 734		ret = device_property_read_u32(dev, td[i].otap_binding,
 735					       &sdhci_am654->otap_del_sel[i]);
 736		if (ret) {
 737			if (i == MMC_TIMING_LEGACY) {
 738				dev_err(dev, "Couldn't find mandatory ti,otap-del-sel-legacy\n");
 739				return ret;
 740			}
 741			dev_dbg(dev, "Couldn't find %s\n",
 742				td[i].otap_binding);
 743			/*
 744			 * Remove the corresponding capability
 745			 * if an otap-del-sel value is not found
 746			 */
 747			if (i <= MMC_TIMING_MMC_DDR52)
 748				host->mmc->caps &= ~td[i].capability;
 749			else
 750				host->mmc->caps2 &= ~td[i].capability;
 751		}
 752
 753		if (td[i].itap_binding) {
 754			ret = device_property_read_u32(dev, td[i].itap_binding,
 755						       &sdhci_am654->itap_del_sel[i]);
 756			if (!ret)
 757				sdhci_am654->itap_del_ena[i] = 0x1;
 758		}
 759	}
 760
 761	return 0;
 762}
 763
 764static int sdhci_am654_init(struct sdhci_host *host)
 765{
 766	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 767	struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
 768	struct device *dev = mmc_dev(host->mmc);
 769	u32 ctl_cfg_2 = 0;
 770	u32 mask;
 771	u32 val;
 772	int ret;
 773
 774	/* Reset OTAP to default value */
 775	mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
 776	regmap_update_bits(sdhci_am654->base, PHY_CTRL4, mask, 0x0);
 777
 778	if (sdhci_am654->flags & DLL_CALIB) {
 779		regmap_read(sdhci_am654->base, PHY_STAT1, &val);
 780		if (~val & CALDONE_MASK) {
 781			/* Calibrate IO lines */
 782			regmap_update_bits(sdhci_am654->base, PHY_CTRL1,
 783					   PDB_MASK, PDB_MASK);
 784			ret = regmap_read_poll_timeout(sdhci_am654->base,
 785						       PHY_STAT1, val,
 786						       val & CALDONE_MASK,
 787						       1, 20);
 788			if (ret)
 789				return ret;
 790		}
 791	}
 792
 793	/* Enable pins by setting IO mux to 0 */
 794	if (sdhci_am654->flags & IOMUX_PRESENT)
 795		regmap_update_bits(sdhci_am654->base, PHY_CTRL1,
 796				   IOMUX_ENABLE_MASK, 0);
 797
 798	/* Set slot type based on SD or eMMC */
 799	if (host->mmc->caps & MMC_CAP_NONREMOVABLE)
 800		ctl_cfg_2 = SLOTTYPE_EMBEDDED;
 801
 802	regmap_update_bits(sdhci_am654->base, CTL_CFG_2, SLOTTYPE_MASK,
 803			   ctl_cfg_2);
 804
 805	/* Enable tuning for SDR50 */
 806	regmap_update_bits(sdhci_am654->base, CTL_CFG_3, TUNINGFORSDR50_MASK,
 807			   TUNINGFORSDR50_MASK);
 808
 809	/* Use to re-execute tuning */
 810	sdhci_am654->tuning_loop = 0;
 811
 812	ret = sdhci_setup_host(host);
 813	if (ret)
 814		return ret;
 815
 816	ret = sdhci_am654_cqe_add_host(host);
 817	if (ret)
 818		goto err_cleanup_host;
 819
 820	ret = sdhci_am654_get_otap_delay(host, sdhci_am654);
 821	if (ret)
 822		goto err_cleanup_host;
 823
 824	if (sdhci_am654->quirks & SDHCI_AM654_QUIRK_DISABLE_HS400 &&
 825	    host->mmc->caps2 & (MMC_CAP2_HS400 | MMC_CAP2_HS400_ES)) {
 826		dev_info(dev, "HS400 mode not supported on this silicon revision, disabling it\n");
 827		host->mmc->caps2 &= ~(MMC_CAP2_HS400 | MMC_CAP2_HS400_ES);
 828	}
 829
 830	ret = __sdhci_add_host(host);
 831	if (ret)
 832		goto err_cleanup_host;
 833
 834	return 0;
 835
 836err_cleanup_host:
 837	sdhci_cleanup_host(host);
 838	return ret;
 839}
 840
 841static int sdhci_am654_get_of_property(struct platform_device *pdev,
 842					struct sdhci_am654_data *sdhci_am654)
 843{
 844	struct device *dev = &pdev->dev;
 845	int drv_strength;
 846	int ret;
 847
 848	if (sdhci_am654->flags & DLL_PRESENT) {
 849		ret = device_property_read_u32(dev, "ti,trm-icp",
 850					       &sdhci_am654->trm_icp);
 851		if (ret)
 852			return ret;
 853
 854		ret = device_property_read_u32(dev, "ti,driver-strength-ohm",
 855					       &drv_strength);
 856		if (ret)
 857			return ret;
 858
 859		switch (drv_strength) {
 860		case 50:
 861			sdhci_am654->drv_strength = DRIVER_STRENGTH_50_OHM;
 862			break;
 863		case 33:
 864			sdhci_am654->drv_strength = DRIVER_STRENGTH_33_OHM;
 865			break;
 866		case 66:
 867			sdhci_am654->drv_strength = DRIVER_STRENGTH_66_OHM;
 868			break;
 869		case 100:
 870			sdhci_am654->drv_strength = DRIVER_STRENGTH_100_OHM;
 871			break;
 872		case 40:
 873			sdhci_am654->drv_strength = DRIVER_STRENGTH_40_OHM;
 874			break;
 875		default:
 876			dev_err(dev, "Invalid driver strength\n");
 877			return -EINVAL;
 878		}
 879	}
 880
 881	device_property_read_u32(dev, "ti,strobe-sel", &sdhci_am654->strb_sel);
 882	device_property_read_u32(dev, "ti,clkbuf-sel",
 883				 &sdhci_am654->clkbuf_sel);
 884
 885	if (device_property_read_bool(dev, "ti,fails-without-test-cd"))
 886		sdhci_am654->quirks |= SDHCI_AM654_QUIRK_FORCE_CDTEST;
 887
 888	sdhci_get_of_property(pdev);
 889
 890	return 0;
 891}
 892
 893static const struct soc_device_attribute sdhci_am654_descope_hs400[] = {
 894	{ .family = "AM62PX", .revision = "SR1.0" },
 895	{ .family = "AM62PX", .revision = "SR1.1" },
 896	{ /* sentinel */ }
 897};
 898
 899static const struct of_device_id sdhci_am654_of_match[] = {
 900	{
 901		.compatible = "ti,am654-sdhci-5.1",
 902		.data = &sdhci_am654_drvdata,
 903	},
 904	{
 905		.compatible = "ti,j721e-sdhci-8bit",
 906		.data = &sdhci_j721e_8bit_drvdata,
 907	},
 908	{
 909		.compatible = "ti,j721e-sdhci-4bit",
 910		.data = &sdhci_j721e_4bit_drvdata,
 911	},
 912	{
 913		.compatible = "ti,am64-sdhci-8bit",
 914		.data = &sdhci_j721e_8bit_drvdata,
 915	},
 916	{
 917		.compatible = "ti,am64-sdhci-4bit",
 918		.data = &sdhci_j721e_4bit_drvdata,
 919	},
 920	{
 921		.compatible = "ti,am62-sdhci",
 922		.data = &sdhci_am62_4bit_drvdata,
 923	},
 924	{ /* sentinel */ }
 925};
 926MODULE_DEVICE_TABLE(of, sdhci_am654_of_match);
 927
 928static int sdhci_am654_probe(struct platform_device *pdev)
 929{
 930	const struct sdhci_am654_driver_data *drvdata;
 931	const struct soc_device_attribute *soc;
 932	struct sdhci_pltfm_host *pltfm_host;
 933	struct sdhci_am654_data *sdhci_am654;
 934	const struct of_device_id *match;
 935	struct sdhci_host *host;
 936	struct clk *clk_xin;
 937	struct device *dev = &pdev->dev;
 938	void __iomem *base;
 939	int ret;
 940
 941	match = of_match_node(sdhci_am654_of_match, pdev->dev.of_node);
 942	drvdata = match->data;
 943
 944	/* Update drvdata based on SoC revision */
 945	soc = soc_device_match(sdhci_am654_devices);
 946	if (soc && soc->data)
 947		drvdata = soc->data;
 948
 949	host = sdhci_pltfm_init(pdev, drvdata->pdata, sizeof(*sdhci_am654));
 950	if (IS_ERR(host))
 951		return PTR_ERR(host);
 952
 953	pltfm_host = sdhci_priv(host);
 954	sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
 955	sdhci_am654->flags = drvdata->flags;
 956	sdhci_am654->quirks = drvdata->quirks;
 957
 958	clk_xin = devm_clk_get(dev, "clk_xin");
 959	if (IS_ERR(clk_xin)) {
 960		dev_err(dev, "clk_xin clock not found.\n");
 961		return PTR_ERR(clk_xin);
 962	}
 963
 964	pltfm_host->clk = clk_xin;
 965
 966	base = devm_platform_ioremap_resource(pdev, 1);
 967	if (IS_ERR(base)) {
 968		return PTR_ERR(base);
 969	}
 970
 971	sdhci_am654->base = devm_regmap_init_mmio(dev, base,
 972						  &sdhci_am654_regmap_config);
 973	if (IS_ERR(sdhci_am654->base)) {
 974		dev_err(dev, "Failed to initialize regmap\n");
 975		return PTR_ERR(sdhci_am654->base);
 976	}
 977
 978	ret = sdhci_am654_get_of_property(pdev, sdhci_am654);
 979	if (ret)
 980		return ret;
 981
 982	ret = mmc_of_parse(host->mmc);
 983	if (ret)
 984		return dev_err_probe(dev, ret, "parsing dt failed\n");
 985
 986	soc = soc_device_match(sdhci_am654_descope_hs400);
 987	if (soc)
 988		sdhci_am654->quirks |= SDHCI_AM654_QUIRK_DISABLE_HS400;
 989
 990	host->mmc_host_ops.start_signal_voltage_switch = sdhci_am654_start_signal_voltage_switch;
 991	host->mmc_host_ops.execute_tuning = sdhci_am654_execute_tuning;
 992
 993	pm_runtime_get_noresume(dev);
 994	ret = pm_runtime_set_active(dev);
 995	if (ret)
 996		goto pm_put;
 997	pm_runtime_enable(dev);
 998	ret = clk_prepare_enable(pltfm_host->clk);
 999	if (ret)
1000		goto pm_disable;
1001
1002	ret = sdhci_am654_init(host);
1003	if (ret)
1004		goto clk_disable;
1005
1006	/* Setting up autosuspend */
1007	pm_runtime_set_autosuspend_delay(dev, SDHCI_AM654_AUTOSUSPEND_DELAY);
1008	pm_runtime_use_autosuspend(dev);
1009	pm_runtime_put_autosuspend(dev);
1010	return 0;
1011
1012clk_disable:
1013	clk_disable_unprepare(pltfm_host->clk);
1014pm_disable:
1015	pm_runtime_disable(dev);
1016pm_put:
1017	pm_runtime_put_noidle(dev);
1018	return ret;
1019}
1020
1021static void sdhci_am654_remove(struct platform_device *pdev)
1022{
1023	struct sdhci_host *host = platform_get_drvdata(pdev);
1024	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
1025	struct device *dev = &pdev->dev;
1026	int ret;
1027
1028	ret = pm_runtime_get_sync(dev);
1029	if (ret < 0)
1030		dev_err(dev, "pm_runtime_get_sync() Failed\n");
1031
1032	sdhci_remove_host(host, true);
1033	clk_disable_unprepare(pltfm_host->clk);
1034	pm_runtime_disable(dev);
1035	pm_runtime_put_noidle(dev);
1036}
1037
1038static int sdhci_am654_restore(struct sdhci_host *host)
1039{
1040	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
1041	struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
1042	u32 ctl_cfg_2 = 0;
1043	u32 val;
1044	int ret;
1045
1046	if (sdhci_am654->flags & DLL_CALIB) {
1047		regmap_read(sdhci_am654->base, PHY_STAT1, &val);
1048		if (~val & CALDONE_MASK) {
1049			/* Calibrate IO lines */
1050			regmap_update_bits(sdhci_am654->base, PHY_CTRL1,
1051					   PDB_MASK, PDB_MASK);
1052			ret = regmap_read_poll_timeout(sdhci_am654->base,
1053						       PHY_STAT1, val,
1054						       val & CALDONE_MASK,
1055						       1, 20);
1056			if (ret)
1057				return ret;
1058		}
1059	}
1060
1061	/* Enable pins by setting IO mux to 0 */
1062	if (sdhci_am654->flags & IOMUX_PRESENT)
1063		regmap_update_bits(sdhci_am654->base, PHY_CTRL1,
1064				   IOMUX_ENABLE_MASK, 0);
1065
1066	/* Set slot type based on SD or eMMC */
1067	if (host->mmc->caps & MMC_CAP_NONREMOVABLE)
1068		ctl_cfg_2 = SLOTTYPE_EMBEDDED;
1069
1070	regmap_update_bits(sdhci_am654->base, CTL_CFG_2, SLOTTYPE_MASK,
1071			   ctl_cfg_2);
1072
1073	regmap_read(sdhci_am654->base, CTL_CFG_3, &val);
1074	if (~val & TUNINGFORSDR50_MASK)
1075		/* Enable tuning for SDR50 */
1076		regmap_update_bits(sdhci_am654->base, CTL_CFG_3, TUNINGFORSDR50_MASK,
1077				   TUNINGFORSDR50_MASK);
1078
1079	return 0;
1080}
1081
1082static int sdhci_am654_runtime_suspend(struct device *dev)
1083{
1084	struct sdhci_host *host = dev_get_drvdata(dev);
1085	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
1086	int ret;
1087
1088	if (host->tuning_mode != SDHCI_TUNING_MODE_3)
1089		mmc_retune_needed(host->mmc);
1090
1091	ret = cqhci_suspend(host->mmc);
1092	if (ret)
1093		return ret;
1094
1095	sdhci_runtime_suspend_host(host);
1096
1097	/* disable the clock */
1098	clk_disable_unprepare(pltfm_host->clk);
1099	return 0;
1100}
1101
1102static int sdhci_am654_runtime_resume(struct device *dev)
1103{
1104	struct sdhci_host *host = dev_get_drvdata(dev);
1105	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
1106	int ret;
1107
1108	/* Enable the clock */
1109	ret = clk_prepare_enable(pltfm_host->clk);
1110	if (ret)
1111		return ret;
1112
1113	ret = sdhci_am654_restore(host);
1114	if (ret)
1115		return ret;
1116
1117	sdhci_runtime_resume_host(host, 0);
1118
1119	ret = cqhci_resume(host->mmc);
1120	if (ret)
1121		return ret;
1122
1123	return 0;
1124}
1125
1126static const struct dev_pm_ops sdhci_am654_dev_pm_ops = {
1127	RUNTIME_PM_OPS(sdhci_am654_runtime_suspend, sdhci_am654_runtime_resume, NULL)
1128	SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
1129};
1130
1131static struct platform_driver sdhci_am654_driver = {
1132	.driver = {
1133		.name = "sdhci-am654",
1134		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
1135		.pm = pm_ptr(&sdhci_am654_dev_pm_ops),
1136		.of_match_table = sdhci_am654_of_match,
1137	},
1138	.probe = sdhci_am654_probe,
1139	.remove = sdhci_am654_remove,
1140};
1141
1142module_platform_driver(sdhci_am654_driver);
1143
1144MODULE_DESCRIPTION("Driver for SDHCI Controller on TI's AM654 devices");
1145MODULE_AUTHOR("Faiz Abbas <faiz_abbas@ti.com>");
1146MODULE_LICENSE("GPL");
~/ Read-only file preview.