[U-Boot] [PATCH 00/35][RFC] arm: socfpga: Usability fixes

This entire RFC series is the first stab at making SoCFPGA usable with mainline U-Boot again. There are still some bits missing, but in general, this allows me to use mainline U-Boot on my SoCFPGA systems. The big missing part is the SPL generation, which still needs a lot of additional work.
This set contains patches for a few subsystems, bu the most part is the SoCFPGA chip support.
Most of the patches should be in good shape already, so I wonder if the RFC tag is really necessary.
Charles Manning (1): tools: socfpga: Add socfpga preloader signing to mkimage
Marek Vasut (21): net: dwc: Fix cache alignment issues net: dwc: Make the cache handling less cryptic mmc: dw_mmc: Fix cache alignment issue arm: socfpga: Clean up base address file arm: socfpga: sysmgr: Clean up system manager arm: socfpga: clock: Implant order into bit definitions arm: socfpga: clock: Drop nonsense inlining from clock manager code arm: socfpga: clock: Add missing stubs into board file arm: socfpga: clock: Trim down code duplication arm: socfpga: timer: Pull the timer reload value from config file arm: socfpga: reset: Add EMAC reset functions arm: socfpga: board: Align checkboard() output arm: socfpga: reset: Add function to reset FPGA bridges arm: socfpga: sysmgr: Add FPGA bits into system manager arm: cache: Add support for write-allocate D-Cache arm: socfpga: cache: Define cacheline size arm: socfpga: cache: Enable D-Cache arm: socfpga: cache: Enable PL310 L2 cache arm: socfpga: scu: Add SCU register file arm: socfpga: nic301: Add NIC-301 GPV register file arm: socfpga: pl310: Map SDRAM to 0x0
Pavel Machek (13): net: Remove unused CONFIG_DW_SEARCH_PHY from configs net: phy: Cleanup drivers/net/phy/micrel.c mmc: dw_mmc: cleanups arm: socfpga: Complete the list of base addresses arm: socfpga: Add watchdog disable for socfpga arm: socfpga: clock: Add code to read clock configuration arm: socfpga: mmc: Pick the clock from clock manager arm: socfpga: misc: Add proper ethernet initialization arm: socfpga: misc: Add SD controller init arm: socfpga: misc: Align print_cpuinfo() output arm: socfpga: board: Correctly set ATAG position arm: socfpga: fpga: Add SoCFPGA FPGA programming interface arm: socfpga: nic301: Add NIC-301 configuration code
arch/arm/cpu/armv7/socfpga/Makefile | 3 +- arch/arm/cpu/armv7/socfpga/clock_manager.c | 218 ++++++++++++- arch/arm/cpu/armv7/socfpga/fpga_manager.c | 354 +++++++++++++++++++++ arch/arm/cpu/armv7/socfpga/misc.c | 144 ++++++++- arch/arm/cpu/armv7/socfpga/reset_manager.c | 72 +++++ arch/arm/cpu/armv7/socfpga/system_manager.c | 57 +++- arch/arm/cpu/armv7/socfpga/timer.c | 2 + arch/arm/include/asm/arch-socfpga/clock_manager.h | 209 ++++++++---- arch/arm/include/asm/arch-socfpga/fpga_manager.h | 77 +++++ arch/arm/include/asm/arch-socfpga/nic301.h | 195 ++++++++++++ arch/arm/include/asm/arch-socfpga/reset_manager.h | 6 + arch/arm/include/asm/arch-socfpga/scu.h | 23 ++ .../include/asm/arch-socfpga/socfpga_base_addrs.h | 62 +++- arch/arm/include/asm/arch-socfpga/system_manager.h | 111 +++++-- arch/arm/include/asm/system.h | 1 + arch/arm/lib/cache-cp15.c | 2 + board/altera/socfpga/pll_config.h | 3 + board/altera/socfpga/socfpga_cyclone5.c | 7 +- common/image.c | 1 + drivers/fpga/altera.c | 21 ++ drivers/mmc/dw_mmc.c | 26 +- drivers/mmc/socfpga_dw_mmc.c | 15 +- drivers/net/designware.c | 46 +-- drivers/net/phy/micrel.c | 7 +- include/altera.h | 1 + include/configs/axs101.h | 1 - include/configs/socfpga_cyclone5.h | 9 +- include/dwmmc.h | 2 +- include/image.h | 1 + tools/Makefile | 1 + tools/imagetool.c | 2 + tools/imagetool.h | 1 + tools/socfpgaimage.c | 255 +++++++++++++++ 33 files changed, 1753 insertions(+), 182 deletions(-) create mode 100644 arch/arm/cpu/armv7/socfpga/fpga_manager.c create mode 100644 arch/arm/include/asm/arch-socfpga/fpga_manager.h create mode 100644 arch/arm/include/asm/arch-socfpga/nic301.h create mode 100644 arch/arm/include/asm/arch-socfpga/scu.h create mode 100644 tools/socfpgaimage.c
Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de Cc: Joe Hershberger joe.hershberger@gmail.com

From: Pavel Machek pavel@denx.de
Remove this symbol from configs, since it's unused.
Signed-off-by: Pavel Machek pavel@denx.de Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de Cc: Joe Hershberger joe.hershberger@gmail.com --- include/configs/axs101.h | 1 - 1 file changed, 1 deletion(-)
diff --git a/include/configs/axs101.h b/include/configs/axs101.h index c22d6d0..1bf8390 100644 --- a/include/configs/axs101.h +++ b/include/configs/axs101.h @@ -125,7 +125,6 @@ */ #define CONFIG_DESIGNWARE_ETH #define CONFIG_DW_AUTONEG -#define CONFIG_DW_SEARCH_PHY #define CONFIG_NET_MULTI
/*

On 09/15/2014 06:05 AM, Marek Vasut wrote:
From: Pavel Machek pavel@denx.de
Remove this symbol from configs, since it's unused.
Signed-off-by: Pavel Machek pavel@denx.de Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de Cc: Joe Hershberger joe.hershberger@gmail.com
include/configs/axs101.h | 1 - 1 file changed, 1 deletion(-)
diff --git a/include/configs/axs101.h b/include/configs/axs101.h index c22d6d0..1bf8390 100644 --- a/include/configs/axs101.h +++ b/include/configs/axs101.h @@ -125,7 +125,6 @@ */ #define CONFIG_DESIGNWARE_ETH #define CONFIG_DW_AUTONEG -#define CONFIG_DW_SEARCH_PHY #define CONFIG_NET_MULTI
/*
Then we can probably remove CONFIG_DW_SEARCH_PHY from configs/socfpga_cyclone5.h too, right?
Dinh

On Monday, September 15, 2014 at 05:34:51 PM, Dinh Nguyen wrote:
On 09/15/2014 06:05 AM, Marek Vasut wrote:
From: Pavel Machek pavel@denx.de
Remove this symbol from configs, since it's unused.
Signed-off-by: Pavel Machek pavel@denx.de Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de Cc: Joe Hershberger joe.hershberger@gmail.com
include/configs/axs101.h | 1 - 1 file changed, 1 deletion(-)
diff --git a/include/configs/axs101.h b/include/configs/axs101.h index c22d6d0..1bf8390 100644 --- a/include/configs/axs101.h +++ b/include/configs/axs101.h @@ -125,7 +125,6 @@
*/
#define CONFIG_DESIGNWARE_ETH #define CONFIG_DW_AUTONEG
-#define CONFIG_DW_SEARCH_PHY
#define CONFIG_NET_MULTI
/*
Then we can probably remove CONFIG_DW_SEARCH_PHY from configs/socfpga_cyclone5.h too, right?
Yes, thanks for spotting this !
Best regards, Marek Vasut

From: Pavel Machek pavel@denx.de
Old saying says that more than three exclamation marks in a row are sign of mental disease. Cleanup micrel.c.
Signed-off-by: Pavel Machek pavel@denx.de Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de Cc: Joe Hershberger joe.hershberger@gmail.com --- drivers/net/phy/micrel.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 5d7e3be..507b9a3 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -25,8 +25,7 @@ static struct phy_driver KSZ804_driver = { #ifndef CONFIG_PHY_MICREL_KSZ9021 /* * I can't believe Micrel used the exact same part number - * for the KSZ9021 - * Shame Micrel, Shame!!!!! + * for the KSZ9021. Shame Micrel, Shame! */ static struct phy_driver KS8721_driver = { .name = "Micrel KS8721BL", @@ -40,7 +39,7 @@ static struct phy_driver KS8721_driver = { #endif
-/** +/* * KSZ9021 - KSZ9031 common */
@@ -69,8 +68,8 @@ static int ksz90xx_startup(struct phy_device *phydev) phydev->speed = SPEED_10; return 0; } -#ifdef CONFIG_PHY_MICREL_KSZ9021
+#ifdef CONFIG_PHY_MICREL_KSZ9021 /* * KSZ9021 */

Fix remaining cache alignment issues in the DWC Ethernet driver. Please note that the cache handling in the driver is making the code hideous and thus the next patch cleans that up. In order to make this change reviewable though, the cleanup is split from it.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de Cc: Joe Hershberger joe.hershberger@gmail.com --- drivers/net/designware.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 7186e3b..aaf146d 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -303,7 +303,8 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length)
/* Flush data to be sent */ flush_dcache_range((unsigned long)desc_p->dmamac_addr, - (unsigned long)desc_p->dmamac_addr + length); + (unsigned long)desc_p->dmamac_addr + + roundup(length, ARCH_DMA_MINALIGN));
#if defined(CONFIG_DW_ALTDESCRIPTOR) desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST; @@ -372,7 +373,8 @@ static int dw_eth_recv(struct eth_device *dev) /* Flush only status field - others weren't changed */ flush_dcache_range((unsigned long)&desc_p->txrx_status, (unsigned long)&desc_p->txrx_status + - sizeof(desc_p->txrx_status)); + roundup(sizeof(desc_p->txrx_status), + ARCH_DMA_MINALIGN));
/* Test the wrap-around condition. */ if (++desc_num >= CONFIG_RX_DESCR_NUM)

On 09/15/2014 06:05 AM, Marek Vasut wrote:
Fix remaining cache alignment issues in the DWC Ethernet driver. Please note that the cache handling in the driver is making the code hideous and thus the next patch cleans that up. In order to make this change reviewable though, the cleanup is split from it.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de Cc: Joe Hershberger joe.hershberger@gmail.com
drivers/net/designware.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 7186e3b..aaf146d 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -303,7 +303,8 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length)
/* Flush data to be sent */ flush_dcache_range((unsigned long)desc_p->dmamac_addr,
(unsigned long)desc_p->dmamac_addr + length);
(unsigned long)desc_p->dmamac_addr +
roundup(length, ARCH_DMA_MINALIGN));
#if defined(CONFIG_DW_ALTDESCRIPTOR) desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST; @@ -372,7 +373,8 @@ static int dw_eth_recv(struct eth_device *dev) /* Flush only status field - others weren't changed */ flush_dcache_range((unsigned long)&desc_p->txrx_status, (unsigned long)&desc_p->txrx_status +
sizeof(desc_p->txrx_status));
roundup(sizeof(desc_p->txrx_status),
Should you keep the number of tabs the same here?
Thanks, Dinh
ARCH_DMA_MINALIGN));
/* Test the wrap-around condition. */ if (++desc_num >= CONFIG_RX_DESCR_NUM)

On Monday, September 15, 2014 at 05:40:54 PM, Dinh Nguyen wrote:
On 09/15/2014 06:05 AM, Marek Vasut wrote:
Fix remaining cache alignment issues in the DWC Ethernet driver. Please note that the cache handling in the driver is making the code hideous and thus the next patch cleans that up. In order to make this change reviewable though, the cleanup is split from it.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de Cc: Joe Hershberger joe.hershberger@gmail.com
drivers/net/designware.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 7186e3b..aaf146d 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -303,7 +303,8 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length)
/* Flush data to be sent */ flush_dcache_range((unsigned long)desc_p->dmamac_addr,
(unsigned long)desc_p->dmamac_addr + length);
(unsigned long)desc_p->dmamac_addr +
roundup(length, ARCH_DMA_MINALIGN));
#if defined(CONFIG_DW_ALTDESCRIPTOR)
desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST;
@@ -372,7 +373,8 @@ static int dw_eth_recv(struct eth_device *dev)
/* Flush only status field - others weren't changed */ flush_dcache_range((unsigned long)&desc_p->txrx_status,
(unsigned long)&desc_p->txrx_status +
sizeof(desc_p->txrx_status));
roundup(sizeof(desc_p->txrx_status),
Should you keep the number of tabs the same here?
This code goes in the following patch, so it's rather irrelevant.
Best regards, Marek Vasut

Add a few new variables to make the cache handling less cryptic. Add a variable for DMA and DATA descriptor start and end, so the correctness of the code is easier to inspect.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de Cc: Joe Hershberger joe.hershberger@gmail.com --- drivers/net/designware.c | 48 +++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 25 deletions(-)
diff --git a/drivers/net/designware.c b/drivers/net/designware.c index aaf146d..9ded895 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -279,19 +279,21 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length) struct eth_dma_regs *dma_p = priv->dma_regs_p; u32 desc_num = priv->tx_currdescnum; struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num]; - + uint32_t desc_start = (uint32_t)desc_p; + uint32_t desc_end = desc_start + + roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN); + uint32_t data_start = (uint32_t)desc_p->dmamac_addr; + uint32_t data_end = data_start + + roundup(length, ARCH_DMA_MINALIGN); /* * Strictly we only need to invalidate the "txrx_status" field * for the following check, but on some platforms we cannot - * invalidate only 4 bytes, so roundup to - * ARCH_DMA_MINALIGN. This is safe because the individual - * descriptors in the array are each aligned to - * ARCH_DMA_MINALIGN. + * invalidate only 4 bytes, so we flush the entire descriptor, + * which is 16 bytes in total. This is safe because the + * individual descriptors in the array are each aligned to + * ARCH_DMA_MINALIGN and padded appropriately. */ - invalidate_dcache_range( - (unsigned long)desc_p, - (unsigned long)desc_p + - roundup(sizeof(desc_p->txrx_status), ARCH_DMA_MINALIGN)); + invalidate_dcache_range(desc_start, desc_end);
/* Check if the descriptor is owned by CPU */ if (desc_p->txrx_status & DESC_TXSTS_OWNBYDMA) { @@ -299,12 +301,10 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length) return -1; }
- memcpy((void *)desc_p->dmamac_addr, packet, length); + memcpy(desc_p->dmamac_addr, packet, length);
/* Flush data to be sent */ - flush_dcache_range((unsigned long)desc_p->dmamac_addr, - (unsigned long)desc_p->dmamac_addr + - roundup(length, ARCH_DMA_MINALIGN)); + flush_dcache_range(data_start, data_end);
#if defined(CONFIG_DW_ALTDESCRIPTOR) desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST; @@ -322,8 +322,7 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length) #endif
/* Flush modified buffer descriptor */ - flush_dcache_range((unsigned long)desc_p, - (unsigned long)desc_p + sizeof(struct dmamacdescr)); + flush_dcache_range(desc_start, desc_end);
/* Test the wrap-around condition. */ if (++desc_num >= CONFIG_TX_DESCR_NUM) @@ -343,11 +342,14 @@ static int dw_eth_recv(struct eth_device *dev) u32 status, desc_num = priv->rx_currdescnum; struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num]; int length = 0; + uint32_t desc_start = (uint32_t)desc_p; + uint32_t desc_end = desc_start + + roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN); + uint32_t data_start = (uint32_t)desc_p->dmamac_addr; + uint32_t data_end;
/* Invalidate entire buffer descriptor */ - invalidate_dcache_range((unsigned long)desc_p, - (unsigned long)desc_p + - sizeof(struct dmamacdescr)); + invalidate_dcache_range(desc_start, desc_end);
status = desc_p->txrx_status;
@@ -358,9 +360,8 @@ static int dw_eth_recv(struct eth_device *dev) DESC_RXSTS_FRMLENSHFT;
/* Invalidate received data */ - invalidate_dcache_range((unsigned long)desc_p->dmamac_addr, - (unsigned long)desc_p->dmamac_addr + - roundup(length, ARCH_DMA_MINALIGN)); + data_end = data_start + roundup(length, ARCH_DMA_MINALIGN); + invalidate_dcache_range(data_start, data_end);
NetReceive(desc_p->dmamac_addr, length);
@@ -371,10 +372,7 @@ static int dw_eth_recv(struct eth_device *dev) desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA;
/* Flush only status field - others weren't changed */ - flush_dcache_range((unsigned long)&desc_p->txrx_status, - (unsigned long)&desc_p->txrx_status + - roundup(sizeof(desc_p->txrx_status), - ARCH_DMA_MINALIGN)); + flush_dcache_range(desc_start, desc_end);
/* Test the wrap-around condition. */ if (++desc_num >= CONFIG_RX_DESCR_NUM)

On Mon 2014-09-15 13:05:57, Marek Vasut wrote:
Add a few new variables to make the cache handling less cryptic. Add a variable for DMA and DATA descriptor start and end, so the correctness of the code is easier to inspect.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de
Acked-by: Pavel Machek pavel@denx.de

On Mon 2014-09-15 13:05:57, Marek Vasut wrote:
Add a few new variables to make the cache handling less cryptic. Add a variable for DMA and DATA descriptor start and end, so the correctness of the code is easier to inspect.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de
Acked-by: Pavel Machek pavel@denx.de

From: Pavel Machek pavel@denx.de
The dw_mmc driver was responding to errors with debug(). Change that to prinf()/puts() respectively so that any errors are immediately obvious. Also adjust english in comments.
Signed-off-by: Pavel Machek pavel@denx.de Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de Cc: Pantelis Antoniou panto@antoniou-consulting.com --- drivers/mmc/dw_mmc.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 0df30bc..f4a6b88 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -119,7 +119,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) { if (get_timer(start) > timeout) { - printf("Timeout on data busy\n"); + printf("%s: Timeout on data busy\n", __func__); return TIMEOUT; } } @@ -177,14 +177,16 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, } }
- if (i == retry) + if (i == retry) { + printf("%s: Timeout.\n", __func__); return TIMEOUT; + }
if (mask & DWMCI_INTMSK_RTO) { - debug("Response Timeout..\n"); + printf("%s: Response Timeout.\n", __func__); return TIMEOUT; } else if (mask & DWMCI_INTMSK_RE) { - debug("Response Error..\n"); + printf("%s: Response Error.\n", __func__); return -1; }
@@ -204,7 +206,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, do { mask = dwmci_readl(host, DWMCI_RINTSTS); if (mask & (DWMCI_DATA_ERR | DWMCI_DATA_TOUT)) { - debug("DATA ERROR!\n"); + printf("%s: DATA ERROR!\n", __func__); return -1; } } while (!(mask & DWMCI_INTMSK_DTO)); @@ -232,16 +234,16 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq) if ((freq == host->clock) || (freq == 0)) return 0; /* - * If host->get_mmc_clk didn't define, + * If host->get_mmc_clk isn't defined, * then assume that host->bus_hz is source clock value. - * host->bus_hz should be set from user. + * host->bus_hz should be set by user. */ if (host->get_mmc_clk) sclk = host->get_mmc_clk(host); else if (host->bus_hz) sclk = host->bus_hz; else { - printf("Didn't get source clock value..\n"); + printf("%s: Didn't get source clock value.\n", __func__); return -EINVAL; }
@@ -260,7 +262,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq) do { status = dwmci_readl(host, DWMCI_CMD); if (timeout-- < 0) { - printf("TIMEOUT error!!\n"); + printf("%s: Timeout!\n", __func__); return -ETIMEDOUT; } } while (status & DWMCI_CMD_START); @@ -275,7 +277,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq) do { status = dwmci_readl(host, DWMCI_CMD); if (timeout-- < 0) { - printf("TIMEOUT error!!\n"); + printf("%s: Timeout!\n", __func__); return -ETIMEDOUT; } } while (status & DWMCI_CMD_START); @@ -290,7 +292,7 @@ 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); + debug("Buswidth = %d, clock: %d\n", mmc->bus_width, mmc->clock);
dwmci_setup_bus(host, mmc->clock); switch (mmc->bus_width) { @@ -329,7 +331,7 @@ static int dwmci_init(struct mmc *mmc) dwmci_writel(host, DWMCI_PWREN, 1);
if (!dwmci_wait_reset(host, DWMCI_RESET_ALL)) { - debug("%s[%d] Fail-reset!!\n",__func__,__LINE__); + printf("%s[%d] Fail-reset!!\n", __func__, __LINE__); return -1; }

On 09/15/2014 06:05 AM, Marek Vasut wrote:
From: Pavel Machek pavel@denx.de
The dw_mmc driver was responding to errors with debug(). Change that to prinf()/puts() respectively so that any errors are immediately obvious. Also adjust english in comments.
Signed-off-by: Pavel Machek pavel@denx.de Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de Cc: Pantelis Antoniou panto@antoniou-consulting.com
drivers/mmc/dw_mmc.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 0df30bc..f4a6b88 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -119,7 +119,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) { if (get_timer(start) > timeout) {
printf("Timeout on data busy\n");
} }printf("%s: Timeout on data busy\n", __func__); return TIMEOUT;
@@ -177,14 +177,16 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, } }
- if (i == retry)
if (i == retry) {
printf("%s: Timeout.\n", __func__);
return TIMEOUT;
}
if (mask & DWMCI_INTMSK_RTO) {
debug("Response Timeout..\n");
return TIMEOUT; } else if (mask & DWMCI_INTMSK_RE) {printf("%s: Response Timeout.\n", __func__);
debug("Response Error..\n");
return -1; }printf("%s: Response Error.\n", __func__);
@@ -204,7 +206,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, do { mask = dwmci_readl(host, DWMCI_RINTSTS); if (mask & (DWMCI_DATA_ERR | DWMCI_DATA_TOUT)) {
debug("DATA ERROR!\n");
} while (!(mask & DWMCI_INTMSK_DTO));printf("%s: DATA ERROR!\n", __func__); return -1; }
@@ -232,16 +234,16 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq) if ((freq == host->clock) || (freq == 0)) return 0; /*
* If host->get_mmc_clk didn't define,
* If host->get_mmc_clk isn't defined,
- then assume that host->bus_hz is source clock value.
* host->bus_hz should be set from user.
*/ if (host->get_mmc_clk) sclk = host->get_mmc_clk(host); else if (host->bus_hz) sclk = host->bus_hz; else {* host->bus_hz should be set by user.
printf("Didn't get source clock value..\n");
return -EINVAL; }printf("%s: Didn't get source clock value.\n", __func__);
@@ -260,7 +262,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq) do { status = dwmci_readl(host, DWMCI_CMD); if (timeout-- < 0) {
printf("TIMEOUT error!!\n");
} } while (status & DWMCI_CMD_START);printf("%s: Timeout!\n", __func__); return -ETIMEDOUT;
@@ -275,7 +277,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq) do { status = dwmci_readl(host, DWMCI_CMD); if (timeout-- < 0) {
printf("TIMEOUT error!!\n");
} } while (status & DWMCI_CMD_START);printf("%s: Timeout!\n", __func__); return -ETIMEDOUT;
@@ -290,7 +292,7 @@ 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);
- debug("Buswidth = %d, clock: %d\n", mmc->bus_width, mmc->clock);
Did you intend to use printf here also? Or just fix up the spacing around mmc->bus_width?
Dinh
dwmci_setup_bus(host, mmc->clock); switch (mmc->bus_width) { @@ -329,7 +331,7 @@ static int dwmci_init(struct mmc *mmc) dwmci_writel(host, DWMCI_PWREN, 1);
if (!dwmci_wait_reset(host, DWMCI_RESET_ALL)) {
debug("%s[%d] Fail-reset!!\n",__func__,__LINE__);
return -1; }printf("%s[%d] Fail-reset!!\n", __func__, __LINE__);

On Monday, September 15, 2014 at 06:00:47 PM, Dinh Nguyen wrote:
On 09/15/2014 06:05 AM, Marek Vasut wrote:
From: Pavel Machek pavel@denx.de
The dw_mmc driver was responding to errors with debug(). Change that to prinf()/puts() respectively so that any errors are immediately obvious. Also adjust english in comments.
[...]
@@ -290,7 +292,7 @@ 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);
- debug("Buswidth = %d, clock: %d\n", mmc->bus_width, mmc->clock);
Did you intend to use printf here also? Or just fix up the spacing around mmc->bus_width?
This cannot be a printf(), since you would get an output upon every call of .set_ios(). This would generate a wall of text. So this is formatting fix.
Best regards, Marek Vasut

The DMA descriptors used by the DW MMC block must be aligned to cacheline size, otherwise we are unable to properly flush/inval cache over them and we get data corruption.
The reason I chose this approach of expanding the structure is because the driver allocates the descriptors in bulk. This approach does waste space by inserting slop inbetween the descriptors, but it makes access to the descriptors easy as the compiler does know the real size of the structure. It also makes cache operations easy, since the size of the structure is cache aligned and the structure start address is as well.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de Cc: Pantelis Antoniou panto@antoniou-consulting.com --- include/dwmmc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/dwmmc.h b/include/dwmmc.h index b67f11b..109f7c8 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -157,7 +157,7 @@ struct dwmci_idmac { u32 cnt; u32 addr; u32 next_addr; -}; +} __aligned(ARCH_DMA_MINALIGN);
static inline void dwmci_writel(struct dwmci_host *host, int reg, u32 val) {

On Mon 2014-09-15 13:05:57, Marek Vasut wrote:
Add a few new variables to make the cache handling less cryptic. Add a variable for DMA and DATA descriptor start and end, so the correctness of the code is easier to inspect.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de
Acked-by: Pavel Machek pavel@denx.de

From: Charles Manning cdhmanning@gmail.com
Like many platforms, the Altera socfpga platform requires that the preloader be "signed" in a certain way or the built-in boot ROM will not boot the code.
This change automatically creates an appropriately signed preloader from an SPL image.
The signed image includes a CRC which must, of course, be generated with a CRC generator that the SoCFPGA boot ROM agrees with otherwise the boot ROM will reject the image.
Unfortunately the CRC used in this boot ROM is not the same as the Adler CRC in lib/crc32.c. Indeed the Adler code is not technically a CRC but is more correctly described as a checksum.
Thus, the appropriate CRC generator is added to lib/ as crc32_alt.c.
Signed-off-by: Charles Manning cdhmanning@gmail.com Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- common/image.c | 1 + include/image.h | 1 + tools/Makefile | 1 + tools/imagetool.c | 2 + tools/imagetool.h | 1 + tools/socfpgaimage.c | 255 +++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 261 insertions(+) create mode 100644 tools/socfpgaimage.c
diff --git a/common/image.c b/common/image.c index 38b56e3..085771c 100644 --- a/common/image.c +++ b/common/image.c @@ -138,6 +138,7 @@ static const table_entry_t uimage_type[] = { { IH_TYPE_PBLIMAGE, "pblimage", "Freescale PBL Boot Image",}, { IH_TYPE_RAMDISK, "ramdisk", "RAMDisk Image", }, { IH_TYPE_SCRIPT, "script", "Script", }, + { IH_TYPE_SOCFPGAIMAGE, "socfpgaimage", "Altera SOCFPGA preloader",}, { IH_TYPE_STANDALONE, "standalone", "Standalone Program", }, { IH_TYPE_UBLIMAGE, "ublimage", "Davinci UBL image",}, { IH_TYPE_MXSIMAGE, "mxsimage", "Freescale MXS Boot Image",}, diff --git a/include/image.h b/include/image.h index 3401056..4347532 100644 --- a/include/image.h +++ b/include/image.h @@ -232,6 +232,7 @@ struct lmb; #define IH_TYPE_MXSIMAGE 16 /* Freescale MXSBoot Image */ #define IH_TYPE_GPIMAGE 17 /* TI Keystone GPHeader Image */ #define IH_TYPE_ATMELIMAGE 18 /* ATMEL ROM bootable Image */ +#define IH_TYPE_SOCFPGAIMAGE 19 /* Altera SOCFPGA Preloader */
/* * Compression Types diff --git a/tools/Makefile b/tools/Makefile index 90e966d..2b05b20 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -87,6 +87,7 @@ dumpimage-mkimage-objs := aisimage.o \ os_support.o \ pblimage.o \ pbl_crc32.o \ + socfpgaimage.o \ lib/sha1.o \ lib/sha256.o \ ublimage.o \ diff --git a/tools/imagetool.c b/tools/imagetool.c index 32d6278..98717bd 100644 --- a/tools/imagetool.c +++ b/tools/imagetool.c @@ -47,6 +47,8 @@ void register_image_tool(imagetool_register_t image_register) init_ubl_image_type(); /* Init Davinci AIS support */ init_ais_image_type(); + /* Init Altera SOCFPGA support */ + init_socfpga_image_type(); /* Init TI Keystone boot image generation/list support */ init_gpimage_type(); } diff --git a/tools/imagetool.h b/tools/imagetool.h index c8af0e8..8bce059 100644 --- a/tools/imagetool.h +++ b/tools/imagetool.h @@ -168,6 +168,7 @@ void init_mxs_image_type(void); void init_fit_image_type(void); void init_ubl_image_type(void); void init_omap_image_type(void); +void init_socfpga_image_type(void); void init_gpimage_type(void);
void pbl_load_uboot(int fd, struct image_tool_params *mparams); diff --git a/tools/socfpgaimage.c b/tools/socfpgaimage.c new file mode 100644 index 0000000..32fa09f --- /dev/null +++ b/tools/socfpgaimage.c @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2014 Charles Manning cdhmanning@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Reference doc http://www.altera.com.cn/literature/hb/cyclone-v/cv_5400A.pdf + * Note this doc is not entirely accurate. Of particular interest to us is the + * "header" length field being in U32s and not bytes. + * + * "Header" is a structure of the following format. + * this is positioned at 0x40. + * + * Endian is LSB. + * + * Offset Length Usage + * ----------------------- + * 0x40 4 Validation word 0x31305341 + * 0x44 1 Version (whatever, zero is fine) + * 0x45 1 Flags (unused, zero is fine) + * 0x46 2 Length (in units of u32, including the end checksum). + * 0x48 2 Zero + * 0x4A 2 Checksum over the header. NB Not CRC32 + * + * At the end of the code we have a 32-bit CRC checksum over whole binary + * excluding the CRC. + * + * Note that the CRC used here is **not** the zlib/Adler crc32. It is the + * CRC-32 used in bzip2, ethernet and elsewhere. + * + * The image is padded out to 64k, because that is what is + * typically used to write the image to the boot medium. + */ + +#include "pbl_crc32.h" +#include "imagetool.h" +#include <image.h> + +#define HEADER_OFFSET 0x40 +#define HEADER_SIZE 0xC +#define VALIDATION_WORD 0x31305341 +#define PADDED_SIZE 0x10000 + +/* To allow for adding CRC, the max input size is a bit smaller. */ +#define MAX_INPUT_SIZE (PADDED_SIZE - sizeof(uint32_t)) + +static uint8_t buffer[PADDED_SIZE]; + +static struct { + uint32_t validation; + uint8_t version; + uint8_t flags; + uint16_t length_u32; + uint16_t zero; + uint16_t checksum; +} header; + +/* + * The header checksum is just a very simple checksum over + * the header area. + * There is still a crc32 over the whole lot. + */ +static uint16_t hdr_checksum(const uint8_t *buf, int len) +{ + uint16_t ret = 0; + int i; + + for (i = 0; i < len; i++) { + ret += (((uint16_t) *buf) & 0xff); + buf++; + } + return ret; +} + + +static void build_header(uint8_t *buf, + uint8_t version, + uint8_t flags, + uint16_t length_bytes) +{ + header.validation = htole32(VALIDATION_WORD); + header.version = version; + header.flags = flags; + header.length_u32 = htole16(length_bytes/4); + header.zero = 0; + header.checksum = htole16(hdr_checksum((const uint8_t *)&header, 10)); + + memcpy(buf, &header, sizeof(header)); +} + +/* + * Perform a rudimentary verification of header and return + * size of image. + */ +static int verify_header(const uint8_t *buf) +{ + memcpy(&header, buf, sizeof(header)); + + if (le32toh(header.validation) != VALIDATION_WORD) + return -1; + if (le16toh(header.checksum) != + hdr_checksum((const uint8_t *)&header, 10)) + return -1; + + return le16toh(header.length_u32) * 4; +} + +/* Sign the buffer and return the signed buffer size */ +static int sign_buffer(uint8_t *buf, + uint8_t version, uint8_t flags, + int len, int pad_64k) +{ + uint32_t calc_crc; + + /* Align the length up */ + len = (len + 3) & (~3); + + /* Build header, adding 4 bytes to length to hold the CRC32. */ + build_header(buf + HEADER_OFFSET, version, flags, len + 4); + + /* Calculate and apply the CRC */ + calc_crc = ~pbl_crc32(0, (char *)buf, len); + + *((uint32_t *)(buf + len)) = htole32(calc_crc); + + if (!pad_64k) + return len + 4; + + return PADDED_SIZE; +} + +/* Verify that the buffer looks sane */ +static int verify_buffer(const uint8_t *buf) +{ + int len; /* Including 32bit CRC */ + uint32_t calc_crc; + uint32_t buf_crc; + + len = verify_header(buf + HEADER_OFFSET); + if (len < 0) + return -1; + if (len < HEADER_OFFSET || len > PADDED_SIZE) + return -1; + + /* + * Adjust length to the base of the CRC. + * Check the CRC. + */ + len -= 4; + + calc_crc = ~pbl_crc32(0, (const char *)buf, len); + + buf_crc = le32toh(*((uint32_t *)(buf + len))); + + if (buf_crc != calc_crc) + return -1; + + return 0; +} + +/* mkimage glue functions */ +static int socfpgaimage_verify_header(unsigned char *ptr, int image_size, + struct image_tool_params *params) +{ + if (image_size != PADDED_SIZE) + return -1; + + return verify_buffer(ptr); +} + +static void socfpgaimage_print_header(const void *ptr) +{ + if (verify_buffer(ptr) == 0) + printf("Looks like a sane SOCFPGA preloader\n"); + else + printf("Not a sane SOCFPGA preloader\n"); +} + +static int socfpgaimage_check_params(struct image_tool_params *params) +{ + /* Not sure if we should be accepting fflags */ + return (params->dflag && (params->fflag || params->lflag)) || + (params->fflag && (params->dflag || params->lflag)) || + (params->lflag && (params->dflag || params->fflag)); +} + +static int socfpgaimage_check_image_types(uint8_t type) +{ + if (type == IH_TYPE_SOCFPGAIMAGE) + return EXIT_SUCCESS; + return EXIT_FAILURE; +} + +/* + * To work in with the mkimage framework, we do some ugly stuff... + * + * First, socfpgaimage_vrec_header() is called. + * We prepend a fake header big enough to make the file PADDED_SIZE. + * This gives us enough space to do what we want later. + * + * Next, socfpgaimage_set_header() is called. + * We fix up the buffer by moving the image to the start of the buffer. + * We now have some room to do what we need (add CRC and padding). + */ + +static int data_size; +#define FAKE_HEADER_SIZE (PADDED_SIZE - data_size) + +static int socfpgaimage_vrec_header(struct image_tool_params *params, + struct image_type_params *tparams) +{ + struct stat sbuf; + + if (params->datafile && + stat(params->datafile, &sbuf) == 0 && + sbuf.st_size <= MAX_INPUT_SIZE) { + data_size = sbuf.st_size; + tparams->header_size = FAKE_HEADER_SIZE; + } + return 0; +} + +static void socfpgaimage_set_header(void *ptr, struct stat *sbuf, int ifd, + struct image_tool_params *params) +{ + uint8_t *buf = (uint8_t *)ptr; + + /* + * This function is called after vrec_header() has been called. + * At this stage we have the FAKE_HEADER_SIZE dummy bytes followed by + * data_size image bytes. Total = PADDED_SIZE. + * We need to fix the buffer by moving the image bytes back to + * the beginning of the buffer, then actually do the signing stuff... + */ + memmove(buf, buf + FAKE_HEADER_SIZE, data_size); + memset(buf + data_size, 0, FAKE_HEADER_SIZE); + + sign_buffer(buf, 0, 0, data_size, 0); +} + +static struct image_type_params socfpgaimage_params = { + .name = "Altera SOCFPGA preloader support", + .vrec_header = socfpgaimage_vrec_header, + .header_size = 0, /* This will be modified by vrec_header() */ + .hdr = (void *)buffer, + .check_image_type = socfpgaimage_check_image_types, + .verify_header = socfpgaimage_verify_header, + .print_header = socfpgaimage_print_header, + .set_header = socfpgaimage_set_header, + .check_params = socfpgaimage_check_params, +}; + +void init_socfpga_image_type(void) +{ + register_image_type(&socfpgaimage_params); +}

From: Pavel Machek pavel@denx.de
Add base addresses for all subsystems as documented in the Cyclone V HPS documentation.
Signed-off-by: Pavel Machek pavel@denx.de Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- .../include/asm/arch-socfpga/socfpga_base_addrs.h | 40 ++++++++++++++++++++++ 1 file changed, 40 insertions(+)
diff --git a/arch/arm/include/asm/arch-socfpga/socfpga_base_addrs.h b/arch/arm/include/asm/arch-socfpga/socfpga_base_addrs.h index 2d3152d..cb062ac 100644 --- a/arch/arm/include/asm/arch-socfpga/socfpga_base_addrs.h +++ b/arch/arm/include/asm/arch-socfpga/socfpga_base_addrs.h @@ -7,16 +7,56 @@ #ifndef _SOCFPGA_BASE_ADDRS_H_ #define _SOCFPGA_BASE_ADDRS_H_
+#define SOCFPGA_SDMMC_ADDRESS 0xff704000 +#define SOCFPGA_FPGAMGRREGS_ADDRESS 0xff706000 #define SOCFPGA_L3REGS_ADDRESS 0xff800000 +#define SOCFPGA_FPGAMGRDATA_ADDRESS 0xffb90000 #define SOCFPGA_UART0_ADDRESS 0xffc02000 #define SOCFPGA_UART1_ADDRESS 0xffc03000 +#define SOCFPGA_SDR_ADDRESS 0xffc20000 #define SOCFPGA_OSC1TIMER0_ADDRESS 0xffd00000 +#define SOCFPGA_OSC1TIMER1_ADDRESS 0xffd01000 #define SOCFPGA_L4WD0_ADDRESS 0xffd02000 +#define SOCFPGA_L4WD1_ADDRESS 0xffd03000 #define SOCFPGA_CLKMGR_ADDRESS 0xffd04000 #define SOCFPGA_RSTMGR_ADDRESS 0xffd05000 #define SOCFPGA_SYSMGR_ADDRESS 0xffd08000 #define SOCFPGA_SCANMGR_ADDRESS 0xfff02000 #define SOCFPGA_EMAC0_ADDRESS 0xff700000 #define SOCFPGA_EMAC1_ADDRESS 0xff702000 +#define SOCFPGA_MPUL2_ADDRESS 0xfffef000 +#define SOCFPGA_MPUSCU_ADDRESS 0xfffec000 +#define SOCFPGA_STM_ADDRESS 0xfc000000 +#define SOCFPGA_DAP_ADDRESS 0xff000000 +#define SOCFPGA_LWFPGASLAVES_ADDRESS 0xff200000 +#define SOCFPGA_LWHPS2FPGAREGS_ADDRESS 0xff400000 +#define SOCFPGA_HPS2FPGAREGS_ADDRESS 0xff500000 +#define SOCFPGA_FPGA2HPSREGS_ADDRESS 0xff600000 +#define SOCFPGA_QSPI_ADDRESS 0xff705000 +#define SOCFPGA_ACPIDMAP_ADDRESS 0xff707000 +#define SOCFPGA_GPIO0_ADDRESS 0xff708000 +#define SOCFPGA_GPIO1_ADDRESS 0xff709000 +#define SOCFPGA_GPIO2_ADDRESS 0xff70a000 +#define SOCFPGA_NANDDATA_ADDRESS 0xff900000 +#define SOCFPGA_QSPIDATA_ADDRESS 0xffa00000 +#define SOCFPGA_USB0_ADDRESS 0xffb00000 +#define SOCFPGA_USB1_ADDRESS 0xffb40000 +#define SOCFPGA_NANDREGS_ADDRESS 0xffb80000 +#define SOCFPGA_CAN0_ADDRESS 0xffc00000 +#define SOCFPGA_CAN1_ADDRESS 0xffc01000 +#define SOCFPGA_I2C0_ADDRESS 0xffc04000 +#define SOCFPGA_I2C1_ADDRESS 0xffc05000 +#define SOCFPGA_I2C2_ADDRESS 0xffc06000 +#define SOCFPGA_I2C3_ADDRESS 0xffc07000 +#define SOCFPGA_SPTIMER0_ADDRESS 0xffc08000 +#define SOCFPGA_SPTIMER1_ADDRESS 0xffc09000 +#define SOCFPGA_DMANONSECURE_ADDRESS 0xffe00000 +#define SOCFPGA_DMASECURE_ADDRESS 0xffe01000 +#define SOCFPGA_SPIS0_ADDRESS 0xffe02000 +#define SOCFPGA_SPIS1_ADDRESS 0xffe03000 +#define SOCFPGA_SPIM0_ADDRESS 0xfff00000 +#define SOCFPGA_SPIM1_ADDRESS 0xfff01000 +#define SOCFPGA_ROM_ADDRESS 0xfffd0000 +#define SOCFPGA_OCRAM_ADDRESS 0xffff0000
#endif /* _SOCFPGA_BASE_ADDRS_H_ */

Sort the list of functional block addresses and fix indentation. No functional change.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- .../include/asm/arch-socfpga/socfpga_base_addrs.h | 102 ++++++++++----------- 1 file changed, 51 insertions(+), 51 deletions(-)
diff --git a/arch/arm/include/asm/arch-socfpga/socfpga_base_addrs.h b/arch/arm/include/asm/arch-socfpga/socfpga_base_addrs.h index cb062ac..6534283 100644 --- a/arch/arm/include/asm/arch-socfpga/socfpga_base_addrs.h +++ b/arch/arm/include/asm/arch-socfpga/socfpga_base_addrs.h @@ -7,56 +7,56 @@ #ifndef _SOCFPGA_BASE_ADDRS_H_ #define _SOCFPGA_BASE_ADDRS_H_
-#define SOCFPGA_SDMMC_ADDRESS 0xff704000 -#define SOCFPGA_FPGAMGRREGS_ADDRESS 0xff706000 -#define SOCFPGA_L3REGS_ADDRESS 0xff800000 -#define SOCFPGA_FPGAMGRDATA_ADDRESS 0xffb90000 -#define SOCFPGA_UART0_ADDRESS 0xffc02000 -#define SOCFPGA_UART1_ADDRESS 0xffc03000 -#define SOCFPGA_SDR_ADDRESS 0xffc20000 -#define SOCFPGA_OSC1TIMER0_ADDRESS 0xffd00000 -#define SOCFPGA_OSC1TIMER1_ADDRESS 0xffd01000 -#define SOCFPGA_L4WD0_ADDRESS 0xffd02000 -#define SOCFPGA_L4WD1_ADDRESS 0xffd03000 -#define SOCFPGA_CLKMGR_ADDRESS 0xffd04000 -#define SOCFPGA_RSTMGR_ADDRESS 0xffd05000 -#define SOCFPGA_SYSMGR_ADDRESS 0xffd08000 -#define SOCFPGA_SCANMGR_ADDRESS 0xfff02000 -#define SOCFPGA_EMAC0_ADDRESS 0xff700000 -#define SOCFPGA_EMAC1_ADDRESS 0xff702000 -#define SOCFPGA_MPUL2_ADDRESS 0xfffef000 -#define SOCFPGA_MPUSCU_ADDRESS 0xfffec000 -#define SOCFPGA_STM_ADDRESS 0xfc000000 -#define SOCFPGA_DAP_ADDRESS 0xff000000 -#define SOCFPGA_LWFPGASLAVES_ADDRESS 0xff200000 -#define SOCFPGA_LWHPS2FPGAREGS_ADDRESS 0xff400000 -#define SOCFPGA_HPS2FPGAREGS_ADDRESS 0xff500000 -#define SOCFPGA_FPGA2HPSREGS_ADDRESS 0xff600000 -#define SOCFPGA_QSPI_ADDRESS 0xff705000 -#define SOCFPGA_ACPIDMAP_ADDRESS 0xff707000 -#define SOCFPGA_GPIO0_ADDRESS 0xff708000 -#define SOCFPGA_GPIO1_ADDRESS 0xff709000 -#define SOCFPGA_GPIO2_ADDRESS 0xff70a000 -#define SOCFPGA_NANDDATA_ADDRESS 0xff900000 -#define SOCFPGA_QSPIDATA_ADDRESS 0xffa00000 -#define SOCFPGA_USB0_ADDRESS 0xffb00000 -#define SOCFPGA_USB1_ADDRESS 0xffb40000 -#define SOCFPGA_NANDREGS_ADDRESS 0xffb80000 -#define SOCFPGA_CAN0_ADDRESS 0xffc00000 -#define SOCFPGA_CAN1_ADDRESS 0xffc01000 -#define SOCFPGA_I2C0_ADDRESS 0xffc04000 -#define SOCFPGA_I2C1_ADDRESS 0xffc05000 -#define SOCFPGA_I2C2_ADDRESS 0xffc06000 -#define SOCFPGA_I2C3_ADDRESS 0xffc07000 -#define SOCFPGA_SPTIMER0_ADDRESS 0xffc08000 -#define SOCFPGA_SPTIMER1_ADDRESS 0xffc09000 -#define SOCFPGA_DMANONSECURE_ADDRESS 0xffe00000 -#define SOCFPGA_DMASECURE_ADDRESS 0xffe01000 -#define SOCFPGA_SPIS0_ADDRESS 0xffe02000 -#define SOCFPGA_SPIS1_ADDRESS 0xffe03000 -#define SOCFPGA_SPIM0_ADDRESS 0xfff00000 -#define SOCFPGA_SPIM1_ADDRESS 0xfff01000 -#define SOCFPGA_ROM_ADDRESS 0xfffd0000 -#define SOCFPGA_OCRAM_ADDRESS 0xffff0000 +#define SOCFPGA_STM_ADDRESS 0xfc000000 +#define SOCFPGA_DAP_ADDRESS 0xff000000 +#define SOCFPGA_EMAC0_ADDRESS 0xff700000 +#define SOCFPGA_EMAC1_ADDRESS 0xff702000 +#define SOCFPGA_SDMMC_ADDRESS 0xff704000 +#define SOCFPGA_QSPI_ADDRESS 0xff705000 +#define SOCFPGA_GPIO0_ADDRESS 0xff708000 +#define SOCFPGA_GPIO1_ADDRESS 0xff709000 +#define SOCFPGA_GPIO2_ADDRESS 0xff70a000 +#define SOCFPGA_L3REGS_ADDRESS 0xff800000 +#define SOCFPGA_USB0_ADDRESS 0xffb00000 +#define SOCFPGA_USB1_ADDRESS 0xffb40000 +#define SOCFPGA_CAN0_ADDRESS 0xffc00000 +#define SOCFPGA_CAN1_ADDRESS 0xffc01000 +#define SOCFPGA_UART0_ADDRESS 0xffc02000 +#define SOCFPGA_UART1_ADDRESS 0xffc03000 +#define SOCFPGA_I2C0_ADDRESS 0xffc04000 +#define SOCFPGA_I2C1_ADDRESS 0xffc05000 +#define SOCFPGA_I2C2_ADDRESS 0xffc06000 +#define SOCFPGA_I2C3_ADDRESS 0xffc07000 +#define SOCFPGA_SDR_ADDRESS 0xffc20000 +#define SOCFPGA_L4WD0_ADDRESS 0xffd02000 +#define SOCFPGA_L4WD1_ADDRESS 0xffd03000 +#define SOCFPGA_CLKMGR_ADDRESS 0xffd04000 +#define SOCFPGA_RSTMGR_ADDRESS 0xffd05000 +#define SOCFPGA_SYSMGR_ADDRESS 0xffd08000 +#define SOCFPGA_SPIS0_ADDRESS 0xffe02000 +#define SOCFPGA_SPIS1_ADDRESS 0xffe03000 +#define SOCFPGA_SPIM0_ADDRESS 0xfff00000 +#define SOCFPGA_SPIM1_ADDRESS 0xfff01000 +#define SOCFPGA_SCANMGR_ADDRESS 0xfff02000 +#define SOCFPGA_ROM_ADDRESS 0xfffd0000 +#define SOCFPGA_MPUSCU_ADDRESS 0xfffec000 +#define SOCFPGA_MPUL2_ADDRESS 0xfffef000 +#define SOCFPGA_OCRAM_ADDRESS 0xffff0000 +#define SOCFPGA_LWFPGASLAVES_ADDRESS 0xff200000 +#define SOCFPGA_LWHPS2FPGAREGS_ADDRESS 0xff400000 +#define SOCFPGA_HPS2FPGAREGS_ADDRESS 0xff500000 +#define SOCFPGA_FPGA2HPSREGS_ADDRESS 0xff600000 +#define SOCFPGA_FPGAMGRREGS_ADDRESS 0xff706000 +#define SOCFPGA_ACPIDMAP_ADDRESS 0xff707000 +#define SOCFPGA_NANDDATA_ADDRESS 0xff900000 +#define SOCFPGA_QSPIDATA_ADDRESS 0xffa00000 +#define SOCFPGA_NANDREGS_ADDRESS 0xffb80000 +#define SOCFPGA_FPGAMGRDATA_ADDRESS 0xffb90000 +#define SOCFPGA_SPTIMER0_ADDRESS 0xffc08000 +#define SOCFPGA_SPTIMER1_ADDRESS 0xffc09000 +#define SOCFPGA_OSC1TIMER0_ADDRESS 0xffd00000 +#define SOCFPGA_OSC1TIMER1_ADDRESS 0xffd01000 +#define SOCFPGA_DMANONSECURE_ADDRESS 0xffe00000 +#define SOCFPGA_DMASECURE_ADDRESS 0xffe01000
#endif /* _SOCFPGA_BASE_ADDRS_H_ */

On Mon 2014-09-15 13:06:02, Marek Vasut wrote:
Sort the list of functional block addresses and fix indentation. No functional change.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de
Acked-by: Pavel Machek pavel@denx.de

On Mon 2014-09-15 13:05:57, Marek Vasut wrote:
Add a few new variables to make the cache handling less cryptic. Add a variable for DMA and DATA descriptor start and end, so the correctness of the code is easier to inspect.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de
Acked-by: Pavel Machek pavel@denx.de

From: Pavel Machek pavel@denx.de
This adds watchdog disable. It is neccessary for running Linux kernel.
Signed-off-by: Pavel Machek pavel@denx.de Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- arch/arm/cpu/armv7/socfpga/misc.c | 4 ++++ arch/arm/cpu/armv7/socfpga/reset_manager.c | 13 +++++++++++++ arch/arm/include/asm/arch-socfpga/reset_manager.h | 2 ++ 3 files changed, 19 insertions(+)
diff --git a/arch/arm/cpu/armv7/socfpga/misc.c b/arch/arm/cpu/armv7/socfpga/misc.c index ecae393..15cd8c2 100644 --- a/arch/arm/cpu/armv7/socfpga/misc.c +++ b/arch/arm/cpu/armv7/socfpga/misc.c @@ -8,6 +8,7 @@ #include <asm/io.h> #include <miiphy.h> #include <netdev.h> +#include <asm/arch/reset_manager.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -38,6 +39,9 @@ int overwrite_console(void)
int misc_init_r(void) { + /* This is needed, otherwise kernel is rebooted by watchdog. */ + watchdog_disable(); + return 0; }
diff --git a/arch/arm/cpu/armv7/socfpga/reset_manager.c b/arch/arm/cpu/armv7/socfpga/reset_manager.c index e320c01..07b8c4f 100644 --- a/arch/arm/cpu/armv7/socfpga/reset_manager.c +++ b/arch/arm/cpu/armv7/socfpga/reset_manager.c @@ -14,6 +14,19 @@ DECLARE_GLOBAL_DATA_PTR; static const struct socfpga_reset_manager *reset_manager_base = (void *)SOCFPGA_RSTMGR_ADDRESS;
+#define RSTMGR_PERMODRST_L4WD0_LSB 6 + +/* Disable the watchdog (toggle reset to watchdog) */ +void watchdog_disable(void) +{ + /* assert reset for watchdog */ + setbits_le32(&reset_manager_base->per_mod_reset, + (1<<RSTMGR_PERMODRST_L4WD0_LSB)); + /* deassert watchdog from reset (watchdog in not running state) */ + clrbits_le32(&reset_manager_base->per_mod_reset, + (1<<RSTMGR_PERMODRST_L4WD0_LSB)); +} + /* * Write the reset manager register to cause reset */ diff --git a/arch/arm/include/asm/arch-socfpga/reset_manager.h b/arch/arm/include/asm/arch-socfpga/reset_manager.h index 3e95476..e004343 100644 --- a/arch/arm/include/asm/arch-socfpga/reset_manager.h +++ b/arch/arm/include/asm/arch-socfpga/reset_manager.h @@ -10,6 +10,8 @@ void reset_cpu(ulong addr); void reset_deassert_peripherals_handoff(void);
+void watchdog_disable(void); + struct socfpga_reset_manager { u32 status; u32 ctrl;

On 09/15/2014 06:06 AM, Marek Vasut wrote:
From: Pavel Machek pavel@denx.de
This adds watchdog disable. It is neccessary for running Linux kernel.
Signed-off-by: Pavel Machek pavel@denx.de Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de
arch/arm/cpu/armv7/socfpga/misc.c | 4 ++++ arch/arm/cpu/armv7/socfpga/reset_manager.c | 13 +++++++++++++ arch/arm/include/asm/arch-socfpga/reset_manager.h | 2 ++ 3 files changed, 19 insertions(+)
diff --git a/arch/arm/cpu/armv7/socfpga/misc.c b/arch/arm/cpu/armv7/socfpga/misc.c index ecae393..15cd8c2 100644 --- a/arch/arm/cpu/armv7/socfpga/misc.c +++ b/arch/arm/cpu/armv7/socfpga/misc.c @@ -8,6 +8,7 @@ #include <asm/io.h> #include <miiphy.h> #include <netdev.h> +#include <asm/arch/reset_manager.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -38,6 +39,9 @@ int overwrite_console(void)
int misc_init_r(void) {
- /* This is needed, otherwise kernel is rebooted by watchdog. */
- watchdog_disable();
- return 0;
}
diff --git a/arch/arm/cpu/armv7/socfpga/reset_manager.c b/arch/arm/cpu/armv7/socfpga/reset_manager.c index e320c01..07b8c4f 100644 --- a/arch/arm/cpu/armv7/socfpga/reset_manager.c +++ b/arch/arm/cpu/armv7/socfpga/reset_manager.c @@ -14,6 +14,19 @@ DECLARE_GLOBAL_DATA_PTR; static const struct socfpga_reset_manager *reset_manager_base = (void *)SOCFPGA_RSTMGR_ADDRESS;
+#define RSTMGR_PERMODRST_L4WD0_LSB 6
Should this define go into -> arch-socfpga/reset_manager.h ?
Dinh
+/* Disable the watchdog (toggle reset to watchdog) */ +void watchdog_disable(void) +{
- /* assert reset for watchdog */
- setbits_le32(&reset_manager_base->per_mod_reset,
(1<<RSTMGR_PERMODRST_L4WD0_LSB));
- /* deassert watchdog from reset (watchdog in not running state) */
- clrbits_le32(&reset_manager_base->per_mod_reset,
(1<<RSTMGR_PERMODRST_L4WD0_LSB));
+}
/*
- Write the reset manager register to cause reset
*/ diff --git a/arch/arm/include/asm/arch-socfpga/reset_manager.h b/arch/arm/include/asm/arch-socfpga/reset_manager.h index 3e95476..e004343 100644 --- a/arch/arm/include/asm/arch-socfpga/reset_manager.h +++ b/arch/arm/include/asm/arch-socfpga/reset_manager.h @@ -10,6 +10,8 @@ void reset_cpu(ulong addr); void reset_deassert_peripherals_handoff(void);
+void watchdog_disable(void);
struct socfpga_reset_manager { u32 status; u32 ctrl;

On Monday, September 15, 2014 at 06:28:20 PM, Dinh Nguyen wrote:
On 09/15/2014 06:06 AM, Marek Vasut wrote:
From: Pavel Machek pavel@denx.de
This adds watchdog disable. It is neccessary for running Linux kernel.
Signed-off-by: Pavel Machek pavel@denx.de Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de
arch/arm/cpu/armv7/socfpga/misc.c | 4 ++++ arch/arm/cpu/armv7/socfpga/reset_manager.c | 13 +++++++++++++ arch/arm/include/asm/arch-socfpga/reset_manager.h | 2 ++ 3 files changed, 19 insertions(+)
diff --git a/arch/arm/cpu/armv7/socfpga/misc.c b/arch/arm/cpu/armv7/socfpga/misc.c index ecae393..15cd8c2 100644 --- a/arch/arm/cpu/armv7/socfpga/misc.c +++ b/arch/arm/cpu/armv7/socfpga/misc.c @@ -8,6 +8,7 @@
#include <asm/io.h> #include <miiphy.h> #include <netdev.h>
+#include <asm/arch/reset_manager.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -38,6 +39,9 @@ int overwrite_console(void)
int misc_init_r(void) {
/* This is needed, otherwise kernel is rebooted by watchdog. */
watchdog_disable();
return 0;
}
diff --git a/arch/arm/cpu/armv7/socfpga/reset_manager.c b/arch/arm/cpu/armv7/socfpga/reset_manager.c index e320c01..07b8c4f 100644 --- a/arch/arm/cpu/armv7/socfpga/reset_manager.c +++ b/arch/arm/cpu/armv7/socfpga/reset_manager.c @@ -14,6 +14,19 @@ DECLARE_GLOBAL_DATA_PTR;
static const struct socfpga_reset_manager *reset_manager_base =
(void *)SOCFPGA_RSTMGR_ADDRESS;
+#define RSTMGR_PERMODRST_L4WD0_LSB 6
Should this define go into -> arch-socfpga/reset_manager.h ?
Yeah, done. And fixed this for the EMAC reset patch as well. Thanks!

Clean up the system manager register definition and add the missing register definitions in place.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- arch/arm/cpu/armv7/socfpga/system_manager.c | 18 ++-- arch/arm/include/asm/arch-socfpga/system_manager.h | 102 +++++++++++++++------ 2 files changed, 86 insertions(+), 34 deletions(-)
diff --git a/arch/arm/cpu/armv7/socfpga/system_manager.c b/arch/arm/cpu/armv7/socfpga/system_manager.c index d96521b..07c72e4 100644 --- a/arch/arm/cpu/armv7/socfpga/system_manager.c +++ b/arch/arm/cpu/armv7/socfpga/system_manager.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Altera Corporation <www.altera.com> + * Copyright (C) 2013 Altera Corporation <www.altera.com> * * SPDX-License-Identifier: GPL-2.0+ */ @@ -7,21 +7,23 @@ #include <common.h> #include <asm/io.h> #include <asm/arch/system_manager.h> +#include <asm/arch/fpga_manager.h>
DECLARE_GLOBAL_DATA_PTR;
+static struct socfpga_system_manager *sysmgr_regs = + (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; + /* * Configure all the pin muxes */ void sysmgr_pinmux_init(void) { - unsigned long offset = CONFIG_SYSMGR_PINMUXGRP_OFFSET; - - const unsigned long *pval = sys_mgr_init_table; - unsigned long i; + uint32_t regs = (uint32_t)&sysmgr_regs->emacio[0]; + int i;
- for (i = 0; i < ARRAY_SIZE(sys_mgr_init_table); - i++, offset += sizeof(unsigned long)) { - writel(*pval++, (SOCFPGA_SYSMGR_ADDRESS + offset)); + for (i = 0; i < ARRAY_SIZE(sys_mgr_init_table); i++) { + writel(sys_mgr_init_table[i], regs); + regs += sizeof(regs); } } diff --git a/arch/arm/include/asm/arch-socfpga/system_manager.h b/arch/arm/include/asm/arch-socfpga/system_manager.h index 838d210..90d2720 100644 --- a/arch/arm/include/asm/arch-socfpga/system_manager.h +++ b/arch/arm/include/asm/arch-socfpga/system_manager.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Altera Corporation <www.altera.com> + * Copyright (C) 2013 Altera Corporation <www.altera.com> * * SPDX-License-Identifier: GPL-2.0+ */ @@ -16,72 +16,122 @@ extern unsigned long sys_mgr_init_table[CONFIG_HPS_PINMUX_NUM];
#endif
- -#define CONFIG_SYSMGR_PINMUXGRP_OFFSET (0x400) - -#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel) \ - ((((drvsel) << 0) & 0x7) | (((smplsel) << 3) & 0x38)) - struct socfpga_system_manager { - u32 siliconid1; + /* System Manager Module */ + u32 siliconid1; /* 0x00 */ u32 siliconid2; u32 _pad_0x8_0xf[2]; - u32 wddbg; + u32 wddbg; /* 0x10 */ u32 bootinfo; u32 hpsinfo; u32 parityinj; - u32 fpgaintfgrp_gbl; + /* FPGA Interface Group */ + u32 fpgaintfgrp_gbl; /* 0x20 */ u32 fpgaintfgrp_indiv; u32 fpgaintfgrp_module; u32 _pad_0x2c_0x2f; - u32 scanmgrgrp_ctrl; + /* Scan Manager Group */ + u32 scanmgrgrp_ctrl; /* 0x30 */ u32 _pad_0x34_0x3f[3]; - u32 frzctrl_vioctrl; + /* Freeze Control Group */ + u32 frzctrl_vioctrl; /* 0x40 */ u32 _pad_0x44_0x4f[3]; - u32 frzctrl_hioctrl; + u32 frzctrl_hioctrl; /* 0x50 */ u32 frzctrl_src; u32 frzctrl_hwctrl; u32 _pad_0x5c_0x5f; - u32 emacgrp_ctrl; + /* EMAC Group */ + u32 emacgrp_ctrl; /* 0x60 */ u32 emacgrp_l3master; u32 _pad_0x68_0x6f[2]; - u32 dmagrp_ctrl; + /* DMA Controller Group */ + u32 dmagrp_ctrl; /* 0x70 */ u32 dmagrp_persecurity; u32 _pad_0x78_0x7f[2]; - u32 iswgrp_handoff[8]; - u32 _pad_0xa0_0xbf[8]; - u32 romcodegrp_ctrl; + /* Preloader (initial software) Group */ + u32 iswgrp_handoff[8]; /* 0x80 */ + u32 _pad_0xa0_0xbf[8]; /* 0xa0 */ + /* Boot ROM Code Register Group */ + u32 romcodegrp_ctrl; /* 0xc0 */ u32 romcodegrp_cpu1startaddr; u32 romcodegrp_initswstate; u32 romcodegrp_initswlastld; - u32 romcodegrp_bootromswstate; + u32 romcodegrp_bootromswstate; /* 0xd0 */ u32 __pad_0xd4_0xdf[3]; - u32 romcodegrp_warmramgrp_enable; + /* Warm Boot from On-Chip RAM Group */ + u32 romcodegrp_warmramgrp_enable; /* 0xe0 */ u32 romcodegrp_warmramgrp_datastart; u32 romcodegrp_warmramgrp_length; u32 romcodegrp_warmramgrp_execution; - u32 romcodegrp_warmramgrp_crc; + u32 romcodegrp_warmramgrp_crc; /* 0xf0 */ u32 __pad_0xf4_0xff[3]; - u32 romhwgrp_ctrl; + /* Boot ROM Hardware Register Group */ + u32 romhwgrp_ctrl; /* 0x100 */ u32 _pad_0x104_0x107; + /* SDMMC Controller Group */ u32 sdmmcgrp_ctrl; u32 sdmmcgrp_l3master; - u32 nandgrp_bootstrap; + /* NAND Flash Controller Register Group */ + u32 nandgrp_bootstrap; /* 0x110 */ u32 nandgrp_l3master; + /* USB Controller Group */ u32 usbgrp_l3master; u32 _pad_0x11c_0x13f[9]; - u32 eccgrp_l2; + /* ECC Management Register Group */ + u32 eccgrp_l2; /* 0x140 */ u32 eccgrp_ocram; u32 eccgrp_usb0; u32 eccgrp_usb1; - u32 eccgrp_emac0; + u32 eccgrp_emac0; /* 0x150 */ u32 eccgrp_emac1; u32 eccgrp_dma; u32 eccgrp_can0; - u32 eccgrp_can1; + u32 eccgrp_can1; /* 0x160 */ u32 eccgrp_nand; u32 eccgrp_qspi; u32 eccgrp_sdmmc; + u32 _pad_0x170_0x3ff[164]; + /* Pin Mux Control Group */ + u32 emacio[20]; /* 0x400 */ + u32 flashio[12]; /* 0x450 */ + u32 generalio[28]; /* 0x480 */ + u32 _pad_0x4f0_0x4ff[4]; + u32 mixed1io[22]; /* 0x500 */ + u32 mixed2io[8]; /* 0x558 */ + u32 gplinmux[23]; /* 0x578 */ + u32 gplmux[71]; /* 0x5d4 */ + u32 nandusefpga; /* 0x6f0 */ + u32 _pad_0x6f4; + u32 rgmii1usefpga; /* 0x6f8 */ + u32 _pad_0x6fc_0x700[2]; + u32 i2c0usefpga; /* 0x704 */ + u32 sdmmcusefpga; /* 0x708 */ + u32 _pad_0x70c_0x710[2]; + u32 rgmii0usefpga; /* 0x714 */ + u32 _pad_0x718_0x720[3]; + u32 i2c3usefpga; /* 0x724 */ + u32 i2c2usefpga; /* 0x728 */ + u32 i2c1usefpga; /* 0x72c */ + u32 spim1usefpga; /* 0x730 */ + u32 _pad_0x734; + u32 spim0usefpga; /* 0x738 */ };
+#define SYSMGR_ROMCODEGRP_CTRL_WARMRSTCFGPINMUX (1 << 0) +#define SYSMGR_ROMCODEGRP_CTRL_WARMRSTCFGIO (1 << 1) +#define SYSMGR_ECC_OCRAM_EN (1 << 0) +#define SYSMGR_ECC_OCRAM_SERR (1 << 3) +#define SYSMGR_ECC_OCRAM_DERR (1 << 4) +#define SYSMGR_FPGAINTF_USEFPGA 0x1 +#define SYSMGR_FPGAINTF_SPIM0 (1 << 0) +#define SYSMGR_FPGAINTF_SPIM1 (1 << 1) +#define SYSMGR_FPGAINTF_EMAC0 (1 << 2) +#define SYSMGR_FPGAINTF_EMAC1 (1 << 3) +#define SYSMGR_FPGAINTF_NAND (1 << 4) +#define SYSMGR_FPGAINTF_SDMMC (1 << 5) + +/* FIXME: This is questionable macro. */ +#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel) \ + ((((drvsel) << 0) & 0x7) | (((smplsel) << 3) & 0x38)) + #endif /* _SYSTEM_MANAGER_H_ */

On Mon 2014-09-15 13:05:57, Marek Vasut wrote:
Add a few new variables to make the cache handling less cryptic. Add a variable for DMA and DATA descriptor start and end, so the correctness of the code is easier to inspect.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de
Acked-by: Pavel Machek pavel@denx.de

The bit definitions for clock manager are complete chaos. Implement some basic logical order into them.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- arch/arm/include/asm/arch-socfpga/clock_manager.h | 166 +++++++++++++--------- 1 file changed, 99 insertions(+), 67 deletions(-)
diff --git a/arch/arm/include/asm/arch-socfpga/clock_manager.h b/arch/arm/include/asm/arch-socfpga/clock_manager.h index babac0e..dea171e 100644 --- a/arch/arm/include/asm/arch-socfpga/clock_manager.h +++ b/arch/arm/include/asm/arch-socfpga/clock_manager.h @@ -103,96 +103,128 @@ struct socfpga_clock_manager { u32 _pad_0xe0_0x200[72]; };
-#define CLKMGR_MAINPLLGRP_EN_S2FUSER0CLK_MASK 0x00000200 +#define CLKMGR_CTRL_SAFEMODE_MASK 0x00000001 +#define CLKMGR_CTRL_SAFEMODE_SET(x) (((x) << 0) & 0x00000001) + +#define CLKMGR_BYPASS_MAINPLL_SET(x) (((x) << 0) & 0x00000001) +#define CLKMGR_BYPASS_PERPLLSRC_SET(x) (((x) << 4) & 0x00000010) +#define CLKMGR_BYPASS_PERPLL_SET(x) (((x) << 3) & 0x00000008) +#define CLKMGR_BYPASS_SDRPLLSRC_SET(x) (((x) << 2) & 0x00000004) +#define CLKMGR_BYPASS_SDRPLL_SET(x) (((x) << 1) & 0x00000002) + +#define CLKMGR_INTER_MAINPLLLOCKED_MASK 0x00000040 +#define CLKMGR_INTER_PERPLLLOCKED_MASK 0x00000080 +#define CLKMGR_INTER_SDRPLLLOCKED_MASK 0x00000100 + +/* Main PLL */ +#define CLKMGR_MAINPLLGRP_VCO_BGPWRDN_SET(x) (((x) << 0) & 0x00000001) +#define CLKMGR_MAINPLLGRP_VCO_DENOM_SET(x) (((x) << 16) & 0x003f0000) +#define CLKMGR_MAINPLLGRP_VCO_EN_SET(x) (((x) << 1) & 0x00000002) +#define CLKMGR_MAINPLLGRP_VCO_NUMER_SET(x) (((x) << 3) & 0x0000fff8) +#define CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK 0x01000000 +#define CLKMGR_MAINPLLGRP_VCO_PWRDN_SET(x) (((x) << 2) & 0x00000004) +#define CLKMGR_MAINPLLGRP_VCO_REGEXTSEL_MASK 0x80000000 +#define CLKMGR_MAINPLLGRP_VCO_RESET_VALUE 0x8001000d + +#define CLKMGR_MAINPLLGRP_MPUCLK_CNT_SET(x) (((x) << 0) & 0x000001ff) + +#define CLKMGR_MAINPLLGRP_MAINCLK_CNT_SET(x) (((x) << 0) & 0x000001ff) + +#define CLKMGR_MAINPLLGRP_DBGATCLK_CNT_SET(x) (((x) << 0) & 0x000001ff) + +#define CLKMGR_MAINPLLGRP_MAINQSPICLK_CNT_SET(x) (((x) << 0) & 0x000001ff) + +#define CLKMGR_MAINPLLGRP_MAINNANDSDMMCCLK_CNT_SET(x) (((x) << 0) & 0x000001ff) + +#define CLKMGR_MAINPLLGRP_CFGS2FUSER0CLK_CNT_SET(x) (((x) << 0) & 0x000001ff) + +#define CLKMGR_MAINPLLGRP_EN_DBGATCLK_MASK 0x00000010 +#define CLKMGR_MAINPLLGRP_EN_DBGCLK_MASK 0x00000020 #define CLKMGR_MAINPLLGRP_EN_DBGTIMERCLK_MASK 0x00000080 #define CLKMGR_MAINPLLGRP_EN_DBGTRACECLK_MASK 0x00000040 -#define CLKMGR_MAINPLLGRP_EN_DBGCLK_MASK 0x00000020 -#define CLKMGR_MAINPLLGRP_EN_DBGATCLK_MASK 0x00000010 #define CLKMGR_MAINPLLGRP_EN_L4MPCLK_MASK 0x00000004 -#define CLKMGR_MAINPLLGRP_VCO_RESET_VALUE 0x8001000d -#define CLKMGR_PERPLLGRP_VCO_RESET_VALUE 0x8001000d -#define CLKMGR_SDRPLLGRP_VCO_RESET_VALUE 0x8001000d +#define CLKMGR_MAINPLLGRP_EN_S2FUSER0CLK_MASK 0x00000200 + +#define CLKMGR_MAINPLLGRP_MAINDIV_L3MPCLK_SET(x) (((x) << 0) & 0x00000003) +#define CLKMGR_MAINPLLGRP_MAINDIV_L3SPCLK_SET(x) (((x) << 2) & 0x0000000c) #define CLKMGR_MAINPLLGRP_MAINDIV_L4MPCLK_SET(x) (((x) << 4) & 0x00000070) #define CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_SET(x) (((x) << 7) & 0x00000380) + +#define CLKMGR_MAINPLLGRP_DBGDIV_DBGATCLK_SET(x) (((x) << 0) & 0x00000003) +#define CLKMGR_MAINPLLGRP_DBGDIV_DBGCLK_SET(x) (((x) << 2) & 0x0000000c) + +#define CLKMGR_MAINPLLGRP_TRACEDIV_TRACECLK_SET(x) (((x) << 0) & 0x00000007) + #define CLKMGR_MAINPLLGRP_L4SRC_L4MP_SET(x) (((x) << 0) & 0x00000001) #define CLKMGR_MAINPLLGRP_L4SRC_L4SP_SET(x) (((x) << 1) & 0x00000002) -#define CLKMGR_PERPLLGRP_SRC_QSPI_SET(x) (((x) << 4) & 0x00000030) -#define CLKMGR_PERPLLGRP_SRC_NAND_SET(x) (((x) << 2) & 0x0000000c) -#define CLKMGR_PERPLLGRP_SRC_SDMMC_SET(x) (((x) << 0) & 0x00000003) -#define CLKMGR_MAINPLLGRP_VCO_DENOM_SET(x) (((x) << 16) & 0x003f0000) -#define CLKMGR_MAINPLLGRP_VCO_NUMER_SET(x) (((x) << 3) & 0x0000fff8) -#define CLKMGR_MAINPLLGRP_VCO_PWRDN_SET(x) (((x) << 2) & 0x00000004) -#define CLKMGR_MAINPLLGRP_VCO_EN_SET(x) (((x) << 1) & 0x00000002) -#define CLKMGR_MAINPLLGRP_VCO_BGPWRDN_SET(x) (((x) << 0) & 0x00000001) -#define CLKMGR_PERPLLGRP_VCO_PSRC_SET(x) (((x) << 22) & 0x00c00000) +#define CLKMGR_MAINPLLGRP_L4SRC_RESET_VALUE 0x00000000 + +/* Per PLL */ #define CLKMGR_PERPLLGRP_VCO_DENOM_SET(x) (((x) << 16) & 0x003f0000) #define CLKMGR_PERPLLGRP_VCO_NUMER_SET(x) (((x) << 3) & 0x0000fff8) -#define CLKMGR_SDRPLLGRP_VCO_OUTRESET_SET(x) (((x) << 25) & 0x7e000000) -#define CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_SET(x) (((x) << 24) & 0x01000000) -#define CLKMGR_SDRPLLGRP_VCO_SSRC_SET(x) (((x) << 22) & 0x00c00000) -#define CLKMGR_SDRPLLGRP_VCO_DENOM_SET(x) (((x) << 16) & 0x003f0000) -#define CLKMGR_SDRPLLGRP_VCO_NUMER_SET(x) (((x) << 3) & 0x0000fff8) -#define CLKMGR_MAINPLLGRP_MPUCLK_CNT_SET(x) (((x) << 0) & 0x000001ff) -#define CLKMGR_MAINPLLGRP_MAINCLK_CNT_SET(x) (((x) << 0) & 0x000001ff) -#define CLKMGR_MAINPLLGRP_DBGATCLK_CNT_SET(x) (((x) << 0) & 0x000001ff) -#define CLKMGR_MAINPLLGRP_CFGS2FUSER0CLK_CNT_SET(x) \ - (((x) << 0) & 0x000001ff) +#define CLKMGR_PERPLLGRP_VCO_OUTRESETALL_MASK 0x01000000 +#define CLKMGR_PERPLLGRP_VCO_PSRC_SET(x) (((x) << 22) & 0x00c00000) +#define CLKMGR_PERPLLGRP_VCO_REGEXTSEL_MASK 0x80000000 +#define CLKMGR_PERPLLGRP_VCO_RESET_VALUE 0x8001000d + #define CLKMGR_PERPLLGRP_EMAC0CLK_CNT_SET(x) (((x) << 0) & 0x000001ff) + #define CLKMGR_PERPLLGRP_EMAC1CLK_CNT_SET(x) (((x) << 0) & 0x000001ff) -#define CLKMGR_MAINPLLGRP_MAINQSPICLK_CNT_SET(x) (((x) << 0) & 0x000001ff) -#define CLKMGR_MAINPLLGRP_MAINNANDSDMMCCLK_CNT_SET(x) \ - (((x) << 0) & 0x000001ff) + +#define CLKMGR_PERPLLGRP_PERQSPICLK_CNT_SET(x) (((x) << 0) & 0x000001ff) + +#define CLKMGR_PERPLLGRP_PERNANDSDMMCCLK_CNT_SET(x) (((x) << 0) & 0x000001ff) + #define CLKMGR_PERPLLGRP_PERBASECLK_CNT_SET(x) (((x) << 0) & 0x000001ff) + #define CLKMGR_PERPLLGRP_S2FUSER1CLK_CNT_SET(x) (((x) << 0) & 0x000001ff) -#define CLKMGR_PERPLLGRP_PERNANDSDMMCCLK_CNT_SET(x) (((x) << 0) & 0x000001ff) -#define CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_SET(x) (((x) << 9) & 0x00000e00) -#define CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_SET(x) (((x) << 0) & 0x000001ff) -#define CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_SET(x) (((x) << 9) & 0x00000e00) -#define CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_SET(x) (((x) << 0) & 0x000001ff) -#define CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_SET(x) (((x) << 9) & 0x00000e00) -#define CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_SET(x) (((x) << 0) & 0x000001ff) -#define CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_SET(x) (((x) << 9) & 0x00000e00) -#define CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_SET(x) (((x) << 0) & 0x000001ff) -#define CLKMGR_MAINPLLGRP_DBGDIV_DBGCLK_SET(x) (((x) << 2) & 0x0000000c) -#define CLKMGR_MAINPLLGRP_DBGDIV_DBGATCLK_SET(x) (((x) << 0) & 0x00000003) -#define CLKMGR_MAINPLLGRP_TRACEDIV_TRACECLK_SET(x) (((x) << 0) & 0x00000007) -#define CLKMGR_MAINPLLGRP_MAINDIV_L3MPCLK_SET(x) (((x) << 0) & 0x00000003) -#define CLKMGR_MAINPLLGRP_MAINDIV_L3SPCLK_SET(x) (((x) << 2) & 0x0000000c) -#define CLKMGR_BYPASS_PERPLL_SET(x) (((x) << 3) & 0x00000008) -#define CLKMGR_BYPASS_SDRPLL_SET(x) (((x) << 1) & 0x00000002) -#define CLKMGR_BYPASS_MAINPLL_SET(x) (((x) << 0) & 0x00000001) -#define CLKMGR_PERPLLGRP_DIV_USBCLK_SET(x) (((x) << 0) & 0x00000007) -#define CLKMGR_PERPLLGRP_DIV_SPIMCLK_SET(x) (((x) << 3) & 0x00000038) + +#define CLKMGR_PERPLLGRP_EN_NANDCLK_MASK 0x00000400 +#define CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK 0x00000100 + #define CLKMGR_PERPLLGRP_DIV_CAN0CLK_SET(x) (((x) << 6) & 0x000001c0) #define CLKMGR_PERPLLGRP_DIV_CAN1CLK_SET(x) (((x) << 9) & 0x00000e00) -#define CLKMGR_INTER_SDRPLLLOCKED_MASK 0x00000100 -#define CLKMGR_INTER_PERPLLLOCKED_MASK 0x00000080 -#define CLKMGR_INTER_MAINPLLLOCKED_MASK 0x00000040 -#define CLKMGR_CTRL_SAFEMODE_MASK 0x00000001 -#define CLKMGR_CTRL_SAFEMODE_SET(x) (((x) << 0) & 0x00000001) -#define CLKMGR_SDRPLLGRP_VCO_OUTRESET_MASK 0x7e000000 -#define CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_SET(x) (((x) << 24) & 0x01000000) -#define CLKMGR_PERPLLGRP_PERQSPICLK_CNT_SET(x) (((x) << 0) & 0x000001ff) #define CLKMGR_PERPLLGRP_DIV_SPIMCLK_SET(x) (((x) << 3) & 0x00000038) +#define CLKMGR_PERPLLGRP_DIV_SPIMCLK_SET(x) (((x) << 3) & 0x00000038) +#define CLKMGR_PERPLLGRP_DIV_USBCLK_SET(x) (((x) << 0) & 0x00000007) + #define CLKMGR_PERPLLGRP_GPIODIV_GPIODBCLK_SET(x) (((x) << 0) & 0x00ffffff) -#define CLKMGR_BYPASS_PERPLLSRC_SET(x) (((x) << 4) & 0x00000010) -#define CLKMGR_BYPASS_SDRPLLSRC_SET(x) (((x) << 2) & 0x00000004) + +#define CLKMGR_PERPLLGRP_SRC_NAND_SET(x) (((x) << 2) & 0x0000000c) +#define CLKMGR_PERPLLGRP_SRC_QSPI_SET(x) (((x) << 4) & 0x00000030) #define CLKMGR_PERPLLGRP_SRC_RESET_VALUE 0x00000015 -#define CLKMGR_MAINPLLGRP_L4SRC_RESET_VALUE 0x00000000 -#define CLKMGR_MAINPLLGRP_VCO_REGEXTSEL_MASK 0x80000000 -#define CLKMGR_PERPLLGRP_VCO_REGEXTSEL_MASK 0x80000000 +#define CLKMGR_PERPLLGRP_SRC_SDMMC_SET(x) (((x) << 0) & 0x00000003) + +/* SDR PLL */ +#define CLKMGR_SDRPLLGRP_VCO_DENOM_SET(x) (((x) << 16) & 0x003f0000) +#define CLKMGR_SDRPLLGRP_VCO_NUMER_SET(x) (((x) << 3) & 0x0000fff8) +#define CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_SET(x) (((x) << 24) & 0x01000000) +#define CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_SET(x) (((x) << 24) & 0x01000000) +#define CLKMGR_SDRPLLGRP_VCO_OUTRESET_MASK 0x7e000000 +#define CLKMGR_SDRPLLGRP_VCO_OUTRESET_SET(x) (((x) << 25) & 0x7e000000) #define CLKMGR_SDRPLLGRP_VCO_REGEXTSEL_MASK 0x80000000 -#define CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_MASK 0x001ffe00 -#define CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_MASK 0x001ffe00 -#define CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_MASK 0x001ffe00 -#define CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_MASK 0x001ffe00 -#define CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK 0x01000000 -#define CLKMGR_PERPLLGRP_VCO_OUTRESETALL_MASK 0x01000000 -#define CLKMGR_PERPLLGRP_EN_NANDCLK_MASK 0x00000400 +#define CLKMGR_SDRPLLGRP_VCO_RESET_VALUE 0x8001000d +#define CLKMGR_SDRPLLGRP_VCO_SSRC_SET(x) (((x) << 22) & 0x00c00000) + #define CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_MASK 0x000001ff +#define CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_SET(x) (((x) << 0) & 0x000001ff) +#define CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_MASK 0x001ffe00 +#define CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_SET(x) (((x) << 9) & 0x00000e00) + #define CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_MASK 0x000001ff +#define CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_SET(x) (((x) << 0) & 0x000001ff) +#define CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_MASK 0x001ffe00 +#define CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_SET(x) (((x) << 9) & 0x00000e00) + #define CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_MASK 0x000001ff +#define CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_SET(x) (((x) << 0) & 0x000001ff) +#define CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_MASK 0x001ffe00 +#define CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_SET(x) (((x) << 9) & 0x00000e00) + #define CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_MASK 0x000001ff +#define CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_SET(x) (((x) << 0) & 0x000001ff) +#define CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_MASK 0x001ffe00 +#define CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_SET(x) (((x) << 9) & 0x00000e00)
#define MAIN_VCO_BASE \ (CLKMGR_MAINPLLGRP_VCO_DENOM_SET(CONFIG_HPS_MAINPLLGRP_VCO_DENOM) | \

Dear Marek Vasut,
In message 1410779188-6880-13-git-send-email-marex@denx.de you wrote:
The bit definitions for clock manager are complete chaos. Implement some basic logical order into them.
...
+#define CLKMGR_BYPASS_MAINPLL_SET(x) (((x) << 0) & 0x00000001) +#define CLKMGR_BYPASS_PERPLLSRC_SET(x) (((x) << 4) & 0x00000010) +#define CLKMGR_BYPASS_PERPLL_SET(x) (((x) << 3) & 0x00000008) +#define CLKMGR_BYPASS_SDRPLLSRC_SET(x) (((x) << 2) & 0x00000004) +#define CLKMGR_BYPASS_SDRPLL_SET(x) (((x) << 1) & 0x00000002)
What is the purpose of all these funny shift operation shere? Is it just to obfuscate the meaning of the code, or is the code eventually wrong?
As is above could be rewritten much simpler without the shifts:
#define CLKMGR_BYPASS_MAINPLL_SET(x) ((x) & 1) #define CLKMGR_BYPASS_PERPLLSRC_SET(x) ((x) & 1) #define CLKMGR_BYPASS_PERPLL_SET(x) ((x) & 1) #define CLKMGR_BYPASS_SDRPLLSRC_SET(x) ((x) & 1) #define CLKMGR_BYPASS_SDRPLL_SET(x) ((x) & 1)
Note also that the macros are misnamed - "<something>_SET" means an action, i. e. the macro is supposed to set some bits in the argument, but here you actually perform a test if something "is set".
Best regards,
Wolfgang Denk

Hi!
Dear Marek Vasut, In message 1410779188-6880-13-git-send-email-marex@denx.de you wrote:
The bit definitions for clock manager are complete chaos. Implement some basic logical order into them.
...
+#define CLKMGR_BYPASS_MAINPLL_SET(x) (((x) << 0) & 0x00000001) +#define CLKMGR_BYPASS_PERPLLSRC_SET(x) (((x) << 4) & 0x00000010) +#define CLKMGR_BYPASS_PERPLL_SET(x) (((x) << 3) & 0x00000008) +#define CLKMGR_BYPASS_SDRPLLSRC_SET(x) (((x) << 2) & 0x00000004) +#define CLKMGR_BYPASS_SDRPLL_SET(x) (((x) << 1) & 0x00000002)
What is the purpose of all these funny shift operation shere? Is it just to obfuscate the meaning of the code, or is the code eventually wrong?
As is above could be rewritten much simpler without the shifts:
#define CLKMGR_BYPASS_MAINPLL_SET(x) ((x) & 1) #define CLKMGR_BYPASS_PERPLLSRC_SET(x) ((x) & 1) #define CLKMGR_BYPASS_PERPLL_SET(x) ((x) & 1) #define CLKMGR_BYPASS_SDRPLLSRC_SET(x) ((x) & 1) #define CLKMGR_BYPASS_SDRPLL_SET(x) ((x) & 1)
Note also that the macros are misnamed - "<something>_SET" means an action, i. e. the macro is supposed to set some bits in the argument, but here you actually perform a test if something "is set".
Not the way macros are used; they really use them to set bits:
/* Put all plls in bypass */ cm_write_bypass( CLKMGR_BYPASS_PERPLLSRC_SET( CLKMGR_BYPASS_PERPLLSRC_SELECT_EOSC1) | CLKMGR_BYPASS_SDRPLLSRC_SET( CLKMGR_BYPASS_SDRPLLSRC_SELECT_EOSC1) | CLKMGR_BYPASS_PERPLL_SET(CLKMGR_BYPASS_ENABLE) | CLKMGR_BYPASS_SDRPLL_SET(CLKMGR_BYPASS_ENABLE) | CLKMGR_BYPASS_MAINPLL_SET(CLKMGR_BYPASS_ENABLE));
So replacing with ((x) & 1) would not work.
But yes, there are more cleanups that could be done there. Pavel

On Monday, September 15, 2014 at 11:21:22 PM, Pavel Machek wrote:
Hi!
Dear Marek Vasut,
In message 1410779188-6880-13-git-send-email-marex@denx.de you wrote:
The bit definitions for clock manager are complete chaos. Implement some basic logical order into them.
...
+#define CLKMGR_BYPASS_MAINPLL_SET(x) (((x) << 0) & 0x00000001) +#define CLKMGR_BYPASS_PERPLLSRC_SET(x) (((x) << 4) & 0x00000010) +#define CLKMGR_BYPASS_PERPLL_SET(x) (((x) << 3) & 0x00000008) +#define CLKMGR_BYPASS_SDRPLLSRC_SET(x) (((x) << 2) & 0x00000004) +#define CLKMGR_BYPASS_SDRPLL_SET(x) (((x) << 1) & 0x00000002)
What is the purpose of all these funny shift operation shere? Is it just to obfuscate the meaning of the code, or is the code eventually wrong?
As is above could be rewritten much simpler without the shifts:
#define CLKMGR_BYPASS_MAINPLL_SET(x) ((x) & 1) #define CLKMGR_BYPASS_PERPLLSRC_SET(x) ((x) & 1) #define CLKMGR_BYPASS_PERPLL_SET(x) ((x) & 1) #define CLKMGR_BYPASS_SDRPLLSRC_SET(x) ((x) & 1) #define CLKMGR_BYPASS_SDRPLL_SET(x) ((x) & 1)
Note also that the macros are misnamed - "<something>_SET" means an action, i. e. the macro is supposed to set some bits in the argument, but here you actually perform a test if something "is set".
Not the way macros are used; they really use them to set bits:
/* Put all plls in bypass */ cm_write_bypass( CLKMGR_BYPASS_PERPLLSRC_SET( CLKMGR_BYPASS_PERPLLSRC_SELECT_EOSC1) | CLKMGR_BYPASS_SDRPLLSRC_SET( CLKMGR_BYPASS_SDRPLLSRC_SELECT_EOSC1) | CLKMGR_BYPASS_PERPLL_SET(CLKMGR_BYPASS_ENABLE) CLKMGR_BYPASS_SDRPLL_SET(CLKMGR_BYPASS_ENABLE) | CLKMGR_BYPASS_MAINPLL_SET(CLKMGR_BYPASS_ENABLE));
So replacing with ((x) & 1) would not work.
But yes, there are more cleanups that could be done there.
You surely wanted to say "must be done where" ;-) I've yet to decide if I'll do it before this patchset or after ; I am more inclined doing it as a subsequent patch to allow Altera guys review the changes and match them with their existing code. And only then do the cleanup , probably automatically using some script.
What do you think, Wolfgang, Pavel, Dinh, others ... ?
Best regards, Marek Vasut

Dear Marek,
In message 201409152348.15411.marex@denx.de you wrote:
cm_write_bypass( CLKMGR_BYPASS_PERPLLSRC_SET( CLKMGR_BYPASS_PERPLLSRC_SELECT_EOSC1) | CLKMGR_BYPASS_SDRPLLSRC_SET( CLKMGR_BYPASS_SDRPLLSRC_SELECT_EOSC1) | CLKMGR_BYPASS_PERPLL_SET(CLKMGR_BYPASS_ENABLE) CLKMGR_BYPASS_SDRPLL_SET(CLKMGR_BYPASS_ENABLE) | CLKMGR_BYPASS_MAINPLL_SET(CLKMGR_BYPASS_ENABLE));
...
But yes, there are more cleanups that could be done there.
You surely wanted to say "must be done where" ;-) I've yet to decide if I'll do it before this patchset or after ; I am more inclined doing it as a subsequent patch to allow Altera guys review the changes and match them with their existing code. And only then do the cleanup , probably automatically using some script.
What do you think, Wolfgang, Pavel, Dinh, others ... ?
Well, frankly speaking, the code above (and many similar use cases) are an unreadable and unmaintainable mess. I understand that parts of this are computer-generated definitions, but in my opinion there are several serious disadvantages:
- The macro names are so long that the code becomes unreadable; the CodingStyle recommens in "Chapter 4: Naming":
C is a Spartan language, and so should your naming be. Unlike Modula-2 and Pascal programmers, C programmers do not use cute names like ThisVariableIsATemporaryCounter. A C programmer would call that variable "tmp", which is much easier to write, and not the least more difficult to understand. ... LOCAL variable names should be short, and to the point.
- There is virtually no visual difference between macro names that take arguments (like CLKMGR_BYPASS_PERPLLSRC_SET()) and macro names that are used as arguments (like CLKMGR_BYPASS_PERPLLSRC_SELECT_EOSC1) which makes parsing the code even more difficult.
We should especially keep in mind that things like CLKMGR_BYPASS_PERPLLSRC_SELECT_EOSC1 are deined in a single C source file only ("arch/arm/cpu/armv7/socfpga/clock_manager.c"), i. e. they have strictly local scope, so the long names make even less sense.
- The code not only difficult to read, but even more difficult to debug. Assume you are single stepping through this code, and you reach this statement:
cm_write_bypass( CLKMGR_BYPASS_PERPLLSRC_SET( CLKMGR_BYPASS_PERPLLSRC_SELECT_EOSC1) | CLKMGR_BYPASS_SDRPLLSRC_SET( CLKMGR_BYPASS_SDRPLLSRC_SELECT_EOSC1) | CLKMGR_BYPASS_PERPLL_SET(CLKMGR_BYPASS_ENABLE) CLKMGR_BYPASS_SDRPLL_SET(CLKMGR_BYPASS_ENABLE) | CLKMGR_BYPASS_MAINPLL_SET(CLKMGR_BYPASS_ENABLE));
In the debugger, you see
cm_write_bypass(0x0000000D);
How long does it take you to figure out if this is what we expect or not?
The macros are probably intended to offer unlimited flexibility, but they come at a cost. Do we really need this flexibility? How many of the macros are actually used und how many different ways.
Under normal conditions I would simple NAK such a patch and demand that the code is cleaned up before it gets accepted for mainline. Unfortunately, we already have this mess in mainline - somehow "arch/arm/cpu/armv7/socfpga/clock_manager.c" slipped through the reviews without anybody noticing this stuff.
So accepting this patch now does not make things dramatically worse, but I understand it would help to prepare the ground for other, urgently needed cleanup.
So as far as I am concerned I do not intend to block this with a plain NAK, but I would be really happy if this whole clock manager code would be put on the list of things that need rework, and we don't forget this about more recent tasks coming.
Best regards,
Wolfgang Denk

On Tuesday, September 16, 2014 at 10:18:32 AM, Wolfgang Denk wrote:
Dear Marek,
In message 201409152348.15411.marex@denx.de you wrote:
cm_write_bypass( CLKMGR_BYPASS_PERPLLSRC_SET( CLKMGR_BYPASS_PERPLLSRC_SELECT_EOSC1) | CLKMGR_BYPASS_SDRPLLSRC_SET( CLKMGR_BYPASS_SDRPLLSRC_SELECT_EOSC1) |
CLKMGR_BYPASS_PERPLL_SET(CLKMGR_BYPASS_ENABLE) CLKMGR_BYPASS_SDRPLL_SET(CLKMGR_BYPASS_ENABLE) | CLKMGR_BYPASS_MAINPLL_SET(CLKMGR_BYPASS_ENABLE));
...
But yes, there are more cleanups that could be done there.
You surely wanted to say "must be done where" ;-) I've yet to decide if I'll do it before this patchset or after ; I am more inclined doing it as a subsequent patch to allow Altera guys review the changes and match them with their existing code. And only then do the cleanup , probably automatically using some script.
What do you think, Wolfgang, Pavel, Dinh, others ... ?
Well, frankly speaking, the code above (and many similar use cases) are an unreadable and unmaintainable mess. I understand that parts of this are computer-generated definitions, but in my opinion there are several serious disadvantages:
Full ACK on this, the header files are full of dark chaos so far.
[...]
So as far as I am concerned I do not intend to block this with a plain NAK, but I would be really happy if this whole clock manager code would be put on the list of things that need rework, and we don't forget this about more recent tasks coming.
Will be in V2.
Best regards, Marek Vasut

The inlining is done by GCC whe needed, there is no need to do it explicitly. Furthermore, the inline keyword does not force-inline the code, but is only a hint for the compiler. Scrub this hint.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- arch/arm/cpu/armv7/socfpga/clock_manager.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/arm/cpu/armv7/socfpga/clock_manager.c b/arch/arm/cpu/armv7/socfpga/clock_manager.c index 158501a..d032bbd 100644 --- a/arch/arm/cpu/armv7/socfpga/clock_manager.c +++ b/arch/arm/cpu/armv7/socfpga/clock_manager.c @@ -30,7 +30,7 @@ static const struct socfpga_clock_manager *clock_manager_base = CLKMGR_MAINPLLGRP_VCO_EN_SET(1)| \ CLKMGR_MAINPLLGRP_VCO_BGPWRDN_SET(0))
-static inline void cm_wait_for_lock(uint32_t mask) +static void cm_wait_for_lock(uint32_t mask) { register uint32_t inter_val; do { @@ -39,7 +39,7 @@ static inline void cm_wait_for_lock(uint32_t mask) }
/* function to poll in the fsm busy bit */ -static inline void cm_wait_for_fsm(void) +static void cm_wait_for_fsm(void) { while (readl(&clock_manager_base->stat) & CLKMGR_STAT_BUSY) ; @@ -49,22 +49,22 @@ static inline void cm_wait_for_fsm(void) * function to write the bypass register which requires a poll of the * busy bit */ -static inline void cm_write_bypass(uint32_t val) +static void cm_write_bypass(uint32_t val) { writel(val, &clock_manager_base->bypass); cm_wait_for_fsm(); }
/* function to write the ctrl register which requires a poll of the busy bit */ -static inline void cm_write_ctrl(uint32_t val) +static void cm_write_ctrl(uint32_t val) { writel(val, &clock_manager_base->ctrl); cm_wait_for_fsm(); }
/* function to write a clock register that has phase information */ -static inline void cm_write_with_phase(uint32_t value, - uint32_t reg_address, uint32_t mask) +static void cm_write_with_phase(uint32_t value, + uint32_t reg_address, uint32_t mask) { /* poll until phase is zero */ while (readl(reg_address) & mask)

On 09/15/2014 06:06 AM, Marek Vasut wrote:
The inlining is done by GCC whe needed, there is no need to do it
s/whe/when.
Acked-by: Dinh Nguyen dinguyen@opensource.altera.com
thanks...
explicitly. Furthermore, the inline keyword does not force-inline the code, but is only a hint for the compiler. Scrub this hint.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de
arch/arm/cpu/armv7/socfpga/clock_manager.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/arm/cpu/armv7/socfpga/clock_manager.c b/arch/arm/cpu/armv7/socfpga/clock_manager.c index 158501a..d032bbd 100644 --- a/arch/arm/cpu/armv7/socfpga/clock_manager.c +++ b/arch/arm/cpu/armv7/socfpga/clock_manager.c @@ -30,7 +30,7 @@ static const struct socfpga_clock_manager *clock_manager_base = CLKMGR_MAINPLLGRP_VCO_EN_SET(1)| \ CLKMGR_MAINPLLGRP_VCO_BGPWRDN_SET(0))
-static inline void cm_wait_for_lock(uint32_t mask) +static void cm_wait_for_lock(uint32_t mask) { register uint32_t inter_val; do { @@ -39,7 +39,7 @@ static inline void cm_wait_for_lock(uint32_t mask) }
/* function to poll in the fsm busy bit */ -static inline void cm_wait_for_fsm(void) +static void cm_wait_for_fsm(void) { while (readl(&clock_manager_base->stat) & CLKMGR_STAT_BUSY) ; @@ -49,22 +49,22 @@ static inline void cm_wait_for_fsm(void)
- function to write the bypass register which requires a poll of the
- busy bit
*/ -static inline void cm_write_bypass(uint32_t val) +static void cm_write_bypass(uint32_t val) { writel(val, &clock_manager_base->bypass); cm_wait_for_fsm(); }
/* function to write the ctrl register which requires a poll of the busy bit */ -static inline void cm_write_ctrl(uint32_t val) +static void cm_write_ctrl(uint32_t val) { writel(val, &clock_manager_base->ctrl); cm_wait_for_fsm(); }
/* function to write a clock register that has phase information */ -static inline void cm_write_with_phase(uint32_t value,
- uint32_t reg_address, uint32_t mask)
+static void cm_write_with_phase(uint32_t value,
uint32_t reg_address, uint32_t mask)
{ /* poll until phase is zero */ while (readl(reg_address) & mask)

On Monday, September 15, 2014 at 09:25:09 PM, Dinh Nguyen wrote:
On 09/15/2014 06:06 AM, Marek Vasut wrote:
The inlining is done by GCC whe needed, there is no need to do it
s/whe/when.
Acked-by: Dinh Nguyen dinguyen@opensource.altera.com
thanks...
Fixed, thanks!
Best regards, Marek Vasut

Add some stub defines, which are used by the clock code, but are missing from the auto-generated header file for the SoCFPGA family.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- board/altera/socfpga/pll_config.h | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/board/altera/socfpga/pll_config.h b/board/altera/socfpga/pll_config.h index 9bd0442..f0f59a9 100644 --- a/board/altera/socfpga/pll_config.h +++ b/board/altera/socfpga/pll_config.h @@ -94,6 +94,9 @@
/* Info for driver */ #define CONFIG_HPS_CLK_OSC1_HZ (25000000) +#define CONFIG_HPS_CLK_OSC2_HZ 0 +#define CONFIG_HPS_CLK_F2S_SDR_REF_HZ 0 +#define CONFIG_HPS_CLK_F2S_PER_REF_HZ 0 #define CONFIG_HPS_CLK_MAINVCO_HZ (1600000000) #define CONFIG_HPS_CLK_PERVCO_HZ (1000000000) #ifdef CONFIG_SOCFPGA_ARRIA5

On 09/15/2014 06:06 AM, Marek Vasut wrote:
Add some stub defines, which are used by the clock code, but are missing from the auto-generated header file for the SoCFPGA family.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de
board/altera/socfpga/pll_config.h | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/board/altera/socfpga/pll_config.h b/board/altera/socfpga/pll_config.h index 9bd0442..f0f59a9 100644 --- a/board/altera/socfpga/pll_config.h +++ b/board/altera/socfpga/pll_config.h @@ -94,6 +94,9 @@
/* Info for driver */ #define CONFIG_HPS_CLK_OSC1_HZ (25000000) +#define CONFIG_HPS_CLK_OSC2_HZ 0 +#define CONFIG_HPS_CLK_F2S_SDR_REF_HZ 0 +#define CONFIG_HPS_CLK_F2S_PER_REF_HZ 0 #define CONFIG_HPS_CLK_MAINVCO_HZ (1600000000) #define CONFIG_HPS_CLK_PERVCO_HZ (1000000000) #ifdef CONFIG_SOCFPGA_ARRIA5
Acked-by: Dinh Nguyen dinguyen@opensource.altera.com
thanks...

On Mon 2014-09-15 13:06:07, Marek Vasut wrote:
Add some stub defines, which are used by the clock code, but are missing from the auto-generated header file for the SoCFPGA family.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de
Acked-by: Pavel Machek pavel@denx.de

From: Pavel Machek pavel@denx.de
Add the entire bulk of code to read out clock configuration from the SoCFPGA CPU registers. This is important for MMC, QSPI and UART drivers as otherwise they cannot determine the frequency of their upstream clock.
Signed-off-by: Pavel Machek pavel@denx.de Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- arch/arm/cpu/armv7/socfpga/clock_manager.c | 226 +++++++++++++++++++++- arch/arm/include/asm/arch-socfpga/clock_manager.h | 43 +++- include/configs/socfpga_cyclone5.h | 1 + 3 files changed, 267 insertions(+), 3 deletions(-)
diff --git a/arch/arm/cpu/armv7/socfpga/clock_manager.c b/arch/arm/cpu/armv7/socfpga/clock_manager.c index d032bbd..07cf74c 100644 --- a/arch/arm/cpu/armv7/socfpga/clock_manager.c +++ b/arch/arm/cpu/armv7/socfpga/clock_manager.c @@ -8,8 +8,10 @@ #include <asm/io.h> #include <asm/arch/clock_manager.h>
+DECLARE_GLOBAL_DATA_PTR; + static const struct socfpga_clock_manager *clock_manager_base = - (void *)SOCFPGA_CLKMGR_ADDRESS; + (struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS;
#define CLKMGR_BYPASS_ENABLE 1 #define CLKMGR_BYPASS_DISABLE 0 @@ -358,3 +360,225 @@ void cm_basic_init(const cm_config_t *cfg) writel(~0, &clock_manager_base->per_pll.en); writel(~0, &clock_manager_base->sdr_pll.en); } + +unsigned long cm_get_mpu_clk_hz(void) +{ + uint32_t reg, clock; + + /* get the main VCO clock */ + reg = readl(&clock_manager_base->main_pll.vco); + clock = CONFIG_HPS_CLK_OSC1_HZ / + (CLKMGR_MAINPLLGRP_VCO_DENOM_GET(reg) + 1); + clock *= (CLKMGR_MAINPLLGRP_VCO_NUMER_GET(reg) + 1); + + /* get the MPU clock */ + reg = readl(&clock_manager_base->altera.mpuclk); + clock /= (reg + 1); + reg = readl(&clock_manager_base->main_pll.mpuclk); + clock /= (reg + 1); + return clock; +} + +unsigned long cm_get_sdram_clk_hz(void) +{ + uint32_t reg, clock = 0; + + /* identify SDRAM PLL clock source */ + reg = readl(&clock_manager_base->sdr_pll.vco); + reg = CLKMGR_SDRPLLGRP_VCO_SSRC_GET(reg); + if (reg == CLKMGR_VCO_SSRC_EOSC1) + clock = CONFIG_HPS_CLK_OSC1_HZ; + else if (reg == CLKMGR_VCO_SSRC_EOSC2) + clock = CONFIG_HPS_CLK_OSC2_HZ; + else if (reg == CLKMGR_VCO_SSRC_F2S) + clock = CONFIG_HPS_CLK_F2S_SDR_REF_HZ; + + /* get the SDRAM VCO clock */ + reg = readl(&clock_manager_base->sdr_pll.vco); + clock /= (CLKMGR_SDRPLLGRP_VCO_DENOM_GET(reg) + 1); + clock *= (CLKMGR_SDRPLLGRP_VCO_NUMER_GET(reg) + 1); + + /* get the SDRAM (DDR_DQS) clock */ + reg = readl(&clock_manager_base->sdr_pll.ddrdqsclk); + reg = CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_GET(reg); + clock /= (reg + 1); + + return clock; +} + +unsigned int cm_get_l4_sp_clk_hz(void) +{ + uint32_t reg, clock = 0; + + /* identify the source of L4 SP clock */ + reg = readl(&clock_manager_base->main_pll.l4src); + reg = CLKMGR_MAINPLLGRP_L4SRC_L4SP_GET(reg); + + if (reg == CLKMGR_L4_SP_CLK_SRC_MAINPLL) { + /* get the main VCO clock */ + reg = readl(&clock_manager_base->main_pll.vco); + clock = CONFIG_HPS_CLK_OSC1_HZ / + (CLKMGR_MAINPLLGRP_VCO_DENOM_GET(reg) + 1); + clock *= (CLKMGR_MAINPLLGRP_VCO_NUMER_GET(reg) + 1); + + /* get the clock prior L4 SP divider (main clk) */ + reg = readl(&clock_manager_base->altera.mainclk); + clock /= (reg + 1); + reg = readl(&clock_manager_base->main_pll.mainclk); + clock /= (reg + 1); + } else if (reg == CLKMGR_L4_SP_CLK_SRC_PERPLL) { + /* identify PER PLL clock source */ + reg = readl(&clock_manager_base->per_pll.vco); + reg = CLKMGR_PERPLLGRP_VCO_SSRC_GET(reg); + if (reg == CLKMGR_VCO_SSRC_EOSC1) + clock = CONFIG_HPS_CLK_OSC1_HZ; + else if (reg == CLKMGR_VCO_SSRC_EOSC2) + clock = CONFIG_HPS_CLK_OSC2_HZ; + else if (reg == CLKMGR_VCO_SSRC_F2S) + clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ; + + /* get the PER VCO clock */ + reg = readl(&clock_manager_base->per_pll.vco); + clock /= (CLKMGR_PERPLLGRP_VCO_DENOM_GET(reg) + 1); + clock *= (CLKMGR_PERPLLGRP_VCO_NUMER_GET(reg) + 1); + + /* get the clock prior L4 SP divider (periph_base_clk) */ + reg = readl(&clock_manager_base->per_pll.perbaseclk); + clock /= (reg + 1); + } + + /* get the L4 SP clock which supplied to UART */ + reg = readl(&clock_manager_base->main_pll.maindiv); + reg = CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_GET(reg); + clock = clock / (reg + 1); + + return clock; +} + +unsigned int cm_get_mmc_controller_clk_hz(void) +{ + uint32_t reg, clock = 0; + + /* identify the source of MMC clock */ + reg = readl(&clock_manager_base->per_pll.src); + reg = CLKMGR_PERPLLGRP_SRC_SDMMC_GET(reg); + + if (reg == CLKMGR_SDMMC_CLK_SRC_F2S) { + clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ; + } else if (reg == CLKMGR_SDMMC_CLK_SRC_MAIN) { + /* get the main VCO clock */ + reg = readl(&clock_manager_base->main_pll.vco); + clock = CONFIG_HPS_CLK_OSC1_HZ / + (CLKMGR_MAINPLLGRP_VCO_DENOM_GET(reg) + 1); + clock *= (CLKMGR_MAINPLLGRP_VCO_NUMER_GET(reg) + 1); + + /* get the SDMMC clock */ + reg = readl(&clock_manager_base->main_pll.mainnandsdmmcclk); + clock /= (reg + 1); + } else if (reg == CLKMGR_SDMMC_CLK_SRC_PER) { + /* identify PER PLL clock source */ + reg = readl(&clock_manager_base->per_pll.vco); + reg = CLKMGR_PERPLLGRP_VCO_SSRC_GET(reg); + if (reg == CLKMGR_VCO_SSRC_EOSC1) + clock = CONFIG_HPS_CLK_OSC1_HZ; + else if (reg == CLKMGR_VCO_SSRC_EOSC2) + clock = CONFIG_HPS_CLK_OSC2_HZ; + else if (reg == CLKMGR_VCO_SSRC_F2S) + clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ; + + /* get the PER VCO clock */ + reg = readl(&clock_manager_base->per_pll.vco); + clock /= (CLKMGR_PERPLLGRP_VCO_DENOM_GET(reg) + 1); + clock *= (CLKMGR_PERPLLGRP_VCO_NUMER_GET(reg) + 1); + + /* get the SDMMC clock */ + reg = readl(&clock_manager_base->per_pll.pernandsdmmcclk); + clock /= (reg + 1); + } + + /* further divide by 4 as we have fixed divider at wrapper */ + clock /= 4; + return clock; +} + +unsigned int cm_get_qspi_controller_clk_hz(void) +{ + uint32_t reg, clock = 0; + + /* identify the source of QSPI clock */ + reg = readl(&clock_manager_base->per_pll.src); + reg = CLKMGR_PERPLLGRP_SRC_QSPI_GET(reg); + + if (reg == CLKMGR_QSPI_CLK_SRC_F2S) { + clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ; + } else if (reg == CLKMGR_QSPI_CLK_SRC_MAIN) { + /* get the main VCO clock */ + reg = readl(&clock_manager_base->main_pll.vco); + clock = CONFIG_HPS_CLK_OSC1_HZ / + (CLKMGR_MAINPLLGRP_VCO_DENOM_GET(reg) + 1); + clock *= (CLKMGR_MAINPLLGRP_VCO_NUMER_GET(reg) + 1); + + /* get the qspi clock */ + reg = readl(&clock_manager_base->main_pll.mainqspiclk); + clock /= (reg + 1); + } else if (reg == CLKMGR_QSPI_CLK_SRC_PER) { + /* identify PER PLL clock source */ + reg = readl(&clock_manager_base->per_pll.vco); + reg = CLKMGR_PERPLLGRP_VCO_SSRC_GET(reg); + if (reg == CLKMGR_VCO_SSRC_EOSC1) + clock = CONFIG_HPS_CLK_OSC1_HZ; + else if (reg == CLKMGR_VCO_SSRC_EOSC2) + clock = CONFIG_HPS_CLK_OSC2_HZ; + else if (reg == CLKMGR_VCO_SSRC_F2S) + clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ; + + /* get the PER VCO clock */ + reg = readl(&clock_manager_base->per_pll.vco); + clock /= (CLKMGR_PERPLLGRP_VCO_DENOM_GET(reg) + 1); + clock *= (CLKMGR_PERPLLGRP_VCO_NUMER_GET(reg) + 1); + + /* get the qspi clock */ + reg = readl(&clock_manager_base->per_pll.perqspiclk); + clock /= (reg + 1); + } + + return clock; +} + +static void cm_print_clock_quick_summary(void) +{ + printf("MPU %10ld kHz\n", cm_get_mpu_clk_hz() / 1000); + printf("DDR %10ld kHz\n", cm_get_sdram_clk_hz() / 1000); + printf("EOSC1 %8d kHz\n", CONFIG_HPS_CLK_OSC1_HZ / 1000); + printf("EOSC2 %8d kHz\n", CONFIG_HPS_CLK_OSC2_HZ / 1000); + printf("F2S_SDR_REF %8d kHz\n", CONFIG_HPS_CLK_F2S_SDR_REF_HZ / 1000); + printf("F2S_PER_REF %8d kHz\n", CONFIG_HPS_CLK_F2S_PER_REF_HZ / 1000); + printf("MMC %8d kHz\n", cm_get_mmc_controller_clk_hz() / 1000); + printf("QSPI %8d kHz\n", cm_get_qspi_controller_clk_hz() / 1000); + printf("UART %8d kHz\n", cm_get_l4_sp_clk_hz() / 1000); +} + +int set_cpu_clk_info(void) +{ + /* Calculate the clock frequencies required for drivers */ + cm_get_l4_sp_clk_hz(); + cm_get_mmc_controller_clk_hz(); + + gd->bd->bi_arm_freq = cm_get_mpu_clk_hz() / 1000000; + gd->bd->bi_dsp_freq = 0; + gd->bd->bi_ddr_freq = cm_get_sdram_clk_hz() / 1000000; + + return 0; +} + +int do_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + cm_print_clock_quick_summary(); + return 0; +} + +U_BOOT_CMD( + clocks, CONFIG_SYS_MAXARGS, 1, do_showclocks, + "display clocks", + "" +); diff --git a/arch/arm/include/asm/arch-socfpga/clock_manager.h b/arch/arm/include/asm/arch-socfpga/clock_manager.h index dea171e..d2a9b48 100644 --- a/arch/arm/include/asm/arch-socfpga/clock_manager.h +++ b/arch/arm/include/asm/arch-socfpga/clock_manager.h @@ -7,6 +7,15 @@ #ifndef _CLOCK_MANAGER_H_ #define _CLOCK_MANAGER_H_
+#ifndef __ASSEMBLER__ +/* Clock speed accessors */ +unsigned long cm_get_mpu_clk_hz(void); +unsigned long cm_get_sdram_clk_hz(void); +unsigned int cm_get_l4_sp_clk_hz(void); +unsigned int cm_get_mmc_controller_clk_hz(void); +unsigned int cm_get_qspi_controller_clk_hz(void); +#endif + typedef struct { /* main group */ uint32_t main_vco_base; @@ -89,6 +98,11 @@ struct socfpga_clock_manager_sdr_pll { u32 stat; };
+struct socfpga_clock_manager_altera { + u32 mpuclk; + u32 mainclk; +}; + struct socfpga_clock_manager { u32 ctrl; u32 bypass; @@ -100,7 +114,8 @@ struct socfpga_clock_manager { struct socfpga_clock_manager_main_pll main_pll; struct socfpga_clock_manager_per_pll per_pll; struct socfpga_clock_manager_sdr_pll sdr_pll; - u32 _pad_0xe0_0x200[72]; + struct socfpga_clock_manager_altera altera; + u32 _pad_0xe8_0x200[70]; };
#define CLKMGR_CTRL_SAFEMODE_MASK 0x00000001 @@ -118,8 +133,10 @@ struct socfpga_clock_manager {
/* Main PLL */ #define CLKMGR_MAINPLLGRP_VCO_BGPWRDN_SET(x) (((x) << 0) & 0x00000001) +#define CLKMGR_MAINPLLGRP_VCO_DENOM_GET(x) (((x) & 0x003f0000) >> 16) #define CLKMGR_MAINPLLGRP_VCO_DENOM_SET(x) (((x) << 16) & 0x003f0000) #define CLKMGR_MAINPLLGRP_VCO_EN_SET(x) (((x) << 1) & 0x00000002) +#define CLKMGR_MAINPLLGRP_VCO_NUMER_GET(x) (((x) & 0x0000fff8) >> 3) #define CLKMGR_MAINPLLGRP_VCO_NUMER_SET(x) (((x) << 3) & 0x0000fff8) #define CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK 0x01000000 #define CLKMGR_MAINPLLGRP_VCO_PWRDN_SET(x) (((x) << 2) & 0x00000004) @@ -148,7 +165,8 @@ struct socfpga_clock_manager { #define CLKMGR_MAINPLLGRP_MAINDIV_L3MPCLK_SET(x) (((x) << 0) & 0x00000003) #define CLKMGR_MAINPLLGRP_MAINDIV_L3SPCLK_SET(x) (((x) << 2) & 0x0000000c) #define CLKMGR_MAINPLLGRP_MAINDIV_L4MPCLK_SET(x) (((x) << 4) & 0x00000070) -#define CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_SET(x) (((x) << 7) & 0x00000380) +#define CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_GET(x) (((x) & 0x00000380) >> 7) +#define CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_SET(x) (((x) << 7) & 0x00000380)
#define CLKMGR_MAINPLLGRP_DBGDIV_DBGATCLK_SET(x) (((x) << 0) & 0x00000003) #define CLKMGR_MAINPLLGRP_DBGDIV_DBGCLK_SET(x) (((x) << 2) & 0x0000000c) @@ -156,16 +174,25 @@ struct socfpga_clock_manager { #define CLKMGR_MAINPLLGRP_TRACEDIV_TRACECLK_SET(x) (((x) << 0) & 0x00000007)
#define CLKMGR_MAINPLLGRP_L4SRC_L4MP_SET(x) (((x) << 0) & 0x00000001) +#define CLKMGR_MAINPLLGRP_L4SRC_L4SP_GET(x) (((x) & 0x00000002) >> 1) #define CLKMGR_MAINPLLGRP_L4SRC_L4SP_SET(x) (((x) << 1) & 0x00000002) #define CLKMGR_MAINPLLGRP_L4SRC_RESET_VALUE 0x00000000 +#define CLKMGR_L4_SP_CLK_SRC_MAINPLL 0x0 +#define CLKMGR_L4_SP_CLK_SRC_PERPLL 0x1
/* Per PLL */ +#define CLKMGR_PERPLLGRP_VCO_DENOM_GET(x) (((x) & 0x003f0000) >> 16) #define CLKMGR_PERPLLGRP_VCO_DENOM_SET(x) (((x) << 16) & 0x003f0000) +#define CLKMGR_PERPLLGRP_VCO_NUMER_GET(x) (((x) & 0x0000fff8) >> 3) #define CLKMGR_PERPLLGRP_VCO_NUMER_SET(x) (((x) << 3) & 0x0000fff8) #define CLKMGR_PERPLLGRP_VCO_OUTRESETALL_MASK 0x01000000 #define CLKMGR_PERPLLGRP_VCO_PSRC_SET(x) (((x) << 22) & 0x00c00000) #define CLKMGR_PERPLLGRP_VCO_REGEXTSEL_MASK 0x80000000 #define CLKMGR_PERPLLGRP_VCO_RESET_VALUE 0x8001000d +#define CLKMGR_PERPLLGRP_VCO_SSRC_GET(x) (((x) & 0x00c00000) >> 22) +#define CLKMGR_VCO_SSRC_EOSC1 0x0 +#define CLKMGR_VCO_SSRC_EOSC2 0x1 +#define CLKMGR_VCO_SSRC_F2S 0x2
#define CLKMGR_PERPLLGRP_EMAC0CLK_CNT_SET(x) (((x) << 0) & 0x000001ff)
@@ -191,12 +218,22 @@ struct socfpga_clock_manager { #define CLKMGR_PERPLLGRP_GPIODIV_GPIODBCLK_SET(x) (((x) << 0) & 0x00ffffff)
#define CLKMGR_PERPLLGRP_SRC_NAND_SET(x) (((x) << 2) & 0x0000000c) +#define CLKMGR_PERPLLGRP_SRC_QSPI_GET(x) (((x) & 0x00000030) >> 4) #define CLKMGR_PERPLLGRP_SRC_QSPI_SET(x) (((x) << 4) & 0x00000030) #define CLKMGR_PERPLLGRP_SRC_RESET_VALUE 0x00000015 +#define CLKMGR_PERPLLGRP_SRC_SDMMC_GET(x) (((x) & 0x00000003) >> 0) #define CLKMGR_PERPLLGRP_SRC_SDMMC_SET(x) (((x) << 0) & 0x00000003) +#define CLKMGR_SDMMC_CLK_SRC_F2S 0x0 +#define CLKMGR_SDMMC_CLK_SRC_MAIN 0x1 +#define CLKMGR_SDMMC_CLK_SRC_PER 0x2 +#define CLKMGR_QSPI_CLK_SRC_F2S 0x0 +#define CLKMGR_QSPI_CLK_SRC_MAIN 0x1 +#define CLKMGR_QSPI_CLK_SRC_PER 0x2
/* SDR PLL */ +#define CLKMGR_SDRPLLGRP_VCO_DENOM_GET(x) (((x) & 0x003f0000) >> 16) #define CLKMGR_SDRPLLGRP_VCO_DENOM_SET(x) (((x) << 16) & 0x003f0000) +#define CLKMGR_SDRPLLGRP_VCO_NUMER_GET(x) (((x) & 0x0000fff8) >> 3) #define CLKMGR_SDRPLLGRP_VCO_NUMER_SET(x) (((x) << 3) & 0x0000fff8) #define CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_SET(x) (((x) << 24) & 0x01000000) #define CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_SET(x) (((x) << 24) & 0x01000000) @@ -204,8 +241,10 @@ struct socfpga_clock_manager { #define CLKMGR_SDRPLLGRP_VCO_OUTRESET_SET(x) (((x) << 25) & 0x7e000000) #define CLKMGR_SDRPLLGRP_VCO_REGEXTSEL_MASK 0x80000000 #define CLKMGR_SDRPLLGRP_VCO_RESET_VALUE 0x8001000d +#define CLKMGR_SDRPLLGRP_VCO_SSRC_GET(x) (((x) & 0x00c00000) >> 22) #define CLKMGR_SDRPLLGRP_VCO_SSRC_SET(x) (((x) << 22) & 0x00c00000)
+#define CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_GET(x) (((x) & 0x000001ff) >> 0) #define CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_MASK 0x000001ff #define CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_SET(x) (((x) << 0) & 0x000001ff) #define CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_MASK 0x001ffe00 diff --git a/include/configs/socfpga_cyclone5.h b/include/configs/socfpga_cyclone5.h index 5d145cd..3b6cfb4 100644 --- a/include/configs/socfpga_cyclone5.h +++ b/include/configs/socfpga_cyclone5.h @@ -24,6 +24,7 @@ #define CONFIG_MISC_INIT_R #define CONFIG_SINGLE_BOOTLOADER #define CONFIG_SOCFPGA +#define CONFIG_CLOCKS
/* base address for .text section */ #ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET

On 09/15/2014 06:06 AM, Marek Vasut wrote:
From: Pavel Machek pavel@denx.de
Add the entire bulk of code to read out clock configuration from the SoCFPGA CPU registers. This is important for MMC, QSPI and UART drivers as otherwise they cannot determine the frequency of their upstream clock.
Signed-off-by: Pavel Machek pavel@denx.de Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de
arch/arm/cpu/armv7/socfpga/clock_manager.c | 226 +++++++++++++++++++++- arch/arm/include/asm/arch-socfpga/clock_manager.h | 43 +++- include/configs/socfpga_cyclone5.h | 1 + 3 files changed, 267 insertions(+), 3 deletions(-)
diff --git a/arch/arm/cpu/armv7/socfpga/clock_manager.c b/arch/arm/cpu/armv7/socfpga/clock_manager.c index d032bbd..07cf74c 100644 --- a/arch/arm/cpu/armv7/socfpga/clock_manager.c +++ b/arch/arm/cpu/armv7/socfpga/clock_manager.c @@ -8,8 +8,10 @@ #include <asm/io.h> #include <asm/arch/clock_manager.h>
+DECLARE_GLOBAL_DATA_PTR;
static const struct socfpga_clock_manager *clock_manager_base =
(void *)SOCFPGA_CLKMGR_ADDRESS;
- (struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS;
#define CLKMGR_BYPASS_ENABLE 1 #define CLKMGR_BYPASS_DISABLE 0 @@ -358,3 +360,225 @@ void cm_basic_init(const cm_config_t *cfg) writel(~0, &clock_manager_base->per_pll.en); writel(~0, &clock_manager_base->sdr_pll.en); }
+unsigned long cm_get_mpu_clk_hz(void) +{
- uint32_t reg, clock;
- /* get the main VCO clock */
- reg = readl(&clock_manager_base->main_pll.vco);
- clock = CONFIG_HPS_CLK_OSC1_HZ /
(CLKMGR_MAINPLLGRP_VCO_DENOM_GET(reg) + 1);
- clock *= (CLKMGR_MAINPLLGRP_VCO_NUMER_GET(reg) + 1);
- /* get the MPU clock */
- reg = readl(&clock_manager_base->altera.mpuclk);
- clock /= (reg + 1);
- reg = readl(&clock_manager_base->main_pll.mpuclk);
- clock /= (reg + 1);
- return clock;
+}
+unsigned long cm_get_sdram_clk_hz(void) +{
- uint32_t reg, clock = 0;
- /* identify SDRAM PLL clock source */
- reg = readl(&clock_manager_base->sdr_pll.vco);
- reg = CLKMGR_SDRPLLGRP_VCO_SSRC_GET(reg);
- if (reg == CLKMGR_VCO_SSRC_EOSC1)
clock = CONFIG_HPS_CLK_OSC1_HZ;
- else if (reg == CLKMGR_VCO_SSRC_EOSC2)
clock = CONFIG_HPS_CLK_OSC2_HZ;
- else if (reg == CLKMGR_VCO_SSRC_F2S)
clock = CONFIG_HPS_CLK_F2S_SDR_REF_HZ;
- /* get the SDRAM VCO clock */
- reg = readl(&clock_manager_base->sdr_pll.vco);
- clock /= (CLKMGR_SDRPLLGRP_VCO_DENOM_GET(reg) + 1);
- clock *= (CLKMGR_SDRPLLGRP_VCO_NUMER_GET(reg) + 1);
- /* get the SDRAM (DDR_DQS) clock */
- reg = readl(&clock_manager_base->sdr_pll.ddrdqsclk);
- reg = CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_GET(reg);
- clock /= (reg + 1);
- return clock;
+}
+unsigned int cm_get_l4_sp_clk_hz(void) +{
- uint32_t reg, clock = 0;
- /* identify the source of L4 SP clock */
- reg = readl(&clock_manager_base->main_pll.l4src);
- reg = CLKMGR_MAINPLLGRP_L4SRC_L4SP_GET(reg);
- if (reg == CLKMGR_L4_SP_CLK_SRC_MAINPLL) {
/* get the main VCO clock */
reg = readl(&clock_manager_base->main_pll.vco);
clock = CONFIG_HPS_CLK_OSC1_HZ /
(CLKMGR_MAINPLLGRP_VCO_DENOM_GET(reg) + 1);
clock *= (CLKMGR_MAINPLLGRP_VCO_NUMER_GET(reg) + 1);
/* get the clock prior L4 SP divider (main clk) */
reg = readl(&clock_manager_base->altera.mainclk);
clock /= (reg + 1);
reg = readl(&clock_manager_base->main_pll.mainclk);
clock /= (reg + 1);
- } else if (reg == CLKMGR_L4_SP_CLK_SRC_PERPLL) {
/* identify PER PLL clock source */
reg = readl(&clock_manager_base->per_pll.vco);
reg = CLKMGR_PERPLLGRP_VCO_SSRC_GET(reg);
if (reg == CLKMGR_VCO_SSRC_EOSC1)
clock = CONFIG_HPS_CLK_OSC1_HZ;
else if (reg == CLKMGR_VCO_SSRC_EOSC2)
clock = CONFIG_HPS_CLK_OSC2_HZ;
else if (reg == CLKMGR_VCO_SSRC_F2S)
clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ;
/* get the PER VCO clock */
reg = readl(&clock_manager_base->per_pll.vco);
clock /= (CLKMGR_PERPLLGRP_VCO_DENOM_GET(reg) + 1);
clock *= (CLKMGR_PERPLLGRP_VCO_NUMER_GET(reg) + 1);
/* get the clock prior L4 SP divider (periph_base_clk) */
reg = readl(&clock_manager_base->per_pll.perbaseclk);
clock /= (reg + 1);
- }
- /* get the L4 SP clock which supplied to UART */
- reg = readl(&clock_manager_base->main_pll.maindiv);
- reg = CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_GET(reg);
- clock = clock / (reg + 1);
This is not a +1. The l4 mp clock divider is structured like this:
0x0 = divide by 1 0x1 = divide by 2 0x2 = divide by 4 0x3 = divide by 8 0x4 = divide by 16
So it should be: clock = clock / (1 << reg);
Dinh

On Monday, September 15, 2014 at 10:09:34 PM, Dinh Nguyen wrote:
On 09/15/2014 06:06 AM, Marek Vasut wrote:
[...]
- /* get the L4 SP clock which supplied to UART */
- reg = readl(&clock_manager_base->main_pll.maindiv);
- reg = CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_GET(reg);
- clock = clock / (reg + 1);
This is not a +1. The l4 mp clock divider is structured like this:
0x0 = divide by 1 0x1 = divide by 2 0x2 = divide by 4 0x3 = divide by 8 0x4 = divide by 16
So it should be: clock = clock / (1 << reg);
Fixed, thanks! I also synched the clock code with your codebase for all but the SDRAM auto refresh part.
Best regards, Marek Vasut

Pull out functions to read frequency of Main clock VCO and PLL clock VCO as the code is duplicated multiple times.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- arch/arm/cpu/armv7/socfpga/clock_manager.c | 96 ++++++++++++------------------ 1 file changed, 38 insertions(+), 58 deletions(-)
diff --git a/arch/arm/cpu/armv7/socfpga/clock_manager.c b/arch/arm/cpu/armv7/socfpga/clock_manager.c index 07cf74c..1ab62e7 100644 --- a/arch/arm/cpu/armv7/socfpga/clock_manager.c +++ b/arch/arm/cpu/armv7/socfpga/clock_manager.c @@ -361,7 +361,7 @@ void cm_basic_init(const cm_config_t *cfg) writel(~0, &clock_manager_base->sdr_pll.en); }
-unsigned long cm_get_mpu_clk_hz(void) +static unsigned int cm_get_main_vco_clk_hz(void) { uint32_t reg, clock;
@@ -371,6 +371,37 @@ unsigned long cm_get_mpu_clk_hz(void) (CLKMGR_MAINPLLGRP_VCO_DENOM_GET(reg) + 1); clock *= (CLKMGR_MAINPLLGRP_VCO_NUMER_GET(reg) + 1);
+ return clock; +} + +static unsigned int cm_get_per_vco_clk_hz(void) +{ + uint32_t reg, clock = 0; + + /* identify PER PLL clock source */ + reg = readl(&clock_manager_base->per_pll.vco); + reg = CLKMGR_PERPLLGRP_VCO_SSRC_GET(reg); + if (reg == CLKMGR_VCO_SSRC_EOSC1) + clock = CONFIG_HPS_CLK_OSC1_HZ; + else if (reg == CLKMGR_VCO_SSRC_EOSC2) + clock = CONFIG_HPS_CLK_OSC2_HZ; + else if (reg == CLKMGR_VCO_SSRC_F2S) + clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ; + + /* get the PER VCO clock */ + reg = readl(&clock_manager_base->per_pll.vco); + clock /= (CLKMGR_PERPLLGRP_VCO_DENOM_GET(reg) + 1); + clock *= (CLKMGR_PERPLLGRP_VCO_NUMER_GET(reg) + 1); + + return clock; +} + +unsigned long cm_get_mpu_clk_hz(void) +{ + uint32_t reg, clock; + + clock = cm_get_main_vco_clk_hz(); + /* get the MPU clock */ reg = readl(&clock_manager_base->altera.mpuclk); clock /= (reg + 1); @@ -415,11 +446,7 @@ unsigned int cm_get_l4_sp_clk_hz(void) reg = CLKMGR_MAINPLLGRP_L4SRC_L4SP_GET(reg);
if (reg == CLKMGR_L4_SP_CLK_SRC_MAINPLL) { - /* get the main VCO clock */ - reg = readl(&clock_manager_base->main_pll.vco); - clock = CONFIG_HPS_CLK_OSC1_HZ / - (CLKMGR_MAINPLLGRP_VCO_DENOM_GET(reg) + 1); - clock *= (CLKMGR_MAINPLLGRP_VCO_NUMER_GET(reg) + 1); + clock = cm_get_main_vco_clk_hz();
/* get the clock prior L4 SP divider (main clk) */ reg = readl(&clock_manager_base->altera.mainclk); @@ -427,20 +454,7 @@ unsigned int cm_get_l4_sp_clk_hz(void) reg = readl(&clock_manager_base->main_pll.mainclk); clock /= (reg + 1); } else if (reg == CLKMGR_L4_SP_CLK_SRC_PERPLL) { - /* identify PER PLL clock source */ - reg = readl(&clock_manager_base->per_pll.vco); - reg = CLKMGR_PERPLLGRP_VCO_SSRC_GET(reg); - if (reg == CLKMGR_VCO_SSRC_EOSC1) - clock = CONFIG_HPS_CLK_OSC1_HZ; - else if (reg == CLKMGR_VCO_SSRC_EOSC2) - clock = CONFIG_HPS_CLK_OSC2_HZ; - else if (reg == CLKMGR_VCO_SSRC_F2S) - clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ; - - /* get the PER VCO clock */ - reg = readl(&clock_manager_base->per_pll.vco); - clock /= (CLKMGR_PERPLLGRP_VCO_DENOM_GET(reg) + 1); - clock *= (CLKMGR_PERPLLGRP_VCO_NUMER_GET(reg) + 1); + clock = cm_get_per_vco_clk_hz();
/* get the clock prior L4 SP divider (periph_base_clk) */ reg = readl(&clock_manager_base->per_pll.perbaseclk); @@ -466,30 +480,13 @@ unsigned int cm_get_mmc_controller_clk_hz(void) if (reg == CLKMGR_SDMMC_CLK_SRC_F2S) { clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ; } else if (reg == CLKMGR_SDMMC_CLK_SRC_MAIN) { - /* get the main VCO clock */ - reg = readl(&clock_manager_base->main_pll.vco); - clock = CONFIG_HPS_CLK_OSC1_HZ / - (CLKMGR_MAINPLLGRP_VCO_DENOM_GET(reg) + 1); - clock *= (CLKMGR_MAINPLLGRP_VCO_NUMER_GET(reg) + 1); + clock = cm_get_main_vco_clk_hz();
/* get the SDMMC clock */ reg = readl(&clock_manager_base->main_pll.mainnandsdmmcclk); clock /= (reg + 1); } else if (reg == CLKMGR_SDMMC_CLK_SRC_PER) { - /* identify PER PLL clock source */ - reg = readl(&clock_manager_base->per_pll.vco); - reg = CLKMGR_PERPLLGRP_VCO_SSRC_GET(reg); - if (reg == CLKMGR_VCO_SSRC_EOSC1) - clock = CONFIG_HPS_CLK_OSC1_HZ; - else if (reg == CLKMGR_VCO_SSRC_EOSC2) - clock = CONFIG_HPS_CLK_OSC2_HZ; - else if (reg == CLKMGR_VCO_SSRC_F2S) - clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ; - - /* get the PER VCO clock */ - reg = readl(&clock_manager_base->per_pll.vco); - clock /= (CLKMGR_PERPLLGRP_VCO_DENOM_GET(reg) + 1); - clock *= (CLKMGR_PERPLLGRP_VCO_NUMER_GET(reg) + 1); + clock = cm_get_per_vco_clk_hz();
/* get the SDMMC clock */ reg = readl(&clock_manager_base->per_pll.pernandsdmmcclk); @@ -512,30 +509,13 @@ unsigned int cm_get_qspi_controller_clk_hz(void) if (reg == CLKMGR_QSPI_CLK_SRC_F2S) { clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ; } else if (reg == CLKMGR_QSPI_CLK_SRC_MAIN) { - /* get the main VCO clock */ - reg = readl(&clock_manager_base->main_pll.vco); - clock = CONFIG_HPS_CLK_OSC1_HZ / - (CLKMGR_MAINPLLGRP_VCO_DENOM_GET(reg) + 1); - clock *= (CLKMGR_MAINPLLGRP_VCO_NUMER_GET(reg) + 1); + clock = cm_get_main_vco_clk_hz();
/* get the qspi clock */ reg = readl(&clock_manager_base->main_pll.mainqspiclk); clock /= (reg + 1); } else if (reg == CLKMGR_QSPI_CLK_SRC_PER) { - /* identify PER PLL clock source */ - reg = readl(&clock_manager_base->per_pll.vco); - reg = CLKMGR_PERPLLGRP_VCO_SSRC_GET(reg); - if (reg == CLKMGR_VCO_SSRC_EOSC1) - clock = CONFIG_HPS_CLK_OSC1_HZ; - else if (reg == CLKMGR_VCO_SSRC_EOSC2) - clock = CONFIG_HPS_CLK_OSC2_HZ; - else if (reg == CLKMGR_VCO_SSRC_F2S) - clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ; - - /* get the PER VCO clock */ - reg = readl(&clock_manager_base->per_pll.vco); - clock /= (CLKMGR_PERPLLGRP_VCO_DENOM_GET(reg) + 1); - clock *= (CLKMGR_PERPLLGRP_VCO_NUMER_GET(reg) + 1); + clock = cm_get_per_vco_clk_hz();
/* get the qspi clock */ reg = readl(&clock_manager_base->per_pll.perqspiclk);

On 09/15/2014 06:06 AM, Marek Vasut wrote:
Pull out functions to read frequency of Main clock VCO and PLL clock VCO as the code is duplicated multiple times.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de
arch/arm/cpu/armv7/socfpga/clock_manager.c | 96 ++++++++++++------------------ 1 file changed, 38 insertions(+), 58 deletions(-)
diff --git a/arch/arm/cpu/armv7/socfpga/clock_manager.c b/arch/arm/cpu/armv7/socfpga/clock_manager.c index 07cf74c..1ab62e7 100644 --- a/arch/arm/cpu/armv7/socfpga/clock_manager.c +++ b/arch/arm/cpu/armv7/socfpga/clock_manager.c @@ -361,7 +361,7 @@ void cm_basic_init(const cm_config_t *cfg) writel(~0, &clock_manager_base->sdr_pll.en); }
-unsigned long cm_get_mpu_clk_hz(void) +static unsigned int cm_get_main_vco_clk_hz(void) { uint32_t reg, clock;
@@ -371,6 +371,37 @@ unsigned long cm_get_mpu_clk_hz(void) (CLKMGR_MAINPLLGRP_VCO_DENOM_GET(reg) + 1); clock *= (CLKMGR_MAINPLLGRP_VCO_NUMER_GET(reg) + 1);
- return clock;
+}
+static unsigned int cm_get_per_vco_clk_hz(void) +{
- uint32_t reg, clock = 0;
- /* identify PER PLL clock source */
- reg = readl(&clock_manager_base->per_pll.vco);
- reg = CLKMGR_PERPLLGRP_VCO_SSRC_GET(reg);
- if (reg == CLKMGR_VCO_SSRC_EOSC1)
clock = CONFIG_HPS_CLK_OSC1_HZ;
- else if (reg == CLKMGR_VCO_SSRC_EOSC2)
clock = CONFIG_HPS_CLK_OSC2_HZ;
- else if (reg == CLKMGR_VCO_SSRC_F2S)
clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ;
- /* get the PER VCO clock */
- reg = readl(&clock_manager_base->per_pll.vco);
- clock /= (CLKMGR_PERPLLGRP_VCO_DENOM_GET(reg) + 1);
- clock *= (CLKMGR_PERPLLGRP_VCO_NUMER_GET(reg) + 1);
- return clock;
+}
+unsigned long cm_get_mpu_clk_hz(void) +{
- uint32_t reg, clock;
- clock = cm_get_main_vco_clk_hz();
- /* get the MPU clock */ reg = readl(&clock_manager_base->altera.mpuclk); clock /= (reg + 1);
@@ -415,11 +446,7 @@ unsigned int cm_get_l4_sp_clk_hz(void) reg = CLKMGR_MAINPLLGRP_L4SRC_L4SP_GET(reg);
if (reg == CLKMGR_L4_SP_CLK_SRC_MAINPLL) {
/* get the main VCO clock */
reg = readl(&clock_manager_base->main_pll.vco);
clock = CONFIG_HPS_CLK_OSC1_HZ /
(CLKMGR_MAINPLLGRP_VCO_DENOM_GET(reg) + 1);
clock *= (CLKMGR_MAINPLLGRP_VCO_NUMER_GET(reg) + 1);
clock = cm_get_main_vco_clk_hz();
/* get the clock prior L4 SP divider (main clk) */ reg = readl(&clock_manager_base->altera.mainclk);
@@ -427,20 +454,7 @@ unsigned int cm_get_l4_sp_clk_hz(void) reg = readl(&clock_manager_base->main_pll.mainclk); clock /= (reg + 1); } else if (reg == CLKMGR_L4_SP_CLK_SRC_PERPLL) {
/* identify PER PLL clock source */
reg = readl(&clock_manager_base->per_pll.vco);
reg = CLKMGR_PERPLLGRP_VCO_SSRC_GET(reg);
if (reg == CLKMGR_VCO_SSRC_EOSC1)
clock = CONFIG_HPS_CLK_OSC1_HZ;
else if (reg == CLKMGR_VCO_SSRC_EOSC2)
clock = CONFIG_HPS_CLK_OSC2_HZ;
else if (reg == CLKMGR_VCO_SSRC_F2S)
clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ;
/* get the PER VCO clock */
reg = readl(&clock_manager_base->per_pll.vco);
clock /= (CLKMGR_PERPLLGRP_VCO_DENOM_GET(reg) + 1);
clock *= (CLKMGR_PERPLLGRP_VCO_NUMER_GET(reg) + 1);
clock = cm_get_per_vco_clk_hz();
/* get the clock prior L4 SP divider (periph_base_clk) */ reg = readl(&clock_manager_base->per_pll.perbaseclk);
@@ -466,30 +480,13 @@ unsigned int cm_get_mmc_controller_clk_hz(void) if (reg == CLKMGR_SDMMC_CLK_SRC_F2S) { clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ; } else if (reg == CLKMGR_SDMMC_CLK_SRC_MAIN) {
/* get the main VCO clock */
reg = readl(&clock_manager_base->main_pll.vco);
clock = CONFIG_HPS_CLK_OSC1_HZ /
(CLKMGR_MAINPLLGRP_VCO_DENOM_GET(reg) + 1);
clock *= (CLKMGR_MAINPLLGRP_VCO_NUMER_GET(reg) + 1);
clock = cm_get_main_vco_clk_hz();
/* get the SDMMC clock */ reg = readl(&clock_manager_base->main_pll.mainnandsdmmcclk); clock /= (reg + 1); } else if (reg == CLKMGR_SDMMC_CLK_SRC_PER) {
/* identify PER PLL clock source */
reg = readl(&clock_manager_base->per_pll.vco);
reg = CLKMGR_PERPLLGRP_VCO_SSRC_GET(reg);
if (reg == CLKMGR_VCO_SSRC_EOSC1)
clock = CONFIG_HPS_CLK_OSC1_HZ;
else if (reg == CLKMGR_VCO_SSRC_EOSC2)
clock = CONFIG_HPS_CLK_OSC2_HZ;
else if (reg == CLKMGR_VCO_SSRC_F2S)
clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ;
/* get the PER VCO clock */
reg = readl(&clock_manager_base->per_pll.vco);
clock /= (CLKMGR_PERPLLGRP_VCO_DENOM_GET(reg) + 1);
clock *= (CLKMGR_PERPLLGRP_VCO_NUMER_GET(reg) + 1);
clock = cm_get_per_vco_clk_hz();
/* get the SDMMC clock */ reg = readl(&clock_manager_base->per_pll.pernandsdmmcclk);
@@ -512,30 +509,13 @@ unsigned int cm_get_qspi_controller_clk_hz(void) if (reg == CLKMGR_QSPI_CLK_SRC_F2S) { clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ; } else if (reg == CLKMGR_QSPI_CLK_SRC_MAIN) {
/* get the main VCO clock */
reg = readl(&clock_manager_base->main_pll.vco);
clock = CONFIG_HPS_CLK_OSC1_HZ /
(CLKMGR_MAINPLLGRP_VCO_DENOM_GET(reg) + 1);
clock *= (CLKMGR_MAINPLLGRP_VCO_NUMER_GET(reg) + 1);
clock = cm_get_main_vco_clk_hz();
/* get the qspi clock */ reg = readl(&clock_manager_base->main_pll.mainqspiclk); clock /= (reg + 1); } else if (reg == CLKMGR_QSPI_CLK_SRC_PER) {
/* identify PER PLL clock source */
reg = readl(&clock_manager_base->per_pll.vco);
reg = CLKMGR_PERPLLGRP_VCO_SSRC_GET(reg);
if (reg == CLKMGR_VCO_SSRC_EOSC1)
clock = CONFIG_HPS_CLK_OSC1_HZ;
else if (reg == CLKMGR_VCO_SSRC_EOSC2)
clock = CONFIG_HPS_CLK_OSC2_HZ;
else if (reg == CLKMGR_VCO_SSRC_F2S)
clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ;
/* get the PER VCO clock */
reg = readl(&clock_manager_base->per_pll.vco);
clock /= (CLKMGR_PERPLLGRP_VCO_DENOM_GET(reg) + 1);
clock *= (CLKMGR_PERPLLGRP_VCO_NUMER_GET(reg) + 1);
clock = cm_get_per_vco_clk_hz();
/* get the qspi clock */ reg = readl(&clock_manager_base->per_pll.perqspiclk);
Acked-by: Dinh Nguyen dinguyen@opensource.altera.com
Thanks...

On Mon 2014-09-15 13:06:09, Marek Vasut wrote:
Pull out functions to read frequency of Main clock VCO and PLL clock VCO as the code is duplicated multiple times.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de
Acked-by : Pavel Machek pavel@denx.de

From: Pavel Machek pavel@denx.de
Make the SoCFPGA MMC stub pick clock via the clock manager frequency accessors instead of hard-coding the frequency.
Also fix calloc() misuse.
Signed-off-by: Pavel Machek pavel@denx.de Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- drivers/mmc/socfpga_dw_mmc.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c index 1f96382..eb69aed 100644 --- a/drivers/mmc/socfpga_dw_mmc.c +++ b/drivers/mmc/socfpga_dw_mmc.c @@ -7,6 +7,7 @@ #include <common.h> #include <malloc.h> #include <dwmmc.h> +#include <errno.h> #include <asm/arch/dwmmc.h> #include <asm/arch/clock_manager.h> #include <asm/arch/system_manager.h> @@ -44,12 +45,18 @@ static void socfpga_dwmci_clksel(struct dwmci_host *host) int socfpga_dwmmc_init(u32 regbase, int bus_width, int index) { struct dwmci_host *host; + unsigned long clk = cm_get_mmc_controller_clk_hz(); + + if (clk == 0) { + printf("%s: MMC clock is zero!", __func__); + return -EINVAL; + }
/* calloc for zero init */ - host = calloc(sizeof(struct dwmci_host), 1); + host = calloc(1, sizeof(struct dwmci_host)); if (!host) { - printf("dwmci_host calloc fail!\n"); - return -1; + printf("%s: calloc() failed!\n", __func__); + return -ENOMEM; }
host->name = "SOCFPGA DWMMC"; @@ -58,7 +65,7 @@ int socfpga_dwmmc_init(u32 regbase, int bus_width, int index) host->clksel = socfpga_dwmci_clksel; host->dev_index = index; /* fixed clock divide by 4 which due to the SDMMC wrapper */ - host->bus_hz = CONFIG_SOCFPGA_DWMMC_BUS_HZ; + host->bus_hz = clk; host->fifoth_val = MSIZE(0x2) | RX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2 - 1) | TX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2);

On 09/15/2014 06:06 AM, Marek Vasut wrote:
From: Pavel Machek pavel@denx.de
Make the SoCFPGA MMC stub pick clock via the clock manager frequency accessors instead of hard-coding the frequency.
Also fix calloc() misuse.
Signed-off-by: Pavel Machek pavel@denx.de Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de
drivers/mmc/socfpga_dw_mmc.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c index 1f96382..eb69aed 100644 --- a/drivers/mmc/socfpga_dw_mmc.c +++ b/drivers/mmc/socfpga_dw_mmc.c @@ -7,6 +7,7 @@ #include <common.h> #include <malloc.h> #include <dwmmc.h> +#include <errno.h> #include <asm/arch/dwmmc.h> #include <asm/arch/clock_manager.h> #include <asm/arch/system_manager.h> @@ -44,12 +45,18 @@ static void socfpga_dwmci_clksel(struct dwmci_host *host) int socfpga_dwmmc_init(u32 regbase, int bus_width, int index) { struct dwmci_host *host;
unsigned long clk = cm_get_mmc_controller_clk_hz();
if (clk == 0) {
printf("%s: MMC clock is zero!", __func__);
return -EINVAL;
}
/* calloc for zero init */
- host = calloc(sizeof(struct dwmci_host), 1);
- host = calloc(1, sizeof(struct dwmci_host)); if (!host) {
printf("dwmci_host calloc fail!\n");
return -1;
printf("%s: calloc() failed!\n", __func__);
return -ENOMEM;
}
host->name = "SOCFPGA DWMMC";
@@ -58,7 +65,7 @@ int socfpga_dwmmc_init(u32 regbase, int bus_width, int index) host->clksel = socfpga_dwmci_clksel; host->dev_index = index; /* fixed clock divide by 4 which due to the SDMMC wrapper */
- host->bus_hz = CONFIG_SOCFPGA_DWMMC_BUS_HZ;
- host->bus_hz = clk; host->fifoth_val = MSIZE(0x2) | RX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2 - 1) | TX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2);
Acked-by: Dinh Nguyen dinguyen@opensource.altera.com
Thanks..

The timer reload value is a property of the timer hardware and there is no reason for this to be configurable. Place this into the timer driver just like on the other hardware.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- arch/arm/cpu/armv7/socfpga/timer.c | 2 ++ include/configs/socfpga_cyclone5.h | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/cpu/armv7/socfpga/timer.c b/arch/arm/cpu/armv7/socfpga/timer.c index 58fc789..253cde3 100644 --- a/arch/arm/cpu/armv7/socfpga/timer.c +++ b/arch/arm/cpu/armv7/socfpga/timer.c @@ -8,6 +8,8 @@ #include <asm/io.h> #include <asm/arch/timer.h>
+#define TIMER_LOAD_VAL 0xFFFFFFFF + static const struct socfpga_timer *timer_base = (void *)CONFIG_SYS_TIMERBASE;
/* diff --git a/include/configs/socfpga_cyclone5.h b/include/configs/socfpga_cyclone5.h index 3b6cfb4..f50081b 100644 --- a/include/configs/socfpga_cyclone5.h +++ b/include/configs/socfpga_cyclone5.h @@ -195,8 +195,6 @@ /* This timer use eosc1 where the clock frequency is fixed * throughout any condition */ #define CONFIG_SYS_TIMERBASE SOCFPGA_OSC1TIMER0_ADDRESS -/* reload value when timer count to zero */ -#define TIMER_LOAD_VAL 0xFFFFFFFF /* Timer info */ #ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET #define CONFIG_SYS_TIMER_RATE 2400000

On Mon 2014-09-15 13:06:11, Marek Vasut wrote:
The timer reload value is a property of the timer hardware and there is no reason for this to be configurable. Place this into the timer driver just like on the other hardware.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de
Acked-by: Pavel Machek pavel@denx.de

On 09/15/2014 06:06 AM, Marek Vasut wrote:
The timer reload value is a property of the timer hardware and there is no reason for this to be configurable. Place this into the timer driver just like on the other hardware.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de
arch/arm/cpu/armv7/socfpga/timer.c | 2 ++ include/configs/socfpga_cyclone5.h | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/cpu/armv7/socfpga/timer.c b/arch/arm/cpu/armv7/socfpga/timer.c index 58fc789..253cde3 100644 --- a/arch/arm/cpu/armv7/socfpga/timer.c +++ b/arch/arm/cpu/armv7/socfpga/timer.c @@ -8,6 +8,8 @@ #include <asm/io.h> #include <asm/arch/timer.h>
+#define TIMER_LOAD_VAL 0xFFFFFFFF
static const struct socfpga_timer *timer_base = (void *)CONFIG_SYS_TIMERBASE;
/* diff --git a/include/configs/socfpga_cyclone5.h b/include/configs/socfpga_cyclone5.h index 3b6cfb4..f50081b 100644 --- a/include/configs/socfpga_cyclone5.h +++ b/include/configs/socfpga_cyclone5.h @@ -195,8 +195,6 @@ /* This timer use eosc1 where the clock frequency is fixed
- throughout any condition */
#define CONFIG_SYS_TIMERBASE SOCFPGA_OSC1TIMER0_ADDRESS -/* reload value when timer count to zero */ -#define TIMER_LOAD_VAL 0xFFFFFFFF /* Timer info */ #ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET #define CONFIG_SYS_TIMER_RATE 2400000
Acked-by: Dinh Nguyen dinguyen@opensource.altera.com
Thanks...

Add functions to reset the EMAC ethernet blocks. We cannot handle two EMAC ethernet blocks yet, therefore the ifdefs. Once there is hardware using both EMAC blocks, this ifdef will have to go.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- arch/arm/cpu/armv7/socfpga/reset_manager.c | 21 +++++++++++++++++++++ arch/arm/include/asm/arch-socfpga/reset_manager.h | 2 ++ 2 files changed, 23 insertions(+)
diff --git a/arch/arm/cpu/armv7/socfpga/reset_manager.c b/arch/arm/cpu/armv7/socfpga/reset_manager.c index 07b8c4f..77579b7 100644 --- a/arch/arm/cpu/armv7/socfpga/reset_manager.c +++ b/arch/arm/cpu/armv7/socfpga/reset_manager.c @@ -14,6 +14,8 @@ DECLARE_GLOBAL_DATA_PTR; static const struct socfpga_reset_manager *reset_manager_base = (void *)SOCFPGA_RSTMGR_ADDRESS;
+#define RSTMGR_PERMODRST_EMAC0_LSB 0 +#define RSTMGR_PERMODRST_EMAC1_LSB 1 #define RSTMGR_PERMODRST_L4WD0_LSB 6
/* Disable the watchdog (toggle reset to watchdog) */ @@ -50,3 +52,22 @@ void reset_deassert_peripherals_handoff(void) { writel(0, &reset_manager_base->per_mod_reset); } + +/* Change the reset state for EMAC 0 and EMAC 1 */ +void socfpga_emac_reset(int enable) +{ + const void *reset = &reset_manager_base->per_mod_reset; + + if (enable) { + setbits_le32(reset, 1 << RSTMGR_PERMODRST_EMAC0_LSB); + setbits_le32(reset, 1 << RSTMGR_PERMODRST_EMAC1_LSB); + } else { +#if (CONFIG_EMAC_BASE == SOCFPGA_EMAC0_ADDRESS) + clrbits_le32(reset, 1 << RSTMGR_PERMODRST_EMAC0_LSB); +#elif (CONFIG_EMAC_BASE == SOCFPGA_EMAC1_ADDRESS) + clrbits_le32(reset, 1 << RSTMGR_PERMODRST_EMAC1_LSB); +#else +#error "Incorrect CONFIG_EMAC_BASE value!" +#endif + } +} diff --git a/arch/arm/include/asm/arch-socfpga/reset_manager.h b/arch/arm/include/asm/arch-socfpga/reset_manager.h index e004343..9d22576 100644 --- a/arch/arm/include/asm/arch-socfpga/reset_manager.h +++ b/arch/arm/include/asm/arch-socfpga/reset_manager.h @@ -10,6 +10,8 @@ void reset_cpu(ulong addr); void reset_deassert_peripherals_handoff(void);
+void socfpga_emac_reset(int enable); + void watchdog_disable(void);
struct socfpga_reset_manager {

On Mon 2014-09-15 13:06:12, Marek Vasut wrote:
Add functions to reset the EMAC ethernet blocks. We cannot handle two EMAC ethernet blocks yet, therefore the ifdefs. Once there is hardware using both EMAC blocks, this ifdef will have to go.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de
Acked-by: Pavel Machek pavel@denx.de

From: Pavel Machek pavel@denx.de
Add function to initialize the EMAC blocks upon board startup. The preprocessor guards against building on SoCFPGA-VT and against SPL build are not needed as those are handled implicitly via both SPL framework and the socfpga_cyclone5.h config file, which will not define CONFIG_DESIGNWARE_ETH if building for SoCFPGA-VT.
We cannot handle two EMAC ethernet blocks yet, therefore the ifdefs. Once there is hardware using both EMAC blocks, this ifdef will have to go.
Signed-off-by: Pavel Machek pavel@denx.de Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- arch/arm/cpu/armv7/socfpga/misc.c | 58 ++++++++++++++++------ arch/arm/include/asm/arch-socfpga/system_manager.h | 9 ++++ 2 files changed, 52 insertions(+), 15 deletions(-)
diff --git a/arch/arm/cpu/armv7/socfpga/misc.c b/arch/arm/cpu/armv7/socfpga/misc.c index 15cd8c2..ee7283b 100644 --- a/arch/arm/cpu/armv7/socfpga/misc.c +++ b/arch/arm/cpu/armv7/socfpga/misc.c @@ -9,15 +9,58 @@ #include <miiphy.h> #include <netdev.h> #include <asm/arch/reset_manager.h> +#include <asm/arch/system_manager.h>
DECLARE_GLOBAL_DATA_PTR;
+static struct socfpga_system_manager *sysmgr_regs = + (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; + int dram_init(void) { gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE); return 0; }
+/* + * DesignWare Ethernet initialization + */ +#ifdef CONFIG_DESIGNWARE_ETH +int cpu_eth_init(bd_t *bis) +{ +#if CONFIG_EMAC_BASE == SOCFPGA_EMAC0_ADDRESS + const int physhift = SYSMGR_EMACGRP_CTRL_PHYSEL0_LSB; +#elif CONFIG_EMAC_BASE == SOCFPGA_EMAC1_ADDRESS + const int physhift = SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB; +#else +#error "Incorrect CONFIG_EMAC_BASE value!" +#endif + + /* Initialize EMAC. This needs to be done at least once per boot. */ + + /* + * Putting the EMAC controller to reset when configuring the PHY + * interface select at System Manager + */ + socfpga_emac_reset(1); + + /* Clearing emac0 PHY interface select to 0 */ + clrbits_le32(&sysmgr_regs->emacgrp_ctrl, + SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << physhift); + + /* configure to PHY interface select choosed */ + setbits_le32(&sysmgr_regs->emacgrp_ctrl, + SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII << physhift); + + /* Release the EMAC controller from reset */ + socfpga_emac_reset(0); + + /* initialize and register the emac */ + return designware_initialize(CONFIG_EMAC_BASE, + CONFIG_PHY_INTERFACE_MODE); +} +#endif + #if defined(CONFIG_DISPLAY_CPUINFO) /* * Print CPU information @@ -44,18 +87,3 @@ int misc_init_r(void)
return 0; } - - -/* - * DesignWare Ethernet initialization - */ -int cpu_eth_init(bd_t *bis) -{ -#if !defined(CONFIG_SOCFPGA_VIRTUAL_TARGET) && !defined(CONFIG_SPL_BUILD) - /* initialize and register the emac */ - return designware_initialize(CONFIG_EMAC_BASE, - CONFIG_PHY_INTERFACE_MODE); -#else - return 0; -#endif -} diff --git a/arch/arm/include/asm/arch-socfpga/system_manager.h b/arch/arm/include/asm/arch-socfpga/system_manager.h index 90d2720..071ec4f 100644 --- a/arch/arm/include/asm/arch-socfpga/system_manager.h +++ b/arch/arm/include/asm/arch-socfpga/system_manager.h @@ -134,4 +134,13 @@ struct socfpga_system_manager { #define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel) \ ((((drvsel) << 0) & 0x7) | (((smplsel) << 3) & 0x38))
+/* EMAC Group Bit definitions */ +#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII 0x0 +#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII 0x1 +#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII 0x2 + +#define SYSMGR_EMACGRP_CTRL_PHYSEL0_LSB 0 +#define SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB 2 +#define SYSMGR_EMACGRP_CTRL_PHYSEL_MASK 0x3 + #endif /* _SYSTEM_MANAGER_H_ */

From: Pavel Machek pavel@denx.de
Add CPU function to register and initialize the dw_mmc SD controller. This allows us to use the HPS SDMMC block.
Signed-off-by: Pavel Machek pavel@denx.de Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- arch/arm/cpu/armv7/socfpga/misc.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/arch/arm/cpu/armv7/socfpga/misc.c b/arch/arm/cpu/armv7/socfpga/misc.c index ee7283b..440d2a3 100644 --- a/arch/arm/cpu/armv7/socfpga/misc.c +++ b/arch/arm/cpu/armv7/socfpga/misc.c @@ -10,6 +10,7 @@ #include <netdev.h> #include <asm/arch/reset_manager.h> #include <asm/arch/system_manager.h> +#include <asm/arch/dwmmc.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -61,6 +62,18 @@ int cpu_eth_init(bd_t *bis) } #endif
+#ifdef CONFIG_DWMMC +/* + * Initializes MMC controllers. + * to override, implement board_mmc_init() + */ +int cpu_mmc_init(bd_t *bis) +{ + return socfpga_dwmmc_init(SOCFPGA_SDMMC_ADDRESS, + CONFIG_HPS_SDMMC_BUSWIDTH, 0); +} +#endif + #if defined(CONFIG_DISPLAY_CPUINFO) /* * Print CPU information

From: Pavel Machek pavel@denx.de
Cosmetic change to the print_cpuinfo() function output. Align the output with the rest of initial output produced by U-Boot.
Signed-off-by: Pavel Machek pavel@denx.de Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- arch/arm/cpu/armv7/socfpga/misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/cpu/armv7/socfpga/misc.c b/arch/arm/cpu/armv7/socfpga/misc.c index 440d2a3..51be55c 100644 --- a/arch/arm/cpu/armv7/socfpga/misc.c +++ b/arch/arm/cpu/armv7/socfpga/misc.c @@ -80,7 +80,7 @@ int cpu_mmc_init(bd_t *bis) */ int print_cpuinfo(void) { - puts("CPU : Altera SOCFPGA Platform\n"); + puts("CPU: Altera SoCFPGA Platform\n"); return 0; } #endif

From: Pavel Machek pavel@denx.de
The bi_boot_params must point to offset 0x100 in DRAM. Make it so.
Signed-off-by: Pavel Machek pavel@denx.de Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- board/altera/socfpga/socfpga_cyclone5.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/board/altera/socfpga/socfpga_cyclone5.c b/board/altera/socfpga/socfpga_cyclone5.c index fb92852..bc8a87c 100644 --- a/board/altera/socfpga/socfpga_cyclone5.c +++ b/board/altera/socfpga/socfpga_cyclone5.c @@ -35,5 +35,9 @@ int board_early_init_f(void) int board_init(void) { icache_enable(); + + /* Address of boot parameters for ATAG (if ATAG is used) */ + gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; + return 0; }

Cosmetic change to the checkboard() function output. Align the output with the rest of initial output produced by U-Boot.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- board/altera/socfpga/socfpga_cyclone5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/board/altera/socfpga/socfpga_cyclone5.c b/board/altera/socfpga/socfpga_cyclone5.c index bc8a87c..4149842 100644 --- a/board/altera/socfpga/socfpga_cyclone5.c +++ b/board/altera/socfpga/socfpga_cyclone5.c @@ -17,7 +17,7 @@ DECLARE_GLOBAL_DATA_PTR; */ int checkboard(void) { - puts("BOARD : Altera SOCFPGA Cyclone5 Board\n"); + puts("BOARD: Altera SoCFPGA Cyclone5 Board\n"); return 0; }

On Mon 2014-09-15 13:06:17, Marek Vasut wrote:
Cosmetic change to the checkboard() function output. Align the output with the rest of initial output produced by U-Boot.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de
Acked-by: Pavel Machek pavel@denx.de

From: Pavel Machek pavel@denx.de
Add code necessary to program the FPGA part of SoCFPGA from U-Boot with an RBF blob. This patch also integrates the code into the FPGA driver framework in U-Boot so it can be used via the 'fpga' command.
Signed-off-by: Pavel Machek pavel@denx.de Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- arch/arm/cpu/armv7/socfpga/Makefile | 3 +- arch/arm/cpu/armv7/socfpga/fpga_manager.c | 354 +++++++++++++++++++++++ arch/arm/cpu/armv7/socfpga/misc.c | 37 +++ arch/arm/include/asm/arch-socfpga/fpga_manager.h | 77 +++++ drivers/fpga/altera.c | 21 ++ include/altera.h | 1 + 6 files changed, 492 insertions(+), 1 deletion(-) create mode 100644 arch/arm/cpu/armv7/socfpga/fpga_manager.c create mode 100644 arch/arm/include/asm/arch-socfpga/fpga_manager.h
diff --git a/arch/arm/cpu/armv7/socfpga/Makefile b/arch/arm/cpu/armv7/socfpga/Makefile index eb33f2c..8b6e108 100644 --- a/arch/arm/cpu/armv7/socfpga/Makefile +++ b/arch/arm/cpu/armv7/socfpga/Makefile @@ -8,5 +8,6 @@ #
obj-y := lowlevel_init.o -obj-y += misc.o timer.o reset_manager.o system_manager.o clock_manager.o +obj-y += misc.o timer.o reset_manager.o system_manager.o clock_manager.o \ + fpga_manager.o obj-$(CONFIG_SPL_BUILD) += spl.o freeze_controller.o scan_manager.o diff --git a/arch/arm/cpu/armv7/socfpga/fpga_manager.c b/arch/arm/cpu/armv7/socfpga/fpga_manager.c new file mode 100644 index 0000000..38d48f8 --- /dev/null +++ b/arch/arm/cpu/armv7/socfpga/fpga_manager.c @@ -0,0 +1,354 @@ +/* + * Copyright (C) 2012 Altera Corporation <www.altera.com> + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/fpga_manager.h> +#include <asm/arch/reset_manager.h> +#include <asm/arch/system_manager.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Timeout count */ +#define FPGA_TIMEOUT_CNT 0x1000000 + +static struct socfpga_fpga_manager *fpgamgr_regs = + (struct socfpga_fpga_manager *)SOCFPGA_FPGAMGRREGS_ADDRESS; +static struct socfpga_system_manager *sysmgr_regs = + (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; + +/* Check whether FPGA Init_Done signal is high */ +static int is_fpgamgr_initdone_high(void) +{ + unsigned long val; + val = readl(&fpgamgr_regs->gpio_ext_porta); + return val & FPGAMGRREGS_MON_GPIO_EXT_PORTA_ID_MASK; +} + +/* Get the FPGA mode */ +static int fpgamgr_get_mode(void) +{ + unsigned long val; + val = readl(&fpgamgr_regs->stat); + return val & FPGAMGRREGS_STAT_MODE_MASK; +} + +/* Check whether FPGA is ready to be accessed */ +int fpgamgr_test_fpga_ready(void) +{ + /* Check for init done signal */ + if (!is_fpgamgr_initdone_high()) + return 0; + + /* Check again to avoid false glitches */ + if (!is_fpgamgr_initdone_high()) + return 0; + + if (fpgamgr_get_mode() != FPGAMGRREGS_MODE_USERMODE) + return 0; + + return 1; +} + +/* Poll until FPGA is ready to be accessed or timeout occurred */ +int fpgamgr_poll_fpga_ready(void) +{ + unsigned long i; + + /* If FPGA is blank, wait till WD invoke warm reset */ + for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { + /* check for init done signal */ + if (!is_fpgamgr_initdone_high()) + continue; + /* check again to avoid false glitches */ + if (!is_fpgamgr_initdone_high()) + continue; + return 1; + } + + return 0; +} + +/* Set CD ratio */ +static void fpgamgr_set_cd_ratio(unsigned long ratio) +{ + clrsetbits_le32(&fpgamgr_regs->ctrl, + 0x3 << FPGAMGRREGS_CTRL_CDRATIO_LSB, + (ratio & 0x3) << FPGAMGRREGS_CTRL_CDRATIO_LSB); +} + +static int fpgamgr_dclkcnt_set(unsigned long cnt) +{ + unsigned long i; + + /* Clear any existing done status */ + if (readl(&fpgamgr_regs->dclkstat)) + writel(0x1, &fpgamgr_regs->dclkstat); + + /* Write the dclkcnt */ + writel(cnt, &fpgamgr_regs->dclkcnt); + + /* Wait till the dclkcnt done */ + for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { + if (!readl(&fpgamgr_regs->dclkstat)) + continue; + + writel(0x1, &fpgamgr_regs->dclkstat); + return 0; + } + + return -ETIMEDOUT; +} + +/* Start the FPGA programming by initialize the FPGA Manager */ +static int fpgamgr_program_init(void) +{ + unsigned long msel, i; + + /* Get the MSEL value */ + msel = readl(&fpgamgr_regs->stat); + msel &= FPGAMGRREGS_STAT_MSEL_MASK; + msel >>= FPGAMGRREGS_STAT_MSEL_LSB; + + /* + * Set the cfg width + * If MSEL[3] = 1, cfg width = 32 bit + */ + if (msel & 0x8) { + setbits_le32(&fpgamgr_regs->ctrl, + FPGAMGRREGS_CTRL_CFGWDTH_MASK); + + /* To determine the CD ratio */ + /* MSEL[1:0] = 0, CD Ratio = 1 */ + if ((msel & 0x3) == 0x0) + fpgamgr_set_cd_ratio(CDRATIO_x1); + /* MSEL[1:0] = 1, CD Ratio = 4 */ + else if ((msel & 0x3) == 0x1) + fpgamgr_set_cd_ratio(CDRATIO_x4); + /* MSEL[1:0] = 2, CD Ratio = 8 */ + else if ((msel & 0x3) == 0x2) + fpgamgr_set_cd_ratio(CDRATIO_x8); + + } else { /* MSEL[3] = 0 */ + clrbits_le32(&fpgamgr_regs->ctrl, + FPGAMGRREGS_CTRL_CFGWDTH_MASK); + + /* To determine the CD ratio */ + /* MSEL[1:0] = 0, CD Ratio = 1 */ + if ((msel & 0x3) == 0x0) + fpgamgr_set_cd_ratio(CDRATIO_x1); + /* MSEL[1:0] = 1, CD Ratio = 2 */ + else if ((msel & 0x3) == 0x1) + fpgamgr_set_cd_ratio(CDRATIO_x2); + /* MSEL[1:0] = 2, CD Ratio = 4 */ + else if ((msel & 0x3) == 0x2) + fpgamgr_set_cd_ratio(CDRATIO_x4); + } + + /* To enable FPGA Manager configuration */ + clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_NCE_MASK); + + /* To enable FPGA Manager drive over configuration line */ + setbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_EN_MASK); + + /* Put FPGA into reset phase */ + setbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_NCONFIGPULL_MASK); + + /* (1) wait until FPGA enter reset phase */ + for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { + if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_RESETPHASE) + break; + } + + /* If not in reset state, return error */ + if (fpgamgr_get_mode() != FPGAMGRREGS_MODE_RESETPHASE) { + puts("FPGA: Could not reset\n"); + return -1; + } + + /* Release FPGA from reset phase */ + clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_NCONFIGPULL_MASK); + + /* (2) wait until FPGA enter configuration phase */ + for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { + if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_CFGPHASE) + break; + } + + /* If not in configuration state, return error */ + if (fpgamgr_get_mode() != FPGAMGRREGS_MODE_CFGPHASE) { + puts("FPGA: Could not configure\n"); + return -2; + } + + /* Clear all interrupts in CB Monitor */ + writel(0xFFF, &fpgamgr_regs->gpio_porta_eoi); + + /* Enable AXI configuration */ + setbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_AXICFGEN_MASK); + + return 0; +} + +/* Write the RBF data to FPGA Manager */ +static noinline void fpgamgr_program_write(const unsigned long *rbf_data, + unsigned long rbf_size) +{ + uint32_t src = (uint32_t)rbf_data; + uint32_t dst = SOCFPGA_FPGAMGRDATA_ADDRESS; + + /* Number of loops for 32-byte long copying. */ + uint32_t loops32 = rbf_size / 32; + /* Number of loops for 4-byte long copying + trailing bytes */ + uint32_t loops4 = DIV_ROUND_UP(rbf_size % 32, 4); + + asm volatile( + "1: ldmia %0!, {r0-r7}\n" + " stmia %1!, {r0-r7}\n" + " sub %1, #32\n" + " subs %2, #1\n" + " bne 1b\n" + "2: ldr %2, [%0], #4\n" + " str %2, [%1]\n" + " subs %3, #1\n" + " bne 2b\n" + : "+r"(src), "+r"(dst), "+r"(loops32), "+r"(loops4) : + : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "cc"); +} + +/* Ensure the FPGA entering config done */ +static int fpgamgr_program_poll_cd(void) +{ + const uint32_t mask = FPGAMGRREGS_MON_GPIO_EXT_PORTA_NS_MASK | + FPGAMGRREGS_MON_GPIO_EXT_PORTA_CD_MASK; + unsigned long reg, i; + + /* (3) wait until full config done */ + for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { + reg = readl(&fpgamgr_regs->gpio_ext_porta); + + /* Config error */ + if (!(reg & mask)) { + printf("FPGA: Configuration error.\n"); + return -3; + } + + /* Config done without error */ + if (reg & mask) + break; + } + + /* Timeout happened, return error */ + if (i == FPGA_TIMEOUT_CNT) { + printf("FPGA: Timeout waiting for program.\n"); + return -4; + } + + /* Disable AXI configuration */ + clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_AXICFGEN_MASK); + + return 0; +} + +/* Ensure the FPGA entering init phase */ +static int fpgamgr_program_poll_initphase(void) +{ + unsigned long i; + + /* Additional clocks for the CB to enter initialization phase */ + if (fpgamgr_dclkcnt_set(0x4)) + return -5; + + /* (4) wait until FPGA enter init phase or user mode */ + for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { + if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_INITPHASE) + break; + if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_USERMODE) + break; + } + + /* If not in configuration state, return error */ + if (i == FPGA_TIMEOUT_CNT) + return -6; + + return 0; +} + +/* Ensure the FPGA entering user mode */ +static int fpgamgr_program_poll_usermode(void) +{ + unsigned long i; + + /* Additional clocks for the CB to exit initialization phase */ + if (fpgamgr_dclkcnt_set(0x5000)) + return -7; + + /* (5) wait until FPGA enter user mode */ + for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { + if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_USERMODE) + break; + } + /* If not in configuration state, return error */ + if (i == FPGA_TIMEOUT_CNT) + return -8; + + /* To release FPGA Manager drive over configuration line */ + clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_EN_MASK); + + return 0; +} + +/* + * FPGA Manager to program the FPGA. This is the interface used by FPGA driver. + * Return 0 for sucess, non-zero for error. + */ +int fpgamgr_program_fpga(const unsigned long *rbf_data, unsigned long rbf_size) +{ + unsigned long status; + + if ((uint32_t)rbf_data & 0x3) { + puts("FPGA: Unaligned data, realign to 32bit boundary.\n"); + return -EINVAL; + } + + /* Prior programming the FPGA, all bridges need to be shut off */ + + /* Disable all signals from hps peripheral controller to fpga */ + writel(0, &sysmgr_regs->fpgaintfgrp_module); + + /* Disable all signals from FPGA to HPS SDRAM */ +#define SDR_CTRLGRP_FPGAPORTRST_ADDRESS 0x5080 + writel(0, SOCFPGA_SDR_ADDRESS + SDR_CTRLGRP_FPGAPORTRST_ADDRESS); + + /* Disable all axi bridge (hps2fpga, lwhps2fpga & fpga2hps) */ + socfpga_bridges_reset(1); + + /* Unmap the bridges from NIC-301 */ + writel(0x1, SOCFPGA_L3REGS_ADDRESS); + + /* Initialize the FPGA Manager */ + status = fpgamgr_program_init(); + if (status) + return status; + + /* Write the RBF data to FPGA Manager */ + fpgamgr_program_write(rbf_data, rbf_size); + + /* Ensure the FPGA entering config done */ + status = fpgamgr_program_poll_cd(); + if (status) + return status; + + /* Ensure the FPGA entering init phase */ + status = fpgamgr_program_poll_initphase(); + if (status) + return status; + + /* Ensure the FPGA entering user mode */ + return fpgamgr_program_poll_usermode(); +} diff --git a/arch/arm/cpu/armv7/socfpga/misc.c b/arch/arm/cpu/armv7/socfpga/misc.c index 51be55c..8e25f09 100644 --- a/arch/arm/cpu/armv7/socfpga/misc.c +++ b/arch/arm/cpu/armv7/socfpga/misc.c @@ -6,6 +6,7 @@
#include <common.h> #include <asm/io.h> +#include <altera.h> #include <miiphy.h> #include <netdev.h> #include <asm/arch/reset_manager.h> @@ -93,8 +94,44 @@ int overwrite_console(void) } #endif
+#ifdef CONFIG_FPGA +/* + * FPGA programming support for SoC FPGA Cyclone V + */ +static Altera_desc altera_fpga[] = { + { + /* Family */ + Altera_SoCFPGA, + /* Interface type */ + fast_passive_parallel, + /* No limitation as additional data will be ignored */ + -1, + /* No device function table */ + NULL, + /* Base interface address specified in driver */ + NULL, + /* No cookie implementation */ + 0 + }, +}; + +/* add device descriptor to FPGA device table */ +static void socfpga_fpga_add(void) +{ + int i; + fpga_init(); + for (i = 0; i < ARRAY_SIZE(altera_fpga); i++) + fpga_add(fpga_altera, &altera_fpga[i]); +} +#else +static inline void socfpga_fpga_add(void) {} +#endif + int misc_init_r(void) { + /* Add device descriptor to FPGA device table */ + socfpga_fpga_add(); + /* This is needed, otherwise kernel is rebooted by watchdog. */ watchdog_disable();
diff --git a/arch/arm/include/asm/arch-socfpga/fpga_manager.h b/arch/arm/include/asm/arch-socfpga/fpga_manager.h new file mode 100644 index 0000000..4812591 --- /dev/null +++ b/arch/arm/include/asm/arch-socfpga/fpga_manager.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2012 Altera Corporation <www.altera.com> + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _FPGA_MANAGER_H_ +#define _FPGA_MANAGER_H_ + +struct socfpga_fpga_manager { + /* FPGA Manager Module */ + u32 stat; /* 0x00 */ + u32 ctrl; + u32 dclkcnt; + u32 dclkstat; + u32 gpo; /* 0x10 */ + u32 gpi; + u32 misci; /* 0x18 */ + u32 _pad_0x1c_0x82c[517]; + + /* Configuration Monitor (MON) Registers */ + u32 gpio_inten; /* 0x830 */ + u32 gpio_intmask; + u32 gpio_inttype_level; + u32 gpio_int_polarity; + u32 gpio_intstatus; /* 0x840 */ + u32 gpio_raw_intstatus; + u32 _pad_0x848; + u32 gpio_porta_eoi; + u32 gpio_ext_porta; /* 0x850 */ + u32 _pad_0x854_0x85c[3]; + u32 gpio_1s_sync; /* 0x860 */ + u32 _pad_0x864_0x868[2]; + u32 gpio_ver_id_code; + u32 gpio_config_reg2; /* 0x870 */ + u32 gpio_config_reg1; +}; + +#define FPGAMGRREGS_STAT_MODE_MASK 0x7 +#define FPGAMGRREGS_STAT_MSEL_MASK 0xf8 +#define FPGAMGRREGS_STAT_MSEL_LSB 3 + +#define FPGAMGRREGS_CTRL_CFGWDTH_MASK 0x200 +#define FPGAMGRREGS_CTRL_AXICFGEN_MASK 0x100 +#define FPGAMGRREGS_CTRL_NCONFIGPULL_MASK 0x4 +#define FPGAMGRREGS_CTRL_NCE_MASK 0x2 +#define FPGAMGRREGS_CTRL_EN_MASK 0x1 +#define FPGAMGRREGS_CTRL_CDRATIO_LSB 6 + +#define FPGAMGRREGS_MON_GPIO_EXT_PORTA_CRC_MASK 0x8 +#define FPGAMGRREGS_MON_GPIO_EXT_PORTA_ID_MASK 0x4 +#define FPGAMGRREGS_MON_GPIO_EXT_PORTA_CD_MASK 0x2 +#define FPGAMGRREGS_MON_GPIO_EXT_PORTA_NS_MASK 0x1 + +/* FPGA Mode */ +#define FPGAMGRREGS_MODE_FPGAOFF 0x0 +#define FPGAMGRREGS_MODE_RESETPHASE 0x1 +#define FPGAMGRREGS_MODE_CFGPHASE 0x2 +#define FPGAMGRREGS_MODE_INITPHASE 0x3 +#define FPGAMGRREGS_MODE_USERMODE 0x4 +#define FPGAMGRREGS_MODE_UNKNOWN 0x5 + +/* FPGA CD Ratio Value */ +#define CDRATIO_x1 0x0 +#define CDRATIO_x2 0x1 +#define CDRATIO_x4 0x2 +#define CDRATIO_x8 0x3 + +/* SoCFPGA support functions */ +int fpgamgr_test_fpga_ready(void); +int fpgamgr_poll_fpga_ready(void); + +/* FPGA driver API function */ +int fpgamgr_program_fpga(const unsigned long *rbf_data, unsigned long rbf_size); + +#endif /* _FPGA_MANAGER_H_ */ diff --git a/drivers/fpga/altera.c b/drivers/fpga/altera.c index 6e34a8e..d20b7be 100644 --- a/drivers/fpga/altera.c +++ b/drivers/fpga/altera.c @@ -1,4 +1,7 @@ /* + * (C) Copyright 2013 + * Altera Corporation <www.altera.com> + * * (C) Copyright 2003 * Steven Scholz, imc Measurement & Control, steven.scholz@imc-berlin.de * @@ -14,6 +17,9 @@ #include <common.h> #include <ACEX1K.h> #include <stratixII.h> +#if defined(CONFIG_FPGA_SOCFPGA) +#include <asm/arch/fpga_manager.h> +#endif
/* Define FPGA_DEBUG to get debug printf's */ /* #define FPGA_DEBUG */ @@ -59,6 +65,13 @@ int altera_load(Altera_desc *desc, const void *buf, size_t bsize) ret_val = StratixII_load (desc, buf, bsize); break; #endif +#if defined(CONFIG_FPGA_SOCFPGA) + case Altera_SoCFPGA: + PRINTF("%s: Launching the SoC FPGA Loader...\n", + __func__); + ret_val = fpgamgr_program_fpga(buf, bsize); + break; +#endif default: printf ("%s: Unsupported family type, %d\n", __FUNCTION__, desc->family); @@ -94,6 +107,11 @@ int altera_dump(Altera_desc *desc, const void *buf, size_t bsize) ret_val = StratixII_dump (desc, buf, bsize); break; #endif + case Altera_SoCFPGA: + printf("%s: Unsupported due to security reason, %d\n", + __func__, desc->family); + ret_val = FPGA_SUCCESS; + break; default: printf ("%s: Unsupported family type, %d\n", __FUNCTION__, desc->family); @@ -119,6 +137,9 @@ int altera_info( Altera_desc *desc ) case Altera_StratixII: printf ("Stratix II\n"); break; + case Altera_SoCFPGA: + printf("SoC FPGA\n"); + break; /* Add new family types here */ default: printf ("Unknown family type, %d\n", desc->family); diff --git a/include/altera.h b/include/altera.h index ae5f7ee..c7f78fc 100644 --- a/include/altera.h +++ b/include/altera.h @@ -27,6 +27,7 @@ typedef enum { /* typedef Altera_Family */ Altera_ACEX1K, /* ACEX1K Family */ Altera_CYC2, /* CYCLONII Family */ Altera_StratixII, /* StratixII Family */ + Altera_SoCFPGA, /* SoCFPGA Family */ /* Add new models here */ max_altera_type /* insert all new types before this */ } Altera_Family; /* end, typedef Altera_Family */

Dear Marek Vasut,
In message 1410779188-6880-26-git-send-email-marex@denx.de you wrote:
From: Pavel Machek pavel@denx.de
Add code necessary to program the FPGA part of SoCFPGA from U-Boot with an RBF blob. This patch also integrates the code into the FPGA driver framework in U-Boot so it can be used via the 'fpga' command.
...
+/* Get the FPGA mode */ +static int fpgamgr_get_mode(void) +{
- unsigned long val;
- val = readl(&fpgamgr_regs->stat);
- return val & FPGAMGRREGS_STAT_MODE_MASK;
+}
Please always separate declarations and code by a blank line (please fix globally).
Best regards,
Wolfgang Denk

On Monday, September 15, 2014 at 05:41:51 PM, Wolfgang Denk wrote:
Dear Marek Vasut,
In message 1410779188-6880-26-git-send-email-marex@denx.de you wrote:
From: Pavel Machek pavel@denx.de
Add code necessary to program the FPGA part of SoCFPGA from U-Boot with an RBF blob. This patch also integrates the code into the FPGA driver framework in U-Boot so it can be used via the 'fpga' command.
...
+/* Get the FPGA mode */ +static int fpgamgr_get_mode(void) +{
- unsigned long val;
- val = readl(&fpgamgr_regs->stat);
- return val & FPGAMGRREGS_STAT_MODE_MASK;
+}
Please always separate declarations and code by a blank line (please fix globally).
Done, thank you!
Best regards, Marek Vasut

On 09/15/2014 01:06 PM, Marek Vasut wrote:
From: Pavel Machek pavel@denx.de
Add code necessary to program the FPGA part of SoCFPGA from U-Boot with an RBF blob. This patch also integrates the code into the FPGA driver framework in U-Boot so it can be used via the 'fpga' command.
Signed-off-by: Pavel Machek pavel@denx.de Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de
arch/arm/cpu/armv7/socfpga/Makefile | 3 +- arch/arm/cpu/armv7/socfpga/fpga_manager.c | 354 +++++++++++++++++++++++
We have drivers/fpga and you should move this driver there to be visible for others. Maybe also nios can use this driver with some changes.
Thanks, Michal

On Tuesday, September 16, 2014 at 11:42:00 AM, Michal Simek wrote:
On 09/15/2014 01:06 PM, Marek Vasut wrote:
From: Pavel Machek pavel@denx.de
Add code necessary to program the FPGA part of SoCFPGA from U-Boot with an RBF blob. This patch also integrates the code into the FPGA driver framework in U-Boot so it can be used via the 'fpga' command.
Signed-off-by: Pavel Machek pavel@denx.de Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de
arch/arm/cpu/armv7/socfpga/Makefile | 3 +- arch/arm/cpu/armv7/socfpga/fpga_manager.c | 354 +++++++++++++++++++++++
We have drivers/fpga and you should move this driver there to be visible for others. Maybe also nios can use this driver with some changes.
Good point about the move, but how could NIOS possibly use this ?
Best regards, Marek Vasut

On 09/16/2014 12:12 PM, Marek Vasut wrote:
On Tuesday, September 16, 2014 at 11:42:00 AM, Michal Simek wrote:
On 09/15/2014 01:06 PM, Marek Vasut wrote:
From: Pavel Machek pavel@denx.de
Add code necessary to program the FPGA part of SoCFPGA from U-Boot with an RBF blob. This patch also integrates the code into the FPGA driver framework in U-Boot so it can be used via the 'fpga' command.
Signed-off-by: Pavel Machek pavel@denx.de Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de
arch/arm/cpu/armv7/socfpga/Makefile | 3 +- arch/arm/cpu/armv7/socfpga/fpga_manager.c | 354 +++++++++++++++++++++++
We have drivers/fpga and you should move this driver there to be visible for others. Maybe also nios can use this driver with some changes.
Good point about the move, but how could NIOS possibly use this ?
I don't know the architecture but I expect that this fpga_manager can also work with partial bitstream. It means the flow is. 1. load full bitstream with NIOS 2. NIOS become security manager and own this driver 3. NIOS is able to load partial bitstreams via this device.
Not sure if this realistic flow on socfpga but this is possible to do on our fpga. That's why IMHO this driver should be in drivers/fpga.
Also look at my xilinx fpga changes I have done recently and you should change that altera code to look the same and remove that ugly ifdef mess.
Thanks, Michal

On Tuesday, September 16, 2014 at 12:33:02 PM, Michal Simek wrote:
On 09/16/2014 12:12 PM, Marek Vasut wrote:
On Tuesday, September 16, 2014 at 11:42:00 AM, Michal Simek wrote:
On 09/15/2014 01:06 PM, Marek Vasut wrote:
From: Pavel Machek pavel@denx.de
Add code necessary to program the FPGA part of SoCFPGA from U-Boot with an RBF blob. This patch also integrates the code into the FPGA driver framework in U-Boot so it can be used via the 'fpga' command.
Signed-off-by: Pavel Machek pavel@denx.de Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de
arch/arm/cpu/armv7/socfpga/Makefile | 3 +- arch/arm/cpu/armv7/socfpga/fpga_manager.c | 354 +++++++++++++++++++++++
We have drivers/fpga and you should move this driver there to be visible for others. Maybe also nios can use this driver with some changes.
Good point about the move, but how could NIOS possibly use this ?
I don't know the architecture but I expect that this fpga_manager can also work with partial bitstream. It means the flow is.
- load full bitstream with NIOS
- NIOS become security manager and own this driver
- NIOS is able to load partial bitstreams via this device.
Not sure if this realistic flow on socfpga but this is possible to do on our fpga. That's why IMHO this driver should be in drivers/fpga.
Also look at my xilinx fpga changes I have done recently and you should change that altera code to look the same and remove that ugly ifdef mess.
I did clean that up to a certain degree. It was truly hideous. Who's picking up the patches for drivers/fpga/ nowadays ?
Best regards, Marek Vasut

Add function to enable and disable FPGA bridges. This code is used by the FPGA manager to disable the bridges before programming the FPGA and will later be also used by the initialization code for the chip to put the chip into well defined state during startup.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- arch/arm/cpu/armv7/socfpga/reset_manager.c | 38 +++++++++++++++++++++++ arch/arm/include/asm/arch-socfpga/reset_manager.h | 2 ++ 2 files changed, 40 insertions(+)
diff --git a/arch/arm/cpu/armv7/socfpga/reset_manager.c b/arch/arm/cpu/armv7/socfpga/reset_manager.c index 77579b7..85579c0 100644 --- a/arch/arm/cpu/armv7/socfpga/reset_manager.c +++ b/arch/arm/cpu/armv7/socfpga/reset_manager.c @@ -8,6 +8,7 @@ #include <common.h> #include <asm/io.h> #include <asm/arch/reset_manager.h> +#include <asm/arch/fpga_manager.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -53,6 +54,43 @@ void reset_deassert_peripherals_handoff(void) writel(0, &reset_manager_base->per_mod_reset); }
+#if defined(CONFIG_SOCFPGA_VIRTUAL_TARGET) +void socfpga_bridges_reset(int enable) +{ + /* For SoCFPGA-VT, this is NOP. */ +} +#else + +#define L3REGS_REMAP_LWHPS2FPGA_MASK 0x10 +#define L3REGS_REMAP_HPS2FPGA_MASK 0x08 +#define L3REGS_REMAP_OCRAM_MASK 0x01 + +void socfpga_bridges_reset(int enable) +{ + const uint32_t l3mask = L3REGS_REMAP_LWHPS2FPGA_MASK | + L3REGS_REMAP_HPS2FPGA_MASK | + L3REGS_REMAP_OCRAM_MASK; + + if (enable) { + /* brdmodrst */ + writel(0xffffffff, &reset_manager_base->brg_mod_reset); + } else { + /* Check signal from FPGA. */ + if (fpgamgr_poll_fpga_ready()) { + /* FPGA not ready. Wait for watchdog timeout. */ + printf("%s: fpga not ready, hanging.\n", __func__); + hang(); + } + + /* brdmodrst */ + writel(0, &reset_manager_base->brg_mod_reset); + + /* Remap the bridges into memory map */ + writel(l3mask, SOCFPGA_L3REGS_ADDRESS); + } +} +#endif + /* Change the reset state for EMAC 0 and EMAC 1 */ void socfpga_emac_reset(int enable) { diff --git a/arch/arm/include/asm/arch-socfpga/reset_manager.h b/arch/arm/include/asm/arch-socfpga/reset_manager.h index 9d22576..4cbce96 100644 --- a/arch/arm/include/asm/arch-socfpga/reset_manager.h +++ b/arch/arm/include/asm/arch-socfpga/reset_manager.h @@ -10,6 +10,8 @@ void reset_cpu(ulong addr); void reset_deassert_peripherals_handoff(void);
+void socfpga_bridges_reset(int enable); + void socfpga_emac_reset(int enable);
void watchdog_disable(void);

On Mon 2014-09-15 13:06:19, Marek Vasut wrote:
Add function to enable and disable FPGA bridges. This code is used by the FPGA manager to disable the bridges before programming the FPGA and will later be also used by the initialization code for the chip to put the chip into well defined state during startup.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de
Acked-by: Pavel Machek pavel@denx.de

Add missing system manager bits from Altera U-Boot to make the code comparable. These are the bits which depend on the FPGA manager.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- arch/arm/cpu/armv7/socfpga/system_manager.c | 39 +++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+)
diff --git a/arch/arm/cpu/armv7/socfpga/system_manager.c b/arch/arm/cpu/armv7/socfpga/system_manager.c index 07c72e4..11f7bad 100644 --- a/arch/arm/cpu/armv7/socfpga/system_manager.c +++ b/arch/arm/cpu/armv7/socfpga/system_manager.c @@ -15,6 +15,43 @@ static struct socfpga_system_manager *sysmgr_regs = (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS;
/* + * Populate the value for SYSMGR.FPGAINTF.MODULE based on pinmux setting. + * The value is not wrote to SYSMGR.FPGAINTF.MODULE but + * CONFIG_SYSMGR_ISWGRP_HANDOFF. + */ +static void populate_sysmgr_fpgaintf_module(void) +{ + uint32_t handoff_val = 0; + + /* ISWGRP_HANDOFF_FPGAINTF */ + writel(0, &sysmgr_regs->iswgrp_handoff[2]); + + /* Enable the signal for those HPS peripherals that use FPGA. */ + if (readl(&sysmgr_regs->nandusefpga) == SYSMGR_FPGAINTF_USEFPGA) + handoff_val |= SYSMGR_FPGAINTF_NAND; + if (readl(&sysmgr_regs->rgmii1usefpga) == SYSMGR_FPGAINTF_USEFPGA) + handoff_val |= SYSMGR_FPGAINTF_EMAC1; + if (readl(&sysmgr_regs->sdmmcusefpga) == SYSMGR_FPGAINTF_USEFPGA) + handoff_val |= SYSMGR_FPGAINTF_SDMMC; + if (readl(&sysmgr_regs->rgmii0usefpga) == SYSMGR_FPGAINTF_USEFPGA) + handoff_val |= SYSMGR_FPGAINTF_EMAC0; + if (readl(&sysmgr_regs->spim0usefpga) == SYSMGR_FPGAINTF_USEFPGA) + handoff_val |= SYSMGR_FPGAINTF_SPIM0; + if (readl(&sysmgr_regs->spim1usefpga) == SYSMGR_FPGAINTF_USEFPGA) + handoff_val |= SYSMGR_FPGAINTF_SPIM1; + + /* populate (not writing) the value for SYSMGR.FPGAINTF.MODULE + based on pinmux setting */ + setbits_le32(&sysmgr_regs->iswgrp_handoff[2], handoff_val); + + handoff_val = readl(&sysmgr_regs->iswgrp_handoff[2]); + if (fpgamgr_test_fpga_ready()) { + /* Enable the required signals only */ + writel(handoff_val, &sysmgr_regs->fpgaintfgrp_module); + } +} + +/* * Configure all the pin muxes */ void sysmgr_pinmux_init(void) @@ -26,4 +63,6 @@ void sysmgr_pinmux_init(void) writel(sys_mgr_init_table[i], regs); regs += sizeof(regs); } + + populate_sysmgr_fpgaintf_module(); }

Add configuration for the write-allocate mode of L1 D-Cache on ARM. This is needed for D-Cache operation on Cortex-A9 on the SoCFPGA .
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- arch/arm/include/asm/system.h | 1 + arch/arm/lib/cache-cp15.c | 2 ++ 2 files changed, 3 insertions(+)
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index d51ba66..ca2d44f 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -185,6 +185,7 @@ enum dcache_option { DCACHE_OFF = 0x12, DCACHE_WRITETHROUGH = 0x1a, DCACHE_WRITEBACK = 0x1e, + DCACHE_WRITEALLOC = 0x16, };
/* Size of an MMU section */ diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c index 3e62d58..2155fe8 100644 --- a/arch/arm/lib/cache-cp15.c +++ b/arch/arm/lib/cache-cp15.c @@ -73,6 +73,8 @@ __weak void dram_bank_mmu_setup(int bank) i++) { #if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH) set_section_dcache(i, DCACHE_WRITETHROUGH); +#elif defined(CONFIG_SYS_ARM_CACHE_WRITEALLOC) + set_section_dcache(i, DCACHE_WRITEALLOC); #else set_section_dcache(i, DCACHE_WRITEBACK); #endif

On Mon 2014-09-15 13:06:21, Marek Vasut wrote:
Add configuration for the write-allocate mode of L1 D-Cache on ARM. This is needed for D-Cache operation on Cortex-A9 on the SoCFPGA .
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de
Acked-by: Pavel Machek pavel@denx.de

The Cortex-A9 has 32-byte long L1 cachelines. Define this value.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- include/configs/socfpga_cyclone5.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/configs/socfpga_cyclone5.h b/include/configs/socfpga_cyclone5.h index f50081b..f0eac4d 100644 --- a/include/configs/socfpga_cyclone5.h +++ b/include/configs/socfpga_cyclone5.h @@ -26,6 +26,8 @@ #define CONFIG_SOCFPGA #define CONFIG_CLOCKS
+#define CONFIG_SYS_CACHELINE_SIZE 32 + /* base address for .text section */ #ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET #define CONFIG_SYS_TEXT_BASE 0x08000040

On Mon 2014-09-15 13:06:22, Marek Vasut wrote:
The Cortex-A9 has 32-byte long L1 cachelines. Define this value.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de
Acked-by: Pavel Machek pavel@denx.de

The code is now fixed to the point where we can safely enable the L1 data cache. Enable the D-Cache and set it as write-alloc.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- board/altera/socfpga/socfpga_cyclone5.c | 1 + include/configs/socfpga_cyclone5.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/board/altera/socfpga/socfpga_cyclone5.c b/board/altera/socfpga/socfpga_cyclone5.c index 4149842..6b98277 100644 --- a/board/altera/socfpga/socfpga_cyclone5.c +++ b/board/altera/socfpga/socfpga_cyclone5.c @@ -35,6 +35,7 @@ int board_early_init_f(void) int board_init(void) { icache_enable(); + dcache_enable();
/* Address of boot parameters for ATAG (if ATAG is used) */ gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; diff --git a/include/configs/socfpga_cyclone5.h b/include/configs/socfpga_cyclone5.h index f0eac4d..20da1ac 100644 --- a/include/configs/socfpga_cyclone5.h +++ b/include/configs/socfpga_cyclone5.h @@ -18,7 +18,6 @@ #undef CONFIG_SOCFPGA_VIRTUAL_TARGET
#define CONFIG_ARMV7 -#define CONFIG_SYS_DCACHE_OFF #undef CONFIG_USE_IRQ
#define CONFIG_MISC_INIT_R @@ -26,6 +25,7 @@ #define CONFIG_SOCFPGA #define CONFIG_CLOCKS
+#define CONFIG_SYS_ARM_CACHE_WRITEALLOC #define CONFIG_SYS_CACHELINE_SIZE 32
/* base address for .text section */

On Mon 2014-09-15 13:59:25, Marek Vasut wrote:
The code is now fixed to the point where we can safely enable the L1 data cache. Enable the D-Cache and set it as write-alloc.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de
Acked-by: Pavel Machek pavel@denx.de

Enable the PL310 L2 cache controller support for the SoCFPGA. With the cache related issues resolved, this is safe to be done.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- include/configs/socfpga_cyclone5.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/configs/socfpga_cyclone5.h b/include/configs/socfpga_cyclone5.h index 20da1ac..32175b7 100644 --- a/include/configs/socfpga_cyclone5.h +++ b/include/configs/socfpga_cyclone5.h @@ -27,6 +27,8 @@
#define CONFIG_SYS_ARM_CACHE_WRITEALLOC #define CONFIG_SYS_CACHELINE_SIZE 32 +#define CONFIG_SYS_L2_PL310 +#define CONFIG_SYS_PL310_BASE SOCFPGA_MPUL2_ADDRESS
/* base address for .text section */ #ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET

On Mon 2014-09-15 13:05:57, Marek Vasut wrote:
Add a few new variables to make the cache handling less cryptic. Add a variable for DMA and DATA descriptor start and end, so the correctness of the code is easier to inspect.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de
Acked-by: Pavel Machek pavel@denx.de

Add the Snoop Control Unit register definition file.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- arch/arm/include/asm/arch-socfpga/scu.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 arch/arm/include/asm/arch-socfpga/scu.h
diff --git a/arch/arm/include/asm/arch-socfpga/scu.h b/arch/arm/include/asm/arch-socfpga/scu.h new file mode 100644 index 0000000..7a5b074 --- /dev/null +++ b/arch/arm/include/asm/arch-socfpga/scu.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2014 Marek Vasut marex@denx.de + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __SOCFPGA_SCU_H__ +#define __SOCFPGA_SCU_H__ + +struct scu_registers { + u32 ctrl; /* 0x00 */ + u32 cfg; + u32 cpsr; + u32 iassr; + u32 _pad_0x10_0x3c[12]; /* 0x10 */ + u32 fsar; /* 0x40 */ + u32 fear; + u32 _pad_0x48_0x50[2]; + u32 acr; /* 0x54 */ + u32 sacr; +}; + +#endif /* __SOCFPGA_SCU_H__ */

On Mon 2014-09-15 13:05:57, Marek Vasut wrote:
Add a few new variables to make the cache handling less cryptic. Add a variable for DMA and DATA descriptor start and end, so the correctness of the code is easier to inspect.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de
Acked-by: Pavel Machek pavel@denx.de

Add register definition for the NIC-301 used on SoCFPGA.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- arch/arm/include/asm/arch-socfpga/nic301.h | 195 +++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 arch/arm/include/asm/arch-socfpga/nic301.h
diff --git a/arch/arm/include/asm/arch-socfpga/nic301.h b/arch/arm/include/asm/arch-socfpga/nic301.h new file mode 100644 index 0000000..3c8ab31 --- /dev/null +++ b/arch/arm/include/asm/arch-socfpga/nic301.h @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2014 Marek Vasut marex@denx.de + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _NIC301_REGISTERS_H_ +#define _NIC301_REGISTERS_H_ + +struct nic301_registers { + u32 remap; /* 0x0 */ + /* Security Register Group */ + u32 _pad_0x4_0x8[1]; + u32 l4main; + u32 l4sp; + u32 l4mp; /* 0x10 */ + u32 l4osc1; + u32 l4spim; + u32 stm; + u32 lwhps2fpgaregs; /* 0x20 */ + u32 _pad_0x24_0x28[1]; + u32 usb1; + u32 nanddata; + u32 _pad_0x30_0x80[20]; + u32 usb0; /* 0x80 */ + u32 nandregs; + u32 qspidata; + u32 fpgamgrdata; + u32 hps2fpgaregs; /* 0x90 */ + u32 acp; + u32 rom; + u32 ocram; + u32 sdrdata; /* 0xA0 */ + u32 _pad_0xa4_0x1fd0[1995]; + /* ID Register Group */ + u32 periph_id_4; /* 0x1FD0 */ + u32 _pad_0x1fd4_0x1fe0[3]; + u32 periph_id_0; /* 0x1FE0 */ + u32 periph_id_1; + u32 periph_id_2; + u32 periph_id_3; + u32 comp_id_0; /* 0x1FF0 */ + u32 comp_id_1; + u32 comp_id_2; + u32 comp_id_3; + u32 _pad_0x2000_0x2008[2]; + /* L4 MAIN */ + u32 l4main_fn_mod_bm_iss; + u32 _pad_0x200c_0x3008[1023]; + /* L4 SP */ + u32 l4sp_fn_mod_bm_iss; + u32 _pad_0x300c_0x4008[1023]; + /* L4 MP */ + u32 l4mp_fn_mod_bm_iss; + u32 _pad_0x400c_0x5008[1023]; + /* L4 OSC1 */ + u32 l4osc_fn_mod_bm_iss; + u32 _pad_0x500c_0x6008[1023]; + /* L4 SPIM */ + u32 l4spim_fn_mod_bm_iss; + u32 _pad_0x600c_0x7008[1023]; + /* STM */ + u32 stm_fn_mod_bm_iss; + u32 _pad_0x700c_0x7108[63]; + u32 stm_fn_mod; + u32 _pad_0x710c_0x8008[959]; + /* LWHPS2FPGA */ + u32 lwhps2fpga_fn_mod_bm_iss; + u32 _pad_0x800c_0x8108[63]; + u32 lwhps2fpga_fn_mod; + u32 _pad_0x810c_0xa008[1983]; + /* USB1 */ + u32 usb1_fn_mod_bm_iss; + u32 _pad_0xa00c_0xa044[14]; + u32 usb1_ahb_cntl; + u32 _pad_0xa048_0xb008[1008]; + /* NANDDATA */ + u32 nanddata_fn_mod_bm_iss; + u32 _pad_0xb00c_0xb108[63]; + u32 nanddata_fn_mod; + u32 _pad_0xb10c_0x20008[21439]; + /* USB0 */ + u32 usb0_fn_mod_bm_iss; + u32 _pad_0x2000c_0x20044[14]; + u32 usb0_ahb_cntl; + u32 _pad_0x20048_0x21008[1008]; + /* NANDREGS */ + u32 nandregs_fn_mod_bm_iss; + u32 _pad_0x2100c_0x21108[63]; + u32 nandregs_fn_mod; + u32 _pad_0x2110c_0x22008[959]; + /* QSPIDATA */ + u32 qspidata_fn_mod_bm_iss; + u32 _pad_0x2200c_0x22044[14]; + u32 qspidata_ahb_cntl; + u32 _pad_0x22048_0x23008[1008]; + /* FPGAMGRDATA */ + u32 fpgamgrdata_fn_mod_bm_iss; + u32 _pad_0x2300c_0x23040[13]; + u32 fpgamgrdata_wr_tidemark; /* 0x23040 */ + u32 _pad_0x23044_0x23108[49]; + u32 fn_mod; + u32 _pad_0x2310c_0x24008[959]; + /* HPS2FPGA */ + u32 hps2fpga_fn_mod_bm_iss; + u32 _pad_0x2400c_0x24040[13]; + u32 hps2fpga_wr_tidemark; /* 0x24040 */ + u32 _pad_0x24044_0x24108[49]; + u32 hps2fpga_fn_mod; + u32 _pad_0x2410c_0x25008[959]; + /* ACP */ + u32 acp_fn_mod_bm_iss; + u32 _pad_0x2500c_0x25108[63]; + u32 acp_fn_mod; + u32 _pad_0x2510c_0x26008[959]; + /* Boot ROM */ + u32 bootrom_fn_mod_bm_iss; + u32 _pad_0x2600c_0x26108[63]; + u32 bootrom_fn_mod; + u32 _pad_0x2610c_0x27008[959]; + /* On-chip RAM */ + u32 ocram_fn_mod_bm_iss; + u32 _pad_0x2700c_0x27040[13]; + u32 ocram_wr_tidemark; /* 0x27040 */ + u32 _pad_0x27044_0x27108[49]; + u32 ocram_fn_mod; + u32 _pad_0x2710c_0x42024[27590]; + /* DAP */ + u32 dap_fn_mod2; + u32 dap_fn_mod_ahb; + u32 _pad_0x4202c_0x42100[53]; + u32 dap_read_qos; /* 0x42100 */ + u32 dap_write_qos; + u32 dap_fn_mod; + u32 _pad_0x4210c_0x43100[1021]; + /* MPU */ + u32 mpu_read_qos; /* 0x43100 */ + u32 mpu_write_qos; + u32 mpu_fn_mod; + u32 _pad_0x4310c_0x44028[967]; + /* SDMMC */ + u32 sdmmc_fn_mod_ahb; + u32 _pad_0x4402c_0x44100[53]; + u32 sdmmc_read_qos; /* 0x44100 */ + u32 sdmmc_write_qos; + u32 sdmmc_fn_mod; + u32 _pad_0x4410c_0x45100[1021]; + /* DMA */ + u32 dma_read_qos; /* 0x45100 */ + u32 dma_write_qos; + u32 dma_fn_mod; + u32 _pad_0x4510c_0x46040[973]; + /* FPGA2HPS */ + u32 fpga2hps_wr_tidemark; /* 0x46040 */ + u32 _pad_0x46044_0x46100[47]; + u32 fpga2hps_read_qos; /* 0x46100 */ + u32 fpga2hps_write_qos; + u32 fpga2hps_fn_mod; + u32 _pad_0x4610c_0x47100[1021]; + /* ETR */ + u32 etr_read_qos; /* 0x47100 */ + u32 etr_write_qos; + u32 etr_fn_mod; + u32 _pad_0x4710c_0x48100[1021]; + /* EMAC0 */ + u32 emac0_read_qos; /* 0x48100 */ + u32 emac0_write_qos; + u32 emac0_fn_mod; + u32 _pad_0x4810c_0x49100[1021]; + /* EMAC1 */ + u32 emac1_read_qos; /* 0x49100 */ + u32 emac1_write_qos; + u32 emac1_fn_mod; + u32 _pad_0x4910c_0x4a028[967]; + /* USB0 */ + u32 usb0_fn_mod_ahb; + u32 _pad_0x4a02c_0x4a100[53]; + u32 usb0_read_qos; /* 0x4A100 */ + u32 usb0_write_qos; + u32 usb0_fn_mod; + u32 _pad_0x4a10c_0x4b100[1021]; + /* NAND */ + u32 nand_read_qos; /* 0x4B100 */ + u32 nand_write_qos; + u32 nand_fn_mod; + u32 _pad_0x4b10c_0x4c028[967]; + /* USB1 */ + u32 usb1_fn_mod_ahb; + u32 _pad_0x4c02c_0x4c100[53]; + u32 usb1_read_qos; /* 0x4C100 */ + u32 usb1_write_qos; + u32 usb1_fn_mod; +}; + +#endif /* _NIC301_REGISTERS_H_ */

On Mon 2014-09-15 13:05:57, Marek Vasut wrote:
Add a few new variables to make the cache handling less cryptic. Add a variable for DMA and DATA descriptor start and end, so the correctness of the code is easier to inspect.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de
Acked-by: Pavel Machek pavel@denx.de

On Tuesday, September 16, 2014 at 03:16:38 PM, Pavel Machek wrote:
On Mon 2014-09-15 13:05:57, Marek Vasut wrote:
Add a few new variables to make the cache handling less cryptic. Add a variable for DMA and DATA descriptor start and end, so the correctness of the code is easier to inspect.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de
Acked-by: Pavel Machek pavel@denx.de
Um, how many copies of this email did you send ? ;-)
Best regards, Marek Vasut

On 09/16/2014 01:10 PM, Marek Vasut wrote:
On Tuesday, September 16, 2014 at 03:16:38 PM, Pavel Machek wrote:
On Mon 2014-09-15 13:05:57, Marek Vasut wrote:
Add a few new variables to make the cache handling less cryptic. Add a variable for DMA and DATA descriptor start and end, so the correctness of the code is easier to inspect.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de
Acked-by: Pavel Machek pavel@denx.de
Um, how many copies of this email did you send ? ;-)
I got 8...do those count towards Pavel's creditability in the community? ;)
Dinh

On Wednesday, September 17, 2014 at 12:03:04 AM, Dinh Nguyen wrote:
On 09/16/2014 01:10 PM, Marek Vasut wrote:
On Tuesday, September 16, 2014 at 03:16:38 PM, Pavel Machek wrote:
On Mon 2014-09-15 13:05:57, Marek Vasut wrote:
Add a few new variables to make the cache handling less cryptic. Add a variable for DMA and DATA descriptor start and end, so the correctness of the code is easier to inspect.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de
Acked-by: Pavel Machek pavel@denx.de
Um, how many copies of this email did you send ? ;-)
I got 8...do those count towards Pavel's creditability in the community? ;)
Well, he managed to master the art of sending email all right. Now's the time to master the art of self-restraint ;-)
Best regards, Marek Vasut

Configure the PL310 address filter to make sure DRAM is mapped to 0x0. This code also configures the "remap" register of NIC-301 and sets the required 'mpuzero' bit.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- arch/arm/cpu/armv7/socfpga/misc.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/arch/arm/cpu/armv7/socfpga/misc.c b/arch/arm/cpu/armv7/socfpga/misc.c index 8e25f09..4ff8bd8 100644 --- a/arch/arm/cpu/armv7/socfpga/misc.c +++ b/arch/arm/cpu/armv7/socfpga/misc.c @@ -12,11 +12,17 @@ #include <asm/arch/reset_manager.h> #include <asm/arch/system_manager.h> #include <asm/arch/dwmmc.h> +#include <asm/arch/nic301.h> +#include <asm/pl310.h>
DECLARE_GLOBAL_DATA_PTR;
+static struct pl310_regs *const pl310 = + (struct pl310_regs *)CONFIG_SYS_PL310_BASE; static struct socfpga_system_manager *sysmgr_regs = (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; +static struct nic301_registers *nic301_regs = + (struct nic301_registers *)SOCFPGA_L3REGS_ADDRESS;
int dram_init(void) { @@ -129,6 +135,14 @@ static inline void socfpga_fpga_add(void) {}
int misc_init_r(void) { + /* Configure the L2 controller to make SDRAM start at 0 */ +#ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET + writel(0x2, &nic301_regs->remap); +#else + writel(0x1, &nic301_regs->remap); /* remap.mpuzero */ + writel(0x1, &pl310->pl310_addr_filter_start); +#endif + /* Add device descriptor to FPGA device table */ socfpga_fpga_add();

From: Pavel Machek pavel@denx.de
Add code which configures the AMBA NIC-301 and the SCU on the SoCFPGA . The code sets the access permissions for the CPU to the AMBA slaves such that the CPU can access them in both secure and non-secure mode.
Signed-off-by: Marek Vasut marex@denx.de Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de --- arch/arm/cpu/armv7/socfpga/misc.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/arch/arm/cpu/armv7/socfpga/misc.c b/arch/arm/cpu/armv7/socfpga/misc.c index 4ff8bd8..417db7c 100644 --- a/arch/arm/cpu/armv7/socfpga/misc.c +++ b/arch/arm/cpu/armv7/socfpga/misc.c @@ -13,6 +13,7 @@ #include <asm/arch/system_manager.h> #include <asm/arch/dwmmc.h> #include <asm/arch/nic301.h> +#include <asm/arch/scu.h> #include <asm/pl310.h>
DECLARE_GLOBAL_DATA_PTR; @@ -23,6 +24,8 @@ static struct socfpga_system_manager *sysmgr_regs = (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; static struct nic301_registers *nic301_regs = (struct nic301_registers *)SOCFPGA_L3REGS_ADDRESS; +static struct scu_registers *scu_regs = + (struct scu_registers *)SOCFPGA_MPUSCU_ADDRESS;
int dram_init(void) { @@ -133,8 +136,31 @@ static void socfpga_fpga_add(void) static inline void socfpga_fpga_add(void) {} #endif
+/* + * Convert all NIC-301 AMBA slaves from secure to non-secure + */ +static void socfpga_nic301_slave_ns(void) +{ + writel(0x1, &nic301_regs->lwhps2fpgaregs); + writel(0x1, &nic301_regs->hps2fpgaregs); + writel(0x1, &nic301_regs->acp); + writel(0x1, &nic301_regs->rom); + writel(0x1, &nic301_regs->ocram); + writel(0x1, &nic301_regs->sdrdata); +} + int misc_init_r(void) { + socfpga_bridges_reset(1); + socfpga_nic301_slave_ns(); + + /* + * Private components security: + * U-Boot : configure private timer, global timer and cpu component + * access as non secure for kernel stage (as required by Linux) + */ + setbits_le32(&scu_regs->sacr, 0xfff); + /* Configure the L2 controller to make SDRAM start at 0 */ #ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET writel(0x2, &nic301_regs->remap);

Hi!
On Mon 2014-09-15 13:05:53, Marek Vasut wrote:
This entire RFC series is the first stab at making SoCFPGA usable with mainline U-Boot again. There are still some bits missing, but in general, this allows me to use mainline U-Boot on my SoCFPGA systems. The big missing part is the SPL generation, which still needs a lot of additional work.
This set contains patches for a few subsystems, bu the most part is the SoCFPGA chip support.
Most of the patches should be in good shape already, so I wonder if the RFC tag is really necessary.
Just... I earlier today I tested Marek's git tree based on this series, and it works well for me on board similar to sockit.
So
Tested-by: Pavel Machek pavel@denx.de
Thanks and best regards, Pavel

On 09/16/2014 08:18 AM, Pavel Machek wrote:
Hi!
On Mon 2014-09-15 13:05:53, Marek Vasut wrote:
This entire RFC series is the first stab at making SoCFPGA usable with mainline U-Boot again. There are still some bits missing, but in general, this allows me to use mainline U-Boot on my SoCFPGA systems. The big missing part is the SPL generation, which still needs a lot of additional work.
This set contains patches for a few subsystems, bu the most part is the SoCFPGA chip support.
Most of the patches should be in good shape already, so I wonder if the RFC tag is really necessary.
Just... I earlier today I tested Marek's git tree based on this series, and it works well for me on board similar to sockit.
So
Tested-by: Pavel Machek pavel@denx.de
Thanks and best regards, Pavel
I applied all the patches to v2014.10-rc2, and I see that the watchdog has been enabled and it's getting reset:
U-Boot 2014.10-rc2-00139-g70e9e3e (Sep 16 2014 - 11:21:38)
CPU: Altera SoCFPGA Platform BOARD: Altera SoCFPGA Cyclone5 Board Watchdog enabled DRAM: U-Boot SPL 2013.01.01-00019-g9cce15f (Jul 18 2013 - 13:05:43) SDRAM : Initializing MMR registers SDRAM : Calibrating PHY SEQ.C: Preparing to start memory calibration SEQ.C: CALIBRATION PASSED ALTERA DWMMC: 0 reading u-boot.img reading u-boot.img
U-Boot 2014.10-rc2-00139-g70e9e3e (Sep 16 2014 - 11:21:38)
CPU: Altera SoCFPGA Platform BOARD: Altera SoCFPGA Cyclone5 Board Watchdog enabled DRAM:
This was tested a Cyclone5 devkit.
Dinh

On Tuesday, September 16, 2014 at 06:28:52 PM, Dinh Nguyen wrote:
On 09/16/2014 08:18 AM, Pavel Machek wrote:
Hi!
On Mon 2014-09-15 13:05:53, Marek Vasut wrote:
This entire RFC series is the first stab at making SoCFPGA usable with mainline U-Boot again. There are still some bits missing, but in general, this allows me to use mainline U-Boot on my SoCFPGA systems. The big missing part is the SPL generation, which still needs a lot of additional work.
This set contains patches for a few subsystems, bu the most part is the SoCFPGA chip support.
Most of the patches should be in good shape already, so I wonder if the RFC tag is really necessary.
Just... I earlier today I tested Marek's git tree based on this series, and it works well for me on board similar to sockit.
So
Tested-by: Pavel Machek pavel@denx.de
Thanks and best regards,
Pavel
I applied all the patches to v2014.10-rc2, and I see that the watchdog has been enabled and it's getting reset:
U-Boot 2014.10-rc2-00139-g70e9e3e (Sep 16 2014 - 11:21:38)
CPU: Altera SoCFPGA Platform BOARD: Altera SoCFPGA Cyclone5 Board Watchdog enabled DRAM: U-Boot SPL 2013.01.01-00019-g9cce15f (Jul 18 2013 - 13:05:43) SDRAM : Initializing MMR registers SDRAM : Calibrating PHY SEQ.C: Preparing to start memory calibration SEQ.C: CALIBRATION PASSED ALTERA DWMMC: 0 reading u-boot.img reading u-boot.img
U-Boot 2014.10-rc2-00139-g70e9e3e (Sep 16 2014 - 11:21:38)
CPU: Altera SoCFPGA Platform BOARD: Altera SoCFPGA Cyclone5 Board Watchdog enabled DRAM:
This doesn't seem like a WDT problem. How much DRAM is there on that kit ? In any case, try this:
1) Edit arch/arm/cpu/armv7/socfpga/misc.c 2) Locate call to get_ram_size() 3) Replace this function call with the size of your DRAM in bytes. (that is, make it "gd->ram_size = 128 * 1024 * 1024;" if you have 128MiB)
I suspect get_ram_size() on socfpga is still broken in mainline and causes this crash you observe.
btw you don't happen to have a spare CV and AV kits you could send me, so I can do the testing rounds on them too, do you ?
Best regards, Marek Vasut

On Tue, 16 Sep 2014, Marek Vasut wrote:
On Tuesday, September 16, 2014 at 06:28:52 PM, Dinh Nguyen wrote:
On 09/16/2014 08:18 AM, Pavel Machek wrote:
Hi!
On Mon 2014-09-15 13:05:53, Marek Vasut wrote:
This entire RFC series is the first stab at making SoCFPGA usable with mainline U-Boot again. There are still some bits missing, but in general, this allows me to use mainline U-Boot on my SoCFPGA systems. The big missing part is the SPL generation, which still needs a lot of additional work.
This set contains patches for a few subsystems, bu the most part is the SoCFPGA chip support.
Most of the patches should be in good shape already, so I wonder if the RFC tag is really necessary.
Just... I earlier today I tested Marek's git tree based on this series, and it works well for me on board similar to sockit.
So
Tested-by: Pavel Machek pavel@denx.de
Thanks and best regards,
Pavel
I applied all the patches to v2014.10-rc2, and I see that the watchdog has been enabled and it's getting reset:
U-Boot 2014.10-rc2-00139-g70e9e3e (Sep 16 2014 - 11:21:38)
CPU: Altera SoCFPGA Platform BOARD: Altera SoCFPGA Cyclone5 Board Watchdog enabled DRAM: U-Boot SPL 2013.01.01-00019-g9cce15f (Jul 18 2013 - 13:05:43) SDRAM : Initializing MMR registers SDRAM : Calibrating PHY SEQ.C: Preparing to start memory calibration SEQ.C: CALIBRATION PASSED ALTERA DWMMC: 0 reading u-boot.img reading u-boot.img
U-Boot 2014.10-rc2-00139-g70e9e3e (Sep 16 2014 - 11:21:38)
CPU: Altera SoCFPGA Platform BOARD: Altera SoCFPGA Cyclone5 Board Watchdog enabled DRAM:
This doesn't seem like a WDT problem. How much DRAM is there on that kit ? In
The devkit has 1GB.
any case, try this:
- Edit arch/arm/cpu/armv7/socfpga/misc.c
- Locate call to get_ram_size()
- Replace this function call with the size of your DRAM in bytes. (that is, make it "gd->ram_size = 128 * 1024 * 1024;" if you have 128MiB)
I suspect get_ram_size() on socfpga is still broken in mainline and causes this crash you observe.
Yes, tracked it down to get_ram_size(). I forced gd->ram_size to 1GB and it works fine for me now. I'll try to spend some cycles to debug the problem.
btw you don't happen to have a spare CV and AV kits you could send me, so I can do the testing rounds on them too, do you ?
I'll look around.
Dinh

On Tuesday, September 16, 2014 at 11:29:45 PM, dinguyen wrote:
On Tue, 16 Sep 2014, Marek Vasut wrote:
On Tuesday, September 16, 2014 at 06:28:52 PM, Dinh Nguyen wrote:
On 09/16/2014 08:18 AM, Pavel Machek wrote:
Hi!
On Mon 2014-09-15 13:05:53, Marek Vasut wrote:
This entire RFC series is the first stab at making SoCFPGA usable with mainline U-Boot again. There are still some bits missing, but in general, this allows me to use mainline U-Boot on my SoCFPGA systems. The big missing part is the SPL generation, which still needs a lot of additional work.
This set contains patches for a few subsystems, bu the most part is the SoCFPGA chip support.
Most of the patches should be in good shape already, so I wonder if the RFC tag is really necessary.
Just... I earlier today I tested Marek's git tree based on this series, and it works well for me on board similar to sockit.
So
Tested-by: Pavel Machek pavel@denx.de
Thanks and best regards,
Pavel
I applied all the patches to v2014.10-rc2, and I see that the watchdog has been enabled and it's getting reset:
U-Boot 2014.10-rc2-00139-g70e9e3e (Sep 16 2014 - 11:21:38)
CPU: Altera SoCFPGA Platform BOARD: Altera SoCFPGA Cyclone5 Board
Watchdog enabled
DRAM: U-Boot SPL 2013.01.01-00019-g9cce15f (Jul 18 2013 - 13:05:43) SDRAM : Initializing MMR registers SDRAM : Calibrating PHY SEQ.C: Preparing to start memory calibration SEQ.C: CALIBRATION PASSED ALTERA DWMMC: 0 reading u-boot.img reading u-boot.img
U-Boot 2014.10-rc2-00139-g70e9e3e (Sep 16 2014 - 11:21:38)
CPU: Altera SoCFPGA Platform BOARD: Altera SoCFPGA Cyclone5 Board
Watchdog enabled
DRAM:
This doesn't seem like a WDT problem. How much DRAM is there on that kit ? In
The devkit has 1GB.
Ah, thanks for this info!
any case, try this:
Edit arch/arm/cpu/armv7/socfpga/misc.c
Locate call to get_ram_size()
Replace this function call with the size of your DRAM in bytes.
(that is, make it "gd->ram_size = 128 * 1024 * 1024;" if you have 128MiB)
I suspect get_ram_size() on socfpga is still broken in mainline and causes this crash you observe.
Yes, tracked it down to get_ram_size(). I forced gd->ram_size to 1GB and it works fine for me now. I'll try to spend some cycles to debug the problem.
Hmmmmm, how much DRAM can the SoCFPGA chip drive in total ?
Well, consider a theoretical SoCFPGA board with 128MiB of DRAM attached to it, what happens if I try to write at address of the 129th MiB (which is past the DRAM) ? Will this generate an DABT for the ARM core or will some kind of DRAM "mirroring" or "wraparound" happen such that I would write to the content of 1st MiB of the DRAM ?
If I would get DABT, then there is a rather easy fix for that, see arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c and mxs_mem_get_size() function. The function places an assembly return instruction into the DABT handler entry position (offset 0x14 in ARM vector table IIRC) and then runs the get_dram_size() . The assembly instruction only returns from the DABT handler right past the code where the DABT happened. For the get_ram_size(), the read from the unpopulated DRAM space contains zeroes and the function doesn't even realize the DABT happened. But it considers the DRAM invalid and thus this works correctly. That's how it detects the amount of DRAM.
You might want to consider something similar if that's how it behaves on SoCFPGA.
btw you don't happen to have a spare CV and AV kits you could send me, so I can do the testing rounds on them too, do you ?
I'll look around.
Thanks!

On 09/16/2014 04:55 PM, Marek Vasut wrote:
On Tuesday, September 16, 2014 at 11:29:45 PM, dinguyen wrote:
On Tue, 16 Sep 2014, Marek Vasut wrote:
On Tuesday, September 16, 2014 at 06:28:52 PM, Dinh Nguyen wrote:
On 09/16/2014 08:18 AM, Pavel Machek wrote:
Hi!
On Mon 2014-09-15 13:05:53, Marek Vasut wrote:
This entire RFC series is the first stab at making SoCFPGA usable with mainline U-Boot again. There are still some bits missing, but in general, this allows me to use mainline U-Boot on my SoCFPGA systems. The big missing part is the SPL generation, which still needs a lot of additional work.
This set contains patches for a few subsystems, bu the most part is the SoCFPGA chip support.
Most of the patches should be in good shape already, so I wonder if the RFC tag is really necessary.
Just... I earlier today I tested Marek's git tree based on this series, and it works well for me on board similar to sockit.
So
Tested-by: Pavel Machek pavel@denx.de
Thanks and best regards,
Pavel
I applied all the patches to v2014.10-rc2, and I see that the watchdog has been enabled and it's getting reset:
U-Boot 2014.10-rc2-00139-g70e9e3e (Sep 16 2014 - 11:21:38)
CPU: Altera SoCFPGA Platform BOARD: Altera SoCFPGA Cyclone5 Board
Watchdog enabled
DRAM: U-Boot SPL 2013.01.01-00019-g9cce15f (Jul 18 2013 - 13:05:43) SDRAM : Initializing MMR registers SDRAM : Calibrating PHY SEQ.C: Preparing to start memory calibration SEQ.C: CALIBRATION PASSED ALTERA DWMMC: 0 reading u-boot.img reading u-boot.img
U-Boot 2014.10-rc2-00139-g70e9e3e (Sep 16 2014 - 11:21:38)
CPU: Altera SoCFPGA Platform BOARD: Altera SoCFPGA Cyclone5 Board
Watchdog enabled
DRAM:
This doesn't seem like a WDT problem. How much DRAM is there on that kit ? In
The devkit has 1GB.
Ah, thanks for this info!
any case, try this:
Edit arch/arm/cpu/armv7/socfpga/misc.c
Locate call to get_ram_size()
Replace this function call with the size of your DRAM in bytes.
(that is, make it "gd->ram_size = 128 * 1024 * 1024;" if you have 128MiB)
I suspect get_ram_size() on socfpga is still broken in mainline and causes this crash you observe.
Yes, tracked it down to get_ram_size(). I forced gd->ram_size to 1GB and it works fine for me now. I'll try to spend some cycles to debug the problem.
Hmmmmm, how much DRAM can the SoCFPGA chip drive in total ?
All of our devkits have at least 1 GiB and I have heard there is a variant with 2GiB in the wild. Spec says up to 4 GiB.
Well, consider a theoretical SoCFPGA board with 128MiB of DRAM attached to it, what happens if I try to write at address of the 129th MiB (which is past the DRAM) ? Will this generate an DABT for the ARM core or will some kind of DRAM "mirroring" or "wraparound" happen such that I would write to the content of 1st MiB of the DRAM ?
We've encountered this issue downstream on a system with 1 GiB.
If I would get DABT, then there is a rather easy fix for that, see arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c and mxs_mem_get_size() function. The function places an assembly return instruction into the DABT handler entry position (offset 0x14 in ARM vector table IIRC) and then runs the get_dram_size() . The assembly instruction only returns from the DABT handler right past the code where the DABT happened. For the get_ram_size(), the read from the unpopulated DRAM space contains zeroes and the function doesn't even realize the DABT happened. But it considers the DRAM invalid and thus this works correctly. That's how it detects the amount of DRAM.
You might want to consider something similar if that's how it behaves on SoCFPGA.
This could be the issue. I think Chin Liang would know about this more than me at this point. So I hope he can solve this quickly.
Seems odd that the get_ram_size is working on your DENX board and not the devkit.
Dinh

On Wednesday, September 17, 2014 at 12:29:54 AM, Dinh Nguyen wrote:
[...]
Yes, tracked it down to get_ram_size(). I forced gd->ram_size to 1GB and it works fine for me now. I'll try to spend some cycles to debug the problem.
Hmmmmm, how much DRAM can the SoCFPGA chip drive in total ?
All of our devkits have at least 1 GiB and I have heard there is a variant with 2GiB in the wild. Spec says up to 4 GiB.
OK, I see. You cannot realistically map all those 4GiB into the 32-bit address space of an CortexA9, but on the other hand, all those bugs related to an CA9 with 4GiB of DRAM should be fixed due to my work on Novena ;-)
Well, consider a theoretical SoCFPGA board with 128MiB of DRAM attached to it, what happens if I try to write at address of the 129th MiB (which is past the DRAM) ? Will this generate an DABT for the ARM core or will some kind of DRAM "mirroring" or "wraparound" happen such that I would write to the content of 1st MiB of the DRAM ?
We've encountered this issue downstream on a system with 1 GiB.
OK, so a wraparound happens ?
If I would get DABT, then there is a rather easy fix for that, see arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c and mxs_mem_get_size() function. The function places an assembly return instruction into the DABT handler entry position (offset 0x14 in ARM vector table IIRC) and then runs the get_dram_size() . The assembly instruction only returns from the DABT handler right past the code where the DABT happened. For the get_ram_size(), the read from the unpopulated DRAM space contains zeroes and the function doesn't even realize the DABT happened. But it considers the DRAM invalid and thus this works correctly. That's how it detects the amount of DRAM.
You might want to consider something similar if that's how it behaves on SoCFPGA.
This could be the issue. I think Chin Liang would know about this more than me at this point. So I hope he can solve this quickly.
Sure, patch is welcome!
Seems odd that the get_ram_size is working on your DENX board and not the devkit.
I _think_ I might have hacked this part up and it's still in the cleanup pipeline.
Best regards, Marek Vasut

On Wed, 2014-09-17 at 01:52 +0200, marex@denx.de wrote:
On Wednesday, September 17, 2014 at 12:29:54 AM, Dinh Nguyen wrote:
[...]
Yes, tracked it down to get_ram_size(). I forced gd->ram_size to 1GB and it works fine for me now. I'll try to spend some cycles to debug the problem.
Hmmmmm, how much DRAM can the SoCFPGA chip drive in total ?
All of our devkits have at least 1 GiB and I have heard there is a variant with 2GiB in the wild. Spec says up to 4 GiB.
OK, I see. You cannot realistically map all those 4GiB into the 32-bit address space of an CortexA9, but on the other hand, all those bugs related to an CA9 with 4GiB of DRAM should be fixed due to my work on Novena ;-)
Yup, 4GB would not be possible. Within SocFPGA, by using HPS-FPGA bridges, we can workaround by swapping memory chunk so ARM processor can access entire 4GB. Interested to find out how you did it for Novena :)
Well, consider a theoretical SoCFPGA board with 128MiB of DRAM attached to it, what happens if I try to write at address of the 129th MiB (which is past the DRAM) ? Will this generate an DABT for the ARM core or will some kind of DRAM "mirroring" or "wraparound" happen such that I would write to the content of 1st MiB of the DRAM ?
We've encountered this issue downstream on a system with 1 GiB.
OK, so a wraparound happens ?
It should be a wrap around. It is not working previously as incorrect configuration for one of SDRAM parameters. The fix is under internal review now. :)
If I would get DABT, then there is a rather easy fix for that, see arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c and mxs_mem_get_size() function. The function places an assembly return instruction into the DABT handler entry position (offset 0x14 in ARM vector table IIRC) and then runs the get_dram_size() . The assembly instruction only returns from the DABT handler right past the code where the DABT happened. For the get_ram_size(), the read from the unpopulated DRAM space contains zeroes and the function doesn't even realize the DABT happened. But it considers the DRAM invalid and thus this works correctly. That's how it detects the amount of DRAM.
You might want to consider something similar if that's how it behaves on SoCFPGA.
This could be the issue. I think Chin Liang would know about this more than me at this point. So I hope he can solve this quickly.
Sure, patch is welcome!
Hmmm... actually I can get it works well for my Altera dev kit. The get_dram_size would take in the argument PHYS_SDRAM_1_SIZE. From here, the function will ensure the memory specified can read and writable. If its failing here, probably the SDRAM access might have issue. FYI, PHYS_SDRAM_1_SIZE is 0x40000000 for 1GB.
Seems odd that the get_ram_size is working on your DENX board and not the devkit.
I _think_ I might have hacked this part up and it's still in the cleanup pipeline.
It works for me without hacks. I can read and write to the SDRAM memory well (include 1MB region).
U-Boot 2014.10-rc2-00123-g461be2f-dirty (Sep 17 2014 - 04:28:52)
CPU: Altera SoCFPGA Platform BOARD: Altera SoCFPGA Cyclone5 Board DRAM: 1 GiB WARNING: Caches not enabled Using default environment
In: serial Out: serial Err: serial Net: dwmac.ff702000 Error: dwmac.ff702000 address not set.
Warning: Your board does not use generic board. Please read doc/README.generic-board and take action. Boards not upgraded by the late 2014 may break or be removed. Hit any key to stop autoboot: 0 Wrong Image Format for bootm command ERROR: can't get kernel image! SOCFPGA_CYCLONE5 # md 0 00000000: 00000000 aaaaaaaa aaaaaaaa aaaaaaaa ................ 00000010: aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa ................ 00000020: 55555555 55555555 55555555 55555555 UUUUUUUUUUUUUUUU 00000030: 55555555 55555555 55555555 55555555 UUUUUUUUUUUUUUUU 00000040: 7f7b958a a30289de 6bfe35cb 2d3f494f ..{......5.kOI?- 00000050: d5777778 6f010bb3 ec671fe4 27131f7b xww....o..g.{..' 00000060: 2f6ff6e4 bb97cecd 7fff9dda 6ffa1fcd ..o/...........o 00000070: b7375b84 7159d3ae f07ac971 e99bbff6 .[7...Yqq.z..... 00000080: d325d7fd d3b663b8 f377cfea f3675f72 ..%..c....w.r_g. 00000090: 3d1d4cd9 11a59b18 b795fffd 33ba95b8 .L.=...........3 000000a0: 575bbfef 73eb794f 33536eee 104389cf ..[WOy.s.nS3..C. 000000b0: 7763a778 35ff5fd8 f33e57c1 f777fbce x.cw._.5.W>...w. 000000c0: f35b6f9b 5bf70fdb bb730de3 7d7b5f88 .o[....[..s.._{} 000000d0: 5547a7f9 f33f07eb a395364c b35377e8 ..GU..?.L6...wS. 000000e0: 77bf6597 27737ea2 af3577f5 5b34f7d9 .e.w.~s'.w5...4[ 000000f0: 33eadbba fed7df87 3efbfaa8 83b9ef9c ...3.......>.... SOCFPGA_CYCLONE5 # mw 0 12345678 100 SOCFPGA_CYCLONE5 # md 0 00000000: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 00000010: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 00000020: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 00000030: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 00000040: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 00000050: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 00000060: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 00000070: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 00000080: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 00000090: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 000000a0: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 000000b0: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 000000c0: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 000000d0: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 000000e0: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 000000f0: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. SOCFPGA_CYCLONE5 # md 100000 00100000: eafffffd fbff4b3f fffffffe fdff33be ....?K.......3.. 00100010: ffb2aacf f7779ac4 f73bbf7f f7fbfbfc ......w...;..... 00100020: ffe3bb6d ef9f3fff fdb63bbd f6f76f5d m....?...;..]o.. 00100030: efafbdf1 bbefbdbd efbffcfd fffffffd ................ 00100040: fffbb58f e7baabfc ebfa37cd ed3ff96e .........7..n.?. 00100050: ff7ff7f4 ef1b3ff3 eff71fb6 ffbb0d73 .....?......s... 00100060: efeff6e7 ffb7afeb f7bfbdfb efffffff ................ 00100070: f7fff7ff f7df73ee f1fafff5 ebbbb1e7 .....s.......... 00100080: f3e3dff5 f7eff3ff fb77fd64 fbffdff2 ........d.w..... 00100090: ffbc5cfd f5fbbff8 effffffd f7f8a1fc ............... 001000a0: 5b7b3fff f7bb734f fbffffee f3fb8bcf .?{[Os.......... 001000b0: f3b3b75f ffffffda f3bf5fc5 fbffffdb _........_...... 001000c0: f3df6fde dbffffdd fbf1ede7 bd7b7fdc .o............{. 001000d0: f7d7b77f f39f2fef f7933bdc f35337af ...../...;...7S. 001000e0: f7f71ddf e7f77e38 ef7777fd ffb4f2fc ....8~...ww..... 001000f0: f3eafb5e fffffee7 fffbdaec f3f0e5f7 ^............... SOCFPGA_CYCLONE5 # mw 100000 23456789 100 SOCFPGA_CYCLONE5 # md 100000 00100000: 23456789 23456789 23456789 23456789 .gE#.gE#.gE#.gE# 00100010: 23456789 23456789 23456789 23456789 .gE#.gE#.gE#.gE# 00100020: 23456789 23456789 23456789 23456789 .gE#.gE#.gE#.gE# 00100030: 23456789 23456789 23456789 23456789 .gE#.gE#.gE#.gE# 00100040: 23456789 23456789 23456789 23456789 .gE#.gE#.gE#.gE# 00100050: 23456789 23456789 23456789 23456789 .gE#.gE#.gE#.gE# 00100060: 23456789 23456789 23456789 23456789 .gE#.gE#.gE#.gE# 00100070: 23456789 23456789 23456789 23456789 .gE#.gE#.gE#.gE# 00100080: 23456789 23456789 23456789 23456789 .gE#.gE#.gE#.gE# 00100090: 23456789 23456789 23456789 23456789 .gE#.gE#.gE#.gE# 001000a0: 23456789 23456789 23456789 23456789 .gE#.gE#.gE#.gE# 001000b0: 23456789 23456789 23456789 23456789 .gE#.gE#.gE#.gE# 001000c0: 23456789 23456789 23456789 23456789 .gE#.gE#.gE#.gE# 001000d0: 23456789 23456789 23456789 23456789 .gE#.gE#.gE#.gE# 001000e0: 23456789 23456789 23456789 23456789 .gE#.gE#.gE#.gE# 001000f0: 23456789 23456789 23456789 23456789 .gE#.gE#.gE#.gE# SOCFPGA_CYCLONE5 #
Thanks Chin Liang
Best regards, Marek Vasut

On Wednesday, September 17, 2014 at 01:07:29 PM, Chin Liang See wrote:
On Wed, 2014-09-17 at 01:52 +0200, marex@denx.de wrote:
On Wednesday, September 17, 2014 at 12:29:54 AM, Dinh Nguyen wrote:
[...]
Yes, tracked it down to get_ram_size(). I forced gd->ram_size to 1GB and it works fine for me now. I'll try to spend some cycles to debug the problem.
Hmmmmm, how much DRAM can the SoCFPGA chip drive in total ?
All of our devkits have at least 1 GiB and I have heard there is a variant with 2GiB in the wild. Spec says up to 4 GiB.
OK, I see. You cannot realistically map all those 4GiB into the 32-bit address space of an CortexA9, but on the other hand, all those bugs related to an CA9 with 4GiB of DRAM should be fixed due to my work on Novena ;-)
Yup, 4GB would not be possible. Within SocFPGA, by using HPS-FPGA bridges, we can workaround by swapping memory chunk so ARM processor can access entire 4GB. Interested to find out how you did it for Novena :)
Awwwwww, you know this kind of stuff is really so cool about these SoC+FPGA combo designs :)
As for the Novena, MX6 can only address 3.8 GiB, there is a bit of the DRAM which is not available .
Well, consider a theoretical SoCFPGA board with 128MiB of DRAM attached to it, what happens if I try to write at address of the 129th MiB (which is past the DRAM) ? Will this generate an DABT for the ARM core or will some kind of DRAM "mirroring" or "wraparound" happen such that I would write to the content of 1st MiB of the DRAM ?
We've encountered this issue downstream on a system with 1 GiB.
OK, so a wraparound happens ?
It should be a wrap around. It is not working previously as incorrect configuration for one of SDRAM parameters. The fix is under internal review now. :)
All right :)
If I would get DABT, then there is a rather easy fix for that, see arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c and mxs_mem_get_size() function. The function places an assembly return instruction into the DABT handler entry position (offset 0x14 in ARM vector table IIRC) and then runs the get_dram_size() . The assembly instruction only returns from the DABT handler right past the code where the DABT happened. For the get_ram_size(), the read from the unpopulated DRAM space contains zeroes and the function doesn't even realize the DABT happened. But it considers the DRAM invalid and thus this works correctly. That's how it detects the amount of DRAM.
You might want to consider something similar if that's how it behaves on SoCFPGA.
This could be the issue. I think Chin Liang would know about this more than me at this point. So I hope he can solve this quickly.
Sure, patch is welcome!
Hmmm... actually I can get it works well for my Altera dev kit. The get_dram_size would take in the argument PHYS_SDRAM_1_SIZE. From here, the function will ensure the memory specified can read and writable. If its failing here, probably the SDRAM access might have issue. FYI, PHYS_SDRAM_1_SIZE is 0x40000000 for 1GB.
Aw, fixed locally, thanks!
[...]
Pavel had some strange issue here, but these patches should address that. This one 'arm: socfpga: pl310: Map SDRAM to 0x0' is extremely important .

Dear Chin Liang See,
In message 1410952049.7769.11.camel@clsee-VirtualBox.altera.com you wrote:
Hmmm... actually I can get it works well for my Altera dev kit. The get_dram_size would take in the argument PHYS_SDRAM_1_SIZE. From here, the function will ensure the memory specified can read and writable. If its failing here, probably the SDRAM access might have issue. FYI, PHYS_SDRAM_1_SIZE is 0x40000000 for 1GB.
Normally, get_dram_size() would be called with a size argument that is _larger_ (twice as big) as the biggest possible memory configuration on the respective device. Otherwise it can only detect smaller memory sizes, but would fail to detect if a bigger memory device is installed by accident.
Best regards,
Wolfgang Denk

Dear Wolfgang,
On Wed, 2014-09-17 at 16:11 +0200, ZY - wd wrote:
Dear Chin Liang See,
In message 1410952049.7769.11.camel@clsee-VirtualBox.altera.com you wrote:
Hmmm... actually I can get it works well for my Altera dev kit. The get_dram_size would take in the argument PHYS_SDRAM_1_SIZE. From here, the function will ensure the memory specified can read and writable. If its failing here, probably the SDRAM access might have issue. FYI, PHYS_SDRAM_1_SIZE is 0x40000000 for 1GB.
Normally, get_dram_size() would be called with a size argument that is _larger_ (twice as big) as the biggest possible memory configuration on the respective device. Otherwise it can only detect smaller memory sizes, but would fail to detect if a bigger memory device is installed by accident.
Yup, you are right. But currently, the memory space after the SDRAM is a bridge to FPGA. We will get data abort when trying to read that area (for a blank FPGA).
I believe Marek's suggestion to work around the DABT and memory detection would work around SOCFPGA memory detection. Its something we would work closely with Marek to enable this auto detection.
Thanks Chin Liang
Best regards,
Wolfgang Denk

On Friday, September 19, 2014 at 11:44:48 AM, Chin Liang See wrote:
Dear Wolfgang,
On Wed, 2014-09-17 at 16:11 +0200, ZY - wd wrote:
Dear Chin Liang See,
In message 1410952049.7769.11.camel@clsee-VirtualBox.altera.com you wrote:
Hmmm... actually I can get it works well for my Altera dev kit. The get_dram_size would take in the argument PHYS_SDRAM_1_SIZE. From here, the function will ensure the memory specified can read and writable. If its failing here, probably the SDRAM access might have issue. FYI, PHYS_SDRAM_1_SIZE is 0x40000000 for 1GB.
Normally, get_dram_size() would be called with a size argument that is _larger_ (twice as big) as the biggest possible memory configuration on the respective device. Otherwise it can only detect smaller memory sizes, but would fail to detect if a bigger memory device is installed by accident.
Yup, you are right. But currently, the memory space after the SDRAM is a bridge to FPGA. We will get data abort when trying to read that area (for a blank FPGA).
This is good, no ? If you reliably get DABT if the H2F bridge is disabled, you can place the trampoline into the DABT vector and detect DRAM size. I'll have to test this.
I believe Marek's suggestion to work around the DABT and memory detection would work around SOCFPGA memory detection. Its something we would work closely with Marek to enable this auto detection.
OK ;-)
Best regards, Marek Vasut

On Friday, September 19, 2014 at 01:12:23 PM, Marek Vasut wrote:
On Friday, September 19, 2014 at 11:44:48 AM, Chin Liang See wrote:
Dear Wolfgang,
On Wed, 2014-09-17 at 16:11 +0200, ZY - wd wrote:
Dear Chin Liang See,
In message 1410952049.7769.11.camel@clsee-VirtualBox.altera.com you
wrote:
Hmmm... actually I can get it works well for my Altera dev kit. The get_dram_size would take in the argument PHYS_SDRAM_1_SIZE. From here, the function will ensure the memory specified can read and writable. If its failing here, probably the SDRAM access might have issue. FYI, PHYS_SDRAM_1_SIZE is 0x40000000 for 1GB.
Normally, get_dram_size() would be called with a size argument that is _larger_ (twice as big) as the biggest possible memory configuration on the respective device. Otherwise it can only detect smaller memory sizes, but would fail to detect if a bigger memory device is installed by accident.
Yup, you are right. But currently, the memory space after the SDRAM is a bridge to FPGA. We will get data abort when trying to read that area (for a blank FPGA).
This is good, no ? If you reliably get DABT if the H2F bridge is disabled, you can place the trampoline into the DABT vector and detect DRAM size. I'll have to test this.
Aw snap, on my hardware, when I access past SDRAM, I am getting a wrap around. What's worse is that I can reliably read and write from that location. This renders get_ram_size() unusable. All right, guys, ideas ?
Best regards, Marek Vasut

Dear Marek,
In message 201409162355.22221.marex@denx.de you wrote:
... For the get_ram_size(), the read
from the unpopulated DRAM space contains zeroes ...
<nitpick>
Reading from non-existent memory is not guaranteed to return zeroes, nor any other specific value; in general, the value you read back is undefined.
</nitpick>
Best regards,
Wolfgang Denk

On Tue, 16 Sep 2014, Marek Vasut wrote:
On Tuesday, September 16, 2014 at 06:28:52 PM, Dinh Nguyen wrote:
On 09/16/2014 08:18 AM, Pavel Machek wrote:
Hi!
On Mon 2014-09-15 13:05:53, Marek Vasut wrote:
This entire RFC series is the first stab at making SoCFPGA usable with mainline U-Boot again. There are still some bits missing, but in general, this allows me to use mainline U-Boot on my SoCFPGA systems. The big missing part is the SPL generation, which still needs a lot of additional work.
This set contains patches for a few subsystems, bu the most part is the SoCFPGA chip support.
Most of the patches should be in good shape already, so I wonder if the RFC tag is really necessary.
Just... I earlier today I tested Marek's git tree based on this series, and it works well for me on board similar to sockit.
So
Tested-by: Pavel Machek pavel@denx.de
Thanks and best regards,
Pavel
I applied all the patches to v2014.10-rc2, and I see that the watchdog has been enabled and it's getting reset:
U-Boot 2014.10-rc2-00139-g70e9e3e (Sep 16 2014 - 11:21:38)
CPU: Altera SoCFPGA Platform BOARD: Altera SoCFPGA Cyclone5 Board Watchdog enabled DRAM: U-Boot SPL 2013.01.01-00019-g9cce15f (Jul 18 2013 - 13:05:43) SDRAM : Initializing MMR registers SDRAM : Calibrating PHY SEQ.C: Preparing to start memory calibration SEQ.C: CALIBRATION PASSED ALTERA DWMMC: 0 reading u-boot.img reading u-boot.img
U-Boot 2014.10-rc2-00139-g70e9e3e (Sep 16 2014 - 11:21:38)
CPU: Altera SoCFPGA Platform BOARD: Altera SoCFPGA Cyclone5 Board Watchdog enabled DRAM:
This doesn't seem like a WDT problem. How much DRAM is there on that kit ? In any case, try this:
- Edit arch/arm/cpu/armv7/socfpga/misc.c
- Locate call to get_ram_size()
- Replace this function call with the size of your DRAM in bytes. (that is, make it "gd->ram_size = 128 * 1024 * 1024;" if you have 128MiB)
I suspect get_ram_size() on socfpga is still broken in mainline and causes this crash you observe.
btw you don't happen to have a spare CV and AV kits you could send me, so I can do the testing rounds on them too, do you ?
What board are doing your testing on? The Arrow Sockit?
I also see this error print:
U-Boot 2014.10-rc2-00139-g70e9e3e-dirty (Sep 16 2014 - 16:26:56)
CPU: Altera SoCFPGA Platform BOARD: Altera SoCFPGA Cyclone5 Board Watchdog enabled DRAM: 1 GiB WARNING: Caches not enabled Using default environment
In: serial Out: serial Err: serial Net: dwmac.ff702000 Error: dwmac.ff702000 address not set. ^^^^^
Do you see this on your side? I can track it down...
Thanks, Dinh

On Tuesday, September 16, 2014 at 11:35:38 PM, dinguyen wrote:
On Tue, 16 Sep 2014, Marek Vasut wrote:
On Tuesday, September 16, 2014 at 06:28:52 PM, Dinh Nguyen wrote:
On 09/16/2014 08:18 AM, Pavel Machek wrote:
Hi!
On Mon 2014-09-15 13:05:53, Marek Vasut wrote:
This entire RFC series is the first stab at making SoCFPGA usable with mainline U-Boot again. There are still some bits missing, but in general, this allows me to use mainline U-Boot on my SoCFPGA systems. The big missing part is the SPL generation, which still needs a lot of additional work.
This set contains patches for a few subsystems, bu the most part is the SoCFPGA chip support.
Most of the patches should be in good shape already, so I wonder if the RFC tag is really necessary.
Just... I earlier today I tested Marek's git tree based on this series, and it works well for me on board similar to sockit.
So
Tested-by: Pavel Machek pavel@denx.de
Thanks and best regards,
Pavel
I applied all the patches to v2014.10-rc2, and I see that the watchdog has been enabled and it's getting reset:
U-Boot 2014.10-rc2-00139-g70e9e3e (Sep 16 2014 - 11:21:38)
CPU: Altera SoCFPGA Platform BOARD: Altera SoCFPGA Cyclone5 Board
Watchdog enabled
DRAM: U-Boot SPL 2013.01.01-00019-g9cce15f (Jul 18 2013 - 13:05:43) SDRAM : Initializing MMR registers SDRAM : Calibrating PHY SEQ.C: Preparing to start memory calibration SEQ.C: CALIBRATION PASSED ALTERA DWMMC: 0 reading u-boot.img reading u-boot.img
U-Boot 2014.10-rc2-00139-g70e9e3e (Sep 16 2014 - 11:21:38)
CPU: Altera SoCFPGA Platform BOARD: Altera SoCFPGA Cyclone5 Board
Watchdog enabled
DRAM:
This doesn't seem like a WDT problem. How much DRAM is there on that kit ? In any case, try this:
Edit arch/arm/cpu/armv7/socfpga/misc.c
Locate call to get_ram_size()
Replace this function call with the size of your DRAM in bytes.
(that is, make it "gd->ram_size = 128 * 1024 * 1024;" if you have 128MiB)
I suspect get_ram_size() on socfpga is still broken in mainline and causes this crash you observe.
btw you don't happen to have a spare CV and AV kits you could send me, so I can do the testing rounds on them too, do you ?
What board are doing your testing on? The Arrow Sockit?
DENX MCVEVK and I also have the SoCKIT here. Pavel has something funny at home, which I prefer to not know ;-)
I also see this error print:
U-Boot 2014.10-rc2-00139-g70e9e3e-dirty (Sep 16 2014 - 16:26:56)
CPU: Altera SoCFPGA Platform BOARD: Altera SoCFPGA Cyclone5 Board Watchdog enabled DRAM: 1 GiB WARNING: Caches not enabled
This needs resolving. The I/D caches are enabled too late so we get this splat. I'll cook a patch for that.
Using default environment
In: serial Out: serial Err: serial Net: dwmac.ff702000 Error: dwmac.ff702000 address not set. ^^^^^
Do you see this on your side? I can track it down...
Use => setenv ethaddr 00:ma:ca:dd:re:ss => saveenv
It's possibly because the code to read out the MAC from some storage where it usually is is likely defunct. So just set the MAC manually and your ethernet will work.

On 09/16/2014 04:46 PM, Marek Vasut wrote:
On Tuesday, September 16, 2014 at 11:35:38 PM, dinguyen wrote:
On Tue, 16 Sep 2014, Marek Vasut wrote:
On Tuesday, September 16, 2014 at 06:28:52 PM, Dinh Nguyen wrote:
On 09/16/2014 08:18 AM, Pavel Machek wrote:
Hi!
On Mon 2014-09-15 13:05:53, Marek Vasut wrote:
This entire RFC series is the first stab at making SoCFPGA usable with mainline U-Boot again. There are still some bits missing, but in general, this allows me to use mainline U-Boot on my SoCFPGA systems. The big missing part is the SPL generation, which still needs a lot of additional work.
This set contains patches for a few subsystems, bu the most part is the SoCFPGA chip support.
Most of the patches should be in good shape already, so I wonder if the RFC tag is really necessary.
Just... I earlier today I tested Marek's git tree based on this series, and it works well for me on board similar to sockit.
So
Tested-by: Pavel Machek pavel@denx.de
Thanks and best regards,
Pavel
I applied all the patches to v2014.10-rc2, and I see that the watchdog has been enabled and it's getting reset:
U-Boot 2014.10-rc2-00139-g70e9e3e (Sep 16 2014 - 11:21:38)
CPU: Altera SoCFPGA Platform BOARD: Altera SoCFPGA Cyclone5 Board
Watchdog enabled
DRAM: U-Boot SPL 2013.01.01-00019-g9cce15f (Jul 18 2013 - 13:05:43) SDRAM : Initializing MMR registers SDRAM : Calibrating PHY SEQ.C: Preparing to start memory calibration SEQ.C: CALIBRATION PASSED ALTERA DWMMC: 0 reading u-boot.img reading u-boot.img
U-Boot 2014.10-rc2-00139-g70e9e3e (Sep 16 2014 - 11:21:38)
CPU: Altera SoCFPGA Platform BOARD: Altera SoCFPGA Cyclone5 Board
Watchdog enabled
DRAM:
This doesn't seem like a WDT problem. How much DRAM is there on that kit ? In any case, try this:
Edit arch/arm/cpu/armv7/socfpga/misc.c
Locate call to get_ram_size()
Replace this function call with the size of your DRAM in bytes.
(that is, make it "gd->ram_size = 128 * 1024 * 1024;" if you have 128MiB)
I suspect get_ram_size() on socfpga is still broken in mainline and causes this crash you observe.
btw you don't happen to have a spare CV and AV kits you could send me, so I can do the testing rounds on them too, do you ?
What board are doing your testing on? The Arrow Sockit?
DENX MCVEVK and I also have the SoCKIT here. Pavel has something funny at home, which I prefer to not know ;-)
I also see this error print:
U-Boot 2014.10-rc2-00139-g70e9e3e-dirty (Sep 16 2014 - 16:26:56)
CPU: Altera SoCFPGA Platform BOARD: Altera SoCFPGA Cyclone5 Board Watchdog enabled DRAM: 1 GiB WARNING: Caches not enabled
This needs resolving. The I/D caches are enabled too late so we get this splat. I'll cook a patch for that.
Using default environment
In: serial Out: serial Err: serial Net: dwmac.ff702000 Error: dwmac.ff702000 address not set. ^^^^^
Do you see this on your side? I can track it down...
Use => setenv ethaddr 00:ma:ca:dd:re:ss => saveenv
ah yes...I added a CONFIG_ETHADDR since "saveenv" is not enabled yet.
Sorry for the noise, I was expecting "Warning: failed to set MAC address"
Dinh

On Wednesday, September 17, 2014 at 12:20:34 AM, Dinh Nguyen wrote: [...]
Using default environment
In: serial Out: serial Err: serial Net: dwmac.ff702000 Error: dwmac.ff702000 address not set. ^^^^^
Do you see this on your side? I can track it down...
Use => setenv ethaddr 00:ma:ca:dd:re:ss => saveenv
ah yes...I added a CONFIG_ETHADDR since "saveenv" is not enabled yet.
Sorry for the noise, I was expecting "Warning: failed to set MAC address"
Ah yes, feel free to post a patch ;-)
Best regards, Marek Vasut

Hi!
What board are doing your testing on? The Arrow Sockit?
I have board similar to SocKit, yes.
I also see this error print:
U-Boot 2014.10-rc2-00139-g70e9e3e-dirty (Sep 16 2014 - 16:26:56)
CPU: Altera SoCFPGA Platform BOARD: Altera SoCFPGA Cyclone5 Board Watchdog enabled DRAM: 1 GiB WARNING: Caches not enabled Using default environment
In: serial Out: serial Err: serial Net: dwmac.ff702000 Error: dwmac.ff702000 address not set. ^^^^^
Do you see this on your side? I can track it down...
i2c code that reads address from ROM was not part of the merge, so you need to either set address manually or port it from rocketboards version.
Best regards, Pavel

On Mon, 2014-09-15 at 13:05 +0200, marex@denx.de wrote:
This entire RFC series is the first stab at making SoCFPGA usable with mainline U-Boot again. There are still some bits missing, but in general, this allows me to use mainline U-Boot on my SoCFPGA systems. The big missing part is the SPL generation, which still needs a lot of additional work.
This set contains patches for a few subsystems, bu the most part is the SoCFPGA chip support.
Most of the patches should be in good shape already, so I wonder if the RFC tag is really necessary.
Charles Manning (1): tools: socfpga: Add socfpga preloader signing to mkimage
Marek Vasut (21): net: dwc: Fix cache alignment issues net: dwc: Make the cache handling less cryptic mmc: dw_mmc: Fix cache alignment issue arm: socfpga: Clean up base address file arm: socfpga: sysmgr: Clean up system manager arm: socfpga: clock: Implant order into bit definitions arm: socfpga: clock: Drop nonsense inlining from clock manager code arm: socfpga: clock: Add missing stubs into board file arm: socfpga: clock: Trim down code duplication arm: socfpga: timer: Pull the timer reload value from config file arm: socfpga: reset: Add EMAC reset functions arm: socfpga: board: Align checkboard() output arm: socfpga: reset: Add function to reset FPGA bridges arm: socfpga: sysmgr: Add FPGA bits into system manager arm: cache: Add support for write-allocate D-Cache arm: socfpga: cache: Define cacheline size arm: socfpga: cache: Enable D-Cache arm: socfpga: cache: Enable PL310 L2 cache arm: socfpga: scu: Add SCU register file arm: socfpga: nic301: Add NIC-301 GPV register file arm: socfpga: pl310: Map SDRAM to 0x0
Pavel Machek (13): net: Remove unused CONFIG_DW_SEARCH_PHY from configs net: phy: Cleanup drivers/net/phy/micrel.c mmc: dw_mmc: cleanups arm: socfpga: Complete the list of base addresses arm: socfpga: Add watchdog disable for socfpga arm: socfpga: clock: Add code to read clock configuration arm: socfpga: mmc: Pick the clock from clock manager arm: socfpga: misc: Add proper ethernet initialization arm: socfpga: misc: Add SD controller init arm: socfpga: misc: Align print_cpuinfo() output arm: socfpga: board: Correctly set ATAG position arm: socfpga: fpga: Add SoCFPGA FPGA programming interface arm: socfpga: nic301: Add NIC-301 configuration code
arch/arm/cpu/armv7/socfpga/Makefile | 3 +- arch/arm/cpu/armv7/socfpga/clock_manager.c | 218 ++++++++++++- arch/arm/cpu/armv7/socfpga/fpga_manager.c | 354 +++++++++++++++++++++ arch/arm/cpu/armv7/socfpga/misc.c | 144 ++++++++- arch/arm/cpu/armv7/socfpga/reset_manager.c | 72 +++++ arch/arm/cpu/armv7/socfpga/system_manager.c | 57 +++- arch/arm/cpu/armv7/socfpga/timer.c | 2 + arch/arm/include/asm/arch-socfpga/clock_manager.h | 209 ++++++++---- arch/arm/include/asm/arch-socfpga/fpga_manager.h | 77 +++++ arch/arm/include/asm/arch-socfpga/nic301.h | 195 ++++++++++++ arch/arm/include/asm/arch-socfpga/reset_manager.h | 6 + arch/arm/include/asm/arch-socfpga/scu.h | 23 ++ .../include/asm/arch-socfpga/socfpga_base_addrs.h | 62 +++- arch/arm/include/asm/arch-socfpga/system_manager.h | 111 +++++-- arch/arm/include/asm/system.h | 1 + arch/arm/lib/cache-cp15.c | 2 + board/altera/socfpga/pll_config.h | 3 + board/altera/socfpga/socfpga_cyclone5.c | 7 +- common/image.c | 1 + drivers/fpga/altera.c | 21 ++ drivers/mmc/dw_mmc.c | 26 +- drivers/mmc/socfpga_dw_mmc.c | 15 +- drivers/net/designware.c | 46 +-- drivers/net/phy/micrel.c | 7 +- include/altera.h | 1 + include/configs/axs101.h | 1 - include/configs/socfpga_cyclone5.h | 9 +- include/dwmmc.h | 2 +- include/image.h | 1 + tools/Makefile | 1 + tools/imagetool.c | 2 + tools/imagetool.h | 1 + tools/socfpgaimage.c | 255 +++++++++++++++ 33 files changed, 1753 insertions(+), 182 deletions(-) create mode 100644 arch/arm/cpu/armv7/socfpga/fpga_manager.c create mode 100644 arch/arm/include/asm/arch-socfpga/fpga_manager.h create mode 100644 arch/arm/include/asm/arch-socfpga/nic301.h create mode 100644 arch/arm/include/asm/arch-socfpga/scu.h create mode 100644 tools/socfpgaimage.c
Cc: Chin Liang See clsee@altera.com Cc: Dinh Nguyen dinguyen@altera.com Cc: Albert Aribaud albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com Cc: Wolfgang Denk wd@denx.de Cc: Pavel Machek pavel@denx.de Cc: Joe Hershberger joe.hershberger@gmail.com
A quick test from my side and result as below:
1. SDRAM access is working where I can read and write to few spots. :)
SOCFPGA_CYCLONE5 # md 0 00000000: 00000000 aaaaaaaa aaaaaaaa aaaaaaaa ................ SOCFPGA_CYCLONE5 # mw 0 12345678 100 SOCFPGA_CYCLONE5 # md 0 00000000: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. SOCFPGA_CYCLONE5 # md 100000 00100000: eafffffd fbff4b3f fffffffe fdff33be ....?K.......3.. SOCFPGA_CYCLONE5 # mw 100000 23456789 100 SOCFPGA_CYCLONE5 # md 100000 00100000: 23456789 23456789 23456789 23456789 .gE#.gE#.gE#.gE# SOCFPGA_CYCLONE5 #
2. Ethernet seems not working for me. But I will look into this to find out any missing pieces.
SOCFPGA_CYCLONE5 # setenv ethaddr 02:11:22:33:44:55 SOCFPGA_CYCLONE5 # dhcp Speed: 1000, full duplex BOOTP broadcast 1 BOOTP broadcast 2 BOOTP broadcast 3 BOOTP broadcast 4 BOOTP broadcast 5 BOOTP broadcast 6 BOOTP broadcast 7 BOOTP broadcast 8 BOOTP broadcast 9 BOOTP broadcast 10 BOOTP broadcast 11 BOOTP broadcast 12 BOOTP broadcast 13 BOOTP broadcast 14 BOOTP broadcast 15 BOOTP broadcast 16 BOOTP broadcast 17
Retry time exceeded; starting again
3. MMC is not enabled in SocFPGA. I recall there is a patch from Pavel. I believe its pending for v2 due to some comments.
Thanks Chin Liang

On Wednesday, September 17, 2014 at 01:29:15 PM, Chin Liang See wrote: [...]
A quick test from my side and result as below:
- SDRAM access is working where I can read and write to few spots. :)
SOCFPGA_CYCLONE5 # md 0 00000000: 00000000 aaaaaaaa aaaaaaaa aaaaaaaa ................ SOCFPGA_CYCLONE5 # mw 0 12345678 100 SOCFPGA_CYCLONE5 # md 0 00000000: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. SOCFPGA_CYCLONE5 # md 100000 00100000: eafffffd fbff4b3f fffffffe fdff33be ....?K.......3.. SOCFPGA_CYCLONE5 # mw 100000 23456789 100 SOCFPGA_CYCLONE5 # md 100000 00100000: 23456789 23456789 23456789 23456789 .gE#.gE#.gE#.gE# SOCFPGA_CYCLONE5 #
What does that mean?
- Ethernet seems not working for me.
But I will look into this to find out any missing pieces.
SOCFPGA_CYCLONE5 # setenv ethaddr 02:11:22:33:44:55 SOCFPGA_CYCLONE5 # dhcp Speed: 1000, full duplex BOOTP broadcast 1 BOOTP broadcast 2 BOOTP broadcast 3 BOOTP broadcast 4 BOOTP broadcast 5 BOOTP broadcast 6 BOOTP broadcast 7 BOOTP broadcast 8 BOOTP broadcast 9 BOOTP broadcast 10 BOOTP broadcast 11 BOOTP broadcast 12 BOOTP broadcast 13 BOOTP broadcast 14 BOOTP broadcast 15 BOOTP broadcast 16 BOOTP broadcast 17
Retry time exceeded; starting again
This is on the SoCDK, right ?
- MMC is not enabled in SocFPGA.
I recall there is a patch from Pavel. I believe its pending for v2 due to some comments.
This should be in the tree in fact. Is CONFIG_CMD_MMC defined ?

On Wed, 2014-09-17 at 13:52 +0200, marex@denx.de wrote:
On Wednesday, September 17, 2014 at 01:29:15 PM, Chin Liang See wrote: [...]
A quick test from my side and result as below:
- SDRAM access is working where I can read and write to few spots. :)
SOCFPGA_CYCLONE5 # md 0 00000000: 00000000 aaaaaaaa aaaaaaaa aaaaaaaa ................ SOCFPGA_CYCLONE5 # mw 0 12345678 100 SOCFPGA_CYCLONE5 # md 0 00000000: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. SOCFPGA_CYCLONE5 # md 100000 00100000: eafffffd fbff4b3f fffffffe fdff33be ....?K.......3.. SOCFPGA_CYCLONE5 # mw 100000 23456789 100 SOCFPGA_CYCLONE5 # md 100000 00100000: 23456789 23456789 23456789 23456789 .gE#.gE#.gE#.gE# SOCFPGA_CYCLONE5 #
What does that mean?
I recall Pavel was having issue when he is accessing 1MB of memory at 0. I believe this is gone as this new patch works well for me.
- Ethernet seems not working for me.
But I will look into this to find out any missing pieces.
SOCFPGA_CYCLONE5 # setenv ethaddr 02:11:22:33:44:55 SOCFPGA_CYCLONE5 # dhcp Speed: 1000, full duplex BOOTP broadcast 1 BOOTP broadcast 2 BOOTP broadcast 3 BOOTP broadcast 4 BOOTP broadcast 5 BOOTP broadcast 6 BOOTP broadcast 7 BOOTP broadcast 8 BOOTP broadcast 9 BOOTP broadcast 10 BOOTP broadcast 11 BOOTP broadcast 12 BOOTP broadcast 13 BOOTP broadcast 14 BOOTP broadcast 15 BOOTP broadcast 16 BOOTP broadcast 17
Retry time exceeded; starting again
This is on the SoCDK, right ?
Yup, Altera SoCDK.
- MMC is not enabled in SocFPGA.
I recall there is a patch from Pavel. I believe its pending for v2 due to some comments.
This should be in the tree in fact. Is CONFIG_CMD_MMC defined ?
I didn't see any MMC configuration at include/configs/socfpga_cyclone5 at mainline nor the new patch series. Wonder I might miss out any ACKed patch?
Thanks Chin Liang

On Wednesday, September 17, 2014 at 02:00:42 PM, Chin Liang See wrote:
On Wed, 2014-09-17 at 13:52 +0200, marex@denx.de wrote:
On Wednesday, September 17, 2014 at 01:29:15 PM, Chin Liang See wrote: [...]
A quick test from my side and result as below:
- SDRAM access is working where I can read and write to few spots. :)
SOCFPGA_CYCLONE5 # md 0 00000000: 00000000 aaaaaaaa aaaaaaaa aaaaaaaa ................ SOCFPGA_CYCLONE5 # mw 0 12345678 100 SOCFPGA_CYCLONE5 # md 0 00000000: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. SOCFPGA_CYCLONE5 # md 100000 00100000: eafffffd fbff4b3f fffffffe fdff33be ....?K.......3.. SOCFPGA_CYCLONE5 # mw 100000 23456789 100 SOCFPGA_CYCLONE5 # md 100000 00100000: 23456789 23456789 23456789 23456789 .gE#.gE#.gE#.gE# SOCFPGA_CYCLONE5 #
What does that mean?
I recall Pavel was having issue when he is accessing 1MB of memory at 0. I believe this is gone as this new patch works well for me.
Yes, the NIC301 patches solve this. Pavel confirmed this yesterday.
- Ethernet seems not working for me.
But I will look into this to find out any missing pieces.
SOCFPGA_CYCLONE5 # setenv ethaddr 02:11:22:33:44:55 SOCFPGA_CYCLONE5 # dhcp Speed: 1000, full duplex BOOTP broadcast 1 BOOTP broadcast 2 BOOTP broadcast 3 BOOTP broadcast 4 BOOTP broadcast 5 BOOTP broadcast 6 BOOTP broadcast 7 BOOTP broadcast 8 BOOTP broadcast 9 BOOTP broadcast 10 BOOTP broadcast 11 BOOTP broadcast 12 BOOTP broadcast 13 BOOTP broadcast 14 BOOTP broadcast 15 BOOTP broadcast 16 BOOTP broadcast 17
Retry time exceeded; starting again
This is on the SoCDK, right ?
Yup, Altera SoCDK.
OK
- MMC is not enabled in SocFPGA.
I recall there is a patch from Pavel. I believe its pending for v2 due to some comments.
This should be in the tree in fact. Is CONFIG_CMD_MMC defined ?
I didn't see any MMC configuration at include/configs/socfpga_cyclone5 at mainline nor the new patch series. Wonder I might miss out any ACKed patch?
Oh I see. I have this enabled in the repository here, but I didn't submit that change since it needs more work. The code is there , added in the patch
arm: socfpga: misc: Add SD controller init
The change for the SoCFPGA config file is missing though.
Best regards, Marek Vasut

Hi Marek,
On Wed, 2014-09-17 at 14:39 +0200, marex@denx.de wrote:
On Wednesday, September 17, 2014 at 02:00:42 PM, Chin Liang See wrote:
On Wed, 2014-09-17 at 13:52 +0200, marex@denx.de wrote:
On Wednesday, September 17, 2014 at 01:29:15 PM, Chin Liang See wrote:
- MMC is not enabled in SocFPGA.
I recall there is a patch from Pavel. I believe its pending for v2 due to some comments.
This should be in the tree in fact. Is CONFIG_CMD_MMC defined ?
I didn't see any MMC configuration at include/configs/socfpga_cyclone5 at mainline nor the new patch series. Wonder I might miss out any ACKed patch?
Oh I see. I have this enabled in the repository here, but I didn't submit that change since it needs more work. The code is there , added in the patch
arm: socfpga: misc: Add SD controller init
The change for the SoCFPGA config file is missing though.
Yup, I just submit the patch to add that "socfpga: Enable DWMMC for SOCFPGA". With this added, the SDMMC is working well at U-Boot. This including all the 35 patches from you. Something to cheer during the weekend :)
Here is the printout:
SOCFPGA_CYCLONE5 # fatls mmc 0:1 194168 u-boot.img 16289 socfpga.dtb 3202824 zimage
3 file(s), 0 dir(s)
SOCFPGA_CYCLONE5 # mmc read 8000 0 1
MMC read: dev # 0, block # 0, count 1 ... 1 blocks read: OK SOCFPGA_CYCLONE5 # md 8000 00008000: 00000000 00000000 00000000 00000000 ................ 00008010: 00000000 00000000 00000000 00000000 ................ 00008020: 00000000 00000000 00000000 00000000 ................ 00008030: 00000000 00000000 00000000 00000000 ................ 00008040: 00000000 00000000 00000000 00000000 ................ 00008050: 00000000 00000000 00000000 00000000 ................ 00008060: 00000000 00000000 00000000 00000000 ................ 00008070: 00000000 00000000 00000000 00000000 ................ 00008080: 00000000 00000000 00000000 00000000 ................ 00008090: 00000000 00000000 00000000 00000000 ................ 000080a0: 00000000 00000000 00000000 00000000 ................ 000080b0: 00000000 00000000 00000000 00000000 ................ 000080c0: 00000000 00000000 00000000 00000000 ................ 000080d0: 00000000 00000000 00000000 00000000 ................ 000080e0: 00000000 00000000 00000000 00000000 ................ 000080f0: 00000000 00000000 00000000 00000000 ................ SOCFPGA_CYCLONE5 # 00008100: 00000000 00000000 00000000 00000000 ................ 00008110: 00000000 00000000 00000000 00000000 ................ 00008120: 00000000 00000000 00000000 00000000 ................ 00008130: 00000000 00000000 00000000 00000000 ................ 00008140: 00000000 00000000 00000000 00000000 ................ 00008150: 00000000 00000000 00000000 00000000 ................ 00008160: 00000000 00000000 00000000 00000000 ................ 00008170: 00000000 00000000 00000000 00000000 ................ 00008180: 00000000 00000000 00000000 00000000 ................ 00008190: 00000000 00000000 00000000 00000000 ................ 000081a0: 00000000 00000000 00000000 00000000 ................ 000081b0: 00000000 00000000 479bf7be 01000000 ...........G.... 000081c0: 3c0b0001 003e093e 937e0000 00000000 ...<>.>...~..... 000081d0: 3c830a01 93bc133e 93bc0000 00000000 ...<>........... 000081e0: 3ca21401 27781d3e 93bc0001 00000000 ...<>.x'........ 000081f0: 00000000 00000000 00000000 aa550000 ..............U. SOCFPGA_CYCLONE5 #
Thanks Chin Liang
Best regards, Marek Vasut

Hi guys,
On Fri, 2014-09-19 at 04:32 -0500, Chin Liang See wrote:
Hi Marek,
On Wed, 2014-09-17 at 14:39 +0200, marex@denx.de wrote:
On Wednesday, September 17, 2014 at 02:00:42 PM, Chin Liang See wrote:
On Wed, 2014-09-17 at 13:52 +0200, marex@denx.de wrote:
On Wednesday, September 17, 2014 at 01:29:15 PM, Chin Liang See wrote:
- MMC is not enabled in SocFPGA.
I recall there is a patch from Pavel. I believe its pending for v2 due to some comments.
This should be in the tree in fact. Is CONFIG_CMD_MMC defined ?
I didn't see any MMC configuration at include/configs/socfpga_cyclone5 at mainline nor the new patch series. Wonder I might miss out any ACKed patch?
Oh I see. I have this enabled in the repository here, but I didn't submit that change since it needs more work. The code is there , added in the patch
arm: socfpga: misc: Add SD controller init
The change for the SoCFPGA config file is missing though.
Yup, I just submit the patch to add that "socfpga: Enable DWMMC for SOCFPGA". With this added, the SDMMC is working well at U-Boot. This including all the 35 patches from you. Something to cheer during the weekend :)
I just submitted a patch "socfpga: Enable SDMMC boot for SOCFPGA U-Boot". This will enable the SDMMC boot as default boot for Altera dev kit. With that, I am able to success boot till Linux 3.10 LTSi successfully :)
Thanks Chin Liang
U-Boot 2014.10-rc2-00126-g77676b6 (Sep 19 2014 - 05:28:06)
CPU: Altera SoCFPGA Platform BOARD: Altera SoCFPGA Cyclone5 Board DRAM: 1 GiB WARNING: Caches not enabled MMC: SOCFPGA DWMMC: 0 Using default environment
In: serial Out: serial Err: serial Net: dwmac.ff702000 Error: dwmac.ff702000 address not set.
Warning: Your board does not use generic board. Please read doc/README.generic-board and take action. Boards not upgraded by the late 2014 may break or be removed. Hit any key to stop autoboot: 0 reading zImage 3525736 bytes read in 196 ms (17.2 MiB/s) reading socfpga.dtb 19247 bytes read in 8 ms (2.3 MiB/s) Kernel image @ 0x007fc0 [ 0x000000 - 0x35cc68 ] ## Flattened Device Tree blob at 00000100 Booting using the fdt blob at 0x000100 Loading Device Tree to 0fff7000, end 0fffeb2e ... OK
Starting kernel ...
Booting Linux on physical CPU 0x0 Initializing cgroup subsys cpuset Linux version 3.10.31-ltsi (jdasilva@sj-interactive3) (gcc version 4.8.3 20140401 (prerelease) (crosstool-NG linaro-1.13.1-4.8-2014.04 - Linaro GCC 4.8-2014.04) ) #1 SMP Wed Sep 17 00:24:24 PDT 2014 CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=10c5387d CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache Machine: Altera SOCFPGA, model: Altera SOCFPGA Cyclone V Memory policy: ECC disabled, Data cache writealloc PERCPU: Embedded 8 pages/cpu @80f70000 s11200 r8192 d13376 u32768 Built 1 zonelists in Zone order, mobility grouping on. Total pages: 260096 Kernel command line: console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootwait PID hash table entries: 4096 (order: 2, 16384 bytes) Dentry cache hash table entries: 131072 (order: 7, 524288 bytes) Inode-cache hash table entries: 65536 (order: 6, 262144 bytes) Memory: 1024MB = 1024MB total Memory: 1031884k/1031884k available, 16692k reserved, 0K highmem Virtual kernel memory layout: vector : 0xffff0000 - 0xffff1000 ( 4 kB) fixmap : 0xfff00000 - 0xfffe0000 ( 896 kB) vmalloc : 0xc0800000 - 0xff000000 (1000 MB) lowmem : 0x80000000 - 0xc0000000 (1024 MB) modules : 0x7f000000 - 0x80000000 ( 16 MB) .text : 0x80008000 - 0x8068cab0 (6675 kB) .init : 0x8068d000 - 0x806e3bc0 ( 347 kB) .data : 0x806e4000 - 0x807204d0 ( 242 kB) .bss : 0x807204d0 - 0x80761cb4 ( 262 kB) SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=2, Nodes=1 Hierarchical RCU implementation. NR_IRQS:16 nr_irqs:16 16 sched_clock: 32 bits at 100MHz, resolution 10ns, wraps every 42949ms Console: colour dummy device 80x30 Calibrating delay loop... 1836.64 BogoMIPS (lpj=9183232) pid_max: default: 32768 minimum: 301 Mount-cache hash table entries: 512 CPU: Testing write buffer coherency: ok ftrace: allocating 17914 entries in 53 pages CPU0: thread -1, cpu 0, socket 0, mpidr 80000000 Setting up static identity map for 0x804d39c8 - 0x804d3a20 CPU1: Booted secondary processor CPU1: thread -1, cpu 1, socket 0, mpidr 80000001 Brought up 2 CPUs SMP: Total of 2 processors activated (3679.84 BogoMIPS). CPU: All CPU(s) started in SVC mode. devtmpfs: initialized NET: Registered protocol family 16 fpga bridge driver DMA: preallocated 256 KiB pool for atomic coherent allocations L310 cache controller enabled l2x0: 8 ways, CACHE_ID 0x410030c9, AUX_CTRL 0x32460000, Cache size: 524288 B syscon fffef000.l2-cache: regmap [mem 0xfffef000-0xfffeffff] registered syscon ffd05000.rstmgr: regmap [mem 0xffd05000-0xffd05fff] registered syscon ffc25000.sdrctl: regmap [mem 0xffc25000-0xffc25fff] registered syscon ff800000.l3regs: regmap [mem 0xff800000-0xff800fff] registered syscon ffd08000.sysmgr: regmap [mem 0xffd08000-0xffd0bfff] registered hw-breakpoint: found 5 (+1 reserved) breakpoint and 1 watchpoint registers. hw-breakpoint: maximum watchpoint size is 4 bytes. altera_hps2fpga_bridge fpgabridge.2: fpga bridge [hps2fpga] registered as device hps2fpga altera_hps2fpga_bridge fpgabridge.2: init-val not specified altera_hps2fpga_bridge fpgabridge.3: fpga bridge [lshps2fpga] registered as device lwhps2fpga altera_hps2fpga_bridge fpgabridge.3: init-val not specified altera_hps2fpga_bridge fpgabridge.4: fpga bridge [fpga2hps] registered as device fpga2hps altera_hps2fpga_bridge fpgabridge.4: init-val not specified bio: create slab <bio-0> at 0 FPGA Mangager framework driver SCSI subsystem initialized usbcore: registered new interface driver usbfs usbcore: registered new interface driver hub usbcore: registered new device driver usb lcd-comm 0-0028: LCD driver initialized pps_core: LinuxPPS API ver. 1 registered pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti giometti@linux.it PTP clock support registered Switching to clocksource timer0 NET: Registered protocol family 2 TCP established hash table entries: 8192 (order: 4, 65536 bytes) TCP bind hash table entries: 8192 (order: 4, 65536 bytes) TCP: Hash tables configured (established 8192 bind 8192) TCP: reno registered UDP hash table entries: 512 (order: 2, 16384 bytes) UDP-Lite hash table entries: 512 (order: 2, 16384 bytes) NET: Registered protocol family 1 RPC: Registered named UNIX socket transport module. RPC: Registered udp transport module. RPC: Registered tcp transport module. RPC: Registered tcp NFSv4.1 backchannel transport module. hw perfevents: enabled with ARMv7 Cortex-A9 PMU driver, 7 counters available arm-pmu arm-pmu: PMU:CTI successfully enabled for 2 cores NFS: Registering the id_resolver key type Key type id_resolver registered Key type id_legacy registered NTFS driver 2.1.30 [Flags: R/W]. jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc. msgmni has been set to 2015 io scheduler noop registered (default) usbcore: registered new interface driver udlfb Serial: 8250/16550 driver, 2 ports, IRQ sharing disabled ffc02000.serial0: ttyS0 at MMIO 0xffc02000 (irq = 194) is a 16550A console [ttyS0] enabled altera_fpga_manager ff706000.fpgamgr: fpga manager [Altera FPGA Manager] registered as minor 0 brd: module loaded at24 0-0051: 4096 byte 24c32 EEPROM, writable, 32 bytes/write cadence-qspi ff705000.spi: DMA NOT enabled cadence-qspi ff705000.spi: master is unqueued, this is deprecated m25p80 spi2.0: found n25q512a, expected n25q00 m25p80 spi2.0: n25q512a (65536 Kbytes) 2 ofpart partitions found on MTD device spi2.0 Creating 2 MTD partitions on "spi2.0": 0x000000000000-0x000000800000 : "Flash 0 Raw Data" 0x000000800000-0x000008000000 : "Flash 0 jffs2 Filesystem" mtd: partition "Flash 0 jffs2 Filesystem" extends beyond the end of device "spi2.0" -- size truncated to 0x3800000 cadence-qspi ff705000.spi: Cadence QSPI controller driver dw_spi_mmio fff00000.spi: master is unqueued, this is deprecated CAN device driver interface c_can_platform ffc00000.d_can: invalid resource c_can_platform ffc00000.d_can: control memory is not used for raminit c_can_platform ffc00000.d_can: c_can_platform device registered (regs=c08e4000, irq=163) stmmac - user ID: 0x10, Synopsys ID: 0x37 Ring mode enabled DMA HW capability register supported Enhanced/Alternate descriptors Enabled extended descriptors RX Checksum Offload Engine supported (type 2) TX Checksum insertion supported Enable RX Mitigation via HW Watchdog Timer libphy: stmmac: probed eth0: PHY ID 00221611 at 4 IRQ POLL (stmmac-1:04) active dwc2 ffb40000.usb: unable to find phy dwc2 ffb40000.usb: EPs:15 dwc2 ffb40000.usb: dedicated fifos dwc2 ffb40000.usb: 2560 invalid for host_rx_fifo_size. Check HW configuration. dwc2 ffb40000.usb: DWC OTG Controller dwc2 ffb40000.usb: new USB bus registered, assigned bus number 1 dwc2 ffb40000.usb: irq 160, io mem 0x00000000 usb usb1: New USB device found, idVendor=1d6b, idProduct=0002 usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1 usb usb1: Product: DWC OTG Controller usb usb1: Manufacturer: Linux 3.10.31-ltsi dwc2_hsotg usb usb1: SerialNumber: ffb40000.usb hub 1-0:1.0: USB hub found hub 1-0:1.0: 1 port detected usbcore: registered new interface driver usb-storage mousedev: PS/2 mouse device common for all mice rtc-ds1307 0-0068: SET TIME! rtc-ds1307 0-0068: rtc core: registered ds1339 as rtc0 i2c /dev entries driver Synopsys Designware Multimedia Card Interface Driver dwmmc_socfpga ff704000.dwmmc0: couldn't determine pwr-en, assuming pwr-en = 0 dwmmc_socfpga ff704000.dwmmc0: Using internal DMA controller. dwmmc_socfpga ff704000.dwmmc0: Version ID is 240a dwmmc_socfpga ff704000.dwmmc0: DW MMC controller at irq 171, 32 bit host data width, 1024 deep fifo mmc_host mmc0: Bus speed (slot 0) = 50000000Hz (slot req 400000Hz, actual 396825HZ div = 63) dwmmc_socfpga ff704000.dwmmc0: 1 slots initialized ledtrig-cpu: registered to indicate activity on CPUs usbcore: registered new interface driver usbhid usbhid: USB HID core driver oprofile: using arm/armv7-ca9 TCP: cubic registered NET: Registered protocol family 10 sit: IPv6 over IPv4 tunneling driver NET: Registered protocol family 17 NET: Registered protocol family 15 can: controller area network core (rev 20120528 abi 9) NET: Registered protocol family 29 can: raw protocol (rev 20120528) can: broadcast manager protocol (rev 20120528 t) can: netlink gateway (rev 20130117) max_hops=1 8021q: 802.1Q VLAN Support v1.8 Key type dns_resolver registered VFP support v0.3: implementor 41 architecture 3 part 30 variant 9 rev 4 ThumbEE CPU extension supported. Registering SWP/SWPB emulation handler Waiting for root device /dev/mmcblk0p2... mmc_host mmc0: Bus speed (slot 0) = 50000000Hz (slot req 50000000Hz, actual 50000000HZ div = 0) mmc0: new high speed SDHC card at address 0007 mmcblk0: mmc0:0007 SD4GB 3.70 GiB mmcblk0: p1 p2 p3 EXT2-fs (mmcblk0p2): warning: mounting unchecked fs, running e2fsck is recommended VFS: Mounted root (ext2 filesystem) on device 179:2. devtmpfs: mounted Freeing unused kernel memory: 344K (8068d000 - 806e3000) Initializing random number generator... done. Starting network...
Welcome to Altera SOCFPGA5XS1 Altera_SOCFPGA5XS1 login: root # cat /proc/cpuinfo processor : 0 model name : ARMv7 Processor rev 0 (v7l) BogoMIPS : 1836.64 Features : swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls lpae CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x3 CPU part : 0xc09 CPU revision : 0
processor : 1 model name : ARMv7 Processor rev 0 (v7l) BogoMIPS : 1843.20 Features : swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls lpae CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x3 CPU part : 0xc09 CPU revision : 0
Hardware : Altera SOCFPGA Revision : 0000 Serial : 0000000000000000 #

On Friday, September 19, 2014 at 12:36:41 PM, Chin Liang See wrote:
Hi guys,
On Fri, 2014-09-19 at 04:32 -0500, Chin Liang See wrote:
Hi Marek,
On Wed, 2014-09-17 at 14:39 +0200, marex@denx.de wrote:
On Wednesday, September 17, 2014 at 02:00:42 PM, Chin Liang See wrote:
On Wed, 2014-09-17 at 13:52 +0200, marex@denx.de wrote:
On Wednesday, September 17, 2014 at 01:29:15 PM, Chin Liang See wrote:
- MMC is not enabled in SocFPGA.
I recall there is a patch from Pavel. I believe its pending for v2 due to some comments.
This should be in the tree in fact. Is CONFIG_CMD_MMC defined ?
I didn't see any MMC configuration at include/configs/socfpga_cyclone5 at mainline nor the new patch series. Wonder I might miss out any ACKed patch?
Oh I see. I have this enabled in the repository here, but I didn't submit that change since it needs more work. The code is there , added in the patch
arm: socfpga: misc: Add SD controller init
The change for the SoCFPGA config file is missing though.
Yup, I just submit the patch to add that "socfpga: Enable DWMMC for SOCFPGA". With this added, the SDMMC is working well at U-Boot. This including all the 35 patches from you. Something to cheer during the weekend :)
I just submitted a patch "socfpga: Enable SDMMC boot for SOCFPGA U-Boot". This will enable the SDMMC boot as default boot for Altera dev kit. With that, I am able to success boot till Linux 3.10 LTSi successfully :)
We still have a few bugs in the DWMMC driver when using eMMC card, but that's a problem with a particular eMMC card I think. I'll have to look into it.
I will pick your patch and re-post the entire bulk today or tomorrow with the suggested changes.
Best regards, Marek Vasut
participants (7)
-
Chin Liang See
-
dinguyen
-
Dinh Nguyen
-
Marek Vasut
-
Michal Simek
-
Pavel Machek
-
Wolfgang Denk