From patchwork Tue Apr 10 12:17:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 133078 Delivered-To: patch@linaro.org Received: by 10.46.84.29 with SMTP id i29csp1240411ljb; Tue, 10 Apr 2018 05:24:02 -0700 (PDT) X-Google-Smtp-Source: AIpwx49+Rz7wG1LEnkO1FxKciv3eifWubpio5r1ITB6JudaGYC3dBfvy46PgR/0eycWEDkYaKXoF X-Received: by 10.55.159.17 with SMTP id i17mr255734qke.162.1523363042461; Tue, 10 Apr 2018 05:24:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1523363042; cv=none; d=google.com; s=arc-20160816; b=d3Jes6v+E6StqoFOBq98H/6e8CB8GdluPuyqyKjGRxcyPqjB2Vn+1R7Y3/H0LUcal2 eVd93ONhWgdpKthLWewEUyarcRCAzi+vCQM3k+VCBabmnkjDflTWzVfmzSvFZs4W5BOn 5RH3RopZzrXsJ6fgqltht0dOYS6rNR+OkxRJdZJj4UtE4wiYL7D21G0I5IlmT16MPMNs mPTGcS/Rol46+H15tXEHlPCMYRKb8lj9Dm3IRZeiCpUTrjJZgCzh2l0Egs/llp9TJ/W7 AI31AtMZk3eVUZ+pTlN5nnPCJYnF0afKekvJPkf1whn2lHy0cqcHGpEgwDX0lztVhWXs uQSQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:arc-authentication-results; bh=pQ58w1nkV0G5md0yLOv7gIVBJluO8lgw0mtybEghFuM=; b=xFekrATXxa7bANqkcGEb/tPZy/kdjqQabanKEQl+EeLOHWMUMdmF9K6Avcur99viKN m4g9k2JmezvIyXZ761wRUrEbXpwWR21uJgiNfPWsL63bLpNgNVOctWLJciN3jPUXbGJi Z83EaY3T6WiQoF7Z3g4S3rxVpKui6DPqAyCmmM+jTwS8SgM34DnJV3YHimGyCtDPHVxD R2DtdED+QQ/OJQykMFBescKHV6mo2ajwjHOZdNEQztGWA2LOJ6QmF8rCyezLiYWqzPk/ FFsR3jGc+AgNLkcUlpVSFe6IC5vC7UBvUMNjAzVyC7hJTrXiaPItT3Mk7VUIVzF3PuOm zftw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id m18si3248290qtb.22.2018.04.10.05.24.02 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 10 Apr 2018 05:24:02 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:40602 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f5sJd-0003so-Pp for patch@linaro.org; Tue, 10 Apr 2018 08:24:01 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56950) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f5sDT-0007v9-MM for qemu-devel@nongnu.org; Tue, 10 Apr 2018 08:17:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1f5sDS-0000kB-Iq for qemu-devel@nongnu.org; Tue, 10 Apr 2018 08:17:39 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:40762) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1f5sDS-0000iH-Av for qemu-devel@nongnu.org; Tue, 10 Apr 2018 08:17:38 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1f5sDK-0007bH-7T for qemu-devel@nongnu.org; Tue, 10 Apr 2018 13:17:30 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Tue, 10 Apr 2018 13:17:17 +0100 Message-Id: <20180410121724.8549-6-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180410121724.8549-1-peter.maydell@linaro.org> References: <20180410121724.8549-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 05/12] hw/sd/bcm2835_sdhost: Don't raise spurious interrupts X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" The Linux bcm2835_sdhost driver doesn't work on QEMU, because our model raises spurious data interrupts. Our function bcm2835_sdhost_fifo_run() will flag an interrupt any time it is called with s->datacnt == 0, even if the host hasn't actually issued a data read or write command yet. This means that the driver gets a spurious data interrupt as soon as it enables IRQs and then does something else that causes us to call the fifo_run routine, like writing to SDHCFG, and before it does the write to SDCMD to issue the read. The driver's IRQ handler then spins forever complaining that there's no data and the SD controller isn't in a state where there's going to be any data: [ 41.040738] sdhost-bcm2835 3f202000.mmc: fsm 1, hsts 00000000 [ 41.042059] sdhost-bcm2835 3f202000.mmc: fsm 1, hsts 00000000 (continues forever). Move the interrupt flag setting to more plausible places: * for BUSY, raise this as soon as a BUSYWAIT command has executed * for DATA, raise this when the FIFO has any space free (for a write) or any data in it (for a read) * for BLOCK, raise this when the data count is 0 and we've actually done some reading or writing This is pure guesswork since the documentation for this hardware is not public, but it is sufficient to get the Linux bcm2835_sdhost driver to work. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Tested-by: Gerd Hoffmann Message-id: 20180319161556.16446-3-peter.maydell@linaro.org --- hw/sd/bcm2835_sdhost.c | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) -- 2.16.2 diff --git a/hw/sd/bcm2835_sdhost.c b/hw/sd/bcm2835_sdhost.c index 79f3c5ceeb..ebf3b926c2 100644 --- a/hw/sd/bcm2835_sdhost.c +++ b/hw/sd/bcm2835_sdhost.c @@ -137,6 +137,12 @@ static void bcm2835_sdhost_send_command(BCM2835SDHostState *s) } #undef RWORD } + /* We never really delay commands, so if this was a 'busywait' command + * then we've completed it now and can raise the interrupt. + */ + if ((s->cmd & SDCMD_BUSYWAIT) && (s->config & SDHCFG_BUSY_IRPT_EN)) { + s->status |= SDHSTS_BUSY_IRPT; + } return; error: @@ -187,18 +193,27 @@ static void bcm2835_sdhost_fifo_run(BCM2835SDHostState *s) n++; if (n == 4) { bcm2835_sdhost_fifo_push(s, value); + s->status |= SDHSTS_DATA_FLAG; + if (s->config & SDHCFG_DATA_IRPT_EN) { + s->status |= SDHSTS_SDIO_IRPT; + } n = 0; value = 0; } } if (n != 0) { bcm2835_sdhost_fifo_push(s, value); + s->status |= SDHSTS_DATA_FLAG; } } else { /* write */ n = 0; while (s->datacnt > 0 && (s->fifo_len > 0 || n > 0)) { if (n == 0) { value = bcm2835_sdhost_fifo_pop(s); + s->status |= SDHSTS_DATA_FLAG; + if (s->config & SDHCFG_DATA_IRPT_EN) { + s->status |= SDHSTS_SDIO_IRPT; + } n = 4; } n--; @@ -207,28 +222,19 @@ static void bcm2835_sdhost_fifo_run(BCM2835SDHostState *s) value >>= 8; } } + if (s->datacnt == 0) { + s->edm &= ~SDEDM_FSM_MASK; + s->edm |= SDEDM_FSM_DATAMODE; + trace_bcm2835_sdhost_edm_change("datacnt 0", s->edm); + + if ((s->cmd & SDCMD_WRITE_CMD) && + (s->config & SDHCFG_BLOCK_IRPT_EN)) { + s->status |= SDHSTS_BLOCK_IRPT; + } + } } - if (s->datacnt == 0) { - s->status |= SDHSTS_DATA_FLAG; - s->edm &= ~0xf; - s->edm |= SDEDM_FSM_DATAMODE; - trace_bcm2835_sdhost_edm_change("datacnt 0", s->edm); - - if (s->config & SDHCFG_DATA_IRPT_EN) { - s->status |= SDHSTS_SDIO_IRPT; - } - - if ((s->cmd & SDCMD_BUSYWAIT) && (s->config & SDHCFG_BUSY_IRPT_EN)) { - s->status |= SDHSTS_BUSY_IRPT; - } - - if ((s->cmd & SDCMD_WRITE_CMD) && (s->config & SDHCFG_BLOCK_IRPT_EN)) { - s->status |= SDHSTS_BLOCK_IRPT; - } - - bcm2835_sdhost_update_irq(s); - } + bcm2835_sdhost_update_irq(s); s->edm &= ~(0x1f << 4); s->edm |= ((s->fifo_len & 0x1f) << 4);