Date: Wed, 10 Apr 2019 19:53:36 +0000 (UTC) From: Ilya Bakulin <kibab@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r346098 - in head/sys: arm/allwinner dev/sdhci Message-ID: <201904101953.x3AJra1Y028818@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kibab Date: Wed Apr 10 19:53:36 2019 New Revision: 346098 URL: https://svnweb.freebsd.org/changeset/base/346098 Log: Implement CMD53 block mode support for SDHCI and AllWinner-based boards If a custom block size requested, use it, otherwise revert to the previous logic of using just a data size if it's less than MMC_BLOCK_SIZE, and MMC_BLOCK_SIZE otherwise. Reviewed by: bz Approved by: imp (mentor) Differential Revision: https://reviews.freebsd.org/D19783 Modified: head/sys/arm/allwinner/aw_mmc.c head/sys/dev/sdhci/sdhci.c Modified: head/sys/arm/allwinner/aw_mmc.c ============================================================================== --- head/sys/arm/allwinner/aw_mmc.c Wed Apr 10 19:49:35 2019 (r346097) +++ head/sys/arm/allwinner/aw_mmc.c Wed Apr 10 19:53:36 2019 (r346098) @@ -1104,10 +1104,17 @@ aw_mmc_request(device_t bus, device_t child, struct mm } 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); +#ifdef MMCCAM + if (cmd->data->flags & MMC_DATA_BLOCK_SIZE) { + AW_MMC_WRITE_4(sc, AW_MMC_BKSR, cmd->data->block_size); + AW_MMC_WRITE_4(sc, AW_MMC_BYCR, cmd->data->len); + } else +#endif + { + 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; } Modified: head/sys/dev/sdhci/sdhci.c ============================================================================== --- head/sys/dev/sdhci/sdhci.c Wed Apr 10 19:49:35 2019 (r346097) +++ head/sys/dev/sdhci/sdhci.c Wed Apr 10 19:53:36 2019 (r346098) @@ -496,7 +496,13 @@ sdhci_read_block_pio(struct sdhci_slot *slot) buffer = slot->curcmd->data->data; buffer += slot->offset; /* Transfer one block at a time. */ - left = min(512, slot->curcmd->data->len - slot->offset); +#ifdef MMCCAM + if (slot->curcmd->data->flags & MMC_DATA_BLOCK_SIZE) + left = min(slot->curcmd->data->block_size, + slot->curcmd->data->len - slot->offset); + else +#endif + left = min(512, slot->curcmd->data->len - slot->offset); slot->offset += left; /* If we are too fast, broken controllers return zeroes. */ @@ -539,7 +545,13 @@ sdhci_write_block_pio(struct sdhci_slot *slot) buffer = slot->curcmd->data->data; buffer += slot->offset; /* Transfer one block at a time. */ - left = min(512, slot->curcmd->data->len - slot->offset); +#ifdef MMCCAM + if (slot->curcmd->data->flags & MMC_DATA_BLOCK_SIZE) { + left = min(slot->curcmd->data->block_size, + slot->curcmd->data->len - slot->offset); + } else +#endif + left = min(512, slot->curcmd->data->len - slot->offset); slot->offset += left; /* Handle unaligned and aligned buffer cases. */ @@ -1623,9 +1635,9 @@ sdhci_set_transfer_mode(struct sdhci_slot *slot, const return; mode = SDHCI_TRNS_BLK_CNT_EN; - if (data->len > 512) { + if (data->len > 512 || data->block_count > 1) { mode |= SDHCI_TRNS_MULTI; - if (__predict_true( + if (data->block_count == 0 && __predict_true( #ifdef MMCCAM slot->ccb->mmcio.stop.opcode == MMC_STOP_TRANSMISSION && #else @@ -1888,11 +1900,23 @@ sdhci_start_data(struct sdhci_slot *slot, const struct } /* Current data offset for both PIO and DMA. */ slot->offset = 0; - /* Set block size and request border interrupts on the SDMA boundary. */ - blksz = SDHCI_MAKE_BLKSZ(slot->sdma_boundary, ulmin(data->len, 512)); +#ifdef MMCCAM + if (data->flags & MMC_DATA_BLOCK_SIZE) { + /* Set block size and request border interrupts on the SDMA boundary. */ + blksz = SDHCI_MAKE_BLKSZ(slot->sdma_boundary, data->block_size); + blkcnt = data->block_count; + if (__predict_false(sdhci_debug > 0)) + slot_printf(slot, "SDIO Custom block params: blksz: " + "%#10x, blk cnt: %#10x\n", blksz, blkcnt); + } else +#endif + { + /* Set block size and request border interrupts on the SDMA boundary. */ + blksz = SDHCI_MAKE_BLKSZ(slot->sdma_boundary, ulmin(data->len, 512)); + blkcnt = howmany(data->len, 512); + } + WR2(slot, SDHCI_BLOCK_SIZE, blksz); - /* Set block count. */ - blkcnt = howmany(data->len, 512); WR2(slot, SDHCI_BLOCK_COUNT, blkcnt); if (__predict_false(sdhci_debug > 1)) slot_printf(slot, "Blk size: 0x%08x | Blk cnt: 0x%08x\n", @@ -2781,10 +2805,13 @@ sdhci_cam_request(struct sdhci_slot *slot, union ccb * } */ if (__predict_false(sdhci_debug > 1)) { - slot_printf(slot, "CMD%u arg %#x flags %#x dlen %u dflags %#x\n", - mmcio->cmd.opcode, mmcio->cmd.arg, mmcio->cmd.flags, - mmcio->cmd.data != NULL ? (unsigned int) mmcio->cmd.data->len : 0, - mmcio->cmd.data != NULL ? mmcio->cmd.data->flags: 0); + slot_printf(slot, "CMD%u arg %#x flags %#x dlen %u dflags %#x " + "blksz=%zu blkcnt=%zu\n", + mmcio->cmd.opcode, mmcio->cmd.arg, mmcio->cmd.flags, + mmcio->cmd.data != NULL ? (unsigned int) mmcio->cmd.data->len : 0, + mmcio->cmd.data != NULL ? mmcio->cmd.data->flags : 0, + mmcio->cmd.data != NULL ? mmcio->cmd.data->block_size : 0, + mmcio->cmd.data != NULL ? mmcio->cmd.data->block_count : 0); } if (mmcio->cmd.data != NULL) { if (mmcio->cmd.data->len == 0 || mmcio->cmd.data->flags == 0)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201904101953.x3AJra1Y028818>