From owner-svn-src-head@freebsd.org Sat May 12 13:13:35 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 28779FDB031; Sat, 12 May 2018 13:13:35 +0000 (UTC) (envelope-from manu@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id CEC8E847A7; Sat, 12 May 2018 13:13:34 +0000 (UTC) (envelope-from manu@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id B07A61ED42; Sat, 12 May 2018 13:13:34 +0000 (UTC) (envelope-from manu@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w4CDDYAJ060327; Sat, 12 May 2018 13:13:34 GMT (envelope-from manu@FreeBSD.org) Received: (from manu@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w4CDDYAv060326; Sat, 12 May 2018 13:13:34 GMT (envelope-from manu@FreeBSD.org) Message-Id: <201805121313.w4CDDYAv060326@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: manu set sender to manu@FreeBSD.org using -f From: Emmanuel Vadot Date: Sat, 12 May 2018 13:13:34 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r333555 - head/sys/arm/allwinner X-SVN-Group: head X-SVN-Commit-Author: manu X-SVN-Commit-Paths: head/sys/arm/allwinner X-SVN-Commit-Revision: 333555 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 12 May 2018 13:13:35 -0000 Author: manu Date: Sat May 12 13:13:34 2018 New Revision: 333555 URL: https://svnweb.freebsd.org/changeset/base/333555 Log: aw_mmc: Do not fully init the controller in attach Only do a reset of the controller at attach and init it at power_up. We use to enable some interrupts in reset, only enable the interrupts we are interested in when doing a request. While here remove the regulators handling in power_on as it is very wrong and will be dealt with in another commit. Tested on: A31, A64 Modified: head/sys/arm/allwinner/aw_mmc.c head/sys/arm/allwinner/aw_mmc.h Modified: head/sys/arm/allwinner/aw_mmc.c ============================================================================== --- head/sys/arm/allwinner/aw_mmc.c Sat May 12 13:12:59 2018 (r333554) +++ head/sys/arm/allwinner/aw_mmc.c Sat May 12 13:13:34 2018 (r333555) @@ -140,6 +140,7 @@ static int aw_mmc_attach(device_t); static int aw_mmc_detach(device_t); static int aw_mmc_setup_dma(struct aw_mmc_softc *); static int aw_mmc_reset(struct aw_mmc_softc *); +static int aw_mmc_init(struct aw_mmc_softc *); static void aw_mmc_intr(void *); static int aw_mmc_update_clock(struct aw_mmc_softc *, uint32_t); @@ -475,18 +476,37 @@ aw_mmc_reset(struct aw_mmc_softc *sc) if (timeout == 0) return (ETIMEDOUT); + return (0); +} + +static int +aw_mmc_init(struct aw_mmc_softc *sc) +{ + int ret; + + ret = aw_mmc_reset(sc); + if (ret != 0) + return (ret); + /* Set the timeout. */ AW_MMC_WRITE_4(sc, AW_MMC_TMOR, AW_MMC_TMOR_DTO_LMT_SHIFT(AW_MMC_TMOR_DTO_LMT_MASK) | AW_MMC_TMOR_RTO_LMT_SHIFT(AW_MMC_TMOR_RTO_LMT_MASK)); + /* Unmask interrupts. */ + AW_MMC_WRITE_4(sc, AW_MMC_IMKR, 0); + /* Clear pending interrupts. */ AW_MMC_WRITE_4(sc, AW_MMC_RISR, 0xffffffff); + + /* Debug register, undocumented */ + AW_MMC_WRITE_4(sc, AW_MMC_DBGC, 0xdeb); + + /* Function select register */ + AW_MMC_WRITE_4(sc, AW_MMC_FUNS, 0xceaa0000); + AW_MMC_WRITE_4(sc, AW_MMC_IDST, 0xffffffff); - /* Unmask interrupts. */ - AW_MMC_WRITE_4(sc, AW_MMC_IMKR, - AW_MMC_INT_CMD_DONE | AW_MMC_INT_ERR_BIT | - AW_MMC_INT_DATA_OVER | AW_MMC_INT_AUTO_STOP_DONE); + /* Enable interrupts and AHB access. */ AW_MMC_WRITE_4(sc, AW_MMC_GCTL, AW_MMC_READ_4(sc, AW_MMC_GCTL) | AW_MMC_CTRL_INT_ENB); @@ -655,7 +675,7 @@ aw_mmc_request(device_t bus, device_t child, struct mm int blksz; struct aw_mmc_softc *sc; struct mmc_command *cmd; - uint32_t cmdreg; + uint32_t cmdreg, imask; int err; sc = device_get_softc(bus); @@ -664,11 +684,19 @@ aw_mmc_request(device_t bus, device_t child, struct mm AW_MMC_UNLOCK(sc); return (EBUSY); } + sc->aw_req = req; cmd = req->cmd; cmdreg = AW_MMC_CMDR_LOAD; + imask = AW_MMC_INT_ERR_BIT; + sc->aw_intr_wait = 0; + sc->aw_intr = 0; + sc->aw_resid = 0; + cmd->error = MMC_ERR_NONE; + if (cmd->opcode == MMC_GO_IDLE_STATE) cmdreg |= AW_MMC_CMDR_SEND_INIT_SEQ; + if (cmd->flags & MMC_RSP_PRESENT) cmdreg |= AW_MMC_CMDR_RESP_RCV; if (cmd->flags & MMC_RSP_136) @@ -676,30 +704,52 @@ aw_mmc_request(device_t bus, device_t child, struct mm if (cmd->flags & MMC_RSP_CRC) cmdreg |= AW_MMC_CMDR_CHK_RESP_CRC; - sc->aw_intr = 0; - sc->aw_resid = 0; - sc->aw_intr_wait = AW_MMC_INT_CMD_DONE; - cmd->error = MMC_ERR_NONE; - if (cmd->data != NULL) { - sc->aw_intr_wait |= AW_MMC_INT_DATA_OVER; + if (cmd->data) { cmdreg |= AW_MMC_CMDR_DATA_TRANS | AW_MMC_CMDR_WAIT_PRE_OVER; + if (cmd->data->flags & MMC_DATA_MULTI) { cmdreg |= AW_MMC_CMDR_STOP_CMD_FLAG; + imask |= AW_MMC_INT_AUTO_STOP_DONE; sc->aw_intr_wait |= AW_MMC_INT_AUTO_STOP_DONE; + } else { + sc->aw_intr_wait |= AW_MMC_INT_DATA_OVER; + imask |= AW_MMC_INT_DATA_OVER; } if (cmd->data->flags & MMC_DATA_WRITE) cmdreg |= AW_MMC_CMDR_DIR_WRITE; + blksz = min(cmd->data->len, MMC_SECTOR_SIZE); AW_MMC_WRITE_4(sc, AW_MMC_BKSR, blksz); AW_MMC_WRITE_4(sc, AW_MMC_BYCR, cmd->data->len); + } else { + imask |= AW_MMC_INT_CMD_DONE; + } + /* Enable the interrupts we are interested in */ + AW_MMC_WRITE_4(sc, AW_MMC_IMKR, imask); + AW_MMC_WRITE_4(sc, AW_MMC_RISR, 0xffffffff); + + /* Enable auto stop if needed */ + AW_MMC_WRITE_4(sc, AW_MMC_A12A, + cmdreg & AW_MMC_CMDR_STOP_CMD_FLAG ? 0 : 0xffff); + + /* Write the command argument */ + AW_MMC_WRITE_4(sc, AW_MMC_CAGR, cmd->arg); + + /* + * If we don't have data start the request + * if we do prepare the dma request and start the request + */ + if (cmd->data == NULL) { + AW_MMC_WRITE_4(sc, AW_MMC_CMDR, cmdreg | cmd->opcode); + } else { err = aw_mmc_prepare_dma(sc); if (err != 0) device_printf(sc->aw_dev, "prepare_dma failed: %d\n", err); + + AW_MMC_WRITE_4(sc, AW_MMC_CMDR, cmdreg | cmd->opcode); } - AW_MMC_WRITE_4(sc, AW_MMC_CAGR, cmd->arg); - AW_MMC_WRITE_4(sc, AW_MMC_CMDR, cmdreg | cmd->opcode); callout_reset(&sc->aw_timeoutc, sc->aw_timeout * hz, aw_mmc_timeout, sc); AW_MMC_UNLOCK(sc); @@ -914,16 +964,20 @@ aw_mmc_update_ios(device_t bus, device_t child) break; } - /* Set the voltage */ - if (ios->power_mode == power_off) { + switch (ios->power_mode) { + case power_on: + break; + case power_off: if (bootverbose) device_printf(sc->aw_dev, "Powering down sd/mmc\n"); - if (sc->aw_reg_vmmc) - regulator_disable(sc->aw_reg_vmmc); - if (sc->aw_reg_vqmmc) - regulator_disable(sc->aw_reg_vqmmc); - } else if (sc->aw_vdd != ios->vdd) - aw_mmc_set_power(sc, ios->vdd); + aw_mmc_reset(sc); + break; + case power_up: + if (bootverbose) + device_printf(sc->aw_dev, "Powering up sd/mmc\n"); + aw_mmc_init(sc); + break; + }; /* Enable ddr mode if needed */ reg = AW_MMC_READ_4(sc, AW_MMC_GCTL); Modified: head/sys/arm/allwinner/aw_mmc.h ============================================================================== --- head/sys/arm/allwinner/aw_mmc.h Sat May 12 13:12:59 2018 (r333554) +++ head/sys/arm/allwinner/aw_mmc.h Sat May 12 13:13:34 2018 (r333555) @@ -47,6 +47,7 @@ #define AW_MMC_STAR 0x3C /* Status Register */ #define AW_MMC_FWLR 0x40 /* FIFO Threshold Watermark Register */ #define AW_MMC_FUNS 0x44 /* Function Select Register */ +#define AW_MMC_DBGC 0x50 /* Debug register */ #define AW_MMC_CSDC 0x54 /* CRC status detect controler register (A64 smhc2 only) */ #define AW_MMC_A12A 0x58 /* Auto command 12 argument register */ #define AW_MMC_NTSR 0x5C /* SD new timing register (H3, A64 smhc0/1 only) */