Skip to content

Commit

Permalink
mmc: sunxi: fix endianness issues
Browse files Browse the repository at this point in the history
The MMC device in Allwinner SoCs uses an internal DMA controller, which
gets its information from DMA descriptors in normal memory. The device
expects the values in there to be in little-endian format.
Since we use normal memory accesses to fill those DMA descriptors, we
must wrap write accesses to these descriptors with cpu_to_le32() calls to
make sure they land in memory in the expected byte order.

This allows the MMC device to be used with big-endian kernels.
Tested on BananaPi(arm) and Pine64(arm64) with both big-endian and
little-endian kernels.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
  • Loading branch information
Andre-ARM committed Jun 27, 2016
1 parent 66fd2ad commit a85d748
Showing 1 changed file with 11 additions and 10 deletions.
21 changes: 11 additions & 10 deletions drivers/mmc/host/sunxi-mmc.c
Expand Up @@ -203,13 +203,14 @@
* Bits 26-31: not used * Bits 26-31: not used
* Since we only ever set buf1 size, we can simply store it directly. * Since we only ever set buf1 size, we can simply store it directly.
*/ */
#define SDXC_IDMAC_DES0_DIC BIT(1) /* disable interrupt on completion */ #define LE32_BIT(n) (cpu_to_le32(BIT(n)))
#define SDXC_IDMAC_DES0_LD BIT(2) /* last descriptor */ #define SDXC_IDMAC_DES0_DIC LE32_BIT(1) /* disable interrupt on completion*/
#define SDXC_IDMAC_DES0_FD BIT(3) /* first descriptor */ #define SDXC_IDMAC_DES0_LD LE32_BIT(2) /* last descriptor */
#define SDXC_IDMAC_DES0_CH BIT(4) /* chain mode */ #define SDXC_IDMAC_DES0_FD LE32_BIT(3) /* first descriptor */
#define SDXC_IDMAC_DES0_ER BIT(5) /* end of ring */ #define SDXC_IDMAC_DES0_CH LE32_BIT(4) /* chain mode */
#define SDXC_IDMAC_DES0_CES BIT(30) /* card error summary */ #define SDXC_IDMAC_DES0_ER LE32_BIT(5) /* end of ring */
#define SDXC_IDMAC_DES0_OWN BIT(31) /* 1-idma owns it, 0-host owns it */ #define SDXC_IDMAC_DES0_CES LE32_BIT(30) /* card error summary */
#define SDXC_IDMAC_DES0_OWN LE32_BIT(31) /* 1-idma owns it, 0-host owns it*/


#define SDXC_CLK_400K 0 #define SDXC_CLK_400K 0
#define SDXC_CLK_25M 1 #define SDXC_CLK_25M 1
Expand Down Expand Up @@ -331,11 +332,11 @@ static void sunxi_mmc_init_idma_des(struct sunxi_mmc_host *host,
if (data->sg[i].length == max_len) if (data->sg[i].length == max_len)
pdes[i].buf_size = 0; /* 0 == max_len */ pdes[i].buf_size = 0; /* 0 == max_len */
else else
pdes[i].buf_size = data->sg[i].length; pdes[i].buf_size = cpu_to_le32(data->sg[i].length);


next_desc += sizeof(struct sunxi_idma_des); next_desc += sizeof(struct sunxi_idma_des);
pdes[i].buf_addr_ptr1 = sg_dma_address(&data->sg[i]); pdes[i].buf_addr_ptr1 = cpu_to_le32(sg_dma_address(&data->sg[i]));
pdes[i].buf_addr_ptr2 = (u32)next_desc; pdes[i].buf_addr_ptr2 = cpu_to_le32(next_desc);
} }


pdes[0].config |= SDXC_IDMAC_DES0_FD; pdes[0].config |= SDXC_IDMAC_DES0_FD;
Expand Down

0 comments on commit a85d748

Please sign in to comment.