/** * ipq806x_uart_init - initializes UART * * Initializes clocks, GPIO and UART controller. */ void uart_init(int idx) { /* Note int idx isn't used in this driver. */ void *dm_base; void *gsbi_base; dm_base = uart_board_param.uart_dm_base; if (read32(MSM_BOOT_UART_DM_CSR(dm_base)) == UART_DM_CLK_RX_TX_BIT_RATE) return; /* UART must have been already initialized. */ gsbi_base = uart_board_param.uart_gsbi_base; ipq_configure_gpio(uart_board_param.dbg_uart_gpio, NO_OF_DBG_UART_GPIOS); /* Configure the uart clock */ uart_clock_config(uart_board_param.uart_gsbi, uart_board_param.mnd_value.m_value, uart_board_param.mnd_value.n_value, uart_board_param.mnd_value.d_value, 0); write32(GSBI_CTRL_REG(gsbi_base), GSBI_PROTOCOL_CODE_I2C_UART << GSBI_CTRL_REG_PROTOCOL_CODE_S); write32(MSM_BOOT_UART_DM_CSR(dm_base), UART_DM_CLK_RX_TX_BIT_RATE); /* Intialize UART_DM */ msm_boot_uart_dm_init(dm_base); }
/** * Reads a word from the RX FIFO or returns not ready. */ static unsigned msm_boot_uart_dm_read(void) { static int total_rx_data = 0; static int rx_data_read = 0; void *base = base_uart_addr; uint32_t status_reg; /* RXSTALE means RX FIFO is not empty. */ status_reg = readl(IPQ_UART_DM_MISR(base)); if (!(status_reg & IPQ_UART_DM_RXSTALE)) return IPQ_UART_DM_E_RX_NOT_READY; /* Check for Overrun error. We'll just reset Error Status */ if (readl(IPQ_UART_DM_SR(base)) & IPQ_UART_DM_SR_UART_OVERRUN) { writel(IPQ_UART_DM_CMD_RESET_ERR_STAT, IPQ_UART_DM_CR(base)); total_rx_data = rx_data_read = 0; msm_boot_uart_dm_init(base); return IPQ_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(IPQ_UART_DM_RX_TOTAL_SNAP(base)); /* Data available in FIFO; read a word. */ uart_rx_fifo_word = readl(IPQ_UART_DM_RF(base, 0)); /* * TODO(vbendeb): this is wrong and will be addressed shortly: there * should be no zeros returned from the FIFO in case there are * received characters (we don't expect to be receiving zeros). * See http://crosbug.com/p/29313 */ if (uart_rx_fifo_word == 0) { return IPQ_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 */ uart_ready_data_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 IPQ_UART_DM_E_SUCCESS; msm_boot_uart_dm_init_rx_transfer(base); total_rx_data = rx_data_read = 0; return IPQ_UART_DM_E_SUCCESS; }
void uart_init(void) { char *data = "Android Bootloader - UART_DM Initialized!!!\n"; msm_boot_uart_dm_init(); msm_boot_uart_dm_write(data, 44); }
static void configure_uart_dm(uart_cfg_t *uart_cfg) { ipq_configure_gpio(uart_cfg->dbg_uart_gpio, NO_OF_DBG_UART_GPIOS); uart_clock_config(uart_cfg->base, uart_cfg->uart_mnd_value.m_value, uart_cfg->uart_mnd_value.n_value, uart_cfg->uart_mnd_value.d_value, gboard_param->clk_dummy); writel(GSBI_PROTOCOL_CODE_I2C_UART << GSBI_CTRL_REG_PROTOCOL_CODE_S, GSBI_CTRL_REG(uart_cfg->gsbi_base)); writel(UART_DM_CLK_RX_TX_BIT_RATE, MSM_BOOT_UART_DM_CSR(uart_cfg->uart_dm_base)); /* Intialize UART_DM */ msm_boot_uart_dm_init(uart_cfg->uart_dm_base); }
/* Defining functions that's exposed to outside world and in coformance to * existing uart implemention. These functions are being called to initialize * UART and print debug messages in bootloader. */ void uart_dm_init(uint8_t id, uint32_t gsbi_base, uint32_t uart_dm_base) { static uint8_t port = 0; char *data = "Android Bootloader - UART_DM Initialized!!!\n"; /* Configure the uart clock */ clock_config_uart_dm(id); dsb(); /* Configure GPIO to provide connectivity between UART block product ports and chip pads */ gpio_config_uart_dm(id); dsb(); /* Configure GSBI for UART_DM protocol. * I2C on 2 ports, UART (without HS flow control) on the other 2. * This is only on chips that have GSBI block */ if(gsbi_base) writel(GSBI_PROTOCOL_CODE_I2C_UART << GSBI_CTRL_REG_PROTOCOL_CODE_S, GSBI_CTRL_REG(gsbi_base)); dsb(); /* Configure clock selection register for tx and rx rates. * Selecting 115.2k for both RX and TX. */ writel(UART_DM_CLK_RX_TX_BIT_RATE, MSM_BOOT_UART_DM_CSR(uart_dm_base)); dsb(); /* Intialize UART_DM */ msm_boot_uart_dm_init(uart_dm_base); msm_boot_uart_dm_write(uart_dm_base, data, 44); ASSERT(port < ARRAY_SIZE(port_lookup)); port_lookup[port++] = uart_dm_base; /* Set UART init flag */ uart_init_flag = 1; }
/** * @brief ipq40xx_uart_init - initializes UART * * Initializes clocks, GPIO and UART controller. */ void uart_init(int idx) { /* Note int idx isn't used in this driver. */ void *dm_base; dm_base = uart_board_param.uart_dm_base; if (read32(MSM_BOOT_UART_DM_CSR(dm_base)) == UART_DM_CLK_RX_TX_BIT_RATE) return; /* UART must have been already initialized. */ ipq_configure_gpio(uart_board_param.dbg_uart_gpio, NO_OF_DBG_UART_GPIOS); /* Configure the uart clock */ uart_clock_config(uart_board_param.blsp_uart, uart_board_param.mnd_value.m_value, uart_board_param.mnd_value.n_value, uart_board_param.mnd_value.d_value); write32(MSM_BOOT_UART_DM_CSR(dm_base), UART_DM_CLK_RX_TX_BIT_RATE); /* Initialize UART_DM */ msm_boot_uart_dm_init(dm_base); }
/** * 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. */ #if 0 /* Not used yet */ 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; void *base; uint32_t status_reg; base = uart_board_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; }