Re: 0001-Fix-CQE-task-queue-timeout.patch
From: Adrian Hunter
Date: Wed Jul 01 2020 - 05:57:52 EST
On 22/06/20 8:44 am, chen jiangnan wrote:
> FromÂ547e5635c04f4f9d62cbc1e3a4b4527f87c4e83bÂMonÂSepÂ17Â00:00:00Â2001
> From:ÂJiangnanChenÂ<chen.jiangnan@xxxxxxxxxxxxxx>
> Date:ÂMon,Â22ÂJunÂ2020Â05:32:21Â+0000
> Subject:Â[PATCH]ÂFixÂCQEÂtaskÂqueueÂtimeout.ÂCQEÂnotifiesÂtheÂsoftwareÂthat
Please separate subject from commit message.
> ÂtaskÂhasÂcompletedÂthroughÂtaskÂcompletionÂnotificationÂ(TCN),ÂbutÂsomeÂCQE
> ÂwillÂoccasionallyÂmarkÂtheÂtaskÂinÂtheÂpendingÂstateÂ(viaÂDPT).ÂAtÂthisÂtime,
> ÂifÂaÂQBRÂtaskÂ(suchÂasÂflushÂcache)ÂisÂfollowed,ÂtheÂentireÂcommandÂqueue
> ÂwillÂbeÂblocked,ÂcausingÂtheÂmmcÂsubsystemÂtoÂreportÂaÂtimeoutÂerror,ÂandÂcqe
> ÂentersÂtheÂrecoveryÂprocess.
It seems like this is a workaround for broken HW, so you could create a quirk for
this, but making use of the ->write_l host op is cleaner for cqhci.
e.g. in your driver, for the broken controller set cqhci_host_ops write_l to use
the following:
static void ???_cqhci_writel(struct cqhci_host *cq_host, u32 val, int reg)
{
writel_relaxed(val, cq_host->mmio + reg);
if (reg == CQHCI_TCN) {
u32 pend_status = cqhci_readl(cq_host, CQHCI_DPT);
if (val & pend_status) {
pr_debug("%s: cqhci conflict: TCN: 0x%08lx DPT: 0x%08lx\n",
mmc_hostname(cq_host->mmc), val, pend_status);
cqhci_writel(cq_host, val & pend_status, CQHCI_TCLR);
}
}
}
>
> Signed-off-by:ÂJiangnanChenÂ<chen.jiangnan@xxxxxxxxxxxxxx>
> ---
> Âdrivers/mmc/host/cqhci.cÂ|Â9Â++++++++-
> Â1ÂfileÂchanged,Â8Âinsertions(+),Â1Âdeletion(-)
>
> diffÂ--gitÂa/drivers/mmc/host/cqhci.cÂb/drivers/mmc/host/cqhci.c
> indexÂ75934f3c117e..b8c7f6119ac4Â100644
> ---Âa/drivers/mmc/host/cqhci.c
> +++Âb/drivers/mmc/host/cqhci.c
> @@Â-760,7Â+760,7Â@@Âirqreturn_tÂcqhci_irq(structÂmmc_hostÂ*mmc,Âu32Âintmask,ÂintÂcmd_error,
> ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂintÂdata_error)
> Â{
> ÂÂÂÂÂÂÂÂu32Âstatus;
> -ÂÂÂÂÂÂÂunsignedÂlongÂtagÂ=Â0,Âcomp_status;
> +ÂÂÂÂÂÂÂunsignedÂlongÂtagÂ=Â0,Âcomp_status,Âpend_status;
> ÂÂÂÂÂÂÂÂstructÂcqhci_hostÂ*cq_hostÂ=Âmmc->cqe_private;
> Â
> ÂÂÂÂÂÂÂÂstatusÂ=Âcqhci_readl(cq_host,ÂCQHCI_IS);
> @@Â-778,6Â+778,13Â@@Âirqreturn_tÂcqhci_irq(structÂmmc_hostÂ*mmc,Âu32Âintmask,ÂintÂcmd_error,
> ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂpr_debug("%s:Âcqhci:ÂTCN:Â0x%08lx\n",
> ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂmmc_hostname(mmc),Âcomp_status);
> Â
> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂpend_statusÂ=Âcqhci_readl(cq_host,ÂCQHCI_DPT);
> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂifÂ(comp_statusÂ&Âpend_status)Â{
> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂpr_debug("%s:ÂcqhciÂconflict:ÂTCN:Â0x%08lxÂDPT:Â0x%08lx\n",
> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂmmc_hostname(mmc),Âcomp_status,Âpend_status);
> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂcqhci_writel(cq_host,Âcomp_statusÂ&Âpend_status,ÂCQHCI_TCLR);
> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ}
> +
> ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂspin_lock(&cq_host->lock);
> Â
> ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂfor_each_set_bit(tag,Â&comp_status,Âcq_host->num_slots)Â{
> --Â
> 2.17.1