[U-Boot] [PATCH v2 8/9] sunxi: mmc support

2014-03-21 Thread Ian Campbell
As well as the following signed-off-by the sunxi branch shows commits to these
files authored by the following:
  Stefan Roese
  Tom Cubie
  yemao

Signed-off-by: Henrik Nordstrom 
Signed-off-by: Luke Leighton 
Signed-off-by: Oliver Schinagl 
Signed-off-by: Wills Wang 
Signed-off-by: Ian Campbell 
Cc: Pantelis Antoniou 
---
Pantelis, most of your review comments have been addressed but not all, in
particular the timeout loops aren't sorted yet, but I wanted to get the rest of
the series reposted.

v2: Based on u-boot-sunxi.git#sunxi d9aa5dd3d15c "sunxi: mmc:
checkpatch whitespace fixes" with v2014.04-rc2 merged in:
  - use proper gpio interfaces, removing awkward casts and some magic numbers.
  - remove magic numbers
  - other cleanups

v1: Based on linux-sunxi#sunxi commit d854c4de2f57 "arm: Handle .gnu.hash
section in ldscripts" vs v2014.01.
---
 arch/arm/include/asm/arch-sunxi/mmc.h | 124 +++
 board/sunxi/board.c   |  13 +
 drivers/mmc/Makefile  |   1 +
 drivers/mmc/sunxi_mmc.c   | 625 ++
 include/configs/sunxi-common.h|  11 +
 5 files changed, 774 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-sunxi/mmc.h
 create mode 100644 drivers/mmc/sunxi_mmc.c

diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h 
b/arch/arm/include/asm/arch-sunxi/mmc.h
new file mode 100644
index 000..97b14c3
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/mmc.h
@@ -0,0 +1,124 @@
+/*
+ * (C) Copyright 2007-2011
+ * Allwinner Technology Co., Ltd. 
+ * Aaron 
+ *
+ * MMC register definition for allwinner sunxi platform.
+ *
+ * SPDX-License-Identifier:GPL-2.0+
+ */
+
+#ifndef _SUNXI_MMC_H
+#define _SUNXI_MMC_H
+
+#include 
+
+struct sunxi_mmc {
+   u32 gctrl;  /* (0x00) SMC Global Control Register */
+   u32 clkcr;  /* (0x04) SMC Clock Control Register */
+   u32 timeout;/* (0x08) SMC Time Out Register */
+   u32 width;  /* (0x0c) SMC Bus Width Register */
+   u32 blksz;  /* (0x10) SMC Block Size Register */
+   u32 bytecnt;/* (0x14) SMC Byte Count Register */
+   u32 cmd;/* (0x18) SMC Command Register */
+   u32 arg;/* (0x1c) SMC Argument Register */
+   u32 resp0;  /* (0x20) SMC Response Register 0 */
+   u32 resp1;  /* (0x24) SMC Response Register 1 */
+   u32 resp2;  /* (0x28) SMC Response Register 2 */
+   u32 resp3;  /* (0x2c) SMC Response Register 3 */
+   u32 imask;  /* (0x30) SMC Interrupt Mask Register */
+   u32 mint;   /* (0x34) SMC Masked Interrupt Status Reg */
+   u32 rint;   /* (0x38) SMC Raw Interrupt Status Register */
+   u32 status; /* (0x3c) SMC Status Register */
+   u32 ftrglevel;  /* (0x40) SMC FIFO Threshold Watermark Reg */
+   u32 funcsel;/* (0x44) SMC Function Select Register */
+   u32 cbcr;   /* (0x48) SMC CIU Byte Count Register */
+   u32 bbcr;   /* (0x4c) SMC BIU Byte Count Register */
+   u32 dbgc;   /* (0x50) SMC Debug Enable Register */
+   u32 res0[11];   /* (0x54~0x7c) */
+   u32 dmac;   /* (0x80) SMC IDMAC Control Register */
+   u32 dlba;   /* (0x84) SMC IDMAC Descr List Base Addr Reg */
+   u32 idst;   /* (0x88) SMC IDMAC Status Register */
+   u32 idie;   /* (0x8c) SMC IDMAC Interrupt Enable Register */
+   u32 chda;   /* (0x90) */
+   u32 cbda;   /* (0x94) */
+   u32 res1[26];   /* (0x98~0xff) */
+   u32 fifo;   /* (0x100) SMC FIFO Access Address */
+};
+
+#define SUNXI_MMC_CLK_POWERSAVE(0x1 << 17)
+#define SUNXI_MMC_CLK_ENABLE   (0x1 << 16)
+#define SUNXI_MMC_CLK_DIVIDER_MASK (0xff)
+
+#define SUNXI_MMC_GCTRL_SOFT_RESET (0x1 << 0)
+#define SUNXI_MMC_GCTRL_FIFO_RESET (0x1 << 1)
+#define SUNXI_MMC_GCTRL_DMA_RESET  (0x1 << 2)
+#define SUNXI_MMC_GCTRL_RESET  (SUNXI_MMC_GCTRL_SOFT_RESET|\
+SUNXI_MMC_GCTRL_FIFO_RESET|\
+SUNXI_MMC_GCTRL_DMA_RESET)
+#define SUNXI_MMC_GCTRL_DMA_ENABLE (0x1 << 5)
+#define SUNXI_MMC_GCTRL_ACCESS_BY_AHB   (0x1 << 31)
+
+#define SUNXI_MMC_CMD_RESP_EXPIRE  (0x1 << 6)
+#define SUNXI_MMC_CMD_LONG_RESPONSE(0x1 << 7)
+#define SUNXI_MMC_CMD_CHK_RESPONSE_CRC (0x1 << 8)
+#define SUNXI_MMC_CMD_DATA_EXPIRE  (0x1 << 9)
+#define SUNXI_MMC_CMD_WRITE(0x1 << 10)
+#define SUNXI_MMC_CMD_AUTO_STOP(0x1 << 12)
+#define SUNXI_MMC_CMD_WAIT_PRE_OVER(0x1 << 13)
+#define SUNXI_MMC_CMD_SEND_INIT_SEQ(0x1 << 15)
+#define SUNXI_MMC_CMD_UPCLK_ONLY   (0x1 << 21)
+#define SUNXI_MMC_CMD_START(0x1 << 31)
+
+#define SUNXI_MMC_RINT_RESP

Re: [U-Boot] [PATCH v2 8/9] sunxi: mmc support

2014-03-24 Thread Marek Vasut
On Friday, March 21, 2014 at 10:54:25 PM, Ian Campbell wrote:
> As well as the following signed-off-by the sunxi branch shows commits to
> these files authored by the following:
>   Stefan Roese
>   Tom Cubie
>   yemao
> 
> Signed-off-by: Henrik Nordstrom 
> Signed-off-by: Luke Leighton 
> Signed-off-by: Oliver Schinagl 
> Signed-off-by: Wills Wang 
> Signed-off-by: Ian Campbell 
> Cc: Pantelis Antoniou 
[...]

> +
> +static void dumphex32(char *name, char *base, int len)
> +{
> + __u32 i;
> +
> + debug("dump %s registers:", name);
> + for (i = 0; i < len; i += 4) {
> + if (!(i & 0xf))
> + debug("\n0x%p : ", base + i);
> + debug("0x%08x ", readl(base + i));
> + }
> + debug("\n");
> +}

Looks like print_hex_dump() reimplementation ...

[...]

> +static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data)
> +{
> + struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv;
> + unsigned i;
> + unsigned byte_cnt = data->blocksize * data->blocks;
> + unsigned *buff;
> + unsigned timeout = 0xf;
> +
> + if (data->flags & MMC_DATA_READ) {
> + buff = (unsigned int *)data->dest;
> + for (i = 0; i < (byte_cnt >> 2); i++) {
> + while (--timeout &&
> +(readl(&mmchost->reg->status) &
> + SUNXI_MMC_STATUS_FIFO_EMPTY))
> + ;
> + if (timeout <= 0)
> + goto out;
> + buff[i] = readl(mmchost->database);
> + timeout = 0xf;
> + }
> + } else {
> + buff = (unsigned int *)data->src;
> + for (i = 0; i < (byte_cnt >> 2); i++) {
> + while (--timeout &&
> +(readl(&mmchost->reg->status) &
> + SUNXI_MMC_STATUS_FIFO_FULL))
> + ;
> + if (timeout <= 0)
> + goto out;
> + writel(buff[i], mmchost->database);
> + timeout = 0xf;

Are these two branches almost the same ? Why not just clear that up by 
squashing 
them into one with a small if (...) at the begining of this function ?

[...]

> +static int mmc_trans_data_by_dma(struct mmc *mmc, struct mmc_data *data)
> +{
> + struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv;
> + unsigned byte_cnt = data->blocksize * data->blocks;
> + unsigned char *buff;
> + unsigned des_idx = 0;
> + unsigned buff_frag_num =
> + (byte_cnt + SDXC_DES_BUFFER_MAX_LEN - 1) >> SDXC_DES_NUM_SHIFT;
> + unsigned remain;
> + unsigned i, rval;
> + ALLOC_CACHE_ALIGN_BUFFER(struct sunxi_mmc_des, pdes, buff_frag_num);
> +
> + buff = data->flags & MMC_DATA_READ ?
> + (unsigned char *)data->dest : (unsigned char *)data->src;
> + remain = byte_cnt & (SDXC_DES_BUFFER_MAX_LEN - 1);
> + if (!remain)
> + remain = SDXC_DES_BUFFER_MAX_LEN;
> +
> + flush_cache((unsigned long)buff, (unsigned long)byte_cnt);
> + for (i = 0; i < buff_frag_num; i++, des_idx++) {
> + memset((void *)&pdes[des_idx], 0, sizeof(struct sunxi_mmc_des));
> + pdes[des_idx].des_chain = 1;
> + pdes[des_idx].own = 1;
> + pdes[des_idx].dic = 1;
> + if (buff_frag_num > 1 && i != buff_frag_num - 1)
> + pdes[des_idx].data_buf1_sz =
> + (SDXC_DES_BUFFER_MAX_LEN -
> +  1) & SDXC_DES_BUFFER_MAX_LEN;
> + else
> + pdes[des_idx].data_buf1_sz = remain;
> +
> + pdes[des_idx].buf_addr_ptr1 =
> + (u32) buff + i * SDXC_DES_BUFFER_MAX_LEN;
> + if (i == 0)
> + pdes[des_idx].first_des = 1;
> +
> + if (i == buff_frag_num - 1) {
> + pdes[des_idx].dic = 0;
> + pdes[des_idx].last_des = 1;
> + pdes[des_idx].end_of_ring = 1;
> + pdes[des_idx].buf_addr_ptr2 = 0;
> + } else {
> + pdes[des_idx].buf_addr_ptr2 = (u32)&pdes[des_idx + 1];
> + }
> + debug("frag %d, remain %d, des[%d](%08x): ",
> +   i, remain, des_idx, (u32)&pdes[des_idx]);
> + debug("[0] = %08x, [1] = %08x, [2] = %08x, [3] = %08x\n",
> +   (u32)((u32 *)&pdes[des_idx])[0],
> +   (u32)((u32 *)&pdes[des_idx])[1],
> +   (u32)((u32 *)&pdes[des_idx])[2],
> +   (u32)((u32 *)&pdes[des_idx])[3]);

Yum, this pointer voodoo looks tasty (and ready for fixing up ... ).
[...]
___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot