summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/console/ipq806x_console.c440
-rwxr-xr-xsrc/mainboard/google/storm/cdp.c379
-rw-r--r--src/soc/qualcomm/ipq806x/Makefile.inc3
-rw-r--r--src/soc/qualcomm/ipq806x/cbfs.c9
-rw-r--r--src/soc/qualcomm/ipq806x/cdp.h127
-rw-r--r--src/soc/qualcomm/ipq806x/clock.c123
-rw-r--r--src/soc/qualcomm/ipq806x/clock.h185
-rw-r--r--src/soc/qualcomm/ipq806x/gpio.c62
-rw-r--r--src/soc/qualcomm/ipq806x/gpio.h63
-rw-r--r--src/soc/qualcomm/ipq806x/gsbi.h37
-rw-r--r--src/soc/qualcomm/ipq806x/iomap.h90
-rw-r--r--src/soc/qualcomm/ipq806x/timer.c145
-rw-r--r--src/soc/qualcomm/ipq806x/timer.h40
-rw-r--r--src/soc/qualcomm/ipq806x/uart.h281
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 0000000000..c65f876821
--- /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 0000000000..f26ae021af
--- /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 1da8489eda..0ea29969a0 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 97ae548821..eec9b7353b 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 0000000000..4ae476a278
--- /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 0000000000..882be02f9f
--- /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 0000000000..263b81b0b8
--- /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 0000000000..6e4140e4f1
--- /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 0000000000..e2b281e04f
--- /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 0000000000..d2ba2b310a
--- /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 0000000000..514c6a7d22
--- /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 c4e250ebe1..691ccbd2c5 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 0000000000..4e1ef34294
--- /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 0000000000..6fff0468f8
--- /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__ */
+