Marc Jones (marc.jones(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7269
-gerrit
commit 8756bb76d6429349bd2bac114975872d25d14bfd
Author: Vadim Bendebury <vbendeb(a)chromium.org>
Date: Wed Apr 9 19:23:04 2014 -0700
ipq8064: Make timer code compile
Commment out nonessential timer services and modify the source code to
cleanly build in coeboot environment. Do not remove dead code just
yet, these functions might be necessary later.
Need to rename the soc timer.h to prevent collisions with timer.h in
the top level include directory.
Currently build timer code for ramstage only.
BUG=chrome-os-partner:27784
TEST='emerge-storm coreboot' still succeeds
Original-Change-Id: Ib10133ccb42697840708845a8ea6d75ceeaeb3d5
Original-Signed-off-by: Vadim Bendebury <vbendeb(a)chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/194067
Original-Reviewed-by: David Hendricks <dhendrix(a)chromium.org>
(cherry picked from commit 987ce95220953c16216d1e1d70d5a941d05fc9bc)
Signed-off-by: Marc Jones <marc.jones(a)se-eng.com>
Change-Id: Ia9cf175da11c70709354def5e51bf79df4fda2fe
---
src/soc/qualcomm/ipq806x/Makefile.inc | 1 +
src/soc/qualcomm/ipq806x/cbfs.c | 9 ------
src/soc/qualcomm/ipq806x/include/cdp.h | 40 +++++++++++++++++-------
src/soc/qualcomm/ipq806x/include/iomap.h | 4 ++-
src/soc/qualcomm/ipq806x/include/ipq_timer.h | 40 ++++++++++++++++++++++++
src/soc/qualcomm/ipq806x/include/timer.h | 40 ------------------------
src/soc/qualcomm/ipq806x/timer.c | 46 ++++++++++++----------------
7 files changed, 93 insertions(+), 87 deletions(-)
diff --git a/src/soc/qualcomm/ipq806x/Makefile.inc b/src/soc/qualcomm/ipq806x/Makefile.inc
index 002e59c..41cde31 100644
--- a/src/soc/qualcomm/ipq806x/Makefile.inc
+++ b/src/soc/qualcomm/ipq806x/Makefile.inc
@@ -6,6 +6,7 @@ romstage-y += gpio.c
ramstage-y += cbfs.c
ramstage-y += gpio.c
+ramstage-y += timer.c
ifeq ($(CONFIG_USE_BLOBS),y)
diff --git a/src/soc/qualcomm/ipq806x/cbfs.c b/src/soc/qualcomm/ipq806x/cbfs.c
index eec9b73..97ae548 100644
--- a/src/soc/qualcomm/ipq806x/cbfs.c
+++ b/src/soc/qualcomm/ipq806x/cbfs.c
@@ -24,12 +24,3 @@ int init_default_cbfs_media(struct cbfs_media *media)
{
return 0;
}
-
-/*
- * Temporary change to make sure storm code still builds. Will be dropped
- * shortly.
- */
-#include <delay.h> /* This driver serves as a CBFS media source. */
-void init_timer(void)
-{
-}
diff --git a/src/soc/qualcomm/ipq806x/include/cdp.h b/src/soc/qualcomm/ipq806x/include/cdp.h
index 4ae476a..22ba192 100644
--- a/src/soc/qualcomm/ipq806x/include/cdp.h
+++ b/src/soc/qualcomm/ipq806x/include/cdp.h
@@ -4,9 +4,23 @@
#ifndef _IPQ806X_CDP_H_
#define _IPQ806X_CDP_H_
-#include <phy.h>
+unsigned smem_get_board_machtype(void);
-unsigned int smem_get_board_machtype(void);
+typedef enum {
+ PHY_INTERFACE_MODE_MII,
+ PHY_INTERFACE_MODE_GMII,
+ PHY_INTERFACE_MODE_SGMII,
+ PHY_INTERFACE_MODE_QSGMII,
+ PHY_INTERFACE_MODE_TBI,
+ PHY_INTERFACE_MODE_RMII,
+ PHY_INTERFACE_MODE_RGMII,
+ PHY_INTERFACE_MODE_RGMII_ID,
+ PHY_INTERFACE_MODE_RGMII_RXID,
+ PHY_INTERFACE_MODE_RGMII_TXID,
+ PHY_INTERFACE_MODE_RTBI,
+ PHY_INTERFACE_MODE_XGMII,
+ PHY_INTERFACE_MODE_NONE /* Must be last */
+} phy_interface_t;
typedef struct {
unsigned int gpio;
@@ -73,17 +87,17 @@ typedef struct {
} spinorflash_params_t;
typedef struct {
- uint count;
- u8 addr[7];
+ unsigned count;
+ uint8_t addr[7];
} ipq_gmac_phy_addr_t;
typedef struct {
- uint base;
+ unsigned base;
int unit;
- uint is_macsec;
- uint mac_pwr0;
- uint mac_pwr1;
- uint mac_conn_to_phy;
+ unsigned is_macsec;
+ unsigned mac_pwr0;
+ unsigned mac_pwr1;
+ unsigned mac_conn_to_phy;
phy_interface_t phy;
ipq_gmac_phy_addr_t phy_addr;
} ipq_gmac_board_cfg_t;
@@ -98,6 +112,7 @@ typedef struct {
unsigned int uart_gsbi_base;
unsigned int uart_dm_base;
unsigned int clk_dummy;
+#if 0
uart_clk_mnd_t mnd_value;
unsigned int gmac_gpio_count;
gpio_func_data_t *gmac_gpio;
@@ -105,10 +120,12 @@ typedef struct {
flash_desc flashdesc;
spinorflash_params_t flash_param;
gpio_func_data_t dbg_uart_gpio[NO_OF_DBG_UART_GPIOS];
+#endif
} __attribute__ ((__packed__)) board_ipq806x_params_t;
extern board_ipq806x_params_t *gboard_param;
+#if 0
static inline int gmac_cfg_is_valid(ipq_gmac_board_cfg_t *cfg)
{
/*
@@ -121,7 +138,8 @@ static inline int gmac_cfg_is_valid(ipq_gmac_board_cfg_t *cfg)
(cfg < &gboard_param->gmac_cfg[IPQ_GMAC_NMACS]) &&
(cfg->unit >= 0) && (cfg->unit < IPQ_GMAC_NMACS));
}
+#endif
-unsigned int get_board_index(unsigned int machid);
-void ipq_configure_gpio(gpio_func_data_t *gpio, uint count);
+unsigned int get_board_index(unsigned machid);
+void ipq_configure_gpio(gpio_func_data_t *gpio, unsigned count);
#endif
diff --git a/src/soc/qualcomm/ipq806x/include/iomap.h b/src/soc/qualcomm/ipq806x/include/iomap.h
index 5fcfde9..8642410 100644
--- a/src/soc/qualcomm/ipq806x/include/iomap.h
+++ b/src/soc/qualcomm/ipq806x/include/iomap.h
@@ -43,6 +43,8 @@
*/
#define readl_i(a) read32((const void *)(a))
#define writel_i(v,a) write32(v,(void *)a)
+#include <arch/io.h>
+#include <cdp.h>
#define MSM_CLK_CTL_BASE 0x00900000
@@ -50,7 +52,7 @@
#define MSM_GPT_BASE (MSM_TMR_BASE + 0x04)
#define MSM_DGT_BASE (MSM_TMR_BASE + 0x24)
-#define GPT_REG(off) (MSM_GPT_BASE + (off))
+#define GPT_REG(off) (((uint8_t *)(MSM_GPT_BASE)) + (off))
#define DGT_REG(off) (MSM_DGT_BASE + (off))
#define APCS_WDT0_EN (MSM_TMR_BASE + 0x0040)
diff --git a/src/soc/qualcomm/ipq806x/include/ipq_timer.h b/src/soc/qualcomm/ipq806x/include/ipq_timer.h
new file mode 100644
index 0000000..4e1ef34
--- /dev/null
+++ b/src/soc/qualcomm/ipq806x/include/ipq_timer.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define TIMER_LOAD_VAL 0x21
+
+#define GPT_ENABLE_CLR_ON_MATCH_EN 2
+#define GPT_ENABLE_EN 1
+#define DGT_ENABLE_CLR_ON_MATCH_EN 2
+#define DGT_ENABLE_EN 1
+
+#define SPSS_TIMER_STATUS_DGT_EN (1 << 0)
+
+
diff --git a/src/soc/qualcomm/ipq806x/include/timer.h b/src/soc/qualcomm/ipq806x/include/timer.h
deleted file mode 100644
index 4e1ef34..0000000
--- a/src/soc/qualcomm/ipq806x/include/timer.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google, Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#define TIMER_LOAD_VAL 0x21
-
-#define GPT_ENABLE_CLR_ON_MATCH_EN 2
-#define GPT_ENABLE_EN 1
-#define DGT_ENABLE_CLR_ON_MATCH_EN 2
-#define DGT_ENABLE_EN 1
-
-#define SPSS_TIMER_STATUS_DGT_EN (1 << 0)
-
-
diff --git a/src/soc/qualcomm/ipq806x/timer.c b/src/soc/qualcomm/ipq806x/timer.c
index 691ccbd..5c0dcb2 100644
--- a/src/soc/qualcomm/ipq806x/timer.c
+++ b/src/soc/qualcomm/ipq806x/timer.c
@@ -31,14 +31,10 @@
* SUCH DAMAGE.
*/
-#include <asm/arch-ipq806x/iomap.h>
-#include <asm/io.h>
-#include <common.h>
-#include <asm/types.h>
-#include <asm/arch-ipq806x/timer.h>
-
-static ulong timestamp;
-static ulong lastinc;
+#include <delay.h>
+#include <iomap.h>
+#include <ipq_timer.h>
+#include <timer.h>
#define GPT_FREQ_KHZ 32
#define GPT_FREQ (GPT_FREQ_KHZ * 1000) /* 32 KHz */
@@ -46,36 +42,24 @@ static ulong lastinc;
/**
* timer_init - initialize timer
*/
-int timer_init(void)
+void init_timer(void)
{
writel(0, GPT_ENABLE);
writel(GPT_ENABLE_EN, GPT_ENABLE);
- return 0;
-}
-
-/**
- * get_timer - returns time lapsed
- * @base: base/start time
- *
- * Returns time lapsed, since the specified base time value.
- */
-ulong get_timer(ulong base)
-{
- return get_timer_masked() - base;
}
/**
- * __udelay - generates micro second delay.
+ * udelay - generates micro second delay.
* @usec: delay duration in microseconds
*
* With 32KHz clock, minimum possible delay is 31.25 Micro seconds and
* its multiples. In Rumi GPT clock is 32 KHz
*/
-void __udelay(unsigned long usec)
+void udelay(unsigned usec)
{
- unsigned int val;
- ulong now, last;
- ulong runcount;
+ unsigned val;
+ unsigned now, last;
+ unsigned runcount;
usec = (usec + GPT_FREQ_KHZ - 1) / GPT_FREQ_KHZ;
last = readl(GPT_COUNT_VAL);
@@ -92,6 +76,15 @@ void __udelay(unsigned long usec)
} while (runcount < val);
}
+#if 0
+
+/*
+ * TODO(vbendeb) clean it up later.
+ * Compile out the below code but leave it for now in case it will become
+ * necessary later in order to make the platform fully functional.
+ */
+static unsigned long timestamp;
+static unsigned long lastinc;
inline ulong gpt_to_sys_freq(unsigned int gpt)
{
@@ -137,3 +130,4 @@ ulong get_tbclk(void)
{
return GPT_FREQ;
}
+#endif
Marc Jones (marc.jones(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7263
-gerrit
commit 5ea8749066ea70581338a0c60703d60ec9ab8d00
Author: Vadim Bendebury <vbendeb(a)chromium.org>
Date: Tue Apr 8 18:45:46 2014 -0700
Copy u-boot sources as is and modify the tree to still build
This patch brings in ipq806x source files from the vendor's u-boot
tree as it was published in the 'cs_banana' release.
The following files are being copied:
arch/arm/cpu/armv7/ipq/clock.c => src/soc/qualcomm/ipq806x/clock.c
arch/arm/cpu/armv7/ipq/gpio.c => src/soc/qualcomm/ipq806x/gpio.c
arch/arm/cpu/armv7/ipq/timer.c => src/soc/qualcomm/ipq806x/timer.c
arch/arm/include/asm/arch-ipq806x/clock.h => src/soc/qualcomm/ipq806x/clock.h
arch/arm/include/asm/arch-ipq806x/gpio.h => src/soc/qualcomm/ipq806x/gpio.h
arch/arm/include/asm/arch-ipq806x/gsbi.h => src/soc/qualcomm/ipq806x/gsbi.h
arch/arm/include/asm/arch-ipq806x/iomap.h => src/soc/qualcomm/ipq806x/iomap.h
arch/arm/include/asm/arch-ipq806x/timer.h src/soc/qualcomm/ipq806x/timer.h
arch/arm/include/asm/arch-ipq806x/uart.h => src/soc/qualcomm/ipq806x/uart.h
board/qcom/ipq806x_cdp/ipq806x_cdp.c => src/mainboard/google/storm/cdp.c
board/qcom/ipq806x_cdp/ipq806x_cdp.h => src/soc/qualcomm/ipq8064/cdp.h
drivers/serial/ipq806x_uart.c => src/console/ipq806x_console.c
Note that local timer.c gets overwritten with the original version. To
prevent a build breakage some shortly to be reverted modifications had
to be made to src/soc/qualcomm/ipq806x/Makefile.inc and
src/soc/qualcomm/ipq806x/cbfs.c.
BRANCH=none
BUG=chrome-os-partner:27784
TEST='emerge-storm coreboot' still succeeds
Original-Change-Id: I3f50bfbec2e18a3b5d2c640cff353a26f88c98c1
Original-Signed-off-by: Vadim Bendebury <vbendeb(a)chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/193722
Original-Reviewed-by: David Hendricks <dhendrix(a)chromium.org>
(cherry picked from commit 3c9c2ede7e97e330cad2c2f3e557cc9bcdaecdcc)
Signed-off-by: Marc Jones <marc.jones(a)se-eng.com>
Change-Id: Ia7bc66cecfc16f1dd4a9f3cb9840cbe91878adf4
---
src/console/ipq806x_console.c | 440 ++++++++++++++++++++++++++++++++++
src/mainboard/google/storm/cdp.c | 379 +++++++++++++++++++++++++++++
src/soc/qualcomm/ipq806x/Makefile.inc | 3 -
src/soc/qualcomm/ipq806x/cbfs.c | 9 +
src/soc/qualcomm/ipq806x/cdp.h | 127 ++++++++++
src/soc/qualcomm/ipq806x/clock.c | 123 ++++++++++
src/soc/qualcomm/ipq806x/clock.h | 185 ++++++++++++++
src/soc/qualcomm/ipq806x/gpio.c | 62 +++++
src/soc/qualcomm/ipq806x/gpio.h | 63 +++++
src/soc/qualcomm/ipq806x/gsbi.h | 37 +++
src/soc/qualcomm/ipq806x/iomap.h | 90 +++++++
src/soc/qualcomm/ipq806x/timer.c | 145 +++++++++--
src/soc/qualcomm/ipq806x/timer.h | 40 ++++
src/soc/qualcomm/ipq806x/uart.h | 281 ++++++++++++++++++++++
14 files changed, 1964 insertions(+), 20 deletions(-)
diff --git a/src/console/ipq806x_console.c b/src/console/ipq806x_console.c
new file mode 100644
index 0000000..c65f876
--- /dev/null
+++ b/src/console/ipq806x_console.c
@@ -0,0 +1,440 @@
+/*
+ * Copyright (c) 2012 The Linux Foundation. All rights reserved.
+ * Source : APQ8064 LK boot
+ *
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include <common.h>
+#include <asm/arch-ipq806x/gsbi.h>
+#include <asm/arch-ipq806x/clock.h>
+#include <asm/arch-ipq806x/uart.h>
+#include <serial.h>
+
+#define FIFO_DATA_SIZE 4
+
+extern board_ipq806x_params_t *gboard_param;
+
+static unsigned int msm_boot_uart_dm_init(unsigned int uart_dm_base);
+
+/* Received data is valid or not */
+static int valid_data = 0;
+
+/* Received data */
+static unsigned int word = 0;
+
+/**
+ * msm_boot_uart_dm_init_rx_transfer - Init Rx transfer
+ * @uart_dm_base: UART controller base address
+ */
+static unsigned int msm_boot_uart_dm_init_rx_transfer(unsigned int uart_dm_base)
+{
+ /* Reset receiver */
+ writel(MSM_BOOT_UART_DM_CMD_RESET_RX,
+ MSM_BOOT_UART_DM_CR(uart_dm_base));
+
+ /* Enable receiver */
+ writel(MSM_BOOT_UART_DM_CR_RX_ENABLE,
+ MSM_BOOT_UART_DM_CR(uart_dm_base));
+ writel(MSM_BOOT_UART_DM_DMRX_DEF_VALUE,
+ MSM_BOOT_UART_DM_DMRX(uart_dm_base));
+
+ /* Clear stale event */
+ writel(MSM_BOOT_UART_DM_CMD_RES_STALE_INT,
+ MSM_BOOT_UART_DM_CR(uart_dm_base));
+
+ /* Enable stale event */
+ writel(MSM_BOOT_UART_DM_GCMD_ENA_STALE_EVT,
+ MSM_BOOT_UART_DM_CR(uart_dm_base));
+
+ return MSM_BOOT_UART_DM_E_SUCCESS;
+}
+
+/**
+ * msm_boot_uart_dm_read - reads a word from the RX FIFO.
+ * @data: location where the read data is stored
+ * @count: no of valid data in the FIFO
+ * @wait: indicates blocking call or not blocking call
+ *
+ * Reads a word from the RX FIFO. If no data is available blocks if
+ * @wait is true, else returns %MSM_BOOT_UART_DM_E_RX_NOT_READY.
+ */
+static unsigned int
+msm_boot_uart_dm_read(unsigned int *data, int *count, int wait)
+{
+ static int total_rx_data = 0;
+ static int rx_data_read = 0;
+ unsigned int base = 0;
+ uint32_t status_reg;
+
+ base = gboard_param->uart_dm_base;
+
+ if (data == NULL)
+ return MSM_BOOT_UART_DM_E_INVAL;
+
+ status_reg = readl(MSM_BOOT_UART_DM_MISR(base));
+
+ /* Check for DM_RXSTALE for RX transfer to finish */
+ while (!(status_reg & MSM_BOOT_UART_DM_RXSTALE)) {
+ status_reg = readl(MSM_BOOT_UART_DM_MISR(base));
+ if (!wait)
+ return MSM_BOOT_UART_DM_E_RX_NOT_READY;
+ }
+
+ /* Check for Overrun error. We'll just reset Error Status */
+ if (readl(MSM_BOOT_UART_DM_SR(base)) &
+ MSM_BOOT_UART_DM_SR_UART_OVERRUN) {
+ writel(MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT,
+ MSM_BOOT_UART_DM_CR(base));
+ total_rx_data = rx_data_read = 0;
+ msm_boot_uart_dm_init(base);
+ return MSM_BOOT_UART_DM_E_RX_NOT_READY;
+ }
+
+ /* Read UART_DM_RX_TOTAL_SNAP for actual number of bytes received */
+ if (total_rx_data == 0)
+ total_rx_data = readl(MSM_BOOT_UART_DM_RX_TOTAL_SNAP(base));
+
+ /* Data available in FIFO; read a word. */
+ *data = readl(MSM_BOOT_UART_DM_RF(base, 0));
+
+ /* WAR for http://prism/CR/548280 */
+ if (*data == 0) {
+ return MSM_BOOT_UART_DM_E_RX_NOT_READY;
+ }
+
+ /* increment the total count of chars we've read so far */
+ rx_data_read += FIFO_DATA_SIZE;
+
+ /* actual count of valid data in word */
+ *count = ((total_rx_data < rx_data_read) ?
+ (FIFO_DATA_SIZE - (rx_data_read - total_rx_data)) :
+ FIFO_DATA_SIZE);
+
+ /* If there are still data left in FIFO we'll read them before
+ * initializing RX Transfer again
+ */
+ if (rx_data_read < total_rx_data)
+ return MSM_BOOT_UART_DM_E_SUCCESS;
+
+ msm_boot_uart_dm_init_rx_transfer(base);
+ total_rx_data = rx_data_read = 0;
+
+ return MSM_BOOT_UART_DM_E_SUCCESS;
+}
+
+/**
+ * msm_boot_uart_replace_lr_with_cr - replaces "\n" with "\r\n"
+ * @data_in: characters to be converted
+ * @num_of_chars: no. of characters
+ * @data_out: location where converted chars are stored
+ *
+ * Replace linefeed char "\n" with carriage return + linefeed
+ * "\r\n". Currently keeping it simple than efficient.
+ */
+static unsigned int
+msm_boot_uart_replace_lr_with_cr(char *data_in,
+ int num_of_chars,
+ char *data_out, int *num_of_chars_out)
+{
+ int i = 0, j = 0;
+
+ if ((data_in == NULL) || (data_out == NULL) || (num_of_chars < 0))
+ return MSM_BOOT_UART_DM_E_INVAL;
+
+ for (i = 0, j = 0; i < num_of_chars; i++, j++) {
+ if (data_in[i] == '\n')
+ data_out[j++] = '\r';
+
+ data_out[j] = data_in[i];
+ }
+
+ *num_of_chars_out = j;
+
+ return MSM_BOOT_UART_DM_E_SUCCESS;
+}
+
+/**
+ * msm_boot_uart_dm_write - transmit data
+ * @data: data to transmit
+ * @num_of_chars: no. of bytes to transmit
+ *
+ * Writes the data to the TX FIFO. If no space is available blocks
+ * till space becomes available.
+ */
+static unsigned int
+msm_boot_uart_dm_write(char *data, unsigned int num_of_chars)
+{
+ unsigned int tx_word_count = 0;
+ unsigned int tx_char_left = 0, tx_char = 0;
+ unsigned int tx_word = 0;
+ int i = 0;
+ char *tx_data = NULL;
+ char new_data[1024];
+ unsigned int base = gboard_param->uart_dm_base;
+
+ if ((data == NULL) || (num_of_chars <= 0))
+ return MSM_BOOT_UART_DM_E_INVAL;
+
+ /* Replace line-feed (/n) with carriage-return + line-feed (/r/n) */
+ msm_boot_uart_replace_lr_with_cr(data, num_of_chars, new_data, &i);
+
+ tx_data = new_data;
+ num_of_chars = i;
+
+ /* Write to NO_CHARS_FOR_TX register number of characters
+ * to be transmitted. However, before writing TX_FIFO must
+ * be empty as indicated by TX_READY interrupt in IMR register
+ */
+ /* Check if transmit FIFO is empty.
+ * If not we'll wait for TX_READY interrupt. */
+
+ if (!(readl(MSM_BOOT_UART_DM_SR(base)) & MSM_BOOT_UART_DM_SR_TXEMT)) {
+ while (!(readl(MSM_BOOT_UART_DM_ISR(base)) & MSM_BOOT_UART_DM_TX_READY))
+ __udelay(1);
+ }
+
+ /* We are here. FIFO is ready to be written. */
+ /* Write number of characters to be written */
+ writel(num_of_chars, MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base));
+
+ /* Clear TX_READY interrupt */
+ writel(MSM_BOOT_UART_DM_GCMD_RES_TX_RDY_INT, MSM_BOOT_UART_DM_CR(base));
+
+ /* We use four-character word FIFO. So we need to divide data into
+ * four characters and write in UART_DM_TF register */
+ tx_word_count = (num_of_chars % 4) ? ((num_of_chars / 4) + 1) :
+ (num_of_chars / 4);
+ tx_char_left = num_of_chars;
+
+ for (i = 0; i < (int)tx_word_count; i++) {
+ tx_char = (tx_char_left < 4) ? tx_char_left : 4;
+ PACK_CHARS_INTO_WORDS(tx_data, tx_char, tx_word);
+
+ /* Wait till TX FIFO has space */
+ while (!(readl(MSM_BOOT_UART_DM_SR(base)) & MSM_BOOT_UART_DM_SR_TXRDY))
+ __udelay(1);
+
+ /* TX FIFO has space. Write the chars */
+ writel(tx_word, MSM_BOOT_UART_DM_TF(base, 0));
+ tx_char_left = num_of_chars - (i + 1) * 4;
+ tx_data = tx_data + 4;
+ }
+
+ return MSM_BOOT_UART_DM_E_SUCCESS;
+}
+
+/*
+ * msm_boot_uart_dm_reset - resets UART controller
+ * @base: UART controller base address
+ */
+static unsigned int msm_boot_uart_dm_reset(unsigned int base)
+{
+ writel(MSM_BOOT_UART_DM_CMD_RESET_RX, MSM_BOOT_UART_DM_CR(base));
+ writel(MSM_BOOT_UART_DM_CMD_RESET_TX, MSM_BOOT_UART_DM_CR(base));
+ writel(MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT, MSM_BOOT_UART_DM_CR(base));
+ writel(MSM_BOOT_UART_DM_CMD_RES_TX_ERR, MSM_BOOT_UART_DM_CR(base));
+ writel(MSM_BOOT_UART_DM_CMD_RES_STALE_INT, MSM_BOOT_UART_DM_CR(base));
+
+ return MSM_BOOT_UART_DM_E_SUCCESS;
+}
+
+/*
+ * msm_boot_uart_dm_init - initilaizes UART controller
+ * @uart_dm_base: UART controller base address
+ */
+static unsigned int msm_boot_uart_dm_init(unsigned int uart_dm_base)
+{
+ /* Configure UART mode registers MR1 and MR2 */
+ /* Hardware flow control isn't supported */
+ writel(0x0, MSM_BOOT_UART_DM_MR1(uart_dm_base));
+
+ /* 8-N-1 configuration: 8 data bits - No parity - 1 stop bit */
+ writel(MSM_BOOT_UART_DM_8_N_1_MODE, MSM_BOOT_UART_DM_MR2(uart_dm_base));
+
+ /* Configure Interrupt Mask register IMR */
+ writel(MSM_BOOT_UART_DM_IMR_ENABLED, MSM_BOOT_UART_DM_IMR(uart_dm_base));
+
+ /*
+ * Configure Tx and Rx watermarks configuration registers
+ * TX watermark value is set to 0 - interrupt is generated when
+ * FIFO level is less than or equal to 0
+ */
+ writel(MSM_BOOT_UART_DM_TFW_VALUE, MSM_BOOT_UART_DM_TFWR(uart_dm_base));
+
+ /* RX watermark value */
+ writel(MSM_BOOT_UART_DM_RFW_VALUE, MSM_BOOT_UART_DM_RFWR(uart_dm_base));
+
+ /* Configure Interrupt Programming Register */
+ /* Set initial Stale timeout value */
+ writel(MSM_BOOT_UART_DM_STALE_TIMEOUT_LSB,
+ MSM_BOOT_UART_DM_IPR(uart_dm_base));
+
+ /* Configure IRDA if required */
+ /* Disabling IRDA mode */
+ writel(0x0, MSM_BOOT_UART_DM_IRDA(uart_dm_base));
+
+ /* Configure hunt character value in HCR register */
+ /* Keep it in reset state */
+ writel(0x0, MSM_BOOT_UART_DM_HCR(uart_dm_base));
+
+ /*
+ * Configure Rx FIFO base address
+ * Both TX/RX shares same SRAM and default is half-n-half.
+ * Sticking with default value now.
+ * As such RAM size is (2^RAM_ADDR_WIDTH, 32-bit entries).
+ * We have found RAM_ADDR_WIDTH = 0x7f
+ */
+
+ /* Issue soft reset command */
+ msm_boot_uart_dm_reset(uart_dm_base);
+
+ /* Enable/Disable Rx/Tx DM interfaces */
+ /* Data Mover not currently utilized. */
+ writel(0x0, MSM_BOOT_UART_DM_DMEN(uart_dm_base));
+
+ /* Enable transmitter */
+ writel(MSM_BOOT_UART_DM_CR_TX_ENABLE,
+ MSM_BOOT_UART_DM_CR(uart_dm_base));
+
+ /* Initialize Receive Path */
+ msm_boot_uart_dm_init_rx_transfer(uart_dm_base);
+
+ return 0;
+}
+
+/**
+ * uart_dm_init - initializes UART
+ *
+ * Initializes clocks, GPIO and UART controller.
+ */
+static int uart_dm_init(void)
+{
+ unsigned int dm_base, gsbi_base;
+
+ dm_base = gboard_param->uart_dm_base;
+ gsbi_base = gboard_param->uart_gsbi_base;
+ ipq_configure_gpio(gboard_param->dbg_uart_gpio, NO_OF_DBG_UART_GPIOS);
+
+ /* Configure the uart clock */
+ uart_clock_config(gboard_param->uart_gsbi,
+ gboard_param->mnd_value.m_value,
+ gboard_param->mnd_value.n_value,
+ gboard_param->mnd_value.d_value,
+ gboard_param->clk_dummy);
+
+ writel(GSBI_PROTOCOL_CODE_I2C_UART <<
+ GSBI_CTRL_REG_PROTOCOL_CODE_S,
+ GSBI_CTRL_REG(gsbi_base));
+ writel(UART_DM_CLK_RX_TX_BIT_RATE, MSM_BOOT_UART_DM_CSR(dm_base));
+ /* Intialize UART_DM */
+ msm_boot_uart_dm_init(dm_base);
+
+ return 0;
+}
+
+/**
+ * ipq806x_serial_putc - transmits a character
+ * @c: character to transmit
+ */
+static void ipq806x_serial_putc(char c)
+{
+ msm_boot_uart_dm_write(&c, 1);
+}
+
+/**
+ * ipq806x_serial_puts - transmits a string of data
+ * @s: string to transmit
+ */
+static void ipq806x_serial_puts(const char *s)
+{
+ while (*s != '\0')
+ serial_putc(*s++);
+}
+
+/**
+ * ipq806x_serial_tstc - checks if data available for reading
+ *
+ * Returns 1 if data available, 0 otherwise
+ */
+static int ipq806x_serial_tstc(void)
+{
+ /* Return if data is already read */
+ if (valid_data)
+ return 1;
+
+ /* Read data from the FIFO */
+ if (msm_boot_uart_dm_read(&word, &valid_data, 0) != MSM_BOOT_UART_DM_E_SUCCESS)
+ return 0;
+
+ return 1;
+}
+
+/**
+ * ipq806x_serial_getc - reads a character
+ *
+ * Returns the character read from serial port.
+ */
+static int ipq806x_serial_getc(void)
+{
+ int byte;
+
+ while (!serial_tstc()) {
+ /* wait for incoming data */
+ }
+
+ byte = (int)word & 0xff;
+ word = word >> 8;
+ valid_data--;
+
+ return byte;
+}
+
+static struct serial_device ipq_serial_device = {
+ .name = "ipq_serial",
+ .start = uart_dm_init,
+ .getc = ipq806x_serial_getc,
+ .tstc = ipq806x_serial_tstc,
+ .putc = ipq806x_serial_putc,
+ .puts = ipq806x_serial_puts,
+};
+
+__weak struct serial_device *default_serial_console(void)
+{
+ return &ipq_serial_device;
+}
+
+/**
+ * ipq806x_serial_init - initializes serial controller
+ */
+void ipq806x_serial_initialize(void)
+{
+ serial_register(&ipq_serial_device);
+}
diff --git a/src/mainboard/google/storm/cdp.c b/src/mainboard/google/storm/cdp.c
new file mode 100755
index 0000000..f26ae02
--- /dev/null
+++ b/src/mainboard/google/storm/cdp.c
@@ -0,0 +1,379 @@
+
+/* * Copyright (c) 2012 - 2013 The Linux Foundation. All rights reserved.* */
+
+#include <common.h>
+#include <linux/mtd/ipq_nand.h>
+#include <asm/arch-ipq806x/gpio.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch-ipq806x/clock.h>
+#include <asm/arch-ipq806x/ebi2.h>
+#include <asm/arch-ipq806x/smem.h>
+#include <asm/errno.h>
+#include "ipq806x_board_param.h"
+#include "ipq806x_cdp.h"
+#include <asm/arch-ipq806x/nss/msm_ipq806x_gmac.h>
+#include <asm/arch-ipq806x/timer.h>
+#include <nand.h>
+#include <phy.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+
+/* Watchdog bite time set to default reset value */
+#define RESET_WDT_BITE_TIME 0x31F3
+
+/* Watchdog bark time value is ketp larger than the watchdog timeout
+ * of 0x31F3, effectively disabling the watchdog bark interrupt
+ */
+#define RESET_WDT_BARK_TIME (5 * RESET_WDT_BITE_TIME)
+
+/*
+ * If SMEM is not found, we provide a value, that will prevent the
+ * environment from being written to random location in the flash.
+ *
+ * NAND: In the case of NAND, we do this by setting ENV_RANGE to
+ * zero. If ENV_RANGE < ENV_SIZE, then environment is not written.
+ *
+ * SPI Flash: In the case of SPI Flash, we do this by setting the
+ * flash_index to -1.
+ */
+
+loff_t board_env_offset;
+loff_t board_env_range;
+extern int nand_env_device;
+
+board_ipq806x_params_t *gboard_param;
+extern int ipq_gmac_eth_initialize(const char *ethaddr);
+uchar ipq_def_enetaddr[6] = {0x00, 0x03, 0x7F, 0xBA, 0xDB, 0xAD};
+
+/*******************************************************
+Function description: Board specific initialization.
+I/P : None
+O/P : integer, 0 - no error.
+
+********************************************************/
+static board_ipq806x_params_t *get_board_param(unsigned int machid)
+{
+ unsigned int index = 0;
+
+ for (index = 0; index < NUM_IPQ806X_BOARDS; index++) {
+ if (machid == board_params[index].machid)
+ return &board_params[index];
+ }
+ BUG_ON(index == NUM_IPQ806X_BOARDS);
+ printf("cdp: Invalid machine id 0x%x\n", machid);
+ for (;;);
+}
+
+int board_init()
+{
+ int ret;
+ uint32_t start_blocks;
+ uint32_t size_blocks;
+ loff_t board_env_size;
+ ipq_smem_flash_info_t *sfi = &ipq_smem_flash_info;
+
+ /*
+ * after relocation gboard_param is reset to NULL
+ * initialize again
+ */
+ gd->bd->bi_boot_params = IPQ_BOOT_PARAMS_ADDR;
+ gd->bd->bi_arch_number = smem_get_board_machtype();
+ gboard_param = get_board_param(gd->bd->bi_arch_number);
+
+ /*
+ * Should be inited, before env_relocate() is called,
+ * since env. offset is obtained from SMEM.
+ */
+ ret = smem_ptable_init();
+ if (ret < 0) {
+ printf("cdp: SMEM init failed\n");
+ return ret;
+ }
+
+ ret = smem_get_boot_flash(&sfi->flash_type,
+ &sfi->flash_index,
+ &sfi->flash_chip_select,
+ &sfi->flash_block_size);
+ if (ret < 0) {
+ printf("cdp: get boot flash failed\n");
+ return ret;
+ }
+
+ if (sfi->flash_type == SMEM_BOOT_NAND_FLASH) {
+ nand_env_device = CONFIG_IPQ_NAND_NAND_INFO_IDX;
+ } else if (sfi->flash_type == SMEM_BOOT_SPI_FLASH) {
+ nand_env_device = CONFIG_IPQ_SPI_NAND_INFO_IDX;
+ } else {
+ printf("BUG: unsupported flash type : %d\n", sfi->flash_type);
+ BUG();
+ }
+
+ ret = smem_getpart("0:APPSBLENV", &start_blocks, &size_blocks);
+ if (ret < 0) {
+ printf("cdp: get environment part failed\n");
+ return ret;
+ }
+
+ board_env_offset = ((loff_t) sfi->flash_block_size) * start_blocks;
+ board_env_size = ((loff_t) sfi->flash_block_size) * size_blocks;
+ board_env_range = CONFIG_ENV_SIZE;
+ BUG_ON(board_env_size < CONFIG_ENV_SIZE);
+
+ return 0;
+}
+
+void enable_caches(void)
+{
+ icache_enable();
+ /* When dcache is enabled it causes the tftp timeout CR is raised CR.No: 513868.
+ * disabing dcache now to make tftp to work */
+#if (CONFIG_IPQ_CACHE_ENABLE == 1)
+ dcache_enable();
+#endif
+}
+
+
+/*******************************************************
+Function description: DRAM initialization.
+I/P : None
+O/P : integer, 0 - no error.
+
+********************************************************/
+
+int dram_init(void)
+{
+ struct smem_ram_ptable rtable;
+ int i;
+ int mx = ARRAY_SIZE(rtable.parts);
+
+ if (smem_ram_ptable_init(&rtable) > 0) {
+ gd->ram_size = 0;
+ for (i = 0; i < mx; i++) {
+ if (rtable.parts[i].category == RAM_PARTITION_SDRAM
+ && rtable.parts[i].type == RAM_PARTITION_SYS_MEMORY) {
+ gd->ram_size += rtable.parts[i].size;
+ }
+ }
+ gboard_param->ddr_size = gd->ram_size;
+ } else {
+ gd->ram_size = gboard_param->ddr_size;
+ }
+ return 0;
+}
+
+/*******************************************************
+Function description: initi Dram Bank size
+I/P : None
+O/P : integer, 0 - no error.
+
+********************************************************/
+
+
+void dram_init_banksize(void)
+{
+ gd->bd->bi_dram[0].start = IPQ_KERNEL_START_ADDR;
+ gd->bd->bi_dram[0].size = gboard_param->ddr_size - GENERATED_IPQ_RESERVE_SIZE;
+
+}
+
+/**********************************************************
+Function description: Display board information on console.
+I/P : None
+O/P : integer, 0 - no error.
+
+**********************************************************/
+
+#ifdef CONFIG_DISPLAY_BOARDINFO
+int checkboard(void)
+{
+ printf("Board: %s\n", sysinfo.board_string);
+ return 0;
+}
+#endif /* CONFIG_DISPLAY_BOARDINFO */
+
+void reset_cpu(ulong addr)
+{
+ printf("\nResetting with watch dog!\n");
+
+ writel(0, APCS_WDT0_EN);
+ writel(1, APCS_WDT0_RST);
+ writel(RESET_WDT_BARK_TIME, APCS_WDT0_BARK_TIME);
+ writel(RESET_WDT_BITE_TIME, APCS_WDT0_BITE_TIME);
+ writel(1, APCS_WDT0_EN);
+ writel(1, APCS_WDT0_CPU0_WDOG_EXPIRED_ENABLE);
+
+ for(;;);
+}
+
+static void configure_nand_gpio(void)
+{
+ /* EBI2 CS, CLE, ALE, WE, OE */
+ gpio_tlmm_config(34, 1, 0, GPIO_NO_PULL, GPIO_10MA, GPIO_DISABLE);
+ gpio_tlmm_config(35, 1, 0, GPIO_NO_PULL, GPIO_10MA, GPIO_DISABLE);
+ gpio_tlmm_config(36, 1, 0, GPIO_NO_PULL, GPIO_10MA, GPIO_DISABLE);
+ gpio_tlmm_config(37, 1, 0, GPIO_NO_PULL, GPIO_10MA, GPIO_DISABLE);
+ gpio_tlmm_config(38, 1, 0, GPIO_NO_PULL, GPIO_10MA, GPIO_DISABLE);
+
+ /* EBI2 BUSY */
+ gpio_tlmm_config(39, 1, 0, GPIO_PULL_UP, GPIO_10MA, GPIO_DISABLE);
+
+ /* EBI2 D7 - D0 */
+ gpio_tlmm_config(40, 1, 0, GPIO_KEEPER, GPIO_10MA, GPIO_DISABLE);
+ gpio_tlmm_config(41, 1, 0, GPIO_KEEPER, GPIO_10MA, GPIO_DISABLE);
+ gpio_tlmm_config(42, 1, 0, GPIO_KEEPER, GPIO_10MA, GPIO_DISABLE);
+ gpio_tlmm_config(43, 1, 0, GPIO_KEEPER, GPIO_10MA, GPIO_DISABLE);
+ gpio_tlmm_config(44, 1, 0, GPIO_KEEPER, GPIO_10MA, GPIO_DISABLE);
+ gpio_tlmm_config(45, 1, 0, GPIO_KEEPER, GPIO_10MA, GPIO_DISABLE);
+ gpio_tlmm_config(46, 1, 0, GPIO_KEEPER, GPIO_10MA, GPIO_DISABLE);
+ gpio_tlmm_config(47, 1, 0, GPIO_KEEPER, GPIO_10MA, GPIO_DISABLE);
+}
+
+void board_nand_init(void)
+{
+ struct ebi2cr_regs *ebi2_regs;
+ extern int ipq_spi_init(void);
+
+ if (gboard_param->flashdesc != NOR_MMC) {
+
+ ebi2_regs = (struct ebi2cr_regs *) EBI2CR_BASE;
+
+ nand_clock_config();
+ configure_nand_gpio();
+
+ /* NAND Flash is connected to CS0 */
+ clrsetbits_le32(&ebi2_regs->chip_select_cfg0, CS0_CFG_MASK,
+ CS0_CFG_SERIAL_FLASH_DEVICE);
+
+ ipq_nand_init(IPQ_NAND_LAYOUT_LINUX);
+ }
+
+ ipq_spi_init();
+}
+
+void ipq_get_part_details(void)
+{
+ int ret, i;
+ uint32_t start; /* block number */
+ uint32_t size; /* no. of blocks */
+
+ ipq_smem_flash_info_t *smem = &ipq_smem_flash_info;
+
+ struct { char *name; ipq_part_entry_t *part; } entries[] = {
+ { "0:HLOS", &smem->hlos },
+ { "0:NSS0", &smem->nss[0] },
+ { "0:NSS1", &smem->nss[1] },
+ };
+
+ for (i = 0; i < ARRAY_SIZE(entries); i++) {
+ ret = smem_getpart(entries[i].name, &start, &size);
+ if (ret < 0) {
+ ipq_part_entry_t *part = entries[i].part;
+ printf("cdp: get part failed for %s\n", entries[i].name);
+ part->offset = 0xBAD0FF5E;
+ part->size = 0xBAD0FF5E;
+ }
+ ipq_set_part_entry(smem, entries[i].part, start, size);
+ }
+
+ return;
+}
+
+/*
+ * Get the kernel partition details from SMEM and populate the,
+ * environment with sufficient information for the boot command to
+ * load and execute the kernel.
+ */
+int board_late_init(void)
+{
+ unsigned int machid;
+
+ ipq_get_part_details();
+
+ /* get machine type from SMEM and set in env */
+ machid = gd->bd->bi_arch_number;
+ if (machid != 0) {
+ setenv_addr("machid", (void *)machid);
+ gd->bd->bi_arch_number = machid;
+ }
+
+ return 0;
+}
+
+/*
+ * This function is called in the very beginning.
+ * Retreive the machtype info from SMEM and map the board specific
+ * parameters. Shared memory region at Dram address 0x40400000
+ * contains the machine id/ board type data polulated by SBL.
+ */
+int board_early_init_f(void)
+{
+ gboard_param = get_board_param(smem_get_board_machtype());
+
+ return 0;
+}
+
+/*
+ * Gets the ethernet address from the ART partition table and return the value
+ */
+int get_eth_mac_address(uchar *enetaddr, uint no_of_macs)
+{
+ s32 ret;
+ u32 start_blocks;
+ u32 size_blocks;
+ u32 length = (6 * no_of_macs);
+ u32 flash_type;
+ loff_t art_offset;
+
+ if (ipq_smem_flash_info.flash_type == SMEM_BOOT_SPI_FLASH)
+ flash_type = CONFIG_IPQ_SPI_NAND_INFO_IDX;
+ else if (ipq_smem_flash_info.flash_type == SMEM_BOOT_NAND_FLASH)
+ flash_type = CONFIG_IPQ_NAND_NAND_INFO_IDX;
+ else {
+ printf("Unknown flash type\n");
+ return -EINVAL;
+ }
+
+ ret = smem_getpart("0:ART", &start_blocks, &size_blocks);
+ if (ret < 0) {
+ printf("No ART partition found\n");
+ return ret;
+ }
+
+ /*
+ * ART partition 0th position (6 * 4) 24 bytes will contain the
+ * 4 MAC Address. First 0-5 bytes for GMAC0, Second 6-11 bytes
+ * for GMAC1, 12-17 bytes for GMAC2 and 18-23 bytes for GMAC3
+ */
+ art_offset = ((loff_t) ipq_smem_flash_info.flash_block_size * start_blocks);
+
+ ret = nand_read(&nand_info[flash_type], art_offset, &length, enetaddr);
+ if (ret < 0)
+ printf("ART partition read failed..\n");
+ return ret;
+}
+
+void ipq_configure_gpio(gpio_func_data_t *gpio, uint count)
+{
+ int i;
+
+ for (i = 0; i < count; i++) {
+ gpio_tlmm_config(gpio->gpio, gpio->func, gpio->dir,
+ gpio->pull, gpio->drvstr, gpio->enable);
+ gpio++;
+ }
+}
+
+int board_eth_init(bd_t *bis)
+{
+ int status;
+
+ ipq_gmac_common_init(gboard_param->gmac_cfg);
+
+ ipq_configure_gpio(gboard_param->gmac_gpio,
+ gboard_param->gmac_gpio_count);
+
+ status = ipq_gmac_init(gboard_param->gmac_cfg);
+ return status;
+}
diff --git a/src/soc/qualcomm/ipq806x/Makefile.inc b/src/soc/qualcomm/ipq806x/Makefile.inc
index 1da8489..0ea2996 100644
--- a/src/soc/qualcomm/ipq806x/Makefile.inc
+++ b/src/soc/qualcomm/ipq806x/Makefile.inc
@@ -1,11 +1,8 @@
bootblock-y += cbfs.c
-bootblock-y += timer.c
romstage-y += cbfs.c
-romstage-y += timer.c
ramstage-y += cbfs.c
-ramstage-y += timer.c
ifeq ($(CONFIG_USE_BLOBS),y)
diff --git a/src/soc/qualcomm/ipq806x/cbfs.c b/src/soc/qualcomm/ipq806x/cbfs.c
index 97ae548..eec9b73 100644
--- a/src/soc/qualcomm/ipq806x/cbfs.c
+++ b/src/soc/qualcomm/ipq806x/cbfs.c
@@ -24,3 +24,12 @@ int init_default_cbfs_media(struct cbfs_media *media)
{
return 0;
}
+
+/*
+ * Temporary change to make sure storm code still builds. Will be dropped
+ * shortly.
+ */
+#include <delay.h> /* This driver serves as a CBFS media source. */
+void init_timer(void)
+{
+}
diff --git a/src/soc/qualcomm/ipq806x/cdp.h b/src/soc/qualcomm/ipq806x/cdp.h
new file mode 100644
index 0000000..4ae476a
--- /dev/null
+++ b/src/soc/qualcomm/ipq806x/cdp.h
@@ -0,0 +1,127 @@
+/* * Copyright (c) 2012 The Linux Foundation. All rights reserved.* */
+
+
+#ifndef _IPQ806X_CDP_H_
+#define _IPQ806X_CDP_H_
+
+#include <phy.h>
+
+unsigned int smem_get_board_machtype(void);
+
+typedef struct {
+ unsigned int gpio;
+ unsigned int func;
+ unsigned int dir;
+ unsigned int pull;
+ unsigned int drvstr;
+ unsigned int enable;
+} gpio_func_data_t;
+
+typedef struct {
+ unsigned int m_value;
+ unsigned int n_value;
+ unsigned int d_value;
+} uart_clk_mnd_t;
+
+/* SPI Mode */
+
+typedef enum {
+ NOR_SPI_MODE_0,
+ NOR_SPI_MODE_1,
+ NOR_SPI_MODE_2,
+ NOR_SPI_MODE_3,
+} spi_mode;
+
+/* SPI GSBI Bus number */
+
+typedef enum {
+ GSBI_BUS_5 = 0,
+ GSBI_BUS_6,
+ GSBI_BUS_7,
+} spi_gsbi_bus_num;
+
+/* SPI Chip selects */
+
+typedef enum {
+ SPI_CS_0 ,
+ SPI_CS_1,
+ SPI_CS_2,
+ SPI_CS_3,
+} spi_cs;
+
+/* Flash Types */
+
+typedef enum {
+ ONLY_NAND,
+ ONLY_NOR,
+ NAND_NOR,
+ NOR_MMC,
+} flash_desc;
+
+#define NO_OF_DBG_UART_GPIOS 2
+
+#define SPI_NOR_FLASH_VENDOR_MICRON 0x1
+#define SPI_NOR_FLASH_VENDOR_SPANSION 0x2
+
+/* SPI parameters */
+
+typedef struct {
+ spi_mode mode;
+ spi_gsbi_bus_num bus_number;
+ spi_cs chip_select;
+ int vendor;
+} spinorflash_params_t;
+
+typedef struct {
+ uint count;
+ u8 addr[7];
+} ipq_gmac_phy_addr_t;
+
+typedef struct {
+ uint base;
+ int unit;
+ uint is_macsec;
+ uint mac_pwr0;
+ uint mac_pwr1;
+ uint mac_conn_to_phy;
+ phy_interface_t phy;
+ ipq_gmac_phy_addr_t phy_addr;
+} ipq_gmac_board_cfg_t;
+
+#define IPQ_GMAC_NMACS 4
+
+/* Board specific parameters */
+typedef struct {
+ unsigned int machid;
+ unsigned int ddr_size;
+ unsigned int uart_gsbi;
+ unsigned int uart_gsbi_base;
+ unsigned int uart_dm_base;
+ unsigned int clk_dummy;
+ uart_clk_mnd_t mnd_value;
+ unsigned int gmac_gpio_count;
+ gpio_func_data_t *gmac_gpio;
+ ipq_gmac_board_cfg_t gmac_cfg[IPQ_GMAC_NMACS];
+ flash_desc flashdesc;
+ spinorflash_params_t flash_param;
+ gpio_func_data_t dbg_uart_gpio[NO_OF_DBG_UART_GPIOS];
+} __attribute__ ((__packed__)) board_ipq806x_params_t;
+
+extern board_ipq806x_params_t *gboard_param;
+
+static inline int gmac_cfg_is_valid(ipq_gmac_board_cfg_t *cfg)
+{
+ /*
+ * 'cfg' is valid if and only if
+ * unit number is non-negative and less than IPQ_GMAC_NMACS.
+ * 'cfg' pointer lies within the array range of
+ * board_ipq806x_params_t->gmac_cfg[]
+ */
+ return ((cfg >= &gboard_param->gmac_cfg[0]) &&
+ (cfg < &gboard_param->gmac_cfg[IPQ_GMAC_NMACS]) &&
+ (cfg->unit >= 0) && (cfg->unit < IPQ_GMAC_NMACS));
+}
+
+unsigned int get_board_index(unsigned int machid);
+void ipq_configure_gpio(gpio_func_data_t *gpio, uint count);
+#endif
diff --git a/src/soc/qualcomm/ipq806x/clock.c b/src/soc/qualcomm/ipq806x/clock.c
new file mode 100644
index 0000000..882be02
--- /dev/null
+++ b/src/soc/qualcomm/ipq806x/clock.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2012 - 2013 The Linux Foundation. All rights reserved.
+ */
+
+#include <common.h>
+#include <asm/arch-ipq806x/clock.h>
+#include <asm/arch-ipq806x/nss/clock.h>
+#include <asm/arch-ipq806x/iomap.h>
+#include <asm/io.h>
+
+/**
+ * uart_pll_vote_clk_enable - enables PLL8
+ */
+void uart_pll_vote_clk_enable(unsigned int clk_dummy)
+{
+ setbits_le32(BB_PLL_ENA_SC0_REG, BIT(8));
+
+ if (!clk_dummy)
+ while((readl(PLL_LOCK_DET_STATUS_REG) & BIT(8)) == 0);
+}
+
+/**
+ * uart_set_rate_mnd - configures divider M and D values
+ *
+ * Sets the M, D parameters of the divider to generate the GSBI UART
+ * apps clock.
+ */
+static void uart_set_rate_mnd(unsigned int gsbi_port, unsigned int m,
+ unsigned int n)
+{
+ /* Assert MND reset. */
+ setbits_le32(GSBIn_UART_APPS_NS_REG(gsbi_port), BIT(7));
+ /* Program M and D values. */
+ writel(MD16(m, n), GSBIn_UART_APPS_MD_REG(gsbi_port));
+ /* Deassert MND reset. */
+ clrbits_le32(GSBIn_UART_APPS_NS_REG(gsbi_port), BIT(7));
+}
+
+/**
+ * uart_branch_clk_enable_reg - enables branch clock
+ *
+ * Enables branch clock for GSBI UART port.
+ */
+static void uart_branch_clk_enable_reg(unsigned int gsbi_port)
+{
+ setbits_le32(GSBIn_UART_APPS_NS_REG(gsbi_port), BIT(9));
+}
+
+/**
+ * uart_local_clock_enable - configures N value and enables root clocks
+ *
+ * Sets the N parameter of the divider and enables root clock and
+ * branch clocks for GSBI UART port.
+ */
+static void uart_local_clock_enable(unsigned int gsbi_port, unsigned int n,
+ unsigned int m)
+{
+ unsigned int reg_val, uart_ns_val;
+ void *const reg = (void *)GSBIn_UART_APPS_NS_REG(gsbi_port);
+
+ /*
+ * Program the NS register, if applicable. NS registers are not
+ * set in the set_rate path because power can be saved by deferring
+ * the selection of a clocked source until the clock is enabled.
+ */
+ reg_val = readl(reg); // REG(0x29D4+(0x20*((n)-1)))
+ reg_val &= ~(Uart_clk_ns_mask);
+ uart_ns_val = NS(BIT_POS_31,BIT_POS_16,n,m, 5, 4, 3, 1, 2, 0,3);
+ reg_val |= (uart_ns_val & Uart_clk_ns_mask);
+ writel(reg_val,reg);
+
+ /* enable MNCNTR_EN */
+ reg_val = readl(reg);
+ reg_val |= BIT(8);
+ writel(reg_val, reg);
+
+ /* set source to PLL8 running @384MHz */
+ reg_val = readl(reg);
+ reg_val |= 0x3;
+ writel(reg_val, reg);
+
+ /* Enable root. */
+ reg_val |= Uart_en_mask;
+ writel(reg_val, reg);
+ uart_branch_clk_enable_reg(gsbi_port);
+}
+
+/**
+ * uart_set_gsbi_clk - enables HCLK for UART GSBI port
+ */
+static void uart_set_gsbi_clk(unsigned int gsbi_port)
+{
+ setbits_le32(GSBIn_HCLK_CTL_REG(gsbi_port), BIT(4));
+}
+
+/**
+ * uart_clock_config - configures UART clocks
+ *
+ * Configures GSBI UART dividers, enable root and branch clocks.
+ */
+void uart_clock_config(unsigned int gsbi_port, unsigned int m,
+ unsigned int n, unsigned int d, unsigned int clk_dummy)
+{
+ uart_set_rate_mnd(gsbi_port, m, d);
+ uart_pll_vote_clk_enable(clk_dummy);
+ uart_local_clock_enable(gsbi_port, n, m);
+ uart_set_gsbi_clk(gsbi_port);
+}
+
+/**
+ * nand_clock_config - configure NAND controller clocks
+ *
+ * Enable clocks to EBI2. Must be invoked before touching EBI2
+ * registers.
+ */
+void nand_clock_config(void)
+{
+ writel(CLK_BRANCH_ENA(1) | ALWAYS_ON_CLK_BRANCH_ENA(1),
+ EBI2_CLK_CTL_REG);
+
+ /* Wait for clock to stabilize. */
+ udelay(10);
+}
diff --git a/src/soc/qualcomm/ipq806x/clock.h b/src/soc/qualcomm/ipq806x/clock.h
new file mode 100644
index 0000000..263b81b
--- /dev/null
+++ b/src/soc/qualcomm/ipq806x/clock.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Source : APQ8064 LK Boot
+ *
+ * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PLATFORM_IPQ860X_CLOCK_H_
+#define __PLATFORM_IPQ860X_CLOCK_H_
+
+#include <asm/io.h>
+/* UART clock @ 7.3728 MHz */
+#define UART_DM_CLK_RX_TX_BIT_RATE 0xCC
+
+/* UART specific definitions */
+
+#define BIT(s) (1<<s)
+#define Uart_ns_val NS(BIT_POS_31,BIT_POS_16,N_VALUE,M_VALUE, 5, 4, 3, 1, 2, 0,3)
+#define Uart_clk_ns_mask (BM(BIT_POS_31, BIT_POS_16) | BM(BIT_POS_6, BIT_POS_0))
+#define Uart_mnd_en_mask BIT(8) * !!(625)
+#define Uart_en_mask BIT(11)
+#define MD16(m, n) (BVAL(BIT_POS_31, BIT_POS_16, m) | BVAL(BIT_POS_15, BIT_POS_0, ~(n)))
+#define Uart_ns_val_rumi NS(BIT_POS_31, BIT_POS_16, N_VALUE, M_VALUE, 5, 4, 3, 1, 2, 0,0)
+#define GSBIn_UART_APPS_MD_REG(n) REG(0x29D0+(0x20*((n)-1)))
+#define GSBIn_UART_APPS_NS_REG(n) REG(0x29D4+(0x20*((n)-1)))
+#define GSBIn_HCLK_CTL_REG(n) REG(0x29C0+(0x20*((n)-1)))
+#define BB_PLL_ENA_SC0_REG REG(0x34C0)
+#define BB_PLL8_STATUS_REG REG(0x3158)
+#define REG(off) (MSM_CLK_CTL_BASE + (off))
+#define PLL8_STATUS_BIT 16
+
+#define PLL_LOCK_DET_STATUS_REG REG(0x03420)
+#define SFAB_AHB_S3_FCLK_CTL_REG REG(0x0216C)
+#define CFPB_CLK_NS_REG REG(0x0264C)
+#define CFPB0_HCLK_CTL_REG REG(0x02650)
+#define SFAB_CFPB_S_HCLK_CTL_REG REG(0x026C0)
+#define CFPB_SPLITTER_HCLK_CTL_REG REG(0x026E0)
+#define EBI2_CLK_CTL_REG REG(0x03B00)
+
+#define ALWAYS_ON_CLK_BRANCH_ENA(i) ((i) << 8)
+
+#define CLK_BRANCH_ENA_MASK 0x00000010
+#define CLK_BRANCH_ENA_ENABLE 0x00000010
+#define CLK_BRANCH_ENA_DISABLE 0x00000000
+#define CLK_BRANCH_ENA(i) ((i) << 4)
+
+/* Register: CFPB_CLK_NS */
+#define CLK_DIV_MASK 0x00000003
+#define CLK_DIV_DIV_1 0x00000000
+#define CLK_DIV_DIV_2 0x00000001
+#define CLK_DIV_DIV_3 0x00000002
+#define CLK_DIV_DIV_4 0x00000003
+#define CLK_DIV(i) ((i) << 0)
+
+#define MN_MODE_DUAL_EDGE 0x2
+#define BIT_POS_31 31
+#define BIT_POS_16 16
+#define BIT_POS_6 6
+#define BIT_POS_0 0
+#define BIT_POS_15 15
+
+#define BM(m, l) (((((unsigned int)-1) << (31-m)) >> (31-m+l)) << l)
+#define BVAL(m, l, val) (((val) << l) & BM(m, l))
+
+/* MD Registers */
+#define MD4(m_lsb, m, n_lsb, n) \
+ (BVAL((m_lsb+3), m_lsb, m) | BVAL((n_lsb+3), n_lsb, ~(n)))
+
+#define MD8(m_lsb, m, n_lsb, n) \
+ (BVAL((m_lsb+7), m_lsb, m) | BVAL((n_lsb+7), n_lsb, ~(n)))
+
+/* NS Registers */
+#define NS(n_msb, n_lsb, n, m, mde_lsb, d_msb, d_lsb, d, s_msb, s_lsb, s) \
+ (BVAL(n_msb, n_lsb, ~(n-m)) \
+ | (BVAL((mde_lsb+1), mde_lsb, MN_MODE_DUAL_EDGE) * !!(n)) \
+ | BVAL(d_msb, d_lsb, (d-1)) | BVAL(s_msb, s_lsb, s))
+
+#define NS_MM(n_msb, n_lsb, n, m, d_msb, d_lsb, d, s_msb, s_lsb, s) \
+ (BVAL(n_msb, n_lsb, ~(n-m)) | BVAL(d_msb, d_lsb, (d-1)) \
+ | BVAL(s_msb, s_lsb, s))
+
+#define NS_DIVSRC(d_msb , d_lsb, d, s_msb, s_lsb, s) \
+ (BVAL(d_msb, d_lsb, (d-1)) | BVAL(s_msb, s_lsb, s))
+
+#define NS_DIV(d_msb , d_lsb, d) \
+ BVAL(d_msb, d_lsb, (d-1))
+
+#define NS_SRC_SEL(s_msb, s_lsb, s) \
+ BVAL(s_msb, s_lsb, s)
+
+#define GMAC_AHB_RESET 0x903E24
+
+#define SRC_SEL_PLL0 (0x2 << 0)
+#define MNCNTR_MODE_DUAL_EDGE (0x2 << 5)
+#define MNCNTR_ENABLE (0x1 << 8)
+#define MNCNTR_RST_ACTIVE (0x1 << 7)
+#define N_VAL 15
+
+#define GMAC_CORE_RESET(n) \
+ ((void *)(0x903CBC + ((n) * 0x20)))
+
+#define GMACSEC_CORE_RESET(n) \
+ ((void *)(0x903E28 + ((n - 1) * 4)))
+
+#define GMAC_COREn_CLCK_SRC_CTL(N) \
+ (0x00900000 + (0x3CA0 + (32*(N-1))))
+
+#define GMAC_COREn_CLCK_SRC0_MD(N) \
+ (0x00900000 + (0x3CA4 + (32*(N-1))))
+
+#define GMAC_COREn_CLCK_SRC1_MD(N) \
+ (0x00900000 + (0x3CA8 + (32*(N-1))))
+
+#define GMAC_COREn_CLCK_SRC0_NS(N) \
+ (0x00900000 + (0x3CAC + (32*(N-1))))
+
+#define GMAC_COREn_CLCK_SRC1_NS(N) \
+ (0x00900000 + (0x3CB0 + (32*(N-1))))
+
+#define DISABLE_DUAL_MN8_SEL (0)
+#define DISABLE_CLK_LOW_PWR (0 << 2)
+#define GMAC_CORE_CLCK_ROOT_ENABLE (1 << 1)
+
+/* GMAC_COREn_CLK_SRC[0,1]_MD register bits (Assuming 133MHz) */
+#define GMAC_CORE_CLCK_M 0x32
+#define GMAC_CORE_CLCK_D 0 /* NOT(2*D) value */
+#define GMAC_CORE_CLCK_M_SHIFT 16
+#define GMAC_CORE_CLCK_D_SHIFT 0
+#define GMAC_CORE_CLCK_M_VAL (GMAC_CORE_CLCK_M << GMAC_CORE_CLCK_M_SHIFT)
+#define GMAC_CORE_CLCK_D_VAL (GMAC_CORE_CLCK_D << GMAC_CORE_CLCK_D_SHIFT)
+
+/* GMAC_COREn_CLK_SRC[0,1]_NS register bits (Assuming 133MHz) */
+#define GMAC_CORE_CLCK_N 0x4 /* NOT(N-M) value, N=301 */
+#define GMAC_CORE_CLCK_N_SHIFT 16
+#define GMAC_CORE_CLCK_N_VAL (GMAC_CORE_CLCK_N << GMAC_CORE_CLCK_N_SHIFT)
+#define GMAC_CORE_CLCK_MNCNTR_EN 0x00000100 /* Enable M/N counter */
+#define GMAC_CORE_CLCK_MNCNTR_RST 0x00000080 /* Activate reset for M/N counter */
+#define GMAC_CORE_CLCK_MNCNTR_MODE_MASK 0x00000060 /* M/N counter mode mask */
+#define GMAC_CORE_CLCK_MNCNTR_MODE_SHIFT 5
+#define GMAC_CORE_CLCK_MNCNTR_MODE_DUAL (2 << GMAC_CORE_CLCK_MNCNTR_MODE_SHIFT) /* M/N counter mode dual-edge */
+#define GMAC_CORE_CLCK_PRE_DIV_SEL_MASK 0x00000018 /* Pre divider select mask */
+#define GMAC_CORE_CLCK_PRE_DIV_SEL_SHIFT 3
+#define GMAC_CORE_CLCK_PRE_DIV_SEL_BYP (0 << GMAC_CORE_CLCK_PRE_DIV_SEL_SHIFT) /* Pre divider bypass */
+#define GMAC_CORE_CLCK_SRC_SEL_MASK 0x00000007 /* clk source Mux select mask */
+#define GMAC_CORE_CLCK_SRC_SEL_SHIFT 0
+#define GMAC_CORE_CLCK_SRC_SEL_PLL0 (2 << GMAC_CORE_CLCK_SRC_SEL_SHIFT) /* output of clk source Mux is PLL0 */
+#define GMAC_COREn_CLCK_CTL(N) (0x00900000 + (0x3CB4 + (32*(N-1))))
+
+#define GMAC_COREn_CLCK_INV_DISABLE (0 << 5)
+#define GMAC_COREn_CLCK_BRANCH_ENA (1 << 4)
+
+
+/* Uart specific clock settings */
+
+void uart_pll_vote_clk_enable(unsigned int);
+void uart_clock_config(unsigned int gsbi_port, unsigned int m, unsigned int n,
+ unsigned int d, unsigned int clk_dummy);
+void nand_clock_config(void);
+
+#endif /* __PLATFORM_IPQ860X_CLOCK_H_ */
diff --git a/src/soc/qualcomm/ipq806x/gpio.c b/src/soc/qualcomm/ipq806x/gpio.c
new file mode 100644
index 0000000..6e4140e
--- /dev/null
+++ b/src/soc/qualcomm/ipq806x/gpio.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <asm/arch-ipq806x/iomap.h>
+#include <asm/arch-ipq806x/gpio.h>
+#include <asm/io.h>
+
+/*******************************************************
+Function description: configure GPIO functinality
+Arguments :
+unsigned int gpio - Gpio number
+unsigned int func - Functionality number
+unsigned int dir - direction 0- i/p, 1- o/p
+unsigned int pull - pull up/down, no pull range(0-3)
+unsigned int drvstr - range (0 - 7)-> (2- 16)MA steps of 2
+unsigned int enable - 1 - Disable, 2- Enable.
+
+Return : None
+*******************************************************/
+
+
+void gpio_tlmm_config(unsigned int gpio, unsigned int func,
+ unsigned int dir, unsigned int pull,
+ unsigned int drvstr, unsigned int enable)
+{
+ unsigned int val = 0;
+ val |= pull;
+ val |= func << 2;
+ val |= drvstr << 6;
+ val |= enable << 9;
+ unsigned int *addr = (unsigned int *)GPIO_CONFIG_ADDR(gpio);
+ writel(val, addr);
+ return;
+}
+
diff --git a/src/soc/qualcomm/ipq806x/gpio.h b/src/soc/qualcomm/ipq806x/gpio.h
new file mode 100644
index 0000000..e2b281e
--- /dev/null
+++ b/src/soc/qualcomm/ipq806x/gpio.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012 The Linux Foundation. All rights reserved.*
+ Source : APQ8064 LK Boot
+
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PLATFORM_AKRONITE_GPIO_H_
+#define __PLATFORM_AKRONITE_GPIO_H_
+
+/* GPIO TLMM: Direction */
+#define GPIO_INPUT 0
+#define GPIO_OUTPUT 1
+
+/* GPIO TLMM: Pullup/Pulldown */
+#define GPIO_NO_PULL 0
+#define GPIO_PULL_DOWN 1
+#define GPIO_KEEPER 2
+#define GPIO_PULL_UP 3
+
+/* GPIO TLMM: Drive Strength */
+#define GPIO_2MA 0
+#define GPIO_4MA 1
+#define GPIO_6MA 2
+#define GPIO_8MA 3
+#define GPIO_10MA 4
+#define GPIO_12MA 5
+#define GPIO_14MA 6
+#define GPIO_16MA 7
+
+/* GPIO TLMM: Status */
+#define GPIO_ENABLE 0
+#define GPIO_DISABLE 1
+
+void gpio_tlmm_config(unsigned int gpio, unsigned int func,
+ unsigned int dir, unsigned int pull,
+ unsigned int drvstr, unsigned int enable);
+#endif
diff --git a/src/soc/qualcomm/ipq806x/gsbi.h b/src/soc/qualcomm/ipq806x/gsbi.h
new file mode 100644
index 0000000..d2ba2b3
--- /dev/null
+++ b/src/soc/qualcomm/ipq806x/gsbi.h
@@ -0,0 +1,37 @@
+/*
+* Copyright (c) 2004-2011 Atheros Communications Inc.
+* Copyright (c) 2011-2012 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for any
+* purpose with or without fee is hereby granted, provided that the above
+* copyright notice and this permission notice appear in all copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+
+#ifndef __GSBI_H_
+#define __GSBI_H_
+
+#include <asm/io.h>
+
+/* GSBI Registers */
+#define GSBI_CTRL_REG(base) ((base) + 0x0)
+
+#define GSBI_CTRL_REG_PROTOCOL_CODE_S 4
+#define GSBI_PROTOCOL_CODE_I2C 0x2
+#define GSBI_PROTOCOL_CODE_SPI 0x3
+#define GSBI_PROTOCOL_CODE_UART_FLOW 0x4
+#define GSBI_PROTOCOL_CODE_I2C_UART 0x6
+
+#define GSBI_HCLK_CTL_S 4
+#define GSBI_HCLK_CTL_CLK_ENA 0x1
+
+#endif
+
diff --git a/src/soc/qualcomm/ipq806x/iomap.h b/src/soc/qualcomm/ipq806x/iomap.h
new file mode 100644
index 0000000..514c6a7
--- /dev/null
+++ b/src/soc/qualcomm/ipq806x/iomap.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2012 - 2013 The Linux Foundation. All rights reserved.
+ *
+ * Copyright (c) 2008, Google Inc.
+ * All rights reserved.
+ *
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _PLATFORM_MSM8960_IOMAP_H_
+#define _PLATFORM_MSM8960_IOMAP_H_
+
+#include <configs/ipq806x_cdp.h>
+#define MSM_CLK_CTL_BASE 0x00900000
+
+#define MSM_TMR_BASE 0x0200A000
+#define MSM_GPT_BASE (MSM_TMR_BASE + 0x04)
+#define MSM_DGT_BASE (MSM_TMR_BASE + 0x24)
+
+#define GPT_REG(off) (MSM_GPT_BASE + (off))
+#define DGT_REG(off) (MSM_DGT_BASE + (off))
+
+#define APCS_WDT0_EN (MSM_TMR_BASE + 0x0040)
+#define APCS_WDT0_RST (MSM_TMR_BASE + 0x0038)
+#define APCS_WDT0_BARK_TIME (MSM_TMR_BASE + 0x004C)
+#define APCS_WDT0_BITE_TIME (MSM_TMR_BASE + 0x005C)
+
+#define APCS_WDT0_CPU0_WDOG_EXPIRED_ENABLE (MSM_CLK_CTL_BASE + 0x3820)
+
+#define GPT_MATCH_VAL GPT_REG(0x0000)
+#define GPT_COUNT_VAL GPT_REG(0x0004)
+#define GPT_ENABLE GPT_REG(0x0008)
+#define GPT_CLEAR GPT_REG(0x000C)
+
+#define GPT1_MATCH_VAL GPT_REG(0x00010)
+#define GPT1_COUNT_VAL GPT_REG(0x00014)
+#define GPT1_ENABLE GPT_REG(0x00018)
+#define GPT1_CLEAR GPT_REG(0x0001C)
+
+#define DGT_MATCH_VAL DGT_REG(0x0000)
+#define DGT_COUNT_VAL DGT_REG(0x0004)
+#define DGT_ENABLE DGT_REG(0x0008)
+#define DGT_CLEAR DGT_REG(0x000C)
+#define DGT_CLK_CTL DGT_REG(0x0010)
+
+#define TLMM_BASE_ADDR 0x00800000
+#define GPIO_CONFIG_ADDR(x) (TLMM_BASE_ADDR + 0x1000 + (x)*0x10)
+#define GPIO_IN_OUT_ADDR(x) (TLMM_BASE_ADDR + 0x1004 + (x)*0x10)
+
+#define GSBI_1 1
+#define GSBI_2 2
+#define GSBI_4 4
+#define GSBI_2 2
+#define UART1_DM_BASE 0x12450000
+#define UART_GSBI1_BASE 0x12440000
+#define UART2_DM_BASE 0x12490000
+#define UART_GSBI2_BASE 0x12480000
+#define UART4_DM_BASE 0x16340000
+#define UART_GSBI4_BASE 0x16300000
+
+#define UART2_DM_BASE 0x12490000
+#define UART_GSBI2_BASE 0x12480000
+
+#endif
diff --git a/src/soc/qualcomm/ipq806x/timer.c b/src/soc/qualcomm/ipq806x/timer.c
index c4e250e..691ccbd 100644
--- a/src/soc/qualcomm/ipq806x/timer.c
+++ b/src/soc/qualcomm/ipq806x/timer.c
@@ -1,28 +1,139 @@
/*
- * This file is part of the coreboot project.
+ * Copyright (c) 2012 - 2013 The Linux Foundation. All rights reserved.
+ * Source : APQ8064 LK boot
*
- * Copyright 2013 Google Inc.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
- * 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; version 2 of the License.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
*
- * 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.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <asm/arch-ipq806x/iomap.h>
+#include <asm/io.h>
+#include <common.h>
+#include <asm/types.h>
+#include <asm/arch-ipq806x/timer.h>
+
+static ulong timestamp;
+static ulong lastinc;
+
+#define GPT_FREQ_KHZ 32
+#define GPT_FREQ (GPT_FREQ_KHZ * 1000) /* 32 KHz */
+
+/**
+ * timer_init - initialize timer
+ */
+int timer_init(void)
+{
+ writel(0, GPT_ENABLE);
+ writel(GPT_ENABLE_EN, GPT_ENABLE);
+ return 0;
+}
+
+/**
+ * get_timer - returns time lapsed
+ * @base: base/start time
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Returns time lapsed, since the specified base time value.
*/
+ulong get_timer(ulong base)
+{
+ return get_timer_masked() - base;
+}
+
+/**
+ * __udelay - generates micro second delay.
+ * @usec: delay duration in microseconds
+ *
+ * With 32KHz clock, minimum possible delay is 31.25 Micro seconds and
+ * its multiples. In Rumi GPT clock is 32 KHz
+ */
+void __udelay(unsigned long usec)
+{
+ unsigned int val;
+ ulong now, last;
+ ulong runcount;
-#include <console/console.h>
-#include <timer.h>
-#include <delay.h>
-#include <thread.h>
+ usec = (usec + GPT_FREQ_KHZ - 1) / GPT_FREQ_KHZ;
+ last = readl(GPT_COUNT_VAL);
+ runcount = last;
+ val = usec + last;
+
+ do {
+ now = readl(GPT_COUNT_VAL);
+ if (last > now)
+ runcount += ((GPT_FREQ - last) + now);
+ else
+ runcount += (now - last);
+ last = now;
+ } while (runcount < val);
+}
-void init_timer(void)
+
+inline ulong gpt_to_sys_freq(unsigned int gpt)
+{
+ /*
+ * get_timer() expects the timer increments to be in terms
+ * of CONFIG_SYS_HZ. Convert GPT timer values to CONFIG_SYS_HZ
+ * units.
+ */
+ return (((ulong)gpt) / (GPT_FREQ / CONFIG_SYS_HZ));
+}
+
+/**
+ * get_timer_masked - returns current ticks
+ *
+ * Returns the current timer ticks, since boot.
+ */
+ulong get_timer_masked(void)
+{
+ ulong now = gpt_to_sys_freq(readl(GPT_COUNT_VAL));
+
+ if (lastinc <= now) { /* normal mode (non roll) */
+ /* normal mode */
+ timestamp += now - lastinc;
+ /* move stamp forward with absolute diff ticks */
+ } else { /* we have overflow of the count down timer */
+ timestamp += now + (TIMER_LOAD_VAL - lastinc);
+ }
+
+ lastinc = now;
+
+ return timestamp;
+}
+
+unsigned long long get_ticks(void)
{
+ return readl(GPT_COUNT_VAL);
}
+/*
+ * Return the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+ return GPT_FREQ;
+}
diff --git a/src/soc/qualcomm/ipq806x/timer.h b/src/soc/qualcomm/ipq806x/timer.h
new file mode 100644
index 0000000..4e1ef34
--- /dev/null
+++ b/src/soc/qualcomm/ipq806x/timer.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define TIMER_LOAD_VAL 0x21
+
+#define GPT_ENABLE_CLR_ON_MATCH_EN 2
+#define GPT_ENABLE_EN 1
+#define DGT_ENABLE_CLR_ON_MATCH_EN 2
+#define DGT_ENABLE_EN 1
+
+#define SPSS_TIMER_STATUS_DGT_EN (1 << 0)
+
+
diff --git a/src/soc/qualcomm/ipq806x/uart.h b/src/soc/qualcomm/ipq806x/uart.h
new file mode 100644
index 0000000..6fff046
--- /dev/null
+++ b/src/soc/qualcomm/ipq806x/uart.h
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2012 The Linux Foundation. All rights reserved.*
+ *
+ * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __UART_DM_H__
+#define __UART_DM_H__
+
+#include <asm/io.h>
+#include "common.h"
+#define MSM_BOOT_UART_DM_EXTR_BITS(value, start_pos, end_pos) \
+ ((value << (32 - end_pos))\
+ >> (32 - (end_pos - start_pos)))
+
+
+extern void dsb(void);
+#define PACK_CHARS_INTO_WORDS(a, cnt, word) { \
+ word = 0; \
+ int j; \
+ for(j=0; j < (int)cnt; j++) { \
+ word |= (a[j] & 0xff)<< (j * 8);\
+ } \
+ }
+
+extern void __udelay(unsigned long usec);
+
+
+enum MSM_BOOT_UART_DM_PARITY_MODE {
+ MSM_BOOT_UART_DM_NO_PARITY,
+ MSM_BOOT_UART_DM_ODD_PARITY,
+ MSM_BOOT_UART_DM_EVEN_PARITY,
+ MSM_BOOT_UART_DM_SPACE_PARITY
+};
+
+/* UART Stop Bit Length */
+enum MSM_BOOT_UART_DM_STOP_BIT_LEN {
+ MSM_BOOT_UART_DM_SBL_9_16,
+ MSM_BOOT_UART_DM_SBL_1,
+ MSM_BOOT_UART_DM_SBL_1_9_16,
+ MSM_BOOT_UART_DM_SBL_2
+};
+
+/* UART Bits per Char */
+enum MSM_BOOT_UART_DM_BITS_PER_CHAR {
+ MSM_BOOT_UART_DM_5_BPS,
+ MSM_BOOT_UART_DM_6_BPS,
+ MSM_BOOT_UART_DM_7_BPS,
+ MSM_BOOT_UART_DM_8_BPS
+};
+
+/* 8-N-1 Configuration */
+#define MSM_BOOT_UART_DM_8_N_1_MODE (MSM_BOOT_UART_DM_NO_PARITY | \
+ (MSM_BOOT_UART_DM_SBL_1 << 2) | \
+ (MSM_BOOT_UART_DM_8_BPS << 4))
+
+/* UART_DM Registers */
+
+/* UART Operational Mode Register */
+#define MSM_BOOT_UART_DM_MR1(base) ((base) + 0x00)
+#define MSM_BOOT_UART_DM_MR2(base) ((base) + 0x04)
+#define MSM_BOOT_UART_DM_RXBRK_ZERO_CHAR_OFF (1 << 8)
+#define MSM_BOOT_UART_DM_LOOPBACK (1 << 7)
+
+/* UART Clock Selection Register */
+#if PERIPH_BLK_BLSP
+#define MSM_BOOT_UART_DM_CSR(base) ((base) + 0xA0)
+#else
+#define MSM_BOOT_UART_DM_CSR(base) ((base) + 0x08)
+#endif
+
+/* UART DM TX FIFO Registers - 4 */
+#if PERIPH_BLK_BLSP
+#define MSM_BOOT_UART_DM_TF(base, x) ((base) + 0x100+(4*(x)))
+#else
+#define MSM_BOOT_UART_DM_TF(base, x) ((base) + 0x70+(4*(x)))
+#endif
+
+/* UART Command Register */
+#if PERIPH_BLK_BLSP
+#define MSM_BOOT_UART_DM_CR(base) ((base) + 0xA8)
+#else
+#define MSM_BOOT_UART_DM_CR(base) ((base) + 0x10)
+#endif
+#define MSM_BOOT_UART_DM_CR_RX_ENABLE (1 << 0)
+#define MSM_BOOT_UART_DM_CR_RX_DISABLE (1 << 1)
+#define MSM_BOOT_UART_DM_CR_TX_ENABLE (1 << 2)
+#define MSM_BOOT_UART_DM_CR_TX_DISABLE (1 << 3)
+
+/* UART Channel Command */
+#define MSM_BOOT_UART_DM_CR_CH_CMD_LSB(x) ((x & 0x0f) << 4)
+#define MSM_BOOT_UART_DM_CR_CH_CMD_MSB(x) ((x >> 4 ) << 11 )
+#define MSM_BOOT_UART_DM_CR_CH_CMD(x) (MSM_BOOT_UART_DM_CR_CH_CMD_LSB(x)\
+ | MSM_BOOT_UART_DM_CR_CH_CMD_MSB(x))
+#define MSM_BOOT_UART_DM_CMD_NULL MSM_BOOT_UART_DM_CR_CH_CMD(0)
+#define MSM_BOOT_UART_DM_CMD_RESET_RX MSM_BOOT_UART_DM_CR_CH_CMD(1)
+#define MSM_BOOT_UART_DM_CMD_RESET_TX MSM_BOOT_UART_DM_CR_CH_CMD(2)
+#define MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT MSM_BOOT_UART_DM_CR_CH_CMD(3)
+#define MSM_BOOT_UART_DM_CMD_RES_BRK_CHG_INT MSM_BOOT_UART_DM_CR_CH_CMD(4)
+#define MSM_BOOT_UART_DM_CMD_START_BRK MSM_BOOT_UART_DM_CR_CH_CMD(5)
+#define MSM_BOOT_UART_DM_CMD_STOP_BRK MSM_BOOT_UART_DM_CR_CH_CMD(6)
+#define MSM_BOOT_UART_DM_CMD_RES_CTS_N MSM_BOOT_UART_DM_CR_CH_CMD(7)
+#define MSM_BOOT_UART_DM_CMD_RES_STALE_INT MSM_BOOT_UART_DM_CR_CH_CMD(8)
+#define MSM_BOOT_UART_DM_CMD_PACKET_MODE MSM_BOOT_UART_DM_CR_CH_CMD(9)
+#define MSM_BOOT_UART_DM_CMD_MODE_RESET MSM_BOOT_UART_DM_CR_CH_CMD(C)
+#define MSM_BOOT_UART_DM_CMD_SET_RFR_N MSM_BOOT_UART_DM_CR_CH_CMD(D)
+#define MSM_BOOT_UART_DM_CMD_RES_RFR_N MSM_BOOT_UART_DM_CR_CH_CMD(E)
+#define MSM_BOOT_UART_DM_CMD_RES_TX_ERR MSM_BOOT_UART_DM_CR_CH_CMD(10)
+#define MSM_BOOT_UART_DM_CMD_CLR_TX_DONE MSM_BOOT_UART_DM_CR_CH_CMD(11)
+#define MSM_BOOT_UART_DM_CMD_RES_BRKSTRT_INT MSM_BOOT_UART_DM_CR_CH_CMD(12)
+#define MSM_BOOT_UART_DM_CMD_RES_BRKEND_INT MSM_BOOT_UART_DM_CR_CH_CMD(13)
+#define MSM_BOOT_UART_DM_CMD_RES_PER_FRM_INT MSM_BOOT_UART_DM_CR_CH_CMD(14)
+
+/*UART General Command */
+#define MSM_BOOT_UART_DM_CR_GENERAL_CMD(x) ((x) << 8)
+
+#define MSM_BOOT_UART_DM_GCMD_NULL MSM_BOOT_UART_DM_CR_GENERAL_CMD(0)
+#define MSM_BOOT_UART_DM_GCMD_CR_PROT_EN MSM_BOOT_UART_DM_CR_GENERAL_CMD(1)
+#define MSM_BOOT_UART_DM_GCMD_CR_PROT_DIS MSM_BOOT_UART_DM_CR_GENERAL_CMD(2)
+#define MSM_BOOT_UART_DM_GCMD_RES_TX_RDY_INT MSM_BOOT_UART_DM_CR_GENERAL_CMD(3)
+#define MSM_BOOT_UART_DM_GCMD_SW_FORCE_STALE MSM_BOOT_UART_DM_CR_GENERAL_CMD(4)
+#define MSM_BOOT_UART_DM_GCMD_ENA_STALE_EVT MSM_BOOT_UART_DM_CR_GENERAL_CMD(5)
+#define MSM_BOOT_UART_DM_GCMD_DIS_STALE_EVT MSM_BOOT_UART_DM_CR_GENERAL_CMD(6)
+
+/* UART Interrupt Mask Register */
+#if PERIPH_BLK_BLSP
+#define MSM_BOOT_UART_DM_IMR(base) ((base) + 0xB0)
+#else
+#define MSM_BOOT_UART_DM_IMR(base) ((base) + 0x14)
+#endif
+
+#define MSM_BOOT_UART_DM_TXLEV (1 << 0)
+#define MSM_BOOT_UART_DM_RXHUNT (1 << 1)
+#define MSM_BOOT_UART_DM_RXBRK_CHNG (1 << 2)
+#define MSM_BOOT_UART_DM_RXSTALE (1 << 3)
+#define MSM_BOOT_UART_DM_RXLEV (1 << 4)
+#define MSM_BOOT_UART_DM_DELTA_CTS (1 << 5)
+#define MSM_BOOT_UART_DM_CURRENT_CTS (1 << 6)
+#define MSM_BOOT_UART_DM_TX_READY (1 << 7)
+#define MSM_BOOT_UART_DM_TX_ERROR (1 << 8)
+#define MSM_BOOT_UART_DM_TX_DONE (1 << 9)
+#define MSM_BOOT_UART_DM_RXBREAK_START (1 << 10)
+#define MSM_BOOT_UART_DM_RXBREAK_END (1 << 11)
+#define MSM_BOOT_UART_DM_PAR_FRAME_ERR_IRQ (1 << 12)
+
+#define MSM_BOOT_UART_DM_IMR_ENABLED (MSM_BOOT_UART_DM_TX_READY | \
+ MSM_BOOT_UART_DM_TXLEV | \
+ MSM_BOOT_UART_DM_RXSTALE)
+
+/* UART Interrupt Programming Register */
+#define MSM_BOOT_UART_DM_IPR(base) ((base) + 0x18)
+#define MSM_BOOT_UART_DM_STALE_TIMEOUT_LSB 0x0f
+#define MSM_BOOT_UART_DM_STALE_TIMEOUT_MSB 0 /* Not used currently */
+
+/* UART Transmit/Receive FIFO Watermark Register */
+#define MSM_BOOT_UART_DM_TFWR(base) ((base) + 0x1C)
+/* Interrupt is generated when FIFO level is less than or equal to this value */
+#define MSM_BOOT_UART_DM_TFW_VALUE 0
+
+#define MSM_BOOT_UART_DM_RFWR(base) ((base) + 0x20)
+/*Interrupt generated when no of words in RX FIFO is greater than this value */
+#define MSM_BOOT_UART_DM_RFW_VALUE 0
+
+/* UART Hunt Character Register */
+#define MSM_BOOT_UART_DM_HCR(base) ((base) + 0x24)
+
+/* Used for RX transfer initialization */
+#define MSM_BOOT_UART_DM_DMRX(base) ((base) + 0x34)
+
+/* Default DMRX value - any value bigger than FIFO size would be fine */
+#define MSM_BOOT_UART_DM_DMRX_DEF_VALUE 0x220
+
+/* Register to enable IRDA function */
+#if PERIPH_BLK_BLSP
+#define MSM_BOOT_UART_DM_IRDA(base) ((base) + 0xB8)
+#else
+#define MSM_BOOT_UART_DM_IRDA(base) ((base) + 0x38)
+#endif
+
+/* UART Data Mover Enable Register */
+#define MSM_BOOT_UART_DM_DMEN(base) ((base) + 0x3C)
+
+/* Number of characters for Transmission */
+#define MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base) ((base) + 0x040)
+
+/* UART RX FIFO Base Address */
+#define MSM_BOOT_UART_DM_BADR(base) ((base) + 0x44)
+
+/* UART Status Register */
+#if PERIPH_BLK_BLSP
+#define MSM_BOOT_UART_DM_SR(base) ((base) + 0x0A4)
+#else
+#define MSM_BOOT_UART_DM_SR(base) ((base) + 0x008)
+#endif
+#define MSM_BOOT_UART_DM_SR_RXRDY (1 << 0)
+#define MSM_BOOT_UART_DM_SR_RXFULL (1 << 1)
+#define MSM_BOOT_UART_DM_SR_TXRDY (1 << 2)
+#define MSM_BOOT_UART_DM_SR_TXEMT (1 << 3)
+#define MSM_BOOT_UART_DM_SR_UART_OVERRUN (1 << 4)
+#define MSM_BOOT_UART_DM_SR_PAR_FRAME_ERR (1 << 5)
+#define MSM_BOOT_UART_DM_RX_BREAK (1 << 6)
+#define MSM_BOOT_UART_DM_HUNT_CHAR (1 << 7)
+#define MSM_BOOT_UART_DM_RX_BRK_START_LAST (1 << 8)
+
+/* UART Receive FIFO Registers - 4 in numbers */
+#if PERIPH_BLK_BLSP
+#define MSM_BOOT_UART_DM_RF(base, x) ((base) + 0x140 + (4*(x)))
+#else
+#define MSM_BOOT_UART_DM_RF(base, x) ((base) + 0x70 + (4*(x)))
+#endif
+
+/* UART Masked Interrupt Status Register */
+#if PERIPH_BLK_BLSP
+#define MSM_BOOT_UART_DM_MISR(base) ((base) + 0xAC)
+#else
+#define MSM_BOOT_UART_DM_MISR(base) ((base) + 0x10)
+#endif
+
+/* UART Interrupt Status Register */
+#if PERIPH_BLK_BLSP
+#define MSM_BOOT_UART_DM_ISR(base) ((base) + 0xB4)
+#else
+#define MSM_BOOT_UART_DM_ISR(base) ((base) + 0x14)
+#endif
+
+/* Number of characters received since the end of last RX transfer */
+#if PERIPH_BLK_BLSP
+#define MSM_BOOT_UART_DM_RX_TOTAL_SNAP(base) ((base) + 0xBC)
+#else
+#define MSM_BOOT_UART_DM_RX_TOTAL_SNAP(base) ((base) + 0x38)
+#endif
+
+/* UART TX FIFO Status Register */
+#define MSM_BOOT_UART_DM_TXFS(base) ((base) + 0x4C)
+#define MSM_BOOT_UART_DM_TXFS_STATE_LSB(x) MSM_BOOT_UART_DM_EXTR_BITS(x,0,6)
+#define MSM_BOOT_UART_DM_TXFS_STATE_MSB(x) MSM_BOOT_UART_DM_EXTR_BITS(x,14,31)
+#define MSM_BOOT_UART_DM_TXFS_BUF_STATE(x) MSM_BOOT_UART_DM_EXTR_BITS(x,7,9)
+#define MSM_BOOT_UART_DM_TXFS_ASYNC_STATE(x) MSM_BOOT_UART_DM_EXTR_BITS(x,10,13)
+
+/* UART RX FIFO Status Register */
+#define MSM_BOOT_UART_DM_RXFS(base) ((base) + 0x50)
+#define MSM_BOOT_UART_DM_RXFS_STATE_LSB(x) MSM_BOOT_UART_DM_EXTR_BITS(x,0,6)
+#define MSM_BOOT_UART_DM_RXFS_STATE_MSB(x) MSM_BOOT_UART_DM_EXTR_BITS(x,14,31)
+#define MSM_BOOT_UART_DM_RXFS_BUF_STATE(x) MSM_BOOT_UART_DM_EXTR_BITS(x,7,9)
+#define MSM_BOOT_UART_DM_RXFS_ASYNC_STATE(x) MSM_BOOT_UART_DM_EXTR_BITS(x,10,13)
+
+/* Macros for Common Errors */
+#define MSM_BOOT_UART_DM_E_SUCCESS 0
+#define MSM_BOOT_UART_DM_E_FAILURE 1
+#define MSM_BOOT_UART_DM_E_TIMEOUT 2
+#define MSM_BOOT_UART_DM_E_INVAL 3
+#define MSM_BOOT_UART_DM_E_MALLOC_FAIL 4
+#define MSM_BOOT_UART_DM_E_RX_NOT_READY 5
+
+#endif /* __UART_DM_H__ */
+
Marc Jones (marc.jones(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7261
-gerrit
commit 6882a9e9eb9cb9125531589b5b35c1d15de2acb6
Author: Vadim Bendebury <vbendeb(a)chromium.org>
Date: Mon Apr 7 15:26:39 2014 -0700
Provide ability to integrate with QComm SBLs
Ipq8064 SBLs initialize the hardware to prepare it to run an arbitrary
user provided bootloader. The only bootloader requirements imposed by
the SBLs are that it is concatenated with the SBL chunks in the
bootprm AND it uses MBN encapsulation (mostly to specify the size and
load address).
This patch adds configuration options to specify the location of the
SBL blobs and to require MBN encapsulation of the bootblock.
BRANCH=none
BUG=chrome-os-partner:27784
TEST=manual
- the below demonstrates added encapsulation, no code run attempts
have been made yet:
$ FEATURES=noclean emerge-storm coreboot
$ cd /build/storm/tmp/portage/sys-boot/coreboot-9999/work/coreboot-9999
$ \od -t x4 build/cbfs/fallback/bootblock.bin | head -3
0000000 00000005 00000003 00000000 2a010000
0000020 00000be0 00000be0 2a010be0 00000000
0000040 2a010be0 00000000 e32bf0df e59f0030
Original-Change-Id: Iae30ad08059e2b35c434ac25a410ac2017752957
Original-Signed-off-by: Vadim Bendebury <vbendeb(a)chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/193511
(cherry picked from commit bf16ea915c723ab124d817e3b0d950282e3cf1c1)
Signed-off-by: Marc Jones <marc.jones(a)se-eng.com>
Change-Id: I53c71d382ec1d826f530d7afb545f64ec4eaf96b
---
src/soc/qualcomm/ipq806x/Kconfig | 18 ++++++++++++++++++
src/soc/qualcomm/ipq806x/Makefile.inc | 10 ++++++++++
2 files changed, 28 insertions(+)
diff --git a/src/soc/qualcomm/ipq806x/Kconfig b/src/soc/qualcomm/ipq806x/Kconfig
index fcf8ccd..0f65990 100644
--- a/src/soc/qualcomm/ipq806x/Kconfig
+++ b/src/soc/qualcomm/ipq806x/Kconfig
@@ -19,4 +19,22 @@ config CBFS_ROM_OFFSET
hex "offset of CBFS data in ROM"
default 0x18080
+config MBN_ENCAPSULATION
+ depends on USE_BLOBS
+ bool "bootblock encapsulation for ipq8064"
+ default y
+
+config SBL_BLOB
+ depends on USE_BLOBS
+ string "file name of the Qualcomm SBL blob"
+ default "3rdparty/cpu/qualcomm/ipq8064/sbls.bin"
+ help
+ The path and filename of the binary blob containing
+ ipq806x early initialization code, as supplied by the
+ vendor.
+
+config BOOTBLOCK_BASE
+ hex "64K bytes left for TZBSP"
+ default 0x2a010000
+
endif
diff --git a/src/soc/qualcomm/ipq806x/Makefile.inc b/src/soc/qualcomm/ipq806x/Makefile.inc
index be37581..2487f46 100644
--- a/src/soc/qualcomm/ipq806x/Makefile.inc
+++ b/src/soc/qualcomm/ipq806x/Makefile.inc
@@ -6,3 +6,13 @@ romstage-y += timer.c
ramstage-y += cbfs.c
ramstage-y += timer.c
+
+ifeq ($(CONFIG_MBN_ENCAPSULATION),y)
+
+$(objcbfs)/%.bin: $(objcbfs)/%.elf
+ @printf " OBJCOPY $(subst $(obj)/,,$(@))\n"
+ $(OBJCOPY_bootblock) -O binary $< $@.prembn
+ @printf " ADD MBN $(subst $(obj)/,,$(@))\n"
+ ./util/ipqheader/ipqheader.py $(CONFIG_BOOTBLOCK_BASE) $@.prembn $@.tmp
+ @mv $@.tmp $@
+endif
the following patch was just integrated into master:
commit bf9d122ecdb97ff6a236a2d8b7ad0e9877fe086c
Author: Edward O'Callaghan <eocallaghan(a)alterapraxis.com>
Date: Wed Oct 29 09:26:00 2014 +1100
mainboard: Trivial - Make AGESA board include consistent
Change-Id: If6cb99469f56fff8f88b294b625f0a5205ec540b
Signed-off-by: Edward O'Callaghan <eocallaghan(a)alterapraxis.com>
Reviewed-on: http://review.coreboot.org/7238
Tested-by: build bot (Jenkins)
Reviewed-by: Marc Jones <marc.jones(a)se-eng.com>
See http://review.coreboot.org/7238 for details.
-gerrit
Marc Jones (marc.jones(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6930
-gerrit
commit b060c2c0c8523524563659daaf55f29c2299d64c
Author: Julius Werner <jwerner(a)chromium.org>
Date: Mon Jan 13 13:24:30 2014 -0800
arm: Thumb ALL the things!
This patch switches every last part of Coreboot on ARM over to Thumb
mode: libpayload, the internal libgcc, and assorted assembly files. In
combination with the respective depthcharge patch, this will switch to
Thumb mode right after the entry point of the bootblock and not switch
back to ARM until the final assembly stub that jumps to the kernel.
The required changes to make this work include some new headers and
Makefile flags to handle assembly files (using the unified syntax and
the same helper macros as Linux), modifying our custom-written libgcc
code for 64-bit division to support Thumb (removing some stale old files
that were never really used for clarity), and flipping the general
CFLAGS to Thumb (some more cleanup there as well while I'm at it).
BUG=None
TEST=Snow and Nyan still boot.
Original-Change-Id: I80c04281e3adbf74f9f477486a96b9fafeb455b3
Original-Signed-off-by: Julius Werner <jwerner(a)chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/182212
Original-Reviewed-by: Gabe Black <gabeblack(a)chromium.org>
(cherry picked from commit 5f65c17cbfae165a95354146ae79e06c512c2c5a)
Conflicts:
payloads/libpayload/include/arm/arch/asm.h
src/arch/arm/Makefile.inc
src/arch/arm/armv7/Makefile.inc
*** There is an issue with what to do with ramstage-S-ccopts, and
*** will need to be covered in additional ARM cleanup patches.
Change-Id: I80c04281e3adbf74f9f477486a96b9fafeb455b3
Signed-off-by: Marc Jones <marc.jones(a)se-eng.com>
---
payloads/libpayload/arch/arm/Makefile.inc | 7 +-
payloads/libpayload/include/arm/arch/asm.h | 19 ++-
src/arch/arm/Makefile.inc | 10 +-
src/arch/arm/armv7/Makefile.inc | 10 +-
src/arch/arm/armv7/bootblock.S | 23 ++--
src/arch/arm/include/arch/asm.h | 19 ++-
src/arch/arm/libgcc/bpabi.c | 214 -----------------------------
src/arch/arm/libgcc/bpabi_asm.S | 130 ------------------
src/arch/arm/libgcc/uldivmod.S | 28 ++--
src/soc/nvidia/tegra124/maincpu.S | 10 +-
10 files changed, 77 insertions(+), 393 deletions(-)
diff --git a/payloads/libpayload/arch/arm/Makefile.inc b/payloads/libpayload/arch/arm/Makefile.inc
index 0078ffe..2f8da15 100644
--- a/payloads/libpayload/arch/arm/Makefile.inc
+++ b/payloads/libpayload/arch/arm/Makefile.inc
@@ -27,7 +27,8 @@
## SUCH DAMAGE.
##
-CFLAGS += -mfloat-abi=hard -marm -mabi=aapcs-linux -march=armv7-a
+CFLAGS += -mthumb -march=armv7-a
+arm_asm_flags = -Wa,-mthumb -Wa,-mimplicit-it=always -Wa,-mno-warn-deprecated
head.o-y += head.S
libc-y += main.c sysinfo.c
@@ -37,3 +38,7 @@ libc-y += memcpy.S memset.S memmove.S
libc-y += exception_asm.S exception.c
libc-y += cache.c cpu.S
libcbfs-$(CONFIG_LP_CBFS) += dummy_media.c
+
+# Add other classes here when you put assembly files into them!
+head.o-S-ccopts += $(arm_asm_flags)
+libc-S-ccopts += $(arm_asm_flags)
diff --git a/payloads/libpayload/include/arm/arch/asm.h b/payloads/libpayload/include/arm/arch/asm.h
index 2f88599..9e9e7ce 100644
--- a/payloads/libpayload/include/arm/arch/asm.h
+++ b/payloads/libpayload/include/arm/arch/asm.h
@@ -20,16 +20,17 @@
#ifndef __ARM_ASM_H
#define __ARM_ASM_H
-#if defined __arm__
-# define ARM(x...) x
-# define THUMB(x...)
-# define W(instr) instr
-#elif defined __thumb__
+/* __arm__ is defined regardless of Thumb mode, so need to order this right */
+#if defined __thumb2__
# define ARM(x...)
# define THUMB(x...) x
# define W(instr) instr.w
+#elif defined __thumb__
+# error You are not compiling Thumb2, this won't work!
#else
-# error Not in ARM or thumb mode!
+# define ARM(x...) x
+# define THUMB(x...)
+# define W(instr) instr
#endif
#define ALIGN .align 0
@@ -46,4 +47,10 @@
#define END(name) \
.size name, .-name
+/* Everything should go into the text section by default. */
+ .text
+
+/* Thumb code uses the (new) unified assembly syntax. */
+THUMB( .syntax unified )
+
#endif /* __ARM_ASM_H */
diff --git a/src/arch/arm/Makefile.inc b/src/arch/arm/Makefile.inc
index 8044dba..95e16b5 100644
--- a/src/arch/arm/Makefile.inc
+++ b/src/arch/arm/Makefile.inc
@@ -66,7 +66,7 @@ $(objcbfs)/bootblock.debug: $(src)/arch/arm/bootblock.ld $(obj)/ldoptions $$(boo
ifeq ($(CONFIG_COMPILER_LLVM_CLANG),y)
$(LD_bootblock) -m armelf_linux_eabi --gc-sections -static -o $@ -L$(obj) $< -T $(src)/arch/arm/bootblock.ld
else
- $(CC_bootblock) $(CFLAGS_bootblock) -nostartfiles -Wl,--gc-sections -static -o $@ -L$(obj) -T $(src)/arch/arm/bootblock.ld -Wl,--start-group $(bootblock-objs) -Wl,--end-group
+ $(CC_bootblock) $(CFLAGS_bootblock) -nostdlib -Wl,--gc-sections -static -o $@ -L$(obj) -T $(src)/arch/arm/bootblock.ld -Wl,--start-group $(bootblock-objs) -Wl,--end-group
endif
endif # CONFIG_ARCH_BOOTBLOCK_ARM
@@ -89,9 +89,9 @@ VBOOT_STUB_DEPS += $(obj)/arch/arm/eabi_compat.rmodules_arm.o
$(objcbfs)/romstage.debug: $$(romstage-objs) $(src)/arch/arm/romstage.ld $(obj)/ldoptions
@printf " LINK $(subst $(obj)/,,$(@))\n"
ifeq ($(CONFIG_COMPILER_LLVM_CLANG),y)
- $(LD_romstage) -nostdlib -nostartfiles --gc-sections -static -o $@ -L$(obj) $(romstage-objs) -T $(src)/arch/arm/romstage.ld
+ $(LD_romstage) -nostdlib --gc-sections -static -o $@ -L$(obj) $(romstage-objs) -T $(src)/arch/arm/romstage.ld
else
- $(CC_romstage) $(CFLAGS_romstage) -nostartfiles -Wl,--gc-sections -static -o $@ -L$(obj) -T $(src)/arch/arm/romstage.ld -Wl,--start-group $(romstage-objs) -Wl,--end-group
+ $(CC_romstage) $(CFLAGS_romstage) -nostdlib -Wl,--gc-sections -static -o $@ -L$(obj) -T $(src)/arch/arm/romstage.ld -Wl,--start-group $(romstage-objs) -Wl,--end-group
endif
endif # CONFIG_ARCH_ROMSTAGE_ARM
@@ -116,7 +116,7 @@ ramstage-srcs += $(wildcard src/mainboard/$(MAINBOARDDIR)/mainboard.c)
$(objcbfs)/ramstage.debug: $$(ramstage-objs) $(src)/arch/arm/ramstage.ld $(obj)/ldoptions
@printf " CC $(subst $(obj)/,,$(@))\n"
ifeq ($(CONFIG_COMPILER_LLVM_CLANG),y)
- $(LD_ramstage) -m armelf_linux_eabi --gc-sections -o $@ -L$(obj) $< -T $(src)/arch/arm/ramstage.ld
+ $(LD_ramstage) -nostdlib -m armelf_linux_eabi --gc-sections -o $@ -L$(obj) $< -T $(src)/arch/arm/ramstage.ld
else
$(CC_ramstage) $(CFLAGS_ramstage) -nostdlib -Wl,--gc-sections -static -o $@ -L$(obj) -Wl,--start-group $(ramstage-objs) -Wl,--end-group -T $(src)/arch/arm/ramstage.ld
endif
@@ -124,7 +124,7 @@ endif
$(objgenerated)/ramstage.o: $(stages_o) $$(ramstage-objs)
@printf " CC $(subst $(obj)/,,$(@))\n"
ifeq ($(CONFIG_COMPILER_LLVM_CLANG),y)
- $(LD_ramstage) -m -m armelf_linux_eabi --gc-sections -r -o $@ --wrap __divdi3 --wrap __udivdi3 --wrap __moddi3 --wrap __umoddi3 --wrap __uidiv --start-group $(ramstage-objs) --end-group
+ $(LD_ramstage) -nostdlib -m armelf_linux_eabi --gc-sections -r -o $@ --wrap __divdi3 --wrap __udivdi3 --wrap __moddi3 --wrap __umoddi3 --wrap __uidiv --start-group $(ramstage-objs) --end-group
else
$(CC_ramstage) $(CFLAGS_ramstage) $(CPPFLAGS_ramstage) -nostdlib -Wl,--gc-sections -r -o $@ -Wl,--start-group $(stages_o) $(ramstage-objs) -Wl,--end-group
endif
diff --git a/src/arch/arm/armv7/Makefile.inc b/src/arch/arm/armv7/Makefile.inc
index 4f3e757..01069c4 100644
--- a/src/arch/arm/armv7/Makefile.inc
+++ b/src/arch/arm/armv7/Makefile.inc
@@ -19,8 +19,10 @@
##
###############################################################################
-armv7_flags = -march=armv7-a -mthumb -mthumb-interwork \
+armv7_flags = -march=armv7-a -mthumb \
-I$(src)/arch/arm/include/armv7/ -D__COREBOOT_ARM_ARCH__=7
+armv7_asm_flags = $(armv7_flags) -Wa,-mthumb -Wa,-mimplicit-it=always \
+ -Wa,-mno-warn-deprecated
###############################################################################
# bootblock
@@ -40,7 +42,7 @@ bootblock-$(CONFIG_BOOTBLOCK_CONSOLE) += exception_asm.S
bootblock-y += mmu.c
bootblock-c-ccopts += $(armv7_flags)
-bootblock-S-ccopts += $(armv7_flags)
+bootblock-S-ccopts += $(armv7_asm_flags)
endif # CONFIG_ARCH_BOOTBLOCK_ARMV7
@@ -57,7 +59,7 @@ romstage-y += exception_asm.S
romstage-y += mmu.c
romstage-c-ccopts += $(armv7_flags)
-romstage-S-ccopts += $(armv7_flags)
+romstage-S-ccopts += $(armv7_asm_flags)
endif # CONFIG_ARCH_ROMSTAGE_ARMV7
@@ -74,6 +76,6 @@ ramstage-y += exception_asm.S
ramstage-y += mmu.c
ramstage-c-ccopts += $(armv7_flags)
-ramstage-S-ccopts += $(armv7_flags)
+ramstage-S-ccopts += $(armv7_asm_flags)
endif # CONFIG_ARCH_RAMSTAGE_ARMV7
diff --git a/src/arch/arm/armv7/bootblock.S b/src/arch/arm/armv7/bootblock.S
index a8d0973..4258caf 100644
--- a/src/arch/arm/armv7/bootblock.S
+++ b/src/arch/arm/armv7/bootblock.S
@@ -32,6 +32,7 @@
#include <arch/asm.h>
.section ".start", "a", %progbits
+.arm
ENTRY(_start)
/*
* Set the cpu to System mode with IRQ and FIQ disabled. Prefetch/Data
@@ -40,7 +41,11 @@ ENTRY(_start)
* causes it.
*/
msr cpsr_cxf, #0xdf
+ bl _thumb_start
+ENDPROC(_start)
+.thumb
+ENTRY(_thumb_start)
/*
* From Cortex-A Series Programmer's Guide:
* Only CPU 0 performs initialization. Other CPUs go into WFI
@@ -72,25 +77,17 @@ call_bootblock:
ldr sp, .Stack /* Set up stack pointer */
ldr r0,=0x00000000
/*
- * The current design of cpu_info places the
- * struct at the top of the stack. The number of
- * words pushed must be at least as large as that
- * struct.
+ * The current design of cpu_info places the struct at the top of the
+ * stack. Free enough space to accomodate for that, but make sure it's
+ * 8-byte aligned for ABI compliance.
*/
- push {r0-r2}
- bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
- /*
- * Use "bl" instead of "b" even though we do not intend to return.
- * "bl" gets compiled to "blx" if we're transitioning from ARM to
- * Thumb. However, "b" will not and GCC may attempt to create a
- * wrapper which is currently broken.
- */
+ sub sp, sp, #16
bl main
wait_for_interrupt:
wfi
mov pc, lr @ back to my caller
-ENDPROC(_start)
+ENDPROC(_thumb_start)
/* we do it this way because it's a 32-bit constant and
* in some cases too far away to be loaded as just an offset
diff --git a/src/arch/arm/include/arch/asm.h b/src/arch/arm/include/arch/asm.h
index 5f3e55f..a57ce4d 100644
--- a/src/arch/arm/include/arch/asm.h
+++ b/src/arch/arm/include/arch/asm.h
@@ -20,19 +20,20 @@
#ifndef __ARM_ASM_H
#define __ARM_ASM_H
-#if defined __arm__
-# define ARM(x...) x
-# define THUMB(x...)
-# define W(instr) instr
-#elif defined __thumb__
+/* __arm__ is defined regardless of Thumb mode, so need to order this right */
+#if defined __thumb2__
# define ARM(x...)
# define THUMB(x...) x
# define W(instr) instr.w
# if __COREBOOT_ARM_ARCH__ < 7
# error thumb mode has not been tested with ARM < v7!
# endif
+#elif defined __thumb__
+# error You are not compiling Thumb2, this won't work!
#else
-# error Not in ARM or thumb mode!
+# define ARM(x...) x
+# define THUMB(x...)
+# define W(instr) instr
#endif
#define ALIGN .align 0
@@ -49,4 +50,10 @@
#define END(name) \
.size name, .-name
+/* Everything should go into the text section by default. */
+ .text
+
+/* Thumb code uses the (new) unified assembly syntax. */
+THUMB( .syntax unified )
+
#endif /* __ARM_ASM_H */
diff --git a/src/arch/arm/libgcc/bpabi.c b/src/arch/arm/libgcc/bpabi.c
deleted file mode 100644
index 8cb7ddf..0000000
--- a/src/arch/arm/libgcc/bpabi.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/* Miscellaneous BPABI functions.
-
- Copyright (C) 2003, 2004 Free Software Foundation, Inc.
- Contributed by CodeSourcery, LLC.
-
- This file 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, or (at your option) any
- later version.
-
- In addition to the permissions in the GNU General Public License, the
- Free Software Foundation gives you unlimited permission to link the
- compiled version of this file into combinations with other programs,
- and to distribute those combinations without any restriction coming
- from the use of this file. (The General Public License restrictions
- do apply in other respects; for example, they cover modification of
- the file, and distribution when not linked into a combine
- executable.)
-
- This file 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
-
-#if defined __GNUC__
-
-#include <stdint.h>
-
-uint64_t __udivmoddi4(uint64_t n, uint64_t d, uint64_t *rp);
-extern int64_t __divdi3(int64_t, int64_t);
-extern uint64_t __udivdi3(uint64_t, uint64_t);
-extern int64_t __gnu_ldivmod_helper(int64_t, int64_t, int64_t *);
-extern uint64_t __gnu_uldivmod_helper(uint64_t, uint64_t, uint64_t *);
-
-typedef union
-{
- struct {
- int32_t low;
- int32_t high;
- } s;
- int64_t ll;
-} DWunion;
-
-uint64_t
-__udivmoddi4(uint64_t n, uint64_t d, uint64_t *rp)
-{
- const DWunion nn = {.ll = n};
- const DWunion dd = {.ll = d};
- DWunion rr;
- uint32_t d0, d1, n0, n1, n2;
- uint32_t q0, q1;
- uint32_t b, bm;
-
- d0 = dd.s.low;
- d1 = dd.s.high;
- n0 = nn.s.low;
- n1 = nn.s.high;
-
- if (d1 == 0) {
- if (d0 > n1) {
- /* 0q = nn / 0D */
- udiv_qrnnd(q0, n0, n1, n0, d0);
- q1 = 0;
- /* Remainder in n0. */
- } else {
- /* qq = NN / 0d */
- if (d0 == 0)
- d0 = 1 / d0; /* Divide intentionally by zero. */
-
- udiv_qrnnd(q1, n1, 0, n1, d0);
- udiv_qrnnd(q0, n0, n1, n0, d0);
-
- /* Remainder in n0. */
- }
-
- if (rp != 0) {
- rr.s.low = n0;
- rr.s.high = 0;
- *rp = rr.ll;
- }
- } else {
- if (d1 > n1) {
- /* 00 = nn / DD */
- q0 = 0;
- q1 = 0;
-
- /* Remainder in n1n0. */
- if (rp != 0) {
- rr.s.low = n0;
- rr.s.high = n1;
- *rp = rr.ll;
- }
- } else {
- /* 0q = NN / dd */
-
- count_leading_zeros(bm, d1);
- if (bm == 0) {
- /* From (n1 >= d1) /\ (the most significant
- bit of d1 is set), conclude (the most
- significant bit of n1 is set) /\ (the
- quotient digit q0 = 0 or 1).
-
- This special case is necessary, not an
- optimization. */
-
- /* The condition on the next line takes
- advantage of that n1 >= d1 (true due to
- program flow). */
- if (n1 > d1 || n0 >= d0) {
- q0 = 1;
- sub_ddmmss(n1, n0, n1, n0, d1, d0);
- } else
- q0 = 0;
-
- q1 = 0;
-
- if (rp != 0) {
- rr.s.low = n0;
- rr.s.high = n1;
- *rp = rr.ll;
- }
- } else {
- uint32_t m1, m0;
- /* Normalize. */
-
- b = 32 - bm;
-
- d1 = (d1 << bm) | (d0 >> b);
- d0 = d0 << bm;
- n2 = n1 >> b;
- n1 = (n1 << bm) | (n0 >> b);
- n0 = n0 << bm;
-
- udiv_qrnnd(q0, n1, n2, n1, d1);
- umul_ppmm(m1, m0, q0, d0);
-
- if (m1 > n1 || (m1 == n1 && m0 > n0)) {
- q0--;
- sub_ddmmss(m1, m0, m1, m0, d1, d0);
- }
-
- q1 = 0;
-
- /* Remainder in (n1n0 - m1m0) >> bm. */
- if (rp != 0) {
- sub_ddmmss(n1, n0, n1, n0, m1, m0);
- rr.s.low = (n1 << b) | (n0 >> bm);
- rr.s.high = n1 >> bm;
- *rp = rr.ll;
- }
- }
- }
- }
-
- const DWunion ww = {{.low = q0, .high = q1}};
- return ww.ll;
-}
-
-int64_t
-__divdi3(int64_t u, int64_t v)
-{
- int32_t c = 0;
- DWunion uu = {.ll = u};
- DWunion vv = {.ll = v};
- int64_t w;
-
- if (uu.s.high < 0) {
- c = ~c;
- uu.ll = -uu.ll;
- }
- if (vv.s.high < 0) {
- c = ~c;
- vv.ll = -vv.ll;
- }
-
- w = __udivmoddi4(uu.ll, vv.ll, (uint64_t *)0);
- if (c)
- w = -w;
-
- return w;
-}
-
-int64_t
-__gnu_ldivmod_helper (int64_t a, int64_t b, int64_t *remainder)
-{
- int64_t quotient;
-
- quotient = __divdi3(a, b);
- *remainder = a - b * quotient;
- return quotient;
-}
-
-uint64_t
-__udivdi3(uint64_t n, uint64_t d)
-{
- return __udivmoddi4(n, d, (uint64_t *)0);
-}
-
-uint64_t
-__gnu_uldivmod_helper(uint64_t a, uint64_t b, uint64_t *remainder)
-{
- uint64_t quotient;
-
- quotient = __udivdi3(a, b);
- *remainder = a - b * quotient;
- return quotient;
-}
-
-#endif
diff --git a/src/arch/arm/libgcc/bpabi_asm.S b/src/arch/arm/libgcc/bpabi_asm.S
deleted file mode 100644
index 27b4a1c..0000000
--- a/src/arch/arm/libgcc/bpabi_asm.S
+++ /dev/null
@@ -1,130 +0,0 @@
-/* Miscellaneous BPABI functions.
-
- Copyright (C) 2003, 2004, 2007, 2008 Free Software Foundation, Inc.
- Contributed by CodeSourcery, LLC.
-
- This file 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, or (at your option) any
- later version.
-
- In addition to the permissions in the GNU General Public License, the
- Free Software Foundation gives you unlimited permission to link the
- compiled version of this file into combinations with other programs,
- and to distribute those combinations without any restriction coming
- from the use of this file. (The General Public License restrictions
- do apply in other respects; for example, they cover modification of
- the file, and distribution when not linked into a combine
- executable.)
-
- This file 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
-
-
-#include <arch/asm.h>
-
-#ifdef __ARMEB__
-#define xxh r0
-#define xxl r1
-#define yyh r2
-#define yyl r3
-#else
-#define xxh r1
-#define xxl r0
-#define yyh r3
-#define yyl r2
-#endif
-
-#if defined __thumb2__
-
-.macro do_it cond
- it \cond
-.endm
-#define do_push push
-#define do_pop pop
-
-#else
-
-.macro do_it cond
-.endm
-#define do_push stmfd sp!,
-#define do_pop ldmfd sp!,
-
-#endif
-
-ENTRY(__aeabi_lcmp)
-
- cmp xxh, yyh
- do_it lt
- movlt r0, #-1
- do_it gt
- movgt r0, #1
- do_it ne
- movne pc, lr
- subs r0, xxl, yyl
- do_it lo
- movlo r0, #-1
- do_it hi
- movhi r0, #1
- mov pc, lr
-
-ENDPROC(__aeabi_lcmp)
-
-ENTRY(__aeabi_ulcmp)
-
- cmp xxh, yyh
- do_it lo
- movlo r0, #-1
- do_it hi
- movhi r0, #1
- do_it ne
- movne pc, lr
- cmp xxl, yyl
- do_it lo
- movlo r0, #-1
- do_it hi
- movhi r0, #1
- do_it eq
- moveq r0, #0
- mov pc, lr
-
-ENDPROC(__aeabi_ulcmp)
-
-ENTRY(__aeabi_ldivmod)
- sub sp, sp, #8
-#if defined(__thumb2__)
- mov ip, sp
- push {ip, lr}
-#else
- do_push {sp, lr}
-#endif
- bl __gnu_ldivmod_helper
- ldr lr, [sp, #4]
- add sp, sp, #8
- do_pop {r2, r3}
- mov pc, lr
-
-ENDPROC(__aeabi_ldivmod)
-
-ENTRY(__aeabi_uldivmod)
- sub sp, sp, #8
-#if defined(__thumb2__)
- mov ip, sp
- push {ip, lr}
-#else
- do_push {sp, lr}
-#endif
- bl __gnu_uldivmod_helper
- ldr lr, [sp, #4]
- add sp, sp, #8
- do_pop {r2, r3}
- mov pc, lr
-
-ENDPROC(__aeabi_uldivmod)
diff --git a/src/arch/arm/libgcc/uldivmod.S b/src/arch/arm/libgcc/uldivmod.S
index ac267d0..521a5d1 100644
--- a/src/arch/arm/libgcc/uldivmod.S
+++ b/src/arch/arm/libgcc/uldivmod.S
@@ -55,8 +55,12 @@ Q_1 .req r1
R_0 .req r2
R_1 .req r3
+THUMB(
+TMP .req r8
+)
+
ENTRY(__aeabi_uldivmod)
- stmfd sp!, {r4, r5, r6, r7, lr}
+ stmfd sp!, {r4, r5, r6, r7, THUMB(TMP,) lr}
@ Test if B == 0
orrs ip, B_0, B_1 @ Z set -> B == 0
beq L_div_by_0
@@ -92,12 +96,16 @@ L_div_64_64:
subs D_1, D_0, #32
rsb ip, D_0, #32
movmi B_1, B_1, lsl D_0
- orrmi B_1, B_1, B_0, lsr ip
+ARM( orrmi B_1, B_1, B_0, lsr ip )
+THUMB( lsrmi TMP, B_0, ip )
+THUMB( orrmi B_1, B_1, TMP )
movpl B_1, B_0, lsl D_1
mov B_0, B_0, lsl D_0
@ C = 1 << (clz B - clz A)
movmi C_1, C_1, lsl D_0
- orrmi C_1, C_1, C_0, lsr ip
+ARM( orrmi C_1, C_1, C_0, lsr ip )
+THUMB( lsrmi TMP, C_0, ip )
+THUMB( orrmi C_1, C_1, TMP )
movpl C_1, C_0, lsl D_1
mov C_0, C_0, lsl D_0
L_done_shift:
@@ -170,7 +178,7 @@ L_exit:
mov R_1, A_1
mov Q_0, D_0
mov Q_1, D_1
- ldmfd sp!, {r4, r5, r6, r7, pc}
+ ldmfd sp!, {r4, r5, r6, r7, THUMB(TMP,) pc}
L_div_32_32:
@ Note: A_0 & r0 are aliases
@@ -180,7 +188,7 @@ L_div_32_32:
mov R_0, r1
mov R_1, #0
mov Q_1, #0
- ldmfd sp!, {r4, r5, r6, r7, pc}
+ ldmfd sp!, {r4, r5, r6, r7, THUMB(TMP,) pc}
L_pow2:
/* CLZ only exists in ARM architecture version 5 and above. */
@@ -201,12 +209,14 @@ L_pow2:
add D_0, D_0, #32
L_1:
movpl A_0, A_0, lsr D_0
- orrpl A_0, A_0, A_1, lsl D_1
+ARM( orrpl A_0, A_0, A_1, lsl D_1 )
+THUMB( lslpl TMP, A_1, D_1 )
+THUMB( orrpl A_0, A_0, TMP )
mov A_1, A_1, lsr D_0
@ Mov back C to R
mov R_0, C_0
mov R_1, C_1
- ldmfd sp!, {r4, r5, r6, r7, pc}
+ ldmfd sp!, {r4, r5, r6, r7, THUMB(TMP,) pc}
#else
@ Note: A, B and Q, R are aliases
@ R = A & (B - 1)
@@ -244,7 +254,7 @@ L_1:
@ Move C to R
mov R_0, C_0
mov R_1, C_1
- ldmfd sp!, {r4, r5, r6, r7, pc}
+ ldmfd sp!, {r4, r5, r6, r7, THUMB(TMP,) pc}
#endif
L_div_by_0:
@@ -254,5 +264,5 @@ L_div_by_0:
mov Q_1, #0
mov R_0, #0
mov R_1, #0
- ldmfd sp!, {r4, r5, r6, r7, pc}
+ ldmfd sp!, {r4, r5, r6, r7, THUMB(TMP,) pc}
ENDPROC(__aeabi_uldivmod)
diff --git a/src/soc/nvidia/tegra124/maincpu.S b/src/soc/nvidia/tegra124/maincpu.S
index 7b217d8..91981ac 100644
--- a/src/soc/nvidia/tegra124/maincpu.S
+++ b/src/soc/nvidia/tegra124/maincpu.S
@@ -27,8 +27,9 @@
* SUCH DAMAGE.
*/
+#include <arch/asm.h>
+
.align 2
- .arm
.global maincpu_stack_pointer
maincpu_stack_pointer:
@@ -38,10 +39,8 @@ maincpu_stack_pointer:
maincpu_entry_point:
.word 0
- .global maincpu_setup
- .type maincpu_setup, function
- maincpu_setup:
-
+.arm
+ENTRY(maincpu_setup)
/*
* Set the cpu to System mode with IRQ and FIQ disabled. Prefetch/Data
* aborts may happen early and crash before the abort handlers are
@@ -54,3 +53,4 @@ maincpu_entry_point:
eor lr, lr
ldr r0, maincpu_entry_point
bx r0
+ENDPROC(maincpu_setup)