From owner-svn-src-head@FreeBSD.ORG Tue Jan 20 09:07:31 2015 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id CEA69CC4; Tue, 20 Jan 2015 09:07:31 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id AD293CE8; Tue, 20 Jan 2015 09:07:31 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t0K97ViZ088132; Tue, 20 Jan 2015 09:07:31 GMT (envelope-from ganbold@FreeBSD.org) Received: (from ganbold@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t0K97TNV088122; Tue, 20 Jan 2015 09:07:29 GMT (envelope-from ganbold@FreeBSD.org) Message-Id: <201501200907.t0K97TNV088122@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: ganbold set sender to ganbold@FreeBSD.org using -f From: Ganbold Tsagaankhuu Date: Tue, 20 Jan 2015 09:07:29 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r277413 - in head/sys: arm/conf arm/rockchip boot/fdt/dts/arm dev/mmc/host X-SVN-Group: head 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.18-1 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: Tue, 20 Jan 2015 09:07:32 -0000 Author: ganbold Date: Tue Jan 20 09:07:28 2015 New Revision: 277413 URL: https://svnweb.freebsd.org/changeset/base/277413 Log: Enable Synopsys DesignWare Mobile Storage Host Controller driver on Rockchip boards. It currently supports PIO mode and dma mode needs external dma controller to be used. Submitted by: jmcneill Approved by: stas (mentor) Modified: head/sys/arm/conf/RK3188 head/sys/arm/rockchip/files.rk30xx head/sys/boot/fdt/dts/arm/rk3188-radxa-lite.dts head/sys/boot/fdt/dts/arm/rk3188-radxa.dts head/sys/boot/fdt/dts/arm/rk3188.dtsi head/sys/dev/mmc/host/dwmmc.c head/sys/dev/mmc/host/dwmmc.h Modified: head/sys/arm/conf/RK3188 ============================================================================== --- head/sys/arm/conf/RK3188 Tue Jan 20 05:44:21 2015 (r277412) +++ head/sys/arm/conf/RK3188 Tue Jan 20 09:07:28 2015 (r277413) @@ -76,8 +76,9 @@ options DIAGNOSTIC options ROOTDEVNAME=\"ufs:/dev/da0s2\" # MMC/SD/SDIO Card slot support -#device mmc # mmc/sd bus -#device mmcsd # mmc/sd flash cards +device mmc # mmc/sd bus +device mmcsd # mmc/sd flash cards +device dwmmc # Console and misc device uart Modified: head/sys/arm/rockchip/files.rk30xx ============================================================================== --- head/sys/arm/rockchip/files.rk30xx Tue Jan 20 05:44:21 2015 (r277412) +++ head/sys/arm/rockchip/files.rk30xx Tue Jan 20 09:07:28 2015 (r277413) @@ -19,3 +19,5 @@ arm/rockchip/rk30xx_grf.c standard arm/rockchip/rk30xx_wdog.c standard arm/rockchip/rk30xx_gpio.c optional gpio arm/rockchip/rk30xx_mp.c optional smp + +dev/mmc/host/dwmmc.c optional dwmmc Modified: head/sys/boot/fdt/dts/arm/rk3188-radxa-lite.dts ============================================================================== --- head/sys/boot/fdt/dts/arm/rk3188-radxa-lite.dts Tue Jan 20 05:44:21 2015 (r277412) +++ head/sys/boot/fdt/dts/arm/rk3188-radxa-lite.dts Tue Jan 20 09:07:28 2015 (r277413) @@ -48,6 +48,10 @@ status = "okay"; }; + mmc@10214000 { + status = "okay"; + }; + }; chosen { Modified: head/sys/boot/fdt/dts/arm/rk3188-radxa.dts ============================================================================== --- head/sys/boot/fdt/dts/arm/rk3188-radxa.dts Tue Jan 20 05:44:21 2015 (r277412) +++ head/sys/boot/fdt/dts/arm/rk3188-radxa.dts Tue Jan 20 09:07:28 2015 (r277413) @@ -48,6 +48,10 @@ status = "okay"; }; + mmc@10214000 { + status = "okay"; + }; + }; chosen { Modified: head/sys/boot/fdt/dts/arm/rk3188.dtsi ============================================================================== --- head/sys/boot/fdt/dts/arm/rk3188.dtsi Tue Jan 20 05:44:21 2015 (r277412) +++ head/sys/boot/fdt/dts/arm/rk3188.dtsi Tue Jan 20 09:07:28 2015 (r277413) @@ -231,22 +231,26 @@ }; mmc@10214000 { - compatible = "rockchip,rk30xx-mmc"; + compatible = "rockchip,rk2928-dw-mshc"; reg = <0x10214000 0x1000>; interrupts = <55>; #address-cells = <1>; #size-cells = <0>; - clock-frequency = <24000000>; /* TODO: verify freq */ + bus-frequency = <48000000>; /* TODO: verify freq */ + fifo-depth = <0x40>; + num-slots = <1>; status = "disabled"; }; mmc@10218000 { - compatible = "rockchip,rk30xx-mmc"; + compatible = "rockchip,rk2928-dw-mshc"; reg = <0x10218000 0x1000>; interrupts = <56>; #address-cells = <1>; #size-cells = <0>; - clock-frequency = <24000000>; /* TODO: verify freq */ + bus-frequency = <48000000>; /* TODO: verify freq */ + fifo-depth = <0x40>; + num-slots = <1>; status = "disabled"; }; }; Modified: head/sys/dev/mmc/host/dwmmc.c ============================================================================== --- head/sys/dev/mmc/host/dwmmc.c Tue Jan 20 05:44:21 2015 (r277412) +++ head/sys/dev/mmc/host/dwmmc.c Tue Jan 20 09:07:28 2015 (r277413) @@ -129,6 +129,8 @@ struct dwmmc_softc { uint32_t flags; uint32_t hwtype; uint32_t use_auto_stop; + uint32_t use_pio; + uint32_t pwren_inverted; bus_dma_tag_t desc_tag; bus_dmamap_t desc_map; @@ -152,6 +154,8 @@ static void dwmmc_next_operation(struct static int dwmmc_setup_bus(struct dwmmc_softc *, int); static int dma_done(struct dwmmc_softc *, struct mmc_command *); static int dma_stop(struct dwmmc_softc *); +static void pio_read(struct dwmmc_softc *, struct mmc_command *); +static void pio_write(struct dwmmc_softc *, struct mmc_command *); static struct resource_spec dwmmc_spec[] = { { SYS_RES_MEMORY, 0, RF_ACTIVE }, @@ -163,6 +167,7 @@ enum { HWTYPE_NONE, HWTYPE_ALTERA, HWTYPE_EXYNOS, + HWTYPE_ROCKCHIP, }; #define HWTYPE_MASK (0x0000ffff) @@ -171,6 +176,7 @@ enum { static struct ofw_compat_data compat_data[] = { {"altr,socfpga-dw-mshc", HWTYPE_ALTERA}, {"samsung,exynos5420-dw-mshc", HWTYPE_EXYNOS}, + {"rockchip,rk2928-dw-mshc", HWTYPE_ROCKCHIP}, {NULL, HWTYPE_NONE}, }; @@ -395,8 +401,10 @@ dwmmc_intr(void *arg) dprintf("data err 0x%08x cmd 0x%08x\n", reg, cmd->opcode); cmd->error = MMC_ERR_FAILED; - dma_done(sc, cmd); - dma_stop(sc); + if (!sc->use_pio) { + dma_done(sc, cmd); + dma_stop(sc); + } } if (reg & SDMMC_INTMASK_CMD_DONE) { @@ -421,15 +429,24 @@ dwmmc_intr(void *arg) } } - /* Now handle DMA interrupts */ - reg = READ4(sc, SDMMC_IDSTS); - if (reg) { - dprintf("dma intr 0x%08x\n", reg); - if (reg & (SDMMC_IDINTEN_TI | SDMMC_IDINTEN_RI)) { - WRITE4(sc, SDMMC_IDSTS, (SDMMC_IDINTEN_TI | - SDMMC_IDINTEN_RI)); - WRITE4(sc, SDMMC_IDSTS, SDMMC_IDINTEN_NI); - dma_done(sc, cmd); + if (sc->use_pio) { + if (reg & (SDMMC_INTMASK_RXDR|SDMMC_INTMASK_DTO)) { + pio_read(sc, cmd); + } + if (reg & (SDMMC_INTMASK_TXDR|SDMMC_INTMASK_DTO)) { + pio_write(sc, cmd); + } + } else { + /* Now handle DMA interrupts */ + reg = READ4(sc, SDMMC_IDSTS); + if (reg) { + dprintf("dma intr 0x%08x\n", reg); + if (reg & (SDMMC_IDINTEN_TI | SDMMC_IDINTEN_RI)) { + WRITE4(sc, SDMMC_IDSTS, (SDMMC_IDINTEN_TI | + SDMMC_IDINTEN_RI)); + WRITE4(sc, SDMMC_IDSTS, SDMMC_IDINTEN_NI); + dma_done(sc, cmd); + } } } @@ -560,17 +577,29 @@ dwmmc_attach(device_t dev) device_printf(dev, "Hardware version ID is %04x\n", READ4(sc, SDMMC_VERID) & 0xffff); - WRITE4(sc, EMMCP_MPSBEGIN0, 0); - WRITE4(sc, EMMCP_SEND0, 0); - WRITE4(sc, EMMCP_CTRL0, (MPSCTRL_SECURE_READ_BIT | - MPSCTRL_SECURE_WRITE_BIT | - MPSCTRL_NON_SECURE_READ_BIT | - MPSCTRL_NON_SECURE_WRITE_BIT | - MPSCTRL_VALID)); + sc->use_pio = 0; + sc->pwren_inverted = 0; + + if ((sc->hwtype & HWTYPE_MASK) == HWTYPE_ROCKCHIP) { + sc->use_pio = 1; + sc->pwren_inverted = 1; + } else { + WRITE4(sc, EMMCP_MPSBEGIN0, 0); + WRITE4(sc, EMMCP_SEND0, 0); + WRITE4(sc, EMMCP_CTRL0, (MPSCTRL_SECURE_READ_BIT | + MPSCTRL_SECURE_WRITE_BIT | + MPSCTRL_NON_SECURE_READ_BIT | + MPSCTRL_NON_SECURE_WRITE_BIT | + MPSCTRL_VALID)); + } /* XXX: we support operation for slot index 0 only */ slot = 0; - WRITE4(sc, SDMMC_PWREN, (1 << slot)); + if (sc->pwren_inverted) { + WRITE4(sc, SDMMC_PWREN, (0 << slot)); + } else { + WRITE4(sc, SDMMC_PWREN, (1 << slot)); + } /* Reset all */ if (dwmmc_ctrl_reset(sc, (SDMMC_CTRL_RESET | @@ -580,17 +609,19 @@ dwmmc_attach(device_t dev) dwmmc_setup_bus(sc, sc->host.f_min); - if (dma_setup(sc)) - return (ENXIO); - - /* Install desc base */ - WRITE4(sc, SDMMC_DBADDR, sc->desc_ring_paddr); - - /* Enable DMA interrupts */ - WRITE4(sc, SDMMC_IDSTS, SDMMC_IDINTEN_MASK); - WRITE4(sc, SDMMC_IDINTEN, (SDMMC_IDINTEN_NI | - SDMMC_IDINTEN_RI | - SDMMC_IDINTEN_TI)); + if (!sc->use_pio) { + if (dma_setup(sc)) + return (ENXIO); + + /* Install desc base */ + WRITE4(sc, SDMMC_DBADDR, sc->desc_ring_paddr); + + /* Enable DMA interrupts */ + WRITE4(sc, SDMMC_IDSTS, SDMMC_IDINTEN_MASK); + WRITE4(sc, SDMMC_IDINTEN, (SDMMC_IDINTEN_NI | + SDMMC_IDINTEN_RI | + SDMMC_IDINTEN_TI)); + } /* Clear and disable interrups for a while */ WRITE4(sc, SDMMC_RINTSTS, 0xffffffff); @@ -797,6 +828,79 @@ dma_prepare(struct dwmmc_softc *sc, stru return (0); } +static int +pio_prepare(struct dwmmc_softc *sc, struct mmc_command *cmd) +{ + struct mmc_data *data; + int reg; + + data = cmd->data; + data->xfer_len = 0; + + reg = (DEF_MSIZE << SDMMC_FIFOTH_MSIZE_S); + reg |= ((sc->fifo_depth / 2) - 1) << SDMMC_FIFOTH_RXWMARK_S; + reg |= (sc->fifo_depth / 2) << SDMMC_FIFOTH_TXWMARK_S; + + WRITE4(sc, SDMMC_FIFOTH, reg); + wmb(); + + return (0); +} + +static void +pio_read(struct dwmmc_softc *sc, struct mmc_command *cmd) +{ + struct mmc_data *data; + uint32_t *p, status; + + if (cmd == NULL || cmd->data == NULL) + return; + + data = cmd->data; + if ((data->flags & MMC_DATA_READ) == 0) + return; + + KASSERT((data->xfer_len & 3) == 0, ("xfer_len not aligned")); + p = (uint32_t *)data->data + (data->xfer_len >> 2); + + while (data->xfer_len < data->len) { + status = READ4(sc, SDMMC_STATUS); + if (status & SDMMC_STATUS_FIFO_EMPTY) + break; + *p++ = READ4(sc, SDMMC_DATA); + data->xfer_len += 4; + } + + WRITE4(sc, SDMMC_RINTSTS, SDMMC_INTMASK_RXDR); +} + +static void +pio_write(struct dwmmc_softc *sc, struct mmc_command *cmd) +{ + struct mmc_data *data; + uint32_t *p, status; + + if (cmd == NULL || cmd->data == NULL) + return; + + data = cmd->data; + if ((data->flags & MMC_DATA_WRITE) == 0) + return; + + KASSERT((data->xfer_len & 3) == 0, ("xfer_len not aligned")); + p = (uint32_t *)data->data + (data->xfer_len >> 2); + + while (data->xfer_len < data->len) { + status = READ4(sc, SDMMC_STATUS); + if (status & SDMMC_STATUS_FIFO_FULL) + break; + WRITE4(sc, SDMMC_DATA, *p++); + data->xfer_len += 4; + } + + WRITE4(sc, SDMMC_RINTSTS, SDMMC_INTMASK_TXDR); +} + static void dwmmc_start_cmd(struct dwmmc_softc *sc, struct mmc_command *cmd) { @@ -807,6 +911,9 @@ dwmmc_start_cmd(struct dwmmc_softc *sc, sc->curcmd = cmd; data = cmd->data; + if ((sc->hwtype & HWTYPE_MASK) == HWTYPE_ROCKCHIP) + dwmmc_setup_bus(sc, sc->host.ios.clock); + /* XXX Upper layers don't always set this */ cmd->mrq = sc->req; @@ -861,7 +968,11 @@ dwmmc_start_cmd(struct dwmmc_softc *sc, data->len : MMC_SECTOR_SIZE; WRITE4(sc, SDMMC_BLKSIZ, blksz); - dma_prepare(sc, cmd); + if (sc->use_pio) { + pio_prepare(sc, cmd); + } else { + dma_prepare(sc, cmd); + } wmb(); } Modified: head/sys/dev/mmc/host/dwmmc.h ============================================================================== --- head/sys/dev/mmc/host/dwmmc.h Tue Jan 20 05:44:21 2015 (r277412) +++ head/sys/dev/mmc/host/dwmmc.h Tue Jan 20 09:07:28 2015 (r277413) @@ -91,6 +91,8 @@ #define SDMMC_RINTSTS 0x44 /* Raw Interrupt Status Register */ #define SDMMC_STATUS 0x48 /* Status Register */ #define SDMMC_STATUS_DATA_BUSY (1 << 9) /* card_data[0] */ +#define SDMMC_STATUS_FIFO_FULL (1 << 3) /* FIFO full */ +#define SDMMC_STATUS_FIFO_EMPTY (1 << 2) /* FIFO empty */ #define SDMMC_FIFOTH 0x4C /* FIFO Threshold Watermark Register */ #define SDMMC_FIFOTH_MSIZE_S 28 /* Burst size of multiple transaction */ #define SDMMC_FIFOTH_RXWMARK_S 16 /* FIFO threshold watermark level */