From 476f7316a1e2596cc5c3e83d05003203a042a4eb Mon Sep 17 00:00:00 2001 From: Vadim Bendebury Date: Tue, 8 Apr 2014 18:45:46 -0700 Subject: 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 Original-Reviewed-on: https://chromium-review.googlesource.com/193722 Original-Reviewed-by: David Hendricks (cherry picked from commit 3c9c2ede7e97e330cad2c2f3e557cc9bcdaecdcc) Signed-off-by: Marc Jones Change-Id: Ia7bc66cecfc16f1dd4a9f3cb9840cbe91878adf4 Reviewed-on: http://review.coreboot.org/7263 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer --- 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(-) create mode 100644 src/console/ipq806x_console.c create mode 100755 src/mainboard/google/storm/cdp.c create mode 100644 src/soc/qualcomm/ipq806x/cdp.h create mode 100644 src/soc/qualcomm/ipq806x/clock.c create mode 100644 src/soc/qualcomm/ipq806x/clock.h create mode 100644 src/soc/qualcomm/ipq806x/gpio.c create mode 100644 src/soc/qualcomm/ipq806x/gpio.h create mode 100644 src/soc/qualcomm/ipq806x/gsbi.h create mode 100644 src/soc/qualcomm/ipq806x/iomap.h create mode 100644 src/soc/qualcomm/ipq806x/timer.h create mode 100644 src/soc/qualcomm/ipq806x/uart.h (limited to 'src') 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 +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include "ipq806x_board_param.h" +#include "ipq806x_cdp.h" +#include +#include +#include +#include + +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 /* 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 + +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 +#include +#include +#include +#include + +/** + * 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 +/* UART clock @ 7.3728 MHz */ +#define UART_DM_CLK_RX_TX_BIT_RATE 0xCC + +/* UART specific definitions */ + +#define BIT(s) (1<> (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 +#include +#include + +/******************************************************* +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 + +/* 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 +#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 +#include +#include +#include +#include + +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 -#include -#include -#include + 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 +#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__ */ + -- cgit v1.2.3