On Fri, 2014-03-14 at 17:36 +0200, Pantelis Antoniou wrote:
> [...]

Thanks for your review. It seems there are still quite a few issues
dating back to the original allwinner dumps here.

@linux-sunxi: if anyone wants to volunteer to help cleanup this
particular driver I'd be very happy -- there's a lot of it!

> +
> > +static void dumpmmcreg(struct sunxi_mmc *reg)
> > +{
> > +   debug("dump mmc registers:\n");
> > +   debug("gctrl     0x%08x\n", reg->gctrl);
> > +   debug("clkcr     0x%08x\n", reg->clkcr);
> > +   debug("timeout   0x%08x\n", reg->timeout);
> > +   debug("width     0x%08x\n", reg->width);
> > +   debug("blksz     0x%08x\n", reg->blksz);
> [...] lots more debug(foo)
> > +}
> 
> ^^^ #ifdef DEBUG here?

I can if you prefer but debug() itself effectively includes the same
ifdef so the end result is already the same.

> [...]

> > +/* support 4 mmc hosts */
> > +struct mmc mmc_dev[4];
> > +struct sunxi_mmc_host mmc_host[4];
> > +
> 
> ^ hosts & mmc structs can be allocated even for SPL now

Can be or must be?

> > +   struct sunxi_mmc_host *mmchost = &mmc_host[sdc_no];
> > +   static struct sunxi_gpio *gpio_c =
> > +       &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[SUNXI_GPIO_C];
> > +   static struct sunxi_gpio *gpio_f =
> > +       &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[SUNXI_GPIO_F];
> > +#if CONFIG_MMC1_PG
> > +   static struct sunxi_gpio *gpio_g =
> > +       &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[SUNXI_GPIO_G];
> > +#endif
> > +   static struct sunxi_gpio *gpio_h =
> > +       &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[SUNXI_GPIO_H];
> > +   static struct sunxi_gpio *gpio_i =
> > +       &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[SUNXI_GPIO_I];
> > +   struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
> > +
> 
> ^ Castings are ugly; rework with a temporary variable.

Ack.

The static's here are odd too and date back to the original alwinner
code dumps. I'll get rid of them too.

> [...]
> > +   case 3:
> > +           /* PI4-CMD, PI5-CLK, PI6~9-D0~D3 : 2 */
> > +           writel(0x2222 << 16, &gpio_i->cfg[0]);
> > +           writel(0x22, &gpio_i->cfg[1]);
> > +           writel(0x555 << 8, &gpio_i->pull[0]);
> > +           writel(0x555 << 8, &gpio_i->drv[0]);
> > +           break;
> > +
> > +   default:
> > +           return -1;
> > +   }
> > +
> 
> Lots of magic constants. I have no idea what's going on here.
> Use a few defines.

Right. These came from the original allwinner dumps so I was worried
that they might be undocumented magic, but actually since the are gpio
frobbing I reckon I can figure them out.

> [...]> +      cmd = (0x1 << 31) | (0x1 << 21) | (0x1 << 13);
> > +   writel(cmd, &mmchost->reg->cmd);
> > +   while ((readl(&mmchost->reg->cmd) & (0x1 << 31)) && timeout--);
> > +   if (!timeout)
> > +           return -1;
> > +
> 
> ^ Eeek! Use udelay and a time based timeout. 

Ack.

> > +   writel(readl(&mmchost->reg->rint), &mmchost->reg->rint);
> > +
> 
> ^ Same here - Not even a timeout?

No loop here though?
[...]

> > +   rval |= (0x1 << 16);
> 
> #define ?

Ack

[...]
> Ambiguous formatting. Use { }

Ack

> [...]
> > +   /* Reset controller */
> > +   writel(0x7, &mmchost->reg->gctrl);
> > +
> 
> Magic value again.

The sum total of the docs for this one are:
         * GCTRLREG
         * GCTRL[2]     : DMA reset
         * GCTRL[5]     : DMA enable

But I'll see what I can do.

[...]
> > +   } else {
> > +           buff = (unsigned int *)data->src;
> > +           for (i = 0; i < (byte_cnt >> 2); i++) {
> > +                   while (--timeout &&
> > +                            (readl(&mmchost->reg->status) & (0x1 << 3)));
> > +                   if (timeout <= 0)
> > +                           goto out;
> > +                   writel(buff[i], mmchost->database);
> > +                   timeout = 0xfffff;
> > +           }
> > +   }
> > +
> 
> ^ Timeouts using time values? udelay? See above.

Ack.

> [....]
> > +   writel(rval, &mmchost->reg->idie);
> > +   writel((u32) pdes, &mmchost->reg->dlba);
> > +   writel((0x2 << 28) | (0x7 << 16) | (0x01 << 3),
> > +          &mmchost->reg->ftrglevel);
> > +
> 
> ^ #define again?

Some of these (ftrgllevel) have no docs whatsoever, but I'll do what I
can.

> [...]

> > +   timeout = 0xfffff;
> > +   do {
> > +           status = readl(&mmchost->reg->rint);
> > +           if (!timeout-- || (status & 0xbfc2)) {
> > +                   error = status & 0xbfc2;
> > +                   debug("cmd timeout %x\n", error);
> > +                   error = TIMEOUT;
> > +                   goto out;
> > +           }
> 
> ^ Again timeouts without using time values.

I'm getting the picture ;-)

> [...]
> > +int sunxi_mmc_init(int sdc_no)
> > +{
> > +   struct mmc *mmc;
> > +
> > +   memset(&mmc_dev[sdc_no], 0, sizeof(struct mmc));
> > +   memset(&mmc_host[sdc_no], 0, sizeof(struct sunxi_mmc_host));
> > +   mmc = &mmc_dev[sdc_no];
> > +
> > +   sprintf(mmc->name, "SUNXI SD/MMC");
> > +   mmc->priv = &mmc_host[sdc_no];
> > +   mmc->send_cmd = mmc_send_cmd;
> > +   mmc->set_ios = mmc_set_ios;
> > +   mmc->init = mmc_core_init;
> > +
> > +   mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
> > +   mmc->host_caps = MMC_MODE_4BIT;
> > +   mmc->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
> > +
> > +   mmc->f_min = 400000;
> > +   mmc->f_max = 52000000;
> > +
> > +   mmc_resource_init(sdc_no);
> > +   mmc_clk_io_on(sdc_no);
> > +
> > +   mmc_register(mmc);
> > +
> 
> ^ The mmc_registeration sequence has changed, but not landed at master yet.

Do you have a reference handy for this?

Thanks again, sorry this driver is such a mess (I must confess I didn't
look at it that closely when I cherry picked it).

Ian.

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to