brintos

brintos / linux-shallow public Read only

0
0
Text · 30.4 KiB · 178277d Raw
1233 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* Copyright (c) 2015, The Linux Foundation. All rights reserved.3 */4 5#include <linux/delay.h>6#include <linux/highmem.h>7#include <linux/io.h>8#include <linux/iopoll.h>9#include <linux/module.h>10#include <linux/dma-mapping.h>11#include <linux/slab.h>12#include <linux/scatterlist.h>13#include <linux/platform_device.h>14#include <linux/ktime.h>15 16#include <linux/mmc/mmc.h>17#include <linux/mmc/host.h>18#include <linux/mmc/card.h>19 20#include "cqhci.h"21#include "cqhci-crypto.h"22 23#define DCMD_SLOT 3124#define NUM_SLOTS 3225 26struct cqhci_slot {27	struct mmc_request *mrq;28	unsigned int flags;29#define CQHCI_EXTERNAL_TIMEOUT	BIT(0)30#define CQHCI_COMPLETED		BIT(1)31#define CQHCI_HOST_CRC		BIT(2)32#define CQHCI_HOST_TIMEOUT	BIT(3)33#define CQHCI_HOST_OTHER	BIT(4)34};35 36static bool cqhci_halted(struct cqhci_host *cq_host)37{38	return cqhci_readl(cq_host, CQHCI_CTL) & CQHCI_HALT;39}40 41static inline u8 *get_desc(struct cqhci_host *cq_host, u8 tag)42{43	return cq_host->desc_base + (tag * cq_host->slot_sz);44}45 46static inline u8 *get_link_desc(struct cqhci_host *cq_host, u8 tag)47{48	u8 *desc = get_desc(cq_host, tag);49 50	return desc + cq_host->task_desc_len;51}52 53static inline size_t get_trans_desc_offset(struct cqhci_host *cq_host, u8 tag)54{55	return cq_host->trans_desc_len * cq_host->mmc->max_segs * tag;56}57 58static inline dma_addr_t get_trans_desc_dma(struct cqhci_host *cq_host, u8 tag)59{60	size_t offset = get_trans_desc_offset(cq_host, tag);61 62	return cq_host->trans_desc_dma_base + offset;63}64 65static inline u8 *get_trans_desc(struct cqhci_host *cq_host, u8 tag)66{67	size_t offset = get_trans_desc_offset(cq_host, tag);68 69	return cq_host->trans_desc_base + offset;70}71 72static void setup_trans_desc(struct cqhci_host *cq_host, u8 tag)73{74	u8 *link_temp;75	dma_addr_t trans_temp;76 77	link_temp = get_link_desc(cq_host, tag);78	trans_temp = get_trans_desc_dma(cq_host, tag);79 80	memset(link_temp, 0, cq_host->link_desc_len);81	if (cq_host->link_desc_len > 8)82		*(link_temp + 8) = 0;83 84	if (tag == DCMD_SLOT && (cq_host->mmc->caps2 & MMC_CAP2_CQE_DCMD)) {85		*link_temp = CQHCI_VALID(0) | CQHCI_ACT(0) | CQHCI_END(1);86		return;87	}88 89	*link_temp = CQHCI_VALID(1) | CQHCI_ACT(0x6) | CQHCI_END(0);90 91	if (cq_host->dma64) {92		__le64 *data_addr = (__le64 __force *)(link_temp + 4);93 94		data_addr[0] = cpu_to_le64(trans_temp);95	} else {96		__le32 *data_addr = (__le32 __force *)(link_temp + 4);97 98		data_addr[0] = cpu_to_le32(trans_temp);99	}100}101 102static void cqhci_set_irqs(struct cqhci_host *cq_host, u32 set)103{104	cqhci_writel(cq_host, set, CQHCI_ISTE);105	cqhci_writel(cq_host, set, CQHCI_ISGE);106}107 108#define DRV_NAME "cqhci"109 110#define CQHCI_DUMP(f, x...) \111	pr_err("%s: " DRV_NAME ": " f, mmc_hostname(mmc), ## x)112 113static void cqhci_dumpregs(struct cqhci_host *cq_host)114{115	struct mmc_host *mmc = cq_host->mmc;116 117	CQHCI_DUMP("============ CQHCI REGISTER DUMP ===========\n");118 119	CQHCI_DUMP("Caps:      0x%08x | Version:  0x%08x\n",120		   cqhci_readl(cq_host, CQHCI_CAP),121		   cqhci_readl(cq_host, CQHCI_VER));122	CQHCI_DUMP("Config:    0x%08x | Control:  0x%08x\n",123		   cqhci_readl(cq_host, CQHCI_CFG),124		   cqhci_readl(cq_host, CQHCI_CTL));125	CQHCI_DUMP("Int stat:  0x%08x | Int enab: 0x%08x\n",126		   cqhci_readl(cq_host, CQHCI_IS),127		   cqhci_readl(cq_host, CQHCI_ISTE));128	CQHCI_DUMP("Int sig:   0x%08x | Int Coal: 0x%08x\n",129		   cqhci_readl(cq_host, CQHCI_ISGE),130		   cqhci_readl(cq_host, CQHCI_IC));131	CQHCI_DUMP("TDL base:  0x%08x | TDL up32: 0x%08x\n",132		   cqhci_readl(cq_host, CQHCI_TDLBA),133		   cqhci_readl(cq_host, CQHCI_TDLBAU));134	CQHCI_DUMP("Doorbell:  0x%08x | TCN:      0x%08x\n",135		   cqhci_readl(cq_host, CQHCI_TDBR),136		   cqhci_readl(cq_host, CQHCI_TCN));137	CQHCI_DUMP("Dev queue: 0x%08x | Dev Pend: 0x%08x\n",138		   cqhci_readl(cq_host, CQHCI_DQS),139		   cqhci_readl(cq_host, CQHCI_DPT));140	CQHCI_DUMP("Task clr:  0x%08x | SSC1:     0x%08x\n",141		   cqhci_readl(cq_host, CQHCI_TCLR),142		   cqhci_readl(cq_host, CQHCI_SSC1));143	CQHCI_DUMP("SSC2:      0x%08x | DCMD rsp: 0x%08x\n",144		   cqhci_readl(cq_host, CQHCI_SSC2),145		   cqhci_readl(cq_host, CQHCI_CRDCT));146	CQHCI_DUMP("RED mask:  0x%08x | TERRI:    0x%08x\n",147		   cqhci_readl(cq_host, CQHCI_RMEM),148		   cqhci_readl(cq_host, CQHCI_TERRI));149	CQHCI_DUMP("Resp idx:  0x%08x | Resp arg: 0x%08x\n",150		   cqhci_readl(cq_host, CQHCI_CRI),151		   cqhci_readl(cq_host, CQHCI_CRA));152 153	if (cq_host->ops->dumpregs)154		cq_host->ops->dumpregs(mmc);155	else156		CQHCI_DUMP(": ===========================================\n");157}158 159/*160 * The allocated descriptor table for task, link & transfer descriptors161 * looks like:162 * |----------|163 * |task desc |  |->|----------|164 * |----------|  |  |trans desc|165 * |link desc-|->|  |----------|166 * |----------|          .167 *      .                .168 *  no. of slots      max-segs169 *      .           |----------|170 * |----------|171 * The idea here is to create the [task+trans] table and mark & point the172 * link desc to the transfer desc table on a per slot basis.173 */174static int cqhci_host_alloc_tdl(struct cqhci_host *cq_host)175{176	int i = 0;177 178	/* task descriptor can be 64/128 bit irrespective of arch */179	if (cq_host->caps & CQHCI_TASK_DESC_SZ_128) {180		cqhci_writel(cq_host, cqhci_readl(cq_host, CQHCI_CFG) |181			       CQHCI_TASK_DESC_SZ, CQHCI_CFG);182		cq_host->task_desc_len = 16;183	} else {184		cq_host->task_desc_len = 8;185	}186 187	/*188	 * 96 bits length of transfer desc instead of 128 bits which means189	 * ADMA would expect next valid descriptor at the 96th bit190	 * or 128th bit191	 */192	if (cq_host->dma64) {193		if (cq_host->quirks & CQHCI_QUIRK_SHORT_TXFR_DESC_SZ)194			cq_host->trans_desc_len = 12;195		else196			cq_host->trans_desc_len = 16;197		cq_host->link_desc_len = 16;198	} else {199		cq_host->trans_desc_len = 8;200		cq_host->link_desc_len = 8;201	}202 203	/* total size of a slot: 1 task & 1 transfer (link) */204	cq_host->slot_sz = cq_host->task_desc_len + cq_host->link_desc_len;205 206	cq_host->desc_size = cq_host->slot_sz * cq_host->num_slots;207 208	cq_host->data_size = get_trans_desc_offset(cq_host, cq_host->mmc->cqe_qdepth);209 210	pr_debug("%s: cqhci: desc_size: %zu data_sz: %zu slot-sz: %d\n",211		 mmc_hostname(cq_host->mmc), cq_host->desc_size, cq_host->data_size,212		 cq_host->slot_sz);213 214	/*215	 * allocate a dma-mapped chunk of memory for the descriptors216	 * allocate a dma-mapped chunk of memory for link descriptors217	 * setup each link-desc memory offset per slot-number to218	 * the descriptor table.219	 */220	cq_host->desc_base = dmam_alloc_coherent(mmc_dev(cq_host->mmc),221						 cq_host->desc_size,222						 &cq_host->desc_dma_base,223						 GFP_KERNEL);224	if (!cq_host->desc_base)225		return -ENOMEM;226 227	cq_host->trans_desc_base = dmam_alloc_coherent(mmc_dev(cq_host->mmc),228					      cq_host->data_size,229					      &cq_host->trans_desc_dma_base,230					      GFP_KERNEL);231	if (!cq_host->trans_desc_base) {232		dmam_free_coherent(mmc_dev(cq_host->mmc), cq_host->desc_size,233				   cq_host->desc_base,234				   cq_host->desc_dma_base);235		cq_host->desc_base = NULL;236		cq_host->desc_dma_base = 0;237		return -ENOMEM;238	}239 240	pr_debug("%s: cqhci: desc-base: 0x%p trans-base: 0x%p\n desc_dma 0x%llx trans_dma: 0x%llx\n",241		 mmc_hostname(cq_host->mmc), cq_host->desc_base, cq_host->trans_desc_base,242		(unsigned long long)cq_host->desc_dma_base,243		(unsigned long long)cq_host->trans_desc_dma_base);244 245	for (; i < (cq_host->num_slots); i++)246		setup_trans_desc(cq_host, i);247 248	return 0;249}250 251static void __cqhci_enable(struct cqhci_host *cq_host)252{253	struct mmc_host *mmc = cq_host->mmc;254	u32 cqcfg;255 256	cqcfg = cqhci_readl(cq_host, CQHCI_CFG);257 258	/* Configuration must not be changed while enabled */259	if (cqcfg & CQHCI_ENABLE) {260		cqcfg &= ~CQHCI_ENABLE;261		cqhci_writel(cq_host, cqcfg, CQHCI_CFG);262	}263 264	cqcfg &= ~(CQHCI_DCMD | CQHCI_TASK_DESC_SZ);265 266	if (mmc->caps2 & MMC_CAP2_CQE_DCMD)267		cqcfg |= CQHCI_DCMD;268 269	if (cq_host->caps & CQHCI_TASK_DESC_SZ_128)270		cqcfg |= CQHCI_TASK_DESC_SZ;271 272	if (mmc->caps2 & MMC_CAP2_CRYPTO)273		cqcfg |= CQHCI_CRYPTO_GENERAL_ENABLE;274 275	cqhci_writel(cq_host, cqcfg, CQHCI_CFG);276 277	cqhci_writel(cq_host, lower_32_bits(cq_host->desc_dma_base),278		     CQHCI_TDLBA);279	cqhci_writel(cq_host, upper_32_bits(cq_host->desc_dma_base),280		     CQHCI_TDLBAU);281 282	cqhci_writel(cq_host, cq_host->rca, CQHCI_SSC2);283 284	cqhci_set_irqs(cq_host, 0);285 286	cqcfg |= CQHCI_ENABLE;287 288	cqhci_writel(cq_host, cqcfg, CQHCI_CFG);289 290	if (cqhci_halted(cq_host))291		cqhci_writel(cq_host, 0, CQHCI_CTL);292 293	mmc->cqe_on = true;294 295	if (cq_host->ops->enable)296		cq_host->ops->enable(mmc);297 298	/* Ensure all writes are done before interrupts are enabled */299	wmb();300 301	cqhci_set_irqs(cq_host, CQHCI_IS_MASK);302 303	cq_host->activated = true;304}305 306static void __cqhci_disable(struct cqhci_host *cq_host)307{308	u32 cqcfg;309 310	cqcfg = cqhci_readl(cq_host, CQHCI_CFG);311	cqcfg &= ~CQHCI_ENABLE;312	cqhci_writel(cq_host, cqcfg, CQHCI_CFG);313 314	cq_host->mmc->cqe_on = false;315 316	cq_host->activated = false;317}318 319int cqhci_deactivate(struct mmc_host *mmc)320{321	struct cqhci_host *cq_host = mmc->cqe_private;322 323	if (cq_host->enabled && cq_host->activated)324		__cqhci_disable(cq_host);325 326	return 0;327}328EXPORT_SYMBOL(cqhci_deactivate);329 330int cqhci_resume(struct mmc_host *mmc)331{332	/* Re-enable is done upon first request */333	return 0;334}335EXPORT_SYMBOL(cqhci_resume);336 337static int cqhci_enable(struct mmc_host *mmc, struct mmc_card *card)338{339	struct cqhci_host *cq_host = mmc->cqe_private;340	int err;341 342	if (!card->ext_csd.cmdq_en)343		return -EINVAL;344 345	if (cq_host->enabled)346		return 0;347 348	cq_host->rca = card->rca;349 350	err = cqhci_host_alloc_tdl(cq_host);351	if (err) {352		pr_err("%s: Failed to enable CQE, error %d\n",353		       mmc_hostname(mmc), err);354		return err;355	}356 357	__cqhci_enable(cq_host);358 359	cq_host->enabled = true;360 361#ifdef DEBUG362	cqhci_dumpregs(cq_host);363#endif364	return 0;365}366 367/* CQHCI is idle and should halt immediately, so set a small timeout */368#define CQHCI_OFF_TIMEOUT 100369 370static u32 cqhci_read_ctl(struct cqhci_host *cq_host)371{372	return cqhci_readl(cq_host, CQHCI_CTL);373}374 375static void cqhci_off(struct mmc_host *mmc)376{377	struct cqhci_host *cq_host = mmc->cqe_private;378	u32 reg;379	int err;380 381	if (!cq_host->enabled || !mmc->cqe_on || cq_host->recovery_halt)382		return;383 384	if (cq_host->ops->disable)385		cq_host->ops->disable(mmc, false);386 387	cqhci_writel(cq_host, CQHCI_HALT, CQHCI_CTL);388 389	err = readx_poll_timeout(cqhci_read_ctl, cq_host, reg,390				 reg & CQHCI_HALT, 0, CQHCI_OFF_TIMEOUT);391	if (err < 0)392		pr_err("%s: cqhci: CQE stuck on\n", mmc_hostname(mmc));393	else394		pr_debug("%s: cqhci: CQE off\n", mmc_hostname(mmc));395 396	if (cq_host->ops->post_disable)397		cq_host->ops->post_disable(mmc);398 399	mmc->cqe_on = false;400}401 402static void cqhci_disable(struct mmc_host *mmc)403{404	struct cqhci_host *cq_host = mmc->cqe_private;405 406	if (!cq_host->enabled)407		return;408 409	cqhci_off(mmc);410 411	__cqhci_disable(cq_host);412 413	dmam_free_coherent(mmc_dev(mmc), cq_host->data_size,414			   cq_host->trans_desc_base,415			   cq_host->trans_desc_dma_base);416 417	dmam_free_coherent(mmc_dev(mmc), cq_host->desc_size,418			   cq_host->desc_base,419			   cq_host->desc_dma_base);420 421	cq_host->trans_desc_base = NULL;422	cq_host->desc_base = NULL;423 424	cq_host->enabled = false;425}426 427static void cqhci_prep_task_desc(struct mmc_request *mrq,428				 struct cqhci_host *cq_host, int tag)429{430	__le64 *task_desc = (__le64 __force *)get_desc(cq_host, tag);431	u32 req_flags = mrq->data->flags;432	u64 desc0;433 434	desc0 = CQHCI_VALID(1) |435		CQHCI_END(1) |436		CQHCI_INT(1) |437		CQHCI_ACT(0x5) |438		CQHCI_FORCED_PROG(!!(req_flags & MMC_DATA_FORCED_PRG)) |439		CQHCI_DATA_TAG(!!(req_flags & MMC_DATA_DAT_TAG)) |440		CQHCI_DATA_DIR(!!(req_flags & MMC_DATA_READ)) |441		CQHCI_PRIORITY(!!(req_flags & MMC_DATA_PRIO)) |442		CQHCI_QBAR(!!(req_flags & MMC_DATA_QBR)) |443		CQHCI_REL_WRITE(!!(req_flags & MMC_DATA_REL_WR)) |444		CQHCI_BLK_COUNT(mrq->data->blocks) |445		CQHCI_BLK_ADDR((u64)mrq->data->blk_addr);446 447	task_desc[0] = cpu_to_le64(desc0);448 449	if (cq_host->caps & CQHCI_TASK_DESC_SZ_128) {450		u64 desc1 = cqhci_crypto_prep_task_desc(mrq);451 452		task_desc[1] = cpu_to_le64(desc1);453 454		pr_debug("%s: cqhci: tag %d task descriptor 0x%016llx%016llx\n",455			 mmc_hostname(mrq->host), mrq->tag, desc1, desc0);456	} else {457		pr_debug("%s: cqhci: tag %d task descriptor 0x%016llx\n",458			 mmc_hostname(mrq->host), mrq->tag, desc0);459	}460}461 462static int cqhci_dma_map(struct mmc_host *host, struct mmc_request *mrq)463{464	int sg_count;465	struct mmc_data *data = mrq->data;466 467	if (!data)468		return -EINVAL;469 470	sg_count = dma_map_sg(mmc_dev(host), data->sg,471			      data->sg_len,472			      (data->flags & MMC_DATA_WRITE) ?473			      DMA_TO_DEVICE : DMA_FROM_DEVICE);474	if (!sg_count) {475		pr_err("%s: sg-len: %d\n", __func__, data->sg_len);476		return -ENOMEM;477	}478 479	return sg_count;480}481 482void cqhci_set_tran_desc(u8 *desc, dma_addr_t addr, int len, bool end,483			 bool dma64)484{485	__le32 *attr = (__le32 __force *)desc;486 487	*attr = (CQHCI_VALID(1) |488		 CQHCI_END(end ? 1 : 0) |489		 CQHCI_INT(0) |490		 CQHCI_ACT(0x4) |491		 CQHCI_DAT_LENGTH(len));492 493	if (dma64) {494		__le64 *dataddr = (__le64 __force *)(desc + 4);495 496		dataddr[0] = cpu_to_le64(addr);497	} else {498		__le32 *dataddr = (__le32 __force *)(desc + 4);499 500		dataddr[0] = cpu_to_le32(addr);501	}502}503EXPORT_SYMBOL(cqhci_set_tran_desc);504 505static int cqhci_prep_tran_desc(struct mmc_request *mrq,506			       struct cqhci_host *cq_host, int tag)507{508	struct mmc_data *data = mrq->data;509	int i, sg_count, len;510	bool end = false;511	bool dma64 = cq_host->dma64;512	dma_addr_t addr;513	u8 *desc;514	struct scatterlist *sg;515 516	sg_count = cqhci_dma_map(mrq->host, mrq);517	if (sg_count < 0) {518		pr_err("%s: %s: unable to map sg lists, %d\n",519				mmc_hostname(mrq->host), __func__, sg_count);520		return sg_count;521	}522 523	desc = get_trans_desc(cq_host, tag);524 525	for_each_sg(data->sg, sg, sg_count, i) {526		addr = sg_dma_address(sg);527		len = sg_dma_len(sg);528 529		if ((i+1) == sg_count)530			end = true;531		if (cq_host->ops->set_tran_desc)532			cq_host->ops->set_tran_desc(cq_host, &desc, addr, len, end, dma64);533		else534			cqhci_set_tran_desc(desc, addr, len, end, dma64);535 536		desc += cq_host->trans_desc_len;537	}538 539	return 0;540}541 542static void cqhci_prep_dcmd_desc(struct mmc_host *mmc,543				   struct mmc_request *mrq)544{545	u64 *task_desc = NULL;546	u64 data = 0;547	u8 resp_type;548	u8 *desc;549	__le64 *dataddr;550	struct cqhci_host *cq_host = mmc->cqe_private;551	u8 timing;552 553	if (!(mrq->cmd->flags & MMC_RSP_PRESENT)) {554		resp_type = 0x0;555		timing = 0x1;556	} else {557		if (mrq->cmd->flags & MMC_RSP_R1B) {558			resp_type = 0x3;559			timing = 0x0;560		} else {561			resp_type = 0x2;562			timing = 0x1;563		}564	}565 566	task_desc = (__le64 __force *)get_desc(cq_host, cq_host->dcmd_slot);567	memset(task_desc, 0, cq_host->task_desc_len);568	data |= (CQHCI_VALID(1) |569		 CQHCI_END(1) |570		 CQHCI_INT(1) |571		 CQHCI_QBAR(1) |572		 CQHCI_ACT(0x5) |573		 CQHCI_CMD_INDEX(mrq->cmd->opcode) |574		 CQHCI_CMD_TIMING(timing) | CQHCI_RESP_TYPE(resp_type));575	if (cq_host->ops->update_dcmd_desc)576		cq_host->ops->update_dcmd_desc(mmc, mrq, &data);577	*task_desc |= data;578	desc = (u8 *)task_desc;579	pr_debug("%s: cqhci: dcmd: cmd: %d timing: %d resp: %d\n",580		 mmc_hostname(mmc), mrq->cmd->opcode, timing, resp_type);581	dataddr = (__le64 __force *)(desc + 4);582	dataddr[0] = cpu_to_le64((u64)mrq->cmd->arg);583 584}585 586static void cqhci_post_req(struct mmc_host *host, struct mmc_request *mrq)587{588	struct mmc_data *data = mrq->data;589 590	if (data) {591		dma_unmap_sg(mmc_dev(host), data->sg, data->sg_len,592			     (data->flags & MMC_DATA_READ) ?593			     DMA_FROM_DEVICE : DMA_TO_DEVICE);594	}595}596 597static inline int cqhci_tag(struct mmc_request *mrq)598{599	return mrq->cmd ? DCMD_SLOT : mrq->tag;600}601 602static int cqhci_request(struct mmc_host *mmc, struct mmc_request *mrq)603{604	int err = 0;605	int tag = cqhci_tag(mrq);606	struct cqhci_host *cq_host = mmc->cqe_private;607	unsigned long flags;608 609	if (!cq_host->enabled) {610		pr_err("%s: cqhci: not enabled\n", mmc_hostname(mmc));611		return -EINVAL;612	}613 614	/* First request after resume has to re-enable */615	if (!cq_host->activated)616		__cqhci_enable(cq_host);617 618	if (!mmc->cqe_on) {619		if (cq_host->ops->pre_enable)620			cq_host->ops->pre_enable(mmc);621 622		cqhci_writel(cq_host, 0, CQHCI_CTL);623		mmc->cqe_on = true;624		pr_debug("%s: cqhci: CQE on\n", mmc_hostname(mmc));625		if (cqhci_halted(cq_host)) {626			pr_err("%s: cqhci: CQE failed to exit halt state\n",627			       mmc_hostname(mmc));628		}629		if (cq_host->ops->enable)630			cq_host->ops->enable(mmc);631	}632 633	if (mrq->data) {634		cqhci_prep_task_desc(mrq, cq_host, tag);635 636		err = cqhci_prep_tran_desc(mrq, cq_host, tag);637		if (err) {638			pr_err("%s: cqhci: failed to setup tx desc: %d\n",639			       mmc_hostname(mmc), err);640			return err;641		}642	} else {643		cqhci_prep_dcmd_desc(mmc, mrq);644	}645 646	spin_lock_irqsave(&cq_host->lock, flags);647 648	if (cq_host->recovery_halt) {649		err = -EBUSY;650		goto out_unlock;651	}652 653	cq_host->slot[tag].mrq = mrq;654	cq_host->slot[tag].flags = 0;655 656	cq_host->qcnt += 1;657	/* Make sure descriptors are ready before ringing the doorbell */658	wmb();659	cqhci_writel(cq_host, 1 << tag, CQHCI_TDBR);660	if (!(cqhci_readl(cq_host, CQHCI_TDBR) & (1 << tag)))661		pr_debug("%s: cqhci: doorbell not set for tag %d\n",662			 mmc_hostname(mmc), tag);663out_unlock:664	spin_unlock_irqrestore(&cq_host->lock, flags);665 666	if (err)667		cqhci_post_req(mmc, mrq);668 669	return err;670}671 672static void cqhci_recovery_needed(struct mmc_host *mmc, struct mmc_request *mrq,673				  bool notify)674{675	struct cqhci_host *cq_host = mmc->cqe_private;676 677	if (!cq_host->recovery_halt) {678		cq_host->recovery_halt = true;679		pr_debug("%s: cqhci: recovery needed\n", mmc_hostname(mmc));680		wake_up(&cq_host->wait_queue);681		if (notify && mrq->recovery_notifier)682			mrq->recovery_notifier(mrq);683	}684}685 686static unsigned int cqhci_error_flags(int error1, int error2)687{688	int error = error1 ? error1 : error2;689 690	switch (error) {691	case -EILSEQ:692		return CQHCI_HOST_CRC;693	case -ETIMEDOUT:694		return CQHCI_HOST_TIMEOUT;695	default:696		return CQHCI_HOST_OTHER;697	}698}699 700static void cqhci_error_irq(struct mmc_host *mmc, u32 status, int cmd_error,701			    int data_error)702{703	struct cqhci_host *cq_host = mmc->cqe_private;704	struct cqhci_slot *slot;705	u32 terri;706	u32 tdpe;707	int tag;708 709	spin_lock(&cq_host->lock);710 711	terri = cqhci_readl(cq_host, CQHCI_TERRI);712 713	pr_debug("%s: cqhci: error IRQ status: 0x%08x cmd error %d data error %d TERRI: 0x%08x\n",714		 mmc_hostname(mmc), status, cmd_error, data_error, terri);715 716	/* Forget about errors when recovery has already been triggered */717	if (cq_host->recovery_halt)718		goto out_unlock;719 720	if (!cq_host->qcnt) {721		WARN_ONCE(1, "%s: cqhci: error when idle. IRQ status: 0x%08x cmd error %d data error %d TERRI: 0x%08x\n",722			  mmc_hostname(mmc), status, cmd_error, data_error,723			  terri);724		goto out_unlock;725	}726 727	if (CQHCI_TERRI_C_VALID(terri)) {728		tag = CQHCI_TERRI_C_TASK(terri);729		slot = &cq_host->slot[tag];730		if (slot->mrq) {731			slot->flags = cqhci_error_flags(cmd_error, data_error);732			cqhci_recovery_needed(mmc, slot->mrq, true);733		}734	}735 736	if (CQHCI_TERRI_D_VALID(terri)) {737		tag = CQHCI_TERRI_D_TASK(terri);738		slot = &cq_host->slot[tag];739		if (slot->mrq) {740			slot->flags = cqhci_error_flags(data_error, cmd_error);741			cqhci_recovery_needed(mmc, slot->mrq, true);742		}743	}744 745	/*746	 * Handle ICCE ("Invalid Crypto Configuration Error").  This should747	 * never happen, since the block layer ensures that all crypto-enabled748	 * I/O requests have a valid keyslot before they reach the driver.749	 *750	 * Note that GCE ("General Crypto Error") is different; it already got751	 * handled above by checking TERRI.752	 */753	if (status & CQHCI_IS_ICCE) {754		tdpe = cqhci_readl(cq_host, CQHCI_TDPE);755		WARN_ONCE(1,756			  "%s: cqhci: invalid crypto configuration error. IRQ status: 0x%08x TDPE: 0x%08x\n",757			  mmc_hostname(mmc), status, tdpe);758		while (tdpe != 0) {759			tag = __ffs(tdpe);760			tdpe &= ~(1 << tag);761			slot = &cq_host->slot[tag];762			if (!slot->mrq)763				continue;764			slot->flags = cqhci_error_flags(data_error, cmd_error);765			cqhci_recovery_needed(mmc, slot->mrq, true);766		}767	}768 769	if (!cq_host->recovery_halt) {770		/*771		 * The only way to guarantee forward progress is to mark at772		 * least one task in error, so if none is indicated, pick one.773		 */774		for (tag = 0; tag < NUM_SLOTS; tag++) {775			slot = &cq_host->slot[tag];776			if (!slot->mrq)777				continue;778			slot->flags = cqhci_error_flags(data_error, cmd_error);779			cqhci_recovery_needed(mmc, slot->mrq, true);780			break;781		}782	}783 784out_unlock:785	spin_unlock(&cq_host->lock);786}787 788static void cqhci_finish_mrq(struct mmc_host *mmc, unsigned int tag)789{790	struct cqhci_host *cq_host = mmc->cqe_private;791	struct cqhci_slot *slot = &cq_host->slot[tag];792	struct mmc_request *mrq = slot->mrq;793	struct mmc_data *data;794 795	if (!mrq) {796		WARN_ONCE(1, "%s: cqhci: spurious TCN for tag %d\n",797			  mmc_hostname(mmc), tag);798		return;799	}800 801	/* No completions allowed during recovery */802	if (cq_host->recovery_halt) {803		slot->flags |= CQHCI_COMPLETED;804		return;805	}806 807	slot->mrq = NULL;808 809	cq_host->qcnt -= 1;810 811	data = mrq->data;812	if (data) {813		if (data->error)814			data->bytes_xfered = 0;815		else816			data->bytes_xfered = data->blksz * data->blocks;817	}818 819	mmc_cqe_request_done(mmc, mrq);820}821 822irqreturn_t cqhci_irq(struct mmc_host *mmc, u32 intmask, int cmd_error,823		      int data_error)824{825	u32 status;826	unsigned long tag = 0, comp_status;827	struct cqhci_host *cq_host = mmc->cqe_private;828 829	status = cqhci_readl(cq_host, CQHCI_IS);830	cqhci_writel(cq_host, status, CQHCI_IS);831 832	pr_debug("%s: cqhci: IRQ status: 0x%08x\n", mmc_hostname(mmc), status);833 834	if ((status & (CQHCI_IS_RED | CQHCI_IS_GCE | CQHCI_IS_ICCE)) ||835	    cmd_error || data_error) {836		if (status & CQHCI_IS_RED)837			mmc_debugfs_err_stats_inc(mmc, MMC_ERR_CMDQ_RED);838		if (status & CQHCI_IS_GCE)839			mmc_debugfs_err_stats_inc(mmc, MMC_ERR_CMDQ_GCE);840		if (status & CQHCI_IS_ICCE)841			mmc_debugfs_err_stats_inc(mmc, MMC_ERR_CMDQ_ICCE);842		cqhci_error_irq(mmc, status, cmd_error, data_error);843	}844 845	if (status & CQHCI_IS_TCC) {846		/* read TCN and complete the request */847		comp_status = cqhci_readl(cq_host, CQHCI_TCN);848		cqhci_writel(cq_host, comp_status, CQHCI_TCN);849		pr_debug("%s: cqhci: TCN: 0x%08lx\n",850			 mmc_hostname(mmc), comp_status);851 852		spin_lock(&cq_host->lock);853 854		for_each_set_bit(tag, &comp_status, cq_host->num_slots) {855			/* complete the corresponding mrq */856			pr_debug("%s: cqhci: completing tag %lu\n",857				 mmc_hostname(mmc), tag);858			cqhci_finish_mrq(mmc, tag);859		}860 861		if (cq_host->waiting_for_idle && !cq_host->qcnt) {862			cq_host->waiting_for_idle = false;863			wake_up(&cq_host->wait_queue);864		}865 866		spin_unlock(&cq_host->lock);867	}868 869	if (status & CQHCI_IS_TCL)870		wake_up(&cq_host->wait_queue);871 872	if (status & CQHCI_IS_HAC)873		wake_up(&cq_host->wait_queue);874 875	return IRQ_HANDLED;876}877EXPORT_SYMBOL(cqhci_irq);878 879static bool cqhci_is_idle(struct cqhci_host *cq_host, int *ret)880{881	unsigned long flags;882	bool is_idle;883 884	spin_lock_irqsave(&cq_host->lock, flags);885	is_idle = !cq_host->qcnt || cq_host->recovery_halt;886	*ret = cq_host->recovery_halt ? -EBUSY : 0;887	cq_host->waiting_for_idle = !is_idle;888	spin_unlock_irqrestore(&cq_host->lock, flags);889 890	return is_idle;891}892 893static int cqhci_wait_for_idle(struct mmc_host *mmc)894{895	struct cqhci_host *cq_host = mmc->cqe_private;896	int ret;897 898	wait_event(cq_host->wait_queue, cqhci_is_idle(cq_host, &ret));899 900	return ret;901}902 903static bool cqhci_timeout(struct mmc_host *mmc, struct mmc_request *mrq,904			  bool *recovery_needed)905{906	struct cqhci_host *cq_host = mmc->cqe_private;907	int tag = cqhci_tag(mrq);908	struct cqhci_slot *slot = &cq_host->slot[tag];909	unsigned long flags;910	bool timed_out;911 912	spin_lock_irqsave(&cq_host->lock, flags);913	timed_out = slot->mrq == mrq;914	if (timed_out) {915		slot->flags |= CQHCI_EXTERNAL_TIMEOUT;916		cqhci_recovery_needed(mmc, mrq, false);917		*recovery_needed = cq_host->recovery_halt;918	}919	spin_unlock_irqrestore(&cq_host->lock, flags);920 921	if (timed_out) {922		pr_err("%s: cqhci: timeout for tag %d, qcnt %d\n",923		       mmc_hostname(mmc), tag, cq_host->qcnt);924		cqhci_dumpregs(cq_host);925	}926 927	return timed_out;928}929 930static bool cqhci_tasks_cleared(struct cqhci_host *cq_host)931{932	return !(cqhci_readl(cq_host, CQHCI_CTL) & CQHCI_CLEAR_ALL_TASKS);933}934 935static bool cqhci_clear_all_tasks(struct mmc_host *mmc, unsigned int timeout)936{937	struct cqhci_host *cq_host = mmc->cqe_private;938	bool ret;939	u32 ctl;940 941	cqhci_set_irqs(cq_host, CQHCI_IS_TCL);942 943	ctl = cqhci_readl(cq_host, CQHCI_CTL);944	ctl |= CQHCI_CLEAR_ALL_TASKS;945	cqhci_writel(cq_host, ctl, CQHCI_CTL);946 947	wait_event_timeout(cq_host->wait_queue, cqhci_tasks_cleared(cq_host),948			   msecs_to_jiffies(timeout) + 1);949 950	cqhci_set_irqs(cq_host, 0);951 952	ret = cqhci_tasks_cleared(cq_host);953 954	if (!ret)955		pr_warn("%s: cqhci: Failed to clear tasks\n",956			mmc_hostname(mmc));957 958	return ret;959}960 961static bool cqhci_halt(struct mmc_host *mmc, unsigned int timeout)962{963	struct cqhci_host *cq_host = mmc->cqe_private;964	bool ret;965	u32 ctl;966 967	if (cqhci_halted(cq_host))968		return true;969 970	cqhci_set_irqs(cq_host, CQHCI_IS_HAC);971 972	ctl = cqhci_readl(cq_host, CQHCI_CTL);973	ctl |= CQHCI_HALT;974	cqhci_writel(cq_host, ctl, CQHCI_CTL);975 976	wait_event_timeout(cq_host->wait_queue, cqhci_halted(cq_host),977			   msecs_to_jiffies(timeout) + 1);978 979	cqhci_set_irqs(cq_host, 0);980 981	ret = cqhci_halted(cq_host);982 983	if (!ret)984		pr_warn("%s: cqhci: Failed to halt\n", mmc_hostname(mmc));985 986	return ret;987}988 989/*990 * After halting we expect to be able to use the command line. We interpret the991 * failure to halt to mean the data lines might still be in use (and the upper992 * layers will need to send a STOP command), however failing to halt complicates993 * the recovery, so set a timeout that would reasonably allow I/O to complete.994 */995#define CQHCI_START_HALT_TIMEOUT	500996 997static void cqhci_recovery_start(struct mmc_host *mmc)998{999	struct cqhci_host *cq_host = mmc->cqe_private;1000 1001	pr_debug("%s: cqhci: %s\n", mmc_hostname(mmc), __func__);1002 1003	WARN_ON(!cq_host->recovery_halt);1004 1005	cqhci_halt(mmc, CQHCI_START_HALT_TIMEOUT);1006 1007	if (cq_host->ops->disable)1008		cq_host->ops->disable(mmc, true);1009 1010	mmc->cqe_on = false;1011}1012 1013static int cqhci_error_from_flags(unsigned int flags)1014{1015	if (!flags)1016		return 0;1017 1018	/* CRC errors might indicate re-tuning so prefer to report that */1019	if (flags & CQHCI_HOST_CRC)1020		return -EILSEQ;1021 1022	if (flags & (CQHCI_EXTERNAL_TIMEOUT | CQHCI_HOST_TIMEOUT))1023		return -ETIMEDOUT;1024 1025	return -EIO;1026}1027 1028static void cqhci_recover_mrq(struct cqhci_host *cq_host, unsigned int tag)1029{1030	struct cqhci_slot *slot = &cq_host->slot[tag];1031	struct mmc_request *mrq = slot->mrq;1032	struct mmc_data *data;1033 1034	if (!mrq)1035		return;1036 1037	slot->mrq = NULL;1038 1039	cq_host->qcnt -= 1;1040 1041	data = mrq->data;1042	if (data) {1043		data->bytes_xfered = 0;1044		data->error = cqhci_error_from_flags(slot->flags);1045	} else {1046		mrq->cmd->error = cqhci_error_from_flags(slot->flags);1047	}1048 1049	mmc_cqe_request_done(cq_host->mmc, mrq);1050}1051 1052static void cqhci_recover_mrqs(struct cqhci_host *cq_host)1053{1054	int i;1055 1056	for (i = 0; i < cq_host->num_slots; i++)1057		cqhci_recover_mrq(cq_host, i);1058}1059 1060/*1061 * By now the command and data lines should be unused so there is no reason for1062 * CQHCI to take a long time to halt, but if it doesn't halt there could be1063 * problems clearing tasks, so be generous.1064 */1065#define CQHCI_FINISH_HALT_TIMEOUT	201066 1067/* CQHCI could be expected to clear it's internal state pretty quickly */1068#define CQHCI_CLEAR_TIMEOUT		201069 1070static void cqhci_recovery_finish(struct mmc_host *mmc)1071{1072	struct cqhci_host *cq_host = mmc->cqe_private;1073	unsigned long flags;1074	u32 cqcfg;1075	bool ok;1076 1077	pr_debug("%s: cqhci: %s\n", mmc_hostname(mmc), __func__);1078 1079	WARN_ON(!cq_host->recovery_halt);1080 1081	ok = cqhci_halt(mmc, CQHCI_FINISH_HALT_TIMEOUT);1082 1083	/*1084	 * The specification contradicts itself, by saying that tasks cannot be1085	 * cleared if CQHCI does not halt, but if CQHCI does not halt, it should1086	 * be disabled/re-enabled, but not to disable before clearing tasks.1087	 * Have a go anyway.1088	 */1089	if (!cqhci_clear_all_tasks(mmc, CQHCI_CLEAR_TIMEOUT))1090		ok = false;1091 1092	/* Disable to make sure tasks really are cleared */1093	cqcfg = cqhci_readl(cq_host, CQHCI_CFG);1094	cqcfg &= ~CQHCI_ENABLE;1095	cqhci_writel(cq_host, cqcfg, CQHCI_CFG);1096 1097	cqcfg = cqhci_readl(cq_host, CQHCI_CFG);1098	cqcfg |= CQHCI_ENABLE;1099	cqhci_writel(cq_host, cqcfg, CQHCI_CFG);1100 1101	cqhci_halt(mmc, CQHCI_FINISH_HALT_TIMEOUT);1102 1103	if (!ok)1104		cqhci_clear_all_tasks(mmc, CQHCI_CLEAR_TIMEOUT);1105 1106	cqhci_recover_mrqs(cq_host);1107 1108	WARN_ON(cq_host->qcnt);1109 1110	spin_lock_irqsave(&cq_host->lock, flags);1111	cq_host->qcnt = 0;1112	cq_host->recovery_halt = false;1113	mmc->cqe_on = false;1114	spin_unlock_irqrestore(&cq_host->lock, flags);1115 1116	/* Ensure all writes are done before interrupts are re-enabled */1117	wmb();1118 1119	cqhci_writel(cq_host, CQHCI_IS_HAC | CQHCI_IS_TCL, CQHCI_IS);1120 1121	cqhci_set_irqs(cq_host, CQHCI_IS_MASK);1122 1123	pr_debug("%s: cqhci: recovery done\n", mmc_hostname(mmc));1124}1125 1126static const struct mmc_cqe_ops cqhci_cqe_ops = {1127	.cqe_enable = cqhci_enable,1128	.cqe_disable = cqhci_disable,1129	.cqe_request = cqhci_request,1130	.cqe_post_req = cqhci_post_req,1131	.cqe_off = cqhci_off,1132	.cqe_wait_for_idle = cqhci_wait_for_idle,1133	.cqe_timeout = cqhci_timeout,1134	.cqe_recovery_start = cqhci_recovery_start,1135	.cqe_recovery_finish = cqhci_recovery_finish,1136};1137 1138struct cqhci_host *cqhci_pltfm_init(struct platform_device *pdev)1139{1140	struct cqhci_host *cq_host;1141	struct resource *cqhci_memres = NULL;1142 1143	/* check and setup CMDQ interface */1144	cqhci_memres = platform_get_resource_byname(pdev, IORESOURCE_MEM,1145						   "cqhci");1146	if (!cqhci_memres) {1147		dev_dbg(&pdev->dev, "CMDQ not supported\n");1148		return ERR_PTR(-EINVAL);1149	}1150 1151	cq_host = devm_kzalloc(&pdev->dev, sizeof(*cq_host), GFP_KERNEL);1152	if (!cq_host)1153		return ERR_PTR(-ENOMEM);1154	cq_host->mmio = devm_ioremap(&pdev->dev,1155				     cqhci_memres->start,1156				     resource_size(cqhci_memres));1157	if (!cq_host->mmio) {1158		dev_err(&pdev->dev, "failed to remap cqhci regs\n");1159		return ERR_PTR(-EBUSY);1160	}1161	dev_dbg(&pdev->dev, "CMDQ ioremap: done\n");1162 1163	return cq_host;1164}1165EXPORT_SYMBOL(cqhci_pltfm_init);1166 1167static unsigned int cqhci_ver_major(struct cqhci_host *cq_host)1168{1169	return CQHCI_VER_MAJOR(cqhci_readl(cq_host, CQHCI_VER));1170}1171 1172static unsigned int cqhci_ver_minor(struct cqhci_host *cq_host)1173{1174	u32 ver = cqhci_readl(cq_host, CQHCI_VER);1175 1176	return CQHCI_VER_MINOR1(ver) * 10 + CQHCI_VER_MINOR2(ver);1177}1178 1179int cqhci_init(struct cqhci_host *cq_host, struct mmc_host *mmc,1180	      bool dma64)1181{1182	int err;1183 1184	cq_host->dma64 = dma64;1185	cq_host->mmc = mmc;1186	cq_host->mmc->cqe_private = cq_host;1187 1188	cq_host->num_slots = NUM_SLOTS;1189	cq_host->dcmd_slot = DCMD_SLOT;1190 1191	mmc->cqe_ops = &cqhci_cqe_ops;1192 1193	mmc->cqe_qdepth = NUM_SLOTS;1194	if (mmc->caps2 & MMC_CAP2_CQE_DCMD)1195		mmc->cqe_qdepth -= 1;1196 1197	cq_host->slot = devm_kcalloc(mmc_dev(mmc), cq_host->num_slots,1198				     sizeof(*cq_host->slot), GFP_KERNEL);1199	if (!cq_host->slot) {1200		err = -ENOMEM;1201		goto out_err;1202	}1203 1204	err = cqhci_crypto_init(cq_host);1205	if (err) {1206		pr_err("%s: CQHCI crypto initialization failed\n",1207		       mmc_hostname(mmc));1208		goto out_err;1209	}1210 1211	spin_lock_init(&cq_host->lock);1212 1213	init_completion(&cq_host->halt_comp);1214	init_waitqueue_head(&cq_host->wait_queue);1215 1216	pr_info("%s: CQHCI version %u.%02u\n",1217		mmc_hostname(mmc), cqhci_ver_major(cq_host),1218		cqhci_ver_minor(cq_host));1219 1220	return 0;1221 1222out_err:1223	pr_err("%s: CQHCI version %u.%02u failed to initialize, error %d\n",1224	       mmc_hostname(mmc), cqhci_ver_major(cq_host),1225	       cqhci_ver_minor(cq_host), err);1226	return err;1227}1228EXPORT_SYMBOL(cqhci_init);1229 1230MODULE_AUTHOR("Venkat Gopalakrishnan <venkatg@codeaurora.org>");1231MODULE_DESCRIPTION("Command Queue Host Controller Interface driver");1232MODULE_LICENSE("GPL v2");1233