On Sat, Apr 30, 2016 at 09:50:15PM +0200, Mark Kettenis wrote:
> The diff below adds support for changing the bus width to the sdmmc
> subsystem and the sdhc(4) controller.  By default controllers and card
> use a 1-bit bus.  But most SD cards actually have support fora 4-bit
> bus.  This can be checked by looking atthe SCR register.  In theory
> using the 4-bit bus quadruples the data rate to and from the card.
> 
> With this diff the raw disk transferrate of the sdhc(4) controller in
> te PC-Engines APU2 goes up from 1.5 MB/s to 5.5 MB/s.
> 
> ok?

diff below for imx/omap.

imx sdhc fails with 

sdmmc0: SD_SEND_SCR send failed
sdmmc0: mem init failed
scsibus2 at sdmmc0: 2 targets, initiator 0
sd1 at scsibus2 targ 1 lun 0: <SD/MMC, Drive #01, > SCSI2 0/direct fixed
sd1: 7655MB, 512 bytes/sector, 15677440 sectors

but it is known to have errors sending block io commands
so perhaps that isn't so surprising.

Index: imx/imxesdhc.c
===================================================================
RCS file: /cvs/src/sys/arch/armv7/imx/imxesdhc.c,v
retrieving revision 1.13
diff -u -p -r1.13 imxesdhc.c
--- imx/imxesdhc.c      10 Jan 2016 14:11:43 -0000      1.13
+++ imx/imxesdhc.c      1 May 2016 03:23:06 -0000
@@ -124,6 +124,9 @@
 #define SDHC_MIX_CTRL_AC12EN                   (1 << 2)
 #define SDHC_MIX_CTRL_DTDSEL                   (1 << 4)
 #define SDHC_MIX_CTRL_MSBSEL                   (1 << 5)
+#define SDHC_PROT_CTRL_DTW_MASK                        (0x3 << 1)
+#define SDHC_PROT_CTRL_DTW_4BIT                        (1 << 1)
+#define SDHC_PROT_CTRL_DTW_8BIT                        (1 << 2)
 #define SDHC_PROT_CTRL_DMASEL_SDMA_MASK                (0x3 << 8)
 #define SDHC_HOST_CTRL_CAP_MBL_SHIFT           16
 #define SDHC_HOST_CTRL_CAP_MBL_MASK            0x7
@@ -196,6 +199,7 @@ int imxesdhc_host_maxblklen(sdmmc_chipse
 int    imxesdhc_card_detect(sdmmc_chipset_handle_t);
 int    imxesdhc_bus_power(sdmmc_chipset_handle_t, uint32_t);
 int    imxesdhc_bus_clock(sdmmc_chipset_handle_t, int);
+int    imxesdhc_bus_width(sdmmc_chipset_handle_t, int);
 void   imxesdhc_card_intr_mask(sdmmc_chipset_handle_t, int);
 void   imxesdhc_card_intr_ack(sdmmc_chipset_handle_t);
 void   imxesdhc_exec_command(sdmmc_chipset_handle_t, struct sdmmc_command *);
@@ -226,6 +230,7 @@ struct sdmmc_chip_functions imxesdhc_fun
        /* bus power and clock frequency */
        imxesdhc_bus_power,
        imxesdhc_bus_clock,
+       imxesdhc_bus_width,
        /* command execution */
        imxesdhc_exec_command,
        /* card interrupt */
@@ -598,6 +603,30 @@ imxesdhc_bus_clock(sdmmc_chipset_handle_
 ret:
        splx(s);
        return error;
+}
+
+int
+imxesdhc_bus_width(sdmmc_chipset_handle_t sch, int width)
+{
+       struct imxesdhc_softc *sc = sch;
+       uint32_t reg;
+       int s;
+
+       if (width != 1 && width != 4 && width != 8)
+               return (1);
+
+       s = splsdmmc();
+
+       reg = HREAD4(sc, SDHC_PROT_CTRL) & ~SDHC_PROT_CTRL_DTW_MASK;
+       if (width == 4)
+               reg |= SDHC_PROT_CTRL_DTW_4BIT;
+       else if (width == 8)
+               reg |= SDHC_PROT_CTRL_DTW_8BIT;
+       HWRITE4(sc, SDHC_PROT_CTRL, reg);
+
+       splx(s);
+
+       return (0);
 }
 
 void
Index: omap/ommmc.c
===================================================================
RCS file: /cvs/src/sys/arch/armv7/omap/ommmc.c,v
retrieving revision 1.15
diff -u -p -r1.15 ommmc.c
--- omap/ommmc.c        10 Jan 2016 14:11:43 -0000      1.15
+++ omap/ommmc.c        1 May 2016 03:23:07 -0000
@@ -229,6 +229,7 @@ int ommmc_host_maxblklen(sdmmc_chipset_h
 int    ommmc_card_detect(sdmmc_chipset_handle_t);
 int    ommmc_bus_power(sdmmc_chipset_handle_t, uint32_t);
 int    ommmc_bus_clock(sdmmc_chipset_handle_t, int);
+int    ommmc_bus_width(sdmmc_chipset_handle_t, int);
 void   ommmc_card_intr_mask(sdmmc_chipset_handle_t, int);
 void   ommmc_card_intr_ack(sdmmc_chipset_handle_t);
 void   ommmc_exec_command(sdmmc_chipset_handle_t, struct sdmmc_command *);
@@ -260,6 +261,7 @@ struct sdmmc_chip_functions ommmc_functi
        /* bus power and clock frequency */
        ommmc_bus_power,
        ommmc_bus_clock,
+       ommmc_bus_width,
        /* command execution */
        ommmc_exec_command,
        /* card interrupt */
@@ -693,6 +695,29 @@ ommmc_bus_clock(sdmmc_chipset_handle_t s
 ret:
        splx(s);
        return (error);
+}
+
+int
+ommmc_bus_width(sdmmc_chipset_handle_t sch, int width)
+{
+       struct ommmc_softc *sc = sch;
+       int s;
+
+       if (width != 1 && width != 4 && width != 8)
+               return (1);
+
+       s = splsdmmc();
+
+       if (width == 8)
+               /* 8 bit */
+               HSET4(sc, MMCHS_CON, MMCHS_CON_DW8);
+       else
+               /* 1 or 4 bit */
+               HCLR4(sc, MMCHS_CON, MMCHS_CON_DW8);
+
+       splx(s);
+
+       return (0);
 }
 
 void

Reply via email to