From 3aed749c32686db50ed8bff32206ecf867300228 Mon Sep 17 00:00:00 2001 From: Steffen Trumtrar Date: Tue, 31 Jul 2018 12:44:24 +0200 Subject: mci: dw_mmc: remove device_d pointer The pointer to the struct device_d *dev is also saved to the struct mci_host. Get rid of it. Signed-off-by: Steffen Trumtrar Signed-off-by: Sascha Hauer --- drivers/mci/dw_mmc.c | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/drivers/mci/dw_mmc.c b/drivers/mci/dw_mmc.c index 27c36a6377..0dd4c1f441 100644 --- a/drivers/mci/dw_mmc.c +++ b/drivers/mci/dw_mmc.c @@ -147,7 +147,6 @@ struct dwmci_host { struct mci_host mci; - struct device_d *dev; struct clk *clk_biu, *clk_ciu; void *ioaddr; unsigned int fifo_size_bytes; @@ -271,7 +270,7 @@ static int dwmci_prepare_data_dma(struct dwmci_host *host, desc->addr = start_addr + (i * PAGE_SIZE); desc->next_addr = (uint32_t)(desc + 1); - dev_dbg(host->dev, "desc@ 0x%p 0x%08x 0x%08x 0x%08x 0x%08x\n", + dev_dbg(host->mci.hw_dev, "desc@ 0x%p 0x%08x 0x%08x 0x%08x 0x%08x\n", desc, flags, cnt, desc->addr, desc->next_addr); if (blk_cnt < 8) break; @@ -331,7 +330,7 @@ static int dwmci_read_data_pio(struct dwmci_host *host, struct mci_data *data) status = dwmci_readl(host, DWMCI_STATUS); } if (!timeout) { - dev_err(host->dev, "%s: FIFO underflow timeout\n", + dev_err(host->mci.hw_dev, "%s: FIFO underflow timeout\n", __func__); break; } @@ -360,7 +359,7 @@ static int dwmci_write_data_pio(struct dwmci_host *host, struct mci_data *data) status = dwmci_readl(host, DWMCI_STATUS); } if (!timeout) { - dev_err(host->dev, "%s: FIFO overflow timeout\n", + dev_err(host->mci.hw_dev, "%s: FIFO overflow timeout\n", __func__); break; } @@ -378,7 +377,7 @@ static int dwmci_write_data_pio(struct dwmci_host *host, struct mci_data *data) status = dwmci_readl(host, DWMCI_STATUS); } if (!timeout) { - dev_err(host->dev, "%s: FIFO flush timeout\n", + dev_err(host->mci.hw_dev, "%s: FIFO flush timeout\n", __func__); return -EIO; } @@ -403,7 +402,7 @@ dwmci_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data) break; if (is_timeout(start, 100 * MSECOND)) { - dev_dbg(host->dev, "Timeout on data busy\n"); + dev_dbg(host->mci.hw_dev, "Timeout on data busy\n"); return -ETIMEDOUT; } } @@ -449,7 +448,7 @@ dwmci_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data) flags |= (cmd->cmdidx | DWMCI_CMD_START | DWMCI_CMD_USE_HOLD_REG); - dev_dbg(host->dev, "Sending CMD%d\n", cmd->cmdidx); + dev_dbg(host->mci.hw_dev, "Sending CMD%d\n", cmd->cmdidx); dwmci_writel(host, DWMCI_CMD, flags); @@ -462,16 +461,16 @@ dwmci_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data) break; } if (is_timeout(start, 100 * MSECOND)) { - dev_dbg(host->dev, "Send command timeout..\n"); + dev_dbg(host->mci.hw_dev, "Send command timeout..\n"); return -ETIMEDOUT; } } if (mask & DWMCI_INTMSK_RTO) { - dev_dbg(host->dev, "Response Timeout..\n"); + dev_dbg(host->mci.hw_dev, "Response Timeout..\n"); return -ETIMEDOUT; } else if (mask & DWMCI_INTMSK_RE) { - dev_dbg(host->dev, "Response Error..\n"); + dev_dbg(host->mci.hw_dev, "Response Error..\n"); return -EIO; } @@ -492,17 +491,17 @@ dwmci_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data) mask = dwmci_readl(host, DWMCI_RINTSTS); if (mask & (DWMCI_DATA_ERR)) { - dev_dbg(host->dev, "DATA ERROR!\n"); + dev_dbg(host->mci.hw_dev, "DATA ERROR!\n"); return -EIO; } if (!dwmci_use_pio(host) && (mask & DWMCI_DATA_TOUT)) { - dev_dbg(host->dev, "DATA TIMEOUT!\n"); + dev_dbg(host->mci.hw_dev, "DATA TIMEOUT!\n"); return -EIO; } if (is_timeout(start, SECOND * 10)) { - dev_dbg(host->dev, "Data timeout\n"); + dev_dbg(host->mci.hw_dev, "Data timeout\n"); return -ETIMEDOUT; } @@ -552,7 +551,7 @@ static int dwmci_send_cmd(struct dwmci_host *host, u32 cmd, u32 arg) return 0; if (is_timeout(start, 100 * MSECOND)) { - dev_err(host->dev, "TIMEOUT error!!\n"); + dev_err(host->mci.hw_dev, "TIMEOUT error!!\n"); return -ETIMEDOUT; } } @@ -590,7 +589,7 @@ static void dwmci_set_ios(struct mci_host *mci, struct mci_ios *ios) struct dwmci_host *host = to_dwmci_host(mci); uint32_t ctype; - dev_dbg(host->dev, "Buswidth = %d, clock: %d\n", ios->bus_width, ios->clock); + dev_dbg(host->mci.hw_dev, "Buswidth = %d, clock: %d\n", ios->bus_width, ios->clock); if (ios->clock) dwmci_setup_bus(host, ios->clock); @@ -623,7 +622,7 @@ static int dwmci_init(struct mci_host *mci, struct device_d *dev) dwmci_writel(host, DWMCI_PWREN, host->pwren_value); if (dwmci_wait_reset(host, DWMCI_RESET_ALL)) { - dev_err(host->dev, "reset failed\n"); + dev_err(host->mci.hw_dev, "reset failed\n"); return -EIO; } @@ -647,10 +646,10 @@ static int dwmci_init(struct mci_host *mci, struct device_d *dev) /* * If fifo-depth property is set, use this value */ - if (!of_property_read_u32(host->dev->device_node, + if (!of_property_read_u32(host->mci.hw_dev->device_node, "fifo-depth", &fifo_size)) { host->fifo_size_bytes = fifo_size; - dev_dbg(host->dev, "Using fifo-depth=%u\n", + dev_dbg(host->mci.hw_dev, "Using fifo-depth=%u\n", host->fifo_size_bytes); } @@ -692,7 +691,6 @@ static int dw_mmc_probe(struct device_d *dev) clk_enable(host->clk_biu); clk_enable(host->clk_ciu); - host->dev = dev; iores = dev_request_mem_resource(dev, 0); if (IS_ERR(iores)) return PTR_ERR(iores); -- cgit v1.2.3 From a4cfc34a726b0caa138876a11f1056bc834dfc4b Mon Sep 17 00:00:00 2001 From: Steffen Trumtrar Date: Tue, 31 Jul 2018 12:44:25 +0200 Subject: mci: dw_mmc: convert to BIT() macro Signed-off-by: Steffen Trumtrar Signed-off-by: Sascha Hauer --- drivers/mci/dw_mmc.c | 99 ++++++++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 49 deletions(-) diff --git a/drivers/mci/dw_mmc.c b/drivers/mci/dw_mmc.c index 0dd4c1f441..473942cbe0 100644 --- a/drivers/mci/dw_mmc.c +++ b/drivers/mci/dw_mmc.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -70,22 +71,22 @@ #define DWMCI_DATA 0x200 /* Interrupt Mask register */ -#define DWMCI_INTMSK_ALL 0xffffffff -#define DWMCI_INTMSK_RE (1 << 1) -#define DWMCI_INTMSK_CDONE (1 << 2) -#define DWMCI_INTMSK_DTO (1 << 3) -#define DWMCI_INTMSK_TXDR (1 << 4) -#define DWMCI_INTMSK_RXDR (1 << 5) -#define DWMCI_INTMSK_RCRC (1 << 6) -#define DWMCI_INTMSK_DCRC (1 << 7) -#define DWMCI_INTMSK_RTO (1 << 8) -#define DWMCI_INTMSK_DRTO (1 << 9) -#define DWMCI_INTMSK_HTO (1 << 10) -#define DWMCI_INTMSK_FRUN (1 << 11) -#define DWMCI_INTMSK_HLE (1 << 12) -#define DWMCI_INTMSK_SBE (1 << 13) -#define DWMCI_INTMSK_ACD (1 << 14) -#define DWMCI_INTMSK_EBE (1 << 15) +#define DWMCI_INTMSK_ALL 0xffffffff +#define DWMCI_INTMSK_RE BIT(1) +#define DWMCI_INTMSK_CDONE BIT(2) +#define DWMCI_INTMSK_DTO BIT(3) +#define DWMCI_INTMSK_TXDR BIT(4) +#define DWMCI_INTMSK_RXDR BIT(5) +#define DWMCI_INTMSK_RCRC BIT(6) +#define DWMCI_INTMSK_DCRC BIT(7) +#define DWMCI_INTMSK_RTO BIT(8) +#define DWMCI_INTMSK_DRTO BIT(9) +#define DWMCI_INTMSK_HTO BIT(10) +#define DWMCI_INTMSK_FRUN BIT(11) +#define DWMCI_INTMSK_HLE BIT(12) +#define DWMCI_INTMSK_SBE BIT(13) +#define DWMCI_INTMSK_ACD BIT(14) +#define DWMCI_INTMSK_EBE BIT(15) /* Raw interrupt Register */ #define DWMCI_DATA_ERR (DWMCI_INTMSK_EBE | DWMCI_INTMSK_SBE | DWMCI_INTMSK_HLE |\ @@ -93,41 +94,41 @@ #define DWMCI_DATA_TOUT (DWMCI_INTMSK_HTO | DWMCI_INTMSK_DRTO) /* CTRL register */ -#define DWMCI_CTRL_RESET (1 << 0) -#define DWMCI_CTRL_FIFO_RESET (1 << 1) -#define DWMCI_CTRL_DMA_RESET (1 << 2) -#define DWMCI_DMA_EN (1 << 5) -#define DWMCI_CTRL_SEND_AS_CCSD (1 << 10) -#define DWMCI_IDMAC_EN (1 << 25) -#define DWMCI_RESET_ALL (DWMCI_CTRL_RESET | DWMCI_CTRL_FIFO_RESET |\ +#define DWMCI_CTRL_RESET BIT(0) +#define DWMCI_CTRL_FIFO_RESET BIT(1) +#define DWMCI_CTRL_DMA_RESET BIT(2) +#define DWMCI_DMA_EN BIT(5) +#define DWMCI_CTRL_SEND_AS_CCSD BIT(10) +#define DWMCI_IDMAC_EN BIT(25) +#define DWMCI_RESET_ALL (DWMCI_CTRL_RESET | DWMCI_CTRL_FIFO_RESET | \ DWMCI_CTRL_DMA_RESET) /* CMD register */ -#define DWMCI_CMD_RESP_EXP (1 << 6) -#define DWMCI_CMD_RESP_LENGTH (1 << 7) -#define DWMCI_CMD_CHECK_CRC (1 << 8) -#define DWMCI_CMD_DATA_EXP (1 << 9) -#define DWMCI_CMD_RW (1 << 10) -#define DWMCI_CMD_SEND_STOP (1 << 12) -#define DWMCI_CMD_ABORT_STOP (1 << 14) -#define DWMCI_CMD_PRV_DAT_WAIT (1 << 13) -#define DWMCI_CMD_UPD_CLK (1 << 21) -#define DWMCI_CMD_USE_HOLD_REG (1 << 29) -#define DWMCI_CMD_START (1 << 31) +#define DWMCI_CMD_RESP_EXP BIT(6) +#define DWMCI_CMD_RESP_LENGTH BIT(7) +#define DWMCI_CMD_CHECK_CRC BIT(8) +#define DWMCI_CMD_DATA_EXP BIT(9) +#define DWMCI_CMD_RW BIT(10) +#define DWMCI_CMD_SEND_STOP BIT(12) +#define DWMCI_CMD_ABORT_STOP BIT(14) +#define DWMCI_CMD_PRV_DAT_WAIT BIT(13) +#define DWMCI_CMD_UPD_CLK BIT(21) +#define DWMCI_CMD_USE_HOLD_REG BIT(29) +#define DWMCI_CMD_START BIT(31) /* CLKENA register */ -#define DWMCI_CLKEN_ENABLE (1 << 0) -#define DWMCI_CLKEN_LOW_PWR (1 << 16) +#define DWMCI_CLKEN_ENABLE BIT(0) +#define DWMCI_CLKEN_LOW_PWR BIT(16) /* Card-type register */ -#define DWMCI_CTYPE_1BIT 0 -#define DWMCI_CTYPE_4BIT (1 << 0) -#define DWMCI_CTYPE_8BIT (1 << 16) +#define DWMCI_CTYPE_1BIT 0 +#define DWMCI_CTYPE_4BIT BIT(0) +#define DWMCI_CTYPE_8BIT BIT(16) /* Status Register */ -#define DWMCI_STATUS_FIFO_EMPTY (1 << 2) -#define DWMCI_STATUS_FIFO_FULL (1 << 3) -#define DWMCI_STATUS_BUSY (1 << 9) +#define DWMCI_STATUS_FIFO_EMPTY BIT(2) +#define DWMCI_STATUS_FIFO_FULL BIT(3) +#define DWMCI_STATUS_BUSY BIT(9) /* FIFOTH Register */ #define DWMCI_FIFOTH_MSIZE(x) ((x) << 28) @@ -135,15 +136,15 @@ #define DWMCI_FIFOTH_TX_WMARK(x) (x) #define DWMCI_FIFOTH_FIFO_DEPTH(x) ((((x) >> 16) & 0x3ff) + 1) -#define DWMCI_IDMAC_OWN (1 << 31) -#define DWMCI_IDMAC_CH (1 << 4) -#define DWMCI_IDMAC_FS (1 << 3) -#define DWMCI_IDMAC_LD (1 << 2) +#define DWMCI_IDMAC_OWN BIT(31) +#define DWMCI_IDMAC_CH BIT(4) +#define DWMCI_IDMAC_FS BIT(3) +#define DWMCI_IDMAC_LD BIT(2) /* Bus Mode Register */ -#define DWMCI_BMOD_IDMAC_RESET (1 << 0) -#define DWMCI_BMOD_IDMAC_FB (1 << 1) -#define DWMCI_BMOD_IDMAC_EN (1 << 7) +#define DWMCI_BMOD_IDMAC_RESET BIT(0) +#define DWMCI_BMOD_IDMAC_FB BIT(1) +#define DWMCI_BMOD_IDMAC_EN BIT(7) struct dwmci_host { struct mci_host mci; -- cgit v1.2.3 From 4ae6397dc15d2025fd5fa890fda58e141bc46f1b Mon Sep 17 00:00:00 2001 From: Steffen Trumtrar Date: Tue, 31 Jul 2018 12:44:26 +0200 Subject: mci: dw: move defines to headerfile Signed-off-by: Steffen Trumtrar Signed-off-by: Sascha Hauer --- drivers/mci/dw_mmc.c | 115 +----------------------------------------- drivers/mci/dw_mmc.h | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+), 114 deletions(-) create mode 100644 drivers/mci/dw_mmc.h diff --git a/drivers/mci/dw_mmc.c b/drivers/mci/dw_mmc.c index 473942cbe0..e4c550c3ed 100644 --- a/drivers/mci/dw_mmc.c +++ b/drivers/mci/dw_mmc.c @@ -30,121 +30,8 @@ #include #include #include +#include "dw_mmc.h" -#define DWMCI_CTRL 0x000 -#define DWMCI_PWREN 0x004 -#define DWMCI_CLKDIV 0x008 -#define DWMCI_CLKSRC 0x00C -#define DWMCI_CLKENA 0x010 -#define DWMCI_TMOUT 0x014 -#define DWMCI_CTYPE 0x018 -#define DWMCI_BLKSIZ 0x01C -#define DWMCI_BYTCNT 0x020 -#define DWMCI_INTMASK 0x024 -#define DWMCI_CMDARG 0x028 -#define DWMCI_CMD 0x02C -#define DWMCI_RESP0 0x030 -#define DWMCI_RESP1 0x034 -#define DWMCI_RESP2 0x038 -#define DWMCI_RESP3 0x03C -#define DWMCI_MINTSTS 0x040 -#define DWMCI_RINTSTS 0x044 -#define DWMCI_STATUS 0x048 -#define DWMCI_FIFOTH 0x04C -#define DWMCI_CDETECT 0x050 -#define DWMCI_WRTPRT 0x054 -#define DWMCI_GPIO 0x058 -#define DWMCI_TCMCNT 0x05C -#define DWMCI_TBBCNT 0x060 -#define DWMCI_DEBNCE 0x064 -#define DWMCI_USRID 0x068 -#define DWMCI_VERID 0x06C -#define DWMCI_HCON 0x070 -#define DWMCI_UHS_REG 0x074 -#define DWMCI_BMOD 0x080 -#define DWMCI_PLDMND 0x084 -#define DWMCI_DBADDR 0x088 -#define DWMCI_IDSTS 0x08C -#define DWMCI_IDINTEN 0x090 -#define DWMCI_DSCADDR 0x094 -#define DWMCI_BUFADDR 0x098 -#define DWMCI_DATA 0x200 - -/* Interrupt Mask register */ -#define DWMCI_INTMSK_ALL 0xffffffff -#define DWMCI_INTMSK_RE BIT(1) -#define DWMCI_INTMSK_CDONE BIT(2) -#define DWMCI_INTMSK_DTO BIT(3) -#define DWMCI_INTMSK_TXDR BIT(4) -#define DWMCI_INTMSK_RXDR BIT(5) -#define DWMCI_INTMSK_RCRC BIT(6) -#define DWMCI_INTMSK_DCRC BIT(7) -#define DWMCI_INTMSK_RTO BIT(8) -#define DWMCI_INTMSK_DRTO BIT(9) -#define DWMCI_INTMSK_HTO BIT(10) -#define DWMCI_INTMSK_FRUN BIT(11) -#define DWMCI_INTMSK_HLE BIT(12) -#define DWMCI_INTMSK_SBE BIT(13) -#define DWMCI_INTMSK_ACD BIT(14) -#define DWMCI_INTMSK_EBE BIT(15) - -/* Raw interrupt Register */ -#define DWMCI_DATA_ERR (DWMCI_INTMSK_EBE | DWMCI_INTMSK_SBE | DWMCI_INTMSK_HLE |\ - DWMCI_INTMSK_FRUN | DWMCI_INTMSK_DCRC) -#define DWMCI_DATA_TOUT (DWMCI_INTMSK_HTO | DWMCI_INTMSK_DRTO) - -/* CTRL register */ -#define DWMCI_CTRL_RESET BIT(0) -#define DWMCI_CTRL_FIFO_RESET BIT(1) -#define DWMCI_CTRL_DMA_RESET BIT(2) -#define DWMCI_DMA_EN BIT(5) -#define DWMCI_CTRL_SEND_AS_CCSD BIT(10) -#define DWMCI_IDMAC_EN BIT(25) -#define DWMCI_RESET_ALL (DWMCI_CTRL_RESET | DWMCI_CTRL_FIFO_RESET | \ - DWMCI_CTRL_DMA_RESET) - -/* CMD register */ -#define DWMCI_CMD_RESP_EXP BIT(6) -#define DWMCI_CMD_RESP_LENGTH BIT(7) -#define DWMCI_CMD_CHECK_CRC BIT(8) -#define DWMCI_CMD_DATA_EXP BIT(9) -#define DWMCI_CMD_RW BIT(10) -#define DWMCI_CMD_SEND_STOP BIT(12) -#define DWMCI_CMD_ABORT_STOP BIT(14) -#define DWMCI_CMD_PRV_DAT_WAIT BIT(13) -#define DWMCI_CMD_UPD_CLK BIT(21) -#define DWMCI_CMD_USE_HOLD_REG BIT(29) -#define DWMCI_CMD_START BIT(31) - -/* CLKENA register */ -#define DWMCI_CLKEN_ENABLE BIT(0) -#define DWMCI_CLKEN_LOW_PWR BIT(16) - -/* Card-type register */ -#define DWMCI_CTYPE_1BIT 0 -#define DWMCI_CTYPE_4BIT BIT(0) -#define DWMCI_CTYPE_8BIT BIT(16) - -/* Status Register */ -#define DWMCI_STATUS_FIFO_EMPTY BIT(2) -#define DWMCI_STATUS_FIFO_FULL BIT(3) -#define DWMCI_STATUS_BUSY BIT(9) - -/* FIFOTH Register */ -#define DWMCI_FIFOTH_MSIZE(x) ((x) << 28) -#define DWMCI_FIFOTH_RX_WMARK(x) ((x) << 16) -#define DWMCI_FIFOTH_TX_WMARK(x) (x) -#define DWMCI_FIFOTH_FIFO_DEPTH(x) ((((x) >> 16) & 0x3ff) + 1) - -#define DWMCI_IDMAC_OWN BIT(31) -#define DWMCI_IDMAC_CH BIT(4) -#define DWMCI_IDMAC_FS BIT(3) -#define DWMCI_IDMAC_LD BIT(2) - -/* Bus Mode Register */ -#define DWMCI_BMOD_IDMAC_RESET BIT(0) -#define DWMCI_BMOD_IDMAC_FB BIT(1) -#define DWMCI_BMOD_IDMAC_EN BIT(7) struct dwmci_host { struct mci_host mci; diff --git a/drivers/mci/dw_mmc.h b/drivers/mci/dw_mmc.h new file mode 100644 index 0000000000..23b0f0fe26 --- /dev/null +++ b/drivers/mci/dw_mmc.h @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2013 Altera Corporation + * + * (C) Copyright 2012 SAMSUNG Electronics + * Jaehoon Chung + * Rajeshawari Shinde + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __DW_MMC_H__ +#define __DW_MMC_H__ + +#include + +#define DWMCI_CTRL 0x000 +#define DWMCI_PWREN 0x004 +#define DWMCI_CLKDIV 0x008 +#define DWMCI_CLKSRC 0x00C +#define DWMCI_CLKENA 0x010 +#define DWMCI_TMOUT 0x014 +#define DWMCI_CTYPE 0x018 +#define DWMCI_BLKSIZ 0x01C +#define DWMCI_BYTCNT 0x020 +#define DWMCI_INTMASK 0x024 +#define DWMCI_CMDARG 0x028 +#define DWMCI_CMD 0x02C +#define DWMCI_RESP0 0x030 +#define DWMCI_RESP1 0x034 +#define DWMCI_RESP2 0x038 +#define DWMCI_RESP3 0x03C +#define DWMCI_MINTSTS 0x040 +#define DWMCI_RINTSTS 0x044 +#define DWMCI_STATUS 0x048 +#define DWMCI_FIFOTH 0x04C +#define DWMCI_CDETECT 0x050 +#define DWMCI_WRTPRT 0x054 +#define DWMCI_GPIO 0x058 +#define DWMCI_TCMCNT 0x05C +#define DWMCI_TBBCNT 0x060 +#define DWMCI_DEBNCE 0x064 +#define DWMCI_USRID 0x068 +#define DWMCI_VERID 0x06C +#define DWMCI_HCON 0x070 +#define DWMCI_UHS_REG 0x074 +#define DWMCI_BMOD 0x080 +#define DWMCI_PLDMND 0x084 +#define DWMCI_DBADDR 0x088 +#define DWMCI_IDSTS 0x08C +#define DWMCI_IDINTEN 0x090 +#define DWMCI_DSCADDR 0x094 +#define DWMCI_BUFADDR 0x098 +#define DWMCI_DATA 0x200 + +/* Interrupt Mask register */ +#define DWMCI_INTMSK_ALL 0xffffffff +#define DWMCI_INTMSK_RE BIT(1) +#define DWMCI_INTMSK_CDONE BIT(2) +#define DWMCI_INTMSK_DTO BIT(3) +#define DWMCI_INTMSK_TXDR BIT(4) +#define DWMCI_INTMSK_RXDR BIT(5) +#define DWMCI_INTMSK_RCRC BIT(6) +#define DWMCI_INTMSK_DCRC BIT(7) +#define DWMCI_INTMSK_RTO BIT(8) +#define DWMCI_INTMSK_DRTO BIT(9) +#define DWMCI_INTMSK_HTO BIT(10) +#define DWMCI_INTMSK_FRUN BIT(11) +#define DWMCI_INTMSK_HLE BIT(12) +#define DWMCI_INTMSK_SBE BIT(13) +#define DWMCI_INTMSK_ACD BIT(14) +#define DWMCI_INTMSK_EBE BIT(15) + +/* Raw interrupt Register */ +#define DWMCI_DATA_ERR (DWMCI_INTMSK_EBE | DWMCI_INTMSK_SBE | DWMCI_INTMSK_HLE |\ + DWMCI_INTMSK_FRUN | DWMCI_INTMSK_DCRC) +#define DWMCI_DATA_TOUT (DWMCI_INTMSK_HTO | DWMCI_INTMSK_DRTO) + +/* CTRL register */ +#define DWMCI_CTRL_RESET BIT(0) +#define DWMCI_CTRL_FIFO_RESET BIT(1) +#define DWMCI_CTRL_DMA_RESET BIT(2) +#define DWMCI_DMA_EN BIT(5) +#define DWMCI_CTRL_SEND_AS_CCSD BIT(10) +#define DWMCI_IDMAC_EN BIT(25) +#define DWMCI_RESET_ALL (DWMCI_CTRL_RESET | DWMCI_CTRL_FIFO_RESET | \ + DWMCI_CTRL_DMA_RESET) + +/* CMD register */ +#define DWMCI_CMD_RESP_EXP BIT(6) +#define DWMCI_CMD_RESP_LENGTH BIT(7) +#define DWMCI_CMD_CHECK_CRC BIT(8) +#define DWMCI_CMD_DATA_EXP BIT(9) +#define DWMCI_CMD_RW BIT(10) +#define DWMCI_CMD_SEND_STOP BIT(12) +#define DWMCI_CMD_ABORT_STOP BIT(14) +#define DWMCI_CMD_PRV_DAT_WAIT BIT(13) +#define DWMCI_CMD_UPD_CLK BIT(21) +#define DWMCI_CMD_USE_HOLD_REG BIT(29) +#define DWMCI_CMD_START BIT(31) + +/* CLKENA register */ +#define DWMCI_CLKEN_ENABLE BIT(0) +#define DWMCI_CLKEN_LOW_PWR BIT(16) + +/* Card-type register */ +#define DWMCI_CTYPE_1BIT 0 +#define DWMCI_CTYPE_4BIT BIT(0) +#define DWMCI_CTYPE_8BIT BIT(16) + +/* Status Register */ +#define DWMCI_STATUS_FIFO_EMPTY BIT(2) +#define DWMCI_STATUS_FIFO_FULL BIT(3) +#define DWMCI_STATUS_BUSY BIT(9) + +/* FIFOTH Register */ +#define DWMCI_FIFOTH_MSIZE(x) ((x) << 28) +#define DWMCI_FIFOTH_RX_WMARK(x) ((x) << 16) +#define DWMCI_FIFOTH_TX_WMARK(x) (x) +#define DWMCI_FIFOTH_FIFO_DEPTH(x) ((((x) >> 16) & 0x3ff) + 1) + +#define DWMCI_IDMAC_OWN BIT(31) +#define DWMCI_IDMAC_CH BIT(4) +#define DWMCI_IDMAC_FS BIT(3) +#define DWMCI_IDMAC_LD BIT(2) + +/* Bus Mode Register */ +#define DWMCI_BMOD_IDMAC_RESET BIT(0) +#define DWMCI_BMOD_IDMAC_FB BIT(1) +#define DWMCI_BMOD_IDMAC_EN BIT(7) + +#endif -- cgit v1.2.3 From 529643163c5ad8f2220355b7d961a5dc714da5a9 Mon Sep 17 00:00:00 2001 From: Enrico Jorns Date: Tue, 31 Jul 2018 12:44:27 +0200 Subject: bootm: allow booting SoCFPGA prebootloader image A prebootloader image might also contain a fully working barebox and allows to be booted second stage. Thus we add a handler here to give it a try. Signed-off-by: Enrico Jorns Signed-off-by: Sascha Hauer --- arch/arm/lib32/bootm.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/lib32/bootm.c b/arch/arm/lib32/bootm.c index 63713acf59..4cf570e577 100644 --- a/arch/arm/lib32/bootm.c +++ b/arch/arm/lib32/bootm.c @@ -434,6 +434,12 @@ static struct image_handler barebox_handler = { .filetype = filetype_arm_barebox, }; +static struct image_handler socfpga_xload_handler = { + .name = "SoCFPGA prebootloader image", + .bootm = do_bootm_linux, + .filetype = filetype_socfpga_xload, +}; + #include static int aimage_load_resource(int fd, struct resource *r, void* buf, int ps) @@ -628,6 +634,7 @@ static int armlinux_register_image_handler(void) globalvar_add_simple_bool("bootm.boot_atag", &bootm_boot_atag); register_image_handler(&barebox_handler); + register_image_handler(&socfpga_xload_handler); register_image_handler(&uimage_handler); register_image_handler(&rawimage_handler); register_image_handler(&zimage_handler); -- cgit v1.2.3 From 54800ba93246ef51a9356f21f72ea3a42c81c08c Mon Sep 17 00:00:00 2001 From: Steffen Trumtrar Date: Tue, 31 Jul 2018 12:44:29 +0200 Subject: ARM: socfpga: arria10: move debug_ll to common code Instead of copy+pasting the debug_ll messages to every new board, move them to the respective functions. Signed-off-by: Steffen Trumtrar Signed-off-by: Sascha Hauer --- arch/arm/boards/reflex-achilles/lowlevel.c | 4 ---- arch/arm/mach-socfpga/arria10-init.c | 2 ++ arch/arm/mach-socfpga/arria10-sdram.c | 2 ++ 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/boards/reflex-achilles/lowlevel.c b/arch/arm/boards/reflex-achilles/lowlevel.c index 25e7ad0f1c..fe57518cbb 100644 --- a/arch/arm/boards/reflex-achilles/lowlevel.c +++ b/arch/arm/boards/reflex-achilles/lowlevel.c @@ -27,12 +27,8 @@ static noinline void achilles_entry(void) arria10_init(&mainpll_cfg, &perpll_cfg, pinmux); - puts_ll("lowlevel init done\n"); - arria10_ddr_calibration_sequence(); - puts_ll("SDRAM setup done\n"); - fdt = __dtb_socfpga_arria10_achilles_start + get_runtime_offset(); barebox_arm_entry(0x0, SZ_2G + SZ_1G, fdt); diff --git a/arch/arm/mach-socfpga/arria10-init.c b/arch/arm/mach-socfpga/arria10-init.c index f016b84bb7..faf4c866a4 100644 --- a/arch/arm/mach-socfpga/arria10-init.c +++ b/arch/arm/mach-socfpga/arria10-init.c @@ -194,4 +194,6 @@ void arria10_init(struct arria10_mainpll_cfg *mainpll, arria10_reset_deassert_fpga_peripherals(); INIT_LL(); + + puts_ll("lowlevel init done\n"); } diff --git a/arch/arm/mach-socfpga/arria10-sdram.c b/arch/arm/mach-socfpga/arria10-sdram.c index 08de0e32cd..35c355df71 100644 --- a/arch/arm/mach-socfpga/arria10-sdram.c +++ b/arch/arm/mach-socfpga/arria10-sdram.c @@ -531,5 +531,7 @@ int arria10_ddr_calibration_sequence(void) if (arria10_sdram_firewall_setup()) puts_ll("FW: Error Configuring Firewall\n"); + puts_ll("SDRAM setup done\n"); + return 0; } -- cgit v1.2.3 From 3927ffb241081253ffb5e06b7da72c4d2a742284 Mon Sep 17 00:00:00 2001 From: Steffen Trumtrar Date: Tue, 31 Jul 2018 12:44:30 +0200 Subject: ARM: socfpga: arria10: add ocram base address Signed-off-by: Steffen Trumtrar Signed-off-by: Sascha Hauer --- arch/arm/mach-socfpga/include/mach/arria10-regs.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-socfpga/include/mach/arria10-regs.h b/arch/arm/mach-socfpga/include/mach/arria10-regs.h index 5569574e15..931876f43a 100644 --- a/arch/arm/mach-socfpga/include/mach/arria10-regs.h +++ b/arch/arm/mach-socfpga/include/mach/arria10-regs.h @@ -43,6 +43,7 @@ #define ARRIA10_NOC_FW_SOC2FPGA_SOC2FPGA_SCR_ADDR (0xffd13500) #define ARRIA10_DMANONSECURE_ADDR (0xffda0000) #define ARRIA10_DMASECURE_ADDR (0xffda1000) +#define ARRIA10_OCRAM_ADDR (0xffe00000) #define ARRIA10_MPUSCU_ADDR (0xffffc000) #define ARRIA10_MPUL2_ADDR (0xfffff000) -- cgit v1.2.3 From 98152c31407a97d5fda8eeb00aade6c93495a11b Mon Sep 17 00:00:00 2001 From: Steffen Trumtrar Date: Tue, 31 Jul 2018 12:44:31 +0200 Subject: ARM: socfpga: add SMP_TWD_ADDR for Arria10 Signed-off-by: Steffen Trumtrar Signed-off-by: Sascha Hauer --- arch/arm/mach-socfpga/include/mach/arria10-regs.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-socfpga/include/mach/arria10-regs.h b/arch/arm/mach-socfpga/include/mach/arria10-regs.h index 931876f43a..4464f06231 100644 --- a/arch/arm/mach-socfpga/include/mach/arria10-regs.h +++ b/arch/arm/mach-socfpga/include/mach/arria10-regs.h @@ -45,6 +45,7 @@ #define ARRIA10_DMASECURE_ADDR (0xffda1000) #define ARRIA10_OCRAM_ADDR (0xffe00000) #define ARRIA10_MPUSCU_ADDR (0xffffc000) +#define ARRIA10_SMP_TWD_ADDR (0xffffc600) #define ARRIA10_MPUL2_ADDR (0xfffff000) /* L2 cache controller */ -- cgit v1.2.3 From 4418dd99704afe1392f7873c5f30cf264414b123 Mon Sep 17 00:00:00 2001 From: Steffen Trumtrar Date: Tue, 31 Jul 2018 12:44:32 +0200 Subject: ARM: socfpga: arria10-init: split pinsetup Move the setup of the shared- and fpgapins to its own function. These pins can only be configured and let out of reset after the FPGA has been programmed. Signed-off-by: Steffen Trumtrar Signed-off-by: Sascha Hauer --- arch/arm/boards/reflex-achilles/lowlevel.c | 1 + arch/arm/mach-socfpga/arria10-init.c | 49 +++++++++++++++------------- arch/arm/mach-socfpga/include/mach/generic.h | 2 ++ 3 files changed, 29 insertions(+), 23 deletions(-) diff --git a/arch/arm/boards/reflex-achilles/lowlevel.c b/arch/arm/boards/reflex-achilles/lowlevel.c index fe57518cbb..4c18fa6bca 100644 --- a/arch/arm/boards/reflex-achilles/lowlevel.c +++ b/arch/arm/boards/reflex-achilles/lowlevel.c @@ -26,6 +26,7 @@ static noinline void achilles_entry(void) setup_c(); arria10_init(&mainpll_cfg, &perpll_cfg, pinmux); + arria10_finish_io(&mainpll_cfg, &perpll_cfg, pinmux); arria10_ddr_calibration_sequence(); diff --git a/arch/arm/mach-socfpga/arria10-init.c b/arch/arm/mach-socfpga/arria10-init.c index faf4c866a4..2fa44c21c5 100644 --- a/arch/arm/mach-socfpga/arria10-init.c +++ b/arch/arm/mach-socfpga/arria10-init.c @@ -127,6 +127,32 @@ static void arria10_mask_ecc_errors(void) writel(0x0007FFFF, ARRIA10_SYSMGR_ADDR + 0x94); } +void arria10_finish_io(struct arria10_mainpll_cfg *mainpll, + struct arria10_perpll_cfg *perpll, + uint32_t *pinmux) +{ + int i; + + /* shared pins */ + for (i = arria10_pinmux_shared_io_q1_1; + i <= arria10_pinmux_shared_io_q4_12; i++) + writel(pinmux[i], ARRIA10_PINMUX_SHARED_3V_IO_GRP_ADDR + + (i - arria10_pinmux_shared_io_q1_1) * sizeof(uint32_t)); + + /* usefpga: select source for signals: hps or fpga */ + for (i = arria10_pinmux_rgmii0_usefpga; + i < arria10_pinmux_max; i++) + writel(pinmux[i], ARRIA10_PINMUX_FPGA_INTERFACE_ADDR + + (i - arria10_pinmux_rgmii0_usefpga) * sizeof(uint32_t)); + + arria10_reset_deassert_shared_peripherals(); + + arria10_reset_deassert_fpga_peripherals(); + + INIT_LL(); + + puts_ll("lowlevel init done\n"); +} /* * First C function to initialize the critical hardware early */ @@ -173,27 +199,4 @@ void arria10_init(struct arria10_mainpll_cfg *mainpll, /* deassert peripheral resets */ arria10_reset_deassert_dedicated_peripherals(); - - /* wait for fpga_usermode */ - while ((readl(0xffd03080) & 0x6) == 0); - - /* shared pins */ - for (i = arria10_pinmux_shared_io_q1_1; - i <= arria10_pinmux_shared_io_q4_12; i++) - writel(pinmux[i], ARRIA10_PINMUX_SHARED_3V_IO_GRP_ADDR + - (i - arria10_pinmux_shared_io_q1_1) * sizeof(uint32_t)); - - arria10_reset_deassert_shared_peripherals(); - - /* usefpga: select source for signals: hps or fpga */ - for (i = arria10_pinmux_rgmii0_usefpga; - i < arria10_pinmux_max; i++) - writel(pinmux[i], ARRIA10_PINMUX_FPGA_INTERFACE_ADDR + - (i - arria10_pinmux_rgmii0_usefpga) * sizeof(uint32_t)); - - arria10_reset_deassert_fpga_peripherals(); - - INIT_LL(); - - puts_ll("lowlevel init done\n"); } diff --git a/arch/arm/mach-socfpga/include/mach/generic.h b/arch/arm/mach-socfpga/include/mach/generic.h index 9d6dd1f26c..da9028903c 100644 --- a/arch/arm/mach-socfpga/include/mach/generic.h +++ b/arch/arm/mach-socfpga/include/mach/generic.h @@ -13,6 +13,8 @@ struct arria10_pinmux_cfg; void arria10_init(struct arria10_mainpll_cfg *mainpll, struct arria10_perpll_cfg *perpll, uint32_t *pinmux); +void arria10_finish_io(struct arria10_mainpll_cfg *mainpll, + struct arria10_perpll_cfg *perpll, uint32_t *pinmux); void socfpga_lowlevel_init(struct socfpga_cm_config *cm_config, struct socfpga_io_config *io_config); -- cgit v1.2.3 From d81a1ba170bf545d11a645d8e6e464335da488b0 Mon Sep 17 00:00:00 2001 From: Steffen Trumtrar Date: Tue, 31 Jul 2018 12:44:33 +0200 Subject: ARM: socfpga: arria10: set default TEXTBASE Signed-off-by: Steffen Trumtrar Signed-off-by: Sascha Hauer --- arch/arm/mach-socfpga/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig index 58e4876f5c..4715e11434 100644 --- a/arch/arm/mach-socfpga/Kconfig +++ b/arch/arm/mach-socfpga/Kconfig @@ -11,6 +11,7 @@ config ARCH_SOCFPGA_XLOAD config ARCH_TEXT_BASE hex default 0x00100000 if MACH_SOCFPGA_CYCLONE5 + default 0xffe00000 if MACH_SOCFPGA_ARRIA10 comment "Altera SoCFPGA System-on-Chip" -- cgit v1.2.3 From 6e147fbd821a4ae586b4ca43edc1661da56b3e3b Mon Sep 17 00:00:00 2001 From: Steffen Trumtrar Date: Tue, 31 Jul 2018 12:44:34 +0200 Subject: ARM: socfpga: arria10: fix SDMMC phase shift Signed-off-by: Steffen Trumtrar Signed-off-by: Sascha Hauer --- arch/arm/mach-socfpga/arria10-generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-socfpga/arria10-generic.c b/arch/arm/mach-socfpga/arria10-generic.c index 6a10c19d14..53ec278739 100644 --- a/arch/arm/mach-socfpga/arria10-generic.c +++ b/arch/arm/mach-socfpga/arria10-generic.c @@ -63,7 +63,7 @@ static int arria10_generic_init(void) pr_debug("Setting SDMMC phase shifts for Arria10\n"); writel(ARRIA10_SYSMGR_SDMMC_DRVSEL(3) | - ARRIA10_SYSMGR_SDMMC_SMPLSEL(0), + ARRIA10_SYSMGR_SDMMC_SMPLSEL(2), ARRIA10_SYSMGR_SDMMC); pr_debug("Initialize EMACs\n"); -- cgit v1.2.3 From bc8adf6cfe67ca03f481d581f9f7cc88bc48a914 Mon Sep 17 00:00:00 2001 From: Steffen Trumtrar Date: Tue, 31 Jul 2018 12:44:35 +0200 Subject: ARM: socfpga: achilles: update handoff files Signed-off-by: Steffen Trumtrar Signed-off-by: Sascha Hauer --- arch/arm/boards/reflex-achilles/pinmux-config-arria10.c | 2 +- arch/arm/boards/reflex-achilles/pll-config-arria10.c | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/arm/boards/reflex-achilles/pinmux-config-arria10.c b/arch/arm/boards/reflex-achilles/pinmux-config-arria10.c index 246838a228..b6a72304b6 100644 --- a/arch/arm/boards/reflex-achilles/pinmux-config-arria10.c +++ b/arch/arm/boards/reflex-achilles/pinmux-config-arria10.c @@ -69,7 +69,7 @@ static uint32_t pinmux[] = { [arria10_pincfg_dedicated_io_3] = 0xb080a, [arria10_pincfg_dedicated_io_4] = 0xa282a, [arria10_pincfg_dedicated_io_5] = 0xa282a, -[arria10_pincfg_dedicated_io_6] = 0xa282a, +[arria10_pincfg_dedicated_io_6] = 0x8282a, [arria10_pincfg_dedicated_io_7] = 0xa282a, [arria10_pincfg_dedicated_io_8] = 0xa282a, [arria10_pincfg_dedicated_io_9] = 0xa282a, diff --git a/arch/arm/boards/reflex-achilles/pll-config-arria10.c b/arch/arm/boards/reflex-achilles/pll-config-arria10.c index 94d596606e..9da41ecdf2 100644 --- a/arch/arm/boards/reflex-achilles/pll-config-arria10.c +++ b/arch/arm/boards/reflex-achilles/pll-config-arria10.c @@ -6,8 +6,8 @@ static struct arria10_mainpll_cfg mainpll_cfg = { .cntr3clk_cnt = 900, .cntr4clk_cnt = 900, .cntr5clk_cnt = 900, - .cntr6clk_cnt = 7, - .cntr7clk_cnt = 900, + .cntr6clk_cnt = 9, + .cntr7clk_cnt = 19, .cntr7clk_src = 0, .cntr8clk_cnt = 900, .cntr9clk_cnt = 900, @@ -24,19 +24,19 @@ static struct arria10_mainpll_cfg mainpll_cfg = { .nocdiv_l4spclk = 2, .vco0_psrc = 0, .vco1_denom = 1, - .vco1_numer = 127, + .vco1_numer = 159, .mpuclk = 0x3840001, - .nocclk = 0x3840003, + .nocclk = 0x3840004, }; static struct arria10_perpll_cfg perpll_cfg = { - .cntr2clk_cnt = 5, + .cntr2clk_cnt = 7, .cntr2clk_src = 1, .cntr3clk_cnt = 900, .cntr3clk_src = 1, - .cntr4clk_cnt = 14, + .cntr4clk_cnt = 19, .cntr4clk_src = 1, - .cntr5clk_cnt = 374, + .cntr5clk_cnt = 499, .cntr5clk_src = 1, .cntr6clk_cnt = 900, .cntr6clk_src = 0, @@ -50,5 +50,5 @@ static struct arria10_perpll_cfg perpll_cfg = { .gpiodiv_gpiodbclk = 32000, .vco0_psrc = 0, .vco1_denom = 1, - .vco1_numer = 119, + .vco1_numer = 159, }; -- cgit v1.2.3 From d916ae12bfdf05e3125e5ab2612ca0ff47f08e04 Mon Sep 17 00:00:00 2001 From: Steffen Trumtrar Date: Tue, 31 Jul 2018 12:44:36 +0200 Subject: ARM: dts: socfpga: Fix achilles dtc warnings The newer dtc has stricter checks on devicetrees. Fix the warnings. Signed-off-by: Steffen Trumtrar Signed-off-by: Sascha Hauer --- arch/arm/dts/socfpga_arria10_achilles.dts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/dts/socfpga_arria10_achilles.dts b/arch/arm/dts/socfpga_arria10_achilles.dts index 059a92c413..36be662990 100644 --- a/arch/arm/dts/socfpga_arria10_achilles.dts +++ b/arch/arm/dts/socfpga_arria10_achilles.dts @@ -93,17 +93,17 @@ &i2c0 { status = "okay"; - tempsensor: ti,tmp102@0x48 { + tempsensor: ti,tmp102@48 { compatible = "ti,tmp102"; reg = <0x48>; }; - rtc: nxp,pcf8563@0x51 { + rtc: nxp,pcf8563@51 { compatible = "nxp,pcf8563"; reg = <0x51>; }; - eeprom: at24@0x54 { + eeprom: at24@54 { compatible = "at24"; reg = <0x54>; bytelen = <256>; -- cgit v1.2.3 From ef7a2a150477ff55e0e7ba74b9d4e86a1482c497 Mon Sep 17 00:00:00 2001 From: Steffen Trumtrar Date: Tue, 31 Jul 2018 12:44:37 +0200 Subject: scripts: socfpga_mkimage: add size feature for PBL barebox Add the switch 's' to fixup the image size into the barebox header. This is used by the Arria10 PBL code to know the complete image size. Signed-off-by: Steffen Trumtrar Signed-off-by: Sascha Hauer --- scripts/socfpga_mkimage.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/scripts/socfpga_mkimage.c b/scripts/socfpga_mkimage.c index d7fe1b1b69..fedcfb5b6f 100644 --- a/scripts/socfpga_mkimage.c +++ b/scripts/socfpga_mkimage.c @@ -256,7 +256,7 @@ static int add_socfpga_header(void *buf, size_t size, unsigned start_addr, unsig static void usage(const char *prgname) { - fprintf(stderr, "usage: %s [-hb] [-v version] -o \n", prgname); + fprintf(stderr, "usage: %s [-hbs] [-v version] -o \n", prgname); } int main(int argc, char *argv[]) @@ -268,9 +268,11 @@ int main(int argc, char *argv[]) int fd; int max_image_size, min_image_size = 80; int addsize = 0, pad; + int fixup_size = 0; unsigned int version = 0; + int fixed_size = 0; - while ((opt = getopt(argc, argv, "o:hbv:")) != -1) { + while ((opt = getopt(argc, argv, "o:hbsv:")) != -1) { switch (opt) { case 'v': version = atoi(optarg); @@ -285,6 +287,9 @@ int main(int argc, char *argv[]) min_image_size = 0; addsize = 512; break; + case 's': + fixup_size = 1; + break; case 'h': usage(argv[0]); exit(0); @@ -349,10 +354,26 @@ int main(int argc, char *argv[]) exit(1); } + fixed_size = s.st_size; + close(fd); if (add_barebox_header) { + int barebox_size = 0; + int *image_size = buf + 0x2c; + memcpy(buf, bb_header, sizeof(bb_header)); + + if (fixup_size) { + fixed_size = htole32(fixed_size); + + barebox_size = *((uint32_t *)buf + (fixed_size + addsize + pad) / 4 - 1); + + /* size of barebox+pbl, header, size */ + fixed_size += (barebox_size + addsize + 4); + + *image_size = fixed_size; + } } ret = add_socfpga_header(buf, s.st_size + 4 + addsize + pad, addsize, -- cgit v1.2.3 From 1466d7d0e485fe43258aea423d2e4deba7d83c1e Mon Sep 17 00:00:00 2001 From: Steffen Trumtrar Date: Tue, 31 Jul 2018 12:44:38 +0200 Subject: ARM: socfpga: arria10-reset-manager: don't reset bootsource Arria10 init code resets all peripherals. Convert this to keep the bootmedium out of reset and keep the setup done by the boot ROM. Signed-off-by: Steffen Trumtrar Signed-off-by: Sascha Hauer --- arch/arm/mach-socfpga/arria10-bootsource.c | 16 +++++++++-- arch/arm/mach-socfpga/arria10-reset-manager.c | 33 +++++++++++++++------- .../include/mach/arria10-system-manager.h | 4 +++ arch/arm/mach-socfpga/include/mach/generic.h | 3 ++ 4 files changed, 43 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-socfpga/arria10-bootsource.c b/arch/arm/mach-socfpga/arria10-bootsource.c index 26af64a1a4..3319dc4bf9 100644 --- a/arch/arm/mach-socfpga/arria10-bootsource.c +++ b/arch/arm/mach-socfpga/arria10-bootsource.c @@ -15,16 +15,17 @@ #include #include #include +#include #include -static int arria10_boot_save_loc(void) -{ +enum bootsource arria10_get_bootsource(void) { enum bootsource src = BOOTSOURCE_UNKNOWN; uint32_t val; + uint32_t mask = ARRIA10_SYSMGR_BOOTINFO_BSEL_MASK; val = readl(ARRIA10_SYSMGR_BOOTINFO); - switch ((val & 0x7000) >> 12) { + switch ((val & mask) >> ARRIA10_SYSMGR_BOOTINFO_BSEL_SHIFT) { case 0: /* reserved */ break; @@ -45,6 +46,15 @@ static int arria10_boot_save_loc(void) break; } + return src; +} + +static int arria10_boot_save_loc(void) +{ + enum bootsource src; + + src = arria10_get_bootsource(); + bootsource_set(src); bootsource_set_instance(0); diff --git a/arch/arm/mach-socfpga/arria10-reset-manager.c b/arch/arm/mach-socfpga/arria10-reset-manager.c index a7e4bd603e..76adc1702c 100644 --- a/arch/arm/mach-socfpga/arria10-reset-manager.c +++ b/arch/arm/mach-socfpga/arria10-reset-manager.c @@ -5,8 +5,10 @@ */ #include +#include #include #include +#include #include #include #include @@ -14,23 +16,35 @@ void arria10_reset_peripherals(void) { - unsigned mask_ecc_ocp = ARRIA10_RSTMGR_PER0MODRST_EMAC0OCP | + enum bootsource src; + + uint32_t mask = ARRIA10_RSTMGR_PER0MODRST_EMAC0OCP | ARRIA10_RSTMGR_PER0MODRST_EMAC1OCP | ARRIA10_RSTMGR_PER0MODRST_EMAC2OCP | ARRIA10_RSTMGR_PER0MODRST_USB0OCP | ARRIA10_RSTMGR_PER0MODRST_USB1OCP | ARRIA10_RSTMGR_PER0MODRST_NANDOCP | - ARRIA10_RSTMGR_PER0MODRST_QSPIOCP | - ARRIA10_RSTMGR_PER0MODRST_SDMMCOCP; + ARRIA10_RSTMGR_PER0MODRST_QSPIOCP; + + src = arria10_get_bootsource(); + if (src == BOOTSOURCE_MMC) { + mask |= ARRIA10_RSTMGR_PER0MODRST_SDMMC; + mask |= ARRIA10_RSTMGR_PER0MODRST_SDMMCOCP; + } - /* disable all components except ECC_OCP, L4 Timer0 and L4 WD0 */ + /* disable all components except the ECC_OCP and bootsource */ writel(0xffffffff, ARRIA10_RSTMGR_ADDR + ARRIA10_RSTMGR_PER1MODRST); - setbits_le32(ARRIA10_RSTMGR_ADDR + ARRIA10_RSTMGR_PER0MODRST, - ~mask_ecc_ocp); + writel(~mask, ARRIA10_RSTMGR_ADDR + ARRIA10_RSTMGR_PER0MODRST); + + mask = 0xffffffff; + + if (src == BOOTSOURCE_MMC) { + mask &= ~ARRIA10_RSTMGR_PER0MODRST_SDMMC; + mask &= ~ARRIA10_RSTMGR_PER0MODRST_SDMMCOCP; + } /* Finally disable the ECC_OCP */ - setbits_le32(ARRIA10_RSTMGR_ADDR + ARRIA10_RSTMGR_PER0MODRST, - mask_ecc_ocp); + writel(mask, ARRIA10_RSTMGR_ADDR + ARRIA10_RSTMGR_PER0MODRST); } void arria10_reset_deassert_dedicated_peripherals(void) @@ -45,8 +59,7 @@ void arria10_reset_deassert_dedicated_peripherals(void) /* enable ECC OCP first */ clrbits_le32(ARRIA10_RSTMGR_ADDR + ARRIA10_RSTMGR_PER0MODRST, mask); - mask = ARRIA10_RSTMGR_PER0MODRST_SDMMC | - ARRIA10_RSTMGR_PER0MODRST_QSPI | + mask = ARRIA10_RSTMGR_PER0MODRST_QSPI | ARRIA10_RSTMGR_PER0MODRST_NAND | ARRIA10_RSTMGR_PER0MODRST_DMA; diff --git a/arch/arm/mach-socfpga/include/mach/arria10-system-manager.h b/arch/arm/mach-socfpga/include/mach/arria10-system-manager.h index f98cc36c76..20bd35270a 100644 --- a/arch/arm/mach-socfpga/include/mach/arria10-system-manager.h +++ b/arch/arm/mach-socfpga/include/mach/arria10-system-manager.h @@ -52,6 +52,10 @@ #define ARRIA10_SYSMGR_NOC_IDLESTATUS (ARRIA10_SYSMGR_ADDR + 0xd4) #define ARRIA10_SYSMGR_FPGA2SOC_CTRL (ARRIA10_SYSMGR_ADDR + 0xd8) + +#define ARRIA10_SYSMGR_BOOTINFO_BSEL_MASK 0x00007000 +#define ARRIA10_SYSMGR_BOOTINFO_BSEL_SHIFT 12 + /* pin mux */ #define ARRIA10_SYSMGR_PINMUXGRP (ARRIA10_SYSMGR_ADDR + 0x400) #define ARRIA10_SYSMGR_PINMUXGRP_NANDUSEFPGA (ARRIA10_SYSMGR_PINMUXGRP + 0x2F0) diff --git a/arch/arm/mach-socfpga/include/mach/generic.h b/arch/arm/mach-socfpga/include/mach/generic.h index da9028903c..5fcbc9ecf5 100644 --- a/arch/arm/mach-socfpga/include/mach/generic.h +++ b/arch/arm/mach-socfpga/include/mach/generic.h @@ -45,6 +45,9 @@ static inline void socfpga_cyclone5_qspi_init(void) return; } #endif +#if defined(CONFIG_ARCH_SOCFPGA_ARRIA10) +enum bootsource arria10_get_bootsource(void); +#endif static inline void __udelay(unsigned us) { -- cgit v1.2.3 From 8a680e3c9b5dd8470b7437654877d5439e9a6407 Mon Sep 17 00:00:00 2001 From: Steffen Trumtrar Date: Tue, 31 Jul 2018 12:44:39 +0200 Subject: ARM: socfpga: Arria10: support programming FPGA in PBL Some Arria10 boards don't have the FPGA programmed externally. Instead barebox needs to do that. As the Arria10 has the SDRAM controller in the FPGA, the first thing we need to do is, configure the FPGA before the SDRAM can even be used. It works like this: 1. boot ROM fetches the PBL from MMC 2. read the MBR from MMC (this depends on the setup done by the boot ROM) 3. read the Bitstream from the MMC and program the FPGA 4. re-read the barebox image from MMC, this time with the full barebox that is appended to the PBL 5. jump into the full barebox Only supported boot device is eMMC. Signed-off-by: Steffen Trumtrar Signed-off-by: Sascha Hauer --- arch/arm/Kconfig | 4 - arch/arm/mach-socfpga/Kconfig | 8 +- arch/arm/mach-socfpga/Makefile | 12 +- arch/arm/mach-socfpga/arria10-xload-emmc.c | 222 ++++++++++ arch/arm/mach-socfpga/arria10-xload.c | 457 +++++++++++++++++++++ arch/arm/mach-socfpga/include/mach/arria10-fpga.h | 86 ++++ .../include/mach/arria10-system-manager.h | 2 + arch/arm/mach-socfpga/include/mach/arria10-xload.h | 13 + arch/arm/mach-socfpga/include/mach/debug_ll.h | 2 - arch/arm/mach-socfpga/include/mach/generic.h | 36 ++ images/Makefile.socfpga | 11 + 11 files changed, 844 insertions(+), 9 deletions(-) create mode 100644 arch/arm/mach-socfpga/arria10-xload-emmc.c create mode 100644 arch/arm/mach-socfpga/arria10-xload.c create mode 100644 arch/arm/mach-socfpga/include/mach/arria10-fpga.h create mode 100644 arch/arm/mach-socfpga/include/mach/arria10-xload.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 3555b4ee53..702b2fe6ef 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -179,10 +179,6 @@ config ARCH_SOCFPGA select CPU_V7 select COMMON_CLK select CLKDEV_LOOKUP - select GPIOLIB - select HAVE_PBL_MULTI_IMAGES - select OFDEVICE if !(ARCH_SOCFPGA_XLOAD && ARCH_SOCFPGA_CYCLONE5) - select OFTREE if !(ARCH_SOCFPGA_XLOAD && ARCH_SOCFPGA_CYCLONE5) config ARCH_S3C24xx bool "Samsung S3C2410, S3C2440" diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig index 4715e11434..65097b676a 100644 --- a/arch/arm/mach-socfpga/Kconfig +++ b/arch/arm/mach-socfpga/Kconfig @@ -18,11 +18,17 @@ comment "Altera SoCFPGA System-on-Chip" config ARCH_SOCFPGA_CYCLONE5 bool select CPU_V7 + select HAVE_PBL_MULTI_IMAGES + select OFDEVICE if !ARCH_SOCFPGA_XLOAD + select OFTREE if !ARCH_SOCFPGA_XLOAD config ARCH_SOCFPGA_ARRIA10 bool select CPU_V7 - select HAVE_MACH_ARM_HEAD + select RESET_CONTROLLER + select HAVE_PBL_MULTI_IMAGES + select OFDEVICE + select OFTREE config MACH_SOCFPGA_ALTERA_SOCDK select ARCH_SOCFPGA_CYCLONE5 diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile index cbb47fa206..3a3a2fc57d 100644 --- a/arch/arm/mach-socfpga/Makefile +++ b/arch/arm/mach-socfpga/Makefile @@ -2,7 +2,15 @@ pbl-$(CONFIG_ARCH_SOCFPGA_CYCLONE5) += cyclone5-init.o cyclone5-freeze-controlle pbl-$(CONFIG_ARCH_SOCFPGA_CYCLONE5) += cyclone5-clock-manager.o obj-$(CONFIG_ARCH_SOCFPGA_CYCLONE5) += cyclone5-generic.o nic301.o cyclone5-bootsource.o cyclone5-reset-manager.o -pbl-$(CONFIG_ARCH_SOCFPGA_ARRIA10) += arria10-init.o arria10-clock-manager.o arria10-sdram.o arria10-reset-manager.o arria10-bootsource.o -obj-$(CONFIG_ARCH_SOCFPGA_ARRIA10) += arria10-bootsource.o arria10-generic.o arria10-reset-manager.o +pbl-$(CONFIG_ARCH_SOCFPGA_ARRIA10) += arria10-xload.o \ + arria10-xload-emmc.o +obj-pbl-$(CONFIG_ARCH_SOCFPGA_ARRIA10) += arria10-bootsource.o \ + arria10-clock-manager.o \ + arria10-generic.o \ + arria10-reset-manager.o \ + arria10-init.o \ + arria10-sdram.o +ifdef CONFIG_ARCH_SOCFPGA_CYCLONE5 obj-$(CONFIG_ARCH_SOCFPGA_XLOAD) += xload.o +endif diff --git a/arch/arm/mach-socfpga/arria10-xload-emmc.c b/arch/arm/mach-socfpga/arria10-xload-emmc.c new file mode 100644 index 0000000000..dcc38cf4a2 --- /dev/null +++ b/arch/arm/mach-socfpga/arria10-xload-emmc.c @@ -0,0 +1,222 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../../drivers/mci/sdhci.h" +#include "../../../drivers/mci/dw_mmc.h" + +#define SECTOR_SIZE 512 + +static int dwmci_wait_reset(uint32_t value) +{ + uint32_t ctrl; + int32_t timeout; + + timeout = 10000; + + writel(value, ARRIA10_SDMMC_ADDR + DWMCI_CTRL); + + while (timeout-- > 0) { + ctrl = readl(ARRIA10_SDMMC_ADDR + DWMCI_CTRL); + if (!(ctrl & DWMCI_RESET_ALL)) + return 0; + } + + return -EIO; +} + +static int dwmci_prepare_data(struct mci_data *data) +{ + unsigned long ctrl; + + dwmci_wait_reset(DWMCI_CTRL_FIFO_RESET); + + writel(DWMCI_INTMSK_TXDR | DWMCI_INTMSK_RXDR, + ARRIA10_SDMMC_ADDR + DWMCI_RINTSTS); + + ctrl = readl(ARRIA10_SDMMC_ADDR + DWMCI_INTMASK); + ctrl |= DWMCI_INTMSK_TXDR | DWMCI_INTMSK_RXDR; + writel(ctrl, ARRIA10_SDMMC_ADDR + DWMCI_INTMASK); + + ctrl = readl(ARRIA10_SDMMC_ADDR + DWMCI_CTRL); + ctrl &= ~(DWMCI_IDMAC_EN | DWMCI_DMA_EN); + writel(ctrl, ARRIA10_SDMMC_ADDR + DWMCI_CTRL); + + writel(0x1, ARRIA10_SDMMC_ADDR + DWMCI_FIFOTH); + writel(0xffffffff, ARRIA10_SDMMC_ADDR + DWMCI_TMOUT); + writel(0x0, ARRIA10_SDMMC_ADDR + DWMCI_IDINTEN); + + return 0; +} + +static int dwmci_read_data_pio(struct mci_data *data) +{ + u32 *pdata = (u32 *)data->dest; + u32 val, status, timeout; + u32 rcnt, rlen = 0; + + for (rcnt = (data->blocksize * data->blocks)>>2; rcnt; rcnt--) { + timeout = 20000; + status = readl(ARRIA10_SDMMC_ADDR + DWMCI_STATUS); + while (--timeout > 0 + && (status & DWMCI_STATUS_FIFO_EMPTY)) { + __udelay(200); + status = readl(ARRIA10_SDMMC_ADDR + DWMCI_STATUS); + } + if (!timeout) + break; + + val = readl(ARRIA10_SDMMC_ADDR + DWMCI_DATA); + *pdata++ = val; + rlen += 4; + } + writel(DWMCI_INTMSK_RXDR, ARRIA10_SDMMC_ADDR + DWMCI_RINTSTS); + + return rlen; +} + +static int dwmci_cmd(struct mci_cmd *cmd, struct mci_data *data) +{ + int flags = 0; + uint32_t mask; + int timeout; + + timeout = 100000; + while (readl(ARRIA10_SDMMC_ADDR + DWMCI_STATUS) & DWMCI_STATUS_BUSY) { + if (timeout-- <= 0) + return -ETIMEDOUT; + + } + + writel(DWMCI_INTMSK_ALL, ARRIA10_SDMMC_ADDR + DWMCI_RINTSTS); + + if (data) { + writel(data->blocksize, ARRIA10_SDMMC_ADDR + DWMCI_BLKSIZ); + writel(data->blocksize * data->blocks, ARRIA10_SDMMC_ADDR + + DWMCI_BYTCNT); + + dwmci_prepare_data(data); + } + + writel(cmd->cmdarg, ARRIA10_SDMMC_ADDR + DWMCI_CMDARG); + + if (data) + flags = DWMCI_CMD_DATA_EXP; + + if ((cmd->resp_type & MMC_RSP_136) && (cmd->resp_type & MMC_RSP_BUSY)) + return -EINVAL; + + if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) + flags |= DWMCI_CMD_ABORT_STOP; + else + flags |= DWMCI_CMD_PRV_DAT_WAIT; + + if (cmd->resp_type & MMC_RSP_PRESENT) { + flags |= DWMCI_CMD_RESP_EXP; + if (cmd->resp_type & MMC_RSP_136) + flags |= DWMCI_CMD_RESP_LENGTH; + } + + if (cmd->resp_type & MMC_RSP_CRC) + flags |= DWMCI_CMD_CHECK_CRC; + + flags |= (cmd->cmdidx | DWMCI_CMD_START | DWMCI_CMD_USE_HOLD_REG); + + writel(flags, ARRIA10_SDMMC_ADDR + DWMCI_CMD); + + for (timeout = 10000; timeout > 0; timeout--) { + mask = readl(ARRIA10_SDMMC_ADDR + DWMCI_RINTSTS); + if (mask & DWMCI_INTMSK_CDONE) { + if (!data) + writel(mask, ARRIA10_SDMMC_ADDR + DWMCI_RINTSTS); + break; + } + } + + if (timeout <= 0) + return -ETIMEDOUT; + + if (mask & DWMCI_INTMSK_RTO) + return -ETIMEDOUT; + else if (mask & DWMCI_INTMSK_RE) + return -EIO; + + if (cmd->resp_type & MMC_RSP_PRESENT) { + if (cmd->resp_type & MMC_RSP_136) { + cmd->response[0] = readl(ARRIA10_SDMMC_ADDR + DWMCI_RESP3); + cmd->response[1] = readl(ARRIA10_SDMMC_ADDR + DWMCI_RESP2); + cmd->response[2] = readl(ARRIA10_SDMMC_ADDR + DWMCI_RESP1); + cmd->response[3] = readl(ARRIA10_SDMMC_ADDR + DWMCI_RESP0); + } else { + cmd->response[0] = readl(ARRIA10_SDMMC_ADDR + DWMCI_RESP0); + } + } + + if (data) { + do { + mask = readl(ARRIA10_SDMMC_ADDR + DWMCI_RINTSTS); + if (mask & (DWMCI_DATA_ERR)) + return -EIO; + + if (mask & DWMCI_INTMSK_RXDR) { + dwmci_read_data_pio(data); + mask = readl(ARRIA10_SDMMC_ADDR + DWMCI_RINTSTS); + } + } while (!(mask & DWMCI_INTMSK_DTO)); + + writel(mask, ARRIA10_SDMMC_ADDR + DWMCI_RINTSTS); + } + + return 0; +} + +int arria10_read_blocks(void *dst, int blocknum, size_t len) +{ + struct mci_cmd cmd; + struct mci_data data; + int ret; + int blocks; + + blocks = len / SECTOR_SIZE; + + if (blocks > 1) + cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK; + else + cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK; + + cmd.cmdarg = blocknum; + cmd.resp_type = MMC_RSP_R1; + + data.dest = dst; + data.blocks = blocks; + data.blocksize = SECTOR_SIZE; + data.flags = MMC_DATA_READ; + + ret = dwmci_cmd(&cmd, &data); + + if (ret || blocks > 1) { + cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION; + cmd.cmdarg = 0; + cmd.resp_type = MMC_RSP_R1b; + + dwmci_cmd(&cmd, NULL); + } + + return ret; +} + +void arria10_init_mmc(void) +{ + writel(ARRIA10_SYSMGR_SDMMC_DRVSEL(3) | + ARRIA10_SYSMGR_SDMMC_SMPLSEL(2), + ARRIA10_SYSMGR_SDMMC); + + /* enable power to card */ + writel(0x1, ARRIA10_SDMMC_ADDR + DWMCI_PWREN); + + writel(DWMCI_CTYPE_1BIT, ARRIA10_SDMMC_ADDR + DWMCI_CTYPE); +} diff --git a/arch/arm/mach-socfpga/arria10-xload.c b/arch/arm/mach-socfpga/arria10-xload.c new file mode 100644 index 0000000000..f665ba4742 --- /dev/null +++ b/arch/arm/mach-socfpga/arria10-xload.c @@ -0,0 +1,457 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int a10_update_bits(unsigned int reg, unsigned int mask, + unsigned int val) +{ + unsigned int tmp, orig; + int ret = 0; + + orig = readl(ARRIA10_FPGAMGRREGS_ADDR + reg); + tmp = orig & ~mask; + tmp |= val & mask; + + if (tmp != orig) + ret = writel(tmp, ARRIA10_FPGAMGRREGS_ADDR + reg); + + return ret; +} + +static uint32_t socfpga_a10_fpga_read_stat(void) +{ + return readl(ARRIA10_FPGAMGRREGS_ADDR + A10_FPGAMGR_IMGCFG_STAT_OFST); +} + +static int a10_fpga_wait_for_condone(void) +{ + u32 reg, i; + + for (i = 0; i < 0x1000000 ; i++) { + reg = socfpga_a10_fpga_read_stat(); + + if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_PIN) + return 0; + + if ((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN) == 0) + return -EIO; + } + + return -ETIMEDOUT; +} + +static void a10_fpga_generate_dclks(uint32_t count) +{ + int32_t timeout; + + /* Clear any existing DONE status. */ + writel(A10_FPGAMGR_DCLKSTAT_DCLKDONE, ARRIA10_FPGAMGRREGS_ADDR + + A10_FPGAMGR_DCLKSTAT_OFST); + + /* Issue the DCLK regmap. */ + writel(count, ARRIA10_FPGAMGRREGS_ADDR + A10_FPGAMGR_DCLKCNT_OFST); + + /* wait till the dclkcnt done */ + timeout = 10000000; + + while (!readl(ARRIA10_FPGAMGRREGS_ADDR + A10_FPGAMGR_DCLKSTAT_OFST)) { + if (timeout-- < 0) + return; + } + + /* Clear DONE status. */ + writel(A10_FPGAMGR_DCLKSTAT_DCLKDONE, ARRIA10_FPGAMGRREGS_ADDR + + A10_FPGAMGR_DCLKSTAT_OFST); +} + +static unsigned int a10_fpga_get_cd_ratio(unsigned int cfg_width, + bool encrypt, bool compress) +{ + unsigned int cd_ratio; + + /* + * cd ratio is dependent on cfg width and whether the bitstream + * is encrypted and/or compressed. + * + * | width | encr. | compr. | cd ratio | value | + * | 16 | 0 | 0 | 1 | 0 | + * | 16 | 0 | 1 | 4 | 2 | + * | 16 | 1 | 0 | 2 | 1 | + * | 16 | 1 | 1 | 4 | 2 | + * | 32 | 0 | 0 | 1 | 0 | + * | 32 | 0 | 1 | 8 | 3 | + * | 32 | 1 | 0 | 4 | 2 | + * | 32 | 1 | 1 | 8 | 3 | + */ + if (!compress && !encrypt) + return CDRATIO_x1; + + if (compress) + cd_ratio = CDRATIO_x4; + else + cd_ratio = CDRATIO_x2; + + /* If 32 bit, double the cd ratio by incrementing the field */ + if (cfg_width == CFGWDTH_32) + cd_ratio += 1; + + return cd_ratio; +} + +static int a10_fpga_set_cdratio(unsigned int cfg_width, + const void *buf) +{ + unsigned int cd_ratio; + int encrypt, compress; + u32 *rbf_data = (u32 *)buf; + + encrypt = (rbf_data[69] >> 2) & 3; + encrypt = encrypt != 0; + + compress = (rbf_data[229] >> 1) & 1; + compress = !compress; + + cd_ratio = a10_fpga_get_cd_ratio(cfg_width, encrypt, compress); + + a10_update_bits(A10_FPGAMGR_IMGCFG_CTL_02_OFST, + A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_MASK, + cd_ratio << A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_SHIFT); + + return 0; +} + +static int a10_fpga_init(void *buf) +{ + uint32_t stat, mask; + uint32_t val; + uint32_t timeout; + + val = CFGWDTH_32 << A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH_SHIFT; + a10_update_bits(A10_FPGAMGR_IMGCFG_CTL_02_OFST, + A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH, val); + + a10_fpga_set_cdratio(CFGWDTH_32, buf); + + mask = A10_FPGAMGR_IMGCFG_STAT_F2S_NCONFIG_PIN | + A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN; + /* Make sure no external devices are interfering */ + timeout = 10000; + while ((socfpga_a10_fpga_read_stat() & mask) != mask) { + if (timeout-- < 0) + return -ETIMEDOUT; + } + + /* S2F_NCE = 1 */ + a10_update_bits(A10_FPGAMGR_IMGCFG_CTL_01_OFST, + A10_FPGAMGR_IMGCFG_CTL_01_S2F_NCE, + A10_FPGAMGR_IMGCFG_CTL_01_S2F_NCE); + /* S2F_PR_REQUEST = 0 */ + a10_update_bits(A10_FPGAMGR_IMGCFG_CTL_01_OFST, + A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST, 0); + /* EN_CFG_CTRL = 0 */ + a10_update_bits(A10_FPGAMGR_IMGCFG_CTL_02_OFST, + A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL, 0); + /* S2F_NCONFIG = 1 */ + a10_update_bits(A10_FPGAMGR_IMGCFG_CTL_00_OFST, + A10_FPGAMGR_IMGCFG_CTL_00_S2F_NCONFIG, + A10_FPGAMGR_IMGCFG_CTL_00_S2F_NCONFIG); + /* S2F_NSTATUS_OE = 0 and S2f_CONDONE_OE = 0 */ + a10_update_bits(A10_FPGAMGR_IMGCFG_CTL_00_OFST, + A10_FPGAMGR_IMGCFG_CTL_00_S2F_NSTATUS_OE | + A10_FPGAMGR_IMGCFG_CTL_00_S2F_CONDONE_OE, + 0); + /* Enable overrides: S2F_NENABLE_CONFIG = 0 */ + a10_update_bits(A10_FPGAMGR_IMGCFG_CTL_01_OFST, + A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG, 0); + /* Enable overrides: S2F_NENABLE_NCONFIG = 0 */ + a10_update_bits(A10_FPGAMGR_IMGCFG_CTL_00_OFST, + A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NCONFIG, 0); + /* Disable unused overrides: S2F_NENABLE_NSTATUS = 1 and S2F_NENABLE_CONDONE = 1 */ + a10_update_bits(A10_FPGAMGR_IMGCFG_CTL_00_OFST, + A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NSTATUS | + A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_CONDONE, + A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NSTATUS | + A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_CONDONE); + /* Drive chip select S2F_NCE = 0 */ + a10_update_bits(A10_FPGAMGR_IMGCFG_CTL_01_OFST, + A10_FPGAMGR_IMGCFG_CTL_01_S2F_NCE, 0); + + mask = A10_FPGAMGR_IMGCFG_STAT_F2S_NCONFIG_PIN | + A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN; + + timeout = 100000; + while ((socfpga_a10_fpga_read_stat() & mask) != mask) { + if (timeout-- < 0) + return -ETIMEDOUT; + } + + /* reset the configuration */ + a10_update_bits(A10_FPGAMGR_IMGCFG_CTL_00_OFST, + A10_FPGAMGR_IMGCFG_CTL_00_S2F_NCONFIG, 0); + + timeout = 1000000; + while ((socfpga_a10_fpga_read_stat() & + A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN) != 0) { + if (timeout-- < 0) + return -ETIMEDOUT; + } + + a10_update_bits(A10_FPGAMGR_IMGCFG_CTL_00_OFST, + A10_FPGAMGR_IMGCFG_CTL_00_S2F_NCONFIG, + A10_FPGAMGR_IMGCFG_CTL_00_S2F_NCONFIG); + + mask = A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN; + /* wait for nstatus == 1 */ + timeout = 1000000; + while ((socfpga_a10_fpga_read_stat() & mask) != mask) { + if (timeout-- < 0) { + writel(socfpga_a10_fpga_read_stat(), 0xFFD06238); + return -ETIMEDOUT; + } + } + + stat = socfpga_a10_fpga_read_stat(); + if ((stat & A10_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_PIN) != 0) + return -EINVAL; + if ((stat & A10_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_OE) == 0) + return -EINVAL; + + a10_update_bits(A10_FPGAMGR_IMGCFG_CTL_02_OFST, + A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL | + A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_DATA, + A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_DATA | + A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL); + + /* Check fpga_usermode */ + if ((socfpga_a10_fpga_read_stat() & 0x6) == 0x6) + return -EIO; + + return 0; +} + +static int a10_fpga_write(void *buf, size_t count) +{ + const uint32_t *buf32 = buf; + uint32_t reg; + + /* Stop if FPGA is configured */ + reg = socfpga_a10_fpga_read_stat(); + + if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_PIN) + return -ENOSPC; + + /* Write out the complete 32-bit chunks */ + while (count >= sizeof(uint32_t)) { + writel(*buf32, ARRIA10_FPGAMGRDATA_ADDR); + buf32++; + count -= sizeof(u32); + } + + /* Write out remaining non 32-bit chunks */ + if (count) { + const uint8_t *buf8 = (const uint8_t *)buf32; + uint32_t word = 0; + + while (count--) { + word |= *buf8; + word <<= 8; + buf8++; + } + + writel(word, ARRIA10_FPGAMGRDATA_ADDR); + } + + return 0; +} + +static int a10_fpga_write_complete(void) +{ + u32 reg; + int ret; + + /* Wait for condone */ + ret = a10_fpga_wait_for_condone(); + + /* Send some clocks to clear out any errors */ + a10_fpga_generate_dclks(256); + + /* Disable s2f dclk and data */ + a10_update_bits(A10_FPGAMGR_IMGCFG_CTL_02_OFST, + A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL, 0); + + /* Deassert chip select */ + a10_update_bits(A10_FPGAMGR_IMGCFG_CTL_01_OFST, + A10_FPGAMGR_IMGCFG_CTL_01_S2F_NCE, + A10_FPGAMGR_IMGCFG_CTL_01_S2F_NCE); + + /* Disable data, dclk, nce, and pr_request override to CSS */ + a10_update_bits(A10_FPGAMGR_IMGCFG_CTL_01_OFST, + A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG, + A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG); + + /* Return any errors regarding pr_done or pr_error */ + if (ret) + return ret; + + /* wait for fpga_usermode */ + a10_wait_for_usermode(0x1000000); + + /* Final check */ + reg = socfpga_a10_fpga_read_stat(); + + if (((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_USERMODE) == 0) || + ((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_PIN) == 0) || + ((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN) == 0)) + return -ETIMEDOUT; + + return 0; +} + +static struct partition bitstream; +static struct partition bootloader; + +int arria10_prepare_mmc(int barebox_part, int rbf_part) +{ + void *buf = (void *)0xffe00000 + SZ_256K - 128 - SECTOR_SIZE; + struct partition_entry *table; + uint32_t i; + int ret; + + arria10_init_mmc(); + + /* read partition table */ + ret = arria10_read_blocks(buf, 0x0, SECTOR_SIZE); + if (ret) + return ret; + + table = (struct partition_entry *)&buf[446]; + + for (i = 0; i < 4; i++) { + bootloader.type = get_unaligned_le32(&table[i].type); + if (bootloader.type == 0xa2) { + bootloader.first_sec = get_unaligned_le32(&table[i].partition_start); + break; + } + } + + bitstream.first_sec = get_unaligned_le32(&table[rbf_part].partition_start); + + return 0; +} + +int arria10_load_fpga(int offset, int bitstream_size) +{ + void *buf = (void *)0xffe00000 + SZ_256K - 256 - SZ_16K; + int ret; + uint32_t count; + uint32_t size = bitstream_size / SECTOR_SIZE; + + if (offset) + offset = offset / SECTOR_SIZE; + + count = offset; + + arria10_read_blocks(buf, count + bitstream.first_sec, SZ_16K); + + count += SZ_16K / SECTOR_SIZE; + + ret = a10_fpga_init(buf); + if (ret) + hang(); + + while (count <= size) { + ret = a10_fpga_write(buf, SZ_16K); + if (ret == -ENOSPC) + break; + count += SZ_16K / SECTOR_SIZE; + ret = arria10_read_blocks(buf, count, SZ_16K); + } + + ret = a10_fpga_write_complete(); + if (ret) + hang(); + + return 0; +} + +static int image_size(void) +{ + uint32_t *image_end = (void *)__image_end; + uint32_t payload_len; + uint32_t pbl_len; + uint32_t arria10_header_len; + uint32_t sizep; + uint32_t arria10_crc; + + /* arria10 header is 512 byte */ + arria10_header_len = 512; + /* pbl is appended with 4 byte CRC for boot rom */ + arria10_crc = 4; + + /* The length of the PBL image */ + pbl_len = __image_end - _text; + + sizep = 4; + + /* The length of the payload is appended directly behind the PBL */ + payload_len = *(image_end); + + return pbl_len + arria10_header_len + sizep + arria10_crc + payload_len; +} + +void arria10_start_image(int offset) +{ + void *buf = (void *)0x0; + void *in_buf = (void *)SZ_1M; + uint32_t start; + int size = 0; + int ret; + void __noreturn (*bb)(void); + uint32_t pbl_len = __image_end - _text; + uint32_t *image_end = (void *)__image_end; + uint32_t arria10_header_len; + uint32_t sizep; + uint32_t arria10_crc; + + size = image_size(); + + start = bootloader.first_sec + offset / SECTOR_SIZE; + + ret = arria10_read_blocks(buf, start, ALIGN(size, SECTOR_SIZE)); + if (ret) { + puts_ll("Loading image failed\n"); + hang(); + } + + /* arria10 header is 512 byte */ + arria10_header_len = 512; + sizep = 4; + + /* copy PBL */ + memcpy(in_buf, buf, pbl_len + sizep + arria10_header_len); + + /* pbl is appended with 4 byte CRC for boot rom */ + arria10_crc = 4; + + /* copy payload, skip the Arria10 CRC */ + memcpy(in_buf + pbl_len + sizep + arria10_header_len, + buf + pbl_len + sizep + arria10_header_len + arria10_crc, *(image_end)); + + bb = in_buf; + + bb(); + + hang(); +} diff --git a/arch/arm/mach-socfpga/include/mach/arria10-fpga.h b/arch/arm/mach-socfpga/include/mach/arria10-fpga.h new file mode 100644 index 0000000000..0d957dedcf --- /dev/null +++ b/arch/arm/mach-socfpga/include/mach/arria10-fpga.h @@ -0,0 +1,86 @@ +/* + * FPGA Manager Driver for Altera Arria10 SoCFPGA + * + * Copyright (C) 2015-2016 Altera Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#ifndef __A10_FPGAMGR_H__ +#define __A10_FPGAMGR_H__ + +#include +#include + +#define A10_FPGAMGR_DCLKCNT_OFST 0x08 +#define A10_FPGAMGR_DCLKSTAT_OFST 0x0c +#define A10_FPGAMGR_IMGCFG_CTL_00_OFST 0x70 +#define A10_FPGAMGR_IMGCFG_CTL_01_OFST 0x74 +#define A10_FPGAMGR_IMGCFG_CTL_02_OFST 0x78 +#define A10_FPGAMGR_IMGCFG_STAT_OFST 0x80 + +#define A10_FPGAMGR_DCLKSTAT_DCLKDONE BIT(0) + +#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NCONFIG BIT(0) +#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NSTATUS BIT(1) +#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_CONDONE BIT(2) +#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NCONFIG BIT(8) +#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NSTATUS_OE BIT(16) +#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_CONDONE_OE BIT(24) + +#define A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG BIT(0) +#define A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST BIT(16) +#define A10_FPGAMGR_IMGCFG_CTL_01_S2F_NCE BIT(24) + +#define A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL BIT(0) +#define A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_DATA BIT(8) +#define A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_MASK (BIT(16) | BIT(17)) +#define A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_SHIFT 16 +#define A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH BIT(24) +#define A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH_SHIFT 24 + +#define A10_FPGAMGR_IMGCFG_STAT_F2S_CRC_ERROR BIT(0) +#define A10_FPGAMGR_IMGCFG_STAT_F2S_EARLY_USERMODE BIT(1) +#define A10_FPGAMGR_IMGCFG_STAT_F2S_USERMODE BIT(2) +#define A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN BIT(4) +#define A10_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_PIN BIT(6) +#define A10_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_OE BIT(7) +#define A10_FPGAMGR_IMGCFG_STAT_F2S_PR_READY BIT(9) +#define A10_FPGAMGR_IMGCFG_STAT_F2S_PR_DONE BIT(10) +#define A10_FPGAMGR_IMGCFG_STAT_F2S_PR_ERROR BIT(11) +#define A10_FPGAMGR_IMGCFG_STAT_F2S_NCONFIG_PIN BIT(12) +#define A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_MASK (BIT(16) | BIT(17) | BIT(18)) +#define A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_SHIFT 16 + +/* FPGA CD Ratio Value */ +#define CDRATIO_x1 0x0 +#define CDRATIO_x2 0x1 +#define CDRATIO_x4 0x2 +#define CDRATIO_x8 0x3 + +/* Configuration width 16/32 bit */ +#define CFGWDTH_32 1 +#define CFGWDTH_16 0 + +int inline a10_wait_for_usermode(int timeout) { + while ((readl(ARRIA10_FPGAMGRREGS_ADDR + + A10_FPGAMGR_IMGCFG_STAT_OFST) & + (A10_FPGAMGR_IMGCFG_STAT_F2S_EARLY_USERMODE | + A10_FPGAMGR_IMGCFG_STAT_F2S_USERMODE)) == 0) + if (timeout-- <= 0) + return -ETIMEDOUT; + + return 0; +} + +#endif diff --git a/arch/arm/mach-socfpga/include/mach/arria10-system-manager.h b/arch/arm/mach-socfpga/include/mach/arria10-system-manager.h index 20bd35270a..9117a93b18 100644 --- a/arch/arm/mach-socfpga/include/mach/arria10-system-manager.h +++ b/arch/arm/mach-socfpga/include/mach/arria10-system-manager.h @@ -52,6 +52,8 @@ #define ARRIA10_SYSMGR_NOC_IDLESTATUS (ARRIA10_SYSMGR_ADDR + 0xd4) #define ARRIA10_SYSMGR_FPGA2SOC_CTRL (ARRIA10_SYSMGR_ADDR + 0xd8) +#define ARRIA10_SYSMGR_ROM_INITSWLASTLD (ARRIA10_SYSMGR_ADDR + 0x10) + #define ARRIA10_SYSMGR_BOOTINFO_BSEL_MASK 0x00007000 #define ARRIA10_SYSMGR_BOOTINFO_BSEL_SHIFT 12 diff --git a/arch/arm/mach-socfpga/include/mach/arria10-xload.h b/arch/arm/mach-socfpga/include/mach/arria10-xload.h new file mode 100644 index 0000000000..71f8397362 --- /dev/null +++ b/arch/arm/mach-socfpga/include/mach/arria10-xload.h @@ -0,0 +1,13 @@ +#ifndef __MACH_ARRIA10_XLOAD_H +#define __MACH_ARRIA10_XLOAD_H + +void arria10_init_mmc(void); +int arria10_prepare_mmc(int barebox_part, int rbf_part); +int arria10_read_blocks(void *dst, int blocknum, size_t len); + +struct partition { + uint64_t first_sec; + uint8_t type; +}; + +#endif /* __MACH_ARRIA10_XLOAD_H */ diff --git a/arch/arm/mach-socfpga/include/mach/debug_ll.h b/arch/arm/mach-socfpga/include/mach/debug_ll.h index f41258c504..3264934e6d 100644 --- a/arch/arm/mach-socfpga/include/mach/debug_ll.h +++ b/arch/arm/mach-socfpga/include/mach/debug_ll.h @@ -40,8 +40,6 @@ static inline void INIT_LL(void) unsigned int div = ns16550_calc_divisor(CONFIG_DEBUG_SOCFPGA_UART_CLOCK, 115200); - while ((readl(UART_BASE + LSR) & LSR_TEMT) == 0); - writel(0x00, UART_BASE + IER); writel(LCR_BKSE, UART_BASE + LCR); diff --git a/arch/arm/mach-socfpga/include/mach/generic.h b/arch/arm/mach-socfpga/include/mach/generic.h index 5fcbc9ecf5..72391f3552 100644 --- a/arch/arm/mach-socfpga/include/mach/generic.h +++ b/arch/arm/mach-socfpga/include/mach/generic.h @@ -46,7 +46,43 @@ static inline void socfpga_cyclone5_qspi_init(void) } #endif #if defined(CONFIG_ARCH_SOCFPGA_ARRIA10) +void socfpga_arria10_mmc_init(void); +void socfpga_arria10_timer_init(void); +int arria10_prepare_mmc(int barebox, int bitstream); +void arria10_start_image(int offset); +int arria10_load_fpga(int offset, int size); +int arria10_device_init(struct arria10_mainpll_cfg *mainpll, + struct arria10_perpll_cfg *perpll, + uint32_t *pinmux); enum bootsource arria10_get_bootsource(void); +#else +static inline void socfpga_arria10_mmc_init(void) +{ + return; +} + +static inline void socfpga_arria10_timer_init(void) +{ + return; +} +static void arria10_prepare_mmc(int barebox, int bitstream) +{ + return; +} +static void arria10_start_image(int offset) +{ + return; +} +static int arria10_load_fpga(int offset, int size) +{ + return; +} +static int arria10_device_init(struct arria10_mainpll_cfg *mainpll, + struct arria10_perpll_cfg *perpll, + uint32_t *pinmux) +{ + return 0; +} #endif static inline void __udelay(unsigned us) diff --git a/images/Makefile.socfpga b/images/Makefile.socfpga index 60b98d1ef2..bba01a38b2 100644 --- a/images/Makefile.socfpga +++ b/images/Makefile.socfpga @@ -13,6 +13,17 @@ quiet_cmd_socfpga_image = SOCFPGA-IMG $@ $(obj)/%.socfpgaimg: $(obj)/% FORCE $(call if_changed,socfpga_image) +ocram-tmp = $(subst $(comma),_,$(dot-target).ocram.tmp) + +quiet_cmd_socfpga_ocram_img ?= SOCFPGA-OCRAM-IMG $@ + cmd_socfpga_ocram_img ?= cat $(obj)/$(patsubst %.socfpga-ocram-img,%.pblb,$(2)) > $(ocram-tmp); \ + $(call size_append, $(obj)/barebox.z) >> $(ocram-tmp); \ + $(objtree)/scripts/socfpga_mkimage -v1 -b -s -o $@ $(ocram-tmp); \ + cat $(obj)/barebox.z >> $@ + +$(obj)/%.socfpga-ocram-img: $(obj)/%.pblb $(obj)/barebox.z FORCE + $(call if_changed,socfpga_ocram_img,$(@F)) + # ----------------------- Cyclone5 based boards --------------------------- pblx-$(CONFIG_MACH_SOCFPGA_ALTERA_SOCDK) += start_socfpga_socdk_xload FILE_barebox-socfpga-socdk-xload.img = start_socfpga_socdk_xload.pblx.socfpgaimg -- cgit v1.2.3 From 21fbe47970155751bb913afa81496eea341a40a1 Mon Sep 17 00:00:00 2001 From: Steffen Trumtrar Date: Tue, 31 Jul 2018 12:44:40 +0200 Subject: ARM: socfpga: achilles: convert to PBL barebox Previously the FPGA was configured externally on the Achilles. On newer versions this is changed and barebox has to configure the FPGA before the SDRAM can be used. If the FPGA is configured via JTAG or from an external memory, the *-bringup version can be used. Signed-off-by: Steffen Trumtrar Signed-off-by: Sascha Hauer --- arch/arm/boards/reflex-achilles/Makefile | 4 +- arch/arm/boards/reflex-achilles/board.c | 19 +++++++ arch/arm/boards/reflex-achilles/lowlevel.c | 86 +++++++++++++++++++++++++++--- images/Makefile.socfpga | 6 ++- 4 files changed, 106 insertions(+), 9 deletions(-) create mode 100644 arch/arm/boards/reflex-achilles/board.c diff --git a/arch/arm/boards/reflex-achilles/Makefile b/arch/arm/boards/reflex-achilles/Makefile index 6b42141153..092c31d6b2 100644 --- a/arch/arm/boards/reflex-achilles/Makefile +++ b/arch/arm/boards/reflex-achilles/Makefile @@ -1,2 +1,2 @@ -obj-y += lowlevel.o -pbl-y += lowlevel.o +lwl-y += lowlevel.o +obj-y += board.o diff --git a/arch/arm/boards/reflex-achilles/board.c b/arch/arm/boards/reflex-achilles/board.c new file mode 100644 index 0000000000..29011ba578 --- /dev/null +++ b/arch/arm/boards/reflex-achilles/board.c @@ -0,0 +1,19 @@ +#include +#include +#include +#include + +static int achilles_init(void) +{ + int pbl_index = 0; + + if (!of_machine_is_compatible("reflex,achilles")) + return 0; + + pbl_index = readl(0xFFD06210); + + pr_debug("Current barebox instance %d\n", pbl_index); + + return 0; +} +postcore_initcall(achilles_init); diff --git a/arch/arm/boards/reflex-achilles/lowlevel.c b/arch/arm/boards/reflex-achilles/lowlevel.c index 4c18fa6bca..2265aa882b 100644 --- a/arch/arm/boards/reflex-achilles/lowlevel.c +++ b/arch/arm/boards/reflex-achilles/lowlevel.c @@ -1,24 +1,39 @@ #include #include #include -#include +#include #include #include +#include +#include #include +#include #include #include #include #include #include +#include #include "pll-config-arria10.c" #include "pinmux-config-arria10.c" #include +#define BAREBOX_PART 0 +#define BITSTREAM_PART 1 +#define BAREBOX1_OFFSET SZ_1M +#define BAREBOX2_OFFSET BAREBOX1_OFFSET + SZ_512K +#define BAREBOX3_OFFSET BAREBOX2_OFFSET + SZ_512K +#define BAREBOX4_OFFSET BAREBOX3_OFFSET + SZ_512K +#define BITSTREAM1_OFFSET 0x0 +#define BITSTREAM2_OFFSET BITSTREAM1_OFFSET + SZ_64M + extern char __dtb_socfpga_arria10_achilles_start[]; -static noinline void achilles_entry(void) +static noinline void achilles_start(void) { - void *fdt; + int pbl_index = 0; + int barebox = 0; + int bitstream = 0; arm_early_mmu_cache_invalidate(); @@ -26,20 +41,79 @@ static noinline void achilles_entry(void) setup_c(); arria10_init(&mainpll_cfg, &perpll_cfg, pinmux); + + arria10_prepare_mmc(BAREBOX_PART, BITSTREAM_PART); + + pbl_index = readl(ARRIA10_SYSMGR_ROM_INITSWLASTLD); + + switch (pbl_index) { + case 0: + barebox = BAREBOX1_OFFSET; + bitstream = BITSTREAM1_OFFSET; + break; + case 1: + barebox = BAREBOX2_OFFSET; + bitstream = BITSTREAM1_OFFSET; + break; + case 2: + barebox = BAREBOX3_OFFSET; + bitstream = BITSTREAM2_OFFSET; + break; + case 3: + barebox = BAREBOX4_OFFSET; + bitstream = BITSTREAM2_OFFSET; + break; + } + + arria10_load_fpga(bitstream, SZ_64M); + arria10_finish_io(&mainpll_cfg, &perpll_cfg, pinmux); arria10_ddr_calibration_sequence(); + arria10_start_image(barebox); +} + +ENTRY_FUNCTION(start_socfpga_achilles, r0, r1, r2) +{ + void *fdt; + + if (get_pc() > ARRIA10_OCRAM_ADDR) { + arm_cpu_lowlevel_init(); + + arm_setup_stack(ARRIA10_OCRAM_ADDR + SZ_256K - 32); + + achilles_start(); + } + fdt = __dtb_socfpga_arria10_achilles_start + get_runtime_offset(); barebox_arm_entry(0x0, SZ_2G + SZ_1G, fdt); } -ENTRY_FUNCTION(start_socfpga_achilles, r0, r1, r2) +ENTRY_FUNCTION(start_socfpga_achilles_bringup, r0, r1, r2) { + void *fdt; + arm_cpu_lowlevel_init(); - arm_setup_stack(0xffe00000 + SZ_256K - SZ_32K - SZ_4K - 16); + arm_setup_stack(ARRIA10_OCRAM_ADDR + SZ_256K - 16); + + arm_early_mmu_cache_invalidate(); + + relocate_to_current_adr(); + setup_c(); + + arria10_init(&mainpll_cfg, &perpll_cfg, pinmux); - achilles_entry(); + /* wait for fpga_usermode */ + a10_wait_for_usermode(0x1000000); + + arria10_finish_io(&mainpll_cfg, &perpll_cfg, pinmux); + + arria10_ddr_calibration_sequence(); + + fdt = __dtb_socfpga_arria10_achilles_start + get_runtime_offset(); + + barebox_arm_entry(0x0, SZ_2G + SZ_1G, fdt); } diff --git a/images/Makefile.socfpga b/images/Makefile.socfpga index bba01a38b2..a075b36702 100644 --- a/images/Makefile.socfpga +++ b/images/Makefile.socfpga @@ -42,9 +42,13 @@ FILE_barebox-socfpga-de0_nano_soc.img = start_socfpga_de0_nano_soc.pblx socfpga-barebox-$(CONFIG_MACH_SOCFPGA_TERASIC_DE0_NANO_SOC) += barebox-socfpga-de0_nano_soc.img pblx-$(CONFIG_MACH_SOCFPGA_REFLEX_ACHILLES) += start_socfpga_achilles -FILE_barebox-socfpga-achilles.img = start_socfpga_achilles.pblx.socfpgaimg +FILE_barebox-socfpga-achilles.img = start_socfpga_achilles.socfpga-ocram-img socfpga-barebox-$(CONFIG_MACH_SOCFPGA_REFLEX_ACHILLES) += barebox-socfpga-achilles.img +pblx-$(CONFIG_MACH_SOCFPGA_REFLEX_ACHILLES) += start_socfpga_achilles_bringup +FILE_barebox-socfpga-achilles-bringup.img = start_socfpga_achilles_bringup.pblx +socfpga-barebox-$(CONFIG_MACH_SOCFPGA_REFLEX_ACHILLES) += barebox-socfpga-achilles-bringup.img + pblx-$(CONFIG_MACH_SOCFPGA_TERASIC_SOCKIT) += start_socfpga_sockit_xload FILE_barebox-socfpga-sockit-xload.img = start_socfpga_sockit_xload.pblx.socfpgaimg socfpga-xload-$(CONFIG_MACH_SOCFPGA_TERASIC_SOCKIT) += barebox-socfpga-sockit-xload.img -- cgit v1.2.3 From 4ff0c3fa31b662e79994b55b33e0cc6ab6f7291f Mon Sep 17 00:00:00 2001 From: Steffen Trumtrar Date: Tue, 31 Jul 2018 12:44:41 +0200 Subject: ARM: arria10: update defconfig Signed-off-by: Steffen Trumtrar Signed-off-by: Sascha Hauer --- arch/arm/configs/socfpga-arria10_defconfig | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/arm/configs/socfpga-arria10_defconfig b/arch/arm/configs/socfpga-arria10_defconfig index e661895d6e..53e932d64b 100644 --- a/arch/arm/configs/socfpga-arria10_defconfig +++ b/arch/arm/configs/socfpga-arria10_defconfig @@ -1,9 +1,9 @@ CONFIG_ARCH_SOCFPGA=y CONFIG_MACH_SOCFPGA_REFLEX_ACHILLES=y -CONFIG_THUMB2_BAREBOX=y +CONFIG_AEABI=y CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y CONFIG_ARM_UNWIND=y -CONFIG_MMU=y +CONFIG_TEXT_BASE=0xffe00000 CONFIG_MALLOC_SIZE=0x0 CONFIG_MALLOC_TLSF=y CONFIG_KALLSYMS=y @@ -17,7 +17,6 @@ CONFIG_BOOTM_SHOW_TYPE=y CONFIG_BOOTM_VERBOSE=y CONFIG_BOOTM_INITRD=y CONFIG_BOOTM_OFTREE=y -CONFIG_PBL_CONSOLE=y CONFIG_DEFAULT_COMPRESSION_LZO=y CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y CONFIG_POLLER=y @@ -57,7 +56,6 @@ CONFIG_CMD_MM=y CONFIG_CMD_CLK=y CONFIG_CMD_DETECT=y CONFIG_CMD_FLASH=y -CONFIG_CMD_GPIO=y CONFIG_CMD_BAREBOX_UPDATE=y CONFIG_CMD_FIRMWARELOAD=y CONFIG_CMD_OF_NODE=y @@ -72,6 +70,7 @@ CONFIG_OF_BAREBOX_DRIVERS=y CONFIG_OF_BAREBOX_ENV_IN_FS=y CONFIG_DRIVER_SERIAL_NS16550=y CONFIG_DRIVER_NET_DESIGNWARE=y +CONFIG_DRIVER_NET_DESIGNWARE_SOCFPGA=y CONFIG_MICREL_PHY=y # CONFIG_SPI is not set CONFIG_MCI=y -- cgit v1.2.3 From 2b8466c26a911bed1ac5aa25c463f67b3bdbf1eb Mon Sep 17 00:00:00 2001 From: Steffen Trumtrar Date: Tue, 31 Jul 2018 12:44:42 +0200 Subject: ARM: socfpga: achilles: move environment to raw partition Signed-off-by: Steffen Trumtrar Signed-off-by: Sascha Hauer --- arch/arm/dts/socfpga_arria10_achilles.dts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm/dts/socfpga_arria10_achilles.dts b/arch/arm/dts/socfpga_arria10_achilles.dts index 36be662990..c03982ef56 100644 --- a/arch/arm/dts/socfpga_arria10_achilles.dts +++ b/arch/arm/dts/socfpga_arria10_achilles.dts @@ -30,8 +30,7 @@ environment { compatible = "barebox,environment"; - device-path = &mmc, "partname:1"; - file-path = "barebox.env"; + device-path = &environment_mmc; }; }; @@ -116,6 +115,11 @@ broken-cd; bus-width = <1>; status = "okay"; + + environment_mmc: partition@178000 { + label = "environment"; + reg = <0x178000 0x8000>; + }; }; &uart0 { -- cgit v1.2.3