All of lore.kernel.org
 help / color / mirror / Atom feed
From: hl <hl@rock-chips.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v1 10/12] rockchip: Add an rk3036 MMC driver
Date: Fri, 23 Oct 2015 09:03:41 +0800	[thread overview]
Message-ID: <5629876D.6040004@rock-chips.com> (raw)
In-Reply-To: <CAPnjgZ2CDX1Acd_JiGFUg4oSek0K6y-KVL6L=9mycNLiQmLPiA@mail.gmail.com>

Hi Simon,


On 22/10/15 22:08, Simon Glass wrote:
> Hi Lin,
>
> On 20 October 2015 at 20:37, Lin Huang <hl@rock-chips.com> wrote:
>> rk3036 mmc driver is similar to dw_mmc, but use external dma,
>> this patch implment fifo mode, need to do dma mode in future.
>>
>> Signed-off-by: Lin Huang <hl@rock-chips.com>
>> ---
>> Changes in v1:
>> - clean copyright announcement
>>
>>   drivers/mmc/Kconfig                |   9 +
>>   drivers/mmc/Makefile               |   1 +
>>   drivers/mmc/rockchip_3036_dw_mmc.c | 479 +++++++++++++++++++++++++++++++++++++
>>   3 files changed, 489 insertions(+)
>>   create mode 100644 drivers/mmc/rockchip_3036_dw_mmc.c
>>
>> diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
>> index 6277f92..38bfb9c 100644
>> --- a/drivers/mmc/Kconfig
>> +++ b/drivers/mmc/Kconfig
>> @@ -19,6 +19,15 @@ config ROCKCHIP_DWMMC
>>            SD 3.0, SDIO 3.0 and MMC 4.5 and supports common eMMC chips as well
>>            as removeable SD and micro-SD cards.
>>
>> +config ROCKCHIP_3036_DWMMC
>> +       bool "Rockchip 3036 SD/MMC controller support"
>> +       depends on DM_MMC && OF_CONTROL
>> +       help
>> +         This enables support for the Rockchip 3036 SD/MMM controller, which is
>> +         based on Designware IP. The device is compatible with at least
>> +         SD 3.0, SDIO 3.0 and MMC 4.5 and supports common eMMC chips as well
>> +         as removeable SD and micro-SD cards.
>> +
>>   config SH_SDHI
>>          bool "SuperH/Renesas ARM SoCs on-chip SDHI host controller support"
>>          depends on RMOBILE
>> diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
>> index 99d0295..ff3920a 100644
>> --- a/drivers/mmc/Makefile
>> +++ b/drivers/mmc/Makefile
>> @@ -30,6 +30,7 @@ obj-$(CONFIG_OMAP_HSMMC) += omap_hsmmc.o
>>   obj-$(CONFIG_X86) += pci_mmc.o
>>   obj-$(CONFIG_PXA_MMC_GENERIC) += pxa_mmc_gen.o
>>   obj-$(CONFIG_ROCKCHIP_DWMMC) += rockchip_dw_mmc.o
>> +obj-$(CONFIG_ROCKCHIP_3036_DWMMC) += rockchip_3036_dw_mmc.o
>>   obj-$(CONFIG_SUPPORT_EMMC_RPMB) += rpmb.o
>>   obj-$(CONFIG_S3C_SDI) += s3c_sdi.o
>>   obj-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o
>> diff --git a/drivers/mmc/rockchip_3036_dw_mmc.c b/drivers/mmc/rockchip_3036_dw_mmc.c
>> new file mode 100644
>> index 0000000..2a2df52
>> --- /dev/null
>> +++ b/drivers/mmc/rockchip_3036_dw_mmc.c
>> @@ -0,0 +1,479 @@
>> +/*
>> + * (C) Copyright 2015 Rockchip Electronics Co., Ltd
>> + *
>> + * SPDX-License-Identifier:     GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <clk.h>
>> +#include <dm.h>
>> +#include <dwmmc.h>
>> +#include <errno.h>
>> +#include <syscon.h>
>> +#include <asm/arch/clock.h>
>> +#include <asm/arch/periph.h>
>> +#include <linux/err.h>
>> +#include <bouncebuf.h>
>> +#include <common.h>
>> +#include <errno.h>
>> +#include <malloc.h>
>> +#include <memalign.h>
>> +#include <mmc.h>
>> +#include <dwmmc.h>
>> +#include <asm-generic/errno.h>
>> +
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +#define PAGE_SIZE 4096
>> +#define MMC_GET_FCNT(x)                (((x)>>17) & 0x1FF)
> Can we use the SHIFT and MASK enums instead (as for clocks)? I'd like
> to avoid these sort of macro accessors.
     Okay,  got it.
>
>> +
>> +struct rockchip_dwmmc_priv {
>> +       struct udevice *clk;
>> +       struct dwmci_host host;
>> +};
>> +
>> +static int dwmci_wait_reset(struct dwmci_host *host, u32 value)
>> +{
>> +       unsigned long timeout = 1000;
>> +       u32 ctrl;
>> +
>> +       dwmci_writel(host, DWMCI_CTRL, value);
>> +
>> +       while (timeout--) {
>> +               ctrl = dwmci_readl(host, DWMCI_CTRL);
>> +               if (!(ctrl & DWMCI_RESET_ALL))
>> +                       return 1;
> The timeout here is somewhat indeterminate, since it does not
> reference the timer. Unless there is a special reason to do this (in
> which case we should have a comment here) we should use something
> like:
>
> unsigned long start;
>
> start = get_timer(0);
> do {
> } while (get_timer(start) < 1000);

     Thanks to point it, i will modify it next version.
>
>> +       }
>> +       return 0;
>> +}
>> +
>> +static int dwmci_set_transfer_mode(struct dwmci_host *host,
>> +               struct mmc_data *data)
>> +{
>> +       unsigned long mode;
>> +
>> +       mode = DWMCI_CMD_DATA_EXP;
>> +       if (data->flags & MMC_DATA_WRITE)
>> +               mode |= DWMCI_CMD_RW;
>> +
>> +       return mode;
>> +}
>> +
>> +static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
>> +               struct mmc_data *data)
>> +{
>> +       struct dwmci_host *host = mmc->priv;
>> +       int ret = 0, flags = 0, i;
>> +       unsigned int timeout = 100000;
>> +       u32 retry = 10000;
>> +       u32 mask;
>> +       ulong start = get_timer(0);
>> +       int size;
>> +       unsigned int fifo_len;
>> +       unsigned int *buf = 0;
>> +
>> +       while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) {
>> +               if (get_timer(start) > timeout) {
>> +                       debug("%s: Timeout on data busy\n", __func__);
>> +                       return TIMEOUT;
>> +               }
>> +       }
>> +
>> +       dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_ALL);
>> +
>> +       if (data) {
>> +               /*
>> +                * TODO: rk3036 use external DMA,
>> +                * need to support DMA mode in future
>> +                */
>> +               if (data->flags == MMC_DATA_READ)
>> +                       buf = (unsigned int *)data->dest;
>> +               else
>> +                       buf = (unsigned int *)data->src;
>> +               dwmci_writel(host, DWMCI_BLKSIZ, data->blocksize);
>> +               dwmci_writel(host, DWMCI_BYTCNT, data->blocksize * data->blocks);
>> +               dwmci_wait_reset(host, DWMCI_CTRL_FIFO_RESET);
>> +       }
>> +
>> +       dwmci_writel(host, DWMCI_CMDARG, cmd->cmdarg);
>> +
>> +       if (data)
>> +               flags = dwmci_set_transfer_mode(host, data);
>> +
>> +       if ((cmd->resp_type & MMC_RSP_136) && (cmd->resp_type & MMC_RSP_BUSY))
>> +               return -1;
>> +
>> +       if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
>> +               flags |= DWMCI_CMD_ABORT_STOP;
>> +       else
>> +               flags |= DWMCI_CMD_PRV_DAT_WAIT;
>> +
>> +       if (cmd->resp_type & MMC_RSP_PRESENT) {
>> +               flags |= DWMCI_CMD_RESP_EXP;
>> +               if (cmd->resp_type & MMC_RSP_136)
>> +                       flags |= DWMCI_CMD_RESP_LENGTH;
>> +       }
>> +
>> +       if (cmd->resp_type & MMC_RSP_CRC)
>> +               flags |= DWMCI_CMD_CHECK_CRC;
>> +
>> +       flags |= (cmd->cmdidx | DWMCI_CMD_START | DWMCI_CMD_USE_HOLD_REG);
>> +
>> +       debug("Sending CMD%d\n", cmd->cmdidx);
>> +
>> +       dwmci_writel(host, DWMCI_CMD, flags);
>> +
>> +       for (i = 0; i < retry; i++) {
>> +               mask = dwmci_readl(host, DWMCI_RINTSTS);
>> +               if (mask & DWMCI_INTMSK_CDONE) {
>> +                       if (!data)
>> +                               dwmci_writel(host, DWMCI_RINTSTS, mask);
>> +                       break;
>> +               }
>> +       }
>> +
>> +       if (i == retry) {
>> +               debug("%s: Timeout.\n", __func__);
>> +               return TIMEOUT;
>> +       }
>> +
>> +       if (mask & DWMCI_INTMSK_RTO) {
>> +               /*
>> +                * Timeout here is not necessarily fatal. (e)MMC cards
>> +                * will splat here when they receive CMD55 as they do
>> +                * not support this command and that is exactly the way
>> +                * to tell them apart from SD cards. Thus, this output
>> +                * below shall be debug(). eMMC cards also do not favor
>> +                * CMD8, please keep that in mind.
>> +                */
>> +               debug("%s: Response Timeout.\n", __func__);
>> +               return TIMEOUT;
>> +       } else if (mask & DWMCI_INTMSK_RE) {
>> +               debug("%s: Response Error.\n", __func__);
>> +               return -EIO;
>> +       }
>> +
>> +       if (cmd->resp_type & MMC_RSP_PRESENT) {
>> +               if (cmd->resp_type & MMC_RSP_136) {
>> +                       cmd->response[0] = dwmci_readl(host, DWMCI_RESP3);
>> +                       cmd->response[1] = dwmci_readl(host, DWMCI_RESP2);
>> +                       cmd->response[2] = dwmci_readl(host, DWMCI_RESP1);
>> +                       cmd->response[3] = dwmci_readl(host, DWMCI_RESP0);
>> +               } else {
>> +                       cmd->response[0] = dwmci_readl(host, DWMCI_RESP0);
>> +               }
>> +       }
>> +
>> +       if (data) {
>> +               size = data->blocksize * data->blocks / 4;
>> +               start = get_timer(0);
>> +               timeout = 1000;
>> +               for (;;) {
>> +                       mask = dwmci_readl(host, DWMCI_RINTSTS);
>> +                       /* Error during data transfer. */
>> +                       if (mask & (DWMCI_DATA_ERR | DWMCI_DATA_TOUT)) {
>> +                               debug("%s: DATA ERROR!\n", __func__);
>> +                               ret = -EINVAL;
>> +                               break;
>> +                       }
>> +
>> +                       /*
>> +                        * TODO: rk3036 use external DMA,
>> +                        * need to support DMA mode in future
>> +                        */
>> +                       if (data->flags == MMC_DATA_READ) {
>> +                               if ((dwmci_readl(host, DWMCI_RINTSTS) &&
>> +                                               DWMCI_INTMSK_RXDR) && size) {
>> +                                       fifo_len = dwmci_readl(host,
>> +                                                               DWMCI_STATUS);
>> +                                       fifo_len = MMC_GET_FCNT(fifo_len);
>> +                                       for (i = 0; i < fifo_len; i++)
>> +                                               *buf++ = dwmci_readl(host,
>> +                                                               DWMCI_DATA);
>> +                                       dwmci_writel(host, DWMCI_RINTSTS,
>> +                                                       DWMCI_INTMSK_RXDR);
>> +                                       size = size > fifo_len ?
>> +                                                       (size - fifo_len) : 0;
>> +                               }
>> +                       } else {
>> +                               if ((dwmci_readl(host, DWMCI_RINTSTS) &&
>> +                                               DWMCI_INTMSK_TXDR) && size) {
>> +                                       fifo_len = dwmci_readl(host,
>> +                                                       DWMCI_STATUS);
>> +                                       fifo_len = MMC_GET_FCNT(fifo_len);
>> +                                       for (i = 0; i < fifo_len; i++)
>> +                                               dwmci_writel(host, DWMCI_DATA,
>> +                                                               *buf++);
>> +                                       dwmci_writel(host, DWMCI_RINTSTS,
>> +                                                       DWMCI_INTMSK_TXDR);
>> +                                       size = size > fifo_len ?
>> +                                                       (size - fifo_len) : 0;
>> +                               }
>> +                       }
>> +
>> +                       /* Data arrived correctly. */
>> +                       if (mask & DWMCI_INTMSK_DTO) {
>> +                               ret = 0;
>> +                               break;
>> +                       }
>> +
>> +                       /* Check for timeout. */
>> +                       if (get_timer(start) > timeout) {
>> +                               debug("%s: Timeout waiting for data!\n",
>> +                                      __func__);
>> +                               ret = TIMEOUT;
>> +                               break;
>> +                       }
>> +               }
>> +               dwmci_writel(host, DWMCI_RINTSTS, mask);
>> +       }
>> +
>> +       udelay(100);
>> +
>> +       return ret;
>> +}
>> +
>> +static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
>> +{
>> +       u32 div, status;
>> +       int timeout = 10000;
>> +       unsigned long sclk;
>> +
>> +       if ((freq == host->clock) || (freq == 0))
>> +               return 0;
>> +       /*
>> +        * If host->get_mmc_clk isn't defined,
>> +        * then assume that host->bus_hz is source clock value.
>> +        * host->bus_hz should be set by user.
>> +        */
>> +       if (host->get_mmc_clk)
>> +               sclk = host->get_mmc_clk(host, freq);
>> +       else if (host->bus_hz)
>> +               sclk = host->bus_hz;
>> +       else {
>> +               debug("%s: Didn't get source clock value.\n", __func__);
>> +               return -EINVAL;
>> +       }
>> +
>> +       if (sclk == freq)
>> +               div = 0;        /* bypass mode */
>> +       else
>> +               div = DIV_ROUND_UP(sclk, 2 * freq);
>> +
>> +       dwmci_writel(host, DWMCI_CLKENA, 0);
>> +       dwmci_writel(host, DWMCI_CLKSRC, 0);
>> +
>> +       dwmci_writel(host, DWMCI_CLKDIV, div);
>> +       dwmci_writel(host, DWMCI_CMD, DWMCI_CMD_PRV_DAT_WAIT |
>> +                       DWMCI_CMD_UPD_CLK | DWMCI_CMD_START);
>> +
>> +       do {
>> +               status = dwmci_readl(host, DWMCI_CMD);
> Similar here.
     Got it.
>
>> +               if (timeout-- < 0) {
>> +                       debug("%s: Timeout!\n", __func__);
>> +                       return -ETIMEDOUT;
>> +               }
>> +       } while (status & DWMCI_CMD_START);
>> +
>> +       dwmci_writel(host, DWMCI_CLKENA, DWMCI_CLKEN_ENABLE |
>> +                       DWMCI_CLKEN_LOW_PWR);
>> +
>> +       dwmci_writel(host, DWMCI_CMD, DWMCI_CMD_PRV_DAT_WAIT |
>> +                       DWMCI_CMD_UPD_CLK | DWMCI_CMD_START);
>> +
>> +       timeout = 10000;
>> +       do {
>> +               status = dwmci_readl(host, DWMCI_CMD);
>> +               if (timeout-- < 0) {
>> +                       debug("%s: Timeout!\n", __func__);
>> +                       return -ETIMEDOUT;
>> +               }
>> +       } while (status & DWMCI_CMD_START);
>> +
>> +       host->clock = freq;
>> +
>> +       return 0;
>> +}
>> +
>> +static void dwmci_set_ios(struct mmc *mmc)
>> +{
>> +       struct dwmci_host *host = (struct dwmci_host *)mmc->priv;
>> +       u32 ctype, regs;
>> +
>> +       debug("Buswidth = %d, clock: %d\n", mmc->bus_width, mmc->clock);
>> +
>> +       dwmci_setup_bus(host, mmc->clock);
>> +       switch (mmc->bus_width) {
>> +       case 8:
>> +               ctype = DWMCI_CTYPE_8BIT;
>> +               break;
>> +       case 4:
>> +               ctype = DWMCI_CTYPE_4BIT;
>> +               break;
>> +       default:
>> +               ctype = DWMCI_CTYPE_1BIT;
>> +               break;
>> +       }
>> +
>> +       dwmci_writel(host, DWMCI_CTYPE, ctype);
>> +
>> +       regs = dwmci_readl(host, DWMCI_UHS_REG);
>> +       if (mmc->ddr_mode)
>> +               regs |= DWMCI_DDR_MODE;
>> +       else
>> +               regs &= ~DWMCI_DDR_MODE;
>> +
>> +       dwmci_writel(host, DWMCI_UHS_REG, regs);
>> +
>> +       if (host->clksel)
>> +               host->clksel(host);
>> +}
>> +
>> +static int dwmci_init(struct mmc *mmc)
>> +{
>> +       struct dwmci_host *host = mmc->priv;
>> +
>> +       if (host->board_init)
>> +               host->board_init(host);
>> +
>> +       dwmci_writel(host, DWMCI_PWREN, 1);
>> +
>> +       if (!dwmci_wait_reset(host, DWMCI_RESET_ALL)) {
>> +               debug("%s[%d] Fail-reset!!\n", __func__, __LINE__);
>> +               return -EIO;
>> +       }
>> +
>> +       /* Enumerate at 400KHz */
>> +       dwmci_setup_bus(host, mmc->cfg->f_min);
>> +
>> +       dwmci_writel(host, DWMCI_RINTSTS, 0xFFFFFFFF);
>> +       dwmci_writel(host, DWMCI_INTMASK, 0);
>> +
>> +       dwmci_writel(host, DWMCI_TMOUT, 0xFFFFFFFF);
>> +
>> +       dwmci_writel(host, DWMCI_IDINTEN, 0);
>> +       dwmci_writel(host, DWMCI_BMOD, 1);
>> +
>> +       if (!host->fifoth_val) {
>> +               uint32_t fifo_size;
>> +               fifo_size = dwmci_readl(host, DWMCI_FIFOTH);
>> +               fifo_size = ((fifo_size & RX_WMARK_MASK) >> RX_WMARK_SHIFT) + 1;
>> +               host->fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_size / 2 - 1) |
>> +                               TX_WMARK(fifo_size / 2);
>> +       }
>> +       dwmci_writel(host, DWMCI_FIFOTH, host->fifoth_val);
>> +
>> +       dwmci_writel(host, DWMCI_CLKENA, 0);
>> +       dwmci_writel(host, DWMCI_CLKSRC, 0);
>> +
>> +       return 0;
>> +}
>> +
>> +static const struct mmc_ops dwmci_ops = {
>> +       .send_cmd       = dwmci_send_cmd,
>> +       .set_ios        = dwmci_set_ios,
>> +       .init           = dwmci_init,
>> +};
>> +
>> +int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk)
>> +{
>> +       host->cfg.name = host->name;
>> +       host->cfg.ops = &dwmci_ops;
>> +       host->cfg.f_min = min_clk;
>> +       host->cfg.f_max = max_clk;
>> +
>> +       host->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
>> +
>> +       host->cfg.host_caps = host->caps;
>> +
>> +       if (host->buswidth == 8) {
>> +               host->cfg.host_caps |= MMC_MODE_8BIT;
>> +               host->cfg.host_caps &= ~MMC_MODE_4BIT;
>> +       } else {
>> +               host->cfg.host_caps |= MMC_MODE_4BIT;
>> +               host->cfg.host_caps &= ~MMC_MODE_8BIT;
>> +       }
>> +       host->cfg.host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz;
>> +
>> +       host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
>> +
>> +       host->mmc = mmc_create(&host->cfg, host);
>> +       if (host->mmc == NULL)
>> +               return -1;
>> +
>> +       return 0;
>> +}
>> +
>> +static uint rockchip_dwmmc_get_mmc_clk(struct dwmci_host *host, uint freq)
>> +{
>> +       struct udevice *dev = host->priv;
>> +       struct rockchip_dwmmc_priv *priv = dev_get_priv(dev);
>> +       int ret;
>> +
>> +       ret = clk_set_periph_rate(priv->clk, PERIPH_ID_SDMMC0 + host->dev_index,
>> +                                 freq);
>> +       if (ret < 0) {
>> +               debug("%s: err=%d\n", __func__, ret);
>> +               return ret;
>> +       }
>> +
>> +       return freq;
>> +}
>> +
>> +static int rockchip_dwmmc_ofdata_to_platdata(struct udevice *dev)
>> +{
>> +       struct rockchip_dwmmc_priv *priv = dev_get_priv(dev);
>> +       struct dwmci_host *host = &priv->host;
>> +
>> +       host->name = dev->name;
>> +       host->ioaddr = (void *)dev_get_addr(dev);
>> +       host->buswidth = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
>> +                                       "bus-width", 4);
>> +       host->get_mmc_clk = rockchip_dwmmc_get_mmc_clk;
>> +       host->priv = dev;
>> +
>> +       /* use non-removeable as sdcard and emmc as judgement */
>> +       if (fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset, "non-removable")
>> +                                       == -FDT_ERR_NOTFOUND)
>> +               host->dev_index = (ulong)host->ioaddr == 1;
>> +
>> +       return 0;
>> +}
>> +
>> +static int rockchip_dwmmc_probe(struct udevice *dev)
>> +{
>> +       struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
>> +       struct rockchip_dwmmc_priv *priv = dev_get_priv(dev);
>> +       struct dwmci_host *host = &priv->host;
>> +       u32 minmax[2];
>> +       int ret;
>> +
>> +       ret = uclass_get_device(UCLASS_CLK, CLK_GENERAL, &priv->clk);
>> +       if (ret)
>> +               return ret;
>> +
>> +       ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset,
>> +                                  "clock-freq-min-max", minmax, 2);
>> +       if (!ret)
>> +               ret = add_dwmci(host, minmax[1], minmax[0]);
>> +       if (ret)
>> +               return ret;
>> +
>> +       upriv->mmc = host->mmc;
>> +
>> +       return 0;
>> +}
>> +
>> +static const struct udevice_id rockchip_dwmmc_ids[] = {
>> +       { .compatible = "rockchip,rk3288-dw-mshc" },
>> +       { }
>> +};
>> +
>> +U_BOOT_DRIVER(rockchip_dwmmc_drv) = {
>> +       .name           = "rockchip_3036_dwmmc",
>> +       .id             = UCLASS_MMC,
>> +       .of_match       = rockchip_dwmmc_ids,
>> +       .ofdata_to_platdata = rockchip_dwmmc_ofdata_to_platdata,
>> +       .probe          = rockchip_dwmmc_probe,
>> +       .priv_auto_alloc_size = sizeof(struct rockchip_dwmmc_priv),
>> +};
>> --
>> 1.9.1
>>
> Regards,
> Simon
>
>
>

-- 
Lin Huang

  reply	other threads:[~2015-10-23  1:03 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-21  2:37 [U-Boot] [PATCH v1 00/12] Bring up rk3036 uboot Lin Huang
2015-10-21  2:37 ` [U-Boot] [PATCH v1 01/12] rockchip: define SUPPORT_SPL and SPL config in RK3288 config Lin Huang
2015-10-22 14:07   ` Simon Glass
2015-10-22 16:01     ` Eddie Cai
2015-10-22 16:30       ` Simon Glass
2015-10-23  0:54         ` Eddie Cai
2015-10-23  1:04           ` Simon Glass
2015-10-23  1:21             ` hl
2015-10-26  4:12               ` Simon Glass
2015-10-27  0:27                 ` hl
2015-10-27 19:03                   ` Simon Glass
2015-10-23  0:50     ` hl
2015-10-23  0:54       ` Simon Glass
2015-10-21  2:37 ` [U-Boot] [PATCH v1 02/12] rockchip: implement rockchip timer init function Lin Huang
2015-10-22 14:07   ` Simon Glass
2015-10-21  2:37 ` [U-Boot] [PATCH v1 03/12] rockchip: serial driver support rk3036 Lin Huang
2015-10-22 14:07   ` Simon Glass
2015-10-23  0:51     ` hl
2015-10-21  2:37 ` [U-Boot] [PATCH v1 04/12] rockchip: Bring in RK3036 device tree file includes and bindings Lin Huang
2015-10-22 14:07   ` Simon Glass
2015-10-21  2:37 ` [U-Boot] [PATCH v1 05/12] rockchip: rk3036: Add clock driver Lin Huang
2015-10-22 14:07   ` Simon Glass
2015-10-23  0:56     ` hl
2015-10-21  2:37 ` [U-Boot] [PATCH v1 06/12] rockchip: rk3036: Add header files for GRF Lin Huang
2015-10-22 14:07   ` Simon Glass
2015-10-21  2:37 ` [U-Boot] [PATCH v1 07/12] rockchip: rk3036: Add Soc reset driver Lin Huang
2015-10-22 14:07   ` Simon Glass
2015-10-21  2:37 ` [U-Boot] [PATCH v1 08/12] rockchip: rk3036: Add a simple syscon driver Lin Huang
2015-10-22 14:08   ` Simon Glass
2015-10-21  2:37 ` [U-Boot] [PATCH v1 09/12] rockchip: rk3036: Add pinctrl driver Lin Huang
2015-10-22 14:08   ` Simon Glass
2015-10-21  2:37 ` [U-Boot] [PATCH v1 10/12] rockchip: Add an rk3036 MMC driver Lin Huang
2015-10-22 14:08   ` Simon Glass
2015-10-23  1:03     ` hl [this message]
2015-10-21  2:37 ` [U-Boot] [PATCH v1 11/12] rockchip: rk3036: Add core Soc start-up code Lin Huang
2015-10-22 14:08   ` Simon Glass
2015-10-21  2:37 ` [U-Boot] [PATCH v1 12/12] rockchip: Add basic support for evb-rk3036 board Lin Huang
2015-10-22 14:08   ` Simon Glass
2015-10-23  1:27     ` hl
2015-10-23  1:34       ` Simon Glass
2015-10-23  2:50         ` hl
2015-10-23  2:53           ` Simon Glass
  -- strict thread matches above, loose matches on Subject: below --
2015-10-21  5:37 [U-Boot] [PATCH v1 00/12] Bring up rk3036 uboot Lin Huang
2015-10-21  5:37 ` [U-Boot] [PATCH v1 10/12] rockchip: Add an rk3036 MMC driver Lin Huang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5629876D.6040004@rock-chips.com \
    --to=hl@rock-chips.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.