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

Marek Vasut
2014-03-24T21:14:02Z

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 <henrik@henriknordstrom.net>
> Signed-off-by: Luke Leighton <lkcl@lkcl.net>
> Signed-off-by: Oliver Schinagl <oliver@schinagl.nl>
> Signed-off-by: Wills Wang <wills.wang.open@gmail.com>
> Signed-off-by: Ian Campbell <ijc@hellion.org.uk>
> Cc: Pantelis Antoniou <panto@antoniou-consulting.com>
[...]

> +
> +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 = 0xfffff;
> +
> + 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 = 0xfffff;
> + }
> + } 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 = 0xfffff;

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 ... ). …