brintos

brintos / linux-shallow public Read only

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