> Date: Sun, 1 May 2016 13:40:31 +1000
> From: Jonathan Gray <[email protected]>
> 
> 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.

What type of card are you using?

In any case, the SD_SEND_SCR command does rely on block io, so if that
doesn't work reliably, then it isn't too surprising that things fail.

The omap code looks wrong.  As far as I can see there is a DTW bit
there as well to switch between 1-bit and 4-bit mode.

> 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