On Wed, 21 Nov 2018 09:52:08 +0100
Lukasz Majewski <lu...@denx.de> wrote:

> On Wed, 07 Nov 2018 16:03:08 +0100
> Marek Szyprowski <m.szyprow...@samsung.com> wrote:
> 
> > From: Lukasz Majewski <l.majew...@samsung.com>
> > 
> > DW-MMC module in Samsung Exynos5433 requires 64bit DMA descriptors.
> > This patch adds code for handling them.
> > 
> > Signed-off-by: Lukasz Majewski <l.majew...@samsung.com>
> > [extracted from old sources and adapted to mainline u-boot, minor
> > fixes] Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
> > ---
> >  drivers/mmc/dw_mmc.c        | 53
> > ++++++++++++++++++++++++++++++------- drivers/mmc/exynos_dw_mmc.c |
> > 6 +++++ include/dwmmc.h             | 25 +++++++++++++++++
> >  3 files changed, 74 insertions(+), 10 deletions(-)
> > 
> > diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
> > index 3c702b3ed8..f50eb29ac9 100644
> > --- a/drivers/mmc/dw_mmc.c
> > +++ b/drivers/mmc/dw_mmc.c
> > @@ -30,8 +30,8 @@ static int dwmci_wait_reset(struct dwmci_host
> > *host, u32 value) return 0;
> >  }
> >  
> > -static void dwmci_set_idma_desc(struct dwmci_idmac *idmac,
> > -           u32 desc0, u32 desc1, u32 desc2)
> > +static void dwmci_set_idma_desc_32bit(void *idmac,
> > +                                 u32 desc0, u32 desc1, u32
> > desc2) {
> >     struct dwmci_idmac *desc = idmac;
> >  
> > @@ -41,11 +41,27 @@ static void dwmci_set_idma_desc(struct
> > dwmci_idmac *idmac, desc->next_addr = (ulong)desc + sizeof(struct
> > dwmci_idmac); }
> >  
> > +static void dwmci_set_idma_desc_64bit(void *idmac,
> > +                                 u32 desc0, u32 desc1, u32
> > desc2) +{
> > +   struct dwmci_idmac_64addr *desc = idmac;
> > +
> > +   desc->flags = desc0;
> > +   desc->_res1 = 0;
> > +   desc->cnt = desc1;
> > +   desc->_res2 = 0;
> > +   desc->addrl = desc2;
> > +   desc->addrh = 0;
> > +   desc->next_addrl = (ulong)desc + sizeof(struct
> > dwmci_idmac_64addr);
> > +   desc->next_addrh = 0;
> > +}
> > +
> >  static void dwmci_prepare_data(struct dwmci_host *host,
> >                            struct mmc_data *data,
> > -                          struct dwmci_idmac *cur_idmac,
> > +                          struct dwmci_idmac_64addr
> > *cur_idmac64, void *bounce_buffer)  
> 
> This looks strange - why the core dwmci_prepare_data() has this
> change?
> 
> Above, the *idmac has been changed to void* from struct dwmci_idmac
> *idmac to handle 64bit DMA descriptors.
> 
> I think that it shall be done in the same way here.
> 
> >  {
> > +   struct dwmci_idmac *cur_idmac = (struct dwmci_idmac
> > *)cur_idmac64; unsigned long ctrl;
> >     unsigned int i = 0, flags, cnt, blk_cnt;
> >     ulong data_start, data_end;
> > @@ -56,7 +72,12 @@ static void dwmci_prepare_data(struct dwmci_host
> > *host, dwmci_wait_reset(host, DWMCI_CTRL_FIFO_RESET);
> >  
> >     data_start = (ulong)cur_idmac;
> > -   dwmci_writel(host, DWMCI_DBADDR, (ulong)cur_idmac);
> > +
> > +   if (host->dma_64bit_address) {
> > +           dwmci_writel(host, DWMCI_DBADDRU, 0);
> > +           dwmci_writel(host, DWMCI_DBADDRL,
> > (ulong)cur_idmac64);  
> 
> This is even more strange - the upper part of 32 bit address is 0, so
> we pass only 32 bit address. Is this SoC working in armv7 mode (32
> bit) and the dwmmc is expecting 64bit descriptors?
> 
> 
> > +   } else
> > +           dwmci_writel(host, DWMCI_DBADDR, (ulong)cur_idmac);
> >  
> >     do {
> >             flags = DWMCI_IDMAC_OWN | DWMCI_IDMAC_CH ;
> > @@ -67,17 +88,27 @@ static void dwmci_prepare_data(struct dwmci_host
> > *host, } else
> >                     cnt = data->blocksize * 8;
> >  
> > -           dwmci_set_idma_desc(cur_idmac, flags, cnt,
> > -                               (ulong)bounce_buffer + (i *
> > PAGE_SIZE));
> > +           if (host->dma_64bit_address)
> > +                   dwmci_set_idma_desc_64bit(cur_idmac64,  
>                                                 ^^^^^^ here a void
>                                                 pointer with a
> static cast would be enough.
> 
> > flags, cnt,
> > +
> > (ulong)bounce_buffer +
> > +                                             (i * PAGE_SIZE));
> > +           else
> > +                   dwmci_set_idma_desc_32bit(cur_idmac, flags,
> > cnt,
> > +
> > (ulong)bounce_buffer +
> > +                                             (i * PAGE_SIZE));
> >  
> >             if (blk_cnt <= 8)
> >                     break;
> >             blk_cnt -= 8;
> >             cur_idmac++;
> > +           cur_idmac64++;  
> 
> This looks like a quick hack - the if (host->dma_64bit_address) / else
> is missing. Otherwise it would break the boards which use this code
> already.
> 
> >             i++;
> >     } while(1);
> >  
> > -   data_end = (ulong)cur_idmac;
> > +   if (host->dma_64bit_address)
> > +           data_end = (ulong)cur_idmac64;
> > +   else
> > +           data_end = (ulong)cur_idmac;
> >     flush_dcache_range(data_start, data_end +
> > ARCH_DMA_MINALIGN); 
> >     ctrl = dwmci_readl(host, DWMCI_CTRL);
> > @@ -222,7 +253,7 @@ static int dwmci_send_cmd(struct mmc *mmc,
> > struct mmc_cmd *cmd, {
> >  #endif
> >     struct dwmci_host *host = mmc->priv;
> > -   ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac, cur_idmac,
> > +   ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac_64addr,  
> 
> Isn't this change causing the boards with 32 bits addressing
> malfunctioning? 
> 
> #ifdef would be necessary - as struct dwmci_idmac / dwmci_idmac_64addr
> have different sizes and fields.
> 
> > cur_idmac64, data ? DIV_ROUND_UP(data->blocks, 8) : 0);
> >     int ret = 0, flags = 0, i;
> >     unsigned int timeout = 500;
> > @@ -256,7 +287,7 @@ static int dwmci_send_cmd(struct mmc *mmc,
> > struct mmc_cmd *cmd, data->blocksize *
> >                                             data->blocks,
> > GEN_BB_READ); }
> > -                   dwmci_prepare_data(host, data, cur_idmac,
> > +                   dwmci_prepare_data(host, data, cur_idmac64,
> >                                        bbstate.bounce_buffer);  
> 
> The above comment also applies here.
> 
> >             }
> >     }
> > @@ -474,7 +505,9 @@ static int dwmci_init(struct mmc *mmc)
> >  
> >     dwmci_writel(host, DWMCI_TMOUT, 0xFFFFFFFF);
> >  
> > -   dwmci_writel(host, DWMCI_IDINTEN, 0);
> > +   dwmci_writel(host, host->dma_64bit_address ?
> > +                      DWMCI_IDINTEN64 : DWMCI_IDINTEN, 0);
> > +
> >     dwmci_writel(host, DWMCI_BMOD, 1);
> >  
> >     if (!host->fifoth_val) {
> > diff --git a/drivers/mmc/exynos_dw_mmc.c
> > b/drivers/mmc/exynos_dw_mmc.c index 435ccac594..3e9d47538c 100644
> > --- a/drivers/mmc/exynos_dw_mmc.c
> > +++ b/drivers/mmc/exynos_dw_mmc.c
> > @@ -98,6 +98,7 @@ static void exynos_dwmci_board_init(struct
> > dwmci_host *host) 
> >  static int exynos_dwmci_core_init(struct dwmci_host *host)
> >  {
> > +   unsigned int addr_config;
> >     unsigned int div;
> >     unsigned long freq, sclk;
> >  
> > @@ -122,6 +123,11 @@ static int exynos_dwmci_core_init(struct
> > dwmci_host *host) host->clksel = exynos_dwmci_clksel;
> >     host->get_mmc_clk = exynos_dwmci_get_clk;
> >  
> > +   addr_config = DWMCI_GET_ADDR_CONFIG(dwmci_readl(host,
> > DWMCI_HCON));
> > +   if (addr_config == 1)
> > +           /* host supports IDMAC in 64-bit address mode */
> > +           host->dma_64bit_address = 1;
> > +
> >  #ifndef CONFIG_DM_MMC
> >     /* Add the mmc channel to be registered with mmc core */
> >     if (add_dwmci(host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ)) {
> > diff --git a/include/dwmmc.h b/include/dwmmc.h
> > index 0f9d51b557..14db03d7d4 100644
> > --- a/include/dwmmc.h
> > +++ b/include/dwmmc.h
> > @@ -48,6 +48,17 @@
> >  #define DWMCI_DSCADDR              0x094
> >  #define DWMCI_BUFADDR              0x098
> >  #define DWMCI_DATA         0x200
> > +/*
> > + * Registers to support idmac 64-bit address mode
> > + */
> > +#define DWMCI_DBADDRL              0x088
> > +#define DWMCI_DBADDRU              0x08c
> > +#define DWMCI_IDSTS64              0x090
> > +#define DWMCI_IDINTEN64            0x094
> > +#define DWMCI_DSCADDRL             0x098
> > +#define DWMCI_DSCADDRU             0x09c
> > +#define DWMCI_BUFADDRL             0x0A0
> > +#define DWMCI_BUFADDRU             0x0A4
> >  
> >  /* Interrupt Mask register */
> >  #define DWMCI_INTMSK_ALL   0xffffffff
> > @@ -132,6 +143,7 @@
> >  /* quirks */
> >  #define DWMCI_QUIRK_DISABLE_SMU            (1 << 0)
> >  
> > +#define DWMCI_GET_ADDR_CONFIG(x) (((x)>>27) & 0x1)
> >  /**
> >   * struct dwmci_host - Information about a designware MMC host
> >   *
> > @@ -145,6 +157,7 @@
> >   * @dev_id:        Arbitrary device ID for use by controller
> >   * @buswidth:      Bus width in bits (8 or 4)
> >   * @fifoth_val:    Value for FIFOTH register (or 0 to leave
> > unset)
> > + * @dma_64bit_address:     True only for devices supporting 64
> > bit DMA
> >   * @mmc:   Pointer to generic MMC structure for this device
> >   * @priv:  Private pointer for use by controller
> >   */
> > @@ -161,6 +174,7 @@ struct dwmci_host {
> >     int dev_id;
> >     int buswidth;
> >     u32 fifoth_val;
> > +   int dma_64bit_address;
> >     struct mmc *mmc;
> >     void *priv;
> >  
> > @@ -196,6 +210,17 @@ struct dwmci_idmac {
> >     u32 next_addr;
> >  } __aligned(ARCH_DMA_MINALIGN);
> >  
> > +struct dwmci_idmac_64addr {
> > +   u32 flags;
> > +   u32 _res1;
> > +   u32 cnt;
> > +   u32 _res2;
> > +   u32 addrl;
> > +   u32 addrh;
> > +   u32 next_addrl;
> > +   u32 next_addrh;
> > +} __aligned(ARCH_DMA_MINALIGN);
> > +
> >  static inline void dwmci_writel(struct dwmci_host *host, int reg,
> > u32 val) {
> >     writel(val, host->ioaddr + reg);  
> 
> 

And just to mention - for such change I would like to have a tested-by:
tag on the SoC (Odroid XU3/4), which uses the 32 bit DMA descriptors.

> 
> 
> Best regards,
> 
> Lukasz Majewski
> 
> --
> 
> DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email:
> lu...@denx.de




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lu...@denx.de

Attachment: pgp1CnjKnhLiI.pgp
Description: OpenPGP digital signature

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

Reply via email to